# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1361992462 0 # Node ID 4790589f52a91ec84b481e5af1c20c18e20b3479 # Parent 5f0e4ca14dcd0c2f77b1970bc34637b9a4bff7b8 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. diff -r 5f0e4ca14dcd -r 4790589f52a9 dw.h --- a/dw.h Fri Feb 15 09:22:56 2013 +0000 +++ b/dw.h Wed Feb 27 19:14:22 2013 +0000 @@ -1719,6 +1719,7 @@ int API dw_timer_connect(int interval, void *sigfunc, void *data); void API dw_timer_disconnect(int id); void API dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data); +void API dw_signal_connect_data(HWND window, char *signame, void *sigfunc, void *discfunc, void *data); void API dw_signal_disconnect_by_window(HWND window); void API dw_signal_disconnect_by_data(HWND window, void *data); void API dw_signal_disconnect_by_name(HWND window, char *signame); diff -r 5f0e4ca14dcd -r 4790589f52a9 gtk/dw.c --- a/gtk/dw.c Fri Feb 15 09:22:56 2013 +0000 +++ b/gtk/dw.c Wed Feb 27 19:14:22 2013 +0000 @@ -3,7 +3,7 @@ * A GTK like cross-platform GUI * GTK forwarder module for portabilty. * - * (C) 2000-2012 Brian Smith + * (C) 2000-2013 Brian Smith * (C) 2003-2011 Mark Hessling * (C) 2002 Nickolay V. Shmyrev */ @@ -177,6 +177,7 @@ #endif static gint _switch_page_event(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer data); static gint _column_click_event(GtkWidget *widget, gint column_num, gpointer data); +static void _dw_signal_disconnect(gpointer data, GClosure *closure); /* Embedable Mozilla functions*/ #ifdef USE_GTKMOZEMBED @@ -1223,23 +1224,28 @@ return NULL; } -static SignalHandler _get_signal_handler(GtkWidget *widget, gpointer data) -{ - int counter = GPOINTER_TO_INT(data); - SignalHandler sh; - char text[101] = {0}; - - snprintf(text, 100, "_dw_sigwindow%d", counter); - sh.window = (HWND)gtk_object_get_data(GTK_OBJECT(widget), text); - snprintf(text, 100, "_dw_sigfunc%d", counter); - sh.func = (void *)gtk_object_get_data(GTK_OBJECT(widget), text); - snprintf(text, 100, "_dw_intfunc%d", counter); - sh.intfunc = (void *)gtk_object_get_data(GTK_OBJECT(widget), text); - snprintf(text, 100, "_dw_sigdata%d", counter); - sh.data = gtk_object_get_data(GTK_OBJECT(widget), text); - snprintf(text, 100, "_dw_sigcid%d", counter); - sh.cid = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), text)); - +static SignalHandler _get_signal_handler(gpointer data) +{ + SignalHandler sh = {0}; + + if(data) + { + void **params = (void **)data; + int counter = GPOINTER_TO_INT(params[0]); + GtkWidget *widget = (GtkWidget *)params[2]; + char text[101] = {0}; + + snprintf(text, 100, "_dw_sigwindow%d", counter); + sh.window = (HWND)gtk_object_get_data(GTK_OBJECT(widget), text); + snprintf(text, 100, "_dw_sigfunc%d", counter); + sh.func = (void *)gtk_object_get_data(GTK_OBJECT(widget), text); + snprintf(text, 100, "_dw_intfunc%d", counter); + sh.intfunc = (void *)gtk_object_get_data(GTK_OBJECT(widget), text); + snprintf(text, 100, "_dw_sigdata%d", counter); + sh.data = gtk_object_get_data(GTK_OBJECT(widget), text); + snprintf(text, 100, "_dw_sigcid%d", counter); + sh.cid = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), text)); + } return sh; } @@ -1292,7 +1298,7 @@ static gint _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data) { - SignalHandler work = _get_signal_handler((GtkWidget *)window, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1307,7 +1313,7 @@ static gint _button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1328,7 +1334,7 @@ static gint _button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1349,7 +1355,7 @@ static gint _motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1382,7 +1388,7 @@ static gint _delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1397,7 +1403,7 @@ static gint _key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1417,7 +1423,7 @@ static gint _generic_event(GtkWidget *widget, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1432,7 +1438,7 @@ static gint _activate_event(GtkWidget *widget, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1448,7 +1454,7 @@ static gint _configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1463,7 +1469,7 @@ static gint _expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1483,7 +1489,7 @@ static gint _item_select_event(GtkWidget *widget, GtkWidget *child, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); static int _dw_recursing = 0; int retval = FALSE; @@ -1528,7 +1534,7 @@ static gint _container_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1551,7 +1557,7 @@ static gint _tree_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1614,7 +1620,7 @@ if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); if(widget) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); if(work.window) { @@ -1636,7 +1642,7 @@ static gint _tree_expand_event(GtkTreeView *widget, GtkTreeIter *iter, GtkTreePath *path, gpointer data) { - SignalHandler work = _get_signal_handler((GtkWidget *)widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1650,7 +1656,7 @@ #else static gint _tree_select_event(GtkTree *tree, GtkWidget *child, gpointer data) { - SignalHandler work = _get_signal_handler((GtkWidget *)tree, data); + SignalHandler work = _get_signal_handler(data); GtkWidget *treeroot = (GtkWidget *)gtk_object_get_data(GTK_OBJECT(child), "_dw_tree"); int retval = FALSE; @@ -1675,7 +1681,7 @@ static gint _tree_expand_event(GtkTreeItem *treeitem, gpointer data) { - SignalHandler work = _get_signal_handler((GtkWidget *)treeitem, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1690,7 +1696,7 @@ static gint _container_select_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1714,7 +1720,7 @@ static gint _container_enter_event(GtkWidget *widget, GdkEventKey *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1750,7 +1756,7 @@ static gint _switch_page_event(GtkNotebook *notebook, GtkNotebookPage *page, guint page_num, gpointer data) { - SignalHandler work = _get_signal_handler((GtkWidget *)notebook, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1764,7 +1770,7 @@ static gint _column_click_event(GtkWidget *widget, gint column_num, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if ( dbgfp != NULL ) _dw_log("%s %d: %s\n",__FILE__,__LINE__,__func__); @@ -1778,7 +1784,7 @@ static gint _container_select_row(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); char *rowdata = gtk_clist_get_row_data(GTK_CLIST(widget), row); int (*contextfunc)(HWND, HWND, char *, void *, void *) = work.func; @@ -1819,7 +1825,7 @@ if (slider || spinbutton || scrollbar) { - SignalHandler work = _get_signal_handler((GtkWidget *)adjustment, data); + SignalHandler work = _get_signal_handler(data); if (work.window) { @@ -6212,14 +6218,24 @@ { void *thisfunc = (void *)gtk_object_get_data(GTK_OBJECT(tree), "_dw_tree_item_expand_func"); void *mydata = (void *)gtk_object_get_data(GTK_OBJECT(tree), "_dw_tree_item_expand_data"); - SignalHandler work = _get_signal_handler(tree, mydata); + void **params = calloc(sizeof(void *), 3): + SignalHandler work; + + params[0] = mydata; + params[2] = (void *)tree; + work = _get_signal_handler(mydata); if(thisfunc && work.window) { - int sigid = _set_signal_handler(newitem, work.window, work.func, work.data, thisfunc); - gint cid =gtk_signal_connect(GTK_OBJECT(newitem), "expand", GTK_SIGNAL_FUNC(thisfunc),(gpointer)sigid); + gint sigid = _set_signal_handler(newitem, work.window, work.func, work.data, thisfunc); + pointer[0] = GINT_TO_POINTER(sigid); + gint cid = g_signal_connect_data(G_OBJECT(newitem), "expand", G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0); _set_signal_handler_id(newitem, sigid, cid); } + else + { + free(params); + } } _dw_ignore_expand = 1; @@ -6230,7 +6246,7 @@ { void *thisfunc = (void *)gtk_object_get_data(GTK_OBJECT(tree), "_dw_select_child_func"); void *mydata = (void *)gtk_object_get_data(GTK_OBJECT(tree), "_dw_select_child_data"); - SignalHandler work = _get_signal_handler(tree, mydata); + SignalHandler work = _get_signal_handler(mydata); subtree = gtk_tree_new(); @@ -6243,7 +6259,7 @@ thisfunc = (void *)gtk_object_get_data(GTK_OBJECT(tree), "_dw_container_context_func"); mydata = (void *)gtk_object_get_data(GTK_OBJECT(tree), "_dw_container_context_data"); - work = _get_signal_handler(tree, mydata); + work = _get_signal_handler(mydata); if(thisfunc && work.window) { @@ -6358,12 +6374,18 @@ { void *thisfunc = (void *)gtk_object_get_data(GTK_OBJECT(tree), "_dw_tree_item_expand_func"); void *mydata = (void *)gtk_object_get_data(GTK_OBJECT(tree), "_dw_tree_item_expand_data"); - SignalHandler work = _get_signal_handler(tree, mydata); + void **params = calloc(sizeof(void *), 3): + SignalHandler work; + + params[0] = mydata; + params[2] = (void *)tree; + work = _get_signal_handler(mydata); if(thisfunc && work.window) { - int sigid = _set_signal_handler(item, work.window, work.func, work.data, thisfunc); - gint cid =gtk_signal_connect(GTK_OBJECT(item), "expand", GTK_SIGNAL_FUNC(thisfunc),(gpointer)sigid); + gint sigid = _set_signal_handler(item, work.window, work.func, work.data, thisfunc); + params[0] = GINT_TO_POINTER(sigid); + gint cid = g_signal_connect_data(G_OBJECT(item), "expand", G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0); _set_signal_handler_id(item, sigid, cid); } } @@ -6376,7 +6398,7 @@ { void *thisfunc = (void *)gtk_object_get_data(GTK_OBJECT(tree), "_dw_select_child_func"); void *mydata = (void *)gtk_object_get_data(GTK_OBJECT(tree), "_dw_select_child_data"); - SignalHandler work = _get_signal_handler(tree, mydata); + SignalHandler work = _get_signal_handler(mydata); subtree = gtk_tree_new(); @@ -6389,7 +6411,7 @@ thisfunc = (void *)gtk_object_get_data(GTK_OBJECT(tree), "_dw_container_context_func"); mydata = (void *)gtk_object_get_data(GTK_OBJECT(tree), "_dw_container_context_data"); - work = _get_signal_handler(tree, mydata); + work = _get_signal_handler(mydata); if(thisfunc && work.window) { @@ -13466,6 +13488,29 @@ return thiswindow; } +/* Internal function to free any allocated signal data.. + * and call any required function to free additional memory. + */ +static void _dw_signal_disconnect(gpointer data, GClosure *closure) +{ + if(data) + { + void **params = (void **)data; + void (*discfunc)(HWND, void *) = params[1]; + + if(discfunc) + { + SignalHandler work = _get_signal_handler(data); + + if(work.window) + { + discfunc(work.window, work.data); + } + } + free(data); + } +} + /* * Add a callback to a window event. * Parameters: @@ -13476,12 +13521,30 @@ */ void 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 dw_signal_connect_data(HWND window, char *signame, void *sigfunc, void *discfunc, void *data) +{ void *thisfunc = _findsigfunc(signame); char *thisname = signame; HWND thiswindow = window; int sigid, _locked_by_me = FALSE; + void **params = calloc(3, sizeof(void *)); gint cid; + /* Save the disconnect function pointer */ + params[1] = discfunc; + DW_MUTEX_LOCK; /* * If the window we are setting the signal on is a scrolled window we need to get @@ -13508,7 +13571,7 @@ thisfunc = _findsigfunc("tree-context"); sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc); - cid = gtk_signal_connect(GTK_OBJECT(thiswindow), "button_press_event", GTK_SIGNAL_FUNC(thisfunc), GINT_TO_POINTER(sigid)); + cid = g_signal_connect_data(G_OBJECT(thiswindow), "button_press_event", G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0); _set_signal_handler_id(thiswindow, sigid, cid); #if 0 @@ -13528,7 +13591,9 @@ thisname = "changed"; sigid = _set_signal_handler(treeview, window, sigfunc, data, thisfunc); - cid = g_signal_connect(G_OBJECT(thiswindow), thisname, (GCallback)thisfunc, GINT_TO_POINTER(sigid)); + params[0] = GINT_TO_POINTER(sigid); + params[2] = (void *)thiswindow; + cid = g_signal_connect_data(G_OBJECT(thiswindow), thisname, (GCallback)thisfunc, params, _dw_signal_disconnect, 0); _set_signal_handler_id(treeview, sigid, cid); DW_MUTEX_UNLOCK; return; @@ -13542,13 +13607,18 @@ { thisfunc = _findsigfunc("tree-context"); sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc); - + params[0] = GINT_TO_POINTER(sigid); + params[2] = (void *)thiswindow; gtk_object_set_data(GTK_OBJECT(thiswindow), "_dw_container_context_func", (gpointer)thisfunc); - gtk_object_set_data(GTK_OBJECT(thiswindow), "_dw_container_context_data", GINT_TO_POINTER(sigid)); - cid = gtk_signal_connect(GTK_OBJECT(thiswindow), "button_press_event", GTK_SIGNAL_FUNC(thisfunc), GINT_TO_POINTER(sigid)); + gtk_object_set_data(GTK_OBJECT(thiswindow), "_dw_container_context_data", params); + cid = gtk_signal_connect(GTK_OBJECT(thiswindow), "button_press_event", GTK_SIGNAL_FUNC(thisfunc), params); _set_signal_handler_id(thiswindow, sigid, cid); + + params = calloc(sizeof(void *), 3); sigid = _set_signal_handler(window, window, sigfunc, data, thisfunc); - cid = gtk_signal_connect(GTK_OBJECT(window), "button_press_event", GTK_SIGNAL_FUNC(thisfunc), GINT_TO_POINTER(sigid)); + params[0] = GINT_TO_POINTER(sigid); + params[2] = (void *)thiswindow; + cid = gtk_signal_connect(GTK_OBJECT(window), "button_press_event", GTK_SIGNAL_FUNC(thisfunc), params); _set_signal_handler_id(window, sigid, cid); DW_MUTEX_UNLOCK; return; @@ -13558,6 +13628,7 @@ if(thisfunc) { sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc); + params[0] = GINT_TO_POINTER(sigid); gtk_object_set_data(GTK_OBJECT(thiswindow), "_dw_select_child_func", (gpointer)thisfunc); gtk_object_set_data(GTK_OBJECT(thiswindow), "_dw_select_child_data", GINT_TO_POINTER(sigid)); } @@ -13578,7 +13649,9 @@ else if (GTK_IS_CLIST(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_ENTER) == 0) { sigid = _set_signal_handler(thiswindow, window, sigfunc, data, _container_enter_event); - cid = gtk_signal_connect(GTK_OBJECT(thiswindow), "key_press_event", GTK_SIGNAL_FUNC(_container_enter_event), GINT_TO_POINTER(sigid)); + params[0] = GINT_TO_POINTER(sigid); + params[2] = (void *)thiswindow; + cid = g_signal_connect_data(G_OBJECT(thiswindow), "key_press_event", G_CALLBACK(_container_enter_event), params, _dw_signal_disconnect, 0); _set_signal_handler_id(thiswindow, sigid, cid); thisname = "button_press_event"; @@ -13634,7 +13707,9 @@ } sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc); - cid = gtk_signal_connect(GTK_OBJECT(thiswindow), thisname, GTK_SIGNAL_FUNC(thisfunc),GINT_TO_POINTER(sigid)); + params[0] = GINT_TO_POINTER(sigid); + params[2] = (void *)thiswindow; + cid = g_signal_connect_data(G_OBJECT(thiswindow), thisname, G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0); _set_signal_handler_id(thiswindow, sigid, cid); DW_MUTEX_UNLOCK; } @@ -13646,22 +13721,25 @@ */ void dw_signal_disconnect_by_name(HWND window, char *signame) { - HWND thiswindow; int z, count; void *thisfunc; int _locked_by_me = FALSE; - - DW_MUTEX_LOCK; - thiswindow = _find_signal_window(window, signame); - count = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(thiswindow), "_dw_sigcounter")); - thisfunc = _findsigfunc(signame); + void **params = alloca(sizeof(void *) * 3); + + DW_MUTEX_LOCK; + params[2] = _find_signal_window(window, signame); + count = GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(params[2]), "_dw_sigcounter")); + thisfunc = _findsigfunc(signame); for(z=0;z + * (C) 2000-2013 Brian Smith * (C) 2003-2011 Mark Hessling * (C) 2002 Nickolay V. Shmyrev */ @@ -152,6 +152,8 @@ static gint _tree_expand_event(GtkTreeView *treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer data); static gint _switch_page_event(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer data); static gint _column_click_event(GtkWidget *widget, gpointer data); +static void _dw_signal_disconnect(gpointer data, GClosure *closure); + #ifdef USE_WEBKIT /* @@ -1083,23 +1085,28 @@ return NULL; } -static SignalHandler _get_signal_handler(GtkWidget *widget, gpointer data) -{ - int counter = GPOINTER_TO_INT(data); - SignalHandler sh; - char text[100]; - - sprintf(text, "_dw_sigwindow%d", counter); - sh.window = (HWND)g_object_get_data(G_OBJECT(widget), text); - sprintf(text, "_dw_sigfunc%d", counter); - sh.func = (void *)g_object_get_data(G_OBJECT(widget), text); - sprintf(text, "_dw_intfunc%d", counter); - sh.intfunc = (void *)g_object_get_data(G_OBJECT(widget), text); - sprintf(text, "_dw_sigdata%d", counter); - sh.data = g_object_get_data(G_OBJECT(widget), text); - sprintf(text, "_dw_sigcid%d", counter); - sh.cid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), text)); - +static SignalHandler _get_signal_handler(gpointer data) +{ + SignalHandler sh = {0}; + + if(data) + { + void **params = (void **)data; + int counter = GPOINTER_TO_INT(params[0]); + GtkWidget *widget = (GtkWidget *)params[2]; + char text[100]; + + sprintf(text, "_dw_sigwindow%d", counter); + sh.window = (HWND)g_object_get_data(G_OBJECT(widget), text); + sprintf(text, "_dw_sigfunc%d", counter); + sh.func = (void *)g_object_get_data(G_OBJECT(widget), text); + sprintf(text, "_dw_intfunc%d", counter); + sh.intfunc = (void *)g_object_get_data(G_OBJECT(widget), text); + sprintf(text, "_dw_sigdata%d", counter); + sh.data = g_object_get_data(G_OBJECT(widget), text); + sprintf(text, "_dw_sigcid%d", counter); + sh.cid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), text)); + } return sh; } @@ -1122,7 +1129,7 @@ g_object_set_data(G_OBJECT(widget), text, NULL); } -static int _set_signal_handler(GtkWidget *widget, HWND window, void *func, gpointer data, void *intfunc) +static int _set_signal_handler(GtkWidget *widget, HWND window, void *func, gpointer data, void *intfunc, void *discfunc) { int counter = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_sigcounter")); char text[100]; @@ -1133,6 +1140,8 @@ g_object_set_data(G_OBJECT(widget), text, (gpointer)func); sprintf(text, "_dw_intfunc%d", counter); g_object_set_data(G_OBJECT(widget), text, (gpointer)intfunc); + sprintf(text, "_dw_discfunc%d", counter); + g_object_set_data(G_OBJECT(widget), text, (gpointer)discfunc); sprintf(text, "_dw_sigdata%d", counter); g_object_set_data(G_OBJECT(widget), text, (gpointer)data); @@ -1152,7 +1161,7 @@ static gint _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data) { - SignalHandler work = _get_signal_handler((GtkWidget *)window, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(work.window) @@ -1166,7 +1175,7 @@ static gint _button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(work.window) @@ -1186,7 +1195,7 @@ static gint _button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(work.window) @@ -1206,7 +1215,7 @@ static gint _motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(work.window) @@ -1238,7 +1247,7 @@ static gint _delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(work.window) @@ -1252,7 +1261,7 @@ static gint _key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(work.window) @@ -1271,7 +1280,7 @@ static gint _generic_event(GtkWidget *widget, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(work.window) @@ -1285,7 +1294,7 @@ static gint _activate_event(GtkWidget *widget, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(work.window && !_dw_ignore_click) @@ -1300,7 +1309,7 @@ static gint _configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(work.window) @@ -1314,7 +1323,7 @@ static gint _expose_event(GtkWidget *widget, cairo_t *cr, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(work.window) @@ -1332,7 +1341,7 @@ static gint _combobox_select_event(GtkWidget *widget, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(g_object_get_data(G_OBJECT(widget), "_dw_recursing")) @@ -1375,7 +1384,7 @@ static gint _tree_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(work.window) @@ -1442,7 +1451,7 @@ if(widget) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); if(work.window) { @@ -1532,7 +1541,7 @@ static gint _tree_expand_event(GtkTreeView *widget, GtkTreeIter *iter, GtkTreePath *path, gpointer data) { - SignalHandler work = _get_signal_handler((GtkWidget *)widget, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(!_dw_ignore_expand && work.window) @@ -1545,7 +1554,7 @@ static gint _container_enter_event(GtkWidget *widget, GdkEventAny *event, gpointer data) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); GdkEventKey *keyevent = (GdkEventKey *)event; GdkEventButton *buttonevent = (GdkEventButton *)event; int retval = FALSE; @@ -1613,7 +1622,7 @@ static gint _switch_page_event(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer data) { - SignalHandler work = _get_signal_handler((GtkWidget *)notebook, data); + SignalHandler work = _get_signal_handler(data); int retval = FALSE; if(work.window) @@ -1626,20 +1635,27 @@ static gint _column_click_event(GtkWidget *widget, gpointer data) { - GtkWidget *tree = data; - gint handlerdata = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(tree), "_dw_column_click_id")); - SignalHandler work; + void **params = data; int retval = FALSE; - - if(handlerdata) - { - work = _get_signal_handler(tree, GINT_TO_POINTER(handlerdata-1)); - - if(work.window) - { - int column_num = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_column")); - int (*clickcolumnfunc)(HWND, int, void *) = work.func; - retval = clickcolumnfunc(work.window, column_num, work.data); + + if(params && params[2]) + { + GtkWidget *tree = (GtkWidget *)params[2]; + gint handlerdata = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(tree), "_dw_column_click_id")); + + if(handlerdata) + { + SignalHandler work; + + params[0] = GINT_TO_POINTER(handlerdata-1); + work = _get_signal_handler(params); + + if(work.window) + { + int column_num = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_column")); + int (*clickcolumnfunc)(HWND, int, void *) = work.func; + retval = clickcolumnfunc(work.window, column_num, work.data); + } } } return retval; @@ -1676,7 +1692,7 @@ if (slider || spinbutton || scrollbar) { - SignalHandler work = _get_signal_handler(widget, data); + SignalHandler work = _get_signal_handler(data); if (work.window) { @@ -5526,6 +5542,7 @@ g_object_set_data(G_OBJECT(tree), numbuf, GINT_TO_POINTER(flags[z])); col = gtk_tree_view_column_new(); rend = NULL; + void **params = calloc(sizeof(void *), 3); if(z == 0 && flags[z] & DW_CFA_STRINGANDICON) { @@ -5571,7 +5588,8 @@ gtk_tree_view_column_set_resizable(col, TRUE); } g_object_set_data(G_OBJECT(col), "_dw_column", GINT_TO_POINTER(z)); - g_signal_connect(G_OBJECT(col), "clicked", G_CALLBACK(_column_click_event), (gpointer)tree); + params[2] = tree; + g_signal_connect_data(G_OBJECT(col), "clicked", G_CALLBACK(_column_click_event), (gpointer)params, _dw_signal_disconnect, 0); gtk_tree_view_column_set_title(col, titles[z]); if(flags[z] & DW_CFA_RIGHT) { @@ -11191,11 +11209,52 @@ */ void dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) { + dw_signal_connect_data(window, signame, sigfunc, NULL, data); +} + +/* Internal function to free any allocated signal data.. + * and call any required function to free additional memory. + */ +static void _dw_signal_disconnect(gpointer data, GClosure *closure) +{ + if(data) + { + void **params = (void **)data; + void (*discfunc)(HWND, void *) = params[1]; + + if(discfunc) + { + SignalHandler work = _get_signal_handler(data); + + if(work.window) + { + discfunc(work.window, work.data); + } + } + free(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 dw_signal_connect_data(HWND window, char *signame, void *sigfunc, void *discfunc, void *data) +{ void *thisfunc = _findsigfunc(signame); char *thisname = signame; HWND thiswindow = window; int sigid, _locked_by_me = FALSE; + void **params = calloc(3, sizeof(void *)); gint cid; + + /* Save the disconnect function pointer */ + params[1] = discfunc; DW_MUTEX_LOCK; /* @@ -11218,8 +11277,10 @@ } else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_CONTEXT) == 0) { - sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc); - cid = g_signal_connect(G_OBJECT(thiswindow), "button_press_event", G_CALLBACK(thisfunc), GINT_TO_POINTER(sigid)); + sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc, discfunc); + params[0] = GINT_TO_POINTER(sigid); + params[2] = (void *)thiswindow; + cid = g_signal_connect_data(G_OBJECT(thiswindow), "button_press_event", G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0); _set_signal_handler_id(thiswindow, sigid, cid); DW_MUTEX_UNLOCK; @@ -11232,15 +11293,17 @@ thisname = "changed"; - sigid = _set_signal_handler(widget, window, sigfunc, data, thisfunc); + sigid = _set_signal_handler(widget, window, sigfunc, data, thisfunc, discfunc); + params[0] = GINT_TO_POINTER(sigid); + params[2] = (void *)thiswindow; if(GTK_IS_TREE_VIEW(thiswindow)) { thiswindow = (GtkWidget *)gtk_tree_view_get_selection(GTK_TREE_VIEW(thiswindow)); - cid = g_signal_connect(G_OBJECT(thiswindow), thisname, G_CALLBACK(thisfunc), GINT_TO_POINTER(sigid)); + cid = g_signal_connect_data(G_OBJECT(thiswindow), thisname, G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0); } else { - cid = g_signal_connect(G_OBJECT(thiswindow), thisname, G_CALLBACK(_combobox_select_event), GINT_TO_POINTER(sigid)); + cid = g_signal_connect_data(G_OBJECT(thiswindow), thisname, G_CALLBACK(_combobox_select_event), params, _dw_signal_disconnect, 0); } _set_signal_handler_id(widget, sigid, cid); @@ -11253,9 +11316,13 @@ } else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_ENTER) == 0) { - sigid = _set_signal_handler(thiswindow, window, sigfunc, data, _container_enter_event); - cid = g_signal_connect(G_OBJECT(thiswindow), "key_press_event", G_CALLBACK(_container_enter_event), GINT_TO_POINTER(sigid)); + sigid = _set_signal_handler(thiswindow, window, sigfunc, data, _container_enter_event, discfunc); + params[0] = GINT_TO_POINTER(sigid); + params[2] = (void *)thiswindow; + cid = g_signal_connect_data(G_OBJECT(thiswindow), "key_press_event", G_CALLBACK(_container_enter_event), params, _dw_signal_disconnect, 0); _set_signal_handler_id(thiswindow, sigid, cid); + + params = calloc(sizeof(void *), 3); thisname = "button_press_event"; thisfunc = _findsigfunc(DW_SIGNAL_ITEM_ENTER); @@ -11265,7 +11332,7 @@ /* We don't actually need a signal handler here... just need to assign the handler ID * Since the handlers for the columns were already created in _dw_container_setup() */ - sigid = _set_signal_handler(thiswindow, window, sigfunc, data, _column_click_event); + sigid = _set_signal_handler(thiswindow, window, sigfunc, data, _column_click_event, discfunc); g_object_set_data(G_OBJECT(thiswindow), "_dw_column_click_id", GINT_TO_POINTER(sigid+1)); DW_MUTEX_UNLOCK; return; @@ -11295,12 +11362,15 @@ if (!thisfunc || !thiswindow) { + free(params); DW_MUTEX_UNLOCK; return; } - sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc); - cid = g_signal_connect(G_OBJECT(thiswindow), thisname, G_CALLBACK(thisfunc),GINT_TO_POINTER(sigid)); + sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc, discfunc); + params[0] = GINT_TO_POINTER(sigid); + params[2] = (void *)thiswindow; + cid = g_signal_connect_data(G_OBJECT(thiswindow), thisname, G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0); _set_signal_handler_id(thiswindow, sigid, cid); DW_MUTEX_UNLOCK; } @@ -11312,22 +11382,25 @@ */ void dw_signal_disconnect_by_name(HWND window, char *signame) { - HWND thiswindow; int z, count; void *thisfunc; int _locked_by_me = FALSE; - - DW_MUTEX_LOCK; - thiswindow = _find_signal_window(window, signame); - count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(thiswindow), "_dw_sigcounter")); - thisfunc = _findsigfunc(signame); + void **params = alloca(sizeof(void *) * 3); + + DW_MUTEX_LOCK; + params[2] = _find_signal_window(window, signame); + count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(params[2]), "_dw_sigcounter")); + thisfunc = _findsigfunc(signame); for(z=0;z + * (C) 2011-2013 Brian Smith * (C) 2011 Mark Hessling * * 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; diff -r 5f0e4ca14dcd -r 4790589f52a9 os2/dw.c --- a/os2/dw.c Fri Feb 15 09:22:56 2013 +0000 +++ b/os2/dw.c Wed Feb 27 19:14:22 2013 +0000 @@ -166,6 +166,7 @@ HWND window; int id; void *signalfunction; + void *discfunction; void *data; } SignalHandler; @@ -216,7 +217,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)); @@ -224,6 +225,7 @@ new->window = window; new->id = id; new->signalfunction = signalfunction; + new->discfunction = discfunc; new->data = data; new->next = NULL; @@ -13210,7 +13212,7 @@ if(timerid) { - _new_signal(WM_TIMER, NULLHANDLE, timerid, sigfunc, data); + _new_signal(WM_TIMER, NULLHANDLE, timerid, sigfunc, NULL, data); return timerid; } } @@ -13267,6 +13269,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) @@ -13291,7 +13307,7 @@ window = owner; } } - _new_signal(message, window, id, sigfunc, data); + _new_signal(message, window, id, sigfunc, discfunc, data); } } } @@ -13313,6 +13329,13 @@ { if(((window < 65536 && tmp->id == window) || tmp->window == window) && tmp->message == message) { + void (API_FUNC discfunc)(HWND, void *) = (void (API_FUNC)(HWND, void *))tmp->discfunction; + + if(discfunc) + { + discfunc(tmp->window, tmp->data); + } + if(prev) { prev->next = tmp->next; @@ -13347,6 +13370,13 @@ { if((window < 65536 && tmp->id == window) || tmp->window == window) { + void (API_FUNC discfunc)(HWND, void *) = (void (API_FUNC)(HWND, void *))tmp->discfunction; + + if(discfunc) + { + discfunc(tmp->window, tmp->data); + } + if(prev) { prev->next = tmp->next; @@ -13382,6 +13412,13 @@ { if(((window < 65536 && tmp->id == window) || tmp->window == window) && tmp->data == data) { + void (API_FUNC discfunc)(HWND, void *) = (void (API_FUNC)(HWND, void *))tmp->discfunction; + + if(discfunc) + { + discfunc(tmp->window, tmp->data); + } + if(prev) { prev->next = tmp->next; diff -r 5f0e4ca14dcd -r 4790589f52a9 win/dw.c --- 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 + * (C) 2000-2013 Brian Smith * (C) 2003-2011 Mark Hessling * */ @@ -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;