void TabletProtocolHandler::AddHandlers(HIDDevice &device, HIDCollection &collection, ProtocolHandler *&handlerList) { 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: // NOTE: Maybe it is supported if X-axis and Y-axis are // absolute. This is determined below by scanning the // report items for absolute X and Y axis. 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: TRACE("found tablet/digitizer\n"); supported = true; break; } break; } } if (!supported) { TRACE("collection not a tablet/digitizer\n"); return; } HIDParser &parser = device.Parser(); uint32 maxReportCount = parser.CountReports(HID_REPORT_TYPE_INPUT); if (maxReportCount == 0) return; uint32 inputReportCount = 0; HIDReport *inputReports[maxReportCount]; collection.BuildReportList(HID_REPORT_TYPE_INPUT, inputReports, inputReportCount); for (uint32 i = 0; i < inputReportCount; i++) { HIDReport *inputReport = inputReports[i]; // try to find at least an absolute x and y axis HIDReportItem *xAxis = inputReport->FindItem( B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_X); if (xAxis == NULL || xAxis->Relative()) continue; HIDReportItem *yAxis = inputReport->FindItem( B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_Y); if (yAxis == NULL || yAxis->Relative()) continue; ProtocolHandler *newHandler = new(std::nothrow) TabletProtocolHandler( *inputReport, *xAxis, *yAxis); if (newHandler == NULL) { TRACE("failed to allocated tablet protocol handler\n"); continue; } newHandler->SetNextHandler(handlerList); handlerList = newHandler; } }
TabletProtocolHandler::TabletProtocolHandler(HIDReport &report, HIDReportItem &xAxis, HIDReportItem &yAxis) : ProtocolHandler(report.Device(), "input/tablet/usb", 0), fReport(report), fXAxis(xAxis), fYAxis(yAxis), fWheel(NULL), fPressure(NULL), fRange(NULL), fTip(NULL), fBarrelSwitch(NULL), fEraser(NULL), fXTilt(NULL), fYTilt(NULL), fLastButtons(0), fClickCount(0), fLastClickTime(0), fClickSpeed(250000) { uint32 buttonCount = 0; for (uint32 i = 0; i < report.CountItems(); i++) { HIDReportItem *item = report.ItemAt(i); if (!item->HasData()) continue; if (item->UsagePage() == B_HID_USAGE_PAGE_BUTTON && item->UsageID() - 1 < B_MAX_MOUSE_BUTTONS) { fButtons[buttonCount++] = item; } } fButtons[buttonCount] = NULL; fWheel = report.FindItem(B_HID_USAGE_PAGE_GENERIC_DESKTOP, B_HID_UID_GD_WHEEL); fPressure = report.FindItem(B_HID_USAGE_PAGE_DIGITIZER, B_HID_UID_DIG_TIP_PRESSURE); fRange = 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); fYTilt = report.FindItem(B_HID_USAGE_PAGE_DIGITIZER, B_HID_UID_DIG_Y_TILT); TRACE("tablet device with %lu buttons, %stip, %seraser, " "%spressure, and %stilt\n", buttonCount, fTip == NULL ? "no " : "", fEraser == NULL ? "no " : "", fPressure == NULL ? "no " : "", fXTilt == NULL && fYTilt == NULL ? "no " : ""); TRACE("report id: %u\n", report.ID()); }