From: Eli Zaretskii <eliz@gnu.org>
To: "Joakim Hårsman" <joakim.harsman@gmail.com>
Cc: lekktu@gmail.com, 10299@debbugs.gnu.org
Subject: bug#10299: Emacs doesn't handle Unicode characters in keyboard layout on MS Windows
Date: Sat, 28 Jul 2012 17:50:06 +0300 [thread overview]
Message-ID: <836298hrdt.fsf@gnu.org> (raw)
In-Reply-To: <CAFJF9wVme13g3uFBHD_QxX2O3Tk6TYH7yR96--62wHKGLW8EQg@mail.gmail.com>
> Date: Tue, 24 Jan 2012 21:42:46 +0100
> From: Joakim Hårsman <joakim.harsman@gmail.com>
> Cc: Andreas Schwab <schwab@linux-m68k.org>, 10299@debbugs.gnu.org
>
> GetMessage is a macro, many Windows API functions are, and switches
> between GetMessageA and GetMessageW based on whether UNICODE is
> defined. I really should explicitly use GetMessageA, I just missed it.
>
> I switched to Stefan's suggestion, but with explicit use of
> GetMessageA. Note that this makes that line longer than 80 chars.
>
> Here's an amended patch that also moves the definition of the
> INIT_WINDOW_CLASS macro to just before use, and makes
> w32_set_frame_text static.
Thanks. It's been a while since you submitted this, so sorry for the
delay. We are now past Emacs 24.1 release, so we are free to install
your changes.
However, when I applied the patch, I bumped into several problems.
First, I don't understand why we need this part:
+/* Set text of w32 frame with handle HWND to TEXT.
+
+ We explicitly switch between the Unicode and ANSI version of
+ SetWindowText because Emacs isn't compiled with UNICODE defined to
+ retain compatibility with Windows 95. */
+
+static void
+w32_set_frame_text (HWND hwnd, LPCSTR text)
+{
+ if (os_subtype == OS_NT)
+ SetWindowTextW (hwnd, (LPCWSTR)text);
+ else
+ SetWindowTextA (hwnd, text);
+}
/* Change the name of frame F to NAME. If NAME is nil, set F's name to
w32_id_name.
@@ -1697,10 +1711,10 @@
if (FRAME_W32_WINDOW (f))
{
if (STRING_MULTIBYTE (name))
- name = ENCODE_SYSTEM (name);
-
+ name = ENCODE_SYSTEM (name);
+
BLOCK_INPUT;
- SetWindowText (FRAME_W32_WINDOW (f), SDATA (name));
+ w32_set_frame_text(FRAME_W32_WINDOW (f), SDATA (name));
UNBLOCK_INPUT;
}
}
@@ -1746,7 +1760,7 @@
name = ENCODE_SYSTEM (name);
BLOCK_INPUT;
- SetWindowText (FRAME_W32_WINDOW (f), SDATA (name));
+ w32_set_frame_text(FRAME_W32_WINDOW (f), SDATA (name));
UNBLOCK_INPUT;
}
}
Why do we need to use SetWindowTextW, when all we change is the way we
request messages for Emacs? With the patch below, which doesn't use
this part, I see no problems at all with the titles of Emacs frames.
Can you tell me how to reproduce the problem with the title?
Moreover, passing 'SDATA (name)' to SetWindowTextW is wrong, since
that function expects a wchar_t *, not a char *, as pointer to the
text to display in the title. (The compiler should warn about that,
didn't it?) So if we do need this part, we will need to convert the
frame name into a wide character string.
Next, this part, whose need was not entirely understood even when you
submitted the patches:
@@ -2915,8 +2948,21 @@
case WM_SYSCHAR:
case WM_CHAR:
- post_character_message (hwnd, msg, wParam, lParam,
- w32_get_key_modifiers (wParam, lParam));
+ if (wParam > 255 )
+ {
+ 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;
This doesn't work in a locale where Unicode codepoints of the
characters generated by the localized keyboard are above 255. (I live
in one such locale.) In those locales, this snippet produces the
wrong characters. The root cause of this is that WM_CHAR's wParam is
not really the Unicode codepoint of the character I type, it's some
garbled value. After looking into this, my conclusion was that your
patches didn't do everything that's needed to get true Unicode
character input. This page:
http://social.msdn.microsoft.com/forums/en-US/windowssdk/thread/07afec87-68c1-4a56-bf46-a38a9c2232e9/
suggests what needs to be done. So I went ahead and made the few
additional changes mentioned there, and the Unicode input started
working for me. With these additional changes, the funky bit-tweaking
code is no longer needed, at least for the characters in the 0x05nn
range of Unicode that I tried. I hope it will work with your custom
keyboard as well.
The patches I tried are below. I'd appreciate if you could try them
and see if they work with your custom keyboard layouts. If they do, I
will install them.
(Juanma, I'd appreciate if you could try this as well.)
Thanks.
=== modified file 'src/w32fns.c'
--- src/w32fns.c 2012-07-27 09:24:34 +0000
+++ src/w32fns.c 2012-07-28 14:28:29 +0000
@@ -1780,23 +1780,37 @@ w32_load_cursor (LPCTSTR name)
static LRESULT CALLBACK w32_wnd_proc (HWND, UINT, WPARAM, LPARAM);
+#define INIT_WINDOW_CLASS(WC) \
+ (WC).style = CS_HREDRAW | CS_VREDRAW; \
+ (WC).lpfnWndProc = (WNDPROC) w32_wnd_proc; \
+ (WC).cbClsExtra = 0; \
+ (WC).cbWndExtra = WND_EXTRA_BYTES; \
+ (WC).hInstance = hinst; \
+ (WC).hIcon = LoadIcon (hinst, EMACS_CLASS); \
+ (WC).hCursor = w32_load_cursor (IDC_ARROW); \
+ (WC).hbrBackground = NULL; \
+ (WC).lpszMenuName = NULL; \
+
static BOOL
w32_init_class (HINSTANCE hinst)
{
- WNDCLASS wc;
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = (WNDPROC) w32_wnd_proc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = WND_EXTRA_BYTES;
- wc.hInstance = hinst;
- wc.hIcon = LoadIcon (hinst, EMACS_CLASS);
- wc.hCursor = w32_load_cursor (IDC_ARROW);
- wc.hbrBackground = NULL; /* GetStockObject (WHITE_BRUSH); */
- wc.lpszMenuName = NULL;
- wc.lpszClassName = EMACS_CLASS;
+ if (os_subtype == OS_NT)
+ {
+ WNDCLASSW uwc;
+ INIT_WINDOW_CLASS(uwc);
+ uwc.lpszClassName = L"Emacs";
+
+ return RegisterClassW (&uwc);
+ }
+ else
+ {
+ WNDCLASS wc;
+ INIT_WINDOW_CLASS(wc);
+ wc.lpszClassName = EMACS_CLASS;
- return (RegisterClass (&wc));
+ return RegisterClassA (&wc);
+ }
}
static HWND
@@ -2246,7 +2260,7 @@ w32_msg_pump (deferred_msg * msg_buf)
msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL);
- while (GetMessage (&msg, NULL, 0, 0))
+ while ((os_subtype == OS_NT ? GetMessageW : GetMessageA) (&msg, NULL, 0, 0))
{
if (msg.hwnd == NULL)
{
@@ -2341,7 +2355,10 @@ w32_msg_pump (deferred_msg * msg_buf)
}
else
{
- DispatchMessage (&msg);
+ if (os_subtype == OS_NT)
+ DispatchMessageW (&msg);
+ else
+ DispatchMessageA (&msg);
}
/* Exit nested loop when our deferred message has completed. */
@@ -2918,8 +2935,18 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARA
case WM_SYSCHAR:
case WM_CHAR:
- post_character_message (hwnd, msg, wParam, lParam,
- w32_get_key_modifiers (wParam, lParam));
+ if (wParam > 255 )
+ {
+ 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:
@@ -3801,7 +3828,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARA
}
dflt:
- return DefWindowProc (hwnd, msg, wParam, lParam);
+ return (os_subtype == OS_NT ? DefWindowProcW : DefWindowProcA) (hwnd, msg, wParam, lParam);
}
/* The most common default return code for handled messages is 0. */
next prev parent reply other threads:[~2012-07-28 14:50 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-14 20:39 bug#10299: Emacs doesn't handle Unicode characters in keyboard layout on MS Windows Joakim Hårsman
2011-12-15 6:22 ` Eli Zaretskii
2011-12-15 6:51 ` Kenichi Handa
2011-12-15 7:53 ` Joakim Hårsman
2011-12-15 10:52 ` Eli Zaretskii
2011-12-15 11:11 ` Joakim Hårsman
2011-12-15 13:16 ` Eli Zaretskii
2011-12-15 14:40 ` Jason Rumney
2011-12-15 15:08 ` Lennart Borgman
2011-12-15 15:40 ` Joakim Hårsman
2011-12-15 17:34 ` Eli Zaretskii
2011-12-15 20:50 ` Joakim Hårsman
2011-12-15 21:47 ` Joakim Hårsman
2011-12-16 8:13 ` Eli Zaretskii
2011-12-16 11:01 ` Joakim Hårsman
2011-12-16 11:14 ` Dani Moncayo
2011-12-16 11:26 ` Eli Zaretskii
2011-12-17 12:52 ` Joakim Hårsman
2011-12-17 15:23 ` Eli Zaretskii
[not found] ` <CAFJF9wW7Cfmad+BmjQ4A-sVeLi+eRvOXSWfD=--=QJmr3Ver6w@mail.gmail.com>
2011-12-18 18:13 ` Eli Zaretskii
2011-12-19 10:44 ` Joakim Hårsman
2011-12-19 10:59 ` Lennart Borgman
2011-12-19 11:04 ` Joakim Hårsman
2011-12-19 11:17 ` Lennart Borgman
2011-12-19 11:50 ` Joakim Hårsman
2011-12-19 13:31 ` Jason Rumney
2011-12-20 21:16 ` Joakim Hårsman
2012-01-14 16:40 ` Joakim Hårsman
2012-01-16 14:03 ` Stefan Monnier
2012-01-23 19:15 ` Joakim Hårsman
2012-01-24 1:35 ` Stefan Monnier
2012-01-24 9:40 ` Andreas Schwab
2012-01-24 12:03 ` Juanma Barranquero
2012-01-24 20:42 ` Joakim Hårsman
2012-07-28 14:50 ` Eli Zaretskii [this message]
2012-08-06 20:20 ` Joakim Hårsman
2012-08-07 2:53 ` Eli Zaretskii
2012-08-07 19:47 ` Joakim Hårsman
2012-08-08 2:48 ` Eli Zaretskii
2012-08-08 18:54 ` Joakim Hårsman
2012-08-10 6:56 ` Eli Zaretskii
2012-08-07 12:15 ` Jason Rumney
2012-08-07 19:49 ` Joakim Hårsman
2011-12-16 11:22 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=836298hrdt.fsf@gnu.org \
--to=eliz@gnu.org \
--cc=10299@debbugs.gnu.org \
--cc=joakim.harsman@gmail.com \
--cc=lekktu@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).