From cbae07d5e07f53472fa972cd31418a4fe851ac31 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Sun, 10 Mar 2013 21:17:40 -0400 Subject: [PATCH] * 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. --- src/ChangeLog | 8 +++ src/keyboard.c | 145 +++++++++++++++++++++++------------------------- src/term.c | 2 +- src/termhooks.h | 28 +++++----- src/terminal.c | 2 +- src/textprop.c | 2 +- 6 files changed, 95 insertions(+), 92 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index b553c96a1db..2359311f98a 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2013-03-11 Stefan Monnier + + * 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. + 2013-03-10 Daniel Colascione * w32term.h (GUISTR, GUI_ENCODE_FILE, GUI_ENCODE_SYSTEM, GUI_FN) 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) return nread; } -static void -decode_keyboard_code (struct tty_display_info *tty, - struct coding_system *coding, - unsigned char *buf, int nbytes) -{ - unsigned char *src = buf; - const unsigned char *p; - int i; - - if (nbytes == 0) - return; - if (tty->meta_key != 2) - for (i = 0; i < nbytes; i++) - buf[i] &= ~0x80; - if (coding->carryover_bytes > 0) - { - src = alloca (coding->carryover_bytes + nbytes); - memcpy (src, coding->carryover, coding->carryover_bytes); - memcpy (src + coding->carryover_bytes, buf, nbytes); - nbytes += coding->carryover_bytes; - } - coding->destination = alloca (nbytes * 4); - coding->dst_bytes = nbytes * 4; - decode_coding_c_string (coding, src, nbytes, Qnil); - if (coding->produced_char == 0) - return; - for (i = 0, p = coding->destination; i < coding->produced_char; i++) - { - struct input_event event_buf; - - EVENT_INIT (event_buf); - event_buf.code = STRING_CHAR_ADVANCE (p); - event_buf.kind = - (ASCII_CHAR_P (event_buf.code) - ? ASCII_KEYSTROKE_EVENT : MULTIBYTE_CHAR_KEYSTROKE_EVENT); - /* See the comment in tty_read_avail_input. */ - event_buf.frame_or_window = tty->top_frame; - event_buf.arg = Qnil; - kbd_buffer_store_event (&event_buf); - } -} - /* This is the tty way of reading available input. Note that each terminal device has its own `struct terminal' object, @@ -7014,36 +6972,6 @@ tty_read_avail_input (struct terminal *terminal, #endif /* not MSDOS */ #endif /* not WINDOWSNT */ - if (TERMINAL_KEYBOARD_CODING (terminal)->common_flags - & CODING_REQUIRE_DECODING_MASK) - { - struct coding_system *coding = TERMINAL_KEYBOARD_CODING (terminal); - int from; - - /* Decode the key sequence except for those with meta - modifiers. */ - for (i = from = 0; ; i++) - if (i == nread || (tty->meta_key == 1 && (cbuf[i] & 0x80))) - { - struct input_event buf; - - decode_keyboard_code (tty, coding, cbuf + from, i - from); - if (i == nread) - break; - - EVENT_INIT (buf); - buf.kind = ASCII_KEYSTROKE_EVENT; - buf.modifiers = meta_modifier; - buf.code = cbuf[i] & ~0x80; - /* See the comment below. */ - buf.frame_or_window = tty->top_frame; - buf.arg = Qnil; - kbd_buffer_store_event (&buf); - from = i + 1; - } - return nread; - } - for (i = 0; i < nread; i++) { struct input_event buf; @@ -8783,6 +8711,71 @@ test_undefined (Lisp_Object binding) && EQ (Fcommand_remapping (binding, Qnil, Qnil), Qundefined))); } +/* Like `read_char' but applies keyboard-coding-system to tty input. */ +static Lisp_Object +read_decoded_char (int commandflag, Lisp_Object map, + Lisp_Object prev_event, bool *used_mouse_menu) +{ +#define MAX_ENCODED_BYTES 16 + Lisp_Object events[MAX_ENCODED_BYTES]; + int n = 0; + while (true) + { + Lisp_Object nextevt + = read_char (commandflag, map, prev_event, used_mouse_menu, NULL); + struct frame *frame = XFRAME (selected_frame); + struct terminal *terminal = frame->terminal; + if (!((FRAME_TERMCAP_P (frame) || FRAME_MSDOS_P (frame)) + && (TERMINAL_KEYBOARD_CODING (terminal)->common_flags + & CODING_REQUIRE_DECODING_MASK))) + return nextevt; /* No decoding needed. */ + else + { + int meta_key = terminal->display_info.tty->meta_key; + eassert (n < MAX_ENCODED_BYTES); + events[n++] = nextevt; + if (NATNUMP (nextevt) + && XINT (nextevt) < (meta_key == 1 ? 0x80 : 0x100)) + { /* An encoded byte sequence, let's try to decode it. */ + struct coding_system *coding + = TERMINAL_KEYBOARD_CODING (terminal); + unsigned char *src = alloca (n); + int i; + for (i = 0; i < n; i++) + src[i] = XINT (events[i]); + if (meta_key != 2) + for (i = 0; i < n; i++) + src[i] &= ~0x80; + coding->destination = alloca (n * 4); + coding->dst_bytes = n * 4; + decode_coding_c_string (coding, src, n, Qnil); + eassert (coding->produced_char <= n); + if (coding->produced_char == 0) + { /* The encoded sequence is incomplete. */ + if (n < MAX_ENCODED_BYTES) /* Avoid buffer overflow. */ + continue; /* Read on! */ + } + else + { + const unsigned char *p = coding->destination; + eassert (coding->carryover_bytes == 0); + n = 0; + while (n < coding->produced_char) + events[n++] = make_number (STRING_CHAR_ADVANCE (p)); + } + } + /* Now `events' should hold decoded events. + Normally, n should be equal to 1, but better not rely on it. + We can only return one event here, so return the first we + had and keep the others (if any) for later. */ + while (n > 1) + Vunread_command_events + = Fcons (events[--n], Vunread_command_events); + return events[0]; + } + } +} + /* Read a sequence of keys that ends with a non prefix character, storing it in KEYBUF, a buffer of size BUFSIZE. Prompt with PROMPT. @@ -9060,9 +9053,9 @@ read_key_sequence (Lisp_Object *keybuf, int bufsize, Lisp_Object prompt, { KBOARD *interrupted_kboard = current_kboard; struct frame *interrupted_frame = SELECTED_FRAME (); - key = read_char (NILP (prompt), - current_binding, last_nonmenu_event, - &used_mouse_menu, NULL); + key = read_decoded_char (NILP (prompt), + current_binding, last_nonmenu_event, + &used_mouse_menu); if ((INTEGERP (key) && XINT (key) == -2) /* wrong_kboard_jmpbuf */ /* When switching to a new tty (with a new keyboard), read_char returns the new buffer, rather than -2 @@ -10553,7 +10546,7 @@ See also `current-input-mode'. */) if (tty->flow_control != !NILP (flow)) { #ifndef DOS_NT - /* this causes startup screen to be restored and messes with the mouse */ + /* This causes startup screen to be restored and messes with the mouse. */ reset_sys_modes (tty); #endif diff --git a/src/term.c b/src/term.c index a31fd51084e..822b74aa44e 100644 --- a/src/term.c +++ b/src/term.c @@ -1321,7 +1321,7 @@ term_get_fkeys_1 (void) if (!KEYMAPP (KVAR (kboard, Vinput_decode_map))) kset_input_decode_map (kboard, Fmake_sparse_keymap (Qnil)); - for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++) + for (i = 0; i < (sizeof (keys) / sizeof (keys[0])); i++) { char *sequence = tgetstr (keys[i].cap, address); if (sequence) diff --git a/src/termhooks.h b/src/termhooks.h index 7385298d3d4..252dbabb6f9 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -382,7 +382,7 @@ struct terminal struct image_cache *image_cache; #endif /* HAVE_WINDOW_SYSTEM */ - /* Device-type dependent data shared amongst all frames on this terminal. */ + /* Device-type dependent data shared amongst all frames on this terminal. */ union display_info { struct tty_display_info *tty; /* termchar.h */ @@ -403,22 +403,22 @@ struct terminal the function `set-keyboard-coding-system'. */ struct coding_system *keyboard_coding; - /* Terminal characteristics. */ - /* XXX Are these really used on non-termcap displays? */ + /* Terminal characteristics. */ + /* XXX Are these really used on non-termcap displays? */ int must_write_spaces; /* Nonzero means spaces in the text must actually be output; can't just skip over some columns to leave them blank. */ - int fast_clear_end_of_line; /* Nonzero means terminal has a `ce' string */ + int fast_clear_end_of_line; /* Nonzero means terminal has a `ce' string. */ - int line_ins_del_ok; /* Terminal can insert and delete lines */ - int char_ins_del_ok; /* Terminal can insert and delete chars */ + int line_ins_del_ok; /* Terminal can insert and delete lines. */ + int char_ins_del_ok; /* Terminal can insert and delete chars. */ int scroll_region_ok; /* Terminal supports setting the scroll - window */ + window. */ int scroll_region_cost; /* Cost of setting the scroll window, - measured in characters. */ + measured in characters. */ int memory_below_frame; /* Terminal remembers lines scrolled - off bottom */ + off bottom. */ /* Window-based redisplay interface for this device (0 for tty devices). */ @@ -617,7 +617,7 @@ tset_selection_alist (struct terminal *t, Lisp_Object val) t->Vselection_alist = val; } -/* Chain of all terminal devices currently in use. */ +/* Chain of all terminal devices currently in use. */ extern struct terminal *terminal_list; #define FRAME_MUST_WRITE_SPACES(f) ((f)->terminal->must_write_spaces) @@ -638,14 +638,16 @@ extern struct terminal *terminal_list; #define FRAME_TERMINAL(f) ((f)->terminal) -/* Return true if the terminal device is not suspended. */ -#define TERMINAL_ACTIVE_P(d) (((d)->type != output_termcap && (d)->type !=output_msdos_raw) || (d)->display_info.tty->input) +/* Return true if the terminal device is not suspended. */ +#define TERMINAL_ACTIVE_P(d) \ + (((d)->type != output_termcap && (d)->type != output_msdos_raw) \ + || (d)->display_info.tty->input) extern struct terminal *get_terminal (Lisp_Object terminal, int); extern struct terminal *create_terminal (void); extern void delete_terminal (struct terminal *); -/* The initial terminal device, created by initial_term_init. */ +/* The initial terminal device, created by initial_term_init. */ extern struct terminal *initial_terminal; extern unsigned char *encode_terminal_code (struct glyph *, int, diff --git a/src/terminal.c b/src/terminal.c index 5e1f1ff77f7..c99c39c64ae 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -280,7 +280,7 @@ delete_terminal (struct terminal *terminal) xfree (terminal->name); terminal->name = NULL; - /* Check for live frames that are still on this terminal. */ + /* Check for live frames that are still on this terminal. */ FOR_EACH_FRAME (tail, frame) { struct frame *f = XFRAME (frame); diff --git a/src/textprop.c b/src/textprop.c index 18e893b3ef2..2b454485370 100644 --- a/src/textprop.c +++ b/src/textprop.c @@ -60,7 +60,7 @@ Lisp_Object Qinvisible, Qintangible, Qmouse_face; static Lisp_Object Qread_only; Lisp_Object Qminibuffer_prompt; -/* Sticky properties */ +/* Sticky properties. */ Lisp_Object Qfront_sticky, Qrear_nonsticky; /* If o1 is a cons whose cdr is a cons, return non-zero and set o2 to -- 2.39.2