status_t JoystickProtocolHandler::_Update() { status_t result = fReport.WaitForReport(B_INFINITE_TIMEOUT); if (result != B_OK) { if (fReport.Device()->IsRemoved()) { TRACE("device has been removed\n"); return B_DEV_NOT_READY; } if (result == B_CANCELED) return B_CANCELED; if (result != B_INTERRUPTED) { // interrupts happen when other reports come in on the same // input as ours TRACE_ALWAYS("error waiting for report: %s\n", strerror(result)); } // signal that we simply want to try again return B_OK; } result = mutex_lock(&fUpdateLock); if (result != B_OK) { fReport.DoneProcessing(); return result; } memset(fCurrentValues.data, 0, fCurrentValues.data_size); for (uint32 i = 0; i < fAxisCount; i++) { if (fAxis[i] == NULL) continue; if (fAxis[i]->Extract() == B_OK && fAxis[i]->Valid()) fCurrentValues.axes[i] = (int16)fAxis[i]->ScaledData(16, true); } for (uint32 i = 0; i < fHatCount; i++) { HIDReportItem *hat = fHats[i]; if (hat == NULL) continue; if (hat->Extract() != B_OK || !hat->Valid()) continue; fCurrentValues.hats[i] = hat->ScaledRangeData(1, 8); } for (uint32 i = 0; i < fButtonCount; i++) { HIDReportItem *button = fButtons[i]; if (button == NULL) break; uint16 index = button->UsageID() - 1; if (index >= fMaxButton) continue; if (button->Extract() == B_OK && button->Valid()) { fCurrentValues.buttons[index / 32] |= (button->Data() & 1) << (index % 32); } } fReport.DoneProcessing(); TRACE("got joystick report\n"); *fCurrentValues.timestamp = system_time(); mutex_unlock(&fUpdateLock); return B_OK; }
status_t TabletProtocolHandler::_ReadReport(void *buffer) { status_t result = fReport.WaitForReport(B_INFINITE_TIMEOUT); if (result != B_OK) { if (fReport.Device()->IsRemoved()) { TRACE("device has been removed\n"); return B_DEV_NOT_READY; } if (result != B_INTERRUPTED) { // interrupts happen when other reports come in on the same // input as ours TRACE_ALWAYS("error waiting for report: %s\n", strerror(result)); } // signal that we simply want to try again return B_INTERRUPTED; } float axisAbsoluteData[2]; axisAbsoluteData[0] = 0.0f; axisAbsoluteData[1] = 0.0f; if (fXAxis.Extract() == B_OK && fXAxis.Valid()) axisAbsoluteData[0] = fXAxis.ScaledFloatData(); if (fYAxis.Extract() == B_OK && fYAxis.Valid()) axisAbsoluteData[1] = fYAxis.ScaledFloatData(); uint32 wheelData = 0; if (fWheel != NULL && fWheel->Extract() == B_OK && fWheel->Valid()) 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()) buttons |= (button->Data() & 1) << (button->UsageID() - 1); } float pressure = 1.0f; if (fPressure != NULL && fPressure->Extract() == B_OK && fPressure->Valid()) { pressure = fPressure->ScaledFloatData(); } float xTilt = 0.0f; if (fXTilt != NULL && fXTilt->Extract() == B_OK && fXTilt->Valid()) xTilt = fXTilt->ScaledFloatData(); float yTilt = 0.0f; if (fXTilt != NULL && fYTilt->Extract() == B_OK && fYTilt->Valid()) yTilt = fYTilt->ScaledFloatData(); bool inRange = true; if (fRange != NULL) inRange = fRange->Extract() == B_OK && fRange->Valid(); bool eraser = false; if (fEraser != NULL && fEraser->Extract() == B_OK && fEraser->Valid()) eraser = (fEraser->Data() & 1) != 0; fReport.DoneProcessing(); TRACE("got tablet report\n"); int32 clicks = 0; bigtime_t timestamp = system_time(); if (buttons != 0) { if (fLastButtons == 0) { if (fLastClickTime + fClickSpeed > timestamp) fClickCount++; else fClickCount = 1; } fLastClickTime = timestamp; clicks = fClickCount; } fLastButtons = buttons; tablet_movement *info = (tablet_movement *)buffer; memset(info, 0, sizeof(tablet_movement)); info->xpos = axisAbsoluteData[0]; info->ypos = axisAbsoluteData[1]; info->has_contact = inRange; info->pressure = pressure; info->eraser = eraser; info->tilt_x = xTilt; info->tilt_y = yTilt; info->buttons = buttons; info->clicks = clicks; info->timestamp = timestamp; info->wheel_ydelta = -wheelData; return B_OK; }