summaryrefslogtreecommitdiff
path: root/indra/llwindow
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llwindow')
-rw-r--r--indra/llwindow/CMakeLists.txt2
-rw-r--r--indra/llwindow/lldxhardware.cpp94
-rw-r--r--indra/llwindow/lldxhardware.h4
-rw-r--r--indra/llwindow/llkeyboard.cpp88
-rw-r--r--indra/llwindow/llkeyboard.h16
-rw-r--r--indra/llwindow/llmousehandler.cpp2
-rw-r--r--indra/llwindow/llmousehandler.h13
-rw-r--r--indra/llwindow/llopenglview-objc.mm6
-rw-r--r--indra/llwindow/llwindow.cpp24
-rw-r--r--indra/llwindow/llwindow.h6
-rw-r--r--indra/llwindow/llwindowcallbacks.cpp4
-rw-r--r--indra/llwindow/llwindowcallbacks.h1
-rw-r--r--indra/llwindow/llwindowmacosx-objc.h2
-rw-r--r--indra/llwindow/llwindowmacosx.cpp38
-rw-r--r--indra/llwindow/llwindowmacosx.h2
-rw-r--r--indra/llwindow/llwindowsdl.cpp48
-rw-r--r--indra/llwindow/llwindowwin32.cpp314
-rw-r--r--indra/llwindow/llwindowwin32.h4
18 files changed, 487 insertions, 181 deletions
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 0743fd899f..8bfb23ed64 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -11,7 +11,6 @@
project(llwindow)
include(00-Common)
-include(DirectX)
include(DragDrop)
include(LLCommon)
include(LLImage)
@@ -30,7 +29,6 @@ include_directories(
${LLVFS_INCLUDE_DIRS}
${LLWINDOW_INCLUDE_DIRS}
${LLXML_INCLUDE_DIRS}
- ${DIRECTX_INCLUDE_DIR}
)
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp
index d4790f9f29..12a6baa3e6 100644
--- a/indra/llwindow/lldxhardware.cpp
+++ b/indra/llwindow/lldxhardware.cpp
@@ -61,7 +61,7 @@ typedef BOOL ( WINAPI* PfnCoSetProxyBlanket )( IUnknown* pProxy, DWORD dwAuthnSv
OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel,
RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities );
-HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
+HRESULT GetVideoMemoryViaWMI(WCHAR* strInputDeviceID, DWORD* pdwAdapterRam)
{
HRESULT hr;
bool bGotMemory = false;
@@ -149,21 +149,26 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
if ( !pVideoControllers[iController] )
continue;
- pPropName = SysAllocString( L"PNPDeviceID" );
- hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );
+ // if strInputDeviceID is set find this specific device and return memory or specific device
+ // if strInputDeviceID is not set return the best device
+ if (strInputDeviceID)
+ {
+ pPropName = SysAllocString( L"PNPDeviceID" );
+ hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );
#ifdef PRINTF_DEBUGGING
- if( FAILED( hr ) )
- wprintf( L"WMI: pVideoControllers[iController]->Get PNPDeviceID failed: 0x%0.8x\n", hr );
+ if( FAILED( hr ) )
+ wprintf( L"WMI: pVideoControllers[iController]->Get PNPDeviceID failed: 0x%0.8x\n", hr );
#endif
- if( SUCCEEDED( hr ) )
- {
- if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 )
- bFound = true;
+ if( SUCCEEDED( hr ) && strInputDeviceID)
+ {
+ if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 )
+ bFound = true;
+ }
+ VariantClear( &var );
+ if( pPropName ) SysFreeString( pPropName );
}
- VariantClear( &var );
- if( pPropName ) SysFreeString( pPropName );
- if( bFound )
+ if( bFound || !strInputDeviceID )
{
pPropName = SysAllocString( L"AdapterRAM" );
hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );
@@ -175,13 +180,18 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
if( SUCCEEDED( hr ) )
{
bGotMemory = true;
- *pdwAdapterRam = var.ulVal;
+ *pdwAdapterRam = llmax(var.ulVal, *pdwAdapterRam);
}
VariantClear( &var );
if( pPropName ) SysFreeString( pPropName );
- break;
}
+
SAFE_RELEASE( pVideoControllers[iController] );
+
+ if (bFound)
+ {
+ break;
+ }
}
}
}
@@ -207,6 +217,17 @@ HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
return E_FAIL;
}
+//static
+S32 LLDXHardware::getMBVideoMemoryViaWMI()
+{
+ DWORD vram = 0;
+ if (SUCCEEDED(GetVideoMemoryViaWMI(NULL, &vram)))
+ {
+ return vram / (1024 * 1024);;
+ }
+ return 0;
+}
+
//Getting the version of graphics controller driver via WMI
std::string LLDXHardware::getDriverVersionWMI()
{
@@ -613,6 +634,9 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
IDxDiagContainer *device_containerp = NULL;
IDxDiagContainer *file_containerp = NULL;
IDxDiagContainer *driver_containerp = NULL;
+ DWORD dw_device_count;
+
+ mVRAM = 0;
// CoCreate a IDxDiagProvider*
LL_DEBUGS("AppInit") << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL;
@@ -663,10 +687,21 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp);
if(FAILED(hr) || !devices_containerp)
{
+ // do not release 'dirty' devices_containerp at this stage, only dx_diag_rootp
+ devices_containerp = NULL;
goto LCleanup;
}
+ // make sure there is something inside
+ hr = devices_containerp->GetNumberOfChildContainers(&dw_device_count);
+ if (FAILED(hr) || dw_device_count == 0)
+ {
+ goto LCleanup;
+ }
+
// Get device 0
+ // By default 0 device is the primary one, howhever in case of various hybrid graphics
+ // like itegrated AMD and PCI AMD GPUs system might switch.
LL_DEBUGS("AppInit") << "devices_containerp->GetChildContainer" << LL_ENDL;
hr = devices_containerp->GetChildContainer(L"0", &device_containerp);
if(FAILED(hr) || !device_containerp)
@@ -679,12 +714,27 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
WCHAR deviceID[512];
get_wstring(device_containerp, L"szDeviceID", deviceID, 512);
-
+ // Example: searches id like 1F06 in pnp string (aka VEN_10DE&DEV_1F06)
+ // doesn't seem to work on some systems since format is unrecognizable
+ // but in such case keyDeviceID works
if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID, &vram)))
{
mVRAM = vram/(1024*1024);
}
else
+ {
+ get_wstring(device_containerp, L"szKeyDeviceID", deviceID, 512);
+ LL_WARNS() << "szDeviceID" << deviceID << LL_ENDL;
+ // '+9' to avoid ENUM\\PCI\\ prefix
+ // Returns string like Enum\\PCI\\VEN_10DE&DEV_1F06&SUBSYS...
+ // and since GetVideoMemoryViaWMI searches by PNPDeviceID it is sufficient
+ if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID + 9, &vram)))
+ {
+ mVRAM = vram / (1024 * 1024);
+ }
+ }
+
+ if (mVRAM == 0)
{ // Get the English VRAM string
std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish");
@@ -872,6 +922,7 @@ LLSD LLDXHardware::getDisplayInfo()
IDxDiagContainer *device_containerp = NULL;
IDxDiagContainer *file_containerp = NULL;
IDxDiagContainer *driver_containerp = NULL;
+ DWORD dw_device_count;
// CoCreate a IDxDiagProvider*
LL_INFOS() << "CoCreateInstance IID_IDxDiagProvider" << LL_ENDL;
@@ -922,9 +973,18 @@ LLSD LLDXHardware::getDisplayInfo()
hr = dx_diag_rootp->GetChildContainer(L"DxDiag_DisplayDevices", &devices_containerp);
if(FAILED(hr) || !devices_containerp)
{
+ // do not release 'dirty' devices_containerp at this stage, only dx_diag_rootp
+ devices_containerp = NULL;
goto LCleanup;
}
+ // make sure there is something inside
+ hr = devices_containerp->GetNumberOfChildContainers(&dw_device_count);
+ if (FAILED(hr) || dw_device_count == 0)
+ {
+ goto LCleanup;
+ }
+
// Get device 0
LL_INFOS() << "devices_containerp->GetChildContainer" << LL_ENDL;
hr = devices_containerp->GetChildContainer(L"0", &device_containerp);
@@ -976,6 +1036,10 @@ LLSD LLDXHardware::getDisplayInfo()
}
LCleanup:
+ if (ret.emptyMap())
+ {
+ LL_INFOS() << "Failed to get data, cleaning up" << LL_ENDL;
+ }
SAFE_RELEASE(file_containerp);
SAFE_RELEASE(driver_containerp);
SAFE_RELEASE(device_containerp);
diff --git a/indra/llwindow/lldxhardware.h b/indra/llwindow/lldxhardware.h
index cf33db8b37..1cb687e3b6 100644
--- a/indra/llwindow/lldxhardware.h
+++ b/indra/llwindow/lldxhardware.h
@@ -94,6 +94,10 @@ public:
LLSD getDisplayInfo();
+ // Will get memory of best GPU in MB, return memory on sucsess, 0 on failure
+ // Note: WMI is not accurate in some cases
+ static S32 getMBVideoMemoryViaWMI();
+
// Find a particular device that matches the following specs.
// Empty strings indicate that you don't care.
// You can separate multiple devices with '|' chars to indicate you want
diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp
index f6f6c3931c..5404ac50e5 100644
--- a/indra/llwindow/llkeyboard.cpp
+++ b/indra/llwindow/llkeyboard.cpp
@@ -327,7 +327,7 @@ BOOL LLKeyboard::keyFromString(const std::string& str, KEY *key)
// static
-std::string LLKeyboard::stringFromKey(KEY key)
+std::string LLKeyboard::stringFromKey(KEY key, bool translate)
{
std::string res = get_if_there(sKeysToNames, key, std::string());
if (res.empty())
@@ -338,16 +338,60 @@ std::string LLKeyboard::stringFromKey(KEY key)
res = std::string(buffer);
}
- LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator;
- if (trans != NULL)
+ if (translate)
{
- res = trans(res.c_str());
+ LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator;
+ if (trans != NULL)
+ {
+ res = trans(res.c_str());
+ }
}
return res;
}
+//static
+std::string LLKeyboard::stringFromAccelerator(MASK accel_mask)
+{
+ std::string res;
+
+ LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator;
+
+ if (trans == NULL)
+ {
+ LL_ERRS() << "No mKeyStringTranslator" << LL_ENDL;
+ return res;
+ }
+ // Append any masks
+#ifdef LL_DARWIN
+ // Standard Mac names for modifier keys in menu equivalents
+ // We could use the symbol characters, but they only exist in certain fonts.
+ if (accel_mask & MASK_CONTROL)
+ {
+ if (accel_mask & MASK_MAC_CONTROL)
+ {
+ res.append(trans("accel-mac-control"));
+ }
+ else
+ {
+ res.append(trans("accel-mac-command")); // Symbol would be "\xE2\x8C\x98"
+ }
+ }
+ if (accel_mask & MASK_ALT)
+ res.append(trans("accel-mac-option")); // Symbol would be "\xE2\x8C\xA5"
+ if (accel_mask & MASK_SHIFT)
+ res.append(trans("accel-mac-shift")); // Symbol would be "\xE2\x8C\xA7"
+#else
+ if (accel_mask & MASK_CONTROL)
+ res.append(trans("accel-win-control"));
+ if (accel_mask & MASK_ALT)
+ res.append(trans("accel-win-alt"));
+ if (accel_mask & MASK_SHIFT)
+ res.append(trans("accel-win-shift"));
+#endif
+ return res;
+}
//static
std::string LLKeyboard::stringFromAccelerator( MASK accel_mask, KEY key )
{
@@ -359,41 +403,7 @@ std::string LLKeyboard::stringFromAccelerator( MASK accel_mask, KEY key )
return res;
}
- LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator;
-
- if( trans == NULL )
- {
- LL_ERRS() << "No mKeyStringTranslator" << LL_ENDL;
- return res;
- }
-
- // Append any masks
-#ifdef LL_DARWIN
- // Standard Mac names for modifier keys in menu equivalents
- // We could use the symbol characters, but they only exist in certain fonts.
- if( accel_mask & MASK_CONTROL )
- {
- if ( accel_mask & MASK_MAC_CONTROL )
- {
- res.append( trans("accel-mac-control") );
- }
- else
- {
- res.append( trans("accel-mac-command") ); // Symbol would be "\xE2\x8C\x98"
- }
- }
- if( accel_mask & MASK_ALT )
- res.append( trans("accel-mac-option") ); // Symbol would be "\xE2\x8C\xA5"
- if( accel_mask & MASK_SHIFT )
- res.append( trans("accel-mac-shift") ); // Symbol would be "\xE2\x8C\xA7"
-#else
- if( accel_mask & MASK_CONTROL )
- res.append( trans("accel-win-control") );
- if( accel_mask & MASK_ALT )
- res.append( trans("accel-win-alt") );
- if( accel_mask & MASK_SHIFT )
- res.append( trans("accel-win-shift") );
-#endif
+ res.append(stringFromAccelerator(accel_mask));
std::string key_string = LLKeyboard::stringFromKey(key);
if ((accel_mask & MASK_NORMALKEYS) &&
(key_string[0] == '-' || key_string[0] == '=' || key_string[0] == '+'))
diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h
index 6f2dc87317..36bd8bcbed 100644
--- a/indra/llwindow/llkeyboard.h
+++ b/indra/llwindow/llkeyboard.h
@@ -38,10 +38,10 @@ enum EKeystate
{
KEYSTATE_DOWN,
KEYSTATE_LEVEL,
- KEYSTATE_UP
+ KEYSTATE_UP
};
-typedef boost::function<void(EKeystate keystate)> LLKeyFunc;
+typedef boost::function<bool(EKeystate keystate)> LLKeyFunc;
typedef std::string (LLKeyStringTranslatorFunc)(const char *label);
enum EKeyboardInsertMode
@@ -50,15 +50,6 @@ enum EKeyboardInsertMode
LL_KIM_OVERWRITE
};
-class LLKeyBinding
-{
-public:
- KEY mKey;
- MASK mMask;
-// const char *mName; // unused
- LLKeyFunc mFunction;
-};
-
class LLWindowCallbacks;
class LLKeyboard
@@ -103,7 +94,8 @@ public:
static BOOL maskFromString(const std::string& str, MASK *mask); // False on failure
static BOOL keyFromString(const std::string& str, KEY *key); // False on failure
- static std::string stringFromKey(KEY key);
+ static std::string stringFromKey(KEY key, bool translate = true);
+ static std::string stringFromAccelerator( MASK accel_mask ); // separated for convinience, returns with "+": "Shift+" or "Shift+Alt+"...
static std::string stringFromAccelerator( MASK accel_mask, KEY key );
void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; }
diff --git a/indra/llwindow/llmousehandler.cpp b/indra/llwindow/llmousehandler.cpp
index d5fa65fe4b..e41ebd42f3 100644
--- a/indra/llwindow/llmousehandler.cpp
+++ b/indra/llwindow/llmousehandler.cpp
@@ -27,7 +27,7 @@
#include "llmousehandler.h"
//virtual
-BOOL LLMouseHandler::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down)
+BOOL LLMouseHandler::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down)
{
BOOL handled = FALSE;
if (down)
diff --git a/indra/llwindow/llmousehandler.h b/indra/llwindow/llmousehandler.h
index 8e6fbdb4e3..d221dd117c 100644
--- a/indra/llwindow/llmousehandler.h
+++ b/indra/llwindow/llmousehandler.h
@@ -29,6 +29,7 @@
#include "linden_common.h"
#include "llrect.h"
+#include "indra_constants.h"
// Mostly-abstract interface.
// Intended for use via multiple inheritance.
@@ -46,16 +47,7 @@ public:
SHOW_ALWAYS,
} EShowToolTip;
- typedef enum {
- CLICK_LEFT,
- CLICK_MIDDLE,
- CLICK_RIGHT,
- CLICK_BUTTON4,
- CLICK_BUTTON5,
- CLICK_DOUBLELEFT
- } EClickType;
-
- virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down);
+ virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask) = 0;
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask) = 0;
virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask) = 0;
@@ -66,6 +58,7 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask) = 0;
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks) = 0;
+ virtual BOOL handleScrollHWheel(S32 x, S32 y, S32 clicks) = 0;
virtual BOOL handleToolTip(S32 x, S32 y, MASK mask) = 0;
virtual const std::string& getName() const = 0;
diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm
index 1b0b9213a5..d2c5b11c3d 100644
--- a/indra/llwindow/llopenglview-objc.mm
+++ b/indra/llwindow/llopenglview-objc.mm
@@ -359,10 +359,10 @@ attributedStringInfo getSegments(NSAttributedString *str)
callRightMouseDown(mMousePos, [theEvent modifierFlags]);
mSimulatedRightClick = true;
} else {
- if ([theEvent clickCount] >= 2)
+ if ([theEvent clickCount] == 2)
{
callDoubleClick(mMousePos, [theEvent modifierFlags]);
- } else if ([theEvent clickCount] == 1) {
+ } else if ([theEvent clickCount] >= 1) {
callLeftMouseDown(mMousePos, [theEvent modifierFlags]);
}
}
@@ -467,7 +467,7 @@ attributedStringInfo getSegments(NSAttributedString *str)
- (void) scrollWheel:(NSEvent *)theEvent
{
- callScrollMoved(-[theEvent deltaY]);
+ callScrollMoved(-[theEvent deltaX], -[theEvent deltaY]);
}
- (void) mouseExited:(NSEvent *)theEvent
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index 1b24250618..30bc743e72 100644
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -263,6 +263,18 @@ std::vector<std::string> LLWindow::getDynamicFallbackFontList()
#endif
}
+// static
+std::vector<std::string> LLWindow::getDisplaysResolutionList()
+{
+#if LL_WINDOWS
+ return LLWindowWin32::getDisplaysResolutionList();
+#elif LL_DARWIN
+ return LLWindowMacOSX::getDisplaysResolutionList();
+#else
+ return std::vector<std::string>();
+#endif
+}
+
#define UTF16_IS_HIGH_SURROGATE(U) ((U16)((U) - 0xD800) < 0x0400)
#define UTF16_IS_LOW_SURROGATE(U) ((U16)((U) - 0xDC00) < 0x0400)
#define UTF16_SURROGATE_PAIR_TO_UTF32(H,L) (((H) << 10) + (L) - (0xD800 << 10) - 0xDC00 + 0x00010000)
@@ -457,9 +469,8 @@ LLCoordCommon LL_COORD_TYPE_WINDOW::convertToCommon() const
{
const LLCoordWindow& self = LLCoordWindow::getTypedCoords(*this);
- LLWindow* windowp = &(*LLWindow::beginInstances());
LLCoordGL out;
- windowp->convertCoords(self, &out);
+ LLWindow::instance_snapshot().begin()->convertCoords(self, &out);
return out.convert();
}
@@ -467,18 +478,16 @@ void LL_COORD_TYPE_WINDOW::convertFromCommon(const LLCoordCommon& from)
{
LLCoordWindow& self = LLCoordWindow::getTypedCoords(*this);
- LLWindow* windowp = &(*LLWindow::beginInstances());
LLCoordGL from_gl(from);
- windowp->convertCoords(from_gl, &self);
+ LLWindow::instance_snapshot().begin()->convertCoords(from_gl, &self);
}
LLCoordCommon LL_COORD_TYPE_SCREEN::convertToCommon() const
{
const LLCoordScreen& self = LLCoordScreen::getTypedCoords(*this);
- LLWindow* windowp = &(*LLWindow::beginInstances());
LLCoordGL out;
- windowp->convertCoords(self, &out);
+ LLWindow::instance_snapshot().begin()->convertCoords(self, &out);
return out.convert();
}
@@ -486,7 +495,6 @@ void LL_COORD_TYPE_SCREEN::convertFromCommon(const LLCoordCommon& from)
{
LLCoordScreen& self = LLCoordScreen::getTypedCoords(*this);
- LLWindow* windowp = &(*LLWindow::beginInstances());
LLCoordGL from_gl(from);
- windowp->convertCoords(from_gl, &self);
+ LLWindow::instance_snapshot().begin()->convertCoords(from_gl, &self);
}
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index a05ba8cbba..d4d5b76937 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -168,6 +168,12 @@ public:
// Get system UI size based on DPI (for 96 DPI UI size should be 1.0)
virtual F32 getSystemUISize() { return 1.0; }
+
+ static std::vector<std::string> getDisplaysResolutionList();
+
+ // windows only DirectInput8 for joysticks
+ virtual void* getDirectInput8() { return NULL; };
+ virtual bool getInputDevices(U32 device_type_filter, void * devices_callback, void* userdata) { return false; };
protected:
LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags);
virtual ~LLWindow();
diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp
index c01f574375..be61e1e16c 100644
--- a/indra/llwindow/llwindowcallbacks.cpp
+++ b/indra/llwindow/llwindowcallbacks.cpp
@@ -130,6 +130,10 @@ void LLWindowCallbacks::handleScrollWheel(LLWindow *window, S32 clicks)
{
}
+void LLWindowCallbacks::handleScrollHWheel(LLWindow *window, S32 clicks)
+{
+}
+
void LLWindowCallbacks::handleResize(LLWindow *window, const S32 width, const S32 height)
{
}
diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h
index 9304446f8f..3b18648138 100644
--- a/indra/llwindow/llwindowcallbacks.h
+++ b/indra/llwindow/llwindowcallbacks.h
@@ -56,6 +56,7 @@ public:
virtual void handleMouseMove(LLWindow *window, LLCoordGL pos, MASK mask);
virtual void handleMouseDragged(LLWindow *window, LLCoordGL pos, MASK mask);
virtual void handleScrollWheel(LLWindow *window, S32 clicks);
+ virtual void handleScrollHWheel(LLWindow *window, S32 clicks);
virtual void handleResize(LLWindow *window, S32 width, S32 height);
virtual void handleFocus(LLWindow *window);
virtual void handleFocusLost(LLWindow *window);
diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h
index 0f77ebe7a4..44fd4127ce 100644
--- a/indra/llwindow/llwindowmacosx-objc.h
+++ b/indra/llwindow/llwindowmacosx-objc.h
@@ -142,7 +142,7 @@ void callDoubleClick(float *pos, unsigned int mask);
void callResize(unsigned int width, unsigned int height);
void callMouseMoved(float *pos, unsigned int mask);
void callMouseDragged(float *pos, unsigned int mask);
-void callScrollMoved(float delta);
+void callScrollMoved(float deltaX, float deltaY);
void callMouseExit();
void callWindowFocus();
void callWindowUnfocus();
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index d9b95d311a..0d0607a0bb 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -41,6 +41,7 @@
#include <OpenGL/OpenGL.h>
#include <Carbon/Carbon.h>
#include <CoreServices/CoreServices.h>
+#include <CoreGraphics/CGDisplayConfiguration.h>
extern BOOL gDebugWindowProc;
BOOL gHiDPISupport = TRUE;
@@ -356,9 +357,13 @@ void callMouseDragged(float *pos, MASK mask)
gWindowImplementation->getCallbacks()->handleMouseDragged(gWindowImplementation, outCoords, gKeyboard->currentMask(TRUE));
}
-void callScrollMoved(float delta)
+void callScrollMoved(float deltaX, float deltaY)
{
- gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, delta);
+ if ( gWindowImplementation && gWindowImplementation->getCallbacks() )
+ {
+ gWindowImplementation->getCallbacks()->handleScrollHWheel(gWindowImplementation, deltaX);
+ gWindowImplementation->getCallbacks()->handleScrollWheel(gWindowImplementation, deltaY);
+ }
}
void callMouseExit()
@@ -1907,6 +1912,35 @@ void LLWindowMacOSX::interruptLanguageTextInput()
commitCurrentPreedit(mGLView);
}
+std::vector<std::string> LLWindowMacOSX::getDisplaysResolutionList()
+{
+ std::vector<std::string> resolution_list;
+
+ CGDirectDisplayID display_ids[10];
+ uint32_t found_displays = 0;
+ CGError err = CGGetActiveDisplayList(10, display_ids, &found_displays);
+
+ if (kCGErrorSuccess != err)
+ {
+ LL_WARNS() << "Couldn't get a list of active displays" << LL_ENDL;
+ return std::vector<std::string>();
+ }
+
+ for (uint32_t i = 0; i < found_displays; i++)
+ {
+ S32 monitor_width = CGDisplayPixelsWide(display_ids[i]);
+ S32 monitor_height = CGDisplayPixelsHigh(display_ids[i]);
+
+ std::ostringstream sstream;
+ sstream << monitor_width << "x" << monitor_height;;
+ std::string res = sstream.str();
+
+ resolution_list.push_back(res);
+ }
+
+ return resolution_list;
+}
+
//static
std::vector<std::string> LLWindowMacOSX::getDynamicFallbackFontList()
{
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 24651027e8..bf45238c8d 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -114,6 +114,8 @@ public:
/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
/*virtual*/ F32 getSystemUISize();
+ static std::vector<std::string> getDisplaysResolutionList();
+
static std::vector<std::string> getDynamicFallbackFontList();
// Provide native key event data
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index c20e639fc7..85eb9d6d1b 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -51,13 +51,13 @@ extern "C" {
# include "fontconfig/fontconfig.h"
}
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
// not necessarily available on random SDL platforms, so #if LL_LINUX
// for execv(), waitpid(), fork()
# include <unistd.h>
# include <sys/types.h>
# include <sys/wait.h>
-#endif // LL_LINUX || LL_SOLARIS
+#endif // LL_LINUX
extern BOOL gDebugWindowProc;
@@ -323,12 +323,6 @@ static int x11_detect_VRAM_kb_fp(FILE *fp, const char *prefix_str)
static int x11_detect_VRAM_kb()
{
-#if LL_SOLARIS && defined(__sparc)
- // NOTE: there's no Xorg server on SPARC so just return 0
- // and allow SDL to attempt to get the amount of VRAM
- return(0);
-#else
-
std::string x_log_location("/var/log/");
std::string fname;
int rtn = 0; // 'could not detect'
@@ -409,7 +403,6 @@ static int x11_detect_VRAM_kb()
}
}
return rtn;
-#endif // LL_SOLARIS
}
#endif // LL_X11
@@ -484,27 +477,10 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
-#if !LL_SOLARIS
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, (bits <= 16) ? 16 : 24);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, (bits <= 16) ? 16 : 24);
// We need stencil support for a few (minor) things.
if (!getenv("LL_GL_NO_STENCIL"))
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
-#else
- // NOTE- use smaller Z-buffer to enable more graphics cards
- // - This should not affect better GPUs and has been proven
- // to provide 24-bit z-buffers when available.
- //
- // As the API states:
- //
- // GLX_DEPTH_SIZE Must be followed by a nonnegative
- // minimum size specification. If this
- // value is zero, visuals with no depth
- // buffer are preferred. Otherwise, the
- // largest available depth buffer of at
- // least the minimum size is preferred.
-
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
-#endif
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, (bits <= 16) ? 1 : 8);
// *FIX: try to toggle vsync here?
@@ -682,25 +658,13 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B
// fixme: actually, it's REALLY important for picking that we get at
// least 8 bits each of red,green,blue. Alpha we can be a bit more
// relaxed about if we have to.
-#if LL_SOLARIS && defined(__sparc)
-// again the __sparc required because Xsun support, 32bit are very pricey on SPARC
- if(colorBits < 24) //HACK: on SPARC allow 24-bit color
-#else
if (colorBits < 32)
-#endif
{
close();
setupFailure(
-#if LL_SOLARIS && defined(__sparc)
- "Second Life requires at least 24-bit color on SPARC to run in a window.\n"
- "Please use fbconfig to set your default color depth to 24 bits.\n"
- "You may also need to adjust the X11 setting in SMF. To do so use\n"
- " 'svccfg -s svc:/application/x11/x11-server setprop options/default_depth=24'\n"
-#else
"Second Life requires True Color (32-bit) to run in a window.\n"
"Please go to Control Panels -> Display -> Settings and\n"
"set the screen to 32-bit color.\n"
-#endif
"Alternately, if you choose to run fullscreen, Second Life\n"
"will automatically adjust the screen each time it runs.",
"Error",
@@ -2503,7 +2467,7 @@ BOOL LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b)
}
#endif // LL_GTK
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
// extracted from spawnWebBrowser for clarity and to eliminate
// compiler confusion regarding close(int fd) vs. LLWindow::close()
void exec_cmd(const std::string& cmd, const std::string& arg)
@@ -2559,7 +2523,7 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async)
LL_INFOS() << "spawn_web_browser: " << escaped_url << LL_ENDL;
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
# if LL_X11
if (mSDL_Display)
{
@@ -2578,7 +2542,7 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async)
cmd += "launch_url.sh";
arg = escaped_url;
exec_cmd(cmd, arg);
-#endif // LL_LINUX || LL_SOLARIS
+#endif // LL_LINUX
LL_INFOS() << "spawn_web_browser returning." << LL_ENDL;
}
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 8fefb119bc..b2b123f0da 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -38,6 +38,7 @@
// Linden library includes
#include "llerror.h"
+#include "llexception.h"
#include "llfasttimer.h"
#include "llgl.h"
#include "llstring.h"
@@ -59,6 +60,9 @@
#include <dinput.h>
#include <Dbt.h.>
+#include <InitGuid.h> // needed for llurlentry test to build on some systems
+#pragma comment(lib, "dxguid.lib") // needed for llurlentry test to build on some systems
+#pragma comment(lib, "dinput8")
const S32 MAX_MESSAGE_PER_UPDATE = 20;
const S32 BITS_PER_PIXEL = 32;
@@ -76,6 +80,7 @@ const F32 ICON_FLASH_TIME = 0.5f;
extern BOOL gDebugWindowProc;
LPWSTR gIconResource = IDI_APPLICATION;
+LPDIRECTINPUT8 gDirectInput8;
LLW32MsgCallback gAsyncMsgCallback = NULL;
@@ -117,7 +122,7 @@ void show_window_creation_error(const std::string& title)
LL_WARNS("Window") << title << LL_ENDL;
}
-HGLRC SafeCreateContext(HDC hdc)
+HGLRC SafeCreateContext(HDC &hdc)
{
__try
{
@@ -129,6 +134,22 @@ HGLRC SafeCreateContext(HDC hdc)
}
}
+GLuint SafeChoosePixelFormat(HDC &hdc, const PIXELFORMATDESCRIPTOR *ppfd)
+{
+ __try
+ {
+ return ChoosePixelFormat(hdc, ppfd);
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER)
+ {
+ // convert to C++ styled exception
+ // C exception don't allow classes, so it's a regular char array
+ char integer_string[32];
+ sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
+ throw std::exception(integer_string);
+ }
+}
+
//static
BOOL LLWindowWin32::sIsClassRegistered = FALSE;
@@ -400,6 +421,39 @@ LLWinImm::~LLWinImm()
}
+class LLMonitorInfo
+{
+public:
+
+ std::vector<std::string> getResolutionsList() { return mResList; }
+
+ LLMonitorInfo()
+ {
+ EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this);
+ }
+
+private:
+
+ static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData)
+ {
+ int monitor_width = lprcMonitor->right - lprcMonitor->left;
+ int monitor_height = lprcMonitor->bottom - lprcMonitor->top;
+
+ std::ostringstream sstream;
+ sstream << monitor_width << "x" << monitor_height;;
+ std::string res = sstream.str();
+
+ LLMonitorInfo* pThis = reinterpret_cast<LLMonitorInfo*>(pData);
+ pThis->mResList.push_back(res);
+
+ return TRUE;
+ }
+
+ std::vector<std::string> mResList;
+};
+
+static LLMonitorInfo sMonitorInfo;
+
LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
S32 height, U32 flags,
@@ -428,6 +482,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
memset(mCurrentGammaRamp, 0, sizeof(mCurrentGammaRamp));
memset(mPrevGammaRamp, 0, sizeof(mPrevGammaRamp));
mCustomGammaSet = FALSE;
+ mWindowHandle = NULL;
if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &mMouseVanish, 0))
{
@@ -482,6 +537,21 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
mhInstance = GetModuleHandle(NULL);
mWndProc = NULL;
+ // Init Direct Input - needed for joystick / Spacemouse
+
+ LPDIRECTINPUT8 di8_interface;
+ HRESULT status = DirectInput8Create(
+ mhInstance, // HINSTANCE hinst,
+ DIRECTINPUT_VERSION, // DWORD dwVersion,
+ IID_IDirectInput8, // REFIID riidltf,
+ (LPVOID*)&di8_interface, // LPVOID * ppvOut,
+ NULL // LPUNKNOWN punkOuter
+ );
+ if (status == DI_OK)
+ {
+ gDirectInput8 = di8_interface;
+ }
+
mSwapMethod = SWAP_METHOD_UNDEFINED;
// No WPARAM yet.
@@ -676,6 +746,37 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
// TrackMouseEvent( &track_mouse_event );
// }
+ // SL-12971 dual GPU display
+ DISPLAY_DEVICEA display_device;
+ int display_index = -1;
+ DWORD display_flags = 0; // EDD_GET_DEVICE_INTERFACE_NAME ?
+ const size_t display_bytes = sizeof(display_device);
+
+ do
+ {
+ if (display_index >= 0)
+ {
+ // CHAR DeviceName [ 32] Adapter name
+ // CHAR DeviceString[128]
+ CHAR text[256];
+
+ size_t name_len = strlen(display_device.DeviceName );
+ size_t desc_len = strlen(display_device.DeviceString);
+
+ CHAR *name = name_len ? display_device.DeviceName : "???";
+ CHAR *desc = desc_len ? display_device.DeviceString : "???";
+
+ sprintf(text, "Display Device %d: %s, %s", display_index, name, desc);
+ LL_INFOS("Window") << text << LL_ENDL;
+ }
+
+ ::ZeroMemory(&display_device,display_bytes);
+ display_device.cb = display_bytes;
+
+ display_index++;
+ } while( EnumDisplayDevicesA(NULL, display_index, &display_device, display_flags ));
+
+ LL_INFOS("Window") << "Total Display Devices: " << display_index << LL_ENDL;
//-----------------------------------------------------------------------
// Create GL drawing context
@@ -714,6 +815,7 @@ LLWindowWin32::~LLWindowWin32()
void LLWindowWin32::show()
{
+ LL_DEBUGS("Window") << "Setting window to show" << LL_ENDL;
ShowWindow(mWindowHandle, SW_SHOW);
SetForegroundWindow(mWindowHandle);
SetFocus(mWindowHandle);
@@ -741,17 +843,27 @@ void LLWindowWin32::restore()
SetFocus(mWindowHandle);
}
+// See SL-12170
+// According to callstack "c0000005 Access violation" happened inside __try block,
+// deep in DestroyWindow and crashed viewer, which shouldn't be possible.
+// I tried manually causing this exception and it was caught without issues, so
+// I'm turning off optimizations for this part to be sure code executes as intended
+// (it is a straw, but I have no idea why else __try can get overruled)
+#pragma optimize("", off)
bool destroy_window_handler(HWND &hWnd)
{
+ bool res;
__try
{
- return DestroyWindow(hWnd);
+ res = DestroyWindow(hWnd);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
- return false;
+ res = false;
}
+ return res;
}
+#pragma optimize("", on)
// close() destroys all OS-specific code associated with a window.
// Usually called from LLWindowManager::destroyWindow()
@@ -773,9 +885,6 @@ void LLWindowWin32::close()
resetDisplayResolution();
}
- // Don't process events in our mainWindowProc any longer.
- SetWindowLongPtr(mWindowHandle, GWLP_USERDATA, NULL);
-
// Make sure cursor is visible and we haven't mangled the clipping state.
showCursor();
setMouseClipping(FALSE);
@@ -821,16 +930,24 @@ void LLWindowWin32::close()
LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL;
- // Make sure we don't leave a blank toolbar button.
- ShowWindow(mWindowHandle, SW_HIDE);
+ if (IsWindow(mWindowHandle))
+ {
+ // Make sure we don't leave a blank toolbar button.
+ ShowWindow(mWindowHandle, SW_HIDE);
- // This causes WM_DESTROY to be sent *immediately*
- if (!destroy_window_handler(mWindowHandle))
- {
- OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
- mCallbacks->translateString("MBShutdownErr"),
- OSMB_OK);
- }
+ // This causes WM_DESTROY to be sent *immediately*
+ if (!destroy_window_handler(mWindowHandle))
+ {
+ OSMessageBox(mCallbacks->translateString("MBDestroyWinFailed"),
+ mCallbacks->translateString("MBShutdownErr"),
+ OSMB_OK);
+ }
+ }
+ else
+ {
+ // Something killed the window while we were busy destroying gl or handle somehow got broken
+ LL_WARNS("Window") << "Failed to destroy Window, invalid handle!" << LL_ENDL;
+ }
mWindowHandle = NULL;
}
@@ -1116,7 +1233,16 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
mPostQuit = FALSE;
// create window
- DestroyWindow(mWindowHandle);
+ LL_DEBUGS("Window") << "Creating window with X: " << window_rect.left
+ << " Y: " << window_rect.top
+ << " Width: " << (window_rect.right - window_rect.left)
+ << " Height: " << (window_rect.bottom - window_rect.top)
+ << " Fullscreen: " << mFullscreen
+ << LL_ENDL;
+ if (mWindowHandle && !destroy_window_handler(mWindowHandle))
+ {
+ LL_WARNS("Window") << "Failed to properly close window before recreating it!" << LL_ENDL;
+ }
mWindowHandle = CreateWindowEx(dw_ex_style,
mWindowClassName,
mWindowTitle,
@@ -1172,11 +1298,24 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
LL_INFOS("Window") << "Device context retrieved." << LL_ENDL ;
- if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd)))
+ try
+ {
+ // Looks like ChoosePixelFormat can crash in case of faulty driver
+ if (!(pixel_format = SafeChoosePixelFormat(mhDC, &pfd)))
{
+ LL_WARNS("Window") << "ChoosePixelFormat failed, code: " << GetLastError() << LL_ENDL;
+ OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"),
+ mCallbacks->translateString("MBError"), OSMB_OK);
close();
+ return FALSE;
+ }
+ }
+ catch (...)
+ {
+ LOG_UNHANDLED_EXCEPTION("ChoosePixelFormat");
OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"),
mCallbacks->translateString("MBError"), OSMB_OK);
+ close();
return FALSE;
}
@@ -1405,21 +1544,27 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
LL_INFOS("Window") << "pixel formats done." << LL_ENDL ;
S32 swap_method = 0;
- S32 cur_format = num_formats-1;
+ S32 cur_format = 0;
+const S32 max_format = (S32)num_formats - 1;
GLint swap_query = WGL_SWAP_METHOD_ARB;
- BOOL found_format = FALSE;
-
- while (!found_format && wglGetPixelFormatAttribivARB(mhDC, pixel_format, 0, 1, &swap_query, &swap_method))
+ // SL-14705 Fix name tags showing in front of objects with AMD GPUs.
+ // On AMD hardware we need to iterate from the first pixel format to the end.
+ // Spec:
+ // https://www.khronos.org/registry/OpenGL/extensions/ARB/WGL_ARB_pixel_format.txt
+ while (wglGetPixelFormatAttribivARB(mhDC, pixel_formats[cur_format], 0, 1, &swap_query, &swap_method))
{
- if (swap_method == WGL_SWAP_UNDEFINED_ARB || cur_format <= 0)
+ if (swap_method == WGL_SWAP_UNDEFINED_ARB)
{
- found_format = TRUE;
+ break;
}
- else
+ else if (cur_format >= max_format)
{
- --cur_format;
+ cur_format = 0;
+ break;
}
+
+ ++cur_format;
}
pixel_format = pixel_formats[cur_format];
@@ -1436,8 +1581,12 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
ReleaseDC (mWindowHandle, mhDC); // Release The Device Context
mhDC = 0; // Zero The Device Context
}
- DestroyWindow (mWindowHandle); // Destroy The Window
-
+
+ // Destroy The Window
+ if (mWindowHandle && !destroy_window_handler(mWindowHandle))
+ {
+ LL_WARNS("Window") << "Failed to properly close window!" << LL_ENDL;
+ }
mWindowHandle = CreateWindowEx(dw_ex_style,
mWindowClassName,
@@ -1931,6 +2080,8 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLongPtr( h_wnd, GWLP_USERDATA );
+ bool debug_window_proc = gDebugWindowProc || debugLoggingEnabled("Window");
+
if (NULL != window_imp)
{
@@ -1973,9 +2124,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_DEVICECHANGE:
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_DEVICECHANGE");
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
- LL_INFOS() << " WM_DEVICECHANGE: wParam=" << w_param
+ LL_INFOS("Window") << " WM_DEVICECHANGE: wParam=" << w_param
<< "; lParam=" << l_param << LL_ENDL;
}
if (w_param == DBT_DEVNODES_CHANGED || w_param == DBT_DEVICEARRIVAL)
@@ -2031,7 +2182,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
BOOL activating = (BOOL) w_param;
BOOL minimized = window_imp->getMinimized();
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
LL_INFOS("Window") << "WINDOWPROC ActivateApp "
<< " activating " << S32(activating)
@@ -2082,7 +2233,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// JC - I'm not sure why, but if we don't report that we handled the
// WM_ACTIVATE message, the WM_ACTIVATEAPP messages don't work
// properly when we run fullscreen.
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
LL_INFOS("Window") << "WINDOWPROC Activate "
<< " activating " << S32(activating)
@@ -2154,7 +2305,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYDOWN");
{
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
LL_INFOS("Window") << "Debug WindowProc WM_KEYDOWN "
<< " key " << S32(w_param)
@@ -2180,7 +2331,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_KEYUP");
LL_RECORD_BLOCK_TIME(FTM_KEYHANDLER);
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
LL_INFOS("Window") << "Debug WindowProc WM_KEYUP "
<< " key " << S32(w_param)
@@ -2196,9 +2347,9 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
}
case WM_IME_SETCONTEXT:
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_SETCONTEXT");
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
- LL_INFOS() << "WM_IME_SETCONTEXT" << LL_ENDL;
+ LL_INFOS("Window") << "WM_IME_SETCONTEXT" << LL_ENDL;
}
if (LLWinImm::isAvailable() && window_imp->mPreeditor)
{
@@ -2209,7 +2360,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_STARTCOMPOSITION:
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_STARTCOMPOSITION");
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
LL_INFOS() << "WM_IME_STARTCOMPOSITION" << LL_ENDL;
}
@@ -2222,7 +2373,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_ENDCOMPOSITION:
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_ENDCOMPOSITION");
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
LL_INFOS() << "WM_IME_ENDCOMPOSITION" << LL_ENDL;
}
@@ -2234,7 +2385,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_COMPOSITION:
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_COMPOSITION");
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
LL_INFOS() << "WM_IME_COMPOSITION" << LL_ENDL;
}
@@ -2247,7 +2398,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
case WM_IME_REQUEST:
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_IME_REQUEST");
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
LL_INFOS() << "WM_IME_REQUEST" << LL_ENDL;
}
@@ -2278,7 +2429,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// characters. We just need to take care of surrogate pairs sent as two WM_CHAR's
// by ourselves. It is not that tough. -- Alissa Sabre @ SL
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_CHAR");
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
LL_INFOS("Window") << "Debug WindowProc WM_CHAR "
<< " key " << S32(w_param)
@@ -2662,6 +2813,42 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
return 0;
}
*/
+ case WM_MOUSEHWHEEL:
+ {
+ window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_MOUSEHWHEEL");
+ static short h_delta = 0;
+
+ RECT client_rect;
+
+ // eat scroll events that occur outside our window, since we use mouse position to direct scroll
+ // instead of keyboard focus
+ // NOTE: mouse_coord is in *window* coordinates for scroll events
+ POINT mouse_coord = {(S32)(S16)LOWORD(l_param), (S32)(S16)HIWORD(l_param)};
+
+ if (ScreenToClient(window_imp->mWindowHandle, &mouse_coord)
+ && GetClientRect(window_imp->mWindowHandle, &client_rect))
+ {
+ // we have a valid mouse point and client rect
+ if (mouse_coord.x < client_rect.left || client_rect.right < mouse_coord.x
+ || mouse_coord.y < client_rect.top || client_rect.bottom < mouse_coord.y)
+ {
+ // mouse is outside of client rect, so don't do anything
+ return 0;
+ }
+ }
+
+ S16 incoming_h_delta = HIWORD(w_param);
+ h_delta += incoming_h_delta;
+
+ // If the user rapidly spins the wheel, we can get messages with
+ // large deltas, like 480 or so. Thus we need to scroll more quickly.
+ if (h_delta <= -WHEEL_DELTA || WHEEL_DELTA <= h_delta)
+ {
+ window_imp->mCallbacks->handleScrollHWheel(window_imp, h_delta / WHEEL_DELTA);
+ h_delta = 0;
+ }
+ return 0;
+ }
// Handle mouse movement within the window
case WM_MOUSEMOVE:
{
@@ -2685,7 +2872,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
S32 width = S32( LOWORD(l_param) );
S32 height = S32( HIWORD(l_param) );
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
BOOL maximized = ( w_param == SIZE_MAXIMIZED );
BOOL restored = ( w_param == SIZE_RESTORED );
@@ -2760,7 +2947,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
}
case WM_SETFOCUS:
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
LL_INFOS("Window") << "WINDOWPROC SetFocus" << LL_ENDL;
}
@@ -2769,7 +2956,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
return 0;
case WM_KILLFOCUS:
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
LL_INFOS("Window") << "WINDOWPROC KillFocus" << LL_ENDL;
}
@@ -2801,7 +2988,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
break;
default:
{
- if (gDebugWindowProc)
+ if (debug_window_proc)
{
LL_INFOS("Window") << "Unhandled windows message code: " << U32(u_msg) << LL_ENDL;
}
@@ -2811,7 +2998,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->mCallbacks->handlePauseWatchdog(window_imp);
}
-
+ else
+ {
+ // (NULL == window_imp)
+ LL_DEBUGS("Window") << "No window implementation to handle message with, message code: " << U32(u_msg) << LL_ENDL;
+ }
// pass unhandled messages down to Windows
return DefWindowProc(h_wnd, u_msg, w_param, l_param);
@@ -3338,7 +3529,10 @@ void LLSplashScreenWin32::hideImpl()
{
if (mWindow)
{
- DestroyWindow(mWindow);
+ if (!destroy_window_handler(mWindow))
+ {
+ LL_WARNS("Window") << "Failed to properly close splash screen window!" << LL_ENDL;
+ }
mWindow = NULL;
}
}
@@ -4111,6 +4305,28 @@ void LLWindowWin32::setDPIAwareness()
}
}
+void* LLWindowWin32::getDirectInput8()
+{
+ return &gDirectInput8;
+}
+
+bool LLWindowWin32::getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata)
+{
+ if (gDirectInput8 != NULL)
+ {
+ // Enumerate devices
+ 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*)userdata, // LPVOID pvRef
+ DIEDFL_ATTACHEDONLY // DWORD dwFlags
+ );
+
+ return status == DI_OK;
+ }
+ return false;
+}
+
F32 LLWindowWin32::getSystemUISize()
{
F32 scale_value = 1.f;
@@ -4173,6 +4389,12 @@ F32 LLWindowWin32::getSystemUISize()
}
//static
+std::vector<std::string> LLWindowWin32::getDisplaysResolutionList()
+{
+ return sMonitorInfo.getResolutionsList();
+}
+
+//static
std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()
{
// Fonts previously in getFontListSans() have moved to fonts.xml.
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 9cd16eb993..0b3d14fb16 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -114,8 +114,12 @@ public:
LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url );
+ static std::vector<std::string> getDisplaysResolutionList();
static std::vector<std::string> getDynamicFallbackFontList();
static void setDPIAwareness();
+
+ /*virtual*/ void* getDirectInput8();
+ /*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,