summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2022-12-14 19:41:07 +0200
committerakleshchev <117672381+akleshchev@users.noreply.github.com>2023-10-23 15:26:19 +0300
commit9b27b6e5098aee7a050d4c3f3f14050c509f74ec (patch)
tree93863e039186d271d3a91247f8e2abf2b8d15125
parent702e4c7dc1a383f83a0324e97b087efef82e9248 (diff)
SL-13610 [MAC] WIP List HID available devices in joystick selection
Doesn't filter the list yet, just shows full list of usb devices Selecting visible devices doesn't work yet
-rw-r--r--indra/llui/lltransutil.cpp4
-rw-r--r--indra/llwindow/llwindow.h8
-rw-r--r--indra/llwindow/llwindowmacosx-objc.mm1
-rw-r--r--indra/llwindow/llwindowmacosx.cpp315
-rw-r--r--indra/llwindow/llwindowmacosx.h5
-rw-r--r--indra/llwindow/llwindowwin32.cpp5
-rw-r--r--indra/llwindow/llwindowwin32.h5
-rw-r--r--indra/llxml/llxmlnode.cpp2
-rw-r--r--indra/newview/llfilepicker.cpp6
-rw-r--r--indra/newview/llfloaterjoystick.cpp14
-rw-r--r--indra/newview/llfloaterjoystick.h1
-rw-r--r--indra/newview/llviewerjoystick.cpp25
-rw-r--r--indra/newview/llviewerjoystick.h6
-rw-r--r--indra/newview/skins/default/xui/en/floater_about_land.xml12
14 files changed, 384 insertions, 25 deletions
diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp
index 5da722a72b..ecd065a4ef 100644
--- a/indra/llui/lltransutil.cpp
+++ b/indra/llui/lltransutil.cpp
@@ -44,8 +44,8 @@ bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<s
bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root, LLDir::ALL_SKINS);
if (!success)
{
- gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
- LL_ERRS() << "Couldn't load string table " << xml_filename << ". Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
+ //gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
+ LL_ERRS() << "Couldn't load string table " << xml_filename << " " << errno << ". Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
return false;
}
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index ac4848579f..2d27092e0a 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -196,7 +196,13 @@ public:
// windows only DirectInput8 for joysticks
virtual void* getDirectInput8() { return NULL; };
- virtual bool getInputDevices(U32 device_type_filter, void * devices_callback, void* userdata) { return false; };
+ virtual bool getInputDevices(U32 device_type_filter,
+ std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback,
+ void* win_callback,
+ void* userdata)
+ {
+ return false;
+ };
virtual S32 getRefreshRate() { return mRefreshRate; }
protected:
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 690fe058db..2e75d309ea 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -27,6 +27,7 @@
#include <AppKit/AppKit.h>
#include <Cocoa/Cocoa.h>
+#include <errno.h>
#include "llopenglview-objc.h"
#include "llwindowmacosx-objc.h"
#include "llappdelegate-objc.h"
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 2c841d4703..bd13138a7d 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -43,6 +43,13 @@
#include <CoreServices/CoreServices.h>
#include <CoreGraphics/CGDisplayConfiguration.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOMessage.h>
+#include <IOKit/hid/IOHIDUsageTables.h>
+#include <IOKit/hid/IOHIDLib.h>
+#include <IOKit/usb/IOUSBLib.h>
+
extern BOOL gDebugWindowProc;
BOOL gHiDPISupport = TRUE;
@@ -212,13 +219,16 @@ bool callKeyUp(NSKeyEventRef event, unsigned short key, unsigned int mask)
bool callKeyDown(NSKeyEventRef event, unsigned short key, unsigned int mask, wchar_t character)
{
- if((key == gKeyboard->inverseTranslateKey('Z')) && (character == 'y'))
- {
- key = gKeyboard->inverseTranslateKey('Y');
- }
- else if ((key == gKeyboard->inverseTranslateKey('Y')) && (character == 'z'))
+ //if (mask!=MASK_NONE)
{
- key = gKeyboard->inverseTranslateKey('Z');
+ if((key == gKeyboard->inverseTranslateKey('Z')) && (character == 'y'))
+ {
+ key = gKeyboard->inverseTranslateKey('Y');
+ }
+ else if ((key == gKeyboard->inverseTranslateKey('Y')) && (character == 'z'))
+ {
+ key = gKeyboard->inverseTranslateKey('Z');
+ }
}
mRawKeyEvent = event;
@@ -1803,6 +1813,299 @@ void LLWindowMacOSX::spawnWebBrowser(const std::string& escaped_url, bool async)
}
}
+
+// Device and Element Interfaces
+
+typedef enum HIDElementTypeMask
+{
+ kHIDElementTypeInput = 1 << 1,
+ kHIDElementTypeOutput = 1 << 2,
+ kHIDElementTypeFeature = 1 << 3,
+ kHIDElementTypeCollection = 1 << 4,
+ kHIDElementTypeIO = kHIDElementTypeInput | kHIDElementTypeOutput | kHIDElementTypeFeature,
+ kHIDElementTypeAll = kHIDElementTypeIO | kHIDElementTypeCollection
+}HIDElementTypeMask;
+
+struct hu_element_t
+{
+ unsigned long type; // the type defined by IOHIDElementType in IOHIDKeys.h
+ long usage; // usage within above page from IOUSBHIDParser.h which defines specific usage
+ long usagePage; // usage page from IOUSBHIDParser.h which defines general usage
+ void* cookie; // unique value( within device of specific vendorID and productID ) which identifies element, will NOT change
+ long min; // reported min value possible
+ long max; // reported max value possible
+ long scaledMin; // reported scaled min value possible
+ long scaledMax; // reported scaled max value possible
+ long size; // size in bits of data return from element
+ unsigned char relative; // are reports relative to last report( deltas )
+ unsigned char wrapping; // does element wrap around( one value higher than max is min )
+ unsigned char nonLinear; // are the values reported non-linear relative to element movement
+ unsigned char preferredState; // does element have a preferred state( such as a button )
+ unsigned char nullState; // does element have null state
+ long units; // units value is reported in( not used very often )
+ long unitExp; // exponent for units( also not used very often )
+ char name[256]; // name of element( c string )
+
+ // runtime variables
+ long initialCenter; // center value at start up
+ unsigned char hasCenter; // whether or not to use center for calibration
+ long minReport; // min returned value
+ long maxReport; // max returned value( calibrate call )
+ long userMin; // user set value to scale to( scale call )
+ long userMax;
+
+ struct hu_element_t* pPrevious; // previous element( NULL at list head )
+ struct hu_element_t* pChild; // next child( only of collections )
+ struct hu_element_t* pSibling; // next sibling( for elements and collections )
+
+ long depth;
+};
+
+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
+};
+
+/*************************************************************************
+*
+* hu_BuildDevice( inHIDDevice )
+*
+* Purpose: given a IO device object build a flat device record including device info and all elements
+*
+* Notes: handles NULL lists properly
+*
+* Inputs: inHIDDevice - the I/O device object
+*
+* Returns: hu_device_t* - the address of the new device record
+*/
+
+
+static void populate_device_info( io_object_t io_obj_p, CFDictionaryRef device_dic, HidDevice* devicep )
+{
+ CFMutableDictionaryRef io_properties = nil;
+ io_registry_entry_t entry1;
+ io_registry_entry_t entry2;
+ kern_return_t rc;
+
+ // Mac OS X currently is not mirroring all USB properties to HID page so need to look at USB device page also
+ // get dictionary for usb properties: step up two levels and get CF dictionary for USB properties
+ // try to get parent1
+ rc = IORegistryEntryGetParentEntry( io_obj_p, kIOServicePlane, &entry1 );
+ if ( KERN_SUCCESS == rc )
+ {
+ rc = IORegistryEntryGetParentEntry( entry1, kIOServicePlane, &entry2 );
+
+ IOObjectRelease( entry1 );
+
+ if ( KERN_SUCCESS == rc )
+ {
+ rc = IORegistryEntryCreateCFProperties( entry2, &io_properties, kCFAllocatorDefault, kNilOptions );
+ // either way, release parent2
+ IOObjectRelease( entry2 );
+ }
+ }
+ if ( KERN_SUCCESS == rc )
+ {
+ // IORegistryEntryCreateCFProperties() succeeded
+ if ( io_properties != nil )
+ {
+ CFTypeRef dict_element = 0;
+ // get device info
+ // try hid dictionary first, if fail then go to usb dictionary
+
+
+ dict_element = CFDictionaryGetValue( device_dic, CFSTR(kIOHIDProductKey) );
+ if ( !dict_element )
+ {
+ dict_element = CFDictionaryGetValue( io_properties, CFSTR( "USB Product Name" ) );
+ }
+ if ( dict_element )
+ {
+ bool res = CFStringGetCString((CFStringRef)dict_element, devicep->mProduct, 256, kCFStringEncodingUTF8);
+ if ( !res )
+ {
+ LL_WARNS("Joystick") << "Failed to populate mProduct" << LL_ENDL;
+ }
+ }
+
+ dict_element = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDLocationIDKey ) );
+ if ( !dict_element )
+ {
+ dict_element = CFDictionaryGetValue( io_properties, CFSTR( "locationID" ) );
+ }
+ if ( dict_element )
+ {
+ bool res = CFNumberGetValue( (CFNumberRef)dict_element, kCFNumberLongType, &devicep->mlocalID );
+ if ( !res )
+ {
+ LL_WARNS("Joystick") << "Failed to populate mLocalID" << LL_ENDL;
+ }
+ }
+
+ dict_element = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDPrimaryUsagePageKey ) );
+ if ( dict_element )
+ {
+ bool res = CFNumberGetValue( (CFNumberRef)dict_element, kCFNumberLongType, &devicep->mUsagePage );
+ if ( !res )
+ {
+ LL_WARNS("Joystick") << "Failed to populate mUsagePage" << LL_ENDL;
+ }
+ dict_element = CFDictionaryGetValue( device_dic, CFSTR( kIOHIDPrimaryUsageKey ) );
+ if ( dict_element )
+ {
+ if ( !CFNumberGetValue( (CFNumberRef)dict_element, kCFNumberLongType, &devicep->mUsage ) )
+ {
+ LL_WARNS("Joystick") << "Failed to populate mUsage" << LL_ENDL;
+ }
+ }
+ }
+ CFRelease(io_properties);
+ }
+ else
+ {
+ LL_WARNS("Joystick") << "Failed to populate fields" << LL_ENDL;
+ }
+ }
+}
+
+HidDevice populate_device( io_object_t io_obj )
+{
+ void* interfacep = nullptr;
+ HidDevice device;
+ memset( &device, 0, sizeof( HidDevice ) );
+ CFMutableDictionaryRef device_dic = 0;
+ kern_return_t result = IORegistryEntryCreateCFProperties( io_obj, &device_dic, kCFAllocatorDefault, kNilOptions );
+
+ if ( KERN_SUCCESS == result
+ && device_dic )
+ {
+ IOReturn io_result = kIOReturnSuccess;
+ HRESULT query_result = S_OK;
+ SInt32 the_score = 0;
+ IOCFPlugInInterface **the_interface = NULL;
+
+
+ io_result = IOCreatePlugInInterfaceForService( io_obj, kIOHIDDeviceUserClientTypeID,
+ kIOCFPlugInInterfaceID, &the_interface, &the_score );
+ if ( io_result == kIOReturnSuccess )
+ {
+ query_result = ( *the_interface )->QueryInterface( the_interface, CFUUIDGetUUIDBytes( kIOHIDDeviceInterfaceID ), ( LPVOID * ) & ( interfacep ) );
+ if ( query_result != S_OK )
+ {
+ LL_WARNS("Joystick") << "QueryInterface failed" << LL_ENDL;
+ }
+ IODestroyPlugInInterface( the_interface );
+ }
+ else
+ {
+ LL_WARNS("Joystick") << "IOCreatePlugInInterfaceForService failed" << LL_ENDL;
+ }
+
+ if ( interfacep )
+ {
+ result = ( *( IOHIDDeviceInterface** )interfacep )->open( interfacep, 0 );
+
+ if ( result != kIOReturnSuccess)
+ {
+ LL_WARNS("Joystick") << "open failed" << LL_ENDL;
+ }
+ }
+ // extract needed fields
+ populate_device_info( io_obj, device_dic, &device );
+
+ // Release interface
+ if ( interfacep )
+ {
+ ( *( IOHIDDeviceInterface** ) interfacep )->close( interfacep );
+
+ ( *( IOHIDDeviceInterface** ) interfacep )->Release( interfacep );
+
+ interfacep = NULL;
+ }
+
+ CFRelease( device_dic );
+ }
+ else
+ {
+ LL_WARNS("Joystick") << "populate_device failed" << LL_ENDL;
+ }
+
+ return device;
+}
+
+static void get_devices(std::list<HidDevice> &list_of_devices,
+ io_iterator_t inIODeviceIterator)
+{
+ IOReturn result = kIOReturnSuccess; // assume success( optimist! )
+ io_object_t io_obj = 0;
+
+ while ( 0 != (io_obj = IOIteratorNext( inIODeviceIterator ) ) )
+ {
+ HidDevice device = populate_device( io_obj );
+
+ list_of_devices.push_back(device);
+
+ // release the device object, it is no longer needed
+ result = IOObjectRelease( io_obj );
+ if ( KERN_SUCCESS != result )
+ {
+ LL_WARNS("Joystick") << "IOObjectRelease failed" << LL_ENDL;
+ }
+ }
+}
+
+bool LLWindowMacOSX::getInputDevices(U32 device_type_filter,
+ std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback,
+ void* win_callback,
+ void* userdata)
+{
+ CFMutableDictionaryRef device_dict_ref;
+ IOReturn result = kIOReturnSuccess; // assume success( optimist! )
+
+ // Set up matching dictionary to search the I/O Registry for HID devices we are interested in. Dictionary reference is NULL if error.
+
+ // A dictionary to match devices to?
+ device_dict_ref = IOServiceMatching( kIOHIDDeviceKey );
+
+ // BUG FIX! one reference is consumed by IOServiceGetMatchingServices
+ CFRetain( device_dict_ref );
+ io_iterator_t io_iter = 0;
+
+ // create an IO object iterator
+ result = IOServiceGetMatchingServices( kIOMasterPortDefault, device_dict_ref, &io_iter );
+ if ( kIOReturnSuccess != result )
+ {
+ LL_WARNS("Joystick") << "IOServiceGetMatchingServices failed" << LL_ENDL;
+ }
+
+ if ( io_iter )
+ {
+ // add all existing devices
+ std::list<HidDevice> device_list;
+
+ get_devices(device_list, io_iter);
+
+ std::list<HidDevice>::iterator iter;
+
+ for (iter = device_list.begin(); iter != device_list.end(); ++iter)
+ {
+ S32 size = sizeof(long);
+ LLSD::Binary data; //just an std::vector
+ data.resize(size);
+ memcpy(&data[0], &iter->mlocalID, size);
+ std::string label(iter->mProduct);
+
+ osx_callback(label, data, userdata);
+ }
+ }
+
+ CFRelease( device_dict_ref );
+ return false; // todo: should be true once UI part gets done
+}
+
LLSD LLWindowMacOSX::getNativeKeyData()
{
LLSD result = LLSD::emptyMap();
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 851c860017..cec4f86b25 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -112,6 +112,11 @@ public:
void interruptLanguageTextInput() override;
void spawnWebBrowser(const std::string& escaped_url, bool async) override;
F32 getSystemUISize() override;
+
+ bool getInputDevices(U32 device_type_filter,
+ std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback,
+ void* win_callback,
+ void* userdata) override;
static std::vector<std::string> getDisplaysResolutionList();
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 2e560ddb0a..b959c03406 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -4495,7 +4495,10 @@ void* LLWindowWin32::getDirectInput8()
return &gDirectInput8;
}
-bool LLWindowWin32::getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata)
+bool LLWindowWin32::getInputDevices(U32 device_type_filter
+ std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback,
+ void * di8_devices_callback,
+ void* userdata)
{
if (gDirectInput8 != NULL)
{
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index b391acc12d..6fbb956539 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -129,7 +129,10 @@ public:
static void setDPIAwareness();
/*virtual*/ void* getDirectInput8();
- /*virtual*/ bool getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata);
+ /*virtual*/ bool getInputDevices(U32 device_type_filter,
+ std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback,
+ void* win_callback,
+ void* userdata);
U32 getRawWParam() { return mRawWParam; }
diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp
index 455df13e48..43d4adbc26 100644
--- a/indra/llxml/llxmlnode.cpp
+++ b/indra/llxml/llxmlnode.cpp
@@ -837,7 +837,7 @@ bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root,
if (!LLXMLNode::parseFile(filename, root, NULL))
{
- LL_WARNS() << "Problem reading UI description file: " << filename << LL_ENDL;
+ LL_WARNS() << "Problem reading UI description file: " << filename << " " << errno << LL_ENDL;
return false;
}
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index f1f156c2e0..e416172eb2 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -599,6 +599,9 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF
switch(filter)
{
case FFLOAD_ALL:
+ case FFLOAD_EXE:
+ allowedv->push_back("app");
+ allowedv->push_back("exe");
allowedv->push_back("wav");
allowedv->push_back("bvh");
allowedv->push_back("anim");
@@ -617,9 +620,6 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF
allowedv->push_back("tpic");
allowedv->push_back("png");
break;
- case FFLOAD_EXE:
- allowedv->push_back("app");
- allowedv->push_back("exe");
break;
case FFLOAD_WAV:
allowedv->push_back("wav");
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index 558b14bba7..5265411e54 100644
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -250,6 +250,12 @@ void LLFloaterJoystick::refresh()
initFromSettings();
}
+void LLFloaterJoystick::addDeviceCallback(std::string &name, LLSD::Binary& value, void* userdata)
+{
+ LLFloaterJoystick * floater = (LLFloaterJoystick*)userdata;
+ floater->mJoysticksCombo->add(name, value, ADD_BOTTOM, 1);
+}
+
void LLFloaterJoystick::addDevice(std::string &name, LLSD& value)
{
mJoysticksCombo->add(name, value, ADD_BOTTOM, 1);
@@ -264,19 +270,21 @@ void LLFloaterJoystick::refreshListOfDevices()
mHasDeviceList = false;
+ void* win_calback = nullptr;
// di8_devices_callback callback is immediate and happens in scope of getInputDevices()
#if LL_WINDOWS && !LL_MESA_HEADLESS
// space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
U32 device_type = DI8DEVCLASS_GAMECTRL;
- void* callback = &di8_list_devices_callback;
+ win_calback = di8_list_devices_callback;
+#elif LL_DARWIN
+ U32 device_type = 0;
#else
// MAC doesn't support device search yet
// On MAC there is an ndof_idsearch and it is possible to specify product
// and manufacturer in NDOF_Device for ndof_init_first to pick specific one
U32 device_type = 0;
- void* callback = NULL;
#endif
- if (gViewerWindow->getWindow()->getInputDevices(device_type, callback, this))
+ if (gViewerWindow->getWindow()->getInputDevices(device_type, addDeviceCallback, win_calback, this))
{
mHasDeviceList = true;
}
diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h
index 1d46efd3f6..912d9b5310 100644
--- a/indra/newview/llfloaterjoystick.h
+++ b/indra/newview/llfloaterjoystick.h
@@ -46,6 +46,7 @@ public:
virtual void draw();
static void setSNDefaults();
+ static void addDeviceCallback(std::string &name, LLSD::Binary& value, void* userdata);
void addDevice(std::string &name, LLSD& value);
protected:
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index e35cb26ce1..26a626f60f 100644
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -227,8 +227,17 @@ std::string string_from_guid(const GUID &guid)
return res;
}
+#elif LL_DARWIN
+
+bool macos_devices_callback(std::string &product, LLSD::Binary &data, void* userdata)
+{
+ //LLViewerJoystick::getInstance()->initDevice(&device, product_name, data);
+ return false;
+}
+
#endif
+
// -----------------------------------------------------------------------------
void LLViewerJoystick::updateEnabled(bool autoenable)
{
@@ -365,19 +374,21 @@ void LLViewerJoystick::init(bool autoenable)
{
if (mNdofDev)
{
+ void* win_callback = nullptr;
+ std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback;
// di8_devices_callback callback is immediate and happens in scope of getInputDevices()
#if LL_WINDOWS && !LL_MESA_HEADLESS
// space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
U32 device_type = DI8DEVCLASS_GAMECTRL;
- void* callback = &di8_devices_callback;
+ win_callback = &di8_devices_callback;
#else
// MAC doesn't support device search yet
// On MAC there is an ndof_idsearch and it is possible to specify product
// and manufacturer in NDOF_Device for ndof_init_first to pick specific one
U32 device_type = 0;
- void* callback = NULL;
+ osx_callback = macos_devices_callback;
#endif
- if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL))
+ if (!gViewerWindow->getWindow()->getInputDevices(device_type, osx_callback, win_callback, NULL))
{
LL_INFOS("Joystick") << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL;
// Failed to gather devices from windows, init first suitable one
@@ -438,21 +449,23 @@ void LLViewerJoystick::initDevice(LLSD &guid)
{
#if LIB_NDOF
mLastDeviceUUID = guid;
+ void* win_callback = nullptr;
+ std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback;
#if LL_WINDOWS && !LL_MESA_HEADLESS
// space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
U32 device_type = DI8DEVCLASS_GAMECTRL;
- void* callback = &di8_devices_callback;
+ win_callback = &di8_devices_callback;
#else
// MAC doesn't support device search yet
// On MAC there is an ndof_idsearch and it is possible to specify product
// and manufacturer in NDOF_Device for ndof_init_first to pick specific one
U32 device_type = 0;
- void* callback = NULL;
+ osx_callback = macos_devices_callback;
#endif
mDriverState = JDS_INITIALIZING;
- if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL))
+ if (!gViewerWindow->getWindow()->getInputDevices(device_type, osx_callback, win_callback, NULL))
{
LL_INFOS("Joystick") << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL;
// Failed to gather devices from windows, init first suitable one
diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h
index 3b4f898710..49f8c8eabf 100644
--- a/indra/newview/llviewerjoystick.h
+++ b/indra/newview/llviewerjoystick.h
@@ -103,7 +103,11 @@ private:
bool mCameraUpdated;
bool mOverrideCamera;
U32 mJoystickRun;
- LLSD mLastDeviceUUID; // _GUID as U8 binary map, integer 1 for no device/ndof's device
+
+ // Windows: _GUID as U8 binary map
+ // MacOS: long as an U8 binary map
+ // Else: integer 1 for no device/ndof's default device
+ LLSD mLastDeviceUUID;
static F32 sLastDelta[7];
static F32 sDelta[7];
diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml
index b1ed245378..d0d4b4ebc0 100644
--- a/indra/newview/skins/default/xui/en/floater_about_land.xml
+++ b/indra/newview/skins/default/xui/en/floater_about_land.xml
@@ -436,6 +436,18 @@
top_pad="7"
width="180" />
<text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ name="Claimed:"
+ top="247"
+ width="100">
+ Place Page:
+ </text>
+ <text
type="string"
length="1"
follows="left|top"