Implement variable joystick mode in the JoystickProtocolHandler. It supports
both, variable and extended joystick mode, using the same mechanism of mimicing the extended_joystick structure with the variable one if required. The mode used depends on the support flag coming in from BJoystick (currently off), so with this commit the behaviour doesn't change. I'm going to flip that switch next though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@41891 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -24,15 +24,19 @@ JoystickProtocolHandler::JoystickProtocolHandler(HIDReport &report)
|
|||||||
:
|
:
|
||||||
ProtocolHandler(report.Device(), "joystick/usb/", 0),
|
ProtocolHandler(report.Device(), "joystick/usb/", 0),
|
||||||
fReport(report),
|
fReport(report),
|
||||||
|
fAxisCount(0),
|
||||||
|
fAxis(NULL),
|
||||||
|
fHatCount(0),
|
||||||
|
fHats(NULL),
|
||||||
|
fButtonCount(0),
|
||||||
|
fMaxButton(0),
|
||||||
|
fButtons(NULL),
|
||||||
fUpdateThread(-1)
|
fUpdateThread(-1)
|
||||||
{
|
{
|
||||||
mutex_init(&fUpdateLock, "joystick update lock");
|
mutex_init(&fUpdateLock, "joystick update lock");
|
||||||
memset(&fCurrentValues, 0, sizeof(extended_joystick));
|
memset(&fJoystickModuleInfo, 0, sizeof(joystick_module_info));
|
||||||
|
memset(&fCurrentValues, 0, sizeof(variable_joystick));
|
||||||
|
|
||||||
for (uint32 i = 0; i < MAX_AXES; i++)
|
|
||||||
fAxis[i] = NULL;
|
|
||||||
|
|
||||||
uint32 buttonCount = 0;
|
|
||||||
for (uint32 i = 0; i < report.CountItems(); i++) {
|
for (uint32 i = 0; i < report.CountItems(); i++) {
|
||||||
HIDReportItem *item = report.ItemAt(i);
|
HIDReportItem *item = report.ItemAt(i);
|
||||||
if (!item->HasData())
|
if (!item->HasData())
|
||||||
@@ -41,8 +45,21 @@ JoystickProtocolHandler::JoystickProtocolHandler(HIDReport &report)
|
|||||||
switch (item->UsagePage()) {
|
switch (item->UsagePage()) {
|
||||||
case B_HID_USAGE_PAGE_BUTTON:
|
case B_HID_USAGE_PAGE_BUTTON:
|
||||||
{
|
{
|
||||||
if (item->UsageID() - 1 < MAX_BUTTONS)
|
if (item->UsageID() > INT16_MAX)
|
||||||
fButtons[buttonCount++] = item;
|
break;
|
||||||
|
|
||||||
|
HIDReportItem **newButtons = (HIDReportItem **)realloc(fButtons,
|
||||||
|
++fButtonCount * sizeof(HIDReportItem *));
|
||||||
|
if (newButtons == NULL) {
|
||||||
|
fButtonCount--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fButtons = newButtons;
|
||||||
|
fButtons[fButtonCount - 1] = item;
|
||||||
|
|
||||||
|
if (fMaxButton < item->UsageID())
|
||||||
|
fMaxButton = item->UsageID();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,11 +72,24 @@ JoystickProtocolHandler::JoystickProtocolHandler(HIDReport &report)
|
|||||||
case B_HID_UID_GD_RX:
|
case B_HID_UID_GD_RX:
|
||||||
case B_HID_UID_GD_RY:
|
case B_HID_UID_GD_RY:
|
||||||
case B_HID_UID_GD_RZ:
|
case B_HID_UID_GD_RZ:
|
||||||
uint16 axis = item->UsageID() - B_HID_UID_GD_X;
|
uint16 axis = item->UsageID() - B_HID_UID_GD_X + 1;
|
||||||
if (axis >= MAX_AXES)
|
if (axis > INT16_MAX)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
fAxis[axis] = item;
|
if (fAxisCount < axis) {
|
||||||
|
HIDReportItem **newAxis = (HIDReportItem **)realloc(
|
||||||
|
fAxis, axis * sizeof(HIDReportItem *));
|
||||||
|
if (newAxis == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (uint16 i = fAxisCount; i < axis; i++)
|
||||||
|
newAxis[i] = NULL;
|
||||||
|
|
||||||
|
fAxis = newAxis;
|
||||||
|
fAxisCount = axis;
|
||||||
|
}
|
||||||
|
|
||||||
|
fAxis[axis - 1] = item;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,13 +98,20 @@ JoystickProtocolHandler::JoystickProtocolHandler(HIDReport &report)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fButtons[buttonCount] = NULL;
|
|
||||||
|
fCurrentValues.initialize(fAxisCount, 0, fMaxButton);
|
||||||
|
|
||||||
TRACE("joystick device with %lu buttons\n", buttonCount);
|
TRACE("joystick device with %lu buttons\n", buttonCount);
|
||||||
TRACE("report id: %u\n", report.ID());
|
TRACE("report id: %u\n", report.ID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JoystickProtocolHandler::~JoystickProtocolHandler()
|
||||||
|
{
|
||||||
|
free(fCurrentValues.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
JoystickProtocolHandler::AddHandlers(HIDDevice &device,
|
JoystickProtocolHandler::AddHandlers(HIDDevice &device,
|
||||||
HIDCollection &collection, ProtocolHandler *&handlerList)
|
HIDCollection &collection, ProtocolHandler *&handlerList)
|
||||||
@@ -136,6 +173,9 @@ JoystickProtocolHandler::AddHandlers(HIDDevice &device,
|
|||||||
status_t
|
status_t
|
||||||
JoystickProtocolHandler::Open(uint32 flags, uint32 *cookie)
|
JoystickProtocolHandler::Open(uint32 flags, uint32 *cookie)
|
||||||
{
|
{
|
||||||
|
if (fCurrentValues.data == NULL)
|
||||||
|
return B_NO_INIT;
|
||||||
|
|
||||||
status_t result = mutex_lock(&fUpdateLock);
|
status_t result = mutex_lock(&fUpdateLock);
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
@@ -176,7 +216,7 @@ status_t
|
|||||||
JoystickProtocolHandler::Read(uint32 *cookie, off_t position, void *buffer,
|
JoystickProtocolHandler::Read(uint32 *cookie, off_t position, void *buffer,
|
||||||
size_t *numBytes)
|
size_t *numBytes)
|
||||||
{
|
{
|
||||||
if (*numBytes < sizeof(extended_joystick))
|
if (*numBytes < fCurrentValues.data_size)
|
||||||
return B_BUFFER_OVERFLOW;
|
return B_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
// this is a polling interface, we just return the current value
|
// this is a polling interface, we just return the current value
|
||||||
@@ -186,10 +226,10 @@ JoystickProtocolHandler::Read(uint32 *cookie, off_t position, void *buffer,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(buffer, &fCurrentValues, sizeof(extended_joystick));
|
memcpy(buffer, fCurrentValues.data, fCurrentValues.data_size);
|
||||||
mutex_unlock(&fUpdateLock);
|
mutex_unlock(&fUpdateLock);
|
||||||
|
|
||||||
*numBytes = sizeof(extended_joystick);
|
*numBytes = fCurrentValues.data_size;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,27 +253,37 @@ JoystickProtocolHandler::Control(uint32 *cookie, uint32 op, void *buffer,
|
|||||||
if (length < sizeof(joystick_module_info))
|
if (length < sizeof(joystick_module_info))
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
status_t result = mutex_lock(&fUpdateLock);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
fJoystickModuleInfo = *(joystick_module_info *)buffer;
|
fJoystickModuleInfo = *(joystick_module_info *)buffer;
|
||||||
|
|
||||||
fJoystickModuleInfo.num_axes = 0;
|
bool supportsVariable = (fJoystickModuleInfo.flags
|
||||||
for (uint32 i = 0; i < MAX_AXES; i++) {
|
& js_flag_variable_size_reads) != 0;
|
||||||
if (fAxis[i] != NULL)
|
if (!supportsVariable) {
|
||||||
fJoystickModuleInfo.num_axes = i + 1;
|
// We revert to a structure that we can support using only
|
||||||
|
// the data available in an extended_joystick structure.
|
||||||
|
free(fCurrentValues.data);
|
||||||
|
fCurrentValues.initialize_to_extended_joystick();
|
||||||
|
if (fAxisCount > MAX_AXES)
|
||||||
|
fAxisCount = MAX_AXES;
|
||||||
|
if (fHatCount > MAX_HATS)
|
||||||
|
fHatCount = MAX_HATS;
|
||||||
|
if (fMaxButton > MAX_BUTTONS)
|
||||||
|
fMaxButton = MAX_BUTTONS;
|
||||||
|
|
||||||
|
TRACE_ALWAYS("using joystick in extended_joystick mode\n");
|
||||||
|
} else {
|
||||||
|
TRACE_ALWAYS("using joystick in variable mode\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fJoystickModuleInfo.num_buttons = 0;
|
fJoystickModuleInfo.num_axes = fAxisCount;
|
||||||
for (uint32 i = 0; i < MAX_BUTTONS; i++) {
|
fJoystickModuleInfo.num_buttons = fMaxButton;
|
||||||
if (fButtons[i] == NULL)
|
fJoystickModuleInfo.num_hats = fHatCount;
|
||||||
break;
|
|
||||||
|
|
||||||
uint8 button = fButtons[i]->UsageID();
|
|
||||||
if (button > fJoystickModuleInfo.num_buttons)
|
|
||||||
fJoystickModuleInfo.num_buttons = button;
|
|
||||||
}
|
|
||||||
|
|
||||||
fJoystickModuleInfo.num_hats = 0;
|
|
||||||
fJoystickModuleInfo.num_sticks = 1;
|
fJoystickModuleInfo.num_sticks = 1;
|
||||||
fJoystickModuleInfo.config_size = 0;
|
fJoystickModuleInfo.config_size = 0;
|
||||||
|
mutex_unlock(&fUpdateLock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,9 +339,9 @@ JoystickProtocolHandler::_Update()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&fCurrentValues, 0, sizeof(extended_joystick));
|
memset(fCurrentValues.data, 0, fCurrentValues.data_size);
|
||||||
|
|
||||||
for (uint32 i = 0; i < MAX_AXES; i++) {
|
for (uint32 i = 0; i < fAxisCount; i++) {
|
||||||
if (fAxis[i] == NULL)
|
if (fAxis[i] == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -299,21 +349,25 @@ JoystickProtocolHandler::_Update()
|
|||||||
fCurrentValues.axes[i] = (int16)fAxis[i]->ScaledData(16, true);
|
fCurrentValues.axes[i] = (int16)fAxis[i]->ScaledData(16, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32 i = 0; i < MAX_BUTTONS; i++) {
|
for (uint32 i = 0; i < fButtonCount; i++) {
|
||||||
HIDReportItem *button = fButtons[i];
|
HIDReportItem *button = fButtons[i];
|
||||||
if (button == NULL)
|
if (button == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
uint16 index = button->UsageID() - 1;
|
||||||
|
if (index >= fMaxButton)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (button->Extract() == B_OK && button->Valid()) {
|
if (button->Extract() == B_OK && button->Valid()) {
|
||||||
fCurrentValues.buttons
|
fCurrentValues.buttons[index / 32]
|
||||||
|= (button->Data() & 1) << (button->UsageID() - 1);
|
|= (button->Data() & 1) << (index % 32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fReport.DoneProcessing();
|
fReport.DoneProcessing();
|
||||||
TRACE("got joystick report\n");
|
TRACE("got joystick report\n");
|
||||||
|
|
||||||
fCurrentValues.timestamp = system_time();
|
*fCurrentValues.timestamp = system_time();
|
||||||
mutex_unlock(&fUpdateLock);
|
mutex_unlock(&fUpdateLock);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class HIDReportItem;
|
|||||||
class JoystickProtocolHandler : public ProtocolHandler {
|
class JoystickProtocolHandler : public ProtocolHandler {
|
||||||
public:
|
public:
|
||||||
JoystickProtocolHandler(HIDReport &report);
|
JoystickProtocolHandler(HIDReport &report);
|
||||||
|
virtual ~JoystickProtocolHandler();
|
||||||
|
|
||||||
static void AddHandlers(HIDDevice &device,
|
static void AddHandlers(HIDDevice &device,
|
||||||
HIDCollection &collection,
|
HIDCollection &collection,
|
||||||
@@ -43,12 +44,17 @@ private:
|
|||||||
|
|
||||||
HIDReport & fReport;
|
HIDReport & fReport;
|
||||||
|
|
||||||
HIDReportItem * fAxis[MAX_AXES];
|
uint32 fAxisCount;
|
||||||
HIDReportItem * fButtons[MAX_BUTTONS];
|
HIDReportItem ** fAxis;
|
||||||
|
uint32 fHatCount;
|
||||||
|
HIDReportItem ** fHats;
|
||||||
|
uint32 fButtonCount;
|
||||||
|
uint32 fMaxButton;
|
||||||
|
HIDReportItem ** fButtons;
|
||||||
|
|
||||||
joystick_module_info fJoystickModuleInfo;
|
joystick_module_info fJoystickModuleInfo;
|
||||||
|
variable_joystick fCurrentValues;
|
||||||
|
|
||||||
extended_joystick fCurrentValues;
|
|
||||||
mutex fUpdateLock;
|
mutex fUpdateLock;
|
||||||
thread_id fUpdateThread;
|
thread_id fUpdateThread;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user