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 }