Mercurial > dwindows
comparison android/dw.cpp @ 2481:94f0d61d6953
Android: Initial commit of signal handlers, connecting buttons to the new
system.
author | bsmith@81767d24-ef19-dc11-ae90-00e081727c95 |
---|---|
date | Mon, 26 Apr 2021 11:01:58 +0000 |
parents | 3fbf8783122d |
children | 4888503c3e3e |
comparison
equal
deleted
inserted
replaced
2480:878d36588aaa | 2481:94f0d61d6953 |
---|---|
105 /* Wait until dwmain() calls dw_main() then return */ | 105 /* Wait until dwmain() calls dw_main() then return */ |
106 dw_event_wait(_dw_main_event, DW_TIMEOUT_INFINITE); | 106 dw_event_wait(_dw_main_event, DW_TIMEOUT_INFINITE); |
107 return env->NewStringUTF("Hello from JNI!"); | 107 return env->NewStringUTF("Hello from JNI!"); |
108 } | 108 } |
109 | 109 |
110 typedef struct _sighandler | |
111 { | |
112 struct _sighandler *next; | |
113 ULONG message; | |
114 HWND window; | |
115 int id; | |
116 void *signalfunction; | |
117 void *discfunction; | |
118 void *data; | |
119 | |
120 } SignalHandler; | |
121 | |
122 static SignalHandler *DWRoot = NULL; | |
123 | |
124 SignalHandler *_dw_get_handler(HWND window, int messageid) | |
125 { | |
126 SignalHandler *tmp = DWRoot; | |
127 | |
128 /* Find any callbacks for this function */ | |
129 while(tmp) | |
130 { | |
131 if(tmp->message == messageid && window == tmp->window) | |
132 { | |
133 return tmp; | |
134 } | |
135 tmp = tmp->next; | |
136 } | |
137 return NULL; | |
138 } | |
139 | |
140 typedef struct | |
141 { | |
142 ULONG message; | |
143 char name[30]; | |
144 | |
145 } DWSignalList; | |
146 | |
147 /* List of signals */ | |
148 #define SIGNALMAX 19 | |
149 | |
150 static DWSignalList DWSignalTranslate[SIGNALMAX] = { | |
151 { 1, DW_SIGNAL_CONFIGURE }, | |
152 { 2, DW_SIGNAL_KEY_PRESS }, | |
153 { 3, DW_SIGNAL_BUTTON_PRESS }, | |
154 { 4, DW_SIGNAL_BUTTON_RELEASE }, | |
155 { 5, DW_SIGNAL_MOTION_NOTIFY }, | |
156 { 6, DW_SIGNAL_DELETE }, | |
157 { 7, DW_SIGNAL_EXPOSE }, | |
158 { 8, DW_SIGNAL_CLICKED }, | |
159 { 9, DW_SIGNAL_ITEM_ENTER }, | |
160 { 10, DW_SIGNAL_ITEM_CONTEXT }, | |
161 { 11, DW_SIGNAL_LIST_SELECT }, | |
162 { 12, DW_SIGNAL_ITEM_SELECT }, | |
163 { 13, DW_SIGNAL_SET_FOCUS }, | |
164 { 14, DW_SIGNAL_VALUE_CHANGED }, | |
165 { 15, DW_SIGNAL_SWITCH_PAGE }, | |
166 { 16, DW_SIGNAL_TREE_EXPAND }, | |
167 { 17, DW_SIGNAL_COLUMN_CLICK }, | |
168 { 18, DW_SIGNAL_HTML_RESULT }, | |
169 { 19, DW_SIGNAL_HTML_CHANGED } | |
170 }; | |
171 | |
172 int _dw_event_handler(jobject object, void **params, int message) | |
173 { | |
174 SignalHandler *handler = _dw_get_handler(object, message); | |
175 | |
176 if(handler) | |
177 { | |
178 switch(message) | |
179 { | |
180 /* Timer event */ | |
181 case 0: | |
182 { | |
183 int (*timerfunc)(void *) = (int (* API)(void *))handler->signalfunction; | |
184 | |
185 if(!timerfunc(handler->data)) | |
186 dw_timer_disconnect(handler->id); | |
187 return 0; | |
188 } | |
189 /* Configure/Resize event */ | |
190 case 1: | |
191 { | |
192 int (*sizefunc)(HWND, int, int, void *) = (int (* API)(HWND, int, int, void *))handler->signalfunction; | |
193 int width = DW_POINTER_TO_INT(params[3]); | |
194 int height = DW_POINTER_TO_INT(params[4]); | |
195 | |
196 if(width > 0 && height > 0) | |
197 { | |
198 return sizefunc(object, width, height, handler->data); | |
199 } | |
200 return 0; | |
201 } | |
202 case 2: | |
203 { | |
204 int (*keypressfunc)(HWND, char, int, int, void *, char *) = (int (* API)(HWND, char, int, int, void *, char *))handler->signalfunction; | |
205 char *utf8 = (char *)params[1], ch = utf8 ? utf8[0] : '\0'; | |
206 int vk = 0, special = 0; | |
207 | |
208 return keypressfunc(handler->window, ch, (int)vk, special, handler->data, utf8); | |
209 } | |
210 /* Button press and release event */ | |
211 case 3: | |
212 case 4: | |
213 { | |
214 int (* API buttonfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))handler->signalfunction; | |
215 int button = 1; | |
216 | |
217 return buttonfunc(object, DW_POINTER_TO_INT(params[3]), DW_POINTER_TO_INT(params[4]), button, handler->data); | |
218 } | |
219 /* Motion notify event */ | |
220 case 5: | |
221 { | |
222 int (* API motionfunc)(HWND, int, int, int, void *) = (int (* API)(HWND, int, int, int, void *))handler->signalfunction; | |
223 | |
224 return motionfunc(object, DW_POINTER_TO_INT(params[3]), DW_POINTER_TO_INT(params[4]), DW_POINTER_TO_INT(params[5]), handler->data); | |
225 } | |
226 /* Window close event */ | |
227 case 6: | |
228 { | |
229 int (* API closefunc)(HWND, void *) = (int (* API)(HWND, void *))handler->signalfunction; | |
230 return closefunc(object, handler->data); | |
231 } | |
232 /* Window expose/draw event */ | |
233 case 7: | |
234 { | |
235 DWExpose exp; | |
236 int (* API exposefunc)(HWND, DWExpose *, void *) = (int (* API)(HWND, DWExpose *, void *))handler->signalfunction; | |
237 | |
238 exp.x = DW_POINTER_TO_INT(params[3]); | |
239 exp.y = DW_POINTER_TO_INT(params[4]); | |
240 exp.width = DW_POINTER_TO_INT(params[5]); | |
241 exp.height = DW_POINTER_TO_INT(params[6]); | |
242 int result = exposefunc(object, &exp, handler->data); | |
243 return result; | |
244 } | |
245 /* Clicked event for buttons and menu items */ | |
246 case 8: | |
247 { | |
248 int (* API clickfunc)(HWND, void *) = (int (* API)(HWND, void *))handler->signalfunction; | |
249 | |
250 return clickfunc(object, handler->data); | |
251 } | |
252 /* Container class selection event */ | |
253 case 9: | |
254 { | |
255 int (*containerselectfunc)(HWND, char *, void *, void *) =(int (* API)(HWND, char *, void *, void *)) handler->signalfunction; | |
256 | |
257 return containerselectfunc(handler->window, (char *)params[1], handler->data, params[7]); | |
258 } | |
259 /* Container context menu event */ | |
260 case 10: | |
261 { | |
262 int (* API containercontextfunc)(HWND, char *, int, int, void *, void *) = (int (* API)(HWND, char *, int, int, void *, void *))handler->signalfunction; | |
263 char *text = (char *)params[1]; | |
264 void *user = params[7]; | |
265 int x = DW_POINTER_TO_INT(params[3]); | |
266 int y = DW_POINTER_TO_INT(params[4]); | |
267 | |
268 return containercontextfunc(handler->window, text, x, y, handler->data, user); | |
269 } | |
270 /* Generic selection changed event for several classes */ | |
271 case 11: | |
272 case 14: | |
273 { | |
274 int (* API valuechangedfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))handler->signalfunction; | |
275 int selected = DW_POINTER_TO_INT(params[3]); | |
276 | |
277 return valuechangedfunc(handler->window, selected, handler->data);; | |
278 } | |
279 /* Tree class selection event */ | |
280 case 12: | |
281 { | |
282 int (* API treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = (int (* API)(HWND, HTREEITEM, char *, void *, void *))handler->signalfunction; | |
283 char *text = (char *)params[1]; | |
284 void *user = params[7]; | |
285 | |
286 return treeselectfunc(handler->window, params[0], text, handler->data, user); | |
287 } | |
288 /* Set Focus event */ | |
289 case 13: | |
290 { | |
291 int (* API setfocusfunc)(HWND, void *) = (int (* API)(HWND, void *))handler->signalfunction; | |
292 | |
293 return setfocusfunc(handler->window, handler->data); | |
294 } | |
295 /* Notebook page change event */ | |
296 case 15: | |
297 { | |
298 int (* API switchpagefunc)(HWND, unsigned long, void *) = (int (* API)(HWND, unsigned long, void *))handler->signalfunction; | |
299 int pageid = DW_POINTER_TO_INT(params[3]); | |
300 | |
301 return switchpagefunc(handler->window, pageid, handler->data); | |
302 } | |
303 /* Tree expand event */ | |
304 case 16: | |
305 { | |
306 int (* API treeexpandfunc)(HWND, HTREEITEM, void *) = (int (* API)(HWND, HTREEITEM, void *))handler->signalfunction; | |
307 | |
308 return treeexpandfunc(handler->window, (HTREEITEM)params[0], handler->data); | |
309 } | |
310 /* Column click event */ | |
311 case 17: | |
312 { | |
313 int (* API clickcolumnfunc)(HWND, int, void *) = (int (* API)(HWND, int, void *))handler->signalfunction; | |
314 int column_num = DW_POINTER_TO_INT(params[3]); | |
315 | |
316 return clickcolumnfunc(handler->window, column_num, handler->data); | |
317 } | |
318 /* HTML result event */ | |
319 case 18: | |
320 { | |
321 int (* API htmlresultfunc)(HWND, int, char *, void *, void *) = (int (* API)(HWND, int, char *, void *, void *))handler->signalfunction; | |
322 char *result = (char *)params[1]; | |
323 | |
324 return htmlresultfunc(handler->window, result ? DW_ERROR_NONE : DW_ERROR_UNKNOWN, result, params[7], handler->data); | |
325 } | |
326 /* HTML changed event */ | |
327 case 19: | |
328 { | |
329 int (* API htmlchangedfunc)(HWND, int, char *, void *) = (int (* API)(HWND, int, char *, void *))handler->signalfunction; | |
330 char *uri = (char *)params[1]; | |
331 | |
332 return htmlchangedfunc(handler->window, DW_POINTER_TO_INT(params[3]), uri, handler->data); | |
333 } | |
334 } | |
335 } | |
336 return -1; | |
337 } | |
338 | |
339 /* | |
340 * Entry location for all event handlers from the Android UI | |
341 */ | |
342 JNIEXPORT jint JNICALL | |
343 Java_org_dbsoft_dwindows_dwtest_DWindows_eventHandler(JNIEnv* env, jobject obj, jobject obj1, jobject obj2, | |
344 jint message, jstring str1, jstring str2, | |
345 jint int1, jint int2, jint int3, jint int4) { | |
346 const char *utf81 = str1 ? env->GetStringUTFChars(str1, NULL) : NULL; | |
347 const char *utf82 = str2 ? env->GetStringUTFChars(str2, NULL) : NULL; | |
348 void *params[8] = { (void *)obj2, (void *)utf81, (void *)utf82, | |
349 DW_INT_TO_POINTER(int1), DW_INT_TO_POINTER(int2), | |
350 DW_INT_TO_POINTER(int3), DW_INT_TO_POINTER(int4), NULL }; | |
351 return _dw_event_handler(obj1, params, message); | |
352 } | |
353 | |
354 /* This function adds a signal handler callback into the linked list. | |
355 */ | |
356 void _dw_new_signal(ULONG message, HWND window, int msgid, void *signalfunction, void *discfunc, void *data) | |
357 { | |
358 SignalHandler *newsig = (SignalHandler *)malloc(sizeof(SignalHandler)); | |
359 | |
360 newsig->message = message; | |
361 newsig->window = window; | |
362 newsig->id = msgid; | |
363 newsig->signalfunction = signalfunction; | |
364 newsig->discfunction = discfunc; | |
365 newsig->data = data; | |
366 newsig->next = NULL; | |
367 | |
368 if (!DWRoot) | |
369 DWRoot = newsig; | |
370 else | |
371 { | |
372 SignalHandler *prev = NULL, *tmp = DWRoot; | |
373 while(tmp) | |
374 { | |
375 if(tmp->message == message && | |
376 tmp->window == window && | |
377 tmp->id == msgid && | |
378 tmp->signalfunction == signalfunction) | |
379 { | |
380 tmp->data = data; | |
381 free(newsig); | |
382 return; | |
383 } | |
384 prev = tmp; | |
385 tmp = tmp->next; | |
386 } | |
387 if(prev) | |
388 prev->next = newsig; | |
389 else | |
390 DWRoot = newsig; | |
391 } | |
392 } | |
393 | |
394 /* Finds the message number for a given signal name */ | |
395 ULONG _dw_findsigmessage(const char *signame) | |
396 { | |
397 int z; | |
398 | |
399 for(z=0;z<SIGNALMAX;z++) | |
400 { | |
401 if(strcasecmp(signame, DWSignalTranslate[z].name) == 0) | |
402 return DWSignalTranslate[z].message; | |
403 } | |
404 return 0L; | |
405 } | |
406 | |
110 /* Implement these to get and set the Box* pointer on the widget handle */ | 407 /* Implement these to get and set the Box* pointer on the widget handle */ |
111 void *_dw_window_pointer_get(HWND handle) | 408 void *_dw_window_pointer_get(HWND handle) |
112 { | 409 { |
113 return NULL; | 410 return NULL; |
114 } | 411 } |
3099 * discfunc: The pointer to the function called when this handler is removed. | 3396 * discfunc: The pointer to the function called when this handler is removed. |
3100 * data: User data to be passed to the handler function. | 3397 * data: User data to be passed to the handler function. |
3101 */ | 3398 */ |
3102 void API dw_signal_connect_data(HWND window, const char *signame, void *sigfunc, void *discfunc, void *data) | 3399 void API dw_signal_connect_data(HWND window, const char *signame, void *sigfunc, void *discfunc, void *data) |
3103 { | 3400 { |
3401 ULONG message = 0, msgid = 0; | |
3402 | |
3403 if(window && signame && sigfunc) | |
3404 { | |
3405 if((message = _dw_findsigmessage(signame)) != 0) | |
3406 { | |
3407 _dw_new_signal(message, window, (int)msgid, sigfunc, discfunc, data); | |
3408 } | |
3409 } | |
3104 } | 3410 } |
3105 | 3411 |
3106 /* | 3412 /* |
3107 * Removes callbacks for a given window with given name. | 3413 * Removes callbacks for a given window with given name. |
3108 * Parameters: | 3414 * Parameters: |
3109 * window: Window handle of callback to be removed. | 3415 * window: Window handle of callback to be removed. |
3110 * signame: Signal name to be matched on window. | |
3111 */ | 3416 */ |
3112 void API dw_signal_disconnect_by_name(HWND window, const char *signame) | 3417 void API dw_signal_disconnect_by_name(HWND window, const char *signame) |
3113 { | 3418 { |
3419 SignalHandler *prev = NULL, *tmp = DWRoot; | |
3420 ULONG message; | |
3421 | |
3422 if(!window || !signame || (message = _dw_findsigmessage(signame)) == 0) | |
3423 return; | |
3424 | |
3425 while(tmp) | |
3426 { | |
3427 if(tmp->window == window && tmp->message == message) | |
3428 { | |
3429 void (*discfunc)(HWND, void *) = (void (*)(HWND, void*))tmp->discfunction; | |
3430 | |
3431 if(discfunc) | |
3432 { | |
3433 discfunc(tmp->window, tmp->data); | |
3434 } | |
3435 | |
3436 if(prev) | |
3437 { | |
3438 prev->next = tmp->next; | |
3439 free(tmp); | |
3440 tmp = prev->next; | |
3441 } | |
3442 else | |
3443 { | |
3444 DWRoot = tmp->next; | |
3445 free(tmp); | |
3446 tmp = DWRoot; | |
3447 } | |
3448 } | |
3449 else | |
3450 { | |
3451 prev = tmp; | |
3452 tmp = tmp->next; | |
3453 } | |
3454 } | |
3114 } | 3455 } |
3115 | 3456 |
3116 /* | 3457 /* |
3117 * Removes all callbacks for a given window. | 3458 * Removes all callbacks for a given window. |
3118 * Parameters: | 3459 * Parameters: |
3119 * window: Window handle of callback to be removed. | 3460 * window: Window handle of callback to be removed. |
3120 */ | 3461 */ |
3121 void API dw_signal_disconnect_by_window(HWND window) | 3462 void API dw_signal_disconnect_by_window(HWND window) |
3122 { | 3463 { |
3464 SignalHandler *prev = NULL, *tmp = DWRoot; | |
3465 | |
3466 while(tmp) | |
3467 { | |
3468 if(tmp->window == window) | |
3469 { | |
3470 void (*discfunc)(HWND, void *) = (void (*)(HWND, void*))tmp->discfunction; | |
3471 | |
3472 if(discfunc) | |
3473 { | |
3474 discfunc(tmp->window, tmp->data); | |
3475 } | |
3476 | |
3477 if(prev) | |
3478 { | |
3479 prev->next = tmp->next; | |
3480 free(tmp); | |
3481 tmp = prev->next; | |
3482 } | |
3483 else | |
3484 { | |
3485 DWRoot = tmp->next; | |
3486 free(tmp); | |
3487 tmp = DWRoot; | |
3488 } | |
3489 } | |
3490 else | |
3491 { | |
3492 prev = tmp; | |
3493 tmp = tmp->next; | |
3494 } | |
3495 } | |
3123 } | 3496 } |
3124 | 3497 |
3125 /* | 3498 /* |
3126 * Removes all callbacks for a given window with specified data. | 3499 * Removes all callbacks for a given window with specified data. |
3127 * Parameters: | 3500 * Parameters: |
3128 * window: Window handle of callback to be removed. | 3501 * window: Window handle of callback to be removed. |
3129 * data: Pointer to the data to be compared against. | 3502 * data: Pointer to the data to be compared against. |
3130 */ | 3503 */ |
3131 void API dw_signal_disconnect_by_data(HWND window, void *data) | 3504 void API dw_signal_disconnect_by_data(HWND window, void *data) |
3132 { | 3505 { |
3506 SignalHandler *prev = NULL, *tmp = DWRoot; | |
3507 | |
3508 while(tmp) | |
3509 { | |
3510 if(tmp->window == window && tmp->data == data) | |
3511 { | |
3512 void (*discfunc)(HWND, void *) = (void (*)(HWND, void*))tmp->discfunction; | |
3513 | |
3514 if(discfunc) | |
3515 { | |
3516 discfunc(tmp->window, tmp->data); | |
3517 } | |
3518 | |
3519 if(prev) | |
3520 { | |
3521 prev->next = tmp->next; | |
3522 free(tmp); | |
3523 tmp = prev->next; | |
3524 } | |
3525 else | |
3526 { | |
3527 DWRoot = tmp->next; | |
3528 free(tmp); | |
3529 tmp = DWRoot; | |
3530 } | |
3531 } | |
3532 else | |
3533 { | |
3534 prev = tmp; | |
3535 tmp = tmp->next; | |
3536 } | |
3537 } | |
3133 } | 3538 } |
3134 | 3539 |
3135 void _dw_strlwr(char *buf) | 3540 void _dw_strlwr(char *buf) |
3136 { | 3541 { |
3137 int z, len = strlen(buf); | 3542 int z, len = strlen(buf); |