Mercurial > hg > xemacs-beta
comparison src/menubar.c @ 428:3ecd8885ac67 r21-2-22
Import from CVS: tag r21-2-22
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:28:15 +0200 |
parents | |
children | 84b14dcb0985 |
comparison
equal
deleted
inserted
replaced
427:0a0253eac470 | 428:3ecd8885ac67 |
---|---|
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. | |
4 | |
5 This file is part of XEmacs. | |
6 | |
7 XEmacs is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2, or (at your option) any | |
10 later version. | |
11 | |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with XEmacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 /* Synched up with: Not in FSF. */ | |
23 | |
24 /* #### There ain't much here because menubars have not been | |
25 properly abstracted yet. */ | |
26 | |
27 #include <config.h> | |
28 #include "lisp.h" | |
29 | |
30 #include "buffer.h" | |
31 #include "device.h" | |
32 #include "frame.h" | |
33 #include "gui.h" | |
34 #include "menubar.h" | |
35 #include "redisplay.h" | |
36 #include "window.h" | |
37 | |
38 int menubar_show_keybindings; | |
39 Lisp_Object Vmenubar_configuration; | |
40 | |
41 Lisp_Object Qcurrent_menubar; | |
42 | |
43 Lisp_Object Qactivate_menubar_hook, Vactivate_menubar_hook; | |
44 | |
45 Lisp_Object Vmenubar_visible_p; | |
46 | |
47 static Lisp_Object Vcurrent_menubar; /* DO NOT ever reference this. | |
48 Always go through Qcurrent_menubar. | |
49 See below. */ | |
50 | |
51 Lisp_Object Vblank_menubar; | |
52 | |
53 int popup_menu_titles; | |
54 | |
55 Lisp_Object Vmenubar_pointer_glyph; | |
56 | |
57 static int | |
58 menubar_variable_changed (Lisp_Object sym, Lisp_Object *val, | |
59 Lisp_Object in_object, int flags) | |
60 { | |
61 MARK_MENUBAR_CHANGED; | |
62 return 0; | |
63 } | |
64 | |
65 void | |
66 update_frame_menubars (struct frame *f) | |
67 { | |
68 if (f->menubar_changed || f->windows_changed) | |
69 MAYBE_FRAMEMETH (f, update_frame_menubars, (f)); | |
70 | |
71 f->menubar_changed = 0; | |
72 } | |
73 | |
74 void | |
75 free_frame_menubars (struct frame *f) | |
76 { | |
77 /* If we had directly allocated any memory for the menubars instead | |
78 of using all Lisp_Objects this is where we would now free it. */ | |
79 | |
80 MAYBE_FRAMEMETH (f, free_frame_menubars, (f)); | |
81 } | |
82 | |
83 static void | |
84 menubar_visible_p_changed (Lisp_Object specifier, struct window *w, | |
85 Lisp_Object oldval) | |
86 { | |
87 MARK_MENUBAR_CHANGED; | |
88 } | |
89 | |
90 static void | |
91 menubar_visible_p_changed_in_frame (Lisp_Object specifier, struct frame *f, | |
92 Lisp_Object oldval) | |
93 { | |
94 update_frame_menubars (f); | |
95 } | |
96 | |
97 Lisp_Object | |
98 current_frame_menubar (CONST struct frame* f) | |
99 { | |
100 struct window *w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f)); | |
101 return symbol_value_in_buffer (Qcurrent_menubar, w->buffer); | |
102 } | |
103 | |
104 Lisp_Object | |
105 menu_parse_submenu_keywords (Lisp_Object desc, Lisp_Object gui_item) | |
106 { | |
107 struct Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item); | |
108 | |
109 /* Menu descriptor should be a list */ | |
110 CHECK_CONS (desc); | |
111 | |
112 /* First element may be menu name, although can be omitted. | |
113 Let's think that if stuff begins with anything than a keyword | |
114 or a list (submenu), this is a menu name, expected to be a string */ | |
115 if (!KEYWORDP (XCAR (desc)) && !CONSP (XCAR (desc))) | |
116 { | |
117 CHECK_STRING (XCAR (desc)); | |
118 pgui_item->name = XCAR (desc); | |
119 desc = XCDR (desc); | |
120 if (!NILP (desc)) | |
121 CHECK_CONS (desc); | |
122 } | |
123 | |
124 /* Walk along all key-value pairs */ | |
125 while (!NILP(desc) && KEYWORDP (XCAR (desc))) | |
126 { | |
127 Lisp_Object key, val; | |
128 key = XCAR (desc); | |
129 desc = XCDR (desc); | |
130 CHECK_CONS (desc); | |
131 val = XCAR (desc); | |
132 desc = XCDR (desc); | |
133 if (!NILP (desc)) | |
134 CHECK_CONS (desc); | |
135 gui_item_add_keyval_pair (gui_item, key, val, ERROR_ME); | |
136 } | |
137 | |
138 /* Return the rest - supposed to be a list of items */ | |
139 return desc; | |
140 } | |
141 | |
142 DEFUN ("menu-find-real-submenu", Fmenu_find_real_submenu, 2, 2, 0, /* | |
143 Find a submenu descriptor within DESC by following PATH. | |
144 This function finds a submenu descriptor, either from the description | |
145 DESC or generated by a filter within DESC. The function regards :config | |
146 and :included keywords in the DESC, and expands submenus along the | |
147 PATH using :filter functions. Return value is a descriptor for the | |
148 submenu, NOT expanded and NOT checked against :config and :included. | |
149 Also, individual menu items are not looked for, only submenus. | |
150 | |
151 See also 'find-menu-item'. | |
152 */ | |
153 (desc, path)) | |
154 { | |
155 Lisp_Object path_entry, submenu_desc, submenu; | |
156 struct gcpro gcpro1; | |
157 Lisp_Object gui_item = allocate_gui_item (); | |
158 struct Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item); | |
159 | |
160 GCPRO1 (gui_item); | |
161 | |
162 EXTERNAL_LIST_LOOP (path_entry, path) | |
163 { | |
164 /* Verify that DESC describes a menu, not single item */ | |
165 if (!CONSP (desc)) | |
166 RETURN_UNGCPRO (Qnil); | |
167 | |
168 /* Parse this menu */ | |
169 desc = menu_parse_submenu_keywords (desc, gui_item); | |
170 | |
171 /* Check that this (sub)menu is active */ | |
172 if (!gui_item_active_p (gui_item)) | |
173 RETURN_UNGCPRO (Qnil); | |
174 | |
175 /* Apply :filter */ | |
176 if (!NILP (pgui_item->filter)) | |
177 desc = call1 (pgui_item->filter, desc); | |
178 | |
179 /* Find the next menu on the path inside this one */ | |
180 EXTERNAL_LIST_LOOP (submenu_desc, desc) | |
181 { | |
182 submenu = XCAR (submenu_desc); | |
183 if (CONSP (submenu) | |
184 && STRINGP (XCAR (submenu)) | |
185 && !NILP (Fstring_equal (XCAR (submenu), XCAR (path_entry)))) | |
186 { | |
187 desc = submenu; | |
188 goto descend; | |
189 } | |
190 } | |
191 /* Submenu not found */ | |
192 RETURN_UNGCPRO (Qnil); | |
193 | |
194 descend: | |
195 /* Prepare for the next iteration */ | |
196 gui_item_init (gui_item); | |
197 } | |
198 | |
199 /* We have successfully descended down the end of the path */ | |
200 UNGCPRO; | |
201 return desc; | |
202 } | |
203 | |
204 DEFUN ("popup-menu", Fpopup_menu, 1, 2, 0, /* | |
205 Pop up the given menu. | |
206 A menu description is a list of menu items, strings, and submenus. | |
207 | |
208 The first element of a menu must be a string, which is the name of the menu. | |
209 This is the string that will be displayed in the parent menu, if any. For | |
210 toplevel menus, it is ignored. This string is not displayed in the menu | |
211 itself. | |
212 | |
213 If an element of a menu is a string, then that string will be presented in | |
214 the menu as unselectable text. | |
215 | |
216 If an element of a menu is a string consisting solely of hyphens, then that | |
217 item will be presented as a solid horizontal line. | |
218 | |
219 If an element of a menu is a list, it is treated as a submenu. The name of | |
220 that submenu (the first element in the list) will be used as the name of the | |
221 item representing this menu on the parent. | |
222 | |
223 Otherwise, the element must be a vector, which describes a menu item. | |
224 A menu item can have any of the following forms: | |
225 | |
226 [ "name" callback <active-p> ] | |
227 [ "name" callback <active-p> <suffix> ] | |
228 [ "name" callback :<keyword> <value> :<keyword> <value> ... ] | |
229 | |
230 The name is the string to display on the menu; it is filtered through the | |
231 resource database, so it is possible for resources to override what string | |
232 is actually displayed. | |
233 | |
234 If the `callback' of a menu item is a symbol, then it must name a command. | |
235 It will be invoked with `call-interactively'. If it is a list, then it is | |
236 evaluated with `eval'. | |
237 | |
238 The possible keywords are this: | |
239 | |
240 :active <form> Same as <active-p> in the first two forms: the | |
241 expression is evaluated just before the menu is | |
242 displayed, and the menu will be selectable only if | |
243 the result is non-nil. | |
244 | |
245 :suffix <form> Same as <suffix> in the second form: the expression | |
246 is evaluated just before the menu is displayed and | |
247 resulting string is appended to the displayed name, | |
248 providing a convenient way of adding the name of a | |
249 command's ``argument'' to the menu, like | |
250 ``Kill Buffer NAME''. | |
251 | |
252 :keys "string" Normally, the keyboard equivalents of commands in | |
253 menus are displayed when the `callback' is a symbol. | |
254 This can be used to specify keys for more complex menu | |
255 items. It is passed through `substitute-command-keys' | |
256 first. | |
257 | |
258 :style <style> Specifies what kind of object this menu item is: | |
259 | |
260 nil A normal menu item. | |
261 toggle A toggle button. | |
262 radio A radio button. | |
263 | |
264 The only difference between toggle and radio buttons is | |
265 how they are displayed. But for consistency, a toggle | |
266 button should be used when there is one option whose | |
267 value can be turned on or off, and radio buttons should | |
268 be used when there is a set of mutually exclusive | |
269 options. When using a group of radio buttons, you | |
270 should arrange for no more than one to be marked as | |
271 selected at a time. | |
272 | |
273 :selected <form> Meaningful only when STYLE is `toggle' or `radio'. | |
274 This specifies whether the button will be in the | |
275 selected or unselected state. | |
276 | |
277 For example: | |
278 | |
279 [ "Save As..." write-file t ] | |
280 [ "Revert Buffer" revert-buffer (buffer-modified-p) ] | |
281 [ "Read Only" toggle-read-only :style toggle :selected buffer-read-only ] | |
282 | |
283 See menubar.el for many more examples. | |
284 */ | |
285 (menu_desc, event)) | |
286 { | |
287 struct frame *f = decode_frame(Qnil); | |
288 MAYBE_FRAMEMETH (f, popup_menu, (menu_desc,event)); | |
289 return Qnil; | |
290 } | |
291 | |
292 DEFUN ("normalize-menu-item-name", Fnormalize_menu_item_name, 1, 2, 0, /* | |
293 Convert a menu item name string into normal form, and return the new string. | |
294 Menu item names should be converted to normal form before being compared. | |
295 */ | |
296 (name, buffer)) | |
297 { | |
298 struct buffer *buf = decode_buffer (buffer, 0); | |
299 struct Lisp_String *n; | |
300 Charcount end; | |
301 int i; | |
302 Bufbyte *name_data; | |
303 Bufbyte *string_result; | |
304 Bufbyte *string_result_ptr; | |
305 Emchar elt; | |
306 int expecting_underscore = 0; | |
307 | |
308 CHECK_STRING (name); | |
309 | |
310 n = XSTRING (name); | |
311 end = string_char_length (n); | |
312 name_data = string_data (n); | |
313 | |
314 string_result = (Bufbyte *) alloca (end * MAX_EMCHAR_LEN); | |
315 string_result_ptr = string_result; | |
316 for (i = 0; i < end; i++) | |
317 { | |
318 elt = charptr_emchar (name_data); | |
319 elt = DOWNCASE (buf, elt); | |
320 if (expecting_underscore) | |
321 { | |
322 expecting_underscore = 0; | |
323 switch (elt) | |
324 { | |
325 case '%': | |
326 /* Allow `%%' to mean `%'. */ | |
327 string_result_ptr += set_charptr_emchar (string_result_ptr, '%'); | |
328 break; | |
329 case '_': | |
330 break; | |
331 default: | |
332 string_result_ptr += set_charptr_emchar (string_result_ptr, '%'); | |
333 string_result_ptr += set_charptr_emchar (string_result_ptr, elt); | |
334 } | |
335 } | |
336 else if (elt == '%') | |
337 expecting_underscore = 1; | |
338 else | |
339 string_result_ptr += set_charptr_emchar (string_result_ptr, elt); | |
340 INC_CHARPTR (name_data); | |
341 } | |
342 | |
343 return make_string (string_result, string_result_ptr - string_result); | |
344 } | |
345 | |
346 void | |
347 syms_of_menubar (void) | |
348 { | |
349 defsymbol (&Qcurrent_menubar, "current-menubar"); | |
350 DEFSUBR (Fpopup_menu); | |
351 DEFSUBR (Fnormalize_menu_item_name); | |
352 DEFSUBR (Fmenu_find_real_submenu); | |
353 } | |
354 | |
355 void | |
356 vars_of_menubar (void) | |
357 { | |
358 { | |
359 /* put in Vblank_menubar a menubar value which has no visible | |
360 * items. This is a bit tricky due to various quirks. We | |
361 * could use '(["" nil nil]), but this is apparently equivalent | |
362 * to '(nil), and a new frame created with this menubar will | |
363 * get a vertically-squished menubar. If we use " " as the | |
364 * button title instead of "", we get an etched button border. | |
365 * So we use | |
366 * '(("No active menubar" ["" nil nil])) | |
367 * which creates a menu whose title is "No active menubar", | |
368 * and this works fine. | |
369 */ | |
370 | |
371 Lisp_Object menu_item[3]; | |
372 static CONST char *blank_msg = "No active menubar"; | |
373 | |
374 menu_item[0] = build_string (""); | |
375 menu_item[1] = Qnil; | |
376 menu_item[2] = Qnil; | |
377 Vblank_menubar = Fcons (Fcons (build_string (blank_msg), | |
378 Fcons (Fvector (3, &menu_item[0]), | |
379 Qnil)), | |
380 Qnil); | |
381 staticpro (&Vblank_menubar); | |
382 } | |
383 | |
384 DEFVAR_BOOL ("popup-menu-titles", &popup_menu_titles /* | |
385 If true, popup menus will have title bars at the top. | |
386 */ ); | |
387 popup_menu_titles = 1; | |
388 | |
389 /* #### Replace current menubar with a specifier. */ | |
390 | |
391 /* All C code must access the menubar via Qcurrent_menubar | |
392 because it can be buffer-local. Note that Vcurrent_menubar | |
393 doesn't need to exist at all, except for the magic function. */ | |
394 | |
395 DEFVAR_LISP_MAGIC ("current-menubar", &Vcurrent_menubar /* | |
396 The current menubar. This may be buffer-local. | |
397 | |
398 When the menubar is changed, the function `set-menubar-dirty-flag' has to | |
399 be called for the menubar to be updated on the frame. See `set-menubar' | |
400 and `set-buffer-menubar'. | |
401 | |
402 A menubar is a list of menus and menu-items. | |
403 A menu is a list of menu items, keyword-value pairs, strings, and submenus. | |
404 | |
405 The first element of a menu must be a string, which is the name of the menu. | |
406 This is the string that will be displayed in the parent menu, if any. For | |
407 toplevel menus, it is ignored. This string is not displayed in the menu | |
408 itself. | |
409 | |
410 Immediately following the name string of the menu, any of three | |
411 optional keyword-value pairs is permitted. | |
412 | |
413 If an element of a menu (or menubar) is a string, then that string will be | |
414 presented as unselectable text. | |
415 | |
416 If an element of a menu is a string consisting solely of hyphens, then that | |
417 item will be presented as a solid horizontal line. | |
418 | |
419 If an element of a menu is a list, it is treated as a submenu. The name of | |
420 that submenu (the first element in the list) will be used as the name of the | |
421 item representing this menu on the parent. | |
422 | |
423 If an element of a menubar is `nil', then it is used to represent the | |
424 division between the set of menubar-items which are flushleft and those | |
425 which are flushright. | |
426 | |
427 Otherwise, the element must be a vector, which describes a menu item. | |
428 A menu item can have any of the following forms: | |
429 | |
430 [ "name" callback <active-p> ] | |
431 [ "name" callback <active-p> <suffix> ] | |
432 [ "name" callback :<keyword> <value> :<keyword> <value> ... ] | |
433 | |
434 The name is the string to display on the menu; it is filtered through the | |
435 resource database, so it is possible for resources to override what string | |
436 is actually displayed. | |
437 | |
438 If the `callback' of a menu item is a symbol, then it must name a command. | |
439 It will be invoked with `call-interactively'. If it is a list, then it is | |
440 evaluated with `eval'. | |
441 | |
442 The possible keywords are this: | |
443 | |
444 :active <form> Same as <active-p> in the first two forms: the | |
445 expression is evaluated just before the menu is | |
446 displayed, and the menu will be selectable only if | |
447 the result is non-nil. | |
448 | |
449 :suffix <form> Same as <suffix> in the second form: the expression | |
450 is evaluated just before the menu is displayed and | |
451 resulting string is appended to the displayed name, | |
452 providing a convenient way of adding the name of a | |
453 command's ``argument'' to the menu, like | |
454 ``Kill Buffer NAME''. | |
455 | |
456 :keys "string" Normally, the keyboard equivalents of commands in | |
457 menus are displayed when the `callback' is a symbol. | |
458 This can be used to specify keys for more complex menu | |
459 items. It is passed through `substitute-command-keys' | |
460 first. | |
461 | |
462 :style <style> Specifies what kind of object this menu item is: | |
463 | |
464 nil A normal menu item. | |
465 toggle A toggle button. | |
466 radio A radio button. | |
467 button A menubar button. | |
468 | |
469 The only difference between toggle and radio buttons is | |
470 how they are displayed. But for consistency, a toggle | |
471 button should be used when there is one option whose | |
472 value can be turned on or off, and radio buttons should | |
473 be used when there is a set of mutually exclusive | |
474 options. When using a group of radio buttons, you | |
475 should arrange for no more than one to be marked as | |
476 selected at a time. | |
477 | |
478 :selected <form> Meaningful only when STYLE is `toggle', `radio' or | |
479 `button'. This specifies whether the button will be in | |
480 the selected or unselected state. | |
481 | |
482 :included <form> This can be used to control the visibility of a menu or | |
483 menu item. The form is evaluated and the menu or menu | |
484 item is only displayed if the result is non-nil. | |
485 | |
486 :config <symbol> This is an efficient shorthand for | |
487 :included (memq symbol menubar-configuration) | |
488 See the variable `menubar-configuration'. | |
489 | |
490 :filter <function> A menu filter can only be used in a menu item list. | |
491 (i.e.: not in a menu item itself). It is used to | |
492 sensitize or incrementally create a submenu only when | |
493 it is selected by the user and not every time the | |
494 menubar is activated. The filter function is passed | |
495 the list of menu items in the submenu and must return a | |
496 list of menu items to be used for the menu. It is | |
497 called only when the menu is about to be displayed, so | |
498 other menus may already be displayed. Vile and | |
499 terrible things will happen if a menu filter function | |
500 changes the current buffer, window, or frame. It | |
501 also should not raise, lower, or iconify any frames. | |
502 Basically, the filter function should have no | |
503 side-effects. | |
504 | |
505 :key-sequence keys Used in FSF Emacs as an hint to an equivalent keybinding. | |
506 Ignored by XEnacs for easymenu.el compatability. | |
507 | |
508 :label <form> (unimplemented!) Like :suffix, but replaces label | |
509 completely. | |
510 (might be added in 21.2). | |
511 | |
512 For example: | |
513 | |
514 ("File" | |
515 :filter file-menu-filter ; file-menu-filter is a function that takes | |
516 ; one argument (a list of menu items) and | |
517 ; returns a list of menu items | |
518 [ "Save As..." write-file t ] | |
519 [ "Revert Buffer" revert-buffer (buffer-modified-p) ] | |
520 [ "Read Only" toggle-read-only :style toggle | |
521 :selected buffer-read-only ] | |
522 ) | |
523 | |
524 See x-menubar.el for many more examples. | |
525 | |
526 After the menubar is clicked upon, but before any menus are popped up, | |
527 the functions on the `activate-menubar-hook' are invoked to make top-level | |
528 changes to the menus and menubar. Note, however, that the use of menu | |
529 filters (using the :filter keyword) is usually a more efficient way to | |
530 dynamically alter or sensitize menus. | |
531 */, menubar_variable_changed); | |
532 | |
533 Vcurrent_menubar = Qnil; | |
534 | |
535 DEFVAR_LISP ("activate-menubar-hook", &Vactivate_menubar_hook /* | |
536 Function or functions called before a menubar menu is pulled down. | |
537 These functions are called with no arguments, and should interrogate and | |
538 modify the value of `current-menubar' as desired. | |
539 | |
540 The functions on this hook are invoked after the mouse goes down, but before | |
541 the menu is mapped, and may be used to activate, deactivate, add, or delete | |
542 items from the menus. However, it is probably the case that using a :filter | |
543 keyword in a submenu would be a more efficient way of updating menus. See | |
544 the documentation of `current-menubar'. | |
545 | |
546 These functions may return the symbol `t' to assert that they have made | |
547 no changes to the menubar. If any other value is returned, the menubar is | |
548 recomputed. If `t' is returned but the menubar has been changed, then the | |
549 changes may not show up right away. Returning `nil' when the menubar has | |
550 not changed is not so bad; more computation will be done, but redisplay of | |
551 the menubar will still be performed optimally. | |
552 */ ); | |
553 Vactivate_menubar_hook = Qnil; | |
554 defsymbol (&Qactivate_menubar_hook, "activate-menubar-hook"); | |
555 | |
556 DEFVAR_BOOL ("menubar-show-keybindings", &menubar_show_keybindings /* | |
557 If true, the menubar will display keyboard equivalents. | |
558 If false, only the command names will be displayed. | |
559 */ ); | |
560 menubar_show_keybindings = 1; | |
561 | |
562 DEFVAR_LISP_MAGIC ("menubar-configuration", &Vmenubar_configuration /* | |
563 A list of symbols, against which the value of the :config tag for each | |
564 menubar item will be compared. If a menubar item has a :config tag, then | |
565 it is omitted from the menubar if that tag is not a member of the | |
566 `menubar-configuration' list. | |
567 */ , menubar_variable_changed); | |
568 Vmenubar_configuration = Qnil; | |
569 | |
570 DEFVAR_LISP ("menubar-pointer-glyph", &Vmenubar_pointer_glyph /* | |
571 *The shape of the mouse-pointer when over the menubar. | |
572 This is a glyph; use `set-glyph-image' to change it. | |
573 If unspecified in a particular domain, the window-system-provided | |
574 default pointer is used. | |
575 */ ); | |
576 | |
577 Fprovide (intern ("menubar")); | |
578 } | |
579 | |
580 void | |
581 specifier_vars_of_menubar (void) | |
582 { | |
583 DEFVAR_SPECIFIER ("menubar-visible-p", &Vmenubar_visible_p /* | |
584 *Whether the menubar is visible. | |
585 This is a specifier; use `set-specifier' to change it. | |
586 */ ); | |
587 Vmenubar_visible_p = Fmake_specifier (Qboolean); | |
588 | |
589 set_specifier_fallback (Vmenubar_visible_p, list1 (Fcons (Qnil, Qt))); | |
590 set_specifier_caching (Vmenubar_visible_p, | |
591 slot_offset (struct window, | |
592 menubar_visible_p), | |
593 menubar_visible_p_changed, | |
594 slot_offset (struct frame, | |
595 menubar_visible_p), | |
596 menubar_visible_p_changed_in_frame); | |
597 } | |
598 | |
599 void | |
600 complex_vars_of_menubar (void) | |
601 { | |
602 Vmenubar_pointer_glyph = Fmake_glyph_internal (Qpointer); | |
603 } |