Mercurial > hg > xemacs-beta
annotate src/menubar.c @ 5602:c9e5612f5424
Support the MP library on recent FreeBSD, have it pass relevant tests.
src/ChangeLog addition:
2011-11-26 Aidan Kehoe <kehoea@parhasard.net>
* number-mp.c (bignum_to_string):
Don't overwrite the accumulator we've just set up for this
function.
* number-mp.c (BIGNUM_TO_TYPE):
mp_itom() doesn't necessarily do what this code used to think with
negative numbers, it can treat them as unsigned ints. Subtract
numbers from bignum_zero instead of multiplying them by -1 to
convert them to their negative equivalents.
* number-mp.c (bignum_to_int):
* number-mp.c (bignum_to_uint):
* number-mp.c (bignum_to_long):
* number-mp.c (bignum_to_ulong):
* number-mp.c (bignum_to_double):
Use the changed BIGNUM_TO_TYPE() in these functions.
* number-mp.c (bignum_ceil):
* number-mp.c (bignum_floor):
In these functions, be more careful about rounding to positive and
negative infinity, respectively. Don't use the sign of QUOTIENT
when working out out whether to add or subtract one, rather use
the sign QUOTIENT would have if arbitrary-precision division were
done.
* number-mp.h:
* number-mp.h (MP_GCD):
Wrap #include <mp.h> in BEGIN_C_DECLS/END_C_DECLS.
* number.c (Fbigfloat_get_precision):
* number.c (Fbigfloat_set_precision):
Don't attempt to call XBIGFLOAT_GET_PREC if this build doesn't
support big floats.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sat, 26 Nov 2011 17:59:14 +0000 |
parents | 56144c8593a8 |
children | 68f8d295be49 |
rev | line source |
---|---|
428 | 1 /* Implements an elisp-programmable menubar. |
2 Copyright (C) 1993, 1994 Free Software Foundation, Inc. | |
3 Copyright (C) 1995 Tinker Systems and INS Engineering Corp. | |
3025 | 4 Copyright (C) 2001, 2002, 2003, 2005 Ben Wing. |
428 | 5 |
6 This file is part of XEmacs. | |
7 | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4952
diff
changeset
|
8 XEmacs is free software: you can redistribute it and/or modify it |
428 | 9 under the terms of the GNU General Public License as published by the |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4952
diff
changeset
|
10 Free Software Foundation, either version 3 of the License, or (at your |
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4952
diff
changeset
|
11 option) any later version. |
428 | 12 |
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
4952
diff
changeset
|
19 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */ |
428 | 20 |
21 /* Synched up with: Not in FSF. */ | |
22 | |
442 | 23 /* Authorship: |
24 | |
25 Created by Ben Wing as part of device-abstraction work for 19.12. | |
26 Menu filters and many other keywords added by Stig for 19.12. | |
27 Menu accelerators c. 1997? by ??. Moved here from event-stream.c. | |
28 Much other work post-1996 by ??. | |
29 */ | |
428 | 30 |
31 #include <config.h> | |
32 #include "lisp.h" | |
33 | |
34 #include "buffer.h" | |
872 | 35 #include "device-impl.h" |
36 #include "frame-impl.h" | |
428 | 37 #include "gui.h" |
442 | 38 #include "keymap.h" |
428 | 39 #include "menubar.h" |
40 #include "redisplay.h" | |
800 | 41 #include "specifier.h" |
872 | 42 #include "window-impl.h" |
428 | 43 |
44 int menubar_show_keybindings; | |
45 Lisp_Object Vmenubar_configuration; | |
46 | |
47 Lisp_Object Qcurrent_menubar; | |
48 | |
49 Lisp_Object Qactivate_menubar_hook, Vactivate_menubar_hook; | |
50 | |
51 Lisp_Object Vmenubar_visible_p; | |
52 | |
53 static Lisp_Object Vcurrent_menubar; /* DO NOT ever reference this. | |
54 Always go through Qcurrent_menubar. | |
55 See below. */ | |
56 | |
57 Lisp_Object Vblank_menubar; | |
58 | |
59 int popup_menu_titles; | |
1279 | 60 int in_menu_callback; |
428 | 61 |
62 Lisp_Object Vmenubar_pointer_glyph; | |
63 | |
442 | 64 /* prefix key(s) that must match in order to activate menu. |
65 This is ugly. fix me. | |
66 */ | |
67 Lisp_Object Vmenu_accelerator_prefix; | |
68 | |
69 /* list of modifier keys to match accelerator for top level menus */ | |
70 Lisp_Object Vmenu_accelerator_modifiers; | |
71 | |
72 /* whether menu accelerators are enabled */ | |
73 Lisp_Object Vmenu_accelerator_enabled; | |
74 | |
75 /* keymap for auxiliary menu accelerator functions */ | |
76 Lisp_Object Vmenu_accelerator_map; | |
77 | |
78 Lisp_Object Qmenu_force; | |
79 Lisp_Object Qmenu_fallback; | |
80 Lisp_Object Qmenu_quit; | |
81 Lisp_Object Qmenu_up; | |
82 Lisp_Object Qmenu_down; | |
83 Lisp_Object Qmenu_left; | |
84 Lisp_Object Qmenu_right; | |
85 Lisp_Object Qmenu_select; | |
86 Lisp_Object Qmenu_escape; | |
87 | |
428 | 88 static int |
2286 | 89 menubar_variable_changed (Lisp_Object UNUSED (sym), Lisp_Object *UNUSED (val), |
90 Lisp_Object UNUSED (in_object), int UNUSED (flags)) | |
428 | 91 { |
92 MARK_MENUBAR_CHANGED; | |
93 return 0; | |
94 } | |
95 | |
96 void | |
97 update_frame_menubars (struct frame *f) | |
98 { | |
99 if (f->menubar_changed || f->windows_changed) | |
100 MAYBE_FRAMEMETH (f, update_frame_menubars, (f)); | |
101 | |
102 f->menubar_changed = 0; | |
103 } | |
104 | |
105 void | |
106 free_frame_menubars (struct frame *f) | |
107 { | |
108 /* If we had directly allocated any memory for the menubars instead | |
109 of using all Lisp_Objects this is where we would now free it. */ | |
110 | |
111 MAYBE_FRAMEMETH (f, free_frame_menubars, (f)); | |
112 } | |
113 | |
114 static void | |
2286 | 115 menubar_visible_p_changed (Lisp_Object UNUSED (specifier), |
116 struct window *UNUSED (w), | |
117 Lisp_Object UNUSED (oldval)) | |
428 | 118 { |
119 MARK_MENUBAR_CHANGED; | |
120 } | |
121 | |
122 static void | |
2286 | 123 menubar_visible_p_changed_in_frame (Lisp_Object UNUSED (specifier), |
124 struct frame *f, | |
125 Lisp_Object UNUSED (oldval)) | |
428 | 126 { |
127 update_frame_menubars (f); | |
128 } | |
129 | |
130 Lisp_Object | |
442 | 131 current_frame_menubar (const struct frame* f) |
428 | 132 { |
133 struct window *w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f)); | |
134 return symbol_value_in_buffer (Qcurrent_menubar, w->buffer); | |
135 } | |
136 | |
137 Lisp_Object | |
138 menu_parse_submenu_keywords (Lisp_Object desc, Lisp_Object gui_item) | |
139 { | |
442 | 140 Lisp_Gui_Item *pgui_item = XGUI_ITEM (gui_item); |
428 | 141 |
142 /* Menu descriptor should be a list */ | |
143 CHECK_CONS (desc); | |
144 | |
145 /* First element may be menu name, although can be omitted. | |
146 Let's think that if stuff begins with anything than a keyword | |
147 or a list (submenu), this is a menu name, expected to be a string */ | |
148 if (!KEYWORDP (XCAR (desc)) && !CONSP (XCAR (desc))) | |
149 { | |
150 CHECK_STRING (XCAR (desc)); | |
151 pgui_item->name = XCAR (desc); | |
152 desc = XCDR (desc); | |
153 if (!NILP (desc)) | |
154 CHECK_CONS (desc); | |
155 } | |
156 | |
157 /* Walk along all key-value pairs */ | |
158 while (!NILP(desc) && KEYWORDP (XCAR (desc))) | |
159 { | |
160 Lisp_Object key, val; | |
161 key = XCAR (desc); | |
162 desc = XCDR (desc); | |
163 CHECK_CONS (desc); | |
164 val = XCAR (desc); | |
165 desc = XCDR (desc); | |
166 if (!NILP (desc)) | |
167 CHECK_CONS (desc); | |
168 gui_item_add_keyval_pair (gui_item, key, val, ERROR_ME); | |
169 } | |
170 | |
171 /* Return the rest - supposed to be a list of items */ | |
172 return desc; | |
173 } | |
174 | |
175 DEFUN ("menu-find-real-submenu", Fmenu_find_real_submenu, 2, 2, 0, /* | |
176 Find a submenu descriptor within DESC by following PATH. | |
177 This function finds a submenu descriptor, either from the description | |
178 DESC or generated by a filter within DESC. The function regards :config | |
179 and :included keywords in the DESC, and expands submenus along the | |
180 PATH using :filter functions. Return value is a descriptor for the | |
181 submenu, NOT expanded and NOT checked against :config and :included. | |
182 Also, individual menu items are not looked for, only submenus. | |
183 | |
184 See also 'find-menu-item'. | |
185 */ | |
186 (desc, path)) | |
187 { | |
442 | 188 struct gcpro gcpro1, gcpro2; |
428 | 189 Lisp_Object gui_item = allocate_gui_item (); |
440 | 190 Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item); |
428 | 191 |
442 | 192 GCPRO2 (gui_item, desc); |
428 | 193 |
2367 | 194 { |
195 EXTERNAL_LIST_LOOP_2 (elt, path) | |
196 { | |
197 /* Verify that DESC describes a menu, not single item */ | |
198 if (!CONSP (desc)) | |
199 RETURN_UNGCPRO (Qnil); | |
200 | |
201 /* Parse this menu */ | |
202 desc = menu_parse_submenu_keywords (desc, gui_item); | |
203 | |
204 /* Check that this (sub)menu is active */ | |
205 if (!gui_item_active_p (gui_item)) | |
206 RETURN_UNGCPRO (Qnil); | |
428 | 207 |
2367 | 208 /* Apply :filter */ |
209 if (!NILP (pgui_item->filter)) | |
210 desc = call1 (pgui_item->filter, desc); | |
428 | 211 |
2367 | 212 /* Find the next menu on the path inside this one */ |
213 { | |
214 EXTERNAL_LIST_LOOP_2 (submenu, desc) | |
215 { | |
216 if (CONSP (submenu) | |
217 && STRINGP (XCAR (submenu)) | |
218 && !NILP (Fstring_equal (XCAR (submenu), elt))) | |
219 { | |
220 desc = submenu; | |
221 goto descend; | |
222 } | |
223 } | |
224 } | |
225 /* Submenu not found */ | |
428 | 226 RETURN_UNGCPRO (Qnil); |
227 | |
2367 | 228 descend: |
229 /* Prepare for the next iteration */ | |
230 gui_item_init (gui_item); | |
231 } | |
232 } | |
428 | 233 |
234 /* We have successfully descended down the end of the path */ | |
235 UNGCPRO; | |
236 return desc; | |
237 } | |
238 | |
239 DEFUN ("popup-menu", Fpopup_menu, 1, 2, 0, /* | |
444 | 240 Pop up the menu described by MENU-DESCRIPTION. |
428 | 241 A menu description is a list of menu items, strings, and submenus. |
242 | |
243 The first element of a menu must be a string, which is the name of the menu. | |
244 This is the string that will be displayed in the parent menu, if any. For | |
245 toplevel menus, it is ignored. This string is not displayed in the menu | |
246 itself. | |
247 | |
248 If an element of a menu is a string, then that string will be presented in | |
249 the menu as unselectable text. | |
250 | |
251 If an element of a menu is a string consisting solely of hyphens, then that | |
252 item will be presented as a solid horizontal line. | |
253 | |
254 If an element of a menu is a list, it is treated as a submenu. The name of | |
255 that submenu (the first element in the list) will be used as the name of the | |
256 item representing this menu on the parent. | |
257 | |
258 Otherwise, the element must be a vector, which describes a menu item. | |
259 A menu item can have any of the following forms: | |
260 | |
261 [ "name" callback <active-p> ] | |
262 [ "name" callback <active-p> <suffix> ] | |
263 [ "name" callback :<keyword> <value> :<keyword> <value> ... ] | |
264 | |
265 The name is the string to display on the menu; it is filtered through the | |
266 resource database, so it is possible for resources to override what string | |
267 is actually displayed. | |
268 | |
269 If the `callback' of a menu item is a symbol, then it must name a command. | |
270 It will be invoked with `call-interactively'. If it is a list, then it is | |
271 evaluated with `eval'. | |
272 | |
273 The possible keywords are this: | |
274 | |
275 :active <form> Same as <active-p> in the first two forms: the | |
276 expression is evaluated just before the menu is | |
277 displayed, and the menu will be selectable only if | |
278 the result is non-nil. | |
279 | |
280 :suffix <form> Same as <suffix> in the second form: the expression | |
281 is evaluated just before the menu is displayed and | |
282 resulting string is appended to the displayed name, | |
283 providing a convenient way of adding the name of a | |
284 command's ``argument'' to the menu, like | |
285 ``Kill Buffer NAME''. | |
286 | |
287 :keys "string" Normally, the keyboard equivalents of commands in | |
288 menus are displayed when the `callback' is a symbol. | |
289 This can be used to specify keys for more complex menu | |
290 items. It is passed through `substitute-command-keys' | |
291 first. | |
292 | |
293 :style <style> Specifies what kind of object this menu item is: | |
294 | |
295 nil A normal menu item. | |
296 toggle A toggle button. | |
297 radio A radio button. | |
298 | |
299 The only difference between toggle and radio buttons is | |
300 how they are displayed. But for consistency, a toggle | |
301 button should be used when there is one option whose | |
302 value can be turned on or off, and radio buttons should | |
303 be used when there is a set of mutually exclusive | |
304 options. When using a group of radio buttons, you | |
305 should arrange for no more than one to be marked as | |
306 selected at a time. | |
307 | |
308 :selected <form> Meaningful only when STYLE is `toggle' or `radio'. | |
309 This specifies whether the button will be in the | |
310 selected or unselected state. | |
311 | |
312 For example: | |
313 | |
314 [ "Save As..." write-file t ] | |
315 [ "Revert Buffer" revert-buffer (buffer-modified-p) ] | |
316 [ "Read Only" toggle-read-only :style toggle :selected buffer-read-only ] | |
317 | |
318 See menubar.el for many more examples. | |
319 */ | |
444 | 320 (menu_description, event)) |
428 | 321 { |
444 | 322 struct frame *f = decode_frame (Qnil); |
323 MAYBE_FRAMEMETH (f, popup_menu, (menu_description, event)); | |
428 | 324 return Qnil; |
325 } | |
326 | |
2545 | 327 DEFUN ("compare-menu-text", Fcompare_menu_text, 2, 2, 0, /* |
328 Compare the text of two menu items, ignoring accelerator specs and case. | |
329 Also treat %% as a single %. Return < 0 if STRING1 is less than STRING2, | |
330 0 if equal, > 0 if STRING1 is greater than STRING2. | |
331 */ | |
332 (string1, string2)) | |
333 { | |
334 Ibyte *p; | |
335 Ibyte *q; | |
336 | |
337 CHECK_STRING (string1); | |
338 CHECK_STRING (string2); | |
339 | |
340 p = XSTRING_DATA (string1); | |
341 q = XSTRING_DATA (string2); | |
342 | |
343 for (;;) | |
344 { | |
345 Ichar val; | |
346 if (*p == '%' && *(p + 1) == '%') | |
347 p++; | |
348 else if (*p == '%' && *(p + 1) == '_') | |
349 p += 2; | |
350 if (*q == '%' && *(q + 1) == '%') | |
351 q++; | |
352 else if (*q == '%' && *(q + 1) == '_') | |
353 q += 2; | |
354 if (!*p || !*q) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
355 return make_fixnum (*p - *q); |
2545 | 356 val = DOWNCASE (0, itext_ichar (p)) - DOWNCASE (0, itext_ichar (q)); |
357 if (val) | |
5581
56144c8593a8
Mechanically change INT to FIXNUM in our sources.
Aidan Kehoe <kehoea@parhasard.net>
parents:
5402
diff
changeset
|
358 return make_fixnum (val); |
2545 | 359 INC_IBYTEPTR (p); |
360 INC_IBYTEPTR (q); | |
361 } | |
362 } | |
363 | |
364 DEFUN ("normalize-menu-text", Fnormalize_menu_text, 1, 1, 0, /* | |
428 | 365 Convert a menu item name string into normal form, and return the new string. |
366 Menu item names should be converted to normal form before being compared. | |
442 | 367 This removes %_'s (accelerator indications) and converts %% to %. |
2545 | 368 The returned string may be the same string as the original. |
428 | 369 */ |
2545 | 370 (name)) |
428 | 371 { |
372 Charcount end; | |
373 int i; | |
867 | 374 Ibyte *name_data; |
375 Ibyte *string_result; | |
376 Ibyte *string_result_ptr; | |
377 Ichar elt; | |
428 | 378 int expecting_underscore = 0; |
379 | |
380 CHECK_STRING (name); | |
381 | |
826 | 382 end = string_char_length (name); |
793 | 383 name_data = XSTRING_DATA (name); |
428 | 384 |
2367 | 385 string_result = alloca_ibytes (end * MAX_ICHAR_LEN); |
428 | 386 string_result_ptr = string_result; |
387 for (i = 0; i < end; i++) | |
388 { | |
867 | 389 elt = itext_ichar (name_data); |
428 | 390 if (expecting_underscore) |
391 { | |
392 expecting_underscore = 0; | |
393 switch (elt) | |
394 { | |
395 case '%': | |
396 /* Allow `%%' to mean `%'. */ | |
867 | 397 string_result_ptr += set_itext_ichar (string_result_ptr, '%'); |
428 | 398 break; |
399 case '_': | |
400 break; | |
401 default: | |
867 | 402 string_result_ptr += set_itext_ichar (string_result_ptr, '%'); |
403 string_result_ptr += set_itext_ichar (string_result_ptr, elt); | |
428 | 404 } |
405 } | |
406 else if (elt == '%') | |
407 expecting_underscore = 1; | |
408 else | |
867 | 409 string_result_ptr += set_itext_ichar (string_result_ptr, elt); |
410 INC_IBYTEPTR (name_data); | |
428 | 411 } |
412 | |
442 | 413 if (string_result_ptr - string_result == XSTRING_LENGTH (name) |
414 && !memcmp (string_result, XSTRING_DATA (name), XSTRING_LENGTH (name))) | |
415 return name; | |
416 | |
428 | 417 return make_string (string_result, string_result_ptr - string_result); |
418 } | |
419 | |
420 void | |
421 syms_of_menubar (void) | |
422 { | |
563 | 423 DEFSYMBOL (Qcurrent_menubar); |
442 | 424 |
563 | 425 DEFSYMBOL (Qmenu_force); |
426 DEFSYMBOL (Qmenu_fallback); | |
442 | 427 |
563 | 428 DEFSYMBOL (Qmenu_quit); |
429 DEFSYMBOL (Qmenu_up); | |
430 DEFSYMBOL (Qmenu_down); | |
431 DEFSYMBOL (Qmenu_left); | |
432 DEFSYMBOL (Qmenu_right); | |
433 DEFSYMBOL (Qmenu_select); | |
434 DEFSYMBOL (Qmenu_escape); | |
442 | 435 |
428 | 436 DEFSUBR (Fpopup_menu); |
2545 | 437 DEFSUBR (Fcompare_menu_text); |
438 DEFSUBR (Fnormalize_menu_text); | |
428 | 439 DEFSUBR (Fmenu_find_real_submenu); |
440 } | |
441 | |
442 void | |
443 vars_of_menubar (void) | |
444 { | |
440 | 445 /* put in Vblank_menubar a menubar value which has no visible |
446 * items. This is a bit tricky due to various quirks. We | |
447 * could use '(["" nil nil]), but this is apparently equivalent | |
448 * to '(nil), and a new frame created with this menubar will | |
449 * get a vertically-squished menubar. If we use " " as the | |
450 * button title instead of "", we get an etched button border. | |
451 * So we use | |
452 * '(("No active menubar" ["" nil nil])) | |
453 * which creates a menu whose title is "No active menubar", | |
454 * and this works fine. | |
455 */ | |
428 | 456 |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
457 Vblank_menubar = list1 (list2 (build_defer_string ("No active menubar"), |
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
3025
diff
changeset
|
458 vector3 (build_ascstring (""), Qnil, Qnil))); |
440 | 459 staticpro (&Vblank_menubar); |
428 | 460 |
461 DEFVAR_BOOL ("popup-menu-titles", &popup_menu_titles /* | |
462 If true, popup menus will have title bars at the top. | |
463 */ ); | |
464 popup_menu_titles = 1; | |
465 | |
466 /* #### Replace current menubar with a specifier. */ | |
467 | |
468 /* All C code must access the menubar via Qcurrent_menubar | |
469 because it can be buffer-local. Note that Vcurrent_menubar | |
470 doesn't need to exist at all, except for the magic function. */ | |
471 | |
472 DEFVAR_LISP_MAGIC ("current-menubar", &Vcurrent_menubar /* | |
473 The current menubar. This may be buffer-local. | |
474 | |
475 When the menubar is changed, the function `set-menubar-dirty-flag' has to | |
476 be called for the menubar to be updated on the frame. See `set-menubar' | |
477 and `set-buffer-menubar'. | |
478 | |
479 A menubar is a list of menus and menu-items. | |
480 A menu is a list of menu items, keyword-value pairs, strings, and submenus. | |
481 | |
482 The first element of a menu must be a string, which is the name of the menu. | |
483 This is the string that will be displayed in the parent menu, if any. For | |
484 toplevel menus, it is ignored. This string is not displayed in the menu | |
485 itself. | |
486 | |
442 | 487 Menu accelerators can be indicated in the string by putting the |
488 sequence "%_" before the character corresponding to the key that will | |
489 invoke the menu or menu item. Uppercase and lowercase accelerators | |
490 are equivalent. The sequence "%%" is also special, and is translated | |
491 into a single %. | |
492 | |
493 If no menu accelerator is present in the string, XEmacs will act as if | |
494 the first character has been tagged as an accelerator. | |
495 | |
496 Immediately following the name string of the menu, various optional | |
497 keyword-value pairs are permitted: currently, :filter, :active, :included, | |
498 and :config. (See below.) | |
428 | 499 |
500 If an element of a menu (or menubar) is a string, then that string will be | |
501 presented as unselectable text. | |
502 | |
503 If an element of a menu is a string consisting solely of hyphens, then that | |
504 item will be presented as a solid horizontal line. | |
505 | |
442 | 506 If an element of a menu is a string beginning with "--:", it will be |
507 presented as a line whose appearance is controlled by the rest of the | |
508 text in the string. The allowed line specs are system-dependent, and | |
509 currently work only under X Windows (with Lucid and Motif menubars); | |
510 otherwise, a solid horizontal line is presented, as if the string were | |
511 all hyphens. | |
512 | |
513 The possibilities are: | |
514 | |
515 "--:singleLine" | |
516 "--:doubleLine" | |
517 "--:singleDashedLine" | |
518 "--:doubleDashedLine" | |
519 "--:noLine" | |
520 "--:shadowEtchedIn" | |
521 "--:shadowEtchedOut" | |
522 "--:shadowEtchedInDash" | |
523 "--:shadowEtchedOutDash" | |
524 "--:shadowDoubleEtchedIn" (Lucid menubars only) | |
525 "--:shadowDoubleEtchedOut" (Lucid menubars only) | |
526 "--:shadowDoubleEtchedInDash" (Lucid menubars only) | |
527 "--:shadowDoubleEtchedOutDash" (Lucid menubars only) | |
528 | |
428 | 529 If an element of a menu is a list, it is treated as a submenu. The name of |
530 that submenu (the first element in the list) will be used as the name of the | |
531 item representing this menu on the parent. | |
532 | |
533 If an element of a menubar is `nil', then it is used to represent the | |
534 division between the set of menubar-items which are flushleft and those | |
535 which are flushright. | |
536 | |
537 Otherwise, the element must be a vector, which describes a menu item. | |
442 | 538 A menu item is of the following form: |
539 | |
540 [ "name" callback :<keyword> <value> :<keyword> <value> ... ] | |
541 | |
542 The following forms are also accepted for compatibility, but deprecated: | |
428 | 543 |
544 [ "name" callback <active-p> ] | |
545 [ "name" callback <active-p> <suffix> ] | |
546 | |
547 The name is the string to display on the menu; it is filtered through the | |
548 resource database, so it is possible for resources to override what string | |
442 | 549 is actually displayed. Menu accelerator indicators (the sequence `%_') are |
550 also processed; see above. If the name is not a string, it will be | |
551 evaluated with `eval', and the result should be a string. | |
428 | 552 |
553 If the `callback' of a menu item is a symbol, then it must name a command. | |
554 It will be invoked with `call-interactively'. If it is a list, then it is | |
555 evaluated with `eval'. | |
556 | |
442 | 557 In the deprecated forms, <active-p> is equivalent to using the :active |
558 keyword, and <suffix> is equivalent to using the :suffix keyword. | |
428 | 559 |
442 | 560 The possible keywords are: |
561 | |
562 :active <form> The expression is evaluated just before the menu is | |
428 | 563 displayed, and the menu will be selectable only if |
564 the result is non-nil. | |
565 | |
442 | 566 :suffix <form> The expression is evaluated just before the menu is |
567 displayed and the resulting string is appended to | |
568 the displayed name, providing a convenient way of | |
569 adding the name of a command's ``argument'' to the | |
570 menu, like ``Kill Buffer NAME''. | |
428 | 571 |
572 :keys "string" Normally, the keyboard equivalents of commands in | |
573 menus are displayed when the `callback' is a symbol. | |
574 This can be used to specify keys for more complex menu | |
575 items. It is passed through `substitute-command-keys' | |
576 first. | |
577 | |
578 :style <style> Specifies what kind of object this menu item is: | |
579 | |
580 nil A normal menu item. | |
581 toggle A toggle button. | |
582 radio A radio button. | |
583 button A menubar button. | |
584 | |
585 The only difference between toggle and radio buttons is | |
586 how they are displayed. But for consistency, a toggle | |
587 button should be used when there is one option whose | |
588 value can be turned on or off, and radio buttons should | |
589 be used when there is a set of mutually exclusive | |
590 options. When using a group of radio buttons, you | |
591 should arrange for no more than one to be marked as | |
592 selected at a time. | |
593 | |
594 :selected <form> Meaningful only when STYLE is `toggle', `radio' or | |
595 `button'. This specifies whether the button will be in | |
596 the selected or unselected state. | |
597 | |
598 :included <form> This can be used to control the visibility of a menu or | |
599 menu item. The form is evaluated and the menu or menu | |
600 item is only displayed if the result is non-nil. | |
601 | |
602 :config <symbol> This is an efficient shorthand for | |
603 :included (memq symbol menubar-configuration) | |
604 See the variable `menubar-configuration'. | |
605 | |
442 | 606 :filter <function> A menu filter can only be used at the beginning of a |
607 submenu description (i.e. not in a menu item itself). | |
608 (Remember that most of the keywords can take evaluated | |
609 expressions as well as constants.) The filter is used to | |
610 incrementally create a submenu only when it is selected | |
611 by the user and not every time the menubar is activated. | |
612 The filter function is passed the list of menu items in | |
613 the submenu and must return the modified list to be | |
614 actually used. The filter MUST NOT destructively modify | |
615 the list of menu items passed to it. It is called only | |
616 when the menu is about to be displayed, so other menus | |
617 may already be displayed. Vile and terrible things will | |
618 happen if a menu filter function changes the current | |
619 buffer, window, or frame. It also should not raise, | |
620 lower, or iconify any frames. Basically, the filter | |
621 function should have no side-effects. | |
428 | 622 |
623 :key-sequence keys Used in FSF Emacs as an hint to an equivalent keybinding. | |
442 | 624 Ignored by XEmacs for easymenu.el compatibility. |
625 (XEmacs computes this information automatically.) | |
428 | 626 |
627 For example: | |
628 | |
442 | 629 ("%_File" |
428 | 630 :filter file-menu-filter ; file-menu-filter is a function that takes |
631 ; one argument (a list of menu items) and | |
632 ; returns a list of menu items | |
442 | 633 [ "Save %_As..." write-file t ] |
634 [ "%_Revert Buffer" revert-buffer (buffer-modified-p) ] | |
635 [ "R%_ead Only" toggle-read-only :style toggle | |
428 | 636 :selected buffer-read-only ] |
637 ) | |
638 | |
442 | 639 See menubar-items.el for many more examples. |
428 | 640 |
641 After the menubar is clicked upon, but before any menus are popped up, | |
642 the functions on the `activate-menubar-hook' are invoked to make top-level | |
643 changes to the menus and menubar. Note, however, that the use of menu | |
644 filters (using the :filter keyword) is usually a more efficient way to | |
442 | 645 dynamically alter or sensitize menus. */, menubar_variable_changed); |
428 | 646 |
647 Vcurrent_menubar = Qnil; | |
648 | |
649 DEFVAR_LISP ("activate-menubar-hook", &Vactivate_menubar_hook /* | |
650 Function or functions called before a menubar menu is pulled down. | |
651 These functions are called with no arguments, and should interrogate and | |
652 modify the value of `current-menubar' as desired. | |
653 | |
654 The functions on this hook are invoked after the mouse goes down, but before | |
655 the menu is mapped, and may be used to activate, deactivate, add, or delete | |
656 items from the menus. However, it is probably the case that using a :filter | |
657 keyword in a submenu would be a more efficient way of updating menus. See | |
658 the documentation of `current-menubar'. | |
659 | |
660 These functions may return the symbol `t' to assert that they have made | |
661 no changes to the menubar. If any other value is returned, the menubar is | |
662 recomputed. If `t' is returned but the menubar has been changed, then the | |
663 changes may not show up right away. Returning `nil' when the menubar has | |
664 not changed is not so bad; more computation will be done, but redisplay of | |
665 the menubar will still be performed optimally. | |
666 */ ); | |
667 Vactivate_menubar_hook = Qnil; | |
563 | 668 DEFSYMBOL (Qactivate_menubar_hook); |
428 | 669 |
670 DEFVAR_BOOL ("menubar-show-keybindings", &menubar_show_keybindings /* | |
671 If true, the menubar will display keyboard equivalents. | |
672 If false, only the command names will be displayed. | |
673 */ ); | |
674 menubar_show_keybindings = 1; | |
675 | |
676 DEFVAR_LISP_MAGIC ("menubar-configuration", &Vmenubar_configuration /* | |
677 A list of symbols, against which the value of the :config tag for each | |
678 menubar item will be compared. If a menubar item has a :config tag, then | |
679 it is omitted from the menubar if that tag is not a member of the | |
680 `menubar-configuration' list. | |
681 */ , menubar_variable_changed); | |
682 Vmenubar_configuration = Qnil; | |
683 | |
684 DEFVAR_LISP ("menubar-pointer-glyph", &Vmenubar_pointer_glyph /* | |
685 *The shape of the mouse-pointer when over the menubar. | |
686 This is a glyph; use `set-glyph-image' to change it. | |
687 If unspecified in a particular domain, the window-system-provided | |
688 default pointer is used. | |
689 */ ); | |
690 | |
442 | 691 DEFVAR_LISP ("menu-accelerator-prefix", &Vmenu_accelerator_prefix /* |
692 Prefix key(s) that must be typed before menu accelerators will be activated. | |
693 Set this to a value acceptable by define-key. | |
694 | |
695 NOTE: This currently only has any effect under X Windows. | |
696 */ ); | |
697 Vmenu_accelerator_prefix = Qnil; | |
698 | |
699 DEFVAR_LISP ("menu-accelerator-modifiers", &Vmenu_accelerator_modifiers /* | |
700 Modifier keys which must be pressed to get to the top level menu accelerators. | |
701 This is a list of modifier key symbols. All modifier keys must be held down | |
702 while a valid menu accelerator key is pressed in order for the top level | |
703 menu to become active. | |
704 | |
705 NOTE: This currently only has any effect under X Windows. | |
706 | |
707 See also menu-accelerator-enabled and menu-accelerator-prefix. | |
708 */ ); | |
709 Vmenu_accelerator_modifiers = list1 (Qmeta); | |
710 | |
711 DEFVAR_LISP ("menu-accelerator-enabled", &Vmenu_accelerator_enabled /* | |
712 Whether menu accelerator keys can cause the menubar to become active. | |
3025 | 713 If `menu-force' or `menu-fallback', then menu accelerator keys can |
442 | 714 be used to activate the top level menu. Once the menubar becomes active, the |
715 accelerator keys can be used regardless of the value of this variable. | |
716 | |
717 menu-force is used to indicate that the menu accelerator key takes | |
718 precedence over bindings in the current keymap(s). menu-fallback means | |
719 that bindings in the current keymap take precedence over menu accelerator keys. | |
720 Thus a top level menu with an accelerator of "T" would be activated on a | |
721 keypress of Meta-t if menu-accelerator-enabled is menu-force. | |
722 However, if menu-accelerator-enabled is menu-fallback, then | |
723 Meta-t will not activate the menubar and will instead run the function | |
724 transpose-words, to which it is normally bound. | |
725 | |
726 See also menu-accelerator-modifiers and menu-accelerator-prefix. | |
727 */ ); | |
728 Vmenu_accelerator_enabled = Qnil; | |
729 | |
730 DEFVAR_LISP ("menu-accelerator-map", &Vmenu_accelerator_map /* | |
731 Keymap for use when the menubar is active. | |
732 The actions menu-quit, menu-up, menu-down, menu-left, menu-right, | |
733 menu-select and menu-escape can be mapped to keys in this map. | |
734 NOTE: This currently only has any effect under X Windows. | |
735 | |
736 menu-quit Immediately deactivate the menubar and any open submenus without | |
737 selecting an item. | |
738 menu-up Move the menu cursor up one row in the current menu. If the | |
739 move extends past the top of the menu, wrap around to the bottom. | |
740 menu-down Move the menu cursor down one row in the current menu. If the | |
741 move extends past the bottom of the menu, wrap around to the top. | |
742 If executed while the cursor is in the top level menu, move down | |
743 into the selected menu. | |
744 menu-left Move the cursor from a submenu into the parent menu. If executed | |
745 while the cursor is in the top level menu, move the cursor to the | |
746 left. If the move extends past the left edge of the menu, wrap | |
747 around to the right edge. | |
748 menu-right Move the cursor into a submenu. If the cursor is located in the | |
749 top level menu or is not currently on a submenu heading, then move | |
750 the cursor to the next top level menu entry. If the move extends | |
751 past the right edge of the menu, wrap around to the left edge. | |
752 menu-select Activate the item under the cursor. If the cursor is located on | |
753 a submenu heading, then move the cursor into the submenu. | |
754 menu-escape Pop up to the next level of menus. Moves from a submenu into its | |
755 parent menu. From the top level menu, this deactivates the | |
756 menubar. | |
757 | |
758 This keymap can also contain normal key-command bindings, in which case the | |
759 menubar is deactivated and the corresponding command is executed. | |
760 | |
761 The action bindings used by the menu accelerator code are designed to mimic | |
762 the actions of menu traversal keys in a commonly used PC operating system. | |
763 */ ); | |
764 | |
428 | 765 Fprovide (intern ("menubar")); |
464 | 766 Fprovide (intern ("menu-accelerator-support")); |
428 | 767 } |
768 | |
769 void | |
770 specifier_vars_of_menubar (void) | |
771 { | |
772 DEFVAR_SPECIFIER ("menubar-visible-p", &Vmenubar_visible_p /* | |
773 *Whether the menubar is visible. | |
774 This is a specifier; use `set-specifier' to change it. | |
775 */ ); | |
776 Vmenubar_visible_p = Fmake_specifier (Qboolean); | |
777 | |
778 set_specifier_fallback (Vmenubar_visible_p, list1 (Fcons (Qnil, Qt))); | |
779 set_specifier_caching (Vmenubar_visible_p, | |
438 | 780 offsetof (struct window, menubar_visible_p), |
428 | 781 menubar_visible_p_changed, |
438 | 782 offsetof (struct frame, menubar_visible_p), |
444 | 783 menubar_visible_p_changed_in_frame, 0); |
428 | 784 } |
785 | |
786 void | |
787 complex_vars_of_menubar (void) | |
788 { | |
789 Vmenubar_pointer_glyph = Fmake_glyph_internal (Qpointer); | |
442 | 790 |
791 Vmenu_accelerator_map = Fmake_keymap (Qnil); | |
428 | 792 } |