diff options
| author | Richard M. Stallman | 1995-04-14 18:36:40 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1995-04-14 18:36:40 +0000 |
| commit | aa669defddb849e4ac3f1f3b49a74338495956b7 (patch) | |
| tree | 120df41f2881bf2f7069d09afd9eaac367b5806f /src | |
| parent | f344058994facf0c7f9f7e58c1d33e4b7f5145a8 (diff) | |
| download | emacs-aa669defddb849e4ac3f1f3b49a74338495956b7.tar.gz emacs-aa669defddb849e4ac3f1f3b49a74338495956b7.zip | |
(popup_get_selection): Queue up events that aren't
for the menu, and process them afterward. New arg dpyinfo.
(set_frame_menubar): Use inhibit_garbage_collection.
[USE_X_TOOLKIT] (xmenu_show): Delete the queue code here.
Pass dpyinfo to popup_get_selection.
Don't call lw_destroy_all_widgets.
[USE_X_TOOLKIT] (xdialog_show): Simplify using popup_get_selection.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xmenu.c | 149 |
1 files changed, 65 insertions, 84 deletions
diff --git a/src/xmenu.c b/src/xmenu.c index fd7c9a3cecb..224fc7fea66 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -1049,12 +1049,25 @@ on the left of the dialog box and all following items on the right.\n\ | |||
| 1049 | 1049 | ||
| 1050 | NOTE: All calls to popup_get_selection() should be protected | 1050 | NOTE: All calls to popup_get_selection() should be protected |
| 1051 | with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */ | 1051 | with BLOCK_INPUT, UNBLOCK_INPUT wrappers. */ |
| 1052 | |||
| 1052 | void | 1053 | void |
| 1053 | popup_get_selection (initial_event) | 1054 | popup_get_selection (initial_event, dpyinfo) |
| 1054 | XEvent *initial_event; | 1055 | XEvent *initial_event; |
| 1056 | struct x_display_info *dpyinfo; | ||
| 1055 | { | 1057 | { |
| 1056 | XEvent event; | 1058 | XEvent event; |
| 1057 | 1059 | ||
| 1060 | /* Define a queue to save up for later unreading | ||
| 1061 | all X events that don't pertain to the menu. */ | ||
| 1062 | struct event_queue | ||
| 1063 | { | ||
| 1064 | XEvent event; | ||
| 1065 | struct event_queue *next; | ||
| 1066 | }; | ||
| 1067 | |||
| 1068 | struct event_queue *queue = NULL; | ||
| 1069 | struct event_queue *queue_tmp; | ||
| 1070 | |||
| 1058 | if (initial_event) | 1071 | if (initial_event) |
| 1059 | event = *initial_event; | 1072 | event = *initial_event; |
| 1060 | else | 1073 | else |
| @@ -1062,14 +1075,52 @@ popup_get_selection (initial_event) | |||
| 1062 | 1075 | ||
| 1063 | while (1) | 1076 | while (1) |
| 1064 | { | 1077 | { |
| 1078 | /* Handle expose events for editor frames right away. */ | ||
| 1079 | if (event.type == Expose) | ||
| 1080 | process_expose_from_menu (event); | ||
| 1081 | /* Make sure we don't consider buttons grabbed after menu goes. */ | ||
| 1082 | else if (event.type == ButtonRelease | ||
| 1083 | && dpyinfo->display == event.xbutton.display) | ||
| 1084 | dpyinfo->grabbed &= ~(1 << event.xbutton.button); | ||
| 1085 | |||
| 1086 | /* Queue all events not for this popup, | ||
| 1087 | except for Expose, which we've already handled. */ | ||
| 1088 | if (event.type != Expose | ||
| 1089 | && (event.xany.display != dpyinfo->display | ||
| 1090 | || ! x_any_window_to_frame (dpyinfo, event.xany.window))) | ||
| 1091 | { | ||
| 1092 | |||
| 1093 | queue_tmp = (struct event_queue *) malloc (sizeof (struct event_queue)); | ||
| 1094 | |||
| 1095 | if (queue_tmp != NULL) | ||
| 1096 | { | ||
| 1097 | queue_tmp->event = event; | ||
| 1098 | queue_tmp->next = queue; | ||
| 1099 | queue = queue_tmp; | ||
| 1100 | } | ||
| 1101 | } | ||
| 1102 | |||
| 1065 | XtDispatchEvent (&event); | 1103 | XtDispatchEvent (&event); |
| 1066 | if (!popup_activated()) | 1104 | |
| 1105 | if (!popup_activated ()) | ||
| 1067 | break; | 1106 | break; |
| 1068 | XtAppNextEvent (Xt_app_con, &event); | 1107 | XtAppNextEvent (Xt_app_con, &event); |
| 1069 | } | 1108 | } |
| 1109 | |||
| 1110 | /* Unread any events that we got but did not handle. */ | ||
| 1111 | while (queue != NULL) | ||
| 1112 | { | ||
| 1113 | queue_tmp = queue; | ||
| 1114 | XPutBackEvent (queue_tmp->event.xany.display, &queue_tmp->event); | ||
| 1115 | queue = queue_tmp->next; | ||
| 1116 | free ((char *)queue_tmp); | ||
| 1117 | /* Cause these events to get read as soon as we UNBLOCK_INPUT. */ | ||
| 1118 | interrupt_input_pending = 1; | ||
| 1119 | } | ||
| 1070 | } | 1120 | } |
| 1071 | 1121 | ||
| 1072 | /* Detect if a dialog or menu has been posted. */ | 1122 | /* Detect if a dialog or menu has been posted. */ |
| 1123 | |||
| 1073 | int | 1124 | int |
| 1074 | popup_activated () | 1125 | popup_activated () |
| 1075 | { | 1126 | { |
| @@ -1427,10 +1478,11 @@ set_frame_menubar (f, first_time) | |||
| 1427 | widget_value *wv, *first_wv, *prev_wv = 0; | 1478 | widget_value *wv, *first_wv, *prev_wv = 0; |
| 1428 | int i; | 1479 | int i; |
| 1429 | int id; | 1480 | int id; |
| 1481 | int count; | ||
| 1430 | 1482 | ||
| 1431 | id = frame_vector_add_frame (f); | 1483 | count = inhibit_garbage_collection (); |
| 1432 | 1484 | ||
| 1433 | BLOCK_INPUT; | 1485 | id = frame_vector_add_frame (f); |
| 1434 | 1486 | ||
| 1435 | wv = malloc_widget_value (); | 1487 | wv = malloc_widget_value (); |
| 1436 | wv->name = "menubar"; | 1488 | wv->name = "menubar"; |
| @@ -1481,6 +1533,10 @@ set_frame_menubar (f, first_time) | |||
| 1481 | f->menu_bar_items_used = menu_items_used; | 1533 | f->menu_bar_items_used = menu_items_used; |
| 1482 | menu_items = Qnil; | 1534 | menu_items = Qnil; |
| 1483 | 1535 | ||
| 1536 | unbind_to (count, Qnil); | ||
| 1537 | |||
| 1538 | BLOCK_INPUT; | ||
| 1539 | |||
| 1484 | if (menubar_widget) | 1540 | if (menubar_widget) |
| 1485 | { | 1541 | { |
| 1486 | /* Disable resizing (done for Motif!) */ | 1542 | /* Disable resizing (done for Motif!) */ |
| @@ -1615,17 +1671,6 @@ xmenu_show (f, x, y, menubarp, for_click, keymaps, title, error) | |||
| 1615 | = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object)); | 1671 | = (Lisp_Object *) alloca (menu_items_used * sizeof (Lisp_Object)); |
| 1616 | int submenu_depth = 0; | 1672 | int submenu_depth = 0; |
| 1617 | 1673 | ||
| 1618 | /* Define a queue to save up for later unreading | ||
| 1619 | all X events that don't pertain to the menu. */ | ||
| 1620 | struct event_queue | ||
| 1621 | { | ||
| 1622 | XEvent event; | ||
| 1623 | struct event_queue *next; | ||
| 1624 | }; | ||
| 1625 | |||
| 1626 | struct event_queue *queue = NULL; | ||
| 1627 | struct event_queue *queue_tmp; | ||
| 1628 | |||
| 1629 | Position root_x, root_y; | 1674 | Position root_x, root_y; |
| 1630 | 1675 | ||
| 1631 | int first_pane; | 1676 | int first_pane; |
| @@ -1786,25 +1831,15 @@ xmenu_show (f, x, y, menubarp, for_click, keymaps, title, error) | |||
| 1786 | popup_activated_flag = 1; | 1831 | popup_activated_flag = 1; |
| 1787 | 1832 | ||
| 1788 | /* Process events that apply to the menu. */ | 1833 | /* Process events that apply to the menu. */ |
| 1789 | popup_get_selection ((XEvent *) 0); | 1834 | popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f)); |
| 1790 | 1835 | ||
| 1791 | pop_down: | 1836 | #if 0 |
| 1792 | /* fp turned off the following statement and wrote a comment | 1837 | /* fp turned off the following statement and wrote a comment |
| 1793 | that it is unnecessary--that the menu has already disappeared. | 1838 | that it is unnecessary--that the menu has already disappeared. |
| 1794 | I observer that is not so. -- rms. */ | 1839 | I observer that is not so. -- rms. */ |
| 1795 | /* Make sure the menu disappears. */ | 1840 | /* Make sure the menu disappears. */ |
| 1796 | lw_destroy_all_widgets (menu_id); | 1841 | lw_destroy_all_widgets (menu_id); |
| 1797 | 1842 | #endif | |
| 1798 | /* Unread any events that we got but did not handle. */ | ||
| 1799 | while (queue != NULL) | ||
| 1800 | { | ||
| 1801 | queue_tmp = queue; | ||
| 1802 | XPutBackEvent (FRAME_X_DISPLAY (f), &queue_tmp->event); | ||
| 1803 | queue = queue_tmp->next; | ||
| 1804 | free ((char *)queue_tmp); | ||
| 1805 | /* Cause these events to get read as soon as we UNBLOCK_INPUT. */ | ||
| 1806 | interrupt_input_pending = 1; | ||
| 1807 | } | ||
| 1808 | 1843 | ||
| 1809 | /* Find the selected item, and its pane, to return | 1844 | /* Find the selected item, and its pane, to return |
| 1810 | the proper value. */ | 1845 | the proper value. */ |
| @@ -1896,17 +1931,6 @@ xdialog_show (f, menubarp, keymaps, title, error) | |||
| 1896 | 1931 | ||
| 1897 | widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0; | 1932 | widget_value *wv, *save_wv = 0, *first_wv = 0, *prev_wv = 0; |
| 1898 | 1933 | ||
| 1899 | /* Define a queue to save up for later unreading | ||
| 1900 | all X events that don't pertain to the menu. */ | ||
| 1901 | struct event_queue | ||
| 1902 | { | ||
| 1903 | XEvent event; | ||
| 1904 | struct event_queue *next; | ||
| 1905 | }; | ||
| 1906 | |||
| 1907 | struct event_queue *queue = NULL; | ||
| 1908 | struct event_queue *queue_tmp; | ||
| 1909 | |||
| 1910 | /* Number of elements seen so far, before boundary. */ | 1934 | /* Number of elements seen so far, before boundary. */ |
| 1911 | int left_count = 0; | 1935 | int left_count = 0; |
| 1912 | /* 1 means we've seen the boundary between left-hand elts and right-hand. */ | 1936 | /* 1 means we've seen the boundary between left-hand elts and right-hand. */ |
| @@ -2024,53 +2048,10 @@ xdialog_show (f, menubarp, keymaps, title, error) | |||
| 2024 | 2048 | ||
| 2025 | /* Display the menu. */ | 2049 | /* Display the menu. */ |
| 2026 | lw_pop_up_all_widgets (dialog_id); | 2050 | lw_pop_up_all_widgets (dialog_id); |
| 2051 | popup_activated_flag = 1; | ||
| 2027 | 2052 | ||
| 2028 | /* Process events that apply to the menu. */ | 2053 | /* Process events that apply to the menu. */ |
| 2029 | while (1) | 2054 | popup_get_selection ((XEvent *) 0, FRAME_X_DISPLAY_INFO (f)); |
| 2030 | { | ||
| 2031 | XEvent event; | ||
| 2032 | |||
| 2033 | XtAppNextEvent (Xt_app_con, &event); | ||
| 2034 | if (event.type == ButtonRelease) | ||
| 2035 | { | ||
| 2036 | XtDispatchEvent (&event); | ||
| 2037 | break; | ||
| 2038 | } | ||
| 2039 | else if (event.type == Expose) | ||
| 2040 | process_expose_from_menu (event); | ||
| 2041 | XtDispatchEvent (&event); | ||
| 2042 | if (XtWindowToWidget (FRAME_X_DISPLAY (f), event.xany.window) != menu) | ||
| 2043 | { | ||
| 2044 | queue_tmp = (struct event_queue *) malloc (sizeof (struct event_queue)); | ||
| 2045 | |||
| 2046 | if (queue_tmp != NULL) | ||
| 2047 | { | ||
| 2048 | queue_tmp->event = event; | ||
| 2049 | queue_tmp->next = queue; | ||
| 2050 | queue = queue_tmp; | ||
| 2051 | } | ||
| 2052 | } | ||
| 2053 | } | ||
| 2054 | pop_down: | ||
| 2055 | |||
| 2056 | #ifdef HAVE_X_WINDOWS | ||
| 2057 | /* State that no mouse buttons are now held. | ||
| 2058 | That is not necessarily true, but the fiction leads to reasonable | ||
| 2059 | results, and it is a pain to ask which are actually held now | ||
| 2060 | or track this in the loop above. */ | ||
| 2061 | FRAME_X_DISPLAY_INFO (f)->grabbed = 0; | ||
| 2062 | #endif | ||
| 2063 | |||
| 2064 | /* Unread any events that we got but did not handle. */ | ||
| 2065 | while (queue != NULL) | ||
| 2066 | { | ||
| 2067 | queue_tmp = queue; | ||
| 2068 | XPutBackEvent (FRAME_X_DISPLAY (f), &queue_tmp->event); | ||
| 2069 | queue = queue_tmp->next; | ||
| 2070 | free ((char *)queue_tmp); | ||
| 2071 | /* Cause these events to get read as soon as we UNBLOCK_INPUT. */ | ||
| 2072 | interrupt_input_pending = 1; | ||
| 2073 | } | ||
| 2074 | 2055 | ||
| 2075 | /* Find the selected item, and its pane, to return | 2056 | /* Find the selected item, and its pane, to return |
| 2076 | the proper value. */ | 2057 | the proper value. */ |