1 /* Logic to run the application in a standalone window */
2
3 #include "studiox_includes.h"
4 #include "app_runner.h"
5 #include "gx_win32_studio_display_driver.h"
6 #include "gx_animation.h"
7
8 #include "gx_api.h"
9
10 #ifdef _DEBUG
11 #define new DEBUG_NEW
12 #endif
13
14 typedef struct APP_ANIMATION_STRUCT{
15 GX_ANIMATION *app_animation;
16 APP_ANIMATION_STRUCT *app_animation_next;
17 INT app_animation_win_thread_id;
18 }APP_ANIMATION;
19
20 APP_ANIMATION *app_animation_created_list;
21 UINT app_animation_id;
22 extern CString SCREEN_STACK_POP_STRING;
23
24 /**************************************************************************/
app_child_widget_find(GX_WIDGET * parent,CString widget_name)25 GX_WIDGET *app_child_widget_find(GX_WIDGET *parent, CString widget_name)
26 {
27 GX_WIDGET *child;
28 CString name;
29 GX_WIDGET *found = GX_NULL;
30
31 /* Is there a widget? */
32 if (parent)
33 {
34 child = parent->gx_widget_first_child;
35
36 while (child)
37 {
38 name = (TCHAR *)child->gx_widget_name;
39 if (name == widget_name)
40 {
41 found = child;
42 }
43 else if (child->gx_widget_first_child)
44 {
45 found = app_child_widget_find(child, widget_name);
46 }
47
48 if (found)
49 {
50 break;
51 }
52
53 child = child->gx_widget_next;
54 }
55 }
56
57 if ((!found) && (parent->gx_widget_type == GX_TYPE_MENU))
58 {
59 GX_MENU *menu = (GX_MENU *)parent;
60 found = app_child_widget_find((GX_WIDGET *)&menu->gx_menu_list, widget_name);
61 }
62
63 return found;
64 }
65
66 /**************************************************************************/
app_widget_find(GX_WINDOW * root,CString widget_name)67 GX_WIDGET *app_widget_find(GX_WINDOW *root, CString widget_name)
68 {
69 int loop;
70 GX_WIDGET *screen;
71 GX_WIDGET *found = GX_NULL;
72 GX_WIN32_DISPLAY_DRIVER_DATA *driver_instance;
73 GX_DISPLAY *display;
74 CString name;
75
76 display = ((GX_WINDOW_ROOT *)root)->gx_window_root_canvas->gx_canvas_display;
77 driver_instance = (GX_WIN32_DISPLAY_DRIVER_DATA *)display->gx_display_driver_data;
78
79 if (widget_name.IsEmpty())
80 {
81 return GX_NULL;
82 }
83
84 for (loop = 0; loop < driver_instance->win32_screen_count; loop++)
85 {
86 screen = driver_instance->win32_screens[loop];
87
88 if (screen)
89 {
90 name = (TCHAR *)screen->gx_widget_name;
91 if (name == widget_name)
92 {
93 found = screen;
94 }
95 else
96 {
97 found = app_child_widget_find(screen, widget_name);
98 }
99
100 if (found)
101 {
102 break;
103 }
104 }
105 }
106
107 return found;
108 }
109
110 /**************************************************************************/
app_flow_item_get(studiox_project * project,int display_index,GX_WIDGET * screen)111 flow_item *app_flow_item_get(studiox_project *project, int display_index, GX_WIDGET *screen)
112 {
113 flow_item *flow_item = GX_NULL;
114 screen_flow *screen_flow = project->mDisplays[display_index].screenflow;
115
116 if (screen_flow && screen)
117 {
118 CString widget_name = (TCHAR *)screen->gx_widget_name;
119 flow_item = screen_flow->GetFlowItem(widget_name);
120 }
121
122 return flow_item;
123 }
124
125 /**************************************************************************/
app_animation_clean_up(GX_WIN32_DISPLAY_DRIVER_DATA * data)126 void app_animation_clean_up(GX_WIN32_DISPLAY_DRIVER_DATA *data)
127 {
128 APP_ANIMATION *entry = app_animation_created_list;
129 APP_ANIMATION *pre = GX_NULL;
130 APP_ANIMATION *next;
131
132 while (entry)
133 {
134 next = entry->app_animation_next;
135 if (entry->app_animation_win_thread_id == data->win32_window_ThreadId)
136 {
137 if (pre)
138 {
139 pre->app_animation_next = entry->app_animation_next;
140 }
141 else
142 {
143 app_animation_created_list = entry->app_animation_next;
144 }
145
146 if (entry->app_animation->gx_animation_status != GX_ANIMATION_IDLE)
147 {
148 gx_animation_stop(entry->app_animation);
149 }
150
151 delete entry->app_animation;
152 delete entry;
153 }
154 else
155 {
156 pre = entry;
157 }
158 entry = next;
159 }
160 }
161
162 /**************************************************************************/
app_animation_create(GX_WINDOW * root,GX_WIDGET * target)163 GX_ANIMATION *app_animation_create(GX_WINDOW *root, GX_WIDGET *target)
164 {
165 //Create a animation
166 APP_ANIMATION *animation;
167 GX_WIN32_DISPLAY_DRIVER_DATA *driver_instance;
168 GX_DISPLAY *display;
169
170 display = ((GX_WINDOW_ROOT *)root)->gx_window_root_canvas->gx_canvas_display;
171 driver_instance = (GX_WIN32_DISPLAY_DRIVER_DATA *)display->gx_display_driver_data;
172
173 animation = new APP_ANIMATION;
174 animation->app_animation = new GX_ANIMATION;
175 gx_animation_create(animation->app_animation);
176 animation->app_animation_win_thread_id = driver_instance->win32_window_ThreadId;
177
178 GX_ENTER_CRITICAL
179 animation->app_animation_next = app_animation_created_list;
180 app_animation_created_list = animation;
181 GX_EXIT_CRITICAL
182
183 return animation->app_animation;
184 }
185
186 /**************************************************************************/
app_animation_delete(UINT animation_id)187 void app_animation_delete(UINT animation_id)
188 {
189 if (!animation_id)
190 {
191 return;
192 }
193
194 GX_ENTER_CRITICAL
195 // Delete a animation
196 APP_ANIMATION *entry = app_animation_created_list;
197 APP_ANIMATION *pre = GX_NULL;
198
199 while (entry)
200 {
201 if (entry->app_animation->gx_animation_info.gx_animation_id == animation_id)
202 {
203 if (pre)
204 {
205 pre->app_animation_next = entry->app_animation_next;
206 }
207 else
208 {
209 app_animation_created_list = entry->app_animation_next;
210 }
211
212 delete entry->app_animation;
213 delete entry;
214 break;
215 }
216 pre = entry;
217 entry = entry->app_animation_next;
218 }
219 GX_EXIT_CRITICAL
220 }
221
222 /**************************************************************************/
app_animation_process(GX_ANIMATION_INFO * animation,GX_WINDOW * root,GX_WIDGET * parent,GX_WIDGET * target)223 void app_animation_process(GX_ANIMATION_INFO *animation, GX_WINDOW *root, GX_WIDGET *parent, GX_WIDGET *target)
224 {
225 GX_ANIMATION *app_animation = app_animation_create(root, target);
226
227 if (app_animation)
228 {
229 GX_ANIMATION_INFO info;
230 info = *animation;
231 info.gx_animation_parent = parent;
232 info.gx_animation_target = target;
233
234 if (!info.gx_animation_id)
235 {
236 GX_ENTER_CRITICAL
237 info.gx_animation_id = app_animation_id;
238 app_animation_id++;
239 GX_EXIT_CRITICAL
240 }
241
242 gx_animation_start(app_animation, &info);
243 }
244 }
245
246 /**************************************************************************/
app_trigger_action_process(studiox_project * project,int display_index,GX_WINDOW * root,CArray<action_info * > * action_list,GX_WIDGET * screen,GX_EVENT * event_ptr)247 UINT app_trigger_action_process(studiox_project *project, int display_index, GX_WINDOW *root, CArray<action_info *> *action_list, GX_WIDGET *screen, GX_EVENT *event_ptr)
248 {
249 action_info *action;
250 GX_WIDGET *target;
251 GX_WIDGET *parent;
252 screen_flow *flow = project->mDisplays[display_index].screenflow;
253
254 //handle child signals
255 for (int index = 0; index < action_list->GetCount(); index++)
256 {
257 action = action_list->GetAt(index);
258
259 switch (action->action_type)
260 {
261 case GX_ACTION_TYPE_ATTACH:
262 if ((action->target_widget_name == SCREEN_STACK_POP_STRING) ||
263 (action->parent_widget_name == SCREEN_STACK_POP_STRING))
264 {
265 gx_system_screen_stack_get(&parent, &target);
266 }
267
268 if (action->parent_widget_name != SCREEN_STACK_POP_STRING)
269 {
270 parent = app_widget_find(root, action->parent_widget_name);
271 }
272
273 if (action->target_widget_name != SCREEN_STACK_POP_STRING)
274 {
275 target = app_widget_find(root, action->target_widget_name);
276 }
277
278 if (!parent)
279 {
280 parent = (GX_WIDGET *)root;
281 }
282
283 if (parent && target)
284 {
285 gx_widget_attach(parent, target);
286 }
287 break;
288
289 case GX_ACTION_TYPE_WINDOW_EXECUTE:
290 if ((action->target_widget_name == SCREEN_STACK_POP_STRING) ||
291 (action->parent_widget_name == SCREEN_STACK_POP_STRING))
292 {
293 gx_system_screen_stack_get(&parent, &target);
294 }
295
296 if (action->parent_widget_name != SCREEN_STACK_POP_STRING)
297 {
298 parent = app_widget_find(root, action->parent_widget_name);
299 }
300
301 if (action->target_widget_name != SCREEN_STACK_POP_STRING)
302 {
303 target = app_widget_find(root, action->target_widget_name);
304 }
305
306 if (!parent)
307 {
308 parent = (GX_WIDGET *)root;
309 }
310
311 if (parent && target && target->gx_widget_type == GX_TYPE_WINDOW)
312 {
313 gx_widget_attach(parent, target);
314 gx_window_execute((GX_WINDOW *)target, GX_NULL);
315 }
316 break;
317
318 case GX_ACTION_TYPE_WINDOW_EXECUTE_STOP:
319 return event_ptr->gx_event_sender;
320 break;
321
322 case GX_ACTION_TYPE_DETACH:
323 if (!action->target_widget_name.IsEmpty())
324 {
325 target = app_widget_find(root, action->target_widget_name);
326 }
327 else
328 {
329 target = screen;
330 }
331
332 if (target)
333 {
334 gx_widget_hide(target);
335 }
336 break;
337
338 case GX_ACTION_TYPE_TOGGLE:
339 if (action->target_widget_name == SCREEN_STACK_POP_STRING)
340 {
341 gx_system_screen_stack_get(&parent, &target);
342 }
343 else
344 {
345 target = app_widget_find(root, action->target_widget_name);
346 }
347
348 if (target)
349 {
350 gx_widget_attach(screen->gx_widget_parent, target);
351 gx_widget_hide(screen);
352 }
353 break;
354
355 case GX_ACTION_TYPE_SHOW:
356 target = app_widget_find(root, action->target_widget_name);
357 if (target)
358 {
359 gx_widget_show(target);
360 }
361 break;
362
363 case GX_ACTION_TYPE_HIDE:
364 target = app_widget_find(root, action->target_widget_name);
365 if (target)
366 {
367 gx_widget_hide(target);
368 }
369 break;
370
371 case GX_ACTION_TYPE_ANIMATION:
372 if ((action->target_widget_name == SCREEN_STACK_POP_STRING) ||
373 (action->parent_widget_name == SCREEN_STACK_POP_STRING))
374 {
375 gx_system_screen_stack_get(&parent, &target);
376 }
377
378 if (action->target_widget_name != SCREEN_STACK_POP_STRING)
379 {
380 target = app_widget_find(root, action->target_widget_name);
381 }
382
383 if (target && action->animation)
384 {
385 action->animation->gx_animation_id = project->GetIdIndex(display_index, ID_TYPE_ANIMATION, action->animation_id_name);
386 if (action->parent_widget_name != SCREEN_STACK_POP_STRING)
387 {
388 parent = app_widget_find(root, action->parent_widget_name);
389 }
390
391 if (!parent)
392 {
393 //animation parent is not set
394 if (target->gx_widget_parent)
395 {
396 //set animation parent to widget's parent
397 parent = target->gx_widget_parent;
398 }
399 else
400 {
401 //set animation parent to root window
402 parent = (GX_WIDGET *)root;
403 }
404 }
405
406 app_animation_process(action->animation, (GX_WINDOW *)root, parent, target);
407 }
408 break;
409
410 case GX_ACTION_TYPE_SCREEN_STACK_PUSH:
411 target = app_widget_find(root, action->target_widget_name);
412 if (target)
413 {
414 gx_system_screen_stack_push(target);
415 }
416 break;
417
418 case GX_ACTION_TYPE_SCREEN_STACK_POP:
419 gx_system_screen_stack_pop();
420 break;
421
422 case GX_ACTION_TYPE_SCREEN_STACK_RESET:
423 gx_system_screen_stack_reset();
424 break;
425 }
426 }
427
428 return 0;
429 }
430
431 /**************************************************************************/
app_root_event_process(GX_WINDOW * root,GX_EVENT * event_ptr)432 UINT app_root_event_process(GX_WINDOW *root, GX_EVENT *event_ptr)
433 {
434 studiox_project *project = GetOpenProject();
435 UINT status;
436
437 switch (event_ptr->gx_event_type)
438 {
439 case GX_EVENT_ANIMATION_COMPLETE:
440 app_animation_delete(event_ptr->gx_event_sender);
441 break;
442 }
443
444 status = gx_window_event_process(root, event_ptr);
445
446 if (project && root->gx_widget_first_child)
447 {
448 BOOL process = GX_FALSE;
449 BOOL child_detect;
450 int display_index;
451 GX_WIDGET *screen = GX_NULL;
452 flow_item *flow_item = NULL;
453 trigger_info *trigger = GX_NULL;
454 GX_WIN32_DISPLAY_DRIVER_DATA *driver_instance;
455 GX_DISPLAY *display;
456
457 display = ((GX_WINDOW_ROOT *)root)->gx_window_root_canvas->gx_canvas_display;
458 driver_instance = (GX_WIN32_DISPLAY_DRIVER_DATA *)display->gx_display_driver_data;
459 display_index = driver_instance->win32_display_index;
460
461 // Loop through top level screens
462 for (int loop = 0; loop < driver_instance->win32_screen_count; loop++)
463 {
464 screen = driver_instance->win32_screens[loop];
465
466 if (event_ptr->gx_event_target)
467 {
468 if (screen == event_ptr->gx_event_target)
469 {
470 //the target is current screen
471 child_detect = GX_TRUE;
472 }
473 else
474 {
475 //is event target a child of current screen?
476 gx_widget_child_detect(screen, event_ptr->gx_event_target, &child_detect);
477 }
478 }
479 else
480 {
481 //no target specified
482 child_detect = GX_TRUE;
483 }
484
485 if ((!(screen->gx_widget_status | GX_STATUS_VISIBLE)) ||
486 (!child_detect))
487 {
488 screen = screen->gx_widget_next;
489 continue;
490 }
491
492 //app_widget_animation_process(project, display_index, root, screen, event_ptr);
493
494 // Find top level screen
495 flow_item = app_flow_item_get(project, display_index, screen);
496
497 if (flow_item)
498 {
499 trigger = flow_item->trigger_list;
500 }
501
502 while (trigger)
503 {
504 CArray<action_info *> *action_list;
505 ULONG signal = 0;
506 INT id;
507
508 action_list = &trigger->action_list;
509
510 switch (trigger->trigger_type)
511 {
512 case TRIGGER_TYPE_SYSTEM_EVENT:
513 if (trigger->event_type == event_ptr->gx_event_type)
514 {
515 if (event_ptr->gx_event_type == GX_EVENT_ANIMATION_COMPLETE)
516 {
517 id = project->GetIdIndex(display_index, ID_TYPE_ANIMATION, trigger->system_event_animat_id_name);
518 if (event_ptr->gx_event_sender == id)
519 {
520 process = TRUE;
521 }
522 }
523 else
524 {
525 process = TRUE;
526 }
527 }
528 break;
529
530 case TRIGGER_TYPE_CHILD_SIGNAL:
531 id = project->GetIdIndex(display_index, ID_TYPE_WIDGET, trigger->signal_id_name);
532 signal = GX_SIGNAL(id, trigger->event_type);
533
534 if (signal == event_ptr->gx_event_type)
535 {
536 process = TRUE;
537 }
538 break;
539
540 case TRIGGER_TYPE_USER_EVENT:
541 break;
542 }
543
544 if (process)
545 {
546 return app_trigger_action_process(project, display_index, root, action_list, screen, event_ptr);
547 }
548 trigger = trigger->next;
549 }
550
551 screen = screen->gx_widget_next;
552 }
553 }
554
555 return status;
556 }
557
558 extern "C" {
559
560 /**************************************************************************/
561 // This function is called by the application execution thread when the
562 // Windows window into which the application is rendering is closed. Cleanup
563 // the canvas, display, and root window
564 /**************************************************************************/
565
guix_cleanup_win32_canvas(GX_WIN32_DISPLAY_DRIVER_DATA * driver)566 VOID guix_cleanup_win32_canvas(GX_WIN32_DISPLAY_DRIVER_DATA *driver)
567 {
568 GX_WIDGET *screen;
569 int loop;
570
571 if (driver->win32_canvas)
572 {
573 gx_widget_hide((GX_WIDGET *)driver->win32_root_win);
574 if (driver->win32_canvas->gx_canvas_memory)
575 {
576 delete (driver->win32_canvas->gx_canvas_memory);
577 }
578
579 resource_view::CleanupDisplayResources(driver->win32_display);
580
581 guix_studio_delete_display(driver->win32_display);
582 delete(driver->win32_display);
583
584 while(driver->win32_root_win->gx_widget_first_child)
585 {
586 screen = driver->win32_root_win->gx_widget_first_child;
587 gx_widget_detach(screen);
588 }
589 gx_window_root_delete(driver->win32_root_win);
590 delete(driver->win32_root_win);
591
592 // make sure none of the top level screen are attached to each other:
593 for (loop = 0; loop < driver->win32_screen_count; loop++)
594 {
595 screen = driver->win32_screens[loop];
596
597 if (screen)
598 {
599 if (screen->gx_widget_parent)
600 {
601 gx_widget_detach(screen);
602 }
603 }
604 }
605
606 // now delete each of the top level screens:
607 for (loop = 0; loop < driver->win32_screen_count; loop++)
608 {
609 screen = driver->win32_screens[loop];
610
611 if (screen)
612 {
613 widget_factory::DeleteWidgets(screen);
614 }
615 }
616 if (driver->win32_screens)
617 {
618 delete [] driver->win32_screens;
619 }
620
621 gx_canvas_delete(driver->win32_canvas);
622 delete driver->win32_canvas;
623
624 memset(driver, 0, sizeof(GX_WIN32_DISPLAY_DRIVER_DATA));
625 }
626 }
627
628 /**************************************************************************/
guix_execute_thread(ULONG thread_input)629 void guix_execute_thread(ULONG thread_input)
630 {
631 GX_WIN32_DISPLAY_DRIVER_DATA *data;
632
633 studiox_project *project = GetOpenProject();
634
635 if (!project)
636 {
637 return;
638 }
639
640 data = (GX_WIN32_DISPLAY_DRIVER_DATA *)thread_input;
641
642 screen_flow *flow = project->mDisplays[data->win32_display_index].screenflow;
643 int size = flow->GetFlowListCount() * 2;
644 GX_WIDGET **memory = new GX_WIDGET*[size];
645 _gx_system_screen_stack_create(memory, sizeof(GX_WIDGET *)* size);
646
647 _gx_system_thread_entry(0);
648
649 app_animation_clean_up(data);
650
651 //save current win32 window position
652 project->mHeader.app_execute_xpos = data->win32_window_xpos;
653 project->mHeader.app_execute_ypos = data->win32_window_ypos;
654
655 //delete system screen stack memory
656 delete _gx_system_screen_stack.gx_screen_stack_control_memory;
657
658 guix_cleanup_win32_canvas(data);
659
660 ExitThread(0);
661 }
662 }
663
664 /**************************************************************************/
app_runner()665 app_runner::app_runner()
666 {
667
668 }
669
670 /**************************************************************************/
~app_runner()671 app_runner::~app_runner()
672 {
673
674 }
675
676
677 /**************************************************************************/
HaveStartupScreens(const CArray<widget_info * > * screen_list) const678 BOOL app_runner::HaveStartupScreens(const CArray<widget_info *> *screen_list) const
679 {
680 widget_info *screen;
681
682 for (int index = 0; index < screen_list->GetCount(); index++)
683 {
684 screen = screen_list->GetAt(index);
685
686 if (screen->visible_at_startup)
687 {
688 return TRUE;
689 }
690 }
691 return FALSE;
692 }
693
694
695 /**************************************************************************/
RunApplication(int display_index,CWnd * parent)696 void app_runner::RunApplication(int display_index, CWnd *parent)
697 {
698 GX_WIN32_DISPLAY_DRIVER_DATA *data;
699
700 int memsize;
701 UCHAR *canvas_memory;
702 GX_DISPLAY *app_display;
703 GX_CANVAS *app_canvas;
704 GX_WINDOW_ROOT *app_root;
705 GX_BOOL status = GX_FALSE;
706 GX_RECTANGLE size;
707 CArray<widget_info *> screen_list;
708 widget_info *screen;
709 display_info *info;
710
711 studiox_project *project = GetOpenProject();
712
713 if (project)
714 {
715 info = &project->mDisplays[display_index];
716
717 if (!info)
718 {
719 ErrorMsg("Internal Error: Invalid display", parent);
720 return;
721 }
722
723 GetProjectView()->GetTopLevelWidgetList(display_index, &screen_list);
724
725 if (!HaveStartupScreens(&screen_list))
726 {
727 ErrorMsg("No startup screen(s) have been defined, cannot run application", parent);
728 return;
729 }
730
731 int canvas_xres = info->xres;
732 int canvas_yres = info->yres;
733
734 if (info->rotation_angle == GX_SCREEN_ROTATION_CCW ||
735 info->rotation_angle == GX_SCREEN_ROTATION_CW)
736 {
737 GX_SWAP_VALS(canvas_xres, canvas_yres);
738 }
739
740 app_display = new GX_DISPLAY;
741 int active_theme = project->mDisplays[display_index].active_theme;
742
743 memsize = guix_create_app_display(app_display, "GUIX App Display",
744 canvas_xres, canvas_yres,
745 info->colorformat,
746 project->mHeader.target_cpu,
747 IsRenesasDave2D(project),
748 IsDave2dFontFormat(project, display_index),
749 info->themes[active_theme].palette,
750 info->themes[active_theme].palette_total_size,
751 project->mHeader.palette_mode_aa_text_colors);
752
753 if (memsize)
754 {
755 data = (GX_WIN32_DISPLAY_DRIVER_DATA *) app_display->gx_display_driver_data;
756
757 if (!data)
758 {
759 ErrorMsg("Internal Error: Invalid display driver data", parent);
760 delete app_display;
761 return;
762 }
763
764 GetResourceView()->BuildResourceTables(display_index, app_display, FALSE);
765
766 canvas_memory = new UCHAR[memsize];
767 app_canvas = new GX_CANVAS;
768 app_root = new GX_WINDOW_ROOT;
769
770 app_animation_created_list = GX_NULL;
771 app_animation_id = 1024;
772
773 // save the dynamically allocated control block pointers, so that we can clean up
774 // when the Win32 window is closed:
775
776 data->win32_canvas = app_canvas;
777 data->win32_root_win = app_root;
778 data->win32_display = app_display;
779
780 data->win32_window_xpos = project->mHeader.app_execute_xpos;
781 data->win32_window_ypos = project->mHeader.app_execute_ypos;
782
783 gx_canvas_create(app_canvas, "GUIX App Canvas",
784 app_display, GX_CANVAS_MANAGED | GX_CANVAS_VISIBLE,
785 canvas_xres, canvas_yres, (GX_COLOR *) canvas_memory, memsize);
786
787 /* Create a background root window and attach to the background canvas. */
788
789 gx_utility_rectangle_define(&size, 0, 0, canvas_xres - 1, canvas_yres - 1);
790 gx_window_root_create(app_root, "GUIX App Root Window", app_canvas,
791 GX_STYLE_BORDER_NONE, GX_ID_NONE, &size);
792
793 gx_widget_event_process_set(app_root, app_root_event_process);
794
795 int screen_count = 0;
796 for (int index = 0; index < screen_list.GetCount(); index++)
797 {
798 screen = screen_list.GetAt(index);
799 if (screen->is_template)
800 {
801 continue;
802 }
803 screen_count++;
804 }
805
806 data->win32_screen_count = screen_count;
807 data->win32_screens = new GX_WIDGET *[screen_count];
808 data->win32_display_index = display_index;
809
810 screen_count = 0;
811
812 for (int index = 0; index < screen_list.GetCount(); index++)
813 {
814 screen = screen_list.GetAt(index);
815
816 if (screen->is_template)
817 {
818 continue;
819 }
820
821 data->win32_screens[screen_count] = widget_factory::GenerateAppScreen(NULL, screen);
822 if (screen->visible_at_startup)
823 {
824 gx_widget_attach(app_root, data->win32_screens[screen_count]);
825 }
826
827 screen_count++;
828 }
829
830 /* create a Windows thread, hand off the configured canvas/display/root window */
831 CreateThread(NULL, GX_WIN32_STACK_SIZE, (LPTHREAD_START_ROUTINE) gx_win32_studio_driver_thread_entry, data, 0, (LPDWORD)&data->win32_window_ThreadId);
832
833 /* create a Windows thread to execute the GUIX event loop */
834 CreateThread(NULL, GX_WIN32_STACK_SIZE, (LPTHREAD_START_ROUTINE) guix_execute_thread, data, 0, (LPDWORD)&data->win32_guix_ThreadId);
835
836 gx_widget_show((GX_WIDGET *)app_root);
837 }
838 else
839 {
840 delete app_display;
841 }
842 }
843 }
844
845
846