Mercurial > dwindows
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() |