* 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.
This commit is contained in:
Stefan Monnier 2013-03-10 21:17:40 -04:00
parent 819e2da92a
commit cbae07d5e0
6 changed files with 95 additions and 92 deletions

View file

@ -1,3 +1,11 @@
2013-03-11 Stefan Monnier <monnier@iro.umontreal.ca>
* 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 <dancol@dancol.org>
* w32term.h (GUISTR, GUI_ENCODE_FILE, GUI_ENCODE_SYSTEM, GUI_FN)

View file

@ -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

View file

@ -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)

View file

@ -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,

View file

@ -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);

View file

@ -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