mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
[WIN32SS/USER]
- Begin a rewrite of our cursor/Icons implementation. The current one is too close to wine's. svn path=/trunk/; revision=57644
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
|
||||
set(USE_DIBLIB FALSE)
|
||||
set(USE_NEW_CURSORICON FALSE)
|
||||
|
||||
# Give WIN32 subsystem its own project.
|
||||
PROJECT(WIN32SS)
|
||||
@@ -10,6 +11,10 @@ if(USE_DIBLIB)
|
||||
add_subdirectory(gdi/diblib)
|
||||
endif()
|
||||
|
||||
if(USE_NEW_CURSORICON)
|
||||
add_definitions(-DNEW_CURSORICON)
|
||||
endif()
|
||||
|
||||
add_subdirectory(gdi/gdi32)
|
||||
add_subdirectory(reactx)
|
||||
add_subdirectory(user/user32)
|
||||
|
||||
@@ -2739,14 +2739,24 @@ NtUserSetCursorContents(
|
||||
HANDLE Handle,
|
||||
PICONINFO IconInfo);
|
||||
|
||||
#if 0 // Correct type.
|
||||
#ifdef NEW_CURSORICON
|
||||
BOOL
|
||||
NTAPI
|
||||
NtUserSetCursorIconData(
|
||||
HCURSOR hCursor,
|
||||
PUNICODE_STRING ModuleName,
|
||||
PUNICODE_STRING ResourceName,
|
||||
PCURSORDATA pCursorData);
|
||||
_In_ HCURSOR hCursor,
|
||||
_In_ HINSTANCE hinst,
|
||||
_In_ HRSRC hrsrc,
|
||||
_In_ PICONINFO pii);
|
||||
#else
|
||||
BOOL
|
||||
NTAPI
|
||||
NtUserSetCursorIconData(
|
||||
HANDLE Handle,
|
||||
PBOOL fIcon,
|
||||
POINT *Hotspot,
|
||||
HMODULE hModule,
|
||||
HRSRC hRsrc,
|
||||
HRSRC hGroupRsrc);
|
||||
#endif
|
||||
|
||||
DWORD
|
||||
@@ -3361,16 +3371,6 @@ NtUserMonitorFromWindow(
|
||||
IN HWND hWnd,
|
||||
IN DWORD dwFlags);
|
||||
|
||||
BOOL
|
||||
NTAPI
|
||||
NtUserSetCursorIconData(
|
||||
HANDLE Handle,
|
||||
PBOOL fIcon,
|
||||
POINT *Hotspot,
|
||||
HMODULE hModule,
|
||||
HRSRC hRsrc,
|
||||
HRSRC hGroupRsrc);
|
||||
|
||||
typedef struct _SETSCROLLBARINFO
|
||||
{
|
||||
int nTrackPos;
|
||||
|
||||
@@ -237,7 +237,7 @@ BOOLEAN FASTCALL
|
||||
IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
|
||||
{
|
||||
PSYSTEM_CURSORINFO CurInfo;
|
||||
HBITMAP bmpMask, bmpColor;
|
||||
HBITMAP bmpMask, bmpColor, bmpAlpha;
|
||||
BOOLEAN Ret, bListEmpty, bFound = FALSE;
|
||||
PCURICON_PROCESS Current = NULL;
|
||||
|
||||
@@ -291,21 +291,28 @@ emptyList:
|
||||
UserSetCursor(NULL, TRUE);
|
||||
}
|
||||
|
||||
bmpMask = CurIcon->IconInfo.hbmMask;
|
||||
bmpColor = CurIcon->IconInfo.hbmColor;
|
||||
bmpMask = CurIcon->aFrame[0].hbmMask;
|
||||
bmpColor = CurIcon->aFrame[0].hbmColor;
|
||||
bmpAlpha = CurIcon->aFrame[0].hbmAlpha;
|
||||
|
||||
/* Delete bitmaps */
|
||||
if (bmpMask)
|
||||
{
|
||||
GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED);
|
||||
GreDeleteObject(bmpMask);
|
||||
CurIcon->IconInfo.hbmMask = NULL;
|
||||
CurIcon->aFrame[0].hbmMask = NULL;
|
||||
}
|
||||
if (bmpColor)
|
||||
{
|
||||
GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED);
|
||||
GreDeleteObject(bmpColor);
|
||||
CurIcon->IconInfo.hbmColor = NULL;
|
||||
CurIcon->aFrame[0].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! */
|
||||
@@ -361,18 +368,21 @@ NtUserGetIconInfo(
|
||||
{
|
||||
goto leave;
|
||||
}
|
||||
|
||||
RtlCopyMemory(&ii, &CurIcon->IconInfo, sizeof(ICONINFO));
|
||||
|
||||
/* Fill data */
|
||||
ii.fIcon = CurIcon->bIcon;
|
||||
ii.xHotspot = CurIcon->ptlHotspot.x;
|
||||
ii.yHotspot = CurIcon->ptlHotspot.y;
|
||||
|
||||
/* Copy bitmaps */
|
||||
ii.hbmMask = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmMask);
|
||||
ii.hbmColor = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmColor);
|
||||
ii.hbmMask = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmMask);
|
||||
ii.hbmColor = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmColor);
|
||||
|
||||
if (pbpp)
|
||||
{
|
||||
PSURFACE psurfBmp;
|
||||
|
||||
psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmColor);
|
||||
psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
|
||||
if (psurfBmp)
|
||||
{
|
||||
colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
|
||||
@@ -799,35 +809,103 @@ NtUserSetCursorContents(
|
||||
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 */
|
||||
if ((CurIcon->IconInfo.hbmColor)
|
||||
&& (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor))
|
||||
{
|
||||
GreDeleteObject(CurIcon->IconInfo.hbmColor);
|
||||
}
|
||||
if ((CurIcon->IconInfo.hbmMask)
|
||||
&& CurIcon->IconInfo.hbmMask != IconInfo.hbmMask)
|
||||
{
|
||||
GreDeleteObject(CurIcon->IconInfo.hbmMask);
|
||||
}
|
||||
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);
|
||||
|
||||
/* Copy new IconInfo field */
|
||||
CurIcon->IconInfo = IconInfo;
|
||||
/* 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 (CurIcon->IconInfo.hbmColor)
|
||||
if (IconInfo.hbmColor)
|
||||
{
|
||||
psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmColor);
|
||||
BOOLEAN bAlpha = FALSE;
|
||||
psurfBmp = SURFACE_ShareLockSurface(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(CurIcon->IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmMask);
|
||||
psurfBmp = SURFACE_ShareLockSurface(IconInfo.hbmMask);
|
||||
if (!psurfBmp)
|
||||
goto done;
|
||||
|
||||
@@ -836,12 +914,18 @@ NtUserSetCursorContents(
|
||||
|
||||
SURFACE_ShareUnlockSurface(psurfBmp);
|
||||
}
|
||||
GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
|
||||
GreSetObjectOwner(IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
|
||||
|
||||
Ret = TRUE;
|
||||
|
||||
done:
|
||||
|
||||
if(!Ret)
|
||||
{
|
||||
IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
|
||||
CurIcon = NULL;
|
||||
}
|
||||
|
||||
if (CurIcon)
|
||||
{
|
||||
UserDereferenceObject(CurIcon);
|
||||
@@ -858,20 +942,21 @@ CLEANUP:
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
#if 0
|
||||
#ifdef NEW_CURSORICON
|
||||
BOOL
|
||||
APIENTRY
|
||||
NtUserSetCursorIconData(
|
||||
HANDLE Handle,
|
||||
HMODULE hModule,
|
||||
PUNICODE_STRING pstrResName,
|
||||
PICONINFO pIconInfo)
|
||||
_In_ HCURSOR Handle,
|
||||
_In_ HINSTANCE hinst,
|
||||
_In_ HRSRC hrsrc,
|
||||
_In_ PICONINFO pIconInfo)
|
||||
{
|
||||
PCURICON_OBJECT CurIcon;
|
||||
PSURFACE psurfBmp;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
BOOL Ret = FALSE;
|
||||
DECLARE_RETURN(BOOL);
|
||||
ICONINFO ii;
|
||||
|
||||
TRACE("Enter NtUserSetCursorIconData\n");
|
||||
UserEnterExclusive();
|
||||
@@ -881,54 +966,96 @@ NtUserSetCursorIconData(
|
||||
RETURN(FALSE);
|
||||
}
|
||||
|
||||
CurIcon->hModule = hModule;
|
||||
CurIcon->hRsrc = NULL; //hRsrc;
|
||||
CurIcon->hGroupRsrc = NULL; //hGroupRsrc;
|
||||
CurIcon->hModule = hinst;
|
||||
CurIcon->hRsrc =hrsrc;
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForRead(pIconInfo, sizeof(ICONINFO), 1);
|
||||
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);
|
||||
}
|
||||
ii = *pIconInfo;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END
|
||||
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastNtError(Status);
|
||||
else
|
||||
Ret = TRUE;
|
||||
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;
|
||||
|
||||
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:
|
||||
@@ -949,7 +1076,6 @@ NtUserSetCursorIconData(
|
||||
{
|
||||
PCURICON_OBJECT CurIcon;
|
||||
NTSTATUS Status;
|
||||
POINT SafeHotspot;
|
||||
BOOL Ret = FALSE;
|
||||
DECLARE_RETURN(BOOL);
|
||||
|
||||
@@ -968,7 +1094,7 @@ NtUserSetCursorIconData(
|
||||
/* Copy fields */
|
||||
if (fIcon)
|
||||
{
|
||||
Status = MmCopyFromCaller(&CurIcon->IconInfo.fIcon, fIcon, sizeof(BOOL));
|
||||
Status = MmCopyFromCaller(&CurIcon->bIcon, fIcon, sizeof(BOOL));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
SetLastNtError(Status);
|
||||
@@ -983,16 +1109,12 @@ NtUserSetCursorIconData(
|
||||
|
||||
if (Hotspot)
|
||||
{
|
||||
Status = MmCopyFromCaller(&SafeHotspot, Hotspot, sizeof(POINT));
|
||||
if (NT_SUCCESS(Status))
|
||||
Status = MmCopyFromCaller(&CurIcon->ptlHotspot, Hotspot, sizeof(POINT));
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
CurIcon->IconInfo.xHotspot = SafeHotspot.x;
|
||||
CurIcon->IconInfo.yHotspot = SafeHotspot.y;
|
||||
|
||||
Ret = TRUE;
|
||||
}
|
||||
else
|
||||
SetLastNtError(Status);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fIcon && !Hotspot)
|
||||
@@ -1004,10 +1126,14 @@ done:
|
||||
if(Ret)
|
||||
{
|
||||
/* This icon is shared now */
|
||||
GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
|
||||
if(CurIcon->IconInfo.hbmColor)
|
||||
GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
|
||||
if(CurIcon->aFrame[0].hbmColor)
|
||||
{
|
||||
GreSetObjectOwner(CurIcon->IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
|
||||
GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_PUBLIC);
|
||||
}
|
||||
if(CurIcon->aFrame[0].hbmAlpha)
|
||||
{
|
||||
GreSetObjectOwner(CurIcon->aFrame[0].hbmAlpha, GDI_OBJ_HMGR_PUBLIC);
|
||||
}
|
||||
}
|
||||
UserDereferenceObject(CurIcon);
|
||||
@@ -1044,8 +1170,8 @@ UserDrawIconEx(
|
||||
PSURFACE psurfDest, psurfMask, psurfColor, psurfOffScreen;
|
||||
PDC pdc = NULL;
|
||||
BOOL Ret = FALSE;
|
||||
HBITMAP hbmMask, hbmColor;
|
||||
BOOL bOffScreen, bAlpha = FALSE;
|
||||
HBITMAP hbmMask, hbmColor, hbmAlpha;
|
||||
BOOL bOffScreen;
|
||||
RECTL rcDest, rcSrc;
|
||||
CLIPOBJ* pdcClipObj = NULL;
|
||||
EXLATEOBJ exlo;
|
||||
@@ -1057,8 +1183,9 @@ UserDrawIconEx(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
hbmMask = pIcon->IconInfo.hbmMask;
|
||||
hbmColor = pIcon->IconInfo.hbmColor;
|
||||
hbmMask = pIcon->aFrame[0].hbmMask;
|
||||
hbmColor = pIcon->aFrame[0].hbmColor;
|
||||
hbmAlpha = pIcon->aFrame[0].hbmAlpha;
|
||||
|
||||
if (istepIfAniCur)
|
||||
ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
|
||||
@@ -1091,35 +1218,11 @@ UserDrawIconEx(
|
||||
/* 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->IconInfo.fIcon ?
|
||||
cxWidth = pIcon->bIcon ?
|
||||
UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR);
|
||||
else
|
||||
cxWidth = pIcon->Size.cx;
|
||||
@@ -1129,7 +1232,7 @@ UserDrawIconEx(
|
||||
if (!cyHeight)
|
||||
{
|
||||
if(diFlags & DI_DEFAULTSIZE)
|
||||
cyHeight = pIcon->IconInfo.fIcon ?
|
||||
cyHeight = pIcon->bIcon ?
|
||||
UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR);
|
||||
else
|
||||
cyHeight = pIcon->Size.cy;
|
||||
@@ -1238,42 +1341,16 @@ UserDrawIconEx(
|
||||
}
|
||||
|
||||
/* Now do the rendering */
|
||||
if(bAlpha && (diFlags & DI_IMAGE))
|
||||
if(hbmAlpha && (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(hsurfCopy);
|
||||
psurf = SURFACE_ShareLockSurface(hbmAlpha);
|
||||
if(!psurf)
|
||||
{
|
||||
ERR("SURFACE_LockSurface failed!\n");
|
||||
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;
|
||||
}
|
||||
goto NoAlpha;
|
||||
}
|
||||
|
||||
/* Initialize color translation object */
|
||||
@@ -1289,14 +1366,11 @@ UserDrawIconEx(
|
||||
&blendobj);
|
||||
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
|
||||
CleanupAlpha:
|
||||
if(psurf) SURFACE_ShareUnlockSurface(psurf);
|
||||
if(hsurfCopy) NtGdiDeleteObjectApp(hsurfCopy);
|
||||
if(Ret) goto done;
|
||||
SURFACE_ShareUnlockSurface(psurf);
|
||||
if(Ret) goto done;
|
||||
ERR("NtGdiAlphaBlend failed!\n");
|
||||
}
|
||||
|
||||
NoAlpha:
|
||||
if (diFlags & DI_MASK)
|
||||
{
|
||||
DWORD rop4 = (diFlags & DI_IMAGE) ? ROP4_SRCAND : ROP4_SRCCOPY;
|
||||
|
||||
@@ -8,6 +8,13 @@ typedef struct tagCURICON_PROCESS
|
||||
PPROCESSINFO Process;
|
||||
} CURICON_PROCESS, *PCURICON_PROCESS;
|
||||
|
||||
typedef struct _CURICON_FRAME
|
||||
{
|
||||
HBITMAP hbmMask;
|
||||
HBITMAP hbmColor;
|
||||
HBITMAP hbmAlpha;
|
||||
} CURICON_FRAME, *PCURICON_FRAME;
|
||||
|
||||
typedef struct _CURICON_OBJECT
|
||||
{
|
||||
PROCMARKHEAD head;
|
||||
@@ -16,10 +23,14 @@ typedef struct _CURICON_OBJECT
|
||||
LIST_ENTRY ProcessList;
|
||||
HMODULE hModule;
|
||||
HRSRC hRsrc;
|
||||
#ifndef NEW_CURSORICON
|
||||
HRSRC hGroupRsrc;
|
||||
#endif
|
||||
SIZE Size;
|
||||
BYTE Shadow;
|
||||
ICONINFO IconInfo;
|
||||
BOOL bIcon;
|
||||
POINTL ptlHotspot;
|
||||
CURICON_FRAME aFrame[1];
|
||||
} CURICON_OBJECT, *PCURICON_OBJECT;
|
||||
|
||||
typedef struct _CURSORACCELERATION_INFO
|
||||
|
||||
@@ -146,10 +146,10 @@ UserSetCursor(
|
||||
{
|
||||
/* Call GDI to set the new screen cursor */
|
||||
GreSetPointerShape(hdcScreen,
|
||||
NewCursor->IconInfo.hbmMask,
|
||||
NewCursor->IconInfo.hbmColor,
|
||||
NewCursor->IconInfo.xHotspot,
|
||||
NewCursor->IconInfo.yHotspot,
|
||||
NewCursor->aFrame[0].hbmMask,
|
||||
NewCursor->aFrame[0].hbmColor,
|
||||
NewCursor->ptlHotspot.x,
|
||||
NewCursor->ptlHotspot.y,
|
||||
gpsi->ptCursor.x,
|
||||
gpsi->ptCursor.y);
|
||||
}
|
||||
@@ -572,10 +572,10 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
|
||||
{
|
||||
/* Call GDI to set the new screen cursor */
|
||||
GreSetPointerShape(hdcScreen,
|
||||
MessageQueue->CursorObject->IconInfo.hbmMask,
|
||||
MessageQueue->CursorObject->IconInfo.hbmColor,
|
||||
MessageQueue->CursorObject->IconInfo.xHotspot,
|
||||
MessageQueue->CursorObject->IconInfo.yHotspot,
|
||||
MessageQueue->CursorObject->aFrame[0].hbmMask,
|
||||
MessageQueue->CursorObject->aFrame[0].hbmColor,
|
||||
MessageQueue->CursorObject->ptlHotspot.x,
|
||||
MessageQueue->CursorObject->ptlHotspot.y,
|
||||
gpsi->ptCursor.x,
|
||||
gpsi->ptCursor.y);
|
||||
} else
|
||||
|
||||
@@ -41,7 +41,7 @@ list(APPEND SOURCE
|
||||
windows/caret.c
|
||||
windows/class.c
|
||||
windows/clipboard.c
|
||||
windows/cursoricon.c
|
||||
# windows/cursoricon.c
|
||||
windows/dc.c
|
||||
windows/defwnd.c
|
||||
windows/dialog.c
|
||||
@@ -64,6 +64,12 @@ list(APPEND SOURCE
|
||||
user32.rc
|
||||
${CMAKE_CURRENT_BINARY_DIR}/user32.def)
|
||||
|
||||
if(USE_NEW_CURSORICON)
|
||||
list(APPEND SOURCE windows/cursoricon_new.c)
|
||||
else()
|
||||
list(APPEND SOURCE windows/cursoricon.c)
|
||||
endif()
|
||||
|
||||
add_library(user32 SHARED ${SOURCE})
|
||||
set_module_type(user32 win32dll UNICODE)
|
||||
|
||||
|
||||
@@ -30,30 +30,6 @@
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(icon);
|
||||
|
||||
#include "pshpack1.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE bWidth; /* Width, in pixels, of the image */
|
||||
BYTE bHeight; /* Height, in pixels, of the image */
|
||||
BYTE bColorCount; /* Number of colors in image (0 if >=8bpp) */
|
||||
BYTE bReserved; /* Reserved ( must be 0) */
|
||||
WORD wPlanes; /* Color Planes */
|
||||
WORD wBitCount; /* Bits per pixel */
|
||||
DWORD dwBytesInRes; /* How many bytes in this resource? */
|
||||
DWORD dwImageOffset; /* Where in the file is this image? */
|
||||
} icoICONDIRENTRY, *LPicoICONDIRENTRY;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD idReserved; /* Reserved (must be 0) */
|
||||
WORD idType; /* Resource Type (RES_ICON or RES_CURSOR) */
|
||||
WORD idCount; /* How many images */
|
||||
icoICONDIRENTRY idEntries[1]; /* An entry for each image (idCount of 'em) */
|
||||
} icoICONDIR, *LPicoICONDIR;
|
||||
|
||||
#include "poppack.h"
|
||||
|
||||
#if 0
|
||||
static void dumpIcoDirEnty ( LPicoICONDIRENTRY entry )
|
||||
{
|
||||
|
||||
@@ -0,0 +1,756 @@
|
||||
/*
|
||||
* PROJECT: ReactOS user32.dll
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* FILE: dll/win32/user32/windows/class.c
|
||||
* PURPOSE: Window classes
|
||||
* PROGRAMMER: Jérôme Gardou ([email protected])
|
||||
*/
|
||||
|
||||
#include <user32.h>
|
||||
|
||||
#include <wine/debug.h>
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(cursor);
|
||||
//WINE_DECLARE_DEBUG_CHANNEL(icon);
|
||||
//WINE_DECLARE_DEBUG_CHANNEL(resource);
|
||||
|
||||
/************* USER32 INTERNAL FUNCTIONS **********/
|
||||
|
||||
/* This callback routine is called directly after switching to gui mode */
|
||||
NTSTATUS
|
||||
WINAPI
|
||||
User32SetupDefaultCursors(PVOID Arguments,
|
||||
ULONG ArgumentLength)
|
||||
{
|
||||
BOOL *DefaultCursor = (BOOL*)Arguments;
|
||||
HCURSOR hCursor;
|
||||
|
||||
if(*DefaultCursor)
|
||||
{
|
||||
/* set default cursor */
|
||||
hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
|
||||
SetCursor(hCursor);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME load system cursor scheme */
|
||||
SetCursor(0);
|
||||
hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
|
||||
SetCursor(hCursor);
|
||||
}
|
||||
|
||||
return(ZwCallbackReturn(&hCursor, sizeof(HCURSOR), STATUS_SUCCESS));
|
||||
}
|
||||
|
||||
BOOL get_icon_size(HICON hIcon, SIZE *size)
|
||||
{
|
||||
return NtUserGetIconSize(hIcon, 0, &size->cx, &size->cy);
|
||||
}
|
||||
|
||||
HCURSOR CursorIconToCursor(HICON hIcon, BOOL SemiTransparent)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/************* IMPLEMENTATION HELPERS ******************/
|
||||
|
||||
static int get_dib_image_size( int width, int height, int depth )
|
||||
{
|
||||
return (((width * depth + 31) / 8) & ~3) * abs( height );
|
||||
}
|
||||
|
||||
static BOOL is_dib_monochrome( const BITMAPINFO* info )
|
||||
{
|
||||
if (info->bmiHeader.biBitCount != 1) return FALSE;
|
||||
|
||||
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
const RGBTRIPLE *rgb = ((const BITMAPCOREINFO*)info)->bmciColors;
|
||||
|
||||
/* Check if the first color is black */
|
||||
if ((rgb->rgbtRed == 0) && (rgb->rgbtGreen == 0) && (rgb->rgbtBlue == 0))
|
||||
{
|
||||
rgb++;
|
||||
|
||||
/* Check if the second color is white */
|
||||
return ((rgb->rgbtRed == 0xff) && (rgb->rgbtGreen == 0xff)
|
||||
&& (rgb->rgbtBlue == 0xff));
|
||||
}
|
||||
else return FALSE;
|
||||
}
|
||||
else /* assume BITMAPINFOHEADER */
|
||||
{
|
||||
const RGBQUAD *rgb = info->bmiColors;
|
||||
|
||||
/* Check if the first color is black */
|
||||
if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) &&
|
||||
(rgb->rgbBlue == 0) && (rgb->rgbReserved == 0))
|
||||
{
|
||||
rgb++;
|
||||
|
||||
/* Check if the second color is white */
|
||||
return ((rgb->rgbRed == 0xff) && (rgb->rgbGreen == 0xff)
|
||||
&& (rgb->rgbBlue == 0xff) && (rgb->rgbReserved == 0));
|
||||
}
|
||||
else return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
|
||||
{
|
||||
unsigned int colors, size, masks = 0;
|
||||
|
||||
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
|
||||
colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
|
||||
return sizeof(BITMAPCOREHEADER) + colors *
|
||||
((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
|
||||
}
|
||||
else /* assume BITMAPINFOHEADER */
|
||||
{
|
||||
colors = info->bmiHeader.biClrUsed;
|
||||
if (colors > 256) /* buffer overflow otherwise */
|
||||
colors = 256;
|
||||
if (!colors && (info->bmiHeader.biBitCount <= 8))
|
||||
colors = 1 << info->bmiHeader.biBitCount;
|
||||
if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
|
||||
size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
|
||||
return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
|
||||
}
|
||||
}
|
||||
|
||||
/************* IMPLEMENTATION CORE ****************/
|
||||
|
||||
static BOOL CURSORICON_GetIconInfoFromBMI(
|
||||
_Inout_ ICONINFO* pii,
|
||||
_In_ const BITMAPINFO *pbmi,
|
||||
_In_ int cxDesired,
|
||||
_In_ int cyDesired
|
||||
)
|
||||
{
|
||||
UINT ubmiSize = bitmap_info_size(pbmi, DIB_RGB_COLORS);
|
||||
BOOL monochrome = is_dib_monochrome(pbmi);
|
||||
HDC hdc, hdcScreen;
|
||||
BITMAPINFO* pbmiCopy;
|
||||
HBITMAP hbmpOld = NULL;
|
||||
BOOL bResult = FALSE;
|
||||
const VOID *pvColor, *pvMask;
|
||||
|
||||
/* Check for invalid data */
|
||||
if ( (pbmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER) &&
|
||||
pbmi->bmiHeader.biSize != sizeof(BITMAPINFOHEADER)) ||
|
||||
pbmi->bmiHeader.biCompression != BI_RGB )
|
||||
{
|
||||
WARN("Invalid resource bitmap header.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Fix the hotspot coords */
|
||||
if(cxDesired != pbmi->bmiHeader.biWidth)
|
||||
pii->xHotspot = (pii->xHotspot * cxDesired) / pbmi->bmiHeader.biWidth;
|
||||
if(cxDesired != (pbmi->bmiHeader.biHeight/2))
|
||||
pii->yHotspot = (pii->yHotspot * cyDesired * 2) / pbmi->bmiHeader.biHeight;
|
||||
|
||||
hdcScreen = CreateDCW(L"DISPLAY", NULL, NULL, NULL);
|
||||
if(!hdcScreen)
|
||||
return FALSE;
|
||||
hdc = CreateCompatibleDC(hdcScreen);
|
||||
if(!hdc)
|
||||
{
|
||||
DeleteDC(hdcScreen);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pbmiCopy = HeapAlloc(GetProcessHeap(), 0, max(ubmiSize, FIELD_OFFSET(BITMAPINFO, bmiColors[3])));
|
||||
if(!pbmiCopy)
|
||||
goto done;
|
||||
RtlCopyMemory(pbmiCopy, pbmi, ubmiSize);
|
||||
pbmiCopy->bmiHeader.biHeight /= 2;
|
||||
|
||||
pvColor = (const char*)pbmi + ubmiSize;
|
||||
pvMask = (const char*)pvColor +
|
||||
get_dib_image_size(pbmi->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight, pbmi->bmiHeader.biBitCount );
|
||||
|
||||
/* Set XOR bits */
|
||||
if(monochrome)
|
||||
{
|
||||
/* Create the 1bpp bitmap which will contain everything */
|
||||
pii->hbmColor = NULL;
|
||||
pii->hbmMask = CreateCompatibleBitmap(hdc, cxDesired, cyDesired * 2);
|
||||
if(!pii->hbmMask)
|
||||
goto done;
|
||||
hbmpOld = SelectObject(hdc, pii->hbmMask);
|
||||
if(!hbmpOld)
|
||||
goto done;
|
||||
|
||||
if(!StretchDIBits(hdc, 0, cyDesired, cxDesired, cyDesired,
|
||||
0, 0, pbmiCopy->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight,
|
||||
pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create the bitmap. It has to be compatible with the screen surface */
|
||||
pii->hbmColor = CreateCompatibleBitmap(hdcScreen, cxDesired, cyDesired);
|
||||
if(!pii->hbmColor)
|
||||
goto done;
|
||||
/* Create the 1bpp mask bitmap */
|
||||
pii->hbmMask = CreateCompatibleBitmap(hdc, cxDesired, cyDesired);
|
||||
if(!pii->hbmMask)
|
||||
goto done;
|
||||
hbmpOld = SelectObject(hdc, pii->hbmColor);
|
||||
if(!hbmpOld)
|
||||
goto done;
|
||||
if(!StretchDIBits(hdc, 0, 0, cxDesired, cyDesired,
|
||||
0, 0, pbmiCopy->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight,
|
||||
pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
|
||||
goto done;
|
||||
|
||||
/* Now convert the info to monochrome for the mask bits */
|
||||
pbmiCopy->bmiHeader.biBitCount = 1;
|
||||
/* Handle the CORE/INFO difference */
|
||||
if (pbmiCopy->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
RGBQUAD *rgb = pbmiCopy->bmiColors;
|
||||
|
||||
pbmiCopy->bmiHeader.biClrUsed = pbmiCopy->bmiHeader.biClrImportant = 2;
|
||||
rgb[0].rgbBlue = rgb[0].rgbGreen = rgb[0].rgbRed = 0x00;
|
||||
rgb[1].rgbBlue = rgb[1].rgbGreen = rgb[1].rgbRed = 0xff;
|
||||
rgb[0].rgbReserved = rgb[1].rgbReserved = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
RGBTRIPLE *rgb = (RGBTRIPLE *)(((BITMAPCOREHEADER *)pbmiCopy) + 1);
|
||||
|
||||
rgb[0].rgbtBlue = rgb[0].rgbtGreen = rgb[0].rgbtRed = 0x00;
|
||||
rgb[1].rgbtBlue = rgb[1].rgbtGreen = rgb[1].rgbtRed = 0xff;
|
||||
}
|
||||
}
|
||||
/* Set the mask bits */
|
||||
if(!SelectObject(hdc, pii->hbmMask))
|
||||
goto done;
|
||||
bResult = StretchDIBits(hdc, 0, 0, cxDesired, cyDesired,
|
||||
0, 0, pbmiCopy->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight,
|
||||
pvMask, pbmiCopy, DIB_RGB_COLORS, SRCCOPY) != 0;
|
||||
|
||||
done:
|
||||
DeleteDC(hdcScreen);
|
||||
if(hbmpOld) SelectObject(hdc, hbmpOld);
|
||||
DeleteDC(hdc);
|
||||
if(pbmiCopy) HeapFree(GetProcessHeap(), 0, pbmiCopy);
|
||||
/* Clean up in case of failure */
|
||||
if(!bResult)
|
||||
{
|
||||
if(pii->hbmMask) DeleteObject(pii->hbmMask);
|
||||
if(pii->hbmColor) DeleteObject(pii->hbmColor);
|
||||
}
|
||||
return bResult;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE
|
||||
BITMAP_LoadImageW(
|
||||
_In_opt_ HINSTANCE hinst,
|
||||
_In_ LPCWSTR lpszName,
|
||||
_In_ int cxDesired,
|
||||
_In_ int cyDesired,
|
||||
_In_ UINT fuLoad
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
HANDLE
|
||||
CURSORICON_LoadImageW(
|
||||
_In_opt_ HINSTANCE hinst,
|
||||
_In_ LPCWSTR lpszName,
|
||||
_In_ int cxDesired,
|
||||
_In_ int cyDesired,
|
||||
_In_ UINT fuLoad,
|
||||
_In_ BOOL bIcon
|
||||
)
|
||||
{
|
||||
HRSRC hrsrc, hrsrc2;
|
||||
HANDLE handle, hCurIcon;
|
||||
CURSORICONDIR* dir;
|
||||
WORD wResId;
|
||||
LPBYTE bits;
|
||||
ICONINFO ii;
|
||||
BOOL bStatus;
|
||||
|
||||
if(fuLoad & LR_LOADFROMFILE)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check if caller wants OEM icons */
|
||||
if(!hinst)
|
||||
hinst = User32Instance;
|
||||
|
||||
/* Find resource ID */
|
||||
hrsrc = FindResourceW(
|
||||
hinst,
|
||||
lpszName,
|
||||
(LPWSTR)(bIcon ? RT_GROUP_ICON : RT_GROUP_CURSOR));
|
||||
|
||||
/* We let FindResource, LoadResource, etc. call SetLastError */
|
||||
if(!hrsrc)
|
||||
return NULL;
|
||||
|
||||
/* Fix width/height */
|
||||
if(fuLoad & LR_DEFAULTSIZE)
|
||||
{
|
||||
if(!cxDesired) cxDesired = GetSystemMetrics(bIcon ? SM_CXICON : SM_CXCURSOR);
|
||||
if(!cyDesired) cyDesired = GetSystemMetrics(bIcon ? SM_CYICON : SM_CYCURSOR);
|
||||
}
|
||||
|
||||
/* If LR_SHARED is set, we must check for the cache */
|
||||
hCurIcon = NtUserFindExistingCursorIcon(hinst, hrsrc, cxDesired, cyDesired);
|
||||
if(hCurIcon)
|
||||
return hCurIcon;
|
||||
|
||||
handle = LoadResource(hinst, hrsrc);
|
||||
if(!handle)
|
||||
return NULL;
|
||||
|
||||
dir = LockResource(handle);
|
||||
if(!dir) return NULL;
|
||||
|
||||
/* For now, take the first entry */
|
||||
wResId = dir->idEntries[0].wResId;
|
||||
FreeResource(handle);
|
||||
|
||||
/* Get the relevant resource pointer */
|
||||
hrsrc2 = FindResourceW(
|
||||
hinst,
|
||||
MAKEINTRESOURCEW(wResId),
|
||||
(LPWSTR)(bIcon ? RT_ICON : RT_CURSOR));
|
||||
if(!hrsrc2)
|
||||
return NULL;
|
||||
|
||||
handle = LoadResource(hinst, hrsrc2);
|
||||
if(!handle)
|
||||
return NULL;
|
||||
|
||||
bits = LockResource(handle);
|
||||
if(!bits)
|
||||
{
|
||||
FreeResource(handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the hospot */
|
||||
if(bIcon)
|
||||
{
|
||||
ii.xHotspot = cxDesired/2;
|
||||
ii.yHotspot = cyDesired/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SHORT* ptr = (SHORT*)bits;
|
||||
ii.xHotspot = ptr[0];
|
||||
ii.yHotspot = ptr[1];
|
||||
bits += 2*sizeof(SHORT);
|
||||
}
|
||||
ii.fIcon = bIcon;
|
||||
|
||||
/* Get the bitmaps */
|
||||
bStatus = CURSORICON_GetIconInfoFromBMI(
|
||||
&ii,
|
||||
(BITMAPINFO*)bits,
|
||||
cxDesired,
|
||||
cyDesired);
|
||||
|
||||
FreeResource( handle );
|
||||
|
||||
if(!bStatus)
|
||||
return NULL;
|
||||
|
||||
/* Create the handle */
|
||||
hCurIcon = NtUserxCreateEmptyCurObject(bIcon ? 0 : 1);
|
||||
if(!hCurIcon)
|
||||
return NULL;
|
||||
|
||||
/* Tell win32k */
|
||||
if(fuLoad & LR_SHARED)
|
||||
bStatus = NtUserSetCursorIconData(hCurIcon, hinst, hrsrc, &ii);
|
||||
else
|
||||
bStatus = NtUserSetCursorIconData(hCurIcon, NULL, NULL, &ii);
|
||||
|
||||
if(!bStatus)
|
||||
{
|
||||
NtUserDestroyCursor(hCurIcon, TRUE);
|
||||
hCurIcon = NULL;
|
||||
}
|
||||
|
||||
DeleteObject(ii.hbmMask);
|
||||
DeleteObject(ii.hbmColor);
|
||||
|
||||
return hCurIcon;
|
||||
}
|
||||
|
||||
/************* PUBLIC FUNCTIONS *******************/
|
||||
|
||||
HANDLE WINAPI CopyImage(
|
||||
_In_ HANDLE hImage,
|
||||
_In_ UINT uType,
|
||||
_In_ int cxDesired,
|
||||
_In_ int cyDesired,
|
||||
_In_ UINT fuFlags
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HICON WINAPI CopyIcon(
|
||||
_In_ HICON hIcon
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL WINAPI DrawIcon(
|
||||
_In_ HDC hDC,
|
||||
_In_ int X,
|
||||
_In_ int Y,
|
||||
_In_ HICON hIcon
|
||||
)
|
||||
{
|
||||
return DrawIconEx(hDC, X, Y, hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
|
||||
}
|
||||
|
||||
BOOL WINAPI DrawIconEx(
|
||||
_In_ HDC hdc,
|
||||
_In_ int xLeft,
|
||||
_In_ int yTop,
|
||||
_In_ HICON hIcon,
|
||||
_In_ int cxWidth,
|
||||
_In_ int cyWidth,
|
||||
_In_ UINT istepIfAniCur,
|
||||
_In_opt_ HBRUSH hbrFlickerFreeDraw,
|
||||
_In_ UINT diFlags
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI GetIconInfo(
|
||||
_In_ HICON hIcon,
|
||||
_Out_ PICONINFO piconinfo
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI DestroyIcon(
|
||||
_In_ HICON hIcon
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HICON WINAPI LoadIconA(
|
||||
_In_opt_ HINSTANCE hInstance,
|
||||
_In_ LPCSTR lpIconName
|
||||
)
|
||||
{
|
||||
TRACE("%p, %s\n", hInstance, debugstr_a(lpIconName));
|
||||
|
||||
return LoadImageA(hInstance,
|
||||
lpIconName,
|
||||
IMAGE_ICON,
|
||||
0,
|
||||
0,
|
||||
LR_SHARED | LR_DEFAULTSIZE );
|
||||
}
|
||||
|
||||
HICON WINAPI LoadIconW(
|
||||
_In_opt_ HINSTANCE hInstance,
|
||||
_In_ LPCWSTR lpIconName
|
||||
)
|
||||
{
|
||||
TRACE("%p, %s\n", hInstance, debugstr_w(lpIconName));
|
||||
|
||||
return LoadImageW(hInstance,
|
||||
lpIconName,
|
||||
IMAGE_ICON,
|
||||
0,
|
||||
0,
|
||||
LR_SHARED | LR_DEFAULTSIZE );
|
||||
}
|
||||
|
||||
HCURSOR WINAPI LoadCursorA(
|
||||
_In_opt_ HINSTANCE hInstance,
|
||||
_In_ LPCSTR lpCursorName
|
||||
)
|
||||
{
|
||||
TRACE("%p, %s\n", hInstance, debugstr_a(lpCursorName));
|
||||
|
||||
return LoadImageA(hInstance,
|
||||
lpCursorName,
|
||||
IMAGE_CURSOR,
|
||||
0,
|
||||
0,
|
||||
LR_SHARED | LR_DEFAULTSIZE );
|
||||
}
|
||||
|
||||
HCURSOR WINAPI LoadCursorW(
|
||||
_In_opt_ HINSTANCE hInstance,
|
||||
_In_ LPCWSTR lpCursorName
|
||||
)
|
||||
{
|
||||
TRACE("%p, %s\n", hInstance, debugstr_w(lpCursorName));
|
||||
|
||||
return LoadImageW(hInstance,
|
||||
lpCursorName,
|
||||
IMAGE_CURSOR,
|
||||
0,
|
||||
0,
|
||||
LR_SHARED | LR_DEFAULTSIZE );
|
||||
}
|
||||
|
||||
HCURSOR WINAPI LoadCursorFromFileA(
|
||||
_In_ LPCSTR lpFileName
|
||||
)
|
||||
{
|
||||
TRACE("%s\n", debugstr_a(lpFileName));
|
||||
|
||||
return LoadImageA(NULL,
|
||||
lpFileName,
|
||||
IMAGE_CURSOR,
|
||||
0,
|
||||
0,
|
||||
LR_LOADFROMFILE | LR_DEFAULTSIZE );
|
||||
}
|
||||
|
||||
HCURSOR WINAPI LoadCursorFromFileW(
|
||||
_In_ LPCWSTR lpFileName
|
||||
)
|
||||
{
|
||||
TRACE("%s\n", debugstr_w(lpFileName));
|
||||
|
||||
return LoadImageW(NULL,
|
||||
lpFileName,
|
||||
IMAGE_CURSOR,
|
||||
0,
|
||||
0,
|
||||
LR_LOADFROMFILE | LR_DEFAULTSIZE );
|
||||
}
|
||||
|
||||
HBITMAP WINAPI LoadBitmapA(
|
||||
_In_opt_ HINSTANCE hInstance,
|
||||
_In_ LPCSTR lpBitmapName
|
||||
)
|
||||
{
|
||||
TRACE("%p, %s\n", hInstance, debugstr_a(lpBitmapName));
|
||||
|
||||
return LoadImageA(hInstance,
|
||||
lpBitmapName,
|
||||
IMAGE_BITMAP,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
HBITMAP WINAPI LoadBitmapW(
|
||||
_In_opt_ HINSTANCE hInstance,
|
||||
_In_ LPCWSTR lpBitmapName
|
||||
)
|
||||
{
|
||||
TRACE("%p, %s\n", hInstance, debugstr_w(lpBitmapName));
|
||||
|
||||
return LoadImageW(hInstance,
|
||||
lpBitmapName,
|
||||
IMAGE_BITMAP,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
}
|
||||
|
||||
HANDLE WINAPI LoadImageA(
|
||||
_In_opt_ HINSTANCE hinst,
|
||||
_In_ LPCSTR lpszName,
|
||||
_In_ UINT uType,
|
||||
_In_ int cxDesired,
|
||||
_In_ int cyDesired,
|
||||
_In_ UINT fuLoad
|
||||
)
|
||||
{
|
||||
HANDLE res;
|
||||
LPWSTR u_name;
|
||||
DWORD len;
|
||||
|
||||
if (IS_INTRESOURCE(lpszName))
|
||||
return LoadImageW(hinst, (LPCWSTR)lpszName, uType, cxDesired, cyDesired, fuLoad);
|
||||
|
||||
len = MultiByteToWideChar( CP_ACP, 0, lpszName, -1, NULL, 0 );
|
||||
u_name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
|
||||
MultiByteToWideChar( CP_ACP, 0, lpszName, -1, u_name, len );
|
||||
|
||||
res = LoadImageW(hinst, u_name, uType, cxDesired, cyDesired, fuLoad);
|
||||
HeapFree(GetProcessHeap(), 0, u_name);
|
||||
return res;
|
||||
}
|
||||
|
||||
HANDLE WINAPI LoadImageW(
|
||||
_In_opt_ HINSTANCE hinst,
|
||||
_In_ LPCWSTR lpszName,
|
||||
_In_ UINT uType,
|
||||
_In_ int cxDesired,
|
||||
_In_ int cyDesired,
|
||||
_In_ UINT fuLoad
|
||||
)
|
||||
{
|
||||
/* Redirect to each implementation */
|
||||
switch(uType)
|
||||
{
|
||||
case IMAGE_BITMAP:
|
||||
return BITMAP_LoadImageW(hinst, lpszName, cxDesired, cyDesired, fuLoad);
|
||||
case IMAGE_CURSOR:
|
||||
case IMAGE_ICON:
|
||||
return CURSORICON_LoadImageW(hinst, lpszName, cxDesired, cyDesired, fuLoad, uType == IMAGE_ICON);
|
||||
default:
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int WINAPI LookupIconIdFromDirectory(
|
||||
_In_ PBYTE presbits,
|
||||
_In_ BOOL fIcon
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WINAPI LookupIconIdFromDirectoryEx(
|
||||
_In_ PBYTE presbits,
|
||||
_In_ BOOL fIcon,
|
||||
_In_ int cxDesired,
|
||||
_In_ int cyDesired,
|
||||
_In_ UINT Flags
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
HICON WINAPI CreateIcon(
|
||||
_In_opt_ HINSTANCE hInstance,
|
||||
_In_ int nWidth,
|
||||
_In_ int nHeight,
|
||||
_In_ BYTE cPlanes,
|
||||
_In_ BYTE cBitsPixel,
|
||||
_In_ const BYTE *lpbANDbits,
|
||||
_In_ const BYTE *lpbXORbits
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HICON WINAPI CreateIconFromResource(
|
||||
_In_ PBYTE presbits,
|
||||
_In_ DWORD dwResSize,
|
||||
_In_ BOOL fIcon,
|
||||
_In_ DWORD dwVer
|
||||
)
|
||||
{
|
||||
return CreateIconFromResourceEx( presbits, dwResSize, fIcon, dwVer, 0,0,0);
|
||||
}
|
||||
|
||||
HICON WINAPI CreateIconFromResourceEx(
|
||||
_In_ PBYTE pbIconBits,
|
||||
_In_ DWORD cbIconBits,
|
||||
_In_ BOOL fIcon,
|
||||
_In_ DWORD dwVersion,
|
||||
_In_ int cxDesired,
|
||||
_In_ int cyDesired,
|
||||
_In_ UINT uFlags
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HICON WINAPI CreateIconIndirect(
|
||||
_In_ PICONINFO piconinfo
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HCURSOR WINAPI CreateCursor(
|
||||
_In_opt_ HINSTANCE hInst,
|
||||
_In_ int xHotSpot,
|
||||
_In_ int yHotSpot,
|
||||
_In_ int nWidth,
|
||||
_In_ int nHeight,
|
||||
_In_ const VOID *pvANDPlane,
|
||||
_In_ const VOID *pvXORPlane
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL WINAPI SetSystemCursor(
|
||||
_In_ HCURSOR hcur,
|
||||
_In_ DWORD id
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI SetCursorPos(
|
||||
_In_ int X,
|
||||
_In_ int Y
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI GetCursorPos(
|
||||
_Out_ LPPOINT lpPoint
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int WINAPI ShowCursor(
|
||||
_In_ BOOL bShow
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
HCURSOR WINAPI GetCursor(void)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL WINAPI DestroyCursor(
|
||||
_In_ HCURSOR hCursor
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
@@ -517,7 +517,11 @@ SVC_(UserSetClipboardViewer, 1)
|
||||
SVC_(UserSetConsoleReserveKeys, 2)
|
||||
SVC_(UserSetCursor, 1)
|
||||
SVC_(UserSetCursorContents, 2)
|
||||
#ifdef NEW_CURSORICON
|
||||
SVC_(UserSetCursorIconData, 4)
|
||||
#else
|
||||
SVC_(UserSetCursorIconData, 6)
|
||||
#endif
|
||||
SVC_(UserSetDbgTag, 2)
|
||||
SVC_(UserSetFocus, 1)
|
||||
SVC_(UserSetImeHotKey, 5)
|
||||
|
||||
Reference in New Issue
Block a user