comparison win/dw.c @ 1853:4790589f52a9

Initial commit for new dw_signal_connect_data() function... Same as dw_signal_connect() but it has an additional callback parameter that gets called when the callback is being removed. This allows me to free memory allocated for the data parameter and prevent memory leaks in godwindows... Tested GTK and Mac.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 27 Feb 2013 19:14:22 +0000
parents 905f8632005b
children 285bf986e4fd
comparison
equal deleted inserted replaced
1852:5f0e4ca14dcd 1853:4790589f52a9
1 /* 1 /*
2 * Dynamic Windows: 2 * Dynamic Windows:
3 * A GTK like implementation of the Win32 GUI 3 * A GTK like implementation of the Win32 GUI
4 * 4 *
5 * (C) 2000-2012 Brian Smith <brian@dbsoft.org> 5 * (C) 2000-2013 Brian Smith <brian@dbsoft.org>
6 * (C) 2003-2011 Mark Hessling <mark@rexx.org> 6 * (C) 2003-2011 Mark Hessling <mark@rexx.org>
7 * 7 *
8 */ 8 */
9 9
10 #ifdef AEROGLASS 10 #ifdef AEROGLASS
334 struct _sighandler *next; 334 struct _sighandler *next;
335 ULONG message; 335 ULONG message;
336 HWND window; 336 HWND window;
337 int id; 337 int id;
338 void *signalfunction; 338 void *signalfunction;
339 void *discfunction;
339 void *data; 340 void *data;
340 341
341 } SignalHandler; 342 } SignalHandler;
342 343
343 SignalHandler *Root = NULL; 344 SignalHandler *Root = NULL;
665 } 666 }
666 #endif 667 #endif
667 668
668 /* This function adds a signal handler callback into the linked list. 669 /* This function adds a signal handler callback into the linked list.
669 */ 670 */
670 void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data) 671 void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *discfunc, void *data)
671 { 672 {
672 SignalHandler *new = malloc(sizeof(SignalHandler)); 673 SignalHandler *new = malloc(sizeof(SignalHandler));
673 674
674 new->message = message; 675 new->message = message;
675 new->window = window; 676 new->window = window;
676 new->id = id; 677 new->id = id;
677 new->signalfunction = signalfunction; 678 new->signalfunction = signalfunction;
679 new->discfunction = discfunc;
678 new->data = data; 680 new->data = data;
679 new->next = NULL; 681 new->next = NULL;
680 682
681 if (!Root) 683 if (!Root)
682 { 684 {
12248 */ 12250 */
12249 int timerid = (int)SetTimer(NULL, 0, interval, _TimerProc); 12251 int timerid = (int)SetTimer(NULL, 0, interval, _TimerProc);
12250 12252
12251 if(timerid) 12253 if(timerid)
12252 { 12254 {
12253 _new_signal(WM_TIMER, NULL, timerid, sigfunc, data); 12255 _new_signal(WM_TIMER, NULL, timerid, sigfunc, NULL, data);
12254 return timerid; 12256 return timerid;
12255 } 12257 }
12256 } 12258 }
12257 return 0; 12259 return 0;
12258 } 12260 }
12305 * sigfunc: The pointer to the function to be used as the callback. 12307 * sigfunc: The pointer to the function to be used as the callback.
12306 * data: User data to be passed to the handler function. 12308 * data: User data to be passed to the handler function.
12307 */ 12309 */
12308 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) 12310 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
12309 { 12311 {
12312 dw_signal_connect_data(window, signame, sigfunc, NULL, data);
12313 }
12314
12315 /*
12316 * Add a callback to a window event with a closure callback.
12317 * Parameters:
12318 * window: Window handle of signal to be called back.
12319 * signame: A string pointer identifying which signal to be hooked.
12320 * sigfunc: The pointer to the function to be used as the callback.
12321 * discfunc: The pointer to the function called when this handler is removed.
12322 * data: User data to be passed to the handler function.
12323 */
12324 void API dw_signal_connect_data(HWND window, char *signame, void *sigfunc, void *discfunc, void *data)
12325 {
12310 ULONG message = 0, id = 0; 12326 ULONG message = 0, id = 0;
12311 12327
12312 if (window && signame && sigfunc) 12328 if (window && signame && sigfunc)
12313 { 12329 {
12314 if (_stricmp(signame, DW_SIGNAL_SET_FOCUS) == 0) 12330 if (_stricmp(signame, DW_SIGNAL_SET_FOCUS) == 0)
12332 { 12348 {
12333 id = (ULONG)(uintptr_t)window; 12349 id = (ULONG)(uintptr_t)window;
12334 window = owner; 12350 window = owner;
12335 } 12351 }
12336 } 12352 }
12337 _new_signal(message, window, id, sigfunc, data); 12353 _new_signal(message, window, id, sigfunc, discfunc, data);
12338 } 12354 }
12339 } 12355 }
12340 } 12356 }
12341 12357
12342 /* 12358 /*
12354 12370
12355 while(tmp) 12371 while(tmp)
12356 { 12372 {
12357 if(((window < (HWND)65536 && (int)(intptr_t)window == tmp->id) || tmp->window == window) && tmp->message == message) 12373 if(((window < (HWND)65536 && (int)(intptr_t)window == tmp->id) || tmp->window == window) && tmp->message == message)
12358 { 12374 {
12375 void (*discfunc)(HWND, void *) = (void (*)(HWND, void *))tmp->discfunction;
12376
12377 if(discfunc)
12378 {
12379 discfunc(tmp->window, tmp->data);
12380 }
12381
12382 if(prev)
12383 {
12384 prev->next = tmp->next;
12385 free(tmp);
12386 tmp = prev->next;
12387 }
12388 else
12389 {
12390 Root = tmp->next;
12391 free(tmp);
12392 tmp = Root;
12393 }
12394 }
12395 else
12396 {
12397 prev = tmp;
12398 tmp = tmp->next;
12399 }
12400 }
12401 }
12402
12403 /*
12404 * Removes all callbacks for a given window.
12405 * Parameters:
12406 * window: Window handle of callback to be removed.
12407 */
12408 void API dw_signal_disconnect_by_window(HWND window)
12409 {
12410 SignalHandler *prev = NULL, *tmp = Root;
12411
12412 while(tmp)
12413 {
12414 if((window < (HWND)65536 && (int)(intptr_t)window == tmp->id) || tmp->window == window)
12415 {
12416 void (*discfunc)(HWND, void *) = (void (*)(HWND, void *))tmp->discfunction;
12417
12418 if(discfunc)
12419 {
12420 discfunc(tmp->window, tmp->data);
12421 }
12422
12423 if(prev)
12424 {
12425 prev->next = tmp->next;
12426 free(tmp);
12427 tmp = prev->next;
12428 }
12429 else
12430 {
12431 Root = tmp->next;
12432 free(tmp);
12433 tmp = Root;
12434 }
12435 }
12436 else
12437 {
12438 prev = tmp;
12439 tmp = tmp->next;
12440 }
12441 }
12442 }
12443
12444 /*
12445 * Removes all callbacks for a given window with specified data.
12446 * Parameters:
12447 * window: Window handle of callback to be removed.
12448 * data: Pointer to the data to be compared against.
12449 */
12450 void API dw_signal_disconnect_by_data(HWND window, void *data)
12451 {
12452 SignalHandler *prev = NULL, *tmp = Root;
12453
12454 while(tmp)
12455 {
12456 if(((window < (HWND)65536 && (int)(intptr_t)window == tmp->id) || tmp->window == window) && tmp->data == data)
12457 {
12458 void (*discfunc)(HWND, void *) = (void (*)(HWND, void *))tmp->discfunction;
12459
12460 if(discfunc)
12461 {
12462 discfunc(tmp->window, tmp->data);
12463 }
12464
12359 if(prev) 12465 if(prev)
12360 { 12466 {
12361 prev->next = tmp->next; 12467 prev->next = tmp->next;
12362 free(tmp); 12468 free(tmp);
12363 tmp = prev->next; 12469 tmp = prev->next;
12376 } 12482 }
12377 } 12483 }
12378 } 12484 }
12379 12485
12380 /* 12486 /*
12381 * Removes all callbacks for a given window.
12382 * Parameters:
12383 * window: Window handle of callback to be removed.
12384 */
12385 void API dw_signal_disconnect_by_window(HWND window)
12386 {
12387 SignalHandler *prev = NULL, *tmp = Root;
12388
12389 while(tmp)
12390 {
12391 if((window < (HWND)65536 && (int)(intptr_t)window == tmp->id) || tmp->window == window)
12392 {
12393 if(prev)
12394 {
12395 prev->next = tmp->next;
12396 free(tmp);
12397 tmp = prev->next;
12398 }
12399 else
12400 {
12401 Root = tmp->next;
12402 free(tmp);
12403 tmp = Root;
12404 }
12405 }
12406 else
12407 {
12408 prev = tmp;
12409 tmp = tmp->next;
12410 }
12411 }
12412 }
12413
12414 /*
12415 * Removes all callbacks for a given window with specified data.
12416 * Parameters:
12417 * window: Window handle of callback to be removed.
12418 * data: Pointer to the data to be compared against.
12419 */
12420 void API dw_signal_disconnect_by_data(HWND window, void *data)
12421 {
12422 SignalHandler *prev = NULL, *tmp = Root;
12423
12424 while(tmp)
12425 {
12426 if(((window < (HWND)65536 && (int)(intptr_t)window == tmp->id) || tmp->window == window) && tmp->data == data)
12427 {
12428 if(prev)
12429 {
12430 prev->next = tmp->next;
12431 free(tmp);
12432 tmp = prev->next;
12433 }
12434 else
12435 {
12436 Root = tmp->next;
12437 free(tmp);
12438 tmp = Root;
12439 }
12440 }
12441 else
12442 {
12443 prev = tmp;
12444 tmp = tmp->next;
12445 }
12446 }
12447 }
12448
12449 /*
12450 * Converts a UTF-8 encoded string into a wide string. 12487 * Converts a UTF-8 encoded string into a wide string.
12451 * Parameters: 12488 * Parameters:
12452 * utf8string: UTF-8 encoded source string. 12489 * utf8string: UTF-8 encoded source string.
12453 * Returns: 12490 * Returns:
12454 * Wide string that needs to be freed with dw_free() 12491 * Wide string that needs to be freed with dw_free()