121b177e0SEddie James #pragma once 221b177e0SEddie James 321b177e0SEddie James #include <rfb/rfb.h> 421b177e0SEddie James 521b177e0SEddie James #include <map> 621b177e0SEddie James #include <string> 721b177e0SEddie James 821b177e0SEddie James namespace ikvm 921b177e0SEddie James { 1021b177e0SEddie James 1121b177e0SEddie James /* 1221b177e0SEddie James * @class Input 1321b177e0SEddie James * @brief Receives events from RFB clients and sends reports to the USB input 1421b177e0SEddie James * device 1521b177e0SEddie James */ 1621b177e0SEddie James class Input 1721b177e0SEddie James { 1821b177e0SEddie James public: 1921b177e0SEddie James /* 2021b177e0SEddie James * @brief Constructs Input object 2121b177e0SEddie James * 22*7dfac9ffSJae Hyun Yoo * @param[in] kbdPath - Path to the USB keyboard device 23*7dfac9ffSJae Hyun Yoo * @param[in] ptrPath - Path to the USB mouse device 2421b177e0SEddie James */ 25*7dfac9ffSJae Hyun Yoo Input(const std::string& kbdPath, const std::string& ptrPath); 2621b177e0SEddie James ~Input(); 2721b177e0SEddie James Input(const Input&) = default; 2821b177e0SEddie James Input& operator=(const Input&) = default; 2921b177e0SEddie James Input(Input&&) = default; 3021b177e0SEddie James Input& operator=(Input&&) = default; 3121b177e0SEddie James 3221b177e0SEddie James /* 3321b177e0SEddie James * @brief RFB client key event handler 3421b177e0SEddie James * 3521b177e0SEddie James * @param[in] down - Boolean indicating whether key is pressed or not 3621b177e0SEddie James * @param[in] key - Key code 3721b177e0SEddie James * @param[in] cl - Handle to the RFB client 3821b177e0SEddie James */ 3921b177e0SEddie James static void keyEvent(rfbBool down, rfbKeySym key, rfbClientPtr cl); 4021b177e0SEddie James /* 4121b177e0SEddie James * @brief RFB client pointer event handler 4221b177e0SEddie James * 4321b177e0SEddie James * @param[in] buttonMask - Bitmask indicating which buttons have been 4421b177e0SEddie James * pressed 4521b177e0SEddie James * @param[in] x - Pointer x-coordinate 4621b177e0SEddie James * @param[in] y - Pointer y-coordinate 4721b177e0SEddie James * @param[in] cl - Handle to the RFB client 4821b177e0SEddie James */ 4921b177e0SEddie James static void pointerEvent(int buttonMask, int x, int y, rfbClientPtr cl); 5021b177e0SEddie James 51*7dfac9ffSJae Hyun Yoo /* @brief Sends a wakeup data packet to the USB input device */ 52*7dfac9ffSJae Hyun Yoo void sendWakeupPacket(); 5321b177e0SEddie James /* @brief Sends an HID report to the USB input device */ 5421b177e0SEddie James void sendReport(); 5521b177e0SEddie James 5621b177e0SEddie James private: 57*7dfac9ffSJae Hyun Yoo static constexpr int NUM_MODIFIER_BITS = 4; 58*7dfac9ffSJae Hyun Yoo static constexpr int KEY_REPORT_LENGTH = 8; 59*7dfac9ffSJae Hyun Yoo static constexpr int PTR_REPORT_LENGTH = 5; 6021b177e0SEddie James 6121b177e0SEddie James /* @brief HID modifier bits mapped to shift and control key codes */ 62*7dfac9ffSJae Hyun Yoo static constexpr uint8_t shiftCtrlMap[NUM_MODIFIER_BITS] = { 63*7dfac9ffSJae Hyun Yoo 0x02, // left shift 64*7dfac9ffSJae Hyun Yoo 0x20, // right shift 65*7dfac9ffSJae Hyun Yoo 0x01, // left control 66*7dfac9ffSJae Hyun Yoo 0x10 // right control 67*7dfac9ffSJae Hyun Yoo }; 6821b177e0SEddie James /* @brief HID modifier bits mapped to meta and alt key codes */ 69*7dfac9ffSJae Hyun Yoo static constexpr uint8_t metaAltMap[NUM_MODIFIER_BITS] = { 70*7dfac9ffSJae Hyun Yoo 0x08, // left meta 71*7dfac9ffSJae Hyun Yoo 0x80, // right meta 72*7dfac9ffSJae Hyun Yoo 0x04, // left alt 73*7dfac9ffSJae Hyun Yoo 0x40 // right alt 74*7dfac9ffSJae Hyun Yoo }; 7521b177e0SEddie James /* 7621b177e0SEddie James * @brief Translates a RFB-specific key code to HID modifier bit 7721b177e0SEddie James * 7821b177e0SEddie James * @param[in] key - key code 7921b177e0SEddie James */ 80*7dfac9ffSJae Hyun Yoo static uint8_t keyToMod(rfbKeySym key); 8121b177e0SEddie James /* 8221b177e0SEddie James * @brief Translates a RFB-specific key code to HID scancode 8321b177e0SEddie James * 8421b177e0SEddie James * @param[in] key - key code 8521b177e0SEddie James */ 86*7dfac9ffSJae Hyun Yoo static uint8_t keyToScancode(rfbKeySym key); 8721b177e0SEddie James 8821b177e0SEddie James /* @brief Indicates whether or not to send a keyboard report */ 8921b177e0SEddie James bool sendKeyboard; 9021b177e0SEddie James /* @brief Indicates whether or not to send a pointer report */ 9121b177e0SEddie James bool sendPointer; 92*7dfac9ffSJae Hyun Yoo /* @brief File descriptor for the USB keyboard device */ 93*7dfac9ffSJae Hyun Yoo int keyboardFd; 94*7dfac9ffSJae Hyun Yoo /* @brief File descriptor for the USB mouse device */ 95*7dfac9ffSJae Hyun Yoo int pointerFd; 9621b177e0SEddie James /* @brief Data for keyboard report */ 97*7dfac9ffSJae Hyun Yoo uint8_t keyboardReport[KEY_REPORT_LENGTH]; 9821b177e0SEddie James /* @brief Data for pointer report */ 99*7dfac9ffSJae Hyun Yoo uint8_t pointerReport[PTR_REPORT_LENGTH]; 100*7dfac9ffSJae Hyun Yoo /* @brief Path to the USB keyboard device */ 101*7dfac9ffSJae Hyun Yoo std::string keyboardPath; 102*7dfac9ffSJae Hyun Yoo /* @brief Path to the USB mouse device */ 103*7dfac9ffSJae Hyun Yoo std::string pointerPath; 10421b177e0SEddie James /* 10521b177e0SEddie James * @brief Mapping of RFB key code to report data index to keep track 10621b177e0SEddie James * of which keys are down 10721b177e0SEddie James */ 10821b177e0SEddie James std::map<int, int> keysDown; 10921b177e0SEddie James }; 11021b177e0SEddie James 11121b177e0SEddie James } // namespace ikvm 112