diff options
author | Jason Rumney <jasonr@gnu.org> | 2010-01-27 21:59:13 +0800 |
---|---|---|
committer | Jason Rumney <jasonr@gnu.org> | 2010-01-27 21:59:13 +0800 |
commit | 7e23373040046d7dd1cfe7dd77c78a0ac1075028 (patch) | |
tree | 7518be1d351cf1933dab3bf5366f34b35569cc87 /src/w32inevt.c | |
parent | c8b96b2a9548c65ad6b0f22f79b724ff2b63054a (diff) |
Use Unicode for console keyboard input on Windows.
w32inevt.c (w32_kbd_patch_key): Save the unicode character.
(key_event): Use unicode for characters 128 and higher.
Diffstat (limited to 'src/w32inevt.c')
-rw-r--r-- | src/w32inevt.c | 77 |
1 files changed, 68 insertions, 9 deletions
diff --git a/src/w32inevt.c b/src/w32inevt.c index 5ba8430eb8..ebdff1357a 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c @@ -81,6 +81,9 @@ extern unsigned int w32_key_to_modifier (int key); static INPUT_RECORD event_queue[EVENT_QUEUE_SIZE]; static INPUT_RECORD *queue_ptr = event_queue, *queue_end = event_queue; +/* Temporarily store lead byte of DBCS input sequences. */ +static char dbcs_lead = 0; + static int fill_queue (BOOL block) { @@ -253,13 +256,15 @@ w32_kbd_patch_key (KEY_EVENT_RECORD *event) keystate, buf, 128, 0); if (isdead > 0) { - char cp[20]; - int cpId; + char cp[20]; + int cpId; - GetLocaleInfo (GetThreadLocale (), + event->uChar.UnicodeChar = buf[isdead - 1]; + + GetLocaleInfo (GetThreadLocale (), LOCALE_IDEFAULTANSICODEPAGE, cp, 20); - cpId = atoi (cp); - isdead = WideCharToMultiByte (cpId, 0, buf, isdead, + cpId = atoi (cp); + isdead = WideCharToMultiByte (cpId, 0, buf, isdead, ansi_code, 4, NULL, NULL); } else @@ -425,8 +430,6 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead) if (lispy_function_keys[event->wVirtualKeyCode] == 0) { - emacs_ev->kind = ASCII_KEYSTROKE_EVENT; - if (!NILP (Vw32_recognize_altgr) && (event->dwControlKeyState & LEFT_CTRL_PRESSED) && (event->dwControlKeyState & RIGHT_ALT_PRESSED)) @@ -461,9 +464,65 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead) else if (event->uChar.AsciiChar == 0) w32_kbd_patch_key (event); } + if (event->uChar.AsciiChar == 0) - return 0; - emacs_ev->code = event->uChar.AsciiChar; + { + emacs_ev->kind = NO_EVENT; + return 0; + } + else if (event->uChar.AsciiChar < 128) + { + emacs_ev->kind = ASCII_KEYSTROKE_EVENT; + emacs_ev->code = event->uChar.AsciiChar; + } + else if (event->uChar.UnicodeChar > 0) + { + emacs_ev->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT; + emacs_ev->code = event->uChar.UnicodeChar; + } + else + { + /* Fallback for non-Unicode versions of Windows. */ + wchar_t code; + char dbcs[2]; + char cp[20]; + int cpId; + + /* Get the codepage to interpret this key with. */ + GetLocaleInfo (GetThreadLocale (), + LOCALE_IDEFAULTANSICODEPAGE, cp, 20); + cpId = atoi (cp); + + dbcs[0] = dbcs_lead; + dbcs[1] = event->uChar.AsciiChar; + if (dbcs_lead) + { + dbcs_lead = 0; + if (!MultiByteToWideChar (cpId, 0, dbcs, 2, &code, 1)) + { + /* Garbage */ + DebPrint (("Invalid DBCS sequence: %d %d\n", + dbcs[0], dbcs[1])); + emacs_ev.kind = NO_EVENT; + } + } + else if (IsDBCSLeadByteEx (cpId, dbcs[1])) + { + dbcs_lead = dbcs[1]; + emacs_ev.kind = NO_EVENT; + } + else + { + if (!MultiByteToWideChar (cpId, 0, &dbcs[1], 1, &code, 1)) + { + /* Garbage */ + DebPrint (("Invalid character: %d\n", dbcs[1])); + emacs_ev.kind = NO_EVENT; + } + } + emacs_ev->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT; + emacs_ev->code = code; + } } else { |