- put changes for the new cursor/icons implementation in a separate file

svn path=/trunk/; revision=57646
This commit is contained in:
Jérôme Gardou 2012-10-29 15:50:20 +00:00
parent b7efe0bd86
commit 9aec2fb369
5 changed files with 1769 additions and 228 deletions

View file

@ -11,10 +11,6 @@ if(USE_DIBLIB)
add_subdirectory(gdi/diblib) add_subdirectory(gdi/diblib)
endif() endif()
if(USE_NEW_CURSORICON)
add_definitions(-DNEW_CURSORICON)
endif()
add_subdirectory(gdi/gdi32) add_subdirectory(gdi/gdi32)
add_subdirectory(reactx) add_subdirectory(reactx)
add_subdirectory(user/user32) add_subdirectory(user/user32)
@ -107,7 +103,6 @@ list(APPEND SOURCE
user/ntuser/class.c user/ntuser/class.c
user/ntuser/clipboard.c user/ntuser/clipboard.c
user/ntuser/csr.c user/ntuser/csr.c
user/ntuser/cursoricon.c
user/ntuser/defwnd.c user/ntuser/defwnd.c
user/ntuser/desktop.c user/ntuser/desktop.c
user/ntuser/display.c user/ntuser/display.c
@ -194,6 +189,13 @@ else()
${GENDIB_FILES}) ${GENDIB_FILES})
endif() endif()
if(USE_NEW_CURSORICON)
add_definitions(-DNEW_CURSORICON)
list(APPEND SOURCE user/ntuser/cursoricon_new.c)
else()
list(APPEND SOURCE user/ntuser/cursoricon.c)
endif()
if(ARCH STREQUAL "i386") if(ARCH STREQUAL "i386")
list(APPEND SOURCE list(APPEND SOURCE
gdi/dib/i386/dib24bpp_hline.s gdi/dib/i386/dib24bpp_hline.s

View file

@ -237,7 +237,7 @@ BOOLEAN FASTCALL
IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi) IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
{ {
PSYSTEM_CURSORINFO CurInfo; PSYSTEM_CURSORINFO CurInfo;
HBITMAP bmpMask, bmpColor, bmpAlpha; HBITMAP bmpMask, bmpColor;
BOOLEAN Ret, bListEmpty, bFound = FALSE; BOOLEAN Ret, bListEmpty, bFound = FALSE;
PCURICON_PROCESS Current = NULL; PCURICON_PROCESS Current = NULL;
@ -291,28 +291,21 @@ emptyList:
UserSetCursor(NULL, TRUE); UserSetCursor(NULL, TRUE);
} }
bmpMask = CurIcon->aFrame[0].hbmMask; bmpMask = CurIcon->IconInfo.hbmMask;
bmpColor = CurIcon->aFrame[0].hbmColor; bmpColor = CurIcon->IconInfo.hbmColor;
bmpAlpha = CurIcon->aFrame[0].hbmAlpha;
/* Delete bitmaps */ /* Delete bitmaps */
if (bmpMask) if (bmpMask)
{ {
GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED); GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(bmpMask); GreDeleteObject(bmpMask);
CurIcon->aFrame[0].hbmMask = NULL; CurIcon->IconInfo.hbmMask = NULL;
} }
if (bmpColor) if (bmpColor)
{ {
GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED); GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(bmpColor); GreDeleteObject(bmpColor);
CurIcon->aFrame[0].hbmColor = NULL; CurIcon->IconInfo.hbmColor = NULL;
}
if (bmpAlpha)
{
GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(bmpAlpha);
CurIcon->aFrame[0].hbmAlpha = NULL;
} }
/* We were given a pointer, no need to keep the reference anylonger! */ /* We were given a pointer, no need to keep the reference anylonger! */
@ -368,21 +361,18 @@ NtUserGetIconInfo(
{ {
goto leave; goto leave;
} }
/* Fill data */ RtlCopyMemory(&ii, &CurIcon->IconInfo, sizeof(ICONINFO));
ii.fIcon = CurIcon->bIcon;
ii.xHotspot = CurIcon->ptlHotspot.x;
ii.yHotspot = CurIcon->ptlHotspot.y;
/* Copy bitmaps */ /* Copy bitmaps */
ii.hbmMask = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmMask); ii.hbmMask = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmMask);
ii.hbmColor = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmColor); ii.hbmColor = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmColor);
if (pbpp) if (pbpp)
{ {
PSURFACE psurfBmp; PSURFACE psurfBmp;
psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor); psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmColor);
if (psurfBmp) if (psurfBmp)
{ {
colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat); colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
@ -809,103 +799,35 @@ NtUserSetCursorContents(
goto done; goto done;
} }
#if 0
/* Check if we get valid information */
if(IconInfo.fIcon != CurInfo->bIcon)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
goto done;
}
#endif
/* Delete old bitmaps */ /* Delete old bitmaps */
if (CurIcon->aFrame[0].hbmColor) if ((CurIcon->IconInfo.hbmColor)
GreDeleteObject(CurIcon->aFrame[0].hbmColor); && (CurIcon->IconInfo.hbmColor != IconInfo.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; GreDeleteObject(CurIcon->IconInfo.hbmColor);
psurfBmp = SURFACE_ShareLockSurface(IconInfo.hbmColor); }
if ((CurIcon->IconInfo.hbmMask)
&& CurIcon->IconInfo.hbmMask != IconInfo.hbmMask)
{
GreDeleteObject(CurIcon->IconInfo.hbmMask);
}
/* Copy new IconInfo field */
CurIcon->IconInfo = IconInfo;
if (CurIcon->IconInfo.hbmColor)
{
psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmColor);
if (!psurfBmp) if (!psurfBmp)
goto done; goto done;
CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx; CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy; 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); SURFACE_ShareUnlockSurface(psurfBmp);
GreSetObjectOwner(IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC); GreSetObjectOwner(CurIcon->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);
}
} }
else else
{ {
psurfBmp = SURFACE_ShareLockSurface(IconInfo.hbmMask); psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmMask);
if (!psurfBmp) if (!psurfBmp)
goto done; goto done;
@ -914,18 +836,12 @@ NtUserSetCursorContents(
SURFACE_ShareUnlockSurface(psurfBmp); SURFACE_ShareUnlockSurface(psurfBmp);
} }
GreSetObjectOwner(IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC); GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
Ret = TRUE; Ret = TRUE;
done: done:
if(!Ret)
{
IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
CurIcon = NULL;
}
if (CurIcon) if (CurIcon)
{ {
UserDereferenceObject(CurIcon); UserDereferenceObject(CurIcon);
@ -942,21 +858,20 @@ CLEANUP:
/* /*
* @implemented * @implemented
*/ */
#ifdef NEW_CURSORICON #if 0
BOOL BOOL
APIENTRY APIENTRY
NtUserSetCursorIconData( NtUserSetCursorIconData(
_In_ HCURSOR Handle, HANDLE Handle,
_In_ HINSTANCE hinst, HMODULE hModule,
_In_ HRSRC hrsrc, PUNICODE_STRING pstrResName,
_In_ PICONINFO pIconInfo) PICONINFO pIconInfo)
{ {
PCURICON_OBJECT CurIcon; PCURICON_OBJECT CurIcon;
PSURFACE psurfBmp; PSURFACE psurfBmp;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
BOOL Ret = FALSE; BOOL Ret = FALSE;
DECLARE_RETURN(BOOL); DECLARE_RETURN(BOOL);
ICONINFO ii;
TRACE("Enter NtUserSetCursorIconData\n"); TRACE("Enter NtUserSetCursorIconData\n");
UserEnterExclusive(); UserEnterExclusive();
@ -966,96 +881,54 @@ NtUserSetCursorIconData(
RETURN(FALSE); RETURN(FALSE);
} }
CurIcon->hModule = hinst; CurIcon->hModule = hModule;
CurIcon->hRsrc =hrsrc; CurIcon->hRsrc = NULL; //hRsrc;
CurIcon->hGroupRsrc = NULL; //hGroupRsrc;
_SEH2_TRY _SEH2_TRY
{ {
ProbeForRead(pIconInfo, sizeof(ICONINFO), 1); 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) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
Status = _SEH2_GetExceptionCode(); Status = _SEH2_GetExceptionCode();
} }
_SEH2_END _SEH2_END
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{
SetLastNtError(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 else
{ Ret = TRUE;
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;
done:
UserDereferenceObject(CurIcon); 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); RETURN(Ret);
CLEANUP: CLEANUP:
@ -1076,6 +949,7 @@ NtUserSetCursorIconData(
{ {
PCURICON_OBJECT CurIcon; PCURICON_OBJECT CurIcon;
NTSTATUS Status; NTSTATUS Status;
POINT SafeHotspot;
BOOL Ret = FALSE; BOOL Ret = FALSE;
DECLARE_RETURN(BOOL); DECLARE_RETURN(BOOL);
@ -1094,7 +968,7 @@ NtUserSetCursorIconData(
/* Copy fields */ /* Copy fields */
if (fIcon) if (fIcon)
{ {
Status = MmCopyFromCaller(&CurIcon->bIcon, fIcon, sizeof(BOOL)); Status = MmCopyFromCaller(&CurIcon->IconInfo.fIcon, fIcon, sizeof(BOOL));
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
SetLastNtError(Status); SetLastNtError(Status);
@ -1109,12 +983,16 @@ NtUserSetCursorIconData(
if (Hotspot) if (Hotspot)
{ {
Status = MmCopyFromCaller(&CurIcon->ptlHotspot, Hotspot, sizeof(POINT)); Status = MmCopyFromCaller(&SafeHotspot, Hotspot, sizeof(POINT));
if (!NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
SetLastNtError(Status); CurIcon->IconInfo.xHotspot = SafeHotspot.x;
goto done; CurIcon->IconInfo.yHotspot = SafeHotspot.y;
Ret = TRUE;
} }
else
SetLastNtError(Status);
} }
if (!fIcon && !Hotspot) if (!fIcon && !Hotspot)
@ -1126,14 +1004,10 @@ done:
if(Ret) if(Ret)
{ {
/* This icon is shared now */ /* This icon is shared now */
GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC); GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
if(CurIcon->aFrame[0].hbmColor) if(CurIcon->IconInfo.hbmColor)
{ {
GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_PUBLIC); GreSetObjectOwner(CurIcon->IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
}
if(CurIcon->aFrame[0].hbmAlpha)
{
GreSetObjectOwner(CurIcon->aFrame[0].hbmAlpha, GDI_OBJ_HMGR_PUBLIC);
} }
} }
UserDereferenceObject(CurIcon); UserDereferenceObject(CurIcon);
@ -1170,8 +1044,8 @@ UserDrawIconEx(
PSURFACE psurfDest, psurfMask, psurfColor, psurfOffScreen; PSURFACE psurfDest, psurfMask, psurfColor, psurfOffScreen;
PDC pdc = NULL; PDC pdc = NULL;
BOOL Ret = FALSE; BOOL Ret = FALSE;
HBITMAP hbmMask, hbmColor, hbmAlpha; HBITMAP hbmMask, hbmColor;
BOOL bOffScreen; BOOL bOffScreen, bAlpha = FALSE;
RECTL rcDest, rcSrc; RECTL rcDest, rcSrc;
CLIPOBJ* pdcClipObj = NULL; CLIPOBJ* pdcClipObj = NULL;
EXLATEOBJ exlo; EXLATEOBJ exlo;
@ -1183,9 +1057,8 @@ UserDrawIconEx(
return FALSE; return FALSE;
} }
hbmMask = pIcon->aFrame[0].hbmMask; hbmMask = pIcon->IconInfo.hbmMask;
hbmColor = pIcon->aFrame[0].hbmColor; hbmColor = pIcon->IconInfo.hbmColor;
hbmAlpha = pIcon->aFrame[0].hbmAlpha;
if (istepIfAniCur) if (istepIfAniCur)
ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n"); ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
@ -1218,11 +1091,35 @@ UserDrawIconEx(
/* Set source rect */ /* Set source rect */
RECTL_vSetRect(&rcSrc, 0, 0, pIcon->Size.cx, pIcon->Size.cy); 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 */ /* Fix width parameter, if needed */
if (!cxWidth) if (!cxWidth)
{ {
if(diFlags & DI_DEFAULTSIZE) if(diFlags & DI_DEFAULTSIZE)
cxWidth = pIcon->bIcon ? cxWidth = pIcon->IconInfo.fIcon ?
UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR); UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR);
else else
cxWidth = pIcon->Size.cx; cxWidth = pIcon->Size.cx;
@ -1232,7 +1129,7 @@ UserDrawIconEx(
if (!cyHeight) if (!cyHeight)
{ {
if(diFlags & DI_DEFAULTSIZE) if(diFlags & DI_DEFAULTSIZE)
cyHeight = pIcon->bIcon ? cyHeight = pIcon->IconInfo.fIcon ?
UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR); UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR);
else else
cyHeight = pIcon->Size.cy; cyHeight = pIcon->Size.cy;
@ -1341,16 +1238,42 @@ UserDrawIconEx(
} }
/* Now do the rendering */ /* Now do the rendering */
if(hbmAlpha && (diFlags & DI_IMAGE)) if(bAlpha && (diFlags & DI_IMAGE))
{ {
BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } }; BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } };
BYTE Alpha;
INT i, j;
PSURFACE psurf = NULL; PSURFACE psurf = NULL;
PBYTE ptr ;
HBITMAP hsurfCopy = NULL;
psurf = SURFACE_ShareLockSurface(hbmAlpha); hsurfCopy = BITMAP_CopyBitmap(hbmColor);
if(!hsurfCopy)
{
ERR("BITMAP_CopyBitmap failed!");
goto CleanupAlpha;
}
psurf = SURFACE_ShareLockSurface(hsurfCopy);
if(!psurf) if(!psurf)
{ {
ERR("SURFACE_LockSurface failed!\n"); 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 */ /* Initialize color translation object */
@ -1366,11 +1289,14 @@ UserDrawIconEx(
&blendobj); &blendobj);
EXLATEOBJ_vCleanup(&exlo); 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"); ERR("NtGdiAlphaBlend failed!\n");
} }
NoAlpha:
if (diFlags & DI_MASK) if (diFlags & DI_MASK)
{ {
DWORD rop4 = (diFlags & DI_IMAGE) ? ROP4_SRCAND : ROP4_SRCCOPY; DWORD rop4 = (diFlags & DI_IMAGE) ? ROP4_SRCAND : ROP4_SRCCOPY;

View file

@ -8,6 +8,7 @@ typedef struct tagCURICON_PROCESS
PPROCESSINFO Process; PPROCESSINFO Process;
} CURICON_PROCESS, *PCURICON_PROCESS; } CURICON_PROCESS, *PCURICON_PROCESS;
#ifdef NEW_CURSORICON
typedef struct _CURICON_FRAME typedef struct _CURICON_FRAME
{ {
HBITMAP hbmMask; HBITMAP hbmMask;
@ -23,9 +24,6 @@ typedef struct _CURICON_OBJECT
LIST_ENTRY ProcessList; LIST_ENTRY ProcessList;
HMODULE hModule; HMODULE hModule;
HRSRC hRsrc; HRSRC hRsrc;
#ifndef NEW_CURSORICON
HRSRC hGroupRsrc;
#endif
SIZE Size; SIZE Size;
BYTE Shadow; BYTE Shadow;
BOOL bIcon; BOOL bIcon;
@ -33,6 +31,23 @@ typedef struct _CURICON_OBJECT
CURICON_FRAME aFrame[1]; CURICON_FRAME aFrame[1];
} CURICON_OBJECT, *PCURICON_OBJECT; } CURICON_OBJECT, *PCURICON_OBJECT;
#else
typedef struct _CURICON_OBJECT
{
PROCMARKHEAD head;
LIST_ENTRY ListEntry;
HANDLE Self;
LIST_ENTRY ProcessList;
HMODULE hModule;
HRSRC hRsrc;
HRSRC hGroupRsrc;
SIZE Size;
BYTE Shadow;
ICONINFO IconInfo;
} CURICON_OBJECT, *PCURICON_OBJECT;
#endif
typedef struct _CURSORACCELERATION_INFO typedef struct _CURSORACCELERATION_INFO
{ {
UINT FirstThreshold; UINT FirstThreshold;

File diff suppressed because it is too large Load diff

View file

@ -145,6 +145,7 @@ UserSetCursor(
if (NewCursor) if (NewCursor)
{ {
/* Call GDI to set the new screen cursor */ /* Call GDI to set the new screen cursor */
#ifdef NEW_CURSORICON
GreSetPointerShape(hdcScreen, GreSetPointerShape(hdcScreen,
NewCursor->aFrame[0].hbmMask, NewCursor->aFrame[0].hbmMask,
NewCursor->aFrame[0].hbmColor, NewCursor->aFrame[0].hbmColor,
@ -152,6 +153,15 @@ UserSetCursor(
NewCursor->ptlHotspot.y, NewCursor->ptlHotspot.y,
gpsi->ptCursor.x, gpsi->ptCursor.x,
gpsi->ptCursor.y); gpsi->ptCursor.y);
#else
GreSetPointerShape(hdcScreen,
NewCursor->IconInfo.hbmMask,
NewCursor->IconInfo.hbmColor,
NewCursor->IconInfo.xHotspot,
NewCursor->IconInfo.yHotspot,
gpsi->ptCursor.x,
gpsi->ptCursor.y);
#endif
} }
else /* Note: OldCursor != NewCursor so we have to hide cursor */ else /* Note: OldCursor != NewCursor so we have to hide cursor */
{ {
@ -571,6 +581,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
if(CurInfo->CurrentCursorObject != MessageQueue->CursorObject) if(CurInfo->CurrentCursorObject != MessageQueue->CursorObject)
{ {
/* Call GDI to set the new screen cursor */ /* Call GDI to set the new screen cursor */
#ifdef NEW_CURSORICON
GreSetPointerShape(hdcScreen, GreSetPointerShape(hdcScreen,
MessageQueue->CursorObject->aFrame[0].hbmMask, MessageQueue->CursorObject->aFrame[0].hbmMask,
MessageQueue->CursorObject->aFrame[0].hbmColor, MessageQueue->CursorObject->aFrame[0].hbmColor,
@ -578,6 +589,15 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
MessageQueue->CursorObject->ptlHotspot.y, MessageQueue->CursorObject->ptlHotspot.y,
gpsi->ptCursor.x, gpsi->ptCursor.x,
gpsi->ptCursor.y); gpsi->ptCursor.y);
#else
GreSetPointerShape(hdcScreen,
MessageQueue->CursorObject->IconInfo.hbmMask,
MessageQueue->CursorObject->IconInfo.hbmColor,
MessageQueue->CursorObject->IconInfo.xHotspot,
MessageQueue->CursorObject->IconInfo.yHotspot,
gpsi->ptCursor.x,
gpsi->ptCursor.y);
#endif
} else } else
GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y); GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y);
} }