597{
598 hid_device* handle = hid_open_path(path.c_str());
599 if (!handle) {
600 return false;
601 }
602
603 std::vector<uint8_t> descriptor(4096);
604 const int written = hid_get_report_descriptor(handle,
605 descriptor.data(), descriptor.size());
606
607 if (written <= 0) {
608 hid_close(handle);
609 return false;
610 }
611 descriptor.resize(static_cast<size_t>(written));
612
614 if (layout.fields.empty()) {
615 hid_close(handle);
616 return false;
617 }
618
619 hid_set_nonblocking(handle, 0);
620
621 auto device = std::make_shared<TabletDevice>();
622 device->handle = handle;
623 device->path = path;
624 device->name = std::move(name);
625 device->vendor_id = vid;
626 device->product_id = pid;
627 device->layout = std::move(layout);
629 device->active.store(true);
630
631 std::vector<TabletToolInfo> announced;
632
633 {
635
636 TabletToolInfo pen;
639 pen.is_connected = true;
640 pen.is_input = true;
641 pen.vendor_id = vid;
642 pen.product_id = pid;
643 pen.tablet_name = device->name;
644 pen.name = device->name + " Pen";
646 pen.axes = device->layout.axes;
647
648 device->pen_id = pen.id;
651 announced.push_back(pen);
652
654 TabletToolInfo eraser = pen;
656 eraser.name = device->name + " Eraser";
658
659 device->eraser_id = eraser.id;
662 announced.push_back(eraser);
663 } else {
664 device->eraser_id = device->pen_id;
665 }
666
668 }
669
671 "Tablet adopted: {} (VID:{:04X} PID:{:04X}, {} field(s))",
672 device->name, vid, pid, device->layout.fields.size());
673
674 for (const auto& info : announced) {
676 }
677
678 return true;
679}
#define MF_INFO(comp, ctx,...)
uint32_t m_next_device_id
void notify_device_change(const InputDeviceInfo &info, bool connected)
static TabletLayout parse_descriptor(std::span< const uint8_t > descriptor)
Parse a HID report descriptor into a tablet layout.
std::unordered_map< uint32_t, std::string > m_tool_paths
std::unordered_map< std::string, std::shared_ptr< TabletDevice > > m_devices
std::mutex m_devices_mutex
std::unordered_map< uint32_t, TabletToolInfo > m_tools
@ TABLET
Digitizers and styluses (pressure, tilt, rotation)
@ InputBackend
Input device backend (HID, MIDI, OSC)
@ Core
Core engine, backend, subsystems.
bool split_eraser
Report the eraser end as its own tool.
size_t read_buffer_size
Per-device read buffer.