Mercurial > repos > rhope
view ms_window.c @ 74:a844c623c7df
Add support for Worker type
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 01 Jul 2010 21:32:08 -0400 |
parents | 76568becd6d6 |
children |
line wrap: on
line source
#include "datum.h" #include "structs.h" #include "ms_window.h" #include "interp.h" #include <string.h> #include <Windows.h> extern HINSTANCE glob_instance; extern int glob_cmd_show; char class_name[] = "RhopeApp"; BOOL started_message_thread = FALSE; HWND * handle_list; size_t handle_list_storage; size_t handle_list_entries=0; datum ** window_list; datum * find_window(HWND window_handle) { size_t i; datum * returnval = NULL; VIS_EnterCriticalSection(hwnd_lock); for(i = 0; i < handle_list_entries; ++i) if(handle_list[i] == window_handle) { returnval = window_list[i]; break; } VIS_LeaveCriticalSection(hwnd_lock); return returnval; } LRESULT CALLBACK process_message (HWND window_handle, UINT message, WPARAM wparam, LPARAM lparam) { datum * params[2]; datum * window_dat; datum * worker; queue_entry entry; vis_window_shown * window; char buf[256]; switch (message) { case WM_COMMAND: if(HIWORD(wparam) == BN_CLICKED) { DEBUGPRINTF("Looking for window with handle %X\n", (int)window_handle); window_dat = find_window(window_handle); DEBUGPRINTF("Found %X\n", window_dat); window = window_dat->c.generic.data; window->instance.in_queue_count = window->instance.in_progress_count = 1000; entry.instance = &(window->instance); DEBUGPRINTF("Looking for handler for message %d\n", LOWORD(wparam)); worker = add_ref(((list_data *)(window->handler_list->c.generic.data))->entries[LOWORD(wparam)]); params[0] = create_list(((worker_datum *)(worker->c.generic.data))->def->program); params[1] = add_ref(window_dat); DEBUGPUTS("Appending param to list\n"); vis_list_append(params, &entry); params[1] = params[0]; params[0] = worker; DEBUGPUTS("Calling handler\n"); vis_worker_do(params, &entry); } break; case WM_DESTROY: PostQuitMessage (0); break; } return DefWindowProc (window_handle, message, wparam, lparam); } DWORD WINAPI window_thread(datum * show_datum) { list_data * list; datum * params[3]; int flags; int j; vis_window * window; double xpos, ypos; datum * widget_datum; vis_widget * widget; char buf[256]; vis_window_shown * window_show = show_datum->c.generic.data; MSG message; HWND window_handle; HWND widget_handle; // Define the Window Class and try to register it WNDCLASSEX wc; wc.cbSize = sizeof (WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = process_message; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = glob_instance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH) COLOR_BACKGROUND; wc.lpszMenuName = NULL; wc.lpszClassName = class_name; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx (&wc)) return 0; // Create and Show the Window window_handle = CreateWindowEx ( 0, class_name, window_show->title->c.generic.data, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, window_show->width, window_show->height, HWND_DESKTOP, NULL, glob_instance, NULL); //release_ref(show_datum); VIS_EnterCriticalSection(hwnd_lock); if(!handle_list) { window_list = malloc(sizeof(datum *) * START_HANDLE_LIST); handle_list = malloc(sizeof(HWND) * START_HANDLE_LIST); handle_list_storage = START_HANDLE_LIST; } else if(handle_list_entries == handle_list_storage) { handle_list_storage += START_HANDLE_LIST; handle_list = realloc(handle_list, sizeof(HWND) * handle_list_storage); window_list = realloc(window_list, sizeof(datum *) * handle_list_storage); } window_list[handle_list_entries] = show_datum; handle_list[handle_list_entries++] = window_handle; VIS_LeaveCriticalSection(hwnd_lock); if(window_show->orig_window) { window = window_show->orig_window->c.generic.data; list = (list_data *)(window->id_list->c.generic.data); for(j = 0; j < list->num_entries; ++j) { DEBUGPRINTF("Retrieving widget %d\n", j); params[0] = add_ref(window->widget_dict); params[1] = add_ref(list->entries[j]); vis_dict_index(params, NULL); widget_datum = params[0]; DEBUGPRINTF("Retrieving xpos for widget: %d\n", j); params[0] = add_ref(window->widget_xpos); params[1] = add_ref(list->entries[j]); DEBUGPUTS("Calling vis_dict_index(params, NULL) for xpos\n"); vis_dict_index(params, NULL); DEBUGPUTS("After vis_dict_index\n"); xpos = params[0]->c.real; DEBUGPUTS("Releasing xpos datum\n"); release_ref(params[0]); DEBUGPRINTF("Retrieving ypos for widget: %d\n", j); params[0] = add_ref(window->widget_ypos); params[1] = add_ref(list->entries[j]); DEBUGPUTS("Calling vis_dict_index(params, NULL) for ypos\n"); vis_dict_index(params, NULL); DEBUGPUTS("After vis_dict_index\n"); ypos = params[0]->c.real; DEBUGPUTS("Releasing ypos datum\n"); release_ref(params[0]); widget = (vis_widget *)(widget_datum->c.generic.data); DEBUGPUTS("Instantiating OS native widget object\n"); switch(widget_datum->company->type_id) { case BUILTIN_TYPE_BUTTON: DEBUGPRINTF("new os::Button() with label %s and message code %d\n", widget->label->c.generic.data, (((list_data *)(window_show->handler_list->c.generic.data))->num_entries)); widget_handle = CreateWindow("Button", widget->label->c.generic.data, WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, xpos, ypos, widget->width, widget->height, window_handle, (HMENU)(((list_data *)(window_show->handler_list->c.generic.data))->num_entries), GetModuleHandle(NULL), NULL); params[0] = add_ref(widget->handler_dict); params[1] = new_datum_comp(widget->label->company, 1, 6);//click strcpy((char *)(params[1]->c.generic.data), "click"); vis_dict_index(params, NULL); params[1] = params[0]; params[0] = window_show->handler_list; vis_list_append(params, NULL); window_show->handler_list = params[0]; break; case BUILTIN_TYPE_INPUTBOX: flags = WS_VISIBLE | WS_CHILD | WS_BORDER; switch(widget->flags) { case 1: flags |= ES_MULTILINE; break; case 2: flags |= ES_NUMBER; break; case 3: flags |= ES_PASSWORD; break; case 4: flags |= ES_READONLY; break; default: break; } DEBUGPRINTF("Adding inputbox with label %s, xpos %d, ypos %d, width %d, height %d\n", (list->entries[j]->c.generic.data), (int)xpos, (int)ypos, (int)widget->width, (int)widget->height); widget_handle = CreateWindow( "Edit", "", flags, xpos, ypos, widget->width, widget->height, window_handle, (HMENU) 0, GetModuleHandle(NULL), NULL); break; //TODO: Error handling? } params[0] = window_show->widget_handle_lookup; params[1] = add_ref(list->entries[j]); params[2] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, window_show->instance.def->program); params[2]->c.integers.num_a = (int)widget_handle; vis_dict_set(params, NULL); window_show->widget_handle_lookup = params[0]; } } ShowWindow (window_handle, glob_cmd_show); while(GetMessage(&message, NULL, 0, 0)) { TranslateMessage(&message); DispatchMessage(&message); } vis_window_closed(show_datum); //TODO remove handle and datum from list return 0; } int vis_window_get_value(datum ** inputlist, queue_entry * worker_entry) { //TODO: Use WM_GETTEXTLEN? message to determine size of string in text box vis_window_shown * window = inputlist[0]->c.generic.data; datum * params[2]; datum * output = new_datum(BUILTIN_TYPE_STRING, 1, 100, worker_entry->instance->def->program); params[0] = add_ref(window->widget_handle_lookup); params[1] = inputlist[1]; vis_dict_index(params, NULL); if(params[0]) SendMessage((HWND)params[0]->c.integers.num_a, WM_GETTEXT, 100, (LPARAM)(output->c.generic.data)); else { *((char*)(output->c.generic.data)) = '\0'; output->c.generic.len = 1; } release_ref(inputlist[0]); inputlist[0] = output; return 0; } int vis_window_set_value(datum ** inputlist, queue_entry * worker_entry) { vis_window_shown * window = inputlist[0]->c.generic.data; datum * params[2]; datum * output = new_datum(BUILTIN_TYPE_STRING, 1, 100, worker_entry->instance->def->program); params[0] = add_ref(window->widget_handle_lookup); params[1] = inputlist[1]; vis_dict_index(params, NULL); if(params[0]) SendMessage((HWND)params[0]->c.integers.num_a, WM_SETTEXT, 0, (LPARAM)(inputlist[2]->c.generic.data)); release_ref(inputlist[0]); release_ref(inputlist[2]); return 0; } int vis_window_show(datum ** inputlist, queue_entry * worker_entry) { vis_window * window = inputlist[0]->c.generic.data; vis_window_shown * window_show; datum * show_datum; show_datum = new_datum(BUILTIN_TYPE_WINDOW_SHOWN, 1, sizeof(vis_window_shown), worker_entry->instance->def->program); window_show = (vis_window_shown *)(show_datum->c.generic.data); window_show->title = add_ref(window->title); window_show->width = window->width; window_show->height = window->height; window_show->xpos = inputlist[1]->c.real; release_ref(inputlist[1]); window_show->ypos = inputlist[2]->c.real; release_ref(inputlist[2]); window_show->is_open = TRUE; window_show->wait_entry = NULL; VIS_InitializeCriticalSection(window_show->lock); window_show->instance.def = worker_entry->instance->def; window_show->instance.workerlist = NULL; VIS_InitializeCriticalSection(window_show->instance.counter_lock); window_show->orig_window = inputlist[0]; window_show->handler_list = create_list(worker_entry->instance->def->program); window_show->widget_handle_lookup = create_dict(worker_entry->instance->def->program); inputlist[0] = show_datum; VIS_NewThread(window_thread, add_ref(show_datum)); return 0; }