Skip to content

Commit bd39fcf

Browse files
tobozoSuGliderP-R-O-C-H-Y
authored
Absolute mouse support (was #6331) (#8831)
* Added absolute mouse support * make click() virtual --------- Co-authored-by: Rodrigo Garcia <[email protected]> Co-authored-by: Jan Procházka <[email protected]>
1 parent dbf0b18 commit bd39fcf

File tree

3 files changed

+246
-40
lines changed

3 files changed

+246
-40
lines changed

Diff for: libraries/USB/src/USBHIDMouse.cpp

+94-29
Original file line numberDiff line numberDiff line change
@@ -25,69 +25,134 @@
2525

2626
#include "USBHIDMouse.h"
2727

28-
static const uint8_t report_descriptor[] = {
29-
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(HID_REPORT_ID_MOUSE))
30-
};
31-
32-
USBHIDMouse::USBHIDMouse(): hid(), _buttons(0){
28+
USBHIDMouseBase::USBHIDMouseBase(HIDMouseType_t *type) : hid(), _buttons(0), _type(type)
29+
{
3330
static bool initialized = false;
3431
if(!initialized){
3532
initialized = true;
36-
hid.addDevice(this, sizeof(report_descriptor));
33+
hid.addDevice(this, _type->descriptor_size);
3734
}
35+
};
36+
37+
uint16_t USBHIDMouseBase::_onGetDescriptor(uint8_t* dst)
38+
{
39+
memcpy(dst, _type->report_descriptor, _type->descriptor_size);
40+
return _type->descriptor_size;
3841
}
3942

40-
uint16_t USBHIDMouse::_onGetDescriptor(uint8_t* dst){
41-
memcpy(dst, report_descriptor, sizeof(report_descriptor));
42-
return sizeof(report_descriptor);
43+
44+
void USBHIDMouseBase::buttons(uint8_t b)
45+
{
46+
if (b != _buttons){
47+
_buttons = b;
48+
}
4349
}
4450

45-
void USBHIDMouse::begin(){
51+
52+
void USBHIDMouseBase::begin()
53+
{
4654
hid.begin();
4755
}
4856

49-
void USBHIDMouse::end(){
57+
void USBHIDMouseBase::end()
58+
{
59+
}
60+
61+
62+
void USBHIDMouseBase::press(uint8_t b)
63+
{
64+
this->buttons(_buttons | b);
65+
}
66+
67+
void USBHIDMouseBase::release(uint8_t b)
68+
{
69+
this->buttons(_buttons & ~b);
70+
}
71+
72+
bool USBHIDMouseBase::isPressed(uint8_t b)
73+
{
74+
if ((b & _buttons) > 0) {
75+
return true;
76+
}
77+
return false;
78+
}
79+
80+
81+
82+
static const uint8_t abs_mouse_report_descriptor[] = {
83+
TUD_HID_REPORT_DESC_ABSMOUSE(HID_REPORT_ID(HID_REPORT_ID_MOUSE))
84+
};
85+
86+
HIDMouseType_t HIDMouseAbs = { HID_MOUSE_ABSOLUTE, abs_mouse_report_descriptor, sizeof(abs_mouse_report_descriptor), sizeof(hid_abs_mouse_report_t) };
87+
88+
89+
void USBHIDAbsoluteMouse::move(int16_t x, int16_t y, int8_t wheel, int8_t pan)
90+
{
91+
hid_abs_mouse_report_t report;
92+
report.buttons = _buttons;
93+
report.x = _lastx = x;
94+
report.y = _lasty = y;
95+
report.wheel = wheel;
96+
report.pan = pan;
97+
sendReport(report);
5098
}
5199

52-
void USBHIDMouse::move(int8_t x, int8_t y, int8_t wheel, int8_t pan){
100+
101+
void USBHIDAbsoluteMouse::click(uint8_t b)
102+
{
103+
_buttons = b;
104+
move(_lastx,_lasty);
105+
_buttons = 0;
106+
move(_lastx,_lasty);
107+
}
108+
109+
void USBHIDAbsoluteMouse::buttons(uint8_t b)
110+
{
111+
if (b != _buttons){
112+
_buttons = b;
113+
move(_lastx,_lasty);
114+
}
115+
}
116+
117+
118+
119+
static const uint8_t rel_mouse_report_descriptor[] = {
120+
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(HID_REPORT_ID_MOUSE))
121+
};
122+
123+
HIDMouseType_t HIDMouseRel = { HID_MOUSE_RELATIVE, rel_mouse_report_descriptor, sizeof(rel_mouse_report_descriptor), sizeof(hid_mouse_report_t) };
124+
125+
126+
127+
void USBHIDRelativeMouse::move(int8_t x, int8_t y, int8_t wheel, int8_t pan)
128+
{
53129
hid_mouse_report_t report = {
54130
.buttons = _buttons,
55131
.x = x,
56132
.y = y,
57133
.wheel = wheel,
58134
.pan = pan
59135
};
60-
hid.SendReport(HID_REPORT_ID_MOUSE, &report, sizeof(report));
136+
sendReport(report);
61137
}
62138

63-
void USBHIDMouse::click(uint8_t b){
139+
140+
void USBHIDRelativeMouse::click(uint8_t b)
141+
{
64142
_buttons = b;
65143
move(0,0);
66144
_buttons = 0;
67145
move(0,0);
68146
}
69147

70-
void USBHIDMouse::buttons(uint8_t b){
148+
void USBHIDRelativeMouse::buttons(uint8_t b)
149+
{
71150
if (b != _buttons){
72151
_buttons = b;
73152
move(0,0);
74153
}
75154
}
76155

77-
void USBHIDMouse::press(uint8_t b){
78-
buttons(_buttons | b);
79-
}
80-
81-
void USBHIDMouse::release(uint8_t b){
82-
buttons(_buttons & ~b);
83-
}
84-
85-
bool USBHIDMouse::isPressed(uint8_t b){
86-
if ((b & _buttons) > 0) {
87-
return true;
88-
}
89-
return false;
90-
}
91156

92157
#endif /* CONFIG_TINYUSB_HID_ENABLED */
93158
#endif /* SOC_USB_OTG_SUPPORTED */

Diff for: libraries/USB/src/USBHIDMouse.h

+54-11
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,69 @@
3434
#define MOUSE_FORWARD 0x10
3535
#define MOUSE_ALL 0x1F
3636

37-
class USBHIDMouse: public USBHIDDevice {
38-
private:
39-
USBHID hid;
40-
uint8_t _buttons;
41-
void buttons(uint8_t b);
42-
bool write(int8_t x, int8_t y, int8_t vertical, int8_t horizontal);
37+
#include "./tusb_hid_mouse.h"
38+
39+
enum MousePositioning_t
40+
{
41+
HID_MOUSE_RELATIVE,
42+
HID_MOUSE_ABSOLUTE
43+
};
44+
45+
struct HIDMouseType_t
46+
{
47+
MousePositioning_t positioning;
48+
const uint8_t* report_descriptor;
49+
size_t descriptor_size;
50+
size_t report_size;
51+
};
52+
53+
extern HIDMouseType_t HIDMouseRel;
54+
extern HIDMouseType_t HIDMouseAbs;
55+
56+
57+
class USBHIDMouseBase: public USBHIDDevice {
4358
public:
44-
USBHIDMouse(void);
59+
USBHIDMouseBase(HIDMouseType_t *type);
4560
void begin(void);
4661
void end(void);
47-
48-
void click(uint8_t b = MOUSE_LEFT);
49-
void move(int8_t x, int8_t y, int8_t wheel = 0, int8_t pan = 0);
5062
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
5163
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
5264
bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
53-
65+
template <typename T> bool sendReport(T report) { return hid.SendReport( HID_REPORT_ID_MOUSE, &report, _type->report_size ); };
5466
// internal use
5567
uint16_t _onGetDescriptor(uint8_t* buffer);
68+
virtual void click(uint8_t b) = 0;
69+
virtual void buttons(uint8_t b) = 0;
70+
protected:
71+
USBHID hid;
72+
uint8_t _buttons;
73+
HIDMouseType_t *_type;
74+
};
75+
76+
77+
class USBHIDRelativeMouse: public USBHIDMouseBase {
78+
public:
79+
USBHIDRelativeMouse(void): USBHIDMouseBase(&HIDMouseRel) { }
80+
void move(int8_t x, int8_t y, int8_t wheel = 0, int8_t pan = 0);
81+
void click(uint8_t b = MOUSE_LEFT) override;
82+
void buttons(uint8_t b) override;
83+
};
84+
85+
86+
class USBHIDAbsoluteMouse: public USBHIDMouseBase {
87+
public:
88+
USBHIDAbsoluteMouse(void): USBHIDMouseBase(&HIDMouseAbs) { }
89+
void move(int16_t x, int16_t y, int8_t wheel = 0, int8_t pan = 0);
90+
void click(uint8_t b = MOUSE_LEFT) override;
91+
void buttons(uint8_t b) override;
92+
private:
93+
int16_t _lastx = 0;
94+
int16_t _lasty = 0;
5695
};
5796

97+
98+
// don't break examples and old sketches
99+
typedef USBHIDRelativeMouse USBHIDMouse;
100+
58101
#endif /* CONFIG_TINYUSB_HID_ENABLED */
59102
#endif /* SOC_USB_OTG_SUPPORTED */

Diff for: libraries/USB/src/tusb_hid_mouse.h

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#pragma once
2+
3+
#include "class/hid/hid_device.h"
4+
5+
#if !defined TUD_HID_REPORT_DESC_ABSMOUSE
6+
// This version of arduino-esp32 does not handle absolute mouse natively.
7+
// Let's throw a minimalistic implementation of absmouse driver.
8+
// See: https://github.com/hathach/tinyusb/pull/1363
9+
// Also see: https://github.com/espressif/arduino-esp32/pull/6331
10+
11+
extern "C" {
12+
13+
// Absolute Mouse data struct is a copy of the relative mouse struct
14+
// with int16_t instead of int8_t for X and Y coordinates.
15+
typedef struct TU_ATTR_PACKED
16+
{
17+
uint8_t buttons = 0;
18+
int16_t x = 0;
19+
int16_t y = 0;
20+
int8_t wheel = 0;
21+
int8_t pan = 0;
22+
} hid_abs_mouse_report_t;
23+
24+
25+
// Absolute Mouse Report Descriptor Template applies those datatype changes too
26+
#define TUD_HID_REPORT_DESC_ABSMOUSE(...) \
27+
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
28+
HID_USAGE ( HID_USAGE_DESKTOP_MOUSE ) ,\
29+
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\
30+
/* Report ID if any */\
31+
__VA_ARGS__ \
32+
HID_USAGE ( HID_USAGE_DESKTOP_POINTER ) ,\
33+
HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\
34+
HID_USAGE_PAGE ( HID_USAGE_PAGE_BUTTON ) ,\
35+
HID_USAGE_MIN ( 1 ) ,\
36+
HID_USAGE_MAX ( 5 ) ,\
37+
HID_LOGICAL_MIN ( 0 ) ,\
38+
HID_LOGICAL_MAX ( 1 ) ,\
39+
/* Left, Right, Middle, Backward, Forward buttons */ \
40+
HID_REPORT_COUNT( 5 ) ,\
41+
HID_REPORT_SIZE ( 1 ) ,\
42+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
43+
/* 3 bit padding */ \
44+
HID_REPORT_COUNT( 1 ) ,\
45+
HID_REPORT_SIZE ( 3 ) ,\
46+
HID_INPUT ( HID_CONSTANT ) ,\
47+
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\
48+
/* X, Y absolute position [0, 32767] */ \
49+
HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\
50+
HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\
51+
HID_LOGICAL_MIN ( 0x00 ) ,\
52+
HID_LOGICAL_MAX_N( 0x7FFF, 2 ) ,\
53+
HID_REPORT_SIZE ( 16 ) ,\
54+
HID_REPORT_COUNT ( 2 ) ,\
55+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\
56+
/* Vertical wheel scroll [-127, 127] */ \
57+
HID_USAGE ( HID_USAGE_DESKTOP_WHEEL ) ,\
58+
HID_LOGICAL_MIN ( 0x81 ) ,\
59+
HID_LOGICAL_MAX ( 0x7f ) ,\
60+
HID_REPORT_COUNT( 1 ) ,\
61+
HID_REPORT_SIZE ( 8 ) ,\
62+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ) ,\
63+
HID_USAGE_PAGE ( HID_USAGE_PAGE_CONSUMER ), \
64+
/* Horizontal wheel scroll [-127, 127] */ \
65+
HID_USAGE_N ( HID_USAGE_CONSUMER_AC_PAN, 2 ), \
66+
HID_LOGICAL_MIN ( 0x81 ), \
67+
HID_LOGICAL_MAX ( 0x7f ), \
68+
HID_REPORT_COUNT( 1 ), \
69+
HID_REPORT_SIZE ( 8 ), \
70+
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_RELATIVE ), \
71+
HID_COLLECTION_END , \
72+
HID_COLLECTION_END \
73+
74+
static inline bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal)
75+
{
76+
hid_abs_mouse_report_t report =
77+
{
78+
.buttons = buttons,
79+
.x = x,
80+
.y = y,
81+
.wheel = vertical,
82+
.pan = horizontal
83+
};
84+
return tud_hid_n_report(instance, report_id, &report, sizeof(report));
85+
}
86+
87+
static inline bool tud_hid_abs_mouse_report(uint8_t report_id, uint8_t buttons, int16_t x, int16_t y, int8_t vertical, int8_t horizontal)
88+
{
89+
return tud_hid_n_abs_mouse_report(0, report_id, buttons, x, y, vertical, horizontal);
90+
}
91+
92+
93+
} // end extern "C"
94+
95+
#else
96+
#pragma message "This file is now safe to delete along with its include from USBHIDMouse.h"
97+
#endif
98+

0 commit comments

Comments
 (0)