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 * 227dfac9ffSJae Hyun Yoo * @param[in] kbdPath - Path to the USB keyboard device 237dfac9ffSJae Hyun Yoo * @param[in] ptrPath - Path to the USB mouse device 2421b177e0SEddie James */ 257dfac9ffSJae 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 5123135dd9SEddie James /* @brief Re-opens USB device in case the endpoint shutdown */ 5223135dd9SEddie James void restart(); 537dfac9ffSJae Hyun Yoo /* @brief Sends a wakeup data packet to the USB input device */ 547dfac9ffSJae Hyun Yoo void sendWakeupPacket(); 5521b177e0SEddie James /* @brief Sends an HID report to the USB input device */ 5621b177e0SEddie James void sendReport(); 5721b177e0SEddie James 5821b177e0SEddie James private: 597dfac9ffSJae Hyun Yoo static constexpr int NUM_MODIFIER_BITS = 4; 607dfac9ffSJae Hyun Yoo static constexpr int KEY_REPORT_LENGTH = 8; 617dfac9ffSJae Hyun Yoo static constexpr int PTR_REPORT_LENGTH = 5; 6221b177e0SEddie James 6321b177e0SEddie James /* @brief HID modifier bits mapped to shift and control key codes */ 647dfac9ffSJae Hyun Yoo static constexpr uint8_t shiftCtrlMap[NUM_MODIFIER_BITS] = { 657dfac9ffSJae Hyun Yoo 0x02, // left shift 667dfac9ffSJae Hyun Yoo 0x20, // right shift 677dfac9ffSJae Hyun Yoo 0x01, // left control 687dfac9ffSJae Hyun Yoo 0x10 // right control 697dfac9ffSJae Hyun Yoo }; 7021b177e0SEddie James /* @brief HID modifier bits mapped to meta and alt key codes */ 717dfac9ffSJae Hyun Yoo static constexpr uint8_t metaAltMap[NUM_MODIFIER_BITS] = { 727dfac9ffSJae Hyun Yoo 0x08, // left meta 737dfac9ffSJae Hyun Yoo 0x80, // right meta 747dfac9ffSJae Hyun Yoo 0x04, // left alt 757dfac9ffSJae Hyun Yoo 0x40 // right alt 767dfac9ffSJae Hyun Yoo }; 7721b177e0SEddie James /* 7821b177e0SEddie James * @brief Translates a RFB-specific key code to HID modifier bit 7921b177e0SEddie James * 8021b177e0SEddie James * @param[in] key - key code 8121b177e0SEddie James */ 827dfac9ffSJae Hyun Yoo static uint8_t keyToMod(rfbKeySym key); 8321b177e0SEddie James /* 8421b177e0SEddie James * @brief Translates a RFB-specific key code to HID scancode 8521b177e0SEddie James * 8621b177e0SEddie James * @param[in] key - key code 8721b177e0SEddie James */ 887dfac9ffSJae Hyun Yoo static uint8_t keyToScancode(rfbKeySym key); 8921b177e0SEddie James 90*7cf1f1d4SEddie James bool writeKeyboard(const uint8_t *report); 91*7cf1f1d4SEddie James void writePointer(const uint8_t *report); 92*7cf1f1d4SEddie James 934749f934SEddie James /* @brief Indicates whether or not a pointer report error has occurred */ 944749f934SEddie James bool pointerError; 9521b177e0SEddie James /* @brief Indicates whether or not to send a keyboard report */ 9621b177e0SEddie James bool sendKeyboard; 9721b177e0SEddie James /* @brief Indicates whether or not to send a pointer report */ 9821b177e0SEddie James bool sendPointer; 997dfac9ffSJae Hyun Yoo /* @brief File descriptor for the USB keyboard device */ 1007dfac9ffSJae Hyun Yoo int keyboardFd; 1017dfac9ffSJae Hyun Yoo /* @brief File descriptor for the USB mouse device */ 1027dfac9ffSJae Hyun Yoo int pointerFd; 10321b177e0SEddie James /* @brief Data for keyboard report */ 1047dfac9ffSJae Hyun Yoo uint8_t keyboardReport[KEY_REPORT_LENGTH]; 10521b177e0SEddie James /* @brief Data for pointer report */ 1067dfac9ffSJae Hyun Yoo uint8_t pointerReport[PTR_REPORT_LENGTH]; 1077dfac9ffSJae Hyun Yoo /* @brief Path to the USB keyboard device */ 1087dfac9ffSJae Hyun Yoo std::string keyboardPath; 1097dfac9ffSJae Hyun Yoo /* @brief Path to the USB mouse device */ 1107dfac9ffSJae Hyun Yoo std::string pointerPath; 11121b177e0SEddie James /* 11221b177e0SEddie James * @brief Mapping of RFB key code to report data index to keep track 11321b177e0SEddie James * of which keys are down 11421b177e0SEddie James */ 11521b177e0SEddie James std::map<int, int> keysDown; 11621b177e0SEddie James }; 11721b177e0SEddie James 11821b177e0SEddie James } // namespace ikvm 119