mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 02:26:03 +00:00
Patch by Filip Navaraf: Removed the mouse class gdi callback
svn path=/trunk/; revision=10317
This commit is contained in:
parent
6a79a66086
commit
61430b7b65
4 changed files with 216 additions and 404 deletions
|
@ -19,119 +19,77 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
BOOLEAN AlreadyOpened = FALSE;
|
||||
|
||||
VOID MouseClassPassiveCallback(PDEVICE_OBJECT ClassDeviceObject, PVOID Context)
|
||||
{
|
||||
PDEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension;
|
||||
MOUSE_INPUT_DATA PortData[MOUSE_BUFFER_SIZE];
|
||||
ULONG InputCount;
|
||||
KIRQL OldIrql;
|
||||
|
||||
assert(NULL != ClassDeviceExtension->GDIInformation.CallBack);
|
||||
KeAcquireSpinLock(&(ClassDeviceExtension->SpinLock), &OldIrql);
|
||||
DPRINT("Entering MouseClassPassiveCallback\n");
|
||||
while (0 != ClassDeviceExtension->InputCount) {
|
||||
ClassDeviceExtension->PortData -= ClassDeviceExtension->InputCount;
|
||||
RtlMoveMemory(PortData, ClassDeviceExtension->PortData,
|
||||
ClassDeviceExtension->InputCount * sizeof(MOUSE_INPUT_DATA));
|
||||
InputCount = ClassDeviceExtension->InputCount;
|
||||
ClassDeviceExtension->InputCount = 0;
|
||||
KeReleaseSpinLock(&(ClassDeviceExtension->SpinLock), OldIrql);
|
||||
|
||||
DPRINT("MouseClassPassiveCallBack() Calling GDI callback at %p\n",
|
||||
ClassDeviceExtension->GDIInformation.CallBack);
|
||||
/* We're jumping through hoops to get to run at PASSIVE_LEVEL, let's make
|
||||
sure we succeeded */
|
||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
||||
(*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack)
|
||||
(PortData, InputCount);
|
||||
|
||||
KeAcquireSpinLock(&(ClassDeviceExtension->SpinLock), &OldIrql);
|
||||
}
|
||||
|
||||
ClassDeviceExtension->PassiveCallbackQueued = FALSE;
|
||||
DPRINT("Leaving MouseClassPassiveCallback\n");
|
||||
KeReleaseSpinLock(&(ClassDeviceExtension->SpinLock), OldIrql);
|
||||
}
|
||||
|
||||
BOOLEAN MouseClassCallBack(PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA MouseDataStart,
|
||||
PMOUSE_INPUT_DATA MouseDataEnd, PULONG InputCount)
|
||||
BOOLEAN MouseClassCallBack(
|
||||
PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA MouseDataStart,
|
||||
PMOUSE_INPUT_DATA MouseDataEnd, PULONG InputCount)
|
||||
{
|
||||
PDEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension;
|
||||
ULONG ReadSize;
|
||||
PIRP Irp;
|
||||
KIRQL OldIrql;
|
||||
|
||||
// In classical NT, you would take the input data and pipe it through the IO system, for the GDI to read.
|
||||
// In ReactOS, however, we use a GDI callback for increased mouse responsiveness. The reason we don't
|
||||
// simply call from the port driver is so that our mouse class driver can support NT mouse port drivers.
|
||||
PIO_STACK_LOCATION Stack;
|
||||
ULONG SafeInputCount = *InputCount;
|
||||
ULONG ReadSize;
|
||||
|
||||
DPRINT("Entering MouseClassCallBack\n");
|
||||
/* if(ClassDeviceExtension->ReadIsPending == TRUE)
|
||||
if (ClassDeviceExtension->ReadIsPending == TRUE)
|
||||
{
|
||||
Irp = ClassDeviceObject->CurrentIrp;
|
||||
ClassDeviceObject->CurrentIrp = NULL;
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
ReadSize = sizeof(MOUSE_INPUT_DATA) * (*InputCount);
|
||||
/* A read request is waiting for input, so go straight to it */
|
||||
RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, MouseDataStart,
|
||||
sizeof(MOUSE_INPUT_DATA));
|
||||
|
||||
// A read request is waiting for input, so go straight to it
|
||||
RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, (PCHAR)MouseDataStart, ReadSize);
|
||||
|
||||
// Go to next packet and complete this request with STATUS_SUCCESS
|
||||
/* Go to next packet and complete this request with STATUS_SUCCESS */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = ReadSize;
|
||||
Stack->Parameters.Read.Length = ReadSize;
|
||||
Irp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA);
|
||||
Stack->Parameters.Read.Length = sizeof(MOUSE_INPUT_DATA);
|
||||
|
||||
IoStartNextPacket(ClassDeviceObject, FALSE);
|
||||
IoCompleteRequest(Irp, IO_MOUSE_INCREMENT);
|
||||
ClassDeviceExtension->ReadIsPending = FALSE;
|
||||
} */
|
||||
|
||||
// If we have data from the port driver and a higher service to send the data to
|
||||
if((*InputCount>0) && (*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack != NULL))
|
||||
{
|
||||
KeAcquireSpinLock(&(ClassDeviceExtension->SpinLock), &OldIrql);
|
||||
/* Skip the packet we just sent away */
|
||||
MouseDataStart++;
|
||||
SafeInputCount--;
|
||||
}
|
||||
|
||||
if(ClassDeviceExtension->InputCount + *InputCount > MOUSE_BUFFER_SIZE)
|
||||
{
|
||||
ReadSize = MOUSE_BUFFER_SIZE - ClassDeviceExtension->InputCount;
|
||||
} else {
|
||||
ReadSize = *InputCount;
|
||||
}
|
||||
/* If we have data from the port driver and a higher service to send the data to */
|
||||
if (SafeInputCount != 0)
|
||||
{
|
||||
KeAcquireSpinLock(&ClassDeviceExtension->SpinLock, &OldIrql);
|
||||
|
||||
// FIXME: If we exceed the buffer, mouse data gets thrown away.. better solution?
|
||||
|
||||
|
||||
// Move the mouse input data from the port data queue to our class data queue
|
||||
RtlMoveMemory(ClassDeviceExtension->PortData, (PCHAR)MouseDataStart,
|
||||
sizeof(MOUSE_INPUT_DATA) * ReadSize);
|
||||
|
||||
// Move the pointer and counter up
|
||||
ClassDeviceExtension->PortData += ReadSize;
|
||||
ClassDeviceExtension->InputCount += ReadSize;
|
||||
|
||||
if(*(PGDI_SERVICE_CALLBACK_ROUTINE)ClassDeviceExtension->GDIInformation.CallBack != NULL) {
|
||||
if (! ClassDeviceExtension->PassiveCallbackQueued) {
|
||||
if (NULL == ClassDeviceExtension->WorkItem) {
|
||||
ClassDeviceExtension->WorkItem = IoAllocateWorkItem(ClassDeviceObject);
|
||||
}
|
||||
if (NULL != ClassDeviceExtension->WorkItem) {
|
||||
DPRINT("Queueing workitem\n");
|
||||
IoQueueWorkItem(ClassDeviceExtension->WorkItem, MouseClassPassiveCallback, CriticalWorkQueue, NULL);
|
||||
ClassDeviceExtension->PassiveCallbackQueued = TRUE;
|
||||
}
|
||||
if (ClassDeviceExtension->InputCount + SafeInputCount > MOUSE_BUFFER_SIZE)
|
||||
{
|
||||
ReadSize = MOUSE_BUFFER_SIZE - ClassDeviceExtension->InputCount;
|
||||
} else {
|
||||
ReadSize = SafeInputCount;
|
||||
}
|
||||
} else {
|
||||
DPRINT("MouseClassCallBack() NO GDI callback installed\n");
|
||||
}
|
||||
KeReleaseSpinLock(&(ClassDeviceExtension->SpinLock), OldIrql);
|
||||
} else {
|
||||
DPRINT("MouseClassCallBack() entered, InputCount = %d - DOING NOTHING\n", *InputCount);
|
||||
}
|
||||
|
||||
DPRINT("Leaving MouseClassCallBack\n");
|
||||
return TRUE;
|
||||
/*
|
||||
* FIXME: If we exceed the buffer, mouse data gets thrown away.. better
|
||||
* solution?
|
||||
*/
|
||||
|
||||
/*
|
||||
* Move the mouse input data from the port data queue to our class data
|
||||
* queue.
|
||||
*/
|
||||
RtlMoveMemory(ClassDeviceExtension->PortData, (PCHAR)MouseDataStart,
|
||||
sizeof(MOUSE_INPUT_DATA) * ReadSize);
|
||||
|
||||
/* Move the pointer and counter up */
|
||||
ClassDeviceExtension->PortData += ReadSize;
|
||||
ClassDeviceExtension->InputCount += ReadSize;
|
||||
|
||||
KeReleaseSpinLock(&ClassDeviceExtension->SpinLock, OldIrql);
|
||||
} else {
|
||||
DPRINT("MouseClassCallBack() entered, InputCount = %d - DOING NOTHING\n", *InputCount);
|
||||
}
|
||||
|
||||
DPRINT("Leaving MouseClassCallBack\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS ConnectMousePortDriver(PDEVICE_OBJECT ClassDeviceObject)
|
||||
|
@ -146,8 +104,6 @@ NTSTATUS ConnectMousePortDriver(PDEVICE_OBJECT ClassDeviceObject)
|
|||
CLASS_INFORMATION ClassInformation;
|
||||
PDEVICE_EXTENSION DeviceExtension = ClassDeviceObject->DeviceExtension;
|
||||
|
||||
DeviceExtension->GDIInformation.CallBack = NULL;
|
||||
|
||||
// Get the port driver's DeviceObject
|
||||
// FIXME: The name might change.. find a way to be more dynamic?
|
||||
|
||||
|
@ -195,147 +151,90 @@ NTSTATUS STDCALL MouseClassDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
NTSTATUS Status;
|
||||
|
||||
switch (Stack->MajorFunction)
|
||||
{
|
||||
{
|
||||
case IRP_MJ_CREATE:
|
||||
if (AlreadyOpened == TRUE)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
AlreadyOpened = TRUE;
|
||||
}
|
||||
break;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IRP_MJ_CLOSE:
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
Status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IRP_MJ_READ:
|
||||
|
||||
if (Stack->Parameters.Read.Length == 0) {
|
||||
Status = STATUS_SUCCESS;
|
||||
} else {
|
||||
Status = STATUS_PENDING;
|
||||
}
|
||||
break;
|
||||
if (Stack->Parameters.Read.Length < sizeof(MOUSE_INPUT_DATA))
|
||||
{
|
||||
Status = STATUS_BUFFER_TOO_SMALL;
|
||||
break;
|
||||
}
|
||||
IoMarkIrpPending(Irp);
|
||||
IoStartPacket(DeviceObject, Irp, NULL, NULL);
|
||||
return STATUS_PENDING;
|
||||
|
||||
default:
|
||||
DPRINT1("NOT IMPLEMENTED\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
DPRINT1("NOT IMPLEMENTED\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
if (Status==STATUS_PENDING)
|
||||
{
|
||||
IoMarkIrpPending(Irp);
|
||||
IoStartPacket(DeviceObject, Irp, NULL, NULL);
|
||||
} else {
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
return(Status);
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID MouseClassStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
VOID STDCALL
|
||||
MouseClassStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
ULONG ReadSize;
|
||||
|
||||
if(DeviceExtension->InputCount>0)
|
||||
if (DeviceExtension->InputCount > 0)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
// FIXME: We should not send too much input data.. depends on the max buffer size of the win32k
|
||||
ReadSize = DeviceExtension->InputCount * sizeof(MOUSE_INPUT_DATA);
|
||||
|
||||
// Bring the PortData back to base so that it can be copied
|
||||
DeviceExtension->PortData -= DeviceExtension->InputCount;
|
||||
DeviceExtension->InputCount = 0;
|
||||
KeAcquireSpinLock(&DeviceExtension->SpinLock, &oldIrql);
|
||||
|
||||
RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
|
||||
DeviceExtension->PortData - DeviceExtension->InputCount,
|
||||
sizeof(MOUSE_INPUT_DATA));
|
||||
|
||||
if (DeviceExtension->InputCount > 1)
|
||||
{
|
||||
RtlMoveMemory(
|
||||
DeviceExtension->PortData - DeviceExtension->InputCount,
|
||||
DeviceExtension->PortData - DeviceExtension->InputCount + 1,
|
||||
(DeviceExtension->InputCount - 1) * sizeof(MOUSE_INPUT_DATA));
|
||||
}
|
||||
DeviceExtension->PortData--;
|
||||
DeviceExtension->InputCount--;
|
||||
DeviceExtension->ReadIsPending = FALSE;
|
||||
|
||||
RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, (PCHAR)DeviceExtension->PortData, ReadSize);
|
||||
|
||||
// Go to next packet and complete this request with STATUS_SUCCESS
|
||||
/* Go to next packet and complete this request with STATUS_SUCCESS */
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
|
||||
Irp->IoStatus.Information = ReadSize;
|
||||
Stack->Parameters.Read.Length = ReadSize;
|
||||
Irp->IoStatus.Information = sizeof(MOUSE_INPUT_DATA);
|
||||
Stack->Parameters.Read.Length = sizeof(MOUSE_INPUT_DATA);
|
||||
IoCompleteRequest(Irp, IO_MOUSE_INCREMENT);
|
||||
oldIrql = KeGetCurrentIrql();
|
||||
if (oldIrql < DISPATCH_LEVEL)
|
||||
{
|
||||
KeRaiseIrql (DISPATCH_LEVEL, &oldIrql);
|
||||
IoStartNextPacket (DeviceObject, FALSE);
|
||||
KeLowerIrql(oldIrql);
|
||||
}
|
||||
else
|
||||
{
|
||||
IoStartNextPacket (DeviceObject, FALSE);
|
||||
}
|
||||
|
||||
IoStartNextPacket(DeviceObject, FALSE);
|
||||
KeReleaseSpinLock(&DeviceExtension->SpinLock, oldIrql);
|
||||
} else {
|
||||
DeviceExtension->ReadIsPending = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL MouseClassInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
|
||||
{
|
||||
// Retrieve GDI's callback
|
||||
|
||||
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
NTSTATUS status;
|
||||
|
||||
switch(Stack->Parameters.DeviceIoControl.IoControlCode)
|
||||
{
|
||||
case IOCTL_INTERNAL_MOUSE_CONNECT:
|
||||
|
||||
DeviceExtension->GDIInformation =
|
||||
*((PGDI_INFORMATION)Stack->Parameters.DeviceIoControl.Type3InputBuffer);
|
||||
|
||||
DPRINT("MouseClassInternalDeviceControl() installed GDI callback at %p\n", DeviceExtension->GDIInformation.CallBack);
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
case IOCTL_INTERNAL_MOUSE_DISCONNECT:
|
||||
|
||||
DeviceExtension->GDIInformation.CallBack = NULL;
|
||||
|
||||
status = STATUS_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
break;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = status;
|
||||
if (status == STATUS_PENDING) {
|
||||
IoMarkIrpPending(Irp);
|
||||
IoStartPacket(DeviceObject, Irp, NULL, NULL);
|
||||
} else {
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
UNICODE_STRING DeviceName = ROS_STRING_INITIALIZER(L"\\Device\\MouseClass");
|
||||
UNICODE_STRING SymlinkName = ROS_STRING_INITIALIZER(L"\\??\\MouseClass"); NTSTATUS Status;
|
||||
|
||||
UNICODE_STRING DeviceName = ROS_STRING_INITIALIZER(L"\\Device\\Mouse");
|
||||
UNICODE_STRING SymlinkName = ROS_STRING_INITIALIZER(L"\\??\\Mouse");
|
||||
NTSTATUS Status;
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = MouseClassDispatch;
|
||||
// DriverObject->MajorFunction[IRP_MJ_CLOSE] = MouseClassDispatch;
|
||||
// DriverObject->MajorFunction[IRP_MJ_READ] = MouseClassDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = MouseClassInternalDeviceControl; // to get GDI callback
|
||||
// DriverObject->DriverStartIo = MouseClassStartIo;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MouseClassDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_READ] = MouseClassDispatch;
|
||||
DriverObject->DriverStartIo = MouseClassStartIo;
|
||||
|
||||
Status = IoCreateDevice(DriverObject,
|
||||
sizeof(DEVICE_EXTENSION),
|
||||
|
@ -345,24 +244,26 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
|||
TRUE,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
|
||||
|
||||
Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
IoDeleteDevice(DeviceObject);
|
||||
return(Status);
|
||||
}
|
||||
{
|
||||
IoDeleteDevice(DeviceObject);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = ConnectMousePortDriver(DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
IoDeleteSymbolicLink(&SymlinkName);
|
||||
IoDeleteDevice(DeviceObject);
|
||||
return(Status);
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
{
|
||||
IoDeleteSymbolicLink(&SymlinkName);
|
||||
IoDeleteDevice(DeviceObject);
|
||||
return Status;
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -6,5 +6,4 @@ typedef struct _DEVICE_EXTENSION {
|
|||
ULONG InputCount;
|
||||
PMOUSE_INPUT_DATA PortData;
|
||||
PDEVICE_OBJECT PortDeviceObject; // FIXME: Expand this to handle multiple port drivers (make *PortDeviceObject)
|
||||
GDI_INFORMATION GDIInformation;
|
||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* 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.76 2004/07/14 20:48:57 navaraf Exp $
|
||||
/* $Id: mouse.c,v 1.77 2004/07/30 09:42:11 weiden Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* PURPOSE: Mouse
|
||||
|
@ -243,103 +243,6 @@ MouseSafetyOnDrawEnd(SURFOBJ *SurfObj)
|
|||
return(TRUE);
|
||||
}
|
||||
|
||||
#define ClearMouseInput(mi) \
|
||||
mi.dx = 0; \
|
||||
mi.dy = 0; \
|
||||
mi.mouseData = 0; \
|
||||
mi.dwFlags = 0;
|
||||
|
||||
#define SendMouseEvent(mi) \
|
||||
if(mi.dx != 0 || mi.dy != 0) \
|
||||
mi.dwFlags |= MOUSEEVENTF_MOVE; \
|
||||
if(mi.dwFlags) \
|
||||
IntMouseInput(&mi); \
|
||||
ClearMouseInput(mi);
|
||||
|
||||
VOID /* STDCALL */
|
||||
MouseGDICallBack(PMOUSE_INPUT_DATA Data, ULONG InputCount)
|
||||
{
|
||||
PMOUSE_INPUT_DATA mid;
|
||||
MOUSEINPUT mi;
|
||||
ULONG i;
|
||||
|
||||
ClearMouseInput(mi);
|
||||
mi.time = 0;
|
||||
mi.dwExtraInfo = 0;
|
||||
for(i = 0; i < InputCount; i++)
|
||||
{
|
||||
mid = (Data + i);
|
||||
mi.dx += mid->LastX;
|
||||
mi.dy += mid->LastY;
|
||||
|
||||
if(mid->ButtonFlags)
|
||||
{
|
||||
if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN)
|
||||
{
|
||||
mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_UP)
|
||||
{
|
||||
mi.dwFlags |= MOUSEEVENTF_LEFTUP;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN)
|
||||
{
|
||||
mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_UP)
|
||||
{
|
||||
mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN)
|
||||
{
|
||||
mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_UP)
|
||||
{
|
||||
mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_BUTTON_4_DOWN)
|
||||
{
|
||||
mi.mouseData |= XBUTTON1;
|
||||
mi.dwFlags |= MOUSEEVENTF_XDOWN;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_BUTTON_4_UP)
|
||||
{
|
||||
mi.mouseData |= XBUTTON1;
|
||||
mi.dwFlags |= MOUSEEVENTF_XUP;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_BUTTON_5_DOWN)
|
||||
{
|
||||
mi.mouseData |= XBUTTON2;
|
||||
mi.dwFlags |= MOUSEEVENTF_XDOWN;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_BUTTON_5_UP)
|
||||
{
|
||||
mi.mouseData |= XBUTTON2;
|
||||
mi.dwFlags |= MOUSEEVENTF_XUP;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_WHEEL)
|
||||
{
|
||||
mi.mouseData = mid->ButtonData;
|
||||
mi.dwFlags |= MOUSEEVENTF_WHEEL;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
|
||||
/* SOFTWARE MOUSE POINTER IMPLEMENTATION **************************************/
|
||||
|
||||
VOID FASTCALL
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: input.c,v 1.36 2004/07/04 01:23:32 navaraf Exp $
|
||||
/* $Id: input.c,v 1.37 2004/07/30 09:42:11 weiden Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -34,13 +34,9 @@
|
|||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
#define ENABLEMOUSEGDICALLBACK 1
|
||||
|
||||
static HANDLE MouseDeviceHandle;
|
||||
#if !ENABLEMOUSEGDICALLBACK
|
||||
static HANDLE MouseThreadHandle;
|
||||
static CLIENT_ID MouseThreadId;
|
||||
#endif
|
||||
static HANDLE KeyboardThreadHandle;
|
||||
static CLIENT_ID KeyboardThreadId;
|
||||
static HANDLE KeyboardDeviceHandle;
|
||||
|
@ -50,8 +46,104 @@ PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue = 0;
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
#if !ENABLEMOUSEGDICALLBACK
|
||||
VOID STDCALL_FUNC STATIC
|
||||
#define ClearMouseInput(mi) \
|
||||
mi.dx = 0; \
|
||||
mi.dy = 0; \
|
||||
mi.mouseData = 0; \
|
||||
mi.dwFlags = 0;
|
||||
|
||||
#define SendMouseEvent(mi) \
|
||||
if(mi.dx != 0 || mi.dy != 0) \
|
||||
mi.dwFlags |= MOUSEEVENTF_MOVE; \
|
||||
if(mi.dwFlags) \
|
||||
IntMouseInput(&mi); \
|
||||
ClearMouseInput(mi);
|
||||
|
||||
VOID FASTCALL
|
||||
ProcessMouseInputData(PMOUSE_INPUT_DATA Data, ULONG InputCount)
|
||||
{
|
||||
PMOUSE_INPUT_DATA mid;
|
||||
MOUSEINPUT mi;
|
||||
ULONG i;
|
||||
|
||||
ClearMouseInput(mi);
|
||||
mi.time = 0;
|
||||
mi.dwExtraInfo = 0;
|
||||
for(i = 0; i < InputCount; i++)
|
||||
{
|
||||
mid = (Data + i);
|
||||
mi.dx += mid->LastX;
|
||||
mi.dy += mid->LastY;
|
||||
|
||||
if(mid->ButtonFlags)
|
||||
{
|
||||
if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_DOWN)
|
||||
{
|
||||
mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_LEFT_BUTTON_UP)
|
||||
{
|
||||
mi.dwFlags |= MOUSEEVENTF_LEFTUP;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN)
|
||||
{
|
||||
mi.dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_MIDDLE_BUTTON_UP)
|
||||
{
|
||||
mi.dwFlags |= MOUSEEVENTF_MIDDLEUP;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN)
|
||||
{
|
||||
mi.dwFlags |= MOUSEEVENTF_RIGHTDOWN;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_RIGHT_BUTTON_UP)
|
||||
{
|
||||
mi.dwFlags |= MOUSEEVENTF_RIGHTUP;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_BUTTON_4_DOWN)
|
||||
{
|
||||
mi.mouseData |= XBUTTON1;
|
||||
mi.dwFlags |= MOUSEEVENTF_XDOWN;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_BUTTON_4_UP)
|
||||
{
|
||||
mi.mouseData |= XBUTTON1;
|
||||
mi.dwFlags |= MOUSEEVENTF_XUP;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_BUTTON_5_DOWN)
|
||||
{
|
||||
mi.mouseData |= XBUTTON2;
|
||||
mi.dwFlags |= MOUSEEVENTF_XDOWN;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_BUTTON_5_UP)
|
||||
{
|
||||
mi.mouseData |= XBUTTON2;
|
||||
mi.dwFlags |= MOUSEEVENTF_XUP;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
if(mid->ButtonFlags & MOUSE_WHEEL)
|
||||
{
|
||||
mi.mouseData = mid->ButtonData;
|
||||
mi.dwFlags |= MOUSEEVENTF_WHEEL;
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SendMouseEvent(mi);
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
MouseThreadMain(PVOID StartContext)
|
||||
{
|
||||
UNICODE_STRING MouseDeviceName;
|
||||
|
@ -121,12 +213,11 @@ MouseThreadMain(PVOID StartContext)
|
|||
}
|
||||
DPRINT("MouseEvent\n");
|
||||
|
||||
MouseGDICallBack(&MouseInput, sizeof(MOUSE_INPUT_DATA));
|
||||
ProcessMouseInputData(&MouseInput, Iosb.Information / sizeof(MOUSE_INPUT_DATA));
|
||||
}
|
||||
DPRINT("Mouse Input Thread Stopped...\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC VOID STDCALL
|
||||
KeyboardThreadMain(PVOID StartContext)
|
||||
|
@ -323,16 +414,6 @@ NTSTATUS FASTCALL
|
|||
InitInputImpl(VOID)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
#if ENABLEMOUSEGDICALLBACK
|
||||
UNICODE_STRING MouseDeviceName;
|
||||
OBJECT_ATTRIBUTES MouseObjectAttributes;
|
||||
IO_STATUS_BLOCK Iosb;
|
||||
PIRP Irp;
|
||||
PFILE_OBJECT FileObject;
|
||||
GDI_INFORMATION GdiInfo;
|
||||
KEVENT IoEvent;
|
||||
PIO_STACK_LOCATION StackPtr;
|
||||
#endif
|
||||
|
||||
KeInitializeEvent(&InputThreadsStart, NotificationEvent, FALSE);
|
||||
|
||||
|
@ -351,78 +432,7 @@ InitInputImpl(VOID)
|
|||
/* Initialize the default keyboard layout */
|
||||
(VOID)W32kGetDefaultKeyLayout();
|
||||
|
||||
#if ENABLEMOUSEGDICALLBACK
|
||||
/*
|
||||
* Connect to the mouse class driver.
|
||||
* Failures here don't result in a failure return, the system must be
|
||||
* able to operate without mouse
|
||||
*/
|
||||
RtlRosInitUnicodeStringFromLiteral(&MouseDeviceName, L"\\??\\MouseClass");
|
||||
InitializeObjectAttributes(&MouseObjectAttributes,
|
||||
&MouseDeviceName,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = ZwOpenFile(&MouseDeviceHandle,
|
||||
FILE_ALL_ACCESS,
|
||||
&MouseObjectAttributes,
|
||||
&Iosb,
|
||||
0,
|
||||
FILE_SYNCHRONOUS_IO_ALERT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Win32K: Failed to open mouse.\n");
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
Status = ObReferenceObjectByHandle(MouseDeviceHandle,
|
||||
FILE_READ_DATA | FILE_WRITE_DATA,
|
||||
IoFileObjectType,
|
||||
KernelMode,
|
||||
(PVOID *) &FileObject,
|
||||
NULL);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Win32K: Failed to reference mouse file object. (0x%X)\n", Status);
|
||||
ZwClose(MouseDeviceHandle);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
KeInitializeEvent(&IoEvent, FALSE, NotificationEvent);
|
||||
GdiInfo.CallBack = MouseGDICallBack;
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_MOUSE_CONNECT,
|
||||
FileObject->DeviceObject,
|
||||
&GdiInfo,
|
||||
sizeof(GdiInfo),
|
||||
NULL,
|
||||
0,
|
||||
TRUE,
|
||||
&FileObject->Event,
|
||||
&Iosb);
|
||||
|
||||
//trigger FileObject/Event dereferencing
|
||||
Irp->Tail.Overlay.OriginalFileObject = FileObject;
|
||||
|
||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||
StackPtr->FileObject = FileObject;
|
||||
StackPtr->DeviceObject = FileObject->DeviceObject;
|
||||
StackPtr->Parameters.DeviceIoControl.InputBufferLength = sizeof(GdiInfo);
|
||||
StackPtr->Parameters.DeviceIoControl.OutputBufferLength = 0;
|
||||
|
||||
Status = IoCallDriver(FileObject->DeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&FileObject->Event, Executive, KernelMode, FALSE,
|
||||
NULL);
|
||||
Status = Iosb.Status;
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Win32K: Failed to connect to mouse driver.\n");
|
||||
ObDereferenceObject(&FileObject);
|
||||
NtClose(MouseDeviceHandle);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#else
|
||||
Status = PsCreateSystemThread(&MouseThreadHandle,
|
||||
THREAD_ALL_ACCESS,
|
||||
NULL,
|
||||
|
@ -434,7 +444,6 @@ InitInputImpl(VOID)
|
|||
{
|
||||
DPRINT1("Win32K: Failed to create mouse thread.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue