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;
+}