16 uint64_t hardware_serial {};
86 size_t read_buffer_size { 256 };
87 int poll_timeout_ms { 2 };
88 bool split_eraser {
true };
89 bool probe_all_devices {
true };
106 void start()
override;
107 void stop()
override;
108 void shutdown()
override;
110 [[nodiscard]]
bool is_initialized()
const override {
return m_initialized.load(); }
111 [[nodiscard]]
bool is_running()
const override {
return m_running.load(); }
113 [[nodiscard]] std::vector<InputDeviceInfo> get_devices()
const override;
114 size_t refresh_devices()
override;
116 bool open_device(uint32_t device_id)
override;
117 void close_device(uint32_t device_id)
override;
118 [[nodiscard]]
bool is_device_open(uint32_t device_id)
const override;
119 [[nodiscard]] std::vector<uint32_t> get_open_devices()
const override;
125 [[nodiscard]] std::string
get_name()
const override {
return "Tablet (HID descriptor)"; }
126 [[nodiscard]] std::string get_version()
const override;
136 [[nodiscard]] std::optional<TabletToolInfo>
137 get_tool_info(uint32_t device_id)
const;
145 [[nodiscard]] std::optional<TabletLayout>
146 get_layout(uint32_t device_id)
const;
157 [[nodiscard]]
static TabletLayout parse_descriptor(std::span<const uint8_t> descriptor);
167 uint16_t vendor_id {};
168 uint16_t product_id {};
171 std::atomic<bool> active {
false };
174 uint32_t eraser_id {};
175 std::array<double, TabletFrame::SLOT_COUNT> slots {};
176 bool inverted {
false };
181 std::atomic<bool> m_initialized {
false };
182 std::atomic<bool> m_running {
false };
183 std::atomic<bool> m_stop_requested {
false };
186 std::unordered_map<std::string, std::shared_ptr<TabletDevice>>
m_devices;
187 std::unordered_map<uint32_t, TabletToolInfo>
m_tools;
189 uint32_t m_next_device_id { 1 };
196 void poll_thread_func();
199 void unpack_report(
TabletDevice& device, std::span<const uint8_t> report);
202 bool adopt_device(
const std::string& path, uint16_t vid, uint16_t pid,
206 void notify_device_change(
const InputDeviceInfo& info,
bool connected);
std::thread m_poll_thread
DeviceCallback m_device_callback
std::mutex m_callback_mutex
TabletBackend(TabletBackend &&)=delete
InputCallback m_input_callback
TabletBackend & operator=(const TabletBackend &)=delete
TabletBackend & operator=(TabletBackend &&)=delete
TabletBackend(const TabletBackend &)=delete
std::unordered_map< uint32_t, std::string > m_tool_paths
std::string get_name() const override
Get backend name/identifier string.
bool is_initialized() const override
Check if backend is initialized.
InputType get_type() const override
Get backend type.
std::unordered_map< std::string, std::shared_ptr< TabletDevice > > m_devices
bool is_running() const override
Check if backend is actively listening.
std::mutex m_devices_mutex
std::unordered_map< uint32_t, TabletToolInfo > m_tools
Cross-platform tablet and stylus backend over raw HID.
InputType
Input backend type enumeration.
std::function< void(const InputValue &)> InputCallback
Callback signature for input events.
TabletToolType
Physical tool type.
std::function< void(const InputDeviceInfo &, bool connected)> DeviceCallback
Callback signature for device connection/disconnection events.
TabletAxes
Axes a tool actually reports.
Configuration for the tablet backend.
std::vector< uint8_t > read_buffer
One physical HID device and the tools it presents.
size_t slot
SLOT_COUNT means not a slot field.
One field located in a report by descriptor parsing.
static constexpr size_t SLOT_COUNT
std::vector< TabletField > fields
Parsed layout of one device's input reports.