mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
Serial mouse driver rewrite by Filip Navara
svn path=/trunk/; revision=5906
This commit is contained in:
parent
d6a2479e6a
commit
eee0086bc9
6 changed files with 698 additions and 464 deletions
|
@ -140,7 +140,7 @@ NTSTATUS ConnectMousePortDriver(PDEVICE_OBJECT ClassDeviceObject)
|
|||
PDEVICE_OBJECT PortDeviceObject = NULL;
|
||||
PFILE_OBJECT FileObject = NULL;
|
||||
NTSTATUS status;
|
||||
UNICODE_STRING PortName = UNICODE_STRING_INITIALIZER(L"\\Device\\Mouse");
|
||||
UNICODE_STRING PortName = UNICODE_STRING_INITIALIZER(L"\\Device\\PointerClass0");
|
||||
IO_STATUS_BLOCK ioStatus;
|
||||
KEVENT event;
|
||||
PIRP irp;
|
||||
|
|
|
@ -147,6 +147,80 @@ VOID PS2MouseIsrDpc(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Cont
|
|||
DeviceExtension->InputDataCount[Queue] = 0;
|
||||
}
|
||||
|
||||
/* Maximum value plus one for \Device\PointerClass* device name */
|
||||
#define POINTER_PORTS_MAXIMUM 8
|
||||
/* Letter count for POINTER_PORTS_MAXIMUM variable * sizeof(WCHAR) */
|
||||
#define SUFFIX_MAXIMUM_SIZE (1 * sizeof(WCHAR))
|
||||
|
||||
/* This is almost the same routine as in sermouse.c. */
|
||||
STATIC PDEVICE_OBJECT
|
||||
AllocatePointerDevice(PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
UNICODE_STRING DeviceName;
|
||||
UNICODE_STRING SuffixString;
|
||||
UNICODE_STRING SymlinkName;
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
ULONG Suffix;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Allocate buffer for full device name */
|
||||
RtlInitUnicodeString(&DeviceName, NULL);
|
||||
DeviceName.MaximumLength = sizeof(DD_MOUSE_DEVICE_NAME_U) + SUFFIX_MAXIMUM_SIZE + sizeof(UNICODE_NULL);
|
||||
DeviceName.Buffer = ExAllocatePool(PagedPool, DeviceName.MaximumLength);
|
||||
RtlAppendUnicodeToString(&DeviceName, DD_MOUSE_DEVICE_NAME_U);
|
||||
|
||||
/* Allocate buffer for device name suffix */
|
||||
RtlInitUnicodeString(&SuffixString, NULL);
|
||||
SuffixString.MaximumLength = SUFFIX_MAXIMUM_SIZE + sizeof(UNICODE_NULL);
|
||||
SuffixString.Buffer = ExAllocatePool(PagedPool, SuffixString.MaximumLength);
|
||||
|
||||
/* Generate full qualified name with suffix */
|
||||
for (Suffix = 0; Suffix < POINTER_PORTS_MAXIMUM; ++Suffix)
|
||||
{
|
||||
ANSI_STRING DebugString;
|
||||
|
||||
RtlIntegerToUnicodeString(Suffix, 10, &SuffixString);
|
||||
RtlAppendUnicodeToString(&DeviceName, SuffixString.Buffer);
|
||||
// FIXME: this isn't really a serial mouse port driver
|
||||
Status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION),
|
||||
&DeviceName, FILE_DEVICE_SERIAL_MOUSE_PORT, 0, TRUE, &DeviceObject);
|
||||
RtlUnicodeStringToAnsiString(&DebugString, &DeviceName, TRUE);
|
||||
DbgPrint(DebugString.Buffer);
|
||||
DbgPrint("\n");
|
||||
RtlFreeAnsiString(&DebugString);
|
||||
/* Device successfully created, leave the cyclus */
|
||||
if (NT_SUCCESS(Status))
|
||||
break;
|
||||
DeviceName.Length -= SuffixString.Length;
|
||||
}
|
||||
|
||||
ExFreePool(DeviceName.Buffer);
|
||||
|
||||
/* Couldn't create device */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ExFreePool(SuffixString.Buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
|
||||
|
||||
/* Create symlink */
|
||||
RtlInitUnicodeString(&SymlinkName, NULL);
|
||||
SymlinkName.MaximumLength = sizeof(L"\\??\\Mouse") + SUFFIX_MAXIMUM_SIZE + sizeof(UNICODE_NULL);
|
||||
SymlinkName.Buffer = ExAllocatePool(PagedPool, SymlinkName.MaximumLength);
|
||||
RtlAppendUnicodeToString(&SymlinkName, L"\\??\\Mouse");
|
||||
RtlAppendUnicodeToString(&DeviceName, SuffixString.Buffer);
|
||||
IoCreateSymbolicLink(&SymlinkName, &DeviceName);
|
||||
ExFreePool(SuffixString.Buffer);
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
KeInitializeDpc(&DeviceExtension->IsrDpc, (PKDEFERRED_ROUTINE)PS2MouseIsrDpc, DeviceObject);
|
||||
|
||||
return DeviceObject;
|
||||
}
|
||||
|
||||
NTSTATUS STDCALL
|
||||
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
||||
{
|
||||
|
@ -162,28 +236,12 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
|
|||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = PS2MouseDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = PS2MouseDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = PS2MouseInternalDeviceControl;
|
||||
DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)PS2MouseDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)PS2MouseDispatch;
|
||||
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = (PDRIVER_DISPATCH)PS2MouseInternalDeviceControl;
|
||||
DriverObject->DriverStartIo = PS2MouseStartIo;
|
||||
|
||||
RtlInitUnicodeStringFromLiteral(&DeviceName,
|
||||
L"\\Device\\Mouse"); // FIXME: find correct device name
|
||||
IoCreateDevice(DriverObject,
|
||||
sizeof(DEVICE_EXTENSION),
|
||||
&DeviceName,
|
||||
FILE_DEVICE_SERIAL_MOUSE_PORT, // FIXME: this isn't really a serial mouse port driver
|
||||
0,
|
||||
TRUE,
|
||||
&DeviceObject);
|
||||
DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
|
||||
|
||||
RtlInitUnicodeStringFromLiteral(&SymlinkName,
|
||||
L"\\??\\Mouse"); // FIXME: find correct device name
|
||||
IoCreateSymbolicLink(&SymlinkName, &DeviceName);
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
KeInitializeDpc(&DeviceExtension->IsrDpc, (PKDEFERRED_ROUTINE)PS2MouseIsrDpc, DeviceObject);
|
||||
DeviceObject = AllocatePointerDevice(DriverObject);
|
||||
|
||||
mouse_init(DeviceObject);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -23,7 +23,7 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "Serial Mouse Device Driver\0"
|
||||
VALUE "FileVersion", "0.0.1\0"
|
||||
VALUE "FileVersion", "0.0.8\0"
|
||||
VALUE "InternalName", "sermouse\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "sermouse.sys\0"
|
||||
|
|
82
reactos/drivers/input/sermouse/sermouse.txt
Normal file
82
reactos/drivers/input/sermouse/sermouse.txt
Normal file
|
@ -0,0 +1,82 @@
|
|||
Following information obtained from Tomi Engdahl (then@delta.hut.fi),
|
||||
http://www.hut.fi/~then/mytexts/mouse.html
|
||||
|
||||
Microsoft serial mouse
|
||||
|
||||
Serial data parameters:
|
||||
1200bps, 7 databits, 1 stop-bit
|
||||
|
||||
Data packet format:
|
||||
Data packet is 3 byte packet. It is send to the computer every time mouse
|
||||
state changes (mouse moves or keys are pressed/released).
|
||||
D7 D6 D5 D4 D3 D2 D1 D0
|
||||
1. X 1 LB RB Y7 Y6 X7 X6
|
||||
2. X 0 X5 X4 X3 X2 X1 X0
|
||||
3. X 0 Y5 Y4 Y3 Y2 Y1 Y0
|
||||
|
||||
Note: The bit marked with X is 0 if the mouse received with 7 databits
|
||||
and 2 stop bits format. It is also possible to use 8 databits and 1 stop
|
||||
bit format for receiving. In this case X gets value 1. The safest thing
|
||||
to get everything working is to use 7 databits and 1 stopbit when
|
||||
receiving mouse information (and if you are making mouse then send out
|
||||
7 databits and 2 stop bits).
|
||||
The byte marked with 1. is send first, then the others. The bit D6 in
|
||||
the first byte is used for syncronizing the software to mouse packets
|
||||
if it goes out of sync.
|
||||
|
||||
LB is the state of the left button (1 means pressed down)
|
||||
RB is the state of the right button (1 means pressed down)
|
||||
X7-X0 movement in X direction since last packet (signed byte)
|
||||
Y7-Y0 movement in Y direction since last packet (signed byte)
|
||||
|
||||
Mouse identification
|
||||
When DTR line is toggled, mouse should send one data byte containing
|
||||
letter 'M' (ascii 77).
|
||||
|
||||
|
||||
Logitech serial mouse
|
||||
|
||||
Logitech uses the Microsoft serial mouse protocol in their mouses (for
|
||||
example Logitech Pilot mouse and others). The origianal protocol supports
|
||||
only two buttons, but logitech as added third button to some of their
|
||||
mouse models. To make this possible logitech has made one extension to
|
||||
the protocol.
|
||||
I have not seen any documentation about the exact documents, but here is
|
||||
what I have found out: The information of the third button state is sent
|
||||
using one extra byte which is send after the normal packet when needed.
|
||||
Value 32 (dec) is sent every time when the center button is pressed down.
|
||||
It is also sent every time with the data packet when center button is kept
|
||||
down and the mouse data packet is sent for other reasons. When center
|
||||
button is released, the mouse sends the normal data packet followed by
|
||||
data bythe which has value 0 (dec). As you can see the extra data byte
|
||||
is sent only when you mess with the center button.
|
||||
|
||||
|
||||
Mouse systems mouse
|
||||
|
||||
Serial data parameters:
|
||||
1200bps, 8 databits, 1 stop-bit
|
||||
|
||||
Data packet format:
|
||||
D7 D6 D5 D4 D3 D2 D1 D0
|
||||
1. 1 0 0 0 0 LB CB RB
|
||||
2. X7 X6 X5 X4 X3 X2 X1 X0
|
||||
3. Y7 Y6 Y5 Y4 Y3 Y4 Y1 Y0
|
||||
4. X7' X6' X5' X4' X3' X2' X1' X0'
|
||||
5. Y7' Y6' Y5' Y4' Y3' Y4' Y1' Y0'
|
||||
|
||||
LB is left button state (0 = pressed, 1 = released)
|
||||
CB is center button state (0 = pressed, 1 = released)
|
||||
RB is right button state (0 = pressed, 1 = released)
|
||||
X7-X0 movement in X direction since last packet in signed byte
|
||||
format (-128..+127), positive direction right
|
||||
Y7-Y0 movement in Y direction since last packet in signed byte
|
||||
format (-128..+127), positive direction up
|
||||
X7'-X0' movement in X direction since sending of X7-X0 packet in
|
||||
signed byte format (-128..+127), positive direction right
|
||||
Y7'-Y0' movement in Y direction since sending of Y7-Y0 packet in
|
||||
signed byte format (-128..+127), positive direction up
|
||||
|
||||
The last two bytes in the packet (bytes 4 and 5) contains information
|
||||
about movement data changes which have occured after data bytes 2 and 3
|
||||
have been sent.
|
|
@ -1,5 +1,8 @@
|
|||
/* Mouse definitions common to both mouse class and port drivers */
|
||||
|
||||
#define DD_MOUSE_DEVICE_NAME "\\Device\\PointerClass"
|
||||
#define DD_MOUSE_DEVICE_NAME_U L"\\Device\\PointerClass"
|
||||
|
||||
#define IO_MOUSE_INCREMENT 6
|
||||
#define MOUSE_BUFFER_SIZE 32
|
||||
|
||||
|
@ -8,6 +11,8 @@
|
|||
#define IOCTL_INTERNAL_MOUSE_ENABLE CTL_CODE(FILE_DEVICE_MOUSE, 0x0200, METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||
#define IOCTL_INTERNAL_MOUSE_DISABLE CTL_CODE(FILE_DEVICE_MOUSE, 0x0400, METHOD_NEITHER, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_MOUSE_QUERY_ATTRIBUTES CTL_CODE(FILE_DEVICE_MOUSE, 0x0000, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define MOUSE_BUTTON_1_DOWN 0x0001
|
||||
#define MOUSE_BUTTON_1_UP 0x0002
|
||||
#define MOUSE_BUTTON_2_DOWN 0x0004
|
||||
|
@ -27,6 +32,16 @@
|
|||
#define MOUSE_MIDDLE_BUTTON_DOWN MOUSE_BUTTON_3_DOWN
|
||||
#define MOUSE_MIDDLE_BUTTON_UP MOUSE_BUTTON_3_UP
|
||||
|
||||
#define MOUSE_SERIAL_HARDWARE 0x0004
|
||||
#define WHEELMOUSE_SERIAL_HARDWARE 0x0040
|
||||
|
||||
typedef struct _MOUSE_ATTRIBUTES {
|
||||
USHORT MouseIdentifier;
|
||||
USHORT NumberOfButtons;
|
||||
USHORT SampleRate;
|
||||
ULONG InputDataQueueLength;
|
||||
} MOUSE_ATTRIBUTES, *PMOUSE_ATTRIBUTES;
|
||||
|
||||
/* Mouse input data structure */
|
||||
typedef struct _MOUSE_INPUT_DATA {
|
||||
USHORT UnitId;
|
||||
|
|
Loading…
Reference in a new issue