diff options
Diffstat (limited to 'indra/llwindow')
| -rwxr-xr-x | indra/llwindow/lldxhardware.cpp | 178 | ||||
| -rwxr-xr-x | indra/llwindow/llwindow.cpp | 4 | ||||
| -rwxr-xr-x | indra/llwindow/llwindowmacosx.cpp | 27 | ||||
| -rwxr-xr-x | indra/llwindow/llwindowsdl.cpp | 4 | ||||
| -rwxr-xr-x | indra/llwindow/llwindowwin32.cpp | 36 | 
5 files changed, 233 insertions, 16 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/llwindow.cpp b/indra/llwindow/llwindow.cpp index 466c3baccf..5720660034 100755 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -71,7 +71,7 @@ S32 OSMessageBox(const std::string& text, const std::string& caption, U32 type)  	}  	S32 result = 0; -#if LL_MESA_HEADLESS // !!! *FIX: (???) +#if LL_MESA_HEADLESS // !!! *FIX: (?)  	LL_WARNS() << "OSMessageBox: " << text << LL_ENDL;  	return OSBTN_OK;  #elif LL_WINDOWS @@ -323,7 +323,7 @@ bool LLSplashScreen::isVisible()  // static  LLSplashScreen *LLSplashScreen::create()  { -#if LL_MESA_HEADLESS || LL_SDL  // !!! *FIX: (???) +#if LL_MESA_HEADLESS || LL_SDL  // !!! *FIX: (?)  	return 0;  #elif LL_WINDOWS  	return new LLSplashScreenWin32; diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index b771e125f9..18d5152015 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -39,6 +39,7 @@  #include "indra_constants.h"  #include <OpenGL/OpenGL.h> +#include <Carbon/Carbon.h>  #include <CoreServices/CoreServices.h>  extern BOOL gDebugWindowProc; @@ -1743,16 +1744,34 @@ LLSD LLWindowMacOSX::getNativeKeyData()  	return result;  } -  BOOL LLWindowMacOSX::dialogColorPicker( F32 *r, F32 *g, F32 *b)  { -	// Is this even used anywhere?  Do we really need an OS color picker?  	BOOL	retval = FALSE; -	//S32		error = 0; +	OSErr	error = noErr; +	NColorPickerInfo	info; +	 +	memset(&info, 0, sizeof(info)); +	info.theColor.color.rgb.red = (UInt16)(*r * 65535.f); +	info.theColor.color.rgb.green = (UInt16)(*g * 65535.f); +	info.theColor.color.rgb.blue = (UInt16)(*b * 65535.f); +	info.placeWhere = kCenterOnMainScreen; + +	error = NPickColor(&info); +	 +	if (error == noErr) +	{ +		retval = info.newColorChosen; +		if (info.newColorChosen) +		{ +			*r = ((float) info.theColor.color.rgb.red) / 65535.0; +			*g = ((float) info.theColor.color.rgb.green) / 65535.0; +			*b = ((float) info.theColor.color.rgb.blue) / 65535.0; +		} +	} +  	return (retval);  } -  void *LLWindowMacOSX::getPlatformWindow()  {  	// NOTE: this will be NULL in fullscreen mode.  Plan accordingly. diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index bb77a24590..c20e639fc7 100755 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -223,7 +223,7 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks,  	mOriginalAspectRatio = 1024.0 / 768.0;  	if (title.empty()) -		mWindowTitle = "SDL Window";  // *FIX: (???) +		mWindowTitle = "SDL Window";  // *FIX: (?)  	else  		mWindowTitle = title; @@ -956,7 +956,7 @@ BOOL LLWindowSDL::setPosition(const LLCoordScreen position)  {  	if(mWindow)  	{ -        // *FIX: (???) +        // *FIX: (?)  		//MacMoveWindow(mWindow, position.mX, position.mY, false);  	} diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 0637572f67..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; @@ -657,7 +669,7 @@ LLWindowWin32::~LLWindowWin32()  	delete [] mSupportedResolutions;  	mSupportedResolutions = NULL; -	delete mWindowClassName; +	delete [] mWindowClassName;  	mWindowClassName = NULL;  } @@ -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 | 
