summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorAndrey Kleshchev <andreykproductengine@lindenlab.com>2020-07-10 20:48:43 +0300
committerAndrey Kleshchev <andreykproductengine@lindenlab.com>2020-07-15 13:55:32 +0300
commit54383cac8fa8a40d96590a300d4fce618f7413f3 (patch)
tree25e5d5b28bcc914a779292f33a2070593f5c247f /indra/newview
parent0fbe4cf62a236ea24f383818bf81b933f87380d8 (diff)
SL-5894 #3 WIP enumerate devices to flaoter, let floater set device
temp
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llfloaterjoystick.cpp87
-rw-r--r--indra/newview/llfloaterjoystick.h2
-rw-r--r--indra/newview/llviewerjoystick.cpp148
-rw-r--r--indra/newview/llviewerjoystick.h6
4 files changed, 193 insertions, 50 deletions
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index 4538d34c95..79814de28d 100644
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -40,9 +40,21 @@
#include "llviewercontrol.h"
#include "llappviewer.h"
#include "llviewerjoystick.h"
+#include "llviewerwindow.h"
+#include "llwindow.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+// Require DirectInput version 8
+#define DIRECTINPUT_VERSION 0x0800
+
+//#include <InitGuid.h>
+//#pragma comment(lib, "dinput8")
+//#pragma comment(lib, "dxguid.lib")
+#include <dinput.h>
+#endif
+
static LLTrace::SampleStatHandle<> sJoystickAxis0("Joystick axis 0"),
sJoystickAxis1("Joystick axis 1"),
sJoystickAxis2("Joystick axis 2"),
@@ -59,6 +71,29 @@ static LLTrace::SampleStatHandle<>* sJoystickAxes[6] =
&sJoystickAxis5
};
+
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+
+BOOL CALLBACK di8_list_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, LPVOID pvRef)
+{
+ // Note: If a single device can function as more than one DirectInput
+ // device type, it is enumerated as each device type that it supports.
+ // Capable of detecting devices like Oculus Rift
+ if (device_instance_ptr && pvRef)
+ {
+ std::string product_name = utf16str_to_utf8str(llutf16string(device_instance_ptr->tszProductName));
+ S32 size = sizeof(GUID);
+ LLSD::Binary data; //just an std::vector
+ data.resize(size);
+ memcpy(&data[0], &device_instance_ptr->guidInstance /*POD _GUID*/, size);
+
+ LLFloaterJoystick * floater = (LLFloaterJoystick*)pvRef;
+ floater->addDevice(product_name, LLSD(data));
+ }
+ return DIENUM_CONTINUE;
+}
+#endif
+
LLFloaterJoystick::LLFloaterJoystick(const LLSD& data)
: LLFloater(data),
mHasDeviceList(false)
@@ -216,25 +251,62 @@ void LLFloaterJoystick::refresh()
initFromSettings();
}
+void LLFloaterJoystick::addDevice(std::string &name, LLSD& value)
+{
+ mJoysticksCombo->add(name, value, ADD_BOTTOM, 1);
+}
+
void LLFloaterJoystick::refreshListOfDevices()
{
mJoysticksCombo->removeall();
- mJoysticksCombo->add(getString("JoystickDisabled"), LLSD(LLSD::Integer(0)), ADD_BOTTOM, 1);
+ std::string no_device = getString("JoystickDisabled");
+ addDevice(no_device, LLSD(LLSD::Integer(0)));
mHasDeviceList = false;
- std::string desc = LLViewerJoystick::getInstance()->getDescription();
- if (!desc.empty())
+
+ // 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;
+#elif
+ // 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))
{
- mJoysticksCombo->add(desc, LLSD(LLSD::Integer(1)), ADD_BOTTOM, 1);
mHasDeviceList = true;
}
- //todo: load list of devices
+ LLSD guid = LLViewerJoystick::getInstance()->getDeviceUUID();
+
+ if (LLViewerJoystick::getInstance()->isJoystickInitialized() &&
+ (!mHasDeviceList || !guid.isBinary()))
+ {
+#if LL_WINDOWS && !LL_MESA_HEADLESS
+ LL_WARNS() << "NDOF connected to device without using SL provided handle" << LL_ENDL;
+#endif
+ std::string desc = LLViewerJoystick::getInstance()->getDescription();
+ if (!desc.empty())
+ {
+ addDevice(desc, LLSD(LLSD::Integer(1)));
+ mHasDeviceList = true;
+ }
+ }
if (gSavedSettings.getBOOL("JoystickEnabled") && mHasDeviceList)
{
- // todo: select device according to data from LLViewerJoystick
- mJoysticksCombo->selectByValue(LLSD::Integer(1));
+ if (guid.isBinary())
+ {
+ mJoysticksCombo->selectByValue(guid);
+ }
+ else
+ {
+ mJoysticksCombo->selectByValue(LLSD::Integer(1));
+ }
}
else
{
@@ -324,6 +396,7 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
}
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
diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h
index b3d879b233..93f5696272 100644
--- a/indra/newview/llfloaterjoystick.h
+++ b/indra/newview/llfloaterjoystick.h
@@ -46,6 +46,8 @@ public:
virtual void draw();
static void setSNDefaults();
+ void addDevice(std::string &name, LLSD& value);
+
protected:
void refreshListOfDevices();
diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp
index 9775bf646a..baeaaa0722 100644
--- a/indra/newview/llviewerjoystick.cpp
+++ b/indra/newview/llviewerjoystick.cpp
@@ -164,56 +164,66 @@ BOOL CALLBACK di8_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, LPVO
// Note: If a single device can function as more than one DirectInput
// device type, it is enumerated as each device type that it supports.
// Capable of detecting devices like Oculus Rift
- if (device_instance_ptr && pvRef)
+ if (device_instance_ptr)
{
std::string product_name = utf16str_to_utf8str(llutf16string(device_instance_ptr->tszProductName));
- LL_DEBUGS("Joystick") << "DirectInput8 Devices: " << product_name << LL_ENDL;
+ LLSD guid = LLViewerJoystick::getInstance()->getDeviceUUID();
- U16 product_id = (device_instance_ptr->guidProduct.Data1 >> 16) & 0xFFFF;
- U16 vendor_id = (device_instance_ptr->guidProduct.Data1 >> 0) & 0xFFFF;
+ bool init_device = false;
+ if (guid.isBinary())
+ {
+ std::vector<U8> bin_bucket = guid.asBinary();
+ init_device = memcmp(&bin_bucket[0], &device_instance_ptr->guidInstance, sizeof(GUID)) == 0;
+ }
+ 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
+ init_device = true;
+ }
- if (!LLViewerJoystick::getInstance()->isJoystickInitialized())
+ if (init_device)
{
- bool found_space_mouse = is_space_mouse(product_id, vendor_id);
+ LL_DEBUGS("Joystick") << "Found and attempting to use device: " << product_name << LL_ENDL;
+ LPDIRECTINPUT8 di8_interface = *((LPDIRECTINPUT8 *)gViewerWindow->getWindow()->getDirectInput8());
+ LPDIRECTINPUTDEVICE8 device = NULL;
+
+ HRESULT status = di8_interface->CreateDevice(
+ device_instance_ptr->guidInstance, // REFGUID rguid,
+ &device, // LPDIRECTINPUTDEVICE * lplpDirectInputDevice,
+ NULL // LPUNKNOWN pUnkOuter
+ );
- if (found_space_mouse)
+ if (status == DI_OK)
{
- LL_DEBUGS("Joystick") << "Found device that matches criteria: " << product_name << LL_ENDL;
- LPDIRECTINPUT8 di8_interface = (LPDIRECTINPUT8)pvRef;
- LPDIRECTINPUTDEVICE8 device = NULL;
-
- HRESULT status = di8_interface->CreateDevice(
- device_instance_ptr->guidInstance, // REFGUID rguid,
- &device, // LPDIRECTINPUTDEVICE * lplpDirectInputDevice,
- NULL // LPUNKNOWN pUnkOuter
- );
-
- if (status == DI_OK)
- {
- // prerequisite for aquire()
- LL_DEBUGS("Joystick") << "Device created" << LL_ENDL;
- status = device->SetDataFormat(&c_dfDIJoystick); // c_dfDIJoystick2
- }
-
- if (status == DI_OK)
- {
- // set properties
- LL_DEBUGS("Joystick") << "Format set" << LL_ENDL;
- status = device->EnumObjects(EnumNDOFObjectsCallback, &device, DIDFT_ALL);
- }
-
- // todo: record device name, ndof won't fill it from passed device
- // strncpy(mNdofDev->product, inst->tszProductName, sizeof(mNdofDev->product));
- // strncpy(mNdofDev->product, product_name.c_str(), sizeof(mNdofDev->product));
-
- if (status == DI_OK)
- {
- LL_DEBUGS("Joystick") << "Properties updated" << LL_ENDL;
- LLViewerJoystick::getInstance()->initDevice(&device);
- return DIENUM_STOP;
- }
+ // prerequisite for aquire()
+ LL_DEBUGS("Joystick") << "Device created" << LL_ENDL;
+ status = device->SetDataFormat(&c_dfDIJoystick); // c_dfDIJoystick2
}
+
+ if (status == DI_OK)
+ {
+ // set properties
+ LL_DEBUGS("Joystick") << "Format set" << LL_ENDL;
+ status = device->EnumObjects(EnumNDOFObjectsCallback, &device, DIDFT_ALL);
+ }
+
+ if (status == DI_OK)
+ {
+ LL_DEBUGS("Joystick") << "Properties updated" << LL_ENDL;
+
+ S32 size = sizeof(GUID);
+ LLSD::Binary data; //just an std::vector
+ data.resize(size);
+ memcpy(&data[0], &device_instance_ptr->guidInstance /*POD _GUID*/, size);
+ LLViewerJoystick::getInstance()->initDevice(&device, product_name, LLSD(data));
+ return DIENUM_STOP;
+ }
+ }
+ else
+ {
+ LL_DEBUGS("Joystick") << "Found device: " << product_name << LL_ENDL;
}
}
return DIENUM_CONTINUE;
@@ -310,6 +320,8 @@ LLViewerJoystick::LLViewerJoystick()
// factor in bandwidth? bandwidth = gViewerStats->mKBitStat
mPerfScale = 4000.f / gSysCPU.getMHz(); // hmm. why?
+
+ mLastDeviceUUID = LLSD::Integer(1);
}
// -----------------------------------------------------------------------------
@@ -327,6 +339,7 @@ void LLViewerJoystick::init(bool autoenable)
#if LIB_NDOF
static bool libinit = false;
mDriverState = JDS_INITIALIZING;
+ //todo: load mLastDeviceUUID from settings
if (libinit == false)
{
@@ -363,10 +376,11 @@ void LLViewerJoystick::init(bool autoenable)
U32 device_type = 0;
void* callback = NULL;
#endif
- if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback))
+ if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL))
{
LL_INFOS() << "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);
void *preffered_device = NULL;
initDevice(preffered_device);
}
@@ -375,6 +389,7 @@ void LLViewerJoystick::init(bool autoenable)
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);
}
@@ -421,6 +436,47 @@ void LLViewerJoystick::init(bool autoenable)
#endif
}
+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
+ // 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, NULL))
+ {
+ LL_INFOS() << "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);
+ initDevice(preffered_device);
+ }
+#endif
+}
+
+void LLViewerJoystick::initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid)
+{
+#if LIB_NDOF
+ mLastDeviceUUID = guid;
+
+ strncpy(mNdofDev->product, name.c_str(), sizeof(mNdofDev->product));
+ mNdofDev->manufacturer[0] = '\0';
+
+ initDevice(preffered_device);
+#endif
+}
+
void LLViewerJoystick::initDevice(void * preffered_device /* LPDIRECTINPUTDEVICE8* */)
{
#if LIB_NDOF
@@ -452,6 +508,8 @@ void LLViewerJoystick::initDevice(void * preffered_device /* LPDIRECTINPUTDEVICE
{
mDriverState = JDS_INITIALIZED;
}
+
+ //todo: save mLastDeviceUUID to settings
#endif
}
@@ -1252,6 +1310,12 @@ void LLViewerJoystick::scanJoystick()
}
// -----------------------------------------------------------------------------
+LLSD LLViewerJoystick::getDeviceUUID()
+{
+ return mLastDeviceUUID;
+}
+
+// -----------------------------------------------------------------------------
std::string LLViewerJoystick::getDescription()
{
std::string res;
diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h
index 9c59f811f1..eba549c5f2 100644
--- a/indra/newview/llviewerjoystick.h
+++ b/indra/newview/llviewerjoystick.h
@@ -50,7 +50,9 @@ class LLViewerJoystick : public LLSingleton<LLViewerJoystick>
public:
void init(bool autoenable);
+ void initDevice(LLSD &guid);
void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/);
+ void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid);
void terminate();
void updateStatus();
@@ -69,8 +71,9 @@ public:
void setOverrideCamera(bool val);
bool toggleFlycam();
void setSNDefaults();
+ LLSD getDeviceUUID();
std::string getDescription();
-
+
protected:
void updateEnabled(bool autoenable);
void handleRun(F32 inc);
@@ -96,6 +99,7 @@ private:
bool mCameraUpdated;
bool mOverrideCamera;
U32 mJoystickRun;
+ LLSD mLastDeviceUUID; // _UUID as U8 binary map, integer 1 for no device/ndof's device
static F32 sLastDelta[7];
static F32 sDelta[7];