summaryrefslogtreecommitdiff
path: root/src/keyboard.c
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2022-02-16 10:10:13 +0800
committerPo Lu <luangruo@yahoo.com>2022-02-16 10:10:13 +0800
commit0a9c8855b0ce9618219ef70bb489107ce7194ba1 (patch)
tree518257b7f796e8245977343e54115555c96fc54e /src/keyboard.c
parent2d573afecb69c7638991c49dad39e414585db13f (diff)
downloademacs-0a9c8855b0ce9618219ef70bb489107ce7194ba1.tar.gz
Don't decode text within XIM callbacks or handle_one_xevent
* src/keyboard.c (kbd_buffer_get_event_1): (kbd_buffer_get_event_2): New functions. (kbd_buffer_get_event): Accept a new meaning of MULTIBYTE_CHAR_KEYSTROKE_EVENT where .arg can be a unibyte string to be decoded in the locale coding system. * src/termhooks.h (enum event_kind): Document new meaning of .arg in a multibyte keystroke event. * src/xfns.c (struct x_xim_text_conversion_data): New struct. (x_xim_text_to_utf8_unix_1): (x_xim_text_to_utf8_unix_2): New functions. (x_xim_text_to_utf8_unix): Handle decode failure correctly. (xic_preedit_draw_callback): Abort IM context if text could not be decoded correctly. * src/xterm.c (handle_one_xevent): Utilize new meaning of MULTIBYTE_CHAR_KEYSTROKE_EVENT.
Diffstat (limited to 'src/keyboard.c')
-rw-r--r--src/keyboard.c67
1 files changed, 63 insertions, 4 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index be9fb665d76..800632aa25d 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3835,6 +3835,18 @@ clear_event (struct input_event *event)
event->kind = NO_EVENT;
}
+static Lisp_Object
+kbd_buffer_get_event_1 (Lisp_Object arg)
+{
+ return code_convert_string (arg, Vlocale_coding_system,
+ Qnil, 0, false, 0);
+}
+
+static Lisp_Object
+kbd_buffer_get_event_2 (Lisp_Object val)
+{
+ return Qnil;
+}
/* Read one event from the event buffer, waiting if necessary.
The value is a Lisp object representing the event.
@@ -3847,7 +3859,7 @@ kbd_buffer_get_event (KBOARD **kbp,
bool *used_mouse_menu,
struct timespec *end_time)
{
- Lisp_Object obj;
+ Lisp_Object obj, str;
#ifdef subprocesses
if (kbd_on_hold_p () && kbd_buffer_nr_stored () < KBD_BUFFER_SIZE / 4)
@@ -4120,6 +4132,47 @@ kbd_buffer_get_event (KBOARD **kbp,
}
}
+ if (event->kind == MULTIBYTE_CHAR_KEYSTROKE_EVENT
+ /* This string has to be decoded. */
+ && STRINGP (event->ie.arg))
+ {
+ str = internal_condition_case_1 (kbd_buffer_get_event_1,
+ event->ie.arg, Qt,
+ kbd_buffer_get_event_2);
+
+ /* Decoding the string failed, so use the original,
+ where at least ASCII text will work. */
+ if (NILP (str))
+ str = event->ie.arg;
+
+ if (!SCHARS (str))
+ {
+ kbd_fetch_ptr = next_kbd_event (event);
+ obj = Qnil;
+ break;
+ }
+
+ /* car is the index of the next character in the
+ string that will be sent and cdr is the string
+ itself. */
+ event->ie.arg = Fcons (make_fixnum (0), str);
+ }
+
+ if (event->kind == MULTIBYTE_CHAR_KEYSTROKE_EVENT
+ && CONSP (event->ie.arg))
+ {
+ eassert (FIXNUMP (XCAR (event->ie.arg)));
+ eassert (STRINGP (XCDR (event->ie.arg)));
+ eassert (XFIXNUM (XCAR (event->ie.arg))
+ < SCHARS (XCDR (event->ie.arg)));
+
+ event->ie.code = XFIXNUM (Faref (XCDR (event->ie.arg),
+ XCAR (event->ie.arg)));
+
+ XSETCAR (event->ie.arg,
+ make_fixnum (XFIXNUM (XCAR (event->ie.arg)) + 1));
+ }
+
obj = make_lispy_event (&event->ie);
#ifdef HAVE_EXT_MENU_BAR
@@ -4142,9 +4195,15 @@ kbd_buffer_get_event (KBOARD **kbp,
*used_mouse_menu = true;
#endif
- /* Wipe out this event, to catch bugs. */
- clear_event (&event->ie);
- kbd_fetch_ptr = next_kbd_event (event);
+ if (event->kind != MULTIBYTE_CHAR_KEYSTROKE_EVENT
+ || !CONSP (event->ie.arg)
+ || (XFIXNUM (XCAR (event->ie.arg))
+ >= SCHARS (XCDR (event->ie.arg))))
+ {
+ /* Wipe out this event, to catch bugs. */
+ clear_event (&event->ie);
+ kbd_fetch_ptr = next_kbd_event (event);
+ }
}
}
}