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;