// gKeyMapper daemon - virtual keyboard for replaying "key" mappings. #ifndef GKEYMAPPER_DAEMON_UINPUT_KEYBOARD_H #define GKEYMAPPER_DAEMON_UINPUT_KEYBOARD_H #include #include "mapping.h" namespace gkeymapper::daemon { // Key code for a single modifier bit (the "left" variants are enough), 0 when // the bit is not a modifier. unsigned short modifier_key_code(unsigned bit); // Expands one shortcut step into the key codes to press: the modifiers first, // then the key itself. Used by play() and by the KeyHold action, which has to // release exactly the codes it pressed. std::vector step_key_codes(const gkeymapper::ShortcutStep& step); // A virtual keyboard created through /dev/uinput. It is only used to replay // shortcuts; the daemon never reads from it. class UinputKeyboard { public: UinputKeyboard() = default; ~UinputKeyboard(); UinputKeyboard(const UinputKeyboard&) = delete; UinputKeyboard& operator=(const UinputKeyboard&) = delete; bool open(); void close(); bool is_open() const { return fd_ >= 0; } // Presses and releases every step of the shortcut in order. void play(const std::vector& steps); // Presses and releases a single Linux key code. The media keys are replayed // with this: the keyboard reports them on its own (see README), so the daemon // passes them on unchanged instead of turning them into a mapping. void tap(unsigned short code); // Presses, respectively releases, all codes in one EV_SYN block (release in // reverse order). Splitting press and release is what "keyhold" needs: the // caller keeps the list and releases it when the G key comes up. void press(const std::vector& codes); void release(const std::vector& codes); private: void emit(unsigned short type, unsigned short code, int value); void sync(); void key_event(unsigned short code, bool down); int fd_ = -1; }; } // namespace gkeymapper::daemon #endif // GKEYMAPPER_DAEMON_UINPUT_KEYBOARD_H