Author: tkreuzer
Date: Fri Aug 7 03:44:38 2009
New Revision: 42447
URL:
http://svn.reactos.org/svn/reactos?rev=42447&view=rev
Log:
[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.
Modified:
trunk/reactos/subsystems/win32/win32k/eng/mouse.c
trunk/reactos/subsystems/win32/win32k/include/cursoricon.h
trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
Modified: trunk/reactos/subsystems/win32/win32k/eng/mouse.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/en…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/eng/mouse.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/eng/mouse.c [iso-8859-1] Fri Aug 7 03:44:38
2009
@@ -240,16 +240,29 @@
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 @@
{
PDEVOBJ *ppdev;
GDIPOINTER *pgp;
- SIZEL Size;
LONG lDelta;
HBITMAP hbmp;
RECTL rcl;
@@ -312,6 +324,31 @@
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,30 +373,13 @@
}
/* See if we are being asked to hide the pointer. */
- if (psoMask == NULL)
+ if (psoMask == NULL && psoColor == NULL)
{
return SPS_ACCEPT_NOEXCLUDE;
}
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 @@
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 @@
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 @@
/* 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 @@
if (x != -1)
{
+ ppdev->ptlPointer.x = x;
+ ppdev->ptlPointer.y = y;
+
IntShowMousePointer(ppdev, pso);
if (prcl != NULL)
@@ -590,4 +627,115 @@
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 */
Modified: trunk/reactos/subsystems/win32/win32k/include/cursoricon.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/cursoricon.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/cursoricon.h [iso-8859-1] Fri Aug 7
03:44:38 2009
@@ -85,6 +85,24 @@
#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 */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] Fri Aug 7
03:44:38 2009
@@ -78,153 +78,70 @@
#define COLORCURSORS_ALLOWED FALSE
-HCURSOR FASTCALL
-IntSetCursor(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT NewCursor,
- BOOL ForceChange)
-{
- SURFACE *psurf;
- SURFOBJ *pso;
- PDEVINFO DevInfo;
- PSURFACE MaskBmpObj = NULL;
+HCURSOR
+FASTCALL
+IntSetCursor(
+ PWINSTATION_OBJECT WinSta,
+ PCURICON_OBJECT NewCursor,
+ BOOL ForceChange)
+{
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;
- }
-
- if (!ForceChange && OldCursor == NewCursor)
- {
- return Ret;
- }
-
- if (!(Screen = IntGetScreenDC()))
+ hOldCursor = (HCURSOR)OldCursor->Self;
+ }
+
+ /* Is the new cursor the same as the old cursor? */
+ if (OldCursor == NewCursor)
+ {
+ /* Nothing to to do in this case */
+ return hOldCursor;
+ }
+
+ /* 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)
- {
- return Ret;
- }
- DevInfo = (PDEVINFO)&dc->ppdev->DevInfo;
-
- 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);
- }
- }
- }
+
+ /* Do we have a new cursor? */
+ if (NewCursor)
+ {
+ UserReferenceObject(NewCursor);
+
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
{
+ /* 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;
- CurInfo->CurrentCursorObject = NULL;
}
/* OldCursor is not in use anymore */
@@ -233,35 +150,10 @@
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)