summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2020-07-14 00:28:21 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2020-07-15 13:55:32 +0300
commit8c66f54cfa9b1d26271338b7629290b35222617f (patch)
tree306740a8d80192fb7da7d96fb2d0474667f27e71 /indra/newview
parent54383cac8fa8a40d96590a300d4fce618f7413f3 (diff)
SL-5894 #4 Organize device storage between sessions
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/llfloaterjoystick.cpp30
-rw-r--r--indra/newview/llfloaterjoystick.h1
-rw-r--r--indra/newview/llviewerjoystick.cpp200
-rw-r--r--indra/newview/llviewerjoystick.h7
5 files changed, 148 insertions, 101 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index dfc3c7b89d..1ab97ccc02 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5242,6 +5242,17 @@
<key>Value</key>
<string />
</map>
+ <key>JoystickDeviceUUID</key>
+ <map>
+ <key>Comment</key>
+ <string>Preffered device ID.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string />
+ </map>
<key>JoystickMouselookYaw</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index 79814de28d..93a26f31cc 100644
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -49,9 +49,6 @@
// Require DirectInput version 8
#define DIRECTINPUT_VERSION 0x0800
-//#include <InitGuid.h>
-//#pragma comment(lib, "dinput8")
-//#pragma comment(lib, "dxguid.lib")
#include <dinput.h>
#endif
@@ -88,7 +85,8 @@ BOOL CALLBACK di8_list_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr,
memcpy(&data[0], &device_instance_ptr->guidInstance /*POD _GUID*/, size);
LLFloaterJoystick * floater = (LLFloaterJoystick*)pvRef;
- floater->addDevice(product_name, LLSD(data));
+ LLSD value = data;
+ floater->addDevice(product_name, value);
}
return DIENUM_CONTINUE;
}
@@ -178,6 +176,7 @@ void LLFloaterJoystick::apply()
void LLFloaterJoystick::initFromSettings()
{
mJoystickEnabled = gSavedSettings.getBOOL("JoystickEnabled");
+ mJoystickId = gSavedSettings.getLLSD("JoystickDeviceUUID");
mJoystickAxis[0] = gSavedSettings.getS32("JoystickAxis0");
mJoystickAxis[1] = gSavedSettings.getS32("JoystickAxis1");
@@ -260,7 +259,8 @@ void LLFloaterJoystick::refreshListOfDevices()
{
mJoysticksCombo->removeall();
std::string no_device = getString("JoystickDisabled");
- addDevice(no_device, LLSD(LLSD::Integer(0)));
+ LLSD value = LLSD::Integer(0);
+ addDevice(no_device, value);
mHasDeviceList = false;
@@ -269,7 +269,7 @@ void LLFloaterJoystick::refreshListOfDevices()
// space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
U32 device_type = DI8DEVCLASS_GAMECTRL;
void* callback = &di8_list_devices_callback;
-#elif
+#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
@@ -281,10 +281,10 @@ void LLFloaterJoystick::refreshListOfDevices()
mHasDeviceList = true;
}
- LLSD guid = LLViewerJoystick::getInstance()->getDeviceUUID();
+ bool is_device_id_set = LLViewerJoystick::getInstance()->isDeviceUUIDSet();
if (LLViewerJoystick::getInstance()->isJoystickInitialized() &&
- (!mHasDeviceList || !guid.isBinary()))
+ (!mHasDeviceList || !is_device_id_set))
{
#if LL_WINDOWS && !LL_MESA_HEADLESS
LL_WARNS() << "NDOF connected to device without using SL provided handle" << LL_ENDL;
@@ -292,15 +292,17 @@ void LLFloaterJoystick::refreshListOfDevices()
std::string desc = LLViewerJoystick::getInstance()->getDescription();
if (!desc.empty())
{
- addDevice(desc, LLSD(LLSD::Integer(1)));
+ LLSD value = LLSD::Integer(0);
+ addDevice(desc, value);
mHasDeviceList = true;
}
}
if (gSavedSettings.getBOOL("JoystickEnabled") && mHasDeviceList)
{
- if (guid.isBinary())
+ if (is_device_id_set)
{
+ LLSD guid = LLViewerJoystick::getInstance()->getDeviceUUID();
mJoysticksCombo->selectByValue(guid);
}
else
@@ -317,6 +319,7 @@ void LLFloaterJoystick::refreshListOfDevices()
void LLFloaterJoystick::cancel()
{
gSavedSettings.setBOOL("JoystickEnabled", mJoystickEnabled);
+ gSavedSettings.setLLSD("JoystickDeviceUUID", mJoystickId);
gSavedSettings.setS32("JoystickAxis0", mJoystickAxis[0]);
gSavedSettings.setS32("JoystickAxis1", mJoystickAxis[1]);
@@ -391,15 +394,14 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
bool joystick_enabled = true;
if (value.isInteger())
{
- joystick_enabled = value.asInteger();
// ndof already has a device selected, we are just setting it enabled or disabled
+ joystick_enabled = value.asInteger();
}
else
{
LLViewerJoystick::getInstance()->initDevice(value);
// else joystick is enabled, because combobox holds id of device
joystick_enabled = true;
- // todo: make LLViewerJoystick select a device based on value
}
gSavedSettings.setBOOL("JoystickEnabled", joystick_enabled);
BOOL flycam_enabled = self->mCheckFlycamEnabled->get();
@@ -414,6 +416,10 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
}
}
+ std::string device_id = LLViewerJoystick::getInstance()->getDeviceUUIDString();
+ gSavedSettings.setString("JoystickDeviceUUID", device_id);
+ LL_DEBUGS("Joystick") << "Selected " << device_id << " as joystick." << LL_ENDL;
+
self->refreshListOfDevices();
}
diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h
index 93f5696272..1d46efd3f6 100644
--- a/indra/newview/llfloaterjoystick.h
+++ b/indra/newview/llfloaterjoystick.h
@@ -69,6 +69,7 @@ private:
private:
// Device prefs
bool mJoystickEnabled;
+ LLSD mJoystickId;
S32 mJoystickAxis[7];
bool m3DCursor;
bool mAutoLeveling;
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index baeaaa0722..a75e0b5569 100644
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -46,9 +46,6 @@
// Require DirectInput version 8
#define DIRECTINPUT_VERSION 0x0800
-//#include <InitGuid.h>
-//#pragma comment(lib, "dinput8")
-//#pragma comment(lib, "dxguid.lib")
#include <dinput.h>
#endif
@@ -76,13 +73,11 @@ F32 LLViewerJoystick::sDelta[] = {0,0,0,0,0,0,0};
#if LL_WINDOWS && !LL_MESA_HEADLESS
-// took this from ndofdev_win.cpp
-BOOL CALLBACK EnumNDOFObjectsCallback(const DIDEVICEOBJECTINSTANCE* inst,
- VOID* user_data)
+// this should reflect ndof and set axises, see ndofdev_win.cpp from ndof package
+BOOL CALLBACK EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* inst, VOID* user_data)
{
if (inst->dwType & DIDFT_AXIS)
{
- HRESULT hr = DI_OK;
LPDIRECTINPUTDEVICE8 device = *((LPDIRECTINPUTDEVICE8 *)user_data);
DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof(DIPROPRANGE);
@@ -93,70 +88,15 @@ BOOL CALLBACK EnumNDOFObjectsCallback(const DIDEVICEOBJECTINSTANCE* inst,
// Set the range for the axis
diprg.lMin = (long)-MAX_JOYSTICK_INPUT_VALUE;
diprg.lMax = (long)+MAX_JOYSTICK_INPUT_VALUE;
- hr = device->SetProperty(DIPROP_RANGE, &diprg.diph);
- assert(hr == DI_OK);
-
+ HRESULT hr = device->SetProperty(DIPROP_RANGE, &diprg.diph);
if (FAILED(hr))
- return DIENUM_STOP;
- }
-
- return DIENUM_CONTINUE;
-}
-
-// vvvv Product ID
-// 0xC62B046D
-// ^^^^ Vendor ID
-// 0x046D Logitech's Vendor ID
-// 0x256F 3Dconnexion's Vendor ID
-//
-// See:
-// https://github.com/janoc/libndofdev/blob/master/ndofdev.c
-// http://spacemice.org/index.php?title=Dev
-// https://www.3dconnexion.com/nc/service/faq/faq/how-can-i-check-if-my-usb-3d-mouse-is-recognized-by-windows.html
-bool is_space_mouse(const U16 product_id, const U16 vendor_id)
-{
- if (vendor_id == 0x046d) // Logitech's Vendor ID
- {
- if (false
- || (product_id == 0xc603) // SpaceMouse Plus USB, SpaceMouse Plus XT USB
- || (product_id == 0xc605) // CadMan: USB
- || (product_id == 0xc606) // SpaceMouse Classic USB
- || (product_id == 0xc621) // SpaceBall 5000 USB
- || (product_id == 0xc623) // SpaceTraveler: USB
- || (product_id == 0xc625) // SpacePilot: USB
- || (product_id == 0xc626) // SpaceNavigator: USB
- || (product_id == 0xc627) // SpaceExplorer: USB
- || (product_id == 0xc628) // SpaceNavigator for Notebooks: USB
- || (product_id == 0xc629) // SpacePilot Pro: USB
- || (product_id == 0xc62b) // SpaceMouse Pro: USB
- )
{
- return true;
+ return DIENUM_STOP;
}
}
- else
- if (vendor_id == 0x256F) // 3Dconnexion's Vendor ID
- {
- if (false
- || (product_id == 0xc62E) // SpaceMouse Wireless (cabled)
- || (product_id == 0xc62F) // SpaceMouse Wireless Receiver
- || (product_id == 0xc631) // Spacemouse Wireless (cabled)
- || (product_id == 0xc632) // SpacemousePro Wireless Receiver
- || (product_id == 0xc633) // SpaceMouse Enterprise
- || (product_id == 0xc635) // Spacemouse Compact
- || (product_id == 0xc650) // CadMouse
- || (product_id == 0xc651) // CadMouse Wireless
- || (product_id == 0xc652) // Universal Receiver
- || (product_id == 0xc654) // CadMouse Pro Wireless
- || (product_id == 0xc657) // CadMouse Pro Wireless Left
- )
- {
- return true;
- }
- }
- return false;
+ return DIENUM_CONTINUE;
}
BOOL CALLBACK di8_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, LPVOID pvRef)
@@ -179,7 +119,7 @@ BOOL CALLBACK di8_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, LPVO
else
{
// It might be better to init space navigator here, but if system doesn't has one,
- // ndof will pick a random device, it is simpler to pick device now
+ // ndof will pick a random device, it is simpler to pick first device now to have an id
init_device = true;
}
@@ -206,7 +146,7 @@ BOOL CALLBACK di8_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, LPVO
{
// set properties
LL_DEBUGS("Joystick") << "Format set" << LL_ENDL;
- status = device->EnumObjects(EnumNDOFObjectsCallback, &device, DIDFT_ALL);
+ status = device->EnumObjects(EnumObjectsCallback, &device, DIDFT_ALL);
}
if (status == DI_OK)
@@ -228,6 +168,27 @@ BOOL CALLBACK di8_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, LPVO
}
return DIENUM_CONTINUE;
}
+
+// Windows guids
+// This is GUID2 so teoretically it can be memcpy copied into LLUUID
+void guid_from_string(GUID &guid, const std::string &input)
+{
+ CLSIDFromString(utf8str_to_utf16str(input).c_str(), &guid);
+}
+
+std::string string_from_guid(const GUID &guid)
+{
+ OLECHAR* guidString; //wchat
+ StringFromCLSID(guid, &guidString);
+
+ // use guidString...
+
+ std::string res = utf16str_to_utf8str(llutf16string(guidString));
+ // ensure memory is freed
+ ::CoTaskMemFree(guidString);
+
+ return res;
+}
#endif
// -----------------------------------------------------------------------------
@@ -239,7 +200,8 @@ void LLViewerJoystick::updateEnabled(bool autoenable)
}
else
{
- if (isLikeSpaceNavigator() && autoenable)
+ // autoenable if user specifically chose this device
+ if (autoenable && (isLikeSpaceNavigator() || isDeviceUUIDSet()))
{
gSavedSettings.setBOOL("JoystickEnabled", TRUE );
}
@@ -275,7 +237,7 @@ NDOF_HotPlugResult LLViewerJoystick::HotPlugAddCallback(NDOF_Device *dev)
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
if (joystick->mDriverState == JDS_UNINITIALIZED)
{
- LL_INFOS() << "HotPlugAddCallback: will use device:" << LL_ENDL;
+ LL_INFOS("Joystick") << "HotPlugAddCallback: will use device:" << LL_ENDL;
ndof_dump(dev);
joystick->mNdofDev = dev;
joystick->mDriverState = JDS_INITIALIZED;
@@ -293,7 +255,7 @@ void LLViewerJoystick::HotPlugRemovalCallback(NDOF_Device *dev)
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
if (joystick->mNdofDev == dev)
{
- LL_INFOS() << "HotPlugRemovalCallback: joystick->mNdofDev="
+ LL_INFOS("Joystick") << "HotPlugRemovalCallback: joystick->mNdofDev="
<< joystick->mNdofDev << "; removed device:" << LL_ENDL;
ndof_dump(dev);
joystick->mDriverState = JDS_UNINITIALIZED;
@@ -339,7 +301,8 @@ void LLViewerJoystick::init(bool autoenable)
#if LIB_NDOF
static bool libinit = false;
mDriverState = JDS_INITIALIZING;
- //todo: load mLastDeviceUUID from settings
+
+ loadDeviceIdFromSettings();
if (libinit == false)
{
@@ -369,7 +332,7 @@ void LLViewerJoystick::init(bool autoenable)
// space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
U32 device_type = DI8DEVCLASS_GAMECTRL;
void* callback = &di8_devices_callback;
-#elif
+#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
@@ -378,20 +341,17 @@ void LLViewerJoystick::init(bool autoenable)
#endif
if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL))
{
- LL_INFOS() << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL;
+ 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::Integer(1);
+ mLastDeviceUUID = LLSD();
void *preffered_device = NULL;
initDevice(preffered_device);
}
- // make sure a device was found:
if (mDriverState == JDS_INITIALIZING)
{
- LL_INFOS() << "Found no suitable devices. Trying ndof's default init" << LL_ENDL;
- mLastDeviceUUID = LLSD::Integer(1);
- void *preffered_device = NULL;
- initDevice(preffered_device);
+ LL_INFOS("Joystick") << "Found no matching joystick devices." << LL_ENDL;
+ mDriverState = JDS_UNINITIALIZED;
}
}
else
@@ -431,7 +391,7 @@ void LLViewerJoystick::init(bool autoenable)
// No device connected, don't change any settings
}
- LL_INFOS() << "ndof: mDriverState=" << mDriverState << "; mNdofDev="
+ LL_INFOS("Joystick") << "ndof: mDriverState=" << mDriverState << "; mNdofDev="
<< mNdofDev << "; libinit=" << libinit << LL_ENDL;
#endif
}
@@ -440,13 +400,12 @@ void LLViewerJoystick::initDevice(LLSD &guid)
{
#if LIB_NDOF
mLastDeviceUUID = guid;
- // todo: should we Unacquire old one?
#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;
-#elif
+#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
@@ -454,14 +413,21 @@ void LLViewerJoystick::initDevice(LLSD &guid)
void* callback = NULL;
#endif
+ mDriverState = JDS_INITIALIZING;
if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL))
{
- LL_INFOS() << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL;
+ 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::Integer(1);
+ mLastDeviceUUID = LLSD();
initDevice(preffered_device);
}
+
+ if (mDriverState == JDS_INITIALIZING)
+ {
+ LL_INFOS("Joystick") << "Found no matching joystick devices." << LL_ENDL;
+ mDriverState = JDS_UNINITIALIZED;
+ }
#endif
}
@@ -508,8 +474,6 @@ void LLViewerJoystick::initDevice(void * preffered_device /* LPDIRECTINPUTDEVICE
{
mDriverState = JDS_INITIALIZED;
}
-
- //todo: save mLastDeviceUUID to settings
#endif
}
@@ -519,7 +483,7 @@ void LLViewerJoystick::terminate()
#if LIB_NDOF
ndof_libcleanup();
- LL_INFOS() << "Terminated connection with NDOF device." << LL_ENDL;
+ LL_INFOS("Joystick") << "Terminated connection with NDOF device." << LL_ENDL;
mDriverState = JDS_UNINITIALIZED;
#endif
}
@@ -1310,11 +1274,73 @@ void LLViewerJoystick::scanJoystick()
}
// -----------------------------------------------------------------------------
+bool LLViewerJoystick::isDeviceUUIDSet()
+{
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // for ease of comparison and to dial less with platform specific variables, we store id as LLSD binary
+ return mLastDeviceUUID.isBinary();
+#else
+ return false;
+#endif
+}
+
LLSD LLViewerJoystick::getDeviceUUID()
{
return mLastDeviceUUID;
}
+std::string LLViewerJoystick::getDeviceUUIDString()
+{
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // Might be simpler to just convert _GUID into string everywhere, store and compare as string
+ if (mLastDeviceUUID.isBinary())
+ {
+ S32 size = sizeof(GUID);
+ LLSD::Binary data = mLastDeviceUUID.asBinary();
+ GUID guid;
+ memcpy(&guid, &data[0], size);
+ return string_from_guid(guid);
+ }
+ else
+ {
+ return std::string();
+ }
+#else
+ return std::string();
+ // return mLastDeviceUUID;
+#endif
+}
+
+void LLViewerJoystick::loadDeviceIdFromSettings()
+{
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ // We can't save binary data to gSavedSettings, somebody editing the file will corrupt it,
+ // so _GUID data gets converted to string (we probably can convert it to LLUUID with memcpy)
+ // and here we need to convert it back to binary from string
+ 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;
+ GUID guid;
+ guid_from_string(guid, device_string);
+ S32 size = sizeof(GUID);
+ 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
+ mLastDeviceUUID = LLSD(data);
+ }
+#else
+ mLastDeviceUUID = LLSD();
+ //mLastDeviceUUID = gSavedSettings.getLLSD("JoystickDeviceUUID");
+#endif
+}
+
// -----------------------------------------------------------------------------
std::string LLViewerJoystick::getDescription()
{
diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h
index eba549c5f2..782c523d4f 100644
--- a/indra/newview/llviewerjoystick.h
+++ b/indra/newview/llviewerjoystick.h
@@ -71,7 +71,9 @@ public:
void setOverrideCamera(bool val);
bool toggleFlycam();
void setSNDefaults();
- LLSD getDeviceUUID();
+ bool isDeviceUUIDSet();
+ LLSD getDeviceUUID(); //unconverted, OS dependent value wrapped into LLSD, for comparison/search
+ std::string getDeviceUUIDString(); // converted readable value for settings
std::string getDescription();
protected:
@@ -84,6 +86,7 @@ protected:
void agentYaw(F32 yaw_inc);
void agentJump();
void resetDeltas(S32 axis[]);
+ void loadDeviceIdFromSettings();
#if LIB_NDOF
static NDOF_HotPlugResult HotPlugAddCallback(NDOF_Device *dev);
static void HotPlugRemovalCallback(NDOF_Device *dev);
@@ -99,7 +102,7 @@ private:
bool mCameraUpdated;
bool mOverrideCamera;
U32 mJoystickRun;
- LLSD mLastDeviceUUID; // _UUID as U8 binary map, integer 1 for no device/ndof's device
+ LLSD mLastDeviceUUID; // _GUID as U8 binary map, integer 1 for no device/ndof's device
static F32 sLastDelta[7];
static F32 sDelta[7];