comparison src/menubar-msw.c @ 233:52952cbfc5b5 r20-5b15

Import from CVS: tag r20-5b15
author cvs
date Mon, 13 Aug 2007 10:14:14 +0200
parents 557eaa0339bf
children 83b3d10dcba9
comparison
equal deleted inserted replaced
232:aa6545ea0638 233:52952cbfc5b5
94 #include "window.h" 94 #include "window.h"
95 95
96 #define EMPTY_ITEM_ID ((UINT)LISP_TO_VOID (Qunbound)) 96 #define EMPTY_ITEM_ID ((UINT)LISP_TO_VOID (Qunbound))
97 #define EMPTY_ITEM_NAME "(empty)" 97 #define EMPTY_ITEM_NAME "(empty)"
98 98
99 /* Qnil when there's no popup being tracked, or a descriptor 99 /* Current menu (bar or popup) descriptor. gcpro'ed */
100 for the popup. gcpro'ed */ 100 static Lisp_Object current_menudesc;
101 static Lisp_Object current_tracking_popup; 101
102 102 /* Current menubar or popup hashtable. gcpro'ed */
103 /* Current popup has table. Qnil when no popup. gcpro'ed */ 103 static Lisp_Object current_hashtable;
104 static Lisp_Object current_popup_hash_table;
105 104
106 /* Bound by menubar.el */ 105 /* Bound by menubar.el */
107 static Lisp_Object Qfind_menu_item; 106 static Lisp_Object Qfind_menu_item;
108 107
109 /* This is used to allocate unique ids to menu items. 108 /* This is used to allocate unique ids to menu items.
164 *name = Qnil; 163 *name = Qnil;
165 *callback = Qnil; 164 *callback = Qnil;
166 *plist = Qnil; 165 *plist = Qnil;
167 166
168 if (length < 3) 167 if (length < 3)
169 signal_simple_error ("button descriptors must be at least 3 long", desc); 168 signal_simple_error ("Button descriptors must be at least 3 long", desc);
170 169
171 /* length 3: [ "name" callback active-p ] 170 /* length 3: [ "name" callback active-p ]
172 length 4: [ "name" callback active-p suffix ] 171 length 4: [ "name" callback active-p suffix ]
173 or [ "name" callback keyword value ] 172 or [ "name" callback keyword value ]
174 length 5+: [ "name" callback [ keyword value ]+ ] 173 length 5+: [ "name" callback [ keyword value ]+ ]
189 /* the new way */ 188 /* the new way */
190 { 189 {
191 int i; 190 int i;
192 if (length & 1) 191 if (length & 1)
193 signal_simple_error ( 192 signal_simple_error (
194 "button descriptor has an odd number of keywords and values", 193 "Button descriptor has an odd number of keywords and values",
195 desc); 194 desc);
196 195
197 for (i = 2; i < length;) 196 for (i = 2; i < length;)
198 { 197 {
199 Lisp_Object key = contents [i++]; 198 Lisp_Object key = contents [i++];
200 Lisp_Object val = contents [i++]; 199 Lisp_Object val = contents [i++];
201 if (!KEYWORDP (key)) 200 if (!KEYWORDP (key))
202 signal_simple_error_2 ("not a keyword", key, desc); 201 signal_simple_error_2 ("Not a keyword", key, desc);
203 internal_plist_put (plist, key, val); 202 internal_plist_put (plist, key, val);
204 } 203 }
205 } 204 }
206 } 205 }
207 206
445 while (DeleteMenu (menu, 0, MF_BYPOSITION)); 444 while (DeleteMenu (menu, 0, MF_BYPOSITION));
446 if (add_empty_p) 445 if (add_empty_p)
447 AppendMenu (menu, MF_STRING | MF_GRAYED, EMPTY_ITEM_ID, EMPTY_ITEM_NAME); 446 AppendMenu (menu, MF_STRING | MF_GRAYED, EMPTY_ITEM_ID, EMPTY_ITEM_NAME);
448 } 447 }
449 448
449 /*
450 * The idea of checksumming is that we must hash minimal object
451 * which is neccessarily changes when the item changes. For separator
452 * this is a constant, for grey strings and submenus these are hashes
453 * of names, since sumbenus are unpopulated until opened so always
454 * equal otherwise. For items, this is a full hash value of a callback,
455 * because a callback may me a form which can be changed only somewhere
456 * in depth.
457 */
458 static unsigned long
459 checksum_menu_item (Lisp_Object item)
460 {
461 if (STRINGP (item))
462 {
463 /* Separator or unselectable text - hash as a string + 13 */
464 if (separator_string_p (XSTRING_DATA (item)))
465 return 13;
466 else
467 return internal_hash (item, 0) + 13;
468 }
469 else if (CONSP (item))
470 {
471 /* Submenu - hash by its string name + 0 */
472 return internal_hash (XCAR(item), 0);
473 }
474 else if (VECTORP (item))
475 {
476 /* An ordinary item - hash its name and callback form. */
477 Lisp_Object plist, name, callback;
478 gui_parse_button_descriptor (item, &name, &callback, &plist);
479 return HASH2 (internal_hash (name, 0),
480 internal_hash (callback, 0));
481 }
482
483 /* An error - will be caught later */
484 return 0;
485 }
486
450 static void 487 static void
451 populate_menu_add_item (HMENU menu, Lisp_Object path, 488 populate_menu_add_item (HMENU menu, Lisp_Object path,
452 Lisp_Object hash_tab, Lisp_Object item, int flush_right) 489 Lisp_Object hash_tab, Lisp_Object item, int flush_right)
453 { 490 {
454 MENUITEMINFO item_info; 491 MENUITEMINFO item_info;
478 Lisp_Object subname = XCAR (item); 515 Lisp_Object subname = XCAR (item);
479 Lisp_Object plist; 516 Lisp_Object plist;
480 HMENU submenu; 517 HMENU submenu;
481 518
482 if (!STRINGP (subname)) 519 if (!STRINGP (subname))
483 signal_simple_error ("menu name (first element) must be a string", item); 520 signal_simple_error ("Menu name (first element) must be a string", item);
484 521
485 item = gui_parse_menu_keywords (XCDR (item), &plist); 522 item = gui_parse_menu_keywords (XCDR (item), &plist);
486 GCPRO1 (plist); 523 GCPRO1 (plist);
487 524
488 if (gui_plist_says_item_excluded (plist, Vmenubar_configuration)) 525 if (gui_plist_says_item_excluded (plist, Vmenubar_configuration))
555 item_info.fType |= MFT_STRING; 592 item_info.fType |= MFT_STRING;
556 item_info.dwTypeData = plist_get_menu_item_name (name, callback, plist); 593 item_info.dwTypeData = plist_get_menu_item_name (name, callback, plist);
557 } 594 }
558 else 595 else
559 { 596 {
560 signal_simple_error ("ill-constructed menu descriptor", item); 597 signal_simple_error ("Ill-constructed menu descriptor", item);
561 } 598 }
562 599
563 if (flush_right) 600 if (flush_right)
564 item_info.fType |= MFT_RIGHTJUSTIFY; 601 item_info.fType |= MFT_RIGHTJUSTIFY;
565 602
566 InsertMenuItem (menu, UINT_MAX, TRUE, &item_info); 603 InsertMenuItem (menu, UINT_MAX, TRUE, &item_info);
567 } 604 }
568 605
569 static void 606 /*
570 populate_menu (HMENU menu, Lisp_Object path, Lisp_Object descriptor, 607 * This function is called from populate_menu and checksum_menu.
571 Lisp_Object hash_tab, int bar_p) 608 * When called to populate, MENU is a menu handle, PATH is a
609 * list of strings representing menu path from root to this submenu,
610 * DESCRIPTOR is a menu descriptor, HASH_TAB is a hashtable associated
611 * with root menu, BAR_P indicates whether this called for a menubar or
612 * a popup, and POPULATE_P is non-zero. Return value must be ignored.
613 * When called to checksum, DESCRIPTOR has the same meaning, POPULATE_P
614 * is zero, PATH must be Qnil, and the rest of parameters is ignored.
615 * Return value is the menu checksum.
616 */
617 static unsigned long
618 populate_or_checksum_helper (HMENU menu, Lisp_Object path, Lisp_Object descriptor,
619 Lisp_Object hash_tab, int bar_p, int populate_p)
572 { 620 {
573 Lisp_Object menu_name, plist, item_desc; 621 Lisp_Object menu_name, plist, item_desc;
574 int deep_p, flush_right; 622 int deep_p, flush_right;
575 struct gcpro gcpro1; 623 struct gcpro gcpro1;
624 unsigned long checksum = 0;
576 625
577 /* Will initially contain only "(empty)" */ 626 /* Will initially contain only "(empty)" */
578 empty_menu (menu, 1); 627 if (populate_p)
628 empty_menu (menu, 1);
579 629
580 /* PATH set to nil indicates top-level popup or menubar */ 630 /* PATH set to nil indicates top-level popup or menubar */
581 deep_p = !NILP (path); 631 deep_p = !NILP (path);
582 632
583 if (!deep_p) 633 if (!deep_p)
584 top_level_menu = menu; 634 top_level_menu = menu;
585 635
586 if (!CONSP(descriptor)) 636 if (!CONSP(descriptor))
587 signal_simple_error ("menu descriptor must be a list", descriptor); 637 signal_simple_error ("Menu descriptor must be a list", descriptor);
588 638
589 if (STRINGP (XCAR (descriptor))) 639 if (STRINGP (XCAR (descriptor)))
590 { 640 {
591 menu_name = XCAR (descriptor); 641 menu_name = XCAR (descriptor);
592 descriptor = XCDR (descriptor); 642 descriptor = XCDR (descriptor);
593 } 643 }
594 else 644 else
595 { 645 {
596 menu_name = Qnil; 646 menu_name = Qnil;
597 if (deep_p) /* Not a popup or bar */ 647 if (deep_p) /* Not a popup or bar */
598 signal_simple_error ("menu must have a name", descriptor); 648 signal_simple_error ("Menu must have a name", descriptor);
599 } 649 }
600 650
601 /* Fetch keywords prepending the item list */ 651 /* Fetch keywords prepending the item list */
602 descriptor = gui_parse_menu_keywords (descriptor, &plist); 652 descriptor = gui_parse_menu_keywords (descriptor, &plist);
603 GCPRO1 (plist); 653 GCPRO1 (plist);
610 { 660 {
611 if (NILP (XCAR (item_desc))) 661 if (NILP (XCAR (item_desc)))
612 { 662 {
613 if (bar_p) 663 if (bar_p)
614 flush_right = 1; 664 flush_right = 1;
665 if (!populate_p)
666 checksum = HASH2 (checksum, Qnil);
615 } 667 }
616 else 668 else if (populate_p)
617 populate_menu_add_item (menu, path, hash_tab, 669 populate_menu_add_item (menu, path, hash_tab,
618 XCAR (item_desc), flush_right); 670 XCAR (item_desc), flush_right);
671 else
672 checksum = HASH2 (checksum,
673 checksum_menu_item (XCAR (item_desc)));
619 } 674 }
620 675
621 /* Remove the "(empty)" item, if there are other ones */ 676 if (populate_p)
622 if (GetMenuItemCount (menu) > 1) 677 {
623 RemoveMenu (menu, EMPTY_ITEM_ID, MF_BYCOMMAND); 678 /* Remove the "(empty)" item, if there are other ones */
624 679 if (GetMenuItemCount (menu) > 1)
625 /* Add the header to the popup, if told so. The same as in X - an 680 RemoveMenu (menu, EMPTY_ITEM_ID, MF_BYCOMMAND);
626 insensitive item, and a separator (Seems to me, there were 681
627 two separators in X... In Windows this looks ugly, anywats. */ 682 /* Add the header to the popup, if told so. The same as in X - an
628 if (!bar_p && !deep_p && popup_menu_titles && !NILP(menu_name)) 683 insensitive item, and a separator (Seems to me, there were
629 { 684 two separators in X... In Windows this looks ugly, anywats. */
630 InsertMenu (menu, 0, MF_BYPOSITION | MF_STRING | MF_DISABLED, 685 if (!bar_p && !deep_p && popup_menu_titles && !NILP(menu_name))
631 0, XSTRING_DATA(menu_name)); 686 {
632 InsertMenu (menu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL); 687 InsertMenu (menu, 0, MF_BYPOSITION | MF_STRING | MF_DISABLED,
633 SetMenuDefaultItem (menu, 0, MF_BYPOSITION); 688 0, XSTRING_DATA(menu_name));
634 } 689 InsertMenu (menu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
690 SetMenuDefaultItem (menu, 0, MF_BYPOSITION);
691 }
692 }
693 return checksum;
694 }
695
696 static void
697 populate_menu (HMENU menu, Lisp_Object path, Lisp_Object descriptor,
698 Lisp_Object hash_tab, int bar_p)
699 {
700 populate_or_checksum_helper (menu, path, descriptor, hash_tab, bar_p, 1);
701 }
702
703 static unsigned long
704 checksum_menu (Lisp_Object descriptor)
705 {
706 return populate_or_checksum_helper (NULL, Qnil, descriptor, Qunbound, 0, 0);
635 } 707 }
636 708
637 static Lisp_Object 709 static Lisp_Object
638 find_menu (Lisp_Object desc, Lisp_Object path) 710 find_menu (Lisp_Object desc, Lisp_Object path)
639 { 711 {
664 736
665 if (NILP (desc) && menubar != NULL) 737 if (NILP (desc) && menubar != NULL)
666 { 738 {
667 /* Menubar has gone */ 739 /* Menubar has gone */
668 FRAME_MSWINDOWS_MENU_HASHTABLE(f) = Qnil; 740 FRAME_MSWINDOWS_MENU_HASHTABLE(f) = Qnil;
741 SetMenu (FRAME_MSWINDOWS_HANDLE (f), NULL);
669 DestroyMenu (menubar); 742 DestroyMenu (menubar);
670 DrawMenuBar (FRAME_MSWINDOWS_HANDLE (f)); 743 DrawMenuBar (FRAME_MSWINDOWS_HANDLE (f));
671 return; 744 return;
672 } 745 }
673 746
682 { 755 {
683 /* We did not have the bar and are not going to */ 756 /* We did not have the bar and are not going to */
684 return; 757 return;
685 } 758 }
686 759
687 /* Now we have to check if the menubar has really changed */ 760 /* Now we bail out if the menubar has not changed */
688 /* #### For now we do not though */ 761 if (FRAME_MSWINDOWS_MENU_CHECKSUM(f) == checksum_menu (desc))
689 762 return;
690 /* We cannot re-create the menu, cause WM_INITMENU does not like that.
691 We'll clear it instead. */
692 empty_menu (menubar, 0);
693 763
694 populate: 764 populate:
695 /* Come with empty hash table */ 765 /* Come with empty hash table */
696 if (NILP (FRAME_MSWINDOWS_MENU_HASHTABLE(f))) 766 if (NILP (FRAME_MSWINDOWS_MENU_HASHTABLE(f)))
697 FRAME_MSWINDOWS_MENU_HASHTABLE(f) = Fmake_hashtable (make_int (50), Qequal); 767 FRAME_MSWINDOWS_MENU_HASHTABLE(f) = Fmake_hashtable (make_int (50), Qequal);
702 FRAME_MSWINDOWS_MENU_HASHTABLE(f)); 772 FRAME_MSWINDOWS_MENU_HASHTABLE(f));
703 populate_menu (menubar, Qnil, desc, 773 populate_menu (menubar, Qnil, desc,
704 FRAME_MSWINDOWS_MENU_HASHTABLE(f), 1); 774 FRAME_MSWINDOWS_MENU_HASHTABLE(f), 1);
705 SetMenu (FRAME_MSWINDOWS_HANDLE (f), menubar); 775 SetMenu (FRAME_MSWINDOWS_HANDLE (f), menubar);
706 DrawMenuBar (FRAME_MSWINDOWS_HANDLE (f)); 776 DrawMenuBar (FRAME_MSWINDOWS_HANDLE (f));
777
778 FRAME_MSWINDOWS_MENU_CHECKSUM(f) = checksum_menu (desc);
707 } 779 }
708 780
709 static void 781 static void
710 prune_menubar (struct frame *f) 782 prune_menubar (struct frame *f)
711 { 783 {
713 Lisp_Object desc = current_frame_menubar (f); 785 Lisp_Object desc = current_frame_menubar (f);
714 if (menubar == NULL) 786 if (menubar == NULL)
715 return; 787 return;
716 788
717 /* #### If a filter function has set desc to Qnil, this abort() 789 /* #### If a filter function has set desc to Qnil, this abort()
718 triggers. To resolve, we must prevent explicitely filters from 790 triggers. To resolve, we must prevent filters explicitely from
719 mangling with te active menu. In apply_filter probably? 791 mangling with the active menu. In apply_filter probably?
720 Is copy-tree on the whole menu too expensive? */ 792 Is copy-tree on the whole menu too expensive? */
721 if (NILP(desc)) 793 if (NILP(desc))
722 /* abort(); */ 794 /* abort(); */
723 return; 795 return;
724 796
740 */ 812 */
741 static void 813 static void
742 menu_cleanup (struct frame *f) 814 menu_cleanup (struct frame *f)
743 { 815 {
744 /* This function can GC */ 816 /* This function can GC */
745 if (!NILP (current_tracking_popup)) 817 current_menudesc = Qnil;
746 { 818 current_hashtable = Qnil;
747 current_tracking_popup = Qnil; 819 prune_menubar (f);
748 current_popup_hash_table = Qnil;
749 }
750 else
751 prune_menubar (f);
752 } 820 }
753 821
754 822
755 /*------------------------------------------------------------------------*/ 823 /*------------------------------------------------------------------------*/
756 /* Message handlers */ 824 /* Message handlers */
759 unsafe_handle_wm_initmenupopup_1 (HMENU menu, struct frame* f) 827 unsafe_handle_wm_initmenupopup_1 (HMENU menu, struct frame* f)
760 { 828 {
761 /* This function can call lisp, beat dogs and stick chewing gum to 829 /* This function can call lisp, beat dogs and stick chewing gum to
762 everything! */ 830 everything! */
763 831
764 Lisp_Object path, desc, hash_tab; 832 Lisp_Object path, desc;
765 struct gcpro gcpro1; 833 struct gcpro gcpro1;
766 834
767 if (!NILP (current_tracking_popup))
768 {
769 desc = current_tracking_popup;
770 hash_tab = current_popup_hash_table;
771 }
772 else
773 {
774 desc = current_frame_menubar (f);
775 hash_tab = FRAME_MSWINDOWS_MENU_HASHTABLE(f);
776 }
777
778 /* Find which guy is going to explode */ 835 /* Find which guy is going to explode */
779 path = Fgethash (hmenu_to_lisp_object (menu), hash_tab, Qunbound); 836 path = Fgethash (hmenu_to_lisp_object (menu), current_hashtable, Qunbound);
780 assert (!UNBOUNDP (path)); 837 assert (!UNBOUNDP (path));
838 #ifdef DEBUG_XEMACS
839 /* Allow to continue in a debugger after assert - not so fatal */
840 if (UNBOUNDP (path))
841 error ("internal menu error");
842 #endif
781 843
782 /* Now find a desc chunk for it. If none, then probably menu open 844 /* Now find a desc chunk for it. If none, then probably menu open
783 hook has played too much games around stuff */ 845 hook has played too much games around stuff */
846 desc = current_menudesc;
784 if (!NILP (path)) 847 if (!NILP (path))
785 { 848 {
786 desc = find_menu (desc, path); 849 desc = find_menu (desc, path);
787 if (NILP (desc)) 850 if (NILP (desc))
788 signal_simple_error ("this menu does not exist any more", path); 851 signal_simple_error ("This menu does not exist any more", path);
789 } 852 }
790 853
791 /* Now, stuff it */ 854 /* Now, stuff it */
792 /* DESC may be generated by filter, so we have to gcpro it */ 855 /* DESC may be generated by filter, so we have to gcpro it */
793 GCPRO1 (desc); 856 GCPRO1 (desc);
794 populate_menu (menu, path, desc, hash_tab, 0); 857 populate_menu (menu, path, desc, current_hashtable, 0);
795 UNGCPRO; 858 UNGCPRO;
796 return Qt; 859 return Qt;
797 } 860 }
798 861
799 static Lisp_Object 862 static Lisp_Object
804 the activate-menubar-hook is now mostly obsolete. */ 867 the activate-menubar-hook is now mostly obsolete. */
805 868
806 /* We simply ignore return value. In any case, we construct the bar 869 /* We simply ignore return value. In any case, we construct the bar
807 on the fly */ 870 on the fly */
808 run_hook (Vactivate_menubar_hook); 871 run_hook (Vactivate_menubar_hook);
809 872
810 update_frame_menubar_maybe (f); 873 update_frame_menubar_maybe (f);
874
875 current_menudesc = current_frame_menubar (f);
876 current_hashtable = FRAME_MSWINDOWS_MENU_HASHTABLE(f);
877 assert (HASHTABLEP (current_hashtable));
878
811 return Qt; 879 return Qt;
812 } 880 }
813
814 881
815 #ifdef KKM_DOES_NOT_LIKE_UNDOCS_SOMETIMES 882 #ifdef KKM_DOES_NOT_LIKE_UNDOCS_SOMETIMES
816 883
817 /* #### This may become wrong in future Windows */ 884 /* #### This may become wrong in future Windows */
818 885
834 */ 901 */
835 Lisp_Object 902 Lisp_Object
836 mswindows_handle_wm_command (struct frame* f, WORD id) 903 mswindows_handle_wm_command (struct frame* f, WORD id)
837 { 904 {
838 /* Try to map the command id through the proper hash table */ 905 /* Try to map the command id through the proper hash table */
839 Lisp_Object hash_tab, command, funcsym, frame; 906 Lisp_Object command, funcsym, frame;
840 struct gcpro gcpro1; 907 struct gcpro gcpro1;
841 908
842 if (!NILP (current_tracking_popup)) 909 command = Fgethash (make_int (id), current_hashtable, Qunbound);
843 hash_tab = current_popup_hash_table;
844 else
845 hash_tab = FRAME_MSWINDOWS_MENU_HASHTABLE(f);
846
847 command = Fgethash (make_int (id), hash_tab, Qunbound);
848 if (UNBOUNDP (command)) 910 if (UNBOUNDP (command))
849 { 911 {
850 menu_cleanup (f); 912 menu_cleanup (f);
851 return Qnil; 913 return Qnil;
852 } 914 }
856 any more */ 918 any more */
857 GCPRO1 (command); 919 GCPRO1 (command);
858 menu_cleanup (f); 920 menu_cleanup (f);
859 921
860 /* Ok, this is our one. Enqueue it. */ 922 /* Ok, this is our one. Enqueue it. */
861 #if 0
862 if (SYMBOLP (command))
863 Fcall_interactively (command, Qnil, Qnil);
864 else if (CONSP (command))
865 Feval (command);
866 else
867 signal_simple_error ("illegal callback", command);
868 #endif
869 if (SYMBOLP (command)) 923 if (SYMBOLP (command))
870 funcsym = Qcall_interactively; 924 funcsym = Qcall_interactively;
871 else if (CONSP (command)) 925 else if (CONSP (command))
872 funcsym = Qeval; 926 funcsym = Qeval;
873 else 927 else
874 signal_simple_error ("illegal callback", command); 928 signal_simple_error ("Illegal callback", command);
875 929
876 XSETFRAME (frame, f); 930 XSETFRAME (frame, f);
877 enqueue_misc_user_event (frame, funcsym, command); 931 enqueue_misc_user_event (frame, funcsym, command);
932
933 /* Needs good bump also, for WM_COMMAND may have been dispatched from
934 mswindows_need_event, which will block again despite new command
935 event has arrived */
936 mswindows_enqueue_magic_event (FRAME_MSWINDOWS_HANDLE(f),
937 XM_BUMPQUEUE);
878 938
879 UNGCPRO; /* command */ 939 UNGCPRO; /* command */
880 return Qt; 940 return Qt;
881 } 941 }
882 942
916 wm_initmenu_frame = frm; 976 wm_initmenu_frame = frm;
917 return mswindows_protect_modal_loop (unsafe_handle_wm_initmenupopup, Qnil); 977 return mswindows_protect_modal_loop (unsafe_handle_wm_initmenupopup, Qnil);
918 } 978 }
919 979
920 Lisp_Object 980 Lisp_Object
921 mswindows_handle_wm_initmenu (struct frame* f) 981 mswindows_handle_wm_initmenu (HMENU hmenu, struct frame* f)
922 { 982 {
923 wm_initmenu_frame = f; 983 /* Handle only frame menubar, ignore if from popup or system menu */
924 return mswindows_protect_modal_loop (unsafe_handle_wm_initmenu, Qnil); 984 if (GetMenu (FRAME_MSWINDOWS_HANDLE(f)) == hmenu)
985 {
986 wm_initmenu_frame = f;
987 return mswindows_protect_modal_loop (unsafe_handle_wm_initmenu, Qnil);
988 }
989 return Qt;
925 } 990 }
926 991
927 Lisp_Object 992 Lisp_Object
928 mswindows_handle_wm_exitmenuloop (struct frame* f) 993 mswindows_handle_wm_exitmenuloop (struct frame* f)
929 { 994 {
990 pt.x = pt.y = 10; 1055 pt.x = pt.y = 10;
991 1056
992 if (SYMBOLP (menu_desc)) 1057 if (SYMBOLP (menu_desc))
993 menu_desc = Fsymbol_value (menu_desc); 1058 menu_desc = Fsymbol_value (menu_desc);
994 1059
995 current_tracking_popup = menu_desc; 1060 current_menudesc = menu_desc;
996 current_popup_hash_table = Fmake_hashtable (make_int(10), Qequal); 1061 current_hashtable = Fmake_hashtable (make_int(10), Qequal);
997 menu = create_empty_popup_menu(); 1062 menu = create_empty_popup_menu();
998 Fputhash (hmenu_to_lisp_object (menu), Qnil, current_popup_hash_table); 1063 Fputhash (hmenu_to_lisp_object (menu), Qnil, current_hashtable);
999 1064
1000 ok = TrackPopupMenu (menu, TPM_LEFTALIGN | TPM_LEFTBUTTON, 1065 ok = TrackPopupMenu (menu,
1066 TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON,
1001 pt.x, pt.y, 0, 1067 pt.x, pt.y, 0,
1002 FRAME_MSWINDOWS_HANDLE (f), NULL); 1068 FRAME_MSWINDOWS_HANDLE (f), NULL);
1003 1069
1004 DestroyMenu (menu); 1070 DestroyMenu (menu);
1005 1071
1007 mswindows_unmodalize_signal_maybe (); 1073 mswindows_unmodalize_signal_maybe ();
1008 1074
1009 /* This is probably the only real reason for failure */ 1075 /* This is probably the only real reason for failure */
1010 if (!ok) { 1076 if (!ok) {
1011 menu_cleanup (f); 1077 menu_cleanup (f);
1012 signal_simple_error ("cannot track popup menu while in menu", 1078 signal_simple_error ("Cannot track popup menu while in menu",
1013 menu_desc); 1079 menu_desc);
1014 } 1080 }
1015 } 1081 }
1016 1082
1017 1083
1033 } 1099 }
1034 1100
1035 void 1101 void
1036 vars_of_menubar_mswindows (void) 1102 vars_of_menubar_mswindows (void)
1037 { 1103 {
1038 current_tracking_popup = Qnil; 1104 current_menudesc = Qnil;
1039 current_popup_hash_table = Qnil; 1105 current_hashtable = Qnil;
1040 1106
1041 staticpro (&current_tracking_popup); 1107 staticpro (&current_menudesc);
1042 staticpro (&current_popup_hash_table); 1108 staticpro (&current_hashtable);
1043 1109
1044 Fprovide (intern ("mswindows-menubars")); 1110 Fprovide (intern ("mswindows-menubars"));
1045 } 1111 }