mirror of
https://github.com/reactos/reactos.git
synced 2024-11-04 22:00:55 +00:00
[win32k]
- Rewrite SetCursorPos and ShowCursror - Store coursor show count in SYSTEM_CURSORINFO and not in GDIPOINTER - Fix broken behaviour in ClipCursor svn path=/trunk/; revision=44975
This commit is contained in:
parent
15269e4b77
commit
b8882998c7
8 changed files with 123 additions and 227 deletions
|
@ -99,6 +99,9 @@
|
|||
#define NtUserGetDesktopMapping(Ptr) \
|
||||
(PVOID)NtUserCallOneParam((DWORD)Ptr, ONEPARAM_ROUTINE_GETDESKTOPMAPPING)
|
||||
|
||||
#define NtUserSetCursorPos(x, y) \
|
||||
(BOOL)NtUserCallTwoParam((DWORD)x, (DWORD)y, TWOPARAM_ROUTINE_SETCURSORPOS)
|
||||
|
||||
#define ShowCaret(hwnd) \
|
||||
NtUserShowCaret(hwnd)
|
||||
|
||||
|
|
|
@ -280,18 +280,7 @@ WINAPI
|
|||
SetCursorPos(int X,
|
||||
int Y)
|
||||
{
|
||||
INPUT Input;
|
||||
|
||||
Input.type = INPUT_MOUSE;
|
||||
Input.mi.dx = (LONG)X;
|
||||
Input.mi.dy = (LONG)Y;
|
||||
Input.mi.mouseData = 0;
|
||||
Input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
|
||||
Input.mi.time = 0;
|
||||
Input.mi.dwExtraInfo = 0;
|
||||
|
||||
NtUserSendInput(1, &Input, sizeof(INPUT));
|
||||
return TRUE;
|
||||
return NtUserSetCursorPos(X,Y);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -157,12 +157,6 @@ IntHideMousePointer(
|
|||
|
||||
pgp->Enabled = FALSE;
|
||||
|
||||
/* The mouse is hide from ShowCours and it is frist ?? */
|
||||
if (pgp->ShowPointer < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pgp->psurfSave)
|
||||
{
|
||||
DPRINT1("No SaveSurface!\n");
|
||||
|
@ -215,12 +209,6 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
|
|||
|
||||
pgp->Enabled = TRUE;
|
||||
|
||||
/* Do not blt the pointer, if it is hidden */
|
||||
if (pgp->ShowPointer < 0)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
/* Calculate pointer coordinates */
|
||||
pt.x = ppdev->ptlPointer.x - pgp->HotSpot.x;
|
||||
pt.y = ppdev->ptlPointer.y - pgp->HotSpot.y;
|
||||
|
@ -538,8 +526,11 @@ EngMovePointer(
|
|||
prcl->right = prcl->left + pgp->Size.cx;
|
||||
prcl->bottom = prcl->top + pgp->Size.cy;
|
||||
}
|
||||
} else if (prcl != NULL)
|
||||
}
|
||||
else if (prcl != NULL)
|
||||
{
|
||||
prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
|
||||
}
|
||||
}
|
||||
|
||||
VOID APIENTRY
|
||||
|
|
|
@ -47,7 +47,7 @@ typedef struct _SYSTEM_CURSORINFO
|
|||
UINT ButtonsDown;
|
||||
CURSORCLIP_INFO CursorClipInfo;
|
||||
PCURICON_OBJECT CurrentCursorObject;
|
||||
BYTE ShowingCursor;
|
||||
INT ShowingCursor;
|
||||
/*
|
||||
UINT WheelScroLines;
|
||||
UINT WheelScroChars;
|
||||
|
@ -77,9 +77,9 @@ BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxW
|
|||
INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags);
|
||||
PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon);
|
||||
|
||||
BOOL FASTCALL UserSetCursorPos( INT x, INT y);
|
||||
BOOL UserSetCursorPos( INT x, INT y);
|
||||
|
||||
int APIENTRY UserShowCursor(BOOL bShow);
|
||||
int UserShowCursor(BOOL bShow);
|
||||
|
||||
PSYSTEM_CURSORINFO FASTCALL
|
||||
IntGetSysCursorInfo();
|
||||
|
|
|
@ -33,7 +33,6 @@ typedef struct _GDIPOINTER /* should stay private to ENG? No, part of PDEVOBJ ak
|
|||
SURFACE *psurfColor;
|
||||
SURFACE *psurfMask;
|
||||
SURFACE *psurfSave;
|
||||
int ShowPointer; /* counter negtive do not show the mouse postive show the mouse */
|
||||
|
||||
/* public pointer information */
|
||||
RECTL Exclude; /* required publicly for SPS_ACCEPT_EXCLUDE */
|
||||
|
|
|
@ -137,7 +137,7 @@ UserSetCursor(
|
|||
{
|
||||
UserReferenceObject(NewCursor);
|
||||
|
||||
CurInfo->ShowingCursor = CURSOR_SHOWING;
|
||||
CurInfo->ShowingCursor = 1;
|
||||
CurInfo->CurrentCursorObject = NewCursor;
|
||||
|
||||
/* Call GDI to set the new screen cursor */
|
||||
|
@ -175,6 +175,101 @@ UserSetCursor(
|
|||
return hOldCursor;
|
||||
}
|
||||
|
||||
BOOL UserSetCursorPos( INT x, INT y)
|
||||
{
|
||||
PWINDOW_OBJECT DesktopWindow;
|
||||
PSYSTEM_CURSORINFO CurInfo;
|
||||
HDC hDC;
|
||||
MSG Msg;
|
||||
|
||||
if(!(hDC = IntGetScreenDC()))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CurInfo = IntGetSysCursorInfo();
|
||||
|
||||
DesktopWindow = UserGetDesktopWindow();
|
||||
|
||||
if (DesktopWindow)
|
||||
{
|
||||
if(x >= DesktopWindow->Wnd->rcClient.right)
|
||||
x = DesktopWindow->Wnd->rcClient.right - 1;
|
||||
if(y >= DesktopWindow->Wnd->rcClient.bottom)
|
||||
y = DesktopWindow->Wnd->rcClient.bottom - 1;
|
||||
}
|
||||
|
||||
if(x < 0)
|
||||
x = 0;
|
||||
if(y < 0)
|
||||
y = 0;
|
||||
|
||||
//Clip cursor position
|
||||
if(CurInfo->CursorClipInfo.IsClipped)
|
||||
{
|
||||
if(x >= (LONG)CurInfo->CursorClipInfo.Right)
|
||||
x = (LONG)CurInfo->CursorClipInfo.Right - 1;
|
||||
if(x < (LONG)CurInfo->CursorClipInfo.Left)
|
||||
x = (LONG)CurInfo->CursorClipInfo.Left;
|
||||
if(y >= (LONG)CurInfo->CursorClipInfo.Bottom)
|
||||
y = (LONG)CurInfo->CursorClipInfo.Bottom - 1;
|
||||
if(y < (LONG)CurInfo->CursorClipInfo.Top)
|
||||
y = (LONG)CurInfo->CursorClipInfo.Top;
|
||||
}
|
||||
|
||||
//Store the new cursor position
|
||||
gpsi->ptCursor.x = x;
|
||||
gpsi->ptCursor.y = y;
|
||||
|
||||
//Move the mouse pointer
|
||||
GreMovePointer(hDC, x, y);
|
||||
|
||||
//Generate a mouse move message
|
||||
Msg.message = WM_MOUSEMOVE;
|
||||
Msg.wParam = CurInfo->ButtonsDown;
|
||||
Msg.lParam = MAKELPARAM(x, y);
|
||||
Msg.pt = gpsi->ptCursor;
|
||||
MsqInsertSystemMessage(&Msg);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Called from NtUserCallOneParam with Routine ONEPARAM_ROUTINE_SHOWCURSOR
|
||||
* User32 macro NtUserShowCursor */
|
||||
int UserShowCursor(BOOL bShow)
|
||||
{
|
||||
PSYSTEM_CURSORINFO CurInfo = IntGetSysCursorInfo();;
|
||||
HDC hdcScreen;
|
||||
|
||||
if (!(hdcScreen = IntGetScreenDC()))
|
||||
{
|
||||
return 0; /* No mouse */
|
||||
}
|
||||
|
||||
if (bShow == FALSE)
|
||||
{
|
||||
/* Check if were diplaying a cursor */
|
||||
if (CurInfo->ShowingCursor == 1)
|
||||
{
|
||||
/* Remove the pointer */
|
||||
GreMovePointer(hdcScreen, -1, -1);
|
||||
DPRINT("Removing pointer!\n");
|
||||
}
|
||||
CurInfo->ShowingCursor--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CurInfo->ShowingCursor == 0)
|
||||
{
|
||||
/*Show the pointer*/
|
||||
GreMovePointer(hdcScreen, gpsi->ptCursor.x, gpsi->ptCursor.y);
|
||||
}
|
||||
CurInfo->ShowingCursor++;
|
||||
}
|
||||
|
||||
return CurInfo->ShowingCursor;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have to register that this object is in use by the current
|
||||
* process. The only way to do that seems to be to walk the list
|
||||
|
@ -712,21 +807,14 @@ NtUserClipCursor(
|
|||
if ((Rect.right > Rect.left) && (Rect.bottom > Rect.top)
|
||||
&& DesktopWindow && UnsafeRect != NULL)
|
||||
{
|
||||
MOUSEINPUT mi;
|
||||
|
||||
CurInfo->CursorClipInfo.IsClipped = TRUE;
|
||||
CurInfo->CursorClipInfo.Left = max(Rect.left, DesktopWindow->Wnd->rcWindow.left);
|
||||
CurInfo->CursorClipInfo.Top = max(Rect.top, DesktopWindow->Wnd->rcWindow.top);
|
||||
CurInfo->CursorClipInfo.Right = min(Rect.right - 1, DesktopWindow->Wnd->rcWindow.right - 1);
|
||||
CurInfo->CursorClipInfo.Bottom = min(Rect.bottom - 1, DesktopWindow->Wnd->rcWindow.bottom - 1);
|
||||
CurInfo->CursorClipInfo.Right = min(Rect.right, DesktopWindow->Wnd->rcWindow.right);
|
||||
CurInfo->CursorClipInfo.Bottom = min(Rect.bottom, DesktopWindow->Wnd->rcWindow.bottom);
|
||||
|
||||
mi.dx = gpsi->ptCursor.x;
|
||||
mi.dy = gpsi->ptCursor.y;
|
||||
mi.mouseData = 0;
|
||||
mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
|
||||
mi.time = 0;
|
||||
mi.dwExtraInfo = 0;
|
||||
IntMouseInput(&mi);
|
||||
UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y);
|
||||
|
||||
RETURN(TRUE);
|
||||
}
|
||||
|
@ -1507,89 +1595,3 @@ NtUserDrawIconEx(
|
|||
return Ret;
|
||||
}
|
||||
|
||||
/* Called from NtUserCallOneParam with Routine ONEPARAM_ROUTINE_SHOWCURSOR
|
||||
* User32 macro NtUserShowCursor */
|
||||
int
|
||||
APIENTRY
|
||||
UserShowCursor(BOOL bShow)
|
||||
{
|
||||
PSYSTEM_CURSORINFO CurInfo;
|
||||
HDC Screen;
|
||||
PDC dc;
|
||||
SURFOBJ *SurfObj;
|
||||
SURFACE *psurfDc;
|
||||
PDEVOBJ *ppdev;
|
||||
GDIPOINTER *pgp;
|
||||
int showpointer=0;
|
||||
|
||||
CurInfo = IntGetSysCursorInfo();
|
||||
|
||||
if (!(Screen = IntGetScreenDC()))
|
||||
{
|
||||
return showpointer; /* No mouse */
|
||||
}
|
||||
|
||||
dc = DC_LockDc(Screen);
|
||||
|
||||
if (!dc)
|
||||
{
|
||||
return showpointer; /* No mouse */
|
||||
}
|
||||
|
||||
psurfDc = dc->dclevel.pSurface;
|
||||
|
||||
if (!psurfDc)
|
||||
{
|
||||
DC_UnlockDc(dc);
|
||||
return showpointer; /* No Mouse */
|
||||
}
|
||||
|
||||
SurfObj = &psurfDc->SurfObj;
|
||||
if (SurfObj == NULL)
|
||||
{
|
||||
DC_UnlockDc(dc);
|
||||
return showpointer; /* No mouse */
|
||||
}
|
||||
|
||||
ppdev = GDIDEV(SurfObj);
|
||||
|
||||
if (ppdev == NULL)
|
||||
{
|
||||
DC_UnlockDc(dc);
|
||||
return showpointer; /* No mouse */
|
||||
}
|
||||
|
||||
pgp = &ppdev->Pointer;
|
||||
|
||||
if (bShow == FALSE)
|
||||
{
|
||||
pgp->ShowPointer--;
|
||||
showpointer = pgp->ShowPointer;
|
||||
|
||||
if (showpointer >= 0)
|
||||
{
|
||||
//ppdev->SafetyRemoveCount = 1;
|
||||
//ppdev->SafetyRemoveLevel = 1;
|
||||
IntEngMovePointer(SurfObj,-1,-1,NULL);
|
||||
CurInfo->ShowingCursor = 0;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
pgp->ShowPointer++;
|
||||
showpointer = pgp->ShowPointer;
|
||||
|
||||
/* Show Cursor */
|
||||
if (showpointer < 0)
|
||||
{
|
||||
//ppdev->SafetyRemoveCount = 0;
|
||||
//ppdev->SafetyRemoveLevel = 0;
|
||||
IntEngMovePointer(SurfObj,-1,-1,NULL);
|
||||
CurInfo->ShowingCursor = CURSOR_SHOWING;
|
||||
}
|
||||
}
|
||||
|
||||
DC_UnlockDc(dc);
|
||||
return showpointer;
|
||||
}
|
||||
|
|
|
@ -120,10 +120,8 @@ ProcessMouseInputData(PMOUSE_INPUT_DATA Data, ULONG InputCount)
|
|||
/* 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)
|
||||
|
@ -1052,48 +1050,19 @@ IntMouseInput(MOUSEINPUT *mi)
|
|||
{
|
||||
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();
|
||||
|
||||
|
@ -1105,84 +1074,26 @@ IntMouseInput(MOUSEINPUT *mi)
|
|||
}
|
||||
|
||||
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.lParam = MAKELPARAM(MousePos.x, MousePos.y);
|
||||
Msg.pt = MousePos;
|
||||
|
@ -1197,13 +1108,10 @@ IntMouseInput(MOUSEINPUT *mi)
|
|||
Msg.wParam |= MK_CONTROL;
|
||||
}
|
||||
|
||||
if(DoMove)
|
||||
if(mi->dwFlags & MOUSEEVENTF_MOVE)
|
||||
{
|
||||
Msg.message = WM_MOUSEMOVE;
|
||||
MsqInsertSystemMessage(&Msg);
|
||||
UserSetCursorPos(MousePos.x, MousePos.y);
|
||||
}
|
||||
|
||||
Msg.message = 0;
|
||||
if(mi->dwFlags & MOUSEEVENTF_LEFTDOWN)
|
||||
{
|
||||
gQueueKeyStateTable[VK_LBUTTON] |= 0xc0;
|
||||
|
|
|
@ -438,6 +438,10 @@ NtUserCallTwoParam(
|
|||
|
||||
case TWOPARAM_ROUTINE_REGISTERLOGONPROC:
|
||||
RETURN( (DWORD_PTR)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2));
|
||||
|
||||
case TWOPARAM_ROUTINE_SETCURSORPOS:
|
||||
RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2));
|
||||
|
||||
}
|
||||
DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
|
||||
Routine, Param1, Param2);
|
||||
|
|
Loading…
Reference in a new issue