aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman2006-04-18 21:01:16 +0000
committerRichard M. Stallman2006-04-18 21:01:16 +0000
commit1fc4d4635c4b08c5506ca8bbafb903d2aba20e8e (patch)
treeefe61f185544da18994e030f1859dc67d0b023de /src
parent6588243de7882f4a3d2902688e363639ac375618 (diff)
downloademacs-1fc4d4635c4b08c5506ca8bbafb903d2aba20e8e.tar.gz
emacs-1fc4d4635c4b08c5506ca8bbafb903d2aba20e8e.zip
(restore_menu_items, save_menu_items): New fns.
(set_frame_menubar): Use save_menu_items. Save updated vector in the frame before unwinding it. Don't use unuse_menu_items. Don't use discard_menu_items. (digest_single_submenu): Abort if an item is not in a pane. (init_menu_items): Put the error check at the top.
Diffstat (limited to 'src')
-rw-r--r--src/xmenu.c60
1 files changed, 52 insertions, 8 deletions
diff --git a/src/xmenu.c b/src/xmenu.c
index 9b93822ecf5..6de1dcb2bd1 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -266,14 +266,15 @@ menubar_id_to_frame (id)
266static void 266static void
267init_menu_items () 267init_menu_items ()
268{ 268{
269 if (!NILP (menu_items_inuse))
270 error ("Trying to use a menu from within a menu-entry");
271
269 if (NILP (menu_items)) 272 if (NILP (menu_items))
270 { 273 {
271 menu_items_allocated = 60; 274 menu_items_allocated = 60;
272 menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil); 275 menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
273 } 276 }
274 277
275 if (!NILP (menu_items_inuse))
276 error ("Trying to use a menu from within a menu-entry");
277 menu_items_inuse = Qt; 278 menu_items_inuse = Qt;
278 menu_items_used = 0; 279 menu_items_used = 0;
279 menu_items_n_panes = 0; 280 menu_items_n_panes = 0;
@@ -310,6 +311,39 @@ discard_menu_items ()
310 xassert (NILP (menu_items_inuse)); 311 xassert (NILP (menu_items_inuse));
311} 312}
312 313
314/* This undoes save_menu_items, and it is called by the specpdl unwind
315 mechanism. */
316
317static Lisp_Object
318restore_menu_items (saved)
319 Lisp_Object saved;
320{
321 menu_items = XCAR (saved);
322 menu_items_inuse = (! NILP (menu_items) ? Qt : Qnil);
323 menu_items_allocated = (VECTORP (menu_items) ? ASIZE (menu_items) : 0);
324 saved = XCDR (saved);
325 menu_items_used = XINT (XCAR (saved));
326 saved = XCDR (saved);
327 menu_items_n_panes = XINT (XCAR (saved));
328 saved = XCDR (saved);
329 menu_items_submenu_depth = XINT (XCAR (saved));
330}
331
332/* Push the whole state of menu_items processing onto the specpdl.
333 It will be restored when the specpdl is unwound. */
334
335static void
336save_menu_items ()
337{
338 Lisp_Object saved = list4 (!NILP (menu_items_inuse) ? menu_items : Qnil,
339 make_number (menu_items_used),
340 make_number (menu_items_n_panes),
341 make_number (menu_items_submenu_depth));
342 record_unwind_protect (restore_menu_items, saved);
343 menu_items_inuse = Qnil;
344 menu_items = Qnil;
345}
346
313/* Make the menu_items vector twice as large. */ 347/* Make the menu_items vector twice as large. */
314 348
315static void 349static void
@@ -320,6 +354,7 @@ grow_menu_items ()
320 old = menu_items; 354 old = menu_items;
321 355
322 menu_items_allocated *= 2; 356 menu_items_allocated *= 2;
357
323 menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil); 358 menu_items = Fmake_vector (make_number (menu_items_allocated), Qnil);
324 bcopy (XVECTOR (old)->contents, XVECTOR (menu_items)->contents, 359 bcopy (XVECTOR (old)->contents, XVECTOR (menu_items)->contents,
325 old_size * sizeof (Lisp_Object)); 360 old_size * sizeof (Lisp_Object));
@@ -1728,6 +1763,7 @@ digest_single_submenu (start, end, top_level_items)
1728 int i; 1763 int i;
1729 int submenu_depth = 0; 1764 int submenu_depth = 0;
1730 widget_value **submenu_stack; 1765 widget_value **submenu_stack;
1766 int panes_seen = 0;
1731 1767
1732 submenu_stack 1768 submenu_stack
1733 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); 1769 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
@@ -1774,6 +1810,8 @@ digest_single_submenu (start, end, top_level_items)
1774 Lisp_Object pane_name, prefix; 1810 Lisp_Object pane_name, prefix;
1775 char *pane_string; 1811 char *pane_string;
1776 1812
1813 panes_seen++;
1814
1777 pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME]; 1815 pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];
1778 prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; 1816 prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
1779 1817
@@ -1821,6 +1859,10 @@ digest_single_submenu (start, end, top_level_items)
1821 Lisp_Object item_name, enable, descrip, def, type, selected; 1859 Lisp_Object item_name, enable, descrip, def, type, selected;
1822 Lisp_Object help; 1860 Lisp_Object help;
1823 1861
1862 /* All items should be contained in panes. */
1863 if (panes_seen == 0)
1864 abort ();
1865
1824 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); 1866 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
1825 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); 1867 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
1826 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY); 1868 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
@@ -2046,7 +2088,6 @@ set_frame_menubar (f, first_time, deep_p)
2046 specbind (Qdebug_on_next_call, Qnil); 2088 specbind (Qdebug_on_next_call, Qnil);
2047 2089
2048 record_unwind_save_match_data (); 2090 record_unwind_save_match_data ();
2049 record_unwind_protect (unuse_menu_items, Qnil);
2050 if (NILP (Voverriding_local_map_menu_flag)) 2091 if (NILP (Voverriding_local_map_menu_flag))
2051 { 2092 {
2052 specbind (Qoverriding_terminal_local_map, Qnil); 2093 specbind (Qoverriding_terminal_local_map, Qnil);
@@ -2074,6 +2115,8 @@ set_frame_menubar (f, first_time, deep_p)
2074 2115
2075 /* Fill in menu_items with the current menu bar contents. 2116 /* Fill in menu_items with the current menu bar contents.
2076 This can evaluate Lisp code. */ 2117 This can evaluate Lisp code. */
2118 save_menu_items ();
2119
2077 menu_items = f->menu_bar_vector; 2120 menu_items = f->menu_bar_vector;
2078 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; 2121 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
2079 submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *)); 2122 submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
@@ -2133,7 +2176,6 @@ set_frame_menubar (f, first_time, deep_p)
2133 } 2176 }
2134 2177
2135 set_buffer_internal_1 (prev); 2178 set_buffer_internal_1 (prev);
2136 unbind_to (specpdl_count, Qnil);
2137 2179
2138 /* If there has been no change in the Lisp-level contents 2180 /* If there has been no change in the Lisp-level contents
2139 of the menu bar, skip redisplaying it. Just exit. */ 2181 of the menu bar, skip redisplaying it. Just exit. */
@@ -2146,10 +2188,15 @@ set_frame_menubar (f, first_time, deep_p)
2146 { 2188 {
2147 free_menubar_widget_value_tree (first_wv); 2189 free_menubar_widget_value_tree (first_wv);
2148 discard_menu_items (); 2190 discard_menu_items ();
2149 2191 unbind_to (specpdl_count, Qnil);
2150 return; 2192 return;
2151 } 2193 }
2152 2194
2195 f->menu_bar_vector = menu_items;
2196 f->menu_bar_items_used = menu_items_used;
2197
2198 unbind_to (specpdl_count, Qnil);
2199
2153 /* Now GC cannot happen during the lifetime of the widget_value, 2200 /* Now GC cannot happen during the lifetime of the widget_value,
2154 so it's safe to store data from a Lisp_String. */ 2201 so it's safe to store data from a Lisp_String. */
2155 wv = first_wv->contents; 2202 wv = first_wv->contents;
@@ -2164,9 +2211,6 @@ set_frame_menubar (f, first_time, deep_p)
2164 wv = wv->next; 2211 wv = wv->next;
2165 } 2212 }
2166 2213
2167 f->menu_bar_vector = menu_items;
2168 f->menu_bar_items_used = menu_items_used;
2169 discard_menu_items ();
2170 } 2214 }
2171 else 2215 else
2172 { 2216 {