diff options
| author | Geoff Voelker | 1997-09-03 00:53:34 +0000 |
|---|---|---|
| committer | Geoff Voelker | 1997-09-03 00:53:34 +0000 |
| commit | 014510b01f9351d93187b339a156133614cd49a0 (patch) | |
| tree | 8f3b6edd4506ac75bff8686ec5b50de658c03689 /src | |
| parent | 59131421e9a8628686201e9122d7eade410247a3 (diff) | |
| download | emacs-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.c | 379 |
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 | ||
| 67 | extern Lisp_Object Qmenu_bar_update_hook; | 67 | extern Lisp_Object Qmenu_bar_update_hook; |
| 68 | 68 | ||
| 69 | void set_frame_menubar (); | ||
| 70 | |||
| 69 | static Lisp_Object w32_dialog_show (); | 71 | static Lisp_Object w32_dialog_show (); |
| 70 | static Lisp_Object w32menu_show (); | 72 | static 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 | ||
| 82 | static void | 85 | static void |
| 83 | init_menu_items (lpmm) | 86 | init_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 | |||
| 99 | static void | ||
| 100 | discard_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 | ||
| 109 | static void | 101 | static 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 | |||
| 120 | static void | ||
| 121 | discard_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? */ | ||
| 131 | static int | ||
| 132 | name_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 | ||
| 139 | static void | 164 | static void |
| 140 | add_menu_item (lpmm, hmenu, name, enable, key) | 165 | add_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 | ||
| 645 | static HMENU | 716 | static HMENU |
| 646 | list_of_items (lpmm, pane) | 717 | list_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 | |||
| 1501 | x_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 | |||
| 1389 | void | 1513 | void |
| 1390 | set_frame_menubar (f, first_time) | 1514 | set_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 | |||
| 1501 | initialize_frame_menubar (f) | 1677 | initialize_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 | ||