mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 19:26:32 +00:00
- Add ShowingCursor counter and CursorObject to message queue and use them when moving mouse. They are not globally in Windows.
svn path=/trunk/; revision=52136
This commit is contained in:
@@ -71,8 +71,6 @@ PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon);
|
||||
|
||||
BOOL UserSetCursorPos( INT x, INT y, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook);
|
||||
|
||||
int UserShowCursor(BOOL bShow);
|
||||
|
||||
PSYSTEM_CURSORINFO IntGetSysCursorInfo(VOID);
|
||||
|
||||
#define IntReleaseCurIconObject(CurIconObj) \
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "hook.h"
|
||||
#include "cursoricon.h"
|
||||
|
||||
#define MSQ_HUNG 5000
|
||||
#define MSQ_NORMAL 0
|
||||
@@ -59,8 +60,6 @@ typedef struct _USER_MESSAGE_QUEUE
|
||||
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 @@ typedef struct _USER_MESSAGE_QUEUE
|
||||
/* 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 @@ UINT FASTCALL GetWakeMask(UINT, UINT);
|
||||
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 */
|
||||
|
||||
@@ -99,80 +99,14 @@ PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
|
||||
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()))
|
||||
{
|
||||
return FALSE;
|
||||
@@ -194,58 +128,19 @@ BOOL UserSetCursorPos( INT x, INT y, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Ho
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have to register that this object is in use by the current
|
||||
* process. The only way to do that seems to be to walk the list
|
||||
|
||||
@@ -634,7 +634,6 @@ NtUserEnumDisplaySettings(
|
||||
|
||||
BOOL APIENTRY UserClipCursor(RECTL *prcl);
|
||||
VOID APIENTRY UserRedrawDesktop();
|
||||
HCURSOR FASTCALL UserSetCursor(PCURICON_OBJECT NewCursor, BOOL ForceChange);
|
||||
|
||||
LONG
|
||||
APIENTRY
|
||||
|
||||
@@ -43,6 +43,151 @@ MsqInitializeImpl(VOID)
|
||||
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)
|
||||
{
|
||||
DWORD ret = 0;
|
||||
@@ -307,13 +452,15 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
|
||||
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 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
|
||||
|
||||
/* Get the desktop window */
|
||||
pwndDesktop = UserGetDesktopWindow();
|
||||
if(!pwndDesktop)
|
||||
if (!pwndDesktop)
|
||||
return;
|
||||
|
||||
/* Set hit somewhere on the desktop */
|
||||
@@ -354,7 +501,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
|
||||
|
||||
/* 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,35 +513,54 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
|
||||
}
|
||||
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 )
|
||||
{
|
||||
DPRINT("The Window is in DESTROY!\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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->hwnd != NULL && pwnd != NULL)
|
||||
{
|
||||
if(Msg->message == WM_MOUSEMOVE)
|
||||
if (Msg->message == WM_MOUSEMOVE)
|
||||
{
|
||||
/* Mouse move is a special case*/
|
||||
MsqPostMouseMove(pwnd->head.pti->MessageQueue, Msg);
|
||||
PUSER_MESSAGE_QUEUE MessageQueue = pwnd->head.pti->MessageQueue;
|
||||
|
||||
/* Check if cursor should be visible */
|
||||
if(hdcScreen &&
|
||||
MessageQueue->CursorObject &&
|
||||
MessageQueue->ShowingCursor >= 0)
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
/* 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
|
||||
{
|
||||
@@ -402,6 +568,12 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
|
||||
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. */
|
||||
MouseHistoryOfMoves[gcur_count].x = Msg->pt.x;
|
||||
@@ -1601,13 +1773,14 @@ MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQu
|
||||
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 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
|
||||
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 @@ NtUserSetKeyboardState(LPBYTE lpKeyState)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
||||
Reference in New Issue
Block a user