diff options
author | Roland Reichwein <mail@reichwein.it> | 2025-01-12 12:34:13 +0100 |
---|---|---|
committer | Roland Reichwein <mail@reichwein.it> | 2025-01-12 12:34:13 +0100 |
commit | cdf85d6e04e664e4f56acd05affa287ac63ed125 (patch) | |
tree | f412284c81b7e9bd76a6e9ab5d40139850478164 | |
parent | 4c5f531300efe0faf2aea88dd6c78f05012934c8 (diff) |
Detect touchpad
-rw-r--r-- | PCM.cpp | 2 | ||||
-rw-r--r-- | PIDFile.cpp | 2 | ||||
-rw-r--r-- | Touchpad.cpp | 82 | ||||
-rw-r--r-- | Touchpad.h | 4 |
4 files changed, 69 insertions, 21 deletions
@@ -41,7 +41,7 @@ PCM::PCM(Config& config): if (0 > snd_pcm_start(handle)) { // On raspberry, this results in error. However, seems to generally work without - log_cout << "PCM could not be started" << std::endl; + log_cout << "PCM could not be started. Ignoring. Will be done implicitly." << std::endl; } if (npfd != 1) { diff --git a/PIDFile.cpp b/PIDFile.cpp index 85f30d3..6bfaa3a 100644 --- a/PIDFile.cpp +++ b/PIDFile.cpp @@ -32,7 +32,7 @@ PIDFile::PIDFile(const std::string& programname): m_programname{programname} try { Reichwein::File::setFile(filename, contents); } catch (const std::exception& ex) { - log_cout << fmt::format("Warning: Not able to write to file{}, ignoring.\n", filename.string()); + log_cout << fmt::format("Warning: Not able to write to file {}, ignoring.\n", filename.string()); } } diff --git a/Touchpad.cpp b/Touchpad.cpp index 3989df7..9d3fe22 100644 --- a/Touchpad.cpp +++ b/Touchpad.cpp @@ -1,34 +1,82 @@ #include "Touchpad.h" +#include <filesystem> #include <fmt/format.h> #include <sys/poll.h> #include <fcntl.h> #include "log.h" -Touchpad::Touchpad(): m_valid{}, m_ev{} -{ - m_fd = open("/dev/input/event0", O_RDONLY | O_NONBLOCK); - int rc = libevdev_new_from_fd(m_fd, &m_dev); - if (rc < 0) { - log_cout << fmt::format("Failed to init libevdev ({})\n", strerror(-rc)); - return; +namespace fs = std::filesystem; + +namespace { + fs::path eventfile_from_index(int i) + { + fs::path result{"/dev/input/event"}; + result += fs::path{std::to_string(i)}; + return result; + } + + libevdev* get_evdev(int& result_fd) + { + for (int i = 0; ; ++i) { + fs::path filename = eventfile_from_index(i); + if (!fs::exists(filename)) { + log_cout << "Warning: No suitable evdev device found.\n"; + return nullptr; + } + + int fd = open(filename.string().c_str(), O_RDONLY | O_NONBLOCK); + if (fd < 0) { + log_cout << fmt::format("Warning: evdev open() failed for {}", filename.string()) << std::endl; + continue; + } + libevdev* result{}; + int rc = libevdev_new_from_fd(fd, &result); + if (rc < 0) { + log_cout << fmt::format("Warning: Failed to init libevdev ({})\n", strerror(-rc)); + continue; + } + + if (!libevdev_has_event_type(result, EV_REL) || + !libevdev_has_event_code(result, EV_KEY, BTN_LEFT) || + !libevdev_has_event_code(result, EV_KEY, BTN_RIGHT)) + { + // Not the correct device + continue; + } + log_cout << fmt::format("evdev using: Input device name: \"{}\"\n", libevdev_get_name(result)); + log_cout << fmt::format("evdev using: Input device ID: bus {:x} vendor {:x} product {:x}\n", + libevdev_get_id_bustype(result), + libevdev_get_id_vendor(result), + libevdev_get_id_product(result)); + result_fd = fd; + return result; + } } - log_cout << fmt::format("Input device name: \"{}\"\n", libevdev_get_name(m_dev)); - log_cout << fmt::format("Input device ID: bus {:x} vendor {:x} product {:x}\n", - libevdev_get_id_bustype(m_dev), - libevdev_get_id_vendor(m_dev), - libevdev_get_id_product(m_dev)); - if (!libevdev_has_event_type(m_dev, EV_REL) || - !libevdev_has_event_code(m_dev, EV_KEY, BTN_LEFT) || - !libevdev_has_event_code(m_dev, EV_KEY, BTN_RIGHT)) { - log_cout << fmt::format("Not the correct device, ignoring.\n"); - } else { + void free_evdev(libevdev* evdev, int fd) + { + if (evdev) { + libevdev_free(evdev); + close(fd); + } + } +} + +Touchpad::Touchpad(): m_fd{}, m_dev{}, m_valid{}, m_ev{} +{ + m_dev = get_evdev(m_fd); + if (m_dev != nullptr) { m_valid = true; } } +Touchpad::~Touchpad() +{ + free_evdev(m_dev, m_fd); +} + bool Touchpad::is_valid() { return m_valid; @@ -8,6 +8,7 @@ class Touchpad { public: Touchpad(); + ~Touchpad(); bool is_valid(); @@ -19,10 +20,9 @@ public: bool event_is_button2(const input_event& ev); private: - libevdev* m_dev = nullptr; int m_fd; + libevdev* m_dev; bool m_valid; - std::optional<input_event> m_ev; }; |