Initial public release
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
#pragma once
|
||||
|
||||
#include "USBHID.h"
|
||||
#include <string.h>
|
||||
|
||||
// Absolute-position mouse HID device.
|
||||
//
|
||||
// The stock USBHIDMouse is RELATIVE (it reports dx/dy deltas), which
|
||||
// accumulates error and drifts the remote cursor out of sync over a lossy
|
||||
// BLE link. This device reports ABSOLUTE coordinates (0..32767 spanning the
|
||||
// target's screen) so every report fully specifies where the cursor is — a
|
||||
// dropped report just means the next one re-pins the position, never drift.
|
||||
// That's exactly what the BT Keyboard virtual trackpad needs to stay synced
|
||||
// across many devices.
|
||||
//
|
||||
// Report payload (the 1-byte report ID is prepended by USBHID::SendReport):
|
||||
// byte 0 : buttons bitmask (bit0 left, bit1 right, bit2 middle)
|
||||
// bytes 1-2 : X (uint16 little-endian, 0..32767)
|
||||
// bytes 3-4 : Y (uint16 little-endian, 0..32767)
|
||||
// byte 5 : wheel (int8, relative scroll tick)
|
||||
|
||||
#define ABS_MOUSE_REPORT_ID 0x0A
|
||||
#define ABS_MOUSE_BTN_LEFT 0x01
|
||||
#define ABS_MOUSE_BTN_RIGHT 0x02
|
||||
#define ABS_MOUSE_BTN_MIDDLE 0x04
|
||||
#define ABS_MOUSE_MAX 32767
|
||||
|
||||
class AbsoluteMouse : public USBHIDDevice {
|
||||
public:
|
||||
AbsoluteMouse() : _hid(), _buttons(0), _x(0), _y(0) {
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
initialized = true;
|
||||
uint16_t len = 0;
|
||||
_descriptor(&len);
|
||||
_hid.addDevice(this, len);
|
||||
}
|
||||
}
|
||||
|
||||
void begin() { _hid.begin(); }
|
||||
|
||||
// Called by the TinyUSB stack to fetch our report descriptor.
|
||||
uint16_t _onGetDescriptor(uint8_t* buffer) override {
|
||||
uint16_t len = 0;
|
||||
const uint8_t* d = _descriptor(&len);
|
||||
memcpy(buffer, d, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
bool ready() { return _hid.ready(); }
|
||||
|
||||
// Emit one absolute report. ``x``/``y`` are 0..ABS_MOUSE_MAX; ``wheel``
|
||||
// is a relative scroll tick. Returns the SendReport result.
|
||||
bool report(uint8_t buttons, uint16_t x, uint16_t y, int8_t wheel) {
|
||||
if (x > ABS_MOUSE_MAX) x = ABS_MOUSE_MAX;
|
||||
if (y > ABS_MOUSE_MAX) y = ABS_MOUSE_MAX;
|
||||
_buttons = buttons;
|
||||
_x = x;
|
||||
_y = y;
|
||||
uint8_t r[6];
|
||||
r[0] = buttons;
|
||||
r[1] = (uint8_t)(x & 0xFF);
|
||||
r[2] = (uint8_t)((x >> 8) & 0xFF);
|
||||
r[3] = (uint8_t)(y & 0xFF);
|
||||
r[4] = (uint8_t)((y >> 8) & 0xFF);
|
||||
r[5] = (uint8_t)wheel;
|
||||
return _hid.SendReport(ABS_MOUSE_REPORT_ID, r, sizeof(r));
|
||||
}
|
||||
|
||||
private:
|
||||
USBHID _hid;
|
||||
uint8_t _buttons;
|
||||
uint16_t _x, _y;
|
||||
|
||||
static const uint8_t* _descriptor(uint16_t* outLen) {
|
||||
static const uint8_t d[] = {
|
||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||
0x09, 0x02, // Usage (Mouse)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x85, ABS_MOUSE_REPORT_ID, // Report ID
|
||||
0x09, 0x01, // Usage (Pointer)
|
||||
0xA1, 0x00, // Collection (Physical)
|
||||
0x05, 0x09, // Usage Page (Button)
|
||||
0x19, 0x01, // Usage Minimum (1)
|
||||
0x29, 0x03, // Usage Maximum (3)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x95, 0x03, // Report Count (3)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x81, 0x02, // Input (Data,Var,Abs)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x75, 0x05, // Report Size (5)
|
||||
0x81, 0x03, // Input (Const) - padding
|
||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||
0x09, 0x30, // Usage (X)
|
||||
0x09, 0x31, // Usage (Y)
|
||||
0x16, 0x00, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x7F, // Logical Maximum (32767)
|
||||
0x75, 0x10, // Report Size (16)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x81, 0x02, // Input (Data,Var,Abs)
|
||||
0x09, 0x38, // Usage (Wheel)
|
||||
0x15, 0x81, // Logical Minimum (-127)
|
||||
0x25, 0x7F, // Logical Maximum (127)
|
||||
0x75, 0x08, // Report Size (8)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x81, 0x06, // Input (Data,Var,Rel)
|
||||
0xC0, // End Collection
|
||||
0xC0 // End Collection
|
||||
};
|
||||
*outLen = sizeof(d);
|
||||
return d;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user