This source file includes following definitions.
- digest_menu_items
- haiku_dialog_show
- haiku_popup_dialog
- haiku_menu_show_help
- haiku_process_pending_signals_for_menu_1
- haiku_process_pending_signals_for_menu_2
- haiku_process_pending_signals_for_menu
- haiku_menu_show
- free_frame_menubar
- initialize_frame_menubar
- set_frame_menubar
- run_menu_bar_help_event
- DEFUN
- DEFUN
- haiku_activate_menubar
- syms_of_haikumenu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 static struct timespec menu_timer_timespec;
33
34 int popup_activated_p = 0;
35
36 static void
37 digest_menu_items (void *first_menu, int start, int menu_items_used,
38 bool is_menu_bar)
39 {
40 void **menus, **panes;
41 ssize_t menu_len;
42 ssize_t pane_len;
43 int i, menu_depth;
44 void *menu, *window, *view;
45 Lisp_Object pane_name, prefix;
46 const char *pane_string;
47 Lisp_Object item_name, enable, descrip, def, selected, help;
48
49 USE_SAFE_ALLOCA;
50
51 menu_len = (menu_items_used + 1 - start) * sizeof *menus;
52 pane_len = (menu_items_used + 1 - start) * sizeof *panes;
53 menu = first_menu;
54
55 i = start;
56 menu_depth = 0;
57
58 menus = SAFE_ALLOCA (menu_len);
59 panes = SAFE_ALLOCA (pane_len);
60 memset (menus, 0, menu_len);
61 memset (panes, 0, pane_len);
62 menus[0] = first_menu;
63
64 window = NULL;
65 view = NULL;
66
67 if (FRAMEP (Vmenu_updating_frame) &&
68 FRAME_LIVE_P (XFRAME (Vmenu_updating_frame)) &&
69 FRAME_HAIKU_P (XFRAME (Vmenu_updating_frame)))
70 {
71 window = FRAME_HAIKU_WINDOW (XFRAME (Vmenu_updating_frame));
72 view = FRAME_HAIKU_VIEW (XFRAME (Vmenu_updating_frame));
73 }
74
75 if (view)
76 BView_draw_lock (view, false, 0, 0, 0, 0);
77
78 while (i < menu_items_used)
79 {
80 if (NILP (AREF (menu_items, i)))
81 {
82 menus[++menu_depth] = menu;
83 i++;
84 }
85 else if (EQ (AREF (menu_items, i), Qlambda))
86 {
87 panes[menu_depth] = NULL;
88 menu = panes[--menu_depth] ? panes[menu_depth] : menus[menu_depth];
89 i++;
90 }
91 else if (EQ (AREF (menu_items, i), Qquote))
92 i += 1;
93 else if (EQ (AREF (menu_items, i), Qt))
94 {
95 if (menu_items_n_panes == 1)
96 {
97 i += MENU_ITEMS_PANE_LENGTH;
98 continue;
99 }
100
101 pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
102 prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
103
104 if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
105 {
106 pane_name = ENCODE_UTF_8 (pane_name);
107 ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
108 }
109
110 pane_string = (NILP (pane_name)
111 ? "" : SSDATA (pane_name));
112 if (!NILP (prefix))
113 pane_string++;
114
115 if (strcmp (pane_string, ""))
116 {
117 panes[menu_depth] =
118 menu = BMenu_new_submenu (menus[menu_depth], pane_string, 1);
119 }
120
121 i += MENU_ITEMS_PANE_LENGTH;
122 }
123 else
124 {
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 help = ENCODE_UTF_8 (help);
146
147 if (i + MENU_ITEMS_ITEM_LENGTH < menu_items_used &&
148 NILP (AREF (menu_items, i + MENU_ITEMS_ITEM_LENGTH)))
149 menu = BMenu_new_submenu (menu, SSDATA (item_name), !NILP (enable));
150 else if (NILP (def) && menu_separator_name_p (SSDATA (item_name)))
151 BMenu_add_separator (menu);
152 else if (!is_menu_bar)
153 {
154 if (!use_system_tooltips || NILP (Fsymbol_value (Qtooltip_mode)))
155 BMenu_add_item (menu, SSDATA (item_name),
156 !NILP (def) ? aref_addr (menu_items, i) : NULL,
157 !NILP (enable), !NILP (selected), 0, window,
158 !NILP (descrip) ? SSDATA (descrip) : NULL,
159 NULL);
160 else
161 BMenu_add_item (menu, SSDATA (item_name),
162 !NILP (def) ? aref_addr (menu_items, i) : NULL,
163 !NILP (enable), !NILP (selected), 0, window,
164 !NILP (descrip) ? SSDATA (descrip) : NULL,
165 STRINGP (help) ? SSDATA (help) : NULL);
166 }
167 else if (!use_system_tooltips || NILP (Fsymbol_value (Qtooltip_mode)))
168 BMenu_add_item (menu, SSDATA (item_name),
169 !NILP (def) ? (void *) (intptr_t) i : NULL,
170 !NILP (enable), !NILP (selected), 1, window,
171 !NILP (descrip) ? SSDATA (descrip) : NULL,
172 NULL);
173 else
174 BMenu_add_item (menu, SSDATA (item_name),
175 !NILP (def) ? (void *) (intptr_t) i : NULL,
176 !NILP (enable), !NILP (selected), 1, window,
177 !NILP (descrip) ? SSDATA (descrip) : NULL,
178 STRINGP (help) ? SSDATA (help) : NULL);
179
180 i += MENU_ITEMS_ITEM_LENGTH;
181 }
182 }
183
184 if (view)
185 BView_draw_unlock (view);
186
187 SAFE_FREE ();
188 }
189
190 static Lisp_Object
191 haiku_dialog_show (struct frame *f, Lisp_Object title,
192 Lisp_Object header, const char **error_name)
193 {
194 int i, nb_buttons = 0;
195 bool boundary_seen = false;
196 Lisp_Object pane_name, vals[10];
197 void *alert, *button;
198 bool enabled_item_seen_p = false;
199 int32 val;
200
201 *error_name = NULL;
202
203 if (menu_items_n_panes > 1)
204 {
205 *error_name = "Multiple panes in dialog box";
206 return Qnil;
207 }
208
209 pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME);
210 i = MENU_ITEMS_PANE_LENGTH;
211
212 if (STRING_MULTIBYTE (pane_name))
213 pane_name = ENCODE_UTF_8 (pane_name);
214
215 block_input ();
216 alert = BAlert_new (SSDATA (pane_name), NILP (header) ? HAIKU_INFO_ALERT :
217 HAIKU_IDEA_ALERT);
218
219 while (i < menu_items_used)
220 {
221 Lisp_Object item_name, enable, descrip, value;
222 item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
223 enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
224 descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
225 value = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
226
227 if (NILP (item_name))
228 {
229 BAlert_delete (alert);
230 *error_name = "Submenu in dialog items";
231 unblock_input ();
232 return Qnil;
233 }
234
235 if (EQ (item_name, Qquote))
236 {
237 if (nb_buttons)
238 boundary_seen = true;
239
240 i++;
241 continue;
242 }
243
244 if (nb_buttons >= 9)
245 {
246 BAlert_delete (alert);
247 *error_name = "Too many dialog items";
248 unblock_input ();
249 return Qnil;
250 }
251
252 if (STRING_MULTIBYTE (item_name))
253 item_name = ENCODE_UTF_8 (item_name);
254 if (!NILP (descrip) && STRING_MULTIBYTE (descrip))
255 descrip = ENCODE_UTF_8 (descrip);
256
257 button = BAlert_add_button (alert, SSDATA (item_name));
258
259 BButton_set_enabled (button, !NILP (enable));
260 enabled_item_seen_p |= !NILP (enable);
261
262 if (!NILP (descrip))
263 BView_set_tooltip (button, SSDATA (descrip));
264
265 vals[nb_buttons] = value;
266 ++nb_buttons;
267 i += MENU_ITEMS_ITEM_LENGTH;
268 }
269
270
271
272 if (boundary_seen)
273 BAlert_set_offset_spacing (alert);
274
275
276
277 if (!enabled_item_seen_p)
278 BAlert_add_button (alert, "Ok");
279 unblock_input ();
280
281 unrequest_sigio ();
282 ++popup_activated_p;
283 val = BAlert_go (alert, block_input, unblock_input,
284 process_pending_signals);
285 --popup_activated_p;
286 request_sigio ();
287
288 if (val < 0)
289 quit ();
290 else if (val < nb_buttons)
291 return vals[val];
292
293
294
295 if (nb_buttons)
296 quit ();
297
298
299 else
300 return Qt;
301
302 emacs_abort ();
303 }
304
305 Lisp_Object
306 haiku_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
307 {
308 Lisp_Object title;
309 const char *error_name = NULL;
310 Lisp_Object selection;
311 specpdl_ref specpdl_count = SPECPDL_INDEX ();
312
313 check_window_system (f);
314
315
316 title = Fcar (contents);
317 CHECK_STRING (title);
318 record_unwind_protect_void (unuse_menu_items);
319
320 if (NILP (Fcar (Fcdr (contents))))
321
322
323
324 contents = list2 (title, Fcons (build_string ("Ok"), Qt));
325
326 list_of_panes (list1 (contents));
327
328
329 selection = haiku_dialog_show (f, title, header, &error_name);
330
331 unbind_to (specpdl_count, Qnil);
332 discard_menu_items ();
333
334 if (error_name)
335 error ("%s", error_name);
336 return selection;
337 }
338
339 static void
340 haiku_menu_show_help (void *help, void *data)
341 {
342 Lisp_Object *id = (Lisp_Object *) help;
343
344 if (help)
345 show_help_echo (id[MENU_ITEMS_ITEM_HELP],
346 Qnil, Qnil, Qnil);
347 else
348 show_help_echo (Qnil, Qnil, Qnil, Qnil);
349 }
350
351 static Lisp_Object
352 haiku_process_pending_signals_for_menu_1 (void *ptr)
353 {
354 menu_timer_timespec = timer_check ();
355
356 return Qnil;
357 }
358
359 static Lisp_Object
360 haiku_process_pending_signals_for_menu_2 (enum nonlocal_exit exit, Lisp_Object error)
361 {
362 menu_timer_timespec.tv_sec = 0;
363 menu_timer_timespec.tv_nsec = -1;
364
365 return Qnil;
366 }
367
368 static struct timespec
369 haiku_process_pending_signals_for_menu (void)
370 {
371 process_pending_signals ();
372
373
374
375
376 internal_catch_all (haiku_process_pending_signals_for_menu_1, NULL,
377 haiku_process_pending_signals_for_menu_2);
378
379 return menu_timer_timespec;
380 }
381
382 Lisp_Object
383 haiku_menu_show (struct frame *f, int x, int y, int menuflags,
384 Lisp_Object title, const char **error_name)
385 {
386 int i, submenu_depth, j;
387 void *view, *menu;
388 Lisp_Object *subprefix_stack;
389 Lisp_Object prefix, entry;
390
391 USE_SAFE_ALLOCA;
392
393 view = FRAME_HAIKU_VIEW (f);
394 i = 0;
395 submenu_depth = 0;
396 subprefix_stack
397 = SAFE_ALLOCA (menu_items_used * sizeof (Lisp_Object));
398
399 eassert (FRAME_HAIKU_P (f));
400
401 *error_name = NULL;
402
403 if (menu_items_used <= MENU_ITEMS_PANE_LENGTH)
404 {
405 *error_name = "Empty menu";
406
407 SAFE_FREE ();
408 return Qnil;
409 }
410
411 block_input ();
412 if (STRINGP (title) && STRING_MULTIBYTE (title))
413 title = ENCODE_UTF_8 (title);
414
415 menu = BPopUpMenu_new (STRINGP (title) ? SSDATA (title) : NULL);
416 if (STRINGP (title))
417 {
418 BMenu_add_title (menu, SSDATA (title));
419 BMenu_add_separator (menu);
420 }
421 digest_menu_items (menu, 0, menu_items_used, 0);
422 BView_convert_to_screen (view, &x, &y);
423 unblock_input ();
424
425 unrequest_sigio ();
426 popup_activated_p++;
427 menu_item_selection = BMenu_run (menu, x, y, haiku_menu_show_help,
428 block_input, unblock_input,
429 haiku_process_pending_signals_for_menu, NULL);
430 popup_activated_p--;
431 request_sigio ();
432
433 FRAME_DISPLAY_INFO (f)->grabbed = 0;
434
435
436
437
438 be_clear_grab_view ();
439
440 if (menu_item_selection)
441 {
442 prefix = entry = Qnil;
443 i = 0;
444 while (i < menu_items_used)
445 {
446 if (NILP (AREF (menu_items, i)))
447 {
448 subprefix_stack[submenu_depth++] = prefix;
449 prefix = entry;
450 i++;
451 }
452 else if (EQ (AREF (menu_items, i), Qlambda))
453 {
454 prefix = subprefix_stack[--submenu_depth];
455 i++;
456 }
457 else if (EQ (AREF (menu_items, i), Qt))
458 {
459 prefix
460 = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
461 i += MENU_ITEMS_PANE_LENGTH;
462 }
463
464
465 else if (EQ (AREF (menu_items, i), Qquote))
466 i += 1;
467 else
468 {
469 entry
470 = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
471 if (menu_item_selection == aref_addr (menu_items, i))
472 {
473 if (menuflags & MENU_KEYMAPS)
474 {
475 entry = list1 (entry);
476 if (!NILP (prefix))
477 entry = Fcons (prefix, entry);
478 for (j = submenu_depth - 1; j >= 0; j--)
479 if (!NILP (subprefix_stack[j]))
480 entry = Fcons (subprefix_stack[j], entry);
481 }
482 block_input ();
483 BPopUpMenu_delete (menu);
484 unblock_input ();
485
486 SAFE_FREE ();
487 return entry;
488 }
489 i += MENU_ITEMS_ITEM_LENGTH;
490 }
491 }
492 }
493 else if (!(menuflags & MENU_FOR_CLICK))
494 {
495 block_input ();
496 BPopUpMenu_delete (menu);
497 unblock_input ();
498 quit ();
499 }
500 block_input ();
501 BPopUpMenu_delete (menu);
502 unblock_input ();
503
504 SAFE_FREE ();
505 return Qnil;
506 }
507
508 void
509 free_frame_menubar (struct frame *f)
510 {
511 void *mbar;
512
513 FRAME_MENU_BAR_LINES (f) = 0;
514 FRAME_MENU_BAR_HEIGHT (f) = 0;
515 FRAME_EXTERNAL_MENU_BAR (f) = 0;
516
517 block_input ();
518 mbar = FRAME_HAIKU_MENU_BAR (f);
519 FRAME_HAIKU_MENU_BAR (f) = NULL;
520
521 if (mbar)
522 BMenuBar_delete (mbar);
523
524 if (FRAME_OUTPUT_DATA (f)->menu_bar_open_p)
525 --popup_activated_p;
526 FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 0;
527 unblock_input ();
528
529 adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines);
530 }
531
532 void
533 initialize_frame_menubar (struct frame *f)
534 {
535
536
537 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
538 set_frame_menubar (f, true);
539 }
540
541 void
542 set_frame_menubar (struct frame *f, bool deep_p)
543 {
544 void *mbar = FRAME_HAIKU_MENU_BAR (f);
545 void *view = FRAME_HAIKU_VIEW (f);
546 bool first_time_p = false;
547
548 if (!mbar)
549 {
550 block_input ();
551 mbar = FRAME_HAIKU_MENU_BAR (f) = BMenuBar_new (view);
552 first_time_p = 1;
553
554
555
556 if (FRAME_VISIBLE_P (f))
557 haiku_wait_for_event (f, MENU_BAR_RESIZE);
558
559 unblock_input ();
560 }
561
562 Lisp_Object items;
563 struct buffer *prev = current_buffer;
564 Lisp_Object buffer;
565 specpdl_ref specpdl_count = SPECPDL_INDEX ();
566 int previous_menu_items_used = f->menu_bar_items_used;
567 Lisp_Object *previous_items
568 = alloca (previous_menu_items_used * sizeof *previous_items);
569 int count;
570 ptrdiff_t subitems, i;
571 int *submenu_start, *submenu_end, *submenu_n_panes;
572 Lisp_Object *submenu_names;
573
574 XSETFRAME (Vmenu_updating_frame, f);
575
576 if (!deep_p)
577 {
578 items = FRAME_MENU_BAR_ITEMS (f);
579 Lisp_Object string;
580
581 block_input ();
582 int count = BMenu_count_items (mbar);
583
584 int i;
585 for (i = 0; i < ASIZE (items); i += 4)
586 {
587 string = AREF (items, i + 1);
588
589 if (!STRINGP (string))
590 break;
591
592 if (STRING_MULTIBYTE (string))
593 string = ENCODE_UTF_8 (string);
594
595 if (i / 4 < count)
596 {
597 void *it = BMenu_item_at (mbar, i / 4);
598 BMenu_item_set_label (it, SSDATA (string));
599 }
600 else
601 BMenu_new_menu_bar_submenu (mbar, SSDATA (string));
602 }
603
604 if (i / 4 < count)
605 BMenu_delete_from (mbar, i / 4, count - i / 4 + 1);
606 unblock_input ();
607
608 f->menu_bar_items_used = 0;
609 }
610 else
611 {
612
613
614 if (first_time_p)
615 previous_menu_items_used = 0;
616
617 buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
618 specbind (Qinhibit_quit, Qt);
619
620
621 specbind (Qdebug_on_next_call, Qnil);
622
623 record_unwind_save_match_data ();
624 if (NILP (Voverriding_local_map_menu_flag))
625 {
626 specbind (Qoverriding_terminal_local_map, Qnil);
627 specbind (Qoverriding_local_map, Qnil);
628 }
629
630 set_buffer_internal_1 (XBUFFER (buffer));
631
632
633 safe_run_hooks (Qactivate_menubar_hook);
634
635
636
637 safe_run_hooks (Qmenu_bar_update_hook);
638 fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
639
640 items = FRAME_MENU_BAR_ITEMS (f);
641
642
643 if (previous_menu_items_used)
644 memcpy (previous_items, xvector_contents (f->menu_bar_vector),
645 previous_menu_items_used * word_size);
646
647
648
649 save_menu_items ();
650
651 menu_items = f->menu_bar_vector;
652 menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
653 subitems = ASIZE (items) / 4;
654 submenu_start = alloca ((subitems + 1) * sizeof *submenu_start);
655 submenu_end = alloca (subitems * sizeof *submenu_end);
656 submenu_n_panes = alloca (subitems * sizeof *submenu_n_panes);
657 submenu_names = alloca (subitems * sizeof (Lisp_Object));
658
659 init_menu_items ();
660 for (i = 0; i < subitems; i++)
661 {
662 Lisp_Object key, string, maps;
663
664 key = AREF (items, 4 * i);
665 string = AREF (items, 4 * i + 1);
666 maps = AREF (items, 4 * i + 2);
667 if (NILP (string))
668 break;
669
670 if (STRINGP (string) && STRING_MULTIBYTE (string))
671 string = ENCODE_UTF_8 (string);
672
673 submenu_start[i] = menu_items_used;
674
675 menu_items_n_panes = 0;
676 parse_single_submenu (key, string, maps);
677 submenu_n_panes[i] = menu_items_n_panes;
678
679 submenu_end[i] = menu_items_used;
680 submenu_names[i] = string;
681 }
682
683 submenu_start[i] = -1;
684 finish_menu_items ();
685
686 set_buffer_internal_1 (prev);
687
688
689
690
691
692 for (i = 0; i < previous_menu_items_used; i++)
693 if (menu_items_used == i
694 || (!EQ (previous_items[i], AREF (menu_items, i))))
695 break;
696 if (i == menu_items_used && i == previous_menu_items_used && i != 0)
697 {
698
699
700 discard_menu_items ();
701 unbind_to (specpdl_count, Qnil);
702 return;
703 }
704
705
706
707
708 block_input ();
709 count = BMenu_count_items (mbar);
710 for (i = 0; submenu_start[i] >= 0; ++i)
711 {
712 void *mn = NULL;
713 if (i < count)
714 mn = BMenu_item_get_menu (BMenu_item_at (mbar, i));
715 if (mn)
716 BMenu_delete_all (mn);
717 else
718 mn = BMenu_new_menu_bar_submenu (mbar, SSDATA (submenu_names[i]));
719
720 menu_items_n_panes = submenu_n_panes[i];
721 digest_menu_items (mn, submenu_start[i], submenu_end[i], 1);
722 }
723 unblock_input ();
724
725
726 fset_menu_bar_vector (f, menu_items);
727 f->menu_bar_items_used = menu_items_used;
728 }
729
730
731 unbind_to (specpdl_count, Qnil);
732 }
733
734 void
735 run_menu_bar_help_event (struct frame *f, int mb_idx)
736 {
737 Lisp_Object frame, vec, help;
738
739 XSETFRAME (frame, f);
740
741 block_input ();
742 if (mb_idx < 0)
743 {
744 kbd_buffer_store_help_event (frame, Qnil);
745 unblock_input ();
746 return;
747 }
748
749 vec = f->menu_bar_vector;
750 if ((mb_idx + MENU_ITEMS_ITEM_HELP) >= ASIZE (vec))
751 return;
752
753 help = AREF (vec, mb_idx + MENU_ITEMS_ITEM_HELP);
754 if (STRINGP (help) || NILP (help))
755 kbd_buffer_store_help_event (frame, help);
756 unblock_input ();
757 }
758
759 DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p,
760 0, 0, 0, doc: )
761 (void)
762 {
763 return popup_activated_p ? Qt : Qnil;
764 }
765
766 DEFUN ("haiku-menu-bar-open", Fhaiku_menu_bar_open, Shaiku_menu_bar_open, 0, 1, "i",
767 doc:
768
769
770
771
772 )
773 (Lisp_Object frame)
774 {
775 struct frame *f = decode_window_system_frame (frame);
776 int rc;
777
778 if (FRAME_EXTERNAL_MENU_BAR (f))
779 {
780 block_input ();
781 set_frame_menubar (f, 1);
782 rc = BMenuBar_start_tracking (FRAME_HAIKU_MENU_BAR (f));
783 unblock_input ();
784
785 if (!rc)
786 return Qnil;
787
788 FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1;
789 popup_activated_p += 1;
790 }
791 else
792 return call2 (Qpopup_menu, call0 (Qmouse_menu_bar_map),
793 last_nonmenu_event);
794
795 return Qnil;
796 }
797
798 void
799 haiku_activate_menubar (struct frame *f)
800 {
801 int rc;
802
803 if (!FRAME_HAIKU_MENU_BAR (f))
804 return;
805
806 set_frame_menubar (f, true);
807
808 if (FRAME_OUTPUT_DATA (f)->saved_menu_event)
809 {
810 block_input ();
811 rc = be_replay_menu_bar_event (FRAME_HAIKU_MENU_BAR (f),
812 FRAME_OUTPUT_DATA (f)->saved_menu_event);
813 xfree (FRAME_OUTPUT_DATA (f)->saved_menu_event);
814 FRAME_OUTPUT_DATA (f)->saved_menu_event = NULL;
815 unblock_input ();
816
817 if (!rc)
818 return;
819
820 FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1;
821 popup_activated_p += 1;
822 }
823 else
824 {
825 block_input ();
826 rc = BMenuBar_start_tracking (FRAME_HAIKU_MENU_BAR (f));
827 unblock_input ();
828
829 if (!rc)
830 return;
831
832 FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1;
833 popup_activated_p += 1;
834 }
835 }
836
837 void
838 syms_of_haikumenu (void)
839 {
840 DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
841 DEFSYM (Qpopup_menu, "popup-menu");
842 DEFSYM (Qmouse_menu_bar_map, "mouse-menu-bar-map");
843 DEFSYM (Qtooltip_mode, "tooltip-mode");
844
845 defsubr (&Smenu_or_popup_active_p);
846 defsubr (&Shaiku_menu_bar_open);
847 return;
848 }