Mercurial > dwindows
comparison mac/dw.m @ 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 | b5e1ccc76e58 |
children | c836603d3f14 |
comparison
equal
deleted
inserted
replaced
1852:5f0e4ca14dcd | 1853:4790589f52a9 |
---|---|
1 /* | 1 /* |
2 * Dynamic Windows: | 2 * Dynamic Windows: |
3 * A GTK like implementation of the MacOS GUI using Cocoa | 3 * A GTK like implementation of the MacOS GUI using Cocoa |
4 * | 4 * |
5 * (C) 2011-2012 Brian Smith <brian@dbsoft.org> | 5 * (C) 2011-2013 Brian Smith <brian@dbsoft.org> |
6 * (C) 2011 Mark Hessling <mark@rexx.org> | 6 * (C) 2011 Mark Hessling <mark@rexx.org> |
7 * | 7 * |
8 * Requires 10.5 or later. | 8 * Requires 10.5 or later. |
9 * clang -std=c99 -g -o dwtest -D__MAC__ -I. dwtest.c mac/dw.m -framework Cocoa -framework WebKit | 9 * clang -std=c99 -g -o dwtest -D__MAC__ -I. dwtest.c mac/dw.m -framework Cocoa -framework WebKit |
10 */ | 10 */ |
143 struct _sighandler *next; | 143 struct _sighandler *next; |
144 ULONG message; | 144 ULONG message; |
145 HWND window; | 145 HWND window; |
146 int id; | 146 int id; |
147 void *signalfunction; | 147 void *signalfunction; |
148 void *discfunction; | |
148 void *data; | 149 void *data; |
149 | 150 |
150 } SignalHandler; | 151 } SignalHandler; |
151 | 152 |
152 SignalHandler *Root = NULL; | 153 SignalHandler *Root = NULL; |
2625 @implementation DWMDI | 2626 @implementation DWMDI |
2626 @end | 2627 @end |
2627 | 2628 |
2628 /* This function adds a signal handler callback into the linked list. | 2629 /* This function adds a signal handler callback into the linked list. |
2629 */ | 2630 */ |
2630 void _new_signal(ULONG message, HWND window, int msgid, void *signalfunction, void *data) | 2631 void _new_signal(ULONG message, HWND window, int msgid, void *signalfunction, void *discfunc, void *data) |
2631 { | 2632 { |
2632 SignalHandler *new = malloc(sizeof(SignalHandler)); | 2633 SignalHandler *new = malloc(sizeof(SignalHandler)); |
2633 | 2634 |
2634 new->message = message; | 2635 new->message = message; |
2635 new->window = window; | 2636 new->window = window; |
2636 new->id = msgid; | 2637 new->id = msgid; |
2637 new->signalfunction = signalfunction; | 2638 new->signalfunction = signalfunction; |
2639 new->discfunction = discfunc; | |
2638 new->data = data; | 2640 new->data = data; |
2639 new->next = NULL; | 2641 new->next = NULL; |
2640 | 2642 |
2641 if (!Root) | 2643 if (!Root) |
2642 Root = new; | 2644 Root = new; |
9852 | 9854 |
9853 if(sigfunc && !DWTimers[z]) | 9855 if(sigfunc && !DWTimers[z]) |
9854 { | 9856 { |
9855 NSTimeInterval seconds = (double)interval / 1000.0; | 9857 NSTimeInterval seconds = (double)interval / 1000.0; |
9856 NSTimer *thistimer = DWTimers[z] = [NSTimer scheduledTimerWithTimeInterval:seconds target:DWHandler selector:@selector(runTimer:) userInfo:nil repeats:YES]; | 9858 NSTimer *thistimer = DWTimers[z] = [NSTimer scheduledTimerWithTimeInterval:seconds target:DWHandler selector:@selector(runTimer:) userInfo:nil repeats:YES]; |
9857 _new_signal(0, thistimer, z+1, sigfunc, data); | 9859 _new_signal(0, thistimer, z+1, sigfunc, NULL, data); |
9858 return z+1; | 9860 return z+1; |
9859 } | 9861 } |
9860 return 0; | 9862 return 0; |
9861 } | 9863 } |
9862 | 9864 |
9912 * sigfunc: The pointer to the function to be used as the callback. | 9914 * sigfunc: The pointer to the function to be used as the callback. |
9913 * data: User data to be passed to the handler function. | 9915 * data: User data to be passed to the handler function. |
9914 */ | 9916 */ |
9915 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) | 9917 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) |
9916 { | 9918 { |
9919 dw_signal_connect_data(window, signame, sigfunc, NULL, data); | |
9920 } | |
9921 | |
9922 /* | |
9923 * Add a callback to a window event with a closure callback. | |
9924 * Parameters: | |
9925 * window: Window handle of signal to be called back. | |
9926 * signame: A string pointer identifying which signal to be hooked. | |
9927 * sigfunc: The pointer to the function to be used as the callback. | |
9928 * discfunc: The pointer to the function called when this handler is removed. | |
9929 * data: User data to be passed to the handler function. | |
9930 */ | |
9931 void API dw_signal_connect_data(HWND window, char *signame, void *sigfunc, void *discfunc, void *data) | |
9932 { | |
9917 ULONG message = 0, msgid = 0; | 9933 ULONG message = 0, msgid = 0; |
9918 | 9934 |
9919 /* Handle special case of application delete signal */ | 9935 /* Handle special case of application delete signal */ |
9920 if(!window && signame && strcmp(signame, DW_SIGNAL_DELETE) == 0) | 9936 if(!window && signame && strcmp(signame, DW_SIGNAL_DELETE) == 0) |
9921 { | 9937 { |
9924 | 9940 |
9925 if(window && signame && sigfunc) | 9941 if(window && signame && sigfunc) |
9926 { | 9942 { |
9927 if((message = _findsigmessage(signame)) != 0) | 9943 if((message = _findsigmessage(signame)) != 0) |
9928 { | 9944 { |
9929 _new_signal(message, window, (int)msgid, sigfunc, data); | 9945 _new_signal(message, window, (int)msgid, sigfunc, discfunc, data); |
9930 } | 9946 } |
9931 } | 9947 } |
9932 } | 9948 } |
9933 | 9949 |
9934 /* | 9950 /* |
9946 | 9962 |
9947 while(tmp) | 9963 while(tmp) |
9948 { | 9964 { |
9949 if(tmp->window == window && tmp->message == message) | 9965 if(tmp->window == window && tmp->message == message) |
9950 { | 9966 { |
9967 void (*discfunc)(HWND, void *) = tmp->discfunction; | |
9968 | |
9969 if(discfunc) | |
9970 { | |
9971 discfunc(tmp->window, tmp->data); | |
9972 } | |
9973 | |
9951 if(prev) | 9974 if(prev) |
9952 { | 9975 { |
9953 prev->next = tmp->next; | 9976 prev->next = tmp->next; |
9954 free(tmp); | 9977 free(tmp); |
9955 tmp = prev->next; | 9978 tmp = prev->next; |
9980 | 10003 |
9981 while(tmp) | 10004 while(tmp) |
9982 { | 10005 { |
9983 if(tmp->window == window) | 10006 if(tmp->window == window) |
9984 { | 10007 { |
10008 void (*discfunc)(HWND, void *) = tmp->discfunction; | |
10009 | |
10010 if(discfunc) | |
10011 { | |
10012 discfunc(tmp->window, tmp->data); | |
10013 } | |
10014 | |
9985 if(prev) | 10015 if(prev) |
9986 { | 10016 { |
9987 prev->next = tmp->next; | 10017 prev->next = tmp->next; |
9988 free(tmp); | 10018 free(tmp); |
9989 tmp = prev->next; | 10019 tmp = prev->next; |
10015 | 10045 |
10016 while(tmp) | 10046 while(tmp) |
10017 { | 10047 { |
10018 if(tmp->window == window && tmp->data == data) | 10048 if(tmp->window == window && tmp->data == data) |
10019 { | 10049 { |
10050 void (*discfunc)(HWND, void *) = tmp->discfunction; | |
10051 | |
10052 if(discfunc) | |
10053 { | |
10054 discfunc(tmp->window, tmp->data); | |
10055 } | |
10056 | |
10020 if(prev) | 10057 if(prev) |
10021 { | 10058 { |
10022 prev->next = tmp->next; | 10059 prev->next = tmp->next; |
10023 free(tmp); | 10060 free(tmp); |
10024 tmp = prev->next; | 10061 tmp = prev->next; |