summaryrefslogtreecommitdiff
path: root/indra/llwindow
diff options
context:
space:
mode:
authorCho <cho@lindenlab.com>2014-08-20 01:11:55 +0100
committerCho <cho@lindenlab.com>2014-08-20 01:11:55 +0100
commitd071aeb6f1ff0d98e27e93391f004d6ff947e3b1 (patch)
treefaa6d458733c4f6288974ab370d7f480ed73a17c /indra/llwindow
parent89eac2548a9b66d8bab27a7e8d7d1ed2159e9515 (diff)
parentd576e66210c020a8a86bcc88898a352bc0875d9a (diff)
merge
Diffstat (limited to 'indra/llwindow')
-rwxr-xr-xindra/llwindow/lldxhardware.cpp178
-rwxr-xr-xindra/llwindow/llwindowwin32.cpp34
2 files changed, 205 insertions, 7 deletions
diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp
index ba5bc8fcfb..e7afef63f8 100755
--- a/indra/llwindow/lldxhardware.cpp
+++ b/indra/llwindow/lldxhardware.cpp
@@ -34,9 +34,12 @@
#include <dxdiag.h>
#undef INITGUID
+#include <wbemidl.h>
+
#include <boost/tokenizer.hpp>
#include "lldxhardware.h"
+
#include "llerror.h"
#include "llstring.h"
@@ -53,11 +56,160 @@ LLDXHardware gDXHardware;
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
-std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName)
+typedef BOOL ( WINAPI* PfnCoSetProxyBlanket )( IUnknown* pProxy, DWORD dwAuthnSvc, DWORD dwAuthzSvc,
+ OLECHAR* pServerPrincName, DWORD dwAuthnLevel, DWORD dwImpLevel,
+ RPC_AUTH_IDENTITY_HANDLE pAuthInfo, DWORD dwCapabilities );
+
+HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam )
{
HRESULT hr;
+ bool bGotMemory = false;
+ HRESULT hrCoInitialize = S_OK;
+ IWbemLocator* pIWbemLocator = nullptr;
+ IWbemServices* pIWbemServices = nullptr;
+ BSTR pNamespace = nullptr;
+
+ *pdwAdapterRam = 0;
+ hrCoInitialize = CoInitialize( 0 );
+
+ hr = CoCreateInstance( CLSID_WbemLocator,
+ nullptr,
+ CLSCTX_INPROC_SERVER,
+ IID_IWbemLocator,
+ ( LPVOID* )&pIWbemLocator );
+#ifdef PRINTF_DEBUGGING
+ if( FAILED( hr ) ) wprintf( L"WMI: CoCreateInstance failed: 0x%0.8x\n", hr );
+#endif
+
+ if( SUCCEEDED( hr ) && pIWbemLocator )
+ {
+ // Using the locator, connect to WMI in the given namespace.
+ pNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );
+
+ hr = pIWbemLocator->ConnectServer( pNamespace, nullptr, nullptr, 0L,
+ 0L, nullptr, nullptr, &pIWbemServices );
+#ifdef PRINTF_DEBUGGING
+ if( FAILED( hr ) ) wprintf( L"WMI: pIWbemLocator->ConnectServer failed: 0x%0.8x\n", hr );
+#endif
+ if( SUCCEEDED( hr ) && pIWbemServices != 0 )
+ {
+ HINSTANCE hinstOle32 = nullptr;
+
+ hinstOle32 = LoadLibraryW( L"ole32.dll" );
+ if( hinstOle32 )
+ {
+ PfnCoSetProxyBlanket pfnCoSetProxyBlanket = nullptr;
+
+ pfnCoSetProxyBlanket = ( PfnCoSetProxyBlanket )GetProcAddress( hinstOle32, "CoSetProxyBlanket" );
+ if( pfnCoSetProxyBlanket != 0 )
+ {
+ // Switch security level to IMPERSONATE.
+ pfnCoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr,
+ RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, 0 );
+ }
+
+ FreeLibrary( hinstOle32 );
+ }
+
+ IEnumWbemClassObject* pEnumVideoControllers = nullptr;
+ BSTR pClassName = nullptr;
+
+ pClassName = SysAllocString( L"Win32_VideoController" );
+
+ hr = pIWbemServices->CreateInstanceEnum( pClassName, 0,
+ nullptr, &pEnumVideoControllers );
+#ifdef PRINTF_DEBUGGING
+ if( FAILED( hr ) ) wprintf( L"WMI: pIWbemServices->CreateInstanceEnum failed: 0x%0.8x\n", hr );
+#endif
+
+ if( SUCCEEDED( hr ) && pEnumVideoControllers )
+ {
+ IWbemClassObject* pVideoControllers[10] = {0};
+ DWORD uReturned = 0;
+ BSTR pPropName = nullptr;
+
+ // Get the first one in the list
+ pEnumVideoControllers->Reset();
+ hr = pEnumVideoControllers->Next( 5000, // timeout in 5 seconds
+ 10, // return the first 10
+ pVideoControllers,
+ &uReturned );
+#ifdef PRINTF_DEBUGGING
+ if( FAILED( hr ) ) wprintf( L"WMI: pEnumVideoControllers->Next failed: 0x%0.8x\n", hr );
+ if( uReturned == 0 ) wprintf( L"WMI: pEnumVideoControllers uReturned == 0\n" );
+#endif
+
+ VARIANT var;
+ if( SUCCEEDED( hr ) )
+ {
+ bool bFound = false;
+ for( UINT iController = 0; iController < uReturned; iController++ )
+ {
+ if ( !pVideoControllers[iController] )
+ continue;
+
+ 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 );
+#endif
+ if( SUCCEEDED( hr ) )
+ {
+ if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 )
+ bFound = true;
+ }
+ VariantClear( &var );
+ if( pPropName ) SysFreeString( pPropName );
+
+ if( bFound )
+ {
+ pPropName = SysAllocString( L"AdapterRAM" );
+ hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr );
+#ifdef PRINTF_DEBUGGING
+ if( FAILED( hr ) )
+ wprintf( L"WMI: pVideoControllers[iController]->Get AdapterRAM failed: 0x%0.8x\n",
+ hr );
+#endif
+ if( SUCCEEDED( hr ) )
+ {
+ bGotMemory = true;
+ *pdwAdapterRam = var.ulVal;
+ }
+ VariantClear( &var );
+ if( pPropName ) SysFreeString( pPropName );
+ break;
+ }
+ SAFE_RELEASE( pVideoControllers[iController] );
+ }
+ }
+ }
+
+ if( pClassName )
+ SysFreeString( pClassName );
+ SAFE_RELEASE( pEnumVideoControllers );
+ }
+
+ if( pNamespace )
+ SysFreeString( pNamespace );
+ SAFE_RELEASE( pIWbemServices );
+ }
+
+ SAFE_RELEASE( pIWbemLocator );
+
+ if( SUCCEEDED( hrCoInitialize ) )
+ CoUninitialize();
+
+ if( bGotMemory )
+ return S_OK;
+ else
+ return E_FAIL;
+}
+
+void get_wstring(IDxDiagContainer* containerp, WCHAR* wszPropName, WCHAR* wszPropValue, int outputSize)
+{
+ HRESULT hr;
VARIANT var;
- WCHAR wszPropValue[256];
VariantInit( &var );
hr = containerp->GetProp(wszPropName, &var );
@@ -76,13 +228,19 @@ std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName)
wcscpy( wszPropValue, (var.boolVal) ? L"true" : L"false" ); /* Flawfinder: ignore */
break;
case VT_BSTR:
- wcsncpy( wszPropValue, var.bstrVal, 255 ); /* Flawfinder: ignore */
- wszPropValue[255] = 0;
+ wcsncpy( wszPropValue, var.bstrVal, outputSize-1 ); /* Flawfinder: ignore */
+ wszPropValue[outputSize-1] = 0;
break;
}
}
// Clear the variant (this is needed to free BSTR memory)
VariantClear( &var );
+}
+
+std::string get_string(IDxDiagContainer *containerp, WCHAR *wszPropName)
+{
+ WCHAR wszPropValue[256];
+ get_wstring(containerp, wszPropName, wszPropValue, 256);
return utf16str_to_utf8str(wszPropValue);
}
@@ -361,8 +519,18 @@ BOOL LLDXHardware::getInfo(BOOL vram_only)
goto LCleanup;
}
- // Get the English VRAM string
+ DWORD vram = 0;
+
+ WCHAR deviceID[512];
+
+ get_wstring(device_containerp, L"szDeviceID", deviceID, 512);
+
+ if (SUCCEEDED(GetVideoMemoryViaWMI(deviceID, &vram)))
{
+ mVRAM = vram/(1024*1024);
+ }
+ else
+ { // Get the English VRAM string
std::string ram_str = get_string(device_containerp, L"szDisplayMemoryEnglish");
// We don't need the device any more
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 19961d5759..cd2be87fad 100755
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -86,6 +86,18 @@ void show_window_creation_error(const std::string& title)
LL_WARNS("Window") << title << LL_ENDL;
}
+HGLRC SafeCreateContext(HDC hdc)
+{
+ __try
+ {
+ return wglCreateContext(hdc);
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ return NULL;
+ }
+}
+
//static
BOOL LLWindowWin32::sIsClassRegistered = FALSE;
@@ -1167,14 +1179,15 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
return FALSE;
}
- if (!(mhRC = wglCreateContext(mhDC)))
+
+ if (!(mhRC = SafeCreateContext(mhDC)))
{
close();
OSMessageBox(mCallbacks->translateString("MBGLContextErr"),
mCallbacks->translateString("MBError"), OSMB_OK);
return FALSE;
}
-
+
if (!wglMakeCurrent(mhDC, mhRC))
{
close();
@@ -1832,6 +1845,10 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
// This helps prevent avatar walking after maximizing the window by double-clicking the title bar.
static bool sHandleLeftMouseUp = true;
+ // Ignore the double click received right after activating app.
+ // This is to avoid triggering double click teleport after returning focus (see MAINT-3786).
+ static bool sHandleDoubleClick = true;
+
LLWindowWin32 *window_imp = (LLWindowWin32 *)GetWindowLong(h_wnd, GWL_USERDATA);
@@ -1959,6 +1976,11 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
}
}
+ if (!activating)
+ {
+ sHandleDoubleClick = false;
+ }
+
window_imp->mCallbacks->handleActivateApp(window_imp, activating);
break;
@@ -2183,6 +2205,7 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_NCLBUTTONDOWN");
// A click in a non-client area, e.g. title bar or window border.
sHandleLeftMouseUp = false;
+ sHandleDoubleClick = true;
}
break;
@@ -2227,6 +2250,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
//case WM_RBUTTONDBLCLK:
{
window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_LBUTTONDBLCLK");
+
+ if (!sHandleDoubleClick)
+ {
+ sHandleDoubleClick = true;
+ break;
+ }
+
// Because we move the cursor position in the app, we need to query
// to find out where the cursor at the time the event is handled.
// If we don't do this, many clicks could get buffered up, and if the