1 
2 /***************************************************************************
3  * Copyright (c) 2024 Microsoft Corporation
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the MIT License which is available at
7  * https://opensource.org/licenses/MIT.
8  *
9  * SPDX-License-Identifier: MIT
10  **************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** GUIX Component                                                        */
17 /**                                                                       */
18 /**   Dispaly Management (Dispaly)                                        */
19 /**                                                                       */
20 /**************************************************************************/
21 
22 #define GX_SOURCE_CODE
23 
24 
25 /* Include necessary system files.  */
26 
27 #include "gx_api.h"
28 #include "gx_display.h"
29 
30 /**************************************************************************/
31 /*                                                                        */
32 /*  FUNCTION                                               RELEASE        */
33 /*                                                                        */
34 /*    _gx_display_driver_4bpp_mouse_capture               PORTABLE C      */
35 /*                                                           6.1          */
36 /*  AUTHOR                                                                */
37 /*                                                                        */
38 /*    Kenneth Maxwell, Microsoft Corporation                              */
39 /*                                                                        */
40 /*  DESCRIPTION                                                           */
41 /*                                                                        */
42 /*    This service captures memory under mouse position.                  */
43 /*                                                                        */
44 /*  INPUT                                                                 */
45 /*                                                                        */
46 /*    display                               Display control block         */
47 /*                                                                        */
48 /*  OUTPUT                                                                */
49 /*                                                                        */
50 /*  CALLS                                                                 */
51 /*                                                                        */
52 /*                                                                        */
53 /*  CALLED BY                                                             */
54 /*                                                                        */
55 /*    GUIX Internal Code                                                  */
56 /*                                                                        */
57 /*  RELEASE HISTORY                                                       */
58 /*                                                                        */
59 /*    DATE              NAME                      DESCRIPTION             */
60 /*                                                                        */
61 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
62 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
63 /*                                            resulting in version 6.1    */
64 /*                                                                        */
65 /**************************************************************************/
66 #if defined(GX_MOUSE_SUPPORT)
67 #if !defined(GX_HARDWARE_MOUSE_SUPPORT)
_gx_display_driver_4bpp_mouse_capture(GX_DISPLAY * display)68 VOID _gx_display_driver_4bpp_mouse_capture(GX_DISPLAY  *display)
69 {
70 INT            width;
71 INT            height;
72 INT            row;
73 INT            column;
74 GX_UBYTE      *put;
75 GX_UBYTE      *putrow;
76 GX_UBYTE      *getrow;
77 GX_UBYTE      *get;
78 GX_PIXELMAP   *map;
79 GX_RESOURCE_ID image_id;
80 GX_RECTANGLE   mouse_rect;
81 GX_UBYTE       getmask;
82 GX_UBYTE       putmask = 0xf0;
83 GX_UBYTE       pixel;
84 GX_CANVAS     *canvas;
85 
86     if (display -> gx_display_mouse.gx_mouse_cursor_info)
87     {
88         if (display -> gx_display_mouse.gx_mouse_capture_memory)
89         {
90             canvas = display -> gx_display_mouse.gx_mouse_canvas;
91             image_id = display -> gx_display_mouse.gx_mouse_cursor_info -> gx_mouse_cursor_image_id;
92 
93             if (image_id && image_id < display -> gx_display_pixelmap_table_size)
94             {
95                 map = display -> gx_display_pixelmap_table[image_id];
96 
97                 mouse_rect.gx_rectangle_left = display -> gx_display_mouse.gx_mouse_position.gx_point_x;
98                 mouse_rect.gx_rectangle_top = display -> gx_display_mouse.gx_mouse_position.gx_point_y;
99                 mouse_rect.gx_rectangle_left = (GX_VALUE)(mouse_rect.gx_rectangle_left - display -> gx_display_mouse.gx_mouse_cursor_info -> gx_mouse_cursor_hotspot_x);
100                 mouse_rect.gx_rectangle_top = (GX_VALUE)(mouse_rect.gx_rectangle_top - display -> gx_display_mouse.gx_mouse_cursor_info -> gx_mouse_cursor_hotspot_y);
101 
102                 mouse_rect.gx_rectangle_right = (GX_VALUE)(mouse_rect.gx_rectangle_left + map -> gx_pixelmap_width - 1);
103                 mouse_rect.gx_rectangle_bottom = (GX_VALUE)(mouse_rect.gx_rectangle_top + map -> gx_pixelmap_height - 1);
104 
105                 if (mouse_rect.gx_rectangle_left < 0)
106                 {
107                     mouse_rect.gx_rectangle_left = 0;
108                 }
109                 if (mouse_rect.gx_rectangle_top < 0)
110                 {
111                     mouse_rect.gx_rectangle_top = 0;
112                 }
113                 if (mouse_rect.gx_rectangle_right >= canvas -> gx_canvas_x_resolution)
114                 {
115                     mouse_rect.gx_rectangle_right = (GX_VALUE)(canvas -> gx_canvas_x_resolution - 1);
116                 }
117                 if (mouse_rect.gx_rectangle_bottom >= canvas -> gx_canvas_y_resolution)
118                 {
119                     mouse_rect.gx_rectangle_bottom = (GX_VALUE)(canvas -> gx_canvas_y_resolution - 1);
120                 }
121                 width = mouse_rect.gx_rectangle_right - mouse_rect.gx_rectangle_left + 1;
122                 height = mouse_rect.gx_rectangle_bottom - mouse_rect.gx_rectangle_top + 1;
123             }
124             else
125             {
126                 width = height = 0;
127             }
128 
129             if (width > 0 && height > 0)
130             {
131                 display -> gx_display_mouse.gx_mouse_rect = mouse_rect;
132 
133                 getrow = (GX_UBYTE *)canvas -> gx_canvas_memory;
134                 getrow += ((canvas -> gx_canvas_x_resolution + 1) >> 1) * mouse_rect.gx_rectangle_top;
135                 getrow += mouse_rect.gx_rectangle_left >> 1;
136                 putrow = (GX_UBYTE *)display -> gx_display_mouse.gx_mouse_capture_memory;
137 
138                 for (row = 0; row < height; row++)
139                 {
140                     if (mouse_rect.gx_rectangle_left & 1)
141                     {
142                         getmask = 0x0f;
143                     }
144                     else
145                     {
146                         getmask = 0xf0;
147                     }
148                     get = getrow;
149                     put = putrow;
150                     putmask = 0xf0;
151 
152                     for (column = 0; column < width; column++)
153                     {
154                         pixel = (*get) & getmask;
155                         if (getmask == 0x0f)
156                         {
157                             get++;
158                             getmask = 0xf0;
159                             pixel |= (GX_UBYTE)(pixel << 4);
160                         }
161                         else
162                         {
163                             getmask = 0x0f;
164                             pixel |= pixel >> 4;
165                         }
166 
167                         *put &= (GX_UBYTE)(~putmask);
168                         *put |= pixel & putmask;
169                         putmask >>= 4;
170                         if (putmask == 0)
171                         {
172                             putmask = 0xf0;
173                             put++;
174                         }
175                     }
176                     getrow += (canvas -> gx_canvas_x_resolution + 1) >> 1;
177                     putrow += (width + 1) >> 1;
178                 }
179             }
180             else
181             {
182                 display -> gx_display_mouse.gx_mouse_rect.gx_rectangle_top = 0;
183                 display -> gx_display_mouse.gx_mouse_rect.gx_rectangle_bottom = -1;
184                 display -> gx_display_mouse.gx_mouse_rect.gx_rectangle_left = 0;
185                 display -> gx_display_mouse.gx_mouse_rect.gx_rectangle_right = -1;
186             }
187         }
188     }
189 }
190 #endif
191 #endif
192 
193