* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Window classes
- * FILE: subsys/win32k/ntuser/class.c
+ * FILE: subsystems/win32/win32k/ntuser/input.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISION HISTORY:
* 06-06-2001 CSH Created
/* INCLUDES ******************************************************************/
-#include <w32k.h>
+#include <win32k.h>
#include <ntddkbd.h>
#define NDEBUG
/* GLOBALS *******************************************************************/
PTHREADINFO ptiRawInput;
-PKTIMER MasterTimer;
+PTHREADINFO ptiKeyboard;
+PTHREADINFO ptiMouse;
+PKTIMER MasterTimer = NULL;
PATTACHINFO gpai = NULL;
static HANDLE MouseDeviceHandle;
/* Check if the mouse move is absolute */
if (mid->Flags == MOUSE_MOVE_ABSOLUTE)
{
- /* Set flag and convert to screen location */
+ /* Set flag to convert to screen location */
mi.dwFlags |= MOUSEEVENTF_ABSOLUTE;
- mi.dx = mi.dx / (65535 / (UserGetSystemMetrics(SM_CXVIRTUALSCREEN) - 1));
- mi.dy = mi.dy / (65535 / (UserGetSystemMetrics(SM_CYVIRTUALSCREEN) - 1));
}
if(mid->ButtonFlags)
NTSTATUS Status;
MOUSE_ATTRIBUTES MouseAttr;
+ KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
+ LOW_REALTIME_PRIORITY + 3);
+
InitializeObjectAttributes(&MouseObjectAttributes,
&MouseDeviceName,
0,
FILE_SYNCHRONOUS_IO_ALERT);
} while (!NT_SUCCESS(Status));
+ /* Need to setup basic win32k for this thread to process WH_MOUSE_LL messages. */
+ Status = Win32kInitWin32Thread(PsGetCurrentThread());
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Win32K: Failed making mouse thread a win32 thread.\n");
+ return; //(Status);
+ }
+
+ ptiMouse = PsGetCurrentThreadWin32Thread();
+ ptiMouse->TIF_flags |= TIF_SYSTEMTHREAD;
+ DPRINT("Mouse Thread 0x%x \n", ptiMouse);
+
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
LOW_REALTIME_PRIORITY + 3);
static VOID APIENTRY
IntKeyboardSendWinKeyMsg()
{
- PWINDOW_OBJECT Window;
+ PWND Window;
MSG Mesg;
if (!(Window = UserGetWindowObject(InputWindowStation->ShellWindow)))
Mesg.lParam = 0;
/* The QS_HOTKEY is just a guess */
- MsqPostMessage(Window->MessageQueue, &Mesg, FALSE, QS_HOTKEY);
+ MsqPostMessage(Window->head.pti->MessageQueue, &Mesg, FALSE, QS_HOTKEY);
}
static VOID APIENTRY
return; //(Status);
}
+ ptiKeyboard = PsGetCurrentThreadWin32Thread();
+ ptiKeyboard->TIF_flags |= TIF_SYSTEMTHREAD;
+ DPRINT("Keyboard Thread 0x%x \n", ptiKeyboard);
+
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
LOW_REALTIME_PRIORITY + 3);
for (;NumKeys;memcpy(&KeyInput, &NextKeyInput, sizeof(KeyInput)),
NumKeys--)
{
+ PKBL keyboardLayout = NULL;
lParam = 0;
IntKeyboardUpdateLeds(KeyboardDeviceHandle,
}
/* Find the target thread whose locale is in effect */
- FocusQueue = IntGetFocusMessageQueue();
+ FocusQueue = IntGetFocusMessageQueue();
- /* This might cause us to lose hot keys, which are important
- * (ctrl-alt-del secure attention sequence). Not sure if it
- * can happen though.
- */
- if (!FocusQueue)
- continue;
-
- msg.lParam = lParam;
- msg.hwnd = FocusQueue->FocusWindow;
+ if (FocusQueue)
+ {
+ msg.hwnd = FocusQueue->FocusWindow;
- FocusThread = FocusQueue->Thread;
+ FocusThread = FocusQueue->Thread;
+ if (FocusThread && FocusThread->Tcb.Win32Thread)
+ {
+ keyboardLayout = ((PTHREADINFO)FocusThread->Tcb.Win32Thread)->KeyboardLayout;
+ }
+ }
+ if (!keyboardLayout)
+ {
+ keyboardLayout = W32kGetDefaultKeyLayout();
+ }
- if (!(FocusThread && FocusThread->Tcb.Win32Thread &&
- ((PTHREADINFO)FocusThread->Tcb.Win32Thread)->KeyboardLayout))
- continue;
+ msg.lParam = lParam;
/* This function uses lParam to fill wParam according to the
* keyboard layout in use.
*/
W32kKeyProcessMessage(&msg,
- ((PTHREADINFO)FocusThread->Tcb.Win32Thread)->KeyboardLayout->KBTables,
+ keyboardLayout->KBTables,
KeyInput.Flags & KEY_E0 ? 0xE0 :
(KeyInput.Flags & KEY_E1 ? 0xE1 : 0));
continue; /* Eat key up motion too */
}
+ if (!FocusQueue)
+ {
+ /* There is no focused window to receive a keyboard message */
+ continue;
+ }
/*
* Post a keyboard message.
*/
Objects[0] = &InputThreadsStart;
-
- MasterTimer = ExAllocatePoolWithTag(NonPagedPool, sizeof(KTIMER), TAG_INPUT);
- if (!MasterTimer)
- {
- DPRINT1("Win32K: Failed making Raw Input thread a win32 thread.\n");
- return;
- }
- KeInitializeTimer(MasterTimer);
Objects[1] = MasterTimer;
// This thread requires win32k!
}
ptiRawInput = PsGetCurrentThreadWin32Thread();
- DPRINT("\nRaw Input Thread 0x%x \n", ptiRawInput);
-
+ ptiRawInput->TIF_flags |= TIF_SYSTEMTHREAD;
+ DPRINT("Raw Input Thread 0x%x \n", ptiRawInput);
KeSetPriorityThread(&PsGetCurrentThread()->Tcb,
LOW_REALTIME_PRIORITY + 3);
DPRINT1("Raw Input Thread Exit!\n");
}
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
InitInputImpl(VOID)
{
NTSTATUS Status;
KeInitializeEvent(&InputThreadsStart, NotificationEvent, FALSE);
+ MasterTimer = ExAllocatePoolWithTag(NonPagedPool, sizeof(KTIMER), TAG_INPUT);
+ if (!MasterTimer)
+ {
+ DPRINT1("Win32K: Failed making Raw Input thread a win32 thread.\n");
+ ASSERT(FALSE);
+ return STATUS_UNSUCCESSFUL;
+ }
+ KeInitializeTimer(MasterTimer);
+
/* Initialize the default keyboard layout */
if(!UserInitDefaultKeyboardLayout())
{
return(STATUS_SUCCESS);
}
-BOOL
-APIENTRY
-NtUserDragDetect(
- HWND hWnd,
- POINT pt) // Just like the User call.
-{
- UNIMPLEMENTED
- return 0;
-}
-
BOOL FASTCALL
IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt)
{
PTHREADINFO OldBlock;
ASSERT(W32Thread);
- if(!W32Thread->Desktop || ((W32Thread->TIF_flags & TIF_INCLEANUP) && BlockIt))
+ if(!W32Thread->rpdesk || ((W32Thread->TIF_flags & TIF_INCLEANUP) && BlockIt))
{
/*
* fail blocking if exiting the thread
* e.g. services running in the service window station cannot block input
*/
if(!ThreadHasInputAccess(W32Thread) ||
- !IntIsActiveDesktop(W32Thread->Desktop))
+ !IntIsActiveDesktop(W32Thread->rpdesk))
{
SetLastWin32Error(ERROR_ACCESS_DENIED);
return FALSE;
}
- ASSERT(W32Thread->Desktop);
- OldBlock = W32Thread->Desktop->BlockInputThread;
+ ASSERT(W32Thread->rpdesk);
+ OldBlock = W32Thread->rpdesk->BlockInputThread;
if(OldBlock)
{
if(OldBlock != W32Thread)
SetLastWin32Error(ERROR_ACCESS_DENIED);
return FALSE;
}
- W32Thread->Desktop->BlockInputThread = (BlockIt ? W32Thread : NULL);
+ W32Thread->rpdesk->BlockInputThread = (BlockIt ? W32Thread : NULL);
return OldBlock == NULL;
}
- W32Thread->Desktop->BlockInputThread = (BlockIt ? W32Thread : NULL);
+ W32Thread->rpdesk->BlockInputThread = (BlockIt ? W32Thread : NULL);
return OldBlock == NULL;
}
{
const UINT SwapBtnMsg[2][2] =
{
- {
- WM_LBUTTONDOWN, WM_RBUTTONDOWN
- },
+ {WM_LBUTTONDOWN, WM_RBUTTONDOWN},
{WM_LBUTTONUP, WM_RBUTTONUP}
};
const WPARAM SwapBtn[2] =
{
MK_LBUTTON, MK_RBUTTON
};
- POINT MousePos = {0}, OrgPos;
+ POINT MousePos;
PSYSTEM_CURSORINFO CurInfo;
- PWINSTATION_OBJECT WinSta;
- BOOL DoMove, SwapButtons;
+ BOOL SwapButtons;
MSG Msg;
- SURFACE *psurf;
- SURFOBJ *pso;
- PDC dc;
- PWINDOW_OBJECT DesktopWindow;
-
-#if 1
-
- HDC hDC;
-
- /* FIXME - get the screen dc from the window station or desktop */
- if(!(hDC = IntGetScreenDC()))
- {
- return FALSE;
- }
-#endif
ASSERT(mi);
-#if 0
-
- WinSta = PsGetCurrentProcessWin32Process()->WindowStation;
-#else
- /* FIXME - ugly hack but as long as we're using this dumb callback from the
- mouse class driver, we can't access the window station from the calling
- process */
- WinSta = InputWindowStation;
-#endif
-
- ASSERT(WinSta);
CurInfo = IntGetSysCursorInfo();
}
SwapButtons = gspv.bMouseBtnSwap;
- DoMove = FALSE;
- OrgPos = MousePos = gpsi->ptCursor;
+ MousePos = gpsi->ptCursor;
if(mi->dwFlags & MOUSEEVENTF_MOVE)
{
if(mi->dwFlags & MOUSEEVENTF_ABSOLUTE)
{
- MousePos.x = mi->dx;
- MousePos.y = mi->dy;
+ MousePos.x = mi->dx * UserGetSystemMetrics(SM_CXVIRTUALSCREEN) >> 16;
+ MousePos.y = mi->dy * UserGetSystemMetrics(SM_CYVIRTUALSCREEN) >> 16;
}
else
{
MousePos.x += mi->dx;
MousePos.y += mi->dy;
}
-
- DesktopWindow = IntGetWindowObject(WinSta->ActiveDesktop->DesktopWindow);
-
- if (DesktopWindow)
- {
- if(MousePos.x >= DesktopWindow->Wnd->rcClient.right)
- MousePos.x = DesktopWindow->Wnd->rcClient.right - 1;
- if(MousePos.y >= DesktopWindow->Wnd->rcClient.bottom)
- MousePos.y = DesktopWindow->Wnd->rcClient.bottom - 1;
- UserDereferenceObject(DesktopWindow);
- }
-
- if(MousePos.x < 0)
- MousePos.x = 0;
- if(MousePos.y < 0)
- MousePos.y = 0;
-
- if(CurInfo->CursorClipInfo.IsClipped)
- {
- /* The mouse cursor needs to be clipped */
-
- if(MousePos.x >= (LONG)CurInfo->CursorClipInfo.Right)
- MousePos.x = (LONG)CurInfo->CursorClipInfo.Right;
- if(MousePos.x < (LONG)CurInfo->CursorClipInfo.Left)
- MousePos.x = (LONG)CurInfo->CursorClipInfo.Left;
- if(MousePos.y >= (LONG)CurInfo->CursorClipInfo.Bottom)
- MousePos.y = (LONG)CurInfo->CursorClipInfo.Bottom;
- if(MousePos.y < (LONG)CurInfo->CursorClipInfo.Top)
- MousePos.y = (LONG)CurInfo->CursorClipInfo.Top;
- }
-
- DoMove = (MousePos.x != OrgPos.x || MousePos.y != OrgPos.y);
- }
-
- if (DoMove)
- {
- dc = DC_LockDc(hDC);
- if (dc)
- {
- psurf = dc->dclevel.pSurface;
- if (psurf)
- {
- pso = &psurf->SurfObj;
-
- if (CurInfo->ShowingCursor)
- {
- IntEngMovePointer(pso, MousePos.x, MousePos.y, &(GDIDEV(pso)->Pointer.Exclude));
- }
- /* Only now, update the info in the PDEVOBJ, so EngMovePointer can
- * use the old values to move the pointer image */
- gpsi->ptCursor.x = MousePos.x;
- gpsi->ptCursor.y = MousePos.y;
- }
-
- DC_UnlockDc(dc);
- }
}
/*
* Insert the messages into the system queue
*/
-
- Msg.wParam = CurInfo->ButtonsDown;
+ Msg.wParam = 0;
Msg.lParam = MAKELPARAM(MousePos.x, MousePos.y);
Msg.pt = MousePos;
Msg.wParam |= MK_CONTROL;
}
- if(DoMove)
+ if(mi->dwFlags & MOUSEEVENTF_MOVE)
{
- Msg.message = WM_MOUSEMOVE;
- MsqInsertSystemMessage(&Msg);
+ UserSetCursorPos(MousePos.x, MousePos.y, TRUE);
}
-
- Msg.message = 0;
if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
{
gQueueKeyStateTable[VK_LBUTTON] |= 0xc0;
Msg.message = SwapBtnMsg[0][SwapButtons];
CurInfo->ButtonsDown |= SwapBtn[SwapButtons];
- MsqInsertSystemMessage(&Msg);
+ Msg.wParam |= CurInfo->ButtonsDown;
+ co_MsqInsertMouseMessage(&Msg);
}
else if(mi->dwFlags & MOUSEEVENTF_LEFTUP)
{
gQueueKeyStateTable[VK_LBUTTON] &= ~0x80;
Msg.message = SwapBtnMsg[1][SwapButtons];
CurInfo->ButtonsDown &= ~SwapBtn[SwapButtons];
- MsqInsertSystemMessage(&Msg);
+ Msg.wParam |= CurInfo->ButtonsDown;
+ co_MsqInsertMouseMessage(&Msg);
}
if(mi->dwFlags & MOUSEEVENTF_MIDDLEDOWN)
{
gQueueKeyStateTable[VK_MBUTTON] |= 0xc0;
Msg.message = WM_MBUTTONDOWN;
CurInfo->ButtonsDown |= MK_MBUTTON;
- MsqInsertSystemMessage(&Msg);
+ Msg.wParam |= CurInfo->ButtonsDown;
+ co_MsqInsertMouseMessage(&Msg);
}
else if(mi->dwFlags & MOUSEEVENTF_MIDDLEUP)
{
gQueueKeyStateTable[VK_MBUTTON] &= ~0x80;
Msg.message = WM_MBUTTONUP;
CurInfo->ButtonsDown &= ~MK_MBUTTON;
- MsqInsertSystemMessage(&Msg);
+ Msg.wParam |= CurInfo->ButtonsDown;
+ co_MsqInsertMouseMessage(&Msg);
}
if(mi->dwFlags & MOUSEEVENTF_RIGHTDOWN)
{
gQueueKeyStateTable[VK_RBUTTON] |= 0xc0;
Msg.message = SwapBtnMsg[0][!SwapButtons];
CurInfo->ButtonsDown |= SwapBtn[!SwapButtons];
- MsqInsertSystemMessage(&Msg);
+ Msg.wParam |= CurInfo->ButtonsDown;
+ co_MsqInsertMouseMessage(&Msg);
}
else if(mi->dwFlags & MOUSEEVENTF_RIGHTUP)
{
gQueueKeyStateTable[VK_RBUTTON] &= ~0x80;
Msg.message = SwapBtnMsg[1][!SwapButtons];
CurInfo->ButtonsDown &= ~SwapBtn[!SwapButtons];
- MsqInsertSystemMessage(&Msg);
+ Msg.wParam |= CurInfo->ButtonsDown;
+ co_MsqInsertMouseMessage(&Msg);
}
if((mi->dwFlags & (MOUSEEVENTF_XDOWN | MOUSEEVENTF_XUP)) &&
if(mi->mouseData & XBUTTON1)
{
gQueueKeyStateTable[VK_XBUTTON1] |= 0xc0;
+ CurInfo->ButtonsDown |= MK_XBUTTON1;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
- CurInfo->ButtonsDown |= XBUTTON1;
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
if(mi->mouseData & XBUTTON2)
{
gQueueKeyStateTable[VK_XBUTTON2] |= 0xc0;
+ CurInfo->ButtonsDown |= MK_XBUTTON2;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
- CurInfo->ButtonsDown |= XBUTTON2;
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
}
else if(mi->dwFlags & MOUSEEVENTF_XUP)
if(mi->mouseData & XBUTTON1)
{
gQueueKeyStateTable[VK_XBUTTON1] &= ~0x80;
+ CurInfo->ButtonsDown &= ~MK_XBUTTON1;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON1);
- CurInfo->ButtonsDown &= ~XBUTTON1;
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
if(mi->mouseData & XBUTTON2)
{
gQueueKeyStateTable[VK_XBUTTON2] &= ~0x80;
+ CurInfo->ButtonsDown &= ~MK_XBUTTON2;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, XBUTTON2);
- CurInfo->ButtonsDown &= ~XBUTTON2;
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
}
if(mi->dwFlags & MOUSEEVENTF_WHEEL)
{
Msg.message = WM_MOUSEWHEEL;
Msg.wParam = MAKEWPARAM(CurInfo->ButtonsDown, mi->mouseData);
- MsqInsertSystemMessage(&Msg);
+ co_MsqInsertMouseMessage(&Msg);
}
return TRUE;
IntKeyboardInput(KEYBDINPUT *ki)
{
PUSER_MESSAGE_QUEUE FocusMessageQueue;
- PTHREADINFO pti;
MSG Msg;
LARGE_INTEGER LargeTickCount;
KBDLLHOOKSTRUCT KbdHookData;
Msg.time = ki->time;
/* All messages have to contain the cursor point. */
- pti = PsGetCurrentThreadWin32Thread();
Msg.pt = gpsi->ptCursor;
- DPRINT1("Kbd Hook msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
- Msg.message, vk_hook, Msg.lParam);
-
KbdHookData.vkCode = vk_hook;
KbdHookData.scanCode = ki->wScan;
KbdHookData.flags = flags >> 8;
KbdHookData.dwExtraInfo = ki->dwExtraInfo;
if (co_HOOK_CallHooks(WH_KEYBOARD_LL, HC_ACTION, Msg.message, (LPARAM) &KbdHookData))
{
- DPRINT("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
+ DPRINT1("Kbd msg %d wParam %d lParam 0x%08x dropped by WH_KEYBOARD_LL hook\n",
Msg.message, vk_hook, Msg.lParam);
if (Entered) UserLeave();
return FALSE;
FocusMessageQueue->Desktop->pDeskInfo->LastInputWasKbd = TRUE;
Msg.pt = gpsi->ptCursor;
-
- MsqPostMessage(FocusMessageQueue, &Msg, FALSE, QS_KEY);
+ // Post to hardware queue, based on the first part of wine "some GetMessage tests"
+ // in test_PeekMessage()
+ MsqPostMessage(FocusMessageQueue, &Msg, TRUE, QS_KEY);
}
else
{
/* Do not attach to system threads or between different desktops. */
if ( pti->TIF_flags & TIF_DONTATTACHQUEUE ||
ptiTo->TIF_flags & TIF_DONTATTACHQUEUE ||
- pti->Desktop != ptiTo->Desktop )
+ pti->rpdesk != ptiTo->rpdesk )
return FALSE;
/* If Attach set, allocate and link. */
W32Thread = PsGetCurrentThreadWin32Thread();
ASSERT(W32Thread);
- if(!W32Thread->Desktop)
+ if(!W32Thread->rpdesk)
{
RETURN( 0);
}
* e.g. services running in the service window station cannot block input
*/
if(!ThreadHasInputAccess(W32Thread) ||
- !IntIsActiveDesktop(W32Thread->Desktop))
+ !IntIsActiveDesktop(W32Thread->rpdesk))
{
SetLastWin32Error(ERROR_ACCESS_DENIED);
RETURN( 0);