aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman2002-07-31 06:15:58 +0000
committerRichard M. Stallman2002-07-31 06:15:58 +0000
commitced89c24f5c9d794291aaccb9e55dcd6e7dbf66a (patch)
tree2f70609ac6357a9d5bd1e19310c8f91bf1c3ab0f
parentac474af158838341ece00dd620f79a7e7cce283d (diff)
downloademacs-ced89c24f5c9d794291aaccb9e55dcd6e7dbf66a.tar.gz
emacs-ced89c24f5c9d794291aaccb9e55dcd6e7dbf66a.zip
(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.
-rw-r--r--src/ChangeLog10
-rw-r--r--src/xmenu.c97
2 files changed, 76 insertions, 31 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 936837e9970..58d1770e1e0 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
12002-07-31 Richard M. Stallman <rms@gnu.org>
2
3 * xmenu.c (set_frame_menubar): First parse all submenus,
4 then make widget_value trees from them.
5 Don't allocate any widget_value objects
6 until we are done with the parsing.
7 (parse_single_submenu): New function.
8 (digest_single_submenu): New function.
9 (single_submenu): Function deleted, replaced by those two.
10
12002-07-30 Juanma Barranquero <lektu@terra.es> 112002-07-30 Juanma Barranquero <lektu@terra.es>
2 12
3 * w32proc.c (syms_of_ntproc): Fix docstring of 13 * w32proc.c (syms_of_ntproc): Fix docstring of
diff --git a/src/xmenu.c b/src/xmenu.c
index cc613bedeb1..75584afc079 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1345,22 +1345,18 @@ free_menubar_widget_value_tree (wv)
1345 UNBLOCK_INPUT; 1345 UNBLOCK_INPUT;
1346} 1346}
1347 1347
1348/* Return a tree of widget_value structures for a menu bar item 1348/* Set up data i menu_items for a menu bar item
1349 whose event type is ITEM_KEY (with string ITEM_NAME) 1349 whose event type is ITEM_KEY (with string ITEM_NAME)
1350 and whose contents come from the list of keymaps MAPS. */ 1350 and whose contents come from the list of keymaps MAPS. */
1351 1351
1352static widget_value * 1352static int
1353single_submenu (item_key, item_name, maps) 1353parse_single_submenu (item_key, item_name, maps)
1354 Lisp_Object item_key, item_name, maps; 1354 Lisp_Object item_key, item_name, maps;
1355{ 1355{
1356 widget_value *wv, *prev_wv, *save_wv, *first_wv;
1357 int i;
1358 int submenu_depth = 0;
1359 Lisp_Object length; 1356 Lisp_Object length;
1360 int len; 1357 int len;
1361 Lisp_Object *mapvec; 1358 Lisp_Object *mapvec;
1362 widget_value **submenu_stack; 1359 int i;
1363 int previous_items = menu_items_used;
1364 int top_level_items = 0; 1360 int top_level_items = 0;
1365 1361
1366 length = Flength (maps); 1362 length = Flength (maps);
@@ -1374,8 +1370,6 @@ single_submenu (item_key, item_name, maps)
1374 maps = Fcdr (maps); 1370 maps = Fcdr (maps);
1375 } 1371 }
1376 1372
1377 menu_items_n_panes = 0;
1378
1379 /* Loop over the given keymaps, making a pane for each map. 1373 /* Loop over the given keymaps, making a pane for each map.
1380 But don't make a pane that is empty--ignore that map instead. */ 1374 But don't make a pane that is empty--ignore that map instead. */
1381 for (i = 0; i < len; i++) 1375 for (i = 0; i < len; i++)
@@ -1394,8 +1388,21 @@ single_submenu (item_key, item_name, maps)
1394 single_keymap_panes (mapvec[i], item_name, item_key, 0, 10); 1388 single_keymap_panes (mapvec[i], item_name, item_key, 0, 10);
1395 } 1389 }
1396 1390
1397 /* Create a tree of widget_value objects 1391 return top_level_items;
1398 representing the panes and their items. */ 1392}
1393
1394/* Create a tree of widget_value objects
1395 representing the panes and items
1396 in menu_items starting at index START, up to index END. */
1397
1398static widget_value *
1399digest_single_submenu (start, end, top_level_items)
1400 int start, end;
1401{
1402 widget_value *wv, *prev_wv, *save_wv, *first_wv;
1403 int i;
1404 int submenu_depth = 0;
1405 widget_value **submenu_stack;
1399 1406
1400 submenu_stack 1407 submenu_stack
1401 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); 1408 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
@@ -1413,8 +1420,8 @@ single_submenu (item_key, item_name, maps)
1413 and construct a tree of widget_value objects. 1420 and construct a tree of widget_value objects.
1414 Ignore the panes and items made by previous calls to 1421 Ignore the panes and items made by previous calls to
1415 single_submenu, even though those are also in menu_items. */ 1422 single_submenu, even though those are also in menu_items. */
1416 i = previous_items; 1423 i = start;
1417 while (i < menu_items_used) 1424 while (i < end)
1418 { 1425 {
1419 if (EQ (XVECTOR (menu_items)->contents[i], Qnil)) 1426 if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
1420 { 1427 {
@@ -1558,8 +1565,6 @@ single_submenu (item_key, item_name, maps)
1558 1565
1559 return first_wv; 1566 return first_wv;
1560} 1567}
1561
1562
1563 1568
1564/* Recompute all the widgets of frame F, when the menu bar has been 1569/* Recompute all the widgets of frame F, when the menu bar has been
1565 changed. Value is non-zero if widgets were updated. */ 1570 changed. Value is non-zero if widgets were updated. */
@@ -1618,7 +1623,9 @@ set_frame_menubar (f, first_time, deep_p)
1618 Widget menubar_widget = f->output_data.x->menubar_widget; 1623 Widget menubar_widget = f->output_data.x->menubar_widget;
1619 Lisp_Object items; 1624 Lisp_Object items;
1620 widget_value *wv, *first_wv, *prev_wv = 0; 1625 widget_value *wv, *first_wv, *prev_wv = 0;
1621 int i; 1626 int i, last_i;
1627 int *submenu_start, *submenu_end;
1628 int *submenu_top_level_items;
1622 1629
1623 LWLIB_ID id; 1630 LWLIB_ID id;
1624 1631
@@ -1640,14 +1647,6 @@ set_frame_menubar (f, first_time, deep_p)
1640 f->output_data.x->saved_menu_event->type = 0; 1647 f->output_data.x->saved_menu_event->type = 0;
1641 } 1648 }
1642 1649
1643 wv = xmalloc_widget_value ();
1644 wv->name = "menubar";
1645 wv->value = 0;
1646 wv->enabled = 1;
1647 wv->button_type = BUTTON_TYPE_NONE;
1648 wv->help = Qnil;
1649 first_wv = wv;
1650
1651 if (deep_p) 1650 if (deep_p)
1652 { 1651 {
1653 /* Make a widget-value tree representing the entire menu trees. */ 1652 /* Make a widget-value tree representing the entire menu trees. */
@@ -1692,28 +1691,58 @@ set_frame_menubar (f, first_time, deep_p)
1692 1691
1693 items = FRAME_MENU_BAR_ITEMS (f); 1692 items = FRAME_MENU_BAR_ITEMS (f);
1694 1693
1695 inhibit_garbage_collection ();
1696
1697 /* Save the frame's previous menu bar contents data. */ 1694 /* Save the frame's previous menu bar contents data. */
1698 if (previous_menu_items_used) 1695 if (previous_menu_items_used)
1699 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, 1696 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
1700 previous_menu_items_used * sizeof (Lisp_Object)); 1697 previous_menu_items_used * sizeof (Lisp_Object));
1701 1698
1702 /* Fill in the current menu bar contents. */ 1699 /* Fill in menu_items with the current menu bar contents.
1700 This can evaluate Lisp code. */
1703 menu_items = f->menu_bar_vector; 1701 menu_items = f->menu_bar_vector;
1704 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; 1702 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
1703 submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1704 submenu_end = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1705 submenu_top_level_items
1706 = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
1705 init_menu_items (); 1707 init_menu_items ();
1706 for (i = 0; i < XVECTOR (items)->size; i += 4) 1708 for (i = 0; i < XVECTOR (items)->size; i += 4)
1707 { 1709 {
1708 Lisp_Object key, string, maps; 1710 Lisp_Object key, string, maps;
1709 1711
1712 last_i = i;
1713
1710 key = XVECTOR (items)->contents[i]; 1714 key = XVECTOR (items)->contents[i];
1711 string = XVECTOR (items)->contents[i + 1]; 1715 string = XVECTOR (items)->contents[i + 1];
1712 maps = XVECTOR (items)->contents[i + 2]; 1716 maps = XVECTOR (items)->contents[i + 2];
1713 if (NILP (string)) 1717 if (NILP (string))
1714 break; 1718 break;
1715 1719
1716 wv = single_submenu (key, string, maps); 1720 submenu_start[i] = menu_items_used;
1721
1722 menu_items_n_panes = 0;
1723 submenu_top_level_items[i]
1724 = parse_single_submenu (key, string, maps);
1725
1726 submenu_end[i] = menu_items_used;
1727 }
1728
1729 finish_menu_items ();
1730
1731 /* Convert menu_items into widget_value trees
1732 to display the menu. This cannot evaluate Lisp code. */
1733
1734 wv = xmalloc_widget_value ();
1735 wv->name = "menubar";
1736 wv->value = 0;
1737 wv->enabled = 1;
1738 wv->button_type = BUTTON_TYPE_NONE;
1739 wv->help = Qnil;
1740 first_wv = wv;
1741
1742 for (i = 0; i < last_i; i += 4)
1743 {
1744 wv = digest_single_submenu (submenu_start[i], submenu_end[i],
1745 submenu_top_level_items[i]);
1717 if (prev_wv) 1746 if (prev_wv)
1718 prev_wv->next = wv; 1747 prev_wv->next = wv;
1719 else 1748 else
@@ -1724,8 +1753,6 @@ set_frame_menubar (f, first_time, deep_p)
1724 prev_wv = wv; 1753 prev_wv = wv;
1725 } 1754 }
1726 1755
1727 finish_menu_items ();
1728
1729 set_buffer_internal_1 (prev); 1756 set_buffer_internal_1 (prev);
1730 unbind_to (specpdl_count, Qnil); 1757 unbind_to (specpdl_count, Qnil);
1731 1758
@@ -1766,6 +1793,14 @@ set_frame_menubar (f, first_time, deep_p)
1766 /* Make a widget-value tree containing 1793 /* Make a widget-value tree containing
1767 just the top level menu bar strings. */ 1794 just the top level menu bar strings. */
1768 1795
1796 wv = xmalloc_widget_value ();
1797 wv->name = "menubar";
1798 wv->value = 0;
1799 wv->enabled = 1;
1800 wv->button_type = BUTTON_TYPE_NONE;
1801 wv->help = Qnil;
1802 first_wv = wv;
1803
1769 items = FRAME_MENU_BAR_ITEMS (f); 1804 items = FRAME_MENU_BAR_ITEMS (f);
1770 for (i = 0; i < XVECTOR (items)->size; i += 4) 1805 for (i = 0; i < XVECTOR (items)->size; i += 4)
1771 { 1806 {