Add support for absolute pointing devices. Supported are mice/pointers with
absolute coordinates (qemu/kvm -usbdevice tablet) and various digitizers. If a tablet-like usage is determined the MouseProtocolHandler publishes to input/tablet instead of input/mouse and reports its info in a tablet_movement structure instead of a mouse_movement structure, allowing for absolute coordinates. Note that right now only the absolute coordinates are used, the other tablet specific inputs (eraser, pressure, tilt and contact) aren't yet filled in. I will add these as a second step. I've only tested this with kvm where this makes the "seamless" mouse integration work and therefore fixes #5989. Note that QEMU for BeOS/Haiku doesn't support that mode (patch pending on my side) and will lock the pointer into the upper left corner if -usbdevice tablet is used (whereas it previously just did nothing). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41951 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -22,11 +22,13 @@
|
|||||||
#include <keyboard_mouse_driver.h>
|
#include <keyboard_mouse_driver.h>
|
||||||
|
|
||||||
|
|
||||||
MouseProtocolHandler::MouseProtocolHandler(HIDReport &report,
|
MouseProtocolHandler::MouseProtocolHandler(HIDReport &report, bool tablet,
|
||||||
HIDReportItem &xAxis, HIDReportItem &yAxis)
|
HIDReportItem &xAxis, HIDReportItem &yAxis)
|
||||||
:
|
:
|
||||||
ProtocolHandler(report.Device(), "input/mouse/usb/", 0),
|
ProtocolHandler(report.Device(),
|
||||||
|
tablet ? "input/tablet/usb" : "input/mouse/usb/", 0),
|
||||||
fReport(report),
|
fReport(report),
|
||||||
|
fTablet(tablet),
|
||||||
fXAxis(xAxis),
|
fXAxis(xAxis),
|
||||||
fYAxis(yAxis),
|
fYAxis(yAxis),
|
||||||
fWheel(NULL),
|
fWheel(NULL),
|
||||||
@@ -62,9 +64,40 @@ void
|
|||||||
MouseProtocolHandler::AddHandlers(HIDDevice &device, HIDCollection &collection,
|
MouseProtocolHandler::AddHandlers(HIDDevice &device, HIDCollection &collection,
|
||||||
ProtocolHandler *&handlerList)
|
ProtocolHandler *&handlerList)
|
||||||
{
|
{
|
||||||
if (collection.UsagePage() != B_HID_USAGE_PAGE_GENERIC_DESKTOP
|
bool tablet = false;
|
||||||
|| collection.UsageID() != B_HID_UID_GD_MOUSE) {
|
bool supported = false;
|
||||||
TRACE("collection not a mouse\n");
|
switch (collection.UsagePage()) {
|
||||||
|
case B_HID_USAGE_PAGE_GENERIC_DESKTOP:
|
||||||
|
{
|
||||||
|
switch (collection.UsageID()) {
|
||||||
|
case B_HID_UID_GD_MOUSE:
|
||||||
|
case B_HID_UID_GD_POINTER:
|
||||||
|
supported = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case B_HID_USAGE_PAGE_DIGITIZER:
|
||||||
|
{
|
||||||
|
switch (collection.UsageID()) {
|
||||||
|
case B_HID_UID_DIG_DIGITIZER:
|
||||||
|
case B_HID_UID_DIG_PEN:
|
||||||
|
case B_HID_UID_DIG_LIGHT_PEN:
|
||||||
|
case B_HID_UID_DIG_TOUCH_SCREEN:
|
||||||
|
case B_HID_UID_DIG_TOUCH_PAD:
|
||||||
|
case B_HID_UID_DIG_WHITE_BOARD:
|
||||||
|
supported = true;
|
||||||
|
tablet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!supported) {
|
||||||
|
TRACE("collection not a mouse/tablet/digitizer\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,8 +125,11 @@ MouseProtocolHandler::AddHandlers(HIDDevice &device, HIDCollection &collection,
|
|||||||
if (yAxis == NULL)
|
if (yAxis == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!xAxis->Relative() && !yAxis->Relative())
|
||||||
|
tablet = true;
|
||||||
|
|
||||||
ProtocolHandler *newHandler = new(std::nothrow) MouseProtocolHandler(
|
ProtocolHandler *newHandler = new(std::nothrow) MouseProtocolHandler(
|
||||||
*inputReport, *xAxis, *yAxis);
|
*inputReport, tablet, *xAxis, *yAxis);
|
||||||
if (newHandler == NULL) {
|
if (newHandler == NULL) {
|
||||||
TRACE("failed to allocated mouse protocol handler\n");
|
TRACE("failed to allocated mouse protocol handler\n");
|
||||||
continue;
|
continue;
|
||||||
@@ -112,8 +148,10 @@ MouseProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer,
|
|||||||
switch (op) {
|
switch (op) {
|
||||||
case MS_READ:
|
case MS_READ:
|
||||||
{
|
{
|
||||||
if (length < sizeof(mouse_movement))
|
if ((!fTablet && length < sizeof(mouse_movement))
|
||||||
|
|| (fTablet && length < sizeof(tablet_movement))) {
|
||||||
return B_BUFFER_OVERFLOW;
|
return B_BUFFER_OVERFLOW;
|
||||||
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
status_t result = _ReadReport(buffer);
|
status_t result = _ReadReport(buffer);
|
||||||
@@ -164,31 +202,42 @@ MouseProtocolHandler::_ReadReport(void *buffer)
|
|||||||
return B_INTERRUPTED;
|
return B_INTERRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
mouse_movement *info = (mouse_movement *)buffer;
|
float axisAbsoluteData[2];
|
||||||
memset(info, 0, sizeof(mouse_movement));
|
uint32 axisRelativeData[2];
|
||||||
|
if (fXAxis.Extract() == B_OK && fXAxis.Valid()) {
|
||||||
|
if (fXAxis.Relative())
|
||||||
|
axisRelativeData[0] = fXAxis.Data();
|
||||||
|
else
|
||||||
|
axisAbsoluteData[0] = fXAxis.ScaledFloatData();
|
||||||
|
}
|
||||||
|
|
||||||
if (fXAxis.Extract() == B_OK && fXAxis.Valid())
|
if (fYAxis.Extract() == B_OK && fYAxis.Valid()) {
|
||||||
info->xdelta = fXAxis.Data();
|
if (fYAxis.Relative())
|
||||||
if (fYAxis.Extract() == B_OK && fYAxis.Valid())
|
axisRelativeData[1] = fYAxis.Data();
|
||||||
info->ydelta = -fYAxis.Data();
|
else
|
||||||
|
axisAbsoluteData[1] = fYAxis.ScaledFloatData();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 wheelData = 0;
|
||||||
if (fWheel != NULL && fWheel->Extract() == B_OK && fWheel->Valid())
|
if (fWheel != NULL && fWheel->Extract() == B_OK && fWheel->Valid())
|
||||||
info->wheel_ydelta = -fWheel->Data();
|
wheelData = fWheel->Data();
|
||||||
|
|
||||||
|
uint32 buttons = 0;
|
||||||
for (uint32 i = 0; i < B_MAX_MOUSE_BUTTONS; i++) {
|
for (uint32 i = 0; i < B_MAX_MOUSE_BUTTONS; i++) {
|
||||||
HIDReportItem *button = fButtons[i];
|
HIDReportItem *button = fButtons[i];
|
||||||
if (button == NULL)
|
if (button == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (button->Extract() == B_OK && button->Valid())
|
if (button->Extract() == B_OK && button->Valid())
|
||||||
info->buttons |= (button->Data() & 1) << (button->UsageID() - 1);
|
buttons |= (button->Data() & 1) << (button->UsageID() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fReport.DoneProcessing();
|
fReport.DoneProcessing();
|
||||||
TRACE("got mouse report\n");
|
TRACE("got mouse report\n");
|
||||||
|
|
||||||
|
int32 clicks = 0;
|
||||||
bigtime_t timestamp = system_time();
|
bigtime_t timestamp = system_time();
|
||||||
if (info->buttons != 0) {
|
if (buttons != 0) {
|
||||||
if (fLastButtons == 0) {
|
if (fLastButtons == 0) {
|
||||||
if (fLastClickTime + fClickSpeed > timestamp)
|
if (fLastClickTime + fClickSpeed > timestamp)
|
||||||
fClickCount++;
|
fClickCount++;
|
||||||
@@ -197,10 +246,38 @@ MouseProtocolHandler::_ReadReport(void *buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fLastClickTime = timestamp;
|
fLastClickTime = timestamp;
|
||||||
info->clicks = fClickCount;
|
clicks = fClickCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
fLastButtons = info->buttons;
|
fLastButtons = buttons;
|
||||||
|
|
||||||
|
if (fTablet) {
|
||||||
|
tablet_movement *info = (tablet_movement *)buffer;
|
||||||
|
memset(info, 0, sizeof(tablet_movement));
|
||||||
|
|
||||||
|
info->xpos = axisAbsoluteData[0];
|
||||||
|
info->ypos = axisAbsoluteData[1];
|
||||||
|
info->has_contact = true;
|
||||||
|
info->pressure = 1.0;
|
||||||
|
info->eraser = false;
|
||||||
|
info->tilt_x = 0.0;
|
||||||
|
info->tilt_y = 0.0;
|
||||||
|
|
||||||
|
info->buttons = buttons;
|
||||||
|
info->clicks = clicks;
|
||||||
info->timestamp = timestamp;
|
info->timestamp = timestamp;
|
||||||
|
info->wheel_ydelta = -wheelData;
|
||||||
|
} else {
|
||||||
|
mouse_movement *info = (mouse_movement *)buffer;
|
||||||
|
memset(info, 0, sizeof(mouse_movement));
|
||||||
|
|
||||||
|
info->buttons = buttons;
|
||||||
|
info->xdelta = axisRelativeData[0];
|
||||||
|
info->ydelta = -axisRelativeData[1];
|
||||||
|
info->clicks = clicks;
|
||||||
|
info->timestamp = timestamp;
|
||||||
|
info->wheel_ydelta = -wheelData;
|
||||||
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ class HIDReportItem;
|
|||||||
class MouseProtocolHandler : public ProtocolHandler {
|
class MouseProtocolHandler : public ProtocolHandler {
|
||||||
public:
|
public:
|
||||||
MouseProtocolHandler(HIDReport &report,
|
MouseProtocolHandler(HIDReport &report,
|
||||||
HIDReportItem &xAxis, HIDReportItem &yAxis);
|
bool tablet, HIDReportItem &xAxis,
|
||||||
|
HIDReportItem &yAxis);
|
||||||
|
|
||||||
static void AddHandlers(HIDDevice &device,
|
static void AddHandlers(HIDDevice &device,
|
||||||
HIDCollection &collection,
|
HIDCollection &collection,
|
||||||
@@ -36,6 +37,7 @@ private:
|
|||||||
status_t _ReadReport(void *buffer);
|
status_t _ReadReport(void *buffer);
|
||||||
|
|
||||||
HIDReport & fReport;
|
HIDReport & fReport;
|
||||||
|
bool fTablet;
|
||||||
|
|
||||||
HIDReportItem & fXAxis;
|
HIDReportItem & fXAxis;
|
||||||
HIDReportItem & fYAxis;
|
HIDReportItem & fYAxis;
|
||||||
|
|||||||
Reference in New Issue
Block a user