#include <ddk/ntddk.h>
-#include "../include/mouse.h"
+#include <ddk/ntddmou.h>
#include "controller.h"
#include "mouse.h"
#include "psaux.h"
// Have we got a PS/2 mouse port?
-BOOLEAN has_mouse = FALSE;
+static BOOLEAN has_mouse = FALSE;
// This buffer holds the mouse scan codes. The PS/2 protocol sends three characters for each event.
-unsigned mouse_buffer[3];
-int mouse_buffer_position = 0;
+static unsigned mouse_buffer[3];
+static int mouse_buffer_position = 0;
// The number of mouse replies expected
-int mouse_replies_expected = 0;
+static int mouse_replies_expected = 0;
+
+// Previous button state
+static ULONG PreviousButtons = 0;
// Handle a mouse event
{
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)ServiceContext;
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
- int state_dx, state_dy, state_buttons;
+ PMOUSE_INPUT_DATA Input;
+ ULONG Queue, ButtonsDiff;
+ int state_dx, state_dy;
unsigned scancode;
unsigned status = controller_read_status();
scancode = controller_read_input();
- /*
- * Don't handle the mouse event if we aren't connected to the mouse class
- * driver
- */
- if (DeviceExtension->ClassInformation.CallBack == NULL)
- {
- return FALSE;
- }
+ /* Don't handle the mouse event if we aren't connected to the mouse class driver */
+ if (DeviceExtension->ClassInformation.CallBack == NULL)
+ {
+ return FALSE;
+ }
if ((status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) != 0)
- {
- // mouse_handle_event(scancode); proceed to handle it
- }
+ {
+ // mouse_handle_event(scancode); proceed to handle it
+ }
else
- {
- return FALSE; // keyboard_handle_event(scancode);
- }
+ {
+ return FALSE; // keyboard_handle_event(scancode);
+ }
- if (mouse_replies_expected > 0)
+ if (mouse_replies_expected > 0)
+ {
+ if (scancode == MOUSE_ACK)
{
- if (scancode == MOUSE_ACK)
- {
- mouse_replies_expected--;
- return;
- }
-
- mouse_replies_expected = 0;
+ mouse_replies_expected--;
+ return;
}
-
+
+ mouse_replies_expected = 0;
+ }
+
/* Add this scancode to the mouse event queue. */
mouse_buffer[mouse_buffer_position] = scancode;
mouse_buffer_position++;
-
+
/* If the buffer is full, parse this event */
if (mouse_buffer_position == 3)
+ {
+ /* Set local variables for DeviceObject and DeviceExtension */
+ DeviceObject = (PDEVICE_OBJECT)ServiceContext;
+ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
+ Queue = DeviceExtension->ActiveQueue % 2;
+
+ /* Prevent buffer overflow */
+ if (DeviceExtension->InputDataCount[Queue] == MOUSE_BUFFER_SIZE)
+ {
+ return TRUE;
+ }
+
+ Input = &DeviceExtension->MouseInputData[Queue]
+ [DeviceExtension->InputDataCount[Queue]];
+
+ mouse_buffer_position = 0;
+
+ /* Determine the current state of the buttons */
+ Input->RawButtons = (mouse_buffer[0] & 1) /* * GPM_B_LEFT */ +
+ (mouse_buffer[0] & 2) /* * GPM_B_RIGHT */ +
+ (mouse_buffer[0] & 4) /* * GPM_B_MIDDLE */;
+
+ /* Determine ButtonFlags */
+ Input->ButtonFlags = 0;
+ ButtonsDiff = PreviousButtons ^ Input->RawButtons;
+
+ if (ButtonsDiff & GPM_B_LEFT)
+ {
+ if (Input->RawButtons & GPM_B_LEFT)
+ {
+ Input->ButtonFlags |= MOUSE_BUTTON_1_DOWN;
+ } else {
+ Input->ButtonFlags |= MOUSE_BUTTON_1_UP;
+ }
+ }
+
+ if (ButtonsDiff & GPM_B_RIGHT)
+ {
+ if (Input->RawButtons & GPM_B_RIGHT)
+ {
+ Input->ButtonFlags |= MOUSE_BUTTON_2_DOWN;
+ } else {
+ Input->ButtonFlags |= MOUSE_BUTTON_2_UP;
+ }
+ }
+
+ if (ButtonsDiff & GPM_B_MIDDLE)
{
- mouse_buffer_position = 0;
-
- state_buttons = (mouse_buffer[0] & 1) * GPM_B_LEFT +
- (mouse_buffer[0] & 2) * GPM_B_RIGHT +
- (mouse_buffer[0] & 4) * GPM_B_MIDDLE;
-
- /*
- * Some PS/2 mice send reports with negative bit set in data[0] and zero
- * for movement. I think this is a bug in the mouse, but working around
- * it only causes artifacts when the actual report is -256; they'll
- * be treated as zero. This should be rare if the mouse sampling rate is
- * set to a reasonable value; the default of 100 Hz is plenty.
- * (Stephen Tell)
- */
- if (mouse_buffer[1] == 0)
- {
- state_dx = 0;
- }
- else
- {
- state_dx = (mouse_buffer[0] & 0x10) ?
- mouse_buffer[1] - 256 :
- mouse_buffer[1];
- }
-
- if (mouse_buffer[2] == 0)
- {
- state_dy = 0;
- }
- else
- {
- state_dy = -((mouse_buffer[0] & 0x20) ?
- mouse_buffer[2] - 256 :
- mouse_buffer[2]);
- }
-
- if (((state_dx!=0) || (state_dy!=0) || (state_buttons!=0)))
- {
- ULONG Queue;
- PMOUSE_INPUT_DATA Input;
-
- /* FIXME: Implement button state, see /include/ntddmous.h */
-
- DeviceObject = (PDEVICE_OBJECT)ServiceContext;
- DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
- Queue = DeviceExtension->ActiveQueue % 2;
-
- if (DeviceExtension->InputDataCount[Queue] == MOUSE_BUFFER_SIZE)
- {
- return TRUE;
- }
-
- Input = &DeviceExtension->MouseInputData[Queue]
- [DeviceExtension->InputDataCount[Queue]];
- Input->RawButtons = state_buttons;
- Input->ButtonData = state_buttons;
- Input->LastX = state_dx;
- Input->LastY = state_dy;
- DeviceExtension->InputDataCount[Queue]++;
-
- KeInsertQueueDpc(&DeviceExtension->IsrDpc, DeviceObject->CurrentIrp,
- NULL);
- return TRUE;
+ if (Input->RawButtons & GPM_B_MIDDLE)
+ {
+ Input->ButtonFlags |= MOUSE_BUTTON_3_DOWN;
+ } else {
+ Input->ButtonFlags |= MOUSE_BUTTON_3_UP;
}
- }
+ }
+
+ /* Some PS/2 mice send reports with negative bit set in data[0] and zero for
+ * movement. I think this is a bug in the mouse, but working around it only
+ * causes artifacts when the actual report is -256; they'll be treated as zero.
+ * This should be rare if the mouse sampling rate is set to a reasonable value;
+ * the default of 100 Hz is plenty. (Stephen Tell) */
+
+ /* Determine LastX */
+ if (mouse_buffer[1] == 0)
+ {
+ Input->LastX = 0;
+ }
+ else
+ {
+ Input->LastX = (mouse_buffer[0] & 0x10) ? mouse_buffer[1] - 256
+ : mouse_buffer[1];
+ }
+
+ /* Determine LastY */
+ if (mouse_buffer[2] == 0)
+ {
+ Input->LastY = 0;
+ }
+ else
+ {
+ Input->LastY = -((mouse_buffer[0] & 0x20) ? mouse_buffer[2] - 256
+ : mouse_buffer[2]);
+ }
+
+ /* Send the Input data to the Mouse Class driver */
+ DeviceExtension->InputDataCount[Queue]++;
+ KeInsertQueueDpc(&DeviceExtension->IsrDpc, DeviceObject->CurrentIrp, NULL);
+
+ /* Copy RawButtons to Previous Buttons for Input */
+ PreviousButtons = Input->RawButtons;
+
+ return TRUE;
+ }
}
/* Write a PS/2 mouse command. */