1 /* Haiku window system support
2    Copyright (C) 2021 Free Software Foundation, Inc.
3 
4 This file is part of GNU Emacs.
5 
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or (at
9 your option) any later version.
10 
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
18 
19 #include <config.h>
20 
21 #include "lisp.h"
22 #include "frame.h"
23 #include "keyboard.h"
24 #include "menu.h"
25 #include "buffer.h"
26 #include "blockinput.h"
27 
28 #include "haikuterm.h"
29 #include "haiku_support.h"
30 
31 static Lisp_Object *volatile menu_item_selection;
32 
33 int popup_activated_p = 0;
34 
35 struct submenu_stack_cell
36 {
37   void *parent_menu;
38   void *pane;
39 };
40 
41 static void
digest_menu_items(void * first_menu,int start,int menu_items_used,int mbar_p)42 digest_menu_items (void *first_menu, int start, int menu_items_used,
43 		   int mbar_p)
44 {
45   void **menus, **panes;
46   ssize_t menu_len = (menu_items_used + 1 - start) * sizeof *menus;
47   ssize_t pane_len = (menu_items_used + 1 - start) * sizeof *panes;
48 
49   menus = alloca (menu_len);
50   panes = alloca (pane_len);
51 
52   int i = start, menu_depth = 0;
53 
54   memset (menus, 0, menu_len);
55   memset (panes, 0, pane_len);
56 
57   void *menu = first_menu;
58 
59   menus[0] = first_menu;
60 
61   void *window = NULL;
62   void *view = NULL;
63   if (FRAMEP (Vmenu_updating_frame) &&
64       FRAME_LIVE_P (XFRAME (Vmenu_updating_frame)) &&
65       FRAME_HAIKU_P (XFRAME (Vmenu_updating_frame)))
66     {
67       window = FRAME_HAIKU_WINDOW (XFRAME (Vmenu_updating_frame));
68       view = FRAME_HAIKU_VIEW (XFRAME (Vmenu_updating_frame));
69     }
70 
71   if (view)
72     BView_draw_lock (view);
73 
74   while (i < menu_items_used)
75     {
76       if (NILP (AREF (menu_items, i)))
77 	{
78 	  menus[++menu_depth] = menu;
79 	  i++;
80 	}
81       else if (EQ (AREF (menu_items, i), Qlambda))
82 	{
83 	  panes[menu_depth] = NULL;
84 	  menu = panes[--menu_depth] ? panes[menu_depth] : menus[menu_depth];
85 	  i++;
86 	}
87       else if (EQ (AREF (menu_items, i), Qquote))
88 	i += 1;
89       else if (EQ (AREF (menu_items, i), Qt))
90 	{
91 	  Lisp_Object pane_name, prefix;
92 	  const char *pane_string;
93 
94 	  if (menu_items_n_panes == 1)
95 	    {
96 	      i += MENU_ITEMS_PANE_LENGTH;
97 	      continue;
98 	    }
99 
100 	  pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
101 	  prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
102 
103 	  if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
104 	    {
105 	      pane_name = ENCODE_UTF_8 (pane_name);
106 	      ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
107 	    }
108 
109 	  pane_string = (NILP (pane_name)
110 			 ? "" : SSDATA (pane_name));
111 	  if (!NILP (prefix))
112 	    pane_string++;
113 
114 	  if (strcmp (pane_string, ""))
115 	    {
116 	      panes[menu_depth] =
117 		menu = BMenu_new_submenu (menus[menu_depth], pane_string, 1);
118 	    }
119 
120 	  i += MENU_ITEMS_PANE_LENGTH;
121 	}
122       else
123 	{
124 	  Lisp_Object item_name, enable, descrip, def, selected, help;
125 	  item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
126 	  enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
127 	  descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
128 	  def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
129 	  selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
130 	  help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
131 
132 	  if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
133 	    {
134 	      item_name = ENCODE_UTF_8 (item_name);
135 	      ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
136 	    }
137 
138 	  if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
139 	    {
140 	      descrip = ENCODE_UTF_8 (descrip);
141 	      ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
142 	    }
143 
144 	  if (STRINGP (help) && STRING_MULTIBYTE (help))
145 	    {
146 	      help = ENCODE_UTF_8 (help);
147 	      ASET (menu_items, i + MENU_ITEMS_ITEM_HELP, help);
148 	    }
149 
150 	  if (i + MENU_ITEMS_ITEM_LENGTH < menu_items_used &&
151 	      NILP (AREF (menu_items, i + MENU_ITEMS_ITEM_LENGTH)))
152 	    menu = BMenu_new_submenu (menu, SSDATA (item_name), !NILP (enable));
153 	  else if (NILP (def) && menu_separator_name_p (SSDATA (item_name)))
154 	    BMenu_add_separator (menu);
155 	  else if (!mbar_p)
156 	    BMenu_add_item (menu, SSDATA (item_name),
157 			    !NILP (def) ? aref_addr (menu_items, i) : NULL,
158 			    !NILP (enable), !NILP (selected), 0, window,
159 			    !NILP (descrip) ? SSDATA (descrip) : NULL,
160 			    STRINGP (help) ? SSDATA (help) : NULL);
161 	  else
162 	    BMenu_add_item (menu, SSDATA (item_name),
163 			    !NILP (def) ? (void *) (intptr_t) i : NULL,
164 			    !NILP (enable), !NILP (selected), 1, window,
165 			    !NILP (descrip) ? SSDATA (descrip) : NULL,
166 			    STRINGP (help) ? SSDATA (help) : NULL);
167 
168 	  i += MENU_ITEMS_ITEM_LENGTH;
169 	}
170     }
171 
172   if (view)
173     BView_draw_unlock (view);
174 }
175 
176 static Lisp_Object
haiku_dialog_show(struct frame * f,Lisp_Object title,Lisp_Object header,const char ** error_name)177 haiku_dialog_show (struct frame *f, Lisp_Object title,
178 		   Lisp_Object header, const char **error_name)
179 {
180   int i, nb_buttons = 0;
181 
182   *error_name = NULL;
183 
184   if (menu_items_n_panes > 1)
185     {
186       *error_name = "Multiple panes in dialog box";
187       return Qnil;
188     }
189 
190   Lisp_Object pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME);
191   i = MENU_ITEMS_PANE_LENGTH;
192 
193   if (STRING_MULTIBYTE (pane_name))
194     pane_name = ENCODE_UTF_8 (pane_name);
195 
196   block_input ();
197   void *alert = BAlert_new (SSDATA (pane_name), NILP (header) ? HAIKU_INFO_ALERT :
198 			    HAIKU_IDEA_ALERT);
199 
200   Lisp_Object vals[10];
201 
202   while (i < menu_items_used)
203     {
204       Lisp_Object item_name, enable, descrip, value;
205       item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
206       enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
207       descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
208       value = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
209 
210       if (NILP (item_name))
211 	{
212 	  BAlert_delete (alert);
213 	  *error_name = "Submenu in dialog items";
214 	  unblock_input ();
215 	  return Qnil;
216 	}
217 
218       if (EQ (item_name, Qquote))
219 	{
220 	  i++;
221 	}
222 
223       if (nb_buttons >= 9)
224 	{
225 	  BAlert_delete (alert);
226 	  *error_name = "Too many dialog items";
227 	  unblock_input ();
228 	  return Qnil;
229 	}
230 
231       if (STRING_MULTIBYTE (item_name))
232 	item_name = ENCODE_UTF_8 (item_name);
233       if (!NILP (descrip) && STRING_MULTIBYTE (descrip))
234 	descrip = ENCODE_UTF_8 (descrip);
235 
236       void *button = BAlert_add_button (alert, SSDATA (item_name));
237 
238       BButton_set_enabled (button, !NILP (enable));
239       if (!NILP (descrip))
240 	BView_set_tooltip (button, SSDATA (descrip));
241 
242       vals[nb_buttons] = value;
243       ++nb_buttons;
244       i += MENU_ITEMS_ITEM_LENGTH;
245     }
246 
247   int32_t val = BAlert_go (alert);
248   unblock_input ();
249 
250   if (val < 0)
251     quit ();
252   else
253     return vals[val];
254 
255   return Qnil;
256 }
257 
258 Lisp_Object
haiku_popup_dialog(struct frame * f,Lisp_Object header,Lisp_Object contents)259 haiku_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
260 {
261   Lisp_Object title;
262   const char *error_name = NULL;
263   Lisp_Object selection;
264   ptrdiff_t specpdl_count = SPECPDL_INDEX ();
265 
266   check_window_system (f);
267 
268   /* Decode the dialog items from what was specified.  */
269   title = Fcar (contents);
270   CHECK_STRING (title);
271   record_unwind_protect_void (unuse_menu_items);
272 
273   if (NILP (Fcar (Fcdr (contents))))
274     /* No buttons specified, add an "Ok" button so users can pop down
275        the dialog.  Also, the lesstif/motif version crashes if there are
276        no buttons.  */
277     contents = list2 (title, Fcons (build_string ("Ok"), Qt));
278 
279   list_of_panes (list1 (contents));
280 
281   /* Display them in a dialog box.  */
282   block_input ();
283   selection = haiku_dialog_show (f, title, header, &error_name);
284   unblock_input ();
285 
286   unbind_to (specpdl_count, Qnil);
287   discard_menu_items ();
288 
289   if (error_name)
290     error ("%s", error_name);
291   return selection;
292 }
293 
294 Lisp_Object
haiku_menu_show(struct frame * f,int x,int y,int menuflags,Lisp_Object title,const char ** error_name)295 haiku_menu_show (struct frame *f, int x, int y, int menuflags,
296 		 Lisp_Object title, const char **error_name)
297 {
298   int i = 0, submenu_depth = 0;
299   void *view = FRAME_HAIKU_VIEW (f);
300   void *menu;
301 
302   Lisp_Object *subprefix_stack =
303     alloca (menu_items_used * sizeof (Lisp_Object));
304 
305   eassert (FRAME_HAIKU_P (f));
306 
307   *error_name = NULL;
308 
309   if (menu_items_used <= MENU_ITEMS_PANE_LENGTH)
310     {
311       *error_name = "Empty menu";
312       return Qnil;
313     }
314 
315   block_input ();
316   if (STRINGP (title) && STRING_MULTIBYTE (title))
317     title = ENCODE_UTF_8 (title);
318 
319   menu = BPopUpMenu_new (STRINGP (title) ? SSDATA (title) : NULL);
320   if (STRINGP (title))
321     {
322       BMenu_add_title (menu, SSDATA (title));
323       BMenu_add_separator (menu);
324     }
325   digest_menu_items (menu, 0, menu_items_used, 0);
326   BView_convert_to_screen (view, &x, &y);
327   unblock_input ();
328 
329   menu_item_selection = BMenu_run (menu, x, y);
330 
331   FRAME_DISPLAY_INFO (f)->grabbed = 0;
332 
333   if (menu_item_selection)
334     {
335       Lisp_Object prefix, entry;
336 
337       prefix = entry = Qnil;
338       i = 0;
339       while (i < menu_items_used)
340 	{
341 	  if (NILP (AREF (menu_items, i)))
342 	    {
343 	      subprefix_stack[submenu_depth++] = prefix;
344 	      prefix = entry;
345 	      i++;
346 	    }
347 	  else if (EQ (AREF (menu_items, i), Qlambda))
348 	    {
349 	      prefix = subprefix_stack[--submenu_depth];
350 	      i++;
351 	    }
352 	  else if (EQ (AREF (menu_items, i), Qt))
353 	    {
354 	      prefix
355 		= AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
356 	      i += MENU_ITEMS_PANE_LENGTH;
357 	    }
358 	  /* Ignore a nil in the item list.
359 	     It's meaningful only for dialog boxes.  */
360 	  else if (EQ (AREF (menu_items, i), Qquote))
361 	    i += 1;
362 	  else
363 	    {
364 	      entry
365 		= AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
366 	      if (menu_item_selection == aref_addr (menu_items, i))
367 		{
368 		  if (menuflags & MENU_KEYMAPS)
369 		    {
370 		      int j;
371 
372 		      entry = list1 (entry);
373 		      if (!NILP (prefix))
374 			entry = Fcons (prefix, entry);
375 		      for (j = submenu_depth - 1; j >= 0; j--)
376 			if (!NILP (subprefix_stack[j]))
377 			  entry = Fcons (subprefix_stack[j], entry);
378 		    }
379 		  BPopUpMenu_delete (menu);
380 		  return entry;
381 		}
382 	      i += MENU_ITEMS_ITEM_LENGTH;
383 	    }
384 	}
385     }
386   else if (!(menuflags & MENU_FOR_CLICK))
387     {
388       BPopUpMenu_delete (menu);
389       quit ();
390     }
391   BPopUpMenu_delete (menu);
392   return Qnil;
393 }
394 
395 void
free_frame_menubar(struct frame * f)396 free_frame_menubar (struct frame *f)
397 {
398   FRAME_MENU_BAR_LINES (f) = 0;
399   FRAME_MENU_BAR_HEIGHT (f) = 0;
400   FRAME_EXTERNAL_MENU_BAR (f) = 0;
401 
402   block_input ();
403   void *mbar = FRAME_HAIKU_MENU_BAR (f);
404   if (mbar)
405     BMenuBar_delete (mbar);
406   if (FRAME_OUTPUT_DATA (f)->menu_bar_open_p)
407     --popup_activated_p;
408   FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 0;
409   unblock_input ();
410 
411   adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines);
412 }
413 
414 void
initialize_frame_menubar(struct frame * f)415 initialize_frame_menubar (struct frame *f)
416 {
417   /* This function is called before the first chance to redisplay
418      the frame.  It has to be, so the frame will have the right size.  */
419   fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
420   set_frame_menubar (f, true);
421 }
422 
423 void
set_frame_menubar(struct frame * f,bool deep_p)424 set_frame_menubar (struct frame *f, bool deep_p)
425 {
426   void *mbar = FRAME_HAIKU_MENU_BAR (f);
427   void *view = FRAME_HAIKU_VIEW (f);
428 
429   int first_time_p = 0;
430 
431   if (!mbar)
432     {
433       mbar = FRAME_HAIKU_MENU_BAR (f) = BMenuBar_new (view);
434       first_time_p = 1;
435     }
436 
437   Lisp_Object items;
438   struct buffer *prev = current_buffer;
439   Lisp_Object buffer;
440   ptrdiff_t specpdl_count = SPECPDL_INDEX ();
441   int previous_menu_items_used = f->menu_bar_items_used;
442   Lisp_Object *previous_items
443     = alloca (previous_menu_items_used * sizeof *previous_items);
444 
445   XSETFRAME (Vmenu_updating_frame, f);
446 
447   if (!deep_p)
448     {
449       FRAME_OUTPUT_DATA (f)->menu_up_to_date_p = 0;
450       items = FRAME_MENU_BAR_ITEMS (f);
451       Lisp_Object string;
452 
453       block_input ();
454       int count = BMenu_count_items (mbar);
455 
456       int i;
457       for (i = 0; i < ASIZE (items); i += 4)
458 	{
459 	  string = AREF (items, i + 1);
460 
461 	  if (!STRINGP (string))
462 	    break;
463 
464 	  if (STRING_MULTIBYTE (string))
465 	    string = ENCODE_UTF_8 (string);
466 
467 	  if (i / 4 < count)
468 	    {
469 	      void *it = BMenu_item_at (mbar, i / 4);
470 	      BMenu_item_set_label (it, SSDATA (string));
471 	    }
472 	  else
473 	    BMenu_new_menu_bar_submenu (mbar, SSDATA (string));
474 	}
475 
476       if (i / 4 < count)
477 	BMenu_delete_from (mbar, i / 4, count - i / 4 + 1);
478       unblock_input ();
479 
480       f->menu_bar_items_used = 0;
481     }
482   else
483     {
484       /* If we are making a new widget, its contents are empty,
485 	 do always reinitialize them.  */
486       if (first_time_p)
487 	previous_menu_items_used = 0;
488       buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
489       specbind (Qinhibit_quit, Qt);
490       /* Don't let the debugger step into this code
491 	 because it is not reentrant.  */
492       specbind (Qdebug_on_next_call, Qnil);
493 
494       record_unwind_save_match_data ();
495       if (NILP (Voverriding_local_map_menu_flag))
496 	{
497 	  specbind (Qoverriding_terminal_local_map, Qnil);
498 	  specbind (Qoverriding_local_map, Qnil);
499 	}
500 
501       set_buffer_internal_1 (XBUFFER (buffer));
502 
503       /* Run the Lucid hook.  */
504       safe_run_hooks (Qactivate_menubar_hook);
505 
506       /* If it has changed current-menubar from previous value,
507 	 really recompute the menubar from the value.  */
508       if (! NILP (Vlucid_menu_bar_dirty_flag))
509 	call0 (Qrecompute_lucid_menubar);
510       safe_run_hooks (Qmenu_bar_update_hook);
511       fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
512 
513       items = FRAME_MENU_BAR_ITEMS (f);
514 
515       /* Save the frame's previous menu bar contents data.  */
516       if (previous_menu_items_used)
517 	memcpy (previous_items, xvector_contents (f->menu_bar_vector),
518 		previous_menu_items_used * word_size);
519 
520       /* Fill in menu_items with the current menu bar contents.
521 	 This can evaluate Lisp code.  */
522       save_menu_items ();
523       menu_items = f->menu_bar_vector;
524       menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
525       init_menu_items ();
526       int i;
527       int count = BMenu_count_items (mbar);
528       int subitems = ASIZE (items) / 4;
529 
530       int *submenu_start, *submenu_end,	*submenu_n_panes;
531       Lisp_Object *submenu_names;
532 
533       submenu_start = alloca ((subitems + 1) * sizeof *submenu_start);
534       submenu_end = alloca (subitems * sizeof *submenu_end);
535       submenu_n_panes = alloca (subitems * sizeof *submenu_n_panes);
536       submenu_names = alloca (subitems * sizeof (Lisp_Object));
537 
538       for (i = 0; i < subitems; ++i)
539 	{
540 	  Lisp_Object key, string, maps;
541 
542 	  key = AREF (items, i * 4);
543 	  string = AREF (items, i * 4 + 1);
544 	  maps = AREF (items, i * 4 + 2);
545 
546 	  if (NILP (string))
547 	    break;
548 
549 	  if (STRINGP (string) && STRING_MULTIBYTE (string))
550 	    string = ENCODE_UTF_8 (string);
551 
552 	  submenu_start[i] = menu_items_used;
553 	  menu_items_n_panes = 0;
554 	  parse_single_submenu (key, string, maps);
555 	  submenu_n_panes[i] = menu_items_n_panes;
556 	  submenu_end[i] = menu_items_used;
557 	  submenu_names[i] = string;
558 	}
559       finish_menu_items ();
560       submenu_start[i] = -1;
561 
562       block_input ();
563       for (i = 0; submenu_start[i] >= 0; ++i)
564 	{
565 	  void *mn = NULL;
566 	  if (i < count)
567 	    mn = BMenu_item_get_menu (BMenu_item_at (mbar, i));
568 	  if (mn)
569 	    BMenu_delete_all (mn);
570 	  else
571 	    mn = BMenu_new_menu_bar_submenu (mbar, SSDATA (submenu_names[i]));
572 
573 	  menu_items_n_panes = submenu_n_panes[i];
574 	  digest_menu_items (mn, submenu_start[i], submenu_end[i], 1);
575 	}
576       unblock_input ();
577 
578       set_buffer_internal_1 (prev);
579 
580       FRAME_OUTPUT_DATA (f)->menu_up_to_date_p = 1;
581       fset_menu_bar_vector (f, menu_items);
582       f->menu_bar_items_used = menu_items_used;
583     }
584   unbind_to (specpdl_count, Qnil);
585 }
586 
587 void
run_menu_bar_help_event(struct frame * f,int mb_idx)588 run_menu_bar_help_event (struct frame *f, int mb_idx)
589 {
590   Lisp_Object frame;
591   Lisp_Object vec;
592   Lisp_Object help;
593 
594   block_input ();
595   if (!FRAME_OUTPUT_DATA (f)->menu_up_to_date_p)
596     {
597       unblock_input ();
598       return;
599     }
600 
601   XSETFRAME (frame, f);
602 
603   if (mb_idx < 0)
604     {
605       kbd_buffer_store_help_event (frame, Qnil);
606       unblock_input ();
607       return;
608     }
609 
610   vec = f->menu_bar_vector;
611   if (mb_idx >= ASIZE (vec))
612     emacs_abort ();
613 
614   help = AREF (vec, mb_idx + MENU_ITEMS_ITEM_HELP);
615   if (STRINGP (help) || NILP (help))
616     kbd_buffer_store_help_event (frame, help);
617   unblock_input ();
618 }
619 
620 DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p,
621        0, 0, 0, doc: /* SKIP: real doc in xmenu.c. */)
622   (void)
623 {
624   return popup_activated_p ? Qt : Qnil;
625 }
626 
627 DEFUN ("haiku-menu-bar-open", Fhaiku_menu_bar_open, Shaiku_menu_bar_open, 0, 1, "i",
628        doc: /* Show the menu bar in FRAME.
629 
630 Move the mouse pointer onto the first element of FRAME's menu bar, and
631 cause it to be opened.  If FRAME is nil or not given, use the selected
632 frame.  If FRAME has no menu bar, a pop-up is displayed at the position
633 of the last non-menu event instead.  */)
634   (Lisp_Object frame)
635 {
636   struct frame *f = decode_window_system_frame (frame);
637 
638   if (FRAME_EXTERNAL_MENU_BAR (f))
639     {
640       if (!FRAME_OUTPUT_DATA (f)->menu_up_to_date_p)
641 	set_frame_menubar (f, 1);
642     }
643   else
644     {
645       return call2 (Qpopup_menu, call0 (Qmouse_menu_bar_map),
646 		    last_nonmenu_event);
647     }
648 
649   block_input ();
650   BMenuBar_start_tracking (FRAME_HAIKU_MENU_BAR (f));
651   unblock_input ();
652 
653   return Qnil;
654 }
655 
656 void
syms_of_haikumenu(void)657 syms_of_haikumenu (void)
658 {
659   DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
660   DEFSYM (Qpopup_menu, "popup-menu");
661   DEFSYM (Qmouse_menu_bar_map, "mouse-menu-bar-map");
662 
663   defsubr (&Smenu_or_popup_active_p);
664   defsubr (&Shaiku_menu_bar_open);
665   return;
666 }
667