diff options
| author | Eli Zaretskii | 2020-03-03 18:40:28 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2020-03-03 18:40:28 +0200 |
| commit | a4e4510ccd92da8ca17743c7dab9b32fc9d850e7 (patch) | |
| tree | 15b520eae5c3f7d0d486db4a107c1c565013114f | |
| parent | a38bebb0c111de65a109f45133aacaf0ac69fe49 (diff) | |
| download | emacs-a4e4510ccd92da8ca17743c7dab9b32fc9d850e7.tar.gz emacs-a4e4510ccd92da8ca17743c7dab9b32fc9d850e7.zip | |
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.
| -rw-r--r-- | src/w32term.c | 42 |
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]; | |||
| 4701 | /* Temporarily store lead byte of DBCS input sequences. */ | 4701 | /* Temporarily store lead byte of DBCS input sequences. */ |
| 4702 | static char dbcs_lead = 0; | 4702 | static char dbcs_lead = 0; |
| 4703 | 4703 | ||
| 4704 | /* Temporarily store pending UTF-16 high surrogate unit and the modifiers. */ | ||
| 4705 | static unsigned short utf16_high; | ||
| 4706 | static DWORD utf16_high_modifiers; | ||
| 4707 | |||
| 4704 | /** | 4708 | /** |
| 4705 | mouse_or_wdesc_frame: When not dropping and the mouse was grabbed | 4709 | mouse_or_wdesc_frame: When not dropping and the mouse was grabbed |
| 4706 | for DPYINFO, return the frame where the mouse was seen last. If | 4710 | for DPYINFO, return the frame where the mouse was seen last. If |
| @@ -4912,9 +4916,45 @@ w32_read_socket (struct terminal *terminal, | |||
| 4912 | XSETFRAME (inev.frame_or_window, f); | 4916 | XSETFRAME (inev.frame_or_window, f); |
| 4913 | inev.timestamp = msg.msg.time; | 4917 | inev.timestamp = msg.msg.time; |
| 4914 | 4918 | ||
| 4919 | if (utf16_high | ||
| 4920 | && (msg.msg.message != WM_UNICHAR | ||
| 4921 | || UTF_16_HIGH_SURROGATE_P (msg.msg.wParam))) | ||
| 4922 | { | ||
| 4923 | /* Flush the pending high surrogate if the low one | ||
| 4924 | isn't coming. (This should never happen, but I | ||
| 4925 | have paranoia about this stuff.) */ | ||
| 4926 | struct input_event inev1; | ||
| 4927 | inev1.modifiers = utf16_high_modifiers; | ||
| 4928 | inev1.code = utf16_high; | ||
| 4929 | inev1.timestamp = inev.timestamp; | ||
| 4930 | inev1.arg = Qnil; | ||
| 4931 | kbd_buffer_store_event_hold (&inev1, hold_quit); | ||
| 4932 | utf16_high = 0; | ||
| 4933 | utf16_high_modifiers = 0; | ||
| 4934 | } | ||
| 4935 | |||
| 4915 | if (msg.msg.message == WM_UNICHAR) | 4936 | if (msg.msg.message == WM_UNICHAR) |
| 4916 | { | 4937 | { |
| 4917 | inev.code = msg.msg.wParam; | 4938 | /* Handle UTF-16 encoded codepoint above the BMP. |
| 4939 | This is needed to support Emoji input from input | ||
| 4940 | panel popped up by "Win+." shortcut. */ | ||
| 4941 | if (UTF_16_HIGH_SURROGATE_P (msg.msg.wParam)) | ||
| 4942 | { | ||
| 4943 | utf16_high = msg.msg.wParam; | ||
| 4944 | utf16_high_modifiers = inev.modifiers; | ||
| 4945 | inev.kind = NO_EVENT; | ||
| 4946 | break; | ||
| 4947 | } | ||
| 4948 | else if (UTF_16_LOW_SURROGATE_P (msg.msg.wParam) | ||
| 4949 | && utf16_high) | ||
| 4950 | { | ||
| 4951 | inev.code = surrogates_to_codepoint (msg.msg.wParam, | ||
| 4952 | utf16_high); | ||
| 4953 | utf16_high = 0; | ||
| 4954 | utf16_high_modifiers = 0; | ||
| 4955 | } | ||
| 4956 | else | ||
| 4957 | inev.code = msg.msg.wParam; | ||
| 4918 | } | 4958 | } |
| 4919 | else if (msg.msg.wParam < 256) | 4959 | else if (msg.msg.wParam < 256) |
| 4920 | { | 4960 | { |