comparison gtk3/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 ff80ad40a5d6
children c836603d3f14
comparison
equal deleted inserted replaced
1852:5f0e4ca14dcd 1853:4790589f52a9
1 /* 1 /*
2 * Dynamic Windows: 2 * Dynamic Windows:
3 * A GTK like cross-platform GUI 3 * A GTK like cross-platform GUI
4 * GTK3 forwarder module for portabilty. 4 * GTK3 forwarder module for portabilty.
5 * 5 *
6 * (C) 2000-2012 Brian Smith <brian@dbsoft.org> 6 * (C) 2000-2013 Brian Smith <brian@dbsoft.org>
7 * (C) 2003-2011 Mark Hessling <mark@rexx.org> 7 * (C) 2003-2011 Mark Hessling <mark@rexx.org>
8 * (C) 2002 Nickolay V. Shmyrev <shmyrev@yandex.ru> 8 * (C) 2002 Nickolay V. Shmyrev <shmyrev@yandex.ru>
9 */ 9 */
10 #include "config.h" 10 #include "config.h"
11 #include "dw.h" 11 #include "dw.h"
150 static gint _value_changed_event(GtkWidget *widget, gpointer user_data); 150 static gint _value_changed_event(GtkWidget *widget, gpointer user_data);
151 static gint _tree_select_event(GtkTreeSelection *sel, gpointer data); 151 static gint _tree_select_event(GtkTreeSelection *sel, gpointer data);
152 static gint _tree_expand_event(GtkTreeView *treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer data); 152 static gint _tree_expand_event(GtkTreeView *treeview, GtkTreeIter *arg1, GtkTreePath *arg2, gpointer data);
153 static gint _switch_page_event(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer data); 153 static gint _switch_page_event(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer data);
154 static gint _column_click_event(GtkWidget *widget, gpointer data); 154 static gint _column_click_event(GtkWidget *widget, gpointer data);
155 static void _dw_signal_disconnect(gpointer data, GClosure *closure);
156
155 157
156 #ifdef USE_WEBKIT 158 #ifdef USE_WEBKIT
157 /* 159 /*
158 * we need to add these equivalents from webkitwebview.h so we can refer to 160 * we need to add these equivalents from webkitwebview.h so we can refer to
159 * our own pointers to functions (we don't link with the webkit libraries 161 * our own pointers to functions (we don't link with the webkit libraries
1081 return SignalTranslate[z].func; 1083 return SignalTranslate[z].func;
1082 } 1084 }
1083 return NULL; 1085 return NULL;
1084 } 1086 }
1085 1087
1086 static SignalHandler _get_signal_handler(GtkWidget *widget, gpointer data) 1088 static SignalHandler _get_signal_handler(gpointer data)
1087 { 1089 {
1088 int counter = GPOINTER_TO_INT(data); 1090 SignalHandler sh = {0};
1089 SignalHandler sh; 1091
1090 char text[100]; 1092 if(data)
1091 1093 {
1092 sprintf(text, "_dw_sigwindow%d", counter); 1094 void **params = (void **)data;
1093 sh.window = (HWND)g_object_get_data(G_OBJECT(widget), text); 1095 int counter = GPOINTER_TO_INT(params[0]);
1094 sprintf(text, "_dw_sigfunc%d", counter); 1096 GtkWidget *widget = (GtkWidget *)params[2];
1095 sh.func = (void *)g_object_get_data(G_OBJECT(widget), text); 1097 char text[100];
1096 sprintf(text, "_dw_intfunc%d", counter); 1098
1097 sh.intfunc = (void *)g_object_get_data(G_OBJECT(widget), text); 1099 sprintf(text, "_dw_sigwindow%d", counter);
1098 sprintf(text, "_dw_sigdata%d", counter); 1100 sh.window = (HWND)g_object_get_data(G_OBJECT(widget), text);
1099 sh.data = g_object_get_data(G_OBJECT(widget), text); 1101 sprintf(text, "_dw_sigfunc%d", counter);
1100 sprintf(text, "_dw_sigcid%d", counter); 1102 sh.func = (void *)g_object_get_data(G_OBJECT(widget), text);
1101 sh.cid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), text)); 1103 sprintf(text, "_dw_intfunc%d", counter);
1102 1104 sh.intfunc = (void *)g_object_get_data(G_OBJECT(widget), text);
1105 sprintf(text, "_dw_sigdata%d", counter);
1106 sh.data = g_object_get_data(G_OBJECT(widget), text);
1107 sprintf(text, "_dw_sigcid%d", counter);
1108 sh.cid = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), text));
1109 }
1103 return sh; 1110 return sh;
1104 } 1111 }
1105 1112
1106 static void _remove_signal_handler(GtkWidget *widget, int counter) 1113 static void _remove_signal_handler(GtkWidget *widget, int counter)
1107 { 1114 {
1120 g_object_set_data(G_OBJECT(widget), text, NULL); 1127 g_object_set_data(G_OBJECT(widget), text, NULL);
1121 sprintf(text, "_dw_sigdata%d", counter); 1128 sprintf(text, "_dw_sigdata%d", counter);
1122 g_object_set_data(G_OBJECT(widget), text, NULL); 1129 g_object_set_data(G_OBJECT(widget), text, NULL);
1123 } 1130 }
1124 1131
1125 static int _set_signal_handler(GtkWidget *widget, HWND window, void *func, gpointer data, void *intfunc) 1132 static int _set_signal_handler(GtkWidget *widget, HWND window, void *func, gpointer data, void *intfunc, void *discfunc)
1126 { 1133 {
1127 int counter = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_sigcounter")); 1134 int counter = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_sigcounter"));
1128 char text[100]; 1135 char text[100];
1129 1136
1130 sprintf(text, "_dw_sigwindow%d", counter); 1137 sprintf(text, "_dw_sigwindow%d", counter);
1131 g_object_set_data(G_OBJECT(widget), text, (gpointer)window); 1138 g_object_set_data(G_OBJECT(widget), text, (gpointer)window);
1132 sprintf(text, "_dw_sigfunc%d", counter); 1139 sprintf(text, "_dw_sigfunc%d", counter);
1133 g_object_set_data(G_OBJECT(widget), text, (gpointer)func); 1140 g_object_set_data(G_OBJECT(widget), text, (gpointer)func);
1134 sprintf(text, "_dw_intfunc%d", counter); 1141 sprintf(text, "_dw_intfunc%d", counter);
1135 g_object_set_data(G_OBJECT(widget), text, (gpointer)intfunc); 1142 g_object_set_data(G_OBJECT(widget), text, (gpointer)intfunc);
1143 sprintf(text, "_dw_discfunc%d", counter);
1144 g_object_set_data(G_OBJECT(widget), text, (gpointer)discfunc);
1136 sprintf(text, "_dw_sigdata%d", counter); 1145 sprintf(text, "_dw_sigdata%d", counter);
1137 g_object_set_data(G_OBJECT(widget), text, (gpointer)data); 1146 g_object_set_data(G_OBJECT(widget), text, (gpointer)data);
1138 1147
1139 counter++; 1148 counter++;
1140 g_object_set_data(G_OBJECT(widget), "_dw_sigcounter", GINT_TO_POINTER(counter)); 1149 g_object_set_data(G_OBJECT(widget), "_dw_sigcounter", GINT_TO_POINTER(counter));
1150 g_object_set_data(G_OBJECT(widget), text, GINT_TO_POINTER(cid)); 1159 g_object_set_data(G_OBJECT(widget), text, GINT_TO_POINTER(cid));
1151 } 1160 }
1152 1161
1153 static gint _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data) 1162 static gint _set_focus_event(GtkWindow *window, GtkWidget *widget, gpointer data)
1154 { 1163 {
1155 SignalHandler work = _get_signal_handler((GtkWidget *)window, data); 1164 SignalHandler work = _get_signal_handler(data);
1156 int retval = FALSE; 1165 int retval = FALSE;
1157 1166
1158 if(work.window) 1167 if(work.window)
1159 { 1168 {
1160 int (*setfocusfunc)(HWND, void *) = work.func; 1169 int (*setfocusfunc)(HWND, void *) = work.func;
1164 return retval; 1173 return retval;
1165 } 1174 }
1166 1175
1167 static gint _button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data) 1176 static gint _button_press_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
1168 { 1177 {
1169 SignalHandler work = _get_signal_handler(widget, data); 1178 SignalHandler work = _get_signal_handler(data);
1170 int retval = FALSE; 1179 int retval = FALSE;
1171 1180
1172 if(work.window) 1181 if(work.window)
1173 { 1182 {
1174 int (*buttonfunc)(HWND, int, int, int, void *) = work.func; 1183 int (*buttonfunc)(HWND, int, int, int, void *) = work.func;
1184 return retval; 1193 return retval;
1185 } 1194 }
1186 1195
1187 static gint _button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data) 1196 static gint _button_release_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
1188 { 1197 {
1189 SignalHandler work = _get_signal_handler(widget, data); 1198 SignalHandler work = _get_signal_handler(data);
1190 int retval = FALSE; 1199 int retval = FALSE;
1191 1200
1192 if(work.window) 1201 if(work.window)
1193 { 1202 {
1194 int (*buttonfunc)(HWND, int, int, int, void *) = work.func; 1203 int (*buttonfunc)(HWND, int, int, int, void *) = work.func;
1204 return retval; 1213 return retval;
1205 } 1214 }
1206 1215
1207 static gint _motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data) 1216 static gint _motion_notify_event(GtkWidget *widget, GdkEventMotion *event, gpointer data)
1208 { 1217 {
1209 SignalHandler work = _get_signal_handler(widget, data); 1218 SignalHandler work = _get_signal_handler(data);
1210 int retval = FALSE; 1219 int retval = FALSE;
1211 1220
1212 if(work.window) 1221 if(work.window)
1213 { 1222 {
1214 int (*motionfunc)(HWND, int, int, int, void *) = work.func; 1223 int (*motionfunc)(HWND, int, int, int, void *) = work.func;
1236 return retval; 1245 return retval;
1237 } 1246 }
1238 1247
1239 static gint _delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) 1248 static gint _delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
1240 { 1249 {
1241 SignalHandler work = _get_signal_handler(widget, data); 1250 SignalHandler work = _get_signal_handler(data);
1242 int retval = FALSE; 1251 int retval = FALSE;
1243 1252
1244 if(work.window) 1253 if(work.window)
1245 { 1254 {
1246 int (*closefunc)(HWND, void *) = work.func; 1255 int (*closefunc)(HWND, void *) = work.func;
1250 return retval; 1259 return retval;
1251 } 1260 }
1252 1261
1253 static gint _key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data) 1262 static gint _key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data)
1254 { 1263 {
1255 SignalHandler work = _get_signal_handler(widget, data); 1264 SignalHandler work = _get_signal_handler(data);
1256 int retval = FALSE; 1265 int retval = FALSE;
1257 1266
1258 if(work.window) 1267 if(work.window)
1259 { 1268 {
1260 int (*keypressfunc)(HWND, char, int, int, void *, char *) = work.func; 1269 int (*keypressfunc)(HWND, char, int, int, void *, char *) = work.func;
1269 return retval; 1278 return retval;
1270 } 1279 }
1271 1280
1272 static gint _generic_event(GtkWidget *widget, gpointer data) 1281 static gint _generic_event(GtkWidget *widget, gpointer data)
1273 { 1282 {
1274 SignalHandler work = _get_signal_handler(widget, data); 1283 SignalHandler work = _get_signal_handler(data);
1275 int retval = FALSE; 1284 int retval = FALSE;
1276 1285
1277 if(work.window) 1286 if(work.window)
1278 { 1287 {
1279 int (*genericfunc)(HWND, void *) = work.func; 1288 int (*genericfunc)(HWND, void *) = work.func;
1283 return retval; 1292 return retval;
1284 } 1293 }
1285 1294
1286 static gint _activate_event(GtkWidget *widget, gpointer data) 1295 static gint _activate_event(GtkWidget *widget, gpointer data)
1287 { 1296 {
1288 SignalHandler work = _get_signal_handler(widget, data); 1297 SignalHandler work = _get_signal_handler(data);
1289 int retval = FALSE; 1298 int retval = FALSE;
1290 1299
1291 if(work.window && !_dw_ignore_click) 1300 if(work.window && !_dw_ignore_click)
1292 { 1301 {
1293 int (*activatefunc)(HWND, void *) = work.func; 1302 int (*activatefunc)(HWND, void *) = work.func;
1298 return retval; 1307 return retval;
1299 } 1308 }
1300 1309
1301 static gint _configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data) 1310 static gint _configure_event(GtkWidget *widget, GdkEventConfigure *event, gpointer data)
1302 { 1311 {
1303 SignalHandler work = _get_signal_handler(widget, data); 1312 SignalHandler work = _get_signal_handler(data);
1304 int retval = FALSE; 1313 int retval = FALSE;
1305 1314
1306 if(work.window) 1315 if(work.window)
1307 { 1316 {
1308 int (*sizefunc)(HWND, int, int, void *) = work.func; 1317 int (*sizefunc)(HWND, int, int, void *) = work.func;
1312 return retval; 1321 return retval;
1313 } 1322 }
1314 1323
1315 static gint _expose_event(GtkWidget *widget, cairo_t *cr, gpointer data) 1324 static gint _expose_event(GtkWidget *widget, cairo_t *cr, gpointer data)
1316 { 1325 {
1317 SignalHandler work = _get_signal_handler(widget, data); 1326 SignalHandler work = _get_signal_handler(data);
1318 int retval = FALSE; 1327 int retval = FALSE;
1319 1328
1320 if(work.window) 1329 if(work.window)
1321 { 1330 {
1322 DWExpose exp; 1331 DWExpose exp;
1330 return retval; 1339 return retval;
1331 } 1340 }
1332 1341
1333 static gint _combobox_select_event(GtkWidget *widget, gpointer data) 1342 static gint _combobox_select_event(GtkWidget *widget, gpointer data)
1334 { 1343 {
1335 SignalHandler work = _get_signal_handler(widget, data); 1344 SignalHandler work = _get_signal_handler(data);
1336 int retval = FALSE; 1345 int retval = FALSE;
1337 1346
1338 if(g_object_get_data(G_OBJECT(widget), "_dw_recursing")) 1347 if(g_object_get_data(G_OBJECT(widget), "_dw_recursing"))
1339 return FALSE; 1348 return FALSE;
1340 1349
1373 return retval; 1382 return retval;
1374 } 1383 }
1375 1384
1376 static gint _tree_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data) 1385 static gint _tree_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
1377 { 1386 {
1378 SignalHandler work = _get_signal_handler(widget, data); 1387 SignalHandler work = _get_signal_handler(data);
1379 int retval = FALSE; 1388 int retval = FALSE;
1380 1389
1381 if(work.window) 1390 if(work.window)
1382 { 1391 {
1383 if(event->button == 3) 1392 if(event->button == 3)
1440 GtkWidget *item = NULL, *widget = (GtkWidget *)gtk_tree_selection_get_tree_view(sel); 1449 GtkWidget *item = NULL, *widget = (GtkWidget *)gtk_tree_selection_get_tree_view(sel);
1441 int retval = FALSE; 1450 int retval = FALSE;
1442 1451
1443 if(widget) 1452 if(widget)
1444 { 1453 {
1445 SignalHandler work = _get_signal_handler(widget, data); 1454 SignalHandler work = _get_signal_handler(data);
1446 1455
1447 if(work.window) 1456 if(work.window)
1448 { 1457 {
1449 int (*treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = work.func; 1458 int (*treeselectfunc)(HWND, HTREEITEM, char *, void *, void *) = work.func;
1450 GtkTreeIter iter; 1459 GtkTreeIter iter;
1530 return retval; 1539 return retval;
1531 } 1540 }
1532 1541
1533 static gint _tree_expand_event(GtkTreeView *widget, GtkTreeIter *iter, GtkTreePath *path, gpointer data) 1542 static gint _tree_expand_event(GtkTreeView *widget, GtkTreeIter *iter, GtkTreePath *path, gpointer data)
1534 { 1543 {
1535 SignalHandler work = _get_signal_handler((GtkWidget *)widget, data); 1544 SignalHandler work = _get_signal_handler(data);
1536 int retval = FALSE; 1545 int retval = FALSE;
1537 1546
1538 if(!_dw_ignore_expand && work.window) 1547 if(!_dw_ignore_expand && work.window)
1539 { 1548 {
1540 int (*treeexpandfunc)(HWND, HTREEITEM, void *) = work.func; 1549 int (*treeexpandfunc)(HWND, HTREEITEM, void *) = work.func;
1543 return retval; 1552 return retval;
1544 } 1553 }
1545 1554
1546 static gint _container_enter_event(GtkWidget *widget, GdkEventAny *event, gpointer data) 1555 static gint _container_enter_event(GtkWidget *widget, GdkEventAny *event, gpointer data)
1547 { 1556 {
1548 SignalHandler work = _get_signal_handler(widget, data); 1557 SignalHandler work = _get_signal_handler(data);
1549 GdkEventKey *keyevent = (GdkEventKey *)event; 1558 GdkEventKey *keyevent = (GdkEventKey *)event;
1550 GdkEventButton *buttonevent = (GdkEventButton *)event; 1559 GdkEventButton *buttonevent = (GdkEventButton *)event;
1551 int retval = FALSE; 1560 int retval = FALSE;
1552 1561
1553 if(work.window) 1562 if(work.window)
1611 } 1620 }
1612 1621
1613 1622
1614 static gint _switch_page_event(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer data) 1623 static gint _switch_page_event(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer data)
1615 { 1624 {
1616 SignalHandler work = _get_signal_handler((GtkWidget *)notebook, data); 1625 SignalHandler work = _get_signal_handler(data);
1617 int retval = FALSE; 1626 int retval = FALSE;
1618 1627
1619 if(work.window) 1628 if(work.window)
1620 { 1629 {
1621 int (*switchpagefunc)(HWND, unsigned long, void *) = work.func; 1630 int (*switchpagefunc)(HWND, unsigned long, void *) = work.func;
1624 return retval; 1633 return retval;
1625 } 1634 }
1626 1635
1627 static gint _column_click_event(GtkWidget *widget, gpointer data) 1636 static gint _column_click_event(GtkWidget *widget, gpointer data)
1628 { 1637 {
1629 GtkWidget *tree = data; 1638 void **params = data;
1630 gint handlerdata = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(tree), "_dw_column_click_id"));
1631 SignalHandler work;
1632 int retval = FALSE; 1639 int retval = FALSE;
1633 1640
1634 if(handlerdata) 1641 if(params && params[2])
1635 { 1642 {
1636 work = _get_signal_handler(tree, GINT_TO_POINTER(handlerdata-1)); 1643 GtkWidget *tree = (GtkWidget *)params[2];
1637 1644 gint handlerdata = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(tree), "_dw_column_click_id"));
1638 if(work.window) 1645
1639 { 1646 if(handlerdata)
1640 int column_num = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_column")); 1647 {
1641 int (*clickcolumnfunc)(HWND, int, void *) = work.func; 1648 SignalHandler work;
1642 retval = clickcolumnfunc(work.window, column_num, work.data); 1649
1650 params[0] = GINT_TO_POINTER(handlerdata-1);
1651 work = _get_signal_handler(params);
1652
1653 if(work.window)
1654 {
1655 int column_num = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "_dw_column"));
1656 int (*clickcolumnfunc)(HWND, int, void *) = work.func;
1657 retval = clickcolumnfunc(work.window, column_num, work.data);
1658 }
1643 } 1659 }
1644 } 1660 }
1645 return retval; 1661 return retval;
1646 } 1662 }
1647 1663
1674 if(g_object_get_data(G_OBJECT(adjustment), "_dw_suppress_value_changed_event")) 1690 if(g_object_get_data(G_OBJECT(adjustment), "_dw_suppress_value_changed_event"))
1675 return FALSE; 1691 return FALSE;
1676 1692
1677 if (slider || spinbutton || scrollbar) 1693 if (slider || spinbutton || scrollbar)
1678 { 1694 {
1679 SignalHandler work = _get_signal_handler(widget, data); 1695 SignalHandler work = _get_signal_handler(data);
1680 1696
1681 if (work.window) 1697 if (work.window)
1682 { 1698 {
1683 int (*valuechangedfunc)(HWND, int, void *) = work.func; 1699 int (*valuechangedfunc)(HWND, int, void *) = work.func;
1684 1700
5524 { 5540 {
5525 snprintf(numbuf, 20, "_dw_cont_col%d", z); 5541 snprintf(numbuf, 20, "_dw_cont_col%d", z);
5526 g_object_set_data(G_OBJECT(tree), numbuf, GINT_TO_POINTER(flags[z])); 5542 g_object_set_data(G_OBJECT(tree), numbuf, GINT_TO_POINTER(flags[z]));
5527 col = gtk_tree_view_column_new(); 5543 col = gtk_tree_view_column_new();
5528 rend = NULL; 5544 rend = NULL;
5545 void **params = calloc(sizeof(void *), 3);
5529 5546
5530 if(z == 0 && flags[z] & DW_CFA_STRINGANDICON) 5547 if(z == 0 && flags[z] & DW_CFA_STRINGANDICON)
5531 { 5548 {
5532 rend = gtk_cell_renderer_pixbuf_new(); 5549 rend = gtk_cell_renderer_pixbuf_new();
5533 gtk_tree_view_column_pack_start(col, rend, FALSE); 5550 gtk_tree_view_column_pack_start(col, rend, FALSE);
5569 gtk_tree_view_column_pack_start(col, rend, TRUE); 5586 gtk_tree_view_column_pack_start(col, rend, TRUE);
5570 gtk_tree_view_column_add_attribute(col, rend, "text", z+2); 5587 gtk_tree_view_column_add_attribute(col, rend, "text", z+2);
5571 gtk_tree_view_column_set_resizable(col, TRUE); 5588 gtk_tree_view_column_set_resizable(col, TRUE);
5572 } 5589 }
5573 g_object_set_data(G_OBJECT(col), "_dw_column", GINT_TO_POINTER(z)); 5590 g_object_set_data(G_OBJECT(col), "_dw_column", GINT_TO_POINTER(z));
5574 g_signal_connect(G_OBJECT(col), "clicked", G_CALLBACK(_column_click_event), (gpointer)tree); 5591 params[2] = tree;
5592 g_signal_connect_data(G_OBJECT(col), "clicked", G_CALLBACK(_column_click_event), (gpointer)params, _dw_signal_disconnect, 0);
5575 gtk_tree_view_column_set_title(col, titles[z]); 5593 gtk_tree_view_column_set_title(col, titles[z]);
5576 if(flags[z] & DW_CFA_RIGHT) 5594 if(flags[z] & DW_CFA_RIGHT)
5577 { 5595 {
5578 gtk_tree_view_column_set_alignment(col, 1.0); 5596 gtk_tree_view_column_set_alignment(col, 1.0);
5579 if(rend) 5597 if(rend)
11189 * sigfunc: The pointer to the function to be used as the callback. 11207 * sigfunc: The pointer to the function to be used as the callback.
11190 * data: User data to be passed to the handler function. 11208 * data: User data to be passed to the handler function.
11191 */ 11209 */
11192 void dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data) 11210 void dw_signal_connect(HWND window, char *signame, void *sigfunc, void *data)
11193 { 11211 {
11212 dw_signal_connect_data(window, signame, sigfunc, NULL, data);
11213 }
11214
11215 /* Internal function to free any allocated signal data..
11216 * and call any required function to free additional memory.
11217 */
11218 static void _dw_signal_disconnect(gpointer data, GClosure *closure)
11219 {
11220 if(data)
11221 {
11222 void **params = (void **)data;
11223 void (*discfunc)(HWND, void *) = params[1];
11224
11225 if(discfunc)
11226 {
11227 SignalHandler work = _get_signal_handler(data);
11228
11229 if(work.window)
11230 {
11231 discfunc(work.window, work.data);
11232 }
11233 }
11234 free(data);
11235 }
11236 }
11237
11238 /*
11239 * Add a callback to a window event with a closure callback.
11240 * Parameters:
11241 * window: Window handle of signal to be called back.
11242 * signame: A string pointer identifying which signal to be hooked.
11243 * sigfunc: The pointer to the function to be used as the callback.
11244 * discfunc: The pointer to the function called when this handler is removed.
11245 * data: User data to be passed to the handler function.
11246 */
11247 void dw_signal_connect_data(HWND window, char *signame, void *sigfunc, void *discfunc, void *data)
11248 {
11194 void *thisfunc = _findsigfunc(signame); 11249 void *thisfunc = _findsigfunc(signame);
11195 char *thisname = signame; 11250 char *thisname = signame;
11196 HWND thiswindow = window; 11251 HWND thiswindow = window;
11197 int sigid, _locked_by_me = FALSE; 11252 int sigid, _locked_by_me = FALSE;
11253 void **params = calloc(3, sizeof(void *));
11198 gint cid; 11254 gint cid;
11255
11256 /* Save the disconnect function pointer */
11257 params[1] = discfunc;
11199 11258
11200 DW_MUTEX_LOCK; 11259 DW_MUTEX_LOCK;
11201 /* 11260 /*
11202 * If the window we are setting the signal on is a scrolled window we need to get 11261 * If the window we are setting the signal on is a scrolled window we need to get
11203 * the "real" widget type. thiswindow is the "real" widget type 11262 * the "real" widget type. thiswindow is the "real" widget type
11216 thisname = "activate"; 11275 thisname = "activate";
11217 thisfunc = _findsigfunc(thisname); 11276 thisfunc = _findsigfunc(thisname);
11218 } 11277 }
11219 else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_CONTEXT) == 0) 11278 else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_CONTEXT) == 0)
11220 { 11279 {
11221 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc); 11280 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc, discfunc);
11222 cid = g_signal_connect(G_OBJECT(thiswindow), "button_press_event", G_CALLBACK(thisfunc), GINT_TO_POINTER(sigid)); 11281 params[0] = GINT_TO_POINTER(sigid);
11282 params[2] = (void *)thiswindow;
11283 cid = g_signal_connect_data(G_OBJECT(thiswindow), "button_press_event", G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0);
11223 _set_signal_handler_id(thiswindow, sigid, cid); 11284 _set_signal_handler_id(thiswindow, sigid, cid);
11224 11285
11225 DW_MUTEX_UNLOCK; 11286 DW_MUTEX_UNLOCK;
11226 return; 11287 return;
11227 } 11288 }
11230 { 11291 {
11231 GtkWidget *widget = thiswindow; 11292 GtkWidget *widget = thiswindow;
11232 11293
11233 thisname = "changed"; 11294 thisname = "changed";
11234 11295
11235 sigid = _set_signal_handler(widget, window, sigfunc, data, thisfunc); 11296 sigid = _set_signal_handler(widget, window, sigfunc, data, thisfunc, discfunc);
11297 params[0] = GINT_TO_POINTER(sigid);
11298 params[2] = (void *)thiswindow;
11236 if(GTK_IS_TREE_VIEW(thiswindow)) 11299 if(GTK_IS_TREE_VIEW(thiswindow))
11237 { 11300 {
11238 thiswindow = (GtkWidget *)gtk_tree_view_get_selection(GTK_TREE_VIEW(thiswindow)); 11301 thiswindow = (GtkWidget *)gtk_tree_view_get_selection(GTK_TREE_VIEW(thiswindow));
11239 cid = g_signal_connect(G_OBJECT(thiswindow), thisname, G_CALLBACK(thisfunc), GINT_TO_POINTER(sigid)); 11302 cid = g_signal_connect_data(G_OBJECT(thiswindow), thisname, G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0);
11240 } 11303 }
11241 else 11304 else
11242 { 11305 {
11243 cid = g_signal_connect(G_OBJECT(thiswindow), thisname, G_CALLBACK(_combobox_select_event), GINT_TO_POINTER(sigid)); 11306 cid = g_signal_connect_data(G_OBJECT(thiswindow), thisname, G_CALLBACK(_combobox_select_event), params, _dw_signal_disconnect, 0);
11244 } 11307 }
11245 _set_signal_handler_id(widget, sigid, cid); 11308 _set_signal_handler_id(widget, sigid, cid);
11246 11309
11247 DW_MUTEX_UNLOCK; 11310 DW_MUTEX_UNLOCK;
11248 return; 11311 return;
11251 { 11314 {
11252 thisname = "row-expanded"; 11315 thisname = "row-expanded";
11253 } 11316 }
11254 else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_ENTER) == 0) 11317 else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_ITEM_ENTER) == 0)
11255 { 11318 {
11256 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, _container_enter_event); 11319 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, _container_enter_event, discfunc);
11257 cid = g_signal_connect(G_OBJECT(thiswindow), "key_press_event", G_CALLBACK(_container_enter_event), GINT_TO_POINTER(sigid)); 11320 params[0] = GINT_TO_POINTER(sigid);
11321 params[2] = (void *)thiswindow;
11322 cid = g_signal_connect_data(G_OBJECT(thiswindow), "key_press_event", G_CALLBACK(_container_enter_event), params, _dw_signal_disconnect, 0);
11258 _set_signal_handler_id(thiswindow, sigid, cid); 11323 _set_signal_handler_id(thiswindow, sigid, cid);
11324
11325 params = calloc(sizeof(void *), 3);
11259 11326
11260 thisname = "button_press_event"; 11327 thisname = "button_press_event";
11261 thisfunc = _findsigfunc(DW_SIGNAL_ITEM_ENTER); 11328 thisfunc = _findsigfunc(DW_SIGNAL_ITEM_ENTER);
11262 } 11329 }
11263 else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_COLUMN_CLICK) == 0) 11330 else if (GTK_IS_TREE_VIEW(thiswindow) && strcmp(signame, DW_SIGNAL_COLUMN_CLICK) == 0)
11264 { 11331 {
11265 /* We don't actually need a signal handler here... just need to assign the handler ID 11332 /* We don't actually need a signal handler here... just need to assign the handler ID
11266 * Since the handlers for the columns were already created in _dw_container_setup() 11333 * Since the handlers for the columns were already created in _dw_container_setup()
11267 */ 11334 */
11268 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, _column_click_event); 11335 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, _column_click_event, discfunc);
11269 g_object_set_data(G_OBJECT(thiswindow), "_dw_column_click_id", GINT_TO_POINTER(sigid+1)); 11336 g_object_set_data(G_OBJECT(thiswindow), "_dw_column_click_id", GINT_TO_POINTER(sigid+1));
11270 DW_MUTEX_UNLOCK; 11337 DW_MUTEX_UNLOCK;
11271 return; 11338 return;
11272 } 11339 }
11273 else if (strcmp(signame, DW_SIGNAL_SET_FOCUS) == 0) 11340 else if (strcmp(signame, DW_SIGNAL_SET_FOCUS) == 0)
11293 thisname = "switch-page"; 11360 thisname = "switch-page";
11294 } 11361 }
11295 11362
11296 if (!thisfunc || !thiswindow) 11363 if (!thisfunc || !thiswindow)
11297 { 11364 {
11365 free(params);
11298 DW_MUTEX_UNLOCK; 11366 DW_MUTEX_UNLOCK;
11299 return; 11367 return;
11300 } 11368 }
11301 11369
11302 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc); 11370 sigid = _set_signal_handler(thiswindow, window, sigfunc, data, thisfunc, discfunc);
11303 cid = g_signal_connect(G_OBJECT(thiswindow), thisname, G_CALLBACK(thisfunc),GINT_TO_POINTER(sigid)); 11371 params[0] = GINT_TO_POINTER(sigid);
11372 params[2] = (void *)thiswindow;
11373 cid = g_signal_connect_data(G_OBJECT(thiswindow), thisname, G_CALLBACK(thisfunc), params, _dw_signal_disconnect, 0);
11304 _set_signal_handler_id(thiswindow, sigid, cid); 11374 _set_signal_handler_id(thiswindow, sigid, cid);
11305 DW_MUTEX_UNLOCK; 11375 DW_MUTEX_UNLOCK;
11306 } 11376 }
11307 11377
11308 /* 11378 /*
11310 * Parameters: 11380 * Parameters:
11311 * window: Window handle of callback to be removed. 11381 * window: Window handle of callback to be removed.
11312 */ 11382 */
11313 void dw_signal_disconnect_by_name(HWND window, char *signame) 11383 void dw_signal_disconnect_by_name(HWND window, char *signame)
11314 { 11384 {
11315 HWND thiswindow;
11316 int z, count; 11385 int z, count;
11317 void *thisfunc; 11386 void *thisfunc;
11318 int _locked_by_me = FALSE; 11387 int _locked_by_me = FALSE;
11319 11388 void **params = alloca(sizeof(void *) * 3);
11320 DW_MUTEX_LOCK; 11389
11321 thiswindow = _find_signal_window(window, signame); 11390 DW_MUTEX_LOCK;
11322 count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(thiswindow), "_dw_sigcounter")); 11391 params[2] = _find_signal_window(window, signame);
11323 thisfunc = _findsigfunc(signame); 11392 count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(params[2]), "_dw_sigcounter"));
11393 thisfunc = _findsigfunc(signame);
11324 11394
11325 for(z=0;z<count;z++) 11395 for(z=0;z<count;z++)
11326 { 11396 {
11327 SignalHandler sh = _get_signal_handler(thiswindow, GINT_TO_POINTER(z)); 11397 SignalHandler sh;
11398
11399 params[0] = GINT_TO_POINTER(z);
11400 sh = _get_signal_handler(params);
11328 11401
11329 if(sh.intfunc == thisfunc) 11402 if(sh.intfunc == thisfunc)
11330 _remove_signal_handler(thiswindow, z); 11403 _remove_signal_handler((HWND)params[2], z);
11331 } 11404 }
11332 DW_MUTEX_UNLOCK; 11405 DW_MUTEX_UNLOCK;
11333 } 11406 }
11334 11407
11335 /* 11408 /*
11359 * window: Window handle of callback to be removed. 11432 * window: Window handle of callback to be removed.
11360 * data: Pointer to the data to be compared against. 11433 * data: Pointer to the data to be compared against.
11361 */ 11434 */
11362 void dw_signal_disconnect_by_data(HWND window, void *data) 11435 void dw_signal_disconnect_by_data(HWND window, void *data)
11363 { 11436 {
11364 HWND thiswindow;
11365 int z, count; 11437 int z, count;
11366 int _locked_by_me = FALSE; 11438 int _locked_by_me = FALSE;
11367 11439 void **params = alloca(sizeof(void *) * 3);
11368 DW_MUTEX_LOCK; 11440
11369 thiswindow = _find_signal_window(window, NULL); 11441 DW_MUTEX_LOCK;
11370 count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(thiswindow), "_dw_sigcounter")); 11442 params[2] = _find_signal_window(window, NULL);
11443 count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(params[2]), "_dw_sigcounter"));
11371 11444
11372 for(z=0;z<count;z++) 11445 for(z=0;z<count;z++)
11373 { 11446 {
11374 SignalHandler sh = _get_signal_handler(thiswindow, GINT_TO_POINTER(z)); 11447 SignalHandler sh;
11448
11449 params[0] = GINT_TO_POINTER(z);
11450 sh = _get_signal_handler(params);
11375 11451
11376 if(sh.data == data) 11452 if(sh.data == data)
11377 _remove_signal_handler(thiswindow, z); 11453 _remove_signal_handler((HWND)params[2], z);
11378 } 11454 }
11379 DW_MUTEX_UNLOCK; 11455 DW_MUTEX_UNLOCK;
11380 } 11456 }
11381 11457
11382 /* 11458 /*