view ms_window.c @ 75:0083b2f7b3c7

Partially working implementation of List. Modified build scripts to allow use of other compilers. Fixed some bugs involving method implementations on different types returning different numbers of outputs. Added Fold to the 'builtins' in the comipler.
author Mike Pavone <pavone@retrodev.com>
date Tue, 06 Jul 2010 07:52:59 -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;
}