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