Merge 48064 from yarotows
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / cursoricon.c
index 4e1802c..b4446cd 100644 (file)
@@ -12,9 +12,9 @@
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 /*
@@ -36,7 +36,7 @@
  * CURICON_PROCESS structs starting at CurIcon->ProcessList.
  */
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
 static PAGED_LOOKASIDE_LIST gProcessLookasideList;
 static LIST_ENTRY gCurIconList;
 
-BOOL FASTCALL
-IntGetCursorLocation(PWINSTATION_OBJECT WinSta, POINT *loc)
+SYSTEM_CURSORINFO gSysCursorInfo;
+
+BOOL
+InitCursorImpl()
 {
-    loc->x = gpsi->ptCursor.x;
-    loc->y = gpsi->ptCursor.y;
+    ExInitializePagedLookasideList(&gProcessLookasideList,
+                                   NULL,
+                                   NULL,
+                                   0,
+                                   sizeof(CURICON_PROCESS),
+                                   TAG_DIB,
+                                   128);
+    InitializeListHead(&gCurIconList);
+
+     gSysCursorInfo.Enabled = FALSE;
+     gSysCursorInfo.ButtonsDown = 0;
+     gSysCursorInfo.CursorClipInfo.IsClipped = FALSE;
+     gSysCursorInfo.LastBtnDown = 0;
+     gSysCursorInfo.CurrentCursorObject = NULL;
+     gSysCursorInfo.ShowingCursor = 0;
+     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)
 {
@@ -72,159 +95,74 @@ PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
         return NULL;
     }
 
-    ASSERT(USER_BODY_TO_HEADER(CurIcon)->RefCount >= 1);
+    ASSERT(CurIcon->head.cLockObj >= 1);
     return CurIcon;
 }
 
-
-#define COLORCURSORS_ALLOWED FALSE
-HCURSOR FASTCALL
-IntSetCursor(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT NewCursor,
-             BOOL ForceChange)
+HCURSOR
+FASTCALL
+UserSetCursor(
+    PCURICON_OBJECT NewCursor,
+    BOOL ForceChange)
 {
-    SURFACE *psurf;
-    SURFOBJ *pso;
-    PDEVINFO DevInfo;
-    PSURFACE MaskBmpObj = NULL;
     PSYSTEM_CURSORINFO CurInfo;
     PCURICON_OBJECT OldCursor;
-    HCURSOR Ret = (HCURSOR)0;
-    HBITMAP hMask = 0;
-    SURFOBJ *soMask = NULL, *soColor = NULL;
-    XLATEOBJ *XlateObj = NULL;
-    HDC Screen;
-    PDC dc;
-    ULONG Status;
-
-    CurInfo = IntGetSysCursorInfo(WinSta);
+    HCURSOR hOldCursor = (HCURSOR)0;
+    HDC hdcScreen;
+    BOOL bResult;
+       
+       CurInfo = IntGetSysCursorInfo();
+
     OldCursor = CurInfo->CurrentCursorObject;
     if (OldCursor)
     {
-        Ret = (HCURSOR)OldCursor->Self;
+        hOldCursor = (HCURSOR)OldCursor->Self;
     }
 
-    if (!ForceChange && OldCursor == NewCursor)
+    /* Is the new cursor the same as the old cursor? */
+    if (OldCursor == NewCursor)
     {
-        return Ret;
+        /* Nothing to to do in this case */
+        return hOldCursor;
     }
 
-    if (!(Screen = IntGetScreenDC()))
+    /* Get the screen DC */
+    if(!(hdcScreen = IntGetScreenDC()))
     {
         return (HCURSOR)0;
     }
-    /* FIXME use the desktop's HDC instead of using ScreenDeviceContext */
-    dc = DC_LockDc(Screen);
 
-    if (!dc)
+    /* Do we have a new cursor? */
+    if (NewCursor)
     {
-        return Ret;
-    }
-    DevInfo = (PDEVINFO)&dc->ppdev->DevInfo;
+        UserReferenceObject(NewCursor);
 
-    psurf = dc->dclevel.pSurface;
-    if (!psurf)
-    {
-        DC_UnlockDc(dc);
-        return (HCURSOR)0;
-    }
-    pso = &psurf->SurfObj;
+        CurInfo->ShowingCursor = 1;
+        CurInfo->CurrentCursorObject = NewCursor;
 
-    if (!NewCursor)
-    {
-        if (CurInfo->CurrentCursorObject || ForceChange)
-        {
-            if (CurInfo->CurrentCursorObject)
-            {
-                UserDereferenceObject(CurInfo->CurrentCursorObject);
-                if (CurInfo->ShowingCursor)
-                {
-                    DPRINT("Removing pointer!\n");
-                    /* Remove the cursor if it was displayed */
-                    IntEngMovePointer(pso, -1, -1, &GDIDEV(pso)->Pointer.Exclude);
-                }
-            }
+        /* Call GDI to set the new screen cursor */
+        bResult = GreSetPointerShape(hdcScreen,
+                                     NewCursor->IconInfo.hbmMask,
+                                     NewCursor->IconInfo.hbmColor,
+                                     NewCursor->IconInfo.xHotspot,
+                                     NewCursor->IconInfo.yHotspot,
+                                     gpsi->ptCursor.x,
+                                     gpsi->ptCursor.y);
 
-            CurInfo->CurrentCursorObject = NewCursor; /* i.e. CurrentCursorObject = NULL */
-            CurInfo->ShowingCursor = 0;
-        }
 
-        DC_UnlockDc(dc);
-        return Ret;
     }
-
-    /* TODO: Fixme. Logic is screwed above */
-
-    MaskBmpObj = SURFACE_LockSurface(NewCursor->IconInfo.hbmMask);
-    if (MaskBmpObj)
+    else
     {
-        const int maskBpp = BitsPerFormat(MaskBmpObj->SurfObj.iBitmapFormat);
-        SURFACE_UnlockSurface(MaskBmpObj);
-        if (maskBpp != 1)
+        /* Check if were diplaying a cursor */
+        if (OldCursor && CurInfo->ShowingCursor)
         {
-            DPRINT1("SetCursor: The Mask bitmap must have 1BPP!\n");
-            DC_UnlockDc(dc);
-            return Ret;
+            /* Remove the cursor */
+            GreMovePointer(hdcScreen, -1, -1);
+            DPRINT("Removing pointer!\n");
         }
 
-        if ((DevInfo->flGraphicsCaps2 & GCAPS2_ALPHACURSOR) &&
-                pso->iBitmapFormat >= BMF_16BPP &&
-                pso->iBitmapFormat <= BMF_32BPP &&
-                NewCursor->Shadow && COLORCURSORS_ALLOWED)
-        {
-            /* FIXME - Create a color pointer, only 32bit bitmap, set alpha bits!
-                       Do not pass a mask bitmap to DrvSetPointerShape()!
-                       Create a XLATEOBJ that describes the colors of the bitmap. */
-            DPRINT1("SetCursor: (Colored) alpha cursors are not supported!\n");
-        }
-        else
-        {
-            if (NewCursor->IconInfo.hbmColor
-                    && COLORCURSORS_ALLOWED)
-            {
-                /* FIXME - Create a color pointer, create only one 32bit bitmap!
-                           Do not pass a mask bitmap to DrvSetPointerShape()!
-                           Create a XLATEOBJ that describes the colors of the bitmap.
-                           (16bit bitmaps are propably allowed) */
-                DPRINT1("SetCursor: Cursors with colors are not supported!\n");
-            }
-            else
-            {
-                MaskBmpObj = SURFACE_LockSurface(NewCursor->IconInfo.hbmMask);
-                if (MaskBmpObj)
-                {
-                    RECTL DestRect = {0, 0, MaskBmpObj->SurfObj.sizlBitmap.cx, MaskBmpObj->SurfObj.sizlBitmap.cy};
-                    POINTL SourcePoint = {0, 0};
-
-                    /*
-                     * NOTE: For now we create the cursor in top-down bitmap,
-                     * because VMware driver rejects it otherwise. This should
-                     * be fixed later.
-                     */
-                    hMask = EngCreateBitmap(
-                                MaskBmpObj->SurfObj.sizlBitmap, abs(MaskBmpObj->SurfObj.lDelta),
-                                MaskBmpObj->SurfObj.iBitmapFormat, BMF_TOPDOWN,
-                                NULL);
-                    if (!hMask)
-                    {
-                        SURFACE_UnlockSurface(MaskBmpObj);
-                        DC_UnlockDc(dc);
-                        return (HCURSOR)0;
-                    }
-                    soMask = EngLockSurface((HSURF)hMask);
-                    IntEngCopyBits(soMask, &MaskBmpObj->SurfObj, NULL, NULL,
-                                   &DestRect, &SourcePoint);
-                    SURFACE_UnlockSurface(MaskBmpObj);
-                }
-            }
-        }
-        CurInfo->ShowingCursor = CURSOR_SHOWING;
-        CurInfo->CurrentCursorObject = NewCursor;
-        UserReferenceObject(NewCursor);
-    }
-    else
-    {
-        CurInfo->ShowingCursor = 0;
         CurInfo->CurrentCursorObject = NULL;
+        CurInfo->ShowingCursor = 0;
     }
 
     /* OldCursor is not in use anymore */
@@ -233,49 +171,106 @@ IntSetCursor(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT NewCursor,
         UserDereferenceObject(OldCursor);
     }
 
-    Status  = IntEngSetPointerShape(pso,
-                                    soMask,
-                                    soColor,
-                                    XlateObj,
-                                    NewCursor->IconInfo.xHotspot,
-                                    NewCursor->IconInfo.yHotspot,
-                                    gpsi->ptCursor.x,
-                                    gpsi->ptCursor.y,
-                                    &(GDIDEV(pso)->Pointer.Exclude),
-                                    SPS_CHANGE);
+    /* Return handle of the old cursor */
+    return hOldCursor;
+}
+
+BOOL UserSetCursorPos( INT x, INT y, BOOL SendMouseMoveMsg)
+{
+    PWINDOW_OBJECT DesktopWindow;
+    PSYSTEM_CURSORINFO CurInfo;
+    HDC hDC;
+    MSG Msg;
 
-    if (Status != SPS_ACCEPT_NOEXCLUDE)
+    if(!(hDC = IntGetScreenDC()))
     {
-        DPRINT1("IntEngSetPointerShape returned %lx\n", Status);
+        return FALSE;
     }
 
-    if (hMask)
+    CurInfo = IntGetSysCursorInfo();
+
+    DesktopWindow = UserGetDesktopWindow();
+
+    if (DesktopWindow)
     {
-        EngUnlockSurface(soMask);
-        EngDeleteSurface((HSURF)hMask);
+        if(x >= DesktopWindow->Wnd->rcClient.right)
+            x = DesktopWindow->Wnd->rcClient.right - 1;
+        if(y >= DesktopWindow->Wnd->rcClient.bottom)
+            y = DesktopWindow->Wnd->rcClient.bottom - 1;
     }
-    if (XlateObj)
+
+    if(x < 0)
+        x = 0;
+    if(y < 0)
+        y = 0;
+
+    //Clip cursor position
+    if(CurInfo->CursorClipInfo.IsClipped)
     {
-        EngDeleteXlate(XlateObj);
+       if(x >= (LONG)CurInfo->CursorClipInfo.Right)
+           x = (LONG)CurInfo->CursorClipInfo.Right - 1;
+       if(x < (LONG)CurInfo->CursorClipInfo.Left)
+           x = (LONG)CurInfo->CursorClipInfo.Left;
+       if(y >= (LONG)CurInfo->CursorClipInfo.Bottom)
+           y = (LONG)CurInfo->CursorClipInfo.Bottom - 1;
+       if(y < (LONG)CurInfo->CursorClipInfo.Top)
+           y = (LONG)CurInfo->CursorClipInfo.Top;
     }
 
-    DC_UnlockDc(dc);
-    return Ret;
+    //Store the new cursor position
+    gpsi->ptCursor.x = x;
+    gpsi->ptCursor.y = y;
+
+    //Move the mouse pointer
+    GreMovePointer(hDC, x, y);
+
+    if (!SendMouseMoveMsg)
+       return TRUE;
+
+    //Generate a mouse move message
+    Msg.message = WM_MOUSEMOVE;
+    Msg.wParam = CurInfo->ButtonsDown;
+    Msg.lParam = MAKELPARAM(x, y);
+    Msg.pt = gpsi->ptCursor;
+    MsqInsertSystemMessage(&Msg);
+
+    return TRUE;
 }
 
-BOOL FASTCALL
-IntSetupCurIconHandles(PWINSTATION_OBJECT WinSta)
+/* Called from NtUserCallOneParam with Routine ONEPARAM_ROUTINE_SHOWCURSOR
+ * User32 macro NtUserShowCursor */
+int UserShowCursor(BOOL bShow)
 {
-    ExInitializePagedLookasideList(&gProcessLookasideList,
-                                   NULL,
-                                   NULL,
-                                   0,
-                                   sizeof(CURICON_PROCESS),
-                                   TAG_DIB,
-                                   128);
-    InitializeListHead(&gCurIconList);
+    PSYSTEM_CURSORINFO CurInfo = IntGetSysCursorInfo();
+    HDC hdcScreen;
 
-    return TRUE;
+    if (!(hdcScreen = IntGetScreenDC()))
+    {
+        return 0; /* No mouse */
+    }
+
+    if (bShow == FALSE)
+    {
+        /* Check if were diplaying a cursor */
+        if (CurInfo->ShowingCursor == 1)
+        {
+            /* Remove the pointer */
+            GreMovePointer(hdcScreen, -1, -1);
+            DPRINT("Removing pointer!\n");
+        }
+        CurInfo->ShowingCursor--;
+    }
+    else
+    {
+        if (CurInfo->ShowingCursor == 0)
+        {
+            /*Show the pointer*/
+            GreMovePointer(hdcScreen, gpsi->ptCursor.x, gpsi->ptCursor.y);
+        }
+        CurInfo->ShowingCursor++;
+    }
+
+    return CurInfo->ShowingCursor;
 }
 
 /*
@@ -317,7 +312,7 @@ ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon)
 }
 
 PCURICON_OBJECT FASTCALL
-IntFindExistingCurIconObject(PWINSTATION_OBJECT WinSta, HMODULE hModule,
+IntFindExistingCurIconObject(HMODULE hModule,
                              HRSRC hRsrc, LONG cx, LONG cy)
 {
     PCURICON_OBJECT CurIcon;
@@ -350,13 +345,13 @@ IntFindExistingCurIconObject(PWINSTATION_OBJECT WinSta, HMODULE hModule,
     return NULL;
 }
 
-PCURICON_OBJECT FASTCALL
-IntCreateCurIconHandle(PWINSTATION_OBJECT WinSta)
+PCURICON_OBJECT
+IntCreateCurIconHandle()
 {
     PCURICON_OBJECT CurIcon;
     HANDLE hCurIcon;
 
-    CurIcon = UserCreateObject(gHandleTable, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
+    CurIcon = UserCreateObject(gHandleTable, NULL, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
 
     if (!CurIcon)
     {
@@ -381,7 +376,7 @@ IntCreateCurIconHandle(PWINSTATION_OBJECT WinSta)
 }
 
 BOOLEAN FASTCALL
-IntDestroyCurIconObject(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT CurIcon, BOOL ProcessCleanup)
+IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, BOOL ProcessCleanup)
 {
     PSYSTEM_CURSORINFO CurInfo;
     HBITMAP bmpMask, bmpColor;
@@ -431,12 +426,12 @@ IntDestroyCurIconObject(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT CurIcon, BOOL
         RemoveEntryList(&CurIcon->ListEntry);
     }
 
-    CurInfo = IntGetSysCursorInfo(WinSta);
+    CurInfo = IntGetSysCursorInfo();
 
     if (CurInfo->CurrentCursorObject == CurIcon)
     {
         /* Hide the cursor if we're destroying the current cursor */
-        IntSetCursor(WinSta, NULL, TRUE);
+        UserSetCursor(NULL, TRUE);
     }
 
     bmpMask = CurIcon->IconInfo.hbmMask;
@@ -466,16 +461,9 @@ IntDestroyCurIconObject(PWINSTATION_OBJECT WinSta, PCURICON_OBJECT CurIcon, BOOL
 VOID FASTCALL
 IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
 {
-    PWINSTATION_OBJECT WinSta;
     PCURICON_OBJECT CurIcon, tmp;
     PCURICON_PROCESS ProcessData;
 
-    WinSta = IntGetWinStaObj();
-    if (WinSta == NULL)
-    {
-        return;
-    }
-
     LIST_FOR_EACH_SAFE(CurIcon, tmp, &gCurIconList, CURICON_OBJECT, ListEntry)
     {
         UserReferenceObject(CurIcon);
@@ -486,7 +474,7 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
                 if (Win32Process == ProcessData->Process)
                 {
                     RemoveEntryList(&CurIcon->ListEntry);
-                    IntDestroyCurIconObject(WinSta, CurIcon, TRUE);
+                    IntDestroyCurIconObject(CurIcon, TRUE);
                     CurIcon = NULL;
                     break;
                 }
@@ -501,94 +489,6 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
         }
     }
 
-    ObDereferenceObject(WinSta);
-}
-
-/*
- * @implemented
- */
-HANDLE
-APIENTRY
-NtUserCreateCursorIconHandle(PICONINFO IconInfo OPTIONAL, BOOL Indirect)
-{
-    PCURICON_OBJECT CurIcon;
-    PWINSTATION_OBJECT WinSta;
-    PSURFACE psurfBmp;
-    NTSTATUS Status;
-    HANDLE Ret;
-    DECLARE_RETURN(HANDLE);
-
-    DPRINT("Enter NtUserCreateCursorIconHandle\n");
-    UserEnterExclusive();
-
-    WinSta = IntGetWinStaObj();
-    if (WinSta == NULL)
-    {
-        RETURN((HANDLE)0);
-    }
-
-    if (!(CurIcon = IntCreateCurIconHandle(WinSta)))
-    {
-        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-        ObDereferenceObject(WinSta);
-        RETURN((HANDLE)0);
-    }
-
-    Ret = CurIcon->Self;
-
-    if (IconInfo)
-    {
-        Status = MmCopyFromCaller(&CurIcon->IconInfo, IconInfo, sizeof(ICONINFO));
-        if (NT_SUCCESS(Status))
-        {
-            /* Copy bitmaps and size info */
-            if (Indirect)
-            {
-                CurIcon->IconInfo.hbmMask = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmMask);
-                CurIcon->IconInfo.hbmColor = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmColor);
-            }
-            if (CurIcon->IconInfo.hbmColor &&
-                    (psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmColor)))
-            {
-                CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
-                CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
-                SURFACE_UnlockSurface(psurfBmp);
-                GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmColor, NULL);
-            }
-            if (CurIcon->IconInfo.hbmMask &&
-                    (psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmMask)))
-            {
-                if (CurIcon->IconInfo.hbmColor == NULL)
-                {
-                    CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
-                    CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy >> 1;
-                }
-                SURFACE_UnlockSurface(psurfBmp);
-                GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
-            }
-
-            /* Calculate icon hotspot */
-            if (CurIcon->IconInfo.fIcon == TRUE)
-            {
-                CurIcon->IconInfo.xHotspot = CurIcon->Size.cx >> 1;
-                CurIcon->IconInfo.yHotspot = CurIcon->Size.cy >> 1;
-            }
-        }
-        else
-        {
-            SetLastNtError(Status);
-            /* FIXME - Don't exit here */
-        }
-    }
-
-    UserDereferenceObject(CurIcon);
-    ObDereferenceObject(WinSta);
-    RETURN(Ret);
-
-CLEANUP:
-    DPRINT("Leave NtUserCreateCursorIconHandle, ret=%i\n",_ret_);
-    UserLeave();
-    END_CLEANUP;
 }
 
 /*
@@ -606,10 +506,9 @@ NtUserGetIconInfo(
 {
     ICONINFO ii;
     PCURICON_OBJECT CurIcon;
-    PWINSTATION_OBJECT WinSta;
     NTSTATUS Status = STATUS_SUCCESS;
     BOOL Ret = FALSE;
-    DECLARE_RETURN(BOOL);
+    DWORD colorBpp = 0;
 
     DPRINT("Enter NtUserGetIconInfo\n");
     UserEnterExclusive();
@@ -617,19 +516,12 @@ NtUserGetIconInfo(
     if (!IconInfo)
     {
         SetLastWin32Error(ERROR_INVALID_PARAMETER);
-        RETURN(FALSE);
-    }
-
-    WinSta = IntGetWinStaObj();
-    if (WinSta == NULL)
-    {
-        RETURN(FALSE);
+        goto leave;
     }
 
     if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
     {
-        ObDereferenceObject(WinSta);
-        RETURN(FALSE);
+        goto leave;
     }
 
     RtlCopyMemory(&ii, &CurIcon->IconInfo, sizeof(ICONINFO));
@@ -638,6 +530,18 @@ NtUserGetIconInfo(
     ii.hbmMask = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmMask);
     ii.hbmColor = BITMAP_CopyBitmap(CurIcon->IconInfo.hbmColor);
 
+    if (pbpp)
+    {
+        PSURFACE psurfBmp;
+
+        psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmColor);
+        if (psurfBmp)
+        {
+            colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
+            SURFACE_UnlockSurface(psurfBmp);
+        }
+    }
+
     /* Copy fields */
     _SEH2_TRY
     {
@@ -646,21 +550,9 @@ NtUserGetIconInfo(
 
         if (pbpp)
         {
-            PSURFACE psurfBmp;
-            int colorBpp = 0;
-
             ProbeForWrite(pbpp, sizeof(DWORD), 1);
-
-            psurfBmp = SURFACE_LockSurface(CurIcon->IconInfo.hbmColor);
-            if (psurfBmp)
-            {
-                colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
-                SURFACE_UnlockSurface(psurfBmp);
-            }
-
-            RtlCopyMemory(pbpp, &colorBpp, sizeof(DWORD));
+            *pbpp = colorBpp;
         }
-
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
@@ -674,13 +566,12 @@ NtUserGetIconInfo(
         SetLastNtError(Status);
 
     UserDereferenceObject(CurIcon);
-    ObDereferenceObject(WinSta);
-    RETURN(Ret);
 
-CLEANUP:
-    DPRINT("Leave NtUserGetIconInfo, ret=%i\n",_ret_);
+leave:
+    DPRINT("Leave NtUserGetIconInfo, ret=%i\n", Ret);
     UserLeave();
-    END_CLEANUP;
+
+    return Ret;
 }
 
 
@@ -761,7 +652,6 @@ NtUserGetCursorInfo(
 {
     CURSORINFO SafeCi;
     PSYSTEM_CURSORINFO CurInfo;
-    PWINSTATION_OBJECT WinSta;
     NTSTATUS Status = STATUS_SUCCESS;
     PCURICON_OBJECT CurIcon;
     BOOL Ret = FALSE;
@@ -770,20 +660,14 @@ NtUserGetCursorInfo(
     DPRINT("Enter NtUserGetCursorInfo\n");
     UserEnterExclusive();
 
-    WinSta = IntGetWinStaObj();
-    if (WinSta == NULL)
-    {
-        RETURN(FALSE);
-    }
-
-    CurInfo = IntGetSysCursorInfo(WinSta);
+    CurInfo = IntGetSysCursorInfo();
     CurIcon = (PCURICON_OBJECT)CurInfo->CurrentCursorObject;
 
     SafeCi.cbSize = sizeof(CURSORINFO);
     SafeCi.flags = ((CurInfo->ShowingCursor && CurIcon) ? CURSOR_SHOWING : 0);
     SafeCi.hCursor = (CurIcon ? (HCURSOR)CurIcon->Self : (HCURSOR)0);
 
-    IntGetCursorLocation(WinSta, &SafeCi.ptScreenPos);
+    SafeCi.ptScreenPos = gpsi->ptCursor;
 
     _SEH2_TRY
     {
@@ -808,7 +692,6 @@ NtUserGetCursorInfo(
         SetLastNtError(Status);
     }
 
-    ObDereferenceObject(WinSta);
     RETURN(Ret);
 
 CLEANUP:
@@ -827,61 +710,40 @@ NtUserClipCursor(
     RECTL *UnsafeRect)
 {
     /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
-
-    PWINSTATION_OBJECT WinSta;
     PSYSTEM_CURSORINFO CurInfo;
     RECTL Rect;
     PWINDOW_OBJECT DesktopWindow = NULL;
-    POINT MousePos = {0};
     DECLARE_RETURN(BOOL);
 
     DPRINT("Enter NtUserClipCursor\n");
     UserEnterExclusive();
 
-    WinSta = IntGetWinStaObj();
-    if (WinSta == NULL)
-    {
-        RETURN(FALSE);
-    }
-
     if (NULL != UnsafeRect && ! NT_SUCCESS(MmCopyFromCaller(&Rect, UnsafeRect, sizeof(RECT))))
     {
-        ObDereferenceObject(WinSta);
         SetLastWin32Error(ERROR_INVALID_PARAMETER);
         RETURN(FALSE);
     }
 
-    CurInfo = IntGetSysCursorInfo(WinSta);
-    IntGetCursorLocation(WinSta, &MousePos);
+    CurInfo = IntGetSysCursorInfo();
 
-    if (WinSta->ActiveDesktop)
-        DesktopWindow = UserGetWindowObject(WinSta->ActiveDesktop->DesktopWindow);
+    DesktopWindow = UserGetDesktopWindow();
 
     if ((Rect.right > Rect.left) && (Rect.bottom > Rect.top)
             && DesktopWindow && UnsafeRect != NULL)
     {
-        MOUSEINPUT mi;
 
         CurInfo->CursorClipInfo.IsClipped = TRUE;
         CurInfo->CursorClipInfo.Left = max(Rect.left, DesktopWindow->Wnd->rcWindow.left);
         CurInfo->CursorClipInfo.Top = max(Rect.top, DesktopWindow->Wnd->rcWindow.top);
-        CurInfo->CursorClipInfo.Right = min(Rect.right - 1, DesktopWindow->Wnd->rcWindow.right - 1);
-        CurInfo->CursorClipInfo.Bottom = min(Rect.bottom - 1, DesktopWindow->Wnd->rcWindow.bottom - 1);
+        CurInfo->CursorClipInfo.Right = min(Rect.right, DesktopWindow->Wnd->rcWindow.right);
+        CurInfo->CursorClipInfo.Bottom = min(Rect.bottom, DesktopWindow->Wnd->rcWindow.bottom);
 
-        mi.dx = MousePos.x;
-        mi.dy = MousePos.y;
-        mi.mouseData = 0;
-        mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
-        mi.time = 0;
-        mi.dwExtraInfo = 0;
-        IntMouseInput(&mi);
+        UserSetCursorPos(gpsi->ptCursor.x, gpsi->ptCursor.y, FALSE);
 
         RETURN(TRUE);
     }
 
     CurInfo->CursorClipInfo.IsClipped = FALSE;
-    ObDereferenceObject(WinSta);
-
     RETURN(TRUE);
 
 CLEANUP:
@@ -900,7 +762,6 @@ NtUserDestroyCursor(
     HANDLE hCurIcon,
     DWORD Unknown)
 {
-    PWINSTATION_OBJECT WinSta;
     PCURICON_OBJECT CurIcon;
     BOOL ret;
     DECLARE_RETURN(BOOL);
@@ -908,22 +769,14 @@ NtUserDestroyCursor(
     DPRINT("Enter NtUserDestroyCursorIcon\n");
     UserEnterExclusive();
 
-    WinSta = IntGetWinStaObj();
-    if (WinSta == NULL)
-    {
-        RETURN(FALSE);
-    }
-
     if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
     {
-        ObDereferenceObject(WinSta);
         RETURN(FALSE);
     }
 
-    ret = IntDestroyCurIconObject(WinSta, CurIcon, FALSE);
+    ret = IntDestroyCurIconObject(CurIcon, FALSE);
     /* Note: IntDestroyCurIconObject will remove our reference for us! */
 
-    ObDereferenceObject(WinSta);
     RETURN(ret);
 
 CLEANUP:
@@ -945,31 +798,22 @@ NtUserFindExistingCursorIcon(
     LONG cy)
 {
     PCURICON_OBJECT CurIcon;
-    PWINSTATION_OBJECT WinSta;
     HANDLE Ret = (HANDLE)0;
     DECLARE_RETURN(HICON);
 
     DPRINT("Enter NtUserFindExistingCursorIcon\n");
     UserEnterExclusive();
 
-    WinSta = IntGetWinStaObj();
-    if (WinSta == NULL)
-    {
-        RETURN(Ret);
-    }
-
-    CurIcon = IntFindExistingCurIconObject(WinSta, hModule, hRsrc, cx, cy);
+    CurIcon = IntFindExistingCurIconObject(hModule, hRsrc, cx, cy);
     if (CurIcon)
     {
         Ret = CurIcon->Self;
 
 //      IntReleaseCurIconObject(CurIcon);//faxme: is this correct? does IntFindExistingCurIconObject add a ref?
-        ObDereferenceObject(WinSta);
         RETURN(Ret);
     }
 
     SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
-    ObDereferenceObject(WinSta);
     RETURN((HANDLE)0);
 
 CLEANUP:
@@ -989,7 +833,6 @@ NtUserGetClipCursor(
 {
     /* FIXME - check if process has WINSTA_READATTRIBUTES */
     PSYSTEM_CURSORINFO CurInfo;
-    PWINSTATION_OBJECT WinSta;
     RECTL Rect;
     NTSTATUS Status;
     DECLARE_RETURN(BOOL);
@@ -1000,13 +843,7 @@ NtUserGetClipCursor(
     if (!lpRect)
         RETURN(FALSE);
 
-    WinSta = IntGetWinStaObj();
-    if (WinSta == NULL)
-    {
-        RETURN(FALSE);
-    }
-
-    CurInfo = IntGetSysCursorInfo(WinSta);
+    CurInfo = IntGetSysCursorInfo();
     if (CurInfo->CursorClipInfo.IsClipped)
     {
         Rect.left = CurInfo->CursorClipInfo.Left;
@@ -1025,13 +862,10 @@ NtUserGetClipCursor(
     Status = MmCopyToCaller(lpRect, &Rect, sizeof(RECT));
     if (!NT_SUCCESS(Status))
     {
-        ObDereferenceObject(WinSta);
         SetLastNtError(Status);
         RETURN(FALSE);
     }
 
-    ObDereferenceObject(WinSta);
-
     RETURN(TRUE);
 
 CLEANUP:
@@ -1051,23 +885,15 @@ NtUserSetCursor(
 {
     PCURICON_OBJECT CurIcon;
     HICON OldCursor;
-    PWINSTATION_OBJECT WinSta;
     DECLARE_RETURN(HCURSOR);
 
     DPRINT("Enter NtUserSetCursor\n");
     UserEnterExclusive();
 
-    WinSta = IntGetWinStaObj();
-    if (WinSta == NULL)
-    {
-        RETURN(NULL);
-    }
-
     if (hCursor)
     {
         if (!(CurIcon = UserGetCurIconObject(hCursor)))
         {
-            ObDereferenceObject(WinSta);
             RETURN(NULL);
         }
     }
@@ -1076,13 +902,12 @@ NtUserSetCursor(
         CurIcon = NULL;
     }
 
-    OldCursor = IntSetCursor(WinSta, CurIcon, FALSE);
+    OldCursor = UserSetCursor(CurIcon, FALSE);
 
     if (CurIcon)
     {
         UserDereferenceObject(CurIcon);
     }
-    ObDereferenceObject(WinSta);
 
     RETURN(OldCursor);
 
@@ -1105,7 +930,6 @@ NtUserSetCursorContents(
     PCURICON_OBJECT CurIcon;
     ICONINFO IconInfo;
     PSURFACE psurfBmp;
-    PWINSTATION_OBJECT WinSta;
     NTSTATUS Status;
     BOOL Ret = FALSE;
     DECLARE_RETURN(BOOL);
@@ -1113,15 +937,8 @@ NtUserSetCursorContents(
     DPRINT("Enter NtUserSetCursorContents\n");
     UserEnterExclusive();
 
-    WinSta = IntGetWinStaObj();
-    if (WinSta == NULL)
-    {
-        RETURN(FALSE);
-    }
-
     if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
     {
-        ObDereferenceObject(WinSta);
         RETURN(FALSE);
     }
 
@@ -1134,11 +951,13 @@ NtUserSetCursorContents(
     }
 
     /* Delete old bitmaps */
-    if (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor)
+    if ((CurIcon->IconInfo.hbmColor)
+               && (CurIcon->IconInfo.hbmColor != IconInfo.hbmColor))
     {
         GreDeleteObject(CurIcon->IconInfo.hbmColor);
     }
-    if (CurIcon->IconInfo.hbmMask != IconInfo.hbmMask)
+    if ((CurIcon->IconInfo.hbmMask)
+               && (CurIcon->IconInfo.hbmMask != IconInfo.hbmMask))
     {
         GreDeleteObject(CurIcon->IconInfo.hbmMask);
     }
@@ -1175,7 +994,6 @@ done:
     {
         UserDereferenceObject(CurIcon);
     }
-    ObDereferenceObject(WinSta);
     RETURN(Ret);
 
 CLEANUP:
@@ -1198,7 +1016,6 @@ NtUserSetCursorIconData(
     PICONINFO pIconInfo)
 {
     PCURICON_OBJECT CurIcon;
-    PWINSTATION_OBJECT WinSta;
     PSURFACE psurfBmp;
     NTSTATUS Status = STATUS_SUCCESS;
     BOOL Ret = FALSE;
@@ -1207,15 +1024,8 @@ NtUserSetCursorIconData(
     DPRINT("Enter NtUserSetCursorIconData\n");
     UserEnterExclusive();
 
-    WinSta = IntGetWinStaObj();
-    if (WinSta == NULL)
-    {
-        RETURN(FALSE);
-    }
-
     if (!(CurIcon = UserGetCurIconObject(Handle)))
     {
-        ObDereferenceObject(WinSta);
         RETURN(FALSE);
     }
 
@@ -1267,7 +1077,6 @@ NtUserSetCursorIconData(
         Ret = TRUE;
 
     UserDereferenceObject(CurIcon);
-    ObDereferenceObject(WinSta);
     RETURN(Ret);
 
 CLEANUP:
@@ -1287,7 +1096,6 @@ NtUserSetCursorIconData(
     HRSRC hGroupRsrc)
 {
     PCURICON_OBJECT CurIcon;
-    PWINSTATION_OBJECT WinSta;
     NTSTATUS Status;
     POINT SafeHotspot;
     BOOL Ret = FALSE;
@@ -1296,15 +1104,8 @@ NtUserSetCursorIconData(
     DPRINT("Enter NtUserSetCursorIconData\n");
     UserEnterExclusive();
 
-    WinSta = IntGetWinStaObj();
-    if (WinSta == NULL)
-    {
-        RETURN(FALSE);
-    }
-
     if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
     {
-        ObDereferenceObject(WinSta);
         RETURN(FALSE);
     }
 
@@ -1348,8 +1149,16 @@ NtUserSetCursorIconData(
     }
 
 done:
+       if(Ret)
+       {
+               /* This icon is shared now */
+               GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmMask, NULL);
+               if(CurIcon->IconInfo.hbmColor)
+               {
+                       GDIOBJ_SetOwnership(CurIcon->IconInfo.hbmColor, NULL);
+               }
+       }
     UserDereferenceObject(CurIcon);
-    ObDereferenceObject(WinSta);
     RETURN(Ret);
 
 
@@ -1576,13 +1385,14 @@ UserDrawIconEx(
                           cyHeight,
                           hdcImage ? hdcImage : hdcMask,
                           0,
-                          ((diFlags & DI_MASK && !(diFlags & DI_IMAGE)) ||
-                           (diFlags & DI_IMAGE && hbmColor) ? 0 : IconSize.cy),
+                          0,
                           IconSize.cx,
                           IconSize.cy,
                           SRCCOPY,
                           0,
-                          hdcImage ? hdcMask : NULL);
+                                                 bAlpha ? 0 : hdcMask,
+                          0,
+                          hdcImage ? 0 : IconSize.cy);
     }
 
     if (hOldMask) NtGdiSelectBitmap(hdcMask, hOldMask);
@@ -1688,8 +1498,8 @@ NtUserDrawIconEx(
     UINT istepIfAniCur,
     HBRUSH hbrFlickerFreeDraw,
     UINT diFlags,
-    DWORD Unknown0,
-    DWORD Unknown1)
+    BOOL bMetaHDC, // When TRUE, GDI functions need to be handled in User32!
+    PVOID pDIXData)
 {
     PCURICON_OBJECT pIcon;
     BOOL Ret;
@@ -1720,92 +1530,3 @@ NtUserDrawIconEx(
     return Ret;
 }
 
-/* Called from NtUserCallOneParam with Routine ONEPARAM_ROUTINE_SHOWCURSOR
- * User32 macro NtUserShowCursor */
-int
-APIENTRY
-UserShowCursor(BOOL bShow)
-{
-    PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
-    PWINSTATION_OBJECT WinSta = pti->Desktop->WindowStation;
-    PSYSTEM_CURSORINFO CurInfo;
-
-    HDC Screen;
-    PDC dc;
-    SURFOBJ *SurfObj;
-    SURFACE *psurfDc;
-    PDEVOBJ *ppdev;
-    GDIPOINTER *pgp;
-    int showpointer=0;
-
-    if (!(Screen = IntGetScreenDC()))
-    {
-        return showpointer; /* No mouse */
-    }
-
-    dc = DC_LockDc(Screen);
-
-    if (!dc)
-    {
-        return showpointer; /* No mouse */
-    }
-
-    psurfDc = dc->dclevel.pSurface;
-
-    if (!psurfDc)
-    {
-        DC_UnlockDc(dc);
-        return showpointer; /* No Mouse */
-    }
-
-    SurfObj = &psurfDc->SurfObj;
-    if (SurfObj == NULL)
-    {
-        DC_UnlockDc(dc);
-        return showpointer; /* No mouse */
-    }
-
-    ppdev = GDIDEV(SurfObj);
-
-    if (ppdev == NULL)
-    {
-        DC_UnlockDc(dc);
-        return showpointer; /* No mouse */
-    }
-
-    pgp = &ppdev->Pointer;
-
-    CurInfo = IntGetSysCursorInfo(WinSta);
-
-    if (bShow == FALSE)
-    {
-        pgp->ShowPointer--;
-        showpointer = pgp->ShowPointer;
-
-        if (showpointer >= 0)
-        {
-            //ppdev->SafetyRemoveCount = 1;
-            //ppdev->SafetyRemoveLevel = 1;
-            IntEngMovePointer(SurfObj,-1,-1,NULL);
-            CurInfo->ShowingCursor = 0;
-        }
-
-    }
-    else
-    {
-        pgp->ShowPointer++;
-        showpointer = pgp->ShowPointer;
-
-        /* Show Cursor */
-        if (showpointer < 0)
-        {
-            //ppdev->SafetyRemoveCount = 0;
-            //ppdev->SafetyRemoveLevel = 0;
-            IntEngMovePointer(SurfObj,-1,-1,NULL);
-            CurInfo->ShowingCursor = CURSOR_SHOWING;
-        }
-    }
-
-    DC_UnlockDc(dc);
-    return showpointer;
-}