branch update for HEAD-2003050101
[reactos.git] / drivers / input / psaux / mouse.c
index 6a6fec0..76b4935 100644 (file)
@@ -1,18 +1,21 @@
 #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
 
@@ -21,112 +24,138 @@ ps2_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext)
 {
   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. */