* 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:
parent
819e2da92a
commit
cbae07d5e0
6 changed files with 95 additions and 92 deletions
|
@ -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)
|
||||
|
|
145
src/keyboard.c
145
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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue