parent
0fbe4cf62a
commit
54383cac8f
|
|
@ -1380,18 +1380,34 @@ BOOL LLScrollListCtrl::setSelectedByValue(const LLSD& value, BOOL selected)
|
|||
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
|
||||
{
|
||||
LLScrollListItem* item = *iter;
|
||||
if (item->getEnabled() && (item->getValue().asString() == value.asString()))
|
||||
if (item->getEnabled())
|
||||
{
|
||||
if (selected)
|
||||
{
|
||||
selectItem(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
deselectItem(item);
|
||||
}
|
||||
found = TRUE;
|
||||
break;
|
||||
if (value.isBinary())
|
||||
{
|
||||
if (item->getValue().isBinary())
|
||||
{
|
||||
LLSD::Binary data1 = value.asBinary();
|
||||
LLSD::Binary data2 = item->getValue().asBinary();
|
||||
found = std::equal(data1.begin(), data1.end(), data2.begin()) ? TRUE : FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
found = item->getValue().asString() == value.asString() ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (selected)
|
||||
{
|
||||
selectItem(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
deselectItem(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ public:
|
|||
|
||||
// windows only DirectInput8 for joysticks
|
||||
virtual void* getDirectInput8() { return NULL; };
|
||||
virtual bool getInputDevices(U32 device_type_filter, void * devices_callback) { return false; };
|
||||
virtual bool getInputDevices(U32 device_type_filter, void * devices_callback, void* userdata) { return false; };
|
||||
protected:
|
||||
LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags);
|
||||
virtual ~LLWindow();
|
||||
|
|
|
|||
|
|
@ -4181,7 +4181,7 @@ void* LLWindowWin32::getDirectInput8()
|
|||
return &gDirectInput8;
|
||||
}
|
||||
|
||||
bool LLWindowWin32::getInputDevices(U32 device_type_filter, void * di8_devices_callback)
|
||||
bool LLWindowWin32::getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata)
|
||||
{
|
||||
if (gDirectInput8 != NULL)
|
||||
{
|
||||
|
|
@ -4189,7 +4189,7 @@ bool LLWindowWin32::getInputDevices(U32 device_type_filter, void * di8_devices_c
|
|||
HRESULT status = gDirectInput8->EnumDevices(
|
||||
(DWORD) device_type_filter, // DWORD dwDevType,
|
||||
(LPDIENUMDEVICESCALLBACK)di8_devices_callback, // LPDIENUMDEVICESCALLBACK lpCallback, // BOOL DIEnumDevicesCallback( LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef ) // BOOL CALLBACK DinputDevice::DevicesCallback
|
||||
(LPVOID*)gDirectInput8, // LPVOID pvRef
|
||||
(LPVOID*)userdata, // LPVOID pvRef
|
||||
DIEDFL_ATTACHEDONLY // DWORD dwFlags
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ public:
|
|||
static void setDPIAwareness();
|
||||
|
||||
/*virtual*/ void* getDirectInput8();
|
||||
/*virtual*/ bool getInputDevices(U32 device_type_filter, void * di8_devices_callback);
|
||||
/*virtual*/ bool getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata);
|
||||
protected:
|
||||
LLWindowWin32(LLWindowCallbacks* callbacks,
|
||||
const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ public:
|
|||
virtual void draw();
|
||||
static void setSNDefaults();
|
||||
|
||||
void addDevice(std::string &name, LLSD& value);
|
||||
|
||||
protected:
|
||||
|
||||
void refreshListOfDevices();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
if (!LLViewerJoystick::getInstance()->isJoystickInitialized())
|
||||
bool init_device = false;
|
||||
if (guid.isBinary())
|
||||
{
|
||||
bool found_space_mouse = is_space_mouse(product_id, vendor_id);
|
||||
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 (found_space_mouse)
|
||||
if (init_device)
|
||||
{
|
||||
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 (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
|
||||
}
|
||||
|
||||
|
|
@ -1251,6 +1309,12 @@ void LLViewerJoystick::scanJoystick()
|
|||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
LLSD LLViewerJoystick::getDeviceUUID()
|
||||
{
|
||||
return mLastDeviceUUID;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
std::string LLViewerJoystick::getDescription()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
Loading…
Reference in New Issue