This patch removes the cursor location from the window station object
and always uses it in the GDIDEVICE. Patch by tinus. Fixes bug #484
Modified: trunk/reactos/include/win32k/dc.h
Modified: trunk/reactos/subsys/win32k/eng/mouse.c
Modified: trunk/reactos/subsys/win32k/include/cursoricon.h
Modified: trunk/reactos/subsys/win32k/ntuser/cursoricon.c
Modified: trunk/reactos/subsys/win32k/ntuser/input.c
Modified: trunk/reactos/subsys/win32k/ntuser/message.c
Modified: trunk/reactos/subsys/win32k/ntuser/misc.c
Modified: trunk/reactos/subsys/win32k/ntuser/winsta.c
_____
Modified: trunk/reactos/include/win32k/dc.h
--- trunk/reactos/include/win32k/dc.h 2005-01-27 00:33:11 UTC (rev
13332)
+++ trunk/reactos/include/win32k/dc.h 2005-01-27 00:49:24 UTC (rev
13333)
@@ -124,9 +124,6 @@
RECTL Exclude; /* required publicly for SPS_ACCEPT_EXCLUDE */
PGD_MOVEPOINTER MovePointer;
ULONG Status;
- UINT SafetyRemoveLevel; /* at what level was the cursor removed?
- 0 for not removed */
- UINT SafetyRemoveCount;
} GDIPOINTER, *PGDIPOINTER;
typedef struct
@@ -141,6 +138,11 @@
PFILE_OBJECT VideoFileObject;
GDIPOINTER Pointer;
+
+ /* Stuff to keep track of software cursors; win32k gdi part */
+ UINT SafetyRemoveLevel; /* at what level was the cursor removed?
+ 0 for not removed */
+ UINT SafetyRemoveCount;
} GDIDEVICE;
/* Internal functions */
_____
Modified: trunk/reactos/subsys/win32k/eng/mouse.c
--- trunk/reactos/subsys/win32k/eng/mouse.c 2005-01-27 00:33:11 UTC
(rev 13332)
+++ trunk/reactos/subsys/win32k/eng/mouse.c 2005-01-27 00:49:24 UTC
(rev 13333)
@@ -68,9 +68,9 @@
tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp;
}
- pgp->SafetyRemoveCount++;
+ ppdev->SafetyRemoveCount++;
- if (pgp->SafetyRemoveLevel)
+ if (ppdev->SafetyRemoveLevel)
{
/* already hidden */
return FALSE;
@@ -81,7 +81,7 @@
&& pgp->Exclude.bottom >= HazardY1
&& pgp->Exclude.top <= HazardY2)
{
- pgp->SafetyRemoveLevel = pgp->SafetyRemoveCount;
+ ppdev->SafetyRemoveLevel = ppdev->SafetyRemoveCount;
if (pgp->MovePointer)
pgp->MovePointer(SurfObj, -1, -1, NULL);
else
@@ -100,6 +100,8 @@
GDIDEVICE *ppdev;
GDIPOINTER *pgp;
+ ASSERT(WinSta);
+
ASSERT(SurfObj != NULL);
ppdev = GDIDEV(SurfObj);
@@ -117,22 +119,16 @@
return FALSE;
}
- if (--pgp->SafetyRemoveCount >= pgp->SafetyRemoveLevel)
+ if (--ppdev->SafetyRemoveCount >= ppdev->SafetyRemoveLevel)
{
return FALSE;
}
- /* FIXME - this is wrong!!!!!! we must NOT access pgp->Pos from
here, it's
- a private field for ENG/driver. This will paint the cursor
to the
- wrong screen coordinates when a driver overrides
DrvMovePointer()!
- We should store the coordinates before calling
Drv/EngMovePointer()
- and Drv/EngSetPointerShape() separately in the GDIDEVICE
structure
- or somewhere where ntuser can access it! */
if (pgp->MovePointer)
pgp->MovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, &pgp->Exclude);
else
EngMovePointer(SurfObj, pgp->Pos.x, pgp->Pos.y, &pgp->Exclude);
- pgp->SafetyRemoveLevel = 0;
+ ppdev->SafetyRemoveLevel = 0;
return(TRUE);
}
@@ -368,6 +364,8 @@
pgp->HotSpot.x = xHot;
pgp->HotSpot.y = yHot;
+ /* Actually this should be set by 'the other side', but it would be
+ * done right after this. It helps IntShowMousePointer. */
if (x != -1)
{
pgp->Pos.x = x;
@@ -472,14 +470,13 @@
if (prcl != NULL)
{
- prcl->left = pgp->Pos.x - pgp->HotSpot.x;
- prcl->top = pgp->Pos.y - pgp->HotSpot.x;
+ prcl->left = x - pgp->HotSpot.x;
+ prcl->top = y - pgp->HotSpot.x;
prcl->right = prcl->left + pgp->Size.cx;
prcl->bottom = prcl->top + pgp->Size.cy;
}
- }
-
- /* FIXME - touch prcl when x == -1? */
+ } else if (prcl != NULL)
+ prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
return SPS_ACCEPT_EXCLUDE;
}
@@ -509,19 +506,21 @@
IntHideMousePointer(ppdev, pso);
if (x != -1)
{
+ /* Actually this should be set by 'the other side', but it would
be
+ * done right after this. It helps IntShowMousePointer. */
pgp->Pos.x = x;
pgp->Pos.y = y;
IntShowMousePointer(ppdev, pso);
if (prcl != NULL)
{
- prcl->left = pgp->Pos.x - pgp->HotSpot.x;
- prcl->top = pgp->Pos.y - pgp->HotSpot.x;
+ prcl->left = x - pgp->HotSpot.x;
+ prcl->top = y - pgp->HotSpot.x;
prcl->right = prcl->left + pgp->Size.cx;
prcl->bottom = prcl->top + pgp->Size.cy;
}
- }
+ } else if (prcl != NULL)
+ prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
- /* FIXME - touch prcl when x == -1? */
}
/* EOF */
_____
Modified: trunk/reactos/subsys/win32k/include/cursoricon.h
--- trunk/reactos/subsys/win32k/include/cursoricon.h 2005-01-27
00:33:11 UTC (rev 13332)
+++ trunk/reactos/subsys/win32k/include/cursoricon.h 2005-01-27
00:49:24 UTC (rev 13333)
@@ -37,7 +37,6 @@
BOOL Enabled;
BOOL SwapButtons;
UINT ButtonsDown;
- LONG x, y;
FAST_MUTEX CursorMutex;
CURSORCLIP_INFO CursorClipInfo;
PCURICON_OBJECT CurrentCursorObject;
@@ -57,6 +56,8 @@
PCURICON_OBJECT FASTCALL IntCreateCurIconHandle(PWINSTATION_OBJECT
WinStaObject);
VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS
Win32Process);
+BOOL FASTCALL IntGetCursorLocation(PWINSTATION_OBJECT WinStaObject,
POINT *loc);
+
#define IntGetSysCursorInfo(WinStaObj) \
(PSYSTEM_CURSORINFO)((WinStaObj)->SystemCursor)
_____
Modified: trunk/reactos/subsys/win32k/ntuser/cursoricon.c
--- trunk/reactos/subsys/win32k/ntuser/cursoricon.c 2005-01-27
00:33:11 UTC (rev 13332)
+++ trunk/reactos/subsys/win32k/ntuser/cursoricon.c 2005-01-27
00:49:24 UTC (rev 13333)
@@ -42,6 +42,40 @@
static LIST_ENTRY CurIconList;
static FAST_MUTEX CurIconListLock;
+/* Look up the location of the cursor in the GDIDEVICE structure
+ * when all we know is the window station object
+ * Actually doesn't use the window station, but should... */
+BOOL FASTCALL
+IntGetCursorLocation(PWINSTATION_OBJECT WinStaObject, POINT *loc)
+{
+ HDC hDC;
+ PDC dc;
+ HBITMAP hBitmap;
+ BITMAPOBJ *BitmapObj;
+ SURFOBJ *SurfObj;
+
+#if 1
+ /* FIXME - get the screen dc from the window station or desktop */
+ if (!(hDC = IntGetScreenDC()))
+ return FALSE;
+#endif
+
+ if (!(dc = DC_LockDc(hDC)))
+ return FALSE;
+
+ hBitmap = dc->w.hBitmap;
+ DC_UnlockDc(hDC);
+ if (!(BitmapObj = BITMAPOBJ_LockBitmap(hBitmap)))
+ return FALSE;
+
+ SurfObj = &BitmapObj->SurfObj;
+ loc->x = GDIDEV(SurfObj)->Pointer.Pos.x;
+ loc->y = GDIDEV(SurfObj)->Pointer.Pos.y;
+
+ BITMAPOBJ_UnlockBitmap(hBitmap);
+ return TRUE;
+}
+
PCURICON_OBJECT FASTCALL
IntGetCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle)
{
@@ -116,10 +150,9 @@
{
/* Remove the cursor if it was displayed */
if (GDIDEV(SurfObj)->Pointer.MovePointer)
- GDIDEV(SurfObj)->Pointer.MovePointer(SurfObj, -1, -1, NULL);
+ GDIDEV(SurfObj)->Pointer.MovePointer(SurfObj, -1, -1,
&GDIDEV(SurfObj)->Pointer.Exclude);
else
- EngMovePointer(SurfObj, -1, -1, NULL);
- GDIDEV(SurfObj)->Pointer.Exclude.right = -1;
+ EngMovePointer(SurfObj, -1, -1,
&GDIDEV(SurfObj)->Pointer.Exclude);
}
GDIDEV(SurfObj)->Pointer.Status = SPS_ACCEPT_NOEXCLUDE;
@@ -218,8 +251,8 @@
SurfObj,
soMask, soColor, XlateObj,
NewCursor->IconInfo.xHotspot,
NewCursor->IconInfo.yHotspot,
- CurInfo->x,
- CurInfo->y,
+
GDIDEV(SurfObj)->Pointer.Pos.x,
+
GDIDEV(SurfObj)->Pointer.Pos.y,
&(GDIDEV(SurfObj)->Pointer.Exclude),
SPS_CHANGE);
DPRINT("SetCursor: DrvSetPointerShape() returned %x\n",
@@ -236,8 +269,8 @@
SurfObj, soMask, soColor, XlateObj,
NewCursor->IconInfo.xHotspot,
NewCursor->IconInfo.yHotspot,
- CurInfo->x,
- CurInfo->y,
+ GDIDEV(SurfObj)->Pointer.Pos.x,
+ GDIDEV(SurfObj)->Pointer.Pos.y,
&(GDIDEV(SurfObj)->Pointer.Exclude),
SPS_CHANGE);
GDIDEV(SurfObj)->Pointer.MovePointer = EngMovePointer;
@@ -760,6 +793,16 @@
PWINSTATION_OBJECT WinStaObject;
NTSTATUS Status;
PCURICON_OBJECT CursorObject;
+
+#if 1
+ HDC hDC;
+
+ /* FIXME - get the screen dc from the window station or desktop */
+ if (!(hDC = IntGetScreenDC()))
+ {
+ return FALSE;
+ }
+#endif
Status = MmCopyFromCaller(&SafeCi.cbSize, pci, sizeof(DWORD));
if(!NT_SUCCESS(Status))
@@ -785,9 +828,9 @@
SafeCi.flags = ((CurInfo->ShowingCursor && CursorObject) ?
CURSOR_SHOWING : 0);
SafeCi.hCursor = (CursorObject ? (HCURSOR)CursorObject->Self :
(HCURSOR)0);
- SafeCi.ptScreenPos.x = CurInfo->x;
- SafeCi.ptScreenPos.y = CurInfo->y;
-
+
+ IntGetCursorLocation(WinStaObject, &SafeCi.ptScreenPos);
+
Status = MmCopyToCaller(pci, &SafeCi, sizeof(CURSORINFO));
if(!NT_SUCCESS(Status))
{
@@ -815,6 +858,7 @@
PSYSTEM_CURSORINFO CurInfo;
RECT Rect;
PWINDOW_OBJECT DesktopWindow = NULL;
+ POINT MousePos;
WinStaObject = IntGetWinStaObj();
if (WinStaObject == NULL)
@@ -830,6 +874,8 @@
}
CurInfo = IntGetSysCursorInfo(WinStaObject);
+ IntGetCursorLocation(WinStaObject, &MousePos);
+
if(WinStaObject->ActiveDesktop)
DesktopWindow =
IntGetWindowObject(WinStaObject->ActiveDesktop->DesktopWindow);
@@ -845,8 +891,8 @@
CurInfo->CursorClipInfo.Bottom = min(Rect.bottom - 1,
DesktopWindow->WindowRect.bottom - 1);
IntReleaseWindowObject(DesktopWindow);
- mi.dx = CurInfo->x;
- mi.dy = CurInfo->y;
+ mi.dx = MousePos.x;
+ mi.dy = MousePos.y;
mi.mouseData = 0;
mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
mi.time = 0;
_____
Modified: trunk/reactos/subsys/win32k/ntuser/input.c
--- trunk/reactos/subsys/win32k/ntuser/input.c 2005-01-27 00:33:11 UTC
(rev 13332)
+++ trunk/reactos/subsys/win32k/ntuser/input.c 2005-01-27 00:49:24 UTC
(rev 13333)
@@ -540,7 +540,7 @@
const UINT SwapBtnMsg[2][2] = {{WM_LBUTTONDOWN, WM_RBUTTONDOWN},
{WM_LBUTTONUP, WM_RBUTTONUP}};
const WPARAM SwapBtn[2] = {MK_LBUTTON, MK_RBUTTON};
- POINT MousePos;
+ POINT MousePos, OrgPos;
PSYSTEM_CURSORINFO CurInfo;
PWINSTATION_OBJECT WinSta;
BOOL DoMove, SwapButtons;
@@ -586,8 +586,10 @@
DoMove = FALSE;
ExAcquireFastMutex(&CurInfo->CursorMutex);
- MousePos.x = CurInfo->x;
- MousePos.y = CurInfo->y;
+ IntGetCursorLocation(WinSta, &MousePos);
+ OrgPos.x = MousePos.x;
+ OrgPos.y = MousePos.y;
+
if(mi->dwFlags & MOUSEEVENTF_MOVE)
{
if(mi->dwFlags & MOUSEEVENTF_ABSOLUTE)
@@ -631,12 +633,7 @@
MousePos.y = (LONG)CurInfo->CursorClipInfo.Top;
}
- DoMove = (MousePos.x != CurInfo->x || MousePos.y != CurInfo->y);
- if(DoMove)
- {
- CurInfo->x = MousePos.x;
- CurInfo->y = MousePos.y;
- }
+ DoMove = (MousePos.x != OrgPos.x || MousePos.y != OrgPos.y);
}
ExReleaseFastMutex(&CurInfo->CursorMutex);
@@ -657,12 +654,13 @@
if (GDIDEV(SurfObj)->Pointer.MovePointer)
{
GDIDEV(SurfObj)->Pointer.MovePointer(SurfObj, MousePos.x,
MousePos.y, &(GDIDEV(SurfObj)->Pointer.Exclude));
- }
- /* FIXME - That's a bad thing! We should't access private gdi
pointer fields
- from here. However it is required so
MouseSafetyOnDrawEnd() can
- properly paint the mouse cursor to the screen again.
See the
- comment in MouseSafetyOnDrawEnd() to fix this
problem! */
- GDIDEV(SurfObj)->Pointer.Pos = MousePos;
+ } else {
+ EngMovePointer(SurfObj, MousePos.x, MousePos.y,
&(GDIDEV(SurfObj)->Pointer.Exclude));
+ }
+ /* Only now, update the info in the GDIDEVICE, so
EngMovePointer can
+ * use the old values to move the pointer image */
+ GDIDEV(SurfObj)->Pointer.Pos.x = MousePos.x;
+ GDIDEV(SurfObj)->Pointer.Pos.y = MousePos.y;
BITMAPOBJ_UnlockBitmap(hBitmap);
}
_____
Modified: trunk/reactos/subsys/win32k/ntuser/message.c
--- trunk/reactos/subsys/win32k/ntuser/message.c 2005-01-27
00:33:11 UTC (rev 13332)
+++ trunk/reactos/subsys/win32k/ntuser/message.c 2005-01-27
00:49:24 UTC (rev 13333)
@@ -1123,7 +1123,6 @@
}
else
{
- PSYSTEM_CURSORINFO CurInfo;
Window = IntGetWindowObject(Wnd);
if (NULL == Window)
{
@@ -1149,9 +1148,8 @@
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
- CurInfo =
IntGetSysCursorInfo(PsGetWin32Thread()->Desktop->WindowStation);
- KernelModeMsg.pt.x = CurInfo->x;
- KernelModeMsg.pt.y = CurInfo->y;
+ IntGetCursorLocation(PsGetWin32Thread()->Desktop->WindowStation,
+ &KernelModeMsg.pt);
KeQueryTickCount(&LargeTickCount);
KernelModeMsg.time = LargeTickCount.u.LowPart;
MsqPostMessage(Window->MessageQueue, &KernelModeMsg,
_____
Modified: trunk/reactos/subsys/win32k/ntuser/misc.c
--- trunk/reactos/subsys/win32k/ntuser/misc.c 2005-01-27 00:33:11 UTC
(rev 13332)
+++ trunk/reactos/subsys/win32k/ntuser/misc.c 2005-01-27 00:49:24 UTC
(rev 13333)
@@ -263,7 +263,6 @@
case ONEPARAM_ROUTINE_GETCURSORPOSITION:
{
- PSYSTEM_CURSORINFO CurInfo;
PWINSTATION_OBJECT WinStaObject;
NTSTATUS Status;
POINT Pos;
@@ -277,10 +276,8 @@
if (!NT_SUCCESS(Status))
return (DWORD)FALSE;
- CurInfo = IntGetSysCursorInfo(WinStaObject);
/* FIXME - check if process has WINSTA_READATTRIBUTES */
- Pos.x = CurInfo->x;
- Pos.y = CurInfo->y;
+ IntGetCursorLocation(WinStaObject, &Pos);
Status = MmCopyToCaller((PPOINT)Param, &Pos, sizeof(POINT));
if(!NT_SUCCESS(Status))
_____
Modified: trunk/reactos/subsys/win32k/ntuser/winsta.c
--- trunk/reactos/subsys/win32k/ntuser/winsta.c 2005-01-27 00:33:11 UTC
(rev 13332)
+++ trunk/reactos/subsys/win32k/ntuser/winsta.c 2005-01-27 00:49:24 UTC
(rev 13333)
@@ -389,8 +389,6 @@
ExInitializeFastMutex(&CurInfo->CursorMutex);
CurInfo->Enabled = FALSE;
CurInfo->ButtonsDown = 0;
- CurInfo->x = (LONG)0;
- CurInfo->y = (LONG)0;
CurInfo->CursorClipInfo.IsClipped = FALSE;
CurInfo->LastBtnDown = 0;
CurInfo->CurrentCursorObject = NULL;