[WIN32K]
[reactos.git] / reactos / win32ss / user / ntuser / cursoricon.c
index c3a95b2..4da91bb 100644 (file)
@@ -2,7 +2,7 @@
  * 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
  */
 /*
@@ -144,12 +144,16 @@ static BOOLEAN FASTCALL
 ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon)
 {
     PPROCESSINFO Win32Process;
+    PLIST_ENTRY ListEntry;
     PCURICON_PROCESS Current;
 
     Win32Process = PsGetCurrentProcessWin32Process();
 
-    LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
+    ListEntry = CurIcon->ProcessList.Flink;
+    while (ListEntry != &CurIcon->ProcessList)
     {
+        Current = CONTAINING_RECORD(ListEntry, CURICON_PROCESS, ListEntry);
+        ListEntry = ListEntry->Flink;
         if (Current->Process == Win32Process)
         {
             /* Already registered for this process */
@@ -165,6 +169,7 @@ ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon)
     }
     InsertHeadList(&CurIcon->ProcessList, &Current->ListEntry);
     Current->Process = Win32Process;
+    IntReferenceProcessInfo(Win32Process);
 
     return TRUE;
 }
@@ -173,10 +178,14 @@ PCURICON_OBJECT FASTCALL
 IntFindExistingCurIconObject(HMODULE hModule,
                              HRSRC hRsrc, LONG cx, LONG cy)
 {
+    PLIST_ENTRY ListEntry;
     PCURICON_OBJECT CurIcon;
 
-    LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry)
+    ListEntry = gCurIconList.Flink;
+    while (ListEntry != &gCurIconList)
     {
+        CurIcon = CONTAINING_RECORD(ListEntry, CURICON_OBJECT, ListEntry);
+        ListEntry = ListEntry->Flink;
 
         // if (NT_SUCCESS(UserReferenceObjectByPointer(Object, TYPE_CURSOR))) // <- huh????
 //      UserReferenceObject(  CurIcon);
@@ -204,12 +213,18 @@ IntFindExistingCurIconObject(HMODULE hModule,
 }
 
 HANDLE
-IntCreateCurIconHandle(DWORD dwNumber)
+IntCreateCurIconHandle(BOOLEAN Anim)
 {
     PCURICON_OBJECT CurIcon;
     HANDLE hCurIcon;
 
-    CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, TYPE_CURSOR, sizeof(CURICON_OBJECT));
+    CurIcon = UserCreateObject(
+        gHandleTable,
+        NULL,
+        GetW32ThreadInfo(),
+        &hCurIcon,
+        TYPE_CURSOR,
+        sizeof(CURICON_OBJECT));
 
     if (!CurIcon)
     {
@@ -241,7 +256,8 @@ IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
     PSYSTEM_CURSORINFO CurInfo;
     HBITMAP bmpMask, bmpColor;
     BOOLEAN Ret, bListEmpty, bFound = FALSE;
-    PCURICON_PROCESS Current = NULL;
+    PLIST_ENTRY ListEntry;
+    PCURICON_PROCESS Current;
 
     /* For handles created without any data (error handling) */
     if(IsListEmpty(&CurIcon->ProcessList))
@@ -249,12 +265,16 @@ IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
 
     /* 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)
+    ListEntry = CurIcon->ProcessList.Flink;
+    while (ListEntry != &CurIcon->ProcessList)
     {
+        Current = CONTAINING_RECORD(ListEntry, CURICON_PROCESS, ListEntry);
+        ListEntry = ListEntry->Flink;
         if (Current->Process == ppi)
         {
             bFound = TRUE;
             bListEmpty = RemoveEntryList(&Current->ListEntry);
+            IntDereferenceProcessInfo(ppi);
             break;
         }
     }
@@ -317,19 +337,55 @@ emptyList:
     return Ret;
 }
 
-VOID FASTCALL
-IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
+HCURSOR FASTCALL
+IntSetCursor(
+    HCURSOR hCursor)
 {
-    PCURICON_OBJECT CurIcon, tmp;
+    PCURICON_OBJECT pcurOld, pcurNew;
+    HCURSOR hOldCursor = NULL;
 
-    /* Run through the list of icon objects */
-    LIST_FOR_EACH_SAFE(CurIcon, tmp, &gCurIconList, CURICON_OBJECT, ListEntry)
+    if (hCursor)
     {
-        UserReferenceObject(CurIcon);
-        IntDestroyCurIconObject(CurIcon, Win32Process);
+        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:
+    return hOldCursor;
 }
 
+BOOL FASTCALL
+IntDestroyCursor(
+  HANDLE hCurIcon,
+  BOOL bForce)
+{
+    PCURICON_OBJECT CurIcon;
+    BOOL ret;
+
+    if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
+    {
+        return FALSE;
+    }
+
+    ret = IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
+    /* Note: IntDestroyCurIconObject will remove our reference for us! */
+
+    return ret;
+}
 
 /*
  * @implemented
@@ -1238,10 +1294,10 @@ UserDrawIconEx(
         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);
 
         /* Get the clip object */
-        pdcClipObj = pdc->rosdc.CombinedClip;
+        pdcClipObj = &pdc->co.ClipObj;
 
         /* We now have our destination surface and rectangle */
         psurfDest = pdc->dclevel.pSurface;
@@ -1423,10 +1479,10 @@ done:
         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);
 
         /* Get the clip object */
-        pdcClipObj = pdc->rosdc.CombinedClip;
+        pdcClipObj = &pdc->co.ClipObj;
 
         /* We now have our destination surface and rectangle */
         psurfDest = pdc->dclevel.pSurface;