Commit ced89c24 authored by Richard M. Stallman's avatar Richard M. Stallman
Browse files

(set_frame_menubar): First parse all submenus,

then make widget_value trees from them.
Don't allocate any widget_value objects
until we are done with the parsing.
(parse_single_submenu): New function.
(digest_single_submenu): New function.
(single_submenu): Function deleted, replaced by those two.
parent ac474af1
2002-07-31 Richard M. Stallman <rms@gnu.org>
* xmenu.c (set_frame_menubar): First parse all submenus,
then make widget_value trees from them.
Don't allocate any widget_value objects
until we are done with the parsing.
(parse_single_submenu): New function.
(digest_single_submenu): New function.
(single_submenu): Function deleted, replaced by those two.
2002-07-30 Juanma Barranquero <lektu@terra.es> 2002-07-30 Juanma Barranquero <lektu@terra.es>
* w32proc.c (syms_of_ntproc): Fix docstring of * w32proc.c (syms_of_ntproc): Fix docstring of
......
...@@ -1345,22 +1345,18 @@ free_menubar_widget_value_tree (wv) ...@@ -1345,22 +1345,18 @@ free_menubar_widget_value_tree (wv)
UNBLOCK_INPUT; UNBLOCK_INPUT;
} }
/* Return a tree of widget_value structures for a menu bar item /* Set up data i menu_items for a menu bar item
whose event type is ITEM_KEY (with string ITEM_NAME) whose event type is ITEM_KEY (with string ITEM_NAME)
and whose contents come from the list of keymaps MAPS. */ and whose contents come from the list of keymaps MAPS. */
static widget_value * static int
single_submenu (item_key, item_name, maps) parse_single_submenu (item_key, item_name, maps)
Lisp_Object item_key, item_name, maps; Lisp_Object item_key, item_name, maps;
{ {
widget_value *wv, *prev_wv, *save_wv, *first_wv;
int i;
int submenu_depth = 0;
Lisp_Object length; Lisp_Object length;
int len; int len;
Lisp_Object *mapvec; Lisp_Object *mapvec;
widget_value **submenu_stack; int i;
int previous_items = menu_items_used;
int top_level_items = 0; int top_level_items = 0;
length = Flength (maps); length = Flength (maps);
...@@ -1374,8 +1370,6 @@ single_submenu (item_key, item_name, maps) ...@@ -1374,8 +1370,6 @@ single_submenu (item_key, item_name, maps)
maps = Fcdr (maps); maps = Fcdr (maps);
} }
menu_items_n_panes = 0;
/* Loop over the given keymaps, making a pane for each map. /* Loop over the given keymaps, making a pane for each map.
But don't make a pane that is empty--ignore that map instead. */ But don't make a pane that is empty--ignore that map instead. */
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
...@@ -1394,8 +1388,21 @@ single_submenu (item_key, item_name, maps) ...@@ -1394,8 +1388,21 @@ single_submenu (item_key, item_name, maps)
single_keymap_panes (mapvec[i], item_name, item_key, 0, 10); single_keymap_panes (mapvec[i], item_name, item_key, 0, 10);
} }
/* Create a tree of widget_value objects return top_level_items;
representing the panes and their items. */ }
/* Create a tree of widget_value objects
representing the panes and items
in menu_items starting at index START, up to index END. */
static widget_value *
digest_single_submenu (start, end, top_level_items)
int start, end;
{
widget_value *wv, *prev_wv, *save_wv, *first_wv;
int i;
int submenu_depth = 0;
widget_value **submenu_stack;
submenu_stack submenu_stack
= (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
...@@ -1413,8 +1420,8 @@ single_submenu (item_key, item_name, maps) ...@@ -1413,8 +1420,8 @@ single_submenu (item_key, item_name, maps)
and construct a tree of widget_value objects. and construct a tree of widget_value objects.
Ignore the panes and items made by previous calls to Ignore the panes and items made by previous calls to
single_submenu, even though those are also in menu_items. */ single_submenu, even though those are also in menu_items. */
i = previous_items; i = start;
while (i < menu_items_used) while (i < end)
{ {
if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
{ {
...@@ -1558,8 +1565,6 @@ single_submenu (item_key, item_name, maps) ...@@ -1558,8 +1565,6 @@ single_submenu (item_key, item_name, maps)
return first_wv; return first_wv;
} }
/* Recompute all the widgets of frame F, when the menu bar has been /* Recompute all the widgets of frame F, when the menu bar has been
changed. Value is non-zero if widgets were updated. */ changed. Value is non-zero if widgets were updated. */
...@@ -1618,7 +1623,9 @@ set_frame_menubar (f, first_time, deep_p) ...@@ -1618,7 +1623,9 @@ set_frame_menubar (f, first_time, deep_p)
Widget menubar_widget = f->output_data.x->menubar_widget; Widget menubar_widget = f->output_data.x->menubar_widget;
Lisp_Object items; Lisp_Object items;
widget_value *wv, *first_wv, *prev_wv = 0; widget_value *wv, *first_wv, *prev_wv = 0;
int i; int i, last_i;
int *submenu_start, *submenu_end;
int *submenu_top_level_items;
LWLIB_ID id; LWLIB_ID id;
...@@ -1640,14 +1647,6 @@ set_frame_menubar (f, first_time, deep_p) ...@@ -1640,14 +1647,6 @@ set_frame_menubar (f, first_time, deep_p)
f->output_data.x->saved_menu_event->type = 0; f->output_data.x->saved_menu_event->type = 0;
} }
wv = xmalloc_widget_value ();
wv->name = "menubar";
wv->value = 0;
wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
wv->help = Qnil;
first_wv = wv;
if (deep_p) if (deep_p)
{ {
/* Make a widget-value tree representing the entire menu trees. */ /* Make a widget-value tree representing the entire menu trees. */
...@@ -1692,28 +1691,58 @@ set_frame_menubar (f, first_time, deep_p) ...@@ -1692,28 +1691,58 @@ set_frame_menubar (f, first_time, deep_p)
items = FRAME_MENU_BAR_ITEMS (f); items = FRAME_MENU_BAR_ITEMS (f);
inhibit_garbage_collection ();
/* Save the frame's previous menu bar contents data. */ /* Save the frame's previous menu bar contents data. */
if (previous_menu_items_used) if (previous_menu_items_used)
bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
previous_menu_items_used * sizeof (Lisp_Object)); previous_menu_items_used * sizeof (Lisp_Object));
/* Fill in the current menu bar contents. */ /* Fill in menu_items with the current menu bar contents.
This can evaluate Lisp code. */
menu_items = f->menu_bar_vector; menu_items = f->menu_bar_vector;
menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
submenu_top_level_items
= (int *) alloca (XVECTOR (items)->size * sizeof (int *));
init_menu_items (); init_menu_items ();
for (i = 0; i < XVECTOR (items)->size; i += 4) for (i = 0; i < XVECTOR (items)->size; i += 4)
{ {
Lisp_Object key, string, maps; Lisp_Object key, string, maps;
last_i = i;
key = XVECTOR (items)->contents[i]; key = XVECTOR (items)->contents[i];
string = XVECTOR (items)->contents[i + 1]; string = XVECTOR (items)->contents[i + 1];
maps = XVECTOR (items)->contents[i + 2]; maps = XVECTOR (items)->contents[i + 2];
if (NILP (string)) if (NILP (string))
break; break;
wv = single_submenu (key, string, maps); submenu_start[i] = menu_items_used;
menu_items_n_panes = 0;
submenu_top_level_items[i]
= parse_single_submenu (key, string, maps);
submenu_end[i] = menu_items_used;
}
finish_menu_items ();
/* Convert menu_items into widget_value trees
to display the menu. This cannot evaluate Lisp code. */
wv = xmalloc_widget_value ();
wv->name = "menubar";
wv->value = 0;
wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
wv->help = Qnil;
first_wv = wv;
for (i = 0; i < last_i; i += 4)
{
wv = digest_single_submenu (submenu_start[i], submenu_end[i],
submenu_top_level_items[i]);
if (prev_wv) if (prev_wv)
prev_wv->next = wv; prev_wv->next = wv;
else else
...@@ -1724,8 +1753,6 @@ set_frame_menubar (f, first_time, deep_p) ...@@ -1724,8 +1753,6 @@ set_frame_menubar (f, first_time, deep_p)
prev_wv = wv; prev_wv = wv;
} }
finish_menu_items ();
set_buffer_internal_1 (prev); set_buffer_internal_1 (prev);
unbind_to (specpdl_count, Qnil); unbind_to (specpdl_count, Qnil);
...@@ -1766,6 +1793,14 @@ set_frame_menubar (f, first_time, deep_p) ...@@ -1766,6 +1793,14 @@ set_frame_menubar (f, first_time, deep_p)
/* Make a widget-value tree containing /* Make a widget-value tree containing
just the top level menu bar strings. */ just the top level menu bar strings. */
wv = xmalloc_widget_value ();
wv->name = "menubar";
wv->value = 0;
wv->enabled = 1;
wv->button_type = BUTTON_TYPE_NONE;
wv->help = Qnil;
first_wv = wv;
items = FRAME_MENU_BAR_ITEMS (f); items = FRAME_MENU_BAR_ITEMS (f);
for (i = 0; i < XVECTOR (items)->size; i += 4) for (i = 0; i < XVECTOR (items)->size; i += 4)
{ {
......
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