#include <win32k.h>
DBG_DEFAULT_CHANNEL(UserIcon);
-static PPAGED_LOOKASIDE_LIST pgProcessLookasideList;
static LIST_ENTRY gCurIconList;
+static PAGED_LOOKASIDE_LIST *pgProcessLookasideList;
SYSTEM_CURSORINFO gSysCursorInfo;
128);
InitializeListHead(&gCurIconList);
- gSysCursorInfo.Enabled = FALSE;
- gSysCursorInfo.ButtonsDown = 0;
- gSysCursorInfo.bClipped = FALSE;
- gSysCursorInfo.LastBtnDown = 0;
- gSysCursorInfo.CurrentCursorObject = NULL;
- gSysCursorInfo.ShowingCursor = -1;
- gSysCursorInfo.ClickLockActive = FALSE;
- gSysCursorInfo.ClickLockTime = 0;
+ gSysCursorInfo.Enabled = FALSE;
+ gSysCursorInfo.ButtonsDown = 0;
+ gSysCursorInfo.bClipped = FALSE;
+ gSysCursorInfo.LastBtnDown = 0;
+ gSysCursorInfo.CurrentCursorObject = NULL;
+ gSysCursorInfo.ShowingCursor = -1;
+ gSysCursorInfo.ClickLockActive = FALSE;
+ gSysCursorInfo.ClickLockTime = 0;
return TRUE;
}
return &gSysCursorInfo;
}
+FORCEINLINE
+BOOL
+is_icon(PCURICON_OBJECT object)
+{
+ return MAKEINTRESOURCE(object->rt) == RT_ICON;
+}
+
/* This function creates a reference for the object! */
PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
{
LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry)
{
/* See if we are looking for an icon or a cursor */
- if(CurIcon->bIcon != param->bIcon)
+ if(MAKEINTRESOURCE(CurIcon->rt) != (param->bIcon ? RT_ICON : RT_CURSOR))
continue;
/* See if module names match */
if(RtlCompareUnicodeString(pustrModule, &CurIcon->ustrModule, TRUE) == 0)
{
/* They do. Now see if this is the same resource */
- if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer) && IS_INTRESOURCE(pustrRsrc->Buffer))
+ if(IS_INTRESOURCE(CurIcon->strName.Buffer) && IS_INTRESOURCE(pustrRsrc->Buffer))
{
- if(CurIcon->ustrRsrc.Buffer != pustrRsrc->Buffer)
+ if(CurIcon->strName.Buffer != pustrRsrc->Buffer)
continue;
}
- else if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer) || IS_INTRESOURCE(pustrRsrc->Buffer))
+ else if(IS_INTRESOURCE(CurIcon->strName.Buffer) || IS_INTRESOURCE(pustrRsrc->Buffer))
continue;
- else if(RtlCompareUnicodeString(pustrRsrc, &CurIcon->ustrRsrc, TRUE) != 0)
+ else if(RtlCompareUnicodeString(pustrRsrc, &CurIcon->strName, TRUE) != 0)
continue;
- if ((param->cx == CurIcon->Size.cx) &&(param->cy == CurIcon->Size.cy))
+ if ((param->cx == CurIcon->cx) && (param->cy == CurIcon->cy))
{
if (! ReferenceCurIconByProcess(CurIcon))
{
IntCreateCurIconHandle(DWORD dwNumber)
{
PCURICON_OBJECT CurIcon;
- BOOLEAN bIcon = dwNumber == 0;
HANDLE hCurIcon;
if(dwNumber == 0)
dwNumber = 1;
- CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, otCursorIcon, FIELD_OFFSET(CURICON_OBJECT, aFrame[dwNumber]));
+ CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
if (!CurIcon)
{
}
CurIcon->Self = hCurIcon;
- CurIcon->bIcon = bIcon;
InitializeListHead(&CurIcon->ProcessList);
if (! ReferenceCurIconByProcess(CurIcon))
{
ERR("Failed to add process\n");
- UserDeleteObject(hCurIcon, otCursorIcon);
UserDereferenceObject(CurIcon);
+ UserDeleteObject(hCurIcon, otCursorIcon);
return NULL;
}
BOOLEAN FASTCALL
IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi, BOOLEAN bForce)
{
- PSYSTEM_CURSORINFO CurInfo;
HBITMAP bmpMask, bmpColor, bmpAlpha;
BOOLEAN Ret, bListEmpty, bFound = FALSE;
PCURICON_PROCESS Current = NULL;
+ /* Check if this is the current cursor */
+ if(CurIcon->CURSORF_flags & CURSORF_CURRENT)
+ {
+ UserDereferenceObject(CurIcon);
+ return FALSE;
+ }
+
/* For handles created without any data (error handling) */
if(IsListEmpty(&CurIcon->ProcessList))
goto emptyList;
/* Remove it from the list */
RemoveEntryList(&CurIcon->ListEntry);
- CurInfo = IntGetSysCursorInfo();
-
- if (CurInfo->CurrentCursorObject == CurIcon)
- {
- /* Hide the cursor if we're destroying the current cursor */
- UserSetCursor(NULL, TRUE);
- }
-
- bmpMask = CurIcon->aFrame[0].hbmMask;
- bmpColor = CurIcon->aFrame[0].hbmColor;
- bmpAlpha = CurIcon->aFrame[0].hbmAlpha;
+ bmpMask = CurIcon->hbmMask;
+ bmpColor = CurIcon->hbmColor;
+ bmpAlpha = CurIcon->hbmAlpha;
/* Delete bitmaps */
if (bmpMask)
{
GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(bmpMask);
- CurIcon->aFrame[0].hbmMask = NULL;
+ CurIcon->hbmMask = NULL;
}
if (bmpColor)
{
GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(bmpColor);
- CurIcon->aFrame[0].hbmColor = NULL;
+ CurIcon->hbmColor = NULL;
}
if (bmpAlpha)
{
GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(bmpAlpha);
- CurIcon->aFrame[0].hbmAlpha = NULL;
+ CurIcon->hbmAlpha = NULL;
}
- if(!IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer))
- ExFreePoolWithTag(CurIcon->ustrRsrc.Buffer, TAG_STRING);
+ if(!IS_INTRESOURCE(CurIcon->strName.Buffer))
+ ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING);
if(CurIcon->ustrModule.Buffer)
ReleaseCapturedUnicodeString(&CurIcon->ustrModule, UserMode);
if(IconInfo)
{
/* Fill data */
- ii.fIcon = CurIcon->bIcon;
- ii.xHotspot = CurIcon->ptlHotspot.x;
- ii.yHotspot = CurIcon->ptlHotspot.y;
+ ii.fIcon = is_icon(CurIcon);
+ ii.xHotspot = CurIcon->xHotspot;
+ ii.yHotspot = CurIcon->yHotspot;
/* Copy bitmaps */
- ii.hbmMask = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmMask);
+ ii.hbmMask = BITMAP_CopyBitmap(CurIcon->hbmMask);
GreSetObjectOwner(ii.hbmMask, GDI_OBJ_HMGR_POWNED);
- ii.hbmColor = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmColor);
+ ii.hbmColor = BITMAP_CopyBitmap(CurIcon->hbmColor);
GreSetObjectOwner(ii.hbmColor, GDI_OBJ_HMGR_POWNED);
-
- if (pbpp)
- {
- PSURFACE psurfBmp;
-
- psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
- if (psurfBmp)
- {
- colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
- SURFACE_ShareUnlockSurface(psurfBmp);
- }
- }
+ colorBpp = CurIcon->bpp;
/* Copy fields */
_SEH2_TRY
if(lpResName)
{
- if(!CurIcon->ustrRsrc.Buffer)
+ if(!CurIcon->strName.Buffer)
{
EngSetLastError(ERROR_INVALID_HANDLE);
goto leave;
_SEH2_TRY
{
ProbeForWrite(lpResName, sizeof(UNICODE_STRING), 1);
- if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer))
+ if(IS_INTRESOURCE(CurIcon->strName.Buffer))
{
- lpResName->Buffer = CurIcon->ustrRsrc.Buffer;
+ lpResName->Buffer = CurIcon->strName.Buffer;
lpResName->Length = 0;
}
else
{
- lpResName->Length = min(lpResName->MaximumLength, CurIcon->ustrRsrc.Length);
- RtlCopyMemory(lpResName->Buffer, CurIcon->ustrRsrc.Buffer, lpResName->Length);
+ lpResName->Length = min(lpResName->MaximumLength, CurIcon->strName.Length);
+ RtlCopyMemory(lpResName->Buffer, CurIcon->strName.Buffer, lpResName->Length);
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
_SEH2_TRY
{
ProbeForWrite(plcx, sizeof(LONG), 1);
- RtlCopyMemory(plcx, &CurIcon->Size.cx, sizeof(LONG));
+ *plcx = CurIcon->cx;
ProbeForWrite(plcy, sizeof(LONG), 1);
- RtlCopyMemory(plcy, &CurIcon->Size.cy, sizeof(LONG));
+ *plcy = CurIcon->cy;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_TRY
{
ProbeForRead(param, sizeof(*param), 1);
- paramSafe = *param;
+ RtlCopyMemory(¶mSafe, param, sizeof(paramSafe));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
goto leave;
}
+ pcurNew->CURSORF_flags |= CURSORF_CURRENT;
}
else
{
if (pcurOld)
{
hOldCursor = (HCURSOR)pcurOld->Self;
+ pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
UserDereferenceObject(pcurOld);
}
/*
- * @implemented
+ * @unimplemented
*/
BOOL
APIENTRY
HANDLE hCurIcon,
PICONINFO UnsafeIconInfo)
{
- PCURICON_OBJECT CurIcon;
- ICONINFO IconInfo;
- PSURFACE psurfBmp;
- NTSTATUS Status;
- BOOL Ret = FALSE;
- DECLARE_RETURN(BOOL);
-
- TRACE("Enter NtUserSetCursorContents\n");
- UserEnterExclusive();
-
- if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
- {
- RETURN(FALSE);
- }
-
- /* Copy fields */
- Status = MmCopyFromCaller(&IconInfo, UnsafeIconInfo, sizeof(ICONINFO));
- if (!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- 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->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);
- 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);
- }
- }
- else
- {
- psurfBmp = SURFACE_ShareLockSurface(IconInfo.hbmMask);
- if (!psurfBmp)
- goto done;
-
- CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
- CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy / 2;
-
- SURFACE_ShareUnlockSurface(psurfBmp);
- }
- GreSetObjectOwner(IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
-
- Ret = TRUE;
-
-done:
-
- if (CurIcon)
- {
- UserDereferenceObject(CurIcon);
- }
- RETURN(Ret);
-
-CLEANUP:
- TRACE("Leave NtUserSetCursorContents, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ FIXME(" is UNIMPLEMENTED.\n");
+ return FALSE;
}
_In_ HCURSOR Handle,
_In_opt_ PUNICODE_STRING pustrModule,
_In_opt_ PUNICODE_STRING pustrRsrc,
- _In_ PICONINFO pIconInfo)
+ _In_ PCURSORDATA pCursorData)
{
PCURICON_OBJECT CurIcon;
- PSURFACE psurfBmp;
NTSTATUS Status = STATUS_SUCCESS;
BOOL Ret = FALSE;
- ICONINFO ii;
+ CURSORDATA dataSafe;
TRACE("Enter NtUserSetCursorIconData\n");
_SEH2_TRY
{
- ProbeForRead(pIconInfo, sizeof(ICONINFO), 1);
- ii = *pIconInfo;
+ ProbeForRead(pCursorData, sizeof(*pCursorData), 1);
+ RtlCopyMemory(&dataSafe, pCursorData, sizeof(dataSafe));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
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;
- /* 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)
+ if(!dataSafe.hbmMask)
{
+ ERR("NtUserSetCursorIconData was got no hbmMask.\n");
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;
- }
+ CurIcon->hbmMask = BITMAP_CopyBitmap(dataSafe.hbmMask);
+ if(!CurIcon->hbmMask)
+ goto done;
+ GreSetObjectOwner(CurIcon->hbmMask, GDI_OBJ_HMGR_PUBLIC);
- if (CurIcon->aFrame[0].hbmColor)
+ if(dataSafe.hbmColor)
{
- psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
- if(!psurfBmp)
+ CurIcon->hbmColor = BITMAP_CopyBitmap(dataSafe.hbmColor);
+ if(!CurIcon->hbmColor)
goto done;
-
- CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
- CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
- SURFACE_ShareUnlockSurface(psurfBmp);
- GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_PUBLIC);
+ GreSetObjectOwner(CurIcon->hbmColor, GDI_OBJ_HMGR_PUBLIC);
}
- else
+
+ if(dataSafe.hbmAlpha)
{
- psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmMask);
- if(!psurfBmp)
+ CurIcon->hbmAlpha = BITMAP_CopyBitmap(dataSafe.hbmAlpha);
+ if(!CurIcon->hbmAlpha)
goto done;
-
- CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
- CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy/2;
- SURFACE_ShareUnlockSurface(psurfBmp);
+ GreSetObjectOwner(CurIcon->hbmAlpha, GDI_OBJ_HMGR_PUBLIC);
}
- GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
if(pustrModule)
{
/* We use this convenient function, because INTRESOURCEs and ATOMs are the same */
- Status = ProbeAndCaptureUnicodeStringOrAtom(&CurIcon->ustrRsrc, pustrRsrc);
+ Status = ProbeAndCaptureUnicodeStringOrAtom(&CurIcon->strName, pustrRsrc);
if(!NT_SUCCESS(Status))
goto done;
Status = ProbeAndCaptureUnicodeString(&CurIcon->ustrModule, UserMode, pustrModule);
Ret = TRUE;
done:
- UserDereferenceObject(CurIcon);
if(!Ret)
{
- if (CurIcon->aFrame[0].hbmMask)
+ if (CurIcon->hbmMask)
{
- GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_POWNED);
- GreDeleteObject(CurIcon->aFrame[0].hbmMask);
- CurIcon->aFrame[0].hbmMask = NULL;
+ GreSetObjectOwner(CurIcon->hbmMask, GDI_OBJ_HMGR_POWNED);
+ GreDeleteObject(CurIcon->hbmMask);
+ CurIcon->hbmMask = NULL;
}
- if (CurIcon->aFrame[0].hbmColor)
+ if (CurIcon->hbmColor)
{
- GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_POWNED);
- GreDeleteObject(CurIcon->aFrame[0].hbmColor);
- CurIcon->aFrame[0].hbmColor = NULL;
+ GreSetObjectOwner(CurIcon->hbmColor, GDI_OBJ_HMGR_POWNED);
+ GreDeleteObject(CurIcon->hbmColor);
+ CurIcon->hbmColor = NULL;
}
- if(!IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer))
- ExFreePoolWithTag(CurIcon->ustrRsrc.Buffer, TAG_STRING);
+ 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)
ReleaseCapturedUnicodeString(&CurIcon->ustrModule, UserMode);
}
-
+ UserDereferenceObject(CurIcon);
TRACE("Leave NtUserSetCursorIconData, ret=%i\n",Ret);
UserLeave();
return FALSE;
}
- hbmMask = pIcon->aFrame[0].hbmMask;
- hbmColor = pIcon->aFrame[0].hbmColor;
- hbmAlpha = pIcon->aFrame[0].hbmAlpha;
+ hbmMask = pIcon->hbmMask;
+ hbmColor = pIcon->hbmColor;
+ hbmAlpha = pIcon->hbmAlpha;
if (istepIfAniCur)
ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
if(hbmColor == NULL)
{
/* But then the mask bitmap must have the information in it's bottom half */
- ASSERT(psurfMask->SurfObj.sizlBitmap.cy == 2*pIcon->Size.cy);
+ ASSERT(psurfMask->SurfObj.sizlBitmap.cy == 2*pIcon->cy);
psurfColor = NULL;
}
else if ((psurfColor = SURFACE_ShareLockSurface(hbmColor)) == NULL)
}
/* Set source rect */
- RECTL_vSetRect(&rcSrc, 0, 0, pIcon->Size.cx, pIcon->Size.cy);
+ RECTL_vSetRect(&rcSrc, 0, 0, pIcon->cx, pIcon->cy);
/* Fix width parameter, if needed */
if (!cxWidth)
{
if(diFlags & DI_DEFAULTSIZE)
- cxWidth = pIcon->bIcon ?
+ cxWidth = is_icon(pIcon) ?
UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR);
else
- cxWidth = pIcon->Size.cx;
+ cxWidth = pIcon->cx;
}
/* Fix height parameter, if needed */
if (!cyHeight)
{
if(diFlags & DI_DEFAULTSIZE)
- cyHeight = pIcon->bIcon ?
+ cyHeight = is_icon(pIcon) ?
UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR);
else
- cyHeight = pIcon->Size.cy;
+ cyHeight = pIcon->cy;
}
/* Should we render off-screen? */
}
/* Now do the rendering */
- if(hbmAlpha && (diFlags & DI_IMAGE))
+ if(hbmAlpha && ((diFlags & DI_NORMAL) == DI_NORMAL))
{
BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } };
PSURFACE psurf = NULL;
{
/* 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);
+ RECTL_vOffsetRect(&rcSrc, 0, pIcon->cy);
EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
/*
* PROJECT: ReactOS user32.dll
* COPYRIGHT: GPL - See COPYING in the top level directory
- * FILE: dll/win32/user32/windows/class.c
- * PURPOSE: Window classes
+ * FILE: dll/win32/user32/windows/cursoricon.c
+ * PURPOSE: cursor and icons implementation
* PROGRAMMER: Jérôme Gardou (jerome.gardou@reactos.org)
*/
return -1;
}
+/***********************************************************************
+ * bmi_has_alpha
+ */
+static BOOL bmi_has_alpha( const BITMAPINFO *info, const void *bits )
+{
+ int i;
+ BOOL has_alpha = FALSE;
+ const unsigned char *ptr = bits;
+
+ if (info->bmiHeader.biBitCount != 32) return FALSE;
+ for (i = 0; i < info->bmiHeader.biWidth * abs(info->bmiHeader.biHeight); i++, ptr += 4)
+ if ((has_alpha = (ptr[3] != 0))) break;
+ return has_alpha;
+}
+
+/***********************************************************************
+ * create_alpha_bitmap
+ *
+ * Create the alpha bitmap for a 32-bpp icon that has an alpha channel.
+ */
+static HBITMAP create_alpha_bitmap(
+ _In_ HBITMAP color,
+ _In_opt_ const BITMAPINFO *src_info,
+ _In_opt_ const void *color_bits )
+{
+ HBITMAP alpha = NULL, hbmpOld;
+ BITMAPINFO *info = NULL;
+ HDC hdc = NULL, hdcScreen;
+ void *bits = NULL;
+ unsigned char *ptr;
+ int i;
+ LONG width, height;
+ BITMAP bm;
+
+ if (!GetObjectW( color, sizeof(bm), &bm ))
+ return NULL;
+ if (bm.bmBitsPixel != 32)
+ return NULL;
+
+ hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
+ if(!hdcScreen)
+ return NULL;
+ if(GetDeviceCaps(hdcScreen, BITSPIXEL) != 32)
+ goto done;
+ hdc = CreateCompatibleDC(hdcScreen);
+ if(!hdc)
+ goto done;
+
+ if(src_info)
+ {
+ WORD bpp;
+ DWORD compr;
+ int size;
+
+ if(!bmi_has_alpha(src_info, color_bits))
+ goto done;
+
+ if(!DIB_GetBitmapInfo(&src_info->bmiHeader, &width, &height, &bpp, &compr))
+ goto done;
+ if(bpp != 32)
+ goto done;
+
+ size = get_dib_image_size(width, height, bpp);
+ bits = HeapAlloc(GetProcessHeap(), 0, size);
+ if(!bits)
+ goto done;
+ CopyMemory(bits, color_bits, size);
+ }
+ else
+ {
+ info = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(BITMAPINFO, bmiColors[256]));
+ if(!info)
+ goto done;
+ info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ info->bmiHeader.biWidth = bm.bmWidth;
+ info->bmiHeader.biHeight = -bm.bmHeight;
+ info->bmiHeader.biPlanes = 1;
+ info->bmiHeader.biBitCount = 32;
+ info->bmiHeader.biCompression = BI_RGB;
+ info->bmiHeader.biSizeImage = bm.bmWidth * bm.bmHeight * 4;
+ info->bmiHeader.biXPelsPerMeter = 0;
+ info->bmiHeader.biYPelsPerMeter = 0;
+ info->bmiHeader.biClrUsed = 0;
+ info->bmiHeader.biClrImportant = 0;
+
+ bits = HeapAlloc(GetProcessHeap(), 0, info->bmiHeader.biSizeImage);
+ if(!bits)
+ goto done;
+ if(!GetDIBits( hdc, color, 0, bm.bmHeight, bits, info, DIB_RGB_COLORS ))
+ goto done;
+ if (!bmi_has_alpha( info, bits ))
+ goto done;
+ width = bm.bmWidth;
+ height = bm.bmHeight;
+ }
+
+ /* pre-multiply by alpha */
+ for (i = 0, ptr = bits; i < width * height; i++, ptr += 4)
+ {
+ unsigned int alpha = ptr[3];
+ ptr[0] = ptr[0] * alpha / 255;
+ ptr[1] = ptr[1] * alpha / 255;
+ ptr[2] = ptr[2] * alpha / 255;
+ }
+
+ /* Create the bitmap */
+ alpha = CreateCompatibleBitmap(hdcScreen, bm.bmWidth, bm.bmHeight);
+ if(!alpha)
+ goto done;
+ hbmpOld = SelectObject(hdc, alpha);
+ if(!hbmpOld)
+ goto done;
+ if(!StretchDIBits( hdc, 0, 0, bm.bmWidth, bm.bmHeight,
+ 0, 0, width, height,
+ bits, src_info ? src_info : info, DIB_RGB_COLORS, SRCCOPY ))
+ {
+ SelectObject(hdc, hbmpOld);
+ hbmpOld = NULL;
+ DeleteObject(alpha);
+ alpha = NULL;
+ }
+ SelectObject(hdc, hbmpOld);
+
+done:
+ DeleteDC(hdcScreen);
+ if(hdc) DeleteDC( hdc );
+ if(info) HeapFree( GetProcessHeap(), 0, info );
+ if(bits) HeapFree(GetProcessHeap(), 0, bits);
+
+ TRACE("Returning 0x%08x.\n", alpha);
+ return alpha;
+}
+
/************* IMPLEMENTATION CORE ****************/
-static BOOL CURSORICON_GetIconInfoFromBMI(
- _Inout_ ICONINFO* pii,
- _In_ const BITMAPINFO *pbmi,
- _In_ int cxDesired,
- _In_ int cyDesired
+static BOOL CURSORICON_GetCursorDataFromBMI(
+ _Inout_ CURSORDATA* pdata,
+ _In_ const BITMAPINFO *pbmi
)
{
UINT ubmiSize = bitmap_info_size(pbmi, DIB_RGB_COLORS);
if(compr != BI_RGB)
return FALSE;
+ /* If no dimensions were set, use the one from the icon */
+ if(!pdata->cx) pdata->cx = width;
+ if(!pdata->cy) pdata->cy = height < 0 ? -height/2 : height/2;
+
/* Fix the hotspot coords */
- if(!pii->fIcon)
+ if(pdata->rt == (USHORT)((ULONG_PTR)RT_CURSOR))
{
- 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;
+ if(pdata->cx != width)
+ pdata->xHotspot = (pdata->xHotspot * pdata->cx) / width;
+ if(pdata->cy != height/2)
+ pdata->yHotspot = (pdata->yHotspot * pdata->cy * 2) / height;
+ }
+ else
+ {
+ pdata->xHotspot = pdata->cx/2;
+ pdata->yHotspot = pdata->cy/2;
}
hdcScreen = CreateDCW(DISPLAYW, NULL, NULL, NULL);
((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcHeight /= 2;
else
pbmiCopy->bmiHeader.biHeight /= 2;
+ height /= 2;
pvColor = (const char*)pbmi + ubmiSize;
pvMask = (const char*)pvColor +
- get_dib_image_size(pbmi->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight, pbmi->bmiHeader.biBitCount );
+ get_dib_image_size(width, height, bpp );
/* 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)
+ pdata->hbmColor = NULL;
+ pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy * 2, 1, 1, NULL);
+ if(!pdata->hbmMask)
goto done;
- hbmpOld = SelectObject(hdc, pii->hbmMask);
+ hbmpOld = SelectObject(hdc, pdata->hbmMask);
if(!hbmpOld)
goto done;
- if(!StretchDIBits(hdc, 0, cyDesired, cxDesired, cyDesired,
- 0, 0, pbmiCopy->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight,
+ if(!StretchDIBits(hdc, 0, pdata->cy, pdata->cx, pdata->cy,
+ 0, 0, width, height,
pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
goto done;
+ pdata->bpp = 1;
}
else
{
/* Create the bitmap. It has to be compatible with the screen surface */
- pii->hbmColor = CreateCompatibleBitmap(hdcScreen, cxDesired, cyDesired);
- if(!pii->hbmColor)
+ pdata->hbmColor = CreateCompatibleBitmap(hdcScreen, pdata->cx, pdata->cy);
+ if(!pdata->hbmColor)
goto done;
/* Create the 1bpp mask bitmap */
- pii->hbmMask = CreateCompatibleBitmap(hdc, cxDesired, cyDesired);
- if(!pii->hbmMask)
+ pdata->hbmMask = CreateBitmap(pdata->cx, pdata->cy, 1, 1, NULL);
+ if(!pdata->hbmMask)
goto done;
- hbmpOld = SelectObject(hdc, pii->hbmColor);
+ hbmpOld = SelectObject(hdc, pdata->hbmColor);
if(!hbmpOld)
goto done;
- if(!StretchDIBits(hdc, 0, 0, cxDesired, cyDesired,
- 0, 0, pbmiCopy->bmiHeader.biWidth, pbmiCopy->bmiHeader.biHeight,
+ if(!StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy,
+ 0, 0, width, height,
pvColor, pbmiCopy, DIB_RGB_COLORS, SRCCOPY))
goto done;
+ pdata->bpp = GetDeviceCaps(hdcScreen, BITSPIXEL);
+ if(pdata->bpp == 32)
+ pdata->hbmAlpha = create_alpha_bitmap(pdata->hbmColor, pbmiCopy, pvColor);
/* 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;
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;
+ pbmiCopy->bmiHeader.biBitCount = 1;
}
else
{
rgb[0].rgbtBlue = rgb[0].rgbtGreen = rgb[0].rgbtRed = 0x00;
rgb[1].rgbtBlue = rgb[1].rgbtGreen = rgb[1].rgbtRed = 0xff;
+ ((BITMAPCOREHEADER*)&pbmiCopy->bmiHeader)->bcBitCount = 1;
}
}
/* Set the mask bits */
- if(!SelectObject(hdc, pii->hbmMask))
+ if(!SelectObject(hdc, pdata->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;
+ bResult = StretchDIBits(hdc, 0, 0, pdata->cx, pdata->cy,
+ 0, 0, width, height,
+ pvMask, pbmiCopy, DIB_RGB_COLORS, SRCCOPY) != 0;
done:
DeleteDC(hdcScreen);
/* Clean up in case of failure */
if(!bResult)
{
- if(pii->hbmMask) DeleteObject(pii->hbmMask);
- if(pii->hbmColor) DeleteObject(pii->hbmColor);
+ if(pdata->hbmMask) DeleteObject(pdata->hbmMask);
+ if(pdata->hbmColor) DeleteObject(pdata->hbmColor);
+ if(pdata->hbmAlpha) DeleteObject(pdata->hbmAlpha);
}
return bResult;
}
+static BOOL CURSORICON_GetCursorDataFromIconInfo(
+ _Out_ CURSORDATA* pCursorData,
+ _In_ ICONINFO* pIconInfo
+)
+{
+ BITMAP bm;
+
+ ZeroMemory(pCursorData, sizeof(*pCursorData));
+ /* Use the CopyImage function, as it will gracefully convert our bitmap to the screen bit depth */
+ if(pIconInfo->hbmColor)
+ {
+ pCursorData->hbmColor = CopyImage(pIconInfo->hbmColor, IMAGE_BITMAP, 0, 0, 0);
+ if(!pCursorData->hbmColor)
+ return FALSE;
+ }
+ pCursorData->hbmMask = CopyImage(pIconInfo->hbmMask, IMAGE_BITMAP, 0, 0, LR_MONOCHROME);
+ if(!pCursorData->hbmMask)
+ return FALSE;
+
+ /* Now, fill some information */
+ pCursorData->rt = (USHORT)((ULONG_PTR)(pIconInfo->fIcon ? RT_ICON : RT_CURSOR));
+ if(pCursorData->hbmColor)
+ {
+ GetObject(pCursorData->hbmColor, sizeof(bm), &bm);
+ pCursorData->bpp = bm.bmBitsPixel;
+ pCursorData->cx = bm.bmWidth;
+ pCursorData->cy = bm.bmHeight;
+ if(pCursorData->bpp == 32)
+ pCursorData->hbmAlpha = create_alpha_bitmap(pCursorData->hbmColor, NULL, NULL);
+ }
+ else
+ {
+ GetObject(pCursorData->hbmMask, sizeof(bm), &bm);
+ pCursorData->bpp = 1;
+ pCursorData->cx = bm.bmWidth;
+ pCursorData->cy = bm.bmHeight/2;
+ }
+
+ if(pIconInfo->fIcon)
+ {
+ pCursorData->xHotspot = pCursorData->cx/2;
+ pCursorData->yHotspot = pCursorData->cy/2;
+ }
+ else
+ {
+ pCursorData->xHotspot = pIconInfo->xHotspot;
+ pCursorData->yHotspot = pIconInfo->yHotspot;
+ }
+
+ return TRUE;
+}
+
static
HBITMAP
BITMAP_LoadImageW(
const BITMAPINFO* pbmi;
BITMAPINFO* pbmiScaled = NULL;
BITMAPINFO* pbmiCopy = NULL;
- const VOID* pvMapping;
+ const VOID* pvMapping = NULL;
DWORD dwOffset = 0;
- HGLOBAL hgRsrc;
+ HGLOBAL hgRsrc = NULL;
int iBMISize;
PVOID pvBits;
HDC hdcScreen = NULL;
HDC hdc = NULL;
- HBITMAP hbmpRet, hbmpOld;
+ HBITMAP hbmpOld, hbmpRet = NULL;
+ LONG width, height;
+ WORD bpp;
+ DWORD compr;
/* Map the bitmap info */
if(fuLoad & LR_LOADFROMFILE)
return NULL;
}
- /* See if we must scale the bitmap */
+ /* Fix up values */
+ if(DIB_GetBitmapInfo(&pbmi->bmiHeader, &width, &height, &bpp, &compr) == -1)
+ goto end;
+ if((width > 65535) || (height > 65535))
+ goto end;
+ if(cxDesired == 0)
+ cxDesired = width;
+ if(cyDesired == 0)
+ cyDesired = height;
+ else if(height < 0)
+ cyDesired = -cyDesired;
+
iBMISize = bitmap_info_size(pbmi, DIB_RGB_COLORS);
/* Get a pointer to the image data */
if(pbmiScaled->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
BITMAPCOREHEADER* pbmch = (BITMAPCOREHEADER*)&pbmiScaled->bmiHeader;
- if(cxDesired == 0)
- cxDesired = pbmch->bcWidth;
- if(cyDesired == 0)
- cyDesired == pbmch->bcHeight;
- else if(pbmch->bcHeight < 0)
- cyDesired = -cyDesired;
-
pbmch->bcWidth = cxDesired;
pbmch->bcHeight = cyDesired;
}
else
{
- if ((pbmi->bmiHeader.biHeight > 65535) || (pbmi->bmiHeader.biWidth > 65535)) {
- WARN("Broken BITMAPINFO!\n");
- goto end;
- }
-
- if(cxDesired == 0)
- cxDesired = pbmi->bmiHeader.biWidth;
- if(cyDesired == 0)
- cyDesired = pbmi->bmiHeader.biHeight;
- else if(pbmi->bmiHeader.biHeight < 0)
- cyDesired = -cyDesired;
-
pbmiScaled->bmiHeader.biWidth = cxDesired;
pbmiScaled->bmiHeader.biHeight = cyDesired;
/* No compression for DIB sections */
- if(fuLoad & LR_CREATEDIBSECTION)
- pbmiScaled->bmiHeader.biCompression = BI_RGB;
+ pbmiScaled->bmiHeader.biCompression = BI_RGB;
}
}
HeapFree(GetProcessHeap(), 0, pbmiScaled);
if(pbmiCopy)
HeapFree(GetProcessHeap(), 0, pbmiCopy);
- if (fuLoad & LR_LOADFROMFILE)
+ if (pvMapping)
UnmapViewOfFile( pvMapping );
- else
+ if(hgRsrc)
FreeResource(hgRsrc);
return hbmpRet;
CURSORICONFILEDIR *dir;
DWORD filesize = 0;
LPBYTE bits;
- HANDLE hRet = NULL;
+ HANDLE hCurIcon = NULL;
WORD i;
- ICONINFO ii;
+ CURSORDATA cursorData;
TRACE("loading %s\n", debugstr_w( lpszName ));
/* Get our entry */
entry = &dir->idEntries[i-1];
+ /* Fix dimensions */
+ if(!cxDesired) cxDesired = entry->bWidth;
+ if(!cyDesired) cyDesired = entry->bHeight;
/* A bit of preparation */
- ii.xHotspot = entry->xHotspot;
- ii.yHotspot = entry->yHotspot;
- ii.fIcon = bIcon;
+ ZeroMemory(&cursorData, sizeof(cursorData));
+ if(!bIcon)
+ {
+ cursorData.xHotspot = entry->xHotspot;
+ cursorData.yHotspot = entry->yHotspot;
+ }
+ cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR));
/* Do the dance */
- if(!CURSORICON_GetIconInfoFromBMI(&ii, (BITMAPINFO*)&bits[entry->dwDIBOffset], cxDesired, cyDesired))
+ if(!CURSORICON_GetCursorDataFromBMI(&cursorData, (BITMAPINFO*)&bits[entry->dwDIBOffset]))
goto end;
- /* Create the icon. NOTE: there's no LR_SHARED icons if they are created from file */
- hRet = CreateIconIndirect(&ii);
+ hCurIcon = NtUserxCreateEmptyCurObject(bIcon ? 0 : 1);
+ if(!hCurIcon)
+ goto end_clean;
+
+ /* Tell win32k */
+ if(!NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData))
+ {
+ NtUserDestroyCursor(hCurIcon, TRUE);
+ hCurIcon = NULL;
+ }
/* Clean up */
- DeleteObject(ii.hbmMask);
- DeleteObject(ii.hbmColor);
+end_clean:
+ DeleteObject(cursorData.hbmMask);
+ if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
+ if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
end:
UnmapViewOfFile(bits);
- return hRet;
+ return hCurIcon;
}
static
CURSORICONDIR* dir;
WORD wResId;
LPBYTE bits;
- ICONINFO ii;
+ CURSORDATA cursorData;
BOOL bStatus;
UNICODE_STRING ustrRsrc;
UNICODE_STRING ustrModule = {0, 0, NULL};
/* Get it */
do
{
- DWORD ret = GetModuleFileName(hinst, ustrModule.Buffer, size);
+ DWORD ret = GetModuleFileNameW(hinst, ustrModule.Buffer, size);
if(ret == 0)
{
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
}
if(ret < size)
{
- ustrModule.Length = ret;
- ustrModule.MaximumLength = size;
+ ustrModule.Length = ret*sizeof(WCHAR);
+ ustrModule.MaximumLength = size*sizeof(WCHAR);
break;
}
size *= 2;
goto done;
}
- /* Get the hotspot */
- if(bIcon)
- {
- ii.xHotspot = cxDesired/2;
- ii.yHotspot = cyDesired/2;
- }
- if(!bIcon)
+ ZeroMemory(&cursorData, sizeof(cursorData));
+
+ if(dir->idType == 2)
{
+ /* idType == 2 for cursor resources */
SHORT* ptr = (SHORT*)bits;
- ii.xHotspot = ptr[0];
- ii.yHotspot = ptr[1];
+ cursorData.xHotspot = ptr[0];
+ cursorData.yHotspot = ptr[1];
bits += 2*sizeof(SHORT);
}
- ii.fIcon = bIcon;
+ cursorData.cx = cxDesired;
+ cursorData.cy = cyDesired;
+ cursorData.rt = (USHORT)((ULONG_PTR)(bIcon ? RT_ICON : RT_CURSOR));
/* Get the bitmaps */
- bStatus = CURSORICON_GetIconInfoFromBMI(
- &ii,
- (BITMAPINFO*)bits,
- cxDesired,
- cyDesired);
+ bStatus = CURSORICON_GetCursorDataFromBMI(
+ &cursorData,
+ (BITMAPINFO*)bits);
FreeResource( handle );
hCurIcon = NtUserxCreateEmptyCurObject(bIcon ? 0 : 1);
if(!hCurIcon)
{
- DeleteObject(ii.hbmMask);
- if(ii.hbmColor) DeleteObject(ii.hbmColor);
+ DeleteObject(cursorData.hbmMask);
+ if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
+ if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
goto done;
}
/* Tell win32k */
if(fuLoad & LR_SHARED)
- bStatus = NtUserSetCursorIconData(hCurIcon, &ustrModule, &ustrRsrc, &ii);
+ bStatus = NtUserSetCursorIconData(hCurIcon, &ustrModule, &ustrRsrc, &cursorData);
else
- bStatus = NtUserSetCursorIconData(hCurIcon, NULL, NULL, &ii);
+ bStatus = NtUserSetCursorIconData(hCurIcon, NULL, NULL, &cursorData);
if(!bStatus)
{
hCurIcon = NULL;
}
- DeleteObject(ii.hbmMask);
- if(ii.hbmColor) DeleteObject(ii.hbmColor);
+ DeleteObject(cursorData.hbmMask);
+ if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
+ if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
done:
if(ustrModule.Buffer)
static
HBITMAP
BITMAP_CopyImage(
- _In_ HBITMAP hbmp,
- _In_ int cxDesired,
- _In_ int cyDesired,
- _In_ UINT fuFlags
+ _In_ HBITMAP hnd,
+ _In_ int desiredx,
+ _In_ int desiredy,
+ _In_ UINT flags
)
{
HBITMAP res = NULL;
int objSize;
BITMAPINFO * bi;
- objSize = GetObjectW( hbmp, sizeof(ds), &ds );
+ objSize = GetObjectW( hnd, sizeof(ds), &ds );
if (!objSize) return 0;
- if ((cxDesired < 0) || (cyDesired < 0)) return 0;
+ if ((desiredx < 0) || (desiredy < 0)) return 0;
- if (fuFlags & LR_COPYFROMRESOURCE)
+ if (flags & LR_COPYFROMRESOURCE)
{
FIXME("The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
}
- if (fuFlags & LR_COPYRETURNORG)
+ if (flags & LR_COPYRETURNORG)
{
FIXME("The flag LR_COPYRETURNORG is not implemented for bitmaps\n");
}
- if (cxDesired == 0) cxDesired = ds.dsBm.bmWidth;
- if (cyDesired == 0) cyDesired = ds.dsBm.bmHeight;
+ if (desiredx == 0) desiredx = ds.dsBm.bmWidth;
+ if (desiredy == 0) desiredy = ds.dsBm.bmHeight;
/* Allocate memory for a BITMAPINFOHEADER structure and a
color table. The maximum number of colors in a color table
bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
bi->bmiHeader.biCompression = BI_RGB;
- if (fuFlags & LR_CREATEDIBSECTION)
+ if (flags & LR_CREATEDIBSECTION)
{
/* Create a DIB section. LR_MONOCHROME is ignored */
void * bits;
memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
}
- /* Get the color table or the color masks */
- GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
+ bi->bmiHeader.biWidth = desiredx;
+ bi->bmiHeader.biHeight = desiredy;
- bi->bmiHeader.biWidth = cxDesired;
- bi->bmiHeader.biHeight = cyDesired;
- bi->bmiHeader.biSizeImage = 0;
+ /* Get the color table or the color masks */
+ GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
res = CreateDIBSection(dc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
DeleteDC(dc);
{
/* Create a device-dependent bitmap */
- BOOL monochrome = (fuFlags & LR_MONOCHROME);
+ BOOL monochrome = (flags & LR_MONOCHROME);
if (objSize == sizeof(DIBSECTION))
{
/* The source bitmap is a DIB section.
Get its attributes */
HDC dc = CreateCompatibleDC(NULL);
- bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
- bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
- GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
+ bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
+ bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
+ GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
DeleteDC(dc);
if (!monochrome && ds.dsBm.bmBitsPixel == 1)
if (monochrome)
{
- res = CreateBitmap(cxDesired, cyDesired, 1, 1, NULL);
+ res = CreateBitmap(desiredx, desiredy, 1, 1, NULL);
}
else
{
HDC screenDC = GetDC(NULL);
- res = CreateCompatibleBitmap(screenDC, cxDesired, cyDesired);
+ res = CreateCompatibleBitmap(screenDC, desiredx, desiredy);
ReleaseDC(NULL, screenDC);
}
}
bi->bmiHeader.biClrImportant = 0;
/* Fill in biSizeImage */
- GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
+ GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bi->bmiHeader.biSizeImage);
if (bits)
HBITMAP oldBmp;
/* Get the image bits of the source bitmap */
- GetDIBits(dc, hbmp, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
+ GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
/* Copy it to the destination bitmap */
oldBmp = SelectObject(dc, res);
- StretchDIBits(dc, 0, 0, cxDesired, cyDesired,
+ StretchDIBits(dc, 0, 0, desiredx, desiredy,
0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight,
bits, bi, DIB_RGB_COLORS, SRCCOPY);
SelectObject(dc, oldBmp);
DeleteDC(dc);
}
- if (fuFlags & LR_COPYDELETEORG)
+ if (flags & LR_COPYDELETEORG)
{
- DeleteObject(hbmp);
+ DeleteObject(hnd);
}
}
HeapFree(GetProcessHeap(), 0, bi);
PVOID pvBuf;
HMODULE hModule;
- ustrModule.MaximumLength = MAX_PATH;
+ ustrModule.MaximumLength = MAX_PATH * sizeof(WCHAR);
ustrRsrc.MaximumLength = 256;
- ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength * sizeof(WCHAR));
+ ustrModule.Buffer = HeapAlloc(GetProcessHeap(), 0, ustrModule.MaximumLength);
if(!ustrModule.Buffer)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
/* Keep track of the buffer for the resource, NtUserGetIconInfo might overwrite it */
- pvBuf = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(WCHAR));
+ pvBuf = HeapAlloc(GetProcessHeap(), 0, ustrRsrc.MaximumLength);
if(!pvBuf)
{
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
{
PWSTR newBuffer;
ustrModule.MaximumLength *= 2;
- newBuffer = HeapReAlloc(GetProcessHeap(), 0, ustrModule.Buffer, ustrModule.MaximumLength * sizeof(WCHAR));
+ newBuffer = HeapReAlloc(GetProcessHeap(), 0, ustrModule.Buffer, ustrModule.MaximumLength);
if(!ustrModule.Buffer)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
if(ustrRsrc.Length == ustrRsrc.MaximumLength)
{
ustrRsrc.MaximumLength *= 2;
- pvBuf = HeapReAlloc(GetProcessHeap(), 0, ustrRsrc.Buffer, ustrRsrc.MaximumLength * sizeof(WCHAR));
+ pvBuf = HeapReAlloc(GetProcessHeap(), 0, ustrRsrc.Buffer, ustrRsrc.MaximumLength);
if(!pvBuf)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
} while(TRUE);
/* NULL-terminate our strings */
- ustrModule.Buffer[ustrModule.Length] = 0;
+ ustrModule.Buffer[ustrModule.Length/sizeof(WCHAR)] = 0;
if(!IS_INTRESOURCE(ustrRsrc.Buffer))
- ustrRsrc.Buffer[ustrRsrc.Length] = 0;
+ ustrRsrc.Buffer[ustrRsrc.Length/sizeof(WCHAR)] = 0;
/* Get the module handle */
if(!GetModuleHandleExW(0, ustrModule.Buffer, &hModule))
{
/* This hould never happen */
+ ERR("Invalid handle?.\n");
SetLastError(ERROR_INVALID_PARAMETER);
goto leave;
}
HeapFree(GetProcessHeap(), 0, ustrModule.Buffer);
HeapFree(GetProcessHeap(), 0, pvBuf);
+ TRACE("Returning 0x%08x.\n", ret);
+
return ret;
}
return 0;
}
- /* idType == 2 is for cursors, 1 for icons */
- /*if(fIcon)
- {
- if(dir->idType == 2)
- {
- WARN("An icon was asked for a cursor resource.\n");
- return 0;
- }
- }
- else if(dir->idType == 1)
- {
- WARN("A cursor was asked for an icon resource.\n");
- return 0;
- }*/
-
if(Flags & LR_MONOCHROME)
bppDesired = 1;
else
bppDesired = GetDeviceCaps(icScreen, BITSPIXEL);
DeleteDC(icScreen);
}
+
+ if(!cxDesired)
+ cxDesired = GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR);
+ if(!cyDesired)
+ cyDesired = GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR);
/* Find the best match for the desired size */
cxyDiff = 0xFFFFFFFF;
_In_ DWORD dwVer
)
{
- return CreateIconFromResourceEx( presbits, dwResSize, fIcon, dwVer, 0,0,0);
+ return CreateIconFromResourceEx( presbits, dwResSize, fIcon, dwVer, 0, 0, LR_DEFAULTSIZE | LR_SHARED);
}
HICON WINAPI CreateIconFromResourceEx(
_In_ UINT uFlags
)
{
- ICONINFO ii;
+ CURSORDATA cursorData;
HICON hIcon;
- if(uFlags)
- FIXME("uFlags 0x%08x ignored.\n", uFlags);
+ TRACE("%p, %lu, %lu, %lu, %i, %i, %lu.\n", pbIconBits, cbIconBits, fIcon, dwVersion, cxDesired, cyDesired, uFlags);
+
+ if(uFlags & ~LR_DEFAULTSIZE)
+ FIXME("uFlags 0x%08x ignored.\n", uFlags & ~LR_DEFAULTSIZE);
- if(fIcon)
+ if(uFlags & LR_DEFAULTSIZE)
{
- ii.xHotspot = cxDesired/2;
- ii.yHotspot = cyDesired/2;
+ if(!cxDesired) cxDesired = GetSystemMetrics(fIcon ? SM_CXICON : SM_CXCURSOR);
+ if(!cyDesired) cyDesired = GetSystemMetrics(fIcon ? SM_CYICON : SM_CYCURSOR);
}
- else
+
+ /* Check if this is an animated cursor */
+ if(!memcmp(pbIconBits, "RIFF", 4))
+ {
+ UNIMPLEMENTED;
+ return NULL;
+ }
+
+ ZeroMemory(&cursorData, sizeof(cursorData));
+ cursorData.cx = cxDesired;
+ cursorData.cy = cyDesired;
+ cursorData.rt = (USHORT)((ULONG_PTR)(fIcon ? RT_ICON : RT_CURSOR));
+ if(!fIcon)
{
WORD* pt = (WORD*)pbIconBits;
- ii.xHotspot = *pt++;
- ii.yHotspot = *pt++;
+ cursorData.xHotspot = *pt++;
+ cursorData.yHotspot = *pt++;
pbIconBits = (PBYTE)pt;
}
- ii.fIcon = fIcon;
- if(!CURSORICON_GetIconInfoFromBMI(&ii, (BITMAPINFO*)pbIconBits, cxDesired, cyDesired))
+ if(!CURSORICON_GetCursorDataFromBMI(&cursorData, (BITMAPINFO*)pbIconBits))
+ {
+ ERR("Couldn't fill the CURSORDATA structure.\n");
+ return NULL;
+ }
+
+ hIcon = NtUserxCreateEmptyCurObject(fIcon ? 0 : 1);
+ if(!hIcon)
return NULL;
- hIcon = CreateIconIndirect(&ii);
+ if(!NtUserSetCursorIconData(hIcon, NULL, NULL, &cursorData))
+ {
+ ERR("NtUserSetCursorIconData failed.\n");
+ NtUserDestroyCursor(hIcon, TRUE);
+ hIcon = NULL;
+ }
/* Clean up */
- DeleteObject(ii.hbmMask);
- if(ii.hbmColor) DeleteObject(ii.hbmColor);
+ DeleteObject(cursorData.hbmMask);
+ if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
+ if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
return hIcon;
}
{
/* As simple as creating a handle, and let win32k deal with the bitmaps */
HICON hiconRet;
+ CURSORDATA cursorData;
TRACE("%p.\n", piconinfo);
+ if(!CURSORICON_GetCursorDataFromIconInfo(&cursorData, piconinfo))
+ return NULL;
+
hiconRet = NtUserxCreateEmptyCurObject(piconinfo->fIcon ? 0 : 1);
if(!hiconRet)
return NULL;
- if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, piconinfo))
+ if(!NtUserSetCursorIconData(hiconRet, NULL, NULL, &cursorData))
{
NtUserDestroyCursor(hiconRet, FALSE);
hiconRet = NULL;
}
+ /* Clean up */
+ DeleteObject(cursorData.hbmMask);
+ if(cursorData.hbmColor) DeleteObject(cursorData.hbmColor);
+ if(cursorData.hbmAlpha) DeleteObject(cursorData.hbmAlpha);
+
TRACE("Returning 0x%08x.\n", hiconRet);
return hiconRet;
_In_ int Y
)
{
- UNIMPLEMENTED;
- return FALSE;
+ return NtUserxSetCursorPos(X,Y);
}
BOOL WINAPI GetCursorPos(
_In_ BOOL bShow
)
{
- UNIMPLEMENTED;
- return -1;
+ return NtUserxShowCursor(bShow);
}
HCURSOR WINAPI GetCursor(void)
{
- UNIMPLEMENTED;
- return NULL;
+ return (HCURSOR)NtUserGetThreadState(THREADSTATE_GETCURSOR);
}
BOOL WINAPI DestroyCursor(