Ken Thomases : winemac: Implement fake support for the active Windows keyboard layout.
Alexandre Julliard
julliard at winehq.org
Wed Feb 6 13:38:12 CST 2013
Module: wine
Branch: master
Commit: 956ec4320174f003d753d2e94213f9c58b23d0e8
URL: http://source.winehq.org/git/wine.git/?a=commit;h=956ec4320174f003d753d2e94213f9c58b23d0e8
Author: Ken Thomases <ken at codeweavers.com>
Date: Wed Feb 6 04:37:04 2013 -0600
winemac: Implement fake support for the active Windows keyboard layout.
---
dlls/winemac.drv/keyboard.c | 127 +++++++++++++++++++++++++++++++++++++
dlls/winemac.drv/macdrv.h | 1 +
dlls/winemac.drv/winemac.drv.spec | 3 +
3 files changed, 131 insertions(+), 0 deletions(-)
diff --git a/dlls/winemac.drv/keyboard.c b/dlls/winemac.drv/keyboard.c
index ae8df76..7b773e3 100644
--- a/dlls/winemac.drv/keyboard.c
+++ b/dlls/winemac.drv/keyboard.c
@@ -847,6 +847,93 @@ void macdrv_keyboard_changed(const macdrv_event *event)
/***********************************************************************
+ * get_locale_keyboard_layout
+ */
+static HKL get_locale_keyboard_layout(void)
+{
+ ULONG_PTR layout;
+ LANGID langid;
+
+ layout = GetUserDefaultLCID();
+
+ /*
+ * Microsoft Office expects this value to be something specific
+ * for Japanese and Korean Windows with an IME the value is 0xe001
+ * We should probably check to see if an IME exists and if so then
+ * set this word properly.
+ */
+ langid = PRIMARYLANGID(LANGIDFROMLCID(layout));
+ if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN)
+ layout |= 0xe001 << 16; /* IME */
+ else
+ layout |= layout << 16;
+
+ return (HKL)layout;
+}
+
+
+/***********************************************************************
+ * match_keyboard_layout
+ */
+static BOOL match_keyboard_layout(HKL hkl)
+{
+ const DWORD isIME = 0xE0000000;
+ HKL current_hkl = get_locale_keyboard_layout();
+
+ /* if the layout is an IME, only match the low word (LCID) */
+ if (((ULONG_PTR)hkl & isIME) == isIME)
+ return (LOWORD(hkl) == LOWORD(current_hkl));
+ else
+ return (hkl == current_hkl);
+}
+
+
+/***********************************************************************
+ * ActivateKeyboardLayout (MACDRV.@)
+ */
+HKL CDECL macdrv_ActivateKeyboardLayout(HKL hkl, UINT flags)
+{
+ HKL oldHkl = 0;
+ struct macdrv_thread_data *thread_data = macdrv_init_thread_data();
+
+ /* FIXME: Use Text Input Services or NSTextInputContext to actually
+ change the Mac keyboard input source. */
+
+ FIXME("hkl %p flags %04x: semi-stub!\n", hkl, flags);
+ if (flags & KLF_SETFORPROCESS)
+ {
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ FIXME("KLF_SETFORPROCESS not supported\n");
+ return 0;
+ }
+
+ if (flags)
+ FIXME("flags %x not supported\n",flags);
+
+ if (hkl == (HKL)HKL_NEXT || hkl == (HKL)HKL_PREV)
+ {
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ FIXME("HKL_NEXT and HKL_PREV not supported\n");
+ return 0;
+ }
+
+ if (!match_keyboard_layout(hkl))
+ {
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ FIXME("setting keyboard of different locales not supported\n");
+ return 0;
+ }
+
+ oldHkl = thread_data->active_keyboard_layout;
+ if (!oldHkl) oldHkl = get_locale_keyboard_layout();
+
+ thread_data->active_keyboard_layout = hkl;
+
+ return oldHkl;
+}
+
+
+/***********************************************************************
* Beep (MACDRV.@)
*/
void CDECL macdrv_Beep(void)
@@ -945,6 +1032,46 @@ INT CDECL macdrv_GetKeyNameText(LONG lparam, LPWSTR buffer, INT size)
/***********************************************************************
+ * GetKeyboardLayout (MACDRV.@)
+ */
+HKL CDECL macdrv_GetKeyboardLayout(DWORD thread_id)
+{
+ if (!thread_id || thread_id == GetCurrentThreadId())
+ {
+ struct macdrv_thread_data *thread_data = macdrv_thread_data();
+ if (thread_data && thread_data->active_keyboard_layout)
+ return thread_data->active_keyboard_layout;
+ }
+ else
+ FIXME("couldn't return keyboard layout for thread %04x\n", thread_id);
+
+ /* FIXME: Use TISGetInputSourceProperty() and kTISPropertyInputSourceLanguages
+ * to get input source language ID string. Use
+ * CFLocaleGetWindowsLocaleCodeFromLocaleIdentifier() to convert that
+ * to a Windows locale ID and from there to a layout handle.
+ */
+
+ return get_locale_keyboard_layout();
+}
+
+
+/***********************************************************************
+ * GetKeyboardLayoutName (MACDRV.@)
+ */
+BOOL CDECL macdrv_GetKeyboardLayoutName(LPWSTR name)
+{
+ static const WCHAR formatW[] = {'%','0','8','x',0};
+ DWORD layout;
+
+ layout = HandleToUlong(get_locale_keyboard_layout());
+ if (HIWORD(layout) == LOWORD(layout)) layout = LOWORD(layout);
+ sprintfW(name, formatW, layout);
+ TRACE("returning %s\n", debugstr_w(name));
+ return TRUE;
+}
+
+
+/***********************************************************************
* MapVirtualKeyEx (MACDRV.@)
*/
UINT CDECL macdrv_MapVirtualKeyEx(UINT wCode, UINT wMapType, HKL hkl)
diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h
index 4dc1e3e..e24d8ab 100644
--- a/dlls/winemac.drv/macdrv.h
+++ b/dlls/winemac.drv/macdrv.h
@@ -89,6 +89,7 @@ struct macdrv_thread_data
int iso_keyboard;
CGEventFlags last_modifiers;
UInt32 dead_key_state;
+ HKL active_keyboard_layout;
WORD keyc2vkey[128];
WORD keyc2scan[128];
};
diff --git a/dlls/winemac.drv/winemac.drv.spec b/dlls/winemac.drv/winemac.drv.spec
index 1bb7d8c..30df9d6 100644
--- a/dlls/winemac.drv/winemac.drv.spec
+++ b/dlls/winemac.drv/winemac.drv.spec
@@ -4,11 +4,14 @@
# USER driver
+@ cdecl ActivateKeyboardLayout(long long) macdrv_ActivateKeyboardLayout
@ cdecl Beep() macdrv_Beep
@ cdecl CreateDesktopWindow(long) macdrv_CreateDesktopWindow
@ cdecl CreateWindow(long) macdrv_CreateWindow
@ cdecl DestroyWindow(long) macdrv_DestroyWindow
@ cdecl EnumDisplayMonitors(long ptr ptr long) macdrv_EnumDisplayMonitors
+@ cdecl GetKeyboardLayout(long) macdrv_GetKeyboardLayout
+@ cdecl GetKeyboardLayoutName(ptr) macdrv_GetKeyboardLayoutName
@ cdecl GetKeyNameText(long ptr long) macdrv_GetKeyNameText
@ cdecl GetMonitorInfo(long ptr) macdrv_GetMonitorInfo
@ cdecl MapVirtualKeyEx(long long long) macdrv_MapVirtualKeyEx
More information about the wine-cvs
mailing list