Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / reactos / win32ss / user / ntuser / keyboard.c
diff --git a/reactos/win32ss/user/ntuser/keyboard.c b/reactos/win32ss/user/ntuser/keyboard.c
deleted file mode 100644 (file)
index d2cba89..0000000
+++ /dev/null
@@ -1,1590 +0,0 @@
-/*
- * COPYRIGHT:        See COPYING in the top level directory
- * PROJECT:          ReactOS kernel
- * PURPOSE:          Keyboard functions
- * FILE:             win32ss/user/ntuser/keyboard.c
- * PROGRAMERS:       Casper S. Hornstrup (chorns@users.sourceforge.net)
- *                   Rafal Harabien (rafalh@reactos.org)
- */
-
-#include <win32k.h>
-DBG_DEFAULT_CHANNEL(UserKbd);
-
-BYTE gafAsyncKeyState[256 * 2 / 8]; // 2 bits per key
-static BYTE gafAsyncKeyStateRecentDown[256 / 8]; // 1 bit per key
-static PKEYBOARD_INDICATOR_TRANSLATION gpKeyboardIndicatorTrans = NULL;
-static KEYBOARD_INDICATOR_PARAMETERS gIndicators = {0, 0};
-KEYBOARD_ATTRIBUTES gKeyboardInfo;
-int gLanguageToggleKeyState = 0;
-DWORD gdwLanguageToggleKey = 0;
-
-/* FUNCTIONS *****************************************************************/
-
-/*
- * InitKeyboardImpl
- *
- * Initialization -- Right now, just zero the key state
- */
-INIT_FUNCTION
-NTSTATUS
-NTAPI
-InitKeyboardImpl(VOID)
-{
-    RtlZeroMemory(&gafAsyncKeyState, sizeof(gafAsyncKeyState));
-    RtlZeroMemory(&gafAsyncKeyStateRecentDown, sizeof(gafAsyncKeyStateRecentDown));
-    // Clear and set default information.
-    RtlZeroMemory(&gKeyboardInfo, sizeof(gKeyboardInfo));
-    gKeyboardInfo.KeyboardIdentifier.Type = 4; /* AT-101 */
-    gKeyboardInfo.NumberOfFunctionKeys = 12; /* We're doing an 101 for now, so return 12 F-keys */
-    return STATUS_SUCCESS;
-}
-
-/*
- * IntKeyboardGetIndicatorTrans
- *
- * Asks the keyboard driver to send a small table that shows which
- * lights should connect with which scancodes
- */
-//static
-NTSTATUS APIENTRY
-IntKeyboardGetIndicatorTrans(HANDLE hKeyboardDevice,
-                             PKEYBOARD_INDICATOR_TRANSLATION *ppIndicatorTrans)
-{
-    NTSTATUS Status;
-    DWORD dwSize = 0;
-    IO_STATUS_BLOCK Block;
-    PKEYBOARD_INDICATOR_TRANSLATION pRet;
-
-    dwSize = sizeof(KEYBOARD_INDICATOR_TRANSLATION);
-
-    pRet = ExAllocatePoolWithTag(PagedPool,
-                                 dwSize,
-                                 USERTAG_KBDTABLE);
-
-    while (pRet)
-    {
-        Status = ZwDeviceIoControlFile(hKeyboardDevice,
-                                       NULL,
-                                       NULL,
-                                       NULL,
-                                       &Block,
-                                       IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION,
-                                       NULL, 0,
-                                       pRet, dwSize);
-
-        if (Status != STATUS_BUFFER_TOO_SMALL)
-            break;
-
-        ExFreePoolWithTag(pRet, USERTAG_KBDTABLE);
-
-        dwSize += sizeof(KEYBOARD_INDICATOR_TRANSLATION);
-
-        pRet = ExAllocatePoolWithTag(PagedPool,
-                                     dwSize,
-                                     USERTAG_KBDTABLE);
-    }
-
-    if (!pRet)
-        return STATUS_INSUFFICIENT_RESOURCES;
-
-    if (!NT_SUCCESS(Status))
-    {
-        ExFreePoolWithTag(pRet, USERTAG_KBDTABLE);
-        return Status;
-    }
-
-    *ppIndicatorTrans = pRet;
-    return Status;
-}
-
-/*
- * IntKeyboardUpdateLeds
- *
- * Sends the keyboard commands to turn on/off the lights
- */
-static
-NTSTATUS APIENTRY
-IntKeyboardUpdateLeds(HANDLE hKeyboardDevice,
-                      WORD wVk,
-                      WORD wScanCode)
-{
-    NTSTATUS Status;
-    UINT i;
-    USHORT LedFlag = 0;
-    IO_STATUS_BLOCK Block;
-
-    if (!gpKeyboardIndicatorTrans)
-        return STATUS_NOT_SUPPORTED;
-
-    switch (wVk)
-    {
-        case VK_CAPITAL: LedFlag = KEYBOARD_CAPS_LOCK_ON; break;
-        case VK_NUMLOCK: LedFlag = KEYBOARD_NUM_LOCK_ON; break;
-        case VK_SCROLL: LedFlag = KEYBOARD_SCROLL_LOCK_ON; break;
-        default:
-            for (i = 0; i < gpKeyboardIndicatorTrans->NumberOfIndicatorKeys; i++)
-            {
-                if (gpKeyboardIndicatorTrans->IndicatorList[i].MakeCode == wScanCode)
-                {
-                    LedFlag = gpKeyboardIndicatorTrans->IndicatorList[i].IndicatorFlags;
-                    break;
-                }
-            }
-    }
-
-    if (LedFlag)
-    {
-        gIndicators.LedFlags ^= LedFlag;
-
-        /* Update the lights on the hardware */
-        Status = ZwDeviceIoControlFile(hKeyboardDevice,
-                                       NULL,
-                                       NULL,
-                                       NULL,
-                                       &Block,
-                                       IOCTL_KEYBOARD_SET_INDICATORS,
-                                       &gIndicators, sizeof(gIndicators),
-                                       NULL, 0);
-
-        return Status;
-    }
-
-    return STATUS_SUCCESS;
-}
-
-/*
- * UserInitKeyboard
- *
- * Initializes keyboard indicators translation and their state
- */
-VOID NTAPI
-UserInitKeyboard(HANDLE hKeyboardDevice)
-{
-    NTSTATUS Status;
-    IO_STATUS_BLOCK Block;
-
-    IntKeyboardGetIndicatorTrans(hKeyboardDevice, &gpKeyboardIndicatorTrans);
-
-    Status = ZwDeviceIoControlFile(hKeyboardDevice,
-                                   NULL,
-                                   NULL,
-                                   NULL,
-                                   &Block,
-                                   IOCTL_KEYBOARD_QUERY_INDICATORS,
-                                   NULL, 0,
-                                   &gIndicators,
-                                   sizeof(gIndicators));
-
-    if (!NT_SUCCESS(Status))
-    {
-        WARN("NtDeviceIoControlFile() failed, ignored\n");
-        gIndicators.LedFlags = 0;
-        gIndicators.UnitId = 0;
-    }
-
-    SET_KEY_LOCKED(gafAsyncKeyState, VK_CAPITAL,
-                   gIndicators.LedFlags & KEYBOARD_CAPS_LOCK_ON);
-    SET_KEY_LOCKED(gafAsyncKeyState, VK_NUMLOCK,
-                   gIndicators.LedFlags & KEYBOARD_NUM_LOCK_ON);
-    SET_KEY_LOCKED(gafAsyncKeyState, VK_SCROLL,
-                   gIndicators.LedFlags & KEYBOARD_SCROLL_LOCK_ON);
-
-    // FIXME: Need device driver to work! HID support more than one!!!!
-    Status = ZwDeviceIoControlFile(hKeyboardDevice,
-                                   NULL,
-                                   NULL,
-                                   NULL,
-                                   &Block,
-                                   IOCTL_KEYBOARD_QUERY_ATTRIBUTES,
-                                   NULL, 0,
-                                   &gKeyboardInfo, sizeof(gKeyboardInfo));
-
-    if (!NT_SUCCESS(Status))
-    {
-        ERR("NtDeviceIoControlFile() failed, ignored\n");
-    }
-    TRACE("Keyboard type %u, subtype %u and number of func keys %u\n",
-             gKeyboardInfo.KeyboardIdentifier.Type,
-             gKeyboardInfo.KeyboardIdentifier.Subtype,
-             gKeyboardInfo.NumberOfFunctionKeys);
-}
-
-/*
- * IntSimplifyVk
- *
- * Changes virtual keys which distinguish between left and right hand, to keys which don't distinguish
- */
-static
-WORD
-IntSimplifyVk(WORD wVk)
-{
-    switch (wVk)
-    {
-        case VK_LSHIFT:
-        case VK_RSHIFT:
-            return VK_SHIFT;
-
-        case VK_LCONTROL:
-        case VK_RCONTROL:
-            return VK_CONTROL;
-
-        case VK_LMENU:
-        case VK_RMENU:
-            return VK_MENU;
-
-        default:
-            return wVk;
-    }
-}
-
-/*
- * IntFixVk
- *
- * Changes virtual keys which don't not distinguish between left and right hand to proper keys
- */
-static
-WORD
-IntFixVk(WORD wVk, BOOL bExt)
-{
-    switch (wVk)
-    {
-        case VK_SHIFT:
-            return bExt ? VK_RSHIFT : VK_LSHIFT;
-
-        case VK_CONTROL:
-            return bExt ? VK_RCONTROL : VK_LCONTROL;
-
-        case VK_MENU:
-            return bExt ? VK_RMENU : VK_LMENU;
-
-        default:
-            return wVk;
-    }
-}
-
-/*
- * IntTranslateNumpadKey
- *
- * Translates numpad keys when numlock is enabled
- */
-static
-WORD
-IntTranslateNumpadKey(WORD wVk)
-{
-    switch (wVk)
-    {
-        case VK_INSERT: return VK_NUMPAD0;
-        case VK_END: return VK_NUMPAD1;
-        case VK_DOWN: return VK_NUMPAD2;
-        case VK_NEXT: return VK_NUMPAD3;
-        case VK_LEFT: return VK_NUMPAD4;
-        case VK_CLEAR: return VK_NUMPAD5;
-        case VK_RIGHT: return VK_NUMPAD6;
-        case VK_HOME: return VK_NUMPAD7;
-        case VK_UP: return VK_NUMPAD8;
-        case VK_PRIOR: return VK_NUMPAD9;
-        case VK_DELETE: return VK_DECIMAL;
-        default: return wVk;
-    }
-}
-
-/*
- * IntGetModBits
- *
- * Gets layout specific modification bits, for example KBDSHIFT, KBDCTRL, KBDALT
- */
-static
-DWORD
-IntGetModBits(PKBDTABLES pKbdTbl, PBYTE pKeyState)
-{
-    DWORD i, dwModBits = 0;
-
-    /* DumpKeyState( KeyState ); */
-
-    for (i = 0; pKbdTbl->pCharModifiers->pVkToBit[i].Vk; i++)
-        if (IS_KEY_DOWN(pKeyState, pKbdTbl->pCharModifiers->pVkToBit[i].Vk))
-            dwModBits |= pKbdTbl->pCharModifiers->pVkToBit[i].ModBits;
-
-    TRACE("Current Mod Bits: %lx\n", dwModBits);
-
-    return dwModBits;
-}
-
-/*
- * IntTranslateChar
- *
- * Translates virtual key to character
- */
-static
-BOOL
-IntTranslateChar(WORD wVirtKey,
-                 PBYTE pKeyState,
-                 PBOOL pbDead,
-                 PBOOL pbLigature,
-                 PWCHAR pwcTranslatedChar,
-                 PKBDTABLES pKbdTbl)
-{
-    PVK_TO_WCHAR_TABLE pVkToVchTbl;
-    PVK_TO_WCHARS10 pVkToVch;
-    DWORD i, dwModBits, dwVkModBits, dwModNumber = 0;
-    WCHAR wch;
-    BOOL bAltGr;
-    WORD wCaplokAttr;
-
-    dwModBits = pKeyState ? IntGetModBits(pKbdTbl, pKeyState) : 0;
-    bAltGr = pKeyState && (pKbdTbl->fLocaleFlags & KLLF_ALTGR) && IS_KEY_DOWN(pKeyState, VK_RMENU);
-    wCaplokAttr = bAltGr ? CAPLOKALTGR : CAPLOK;
-
-    TRACE("TryToTranslate: %04x %x\n", wVirtKey, dwModBits);
-
-    /* If ALT without CTRL has ben used, remove ALT flag */
-    if ((dwModBits & (KBDALT|KBDCTRL)) == KBDALT)
-        dwModBits &= ~KBDALT;
-
-    if (dwModBits > pKbdTbl->pCharModifiers->wMaxModBits)
-    {
-        TRACE("dwModBits %x > wMaxModBits %x\n", dwModBits, pKbdTbl->pCharModifiers->wMaxModBits);
-        return FALSE;
-    }
-
-    for (i = 0; pKbdTbl->pVkToWcharTable[i].pVkToWchars; i++)
-    {
-        pVkToVchTbl = &pKbdTbl->pVkToWcharTable[i];
-        pVkToVch = (PVK_TO_WCHARS10)(pVkToVchTbl->pVkToWchars);
-        while (pVkToVch->VirtualKey)
-        {
-            if (wVirtKey == (pVkToVch->VirtualKey & 0xFF))
-            {
-                dwVkModBits = dwModBits;
-
-                /* If CapsLock is enabled for this key and locked, add SHIFT bit */
-                if ((pVkToVch->Attributes & wCaplokAttr) &&
-                    pKeyState &&
-                    IS_KEY_LOCKED(pKeyState, VK_CAPITAL))
-                {
-                    /* Note: we use special value here instead of getting VK_SHIFT mod bit - it's verified */
-                    dwVkModBits ^= KBDSHIFT;
-                }
-
-                if (dwVkModBits > pKbdTbl->pCharModifiers->wMaxModBits)
-                    break;
-
-                /* Get modification number */
-                dwModNumber = pKbdTbl->pCharModifiers->ModNumber[dwVkModBits];
-                if (dwModNumber >= pVkToVchTbl->nModifications)
-                {
-                    TRACE("dwModNumber %u >= nModifications %u\n", dwModNumber, pVkToVchTbl->nModifications);
-                    break;
-                }
-
-                /* Read character */
-                wch = pVkToVch->wch[dwModNumber];
-                if (wch == WCH_NONE)
-                    break;
-
-                *pbDead = (wch == WCH_DEAD);
-                *pbLigature = (wch == WCH_LGTR);
-                *pwcTranslatedChar = wch;
-
-                TRACE("%lu %04x: dwModNumber %08x Char %04x\n",
-                      i, wVirtKey, dwModNumber, wch);
-
-                if (*pbDead)
-                {
-                    /* After WCH_DEAD, real character is located */
-                    pVkToVch = (PVK_TO_WCHARS10)(((BYTE *)pVkToVch) + pVkToVchTbl->cbSize);
-                    if (pVkToVch->VirtualKey != 0xFF)
-                    {
-                        WARN("Found dead key with no trailer in the table.\n");
-                        WARN("VK: %04x, ADDR: %p\n", wVirtKey, pVkToVch);
-                        break;
-                    }
-                    *pwcTranslatedChar = pVkToVch->wch[dwModNumber];
-                }
-                return TRUE;
-            }
-            pVkToVch = (PVK_TO_WCHARS10)(((BYTE *)pVkToVch) + pVkToVchTbl->cbSize);
-        }
-    }
-
-    /* If nothing has been found in layout, check if this is ASCII control character.
-       Note: we could add it to layout table, but windows does not have it there */
-    if (wVirtKey >= 'A' && wVirtKey <= 'Z' &&
-        pKeyState && IS_KEY_DOWN(pKeyState, VK_CONTROL) &&
-        !IS_KEY_DOWN(pKeyState, VK_MENU))
-    {
-        *pwcTranslatedChar = (wVirtKey - 'A') + 1; /* ASCII control character */
-        *pbDead = FALSE;
-        *pbLigature = FALSE;
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-/*
- * IntToUnicodeEx
- *
- * Translates virtual key to characters
- */
-static
-int APIENTRY
-IntToUnicodeEx(UINT wVirtKey,
-               UINT wScanCode,
-               PBYTE pKeyState,
-               LPWSTR pwszBuff,
-               int cchBuff,
-               UINT wFlags,
-               PKBDTABLES pKbdTbl)
-{
-    WCHAR wchTranslatedChar;
-    BOOL bDead, bLigature;
-    static WCHAR wchDead = 0;
-    int iRet = 0;
-
-    ASSERT(pKbdTbl);
-
-    if (!IntTranslateChar(wVirtKey,
-                          pKeyState,
-                          &bDead,
-                          &bLigature,
-                          &wchTranslatedChar,
-                          pKbdTbl))
-    {
-        return 0;
-    }
-
-    if (bLigature)
-    {
-        WARN("Not handling ligature (yet)\n" );
-        return 0;
-    }
-
-    /* If we got dead char in previous call check dead keys in keyboard layout */
-    if (wchDead)
-    {
-        UINT i;
-        WCHAR wchFirst, wchSecond;
-        TRACE("Previous dead char: %lc (%x)\n", wchDead, wchDead);
-
-        for (i = 0; pKbdTbl->pDeadKey[i].dwBoth; i++)
-        {
-            wchFirst = pKbdTbl->pDeadKey[i].dwBoth >> 16;
-            wchSecond = pKbdTbl->pDeadKey[i].dwBoth & 0xFFFF;
-            if (wchFirst == wchDead && wchSecond == wchTranslatedChar)
-            {
-                wchTranslatedChar = pKbdTbl->pDeadKey[i].wchComposed;
-                wchDead = 0;
-                bDead = FALSE;
-                break;
-            }
-        }
-
-        TRACE("Final char: %lc (%x)\n", wchTranslatedChar, wchTranslatedChar);
-    }
-
-    /* Dead char has not been not found */
-    if (wchDead)
-    {
-        /* Treat both characters normally */
-        if (cchBuff > iRet)
-            pwszBuff[iRet++] = wchDead;
-        bDead = FALSE;
-    }
-
-    /* Add character to the buffer */
-    if (cchBuff > iRet)
-        pwszBuff[iRet++] = wchTranslatedChar;
-
-    /* Save dead character */
-    wchDead = bDead ? wchTranslatedChar : 0;
-
-    return bDead ? -iRet : iRet;
-}
-
-/*
- * IntVkToVsc
- *
- * Translates virtual key to scan code
- */
-static
-WORD FASTCALL
-IntVkToVsc(WORD wVk, PKBDTABLES pKbdTbl)
-{
-    unsigned i;
-
-    ASSERT(pKbdTbl);
-
-    /* Check standard keys first */
-    for (i = 0; i < pKbdTbl->bMaxVSCtoVK; i++)
-    {
-        if ((pKbdTbl->pusVSCtoVK[i] & 0xFF) == wVk)
-            return i;
-    }
-
-    /* Check extended keys now */
-    for (i = 0; pKbdTbl->pVSCtoVK_E0[i].Vsc; i++)
-    {
-        if ((pKbdTbl->pVSCtoVK_E0[i].Vk & 0xFF) == wVk)
-            return 0xE000 | pKbdTbl->pVSCtoVK_E0[i].Vsc;
-    }
-
-    for (i = 0; pKbdTbl->pVSCtoVK_E1[i].Vsc; i++)
-    {
-        if ((pKbdTbl->pVSCtoVK_E1[i].Vk & 0xFF) == wVk)
-            return 0xE100 | pKbdTbl->pVSCtoVK_E1[i].Vsc;
-    }
-
-    /* Virtual key has not been found */
-    return 0;
-}
-
-/*
- * IntVscToVk
- *
- * Translates prefixed scancode to virtual key
- */
-static
-WORD FASTCALL
-IntVscToVk(WORD wScanCode, PKBDTABLES pKbdTbl)
-{
-    unsigned i;
-    WORD wVk = 0;
-
-    ASSERT(pKbdTbl);
-
-    if ((wScanCode & 0xFF00) == 0xE000)
-    {
-        for (i = 0; pKbdTbl->pVSCtoVK_E0[i].Vsc; i++)
-        {
-            if (pKbdTbl->pVSCtoVK_E0[i].Vsc == (wScanCode & 0xFF))
-            {
-                wVk = pKbdTbl->pVSCtoVK_E0[i].Vk;
-            }
-        }
-    }
-    else if ((wScanCode & 0xFF00) == 0xE100)
-    {
-        for (i = 0; pKbdTbl->pVSCtoVK_E1[i].Vsc; i++)
-        {
-            if (pKbdTbl->pVSCtoVK_E1[i].Vsc == (wScanCode & 0xFF))
-            {
-                wVk = pKbdTbl->pVSCtoVK_E1[i].Vk;
-            }
-        }
-    }
-    else if (wScanCode < pKbdTbl->bMaxVSCtoVK)
-    {
-        wVk = pKbdTbl->pusVSCtoVK[wScanCode];
-    }
-
-    /* 0xFF nad 0x00 are invalid VKs */
-    return wVk != 0xFF ? wVk : 0;
-}
-
-/*
- * IntVkToChar
- *
- * Translates virtual key to character, ignoring shift state
- */
-static
-WCHAR FASTCALL
-IntVkToChar(WORD wVk, PKBDTABLES pKbdTbl)
-{
-    WCHAR wch;
-    BOOL bDead, bLigature;
-
-    ASSERT(pKbdTbl);
-
-    if (IntTranslateChar(wVk,
-                         NULL,
-                         &bDead,
-                         &bLigature,
-                         &wch,
-                         pKbdTbl))
-    {
-        return wch;
-    }
-
-    return 0;
-}
-
-/*
- * NtUserGetAsyncKeyState
- *
- * Gets key state from global bitmap
- */
-SHORT
-APIENTRY
-NtUserGetAsyncKeyState(INT Key)
-{
-    WORD wRet = 0;
-
-    TRACE("Enter NtUserGetAsyncKeyState\n");
-
-    if (Key >= 0x100)
-    {
-        EngSetLastError(ERROR_INVALID_PARAMETER);
-        ERR("Invalid parameter Key\n");
-        return 0;
-    }
-
-    UserEnterExclusive();
-
-    if (IS_KEY_DOWN(gafAsyncKeyState, Key))
-        wRet |= 0x8000; // If down, windows returns 0x8000.
-    if (gafAsyncKeyStateRecentDown[Key / 8] & (1 << (Key % 8)))
-        wRet |= 0x1;
-    gafAsyncKeyStateRecentDown[Key / 8] &= ~(1 << (Key % 8));
-
-    UserLeave();
-
-    TRACE("Leave NtUserGetAsyncKeyState, ret=%u\n", wRet);
-    return wRet;
-}
-
-/*
- * UpdateAsyncKeyState
- *
- * Updates gafAsyncKeyState array
- */
-static
-VOID NTAPI
-UpdateAsyncKeyState(WORD wVk, BOOL bIsDown)
-{
-    if (bIsDown)
-    {
-        /* If it's first key down event, xor lock bit */
-        if (!IS_KEY_DOWN(gafAsyncKeyState, wVk))
-            SET_KEY_LOCKED(gafAsyncKeyState, wVk, !IS_KEY_LOCKED(gafAsyncKeyState, wVk));
-
-        SET_KEY_DOWN(gafAsyncKeyState, wVk, TRUE);
-        gafAsyncKeyStateRecentDown[wVk / 8] |= (1 << (wVk % 8));
-    }
-    else
-        SET_KEY_DOWN(gafAsyncKeyState, wVk, FALSE);
-}
-
-/*
- * co_CallLowLevelKeyboardHook
- *
- * Calls WH_KEYBOARD_LL hook
- */
-static LRESULT
-co_CallLowLevelKeyboardHook(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime, DWORD dwExtraInfo)
-{
-    KBDLLHOOKSTRUCT KbdHookData;
-    UINT uMsg;
-
-    KbdHookData.vkCode = wVk;
-    KbdHookData.scanCode = wScanCode;
-    KbdHookData.flags = 0;
-    if (dwFlags & KEYEVENTF_EXTENDEDKEY)
-        KbdHookData.flags |= LLKHF_EXTENDED;
-    if (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU))
-        KbdHookData.flags |= LLKHF_ALTDOWN;
-    if (dwFlags & KEYEVENTF_KEYUP)
-        KbdHookData.flags |= LLKHF_UP;
-    if (bInjected)
-        KbdHookData.flags |= LLKHF_INJECTED;
-    KbdHookData.time = dwTime;
-    KbdHookData.dwExtraInfo = dwExtraInfo;
-
-    /* Note: it doesnt support WM_SYSKEYUP */
-    if (dwFlags & KEYEVENTF_KEYUP)
-        uMsg = WM_KEYUP;
-    else if (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU) && !IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL))
-        uMsg = WM_SYSKEYDOWN;
-    else
-        uMsg = WM_KEYDOWN;
-
-    return co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, uMsg, (LPARAM)&KbdHookData);
-}
-
-/*
- * SnapWindow
- *
- * Saves snapshot of specified window or whole screen in the clipboard
- */
-static VOID
-SnapWindow(HWND hWnd)
-{
-    HBITMAP hbm = NULL, hbmOld;
-    HDC hdc = NULL, hdcMem;
-    SETCLIPBDATA scd;
-    INT cx, cy;
-    PWND pWnd = NULL;
-
-    TRACE("SnapWindow(%p)\n", hWnd);
-
-    /* If no windows is given, make snapshot of desktop window */
-    if (!hWnd)
-        hWnd = IntGetDesktopWindow();
-
-    pWnd = UserGetWindowObject(hWnd);
-    if (!pWnd)
-    {
-        ERR("Invalid window\n");
-        goto cleanup;
-    }
-
-    hdc = UserGetDCEx(pWnd, NULL, DCX_USESTYLE | DCX_WINDOW);
-    if (!hdc)
-    {
-        ERR("UserGetDCEx failed!\n");
-        goto cleanup;
-    }
-
-    cx = pWnd->rcWindow.right - pWnd->rcWindow.left;
-    cy = pWnd->rcWindow.bottom - pWnd->rcWindow.top;
-
-    hbm = NtGdiCreateCompatibleBitmap(hdc, cx, cy);
-    if (!hbm)
-    {
-        ERR("NtGdiCreateCompatibleBitmap failed!\n");
-        goto cleanup;
-    }
-
-    hdcMem = NtGdiCreateCompatibleDC(hdc);
-    if (!hdcMem)
-    {
-        ERR("NtGdiCreateCompatibleDC failed!\n");
-        goto cleanup;
-    }
-
-    hbmOld = NtGdiSelectBitmap(hdcMem, hbm);
-    NtGdiBitBlt(hdcMem, 0, 0, cx, cy, hdc, 0, 0, SRCCOPY, 0, 0);
-    NtGdiSelectBitmap(hdcMem, hbmOld);
-    IntGdiDeleteDC(hdcMem, FALSE);
-
-    /* Save snapshot in clipboard */
-    if (UserOpenClipboard(NULL))
-    {
-        UserEmptyClipboard();
-        scd.fIncSerialNumber = TRUE;
-        scd.fGlobalHandle = FALSE;
-        if (UserSetClipboardData(CF_BITMAP, hbm, &scd))
-        {
-            /* Bitmap is managed by system now */
-            hbm = NULL;
-        }
-        UserCloseClipboard();
-    }
-
-cleanup:
-    if (hbm)
-        GreDeleteObject(hbm);
-    if (hdc)
-        UserReleaseDC(pWnd, hdc, FALSE);
-}
-
-/*
- * UserSendKeyboardInput
- *
- * Process keyboard input from input devices and SendInput API
- */
-BOOL NTAPI
-ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD dwTime, DWORD dwExtraInfo)
-{
-    WORD wSimpleVk = 0, wFixedVk, wVk2;
-    PUSER_MESSAGE_QUEUE pFocusQueue;
-    PTHREADINFO pti;
-    BOOL bExt = (dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
-    BOOL bIsDown = (dwFlags & KEYEVENTF_KEYUP) ? FALSE : TRUE;
-    BOOL bPacket = (dwFlags & KEYEVENTF_UNICODE) ? TRUE : FALSE;
-    BOOL bWasSimpleDown = FALSE, bPostMsg = TRUE, bIsSimpleDown;
-    MSG Msg;
-    static BOOL bMenuDownRecently = FALSE;
-
-    /* Get virtual key without shifts (VK_(L|R)* -> VK_*) */
-    wSimpleVk = IntSimplifyVk(wVk);
-    bWasSimpleDown = IS_KEY_DOWN(gafAsyncKeyState, wSimpleVk);
-
-    /* Update key without shifts */
-    wVk2 = IntFixVk(wSimpleVk, !bExt);
-    bIsSimpleDown = bIsDown || IS_KEY_DOWN(gafAsyncKeyState, wVk2);
-    UpdateAsyncKeyState(wSimpleVk, bIsSimpleDown);
-
-    if (bIsDown)
-    {
-        /* Update keyboard LEDs */
-        IntKeyboardUpdateLeds(ghKeyboardDevice,
-                              wSimpleVk,
-                              wScanCode);
-    }
-
-    /* Call WH_KEYBOARD_LL hook */
-    if (co_CallLowLevelKeyboardHook(wVk, wScanCode, dwFlags, bInjected, dwTime, dwExtraInfo))
-    {
-        ERR("Kbd msg dropped by WH_KEYBOARD_LL hook\n");
-        bPostMsg = FALSE;
-    }
-
-    /* Check if this is a hotkey */
-    if (co_UserProcessHotKeys(wSimpleVk, bIsDown)) //// Check if this is correct, refer to hotkey sequence message tests.
-    {
-        TRACE("HotKey Processed\n");
-        bPostMsg = FALSE;
-    }
-
-    wFixedVk = IntFixVk(wSimpleVk, bExt); /* LSHIFT + EXT = RSHIFT */
-    if (wSimpleVk == VK_SHIFT) /* shift can't be extended */
-        bExt = FALSE;
-
-    /* If we have a focus queue, post a keyboard message */
-    pFocusQueue = IntGetFocusMessageQueue();
-    TRACE("ProcessKeyEvent Q 0x%p Active pWnd 0x%p Focus pWnd 0x%p\n",
-           pFocusQueue,
-           (pFocusQueue ?  pFocusQueue->spwndActive : 0),
-           (pFocusQueue ?  pFocusQueue->spwndFocus : 0));
-
-    /* If it is F10 or ALT is down and CTRL is up, it's a system key */
-    if ( wVk == VK_F10 ||
-        (wSimpleVk == VK_MENU && bMenuDownRecently) ||
-        (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU) &&
-        !IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL)) ||
-         // See MSDN WM_SYSKEYDOWN/UP fixes last wine Win test_keyboard_input.
-        (pFocusQueue && !pFocusQueue->spwndFocus) )
-    {
-        bMenuDownRecently = FALSE; // reset
-        if (bIsDown)
-        {
-            Msg.message = WM_SYSKEYDOWN;
-            if (wSimpleVk == VK_MENU)
-            {
-                // Note: If only LALT is pressed WM_SYSKEYUP is generated instead of WM_KEYUP
-                bMenuDownRecently = TRUE;
-            }
-        }
-        else
-            Msg.message = WM_SYSKEYUP;
-    }
-    else
-    {
-        if (bIsDown)
-            Msg.message = WM_KEYDOWN;
-        else
-            Msg.message = WM_KEYUP;
-    }
-
-    /* Update async state of not simplified vk here.
-       See user32_apitest:GetKeyState */
-    UpdateAsyncKeyState(wFixedVk, bIsDown);
-
-    /* Alt-Tab/Esc Check. Use FocusQueue or RIT Queue */
-    if (bIsSimpleDown && !bWasSimpleDown &&
-        IS_KEY_DOWN(gafAsyncKeyState, VK_MENU) &&
-        !IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL) &&
-        (wVk == VK_ESCAPE || wVk == VK_TAB))
-    {
-       TRACE("Alt-Tab/Esc Pressed wParam %x\n",wVk);
-    }
-
-    if (bIsDown && wVk == VK_SNAPSHOT)
-    {
-        if (pFocusQueue &&
-            IS_KEY_DOWN(gafAsyncKeyState, VK_MENU) &&
-            !IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL))
-        {
-            // Snap from Active Window, Focus can be null.
-            SnapWindow(pFocusQueue->spwndActive ? UserHMGetHandle(pFocusQueue->spwndActive) : 0);
-        }
-        else
-            SnapWindow(NULL); // Snap Desktop.
-    }
-    else if (pFocusQueue && bPostMsg)
-    {
-        PWND Wnd = pFocusQueue->spwndFocus; // SysInit.....
-
-        pti = pFocusQueue->ptiKeyboard;
-
-        if (!Wnd && pFocusQueue->spwndActive) // SysInit.....
-        {
-           // Going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input.
-           Wnd = pFocusQueue->spwndActive;
-        }
-        if (Wnd) pti = Wnd->head.pti;
-
-        /* Init message */
-        Msg.hwnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
-        Msg.wParam = wFixedVk & 0xFF; /* Note: It's simplified by msg queue */
-        Msg.lParam = MAKELPARAM(1, wScanCode);
-        Msg.time = dwTime;
-        Msg.pt = gpsi->ptCursor;
-
-        if ( Msg.message == WM_KEYDOWN || Msg.message == WM_SYSKEYDOWN )
-        {
-           if ( (Msg.wParam == VK_SHIFT ||
-                 Msg.wParam == VK_CONTROL ||
-                 Msg.wParam == VK_MENU ) &&
-               !IS_KEY_DOWN(gafAsyncKeyState, Msg.wParam))
-           {
-              ERR("Set last input\n");
-              //ptiLastInput = pti;
-           }
-        }
-
-        /* If it is VK_PACKET, high word of wParam is used for wchar */
-        if (!bPacket)
-        {
-            if (bExt)
-                Msg.lParam |= KF_EXTENDED << 16;
-            if (IS_KEY_DOWN(gafAsyncKeyState, VK_MENU))
-                Msg.lParam |= KF_ALTDOWN << 16;
-            if (bWasSimpleDown)
-                Msg.lParam |= KF_REPEAT << 16;
-            if (!bIsDown)
-                Msg.lParam |= KF_UP << 16;
-            /* FIXME: Set KF_DLGMODE and KF_MENUMODE when needed */
-            if (pFocusQueue->QF_flags & QF_DIALOGACTIVE)
-                Msg.lParam |= KF_DLGMODE << 16;
-            if (pFocusQueue->MenuOwner) // pti->pMenuState->fMenuStarted
-                Msg.lParam |= KF_MENUMODE << 16;
-        }
-
-        // Post mouse move before posting key buttons, to keep it syned.
-        if (pFocusQueue->QF_flags & QF_MOUSEMOVED)
-        {
-           IntCoalesceMouseMove(pti);
-        }
-
-        /* Post a keyboard message */
-        TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam);
-        if (!Wnd) {ERR("Window is NULL\n");}
-        MsqPostMessage(pti, &Msg, TRUE, QS_KEY, 0, dwExtraInfo);
-    }
-    return TRUE;
-}
-
-BOOL NTAPI
-UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
-{
-    WORD wScanCode, wVk;
-    PKL pKl = NULL;
-    PKBDTABLES pKbdTbl;
-    PUSER_MESSAGE_QUEUE pFocusQueue;
-    LARGE_INTEGER LargeTickCount;
-    DWORD dwTime;
-    BOOL bExt = (pKbdInput->dwFlags & KEYEVENTF_EXTENDEDKEY) ? TRUE : FALSE;
-
-    gppiInputProvider = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->ppi;
-
-    /* Find the target thread whose locale is in effect */
-    pFocusQueue = IntGetFocusMessageQueue();
-
-    if (pFocusQueue && pFocusQueue->ptiKeyboard)
-    {
-        pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
-    }
-
-    if (!pKl)
-        pKl = W32kGetDefaultKeyLayout();
-    if (!pKl)
-    {
-        ERR("No keyboard layout!\n");
-        return FALSE;
-    }
-
-    pKbdTbl = pKl->spkf->pKbdTbl;
-
-    /* Note: wScan field is always used */
-    wScanCode = pKbdInput->wScan;
-
-    if (pKbdInput->dwFlags & KEYEVENTF_UNICODE)
-    {
-        /* Generate WM_KEYDOWN msg with wParam == VK_PACKET and
-           high order word of lParam == pKbdInput->wScan */
-        wVk = VK_PACKET;
-    }
-    else
-    {
-        wScanCode &= 0x7F;
-        if (pKbdInput->dwFlags & KEYEVENTF_SCANCODE)
-        {
-            /* Don't ignore invalid scan codes */
-            wVk = IntVscToVk(wScanCode | (bExt ? 0xE000 : 0), pKbdTbl);
-            if (!wVk) /* use 0xFF if vsc is invalid */
-                wVk = 0xFF;
-        }
-        else
-        {
-            wVk = pKbdInput->wVk & 0xFF;
-        }
-    }
-
-    /* If time is given, use it */
-    if (pKbdInput->time)
-        dwTime = pKbdInput->time;
-    else
-    {
-        KeQueryTickCount(&LargeTickCount);
-        dwTime = MsqCalculateMessageTime(&LargeTickCount);
-    }
-
-    if (wVk == VK_RMENU && (pKbdTbl->fLocaleFlags & KLLF_ALTGR))
-    {
-        /* For AltGr keyboards RALT generates CTRL events */
-        ProcessKeyEvent(VK_LCONTROL, 0, pKbdInput->dwFlags & KEYEVENTF_KEYUP, bInjected, dwTime, 0);
-    }
-
-    /* Finally process this key */
-    return ProcessKeyEvent(wVk, wScanCode, pKbdInput->dwFlags, bInjected, dwTime, pKbdInput->dwExtraInfo);
-}
-
-/*
- * UserProcessKeyboardInput
- *
- * Process raw keyboard input data
- */
-VOID NTAPI
-UserProcessKeyboardInput(
-    PKEYBOARD_INPUT_DATA pKbdInputData)
-{
-    WORD wScanCode, wVk;
-    PKL pKl = NULL;
-    PKBDTABLES pKbdTbl;
-    PUSER_MESSAGE_QUEUE pFocusQueue;
-
-    /* Calculate scan code with prefix */
-    wScanCode = pKbdInputData->MakeCode & 0x7F;
-    if (pKbdInputData->Flags & KEY_E0)
-        wScanCode |= 0xE000;
-    if (pKbdInputData->Flags & KEY_E1)
-        wScanCode |= 0xE100;
-
-    /* Find the target thread whose locale is in effect */
-    pFocusQueue = IntGetFocusMessageQueue();
-
-    if (pFocusQueue && pFocusQueue->ptiKeyboard)
-    {
-        pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
-    }
-
-    if (!pKl)
-        pKl = W32kGetDefaultKeyLayout();
-    if (!pKl)
-        return;
-
-    pKbdTbl = pKl->spkf->pKbdTbl;
-
-    /* Convert scan code to virtual key.
-       Note: We could call UserSendKeyboardInput using scan code,
-             but it wouldn't interpret E1 key(s) properly */
-    wVk = IntVscToVk(wScanCode, pKbdTbl);
-    TRACE("UserProcessKeyboardInput: %x (break: %u) -> %x\n",
-          wScanCode, (pKbdInputData->Flags & KEY_BREAK) ? 1u : 0, wVk);
-
-    if (wVk)
-    {
-        KEYBDINPUT KbdInput;
-
-        /* Support numlock */
-        if ((wVk & KBDNUMPAD) && IS_KEY_LOCKED(gafAsyncKeyState, VK_NUMLOCK))
-        {
-            wVk = IntTranslateNumpadKey(wVk & 0xFF);
-        }
-
-        /* Send keyboard input */
-        KbdInput.wVk = wVk & 0xFF;
-        KbdInput.wScan = wScanCode & 0x7F;
-        KbdInput.dwFlags = 0;
-        if (pKbdInputData->Flags & KEY_BREAK)
-            KbdInput.dwFlags |= KEYEVENTF_KEYUP;
-
-        if (wVk & KBDEXT)
-            KbdInput.dwFlags |= KEYEVENTF_EXTENDEDKEY;
-        //
-        // Based on wine input:test_Input_blackbox this is okay. It seems the 
-        // bit did not get set and more research is needed. Now the right
-        // shift works.
-        //
-        if (wVk == VK_RSHIFT)
-            KbdInput.dwFlags |= KEYEVENTF_EXTENDEDKEY;
-
-        KbdInput.time = 0;
-        KbdInput.dwExtraInfo = pKbdInputData->ExtraInformation;
-        UserSendKeyboardInput(&KbdInput, FALSE);
-
-        /* E1 keys don't have break code */
-        if (pKbdInputData->Flags & KEY_E1)
-        {
-            /* Send key up event */
-            KbdInput.dwFlags |= KEYEVENTF_KEYUP;
-            UserSendKeyboardInput(&KbdInput, FALSE);
-        }
-    }
-}
-
-/*
- * IntTranslateKbdMessage
- *
- * Addes WM_(SYS)CHAR messages to message queue if message
- * describes key which produce character.
- */
-BOOL FASTCALL
-IntTranslateKbdMessage(LPMSG lpMsg,
-                       UINT flags)
-{
-    PTHREADINFO pti;
-    INT cch = 0, i;
-    WCHAR wch[3] = { 0 };
-    MSG NewMsg = { 0 };
-    PKBDTABLES pKbdTbl;
-    LARGE_INTEGER LargeTickCount;
-    BOOL bResult = FALSE;
-
-    switch(lpMsg->message)
-    {
-       case WM_KEYDOWN:
-       case WM_KEYUP:
-       case WM_SYSKEYDOWN:
-       case WM_SYSKEYUP:
-          break;
-       default:
-          return FALSE;
-    }
-
-    pti = PsGetCurrentThreadWin32Thread();
-
-    if (!pti->KeyboardLayout)
-    {
-       pti->KeyboardLayout = W32kGetDefaultKeyLayout();
-       pti->pClientInfo->hKL = pti->KeyboardLayout ? pti->KeyboardLayout->hkl : NULL;
-       pKbdTbl = pti->KeyboardLayout ? pti->KeyboardLayout->spkf->pKbdTbl : NULL;
-    }
-    else
-       pKbdTbl = pti->KeyboardLayout->spkf->pKbdTbl;
-    if (!pKbdTbl)
-        return FALSE;
-
-    if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN)
-        return FALSE;
-
-    /* Init pt, hwnd and time msg fields */
-    NewMsg.pt = gpsi->ptCursor;
-    NewMsg.hwnd = lpMsg->hwnd;
-    KeQueryTickCount(&LargeTickCount);
-    NewMsg.time = MsqCalculateMessageTime(&LargeTickCount);
-
-    TRACE("Enter IntTranslateKbdMessage msg %s, vk %x\n",
-        lpMsg->message == WM_SYSKEYDOWN ? "WM_SYSKEYDOWN" : "WM_KEYDOWN", lpMsg->wParam);
-
-    if (lpMsg->wParam == VK_PACKET)
-    {
-        NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
-        NewMsg.wParam = HIWORD(lpMsg->lParam);
-        NewMsg.lParam = LOWORD(lpMsg->lParam);
-        MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0, 0);
-        return TRUE;
-    }
-
-    cch = IntToUnicodeEx(lpMsg->wParam,
-                         HIWORD(lpMsg->lParam) & 0xFF,
-                         pti->MessageQueue->afKeyState,
-                         wch,
-                         sizeof(wch) / sizeof(wch[0]),
-                         0,
-                         pKbdTbl);
-
-    if (cch)
-    {
-        if (cch > 0) /* Normal characters */
-            NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
-        else /* Dead character */
-        {
-            cch = -cch;
-            NewMsg.message =
-                (lpMsg->message == WM_KEYDOWN) ? WM_DEADCHAR : WM_SYSDEADCHAR;
-        }
-        NewMsg.lParam = lpMsg->lParam;
-
-        /* Send all characters */
-        for (i = 0; i < cch; ++i)
-        {
-            TRACE("Msg: %x '%lc' (%04x) %08x\n", NewMsg.message, wch[i], wch[i], NewMsg.lParam);
-            NewMsg.wParam = wch[i];
-            MsqPostMessage(pti, &NewMsg, FALSE, QS_KEY, 0, 0);
-        }
-        bResult = TRUE;
-    }
-
-    TRACE("Leave IntTranslateKbdMessage ret %d, cch %d, msg %x, wch %x\n",
-        bResult, cch, NewMsg.message, NewMsg.wParam);
-    return bResult;
-}
-
-/*
- * Map a virtual key code, or virtual scan code, to a scan code, key code,
- * or unshifted unicode character.
- *
- * Code: See Below
- * Type:
- * 0 -- Code is a virtual key code that is converted into a virtual scan code
- *      that does not distinguish between left and right shift keys.
- * 1 -- Code is a virtual scan code that is converted into a virtual key code
- *      that does not distinguish between left and right shift keys.
- * 2 -- Code is a virtual key code that is converted into an unshifted unicode
- *      character.
- * 3 -- Code is a virtual scan code that is converted into a virtual key code
- *      that distinguishes left and right shift keys.
- * KeyLayout: Keyboard layout handle
- *
- * @implemented
- */
-static UINT
-IntMapVirtualKeyEx(UINT uCode, UINT Type, PKBDTABLES pKbdTbl)
-{
-    UINT uRet = 0;
-
-    switch (Type)
-    {
-        case MAPVK_VK_TO_VSC:
-            uCode = IntFixVk(uCode, FALSE);
-            uRet = IntVkToVsc(uCode, pKbdTbl);
-            if (uRet > 0xFF) // Fail for scancodes with prefix (e0, e1)
-                uRet = 0;
-            break;
-
-        case MAPVK_VSC_TO_VK:
-            uRet = IntVscToVk(uCode, pKbdTbl) & 0xFF;
-            uRet = IntSimplifyVk(uRet);
-            break;
-
-        case MAPVK_VK_TO_CHAR:
-            uRet = (UINT)IntVkToChar(uCode, pKbdTbl);
-        break;
-
-        case MAPVK_VSC_TO_VK_EX:
-            uRet = IntVscToVk(uCode, pKbdTbl) & 0xFF;
-            break;
-
-        case MAPVK_VK_TO_VSC_EX:
-            uRet = IntVkToVsc(uCode, pKbdTbl);
-            break;
-
-        default:
-            EngSetLastError(ERROR_INVALID_PARAMETER);
-            ERR("Wrong type value: %u\n", Type);
-    }
-
-    return uRet;
-}
-
-/*
- * NtUserMapVirtualKeyEx
- *
- * Map a virtual key code, or virtual scan code, to a scan code, key code,
- * or unshifted unicode character. See IntMapVirtualKeyEx.
- */
-UINT
-APIENTRY
-NtUserMapVirtualKeyEx(UINT uCode, UINT uType, DWORD keyboardId, HKL dwhkl)
-{
-    PKBDTABLES pKbdTbl = NULL;
-    UINT ret = 0;
-
-    TRACE("Enter NtUserMapVirtualKeyEx\n");
-    UserEnterShared();
-
-    if (!dwhkl)
-    {
-        PTHREADINFO pti;
-
-        pti = PsGetCurrentThreadWin32Thread();
-        if (pti && pti->KeyboardLayout)
-            pKbdTbl = pti->KeyboardLayout->spkf->pKbdTbl;
-    }
-    else
-    {
-        PKL pKl;
-
-        pKl = UserHklToKbl(dwhkl);
-        if (pKl)
-            pKbdTbl = pKl->spkf->pKbdTbl;
-    }
-
-    if (pKbdTbl)
-        ret = IntMapVirtualKeyEx(uCode, uType, pKbdTbl);
-
-    UserLeave();
-    TRACE("Leave NtUserMapVirtualKeyEx, ret=%u\n", ret);
-    return ret;
-}
-
-/*
- * NtUserToUnicodeEx
- *
- * Translates virtual key to characters
- */
-int
-APIENTRY
-NtUserToUnicodeEx(
-    UINT wVirtKey,
-    UINT wScanCode,
-    PBYTE pKeyStateUnsafe,
-    LPWSTR pwszBuffUnsafe,
-    INT cchBuff,
-    UINT wFlags,
-    HKL dwhkl)
-{
-    PTHREADINFO pti;
-    BYTE afKeyState[256 * 2 / 8] = {0};
-    PWCHAR pwszBuff = NULL;
-    INT i, iRet = 0;
-    PKL pKl = NULL;
-
-    TRACE("Enter NtUserSetKeyboardState\n");
-
-    /* Return 0 if SC_KEY_UP bit is set */
-    if (wScanCode & SC_KEY_UP || wVirtKey >= 0x100)
-    {
-        ERR("Invalid parameter\n");
-        return 0;
-    }
-
-    _SEH2_TRY
-    {
-        /* Probe and copy key state to smaller bitmap */
-        ProbeForRead(pKeyStateUnsafe, 256 * sizeof(BYTE), 1);
-        for (i = 0; i < 256; ++i)
-        {
-            if (pKeyStateUnsafe[i] & KS_DOWN_BIT)
-                SET_KEY_DOWN(afKeyState, i, TRUE);
-            if (pKeyStateUnsafe[i] & KS_LOCK_BIT)
-                SET_KEY_LOCKED(afKeyState, i, TRUE);
-        }
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-        ERR("Cannot copy key state\n");
-        SetLastNtError(_SEH2_GetExceptionCode());
-        _SEH2_YIELD(return 0);
-    }
-    _SEH2_END;
-
-    pwszBuff = ExAllocatePoolWithTag(NonPagedPool, sizeof(WCHAR) * cchBuff, TAG_STRING);
-    if (!pwszBuff)
-    {
-        ERR("ExAllocatePoolWithTag(%u) failed\n", sizeof(WCHAR) * cchBuff);
-        return 0;
-    }
-    RtlZeroMemory(pwszBuff, sizeof(WCHAR) * cchBuff);
-
-    UserEnterExclusive(); // Note: We modify wchDead static variable
-
-    if (dwhkl)
-        pKl = UserHklToKbl(dwhkl);
-
-    if (!pKl)
-    {
-        pti = PsGetCurrentThreadWin32Thread();
-        pKl = pti->KeyboardLayout;
-    }
-
-    iRet = IntToUnicodeEx(wVirtKey,
-                          wScanCode,
-                          afKeyState,
-                          pwszBuff,
-                          cchBuff,
-                          wFlags,
-                          pKl ? pKl->spkf->pKbdTbl : NULL);
-
-    MmCopyToCaller(pwszBuffUnsafe, pwszBuff, cchBuff * sizeof(WCHAR));
-    ExFreePoolWithTag(pwszBuff, TAG_STRING);
-
-    UserLeave();
-    TRACE("Leave NtUserSetKeyboardState, ret=%i\n", iRet);
-    return iRet;
-}
-
-/*
- * NtUserGetKeyNameText
- *
- * Gets key name from keyboard layout
- */
-DWORD
-APIENTRY
-NtUserGetKeyNameText(LONG lParam, LPWSTR lpString, int cchSize)
-{
-    PTHREADINFO pti;
-    DWORD i, cchKeyName, dwRet = 0;
-    WORD wScanCode = (lParam >> 16) & 0xFF;
-    BOOL bExtKey = (HIWORD(lParam) & KF_EXTENDED) ? TRUE : FALSE;
-    PKBDTABLES pKbdTbl;
-    VSC_LPWSTR *pKeyNames = NULL;
-    CONST WCHAR *pKeyName = NULL;
-    WCHAR KeyNameBuf[2];
-
-    TRACE("Enter NtUserGetKeyNameText\n");
-
-    UserEnterShared();
-
-    /* Get current keyboard layout */
-    pti = PsGetCurrentThreadWin32Thread();
-    pKbdTbl = pti ? pti->KeyboardLayout->spkf->pKbdTbl : 0;
-
-    if (!pKbdTbl || cchSize < 1)
-    {
-        ERR("Invalid parameter\n");
-        goto cleanup;
-    }
-
-    /* "Do not care" flag */
-    if(lParam & LP_DO_NOT_CARE_BIT)
-    {
-        /* Note: We could do vsc -> vk -> vsc conversion, instead of using
-                 hardcoded scan codes, but it's not what Windows does */
-        if (wScanCode == SCANCODE_RSHIFT && !bExtKey)
-            wScanCode = SCANCODE_LSHIFT;
-        else if (wScanCode == SCANCODE_CTRL || wScanCode == SCANCODE_ALT)
-            bExtKey = FALSE;
-    }
-
-    if (bExtKey)
-        pKeyNames = pKbdTbl->pKeyNamesExt;
-    else
-        pKeyNames = pKbdTbl->pKeyNames;
-
-    for (i = 0; pKeyNames[i].pwsz; i++)
-    {
-        if (pKeyNames[i].vsc == wScanCode)
-        {
-            pKeyName = pKeyNames[i].pwsz;
-            break;
-        }
-    }
-
-    if (!pKeyName)
-    {
-        WORD wVk = IntVscToVk(wScanCode, pKbdTbl);
-
-        if (wVk)
-        {
-            KeyNameBuf[0] = IntVkToChar(wVk, pKbdTbl);
-            KeyNameBuf[1] = 0;
-            if (KeyNameBuf[0])
-                pKeyName = KeyNameBuf;
-        }
-    }
-
-    if (pKeyName)
-    {
-        cchKeyName = wcslen(pKeyName);
-        if (cchKeyName > (cchSize - 1UL))
-            cchKeyName = cchSize - 1UL; // Don't count '\0'
-
-        _SEH2_TRY
-        {
-            ProbeForWrite(lpString, (cchKeyName + 1) * sizeof(WCHAR), 1);
-            RtlCopyMemory(lpString, pKeyName, cchKeyName * sizeof(WCHAR));
-            lpString[cchKeyName] = UNICODE_NULL;
-            dwRet = cchKeyName;
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            SetLastNtError(_SEH2_GetExceptionCode());
-        }
-        _SEH2_END;
-    }
-    else
-    {
-        EngSetLastError(ERROR_INVALID_PARAMETER);
-    }
-
-cleanup:
-    UserLeave();
-    TRACE("Leave NtUserGetKeyNameText, ret=%lu\n", dwRet);
-    return dwRet;
-}
-
-/*
- * UserGetKeyboardType
- *
- * Returns some keyboard specific information
- */
-DWORD FASTCALL
-UserGetKeyboardType(
-    DWORD dwTypeFlag)
-{
-    switch (dwTypeFlag)
-    {
-        case 0:        /* Keyboard type */
-            return (DWORD)gKeyboardInfo.KeyboardIdentifier.Type;
-        case 1:        /* Keyboard Subtype */
-            return (DWORD)gKeyboardInfo.KeyboardIdentifier.Subtype;
-        case 2:        /* Number of F-keys */
-            return (DWORD)gKeyboardInfo.NumberOfFunctionKeys;
-        default:
-            ERR("Unknown type!\n");
-            return 0;    /* Note: we don't have to set last error here */
-    }
-}
-
-/*
- * NtUserVkKeyScanEx
- *
- * Based on IntTranslateChar, instead of processing VirtualKey match,
- * look for wChar match.
- */
-DWORD
-APIENTRY
-NtUserVkKeyScanEx(
-    WCHAR wch,
-    HKL dwhkl,
-    BOOL bUsehKL)
-{
-    PKBDTABLES pKbdTbl;
-    PVK_TO_WCHAR_TABLE pVkToWchTbl;
-    PVK_TO_WCHARS10 pVkToWch;
-    PKL pKl = NULL;
-    DWORD i, dwModBits = 0, dwModNumber = 0, Ret = (DWORD)-1;
-
-    TRACE("NtUserVkKeyScanEx() wch %u, KbdLayout 0x%p\n", wch, dwhkl);
-    UserEnterShared();
-
-    if (bUsehKL)
-    {
-        // Use given keyboard layout
-        if (dwhkl)
-            pKl = UserHklToKbl(dwhkl);
-    }
-    else
-    {
-        // Use thread keyboard layout
-        pKl = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->KeyboardLayout;
-    }
-
-    if (!pKl)
-        goto Exit;
-
-    pKbdTbl = pKl->spkf->pKbdTbl;
-
-    // Interate through all VkToWchar tables while pVkToWchars is not NULL
-    for (i = 0; pKbdTbl->pVkToWcharTable[i].pVkToWchars; i++)
-    {
-        pVkToWchTbl = &pKbdTbl->pVkToWcharTable[i];
-        pVkToWch = (PVK_TO_WCHARS10)(pVkToWchTbl->pVkToWchars);
-
-        // Interate through all virtual keys
-        while (pVkToWch->VirtualKey)
-        {
-            for (dwModNumber = 0; dwModNumber < pVkToWchTbl->nModifications; dwModNumber++)
-            {
-                if (pVkToWch->wch[dwModNumber] == wch)
-                {
-                    dwModBits = pKbdTbl->pCharModifiers->ModNumber[dwModNumber];
-                    TRACE("i %lu wC %04x: dwModBits %08x dwModNumber %08x MaxModBits %08x\n",
-                          i, wch, dwModBits, dwModNumber, pKbdTbl->pCharModifiers->wMaxModBits);
-                    Ret = (dwModBits << 8) | (pVkToWch->VirtualKey & 0xFF);
-                    goto Exit;
-                }
-            }
-            pVkToWch = (PVK_TO_WCHARS10)(((BYTE *)pVkToWch) + pVkToWchTbl->cbSize);
-        }
-    }
-Exit:
-    UserLeave();
-    return Ret;
-}
-
-/* EOF */