mirror of
https://github.com/azure-rtos/guix.git
synced 2025-01-28 07:03:11 +08:00
846 lines
25 KiB
C++
846 lines
25 KiB
C++
/* Logic to run the application in a standalone window */
|
|
|
|
#include "studiox_includes.h"
|
|
#include "app_runner.h"
|
|
#include "gx_win32_studio_display_driver.h"
|
|
#include "gx_animation.h"
|
|
|
|
#include "gx_api.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
typedef struct APP_ANIMATION_STRUCT{
|
|
GX_ANIMATION *app_animation;
|
|
APP_ANIMATION_STRUCT *app_animation_next;
|
|
INT app_animation_win_thread_id;
|
|
}APP_ANIMATION;
|
|
|
|
APP_ANIMATION *app_animation_created_list;
|
|
UINT app_animation_id;
|
|
extern CString SCREEN_STACK_POP_STRING;
|
|
|
|
/**************************************************************************/
|
|
GX_WIDGET *app_child_widget_find(GX_WIDGET *parent, CString widget_name)
|
|
{
|
|
GX_WIDGET *child;
|
|
CString name;
|
|
GX_WIDGET *found = GX_NULL;
|
|
|
|
/* Is there a widget? */
|
|
if (parent)
|
|
{
|
|
child = parent->gx_widget_first_child;
|
|
|
|
while (child)
|
|
{
|
|
name = (TCHAR *)child->gx_widget_name;
|
|
if (name == widget_name)
|
|
{
|
|
found = child;
|
|
}
|
|
else if (child->gx_widget_first_child)
|
|
{
|
|
found = app_child_widget_find(child, widget_name);
|
|
}
|
|
|
|
if (found)
|
|
{
|
|
break;
|
|
}
|
|
|
|
child = child->gx_widget_next;
|
|
}
|
|
}
|
|
|
|
if ((!found) && (parent->gx_widget_type == GX_TYPE_MENU))
|
|
{
|
|
GX_MENU *menu = (GX_MENU *)parent;
|
|
found = app_child_widget_find((GX_WIDGET *)&menu->gx_menu_list, widget_name);
|
|
}
|
|
|
|
return found;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
GX_WIDGET *app_widget_find(GX_WINDOW *root, CString widget_name)
|
|
{
|
|
int loop;
|
|
GX_WIDGET *screen;
|
|
GX_WIDGET *found = GX_NULL;
|
|
GX_WIN32_DISPLAY_DRIVER_DATA *driver_instance;
|
|
GX_DISPLAY *display;
|
|
CString name;
|
|
|
|
display = ((GX_WINDOW_ROOT *)root)->gx_window_root_canvas->gx_canvas_display;
|
|
driver_instance = (GX_WIN32_DISPLAY_DRIVER_DATA *)display->gx_display_driver_data;
|
|
|
|
if (widget_name.IsEmpty())
|
|
{
|
|
return GX_NULL;
|
|
}
|
|
|
|
for (loop = 0; loop < driver_instance->win32_screen_count; loop++)
|
|
{
|
|
screen = driver_instance->win32_screens[loop];
|
|
|
|
if (screen)
|
|
{
|
|
name = (TCHAR *)screen->gx_widget_name;
|
|
if (name == widget_name)
|
|
{
|
|
found = screen;
|
|
}
|
|
else
|
|
{
|
|
found = app_child_widget_find(screen, widget_name);
|
|
}
|
|
|
|
if (found)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return found;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
flow_item *app_flow_item_get(studiox_project *project, int display_index, GX_WIDGET *screen)
|
|
{
|
|
flow_item *flow_item = GX_NULL;
|
|
screen_flow *screen_flow = project->mDisplays[display_index].screenflow;
|
|
|
|
if (screen_flow && screen)
|
|
{
|
|
CString widget_name = (TCHAR *)screen->gx_widget_name;
|
|
flow_item = screen_flow->GetFlowItem(widget_name);
|
|
}
|
|
|
|
return flow_item;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
void app_animation_clean_up(GX_WIN32_DISPLAY_DRIVER_DATA *data)
|
|
{
|
|
APP_ANIMATION *entry = app_animation_created_list;
|
|
APP_ANIMATION *pre = GX_NULL;
|
|
APP_ANIMATION *next;
|
|
|
|
while (entry)
|
|
{
|
|
next = entry->app_animation_next;
|
|
if (entry->app_animation_win_thread_id == data->win32_window_ThreadId)
|
|
{
|
|
if (pre)
|
|
{
|
|
pre->app_animation_next = entry->app_animation_next;
|
|
}
|
|
else
|
|
{
|
|
app_animation_created_list = entry->app_animation_next;
|
|
}
|
|
|
|
if (entry->app_animation->gx_animation_status != GX_ANIMATION_IDLE)
|
|
{
|
|
gx_animation_stop(entry->app_animation);
|
|
}
|
|
|
|
delete entry->app_animation;
|
|
delete entry;
|
|
}
|
|
else
|
|
{
|
|
pre = entry;
|
|
}
|
|
entry = next;
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
GX_ANIMATION *app_animation_create(GX_WINDOW *root, GX_WIDGET *target)
|
|
{
|
|
//Create a animation
|
|
APP_ANIMATION *animation;
|
|
GX_WIN32_DISPLAY_DRIVER_DATA *driver_instance;
|
|
GX_DISPLAY *display;
|
|
|
|
display = ((GX_WINDOW_ROOT *)root)->gx_window_root_canvas->gx_canvas_display;
|
|
driver_instance = (GX_WIN32_DISPLAY_DRIVER_DATA *)display->gx_display_driver_data;
|
|
|
|
animation = new APP_ANIMATION;
|
|
animation->app_animation = new GX_ANIMATION;
|
|
gx_animation_create(animation->app_animation);
|
|
animation->app_animation_win_thread_id = driver_instance->win32_window_ThreadId;
|
|
|
|
GX_ENTER_CRITICAL
|
|
animation->app_animation_next = app_animation_created_list;
|
|
app_animation_created_list = animation;
|
|
GX_EXIT_CRITICAL
|
|
|
|
return animation->app_animation;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
void app_animation_delete(UINT animation_id)
|
|
{
|
|
if (!animation_id)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GX_ENTER_CRITICAL
|
|
// Delete a animation
|
|
APP_ANIMATION *entry = app_animation_created_list;
|
|
APP_ANIMATION *pre = GX_NULL;
|
|
|
|
while (entry)
|
|
{
|
|
if (entry->app_animation->gx_animation_info.gx_animation_id == animation_id)
|
|
{
|
|
if (pre)
|
|
{
|
|
pre->app_animation_next = entry->app_animation_next;
|
|
}
|
|
else
|
|
{
|
|
app_animation_created_list = entry->app_animation_next;
|
|
}
|
|
|
|
delete entry->app_animation;
|
|
delete entry;
|
|
break;
|
|
}
|
|
pre = entry;
|
|
entry = entry->app_animation_next;
|
|
}
|
|
GX_EXIT_CRITICAL
|
|
}
|
|
|
|
/**************************************************************************/
|
|
void app_animation_process(GX_ANIMATION_INFO *animation, GX_WINDOW *root, GX_WIDGET *parent, GX_WIDGET *target)
|
|
{
|
|
GX_ANIMATION *app_animation = app_animation_create(root, target);
|
|
|
|
if (app_animation)
|
|
{
|
|
GX_ANIMATION_INFO info;
|
|
info = *animation;
|
|
info.gx_animation_parent = parent;
|
|
info.gx_animation_target = target;
|
|
|
|
if (!info.gx_animation_id)
|
|
{
|
|
GX_ENTER_CRITICAL
|
|
info.gx_animation_id = app_animation_id;
|
|
app_animation_id++;
|
|
GX_EXIT_CRITICAL
|
|
}
|
|
|
|
gx_animation_start(app_animation, &info);
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
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)
|
|
{
|
|
action_info *action;
|
|
GX_WIDGET *target;
|
|
GX_WIDGET *parent;
|
|
screen_flow *flow = project->mDisplays[display_index].screenflow;
|
|
|
|
//handle child signals
|
|
for (int index = 0; index < action_list->GetCount(); index++)
|
|
{
|
|
action = action_list->GetAt(index);
|
|
|
|
switch (action->action_type)
|
|
{
|
|
case GX_ACTION_TYPE_ATTACH:
|
|
if ((action->target_widget_name == SCREEN_STACK_POP_STRING) ||
|
|
(action->parent_widget_name == SCREEN_STACK_POP_STRING))
|
|
{
|
|
gx_system_screen_stack_get(&parent, &target);
|
|
}
|
|
|
|
if (action->parent_widget_name != SCREEN_STACK_POP_STRING)
|
|
{
|
|
parent = app_widget_find(root, action->parent_widget_name);
|
|
}
|
|
|
|
if (action->target_widget_name != SCREEN_STACK_POP_STRING)
|
|
{
|
|
target = app_widget_find(root, action->target_widget_name);
|
|
}
|
|
|
|
if (!parent)
|
|
{
|
|
parent = (GX_WIDGET *)root;
|
|
}
|
|
|
|
if (parent && target)
|
|
{
|
|
gx_widget_attach(parent, target);
|
|
}
|
|
break;
|
|
|
|
case GX_ACTION_TYPE_WINDOW_EXECUTE:
|
|
if ((action->target_widget_name == SCREEN_STACK_POP_STRING) ||
|
|
(action->parent_widget_name == SCREEN_STACK_POP_STRING))
|
|
{
|
|
gx_system_screen_stack_get(&parent, &target);
|
|
}
|
|
|
|
if (action->parent_widget_name != SCREEN_STACK_POP_STRING)
|
|
{
|
|
parent = app_widget_find(root, action->parent_widget_name);
|
|
}
|
|
|
|
if (action->target_widget_name != SCREEN_STACK_POP_STRING)
|
|
{
|
|
target = app_widget_find(root, action->target_widget_name);
|
|
}
|
|
|
|
if (!parent)
|
|
{
|
|
parent = (GX_WIDGET *)root;
|
|
}
|
|
|
|
if (parent && target && target->gx_widget_type == GX_TYPE_WINDOW)
|
|
{
|
|
gx_widget_attach(parent, target);
|
|
gx_window_execute((GX_WINDOW *)target, GX_NULL);
|
|
}
|
|
break;
|
|
|
|
case GX_ACTION_TYPE_WINDOW_EXECUTE_STOP:
|
|
return event_ptr->gx_event_sender;
|
|
break;
|
|
|
|
case GX_ACTION_TYPE_DETACH:
|
|
if (!action->target_widget_name.IsEmpty())
|
|
{
|
|
target = app_widget_find(root, action->target_widget_name);
|
|
}
|
|
else
|
|
{
|
|
target = screen;
|
|
}
|
|
|
|
if (target)
|
|
{
|
|
gx_widget_hide(target);
|
|
}
|
|
break;
|
|
|
|
case GX_ACTION_TYPE_TOGGLE:
|
|
if (action->target_widget_name == SCREEN_STACK_POP_STRING)
|
|
{
|
|
gx_system_screen_stack_get(&parent, &target);
|
|
}
|
|
else
|
|
{
|
|
target = app_widget_find(root, action->target_widget_name);
|
|
}
|
|
|
|
if (target)
|
|
{
|
|
gx_widget_attach(screen->gx_widget_parent, target);
|
|
gx_widget_hide(screen);
|
|
}
|
|
break;
|
|
|
|
case GX_ACTION_TYPE_SHOW:
|
|
target = app_widget_find(root, action->target_widget_name);
|
|
if (target)
|
|
{
|
|
gx_widget_show(target);
|
|
}
|
|
break;
|
|
|
|
case GX_ACTION_TYPE_HIDE:
|
|
target = app_widget_find(root, action->target_widget_name);
|
|
if (target)
|
|
{
|
|
gx_widget_hide(target);
|
|
}
|
|
break;
|
|
|
|
case GX_ACTION_TYPE_ANIMATION:
|
|
if ((action->target_widget_name == SCREEN_STACK_POP_STRING) ||
|
|
(action->parent_widget_name == SCREEN_STACK_POP_STRING))
|
|
{
|
|
gx_system_screen_stack_get(&parent, &target);
|
|
}
|
|
|
|
if (action->target_widget_name != SCREEN_STACK_POP_STRING)
|
|
{
|
|
target = app_widget_find(root, action->target_widget_name);
|
|
}
|
|
|
|
if (target && action->animation)
|
|
{
|
|
action->animation->gx_animation_id = project->GetIdIndex(display_index, ID_TYPE_ANIMATION, action->animation_id_name);
|
|
if (action->parent_widget_name != SCREEN_STACK_POP_STRING)
|
|
{
|
|
parent = app_widget_find(root, action->parent_widget_name);
|
|
}
|
|
|
|
if (!parent)
|
|
{
|
|
//animation parent is not set
|
|
if (target->gx_widget_parent)
|
|
{
|
|
//set animation parent to widget's parent
|
|
parent = target->gx_widget_parent;
|
|
}
|
|
else
|
|
{
|
|
//set animation parent to root window
|
|
parent = (GX_WIDGET *)root;
|
|
}
|
|
}
|
|
|
|
app_animation_process(action->animation, (GX_WINDOW *)root, parent, target);
|
|
}
|
|
break;
|
|
|
|
case GX_ACTION_TYPE_SCREEN_STACK_PUSH:
|
|
target = app_widget_find(root, action->target_widget_name);
|
|
if (target)
|
|
{
|
|
gx_system_screen_stack_push(target);
|
|
}
|
|
break;
|
|
|
|
case GX_ACTION_TYPE_SCREEN_STACK_POP:
|
|
gx_system_screen_stack_pop();
|
|
break;
|
|
|
|
case GX_ACTION_TYPE_SCREEN_STACK_RESET:
|
|
gx_system_screen_stack_reset();
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**************************************************************************/
|
|
UINT app_root_event_process(GX_WINDOW *root, GX_EVENT *event_ptr)
|
|
{
|
|
studiox_project *project = GetOpenProject();
|
|
UINT status;
|
|
|
|
switch (event_ptr->gx_event_type)
|
|
{
|
|
case GX_EVENT_ANIMATION_COMPLETE:
|
|
app_animation_delete(event_ptr->gx_event_sender);
|
|
break;
|
|
}
|
|
|
|
status = gx_window_event_process(root, event_ptr);
|
|
|
|
if (project && root->gx_widget_first_child)
|
|
{
|
|
BOOL process = GX_FALSE;
|
|
BOOL child_detect;
|
|
int display_index;
|
|
GX_WIDGET *screen = GX_NULL;
|
|
flow_item *flow_item = NULL;
|
|
trigger_info *trigger = GX_NULL;
|
|
GX_WIN32_DISPLAY_DRIVER_DATA *driver_instance;
|
|
GX_DISPLAY *display;
|
|
|
|
display = ((GX_WINDOW_ROOT *)root)->gx_window_root_canvas->gx_canvas_display;
|
|
driver_instance = (GX_WIN32_DISPLAY_DRIVER_DATA *)display->gx_display_driver_data;
|
|
display_index = driver_instance->win32_display_index;
|
|
|
|
// Loop through top level screens
|
|
for (int loop = 0; loop < driver_instance->win32_screen_count; loop++)
|
|
{
|
|
screen = driver_instance->win32_screens[loop];
|
|
|
|
if (event_ptr->gx_event_target)
|
|
{
|
|
if (screen == event_ptr->gx_event_target)
|
|
{
|
|
//the target is current screen
|
|
child_detect = GX_TRUE;
|
|
}
|
|
else
|
|
{
|
|
//is event target a child of current screen?
|
|
gx_widget_child_detect(screen, event_ptr->gx_event_target, &child_detect);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//no target specified
|
|
child_detect = GX_TRUE;
|
|
}
|
|
|
|
if ((!(screen->gx_widget_status | GX_STATUS_VISIBLE)) ||
|
|
(!child_detect))
|
|
{
|
|
screen = screen->gx_widget_next;
|
|
continue;
|
|
}
|
|
|
|
//app_widget_animation_process(project, display_index, root, screen, event_ptr);
|
|
|
|
// Find top level screen
|
|
flow_item = app_flow_item_get(project, display_index, screen);
|
|
|
|
if (flow_item)
|
|
{
|
|
trigger = flow_item->trigger_list;
|
|
}
|
|
|
|
while (trigger)
|
|
{
|
|
CArray<action_info *> *action_list;
|
|
ULONG signal = 0;
|
|
INT id;
|
|
|
|
action_list = &trigger->action_list;
|
|
|
|
switch (trigger->trigger_type)
|
|
{
|
|
case TRIGGER_TYPE_SYSTEM_EVENT:
|
|
if (trigger->event_type == event_ptr->gx_event_type)
|
|
{
|
|
if (event_ptr->gx_event_type == GX_EVENT_ANIMATION_COMPLETE)
|
|
{
|
|
id = project->GetIdIndex(display_index, ID_TYPE_ANIMATION, trigger->system_event_animat_id_name);
|
|
if (event_ptr->gx_event_sender == id)
|
|
{
|
|
process = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
process = TRUE;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case TRIGGER_TYPE_CHILD_SIGNAL:
|
|
id = project->GetIdIndex(display_index, ID_TYPE_WIDGET, trigger->signal_id_name);
|
|
signal = GX_SIGNAL(id, trigger->event_type);
|
|
|
|
if (signal == event_ptr->gx_event_type)
|
|
{
|
|
process = TRUE;
|
|
}
|
|
break;
|
|
|
|
case TRIGGER_TYPE_USER_EVENT:
|
|
break;
|
|
}
|
|
|
|
if (process)
|
|
{
|
|
return app_trigger_action_process(project, display_index, root, action_list, screen, event_ptr);
|
|
}
|
|
trigger = trigger->next;
|
|
}
|
|
|
|
screen = screen->gx_widget_next;
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
extern "C" {
|
|
|
|
/**************************************************************************/
|
|
// This function is called by the application execution thread when the
|
|
// Windows window into which the application is rendering is closed. Cleanup
|
|
// the canvas, display, and root window
|
|
/**************************************************************************/
|
|
|
|
VOID guix_cleanup_win32_canvas(GX_WIN32_DISPLAY_DRIVER_DATA *driver)
|
|
{
|
|
GX_WIDGET *screen;
|
|
int loop;
|
|
|
|
if (driver->win32_canvas)
|
|
{
|
|
gx_widget_hide((GX_WIDGET *)driver->win32_root_win);
|
|
if (driver->win32_canvas->gx_canvas_memory)
|
|
{
|
|
delete (driver->win32_canvas->gx_canvas_memory);
|
|
}
|
|
|
|
resource_view::CleanupDisplayResources(driver->win32_display);
|
|
|
|
guix_studio_delete_display(driver->win32_display);
|
|
delete(driver->win32_display);
|
|
|
|
while(driver->win32_root_win->gx_widget_first_child)
|
|
{
|
|
screen = driver->win32_root_win->gx_widget_first_child;
|
|
gx_widget_detach(screen);
|
|
}
|
|
gx_window_root_delete(driver->win32_root_win);
|
|
delete(driver->win32_root_win);
|
|
|
|
// make sure none of the top level screen are attached to each other:
|
|
for (loop = 0; loop < driver->win32_screen_count; loop++)
|
|
{
|
|
screen = driver->win32_screens[loop];
|
|
|
|
if (screen)
|
|
{
|
|
if (screen->gx_widget_parent)
|
|
{
|
|
gx_widget_detach(screen);
|
|
}
|
|
}
|
|
}
|
|
|
|
// now delete each of the top level screens:
|
|
for (loop = 0; loop < driver->win32_screen_count; loop++)
|
|
{
|
|
screen = driver->win32_screens[loop];
|
|
|
|
if (screen)
|
|
{
|
|
widget_factory::DeleteWidgets(screen);
|
|
}
|
|
}
|
|
if (driver->win32_screens)
|
|
{
|
|
delete [] driver->win32_screens;
|
|
}
|
|
|
|
gx_canvas_delete(driver->win32_canvas);
|
|
delete driver->win32_canvas;
|
|
|
|
memset(driver, 0, sizeof(GX_WIN32_DISPLAY_DRIVER_DATA));
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
void guix_execute_thread(ULONG thread_input)
|
|
{
|
|
GX_WIN32_DISPLAY_DRIVER_DATA *data;
|
|
|
|
studiox_project *project = GetOpenProject();
|
|
|
|
if (!project)
|
|
{
|
|
return;
|
|
}
|
|
|
|
data = (GX_WIN32_DISPLAY_DRIVER_DATA *)thread_input;
|
|
|
|
screen_flow *flow = project->mDisplays[data->win32_display_index].screenflow;
|
|
int size = flow->GetFlowListCount() * 2;
|
|
GX_WIDGET **memory = new GX_WIDGET*[size];
|
|
_gx_system_screen_stack_create(memory, sizeof(GX_WIDGET *)* size);
|
|
|
|
_gx_system_thread_entry(0);
|
|
|
|
app_animation_clean_up(data);
|
|
|
|
//save current win32 window position
|
|
project->mHeader.app_execute_xpos = data->win32_window_xpos;
|
|
project->mHeader.app_execute_ypos = data->win32_window_ypos;
|
|
|
|
//delete system screen stack memory
|
|
delete _gx_system_screen_stack.gx_screen_stack_control_memory;
|
|
|
|
guix_cleanup_win32_canvas(data);
|
|
|
|
ExitThread(0);
|
|
}
|
|
}
|
|
|
|
/**************************************************************************/
|
|
app_runner::app_runner()
|
|
{
|
|
|
|
}
|
|
|
|
/**************************************************************************/
|
|
app_runner::~app_runner()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
BOOL app_runner::HaveStartupScreens(const CArray<widget_info *> *screen_list) const
|
|
{
|
|
widget_info *screen;
|
|
|
|
for (int index = 0; index < screen_list->GetCount(); index++)
|
|
{
|
|
screen = screen_list->GetAt(index);
|
|
|
|
if (screen->visible_at_startup)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**************************************************************************/
|
|
void app_runner::RunApplication(int display_index, CWnd *parent)
|
|
{
|
|
GX_WIN32_DISPLAY_DRIVER_DATA *data;
|
|
|
|
int memsize;
|
|
UCHAR *canvas_memory;
|
|
GX_DISPLAY *app_display;
|
|
GX_CANVAS *app_canvas;
|
|
GX_WINDOW_ROOT *app_root;
|
|
GX_BOOL status = GX_FALSE;
|
|
GX_RECTANGLE size;
|
|
CArray<widget_info *> screen_list;
|
|
widget_info *screen;
|
|
display_info *info;
|
|
|
|
studiox_project *project = GetOpenProject();
|
|
|
|
if (project)
|
|
{
|
|
info = &project->mDisplays[display_index];
|
|
|
|
if (!info)
|
|
{
|
|
ErrorMsg("Internal Error: Invalid display", parent);
|
|
return;
|
|
}
|
|
|
|
GetProjectView()->GetTopLevelWidgetList(display_index, &screen_list);
|
|
|
|
if (!HaveStartupScreens(&screen_list))
|
|
{
|
|
ErrorMsg("No startup screen(s) have been defined, cannot run application", parent);
|
|
return;
|
|
}
|
|
|
|
int canvas_xres = info->xres;
|
|
int canvas_yres = info->yres;
|
|
|
|
if (info->rotation_angle == GX_SCREEN_ROTATION_CCW ||
|
|
info->rotation_angle == GX_SCREEN_ROTATION_CW)
|
|
{
|
|
GX_SWAP_VALS(canvas_xres, canvas_yres);
|
|
}
|
|
|
|
app_display = new GX_DISPLAY;
|
|
int active_theme = project->mDisplays[display_index].active_theme;
|
|
|
|
memsize = guix_create_app_display(app_display, "GUIX App Display",
|
|
canvas_xres, canvas_yres,
|
|
info->colorformat,
|
|
project->mHeader.target_cpu,
|
|
IsRenesasDave2D(project),
|
|
IsDave2dFontFormat(project, display_index),
|
|
info->themes[active_theme].palette,
|
|
info->themes[active_theme].palette_total_size,
|
|
project->mHeader.palette_mode_aa_text_colors);
|
|
|
|
if (memsize)
|
|
{
|
|
data = (GX_WIN32_DISPLAY_DRIVER_DATA *) app_display->gx_display_driver_data;
|
|
|
|
if (!data)
|
|
{
|
|
ErrorMsg("Internal Error: Invalid display driver data", parent);
|
|
delete app_display;
|
|
return;
|
|
}
|
|
|
|
GetResourceView()->BuildResourceTables(display_index, app_display, FALSE);
|
|
|
|
canvas_memory = new UCHAR[memsize];
|
|
app_canvas = new GX_CANVAS;
|
|
app_root = new GX_WINDOW_ROOT;
|
|
|
|
app_animation_created_list = GX_NULL;
|
|
app_animation_id = 1024;
|
|
|
|
// save the dynamically allocated control block pointers, so that we can clean up
|
|
// when the Win32 window is closed:
|
|
|
|
data->win32_canvas = app_canvas;
|
|
data->win32_root_win = app_root;
|
|
data->win32_display = app_display;
|
|
|
|
data->win32_window_xpos = project->mHeader.app_execute_xpos;
|
|
data->win32_window_ypos = project->mHeader.app_execute_ypos;
|
|
|
|
gx_canvas_create(app_canvas, "GUIX App Canvas",
|
|
app_display, GX_CANVAS_MANAGED | GX_CANVAS_VISIBLE,
|
|
canvas_xres, canvas_yres, (GX_COLOR *) canvas_memory, memsize);
|
|
|
|
/* Create a background root window and attach to the background canvas. */
|
|
|
|
gx_utility_rectangle_define(&size, 0, 0, canvas_xres - 1, canvas_yres - 1);
|
|
gx_window_root_create(app_root, "GUIX App Root Window", app_canvas,
|
|
GX_STYLE_BORDER_NONE, GX_ID_NONE, &size);
|
|
|
|
gx_widget_event_process_set(app_root, app_root_event_process);
|
|
|
|
int screen_count = 0;
|
|
for (int index = 0; index < screen_list.GetCount(); index++)
|
|
{
|
|
screen = screen_list.GetAt(index);
|
|
if (screen->is_template)
|
|
{
|
|
continue;
|
|
}
|
|
screen_count++;
|
|
}
|
|
|
|
data->win32_screen_count = screen_count;
|
|
data->win32_screens = new GX_WIDGET *[screen_count];
|
|
data->win32_display_index = display_index;
|
|
|
|
screen_count = 0;
|
|
|
|
for (int index = 0; index < screen_list.GetCount(); index++)
|
|
{
|
|
screen = screen_list.GetAt(index);
|
|
|
|
if (screen->is_template)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
data->win32_screens[screen_count] = widget_factory::GenerateAppScreen(NULL, screen);
|
|
if (screen->visible_at_startup)
|
|
{
|
|
gx_widget_attach(app_root, data->win32_screens[screen_count]);
|
|
}
|
|
|
|
screen_count++;
|
|
}
|
|
|
|
/* create a Windows thread, hand off the configured canvas/display/root window */
|
|
CreateThread(NULL, GX_WIN32_STACK_SIZE, (LPTHREAD_START_ROUTINE) gx_win32_studio_driver_thread_entry, data, 0, (LPDWORD)&data->win32_window_ThreadId);
|
|
|
|
/* create a Windows thread to execute the GUIX event loop */
|
|
CreateThread(NULL, GX_WIN32_STACK_SIZE, (LPTHREAD_START_ROUTINE) guix_execute_thread, data, 0, (LPDWORD)&data->win32_guix_ThreadId);
|
|
|
|
gx_widget_show((GX_WIDGET *)app_root);
|
|
}
|
|
else
|
|
{
|
|
delete app_display;
|
|
}
|
|
}
|
|
}
|
|
|
|
|