Implemented mouse messages.

svn path=/trunk/; revision=3679
This commit is contained in:
David Welch 2002-10-31 00:03:31 +00:00
parent 5672a8cbc6
commit ae67380311
13 changed files with 597 additions and 134 deletions

View file

@ -1,13 +1,47 @@
/*
* ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* 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.
*/
/* $Id: mouse.c,v 1.14 2002/10/31 00:03:30 dwelch Exp $
*
* PROJECT: ReactOS kernel
* PURPOSE: Mouse
* FILE: subsys/win32k/eng/mouse.c
* PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISION HISTORY:
* 06-06-2001 CSH Created
*/
/* INCLUDES ******************************************************************/
#include <windows.h>
#include <ddk/ntddk.h>
#include <win32k/dc.h>
#include "../../drivers/input/include/mouse.h"
#include "objects.h"
#include "include/msgqueue.h"
/* GLOBALS *******************************************************************/
static BOOLEAN SafetySwitch = FALSE;
static BOOLEAN SafetySwitch2 = FALSE;
static BOOLEAN MouseEnabled = FALSE;
static LONG mouse_x, mouse_y;
static UINT mouse_width = 0, mouse_height = 0;
static UCHAR DefaultCursor[256] = {
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
@ -75,51 +109,85 @@ static UCHAR DefaultCursor[256] = {
0x1F, 0xFF, 0xFF, 0xFF,
0x3F, 0xFF, 0xFF, 0xFF};
INT MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1, LONG HazardY1, LONG HazardX2, LONG HazardY2)
/* FUNCTIONS *****************************************************************/
INT
MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1,
LONG HazardY1, LONG HazardX2, LONG HazardY2)
/*
* FUNCTION: Notify the mouse driver that drawing is about to begin in
* a rectangle on a particular surface.
*/
{
RECTL MouseRect;
LONG tmp;
if(SurfObj == NULL) return 0;
if (SurfObj == NULL)
{
return(FALSE);
}
if((SurfObj->iType != STYPE_DEVICE) || (MouseEnabled == FALSE)) return 0;
if (SurfObj->iType != STYPE_DEVICE || MouseEnabled == FALSE)
{
return(FALSE);
}
if(HazardX1 > HazardX2) { tmp = HazardX2; HazardX2 = HazardX1; HazardX1 = tmp; }
if(HazardY1 > HazardY2) { tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp; }
if (HazardX1 > HazardX2)
{
tmp = HazardX2; HazardX2 = HazardX1; HazardX1 = tmp;
}
if (HazardY1 > HazardY2)
{
tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp;
}
if( (mouse_x + mouse_width >= HazardX1) && (mouse_x <= HazardX2) &&
(mouse_y + mouse_height >= HazardY1) && (mouse_y <= HazardY2) )
{
SurfGDI->MovePointer(SurfObj, -1, -1, &MouseRect);
SafetySwitch = TRUE;
}
if ((mouse_x + mouse_width >= HazardX1) && (mouse_x <= HazardX2) &&
(mouse_y + mouse_height >= HazardY1) && (mouse_y <= HazardY2))
{
SurfGDI->MovePointer(SurfObj, -1, -1, &MouseRect);
SafetySwitch = TRUE;
}
// Mouse is not allowed to move if GDI is busy drawing
/* Mouse is not allowed to move if GDI is busy drawing */
SafetySwitch2 = TRUE;
return 1;
return(TRUE);
}
INT MouseSafetyOnDrawEnd(PSURFOBJ SurfObj, PSURFGDI SurfGDI)
INT
MouseSafetyOnDrawEnd(PSURFOBJ SurfObj, PSURFGDI SurfGDI)
/*
* FUNCTION: Notify the mouse driver that drawing has finished on a surface.
*/
{
RECTL MouseRect;
if(SurfObj == NULL) return 0;
if (SurfObj == NULL)
{
return(FALSE);
}
if((SurfObj->iType != STYPE_DEVICE) || (MouseEnabled == FALSE)) return 0;
if(SafetySwitch == TRUE)
{
SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect);
SafetySwitch = FALSE;
}
if (SurfObj->iType != STYPE_DEVICE || MouseEnabled == FALSE)
{
return(FALSE);
}
if (SafetySwitch)
{
SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect);
SafetySwitch = FALSE;
}
SafetySwitch2 = FALSE;
return 1;
return(TRUE);
}
VOID MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
VOID
MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
/*
* FUNCTION: Call by the mouse driver when input events occur.
*/
{
ULONG i;
LONG mouse_cx = 0, mouse_cy = 0;
@ -128,14 +196,19 @@ VOID MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
PSURFOBJ SurfObj;
PSURFGDI SurfGDI;
RECTL MouseRect;
MSG Msg;
ULONG j;
LARGE_INTEGER LargeTickCount;
ULONG TickCount;
static ULONG ButtonsDown = 0;
const UINT MouseButtonDownMessage[3] =
{WM_RBUTTONDOWN, WM_MBUTTONDOWN, WM_LBUTTONDOWN};
const UINT MouseButtonUpMessage[3] =
{WM_RBUTTONUP, WM_MBUTTONUP, WM_LBUTTONUP};
const ULONG MouseButtonFlag[3] = {MK_RBUTTON, MK_MBUTTON, MK_LBUTTON};
PDEVICE_OBJECT ClassDeviceObject = NULL;
PFILE_OBJECT FileObject = NULL;
NTSTATUS status;
UNICODE_STRING ClassName;
IO_STATUS_BLOCK ioStatus;
KEVENT event;
PIRP irp;
KeQueryTickCount(&LargeTickCount);
TickCount = LargeTickCount.u.LowPart;
if (hDC == 0)
{
@ -145,42 +218,70 @@ VOID MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
dc = DC_HandleToPtr(hDC);
SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface);
SurfGDI = (PSURFGDI)AccessInternalObject(dc->Surface);
/* Compile the total mouse movement change and dispatch button events. */
for (i = 0; i < InputCount; i++)
{
mouse_cx += Data[i].LastX;
mouse_cy += Data[i].LastY;
// Compile the total mouse movement change
for (i=0; i<InputCount; i++)
{
mouse_cx += Data[i].LastX;
mouse_cy += Data[i].LastY;
}
Msg.wParam = ButtonsDown;
Msg.lParam = MAKELPARAM(mouse_x + mouse_cx, mouse_y + mouse_cy);
Msg.message = WM_MOUSEMOVE;
Msg.time = TickCount;
Msg.pt.x = mouse_x + mouse_cx;
Msg.pt.y = mouse_y + mouse_cy;
MsqInsertSystemMessage(&Msg);
for (j = 0; j < 3; j++)
{
ULONG Flag = MouseButtonFlag[j];
if (Data[i].ButtonData & (1 << j) && !(ButtonsDown & Flag))
{
ButtonsDown |= Flag;
if((mouse_cx != 0) || (mouse_cy != 0))
{
mouse_x += mouse_cx;
mouse_y += mouse_cy;
Msg.wParam = ButtonsDown;
Msg.message = MouseButtonDownMessage[j];
MsqInsertSystemMessage(&Msg);
}
if (!(Data[i].ButtonData & (1 << j)) && (ButtonsDown & Flag))
{
ButtonsDown &= ~Flag;
if(mouse_x < 0) mouse_x = 0;
if(mouse_y < 0) mouse_y = 0;
if(mouse_x > 620) mouse_x = 620;
if(mouse_y > 460) mouse_y = 460;
Msg.wParam = ButtonsDown;
Msg.message = MouseButtonUpMessage[j];
MsqInsertSystemMessage(&Msg);
}
}
}
if((SafetySwitch == FALSE) && (SafetySwitch2 == FALSE)) ;
SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect);
}
/* If the mouse moved then move the pointer. */
if (mouse_cx != 0 || mouse_cy != 0)
{
mouse_x += mouse_cx;
mouse_y += mouse_cy;
mouse_x = max(mouse_x, 0);
mouse_y = max(mouse_y, 0);
mouse_x = min(mouse_x, 620);
mouse_y = min(mouse_y, 460);
if (SafetySwitch == FALSE && SafetySwitch2 == FALSE)
{
SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect);
}
}
}
VOID EnableMouse(HDC hDisplayDC)
VOID
EnableMouse(HDC hDisplayDC)
{
PDC dc = DC_HandleToPtr(hDisplayDC);
PSURFOBJ SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface);
PSURFGDI SurfGDI = (PSURFGDI)AccessInternalObject(dc->Surface);
BOOL txt;
int i;
BRUSHOBJ Brush;
HBITMAP hMouseSurf;
PSURFOBJ MouseSurf;
SIZEL MouseSize;
POINTL ZeroPoint;
RECTL MouseRect;
/* Create the default mouse cursor. */

View file

@ -36,6 +36,9 @@ ClassReferenceClassByNameOrAtom(PWNDCLASS_OBJECT *Class,
PWNDCLASS_OBJECT
W32kCreateClass(LPWNDCLASSEX lpwcx,
BOOL bUnicodeClass);
struct _WINDOW_OBJECT;
ULONG
W32kGetClassLong(struct _WINDOW_OBJECT* WindowObject, ULONG Offset);
#endif /* __WIN32K_CLASS_H */

View file

@ -38,10 +38,10 @@ typedef struct _USER_MESSAGE_QUEUE
LIST_ENTRY SentMessagesListHead;
/* Queue of messages posted to the queue. */
LIST_ENTRY PostedMessagesListHead;
/* Queue of hardware messages for the queue. */
LIST_ENTRY HardwareMessagesListHead;
/* Queue of sent-message notifies for the queue. */
LIST_ENTRY NotifyMessagesListHead;
/* Queue for hardware messages for the queue. */
LIST_ENTRY HardwareMessagesListHead;
/* Lock for the queue. */
FAST_MUTEX Lock;
/* True if a WM_QUIT message is pending. */
@ -76,8 +76,7 @@ VOID
MsqDestroyMessage(PUSER_MESSAGE Message);
VOID
MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue,
PUSER_MESSAGE Message,
BOOLEAN Hardware);
PUSER_MESSAGE Message);
BOOLEAN
MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
IN BOOLEAN Hardware,
@ -117,6 +116,10 @@ W32kSendMessage(HWND hWnd,
WPARAM wParam,
LPARAM lParam,
BOOL KernelMessage);
VOID
MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
VOID
MsqInsertSystemMessage(MSG* Msg);
#define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF))

View file

@ -14,3 +14,6 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
INT cy, UINT flags);
BOOLEAN
WinPosShowWindow(HWND Wnd, INT Cmd);
USHORT
WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, POINT WinPoint,
PWINDOW_OBJECT* Window);

View file

@ -1,4 +1,4 @@
/* $Id: class.c,v 1.13 2002/09/08 10:23:52 chorns Exp $
/* $Id: class.c,v 1.14 2002/10/31 00:03:31 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -265,17 +265,10 @@ NtUserRegisterClassExWOW(LPWNDCLASSEX lpwcx,
return(Atom);
}
DWORD STDCALL
NtUserGetClassLong(HWND hWnd, DWORD Offset)
ULONG
W32kGetClassLong(PWINDOW_OBJECT WindowObject, ULONG Offset)
{
PWINDOW_OBJECT WindowObject;
LONG Ret;
WindowObject = W32kGetWindowObject(hWnd);
if (WindowObject == NULL)
{
return(0);
}
switch (Offset)
{
case GCL_STYLE:
@ -288,15 +281,30 @@ NtUserGetClassLong(HWND hWnd, DWORD Offset)
Ret = WindowObject->Class->Class.cbClsExtra;
break;
case GCL_HMODULE:
Ret = WindowObject->Class->Class.hInstance;
Ret = (ULONG)WindowObject->Class->Class.hInstance;
break;
case GCL_HBRBACKGROUND:
Ret = WindowObject->Class->Class.hbrBackground;
Ret = (ULONG)WindowObject->Class->Class.hbrBackground;
break;
default:
Ret = 0;
break;
}
return(Ret);
}
DWORD STDCALL
NtUserGetClassLong(HWND hWnd, DWORD Offset)
{
PWINDOW_OBJECT WindowObject;
LONG Ret;
WindowObject = W32kGetWindowObject(hWnd);
if (WindowObject == NULL)
{
return(0);
}
Ret = W32kGetClassLong(WindowObject, Offset);
W32kReleaseWindowObject(WindowObject);
return(Ret);
}

View file

@ -1,4 +1,4 @@
/* $Id: input.c,v 1.3 2002/09/17 23:43:28 dwelch Exp $
/* $Id: input.c,v 1.4 2002/10/31 00:03:31 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -55,7 +55,7 @@ KeyboardThreadMain(PVOID StartContext)
&KeyboardObjectAttributes,
&Iosb,
0,
0);
FILE_SYNCHRONOUS_IO_ALERT);
if (!NT_SUCCESS(Status))
{
DbgPrint("W32K: Failed to open keyboard.\n");
@ -164,7 +164,6 @@ InitInputImpl(VOID)
if (!NT_SUCCESS(Status))
{
DbgPrint("W32K: Failed to create keyboard thread.\n");
NtClose(KeyboardThreadHandle);
}
/*
@ -228,7 +227,7 @@ InitInputImpl(VOID)
DbgPrint("W32K: Failed to connect to mouse driver.\n");
return(Status);
}
return(STATUS_SUCCESS);
}

View file

@ -1,4 +1,4 @@
/* $Id: keyboard.c,v 1.1 2002/01/27 14:47:44 dwelch Exp $
/* $Id: keyboard.c,v 1.2 2002/10/31 00:03:31 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -202,9 +202,7 @@ NtUserTranslateMessage(LPMSG lpMsg,
NewMsg.wParam = wp[0];
NewMsg.lParam = lpMsg->lParam;
UMsg = MsqCreateMessage(&NewMsg);
MsqPostMessage(PsGetWin32Thread()->MessageQueue,
UMsg,
FALSE);
MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
return(TRUE);
}
}
@ -217,9 +215,7 @@ NtUserTranslateMessage(LPMSG lpMsg,
NewMsg.lParam = lpMsg->lParam;
dead_char = wp[0];
UMsg = MsqCreateMessage(&NewMsg);
MsqPostMessage(PsGetWin32Thread()->MessageQueue,
UMsg,
FALSE);
MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
return(TRUE);
}
return(FALSE);

View file

@ -1,4 +1,4 @@
/* $Id: message.c,v 1.10 2002/09/17 23:43:28 dwelch Exp $
/* $Id: message.c,v 1.11 2002/10/31 00:03:31 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -216,7 +216,7 @@ NtUserGetMessage(LPMSG lpMsg,
/* Nothing found so far. Wait for new messages. */
Status = MsqWaitForNewMessages(ThreadQueue);
}
while (Status == STATUS_WAIT_0);
while (Status >= STATUS_WAIT_0 && Status <= STATUS_WAIT_63);
return((BOOLEAN)(-1));
}

View file

@ -1,4 +1,4 @@
/* $Id: msgqueue.c,v 1.5 2002/07/17 21:04:57 dwelch Exp $
/* $Id: msgqueue.c,v 1.6 2002/10/31 00:03:31 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -15,13 +15,28 @@
#include <win32k/win32k.h>
#include <include/msgqueue.h>
#include <include/callback.h>
#include <include/window.h>
#include <include/winpos.h>
#include <include/class.h>
#define NDEBUG
#include <debug.h>
/* GLOBALS *******************************************************************/
static PUSER_MESSAGE_QUEUE CurrentFocusMessageQueue;
#define SYSTEM_MESSAGE_QUEUE_SIZE (256)
static MSG SystemMessageQueue[SYSTEM_MESSAGE_QUEUE_SIZE];
static ULONG SystemMessageQueueHead = 0;
static ULONG SystemMessageQueueTail = 0;
static ULONG SystemMessageQueueCount = 0;
static KSPIN_LOCK SystemMessageQueueLock;
static ULONG HardwareMessageQueueStamp = 0;
static LIST_ENTRY HardwareMessageQueueHead;
static FAST_MUTEX HardwareMessageQueueLock;
static KEVENT HardwareMessageEvent;
/* FUNCTIONS *****************************************************************/
@ -50,16 +65,273 @@ MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue)
NTSTATUS
MsqInitializeImpl(VOID)
{
CurrentFocusMessageQueue = NULL;
/*CurrentFocusMessageQueue = NULL;*/
InitializeListHead(&HardwareMessageQueueHead);
KeInitializeEvent(&HardwareMessageEvent, NotificationEvent, 0);
KeInitializeSpinLock(&SystemMessageQueueLock);
ExInitializeFastMutex(&HardwareMessageQueueLock);
return(STATUS_SUCCESS);
}
VOID
MsqInsertSystemMessage(MSG* Msg)
{
KIRQL OldIrql;
KeAcquireSpinLock(&SystemMessageQueueLock, &OldIrql);
if (SystemMessageQueueCount == SYSTEM_MESSAGE_QUEUE_SIZE)
{
KeReleaseSpinLock(&SystemMessageQueueLock, OldIrql);
return;
}
SystemMessageQueue[SystemMessageQueueTail] = *Msg;
SystemMessageQueueTail =
(SystemMessageQueueTail + 1) % SYSTEM_MESSAGE_QUEUE_SIZE;
SystemMessageQueueCount++;
KeReleaseSpinLock(&SystemMessageQueueLock, OldIrql);
KeSetEvent(&HardwareMessageEvent, IO_NO_INCREMENT, FALSE);
}
BOOL STATIC
MsqTranslateMouseMessage(HWND hWnd, UINT FilterLow, UINT FilterHigh,
PUSER_MESSAGE Message, BOOL Remove,
PWINDOW_OBJECT ScopeWin, PUSHORT HitTest,
PPOINT ScreenPoint, PBOOL MouseClick)
{
static ULONG ClkTime = 0;
static USHORT ClkMessage = 0;
static HWND ClkWnd = 0;
static POINT ClkPos = {0, 0};
USHORT Msg = Message->Msg.message;
PWINDOW_OBJECT Window;
POINT Point;
ULONG Click = 0;
/* FIXME: Handle window capture. */
*HitTest = WinPosWindowFromPoint(ScopeWin, Message->Msg.pt, &Window);
if (Window->MessageQueue != PsGetWin32Thread()->MessageQueue)
{
ExAcquireFastMutex(&Window->MessageQueue->Lock);
InsertTailList(&Window->MessageQueue->HardwareMessagesListHead,
&Message->ListEntry);
ExReleaseFastMutex(&Window->MessageQueue->Lock);
KeSetEvent(&Window->MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
return(FALSE);
}
if (hWnd != NULL && Window->Self != hWnd &&
!W32kIsChildWindow(hWnd, Window->Self))
{
return(FALSE);
}
if (Msg == WM_LBUTTONDOWN || Msg == WM_RBUTTONDOWN || Msg == WM_MBUTTONDOWN)
{
(*MouseClick) = Click = 1;
}
if (Click)
{
if (W32kGetClassLong(Window, GCL_STYLE) & CS_DBLCLKS ||
(*HitTest) != HTCLIENT)
{
if (Msg == ClkMessage &&
Window->Self == ClkWnd &&
(Message->Msg.time - ClkTime) < 452 &&
abs(Message->Msg.pt.x - ClkPos.x) < 2 &&
abs(Message->Msg.pt.y - ClkPos.y) < 2)
{
Msg += (WM_LBUTTONDBLCLK - WM_LBUTTONDOWN);
Click++;
}
}
}
*ScreenPoint = Message->Msg.pt;
if ((*HitTest) != HTCLIENT)
{
Msg += WM_NCMOUSEMOVE - WM_MOUSEMOVE;
Message->Msg.wParam = *HitTest;
}
else
{
Point = Message->Msg.pt;
Point.x -= Window->ClientRect.left;
Point.y -= Window->ClientRect.top;
}
/* FIXME: Check message filter. */
if (Remove && Click)
{
if (Click == 1)
{
ClkTime = Message->Msg.time;
ClkMessage = Msg;
ClkWnd = Window->Self;
ClkPos = (*ScreenPoint);
}
else
{
ClkTime = 0;
ClkWnd = NULL;
}
}
Message->Msg.hwnd = Window->Self;
Message->Msg.message = Msg;
Message->Msg.lParam = MAKELONG(Point.x, Point.y);
return(TRUE);
}
BOOL
MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd,
UINT FilterLow, UINT FilterHigh, BOOL Remove,
PUSER_MESSAGE* Message)
{
KIRQL OldIrql;
USHORT HitTest;
POINT ScreenPoint;
BOOL Accept;
BOOL MouseClick;
PLIST_ENTRY CurrentEntry;
ULONG ActiveStamp;
PWINDOW_OBJECT DesktopWindow;
DesktopWindow = W32kGetWindowObject(W32kGetDesktopWindow());
/* Process messages in the message queue itself. */
ExAcquireFastMutex(&MessageQueue->Lock);
CurrentEntry = MessageQueue->HardwareMessagesListHead.Flink;
while (CurrentEntry != &MessageQueue->HardwareMessagesListHead)
{
PUSER_MESSAGE Current =
CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
CurrentEntry = CurrentEntry->Flink;
RemoveEntryList(&Current->ListEntry);
if (Current->Msg.message >= WM_MOUSEFIRST &&
Current->Msg.message <= WM_MOUSELAST)
{
Accept = MsqTranslateMouseMessage(hWnd, FilterLow, FilterHigh,
Current, Remove,
DesktopWindow, &HitTest,
&ScreenPoint, &MouseClick);
if (Accept)
{
RemoveEntryList(&Current->ListEntry);
ExReleaseFastMutex(&MessageQueue->Lock);
*Message = Current;
W32kReleaseWindowObject(DesktopWindow);
return(TRUE);
}
}
CurrentEntry = CurrentEntry->Flink;
}
ExReleaseFastMutex(&MessageQueue->Lock);
/* Now try the global queue. */
ExAcquireFastMutex(&HardwareMessageQueueLock);
/* Transfer all messages from the DPC accessible queue to the main queue. */
KeAcquireSpinLock(&SystemMessageQueueLock, &OldIrql);
while (SystemMessageQueueCount > 0)
{
PUSER_MESSAGE UserMsg;
MSG Msg;
Msg = SystemMessageQueue[SystemMessageQueueHead];
SystemMessageQueueHead =
(SystemMessageQueueHead + 1) % SYSTEM_MESSAGE_QUEUE_SIZE;
SystemMessageQueueCount--;
KeReleaseSpinLock(&SystemMessageQueueLock, OldIrql);
UserMsg = ExAllocatePool(NonPagedPool, sizeof(USER_MESSAGE));
UserMsg->Msg = Msg;
InsertTailList(&HardwareMessageQueueHead, &UserMsg->ListEntry);
KeAcquireSpinLock(&SystemMessageQueueLock, &OldIrql);
}
KeReleaseSpinLock(&SystemMessageQueueLock, OldIrql);
HardwareMessageQueueStamp++;
/* Process messages in the queue until we find one to return. */
CurrentEntry = HardwareMessageQueueHead.Flink;
while (CurrentEntry != &HardwareMessageQueueHead)
{
PUSER_MESSAGE Current =
CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, ListEntry);
CurrentEntry = CurrentEntry->Flink;
RemoveEntryList(&Current->ListEntry);
if (Current->Msg.message >= WM_MOUSEFIRST &&
Current->Msg.message <= WM_MOUSELAST)
{
ActiveStamp = HardwareMessageQueueStamp;
ExReleaseFastMutex(&HardwareMessageQueueLock);
/* Translate the message. */
Accept = MsqTranslateMouseMessage(hWnd, FilterLow, FilterHigh,
Current, Remove,
DesktopWindow, &HitTest,
&ScreenPoint, &MouseClick);
ExAcquireFastMutex(&HardwareMessageQueueLock);
if (Accept)
{
/* Check for no more messages in the system queue. */
KeAcquireSpinLock(&SystemMessageQueueLock, &OldIrql);
if (SystemMessageQueueCount == 0 &&
IsListEmpty(&HardwareMessageQueueHead))
{
KeClearEvent(&HardwareMessageEvent);
}
KeReleaseSpinLock(&SystemMessageQueueLock, OldIrql);
/*
If we aren't removing the message then add it to the private
queue.
*/
if (!Remove)
{
InsertTailList(&MessageQueue->HardwareMessagesListHead,
&Current->ListEntry);
}
ExReleaseFastMutex(&HardwareMessageQueueLock);
*Message = Current;
W32kReleaseWindowObject(DesktopWindow);
return(TRUE);
}
/* If the contents of the queue changed then restart processing. */
if (HardwareMessageQueueStamp != ActiveStamp)
{
CurrentEntry = HardwareMessageQueueHead.Flink;
continue;
}
}
}
/* Check if the system message queue is now empty. */
KeAcquireSpinLock(&SystemMessageQueueLock, &OldIrql);
if (SystemMessageQueueCount == 0 && IsListEmpty(&HardwareMessageQueueHead))
{
KeClearEvent(&HardwareMessageEvent);
}
KeReleaseSpinLock(&SystemMessageQueueLock, OldIrql);
ExReleaseFastMutex(&HardwareMessageQueueLock);
return(FALSE);
}
VOID
MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
#if 0
MSG Msg;
PUSER_MESSAGE Message;
if (CurrentFocusMessageQueue == NULL)
{
return;
}
Msg.hwnd = CurrentFocusMessageQueue->FocusWindow;
Msg.message = uMsg;
Msg.wParam = wParam;
@ -68,6 +340,7 @@ MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
Message = MsqCreateMessage(&Msg);
MsqPostMessage(CurrentFocusMessageQueue, Message, TRUE);
#endif
}
VOID
@ -203,21 +476,11 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
}
VOID
MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue,
PUSER_MESSAGE Message,
BOOLEAN Hardware)
MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, PUSER_MESSAGE Message)
{
ExAcquireFastMutex(&MessageQueue->Lock);
if (Hardware)
{
InsertTailList(&MessageQueue->HardwareMessagesListHead,
&Message->ListEntry);
}
else
{
InsertTailList(&MessageQueue->PostedMessagesListHead,
&Message->ListEntry);
}
InsertTailList(&MessageQueue->PostedMessagesListHead,
&Message->ListEntry);
KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
ExReleaseFastMutex(&MessageQueue->Lock);
}
@ -234,18 +497,17 @@ MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
PLIST_ENTRY CurrentEntry;
PUSER_MESSAGE CurrentMessage;
PLIST_ENTRY ListHead;
ExAcquireFastMutex(&MessageQueue->Lock);
if (Hardware)
{
CurrentEntry = MessageQueue->HardwareMessagesListHead.Flink;
ListHead = &MessageQueue->HardwareMessagesListHead;
}
else
{
CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
ListHead = &MessageQueue->PostedMessagesListHead;
return(MsqPeekHardwareMessage(MessageQueue, Wnd,
MsgFilterLow, MsgFilterHigh,
Remove, Message));
}
ExAcquireFastMutex(&MessageQueue->Lock);
CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
ListHead = &MessageQueue->PostedMessagesListHead;
while (CurrentEntry != ListHead)
{
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
@ -272,19 +534,23 @@ MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
NTSTATUS
MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue)
{
return(KeWaitForSingleObject(&MessageQueue->NewMessages,
0,
UserMode,
TRUE,
NULL));
PVOID WaitObjects[2] = {&MessageQueue->NewMessages, &HardwareMessageEvent};
return(KeWaitForMultipleObjects(2,
WaitObjects,
WaitAny,
Executive,
UserMode,
TRUE,
NULL,
NULL));
}
VOID
MsqInitializeMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
{
InitializeListHead(&MessageQueue->PostedMessagesListHead);
InitializeListHead(&MessageQueue->HardwareMessagesListHead);
InitializeListHead(&MessageQueue->SentMessagesListHead);
InitializeListHead(&MessageQueue->HardwareMessagesListHead);
ExInitializeFastMutex(&MessageQueue->Lock);
MessageQueue->QuitPosted = FALSE;
MessageQueue->QuitExitCode = 0;
@ -307,15 +573,6 @@ MsqFreeMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
CurrentEntry = CurrentEntry->Flink;
ExFreePool(CurrentMessage);
}
CurrentEntry = MessageQueue->HardwareMessagesListHead.Flink;
while (CurrentEntry != &MessageQueue->HardwareMessagesListHead)
{
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
ListEntry);
CurrentEntry = CurrentEntry->Flink;
ExFreePool(CurrentMessage);
}
}
PUSER_MESSAGE_QUEUE

View file

@ -1,4 +1,4 @@
/* $Id: painting.c,v 1.6 2002/09/17 23:43:28 dwelch Exp $
/* $Id: painting.c,v 1.7 2002/10/31 00:03:31 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -546,7 +546,6 @@ PaintingFindWinToRepaint(HWND hWnd, PW32THREAD Thread)
PWINDOW_OBJECT BaseWindow;
PLIST_ENTRY current_entry;
HWND hFoundWnd = NULL;
NTSTATUS Status;
if (hWnd == NULL)
{

View file

@ -1,4 +1,4 @@
/* $Id: window.c,v 1.18 2002/09/17 23:43:28 dwelch Exp $
/* $Id: window.c,v 1.19 2002/10/31 00:03:31 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -901,8 +901,6 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index)
NTSTATUS Status;
DWORD Result;
DPRINT("NtUserGetWindowLong(hWnd %X, Index %d)\n", hWnd, Index);
W32kGuiCheck();
Status =
@ -912,7 +910,6 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index)
(PVOID*)&WindowObject);
if (!NT_SUCCESS(Status))
{
DPRINT("NtUserGetWindowLong(): Bad handle.\n");
return(0);
}
@ -945,7 +942,6 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index)
}
ObmDereferenceObject(WindowObject);
DPRINT("NtUserGetWindowLong(): %X\n", Result);
return(Result);
}

View file

@ -1,4 +1,4 @@
/* $Id: winpos.c,v 1.5 2002/09/17 23:43:28 dwelch Exp $
/* $Id: winpos.c,v 1.6 2002/10/31 00:03:31 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -59,10 +59,11 @@ NtUserGetClientOrigin(HWND hWnd, LPPOINT Point)
WindowObject = W32kGetWindowObject(hWnd);
if (WindowObject == NULL)
{
return(FALSE);
Point->x = Point->y = 0;
return(TRUE);
}
Point->x = WindowObject->ClientRect.left;
Point->y = WindowObject->ClientRect.right;
Point->y = WindowObject->ClientRect.top;
return(TRUE);
}
@ -729,3 +730,99 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
ObmDereferenceObject(Window);
return(WasVisible);
}
BOOL STATIC
WinPosPtInWindow(PWINDOW_OBJECT Window, POINT Point)
{
return(Point.x >= Window->WindowRect.left &&
Point.x < Window->WindowRect.right &&
Point.y >= Window->WindowRect.top &&
Point.y < Window->WindowRect.bottom);
}
USHORT STATIC
WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point,
PWINDOW_OBJECT* Window)
{
PLIST_ENTRY CurrentEntry;
PWINDOW_OBJECT Current;
CurrentEntry = ScopeWin->ChildrenListHead.Flink;
while (CurrentEntry != &ScopeWin->ChildrenListHead)
{
Current =
CONTAINING_RECORD(CurrentEntry, WINDOW_OBJECT, SiblingListEntry);
if (Current->Style & WS_VISIBLE &&
((!(Current->Style & WS_DISABLED)) ||
(Current->Style & (WS_CHILD | WS_POPUP)) != WS_CHILD) &&
WinPosPtInWindow(Current, Point))
{
*Window = Current;
if (Current->Style & WS_DISABLED)
{
return(HTERROR);
}
if (Current->Style & WS_MINIMIZE)
{
return(HTCAPTION);
}
if (Point.x >= Current->ClientRect.left &&
Point.x < Current->ClientRect.right &&
Point.y >= Current->ClientRect.top &&
Point.y < Current->ClientRect.bottom)
{
Point.x -= Current->ClientRect.left;
Point.y -= Current->ClientRect.top;
return(WinPosSearchChildren(Current, Point, Window));
}
return(0);
}
CurrentEntry = CurrentEntry->Flink;
}
return(0);
}
USHORT
WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, POINT WinPoint,
PWINDOW_OBJECT* Window)
{
HWND DesktopWindowHandle;
PWINDOW_OBJECT DesktopWindow;
POINT Point = WinPoint;
USHORT HitTest;
*Window = NULL;
if (ScopeWin->Style & WS_DISABLED)
{
return(HTERROR);
}
/* Translate the point to the space of the scope window. */
DesktopWindowHandle = W32kGetDesktopWindow();
DesktopWindow = W32kGetWindowObject(DesktopWindowHandle);
Point.x += ScopeWin->ClientRect.left - DesktopWindow->ClientRect.left;
Point.y += ScopeWin->ClientRect.top - DesktopWindow->ClientRect.top;
W32kReleaseWindowObject(DesktopWindow);
HitTest = WinPosSearchChildren(ScopeWin, Point, Window);
if (HitTest != 0)
{
return(HitTest);
}
if ((*Window)->MessageQueue == PsGetWin32Thread()->MessageQueue)
{
HitTest = W32kSendMessage((*Window)->Self, WM_NCHITTEST, 0,
MAKELONG(Point.x, Point.y), FALSE);
/* FIXME: Check for HTTRANSPARENT here. */
}
else
{
HitTest = HTCLIENT;
}
return(HitTest);
}

View file

@ -1,4 +1,4 @@
/* $Id: winsta.c,v 1.10 2002/09/17 23:43:28 dwelch Exp $
/* $Id: winsta.c,v 1.11 2002/10/31 00:03:31 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -844,6 +844,7 @@ W32kInitializeDesktopGraphics(VOID)
ScreenDeviceContext = W32kCreateDC(L"DISPLAY", NULL, NULL, NULL);
GDIOBJ_MarkObjectGlobal(ScreenDeviceContext);
EnableMouse(ScreenDeviceContext);
NtUserAcquireOrReleaseInputOwnership(FALSE);
}
HDC