BOOLEAN MouseInit(BYTE PS2Connector) { /* Finish to plug the mouse to the specified PS/2 port */ MousePS2Port = PS2Connector; PS2SetDeviceCmdProc(MousePS2Port, NULL, MouseCommand); MouseMutex = CreateMutex(NULL, FALSE, NULL); if (MouseMutex == NULL) return FALSE; StreamTimer = CreateHardwareTimer(HARDWARE_TIMER_ENABLED, HZ_TO_NS(100), MouseStreamingCallback); MouseReset(); return TRUE; }
CLIPPER MReset() { MouseReset(); }
static VOID WINAPI MouseCommand(LPVOID Param, BYTE Command) { /* Check if we were waiting for a data byte */ if (MouseDataByteWait) { PS2QueuePush(MousePS2Port, MOUSE_ACK); switch (MouseDataByteWait) { /* Set Resolution */ case 0xE8: { Resolution = Command; break; } /* Set Sample Rate */ case 0xF3: { /* Check for the scroll wheel enabling sequence */ if (MouseId == 0) { if (Command == ScrollMagic[ScrollMagicCounter]) { ScrollMagicCounter++; if (ScrollMagicCounter == 3) MouseId = 3; } else { ScrollMagicCounter = 0; } } /* Check for the 5-button enabling sequence */ if (MouseId == 3) { if (Command == ExtraButtonMagic[ExtraButtonMagicCounter]) { ExtraButtonMagicCounter++; if (ExtraButtonMagicCounter == 3) MouseId = 4; } else { ExtraButtonMagicCounter = 0; } } MouseCycles = 1000 / (UINT)Command; break; } default: { /* Shouldn't happen */ ASSERT(FALSE); } } MouseDataByteWait = 0; return; } /* Check if we're in wrap mode */ if (Mode == MOUSE_WRAP_MODE) { /* * In this mode, we just echo whatever byte we get, * except for the 0xEC and 0xFF commands. */ if (Command != 0xEC && Command != 0xFF) { PS2QueuePush(MousePS2Port, Command); return; } } switch (Command) { /* Set 1:1 Scaling */ case 0xE6: { Scaling = FALSE; PS2QueuePush(MousePS2Port, MOUSE_ACK); break; } /* Set 2:1 Scaling */ case 0xE7: { Scaling = TRUE; PS2QueuePush(MousePS2Port, MOUSE_ACK); break; } /* Set Resolution */ case 0xE8: /* Set Sample Rate */ case 0xF3: { MouseDataByteWait = Command; PS2QueuePush(MousePS2Port, MOUSE_ACK); break; } /* Read Status */ case 0xE9: { BYTE Status = ButtonState & 7; if (Scaling) Status |= 1 << 4; if (MouseReporting) Status |= 1 << 5; if (Mode == MOUSE_REMOTE_MODE) Status |= 1 << 6; PS2QueuePush(MousePS2Port, MOUSE_ACK); PS2QueuePush(MousePS2Port, Status); PS2QueuePush(MousePS2Port, Resolution); PS2QueuePush(MousePS2Port, (BYTE)(1000 / MouseCycles)); break; } /* Enter Streaming Mode */ case 0xEA: { MouseResetCounters(); Mode = MOUSE_STREAMING_MODE; PS2QueuePush(MousePS2Port, MOUSE_ACK); break; } /* Read Packet */ case 0xEB: { PS2QueuePush(MousePS2Port, MOUSE_ACK); MouseGetPacket(&LastPacket); MouseDispatchPacket(&LastPacket); break; } /* Return from Wrap Mode */ case 0xEC: { if (Mode == MOUSE_WRAP_MODE) { /* Restore the previous mode */ MouseResetCounters(); Mode = PreviousMode; PS2QueuePush(MousePS2Port, MOUSE_ACK); } else { PS2QueuePush(MousePS2Port, MOUSE_ERROR); } break; } /* Enter Wrap Mode */ case 0xEE: { if (Mode != MOUSE_WRAP_MODE) { /* Save the previous mode */ PreviousMode = Mode; } MouseResetCounters(); Mode = MOUSE_WRAP_MODE; PS2QueuePush(MousePS2Port, MOUSE_ACK); break; } /* Enter Remote Mode */ case 0xF0: { MouseResetCounters(); Mode = MOUSE_REMOTE_MODE; PS2QueuePush(MousePS2Port, MOUSE_ACK); break; } /* Get Mouse ID */ case 0xF2: { PS2QueuePush(MousePS2Port, MOUSE_ACK); PS2QueuePush(MousePS2Port, MouseId); break; } /* Enable Reporting */ case 0xF4: { MouseReporting = TRUE; MouseResetCounters(); PS2QueuePush(MousePS2Port, MOUSE_ACK); break; } /* Disable Reporting */ case 0xF5: { MouseReporting = FALSE; MouseResetCounters(); PS2QueuePush(MousePS2Port, MOUSE_ACK); break; } /* Set Defaults */ case 0xF6: { /* Reset the configuration and counters */ MouseResetConfig(); MouseResetCounters(); PS2QueuePush(MousePS2Port, MOUSE_ACK); break; } /* Resend */ case 0xFE: { PS2QueuePush(MousePS2Port, MOUSE_ACK); MouseDispatchPacket(&LastPacket); break; } /* Reset */ case 0xFF: { /* Send ACKnowledge */ PS2QueuePush(MousePS2Port, MOUSE_ACK); MouseReset(); /* Send the Basic Assurance Test success code and the device ID */ PS2QueuePush(MousePS2Port, MOUSE_BAT_SUCCESS); PS2QueuePush(MousePS2Port, MouseId); break; } /* Unknown command */ default: { PS2QueuePush(MousePS2Port, MOUSE_ERROR); } } }