/* * UserSendMouseInput * * Process mouse input from input devices and SendInput API */ BOOL NTAPI UserSendMouseInput(MOUSEINPUT *pmi, BOOL bInjected) { POINT ptCursor; PSYSTEM_CURSORINFO pCurInfo; MSG Msg; DWORD dwFlags; ASSERT(pmi); pCurInfo = IntGetSysCursorInfo(); ptCursor = gpsi->ptCursor; dwFlags = IntFixMouseInputButtons(pmi->dwFlags); gppiInputProvider = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->ppi; if (pmi->dwFlags & MOUSEEVENTF_MOVE) { /* Mouse has changes position */ if (!(pmi->dwFlags & MOUSEEVENTF_ABSOLUTE)) { /* Relative move */ ptCursor.x += pmi->dx; ptCursor.y += pmi->dy; } else if (pmi->dwFlags & MOUSEEVENTF_VIRTUALDESK) { /* Absolute move in virtual screen units */ ptCursor.x = pmi->dx * UserGetSystemMetrics(SM_CXVIRTUALSCREEN) >> 16; ptCursor.y = pmi->dy * UserGetSystemMetrics(SM_CYVIRTUALSCREEN) >> 16; } else {
/* * @implemented */ BOOL APIENTRY NtUserGetCursorInfo( PCURSORINFO pci) { CURSORINFO SafeCi; PSYSTEM_CURSORINFO CurInfo; NTSTATUS Status = STATUS_SUCCESS; PCURICON_OBJECT CurIcon; BOOL Ret = FALSE; DECLARE_RETURN(BOOL); TRACE("Enter NtUserGetCursorInfo\n"); UserEnterExclusive(); CurInfo = IntGetSysCursorInfo(); CurIcon = (PCURICON_OBJECT)CurInfo->CurrentCursorObject; SafeCi.cbSize = sizeof(CURSORINFO); SafeCi.flags = ((CurIcon && CurInfo->ShowingCursor >= 0) ? CURSOR_SHOWING : 0); SafeCi.hCursor = (CurIcon ? CurIcon->head.h : NULL); SafeCi.ptScreenPos = gpsi->ptCursor; _SEH2_TRY { if (pci->cbSize == sizeof(CURSORINFO)) { ProbeForWrite(pci, sizeof(CURSORINFO), 1); RtlCopyMemory(pci, &SafeCi, sizeof(CURSORINFO)); Ret = TRUE; } else { EngSetLastError(ERROR_INVALID_PARAMETER); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; if (!NT_SUCCESS(Status)) { SetLastNtError(Status); } RETURN(Ret); CLEANUP: TRACE("Leave NtUserGetCursorInfo, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; }
/* * UserGetMouseButtonsState * * Returns bitfield of MK_* flags used in mouse messages */ WORD FASTCALL UserGetMouseButtonsState(VOID) { WORD wRet = 0; wRet = IntGetSysCursorInfo()->ButtonsDown; if (IS_KEY_DOWN(gafAsyncKeyState, VK_SHIFT)) wRet |= MK_SHIFT; if (IS_KEY_DOWN(gafAsyncKeyState, VK_CONTROL)) wRet |= MK_CONTROL; return wRet; }
BOOL APIENTRY UserClipCursor( RECTL *prcl) { /* FIXME: Check if process has WINSTA_WRITEATTRIBUTES */ PSYSTEM_CURSORINFO CurInfo; PWND DesktopWindow = NULL; CurInfo = IntGetSysCursorInfo(); DesktopWindow = UserGetDesktopWindow(); if (prcl != NULL && DesktopWindow != NULL) { if (prcl->right < prcl->left || prcl->bottom < prcl->top) { EngSetLastError(ERROR_INVALID_PARAMETER); return FALSE; } CurInfo->bClipped = TRUE; /* Set nw cliping region. Note: we can't use RECTL_bIntersectRect because it sets rect to 0 0 0 0 when it's empty. For more info see monitor winetest */ CurInfo->rcClip.left = max(prcl->left, DesktopWindow->rcWindow.left); CurInfo->rcClip.right = min(prcl->right, DesktopWindow->rcWindow.right); if (CurInfo->rcClip.right < CurInfo->rcClip.left) CurInfo->rcClip.right = CurInfo->rcClip.left; CurInfo->rcClip.top = max(prcl->top, DesktopWindow->rcWindow.top); CurInfo->rcClip.bottom = min(prcl->bottom, DesktopWindow->rcWindow.bottom); if (CurInfo->rcClip.bottom < CurInfo->rcClip.top) CurInfo->rcClip.bottom = CurInfo->rcClip.top; /* Make sure cursor is in clipping region */ UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, 0, 0, FALSE); } else { CurInfo->bClipped = FALSE; } return TRUE; }
/* * @implemented */ BOOL APIENTRY NtUserGetClipCursor( RECTL *lpRect) { /* FIXME: Check if process has WINSTA_READATTRIBUTES */ PSYSTEM_CURSORINFO CurInfo; RECTL Rect; NTSTATUS Status; DECLARE_RETURN(BOOL); TRACE("Enter NtUserGetClipCursor\n"); UserEnterExclusive(); if (!lpRect) RETURN(FALSE); CurInfo = IntGetSysCursorInfo(); if (CurInfo->bClipped) { Rect = CurInfo->rcClip; } else { Rect.left = 0; Rect.top = 0; Rect.right = UserGetSystemMetrics(SM_CXSCREEN); Rect.bottom = UserGetSystemMetrics(SM_CYSCREEN); } Status = MmCopyToCaller(lpRect, &Rect, sizeof(RECT)); if (!NT_SUCCESS(Status)) { SetLastNtError(Status); RETURN(FALSE); } RETURN(TRUE); CLEANUP: TRACE("Leave NtUserGetClipCursor, ret=%i\n",_ret_); UserLeave(); END_CLEANUP; }
BOOL UserSetCursorPos( INT x, INT y, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook) { PWND DesktopWindow; PSYSTEM_CURSORINFO CurInfo; MSG Msg; RECTL rcClip; POINT pt; if(!(DesktopWindow = UserGetDesktopWindow())) { return FALSE; } CurInfo = IntGetSysCursorInfo(); /* Clip cursor position */ if (!CurInfo->bClipped) rcClip = DesktopWindow->rcClient; else rcClip = CurInfo->rcClip; if(x >= rcClip.right) x = rcClip.right - 1; if(x < rcClip.left) x = rcClip.left; if(y >= rcClip.bottom) y = rcClip.bottom - 1; if(y < rcClip.top) y = rcClip.top; pt.x = x; pt.y = y; /* 1. Generate a mouse move message, this sets the htEx and Track Window too. */ Msg.message = WM_MOUSEMOVE; Msg.wParam = UserGetMouseButtonsState(); Msg.lParam = MAKELPARAM(x, y); Msg.pt = pt; co_MsqInsertMouseMessage(&Msg, flags, dwExtraInfo, Hook); /* 2. Store the new cursor position */ gpsi->ptCursor = pt; return TRUE; }