aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGeoff Voelker1997-09-03 00:53:34 +0000
committerGeoff Voelker1997-09-03 00:53:34 +0000
commit014510b01f9351d93187b339a156133614cd49a0 (patch)
tree8f3b6edd4506ac75bff8686ec5b50de658c03689 /src
parent59131421e9a8628686201e9122d7eade410247a3 (diff)
downloademacs-014510b01f9351d93187b339a156133614cd49a0.tar.gz
emacs-014510b01f9351d93187b339a156133614cd49a0.zip
(init_menu_items): Disable code.
(x_activate_menubar): New function. (initialize_frame_menubar): Pass in new param to set_frame_menubar. (get_frame_menubar_event): Check for the possibility of a menu-bar button. A menu-bar button is a caption on the menu bar with no submenu. (set_frame_menubar): Correctly handle menu-bar buttons. (add_menu_item): Equiv parameter send and paid attention to. (keymap_panes, list_of_panes): Use CreatePopupMenu. (single_keymap_panes): Use CreatePopupMenu. Send key descriptions to add_menu_item. (list_of_items): Use CreatePopupMenu. Send nil description to add_menu_item. (get_menu_event): Send keymap instead of menu to get_keymap_event. (Fx_popup_menu): Extra parameter to mouse_position_hook. Don't send address of menu to win32menu_show. (win32menu_show): Send message to call popup menu rather than trying directly. get_menu_event should take an address. Call eat_mouse_events in order to get rid of any extraneous mouse events. (list_of_panes): Only bring up one pane if the length of the list of panes is one. (single_keymap_panes): Fixed problem with 'descrip' lisp object not being protected properly (GCPRO). (get_single_keymap_event): Fixed problem with 'descrip' lisp object not being protected properly (GCPRO). (name_is_separator): New function. (list_of_panes): If a pane's name is empty ("") items are now placed in the main popup instead of a blank-named submenu. This seems to be an undocumented feature of x-popup-menu. (list_of_items): New argument HMENU. Use 1 and 0 instead of Qt and Qnil for enable in add_menu_item
Diffstat (limited to 'src')
-rw-r--r--src/w32menu.c379
1 files changed, 278 insertions, 101 deletions
diff --git a/src/w32menu.c b/src/w32menu.c
index f77ce136fe2..0495818d7ff 100644
--- a/src/w32menu.c
+++ b/src/w32menu.c
@@ -66,6 +66,8 @@ extern Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
66 66
67extern Lisp_Object Qmenu_bar_update_hook; 67extern Lisp_Object Qmenu_bar_update_hook;
68 68
69void set_frame_menubar ();
70
69static Lisp_Object w32_dialog_show (); 71static Lisp_Object w32_dialog_show ();
70static Lisp_Object w32menu_show (); 72static Lisp_Object w32menu_show ();
71 73
@@ -79,6 +81,7 @@ static HMENU create_menu_items ();
79/* Initialize the menu_items structure if we haven't already done so. 81/* Initialize the menu_items structure if we haven't already done so.
80 Also mark it as currently empty. */ 82 Also mark it as currently empty. */
81 83
84#if 0
82static void 85static void
83init_menu_items (lpmm) 86init_menu_items (lpmm)
84 menu_map * lpmm; 87 menu_map * lpmm;
@@ -93,17 +96,6 @@ init_menu_items (lpmm)
93 lpmm->menu_items_used = 0; 96 lpmm->menu_items_used = 0;
94} 97}
95 98
96/* Call when finished using the data for the current menu
97 in menu_items. */
98
99static void
100discard_menu_items (lpmm)
101 menu_map * lpmm;
102{
103 lpmm->menu_items = Qnil;
104 lpmm->menu_items_allocated = lpmm->menu_items_used = 0;
105}
106
107/* Make the menu_items vector twice as large. */ 99/* Make the menu_items vector twice as large. */
108 100
109static void 101static void
@@ -120,6 +112,39 @@ grow_menu_items (lpmm)
120 112
121 lpmm->menu_items = new; 113 lpmm->menu_items = new;
122} 114}
115#endif
116
117/* Call when finished using the data for the current menu
118 in menu_items. */
119
120static void
121discard_menu_items (lpmm)
122 menu_map * lpmm;
123{
124#if 0
125 lpmm->menu_items = Qnil;
126#endif
127 lpmm->menu_items_allocated = lpmm->menu_items_used = 0;
128}
129
130/* Is this item a separator? */
131static int
132name_is_separator (name)
133 Lisp_Object name;
134{
135 int isseparator = (((char *)XSTRING (name)->data)[0] == 0);
136
137 if (!isseparator)
138 {
139 /* Check if name string consists of only dashes ('-') */
140 char *string = (char *)XSTRING (name)->data;
141 while (*string == '-') string++;
142 isseparator = (*string == 0);
143 }
144
145 return isseparator;
146}
147
123 148
124/* Indicate boundary between left and right. */ 149/* Indicate boundary between left and right. */
125 150
@@ -137,28 +162,40 @@ add_left_right_boundary (hmenu)
137 of the keyboard equivalent for this item (or nil if none). */ 162 of the keyboard equivalent for this item (or nil if none). */
138 163
139static void 164static void
140add_menu_item (lpmm, hmenu, name, enable, key) 165add_menu_item (lpmm, hmenu, name, enable, key, equiv)
141 menu_map * lpmm; 166 menu_map * lpmm;
142 HMENU hmenu; 167 HMENU hmenu;
143 Lisp_Object name; 168 Lisp_Object name;
144 UINT enable; 169 UINT enable;
145 Lisp_Object key; 170 Lisp_Object key;
171 Lisp_Object equiv;
146{ 172{
147 UINT fuFlags; 173 UINT fuFlags;
174 Lisp_Object out_string;
148 175
149 if (NILP (name) 176 if (NILP (name) || name_is_separator (name))
150 || ((char *) XSTRING (name)->data)[0] == 0
151 || strcmp ((char *) XSTRING (name)->data, "--") == 0)
152 fuFlags = MF_SEPARATOR; 177 fuFlags = MF_SEPARATOR;
153 else if (enable) 178 else
154 fuFlags = MF_STRING; 179 {
155 else 180 if (enable)
156 fuFlags = MF_STRING | MF_GRAYED; 181 fuFlags = MF_STRING;
157 182 else
183 fuFlags = MF_STRING | MF_GRAYED;
184
185 if (!NILP (equiv))
186 {
187 out_string = concat2 (name, make_string ("\t", 1));
188 out_string = concat2 (out_string, equiv);
189 }
190 else
191 out_string = name;
192 }
193
158 AppendMenu (hmenu, 194 AppendMenu (hmenu,
159 fuFlags, 195 fuFlags,
160 lpmm->menu_items_used + 1, 196 lpmm->menu_items_used + 1,
161 (fuFlags == MF_SEPARATOR)?NULL: (char *) XSTRING (name)->data); 197 (fuFlags == MF_SEPARATOR)?NULL:
198 (char *) XSTRING (out_string)->data);
162 199
163 lpmm->menu_items_used++; 200 lpmm->menu_items_used++;
164#if 0 201#if 0
@@ -316,16 +353,18 @@ keymap_panes (lpmm, keymaps, nmaps, notreal)
316 int notreal; 353 int notreal;
317{ 354{
318 int mapno; 355 int mapno;
319 356
320 // init_menu_items (lpmm); 357#if 0
321 358 init_menu_items (lpmm);
359#endif
360
322 if (nmaps > 1) 361 if (nmaps > 1)
323 { 362 {
324 HMENU hmenu; 363 HMENU hmenu;
325 364
326 if (!notreal) 365 if (!notreal)
327 { 366 {
328 hmenu = CreateMenu (); 367 hmenu = CreatePopupMenu ();
329 368
330 if (!hmenu) return (NULL); 369 if (!hmenu) return (NULL);
331 } 370 }
@@ -376,11 +415,11 @@ single_keymap_panes (lpmm, keymap, pane_name, prefix, notreal)
376 Lisp_Object pending_maps; 415 Lisp_Object pending_maps;
377 Lisp_Object tail, item, item1, item_string, table; 416 Lisp_Object tail, item, item1, item_string, table;
378 HMENU hmenu; 417 HMENU hmenu;
379 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 418 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
380 419
381 if (!notreal) 420 if (!notreal)
382 { 421 {
383 hmenu = CreateMenu (); 422 hmenu = CreatePopupMenu ();
384 if (hmenu == NULL) return NULL; 423 if (hmenu == NULL) return NULL;
385 } 424 }
386 else 425 else
@@ -427,7 +466,12 @@ single_keymap_panes (lpmm, keymap, pane_name, prefix, notreal)
427 GCPRO4 (keymap, pending_maps, def, prefix); 466 GCPRO4 (keymap, pending_maps, def, prefix);
428 467
429 def = menu_item_equiv_key (item_string, item1, &descrip); 468 def = menu_item_equiv_key (item_string, item1, &descrip);
430 enabled = menu_item_enabled_p (def, notreal); 469 {
470 struct gcpro gcpro1;
471 GCPRO1 (descrip);
472 enabled = menu_item_enabled_p (def, notreal);
473 UNGCPRO;
474 }
431 475
432 UNGCPRO; 476 UNGCPRO;
433 477
@@ -445,7 +489,7 @@ single_keymap_panes (lpmm, keymap, pane_name, prefix, notreal)
445 { 489 {
446 Lisp_Object submap; 490 Lisp_Object submap;
447 491
448 GCPRO4 (keymap, pending_maps, item, item_string); 492 GCPRO5 (keymap, pending_maps, item, item_string, descrip);
449 493
450 submap = get_keymap_1 (def, 0, 1); 494 submap = get_keymap_1 (def, 0, 1);
451 495
@@ -459,7 +503,8 @@ single_keymap_panes (lpmm, keymap, pane_name, prefix, notreal)
459 hmenu, 503 hmenu,
460 item_string, 504 item_string,
461 !NILP (enabled), 505 !NILP (enabled),
462 Fcons (XCONS (item)->car, prefix)); 506 Fcons (XCONS (item)->car, prefix),
507 descrip);
463 } 508 }
464 } 509 }
465 else 510 else
@@ -510,11 +555,16 @@ single_keymap_panes (lpmm, keymap, pane_name, prefix, notreal)
510 aside from that, must protect whatever might be 555 aside from that, must protect whatever might be
511 a string. Since there's no GCPRO5, we refetch 556 a string. Since there's no GCPRO5, we refetch
512 item_string instead of protecting it. */ 557 item_string instead of protecting it. */
513 GCPRO4 (keymap, pending_maps, def, descrip); 558 GCPRO3 (keymap, pending_maps, def);
514 descrip = def = Qnil; 559 descrip = def = Qnil;
515 560
516 def = menu_item_equiv_key (item_string, item1, &descrip); 561 def = menu_item_equiv_key (item_string, item1, &descrip);
517 enabled = menu_item_enabled_p (def, notreal); 562 {
563 struct gcpro gcpro1;
564 GCPRO1 (descrip);
565 enabled = menu_item_enabled_p (def, notreal);
566 UNGCPRO;
567 }
518 568
519 UNGCPRO; 569 UNGCPRO;
520 570
@@ -528,7 +578,7 @@ single_keymap_panes (lpmm, keymap, pane_name, prefix, notreal)
528 { 578 {
529 Lisp_Object submap; 579 Lisp_Object submap;
530 580
531 GCPRO4 (keymap, pending_maps, descrip, item_string); 581 GCPRO5 (keymap, pending_maps, descrip, item_string, descrip);
532 582
533 submap = get_keymap_1 (def, 0, 1); 583 submap = get_keymap_1 (def, 0, 1);
534 584
@@ -542,7 +592,8 @@ single_keymap_panes (lpmm, keymap, pane_name, prefix, notreal)
542 hmenu, 592 hmenu,
543 item_string, 593 item_string,
544 !NILP (enabled), 594 !NILP (enabled),
545 character); 595 character,
596 descrip);
546 } 597 }
547 } 598 }
548 else 599 else
@@ -609,29 +660,49 @@ list_of_panes (lpmm, menu)
609 Lisp_Object tail; 660 Lisp_Object tail;
610 HMENU hmenu; 661 HMENU hmenu;
611 662
612 hmenu = CreateMenu (); 663 if (XFASTINT (Flength (menu)) > 1)
613 if (hmenu == NULL) return NULL; 664 {
665 hmenu = CreatePopupMenu ();
666 if (hmenu == NULL) return NULL;
614 667
615 // init_menu_items (lpmm); 668/* init_menu_items (lpmm); */
616 669
617 for (tail = menu; !NILP (tail); tail = Fcdr (tail)) 670 for (tail = menu; !NILP (tail); tail = Fcdr (tail))
671 {
672 Lisp_Object elt, pane_name, pane_data;
673 HMENU new_hmenu;
674
675 elt = Fcar (tail);
676 pane_name = Fcar (elt);
677 CHECK_STRING (pane_name, 0);
678 pane_data = Fcdr (elt);
679 CHECK_CONS (pane_data, 0);
680
681 if (XSTRING (pane_name)->data[0] == 0)
682 {
683 list_of_items (hmenu, lpmm, pane_data);
684 }
685 else
686 {
687 new_hmenu = list_of_items (NULL, lpmm, pane_data);
688 if (new_hmenu == NULL) goto error;
689
690 AppendMenu (hmenu, MF_POPUP, (UINT)new_hmenu,
691 (char *) XSTRING (pane_name)->data);
692 }
693 }
694 }
695 else
618 { 696 {
619 Lisp_Object elt, pane_name, pane_data; 697 Lisp_Object elt, pane_name, pane_data;
620 HMENU new_hmenu; 698
621 699 elt = Fcar (menu);
622 elt = Fcar (tail);
623 pane_name = Fcar (elt); 700 pane_name = Fcar (elt);
624 CHECK_STRING (pane_name, 0); 701 CHECK_STRING (pane_name, 0);
625 pane_data = Fcdr (elt); 702 pane_data = Fcdr (elt);
626 CHECK_CONS (pane_data, 0); 703 CHECK_CONS (pane_data, 0);
627 704 hmenu = list_of_items (NULL, lpmm, pane_data);
628 new_hmenu = list_of_items (lpmm, pane_data);
629 if (new_hmenu == NULL) goto error;
630
631 AppendMenu (hmenu, MF_POPUP, (UINT)new_hmenu,
632 (char *) XSTRING (pane_name)->data);
633 } 705 }
634
635 return (hmenu); 706 return (hmenu);
636 707
637 error: 708 error:
@@ -643,21 +714,24 @@ list_of_panes (lpmm, menu)
643/* Push the items in a single pane defined by the alist PANE. */ 714/* Push the items in a single pane defined by the alist PANE. */
644 715
645static HMENU 716static HMENU
646list_of_items (lpmm, pane) 717list_of_items (hmenu, lpmm, pane)
718 HMENU hmenu;
647 menu_map * lpmm; 719 menu_map * lpmm;
648 Lisp_Object pane; 720 Lisp_Object pane;
649{ 721{
650 Lisp_Object tail, item, item1; 722 Lisp_Object tail, item, item1;
651 HMENU hmenu;
652 723
653 hmenu = CreateMenu (); 724 if (hmenu == NULL)
654 if (hmenu == NULL) return NULL; 725 {
726 hmenu = CreatePopupMenu ();
727 if (hmenu == NULL) return NULL;
728 }
655 729
656 for (tail = pane; !NILP (tail); tail = Fcdr (tail)) 730 for (tail = pane; !NILP (tail); tail = Fcdr (tail))
657 { 731 {
658 item = Fcar (tail); 732 item = Fcar (tail);
659 if (STRINGP (item)) 733 if (STRINGP (item))
660 add_menu_item (lpmm, hmenu, item, Qnil, Qnil); 734 add_menu_item (lpmm, hmenu, item, 0, Qnil, Qnil);
661 else if (NILP (item)) 735 else if (NILP (item))
662 add_left_right_boundary (); 736 add_left_right_boundary ();
663 else 737 else
@@ -665,7 +739,7 @@ list_of_items (lpmm, pane)
665 CHECK_CONS (item, 0); 739 CHECK_CONS (item, 0);
666 item1 = Fcar (item); 740 item1 = Fcar (item);
667 CHECK_STRING (item1, 1); 741 CHECK_STRING (item1, 1);
668 add_menu_item (lpmm, hmenu, item1, Qt, Fcdr (item)); 742 add_menu_item (lpmm, hmenu, item1, 1, Fcdr (item), Qnil);
669 } 743 }
670 } 744 }
671 745
@@ -770,7 +844,7 @@ get_single_keymap_event (keymap, lpnum)
770{ 844{
771 Lisp_Object pending_maps; 845 Lisp_Object pending_maps;
772 Lisp_Object tail, item, item1, item_string, table; 846 Lisp_Object tail, item, item1, item_string, table;
773 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 847 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
774 848
775 pending_maps = Qnil; 849 pending_maps = Qnil;
776 850
@@ -828,7 +902,7 @@ get_single_keymap_event (keymap, lpnum)
828 { 902 {
829 Lisp_Object submap; 903 Lisp_Object submap;
830 904
831 GCPRO4 (keymap, pending_maps, item, item_string); 905 GCPRO5 (keymap, pending_maps, item, item_string, descrip);
832 906
833 submap = get_keymap_1 (def, 0, 1); 907 submap = get_keymap_1 (def, 0, 1);
834 908
@@ -887,7 +961,7 @@ get_single_keymap_event (keymap, lpnum)
887 aside from that, must protect whatever might be 961 aside from that, must protect whatever might be
888 a string. Since there's no GCPRO5, we refetch 962 a string. Since there's no GCPRO5, we refetch
889 item_string instead of protecting it. */ 963 item_string instead of protecting it. */
890 GCPRO4 (keymap, pending_maps, def, descrip); 964 GCPRO3 (keymap, pending_maps, def);
891 descrip = def = Qnil; 965 descrip = def = Qnil;
892 966
893 def = menu_item_equiv_key (item_string, item1, &descrip); 967 def = menu_item_equiv_key (item_string, item1, &descrip);
@@ -904,7 +978,7 @@ get_single_keymap_event (keymap, lpnum)
904 { 978 {
905 Lisp_Object submap; 979 Lisp_Object submap;
906 980
907 GCPRO4 (keymap, pending_maps, descrip, item_string); 981 GCPRO5 (keymap, pending_maps, descrip, item_string, descrip);
908 982
909 submap = get_keymap_1 (def, 0, 1); 983 submap = get_keymap_1 (def, 0, 1);
910 984
@@ -1072,7 +1146,7 @@ get_menu_event (menu, lpnum)
1072 { 1146 {
1073 keymap = get_keymap (menu); 1147 keymap = get_keymap (menu);
1074 1148
1075 event = get_keymap_event (menu, 1, lpnum); 1149 event = get_keymap_event (&keymap, 1, lpnum);
1076 } 1150 }
1077 else if (!NILP (tem)) 1151 else if (!NILP (tem))
1078 { 1152 {
@@ -1162,8 +1236,8 @@ cached information about equivalent key sequences.")
1162 unsigned long time; 1236 unsigned long time;
1163 1237
1164 if (mouse_position_hook) 1238 if (mouse_position_hook)
1165 (*mouse_position_hook) (&new_f, 1, &bar_window, 1239 (*mouse_position_hook) (&new_f, 1, &bar_window, &part, &x, &y,
1166 &part, &x, &y, &time); 1240 &time);
1167 if (new_f != 0) 1241 if (new_f != 0)
1168 XSETFRAME (window, new_f); 1242 XSETFRAME (window, new_f);
1169 else 1243 else
@@ -1368,15 +1442,41 @@ get_frame_menubar_event (f, num)
1368 1442
1369 for (i = 0; i < XVECTOR (items)->size; i += 4) 1443 for (i = 0; i < XVECTOR (items)->size; i += 4)
1370 { 1444 {
1371 Lisp_Object event; 1445 Lisp_Object event, binding;
1372 1446 binding = XVECTOR (items)->contents[i + 2];
1373 event = get_menu_event (XVECTOR (items)->contents[i + 2], &num); 1447
1374 1448 /* Check to see if this might be a menubar button. It might be
1375 if (num <= 0) 1449 if it is not a keymap, it is a cons cell, its car is not a
1450 keymap, and its cdr is nil. */
1451 if (NILP (Fkeymapp (binding))
1452 && CONSP (binding)
1453 && NILP (Fkeymapp (XCONS (binding)->car))
1454 && NILP (XCONS (binding)->cdr))
1376 { 1455 {
1377 UNGCPRO; 1456 /* The fact that we have to check that this is a string here
1378 UNBLOCK_INPUT; 1457 is the reason we don't do all this rigamarole in
1379 return (Fcons (XVECTOR (items)->contents[i], event)); 1458 get_menu_event. */
1459 if (XTYPE (XVECTOR (items)->contents[i + 1]) == Lisp_String)
1460 {
1461 /* This was a menubar button. */
1462 if (--num <= 0)
1463 {
1464 UNGCPRO;
1465 UNBLOCK_INPUT;
1466 return (Fcons (XVECTOR (items)->contents[i], Qnil));
1467 }
1468 }
1469 }
1470 else
1471 {
1472 event = get_menu_event (binding, &num);
1473
1474 if (num <= 0)
1475 {
1476 UNGCPRO;
1477 UNBLOCK_INPUT;
1478 return (Fcons (XVECTOR (items)->contents[i], event));
1479 }
1380 } 1480 }
1381 } 1481 }
1382 1482
@@ -1386,21 +1486,56 @@ get_frame_menubar_event (f, num)
1386 return (Qnil); 1486 return (Qnil);
1387} 1487}
1388 1488
1489/* Activate the menu bar of frame F.
1490 This is called from keyboard.c when it gets the
1491 menu_bar_activate_event out of the Emacs event queue.
1492
1493 To activate the menu bar, we signal to the input thread that it can
1494 return from the WM_INITMENU message, allowing the normal Windows
1495 processing of the menus.
1496
1497 But first we recompute the menu bar contents (the whole tree).
1498
1499 This way we can safely execute Lisp code. */
1500
1501x_activate_menubar (f)
1502 FRAME_PTR f;
1503{
1504 set_frame_menubar (f, 0, 1);
1505
1506 /* Lock out further menubar changes while active. */
1507 f->output_data.w32->menubar_active = 1;
1508
1509 /* Signal input thread to return from WM_INITMENU. */
1510 complete_deferred_msg (FRAME_W32_WINDOW (f), WM_INITMENU, 0);
1511}
1512
1389void 1513void
1390set_frame_menubar (f, first_time) 1514set_frame_menubar (f, first_time, deep_p)
1391 FRAME_PTR f; 1515 FRAME_PTR f;
1392 int first_time; 1516 int first_time;
1517 int deep_p;
1393{ 1518{
1394 Lisp_Object tail, items; 1519 Lisp_Object tail, items;
1395 HMENU hmenu; 1520 HMENU hmenu;
1396 int i; 1521 int i;
1397 struct gcpro gcpro1; 1522 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
1398 menu_map mm; 1523 menu_map mm;
1399 int count = specpdl_ptr - specpdl; 1524 int count = specpdl_ptr - specpdl;
1400 1525
1401 struct buffer *prev = current_buffer; 1526 struct buffer *prev = current_buffer;
1402 Lisp_Object buffer; 1527 Lisp_Object buffer;
1403 1528
1529 /* We must not change the menubar when actually in use. */
1530 if (f->output_data.w32->menubar_active)
1531 return;
1532
1533#if 0 /* I don't see why this should be needed */
1534 /* Ensure menubar is up to date when about to be used. */
1535 if (f->output_data.w32->pending_menu_activation && !deep_p)
1536 deep_p = 1;
1537#endif
1538
1404 buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer; 1539 buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->buffer;
1405 specbind (Qinhibit_quit, Qt); 1540 specbind (Qinhibit_quit, Qt);
1406 /* Don't let the debugger step into this code 1541 /* Don't let the debugger step into this code
@@ -1432,16 +1567,25 @@ set_frame_menubar (f, first_time)
1432 if (NILP (items)) 1567 if (NILP (items))
1433 items = FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f)); 1568 items = FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
1434 1569
1570 hmenu = f->output_data.w32->menubar_widget;
1571 if (!hmenu)
1572 {
1435 hmenu = CreateMenu (); 1573 hmenu = CreateMenu ();
1436
1437 if (!hmenu) goto error; 1574 if (!hmenu) goto error;
1575 }
1576 else
1577 {
1578 /* Delete current contents. */
1579 while (DeleteMenu (hmenu, 0, MF_BYPOSITION))
1580 ;
1581 }
1438 1582
1439 discard_menu_items (&mm); 1583 discard_menu_items (&mm);
1440 UNBLOCK_INPUT; 1584 UNBLOCK_INPUT;
1441 1585
1442 for (i = 0; i < XVECTOR (items)->size; i += 4) 1586 for (i = 0; i < XVECTOR (items)->size; i += 4)
1443 { 1587 {
1444 Lisp_Object string; 1588 Lisp_Object string, binding;
1445 int keymaps; 1589 int keymaps;
1446 CHAR *error; 1590 CHAR *error;
1447 HMENU new_hmenu; 1591 HMENU new_hmenu;
@@ -1449,27 +1593,58 @@ set_frame_menubar (f, first_time)
1449 string = XVECTOR (items)->contents[i + 1]; 1593 string = XVECTOR (items)->contents[i + 1];
1450 if (NILP (string)) 1594 if (NILP (string))
1451 break; 1595 break;
1596
1597 binding = XVECTOR (items)->contents[i + 2];
1598
1599 if (NILP (Fkeymapp (binding))
1600 && CONSP (binding)
1601 && NILP (Fkeymapp (XCONS (binding)->car))
1602 && NILP (XCONS (binding)->cdr))
1603 {
1604 /* This is a menubar button. */
1605 Lisp_Object descrip, def;
1606 Lisp_Object enabled, item;
1607 item = Fcons (string, Fcar (binding));
1608 descrip = def = Qnil;
1609 UNGCPRO;
1610 GCPRO4 (items, item, def, string);
1611
1612 def = menu_item_equiv_key (string, item, &descrip);
1613 enabled = menu_item_enabled_p (def, 0);
1614
1615 UNGCPRO;
1616 GCPRO1 (items);
1617
1618 add_menu_item (&mm, hmenu, string, enabled, def, Qnil);
1619 }
1620 else
1621 {
1622 /* Input must not be blocked here because we call general
1623 Lisp code and internal_condition_case_1. */
1624 new_hmenu = create_menu_items (&mm, binding, 0);
1452 1625
1453 /* Input must not be blocked here 1626 if (!new_hmenu)
1454 because we call general Lisp code and internal_condition_case_1. */ 1627 continue;
1455 new_hmenu = create_menu_items (&mm,
1456 XVECTOR (items)->contents[i + 2],
1457 0);
1458
1459 if (!new_hmenu)
1460 continue;
1461 1628
1462 BLOCK_INPUT; 1629 BLOCK_INPUT;
1463 AppendMenu (hmenu, MF_POPUP, (UINT)new_hmenu, 1630 AppendMenu (hmenu, MF_POPUP, (UINT)new_hmenu,
1464 (char *) XSTRING (string)->data); 1631 (char *) XSTRING (string)->data);
1465 UNBLOCK_INPUT; 1632 UNBLOCK_INPUT;
1633 }
1466 } 1634 }
1467 1635
1468 BLOCK_INPUT; 1636 BLOCK_INPUT;
1469 { 1637 {
1470 HMENU old = GetMenu (FRAME_W32_WINDOW (f)); 1638 HMENU old = f->output_data.w32->menubar_widget;
1471 SetMenu (FRAME_W32_WINDOW (f), hmenu); 1639 SetMenu (FRAME_W32_WINDOW (f), hmenu);
1472 DestroyMenu (old); 1640 f->output_data.w32->menubar_widget = hmenu;
1641 /* Causes flicker when menu bar is updated
1642 DrawMenuBar (FRAME_W32_WINDOW (f)); */
1643
1644 /* Force the window size to be recomputed so that the frame's text
1645 area remains the same, if menubar has just been created. */
1646 if (old == NULL)
1647 x_set_window_size (f, 0, FRAME_WIDTH (f), FRAME_HEIGHT (f));
1473 } 1648 }
1474 1649
1475 error: 1650 error:
@@ -1488,6 +1663,7 @@ free_frame_menubar (f)
1488 { 1663 {
1489 HMENU old = GetMenu (FRAME_W32_WINDOW (f)); 1664 HMENU old = GetMenu (FRAME_W32_WINDOW (f));
1490 SetMenu (FRAME_W32_WINDOW (f), NULL); 1665 SetMenu (FRAME_W32_WINDOW (f), NULL);
1666 f->output_data.w32->menubar_widget = NULL;
1491 DestroyMenu (old); 1667 DestroyMenu (old);
1492 } 1668 }
1493 1669
@@ -1501,7 +1677,7 @@ void
1501initialize_frame_menubar (f) 1677initialize_frame_menubar (f)
1502 FRAME_PTR f; 1678 FRAME_PTR f;
1503{ 1679{
1504 set_frame_menubar (f, 1); 1680 set_frame_menubar (f, 1, 1);
1505} 1681}
1506 1682
1507#if 0 1683#if 0
@@ -1590,7 +1766,7 @@ else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
1590 1766
1591 if (!hmenu || strcmp (pane_string, "")) 1767 if (!hmenu || strcmp (pane_string, ""))
1592 { 1768 {
1593 HMENU new_hmenu = CreateMenu (); 1769 HMENU new_hmenu = CreatePopupMenu ();
1594 1770
1595 if (!new_hmenu) 1771 if (!new_hmenu)
1596 { 1772 {
@@ -1620,10 +1796,9 @@ else
1620 enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE]; 1796 enable = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_ENABLE];
1621 // descrip = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY]; 1797 // descrip = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_EQUIV_KEY];
1622 1798
1623 if (((char *) XSTRING (item_name)->data)[0] == 0 1799 if (name_is_separator (item_name))
1624 || strcmp ((char *) XSTRING (item_name)->data, "--") == 0)
1625 fuFlags = MF_SEPARATOR; 1800 fuFlags = MF_SEPARATOR;
1626 else if (NILP (enable) || !XUINT(enable)) 1801 else if (NILP (enable) || !XUINT (enable))
1627 fuFlags = MF_STRING | MF_GRAYED; 1802 fuFlags = MF_STRING | MF_GRAYED;
1628 else 1803 else
1629 fuFlags = MF_STRING; 1804 fuFlags = MF_STRING;
@@ -1701,14 +1876,16 @@ w32menu_show (f, x, y, menu, hmenu, error)
1701 return Qnil; 1876 return Qnil;
1702 } 1877 }
1703#endif 1878#endif
1704 1879
1705 /* Display the menu. */ 1880 /* Display the menu. */
1706 menu_selection = TrackPopupMenu (hmenu, 1881 menu_selection = SendMessage (FRAME_W32_WINDOW (f),
1707 0x10, 1882 WM_EMACS_TRACKPOPUPMENU,
1708 pos.x, pos.y, 1883 (WPARAM)hmenu, (LPARAM)&pos);
1709 0, 1884
1710 FRAME_W32_WINDOW (f), 1885 /* Clean up extraneous mouse events which might have been generated
1711 NULL); 1886 during the call. */
1887 discard_mouse_events ();
1888
1712 if (menu_selection == -1) 1889 if (menu_selection == -1)
1713 { 1890 {
1714 *error = "Invalid menu specification"; 1891 *error = "Invalid menu specification";
@@ -1721,7 +1898,7 @@ w32menu_show (f, x, y, menu, hmenu, error)
1721#if 1 1898#if 1
1722 if (menu_selection > 0) 1899 if (menu_selection > 0)
1723 { 1900 {
1724 return get_menu_event (menu, menu_selection); 1901 return get_menu_event (menu, &menu_selection);
1725 } 1902 }
1726#else 1903#else
1727 if (menu_selection > 0 && menu_selection <= lpmm->menu_items_used) 1904 if (menu_selection > 0 && menu_selection <= lpmm->menu_items_used)
@@ -1729,7 +1906,7 @@ w32menu_show (f, x, y, menu, hmenu, error)
1729 return (XVECTOR (lpmm->menu_items)->contents[menu_selection - 1]); 1906 return (XVECTOR (lpmm->menu_items)->contents[menu_selection - 1]);
1730 } 1907 }
1731#endif 1908#endif
1732 1909
1733 return Qnil; 1910 return Qnil;
1734} 1911}
1735 1912