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