summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2025-01-12 12:34:13 +0100
committerRoland Reichwein <mail@reichwein.it>2025-01-12 12:34:13 +0100
commitcdf85d6e04e664e4f56acd05affa287ac63ed125 (patch)
treef412284c81b7e9bd76a6e9ab5d40139850478164
parent4c5f531300efe0faf2aea88dd6c78f05012934c8 (diff)
Detect touchpad
-rw-r--r--PCM.cpp2
-rw-r--r--PIDFile.cpp2
-rw-r--r--Touchpad.cpp82
-rw-r--r--Touchpad.h4
4 files changed, 69 insertions, 21 deletions
diff --git a/PCM.cpp b/PCM.cpp
index b8510b5..205b1cd 100644
--- a/PCM.cpp
+++ b/PCM.cpp
@@ -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;
diff --git a/Touchpad.h b/Touchpad.h
index 0474d04..b5945fe 100644
--- a/Touchpad.h
+++ b/Touchpad.h
@@ -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;
};