diff --git a/src/logid/InputDevice.cpp b/src/logid/InputDevice.cpp index 30b448b..a97daf8 100644 --- a/src/logid/InputDevice.cpp +++ b/src/logid/InputDevice.cpp @@ -43,10 +43,19 @@ InputDevice::InputDevice(const char* name) device = libevdev_new(); libevdev_set_name(device, name); - ///TODO: Is it really a good idea to enable all events? libevdev_enable_event_type(device, EV_KEY); - for(unsigned int i = 0; i < KEY_CNT; i++) - libevdev_enable_event_code(device, EV_KEY, i, nullptr); + for (unsigned int i = 0; i < KEY_CNT; i++) { + // Enable some keys which a normal keyboard should have + // by default, i.e. a-z, modifier keys and so on, see: + // /usr/include/linux/input-event-codes.h + if (i < 128) { + registered_keys[i] = true; + libevdev_enable_event_code(device, EV_KEY, i, nullptr); + } else { + registered_keys[i] = false; + } + } + libevdev_enable_event_type(device, EV_REL); for(unsigned int i = 0; i < REL_CNT; i++) libevdev_enable_event_code(device, EV_REL, i, nullptr); @@ -54,8 +63,10 @@ InputDevice::InputDevice(const char* name) int err = libevdev_uinput_create_from_device(device, LIBEVDEV_UINPUT_OPEN_MANAGED, &ui_device); - if(err != 0) + if(err != 0) { + libevdev_free(device); throw std::system_error(-err, std::generic_category()); + } } InputDevice::~InputDevice() @@ -64,6 +75,28 @@ InputDevice::~InputDevice() libevdev_free(device); } +void InputDevice::registerKey(uint code) +{ + if (registered_keys[code]) { + return; + } + + libevdev_uinput_destroy(ui_device); + + libevdev_enable_event_code(device, EV_KEY, code, nullptr); + int err = libevdev_uinput_create_from_device(device, + LIBEVDEV_UINPUT_OPEN_MANAGED, &ui_device); + + if(err != 0) { + libevdev_free(device); + device = nullptr; + ui_device = nullptr; + throw std::system_error(-err, std::generic_category()); + } + + registered_keys[code] = true; +} + void InputDevice::moveAxis(uint axis, int movement) { _sendEvent(EV_REL, axis, movement); @@ -119,4 +152,4 @@ void InputDevice::_sendEvent(uint type, uint code, int value) { libevdev_uinput_write_event(ui_device, type, code, value); libevdev_uinput_write_event(ui_device, EV_SYN, SYN_REPORT, 0); -} \ No newline at end of file +} diff --git a/src/logid/InputDevice.h b/src/logid/InputDevice.h index 8815d05..4846a15 100644 --- a/src/logid/InputDevice.h +++ b/src/logid/InputDevice.h @@ -20,6 +20,7 @@ #define LOGID_INPUTDEVICE_H #include +#include extern "C" { @@ -43,6 +44,7 @@ namespace logid explicit InputDevice(const char *name); ~InputDevice(); + void registerKey(uint code); void moveAxis(uint axis, int movement); void pressKey(uint code); void releaseKey(uint code); @@ -56,6 +58,7 @@ namespace logid static uint _toEventCode(uint type, const std::string& name); + bool registered_keys[KEY_CNT]; libevdev* device; libevdev_uinput* ui_device{}; }; @@ -63,4 +66,4 @@ namespace logid extern std::unique_ptr virtual_input; } -#endif //LOGID_INPUTDEVICE_H \ No newline at end of file +#endif //LOGID_INPUTDEVICE_H diff --git a/src/logid/actions/KeypressAction.cpp b/src/logid/actions/KeypressAction.cpp index da097cc..a71546b 100644 --- a/src/logid/actions/KeypressAction.cpp +++ b/src/logid/actions/KeypressAction.cpp @@ -64,9 +64,11 @@ KeypressAction::Config::Config(Device* device, libconfig::Setting& config) : auto& key = keys[i]; if(key.isNumber()) { _keys.push_back(key); + virtual_input->registerKey(key); } else if(key.getType() == libconfig::Setting::TypeString) { try { _keys.push_back(virtual_input->toKeyCode(key)); + virtual_input->registerKey(virtual_input->toKeyCode(key)); } catch(InputDevice::InvalidEventCode& e) { logPrintf(WARN, "Line %d: Invalid keycode %s, skipping." , key.getSourceLine(), key.c_str());