summaryrefslogtreecommitdiff
path: root/src/w32term.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2020-03-03 18:40:28 +0200
committerEli Zaretskii <eliz@gnu.org>2020-03-03 18:40:28 +0200
commita4e4510ccd92da8ca17743c7dab9b32fc9d850e7 (patch)
tree15b520eae5c3f7d0d486db4a107c1c565013114f /src/w32term.c
parenta38bebb0c111de65a109f45133aacaf0ac69fe49 (diff)
downloademacs-a4e4510ccd92da8ca17743c7dab9b32fc9d850e7.tar.gz
Fix handling MS-Windows keyboard input above the BMP
* src/w32term.c (w32_read_socket): If we get a WM_UNICHAR message with a surrogate codepoint, assemble the corresponding character code above the BMP from its UTF-16 encoding, communicated in two consecutive WM_UNICHAR messages.
Diffstat (limited to 'src/w32term.c')
-rw-r--r--src/w32term.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/src/w32term.c b/src/w32term.c
index 4eb5045fc5b..f515f5604d6 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -4701,6 +4701,10 @@ static short temp_buffer[100];
/* Temporarily store lead byte of DBCS input sequences. */
static char dbcs_lead = 0;
+/* Temporarily store pending UTF-16 high surrogate unit and the modifiers. */
+static unsigned short utf16_high;
+static DWORD utf16_high_modifiers;
+
/**
mouse_or_wdesc_frame: When not dropping and the mouse was grabbed
for DPYINFO, return the frame where the mouse was seen last. If
@@ -4912,9 +4916,45 @@ w32_read_socket (struct terminal *terminal,
XSETFRAME (inev.frame_or_window, f);
inev.timestamp = msg.msg.time;
+ if (utf16_high
+ && (msg.msg.message != WM_UNICHAR
+ || UTF_16_HIGH_SURROGATE_P (msg.msg.wParam)))
+ {
+ /* Flush the pending high surrogate if the low one
+ isn't coming. (This should never happen, but I
+ have paranoia about this stuff.) */
+ struct input_event inev1;
+ inev1.modifiers = utf16_high_modifiers;
+ inev1.code = utf16_high;
+ inev1.timestamp = inev.timestamp;
+ inev1.arg = Qnil;
+ kbd_buffer_store_event_hold (&inev1, hold_quit);
+ utf16_high = 0;
+ utf16_high_modifiers = 0;
+ }
+
if (msg.msg.message == WM_UNICHAR)
{
- inev.code = msg.msg.wParam;
+ /* Handle UTF-16 encoded codepoint above the BMP.
+ This is needed to support Emoji input from input
+ panel popped up by "Win+." shortcut. */
+ if (UTF_16_HIGH_SURROGATE_P (msg.msg.wParam))
+ {
+ utf16_high = msg.msg.wParam;
+ utf16_high_modifiers = inev.modifiers;
+ inev.kind = NO_EVENT;
+ break;
+ }
+ else if (UTF_16_LOW_SURROGATE_P (msg.msg.wParam)
+ && utf16_high)
+ {
+ inev.code = surrogates_to_codepoint (msg.msg.wParam,
+ utf16_high);
+ utf16_high = 0;
+ utf16_high_modifiers = 0;
+ }
+ else
+ inev.code = msg.msg.wParam;
}
else if (msg.msg.wParam < 256)
{