* Re: Switch the Windows port to using Unicode keyboard input [not found] ` <4AC8B391.4020906@gnu.org> @ 2009-10-04 17:41 ` Eugen Anghel 2009-10-04 19:17 ` Eli Zaretskii 0 siblings, 1 reply; 3+ messages in thread From: Eugen Anghel @ 2009-10-04 17:41 UTC (permalink / raw) To: Jason Rumney, Lennart Borgman, Eli Zaretskii; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 841 bytes --] 2009/10/4 Jason Rumney <jasonr@gnu.org>: > Lennart Borgman wrote: >> >> Isn't it possible to keep the old code and check whether to use it or >> not in the binary? >> > > It may be, but changing the window class in a backwards compatible way is > not as straightforward as the other function calls where we have done that. > I suspect that a better approach would be to fix all the locations where > system calls are used to cope with both _UNICODE and non _UNICODE builds, > and use the non-specific system functions throughout. > Is having two separate binaries, one for 9x/Me and one for XP/Vista an option? because I agree, that would simplify some things. As for loading the functions at runtime, I've attached a patch that should work on both 9x and XP/Vista. While kind of ugly, it's definitely a possibility. [-- Attachment #2: patch.patch --] [-- Type: application/octet-stream, Size: 14286 bytes --] diff --git a/src/coding.c b/src/coding.c index 405284f..57f3063 100644 --- a/src/coding.c +++ b/src/coding.c @@ -310,7 +310,7 @@ Lisp_Object Qbuffer_file_coding_system; Lisp_Object Qpost_read_conversion, Qpre_write_conversion; Lisp_Object Qdefault_char; Lisp_Object Qno_conversion, Qundecided; -Lisp_Object Qcharset, Qiso_2022, Qutf_8, Qutf_16, Qshift_jis, Qbig5; +Lisp_Object Qcharset, Qiso_2022, Qutf_8, Qutf_16, Qutf_16le, Qutf_16be, Qutf_16_le, Qutf_16_be, Qshift_jis, Qbig5; Lisp_Object Qbig, Qlittle; Lisp_Object Qcoding_system_history; Lisp_Object Qvalid_codes; @@ -10465,6 +10465,10 @@ syms_of_coding () DEFSYM (Qutf_8_emacs, "utf-8-emacs"); DEFSYM (Qutf_16, "utf-16"); + DEFSYM (Qutf_16_le, "utf-16-le"); + DEFSYM (Qutf_16_be, "utf-16-be"); + DEFSYM (Qutf_16le, "utf-16le"); + DEFSYM (Qutf_16be, "utf-16be"); DEFSYM (Qbig, "big"); DEFSYM (Qlittle, "little"); diff --git a/src/coding.h b/src/coding.h index ca8878f..f37fd73 100644 --- a/src/coding.h +++ b/src/coding.h @@ -757,6 +757,7 @@ extern Lisp_Object preferred_coding_system P_ (()); extern Lisp_Object Qutf_8, Qutf_8_emacs; +extern Lisp_Object Qutf_16, Qutf_16_le, Qutf_16le, Qutf_16be, Qutf_16_be; extern Lisp_Object Qcoding_system, Qeol_type, Qcoding_category_index; extern Lisp_Object Qcoding_system_p; diff --git a/src/w32fns.c b/src/w32fns.c index 8003d79..499d585 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -247,6 +247,8 @@ struct MONITOR_INFO DECLARE_HANDLE(HMONITOR); #endif +#define HAS_UNICODE_WINDOWS (create_window_ex_unicode_fn != NULL) + typedef BOOL (WINAPI * TrackMouseEvent_Proc) (IN OUT LPTRACKMOUSEEVENT lpEventTrack); typedef LONG (WINAPI * ImmGetCompositionString_Proc) @@ -258,6 +260,15 @@ typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context, typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags); typedef BOOL (WINAPI * GetMonitorInfo_Proc) (IN HMONITOR monitor, OUT struct MONITOR_INFO* info); +typedef ATOM (WINAPI * RegisterClassW_Proc) (CONST WNDCLASS *lpWndClass); +typedef HWND (WINAPI * CreateWindowExW_Proc) + (DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, + int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, + HINSTANCE hInstance, LPVOID lpParam); +typedef BOOL (WINAPI * SetWindowTextW_Proc) (HWND hWnd, LPCWSTR lpString); +typedef BOOL (WINAPI * GetMessage_Proc) (LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax); +typedef BOOL (WINAPI * MessageProc_Proc) (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +typedef LRESULT (WINAPI * DispatchMessage_Proc) (const MSG *lpmsg); TrackMouseEvent_Proc track_mouse_event_fn = NULL; ClipboardSequence_Proc clipboard_sequence_fn = NULL; @@ -267,6 +278,13 @@ ImmReleaseContext_Proc release_ime_context_fn = NULL; ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL; MonitorFromPoint_Proc monitor_from_point_fn = NULL; GetMonitorInfo_Proc get_monitor_info_fn = NULL; +RegisterClassW_Proc register_class_unicode_fn = NULL; +CreateWindowExW_Proc create_window_ex_unicode_fn = NULL; +SetWindowTextW_Proc set_window_text_unicode_fn = NULL; +GetMessage_Proc get_message_fn = NULL; +MessageProc_Proc post_message_fn = NULL; +MessageProc_Proc def_window_proc_fn = NULL; +DispatchMessage_Proc dispatch_message_fn = NULL; extern AppendMenuW_Proc unicode_append_menu; @@ -1871,11 +1889,23 @@ x_set_name (f, name, explicit) if (FRAME_W32_WINDOW (f)) { - if (STRING_MULTIBYTE (name)) - name = ENCODE_SYSTEM (name); + /* ensure name is null-terminated */ + if (SREF (name, SBYTES (name) - 1)) + name = make_string (SDATA (name), SBYTES (name) + 1); BLOCK_INPUT; - SetWindowText (FRAME_W32_WINDOW (f), SDATA (name)); + if (set_window_text_unicode_fn) + { + name = code_convert_string_norecord(name, Qutf_16le, 1); + set_window_text_unicode_fn (FRAME_W32_WINDOW (f), + (LPCWSTR) SDATA (name)); + } + else + { + if (STRING_MULTIBYTE (name)) + name = ENCODE_SYSTEM (name); + SetWindowTextA (FRAME_W32_WINDOW (f), SDATA (name)); + } UNBLOCK_INPUT; } } @@ -1923,11 +1953,23 @@ x_set_title (f, name, old_name) if (FRAME_W32_WINDOW (f)) { - if (STRING_MULTIBYTE (name)) - name = ENCODE_SYSTEM (name); + /* ensure name is null-terminated */ + if (SREF (name, SBYTES (name) - 1)) + name = make_string (SDATA (name), SBYTES (name) + 1); BLOCK_INPUT; - SetWindowText (FRAME_W32_WINDOW (f), SDATA (name)); + if (set_window_text_unicode_fn) + { + name = code_convert_string_norecord(name, Qutf_16le, 1); + set_window_text_unicode_fn (FRAME_W32_WINDOW (f), + (LPCWSTR) SDATA (name)); + } + else + { + if (STRING_MULTIBYTE (name)) + name = ENCODE_SYSTEM (name); + SetWindowTextA (FRAME_W32_WINDOW (f), SDATA (name)); + } UNBLOCK_INPUT; } } @@ -1968,20 +2010,42 @@ static BOOL w32_init_class (hinst) 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; - - return (RegisterClass (&wc)); + if (register_class_unicode_fn) + { + WNDCLASSW 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; + + Lisp_Object classStr = make_string(EMACS_CLASS, strlen(EMACS_CLASS) + 1); + classStr = code_convert_string_norecord(classStr, Qutf_16le, 1); + wc.lpszClassName = (LPWSTR) SDATA (classStr); + return (register_class_unicode_fn (&wc)); + } + else + { + WNDCLASSA 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; + return (RegisterClass (&wc)); + } } static HWND @@ -2007,10 +2071,11 @@ w32_createwindow (f) { HWND hwnd; RECT rect; + Lisp_Object classStr = make_string (EMACS_CLASS, strlen (EMACS_CLASS) + 1); + Lisp_Object nameStr = make_string (f->namebuf, strlen(f->namebuf) + 1); Lisp_Object top = Qunbound; Lisp_Object left = Qunbound; struct w32_display_info *dpyinfo = &one_w32_display_info; - rect.left = rect.top = 0; rect.right = FRAME_PIXEL_WIDTH (f); rect.bottom = FRAME_PIXEL_HEIGHT (f); @@ -2038,18 +2103,40 @@ w32_createwindow (f) top = x_get_arg (dpyinfo, Qnil, Qtop, "top", "Top", RES_TYPE_NUMBER); } - FRAME_W32_WINDOW (f) = hwnd - = CreateWindow (EMACS_CLASS, - f->namebuf, - f->output_data.w32->dwStyle | WS_CLIPCHILDREN, - EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left), - EQ (top, Qunbound) ? CW_USEDEFAULT : XINT (top), - rect.right - rect.left, - rect.bottom - rect.top, - NULL, - NULL, - hinst, - NULL); + if (HAS_UNICODE_WINDOWS) + { + classStr = code_convert_string_norecord(classStr, Qutf_16le, 1); + nameStr = code_convert_string_norecord(nameStr, Qutf_16le, 1); + FRAME_W32_WINDOW (f) = hwnd + = create_window_ex_unicode_fn ( + 0, + (LPWSTR) SDATA (classStr), + (LPWSTR) SDATA (nameStr), + f->output_data.w32->dwStyle | WS_CLIPCHILDREN, + EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left), + EQ (top, Qunbound) ? CW_USEDEFAULT : XINT (top), + rect.right - rect.left, + rect.bottom - rect.top, + NULL, + NULL, + hinst, + NULL); + } + else + { + FRAME_W32_WINDOW (f) = hwnd + = CreateWindowA (SDATA (classStr), + SDATA (nameStr), + f->output_data.w32->dwStyle | WS_CLIPCHILDREN, + EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left), + EQ (top, Qunbound) ? CW_USEDEFAULT : XINT (top), + rect.right - rect.left, + rect.bottom - rect.top, + NULL, + NULL, + hinst, + NULL); + } if (hwnd) { @@ -2441,7 +2528,7 @@ w32_msg_pump (deferred_msg * msg_buf) msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL); - while (GetMessage (&msg, NULL, 0, 0)) + while (get_message_fn (&msg, NULL, 0, 0)) { if (msg.hwnd == NULL) { @@ -2536,7 +2623,7 @@ w32_msg_pump (deferred_msg * msg_buf) } else { - DispatchMessage (&msg); + dispatch_message_fn (&msg); } /* Exit nested loop when our deferred message has completed. */ @@ -2897,7 +2984,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam) case WM_HOTKEY: /* Synchronize hot keys with normal input. */ - PostMessage (hwnd, WM_KEYDOWN, HIWORD (lParam), 0); + post_message_fn (hwnd, WM_KEYDOWN, HIWORD (lParam), 0); return (0); case WM_KEYUP: @@ -3995,7 +4082,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam) } dflt: - return DefWindowProc (hwnd, msg, wParam, lParam); + return (def_window_proc_fn (hwnd, msg, wParam, lParam)); } @@ -4011,7 +4098,7 @@ my_create_window (f) if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW, (WPARAM)f, 0)) abort (); - GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); + get_message_fn (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); } @@ -6277,7 +6364,7 @@ If optional parameter FRAME is not specified, use selected frame. */) CHECK_NUMBER (command); - PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, XINT (command), 0); + post_message_fn (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, XINT (command), 0); return Qnil; } @@ -6508,7 +6595,7 @@ DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key, #endif { MSG msg; - GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); + get_message_fn (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); } return Qt; } @@ -6588,7 +6675,7 @@ is set to off if the low bit of NEW-STATE is zero, otherwise on. */) #endif { MSG msg; - GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); + get_message_fn (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); return make_number (msg.wParam); } return Qnil; @@ -7312,6 +7399,20 @@ globals_of_w32fns () GetProcAddress (user32_lib, "MonitorFromPoint"); get_monitor_info_fn = (GetMonitorInfo_Proc) GetProcAddress (user32_lib, "GetMonitorInfoA"); + register_class_unicode_fn = (RegisterClassW_Proc) + GetProcAddress (user32_lib, "RegisterClassW"); + create_window_ex_unicode_fn = (CreateWindowExW_Proc) + GetProcAddress (user32_lib, "CreateWindowExW"); + set_window_text_unicode_fn = (SetWindowTextW_Proc) + GetProcAddress (user32_lib, "SetWindowTextW"); + get_message_fn = (GetMessage_Proc) + GetProcAddress (user32_lib, HAS_UNICODE_WINDOWS ? "GetMessageW" : "GetMessageA"); + post_message_fn = (MessageProc_Proc) + GetProcAddress (user32_lib, HAS_UNICODE_WINDOWS ? "PostMessageW" : "PostMessageA"); + def_window_proc_fn = (MessageProc_Proc) + GetProcAddress (user32_lib, HAS_UNICODE_WINDOWS ? "DefWindowProcW" : "DefWindowProcA"); + dispatch_message_fn = (DispatchMessage_Proc) + GetProcAddress (user32_lib, HAS_UNICODE_WINDOWS ? "DispatchMessageW" : "DispatchMessageA"); { HMODULE imm32_lib = GetModuleHandle ("imm32.dll"); diff --git a/src/w32term.c b/src/w32term.c index b7642b4..5f28b2b 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -4229,10 +4229,14 @@ w32_read_socket (sd, expected, hold_quit) XSETFRAME (inev.frame_or_window, f); inev.timestamp = msg.msg.time; + if (msg.msg.message == WM_UNICHAR) { inev.code = msg.msg.wParam; } + else if (IsWindowUnicode (msg.msg.hwnd)) { + inev.code = msg.msg.wParam; + } else if (msg.msg.wParam < 256) { wchar_t code; @@ -4245,7 +4249,7 @@ w32_read_socket (sd, expected, hold_quit) dbcs[0] = dbcs_lead; dbcs_lead = 0; if (!MultiByteToWideChar (keyboard_codepage, 0, - dbcs, 2, &code, 1)) + dbcs, 2, &code, 1)) { /* Garbage */ DebPrint (("Invalid DBCS sequence: %d %d\n", @@ -4255,7 +4259,7 @@ w32_read_socket (sd, expected, hold_quit) } } else if (IsDBCSLeadByteEx (keyboard_codepage, - (BYTE) msg.msg.wParam)) + (BYTE) msg.msg.wParam)) { dbcs_lead = (char) msg.msg.wParam; inev.kind = NO_EVENT; @@ -4264,7 +4268,7 @@ w32_read_socket (sd, expected, hold_quit) else { if (!MultiByteToWideChar (keyboard_codepage, 0, - &dbcs[1], 1, &code, 1)) + &dbcs[1], 1, &code, 1)) { /* What to do with garbage? */ DebPrint (("Invalid character: %d\n", dbcs[1])); ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: Switch the Windows port to using Unicode keyboard input 2009-10-04 17:41 ` Switch the Windows port to using Unicode keyboard input Eugen Anghel @ 2009-10-04 19:17 ` Eli Zaretskii 2009-10-06 18:11 ` Eugen Anghel 0 siblings, 1 reply; 3+ messages in thread From: Eli Zaretskii @ 2009-10-04 19:17 UTC (permalink / raw) To: Eugen Anghel; +Cc: emacs-devel, lennart.borgman, jasonr > From: Eugen Anghel <eugen@syntactic.org> > Date: Sun, 4 Oct 2009 20:41:53 +0300 > Cc: emacs-devel@gnu.org > > Is having two separate binaries, one for 9x/Me and one for XP/Vista an > option? That would be inconvenient (need two binaries on FTP sites, migrating from 9x to XP needs to install a different binary, etc.). So I think we should do this only if there's no better solution. ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Switch the Windows port to using Unicode keyboard input 2009-10-04 19:17 ` Eli Zaretskii @ 2009-10-06 18:11 ` Eugen Anghel 0 siblings, 0 replies; 3+ messages in thread From: Eugen Anghel @ 2009-10-06 18:11 UTC (permalink / raw) To: Eli Zaretskii, emacs-devel; +Cc: lennart.borgman, jasonr [-- Attachment #1: Type: text/plain, Size: 657 bytes --] 2009/10/4 Eli Zaretskii <eliz@gnu.org>: >> From: Eugen Anghel <eugen@syntactic.org> >> Date: Sun, 4 Oct 2009 20:41:53 +0300 >> Cc: emacs-devel@gnu.org >> >> Is having two separate binaries, one for 9x/Me and one for XP/Vista an >> option? > > That would be inconvenient (need two binaries on FTP sites, migrating > from 9x to XP needs to install a different binary, etc.). So I think > we should do this only if there's no better solution. > Hi. I have attached another patch that should function correctly on XP/Vista without affecting win98/me users in any way. It's working for me on Windows 7 and I'll test it tomorrow on XP at work. [-- Attachment #2: w32-unicode.patch --] [-- Type: application/octet-stream, Size: 15161 bytes --] diff --git a/src/coding.c b/src/coding.c index 405284f..57f3063 100644 --- a/src/coding.c +++ b/src/coding.c @@ -310,7 +310,7 @@ Lisp_Object Qbuffer_file_coding_system; Lisp_Object Qpost_read_conversion, Qpre_write_conversion; Lisp_Object Qdefault_char; Lisp_Object Qno_conversion, Qundecided; -Lisp_Object Qcharset, Qiso_2022, Qutf_8, Qutf_16, Qshift_jis, Qbig5; +Lisp_Object Qcharset, Qiso_2022, Qutf_8, Qutf_16, Qutf_16le, Qutf_16be, Qutf_16_le, Qutf_16_be, Qshift_jis, Qbig5; Lisp_Object Qbig, Qlittle; Lisp_Object Qcoding_system_history; Lisp_Object Qvalid_codes; @@ -10465,6 +10465,10 @@ syms_of_coding () DEFSYM (Qutf_8_emacs, "utf-8-emacs"); DEFSYM (Qutf_16, "utf-16"); + DEFSYM (Qutf_16_le, "utf-16-le"); + DEFSYM (Qutf_16_be, "utf-16-be"); + DEFSYM (Qutf_16le, "utf-16le"); + DEFSYM (Qutf_16be, "utf-16be"); DEFSYM (Qbig, "big"); DEFSYM (Qlittle, "little"); diff --git a/src/coding.h b/src/coding.h index ca8878f..f37fd73 100644 --- a/src/coding.h +++ b/src/coding.h @@ -757,6 +757,7 @@ extern Lisp_Object preferred_coding_system P_ (()); extern Lisp_Object Qutf_8, Qutf_8_emacs; +extern Lisp_Object Qutf_16, Qutf_16_le, Qutf_16le, Qutf_16be, Qutf_16_be; extern Lisp_Object Qcoding_system, Qeol_type, Qcoding_category_index; extern Lisp_Object Qcoding_system_p; diff --git a/src/w32fns.c b/src/w32fns.c index 8003d79..91cfa5e 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -247,6 +247,8 @@ struct MONITOR_INFO DECLARE_HANDLE(HMONITOR); #endif +#define HAS_UNICODE_WINDOWS (create_window_ex_unicode_fn != NULL) + typedef BOOL (WINAPI * TrackMouseEvent_Proc) (IN OUT LPTRACKMOUSEEVENT lpEventTrack); typedef LONG (WINAPI * ImmGetCompositionString_Proc) @@ -258,6 +260,20 @@ typedef HWND (WINAPI * ImmSetCompositionWindow_Proc) (IN HIMC context, typedef HMONITOR (WINAPI * MonitorFromPoint_Proc) (IN POINT pt, IN DWORD flags); typedef BOOL (WINAPI * GetMonitorInfo_Proc) (IN HMONITOR monitor, OUT struct MONITOR_INFO* info); +typedef ATOM (WINAPI * RegisterClassW_Proc) (CONST WNDCLASS *lpWndClass); +typedef HWND (WINAPI * CreateWindowExW_Proc) + (DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, + int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, + HINSTANCE hInstance, LPVOID lpParam); +typedef BOOL (WINAPI * SetWindowText_Proc) (HWND hWnd, LPCSTR lpString); +typedef BOOL (WINAPI * GetMessage_Proc) (LPMSG lpMsg, HWND hWnd, UINT + wMsgFilterMin, UINT wMsgFilterMax); +typedef BOOL (WINAPI * MessageProc_Proc) (HWND hWnd, UINT msg, + WPARAM wParam, LPARAM lParam); +typedef LRESULT (WINAPI * DispatchMessage_Proc) (const MSG *lpmsg); +typedef BOOL (WINAPI * PeekMessage_Proc) + (LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, + UINT wMsgFilterMax, UINT wRemoveMsg); TrackMouseEvent_Proc track_mouse_event_fn = NULL; ClipboardSequence_Proc clipboard_sequence_fn = NULL; @@ -267,6 +283,14 @@ ImmReleaseContext_Proc release_ime_context_fn = NULL; ImmSetCompositionWindow_Proc set_ime_composition_window_fn = NULL; MonitorFromPoint_Proc monitor_from_point_fn = NULL; GetMonitorInfo_Proc get_monitor_info_fn = NULL; +RegisterClassW_Proc register_class_unicode_fn = NULL; +CreateWindowExW_Proc create_window_ex_unicode_fn = NULL; +SetWindowText_Proc set_window_text_fn = NULL; +GetMessage_Proc get_message_fn = NULL; +MessageProc_Proc post_message_fn = NULL; +MessageProc_Proc def_window_proc_fn = NULL; +DispatchMessage_Proc dispatch_message_fn = NULL; +PeekMessage_Proc peek_message_fn = NULL; extern AppendMenuW_Proc unicode_append_menu; @@ -1871,11 +1895,18 @@ x_set_name (f, name, explicit) if (FRAME_W32_WINDOW (f)) { - if (STRING_MULTIBYTE (name)) - name = ENCODE_SYSTEM (name); + /* ensure name is null-terminated */ + if (SREF (name, SBYTES (name) - 1)) + name = make_string (SDATA (name), SBYTES (name) + 1); BLOCK_INPUT; - SetWindowText (FRAME_W32_WINDOW (f), SDATA (name)); + if (HAS_UNICODE_WINDOWS) + name = code_convert_string_norecord(name, Qutf_16le, 1); + else + if (STRING_MULTIBYTE (name)) + name = ENCODE_SYSTEM (name); + + set_window_text_fn (FRAME_W32_WINDOW (f), SDATA (name)); UNBLOCK_INPUT; } } @@ -1923,11 +1954,18 @@ x_set_title (f, name, old_name) if (FRAME_W32_WINDOW (f)) { - if (STRING_MULTIBYTE (name)) - name = ENCODE_SYSTEM (name); + /* ensure name is null-terminated */ + if (SREF (name, SBYTES (name) - 1)) + name = make_string (SDATA (name), SBYTES (name) + 1); BLOCK_INPUT; - SetWindowText (FRAME_W32_WINDOW (f), SDATA (name)); + if (HAS_UNICODE_WINDOWS) + name = code_convert_string_norecord(name, Qutf_16le, 1); + else + if (STRING_MULTIBYTE (name)) + name = ENCODE_SYSTEM (name); + + set_window_text_fn (FRAME_W32_WINDOW (f), SDATA (name)); UNBLOCK_INPUT; } } @@ -1968,20 +2006,42 @@ static BOOL w32_init_class (hinst) 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; - - return (RegisterClass (&wc)); + if (register_class_unicode_fn) + { + WNDCLASSW 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; + + Lisp_Object classStr = make_string(EMACS_CLASS, strlen(EMACS_CLASS) + 1); + classStr = code_convert_string_norecord(classStr, Qutf_16le, 1); + wc.lpszClassName = (LPWSTR) SDATA (classStr); + return (register_class_unicode_fn (&wc)); + } + else + { + WNDCLASSA 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; + return (RegisterClass (&wc)); + } } static HWND @@ -2007,10 +2067,11 @@ w32_createwindow (f) { HWND hwnd; RECT rect; + Lisp_Object classStr = make_string (EMACS_CLASS, strlen (EMACS_CLASS) + 1); + Lisp_Object nameStr = make_string (f->namebuf, strlen(f->namebuf) + 1); Lisp_Object top = Qunbound; Lisp_Object left = Qunbound; struct w32_display_info *dpyinfo = &one_w32_display_info; - rect.left = rect.top = 0; rect.right = FRAME_PIXEL_WIDTH (f); rect.bottom = FRAME_PIXEL_HEIGHT (f); @@ -2038,18 +2099,40 @@ w32_createwindow (f) top = x_get_arg (dpyinfo, Qnil, Qtop, "top", "Top", RES_TYPE_NUMBER); } - FRAME_W32_WINDOW (f) = hwnd - = CreateWindow (EMACS_CLASS, - f->namebuf, - f->output_data.w32->dwStyle | WS_CLIPCHILDREN, - EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left), - EQ (top, Qunbound) ? CW_USEDEFAULT : XINT (top), - rect.right - rect.left, - rect.bottom - rect.top, - NULL, - NULL, - hinst, - NULL); + if (HAS_UNICODE_WINDOWS) + { + classStr = code_convert_string_norecord(classStr, Qutf_16le, 1); + nameStr = code_convert_string_norecord(nameStr, Qutf_16le, 1); + FRAME_W32_WINDOW (f) = hwnd + = create_window_ex_unicode_fn ( + 0, + (LPWSTR) SDATA (classStr), + (LPWSTR) SDATA (nameStr), + f->output_data.w32->dwStyle | WS_CLIPCHILDREN, + EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left), + EQ (top, Qunbound) ? CW_USEDEFAULT : XINT (top), + rect.right - rect.left, + rect.bottom - rect.top, + NULL, + NULL, + hinst, + NULL); + } + else + { + FRAME_W32_WINDOW (f) = hwnd + = CreateWindowA (SDATA (classStr), + SDATA (nameStr), + f->output_data.w32->dwStyle | WS_CLIPCHILDREN, + EQ (left, Qunbound) ? CW_USEDEFAULT : XINT (left), + EQ (top, Qunbound) ? CW_USEDEFAULT : XINT (top), + rect.right - rect.left, + rect.bottom - rect.top, + NULL, + NULL, + hinst, + NULL); + } if (hwnd) { @@ -2441,7 +2524,7 @@ w32_msg_pump (deferred_msg * msg_buf) msh_mousewheel = RegisterWindowMessage (MSH_MOUSEWHEEL); - while (GetMessage (&msg, NULL, 0, 0)) + while (get_message_fn (&msg, NULL, 0, 0)) { if (msg.hwnd == NULL) { @@ -2536,7 +2619,7 @@ w32_msg_pump (deferred_msg * msg_buf) } else { - DispatchMessage (&msg); + dispatch_message_fn (&msg); } /* Exit nested loop when our deferred message has completed. */ @@ -2649,7 +2732,7 @@ w32_msg_worker (void *arg) /* Ensure our message queue is created */ - PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE); + peek_message_fn (&msg, NULL, 0, 0, PM_NOREMOVE); if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0)) abort (); @@ -2897,7 +2980,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam) case WM_HOTKEY: /* Synchronize hot keys with normal input. */ - PostMessage (hwnd, WM_KEYDOWN, HIWORD (lParam), 0); + post_message_fn (hwnd, WM_KEYDOWN, HIWORD (lParam), 0); return (0); case WM_KEYUP: @@ -3964,10 +4047,10 @@ w32_wnd_proc (hwnd, msg, wParam, lParam) { MSG amsg; /* Eat any mouse messages during popupmenu */ - while (PeekMessage (&amsg, hwnd, WM_MOUSEFIRST, WM_MOUSELAST, + while (peek_message_fn (&amsg, hwnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE)); /* Get the menu selection, if any */ - if (PeekMessage (&amsg, hwnd, WM_COMMAND, WM_COMMAND, PM_REMOVE)) + if (peek_message_fn (&amsg, hwnd, WM_COMMAND, WM_COMMAND, PM_REMOVE)) { retval = LOWORD (amsg.wParam); } @@ -3995,7 +4078,7 @@ w32_wnd_proc (hwnd, msg, wParam, lParam) } dflt: - return DefWindowProc (hwnd, msg, wParam, lParam); + return (def_window_proc_fn (hwnd, msg, wParam, lParam)); } @@ -4011,7 +4094,7 @@ my_create_window (f) if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW, (WPARAM)f, 0)) abort (); - GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); + get_message_fn (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); } @@ -6277,7 +6360,7 @@ If optional parameter FRAME is not specified, use selected frame. */) CHECK_NUMBER (command); - PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, XINT (command), 0); + post_message_fn (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, XINT (command), 0); return Qnil; } @@ -6508,7 +6591,7 @@ DEFUN ("w32-unregister-hot-key", Fw32_unregister_hot_key, #endif { MSG msg; - GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); + get_message_fn (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); } return Qt; } @@ -6588,7 +6671,7 @@ is set to off if the low bit of NEW-STATE is zero, otherwise on. */) #endif { MSG msg; - GetMessage (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); + get_message_fn (&msg, NULL, WM_EMACS_DONE, WM_EMACS_DONE); return make_number (msg.wParam); } return Qnil; @@ -7312,6 +7395,22 @@ globals_of_w32fns () GetProcAddress (user32_lib, "MonitorFromPoint"); get_monitor_info_fn = (GetMonitorInfo_Proc) GetProcAddress (user32_lib, "GetMonitorInfoA"); + register_class_unicode_fn = (RegisterClassW_Proc) + GetProcAddress (user32_lib, "RegisterClassW"); + create_window_ex_unicode_fn = (CreateWindowExW_Proc) + GetProcAddress (user32_lib, "CreateWindowExW"); + set_window_text_fn = (SetWindowText_Proc) + GetProcAddress (user32_lib, HAS_UNICODE_WINDOWS ? "SetWindowTextW" : "SetWindowTextA"); + get_message_fn = (GetMessage_Proc) + GetProcAddress (user32_lib, HAS_UNICODE_WINDOWS ? "GetMessageW" : "GetMessageA"); + post_message_fn = (MessageProc_Proc) + GetProcAddress (user32_lib, HAS_UNICODE_WINDOWS ? "PostMessageW" : "PostMessageA"); + def_window_proc_fn = (MessageProc_Proc) + GetProcAddress (user32_lib, HAS_UNICODE_WINDOWS ? "DefWindowProcW" : "DefWindowProcA"); + dispatch_message_fn = (DispatchMessage_Proc) + GetProcAddress (user32_lib, HAS_UNICODE_WINDOWS ? "DispatchMessageW" : "DispatchMessageA"); + peek_message_fn = (PeekMessage_Proc) + GetProcAddress (user32_lib, HAS_UNICODE_WINDOWS ? "PeekMessageW" : "PeekMessageA"); { HMODULE imm32_lib = GetModuleHandle ("imm32.dll"); diff --git a/src/w32term.c b/src/w32term.c index b7642b4..5f28b2b 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -4229,10 +4229,14 @@ w32_read_socket (sd, expected, hold_quit) XSETFRAME (inev.frame_or_window, f); inev.timestamp = msg.msg.time; + if (msg.msg.message == WM_UNICHAR) { inev.code = msg.msg.wParam; } + else if (IsWindowUnicode (msg.msg.hwnd)) { + inev.code = msg.msg.wParam; + } else if (msg.msg.wParam < 256) { wchar_t code; @@ -4245,7 +4249,7 @@ w32_read_socket (sd, expected, hold_quit) dbcs[0] = dbcs_lead; dbcs_lead = 0; if (!MultiByteToWideChar (keyboard_codepage, 0, - dbcs, 2, &code, 1)) + dbcs, 2, &code, 1)) { /* Garbage */ DebPrint (("Invalid DBCS sequence: %d %d\n", @@ -4255,7 +4259,7 @@ w32_read_socket (sd, expected, hold_quit) } } else if (IsDBCSLeadByteEx (keyboard_codepage, - (BYTE) msg.msg.wParam)) + (BYTE) msg.msg.wParam)) { dbcs_lead = (char) msg.msg.wParam; inev.kind = NO_EVENT; @@ -4264,7 +4268,7 @@ w32_read_socket (sd, expected, hold_quit) else { if (!MultiByteToWideChar (keyboard_codepage, 0, - &dbcs[1], 1, &code, 1)) + &dbcs[1], 1, &code, 1)) { /* What to do with garbage? */ DebPrint (("Invalid character: %d\n", dbcs[1])); ^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-10-06 18:11 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- [not found] <ffeec6560910040639o8646689qb1622d487a10c043@mail.gmail.com> [not found] ` <83y6nrnthg.fsf@gnu.org> [not found] ` <e01d8a50910040712v56c96b4bp64d3f1105382f527@mail.gmail.com> [not found] ` <4AC8B391.4020906@gnu.org> 2009-10-04 17:41 ` Switch the Windows port to using Unicode keyboard input Eugen Anghel 2009-10-04 19:17 ` Eli Zaretskii 2009-10-06 18:11 ` Eugen Anghel
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).