+/*
+ * 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,
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->iType != STYPE_DEVICE) || (MouseEnabled == FALSE)) return 0;
+ if (SurfObj == NULL)
+ {
+ return(FALSE);
+ }
- 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;
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)
{
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;
+
+ 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;
- // Compile the total mouse movement change
- for (i=0; i<InputCount; i++)
- {
- mouse_cx += Data[i].LastX;
- mouse_cy += Data[i].LastY;
- }
-
- if((mouse_cx != 0) || (mouse_cy != 0))
- {
- mouse_x += mouse_cx;
- mouse_y += mouse_cy;
-
- 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;
-
- if((SafetySwitch == FALSE) && (SafetySwitch2 == FALSE)) ;
- SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect);
- }
+ 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 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. */
PWNDCLASS_OBJECT
W32kCreateClass(LPWNDCLASSEX lpwcx,
BOOL bUnicodeClass);
+struct _WINDOW_OBJECT;
+ULONG
+W32kGetClassLong(struct _WINDOW_OBJECT* WindowObject, ULONG Offset);
#endif /* __WIN32K_CLASS_H */
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. */
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,
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))
INT cy, UINT flags);
BOOLEAN
WinPosShowWindow(HWND Wnd, INT Cmd);
+USHORT
+WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, POINT WinPoint,
+ PWINDOW_OBJECT* Window);
-/* $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
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:
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);
}
-/* $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
&KeyboardObjectAttributes,
&Iosb,
0,
- 0);
+ FILE_SYNCHRONOUS_IO_ALERT);
if (!NT_SUCCESS(Status))
{
DbgPrint("W32K: Failed to open keyboard.\n");
if (!NT_SUCCESS(Status))
{
DbgPrint("W32K: Failed to create keyboard thread.\n");
- NtClose(KeyboardThreadHandle);
}
/*
DbgPrint("W32K: Failed to connect to mouse driver.\n");
return(Status);
}
-
+
return(STATUS_SUCCESS);
}
-/* $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
NewMsg.wParam = wp[0];
NewMsg.lParam = lpMsg->lParam;
UMsg = MsqCreateMessage(&NewMsg);
- MsqPostMessage(PsGetWin32Thread()->MessageQueue,
- UMsg,
- FALSE);
+ MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
return(TRUE);
}
}
NewMsg.lParam = lpMsg->lParam;
dead_char = wp[0];
UMsg = MsqCreateMessage(&NewMsg);
- MsqPostMessage(PsGetWin32Thread()->MessageQueue,
- UMsg,
- FALSE);
+ MsqPostMessage(PsGetWin32Thread()->MessageQueue, UMsg);
return(TRUE);
}
return(FALSE);
-/* $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
/* 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));
}
-/* $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
#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 *****************************************************************/
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;
Message = MsqCreateMessage(&Msg);
MsqPostMessage(CurrentFocusMessageQueue, Message, TRUE);
+#endif
}
VOID
}
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);
}
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,
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;
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
-/* $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
PWINDOW_OBJECT BaseWindow;
PLIST_ENTRY current_entry;
HWND hFoundWnd = NULL;
- NTSTATUS Status;
if (hWnd == NULL)
{
-/* $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
NTSTATUS Status;
DWORD Result;
- DPRINT("NtUserGetWindowLong(hWnd %X, Index %d)\n", hWnd, Index);
-
W32kGuiCheck();
Status =
(PVOID*)&WindowObject);
if (!NT_SUCCESS(Status))
{
- DPRINT("NtUserGetWindowLong(): Bad handle.\n");
return(0);
}
}
ObmDereferenceObject(WindowObject);
- DPRINT("NtUserGetWindowLong(): %X\n", Result);
return(Result);
}
-/* $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
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);
}
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);
+}
-/* $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
ScreenDeviceContext = W32kCreateDC(L"DISPLAY", NULL, NULL, NULL);
GDIOBJ_MarkObjectGlobal(ScreenDeviceContext);
EnableMouse(ScreenDeviceContext);
+ NtUserAcquireOrReleaseInputOwnership(FALSE);
}
HDC