usb_hid: Enable digitizers to produce button events from tip and barrel switches
Change-Id: Ifcf542e6b04f2f210c80528279e70e0fdd1bb4e3 Reviewed-on: https://review.haiku-os.org/c/haiku/+/2685 Reviewed-by: Adrien Destugues <pulkomandy@gmail.com>
This commit is contained in:
parent
20719db962
commit
52a54e1b51
@ -98,14 +98,21 @@ typedef struct {
|
||||
} mouse_movement;
|
||||
|
||||
|
||||
#define B_TIP_SWITCH 0x01
|
||||
#define B_SECONDARY_TIP_SWITCH 0x02
|
||||
#define B_BARREL_SWITCH 0x04
|
||||
#define B_ERASER 0x08
|
||||
#define B_TABLET_PICK 0x0F
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32 buttons;
|
||||
uint32 switches;
|
||||
float xpos;
|
||||
float ypos;
|
||||
bool has_contact;
|
||||
float pressure;
|
||||
int32 clicks;
|
||||
bool eraser;
|
||||
bigtime_t timestamp;
|
||||
int32 wheel_ydelta;
|
||||
int32 wheel_xdelta;
|
||||
|
@ -327,6 +327,10 @@ TabletDevice::_ControlThread()
|
||||
if (movements.has_contact) {
|
||||
// Send single messages for each event
|
||||
|
||||
movements.buttons |= (movements.switches & B_TIP_SWITCH);
|
||||
movements.buttons |= (movements.switches & B_BARREL_SWITCH) >> 1;
|
||||
bool eraser = (movements.switches & B_ERASER) != 0;
|
||||
|
||||
uint32 buttons = lastButtons ^ movements.buttons;
|
||||
if (buttons != 0) {
|
||||
bool pressedButton = (buttons & movements.buttons) > 0;
|
||||
@ -355,7 +359,8 @@ TabletDevice::_ControlThread()
|
||||
message->AddFloat("be:tablet_x", movements.xpos);
|
||||
message->AddFloat("be:tablet_y", movements.ypos);
|
||||
message->AddFloat("be:tablet_pressure", movements.pressure);
|
||||
message->AddInt32("be:tablet_eraser", movements.eraser);
|
||||
message->AddInt32("be:tablet_eraser", eraser);
|
||||
|
||||
if (movements.tilt_x != 0.0 || movements.tilt_y != 0.0) {
|
||||
message->AddFloat("be:tablet_tilt_x", movements.tilt_x);
|
||||
message->AddFloat("be:tablet_tilt_y", movements.tilt_y);
|
||||
|
@ -37,19 +37,19 @@ TabletProtocolHandler::TabletProtocolHandler(HIDReport &report,
|
||||
fWheel(NULL),
|
||||
|
||||
fPressure(NULL),
|
||||
fRange(NULL),
|
||||
fTip(NULL),
|
||||
fBarrelSwitch(NULL),
|
||||
fEraser(NULL),
|
||||
fInRange(NULL),
|
||||
fXTilt(NULL),
|
||||
fYTilt(NULL),
|
||||
|
||||
fLastButtons(0),
|
||||
fLastSwitches(0),
|
||||
fClickCount(0),
|
||||
fLastClickTime(0),
|
||||
fClickSpeed(250000)
|
||||
{
|
||||
uint32 buttonCount = 0;
|
||||
uint32 switchCount = 0;
|
||||
|
||||
for (uint32 i = 0; i < report.CountItems(); i++) {
|
||||
HIDReportItem *item = report.ItemAt(i);
|
||||
if (!item->HasData())
|
||||
@ -59,9 +59,16 @@ TabletProtocolHandler::TabletProtocolHandler(HIDReport &report,
|
||||
&& item->UsageID() - 1 < B_MAX_MOUSE_BUTTONS) {
|
||||
fButtons[buttonCount++] = item;
|
||||
}
|
||||
|
||||
if (item->UsagePage() == B_HID_USAGE_PAGE_DIGITIZER
|
||||
&& item->UsageID() >= B_HID_UID_DIG_TIP_SWITCH
|
||||
&& item->UsageID() <= B_HID_UID_DIG_TABLET_PICK) {
|
||||
fSwitches[switchCount++] = item;
|
||||
}
|
||||
}
|
||||
|
||||
fButtons[buttonCount] = NULL;
|
||||
fSwitches[switchCount] = NULL;
|
||||
|
||||
fWheel = report.FindItem(B_HID_USAGE_PAGE_GENERIC_DESKTOP,
|
||||
B_HID_UID_GD_WHEEL);
|
||||
@ -69,17 +76,8 @@ TabletProtocolHandler::TabletProtocolHandler(HIDReport &report,
|
||||
fPressure = report.FindItem(B_HID_USAGE_PAGE_DIGITIZER,
|
||||
B_HID_UID_DIG_TIP_PRESSURE);
|
||||
|
||||
fRange = report.FindItem(B_HID_USAGE_PAGE_DIGITIZER,
|
||||
fInRange = report.FindItem(B_HID_USAGE_PAGE_DIGITIZER,
|
||||
B_HID_UID_DIG_IN_RANGE);
|
||||
|
||||
fTip = report.FindItem(B_HID_USAGE_PAGE_DIGITIZER,
|
||||
B_HID_UID_DIG_TIP_SWITCH);
|
||||
|
||||
fBarrelSwitch = report.FindItem(B_HID_USAGE_PAGE_DIGITIZER,
|
||||
B_HID_UID_DIG_BARREL_SWITCH);
|
||||
|
||||
fEraser = report.FindItem(B_HID_USAGE_PAGE_DIGITIZER,
|
||||
B_HID_UID_DIG_ERASER);
|
||||
|
||||
fXTilt = report.FindItem(B_HID_USAGE_PAGE_DIGITIZER,
|
||||
B_HID_UID_DIG_X_TILT);
|
||||
@ -87,11 +85,10 @@ TabletProtocolHandler::TabletProtocolHandler(HIDReport &report,
|
||||
fYTilt = report.FindItem(B_HID_USAGE_PAGE_DIGITIZER,
|
||||
B_HID_UID_DIG_Y_TILT);
|
||||
|
||||
TRACE("tablet device with %" B_PRIu32 " buttons, %stip, %seraser, "
|
||||
TRACE("tablet device with %" B_PRIu32 " buttons, %" B_PRIu32 " switches,"
|
||||
"%spressure, and %stilt\n",
|
||||
buttonCount,
|
||||
fTip == NULL ? "no " : "",
|
||||
fEraser == NULL ? "no " : "",
|
||||
switchCount,
|
||||
fPressure == NULL ? "no " : "",
|
||||
fXTilt == NULL && fYTilt == NULL ? "no " : "");
|
||||
|
||||
@ -275,6 +272,17 @@ TabletProtocolHandler::_ReadReport(void *buffer, uint32 *cookie)
|
||||
buttons |= (button->Data() & 1) << (button->UsageID() - 1);
|
||||
}
|
||||
|
||||
uint32 switches = 0;
|
||||
for (uint32 i = 0; i < B_MAX_DIGITIZER_SWITCHES; i++) {
|
||||
HIDReportItem *dswitch = fSwitches[i];
|
||||
if (dswitch == NULL)
|
||||
break;
|
||||
|
||||
if (dswitch->Extract() == B_OK && dswitch->Valid())
|
||||
switches |= (dswitch->Data() & 1) << (dswitch->UsageID()
|
||||
- B_HID_UID_DIG_TIP_SWITCH);
|
||||
}
|
||||
|
||||
float pressure = 1.0f;
|
||||
if (fPressure != NULL && fPressure->Extract() == B_OK
|
||||
&& fPressure->Valid()) {
|
||||
@ -290,12 +298,8 @@ TabletProtocolHandler::_ReadReport(void *buffer, uint32 *cookie)
|
||||
yTilt = fYTilt->ScaledFloatData();
|
||||
|
||||
bool inRange = true;
|
||||
if (fRange != NULL && fRange->Extract() == B_OK && fRange->Valid())
|
||||
inRange = ((fRange->Data() & 1) != 0);
|
||||
|
||||
bool eraser = false;
|
||||
if (fEraser != NULL && fEraser->Extract() == B_OK && fEraser->Valid())
|
||||
eraser = ((fEraser->Data() & 1) != 0);
|
||||
if (fInRange != NULL && fInRange->Extract() == B_OK && fInRange->Valid())
|
||||
inRange = ((fInRange->Data() & 1) != 0);
|
||||
|
||||
fReport.DoneProcessing();
|
||||
TRACE("got tablet report\n");
|
||||
@ -316,6 +320,17 @@ TabletProtocolHandler::_ReadReport(void *buffer, uint32 *cookie)
|
||||
|
||||
fLastButtons = buttons;
|
||||
|
||||
if (switches != 0) {
|
||||
if (fLastSwitches == 0) {
|
||||
if (fLastClickTime + fClickSpeed > timestamp)
|
||||
fClickCount++;
|
||||
else
|
||||
fClickCount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
fLastSwitches = switches;
|
||||
|
||||
tablet_movement *info = (tablet_movement *)buffer;
|
||||
memset(info, 0, sizeof(tablet_movement));
|
||||
|
||||
@ -323,10 +338,10 @@ TabletProtocolHandler::_ReadReport(void *buffer, uint32 *cookie)
|
||||
info->ypos = axisAbsoluteData[1];
|
||||
info->has_contact = inRange;
|
||||
info->pressure = pressure;
|
||||
info->eraser = eraser;
|
||||
info->tilt_x = xTilt;
|
||||
info->tilt_y = yTilt;
|
||||
|
||||
info->switches = switches;
|
||||
info->buttons = buttons;
|
||||
info->clicks = clicks;
|
||||
info->timestamp = timestamp;
|
||||
|
@ -21,6 +21,9 @@ class HIDReportItem;
|
||||
# define B_MAX_MOUSE_BUTTONS 8
|
||||
#endif
|
||||
|
||||
#ifndef B_MAX_DIGITIZER_SWITCHES
|
||||
#define B_MAX_DIGITIZER_SWITCHES 5
|
||||
#endif
|
||||
|
||||
class TabletProtocolHandler : public ProtocolHandler {
|
||||
public:
|
||||
@ -44,9 +47,10 @@ private:
|
||||
HIDReportItem & fYAxis;
|
||||
HIDReportItem * fWheel;
|
||||
HIDReportItem * fButtons[B_MAX_MOUSE_BUTTONS];
|
||||
HIDReportItem * fSwitches[B_MAX_DIGITIZER_SWITCHES];
|
||||
|
||||
HIDReportItem * fPressure;
|
||||
HIDReportItem * fRange;
|
||||
HIDReportItem * fInRange;
|
||||
HIDReportItem * fTip;
|
||||
HIDReportItem * fBarrelSwitch;
|
||||
HIDReportItem * fEraser;
|
||||
@ -54,6 +58,7 @@ private:
|
||||
HIDReportItem * fYTilt;
|
||||
|
||||
uint32 fLastButtons;
|
||||
uint32 fLastSwitches;
|
||||
uint32 fClickCount;
|
||||
bigtime_t fLastClickTime;
|
||||
bigtime_t fClickSpeed;
|
||||
|
Loading…
Reference in New Issue
Block a user