return NULL;
}
- CurIcon = (PCURICON_OBJECT)UserReferenceObjectByHandle(hCurIcon, otCursorIcon);
+ CurIcon = (PCURICON_OBJECT)UserReferenceObjectByHandle(hCurIcon, TYPE_CURSOR);
if (!CurIcon)
{
/* We never set ERROR_INVALID_ICON_HANDLE. lets hope noone ever checks for it */
LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry)
{
- // if (NT_SUCCESS(UserReferenceObjectByPointer(Object, otCursorIcon))) // <- huh????
+ // if (NT_SUCCESS(UserReferenceObjectByPointer(Object, TYPE_CURSOR))) // <- huh????
// UserReferenceObject( CurIcon);
// {
if ((CurIcon->hModule == hModule) && (CurIcon->hRsrc == hRsrc))
return NULL;
}
-PCURICON_OBJECT
-IntCreateCurIconHandle()
+HANDLE
+IntCreateCurIconHandle(BOOLEAN Anim)
{
PCURICON_OBJECT CurIcon;
HANDLE hCurIcon;
- CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
+ CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, TYPE_CURSOR, sizeof(CURICON_OBJECT));
if (!CurIcon)
{
CurIcon->Self = hCurIcon;
InitializeListHead(&CurIcon->ProcessList);
- if (! ReferenceCurIconByProcess(CurIcon))
+ if (!ReferenceCurIconByProcess(CurIcon))
{
ERR("Failed to add process\n");
- UserDeleteObject(hCurIcon, otCursorIcon);
+ UserDeleteObject(hCurIcon, TYPE_CURSOR);
UserDereferenceObject(CurIcon);
return NULL;
}
InsertHeadList(&gCurIconList, &CurIcon->ListEntry);
- return CurIcon;
+ UserDereferenceObject(CurIcon);
+
+ return hCurIcon;
}
BOOLEAN FASTCALL
IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
{
PSYSTEM_CURSORINFO CurInfo;
- HBITMAP bmpMask, bmpColor, bmpAlpha;
+ HBITMAP bmpMask, bmpColor;
BOOLEAN Ret, bListEmpty, bFound = FALSE;
PCURICON_PROCESS Current = NULL;
-
+
/* For handles created without any data (error handling) */
if(IsListEmpty(&CurIcon->ProcessList))
goto emptyList;
break;
}
}
-
+
if(!bFound)
{
/* This object doesn't belong to this process */
{
/* Set the first process of the list as owner */
Current = CONTAINING_RECORD(CurIcon->ProcessList.Flink, CURICON_PROCESS, ListEntry);
- UserSetObjectOwner(CurIcon, otCursorIcon, Current->Process);
+ UserSetObjectOwner(CurIcon, TYPE_CURSOR, Current->Process);
}
UserDereferenceObject(CurIcon);
return TRUE;
UserSetCursor(NULL, TRUE);
}
- bmpMask = CurIcon->aFrame[0].hbmMask;
- bmpColor = CurIcon->aFrame[0].hbmColor;
- bmpAlpha = CurIcon->aFrame[0].hbmAlpha;
+ bmpMask = CurIcon->IconInfo.hbmMask;
+ bmpColor = CurIcon->IconInfo.hbmColor;
/* Delete bitmaps */
if (bmpMask)
{
GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(bmpMask);
- CurIcon->aFrame[0].hbmMask = NULL;
+ CurIcon->IconInfo.hbmMask = NULL;
}
if (bmpColor)
{
GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(bmpColor);
- CurIcon->aFrame[0].hbmColor = NULL;
- }
- if (bmpAlpha)
- {
- GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED);
- GreDeleteObject(bmpAlpha);
- CurIcon->aFrame[0].hbmAlpha = NULL;
+ CurIcon->IconInfo.hbmColor = NULL;
}
/* We were given a pointer, no need to keep the reference anylonger! */
UserDereferenceObject(CurIcon);
- Ret = UserDeleteObject(CurIcon->Self, otCursorIcon);
+ Ret = UserDeleteObject(CurIcon->Self, TYPE_CURSOR);
return Ret;
}
{
goto leave;
}
-
- /* Fill data */
- ii.fIcon = CurIcon->bIcon;
- ii.xHotspot = CurIcon->ptlHotspot.x;
- ii.yHotspot = CurIcon->ptlHotspot.y;
+
+ RtlCopyMemory(&ii, &CurIcon->IconInfo, sizeof(ICONINFO));
/* Copy bitmaps */
- ii.hbmMask = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmMask);
- ii.hbmColor = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmColor);
+ ii.hbmMask = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmMask);
+ ii.hbmColor = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmColor);
if (pbpp)
{
PSURFACE psurfBmp;
- psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
+ psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmColor);
if (psurfBmp)
{
colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
ProbeForWrite(IconInfo, sizeof(ICONINFO), 1);
RtlCopyMemory(IconInfo, &ii, sizeof(ICONINFO));
+ /// @todo Implement support for lpInstName
+ if (lpInstName)
+ {
+ RtlInitEmptyUnicodeString(lpInstName, NULL, 0);
+ }
+
+ /// @todo Implement support for lpResName
+ if (lpResName)
+ {
+ RtlInitEmptyUnicodeString(lpResName, NULL, 0);
+ }
+
if (pbpp)
{
ProbeForWrite(pbpp, sizeof(DWORD), 1);
BOOL
APIENTRY
NtUserDestroyCursor(
- HANDLE hCurIcon,
- DWORD Unknown)
+ _In_ HANDLE hCurIcon,
+ _In_ BOOL bForce)
{
PCURICON_OBJECT CurIcon;
BOOL ret;
goto done;
}
-#if 0
- /* Check if we get valid information */
- if(IconInfo.fIcon != CurInfo->bIcon)
+ /* Delete old bitmaps */
+ if ((CurIcon->IconInfo.hbmColor)
+ && (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor))
{
- EngSetLastError(ERROR_INVALID_PARAMETER);
- goto done;
+ GreDeleteObject(CurIcon->IconInfo.hbmColor);
+ }
+ if ((CurIcon->IconInfo.hbmMask)
+ && CurIcon->IconInfo.hbmMask != IconInfo.hbmMask)
+ {
+ GreDeleteObject(CurIcon->IconInfo.hbmMask);
}
-#endif
- /* Delete old bitmaps */
- if (CurIcon->aFrame[0].hbmColor)
- GreDeleteObject(CurIcon->aFrame[0].hbmColor);
- if (CurIcon->aFrame[0].hbmMask)
- GreDeleteObject(CurIcon->aFrame[0].hbmMask);
- if(CurIcon->aFrame[0].hbmAlpha)
- GreDeleteObject(CurIcon->aFrame[0].hbmAlpha);
-
- /* Set fields */
- CurIcon->bIcon = IconInfo.fIcon;
- CurIcon->ptlHotspot.x = IconInfo.xHotspot;
- CurIcon->ptlHotspot.y = IconInfo.yHotspot;
- CurIcon->aFrame[0].hbmMask = IconInfo.hbmMask;
- CurIcon->aFrame[0].hbmColor = IconInfo.hbmColor;
- CurIcon->aFrame[0].hbmAlpha = NULL;
-
- if (IconInfo.hbmColor)
- {
- BOOLEAN bAlpha = FALSE;
- psurfBmp = SURFACE_ShareLockSurface(IconInfo.hbmColor);
+ /* Copy new IconInfo field */
+ CurIcon->IconInfo = IconInfo;
+
+ if (CurIcon->IconInfo.hbmColor)
+ {
+ psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmColor);
if (!psurfBmp)
goto done;
+
CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
-
- /* 32bpp bitmap is likely to have an alpha channel */
- if(psurfBmp->SurfObj.iBitmapFormat == BMF_32BPP)
- {
- PFN_DIB_GetPixel fn_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel;
- INT i, j;
-
- fn_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel;
- for (i = 0; i < psurfBmp->SurfObj.sizlBitmap.cx; i++)
- {
- for (j = 0; j < psurfBmp->SurfObj.sizlBitmap.cy; j++)
- {
- bAlpha = ((BYTE)(fn_GetPixel(&psurfBmp->SurfObj, i, j) >> 24)) != 0;
- if (bAlpha)
- break;
- }
- if (bAlpha)
- break;
- }
- }
- /* We're done with this one */
SURFACE_ShareUnlockSurface(psurfBmp);
- GreSetObjectOwner(IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
-
- if(bAlpha)
- {
- UCHAR Alpha;
- PUCHAR ptr;
- INT i, j;
- /* Copy the bitmap */
- CurIcon->aFrame[0].hbmAlpha = BITMAP_CopyBitmap(IconInfo.hbmColor);
- if(!CurIcon->aFrame[0].hbmAlpha)
- {
- ERR("BITMAP_CopyBitmap failed!");
- goto done;
- }
-
- psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmAlpha);
- if(!psurfBmp)
- {
- ERR("SURFACE_LockSurface failed!\n");
- goto done;
- }
-
- /* Premultiply with the alpha channel value */
- for (i = 0; i < psurfBmp->SurfObj.sizlBitmap.cy; i++)
- {
- ptr = (PBYTE)psurfBmp->SurfObj.pvScan0 + i*psurfBmp->SurfObj.lDelta;
- for (j = 0; j < psurfBmp->SurfObj.sizlBitmap.cx; j++)
- {
- Alpha = ptr[3];
- ptr[0] = (ptr[0] * Alpha) / 0xff;
- ptr[1] = (ptr[1] * Alpha) / 0xff;
- ptr[2] = (ptr[2] * Alpha) / 0xff;
- ptr += 4;
- }
- }
- SURFACE_ShareUnlockSurface(psurfBmp);
- GreSetObjectOwner(CurIcon->aFrame[0].hbmAlpha, GDI_OBJ_HMGR_PUBLIC);
- }
+ GreSetObjectOwner(CurIcon->IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
}
else
{
- psurfBmp = SURFACE_ShareLockSurface(IconInfo.hbmMask);
+ psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmMask);
if (!psurfBmp)
goto done;
SURFACE_ShareUnlockSurface(psurfBmp);
}
- GreSetObjectOwner(IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
+ GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
Ret = TRUE;
done:
- if(!Ret)
- {
- IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
- CurIcon = NULL;
- }
-
if (CurIcon)
{
UserDereferenceObject(CurIcon);
/*
* @implemented
*/
-#ifdef NEW_CURSORICON
+#if 0
BOOL
APIENTRY
NtUserSetCursorIconData(
- _In_ HCURSOR Handle,
- _In_ HINSTANCE hinst,
- _In_ HRSRC hrsrc,
- _In_ PICONINFO pIconInfo)
+ HANDLE Handle,
+ HMODULE hModule,
+ PUNICODE_STRING pstrResName,
+ PICONINFO pIconInfo)
{
PCURICON_OBJECT CurIcon;
PSURFACE psurfBmp;
NTSTATUS Status = STATUS_SUCCESS;
BOOL Ret = FALSE;
DECLARE_RETURN(BOOL);
- ICONINFO ii;
TRACE("Enter NtUserSetCursorIconData\n");
UserEnterExclusive();
RETURN(FALSE);
}
- CurIcon->hModule = hinst;
- CurIcon->hRsrc =hrsrc;
+ CurIcon->hModule = hModule;
+ CurIcon->hRsrc = NULL; //hRsrc;
+ CurIcon->hGroupRsrc = NULL; //hGroupRsrc;
_SEH2_TRY
{
ProbeForRead(pIconInfo, sizeof(ICONINFO), 1);
- ii = *pIconInfo;
+ RtlCopyMemory(&CurIcon->IconInfo, pIconInfo, sizeof(ICONINFO));
+
+ CurIcon->IconInfo.hbmMask = BITMAP_CopyBitmap(pIconInfo->hbmMask);
+ CurIcon->IconInfo.hbmColor = BITMAP_CopyBitmap(pIconInfo->hbmColor);
+
+ if (CurIcon->IconInfo.hbmColor)
+ {
+ if ((psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmColor)))
+ {
+ CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
+ CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
+ SURFACE_UnlockSurface(psurfBmp);
+ GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
+ }
+ }
+ if (CurIcon->IconInfo.hbmMask)
+ {
+ if (CurIcon->IconInfo.hbmColor == NULL)
+ {
+ if ((psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmMask)))
+ {
+ CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
+ CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
+ SURFACE_UnlockSurface(psurfBmp);
+ }
+ }
+ GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
+ }
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END
-
+
if (!NT_SUCCESS(Status))
- {
SetLastNtError(Status);
- goto done;
- }
-
- /* This is probably not what windows does, but consistency checks can't hurt */
- if(CurIcon->bIcon != ii.fIcon)
- {
- EngSetLastError(ERROR_INVALID_PARAMETER);
- goto done;
- }
- CurIcon->ptlHotspot.x = ii.xHotspot;
- CurIcon->ptlHotspot.y = ii.yHotspot;
-
- if(!ii.hbmMask)
- {
- EngSetLastError(ERROR_INVALID_PARAMETER);
- goto done;
- }
-
- CurIcon->aFrame[0].hbmMask = BITMAP_CopyBitmap(ii.hbmMask);
- if(!CurIcon->aFrame[0].hbmMask)
- goto done;
-
- if(ii.hbmColor)
- {
- CurIcon->aFrame[0].hbmColor = BITMAP_CopyBitmap(ii.hbmColor);
- if(!CurIcon->aFrame[0].hbmColor)
- goto done;
- }
-
- if (CurIcon->aFrame[0].hbmColor)
- {
- if ((psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor)))
- {
- CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
- CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
- SURFACE_ShareUnlockSurface(psurfBmp);
- GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
- }
- else
- goto done;
- }
else
- {
- if ((psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmMask)))
- {
- CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
- CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy/2;
- SURFACE_ShareUnlockSurface(psurfBmp);
- }
- else
- goto done;
- }
- GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
-
- Ret = TRUE;
+ Ret = TRUE;
-done:
UserDereferenceObject(CurIcon);
- if(!Ret)
- {
- if (CurIcon->aFrame[0].hbmMask)
- {
- GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_POWNED);
- GreDeleteObject(CurIcon->aFrame[0].hbmMask);
- CurIcon->aFrame[0].hbmMask = NULL;
- }
- if (CurIcon->aFrame[0].hbmColor)
- {
- GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_POWNED);
- GreDeleteObject(CurIcon->aFrame[0].hbmColor);
- CurIcon->aFrame[0].hbmColor = NULL;
- }
- }
RETURN(Ret);
CLEANUP:
{
PCURICON_OBJECT CurIcon;
NTSTATUS Status;
+ POINT SafeHotspot;
BOOL Ret = FALSE;
DECLARE_RETURN(BOOL);
/* Copy fields */
if (fIcon)
{
- Status = MmCopyFromCaller(&CurIcon->bIcon, fIcon, sizeof(BOOL));
+ Status = MmCopyFromCaller(&CurIcon->IconInfo.fIcon, fIcon, sizeof(BOOL));
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
if (Hotspot)
{
- Status = MmCopyFromCaller(&CurIcon->ptlHotspot, Hotspot, sizeof(POINT));
- if (!NT_SUCCESS(Status))
+ Status = MmCopyFromCaller(&SafeHotspot, Hotspot, sizeof(POINT));
+ if (NT_SUCCESS(Status))
{
- SetLastNtError(Status);
- goto done;
+ CurIcon->IconInfo.xHotspot = SafeHotspot.x;
+ CurIcon->IconInfo.yHotspot = SafeHotspot.y;
+
+ Ret = TRUE;
}
+ else
+ SetLastNtError(Status);
}
if (!fIcon && !Hotspot)
if(Ret)
{
/* This icon is shared now */
- GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
- if(CurIcon->aFrame[0].hbmColor)
- {
- GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_PUBLIC);
- }
- if(CurIcon->aFrame[0].hbmAlpha)
+ GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
+ if(CurIcon->IconInfo.hbmColor)
{
- GreSetObjectOwner(CurIcon->aFrame[0].hbmAlpha, GDI_OBJ_HMGR_PUBLIC);
+ GreSetObjectOwner(CurIcon->IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
}
}
UserDereferenceObject(CurIcon);
PSURFACE psurfDest, psurfMask, psurfColor, psurfOffScreen;
PDC pdc = NULL;
BOOL Ret = FALSE;
- HBITMAP hbmMask, hbmColor, hbmAlpha;
- BOOL bOffScreen;
+ HBITMAP hbmMask, hbmColor;
+ BOOL bOffScreen, bAlpha = FALSE;
RECTL rcDest, rcSrc;
CLIPOBJ* pdcClipObj = NULL;
EXLATEOBJ exlo;
-
+
/* Stupid case */
if((diFlags & DI_NORMAL) == 0)
{
return FALSE;
}
- hbmMask = pIcon->aFrame[0].hbmMask;
- hbmColor = pIcon->aFrame[0].hbmColor;
- hbmAlpha = pIcon->aFrame[0].hbmAlpha;
-
+ hbmMask = pIcon->IconInfo.hbmMask;
+ hbmColor = pIcon->IconInfo.hbmColor;
+
if (istepIfAniCur)
ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
-
+
/*
- * Get our objects.
+ * Get our objects.
* Shared locks are enough, we are only reading those bitmaps
*/
psurfMask = SURFACE_ShareLockSurface(hbmMask);
ERR("Unable to lock the mask surface.\n");
return FALSE;
}
-
+
/* Color bitmap is not mandatory */
if(hbmColor == NULL)
{
SURFACE_ShareUnlockSurface(psurfMask);
return FALSE;
}
-
+
/* Set source rect */
RECTL_vSetRect(&rcSrc, 0, 0, pIcon->Size.cx, pIcon->Size.cy);
+ /* Check for alpha */
+ if (psurfColor &&
+ (psurfColor->SurfObj.iBitmapFormat == BMF_32BPP) &&
+ (diFlags & DI_IMAGE))
+ {
+ PFN_DIB_GetPixel fnSource_GetPixel = NULL;
+ INT i, j;
+
+ /* In order to correctly display 32 bit icons Windows first scans the image,
+ because information about transparency is not stored in any image's headers */
+ fnSource_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel;
+ for (i = 0; i < psurfColor->SurfObj.sizlBitmap.cx; i++)
+ {
+ for (j = 0; j < psurfColor->SurfObj.sizlBitmap.cy; j++)
+ {
+ bAlpha = ((BYTE)(fnSource_GetPixel(&psurfColor->SurfObj, i, j) >> 24) & 0xff);
+ if (bAlpha)
+ break;
+ }
+ if (bAlpha)
+ break;
+ }
+ }
+
/* Fix width parameter, if needed */
if (!cxWidth)
{
if(diFlags & DI_DEFAULTSIZE)
- cxWidth = pIcon->bIcon ?
+ cxWidth = pIcon->IconInfo.fIcon ?
UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR);
else
cxWidth = pIcon->Size.cx;
}
-
+
/* Fix height parameter, if needed */
if (!cyHeight)
{
if(diFlags & DI_DEFAULTSIZE)
- cyHeight = pIcon->bIcon ?
+ cyHeight = pIcon->IconInfo.fIcon ?
UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR);
else
cyHeight = pIcon->Size.cy;
/* Yes: Allocate and paint the offscreen surface */
EBRUSHOBJ eboFill;
PBRUSH pbrush = BRUSH_ShareLockBrush(hbrFlickerFreeDraw);
-
+
TRACE("Performing off-screen rendering.\n");
-
+
if(!pbrush)
{
ERR("Failed to get brush object.\n");
return FALSE;
}
+ if (!psurfColor)
+ {
+ ERR("Attention HAX FIX API DrawIconEx TEST Line 37: psurfColor is NULL going with Mask!\n");
+ psurfColor = SURFACE_ShareLockSurface(hbmMask);
+ }
+
psurfOffScreen = SURFACE_AllocSurface(STYPE_BITMAP,
cxWidth, cyHeight, psurfColor->SurfObj.iBitmapFormat,
0, 0, NULL);
BRUSH_ShareUnlockBrush(pbrush);
return FALSE;
}
-
+
/* Paint the brush */
EBRUSHOBJ_vInit(&eboFill, pbrush, psurfOffScreen, 0x00FFFFFF, 0, NULL);
RECTL_vSetRect(&rcDest, 0, 0, cxWidth, cyHeight);
-
+
Ret = IntEngBitBlt(&psurfOffScreen->SurfObj,
NULL,
NULL,
/* Clean up everything */
EBRUSHOBJ_vCleanup(&eboFill);
BRUSH_ShareUnlockBrush(pbrush);
-
+
if(!Ret)
{
ERR("Failed to paint the off-screen surface.\n");
GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
return FALSE;
}
-
+
/* We now have our destination surface */
psurfDest = psurfOffScreen;
}
{
/* We directly draw to the DC */
TRACE("Performing on screen rendering.\n");
-
+
psurfOffScreen = NULL;
pdc = DC_LockDc(hDc);
if(!pdc)
RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
-
+
/* Prepare the underlying surface */
DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
-
+
/* Get the clip object */
pdcClipObj = pdc->rosdc.CombinedClip;
-
+
/* We now have our destination surface and rectangle */
psurfDest = pdc->dclevel.pSurface;
-
+
if(psurfDest == NULL)
{
/* Empty DC */
}
/* Now do the rendering */
- if(hbmAlpha && (diFlags & DI_IMAGE))
+ if(bAlpha && (diFlags & DI_IMAGE))
{
BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } };
+ BYTE Alpha;
+ INT i, j;
PSURFACE psurf = NULL;
+ PBYTE ptr ;
+ HBITMAP hsurfCopy = NULL;
+
+ hsurfCopy = BITMAP_CopyBitmap(hbmColor);
+ if(!hsurfCopy)
+ {
+ ERR("BITMAP_CopyBitmap failed!");
+ goto CleanupAlpha;
+ }
- psurf = SURFACE_ShareLockSurface(hbmAlpha);
+ psurf = SURFACE_ShareLockSurface(hsurfCopy);
if(!psurf)
{
ERR("SURFACE_LockSurface failed!\n");
- goto NoAlpha;
+ goto CleanupAlpha;
}
-
+
+ /* Premultiply with the alpha channel value */
+ for (i = 0; i < psurf->SurfObj.sizlBitmap.cy; i++)
+ {
+ ptr = (PBYTE)psurf->SurfObj.pvScan0 + i*psurf->SurfObj.lDelta;
+ for (j = 0; j < psurf->SurfObj.sizlBitmap.cx; j++)
+ {
+ Alpha = ptr[3];
+ ptr[0] = (ptr[0] * Alpha) / 0xff;
+ ptr[1] = (ptr[1] * Alpha) / 0xff;
+ ptr[2] = (ptr[2] * Alpha) / 0xff;
+
+ ptr += 4;
+ }
+ }
+
/* Initialize color translation object */
EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0xFFFFFFFF, 0xFFFFFFFF, 0);
-
+
/* Now do it */
Ret = IntEngAlphaBlend(&psurfDest->SurfObj,
&psurf->SurfObj,
&rcDest,
&rcSrc,
&blendobj);
-
+
EXLATEOBJ_vCleanup(&exlo);
- SURFACE_ShareUnlockSurface(psurf);
- if(Ret) goto done;
+
+ CleanupAlpha:
+ if(psurf) SURFACE_ShareUnlockSurface(psurf);
+ if(hsurfCopy) NtGdiDeleteObjectApp(hsurfCopy);
+ if(Ret) goto done;
ERR("NtGdiAlphaBlend failed!\n");
}
-NoAlpha:
+
if (diFlags & DI_MASK)
{
DWORD rop4 = (diFlags & DI_IMAGE) ? ROP4_SRCAND : ROP4_SRCCOPY;
-
+
EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
-
+
Ret = IntEngStretchBlt(&psurfDest->SurfObj,
&psurfMask->SurfObj,
NULL,
NULL,
NULL,
rop4);
-
+
EXLATEOBJ_vCleanup(&exlo);
if(!Ret)
if (psurfColor)
{
DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY ;
-
+
EXLATEOBJ_vInitialize(&exlo, psurfColor->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
-
+
Ret = IntEngStretchBlt(&psurfDest->SurfObj,
&psurfColor->SurfObj,
NULL,
NULL,
NULL,
rop4);
-
+
EXLATEOBJ_vCleanup(&exlo);
if(!Ret)
/* Mask bitmap holds the information in its bottom half */
DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY;
RECTL_vOffsetRect(&rcSrc, 0, pIcon->Size.cy);
-
+
EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
-
+
Ret = IntEngStretchBlt(&psurfDest->SurfObj,
&psurfMask->SurfObj,
NULL,
NULL,
NULL,
rop4);
-
+
EXLATEOBJ_vCleanup(&exlo);
if(!Ret)
RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
-
+
/* Prepare the underlying surface */
DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
-
+
/* Get the clip object */
pdcClipObj = pdc->rosdc.CombinedClip;
-
+
/* We now have our destination surface and rectangle */
psurfDest = pdc->dclevel.pSurface;
if(!psurfDest)
DC_UnlockDc(pdc);
goto Cleanup2;
}
-
+
/* Color translation */
EXLATEOBJ_vInitialize(&exlo, psurfOffScreen->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
-
+
/* Blt it! */
Ret = IntEngBitBlt(&psurfDest->SurfObj,
&psurfOffScreen->SurfObj,
NULL,
NULL,
ROP4_SRCCOPY);
-
+
EXLATEOBJ_vCleanup(&exlo);
}
Cleanup:
DC_vFinishBlit(pdc, NULL);
DC_UnlockDc(pdc);
}
-
+
Cleanup2:
/* Delete off screen rendering surface */
if(psurfOffScreen)
GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
-
+
/* Unlock other surfaces */
SURFACE_ShareUnlockSurface(psurfMask);
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
return Ret;
}
+/*
+ * @unimplemented
+ */
+HCURSOR
+NTAPI
+NtUserGetCursorFrameInfo(
+ HCURSOR hCursor,
+ DWORD istep,
+ INT* rate_jiffies,
+ DWORD* num_steps)
+{
+ STUB
+
+ return 0;
+}
+
/* EOF */