Mercurial > hg > xemacs-beta
comparison src/menubar.c @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 859a2309aef8 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
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 "device.h" | |
31 #include "frame.h" | |
32 #include "menubar.h" | |
33 #include "redisplay.h" | |
34 #include "window.h" | |
35 | |
36 int menubar_show_keybindings; | |
37 Lisp_Object Vmenubar_configuration; | |
38 | |
39 Lisp_Object Qcurrent_menubar; | |
40 | |
41 Lisp_Object Qactivate_menubar_hook, Vactivate_menubar_hook; | |
42 | |
43 Lisp_Object Vmenubar_visible_p; | |
44 | |
45 static Lisp_Object Vcurrent_menubar; /* DO NOT ever reference this. | |
46 Always go through Qcurrent_menubar. | |
47 See below. */ | |
48 Lisp_Object Vblank_menubar; | |
49 | |
50 int popup_menu_titles; | |
51 | |
52 Lisp_Object Vmenubar_pointer_glyph; | |
53 | |
54 static int | |
55 menubar_variable_changed (Lisp_Object sym, Lisp_Object *val, | |
56 Lisp_Object in_object, int flags) | |
57 { | |
58 MARK_MENUBAR_CHANGED; | |
59 return 0; | |
60 } | |
61 | |
62 void | |
63 update_frame_menubars (struct frame *f) | |
64 { | |
65 if (f->menubar_changed || f->windows_changed) | |
66 MAYBE_FRAMEMETH (f, update_frame_menubars, (f)); | |
67 | |
68 f->menubar_changed = 0; | |
69 } | |
70 | |
71 void | |
72 free_frame_menubars (struct frame *f) | |
73 { | |
74 /* If we had directly allocated any memory for the menubars instead | |
75 of using all Lisp_Objects this is where we would now free it. */ | |
76 | |
77 MAYBE_FRAMEMETH (f, free_frame_menubars, (f)); | |
78 } | |
79 | |
80 static void | |
81 menubar_visible_p_changed (Lisp_Object specifier, struct window *w, | |
82 Lisp_Object oldval) | |
83 { | |
84 MARK_MENUBAR_CHANGED; | |
85 } | |
86 | |
87 static void | |
88 menubar_visible_p_changed_in_frame (Lisp_Object specifier, struct frame *f, | |
89 Lisp_Object oldval) | |
90 { | |
91 update_frame_menubars (f); | |
92 } | |
93 | |
94 DEFUN ("popup-menu", Fpopup_menu, Spopup_menu, 1, 2, 0 /* | |
95 Pop up the given menu. | |
96 A menu description is a list of menu items, strings, and submenus. | |
97 | |
98 The first element of a menu must be a string, which is the name of the menu. | |
99 This is the string that will be displayed in the parent menu, if any. For | |
100 toplevel menus, it is ignored. This string is not displayed in the menu | |
101 itself. | |
102 | |
103 If an element of a menu is a string, then that string will be presented in | |
104 the menu as unselectable text. | |
105 | |
106 If an element of a menu is a string consisting solely of hyphens, then that | |
107 item will be presented as a solid horizontal line. | |
108 | |
109 If an element of a menu is a list, it is treated as a submenu. The name of | |
110 that submenu (the first element in the list) will be used as the name of the | |
111 item representing this menu on the parent. | |
112 | |
113 Otherwise, the element must be a vector, which describes a menu item. | |
114 A menu item can have any of the following forms: | |
115 | |
116 [ \"name\" callback <active-p> ] | |
117 [ \"name\" callback <active-p> \"suffix\" ] | |
118 [ \"name\" callback :<keyword> <value> :<keyword> <value> ... ] | |
119 | |
120 The name is the string to display on the menu; it is filtered through the | |
121 resource database, so it is possible for resources to override what string | |
122 is actually displayed. | |
123 | |
124 If the `callback' of a menu item is a symbol, then it must name a command. | |
125 It will be invoked with `call-interactively'. If it is a list, then it is | |
126 evaluated with `eval'. | |
127 | |
128 The possible keywords are this: | |
129 | |
130 :active <form> Same as <active-p> in the first two forms: the | |
131 expression is evaluated just before the menu is | |
132 displayed, and the menu will be selectable only if | |
133 the result is non-nil. | |
134 | |
135 :suffix \"string\" Same as \"suffix\" in the second form: the suffix is | |
136 appended to the displayed name, providing a convenient | |
137 way of adding the name of a command's ``argument'' to | |
138 the menu, like ``Kill Buffer NAME''. | |
139 | |
140 :keys \"string\" Normally, the keyboard equivalents of commands in | |
141 menus are displayed when the `callback' is a symbol. | |
142 This can be used to specify keys for more complex menu | |
143 items. It is passed through `substitute-command-keys' | |
144 first. | |
145 | |
146 :style <style> Specifies what kind of object this menu item is: | |
147 | |
148 nil A normal menu item. | |
149 toggle A toggle button. | |
150 radio A radio button. | |
151 | |
152 The only difference between toggle and radio buttons is | |
153 how they are displayed. But for consistency, a toggle | |
154 button should be used when there is one option whose | |
155 value can be turned on or off, and radio buttons should | |
156 be used when there is a set of mutually exclusive | |
157 options. When using a group of radio buttons, you | |
158 should arrange for no more than one to be marked as | |
159 selected at a time. | |
160 | |
161 :selected <form> Meaningful only when STYLE is `toggle' or `radio'. | |
162 This specifies whether the button will be in the | |
163 selected or unselected state. | |
164 | |
165 For example: | |
166 | |
167 [ \"Save As...\" write-file t ] | |
168 [ \"Revert Buffer\" revert-buffer (buffer-modified-p) ] | |
169 [ \"Read Only\" toggle-read-only :style toggle :selected buffer-read-only ] | |
170 | |
171 See menubar.el for many more examples. | |
172 */ ) | |
173 (menu_desc, event) | |
174 Lisp_Object menu_desc, event; | |
175 { | |
176 struct frame *f = decode_frame(Qnil); | |
177 MAYBE_FRAMEMETH (f, popup_menu, (menu_desc,event)); | |
178 return Qnil; | |
179 } | |
180 | |
181 void | |
182 syms_of_menubar (void) | |
183 { | |
184 defsymbol (&Qcurrent_menubar, "current-menubar"); | |
185 defsubr (&Spopup_menu); | |
186 } | |
187 | |
188 void | |
189 vars_of_menubar (void) | |
190 { | |
191 { | |
192 /* put in Vblank_menubar a menubar value which has no visible | |
193 * items. This is a bit tricky due to various quirks. We | |
194 * could use '(["" nil nil]), but this is apparently equivalent | |
195 * to '(nil), and a new frame created with this menubar will | |
196 * get a vertically-squished menubar. If we use " " as the | |
197 * button title instead of "", we get an etched button border. | |
198 * So we use | |
199 * '(("No active menubar" ["" nil nil])) | |
200 * which creates a menu whose title is "No active menubar", | |
201 * and this works fine. | |
202 */ | |
203 | |
204 Lisp_Object menu_item[3]; | |
205 static CONST char *blank_msg = "No active menubar"; | |
206 | |
207 menu_item[0] = build_string (""); | |
208 menu_item[1] = Qnil; | |
209 menu_item[2] = Qnil; | |
210 Vblank_menubar = Fcons (Fcons (build_string (blank_msg), | |
211 Fcons (Fvector (3, &menu_item[0]), | |
212 Qnil)), | |
213 Qnil); | |
214 Vblank_menubar = Fpurecopy (Vblank_menubar); | |
215 staticpro (&Vblank_menubar); | |
216 } | |
217 | |
218 DEFVAR_BOOL ("popup-menu-titles", &popup_menu_titles /* | |
219 If true, popup menus will have title bars at the top. | |
220 */ ); | |
221 popup_menu_titles = 1; | |
222 | |
223 /* #### Replace current menubar with a specifier. */ | |
224 | |
225 /* All C code must access the menubar via Qcurrent_menubar | |
226 because it can be buffer-local. Note that Vcurrent_menubar | |
227 doesn't need to exist at all, except for the magic function. */ | |
228 | |
229 DEFVAR_LISP_MAGIC ("current-menubar", &Vcurrent_menubar /* | |
230 The current menubar. This may be buffer-local. | |
231 | |
232 When the menubar is changed, the function `set-menubar-dirty-flag' has to | |
233 be called for the menubar to be updated on the frame. See `set-menubar' | |
234 and `set-buffer-menubar'. | |
235 | |
236 A menubar is a list of menus and menu-items. | |
237 A menu is a list of menu items, keyword-value pairs, strings, and submenus. | |
238 | |
239 The first element of a menu must be a string, which is the name of the menu. | |
240 This is the string that will be displayed in the parent menu, if any. For | |
241 toplevel menus, it is ignored. This string is not displayed in the menu | |
242 itself. | |
243 | |
244 Immediately following the name string of the menu, any of three | |
245 optional keyword-value pairs is permitted. | |
246 | |
247 If an element of a menu (or menubar) is a string, then that string will be | |
248 presented as unselectable text. | |
249 | |
250 If an element of a menu is a string consisting solely of hyphens, then that | |
251 item will be presented as a solid horizontal line. | |
252 | |
253 If an element of a menu is a list, it is treated as a submenu. The name of | |
254 that submenu (the first element in the list) will be used as the name of the | |
255 item representing this menu on the parent. | |
256 | |
257 If an element of a menubar is `nil', then it is used to represent the | |
258 division between the set of menubar-items which are flushleft and those | |
259 which are flushright. | |
260 | |
261 Otherwise, the element must be a vector, which describes a menu item. | |
262 A menu item can have any of the following forms: | |
263 | |
264 [ \"name\" callback <active-p> ] | |
265 [ \"name\" callback <active-p> \"suffix\" ] | |
266 [ \"name\" callback :<keyword> <value> :<keyword> <value> ... ] | |
267 | |
268 The name is the string to display on the menu; it is filtered through the | |
269 resource database, so it is possible for resources to override what string | |
270 is actually displayed. | |
271 | |
272 If the `callback' of a menu item is a symbol, then it must name a command. | |
273 It will be invoked with `call-interactively'. If it is a list, then it is | |
274 evaluated with `eval'. | |
275 | |
276 The possible keywords are this: | |
277 | |
278 :active <form> Same as <active-p> in the first two forms: the | |
279 expression is evaluated just before the menu is | |
280 displayed, and the menu will be selectable only if | |
281 the result is non-nil. | |
282 | |
283 :suffix \"string\" Same as \"suffix\" in the second form: the suffix is | |
284 appended to the displayed name, providing a convenient | |
285 way of adding the name of a command's ``argument'' to | |
286 the menu, like ``Kill Buffer NAME''. | |
287 | |
288 :keys \"string\" Normally, the keyboard equivalents of commands in | |
289 menus are displayed when the `callback' is a symbol. | |
290 This can be used to specify keys for more complex menu | |
291 items. It is passed through `substitute-command-keys' | |
292 first. | |
293 | |
294 :style <style> Specifies what kind of object this menu item is: | |
295 | |
296 nil A normal menu item. | |
297 toggle A toggle button. | |
298 radio A radio button. | |
299 button A menubar button. | |
300 | |
301 The only difference between toggle and radio buttons is | |
302 how they are displayed. But for consistency, a toggle | |
303 button should be used when there is one option whose | |
304 value can be turned on or off, and radio buttons should | |
305 be used when there is a set of mutually exclusive | |
306 options. When using a group of radio buttons, you | |
307 should arrange for no more than one to be marked as | |
308 selected at a time. | |
309 | |
310 :selected <form> Meaningful only when STYLE is `toggle', `radio' or | |
311 `button'. This specifies whether the button will be in | |
312 the selected or unselected state. | |
313 | |
314 :included <form> This can be used to control the visibility of a menu or | |
315 menu item. The form is evaluated and the menu or menu | |
316 item is only displayed if the result is non-nil. | |
317 | |
318 :config <symbol> This is an efficient shorthand for | |
319 :included (memq symbol menubar-configuration) | |
320 See the variable `menubar-configuration'. | |
321 | |
322 :filter <function> A menu filter can only be used in a menu item list. | |
323 (i.e.: not in a menu item itself). It is used to | |
324 sensitize or incrementally create a submenu only when | |
325 it is selected by the user and not every time the | |
326 menubar is activated. The filter function is passed | |
327 the list of menu items in the submenu and must return a | |
328 list of menu items to be used for the menu. It is | |
329 called only when the menu is about to be displayed, so | |
330 other menus may already be displayed. Vile and | |
331 terrible things will happen if a menu filter function | |
332 changes the current buffer, window, or frame. It | |
333 also should not raise, lower, or iconify any frames. | |
334 Basically, the filter function should have no | |
335 side-effects. | |
336 | |
337 For example: | |
338 | |
339 (\"File\" | |
340 :filter file-menu-filter ; file-menu-filter is a function that takes | |
341 ; one argument (a list of menu items) and | |
342 ; returns a list of menu items | |
343 [ \"Save As...\" write-file t ] | |
344 [ \"Revert Buffer\" revert-buffer (buffer-modified-p) ] | |
345 [ \"Read Only\" toggle-read-only :style toggle | |
346 :selected buffer-read-only ] | |
347 ) | |
348 | |
349 See x-menubar.el for many more examples. | |
350 | |
351 After the menubar is clicked upon, but before any menus are popped up, | |
352 the functions on the `activate-menubar-hook' are invoked to make top-level | |
353 changes to the menus and menubar. Note, however, that the use of menu | |
354 filters (using the :filter keyword) is usually a more efficient way to | |
355 dynamically alter or sensitize menus. | |
356 */, menubar_variable_changed); | |
357 | |
358 Vcurrent_menubar = Qnil; | |
359 | |
360 DEFVAR_LISP ("activate-menubar-hook", &Vactivate_menubar_hook /* | |
361 Function or functions called before a menubar menu is pulled down. | |
362 These functions are called with no arguments, and should interrogate and | |
363 modify the value of `current-menubar' as desired. | |
364 | |
365 The functions on this hook are invoked after the mouse goes down, but before | |
366 the menu is mapped, and may be used to activate, deactivate, add, or delete | |
367 items from the menus. However, it is probably the case that using a :filter | |
368 keyword in a submenu would be a more efficient way of updating menus. See | |
369 the documentation of `current-menubar'. | |
370 | |
371 These functions may return the symbol `t' to assert that they have made | |
372 no changes to the menubar. If any other value is returned, the menubar is | |
373 recomputed. If `t' is returned but the menubar has been changed, then the | |
374 changes may not show up right away. Returning `nil' when the menubar has | |
375 not changed is not so bad; more computation will be done, but redisplay of | |
376 the menubar will still be performed optimally. | |
377 */ ); | |
378 Vactivate_menubar_hook = Qnil; | |
379 defsymbol (&Qactivate_menubar_hook, "activate-menubar-hook"); | |
380 | |
381 DEFVAR_BOOL ("menubar-show-keybindings", &menubar_show_keybindings /* | |
382 If true, the menubar will display keyboard equivalents. | |
383 If false, only the command names will be displayed. | |
384 */ ); | |
385 menubar_show_keybindings = 1; | |
386 | |
387 DEFVAR_LISP_MAGIC ("menubar-configuration", &Vmenubar_configuration /* | |
388 A list of symbols, against which the value of the :config tag for each | |
389 menubar item will be compared. If a menubar item has a :config tag, then | |
390 it is omitted from the menubar if that tag is not a member of the | |
391 `menubar-configuration' list. | |
392 */ , menubar_variable_changed); | |
393 Vmenubar_configuration = Qnil; | |
394 | |
395 DEFVAR_LISP ("menubar-pointer-glyph", &Vmenubar_pointer_glyph /* | |
396 *The shape of the mouse-pointer when over the menubar. | |
397 This is a glyph; use `set-glyph-image' to change it. | |
398 If unspecified in a particular domain, the window-system-provided | |
399 default pointer is used. | |
400 */ ); | |
401 | |
402 Fprovide (intern ("menubar")); | |
403 } | |
404 | |
405 void | |
406 specifier_vars_of_menubar (void) | |
407 { | |
408 DEFVAR_SPECIFIER ("menubar-visible-p", &Vmenubar_visible_p /* | |
409 *Whether the menubar is visible. | |
410 This is a specifier; use `set-specifier' to change it. | |
411 */ ); | |
412 Vmenubar_visible_p = Fmake_specifier (Qboolean); | |
413 | |
414 set_specifier_fallback (Vmenubar_visible_p, list1 (Fcons (Qnil, Qt))); | |
415 set_specifier_caching (Vmenubar_visible_p, | |
416 slot_offset (struct window, | |
417 menubar_visible_p), | |
418 menubar_visible_p_changed, | |
419 slot_offset (struct frame, | |
420 menubar_visible_p), | |
421 menubar_visible_p_changed_in_frame); | |
422 } | |
423 | |
424 void | |
425 complex_vars_of_menubar (void) | |
426 { | |
427 Vmenubar_pointer_glyph = Fmake_glyph_internal (Qpointer); | |
428 } |