Mercurial > hg > xemacs-beta
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 (¤t_tracking_popup); | 1107 staticpro (¤t_menudesc); |
1042 staticpro (¤t_popup_hash_table); | 1108 staticpro (¤t_hashtable); |
1043 | 1109 |
1044 Fprovide (intern ("mswindows-menubars")); | 1110 Fprovide (intern ("mswindows-menubars")); |
1045 } | 1111 } |