- 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:
Giannis Adamopoulos 2010-01-06 12:44:31 +00:00
parent 15269e4b77
commit b8882998c7
8 changed files with 123 additions and 227 deletions

View file

@ -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)

View file

@ -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);
}

View file

@ -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

View file

@ -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();

View file

@ -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 */

View file

@ -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;
}

View file

@ -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;

View file

@ -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);