From 29c24f700e2af443d910eef0ec1a5d41ff97066e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 7 Aug 2009 01:44:38 +0000 Subject: [PATCH] [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 --- reactos/subsystems/win32/win32k/eng/mouse.c | 240 ++++++++++++++---- .../win32/win32k/include/cursoricon.h | 18 ++ .../win32/win32k/ntuser/cursoricon.c | 186 +++----------- 3 files changed, 251 insertions(+), 193 deletions(-) diff --git a/reactos/subsystems/win32/win32k/eng/mouse.c b/reactos/subsystems/win32/win32k/eng/mouse.c index 7ee6d3ea1f8..d3b67f81072 100644 --- a/reactos/subsystems/win32/win32k/eng/mouse.c +++ b/reactos/subsystems/win32/win32k/eng/mouse.c @@ -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 */ diff --git a/reactos/subsystems/win32/win32k/include/cursoricon.h b/reactos/subsystems/win32/win32k/include/cursoricon.h index a3464ba887f..5e31b1fc414 100644 --- a/reactos/subsystems/win32/win32k/include/cursoricon.h +++ b/reactos/subsystems/win32/win32k/include/cursoricon.h @@ -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 */ diff --git a/reactos/subsystems/win32/win32k/ntuser/cursoricon.c b/reactos/subsystems/win32/win32k/ntuser/cursoricon.c index 4e1802c9d26..56cce86a84b 100644 --- a/reactos/subsystems/win32/win32k/ntuser/cursoricon.c +++ b/reactos/subsystems/win32/win32k/ntuser/cursoricon.c @@ -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; + CurInfo->ShowingCursor = CURSOR_SHOWING; + CurInfo->CurrentCursorObject = NewCursor; - 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); - } - } + /* 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); - 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) + else { - const int maskBpp = BitsPerFormat(MaskBmpObj->SurfObj.iBitmapFormat); - SURFACE_UnlockSurface(MaskBmpObj); - if (maskBpp != 1) + /* Check if were diplaying a cursor */ + if (OldCursor && CurInfo->ShowingCursor) { - DPRINT1("SetCursor: The Mask bitmap must have 1BPP!\n"); - DC_UnlockDc(dc); - return Ret; + /* Remove the cursor */ + GreMovePointer(hdcScreen, -1, -1); + DPRINT("Removing pointer!\n"); } - 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); - } - else - { - CurInfo->ShowingCursor = 0; 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) { -- 2.17.1