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:
parent
3e144a2ffd
commit
bc64bf6ab4
@ -22,11 +22,13 @@
|
||||
#include <keyboard_mouse_driver.h>
|
||||
|
||||
|
||||
MouseProtocolHandler::MouseProtocolHandler(HIDReport &report,
|
||||
MouseProtocolHandler::MouseProtocolHandler(HIDReport &report, bool tablet,
|
||||
HIDReportItem &xAxis, HIDReportItem &yAxis)
|
||||
:
|
||||
ProtocolHandler(report.Device(), "input/mouse/usb/", 0),
|
||||
ProtocolHandler(report.Device(),
|
||||
tablet ? "input/tablet/usb" : "input/mouse/usb/", 0),
|
||||
fReport(report),
|
||||
fTablet(tablet),
|
||||
fXAxis(xAxis),
|
||||
fYAxis(yAxis),
|
||||
fWheel(NULL),
|
||||
@ -62,9 +64,40 @@ void
|
||||
MouseProtocolHandler::AddHandlers(HIDDevice &device, HIDCollection &collection,
|
||||
ProtocolHandler *&handlerList)
|
||||
{
|
||||
if (collection.UsagePage() != B_HID_USAGE_PAGE_GENERIC_DESKTOP
|
||||
|| collection.UsageID() != B_HID_UID_GD_MOUSE) {
|
||||
TRACE("collection not a mouse\n");
|
||||
bool tablet = false;
|
||||
bool supported = false;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -92,8 +125,11 @@ MouseProtocolHandler::AddHandlers(HIDDevice &device, HIDCollection &collection,
|
||||
if (yAxis == NULL)
|
||||
continue;
|
||||
|
||||
if (!xAxis->Relative() && !yAxis->Relative())
|
||||
tablet = true;
|
||||
|
||||
ProtocolHandler *newHandler = new(std::nothrow) MouseProtocolHandler(
|
||||
*inputReport, *xAxis, *yAxis);
|
||||
*inputReport, tablet, *xAxis, *yAxis);
|
||||
if (newHandler == NULL) {
|
||||
TRACE("failed to allocated mouse protocol handler\n");
|
||||
continue;
|
||||
@ -112,8 +148,10 @@ MouseProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer,
|
||||
switch (op) {
|
||||
case MS_READ:
|
||||
{
|
||||
if (length < sizeof(mouse_movement))
|
||||
if ((!fTablet && length < sizeof(mouse_movement))
|
||||
|| (fTablet && length < sizeof(tablet_movement))) {
|
||||
return B_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
status_t result = _ReadReport(buffer);
|
||||
@ -164,31 +202,42 @@ MouseProtocolHandler::_ReadReport(void *buffer)
|
||||
return B_INTERRUPTED;
|
||||
}
|
||||
|
||||
mouse_movement *info = (mouse_movement *)buffer;
|
||||
memset(info, 0, sizeof(mouse_movement));
|
||||
float axisAbsoluteData[2];
|
||||
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())
|
||||
info->xdelta = fXAxis.Data();
|
||||
if (fYAxis.Extract() == B_OK && fYAxis.Valid())
|
||||
info->ydelta = -fYAxis.Data();
|
||||
if (fYAxis.Extract() == B_OK && fYAxis.Valid()) {
|
||||
if (fYAxis.Relative())
|
||||
axisRelativeData[1] = fYAxis.Data();
|
||||
else
|
||||
axisAbsoluteData[1] = fYAxis.ScaledFloatData();
|
||||
}
|
||||
|
||||
uint32 wheelData = 0;
|
||||
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++) {
|
||||
HIDReportItem *button = fButtons[i];
|
||||
if (button == NULL)
|
||||
break;
|
||||
|
||||
if (button->Extract() == B_OK && button->Valid())
|
||||
info->buttons |= (button->Data() & 1) << (button->UsageID() - 1);
|
||||
buttons |= (button->Data() & 1) << (button->UsageID() - 1);
|
||||
}
|
||||
|
||||
fReport.DoneProcessing();
|
||||
TRACE("got mouse report\n");
|
||||
|
||||
int32 clicks = 0;
|
||||
bigtime_t timestamp = system_time();
|
||||
if (info->buttons != 0) {
|
||||
if (buttons != 0) {
|
||||
if (fLastButtons == 0) {
|
||||
if (fLastClickTime + fClickSpeed > timestamp)
|
||||
fClickCount++;
|
||||
@ -197,10 +246,38 @@ MouseProtocolHandler::_ReadReport(void *buffer)
|
||||
}
|
||||
|
||||
fLastClickTime = timestamp;
|
||||
info->clicks = fClickCount;
|
||||
clicks = fClickCount;
|
||||
}
|
||||
|
||||
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->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;
|
||||
}
|
||||
|
||||
fLastButtons = info->buttons;
|
||||
info->timestamp = timestamp;
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -23,7 +23,8 @@ class HIDReportItem;
|
||||
class MouseProtocolHandler : public ProtocolHandler {
|
||||
public:
|
||||
MouseProtocolHandler(HIDReport &report,
|
||||
HIDReportItem &xAxis, HIDReportItem &yAxis);
|
||||
bool tablet, HIDReportItem &xAxis,
|
||||
HIDReportItem &yAxis);
|
||||
|
||||
static void AddHandlers(HIDDevice &device,
|
||||
HIDCollection &collection,
|
||||
@ -36,6 +37,7 @@ private:
|
||||
status_t _ReadReport(void *buffer);
|
||||
|
||||
HIDReport & fReport;
|
||||
bool fTablet;
|
||||
|
||||
HIDReportItem & fXAxis;
|
||||
HIDReportItem & fYAxis;
|
||||
|
Loading…
Reference in New Issue
Block a user