mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
This patch removes the cursor location from the window station object and always uses it in the GDIDEVICE. Patch by tinus. Fixes bug #484
svn path=/trunk/; revision=13333
This commit is contained in:
parent
f99bb4b97d
commit
a84129a69e
8 changed files with 100 additions and 61 deletions
|
@ -124,9 +124,6 @@ typedef struct _GDIPOINTER /* should stay private to ENG */
|
|||
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 @@ typedef struct
|
|||
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 */
|
||||
|
|
|
@ -68,9 +68,9 @@ MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1,
|
|||
tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp;
|
||||
}
|
||||
|
||||
pgp->SafetyRemoveCount++;
|
||||
ppdev->SafetyRemoveCount++;
|
||||
|
||||
if (pgp->SafetyRemoveLevel)
|
||||
if (ppdev->SafetyRemoveLevel)
|
||||
{
|
||||
/* already hidden */
|
||||
return FALSE;
|
||||
|
@ -81,7 +81,7 @@ MouseSafetyOnDrawStart(SURFOBJ *SurfObj, LONG HazardX1,
|
|||
&& 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 @@ MouseSafetyOnDrawEnd(SURFOBJ *SurfObj)
|
|||
GDIDEVICE *ppdev;
|
||||
GDIPOINTER *pgp;
|
||||
|
||||
ASSERT(WinSta);
|
||||
|
||||
ASSERT(SurfObj != NULL);
|
||||
|
||||
ppdev = GDIDEV(SurfObj);
|
||||
|
@ -117,22 +119,16 @@ MouseSafetyOnDrawEnd(SURFOBJ *SurfObj)
|
|||
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 @@ EngSetPointerShape(
|
|||
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 @@ EngSetPointerShape(
|
|||
|
||||
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 @@ EngMovePointer(
|
|||
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 */
|
||||
|
|
|
@ -37,7 +37,6 @@ typedef struct _SYSTEM_CURSORINFO
|
|||
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 IntGetCurIconObject(PWINSTATION_OBJECT WinStaObject, HA
|
|||
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)
|
||||
|
||||
|
|
|
@ -42,6 +42,40 @@ static PAGED_LOOKASIDE_LIST ProcessLookasideList;
|
|||
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 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor,
|
|||
{
|
||||
/* 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 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor,
|
|||
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 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor,
|
|||
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 @@ NtUserGetCursorInfo(
|
|||
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 @@ NtUserGetCursorInfo(
|
|||
|
||||
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 @@ NtUserClipCursor(
|
|||
PSYSTEM_CURSORINFO CurInfo;
|
||||
RECT Rect;
|
||||
PWINDOW_OBJECT DesktopWindow = NULL;
|
||||
POINT MousePos;
|
||||
|
||||
WinStaObject = IntGetWinStaObj();
|
||||
if (WinStaObject == NULL)
|
||||
|
@ -830,6 +874,8 @@ NtUserClipCursor(
|
|||
}
|
||||
|
||||
CurInfo = IntGetSysCursorInfo(WinStaObject);
|
||||
IntGetCursorLocation(WinStaObject, &MousePos);
|
||||
|
||||
if(WinStaObject->ActiveDesktop)
|
||||
DesktopWindow = IntGetWindowObject(WinStaObject->ActiveDesktop->DesktopWindow);
|
||||
|
||||
|
@ -845,8 +891,8 @@ NtUserClipCursor(
|
|||
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;
|
||||
|
|
|
@ -540,7 +540,7 @@ IntMouseInput(MOUSEINPUT *mi)
|
|||
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 @@ IntMouseInput(MOUSEINPUT *mi)
|
|||
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 @@ IntMouseInput(MOUSEINPUT *mi)
|
|||
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 @@ IntMouseInput(MOUSEINPUT *mi)
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -1123,7 +1123,6 @@ NtUserPostMessage(HWND Wnd,
|
|||
}
|
||||
else
|
||||
{
|
||||
PSYSTEM_CURSORINFO CurInfo;
|
||||
Window = IntGetWindowObject(Wnd);
|
||||
if (NULL == Window)
|
||||
{
|
||||
|
@ -1149,9 +1148,8 @@ NtUserPostMessage(HWND Wnd,
|
|||
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,
|
||||
|
|
|
@ -263,7 +263,6 @@ NtUserCallOneParam(
|
|||
|
||||
case ONEPARAM_ROUTINE_GETCURSORPOSITION:
|
||||
{
|
||||
PSYSTEM_CURSORINFO CurInfo;
|
||||
PWINSTATION_OBJECT WinStaObject;
|
||||
NTSTATUS Status;
|
||||
POINT Pos;
|
||||
|
@ -277,10 +276,8 @@ NtUserCallOneParam(
|
|||
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))
|
||||
|
|
|
@ -389,8 +389,6 @@ NtUserCreateWindowStation(
|
|||
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;
|
||||
|
|
Loading…
Reference in a new issue