Commit 49853a4d authored by Jan Djärv's avatar Jan Djärv

Fix memory leak.

parent 769c4c63
2003-02-02 Jan Dj,Ad(Brv <jan.h.d@swipnet.se>
* gtkutil.c (remove_from_container): Copying list is not needed.
(xg_update_menubar, xg_update_menu_item, xg_update_submenu)
(xg_modify_menubar_widgets, update_frame_tool_bar): Call g_list_free
on list returned from gtk_container_get_children to avoid memory leak.
2003-02-01 Jason Rumney <jasonr@gnu.org> 2003-02-01 Jason Rumney <jasonr@gnu.org>
* w32fns.c (w32_create_pixmap_from_bitmap_data): Use alloca for * w32fns.c (w32_create_pixmap_from_bitmap_data): Use alloca for
......
...@@ -1576,11 +1576,9 @@ remove_from_container (wcont, list) ...@@ -1576,11 +1576,9 @@ remove_from_container (wcont, list)
GtkWidget *wcont; GtkWidget *wcont;
GList *list; GList *list;
{ {
/* We must copy list because gtk_container_remove changes it. */
GList *clist = g_list_copy (list);
GList *iter; GList *iter;
for (iter = clist; iter; iter = g_list_next (iter)) for (iter = list; iter; iter = g_list_next (iter))
{ {
GtkWidget *w = GTK_WIDGET (iter->data); GtkWidget *w = GTK_WIDGET (iter->data);
...@@ -1595,39 +1593,44 @@ remove_from_container (wcont, list) ...@@ -1595,39 +1593,44 @@ remove_from_container (wcont, list)
removing the detached window also if there was one. */ removing the detached window also if there was one. */
gtk_widget_destroy (w); gtk_widget_destroy (w);
} }
g_list_free (clist);
} }
/* Update the top level names in MENUBAR (i.e. not submenus). /* Update the top level names in MENUBAR (i.e. not submenus).
F is the frame the menu bar belongs to. F is the frame the menu bar belongs to.
LIST is a list with the current menu bar names (menu item widgets). *LIST is a list with the current menu bar names (menu item widgets).
ITER is the item within *LIST that shall be updated.
POS is the numerical position, starting at 0, of ITER in *LIST.
VAL describes what the menu bar shall look like after the update. VAL describes what the menu bar shall look like after the update.
SELECT_CB is the callback to use when a menu item is selected. SELECT_CB is the callback to use when a menu item is selected.
HIGHLIGHT_CB is the callback to call when entering/leaving menu items. HIGHLIGHT_CB is the callback to call when entering/leaving menu items.
CL_DATA points to the callback data to be used for this menu bar.
This function calls itself to walk through the menu bar names. */ This function calls itself to walk through the menu bar names. */
static void static void
xg_update_menubar (menubar, f, list, val, select_cb, highlight_cb, cl_data) xg_update_menubar (menubar, f, list, iter, pos, val,
select_cb, highlight_cb, cl_data)
GtkWidget *menubar; GtkWidget *menubar;
FRAME_PTR f; FRAME_PTR f;
GList *list; GList **list;
GList *iter;
int pos;
widget_value *val; widget_value *val;
GCallback select_cb; GCallback select_cb;
GCallback highlight_cb; GCallback highlight_cb;
xg_menu_cb_data *cl_data; xg_menu_cb_data *cl_data;
{ {
if (! list && ! val) if (! iter && ! val)
return; return;
else if (list && ! val) else if (iter && ! val)
{ {
/* Item(s) have been removed. Remove all remaining items from list. */ /* Item(s) have been removed. Remove all remaining items. */
remove_from_container (menubar, list); remove_from_container (menubar, iter);
/* All updated. */ /* All updated. */
val = 0; val = 0;
list = 0; iter = 0;
} }
else if (! list && val) else if (! iter && val)
{ {
/* Item(s) added. Add all new items in one call. */ /* Item(s) added. Add all new items in one call. */
create_menus (val, f, select_cb, 0, highlight_cb, create_menus (val, f, select_cb, 0, highlight_cb,
...@@ -1635,51 +1638,43 @@ xg_update_menubar (menubar, f, list, val, select_cb, highlight_cb, cl_data) ...@@ -1635,51 +1638,43 @@ xg_update_menubar (menubar, f, list, val, select_cb, highlight_cb, cl_data)
/* All updated. */ /* All updated. */
val = 0; val = 0;
list = 0; iter = 0;
} }
/* Below this neither list or val is NULL */ /* Below this neither iter or val is NULL */
else if (xg_item_label_same_p (GTK_MENU_ITEM (list->data), val->name)) else if (xg_item_label_same_p (GTK_MENU_ITEM (iter->data), val->name))
{ {
/* This item is still the same, check next item. */ /* This item is still the same, check next item. */
val = val->next; val = val->next;
list = g_list_next (list); iter = g_list_next (iter);
++pos;
} }
else /* This item is changed. */ else /* This item is changed. */
{ {
GtkMenuItem *witem = GTK_MENU_ITEM (list->data); GtkMenuItem *witem = GTK_MENU_ITEM (iter->data);
GtkMenuItem *witem2 = 0; GtkMenuItem *witem2 = 0;
int pos = 0;
int val_in_menubar = 0; int val_in_menubar = 0;
int list_in_new_menubar = 0; int iter_in_new_menubar = 0;
GList *list2; GList *iter2;
GList *iter;
widget_value *cur; widget_value *cur;
/* Get position number for witem. */
list2 = gtk_container_get_children (GTK_CONTAINER (menubar));
for (iter = list2; iter; iter = g_list_next (iter))
{
if (list->data == iter->data) break;
++pos;
}
/* See if the changed entry (val) is present later in the menu bar */ /* See if the changed entry (val) is present later in the menu bar */
for (iter = g_list_next (list); for (iter2 = iter;
iter && ! val_in_menubar; iter2 && ! val_in_menubar;
iter = g_list_next (iter)) iter2 = g_list_next (iter2))
{ {
witem2 = GTK_MENU_ITEM (iter->data); witem2 = GTK_MENU_ITEM (iter2->data);
val_in_menubar = xg_item_label_same_p (witem2, val->name); val_in_menubar = xg_item_label_same_p (witem2, val->name);
} }
/* See if the current entry (list) is present later in the /* See if the current entry (iter) is present later in the
specification for the new menu bar. */ specification for the new menu bar. */
for (cur = val; cur && ! list_in_new_menubar; cur = cur->next) for (cur = val; cur && ! iter_in_new_menubar; cur = cur->next)
list_in_new_menubar = xg_item_label_same_p (witem, cur->name); iter_in_new_menubar = xg_item_label_same_p (witem, cur->name);
if (val_in_menubar && ! list_in_new_menubar) if (val_in_menubar && ! iter_in_new_menubar)
{ {
int nr = pos;
/* This corresponds to: /* This corresponds to:
Current: A B C Current: A B C
New: A C New: A C
...@@ -1690,10 +1685,11 @@ xg_update_menubar (menubar, f, list, val, select_cb, highlight_cb, cl_data) ...@@ -1690,10 +1685,11 @@ xg_update_menubar (menubar, f, list, val, select_cb, highlight_cb, cl_data)
gtk_widget_destroy (GTK_WIDGET (witem)); gtk_widget_destroy (GTK_WIDGET (witem));
/* Must get new list since the old changed. */ /* Must get new list since the old changed. */
list = gtk_container_get_children (GTK_CONTAINER (menubar)); g_list_free (*list);
while (pos-- > 0) list = g_list_next (list); *list = iter = gtk_container_get_children (GTK_CONTAINER (menubar));
while (nr-- > 0) iter = g_list_next (iter);
} }
else if (! val_in_menubar && ! list_in_new_menubar) else if (! val_in_menubar && ! iter_in_new_menubar)
{ {
/* This corresponds to: /* This corresponds to:
Current: A B C Current: A B C
...@@ -1714,16 +1710,18 @@ xg_update_menubar (menubar, f, list, val, select_cb, highlight_cb, cl_data) ...@@ -1714,16 +1710,18 @@ xg_update_menubar (menubar, f, list, val, select_cb, highlight_cb, cl_data)
gtk_label_set_text_with_mnemonic (wlabel, utf8_label); gtk_label_set_text_with_mnemonic (wlabel, utf8_label);
list = g_list_next (list); iter = g_list_next (iter);
val = val->next; val = val->next;
++pos;
} }
else if (! val_in_menubar && list_in_new_menubar) else if (! val_in_menubar && iter_in_new_menubar)
{ {
/* This corresponds to: /* This corresponds to:
Current: A B C Current: A B C
New: A X B C New: A X B C
Insert X. */ Insert X. */
int nr = pos;
GList *group = 0; GList *group = 0;
GtkWidget *w = xg_create_one_menuitem (val, GtkWidget *w = xg_create_one_menuitem (val,
f, f,
...@@ -1735,13 +1733,16 @@ xg_update_menubar (menubar, f, list, val, select_cb, highlight_cb, cl_data) ...@@ -1735,13 +1733,16 @@ xg_update_menubar (menubar, f, list, val, select_cb, highlight_cb, cl_data)
gtk_widget_set_name (w, MENU_ITEM_NAME); gtk_widget_set_name (w, MENU_ITEM_NAME);
gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), w, pos); gtk_menu_shell_insert (GTK_MENU_SHELL (menubar), w, pos);
list = gtk_container_get_children (GTK_CONTAINER (menubar)); g_list_free (*list);
while (pos-- > 0) list = g_list_next (list); *list = iter = gtk_container_get_children (GTK_CONTAINER (menubar));
list = g_list_next (list); while (nr-- > 0) iter = g_list_next (iter);
iter = g_list_next (iter);
val = val->next; val = val->next;
++pos;
} }
else /* if (val_in_menubar && list_in_new_menubar) */ else /* if (val_in_menubar && iter_in_new_menubar) */
{ {
int nr = pos;
/* This corresponds to: /* This corresponds to:
Current: A B C Current: A B C
New: A C B New: A C B
...@@ -1753,16 +1754,17 @@ xg_update_menubar (menubar, f, list, val, select_cb, highlight_cb, cl_data) ...@@ -1753,16 +1754,17 @@ xg_update_menubar (menubar, f, list, val, select_cb, highlight_cb, cl_data)
GTK_WIDGET (witem2), pos); GTK_WIDGET (witem2), pos);
gtk_widget_unref (GTK_WIDGET (witem2)); gtk_widget_unref (GTK_WIDGET (witem2));
g_list_free (*list);
*list = iter = gtk_container_get_children (GTK_CONTAINER (menubar));
while (nr-- > 0) iter = g_list_next (iter);
val = val->next; val = val->next;
list = gtk_container_get_children (GTK_CONTAINER (menubar)); ++pos;
while (pos-- > 0) list = g_list_next (list);
list = g_list_next (list);
} }
} }
/* Update the rest of the menu bar. */ /* Update the rest of the menu bar. */
xg_update_menubar (menubar, f, list, val, select_cb, highlight_cb, cl_data); xg_update_menubar (menubar, f, list, iter, pos, val,
select_cb, highlight_cb, cl_data);
} }
/* Update the menu item W so it corresponds to VAL. /* Update the menu item W so it corresponds to VAL.
...@@ -1797,6 +1799,8 @@ xg_update_menu_item (val, w, select_cb, highlight_cb, cl_data) ...@@ -1797,6 +1799,8 @@ xg_update_menu_item (val, w, select_cb, highlight_cb, cl_data)
wlbl = GTK_LABEL (list->data); wlbl = GTK_LABEL (list->data);
wkey = GTK_LABEL (list->next->data); wkey = GTK_LABEL (list->next->data);
g_list_free (list);
if (! utf8_key) if (! utf8_key)
{ {
/* Remove the key and keep just the label. */ /* Remove the key and keep just the label. */
...@@ -1805,6 +1809,7 @@ xg_update_menu_item (val, w, select_cb, highlight_cb, cl_data) ...@@ -1805,6 +1809,7 @@ xg_update_menu_item (val, w, select_cb, highlight_cb, cl_data)
gtk_container_add (GTK_CONTAINER (w), GTK_WIDGET (wlbl)); gtk_container_add (GTK_CONTAINER (w), GTK_WIDGET (wlbl));
wkey = 0; wkey = 0;
} }
} }
else /* Just a label. */ else /* Just a label. */
{ {
...@@ -1815,8 +1820,10 @@ xg_update_menu_item (val, w, select_cb, highlight_cb, cl_data) ...@@ -1815,8 +1820,10 @@ xg_update_menu_item (val, w, select_cb, highlight_cb, cl_data)
{ {
GtkWidget *wtoadd = make_widget_for_menu_item (utf8_label, utf8_key); GtkWidget *wtoadd = make_widget_for_menu_item (utf8_label, utf8_key);
GList *list = gtk_container_get_children (GTK_CONTAINER (wtoadd)); GList *list = gtk_container_get_children (GTK_CONTAINER (wtoadd));
wlbl = GTK_LABEL (list->data); wlbl = GTK_LABEL (list->data);
wkey = GTK_LABEL (list->next->data); wkey = GTK_LABEL (list->next->data);
g_list_free (list);
gtk_container_remove (GTK_CONTAINER (w), wchild); gtk_container_remove (GTK_CONTAINER (w), wchild);
gtk_container_add (GTK_CONTAINER (w), wtoadd); gtk_container_add (GTK_CONTAINER (w), wtoadd);
...@@ -2056,6 +2063,8 @@ xg_update_submenu (submenu, f, val, ...@@ -2056,6 +2063,8 @@ xg_update_submenu (submenu, f, val,
0); 0);
} }
if (list) g_list_free (list);
return newsub; return newsub;
} }
...@@ -2080,7 +2089,6 @@ xg_modify_menubar_widgets (menubar, f, val, deep_p, ...@@ -2080,7 +2089,6 @@ xg_modify_menubar_widgets (menubar, f, val, deep_p,
{ {
xg_menu_cb_data *cl_data; xg_menu_cb_data *cl_data;
GList *list = gtk_container_get_children (GTK_CONTAINER (menubar)); GList *list = gtk_container_get_children (GTK_CONTAINER (menubar));
GList *iter;
if (! list) return; if (! list) return;
...@@ -2090,7 +2098,7 @@ xg_modify_menubar_widgets (menubar, f, val, deep_p, ...@@ -2090,7 +2098,7 @@ xg_modify_menubar_widgets (menubar, f, val, deep_p,
if (! deep_p) if (! deep_p)
{ {
widget_value *cur = val->contents; widget_value *cur = val->contents;
xg_update_menubar (menubar, f, list, cur, xg_update_menubar (menubar, f, &list, list, 0, cur,
select_cb, highlight_cb, cl_data); select_cb, highlight_cb, cl_data);
} }
else else
...@@ -2106,6 +2114,7 @@ xg_modify_menubar_widgets (menubar, f, val, deep_p, ...@@ -2106,6 +2114,7 @@ xg_modify_menubar_widgets (menubar, f, val, deep_p,
for (cur = val->contents; cur; cur = cur->next) for (cur = val->contents; cur; cur = cur->next)
{ {
GList *iter;
GtkWidget *sub = 0; GtkWidget *sub = 0;
GtkWidget *newsub; GtkWidget *newsub;
GtkMenuItem *witem; GtkMenuItem *witem;
...@@ -2137,6 +2146,7 @@ xg_modify_menubar_widgets (menubar, f, val, deep_p, ...@@ -2137,6 +2146,7 @@ xg_modify_menubar_widgets (menubar, f, val, deep_p,
} }
} }
g_list_free (list);
gtk_widget_show_all (menubar); gtk_widget_show_all (menubar);
} }
...@@ -2424,34 +2434,35 @@ xg_update_scrollbar_pos (f, scrollbar_id, top, left, width, height) ...@@ -2424,34 +2434,35 @@ xg_update_scrollbar_pos (f, scrollbar_id, top, left, width, height)
int width; int width;
int height; int height;
{ {
GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id);
if (wscroll) GtkWidget *wscroll = xg_get_widget_from_map (scrollbar_id);
{
int gheight = max (height, 1); if (wscroll)
{
int gheight = max (height, 1);
gtk_fixed_move (GTK_FIXED (f->output_data.x->edit_widget), gtk_fixed_move (GTK_FIXED (f->output_data.x->edit_widget),
wscroll, left, top); wscroll, left, top);
gtk_widget_set_size_request (wscroll, width, gheight); gtk_widget_set_size_request (wscroll, width, gheight);
/* Must force out update so wscroll gets the resize. /* Must force out update so wscroll gets the resize.
Otherwise, the gdk_window_clear clears the old window size. */ Otherwise, the gdk_window_clear clears the old window size. */
gdk_window_process_all_updates (); gdk_window_process_all_updates ();
/* The scroll bar doesn't explicitly redraw the whole window /* The scroll bar doesn't explicitly redraw the whole window
when a resize occurs. Since the scroll bar seems to be fixed when a resize occurs. Since the scroll bar seems to be fixed
in width it doesn't fill the space reserved, so we must clear in width it doesn't fill the space reserved, so we must clear
the whole window. */ the whole window. */
gdk_window_clear (wscroll->window); gdk_window_clear (wscroll->window);
/* Since we are not using a pure gtk event loop, we must force out /* Since we are not using a pure gtk event loop, we must force out
pending update events with this call. */ pending update events with this call. */
gdk_window_process_all_updates (); gdk_window_process_all_updates ();
SET_FRAME_GARBAGED (f); SET_FRAME_GARBAGED (f);
cancel_mouse_face (f); cancel_mouse_face (f);
} }
} }
/* Set the thumb size and position of scroll bar BAR. We are currently /* Set the thumb size and position of scroll bar BAR. We are currently
...@@ -2698,6 +2709,7 @@ update_frame_tool_bar (f) ...@@ -2698,6 +2709,7 @@ update_frame_tool_bar (f)
int i; int i;
GtkRequisition old_req, new_req; GtkRequisition old_req, new_req;
GList *icon_list; GList *icon_list;
GList *iter;
struct x_output *x = f->output_data.x; struct x_output *x = f->output_data.x;
if (! FRAME_GTK_WIDGET (f)) if (! FRAME_GTK_WIDGET (f))
...@@ -2711,7 +2723,8 @@ update_frame_tool_bar (f) ...@@ -2711,7 +2723,8 @@ update_frame_tool_bar (f)
gtk_widget_size_request (x->toolbar_widget, &old_req); gtk_widget_size_request (x->toolbar_widget, &old_req);
icon_list = gtk_container_get_children (GTK_CONTAINER (x->toolbar_widget)); icon_list = gtk_container_get_children (GTK_CONTAINER (x->toolbar_widget));
iter = icon_list;
for (i = 0; i < f->n_tool_bar_items; ++i) for (i = 0; i < f->n_tool_bar_items; ++i)
{ {
#define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX)) #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
...@@ -2722,9 +2735,9 @@ update_frame_tool_bar (f) ...@@ -2722,9 +2735,9 @@ update_frame_tool_bar (f)
int img_id; int img_id;
struct image *img; struct image *img;
Lisp_Object image; Lisp_Object image;
GtkWidget *wicon = icon_list ? GTK_WIDGET (icon_list->data) : 0; GtkWidget *wicon = iter ? GTK_WIDGET (iter->data) : 0;
if (icon_list) icon_list = g_list_next (icon_list); if (iter) iter = g_list_next (iter);
/* If image is a vector, choose the image according to the /* If image is a vector, choose the image according to the
button state. */ button state. */
...@@ -2812,10 +2825,11 @@ update_frame_tool_bar (f) ...@@ -2812,10 +2825,11 @@ update_frame_tool_bar (f)
/* The child of the tool bar is a button. Inside that button /* The child of the tool bar is a button. Inside that button
is a vbox. Inside that vbox is the GtkImage. */ is a vbox. Inside that vbox is the GtkImage. */
GtkWidget *wvbox = gtk_bin_get_child (GTK_BIN (wicon)); GtkWidget *wvbox = gtk_bin_get_child (GTK_BIN (wicon));
GList *ch = gtk_container_get_children (GTK_CONTAINER (wvbox)); GList *chlist = gtk_container_get_children (GTK_CONTAINER (wvbox));
GtkImage *wimage = GTK_IMAGE (ch->data); GtkImage *wimage = GTK_IMAGE (chlist->data);
struct image *old_img = g_object_get_data (G_OBJECT (wimage), struct image *old_img = g_object_get_data (G_OBJECT (wimage),
XG_TOOL_BAR_IMAGE_DATA); XG_TOOL_BAR_IMAGE_DATA);
g_list_free (chlist);
if (! old_img if (! old_img
|| old_img->pixmap != img->pixmap || old_img->pixmap != img->pixmap
...@@ -2840,11 +2854,11 @@ update_frame_tool_bar (f) ...@@ -2840,11 +2854,11 @@ update_frame_tool_bar (f)
/* Remove buttons not longer needed. We just hide them so they /* Remove buttons not longer needed. We just hide them so they
can be reused later on. */ can be reused later on. */
while (icon_list) while (iter)
{ {
GtkWidget *w = GTK_WIDGET (icon_list->data); GtkWidget *w = GTK_WIDGET (iter->data);
gtk_widget_hide (w); gtk_widget_hide (w);
icon_list = g_list_next (icon_list); iter = g_list_next (iter);
} }
gtk_widget_size_request (x->toolbar_widget, &new_req); gtk_widget_size_request (x->toolbar_widget, &new_req);
...@@ -2857,6 +2871,8 @@ update_frame_tool_bar (f) ...@@ -2857,6 +2871,8 @@ update_frame_tool_bar (f)
/* Must force out update so changed images gets redrawn. */ /* Must force out update so changed images gets redrawn. */
gdk_window_process_all_updates (); gdk_window_process_all_updates ();
if (icon_list) g_list_free (icon_list);
UNBLOCK_INPUT; UNBLOCK_INPUT;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment