* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* COPYRIGHT: See COPYING in the top level directory
/* INCLUDES ******************************************************************/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
/* Key States */
#define KS_DOWN_MASK 0xc0
#define KS_DOWN_BIT 0x80
-#define KS_LOCK_BIT 0x01
+#define KS_LOCK_BIT 0x01
+/* Scan Codes */
+#define SC_KEY_UP 0x8000
/* lParam bits */
#define LP_EXT_BIT (1<<24)
/* From kbdxx.c -- Key changes with numlock */
static UINT DontDistinguishShifts( UINT ret )
{
if( ret == VK_LSHIFT || ret == VK_RSHIFT )
- ret = VK_LSHIFT;
+ ret = VK_SHIFT;
if( ret == VK_LCONTROL || ret == VK_RCONTROL )
- ret = VK_LCONTROL;
+ ret = VK_CONTROL;
if( ret == VK_LMENU || ret == VK_RMENU )
- ret = VK_LMENU;
+ ret = VK_MENU;
return ret;
}
-static VOID STDCALL SetKeyState(DWORD key, DWORD vk, DWORD ext, BOOL down)
+static VOID APIENTRY SetKeyState(DWORD key, DWORD vk, DWORD ext, BOOL down)
{
ASSERT(vk <= 0xff);
gQueueKeyStateTable[vk] ^= KS_LOCK_BIT;
}
- if (ext && vk == VK_LSHIFT)
- vk = VK_RSHIFT;
- if (ext && vk == VK_LCONTROL)
- vk = VK_RCONTROL;
- if (ext && vk == VK_LMENU)
- vk = VK_RMENU;
+ if (vk == VK_SHIFT)
+ vk = ext ? VK_RSHIFT : VK_LSHIFT;
+ if (vk == VK_CONTROL)
+ vk = ext ? VK_RCONTROL : VK_LCONTROL;
+ if (vk == VK_MENU)
+ vk = ext ? VK_RMENU : VK_LMENU;
if (down)
gQueueKeyStateTable[vk] |= KS_DOWN_BIT;
ModBits |= GetShiftBit( pkKT, VK_MENU );
/* Handle Alt+Gr */
- if (KeysSet( pkKT, KeyState, VK_RMENU, 0 ) &
- KS_DOWN_BIT )
- ModBits |= GetShiftBit( pkKT, VK_CONTROL );
+ if (pkKT->fLocalFlags & 0x1)
+ if (KeysSet( pkKT, KeyState, VK_RMENU, 0 ) &
+ KS_DOWN_BIT)
+ ModBits |= GetShiftBit( pkKT, VK_CONTROL );
/* Deal with VK_CAPITAL */
if (KeysSet( pkKT, KeyState, VK_CAPITAL, 0 ) & KS_LOCK_BIT)
if( vkPtr->VirtualKey != 0xff )
{
DPRINT( "Found dead key with no trailer in the table.\n" );
- DPRINT( "VK: %04x, ADDR: %08x\n", wVirtKey, (int)vkPtr );
+ DPRINT( "VK: %04x, ADDR: %p\n", wVirtKey, vkPtr );
return FALSE;
}
*pwcTranslatedChar = vkPtr->wch[CapsMod];
}
static
-int STDCALL
+int APIENTRY
ToUnicodeInner(UINT wVirtKey,
UINT wScanCode,
PBYTE lpKeyState,
}
-DWORD
-STDCALL
+SHORT
+APIENTRY
NtUserGetKeyState(
- DWORD key)
+ INT key)
{
DECLARE_RETURN(DWORD);
-DWORD
-STDCALL
+SHORT
+APIENTRY
NtUserGetAsyncKeyState(
- DWORD key)
+ INT key)
{
- DECLARE_RETURN(DWORD);
+ DECLARE_RETURN(SHORT);
DPRINT("Enter NtUserGetAsyncKeyState\n");
UserEnterExclusive();
- RETURN(UserGetAsyncKeyState(key));
+ RETURN((SHORT)UserGetAsyncKeyState(key));
CLEANUP:
DPRINT("Leave NtUserGetAsyncKeyState, ret=%i\n",_ret_);
BOOL FASTCALL
IntTranslateKbdMessage(LPMSG lpMsg,
- HKL dwhkl)
+ UINT flags)
{
+ PTHREADINFO pti;
static INT dead_char = 0;
LONG UState = 0;
WCHAR wp[2] = { 0 };
BOOL Result = FALSE;
DWORD ScanCode = 0;
-
- keyLayout = PsGetCurrentThreadWin32Thread()->KeyboardLayout->KBTables;
+ pti = PsGetCurrentThreadWin32Thread();
+ keyLayout = pti->KeyboardLayout->KBTables;
if( !keyLayout )
return FALSE;
+ if (lpMsg->message < WM_KEYFIRST || lpMsg->message > WM_KEYLAST)
+ return FALSE;
if (lpMsg->message != WM_KEYDOWN && lpMsg->message != WM_SYSKEYDOWN)
return FALSE;
- ScanCode = (lpMsg->lParam >> 16) & 0xff;
-
/* All messages have to contain the cursor point. */
- IntGetCursorLocation(PsGetCurrentThreadWin32Thread()->Desktop->WindowStation,
- &NewMsg.pt);
+ NewMsg.pt = gpsi->ptCursor;
+
+ switch (lpMsg->wParam)
+ {
+ case VK_PACKET:
+ NewMsg.message = (lpMsg->message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR;
+ NewMsg.hwnd = lpMsg->hwnd;
+ NewMsg.wParam = HIWORD(lpMsg->lParam);
+ NewMsg.lParam = LOWORD(lpMsg->lParam);
+ MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
+ return TRUE;
+ }
+
+ ScanCode = (lpMsg->lParam >> 16) & 0xff;
UState = ToUnicodeInner(lpMsg->wParam, HIWORD(lpMsg->lParam) & 0xff,
gQueueKeyStateTable, wp, 2, 0,
NewMsg.wParam = dead_char;
NewMsg.lParam = lpMsg->lParam;
dead_char = 0;
- MsqPostMessage(PsGetCurrentThreadWin32Thread()->MessageQueue, &NewMsg, FALSE, QS_KEY);
+ MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
}
NewMsg.hwnd = lpMsg->hwnd;
NewMsg.wParam = wp[0];
NewMsg.lParam = lpMsg->lParam;
DPRINT( "CHAR='%c' %04x %08x\n", wp[0], wp[0], lpMsg->lParam );
- MsqPostMessage(PsGetCurrentThreadWin32Thread()->MessageQueue, &NewMsg, FALSE, QS_KEY);
+ MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
Result = TRUE;
}
else if (UState == -1)
NewMsg.wParam = wp[0];
NewMsg.lParam = lpMsg->lParam;
dead_char = wp[0];
- MsqPostMessage(PsGetCurrentThreadWin32Thread()->MessageQueue, &NewMsg, FALSE, QS_KEY);
+ MsqPostMessage(pti->MessageQueue, &NewMsg, FALSE, QS_KEY);
Result = TRUE;
}
}
DWORD
-STDCALL
+APIENTRY
NtUserGetKeyboardState(
LPBYTE lpKeyState)
{
END_CLEANUP;
}
-DWORD
-STDCALL
+BOOL
+APIENTRY
NtUserSetKeyboardState(LPBYTE lpKeyState)
{
BOOL Result = TRUE;
switch( Type )
{
case 0:
- if( Code == VK_RSHIFT )
+ if( Code == VK_SHIFT )
Code = VK_LSHIFT;
- if( Code == VK_RMENU )
+ if( Code == VK_MENU )
Code = VK_LMENU;
- if( Code == VK_RCONTROL )
+ if( Code == VK_CONTROL )
Code = VK_LCONTROL;
ret = VkToScan( Code, FALSE, keyLayout );
break;
}
UINT
-STDCALL
+APIENTRY
NtUserMapVirtualKeyEx( UINT Code, UINT Type, DWORD keyboardId, HKL dwhkl )
{
+ PTHREADINFO pti;
PKBDTABLES keyLayout;
DECLARE_RETURN(UINT);
DPRINT("Enter NtUserMapVirtualKeyEx\n");
UserEnterExclusive();
- keyLayout = PsGetCurrentThreadWin32Thread() ? PsGetCurrentThreadWin32Thread()->KeyboardLayout->KBTables : 0;
+ pti = PsGetCurrentThreadWin32Thread();
+ keyLayout = pti ? pti->KeyboardLayout->KBTables : 0;
if( !keyLayout )
RETURN(0);
int
-STDCALL
+APIENTRY
NtUserToUnicodeEx(
UINT wVirtKey,
UINT wScanCode,
UINT wFlags,
HKL dwhkl )
{
+ PTHREADINFO pti;
BYTE KeyStateBuf[0x100];
PWCHAR OutPwszBuff = 0;
int ret = 0;
DECLARE_RETURN(int);
DPRINT("Enter NtUserSetKeyboardState\n");
- UserEnterShared();//faxme: this syscall doesnt seem to need any locking...
+ UserEnterShared();//fixme: this syscall doesnt seem to need any locking...
+ /* Key up? */
+ if (wScanCode & SC_KEY_UP)
+ {
+ RETURN(0);
+ }
if( !NT_SUCCESS(MmCopyFromCaller(KeyStateBuf,
lpKeyState,
DPRINT1( "Couldn't copy key state from caller.\n" );
RETURN(0);
}
- OutPwszBuff = ExAllocatePoolWithTag(NonPagedPool,sizeof(WCHAR) * cchBuff, TAG_STRING);
- if( !OutPwszBuff )
+
+ /* Virtual code is correct? */
+ if (wVirtKey < 0x100)
{
- DPRINT1( "ExAllocatePool(%d) failed\n", sizeof(WCHAR) * cchBuff);
- RETURN(0);
+ OutPwszBuff = ExAllocatePoolWithTag(NonPagedPool,sizeof(WCHAR) * cchBuff, TAG_STRING);
+ if( !OutPwszBuff )
+ {
+ DPRINT1( "ExAllocatePoolWithTag(%d) failed\n", sizeof(WCHAR) * cchBuff);
+ RETURN(0);
+ }
+ RtlZeroMemory( OutPwszBuff, sizeof( WCHAR ) * cchBuff );
+
+ pti = PsGetCurrentThreadWin32Thread();
+ ret = ToUnicodeInner( wVirtKey,
+ wScanCode,
+ KeyStateBuf,
+ OutPwszBuff,
+ cchBuff,
+ wFlags,
+ pti ? pti->KeyboardLayout->KBTables : 0 );
+
+ MmCopyToCaller(pwszBuff,OutPwszBuff,sizeof(WCHAR)*cchBuff);
+ ExFreePoolWithTag(OutPwszBuff, TAG_STRING);
}
- RtlZeroMemory( OutPwszBuff, sizeof( WCHAR ) * cchBuff );
-
- ret = ToUnicodeInner( wVirtKey,
- wScanCode,
- KeyStateBuf,
- OutPwszBuff,
- cchBuff,
- wFlags,
- PsGetCurrentThreadWin32Thread() ?
- PsGetCurrentThreadWin32Thread()->KeyboardLayout->KBTables : 0 );
-
- MmCopyToCaller(pwszBuff,OutPwszBuff,sizeof(WCHAR)*cchBuff);
- ExFreePool(OutPwszBuff);
RETURN(ret);
}
DWORD
-STDCALL
+APIENTRY
NtUserGetKeyNameText( LONG lParam, LPWSTR lpString, int nSize )
{
+ PTHREADINFO pti;
int i;
DWORD ret = 0;
UINT CareVk = 0;
DPRINT("Enter NtUserGetKeyNameText\n");
UserEnterShared();
- keyLayout = PsGetCurrentThreadWin32Thread() ?
- PsGetCurrentThreadWin32Thread()->KeyboardLayout->KBTables : 0;
+ pti = PsGetCurrentThreadWin32Thread();
+ keyLayout = pti ? pti->KeyboardLayout->KBTables : 0;
if( !keyLayout || nSize < 1 )
RETURN(0);
if( lParam & (1<<25) )
{
CareVk = VkCode = ScanToVk( ScanCode, ExtKey, keyLayout );
- if( VkCode == VK_LSHIFT || VkCode == VK_RSHIFT )
- VkCode = VK_LSHIFT;
- if( VkCode == VK_LCONTROL || VkCode == VK_RCONTROL )
- VkCode = VK_LCONTROL;
- if( VkCode == VK_LMENU || VkCode == VK_RMENU )
- VkCode = VK_LMENU;
+ switch (VkCode)
+ {
+ case VK_RSHIFT:
+ ScanCode |= 0x100;
+ case VK_LSHIFT:
+ VkCode = VK_SHIFT;
+ break;
+ case VK_LCONTROL:
+ case VK_RCONTROL:
+ VkCode = VK_CONTROL;
+ break;
+ case VK_LMENU:
+ case VK_RMENU:
+ VkCode = VK_MENU;
+ break;
+ }
}
else
{
look for wChar match.
*/
DWORD
-STDCALL
+APIENTRY
NtUserVkKeyScanEx(
WCHAR wChar,
- HKL KeyboardLayout,
- DWORD Unknown2)
+ HKL hKeyboardLayout,
+ BOOL UsehKL ) // TRUE from KeyboardLayout, FALSE from pkbl = (THREADINFO)->KeyboardLayout
{
-/* FIXME: currently, this routine doesnt seem to need any locking */
PKBDTABLES KeyLayout;
PVK_TO_WCHAR_TABLE vtwTbl;
PVK_TO_WCHARS10 vkPtr;
size_t size_this_entry;
int nMod;
- DWORD CapsMod = 0, CapsState = 0;
+ PKBL pkbl = NULL;
+ DWORD CapsMod = 0, CapsState = 0, Ret = -1;
- DPRINT("NtUserVkKeyScanEx() wChar %d, KbdLayout 0x%p\n", wChar, KeyboardLayout);
+ DPRINT("NtUserVkKeyScanEx() wChar %d, KbdLayout 0x%p\n", wChar, hKeyboardLayout);
+ UserEnterShared();
- if(!KeyboardLayout)
- return -1;
- KeyLayout = UserHklToKbl(KeyboardLayout)->KBTables;
+ if (UsehKL)
+ {
+ if ( !hKeyboardLayout || !(pkbl = UserHklToKbl(hKeyboardLayout)))
+ goto Exit;
+ }
+ else // From VkKeyScanAW it is FALSE so KeyboardLayout is white noise.
+ {
+ pkbl = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->KeyboardLayout;
+ }
+
+ KeyLayout = pkbl->KBTables;
for (nMod = 0; KeyLayout->pVkToWcharTable[nMod].nModifications; nMod++)
{
CapsMod = KeyLayout->pCharModifiers->ModNumber[CapsState];
DPRINT("nMod %d wC %04x: CapsMod %08x CapsState %08x MaxModBits %08x\n",
nMod, wChar, CapsMod, CapsState, KeyLayout->pCharModifiers->wMaxModBits);
- return ((CapsMod << 8)|(vkPtr->VirtualKey & 0xff));
+ Ret = ((CapsMod << 8)|(vkPtr->VirtualKey & 0xff));
+ goto Exit;
}
}
vkPtr = (PVK_TO_WCHARS10)(((BYTE *)vkPtr) + size_this_entry);
}
}
- return -1;
+Exit:
+ UserLeave();
+ return Ret;
}