[ros-diffs] [rharabien] 52136: - Add ShowingCursor counter and CursorObject to message queue and use them when moving mouse. They are not globally in Windows.

rharabien at svn.reactos.org rharabien at svn.reactos.org
Tue Jun 7 20:12:56 UTC 2011


Author: rharabien
Date: Tue Jun  7 20:12:56 2011
New Revision: 52136

URL: http://svn.reactos.org/svn/reactos?rev=52136&view=rev
Log:
- Add ShowingCursor counter and CursorObject to message queue and use them when moving mouse. They are not globally in Windows.

Modified:
    trunk/reactos/subsystems/win32/win32k/include/cursoricon.h
    trunk/reactos/subsystems/win32/win32k/include/msgqueue.h
    trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
    trunk/reactos/subsystems/win32/win32k/ntuser/display.c
    trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c

Modified: trunk/reactos/subsystems/win32/win32k/include/cursoricon.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/cursoricon.h?rev=52136&r1=52135&r2=52136&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/cursoricon.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/cursoricon.h [iso-8859-1] Tue Jun  7 20:12:56 2011
@@ -71,8 +71,6 @@
 
 BOOL UserSetCursorPos( INT x, INT y, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook);
 
-int UserShowCursor(BOOL bShow);
-
 PSYSTEM_CURSORINFO IntGetSysCursorInfo(VOID);
 
 #define IntReleaseCurIconObject(CurIconObj) \

Modified: trunk/reactos/subsystems/win32/win32k/include/msgqueue.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/msgqueue.h?rev=52136&r1=52135&r2=52136&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] Tue Jun  7 20:12:56 2011
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "hook.h"
+#include "cursoricon.h"
 
 #define MSQ_HUNG        5000
 #define MSQ_NORMAL      0
@@ -59,8 +60,6 @@
   LIST_ENTRY PostedMessagesListHead;
   /* Queue for hardware messages for the queue. */
   LIST_ENTRY HardwareMessagesListHead;
-  /* Lock for the hardware message list. */
-  KMUTEX HardwareLock;
   /* True if a WM_MOUSEMOVE is pending */
   BOOLEAN MouseMoved;
   /* Current WM_MOUSEMOVE message */
@@ -111,6 +110,11 @@
   /* state of each key */
   UCHAR KeyState[256];
 
+  /* showing cursor counter (value>=0 - cursor visible, value<0 - cursor hidden) */
+  INT ShowingCursor;
+  /* cursor object */
+  PCURICON_OBJECT CursorObject;
+
   /* messages that are currently dispatched by other threads */
   LIST_ENTRY DispatchingMessagesHead;
   /* messages that are currently dispatched by this message queue, required for cleanup */
@@ -322,4 +326,10 @@
 VOID FASTCALL MsqWakeQueue(PUSER_MESSAGE_QUEUE,DWORD,BOOL);
 VOID FASTCALL ClearMsgBitsMask(PUSER_MESSAGE_QUEUE,UINT);
 
+int UserShowCursor(BOOL bShow);
+PCURICON_OBJECT
+FASTCALL
+UserSetCursor(PCURICON_OBJECT NewCursor,
+              BOOL ForceChange);
+
 /* EOF */

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c?rev=52136&r1=52135&r2=52136&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] Tue Jun  7 20:12:56 2011
@@ -99,79 +99,13 @@
     return CurIcon;
 }
 
-PCURICON_OBJECT
-FASTCALL
-UserSetCursor(
-    PCURICON_OBJECT NewCursor,
-    BOOL ForceChange)
-{
-    PSYSTEM_CURSORINFO CurInfo;
-    PCURICON_OBJECT OldCursor;
-    HDC hdcScreen;
-
-	CurInfo = IntGetSysCursorInfo();
-
-    OldCursor = CurInfo->CurrentCursorObject;
-
-    /* Is the new cursor the same as the old cursor? */
-    if (OldCursor == NewCursor)
-    {
-        /* Nothing to to do in this case */
-        return OldCursor;
-    }
-
-    /* Get the screen DC */
-    if(!(hdcScreen = IntGetScreenDC()))
-    {
-        return (HCURSOR)0;
-    }
-
-    /* Do we have a new cursor? */
-    if (NewCursor)
-    {
-        CurInfo->ShowingCursor = 0;
-        CurInfo->CurrentCursorObject = NewCursor;
-
-        /* Call GDI to set the new screen cursor */
-        GreSetPointerShape(hdcScreen,
-                           NewCursor->IconInfo.hbmMask,
-                           NewCursor->IconInfo.hbmColor,
-                           NewCursor->IconInfo.xHotspot,
-                           NewCursor->IconInfo.yHotspot,
-                           gpsi->ptCursor.x,
-                           gpsi->ptCursor.y);
-    }
-    else
-    {
-        /* Check if were diplaying a cursor */
-        if (OldCursor && CurInfo->ShowingCursor >= 0)
-        {
-            /* Remove the cursor */
-            GreMovePointer(hdcScreen, -1, -1);
-            DPRINT("Removing pointer!\n");
-        }
-
-        CurInfo->CurrentCursorObject = NULL;
-        CurInfo->ShowingCursor = -1;
-    }
-
-    /* Return the old cursor */
-    return OldCursor;
-}
-
 BOOL UserSetCursorPos( INT x, INT y, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook)
 {
     PWND DesktopWindow;
     PSYSTEM_CURSORINFO CurInfo;
-    HDC hDC;
     MSG Msg;
     RECTL rcClip;
     POINT pt;
-
-    if(!(hDC = IntGetScreenDC()))
-    {
-        return FALSE;
-    }
 
     if(!(DesktopWindow = UserGetDesktopWindow()))
     {
@@ -194,56 +128,17 @@
     pt.x = x;
     pt.y = y;
 
-    /* 3. Generate a mouse move message, this sets the htEx and Track Window too. */
+    /* 1. Generate a mouse move message, this sets the htEx and Track Window too. */
     Msg.message = WM_MOUSEMOVE;
     Msg.wParam = CurInfo->ButtonsDown;
     Msg.lParam = MAKELPARAM(x, y);
     Msg.pt = pt;
     co_MsqInsertMouseMessage(&Msg, flags, dwExtraInfo, Hook);
 
-    /* 1. Store the new cursor position */
+    /* 2. Store the new cursor position */
     gpsi->ptCursor = pt;
 
-    /* 2. Move the mouse pointer */
-    GreMovePointer(hDC, x, y);
-
     return TRUE;
-}
-
-/* Called from NtUserCallOneParam with Routine ONEPARAM_ROUTINE_SHOWCURSOR
- * User32 macro NtUserShowCursor */
-int UserShowCursor(BOOL bShow)
-{
-    PSYSTEM_CURSORINFO CurInfo = IntGetSysCursorInfo();
-    HDC hdcScreen;
-
-    if (!(hdcScreen = IntGetScreenDC()))
-    {
-        return -1; /* No mouse */
-    }
-
-    if (bShow == FALSE)
-    {
-        /* Check if were diplaying a cursor */
-        if (CurInfo->ShowingCursor == 0)
-        {
-            /* Remove the pointer */
-            GreMovePointer(hdcScreen, -1, -1);
-            DPRINT("Removing pointer!\n");
-        }
-        CurInfo->ShowingCursor--;
-    }
-    else
-    {
-        if (CurInfo->ShowingCursor == -1)
-        {
-            /*Show the pointer*/
-            GreMovePointer(hdcScreen, gpsi->ptCursor.x, gpsi->ptCursor.y);
-        }
-        CurInfo->ShowingCursor++;
-    }
-
-    return CurInfo->ShowingCursor;
 }
 
 /*

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/display.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/display.c?rev=52136&r1=52135&r2=52136&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/display.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/display.c [iso-8859-1] Tue Jun  7 20:12:56 2011
@@ -634,7 +634,6 @@
 
 BOOL APIENTRY UserClipCursor(RECTL *prcl);
 VOID APIENTRY UserRedrawDesktop();
-HCURSOR FASTCALL UserSetCursor(PCURICON_OBJECT NewCursor, BOOL ForceChange);
 
 LONG
 APIENTRY

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c?rev=52136&r1=52135&r2=52136&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] Tue Jun  7 20:12:56 2011
@@ -41,6 +41,151 @@
                                   256);
 
    return(STATUS_SUCCESS);
+}
+
+PWND FASTCALL
+IntTopLevelWindowFromPoint(INT x, INT y)
+{
+    PWND pWnd, pwndDesktop;
+
+    /* Get the desktop window */
+    pwndDesktop = UserGetDesktopWindow();
+    if (!pwndDesktop)
+        return NULL;
+
+    /* Loop all top level windows */
+    for (pWnd = pwndDesktop->spwndChild;
+         pWnd != NULL;
+         pWnd = pWnd->spwndNext)
+    {
+        if (pWnd->state2 & WNDS2_INDESTROY || pWnd->state & WNDS_DESTROYED)
+        {
+            DPRINT("The Window is in DESTROY!\n");
+            continue;
+        }
+
+        if ((pWnd->style & WS_VISIBLE) && IntPtInWindow(pWnd, x, y))
+            return pWnd;
+    }
+    
+    /* Window has not been found */
+    return NULL;
+}
+
+PCURICON_OBJECT
+FASTCALL
+UserSetCursor(
+    PCURICON_OBJECT NewCursor,
+    BOOL ForceChange)
+{
+    PCURICON_OBJECT OldCursor;
+    HDC hdcScreen;
+    PTHREADINFO pti;
+    PUSER_MESSAGE_QUEUE MessageQueue;
+    PWND pWnd;
+
+    pti = PsGetCurrentThreadWin32Thread();
+    MessageQueue = pti->MessageQueue;
+
+    /* Get the screen DC */
+    if(!(hdcScreen = IntGetScreenDC()))
+    {
+        return (HCURSOR)0;
+    }
+
+    OldCursor = MessageQueue->CursorObject;
+
+    /* Check if cursors are different */
+    if (OldCursor == NewCursor)
+        return OldCursor;
+
+    /* Update cursor for this message queue */
+    MessageQueue->CursorObject = NewCursor;
+
+    /* If cursor is not visible we have nothing to do */
+    if (MessageQueue->ShowingCursor < 0)
+        return OldCursor;
+
+    /* Update cursor if this message queue controls it */
+    pWnd = IntTopLevelWindowFromPoint(gpsi->ptCursor.x, gpsi->ptCursor.y);
+    if (pWnd && pWnd->head.pti->MessageQueue == MessageQueue)
+    {
+        if (NewCursor)
+        {
+            /* Call GDI to set the new screen cursor */
+            GreSetPointerShape(hdcScreen,
+                               NewCursor->IconInfo.hbmMask,
+                               NewCursor->IconInfo.hbmColor,
+                               NewCursor->IconInfo.xHotspot,
+                               NewCursor->IconInfo.yHotspot,
+                               gpsi->ptCursor.x,
+                               gpsi->ptCursor.y);
+        }
+        else /* Note: OldCursor != NewCursor so we have to hide cursor */
+        {
+            /* Remove the cursor */
+            GreMovePointer(hdcScreen, -1, -1);
+            DPRINT1("Removing pointer!\n");
+            DbgBreakPoint();
+        }
+        IntGetSysCursorInfo()->CurrentCursorObject = NewCursor;
+    }
+
+    /* Return the old cursor */
+    return OldCursor;
+}
+
+/* Called from NtUserCallOneParam with Routine ONEPARAM_ROUTINE_SHOWCURSOR
+ * User32 macro NtUserShowCursor */
+int UserShowCursor(BOOL bShow)
+{
+    HDC hdcScreen;
+    PTHREADINFO pti;
+    PUSER_MESSAGE_QUEUE MessageQueue;
+    PWND pWnd;
+
+    if (!(hdcScreen = IntGetScreenDC()))
+    {
+        return -1; /* No mouse */
+    }
+
+    pti = PsGetCurrentThreadWin32Thread();
+    MessageQueue = pti->MessageQueue;
+    
+    /* Update counter */
+    MessageQueue->ShowingCursor += bShow ? 1 : -1;
+    
+    /* Check for trivial cases */
+    if ((bShow && MessageQueue->ShowingCursor != 0) ||
+        (!bShow && MessageQueue->ShowingCursor != -1))
+    {
+        /* Note: w don't update global info here because it is used only
+          internally to check if cursor is visible */
+        return MessageQueue->ShowingCursor;
+    }
+    
+    /* Check if cursor is above window owned by this MessageQueue */
+    pWnd = IntTopLevelWindowFromPoint(gpsi->ptCursor.x, gpsi->ptCursor.y);
+    if (pWnd && pWnd->head.pti->MessageQueue == MessageQueue)
+    {
+        if (bShow)
+        {
+            /* Show the pointer */
+            GreMovePointer(hdcScreen, gpsi->ptCursor.x, gpsi->ptCursor.y);
+            DPRINT1("Showing pointer!\n");
+        }
+        else
+        {
+            /* Remove the pointer */
+            GreMovePointer(hdcScreen, -1, -1);
+            DPRINT1("Removing pointer!\n");
+        }
+        
+        /* Update global info */
+        IntGetSysCursorInfo()->ShowingCursor = MessageQueue->ShowingCursor;
+    }
+
+    return MessageQueue->ShowingCursor;
 }
 
 DWORD FASTCALL UserGetKeyState(DWORD key)
@@ -307,13 +452,15 @@
    MSLLHOOKSTRUCT MouseHookData;
    PDESKTOP pDesk;
    PWND pwnd, pwndDesktop;
+   HDC hdcScreen;
+   PSYSTEM_CURSORINFO CurInfo;
 
    KeQueryTickCount(&LargeTickCount);
    Msg->time = MsqCalculateMessageTime(&LargeTickCount);
 
    MouseHookData.pt.x = LOWORD(Msg->lParam);
    MouseHookData.pt.y = HIWORD(Msg->lParam);
-   switch(Msg->message)
+   switch (Msg->message)
    {
       case WM_MOUSEWHEEL:
          MouseHookData.mouseData = MAKELONG(0, GET_WHEEL_DELTA_WPARAM(Msg->wParam));
@@ -344,7 +491,7 @@
 
    /* Get the desktop window */
    pwndDesktop = UserGetDesktopWindow();
-   if(!pwndDesktop)
+   if (!pwndDesktop)
        return;
 
    /* Set hit somewhere on the desktop */
@@ -354,7 +501,7 @@
 
    /* Check if the mouse is captured */
    Msg->hwnd = IntGetCaptureWindow();
-   if(Msg->hwnd != NULL)
+   if (Msg->hwnd != NULL)
    {
        pwnd = UserGetWindowObject(Msg->hwnd);
        if ((pwnd->style & WS_VISIBLE) &&
@@ -366,41 +513,66 @@
    }
    else
    {
-       /* Loop all top level windows to find which one should receive input */
-       for( pwnd = pwndDesktop->spwndChild;
-            pwnd != NULL;
-            pwnd = pwnd->spwndNext )
+       pwnd = IntTopLevelWindowFromPoint(Msg->pt.x, Msg->pt.y);
+       if (pwnd)
        {
-           if ( pwnd->state2 & WNDS2_INDESTROY || pwnd->state & WNDS_DESTROYED )
+           Msg->hwnd = pwnd->head.h;
+           pDesk->htEx = HTCLIENT;
+           pDesk->spwndTrack = pwnd;
+       }
+   }
+
+   hdcScreen = IntGetScreenDC();
+   CurInfo = IntGetSysCursorInfo();
+
+   /* Check if we found a window */
+   if (Msg->hwnd != NULL && pwnd != NULL)
+   {
+       if (Msg->message == WM_MOUSEMOVE)
+       {
+           PUSER_MESSAGE_QUEUE MessageQueue = pwnd->head.pti->MessageQueue;
+
+           /* Check if cursor should be visible */
+           if(hdcScreen &&
+              MessageQueue->CursorObject &&
+              MessageQueue->ShowingCursor >= 0)
            {
-              DPRINT("The Window is in DESTROY!\n");
-              continue;
+               /* Check if shape has changed */
+               if(CurInfo->CurrentCursorObject != MessageQueue->CursorObject)
+               {
+                   /* Call GDI to set the new screen cursor */
+                   GreSetPointerShape(hdcScreen,
+                                      MessageQueue->CursorObject->IconInfo.hbmMask,
+                                      MessageQueue->CursorObject->IconInfo.hbmColor,
+                                      MessageQueue->CursorObject->IconInfo.xHotspot,
+                                      MessageQueue->CursorObject->IconInfo.yHotspot,
+                                      gpsi->ptCursor.x,
+                                      gpsi->ptCursor.y);
+               } else
+                   GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y);
            }
-
-           if((pwnd->style & WS_VISIBLE) &&
-              IntPtInWindow(pwnd, Msg->pt.x, Msg->pt.y))
-           {
-               Msg->hwnd = pwnd->head.h;
-               pDesk->htEx = HTCLIENT;
-               pDesk->spwndTrack = pwnd;
-               break;
-           }
-       }
-   }
-
-   /* Check if we found a window */
-   if(Msg->hwnd != NULL && pwnd != NULL)
-   {
-       if(Msg->message == WM_MOUSEMOVE)
-       {
-           /* Mouse move is a special case*/
-           MsqPostMouseMove(pwnd->head.pti->MessageQueue, Msg);
+           /* Check if w have to hide cursor */
+           else if (CurInfo->ShowingCursor >= 0)
+               GreMovePointer(hdcScreen, -1, -1);
+
+           /* Update global cursor info */
+           CurInfo->ShowingCursor = MessageQueue->ShowingCursor;
+           CurInfo->CurrentCursorObject = MessageQueue->CursorObject;
+
+           /* Mouse move is a special case */
+           MsqPostMouseMove(MessageQueue, Msg);
        }
        else
        {
            DPRINT("Posting mouse message to hwnd=0x%x!\n", UserHMGetHandle(pwnd));
            MsqPostMessage(pwnd->head.pti->MessageQueue, Msg, TRUE, QS_MOUSEBUTTON);
        }
+   }
+   else if (hdcScreen)
+   {
+       /* always show cursor on background; FIXME: set default pointer */
+       GreMovePointer(hdcScreen, Msg->pt.x, Msg->pt.y);
+       CurInfo->ShowingCursor = 0;
    }
 
    /* Do GetMouseMovePointsEx FIFO. */
@@ -1601,13 +1773,14 @@
    InitializeListHead(&MessageQueue->HardwareMessagesListHead);
    InitializeListHead(&MessageQueue->DispatchingMessagesHead);
    InitializeListHead(&MessageQueue->LocalDispatchingMessagesHead);
-   KeInitializeMutex(&MessageQueue->HardwareLock, 0);
    MessageQueue->QuitPosted = FALSE;
    MessageQueue->QuitExitCode = 0;
    KeQueryTickCount(&LargeTickCount);
    MessageQueue->LastMsgRead = LargeTickCount.u.LowPart;
    MessageQueue->FocusWindow = NULL;
    MessageQueue->NewMessagesHandle = NULL;
+   MessageQueue->ShowingCursor = 0;
+   MessageQueue->CursorObject = NULL;
 
    Status = ZwCreateEvent(&MessageQueue->NewMessagesHandle, EVENT_ALL_ACCESS,
                           NULL, SynchronizationEvent, FALSE);
@@ -1763,6 +1936,18 @@
    MessageQueue->nCntsQBits[QSRosPostMessage] = 0;
    MessageQueue->nCntsQBits[QSRosSendMessage] = 0;
    MessageQueue->nCntsQBits[QSRosHotKey] = 0;
+   
+   if (MessageQueue->CursorObject)
+   {
+       PCURICON_OBJECT pCursor = MessageQueue->CursorObject;
+
+       /* Change to another cursor if we going to dereference current one */
+       if (IntGetSysCursorInfo()->CurrentCursorObject == pCursor)
+           UserSetCursor(NULL, TRUE);
+
+       UserDereferenceObject(pCursor);
+   }
+      
 }
 
 PUSER_MESSAGE_QUEUE FASTCALL
@@ -1989,5 +2174,4 @@
    return ret;
 }
 
-
 /* EOF */




More information about the Ros-diffs mailing list