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/in…
==============================================================================
--- 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/in…
==============================================================================
--- 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/nt…
==============================================================================
--- 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/nt…
==============================================================================
--- 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/nt…
==============================================================================
--- 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 */