[Win32SS]
authorJames Tabor <james.tabor@reactos.org>
Thu, 7 Jun 2012 12:05:17 +0000 (12:05 +0000)
committerJames Tabor <james.tabor@reactos.org>
Thu, 7 Jun 2012 12:05:17 +0000 (12:05 +0000)
- Fix crash and pass all wine CursorIcon test_SetCursor and test_ShowCursor.

svn path=/trunk/; revision=56707

reactos/win32ss/include/ntuser.h
reactos/win32ss/user/ntuser/input.c
reactos/win32ss/user/ntuser/main.c
reactos/win32ss/user/ntuser/misc.c
reactos/win32ss/user/ntuser/msgqueue.c
reactos/win32ss/user/ntuser/msgqueue.h
reactos/win32ss/user/ntuser/win32.h
reactos/win32ss/user/user32/windows/cursoricon.c

index 91abf8f..b0f8732 100644 (file)
@@ -2184,7 +2184,8 @@ enum ThreadStateRoutines
     THREADSTATE_GETMESSAGETIME,
     THREADSTATE_GETINPUTSTATE,
     THREADSTATE_UPTIMELASTREAD,
-    THREADSTATE_FOREGROUNDTHREAD
+    THREADSTATE_FOREGROUNDTHREAD,
+    THREADSTATE_GETCURSOR
 };
 
 DWORD_PTR
index 8787b4a..2dcb5e7 100644 (file)
@@ -418,13 +418,15 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach)
         pai->pti1 = ptiFrom;
         pai->pti2 = ptiTo;
         gpai = pai;
-        ERR("Attach Allocated! ptiFrom 0x%p  ptiTo 0x%p\n",ptiFrom,ptiTo);
+        TRACE("Attach Allocated! ptiFrom 0x%p  ptiTo 0x%p\n",ptiFrom,ptiTo);
 
+        ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
         ptiFrom->pqAttach = ptiFrom->MessageQueue;
         ptiFrom->MessageQueue = ptiTo->MessageQueue;
         // FIXME: conditions?
         ptiFrom->MessageQueue->spwndActive = ptiFrom->pqAttach->spwndActive;
         ptiFrom->MessageQueue->spwndFocus = ptiFrom->pqAttach->spwndFocus;
+        ptiFrom->MessageQueue->CursorObject = ptiFrom->pqAttach->CursorObject;
     }
     else /* If clear, unlink and free it. */
     {
@@ -447,13 +449,15 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach)
         if (paiprev) paiprev->paiNext = pai->paiNext;
 
         ExFreePoolWithTag(pai, USERTAG_ATTACHINFO);
-        ERR("Attach Free! ptiFrom 0x%p  ptiTo 0x%p\n",ptiFrom,ptiTo);
+        TRACE("Attach Free! ptiFrom 0x%p  ptiTo 0x%p\n",ptiFrom,ptiTo);
 
         ptiFrom->MessageQueue = ptiFrom->pqAttach;
         // FIXME: conditions?
+        ptiFrom->MessageQueue->CursorObject = NULL;
         ptiFrom->MessageQueue->spwndActive = NULL;
         ptiFrom->MessageQueue->spwndFocus = NULL;
         ptiFrom->pqAttach = NULL;
+        ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
     }
     /* Note that key state, which can be ascertained by calls to the GetKeyState
        or GetKeyboardState function, is reset after a call to AttachThreadInput.
index 8d7d7e1..d08d1c5 100644 (file)
@@ -462,9 +462,19 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread)
         }
     }
 
+    if (ptiCurrent->pqAttach && ptiCurrent->MessageQueue)
+    {
+       PTHREADINFO ptiTo;
+       ptiTo = PsGetThreadWin32Thread(ptiCurrent->MessageQueue->Thread);
+       TRACE_CH(UserThread,"Attached Thread is getting switched!\n");
+       UserAttachThreadInput( ptiCurrent, ptiTo, FALSE);
+    }
+
     /* Free the message queue */
     if(ptiCurrent->MessageQueue)
-        MsqDestroyMessageQueue(ptiCurrent->MessageQueue);
+    {
+       MsqDestroyMessageQueue(ptiCurrent->MessageQueue);
+    }
 
     /* Find the THREADINFO in the PROCESSINFO's list */
     ppti = &ppiCurrent->ptiList;
index 0ed1e37..37f14e8 100644 (file)
@@ -225,6 +225,10 @@ NtUserGetThreadState(
       case THREADSTATE_FOREGROUNDTHREAD:
          ret = (gpqForeground == GetW32ThreadInfo()->MessageQueue);
          break;
+      case THREADSTATE_GETCURSOR:
+         ret = (DWORD_PTR) (GetW32ThreadInfo()->MessageQueue->CursorObject ?
+                            UserHMGetHandle(GetW32ThreadInfo()->MessageQueue->CursorObject) : 0);
+         break;
    }
 
    TRACE("Leave NtUserGetThreadState, ret=%i\n", ret);
index 1e4e119..ec02c1c 100644 (file)
@@ -46,8 +46,7 @@ IntChildrenWindowFromPoint(PWND pWndTop, INT x, INT y)
     if ((pWndTop->style & WS_DISABLED)) return NULL;
     if (!IntPtInWindow(pWndTop, x, y)) return NULL;
 
-    if (x - pWndTop->rcClient.left < pWndTop->rcClient.right &&
-        y - pWndTop->rcClient.top  < pWndTop->rcClient.bottom )
+    if (RECTL_bPointInRect(&pWndTop->rcClient, x, y))
     {
        for (pWnd = pWndTop->spwndChild;
             pWnd != NULL;
@@ -130,7 +129,7 @@ UserSetCursor(
     MessageQueue->CursorObject = NewCursor;
 
     /* If cursor is not visible we have nothing to do */
-    if (MessageQueue->ShowingCursor < 0)
+    if (MessageQueue->iCursorLevel < 0)
         return OldCursor;
 
     /* Update cursor if this message queue controls it */
@@ -179,15 +178,16 @@ int UserShowCursor(BOOL bShow)
     MessageQueue = pti->MessageQueue;
 
     /* Update counter */
-    MessageQueue->ShowingCursor += bShow ? 1 : -1;
+    MessageQueue->iCursorLevel += bShow ? 1 : -1;
+    pti->iCursorLevel += bShow ? 1 : -1;
 
     /* Check for trivial cases */
-    if ((bShow && MessageQueue->ShowingCursor != 0) ||
-        (!bShow && MessageQueue->ShowingCursor != -1))
+    if ((bShow && MessageQueue->iCursorLevel != 0) ||
+        (!bShow && MessageQueue->iCursorLevel != -1))
     {
         /* Note: w don't update global info here because it is used only
           internally to check if cursor is visible */
-        return MessageQueue->ShowingCursor;
+        return MessageQueue->iCursorLevel;
     }
 
     /* Check if cursor is above window owned by this MessageQueue */
@@ -208,10 +208,10 @@ int UserShowCursor(BOOL bShow)
         }
 
         /* Update global info */
-        IntGetSysCursorInfo()->ShowingCursor = MessageQueue->ShowingCursor;
+        IntGetSysCursorInfo()->ShowingCursor = MessageQueue->iCursorLevel;
     }
 
-    return MessageQueue->ShowingCursor;
+    return MessageQueue->iCursorLevel;
 }
 
 DWORD FASTCALL
@@ -382,6 +382,10 @@ MsqWakeQueue(PUSER_MESSAGE_QUEUE Queue, DWORD MessageBits, BOOL KeyEvent)
 {
    PTHREADINFO pti;
 
+   if (Queue->QF_flags & QF_INDESTROY)
+   {
+      ERR("This Message Queue is in Destroy!\n");
+   }
    pti = Queue->Thread->Tcb.Win32Thread;
    pti->pcti->fsWakeBits |= MessageBits;
    pti->pcti->fsChangeBits |= MessageBits;
@@ -482,6 +486,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
    PDESKTOP pDesk;
    PWND pwnd, pwndDesktop;
    HDC hdcScreen;
+   PUSER_MESSAGE_QUEUE MessageQueue;
    PSYSTEM_CURSORINFO CurInfo;
 
    KeQueryTickCount(&LargeTickCount);
@@ -541,14 +546,20 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
    /* Check if we found a window */
    if (Msg->hwnd != NULL && pwnd != NULL)
    {
-       if (Msg->message == WM_MOUSEMOVE)
+       MessageQueue = pwnd->head.pti->MessageQueue;
+
+       if ( pwnd->head.pti->TIF_flags & TIF_INCLEANUP || MessageQueue->QF_flags & QF_INDESTROY)
        {
-           PUSER_MESSAGE_QUEUE MessageQueue = pwnd->head.pti->MessageQueue;
+          ERR("Mouse is over the Window Thread is Dead!\n");
+          return;
+       }
 
-           /* Check if cursor should be visible */
+       if (Msg->message == WM_MOUSEMOVE)
+       {
+          /* Check if cursor should be visible */
            if(hdcScreen &&
               MessageQueue->CursorObject &&
-              MessageQueue->ShowingCursor >= 0)
+              MessageQueue->iCursorLevel >= 0)
            {
                /* Check if shape has changed */
                if(CurInfo->CurrentCursorObject != MessageQueue->CursorObject)
@@ -569,7 +580,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
                GreMovePointer(hdcScreen, -1, -1);
 
            /* Update global cursor info */
-           CurInfo->ShowingCursor = MessageQueue->ShowingCursor;
+           CurInfo->ShowingCursor = MessageQueue->iCursorLevel;
            CurInfo->CurrentCursorObject = MessageQueue->CursorObject;
            gpqCursor = MessageQueue;
 
@@ -579,7 +590,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
        else
        {
            TRACE("Posting mouse message to hwnd=0x%x!\n", UserHMGetHandle(pwnd));
-           MsqPostMessage(pwnd->head.pti->MessageQueue, Msg, TRUE, QS_MOUSEBUTTON);
+           MsqPostMessage(MessageQueue, Msg, TRUE, QS_MOUSEBUTTON);
        }
    }
    else if (hdcScreen)
@@ -1532,7 +1543,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT
 
         /* Activate the window if needed */
 
-        if (msg->hwnd != UserGetForegroundWindow())
+        if (pwndMsg != pti->MessageQueue->spwndActive) //msg->hwnd != UserGetForegroundWindow())
         {
             PWND pwndTop = pwndMsg;
             while (pwndTop)
@@ -1559,7 +1570,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT
                     /* fall through */
                 case MA_ACTIVATE:
                 case 0:
-                    if(!co_IntMouseActivateWindow(pwndMsg)) eatMsg = TRUE;
+                    if (!co_IntMouseActivateWindow( pwndTop )) eatMsg = TRUE;
                     break;
                 default:
                     ERR( "unknown WM_MOUSEACTIVATE code %d\n", ret );
@@ -1865,7 +1876,7 @@ MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQu
    MessageQueue->LastMsgRead = LargeTickCount.u.LowPart;
    MessageQueue->spwndFocus = NULL;
    MessageQueue->NewMessagesHandle = NULL;
-   MessageQueue->ShowingCursor = 0;
+   MessageQueue->iCursorLevel = 0;
    MessageQueue->CursorObject = NULL;
    RtlCopyMemory(MessageQueue->afKeyState, gafAsyncKeyState, sizeof(gafAsyncKeyState));
 
index 6e5ba59..c832737 100644 (file)
@@ -92,6 +92,7 @@ typedef struct _USER_MESSAGE_QUEUE
   PTHRDCARETINFO CaretInfo;
   /* Message Queue Flags */
   DWORD QF_flags;
+  DWORD cThreads; // Shared message queue counter.
 
   /* Queue state tracking */
   // Send list QS_SENDMESSAGE
@@ -108,7 +109,7 @@ typedef struct _USER_MESSAGE_QUEUE
   BYTE afKeyState[256 * 2 / 8]; // 2 bits per key
 
   /* Showing cursor counter (value>=0 - cursor visible, value<0 - cursor hidden) */
-  INT ShowingCursor;
+  INT iCursorLevel;
   /* Cursor object */
   PCURICON_OBJECT CursorObject;
 
index 3ec0f54..2f23fbb 100644 (file)
@@ -97,6 +97,7 @@ typedef struct _THREADINFO
     HANDLE              hEventQueueClient;
     PKEVENT             pEventQueueServer;
     LIST_ENTRY          PtiLink;
+    INT                 iCursorLevel;
     POINT               ptLast;
 
     LIST_ENTRY          aphkStart[NB_HOOKS];
index eef5b24..45d30f8 100644 (file)
@@ -1253,12 +1253,7 @@ INT WINAPI /*DECLSPEC_HOTPATCH*/ ShowCursor( BOOL bShow )
  */
 HCURSOR WINAPI GetCursor(void)
 {
-    CURSORINFO ci;
-    ci.cbSize = sizeof(CURSORINFO);
-    if(NtUserGetCursorInfo(&ci))
-        return ci.hCursor;
-    else
-        return (HCURSOR)0;
+     return (HCURSOR)NtUserGetThreadState(THREADSTATE_GETCURSOR);
 }