diff options
| author | Richard M. Stallman | 2002-07-31 06:15:58 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2002-07-31 06:15:58 +0000 |
| commit | ced89c24f5c9d794291aaccb9e55dcd6e7dbf66a (patch) | |
| tree | 2f70609ac6357a9d5bd1e19310c8f91bf1c3ab0f | |
| parent | ac474af158838341ece00dd620f79a7e7cce283d (diff) | |
| download | emacs-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/ChangeLog | 10 | ||||
| -rw-r--r-- | src/xmenu.c | 97 |
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 @@ | |||
| 1 | 2002-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 | |||
| 1 | 2002-07-30 Juanma Barranquero <lektu@terra.es> | 11 | 2002-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 | ||
| 1352 | static widget_value * | 1352 | static int |
| 1353 | single_submenu (item_key, item_name, maps) | 1353 | parse_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 | |||
| 1398 | static widget_value * | ||
| 1399 | digest_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 | { |