comparison gtk3/dw.c @ 1884:71780cf68aa2

More container and tree changes on all platforms regarding memory. This should fix GTK3 memory leaks I wasn't previously aware of... but it will cause all platforms to leak memory if strings returned from dw_container_query_start(), dw_container_query_next() and dw_tree_get_title() are not freed with dw_free() when using version 3.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Wed, 28 Aug 2013 23:47:40 +0000
parents 653ccb517aa1
children f7d408a47752
comparison
equal deleted inserted replaced
1883:0fecaedb83fa 1884:71780cf68aa2
1380 } 1380 }
1381 } 1381 }
1382 return retval; 1382 return retval;
1383 } 1383 }
1384 1384
1385 #define _DW_DATA_TYPE_STRING 0
1386 #define _DW_DATA_TYPE_POINTER 1
1387
1385 static gint _tree_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data) 1388 static gint _tree_context_event(GtkWidget *widget, GdkEventButton *event, gpointer data)
1386 { 1389 {
1387 SignalHandler work = _get_signal_handler(data); 1390 SignalHandler work = _get_signal_handler(data);
1388 int retval = FALSE; 1391 int retval = FALSE;
1389 1392
1404 if(sel && gtk_tree_selection_get_mode(sel) != GTK_SELECTION_MULTIPLE && 1407 if(sel && gtk_tree_selection_get_mode(sel) != GTK_SELECTION_MULTIPLE &&
1405 gtk_tree_selection_get_selected(sel, NULL, &iter)) 1408 gtk_tree_selection_get_selected(sel, NULL, &iter))
1406 { 1409 {
1407 if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE)) 1410 if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE))
1408 { 1411 {
1409 gtk_tree_model_get(store, &iter, 0, &text, 2, &itemdata, -1); 1412 gtk_tree_model_get(store, &iter, _DW_DATA_TYPE_STRING, &text, 2, &itemdata, -1);
1410 } 1413 }
1411 else 1414 else
1412 { 1415 {
1413 gtk_tree_model_get(store, &iter, 0, &text, -1); 1416 gtk_tree_model_get(store, &iter, _DW_DATA_TYPE_STRING, &text, -1);
1414 } 1417 }
1415 } 1418 }
1416 else 1419 else
1417 { 1420 {
1418 GtkTreePath *path; 1421 GtkTreePath *path;
1424 1427
1425 if(gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path)) 1428 if(gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path))
1426 { 1429 {
1427 if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE)) 1430 if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE))
1428 { 1431 {
1429 gtk_tree_model_get(store, &iter, 0, &text, 2, &itemdata, -1); 1432 gtk_tree_model_get(store, &iter, _DW_DATA_TYPE_STRING, &text, 2, &itemdata, -1);
1430 } 1433 }
1431 else 1434 else
1432 { 1435 {
1433 gtk_tree_model_get(store, &iter, 0, &text, -1); 1436 gtk_tree_model_get(store, &iter, _DW_DATA_TYPE_STRING, &text, -1);
1434 } 1437 }
1435 } 1438 }
1436 gtk_tree_path_free(path); 1439 gtk_tree_path_free(path);
1437 } 1440 }
1438 } 1441 }
1439 } 1442 }
1440 1443
1441 retval = contextfunc(work.window, text, event->x, event->y, work.data, itemdata); 1444 retval = contextfunc(work.window, text, event->x, event->y, work.data, itemdata);
1445 if(text)
1446 g_free(text);
1442 } 1447 }
1443 } 1448 }
1444 return retval; 1449 return retval;
1445 } 1450 }
1446 1451
1470 if(gtk_tree_selection_get_mode(sel) != GTK_SELECTION_MULTIPLE && 1475 if(gtk_tree_selection_get_mode(sel) != GTK_SELECTION_MULTIPLE &&
1471 gtk_tree_selection_get_selected(sel, NULL, &iter)) 1476 gtk_tree_selection_get_selected(sel, NULL, &iter))
1472 { 1477 {
1473 if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE)) 1478 if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE))
1474 { 1479 {
1475 gtk_tree_model_get(store, &iter, 0, &text, 2, &itemdata, 3, &item, -1); 1480 gtk_tree_model_get(store, &iter, _DW_DATA_TYPE_STRING, &text, 2, &itemdata, 3, &item, -1);
1476 retval = treeselectfunc(work.window, (HTREEITEM)item, text, work.data, itemdata); 1481 retval = treeselectfunc(work.window, (HTREEITEM)item, text, work.data, itemdata);
1477 } 1482 }
1478 else if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_CONTAINER)) 1483 else if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_CONTAINER))
1479 { 1484 {
1480 gtk_tree_model_get(store, &iter, 0, &text, 1, &itemdata, -1); 1485 gtk_tree_model_get(store, &iter, _DW_DATA_TYPE_STRING, &text, _DW_DATA_TYPE_POINTER, &itemdata, -1);
1481 retval = treeselectfunc(work.window, (HTREEITEM)item, text, work.data, itemdata); 1486 retval = treeselectfunc(work.window, (HTREEITEM)item, text, work.data, itemdata);
1482 } 1487 }
1483 else 1488 else
1484 { 1489 {
1485 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter); 1490 GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
1509 1514
1510 if(gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path)) 1515 if(gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path))
1511 { 1516 {
1512 if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE)) 1517 if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_TREE))
1513 { 1518 {
1514 gtk_tree_model_get(store, &iter, 0, &text, 2, &itemdata, 3, &item, -1); 1519 gtk_tree_model_get(store, &iter, _DW_DATA_TYPE_STRING, &text, 2, &itemdata, 3, &item, -1);
1515 retval = treeselectfunc(work.window, (HTREEITEM)item, text, work.data, itemdata); 1520 retval = treeselectfunc(work.window, (HTREEITEM)item, text, work.data, itemdata);
1516 } 1521 }
1517 else if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_CONTAINER)) 1522 else if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_CONTAINER))
1518 { 1523 {
1519 gtk_tree_model_get(store, &iter, 0, &text, 1, &itemdata, -1); 1524 gtk_tree_model_get(store, &iter, _DW_DATA_TYPE_STRING, &text, _DW_DATA_TYPE_POINTER, &itemdata, -1);
1520 retval = treeselectfunc(work.window, (HTREEITEM)item, text, work.data, itemdata); 1525 retval = treeselectfunc(work.window, (HTREEITEM)item, text, work.data, itemdata);
1521 } 1526 }
1522 else 1527 else
1523 { 1528 {
1524 gint *indices = gtk_tree_path_get_indices(path); 1529 gint *indices = gtk_tree_path_get_indices(path);
1532 } 1537 }
1533 } 1538 }
1534 gtk_tree_path_free(path); 1539 gtk_tree_path_free(path);
1535 } 1540 }
1536 } 1541 }
1542 if(text)
1543 g_free(text);
1537 } 1544 }
1538 } 1545 }
1539 return retval; 1546 return retval;
1540 } 1547 }
1541 1548
1588 1595
1589 if(gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path)) 1596 if(gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path))
1590 { 1597 {
1591 if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_CONTAINER)) 1598 if(g_object_get_data(G_OBJECT(widget), "_dw_tree_type") == GINT_TO_POINTER(_DW_TREE_TYPE_CONTAINER))
1592 { 1599 {
1593 gtk_tree_model_get(store, &iter, 0, &text, 1, &data, -1); 1600 gtk_tree_model_get(store, &iter, _DW_DATA_TYPE_STRING, &text, _DW_DATA_TYPE_POINTER, &data, -1);
1594 retval = contextfunc(work.window, text, work.data, data); 1601 retval = contextfunc(work.window, text, work.data, data);
1602 if(text)
1603 g_free(text);
1595 } 1604 }
1596 } 1605 }
1597 gtk_tree_path_free(path); 1606 gtk_tree_path_free(path);
1598 } 1607 }
1599 } 1608 }
5258 DW_MUTEX_LOCK; 5267 DW_MUTEX_LOCK;
5259 tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); 5268 tree = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user");
5260 5269
5261 if(tree && GTK_IS_TREE_VIEW(tree) && 5270 if(tree && GTK_IS_TREE_VIEW(tree) &&
5262 (store = (GtkTreeModel *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree)))) 5271 (store = (GtkTreeModel *)gtk_tree_view_get_model(GTK_TREE_VIEW(tree))))
5263 gtk_tree_model_get(store, (GtkTreeIter *)item, 0, &text, -1); 5272 gtk_tree_model_get(store, (GtkTreeIter *)item, _DW_DATA_TYPE_STRING, &text, -1);
5273 if(text)
5274 {
5275 char *temp = text;
5276 text = strdup(temp);
5277 g_free(temp);
5278 }
5264 DW_MUTEX_UNLOCK; 5279 DW_MUTEX_UNLOCK;
5265 return text; 5280 return text;
5266 } 5281 }
5267 5282
5268 /* 5283 /*
6139 } 6154 }
6140 DW_MUTEX_UNLOCK; 6155 DW_MUTEX_UNLOCK;
6141 } 6156 }
6142 6157
6143 /* Internal version for both */ 6158 /* Internal version for both */
6144 #define _DW_DATA_TYPE_STRING 0
6145 #define _DW_DATA_TYPE_POINTER 1
6146
6147 void _dw_container_set_row_data(HWND handle, void *pointer, int row, int type, void *data) 6159 void _dw_container_set_row_data(HWND handle, void *pointer, int row, int type, void *data)
6148 { 6160 {
6149 GtkWidget *cont = handle; 6161 GtkWidget *cont = handle;
6150 GtkListStore *store = NULL; 6162 GtkListStore *store = NULL;
6151 int _locked_by_me = FALSE; 6163 int _locked_by_me = FALSE;
6391 { 6403 {
6392 GtkWidget *cont; 6404 GtkWidget *cont;
6393 GtkListStore *store = NULL; 6405 GtkListStore *store = NULL;
6394 char *retval = NULL; 6406 char *retval = NULL;
6395 int _locked_by_me = FALSE; 6407 int _locked_by_me = FALSE;
6408 int type = flags & DW_CR_RETDATA ? _DW_DATA_TYPE_POINTER : _DW_DATA_TYPE_STRING;
6396 6409
6397 DW_MUTEX_LOCK; 6410 DW_MUTEX_LOCK;
6398 cont = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); 6411 cont = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user");
6399 6412
6400 /* Make sure it is the correct tree type */ 6413 /* Make sure it is the correct tree type */
6420 { 6433 {
6421 GtkTreeIter iter; 6434 GtkTreeIter iter;
6422 6435
6423 if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, indices[0])) 6436 if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, indices[0]))
6424 { 6437 {
6425 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &retval, -1); 6438 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, type, &retval, -1);
6426 g_object_set_data(G_OBJECT(cont), "_dw_querypos", GINT_TO_POINTER(1)); 6439 g_object_set_data(G_OBJECT(cont), "_dw_querypos", GINT_TO_POINTER(1));
6427 } 6440 }
6428 } 6441 }
6429 } 6442 }
6430 g_list_foreach(list, (GFunc) gtk_tree_path_free, NULL); 6443 g_list_foreach(list, (GFunc) gtk_tree_path_free, NULL);
6440 { 6453 {
6441 GtkTreeIter iter; 6454 GtkTreeIter iter;
6442 6455
6443 if(gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path)) 6456 if(gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path))
6444 { 6457 {
6445 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &retval, -1); 6458 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, type, &retval, -1);
6446 } 6459 }
6447 gtk_tree_path_free(path); 6460 gtk_tree_path_free(path);
6448 } 6461 }
6449 } 6462 }
6450 else 6463 else
6451 { 6464 {
6452 GtkTreeIter iter; 6465 GtkTreeIter iter;
6453 6466
6454 if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, 0)) 6467 if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, 0))
6455 { 6468 {
6456 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &retval, -1); 6469 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, type, &retval, -1);
6457 g_object_set_data(G_OBJECT(cont), "_dw_querypos", GINT_TO_POINTER(1)); 6470 g_object_set_data(G_OBJECT(cont), "_dw_querypos", GINT_TO_POINTER(1));
6458 } 6471 }
6459 } 6472 }
6473 }
6474 /* If there is a title, duplicate it and free the temporary copy */
6475 if(retval && type == _DW_DATA_TYPE_STRING)
6476 {
6477 char *temp = retval;
6478 retval = strdup(temp);
6479 g_free(temp);
6460 } 6480 }
6461 DW_MUTEX_UNLOCK; 6481 DW_MUTEX_UNLOCK;
6462 return retval; 6482 return retval;
6463 } 6483 }
6464 6484
6474 { 6494 {
6475 GtkWidget *cont; 6495 GtkWidget *cont;
6476 GtkListStore *store = NULL; 6496 GtkListStore *store = NULL;
6477 char *retval = NULL; 6497 char *retval = NULL;
6478 int _locked_by_me = FALSE; 6498 int _locked_by_me = FALSE;
6499 int type = flags & DW_CR_RETDATA ? _DW_DATA_TYPE_POINTER : _DW_DATA_TYPE_STRING;
6479 6500
6480 DW_MUTEX_LOCK; 6501 DW_MUTEX_LOCK;
6481 cont = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user"); 6502 cont = (GtkWidget *)g_object_get_data(G_OBJECT(handle), "_dw_user");
6482 6503
6483 /* Make sure it is the correct tree type */ 6504 /* Make sure it is the correct tree type */
6507 { 6528 {
6508 GtkTreeIter iter; 6529 GtkTreeIter iter;
6509 6530
6510 if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, indices[0])) 6531 if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, indices[0]))
6511 { 6532 {
6512 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &retval, -1); 6533 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, type, &retval, -1);
6513 g_object_set_data(G_OBJECT(cont), "_dw_querypos", GINT_TO_POINTER(pos+1)); 6534 g_object_set_data(G_OBJECT(cont), "_dw_querypos", GINT_TO_POINTER(pos+1));
6514 } 6535 }
6515 } 6536 }
6516 } 6537 }
6517 g_list_foreach(list, (GFunc) gtk_tree_path_free, NULL); 6538 g_list_foreach(list, (GFunc) gtk_tree_path_free, NULL);
6529 { 6550 {
6530 GtkTreeIter iter; 6551 GtkTreeIter iter;
6531 6552
6532 if(pos < count && gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, pos)) 6553 if(pos < count && gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, pos))
6533 { 6554 {
6534 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &retval, -1); 6555 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, type, &retval, -1);
6535 g_object_set_data(G_OBJECT(cont), "_dw_querypos", GINT_TO_POINTER(pos+1)); 6556 g_object_set_data(G_OBJECT(cont), "_dw_querypos", GINT_TO_POINTER(pos+1));
6536 } 6557 }
6537 } 6558 }
6538 } 6559 }
6560 /* If there is a title, duplicate it and free the temporary copy */
6561 if(retval && type == _DW_DATA_TYPE_STRING)
6562 {
6563 char *temp = retval;
6564 retval = strdup(temp);
6565 g_free(temp);
6566 }
6539 DW_MUTEX_UNLOCK; 6567 DW_MUTEX_UNLOCK;
6540 return retval; 6568 return retval;
6541 } 6569 }
6542 6570
6543 int _find_iter(GtkListStore *store, GtkTreeIter *iter, void *data, int textcomp) 6571 int _find_iter(GtkListStore *store, GtkTreeIter *iter, void *data, int textcomp)
6544 { 6572 {
6545 int z, rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL); 6573 int z, rows = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store), NULL);
6546 void *thisdata; 6574 void *thisdata;
6575 int retval = FALSE;
6547 6576
6548 for(z=0;z<rows;z++) 6577 for(z=0;z<rows;z++)
6549 { 6578 {
6550 if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), iter, NULL, z)) 6579 if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), iter, NULL, z))
6551 { 6580 {
6552 /* Get either string from position 0 or pointer from position 1 */ 6581 /* Get either string from position 0 or pointer from position 1 */
6553 gtk_tree_model_get(GTK_TREE_MODEL(store), iter, textcomp ? 0 : 1, &thisdata, -1); 6582 gtk_tree_model_get(GTK_TREE_MODEL(store), iter, textcomp ? _DW_DATA_TYPE_STRING : _DW_DATA_TYPE_POINTER, &thisdata, -1);
6554 if((textcomp && thisdata && strcmp((char *)thisdata, (char *)data) == 0) || (!textcomp && thisdata == data)) 6583 if((textcomp && thisdata && strcmp((char *)thisdata, (char *)data) == 0) || (!textcomp && thisdata == data))
6555 { 6584 {
6556 return TRUE; 6585 retval = TRUE;
6586 z = rows;
6557 } 6587 }
6558 } 6588 if(textcomp && thisdata)
6559 } 6589 g_free(thisdata);
6560 return FALSE; 6590 }
6591 }
6592 return retval;
6561 } 6593 }
6562 6594
6563 void _dw_container_cursor(HWND handle, void *data, int textcomp) 6595 void _dw_container_cursor(HWND handle, void *data, int textcomp)
6564 { 6596 {
6565 GtkWidget *cont; 6597 GtkWidget *cont;
9988 /* Get the nth child at the top level */ 10020 /* Get the nth child at the top level */
9989 if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, index)) 10021 if(gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), &iter, NULL, index))
9990 { 10022 {
9991 /* Get the text */ 10023 /* Get the text */
9992 gchar *text; 10024 gchar *text;
9993 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 0, &text, -1); 10025 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, _DW_DATA_TYPE_STRING, &text, -1);
9994 strncpy(buffer, text, length); 10026 if(text)
10027 {
10028 strncpy(buffer, text, length);
10029 g_free(text);
10030 }
9995 DW_MUTEX_UNLOCK; 10031 DW_MUTEX_UNLOCK;
9996 return; 10032 return;
9997 } 10033 }
9998 } 10034 }
9999 } 10035 }