diff 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
line wrap: on
line diff
--- a/win/dw.c	Fri Feb 15 09:22:56 2013 +0000
+++ b/win/dw.c	Wed Feb 27 19:14:22 2013 +0000
@@ -2,7 +2,7 @@
  * Dynamic Windows:
  *          A GTK like implementation of the Win32 GUI
  *
- * (C) 2000-2012 Brian Smith <brian@dbsoft.org>
+ * (C) 2000-2013 Brian Smith <brian@dbsoft.org>
  * (C) 2003-2011 Mark Hessling <mark@rexx.org>
  *
  */
@@ -336,6 +336,7 @@
    HWND window;
    int id;
    void *signalfunction;
+   void *discfunction;
    void *data;
 
 } SignalHandler;
@@ -667,7 +668,7 @@
 
 /* This function adds a signal handler callback into the linked list.
  */
-void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *data)
+void _new_signal(ULONG message, HWND window, int id, void *signalfunction, void *discfunc, void *data)
 {
    SignalHandler *new = malloc(sizeof(SignalHandler));
 
@@ -675,6 +676,7 @@
    new->window = window;
    new->id = id;
    new->signalfunction = signalfunction;
+   new->discfunction = discfunc;
    new->data = data;
    new->next = NULL;
 
@@ -12250,7 +12252,7 @@
 
       if(timerid)
       {
-         _new_signal(WM_TIMER, NULL, timerid, sigfunc, data);
+         _new_signal(WM_TIMER, NULL, timerid, sigfunc, NULL, data);
          return timerid;
       }
    }
@@ -12307,6 +12309,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, id = 0;
 
    if (window && signame && sigfunc)
@@ -12334,7 +12350,7 @@
                window = owner;
             }
          }
-         _new_signal(message, window, id, sigfunc, data);
+         _new_signal(message, window, id, sigfunc, discfunc, data);
       }
    }
 }
@@ -12356,7 +12372,14 @@
    {
       if(((window < (HWND)65536 && (int)(intptr_t)window == tmp->id) || tmp->window == window) && tmp->message == message)
       {
-        if(prev)
+         void (*discfunc)(HWND, void *) = (void (*)(HWND, void *))tmp->discfunction;
+            
+         if(discfunc)
+         {
+             discfunc(tmp->window, tmp->data);
+         }
+         
+         if(prev)
          {
             prev->next = tmp->next;
             free(tmp);
@@ -12390,6 +12413,13 @@
    {
       if((window < (HWND)65536 && (int)(intptr_t)window == tmp->id) || tmp->window == window)
       {
+         void (*discfunc)(HWND, void *) = (void (*)(HWND, void *))tmp->discfunction;
+            
+         if(discfunc)
+         {
+             discfunc(tmp->window, tmp->data);
+         }
+         
          if(prev)
          {
             prev->next = tmp->next;
@@ -12425,6 +12455,13 @@
    {
       if(((window < (HWND)65536 && (int)(intptr_t)window == tmp->id) || tmp->window == window) && tmp->data == data)
       {
+         void (*discfunc)(HWND, void *) = (void (*)(HWND, void *))tmp->discfunction;
+            
+         if(discfunc)
+         {
+             discfunc(tmp->window, tmp->data);
+         }
+         
         if(prev)
          {
             prev->next = tmp->next;