aboutsummaryrefslogtreecommitdiffstats
path: root/src/xmenu.c
diff options
context:
space:
mode:
authorKaroly Lorentey2006-04-19 16:23:46 +0000
committerKaroly Lorentey2006-04-19 16:23:46 +0000
commit447b0165acd09060977e05c843f81c0bee4aa4df (patch)
tree70cf2d254760a2cf68a10b67f8a3570c05fff9a5 /src/xmenu.c
parent4c57cca724993ab1334cc5c0b35c22b06daee0c3 (diff)
parent0fea1d10293b4c6d35c1e55b68cd26e91445213c (diff)
downloademacs-447b0165acd09060977e05c843f81c0bee4aa4df.tar.gz
emacs-447b0165acd09060977e05c843f81c0bee4aa4df.zip
Merged from emacs@sv.gnu.org
Patches applied: * emacs@sv.gnu.org/emacs--devo--0--patch-216 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-217 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-218 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-219 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-220 Improve tq.el. * emacs@sv.gnu.org/emacs--devo--0--patch-221 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-222 Update from CVS: src/puresize.h (PURESIZE_RATIO): Reduce to 10/6. * emacs@sv.gnu.org/emacs--devo--0--patch-223 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-224 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-225 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-226 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-227 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-228 Merge from gnus--rel--5.10 * emacs@sv.gnu.org/emacs--devo--0--patch-229 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-230 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-231 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-232 Update from CVS * emacs@sv.gnu.org/emacs--devo--0--patch-233 Update from CVS: lisp/progmodes/python.el (python-mode): Fix typo. * emacs@sv.gnu.org/gnus--rel--5.10--patch-84 Merge from emacs--devo--0 * emacs@sv.gnu.org/gnus--rel--5.10--patch-85 Update from CVS * emacs@sv.gnu.org/gnus--rel--5.10--patch-86 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-550
Diffstat (limited to 'src/xmenu.c')
-rw-r--r--src/xmenu.c66
1 files changed, 58 insertions, 8 deletions
diff --git a/src/xmenu.c b/src/xmenu.c
index 3c8c6d81a37..6e5ec6c5058 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));
@@ -1740,6 +1775,7 @@ digest_single_submenu (start, end, top_level_items)
1740 int i; 1775 int i;
1741 int submenu_depth = 0; 1776 int submenu_depth = 0;
1742 widget_value **submenu_stack; 1777 widget_value **submenu_stack;
1778 int panes_seen = 0;
1743 1779
1744 submenu_stack 1780 submenu_stack
1745 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *)); 1781 = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
@@ -1786,6 +1822,8 @@ digest_single_submenu (start, end, top_level_items)
1786 Lisp_Object pane_name, prefix; 1822 Lisp_Object pane_name, prefix;
1787 char *pane_string; 1823 char *pane_string;
1788 1824
1825 panes_seen++;
1826
1789 pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME]; 1827 pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];
1790 prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX]; 1828 prefix = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
1791 1829
@@ -1833,6 +1871,10 @@ digest_single_submenu (start, end, top_level_items)
1833 Lisp_Object item_name, enable, descrip, def, type, selected; 1871 Lisp_Object item_name, enable, descrip, def, type, selected;
1834 Lisp_Object help; 1872 Lisp_Object help;
1835 1873
1874 /* All items should be contained in panes. */
1875 if (panes_seen == 0)
1876 abort ();
1877
1836 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME); 1878 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
1837 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE); 1879 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
1838 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY); 1880 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
@@ -2067,7 +2109,6 @@ set_frame_menubar (f, first_time, deep_p)
2067 specbind (Qdebug_on_next_call, Qnil); 2109 specbind (Qdebug_on_next_call, Qnil);
2068 2110
2069 record_unwind_save_match_data (); 2111 record_unwind_save_match_data ();
2070 record_unwind_protect (unuse_menu_items, Qnil);
2071 if (NILP (Voverriding_local_map_menu_flag)) 2112 if (NILP (Voverriding_local_map_menu_flag))
2072 { 2113 {
2073 specbind (Qoverriding_terminal_local_map, Qnil); 2114 specbind (Qoverriding_terminal_local_map, Qnil);
@@ -2095,6 +2136,8 @@ set_frame_menubar (f, first_time, deep_p)
2095 2136
2096 /* Fill in menu_items with the current menu bar contents. 2137 /* Fill in menu_items with the current menu bar contents.
2097 This can evaluate Lisp code. */ 2138 This can evaluate Lisp code. */
2139 save_menu_items ();
2140
2098 menu_items = f->menu_bar_vector; 2141 menu_items = f->menu_bar_vector;
2099 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0; 2142 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
2100 submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *)); 2143 submenu_start = (int *) alloca (XVECTOR (items)->size * sizeof (int *));
@@ -2154,23 +2197,33 @@ set_frame_menubar (f, first_time, deep_p)
2154 } 2197 }
2155 2198
2156 set_buffer_internal_1 (prev); 2199 set_buffer_internal_1 (prev);
2157 unbind_to (specpdl_count, Qnil);
2158 2200
2159 /* If there has been no change in the Lisp-level contents 2201 /* If there has been no change in the Lisp-level contents
2160 of the menu bar, skip redisplaying it. Just exit. */ 2202 of the menu bar, skip redisplaying it. Just exit. */
2161 2203
2204 /* Compare the new menu items with the ones computed last time. */
2162 for (i = 0; i < previous_menu_items_used; i++) 2205 for (i = 0; i < previous_menu_items_used; i++)
2163 if (menu_items_used == i 2206 if (menu_items_used == i
2164 || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i]))) 2207 || (!EQ (previous_items[i], XVECTOR (menu_items)->contents[i])))
2165 break; 2208 break;
2166 if (i == menu_items_used && i == previous_menu_items_used && i != 0) 2209 if (i == menu_items_used && i == previous_menu_items_used && i != 0)
2167 { 2210 {
2211 /* The menu items have not changed. Don't bother updating
2212 the menus in any form, since it would be a no-op. */
2168 free_menubar_widget_value_tree (first_wv); 2213 free_menubar_widget_value_tree (first_wv);
2169 discard_menu_items (); 2214 discard_menu_items ();
2170 2215 unbind_to (specpdl_count, Qnil);
2171 return; 2216 return;
2172 } 2217 }
2173 2218
2219 /* The menu items are different, so store them in the frame. */
2220 f->menu_bar_vector = menu_items;
2221 f->menu_bar_items_used = menu_items_used;
2222
2223 /* This calls restore_menu_items to restore menu_items, etc.,
2224 as they were outside. */
2225 unbind_to (specpdl_count, Qnil);
2226
2174 /* Now GC cannot happen during the lifetime of the widget_value, 2227 /* Now GC cannot happen during the lifetime of the widget_value,
2175 so it's safe to store data from a Lisp_String. */ 2228 so it's safe to store data from a Lisp_String. */
2176 wv = first_wv->contents; 2229 wv = first_wv->contents;
@@ -2185,9 +2238,6 @@ set_frame_menubar (f, first_time, deep_p)
2185 wv = wv->next; 2238 wv = wv->next;
2186 } 2239 }
2187 2240
2188 f->menu_bar_vector = menu_items;
2189 f->menu_bar_items_used = menu_items_used;
2190 discard_menu_items ();
2191 } 2241 }
2192 else 2242 else
2193 { 2243 {