add hid stylus pen device.

this works with android, for bypassing that absmouse does not support android.
note that, to hide cursor on android for every touch signal, find cursor option in android settings menu.

references:
1. https://stackoverflow.com/questions/28536602/hid-digitizer-descriptor-doesnt-perform-well-with-landscape-orientation
2. https://github.com/jonathanedgecombe/absmouse/blob/master/src/AbsMouse.cpp
This commit is contained in:
Jay 2024-12-23 22:03:37 +09:00
parent 7c1afa837a
commit 15b1623aa3
6 changed files with 121 additions and 1 deletions

View File

@ -197,11 +197,43 @@ static void send_hid_report(uint8_t report_id, uint32_t btn)
}
}
break;
default: break;
}
}
/* use this to send stylus touch signal through USB. */
static void send_stylus_touch(uint16_t x, uint16_t y, bool state)
{
// skip if hid is not ready yet
if ( !tud_hid_ready() ) return;
static bool has_stylus_pen = false;
hid_stylus_report_t report =
{
.attr = 0,
.x = 0,
.y = 0
};
report.x = x;
report.y = y;
if (state)
{
report.attr = STYLUS_ATTR_TIP_SWITCH | STYLUS_ATTR_IN_RANGE;
tud_hid_report(REPORT_ID_STYLUS_PEN, &report, sizeof(report));
has_stylus_pen = true;
}else
{
report.attr = 0;
if (has_stylus_pen) tud_hid_report(REPORT_ID_STYLUS_PEN, &report, sizeof(report));
has_stylus_pen = false;
}
}
// Every 10ms, we will sent 1 report for each HID profile (keyboard, mouse etc ..)
// tud_hid_report_complete_cb() is used to send the next report after previous one is complete
void hid_task(void)

View File

@ -79,6 +79,7 @@ uint8_t const desc_hid_report[] =
{
TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD )),
TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE )),
TUD_HID_REPORT_DESC_STYLUS_PEN( HID_REPORT_ID(REPORT_ID_STYLUS_PEN )),
TUD_HID_REPORT_DESC_CONSUMER( HID_REPORT_ID(REPORT_ID_CONSUMER_CONTROL )),
TUD_HID_REPORT_DESC_GAMEPAD ( HID_REPORT_ID(REPORT_ID_GAMEPAD ))
};

View File

@ -29,6 +29,7 @@ enum
{
REPORT_ID_KEYBOARD = 1,
REPORT_ID_MOUSE,
REPORT_ID_STYLUS_PEN,
REPORT_ID_CONSUMER_CONTROL,
REPORT_ID_GAMEPAD,
REPORT_ID_COUNT

View File

@ -325,6 +325,29 @@ typedef enum
/// @}
//--------------------------------------------------------------------+
// Digitizer Stylus Pen
//--------------------------------------------------------------------+
/** \addtogroup ClassDriver_HID_Stylus Stylus
* @{ */
// Standard Stylus Pen Report.
typedef struct TU_ATTR_PACKED
{
uint8_t attr; /**< Attribute mask for describing current status of the stylus pen. */
uint16_t x; /**< Current x position of the mouse. */
uint16_t y; /**< Current y position of the mouse. */
} hid_stylus_report_t;
// Standard Stylus Pen Attributes Bitmap.
typedef enum
{
STYLUS_ATTR_TIP_SWITCH = TU_BIT(0), ///< Tip switch
STYLUS_ATTR_IN_RANGE = TU_BIT(1), ///< In-range bit.
} hid_stylus_attr_bm_t;
/// @}
//--------------------------------------------------------------------+
// Keyboard
//--------------------------------------------------------------------+
@ -760,7 +783,9 @@ enum {
HID_USAGE_PAGE_PID = 0x0f,
HID_USAGE_PAGE_UNICODE = 0x10,
HID_USAGE_PAGE_ALPHA_DISPLAY = 0x14,
HID_USAGE_PAGE_IN_RANGE = 0x32,
HID_USAGE_PAGE_MEDICAL = 0x40,
HID_USAGE_PAGE_TIP_SWITCH = 0x42,
HID_USAGE_PAGE_LIGHTING_AND_ILLUMINATION = 0x59,
HID_USAGE_PAGE_MONITOR = 0x80, // 0x80 - 0x83
HID_USAGE_PAGE_POWER = 0x84, // 0x084 - 0x87
@ -846,6 +871,15 @@ enum {
HID_USAGE_DESKTOP_SYSTEM_DISPLAY_LCD_AUTOSCALE = 0xB7
};
/// HID Usage Table: Digitizer Page (0x0D)
enum {
// Touch Screen.
HID_USAGE_DIGITIZER_TOUCH_SCREEN = 0x04,
// Stylus Pen.
HID_USAGE_DIGITIZER_STYLUS = 0x20,
};
/// HID Usage Table: Consumer Page (0x0C)
/// Only contains controls that supported by Windows (whole list is too long)

View File

@ -194,6 +194,16 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id,
return tud_hid_n_report(instance, report_id, &report, sizeof(report));
}
bool tud_hid_n_stylus_report(uint8_t instance, uint8_t report_id, uint8_t attrs, uint16_t x, uint16_t y) {
hid_stylus_report_t report = {
.attr = attrs,
.x = x,
.y = y,
};
return tud_hid_n_report(instance, report_id, &report, sizeof(report));
}
//--------------------------------------------------------------------+
// USBD-CLASS API
//--------------------------------------------------------------------+

View File

@ -79,6 +79,9 @@ bool tud_hid_n_abs_mouse_report(uint8_t instance, uint8_t report_id, uint8_t but
// use template layout report TUD_HID_REPORT_DESC_GAMEPAD
bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons);
// STYLUS PEN: convenient helper to send absolute stylus pen report if application
bool tud_hid_n_stylus_report(uint8_t instance, uint8_t report_id, uint8_t attrs, uint16_t x, uint16_t y);
//--------------------------------------------------------------------+
// Application API (Single Port)
//--------------------------------------------------------------------+
@ -114,6 +117,10 @@ TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_gamepad_report(uint8_t report_i
return tud_hid_n_gamepad_report(0, report_id, x, y, z, rz, rx, ry, hat, buttons);
}
TU_ATTR_ALWAYS_INLINE static inline bool tud_hid_stylus_report(uint8_t report_id, uint8_t attrs, uint16_t x, uint16_t y) {
return tud_hid_n_stylus_report(0, report_id, attrs, x, y);
}
//--------------------------------------------------------------------+
// Application Callbacks
//--------------------------------------------------------------------+
@ -257,6 +264,41 @@ void tud_hid_report_failed_cb(uint8_t instance, hid_report_type_t report_type, u
HID_COLLECTION_END , \
HID_COLLECTION_END \
// Stylus Pen Report Descriptor Template
#define TUD_HID_REPORT_DESC_STYLUS_PEN(...) \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DIGITIZER ) , \
HID_USAGE ( HID_USAGE_DIGITIZER_TOUCH_SCREEN ) , \
HID_COLLECTION ( HID_COLLECTION_APPLICATION ) , \
/* Report ID if any */\
__VA_ARGS__ \
HID_USAGE ( HID_USAGE_DIGITIZER_STYLUS ) , \
HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) , \
HID_USAGE_PAGE ( HID_USAGE_PAGE_TIP_SWITCH ) , \
HID_USAGE_PAGE ( HID_USAGE_PAGE_IN_RANGE ) , \
HID_LOGICAL_MIN ( 0 ), \
HID_LOGICAL_MAX ( 1 ), \
HID_REPORT_SIZE ( 1 ), \
HID_REPORT_COUNT( 2 ), \
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), \
HID_REPORT_SIZE ( 1 ), \
HID_REPORT_COUNT( 6 ), \
HID_INPUT ( HID_CONSTANT | HID_ARRAY | HID_ABSOLUTE), \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ), \
HID_PHYSICAL_MAX( 0x7fff ), \
HID_LOGICAL_MAX ( 0x7fff ), \
HID_REPORT_SIZE ( 16 ), \
HID_REPORT_COUNT( 1 ), \
HID_UNIT_EXPONENT( -1 ), \
HID_UNIT ( HID_VARIABLE | HID_NONLINEAR ), \
HID_PHYSICAL_MIN( 0 ), \
HID_PHYSICAL_MAX( 0 ), \
HID_USAGE ( HID_USAGE_DESKTOP_X ), \
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), \
HID_USAGE ( HID_USAGE_DESKTOP_Y ), \
HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ), \
HID_COLLECTION_END , \
HID_COLLECTION_END \
// Absolute Mouse Report Descriptor Template
#define TUD_HID_REPORT_DESC_ABSMOUSE(...) \
HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\