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 <ddk/ntddk.h>
#include <win32k/dc.h> #include <win32k/dc.h>
#include "../../drivers/input/include/mouse.h" #include "../../drivers/input/include/mouse.h"
#include "objects.h" #include "objects.h"
#include "include/msgqueue.h"
/* GLOBALS *******************************************************************/
static BOOLEAN SafetySwitch = FALSE; static BOOLEAN SafetySwitch = FALSE;
static BOOLEAN SafetySwitch2 = FALSE; static BOOLEAN SafetySwitch2 = FALSE;
static BOOLEAN MouseEnabled = FALSE; static BOOLEAN MouseEnabled = FALSE;
static LONG mouse_x, mouse_y; static LONG mouse_x, mouse_y;
static UINT mouse_width = 0, mouse_height = 0; static UINT mouse_width = 0, mouse_height = 0;
static UCHAR DefaultCursor[256] = { static UCHAR DefaultCursor[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -75,17 +109,37 @@ static UCHAR DefaultCursor[256] = {
0x1F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xFF, 0xFF,
0x3F, 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; RECTL MouseRect;
LONG tmp; 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 (HazardX1 > HazardX2)
if(HazardY1 > HazardY2) { tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp; } {
tmp = HazardX2; HazardX2 = HazardX1; HazardX1 = tmp;
}
if (HazardY1 > HazardY2)
{
tmp = HazardY2; HazardY2 = HazardY1; HazardY1 = tmp;
}
if ((mouse_x + mouse_width >= HazardX1) && (mouse_x <= HazardX2) && if ((mouse_x + mouse_width >= HazardX1) && (mouse_x <= HazardX2) &&
(mouse_y + mouse_height >= HazardY1) && (mouse_y <= HazardY2)) (mouse_y + mouse_height >= HazardY1) && (mouse_y <= HazardY2))
@ -94,21 +148,31 @@ INT MouseSafetyOnDrawStart(PSURFOBJ SurfObj, PSURFGDI SurfGDI, LONG HazardX1, LO
SafetySwitch = TRUE; 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; 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; RECTL MouseRect;
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(SafetySwitch == TRUE) if (SafetySwitch)
{ {
SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect); SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect);
SafetySwitch = FALSE; SafetySwitch = FALSE;
@ -116,10 +180,14 @@ INT MouseSafetyOnDrawEnd(PSURFOBJ SurfObj, PSURFGDI SurfGDI)
SafetySwitch2 = 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; ULONG i;
LONG mouse_cx = 0, mouse_cy = 0; LONG mouse_cx = 0, mouse_cy = 0;
@ -128,14 +196,19 @@ VOID MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
PSURFOBJ SurfObj; PSURFOBJ SurfObj;
PSURFGDI SurfGDI; PSURFGDI SurfGDI;
RECTL MouseRect; 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; KeQueryTickCount(&LargeTickCount);
PFILE_OBJECT FileObject = NULL; TickCount = LargeTickCount.u.LowPart;
NTSTATUS status;
UNICODE_STRING ClassName;
IO_STATUS_BLOCK ioStatus;
KEVENT event;
PIRP irp;
if (hDC == 0) if (hDC == 0)
{ {
@ -146,41 +219,69 @@ VOID MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface); SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface);
SurfGDI = (PSURFGDI)AccessInternalObject(dc->Surface); SurfGDI = (PSURFGDI)AccessInternalObject(dc->Surface);
// Compile the total mouse movement change /* Compile the total mouse movement change and dispatch button events. */
for (i = 0; i < InputCount; i++) for (i = 0; i < InputCount; i++)
{ {
mouse_cx += Data[i].LastX; mouse_cx += Data[i].LastX;
mouse_cy += Data[i].LastY; 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;
Msg.wParam = ButtonsDown;
Msg.message = MouseButtonDownMessage[j];
MsqInsertSystemMessage(&Msg);
}
if (!(Data[i].ButtonData & (1 << j)) && (ButtonsDown & Flag))
{
ButtonsDown &= ~Flag;
Msg.wParam = ButtonsDown;
Msg.message = MouseButtonUpMessage[j];
MsqInsertSystemMessage(&Msg);
}
}
} }
if((mouse_cx != 0) || (mouse_cy != 0)) /* If the mouse moved then move the pointer. */
if (mouse_cx != 0 || mouse_cy != 0)
{ {
mouse_x += mouse_cx; mouse_x += mouse_cx;
mouse_y += mouse_cy; mouse_y += mouse_cy;
if(mouse_x < 0) mouse_x = 0; mouse_x = max(mouse_x, 0);
if(mouse_y < 0) mouse_y = 0; mouse_y = max(mouse_y, 0);
if(mouse_x > 620) mouse_x = 620; mouse_x = min(mouse_x, 620);
if(mouse_y > 460) mouse_y = 460; mouse_y = min(mouse_y, 460);
if((SafetySwitch == FALSE) && (SafetySwitch2 == FALSE)) ; if (SafetySwitch == FALSE && SafetySwitch2 == FALSE)
{
SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect); SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect);
} }
} }
}
VOID EnableMouse(HDC hDisplayDC) VOID
EnableMouse(HDC hDisplayDC)
{ {
PDC dc = DC_HandleToPtr(hDisplayDC); PDC dc = DC_HandleToPtr(hDisplayDC);
PSURFOBJ SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface); PSURFOBJ SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface);
PSURFGDI SurfGDI = (PSURFGDI)AccessInternalObject(dc->Surface); PSURFGDI SurfGDI = (PSURFGDI)AccessInternalObject(dc->Surface);
BOOL txt;
int i;
BRUSHOBJ Brush;
HBITMAP hMouseSurf; HBITMAP hMouseSurf;
PSURFOBJ MouseSurf; PSURFOBJ MouseSurf;
SIZEL MouseSize; SIZEL MouseSize;
POINTL ZeroPoint;
RECTL MouseRect; RECTL MouseRect;
/* Create the default mouse cursor. */ /* Create the default mouse cursor. */

View file

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

View file

@ -38,10 +38,10 @@ typedef struct _USER_MESSAGE_QUEUE
LIST_ENTRY SentMessagesListHead; LIST_ENTRY SentMessagesListHead;
/* Queue of messages posted to the queue. */ /* Queue of messages posted to the queue. */
LIST_ENTRY PostedMessagesListHead; LIST_ENTRY PostedMessagesListHead;
/* Queue of hardware messages for the queue. */
LIST_ENTRY HardwareMessagesListHead;
/* Queue of sent-message notifies for the queue. */ /* Queue of sent-message notifies for the queue. */
LIST_ENTRY NotifyMessagesListHead; LIST_ENTRY NotifyMessagesListHead;
/* Queue for hardware messages for the queue. */
LIST_ENTRY HardwareMessagesListHead;
/* Lock for the queue. */ /* Lock for the queue. */
FAST_MUTEX Lock; FAST_MUTEX Lock;
/* True if a WM_QUIT message is pending. */ /* True if a WM_QUIT message is pending. */
@ -76,8 +76,7 @@ VOID
MsqDestroyMessage(PUSER_MESSAGE Message); MsqDestroyMessage(PUSER_MESSAGE Message);
VOID VOID
MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue,
PUSER_MESSAGE Message, PUSER_MESSAGE Message);
BOOLEAN Hardware);
BOOLEAN BOOLEAN
MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue, MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
IN BOOLEAN Hardware, IN BOOLEAN Hardware,
@ -117,6 +116,10 @@ W32kSendMessage(HWND hWnd,
WPARAM wParam, WPARAM wParam,
LPARAM lParam, LPARAM lParam,
BOOL KernelMessage); BOOL KernelMessage);
VOID
MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
VOID
MsqInsertSystemMessage(MSG* Msg);
#define MAKE_LONG(x, y) ((((y) & 0xFFFF) << 16) | ((x) & 0xFFFF)) #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); INT cy, UINT flags);
BOOLEAN BOOLEAN
WinPosShowWindow(HWND Wnd, INT Cmd); 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -265,17 +265,10 @@ NtUserRegisterClassExWOW(LPWNDCLASSEX lpwcx,
return(Atom); return(Atom);
} }
DWORD STDCALL ULONG
NtUserGetClassLong(HWND hWnd, DWORD Offset) W32kGetClassLong(PWINDOW_OBJECT WindowObject, ULONG Offset)
{ {
PWINDOW_OBJECT WindowObject;
LONG Ret; LONG Ret;
WindowObject = W32kGetWindowObject(hWnd);
if (WindowObject == NULL)
{
return(0);
}
switch (Offset) switch (Offset)
{ {
case GCL_STYLE: case GCL_STYLE:
@ -288,15 +281,30 @@ NtUserGetClassLong(HWND hWnd, DWORD Offset)
Ret = WindowObject->Class->Class.cbClsExtra; Ret = WindowObject->Class->Class.cbClsExtra;
break; break;
case GCL_HMODULE: case GCL_HMODULE:
Ret = WindowObject->Class->Class.hInstance; Ret = (ULONG)WindowObject->Class->Class.hInstance;
break; break;
case GCL_HBRBACKGROUND: case GCL_HBRBACKGROUND:
Ret = WindowObject->Class->Class.hbrBackground; Ret = (ULONG)WindowObject->Class->Class.hbrBackground;
break; break;
default: default:
Ret = 0; Ret = 0;
break; 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); W32kReleaseWindowObject(WindowObject);
return(Ret); 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -55,7 +55,7 @@ KeyboardThreadMain(PVOID StartContext)
&KeyboardObjectAttributes, &KeyboardObjectAttributes,
&Iosb, &Iosb,
0, 0,
0); FILE_SYNCHRONOUS_IO_ALERT);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("W32K: Failed to open keyboard.\n"); DbgPrint("W32K: Failed to open keyboard.\n");
@ -164,7 +164,6 @@ InitInputImpl(VOID)
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("W32K: Failed to create keyboard thread.\n"); DbgPrint("W32K: Failed to create keyboard thread.\n");
NtClose(KeyboardThreadHandle);
} }
/* /*

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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -202,9 +202,7 @@ NtUserTranslateMessage(LPMSG lpMsg,
NewMsg.wParam = wp[0]; NewMsg.wParam = wp[0];
NewMsg.lParam = lpMsg->lParam; NewMsg.lParam = lpMsg->lParam;
UMsg = MsqCreateMessage(&NewMsg); UMsg = MsqCreateMessage(&NewMsg);
MsqPostMessage(PsGetWin32Thread()->MessageQueue, MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
UMsg,
FALSE);
return(TRUE); return(TRUE);
} }
} }
@ -217,9 +215,7 @@ NtUserTranslateMessage(LPMSG lpMsg,
NewMsg.lParam = lpMsg->lParam; NewMsg.lParam = lpMsg->lParam;
dead_char = wp[0]; dead_char = wp[0];
UMsg = MsqCreateMessage(&NewMsg); UMsg = MsqCreateMessage(&NewMsg);
MsqPostMessage(PsGetWin32Thread()->MessageQueue, MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
UMsg,
FALSE);
return(TRUE); return(TRUE);
} }
return(FALSE); 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -216,7 +216,7 @@ NtUserGetMessage(LPMSG lpMsg,
/* Nothing found so far. Wait for new messages. */ /* Nothing found so far. Wait for new messages. */
Status = MsqWaitForNewMessages(ThreadQueue); Status = MsqWaitForNewMessages(ThreadQueue);
} }
while (Status == STATUS_WAIT_0); while (Status >= STATUS_WAIT_0 && Status <= STATUS_WAIT_63);
return((BOOLEAN)(-1)); 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -15,13 +15,28 @@
#include <win32k/win32k.h> #include <win32k/win32k.h>
#include <include/msgqueue.h> #include <include/msgqueue.h>
#include <include/callback.h> #include <include/callback.h>
#include <include/window.h>
#include <include/winpos.h>
#include <include/class.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* GLOBALS *******************************************************************/ /* 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 *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -50,16 +65,273 @@ MsqDecPaintCountQueue(PUSER_MESSAGE_QUEUE Queue)
NTSTATUS NTSTATUS
MsqInitializeImpl(VOID) MsqInitializeImpl(VOID)
{ {
CurrentFocusMessageQueue = NULL; /*CurrentFocusMessageQueue = NULL;*/
InitializeListHead(&HardwareMessageQueueHead);
KeInitializeEvent(&HardwareMessageEvent, NotificationEvent, 0);
KeInitializeSpinLock(&SystemMessageQueueLock);
ExInitializeFastMutex(&HardwareMessageQueueLock);
return(STATUS_SUCCESS); 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 VOID
MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
#if 0
MSG Msg; MSG Msg;
PUSER_MESSAGE Message; PUSER_MESSAGE Message;
if (CurrentFocusMessageQueue == NULL)
{
return;
}
Msg.hwnd = CurrentFocusMessageQueue->FocusWindow; Msg.hwnd = CurrentFocusMessageQueue->FocusWindow;
Msg.message = uMsg; Msg.message = uMsg;
Msg.wParam = wParam; Msg.wParam = wParam;
@ -68,6 +340,7 @@ MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)
Message = MsqCreateMessage(&Msg); Message = MsqCreateMessage(&Msg);
MsqPostMessage(CurrentFocusMessageQueue, Message, TRUE); MsqPostMessage(CurrentFocusMessageQueue, Message, TRUE);
#endif
} }
VOID VOID
@ -203,21 +476,11 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
} }
VOID VOID
MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, MsqPostMessage(PUSER_MESSAGE_QUEUE MessageQueue, PUSER_MESSAGE Message)
PUSER_MESSAGE Message,
BOOLEAN Hardware)
{ {
ExAcquireFastMutex(&MessageQueue->Lock); ExAcquireFastMutex(&MessageQueue->Lock);
if (Hardware)
{
InsertTailList(&MessageQueue->HardwareMessagesListHead,
&Message->ListEntry);
}
else
{
InsertTailList(&MessageQueue->PostedMessagesListHead, InsertTailList(&MessageQueue->PostedMessagesListHead,
&Message->ListEntry); &Message->ListEntry);
}
KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE); KeSetEvent(&MessageQueue->NewMessages, IO_NO_INCREMENT, FALSE);
ExReleaseFastMutex(&MessageQueue->Lock); ExReleaseFastMutex(&MessageQueue->Lock);
} }
@ -235,17 +498,16 @@ MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
PUSER_MESSAGE CurrentMessage; PUSER_MESSAGE CurrentMessage;
PLIST_ENTRY ListHead; PLIST_ENTRY ListHead;
ExAcquireFastMutex(&MessageQueue->Lock);
if (Hardware) if (Hardware)
{ {
CurrentEntry = MessageQueue->HardwareMessagesListHead.Flink; return(MsqPeekHardwareMessage(MessageQueue, Wnd,
ListHead = &MessageQueue->HardwareMessagesListHead; MsgFilterLow, MsgFilterHigh,
Remove, Message));
} }
else
{ ExAcquireFastMutex(&MessageQueue->Lock);
CurrentEntry = MessageQueue->PostedMessagesListHead.Flink; CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
ListHead = &MessageQueue->PostedMessagesListHead; ListHead = &MessageQueue->PostedMessagesListHead;
}
while (CurrentEntry != ListHead) while (CurrentEntry != ListHead)
{ {
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE, CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
@ -272,10 +534,14 @@ MsqFindMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
NTSTATUS NTSTATUS
MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue) MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue)
{ {
return(KeWaitForSingleObject(&MessageQueue->NewMessages, PVOID WaitObjects[2] = {&MessageQueue->NewMessages, &HardwareMessageEvent};
0, return(KeWaitForMultipleObjects(2,
WaitObjects,
WaitAny,
Executive,
UserMode, UserMode,
TRUE, TRUE,
NULL,
NULL)); NULL));
} }
@ -283,8 +549,8 @@ VOID
MsqInitializeMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) MsqInitializeMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
{ {
InitializeListHead(&MessageQueue->PostedMessagesListHead); InitializeListHead(&MessageQueue->PostedMessagesListHead);
InitializeListHead(&MessageQueue->HardwareMessagesListHead);
InitializeListHead(&MessageQueue->SentMessagesListHead); InitializeListHead(&MessageQueue->SentMessagesListHead);
InitializeListHead(&MessageQueue->HardwareMessagesListHead);
ExInitializeFastMutex(&MessageQueue->Lock); ExInitializeFastMutex(&MessageQueue->Lock);
MessageQueue->QuitPosted = FALSE; MessageQueue->QuitPosted = FALSE;
MessageQueue->QuitExitCode = 0; MessageQueue->QuitExitCode = 0;
@ -307,15 +573,6 @@ MsqFreeMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
CurrentEntry = CurrentEntry->Flink; CurrentEntry = CurrentEntry->Flink;
ExFreePool(CurrentMessage); 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 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -546,7 +546,6 @@ PaintingFindWinToRepaint(HWND hWnd, PW32THREAD Thread)
PWINDOW_OBJECT BaseWindow; PWINDOW_OBJECT BaseWindow;
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
HWND hFoundWnd = NULL; HWND hFoundWnd = NULL;
NTSTATUS Status;
if (hWnd == NULL) 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -901,8 +901,6 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index)
NTSTATUS Status; NTSTATUS Status;
DWORD Result; DWORD Result;
DPRINT("NtUserGetWindowLong(hWnd %X, Index %d)\n", hWnd, Index);
W32kGuiCheck(); W32kGuiCheck();
Status = Status =
@ -912,7 +910,6 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index)
(PVOID*)&WindowObject); (PVOID*)&WindowObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT("NtUserGetWindowLong(): Bad handle.\n");
return(0); return(0);
} }
@ -945,7 +942,6 @@ NtUserGetWindowLong(HWND hWnd, DWORD Index)
} }
ObmDereferenceObject(WindowObject); ObmDereferenceObject(WindowObject);
DPRINT("NtUserGetWindowLong(): %X\n", Result);
return(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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -59,10 +59,11 @@ NtUserGetClientOrigin(HWND hWnd, LPPOINT Point)
WindowObject = W32kGetWindowObject(hWnd); WindowObject = W32kGetWindowObject(hWnd);
if (WindowObject == NULL) if (WindowObject == NULL)
{ {
return(FALSE); Point->x = Point->y = 0;
return(TRUE);
} }
Point->x = WindowObject->ClientRect.left; Point->x = WindowObject->ClientRect.left;
Point->y = WindowObject->ClientRect.right; Point->y = WindowObject->ClientRect.top;
return(TRUE); return(TRUE);
} }
@ -729,3 +730,99 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
ObmDereferenceObject(Window); ObmDereferenceObject(Window);
return(WasVisible); 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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -844,6 +844,7 @@ W32kInitializeDesktopGraphics(VOID)
ScreenDeviceContext = W32kCreateDC(L"DISPLAY", NULL, NULL, NULL); ScreenDeviceContext = W32kCreateDC(L"DISPLAY", NULL, NULL, NULL);
GDIOBJ_MarkObjectGlobal(ScreenDeviceContext); GDIOBJ_MarkObjectGlobal(ScreenDeviceContext);
EnableMouse(ScreenDeviceContext); EnableMouse(ScreenDeviceContext);
NtUserAcquireOrReleaseInputOwnership(FALSE);
} }
HDC HDC