- 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

svn path=/trunk/; revision=57695
This commit is contained in:
Jérôme Gardou 2012-11-10 15:56:42 +00:00
parent cde9a5f895
commit 6f481467d5
6 changed files with 149 additions and 118 deletions

View file

@ -232,29 +232,51 @@ IntShowMousePointer(PDEVOBJ *ppdev, SURFOBJ *psoDest)
/* 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));
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_FROM_INDEX(R3_OPINDEX_SRCINVERT));
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 @@ EngSetPointerShape(
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 @@ EngSetPointerShape(
pgp->HotSpot.x = xHot;
pgp->HotSpot.y = yHot;
pgp->Size = sizel;
pgp->flags = fl;
if (x != -1)
{
@ -598,12 +629,12 @@ GreSetPointerShape(
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 @@ GreSetPointerShape(
if (hbmMask)
psurfMask = SURFACE_ShareLockSurface(hbmMask);
else
{
ASSERT(fl & SPS_ALPHA);
psurfMask = NULL;
}
/* Check for color bitmap */
if (hbmColor)
@ -645,6 +679,9 @@ GreSetPointerShape(
}
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,

View file

@ -12,7 +12,8 @@ GreSetPointerShape(
LONG xHot,
LONG yHot,
LONG x,
LONG y);
LONG y,
FLONG fl);
VOID
NTAPI

View file

@ -34,6 +34,7 @@ typedef struct _GDIPOINTER /* should stay private to ENG? No, part of PDEVOBJ ak
SURFACE *psurfColor;
SURFACE *psurfMask;
SURFACE *psurfSave;
FLONG flags;
/* Public pointer information */
RECTL Exclude; /* Required publicly for SPS_ACCEPT_EXCLUDE */

View file

@ -923,7 +923,6 @@ NtUserSetCursorIconData(
PCURICON_OBJECT CurIcon;
NTSTATUS Status = STATUS_SUCCESS;
BOOL Ret = FALSE;
CURSORDATA dataSafe;
TRACE("Enter NtUserSetCursorIconData\n");
@ -943,7 +942,15 @@ NtUserSetCursorIconData(
_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)
{
@ -956,41 +963,6 @@ NtUserSetCursorIconData(
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 @@ NtUserSetCursorIconData(
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)

View file

@ -147,12 +147,13 @@ UserSetCursor(
/* 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 @@ UserSetCursor(
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 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
{
/* 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 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
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);

View file

@ -906,24 +906,26 @@ CURSORICON_LoadFromFileW(
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;
goto end_error;
}
/* Clean up */
end_clean:
DeleteObject(cursorData.hbmMask);
if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
end:
UnmapViewOfFile(bits);
return hCurIcon;
/* Clean up */
end_error:
DeleteObject(cursorData.hbmMask);
if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
return NULL;
}
static
@ -1078,36 +1080,44 @@ CURSORICON_LoadImageW(
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;
goto end_error;
}
DeleteObject(cursorData.hbmMask);
if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
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,21 +1922,24 @@ HICON WINAPI CreateIconFromResourceEx(
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 hIcon;
return NULL;
}
HICON WINAPI CreateIconIndirect(
@ -1944,22 +1957,25 @@ HICON WINAPI CreateIconIndirect(
hiconRet = NtUserxCreateEmptyCurObject(piconinfo->fIcon ? 0 : 1);
if(!hiconRet)
return NULL;
goto end_error;
if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, &cursorData))
{
NtUserDestroyCursor(hiconRet, FALSE);
hiconRet = NULL;
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);
TRACE("Returning 0x%08x.\n", hiconRet);
return hiconRet;
return NULL;
}
HCURSOR WINAPI CreateCursor(