*** empty log message ***

svn path=/trunk/; revision=1408
This commit is contained in:
Jason Filby 2000-10-18 09:11:01 +00:00
parent bb44d63a00
commit 77d9f6fb99
20 changed files with 1595 additions and 5 deletions

View file

@ -1,4 +0,0 @@
base.tmp
junk.tmp
temp.exp
keyboard.coff

View file

@ -0,0 +1,39 @@
// Mouse definitions common to both mouse class and port drivers
#define IO_MOUSE_INCREMENT 6
#define MOUSE_BUFFER_SIZE 32
#define IOCTL_INTERNAL_MOUSE_CONNECT CTL_CODE(FILE_DEVICE_MOUSE, 0x0080, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_INTERNAL_MOUSE_DISCONNECT CTL_CODE(FILE_DEVICE_MOUSE, 0x0100, METHOD_NEITHER, FILE_ANY_ACCESS)
#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)
typedef struct _MOUSE_INPUT_DATA {
USHORT UnitId;
USHORT Flags;
union {
ULONG Buttons;
struct {
USHORT ButtonFlags;
USHORT ButtonData;
};
};
ULONG RawButtons;
LONG LastX;
LONG LastY;
ULONG ExtraInformation;
} MOUSE_INPUT_DATA, *PMOUSE_INPUT_DATA;
typedef struct _CLASS_INFORMATION {
PDEVICE_OBJECT DeviceObject;
PVOID CallBack;
} CLASS_INFORMATION, *PCLASS_INFORMATION;
typedef
VOID
(*PSERVICE_CALLBACK_ROUTINE) (
IN PVOID NormalContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2,
IN OUT PVOID SystemArgument3
);

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.14 2000/10/07 13:41:55 dwelch Exp $
# $Id: makefile,v 1.1 2000/10/18 09:09:14 jfilby Exp $
#
#
PATH_TO_TOP = ../../..

View file

@ -0,0 +1,71 @@
# $Id: makefile,v 1.1 2000/10/18 09:09:14 jfilby Exp $
#
#
TARGET = mouclass
BASE_CFLAGS = -I../../../include
OBJECTS = $(TARGET).o $(TARGET).coff ../../../ntoskrnl/ntoskrnl.a
all: $(TARGET).sys
.phony: all
clean:
- $(RM) $(TARGET).o
- $(RM) $(TARGET).coff
- $(RM) junk.tmp
- $(RM) base.tmp
- $(RM) temp.exp
- $(RM) mouclass.sys
.phony: clean
install: $(FLOPPY_DIR)/drivers/$(TARGET).sys
$(FLOPPY_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
ifeq ($(DOSCLI),yes)
$(CP) $(TARGET).sys $(FLOPPY_DIR)\drivers\$(TARGET).sys
else
$(CP) $(TARGET).sys $(FLOPPY_DIR)/drivers/$(TARGET).sys
endif
dist: ../../../$(DIST_DIR)/drivers/$(TARGET).sys
../../../$(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
ifeq ($(DOSCLI),yes)
$(CP) $(TARGET).sys ..\..\..\$(DIST_DIR)\drivers\$(TARGET).sys
else
$(CP) $(TARGET).sys ../../../$(DIST_DIR)/drivers/$(TARGET).sys
endif
$(TARGET).sys: $(OBJECTS)
$(CC) \
-specs=../../svc_specs \
-mdll \
-o junk.tmp \
-Wl,--defsym,_end=end \
-Wl,--defsym,_edata=__data_end__ \
-Wl,--defsym,_etext=etext \
-Wl,--base-file,base.tmp \
$(OBJECTS)
- $(RM) junk.tmp
$(DLLTOOL) \
--dllname $(TARGET).sys \
--base-file base.tmp \
--output-exp temp.exp \
--kill-at
- $(RM) base.tmp
$(CC) \
--verbose \
-Wl,--image-base,0x10000 \
-Wl,-e,_DriverEntry@8 \
-Wl,temp.exp \
-specs=../../svc_specs \
-mdll \
-o $(TARGET).sys \
$(OBJECTS)
- $(RM) temp.exp
include ../../../rules.mak

View file

@ -0,0 +1,228 @@
/*
** Mouse class driver 0.0.1
** Written by Jason Filby (jasonfilby@yahoo.com)
** For ReactOS (www.reactos.com)
** The class driver between win32k and the various mouse port drivers
** TODO: Change interface to win32k to a callback instead of ReadFile IO
Add support for multiple port devices
*/
#include <ddk/ntddk.h>
#include "..\include\mouse.h"
#include "mouclass.h"
BOOLEAN AlreadyOpened = FALSE;
VOID MouseClassCallBack(PDEVICE_OBJECT ClassDeviceObject, PMOUSE_INPUT_DATA MouseDataStart,
PMOUSE_INPUT_DATA MouseDataEnd, PULONG InputCount)
{
PDEVICE_EXTENSION ClassDeviceExtension = ClassDeviceObject->DeviceExtension;
PIRP Irp;
ULONG ReadSize;
PIO_STACK_LOCATION Stack;
if(ClassDeviceExtension->ReadIsPending == TRUE)
{
Irp = ClassDeviceObject->CurrentIrp;
ClassDeviceObject->CurrentIrp = NULL;
Stack = IoGetCurrentIrpStackLocation(Irp);
ReadSize = sizeof(MOUSE_INPUT_DATA) * (*InputCount);
// A read request is waiting for input, so go straight to it
RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, (PCHAR)MouseDataStart, ReadSize);
// Go to next packet and complete this request with STATUS_SUCCESS
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = ReadSize;
Stack->Parameters.Read.Length = ReadSize;
IoStartNextPacket(ClassDeviceObject, FALSE);
IoCompleteRequest(Irp, IO_MOUSE_INCREMENT);
ClassDeviceExtension->ReadIsPending = FALSE;
}
if(InputCount>0)
{
// FIXME: If we exceed the buffer, mouse data gets thrown away.. better solution?
if(ClassDeviceExtension->InputCount + *InputCount > MOUSE_BUFFER_SIZE)
{
ReadSize = MOUSE_BUFFER_SIZE - ClassDeviceExtension->InputCount;
} else {
ReadSize = *InputCount;
}
// Move the mouse input data from the port data queue to our class data queue
RtlMoveMemory(ClassDeviceExtension->PortData, (PCHAR)MouseDataStart,
sizeof(MOUSE_INPUT_DATA) * ReadSize);
// Move the pointer and counter up
ClassDeviceExtension->PortData += ReadSize;
ClassDeviceExtension->InputCount += ReadSize;
}
}
NTSTATUS ConnectMousePortDriver(PDEVICE_OBJECT ClassDeviceObject)
{
PDEVICE_OBJECT PortDeviceObject = NULL;
PFILE_OBJECT FileObject = NULL;
NTSTATUS status;
UNICODE_STRING PortName;
IO_STATUS_BLOCK ioStatus;
KEVENT event;
PIRP irp;
CLASS_INFORMATION ClassInformation;
PDEVICE_EXTENSION DeviceExtension = ClassDeviceObject->DeviceExtension;
// Get the port driver's DeviceObject
// FIXME: The name might change.. find a way to be more dynamic?
RtlInitUnicodeString(&PortName, L"\\Device\\Mouse");
status = IoGetDeviceObjectPointer(&PortName, FILE_READ_ATTRIBUTES, &FileObject, &PortDeviceObject);
if(status != STATUS_SUCCESS)
{
DbgPrint("MOUCLASS: Could not connect to mouse port driver\n");
return status;
}
DeviceExtension->PortDeviceObject = PortDeviceObject;
DeviceExtension->PortData = ExAllocatePool(NonPagedPool, MOUSE_BUFFER_SIZE * sizeof(MOUSE_INPUT_DATA));
DeviceExtension->InputCount = 0;
DeviceExtension->ReadIsPending = FALSE;
// Connect our callback to the port driver
KeInitializeEvent(&event, NotificationEvent, FALSE);
ClassInformation.DeviceObject = ClassDeviceObject;
ClassInformation.CallBack = MouseClassCallBack;
irp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_MOUSE_CONNECT,
PortDeviceObject, &ClassInformation, sizeof(CLASS_INFORMATION), NULL, 0, TRUE, &event, &ioStatus);
status = IoCallDriver(DeviceExtension->PortDeviceObject, irp);
if (status == STATUS_PENDING) {
KeWaitForSingleObject(&event, Suspended, KernelMode, FALSE, NULL);
} else {
ioStatus.Status = status;
}
return ioStatus.Status;
}
NTSTATUS MouseClassDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS Status;
switch (Stack->MajorFunction)
{
case IRP_MJ_CREATE:
if (AlreadyOpened == TRUE)
{
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_SUCCESS;
AlreadyOpened = TRUE;
}
break;
case IRP_MJ_CLOSE:
Status = STATUS_SUCCESS;
break;
case IRP_MJ_READ:
if (Stack->Parameters.Read.Length == 0) {
Status = STATUS_SUCCESS;
} else {
Status = STATUS_PENDING;
}
break;
default:
DbgPrint("NOT IMPLEMENTED\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
if (Status==STATUS_PENDING)
{
IoMarkIrpPending(Irp);
IoStartPacket(DeviceObject, Irp, NULL, NULL);
} else {
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
return(Status);
}
VOID MouseClassStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
ULONG ReadSize;
if(DeviceExtension->InputCount>0)
{
// FIXME: We should not send to much input data.. depends on the max buffer size of the win32k
ReadSize = DeviceExtension->InputCount * sizeof(MOUSE_INPUT_DATA);
// Bring the PortData back to base so that it can be copied
DeviceExtension->PortData -= DeviceExtension->InputCount;
DeviceExtension->InputCount = 0;
DeviceExtension->ReadIsPending = FALSE;
RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, (PCHAR)DeviceExtension->PortData, ReadSize);
// Go to next packet and complete this request with STATUS_SUCCESS
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = ReadSize;
Stack->Parameters.Read.Length = ReadSize;
IoStartNextPacket(DeviceObject, FALSE);
IoCompleteRequest(Irp, IO_MOUSE_INCREMENT);
} else {
DeviceExtension->ReadIsPending = TRUE;
}
}
NTSTATUS STDCALL
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName;
UNICODE_STRING SymlinkName;
DbgPrint("Mouse Class Driver 0.0.1\n");
DriverObject->MajorFunction[IRP_MJ_CREATE] = MouseClassDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MouseClassDispatch;
DriverObject->MajorFunction[IRP_MJ_READ] = MouseClassDispatch;
DriverObject->DriverStartIo = MouseClassStartIo;
RtlInitUnicodeString(&DeviceName, L"\\Device\\MouseClass");
IoCreateDevice(DriverObject,
sizeof(DEVICE_EXTENSION),
&DeviceName,
FILE_DEVICE_MOUSE,
0,
TRUE,
&DeviceObject);
DeviceObject->Flags = DeviceObject->Flags | DO_BUFFERED_IO;
RtlInitUnicodeString(&SymlinkName, L"\\??\\MouseClass");
IoCreateSymbolicLink(&SymlinkName, &DeviceName);
return ConnectMousePortDriver(DeviceObject);
}

View file

@ -0,0 +1,6 @@
typedef struct _DEVICE_EXTENSION {
BOOLEAN ReadIsPending;
ULONG InputCount;
PMOUSE_INPUT_DATA PortData;
PDEVICE_OBJECT PortDeviceObject; // FIXME: Expand this to handle multiple port drivers (make *PortDeviceObject)
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

View file

@ -0,0 +1,39 @@
#include <defines.h>
#include <reactos/resource.h>
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", RES_STR_COMPANY_NAME
VALUE "FileDescription", "Mouse Class Device Driver\0"
VALUE "FileVersion", "0.0.1\0"
VALUE "InternalName", "mouclass\0"
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
VALUE "OriginalFilename", "mouclass.sys\0"
VALUE "ProductName", RES_STR_PRODUCT_NAME
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View file

@ -0,0 +1,150 @@
// All or parts of this file are from CHAOS (http://www.se.chaosdev.org/).
// CHAOS is also under the GNU General Public License.
#include <ddk/ntddk.h>
#include "controller.h"
#include "keyboard.h"
#include "mouse.h"
/* This reads the controller status port, and does the appropriate
action. It requires that we hold the keyboard controller spinlock. */
unsigned handle_event(void)
{
unsigned status = controller_read_status();
unsigned int work;
for(work = 0; (work < 10000) && ((status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0); work++)
{
unsigned scancode;
scancode = controller_read_input();
#if 0
/* Ignore error bytes. */
if((status &(CONTROLLER_STATUS_GENERAL_TIMEOUT |
CONTROLLER_STATUS_PARITY_ERROR)) == 0)
#endif
{
if((status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) != 0)
{
// mouse_handle_event(scancode); we just use the mouse handler directly..
}
else
{
// keyboard_handle_event(scancode);
}
}
status = controller_read_status();
}
if(work == 10000)
{
DbgPrint("PSAUX: Keyboard controller jammed\n");
}
return status;
}
/* Wait for keyboard controller input buffer to drain.
Quote from PS/2 System Reference Manual:
"Address hex 0060 and address hex 0064 should be written only
when the input-buffer-full bit and output-buffer-full bit in the
Controller Status register are set 0." */
void controller_wait(void)
{
unsigned long timeout;
for(timeout = 0; timeout < CONTROLLER_TIMEOUT; timeout++)
{
// "handle_keyboard_event()" will handle any incoming events
// while we wait -- keypresses or mouse movement
unsigned char status = handle_event();
if((status & CONTROLLER_STATUS_INPUT_BUFFER_FULL) == 0) return;
// Sleep for one millisecond
KeDelayExecutionThread (KernelMode, FALSE, 1);
}
DbgPrint("PSAUX: Keyboard timed out\n");
}
/* Wait for input from the keyboard controller. */
int controller_wait_for_input(void)
{
int timeout;
for(timeout = KEYBOARD_INIT_TIMEOUT; timeout > 0; timeout--)
{
int return_value = controller_read_data();
if(return_value >= 0) return return_value;
// Sleep for one millisecond
KeDelayExecutionThread (KernelMode, FALSE, 1);
}
return -1;
}
/* Write a command word to the keyboard controller. */
void controller_write_command_word(unsigned data)
{
controller_wait();
controller_write_command(data);
}
/* Write an output word to the keyboard controller. */
void controller_write_output_word(unsigned data)
{
controller_wait();
controller_write_output(data);
}
/* Empty the keyboard input buffer. */
void keyboard_clear_input(void)
{
int max_read;
for(max_read = 0; max_read < 100; max_read++)
{
if(controller_read_data() == KEYBOARD_NO_DATA)
{
break;
}
}
}
/* Read data from the keyboard controller. */
int controller_read_data(void)
{
int return_value = KEYBOARD_NO_DATA;
unsigned status;
status = controller_read_status();
if(status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL)
{
unsigned data = controller_read_input();
return_value = data;
if(status &(CONTROLLER_STATUS_GENERAL_TIMEOUT |
CONTROLLER_STATUS_PARITY_ERROR))
{
return_value = KEYBOARD_BAD_DATA;
}
}
return return_value;
}

View file

@ -0,0 +1,139 @@
// All or parts of this file are from CHAOS (http://www.se.chaosdev.org/).
// CHAOS is also under the GNU General Public License.
/* Keyboard controller registers. */
#define CONTROLLER_REGISTER_STATUS 0x64
#define CONTROLLER_REGISTER_CONTROL 0x64
#define CONTROLLER_REGISTER_DATA 0x60
/* Keyboard controller commands. */
/* Read mode bits. */
#define CONTROLLER_COMMAND_READ_MODE 0x20
/* Write mode bits. */
#define CONTROLLER_COMMAND_WRITE_MODE 0x60
/* Get controller version. */
#define CONTROLLER_COMMAND_GET_VERSION 0xA1
/* Disable mouse interface. */
#define CONTROLLER_COMMAND_MOUSE_DISABLE 0xA7
/* Enable mouse interface. */
#define CONTROLLER_COMMAND_MOUSE_ENABLE 0xA8
/* Mouse interface test. */
#define CONTROLLER_COMMAND_TEST_MOUSE 0xA9
/* Controller self test. */
#define CONTROLLER_COMMAND_SELF_TEST 0xAA
/* Keyboard interface test. */
#define CONTROLLER_COMMAND_KEYBOARD_TEST 0xAB
/* Keyboard interface disable. */
#define CONTROLLER_COMMAND_KEYBOARD_DISABLE 0xAD
/* Keyboard interface enable. */
#define CONTROLLER_COMMAND_KEYBOARD_ENABLE 0xAE
/* Write to output buffer as if initiated by the auxiliary device. */
#define CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER 0xD3
/* Write the following byte to the mouse. */
#define CONTROLLER_COMMAND_WRITE_MOUSE 0xD4
/* Status Register Bits. */
/* Keyboard output buffer full. */
#define CONTROLLER_STATUS_OUTPUT_BUFFER_FULL 0x01
/* Keyboard input buffer full. */
#define CONTROLLER_STATUS_INPUT_BUFFER_FULL 0x02
/* Self test successful. */
#define CONTROLLER_STATUS_SELF_TEST 0x04
/* Last write was a command write. (0 = data) */
#define CONTROLLER_STATUS_COMMAND 0x08
/* Zero if keyboard locked. */
#define CONTROLLER_STATUS_UNLOCKED 0x10
/* Mouse output buffer full. */
#define CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL 0x20
/* General receive/xmit timeout. */
#define CONTROLLER_STATUS_GENERAL_TIMEOUT 0x40
/* Parity error. */
#define CONTROLLER_STATUS_PARITY_ERROR 0x80
#define AUX_STATUS_OUTPUT_BUFFER_FULL (CONTROLLER_STATUS_OUTPUT_BUFFER_FULL | \
CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL)
/* Controller mode register bits. */
/* Keyboard data generate IRQ1. */
#define CONTROLLER_MODE_KEYBOARD_INTERRUPT 0x01
/* Mouse data generate IRQ12. */
#define CONTROLLER_MODE_MOUSE_INTERRUPT 0x02
/* The system flag. (?) */
#define CONTROLLER_MODE_SYS 0x04
/* The keylock doesn't affect the keyboard if set. */
#define CONTROLLER_MODE_NO_KEYLOCK 0x08
/* Disable keyboard interface. */
#define CONTROLLER_MODE_DISABLE_KEYBOARD 0x10
/* Disable mouse interface. */
#define CONTROLLER_MODE_DISABLE_MOUSE 0x20
/* Scan code conversion to PC format. */
#define CONTROLLER_MODE_KCC 0x40
#define CONTROLLER_MODE_RFU 0x80
/* Timeout in ms for sending to keyboard controller. */
#define CONTROLLER_TIMEOUT 250
/* Hardware defines. */
#define CONTROLLER_PORT_BASE 0x60
#define CONTROLLER_PORTS 0x10
/* Macros for accessing the keyboard controller on this platform. */
#define controller_read_input() READ_PORT_UCHAR ((PUCHAR)CONTROLLER_REGISTER_DATA)
#define controller_read_status() READ_PORT_UCHAR ((PUCHAR)CONTROLLER_REGISTER_STATUS)
#define controller_write_output(value) WRITE_PORT_UCHAR ((PUCHAR)CONTROLLER_REGISTER_DATA, value)
#define controller_write_command(value) WRITE_PORT_UCHAR ((PUCHAR)CONTROLLER_REGISTER_CONTROL, value)

View file

@ -0,0 +1,51 @@
// All or parts of this file are from CHAOS (http://www.se.chaosdev.org/).
// CHAOS is also under the GNU General Public License.
/* Timeout in ms for keyboard command acknowledge. */
#define KEYBOARD_TIMEOUT 1000
/* Timeout in ms for initializing the keyboard. */
#define KEYBOARD_INIT_TIMEOUT 1000
/* Keyboard commands. */
#define KEYBOARD_COMMAND_SET_LEDS 0xED
#define KEYBOARD_COMMAND_SET_RATE 0xF3
#define KEYBOARD_COMMAND_ENABLE 0xF4
#define KEYBOARD_COMMAND_DISABLE 0xF5
#define KEYBOARD_COMMAND_RESET 0xFF
/* Keyboard replies. */
/* Power on reset. */
#define KEYBOARD_REPLY_POWER_ON_RESET 0xAA
/* Acknowledgement of previous command. */
#define KEYBOARD_REPLY_ACK 0xFA
/* Command NACK, send the command again. */
#define KEYBOARD_REPLY_RESEND 0xFE
/* Hardware defines. */
#define KEYBOARD_IRQ 1
/* Return values from keyboard_read_data (). */
/* No data. */
#define KEYBOARD_NO_DATA (-1)
/* Parity or other error. */
#define KEYBOARD_BAD_DATA (-2)
/* Common variables. */
int mouse_replies_expected;
BOOLEAN has_mouse;
// mailbox_id_type keyboard_target_mailbox_id;
unsigned keyboard_pressed_keys[16];

View file

@ -0,0 +1,226 @@
// All or parts of this file are from CHAOS (http://www.se.chaosdev.org/).
// CHAOS is also under the GNU General Public License.
#include <ddk/ntddk.h>
#include "controller.h"
#include "mouse.h"
#include "psaux.h"
// Have we got a PS/2 mouse port?
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;
// The number of mouse replies expected
int mouse_replies_expected = 0;
// Handle a mouse event
BOOLEAN ps2_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext)
{
// char tmpstr[100];
PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)ServiceContext;
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
int state_dx, state_dy, state_buttons;
unsigned scancode;
unsigned status = controller_read_status();
scancode = controller_read_input();
if((status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) != 0)
{
// mouse_handle_event(scancode); proceed to handle it
}
else
{
return FALSE; // keyboard_handle_event(scancode);
}
if (mouse_replies_expected > 0)
{
if (scancode == MOUSE_ACK)
{
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)
{
mouse_buffer_position = 0;
// system_call_debug_print_simple ("We got a mouse event");
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) */ ))
{
// FIXME: Implement button state, see /include/ntddmous.h
DeviceObject = (PDEVICE_OBJECT)ServiceContext;
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (DeviceExtension->InputDataCount == MOUSE_BUFFER_SIZE)
{
return TRUE;
}
DeviceExtension->MouseInputData[DeviceExtension->InputDataCount].LastX = state_dx;
DeviceExtension->MouseInputData[DeviceExtension->InputDataCount].LastY = state_dy;
DeviceExtension->InputDataCount++;
KeInsertQueueDpc(&DeviceExtension->IsrDpc, DeviceObject->CurrentIrp, NULL);
return TRUE;
}
}
}
/* Write a PS/2 mouse command. */
static void mouse_write_command (int command)
{
controller_wait ();
controller_write_command (CONTROLLER_COMMAND_WRITE_MODE);
controller_wait ();
controller_write_output (command);
}
/* Send a byte to the PS/2 mouse & handle returned ACK. */
static void mouse_write_ack (int value)
{
controller_wait ();
controller_write_command (CONTROLLER_COMMAND_WRITE_MOUSE);
controller_wait ();
controller_write_output (value);
/* We expect an ACK in response. */
mouse_replies_expected++;
controller_wait ();
}
/* Check if this is a dual port controller. */
BOOLEAN detect_ps2_port(void)
{
int loops;
BOOLEAN return_value = FALSE;
return TRUE; // The rest of this code fails under BOCHs
/* Put the value 0x5A in the output buffer using the "WriteAuxiliary Device Output Buffer" command (0xD3).
Poll the Status Register for a while to see if the value really turns up in the Data Register. If the
KEYBOARD_STATUS_MOUSE_OBF bit is also set to 1 in the Status Register, we assume this controller has an
Auxiliary Port (a.k.a. Mouse Port). */
controller_wait ();
controller_write_command (CONTROLLER_COMMAND_WRITE_MOUSE_OUTPUT_BUFFER);
controller_wait ();
// 0x5A is a random dummy value
controller_write_output (0x5A);
for (loops = 0; loops < 10; loops++)
{
unsigned char status = controller_read_status();
if((status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0)
{
controller_read_input();
if ((status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) != 0)
{
return_value = TRUE;
}
break;
}
KeDelayExecutionThread (KernelMode, FALSE, 1);
}
return return_value;
}
// Initialize the PS/2 mouse support
BOOLEAN mouse_init (PDEVICE_OBJECT DeviceObject)
{
ULONG MappedIrq;
KIRQL Dirql;
KAFFINITY Affinity;
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
DeviceExtension->InputDataCount = 0;
DeviceExtension->MouseInputData = ExAllocatePool(NonPagedPool, sizeof(MOUSE_INPUT_DATA) * MOUSE_BUFFER_SIZE);
if (!detect_ps2_port ()) return FALSE;
has_mouse = TRUE;
// Enable the PS/2 mouse port
controller_write_command_word (CONTROLLER_COMMAND_MOUSE_ENABLE);
// 200 samples/sec
mouse_write_ack (MOUSE_SET_SAMPLE_RATE);
mouse_write_ack (200);
// 8 counts per mm
mouse_write_ack (MOUSE_SET_RESOLUTION);
mouse_write_ack (3);
// 2:1 scaling
mouse_write_ack (MOUSE_SET_SCALE21);
// Enable the PS/2 device
mouse_write_ack (MOUSE_ENABLE_DEVICE);
// Enable controller interrupts
mouse_write_command (MOUSE_INTERRUPTS_ON);
// Connect the interrupt for the mouse irq
MappedIrq = HalGetInterruptVector(Internal, 0, 0, MOUSE_IRQ, &Dirql, &Affinity);
IoConnectInterrupt(&DeviceExtension->MouseInterrupt, ps2_mouse_handler, DeviceObject, NULL, MappedIrq,
Dirql, Dirql, 0, FALSE, Affinity, FALSE);
return TRUE;
}

View file

@ -0,0 +1,80 @@
// 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
#define MOUSE_INTERRUPTS_OFF (CONTROLLER_MODE_KCC | \
CONTROLLER_MODE_DISABLE_MOUSE | \
CONTROLLER_MODE_SYS | \
CONTROLLER_MODE_KEYBOARD_INTERRUPT)
#define MOUSE_INTERRUPTS_ON (CONTROLLER_MODE_KCC | \
CONTROLLER_MODE_SYS | \
CONTROLLER_MODE_MOUSE_INTERRUPT | \
CONTROLLER_MODE_KEYBOARD_INTERRUPT)
/* 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. */
#define MAX_RETRIES 60
/* Hardware defines. */
#define MOUSE_IRQ 12
#define MOUSE_WRAP_MASK 0x1F
static PIRP CurrentIrp;
static ULONG MouseDataRead;
static ULONG MouseDataRequired;
static BOOLEAN AlreadyOpened = FALSE;
static KDPC MouseDpc;
static VOID MouseDpcRoutine(PKDPC Dpc,
PVOID DeferredContext,
PVOID SystemArgument1,
PVOID SystemArgument2);

View file

@ -0,0 +1,192 @@
/*
** PS/2 driver 0.0.1
** 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>
#include "../include/mouse.h"
#include "mouse.h"
#include "psaux.h"
BOOLEAN MouseSynchronizeRoutine(PVOID Context)
{
PIRP Irp = (PIRP)Context;
PMOUSE_INPUT_DATA rec = (PMOUSE_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
ULONG NrToRead = stk->Parameters.Read.Length/sizeof(MOUSE_INPUT_DATA);
int i;
if ((stk->Parameters.Read.Length/sizeof(MOUSE_INPUT_DATA))==NrToRead)
{
return(TRUE);
}
MouseDataRequired=stk->Parameters.Read.Length/sizeof(MOUSE_INPUT_DATA);
MouseDataRead=NrToRead;
CurrentIrp=Irp;
return(FALSE);
}
VOID PS2MouseStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
if (KeSynchronizeExecution(DeviceExtension->MouseInterrupt, MouseSynchronizeRoutine, Irp))
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStartNextPacket(DeviceObject, FALSE);
}
}
NTSTATUS PS2MouseDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION stk = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS Status;
switch (stk->MajorFunction)
{
case IRP_MJ_CREATE:
if (AlreadyOpened == TRUE)
{
Status = STATUS_SUCCESS;
}
else
{
Status = STATUS_SUCCESS;
AlreadyOpened = TRUE;
}
break;
case IRP_MJ_CLOSE:
Status = STATUS_SUCCESS;
break;
default:
DbgPrint("NOT IMPLEMENTED\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
}
if (Status==STATUS_PENDING)
{
IoMarkIrpPending(Irp);
}
else
{
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
}
return(Status);
}
VOID PS2MouseInitializeDataQueue(PVOID Context)
{
/* PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)((PGET_DATA_POINTER_CONTEXT)Context)->DeviceExtension;
((PGET_DATA_POINTER_CONTEXT)Context)->DataIn = DeviceExtension->DataIn;
((PGET_DATA_POINTER_CONTEXT)Context)->DataOut = DeviceExtension->DataOut;
((PGET_DATA_POINTER_CONTEXT)Context)->InputCount = DeviceExtension->InputCount; */
DbgPrint("PS2MouseInitializeDataQueue UNIMPLEMENTED\n");
}
NTSTATUS PS2MouseInternalDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
// Refer to \readableMouseDriver\port\sermcmn.c line 54
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status;
switch(Stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_INTERNAL_MOUSE_CONNECT:
DeviceExtension->ClassInformation =
*((PCLASS_INFORMATION)Stack->Parameters.DeviceIoControl.Type3InputBuffer);
// Reinitialize the port input data queue synchronously
KeSynchronizeExecution(DeviceExtension->MouseInterrupt,
(PKSYNCHRONIZE_ROUTINE)PS2MouseInitializeDataQueue, DeviceExtension);
status = STATUS_SUCCESS;
break;
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Irp->IoStatus.Status = status;
if (status == STATUS_PENDING) {
IoMarkIrpPending(Irp);
IoStartPacket(DeviceObject, Irp, NULL, NULL);
} else {
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
return status;
}
VOID PS2MouseIsrDpc(PKDPC Dpc, PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
(*(PSERVICE_CALLBACK_ROUTINE)DeviceExtension->ClassInformation.CallBack)(
DeviceExtension->ClassInformation.DeviceObject,
DeviceExtension->MouseInputData,
NULL,
&DeviceExtension->InputDataCount);
DeviceExtension->InputDataCount = 0;
}
NTSTATUS STDCALL
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT DeviceObject;
UNICODE_STRING DeviceName;
UNICODE_STRING SymlinkName;
PDEVICE_EXTENSION DeviceExtension;
DbgPrint("PS/2 Keyboard & Mouse Driver 0.0.1\n");
DriverObject->MajorFunction[IRP_MJ_CREATE] = PS2MouseDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = PS2MouseDispatch;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = PS2MouseInternalDeviceControl;
DriverObject->DriverStartIo = PS2MouseStartIo;
RtlInitUnicodeString(&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;
RtlInitUnicodeString(&SymlinkName, L"\\??\\Mouse"); // FIXME: find correct device name
IoCreateSymbolicLink(&SymlinkName, &DeviceName);
DeviceExtension = DeviceObject->DeviceExtension;
KeInitializeDpc(&DeviceExtension->IsrDpc, (PKDEFERRED_ROUTINE)PS2MouseIsrDpc, DeviceObject);
KeInitializeDpc(&DeviceExtension->IsrDpcRetry, (PKDEFERRED_ROUTINE)PS2MouseIsrDpc, DeviceObject);
mouse_init(DeviceObject);
return(STATUS_SUCCESS);
}

View file

@ -0,0 +1,12 @@
typedef struct _DEVICE_EXTENSION {
PDEVICE_OBJECT DeviceObject;
ULONG InputDataCount;
PMOUSE_INPUT_DATA MouseInputData;
CLASS_INFORMATION ClassInformation;
PKINTERRUPT MouseInterrupt;
KDPC IsrDpc;
KDPC IsrDpcRetry;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

View file

@ -0,0 +1,39 @@
#include <defines.h>
#include <reactos/resource.h>
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", RES_STR_COMPANY_NAME
VALUE "FileDescription", "PS Auxiliary Device Driver\0"
VALUE "FileVersion", "0.0.1\0"
VALUE "InternalName", "psaux\0"
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
VALUE "OriginalFilename", "psaux.sys\0"
VALUE "ProductName", RES_STR_PRODUCT_NAME
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View file

@ -0,0 +1,52 @@
#
#
#
PATH_TO_TOP = ../../..
TARGET=mouse
OBJECTS= mouse.o ../../../ntoskrnl/ntoskrnl.a
all: mouse.o
.phony: all
clean:
- $(RM) mouse.o
- $(RM) junk.tmp
- $(RM) base.tmp
- $(RM) temp.exp
- $(RM) mouse.sys
.phony: clean
install: $(FLOPPY_DIR)/drivers/$(TARGET).sys
$(FLOPPY_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
ifeq ($(DOSCLI),yes)
$(CP) $(TARGET).sys $(FLOPPY_DIR)\drivers\$(TARGET).sys
else
$(CP) $(TARGET).sys $(FLOPPY_DIR)/drivers/$(TARGET).sys
endif
dist: ../../../$(DIST_DIR)/drivers/$(TARGET).sys
../../../$(DIST_DIR)/drivers/$(TARGET).sys: $(TARGET).sys
ifeq ($(DOSCLI),yes)
$(CP) $(TARGET).sys ..\..\..\$(DIST_DIR)\drivers\$(TARGET).sys
else
$(CP) $(TARGET).sys ../../../$(DIST_DIR)/drivers/$(TARGET).sys
endif
mouse.sys: $(OBJECTS)
$(CC) -specs=../../svc_specs -mdll -o junk.tmp -Wl,--defsym,_end=end \
-Wl,--defsym,_edata=__data_end__ -Wl,--defsym,_etext=etext \
-Wl,--base-file,base.tmp $(OBJECTS)
- $(RM) junk.tmp
$(DLLTOOL) --dllname mouse.sys --base-file base.tmp \
--output-exp temp.exp
- $(RM) base.tmp
$(CC) --verbose -Wl,--image-base,0x10000 -Wl,-e,_DriverEntry@8 \
-specs=../../svc_specs -mdll -o mouse.sys $(OBJECTS) -Wl,temp.exp
- $(RM) temp.exp

View file

@ -0,0 +1,270 @@
/*
** Mouse driver 0.0.3
** Written by Jason Filby (jasonfilby@yahoo.com)
** For ReactOS (www.sid-dis.com/reactos)
** Note: The serial.o driver must be loaded before loading this driver
** Known Limitations:
** Only supports mice on COM port 1
*/
#include <ddk/ntddk.h>
#include <internal/mmhal.h>
#include <internal/halio.h>
/* #include <internal/hal/ddk.h> */
#include <funcs.h>
#define MOUSE_IRQ_COM1 4
#define MOUSE_IRQ_COM2 3
#define COM1_PORT 0x3f8
#define COM2_PORT 0x2f8
#define max_screen_x 79
#define max_screen_y 24
static unsigned int MOUSE_IRQ=MOUSE_IRQ_COM1;
static unsigned int MOUSE_COM=COM1_PORT;
static unsigned int bytepos=0, coordinate;
static unsigned char mpacket[3];
static signed int mouse_x=40, mouse_y=12;
static unsigned char mouse_button1, mouse_button2;
static signed int horiz_sensitivity, vert_sensitivity;
BOOLEAN microsoft_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext)
{
unsigned int mbyte=inb(MOUSE_COM);
// Synchronize
if((mbyte&64)==64) { bytepos=0; };
mpacket[bytepos]=mbyte;
bytepos++;
// Process packet
if(bytepos==3) {
// Retrieve change in x and y from packet
int change_x=((mpacket[0] & 3) << 6) + mpacket[1];
int change_y=((mpacket[0] & 12) << 4) + mpacket[2];
// Some mice need this
if(coordinate==1) {
change_x-=128;
change_y-=128;
};
// Change to signed
if(change_x>=128) { change_x=change_x-256; };
if(change_y>=128) { change_y=change_y-256; };
// Adjust mouse position according to sensitivity
mouse_x+=change_x/horiz_sensitivity;
mouse_y+=change_y/vert_sensitivity;
// Check that mouse is still in screen
if(mouse_x<0) { mouse_x=0; };
if(mouse_x>max_screen_x) { mouse_x=max_screen_x; };
if(mouse_y<0) { mouse_y=0; };
if(mouse_y>max_screen_y) { mouse_y=max_screen_y; };
// Retrieve mouse button status from packet
mouse_button1=mpacket[0] & 32;
mouse_button2=mpacket[0] & 16;
bytepos=0;
};
};
void InitializeMouseHardware(unsigned int mtype)
{
char clear_error_bits;
outb_p(MOUSE_COM+3, 0x80); // set DLAB on
outb_p(MOUSE_COM, 0x60); // speed LO byte
outb_p(MOUSE_COM+1, 0); // speed HI byte
outb_p(MOUSE_COM+3, mtype); // 2=MS Mouse; 3=Mouse systems mouse
outb_p(MOUSE_COM+1, 0); // set comm and DLAB to 0
outb_p(MOUSE_COM+4, 1); // DR int enable
clear_error_bits=inb_p(MOUSE_COM+5); // clear error bits
};
int DetMicrosoft(void)
{
char tmp, ind;
int buttons=0, i;
outb_p(MOUSE_COM+4, 0x0b);
tmp=inb_p(MOUSE_COM);
// Check the first for bytes for signs that this is an MS mouse
for(i=0; i<4; i++) {
while((inb_p(MOUSE_COM+5) & 1)==0) ;
ind=inb_p(MOUSE_COM);
if(ind==0x33) buttons=3;
if(ind==0x4d) buttons=2;
};
return buttons;
};
int CheckMouseType(unsigned int mtype)
{
unsigned int retval=0;
InitializeMouseHardware(mtype);
if(mtype==2) retval=DetMicrosoft();
if(mtype==3) {
outb_p(MOUSE_COM+4, 11);
retval=3;
};
outb_p(MOUSE_COM+1, 1);
return retval;
};
void ClearMouse(void)
{
// Waits until the mouse calms down but also quits out after a while
// in case some destructive user wants to keep moving the mouse
// before we're done
unsigned int restarts=0, i;
for (i=0; i<60000; i++)
{
unsigned temp=inb(MOUSE_COM);
if(temp!=0) {
restarts++;
if(restarts<300000) {
i=0;
} else
{
i=60000;
};
};
};
};
void InitializeMouse(void)
{
int mbuttons=0, gotmouse=0;
ULONG MappedIrq;
KIRQL Dirql;
KAFFINITY Affinity;
PKINTERRUPT IrqObject;
horiz_sensitivity=2;
vert_sensitivity=3;
// Check for Microsoft mouse (2 buttons)
if(CheckMouseType(2)!=0)
{
gotmouse=1;
DbgPrint("Microsoft Mouse Detected\n");
ClearMouse();
coordinate=0;
};
// Check for Microsoft Systems mouse (3 buttons)
if(gotmouse==0) {
if(CheckMouseType(3)!=0)
{
gotmouse=1;
DbgPrint("Microsoft Mouse Detected\n");
ClearMouse();
coordinate=1;
};
};
if(gotmouse==0) {
DbgPrint("No Mouse Detected!\n");
} else {
MappedIrq = HalGetInterruptVector(Internal, 0, 0, MOUSE_IRQ,
&Dirql, &Affinity);
IoConnectInterrupt(&IrqObject, microsoft_mouse_handler, NULL,
NULL, MappedIrq, Dirql, Dirql, 0, FALSE,
Affinity, FALSE);
};
};
// For test purposes only
unsigned char get_text_char(int x, int y)
{
unsigned char getchar;
char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2)));
getchar=*vidmem;
return getchar;
};
// For test purposes only
unsigned char get_text_color(int x, int y)
{
unsigned char getcolor;
char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2)));
vidmem++;
getcolor=*vidmem;
return getcolor;
};
// For test purposes only
void put_text_char(int x, int y, unsigned char putchar[2])
{
char *vidmem=(char*)physical_to_linear((0xb8000+(y*160)+(x*2)));
*vidmem=putchar[0];
vidmem++;
*vidmem=putchar[1];
};
// For test purposes only
void test_mouse(void)
{
static int i=0, forcechange=0;
static int old_x=40, old_y=12;
static unsigned char old_cursor[2], new_cursor[2];
DbgPrint("Testing mouse...");
old_cursor[0]=' ';
old_cursor[1]=7;
new_cursor[0]='Û';
new_cursor[1]=15;
old_cursor[0]=get_text_char(mouse_x, mouse_y);
old_cursor[1]=get_text_color(mouse_x, mouse_y);
put_text_char(mouse_x, mouse_y, new_cursor);
while(i!=1)
{
if(mouse_button1!=0) { new_cursor[1]=10; mouse_button1=0; forcechange=1; };
if(mouse_button2!=0) { new_cursor[1]=12; mouse_button2=0; forcechange=1; };
if((mouse_x!=old_x) || (mouse_y!=old_y) || (forcechange==1)) {
forcechange=0;
put_text_char(old_x, old_y, old_cursor);
old_cursor[0]=get_text_char(mouse_x, mouse_y);
old_cursor[1]=get_text_color(mouse_x, mouse_y);
put_text_char(mouse_x, mouse_y, new_cursor);
old_x=mouse_x;
old_y=mouse_y;
};
};
};
NTSTATUS STDCALL
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
DbgPrint("Mouse Driver 0.0.3\n");
InitializeMouse();
test_mouse();
return(STATUS_SUCCESS);
};