Mouse pointer fix:

- Remove useless Status from the GDIPOINTER struct
- Remove MovePointer and use PDEVOBJ.pfnMovePointer instead, which is always set to a valid function.
- Implement IntEngSetPointerShape, calling either the Eng or the Drv function if available, set pfnMovePointer according to the result.
- Use IntEngSetPointerShape instead of doing the atuff in IntSetCursor.
- Don't misuse gpsi->ptCursor in IntShow/HideMousePointer and EngMovePointer, use ppdev->ptlPointer instead.
- Dont Lock and unlock the surface evertime the pointer is drwn, instead keep a shared lock.
- Implement IntEngCopyBits, that does the MouseSafety stuff and calls EngCopyBits.
Fixes the broken mouse cursor with VBox display driver and improves mouse performance

svn path=/trunk/; revision=40409
This commit is contained in:
Timo Kreuzer 2009-04-07 01:36:22 +00:00
parent 1862a76af4
commit fe1ed19dca
7 changed files with 349 additions and 299 deletions

View file

@ -54,9 +54,6 @@ EngCopyBits(SURFOBJ *psoDest,
psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj); psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj);
SURFACE_LockBitmapBits(psurfSource); SURFACE_LockBitmapBits(psurfSource);
MouseSafetyOnDrawStart(psoSource, SourcePoint->x, SourcePoint->y,
(SourcePoint->x + abs(DestRect->right - DestRect->left)),
(SourcePoint->y + abs(DestRect->bottom - DestRect->top)));
psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj);
if (psoDest != psoSource) if (psoDest != psoSource)
@ -64,8 +61,6 @@ EngCopyBits(SURFOBJ *psoDest,
SURFACE_LockBitmapBits(psurfDest); SURFACE_LockBitmapBits(psurfDest);
} }
MouseSafetyOnDrawStart(psoDest, DestRect->left, DestRect->top, DestRect->right, DestRect->bottom);
// FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead, // FIXME: Don't punt to the driver's DrvCopyBits immediately. Instead,
// mark the copy block function to be DrvCopyBits instead of the // mark the copy block function to be DrvCopyBits instead of the
// GDI's copy bit function so as to remove clipping from the // GDI's copy bit function so as to remove clipping from the
@ -83,12 +78,10 @@ EngCopyBits(SURFOBJ *psoDest,
ret = GDIDEVFUNCS(psoDest).CopyBits( ret = GDIDEVFUNCS(psoDest).CopyBits(
psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint); psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint);
MouseSafetyOnDrawEnd(psoDest);
if (psoDest != psoSource) if (psoDest != psoSource)
{ {
SURFACE_UnlockBitmapBits(psurfDest); SURFACE_UnlockBitmapBits(psurfDest);
} }
MouseSafetyOnDrawEnd(psoSource);
SURFACE_UnlockBitmapBits(psurfSource); SURFACE_UnlockBitmapBits(psurfSource);
return ret; return ret;
@ -104,12 +97,10 @@ EngCopyBits(SURFOBJ *psoDest,
ret = GDIDEVFUNCS(psoSource).CopyBits( ret = GDIDEVFUNCS(psoSource).CopyBits(
psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint); psoDest, psoSource, Clip, ColorTranslation, DestRect, SourcePoint);
MouseSafetyOnDrawEnd(psoDest);
if (psoDest != psoSource) if (psoDest != psoSource)
{ {
SURFACE_UnlockBitmapBits(psurfDest); SURFACE_UnlockBitmapBits(psurfDest);
} }
MouseSafetyOnDrawEnd(psoSource);
SURFACE_UnlockBitmapBits(psurfSource); SURFACE_UnlockBitmapBits(psurfSource);
return ret; return ret;
@ -121,12 +112,10 @@ EngCopyBits(SURFOBJ *psoDest,
NULL, Clip, ColorTranslation, DestRect, SourcePoint, NULL, Clip, ColorTranslation, DestRect, SourcePoint,
NULL, NULL, NULL, ROP3_TO_ROP4(SRCCOPY)); NULL, NULL, NULL, ROP3_TO_ROP4(SRCCOPY));
MouseSafetyOnDrawEnd(psoDest);
if (psoDest != psoSource) if (psoDest != psoSource)
{ {
SURFACE_UnlockBitmapBits(psurfDest); SURFACE_UnlockBitmapBits(psurfDest);
} }
MouseSafetyOnDrawEnd(psoSource);
SURFACE_UnlockBitmapBits(psurfSource); SURFACE_UnlockBitmapBits(psurfSource);
return ret; return ret;
@ -160,7 +149,6 @@ EngCopyBits(SURFOBJ *psoDest,
{ {
SURFACE_UnlockBitmapBits(psurfDest); SURFACE_UnlockBitmapBits(psurfDest);
} }
MouseSafetyOnDrawEnd(psoSource);
SURFACE_UnlockBitmapBits(psurfSource); SURFACE_UnlockBitmapBits(psurfSource);
return(TRUE); return(TRUE);
@ -174,12 +162,10 @@ EngCopyBits(SURFOBJ *psoDest,
DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo); DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_BitBltSrcCopy(&BltInfo);
MouseSafetyOnDrawEnd(psoDest);
if (psoDest != psoSource) if (psoDest != psoSource)
{ {
SURFACE_UnlockBitmapBits(psurfDest); SURFACE_UnlockBitmapBits(psurfDest);
} }
MouseSafetyOnDrawEnd(psoSource);
SURFACE_UnlockBitmapBits(psurfSource); SURFACE_UnlockBitmapBits(psurfSource);
return(TRUE); return(TRUE);
@ -212,26 +198,48 @@ EngCopyBits(SURFOBJ *psoDest,
} while(EnumMore); } while(EnumMore);
MouseSafetyOnDrawEnd(psoDest);
if (psoDest != psoSource) if (psoDest != psoSource)
{ {
SURFACE_UnlockBitmapBits(psurfDest); SURFACE_UnlockBitmapBits(psurfDest);
} }
MouseSafetyOnDrawEnd(psoSource);
SURFACE_UnlockBitmapBits(psurfSource); SURFACE_UnlockBitmapBits(psurfSource);
return(TRUE); return(TRUE);
} }
MouseSafetyOnDrawEnd(psoDest);
if (psoDest != psoSource) if (psoDest != psoSource)
{ {
SURFACE_UnlockBitmapBits(psurfDest); SURFACE_UnlockBitmapBits(psurfDest);
} }
MouseSafetyOnDrawEnd(psoSource);
SURFACE_UnlockBitmapBits(psurfSource); SURFACE_UnlockBitmapBits(psurfSource);
return FALSE; return FALSE;
} }
BOOL APIENTRY
IntEngCopyBits(
SURFOBJ *psoDest,
SURFOBJ *psoSource,
CLIPOBJ *pco,
XLATEOBJ *pxlo,
RECTL *prclDest,
POINTL *ptlSource)
{
BOOL bResult;
MouseSafetyOnDrawStart(psoSource, ptlSource->x, ptlSource->y,
(ptlSource->x + abs(prclDest->right - prclDest->left)),
(ptlSource->y + abs(prclDest->bottom - prclDest->top)));
MouseSafetyOnDrawStart(psoDest, prclDest->left, prclDest->top, prclDest->right, prclDest->bottom);
bResult = EngCopyBits(psoDest, psoSource, pco, pxlo, prclDest, ptlSource);
MouseSafetyOnDrawEnd(psoDest);
MouseSafetyOnDrawEnd(psoSource);
return bResult;
}
/* EOF */ /* EOF */

View file

@ -3,6 +3,7 @@
* PURPOSE: Mouse pointer functions * PURPOSE: Mouse pointer functions
* FILE: subsystems/win32k/eng/mouse.c * FILE: subsystems/win32k/eng/mouse.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net) * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* Timo Kreuzer (timo.kreuzer@reactos.org)
* REVISION HISTORY: * REVISION HISTORY:
* 06-06-2001 CSH Created * 06-06-2001 CSH Created
*/ */
@ -21,7 +22,7 @@
*/ */
INT INTERNAL_CALL INT INTERNAL_CALL
MouseSafetyOnDrawStart( MouseSafetyOnDrawStart(
SURFOBJ *SurfObj, SURFOBJ *pso,
LONG HazardX1, LONG HazardX1,
LONG HazardY1, LONG HazardY1,
LONG HazardX2, LONG HazardX2,
@ -31,20 +32,26 @@ MouseSafetyOnDrawStart(
PDEVOBJ *ppdev; PDEVOBJ *ppdev;
GDIPOINTER *pgp; GDIPOINTER *pgp;
ASSERT(SurfObj != NULL); ASSERT(pso != NULL);
ppdev = GDIDEV(SurfObj); ppdev = GDIDEV(pso);
if (ppdev == NULL) if (ppdev == NULL)
{ {
return(FALSE); return FALSE;
} }
pgp = &ppdev->Pointer; pgp = &ppdev->Pointer;
if (SPS_ACCEPT_NOEXCLUDE == pgp->Status || if (pgp->Exclude.right == -1)
pgp->Exclude.right == -1)
{ {
return(FALSE); return FALSE;
}
ppdev->SafetyRemoveCount++;
if (ppdev->SafetyRemoveLevel != 0)
{
return FALSE;
} }
if (HazardX1 > HazardX2) if (HazardX1 > HazardX2)
@ -60,24 +67,13 @@ MouseSafetyOnDrawStart(
HazardY1 = tmp; HazardY1 = tmp;
} }
if (ppdev->SafetyRemoveLevel != 0)
{
ppdev->SafetyRemoveCount++;
return FALSE;
}
ppdev->SafetyRemoveCount++;
if (pgp->Exclude.right >= HazardX1 if (pgp->Exclude.right >= HazardX1
&& pgp->Exclude.left <= HazardX2 && pgp->Exclude.left <= HazardX2
&& pgp->Exclude.bottom >= HazardY1 && pgp->Exclude.bottom >= HazardY1
&& pgp->Exclude.top <= HazardY2) && pgp->Exclude.top <= HazardY2)
{ {
ppdev->SafetyRemoveLevel = ppdev->SafetyRemoveCount; ppdev->SafetyRemoveLevel = ppdev->SafetyRemoveCount;
if (pgp->MovePointer) ppdev->pfnMovePointer(pso, -1, -1, NULL);
pgp->MovePointer(SurfObj, -1, -1, NULL);
else
EngMovePointer(SurfObj, -1, -1, NULL);
} }
return(TRUE); return(TRUE);
@ -88,14 +84,14 @@ MouseSafetyOnDrawStart(
*/ */
INT INTERNAL_CALL INT INTERNAL_CALL
MouseSafetyOnDrawEnd( MouseSafetyOnDrawEnd(
SURFOBJ *SurfObj) SURFOBJ *pso)
{ {
PDEVOBJ *ppdev; PDEVOBJ *ppdev;
GDIPOINTER *pgp; GDIPOINTER *pgp;
ASSERT(SurfObj != NULL); ASSERT(pso != NULL);
ppdev = GDIDEV(SurfObj); ppdev = (PDEVOBJ*)pso->hdev;
if (ppdev == NULL) if (ppdev == NULL)
{ {
@ -104,8 +100,7 @@ MouseSafetyOnDrawEnd(
pgp = &ppdev->Pointer; pgp = &ppdev->Pointer;
if (SPS_ACCEPT_NOEXCLUDE == pgp->Status || if (pgp->Exclude.right == -1)
pgp->Exclude.right == -1)
{ {
return FALSE; return FALSE;
} }
@ -114,10 +109,8 @@ MouseSafetyOnDrawEnd(
{ {
return FALSE; return FALSE;
} }
if (pgp->MovePointer)
pgp->MovePointer(SurfObj, gpsi->ptCursor.x, gpsi->ptCursor.y, &pgp->Exclude); ppdev->pfnMovePointer(pso, gpsi->ptCursor.x, gpsi->ptCursor.y, &pgp->Exclude);
else
EngMovePointer(SurfObj, gpsi->ptCursor.x, gpsi->ptCursor.y, &pgp->Exclude);
ppdev->SafetyRemoveLevel = 0; ppdev->SafetyRemoveLevel = 0;
@ -126,13 +119,16 @@ MouseSafetyOnDrawEnd(
/* SOFTWARE MOUSE POINTER IMPLEMENTATION **************************************/ /* SOFTWARE MOUSE POINTER IMPLEMENTATION **************************************/
VOID INTERNAL_CALL VOID
INTERNAL_CALL
IntHideMousePointer( IntHideMousePointer(
PDEVOBJ *ppdev, PDEVOBJ *ppdev,
SURFOBJ *psoDest) SURFOBJ *psoDest)
{ {
GDIPOINTER *pgp; GDIPOINTER *pgp;
POINTL pt; POINTL pt;
RECTL rclDest;
POINTL ptlSave;
ASSERT(ppdev); ASSERT(ppdev);
ASSERT(psoDest); ASSERT(psoDest);
@ -149,53 +145,48 @@ IntHideMousePointer(
/* The mouse is hide from ShowCours and it is frist ?? */ /* The mouse is hide from ShowCours and it is frist ?? */
if (pgp->ShowPointer < 0) if (pgp->ShowPointer < 0)
{ {
return ; return;
} }
/* Hide the cours */ if (!pgp->psurfSave)
pt.x = gpsi->ptCursor.x - pgp->HotSpot.x;
pt.y = gpsi->ptCursor.y - pgp->HotSpot.y;
if (pgp->SaveSurface != NULL)
{ {
RECTL DestRect; DPRINT1("No SaveSurface!\n");
POINTL SrcPoint; return;
SURFOBJ *SaveSurface;
SURFOBJ *MaskSurface;
DestRect.left = max(pt.x, 0);
DestRect.top = max(pt.y, 0);
DestRect.right = min(
pt.x + pgp->Size.cx,
psoDest->sizlBitmap.cx);
DestRect.bottom = min(
pt.y + pgp->Size.cy,
psoDest->sizlBitmap.cy);
SrcPoint.x = max(-pt.x, 0);
SrcPoint.y = max(-pt.y, 0);
if ((SaveSurface = EngLockSurface(pgp->SaveSurface)))
{
if ((MaskSurface = EngLockSurface(pgp->MaskSurface)))
{
IntEngBitBltEx(psoDest, SaveSurface, MaskSurface, NULL, NULL,
&DestRect, &SrcPoint, &SrcPoint, NULL, NULL,
ROP3_TO_ROP4(SRCCOPY), FALSE);
EngUnlockSurface(MaskSurface);
}
EngUnlockSurface(SaveSurface);
}
} }
/* Calculate cursor coordinates */
pt.x = ppdev->ptlPointer.x - pgp->HotSpot.x;
pt.y = ppdev->ptlPointer.y - pgp->HotSpot.y;
rclDest.left = max(pt.x, 0);
rclDest.top = max(pt.y, 0);
rclDest.right = min(pt.x + pgp->Size.cx, psoDest->sizlBitmap.cx);
rclDest.bottom = min(pt.y + pgp->Size.cy, psoDest->sizlBitmap.cy);
ptlSave.x = rclDest.left - pt.x;
ptlSave.y = rclDest.top - pt.y;
IntEngBitBltEx(psoDest,
&pgp->psurfSave->SurfObj,
NULL,
NULL,
NULL,
&rclDest,
&ptlSave,
&ptlSave,
NULL,
NULL,
ROP3_TO_ROP4(SRCCOPY),
FALSE);
} }
VOID INTERNAL_CALL VOID
INTERNAL_CALL
IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest) IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
{ {
GDIPOINTER *pgp; GDIPOINTER *pgp;
SURFOBJ *SaveSurface;
POINTL pt; POINTL pt;
RECTL rclSurf, rclPointer;
ASSERT(ppdev); ASSERT(ppdev);
ASSERT(psoDest); ASSERT(psoDest);
@ -209,87 +200,87 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
pgp->Enabled = TRUE; pgp->Enabled = TRUE;
/* Do not blt the mouse if it in hide */ /* Do not blt the pointer, if it is hidden */
if (pgp->ShowPointer < 0) if (pgp->ShowPointer < 0)
{ {
return ; return ;
} }
pt.x = gpsi->ptCursor.x - pgp->HotSpot.x; /* Calculate pointer coordinates */
pt.y = gpsi->ptCursor.y - pgp->HotSpot.y; pt.x = ppdev->ptlPointer.x - pgp->HotSpot.x;
pt.y = ppdev->ptlPointer.y - pgp->HotSpot.y;
/* Calculate the rect on the surface */
rclSurf.left = max(pt.x, 0);
rclSurf.top = max(pt.y, 0);
rclSurf.right = min(pt.x + pgp->Size.cx, psoDest->sizlBitmap.cx);
rclSurf.bottom = min(pt.y + pgp->Size.cy, psoDest->sizlBitmap.cy);
/* Calculate the rect in the pointer bitmap */
rclPointer.left = rclSurf.left - pt.x;
rclPointer.top = rclSurf.top - pt.y;
rclPointer.right = min(pgp->Size.cx, psoDest->sizlBitmap.cx - pt.x);
rclPointer.bottom = min(pgp->Size.cy, psoDest->sizlBitmap.cy - pt.y);
/* Copy the pixels under the cursor to temporary surface. */ /* Copy the pixels under the cursor to temporary surface. */
if (pgp->SaveSurface != NULL && IntEngBitBltEx(&pgp->psurfSave->SurfObj,
(SaveSurface = EngLockSurface(pgp->SaveSurface))) psoDest,
NULL,
NULL,
NULL,
&rclPointer,
(POINTL*)&rclSurf,
NULL,
NULL,
NULL,
ROP3_TO_ROP4(SRCCOPY),
FALSE);
/* Blt the pointer on the screen. */
if (pgp->psurfColor)
{ {
RECTL DestRect; IntEngBitBltEx(psoDest,
POINTL SrcPoint; &pgp->psurfColor->SurfObj,
&pgp->psurfMask->SurfObj,
SrcPoint.x = max(pt.x, 0); NULL,
SrcPoint.y = max(pt.y, 0); pgp->XlateObject,
&rclSurf,
DestRect.left = SrcPoint.x - pt.x; (POINTL*)&rclPointer,
DestRect.top = SrcPoint.y - pt.y; (POINTL*)&rclPointer,
DestRect.right = min( NULL,
pgp->Size.cx, NULL,
psoDest->sizlBitmap.cx - pt.x); R4_MASK,
DestRect.bottom = min( FALSE);
pgp->Size.cy,
psoDest->sizlBitmap.cy - pt.y);
IntEngBitBltEx(SaveSurface, psoDest, NULL, NULL, NULL,
&DestRect, &SrcPoint, NULL, NULL, NULL,
ROP3_TO_ROP4(SRCCOPY), FALSE);
EngUnlockSurface(SaveSurface);
} }
else
/* Blit the cursor on the screen. */
{ {
RECTL DestRect; IntEngBitBltEx(psoDest,
POINTL SrcPoint; &pgp->psurfMask->SurfObj,
SURFOBJ *psoColor; NULL,
SURFOBJ *psoMask = NULL; NULL,
pgp->XlateObject,
&rclSurf,
(POINTL*)&rclPointer,
NULL,
NULL,
NULL,
ROP3_TO_ROP4(SRCAND),
FALSE);
DestRect.left = max(pt.x, 0); rclPointer.top += pgp->Size.cy;
DestRect.top = max(pt.y, 0);
DestRect.right = min(
pt.x + pgp->Size.cx,
psoDest->sizlBitmap.cx);
DestRect.bottom = min(
pt.y + pgp->Size.cy,
psoDest->sizlBitmap.cy);
SrcPoint.x = max(-pt.x, 0); IntEngBitBltEx(psoDest,
SrcPoint.y = max(-pt.y, 0); &pgp->psurfMask->SurfObj,
NULL,
if (pgp->MaskSurface) NULL,
psoMask = EngLockSurface(pgp->MaskSurface); pgp->XlateObject,
&rclSurf,
if (psoMask != NULL) (POINTL*)&rclPointer,
{ NULL,
if (pgp->ColorSurface != NULL) NULL,
{ NULL,
if ((psoColor = EngLockSurface(pgp->ColorSurface))) ROP3_TO_ROP4(SRCINVERT),
{ FALSE);
IntEngBitBltEx(psoDest, psoColor, psoMask, NULL,
pgp->XlateObject, &DestRect, &SrcPoint, &SrcPoint,
NULL, NULL, R4_MASK, FALSE);
EngUnlockSurface(psoColor);
}
}
else
{
IntEngBitBltEx(psoDest, psoMask, NULL, NULL, pgp->XlateObject,
&DestRect, &SrcPoint, NULL, NULL, NULL,
ROP3_TO_ROP4(SRCAND), FALSE);
SrcPoint.y += pgp->Size.cy;
IntEngBitBltEx(psoDest, psoMask, NULL, NULL, pgp->XlateObject,
&DestRect, &SrcPoint, NULL, NULL, NULL,
ROP3_TO_ROP4(SRCINVERT), FALSE);
}
EngUnlockSurface(psoMask);
}
} }
} }
@ -310,8 +301,11 @@ EngSetPointerShape(
IN FLONG fl) IN FLONG fl)
{ {
PDEVOBJ *ppdev; PDEVOBJ *ppdev;
SURFOBJ *psoTemp;
GDIPOINTER *pgp; GDIPOINTER *pgp;
PBYTE Bits;
SIZEL Size;
LONG lDelta;
HBITMAP hbmp;
ASSERT(pso); ASSERT(pso);
@ -320,38 +314,33 @@ EngSetPointerShape(
IntHideMousePointer(ppdev, pso); IntHideMousePointer(ppdev, pso);
if (pgp->ColorSurface != NULL) if (pgp->psurfColor)
{ {
/* FIXME: Is this really needed? */ /* FIXME: let GDI allocate/free memory */
if ((psoTemp = EngLockSurface(pgp->ColorSurface))) EngFreeMem(pgp->psurfColor->SurfObj.pvBits);
{ pgp->psurfColor->SurfObj.pvBits = 0;
EngFreeMem(psoTemp->pvBits);
psoTemp->pvBits = 0;
EngUnlockSurface(psoTemp);
}
EngDeleteSurface(pgp->ColorSurface); EngDeleteSurface(pgp->psurfColor->BaseObject.hHmgr);
pgp->MaskSurface = NULL; SURFACE_ShareUnlockSurface(pgp->psurfColor);
pgp->psurfColor = NULL;
} }
if (pgp->MaskSurface != NULL) if (pgp->psurfMask)
{ {
/* FIXME: Is this really needed? */ /* FIXME: let GDI allocate/free memory */
if ((psoTemp = EngLockSurface(pgp->MaskSurface))) EngFreeMem(pgp->psurfMask->SurfObj.pvBits);
{ pgp->psurfMask->SurfObj.pvBits = 0;
EngFreeMem(psoTemp->pvBits);
psoTemp->pvBits = 0;
EngUnlockSurface(psoTemp);
}
EngDeleteSurface(pgp->MaskSurface); EngDeleteSurface(pgp->psurfMask->BaseObject.hHmgr);
pgp->MaskSurface = NULL; SURFACE_ShareUnlockSurface(pgp->psurfMask);
pgp->psurfMask = NULL;
} }
if (pgp->SaveSurface != NULL) if (pgp->psurfSave != NULL)
{ {
EngDeleteSurface(pgp->SaveSurface); EngDeleteSurface(pgp->psurfSave->BaseObject.hHmgr);
pgp->SaveSurface = NULL; SURFACE_ShareUnlockSurface(pgp->psurfSave);
pgp->psurfSave = NULL;
} }
if (pgp->XlateObject != NULL) if (pgp->XlateObject != NULL)
@ -369,12 +358,10 @@ EngSetPointerShape(
pgp->HotSpot.x = xHot; pgp->HotSpot.x = xHot;
pgp->HotSpot.y = yHot; 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) if (x != -1)
{ {
gpsi->ptCursor.x = x; ppdev->ptlPointer.x = x;
gpsi->ptCursor.y = y; ppdev->ptlPointer.y = y;
} }
pgp->Size.cx = abs(psoMask->lDelta) << 3; pgp->Size.cx = abs(psoMask->lDelta) << 3;
@ -382,8 +369,7 @@ EngSetPointerShape(
if (psoColor != NULL) if (psoColor != NULL)
{ {
PBYTE Bits; /* FIXME: let GDI allocate/free memory */
Bits = EngAllocMem(0, psoColor->cjBits, TAG_MOUSE); Bits = EngAllocMem(0, psoColor->cjBits, TAG_MOUSE);
if (Bits == NULL) if (Bits == NULL)
{ {
@ -392,34 +378,37 @@ EngSetPointerShape(
memcpy(Bits, psoColor->pvBits, psoColor->cjBits); memcpy(Bits, psoColor->pvBits, psoColor->cjBits);
pgp->ColorSurface = (HSURF)EngCreateBitmap(pgp->Size, hbmp = EngCreateBitmap(pgp->Size,
psoColor->lDelta, psoColor->iBitmapFormat, psoColor->lDelta,
psoColor->lDelta < 0 ? 0 : BMF_TOPDOWN, Bits); psoColor->iBitmapFormat,
psoColor->lDelta < 0 ? 0 : BMF_TOPDOWN,
Bits);
pgp->psurfColor = SURFACE_ShareLockSurface(hbmp);
} }
else else
{ {
pgp->ColorSurface = NULL; pgp->psurfColor = NULL;
} }
Size.cx = pgp->Size.cx;
Size.cy = pgp->Size.cy << 1;
Bits = EngAllocMem(0, psoMask->cjBits, TAG_MOUSE);
if (Bits == NULL)
{ {
SIZEL Size; return SPS_ERROR;
PBYTE Bits;
Size.cx = pgp->Size.cx;
Size.cy = pgp->Size.cy << 1;
Bits = EngAllocMem(0, psoMask->cjBits, TAG_MOUSE);
if (Bits == NULL)
{
return SPS_ERROR;
}
memcpy(Bits, psoMask->pvBits, psoMask->cjBits);
pgp->MaskSurface = (HSURF)EngCreateBitmap(Size,
psoMask->lDelta, psoMask->iBitmapFormat,
psoMask->lDelta < 0 ? 0 : BMF_TOPDOWN, Bits);
} }
memcpy(Bits, psoMask->pvBits, psoMask->cjBits);
hbmp = EngCreateBitmap(Size,
psoMask->lDelta,
psoMask->iBitmapFormat,
psoMask->lDelta < 0 ? 0 : BMF_TOPDOWN,
Bits);
pgp->psurfMask = SURFACE_ShareLockSurface(hbmp);
/* Create an XLATEOBJ that will be used for drawing masks. /* Create an XLATEOBJ that will be used for drawing masks.
* FIXME: We should get this in pxlo parameter! */ * FIXME: We should get this in pxlo parameter! */
if (pxlo == NULL) if (pxlo == NULL)
@ -441,40 +430,39 @@ EngSetPointerShape(
} }
/* Create surface for saving the pixels under the cursor. */ /* Create surface for saving the pixels under the cursor. */
switch (pso->iBitmapFormat)
{ {
LONG lDelta; case BMF_1BPP:
lDelta = pgp->Size.cx >> 3;
switch (pso->iBitmapFormat) break;
{ case BMF_4BPP:
case BMF_1BPP: lDelta = pgp->Size.cx >> 1;
lDelta = pgp->Size.cx >> 3; break;
break; case BMF_8BPP:
case BMF_4BPP: lDelta = pgp->Size.cx;
lDelta = pgp->Size.cx >> 1; break;
break; case BMF_16BPP:
case BMF_8BPP: lDelta = pgp->Size.cx << 1;
lDelta = pgp->Size.cx; break;
break; case BMF_24BPP:
case BMF_16BPP: lDelta = pgp->Size.cx * 3;
lDelta = pgp->Size.cx << 1; break;
break; case BMF_32BPP:
case BMF_24BPP: lDelta = pgp->Size.cx << 2;
lDelta = pgp->Size.cx * 3; break;
break; default:
case BMF_32BPP: lDelta = 0;
lDelta = pgp->Size.cx << 2; break;
break;
default:
lDelta = 0;
break;
}
pgp->SaveSurface = (HSURF)EngCreateBitmap(pgp->Size,
lDelta,
pso->iBitmapFormat,
BMF_TOPDOWN | BMF_NOZEROINIT, NULL);
} }
hbmp = EngCreateBitmap(pgp->Size,
lDelta,
pso->iBitmapFormat,
BMF_TOPDOWN | BMF_NOZEROINIT,
NULL);
pgp->psurfSave = SURFACE_ShareLockSurface(hbmp);
if (x != -1) if (x != -1)
{ {
IntShowMousePointer(ppdev, pso); IntShowMousePointer(ppdev, pso);
@ -489,7 +477,7 @@ EngSetPointerShape(
} else if (prcl != NULL) } else if (prcl != NULL)
prcl->left = prcl->top = prcl->right = prcl->bottom = -1; prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
return SPS_ACCEPT_EXCLUDE; return SPS_ACCEPT_NOEXCLUDE;
} }
/* /*
@ -509,18 +497,17 @@ EngMovePointer(
ASSERT(pso); ASSERT(pso);
ppdev = GDIDEV(pso); ppdev = GDIDEV(pso);
ASSERT(ppdev); ASSERT(ppdev);
pgp = &ppdev->Pointer; pgp = &ppdev->Pointer;
IntHideMousePointer(ppdev, pso); IntHideMousePointer(ppdev, pso);
ppdev->ptlPointer.x = x;
ppdev->ptlPointer.y = y;
if (x != -1) if (x != -1)
{ {
/* Actually this should be set by 'the other side', but it would be
* done right after this. It helps IntShowMousePointer. */
gpsi->ptCursor.x = x;
gpsi->ptCursor.y = y;
IntShowMousePointer(ppdev, pso); IntShowMousePointer(ppdev, pso);
if (prcl != NULL) if (prcl != NULL)
{ {
@ -531,7 +518,6 @@ EngMovePointer(
} }
} else if (prcl != NULL) } else if (prcl != NULL)
prcl->left = prcl->top = prcl->right = prcl->bottom = -1; prcl->left = prcl->top = prcl->right = prcl->bottom = -1;
} }
VOID APIENTRY VOID APIENTRY
@ -542,17 +528,74 @@ IntEngMovePointer(
IN RECTL *prcl) IN RECTL *prcl)
{ {
SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj); SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
PPDEVOBJ ppdev = (PPDEVOBJ)pso->hdev;
SURFACE_LockBitmapBits(psurf); SURFACE_LockBitmapBits(psurf);
if (GDIDEV(pso)->Pointer.MovePointer) ppdev->pfnMovePointer(pso, x, y, prcl);
{
GDIDEV(pso)->Pointer.MovePointer(pso, x, y, prcl);
}
else
{
EngMovePointer(pso, x, y, prcl);
}
SURFACE_UnlockBitmapBits(psurf); SURFACE_UnlockBitmapBits(psurf);
} }
ULONG APIENTRY
IntEngSetPointerShape(
IN SURFOBJ *pso,
IN SURFOBJ *psoMask,
IN SURFOBJ *psoColor,
IN XLATEOBJ *pxlo,
IN LONG xHot,
IN LONG yHot,
IN LONG x,
IN LONG y,
IN RECTL *prcl,
IN FLONG fl)
{
ULONG ulResult = SPS_DECLINE;
SURFACE *psurf = CONTAINING_RECORD(pso, SURFACE, SurfObj);
PFN_DrvSetPointerShape pfnSetPointerShape;
PPDEVOBJ ppdev = GDIDEV(pso);
pfnSetPointerShape = GDIDEVFUNCS(pso).SetPointerShape;
SURFACE_LockBitmapBits(psurf);
if (pfnSetPointerShape)
{
ulResult = pfnSetPointerShape(pso,
psoMask,
psoColor,
pxlo,
xHot,
yHot,
x,
y,
prcl,
fl);
}
/* Check if the driver accepted it */
if (ulResult == SPS_ACCEPT_NOEXCLUDE)
{
/* Set MovePointer to the driver function */
ppdev->pfnMovePointer = GDIDEVFUNCS(pso).MovePointer;
}
else
{
/* Set software pointer */
ulResult = EngSetPointerShape(pso,
psoMask,
psoColor,
pxlo,
xHot,
yHot,
x,
y,
prcl,
fl);
/* Set MovePointer to the eng function */
ppdev->pfnMovePointer = EngMovePointer;
}
SURFACE_UnlockBitmapBits(psurf);
return ulResult;
}
/* EOF */ /* EOF */

View file

@ -156,6 +156,19 @@ IntEngMovePointer(IN SURFOBJ *pso,
IN LONG y, IN LONG y,
IN RECTL *prcl); IN RECTL *prcl);
ULONG APIENTRY
IntEngSetPointerShape(
IN SURFOBJ *pso,
IN SURFOBJ *psoMask,
IN SURFOBJ *psoColor,
IN XLATEOBJ *pxlo,
IN LONG xHot,
IN LONG yHot,
IN LONG x,
IN LONG y,
IN RECTL *prcl,
IN FLONG fl);
BOOL APIENTRY BOOL APIENTRY
IntEngAlphaBlend(IN SURFOBJ *Dest, IntEngAlphaBlend(IN SURFOBJ *Dest,
IN SURFOBJ *Source, IN SURFOBJ *Source,
@ -165,5 +178,12 @@ IntEngAlphaBlend(IN SURFOBJ *Dest,
IN PRECTL SourceRect, IN PRECTL SourceRect,
IN BLENDOBJ *BlendObj); IN BLENDOBJ *BlendObj);
BOOL APIENTRY
IntEngCopyBits(SURFOBJ *psoDest,
SURFOBJ *psoSource,
CLIPOBJ *pco,
XLATEOBJ *pxlo,
RECTL *prclDest,
POINTL *ptlSource);
#endif /* _WIN32K_INTENG_H */ #endif /* _WIN32K_INTENG_H */

View file

@ -28,15 +28,13 @@ typedef struct _GDIPOINTER /* should stay private to ENG? No, part of PDEVOBJ ak
SIZEL Size; SIZEL Size;
POINTL HotSpot; POINTL HotSpot;
XLATEOBJ *XlateObject; XLATEOBJ *XlateObject;
HSURF ColorSurface; SURFACE *psurfColor;
HSURF MaskSurface; SURFACE *psurfMask;
HSURF SaveSurface; SURFACE *psurfSave;
int ShowPointer; /* counter negtive do not show the mouse postive show the mouse */ int ShowPointer; /* counter negtive do not show the mouse postive show the mouse */
/* public pointer information */ /* public pointer information */
RECTL Exclude; /* required publicly for SPS_ACCEPT_EXCLUDE */ RECTL Exclude; /* required publicly for SPS_ACCEPT_EXCLUDE */
PFN_DrvMovePointer MovePointer;
ULONG Status;
} GDIPOINTER, *PGDIPOINTER; } GDIPOINTER, *PGDIPOINTER;
typedef struct _GRAPHICS_DEVICE typedef struct _GRAPHICS_DEVICE
@ -59,7 +57,7 @@ typedef struct _PDEVOBJ
// FLONG flAccelerated; // FLONG flAccelerated;
PERESOURCE hsemDevLock; /* Device lock. */ PERESOURCE hsemDevLock; /* Device lock. */
// HSEMAPHORE hsemPointer; // HSEMAPHORE hsemPointer;
// POINTL ptlPointer; POINTL ptlPointer;
// SIZEL szlPointer; // SIZEL szlPointer;
// SPRITESTATE SpriteState; // SPRITESTATE SpriteState;
// HFONT hlfntDefault; // HFONT hlfntDefault;
@ -80,7 +78,7 @@ typedef struct _PDEVOBJ
// ULONG ulVertRes; // ULONG ulVertRes;
// PFN_DrvSetPointerShape pfnDrvSetPointerShape; // PFN_DrvSetPointerShape pfnDrvSetPointerShape;
// PFN_DrvMovePointer pfnDrvMovePointer; // PFN_DrvMovePointer pfnDrvMovePointer;
// PFN_DrvMovePointer pfnMovePointer; PFN_DrvMovePointer pfnMovePointer;
// PFN_DrvSynchronize pfnDrvSynchronize; // PFN_DrvSynchronize pfnDrvSynchronize;
// PFN_DrvSynchronizeSurface pfnDrvSynchronizeSurface; // PFN_DrvSynchronizeSurface pfnDrvSynchronizeSurface;
// PFN_DrvSetPalette pfnDrvSetPalette; // PFN_DrvSetPalette pfnDrvSetPalette;

View file

@ -95,6 +95,7 @@ IntSetCursor(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT NewCursor,
XLATEOBJ *XlateObj = NULL; XLATEOBJ *XlateObj = NULL;
HDC Screen; HDC Screen;
PDC dc; PDC dc;
ULONG Status;
CurInfo = IntGetSysCursorInfo(WinSta); CurInfo = IntGetSysCursorInfo(WinSta);
OldCursor = CurInfo->CurrentCursorObject; OldCursor = CurInfo->CurrentCursorObject;
@ -137,14 +138,12 @@ IntSetCursor(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT NewCursor,
UserDereferenceObject(CurInfo->CurrentCursorObject); UserDereferenceObject(CurInfo->CurrentCursorObject);
if (CurInfo->ShowingCursor) if (CurInfo->ShowingCursor)
{ {
DPRINT1("Removing pointer!\n"); DPRINT("Removing pointer!\n");
/* Remove the cursor if it was displayed */ /* Remove the cursor if it was displayed */
IntEngMovePointer(pso, -1, -1, &GDIDEV(pso)->Pointer.Exclude); IntEngMovePointer(pso, -1, -1, &GDIDEV(pso)->Pointer.Exclude);
} }
} }
GDIDEV(pso)->Pointer.Status = SPS_ACCEPT_NOEXCLUDE;
CurInfo->CurrentCursorObject = NewCursor; /* i.e. CurrentCursorObject = NULL */ CurInfo->CurrentCursorObject = NewCursor; /* i.e. CurrentCursorObject = NULL */
CurInfo->ShowingCursor = 0; CurInfo->ShowingCursor = 0;
} }
@ -212,7 +211,7 @@ IntSetCursor(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT NewCursor,
return (HCURSOR)0; return (HCURSOR)0;
} }
soMask = EngLockSurface((HSURF)hMask); soMask = EngLockSurface((HSURF)hMask);
EngCopyBits(soMask, &MaskBmpObj->SurfObj, NULL, NULL, IntEngCopyBits(soMask, &MaskBmpObj->SurfObj, NULL, NULL,
&DestRect, &SourcePoint); &DestRect, &SourcePoint);
SURFACE_UnlockSurface(MaskBmpObj); SURFACE_UnlockSurface(MaskBmpObj);
} }
@ -234,40 +233,20 @@ IntSetCursor(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT NewCursor,
UserDereferenceObject(OldCursor); UserDereferenceObject(OldCursor);
} }
if (GDIDEVFUNCS(pso).SetPointerShape) Status = IntEngSetPointerShape(pso,
{ soMask,
GDIDEV(pso)->Pointer.Status = soColor,
GDIDEVFUNCS(pso).SetPointerShape( XlateObj,
pso, soMask, soColor, XlateObj, NewCursor->IconInfo.xHotspot,
NewCursor->IconInfo.xHotspot, NewCursor->IconInfo.yHotspot,
NewCursor->IconInfo.yHotspot, gpsi->ptCursor.x,
gpsi->ptCursor.x, gpsi->ptCursor.y,
gpsi->ptCursor.y, &(GDIDEV(pso)->Pointer.Exclude),
&(GDIDEV(pso)->Pointer.Exclude), SPS_CHANGE);
SPS_CHANGE);
DPRINT("SetCursor: DrvSetPointerShape() returned %x\n",
GDIDEV(pso)->Pointer.Status);
}
else
{
GDIDEV(pso)->Pointer.Status = SPS_DECLINE;
}
if(GDIDEV(pso)->Pointer.Status == SPS_DECLINE) if (Status != SPS_ACCEPT_NOEXCLUDE)
{ {
GDIDEV(pso)->Pointer.Status = EngSetPointerShape( DPRINT1("IntEngSetPointerShape returned %lx\n", Status);
pso, soMask, soColor, XlateObj,
NewCursor->IconInfo.xHotspot,
NewCursor->IconInfo.yHotspot,
gpsi->ptCursor.x,
gpsi->ptCursor.y,
&(GDIDEV(pso)->Pointer.Exclude),
SPS_CHANGE);
GDIDEV(pso)->Pointer.MovePointer = NULL;
}
else
{
GDIDEV(pso)->Pointer.MovePointer = GDIDEVFUNCS(pso).MovePointer;
} }
SURFACE_UnlockSurface(psurf); SURFACE_UnlockSurface(psurf);
@ -281,9 +260,6 @@ IntSetCursor(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT NewCursor,
EngDeleteXlate(XlateObj); EngDeleteXlate(XlateObj);
} }
if(GDIDEV(pso)->Pointer.Status == SPS_ERROR)
DPRINT1("SetCursor: DrvSetPointerShape() returned SPS_ERROR\n");
return Ret; return Ret;
} }
@ -1804,7 +1780,7 @@ UserShowCursor(BOOL bShow)
{ {
//ppdev->SafetyRemoveCount = 1; //ppdev->SafetyRemoveCount = 1;
//ppdev->SafetyRemoveLevel = 1; //ppdev->SafetyRemoveLevel = 1;
EngMovePointer(SurfObj,-1,-1,NULL); IntEngMovePointer(SurfObj,-1,-1,NULL);
CurInfo->ShowingCursor = 0; CurInfo->ShowingCursor = 0;
} }
@ -1819,7 +1795,7 @@ UserShowCursor(BOOL bShow)
{ {
//ppdev->SafetyRemoveCount = 0; //ppdev->SafetyRemoveCount = 0;
//ppdev->SafetyRemoveLevel = 0; //ppdev->SafetyRemoveLevel = 0;
EngMovePointer(SurfObj,-1,-1,NULL); IntEngMovePointer(SurfObj,-1,-1,NULL);
CurInfo->ShowingCursor = CURSOR_SHOWING; CurInfo->ShowingCursor = CURSOR_SHOWING;
} }
} }

View file

@ -553,6 +553,11 @@ IntCreatePrimarySurface()
gpsi->ptCursor.x = (SurfaceRect.right - SurfaceRect.left) / 2; gpsi->ptCursor.x = (SurfaceRect.right - SurfaceRect.left) / 2;
gpsi->ptCursor.y = (SurfaceRect.bottom - SurfaceRect.top) / 2; gpsi->ptCursor.y = (SurfaceRect.bottom - SurfaceRect.top) / 2;
/* Give the PDEV a MovePointer function */
PrimarySurface.pfnMovePointer = PrimarySurface.DriverFunctions.MovePointer;
if (!PrimarySurface.pfnMovePointer)
PrimarySurface.pfnMovePointer = EngMovePointer;
EngUnlockSurface(SurfObj); EngUnlockSurface(SurfObj);
co_IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy); co_IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy);

View file

@ -329,7 +329,7 @@ IntSetDIBits(
DestRect.right = SourceSize.cx; DestRect.right = SourceSize.cx;
DestRect.bottom = DestRect.top + ScanLines; DestRect.bottom = DestRect.top + ScanLines;
copyBitsResult = EngCopyBits(DestSurf, SourceSurf, NULL, XlateObj, &DestRect, &ZeroPoint); copyBitsResult = IntEngCopyBits(DestSurf, SourceSurf, NULL, XlateObj, &DestRect, &ZeroPoint);
// If it succeeded, return number of scanlines copies // If it succeeded, return number of scanlines copies
if(copyBitsResult == TRUE) if(copyBitsResult == TRUE)
@ -952,7 +952,7 @@ NtGdiGetDIBitsInternal(HDC hDC,
DestSurfObj = EngLockSurface((HSURF)hDestBitmap); DestSurfObj = EngLockSurface((HSURF)hDestBitmap);
if (EngCopyBits( DestSurfObj, if (IntEngCopyBits( DestSurfObj,
&psurf->SurfObj, &psurf->SurfObj,
NULL, NULL,
XlateObj, XlateObj,