Author: jgardou Date: Sat Nov 10 15:56:42 2012 New Revision: 57695 URL: http://svn.reactos.org/svn/reactos?rev=57695&view=rev Log: [WIN32K] - Implement usage of alpha cursors (does not work yet due to a bug in windres) - Directly use bitmaps passed to NtUserSetCursorIconData instead of copying them
Modified: trunk/reactos/win32ss/gdi/eng/mouse.c trunk/reactos/win32ss/gdi/eng/mouse.h trunk/reactos/win32ss/gdi/eng/pdevobj.h trunk/reactos/win32ss/user/ntuser/cursoricon_new.c trunk/reactos/win32ss/user/ntuser/msgqueue.c trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c Modified: trunk/reactos/win32ss/gdi/eng/mouse.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/eng/mouse.c?rev=57695&r1=57694&r2=57695&view=diff ============================================================================== --- trunk/reactos/win32ss/gdi/eng/mouse.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/eng/mouse.c [iso-8859-1] Sat Nov 10 15:56:42 2012 @@ -232,29 +232,51 @@ /* Blt the pointer on the screen. */ if (pgp->psurfColor) { - IntEngBitBlt(psoDest, - &pgp->psurfMask->SurfObj, - NULL, - NULL, - NULL, - &rclSurf, - (POINTL*)&rclPointer, - NULL, - NULL, - NULL, - ROP4_FROM_INDEX(R3_OPINDEX_SRCAND)); - - IntEngBitBlt(psoDest, - &pgp->psurfColor->SurfObj, - NULL, - NULL, - NULL, - &rclSurf, - (POINTL*)&rclPointer, - NULL, - NULL, - NULL, - ROP4_FROM_INDEX(R3_OPINDEX_SRCINVERT)); + if(!(pgp->flags & SPS_ALPHA)) + { + IntEngBitBlt(psoDest, + &pgp->psurfMask->SurfObj, + NULL, + NULL, + NULL, + &rclSurf, + (POINTL*)&rclPointer, + NULL, + NULL, + NULL, + ROP4_SRCAND); + + IntEngBitBlt(psoDest, + &pgp->psurfColor->SurfObj, + NULL, + NULL, + NULL, + &rclSurf, + (POINTL*)&rclPointer, + NULL, + NULL, + NULL, + ROP4_SRCINVERT); + } + else + { + BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } }; + EXLATEOBJ exlo; + EXLATEOBJ_vInitialize(&exlo, + pgp->psurfColor->ppal, + ppdev->ppalSurf, + 0xFFFFFFFF, + 0xFFFFFFFF, + 0); + IntEngAlphaBlend(psoDest, + &pgp->psurfColor->SurfObj, + NULL, + &exlo.xlo, + &rclSurf, + &rclPointer, + &blendobj); + EXLATEOBJ_vCleanup(&exlo); + } } else { @@ -352,7 +374,15 @@ if (psoColor) { /* Color bitmap must have the same format as the dest surface */ - if (psoColor->iBitmapFormat != pso->iBitmapFormat) goto failure; + if (psoColor->iBitmapFormat != pso->iBitmapFormat) + { + /* It's OK if we have an alpha bitmap */ + if(!(fl & SPS_ALPHA)) + { + DPRINT1("Screen surface and cursor color bitmap format don't match!.\n"); + goto failure; + } + } /* Create a bitmap to copy the color bitmap to */ hbmColor = EngCreateBitmap(psoColor->sizlBitmap, @@ -452,6 +482,7 @@ pgp->HotSpot.x = xHot; pgp->HotSpot.y = yHot; pgp->Size = sizel; + pgp->flags = fl; if (x != -1) { @@ -598,12 +629,12 @@ LONG xHot, LONG yHot, LONG x, - LONG y) + LONG y, + FLONG fl) { PDC pdc; PSURFACE psurf, psurfMask, psurfColor; EXLATEOBJ exlo; - FLONG fl = 0; ULONG ulResult = 0; pdc = DC_LockDc(hdc); @@ -629,7 +660,10 @@ if (hbmMask) psurfMask = SURFACE_ShareLockSurface(hbmMask); else + { + ASSERT(fl & SPS_ALPHA); psurfMask = NULL; + } /* Check for color bitmap */ if (hbmColor) @@ -645,6 +679,9 @@ } else psurfColor = NULL; + + /* We must have a valid surface in case of alpha bitmap */ + ASSERT(((fl & SPS_ALPHA) && psurfColor) || !(fl & SPS_ALPHA)); /* Call the driver or eng function */ ulResult = IntEngSetPointerShape(&psurf->SurfObj, Modified: trunk/reactos/win32ss/gdi/eng/mouse.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/eng/mouse.h?rev=57695&r1=57694&r2=57695&view=diff ============================================================================== --- trunk/reactos/win32ss/gdi/eng/mouse.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/eng/mouse.h [iso-8859-1] Sat Nov 10 15:56:42 2012 @@ -12,7 +12,8 @@ LONG xHot, LONG yHot, LONG x, - LONG y); + LONG y, + FLONG fl); VOID NTAPI Modified: trunk/reactos/win32ss/gdi/eng/pdevobj.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/gdi/eng/pdevobj.h?rev=57695&r1=57694&r2=57695&view=diff ============================================================================== --- trunk/reactos/win32ss/gdi/eng/pdevobj.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/gdi/eng/pdevobj.h [iso-8859-1] Sat Nov 10 15:56:42 2012 @@ -34,6 +34,7 @@ SURFACE *psurfColor; SURFACE *psurfMask; SURFACE *psurfSave; + FLONG flags; /* Public pointer information */ RECTL Exclude; /* Required publicly for SPS_ACCEPT_EXCLUDE */ Modified: trunk/reactos/win32ss/user/ntuser/cursoricon_new.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/cursoricon_new.c?rev=57695&r1=57694&r2=57695&view=diff ============================================================================== --- trunk/reactos/win32ss/user/ntuser/cursoricon_new.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/cursoricon_new.c [iso-8859-1] Sat Nov 10 15:56:42 2012 @@ -923,7 +923,6 @@ PCURICON_OBJECT CurIcon; NTSTATUS Status = STATUS_SUCCESS; BOOL Ret = FALSE; - CURSORDATA dataSafe; TRACE("Enter NtUserSetCursorIconData\n"); @@ -943,7 +942,15 @@ _SEH2_TRY { ProbeForRead(pCursorData, sizeof(*pCursorData), 1); - RtlCopyMemory(&dataSafe, pCursorData, sizeof(dataSafe)); + CurIcon->xHotspot = pCursorData->xHotspot; + CurIcon->yHotspot = pCursorData->yHotspot; + CurIcon->cx = pCursorData->cx; + CurIcon->cy = pCursorData->cy; + CurIcon->rt = pCursorData->rt; + CurIcon->bpp = pCursorData->bpp; + CurIcon->hbmMask = pCursorData->hbmMask; + CurIcon->hbmColor = pCursorData->hbmColor; + CurIcon->hbmAlpha = pCursorData->hbmAlpha; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -955,41 +962,6 @@ { SetLastNtError(Status); goto done; - } - - CurIcon->xHotspot = dataSafe.xHotspot; - CurIcon->yHotspot = dataSafe.yHotspot; - CurIcon->cx = dataSafe.cx; - CurIcon->cy = dataSafe.cy; - CurIcon->rt = dataSafe.rt; - CurIcon->bpp = dataSafe.bpp; - - if(!dataSafe.hbmMask) - { - ERR("NtUserSetCursorIconData was got no hbmMask.\n"); - EngSetLastError(ERROR_INVALID_PARAMETER); - goto done; - } - - CurIcon->hbmMask = BITMAP_CopyBitmap(dataSafe.hbmMask); - if(!CurIcon->hbmMask) - goto done; - GreSetObjectOwner(CurIcon->hbmMask, GDI_OBJ_HMGR_PUBLIC); - - if(dataSafe.hbmColor) - { - CurIcon->hbmColor = BITMAP_CopyBitmap(dataSafe.hbmColor); - if(!CurIcon->hbmColor) - goto done; - GreSetObjectOwner(CurIcon->hbmColor, GDI_OBJ_HMGR_PUBLIC); - } - - if(dataSafe.hbmAlpha) - { - CurIcon->hbmAlpha = BITMAP_CopyBitmap(dataSafe.hbmAlpha); - if(!CurIcon->hbmAlpha) - goto done; - GreSetObjectOwner(CurIcon->hbmAlpha, GDI_OBJ_HMGR_PUBLIC); } if(pustrModule) @@ -1002,30 +974,28 @@ if(!NT_SUCCESS(Status)) goto done; } + + + if(!CurIcon->hbmMask) + { + ERR("NtUserSetCursorIconData was got no hbmMask.\n"); + EngSetLastError(ERROR_INVALID_PARAMETER); + goto done; + } + + GreSetObjectOwner(CurIcon->hbmMask, GDI_OBJ_HMGR_PUBLIC); + + if(CurIcon->hbmColor) + GreSetObjectOwner(CurIcon->hbmColor, GDI_OBJ_HMGR_PUBLIC); + + if(CurIcon->hbmAlpha) + GreSetObjectOwner(CurIcon->hbmAlpha, GDI_OBJ_HMGR_PUBLIC); Ret = TRUE; done: if(!Ret) { - if (CurIcon->hbmMask) - { - GreSetObjectOwner(CurIcon->hbmMask, GDI_OBJ_HMGR_POWNED); - GreDeleteObject(CurIcon->hbmMask); - CurIcon->hbmMask = NULL; - } - if (CurIcon->hbmColor) - { - GreSetObjectOwner(CurIcon->hbmColor, GDI_OBJ_HMGR_POWNED); - GreDeleteObject(CurIcon->hbmColor); - CurIcon->hbmColor = NULL; - } - if (CurIcon->hbmAlpha) - { - GreSetObjectOwner(CurIcon->hbmAlpha, GDI_OBJ_HMGR_POWNED); - GreDeleteObject(CurIcon->hbmAlpha); - CurIcon->hbmAlpha = NULL; - } if(!IS_INTRESOURCE(CurIcon->strName.Buffer)) ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING); if(CurIcon->ustrModule.Buffer) Modified: trunk/reactos/win32ss/user/ntuser/msgqueue.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/msgqueue.c?rev=57695&r1=57694&r2=57695&view=diff ============================================================================== --- trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] Sat Nov 10 15:56:42 2012 @@ -147,12 +147,13 @@ /* Call GDI to set the new screen cursor */ #ifdef NEW_CURSORICON GreSetPointerShape(hdcScreen, - NewCursor->hbmMask, - NewCursor->hbmColor, + NewCursor->hbmAlpha ? NULL : NewCursor->hbmMask, + NewCursor->hbmAlpha ? NewCursor->hbmAlpha : NewCursor->hbmColor, NewCursor->xHotspot, NewCursor->yHotspot, gpsi->ptCursor.x, - gpsi->ptCursor.y); + gpsi->ptCursor.y, + NewCursor->hbmAlpha ? SPS_ALPHA : 0); #else GreSetPointerShape(hdcScreen, NewCursor->IconInfo.hbmMask, @@ -160,7 +161,8 @@ NewCursor->IconInfo.xHotspot, NewCursor->IconInfo.yHotspot, gpsi->ptCursor.x, - gpsi->ptCursor.y); + gpsi->ptCursor.y, + 0); #endif } else /* Note: OldCursor != NewCursor so we have to hide cursor */ @@ -582,13 +584,16 @@ { /* Call GDI to set the new screen cursor */ #ifdef NEW_CURSORICON - GreSetPointerShape(hdcScreen, - MessageQueue->CursorObject->hbmMask, - MessageQueue->CursorObject->hbmColor, - MessageQueue->CursorObject->xHotspot, - MessageQueue->CursorObject->yHotspot, - gpsi->ptCursor.x, - gpsi->ptCursor.y); + GreSetPointerShape(hdcScreen, + MessageQueue->CursorObject->hbmAlpha ? + NULL : MessageQueue->CursorObject->hbmMask, + MessageQueue->CursorObject->hbmAlpha ? + MessageQueue->CursorObject->hbmAlpha : MessageQueue->CursorObject->hbmColor, + MessageQueue->CursorObject->xHotspot, + MessageQueue->CursorObject->yHotspot, + gpsi->ptCursor.x, + gpsi->ptCursor.y, + MessageQueue->CursorObject->hbmAlpha ? SPS_ALPHA : 0); #else GreSetPointerShape(hdcScreen, MessageQueue->CursorObject->IconInfo.hbmMask, @@ -596,7 +601,8 @@ MessageQueue->CursorObject->IconInfo.xHotspot, MessageQueue->CursorObject->IconInfo.yHotspot, gpsi->ptCursor.x, - gpsi->ptCursor.y); + gpsi->ptCursor.y, + 0); #endif } else GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y); Modified: trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c?rev=57695&r1=57694&r2=57695&view=diff ============================================================================== --- trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/user32/windows/cursoricon_new.c [iso-8859-1] Sat Nov 10 15:56:42 2012 @@ -906,24 +906,26 @@ hCurIcon = NtUserxCreateEmptyCurObject(bIcon ? 0 : 1); if(!hCurIcon) - goto end_clean; + goto end_error; /* Tell win32k */ if(!NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData)) { NtUserDestroyCursor(hCurIcon, TRUE); - hCurIcon = NULL; - } - - /* Clean up */ -end_clean: + goto end_error; + } + +end: + UnmapViewOfFile(bits); + return hCurIcon; + + /* Clean up */ +end_error: DeleteObject(cursorData.hbmMask); if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha); -end: - UnmapViewOfFile(bits); - return hCurIcon; + return NULL; } static @@ -1078,36 +1080,44 @@ if(!bStatus) goto done; + /* This is from resource */ + cursorData.CURSORF_flags = CURSORF_FROMRESOURCE; + /* Create the handle */ hCurIcon = NtUserxCreateEmptyCurObject(bIcon ? 0 : 1); if(!hCurIcon) { - DeleteObject(cursorData.hbmMask); - if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); - if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha); - goto done; + goto end_error; } /* Tell win32k */ if(fuLoad & LR_SHARED) + { + cursorData.CURSORF_flags |= CURSORF_LRSHARED; bStatus = NtUserSetCursorIconData(hCurIcon, &ustrModule, &ustrRsrc, &cursorData); + } else bStatus = NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData); if(!bStatus) { NtUserDestroyCursor(hCurIcon, TRUE); - hCurIcon = NULL; - } - - DeleteObject(cursorData.hbmMask); - if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); - if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha); + goto end_error; + } done: if(ustrModule.Buffer) HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); return hCurIcon; + +end_error: + if(ustrModule.Buffer) + HeapFree(GetProcessHeap(), 0, ustrModule.Buffer); + DeleteObject(cursorData.hbmMask); + if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); + if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha); + + return NULL; } static @@ -1912,54 +1922,60 @@ hIcon = NtUserxCreateEmptyCurObject(fIcon ? 0 : 1); if(!hIcon) - return NULL; + goto end_error; if(!NtUserSetCursorIconData(hIcon, NULL, NULL, &cursorData)) { ERR("NtUserSetCursorIconData failed.\n"); NtUserDestroyCursor(hIcon, TRUE); - hIcon = NULL; - } - + goto end_error; + } + + return hIcon; + + /* Clean up */ +end_error: + DeleteObject(cursorData.hbmMask); + if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); + if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha); + + return NULL; +} + +HICON WINAPI CreateIconIndirect( + _In_ PICONINFO piconinfo +) +{ + /* As simple as creating a handle, and let win32k deal with the bitmaps */ + HICON hiconRet; + CURSORDATA cursorData; + + TRACE("%p.\n", piconinfo); + + if(!CURSORICON_GetCursorDataFromIconInfo(&cursorData, piconinfo)) + return NULL; + + hiconRet = NtUserxCreateEmptyCurObject(piconinfo->fIcon ? 0 : 1); + if(!hiconRet) + goto end_error; + + if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, &cursorData)) + { + NtUserDestroyCursor(hiconRet, FALSE); + goto end_error; + } + + TRACE("Returning 0x%08x.\n", hiconRet); + + return hiconRet; + +end_error: /* Clean up */ DeleteObject(cursorData.hbmMask); if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha); - return hIcon; -} - -HICON WINAPI CreateIconIndirect( - _In_ PICONINFO piconinfo -) -{ - /* As simple as creating a handle, and let win32k deal with the bitmaps */ - HICON hiconRet; - CURSORDATA cursorData; - - TRACE("%p.\n", piconinfo); - - if(!CURSORICON_GetCursorDataFromIconInfo(&cursorData, piconinfo)) - return NULL; - - hiconRet = NtUserxCreateEmptyCurObject(piconinfo->fIcon ? 0 : 1); - if(!hiconRet) - return NULL; - - if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, &cursorData)) - { - NtUserDestroyCursor(hiconRet, FALSE); - hiconRet = NULL; - } - - /* Clean up */ - DeleteObject(cursorData.hbmMask); - if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor); - if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha); - - TRACE("Returning 0x%08x.\n", hiconRet); - - return hiconRet; + return NULL; } HCURSOR WINAPI CreateCursor(