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);