mirror of
https://github.com/reactos/reactos.git
synced 2025-06-01 07:28:19 +00:00
[win32k]
Implement GreMovePointer and GreSetPointerShape, calling the eng functions and use them instead of the former mess in IntSetCursor. Fix IntShowMousePointer, EngSetPointerShape to properly handle the color bitmap. We now have support for colored mouse cursors, like used by our paint. svn path=/trunk/; revision=42447
This commit is contained in:
parent
314fa19276
commit
29c24f700e
3 changed files with 254 additions and 196 deletions
|
@ -240,16 +240,29 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
|
|||
if (pgp->psurfColor)
|
||||
{
|
||||
IntEngBitBltEx(psoDest,
|
||||
&pgp->psurfColor->SurfObj,
|
||||
&pgp->psurfMask->SurfObj,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&rclSurf,
|
||||
(POINTL*)&rclPointer,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
ROP3_TO_ROP4(SRCAND),
|
||||
FALSE);
|
||||
|
||||
IntEngBitBltEx(psoDest,
|
||||
&pgp->psurfColor->SurfObj,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&rclSurf,
|
||||
(POINTL*)&rclPointer,
|
||||
NULL,
|
||||
NULL,
|
||||
R4_MASK,
|
||||
NULL,
|
||||
ROP3_TO_ROP4(SRCINVERT),
|
||||
FALSE);
|
||||
}
|
||||
else
|
||||
|
@ -302,7 +315,6 @@ EngSetPointerShape(
|
|||
{
|
||||
PDEVOBJ *ppdev;
|
||||
GDIPOINTER *pgp;
|
||||
SIZEL Size;
|
||||
LONG lDelta;
|
||||
HBITMAP hbmp;
|
||||
RECTL rcl;
|
||||
|
@ -312,6 +324,31 @@ EngSetPointerShape(
|
|||
ppdev = GDIDEV(pso);
|
||||
pgp = &ppdev->Pointer;
|
||||
|
||||
if (psoColor)
|
||||
{
|
||||
pgp->Size.cx = psoColor->sizlBitmap.cx;
|
||||
pgp->Size.cy = psoColor->sizlBitmap.cy;
|
||||
if (psoMask)
|
||||
{
|
||||
// CHECKME: Is this really required? if we have a color surface,
|
||||
// we only need the and part of the mask.
|
||||
/* Check if the sizes match as they should */
|
||||
if (psoMask->sizlBitmap.cx != psoColor->sizlBitmap.cx ||
|
||||
psoMask->sizlBitmap.cy != psoColor->sizlBitmap.cy * 2)
|
||||
{
|
||||
DPRINT("Sizes of mask (%ld,%ld) and color (%ld,%ld) don't match\n",
|
||||
psoMask->sizlBitmap.cx, psoMask->sizlBitmap.cy,
|
||||
psoColor->sizlBitmap.cx, psoColor->sizlBitmap.cy);
|
||||
// return SPS_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pgp->Size.cx = psoMask->sizlBitmap.cx;
|
||||
pgp->Size.cy = psoMask->sizlBitmap.cy / 2;
|
||||
}
|
||||
|
||||
IntHideMousePointer(ppdev, pso);
|
||||
|
||||
if (pgp->psurfColor)
|
||||
|
@ -336,7 +373,7 @@ EngSetPointerShape(
|
|||
}
|
||||
|
||||
/* See if we are being asked to hide the pointer. */
|
||||
if (psoMask == NULL)
|
||||
if (psoMask == NULL && psoColor == NULL)
|
||||
{
|
||||
return SPS_ACCEPT_NOEXCLUDE;
|
||||
}
|
||||
|
@ -344,23 +381,6 @@ EngSetPointerShape(
|
|||
pgp->HotSpot.x = xHot;
|
||||
pgp->HotSpot.y = yHot;
|
||||
|
||||
if (x != -1)
|
||||
{
|
||||
ppdev->ptlPointer.x = x;
|
||||
ppdev->ptlPointer.y = y;
|
||||
}
|
||||
|
||||
pgp->Size.cx = abs(psoMask->lDelta) << 3;
|
||||
pgp->Size.cy = (psoMask->cjBits / abs(psoMask->lDelta)) >> 1;
|
||||
|
||||
Size.cx = pgp->Size.cx;
|
||||
Size.cy = pgp->Size.cy << 1;
|
||||
|
||||
rcl.left = 0;
|
||||
rcl.top = 0;
|
||||
rcl.right = Size.cx;
|
||||
rcl.bottom = Size.cy;
|
||||
|
||||
/* Calculate lDelta for our surfaces. */
|
||||
switch (pso->iBitmapFormat)
|
||||
{
|
||||
|
@ -387,6 +407,11 @@ EngSetPointerShape(
|
|||
break;
|
||||
}
|
||||
|
||||
rcl.left = 0;
|
||||
rcl.top = 0;
|
||||
rcl.right = pgp->Size.cx;
|
||||
rcl.bottom = pgp->Size.cy;
|
||||
|
||||
/* Create surface for saving the pixels under the cursor. */
|
||||
hbmp = EngCreateBitmap(pgp->Size,
|
||||
lDelta,
|
||||
|
@ -401,30 +426,35 @@ EngSetPointerShape(
|
|||
EXLATEOBJ exlo;
|
||||
PPALETTE ppal;
|
||||
|
||||
ppal = PALETTE_LockPalette(ppdev->DevInfo.hpalDefault);
|
||||
EXLATEOBJ_vInitialize(&exlo,
|
||||
&gpalMono,
|
||||
ppal,
|
||||
0,
|
||||
RGB(0xff,0xff,0xff),
|
||||
RGB(0,0,0));
|
||||
|
||||
hbmp = EngCreateBitmap(Size,
|
||||
hbmp = EngCreateBitmap(psoMask->sizlBitmap,
|
||||
lDelta,
|
||||
pso->iBitmapFormat,
|
||||
0,
|
||||
NULL);
|
||||
pgp->psurfMask = SURFACE_ShareLockSurface(hbmp);
|
||||
IntEngCopyBits(&pgp->psurfMask->SurfObj,
|
||||
psoMask,
|
||||
NULL,
|
||||
&exlo.xlo,
|
||||
&rcl,
|
||||
(POINTL*)&rcl);
|
||||
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
if (ppal)
|
||||
PALETTE_UnlockPalette(ppal);
|
||||
if(pgp->psurfMask)
|
||||
{
|
||||
ppal = PALETTE_LockPalette(ppdev->DevInfo.hpalDefault);
|
||||
EXLATEOBJ_vInitialize(&exlo,
|
||||
&gpalMono,
|
||||
ppal,
|
||||
0,
|
||||
RGB(0xff,0xff,0xff),
|
||||
RGB(0,0,0));
|
||||
|
||||
rcl.bottom = pgp->Size.cy * 2;
|
||||
IntEngCopyBits(&pgp->psurfMask->SurfObj,
|
||||
psoMask,
|
||||
NULL,
|
||||
&exlo.xlo,
|
||||
&rcl,
|
||||
(POINTL*)&rcl);
|
||||
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
if (ppal)
|
||||
PALETTE_UnlockPalette(ppal);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -434,18 +464,22 @@ EngSetPointerShape(
|
|||
/* Create a color surface */
|
||||
if (psoColor)
|
||||
{
|
||||
hbmp = EngCreateBitmap(pgp->Size,
|
||||
hbmp = EngCreateBitmap(psoColor->sizlBitmap,
|
||||
lDelta,
|
||||
pso->iBitmapFormat,
|
||||
BMF_TOPDOWN | BMF_NOZEROINIT,
|
||||
NULL);
|
||||
pgp->psurfColor = SURFACE_ShareLockSurface(hbmp);
|
||||
IntEngCopyBits(&pgp->psurfColor->SurfObj,
|
||||
psoColor,
|
||||
NULL,
|
||||
pxlo,
|
||||
&rcl,
|
||||
(POINTL*)&rcl);
|
||||
if (pgp->psurfColor)
|
||||
{
|
||||
rcl.bottom = pgp->Size.cy;
|
||||
IntEngCopyBits(&pgp->psurfColor->SurfObj,
|
||||
psoColor,
|
||||
NULL,
|
||||
pxlo,
|
||||
&rcl,
|
||||
(POINTL*)&rcl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -454,6 +488,9 @@ EngSetPointerShape(
|
|||
|
||||
if (x != -1)
|
||||
{
|
||||
ppdev->ptlPointer.x = x;
|
||||
ppdev->ptlPointer.y = y;
|
||||
|
||||
IntShowMousePointer(ppdev, pso);
|
||||
|
||||
if (prcl != NULL)
|
||||
|
@ -590,4 +627,115 @@ IntEngSetPointerShape(
|
|||
return ulResult;
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
GreSetPointerShape(
|
||||
HDC hdc,
|
||||
HBITMAP hbmMask,
|
||||
HBITMAP hbmColor,
|
||||
LONG xHot,
|
||||
LONG yHot,
|
||||
LONG x,
|
||||
LONG y)
|
||||
{
|
||||
PDC pdc;
|
||||
PSURFACE psurf, psurfMask, psurfColor;
|
||||
EXLATEOBJ exlo;
|
||||
FLONG fl = 0;
|
||||
ULONG ulResult = 0;
|
||||
|
||||
pdc = DC_LockDc(hdc);
|
||||
if (!pdc)
|
||||
{
|
||||
DPRINT1("Failed to lock the DC.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
psurf = pdc->dclevel.pSurface;
|
||||
if (!psurf)
|
||||
{
|
||||
DPRINT1("DC has no surface.\n");
|
||||
DC_UnlockDc(pdc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Lock the mask bitmap */
|
||||
if (hbmMask)
|
||||
psurfMask = SURFACE_ShareLockSurface(hbmMask);
|
||||
else
|
||||
psurfMask = NULL;
|
||||
|
||||
/* Check for color bitmap */
|
||||
if (hbmColor)
|
||||
{
|
||||
/* We have one, lock it */
|
||||
psurfColor = SURFACE_ShareLockSurface(hbmColor);
|
||||
|
||||
if (psurfColor)
|
||||
{
|
||||
/* Create an XLATEOBJ, no mono support */
|
||||
EXLATEOBJ_vInitialize(&exlo, psurfColor->ppal, psurf->ppal, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
psurfColor = NULL;
|
||||
|
||||
/* Call the driver or eng function */
|
||||
ulResult = IntEngSetPointerShape(&psurf->SurfObj,
|
||||
psurfMask ? &psurfMask->SurfObj : NULL,
|
||||
psurfColor ? &psurfColor->SurfObj : NULL,
|
||||
psurfColor ? &exlo.xlo : NULL,
|
||||
xHot,
|
||||
yHot,
|
||||
x,
|
||||
y,
|
||||
&pdc->ppdev->Pointer.Exclude,
|
||||
fl);
|
||||
|
||||
/* Cleanup */
|
||||
if (hbmColor)
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
|
||||
if (psurfColor)
|
||||
SURFACE_ShareUnlockSurface(psurfColor);
|
||||
|
||||
if (psurfMask)
|
||||
SURFACE_ShareUnlockSurface(psurfMask);
|
||||
|
||||
/* Unlock the DC */
|
||||
DC_UnlockDc(pdc);
|
||||
|
||||
/* Return result */
|
||||
return ulResult;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
GreMovePointer(
|
||||
HDC hdc,
|
||||
LONG x,
|
||||
LONG y)
|
||||
{
|
||||
PDC pdc;
|
||||
PRECTL prcl;
|
||||
|
||||
/* Lock the DC */
|
||||
pdc = DC_LockDc(hdc);
|
||||
if (!pdc)
|
||||
{
|
||||
DPRINT1("Failed to lock the DC.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Store the cursor exclude position in the PDEV */
|
||||
prcl = &pdc->ppdev->Pointer.Exclude;
|
||||
|
||||
/* Call Eng/Drv function */
|
||||
IntEngMovePointer(&pdc->dclevel.pSurface->SurfObj, x, y, prcl);
|
||||
|
||||
/* Unlock the DC */
|
||||
DC_UnlockDc(pdc);
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -85,6 +85,24 @@ int APIENTRY UserShowCursor(BOOL bShow);
|
|||
#define IntReleaseCurIconObject(CurIconObj) \
|
||||
UserDereferenceObject(CurIconObj)
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
GreSetPointerShape(
|
||||
HDC hdc,
|
||||
HBITMAP hbmMask,
|
||||
HBITMAP hbmColor,
|
||||
LONG xHot,
|
||||
LONG yHot,
|
||||
LONG x,
|
||||
LONG y);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
GreMovePointer(
|
||||
HDC hdc,
|
||||
LONG x,
|
||||
LONG y);
|
||||
|
||||
#endif /* _WIN32K_CURSORICON_H */
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -78,153 +78,70 @@ PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
|
|||
|
||||
|
||||
#define COLORCURSORS_ALLOWED FALSE
|
||||
HCURSOR FASTCALL
|
||||
IntSetCursor(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT NewCursor,
|
||||
BOOL ForceChange)
|
||||
HCURSOR
|
||||
FASTCALL
|
||||
IntSetCursor(
|
||||
PWINSTATION_OBJECT WinSta,
|
||||
PCURICON_OBJECT NewCursor,
|
||||
BOOL ForceChange)
|
||||
{
|
||||
SURFACE *psurf;
|
||||
SURFOBJ *pso;
|
||||
PDEVINFO DevInfo;
|
||||
PSURFACE MaskBmpObj = NULL;
|
||||
PSYSTEM_CURSORINFO CurInfo;
|
||||
PCURICON_OBJECT OldCursor;
|
||||
HCURSOR Ret = (HCURSOR)0;
|
||||
HBITMAP hMask = 0;
|
||||
SURFOBJ *soMask = NULL, *soColor = NULL;
|
||||
XLATEOBJ *XlateObj = NULL;
|
||||
HDC Screen;
|
||||
PDC dc;
|
||||
ULONG Status;
|
||||
HCURSOR hOldCursor = (HCURSOR)0;
|
||||
HDC hdcScreen;
|
||||
BOOL bResult;
|
||||
|
||||
CurInfo = IntGetSysCursorInfo(WinSta);
|
||||
OldCursor = CurInfo->CurrentCursorObject;
|
||||
if (OldCursor)
|
||||
{
|
||||
Ret = (HCURSOR)OldCursor->Self;
|
||||
hOldCursor = (HCURSOR)OldCursor->Self;
|
||||
}
|
||||
|
||||
if (!ForceChange && OldCursor == NewCursor)
|
||||
/* Is the new cursor the same as the old cursor? */
|
||||
if (OldCursor == NewCursor)
|
||||
{
|
||||
return Ret;
|
||||
/* Nothing to to do in this case */
|
||||
return hOldCursor;
|
||||
}
|
||||
|
||||
if (!(Screen = IntGetScreenDC()))
|
||||
/* Get the screen DC */
|
||||
if(!(hdcScreen = IntGetScreenDC()))
|
||||
{
|
||||
return (HCURSOR)0;
|
||||
}
|
||||
/* FIXME use the desktop's HDC instead of using ScreenDeviceContext */
|
||||
dc = DC_LockDc(Screen);
|
||||
|
||||
if (!dc)
|
||||
/* Do we have a new cursor? */
|
||||
if (NewCursor)
|
||||
{
|
||||
return Ret;
|
||||
}
|
||||
DevInfo = (PDEVINFO)&dc->ppdev->DevInfo;
|
||||
UserReferenceObject(NewCursor);
|
||||
|
||||
psurf = dc->dclevel.pSurface;
|
||||
if (!psurf)
|
||||
{
|
||||
DC_UnlockDc(dc);
|
||||
return (HCURSOR)0;
|
||||
}
|
||||
pso = &psurf->SurfObj;
|
||||
|
||||
if (!NewCursor)
|
||||
{
|
||||
if (CurInfo->CurrentCursorObject || ForceChange)
|
||||
{
|
||||
if (CurInfo->CurrentCursorObject)
|
||||
{
|
||||
UserDereferenceObject(CurInfo->CurrentCursorObject);
|
||||
if (CurInfo->ShowingCursor)
|
||||
{
|
||||
DPRINT("Removing pointer!\n");
|
||||
/* Remove the cursor if it was displayed */
|
||||
IntEngMovePointer(pso, -1, -1, &GDIDEV(pso)->Pointer.Exclude);
|
||||
}
|
||||
}
|
||||
|
||||
CurInfo->CurrentCursorObject = NewCursor; /* i.e. CurrentCursorObject = NULL */
|
||||
CurInfo->ShowingCursor = 0;
|
||||
}
|
||||
|
||||
DC_UnlockDc(dc);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
/* TODO: Fixme. Logic is screwed above */
|
||||
|
||||
MaskBmpObj = SURFACE_LockSurface(NewCursor->IconInfo.hbmMask);
|
||||
if (MaskBmpObj)
|
||||
{
|
||||
const int maskBpp = BitsPerFormat(MaskBmpObj->SurfObj.iBitmapFormat);
|
||||
SURFACE_UnlockSurface(MaskBmpObj);
|
||||
if (maskBpp != 1)
|
||||
{
|
||||
DPRINT1("SetCursor: The Mask bitmap must have 1BPP!\n");
|
||||
DC_UnlockDc(dc);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
if ((DevInfo->flGraphicsCaps2 & GCAPS2_ALPHACURSOR) &&
|
||||
pso->iBitmapFormat >= BMF_16BPP &&
|
||||
pso->iBitmapFormat <= BMF_32BPP &&
|
||||
NewCursor->Shadow && COLORCURSORS_ALLOWED)
|
||||
{
|
||||
/* FIXME - Create a color pointer, only 32bit bitmap, set alpha bits!
|
||||
Do not pass a mask bitmap to DrvSetPointerShape()!
|
||||
Create a XLATEOBJ that describes the colors of the bitmap. */
|
||||
DPRINT1("SetCursor: (Colored) alpha cursors are not supported!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NewCursor->IconInfo.hbmColor
|
||||
&& COLORCURSORS_ALLOWED)
|
||||
{
|
||||
/* FIXME - Create a color pointer, create only one 32bit bitmap!
|
||||
Do not pass a mask bitmap to DrvSetPointerShape()!
|
||||
Create a XLATEOBJ that describes the colors of the bitmap.
|
||||
(16bit bitmaps are propably allowed) */
|
||||
DPRINT1("SetCursor: Cursors with colors are not supported!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
MaskBmpObj = SURFACE_LockSurface(NewCursor->IconInfo.hbmMask);
|
||||
if (MaskBmpObj)
|
||||
{
|
||||
RECTL DestRect = {0, 0, MaskBmpObj->SurfObj.sizlBitmap.cx, MaskBmpObj->SurfObj.sizlBitmap.cy};
|
||||
POINTL SourcePoint = {0, 0};
|
||||
|
||||
/*
|
||||
* NOTE: For now we create the cursor in top-down bitmap,
|
||||
* because VMware driver rejects it otherwise. This should
|
||||
* be fixed later.
|
||||
*/
|
||||
hMask = EngCreateBitmap(
|
||||
MaskBmpObj->SurfObj.sizlBitmap, abs(MaskBmpObj->SurfObj.lDelta),
|
||||
MaskBmpObj->SurfObj.iBitmapFormat, BMF_TOPDOWN,
|
||||
NULL);
|
||||
if (!hMask)
|
||||
{
|
||||
SURFACE_UnlockSurface(MaskBmpObj);
|
||||
DC_UnlockDc(dc);
|
||||
return (HCURSOR)0;
|
||||
}
|
||||
soMask = EngLockSurface((HSURF)hMask);
|
||||
IntEngCopyBits(soMask, &MaskBmpObj->SurfObj, NULL, NULL,
|
||||
&DestRect, &SourcePoint);
|
||||
SURFACE_UnlockSurface(MaskBmpObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
CurInfo->ShowingCursor = CURSOR_SHOWING;
|
||||
CurInfo->CurrentCursorObject = NewCursor;
|
||||
UserReferenceObject(NewCursor);
|
||||
|
||||
/* Call GDI to set the new screen cursor */
|
||||
bResult = GreSetPointerShape(hdcScreen,
|
||||
NewCursor->IconInfo.hbmMask,
|
||||
NewCursor->IconInfo.hbmColor,
|
||||
NewCursor->IconInfo.xHotspot,
|
||||
NewCursor->IconInfo.yHotspot,
|
||||
gpsi->ptCursor.x,
|
||||
gpsi->ptCursor.y);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
CurInfo->ShowingCursor = 0;
|
||||
/* Check if were diplaying a cursor */
|
||||
if (OldCursor && CurInfo->ShowingCursor)
|
||||
{
|
||||
/* Remove the cursor */
|
||||
GreMovePointer(hdcScreen, -1, -1);
|
||||
DPRINT("Removing pointer!\n");
|
||||
}
|
||||
|
||||
CurInfo->CurrentCursorObject = NULL;
|
||||
CurInfo->ShowingCursor = 0;
|
||||
}
|
||||
|
||||
/* OldCursor is not in use anymore */
|
||||
|
@ -233,36 +150,11 @@ IntSetCursor(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT NewCursor,
|
|||
UserDereferenceObject(OldCursor);
|
||||
}
|
||||
|
||||
Status = IntEngSetPointerShape(pso,
|
||||
soMask,
|
||||
soColor,
|
||||
XlateObj,
|
||||
NewCursor->IconInfo.xHotspot,
|
||||
NewCursor->IconInfo.yHotspot,
|
||||
gpsi->ptCursor.x,
|
||||
gpsi->ptCursor.y,
|
||||
&(GDIDEV(pso)->Pointer.Exclude),
|
||||
SPS_CHANGE);
|
||||
|
||||
if (Status != SPS_ACCEPT_NOEXCLUDE)
|
||||
{
|
||||
DPRINT1("IntEngSetPointerShape returned %lx\n", Status);
|
||||
}
|
||||
|
||||
if (hMask)
|
||||
{
|
||||
EngUnlockSurface(soMask);
|
||||
EngDeleteSurface((HSURF)hMask);
|
||||
}
|
||||
if (XlateObj)
|
||||
{
|
||||
EngDeleteXlate(XlateObj);
|
||||
}
|
||||
|
||||
DC_UnlockDc(dc);
|
||||
return Ret;
|
||||
/* Return handle of the old cursor */
|
||||
return hOldCursor;
|
||||
}
|
||||
|
||||
|
||||
BOOL FASTCALL
|
||||
IntSetupCurIconHandles(PWINSTATION_OBJECT WinSta)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue