summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2022-12-27 15:27:29 +0200
committerakleshchev <117672381+akleshchev@users.noreply.github.com>2023-10-23 15:26:19 +0300
commit6481d36c69dbcafdb23cb27dc07aa047b3d7d64e (patch)
tree151cb083c15cd9ddb6107abbbdf5e228fcd3fdac
parent453a4a13f87d5cbfa6150a4f76f9e976692b54e6 (diff)
SL-13610 [MAC] WIP filter out incompatible devices
-rw-r--r--indra/llwindow/llwindowmacosx.cpp95
-rw-r--r--indra/newview/llviewerjoystick.cpp2
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;