[haiku-commits] r41885 - in haiku/trunk: headers/os/device headers/private/device src/kits/device

  • From: mmlr@xxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 3 Jun 2011 20:33:45 +0200 (CEST)

Author: mmlr
Date: 2011-06-03 20:33:43 +0200 (Fri, 03 Jun 2011)
New Revision: 41885
Changeset: https://dev.haiku-os.org/changeset/41885

Added:
   haiku/trunk/headers/private/device/JoystickPrivate.h
Modified:
   haiku/trunk/headers/os/device/Joystick.h
   haiku/trunk/headers/private/device/joystick_driver.h
   haiku/trunk/src/kits/device/Joystick.cpp
Log:
* Replace the fixed size extended_joystick structure with a variably sized one
  inside BJoystick.
* Add joystick_module_info flag to communicate support for variably sized reads.
* The variably sized data structure is set up to describe either the actual
  amount of data, when variably sized reads are supported by the driver, or it
  is set up so that it exactly matches the data layout of the extended_joystick
  structure. This allows us to support both as input data, while only needing to
  care about a single format inside BJoystick. Convenience pointers allow the
  data to be retrieved without additional overhead or extra logic.
* Add some sanity checks and ensure some boundaries when dealing reading data
  from the variably sized structure (as there might not be any buttons, hats,
  axis at all now).
* Ensure that the extended_joystick structure doesn't change in size due to
  padding by making it _PACKED (it wasn't padded though).

This is still supposed to work exactly as before. However, it opens up the
possibility to actually support arbitrary controllers with arbitrary axis, hat
and button counts. It therefore allows to actually deliver what the BJoystick
API was designed to handle all along.


Modified: haiku/trunk/headers/os/device/Joystick.h
===================================================================
--- haiku/trunk/headers/os/device/Joystick.h    2011-06-03 17:44:07 UTC (rev 
41884)
+++ haiku/trunk/headers/os/device/Joystick.h    2011-06-03 18:33:43 UTC (rev 
41885)
@@ -103,7 +103,8 @@
                        int                             fFD;
                        BList*                  fDevices;
                        _joystick_info* fJoystickInfo;
-                       BList*                  fExtendedJoystick;
+                       BList*                  fJoystickData;
+
                        uint32          _reserved_Joystick_[10];
 };
 

Added: haiku/trunk/headers/private/device/JoystickPrivate.h
===================================================================
--- haiku/trunk/headers/private/device/JoystickPrivate.h                        
        (rev 0)
+++ haiku/trunk/headers/private/device/JoystickPrivate.h        2011-06-03 
18:33:43 UTC (rev 41885)
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2011 Michael Lotz <mmlr@xxxxxxxx>
+ * Distributed under the terms of the MIT license.
+ */
+#ifndef _JOYSTICK_PRIVATE_H
+#define _JOYSTICK_PRIVATE_H
+
+#include <SupportDefs.h>
+
+typedef struct _variable_joystick {
+       uint32          axis_count;
+       uint32          hat_count;
+       uint32          button_blocks;
+
+       // these pointers all point into the data section
+       bigtime_t *     timestamp;
+       uint32 *        buttons;
+       int16 *         axes;
+       uint8 *         hats;
+
+       size_t          data_size;
+       uint8 *         data;
+} variable_joystick;
+
+#endif // _JOYSTICK_PRIVATE_H

Modified: haiku/trunk/headers/private/device/joystick_driver.h
===================================================================
--- haiku/trunk/headers/private/device/joystick_driver.h        2011-06-03 
17:44:07 UTC (rev 41884)
+++ haiku/trunk/headers/private/device/joystick_driver.h        2011-06-03 
18:33:43 UTC (rev 41885)
@@ -39,13 +39,14 @@
        uint32          buttons;                /* lsb to msb, 1 == on */
        int16           axes[MAX_AXES]; /* -32768 to 32767, X, Y, Z, U, V, W */
        uint8           hats[MAX_HATS]; /* 0 through 8 (1 == N, 3 == E, 5 == S, 
7 == W) */
-} extended_joystick;
+} _PACKED extended_joystick;
 
 #define MAX_CONFIG_SIZE 100
 
 enum { /* flags for joystick module info */
        js_flag_force_feedback = 0x1,
-       js_flag_force_feedback_directional = 0x2
+       js_flag_force_feedback_directional = 0x2,
+       js_flag_variable_size_reads = 0x4
 };
 
 typedef struct _joystick_module_info {

Modified: haiku/trunk/src/kits/device/Joystick.cpp
===================================================================
--- haiku/trunk/src/kits/device/Joystick.cpp    2011-06-03 17:44:07 UTC (rev 
41884)
+++ haiku/trunk/src/kits/device/Joystick.cpp    2011-06-03 18:33:43 UTC (rev 
41885)
@@ -6,6 +6,7 @@
 
 
 #include <Joystick.h>
+#include <JoystickPrivate.h>
 #include <JoystickTweaker.h>
 
 #include <new>
@@ -56,7 +57,7 @@
        fFD(-1),
        fDevices(new(std::nothrow) BList),
        fJoystickInfo(new(std::nothrow) joystick_info),
-       fExtendedJoystick(new(std::nothrow) BList)
+       fJoystickData(new(std::nothrow) BList)
 {
 #if DEBUG
        sLogFile = fopen("/var/log/joystick.log", "a");
@@ -83,11 +84,18 @@
 
        delete fJoystickInfo;
 
-       if (fExtendedJoystick != NULL) {
-               for (int32 i = 0; i < fExtendedJoystick->CountItems(); i++)
-                       delete (extended_joystick 
*)fExtendedJoystick->ItemAt(i);
+       if (fJoystickData != NULL) {
+               for (int32 i = 0; i < fJoystickData->CountItems(); i++) {
+                       variable_joystick *variableJoystick
+                               = (variable_joystick *)fJoystickData->ItemAt(i);
+                       if (variableJoystick == NULL)
+                               continue;
 
-               delete fExtendedJoystick;
+                       free(variableJoystick->data);
+                       delete variableJoystick;
+               }
+
+               delete fJoystickData;
        }
 }
 
@@ -108,7 +116,7 @@
        if (portName == NULL)
                return B_BAD_VALUE;
 
-       if (fJoystickInfo == NULL || fExtendedJoystick == NULL)
+       if (fJoystickInfo == NULL || fJoystickData == NULL)
                return B_NO_INIT;
 
        fBeBoxMode = !enhanced;
@@ -141,23 +149,70 @@
                sizeof(joystick_module_info));
        LOG("ioctl - %d\n", fJoystickInfo->module_info.num_buttons);
 
-       // Allocate the extended_joystick structures to hold the info for each
+       // Allocate the variable_joystick structures to hold the info for each
        // "stick". Note that the whole num_sticks thing seems a bit bogus, as
        // all sticks would be required to have exactly the same attributes,
        // i.e. axis, hat and button counts, since there is only one global
        // joystick_info for the whole device. What's implemented here is a
        // "best guess", using the read position in Update() to select the
-       // stick for which an extended_joystick structure shall be returned.
+       // stick for which data shall be returned.
+       bool supportsVariable
+               = (fJoystickInfo->module_info.flags & 
js_flag_variable_size_reads) != 0;
        for (uint16 i = 0; i < fJoystickInfo->module_info.num_sticks; i++) {
-               extended_joystick *extendedJoystick
-                       = new(std::nothrow) extended_joystick;
-               if (extendedJoystick == NULL)
+               variable_joystick *variableJoystick
+                       = new(std::nothrow) variable_joystick;
+               if (variableJoystick == NULL)
                        return B_NO_MEMORY;
 
-               if (!fExtendedJoystick->AddItem(extendedJoystick)) {
-                       delete extendedJoystick;
+               if (supportsVariable) {
+                       // The driver supports arbitrary controls.
+                       variableJoystick->axis_count = 
fJoystickInfo->module_info.num_axes;
+                       variableJoystick->hat_count = 
fJoystickInfo->module_info.num_hats;
+                       variableJoystick->button_blocks
+                               = (fJoystickInfo->module_info.num_buttons + 31) 
/ 32;
+               } else {
+                       // The driver doesn't support our variable requests so 
we construct
+                       // a data structure that is compatible with 
extended_joystick and
+                       // just use that in reads. This allows us to use a 
single data
+                       // format internally but be compatible with both inputs.
+                       variableJoystick->axis_count = MAX_AXES;
+                       variableJoystick->hat_count = MAX_HATS;
+                       variableJoystick->button_blocks = (MAX_BUTTONS + 31) / 
32;
+
+                       // Also ensure that we don't read over those boundaries.
+                       if (fJoystickInfo->module_info.num_axes > MAX_AXES)
+                               fJoystickInfo->module_info.num_axes = MAX_AXES;
+                       if (fJoystickInfo->module_info.num_hats > MAX_HATS)
+                               fJoystickInfo->module_info.num_hats = MAX_HATS;
+                       if (fJoystickInfo->module_info.num_buttons > 
MAX_BUTTONS)
+                               fJoystickInfo->module_info.num_buttons = 
MAX_BUTTONS;
+               }
+
+               variableJoystick->data_size = sizeof(bigtime_t)                 
// timestamp
+                       + variableJoystick->button_blocks * sizeof(uint32)      
// bitmaps
+                       + variableJoystick->axis_count * sizeof(int16)          
// axis values
+                       + variableJoystick->hat_count * sizeof(uint8);          
// hat values
+
+               variableJoystick->data
+                       = (uint8 *)malloc(variableJoystick->data_size);
+               if (variableJoystick->data == NULL) {
+                       delete variableJoystick;
                        return B_NO_MEMORY;
                }
+
+               // fill in the convenience pointers
+               variableJoystick->timestamp = (bigtime_t 
*)variableJoystick->data;
+               variableJoystick->buttons = (uint32 
*)(&variableJoystick->timestamp[1]);
+               variableJoystick->axes = (int16 *)(&variableJoystick->buttons[
+                       variableJoystick->button_blocks]);
+               variableJoystick->hats = (uint8 *)(&variableJoystick->axes[
+                       variableJoystick->axis_count]);
+
+               if (!fJoystickData->AddItem(variableJoystick)) {
+                       free(variableJoystick->data);
+                       delete variableJoystick;
+                       return B_NO_MEMORY;
+               }
        }
 
        return fFD;
@@ -179,32 +234,46 @@
 BJoystick::Update()
 {
        CALLED();
-       if (fJoystickInfo == NULL || fExtendedJoystick == NULL || fFD < 0)
+       if (fJoystickInfo == NULL || fJoystickData == NULL || fFD < 0)
                return B_NO_INIT;
 
        for (uint16 i = 0; i < fJoystickInfo->module_info.num_sticks; i++) {
-               extended_joystick *extendedJoystick
-                       = (extended_joystick *)fExtendedJoystick->ItemAt(i);
-               if (extendedJoystick == NULL)
+               variable_joystick *values
+                       = (variable_joystick *)fJoystickData->ItemAt(i);
+               if (values == NULL)
                        return B_NO_INIT;
 
-               ssize_t result = read_pos(fFD, i, extendedJoystick,
-                       sizeof(extended_joystick));
+               ssize_t result = read_pos(fFD, i, values->data,
+                       values->data_size);
                if (result < 0)
                        return result;
 
-               if (result != sizeof(extended_joystick))
+               if ((size_t)result != values->data_size)
                        return B_ERROR;
 
                if (i > 0)
                        continue;
 
                // fill in the legacy values for the first stick
-               timestamp = extendedJoystick->timestamp;
-               horizontal = extendedJoystick->axes[0];
-               vertical = extendedJoystick->axes[1];
-               button1 = (extendedJoystick->buttons & 1) == 0;
-               button2 = (extendedJoystick->buttons & 2) == 0;
+               timestamp = *values->timestamp;
+
+               if (values->axis_count >= 1)
+                       horizontal = values->axes[0];
+               else
+                       horizontal = 0;
+
+               if (values->axis_count >= 2)
+                       vertical = values->axes[1];
+               else
+                       vertical = 0;
+
+               if (values->button_blocks > 0) {
+                       button1 = (*values->buttons & 1) == 0;
+                       button2 = (*values->buttons & 2) == 0;
+               } else {
+                       button1 = true;
+                       button2 = true;
+               }
        }
 
        return B_OK;
@@ -314,19 +383,19 @@
 {
        CALLED();
 
-       if (fJoystickInfo == NULL || fExtendedJoystick == NULL)
+       if (fJoystickInfo == NULL || fJoystickData == NULL)
                return B_NO_INIT;
 
        if (forStick < 0
                || forStick >= (int32)fJoystickInfo->module_info.num_sticks)
                return B_BAD_INDEX;
 
-       extended_joystick *extendedJoystick
-               = (extended_joystick *)fExtendedJoystick->ItemAt(forStick);
-       if (extendedJoystick == NULL)
+       variable_joystick *variableJoystick
+               = (variable_joystick *)fJoystickData->ItemAt(forStick);
+       if (variableJoystick == NULL)
                return B_NO_INIT;
 
-       memcpy(outValues, extendedJoystick->axes,
+       memcpy(outValues, variableJoystick->axes,
                fJoystickInfo->module_info.num_axes * sizeof(uint16));
        return B_OK;
 }
@@ -366,19 +435,19 @@
 {
        CALLED();
 
-       if (fJoystickInfo == NULL || fExtendedJoystick == NULL)
+       if (fJoystickInfo == NULL || fJoystickData == NULL)
                return B_NO_INIT;
 
        if (forStick < 0
                || forStick >= (int32)fJoystickInfo->module_info.num_sticks)
                return B_BAD_INDEX;
 
-       extended_joystick *extendedJoystick
-               = (extended_joystick *)fExtendedJoystick->ItemAt(forStick);
-       if (extendedJoystick == NULL)
+       variable_joystick *variableJoystick
+               = (variable_joystick *)fJoystickData->ItemAt(forStick);
+       if (variableJoystick == NULL)
                return B_NO_INIT;
 
-       memcpy(outHats, extendedJoystick->hats,
+       memcpy(outHats, variableJoystick->hats,
                fJoystickInfo->module_info.num_hats);
        return B_OK;
 }
@@ -418,19 +487,19 @@
 {
        CALLED();
 
-       if (fJoystickInfo == NULL || fExtendedJoystick == NULL)
+       if (fJoystickInfo == NULL || fJoystickData == NULL)
                return 0;
 
        if (forStick < 0
                || forStick >= (int32)fJoystickInfo->module_info.num_sticks)
                return 0;
 
-       extended_joystick *extendedJoystick
-               = (extended_joystick *)fExtendedJoystick->ItemAt(forStick);
-       if (extendedJoystick == NULL)
+       variable_joystick *variableJoystick
+               = (variable_joystick *)fJoystickData->ItemAt(forStick);
+       if (variableJoystick == NULL || variableJoystick->button_blocks == 0)
                return 0;
 
-       return extendedJoystick->buttons;
+       return *variableJoystick->buttons;
 }
 
 
@@ -439,24 +508,22 @@
 {
        CALLED();
 
-       if (fJoystickInfo == NULL || fExtendedJoystick == NULL)
+       if (fJoystickInfo == NULL || fJoystickData == NULL)
                return B_NO_INIT;
 
        if (forStick < 0
                || forStick >= (int32)fJoystickInfo->module_info.num_sticks)
                return B_BAD_INDEX;
 
-       extended_joystick *extendedJoystick
-               = (extended_joystick *)fExtendedJoystick->ItemAt(forStick);
-       if (extendedJoystick == NULL)
+       variable_joystick *variableJoystick
+               = (variable_joystick *)fJoystickData->ItemAt(forStick);
+       if (variableJoystick == NULL)
                return B_NO_INIT;
 
        int16 buttonCount = fJoystickInfo->module_info.num_buttons;
        for (int16 i = 0; i < buttonCount; i++) {
-               if (buttonCount >= 32)
-                       outButtons[i] = false;
-               else
-                       outButtons[i] = (extendedJoystick->buttons & (1 << i)) 
!= 0;
+               outButtons[i]
+                       = (variableJoystick->buttons[i / 32] & (1 << (i % 32))) 
!= 0;
        }
 
        return B_OK;


Other related posts:

  • » [haiku-commits] r41885 - in haiku/trunk: headers/os/device headers/private/device src/kits/device - mmlr