summaryrefslogtreecommitdiff
path: root/indra/newview/llfloaterjoystick.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llfloaterjoystick.cpp')
-rw-r--r--indra/newview/llfloaterjoystick.cpp148
1 files changed, 136 insertions, 12 deletions
diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp
index 2b672bc890..93a26f31cc 100644
--- a/indra/newview/llfloaterjoystick.cpp
+++ b/indra/newview/llfloaterjoystick.cpp
@@ -40,7 +40,17 @@
#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 <dinput.h>
+#endif
static LLTrace::SampleStatHandle<> sJoystickAxis0("Joystick axis 0"),
sJoystickAxis1("Joystick axis 1"),
@@ -58,8 +68,33 @@ 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;
+ LLSD value = data;
+ floater->addDevice(product_name, value);
+ }
+ return DIENUM_CONTINUE;
+}
+#endif
+
LLFloaterJoystick::LLFloaterJoystick(const LLSD& data)
- : LLFloater(data)
+ : LLFloater(data),
+ mHasDeviceList(false)
{
if (!LLViewerJoystick::getInstance()->isJoystickInitialized())
{
@@ -71,14 +106,13 @@ LLFloaterJoystick::LLFloaterJoystick(const LLSD& data)
void LLFloaterJoystick::draw()
{
- bool joystick_inited = LLViewerJoystick::getInstance()->isJoystickInitialized();
- getChildView("enable_joystick")->setEnabled(joystick_inited);
- getChildView("joystick_type")->setEnabled(joystick_inited);
- std::string desc = LLViewerJoystick::getInstance()->getDescription();
- if (desc.empty()) desc = getString("NoDevice");
- getChild<LLUICtrl>("joystick_type")->setValue(desc);
-
- LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
+ LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
+ bool joystick_inited = joystick->isJoystickInitialized();
+ if (joystick_inited != mHasDeviceList)
+ {
+ refreshListOfDevices();
+ }
+
for (U32 i = 0; i < 6; i++)
{
F32 value = joystick->getJoystickAxis(i);
@@ -115,8 +149,8 @@ BOOL LLFloaterJoystick::postBuild()
}
}
- mCheckJoystickEnabled = getChild<LLCheckBoxCtrl>("enable_joystick");
- childSetCommitCallback("enable_joystick",onCommitJoystickEnabled,this);
+ mJoysticksCombo = getChild<LLComboBox>("joystick_combo");
+ childSetCommitCallback("joystick_combo",onCommitJoystickEnabled,this);
mCheckFlycamEnabled = getChild<LLCheckBoxCtrl>("JoystickFlycamEnabled");
childSetCommitCallback("JoystickFlycamEnabled",onCommitJoystickEnabled,this);
@@ -125,6 +159,7 @@ BOOL LLFloaterJoystick::postBuild()
childSetAction("ok_btn", onClickOK, this);
refresh();
+ refreshListOfDevices();
return TRUE;
}
@@ -141,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");
@@ -210,12 +246,80 @@ void LLFloaterJoystick::initFromSettings()
void LLFloaterJoystick::refresh()
{
LLFloater::refresh();
+
initFromSettings();
}
+void LLFloaterJoystick::addDevice(std::string &name, LLSD& value)
+{
+ mJoysticksCombo->add(name, value, ADD_BOTTOM, 1);
+}
+
+void LLFloaterJoystick::refreshListOfDevices()
+{
+ mJoysticksCombo->removeall();
+ std::string no_device = getString("JoystickDisabled");
+ LLSD value = LLSD::Integer(0);
+ addDevice(no_device, value);
+
+ mHasDeviceList = false;
+
+ // 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;
+#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))
+ {
+ mHasDeviceList = true;
+ }
+
+ bool is_device_id_set = LLViewerJoystick::getInstance()->isDeviceUUIDSet();
+
+ if (LLViewerJoystick::getInstance()->isJoystickInitialized() &&
+ (!mHasDeviceList || !is_device_id_set))
+ {
+#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())
+ {
+ LLSD value = LLSD::Integer(0);
+ addDevice(desc, value);
+ mHasDeviceList = true;
+ }
+ }
+
+ if (gSavedSettings.getBOOL("JoystickEnabled") && mHasDeviceList)
+ {
+ if (is_device_id_set)
+ {
+ LLSD guid = LLViewerJoystick::getInstance()->getDeviceUUID();
+ mJoysticksCombo->selectByValue(guid);
+ }
+ else
+ {
+ mJoysticksCombo->selectByValue(LLSD::Integer(1));
+ }
+ }
+ else
+ {
+ mJoysticksCombo->selectByValue(LLSD::Integer(0));
+ }
+}
+
void LLFloaterJoystick::cancel()
{
gSavedSettings.setBOOL("JoystickEnabled", mJoystickEnabled);
+ gSavedSettings.setLLSD("JoystickDeviceUUID", mJoystickId);
gSavedSettings.setS32("JoystickAxis0", mJoystickAxis[0]);
gSavedSettings.setS32("JoystickAxis1", mJoystickAxis[1]);
@@ -285,7 +389,21 @@ void LLFloaterJoystick::cancel()
void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
{
LLFloaterJoystick* self = (LLFloaterJoystick*)joy_panel;
- BOOL joystick_enabled = self->mCheckJoystickEnabled->get();
+
+ LLSD value = self->mJoysticksCombo->getValue();
+ bool joystick_enabled = true;
+ if (value.isInteger())
+ {
+ // 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;
+ }
+ gSavedSettings.setBOOL("JoystickEnabled", joystick_enabled);
BOOL flycam_enabled = self->mCheckFlycamEnabled->get();
if (!joystick_enabled || !flycam_enabled)
@@ -297,6 +415,12 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
joystick->toggleFlycam();
}
}
+
+ std::string device_id = LLViewerJoystick::getInstance()->getDeviceUUIDString();
+ gSavedSettings.setString("JoystickDeviceUUID", device_id);
+ LL_DEBUGS("Joystick") << "Selected " << device_id << " as joystick." << LL_ENDL;
+
+ self->refreshListOfDevices();
}
void LLFloaterJoystick::onClickRestoreSNDefaults(void *joy_panel)