Mercurial > repos > rhope
diff ms_window.c @ 0:76568becd6d6
Rhope Alpha 2a source import
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Tue, 28 Apr 2009 23:06:07 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ms_window.c Tue Apr 28 23:06:07 2009 +0000 @@ -0,0 +1,295 @@ +#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; +}