diff options
| author | Andrey Kleshchev <andreykproductengine@lindenlab.com> | 2022-12-27 15:27:29 +0200 | 
|---|---|---|
| committer | akleshchev <117672381+akleshchev@users.noreply.github.com> | 2023-10-23 15:26:19 +0300 | 
| commit | 6481d36c69dbcafdb23cb27dc07aa047b3d7d64e (patch) | |
| tree | 151cb083c15cd9ddb6107abbbdf5e228fcd3fdac | |
| parent | 453a4a13f87d5cbfa6150a4f76f9e976692b54e6 (diff) | |
SL-13610 [MAC] WIP filter out incompatible devices
| -rw-r--r-- | indra/llwindow/llwindowmacosx.cpp | 95 | ||||
| -rw-r--r-- | indra/newview/llviewerjoystick.cpp | 2 | 
2 files changed, 89 insertions, 8 deletions
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 914e590ae9..3cb5939dc9 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1862,11 +1862,13 @@ struct hu_element_t  };  struct HidDevice -{                    // interface to device, NULL = no interface -    char mProduct[256];                        // name of product -    long mlocalID;                                // long representing location in USB( or other I/O ) chain which device is pluged into, can identify specific device on machine -    long mUsage;                                // usage page from IOUSBHID Parser.h which defines general usage -    long mUsagePage;                            // usage within above page from IOUSBHID Parser.h which defines specific usage +{ +    long mAxis; +    long mLocalID; +    char mProduct[256]; +    char mManufacturer[256]; +    long mUsage; +    long mUsagePage;  };  /************************************************************************* @@ -1931,6 +1933,20 @@ static void populate_device_info( io_object_t io_obj_p, CFDictionaryRef device_d                  }              } +            dict_element = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDManufacturerKey ) ); +            if ( !dict_element ) +            { +                dict_element = CFDictionaryGetValue( io_properties, CFSTR( "USB Vendor Name" ) ); +            } +            if ( dict_element ) +            { +                bool res = CFStringGetCString( (CFStringRef)dict_element, devicep->mManufacturer, 256, kCFStringEncodingUTF8 ); +                if ( !res ) +                { +                    LL_WARNS("Joystick") << "Failed to populate mManufacturer" << LL_ENDL; +                } +            } +                          dict_element = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDLocationIDKey ) );              if ( !dict_element )              { @@ -1938,7 +1954,7 @@ static void populate_device_info( io_object_t io_obj_p, CFDictionaryRef device_d              }              if ( dict_element )              { -                bool res = CFNumberGetValue( (CFNumberRef)dict_element, kCFNumberLongType, &devicep->mlocalID ); +                bool res = CFNumberGetValue( (CFNumberRef)dict_element, kCFNumberLongType, &devicep->mLocalID );                  if ( !res )                  {                      LL_WARNS("Joystick") << "Failed to populate mLocalID" << LL_ENDL; @@ -1962,6 +1978,59 @@ static void populate_device_info( io_object_t io_obj_p, CFDictionaryRef device_d                      }                  }              } +             +            //Add axis, because ndof lib checks sutability by axises as well as other elements +            devicep->mAxis = 0; +            CFTypeRef hid_elements = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDElementKey ) ); +            if ( hid_elements && CFGetTypeID( hid_elements ) == CFArrayGetTypeID( ) ) +            { +                long count = CFArrayGetCount( (CFArrayRef) hid_elements ); +                for (int i = 0; i < count; ++i) +                { +                    CFTypeRef element = CFArrayGetValueAtIndex((CFArrayRef) hid_elements, i); +                    if (element && CFGetTypeID( element ) == CFDictionaryGetTypeID( )) +                    { +                        long type = 0, usage_page = 0, usage = 0; +                         +                        CFTypeRef ref_value = CFDictionaryGetValue( (CFDictionaryRef) element, CFSTR( kIOHIDElementTypeKey ) ); +                        if ( ref_value ) +                        { +                            CFNumberGetValue( (CFNumberRef)ref_value, kCFNumberLongType, &type ); +                        } +                         +                        ref_value = CFDictionaryGetValue( (CFDictionaryRef) element, CFSTR( kIOHIDElementUsagePageKey ) ); +                        if ( ref_value ) +                        { +                             CFNumberGetValue( (CFNumberRef)ref_value, kCFNumberLongType, &usage_page ); +                        } +                         +                        ref_value = CFDictionaryGetValue( (CFDictionaryRef) element, CFSTR( kIOHIDElementUsageKey ) ); +                        if ( ref_value ) +                        { +                            CFNumberGetValue( (CFNumberRef)ref_value, kCFNumberLongType, &usage ); +                        } +                        if ( type != 0 +                            && type != kIOHIDElementTypeCollection +                            && usage_page == kHIDPage_GenericDesktop) +                        { +                            switch( usage ) +                            { +                                case kHIDUsage_GD_X: +                                case kHIDUsage_GD_Y: +                                case kHIDUsage_GD_Z: +                                case kHIDUsage_GD_Rx: +                                case kHIDUsage_GD_Ry: +                                case kHIDUsage_GD_Rz: +                                    devicep->mAxis++; +                                    break; +                                default: +                                    break; +                            } +                        } +                    } +                } +            } +                          CFRelease(io_properties);          }          else @@ -2046,7 +2115,17 @@ static void get_devices(std::list<HidDevice> &list_of_devices,      {          HidDevice device = populate_device( io_obj ); -        list_of_devices.push_back(device); +        if (device.mAxis >= 3 +            || (device.mUsagePage == kHIDPage_GenericDesktop +                && (device.mUsage == kHIDUsage_GD_MultiAxisController +                    || device.mUsage == kHIDUsage_GD_GamePad +                    || device.mUsage == kHIDUsage_GD_Joystick)) +            || (device.mUsagePage == kHIDPage_Game +                && (device.mUsage == kHIDUsage_Game_3DGameController)) +            || strstr(device.mManufacturer, "3Dconnexion")) +        { +            list_of_devices.push_back(device); +        }          // release the device object, it is no longer needed          result = IOObjectRelease( io_obj ); @@ -2096,7 +2175,7 @@ bool LLWindowMacOSX::getInputDevices(U32 device_type_filter,              S32 size = sizeof(long);              LLSD::Binary data; //just an std::vector              data.resize(size); -            memcpy(&data[0], &iter->mlocalID, size); +            memcpy(&data[0], &iter->mLocalID, size);              std::string label(iter->mProduct);              if (osx_callback(label, data, userdata)) diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index e182b31ed2..95cfa5cd78 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -399,6 +399,7 @@ void LLViewerJoystick::init(bool autoenable)                  long id;                  memcpy(&id, &mLastDeviceUUID[0], size); +                // todo: search by manufcturer instead, locid might have changed                  NDOF_Device *device = ndof_idsearch(id);                  if (device)                  { @@ -500,6 +501,7 @@ void LLViewerJoystick::initDevice(LLSD &guid)          NDOF_Device *device = ndof_idsearch(id);          if (device)          { +            // todo: search by manufcturer instead, locid might have changed              if (ndof_init_first(device, nullptr))              {                  mDriverState = JDS_INITIALIZING;  | 
