diff options
| author | Karoly Lorentey | 2006-04-19 16:23:46 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2006-04-19 16:23:46 +0000 |
| commit | 447b0165acd09060977e05c843f81c0bee4aa4df (patch) | |
| tree | 70cf2d254760a2cf68a10b67f8a3570c05fff9a5 /src/xmenu.c | |
| parent | 4c57cca724993ab1334cc5c0b35c22b06daee0c3 (diff) | |
| parent | 0fea1d10293b4c6d35c1e55b68cd26e91445213c (diff) | |
| download | emacs-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.c | 66 |
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) | |||
| 266 | static void | 266 | static void |
| 267 | init_menu_items () | 267 | init_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 | |||
| 317 | static Lisp_Object | ||
| 318 | restore_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 | |||
| 335 | static void | ||
| 336 | save_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 | ||
| 315 | static void | 349 | static 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 | { |