Mercurial > repos > rhope
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:76568becd6d6 |
---|---|
1 #include "datum.h" | |
2 #include "structs.h" | |
3 #include "ms_window.h" | |
4 #include "interp.h" | |
5 #include <string.h> | |
6 #include <Windows.h> | |
7 | |
8 extern HINSTANCE glob_instance; | |
9 extern int glob_cmd_show; | |
10 | |
11 char class_name[] = "RhopeApp"; | |
12 | |
13 BOOL started_message_thread = FALSE; | |
14 HWND * handle_list; | |
15 size_t handle_list_storage; | |
16 size_t handle_list_entries=0; | |
17 datum ** window_list; | |
18 | |
19 | |
20 datum * find_window(HWND window_handle) | |
21 { | |
22 size_t i; | |
23 datum * returnval = NULL; | |
24 VIS_EnterCriticalSection(hwnd_lock); | |
25 for(i = 0; i < handle_list_entries; ++i) | |
26 if(handle_list[i] == window_handle) | |
27 { | |
28 returnval = window_list[i]; | |
29 break; | |
30 } | |
31 VIS_LeaveCriticalSection(hwnd_lock); | |
32 return returnval; | |
33 } | |
34 | |
35 | |
36 LRESULT CALLBACK process_message (HWND window_handle, UINT message, WPARAM wparam, LPARAM lparam) | |
37 { | |
38 datum * params[2]; | |
39 datum * window_dat; | |
40 datum * worker; | |
41 queue_entry entry; | |
42 vis_window_shown * window; | |
43 char buf[256]; | |
44 switch (message) | |
45 { | |
46 | |
47 case WM_COMMAND: | |
48 if(HIWORD(wparam) == BN_CLICKED) | |
49 { | |
50 DEBUGPRINTF("Looking for window with handle %X\n", (int)window_handle); | |
51 window_dat = find_window(window_handle); | |
52 DEBUGPRINTF("Found %X\n", window_dat); | |
53 window = window_dat->c.generic.data; | |
54 window->instance.in_queue_count = window->instance.in_progress_count = 1000; | |
55 entry.instance = &(window->instance); | |
56 DEBUGPRINTF("Looking for handler for message %d\n", LOWORD(wparam)); | |
57 worker = add_ref(((list_data *)(window->handler_list->c.generic.data))->entries[LOWORD(wparam)]); | |
58 params[0] = create_list(((worker_datum *)(worker->c.generic.data))->def->program); | |
59 params[1] = add_ref(window_dat); | |
60 DEBUGPUTS("Appending param to list\n"); | |
61 vis_list_append(params, &entry); | |
62 params[1] = params[0]; | |
63 params[0] = worker; | |
64 DEBUGPUTS("Calling handler\n"); | |
65 vis_worker_do(params, &entry); | |
66 } | |
67 break; | |
68 | |
69 case WM_DESTROY: | |
70 PostQuitMessage (0); | |
71 break; | |
72 } | |
73 return DefWindowProc (window_handle, message, wparam, lparam); | |
74 } | |
75 | |
76 DWORD WINAPI window_thread(datum * show_datum) | |
77 { | |
78 list_data * list; | |
79 datum * params[3]; | |
80 int flags; | |
81 int j; | |
82 vis_window * window; | |
83 double xpos, ypos; | |
84 datum * widget_datum; | |
85 vis_widget * widget; | |
86 char buf[256]; | |
87 vis_window_shown * window_show = show_datum->c.generic.data; | |
88 MSG message; | |
89 HWND window_handle; | |
90 HWND widget_handle; | |
91 // Define the Window Class and try to register it | |
92 WNDCLASSEX wc; | |
93 wc.cbSize = sizeof (WNDCLASSEX); | |
94 wc.style = 0; | |
95 wc.lpfnWndProc = process_message; | |
96 wc.cbClsExtra = 0; | |
97 wc.cbWndExtra = 0; | |
98 wc.hInstance = glob_instance; | |
99 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); | |
100 wc.hCursor = LoadCursor(NULL, IDC_ARROW); | |
101 wc.hbrBackground = (HBRUSH) COLOR_BACKGROUND; | |
102 wc.lpszMenuName = NULL; | |
103 wc.lpszClassName = class_name; | |
104 wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); | |
105 if (!RegisterClassEx (&wc)) return 0; | |
106 | |
107 // Create and Show the Window | |
108 window_handle = CreateWindowEx ( | |
109 0, class_name, window_show->title->c.generic.data, | |
110 WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, | |
111 window_show->width, window_show->height, | |
112 HWND_DESKTOP, NULL, glob_instance, NULL); | |
113 //release_ref(show_datum); | |
114 | |
115 VIS_EnterCriticalSection(hwnd_lock); | |
116 | |
117 if(!handle_list) | |
118 { | |
119 window_list = malloc(sizeof(datum *) * START_HANDLE_LIST); | |
120 handle_list = malloc(sizeof(HWND) * START_HANDLE_LIST); | |
121 handle_list_storage = START_HANDLE_LIST; | |
122 } | |
123 else if(handle_list_entries == handle_list_storage) | |
124 { | |
125 handle_list_storage += START_HANDLE_LIST; | |
126 handle_list = realloc(handle_list, sizeof(HWND) * handle_list_storage); | |
127 window_list = realloc(window_list, sizeof(datum *) * handle_list_storage); | |
128 } | |
129 window_list[handle_list_entries] = show_datum; | |
130 handle_list[handle_list_entries++] = window_handle; | |
131 VIS_LeaveCriticalSection(hwnd_lock); | |
132 | |
133 if(window_show->orig_window) | |
134 { | |
135 window = window_show->orig_window->c.generic.data; | |
136 list = (list_data *)(window->id_list->c.generic.data); | |
137 for(j = 0; j < list->num_entries; ++j) | |
138 { | |
139 DEBUGPRINTF("Retrieving widget %d\n", j); | |
140 params[0] = add_ref(window->widget_dict); | |
141 params[1] = add_ref(list->entries[j]); | |
142 vis_dict_index(params, NULL); | |
143 widget_datum = params[0]; | |
144 DEBUGPRINTF("Retrieving xpos for widget: %d\n", j); | |
145 params[0] = add_ref(window->widget_xpos); | |
146 params[1] = add_ref(list->entries[j]); | |
147 DEBUGPUTS("Calling vis_dict_index(params, NULL) for xpos\n"); | |
148 vis_dict_index(params, NULL); | |
149 DEBUGPUTS("After vis_dict_index\n"); | |
150 xpos = params[0]->c.real; | |
151 DEBUGPUTS("Releasing xpos datum\n"); | |
152 release_ref(params[0]); | |
153 DEBUGPRINTF("Retrieving ypos for widget: %d\n", j); | |
154 params[0] = add_ref(window->widget_ypos); | |
155 params[1] = add_ref(list->entries[j]); | |
156 DEBUGPUTS("Calling vis_dict_index(params, NULL) for ypos\n"); | |
157 vis_dict_index(params, NULL); | |
158 DEBUGPUTS("After vis_dict_index\n"); | |
159 ypos = params[0]->c.real; | |
160 DEBUGPUTS("Releasing ypos datum\n"); | |
161 release_ref(params[0]); | |
162 widget = (vis_widget *)(widget_datum->c.generic.data); | |
163 DEBUGPUTS("Instantiating OS native widget object\n"); | |
164 switch(widget_datum->company->type_id) | |
165 { | |
166 case BUILTIN_TYPE_BUTTON: | |
167 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)); | |
168 widget_handle = CreateWindow("Button", widget->label->c.generic.data, | |
169 WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, | |
170 xpos, ypos, widget->width, widget->height, | |
171 window_handle, (HMENU)(((list_data *)(window_show->handler_list->c.generic.data))->num_entries), | |
172 GetModuleHandle(NULL), NULL); | |
173 params[0] = add_ref(widget->handler_dict); | |
174 params[1] = new_datum_comp(widget->label->company, 1, 6);//click | |
175 strcpy((char *)(params[1]->c.generic.data), "click"); | |
176 vis_dict_index(params, NULL); | |
177 params[1] = params[0]; | |
178 params[0] = window_show->handler_list; | |
179 vis_list_append(params, NULL); | |
180 window_show->handler_list = params[0]; | |
181 break; | |
182 case BUILTIN_TYPE_INPUTBOX: | |
183 flags = WS_VISIBLE | WS_CHILD | WS_BORDER; | |
184 switch(widget->flags) | |
185 { | |
186 case 1: | |
187 flags |= ES_MULTILINE; | |
188 break; | |
189 case 2: | |
190 flags |= ES_NUMBER; | |
191 break; | |
192 case 3: | |
193 flags |= ES_PASSWORD; | |
194 break; | |
195 case 4: | |
196 flags |= ES_READONLY; | |
197 break; | |
198 default: | |
199 break; | |
200 } | |
201 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); | |
202 widget_handle = CreateWindow( | |
203 "Edit", "", | |
204 flags, | |
205 xpos, ypos, widget->width, widget->height, | |
206 window_handle, (HMENU) 0, | |
207 GetModuleHandle(NULL), NULL); | |
208 break; | |
209 //TODO: Error handling? | |
210 } | |
211 params[0] = window_show->widget_handle_lookup; | |
212 params[1] = add_ref(list->entries[j]); | |
213 params[2] = new_datum(BUILTIN_TYPE_WHOLE, 2, 0, window_show->instance.def->program); | |
214 params[2]->c.integers.num_a = (int)widget_handle; | |
215 vis_dict_set(params, NULL); | |
216 window_show->widget_handle_lookup = params[0]; | |
217 } | |
218 } | |
219 ShowWindow (window_handle, glob_cmd_show); | |
220 while(GetMessage(&message, NULL, 0, 0)) | |
221 { | |
222 TranslateMessage(&message); | |
223 DispatchMessage(&message); | |
224 } | |
225 vis_window_closed(show_datum); | |
226 //TODO remove handle and datum from list | |
227 return 0; | |
228 } | |
229 | |
230 int vis_window_get_value(datum ** inputlist, queue_entry * worker_entry) | |
231 { | |
232 //TODO: Use WM_GETTEXTLEN? message to determine size of string in text box | |
233 vis_window_shown * window = inputlist[0]->c.generic.data; | |
234 datum * params[2]; | |
235 datum * output = new_datum(BUILTIN_TYPE_STRING, 1, 100, worker_entry->instance->def->program); | |
236 params[0] = add_ref(window->widget_handle_lookup); | |
237 params[1] = inputlist[1]; | |
238 vis_dict_index(params, NULL); | |
239 if(params[0]) | |
240 SendMessage((HWND)params[0]->c.integers.num_a, WM_GETTEXT, 100, (LPARAM)(output->c.generic.data)); | |
241 else | |
242 { | |
243 *((char*)(output->c.generic.data)) = '\0'; | |
244 output->c.generic.len = 1; | |
245 } | |
246 release_ref(inputlist[0]); | |
247 inputlist[0] = output; | |
248 return 0; | |
249 } | |
250 | |
251 int vis_window_set_value(datum ** inputlist, queue_entry * worker_entry) | |
252 { | |
253 vis_window_shown * window = inputlist[0]->c.generic.data; | |
254 datum * params[2]; | |
255 datum * output = new_datum(BUILTIN_TYPE_STRING, 1, 100, worker_entry->instance->def->program); | |
256 params[0] = add_ref(window->widget_handle_lookup); | |
257 params[1] = inputlist[1]; | |
258 vis_dict_index(params, NULL); | |
259 if(params[0]) | |
260 SendMessage((HWND)params[0]->c.integers.num_a, WM_SETTEXT, 0, (LPARAM)(inputlist[2]->c.generic.data)); | |
261 release_ref(inputlist[0]); | |
262 release_ref(inputlist[2]); | |
263 return 0; | |
264 } | |
265 | |
266 int vis_window_show(datum ** inputlist, queue_entry * worker_entry) | |
267 { | |
268 vis_window * window = inputlist[0]->c.generic.data; | |
269 vis_window_shown * window_show; | |
270 datum * show_datum; | |
271 | |
272 show_datum = new_datum(BUILTIN_TYPE_WINDOW_SHOWN, 1, sizeof(vis_window_shown), worker_entry->instance->def->program); | |
273 window_show = (vis_window_shown *)(show_datum->c.generic.data); | |
274 window_show->title = add_ref(window->title); | |
275 window_show->width = window->width; | |
276 window_show->height = window->height; | |
277 window_show->xpos = inputlist[1]->c.real; | |
278 release_ref(inputlist[1]); | |
279 window_show->ypos = inputlist[2]->c.real; | |
280 release_ref(inputlist[2]); | |
281 window_show->is_open = TRUE; | |
282 window_show->wait_entry = NULL; | |
283 VIS_InitializeCriticalSection(window_show->lock); | |
284 window_show->instance.def = worker_entry->instance->def; | |
285 window_show->instance.workerlist = NULL; | |
286 VIS_InitializeCriticalSection(window_show->instance.counter_lock); | |
287 window_show->orig_window = inputlist[0]; | |
288 window_show->handler_list = create_list(worker_entry->instance->def->program); | |
289 window_show->widget_handle_lookup = create_dict(worker_entry->instance->def->program); | |
290 | |
291 inputlist[0] = show_datum; | |
292 VIS_NewThread(window_thread, add_ref(show_datum)); | |
293 | |
294 return 0; | |
295 } |