ReactOS 0.4.15-dev-7113-g9ea2222
readmouse.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Serial mouse driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/input/sermouse/fdo.c
5 * PURPOSE: Read mouse moves and send them to mouclass
6 * PROGRAMMERS: Copyright Jason Filby (jasonfilby@yahoo.com)
7 Copyright Filip Navara (xnavara@volny.cz)
8 Copyright 2005-2006 Hervé Poussineau (hpoussin@reactos.org)
9 */
10
11#include "sermouse.h"
12
13#include <debug.h>
14
15static NTSTATUS
18 IN ULONG CtlCode,
20 IN ULONG InputBufferSize,
22 IN OUT PULONG OutputBufferSize)
23{
25 PIRP Irp;
28
30
34 InputBufferSize,
36 (OutputBufferSize) ? *OutputBufferSize : 0,
37 FALSE,
38 &Event,
39 &IoStatus);
40 if (Irp == NULL)
41 {
42 WARN_(SERMOUSE, "IoBuildDeviceIoControlRequest() failed\n");
44 }
45
47
49 {
50 INFO_(SERMOUSE, "Operation pending\n");
52 Status = IoStatus.Status;
53 }
54
55 if (OutputBufferSize)
56 {
57 *OutputBufferSize = (ULONG)IoStatus.Information;
58 }
59
60 return Status;
61}
62
66{
67 PSERMOUSE_DEVICE_EXTENSION DeviceExtension;
68 PDEVICE_OBJECT LowerDevice;
70 PIRP Irp;
71 IO_STATUS_BLOCK ioStatus;
73 PUCHAR PacketBuffer;
74 UCHAR ReceivedByte;
77 ULONG ButtonsDifference;
79 ULONG i;
80 ULONG Fcr;
81 ULONG BaudRate;
82 SERIAL_TIMEOUTS Timeouts;
86
87 TRACE_(SERMOUSE, "SermouseDeviceWorker() called\n");
88
89 DeviceExtension = (PSERMOUSE_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
90 LowerDevice = DeviceExtension->LowerDevice;
91 Zero.QuadPart = 0;
92 PacketBuffer = DeviceExtension->PacketBuffer;
93
94 ASSERT(LowerDevice);
95
96 /* Initialize device extension */
97 DeviceExtension->ActiveQueue = 0;
98 DeviceExtension->PacketBufferPosition = 0;
99 DeviceExtension->PreviousButtons = 0;
100
101 /* Initialize serial port */
102 Fcr = 0;
104 &Fcr, sizeof(Fcr), NULL, NULL);
106 /* Set serial port speed */
107 BaudRate = DeviceExtension->AttributesInformation.SampleRate * 8;
109 &BaudRate, sizeof(BaudRate), NULL, NULL);
111 /* Set LCR */
112 LCR.WordLength = 7;
113 LCR.Parity = NO_PARITY;
114 LCR.StopBits = STOP_BIT_1;
116 &LCR, sizeof(LCR), NULL, NULL);
118
119 /* Set timeouts */
121 Timeouts.ReadIntervalTimeout = 100;
124 &Timeouts, sizeof(Timeouts), NULL, NULL);
126
127 /* main read loop */
129 while (TRUE)
130 {
132 &DeviceExtension->StopWorkerThreadEvent,
133 Executive,
135 TRUE,
136 &Zero);
137 if (Status != STATUS_TIMEOUT)
138 {
139 /* we need to stop the worker thread */
140 KeClearEvent(&DeviceExtension->StopWorkerThreadEvent);
141 break;
142 }
143
147 LowerDevice,
149 &Zero,
150 &event,
151 &ioStatus);
152 if (!Irp)
153 {
154 /* No memory actually, try later */
155 INFO_(SERMOUSE, "No memory actually, trying again\n");
157 continue;
158 }
159
160 Status = IoCallDriver(LowerDevice, Irp);
161 if (Status == STATUS_PENDING)
162 {
164 Status = ioStatus.Status;
165 }
166
167 if (!NT_SUCCESS(Status))
168 continue;
169
170 /* Read all available data and process */
171 for (i = 0; i < ioStatus.Information; i++)
172 {
173 ReceivedByte = Buffer[i];
174 INFO_(SERMOUSE, "ReceivedByte 0x%02x\n", ReceivedByte);
175
176 /* Synchronize */
177 if ((ReceivedByte & 0x40) == 0x40)
178 DeviceExtension->PacketBufferPosition = 0;
179
180 PacketBuffer[DeviceExtension->PacketBufferPosition] = ReceivedByte & 0x7f;
181 DeviceExtension->PacketBufferPosition++;
182
183 /* Process packet if complete */
184 if (DeviceExtension->PacketBufferPosition >= 3)
185 {
186 Queue = DeviceExtension->ActiveQueue % 2;
187
188 /* Prevent buffer overflow */
189 if (DeviceExtension->InputDataCount[Queue] == 1)
190 continue;
191
192 Input = &DeviceExtension->MouseInputData[Queue];
193
194 if (DeviceExtension->PacketBufferPosition == 3)
195 {
196 /* Retrieve change in x and y from packet */
197 Input->LastX = (signed char)(PacketBuffer[1] | ((PacketBuffer[0] & 0x03) << 6));
198 Input->LastY = (signed char)(PacketBuffer[2] | ((PacketBuffer[0] & 0x0c) << 4));
199
200 /* Determine the current state of the buttons */
201 Input->RawButtons = (DeviceExtension->PreviousButtons & MOUSE_BUTTON_MIDDLE) |
202 ((UCHAR)(PacketBuffer[0] & LEFT_BUTTON_MASK) >> LEFT_BUTTON_SHIFT) |
203 ((UCHAR)(PacketBuffer[0] & RIGHT_BUTTON_MASK) >> RIGHT_BUTTON_SHIFT);
204 }
205 else if (DeviceExtension->PacketBufferPosition == 4)
206 {
207 DeviceExtension->PacketBufferPosition = 0;
208 /* If middle button state changed than report event */
209 if (((UCHAR)(PacketBuffer[3] & MIDDLE_BUTTON_MASK) >> MIDDLE_BUTTON_SHIFT) ^
210 (DeviceExtension->PreviousButtons & MOUSE_BUTTON_MIDDLE))
211 {
212 Input->RawButtons ^= MOUSE_BUTTON_MIDDLE;
213 Input->LastX = 0;
214 Input->LastY = 0;
215 }
216 else
217 {
218 continue;
219 }
220 }
221
222 /* Determine ButtonFlags */
223 Input->ButtonFlags = 0;
224 ButtonsDifference = DeviceExtension->PreviousButtons ^ Input->RawButtons;
225
226 if (ButtonsDifference != 0)
227 {
228 if (ButtonsDifference & MOUSE_BUTTON_LEFT
229 && DeviceExtension->AttributesInformation.NumberOfButtons >= 1)
230 {
231 if (Input->RawButtons & MOUSE_BUTTON_LEFT)
232 Input->ButtonFlags |= MOUSE_LEFT_BUTTON_DOWN;
233 else
234 Input->ButtonFlags |= MOUSE_LEFT_BUTTON_UP;
235 }
236
237 if (ButtonsDifference & MOUSE_BUTTON_RIGHT
238 && DeviceExtension->AttributesInformation.NumberOfButtons >= 2)
239 {
240 if (Input->RawButtons & MOUSE_BUTTON_RIGHT)
241 Input->ButtonFlags |= MOUSE_RIGHT_BUTTON_DOWN;
242 else
243 Input->ButtonFlags |= MOUSE_RIGHT_BUTTON_UP;
244 }
245
246 if (ButtonsDifference & MOUSE_BUTTON_MIDDLE
247 && DeviceExtension->AttributesInformation.NumberOfButtons >= 3)
248 {
249 if (Input->RawButtons & MOUSE_BUTTON_MIDDLE)
250 Input->ButtonFlags |= MOUSE_MIDDLE_BUTTON_DOWN;
251 else
252 Input->ButtonFlags |= MOUSE_MIDDLE_BUTTON_UP;
253 }
254 }
255
256 /* Send the Input data to the Mouse Class driver */
257 DeviceExtension->InputDataCount[Queue]++;
258
260 InterlockedIncrement((PLONG)&DeviceExtension->ActiveQueue);
262 DeviceExtension->ConnectData.ClassDeviceObject,
263 &DeviceExtension->MouseInputData[Queue],
264 &DeviceExtension->MouseInputData[Queue] + 1,
265 &DeviceExtension->InputDataCount[Queue]);
267 DeviceExtension->InputDataCount[Queue] = 0;
268
269 /* Copy RawButtons to Previous Buttons for Input */
270 DeviceExtension->PreviousButtons = Input->RawButtons;
271 }
272 }
273 }
274
276}
#define InterlockedIncrement
Definition: armddk.h:53
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI KeStallExecutionProcessor(IN ULONG MicroSeconds)
Definition: ntoskrnl.c:81
Definition: bufpool.h:45
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define TRACE_(x)
Definition: compat.h:76
unsigned char
Definition: typeof.h:29
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:418
Status
Definition: gdiplustypes.h:25
struct _cl_event * event
Definition: glext.h:7739
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID(STDAPICALLTYPE * PSERVICE_CALLBACK_ROUTINE)(IN PVOID NormalContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2, IN OUT PVOID SystemArgument3)
Definition: kbdmou.h:86
#define ASSERT(a)
Definition: mode.c:44
#define NO_PARITY
Definition: serial.c:89
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define KernelMode
Definition: asm.h:34
#define MOUSE_LEFT_BUTTON_DOWN
Definition: ntddmou.h:46
#define MOUSE_LEFT_BUTTON_UP
Definition: ntddmou.h:47
#define MOUSE_MIDDLE_BUTTON_DOWN
Definition: ntddmou.h:50
#define MOUSE_RIGHT_BUTTON_UP
Definition: ntddmou.h:49
#define MOUSE_MIDDLE_BUTTON_UP
Definition: ntddmou.h:51
#define MOUSE_RIGHT_BUTTON_DOWN
Definition: ntddmou.h:48
#define IOCTL_SERIAL_SET_LINE_CONTROL
Definition: ntddser.h:96
#define IOCTL_SERIAL_SET_TIMEOUTS
Definition: ntddser.h:104
#define STOP_BIT_1
Definition: ntddser.h:215
#define IOCTL_SERIAL_SET_FIFO_CONTROL
Definition: ntddser.h:92
#define IOCTL_SERIAL_SET_BAUD_RATE
Definition: ntddser.h:82
@ NotificationEvent
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IoCallDriver
Definition: irp.c:1225
NTSTATUS NTAPI PsTerminateSystemThread(IN NTSTATUS ExitStatus)
Definition: kill.c:1145
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IRP_MJ_READ
Definition: rdpdr.c:46
static NTSTATUS SermouseDeviceIoControl(IN PDEVICE_OBJECT DeviceObject, IN ULONG CtlCode, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferSize, IN OUT PVOID OutputBuffer OPTIONAL, IN OUT PULONG OutputBufferSize)
Definition: readmouse.c:16
VOID NTAPI SermouseDeviceWorker(PVOID Context)
Definition: readmouse.c:64
@ Input
Definition: arc.h:84
#define INFO_(ch,...)
Definition: debug.h:159
#define WARN_(ch,...)
Definition: debug.h:157
#define LEFT_BUTTON_MASK
Definition: sermouse.h:31
#define MIDDLE_BUTTON_SHIFT
Definition: sermouse.h:41
#define RIGHT_BUTTON_MASK
Definition: sermouse.h:35
struct _SERMOUSE_DEVICE_EXTENSION * PSERMOUSE_DEVICE_EXTENSION
#define MOUSE_BUTTON_LEFT
Definition: sermouse.h:44
#define MIDDLE_BUTTON_MASK
Definition: sermouse.h:39
#define PACKET_BUFFER_SIZE
Definition: sermouse.h:28
#define RIGHT_BUTTON_SHIFT
Definition: sermouse.h:37
#define MOUSE_BUTTON_MIDDLE
Definition: sermouse.h:48
#define MOUSE_BUTTON_RIGHT
Definition: sermouse.h:46
#define LEFT_BUTTON_SHIFT
Definition: sermouse.h:33
#define STATUS_SUCCESS
Definition: shellext.h:65
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
PVOID ClassService
Definition: kbdmou.h:82
PDEVICE_OBJECT ClassDeviceObject
Definition: kbdmou.h:81
USHORT SampleRate
Definition: ntddmou.h:111
USHORT NumberOfButtons
Definition: ntddmou.h:110
ULONG WriteTotalTimeoutMultiplier
Definition: ntddser.h:306
ULONG ReadTotalTimeoutConstant
Definition: ntddser.h:305
ULONG WriteTotalTimeoutConstant
Definition: ntddser.h:307
ULONG ReadTotalTimeoutMultiplier
Definition: ntddser.h:304
ULONG ReadIntervalTimeout
Definition: ntddser.h:303
CONNECT_DATA ConnectData
Definition: sermouse.h:67
PDEVICE_OBJECT LowerDevice
Definition: sermouse.h:57
MOUSE_ATTRIBUTES AttributesInformation
Definition: sermouse.h:72
UCHAR PacketBuffer[PACKET_BUFFER_SIZE]
Definition: sermouse.h:69
MOUSE_INPUT_DATA MouseInputData[2]
Definition: sermouse.h:68
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2225
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
@ Suspended
Definition: ketypes.h:420
@ Executive
Definition: ketypes.h:415
unsigned char UCHAR
Definition: xmlstorage.h:181