Skip to content

Commit

Permalink
all: Modularize HID code even further
Browse files Browse the repository at this point in the history
* Move IPTS interface logic to ipts namespace
* core::linux only contains the linux specific hidraw code
* Report entries in the HID descriptor get deduplicated
  • Loading branch information
StollD committed Jun 20, 2023
1 parent 9202430 commit eb93c26
Show file tree
Hide file tree
Showing 11 changed files with 510 additions and 338 deletions.
24 changes: 18 additions & 6 deletions src/apps/check-device/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
#include <core/generic/device.hpp>
#include <core/linux/config-loader.hpp>
#include <core/linux/hidraw-device.hpp>
#include <hid/report.hpp>
#include <ipts/data.hpp>
#include <ipts/descriptor.hpp>
#include <ipts/device.hpp>

#include <CLI/CLI.hpp>
#include <gsl/gsl>
Expand All @@ -14,6 +17,7 @@
#include <cstdlib>
#include <exception>
#include <filesystem>
#include <memory>
#include <optional>
#include <string>

Expand All @@ -39,21 +43,29 @@ int run(const int argc, const char **argv)
spdlog::set_level(spdlog::level::off);

// Open the device
const core::linux::HidrawDevice device {path};
const auto device = std::make_shared<core::linux::HidrawDevice>(path);

const core::DeviceInfo info = device.info();
const std::optional<const ipts::Metadata> metadata = device.get_metadata();
core::DeviceInfo info {};
info.vendor = device->vendor();
info.product = device->product();

spdlog::info("Opened device {:04X}:{:04X}", info.vendor, info.product);
// Create IPTS interface
const ipts::Device ipts {device};
const ipts::Descriptor &descriptor = ipts.descriptor();
const std::optional<const ipts::Metadata> metadata = ipts.metadata();

info.buffer_size = ipts.buffer_size();

spdlog::info("Opened device {:04X}:{:04X}", device->vendor(), device->product());

// Check if the device can switch modes
if (!device.has_set_mode()) {
if (!descriptor.find_modesetting_report().has_value()) {
spdlog::error("{} is not an IPTS device!", path.string());
return EXIT_FAILURE;
}

// Check if the device can send touch data.
if (!device.has_touch_data()) {
if (descriptor.find_touch_data_reports().empty()) {
spdlog::error("{} is not an IPTS device!", path.string());
return EXIT_FAILURE;
}
Expand Down
27 changes: 19 additions & 8 deletions src/core/linux/device-runner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
#include <common/chrono.hpp>
#include <core/generic/application.hpp>
#include <ipts/data.hpp>
#include <ipts/device.hpp>

#include <spdlog/spdlog.h>

#include <atomic>
#include <filesystem>
#include <memory>
#include <thread>
#include <type_traits>
#include <vector>
Expand All @@ -28,7 +30,10 @@ class DeviceRunner {

private:
// The hidraw device serving as the source of data.
HidrawDevice m_device;
std::shared_ptr<HidrawDevice> m_device;

// The IPTS touchscreen interface
ipts::Device m_ipts;

// Whether the loop for reading from the device should stop.
std::atomic_bool m_should_stop = false;
Expand All @@ -45,10 +50,16 @@ class DeviceRunner {

public:
template <class... Args>
DeviceRunner(const std::filesystem::path &path, Args... args) : m_device {path}
DeviceRunner(const std::filesystem::path &path, Args... args)
: m_device {std::make_shared<HidrawDevice>(path)}
, m_ipts {m_device}
{
const DeviceInfo info = m_device.info();
const std::optional<const ipts::Metadata> meta = m_device.get_metadata();
DeviceInfo info {};
info.vendor = m_device->vendor();
info.product = m_device->product();
info.buffer_size = m_ipts.buffer_size();

const std::optional<const ipts::Metadata> meta = m_ipts.metadata();

const ConfigLoader loader {info, meta};
m_application.emplace(loader.config(), info, meta, args...);
Expand Down Expand Up @@ -94,7 +105,7 @@ class DeviceRunner {
throw std::runtime_error("Init error: Application is null");

// Enable multitouch mode
m_device.set_mode(true);
m_ipts.set_mode(ipts::Mode::Multitouch);

// Signal the application that the data flow has started.
m_application->on_start();
Expand All @@ -108,10 +119,10 @@ class DeviceRunner {
}

try {
const isize size = m_device.read(m_buffer);
const isize size = m_device->read(m_buffer);

// Does this report contain touch data?
if (!m_device.is_touch_data(m_buffer[0]))
if (!m_ipts.is_touch_data(m_buffer))
continue;

m_application->process(
Expand All @@ -137,7 +148,7 @@ class DeviceRunner {

try {
// Disable multitouch mode
m_device.set_mode(false);
m_ipts.set_mode(ipts::Mode::Singletouch);
} catch (std::exception &e) {
spdlog::error(e.what());
}
Expand Down
Loading

0 comments on commit eb93c26

Please sign in to comment.