SL-13610 [MAC] WIP enable initing devices by local id

master
Andrey Kleshchev 2022-12-20 17:44:08 +02:00 committed by akleshchev
parent 9b27b6e509
commit 453a4a13f8
10 changed files with 156 additions and 46 deletions

View File

@ -1384,9 +1384,9 @@
<key>archive</key>
<map>
<key>hash</key>
<string>a487fff84208a45844602c4a1f68c974</string>
<string>69c3e7c8cbf47d6f840011d1fa34cd8b</string>
<key>url</key>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76356/727333/libndofdev-0.1.555523-darwin64-555523.tar.bz2</string>
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/108791/947410/libndofdev-0.1.577357-darwin64-577357.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -1417,7 +1417,7 @@
</map>
</map>
<key>version</key>
<string>0.1.555523</string>
<string>0.1.577357</string>
</map>
<key>libpng</key>
<map>

View File

@ -197,7 +197,7 @@ public:
// windows only DirectInput8 for joysticks
virtual void* getDirectInput8() { return NULL; };
virtual bool getInputDevices(U32 device_type_filter,
std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback,
std::function<bool(std::string&, LLSD::Binary&, void*)> osx_callback,
void* win_callback,
void* userdata)
{

View File

@ -2058,10 +2058,11 @@ static void get_devices(std::list<HidDevice> &list_of_devices,
}
bool LLWindowMacOSX::getInputDevices(U32 device_type_filter,
std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback,
std::function<bool(std::string&, LLSD::Binary&, void*)> osx_callback,
void* win_callback,
void* userdata)
{
bool return_value = false;
CFMutableDictionaryRef device_dict_ref;
IOReturn result = kIOReturnSuccess; // assume success( optimist! )
@ -2098,12 +2099,16 @@ bool LLWindowMacOSX::getInputDevices(U32 device_type_filter,
memcpy(&data[0], &iter->mlocalID, size);
std::string label(iter->mProduct);
osx_callback(label, data, userdata);
if (osx_callback(label, data, userdata))
{
break; //found device
}
}
return_value = true;
}
CFRelease( device_dict_ref );
return false; // todo: should be true once UI part gets done
return return_value;
}
LLSD LLWindowMacOSX::getNativeKeyData()

View File

@ -114,7 +114,7 @@ public:
F32 getSystemUISize() override;
bool getInputDevices(U32 device_type_filter,
std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback,
std::function<bool(std::string&, LLSD::Binary&, void*)> osx_callback,
void* win_callback,
void* userdata) override;

View File

@ -4496,7 +4496,7 @@ void* LLWindowWin32::getDirectInput8()
}
bool LLWindowWin32::getInputDevices(U32 device_type_filter
std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback,
std::function<bool(std::string&, LLSD::Binary&, void*)> osx_callback,
void * di8_devices_callback,
void* userdata)
{

View File

@ -130,7 +130,7 @@ public:
/*virtual*/ void* getDirectInput8();
/*virtual*/ bool getInputDevices(U32 device_type_filter,
std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback,
std::function<bool(std::string&, LLSD::Binary&, void*)> osx_callback,
void* win_callback,
void* userdata);

View File

@ -250,10 +250,11 @@ void LLFloaterJoystick::refresh()
initFromSettings();
}
void LLFloaterJoystick::addDeviceCallback(std::string &name, LLSD::Binary& value, void* userdata)
bool LLFloaterJoystick::addDeviceCallback(std::string &name, LLSD::Binary& value, void* userdata)
{
LLFloaterJoystick * floater = (LLFloaterJoystick*)userdata;
floater->mJoysticksCombo->add(name, value, ADD_BOTTOM, 1);
return false; // keep searching
}
void LLFloaterJoystick::addDevice(std::string &name, LLSD& value)

View File

@ -46,7 +46,7 @@ public:
virtual void draw();
static void setSNDefaults();
static void addDeviceCallback(std::string &name, LLSD::Binary& value, void* userdata);
static bool addDeviceCallback(std::string &name, LLSD::Binary& value, void* userdata);
void addDevice(std::string &name, LLSD& value);
protected:

View File

@ -229,9 +229,17 @@ std::string string_from_guid(const GUID &guid)
}
#elif LL_DARWIN
bool macos_devices_callback(std::string &product, LLSD::Binary &data, void* userdata)
bool macos_devices_callback(std::string &product_name, LLSD::Binary &data, void* userdata)
{
//LLViewerJoystick::getInstance()->initDevice(&device, product_name, data);
S32 size = sizeof(long);
long id;
memcpy(&id, &data[0], size);
NDOF_Device *device = ndof_idsearch(id);
if (device)
{
return LLViewerJoystick::getInstance()->initDevice(device, data);
}
return false;
}
@ -374,27 +382,50 @@ void LLViewerJoystick::init(bool autoenable)
{
if (mNdofDev)
{
U32 device_type = 0;
void* win_callback = nullptr;
std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback;
std::function<bool(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;
device_type = DI8DEVCLASS_GAMECTRL;
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;
#elif LL_DARWIN
osx_callback = macos_devices_callback;
#endif
if (!gViewerWindow->getWindow()->getInputDevices(device_type, osx_callback, win_callback, NULL))
if (mLastDeviceUUID.isBinary())
{
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
mLastDeviceUUID = LLSD();
void *preffered_device = NULL;
initDevice(preffered_device);
S32 size = sizeof(long);
long id;
memcpy(&id, &mLastDeviceUUID[0], size);
NDOF_Device *device = ndof_idsearch(id);
if (device)
{
if (ndof_init_first(device, nullptr))
{
mDriverState = JDS_INITIALIZING;
// Saved device no longer exist
LL_WARNS() << "ndof_init_first FAILED" << LL_ENDL;
}
else
{
mNdofDev = device;
mDriverState = JDS_INITIALIZED;
}
}
}
#endif
if (mDriverState != JDS_INITIALIZED)
{
if (!gViewerWindow->getWindow()->getInputDevices(device_type, osx_callback, win_callback, NULL))
{
LL_INFOS("Joystick") << "Failed to gather input devices. Falling back to ndof's init" << LL_ENDL;
// Failed to gather devices, init first suitable one
mLastDeviceUUID = LLSD();
void *preffered_device = NULL;
initDevice(preffered_device);
}
}
if (mDriverState == JDS_INITIALIZING)
@ -449,29 +480,51 @@ void LLViewerJoystick::initDevice(LLSD &guid)
{
#if LIB_NDOF
mLastDeviceUUID = guid;
U32 device_type = 0;
void* win_callback = nullptr;
std::function<void(std::string&, LLSD::Binary&, void*)> osx_callback;
std::function<bool(std::string&, LLSD::Binary&, void*)> osx_callback;
mDriverState = JDS_INITIALIZING;
#if LL_WINDOWS && !LL_MESA_HEADLESS
// space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
U32 device_type = DI8DEVCLASS_GAMECTRL;
device_type = DI8DEVCLASS_GAMECTRL;
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;
#elif LL_DARWIN
osx_callback = macos_devices_callback;
if (mLastDeviceUUID.isBinary())
{
S32 size = sizeof(long);
long id;
memcpy(&id, &mLastDeviceUUID[0], size);
NDOF_Device *device = ndof_idsearch(id);
if (device)
{
if (ndof_init_first(device, nullptr))
{
mDriverState = JDS_INITIALIZING;
// Saved device no longer exist
LL_WARNS() << "ndof_init_first FAILED" << LL_ENDL;
}
else
{
mNdofDev = device;
mDriverState = JDS_INITIALIZED;
}
}
}
#endif
mDriverState = JDS_INITIALIZING;
if (!gViewerWindow->getWindow()->getInputDevices(device_type, osx_callback, win_callback, NULL))
if (mDriverState != JDS_INITIALIZED)
{
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
void *preffered_device = NULL;
mLastDeviceUUID = LLSD();
initDevice(preffered_device);
if (!gViewerWindow->getWindow()->getInputDevices(device_type, osx_callback, win_callback, NULL))
{
LL_INFOS("Joystick") << "Failed to gather input devices. Falling back to ndof's init" << LL_ENDL;
// Failed to gather devices from windows, init first suitable one
void *preffered_device = NULL;
mLastDeviceUUID = LLSD();
initDevice(preffered_device);
}
}
if (mDriverState == JDS_INITIALIZING)
@ -528,6 +581,25 @@ void LLViewerJoystick::initDevice(void * preffered_device /* LPDIRECTINPUTDEVICE
#endif
}
bool LLViewerJoystick::initDevice(NDOF_Device * ndof_device, LLSD::Binary &data)
{
mLastDeviceUUID = data;
#if LIB_NDOF
if (ndof_init_first(ndof_device, nullptr))
{
mDriverState = JDS_UNINITIALIZED;
LL_WARNS() << "ndof_init_first FAILED" << LL_ENDL;
}
else
{
mNdofDev = ndof_device;
mDriverState = JDS_INITIALIZED;
return true;
}
#endif
return false;
}
// -----------------------------------------------------------------------------
void LLViewerJoystick::terminate()
{
@ -1359,9 +1431,21 @@ std::string LLViewerJoystick::getDeviceUUIDString()
{
return std::string();
}
#elif LL_DARWIN
if (mLastDeviceUUID.isBinary())
{
S32 size = sizeof(long);
LLSD::Binary data = mLastDeviceUUID.asBinary();
long id;
memcpy(&id, &data[0], size);
return std::to_string(id);
}
else
{
return std::string();
}
#else
return std::string();
// return mLastDeviceUUID;
#endif
}
@ -1385,8 +1469,24 @@ void LLViewerJoystick::loadDeviceIdFromSettings()
LLSD::Binary data; //just an std::vector
data.resize(size);
memcpy(&data[0], &guid /*POD _GUID*/, size);
// We store this data in LLSD since LLSD is versatile and will be able to handle both GUID2
// and any data MAC will need for device selection
// We store this data in LLSD since it can handle both GUID2 and long
mLastDeviceUUID = LLSD(data);
}
#elif LL_DARWIN
std::string device_string = gSavedSettings.getString("JoystickDeviceUUID");
if (device_string.empty())
{
mLastDeviceUUID = LLSD();
}
else
{
LL_DEBUGS("Joystick") << "Looking for device by id: " << device_string << LL_ENDL;
long id = std::stol(device_string);
S32 size = sizeof(long);
LLSD::Binary data; //just an std::vector
data.resize(size);
memcpy(&data[0], &id, size);
// We store this data in LLSD since it can handle both GUID2 and long
mLastDeviceUUID = LLSD(data);
}
#else

View File

@ -30,6 +30,9 @@
#include "stdtypes.h"
#if LIB_NDOF
#if LL_DARWIN
#define TARGET_OS_MAC 1
#endif
#include "ndofdev_external.h"
#else
#define NDOF_Device void
@ -54,6 +57,7 @@ public:
void initDevice(LLSD &guid);
void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/);
void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid);
bool initDevice(NDOF_Device * ndof_device, LLSD::Binary &guid);
void terminate();
void updateStatus();