aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2013-05-23 13:25:42 -0400
committerStefan Monnier2013-05-23 13:25:42 -0400
commita7eb9b0fbeeaa24d803355fd90d462809916a2d8 (patch)
tree4696206f7fcaf47c38cea418a47ceeb4bb2f0264 /src
parentfe1eb856c5457a220c7c9cc96030247aaad2a0a3 (diff)
downloademacs-a7eb9b0fbeeaa24d803355fd90d462809916a2d8.tar.gz
emacs-a7eb9b0fbeeaa24d803355fd90d462809916a2d8.zip
Don't apply keyboard decoding to unread-command-events.
* src/keyboard.c: Apply keyboard decoding only to events that come directly from the tty, not from unread-command-events (bug#14368). (read_event_from_main_queue): New function, extracted from read_char). (read_decoded_char): Remove. (read_decoded_event_from_main_queue): New function to replace it. (read_char): Use it. (read_key_sequence): Use read_char rather than read_decoded_char. Fixes: debbugs:14403
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog8
-rw-r--r--src/keyboard.c291
2 files changed, 170 insertions, 129 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 8f97659db33..1d2af4b2a7d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,13 @@
12013-05-23 Stefan Monnier <monnier@iro.umontreal.ca> 12013-05-23 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * keyboard.c: Apply keyboard decoding only to events that come directly
4 from the tty, not from unread-command-events (bug#14368).
5 (read_event_from_main_queue): New function, extracted from read_char).
6 (read_decoded_char): Remove.
7 (read_decoded_event_from_main_queue): New function to replace it.
8 (read_char): Use it.
9 (read_key_sequence): Use read_char rather than read_decoded_char.
10
3 * keyboard.c (read_decoded_char): Don't decode under w32 (bug#14403). 11 * keyboard.c (read_decoded_char): Don't decode under w32 (bug#14403).
4 12
52013-05-22 Barry OReilly <gundaetiapo@gmail.com> (tiny change) 132013-05-22 Barry OReilly <gundaetiapo@gmail.com> (tiny change)
diff --git a/src/keyboard.c b/src/keyboard.c
index 7f863269a7e..c9ba39769cd 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -2222,6 +2222,157 @@ do { if (! polling_stopped_here) stop_polling (); \
2222do { if (polling_stopped_here) start_polling (); \ 2222do { if (polling_stopped_here) start_polling (); \
2223 polling_stopped_here = 0; } while (0) 2223 polling_stopped_here = 0; } while (0)
2224 2224
2225static Lisp_Object
2226read_event_from_main_queue (EMACS_TIME *end_time,
2227 sys_jmp_buf local_getcjmp,
2228 bool *used_mouse_menu)
2229{
2230 Lisp_Object c = Qnil;
2231 sys_jmp_buf save_jump;
2232 KBOARD *kb IF_LINT (= NULL);
2233
2234 start:
2235
2236 /* Read from the main queue, and if that gives us something we can't use yet,
2237 we put it on the appropriate side queue and try again. */
2238
2239 if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ()))
2240 return c;
2241
2242 /* Actually read a character, waiting if necessary. */
2243 save_getcjmp (save_jump);
2244 restore_getcjmp (local_getcjmp);
2245 if (!end_time)
2246 timer_start_idle ();
2247 c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
2248 restore_getcjmp (save_jump);
2249
2250 if (! NILP (c) && (kb != current_kboard))
2251 {
2252 Lisp_Object last = KVAR (kb, kbd_queue);
2253 if (CONSP (last))
2254 {
2255 while (CONSP (XCDR (last)))
2256 last = XCDR (last);
2257 if (!NILP (XCDR (last)))
2258 emacs_abort ();
2259 }
2260 if (!CONSP (last))
2261 kset_kbd_queue (kb, Fcons (c, Qnil));
2262 else
2263 XSETCDR (last, Fcons (c, Qnil));
2264 kb->kbd_queue_has_data = 1;
2265 c = Qnil;
2266 if (single_kboard)
2267 goto start;
2268 current_kboard = kb;
2269 /* This is going to exit from read_char
2270 so we had better get rid of this frame's stuff. */
2271 return make_number (-2);
2272 }
2273
2274 /* Terminate Emacs in batch mode if at eof. */
2275 if (noninteractive && INTEGERP (c) && XINT (c) < 0)
2276 Fkill_emacs (make_number (1));
2277
2278 if (INTEGERP (c))
2279 {
2280 /* Add in any extra modifiers, where appropriate. */
2281 if ((extra_keyboard_modifiers & CHAR_CTL)
2282 || ((extra_keyboard_modifiers & 0177) < ' '
2283 && (extra_keyboard_modifiers & 0177) != 0))
2284 XSETINT (c, make_ctrl_char (XINT (c)));
2285
2286 /* Transfer any other modifier bits directly from
2287 extra_keyboard_modifiers to c. Ignore the actual character code
2288 in the low 16 bits of extra_keyboard_modifiers. */
2289 XSETINT (c, XINT (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
2290 }
2291
2292 /* FIXME: Decode tty keyboard input here. */
2293 return c;
2294}
2295
2296
2297
2298/* Like `read_event_from_main_queue' but applies keyboard-coding-system
2299 to tty input. */
2300static Lisp_Object
2301read_decoded_event_from_main_queue (EMACS_TIME *end_time,
2302 sys_jmp_buf local_getcjmp,
2303 Lisp_Object prev_event,
2304 bool *used_mouse_menu)
2305{
2306#define MAX_ENCODED_BYTES 16
2307 Lisp_Object events[MAX_ENCODED_BYTES];
2308 int n = 0;
2309 while (true)
2310 {
2311 Lisp_Object nextevt
2312 = read_event_from_main_queue (end_time, local_getcjmp,
2313 used_mouse_menu);
2314#ifdef WINDOWSNT
2315 /* w32_console already returns decoded events. */
2316 return nextevt;
2317#else
2318 struct frame *frame = XFRAME (selected_frame);
2319 struct terminal *terminal = frame->terminal;
2320 if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame))
2321 /* Don't apply decoding if we're just reading a raw event
2322 (e.g. reading bytes sent by the xterm to specify the position
2323 of a mouse click). */
2324 && (!EQ (prev_event, Qt))
2325 && (TERMINAL_KEYBOARD_CODING (terminal)->common_flags
2326 & CODING_REQUIRE_DECODING_MASK)))
2327 return nextevt; /* No decoding needed. */
2328 else
2329 {
2330 int meta_key = terminal->display_info.tty->meta_key;
2331 eassert (n < MAX_ENCODED_BYTES);
2332 events[n++] = nextevt;
2333 if (NATNUMP (nextevt)
2334 && XINT (nextevt) < (meta_key == 1 ? 0x80 : 0x100))
2335 { /* An encoded byte sequence, let's try to decode it. */
2336 struct coding_system *coding
2337 = TERMINAL_KEYBOARD_CODING (terminal);
2338 unsigned char *src = alloca (n);
2339 int i;
2340 for (i = 0; i < n; i++)
2341 src[i] = XINT (events[i]);
2342 if (meta_key != 2)
2343 for (i = 0; i < n; i++)
2344 src[i] &= ~0x80;
2345 coding->destination = alloca (n * 4);
2346 coding->dst_bytes = n * 4;
2347 decode_coding_c_string (coding, src, n, Qnil);
2348 eassert (coding->produced_char <= n);
2349 if (coding->produced_char == 0)
2350 { /* The encoded sequence is incomplete. */
2351 if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow. */
2352 continue; /* Read on! */
2353 }
2354 else
2355 {
2356 const unsigned char *p = coding->destination;
2357 eassert (coding->carryover_bytes == 0);
2358 n = 0;
2359 while (n < coding->produced_char)
2360 events[n++] = make_number (STRING_CHAR_ADVANCE (p));
2361 }
2362 }
2363 /* Now `events' should hold decoded events.
2364 Normally, n should be equal to 1, but better not rely on it.
2365 We can only return one event here, so return the first we
2366 had and keep the others (if any) for later. */
2367 while (n > 1)
2368 Vunread_command_events
2369 = Fcons (events[--n], Vunread_command_events);
2370 return events[0];
2371 }
2372#endif
2373 }
2374}
2375
2225/* Read a character from the keyboard; call the redisplay if needed. */ 2376/* Read a character from the keyboard; call the redisplay if needed. */
2226/* commandflag 0 means do not autosave, but do redisplay. 2377/* commandflag 0 means do not autosave, but do redisplay.
2227 -1 means do not redisplay, but do autosave. 2378 -1 means do not redisplay, but do autosave.
@@ -2739,68 +2890,20 @@ read_char (int commandflag, Lisp_Object map,
2739 2890
2740 STOP_POLLING; 2891 STOP_POLLING;
2741 2892
2742 /* Finally, we read from the main queue,
2743 and if that gives us something we can't use yet, we put it on the
2744 appropriate side queue and try again. */
2745
2746 if (NILP (c)) 2893 if (NILP (c))
2747 { 2894 {
2748 KBOARD *kb IF_LINT (= NULL); 2895 c = read_decoded_event_from_main_queue (end_time, local_getcjmp,
2749 2896 prev_event, used_mouse_menu);
2750 if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ())) 2897 if (end_time && EMACS_TIME_LE (*end_time, current_emacs_time ()))
2751 goto exit; 2898 goto exit;
2752 2899 if (EQ (c, make_number (-2)))
2753 /* Actually read a character, waiting if necessary. */ 2900 {
2754 save_getcjmp (save_jump);
2755 restore_getcjmp (local_getcjmp);
2756 if (!end_time)
2757 timer_start_idle ();
2758 c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
2759 restore_getcjmp (save_jump);
2760
2761 if (! NILP (c) && (kb != current_kboard))
2762 {
2763 Lisp_Object last = KVAR (kb, kbd_queue);
2764 if (CONSP (last))
2765 {
2766 while (CONSP (XCDR (last)))
2767 last = XCDR (last);
2768 if (!NILP (XCDR (last)))
2769 emacs_abort ();
2770 }
2771 if (!CONSP (last))
2772 kset_kbd_queue (kb, Fcons (c, Qnil));
2773 else
2774 XSETCDR (last, Fcons (c, Qnil));
2775 kb->kbd_queue_has_data = 1;
2776 c = Qnil;
2777 if (single_kboard)
2778 goto wrong_kboard;
2779 current_kboard = kb;
2780 /* This is going to exit from read_char 2901 /* This is going to exit from read_char
2781 so we had better get rid of this frame's stuff. */ 2902 so we had better get rid of this frame's stuff. */
2782 UNGCPRO; 2903 UNGCPRO;
2783 return make_number (-2); 2904 return c;
2784 } 2905 }
2785 } 2906 }
2786
2787 /* Terminate Emacs in batch mode if at eof. */
2788 if (noninteractive && INTEGERP (c) && XINT (c) < 0)
2789 Fkill_emacs (make_number (1));
2790
2791 if (INTEGERP (c))
2792 {
2793 /* Add in any extra modifiers, where appropriate. */
2794 if ((extra_keyboard_modifiers & CHAR_CTL)
2795 || ((extra_keyboard_modifiers & 0177) < ' '
2796 && (extra_keyboard_modifiers & 0177) != 0))
2797 XSETINT (c, make_ctrl_char (XINT (c)));
2798
2799 /* Transfer any other modifier bits directly from
2800 extra_keyboard_modifiers to c. Ignore the actual character code
2801 in the low 16 bits of extra_keyboard_modifiers. */
2802 XSETINT (c, XINT (c) | (extra_keyboard_modifiers & ~0xff7f & ~CHAR_CTL));
2803 }
2804 2907
2805 non_reread: 2908 non_reread:
2806 2909
@@ -8690,76 +8793,6 @@ test_undefined (Lisp_Object binding)
8690 && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined))); 8793 && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined)));
8691} 8794}
8692 8795
8693/* Like `read_char' but applies keyboard-coding-system to tty input. */
8694static Lisp_Object
8695read_decoded_char (int commandflag, Lisp_Object map,
8696 Lisp_Object prev_event, bool *used_mouse_menu)
8697{
8698#define MAX_ENCODED_BYTES 16
8699 Lisp_Object events[MAX_ENCODED_BYTES];
8700 int n = 0;
8701 while (true)
8702 {
8703 Lisp_Object nextevt
8704 = read_char (commandflag, map, prev_event, used_mouse_menu, NULL);
8705#ifdef WINDOWSNT
8706 /* w32_console already returns decoded events. */
8707 return nextevt;
8708#else
8709 struct frame *frame = XFRAME (selected_frame);
8710 struct terminal *terminal = frame->terminal;
8711 if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame))
8712 && (TERMINAL_KEYBOARD_CODING (terminal)->common_flags
8713 & CODING_REQUIRE_DECODING_MASK)))
8714 return nextevt; /* No decoding needed. */
8715 else
8716 {
8717 int meta_key = terminal->display_info.tty->meta_key;
8718 eassert (n < MAX_ENCODED_BYTES);
8719 events[n++] = nextevt;
8720 if (NATNUMP (nextevt)
8721 && XINT (nextevt) < (meta_key == 1 ? 0x80 : 0x100))
8722 { /* An encoded byte sequence, let's try to decode it. */
8723 struct coding_system *coding
8724 = TERMINAL_KEYBOARD_CODING (terminal);
8725 unsigned char *src = alloca (n);
8726 int i;
8727 for (i = 0; i < n; i++)
8728 src[i] = XINT (events[i]);
8729 if (meta_key != 2)
8730 for (i = 0; i < n; i++)
8731 src[i] &= ~0x80;
8732 coding->destination = alloca (n * 4);
8733 coding->dst_bytes = n * 4;
8734 decode_coding_c_string (coding, src, n, Qnil);
8735 eassert (coding->produced_char <= n);
8736 if (coding->produced_char == 0)
8737 { /* The encoded sequence is incomplete. */
8738 if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow. */
8739 continue; /* Read on! */
8740 }
8741 else
8742 {
8743 const unsigned char *p = coding->destination;
8744 eassert (coding->carryover_bytes == 0);
8745 n = 0;
8746 while (n < coding->produced_char)
8747 events[n++] = make_number (STRING_CHAR_ADVANCE (p));
8748 }
8749 }
8750 /* Now `events' should hold decoded events.
8751 Normally, n should be equal to 1, but better not rely on it.
8752 We can only return one event here, so return the first we
8753 had and keep the others (if any) for later. */
8754 while (n > 1)
8755 Vunread_command_events
8756 = Fcons (events[--n], Vunread_command_events);
8757 return events[0];
8758 }
8759#endif
8760 }
8761}
8762
8763/* Read a sequence of keys that ends with a non prefix character, 8796/* Read a sequence of keys that ends with a non prefix character,
8764 storing it in KEYBUF, a buffer of size BUFSIZE. 8797 storing it in KEYBUF, a buffer of size BUFSIZE.
8765 Prompt with PROMPT. 8798 Prompt with PROMPT.
@@ -9037,9 +9070,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt,
9037 { 9070 {
9038 KBOARD *interrupted_kboard = current_kboard; 9071 KBOARD *interrupted_kboard = current_kboard;
9039 struct frame *interrupted_frame = SELECTED_FRAME (); 9072 struct frame *interrupted_frame = SELECTED_FRAME ();
9040 key = read_decoded_char (NILP (prompt), 9073 key = read_char (NILP (prompt),
9041 current_binding, last_nonmenu_event, 9074 current_binding, last_nonmenu_event,
9042 &used_mouse_menu); 9075 &used_mouse_menu, NULL);
9043 if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */ 9076 if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */
9044 /* When switching to a new tty (with a new keyboard), 9077 /* When switching to a new tty (with a new keyboard),
9045 read_char returns the new buffer, rather than -2 9078 read_char returns the new buffer, rather than -2