aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2006-04-21 07:56:47 +0000
committerYAMAMOTO Mitsuharu2006-04-21 07:56:47 +0000
commitf1d7196a178d12d29238dee6d272fb85ff191a32 (patch)
tree6caa2411b050417a8da8aab8456c1a8494390f6d
parent0b8ac8420248493a9dbf19aced274492ee030fe0 (diff)
downloademacs-f1d7196a178d12d29238dee6d272fb85ff191a32.tar.gz
emacs-f1d7196a178d12d29238dee6d272fb85ff191a32.zip
(restore_menu_items, save_menu_items): New functions from xmenu.c.
(set_frame_menubar, digest_single_submenu): Apply 2006-04-18 changes for xmenu.c.
-rw-r--r--src/macmenu.c58
1 files changed, 53 insertions, 5 deletions
diff --git a/src/macmenu.c b/src/macmenu.c
index 29233ec0d64..be565f89259 100644
--- a/src/macmenu.c
+++ b/src/macmenu.c
@@ -303,6 +303,37 @@ discard_menu_items ()
303 } 303 }
304} 304}
305 305
306/* This undoes save_menu_items, and it is called by the specpdl unwind
307 mechanism. */
308
309static Lisp_Object
310restore_menu_items (saved)
311 Lisp_Object saved;
312{
313 menu_items = XCAR (saved);
314 menu_items_allocated = (VECTORP (menu_items) ? ASIZE (menu_items) : 0);
315 saved = XCDR (saved);
316 menu_items_used = XINT (XCAR (saved));
317 saved = XCDR (saved);
318 menu_items_n_panes = XINT (XCAR (saved));
319 saved = XCDR (saved);
320 menu_items_submenu_depth = XINT (XCAR (saved));
321}
322
323/* Push the whole state of menu_items processing onto the specpdl.
324 It will be restored when the specpdl is unwound. */
325
326static void
327save_menu_items ()
328{
329 Lisp_Object saved = list4 (menu_items,
330 make_number (menu_items_used),
331 make_number (menu_items_n_panes),
332 make_number (menu_items_submenu_depth));
333 record_unwind_protect (restore_menu_items, saved);
334 menu_items = Qnil;
335}
336
306/* Make the menu_items vector twice as large. */ 337/* Make the menu_items vector twice as large. */
307 338
308static void 339static void
@@ -313,6 +344,7 @@ grow_menu_items ()
313 old = menu_items; 344 old = menu_items;
314 345
315 menu_items_allocated *= 2; 346 menu_items_allocated *= 2;
347
316 menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil); 348 menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
317 bcopy (XVECTOR (old)->contents, XVECTOR (menu_items)->contents, 349 bcopy (XVECTOR (old)->contents, XVECTOR (menu_items)->contents,
318 old_size * sizeof (Lisp_Object)); 350 old_size * sizeof (Lisp_Object));
@@ -1185,6 +1217,7 @@ digest_single_submenu (start, end, top_level_items)
1185 int i; 1217 int i;
1186 int submenu_depth = 0; 1218 int submenu_depth = 0;
1187 widget_value **submenu_stack; 1219 widget_value **submenu_stack;
1220 int panes_seen = 0;
1188 1221
1189 submenu_stack 1222 submenu_stack
1190 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); 1223 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
@@ -1231,6 +1264,8 @@ digest_single_submenu (start, end, top_level_items)
1231 Lisp_Object pane_name, prefix; 1264 Lisp_Object pane_name, prefix;
1232 char *pane_string; 1265 char *pane_string;
1233 1266
1267 panes_seen++;
1268
1234 pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME]; 1269 pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];
1235 prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; 1270 prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
1236 1271
@@ -1278,6 +1313,10 @@ digest_single_submenu (start, end, top_level_items)
1278 Lisp_Object item_name, enable, descrip, def, type, selected; 1313 Lisp_Object item_name, enable, descrip, def, type, selected;
1279 Lisp_Object help; 1314 Lisp_Object help;
1280 1315
1316 /* All items should be contained in panes. */
1317 if (panes_seen == 0)
1318 abort ();
1319
1281 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); 1320 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
1282 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); 1321 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
1283 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY); 1322 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
@@ -1529,6 +1568,8 @@ set_frame_menubar (f, first_time, deep_p)
1529 1568
1530 /* Fill in menu_items with the current menu bar contents. 1569 /* Fill in menu_items with the current menu bar contents.
1531 This can evaluate Lisp code. */ 1570 This can evaluate Lisp code. */
1571 save_menu_items ();
1572
1532 menu_items = f->menu_bar_vector; 1573 menu_items = f->menu_bar_vector;
1533 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; 1574 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
1534 submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *)); 1575 submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
@@ -1588,23 +1629,33 @@ set_frame_menubar (f, first_time, deep_p)
1588 } 1629 }
1589 1630
1590 set_buffer_internal_1 (prev); 1631 set_buffer_internal_1 (prev);
1591 unbind_to (specpdl_count, Qnil);
1592 1632
1593 /* If there has been no change in the Lisp-level contents 1633 /* If there has been no change in the Lisp-level contents
1594 of the menu bar, skip redisplaying it. Just exit. */ 1634 of the menu bar, skip redisplaying it. Just exit. */
1595 1635
1636 /* Compare the new menu items with the ones computed last time. */
1596 for (i = 0; i < previous_menu_items_used; i++) 1637 for (i = 0; i < previous_menu_items_used; i++)
1597 if (menu_items_used == i 1638 if (menu_items_used == i
1598 || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i]))) 1639 || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i])))
1599 break; 1640 break;
1600 if (i == menu_items_used && i == previous_menu_items_used && i != 0) 1641 if (i == menu_items_used && i == previous_menu_items_used && i != 0)
1601 { 1642 {
1643 /* The menu items have not changed. Don't bother updating
1644 the menus in any form, since it would be a no-op. */
1602 free_menubar_widget_value_tree (first_wv); 1645 free_menubar_widget_value_tree (first_wv);
1603 discard_menu_items (); 1646 discard_menu_items ();
1604 1647 unbind_to (specpdl_count, Qnil);
1605 return; 1648 return;
1606 } 1649 }
1607 1650
1651 /* The menu items are different, so store them in the frame. */
1652 f->menu_bar_vector = menu_items;
1653 f->menu_bar_items_used = menu_items_used;
1654
1655 /* This calls restore_menu_items to restore menu_items, etc.,
1656 as they were outside. */
1657 unbind_to (specpdl_count, Qnil);
1658
1608 /* Now GC cannot happen during the lifetime of the widget_value, 1659 /* Now GC cannot happen during the lifetime of the widget_value,
1609 so it's safe to store data from a Lisp_String. */ 1660 so it's safe to store data from a Lisp_String. */
1610 wv = first_wv->contents; 1661 wv = first_wv->contents;
@@ -1619,9 +1670,6 @@ set_frame_menubar (f, first_time, deep_p)
1619 wv = wv->next; 1670 wv = wv->next;
1620 } 1671 }
1621 1672
1622 f->menu_bar_vector = menu_items;
1623 f->menu_bar_items_used = menu_items_used;
1624 discard_menu_items ();
1625 } 1673 }
1626 else 1674 else
1627 { 1675 {