Add preliminary support for keyboard layout APIs.
diff --git a/dlls/ttydrv/ttydrv.spec b/dlls/ttydrv/ttydrv.spec
index 9b75498..4f10c4c 100644
--- a/dlls/ttydrv/ttydrv.spec
+++ b/dlls/ttydrv/ttydrv.spec
@@ -35,10 +35,10 @@
# USER driver
-@ cdecl VkKeyScan(long) TTYDRV_VkKeyScan
-@ cdecl MapVirtualKey(long long) TTYDRV_MapVirtualKey
-@ cdecl GetKeyNameText(long str long) TTYDRV_GetKeyNameText
-@ cdecl ToUnicode(long long ptr ptr long long) TTYDRV_ToUnicode
+@ cdecl VkKeyScanEx(long long) TTYDRV_VkKeyScanEx
+@ cdecl MapVirtualKeyEx(long long long) TTYDRV_MapVirtualKeyEx
+@ cdecl GetKeyNameText(long ptr long) TTYDRV_GetKeyNameText
+@ cdecl ToUnicodeEx(long long ptr ptr long long long) TTYDRV_ToUnicodeEx
@ cdecl Beep() TTYDRV_Beep
@ cdecl SetCursor(ptr) TTYDRV_SetCursor
@ cdecl GetScreenSaveActive() TTYDRV_GetScreenSaveActive
diff --git a/dlls/ttydrv/user.c b/dlls/ttydrv/user.c
index 9c9afdb..fad2331 100644
--- a/dlls/ttydrv/user.c
+++ b/dlls/ttydrv/user.c
@@ -34,17 +34,17 @@
struct tagCURSORICONINFO;
/***********************************************************************
- * VkKeyScan (TTYDRV.@)
+ * VkKeyScanEx (TTYDRV.@)
*/
-WORD TTYDRV_VkKeyScan(CHAR cChar)
+SHORT TTYDRV_VkKeyScanEx(WCHAR cChar, HKL hkl)
{
return 0;
}
/***********************************************************************
- * MapVirtualKey (TTYDRV.@)
+ * MapVirtualKeyEx (TTYDRV.@)
*/
-UINT16 TTYDRV_MapVirtualKey(UINT16 wCode, UINT16 wMapType)
+UINT TTYDRV_MapVirtualKeyEx(UINT wCode, UINT wMapType, HKL hkl)
{
return 0;
}
@@ -52,7 +52,7 @@
/***********************************************************************
* GetKeyNameText (TTYDRV.@)
*/
-INT16 TTYDRV_GetKeyNameText( LONG lParam, LPSTR lpBuffer, INT16 nSize )
+INT TTYDRV_GetKeyNameText( LONG lParam, LPWSTR lpBuffer, INT nSize )
{
if(lpBuffer && nSize)
{
@@ -62,10 +62,10 @@
}
/***********************************************************************
- * ToUnicode (TTYDRV.@)
+ * ToUnicodeEx (TTYDRV.@)
*/
-INT TTYDRV_ToUnicode( UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
- LPWSTR pwszBuff, int cchBuff, UINT flags )
+INT TTYDRV_ToUnicodeEx( UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
+ LPWSTR pwszBuff, int cchBuff, UINT flags, HKL hkl )
{
return 0;
}
diff --git a/dlls/user/user32.spec b/dlls/user/user32.spec
index 22c5705..ef3fe23 100644
--- a/dlls/user/user32.spec
+++ b/dlls/user/user32.spec
@@ -591,7 +591,7 @@
@ stdcall UnhookWindowsHook(long ptr)
@ stdcall UnhookWindowsHookEx(long)
@ stdcall UnionRect(ptr ptr ptr)
-@ stub UnloadKeyboardLayout
+@ stdcall UnloadKeyboardLayout(long)
@ stub UnlockWindowStation
@ stdcall UnpackDDElParam(long long ptr ptr)
@ stdcall UnregisterClassA(str long)
diff --git a/dlls/user/user_main.c b/dlls/user/user_main.c
index 999c8b1..d8e5262 100644
--- a/dlls/user/user_main.c
+++ b/dlls/user/user_main.c
@@ -76,10 +76,16 @@
}
GET_USER_FUNC(InitKeyboard);
- GET_USER_FUNC(VkKeyScan);
- GET_USER_FUNC(MapVirtualKey);
+ GET_USER_FUNC(VkKeyScanEx);
+ GET_USER_FUNC(MapVirtualKeyEx);
GET_USER_FUNC(GetKeyNameText);
- GET_USER_FUNC(ToUnicode);
+ GET_USER_FUNC(ToUnicodeEx);
+ GET_USER_FUNC(GetKeyboardLayoutList);
+ GET_USER_FUNC(GetKeyboardLayout);
+ GET_USER_FUNC(GetKeyboardLayoutName);
+ GET_USER_FUNC(LoadKeyboardLayout);
+ GET_USER_FUNC(ActivateKeyboardLayout);
+ GET_USER_FUNC(UnloadKeyboardLayout);
GET_USER_FUNC(Beep);
GET_USER_FUNC(InitMouse);
GET_USER_FUNC(SetCursor);
diff --git a/dlls/x11drv/Makefile.in b/dlls/x11drv/Makefile.in
index a083dfe..dc24c19 100644
--- a/dlls/x11drv/Makefile.in
+++ b/dlls/x11drv/Makefile.in
@@ -6,7 +6,7 @@
MODULE = x11drv.dll
IMPORTS = user32 gdi32 advapi32 kernel32 ntdll
EXTRAINCL = @X_CFLAGS@
-EXTRALIBS = @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@
+EXTRALIBS = $(LIBUNICODE) @X_LIBS@ @X_PRE_LIBS@ @XLIB@ @X_EXTRA_LIBS@
C_SRCS = \
$(TOPOBJDIR)/graphics/x11drv/bitblt.c \
diff --git a/dlls/x11drv/keyboard.c b/dlls/x11drv/keyboard.c
index 8a8b80f..1c1ce06 100644
--- a/dlls/x11drv/keyboard.c
+++ b/dlls/x11drv/keyboard.c
@@ -44,10 +44,12 @@
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
+#include "winuser.h"
#include "wine/winuser16.h"
#include "winnls.h"
#include "win.h"
#include "x11drv.h"
+#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(keyboard);
@@ -115,6 +117,16 @@
VK_OEM_102 /* the 102nd key (actually to the right of l-shift) */
};
+static const WORD main_key_vkey_qwerty_v2[MAIN_LEN] =
+{
+/* NOTE: this layout must concur with the scan codes layout above */
+ VK_OEM_5,VK_1,VK_2,VK_3,VK_4,VK_5,VK_6,VK_7,VK_8,VK_9,VK_0,VK_OEM_PLUS,VK_OEM_4,
+ VK_Q,VK_W,VK_E,VK_R,VK_T,VK_Y,VK_U,VK_I,VK_O,VK_P,VK_OEM_6,VK_OEM_1,
+ VK_A,VK_S,VK_D,VK_F,VK_G,VK_H,VK_J,VK_K,VK_L,VK_OEM_3,VK_OEM_7,VK_OEM_2,
+ VK_Z,VK_X,VK_C,VK_V,VK_B,VK_N,VK_M,VK_OEM_COMMA,VK_OEM_PERIOD,VK_OEM_MINUS,
+ VK_OEM_102 /* the 102nd key (actually to the right of l-shift) */
+};
+
static const WORD main_key_vkey_qwertz[MAIN_LEN] =
{
/* NOTE: this layout must concur with the scan codes layout above */
@@ -738,68 +750,70 @@
/*** Layout table. Add your keyboard mappings to this list */
static const struct {
+ LCID lcid; /* input locale identifier, look for LOCALE_ILANGUAGE
+ in the appropriate dlls/kernel/nls/.nls file */
const char *comment;
const char (*key)[MAIN_LEN][4];
const WORD (*scan)[MAIN_LEN]; /* scan codes mapping */
const WORD (*vkey)[MAIN_LEN]; /* virtual key codes mapping */
} main_key_tab[]={
- {"United States keyboard layout", &main_key_US, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"United States keyboard layout (phantom key version)", &main_key_US_phantom, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"United States keyboard layout (dvorak)", &main_key_US_dvorak, &main_key_scan_dvorak, &main_key_vkey_dvorak},
- {"British keyboard layout", &main_key_UK, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"German keyboard layout", &main_key_DE, &main_key_scan_qwerty, &main_key_vkey_qwertz},
- {"German keyboard layout without dead keys", &main_key_DE_nodead, &main_key_scan_qwerty, &main_key_vkey_qwertz},
- {"German keyboard layout for logitech desktop pro", &main_key_DE_logitech, &main_key_scan_qwerty, &main_key_vkey_qwertz},
- {"German keyboard layout without dead keys 105", &main_key_DE_nodead_105, &main_key_scan_qwerty, &main_key_vkey_qwertz_105},
- {"Swiss German keyboard layout", &main_key_SG, &main_key_scan_qwerty, &main_key_vkey_qwertz},
- {"Swiss French keyboard layout", &main_key_SF, &main_key_scan_qwerty, &main_key_vkey_qwertz},
- {"Swedish keyboard layout", &main_key_SE, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Estonian keyboard layout", &main_key_ET, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Norwegian keyboard layout", &main_key_NO, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Danish keyboard layout", &main_key_DA, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"French keyboard layout", &main_key_FR, &main_key_scan_qwerty, &main_key_vkey_azerty},
- {"Canadian French keyboard layout", &main_key_CF, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Belgian keyboard layout", &main_key_BE, &main_key_scan_qwerty, &main_key_vkey_azerty},
- {"Portuguese keyboard layout", &main_key_PT, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Brazilian ABNT-2 keyboard layout", &main_key_PT_br, &main_key_scan_abnt_qwerty, &main_key_vkey_abnt_qwerty},
- {"Brazilian ABNT-2 keyboard layout ALT GR", &main_key_PT_br_alt_gr,&main_key_scan_abnt_qwerty, &main_key_vkey_abnt_qwerty},
- {"United States International keyboard layout", &main_key_US_intl, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Finnish keyboard layout", &main_key_FI, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Bulgarian bds keyboard layout", &main_key_BG_bds, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Bulgarian phonetic keyboard layout", &main_key_BG_phonetic, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Belarusian keyboard layout", &main_key_BY, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Russian keyboard layout", &main_key_RU, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Russian keyboard layout (phantom key version)", &main_key_RU_phantom, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Russian keyboard layout KOI8-R", &main_key_RU_koi8r, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Russian keyboard layout cp1251", &main_key_RU_cp1251, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Russian phonetic keyboard layout", &main_key_RU_phonetic, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Ukrainian keyboard layout KOI8-U", &main_key_UA, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Spanish keyboard layout", &main_key_ES, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Italian keyboard layout", &main_key_IT, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Icelandic keyboard layout", &main_key_IS, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Hungarian keyboard layout", &main_key_HU, &main_key_scan_qwerty, &main_key_vkey_qwertz},
- {"Polish (programmer's) keyboard layout", &main_key_PL, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Slovenian keyboard layout", &main_key_SI, &main_key_scan_qwerty, &main_key_vkey_qwertz},
- {"Croatian keyboard layout", &main_key_HR, &main_key_scan_qwerty, &main_key_vkey_qwertz},
- {"Croatian keyboard layout (specific)", &main_key_HR_jelly, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Japanese 106 keyboard layout", &main_key_JA_jp106, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Japanese pc98x1 keyboard layout", &main_key_JA_pc98x1, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Slovak keyboard layout", &main_key_SK, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Slovak and Czech keyboard layout without dead keys", &main_key_SK_prog, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Czech keyboard layout", &main_key_CS, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Czech keyboard layout cz", &main_key_CZ, &main_key_scan_qwerty, &main_key_vkey_qwertz},
- {"Czech keyboard layout cz_qwerty", &main_key_CZ_qwerty, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Latin American keyboard layout", &main_key_LA, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Lithuanian (Baltic) keyboard layout", &main_key_LT_B, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Turkish keyboard layout", &main_key_TK, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Israelian keyboard layout", &main_key_IL, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Israelian phonetic keyboard layout", &main_key_IL_phonetic, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Israelian Saharon keyboard layout", &main_key_IL_saharon, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"VNC keyboard layout", &main_key_vnc, &main_key_scan_vnc, &main_key_vkey_vnc},
- {"Greek keyboard layout", &main_key_EL, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {"Thai (Kedmanee) keyboard layout", &main_key_th, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0409, "United States keyboard layout", &main_key_US, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0409, "United States keyboard layout (phantom key version)", &main_key_US_phantom, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0409, "United States keyboard layout (dvorak)", &main_key_US_dvorak, &main_key_scan_dvorak, &main_key_vkey_dvorak},
+ {0x0409, "United States International keyboard layout", &main_key_US_intl, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0809, "British keyboard layout", &main_key_UK, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0407, "German keyboard layout", &main_key_DE, &main_key_scan_qwerty, &main_key_vkey_qwertz},
+ {0x0407, "German keyboard layout without dead keys", &main_key_DE_nodead, &main_key_scan_qwerty, &main_key_vkey_qwertz},
+ {0x0407, "German keyboard layout for logitech desktop pro", &main_key_DE_logitech, &main_key_scan_qwerty, &main_key_vkey_qwertz},
+ {0x0407, "German keyboard layout without dead keys 105", &main_key_DE_nodead_105, &main_key_scan_qwerty, &main_key_vkey_qwertz_105},
+ {0x0807, "Swiss German keyboard layout", &main_key_SG, &main_key_scan_qwerty, &main_key_vkey_qwertz},
+ {0x100c, "Swiss French keyboard layout", &main_key_SF, &main_key_scan_qwerty, &main_key_vkey_qwertz},
+ {0x041d, "Swedish keyboard layout", &main_key_SE, &main_key_scan_qwerty, &main_key_vkey_qwerty_v2},
+ {0x0425, "Estonian keyboard layout", &main_key_ET, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0414, "Norwegian keyboard layout", &main_key_NO, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0406, "Danish keyboard layout", &main_key_DA, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x040c, "French keyboard layout", &main_key_FR, &main_key_scan_qwerty, &main_key_vkey_azerty},
+ {0x0c0c, "Canadian French keyboard layout", &main_key_CF, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x080c, "Belgian keyboard layout", &main_key_BE, &main_key_scan_qwerty, &main_key_vkey_azerty},
+ {0x0816, "Portuguese keyboard layout", &main_key_PT, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0416, "Brazilian ABNT-2 keyboard layout", &main_key_PT_br, &main_key_scan_abnt_qwerty, &main_key_vkey_abnt_qwerty},
+ {0x0416, "Brazilian ABNT-2 keyboard layout ALT GR", &main_key_PT_br_alt_gr,&main_key_scan_abnt_qwerty, &main_key_vkey_abnt_qwerty},
+ {0x040b, "Finnish keyboard layout", &main_key_FI, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0402, "Bulgarian bds keyboard layout", &main_key_BG_bds, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0402, "Bulgarian phonetic keyboard layout", &main_key_BG_phonetic, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0423, "Belarusian keyboard layout", &main_key_BY, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0419, "Russian keyboard layout", &main_key_RU, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0419, "Russian keyboard layout (phantom key version)", &main_key_RU_phantom, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0419, "Russian keyboard layout KOI8-R", &main_key_RU_koi8r, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0419, "Russian keyboard layout cp1251", &main_key_RU_cp1251, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0419, "Russian phonetic keyboard layout", &main_key_RU_phonetic, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0422, "Ukrainian keyboard layout KOI8-U", &main_key_UA, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x040a, "Spanish keyboard layout", &main_key_ES, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0410, "Italian keyboard layout", &main_key_IT, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x040f, "Icelandic keyboard layout", &main_key_IS, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x040e, "Hungarian keyboard layout", &main_key_HU, &main_key_scan_qwerty, &main_key_vkey_qwertz},
+ {0x0415, "Polish (programmer's) keyboard layout", &main_key_PL, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0424, "Slovenian keyboard layout", &main_key_SI, &main_key_scan_qwerty, &main_key_vkey_qwertz},
+ {0x041a, "Croatian keyboard layout", &main_key_HR, &main_key_scan_qwerty, &main_key_vkey_qwertz},
+ {0x041a, "Croatian keyboard layout (specific)", &main_key_HR_jelly, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0411, "Japanese 106 keyboard layout", &main_key_JA_jp106, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0411, "Japanese pc98x1 keyboard layout", &main_key_JA_pc98x1, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x041b, "Slovak keyboard layout", &main_key_SK, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x041b, "Slovak and Czech keyboard layout without dead keys", &main_key_SK_prog, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0405, "Czech keyboard layout", &main_key_CS, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0405, "Czech keyboard layout cz", &main_key_CZ, &main_key_scan_qwerty, &main_key_vkey_qwertz},
+ {0x0405, "Czech keyboard layout cz_qwerty", &main_key_CZ_qwerty, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x040a, "Latin American keyboard layout", &main_key_LA, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0427, "Lithuanian (Baltic) keyboard layout", &main_key_LT_B, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x041f, "Turkish keyboard layout", &main_key_TK, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x040d, "Israelian keyboard layout", &main_key_IL, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x040d, "Israelian phonetic keyboard layout", &main_key_IL_phonetic, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x040d, "Israelian Saharon keyboard layout", &main_key_IL_saharon, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x0409, "VNC keyboard layout", &main_key_vnc, &main_key_scan_vnc, &main_key_vkey_vnc},
+ {0x0408, "Greek keyboard layout", &main_key_EL, &main_key_scan_qwerty, &main_key_vkey_qwerty},
+ {0x041e, "Thai (Kedmanee) keyboard layout", &main_key_th, &main_key_scan_qwerty, &main_key_vkey_qwerty},
- {NULL, NULL, NULL, NULL} /* sentinel */
+ {0, NULL, NULL, NULL, NULL} /* sentinel */
};
static unsigned kbd_layout=0; /* index into above table of layouts */
@@ -1487,26 +1501,148 @@
/***********************************************************************
- * X11DRV_MappingNotify
+ * GetKeyboardLayoutList (X11DRV.@)
*/
-void X11DRV_MappingNotify( XMappingEvent *event )
+UINT X11DRV_GetKeyboardLayoutList(INT size, HKL *hkl)
{
- TSXRefreshKeyboardMapping(event);
- X11DRV_InitKeyboard( pKeyStateTable );
+ INT i;
+
+ TRACE("%d, %p\n", size, hkl);
+
+ if (!size)
+ {
+ size = 4096; /* hope we will never have that many */
+ hkl = NULL;
+ }
+
+ for (i = 0; main_key_tab[i].comment && (i < size); i++)
+ {
+ if (hkl)
+ hkl[i] = (HKL)main_key_tab[i].lcid;
+ }
+ return i;
}
/***********************************************************************
- * VkKeyScan (X11DRV.@)
+ * GetKeyboardLayout (X11DRV.@)
*/
-WORD X11DRV_VkKeyScan(CHAR cChar)
+HKL X11DRV_GetKeyboardLayout(DWORD dwThreadid)
+{
+ DWORD layout;
+ LANGID langid;
+
+ if (dwThreadid)
+ FIXME("couldn't return keyboard layout for thread %04lx\n", dwThreadid);
+
+ layout = main_key_tab[kbd_layout].lcid;
+ /*
+ * Microsoft Office expects this value to be something specific
+ * for Japanese and Korean Windows with an IME the value is 0xe001
+ * We should probibly 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; /* FIXME */
+
+ return (HKL)layout;
+}
+
+
+/***********************************************************************
+ * GetKeyboardLayoutName (X11DRV.@)
+ */
+BOOL X11DRV_GetKeyboardLayoutName(LPWSTR name)
+{
+ static const WCHAR formatW[] = {'%','0','8','l','x',0};
+ DWORD layout;
+ LANGID langid;
+
+ layout = main_key_tab[kbd_layout].lcid;
+ /* see comment above */
+ langid = PRIMARYLANGID(LANGIDFROMLCID(layout));
+ if (langid == LANG_CHINESE || langid == LANG_JAPANESE || langid == LANG_KOREAN)
+ layout |= 0xe001 << 16; /* FIXME */
+
+ sprintfW(name, formatW, layout);
+ TRACE("returning %s\n", debugstr_w(name));
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * LoadKeyboardLayout (X11DRV.@)
+ */
+HKL X11DRV_LoadKeyboardLayout(LPCWSTR name, UINT flags)
+{
+ FIXME("%s, %04x: stub!\n", debugstr_w(name), flags);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+
+/***********************************************************************
+ * UnloadKeyboardLayout (X11DRV.@)
+ */
+BOOL X11DRV_UnloadKeyboardLayout(HKL hkl)
+{
+ FIXME("%p: stub!\n", hkl);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+
+/***********************************************************************
+ * ActivateKeyboardLayout (X11DRV.@)
+ */
+HKL X11DRV_ActivateKeyboardLayout(HKL hkl, UINT flags)
+{
+ FIXME("%p, %04x: stub!\n", hkl, flags);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return 0;
+}
+
+
+/***********************************************************************
+ * X11DRV_MappingNotify
+ */
+void X11DRV_MappingNotify( XMappingEvent *event )
+{
+ HWND hwnd;
+
+ TSXRefreshKeyboardMapping(event);
+ X11DRV_InitKeyboard( pKeyStateTable );
+
+ hwnd = GetFocus();
+ if (!hwnd) hwnd = GetActiveWindow();
+ PostMessageW(hwnd, WM_INPUTLANGCHANGEREQUEST,
+ 0 /*FIXME*/, (LPARAM)X11DRV_GetKeyboardLayout(0));
+}
+
+
+/***********************************************************************
+ * VkKeyScanEx (X11DRV.@)
+ *
+ * Note: Windows ignores HKL parameter and uses current active layout instead
+ */
+SHORT X11DRV_VkKeyScanEx(WCHAR wChar, HKL hkl)
{
Display *display = thread_display();
KeyCode keycode;
KeySym keysym;
int i, index;
+ CHAR cChar;
SHORT ret;
+ if (!WideCharToMultiByte(CP_UNIXCP, 0, &wChar, 1, &cChar, 1, NULL, NULL))
+ {
+ WARN("no translation from unicode to CP_UNIXCP for 0x%02x\n", wChar);
+ return -1;
+ }
+
+ TRACE("wChar 0x%02x -> cChar '%c'\n", wChar, cChar);
+
/* char->keysym (same for ANSI chars) */
keysym = (unsigned char)cChar; /* (!) cChar is signed */
if (keysym <= 27) keysym += 0xFF00; /* special chars : return, backspace... */
@@ -1565,15 +1701,18 @@
}
/***********************************************************************
- * MapVirtualKey (X11DRV.@)
+ * MapVirtualKeyEx (X11DRV.@)
*/
-UINT X11DRV_MapVirtualKey(UINT wCode, UINT wMapType)
+UINT X11DRV_MapVirtualKeyEx(UINT wCode, UINT wMapType, HKL hkl)
{
Display *display = thread_display();
#define returnMVK(value) { TRACE("returning 0x%x.\n",value); return value; }
- TRACE("wCode=0x%x wMapType=%d ...\n", wCode,wMapType);
+ TRACE("wCode=0x%x, wMapType=%d, hkl %p\n", wCode, wMapType, hkl);
+ if (hkl != X11DRV_GetKeyboardLayout(0))
+ FIXME("keyboard layout %p is not supported\n", hkl);
+
switch(wMapType) {
case 0: { /* vkey-code to scan-code */
/* let's do vkey -> keycode -> scan */
@@ -1667,7 +1806,7 @@
/***********************************************************************
* GetKeyNameText (X11DRV.@)
*/
-INT X11DRV_GetKeyNameText(LONG lParam, LPSTR lpBuffer, INT nSize)
+INT X11DRV_GetKeyNameText(LONG lParam, LPWSTR lpBuffer, INT nSize)
{
int vkey, ansi, scanCode;
KeyCode keyc;
@@ -1679,7 +1818,7 @@
scanCode &= 0x1ff; /* keep "extended-key" flag with code */
/* FIXME: should use MVK type 3 (NT version that distinguishes right and left */
- vkey = X11DRV_MapVirtualKey(scanCode, 1);
+ vkey = X11DRV_MapVirtualKeyEx(scanCode, 1, X11DRV_GetKeyboardLayout(0));
/* handle "don't care" bit (0x02000000) */
if (!(lParam & 0x02000000)) {
@@ -1701,7 +1840,7 @@
}
}
- ansi = X11DRV_MapVirtualKey(vkey, 2);
+ ansi = X11DRV_MapVirtualKeyEx(vkey, 2, X11DRV_GetKeyboardLayout(0));
TRACE("scan 0x%04x, vkey 0x%04x, ANSI 0x%04x\n", scanCode, vkey, ansi);
/* first get the name of the "regular" keys which is the Upper case
@@ -1715,7 +1854,7 @@
{
if ((nSize >= 2) && lpBuffer)
{
- *lpBuffer = toupper((char)ansi);
+ *lpBuffer = toupperW((WCHAR)ansi);
*(lpBuffer+1) = 0;
return 1;
}
@@ -1747,7 +1886,8 @@
scanCode, keyc, (int)keys, name);
if (lpBuffer && nSize && name)
{
- lstrcpynA(lpBuffer, name, nSize);
+ MultiByteToWideChar(CP_UNIXCP, 0, name, -1, lpBuffer, nSize);
+ lpBuffer[nSize - 1] = 0;
return 1;
}
}
@@ -1839,7 +1979,7 @@
}
/***********************************************************************
- * ToUnicode (X11DRV.@)
+ * ToUnicodeEx (X11DRV.@)
*
* The ToUnicode function translates the specified virtual-key code and keyboard
* state to the corresponding Windows character or characters.
@@ -1856,8 +1996,8 @@
* FIXME : should do the above (return 2 for non matching deadchar+char combinations)
*
*/
-INT X11DRV_ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
- LPWSTR bufW, int bufW_size, UINT flags)
+INT X11DRV_ToUnicodeEx(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
+ LPWSTR bufW, int bufW_size, UINT flags, HKL hkl)
{
Display *display = thread_display();
XKeyEvent e;
@@ -1874,6 +2014,9 @@
return 0;
}
+ if (hkl != X11DRV_GetKeyboardLayout(0))
+ FIXME("keyboard layout %p is not supported\n", hkl);
+
e.display = display;
e.keycode = 0;
e.state = 0;
diff --git a/dlls/x11drv/x11drv.spec b/dlls/x11drv/x11drv.spec
index c24c67d..e38f95d 100644
--- a/dlls/x11drv/x11drv.spec
+++ b/dlls/x11drv/x11drv.spec
@@ -63,10 +63,16 @@
# USER driver
@ cdecl InitKeyboard(ptr) X11DRV_InitKeyboard
-@ cdecl VkKeyScan(long) X11DRV_VkKeyScan
-@ cdecl MapVirtualKey(long long) X11DRV_MapVirtualKey
-@ cdecl GetKeyNameText(long str long) X11DRV_GetKeyNameText
-@ cdecl ToUnicode(long long ptr ptr long long) X11DRV_ToUnicode
+@ cdecl VkKeyScanEx(long long) X11DRV_VkKeyScanEx
+@ cdecl MapVirtualKeyEx(long long long) X11DRV_MapVirtualKeyEx
+@ cdecl GetKeyNameText(long ptr long) X11DRV_GetKeyNameText
+@ cdecl ToUnicodeEx(long long ptr ptr long long long) X11DRV_ToUnicodeEx
+@ cdecl GetKeyboardLayoutList(long ptr) X11DRV_GetKeyboardLayoutList
+@ cdecl GetKeyboardLayout(long) X11DRV_GetKeyboardLayout
+@ cdecl GetKeyboardLayoutName(ptr) X11DRV_GetKeyboardLayoutName
+@ cdecl LoadKeyboardLayout(wstr long) X11DRV_LoadKeyboardLayout
+@ cdecl ActivateKeyboardLayout(long long) X11DRV_ActivateKeyboardLayout
+@ cdecl UnloadKeyboardLayout(long) X11DRV_UnloadKeyboardLayout
@ cdecl Beep() X11DRV_Beep
@ cdecl InitMouse(ptr) X11DRV_InitMouse
@ cdecl SetCursor(ptr) X11DRV_SetCursor
diff --git a/include/user.h b/include/user.h
index d8221ff..f87e0e3 100644
--- a/include/user.h
+++ b/include/user.h
@@ -72,10 +72,16 @@
typedef struct tagUSER_DRIVER {
/* keyboard functions */
void (*pInitKeyboard)(LPBYTE);
- WORD (*pVkKeyScan)(CHAR);
- UINT (*pMapVirtualKey)(UINT,UINT);
- INT (*pGetKeyNameText)(LONG,LPSTR,INT);
- INT (*pToUnicode)(UINT, UINT, LPBYTE, LPWSTR, int, UINT);
+ SHORT (*pVkKeyScanEx)(WCHAR, HKL);
+ UINT (*pMapVirtualKeyEx)(UINT, UINT, HKL);
+ INT (*pGetKeyNameText)(LONG, LPWSTR, INT);
+ INT (*pToUnicodeEx)(UINT, UINT, LPBYTE, LPWSTR, int, UINT, HKL);
+ UINT (*pGetKeyboardLayoutList)(INT, HKL *);
+ HKL (*pGetKeyboardLayout)(DWORD);
+ BOOL (*pGetKeyboardLayoutName)(LPWSTR);
+ HKL (*pLoadKeyboardLayout)(LPCWSTR, UINT);
+ HKL (*pActivateKeyboardLayout)(HKL, UINT);
+ BOOL (*pUnloadKeyboardLayout)(HKL);
void (*pBeep)(void);
/* mouse functions */
void (*pInitMouse)(LPBYTE);
diff --git a/include/winuser.h b/include/winuser.h
index bc3d628..43684f9 100644
--- a/include/winuser.h
+++ b/include/winuser.h
@@ -3714,7 +3714,7 @@
BOOL WINAPI ExitWindowsEx(UINT,DWORD);
BOOL WINAPI GetIconInfo(HICON,PICONINFO);
HKL WINAPI GetKeyboardLayout(DWORD);
-INT WINAPI GetKeyboardLayoutList(INT,HKL *);
+UINT WINAPI GetKeyboardLayoutList(INT,HKL *);
BOOL WINAPI GetComboBoxInfo(HWND,PCOMBOBOXINFO);
DWORD WINAPI GetMenuContextHelpId(HMENU);
UINT WINAPI GetMenuDefaultItem(HMENU,UINT,UINT);
@@ -3767,9 +3767,11 @@
WORD WINAPI TileWindows (HWND, UINT, const LPRECT,
UINT, const HWND *);
INT WINAPI ToUnicode(UINT,UINT,PBYTE,LPWSTR,int,UINT);
+INT WINAPI ToUnicodeEx(UINT,UINT,LPBYTE,LPWSTR,int,UINT,HKL);
BOOL WINAPI TrackPopupMenuEx(HMENU,UINT,INT,INT,HWND,
LPTPMPARAMS);
BOOL WINAPI UnhookWinEvent(HWINEVENTHOOK);
+BOOL WINAPI UnloadKeyboardLayout(HKL);
BOOL WINAPI UnregisterDeviceNotification(HDEVNOTIFY);
BOOL WINAPI UnregisterHotKey(HWND,INT);
DWORD WINAPI WaitForInputIdle(HANDLE,DWORD);
@@ -4077,8 +4079,8 @@
INT WINAPI GetKeyNameTextA(LONG,LPSTR,INT);
INT WINAPI GetKeyNameTextW(LONG,LPWSTR,INT);
#define GetKeyNameText WINELIB_NAME_AW(GetKeyNameText)
-INT WINAPI GetKeyboardLayoutNameA(LPSTR);
-INT WINAPI GetKeyboardLayoutNameW(LPWSTR);
+BOOL WINAPI GetKeyboardLayoutNameA(LPSTR);
+BOOL WINAPI GetKeyboardLayoutNameW(LPWSTR);
#define GetKeyboardLayoutName WINELIB_NAME_AW(GetKeyboardLayoutName)
SHORT WINAPI GetKeyState(INT);
HWND WINAPI GetLastActivePopup(HWND);
@@ -4399,8 +4401,8 @@
UINT WINAPI UserRealizePalette(HDC);
BOOL WINAPI ValidateRect(HWND,const RECT*);
BOOL WINAPI ValidateRgn(HWND,HRGN);
-WORD WINAPI VkKeyScanA(CHAR);
-WORD WINAPI VkKeyScanW(WCHAR);
+SHORT WINAPI VkKeyScanA(CHAR);
+SHORT WINAPI VkKeyScanW(WCHAR);
#define VkKeyScan WINELIB_NAME_AW(VkKeyScan)
WORD WINAPI VkKeyScanExA(CHAR, HKL);
WORD WINAPI VkKeyScanExW(WCHAR, HKL);
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 774a5be..71dc3fa 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -859,6 +859,14 @@
}
break;
+ case WM_INPUTLANGCHANGEREQUEST:
+ /* notify about the switch only if it's really our current layout */
+ if ((HKL)lParam == GetKeyboardLayout(0))
+ result = SendMessageA( hwnd, WM_INPUTLANGCHANGE, wParam, lParam );
+ else
+ result = 0;
+ break;
+
default:
result = DEFWND_DefWinProc( hwnd, msg, wParam, lParam );
break;
@@ -970,6 +978,14 @@
}
break;
+ case WM_INPUTLANGCHANGEREQUEST:
+ /* notify about the switch only if it's really our current layout */
+ if ((HKL)lParam == GetKeyboardLayout(0))
+ result = SendMessageW( hwnd, WM_INPUTLANGCHANGE, wParam, lParam );
+ else
+ result = 0;
+ break;
+
default:
result = DEFWND_DefWinProc( hwnd, msg, wParam, lParam );
break;
diff --git a/windows/input.c b/windows/input.c
index 5ad72a6..ed845da 100644
--- a/windows/input.c
+++ b/windows/input.c
@@ -645,17 +645,22 @@
* VkKeyScan '^'(0x5e, 94) ... got keycode 00 ... returning 00
* VkKeyScan '`'(0x60, 96) ... got keycode 00 ... returning 00
*/
-WORD WINAPI VkKeyScanA(CHAR cChar)
+SHORT WINAPI VkKeyScanA(CHAR cChar)
{
- return USER_Driver.pVkKeyScan( cChar );
+ WCHAR wChar;
+
+ if (IsDBCSLeadByte(cChar)) return -1;
+
+ MultiByteToWideChar(CP_ACP, 0, &cChar, 1, &wChar, 1);
+ return VkKeyScanW(wChar);
}
/******************************************************************************
* VkKeyScanW (USER32.@)
*/
-WORD WINAPI VkKeyScanW(WCHAR cChar)
+SHORT WINAPI VkKeyScanW(WCHAR cChar)
{
- return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
+ return VkKeyScanExW(cChar, GetKeyboardLayout(0));
}
/**********************************************************************
@@ -663,8 +668,12 @@
*/
WORD WINAPI VkKeyScanExA(CHAR cChar, HKL dwhkl)
{
- /* FIXME: complete workaround this is */
- return VkKeyScanA(cChar);
+ WCHAR wChar;
+
+ if (IsDBCSLeadByte(cChar)) return -1;
+
+ MultiByteToWideChar(CP_ACP, 0, &cChar, 1, &wChar, 1);
+ return VkKeyScanExW(wChar, dwhkl);
}
/******************************************************************************
@@ -672,8 +681,9 @@
*/
WORD WINAPI VkKeyScanExW(WCHAR cChar, HKL dwhkl)
{
- /* FIXME: complete workaround this is */
- return VkKeyScanA((CHAR)cChar); /* FIXME: check unicode */
+ if (USER_Driver.pVkKeyScanEx)
+ return USER_Driver.pVkKeyScanEx(cChar, dwhkl);
+ return -1;
}
/******************************************************************************
@@ -701,7 +711,7 @@
*/
UINT WINAPI MapVirtualKeyA(UINT code, UINT maptype)
{
- return USER_Driver.pMapVirtualKey( code, maptype );
+ return MapVirtualKeyExA( code, maptype, GetKeyboardLayout(0) );
}
/******************************************************************************
@@ -709,7 +719,7 @@
*/
UINT WINAPI MapVirtualKeyW(UINT code, UINT maptype)
{
- return MapVirtualKeyA(code,maptype);
+ return MapVirtualKeyExW(code, maptype, GetKeyboardLayout(0));
}
/******************************************************************************
@@ -717,9 +727,7 @@
*/
UINT WINAPI MapVirtualKeyExA(UINT code, UINT maptype, HKL hkl)
{
- if (hkl)
- FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
- return MapVirtualKeyA(code,maptype);
+ return MapVirtualKeyExW(code, maptype, hkl);
}
/******************************************************************************
@@ -727,9 +735,11 @@
*/
UINT WINAPI MapVirtualKeyExW(UINT code, UINT maptype, HKL hkl)
{
- if (hkl)
- FIXME_(keyboard)("(%d,%d,0x%08lx), hkl unhandled!\n",code,maptype,(DWORD)hkl);
- return MapVirtualKeyA(code,maptype);
+ TRACE_(keyboard)("(%d, %d, %p)\n", code, maptype, hkl);
+
+ if (USER_Driver.pMapVirtualKeyEx)
+ return USER_Driver.pMapVirtualKeyEx(code, maptype, hkl);
+ return 0;
}
/****************************************************************************
@@ -751,37 +761,37 @@
/***********************************************************************
* GetKeyboardLayout (USER32.@)
*
- * FIXME: - device handle for keyboard layout defaulted to
+ * - device handle for keyboard layout defaulted to
* the language id. This is the way Windows default works.
* - the thread identifier (dwLayout) is also ignored.
*/
HKL WINAPI GetKeyboardLayout(DWORD dwLayout)
{
- UINT layout;
- layout = GetSystemDefaultLCID(); /* FIXME */
- layout |= (layout<<16); /* FIXME */
- TRACE_(keyboard)("returning %08x\n",layout);
- return (HKL)layout;
+ if (USER_Driver.pGetKeyboardLayout)
+ return USER_Driver.pGetKeyboardLayout(dwLayout);
+ return 0;
}
/****************************************************************************
* GetKeyboardLayoutNameA (USER32.@)
*/
-INT WINAPI GetKeyboardLayoutNameA(LPSTR pwszKLID)
+BOOL WINAPI GetKeyboardLayoutNameA(LPSTR pszKLID)
{
- sprintf(pwszKLID, "%p",GetKeyboardLayout(0));
- return 1;
+ WCHAR buf[KL_NAMELENGTH];
+
+ if (GetKeyboardLayoutNameW(buf))
+ return WideCharToMultiByte( CP_ACP, 0, buf, -1, pszKLID, KL_NAMELENGTH, NULL, NULL ) != 0;
+ return FALSE;
}
/****************************************************************************
* GetKeyboardLayoutNameW (USER32.@)
*/
-INT WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID)
+BOOL WINAPI GetKeyboardLayoutNameW(LPWSTR pwszKLID)
{
- char buf[KL_NAMELENGTH];
- int res = GetKeyboardLayoutNameA(buf);
- MultiByteToWideChar( CP_ACP, 0, buf, -1, pwszKLID, KL_NAMELENGTH );
- return res;
+ if (USER_Driver.pGetKeyboardLayoutName)
+ return USER_Driver.pGetKeyboardLayoutName(pwszKLID);
+ return FALSE;
}
/****************************************************************************
@@ -789,7 +799,18 @@
*/
INT WINAPI GetKeyNameTextA(LONG lParam, LPSTR lpBuffer, INT nSize)
{
- return USER_Driver.pGetKeyNameText( lParam, lpBuffer, nSize );
+ WCHAR buf[256];
+ INT ret;
+
+ if (!GetKeyNameTextW(lParam, buf, 256))
+ return 0;
+ ret = WideCharToMultiByte(CP_ACP, 0, buf, -1, lpBuffer, nSize, NULL, NULL);
+ if (!ret && nSize)
+ {
+ ret = nSize - 1;
+ lpBuffer[ret] = 0;
+ }
+ return ret;
}
/****************************************************************************
@@ -797,15 +818,9 @@
*/
INT WINAPI GetKeyNameTextW(LONG lParam, LPWSTR lpBuffer, INT nSize)
{
- int res;
- LPSTR buf = HeapAlloc( GetProcessHeap(), 0, nSize );
- if(buf == NULL) return 0; /* FIXME: is this the correct failure value?*/
- res = GetKeyNameTextA(lParam,buf,nSize);
-
- if (nSize > 0 && !MultiByteToWideChar( CP_ACP, 0, buf, -1, lpBuffer, nSize ))
- lpBuffer[nSize-1] = 0;
- HeapFree( GetProcessHeap(), 0, buf );
- return res;
+ if (USER_Driver.pGetKeyNameText)
+ return USER_Driver.pGetKeyNameText( lParam, lpBuffer, nSize );
+ return 0;
}
/****************************************************************************
@@ -814,7 +829,7 @@
INT WINAPI ToUnicode(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
LPWSTR lpwStr, int size, UINT flags)
{
- return USER_Driver.pToUnicode(virtKey, scanCode, lpKeyState, lpwStr, size, flags);
+ return ToUnicodeEx(virtKey, scanCode, lpKeyState, lpwStr, size, flags, GetKeyboardLayout(0));
}
/****************************************************************************
@@ -823,24 +838,18 @@
INT WINAPI ToUnicodeEx(UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
LPWSTR lpwStr, int size, UINT flags, HKL hkl)
{
- /* FIXME: need true implementation */
- return ToUnicode(virtKey, scanCode, lpKeyState, lpwStr, size, flags);
+ if (USER_Driver.pToUnicodeEx)
+ return USER_Driver.pToUnicodeEx(virtKey, scanCode, lpKeyState, lpwStr, size, flags, hkl);
+ return 0;
}
/****************************************************************************
* ToAscii (USER32.@)
*/
-INT WINAPI ToAscii( UINT virtKey,UINT scanCode,LPBYTE lpKeyState,
- LPWORD lpChar,UINT flags )
+INT WINAPI ToAscii( UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
+ LPWORD lpChar, UINT flags )
{
- WCHAR uni_chars[2];
- INT ret, n_ret;
-
- ret = ToUnicode(virtKey, scanCode, lpKeyState, uni_chars, 2, flags);
- if(ret < 0) n_ret = 1; /* FIXME: make ToUnicode return 2 for dead chars */
- else n_ret = ret;
- WideCharToMultiByte(CP_ACP, 0, uni_chars, n_ret, (LPSTR)lpChar, 2, NULL, NULL);
- return ret;
+ return ToAsciiEx(virtKey, scanCode, lpKeyState, lpChar, flags, GetKeyboardLayout(0));
}
/****************************************************************************
@@ -849,19 +858,25 @@
INT WINAPI ToAsciiEx( UINT virtKey, UINT scanCode, LPBYTE lpKeyState,
LPWORD lpChar, UINT flags, HKL dwhkl )
{
- /* FIXME: need true implementation */
- return ToAscii(virtKey, scanCode, lpKeyState, lpChar, flags);
+ WCHAR uni_chars[2];
+ INT ret, n_ret;
+
+ ret = ToUnicodeEx(virtKey, scanCode, lpKeyState, uni_chars, 2, flags, dwhkl);
+ if (ret < 0) n_ret = 1; /* FIXME: make ToUnicode return 2 for dead chars */
+ else n_ret = ret;
+ WideCharToMultiByte(CP_ACP, 0, uni_chars, n_ret, (LPSTR)lpChar, 2, NULL, NULL);
+ return ret;
}
/**********************************************************************
* ActivateKeyboardLayout (USER32.@)
- *
- * Call ignored. WINE supports only system default keyboard layout.
*/
HKL WINAPI ActivateKeyboardLayout(HKL hLayout, UINT flags)
{
TRACE_(keyboard)("(%p, %d)\n", hLayout, flags);
- ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n");
+
+ if (USER_Driver.pActivateKeyboardLayout)
+ return USER_Driver.pActivateKeyboardLayout(hLayout, flags);
return 0;
}
@@ -869,21 +884,16 @@
/***********************************************************************
* GetKeyboardLayoutList (USER32.@)
*
- * FIXME: Supports only the system default language and layout and
- * returns only 1 value.
- *
* Return number of values available if either input parm is
* 0, per MS documentation.
- *
*/
-INT WINAPI GetKeyboardLayoutList(INT nBuff,HKL *layouts)
+UINT WINAPI GetKeyboardLayoutList(INT nBuff, HKL *layouts)
{
- TRACE_(keyboard)("(%d,%p)\n",nBuff,layouts);
- if (!nBuff || !layouts)
- return 1;
- if (layouts)
- layouts[0] = GetKeyboardLayout(0);
- return 1;
+ TRACE_(keyboard)("(%d,%p)\n",nBuff,layouts);
+
+ if (USER_Driver.pGetKeyboardLayoutList)
+ return USER_Driver.pGetKeyboardLayoutList(nBuff, layouts);
+ return 0;
}
@@ -905,13 +915,14 @@
/***********************************************************************
* LoadKeyboardLayoutW (USER32.@)
- * Call ignored. WINE supports only system default keyboard layout.
*/
HKL WINAPI LoadKeyboardLayoutW(LPCWSTR pwszKLID, UINT Flags)
{
TRACE_(keyboard)("(%s, %d)\n", debugstr_w(pwszKLID), Flags);
- ERR_(keyboard)("Only default system keyboard layout supported. Call ignored.\n");
- return 0;
+
+ if (USER_Driver.pLoadKeyboardLayout)
+ return USER_Driver.pLoadKeyboardLayout(pwszKLID, Flags);
+ return 0;
}
/***********************************************************************
@@ -931,6 +942,18 @@
}
+/***********************************************************************
+ * UnloadKeyboardLayout (USER32.@)
+ */
+BOOL WINAPI UnloadKeyboardLayout(HKL hkl)
+{
+ TRACE_(keyboard)("(%p)\n", hkl);
+
+ if (USER_Driver.pUnloadKeyboardLayout)
+ return USER_Driver.pUnloadKeyboardLayout(hkl);
+ return 0;
+}
+
typedef struct __TRACKINGLIST {
TRACKMOUSEEVENT tme;
POINT pos; /* center of hover rectangle */