diff --git a/reactos/drivers/input/psaux/logips2pp.c b/reactos/drivers/input/psaux/logips2pp.c index 9c24ae99899..448c8ef4bad 100644 --- a/reactos/drivers/input/psaux/logips2pp.c +++ b/reactos/drivers/input/psaux/logips2pp.c @@ -18,7 +18,7 @@ * Process a PS2++ or PS2T++ packet. */ -void ps2pp_process_packet(PDEVICE_EXTENSION DeviceExtension, PMOUSE_INPUT_DATA Input) +void PS2PPProcessPacket(PDEVICE_EXTENSION DeviceExtension, PMOUSE_INPUT_DATA Input, int *wheel) { unsigned char *packet = DeviceExtension->MouseBuffer; @@ -32,16 +32,16 @@ void ps2pp_process_packet(PDEVICE_EXTENSION DeviceExtension, PMOUSE_INPUT_DATA I input_report_rel(dev, packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL, (int) (packet[2] & 8) - (int) (packet[2] & 7)); */ - Input->ButtonData = (UINT)((WHEEL_DELTA) * ((int)(packet[2] & 8) - (int)(packet[2] & 7))); - Input->RawButtons |= ((packet[2] >> 4) & 1) ? GPM_B_FOURTH : 0; - Input->RawButtons |= ((packet[2] >> 5) & 1) ? GPM_B_FIFTH : 0; + *wheel = (int)(packet[2] & 8) - (int)(packet[2] & 7); + Input->RawButtons |= (((packet[2] >> 4) & 1) ? GPM_B_FOURTH : 0); + Input->RawButtons |= (((packet[2] >> 5) & 1) ? GPM_B_FIFTH : 0); break; case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */ - Input->RawButtons |= (packet[2] & 1) ? GPM_B_FOURTH : 0; - Input->RawButtons |= ((packet[2] >> 1) & 1) ? GPM_B_FIFTH : 0; + Input->RawButtons |= ((packet[2] & 1) ? GPM_B_FOURTH : 0); + Input->RawButtons |= (((packet[2] >> 1) & 1) ? GPM_B_FIFTH : 0); /* FIXME - support those buttons??? input_report_key(dev, BTN_BACK, (packet[2] >> 3) & 1); @@ -57,7 +57,7 @@ void ps2pp_process_packet(PDEVICE_EXTENSION DeviceExtension, PMOUSE_INPUT_DATA I input_report_rel(dev, packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL, (int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7)); */ - Input->ButtonData = (UINT)((WHEEL_DELTA) *((int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7))); + *wheel = (int) ((packet[2] >> 4) & 8) - (int) ((packet[2] >> 4) & 7); packet[0] = packet[2] | 0x08; break; @@ -86,16 +86,16 @@ static int ps2pp_cmd(PDEVICE_EXTENSION DeviceExtension, unsigned char *param, un unsigned char d; int i; - if (psmouse_command(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11)) + if (SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11)) return -1; for (i = 6; i >= 0; i -= 2) { d = (command >> i) & 3; - if(psmouse_command(DeviceExtension, &d, PSMOUSE_CMD_SETRES)) + if(SendCommand(DeviceExtension, &d, PSMOUSE_CMD_SETRES)) return -1; } - if (psmouse_command(DeviceExtension, param, PSMOUSE_CMD_POLL)) + if (SendCommand(DeviceExtension, param, PSMOUSE_CMD_POLL)) return -1; return 0; @@ -116,18 +116,18 @@ static void ps2pp_set_smartscroll(PDEVICE_EXTENSION DeviceExtension) ps2pp_cmd(DeviceExtension, param, 0x32); param[0] = 0; - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRES); - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRES); - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRES); + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRES); + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRES); + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRES); - if (DeviceExtension->psmouse_smartscroll == 1) + if (DeviceExtension->SmartScroll == 1) param[0] = 1; else - if (DeviceExtension->psmouse_smartscroll > 2) + if (DeviceExtension->SmartScroll > 2) return; /* else leave param[0] == 0 to disable */ - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRES); + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRES); } /* @@ -136,13 +136,13 @@ static void ps2pp_set_smartscroll(PDEVICE_EXTENSION DeviceExtension) * also good reasons to use it, let the user decide). */ -void ps2pp_set_800dpi(PDEVICE_EXTENSION DeviceExtension) +void PS2PPSet800dpi(PDEVICE_EXTENSION DeviceExtension) { unsigned char param = 3; - psmouse_command(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(DeviceExtension, ¶m, PSMOUSE_CMD_SETRES); + SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); + SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); + SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); + SendCommand(DeviceExtension, ¶m, PSMOUSE_CMD_SETRES); } /* @@ -150,7 +150,7 @@ void ps2pp_set_800dpi(PDEVICE_EXTENSION DeviceExtension) * touchpad. */ -int ps2pp_detect_model(PDEVICE_EXTENSION DeviceExtension, unsigned char *param) +int PS2PPDetectModel(PDEVICE_EXTENSION DeviceExtension, unsigned char *param) { int i; //char *vendor, *name; @@ -162,7 +162,7 @@ int ps2pp_detect_model(PDEVICE_EXTENSION DeviceExtension, unsigned char *param) //vendor = "Logitech"; //DbgPrint("Vendor: %s, name: %s\n", vendor, name); - DeviceExtension->model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); + DeviceExtension->MouseModel = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); /*if (param[1] < 3) clear_bit(BTN_MIDDLE, DeviceExtension->dev.keybit); @@ -172,23 +172,23 @@ int ps2pp_detect_model(PDEVICE_EXTENSION DeviceExtension, unsigned char *param) DeviceExtension->MouseType = PSMOUSE_PS2; for (i = 0; logitech_ps2pp[i] != -1; i++) - if (logitech_ps2pp[i] == DeviceExtension->model) + if (logitech_ps2pp[i] == DeviceExtension->MouseModel) DeviceExtension->MouseType = PSMOUSE_PS2PP; if (DeviceExtension->MouseType == PSMOUSE_PS2PP) { /* for (i = 0; logitech_4btn[i] != -1; i++) - if (logitech_4btn[i] == psmouse->model) + if (logitech_4btn[i] == DeviceExtension->MouseModel) set_bit(BTN_SIDE, psmouse->dev.keybit); */ for (i = 0; logitech_wheel[i] != -1; i++) - if (logitech_wheel[i] == DeviceExtension->model) { + if (logitech_wheel[i] == DeviceExtension->MouseModel) { // set_bit(REL_WHEEL, psmouse->dev.relbit); //name = "Wheel Mouse";DbgPrint("Vendor: %s, name: %s\n", vendor, name); } for (i = 0; logitech_mx[i] != -1; i++) - if (logitech_mx[i] == DeviceExtension->model) { + if (logitech_mx[i] == DeviceExtension->MouseModel) { /* set_bit(BTN_SIDE, psmouse->dev.keybit); set_bit(BTN_EXTRA, psmouse->dev.keybit); set_bit(BTN_BACK, psmouse->dev.keybit); @@ -201,20 +201,20 @@ int ps2pp_detect_model(PDEVICE_EXTENSION DeviceExtension, unsigned char *param) * Do Logitech PS2++ / PS2T++ magic init. */ - if (DeviceExtension->model == 97) { /* TouchPad 3 */ + if (DeviceExtension->MouseModel == 97) { /* TouchPad 3 */ // set_bit(REL_WHEEL, psmouse->dev.relbit); // set_bit(REL_HWHEEL, psmouse->dev.relbit); param[0] = 0x11; param[1] = 0x04; param[2] = 0x68; /* Unprotect RAM */ - psmouse_command(DeviceExtension, param, 0x30d1); + SendCommand(DeviceExtension, param, 0x30d1); param[0] = 0x11; param[1] = 0x05; param[2] = 0x0b; /* Enable features */ - psmouse_command(DeviceExtension, param, 0x30d1); + SendCommand(DeviceExtension, param, 0x30d1); param[0] = 0x11; param[1] = 0x09; param[2] = 0xc3; /* Enable PS2++ */ - psmouse_command(DeviceExtension, param, 0x30d1); + SendCommand(DeviceExtension, param, 0x30d1); param[0] = 0; - if (!psmouse_command(DeviceExtension, param, 0x13d1) && + if (!SendCommand(DeviceExtension, param, 0x13d1) && param[0] == 0x06 && param[1] == 0x00 && param[2] == 0x14) { //name = "TouchPad 3";DbgPrint("Vendor: %s, name: %s\n", vendor, name); return PSMOUSE_PS2TPP; diff --git a/reactos/drivers/input/psaux/mouse.c b/reactos/drivers/input/psaux/mouse.c index bd54679beca..d020fabdd29 100644 --- a/reactos/drivers/input/psaux/mouse.c +++ b/reactos/drivers/input/psaux/mouse.c @@ -1,88 +1,93 @@ +/* + ** PS/2 Mouse Driver + ** Written by Thomas Weidenmueller (w3seek@users.sourceforge.net) + ** For ReactOS (www.reactos.com) + ** Adapted from the linux 2.6 mouse driver +*/ + #include #include #include "controller.h" #include "mouse.h" #include "psaux.h" +#include -#define PSMOUSE_LOGITECH_SMARTSCROLL 1 -/* - * psmouse_process_packet() anlyzes the PS/2 mouse packet contents and - * reports relevant events to the input module. - */ - -static void psmouse_process_packet(PDEVICE_EXTENSION DeviceExtension, PMOUSE_INPUT_DATA Input) +// Parse incoming packets +BOOLEAN FASTCALL +ParsePackets(PDEVICE_EXTENSION DeviceExtension, PMOUSE_INPUT_DATA Input) { - ULONG ButtonsDiff; - unsigned char *packet = DeviceExtension->MouseBuffer; - - /* Determine the current state of the buttons */ - Input->RawButtons = (packet[0] & 1) ? GPM_B_LEFT : 0; - Input->RawButtons |= ((packet[0] >> 1) & 1) ? GPM_B_RIGHT : 0; - Input->RawButtons |= ((packet[0] >> 2) & 1) ? GPM_B_MIDDLE : 0; - -/* - * The PS2++ protocol is a little bit complex - */ - - if (DeviceExtension->MouseType == PSMOUSE_PS2PP || DeviceExtension->MouseType == PSMOUSE_PS2TPP) - ps2pp_process_packet(DeviceExtension, Input); - -/* - * Scroll wheel on IntelliMice, scroll buttons on NetMice - */ - - if (DeviceExtension->MouseType == PSMOUSE_IMPS || DeviceExtension->MouseType == PSMOUSE_GENPS) - { - Input->ButtonData = (UINT)((int)((-(signed char) packet[3]) * WHEEL_DELTA)); - } - -/* - * Scroll wheel and buttons on IntelliMouse Explorer - */ - - if (DeviceExtension->MouseType == PSMOUSE_IMEX) - { - Input->ButtonData = (UINT)((WHEEL_DELTA) * ((int)(packet[3] & 8) - (int)(packet[3] & 7))); - Input->RawButtons |= ((packet[3] >> 4) & 1) ? GPM_B_FOURTH : 0; - Input->RawButtons |= ((packet[3] >> 5) & 1) ? GPM_B_FIFTH : 0; - } - -/* - * Extra buttons on Genius NewNet 3D - */ - - if (DeviceExtension->MouseType == PSMOUSE_GENPS) - { - Input->RawButtons |= ((packet[0] >> 6) & 1) ? GPM_B_FOURTH : 0; - Input->RawButtons |= ((packet[0] >> 7) & 1) ? GPM_B_FIFTH : 0; - } - -/* - * Determine ButtonFlags - */ - + ULONG ButtonsDiff; + int wheel = 0; + unsigned char *packet = DeviceExtension->MouseBuffer; + + /* Determine the current state of the buttons */ + Input->RawButtons = ((packet[0] & 1) ? GPM_B_LEFT : 0); + Input->RawButtons |= (((packet[0] >> 1) & 1) ? GPM_B_RIGHT : 0); + Input->RawButtons |= (((packet[0] >> 2) & 1) ? GPM_B_MIDDLE : 0); + + /* + * The PS2++ protocol is a little bit complex + */ + + if(DeviceExtension->MouseType == PSMOUSE_PS2PP || DeviceExtension->MouseType == PSMOUSE_PS2TPP) + PS2PPProcessPacket(DeviceExtension, Input, &wheel); + + /* + * Scroll wheel on IntelliMice, scroll buttons on NetMice + */ + + if(DeviceExtension->MouseType == PSMOUSE_IMPS || DeviceExtension->MouseType == PSMOUSE_GENPS) + { + wheel = (int)(-(signed char) packet[3]); + } + + /* + * Scroll wheel and buttons on IntelliMouse Explorer + */ + + if(DeviceExtension->MouseType == PSMOUSE_IMEX) + { + wheel = (int)(packet[3] & 8) - (int)(packet[3] & 7); + Input->RawButtons |= (((packet[3] >> 4) & 1) ? GPM_B_FOURTH : 0); + Input->RawButtons |= (((packet[3] >> 5) & 1) ? GPM_B_FIFTH : 0); + } + + /* + * Extra buttons on Genius NewNet 3D + */ + + if(DeviceExtension->MouseType == PSMOUSE_GENPS) + { + Input->RawButtons |= (((packet[0] >> 6) & 1) ? GPM_B_FOURTH : 0); + Input->RawButtons |= (((packet[0] >> 7) & 1) ? GPM_B_FIFTH : 0); + } + + /* + * Determine ButtonFlags + */ + Input->ButtonFlags = 0; ButtonsDiff = DeviceExtension->PreviousButtons ^ Input->RawButtons; - -/* - * Generic PS/2 Mouse - */ + + /* + * Generic PS/2 Mouse + */ if(ButtonsDiff & GPM_B_LEFT) - Input->ButtonFlags |= (Input->RawButtons & GPM_B_LEFT) ? MOUSE_BUTTON_1_DOWN : MOUSE_BUTTON_1_UP; + Input->ButtonFlags |= ((Input->RawButtons & GPM_B_LEFT) ? MOUSE_BUTTON_1_DOWN : MOUSE_BUTTON_1_UP); if(ButtonsDiff & GPM_B_RIGHT) - Input->ButtonFlags |= (Input->RawButtons & GPM_B_RIGHT) ? MOUSE_BUTTON_2_DOWN : MOUSE_BUTTON_2_UP; + Input->ButtonFlags |= ((Input->RawButtons & GPM_B_RIGHT) ? MOUSE_BUTTON_2_DOWN : MOUSE_BUTTON_2_UP); if(ButtonsDiff & GPM_B_MIDDLE) - Input->ButtonFlags |= (Input->RawButtons & GPM_B_MIDDLE) ? MOUSE_BUTTON_3_DOWN : MOUSE_BUTTON_3_UP; + Input->ButtonFlags |= ((Input->RawButtons & GPM_B_MIDDLE) ? MOUSE_BUTTON_3_DOWN : MOUSE_BUTTON_3_UP); if(ButtonsDiff & GPM_B_FOURTH) - Input->ButtonFlags |= (Input->RawButtons & GPM_B_FOURTH) ? MOUSE_BUTTON_4_DOWN : MOUSE_BUTTON_4_UP; + Input->ButtonFlags |= ((Input->RawButtons & GPM_B_FOURTH) ? MOUSE_BUTTON_4_DOWN : MOUSE_BUTTON_4_UP); if(ButtonsDiff & GPM_B_FIFTH) - Input->ButtonFlags |= (Input->RawButtons & GPM_B_FIFTH) ? MOUSE_BUTTON_5_DOWN : MOUSE_BUTTON_5_UP; + Input->ButtonFlags |= ((Input->RawButtons & GPM_B_FIFTH) ? MOUSE_BUTTON_5_DOWN : MOUSE_BUTTON_5_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 @@ -91,81 +96,70 @@ static void psmouse_process_packet(PDEVICE_EXTENSION DeviceExtension, PMOUSE_INP * the default of 100 Hz is plenty. (Stephen Tell) */ /* Determine LastX */ - Input->LastX = packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0; - + if(packet[1]) + Input->LastX = ((packet[0] & 0x10) ? (int)(packet[1] - 256) : (int) packet[1]); + else + Input->LastX = 0; + + //Input->LastX = (packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0); + /* Determine LastY */ - Input->LastY = packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0; + if(packet[2]) + Input->LastY = -((packet[0] & 0x20) ? (int)(packet[2] - 256) : (int) packet[2]); + else + Input->LastY = 0; + + //Input->LastY = (packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0); /* Copy RawButtons to Previous Buttons for Input */ DeviceExtension->PreviousButtons = Input->RawButtons; - if(Input->ButtonData) + if((wheel != 0) && (wheel >= -8) && (wheel <= 7)) + { Input->ButtonFlags |= MOUSE_WHEEL; + Input->ButtonData = (UINT)(wheel * WHEEL_DELTA); + } + + return TRUE; } - // Handle a mouse event - BOOLEAN STDCALL -ps2_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext) +MouseHandler(PKINTERRUPT Interrupt, PVOID ServiceContext) { PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)ServiceContext; PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; PMOUSE_INPUT_DATA Input; ULONG Queue; - BOOLEAN ret = FALSE; + BOOLEAN ret; int state_dx, state_dy; unsigned scancode; unsigned status = controller_read_status(); scancode = controller_read_input(); - if ((status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) == 0) - { - return FALSE; // keyboard_handle_event(scancode); - } - - if(DeviceExtension->acking) - { - switch(scancode) - { - case PSMOUSE_RET_ACK: - DeviceExtension->ack = 1; - break; - case PSMOUSE_RET_NAK: - DeviceExtension->ack = -1; - break; - default: - DeviceExtension->ack = 1; /* Workaround for mice which don't ACK the Get ID command */ - if (DeviceExtension->cmdcnt) - DeviceExtension->cmdbuf[--DeviceExtension->cmdcnt] = scancode; - break; - } - DeviceExtension->acking = 0; - return TRUE; - } - - if (DeviceExtension->cmdcnt) - { - DeviceExtension->cmdbuf[--DeviceExtension->cmdcnt] = scancode; - return TRUE; - } - /* 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 + } + else + { + return FALSE; // keyboard_handle_event(scancode); + } + /* Add this scancode to the mouse event queue. */ DeviceExtension->MouseBuffer[DeviceExtension->MouseBufferPosition] = scancode; DeviceExtension->MouseBufferPosition++; - - Queue = DeviceExtension->ActiveQueue % 2; - /* If the buffer is full, parse the standard ps/2 packets */ - if (DeviceExtension->MouseBufferPosition == - DeviceExtension->MouseBufferSize + (DeviceExtension->MouseType >= PSMOUSE_GENPS)) + /* If the buffer is full, parse this event */ + if (DeviceExtension->MouseBufferPosition == DeviceExtension->MouseBufferSize) { + Queue = DeviceExtension->ActiveQueue % 2; /* Reset the buffer state. */ DeviceExtension->MouseBufferPosition = 0; @@ -177,443 +171,498 @@ ps2_mouse_handler(PKINTERRUPT Interrupt, PVOID ServiceContext) } Input = &DeviceExtension->MouseInputData[Queue] - [DeviceExtension->InputDataCount[Queue]]; + [DeviceExtension->InputDataCount[Queue]]; - psmouse_process_packet(DeviceExtension, Input); + ParsePackets(DeviceExtension, Input); + + /* Send the Input data to the Mouse Class driver */ + DeviceExtension->InputDataCount[Queue]++; + KeInsertQueueDpc(&DeviceExtension->IsrDpc, DeviceObject->CurrentIrp, NULL); - goto end; + return ret; } - - /* - * The synaptics driver has its own resync logic, - * so it needs to receive all bytes one at a time. - */ - if ((DeviceExtension->MouseBufferPosition == 1) && (DeviceExtension->MouseType == PSMOUSE_SYNAPTICS)) - { -// synaptics_process_byte(psmouse, regs); - /* Reset the buffer state. */ - DeviceExtension->MouseBufferPosition = 0; - - return TRUE; - } - - /* FIXME */ - if ((DeviceExtension->MouseBufferPosition == 1) && (DeviceExtension->MouseBuffer[0] == PSMOUSE_RET_BAT)) - { - /* FIXME ????????? */ - DeviceExtension->MouseBufferPosition = 0; - - return TRUE; - } - - return TRUE; - -end: - /* Send the Input data to the Mouse Class driver */ - DeviceExtension->InputDataCount[Queue]++; - KeInsertQueueDpc(&DeviceExtension->IsrDpc, DeviceObject->CurrentIrp, NULL); - return ret; } -/* - * psmouse_sendbyte() sends a byte to the mouse, and waits for acknowledge. - * It doesn't handle retransmission, though it could - because when there would - * be need for retransmissions, the mouse has to be replaced anyway. - */ - -static int psmouse_sendbyte(PDEVICE_EXTENSION DeviceExtension, unsigned char byte) -{ - int timeout = 100; /* 100 msec */ - LARGE_INTEGER Millisecond_Timeout; - - Millisecond_Timeout.QuadPart = 1; - - DeviceExtension->ack = 0; - DeviceExtension->acking = 1; - controller_wait(); - controller_write_command(CONTROLLER_COMMAND_WRITE_MOUSE); - controller_wait(); - controller_write_output(byte); - controller_wait(); - while ((DeviceExtension->ack == 0) && timeout--) - { - KeDelayExecutionThread (KernelMode, FALSE, &Millisecond_Timeout); - } - return -(DeviceExtension->ack <= 0); +// 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); } -/* - * psmouse_command() sends a command and its parameters to the mouse, - * then waits for the response and puts it in the param array. - */ -int psmouse_command(PDEVICE_EXTENSION DeviceExtension, unsigned char *param, int command) +// Sends a byte to the mouse +static int SendByte(PDEVICE_EXTENSION DeviceExtension, unsigned char byte) { - LARGE_INTEGER Millisecond_Timeout; - int timeout = 500; /* 500 msec */ - int send = (command >> 12) & 0xf; - int receive = (command >> 8) & 0xf; - int i; - - Millisecond_Timeout.QuadPart = 1; - - DeviceExtension->cmdcnt = receive; - if (command == PSMOUSE_CMD_RESET_BAT) - timeout = 2000; /* 2 sec */ - - if (command & 0xff) - if (psmouse_sendbyte(DeviceExtension, command & 0xff)) - return (DeviceExtension->cmdcnt = 0) - 1; - - for (i = 0; i < send; i++) - if (psmouse_sendbyte(DeviceExtension, param[i])) - return (DeviceExtension->cmdcnt = 0) - 1; - - while (DeviceExtension->cmdcnt && timeout--) { - - if (DeviceExtension->cmdcnt == 1 && command == PSMOUSE_CMD_RESET_BAT) - timeout = 100; - - if (DeviceExtension->cmdcnt == 1 && command == PSMOUSE_CMD_GETID && - DeviceExtension->cmdbuf[1] != 0xab && DeviceExtension->cmdbuf[1] != 0xac) { - DeviceExtension->cmdcnt = 0; - break; - } - - KeDelayExecutionThread (KernelMode, FALSE, &Millisecond_Timeout); - } - - for (i = 0; i < receive; i++) - param[i] = DeviceExtension->cmdbuf[(receive - 1) - i]; - if (DeviceExtension->cmdcnt) - return (DeviceExtension->cmdcnt = 0) - 1; - - return 0; -} - -/* - * psmouse_extensions() probes for any extensions to the basic PS/2 protocol - * the mouse may have. - */ - -static int psmouse_extensions(PDEVICE_EXTENSION DeviceExtension) -{ - unsigned char param[4]; - - param[0] = 0; - //vendor = "Generic"; - //name = "Mouse"; - DeviceExtension->model = 0; - - if (DeviceExtension->psmouse_noext) - { - return PSMOUSE_PS2; - } - -/* - * Try Synaptics TouchPad magic ID - */ - - param[0] = 0; - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRES); - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRES); - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRES); - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRES); - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_GETINFO); - - if (param[1] == 0x47) { - //vendor = "Synaptics"; - //name = "TouchPad"; - - if (!synaptics_init(DeviceExtension)) - return PSMOUSE_SYNAPTICS; - else - return PSMOUSE_PS2; - } - -/* - * Try Genius NetMouse magic init. - */ - - param[0] = 3; - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRES); - psmouse_command(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_GETINFO); - - if (param[0] == 0x00 && param[1] == 0x33 && param[2] == 0x55) { - - //set_bit(BTN_EXTRA, psmouse->dev.keybit); - //set_bit(BTN_SIDE, psmouse->dev.keybit); - //set_bit(REL_WHEEL, psmouse->dev.relbit); - - //vendor = "Genius"; - //name = "Wheel Mouse"; - return PSMOUSE_GENPS; - } - -/* - * Try Logitech magic ID. - */ - - param[0] = 0; - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRES); - psmouse_command(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); - psmouse_command(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); - param[1] = 0; - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_GETINFO); - - if (param[1]) { - int type = ps2pp_detect_model(DeviceExtension, param); - if (type) - { - return type; - } - } - -/* - * Try IntelliMouse magic init. - */ - - param[0] = 200; - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRATE); - param[0] = 100; - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRATE); - param[0] = 80; - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRATE); - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_GETID); - - if (param[0] == 3) { - - // set_bit(REL_WHEEL, DeviceExtension->dev.relbit); - -/* - * Try IntelliMouse/Explorer magic init. - */ - - param[0] = 200; - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRATE); - param[0] = 200; - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRATE); - param[0] = 80; - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRATE); - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_GETID); - - if (param[0] == 4) { - - //set_bit(BTN_SIDE, psmouse->dev.keybit); - //set_bit(BTN_EXTRA, psmouse->dev.keybit); - - //name = "Explorer Mouse"; - return PSMOUSE_IMEX; - } - - //name = "Wheel Mouse"; - return PSMOUSE_IMPS; - } - -/* - * Okay, all failed, we have a standard mouse here. The number of the buttons - * is still a question, though. We assume 3. - */ - return PSMOUSE_PS2; -} - -/* - * psmouse_test() probes for a PS/2 mouse. - */ - -static int psmouse_test(PDEVICE_EXTENSION DeviceExtension) -{ - unsigned char param[2]; -/* - * First, we check if it's a mouse. It should send 0x00 or 0x03 - * in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. - */ - - param[0] = param[1] = 0xa5; - - if (psmouse_command(DeviceExtension, param, PSMOUSE_CMD_GETID)) - return -1; - - if (param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04) - return -1; - -/* - * Then we reset and disable the mouse so that it doesn't generate events. - */ - - if (psmouse_command(DeviceExtension, NULL, PSMOUSE_CMD_RESET_DIS)) - return -1; - -/* - * And here we try to determine if it has any extensions over the - * basic PS/2 3-button mouse. - */ - return DeviceExtension->MouseType = psmouse_extensions(DeviceExtension); -} - -/* Check if this is a dual port controller. */ - -BOOLEAN detect_ps2_port(void) -{ - int loops; - unsigned scancode; - BOOLEAN return_value = FALSE; + int timeout = 100; /* 100 msec */ + int scancode; + unsigned char status; LARGE_INTEGER Millisecond_Timeout; - + Millisecond_Timeout.QuadPart = 1; + + DeviceExtension->ack = 0; + DeviceExtension->acking = 1; - //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++) + controller_wait(); + controller_write_command(CONTROLLER_COMMAND_WRITE_MOUSE); + controller_wait(); + controller_write_output(byte); + while ((DeviceExtension->ack == 0) && timeout--) { - unsigned char status = controller_read_status(); - + status = controller_read_status(); if((status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0) { scancode = controller_read_input(); - if ((status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) != 0) + if(scancode >= 0) { - return_value = TRUE; + switch(scancode) + { + case PSMOUSE_RET_ACK: + DeviceExtension->ack = 1; + break; + case PSMOUSE_RET_NAK: + DeviceExtension->ack = -1; + break; + default: + DeviceExtension->ack = 1; /* Workaround for mice which don't ACK the Get ID command */ + if (DeviceExtension->RepliesExpected) + DeviceExtension->pkt[--DeviceExtension->RepliesExpected] = scancode; + break; + } + return (int)(-(DeviceExtension->ack <= 0)); } + } + KeDelayExecutionThread (KernelMode, FALSE, &Millisecond_Timeout); + } + return (int)(-(DeviceExtension->ack <= 0)); +} + + +// Send a PS/2 command to the mouse. +int SendCommand(PDEVICE_EXTENSION DeviceExtension, unsigned char *param, int command) +{ + LARGE_INTEGER Millisecond_Timeout; + unsigned char status; + int scancode; + int timeout = 500; /* 500 msec */ + int send = (command >> 12) & 0xf; + int receive = (command >> 8) & 0xf; + int i; + + Millisecond_Timeout.QuadPart = 1; + + DeviceExtension->RepliesExpected = receive; + if (command == PSMOUSE_CMD_RESET_BAT) + timeout = 2000; /* 2 sec */ + + if (command & 0xff) + if (SendByte(DeviceExtension, command & 0xff)) + return (int)(DeviceExtension->RepliesExpected = 0) - 1; + + for (i = 0; i < send; i++) + if (SendByte(DeviceExtension, param[i])) + return (int)(DeviceExtension->RepliesExpected = 0) - 1; + + while (DeviceExtension->RepliesExpected && timeout--) + { + if (DeviceExtension->RepliesExpected == 1 && command == PSMOUSE_CMD_RESET_BAT) + timeout = 100; + + if (DeviceExtension->RepliesExpected == 1 && command == PSMOUSE_CMD_GETID && + DeviceExtension->pkt[1] != 0xab && DeviceExtension->pkt[1] != 0xac) + { + DeviceExtension->RepliesExpected = 0; break; } + + status = controller_read_status(); + if((status & CONTROLLER_STATUS_OUTPUT_BUFFER_FULL) != 0) + { + scancode = controller_read_input(); + if(scancode >= 0) + { + DeviceExtension->pkt[--DeviceExtension->RepliesExpected] = scancode; + } + } KeDelayExecutionThread (KernelMode, FALSE, &Millisecond_Timeout); } + + for (i = 0; i < receive; i++) + param[i] = DeviceExtension->pkt[(receive - 1) - i]; + + if (DeviceExtension->RepliesExpected) + return (int)(DeviceExtension->RepliesExpected = 0) - 1; + + return 0; +} + + +// changes the resolution of the mouse +void SetResolution(PDEVICE_EXTENSION DeviceExtension) +{ + unsigned char param[1]; - return return_value; + if(DeviceExtension->MouseType == PSMOUSE_PS2PP && DeviceExtension->Resolution > 400) + { + PS2PPSet800dpi(DeviceExtension); + return; + } + + if(!DeviceExtension->Resolution || DeviceExtension->Resolution >= 200) + param[0] = 3; + else if(DeviceExtension->Resolution >= 100) + param[0] = 2; + else if(DeviceExtension->Resolution >= 50) + param[0] = 1; + else if(DeviceExtension->Resolution ) + param[0] = 0; + + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRES); } -/* - * Here we set the mouse resolution. - */ -static void psmouse_set_resolution(PDEVICE_EXTENSION DeviceExtension) +// Detect mouse models +int TestMouseExtensions(PDEVICE_EXTENSION DeviceExtension) { - unsigned char param[1]; - - if (DeviceExtension->MouseType == PSMOUSE_PS2PP && DeviceExtension->Resolution > 400) { - ps2pp_set_800dpi(DeviceExtension); - return; - } - - if (!DeviceExtension->Resolution || DeviceExtension->Resolution >= 200) - param[0] = 3; - else if (DeviceExtension->Resolution >= 100) - param[0] = 2; - else if (DeviceExtension->Resolution >= 50) - param[0] = 1; - else if (DeviceExtension->Resolution) - param[0] = 0; - - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRES); + unsigned char param[4]; + int type = 0; + + param[0] = 0; + + // vendor = Generic + // name = Mouse + DeviceExtension->MouseModel = 0; + + /* + * Try Synaptics TouchPad magic ID + */ + param[0] = 0; + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRES); + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRES); + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRES); + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRES); + SendCommand(DeviceExtension, param, PSMOUSE_CMD_GETINFO); + if(param[1] == 0x47) + { + // vendor = Synaptics + // name = TouchPad + if(!InitSynaptics(DeviceExtension)) + return PSMOUSE_SYNAPTICS; + else + return PSMOUSE_PS2; + } + + /* + * Try Genius NetMouse magic init. + */ + param[0] = 3; + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRES); + SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); + SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); + SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); + SendCommand(DeviceExtension, param, PSMOUSE_CMD_GETINFO); + if(param[0] == 0x00 && param[1] == 0x33 && param[2] == 0x55) + { + // vendor = Genius + // name = Wheel Mouse + // Features = 4th, 5th, Wheel + return PSMOUSE_GENPS; + } + + /* + * Try Logitech magic ID. + */ + param[0] = 0; + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRES); + SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); + SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); + SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); + param[1] = 0; + SendCommand(DeviceExtension, param, PSMOUSE_CMD_GETINFO); + if(param[1]) + { + type = PS2PPDetectModel(DeviceExtension, param); + if(type) + return type; + } + + /* + * Try IntelliMouse magic init. + */ + param[0] = 200; + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRATE); + param[0] = 100; + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRATE); + param[0] = 80; + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRATE); + SendCommand(DeviceExtension, param, PSMOUSE_CMD_GETID); + if(param[0] == 3) + { + // Features = Wheel + + /* + * Try IntelliMouse/Explorer magic init. + */ + param[0] = 200; + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRATE); + param[0] = 200; + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRATE); + param[0] = 80; + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRATE); + SendCommand(DeviceExtension, param, PSMOUSE_CMD_GETID); + if(param[0] == 4) + { + // name = Explorer Mouse + // Features = 4th, 5th, Wheel + return PSMOUSE_IMEX; + } + + // name = Wheel Mouse + return PSMOUSE_IMPS; + } + +/* + * Okay, all failed, we have a standard mouse here. The number of the buttons + * is still a question, though. We assume 3. + */ + return PSMOUSE_PS2; } -/* - * psmouse_initialize() initializes the mouse to a sane state. - */ -static void psmouse_initialize(PDEVICE_EXTENSION DeviceExtension) +// Detect if mouse is just a standard ps/2 mouse +int TestMouse(PDEVICE_EXTENSION DeviceExtension) { - unsigned char param[2]; -/* - * We set the mouse report rate to a highest possible value. - * We try 100 first in case mouse fails to set 200. - */ - - param[0] = 100; - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRATE); - - param[0] = 200; - psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETRATE); + unsigned char param[4]; + + param[0] = param[1] = 0xa5; + + /* + * First, we check if it's a mouse. It should send 0x00 or 0x03 + * in case of an IntelliMouse in 4-byte mode or 0x04 for IM Explorer. + */ + if(SendCommand(DeviceExtension, param, PSMOUSE_CMD_GETID)) + return -1; + + if(param[0] != 0x00 && param[0] != 0x03 && param[0] != 0x04) + return -1; + + /* + * Then we reset and disable the mouse so that it doesn't generate events. + */ + + if(DeviceExtension->NoExtensions) + { + return DeviceExtension->MouseType = PSMOUSE_PS2; + } + + if(SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_RESET_DIS)) + return -1; -/* - * We also set the resolution and scaling. - */ - - //psmouse_set_resolution(DeviceExtension); - psmouse_command(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); - -/* - * We set the mouse into streaming mode. - */ - - //psmouse_command(DeviceExtension, param, PSMOUSE_CMD_SETSTREAM); - -/* - * Last, we enable the mouse so that we get reports from it. - */ - - if (psmouse_command(DeviceExtension, NULL, PSMOUSE_CMD_ENABLE)) - DbgPrint("mouse.c: Failed to enable mouse\n"); + return DeviceExtension->MouseType = TestMouseExtensions(DeviceExtension); } + + +// Initialize and enable the mouse +void InitializeMouse(PDEVICE_EXTENSION DeviceExtension) +{ + unsigned char param[4]; + + /* + * We set the mouse report rate to a highest possible value. + * We try 100 first in case mouse fails to set 200. + */ -/* Initialize the PS/2 mouse support */ -BOOLEAN mouse_init (PDEVICE_OBJECT DeviceObject) + param[0] = 200; + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRATE); + + param[0] = 100; + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETRATE); + + SetResolution(DeviceExtension); + SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_SETSCALE11); + + /* + * We set the mouse into streaming mode. + */ + + SendCommand(DeviceExtension, param, PSMOUSE_CMD_SETSTREAM); + + /* + * Last, we enable the mouse so that we get reports from it. + */ + + if(SendCommand(DeviceExtension, NULL, PSMOUSE_CMD_ENABLE)) + DbgPrint("mouse.c: Failed to enable mouse!\n"); +} + + +// Load settings from registry (by Filip Navara) +BOOL LoadMouseSettings(PDEVICE_EXTENSION DeviceExtension, PUNICODE_STRING RegistryPath) +{ + /* + * Get the parameters from registry + */ + ULONG DefaultMouseResolution = 0; + ULONG DisableExtensionDetection = 1; + UNICODE_STRING ParametersPath; + RTL_QUERY_REGISTRY_TABLE Parameters[3]; + PWSTR ParametersKeyPath = L"\\Parameters"; + NTSTATUS Status; + + RtlZeroMemory(Parameters, sizeof(Parameters)); + + /* + * Formulate path to registry + */ + RtlInitUnicodeString(&ParametersPath, NULL); + ParametersPath.MaximumLength = RegistryPath->Length + + (wcslen(ParametersKeyPath) * sizeof(WCHAR)) + sizeof(UNICODE_NULL); + ParametersPath.Buffer = ExAllocatePool(PagedPool, + ParametersPath.MaximumLength); + if (!ParametersPath.Buffer) + { + DPRINT("Can't allocate buffer for parameters\n"); + return FALSE; + } + RtlZeroMemory(ParametersPath.Buffer, ParametersPath.MaximumLength); + RtlAppendUnicodeToString(&ParametersPath, RegistryPath->Buffer); + RtlAppendUnicodeToString(&ParametersPath, ParametersKeyPath); + DPRINT("Parameters Path: %wZ\n", &ParametersPath); + + Parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[0].Name = L"Resolution"; + Parameters[0].EntryContext = &DeviceExtension->Resolution; + Parameters[0].DefaultType = REG_DWORD; + Parameters[0].DefaultData = &DefaultMouseResolution; + Parameters[0].DefaultLength = sizeof(ULONG); + + Parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT; + Parameters[1].Name = L"DisableExtensionDetection"; + Parameters[1].EntryContext = &DeviceExtension->NoExtensions; + Parameters[1].DefaultType = REG_DWORD; + Parameters[1].DefaultData = &DisableExtensionDetection; + Parameters[1].DefaultLength = sizeof(ULONG); + + Status = RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, + ParametersPath.Buffer, + Parameters, + NULL, + NULL); + + if (!NT_SUCCESS(Status)) + { + DPRINT("RtlQueryRegistryValues failed (0x%x)\n", Status); + return FALSE; + } + return TRUE; +} + + +// Initialize the PS/2 mouse support +BOOLEAN SetupMouse(PDEVICE_OBJECT DeviceObject, PUNICODE_STRING RegistryPath) { PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; ULONG MappedIrq; KIRQL Dirql; KAFFINITY Affinity; unsigned scancode; + unsigned char status; + LARGE_INTEGER Millisecond_Timeout; + + Millisecond_Timeout.QuadPart = 1; - DeviceExtension->MouseBufferPosition = 0; - DeviceExtension->MouseBufferSize = 3; /* standard PS/2 packet size */ - DeviceExtension->PreviousButtons = 0; - DeviceExtension->MouseType = 0; - - DeviceExtension->psmouse_noext = 1; // Set this to 1 if you don't want to detect enhanced mice (BOCHS?) - DeviceExtension->psmouse_smartscroll = PSMOUSE_LOGITECH_SMARTSCROLL; - DeviceExtension->Resolution = 0; // Set this to the resolution of the mouse - + /* setup */ + DeviceExtension->NoExtensions = 0; DeviceExtension->InputDataCount[0] = 0; DeviceExtension->InputDataCount[1] = 0; DeviceExtension->ActiveQueue = 0; - + DeviceExtension->MouseBufferPosition = 0; + DeviceExtension->MouseBufferSize = 3; + DeviceExtension->Resolution = 0; + DeviceExtension->RepliesExpected = 0; + DeviceExtension->PreviousButtons = 0; + DeviceExtension->SmartScroll = 1; DeviceExtension->ack = 0; DeviceExtension->acking = 0; - DeviceExtension->HasMouse = detect_ps2_port(); - - if(!DeviceExtension->HasMouse) - return FALSE; + LoadMouseSettings(DeviceExtension, RegistryPath); // Enable the PS/2 mouse port - controller_write_command_word (CONTROLLER_COMMAND_MOUSE_ENABLE); - - // Enable controller interrupts - controller_wait(); - controller_write_command (CONTROLLER_COMMAND_WRITE_MODE); - controller_wait(); - controller_write_output (MOUSE_INTERRUPTS_ON); - controller_wait(); - - // 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); + controller_write_command_word (CONTROLLER_COMMAND_MOUSE_ENABLE); - psmouse_test(DeviceExtension); - psmouse_initialize(DeviceExtension); + //InitializeMouse(DeviceExtension); + DeviceExtension->MouseType = TestMouse(DeviceExtension); + + if(DeviceExtension->MouseType > 0) + { + /* set the incoming buffer to 4 if needed */ + DeviceExtension->MouseBufferSize += (DeviceExtension->MouseType >= PSMOUSE_GENPS); + + DPRINT("Detected Mouse: 0x%x\n", DeviceExtension->MouseType); + + InitializeMouse(DeviceExtension); + + // 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, MouseHandler, DeviceObject, NULL, MappedIrq, + Dirql, Dirql, 0, FALSE, Affinity, FALSE); + } return TRUE; } + +// Check if this is a dual port controller. +BOOLEAN DetectPS2Port(void) +{ + int loops; + unsigned scancode; + BOOLEAN return_value = FALSE; + LARGE_INTEGER Millisecond_Timeout; + + Millisecond_Timeout.QuadPart = 1; + + //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) + { + scancode = controller_read_input(); + if((status & CONTROLLER_STATUS_MOUSE_OUTPUT_BUFFER_FULL) != 0) + { + return_value = TRUE; + } + break; + } + + KeDelayExecutionThread(KernelMode, FALSE, &Millisecond_Timeout); + } + + return return_value; +} + diff --git a/reactos/drivers/input/psaux/mouse.h b/reactos/drivers/input/psaux/mouse.h index 68afd6c54e3..192a452c0b1 100644 --- a/reactos/drivers/input/psaux/mouse.h +++ b/reactos/drivers/input/psaux/mouse.h @@ -1,51 +1,7 @@ // 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 -#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_READ_DEVICETYPE 0xF2 // Read Device Type -#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_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 1 -#define GPM_B_RIGHT 2 -#define GPM_B_MIDDLE 4 -#define GPM_B_FOURTH 0x10 -#define GPM_B_FIFTH 0x20 - -// Some aux operations take long time -#define MAX_RETRIES 60 - -// Hardware defines -#define MOUSE_IRQ 12 -#define MOUSE_WRAP_MASK 0x1F - -#define MOUSE_ISINTELLIMOUSE 0x03 -#define MOUSE_ISINTELLIMOUSE5BUTTONS 0x04 - -// ----------------------------------------------------------------------------- - -#define WHEEL_DELTA 120 +#define WHEEL_DELTA (120) #define PSMOUSE_CMD_SETSCALE11 0x00e6 #define PSMOUSE_CMD_SETRES 0x10e8 @@ -62,6 +18,24 @@ #define PSMOUSE_RET_ACK 0xfa #define PSMOUSE_RET_NAK 0xfe +#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 0x01 +#define GPM_B_RIGHT 0x02 +#define GPM_B_MIDDLE 0x04 +#define GPM_B_FOURTH 0x10 +#define GPM_B_FIFTH 0x20 + +// Mouse types #define PSMOUSE_PS2 1 #define PSMOUSE_PS2PP 2 #define PSMOUSE_PS2TPP 3 @@ -70,7 +44,15 @@ #define PSMOUSE_IMEX 6 #define PSMOUSE_SYNAPTICS 7 -#define input_regs(a,b) do { (a)->regs = (b); } while (0) +// Some aux operations take long time +#define MAX_RETRIES 60 + +// Hardware defines +#define MOUSE_IRQ 12 +#define MOUSE_WRAP_MASK 0x1F + +#define MOUSE_ISINTELLIMOUSE 0x03 +#define MOUSE_ISINTELLIMOUSE5BUTTONS 0x04 static PIRP CurrentIrp; static ULONG MouseDataRead; diff --git a/reactos/drivers/input/psaux/psaux.c b/reactos/drivers/input/psaux/psaux.c index 6116650b834..ecbdb37bfe5 100644 --- a/reactos/drivers/input/psaux/psaux.c +++ b/reactos/drivers/input/psaux/psaux.c @@ -230,7 +230,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) UNICODE_STRING SymlinkName; PDEVICE_EXTENSION DeviceExtension; - if (detect_ps2_port() == TRUE) { + if (DetectPS2Port() == TRUE) { DbgPrint("PS2 Port Driver version 0.0.2\n"); } else { DbgPrint("PS2 port not found.\n"); @@ -244,7 +244,7 @@ DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) DeviceObject = AllocatePointerDevice(DriverObject); - mouse_init(DeviceObject); + SetupMouse(DeviceObject, RegistryPath); return(STATUS_SUCCESS); } diff --git a/reactos/drivers/input/psaux/psaux.h b/reactos/drivers/input/psaux/psaux.h index fdd3143d165..1782e5da438 100644 --- a/reactos/drivers/input/psaux/psaux.h +++ b/reactos/drivers/input/psaux/psaux.h @@ -1,5 +1,3 @@ -#include -#include typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT DeviceObject; @@ -7,29 +5,24 @@ typedef struct _DEVICE_EXTENSION { ULONG ActiveQueue; ULONG InputDataCount[2]; MOUSE_INPUT_DATA MouseInputData[2][MOUSE_BUFFER_SIZE]; - BOOL HasMouse; - - unsigned char MouseType; - unsigned char model; unsigned char MouseBuffer[8]; + unsigned char pkt[8]; + unsigned char MouseType; + unsigned char MouseModel; + unsigned char ack, acking; + ULONG SmartScroll; + ULONG NoExtensions; UINT MouseBufferPosition; UINT MouseBufferSize; UINT Resolution; - - unsigned char cmdbuf[8]; - unsigned char cmdcnt; - unsigned char pktcnt; - char acking; - volatile char ack; - - int psmouse_noext; - int psmouse_smartscroll; - + UINT RepliesExpected; ULONG PreviousButtons; + CLASS_INFORMATION ClassInformation; PKINTERRUPT MouseInterrupt; KDPC IsrDpc; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; + diff --git a/reactos/drivers/input/psaux/synaptics.c b/reactos/drivers/input/psaux/synaptics.c index 9d0b24c6a82..4a9a209cfa9 100644 --- a/reactos/drivers/input/psaux/synaptics.c +++ b/reactos/drivers/input/psaux/synaptics.c @@ -402,7 +402,7 @@ void synaptics_process_byte(struct psmouse *psmouse, struct pt_regs *regs) #else -int synaptics_init(PDEVICE_EXTENSION DeviceExtension) +int InitSynaptics(PDEVICE_EXTENSION DeviceExtension) { return -1; }