bool Ps2Input::pollEvent(Common::Event *event) { bool checkPadMouse, checkPadKbd; checkPadMouse = checkPadKbd = _pad->padAlive(); if (_mouseLoaded && (PS2MouseEnum() > 0)) { // usb mouse connected mouse_data mData; PS2MouseRead(&mData); if ((_posX != mData.x) || (_posY != mData.y)) { event->mouse.x = _posX = mData.x; event->mouse.y = _posY = mData.y; event->type = Common::EVENT_MOUSEMOVE; return true; } if (mData.buttons != _mButtons) { uint16 change = _mButtons ^ mData.buttons; _mButtons = mData.buttons; if (change & (PS2MOUSE_BTN1 | PS2MOUSE_BTN2)) { if (change & PS2MOUSE_BTN1) event->type = (_mButtons & PS2MOUSE_BTN1) ? Common::EVENT_LBUTTONDOWN : Common::EVENT_LBUTTONUP; else event->type = (_mButtons & PS2MOUSE_BTN2) ? Common::EVENT_RBUTTONDOWN : Common::EVENT_RBUTTONUP; event->mouse.x = _posX; event->mouse.y = _posY; return true; } } checkPadMouse = false; } if (_kbdLoaded) { // there's no way to tell if there's actually a keyboard connected PS2KbdRawKey key; if (PS2KbdReadRaw(&key) == 1) { if (_usbToSdlk[key.key]) { if ((_usbToSdlk[key.key] == Common::KEYCODE_LSHIFT) || (_usbToSdlk[key.key] == Common::KEYCODE_RSHIFT)) { if (key.state & 1) _keyFlags |= Common::KBD_SHIFT; else _keyFlags &= ~Common::KBD_SHIFT; } else if ((_usbToSdlk[key.key] == Common::KEYCODE_LCTRL) || (_usbToSdlk[key.key] == Common::KEYCODE_RCTRL)) { if (key.state & 1) _keyFlags |= Common::KBD_CTRL; else _keyFlags &= ~Common::KBD_CTRL; } else if ((_usbToSdlk[key.key] == Common::KEYCODE_LALT) || (_usbToSdlk[key.key] == Common::KEYCODE_RALT)) { if (key.state & 1) _keyFlags |= Common::KBD_ALT; else _keyFlags &= ~Common::KBD_ALT; } if (key.state & 1) // down event->type = Common::EVENT_KEYDOWN; else event->type = Common::EVENT_KEYUP; event->kbd.flags = 0; event->kbd.keycode = _usbToSdlk[key.key]; event->kbd.ascii = mapKey(_usbToSdlk[key.key], _keyFlags); return true; } else printf("unknown keycode %02X - %02X\n", key.state, key.key); } } if (checkPadMouse || checkPadKbd) { // no usb mouse, simulate it using the pad uint16 buttons; int16 joyh, joyv; _pad->readPad(&buttons, &joyh, &joyv); uint16 btnChange = buttons ^ _padLastButtons; if (checkPadMouse) { if (btnChange & (PAD_CROSS | PAD_CIRCLE)) { if (btnChange & PAD_CROSS) event->type = (buttons & PAD_CROSS) ? Common::EVENT_LBUTTONDOWN : Common::EVENT_LBUTTONUP; else event->type = (buttons & PAD_CIRCLE) ? Common::EVENT_RBUTTONDOWN : Common::EVENT_RBUTTONUP; event->mouse.x = _posX; event->mouse.y = _posY; _padLastButtons = buttons; return true; } uint32 time = _system->getMillis(); if (time - _lastPadCheck > PAD_CHECK_TIME) { _lastPadCheck = time; int16 newX = _posX; int16 newY = _posY; if ((ABS(joyh) > JOY_THRESHOLD) || (ABS(joyv) > JOY_THRESHOLD)) { newX += joyh / 20; newY += joyv / 20; } else if (buttons & PAD_DIR_MASK) { if (_padLastButtons & PAD_DIR_MASK) { if (_padAccel < 16) _padAccel++; } else _padAccel = 0; _padLastButtons = buttons; if (buttons & PAD_LEFT) newX -= _padAccel >> 2; if (buttons & PAD_RIGHT) newX += _padAccel >> 2; if (buttons & PAD_UP) newY -= _padAccel >> 2; if (buttons & PAD_DOWN) newY += _padAccel >> 2; } newX = ((newX < (int16)_minx) ? (_minx) : ((newX > (int16)_maxx) ? (_maxx) : ((int16)newX))); newY = ((newY < (int16)_miny) ? (_miny) : ((newY > (int16)_maxy) ? (_maxy) : ((int16)newY))); if ((_posX != newX) || (_posY != newY)) { event->type = Common::EVENT_MOUSEMOVE; event->mouse.x = _posX = newX; event->mouse.y = _posY = newY; return true; } } }
/** Get mouse packet . Only care first 3 bytes @param MouseDev Pointer of PS2 Mouse Private Data Structure @retval EFI_NOT_READY Mouse Device not ready to input data packet, or some error happened during getting the packet @retval EFI_SUCCESS The data packet is gotten successfully. **/ EFI_STATUS PS2MouseGetPacket ( PS2_MOUSE_DEV *MouseDev ) { EFI_STATUS Status; BOOLEAN KeyboardEnable; UINT8 Packet[PS2_PACKET_LENGTH]; UINT8 Data; UINTN Count; UINTN State; INT16 RelativeMovementX; INT16 RelativeMovementY; BOOLEAN LButton; BOOLEAN RButton; KeyboardEnable = FALSE; Count = 1; State = PS2_READ_BYTE_ONE; // // State machine to get mouse packet // while (1) { switch (State) { case PS2_READ_BYTE_ONE: // // Read mouse first byte data, if failed, immediately return // KbcDisableAux (); Status = PS2MouseRead (&Data, &Count, State); if (EFI_ERROR (Status)) { KbcEnableAux (); return EFI_NOT_READY; } if (Count != 1) { KbcEnableAux (); return EFI_NOT_READY; } if (IS_PS2_SYNC_BYTE (Data)) { Packet[0] = Data; State = PS2_READ_DATA_BYTE; CheckKbStatus (&KeyboardEnable); KbcDisableKb (); KbcEnableAux (); } break; case PS2_READ_DATA_BYTE: Count = 2; Status = PS2MouseRead ((Packet + 1), &Count, State); if (EFI_ERROR (Status)) { if (KeyboardEnable) { KbcEnableKb (); } return EFI_NOT_READY; } if (Count != 2) { if (KeyboardEnable) { KbcEnableKb (); } return EFI_NOT_READY; } State = PS2_PROCESS_PACKET; break; case PS2_PROCESS_PACKET: if (KeyboardEnable) { KbcEnableKb (); } // // Decode the packet // RelativeMovementX = Packet[1]; RelativeMovementY = Packet[2]; // // Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 // Byte 0 | Y overflow | X overflow | Y sign bit | X sign bit | Always 1 | Middle Btn | Right Btn | Left Btn // Byte 1 | 8 bit X Movement // Byte 2 | 8 bit Y Movement // // X sign bit + 8 bit X Movement : 9-bit signed twos complement integer that presents the relative displacement of the device in the X direction since the last data transmission. // Y sign bit + 8 bit Y Movement : Same as X sign bit + 8 bit X Movement. // // // First, Clear X and Y high 8 bits // RelativeMovementX = (INT16) (RelativeMovementX & 0xFF); RelativeMovementY = (INT16) (RelativeMovementY & 0xFF); // // Second, if the 9-bit signed twos complement integer is negative, set the high 8 bit 0xff // if ((Packet[0] & 0x10) != 0) { RelativeMovementX = (INT16) (RelativeMovementX | 0xFF00); } if ((Packet[0] & 0x20) != 0) { RelativeMovementY = (INT16) (RelativeMovementY | 0xFF00); } RButton = (UINT8) (Packet[0] & 0x2); LButton = (UINT8) (Packet[0] & 0x1); // // Update mouse state // MouseDev->State.RelativeMovementX += RelativeMovementX; MouseDev->State.RelativeMovementY -= RelativeMovementY; MouseDev->State.RightButton = (UINT8) (RButton ? TRUE : FALSE); MouseDev->State.LeftButton = (UINT8) (LButton ? TRUE : FALSE); MouseDev->StateChanged = TRUE; return EFI_SUCCESS; } } }