*/
#include <ddk/ntddk.h>
-#include "../include/mouse.h"
+#include <ddk/ntddmou.h>
#include "mouclass.h"
#define NDEBUG
#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)
{
- 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;
+ 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)
+ {
+ 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. */
// All or parts of this file are from CHAOS (http://www.se.chaosdev.org/).
// CHAOS is also under the GNU General Public License.
-/* Mouse commands. */
-/* Set resolution. */
-
-#define MOUSE_SET_RESOLUTION 0xE8
-
-/* Set 1:1 scaling. */
-
-#define MOUSE_SET_SCALE11 0xE6
-
-/* Set 2:1 scaling. */
-
-#define MOUSE_SET_SCALE21 0xE7
-
-/* Get scaling factor. */
-
-#define MOUSE_GET_SCALE 0xE9
-
-/* Set stream mode. */
-
-#define MOUSE_SET_STREAM 0xEA
-
-/* Set sample rate (number of times the controller will poll the port
- per second). */
-
-#define MOUSE_SET_SAMPLE_RATE 0xF3
-
-/* Enable mouse device. */
-
-#define MOUSE_ENABLE_DEVICE 0xF4
-
-/* Disable mouse device. */
-
-#define MOUSE_DISABLE_DEVICE 0xF5
-
-/* Reset aux device. */
-
-#define MOUSE_RESET 0xFF
-
-/* Command byte ACK. */
-
-#define MOUSE_ACK 0xFA
+// Mouse commands
+#define MOUSE_SET_RESOLUTION 0xE8 // Set resolution
+#define MOUSE_SET_SCALE11 0xE6 // Set 1:1 scaling
+#define MOUSE_SET_SCALE21 0xE7 // Set 2:1 scaling
+#define MOUSE_GET_SCALE 0xE9 // Get scaling factor
+#define MOUSE_SET_STREAM 0xEA // Set stream mode
+#define MOUSE_SET_SAMPLE_RATE 0xF3 /* Set sample rate (number of times
+ * the controller will poll the port
+ * per second */
+#define MOUSE_ENABLE_DEVICE 0xF4 // Enable mouse device
+#define MOUSE_DISABLE_DEVICE 0xF5 // Disable mouse device
+#define MOUSE_RESET 0xFF // Reset aux device
+#define MOUSE_ACK 0xFA // Command byte ACK
#define MOUSE_INTERRUPTS_OFF (CONTROLLER_MODE_KCC | \
CONTROLLER_MODE_DISABLE_MOUSE | \
CONTROLLER_MODE_MOUSE_INTERRUPT | \
CONTROLLER_MODE_KEYBOARD_INTERRUPT)
-/* Used with mouse buttons */
-
+// Used with mouse buttons
#define GPM_B_LEFT 4
#define GPM_B_MIDDLE 2
#define GPM_B_RIGHT 1
-/* Some aux operations take long time. */
-
+// Some aux operations take long time
#define MAX_RETRIES 60
-/* Hardware defines. */
-
+// Hardware defines
#define MOUSE_IRQ 12
#define MOUSE_WRAP_MASK 0x1F
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2);
+
/*
-
- ** PS/2 driver 0.0.1
+ ** PS/2 driver 0.0.2
** Written by Jason Filby (jasonfilby@yahoo.com)
** For ReactOS (www.reactos.com)
** Handles the keyboard and mouse on the PS/2 ports
** TODO: Fix detect_ps2_port(void) so that it works under BOCHs
- Implement mouse button support
-
*/
#include <ddk/ntddk.h>
PDEVICE_EXTENSION DeviceExtension;
if (detect_ps2_port() == TRUE) {
- DbgPrint("PS2 Port Driver version 0.0.1\n");
+ DbgPrint("PS2 Port Driver version 0.0.2\n");
} else {
DbgPrint("PS2 port not found.\n");
return STATUS_UNSUCCESSFUL;
CLASS_INFORMATION ClassInformation;
PKINTERRUPT MouseInterrupt;
- KDPC IsrDpc;
+ KDPC IsrDpc;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
+
#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 MOUSE_BUTTON_1_DOWN 0x0001
+#define MOUSE_BUTTON_1_UP 0x0002
+#define MOUSE_BUTTON_2_DOWN 0x0004
+#define MOUSE_BUTTON_2_UP 0x0008
+#define MOUSE_BUTTON_3_DOWN 0x0010
+#define MOUSE_BUTTON_3_UP 0x0020
+#define MOUSE_BUTTON_4_DOWN 0x0040
+#define MOUSE_BUTTON_4_UP 0x0080
+#define MOUSE_BUTTON_5_DOWN 0x0100
+#define MOUSE_BUTTON_5_UP 0x0200
+#define MOUSE_WHEEL 0x0400
+
+#define MOUSE_LEFT_BUTTON_DOWN MOUSE_BUTTON_1_DOWN
+#define MOUSE_LEFT_BUTTON_UP MOUSE_BUTTON_1_UP
+#define MOUSE_RIGHT_BUTTON_DOWN MOUSE_BUTTON_2_DOWN
+#define MOUSE_RIGHT_BUTTON_UP MOUSE_BUTTON_2_UP
+#define MOUSE_MIDDLE_BUTTON_DOWN MOUSE_BUTTON_3_DOWN
+#define MOUSE_MIDDLE_BUTTON_UP MOUSE_BUTTON_3_UP
+
+/* Mouse input data structure */
typedef struct _MOUSE_INPUT_DATA {
USHORT UnitId;
USHORT Flags;
IN PVOID SystemArgument1,
IN ULONG SystemArgument2
);
+
* 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.18 2003/03/06 23:57:02 gvg Exp $
+/* $Id: mouse.c,v 1.19 2003/03/09 15:00:51 jfilby Exp $
*
* PROJECT: ReactOS kernel
* PURPOSE: Mouse
#include <windows.h>
#include <ddk/ntddk.h>
+#include <ddk/ntddmou.h>
#include <win32k/dc.h>
-#include "../../drivers/input/include/mouse.h"
#include "objects.h"
#include "include/msgqueue.h"
TickCount = LargeTickCount.u.LowPart;
if (hDC == 0)
- {
- return;
- }
+ {
+ return;
+ }
dc = DC_HandleToPtr(hDC);
SurfObj = (PSURFOBJ)AccessUserObject(dc->Surface);
/* Compile the total mouse movement change and dispatch button events. */
for (i = 0; i < InputCount; i++)
+ {
+ mouse_cx += Data[i].LastX;
+ mouse_cy += Data[i].LastY;
+
+ Msg.wParam = ButtonsDown;
+ Msg.lParam = MAKELPARAM(mouse_x + mouse_cx, mouse_y + mouse_cy);
+ Msg.message = WM_MOUSEMOVE;
+ Msg.time = TickCount;
+ Msg.pt.x = mouse_x + mouse_cx;
+ Msg.pt.y = mouse_y + mouse_cy;
+ if ((mouse_cx > 0) || (mouse_cy > 0))
{
- mouse_cx += Data[i].LastX;
- mouse_cy += Data[i].LastY;
-
- Msg.wParam = ButtonsDown;
- Msg.lParam = MAKELPARAM(mouse_x + mouse_cx, mouse_y + mouse_cy);
- Msg.message = WM_MOUSEMOVE;
- Msg.time = TickCount;
- Msg.pt.x = mouse_x + mouse_cx;
- Msg.pt.y = mouse_y + mouse_cy;
MsqInsertSystemMessage(&Msg);
+ }
+
+ if (Data[i].ButtonFlags != 0)
+ {
+ if ((Data[i].ButtonFlags & MOUSE_LEFT_BUTTON_DOWN) > 0)
+ {
+ Msg.wParam = MK_LBUTTON;
+ Msg.message = WM_LBUTTONDOWN;
+ }
+ if ((Data[i].ButtonFlags & MOUSE_MIDDLE_BUTTON_DOWN) > 0)
+ {
+ Msg.wParam = MK_MBUTTON;
+ Msg.message = WM_MBUTTONDOWN;
+ }
+ if ((Data[i].ButtonFlags & MOUSE_RIGHT_BUTTON_DOWN) > 0)
+ {
+ Msg.wParam = MK_RBUTTON;
+ Msg.message = WM_RBUTTONDOWN;
+ }
+
+ if ((Data[i].ButtonFlags & MOUSE_LEFT_BUTTON_UP) > 0)
+ {
+ Msg.wParam = MK_LBUTTON;
+ Msg.message = WM_LBUTTONUP;
+ }
+ if ((Data[i].ButtonFlags & MOUSE_MIDDLE_BUTTON_UP) > 0)
+ {
+ Msg.wParam = MK_MBUTTON;
+ Msg.message = WM_MBUTTONUP;
+ }
+ if ((Data[i].ButtonFlags & MOUSE_RIGHT_BUTTON_UP) > 0)
+ {
+ Msg.wParam = MK_RBUTTON;
+ Msg.message = WM_RBUTTONUP;
+ }
- for (j = 0; j < 3; j++)
- {
- ULONG Flag = MouseButtonFlag[j];
- if (Data[i].ButtonData & (1 << j) && !(ButtonsDown & Flag))
- {
- ButtonsDown |= Flag;
-
- Msg.wParam = ButtonsDown;
- Msg.message = MouseButtonDownMessage[j];
- MsqInsertSystemMessage(&Msg);
- }
- if (!(Data[i].ButtonData & (1 << j)) && (ButtonsDown & Flag))
- {
- ButtonsDown &= ~Flag;
-
- Msg.wParam = ButtonsDown;
- Msg.message = MouseButtonUpMessage[j];
- MsqInsertSystemMessage(&Msg);
- }
- }
+ MsqInsertSystemMessage(&Msg);
}
+ }
/* If the mouse moved then move the pointer. */
if ((mouse_cx != 0 || mouse_cy != 0) && MouseEnabled)
+ {
+ mouse_x += mouse_cx;
+ mouse_y += mouse_cy;
+
+ mouse_x = max(mouse_x, 0);
+ mouse_y = max(mouse_y, 0);
+ mouse_x = min(mouse_x, 620);
+ mouse_y = min(mouse_y, 460);
+
+ if (SafetySwitch == FALSE && SafetySwitch2 == FALSE)
{
- mouse_x += mouse_cx;
- mouse_y += mouse_cy;
-
- mouse_x = max(mouse_x, 0);
- mouse_y = max(mouse_y, 0);
- mouse_x = min(mouse_x, 620);
- mouse_y = min(mouse_y, 460);
-
- if (SafetySwitch == FALSE && SafetySwitch2 == FALSE)
- {
- SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect);
- }
+ SurfGDI->MovePointer(SurfObj, mouse_x, mouse_y, &MouseRect);
}
+ }
}
VOID