1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** GUIX Component                                                        */
16 /**                                                                       */
17 /**   Win32 Display Management (Display)                                  */
18 /**                                                                       */
19 /**************************************************************************/
20 #define GX_SOURCE_CODE
21 
22 #include "tx_api.h"
23 /*#include "tx_thread.h"*/
24 #include "gx_api.h"
25 #include "gx_system.h"
26 #include "gx_widget.h"
27 #include "gx_window.h"
28 #include "gx_utility.h"
29 #include "gx_display.h"
30 #include "gx_canvas.h"
31 
32 #include "windows.h"
33 #include "gx_win32_studio_display_driver.h"
34 #include "gx_dave2d_simulation_display_driver.h"
35 #include "studiox_constants.h"
36 #include "studiox_screen_driver.h"
37 
38 #ifdef _DEBUG
39 #define _CRTDBG_MAP_ALLOC
40 #include <stdlib.h>
41 #include <crtdbg.h>
42 #endif
43 
44 GX_DISPLAY      target_win_display;
45 GX_CANVAS       target_win_canvas;
46 GX_WINDOW_ROOT  target_win_root_window;
47 
48 void           *target_win_canvas_memory = NULL;
49 HWND            target_win_handle;
50 extern HPALETTE gx_palette_handle;
51 UINT            win32_graphics_driver_setup_24xrgb(GX_DISPLAY *graphic);
52 VOID            win32_graphics_driver_cleanup_24xrgb(GX_DISPLAY *graphic);
53 UINT            win32_graphics_driver_setup_565rgb(GX_DISPLAY *graphic);
54 VOID            win32_graphics_driver_cleanup_565rgb(GX_DISPLAY *graphic);
55 UINT            win32_graphics_driver_setup_4444argb(GX_DISPLAY *display);
56 VOID            win32_graphics_driver_cleanup_4444argb(GX_DISPLAY *graphic);
57 UINT            win32_graphics_driver_setup_565bgr(GX_DISPLAY *graphic);
58 VOID            win32_graphics_driver_cleanup_565bgr(GX_DISPLAY *graphic);
59 UINT            win32_graphics_driver_setup_1555xrgb(GX_DISPLAY *display);
60 VOID            win32_graphics_driver_cleanup_1555xrgb(GX_DISPLAY *display);
61 UINT            win32_graphics_driver_setup_8bit_palette(GX_DISPLAY *graphic);
62 VOID            win32_graphics_driver_cleanup_8bit_palette(GX_DISPLAY *graphic);
63 UINT            win32_graphics_driver_setup_332rgb(GX_DISPLAY *display);
64 VOID            win32_graphics_driver_cleanup_332rgb(GX_DISPLAY *display);
65 UINT            win32_graphics_driver_setup_4bpp_grayscale(GX_DISPLAY *display);
66 VOID            win32_graphics_driver_cleanup_4bpp_grayscale(GX_DISPLAY *display);
67 UINT            win32_graphics_driver_setup_monochrome(GX_DISPLAY *graphic);
68 VOID            win32_graphics_driver_cleanup_monochrome(GX_DISPLAY *graphic);
69 
70 UINT win32_dave2d_graphics_driver_setup_8bit_palette(GX_DISPLAY *display);
71 UINT win32_dave2d_graphics_driver_setup_565rgb(GX_DISPLAY *display);
72 UINT win32_dave2d_graphics_driver_setup_24xrgb(GX_DISPLAY *display);
73 UINT win32_chromeart_graphics_driver_setup_565rgb(GX_DISPLAY *display);
74 
75 BOOL guix_configure_canvas(int xres, int yres, int colorformat, int cpu_type, int IsSynergyD2D, GX_COLOR *palette, int pal_size);
76 UINT gx_system_focus_claim_standard(GX_WIDGET *widget);
77 HWND GetGuixWinHandle(void);
78 
79 /*LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);*/
80 /**************************************************************************/
gx_studio_buffer_toggle_stub(GX_CANVAS * canvas,GX_RECTANGLE * dirty)81 VOID gx_studio_buffer_toggle_stub(GX_CANVAS *canvas, GX_RECTANGLE *dirty)
82 {
83 }
84 
85 /**************************************************************************/
guix_canvas_flush(HDC win_device,int xpos,int ypos,GX_CANVAS * canvas,GX_RECTANGLE * dirty,int scale,GRID_SNAP_INFO * gsi)86 VOID guix_canvas_flush(HDC win_device, int xpos, int ypos,
87                        GX_CANVAS *canvas, GX_RECTANGLE *dirty, int scale, GRID_SNAP_INFO *gsi)
88 {
89 INT                           Top;
90 INT                           Left;
91 INT                           Height;
92 INT                           Width;
93 //HPALETTE      old_palette;
94 GX_DISPLAY                   *display;
95 GX_RECTANGLE                  Limit;
96 GX_RECTANGLE                  Copy;
97 
98 GX_WIN32_DISPLAY_DRIVER_DATA *driver_instance;
99 VOID                         *memptr;
100 HDC                           hdcMem;
101 HBITMAP                       hbmMem;
102 HANDLE                        hOld;
103 INT                           copy_width;
104 INT                           copy_height;
105 INT                           canvas_width;
106 INT                           canvas_height;
107 INT                           row;
108 INT                           col;
109 
110     display = canvas -> gx_canvas_display;
111     driver_instance = (GX_WIN32_DISPLAY_DRIVER_DATA *)(display -> gx_display_driver_data);
112 
113     _gx_utility_rectangle_define(&Limit, 0, 0,
114                                  canvas -> gx_canvas_x_resolution - 1,
115                                  canvas -> gx_canvas_y_resolution - 1);
116 
117     if (dirty)
118     {
119         if (!_gx_utility_rectangle_overlap_detect(&Limit, dirty, &Copy))
120         {
121             return;
122         }
123     }
124     else
125     {
126         Copy = Limit;
127     }
128     SetMapMode(win_device, MM_TEXT);
129 
130     Top = Copy.gx_rectangle_top;
131     Left = Copy.gx_rectangle_left;
132     Width = Copy.gx_rectangle_right - Copy.gx_rectangle_left + 1;
133     Height = Copy.gx_rectangle_bottom - Copy.gx_rectangle_top + 1;
134 
135     memptr = _win32_canvas_memory_prepare(canvas, &Copy);
136 
137     copy_width = Width * scale / 100;
138     copy_height = Height * scale / 100;
139 
140     Left = Left * scale / 100;
141     Top = Top * scale / 100;
142     xpos = xpos * scale / 100;
143     ypos = ypos * scale / 100;
144 
145     int grid_space = gsi->grid_space;
146 
147     if (grid_space || gsi->crosshair_enabled || gsi->snap_line_count)
148     {
149         canvas_width = canvas->gx_canvas_x_resolution * scale / 100;
150         canvas_height = canvas->gx_canvas_y_resolution * scale / 100;
151 
152         /* Create an off-screen DC for double-buffering */
153         hdcMem = CreateCompatibleDC(win_device);
154         hbmMem = CreateCompatibleBitmap(win_device, canvas_width, canvas_height);
155         hOld = SelectObject(hdcMem, hbmMem);
156 
157         /* Flush canvas memory to off-screen DC. */
158         StretchDIBits(hdcMem, Left + xpos, Top + ypos, copy_width, copy_height,
159             Copy.gx_rectangle_left,
160             Copy.gx_rectangle_top + Height + 1,
161             Width, -Height, memptr,
162             (BITMAPINFO*)&(driver_instance->win32_driver_bmpinfo),
163             DIB_RGB_COLORS,
164             SRCCOPY);
165 
166         if (grid_space)
167         {
168             grid_space *= scale / 100;
169 
170             /* Draw grid. */
171             for (col = grid_space; col < canvas_height; col += grid_space)
172             {
173                 for (row = grid_space; row < canvas_width; row += grid_space)
174                 {
175                     SetPixel(hdcMem, row, col, RGB(128, 128, 128));
176                 }
177             }
178         }
179 
180 
181         if (gsi->crosshair_enabled)
182         {
183             // Draw crosshair
184             SelectObject(hdcMem, GetStockObject(DC_PEN));
185             SetDCPenColor(hdcMem, RGB(128, 128, 128));
186 
187             col = (gsi->crosshair_cx - gsi->crosshair_size) * scale / 100;
188             row = gsi->crosshair_cy * scale / 100;
189 
190             MoveToEx(hdcMem, col, row, NULL);
191 
192             col = (gsi->crosshair_cx + gsi->crosshair_size + 1) * scale / 100;
193             LineTo(hdcMem, col, row);
194 
195             col = gsi->crosshair_cx * scale / 100;
196             row = (gsi->crosshair_cy - gsi->crosshair_size) * scale / 100;
197             MoveToEx(hdcMem, col, row, NULL);
198 
199             row = (gsi->crosshair_cy + gsi->crosshair_size + 1) * scale / 100;
200             LineTo(hdcMem, col, row);
201         }
202 
203         if (gsi->snap_line_count)
204         {
205             // Draw snap lines;
206             SelectObject(hdcMem, GetStockObject(DC_PEN));
207             SetDCPenColor(hdcMem, RGB(255, 0, 0));
208 
209             SNAPLINE_INFO *snapline;
210 
211             for (int index = 0; index < gsi->snap_line_count; index++)
212             {
213                 snapline = &gsi->snap_lines[index];
214 
215                 if (snapline->direction == SNAP_LINE_DIRECTION_VERTICAL)
216                 {
217                     // Draw vertical line
218                     col = snapline->target_x_y * scale / 100;
219                     row = snapline->target_top_left * scale / 100;
220 
221                     MoveToEx(hdcMem, col, row, NULL);
222 
223                     row = (snapline->target_bottom_right + 1) * scale / 100;
224 
225                     LineTo(hdcMem, col, row);
226                 }
227                 else
228                 {
229                     // Draw horizontal line
230                     col = snapline->target_top_left * scale / 100;
231                     row = snapline->target_x_y * scale / 100;
232 
233                     MoveToEx(hdcMem, col, row, NULL);
234 
235                     col = (snapline->target_bottom_right + 1) * scale / 100;
236 
237                     LineTo(hdcMem, col, row);
238                 }
239             }
240         }
241 
242         /* Transfer the off-screen DC to the screen. */
243         BitBlt(win_device, Left + xpos, Top + ypos, copy_width, copy_height, hdcMem, Left + xpos, Top + ypos, SRCCOPY);
244 
245         /* Free-up the off-screen DC.  */
246         SelectObject(hdcMem, hOld);
247         DeleteObject(hbmMem);
248         DeleteDC(hdcMem);
249     }
250     else
251     {
252         /* Flush canvas memory to the screen. */
253         StretchDIBits(win_device, Left + xpos, Top + ypos, copy_width, copy_height,
254                       Copy.gx_rectangle_left,
255                       Copy.gx_rectangle_top + Height + 1,
256                       Width, -Height, memptr,
257                       (BITMAPINFO *)&(driver_instance->win32_driver_bmpinfo),
258                       DIB_RGB_COLORS,
259                       SRCCOPY);
260     }
261 }
262 
263 /**************************************************************************/
guix_bitmap_flush(HDC win_device,int xpos,int ypos,int Width,VOID * memptr,GX_BMP_INFO * bmpinfo)264 void guix_bitmap_flush(HDC win_device, int xpos, int ypos, int Width,
265                        VOID *memptr, GX_BMP_INFO *bmpinfo)
266 {
267 INT Height;
268 
269     SetMapMode(win_device, MM_TEXT);
270 
271     Height = bmpinfo -> gx_bmp_header.biHeight;
272 
273     StretchDIBits(win_device, xpos, ypos, Width, Height,
274                   0, Height + 1, Width, -Height, memptr,
275                   (BITMAPINFO *)bmpinfo,
276                   DIB_RGB_COLORS,
277                   SRCCOPY);
278 }
279 
280 /**************************************************************************/
guix_canvas_paint(HDC dc,GX_RECTANGLE dirty,int scale,GRID_SNAP_INFO * gsi)281 void guix_canvas_paint(HDC dc, GX_RECTANGLE dirty, int scale, GRID_SNAP_INFO *gsi)
282 {
283 GX_CANVAS      *canvas;
284 
285     canvas = &target_win_canvas;
286 
287     /* Call the driver buffer toggle function for this canvas.  */
288     #if 0
289     _gx_utility_rectangle_define(&dirty, 0, 0,
290                                  canvas -> gx_canvas_x_resolution - 1,
291                                  canvas -> gx_canvas_y_resolution - 1);
292 
293     #else
294         //dirty = canvas ->gx_canvas_dirty_area;
295     #endif
296     guix_canvas_flush(dc, 0, 0, canvas, &dirty, scale, gsi);
297 }
298 
299 /**************************************************************************/
guix_memory_allocate(ULONG size)300 VOID *guix_memory_allocate(ULONG size)
301 {
302     VOID *pointer;
303     pointer = malloc(size);
304     return pointer;
305 }
306 
307 /**************************************************************************/
guix_memory_free(VOID * mem)308 VOID guix_memory_free(VOID *mem)
309 {
310     free(mem);
311 }
312 
313 /**************************************************************************/
GetGuixWinHandle(void)314 HWND GetGuixWinHandle(void)
315 {
316     return target_win_handle;
317 }
318 
319 /**************************************************************************/
initialize_guix(HWND target_win)320 void initialize_guix(HWND target_win)
321 {
322     target_win_handle = target_win;
323     _gx_system_initialize();
324 
325     _gx_system_memory_allocator_set(guix_memory_allocate, guix_memory_free);
326 }
327 
gx_main(int argc,char ** argv)328 int gx_main(int argc, char ** argv)
329 {
330   return(0);
331 }
332 
333 /**************************************************************************/
RunGuixDisplaySetupFunction(GX_DISPLAY * display,char * name,int xres,int yres,int colorformat,int target_cpu,int IsRenesasDave2D,int IsDave2DFontFormat,GX_COLOR * palette,int palsize,int aliased_font_palsize)334 INT RunGuixDisplaySetupFunction(GX_DISPLAY *display, char *name, int xres, int yres,
335                                 int colorformat, int target_cpu, int IsRenesasDave2D, int IsDave2DFontFormat,
336                                 GX_COLOR *palette, int palsize, int aliased_font_palsize)
337 {
338 UINT (*setup_func)(GX_DISPLAY *);
339 INT  memsize = xres * yres;
340 
341     setup_func = GX_NULL;
342 
343     /* figure out which setup function to run */
344     switch (colorformat)
345     {
346     case GX_COLOR_FORMAT_MONOCHROME:
347     case GX_COLOR_FORMAT_MONOCHROME_INVERTED:
348         setup_func = win32_graphics_driver_setup_monochrome;
349         memsize = ((xres + 7) >> 3) * yres;
350         break;
351 
352     case GX_COLOR_FORMAT_2BIT_GRAY:
353     case GX_COLOR_FORMAT_2BIT_GRAY_INVERTED:
354     case GX_COLOR_FORMAT_4BIT_GRAY_INVERTED:
355     case GX_COLOR_FORMAT_4BIT_VGA:
356     case GX_COLOR_FORMAT_8BIT_GRAY:
357     case GX_COLOR_FORMAT_8BIT_GRAY_INVERTED:
358         /* FIXME: These formats are not done yet */
359         break;
360 
361     case GX_COLOR_FORMAT_4BIT_GRAY:
362         setup_func = win32_graphics_driver_setup_4bpp_grayscale;
363         memsize = ((xres + 1) >> 1) * yres;
364         break;
365 
366     case GX_COLOR_FORMAT_8BIT_PALETTE:
367         if (IsDave2DFontFormat)
368         {
369             setup_func = win32_dave2d_graphics_driver_setup_8bit_palette;
370         }
371         else
372         {
373             setup_func = win32_graphics_driver_setup_8bit_palette;
374         }
375         break;
376 
377     case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
378         setup_func = win32_graphics_driver_setup_332rgb;
379         break;
380 
381     case GX_COLOR_FORMAT_5551BGRX:
382     case GX_COLOR_FORMAT_1555XRGB:
383         if (!IsRenesasDave2D)
384         {
385             setup_func = win32_graphics_driver_setup_1555xrgb;
386         }
387         memsize *= 2;
388         break;
389 
390     case GX_COLOR_FORMAT_565RGB:
391         switch(target_cpu)
392         {
393         case CPU_SYNERGY:
394         case CPU_RA:
395         case CPU_RX:
396             if (IsRenesasDave2D)
397             {
398                 setup_func = win32_dave2d_graphics_driver_setup_565rgb;
399             }
400             else
401             {
402                 setup_func = win32_graphics_driver_setup_565rgb;
403             }
404             break;
405 
406         case CPU_ST_CHROMEART:
407             setup_func = win32_chromeart_graphics_driver_setup_565rgb;
408             break;
409 
410         default:
411             setup_func = win32_graphics_driver_setup_565rgb;
412             break;
413         }
414         memsize *= 2;
415         break;
416 
417     case GX_COLOR_FORMAT_4444ARGB:
418     case GX_COLOR_FORMAT_4444BGRA:
419         setup_func = win32_graphics_driver_setup_4444argb;
420         memsize *= 2;
421         break;
422 
423     case GX_COLOR_FORMAT_565BGR:
424         setup_func = win32_graphics_driver_setup_565bgr;
425         memsize *= 2;
426         break;
427 
428     case GX_COLOR_FORMAT_24RGB:
429     case GX_COLOR_FORMAT_24BGR:
430     case GX_COLOR_FORMAT_24XRGB:
431     case GX_COLOR_FORMAT_24BGRX:
432     case GX_COLOR_FORMAT_32ARGB:
433     case GX_COLOR_FORMAT_32BGRA:
434         /* counts go in the aux data array: */
435         if (IsRenesasDave2D)
436         {
437             setup_func = win32_dave2d_graphics_driver_setup_24xrgb;
438         }
439         else
440         {
441             setup_func = win32_graphics_driver_setup_24xrgb;
442         }
443         memsize *= 4;
444         break;
445     }
446 
447     if (setup_func)
448     {
449         if (_gx_display_create(display, name, setup_func, xres, yres) == GX_SUCCESS)
450         {
451             if (colorformat == GX_COLOR_FORMAT_8BIT_PALETTE)
452             {
453                 if (!IsDave2DFontFormat)
454                 {
455                     if (aliased_font_palsize == 8)
456                     {
457                         display->gx_display_driver_4bit_glyph_draw = _gx_display_driver_8bpp_glyph_3bit_draw;
458                     }
459                     else
460                     {
461                         display->gx_display_driver_4bit_glyph_draw = _gx_display_driver_8bpp_glyph_4bit_draw;
462                     }
463                 }
464             }
465 
466             return memsize;
467         }
468     }
469     return 0;
470 }
471 
472 /**************************************************************************/
guix_create_app_display(GX_DISPLAY * display,char * name,int xres,int yres,int colorformat,int target_cpu,int IsRenesasDave2D,int IsDave2DFontFormat,GX_COLOR * palette,int palsize,int aliased_font_palsize)473 INT guix_create_app_display(GX_DISPLAY *display, char *name,
474                                int xres, int yres,  int colorformat,
475                                int target_cpu, int IsRenesasDave2D, int IsDave2DFontFormat,
476                                GX_COLOR *palette, int palsize, int aliased_font_palsize)
477 {
478 INT  memsize;
479 
480     memsize = RunGuixDisplaySetupFunction(display, name, xres, yres,
481                                           colorformat, target_cpu, IsRenesasDave2D, IsDave2DFontFormat,
482                                           palette, palsize, aliased_font_palsize);
483 
484     if (memsize)
485     {
486         if (colorformat <= GX_COLOR_FORMAT_8BIT_PALETTE)
487         {
488             if (display -> gx_display_driver_palette_set && palette)
489             {
490                 display -> gx_display_driver_palette_set(display, palette, palsize);
491             }
492         }
493     }
494     return memsize;
495 }
496 
497 /**************************************************************************/
guix_studio_create_display(GX_DISPLAY * display,char * name,int xres,int yres,int colorformat,int target_cpu,int IsRenesasDave2D,int IsDave2DFontFormat,GX_COLOR * palette,int palsize,int aliased_font_palsize)498 INT guix_studio_create_display(GX_DISPLAY *display, char *name,
499                                int xres, int yres,  int colorformat,
500                                int target_cpu, int IsRenesasDave2D, int IsDave2DFontFormat,
501                                GX_COLOR *palette, int palsize, int aliased_font_palsize)
502 {
503 INT  memsize;
504 
505     memsize = RunGuixDisplaySetupFunction(display, name, xres, yres,
506                                           colorformat, target_cpu, IsRenesasDave2D, IsDave2DFontFormat,
507                                           palette, palsize, aliased_font_palsize);
508 
509     if (memsize)
510     {
511         // Dummy out the display toggle function, Studio uses it's own canvas_flush function
512         // to draw the canvas to the visible window
513 
514         display->gx_display_driver_buffer_toggle = gx_studio_buffer_toggle_stub;
515 
516         if (colorformat <= GX_COLOR_FORMAT_8BIT_PALETTE)
517         {
518             if (display -> gx_display_driver_palette_set && palette)
519             {
520                 display -> gx_display_driver_palette_set(display, palette, palsize);
521             }
522         }
523     }
524     return memsize;
525 }
526 
guix_studio_delete_display(GX_DISPLAY * display)527 void guix_studio_delete_display(GX_DISPLAY *display)
528 {
529 void (*cleanup_func)(GX_DISPLAY *);
530 
531     cleanup_func = NULL;
532 
533     /* figure out which cleanup function to run if
534        this is not first time */
535     switch (display -> gx_display_color_format)
536     {
537     case GX_COLOR_FORMAT_MONOCHROME:
538     case GX_COLOR_FORMAT_MONOCHROME_INVERTED:
539         cleanup_func = win32_graphics_driver_cleanup;
540         break;
541 
542     case GX_COLOR_FORMAT_2BIT_GRAY:
543     case GX_COLOR_FORMAT_2BIT_GRAY_INVERTED:
544     case GX_COLOR_FORMAT_4BIT_GRAY_INVERTED:
545     case GX_COLOR_FORMAT_4BIT_VGA:
546     case GX_COLOR_FORMAT_8BIT_GRAY:
547     case GX_COLOR_FORMAT_8BIT_GRAY_INVERTED:
548         break;
549 
550     case GX_COLOR_FORMAT_4BIT_GRAY:
551     case GX_COLOR_FORMAT_8BIT_PALETTE:
552     case GX_COLOR_FORMAT_8BIT_PACKED_PIXEL:
553     case GX_COLOR_FORMAT_5551BGRX:
554     case GX_COLOR_FORMAT_1555XRGB:
555     case GX_COLOR_FORMAT_565RGB:
556     case GX_COLOR_FORMAT_4444ARGB:
557     case GX_COLOR_FORMAT_4444BGRA:
558     case GX_COLOR_FORMAT_565BGR:
559     case GX_COLOR_FORMAT_24RGB:
560     case GX_COLOR_FORMAT_24BGR:
561     case GX_COLOR_FORMAT_24BGRX:
562     case GX_COLOR_FORMAT_24XRGB:
563     case GX_COLOR_FORMAT_32ARGB:
564     case GX_COLOR_FORMAT_32BGRA:
565         /* counts go in the aux data array: */
566         cleanup_func = win32_graphics_driver_cleanup;
567         break;
568     }
569 
570     if (cleanup_func)
571     {
572         _gx_display_delete(display, cleanup_func);
573     }
574 }
575 
576 /**************************************************************************/
guix_cleanup_target_win_canvas(VOID)577 VOID guix_cleanup_target_win_canvas(VOID)
578 {
579     if (target_win_canvas_memory != NULL)
580     {
581         free(target_win_canvas_memory);
582         target_win_canvas_memory = NULL;
583         guix_studio_delete_display(&target_win_display);
584         _gx_canvas_delete(&target_win_canvas);
585         _gx_window_root_delete(&target_win_root_window);
586     }
587 }
588 
589 
590 /**************************************************************************/
guix_configure_target_win_canvas(int xres,int yres,int colorformat,int target_cpu,int IsSynergyD2D,int IsSynergyFontFormat,GX_COLOR * palette,int palsize,int aliased_font_palsize)591 BOOL guix_configure_target_win_canvas(int xres,
592                            int yres,
593                            int colorformat,
594                            int target_cpu,
595                            int IsSynergyD2D,
596                            int IsSynergyFontFormat,
597                            GX_COLOR *palette,
598                            int palsize,
599                            int aliased_font_palsize)
600 {
601 GX_RECTANGLE size;
602 int          memsize;
603 
604     if (target_win_canvas_memory != NULL)
605     {
606         _gx_widget_hide((GX_WIDGET *)&target_win_root_window);
607         free(target_win_canvas_memory);
608         target_win_canvas_memory = NULL;
609         guix_studio_delete_display(&target_win_display);
610         _gx_canvas_delete(&target_win_canvas);
611         _gx_window_root_delete(&target_win_root_window);
612     }
613 
614     memsize = guix_studio_create_display(&target_win_display, "StudioX Main Display",
615                                          xres, yres, colorformat, target_cpu, IsSynergyD2D, IsSynergyFontFormat, palette, palsize, aliased_font_palsize);
616 
617     if (memsize)
618     {
619 
620         gx_win32_set_win_handle(target_win_display.gx_display_driver_data, GetGuixWinHandle());
621         gx_win32_set_thread_id(target_win_display.gx_display_driver_data, GetCurrentThreadId());
622 
623         target_win_canvas_memory = malloc(memsize);
624 
625         //_gx_canvas_create(&target_win_canvas, "StudioX Canvas",
626         //                  &target_win_display, GX_CANVAS_MANAGED | GX_CANVAS_VISIBLE,
627         //                  xres, yres, target_win_canvas_memory, memsize);
628 
629         _gx_canvas_create(&target_win_canvas, "StudioX Canvas",
630                           &target_win_display, GX_CANVAS_VISIBLE,
631                           xres, yres, target_win_canvas_memory, memsize);
632 
633         /* Create a background root window and attach to the background canvas.  */
634 
635         _gx_utility_rectangle_define(&size, 0, 0, xres - 1, yres - 1);
636         _gx_window_root_create(&target_win_root_window, "GUIX root window", &target_win_canvas,
637                                GX_STYLE_BORDER_NONE, GX_ID_NONE, &size);
638         return TRUE;
639     }
640     return FALSE;
641 }
642 
643 /**************************************************************************/
get_root_window(void)644 GX_WINDOW_ROOT *get_root_window(void)
645 {
646 GX_WINDOW_ROOT *root = _gx_system_root_window_created_list;
647 
648     return &target_win_root_window;
649 }
650 
651 /**************************************************************************/
get_target_view_display(void)652 GX_DISPLAY *get_target_view_display(void)
653 {
654     return &target_win_display;
655 }
656 
657 /**************************************************************************/
get_target_win_canvas(void)658 GX_CANVAS *get_target_win_canvas(void)
659 {
660     return &target_win_canvas;
661 }
662 
663 /**************************************************************************/
get_target_win_handle()664 HWND get_target_win_handle()
665 {
666     return target_win_handle;
667 }
668 
669 /**************************************************************************/
670 /* kgm- replace the standard implementation of this function (remove the
671    file gx_system_dirty_partial_add from GUIX library build for studiox.
672 
673     This replacement sends an event to studioX target window when the
674     root canvas is marked dirty */
675 
_gx_system_dirty_partial_add(GX_WIDGET * widget,GX_RECTANGLE * dirty_area)676 UINT  _gx_system_dirty_partial_add(GX_WIDGET *widget, GX_RECTANGLE *dirty_area)
677 {
678 
679 UINT            index;
680 GX_DIRTY_AREA  *dirty_entry;
681 GX_WIDGET      *test;
682 GX_WINDOW_ROOT *root;
683 GX_CANVAS      *canvas;
684 GX_DIRTY_AREA  *empty_dirty_entry = GX_NULL;
685 
686     if (!widget)
687     {
688         return GX_PTR_ERROR;
689     }
690     if (!(widget -> gx_widget_status & GX_STATUS_VISIBLE))
691     {
692         return GX_PTR_ERROR;
693     }
694 
695     /* if a widget is transparent, we actually need to mark it's
696        first non-transparent parent as being dirty
697      */
698     while ((widget -> gx_widget_status & GX_STATUS_TRANSPARENT) &&
699            (widget -> gx_widget_parent))
700     {
701         widget = widget -> gx_widget_parent;
702     }
703 
704     /* walk up to find root window */
705     test = widget;
706 
707     while (test -> gx_widget_parent)
708     {
709         test = test -> gx_widget_parent;
710     }
711 
712     if (test -> gx_widget_type != GX_TYPE_ROOT_WINDOW)
713     {
714         return GX_PTR_ERROR;
715     }
716 
717     root = (GX_WINDOW_ROOT *)test;
718 
719     /* pick up pointer to canvas */
720     canvas = root -> gx_window_root_canvas;
721 
722     /***************************************
723        THIS IS THE ADDED CODE FOR STUDIOX
724     ***************************************/
725 
726     if (canvas == &target_win_canvas)
727     {
728         WPARAM wparam = MAKEWPARAM(dirty_area->gx_rectangle_left, dirty_area->gx_rectangle_top);
729         LPARAM lparam = MAKELPARAM(dirty_area->gx_rectangle_right, dirty_area->gx_rectangle_bottom);
730         PostMessage(target_win_handle, GUIX_DIRTY, wparam, lparam);
731 
732         // When marking widgets dirty for the target win, just always mark the top-level
733         // window dirty to fix any drawing issues caused by Studio intercepting the
734         // target widget drawing, or a transparent target widget not being given
735         // transparent style. We want the drawing inside Studio to look right.
736 
737         if (widget != (GX_WIDGET *) root)
738         {
739             widget = (GX_WIDGET *) root->gx_widget_first_child;
740         }
741     }
742 
743     /***************************************
744        END OF THE ADDED CODE
745     ***************************************/
746 
747     /* Setup pointer to dirty list.  */
748 
749     dirty_entry = canvas -> gx_canvas_dirty_list;
750 
751     /* Check to see if widget already has an entry.  */
752     for (index = 0; index < canvas -> gx_canvas_dirty_count; index++)
753     {
754         /* Is the same widget is present. */
755         if (dirty_entry -> gx_dirty_area_widget == widget)
756         {
757             /* if rectangles overlap, combine them rather
758                than adding another entry
759              */
760             if (_gx_utility_rectangle_overlap_detect(&dirty_entry -> gx_dirty_area_rectangle,
761                                                      dirty_area, GX_NULL))
762             {
763                 /* Combine the dirty rectangles.  */
764                 _gx_utility_rectangle_combine(&dirty_entry -> gx_dirty_area_rectangle, dirty_area);
765 
766                 /* Return success.  */
767                 return(GX_SUCCESS);
768             }
769         }
770         else if ((empty_dirty_entry == GX_NULL) && (dirty_entry -> gx_dirty_area_widget == GX_NULL))
771         {
772             empty_dirty_entry = dirty_entry;
773         }
774 
775         /* Move to next dirty entry.  */
776         dirty_entry++;
777     }
778 
779     if (empty_dirty_entry)
780     {
781 
782         /* Reuse the invalid dirty entry.  */
783         empty_dirty_entry -> gx_dirty_area_widget = widget;
784         empty_dirty_entry -> gx_dirty_area_rectangle = *dirty_area;
785 
786         return(GX_SUCCESS);
787     }
788 
789     /* If we get here, we didn't find an entry for this caller. Add a new entry.  */
790 
791     /* Are there more dirty entries?  */
792     if (canvas -> gx_canvas_dirty_count < GX_MAX_DIRTY_AREAS)
793     {
794         /* Yes, more dirty entries, add this one!  */
795         dirty_entry = &canvas -> gx_canvas_dirty_list[canvas -> gx_canvas_dirty_count];
796         canvas -> gx_canvas_dirty_count++;
797         dirty_entry -> gx_dirty_area_widget =    widget;
798         dirty_entry -> gx_dirty_area_rectangle = *dirty_area;
799     }
800 
801     /* Return success.  */
802     return(GX_SUCCESS);
803 }
804 
805 /**************************************************************************/
806 /* replace the standard implementation of this function (remove the
807 file gx_scroll_wheeel_selected_set from GUIX library build for studiox.)
808 
809 This replacement can be removed when timer issue in studio get fix. */
_gx_scroll_wheel_selected_set(GX_SCROLL_WHEEL * wheel,INT row)810 UINT _gx_scroll_wheel_selected_set(GX_SCROLL_WHEEL *wheel, INT row)
811 {
812     if ((row < 0) || wheel->gx_scroll_wheel_total_rows <= 0)
813     {
814         row = 0;
815     }
816     else if (row > wheel->gx_scroll_wheel_total_rows - 1)
817     {
818         row = wheel->gx_scroll_wheel_total_rows - 1;
819     }
820 
821     wheel->gx_scroll_wheel_selected_row = row;
822 
823     if (wheel->gx_widget_style & GX_STATUS_VISIBLE)
824     {
825         _gx_system_dirty_mark((GX_WIDGET *)wheel);
826     }
827 
828     return GX_SUCCESS;
829 }
830 
831 /**************************************************************************/
832 /* replace the standard implementation of this function
833   (guix focus is not need in studio edit mode) */
_gx_system_focus_claim(GX_WIDGET * widget)834 UINT _gx_system_focus_claim(GX_WIDGET *widget)
835 {
836     GX_WINDOW_ROOT *root = get_root_window();
837     GX_BOOL child_detect;
838 
839     if (root)
840     {
841         _gx_widget_child_detect((GX_WIDGET *)root, widget, &child_detect);
842         if (child_detect)
843         {
844             /* GUIX edit mode. */
845             return 0;
846         }
847         else
848         {
849             /* GUIX running mode. */
850             return gx_system_focus_claim_standard(widget);
851         }
852     }
853     return 0;
854 }
855 
856