Author: jgardou
Date: Mon Oct 29 15:50:20 2012
New Revision: 57646
URL:
http://svn.reactos.org/svn/reactos?rev=57646&view=rev
Log:
[WIN32K]
- put changes for the new cursor/icons implementation in a separate file
Added:
trunk/reactos/win32ss/user/ntuser/cursoricon_new.c (with props)
Modified:
trunk/reactos/win32ss/CMakeLists.txt
trunk/reactos/win32ss/user/ntuser/cursoricon.c
trunk/reactos/win32ss/user/ntuser/cursoricon.h
trunk/reactos/win32ss/user/ntuser/msgqueue.c
Modified: trunk/reactos/win32ss/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/CMakeLists.txt?rev…
==============================================================================
--- trunk/reactos/win32ss/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/win32ss/CMakeLists.txt [iso-8859-1] Mon Oct 29 15:50:20 2012
@@ -9,10 +9,6 @@
if(USE_DIBLIB)
add_subdirectory(gdi/diblib)
-endif()
-
-if(USE_NEW_CURSORICON)
- add_definitions(-DNEW_CURSORICON)
endif()
add_subdirectory(gdi/gdi32)
@@ -107,7 +103,6 @@
user/ntuser/class.c
user/ntuser/clipboard.c
user/ntuser/csr.c
- user/ntuser/cursoricon.c
user/ntuser/defwnd.c
user/ntuser/desktop.c
user/ntuser/display.c
@@ -194,6 +189,13 @@
${GENDIB_FILES})
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")
list(APPEND SOURCE
gdi/dib/i386/dib24bpp_hline.s
Modified: trunk/reactos/win32ss/user/ntuser/cursoricon.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/cursor…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/cursoricon.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/cursoricon.c [iso-8859-1] Mon Oct 29 15:50:20 2012
@@ -237,7 +237,7 @@
IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
{
PSYSTEM_CURSORINFO CurInfo;
- HBITMAP bmpMask, bmpColor, bmpAlpha;
+ HBITMAP bmpMask, bmpColor;
BOOLEAN Ret, bListEmpty, bFound = FALSE;
PCURICON_PROCESS Current = NULL;
@@ -291,28 +291,21 @@
UserSetCursor(NULL, TRUE);
}
- bmpMask = CurIcon->aFrame[0].hbmMask;
- bmpColor = CurIcon->aFrame[0].hbmColor;
- bmpAlpha = CurIcon->aFrame[0].hbmAlpha;
+ bmpMask = CurIcon->IconInfo.hbmMask;
+ bmpColor = CurIcon->IconInfo.hbmColor;
/* Delete bitmaps */
if (bmpMask)
{
GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(bmpMask);
- CurIcon->aFrame[0].hbmMask = NULL;
+ CurIcon->IconInfo.hbmMask = NULL;
}
if (bmpColor)
{
GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED);
GreDeleteObject(bmpColor);
- CurIcon->aFrame[0].hbmColor = NULL;
- }
- if (bmpAlpha)
- {
- GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED);
- GreDeleteObject(bmpAlpha);
- CurIcon->aFrame[0].hbmAlpha = NULL;
+ CurIcon->IconInfo.hbmColor = NULL;
}
/* We were given a pointer, no need to keep the reference anylonger! */
@@ -368,21 +361,18 @@
{
goto leave;
}
-
- /* Fill data */
- ii.fIcon = CurIcon->bIcon;
- ii.xHotspot = CurIcon->ptlHotspot.x;
- ii.yHotspot = CurIcon->ptlHotspot.y;
+
+ RtlCopyMemory(&ii, &CurIcon->IconInfo, sizeof(ICONINFO));
/* Copy bitmaps */
- ii.hbmMask = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmMask);
- ii.hbmColor = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmColor);
+ ii.hbmMask = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmMask);
+ ii.hbmColor = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmColor);
if (pbpp)
{
PSURFACE psurfBmp;
- psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
+ psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmColor);
if (psurfBmp)
{
colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
@@ -809,103 +799,35 @@
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 ((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);
+ }
+
+ /* Copy new IconInfo field */
+ CurIcon->IconInfo = IconInfo;
+
+ if (CurIcon->IconInfo.hbmColor)
+ {
+ psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmColor);
if (!psurfBmp)
goto done;
+
CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
-
- /* 32bpp bitmap is likely to have an alpha channel */
- if(psurfBmp->SurfObj.iBitmapFormat == BMF_32BPP)
- {
- PFN_DIB_GetPixel fn_GetPixel =
DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel;
- INT i, j;
-
- fn_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel;
- for (i = 0; i < psurfBmp->SurfObj.sizlBitmap.cx; i++)
- {
- for (j = 0; j < psurfBmp->SurfObj.sizlBitmap.cy; j++)
- {
- bAlpha = ((BYTE)(fn_GetPixel(&psurfBmp->SurfObj, i, j)
>> 24)) != 0;
- if (bAlpha)
- break;
- }
- if (bAlpha)
- break;
- }
- }
- /* We're done with this one */
SURFACE_ShareUnlockSurface(psurfBmp);
- GreSetObjectOwner(IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
-
- if(bAlpha)
- {
- UCHAR Alpha;
- PUCHAR ptr;
- INT i, j;
- /* Copy the bitmap */
- CurIcon->aFrame[0].hbmAlpha = BITMAP_CopyBitmap(IconInfo.hbmColor);
- if(!CurIcon->aFrame[0].hbmAlpha)
- {
- ERR("BITMAP_CopyBitmap failed!");
- goto done;
- }
-
- psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmAlpha);
- if(!psurfBmp)
- {
- ERR("SURFACE_LockSurface failed!\n");
- goto done;
- }
-
- /* Premultiply with the alpha channel value */
- for (i = 0; i < psurfBmp->SurfObj.sizlBitmap.cy; i++)
- {
- ptr = (PBYTE)psurfBmp->SurfObj.pvScan0 + i*psurfBmp->SurfObj.lDelta;
- for (j = 0; j < psurfBmp->SurfObj.sizlBitmap.cx; j++)
- {
- Alpha = ptr[3];
- ptr[0] = (ptr[0] * Alpha) / 0xff;
- ptr[1] = (ptr[1] * Alpha) / 0xff;
- ptr[2] = (ptr[2] * Alpha) / 0xff;
- ptr += 4;
- }
- }
- SURFACE_ShareUnlockSurface(psurfBmp);
- GreSetObjectOwner(CurIcon->aFrame[0].hbmAlpha, GDI_OBJ_HMGR_PUBLIC);
- }
+ GreSetObjectOwner(CurIcon->IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
}
else
{
- psurfBmp = SURFACE_ShareLockSurface(IconInfo.hbmMask);
+ psurfBmp = SURFACE_ShareLockSurface(CurIcon->IconInfo.hbmMask);
if (!psurfBmp)
goto done;
@@ -914,17 +836,11 @@
SURFACE_ShareUnlockSurface(psurfBmp);
}
- GreSetObjectOwner(IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
+ GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
Ret = TRUE;
done:
-
- if(!Ret)
- {
- IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
- CurIcon = NULL;
- }
if (CurIcon)
{
@@ -942,21 +858,20 @@
/*
* @implemented
*/
-#ifdef NEW_CURSORICON
+#if 0
BOOL
APIENTRY
NtUserSetCursorIconData(
- _In_ HCURSOR Handle,
- _In_ HINSTANCE hinst,
- _In_ HRSRC hrsrc,
- _In_ PICONINFO pIconInfo)
+ HANDLE Handle,
+ HMODULE hModule,
+ PUNICODE_STRING pstrResName,
+ PICONINFO pIconInfo)
{
PCURICON_OBJECT CurIcon;
PSURFACE psurfBmp;
NTSTATUS Status = STATUS_SUCCESS;
BOOL Ret = FALSE;
DECLARE_RETURN(BOOL);
- ICONINFO ii;
TRACE("Enter NtUserSetCursorIconData\n");
UserEnterExclusive();
@@ -966,96 +881,54 @@
RETURN(FALSE);
}
- CurIcon->hModule = hinst;
- CurIcon->hRsrc =hrsrc;
+ CurIcon->hModule = hModule;
+ CurIcon->hRsrc = NULL; //hRsrc;
+ CurIcon->hGroupRsrc = NULL; //hGroupRsrc;
_SEH2_TRY
{
ProbeForRead(pIconInfo, sizeof(ICONINFO), 1);
- ii = *pIconInfo;
+ RtlCopyMemory(&CurIcon->IconInfo, pIconInfo, sizeof(ICONINFO));
+
+ CurIcon->IconInfo.hbmMask = BITMAP_CopyBitmap(pIconInfo->hbmMask);
+ CurIcon->IconInfo.hbmColor = BITMAP_CopyBitmap(pIconInfo->hbmColor);
+
+ if (CurIcon->IconInfo.hbmColor)
+ {
+ if ((psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmColor)))
+ {
+ CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
+ CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
+ SURFACE_UnlockSurface(psurfBmp);
+ GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
+ }
+ }
+ if (CurIcon->IconInfo.hbmMask)
+ {
+ if (CurIcon->IconInfo.hbmColor == NULL)
+ {
+ if ((psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmMask)))
+ {
+ CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
+ CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
+ SURFACE_UnlockSurface(psurfBmp);
+ }
+ }
+ GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
+ }
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END
-
+
if (!NT_SUCCESS(Status))
- {
SetLastNtError(Status);
- goto done;
- }
-
- /* This is probably not what windows does, but consistency checks can't hurt */
- if(CurIcon->bIcon != ii.fIcon)
- {
- EngSetLastError(ERROR_INVALID_PARAMETER);
- goto done;
- }
- CurIcon->ptlHotspot.x = ii.xHotspot;
- CurIcon->ptlHotspot.y = ii.yHotspot;
-
- if(!ii.hbmMask)
- {
- EngSetLastError(ERROR_INVALID_PARAMETER);
- goto done;
- }
-
- CurIcon->aFrame[0].hbmMask = BITMAP_CopyBitmap(ii.hbmMask);
- if(!CurIcon->aFrame[0].hbmMask)
- goto done;
-
- if(ii.hbmColor)
- {
- CurIcon->aFrame[0].hbmColor = BITMAP_CopyBitmap(ii.hbmColor);
- if(!CurIcon->aFrame[0].hbmColor)
- goto done;
- }
-
- if (CurIcon->aFrame[0].hbmColor)
- {
- if ((psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor)))
- {
- CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
- CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
- SURFACE_ShareUnlockSurface(psurfBmp);
- GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
- }
- else
- goto done;
- }
else
- {
- if ((psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmMask)))
- {
- CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
- CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy/2;
- SURFACE_ShareUnlockSurface(psurfBmp);
- }
- else
- goto done;
- }
- GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
-
- Ret = TRUE;
-
-done:
+ Ret = TRUE;
+
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:
@@ -1076,6 +949,7 @@
{
PCURICON_OBJECT CurIcon;
NTSTATUS Status;
+ POINT SafeHotspot;
BOOL Ret = FALSE;
DECLARE_RETURN(BOOL);
@@ -1094,7 +968,7 @@
/* Copy fields */
if (fIcon)
{
- Status = MmCopyFromCaller(&CurIcon->bIcon, fIcon, sizeof(BOOL));
+ Status = MmCopyFromCaller(&CurIcon->IconInfo.fIcon, fIcon, sizeof(BOOL));
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
@@ -1109,12 +983,16 @@
if (Hotspot)
{
- Status = MmCopyFromCaller(&CurIcon->ptlHotspot, Hotspot, sizeof(POINT));
- if (!NT_SUCCESS(Status))
- {
+ Status = MmCopyFromCaller(&SafeHotspot, 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)
@@ -1126,14 +1004,10 @@
if(Ret)
{
/* This icon is shared now */
- GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
- if(CurIcon->aFrame[0].hbmColor)
+ GreSetObjectOwner(CurIcon->IconInfo.hbmMask, GDI_OBJ_HMGR_PUBLIC);
+ if(CurIcon->IconInfo.hbmColor)
{
- GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_PUBLIC);
- }
- if(CurIcon->aFrame[0].hbmAlpha)
- {
- GreSetObjectOwner(CurIcon->aFrame[0].hbmAlpha, GDI_OBJ_HMGR_PUBLIC);
+ GreSetObjectOwner(CurIcon->IconInfo.hbmColor, GDI_OBJ_HMGR_PUBLIC);
}
}
UserDereferenceObject(CurIcon);
@@ -1170,8 +1044,8 @@
PSURFACE psurfDest, psurfMask, psurfColor, psurfOffScreen;
PDC pdc = NULL;
BOOL Ret = FALSE;
- HBITMAP hbmMask, hbmColor, hbmAlpha;
- BOOL bOffScreen;
+ HBITMAP hbmMask, hbmColor;
+ BOOL bOffScreen, bAlpha = FALSE;
RECTL rcDest, rcSrc;
CLIPOBJ* pdcClipObj = NULL;
EXLATEOBJ exlo;
@@ -1183,9 +1057,8 @@
return FALSE;
}
- hbmMask = pIcon->aFrame[0].hbmMask;
- hbmColor = pIcon->aFrame[0].hbmColor;
- hbmAlpha = pIcon->aFrame[0].hbmAlpha;
+ hbmMask = pIcon->IconInfo.hbmMask;
+ hbmColor = pIcon->IconInfo.hbmColor;
if (istepIfAniCur)
ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
@@ -1218,11 +1091,35 @@
/* Set source rect */
RECTL_vSetRect(&rcSrc, 0, 0, pIcon->Size.cx, pIcon->Size.cy);
+ /* Check for alpha */
+ if (psurfColor &&
+ (psurfColor->SurfObj.iBitmapFormat == BMF_32BPP) &&
+ (diFlags & DI_IMAGE))
+ {
+ PFN_DIB_GetPixel fnSource_GetPixel = NULL;
+ INT i, j;
+
+ /* In order to correctly display 32 bit icons Windows first scans the image,
+ because information about transparency is not stored in any image's
headers */
+ fnSource_GetPixel = DibFunctionsForBitmapFormat[BMF_32BPP].DIB_GetPixel;
+ for (i = 0; i < psurfColor->SurfObj.sizlBitmap.cx; i++)
+ {
+ for (j = 0; j < psurfColor->SurfObj.sizlBitmap.cy; j++)
+ {
+ bAlpha = ((BYTE)(fnSource_GetPixel(&psurfColor->SurfObj, i, j)
>> 24) & 0xff);
+ if (bAlpha)
+ break;
+ }
+ if (bAlpha)
+ break;
+ }
+ }
+
/* Fix width parameter, if needed */
if (!cxWidth)
{
if(diFlags & DI_DEFAULTSIZE)
- cxWidth = pIcon->bIcon ?
+ cxWidth = pIcon->IconInfo.fIcon ?
UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR);
else
cxWidth = pIcon->Size.cx;
@@ -1232,7 +1129,7 @@
if (!cyHeight)
{
if(diFlags & DI_DEFAULTSIZE)
- cyHeight = pIcon->bIcon ?
+ cyHeight = pIcon->IconInfo.fIcon ?
UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR);
else
cyHeight = pIcon->Size.cy;
@@ -1341,16 +1238,42 @@
}
/* Now do the rendering */
- if(hbmAlpha && (diFlags & DI_IMAGE))
+ if(bAlpha && (diFlags & DI_IMAGE))
{
BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } };
+ BYTE Alpha;
+ INT i, j;
PSURFACE psurf = NULL;
-
- psurf = SURFACE_ShareLockSurface(hbmAlpha);
+ PBYTE ptr ;
+ HBITMAP hsurfCopy = NULL;
+
+ hsurfCopy = BITMAP_CopyBitmap(hbmColor);
+ if(!hsurfCopy)
+ {
+ ERR("BITMAP_CopyBitmap failed!");
+ goto CleanupAlpha;
+ }
+
+ psurf = SURFACE_ShareLockSurface(hsurfCopy);
if(!psurf)
{
ERR("SURFACE_LockSurface failed!\n");
- goto NoAlpha;
+ goto CleanupAlpha;
+ }
+
+ /* Premultiply with the alpha channel value */
+ for (i = 0; i < psurf->SurfObj.sizlBitmap.cy; i++)
+ {
+ ptr = (PBYTE)psurf->SurfObj.pvScan0 + i*psurf->SurfObj.lDelta;
+ for (j = 0; j < psurf->SurfObj.sizlBitmap.cx; j++)
+ {
+ Alpha = ptr[3];
+ ptr[0] = (ptr[0] * Alpha) / 0xff;
+ ptr[1] = (ptr[1] * Alpha) / 0xff;
+ ptr[2] = (ptr[2] * Alpha) / 0xff;
+
+ ptr += 4;
+ }
}
/* Initialize color translation object */
@@ -1366,11 +1289,14 @@
&blendobj);
EXLATEOBJ_vCleanup(&exlo);
- SURFACE_ShareUnlockSurface(psurf);
- if(Ret) goto done;
+
+ CleanupAlpha:
+ if(psurf) SURFACE_ShareUnlockSurface(psurf);
+ if(hsurfCopy) NtGdiDeleteObjectApp(hsurfCopy);
+ if(Ret) goto done;
ERR("NtGdiAlphaBlend failed!\n");
}
-NoAlpha:
+
if (diFlags & DI_MASK)
{
DWORD rop4 = (diFlags & DI_IMAGE) ? ROP4_SRCAND : ROP4_SRCCOPY;
Modified: trunk/reactos/win32ss/user/ntuser/cursoricon.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/cursor…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/cursoricon.h [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/cursoricon.h [iso-8859-1] Mon Oct 29 15:50:20 2012
@@ -8,6 +8,7 @@
PPROCESSINFO Process;
} CURICON_PROCESS, *PCURICON_PROCESS;
+#ifdef NEW_CURSORICON
typedef struct _CURICON_FRAME
{
HBITMAP hbmMask;
@@ -23,15 +24,29 @@
LIST_ENTRY ProcessList;
HMODULE hModule;
HRSRC hRsrc;
-#ifndef NEW_CURSORICON
- HRSRC hGroupRsrc;
-#endif
SIZE Size;
BYTE Shadow;
BOOL bIcon;
POINTL ptlHotspot;
CURICON_FRAME aFrame[1];
} 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
{
Added: trunk/reactos/win32ss/user/ntuser/cursoricon_new.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/cursor…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/cursoricon_new.c (added)
+++ trunk/reactos/win32ss/user/ntuser/cursoricon_new.c [iso-8859-1] Mon Oct 29 15:50:20
2012
@@ -1,0 +1,1578 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Win32k subsystem
+ * PURPOSE: Cursor and icon functions
+ * FILE: subsystems/win32/win32k/ntuser/cursoricon.c
+ * PROGRAMER: ReactOS Team
+ */
+/*
+ * We handle two types of cursors/icons:
+ * - Private
+ * Loaded without LR_SHARED flag
+ * Private to a process
+ * Can be deleted by calling NtDestroyCursorIcon()
+ * CurIcon->hModule, CurIcon->hRsrc and CurIcon->hGroupRsrc set to NULL
+ * - Shared
+ * Loaded with LR_SHARED flag
+ * Possibly shared by multiple processes
+ * Immune to NtDestroyCursorIcon()
+ * CurIcon->hModule, CurIcon->hRsrc and CurIcon->hGroupRsrc are valid
+ * There's a M:N relationship between processes and (shared) cursor/icons.
+ * A process can have multiple cursor/icons and a cursor/icon can be used
+ * by multiple processes. To keep track of this we keep a list of all
+ * cursor/icons (CurIconList) and per cursor/icon we keep a list of
+ * CURICON_PROCESS structs starting at CurIcon->ProcessList.
+ */
+
+#include <win32k.h>
+DBG_DEFAULT_CHANNEL(UserIcon);
+
+static PPAGED_LOOKASIDE_LIST pgProcessLookasideList;
+static LIST_ENTRY gCurIconList;
+
+SYSTEM_CURSORINFO gSysCursorInfo;
+
+BOOL
+InitCursorImpl()
+{
+ pgProcessLookasideList = ExAllocatePool(NonPagedPool, sizeof(PAGED_LOOKASIDE_LIST));
+ if(!pgProcessLookasideList)
+ return FALSE;
+
+ ExInitializePagedLookasideList(pgProcessLookasideList,
+ NULL,
+ NULL,
+ 0,
+ sizeof(CURICON_PROCESS),
+ TAG_DIB,
+ 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;
+
+ return TRUE;
+}
+
+PSYSTEM_CURSORINFO
+IntGetSysCursorInfo()
+{
+ return &gSysCursorInfo;
+}
+
+/* This function creates a reference for the object! */
+PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
+{
+ PCURICON_OBJECT CurIcon;
+
+ if (!hCurIcon)
+ {
+ EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
+ return NULL;
+ }
+
+ CurIcon = (PCURICON_OBJECT)UserReferenceObjectByHandle(hCurIcon, otCursorIcon);
+ if (!CurIcon)
+ {
+ /* We never set ERROR_INVALID_ICON_HANDLE. lets hope noone ever checks for it */
+ EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
+ return NULL;
+ }
+
+ ASSERT(CurIcon->head.cLockObj >= 1);
+ return CurIcon;
+}
+
+BOOL UserSetCursorPos( INT x, INT y, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook)
+{
+ PWND DesktopWindow;
+ PSYSTEM_CURSORINFO CurInfo;
+ MSG Msg;
+ RECTL rcClip;
+ POINT pt;
+
+ if(!(DesktopWindow = UserGetDesktopWindow()))
+ {
+ return FALSE;
+ }
+
+ CurInfo = IntGetSysCursorInfo();
+
+ /* Clip cursor position */
+ if (!CurInfo->bClipped)
+ rcClip = DesktopWindow->rcClient;
+ else
+ rcClip = CurInfo->rcClip;
+
+ if(x >= rcClip.right) x = rcClip.right - 1;
+ if(x < rcClip.left) x = rcClip.left;
+ if(y >= rcClip.bottom) y = rcClip.bottom - 1;
+ if(y < rcClip.top) y = rcClip.top;
+
+ pt.x = x;
+ pt.y = y;
+
+ /* 1. Generate a mouse move message, this sets the htEx and Track Window too. */
+ Msg.message = WM_MOUSEMOVE;
+ Msg.wParam = UserGetMouseButtonsState();
+ Msg.lParam = MAKELPARAM(x, y);
+ Msg.pt = pt;
+ co_MsqInsertMouseMessage(&Msg, flags, dwExtraInfo, Hook);
+
+ /* 2. Store the new cursor position */
+ gpsi->ptCursor = pt;
+
+ return TRUE;
+}
+
+/*
+ * We have to register that this object is in use by the current
+ * process. The only way to do that seems to be to walk the list
+ * of cursor/icon objects starting at W32Process->CursorIconListHead.
+ * If the object is already present in the list, we don't have to do
+ * anything, if it's not present we add it and inc the ProcessCount
+ * in the object. Having to walk the list kind of sucks, but that's
+ * life...
+ */
+static BOOLEAN FASTCALL
+ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon)
+{
+ PPROCESSINFO Win32Process;
+ PCURICON_PROCESS Current;
+
+ Win32Process = PsGetCurrentProcessWin32Process();
+
+ LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
+ {
+ if (Current->Process == Win32Process)
+ {
+ /* Already registered for this process */
+ return TRUE;
+ }
+ }
+
+ /* Not registered yet */
+ Current = ExAllocateFromPagedLookasideList(pgProcessLookasideList);
+ if (NULL == Current)
+ {
+ return FALSE;
+ }
+ InsertHeadList(&CurIcon->ProcessList, &Current->ListEntry);
+ Current->Process = Win32Process;
+
+ return TRUE;
+}
+
+PCURICON_OBJECT FASTCALL
+IntFindExistingCurIconObject(HMODULE hModule,
+ HRSRC hRsrc, LONG cx, LONG cy)
+{
+ PCURICON_OBJECT CurIcon;
+
+ LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry)
+ {
+
+ // if (NT_SUCCESS(UserReferenceObjectByPointer(Object, otCursorIcon))) // <-
huh????
+// UserReferenceObject( CurIcon);
+// {
+ if ((CurIcon->hModule == hModule) && (CurIcon->hRsrc == hRsrc))
+ {
+ if (cx && ((cx != CurIcon->Size.cx) || (cy !=
CurIcon->Size.cy)))
+ {
+// UserDereferenceObject(CurIcon);
+ continue;
+ }
+ if (! ReferenceCurIconByProcess(CurIcon))
+ {
+ return NULL;
+ }
+
+ return CurIcon;
+ }
+// }
+// UserDereferenceObject(CurIcon);
+
+ }
+
+ return NULL;
+}
+
+PCURICON_OBJECT
+IntCreateCurIconHandle()
+{
+ PCURICON_OBJECT CurIcon;
+ HANDLE hCurIcon;
+
+ CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, otCursorIcon,
sizeof(CURICON_OBJECT));
+
+ if (!CurIcon)
+ {
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ CurIcon->Self = hCurIcon;
+ InitializeListHead(&CurIcon->ProcessList);
+
+ if (! ReferenceCurIconByProcess(CurIcon))
+ {
+ ERR("Failed to add process\n");
+ UserDeleteObject(hCurIcon, otCursorIcon);
+ UserDereferenceObject(CurIcon);
+ return NULL;
+ }
+
+ InsertHeadList(&gCurIconList, &CurIcon->ListEntry);
+
+ return CurIcon;
+}
+
+BOOLEAN FASTCALL
+IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
+{
+ PSYSTEM_CURSORINFO CurInfo;
+ HBITMAP bmpMask, bmpColor, bmpAlpha;
+ BOOLEAN Ret, bListEmpty, bFound = FALSE;
+ PCURICON_PROCESS Current = NULL;
+
+ /* For handles created without any data (error handling) */
+ if(IsListEmpty(&CurIcon->ProcessList))
+ goto emptyList;
+
+ /* Now find this process in the list of processes referencing this object and
+ remove it from that list */
+ LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
+ {
+ if (Current->Process == ppi)
+ {
+ bFound = TRUE;
+ bListEmpty = RemoveEntryList(&Current->ListEntry);
+ break;
+ }
+ }
+
+ if(!bFound)
+ {
+ /* This object doesn't belong to this process */
+ EngSetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ ExFreeToPagedLookasideList(pgProcessLookasideList, Current);
+
+ /* If there are still processes referencing this object we can't destroy it yet
*/
+ if (!bListEmpty)
+ {
+ if(CurIcon->head.ppi == ppi)
+ {
+ /* Set the first process of the list as owner */
+ Current = CONTAINING_RECORD(CurIcon->ProcessList.Flink, CURICON_PROCESS,
ListEntry);
+ UserSetObjectOwner(CurIcon, otCursorIcon, Current->Process);
+ }
+ UserDereferenceObject(CurIcon);
+ return TRUE;
+ }
+
+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;
+
+ /* Delete bitmaps */
+ if (bmpMask)
+ {
+ GreSetObjectOwner(bmpMask, GDI_OBJ_HMGR_POWNED);
+ GreDeleteObject(bmpMask);
+ CurIcon->aFrame[0].hbmMask = NULL;
+ }
+ if (bmpColor)
+ {
+ GreSetObjectOwner(bmpColor, GDI_OBJ_HMGR_POWNED);
+ GreDeleteObject(bmpColor);
+ CurIcon->aFrame[0].hbmColor = NULL;
+ }
+ if (bmpAlpha)
+ {
+ GreSetObjectOwner(bmpAlpha, GDI_OBJ_HMGR_POWNED);
+ GreDeleteObject(bmpAlpha);
+ CurIcon->aFrame[0].hbmAlpha = NULL;
+ }
+
+ /* We were given a pointer, no need to keep the reference anylonger! */
+ UserDereferenceObject(CurIcon);
+ Ret = UserDeleteObject(CurIcon->Self, otCursorIcon);
+
+ return Ret;
+}
+
+VOID FASTCALL
+IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
+{
+ PCURICON_OBJECT CurIcon, tmp;
+
+ /* Run through the list of icon objects */
+ LIST_FOR_EACH_SAFE(CurIcon, tmp, &gCurIconList, CURICON_OBJECT, ListEntry)
+ {
+ UserReferenceObject(CurIcon);
+ IntDestroyCurIconObject(CurIcon, Win32Process);
+ }
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+NtUserGetIconInfo(
+ HANDLE hCurIcon,
+ PICONINFO IconInfo,
+ PUNICODE_STRING lpInstName, // Optional
+ PUNICODE_STRING lpResName, // Optional
+ LPDWORD pbpp, // Optional
+ BOOL bInternal)
+{
+ ICONINFO ii;
+ PCURICON_OBJECT CurIcon;
+ NTSTATUS Status = STATUS_SUCCESS;
+ BOOL Ret = FALSE;
+ DWORD colorBpp = 0;
+
+ TRACE("Enter NtUserGetIconInfo\n");
+ UserEnterExclusive();
+
+ if (!IconInfo)
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ goto leave;
+ }
+
+ if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
+ {
+ goto leave;
+ }
+
+ /* Fill data */
+ ii.fIcon = CurIcon->bIcon;
+ ii.xHotspot = CurIcon->ptlHotspot.x;
+ ii.yHotspot = CurIcon->ptlHotspot.y;
+
+ /* Copy bitmaps */
+ ii.hbmMask = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmMask);
+ ii.hbmColor = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmColor);
+
+ if (pbpp)
+ {
+ PSURFACE psurfBmp;
+
+ psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
+ if (psurfBmp)
+ {
+ colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
+ SURFACE_ShareUnlockSurface(psurfBmp);
+ }
+ }
+
+ /* Copy fields */
+ _SEH2_TRY
+ {
+ ProbeForWrite(IconInfo, sizeof(ICONINFO), 1);
+ RtlCopyMemory(IconInfo, &ii, sizeof(ICONINFO));
+
+ if (pbpp)
+ {
+ ProbeForWrite(pbpp, sizeof(DWORD), 1);
+ *pbpp = colorBpp;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if (NT_SUCCESS(Status))
+ Ret = TRUE;
+ else
+ SetLastNtError(Status);
+
+ UserDereferenceObject(CurIcon);
+
+leave:
+ TRACE("Leave NtUserGetIconInfo, ret=%i\n", Ret);
+ UserLeave();
+
+ return Ret;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+NtUserGetIconSize(
+ HANDLE hCurIcon,
+ UINT istepIfAniCur,
+ PLONG plcx, // &size.cx
+ PLONG plcy) // &size.cy
+{
+ PCURICON_OBJECT CurIcon;
+ NTSTATUS Status = STATUS_SUCCESS;
+ BOOL bRet = FALSE;
+
+ TRACE("Enter NtUserGetIconSize\n");
+ UserEnterExclusive();
+
+ if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
+ {
+ goto cleanup;
+ }
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(plcx, sizeof(LONG), 1);
+ RtlCopyMemory(plcx, &CurIcon->Size.cx, sizeof(LONG));
+ ProbeForWrite(plcy, sizeof(LONG), 1);
+ RtlCopyMemory(plcy, &CurIcon->Size.cy, sizeof(LONG));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if (NT_SUCCESS(Status))
+ bRet = TRUE;
+ else
+ SetLastNtError(Status); // Maybe not, test this
+
+ UserDereferenceObject(CurIcon);
+
+cleanup:
+ TRACE("Leave NtUserGetIconSize, ret=%i\n", bRet);
+ UserLeave();
+ return bRet;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+NtUserGetCursorInfo(
+ PCURSORINFO pci)
+{
+ CURSORINFO SafeCi;
+ PSYSTEM_CURSORINFO CurInfo;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PCURICON_OBJECT CurIcon;
+ BOOL Ret = FALSE;
+ DECLARE_RETURN(BOOL);
+
+ TRACE("Enter NtUserGetCursorInfo\n");
+ UserEnterExclusive();
+
+ CurInfo = IntGetSysCursorInfo();
+ CurIcon = (PCURICON_OBJECT)CurInfo->CurrentCursorObject;
+
+ SafeCi.cbSize = sizeof(CURSORINFO);
+ SafeCi.flags = ((CurIcon && CurInfo->ShowingCursor >= 0) ?
CURSOR_SHOWING : 0);
+ SafeCi.hCursor = (CurIcon ? (HCURSOR)CurIcon->Self : (HCURSOR)0);
+
+ SafeCi.ptScreenPos = gpsi->ptCursor;
+
+ _SEH2_TRY
+ {
+ if (pci->cbSize == sizeof(CURSORINFO))
+ {
+ ProbeForWrite(pci, sizeof(CURSORINFO), 1);
+ RtlCopyMemory(pci, &SafeCi, sizeof(CURSORINFO));
+ Ret = TRUE;
+ }
+ else
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ }
+
+ RETURN(Ret);
+
+CLEANUP:
+ TRACE("Leave NtUserGetCursorInfo, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
+BOOL
+APIENTRY
+UserClipCursor(
+ RECTL *prcl)
+{
+ /* FIXME: Check if process has WINSTA_WRITEATTRIBUTES */
+ PSYSTEM_CURSORINFO CurInfo;
+ PWND DesktopWindow = NULL;
+
+ CurInfo = IntGetSysCursorInfo();
+
+ DesktopWindow = UserGetDesktopWindow();
+
+ if (prcl != NULL && DesktopWindow != NULL)
+ {
+ if (prcl->right < prcl->left || prcl->bottom < prcl->top)
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ CurInfo->bClipped = TRUE;
+
+ /* Set nw cliping region. Note: we can't use RECTL_bIntersectRect because
+ it sets rect to 0 0 0 0 when it's empty. For more info see monitor
winetest */
+ CurInfo->rcClip.left = max(prcl->left, DesktopWindow->rcWindow.left);
+ CurInfo->rcClip.right = min(prcl->right,
DesktopWindow->rcWindow.right);
+ if (CurInfo->rcClip.right < CurInfo->rcClip.left)
+ CurInfo->rcClip.right = CurInfo->rcClip.left;
+
+ CurInfo->rcClip.top = max(prcl->top, DesktopWindow->rcWindow.top);
+ CurInfo->rcClip.bottom = min(prcl->bottom,
DesktopWindow->rcWindow.bottom);
+ if (CurInfo->rcClip.bottom < CurInfo->rcClip.top)
+ CurInfo->rcClip.bottom = CurInfo->rcClip.top;
+
+ /* Make sure cursor is in clipping region */
+ UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, 0, 0, FALSE);
+ }
+ else
+ {
+ CurInfo->bClipped = FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+NtUserClipCursor(
+ RECTL *prcl)
+{
+ RECTL rclLocal;
+ BOOL bResult;
+
+ if (prcl)
+ {
+ _SEH2_TRY
+ {
+ /* Probe and copy rect */
+ ProbeForRead(prcl, sizeof(RECTL), 1);
+ rclLocal = *prcl;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ _SEH2_YIELD(return FALSE;)
+ }
+ _SEH2_END
+
+ prcl = &rclLocal;
+ }
+
+ UserEnterExclusive();
+
+ /* Call the internal function */
+ bResult = UserClipCursor(prcl);
+
+ UserLeave();
+
+ return bResult;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+NtUserDestroyCursor(
+ HANDLE hCurIcon,
+ DWORD Unknown)
+{
+ PCURICON_OBJECT CurIcon;
+ BOOL ret;
+ DECLARE_RETURN(BOOL);
+
+ TRACE("Enter NtUserDestroyCursorIcon\n");
+ UserEnterExclusive();
+
+ if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
+ {
+ RETURN(FALSE);
+ }
+
+ ret = IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
+ /* Note: IntDestroyCurIconObject will remove our reference for us! */
+
+ RETURN(ret);
+
+CLEANUP:
+ TRACE("Leave NtUserDestroyCursorIcon, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
+
+/*
+ * @implemented
+ */
+HICON
+APIENTRY
+NtUserFindExistingCursorIcon(
+ HMODULE hModule,
+ HRSRC hRsrc,
+ LONG cx,
+ LONG cy)
+{
+ PCURICON_OBJECT CurIcon;
+ HANDLE Ret = (HANDLE)0;
+ DECLARE_RETURN(HICON);
+
+ TRACE("Enter NtUserFindExistingCursorIcon\n");
+ UserEnterExclusive();
+
+ CurIcon = IntFindExistingCurIconObject(hModule, hRsrc, cx, cy);
+ if (CurIcon)
+ {
+ Ret = CurIcon->Self;
+
+// IntReleaseCurIconObject(CurIcon); // FIXME: Is this correct? Does
IntFindExistingCurIconObject add a ref?
+ RETURN(Ret);
+ }
+
+ EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
+ RETURN((HANDLE)0);
+
+CLEANUP:
+ TRACE("Leave NtUserFindExistingCursorIcon, ret=%p\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+NtUserGetClipCursor(
+ RECTL *lpRect)
+{
+ /* FIXME: Check if process has WINSTA_READATTRIBUTES */
+ PSYSTEM_CURSORINFO CurInfo;
+ RECTL Rect;
+ NTSTATUS Status;
+ DECLARE_RETURN(BOOL);
+
+ TRACE("Enter NtUserGetClipCursor\n");
+ UserEnterExclusive();
+
+ if (!lpRect)
+ RETURN(FALSE);
+
+ CurInfo = IntGetSysCursorInfo();
+ if (CurInfo->bClipped)
+ {
+ Rect = CurInfo->rcClip;
+ }
+ else
+ {
+ Rect.left = 0;
+ Rect.top = 0;
+ Rect.right = UserGetSystemMetrics(SM_CXSCREEN);
+ Rect.bottom = UserGetSystemMetrics(SM_CYSCREEN);
+ }
+
+ Status = MmCopyToCaller(lpRect, &Rect, sizeof(RECT));
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ RETURN(FALSE);
+ }
+
+ RETURN(TRUE);
+
+CLEANUP:
+ TRACE("Leave NtUserGetClipCursor, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
+
+/*
+ * @implemented
+ */
+HCURSOR
+APIENTRY
+NtUserSetCursor(
+ HCURSOR hCursor)
+{
+ PCURICON_OBJECT pcurOld, pcurNew;
+ HCURSOR hOldCursor = NULL;
+
+ TRACE("Enter NtUserSetCursor\n");
+ UserEnterExclusive();
+
+ if (hCursor)
+ {
+ pcurNew = UserGetCurIconObject(hCursor);
+ if (!pcurNew)
+ {
+ EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
+ goto leave;
+ }
+ }
+ else
+ {
+ pcurNew = NULL;
+ }
+
+ pcurOld = UserSetCursor(pcurNew, FALSE);
+ if (pcurOld)
+ {
+ hOldCursor = (HCURSOR)pcurOld->Self;
+ UserDereferenceObject(pcurOld);
+ }
+
+leave:
+ UserLeave();
+ return hOldCursor;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+NtUserSetCursorContents(
+ 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(!Ret)
+ {
+ IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
+ CurIcon = NULL;
+ }
+
+ if (CurIcon)
+ {
+ UserDereferenceObject(CurIcon);
+ }
+ RETURN(Ret);
+
+CLEANUP:
+ TRACE("Leave NtUserSetCursorContents, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
+
+/*
+ * @implemented
+ */
+#ifdef NEW_CURSORICON
+BOOL
+APIENTRY
+NtUserSetCursorIconData(
+ _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();
+
+ if (!(CurIcon = UserGetCurIconObject(Handle)))
+ {
+ RETURN(FALSE);
+ }
+
+ CurIcon->hModule = hinst;
+ CurIcon->hRsrc =hrsrc;
+
+ _SEH2_TRY
+ {
+ ProbeForRead(pIconInfo, sizeof(ICONINFO), 1);
+ ii = *pIconInfo;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ goto done;
+ }
+
+ /* This is probably not what windows does, but consistency checks can't hurt */
+ if(CurIcon->bIcon != ii.fIcon)
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ goto done;
+ }
+ CurIcon->ptlHotspot.x = ii.xHotspot;
+ CurIcon->ptlHotspot.y = ii.yHotspot;
+
+ if(!ii.hbmMask)
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ goto done;
+ }
+
+ CurIcon->aFrame[0].hbmMask = BITMAP_CopyBitmap(ii.hbmMask);
+ if(!CurIcon->aFrame[0].hbmMask)
+ goto done;
+
+ if(ii.hbmColor)
+ {
+ CurIcon->aFrame[0].hbmColor = BITMAP_CopyBitmap(ii.hbmColor);
+ if(!CurIcon->aFrame[0].hbmColor)
+ goto done;
+ }
+
+ if (CurIcon->aFrame[0].hbmColor)
+ {
+ if ((psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor)))
+ {
+ CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
+ CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
+ SURFACE_ShareUnlockSurface(psurfBmp);
+ GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
+ }
+ else
+ goto done;
+ }
+ else
+ {
+ if ((psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmMask)))
+ {
+ CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
+ CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy/2;
+ SURFACE_ShareUnlockSurface(psurfBmp);
+ }
+ else
+ goto done;
+ }
+ GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
+
+ Ret = TRUE;
+
+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:
+ TRACE("Leave NtUserSetCursorIconData, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+#else
+BOOL
+APIENTRY
+NtUserSetCursorIconData(
+ HANDLE hCurIcon,
+ PBOOL fIcon,
+ POINT *Hotspot,
+ HMODULE hModule,
+ HRSRC hRsrc,
+ HRSRC hGroupRsrc)
+{
+ PCURICON_OBJECT CurIcon;
+ NTSTATUS Status;
+ BOOL Ret = FALSE;
+ DECLARE_RETURN(BOOL);
+
+ TRACE("Enter NtUserSetCursorIconData\n");
+ UserEnterExclusive();
+
+ if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
+ {
+ RETURN(FALSE);
+ }
+
+ CurIcon->hModule = hModule;
+ CurIcon->hRsrc = hRsrc;
+ CurIcon->hGroupRsrc = hGroupRsrc;
+
+ /* Copy fields */
+ if (fIcon)
+ {
+ Status = MmCopyFromCaller(&CurIcon->bIcon, fIcon, sizeof(BOOL));
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ goto done;
+ }
+ }
+ else
+ {
+ if (!Hotspot)
+ Ret = TRUE;
+ }
+
+ if (Hotspot)
+ {
+ Status = MmCopyFromCaller(&CurIcon->ptlHotspot, Hotspot, sizeof(POINT));
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ goto done;
+ }
+ }
+
+ if (!fIcon && !Hotspot)
+ {
+ Ret = TRUE;
+ }
+
+done:
+ if(Ret)
+ {
+ /* This icon is shared now */
+ GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
+ if(CurIcon->aFrame[0].hbmColor)
+ {
+ GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_PUBLIC);
+ }
+ if(CurIcon->aFrame[0].hbmAlpha)
+ {
+ GreSetObjectOwner(CurIcon->aFrame[0].hbmAlpha, GDI_OBJ_HMGR_PUBLIC);
+ }
+ }
+ UserDereferenceObject(CurIcon);
+ RETURN(Ret);
+
+
+CLEANUP:
+ TRACE("Leave NtUserSetCursorIconData, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+#endif
+
+/* Mostly inspired from wine code.
+ * We use low level functions because:
+ * - at this point, the icon bitmap could have a different bit depth than the DC,
+ * making it thus impossible to use NtCreateCompatibleDC and selecting the bitmap.
+ * This happens after a mode setting change.
+ * - it avoids massive GDI objects locking when only the destination surface needs it.
+ * - It makes (small) performance gains.
+ */
+BOOL
+UserDrawIconEx(
+ HDC hDc,
+ INT xLeft,
+ INT yTop,
+ PCURICON_OBJECT pIcon,
+ INT cxWidth,
+ INT cyHeight,
+ UINT istepIfAniCur,
+ HBRUSH hbrFlickerFreeDraw,
+ UINT diFlags)
+{
+ PSURFACE psurfDest, psurfMask, psurfColor, psurfOffScreen;
+ PDC pdc = NULL;
+ BOOL Ret = FALSE;
+ HBITMAP hbmMask, hbmColor, hbmAlpha;
+ BOOL bOffScreen;
+ RECTL rcDest, rcSrc;
+ CLIPOBJ* pdcClipObj = NULL;
+ EXLATEOBJ exlo;
+
+ /* Stupid case */
+ if((diFlags & DI_NORMAL) == 0)
+ {
+ ERR("DrawIconEx called without mask or color bitmap to draw.\n");
+ return FALSE;
+ }
+
+ hbmMask = pIcon->aFrame[0].hbmMask;
+ hbmColor = pIcon->aFrame[0].hbmColor;
+ hbmAlpha = pIcon->aFrame[0].hbmAlpha;
+
+ if (istepIfAniCur)
+ ERR("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
+
+ /*
+ * Get our objects.
+ * Shared locks are enough, we are only reading those bitmaps
+ */
+ psurfMask = SURFACE_ShareLockSurface(hbmMask);
+ if(psurfMask == NULL)
+ {
+ ERR("Unable to lock the mask surface.\n");
+ return FALSE;
+ }
+
+ /* Color bitmap is not mandatory */
+ 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);
+ psurfColor = NULL;
+ }
+ else if ((psurfColor = SURFACE_ShareLockSurface(hbmColor)) == NULL)
+ {
+ ERR("Unable to lock the color bitmap.\n");
+ SURFACE_ShareUnlockSurface(psurfMask);
+ return FALSE;
+ }
+
+ /* Set source rect */
+ RECTL_vSetRect(&rcSrc, 0, 0, pIcon->Size.cx, pIcon->Size.cy);
+
+ /* Fix width parameter, if needed */
+ if (!cxWidth)
+ {
+ if(diFlags & DI_DEFAULTSIZE)
+ cxWidth = pIcon->bIcon ?
+ UserGetSystemMetrics(SM_CXICON) : UserGetSystemMetrics(SM_CXCURSOR);
+ else
+ cxWidth = pIcon->Size.cx;
+ }
+
+ /* Fix height parameter, if needed */
+ if (!cyHeight)
+ {
+ if(diFlags & DI_DEFAULTSIZE)
+ cyHeight = pIcon->bIcon ?
+ UserGetSystemMetrics(SM_CYICON) : UserGetSystemMetrics(SM_CYCURSOR);
+ else
+ cyHeight = pIcon->Size.cy;
+ }
+
+ /* Should we render off-screen? */
+ bOffScreen = hbrFlickerFreeDraw && (GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw)
== GDI_OBJECT_TYPE_BRUSH);
+
+ if (bOffScreen)
+ {
+ /* Yes: Allocate and paint the offscreen surface */
+ EBRUSHOBJ eboFill;
+ PBRUSH pbrush = BRUSH_ShareLockBrush(hbrFlickerFreeDraw);
+
+ TRACE("Performing off-screen rendering.\n");
+
+ if(!pbrush)
+ {
+ ERR("Failed to get brush object.\n");
+ SURFACE_ShareUnlockSurface(psurfMask);
+ if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
+ return FALSE;
+ }
+
+ psurfOffScreen = SURFACE_AllocSurface(STYPE_BITMAP,
+ cxWidth, cyHeight, psurfColor->SurfObj.iBitmapFormat,
+ 0, 0, NULL);
+ if(!psurfOffScreen)
+ {
+ ERR("Failed to allocate the off-screen surface.\n");
+ SURFACE_ShareUnlockSurface(psurfMask);
+ if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
+ BRUSH_ShareUnlockBrush(pbrush);
+ return FALSE;
+ }
+
+ /* Paint the brush */
+ EBRUSHOBJ_vInit(&eboFill, pbrush, psurfOffScreen, 0x00FFFFFF, 0, NULL);
+ RECTL_vSetRect(&rcDest, 0, 0, cxWidth, cyHeight);
+
+ Ret = IntEngBitBlt(&psurfOffScreen->SurfObj,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &rcDest,
+ NULL,
+ NULL,
+ &eboFill.BrushObject,
+ &pbrush->ptOrigin,
+ ROP4_PATCOPY);
+
+ /* Clean up everything */
+ EBRUSHOBJ_vCleanup(&eboFill);
+ BRUSH_ShareUnlockBrush(pbrush);
+
+ if(!Ret)
+ {
+ ERR("Failed to paint the off-screen surface.\n");
+ SURFACE_ShareUnlockSurface(psurfMask);
+ if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
+ GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
+ return FALSE;
+ }
+
+ /* We now have our destination surface */
+ psurfDest = psurfOffScreen;
+ }
+ else
+ {
+ /* We directly draw to the DC */
+ TRACE("Performing on screen rendering.\n");
+
+ psurfOffScreen = NULL;
+ pdc = DC_LockDc(hDc);
+ if(!pdc)
+ {
+ ERR("Could not lock the destination DC.\n");
+ SURFACE_ShareUnlockSurface(psurfMask);
+ if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
+ return FALSE;
+ }
+ /* Calculate destination rectangle */
+ RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
+ IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
+ RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
+
+ /* Prepare the underlying surface */
+ DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
+
+ /* Get the clip object */
+ pdcClipObj = pdc->rosdc.CombinedClip;
+
+ /* We now have our destination surface and rectangle */
+ psurfDest = pdc->dclevel.pSurface;
+
+ if(psurfDest == NULL)
+ {
+ /* Empty DC */
+ DC_vFinishBlit(pdc, NULL);
+ DC_UnlockDc(pdc);
+ SURFACE_ShareUnlockSurface(psurfMask);
+ if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
+ return FALSE;
+ }
+ }
+
+ /* Now do the rendering */
+ if(hbmAlpha && (diFlags & DI_IMAGE))
+ {
+ BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } };
+ PSURFACE psurf = NULL;
+
+ psurf = SURFACE_ShareLockSurface(hbmAlpha);
+ if(!psurf)
+ {
+ ERR("SURFACE_LockSurface failed!\n");
+ goto NoAlpha;
+ }
+
+ /* Initialize color translation object */
+ EXLATEOBJ_vInitialize(&exlo, psurf->ppal, psurfDest->ppal, 0xFFFFFFFF,
0xFFFFFFFF, 0);
+
+ /* Now do it */
+ Ret = IntEngAlphaBlend(&psurfDest->SurfObj,
+ &psurf->SurfObj,
+ pdcClipObj,
+ &exlo.xlo,
+ &rcDest,
+ &rcSrc,
+ &blendobj);
+
+ EXLATEOBJ_vCleanup(&exlo);
+ 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;
+
+ EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
+
+ Ret = IntEngStretchBlt(&psurfDest->SurfObj,
+ &psurfMask->SurfObj,
+ NULL,
+ pdcClipObj,
+ &exlo.xlo,
+ NULL,
+ &rcDest,
+ &rcSrc,
+ NULL,
+ NULL,
+ NULL,
+ rop4);
+
+ EXLATEOBJ_vCleanup(&exlo);
+
+ if(!Ret)
+ {
+ ERR("Failed to mask the bitmap data.\n");
+ goto Cleanup;
+ }
+ }
+
+ if(diFlags & DI_IMAGE)
+ {
+ if (psurfColor)
+ {
+ DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY ;
+
+ EXLATEOBJ_vInitialize(&exlo, psurfColor->ppal, psurfDest->ppal,
0x00FFFFFF, 0x00FFFFFF, 0);
+
+ Ret = IntEngStretchBlt(&psurfDest->SurfObj,
+ &psurfColor->SurfObj,
+ NULL,
+ pdcClipObj,
+ &exlo.xlo,
+ NULL,
+ &rcDest,
+ &rcSrc,
+ NULL,
+ NULL,
+ NULL,
+ rop4);
+
+ EXLATEOBJ_vCleanup(&exlo);
+
+ if(!Ret)
+ {
+ ERR("Failed to render the icon bitmap.\n");
+ goto Cleanup;
+ }
+ }
+ else
+ {
+ /* Mask bitmap holds the information in its bottom half */
+ DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY;
+ RECTL_vOffsetRect(&rcSrc, 0, pIcon->Size.cy);
+
+ EXLATEOBJ_vInitSrcMonoXlate(&exlo, psurfDest->ppal, 0x00FFFFFF, 0);
+
+ Ret = IntEngStretchBlt(&psurfDest->SurfObj,
+ &psurfMask->SurfObj,
+ NULL,
+ pdcClipObj,
+ &exlo.xlo,
+ NULL,
+ &rcDest,
+ &rcSrc,
+ NULL,
+ NULL,
+ NULL,
+ rop4);
+
+ EXLATEOBJ_vCleanup(&exlo);
+
+ if(!Ret)
+ {
+ ERR("Failed to render the icon bitmap.\n");
+ goto Cleanup;
+ }
+ }
+ }
+
+done:
+ /* We're done. Was it a double buffered draw ? */
+ if(bOffScreen)
+ {
+ /* Yes. Draw it back to our DC */
+ POINTL ptSrc = {0, 0};
+ pdc = DC_LockDc(hDc);
+ if(!pdc)
+ {
+ ERR("Could not lock the destination DC.\n");
+ return FALSE;
+ }
+ /* Calculate destination rectangle */
+ RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
+ IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
+ RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
+
+ /* Prepare the underlying surface */
+ DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
+
+ /* Get the clip object */
+ pdcClipObj = pdc->rosdc.CombinedClip;
+
+ /* We now have our destination surface and rectangle */
+ psurfDest = pdc->dclevel.pSurface;
+ if(!psurfDest)
+ {
+ /* So, you did all of this for an empty DC. */
+ DC_UnlockDc(pdc);
+ goto Cleanup2;
+ }
+
+ /* Color translation */
+ EXLATEOBJ_vInitialize(&exlo, psurfOffScreen->ppal, psurfDest->ppal,
0x00FFFFFF, 0x00FFFFFF, 0);
+
+ /* Blt it! */
+ Ret = IntEngBitBlt(&psurfDest->SurfObj,
+ &psurfOffScreen->SurfObj,
+ NULL,
+ pdcClipObj,
+ &exlo.xlo,
+ &rcDest,
+ &ptSrc,
+ NULL,
+ NULL,
+ NULL,
+ ROP4_SRCCOPY);
+
+ EXLATEOBJ_vCleanup(&exlo);
+ }
+Cleanup:
+ if(pdc)
+ {
+ DC_vFinishBlit(pdc, NULL);
+ DC_UnlockDc(pdc);
+ }
+
+Cleanup2:
+ /* Delete off screen rendering surface */
+ if(psurfOffScreen)
+ GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
+
+ /* Unlock other surfaces */
+ SURFACE_ShareUnlockSurface(psurfMask);
+ if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
+
+ return Ret;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+NtUserDrawIconEx(
+ HDC hdc,
+ int xLeft,
+ int yTop,
+ HICON hIcon,
+ int cxWidth,
+ int cyHeight,
+ UINT istepIfAniCur,
+ HBRUSH hbrFlickerFreeDraw,
+ UINT diFlags,
+ BOOL bMetaHDC, // When TRUE, GDI functions need to be handled in User32!
+ PVOID pDIXData)
+{
+ PCURICON_OBJECT pIcon;
+ BOOL Ret;
+
+ TRACE("Enter NtUserDrawIconEx\n");
+ UserEnterExclusive();
+
+ if (!(pIcon = UserGetCurIconObject(hIcon)))
+ {
+ ERR("UserGetCurIconObject() failed!\n");
+ UserLeave();
+ return FALSE;
+ }
+
+ Ret = UserDrawIconEx(hdc,
+ xLeft,
+ yTop,
+ pIcon,
+ cxWidth,
+ cyHeight,
+ istepIfAniCur,
+ hbrFlickerFreeDraw,
+ diFlags);
+
+ UserDereferenceObject(pIcon);
+
+ UserLeave();
+ return Ret;
+}
+
+/* EOF */
Propchange: trunk/reactos/win32ss/user/ntuser/cursoricon_new.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/win32ss/user/ntuser/msgqueue.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/msgque…
==============================================================================
--- trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] (original)
+++ trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] Mon Oct 29 15:50:20 2012
@@ -145,6 +145,7 @@
if (NewCursor)
{
/* Call GDI to set the new screen cursor */
+#ifdef NEW_CURSORICON
GreSetPointerShape(hdcScreen,
NewCursor->aFrame[0].hbmMask,
NewCursor->aFrame[0].hbmColor,
@@ -152,6 +153,15 @@
NewCursor->ptlHotspot.y,
gpsi->ptCursor.x,
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 */
{
@@ -571,6 +581,7 @@
if(CurInfo->CurrentCursorObject != MessageQueue->CursorObject)
{
/* Call GDI to set the new screen cursor */
+#ifdef NEW_CURSORICON
GreSetPointerShape(hdcScreen,
MessageQueue->CursorObject->aFrame[0].hbmMask,
MessageQueue->CursorObject->aFrame[0].hbmColor,
@@ -578,6 +589,15 @@
MessageQueue->CursorObject->ptlHotspot.y,
gpsi->ptCursor.x,
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
GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y);
}