* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Win32k subsystem
* PURPOSE: Cursor and icon functions
- * FILE: subsystems/win32/win32k/ntuser/cursoricon.c
+ * FILE: win32ss/user/ntuser/cursoricon.c
* PROGRAMER: ReactOS Team
*/
/*
return NULL;
}
- if(UserObjectInDestroy(hCurIcon))
+ if (UserObjectInDestroy(hCurIcon))
{
- ERR("Requesting destroyed cursor.\n");
+ WARN("Requesting invalid/destroyed cursor.\n");
EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
return NULL;
}
CurIcon = UserCreateObject(
gHandleTable,
NULL,
- NULL,
+ GetW32ThreadInfo(),
&hCurIcon,
TYPE_CURSOR,
Animated ? sizeof(ACON) : sizeof(CURICON_OBJECT));
return hCurIcon;
}
-BOOLEAN FASTCALL
-IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, BOOLEAN bForce)
+BOOLEAN
+IntDestroyCurIconObject(
+ _In_ PVOID Object)
{
- if(CurIcon->CURSORF_flags & CURSORF_CURRENT)
- {
- /* Mark the object as destroyed, and fail, as per tests */
- TRACE("Cursor is current, marking as destroyed.\n");
- UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
- return FALSE;
- }
+ PCURICON_OBJECT CurIcon = Object;
- if(CurIcon->head.ppi != PsGetCurrentProcessWin32Process())
- {
- /* This object doesn't belong to the current process */
- WARN("Trying to delete foreign cursor!\n");
- UserDereferenceObject(CurIcon);
- EngSetLastError(ERROR_DESTROY_OBJECT_OF_OTHER_THREAD);
- return FALSE;
- }
-
- /* Do not destroy it if it is shared. (And we're not forced to) */
- if((CurIcon->CURSORF_flags & CURSORF_LRSHARED) && !bForce)
+ /* Try finding it in its process cache */
+ if (CurIcon->CURSORF_flags & CURSORF_LRSHARED)
{
- /* Tests show this is a valid call */
- WARN("Trying to destroy shared cursor!\n");
- UserDereferenceObject(CurIcon);
- return TRUE;
+ PPROCESSINFO ppi;
+
+ ppi = CurIcon->head.ppi;
+ if (ppi->pCursorCache == CurIcon)
+ {
+ ppi->pCursorCache = CurIcon->pcurNext;
+ UserDereferenceObject(CurIcon);
+ }
+ else
+ {
+ PCURICON_OBJECT CacheCurIcon = ppi->pCursorCache;
+ while (CacheCurIcon)
+ {
+ if (CacheCurIcon->pcurNext == CurIcon)
+ {
+ CacheCurIcon->pcurNext = CurIcon->pcurNext;
+ break;
+ }
+ CacheCurIcon = CacheCurIcon->pcurNext;
+ }
+
+ /* We must have found it! */
+ ASSERT(CacheCurIcon != NULL);
+ UserDereferenceObject(CurIcon);
+ }
}
+ /* We just mark the handle as being destroyed.
+ * Deleting all the stuff will be deferred to the actual struct free. */
+ return UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
+}
+
+void
+FreeCurIconObject(
+ _In_ PVOID Object)
+{
+ PCURICON_OBJECT CurIcon = Object;
+
if(!(CurIcon->CURSORF_flags & CURSORF_ACON))
{
HBITMAP bmpMask = CurIcon->hbmMask;
UINT i;
for(i = 0; i < AniCurIcon->cpcur; i++)
- IntDestroyCurIconObject(AniCurIcon->aspcur[i], TRUE);
+ IntDestroyCurIconObject(AniCurIcon->aspcur[i]);
ExFreePoolWithTag(AniCurIcon->aspcur, USERTAG_CURSOR);
}
CurIcon->atomModName = 0;
}
- /* We were given a pointer, no need to keep the reference any longer! */
- UserDereferenceObject(CurIcon);
- return UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
+ /* Finally free the thing */
+ FreeProcMarkObject(CurIcon);
}
VOID FASTCALL
-IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
+IntCleanupCurIconCache(PPROCESSINFO Win32Process)
{
PCURICON_OBJECT CurIcon;
/* Run through the list of icon objects */
- while(Win32Process->pCursorCache)
+ while (Win32Process->pCursorCache)
{
CurIcon = Win32Process->pCursorCache;
Win32Process->pCursorCache = CurIcon->pcurNext;
- /* One ref for the handle, one for the list,
- * and potentially one from an other process via SetCursor */
- ASSERT(CurIcon->head.cLockObj <= 3);
- IntDestroyCurIconObject(CurIcon, TRUE);
- }
-}
-
-HCURSOR FASTCALL
-IntSetCursor(
- HCURSOR hCursor)
-{
- PCURICON_OBJECT pcurOld, pcurNew;
- HCURSOR hOldCursor = NULL;
-
- if (hCursor)
- {
- pcurNew = UserGetCurIconObject(hCursor);
- if (!pcurNew)
- {
- EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
- goto leave;
- }
- pcurNew->CURSORF_flags |= CURSORF_CURRENT;
- }
- else
- {
- pcurNew = NULL;
- }
-
- pcurOld = UserSetCursor(pcurNew, FALSE);
- if (pcurOld)
- {
- hOldCursor = pcurOld->head.h;
- pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
- if(UserObjectInDestroy(hOldCursor))
- {
- /* Destroy it once and for all */
- IntDestroyCurIconObject(pcurOld, TRUE);
- hOldCursor = NULL;
- }
- else
- {
- UserDereferenceObject(pcurOld);
- }
- }
-leave:
- return hOldCursor;
-}
-
-BOOL FASTCALL
-IntDestroyCursor(
- HANDLE hCurIcon,
- BOOL bForce)
-{
- PCURICON_OBJECT CurIcon;
- BOOL ret;
-
- if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
- {
- RETURN(FALSE);
+ UserDereferenceObject(CurIcon);
}
-
- ret = IntDestroyCurIconObject(CurIcon, bForce);
- /* Note: IntDestroyCurIconObject will remove our reference for us! */
-
- return ret;
}
/*
prcl = &rclLocal;
}
- UserEnterExclusive();
+ UserEnterExclusive();
/* Call the internal function */
bResult = UserClipCursor(prcl);
_In_ HANDLE hCurIcon,
_In_ BOOL bForce)
{
- PCURICON_OBJECT CurIcon;
BOOL ret;
- DECLARE_RETURN(BOOL);
+ PCURICON_OBJECT CurIcon = NULL;
- TRACE("Enter NtUserDestroyCursorIcon\n");
+ TRACE("Enter NtUserDestroyCursorIcon (%p, %u)\n", hCurIcon, bForce);
UserEnterExclusive();
- if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
+ CurIcon = UserGetCurIconObject(hCurIcon);
+ if (!CurIcon)
{
- RETURN(FALSE);
+ ret = FALSE;
+ goto leave;
}
- ret = IntDestroyCurIconObject(CurIcon, bForce);
- /* Note: IntDestroyCurIconObject will remove our reference for us! */
+ if (!bForce)
+ {
+ /* Maybe we have good reasons not to destroy this object */
+ if (CurIcon->head.ppi != PsGetCurrentProcessWin32Process())
+ {
+ /* No way, you're not touching my cursor */
+ ret = FALSE;
+ goto leave;
+ }
- RETURN(ret);
+ if (CurIcon->CURSORF_flags & CURSORF_CURRENT)
+ {
+ WARN("Trying to delete current cursor!\n");
+ ret = FALSE;
+ goto leave;
+ }
-CLEANUP:
- TRACE("Leave NtUserDestroyCursorIcon, ret=%i\n",_ret_);
+ if (CurIcon->CURSORF_flags & CURSORF_LRSHARED)
+ {
+ WARN("Trying to delete shared cursor.\n");
+ /* This one is not an error */
+ ret = TRUE;
+ goto leave;
+ }
+ }
+
+ /* Destroy the handle */
+ ret = IntDestroyCurIconObject(CurIcon);
+
+leave:
+ if (CurIcon)
+ UserDereferenceObject(CurIcon);
+ TRACE("Leave NtUserDestroyCursorIcon, ret=%i\n", ret);
UserLeave();
- END_CLEANUP;
+ return ret;
}
PCURICON_OBJECT pcurOld, pcurNew;
HCURSOR hOldCursor = NULL;
- TRACE("Enter NtUserSetCursor\n");
+ TRACE("Enter NtUserSetCursor: %p\n", hCursor);
UserEnterExclusive();
if (hCursor)
if (pcurOld)
{
hOldCursor = pcurOld->head.h;
- pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
- if(UserObjectInDestroy(hOldCursor))
- {
- /* Destroy it once and for all */
- IntDestroyCurIconObject(pcurOld, TRUE);
+ /* See if it was destroyed in the meantime */
+ if (UserObjectInDestroy(hOldCursor))
hOldCursor = NULL;
- }
- else
- {
- UserDereferenceObject(pcurOld);
- }
+ pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
+ UserDereferenceObject(pcurOld);
}
leave:
for(i = 0; i < numFrames; i++)
{
if(AniCurIcon->aspcur[i])
- IntDestroyCurIconObject(AniCurIcon->aspcur[i], TRUE);
+ IntDestroyCurIconObject(AniCurIcon->aspcur[i]);
}
AniCurIcon->cicur = 0;
AniCurIcon->cpcur = 0;
RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
/* Prepare the underlying surface */
- DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
+ DC_vPrepareDCsForBlit(pdc, &rcDest, NULL, NULL);
/* We now have our destination surface and rectangle */
psurfDest = pdc->dclevel.pSurface;
/* We now have our destination surface */
psurfDest = psurfOffScreen;
#else
- pdcClipObj = pdc->rosdc.CombinedClip;
+ pdcClipObj = &pdc->co.ClipObj;
/* Paint the brush */
EBRUSHOBJ_vInit(&eboFill, pbrush, psurfDest, 0x00FFFFFF, 0, NULL);
{
/* We directly draw to the DC */
TRACE("Performing on screen rendering.\n");
- pdcClipObj = pdc->rosdc.CombinedClip;
+ pdcClipObj = &pdc->co.ClipObj;
// psurfOffScreen = NULL;
}
/* Now do the rendering */
- if(hbmAlpha && ((diFlags & DI_NORMAL) == DI_NORMAL))
- {
- BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } };
+ if(hbmAlpha && ((diFlags & DI_NORMAL) == DI_NORMAL))
+ {
+ BLENDOBJ blendobj = { {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA } };
PSURFACE psurf = NULL;
psurf = SURFACE_ShareLockSurface(hbmAlpha);
EXLATEOBJ_vCleanup(&exlo);
SURFACE_ShareUnlockSurface(psurf);
if(Ret) goto done;
- ERR("NtGdiAlphaBlend failed!\n");
+ ERR("NtGdiAlphaBlend failed!\n");
}
NoAlpha:
if (diFlags & DI_MASK)
if(diFlags & DI_IMAGE)
{
- if (psurfColor)
+ if (psurfColor)
{
DWORD rop4 = (diFlags & DI_MASK) ? ROP4_SRCINVERT : ROP4_SRCCOPY ;