diff 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
line wrap: on
line diff
--- a/mac/dw.m	Fri Feb 15 09:22:56 2013 +0000
+++ b/mac/dw.m	Wed Feb 27 19:14:22 2013 +0000
@@ -2,7 +2,7 @@
  * Dynamic Windows:
  *          A GTK like implementation of the MacOS GUI using Cocoa
  *
- * (C) 2011-2012 Brian Smith <brian@dbsoft.org>
+ * (C) 2011-2013 Brian Smith <brian@dbsoft.org>
  * (C) 2011 Mark Hessling <mark@rexx.org>
  *
  * Requires 10.5 or later.
@@ -145,6 +145,7 @@
     HWND window;
     int id;
     void *signalfunction;
+    void *discfunction;
     void *data;
 
 } SignalHandler;
@@ -2627,7 +2628,7 @@
 
 /* This function adds a signal handler callback into the linked list.
  */
-void _new_signal(ULONG message, HWND window, int msgid, void *signalfunction, void *data)
+void _new_signal(ULONG message, HWND window, int msgid, void *signalfunction, void *discfunc, void *data)
 {
     SignalHandler *new = malloc(sizeof(SignalHandler));
 
@@ -2635,6 +2636,7 @@
     new->window = window;
     new->id = msgid;
     new->signalfunction = signalfunction;
+    new->discfunction = discfunc;
     new->data = data;
     new->next = NULL;
 
@@ -9854,7 +9856,7 @@
     {
         NSTimeInterval seconds = (double)interval / 1000.0;
         NSTimer *thistimer = DWTimers[z] = [NSTimer scheduledTimerWithTimeInterval:seconds target:DWHandler selector:@selector(runTimer:) userInfo:nil repeats:YES];
-        _new_signal(0, thistimer, z+1, sigfunc, data);
+        _new_signal(0, thistimer, z+1, sigfunc, NULL, data);
         return z+1;
     }
     return 0;
@@ -9914,6 +9916,20 @@
  */
 void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
 {
+    dw_signal_connect_data(window, signame, sigfunc, NULL, data);
+}
+
+/*
+ * Add a callback to a window event with a closure callback.
+ * Parameters:
+ *       window: Window handle of signal to be called back.
+ *       signame: A string pointer identifying which signal to be hooked.
+ *       sigfunc: The pointer to the function to be used as the callback.
+ *       discfunc: The pointer to the function called when this handler is removed.
+ *       data: User data to be passed to the handler function.
+ */
+void API dw_signal_connect_data(HWND window, char *signame, void *sigfunc, void *discfunc, void *data)
+{
     ULONG message = 0, msgid = 0;
     
     /* Handle special case of application delete signal */
@@ -9926,7 +9942,7 @@
     {
         if((message = _findsigmessage(signame)) != 0)
         {
-            _new_signal(message, window, (int)msgid, sigfunc, data);
+            _new_signal(message, window, (int)msgid, sigfunc, discfunc, data);
         }
     }
 }
@@ -9948,6 +9964,13 @@
     {
         if(tmp->window == window && tmp->message == message)
         {
+            void (*discfunc)(HWND, void *) = tmp->discfunction;
+            
+            if(discfunc)
+            {
+                discfunc(tmp->window, tmp->data);
+            }
+            
             if(prev)
             {
                 prev->next = tmp->next;
@@ -9982,6 +10005,13 @@
     {
         if(tmp->window == window)
         {
+            void (*discfunc)(HWND, void *) = tmp->discfunction;
+            
+            if(discfunc)
+            {
+                discfunc(tmp->window, tmp->data);
+            }
+            
             if(prev)
             {
                 prev->next = tmp->next;
@@ -10017,6 +10047,13 @@
     {
         if(tmp->window == window && tmp->data == data)
         {
+            void (*discfunc)(HWND, void *) = tmp->discfunction;
+            
+            if(discfunc)
+            {
+                discfunc(tmp->window, tmp->data);
+            }
+            
             if(prev)
             {
                 prev->next = tmp->next;