XEmacs 21.2.27 "Hera".
[chise/xemacs-chise.git.1] / src / menubar.c
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                          offsetof (struct window, menubar_visible_p),
592                          menubar_visible_p_changed,
593                          offsetof (struct frame, menubar_visible_p),
594                          menubar_visible_p_changed_in_frame);
595 }
596
597 void
598 complex_vars_of_menubar (void)
599 {
600   Vmenubar_pointer_glyph = Fmake_glyph_internal (Qpointer);
601 }