diff options
| author | Stefan Monnier | 2013-03-10 21:17:40 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2013-03-10 21:17:40 -0400 |
| commit | cbae07d5e07f53472fa972cd31418a4fe851ac31 (patch) | |
| tree | 1d10110dc3408b650aba2e8f311f7e36f4074933 /src/keyboard.c | |
| parent | 819e2da92a18d7af03ccd9cf0a2e5b940eb7b54f (diff) | |
| download | emacs-cbae07d5e07f53472fa972cd31418a4fe851ac31.tar.gz emacs-cbae07d5e07f53472fa972cd31418a4fe851ac31.zip | |
* src/keyboard.c: Move keyboard decoding to read_key_sequence.
(decode_keyboard_code): Remove.
(tty_read_avail_input): Don't try to decode input.
(read_decoded_char): New function.
(read_key_sequence): Use it.
Diffstat (limited to 'src/keyboard.c')
| -rw-r--r-- | src/keyboard.c | 145 |
1 files changed, 69 insertions, 76 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index a66c28dc3d3..fe8b45a0130 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -6815,48 +6815,6 @@ gobble_input (void) | |||
| 6815 | return nread; | 6815 | return nread; |
| 6816 | } | 6816 | } |
| 6817 | 6817 | ||
| 6818 | static void | ||
| 6819 | decode_keyboard_code (struct tty_display_info *tty, | ||
| 6820 | struct coding_system *coding, | ||
| 6821 | unsigned char *buf, int nbytes) | ||
| 6822 | { | ||
| 6823 | unsigned char *src = buf; | ||
| 6824 | const unsigned char *p; | ||
| 6825 | int i; | ||
| 6826 | |||
| 6827 | if (nbytes == 0) | ||
| 6828 | return; | ||
| 6829 | if (tty->meta_key != 2) | ||
| 6830 | for (i = 0; i < nbytes; i++) | ||
| 6831 | buf[i] &= ~0x80; | ||
| 6832 | if (coding->carryover_bytes > 0) | ||
| 6833 | { | ||
| 6834 | src = alloca (coding->carryover_bytes + nbytes); | ||
| 6835 | memcpy (src, coding->carryover, coding->carryover_bytes); | ||
| 6836 | memcpy (src + coding->carryover_bytes, buf, nbytes); | ||
| 6837 | nbytes += coding->carryover_bytes; | ||
| 6838 | } | ||
| 6839 | coding->destination = alloca (nbytes * 4); | ||
| 6840 | coding->dst_bytes = nbytes * 4; | ||
| 6841 | decode_coding_c_string (coding, src, nbytes, Qnil); | ||
| 6842 | if (coding->produced_char == 0) | ||
| 6843 | return; | ||
| 6844 | for (i = 0, p = coding->destination; i < coding->produced_char; i++) | ||
| 6845 | { | ||
| 6846 | struct input_event event_buf; | ||
| 6847 | |||
| 6848 | EVENT_INIT (event_buf); | ||
| 6849 | event_buf.code = STRING_CHAR_ADVANCE (p); | ||
| 6850 | event_buf.kind = | ||
| 6851 | (ASCII_CHAR_P (event_buf.code) | ||
| 6852 | ? ASCII_KEYSTROKE_EVENT : MULTIBYTE_CHAR_KEYSTROKE_EVENT); | ||
| 6853 | /* See the comment in tty_read_avail_input. */ | ||
| 6854 | event_buf.frame_or_window = tty->top_frame; | ||
| 6855 | event_buf.arg = Qnil; | ||
| 6856 | kbd_buffer_store_event (&event_buf); | ||
| 6857 | } | ||
| 6858 | } | ||
| 6859 | |||
| 6860 | /* This is the tty way of reading available input. | 6818 | /* This is the tty way of reading available input. |
| 6861 | 6819 | ||
| 6862 | Note that each terminal device has its own `struct terminal' object, | 6820 | Note that each terminal device has its own `struct terminal' object, |
| @@ -7014,36 +6972,6 @@ tty_read_avail_input (struct terminal *terminal, | |||
| 7014 | #endif /* not MSDOS */ | 6972 | #endif /* not MSDOS */ |
| 7015 | #endif /* not WINDOWSNT */ | 6973 | #endif /* not WINDOWSNT */ |
| 7016 | 6974 | ||
| 7017 | if (TERMINAL_KEYBOARD_CODING (terminal)->common_flags | ||
| 7018 | & CODING_REQUIRE_DECODING_MASK) | ||
| 7019 | { | ||
| 7020 | struct coding_system *coding = TERMINAL_KEYBOARD_CODING (terminal); | ||
| 7021 | int from; | ||
| 7022 | |||
| 7023 | /* Decode the key sequence except for those with meta | ||
| 7024 | modifiers. */ | ||
| 7025 | for (i = from = 0; ; i++) | ||
| 7026 | if (i == nread || (tty->meta_key == 1 && (cbuf[i] & 0x80))) | ||
| 7027 | { | ||
| 7028 | struct input_event buf; | ||
| 7029 | |||
| 7030 | decode_keyboard_code (tty, coding, cbuf + from, i - from); | ||
| 7031 | if (i == nread) | ||
| 7032 | break; | ||
| 7033 | |||
| 7034 | EVENT_INIT (buf); | ||
| 7035 | buf.kind = ASCII_KEYSTROKE_EVENT; | ||
| 7036 | buf.modifiers = meta_modifier; | ||
| 7037 | buf.code = cbuf[i] & ~0x80; | ||
| 7038 | /* See the comment below. */ | ||
| 7039 | buf.frame_or_window = tty->top_frame; | ||
| 7040 | buf.arg = Qnil; | ||
| 7041 | kbd_buffer_store_event (&buf); | ||
| 7042 | from = i + 1; | ||
| 7043 | } | ||
| 7044 | return nread; | ||
| 7045 | } | ||
| 7046 | |||
| 7047 | for (i = 0; i < nread; i++) | 6975 | for (i = 0; i < nread; i++) |
| 7048 | { | 6976 | { |
| 7049 | struct input_event buf; | 6977 | struct input_event buf; |
| @@ -8783,6 +8711,71 @@ test_undefined (Lisp_Object binding) | |||
| 8783 | && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined))); | 8711 | && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined))); |
| 8784 | } | 8712 | } |
| 8785 | 8713 | ||
| 8714 | /* Like `read_char' but applies keyboard-coding-system to tty input. */ | ||
| 8715 | static Lisp_Object | ||
| 8716 | read_decoded_char (int commandflag, Lisp_Object map, | ||
| 8717 | Lisp_Object prev_event, bool *used_mouse_menu) | ||
| 8718 | { | ||
| 8719 | #define MAX_ENCODED_BYTES 16 | ||
| 8720 | Lisp_Object events[MAX_ENCODED_BYTES]; | ||
| 8721 | int n = 0; | ||
| 8722 | while (true) | ||
| 8723 | { | ||
| 8724 | Lisp_Object nextevt | ||
| 8725 | = read_char (commandflag, map, prev_event, used_mouse_menu, NULL); | ||
| 8726 | struct frame *frame = XFRAME (selected_frame); | ||
| 8727 | struct terminal *terminal = frame->terminal; | ||
| 8728 | if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame)) | ||
| 8729 | && (TERMINAL_KEYBOARD_CODING (terminal)->common_flags | ||
| 8730 | & CODING_REQUIRE_DECODING_MASK))) | ||
| 8731 | return nextevt; /* No decoding needed. */ | ||
| 8732 | else | ||
| 8733 | { | ||
| 8734 | int meta_key = terminal->display_info.tty->meta_key; | ||
| 8735 | eassert (n < MAX_ENCODED_BYTES); | ||
| 8736 | events[n++] = nextevt; | ||
| 8737 | if (NATNUMP (nextevt) | ||
| 8738 | && XINT (nextevt) < (meta_key == 1 ? 0x80 : 0x100)) | ||
| 8739 | { /* An encoded byte sequence, let's try to decode it. */ | ||
| 8740 | struct coding_system *coding | ||
| 8741 | = TERMINAL_KEYBOARD_CODING (terminal); | ||
| 8742 | unsigned char *src = alloca (n); | ||
| 8743 | int i; | ||
| 8744 | for (i = 0; i < n; i++) | ||
| 8745 | src[i] = XINT (events[i]); | ||
| 8746 | if (meta_key != 2) | ||
| 8747 | for (i = 0; i < n; i++) | ||
| 8748 | src[i] &= ~0x80; | ||
| 8749 | coding->destination = alloca (n * 4); | ||
| 8750 | coding->dst_bytes = n * 4; | ||
| 8751 | decode_coding_c_string (coding, src, n, Qnil); | ||
| 8752 | eassert (coding->produced_char <= n); | ||
| 8753 | if (coding->produced_char == 0) | ||
| 8754 | { /* The encoded sequence is incomplete. */ | ||
| 8755 | if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow. */ | ||
| 8756 | continue; /* Read on! */ | ||
| 8757 | } | ||
| 8758 | else | ||
| 8759 | { | ||
| 8760 | const unsigned char *p = coding->destination; | ||
| 8761 | eassert (coding->carryover_bytes == 0); | ||
| 8762 | n = 0; | ||
| 8763 | while (n < coding->produced_char) | ||
| 8764 | events[n++] = make_number (STRING_CHAR_ADVANCE (p)); | ||
| 8765 | } | ||
| 8766 | } | ||
| 8767 | /* Now `events' should hold decoded events. | ||
| 8768 | Normally, n should be equal to 1, but better not rely on it. | ||
| 8769 | We can only return one event here, so return the first we | ||
| 8770 | had and keep the others (if any) for later. */ | ||
| 8771 | while (n > 1) | ||
| 8772 | Vunread_command_events | ||
| 8773 | = Fcons (events[--n], Vunread_command_events); | ||
| 8774 | return events[0]; | ||
| 8775 | } | ||
| 8776 | } | ||
| 8777 | } | ||
| 8778 | |||
| 8786 | /* Read a sequence of keys that ends with a non prefix character, | 8779 | /* Read a sequence of keys that ends with a non prefix character, |
| 8787 | storing it in KEYBUF, a buffer of size BUFSIZE. | 8780 | storing it in KEYBUF, a buffer of size BUFSIZE. |
| 8788 | Prompt with PROMPT. | 8781 | Prompt with PROMPT. |
| @@ -9060,9 +9053,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, | |||
| 9060 | { | 9053 | { |
| 9061 | KBOARD *interrupted_kboard = current_kboard; | 9054 | KBOARD *interrupted_kboard = current_kboard; |
| 9062 | struct frame *interrupted_frame = SELECTED_FRAME (); | 9055 | struct frame *interrupted_frame = SELECTED_FRAME (); |
| 9063 | key = read_char (NILP (prompt), | 9056 | key = read_decoded_char (NILP (prompt), |
| 9064 | current_binding, last_nonmenu_event, | 9057 | current_binding, last_nonmenu_event, |
| 9065 | &used_mouse_menu, NULL); | 9058 | &used_mouse_menu); |
| 9066 | if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */ | 9059 | if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */ |
| 9067 | /* When switching to a new tty (with a new keyboard), | 9060 | /* When switching to a new tty (with a new keyboard), |
| 9068 | read_char returns the new buffer, rather than -2 | 9061 | read_char returns the new buffer, rather than -2 |
| @@ -10553,7 +10546,7 @@ See also `current-input-mode'. */) | |||
| 10553 | if (tty->flow_control != !NILP (flow)) | 10546 | if (tty->flow_control != !NILP (flow)) |
| 10554 | { | 10547 | { |
| 10555 | #ifndef DOS_NT | 10548 | #ifndef DOS_NT |
| 10556 | /* this causes startup screen to be restored and messes with the mouse */ | 10549 | /* This causes startup screen to be restored and messes with the mouse. */ |
| 10557 | reset_sys_modes (tty); | 10550 | reset_sys_modes (tty); |
| 10558 | #endif | 10551 | #endif |
| 10559 | 10552 | ||