aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2013-09-21 17:53:04 +0300
committerEli Zaretskii2013-09-21 17:53:04 +0300
commitf0177f86f745ef86357214b110f9d98e4ed63b7a (patch)
tree85f8cbb3a930a39ea84bb02637279b7a783d37eb /src
parente11a3bd1d1848d0a3a2ac21a48360eb628127ed9 (diff)
downloademacs-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.c16
-rw-r--r--src/menu.c3
-rw-r--r--src/nsmenu.m3
-rw-r--r--src/term.c91
-rw-r--r--src/w32fns.c5
-rw-r--r--src/w32inevt.c7
-rw-r--r--src/w32menu.c11
-rw-r--r--src/xmenu.c22
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
1697Lisp_Object
1698read_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
2816static int menu_x, menu_y; 2816static int menu_x, menu_y;
2817 2817
2818static Lisp_Object Qright_char, Qleft_char, Qforward_char, Qbackward_char;
2819static Lisp_Object Qnext_line, Qprevious_line, Qnewline;
2820
2818typedef struct tty_menu_struct 2821typedef 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;