From 302fc036e8b6305a45aca868e0001dd8fb3ed123 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 30 Jul 2012 20:07:33 +0300 Subject: [PATCH] Fix bug #12082 with input of Meta-non-ASCII-characters on MS-Windows. src/w32fns.c (w32_wnd_proc): Pass w32_keyboard_codepage to w32_kbd_patch_key as the 2nd arg. src/w32term.c : Renamed from keyboard_codepage and now external. All users changed. src/w32term.h: Add declaration of w32_keyboard_codepage. src/w32inevt.c (w32_kbd_patch_key): Accept an additional argument -- the codepage to translate keys to Unicode. If this argument is -1, use the value returned by GetConsoleCP. All callers changed. --- src/ChangeLog | 14 ++++++++++++++ src/w32fns.c | 4 ++-- src/w32inevt.c | 14 ++++++++++---- src/w32term.c | 21 +++++++++++---------- src/w32term.h | 3 +++ 5 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 792dc10f88c..be60f3d22b3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2012-07-30 Eli Zaretskii + + * w32fns.c (w32_wnd_proc): Pass w32_keyboard_codepage to + w32_kbd_patch_key as the 2nd arg. (Bug#12082) + + * w32term.c : Renamed from + keyboard_codepage and now external. All users changed. + + * w32term.h: Add declaration of w32_keyboard_codepage. + + * w32inevt.c (w32_kbd_patch_key): Accept an additional argument -- + the codepage to translate keys to Unicode. If this argument is + -1, use the value returned by GetConsoleCP. All callers changed. + 2012-07-30 Paul Eggert Update .PHONY listings in makefiles. diff --git a/src/w32fns.c b/src/w32fns.c index 97b7001a3fa..91744e2691f 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -2882,7 +2882,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) key.uChar.AsciiChar = 0; key.dwControlKeyState = modifiers; - add = w32_kbd_patch_key (&key); + add = w32_kbd_patch_key (&key, w32_keyboard_codepage); /* 0 means an unrecognized keycode, negative means dead key. Ignore both. */ while (--add >= 0) @@ -2892,7 +2892,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) (hwnd, WM_CHAR, (unsigned char) key.uChar.AsciiChar, lParam, w32_get_key_modifiers (wParam, lParam)); - w32_kbd_patch_key (&key); + w32_kbd_patch_key (&key, w32_keyboard_codepage); } return 0; } diff --git a/src/w32inevt.c b/src/w32inevt.c index 6d869727d2f..731dd6715dc 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c @@ -185,9 +185,11 @@ is_dead_key (int wparam) } #endif -/* The return code indicates key code size. */ +/* The return code indicates key code size. cpID is the codepage to + use for translation to Unicode; -1 means use the current console + input codepage. */ int -w32_kbd_patch_key (KEY_EVENT_RECORD *event) +w32_kbd_patch_key (KEY_EVENT_RECORD *event, int cpId) { unsigned int key_code = event->wVirtualKeyCode; unsigned int mods = event->dwControlKeyState; @@ -243,7 +245,11 @@ w32_kbd_patch_key (KEY_EVENT_RECORD *event) keystate, buf, 128, 0); if (isdead > 0) { - int cpId = GetConsoleCP (); + /* When we are called from the GUI message processing code, + we are passed the current keyboard codepage, a positive + number, to use below. */ + if (cpId == -1) + cpId = GetConsoleCP (); event->uChar.UnicodeChar = buf[isdead - 1]; isdead = WideCharToMultiByte (cpId, 0, buf, isdead, @@ -442,7 +448,7 @@ key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead) base character (ie. translating the base key plus shift modifier). */ else if (event->uChar.AsciiChar == 0) - w32_kbd_patch_key (event); + w32_kbd_patch_key (event, -1); } if (event->uChar.AsciiChar == 0) diff --git a/src/w32term.c b/src/w32term.c index f02d101cea3..7c4860d5139 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -155,6 +155,9 @@ int vertical_scroll_bar_bottom_border; int last_scroll_bar_drag_pos; +/* Keyboard code page - may be changed by language-change events. */ +int w32_keyboard_codepage; + /* Mouse movement. */ /* Where the mouse was last time we reported a mouse event. */ @@ -188,9 +191,6 @@ static int volatile input_signal_count; static int input_signal_count; #endif -/* Keyboard code page - may be changed by language-change events. */ -static int keyboard_codepage; - static void x_update_window_end (struct window *, int, int); static void w32_handle_tool_bar_click (struct frame *, struct input_event *); @@ -4235,14 +4235,14 @@ w32_read_socket (struct terminal *terminal, int expected, /* lParam contains the input language ID in its low 16 bits. Use it to update our record of the keyboard codepage. */ - keyboard_codepage = codepage_for_locale ((LCID)(msg.msg.lParam - & 0xffff)); + w32_keyboard_codepage = codepage_for_locale ((LCID)(msg.msg.lParam + & 0xffff)); if (f) { inev.kind = LANGUAGE_CHANGE_EVENT; XSETFRAME (inev.frame_or_window, f); - inev.code = keyboard_codepage; + inev.code = w32_keyboard_codepage; inev.modifiers = msg.msg.lParam & 0xffff; } break; @@ -4308,7 +4308,7 @@ w32_read_socket (struct terminal *terminal, int expected, { dbcs[0] = dbcs_lead; dbcs_lead = 0; - if (!MultiByteToWideChar (keyboard_codepage, 0, + if (!MultiByteToWideChar (w32_keyboard_codepage, 0, dbcs, 2, &code, 1)) { /* Garbage */ @@ -4318,7 +4318,7 @@ w32_read_socket (struct terminal *terminal, int expected, break; } } - else if (IsDBCSLeadByteEx (keyboard_codepage, + else if (IsDBCSLeadByteEx (w32_keyboard_codepage, (BYTE) msg.msg.wParam)) { dbcs_lead = (char) msg.msg.wParam; @@ -4327,7 +4327,7 @@ w32_read_socket (struct terminal *terminal, int expected, } else { - if (!MultiByteToWideChar (keyboard_codepage, 0, + if (!MultiByteToWideChar (w32_keyboard_codepage, 0, &dbcs[1], 1, &code, 1)) { /* What to do with garbage? */ @@ -6426,7 +6426,8 @@ w32_initialize (void) { DWORD input_locale_id = (DWORD) GetKeyboardLayout (0); - keyboard_codepage = codepage_for_locale ((LCID) (input_locale_id & 0xffff)); + w32_keyboard_codepage = + codepage_for_locale ((LCID) (input_locale_id & 0xffff)); } /* Create the window thread - it will terminate itself when the app diff --git a/src/w32term.h b/src/w32term.h index b49104dde8b..c0a958ba5e5 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -667,6 +667,9 @@ extern void x_delete_display (struct w32_display_info *dpyinfo); #define RIGHT_WIN_PRESSED 0x4000 #define APPS_PRESSED 0x2000 +/* The current ANSI input codepage for GUI sessions. */ +extern int w32_keyboard_codepage; + /* When compiling on Windows 9x/ME and NT 3.x, the following are not defined (even though they are supported on 98 and ME. */ #ifndef WM_MOUSELEAVE -- 2.39.2