diff --git a/libraries/USB/src/USBHIDMouse.cpp b/libraries/USB/src/USBHIDMouse.cpp index 30b802a4607..635004804ce 100644 --- a/libraries/USB/src/USBHIDMouse.cpp +++ b/libraries/USB/src/USBHIDMouse.cpp @@ -24,31 +24,110 @@ #include "USBHIDMouse.h" -static const uint8_t report_descriptor[] = { - TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(HID_REPORT_ID_MOUSE)) -}; -USBHIDMouse::USBHIDMouse(): hid(), _buttons(0){ + + +USBHIDMouseBase::USBHIDMouseBase(HIDMouseType_t *type) : hid(), _buttons(0), _type(type) +{ static bool initialized = false; if(!initialized){ initialized = true; - hid.addDevice(this, sizeof(report_descriptor)); + hid.addDevice(this, _type->descriptor_size); } +}; + +uint16_t USBHIDMouseBase::_onGetDescriptor(uint8_t* dst) +{ + memcpy(dst, _type->report_descriptor, _type->descriptor_size); + return _type->descriptor_size; } -uint16_t USBHIDMouse::_onGetDescriptor(uint8_t* dst){ - memcpy(dst, report_descriptor, sizeof(report_descriptor)); - return sizeof(report_descriptor); + +void USBHIDMouseBase::buttons(uint8_t b) +{ + if (b != _buttons){ + _buttons = b; + } } -void USBHIDMouse::begin(){ + +void USBHIDMouseBase::begin() +{ hid.begin(); } -void USBHIDMouse::end(){ +void USBHIDMouseBase::end() +{ +} + + +void USBHIDMouseBase::press(uint8_t b) +{ + this->buttons(_buttons | b); +} + +void USBHIDMouseBase::release(uint8_t b) +{ + this->buttons(_buttons & ~b); +} + +bool USBHIDMouseBase::isPressed(uint8_t b) +{ + if ((b & _buttons) > 0) { + return true; + } + return false; +} + + + +static const uint8_t abs_mouse_report_descriptor[] = { + TUD_HID_REPORT_DESC_ABSMOUSE(HID_REPORT_ID(HID_REPORT_ID_MOUSE)) +}; + +HIDMouseType_t HIDMouseAbs = { HID_MOUSE_ABSOLUTE, abs_mouse_report_descriptor, sizeof(abs_mouse_report_descriptor), sizeof(hid_abs_mouse_report_t) }; + + +void USBHIDAbsoluteMouse::move(int16_t x, int16_t y, int8_t wheel, int8_t pan) +{ + hid_abs_mouse_report_t report; + report.buttons = _buttons; + report.x = _lastx = x; + report.y = _lasty = y; + report.wheel = wheel; + report.pan = pan; + sendReport(report); +} + + +void USBHIDAbsoluteMouse::click(uint8_t b) +{ + _buttons = b; + move(_lastx,_lasty); + _buttons = 0; + move(_lastx,_lasty); +} + +void USBHIDAbsoluteMouse::buttons(uint8_t b) +{ + if (b != _buttons){ + _buttons = b; + move(_lastx,_lasty); + } } -void USBHIDMouse::move(int8_t x, int8_t y, int8_t wheel, int8_t pan){ + + +static const uint8_t rel_mouse_report_descriptor[] = { + TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(HID_REPORT_ID_MOUSE)) +}; + +HIDMouseType_t HIDMouseRel = { HID_MOUSE_RELATIVE, rel_mouse_report_descriptor, sizeof(rel_mouse_report_descriptor), sizeof(hid_mouse_report_t) }; + + + +void USBHIDRelativeMouse::move(int8_t x, int8_t y, int8_t wheel, int8_t pan) +{ hid_mouse_report_t report = { .buttons = _buttons, .x = x, @@ -56,37 +135,28 @@ void USBHIDMouse::move(int8_t x, int8_t y, int8_t wheel, int8_t pan){ .wheel = wheel, .pan = pan }; - hid.SendReport(HID_REPORT_ID_MOUSE, &report, sizeof(report)); + sendReport(report); } -void USBHIDMouse::click(uint8_t b){ + +void USBHIDRelativeMouse::click(uint8_t b) +{ _buttons = b; move(0,0); _buttons = 0; move(0,0); } -void USBHIDMouse::buttons(uint8_t b){ +void USBHIDRelativeMouse::buttons(uint8_t b) +{ if (b != _buttons){ _buttons = b; move(0,0); } } -void USBHIDMouse::press(uint8_t b){ - buttons(_buttons | b); -} -void USBHIDMouse::release(uint8_t b){ - buttons(_buttons & ~b); -} -bool USBHIDMouse::isPressed(uint8_t b){ - if ((b & _buttons) > 0) { - return true; - } - return false; -} #endif /* CONFIG_TINYUSB_HID_ENABLED */ diff --git a/libraries/USB/src/USBHIDMouse.h b/libraries/USB/src/USBHIDMouse.h index 17adf17b471..b62d4473851 100644 --- a/libraries/USB/src/USBHIDMouse.h +++ b/libraries/USB/src/USBHIDMouse.h @@ -30,25 +30,67 @@ #define MOUSE_FORWARD 0x10 #define MOUSE_ALL 0x1F -class USBHIDMouse: public USBHIDDevice { -private: - USBHID hid; - uint8_t _buttons; - void buttons(uint8_t b); - bool write(int8_t x, int8_t y, int8_t vertical, int8_t horizontal); + +enum MousePositioning_t +{ + HID_MOUSE_RELATIVE, + HID_MOUSE_ABSOLUTE +}; + +struct HIDMouseType_t +{ + MousePositioning_t positioning; + const uint8_t* report_descriptor; + size_t descriptor_size; + size_t report_size; +}; + +extern HIDMouseType_t HIDMouseRel; +extern HIDMouseType_t HIDMouseAbs; + + +class USBHIDMouseBase: public USBHIDDevice { public: - USBHIDMouse(void); + USBHIDMouseBase(HIDMouseType_t *type); void begin(void); void end(void); - - void click(uint8_t b = MOUSE_LEFT); - void move(int8_t x, int8_t y, int8_t wheel = 0, int8_t pan = 0); void press(uint8_t b = MOUSE_LEFT); // press LEFT by default void release(uint8_t b = MOUSE_LEFT); // release LEFT by default bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default - + template bool sendReport(T report) { return hid.SendReport( HID_REPORT_ID_MOUSE, &report, _type->report_size ); }; // internal use uint16_t _onGetDescriptor(uint8_t* buffer); + virtual void buttons(uint8_t b); +protected: + USBHID hid; + uint8_t _buttons; + HIDMouseType_t *_type; }; + +class USBHIDRelativeMouse: public USBHIDMouseBase { +public: + USBHIDRelativeMouse(void): USBHIDMouseBase(&HIDMouseRel) { } + void move(int8_t x, int8_t y, int8_t wheel = 0, int8_t pan = 0); + void click(uint8_t b = MOUSE_LEFT); + void buttons(uint8_t b) override; +}; + + +class USBHIDAbsoluteMouse: public USBHIDMouseBase { +public: + USBHIDAbsoluteMouse(void): USBHIDMouseBase(&HIDMouseAbs) { } + void move(int16_t x, int16_t y, int8_t wheel = 0, int8_t pan = 0); + void click(uint8_t b = MOUSE_LEFT); + void buttons(uint8_t b) override; +private: + int16_t _lastx = 0; + int16_t _lasty = 0; +}; + + +// don't break examples and old sketches +typedef USBHIDRelativeMouse USBHIDMouse; + + #endif diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/hid/hid.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/hid/hid.h index d9b0ead1057..a3f0da09b75 100644 --- a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/hid/hid.h +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/hid/hid.h @@ -300,6 +300,17 @@ typedef struct TU_ATTR_PACKED int8_t pan; // using AC Pan } hid_mouse_report_t; +// Absolute Mouse data struct is a copy of the Standard (relative) Mouse Report +// with int16_t instead of int8_t for X and Y coordinates. +typedef struct TU_ATTR_PACKED +{ + uint8_t buttons; /**< buttons mask for currently pressed buttons in the mouse. */ + int16_t x; /**< Current x position of the mouse. */ + int16_t y; /**< Current y position of the mouse. */ + int8_t wheel; /**< Current delta wheel movement on the mouse. */ + int8_t pan; // using AC Pan +} hid_abs_mouse_report_t; + /// Standard Mouse Buttons Bitmap typedef enum { diff --git a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/hid/hid_device.h b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/hid/hid_device.h index eeef6d3bade..cafe98eb822 100644 --- a/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/hid/hid_device.h +++ b/tools/sdk/esp32s2/include/arduino_tinyusb/tinyusb/src/class/hid/hid_device.h @@ -266,6 +266,55 @@ static inline bool tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y HID_COLLECTION_END , \ HID_COLLECTION_END \ +// Absolute Mouse Report Descriptor Template +#define TUD_HID_REPORT_DESC_ABSMOUSE(...) \ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\ + HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */\ + __VA_ARGS__ \ + HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\ + HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\ + HID_USAGE_MIN ( 1 ) ,\ + HID_USAGE_MAX ( 5 ) ,\ + HID_LOGICAL_MIN ( 0 ) ,\ + HID_LOGICAL_MAX ( 1 ) ,\ + /* Left, Right, Middle, Backward, Forward buttons */ \ + HID_REPORT_COUNT( 5 ) ,\ + HID_REPORT_SIZE ( 1 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + /* 3 bit padding */ \ + HID_REPORT_COUNT( 1 ) ,\ + HID_REPORT_SIZE ( 3 ) ,\ + HID_INPUT ( HID_CONSTANT ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + /* X, Y absolute position [0, 32767] */ \ + HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\ + HID_LOGICAL_MIN ( 0x00 ) ,\ + HID_LOGICAL_MAX_N( 0x7FFF, 2 ) ,\ + HID_REPORT_SIZE ( 16 ) ,\ + HID_REPORT_COUNT ( 2 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + /* Vertical wheel scroll [-127, 127] */ \ + HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\ + HID_LOGICAL_MIN ( 0x81 ) ,\ + HID_LOGICAL_MAX ( 0x7f ) ,\ + HID_REPORT_COUNT( 1 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \ + /* Horizontal wheel scroll [-127, 127] */ \ + HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \ + HID_LOGICAL_MIN ( 0x81 ), \ + HID_LOGICAL_MAX ( 0x7f ), \ + HID_REPORT_COUNT( 1 ), \ + HID_REPORT_SIZE ( 8 ), \ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \ + HID_COLLECTION_END , \ + HID_COLLECTION_END \ + // Consumer Control Report Descriptor Template #define TUD_HID_REPORT_DESC_CONSUMER(...) \ HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ) ,\