-
Notifications
You must be signed in to change notification settings - Fork 7.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Absolute mouse support #6331
Absolute mouse support #6331
Conversation
testing this one with all imported features from relative mouse, still not sure how to melt that properly with the existing USBHIDMouse, both absolute and relative mouse positioning can coexist so I'm not sure it should be exclusive. typedef struct TU_ATTR_PACKED
{
uint8_t buttons = 0;
int16_t x = 0;
int16_t y = 0;
int8_t wheel = 0;
int8_t pan = 0;
} abs_mouse_report_t;
// 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 \ |
this is a better looking descriptor. Give me a few days to wrap up other issues and will think of how to best put that in the USB. |
been testing this and it seems to work Also moved the new descriptor macro to hid_device.h and the [edit] looks like there are multiple copies of hid_device.h and hid.h 🙄 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:
USBHIDMouseBase(HIDMouseType_t *type);
void begin(void);
void end(void);
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 <typename T> bool sendReport(T report) { return hid.SendReport( HID_REPORT_ID_MOUSE, &report, _type->report_size ); };
// internal use
uint16_t _onGetDescriptor(uint8_t* buffer);
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);
};
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);
private:
int16_t _lastx = 0;
int16_t _lasty = 0;
};
// don't break examples and old sketches
#define USBHIDMouse USBHIDRelativeMouse;
USBHIDMouseBase::USBHIDMouseBase(HIDMouseType_t *type) : hid(), _buttons(0), _type(type)
{
static bool initialized = false;
if(!initialized){
initialized = true;
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;
}
void USBHIDMouseBase::begin()
{
hid.begin();
}
void USBHIDMouseBase::end()
{
}
void USBHIDMouseBase::press(uint8_t b)
{
buttons(_buttons | b);
}
void USBHIDMouseBase::release(uint8_t b)
{
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(abs_mouse_report_t) };
void USBHIDAbsoluteMouse::move(int16_t x, int16_t y, int8_t wheel, int8_t pan)
{
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);
}
}
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,
.y = y,
.wheel = wheel,
.pan = pan
};
sendReport(report);
}
void USBHIDRelativeMouse::click(uint8_t b)
{
_buttons = b;
move(0,0);
_buttons = 0;
move(0,0);
}
void USBHIDRelativeMouse::buttons(uint8_t b)
{
if (b != _buttons){
_buttons = b;
move(0,0);
}
}
|
@@ -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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any change to headers in the sdk folder should be done in the appropriate remote place. in his case, it is https://github.com/hathach/tinyusb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks! PR submitted hathach/tinyusb#1363
I need to solve other C++ issues with the build breaking, I don't know how (and if) to template move()
, click()
and buttons()
in the base class and have them superseded in the absolute/relative inherited classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's get the descriptor merged into tinyusb and then we will discuss how to best plug it in. Probably separate class with own report ID
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are separate classes: USBHIDRelativeMouse
(aliased as USBHIDMouse
for legacy), and USBHIDAbsoluteMouse
.
There's also a base class USBHIDMouseBase
but only to provide inheritance, so it's not an issue to have separate instances and should also work with a different report ID.
I tried to solve the build errors by using virtual / override, will do more testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The build failed for ESP32 only, but looking at the error it's not coming from my pull request.
Will I have to do something to trigger the check_suite once this is fixed on arduino-esp32 repo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
last build error points to a missing implementation for esp32s3, I can't remember why this PR was only targeting esp32s2, but I wonder how this should be dealt with: should I also apply the hid patch to sdk/tools/esp32s3/includes/arduino_tinyusb folder?
also the mouse class needs rewriting
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
header patches should not be in the sdk folder at all. They should be in USBHIDMouse.h
. In 3.0.0 SDK is no longer part of the repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh nice, that makes more sense, also it simplifies the path
I guess this PR is no longer relevant since it's based on the 2.x.x core, should I keep it open until I can properly test it with core 3.0.0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes. It should work with 3.0.0 as well
This PR adds
USBHIDAbsMouse
class with absolute mouse positioning support.TinyUSB does not appear to provide (yet) the report struct for absolute positioning, only relative positioning.
Limitations: only one of
USBHIDMouse
/USBHIDAbsMouse
should be used.I'm still open to discussion as how to properly contribute the
abs_mouse_report_descriptor
andstruct abs_mouse_report_t
to the TinyUSB project so it eventually lands back in the espressif codebase.