Package: emacs;
Reported by: Joakim Hårsman <joakim.harsman <at> gmail.com>
Date: Wed, 14 Dec 2011 20:42:02 UTC
Severity: normal
Done: Eli Zaretskii <eliz <at> gnu.org>
Bug is archived. No further changes may be made.
Message #59 received at 10299 <at> debbugs.gnu.org (full text, mbox):
From: Joakim Hårsman <joakim.harsman <at> gmail.com> To: Eli Zaretskii <eliz <at> gnu.org> Cc: 10299 <at> debbugs.gnu.org Subject: Re: bug#10299: Emacs doesn't handle Unicode characters in keyboard layout on MS Windows Date: Sat, 17 Dec 2011 13:52:29 +0100
On 16 December 2011 12:26, Eli Zaretskii <eliz <at> gnu.org> wrote: >> Date: Fri, 16 Dec 2011 12:14:50 +0100 >> From: Dani Moncayo <dmoncayo <at> gmail.com> >> Cc: Eli Zaretskii <eliz <at> gnu.org>, 10299 <at> debbugs.gnu.org >> >> > I think I have a MSYS sh.exe somewhere in my path which caused the >> > build to fail if I didn't explicitly set SHELL. >> >> Maybe if you try "mingw32-make" instead of "make", you will be able to >> build Emacs successfully (see >> http://lists.gnu.org/archive/html/emacs-devel/2011-12/msg00025.html) > > If his make.exe reacts correctly to SHELL=cmd.exe, it is most probably > a MinGW Make, just renamed to make.exe. (FWIW, my MinGW compiled Make > is also called make.exe.) Ok, I tried switching to RegisterClassW, but that didn't really help, after calling TranslateMessage I still got WM_CHAR with a question mark. So I tried switching to CreateWindowW and GetMessageW as well, and that did the trick. Here's my changes: D:\Dev_projects\emacs\trunk\nt>bzr diff === modified file 'src/w32fns.c' --- src/w32fns.c 2011-12-04 08:02:42 +0000 +++ src/w32fns.c 2011-12-17 11:39:10 +0000 @@ -1785,7 +1785,7 @@ static BOOL w32_init_class (HINSTANCE hinst) { - WNDCLASS wc; + WNDCLASSW wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC) w32_wnd_proc; @@ -1796,9 +1796,9 @@ wc.hCursor = w32_load_cursor (IDC_ARROW); wc.hbrBackground = NULL; /* GetStockObject (WHITE_BRUSH); */ wc.lpszMenuName = NULL; - wc.lpszClassName = EMACS_CLASS; + wc.lpszClassName = L"Emacs"; - return (RegisterClass (&wc)); + return (RegisterClassW (&wc)); } static HWND @@ -1853,7 +1853,7 @@ } FRAME_W32_WINDOW (f) = hwnd - = CreateWindow (EMACS_CLASS, + = CreateWindowW (L"Emacs", f->namebuf, f->output_data.w32->dwStyle | WS_CLIPCHILDREN, EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left), @@ -2248,7 +2248,7 @@ msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL); - while (GetMessage (&msg, NULL, 0, 0)) + while (GetMessageW (&msg, NULL, 0, 0)) { if (msg.hwnd == NULL) { @@ -2507,7 +2507,7 @@ message that has no particular effect. */ { int c = wParam; - if (isalpha (c) && wmsg.dwModifiers == ctrl_modifier) + if (iswalpha (c) && wmsg.dwModifiers == ctrl_modifier) c = make_ctrl_char (c) & 0377; if (c == quit_char || (wmsg.dwModifiers == 0 && I had to switch to iswalpha because isalpha segfaulted when sent values larger than 255. wParam isn't really the Unicode code point here either, it's encoded as UTF-16. With this change, Emacs no longer prints a question mark when I press the special keys, it doesn't print anything at all. I figured this is beacause wParam isn't a valid Unicode codepoint here, like it is when you get a WM_UNICHAR, so I tried a quick hack converting from UTF-16 and re-posting as a WM_UNICHAR even. I changed the handling of WM_CHAR in w32_wnd_proc: case WM_CHAR: if (wParam > 255 ) { /* Hacky conversion from UTF-16 to UCS-4. Doesn't handle surrogate pairs. */ unsigned short lo = wParam & 0x0000FFFF; unsigned short hi = (wParam & 0xFFFF0000) >> 8; wParam = hi | lo; W32Msg wmsg; wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam); signal_user_input (); my_post_msg (&wmsg, hwnd, WM_UNICHAR, wParam, lParam); } else post_character_message (hwnd, msg, wParam, lParam, w32_get_key_modifiers (wParam, lParam)); This fixed it! I can now enter the characters with a custom keyboard layout so I'm happy. There's loads of bugs still (e.g. the frame title is "e" instead of "Emacs <at> host" because I just pass the frame's namebuf to CreateWindowW without converting it to a wide string), but at least the main issue is fixed. I guess these changes need to only happen when running on NT for Emacs to still work on Windows 95 or does Emacs use MSLU? Maybe they should depend on some lisp variable being set? Here's my changes in full so far: === modified file 'src/w32fns.c' --- src/w32fns.c 2011-12-04 08:02:42 +0000 +++ src/w32fns.c 2011-12-17 12:47:44 +0000 @@ -1785,7 +1785,7 @@ static BOOL w32_init_class (HINSTANCE hinst) { - WNDCLASS wc; + WNDCLASSW wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC) w32_wnd_proc; @@ -1796,9 +1796,9 @@ wc.hCursor = w32_load_cursor (IDC_ARROW); wc.hbrBackground = NULL; /* GetStockObject (WHITE_BRUSH); */ wc.lpszMenuName = NULL; - wc.lpszClassName = EMACS_CLASS; + wc.lpszClassName = L"Emacs"; - return (RegisterClass (&wc)); + return (RegisterClassW (&wc)); } static HWND @@ -1853,7 +1853,7 @@ } FRAME_W32_WINDOW (f) = hwnd - = CreateWindow (EMACS_CLASS, + = CreateWindowW (L"Emacs", f->namebuf, f->output_data.w32->dwStyle | WS_CLIPCHILDREN, EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left), @@ -2248,7 +2248,7 @@ msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL); - while (GetMessage (&msg, NULL, 0, 0)) + while (GetMessageW (&msg, NULL, 0, 0)) { if (msg.hwnd == NULL) { @@ -2507,7 +2507,7 @@ message that has no particular effect. */ { int c = wParam; - if (isalpha (c) && wmsg.dwModifiers == ctrl_modifier) + if (iswalpha (c) && wmsg.dwModifiers == ctrl_modifier) c = make_ctrl_char (c) & 0377; if (c == quit_char || (wmsg.dwModifiers == 0 && @@ -2915,8 +2915,23 @@ case WM_SYSCHAR: case WM_CHAR: - post_character_message (hwnd, msg, wParam, lParam, - w32_get_key_modifiers (wParam, lParam)); + if (wParam > 255 ) + { + /* Hacky conversion from UTF-16 to UCS-4. + Doesn't handle surrogate pairs. */ + unsigned short lo = wParam & 0x0000FFFF; + unsigned short hi = (wParam & 0xFFFF0000) >> 8; + wParam = hi | lo; + + W32Msg wmsg; + wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam); + signal_user_input (); + my_post_msg (&wmsg, hwnd, WM_UNICHAR, wParam, lParam); + + } + else + post_character_message (hwnd, msg, wParam, lParam, + w32_get_key_modifiers (wParam, lParam)); break; case WM_UNICHAR:
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.