diff options
| author | Eli Zaretskii | 2013-09-21 17:53:04 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2013-09-21 17:53:04 +0300 |
| commit | f0177f86f745ef86357214b110f9d98e4ed63b7a (patch) | |
| tree | 85f8cbb3a930a39ea84bb02637279b7a783d37eb /src | |
| parent | e11a3bd1d1848d0a3a2ac21a48360eb628127ed9 (diff) | |
| download | emacs-f0177f86f745ef86357214b110f9d98e4ed63b7a.tar.gz emacs-f0177f86f745ef86357214b110f9d98e4ed63b7a.zip | |
Fix infinite loop in menu input due to block_input.
Diffstat (limited to 'src')
| -rw-r--r-- | src/keyboard.c | 16 | ||||
| -rw-r--r-- | src/menu.c | 3 | ||||
| -rw-r--r-- | src/nsmenu.m | 3 | ||||
| -rw-r--r-- | src/term.c | 91 | ||||
| -rw-r--r-- | src/w32fns.c | 5 | ||||
| -rw-r--r-- | src/w32inevt.c | 7 | ||||
| -rw-r--r-- | src/w32menu.c | 11 | ||||
| -rw-r--r-- | src/xmenu.c | 22 |
8 files changed, 101 insertions, 57 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index 1150064a10f..8318d4eb3b1 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -1694,6 +1694,22 @@ command_loop_1 (void) | |||
| 1694 | } | 1694 | } |
| 1695 | } | 1695 | } |
| 1696 | 1696 | ||
| 1697 | Lisp_Object | ||
| 1698 | read_menu_command (void) | ||
| 1699 | { | ||
| 1700 | Lisp_Object cmd; | ||
| 1701 | Lisp_Object keybuf[30]; | ||
| 1702 | int i = read_key_sequence (keybuf, sizeof keybuf / sizeof keybuf[0], | ||
| 1703 | Qnil, 0, 1, 1); | ||
| 1704 | |||
| 1705 | if (! FRAME_LIVE_P (XFRAME (selected_frame))) | ||
| 1706 | Fkill_emacs (Qnil); | ||
| 1707 | if (i == 0 || i == -1) | ||
| 1708 | return Qnil; | ||
| 1709 | |||
| 1710 | return read_key_sequence_cmd; | ||
| 1711 | } | ||
| 1712 | |||
| 1697 | /* Adjust point to a boundary of a region that has such a property | 1713 | /* Adjust point to a boundary of a region that has such a property |
| 1698 | that should be treated intangible. For the moment, we check | 1714 | that should be treated intangible. For the moment, we check |
| 1699 | `composition', `display' and `invisible' properties. | 1715 | `composition', `display' and `invisible' properties. |
diff --git a/src/menu.c b/src/menu.c index cf6ceb58e7f..bbd0e70fe04 100644 --- a/src/menu.c +++ b/src/menu.c | |||
| @@ -1328,7 +1328,6 @@ no quit occurs and `x-popup-menu' returns nil. */) | |||
| 1328 | #endif | 1328 | #endif |
| 1329 | 1329 | ||
| 1330 | /* Display them in a menu. */ | 1330 | /* Display them in a menu. */ |
| 1331 | block_input (); | ||
| 1332 | 1331 | ||
| 1333 | /* FIXME: Use a terminal hook! */ | 1332 | /* FIXME: Use a terminal hook! */ |
| 1334 | #if defined HAVE_NTGUI | 1333 | #if defined HAVE_NTGUI |
| @@ -1358,8 +1357,6 @@ no quit occurs and `x-popup-menu' returns nil. */) | |||
| 1358 | selection = tty_menu_show (f, xpos, ypos, for_click, | 1357 | selection = tty_menu_show (f, xpos, ypos, for_click, |
| 1359 | keymaps, title, &error_name); | 1358 | keymaps, title, &error_name); |
| 1360 | 1359 | ||
| 1361 | unblock_input (); | ||
| 1362 | |||
| 1363 | #ifdef HAVE_NS | 1360 | #ifdef HAVE_NS |
| 1364 | unbind_to (specpdl_count, Qnil); | 1361 | unbind_to (specpdl_count, Qnil); |
| 1365 | #else | 1362 | #else |
diff --git a/src/nsmenu.m b/src/nsmenu.m index f9cd511efe9..697329df675 100644 --- a/src/nsmenu.m +++ b/src/nsmenu.m | |||
| @@ -833,6 +833,8 @@ ns_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, | |||
| 833 | ptrdiff_t specpdl_count = SPECPDL_INDEX (); | 833 | ptrdiff_t specpdl_count = SPECPDL_INDEX (); |
| 834 | widget_value *wv, *first_wv = 0; | 834 | widget_value *wv, *first_wv = 0; |
| 835 | 835 | ||
| 836 | block_input (); | ||
| 837 | |||
| 836 | p.x = x; p.y = y; | 838 | p.x = x; p.y = y; |
| 837 | 839 | ||
| 838 | /* now parse stage 2 as in ns_update_menubar */ | 840 | /* now parse stage 2 as in ns_update_menubar */ |
| @@ -1035,6 +1037,7 @@ ns_menu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, | |||
| 1035 | popup_activated_flag = 0; | 1037 | popup_activated_flag = 0; |
| 1036 | [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; | 1038 | [[FRAME_NS_VIEW (SELECTED_FRAME ()) window] makeKeyWindow]; |
| 1037 | 1039 | ||
| 1040 | unblock_input (); | ||
| 1038 | return tem; | 1041 | return tem; |
| 1039 | } | 1042 | } |
| 1040 | 1043 | ||
diff --git a/src/term.c b/src/term.c index 553cc1b6084..a600a3b33b4 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -2815,6 +2815,9 @@ static int menu_help_paneno, menu_help_itemno; | |||
| 2815 | 2815 | ||
| 2816 | static int menu_x, menu_y; | 2816 | static int menu_x, menu_y; |
| 2817 | 2817 | ||
| 2818 | static Lisp_Object Qright_char, Qleft_char, Qforward_char, Qbackward_char; | ||
| 2819 | static Lisp_Object Qnext_line, Qprevious_line, Qnewline; | ||
| 2820 | |||
| 2818 | typedef struct tty_menu_struct | 2821 | typedef struct tty_menu_struct |
| 2819 | { | 2822 | { |
| 2820 | int count; | 2823 | int count; |
| @@ -3171,51 +3174,31 @@ read_menu_input (struct frame *sf, int *x, int *y, bool *first_time) | |||
| 3171 | 3174 | ||
| 3172 | while (1) | 3175 | while (1) |
| 3173 | { | 3176 | { |
| 3174 | #if 0 | 3177 | #if 1 |
| 3175 | do { | 3178 | extern Lisp_Object read_menu_command (void); |
| 3176 | c = read_char (-2, Qnil, Qnil, NULL, NULL); | 3179 | Lisp_Object cmd = read_menu_command (); |
| 3177 | } while (BUFFERP (c) || (INTEGERP (c) && XINT (c) == -2)); | 3180 | int usable_input = 1; |
| 3178 | 3181 | int st = 0; | |
| 3179 | if (INTEGERP (c)) | 3182 | |
| 3183 | if (NILP (cmd)) | ||
| 3184 | return -1; | ||
| 3185 | if (EQ (cmd, Qright_char) || EQ (cmd, Qforward_char)) | ||
| 3186 | *x += 1; | ||
| 3187 | else if (EQ (cmd, Qleft_char) || EQ (cmd, Qbackward_char)) | ||
| 3188 | *x -= 1; | ||
| 3189 | else if (EQ (cmd, Qnext_line)) | ||
| 3190 | *y += 1; | ||
| 3191 | else if (EQ (cmd, Qprevious_line)) | ||
| 3192 | *y -= 1; | ||
| 3193 | else if (EQ (cmd, Qnewline)) | ||
| 3194 | st = 1; | ||
| 3195 | else | ||
| 3180 | { | 3196 | { |
| 3181 | int ch = XINT (c); | 3197 | usable_input = 0; |
| 3182 | int usable_input = 1; | 3198 | st = -1; |
| 3183 | |||
| 3184 | /* FIXME: Exceedingly primitive! Can we support arrow keys? */ | ||
| 3185 | switch (ch && ~CHAR_MODIFIER_MASK) | ||
| 3186 | { | ||
| 3187 | case 7: /* ^G */ | ||
| 3188 | return -1; | ||
| 3189 | case 6: /* ^F */ | ||
| 3190 | *x += 1; | ||
| 3191 | break; | ||
| 3192 | case 2: /* ^B */ | ||
| 3193 | *x -= 1; | ||
| 3194 | break; | ||
| 3195 | case 14: /* ^N */ | ||
| 3196 | *y += 1; | ||
| 3197 | break; | ||
| 3198 | case 16: /* ^P */ | ||
| 3199 | *y -= 1; | ||
| 3200 | break; | ||
| 3201 | default: | ||
| 3202 | usable_input = 0; | ||
| 3203 | break; | ||
| 3204 | } | ||
| 3205 | if (usable_input) | ||
| 3206 | sf->mouse_moved = 1; | ||
| 3207 | break; | ||
| 3208 | } | ||
| 3209 | |||
| 3210 | else if (EVENT_HAS_PARAMETERS (c)) | ||
| 3211 | { | ||
| 3212 | if (EQ (EVENT_HEAD (c), Qmouse_movement)) | ||
| 3213 | { | ||
| 3214 | } | ||
| 3215 | else if (EQ (EVENT_HEAD_KIND (EVENT_HEAD (c)), Qmouse_click)) | ||
| 3216 | { | ||
| 3217 | } | ||
| 3218 | } | 3199 | } |
| 3200 | if (usable_input) | ||
| 3201 | sf->mouse_moved = 1; | ||
| 3219 | #else | 3202 | #else |
| 3220 | int volatile dx = 0; | 3203 | int volatile dx = 0; |
| 3221 | int volatile dy = 0; | 3204 | int volatile dy = 0; |
| @@ -3225,11 +3208,11 @@ read_menu_input (struct frame *sf, int *x, int *y, bool *first_time) | |||
| 3225 | *y += dy; | 3208 | *y += dy; |
| 3226 | if (dx != 0 || dy != 0) | 3209 | if (dx != 0 || dy != 0) |
| 3227 | sf->mouse_moved = 1; | 3210 | sf->mouse_moved = 1; |
| 3211 | Sleep (300); | ||
| 3212 | #endif | ||
| 3228 | menu_x = *x; | 3213 | menu_x = *x; |
| 3229 | menu_y = *y; | 3214 | menu_y = *y; |
| 3230 | Sleep (300); | ||
| 3231 | return st; | 3215 | return st; |
| 3232 | #endif | ||
| 3233 | } | 3216 | } |
| 3234 | return 0; | 3217 | return 0; |
| 3235 | } | 3218 | } |
| @@ -3371,10 +3354,16 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx, | |||
| 3371 | while (!leave) | 3354 | while (!leave) |
| 3372 | { | 3355 | { |
| 3373 | int mouse_button_count = 3; /* FIXME */ | 3356 | int mouse_button_count = 3; /* FIXME */ |
| 3357 | int input_status; | ||
| 3374 | 3358 | ||
| 3375 | if (!mouse_visible) mouse_on (); | 3359 | if (!mouse_visible) mouse_on (); |
| 3376 | if (read_menu_input (sf, &x, &y, &first_time) == -1) | 3360 | input_status = read_menu_input (sf, &x, &y, &first_time); |
| 3377 | leave = 1; | 3361 | if (input_status) |
| 3362 | { | ||
| 3363 | if (input_status == -1) | ||
| 3364 | result = TTYM_NO_SELECT; | ||
| 3365 | leave = 1; | ||
| 3366 | } | ||
| 3378 | else if (sf->mouse_moved) | 3367 | else if (sf->mouse_moved) |
| 3379 | { | 3368 | { |
| 3380 | sf->mouse_moved = 0; | 3369 | sf->mouse_moved = 0; |
| @@ -4607,4 +4596,12 @@ bigger, or it may make it blink, or it may do nothing at all. */); | |||
| 4607 | 4596 | ||
| 4608 | encode_terminal_src = NULL; | 4597 | encode_terminal_src = NULL; |
| 4609 | encode_terminal_dst = NULL; | 4598 | encode_terminal_dst = NULL; |
| 4599 | |||
| 4600 | DEFSYM (Qright_char, "right-char"); | ||
| 4601 | DEFSYM (Qleft_char, "left-char"); | ||
| 4602 | DEFSYM (Qforward_char, "forward-char"); | ||
| 4603 | DEFSYM (Qbackward_char, "backward-char"); | ||
| 4604 | DEFSYM (Qprevious_line, "previous-line"); | ||
| 4605 | DEFSYM (Qnext_line, "next-line"); | ||
| 4606 | DEFSYM (Qnewline, "newline"); | ||
| 4610 | } | 4607 | } |
diff --git a/src/w32fns.c b/src/w32fns.c index b8c445a3a36..8ec911280a0 100644 --- a/src/w32fns.c +++ b/src/w32fns.c | |||
| @@ -5486,7 +5486,10 @@ show_hourglass (struct atimer *timer) | |||
| 5486 | f = SELECTED_FRAME (); | 5486 | f = SELECTED_FRAME (); |
| 5487 | 5487 | ||
| 5488 | if (!FRAME_W32_P (f)) | 5488 | if (!FRAME_W32_P (f)) |
| 5489 | return; | 5489 | { |
| 5490 | unblock_input (); | ||
| 5491 | return; | ||
| 5492 | } | ||
| 5490 | 5493 | ||
| 5491 | w32_show_hourglass (f); | 5494 | w32_show_hourglass (f); |
| 5492 | unblock_input (); | 5495 | unblock_input (); |
diff --git a/src/w32inevt.c b/src/w32inevt.c index ce36f291b00..3c41bec6bb5 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c | |||
| @@ -712,12 +712,17 @@ w32_console_read_socket (struct terminal *terminal, | |||
| 712 | while (nev > 0) | 712 | while (nev > 0) |
| 713 | { | 713 | { |
| 714 | struct input_event inev; | 714 | struct input_event inev; |
| 715 | /* Having a separate variable with this value makes | ||
| 716 | debugging easier, as otherwise the compiler might | ||
| 717 | rearrange the switch below in a way that makes it hard to | ||
| 718 | track the event type. */ | ||
| 719 | unsigned evtype = queue_ptr->EventType; | ||
| 715 | 720 | ||
| 716 | EVENT_INIT (inev); | 721 | EVENT_INIT (inev); |
| 717 | inev.kind = NO_EVENT; | 722 | inev.kind = NO_EVENT; |
| 718 | inev.arg = Qnil; | 723 | inev.arg = Qnil; |
| 719 | 724 | ||
| 720 | switch (queue_ptr->EventType) | 725 | switch (evtype) |
| 721 | { | 726 | { |
| 722 | case KEY_EVENT: | 727 | case KEY_EVENT: |
| 723 | add = key_event (&queue_ptr->Event.KeyEvent, &inev, &isdead); | 728 | add = key_event (&queue_ptr->Event.KeyEvent, &inev, &isdead); |
diff --git a/src/w32menu.c b/src/w32menu.c index 34020fa61d2..f804e830ac0 100644 --- a/src/w32menu.c +++ b/src/w32menu.c | |||
| @@ -682,6 +682,8 @@ w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps, | |||
| 682 | return Qnil; | 682 | return Qnil; |
| 683 | } | 683 | } |
| 684 | 684 | ||
| 685 | block_input (); | ||
| 686 | |||
| 685 | /* Create a tree of widget_value objects | 687 | /* Create a tree of widget_value objects |
| 686 | representing the panes and their items. */ | 688 | representing the panes and their items. */ |
| 687 | wv = xmalloc_widget_value (); | 689 | wv = xmalloc_widget_value (); |
| @@ -940,6 +942,7 @@ w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps, | |||
| 940 | if (!NILP (subprefix_stack[j])) | 942 | if (!NILP (subprefix_stack[j])) |
| 941 | entry = Fcons (subprefix_stack[j], entry); | 943 | entry = Fcons (subprefix_stack[j], entry); |
| 942 | } | 944 | } |
| 945 | unblock_input (); | ||
| 943 | return entry; | 946 | return entry; |
| 944 | } | 947 | } |
| 945 | i += MENU_ITEMS_ITEM_LENGTH; | 948 | i += MENU_ITEMS_ITEM_LENGTH; |
| @@ -947,9 +950,13 @@ w32_menu_show (struct frame *f, int x, int y, int for_click, int keymaps, | |||
| 947 | } | 950 | } |
| 948 | } | 951 | } |
| 949 | else if (!for_click) | 952 | else if (!for_click) |
| 950 | /* Make "Cancel" equivalent to C-g. */ | 953 | { |
| 951 | Fsignal (Qquit, Qnil); | 954 | unblock_input (); |
| 955 | /* Make "Cancel" equivalent to C-g. */ | ||
| 956 | Fsignal (Qquit, Qnil); | ||
| 957 | } | ||
| 952 | 958 | ||
| 959 | unblock_input (); | ||
| 953 | return Qnil; | 960 | return Qnil; |
| 954 | } | 961 | } |
| 955 | 962 | ||
diff --git a/src/xmenu.c b/src/xmenu.c index 823c63bfc6f..5d1f44e0f5a 100644 --- a/src/xmenu.c +++ b/src/xmenu.c | |||
| @@ -1618,6 +1618,8 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, | |||
| 1618 | return Qnil; | 1618 | return Qnil; |
| 1619 | } | 1619 | } |
| 1620 | 1620 | ||
| 1621 | block_input (); | ||
| 1622 | |||
| 1621 | /* Create a tree of widget_value objects | 1623 | /* Create a tree of widget_value objects |
| 1622 | representing the panes and their items. */ | 1624 | representing the panes and their items. */ |
| 1623 | wv = xmalloc_widget_value (); | 1625 | wv = xmalloc_widget_value (); |
| @@ -1857,6 +1859,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, | |||
| 1857 | if (!NILP (subprefix_stack[j])) | 1859 | if (!NILP (subprefix_stack[j])) |
| 1858 | entry = Fcons (subprefix_stack[j], entry); | 1860 | entry = Fcons (subprefix_stack[j], entry); |
| 1859 | } | 1861 | } |
| 1862 | unblock_input (); | ||
| 1860 | return entry; | 1863 | return entry; |
| 1861 | } | 1864 | } |
| 1862 | i += MENU_ITEMS_ITEM_LENGTH; | 1865 | i += MENU_ITEMS_ITEM_LENGTH; |
| @@ -1864,9 +1867,13 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, | |||
| 1864 | } | 1867 | } |
| 1865 | } | 1868 | } |
| 1866 | else if (!for_click) | 1869 | else if (!for_click) |
| 1867 | /* Make "Cancel" equivalent to C-g. */ | 1870 | { |
| 1868 | Fsignal (Qquit, Qnil); | 1871 | unblock_input (); |
| 1872 | /* Make "Cancel" equivalent to C-g. */ | ||
| 1873 | Fsignal (Qquit, Qnil); | ||
| 1874 | } | ||
| 1869 | 1875 | ||
| 1876 | unblock_input (); | ||
| 1870 | return Qnil; | 1877 | return Qnil; |
| 1871 | } | 1878 | } |
| 1872 | 1879 | ||
| @@ -2261,6 +2268,8 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, | |||
| 2261 | return Qnil; | 2268 | return Qnil; |
| 2262 | } | 2269 | } |
| 2263 | 2270 | ||
| 2271 | block_input (); | ||
| 2272 | |||
| 2264 | /* Figure out which root window F is on. */ | 2273 | /* Figure out which root window F is on. */ |
| 2265 | XGetGeometry (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &root, | 2274 | XGetGeometry (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &root, |
| 2266 | &dummy_int, &dummy_int, &dummy_uint, &dummy_uint, | 2275 | &dummy_int, &dummy_int, &dummy_uint, &dummy_uint, |
| @@ -2271,6 +2280,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, | |||
| 2271 | if (menu == NULL) | 2280 | if (menu == NULL) |
| 2272 | { | 2281 | { |
| 2273 | *error_name = "Can't create menu"; | 2282 | *error_name = "Can't create menu"; |
| 2283 | unblock_input (); | ||
| 2274 | return Qnil; | 2284 | return Qnil; |
| 2275 | } | 2285 | } |
| 2276 | 2286 | ||
| @@ -2314,6 +2324,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, | |||
| 2314 | { | 2324 | { |
| 2315 | XMenuDestroy (FRAME_X_DISPLAY (f), menu); | 2325 | XMenuDestroy (FRAME_X_DISPLAY (f), menu); |
| 2316 | *error_name = "Can't create pane"; | 2326 | *error_name = "Can't create pane"; |
| 2327 | unblock_input (); | ||
| 2317 | return Qnil; | 2328 | return Qnil; |
| 2318 | } | 2329 | } |
| 2319 | i += MENU_ITEMS_PANE_LENGTH; | 2330 | i += MENU_ITEMS_PANE_LENGTH; |
| @@ -2378,6 +2389,7 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, | |||
| 2378 | { | 2389 | { |
| 2379 | XMenuDestroy (FRAME_X_DISPLAY (f), menu); | 2390 | XMenuDestroy (FRAME_X_DISPLAY (f), menu); |
| 2380 | *error_name = "Can't add selection to menu"; | 2391 | *error_name = "Can't add selection to menu"; |
| 2392 | unblock_input (); | ||
| 2381 | return Qnil; | 2393 | return Qnil; |
| 2382 | } | 2394 | } |
| 2383 | i += MENU_ITEMS_ITEM_LENGTH; | 2395 | i += MENU_ITEMS_ITEM_LENGTH; |
| @@ -2504,10 +2516,14 @@ xmenu_show (struct frame *f, int x, int y, bool for_click, bool keymaps, | |||
| 2504 | /* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means | 2516 | /* Make "Cancel" equivalent to C-g unless FOR_CLICK (which means |
| 2505 | the menu was invoked with a mouse event as POSITION). */ | 2517 | the menu was invoked with a mouse event as POSITION). */ |
| 2506 | if (! for_click) | 2518 | if (! for_click) |
| 2507 | Fsignal (Qquit, Qnil); | 2519 | { |
| 2520 | unblock_input (); | ||
| 2521 | Fsignal (Qquit, Qnil); | ||
| 2522 | } | ||
| 2508 | break; | 2523 | break; |
| 2509 | } | 2524 | } |
| 2510 | 2525 | ||
| 2526 | unblock_input (); | ||
| 2511 | unbind_to (specpdl_count, Qnil); | 2527 | unbind_to (specpdl_count, Qnil); |
| 2512 | 2528 | ||
| 2513 | return entry; | 2529 | return entry; |