diff options
author | Eli Zaretskii <eliz@gnu.org> | 2012-07-28 19:57:57 +0300 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2012-07-28 19:57:57 +0300 |
commit | 01bd1b0df605d644ae31e8f1f81d926a5d8c7099 (patch) | |
tree | 4831ac9d45815c50fe276079dd5edb7cb8e63ef8 /src/w32inevt.c | |
parent | a5c66610be0d94045c417dde54f8ffadd26977b5 (diff) | |
download | emacs-01bd1b0df605d644ae31e8f1f81d926a5d8c7099.tar.gz |
Fix non-ASCII input in non-GUI frames on MS-Windows. (Bug#12055)
src/w32inevt.c: Include w32inevt.h.
(w32_read_console_input): New inline function, calls either
ReadConsoleInputA or ReadConsoleInputW, depending on the value of
w32_console_unicode_input.
(fill_queue): Call w32_read_console_input instead of ReadConsoleInput.
(w32_kbd_patch_key, key_event): Use the codepage returned by
GetConsoleCP, rather than the ANSI codepage returned by GetLocaleInfo.
(key_event): use uChar.UnicodeChar only if
w32_console_unicode_input is non-zero.
src/w32console.c: Include w32heap.h.
<w32_console_unicode_input>: New global variable.
(initialize_w32_display): Set w32_console_unicode_input to 1 on NT
family of Windows, zero otherwise.
src/w32inevt.h: Declare w32_console_unicode_input.
lisp/international/mule-cmds.el (set-locale-environment): In a
console session on MS-Windows, set up keyboard and terminal
encoding from the OEM codepage, not the ANSI codepage.
Diffstat (limited to 'src/w32inevt.c')
-rw-r--r-- | src/w32inevt.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/src/w32inevt.c b/src/w32inevt.c index a85fdbbe435..8d041194ca1 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c @@ -41,6 +41,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include "termchar.h" #include "w32heap.h" #include "w32term.h" +#include "w32inevt.h" /* stdin, from w32console.c */ extern HANDLE keyboard_handle; @@ -61,6 +62,15 @@ 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 inline BOOL +w32_read_console_input (HANDLE h, INPUT_RECORD *rec, DWORD recsize, + DWORD *waiting) +{ + return (w32_console_unicode_input + ? ReadConsoleInputW (h, rec, recsize, waiting) + : ReadConsoleInputA (h, rec, recsize, waiting)); +} + static int fill_queue (BOOL block) { @@ -80,8 +90,8 @@ fill_queue (BOOL block) return 0; } - rc = ReadConsoleInput (keyboard_handle, event_queue, EVENT_QUEUE_SIZE, - &events_waiting); + rc = w32_read_console_input (keyboard_handle, event_queue, EVENT_QUEUE_SIZE, + &events_waiting); if (!rc) return -1; queue_ptr = event_queue; @@ -224,7 +234,7 @@ w32_kbd_patch_key (KEY_EVENT_RECORD *event) #endif /* On NT, call ToUnicode instead and then convert to the current - locale's default codepage. */ + console input codepage. */ if (os_subtype == OS_NT) { WCHAR buf[128]; @@ -233,14 +243,9 @@ w32_kbd_patch_key (KEY_EVENT_RECORD *event) keystate, buf, 128, 0); if (isdead > 0) { - char cp[20]; - int cpId; + int cpId = GetConsoleCP (); event->uChar.UnicodeChar = buf[isdead - 1]; - - GetLocaleInfo (GetThreadLocale (), - LOCALE_IDEFAULTANSICODEPAGE, cp, 20); - cpId = atoi (cp); isdead = WideCharToMultiByte (cpId, 0, buf, isdead, ansi_code, 4, NULL, NULL); } @@ -447,26 +452,34 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead) } else if (event->uChar.AsciiChar > 0) { + /* Pure ASCII characters < 128. */ emacs_ev->kind = ASCII_KEYSTROKE_EVENT; emacs_ev->code = event->uChar.AsciiChar; } - else if (event->uChar.UnicodeChar > 0) + else if (event->uChar.UnicodeChar > 0 + && w32_console_unicode_input) { + /* Unicode codepoint; only valid if we are using Unicode + console input mode. */ emacs_ev->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT; emacs_ev->code = event->uChar.UnicodeChar; } else { - /* Fallback for non-Unicode versions of Windows. */ + /* Fallback handling of non-ASCII characters for non-Unicode + versions of Windows, and for non-Unicode input on NT + family of Windows. Only characters in the current + console codepage are supported by this fallback. */ 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); + /* Get the current console input codepage to interpret this + key with. Note that the system defaults for the OEM + codepage could have been changed by calling SetConsoleCP + or w32-set-console-codepage, so using GetLocaleInfo to + get LOCALE_IDEFAULTCODEPAGE is not TRT here. */ + cpId = GetConsoleCP (); dbcs[0] = dbcs_lead; dbcs[1] = event->uChar.AsciiChar; @@ -501,6 +514,7 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead) } else { + /* Function keys and other non-character keys. */ emacs_ev->kind = NON_ASCII_KEYSTROKE_EVENT; emacs_ev->code = event->wVirtualKeyCode; } |