aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2017-11-20 18:05:33 +0000
committerAlan Mackenzie2017-11-20 18:08:43 +0000
commit5b5f441ff8986800aa5f175bb5db2dd90e642a3a (patch)
treef293bf9b7af092d518185b680e1522c9899b8d61
parent9c6791afcd2b60f069494031ef64a5aac70ca3f8 (diff)
downloademacs-5b5f441ff8986800aa5f175bb5db2dd90e642a3a.tar.gz
emacs-5b5f441ff8986800aa5f175bb5db2dd90e642a3a.zip
read_key_sequence: correct the handling of raw_keybuf in recursive calls
This fixes bug #29349. * src/keyboard.c (raw_keybuf_buffer, raw_keybuf_count_buffer): New variables pointed to by ... (raw_keybuf, raw_keybuf_count): Variables converted to pointers. (GROW_RAW_KEYBUF): enhance with a length argument. (command_loop_1): Initialize the above two pointers to their canonical values. (read_key_sequence): In recursive calls (for menus) the function was overwriting the raw event buffer of the outer call. Correct this by introducing a local buffer for each level of call, and setting this up to be used by the call to read_char. Any contents of this local buffer are appended to the global buffer afterwards.
-rw-r--r--src/keyboard.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 6b7a6bfa743..b18dc1abbe7 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -121,12 +121,17 @@ ptrdiff_t this_command_key_count;
121 121
122/* This vector is used as a buffer to record the events that were actually read 122/* This vector is used as a buffer to record the events that were actually read
123 by read_key_sequence. */ 123 by read_key_sequence. */
124static Lisp_Object raw_keybuf; 124static Lisp_Object raw_keybuf_buffer;
125static int raw_keybuf_count; 125static int raw_keybuf_count_buffer;
126 126static Lisp_Object *raw_keybuf = &raw_keybuf_buffer;
127#define GROW_RAW_KEYBUF \ 127static int *raw_keybuf_count = &raw_keybuf_count_buffer;
128 if (raw_keybuf_count == ASIZE (raw_keybuf)) \ 128
129 raw_keybuf = larger_vector (raw_keybuf, 1, -1) 129#define GROW_RAW_KEYBUF(inc) \
130 if (*raw_keybuf_count > ASIZE (*raw_keybuf) - (inc)) \
131 *raw_keybuf = \
132 larger_vector (*raw_keybuf, \
133 (inc) + *raw_keybuf_count - ASIZE (*raw_keybuf), \
134 -1)
130 135
131/* Number of elements of this_command_keys 136/* Number of elements of this_command_keys
132 that precede this key sequence. */ 137 that precede this key sequence. */
@@ -1365,6 +1370,8 @@ command_loop_1 (void)
1365 Vthis_command_keys_shift_translated = Qnil; 1370 Vthis_command_keys_shift_translated = Qnil;
1366 1371
1367 /* Read next key sequence; i gets its length. */ 1372 /* Read next key sequence; i gets its length. */
1373 raw_keybuf_count = &raw_keybuf_count_buffer; /* For safety */
1374 raw_keybuf = &raw_keybuf_buffer; /* Ditto */
1368 i = read_key_sequence (keybuf, ARRAYELTS (keybuf), 1375 i = read_key_sequence (keybuf, ARRAYELTS (keybuf),
1369 Qnil, 0, 1, 1, 0); 1376 Qnil, 0, 1, 1, 0);
1370 1377
@@ -8913,6 +8920,11 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
8913 /* How many keys there are in the current key sequence. */ 8920 /* How many keys there are in the current key sequence. */
8914 int t; 8921 int t;
8915 8922
8923 int *outer_raw_keybuf_count;
8924 Lisp_Object *outer_raw_keybuf;
8925 int inner_raw_keybuf_count_buffer;
8926 Lisp_Object inner_raw_keybuf_buffer = Fmake_vector (make_number (30), Qnil);
8927
8916 /* The length of the echo buffer when we started reading, and 8928 /* The length of the echo buffer when we started reading, and
8917 the length of this_command_keys when we started reading. */ 8929 the length of this_command_keys when we started reading. */
8918 ptrdiff_t echo_start UNINIT; 8930 ptrdiff_t echo_start UNINIT;
@@ -8973,7 +8985,7 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
8973 /* List of events for which a fake prefix key has been generated. */ 8985 /* List of events for which a fake prefix key has been generated. */
8974 Lisp_Object fake_prefixed_keys = Qnil; 8986 Lisp_Object fake_prefixed_keys = Qnil;
8975 8987
8976 raw_keybuf_count = 0; 8988 *raw_keybuf_count = 0;
8977 8989
8978 last_nonmenu_event = Qnil; 8990 last_nonmenu_event = Qnil;
8979 8991
@@ -9145,11 +9157,23 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9145 { 9157 {
9146 KBOARD *interrupted_kboard = current_kboard; 9158 KBOARD *interrupted_kboard = current_kboard;
9147 struct frame *interrupted_frame = SELECTED_FRAME (); 9159 struct frame *interrupted_frame = SELECTED_FRAME ();
9160 int i;
9161 outer_raw_keybuf_count = raw_keybuf_count;
9162 outer_raw_keybuf = raw_keybuf;
9163 inner_raw_keybuf_count_buffer = 0;
9164 raw_keybuf_count = &inner_raw_keybuf_count_buffer;
9165 raw_keybuf = &inner_raw_keybuf_buffer;
9148 /* Calling read_char with COMMANDFLAG = -2 avoids 9166 /* Calling read_char with COMMANDFLAG = -2 avoids
9149 redisplay in read_char and its subroutines. */ 9167 redisplay in read_char and its subroutines. */
9150 key = read_char (prevent_redisplay ? -2 : NILP (prompt), 9168 key = read_char (prevent_redisplay ? -2 : NILP (prompt),
9151 current_binding, last_nonmenu_event, 9169 current_binding, last_nonmenu_event,
9152 &used_mouse_menu, NULL); 9170 &used_mouse_menu, NULL);
9171 raw_keybuf_count = outer_raw_keybuf_count;
9172 raw_keybuf = outer_raw_keybuf;
9173 GROW_RAW_KEYBUF (inner_raw_keybuf_count_buffer);
9174 for (i = 0; i < inner_raw_keybuf_count_buffer; i++)
9175 ASET (*raw_keybuf, (*raw_keybuf_count)++,
9176 AREF (inner_raw_keybuf_buffer, i));
9153 if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */ 9177 if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */
9154 /* When switching to a new tty (with a new keyboard), 9178 /* When switching to a new tty (with a new keyboard),
9155 read_char returns the new buffer, rather than -2 9179 read_char returns the new buffer, rather than -2
@@ -9257,9 +9281,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9257 && XINT (key) == quit_char 9281 && XINT (key) == quit_char
9258 && current_buffer != starting_buffer) 9282 && current_buffer != starting_buffer)
9259 { 9283 {
9260 GROW_RAW_KEYBUF; 9284 GROW_RAW_KEYBUF (1);
9261 ASET (raw_keybuf, raw_keybuf_count, key); 9285 ASET (*raw_keybuf, *raw_keybuf_count, key);
9262 raw_keybuf_count++; 9286 (*raw_keybuf_count)++;
9263 keybuf[t++] = key; 9287 keybuf[t++] = key;
9264 mock_input = t; 9288 mock_input = t;
9265 Vquit_flag = Qnil; 9289 Vquit_flag = Qnil;
@@ -9298,9 +9322,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9298 current_binding = active_maps (first_event); 9322 current_binding = active_maps (first_event);
9299 } 9323 }
9300 9324
9301 GROW_RAW_KEYBUF; 9325 GROW_RAW_KEYBUF (1);
9302 ASET (raw_keybuf, raw_keybuf_count, key); 9326 ASET (*raw_keybuf, *raw_keybuf_count, key);
9303 raw_keybuf_count++; 9327 (*raw_keybuf_count)++;
9304 } 9328 }
9305 9329
9306 /* Clicks in non-text areas get prefixed by the symbol 9330 /* Clicks in non-text areas get prefixed by the symbol
@@ -9346,8 +9370,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9346 && BUFFERP (XWINDOW (window)->contents) 9370 && BUFFERP (XWINDOW (window)->contents)
9347 && XBUFFER (XWINDOW (window)->contents) != current_buffer) 9371 && XBUFFER (XWINDOW (window)->contents) != current_buffer)
9348 { 9372 {
9349 ASET (raw_keybuf, raw_keybuf_count, key); 9373 GROW_RAW_KEYBUF (1);
9350 raw_keybuf_count++; 9374 ASET (*raw_keybuf, *raw_keybuf_count, key);
9375 (*raw_keybuf_count)++;
9351 keybuf[t] = key; 9376 keybuf[t] = key;
9352 mock_input = t + 1; 9377 mock_input = t + 1;
9353 9378
@@ -10120,7 +10145,7 @@ shows the events before all translations (except for input methods).
10120The value is always a vector. */) 10145The value is always a vector. */)
10121 (void) 10146 (void)
10122{ 10147{
10123 return Fvector (raw_keybuf_count, XVECTOR (raw_keybuf)->contents); 10148 return Fvector (*raw_keybuf_count, XVECTOR (*raw_keybuf)->contents);
10124} 10149}
10125 10150
10126DEFUN ("clear-this-command-keys", Fclear_this_command_keys, 10151DEFUN ("clear-this-command-keys", Fclear_this_command_keys,
@@ -11265,8 +11290,8 @@ syms_of_keyboard (void)
11265 this_command_keys = Fmake_vector (make_number (40), Qnil); 11290 this_command_keys = Fmake_vector (make_number (40), Qnil);
11266 staticpro (&this_command_keys); 11291 staticpro (&this_command_keys);
11267 11292
11268 raw_keybuf = Fmake_vector (make_number (30), Qnil); 11293 raw_keybuf_buffer = Fmake_vector (make_number (30), Qnil);
11269 staticpro (&raw_keybuf); 11294 staticpro (raw_keybuf);
11270 11295
11271 DEFSYM (Qcommand_execute, "command-execute"); 11296 DEFSYM (Qcommand_execute, "command-execute");
11272 DEFSYM (Qinternal_echo_keystrokes_prefix, "internal-echo-keystrokes-prefix"); 11297 DEFSYM (Qinternal_echo_keystrokes_prefix, "internal-echo-keystrokes-prefix");