diff options
| author | AndreyL ProductEngine <alihatskiy@productengine.com> | 2016-10-10 23:26:58 +0300 | 
|---|---|---|
| committer | AndreyL ProductEngine <alihatskiy@productengine.com> | 2016-10-10 23:26:58 +0300 | 
| commit | 4617e07b3795e46c2037462f738ab81b35bd7294 (patch) | |
| tree | 9cd991fe86f65590f9bb5c87499fab1911e4aae5 /indra/newview | |
| parent | 5dd97bc2bd4924b0342068e697b5d45165225b76 (diff) | |
| parent | 086c1342152895da28d2e0130d09432152604ca8 (diff) | |
Merged in lindenlab/viewer-release
Diffstat (limited to 'indra/newview')
34 files changed, 842 insertions, 671 deletions
| diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 195363fb75..16edd39ecc 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1755,6 +1755,7 @@ if (WINDOWS)        SLPlugin        media_plugin_quicktime        media_plugin_cef +      media_plugin_libvlc        winmm_shim        windows-crash-logger        ) @@ -1970,6 +1971,7 @@ if (LINUX)      linux-crash-logger      SLPlugin      media_plugin_gstreamer010 +    media_plugin_libvlc      llcommon      ) @@ -2077,7 +2079,7 @@ if (DARWIN)        ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py      ) -  add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_cef mac-crash-logger) +  add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_libvlc media_plugin_cef mac-crash-logger)    add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger)    if (ENABLE_SIGNING) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 7919852fe1..4d0dcda01c 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -4.0.9 +4.1.2 diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp index 92a5413adb..1dddf52961 100644 --- a/indra/newview/llaccountingcostmanager.cpp +++ b/indra/newview/llaccountingcostmanager.cpp @@ -31,6 +31,8 @@  #include "llcoros.h"  #include "lleventcoro.h"  #include "llcorehttputil.h" +#include "llexception.h" +#include "stringize.h"  #include <algorithm>  #include <iterator> @@ -154,13 +156,11 @@ void LLAccountingCostManager::accountingCostCoro(std::string url,          } while (false);      } -    catch (std::exception e) -    { -        LL_WARNS() << "Caught exception '" << e.what() << "'" << LL_ENDL; -    }      catch (...)      { -        LL_WARNS() << "Caught unknown exception." << LL_ENDL; +        LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::instance().getName() +                                          << "('" << url << "')")); +        throw;      }      mPendingObjectQuota.clear(); diff --git a/indra/newview/llappcorehttp.cpp b/indra/newview/llappcorehttp.cpp index 49291ea564..c1f898284a 100644 --- a/indra/newview/llappcorehttp.cpp +++ b/indra/newview/llappcorehttp.cpp @@ -30,6 +30,8 @@  #include "llappviewer.h"  #include "llviewercontrol.h" +#include "llexception.h" +#include "stringize.h"  #include <openssl/x509_vfy.h>  #include <openssl/ssl.h> @@ -534,7 +536,7 @@ LLCore::HttpStatus LLAppCoreHttp::sslVerify(const std::string &url,  		// somewhat clumsy, as we may run into errors that do not map directly to curl  		// error codes.  Should be refactored with login refactoring, perhaps.  		result = LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_SSL_CACERT); -		result.setMessage(cert_exception.getMessage()); +		result.setMessage(cert_exception.what());  		LLPointer<LLCertificate> cert = cert_exception.getCert();  		cert->ref(); // adding an extra ref here  		result.setErrorData(cert.get()); @@ -544,13 +546,14 @@ LLCore::HttpStatus LLAppCoreHttp::sslVerify(const std::string &url,  	catch (LLCertException &cert_exception)  	{  		result = LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_SSL_PEER_CERTIFICATE); -		result.setMessage(cert_exception.getMessage()); +		result.setMessage(cert_exception.what());  		LLPointer<LLCertificate> cert = cert_exception.getCert();  		cert->ref(); // adding an extra ref here  		result.setErrorData(cert.get());  	}  	catch (...)  	{ +		LOG_UNHANDLED_EXCEPTION(STRINGIZE("('" << url << "')"));  		// any other odd error, we just handle as a connect error.  		result = LLCore::HttpStatus(LLCore::HttpStatus::EXT_CURL_EASY, CURLE_SSL_CONNECT_ERROR);  	} diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 549df80fa1..be8877328d 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -48,16 +48,19 @@  - (void) applicationDidFinishLaunching:(NSNotification *)notification  {  	frameTimer = nil; -	 +  	[self languageUpdated]; -	 +  	if (initViewer())  	{ -		frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(mainLoop) userInfo:nil repeats:YES]; +		// Set up recurring calls to oneFrame (repeating timer with timeout 0) +		// until applicationShouldTerminate. +		frameTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self +							  selector:@selector(oneFrame) userInfo:nil repeats:YES];  	} else {  		handleQuit();  	} -	 +  	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil];   //   [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; @@ -96,22 +99,29 @@  - (NSApplicationDelegateReply) applicationShouldTerminate:(NSApplication *)sender  { -	if (!runMainLoop()) +	// run one frame to assess state +	if (!pumpMainLoop())  	{ +		// pumpMainLoop() returns true when done, false if it wants to be +		// called again. Since it returned false, do not yet cancel +		// frameTimer.  		handleQuit();  		return NSTerminateCancel;  	} else { +		// pumpMainLoop() returned true: it's done. Okay, done with frameTimer.  		[frameTimer release];  		cleanupViewer();  		return NSTerminateNow;  	}  } -- (void) mainLoop +- (void) oneFrame  { -	bool appExiting = runMainLoop(); +	bool appExiting = pumpMainLoop();  	if (appExiting)  	{ +		// Once pumpMainLoop() reports that we're done, cancel frameTimer: +		// stop the repetitive calls.  		[frameTimer release];  		[[NSApplication sharedApplication] terminate:self];  	} diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 7d1e6393ea..b0829a3da1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -122,15 +122,20 @@  #include "llleap.h"  #include "stringize.h"  #include "llcoros.h" +#include "llexception.h"  #if !LL_LINUX  #include "cef/llceflib.h" -#endif +#if LL_WINDOWS +#include "vlc/libvlc_version.h" +#endif // LL_WINDOWS +#endif // LL_LINUX  // Third party library includes  #include <boost/bind.hpp>  #include <boost/foreach.hpp>  #include <boost/algorithm/string.hpp>  #include <boost/regex.hpp> +#include <boost/throw_exception.hpp>  #if LL_WINDOWS  #	include <share.h> // For _SH_DENYWR in processMarkerFiles @@ -232,7 +237,6 @@  #include "llcoproceduremanager.h"  #include "llviewereventrecorder.h" -  // *FIX: These extern globals should be cleaned up.  // The globals either represent state/config/resource-storage of either   // this app, or another 'component' of the viewer. App globals should be  @@ -772,9 +776,6 @@ bool LLAppViewer::init()  	//  	// Start of the application  	// -#ifdef LL_DARWIN -	mMainLoopInitialized = false; -#endif  	// initialize LLWearableType translation bridge.  	// Memory will be cleaned up in ::cleanupClass() @@ -928,7 +929,7 @@ bool LLAppViewer::init()  	// Provide the text fields with callbacks for opening Urls  	LLUrlAction::setOpenURLCallback(boost::bind(&LLWeb::loadURL, _1, LLStringUtil::null, LLStringUtil::null)); -	LLUrlAction::setOpenURLInternalCallback(boost::bind(&LLWeb::loadURLInternal, _1, LLStringUtil::null, LLStringUtil::null)); +	LLUrlAction::setOpenURLInternalCallback(boost::bind(&LLWeb::loadURLInternal, _1, LLStringUtil::null, LLStringUtil::null, false));  	LLUrlAction::setOpenURLExternalCallback(boost::bind(&LLWeb::loadURLExternal, _1, true, LLStringUtil::null));  	LLUrlAction::setExecuteSLURLCallback(&LLURLDispatcher::dispatchFromTextEditor); @@ -1231,6 +1232,23 @@ bool LLAppViewer::init()  	showReleaseNotesIfRequired(); +	/*----------------------------------------------------------------------*/ +	// nat 2016-06-29 moved the following here from the former mainLoop(). +	mMainloopTimeout = new LLWatchdogTimeout(); + +	// Create IO Pump to use for HTTP Requests. +	gServicePump = new LLPumpIO(gAPRPoolp); + +	// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. + +	LLVoiceChannel::initClass(); +	LLVoiceClient::getInstance()->init(gServicePump); +	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); + +	joystick = LLViewerJoystick::getInstance(); +	joystick->setNeedsReset(true); +	/*----------------------------------------------------------------------*/ +  	return true;  } @@ -1305,300 +1323,266 @@ static LLTrace::BlockTimerStatHandle FTM_AGENT_UPDATE("Update");  // externally visible timers  LLTrace::BlockTimerStatHandle FTM_FRAME("Frame"); -bool LLAppViewer::mainLoop() +bool LLAppViewer::frame()  { -#ifdef LL_DARWIN -	if (!mMainLoopInitialized) -#endif -	{ -        LL_INFOS() << "Entering main_loop" << LL_ENDL; -		mMainloopTimeout = new LLWatchdogTimeout(); -		 -		//------------------------------------------- -		// Run main loop until time to quit -		//------------------------------------------- -		 -		// Create IO Pump to use for HTTP Requests. -		gServicePump = new LLPumpIO(gAPRPoolp); -		 -		// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated. -		 -		LLVoiceChannel::initClass(); -		LLVoiceClient::getInstance()->init(gServicePump); -		LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true); -		 -		joystick = LLViewerJoystick::getInstance(); -		joystick->setNeedsReset(true); -		 -#ifdef LL_DARWIN -		// Ensure that this section of code never gets called again on OS X. -		mMainLoopInitialized = true; -#endif -	} -	// As we do not (yet) send data on the mainloop LLEventPump that varies -	// with each frame, no need to instantiate a new LLSD event object each -	// time. Obviously, if that changes, just instantiate the LLSD at the -	// point of posting. -	  	LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop")); -	 -    LLSD newFrame; -	 +	LLSD newFrame; +  	LLTimer frameTimer,idleTimer;  	LLTimer debugTime; -	 +  	//LLPrivateMemoryPoolTester::getInstance()->run(false) ;  	//LLPrivateMemoryPoolTester::getInstance()->run(true) ;  	//LLPrivateMemoryPoolTester::destroy() ; -	// Handle messages -#ifdef LL_DARWIN -	if (!LLApp::isExiting()) -#else -	while (!LLApp::isExiting()) -#endif -	{ -		LL_RECORD_BLOCK_TIME(FTM_FRAME); -		LLTrace::BlockTimer::processTimes(); -		LLTrace::get_frame_recording().nextPeriod(); -		LLTrace::BlockTimer::logStats(); +	LL_RECORD_BLOCK_TIME(FTM_FRAME); +	LLTrace::BlockTimer::processTimes(); +	LLTrace::get_frame_recording().nextPeriod(); +	LLTrace::BlockTimer::logStats(); -		LLTrace::get_thread_recorder()->pullFromChildren(); +	LLTrace::get_thread_recorder()->pullFromChildren(); -		//clear call stack records -		LL_CLEAR_CALLSTACKS(); +	//clear call stack records +	LL_CLEAR_CALLSTACKS(); -		//check memory availability information -		checkMemory() ; -		 -		try +	//check memory availability information +	checkMemory() ; + +	try +	{ +		pingMainloopTimeout("Main:MiscNativeWindowEvents"); + +		if (gViewerWindow)  		{ -			pingMainloopTimeout("Main:MiscNativeWindowEvents"); +			LL_RECORD_BLOCK_TIME(FTM_MESSAGES); +			gViewerWindow->getWindow()->processMiscNativeEvents(); +		} + +		pingMainloopTimeout("Main:GatherInput"); -			if (gViewerWindow) +		if (gViewerWindow) +		{ +			LL_RECORD_BLOCK_TIME(FTM_MESSAGES); +			if (!restoreErrorTrap())  			{ -				LL_RECORD_BLOCK_TIME(FTM_MESSAGES); -				gViewerWindow->getWindow()->processMiscNativeEvents(); +				LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL;  			} -		 -			pingMainloopTimeout("Main:GatherInput"); -			 -			if (gViewerWindow) -			{ -				LL_RECORD_BLOCK_TIME(FTM_MESSAGES); -				if (!restoreErrorTrap()) -				{ -					LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL; -				} -				gViewerWindow->getWindow()->gatherInput(); -			} +			gViewerWindow->getWindow()->gatherInput(); +		}  #if 1 && !LL_RELEASE_FOR_DOWNLOAD -			// once per second debug info -			if (debugTime.getElapsedTimeF32() > 1.f) -			{ -				debugTime.reset(); -			} -			 +		// once per second debug info +		if (debugTime.getElapsedTimeF32() > 1.f) +		{ +			debugTime.reset(); +		} +		  #endif -			//memory leaking simulation -			LLFloaterMemLeak* mem_leak_instance = -				LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); -			if(mem_leak_instance) -			{ -				mem_leak_instance->idle() ;				 -			}							 +		//memory leaking simulation +		LLFloaterMemLeak* mem_leak_instance = +			LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); +		if(mem_leak_instance) +		{ +			mem_leak_instance->idle() ;				 +		}							 + +		// canonical per-frame event +		mainloop.post(newFrame); -            // canonical per-frame event -            mainloop.post(newFrame); +		if (!LLApp::isExiting()) +		{ +			pingMainloopTimeout("Main:JoystickKeyboard"); + +			// Scan keyboard for movement keys.  Command keys and typing +			// are handled by windows callbacks.  Don't do this until we're +			// done initializing.  JC +			if ((gHeadlessClient || gViewerWindow->getWindow()->getVisible()) +				&& gViewerWindow->getActive() +				&& !gViewerWindow->getWindow()->getMinimized() +				&& LLStartUp::getStartupState() == STATE_STARTED +				&& (gHeadlessClient || !gViewerWindow->getShowProgress()) +				&& !gFocusMgr.focusLocked()) +			{ +				joystick->scanJoystick(); +				gKeyboard->scanKeyboard(); +			} -			if (!LLApp::isExiting()) +			// Update state based on messages, user input, object idle.  			{ -				pingMainloopTimeout("Main:JoystickKeyboard"); +				pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! -				// Scan keyboard for movement keys.  Command keys and typing -				// are handled by windows callbacks.  Don't do this until we're -				// done initializing.  JC -				if ((gHeadlessClient || gViewerWindow->getWindow()->getVisible()) -					&& gViewerWindow->getActive() -					&& !gViewerWindow->getWindow()->getMinimized() -					&& LLStartUp::getStartupState() == STATE_STARTED -					&& (gHeadlessClient || !gViewerWindow->getShowProgress()) -					&& !gFocusMgr.focusLocked()) -				{ -					joystick->scanJoystick(); -					gKeyboard->scanKeyboard(); -				} +				LL_RECORD_BLOCK_TIME(FTM_IDLE); +				idle(); -				// Update state based on messages, user input, object idle. -				{ -					pauseMainloopTimeout(); // *TODO: Remove. Messages shouldn't be stalling for 20+ seconds! -					 -					LL_RECORD_BLOCK_TIME(FTM_IDLE); -					idle(); +				resumeMainloopTimeout(); +			} -					resumeMainloopTimeout(); -				} -  -				if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) -				{ -					pauseMainloopTimeout(); -					saveFinalSnapshot(); -					disconnectViewer(); -					resumeMainloopTimeout(); -				} +			if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) +			{ +				pauseMainloopTimeout(); +				saveFinalSnapshot(); +				disconnectViewer(); +				resumeMainloopTimeout(); +			} -				// Render scene. -				// *TODO: Should we run display() even during gHeadlessClient?  DK 2011-02-18 -				if (!LLApp::isExiting() && !gHeadlessClient) -				{ -					pingMainloopTimeout("Main:Display"); -					gGLActive = TRUE; -					display(); -					pingMainloopTimeout("Main:Snapshot"); -					LLFloaterSnapshot::update(); // take snapshots +			// Render scene. +			// *TODO: Should we run display() even during gHeadlessClient?  DK 2011-02-18 +			if (!LLApp::isExiting() && !gHeadlessClient) +			{ +				pingMainloopTimeout("Main:Display"); +				gGLActive = TRUE; +				display(); +				pingMainloopTimeout("Main:Snapshot"); +				LLFloaterSnapshot::update(); // take snapshots  					LLFloaterOutfitSnapshot::update(); -					gGLActive = FALSE; -				} +				gGLActive = FALSE;  			} +		} -			pingMainloopTimeout("Main:Sleep"); +		pingMainloopTimeout("Main:Sleep"); + +		pauseMainloopTimeout(); + +		// Sleep and run background threads +		{ +			LL_RECORD_BLOCK_TIME(FTM_SLEEP); -			pauseMainloopTimeout(); +			// yield some time to the os based on command line option +			if(mYieldTime >= 0) +			{ +				LL_RECORD_BLOCK_TIME(FTM_YIELD); +				ms_sleep(mYieldTime); +			} -			// Sleep and run background threads +			// yield cooperatively when not running as foreground window +			if (   (gViewerWindow && !gViewerWindow->getWindow()->getVisible()) +					|| !gFocusMgr.getAppHasFocus())  			{ -				LL_RECORD_BLOCK_TIME(FTM_SLEEP); -				 -				// yield some time to the os based on command line option -				if(mYieldTime >= 0) +				// Sleep if we're not rendering, or the window is minimized. +				S32 milliseconds_to_sleep = llclamp(gSavedSettings.getS32("BackgroundYieldTime"), 0, 1000); +				// don't sleep when BackgroundYieldTime set to 0, since this will still yield to other threads +				// of equal priority on Windows +				if (milliseconds_to_sleep > 0)  				{ -					LL_RECORD_BLOCK_TIME(FTM_YIELD); -					ms_sleep(mYieldTime); +					ms_sleep(milliseconds_to_sleep); +					// also pause worker threads during this wait period +					LLAppViewer::getTextureCache()->pause(); +					LLAppViewer::getImageDecodeThread()->pause();  				} +			} +			 +			if (mRandomizeFramerate) +			{ +				ms_sleep(rand() % 200); +			} + +			if (mPeriodicSlowFrame +				&& (gFrameCount % 10 == 0)) +			{ +				LL_INFOS() << "Periodic slow frame - sleeping 500 ms" << LL_ENDL; +				ms_sleep(500); +			} + +			const F64Milliseconds max_idle_time = llmin(.005f*10.f*(F32Milliseconds)gFrameTimeSeconds, F32Milliseconds(5)); // 5 ms a second +			idleTimer.reset(); +			S32 total_work_pending = 0; +			S32 total_io_pending = 0;	 +			while(1) +			{ +				S32 work_pending = 0; +				S32 io_pending = 0; +				F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f); + +				work_pending += updateTextureThreads(max_time); -				// yield cooperatively when not running as foreground window -				if (   (gViewerWindow && !gViewerWindow->getWindow()->getVisible()) -						|| !gFocusMgr.getAppHasFocus())  				{ -					// Sleep if we're not rendering, or the window is minimized. -					S32 milliseconds_to_sleep = llclamp(gSavedSettings.getS32("BackgroundYieldTime"), 0, 1000); -					// don't sleep when BackgroundYieldTime set to 0, since this will still yield to other threads -					// of equal priority on Windows -					if (milliseconds_to_sleep > 0) -					{ -						ms_sleep(milliseconds_to_sleep); -						// also pause worker threads during this wait period -						LLAppViewer::getTextureCache()->pause(); -						LLAppViewer::getImageDecodeThread()->pause(); -					} +					LL_RECORD_BLOCK_TIME(FTM_VFS); + 					io_pending += LLVFSThread::updateClass(1);  				} -				 -				if (mRandomizeFramerate)  				{ -					ms_sleep(rand() % 200); +					LL_RECORD_BLOCK_TIME(FTM_LFS); + 					io_pending += LLLFSThread::updateClass(1);  				} -				if (mPeriodicSlowFrame -					&& (gFrameCount % 10 == 0)) +				if (io_pending > 1000)  				{ -					LL_INFOS() << "Periodic slow frame - sleeping 500 ms" << LL_ENDL; -					ms_sleep(500); +					ms_sleep(llmin(io_pending/100,100)); // give the vfs some time to catch up  				} -				const F64Milliseconds max_idle_time = llmin(.005f*10.f*(F32Milliseconds)gFrameTimeSeconds, F32Milliseconds(5)); // 5 ms a second -				idleTimer.reset(); -				S32 total_work_pending = 0; -				S32 total_io_pending = 0;	 -				while(1) -				{ -					S32 work_pending = 0; -					S32 io_pending = 0; -					F32 max_time = llmin(gFrameIntervalSeconds.value() *10.f, 1.f); - -					work_pending += updateTextureThreads(max_time); - -					{ -						LL_RECORD_BLOCK_TIME(FTM_VFS); -	 					io_pending += LLVFSThread::updateClass(1); -					} -					{ -						LL_RECORD_BLOCK_TIME(FTM_LFS); -	 					io_pending += LLLFSThread::updateClass(1); -					} - -					if (io_pending > 1000) -					{ -						ms_sleep(llmin(io_pending/100,100)); // give the vfs some time to catch up -					} - -					total_work_pending += work_pending ; -					total_io_pending += io_pending ; -					 -					if (!work_pending || idleTimer.getElapsedTimeF64() >= max_idle_time) -					{ -						break; -					} -				} -				gMeshRepo.update() ; +				total_work_pending += work_pending ; +				total_io_pending += io_pending ; -				if(!total_work_pending) //pause texture fetching threads if nothing to process. +				if (!work_pending || idleTimer.getElapsedTimeF64() >= max_idle_time)  				{ -					LLAppViewer::getTextureCache()->pause(); -					LLAppViewer::getImageDecodeThread()->pause(); -					LLAppViewer::getTextureFetch()->pause();  +					break;  				} -				if(!total_io_pending) //pause file threads if nothing to process. -				{ -					LLVFSThread::sLocal->pause();  -					LLLFSThread::sLocal->pause();  -				}									 +			} +			gMeshRepo.update() ; +			 +			if(!total_work_pending) //pause texture fetching threads if nothing to process. +			{ +				LLAppViewer::getTextureCache()->pause(); +				LLAppViewer::getImageDecodeThread()->pause(); +				LLAppViewer::getTextureFetch()->pause();  +			} +			if(!total_io_pending) //pause file threads if nothing to process. +			{ +				LLVFSThread::sLocal->pause();  +				LLLFSThread::sLocal->pause();  +			}									 -				//texture fetching debugger -				if(LLTextureFetchDebugger::isEnabled()) +			//texture fetching debugger +			if(LLTextureFetchDebugger::isEnabled()) +			{ +				LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = +					LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger"); +				if(tex_fetch_debugger_instance)  				{ -					LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance = -						LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger"); -					if(tex_fetch_debugger_instance) -					{ -						tex_fetch_debugger_instance->idle() ;				 -					} +					tex_fetch_debugger_instance->idle() ;				  				} +			} -				if ((LLStartUp::getStartupState() >= STATE_CLEANUP) && -					(frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD)) -				{ -					gFrameStalls++; -				} -				frameTimer.reset(); +			if ((LLStartUp::getStartupState() >= STATE_CLEANUP) && +				(frameTimer.getElapsedTimeF64() > FRAME_STALL_THRESHOLD)) +			{ +				gFrameStalls++; +			} +			frameTimer.reset(); -				resumeMainloopTimeout(); -	 -				pingMainloopTimeout("Main:End"); -			}	 +			resumeMainloopTimeout(); + +			pingMainloopTimeout("Main:End");  		} -		catch(std::bad_alloc) -		{			 -			LLMemory::logMemoryInfo(TRUE) ; +	} +	catch (const LLContinueError&) +	{ +		LOG_UNHANDLED_EXCEPTION(""); +	} +	catch(std::bad_alloc) +	{ +		LLMemory::logMemoryInfo(TRUE) ; -			//stop memory leaking simulation -			LLFloaterMemLeak* mem_leak_instance = -				LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); -			if(mem_leak_instance) -			{ -				mem_leak_instance->stop() ;				 -				LL_WARNS() << "Bad memory allocation in LLAppViewer::mainLoop()!" << LL_ENDL ; -			} -			else -			{ -				//output possible call stacks to log file. -				LLError::LLCallStacks::print() ; +		//stop memory leaking simulation +		LLFloaterMemLeak* mem_leak_instance = +			LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); +		if(mem_leak_instance) +		{ +			mem_leak_instance->stop() ; +			LL_WARNS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL ; +		} +		else +		{ +			//output possible call stacks to log file. +			LLError::LLCallStacks::print() ; -				LL_ERRS() << "Bad memory allocation in LLAppViewer::mainLoop()!" << LL_ENDL ; -			} +			LL_ERRS() << "Bad memory allocation in LLAppViewer::frame()!" << LL_ENDL ;  		}  	} +	catch (...) +	{ +		CRASH_ON_UNHANDLED_EXCEPTION(""); +	}  	if (LLApp::isExiting())  	{ @@ -1612,7 +1596,7 @@ bool LLAppViewer::mainLoop()  			catch(std::bad_alloc)  			{  				LL_WARNS() << "Bad memory allocation when saveFinalSnapshot() is called!" << LL_ENDL ; -				 +  				//stop memory leaking simulation  				LLFloaterMemLeak* mem_leak_instance =  				LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking"); @@ -1621,16 +1605,20 @@ bool LLAppViewer::mainLoop()  					mem_leak_instance->stop() ;  				}  			} +			catch (...) +			{ +				CRASH_ON_UNHANDLED_EXCEPTION("saveFinalSnapshot()"); +			}  		} -		 +  		delete gServicePump; -		 +  		destroyMainloopTimeout(); -		 +  		LL_INFOS() << "Exiting main_loop" << LL_ENDL;  	} -	return LLApp::isExiting(); +	return ! LLApp::isRunning();  }  S32 LLAppViewer::updateTextureThreads(F32 max_time) @@ -3358,6 +3346,19 @@ LLSD LLAppViewer::getViewerInfo() const  	info["LLCEFLIB_VERSION"] = LLCEFLIB_VERSION;  #else  	info["LLCEFLIB_VERSION"] = "Undefined"; + +#endif + +#if LL_WINDOWS +	std::ostringstream ver_codec; +	ver_codec << LIBVLC_VERSION_MAJOR; +	ver_codec << "."; +	ver_codec << LIBVLC_VERSION_MINOR; +	ver_codec << "."; +	ver_codec << LIBVLC_VERSION_REVISION; +	info["LIBVLC_VERSION"] = ver_codec.str(); +#else +	info["LIBVLC_VERSION"] = "Undefined";  #endif  	S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN); @@ -5562,8 +5563,7 @@ void LLAppViewer::forceErrorInfiniteLoop()  void LLAppViewer::forceErrorSoftwareException()  {     	LL_WARNS() << "Forcing a deliberate exception" << LL_ENDL; -    // *FIX: Any way to insure it won't be handled? -    throw;  +    LLTHROW(LLException("User selected Force Software Exception"));  }  void LLAppViewer::forceErrorDriverCrash() diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index d4af2440be..948d316009 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -79,7 +79,7 @@ public:  	//  	virtual bool init();			// Override to do application initialization  	virtual bool cleanup();			// Override to do application cleanup -	virtual bool mainLoop(); // Override for the application main loop.  Needs to at least gracefully notice the QUITTING state and exit. +	virtual bool frame(); // Override for application body logic  	// Application control  	void flushVFSIO(); // waits for vfs transfers to complete @@ -285,7 +285,6 @@ private:  	std::string mSerialNumber;  	bool mPurgeCache;      bool mPurgeOnExit; -	bool mMainLoopInitialized;  	LLViewerJoystick* joystick;  	bool mSavedFinalSnapshot; diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index f5742b29cf..6f32aab851 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -95,10 +95,8 @@ int main( int argc, char **argv )  	}  		// Run the application main loop -	if(!LLApp::isQuitting())  -	{ -		viewer_app_ptr->mainLoop(); -	} +	while (! viewer_app_ptr->frame())  +	{}  	if (!LLApp::isError())  	{ diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index ca219fda59..4fe1e31668 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -117,12 +117,17 @@ void handleQuit()  	LLAppViewer::instance()->userQuit();  } -bool runMainLoop() +// This function is called pumpMainLoop() rather than runMainLoop() because +// it passes control to the viewer's main-loop logic for a single frame. Like +// LLAppViewer::frame(), it returns 'true' when it's done. Until then, it +// expects to be called again by the timer in LLAppDelegate +// (llappdelegate-objc.mm). +bool pumpMainLoop()  {  	bool ret = LLApp::isQuitting();  	if (!ret && gViewerAppPtr != NULL)  	{ -		ret = gViewerAppPtr->mainLoop(); +		ret = gViewerAppPtr->frame();  	} else {  		ret = true;  	} diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index febcfe1f61..5107030476 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -319,10 +319,8 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,  	}  	// Run the application main loop -	if(!LLApp::isQuitting())  -	{ -		viewer_app_ptr->mainLoop(); -	} +	while (! viewer_app_ptr->frame())  +	{}  	if (!LLApp::isError())  	{ @@ -332,33 +330,33 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,  		// app cleanup if there was a problem.  		//  #if WINDOWS_CRT_MEM_CHECKS -    LL_INFOS() << "CRT Checking memory:" << LL_ENDL; -	if (!_CrtCheckMemory()) -	{ -		LL_WARNS() << "_CrtCheckMemory() failed at prior to cleanup!" << LL_ENDL; -	} -	else -	{ -		LL_INFOS() << " No corruption detected." << LL_ENDL; -	} +		LL_INFOS() << "CRT Checking memory:" << LL_ENDL; +		if (!_CrtCheckMemory()) +		{ +			LL_WARNS() << "_CrtCheckMemory() failed at prior to cleanup!" << LL_ENDL; +		} +		else +		{ +			LL_INFOS() << " No corruption detected." << LL_ENDL; +		}  #endif -	 -	gGLActive = TRUE; -	viewer_app_ptr->cleanup(); -	 +		gGLActive = TRUE; + +		viewer_app_ptr->cleanup(); +  #if WINDOWS_CRT_MEM_CHECKS -    LL_INFOS() << "CRT Checking memory:" << LL_ENDL; -	if (!_CrtCheckMemory()) -	{ -		LL_WARNS() << "_CrtCheckMemory() failed after cleanup!" << LL_ENDL; -	} -	else -	{ -		LL_INFOS() << " No corruption detected." << LL_ENDL; -	} +		LL_INFOS() << "CRT Checking memory:" << LL_ENDL; +		if (!_CrtCheckMemory()) +		{ +			LL_WARNS() << "_CrtCheckMemory() failed after cleanup!" << LL_ENDL; +		} +		else +		{ +			LL_INFOS() << " No corruption detected." << LL_ENDL; +		}  #endif -	  +  	}  	delete viewer_app_ptr;  	viewer_app_ptr = NULL; diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp index 1819fc74ee..90a5483dc9 100644 --- a/indra/newview/llcommandlineparser.cpp +++ b/indra/newview/llcommandlineparser.cpp @@ -26,6 +26,7 @@  #include "llviewerprecompiledheaders.h"  #include "llcommandlineparser.h" +#include "llexception.h"  // *NOTE: The boost::lexical_cast generates   // the warning C4701(local used with out assignment) in VC7.1. @@ -50,6 +51,7 @@  #include "llsdserialize.h"  #include "llerror.h"  #include "stringize.h" +#include "llexception.h"  #include <string>  #include <set>  #include <iostream> @@ -98,14 +100,14 @@ namespace      bool gPastLastOption = false;  } -class LLCLPError : public std::logic_error { +class LLCLPError : public LLException {  public: -    LLCLPError(const std::string& what) : std::logic_error(what) {} +    LLCLPError(const std::string& what) : LLException(what) {}  }; -class LLCLPLastOption : public std::logic_error { +class LLCLPLastOption : public LLException {  public: -    LLCLPLastOption(const std::string& what) : std::logic_error(what) {} +    LLCLPLastOption(const std::string& what) : LLException(what) {}  };  class LLCLPValue : public po::value_semantic_codecvt_helper<char>  @@ -202,17 +204,17 @@ protected:      {          if(gPastLastOption)          { -            throw(LLCLPLastOption("Don't parse no more!")); +            LLTHROW(LLCLPLastOption("Don't parse no more!"));          }          // Error checks. Needed?          if (!value_store.empty() && !is_composing())           { -            throw(LLCLPError("Non composing value with multiple occurences.")); +            LLTHROW(LLCLPError("Non composing value with multiple occurences."));          }          if (new_tokens.size() < min_tokens() || new_tokens.size() > max_tokens())          { -            throw(LLCLPError("Illegal number of tokens specified.")); +            LLTHROW(LLCLPError("Illegal number of tokens specified."));          }          if(value_store.empty()) @@ -466,7 +468,7 @@ onevalue(const std::string& option,      {          // What does it mean when the user specifies a command-line switch          // that requires a value, but omits the value? Complain. -        throw LLCLPError(STRINGIZE("No value specified for --" << option << "!")); +        LLTHROW(LLCLPError(STRINGIZE("No value specified for --" << option << "!")));      }      else if (value.size() > 1)      { @@ -484,9 +486,9 @@ void badvalue(const std::string& option,      // If the user passes an unusable value for a command-line switch, it      // seems like a really bad idea to just ignore it, even with a log      // warning. -    throw LLCLPError(STRINGIZE("Invalid value specified by command-line switch '" << option -                               << "' for variable '" << varname << "' of type " << type -                               << ": '" << value << "'")); +    LLTHROW(LLCLPError(STRINGIZE("Invalid value specified by command-line switch '" << option +                                 << "' for variable '" << varname << "' of type " << type +                                 << ": '" << value << "'")));  }  template <typename T> diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp index 7721e67290..76e16f5a1f 100644 --- a/indra/newview/llcompilequeue.cpp +++ b/indra/newview/llcompilequeue.cpp @@ -67,7 +67,9 @@ namespace      const std::string QUEUE_EVENTPUMP_NAME("ScriptActionQueue"); - +    // ObjectIventoryFetcher is an adapter between the LLVOInventoryListener::inventoryChanged  +    // callback mechanism and the LLEventPump coroutine architecture allowing the  +    // coroutine to wait for the inventory event.      class ObjectInventoryFetcher: public LLVOInventoryListener      {      public: @@ -144,7 +146,7 @@ public:              queue->getChild<LLScrollListCtrl>("queue output")->addSimpleElement(message, ADD_BOTTOM);          } -        return LLSD().with("success", LLSD::Boolean(true)); +        return LLSDMap("success", LLSD::Boolean(true));      } @@ -254,7 +256,6 @@ LLFloaterCompileQueue::LLFloaterCompileQueue(const LLSD& key)  	setTitle(LLTrans::getString("CompileQueueTitle"));  	setStartString(LLTrans::getString("CompileQueueStart")); -//	mUploadQueue = new LLAssetUploadQueue(new LLCompileFloaterUploadQueueSupplier(key.asUUID()));  }  LLFloaterCompileQueue::~LLFloaterCompileQueue() @@ -267,7 +268,6 @@ void LLFloaterCompileQueue::experienceIdsReceived( const LLSD& content )  	{  		mExperienceIds.insert(it->asUUID());  	} -//	nextObject();  }  BOOL LLFloaterCompileQueue::hasExperience( const LLUUID& id ) const @@ -277,11 +277,6 @@ BOOL LLFloaterCompileQueue::hasExperience( const LLUUID& id ) const  // //Attempt to record this asset ID.  If it can not be inserted into the set   // //then it has already been processed so return false. -// bool LLFloaterCompileQueue::checkAssetId(const LLUUID &assetId) -// { -//     std::pair<uuid_list_t::iterator, bool> result = mAssetIds.insert(assetId); -//     return result.second; -// }  void LLFloaterCompileQueue::handleHTTPResponse(std::string pumpName, const LLSD &expresult)  { @@ -331,8 +326,10 @@ void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID paren      queue->experienceIdsReceived(result["experience_ids"]); +    // getDerived handle gets a handle that can be resolved to a parent class of the derived object.      LLHandle<LLFloaterScriptQueue> hFloater(queue->getDerivedHandle<LLFloaterScriptQueue>()); +    // note subtle difference here: getDerivedHandle in this case is for an LLFloaterCompileQueue      fnQueueAction_t fn = boost::bind(LLFloaterCompileQueue::processScript,          queue->getDerivedHandle<LLFloaterCompileQueue>(), _1, _2, _3); @@ -345,37 +342,35 @@ void LLFloaterCompileQueue::processExperienceIdResults(LLSD result, LLUUID paren  } +/// This is a utility function to be bound and called from objectScriptProcessingQueueCoro. +/// Do not call directly. It may throw a LLCheckedHandle<>::Stale exception.  bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloater,      const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)  {      LLSD result; -    LLFloaterCompileQueue *that = hfloater.get(); -    bool monocompile = that->mMono; +    LLCheckedHandle<LLFloaterCompileQueue> floater(hfloater); +    // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle. +    // which is caught in objectScriptProcessingQueueCoro +    bool monocompile = floater->mMono;      F32 fetch_timeout = gSavedSettings.getF32("QueueInventoryFetchTimeout"); -    if (!that) -        return false;      // Initial test to see if we can (or should) attempt to compile the script.      LLInventoryItem *item = dynamic_cast<LLInventoryItem *>(inventory); -    { -        if (!item->getPermissions().allowModifyBy(gAgent.getID(), gAgent.getGroupID()) || -            !item->getPermissions().allowCopyBy(gAgent.getID(), gAgent.getGroupID())) -        { -            std::string buffer = "Skipping: " + item->getName() + "(Permissions)"; -            that->addStringMessage(buffer); -            return true; -        } +    if (!item) +    { +        LL_WARNS("SCRIPTQ") << "item retrieved is not an LLInventoryItem." << LL_ENDL; +        return true; +    } -//         if (!that->checkAssetId(item->getAssetUUID())) -//         { -//             std::string buffer = "Skipping: " + item->getName() + "(Repeat)"; -//             that->addStringMessage(buffer); -//             return true; -//         } +    if (!item->getPermissions().allowModifyBy(gAgent.getID(), gAgent.getGroupID()) || +        !item->getPermissions().allowCopyBy(gAgent.getID(), gAgent.getGroupID())) +    { +        std::string buffer = "Skipping: " + item->getName() + "(Permissions)"; +        floater->addStringMessage(buffer); +        return true;      } -    that = NULL;      // Attempt to retrieve the experience      LLUUID experienceId; @@ -384,37 +379,30 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat              boost::bind(&LLFloaterCompileQueue::handleHTTPResponse, pump.getName(), _1));          result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, -            LLSD().with("timeout", LLSD::Boolean(true))); +            LLSDMap("timeout", LLSD::Boolean(true))); -        that = hfloater.get(); -        if (!that) -        { -            return false; -        } - -        if (result.has("timeout") && result["timeout"].asBoolean()) -        { +        if (result.has("timeout")) +        {   // A timeout filed in the result will always be true if present.              LLStringUtil::format_map_t args;              args["[OBJECT_NAME]"] = inventory->getName(); -            std::string buffer = that->getString("Timeout", args); -            that->addStringMessage(buffer); +            std::string buffer = floater->getString("Timeout", args); +            floater->addStringMessage(buffer);              return true;          }          if (result.has(LLExperienceCache::EXPERIENCE_ID))          {              experienceId = result[LLExperienceCache::EXPERIENCE_ID].asUUID(); -            if (!that->hasExperience(experienceId)) +            if (!floater->hasExperience(experienceId))              { -                that->addProcessingMessage("CompileNoExperiencePerm", LLSD() -                    .with("SCRIPT", inventory->getName()) -                    .with("EXPERIENCE", result[LLExperienceCache::NAME].asString())); +                floater->addProcessingMessage("CompileNoExperiencePerm",  +                    LLSDMap("SCRIPT", inventory->getName()) +                        ("EXPERIENCE", result[LLExperienceCache::NAME].asString()));                  return true;              }          }      } -    that = NULL;      {          HandleScriptUserData    userData(pump.getName()); @@ -433,32 +421,23 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat              &userData);          result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, -            LLSD().with("timeout", LLSD::Boolean(true))); -    } - -    that = hfloater.get(); -    if (!that) -    { -        return false; +            LLSDMap("timeout", LLSD::Boolean(true)));      }      if (result.has("timeout")) -    { -        if (result.has("timeout") && result["timeout"].asBoolean()) -        { -            LLStringUtil::format_map_t args; -            args["[OBJECT_NAME]"] = inventory->getName(); -            std::string buffer = that->getString("Timeout", args); -            that->addStringMessage(buffer); -            return true; -        } +    {   // A timeout filed in the result will always be true if present. +        LLStringUtil::format_map_t args; +        args["[OBJECT_NAME]"] = inventory->getName(); +        std::string buffer = floater->getString("Timeout", args); +        floater->addStringMessage(buffer); +        return true;      }      if (result.has("error"))      {          LL_WARNS("SCRIPTQ") << "Inventory fetch returned with error. Code: " << result["error"].asString() << LL_ENDL;          std::string buffer = result["message"].asString() + " " + inventory->getName(); -        that->addStringMessage(buffer); +        floater->addStringMessage(buffer);          if (result.has("alert"))          { @@ -470,12 +449,9 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat      }      LLUUID assetId = result["asset_id"]; -    that = NULL; -      std::string url = object->getRegion()->getCapability("UpdateScriptTask"); -      {          LLResourceUploadInfo::ptr_t uploadInfo(new LLQueuedScriptAssetUpload(object->getID(),               inventory->getUUID(),  @@ -490,24 +466,15 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat          LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);      } -    result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, LLSD().with("timeout", LLSD::Boolean(true))); - -    that = hfloater.get(); -    if (!that) -    { -        return false; -    } +    result = llcoro::suspendUntilEventOnWithTimeout(pump, fetch_timeout, LLSDMap("timeout", LLSD::Boolean(true)));      if (result.has("timeout")) -    { -        if (result.has("timeout") && result["timeout"].asBoolean()) -        { -            LLStringUtil::format_map_t args; -            args["[OBJECT_NAME]"] = inventory->getName(); -            std::string buffer = that->getString("Timeout", args); -            that->addStringMessage(buffer); -            return true; -        } +    { // A timeout filed in the result will always be true if present. +        LLStringUtil::format_map_t args; +        args["[OBJECT_NAME]"] = inventory->getName(); +        std::string buffer = floater->getString("Timeout", args); +        floater->addStringMessage(buffer); +        return true;      }      // Bytecode save completed @@ -515,21 +482,21 @@ bool LLFloaterCompileQueue::processScript(LLHandle<LLFloaterCompileQueue> hfloat      {          std::string buffer = std::string("Compilation of \"") + inventory->getName() + std::string("\" succeeded"); -        that->addStringMessage(buffer); +        floater->addStringMessage(buffer);          LL_INFOS() << buffer << LL_ENDL;      }      else      {          LLSD compile_errors = result["errors"];          std::string buffer = std::string("Compilation of \"") + inventory->getName() + std::string("\" failed:"); -        that->addStringMessage(buffer); +        floater->addStringMessage(buffer);          for (LLSD::array_const_iterator line = compile_errors.beginArray();              line < compile_errors.endArray(); line++)          {              std::string str = line->asString();              str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); -            that->addStringMessage(str); +            floater->addStringMessage(str);          }          LL_INFOS() << result["errors"] << LL_ENDL;      } @@ -576,16 +543,18 @@ LLFloaterResetQueue::~LLFloaterResetQueue()  {   } -bool LLFloaterResetQueue::resetObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater,  +/// This is a utility function to be bound and called from objectScriptProcessingQueueCoro. +/// Do not call directly. It may throw a LLCheckedHandle<>::Stale exception. +bool LLFloaterResetQueue::resetObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater,      const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)  { -    LLFloaterScriptQueue *that = hfloater.get(); -    if (that) -    { -        std::string buffer; -        buffer = that->getString("Resetting") + (": ") + inventory->getName(); -        that->addStringMessage(buffer); -    } +    LLCheckedHandle<LLFloaterScriptQueue> floater(hfloater); +    // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle. +    // which is caught in objectScriptProcessingQueueCoro + +    std::string buffer; +    buffer = floater->getString("Resetting") + (": ") + inventory->getName(); +    floater->addStringMessage(buffer);      LLMessageSystem* msg = gMessageSystem;      msg->newMessageFast(_PREHASH_ScriptReset); @@ -602,6 +571,8 @@ bool LLFloaterResetQueue::resetObjectScripts(LLHandle<LLFloaterScriptQueue> hflo  bool LLFloaterResetQueue::startQueue()  { +    // Bind the resetObjectScripts method into a QueueAction function and pass it +    // into the object queue processing coroutine.      fnQueueAction_t fn = boost::bind(LLFloaterResetQueue::resetObjectScripts,          getDerivedHandle<LLFloaterScriptQueue>(), _1, _2, _3); @@ -629,16 +600,18 @@ LLFloaterRunQueue::~LLFloaterRunQueue()  {   } -bool LLFloaterRunQueue::runObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater,  +/// This is a utility function to be bound and called from objectScriptProcessingQueueCoro. +/// Do not call directly. It may throw a LLCheckedHandle<>::Stale exception. +bool LLFloaterRunQueue::runObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater,      const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)  { -    LLFloaterScriptQueue *that = hfloater.get(); -    if (that) -    { -        std::string buffer; -        buffer = that->getString("Running") + (": ") + inventory->getName(); -        that->addStringMessage(buffer); -    } +    LLCheckedHandle<LLFloaterScriptQueue> floater(hfloater); +    // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle. +    // which is caught in objectScriptProcessingQueueCoro + +    std::string buffer; +    buffer = floater->getString("Running") + (": ") + inventory->getName(); +    floater->addStringMessage(buffer);      LLMessageSystem* msg = gMessageSystem;      msg->newMessageFast(_PREHASH_SetScriptRunning); @@ -684,16 +657,18 @@ LLFloaterNotRunQueue::~LLFloaterNotRunQueue()  {   } +/// This is a utility function to be bound and called from objectScriptProcessingQueueCoro. +/// Do not call directly. It may throw a LLCheckedHandle<>::Stale exception.  bool LLFloaterNotRunQueue::stopObjectScripts(LLHandle<LLFloaterScriptQueue> hfloater,       const LLPointer<LLViewerObject> &object, LLInventoryObject* inventory, LLEventPump &pump)  { -    LLFloaterScriptQueue *that = hfloater.get(); -    if (that) -    { -        std::string buffer; -        buffer = that->getString("NotRunning") + (": ") + inventory->getName(); -        that->addStringMessage(buffer); -    } +    LLCheckedHandle<LLFloaterScriptQueue> floater(hfloater); +    // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle. +    // which is caught in objectScriptProcessingQueueCoro + +    std::string buffer; +    buffer = floater->getString("NotRunning") + (": ") + inventory->getName(); +    floater->addStringMessage(buffer);      LLMessageSystem* msg = gMessageSystem;      msg->newMessageFast(_PREHASH_SetScriptRunning); @@ -732,7 +707,7 @@ void ObjectInventoryFetcher::inventoryChanged(LLViewerObject* object,      mInventoryList.clear();      mInventoryList.assign(inventory->begin(), inventory->end()); -    mPump.post(LLSD().with("changed", LLSD::Boolean(true))); +    mPump.post(LLSDMap("changed", LLSD::Boolean(true)));  } @@ -740,115 +715,97 @@ void LLFloaterScriptQueue::objectScriptProcessingQueueCoro(std::string action, L      object_data_list_t objectList, fnQueueAction_t func)  {      LLCoros::set_consuming(true); -    LLFloaterScriptQueue * floater(NULL); +    LLCheckedHandle<LLFloaterScriptQueue> floater(hfloater);     +    // Dereferencing floater may fail. If they do they throw LLExeceptionStaleHandle.  +    // This is expected if the dialog closes.      LLEventMailDrop        maildrop(QUEUE_EVENTPUMP_NAME, true);      F32 fetch_timeout = gSavedSettings.getF32("QueueInventoryFetchTimeout"); -//     floater = hfloater.get(); -//     floater->addProcessingMessage("Starting", -//         LLSD() -//         .with("[START]", action) -//         .with("[COUNT]", LLSD::Integer(objectList.size()))); -//     floater = NULL; -    for (object_data_list_t::iterator itObj(objectList.begin()); (itObj != objectList.end()); ++itObj) +    try      { -        bool firstForObject = true; -        LLUUID object_id = (*itObj).mObjectId; -        LL_INFOS("SCRIPTQ") << "Next object in queue with ID=" << object_id.asString() << LL_ENDL; - -        LLPointer<LLViewerObject> obj = gObjectList.findObject(object_id); -        LLInventoryObject::object_list_t inventory; -        if (obj) +        for (object_data_list_t::iterator itObj(objectList.begin()); (itObj != objectList.end()); ++itObj)          { -            ObjectInventoryFetcher::ptr_t fetcher(new ObjectInventoryFetcher(maildrop, obj, NULL)); +            bool firstForObject = true; +            LLUUID object_id = (*itObj).mObjectId; +            LL_INFOS("SCRIPTQ") << "Next object in queue with ID=" << object_id.asString() << LL_ENDL; -            fetcher->fetchInventory(); - -            floater = hfloater.get(); -            if (floater) +            LLPointer<LLViewerObject> obj = gObjectList.findObject(object_id); +            LLInventoryObject::object_list_t inventory; +            if (obj)              { +                ObjectInventoryFetcher::ptr_t fetcher(new ObjectInventoryFetcher(maildrop, obj, NULL)); + +                fetcher->fetchInventory(); +                  LLStringUtil::format_map_t args;                  args["[OBJECT_NAME]"] = (*itObj).mObjectName;                  floater->addStringMessage(floater->getString("LoadingObjInv", args)); -            } -            LLSD result = llcoro::suspendUntilEventOnWithTimeout(maildrop, fetch_timeout, -                LLSD().with("timeout", LLSD::Boolean(true))); +                LLSD result = llcoro::suspendUntilEventOnWithTimeout(maildrop, fetch_timeout, +                    LLSDMap("timeout", LLSD::Boolean(true))); -            if (result.has("timeout") && result["timeout"].asBoolean()) -            { -                LL_WARNS("SCRIPTQ") << "Unable to retrieve inventory for object " << object_id.asString() << -                    ". Skipping to next object." << LL_ENDL; +                if (result.has("timeout")) +                {    // A timeout filed in the result will always be true if present. +                    LL_WARNS("SCRIPTQ") << "Unable to retrieve inventory for object " << object_id.asString() << +                        ". Skipping to next object." << LL_ENDL; -                // floater could have been closed -                floater = hfloater.get(); -                if (floater) -                {                      LLStringUtil::format_map_t args;                      args["[OBJECT_NAME]"] = (*itObj).mObjectName;                      floater->addStringMessage(floater->getString("Timeout", args)); + +                    continue;                  } +                inventory.assign(fetcher->getInventoryList().begin(), fetcher->getInventoryList().end()); +            } +            else +            { +                LL_WARNS("SCRIPTQ") << "Unable to retrieve object with ID of " << object_id << +                    ". Skipping to next." << LL_ENDL;                  continue;              } -            inventory.assign(fetcher->getInventoryList().begin(), fetcher->getInventoryList().end()); -        } -        else -        { -            LL_WARNS("SCRIPTQ") << "Unable to retrieve object with ID of " << object_id << -                ". Skipping to next." << LL_ENDL; -            continue; -        } +            // TODO: Get the name of the object we are looking at here so that we can display it below. +            //std::string objName = (dynamic_cast<LLInventoryObject *>(obj.get()))->getName(); +            LL_DEBUGS("SCRIPTQ") << "Object has " << inventory.size() << " items." << LL_ENDL; -        // TODO: Get the name of the object we are looking at here so that we can display it below. -        //std::string objName = (dynamic_cast<LLInventoryObject *>(obj.get()))->getName(); -        LL_DEBUGS("SCRIPTQ") << "Object has " << inventory.size() << " items." << LL_ENDL; - -        for (LLInventoryObject::object_list_t::iterator itInv = inventory.begin(); -            itInv != inventory.end(); ++itInv) -        { -            floater = hfloater.get(); -            if (!floater) +            for (LLInventoryObject::object_list_t::iterator itInv = inventory.begin(); +                itInv != inventory.end(); ++itInv)              { -                LL_WARNS("SCRIPTQ") << "Script Queue floater closed! Canceling remaining ops" << LL_ENDL; -                break; -            } +                floater.check(); -            // note, we have a smart pointer to the obj above... but if we didn't we'd check that  -            // it still exists here. +                // note, we have a smart pointer to the obj above... but if we didn't we'd check that  +                // it still exists here. -            if (((*itInv)->getType() == LLAssetType::AT_LSL_TEXT)) -            { -                LL_DEBUGS("SCRIPTQ") << "Inventory item " << (*itInv)->getUUID().asString() << "\"" << (*itInv)->getName() << "\"" << LL_ENDL; -                if (firstForObject) +                if (((*itInv)->getType() == LLAssetType::AT_LSL_TEXT))                  { -                    //floater->addStringMessage(objName + ":"); -                    firstForObject = false; +                    LL_DEBUGS("SCRIPTQ") << "Inventory item " << (*itInv)->getUUID().asString() << "\"" << (*itInv)->getName() << "\"" << LL_ENDL; +                    if (firstForObject) +                    { +                        //floater->addStringMessage(objName + ":"); +                        firstForObject = false; +                    } + +                    if (!func(obj, (*itInv), maildrop)) +                    { +                        continue; +                    }                  } -                if (!func(obj, (*itInv), maildrop)) -                { -                    continue; -                } +                // no other explicit suspension point in this loop.  func(...) MIGHT suspend +                // but offers no guarantee of doing so. +                llcoro::suspend();              } - -            llcoro::suspend(); -        } -        // Just test to be sure the floater is still present before calling the func -        if (!hfloater.get()) -        { -            LL_WARNS("SCRIPTQ") << "Script Queue floater dismissed." << LL_ENDL; -            break;          } -    } - -    floater = hfloater.get(); -    if (floater) -    {          floater->addStringMessage("Done");          floater->getChildView("close")->setEnabled(TRUE);      } +    catch (LLCheckedHandleBase::Stale &) +    { +        // This is expected.  It means that floater has been closed before  +        // processing was completed. +        LL_DEBUGS("SCRIPTQ") << "LLExeceptionStaleHandle caught! Floater has most likely been closed." << LL_ENDL; +    }  } diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp index 024e315632..dece3fc1ea 100644 --- a/indra/newview/llfloaterwebcontent.cpp +++ b/indra/newview/llfloaterwebcontent.cpp @@ -55,7 +55,8 @@ LLFloaterWebContent::_Params::_Params()  	preferred_media_size("preferred_media_size"),  	trusted_content("trusted_content", false),  	show_page_title("show_page_title", true), -    clean_browser("clean_browser", false) +	clean_browser("clean_browser", false), +	dev_mode("dev_mode", false)  {}  LLFloaterWebContent::LLFloaterWebContent( const Params& params ) @@ -74,14 +75,16 @@ LLFloaterWebContent::LLFloaterWebContent( const Params& params )  	mShowPageTitle(params.show_page_title),      mAllowNavigation(true),      mCurrentURL(""), -    mDisplayURL("") +    mDisplayURL(""), +    mDevelopMode(params.dev_mode) // if called from "Develop" Menu, set a flag and change things to be more useful for devs  {  	mCommitCallbackRegistrar.add( "WebContent.Back", boost::bind( &LLFloaterWebContent::onClickBack, this ));  	mCommitCallbackRegistrar.add( "WebContent.Forward", boost::bind( &LLFloaterWebContent::onClickForward, this ));  	mCommitCallbackRegistrar.add( "WebContent.Reload", boost::bind( &LLFloaterWebContent::onClickReload, this ));  	mCommitCallbackRegistrar.add( "WebContent.Stop", boost::bind( &LLFloaterWebContent::onClickStop, this ));  	mCommitCallbackRegistrar.add( "WebContent.EnterAddress", boost::bind( &LLFloaterWebContent::onEnterAddress, this )); -	mCommitCallbackRegistrar.add( "WebContent.PopExternal", boost::bind( &LLFloaterWebContent::onPopExternal, this )); +	mCommitCallbackRegistrar.add( "WebContent.PopExternal", boost::bind(&LLFloaterWebContent::onPopExternal, this)); +	mCommitCallbackRegistrar.add( "WebContent.TestURL", boost::bind(&LLFloaterWebContent::onTestURL, this, _2));  }  BOOL LLFloaterWebContent::postBuild() @@ -195,8 +198,6 @@ void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height)  						width + getRect().getWidth() - browser_rect.getWidth(),   						height + getRect().getHeight() - browser_rect.getHeight()); -	LL_DEBUGS() << "geometry change: " << geom << LL_ENDL; -	  	LLRect new_rect;  	getParent()->screenRectToLocal(geom, &new_rect);  	setShape(new_rect);	 @@ -205,8 +206,6 @@ void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height)  // static  void LLFloaterWebContent::preCreate(LLFloaterWebContent::Params& p)  { -	LL_DEBUGS() << "url = " << p.url() << ", target = " << p.target() << ", uuid = " << p.id() << LL_ENDL; -  	if (!p.id.isProvided())  	{  		p.id = LLUUID::generateNewID().asString(); @@ -224,12 +223,6 @@ void LLFloaterWebContent::preCreate(LLFloaterWebContent::Params& p)  		// and close the least recently opened one if this will put us over the limit.  		LLFloaterReg::const_instance_list_t &instances = LLFloaterReg::getFloaterList(p.window_class); -		LL_DEBUGS() << "total instance count is " << instances.size() << LL_ENDL; - -		for(LLFloaterReg::const_instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); iter++) -		{ -			LL_DEBUGS() << "    " << (*iter)->getKey()["target"] << LL_ENDL; -		}  		if(instances.size() >= (size_t)browser_window_limit)  		{ @@ -241,16 +234,19 @@ void LLFloaterWebContent::preCreate(LLFloaterWebContent::Params& p)  void LLFloaterWebContent::open_media(const Params& p)  { -	// Specifying a mime type of text/html here causes the plugin system to skip the MIME type probe and just open a browser plugin.  	LLViewerMedia::proxyWindowOpened(p.target(), p.id()); -	mWebBrowser->setHomePageUrl(p.url, HTTP_CONTENT_TEXT_HTML); +	mWebBrowser->setHomePageUrl(p.url);  	mWebBrowser->setTarget(p.target); -	mWebBrowser->navigateTo(p.url, HTTP_CONTENT_TEXT_HTML, p.clean_browser); +	mWebBrowser->navigateTo(p.url);  	set_current_url(p.url);  	getChild<LLLayoutPanel>("status_bar")->setVisible(p.show_chrome);  	getChild<LLLayoutPanel>("nav_controls")->setVisible(p.show_chrome); + +	// turn additional debug controls on but only for Develop mode (Develop menu open) +	getChild<LLLayoutPanel>("debug_controls")->setVisible(mDevelopMode); +  	bool address_entry_enabled = p.allow_address_entry && !p.trusted_content;      mAllowNavigation = p.allow_back_forward_navigation;  	getChildView("address")->setEnabled(address_entry_enabled); @@ -499,7 +495,7 @@ void LLFloaterWebContent::onEnterAddress()      LLStringUtil::trim(url);  	if ( url.length() > 0 )  	{ -		mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML); +		mWebBrowser->navigateTo(url);  	};  } @@ -508,9 +504,18 @@ void LLFloaterWebContent::onPopExternal()  	// make sure there is at least something there.  	// (perhaps this test should be for minimum length of a URL)  	std::string url = mAddressCombo->getValue().asString(); -    LLStringUtil::trim(url); -	if ( url.length() > 0 ) +	LLStringUtil::trim(url); +	if (url.length() > 0) +	{ +		LLWeb::loadURLExternal(url); +	}; +} + +void LLFloaterWebContent::onTestURL(std::string url) +{ +	LLStringUtil::trim(url); +	if (url.length() > 0)  	{ -		LLWeb::loadURLExternal( url ); +		mWebBrowser->navigateTo(url);  	};  } diff --git a/indra/newview/llfloaterwebcontent.h b/indra/newview/llfloaterwebcontent.h index 4291fd9f2c..0bf93504c2 100644 --- a/indra/newview/llfloaterwebcontent.h +++ b/indra/newview/llfloaterwebcontent.h @@ -58,7 +58,8 @@ public:                                  allow_back_forward_navigation,  								trusted_content,  								show_page_title, -                                clean_browser; +								clean_browser, +								dev_mode;  		Optional<LLRect>		preferred_media_size;  		_Params(); @@ -92,6 +93,7 @@ protected:  	void onClickStop();  	void onEnterAddress();  	void onPopExternal(); +	void onTestURL(std::string url);  	static void preCreate(Params& p);  	void open_media(const Params& ); @@ -113,6 +115,7 @@ protected:  	std::string		mUUID;  	bool			mShowPageTitle;      bool            mAllowNavigation; +	bool			mDevelopMode;  };  #endif  // LL_LLFLOATERWEBCONTENT_H diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp index 763657ebad..0bcd8a9e63 100644 --- a/indra/newview/llpanelprimmediacontrols.cpp +++ b/indra/newview/llpanelprimmediacontrols.cpp @@ -95,7 +95,8 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() :  	mVolumeSliderVisible(0),  	mWindowShade(NULL),  	mHideImmediately(false), -    mSecureURL(false) +    mSecureURL(false), +	mMediaPlaySliderCtrlMouseDownValue(0.0)  {  	mCommitCallbackRegistrar.add("MediaCtrl.Close",		boost::bind(&LLPanelPrimMediaControls::onClickClose, this));  	mCommitCallbackRegistrar.add("MediaCtrl.Back",		boost::bind(&LLPanelPrimMediaControls::onClickBack, this)); @@ -109,7 +110,8 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() :  	mCommitCallbackRegistrar.add("MediaCtrl.Open",		boost::bind(&LLPanelPrimMediaControls::onClickOpen, this));  	mCommitCallbackRegistrar.add("MediaCtrl.Zoom",		boost::bind(&LLPanelPrimMediaControls::onClickZoom, this));  	mCommitCallbackRegistrar.add("MediaCtrl.CommitURL",	boost::bind(&LLPanelPrimMediaControls::onCommitURL, this)); -	mCommitCallbackRegistrar.add("MediaCtrl.JumpProgress",		boost::bind(&LLPanelPrimMediaControls::onCommitSlider, this)); +	mCommitCallbackRegistrar.add("MediaCtrl.MouseDown", boost::bind(&LLPanelPrimMediaControls::onMediaPlaySliderCtrlMouseDown, this)); +	mCommitCallbackRegistrar.add("MediaCtrl.MouseUp", boost::bind(&LLPanelPrimMediaControls::onMediaPlaySliderCtrlMouseUp, this));  	mCommitCallbackRegistrar.add("MediaCtrl.CommitVolumeUp",	boost::bind(&LLPanelPrimMediaControls::onCommitVolumeUp, this));  	mCommitCallbackRegistrar.add("MediaCtrl.CommitVolumeDown",	boost::bind(&LLPanelPrimMediaControls::onCommitVolumeDown, this));  	mCommitCallbackRegistrar.add("MediaCtrl.Volume",	boost::bind(&LLPanelPrimMediaControls::onCommitVolumeSlider, this)); @@ -1246,26 +1248,38 @@ void LLPanelPrimMediaControls::setCurrentURL()  #endif	// USE_COMBO_BOX_FOR_MEDIA_URL  } -void LLPanelPrimMediaControls::onCommitSlider() + +void LLPanelPrimMediaControls::onMediaPlaySliderCtrlMouseDown()  { -	focusOnTarget(); +	mMediaPlaySliderCtrlMouseDownValue = mMediaPlaySliderCtrl->getValue().asReal(); -	LLViewerMediaImpl* media_impl = getTargetMediaImpl(); -	if (media_impl)  +	mUpdateSlider = false; +} + +void LLPanelPrimMediaControls::onMediaPlaySliderCtrlMouseUp() +{ +	F64 cur_value = mMediaPlaySliderCtrl->getValue().asReal(); + +	if (mMediaPlaySliderCtrlMouseDownValue != cur_value)  	{ -		// get slider value -		F64 slider_value = mMediaPlaySliderCtrl->getValue().asReal(); -		if(slider_value <= 0.0) -		{	 -			media_impl->stop(); -		} -		else  +		focusOnTarget(); + +		LLViewerMediaImpl* media_impl = getTargetMediaImpl(); +		if (media_impl)  		{ -			media_impl->seek(slider_value*mMovieDuration); -			//mUpdateSlider= false; +			if (cur_value <= 0.0) +			{ +				media_impl->stop(); +			} +			else +			{ +				media_impl->seek(cur_value * mMovieDuration); +			}  		} + +		mUpdateSlider = true;  	} -}		 +}  void LLPanelPrimMediaControls::onCommitVolumeUp()  { diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h index 6d2eb3430e..21d5236074 100644 --- a/indra/newview/llpanelprimmediacontrols.h +++ b/indra/newview/llpanelprimmediacontrols.h @@ -107,8 +107,10 @@ private:  	void updateZoom();  	void setCurrentURL(); -	void onCommitSlider(); -	 + +	void onMediaPlaySliderCtrlMouseDown(); +	void onMediaPlaySliderCtrlMouseUp(); +  	void onCommitVolumeUp();  	void onCommitVolumeDown();  	void onCommitVolumeSlider(); @@ -219,6 +221,8 @@ private:  	S32 mVolumeSliderVisible;  	LLNotificationPtr mActiveNotification; + +	F64 mMediaPlaySliderCtrlMouseDownValue;  };  #endif // LL_PANELPRIMMEDIACONTROLS_H diff --git a/indra/newview/llsecapi.cpp b/indra/newview/llsecapi.cpp index 4f9f83b6f2..72d7cf1e45 100644 --- a/indra/newview/llsecapi.cpp +++ b/indra/newview/llsecapi.cpp @@ -29,6 +29,8 @@  #include "llviewerprecompiledheaders.h"  #include "llsecapi.h"  #include "llsechandler_basic.h" +#include "llexception.h" +#include "stringize.h"  #include <openssl/evp.h>  #include <openssl/err.h>  #include <map> @@ -64,12 +66,12 @@ void initializeSecHandler()  		}  		catch (LLProtectedDataException e)  		{ -			exception_msg = e.getMessage(); +			exception_msg = e.what();  		}  	}  	if (!exception_msg.empty())  // an exception was thrown.  	{ -		throw LLProtectedDataException(exception_msg.c_str()); +		LLTHROW(LLProtectedDataException(exception_msg));  	}  } @@ -101,6 +103,7 @@ std::ostream& operator <<(std::ostream& s, const LLCredential& cred)  LLSD LLCredential::getLoginParams()  {  	LLSD result = LLSD::emptyMap(); +	std::string username;  	try   	{  		if (mIdentifier["type"].asString() == "agent") @@ -109,17 +112,19 @@ LLSD LLCredential::getLoginParams()  			result["passwd"] = "$1$" + mAuthenticator["secret"].asString();  			result["first"] = mIdentifier["first_name"];  			result["last"] = mIdentifier["last_name"]; -		 +			username = result["first"].asString() + " " + result["last"].asString();  		}  		else if (mIdentifier["type"].asString() == "account")  		{  			result["username"] = mIdentifier["account_name"];  			result["passwd"] = mAuthenticator["secret"]; -										 +			username = result["username"].asString();  		}  	}  	catch (...)  	{ +		// nat 2016-08-18: not clear what exceptions the above COULD throw?! +		LOG_UNHANDLED_EXCEPTION(STRINGIZE("for '" << username << "'"));  		// we could have corrupt data, so simply return a null login param if so  		LL_WARNS("AppInit") << "Invalid credential" << LL_ENDL;  	} diff --git a/indra/newview/llsecapi.h b/indra/newview/llsecapi.h index 6fe3ee31cf..6af5a28fa5 100644 --- a/indra/newview/llsecapi.h +++ b/indra/newview/llsecapi.h @@ -32,6 +32,7 @@  #include <openssl/x509.h>  #include <ostream>  #include "llpointer.h" +#include "llexception.h"  #ifdef LL_WINDOWS  #pragma warning(disable:4250) @@ -116,17 +117,13 @@ -class LLProtectedDataException +struct LLProtectedDataException: public LLException  { -public: -	LLProtectedDataException(const char *msg)  +	LLProtectedDataException(const std::string& msg): +		LLException(msg)  	{ -		LL_WARNS("SECAPI") << "Protected Data Error: " << (std::string)msg << LL_ENDL; -		mMsg = (std::string)msg; +		LL_WARNS("SECAPI") << "Protected Data Error: " << msg << LL_ENDL;  	} -	std::string getMessage() { return mMsg; } -protected: -	std::string mMsg;  };  // class LLCertificate @@ -334,22 +331,21 @@ std::ostream& operator <<(std::ostream& s, const LLCredential& cred);  // All error handling is via exceptions. -class LLCertException +class LLCertException: public LLException  {  public: -	LLCertException(LLPointer<LLCertificate> cert, const char* msg) +	LLCertException(LLPointer<LLCertificate> cert, const std::string& msg): +		LLException(msg)  	{  		mCert = cert; -		LL_WARNS("SECAPI") << "Certificate Error: " << (std::string)msg << LL_ENDL; -		mMsg = (std::string)msg; +		LL_WARNS("SECAPI") << "Certificate Error: " << msg << LL_ENDL;  	} -	LLPointer<LLCertificate> getCert() { return mCert; } -	std::string getMessage() { return mMsg; } +	virtual ~LLCertException() throw() {} +	LLPointer<LLCertificate> getCert() const { return mCert; }  protected:  	LLPointer<LLCertificate> mCert; -	std::string mMsg;  };  class LLInvalidCertificate : public LLCertException @@ -358,6 +354,7 @@ public:  	LLInvalidCertificate(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertInvalid")  	{  	} +	virtual ~LLInvalidCertificate() throw() {}  protected:  }; @@ -367,6 +364,7 @@ public:  	LLCertValidationTrustException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertUntrusted")  	{  	} +	virtual ~LLCertValidationTrustException() throw() {}  protected:  }; @@ -378,7 +376,7 @@ public:  	{  		mHostname = hostname;  	} -	 +	virtual ~LLCertValidationHostnameException() throw() {}  	std::string getHostname() { return mHostname; }  protected:  	std::string mHostname; @@ -392,6 +390,7 @@ public:  	{  		mTime = current_time;  	} +	virtual ~LLCertValidationExpirationException() throw() {}  	LLDate GetTime() { return mTime; }  protected:  	LLDate mTime; @@ -403,6 +402,7 @@ public:  	LLCertKeyUsageValidationException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertKeyUsage")  	{  	} +	virtual ~LLCertKeyUsageValidationException() throw() {}  protected:  }; @@ -412,6 +412,7 @@ public:  	LLCertBasicConstraintsValidationException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertBasicConstraints")  	{  	} +	virtual ~LLCertBasicConstraintsValidationException() throw() {}  protected:  }; @@ -421,6 +422,7 @@ public:  	LLCertValidationInvalidSignatureException(LLPointer<LLCertificate> cert) : LLCertException(cert, "CertInvalidSignature")  	{  	} +	virtual ~LLCertValidationInvalidSignatureException() throw() {}  protected:  }; diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp index 40516f9bbb..d6fb801cc0 100644 --- a/indra/newview/llsechandler_basic.cpp +++ b/indra/newview/llsechandler_basic.cpp @@ -35,6 +35,8 @@  #include "llfile.h"  #include "lldir.h"  #include "llviewercontrol.h" +#include "llexception.h" +#include "stringize.h"  #include <vector>  #include <ios>  #include <openssl/ossl_typ.h> @@ -72,14 +74,14 @@ LLBasicCertificate::LLBasicCertificate(const std::string& pem_cert)  	if(pem_bio == NULL)  	{  		LL_WARNS("SECAPI") << "Could not allocate an openssl memory BIO." << LL_ENDL; -		throw LLInvalidCertificate(this); +		LLTHROW(LLInvalidCertificate(this));  	}  	mCert = NULL;  	PEM_read_bio_X509(pem_bio, &mCert, 0, NULL);  	BIO_free(pem_bio);  	if (!mCert)  	{ -		throw LLInvalidCertificate(this); +		LLTHROW(LLInvalidCertificate(this));  	}  } @@ -88,7 +90,7 @@ LLBasicCertificate::LLBasicCertificate(X509* pCert)  {  	if (!pCert || !pCert->cert_info)  	{ -		throw LLInvalidCertificate(this); +		LLTHROW(LLInvalidCertificate(this));  	}	  	mCert = X509_dup(pCert);  } @@ -617,7 +619,7 @@ void LLBasicCertificateStore::load_from_file(const std::string& filename)  				}  				catch (...)  				{ -					LL_WARNS("SECAPI") << "Failure creating certificate from the certificate store file." << LL_ENDL; +					LOG_UNHANDLED_EXCEPTION("creating certificate from the certificate store file");  				}  				X509_free(cert_x509);  				cert_x509 = NULL; @@ -873,22 +875,22 @@ void _validateCert(int validation_policy,  	// check basic properties exist in the cert  	if(!current_cert_info.has(CERT_SUBJECT_NAME) || !current_cert_info.has(CERT_SUBJECT_NAME_STRING))  	{ -		throw LLCertException(cert, "Cert doesn't have a Subject Name");				 +		LLTHROW(LLCertException(cert, "Cert doesn't have a Subject Name"));  	}  	if(!current_cert_info.has(CERT_ISSUER_NAME_STRING))  	{ -		throw LLCertException(cert, "Cert doesn't have an Issuer Name");				 +		LLTHROW(LLCertException(cert, "Cert doesn't have an Issuer Name"));  	}  	// check basic properties exist in the cert  	if(!current_cert_info.has(CERT_VALID_FROM) || !current_cert_info.has(CERT_VALID_TO))  	{ -		throw LLCertException(cert, "Cert doesn't have an expiration period");				 +		LLTHROW(LLCertException(cert, "Cert doesn't have an expiration period"));  	}  	if (!current_cert_info.has(CERT_SHA1_DIGEST))  	{ -		throw LLCertException(cert, "No SHA1 digest"); +		LLTHROW(LLCertException(cert, "No SHA1 digest"));  	}  	if (validation_policy & VALIDATION_POLICY_TIME) @@ -903,7 +905,7 @@ void _validateCert(int validation_policy,  		if((validation_date < current_cert_info[CERT_VALID_FROM].asDate()) ||  		   (validation_date > current_cert_info[CERT_VALID_TO].asDate()))  		{ -			throw LLCertValidationExpirationException(cert, validation_date); +			LLTHROW(LLCertValidationExpirationException(cert, validation_date));  		}  	}  	if (validation_policy & VALIDATION_POLICY_SSL_KU) @@ -914,14 +916,14 @@ void _validateCert(int validation_policy,  			!(_LLSDArrayIncludesValue(current_cert_info[CERT_KEY_USAGE],   									  LLSD((std::string)CERT_KU_KEY_ENCIPHERMENT)))))  		{ -			throw LLCertKeyUsageValidationException(cert); +			LLTHROW(LLCertKeyUsageValidationException(cert));  		}  		// only validate EKU if the cert has it  		if(current_cert_info.has(CERT_EXTENDED_KEY_USAGE) && current_cert_info[CERT_EXTENDED_KEY_USAGE].isArray() &&	     		   (!_LLSDArrayIncludesValue(current_cert_info[CERT_EXTENDED_KEY_USAGE],   									LLSD((std::string)CERT_EKU_SERVER_AUTH))))  		{ -			throw LLCertKeyUsageValidationException(cert);			 +			LLTHROW(LLCertKeyUsageValidationException(cert));  		}  	}  	if (validation_policy & VALIDATION_POLICY_CA_KU) @@ -930,7 +932,7 @@ void _validateCert(int validation_policy,  			(!_LLSDArrayIncludesValue(current_cert_info[CERT_KEY_USAGE],   									   (std::string)CERT_KU_CERT_SIGN)))  			{ -				throw LLCertKeyUsageValidationException(cert);						 +				LLTHROW(LLCertKeyUsageValidationException(cert));  			}  	} @@ -942,13 +944,13 @@ void _validateCert(int validation_policy,  		if(!current_cert_info[CERT_BASIC_CONSTRAINTS].has(CERT_BASIC_CONSTRAINTS_CA) ||  		   !current_cert_info[CERT_BASIC_CONSTRAINTS][CERT_BASIC_CONSTRAINTS_CA])  		{ -				throw LLCertBasicConstraintsValidationException(cert); +				LLTHROW(LLCertBasicConstraintsValidationException(cert));  		}  		if (current_cert_info[CERT_BASIC_CONSTRAINTS].has(CERT_BASIC_CONSTRAINTS_PATHLEN) &&  			((current_cert_info[CERT_BASIC_CONSTRAINTS][CERT_BASIC_CONSTRAINTS_PATHLEN].asInteger() != 0) &&  			 (depth > current_cert_info[CERT_BASIC_CONSTRAINTS][CERT_BASIC_CONSTRAINTS_PATHLEN].asInteger())))  		{ -			throw LLCertBasicConstraintsValidationException(cert);					 +			LLTHROW(LLCertBasicConstraintsValidationException(cert));  		}  	}  } @@ -1018,7 +1020,7 @@ void LLBasicCertificateStore::validate(int validation_policy,  	if(cert_chain->size() < 1)  	{ -		throw LLCertException(NULL, "No certs in chain"); +		LLTHROW(LLCertException(NULL, "No certs in chain"));  	}  	iterator current_cert = cert_chain->begin();  	LLSD 	current_cert_info; @@ -1033,11 +1035,11 @@ void LLBasicCertificateStore::validate(int validation_policy,  		(*current_cert)->getLLSD(current_cert_info);  		if(!validation_params.has(CERT_HOSTNAME))  		{ -			throw LLCertException((*current_cert), "No hostname passed in for validation");			 +			LLTHROW(LLCertException((*current_cert), "No hostname passed in for validation"));  		}  		if(!current_cert_info.has(CERT_SUBJECT_NAME) || !current_cert_info[CERT_SUBJECT_NAME].has(CERT_NAME_CN))  		{ -			throw LLInvalidCertificate((*current_cert));				 +			LLTHROW(LLInvalidCertificate((*current_cert)));  		}  		LL_DEBUGS("SECAPI") << "Validating the hostname " << validation_params[CERT_HOSTNAME].asString() <<  @@ -1054,7 +1056,7 @@ void LLBasicCertificateStore::validate(int validation_policy,  	X509* cert_x509 = (*current_cert)->getOpenSSLX509();  	if(!cert_x509)  	{ -		throw LLInvalidCertificate((*current_cert));			 +		LLTHROW(LLInvalidCertificate((*current_cert)));  	}  	std::string sha1_hash((const char *)cert_x509->sha1_hash, SHA_DIGEST_LENGTH);  	X509_free( cert_x509 ); @@ -1075,7 +1077,7 @@ void LLBasicCertificateStore::validate(int validation_policy,  			if((validation_date < cache_entry->second.first) ||  			   (validation_date > cache_entry->second.second))  			{ -				throw LLCertValidationExpirationException((*current_cert), validation_date); +				LLTHROW(LLCertValidationExpirationException((*current_cert), validation_date));  			}  		}  		// successfully found in cache @@ -1107,7 +1109,7 @@ void LLBasicCertificateStore::validate(int validation_policy,  			if(!_verify_signature((*current_cert),  								  previous_cert))  			{ -			   throw LLCertValidationInvalidSignatureException(previous_cert); +			   LLTHROW(LLCertValidationInvalidSignatureException(previous_cert));  			}  		}  		_validateCert(local_validation_policy, @@ -1156,7 +1158,7 @@ void LLBasicCertificateStore::validate(int validation_policy,  			if(!_verify_signature((*found_store_cert),  								  (*current_cert)))  			{ -				throw LLCertValidationInvalidSignatureException(*current_cert); +				LLTHROW(LLCertValidationInvalidSignatureException(*current_cert));  			}			  			// successfully validated.  			mTrustedCertCache[sha1_hash] = std::pair<LLDate, LLDate>(from_time, to_time);		 @@ -1173,7 +1175,7 @@ void LLBasicCertificateStore::validate(int validation_policy,  	if (validation_policy & VALIDATION_POLICY_TRUSTED)  	{  		// we reached the end without finding a trusted cert. -		throw LLCertValidationTrustException((*cert_chain)[cert_chain->size()-1]); +		LLTHROW(LLCertValidationTrustException((*cert_chain)[cert_chain->size()-1]));  	}  	mTrustedCertCache[sha1_hash] = std::pair<LLDate, LLDate>(from_time, to_time);	 @@ -1261,7 +1263,7 @@ void LLSecAPIBasicHandler::_readProtectedData()  		protected_data_stream.read((char *)salt, STORE_SALT_SIZE);  		if (protected_data_stream.gcount() < STORE_SALT_SIZE)  		{ -			throw LLProtectedDataException("Config file too short."); +			LLTHROW(LLProtectedDataException("Config file too short."));  		}  		cipher.decrypt(salt, STORE_SALT_SIZE);		 @@ -1301,7 +1303,7 @@ void LLSecAPIBasicHandler::_readProtectedData()  		if (parser->parse(parse_stream, mProtectedDataMap,   						  LLSDSerialize::SIZE_UNLIMITED) == LLSDParser::PARSE_FAILURE)  		{ -			throw LLProtectedDataException("Config file cannot be decrypted."); +			LLTHROW(LLProtectedDataException("Config file cannot be decrypted."));  		}  	}  } @@ -1364,7 +1366,7 @@ void LLSecAPIBasicHandler::_writeProtectedData()  	}  	catch (...)  	{ -		LL_WARNS() << "LLProtectedDataException(Error writing Protected Data Store)" << LL_ENDL; +		LOG_UNHANDLED_EXCEPTION("LLProtectedDataException(Error writing Protected Data Store)");  		// it's good practice to clean up any secure information on error  		// (even though this file isn't really secure.  Perhaps in the future  		// it may be, however. @@ -1372,39 +1374,39 @@ void LLSecAPIBasicHandler::_writeProtectedData()  		// EXP-1825 crash in LLSecAPIBasicHandler::_writeProtectedData()  		// Decided throwing an exception here was overkill until we figure out why this happens -		//throw LLProtectedDataException("Error writing Protected Data Store"); +		//LLTHROW(LLProtectedDataException("Error writing Protected Data Store"));  	} -    try -    { -        // move the temporary file to the specified file location. -        if(((   (LLFile::isfile(mProtectedDataFilename) != 0) -             && (LLFile::remove(mProtectedDataFilename) != 0))) -           || (LLFile::rename(tmp_filename, mProtectedDataFilename))) -        { -            LL_WARNS() << "LLProtectedDataException(Could not overwrite protected data store)" << LL_ENDL; -            LLFile::remove(tmp_filename); +	try +	{ +		// move the temporary file to the specified file location. +		if(((	(LLFile::isfile(mProtectedDataFilename) != 0) +			 && (LLFile::remove(mProtectedDataFilename) != 0))) +		   || (LLFile::rename(tmp_filename, mProtectedDataFilename))) +		{ +			LL_WARNS() << "LLProtectedDataException(Could not overwrite protected data store)" << LL_ENDL; +			LLFile::remove(tmp_filename); -            // EXP-1825 crash in LLSecAPIBasicHandler::_writeProtectedData() -            // Decided throwing an exception here was overkill until we figure out why this happens -            //throw LLProtectedDataException("Could not overwrite protected data store"); -        } +			// EXP-1825 crash in LLSecAPIBasicHandler::_writeProtectedData() +			// Decided throwing an exception here was overkill until we figure out why this happens +			//LLTHROW(LLProtectedDataException("Could not overwrite protected data store")); +		}  	}  	catch (...)  	{ -		LL_WARNS() << "LLProtectedDataException(Error renaming '" << tmp_filename -                   << "' to '" << mProtectedDataFilename << "')" << LL_ENDL; +		LOG_UNHANDLED_EXCEPTION(STRINGIZE("renaming '" << tmp_filename << "' to '" +										  << mProtectedDataFilename << "'"));  		// it's good practice to clean up any secure information on error  		// (even though this file isn't really secure.  Perhaps in the future -		// it may be, however. +		// it may be, however).  		LLFile::remove(tmp_filename);  		//crash in LLSecAPIBasicHandler::_writeProtectedData()  		// Decided throwing an exception here was overkill until we figure out why this happens -		//throw LLProtectedDataException("Error writing Protected Data Store"); +		//LLTHROW(LLProtectedDataException("Error writing Protected Data Store"));  	}  } -		 +  // instantiate a certificate from a pem string  LLPointer<LLCertificate> LLSecAPIBasicHandler::getCertificate(const std::string& pem_cert)  { diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index 2d06b8599c..d28a7cc048 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -230,8 +230,8 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3  	const F32 xyScaleInv = (1.f / xyScale)*(0.2222222222f);  	F32 vec[3] = { -					fmod((F32)(mOriginGlobal.mdV[0] + x)*xyScaleInv, 256.f), -					fmod((F32)(mOriginGlobal.mdV[1] + y)*xyScaleInv, 256.f), +                    (F32)fmod((F32)(mOriginGlobal.mdV[0] + x)*xyScaleInv, 256.f), +                    (F32)fmod((F32)(mOriginGlobal.mdV[1] + y)*xyScaleInv, 256.f),  					0.f  				};  	F32 rand_val = llclamp(noise2(vec)* 0.75f + 0.5f, 0.f, 1.f); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 46f03f9971..39059fc01e 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7908,7 +7908,7 @@ void handle_web_browser_test(const LLSD& param)  void handle_web_content_test(const LLSD& param)  {  	std::string url = param.asString(); -	LLWeb::loadURLInternal(url); +	LLWeb::loadURLInternal(url, LLStringUtil::null, LLStringUtil::null, true);  }  void handle_show_url(const LLSD& param) diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index b37e41fb85..8026dc3ea8 100644 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -104,10 +104,10 @@ void LLWeb::loadURL(const std::string& url, const std::string& target, const std  // static  // Explicitly open a Web URL using the Web content floater -void LLWeb::loadURLInternal(const std::string &url, const std::string& target, const std::string& uuid) +void LLWeb::loadURLInternal(const std::string &url, const std::string& target, const std::string& uuid, bool dev_mode)  {  	LLFloaterWebContent::Params p; -	p.url(url).target(target).id(uuid); +	p.url(url).target(target).id(uuid).dev_mode(dev_mode);  	LLFloaterReg::showInstance("web_content", p);  } diff --git a/indra/newview/llweb.h b/indra/newview/llweb.h index 7c90badbfe..7149ce9baf 100644 --- a/indra/newview/llweb.h +++ b/indra/newview/llweb.h @@ -57,7 +57,7 @@ public:  	static void loadURL(const std::string& url, const std::string& target = LLStringUtil::null, const std::string& uuid = LLStringUtil::null);  	// load content using built-in browser -	static void loadURLInternal(const std::string &url, const std::string& target = LLStringUtil::null, const std::string& uuid = LLStringUtil::null); +	static void loadURLInternal(const std::string &url, const std::string& target = LLStringUtil::null, const std::string& uuid = LLStringUtil::null, bool dev_mode = false);  	/// Returns escaped url (eg, " " to "%20") - used by all loadURL methods  	static std::string escapeURL(const std::string& url); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 11d3706821..cee47a591e 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -957,10 +957,10 @@ void LLWorld::updateWaterObjects()  	center_y = min_y + (wy >> 1);  	S32 add_boundary[4] = { -		512 - (max_x - region_x), -		512 - (max_y - region_y), -		512 - (region_x - min_x), -		512 - (region_y - min_y) }; +		(S32)(512 - (max_x - region_x)), +		(S32)(512 - (max_y - region_y)), +		(S32)(512 - (region_x - min_x)), +		(S32)(512 - (region_y - min_y)) };  	S32 dir;  	for (dir = 0; dir < 8; dir++) diff --git a/indra/newview/skins/default/textures/icons/Video_URL_Off.png b/indra/newview/skins/default/textures/icons/Video_URL_Off.pngBinary files differ new file mode 100644 index 0000000000..40e5df7d81 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Video_URL_Off.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 30ad0a0288..f2da22256c 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -676,7 +676,10 @@ with the same filename but different name    <texture name="Unread_Chiclet" file_name="bottomtray/Unread_Chiclet.png" preload="false" />    <texture name="UpArrow_Off" file_name="icons/UpArrow_Off.png" preload="false" /> -	<texture name="Vertical Drag Handle" file_name="widgets/vertical_drag_handle.png" scale.left="2" scale.right="7" scale.bottom="8" scale.top="120"  scale_type="scale_outer"/> + +  <texture name="Video_URL_Off" file_name="icons/Video_URL_Off.png" preload="true" /> +   +  <texture name="Vertical Drag Handle" file_name="widgets/vertical_drag_handle.png" scale.left="2" scale.right="7" scale.bottom="8" scale.top="120"  scale_type="scale_outer"/>      <texture name="Volume_Background" file_name="windows/Volume_Background.png" preload="false"             scale.left="6" scale.top="33" scale.right="63" scale.bottom="10" /> diff --git a/indra/newview/skins/default/xui/en/floater_web_content.xml b/indra/newview/skins/default/xui/en/floater_web_content.xml index a80440e844..4473ce0cda 100644 --- a/indra/newview/skins/default/xui/en/floater_web_content.xml +++ b/indra/newview/skins/default/xui/en/floater_web_content.xml @@ -154,6 +154,136 @@        </button>      </layout_panel>      <layout_panel +     height="22" +     layout="topleft" +     left_delta="0" +     name="debug_controls" +     top_delta="0" +     auto_resize="false" +     width="585"> +      <button +        image_overlay="Home_Off" +            image_disabled="PushButton_Disabled" +            image_disabled_selected="PushButton_Disabled" +            image_selected="PushButton_Selected" +            image_unselected="PushButton_Off" +        chrome="true" +        tool_tip="Web tests home page" +        enabled="true" +        follows="left|top" +        height="22" +        layout="topleft" +        left="1" +        name="web_test_home_page" +        top="0" +        width="22"> +        <button.commit_callback +          function="WebContent.TestURL" +          parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/> +      </button> + +      <button +        image_overlay="Video_URL_Off" +            image_disabled="PushButton_Disabled" +            image_disabled_selected="PushButton_Disabled" +            image_selected="PushButton_Selected" +            image_unselected="PushButton_Off" +        chrome="true" +        tool_tip="MPEG4 Video Test" +        enabled="true" +        follows="left|top" +        height="22" +        layout="topleft" +        left="27" +        name="VLC Plugin Test" +        top="0" +        width="22"> +        <button.commit_callback +          function="WebContent.TestURL" +          parameter="https://callum-linden.s3.amazonaws.com/sample_media/ss.mp4"/> +      </button> +      <button +        image_overlay="Video_URL_Off" +            image_disabled="PushButton_Disabled" +            image_disabled_selected="PushButton_Disabled" +            image_selected="PushButton_Selected" +            image_unselected="PushButton_Off" +        chrome="true" +        tool_tip="MKV Video Test" +        enabled="true" +        follows="left|top" +        height="22" +        layout="topleft" +        left="51" +        name="VLC Plugin Test" +        top="0" +        width="22"> +        <button.commit_callback +          function="WebContent.TestURL" +          parameter="https://callum-linden.s3.amazonaws.com/sample_media/jellyfish.mkv"/> +      </button> +      <button +        image_overlay="Video_URL_Off" +            image_disabled="PushButton_Disabled" +            image_disabled_selected="PushButton_Disabled" +            image_selected="PushButton_Selected" +            image_unselected="PushButton_Off" +        chrome="true" +        tool_tip="WebM Video Test" +        enabled="true" +        follows="left|top" +        height="22" +        layout="topleft" +        left="75" +        name="VLC Plugin Test" +        top="0" +        width="22"> +        <button.commit_callback +          function="WebContent.TestURL" +          parameter="https://callum-linden.s3.amazonaws.com/sample_media/jumprope.webm"/> +      </button> +      <button +        image_overlay="Video_URL_Off" +            image_disabled="PushButton_Disabled" +            image_disabled_selected="PushButton_Disabled" +            image_selected="PushButton_Selected" +            image_unselected="PushButton_Off" +        chrome="true" +        tool_tip="MP3 audio Test" +        enabled="true" +        follows="left|top" +        height="22" +        layout="topleft" +        left="99" +        name="VLC Plugin Test" +        top="0" +        width="22"> +        <button.commit_callback +          function="WebContent.TestURL" +          parameter="https://callum-linden.s3.amazonaws.com/alegria.mp3"/> +      </button> +      <button +        image_overlay="Video_URL_Off" +            image_disabled="PushButton_Disabled" +            image_disabled_selected="PushButton_Disabled" +            image_selected="PushButton_Selected" +            image_unselected="PushButton_Off" +        chrome="true" +        tool_tip="FLV Test" +        enabled="true" +        follows="left|top" +        height="22" +        layout="topleft" +        left="123" +        name="VLC Plugin Test" +        top="0" +        width="22"> +        <button.commit_callback +          function="WebContent.TestURL" +          parameter="https://callum-linden.s3.amazonaws.com/sample_media/vandal.flv"/> +      </button> +    </layout_panel> +    <layout_panel        height="40"        layout="topleft"        left_delta="0" diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index dcf2da52f1..a39ee5fddd 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -225,11 +225,11 @@               parameter="message_critical" />          </menu_item_call>        <menu_item_call -       label="Web Content Floater Debug Test" -       name="Web Content Floater Debug Test"> +       label="Media Browser" +       name="Media Browser">          <menu_item_call.on_click           function="Advanced.WebContentTest" -         parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/> +         parameter="http://google.com"/>        </menu_item_call>        <menu         create_jump_keys="true" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index b189d1038f..8a649a57d1 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3141,30 +3141,13 @@           label="UI"           name="UI"           tear_off="true"> -         <!--   <menu_item_check -             label="New Bottom Bar" -             name="New Bottom Bar"> -                <menu_item_check.on_check -                 function="CheckControl" -                 parameter="BottomPanelNew" /> -                <menu_item_check.on_click -                 function="ToggleControl" -                 parameter="BottomPanelNew" /> -            </menu_item_check>--> -            <menu_item_call -             label="Media Browser Test" -             name="Web Browser Test"> -                <menu_item_call.on_click -                 function="Advanced.WebBrowserTest" -                 parameter="http://secondlife.com/app/search/slurls.html"/> -            </menu_item_call>            <menu_item_call -           label="Web Content Browser" -           name="Web Content Browser" -           shortcut="control|shift|Z"> +           label="Media Browser" +           name="Media Browser" +           shortcut="control|alt|shift|Z">              <menu_item_call.on_click               function="Advanced.WebContentTest" -             parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/> +             parameter="http://google.com"/>            </menu_item_call>            <menu_item_call             label="FB Connect Test" diff --git a/indra/newview/skins/default/xui/en/mime_types.xml b/indra/newview/skins/default/xui/en/mime_types.xml index 7cb4a6e53b..c27fac6731 100644 --- a/indra/newview/skins/default/xui/en/mime_types.xml +++ b/indra/newview/skins/default/xui/en/mime_types.xml @@ -130,10 +130,21 @@  			movie  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_cef  		</impl>  	</scheme> -	<mimetype name="blank"> +  <scheme name="libvlc"> +    <label name="libvlc_label"> +      LibVLC supported media +    </label> +    <widgettype> +      movie +    </widgettype> +    <impl> +      media_plugin_libvlc +    </impl> +  </scheme> +  <mimetype name="blank">  		<label name="blank_label">  			- None -  		</label> @@ -163,7 +174,7 @@  			audio  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="video/*"> @@ -174,7 +185,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="image/*"> @@ -196,7 +207,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="application/javascript"> @@ -218,7 +229,7 @@  			audio  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_cef  		</impl>  	</mimetype>  	<mimetype name="application/pdf"> @@ -295,7 +306,7 @@  			audio  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_cef  		</impl>  	</mimetype>  	<mimetype name="audio/mpeg"> @@ -306,7 +317,7 @@  			audio  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="audio/x-aiff"> @@ -317,7 +328,7 @@  			audio  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="audio/x-wav"> @@ -328,7 +339,7 @@  			audio  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype menu="1" name="image/bmp"> @@ -438,7 +449,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="video/mp4"> @@ -449,10 +460,21 @@  			movie  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_libvlc  		</impl>  	</mimetype> -	<mimetype menu="1" name="video/quicktime"> +  <mimetype name="application/octet-stream"> +    <label name="video/octet-stream"> +      Movie +    </label> +    <widgettype> +      movie +    </widgettype> +    <impl> +      media_plugin_libvlc +    </impl> +  </mimetype> +  <mimetype menu="1" name="video/quicktime">  		<label name="video/quicktime_label">  			Movie (QuickTime)  		</label> @@ -460,7 +482,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="video/x-ms-asf"> @@ -471,7 +493,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="video/x-ms-wmv"> @@ -482,7 +504,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_cef  		</impl>  	</mimetype>  	<mimetype menu="1" name="video/x-msvideo"> @@ -493,7 +515,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_quicktime +			media_plugin_cef  		</impl>  	</mimetype>  </mimetypes> diff --git a/indra/newview/skins/default/xui/en/mime_types_linux.xml b/indra/newview/skins/default/xui/en/mime_types_linux.xml index 84aeaf3b54..7188b1e699 100644 --- a/indra/newview/skins/default/xui/en/mime_types_linux.xml +++ b/indra/newview/skins/default/xui/en/mime_types_linux.xml @@ -130,7 +130,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</scheme>  	<mimetype name="blank"> @@ -163,7 +163,7 @@  			audio  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="video/*"> @@ -174,7 +174,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="image/*"> @@ -196,7 +196,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="application/javascript"> @@ -218,7 +218,7 @@  			audio  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="application/pdf"> @@ -295,7 +295,7 @@  			audio  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="audio/mpeg"> @@ -306,7 +306,7 @@  			audio  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="audio/x-aiff"> @@ -317,7 +317,7 @@  			audio  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="audio/x-wav"> @@ -328,7 +328,7 @@  			audio  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype menu="1" name="image/bmp"> @@ -438,7 +438,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="video/mp4"> @@ -449,7 +449,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype menu="1" name="video/quicktime"> @@ -460,7 +460,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="video/x-ms-asf"> @@ -471,7 +471,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype name="video/x-ms-wmv"> @@ -482,7 +482,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  	<mimetype menu="1" name="video/x-msvideo"> @@ -493,7 +493,7 @@  			movie  		</widgettype>  		<impl> -			media_plugin_gstreamer +			media_plugin_libvlc  		</impl>  	</mimetype>  </mimetypes> diff --git a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml index eb67d07601..068e4420bc 100644 --- a/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml +++ b/indra/newview/skins/default/xui/en/panel_prim_media_controls.xml @@ -374,9 +374,11 @@  		  layout="topleft"  		  tool_tip="Movie play progress"  		  width="200"> -		<slider_bar.commit_callback -			function="MediaCtrl.JumpProgress" /> -	  </slider_bar> +      <slider_bar.mouse_down_callback +        function="MediaCtrl.MouseDown" /> +      <slider_bar.mouse_up_callback +        function="MediaCtrl.MouseUp" /> +    </slider_bar>  	</layout_panel>  	<layout_panel  		name="skip_back" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 6bcf5c791f..e2c67fc80a 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -51,13 +51,14 @@ OpenGL Version: [OPENGL_VERSION]  J2C Decoder Version: [J2C_VERSION]  Audio Driver Version: [AUDIO_DRIVER_VERSION]  LLCEFLib/CEF Version: [LLCEFLIB_VERSION] +LibVLC Version: [LIBVLC_VERSION]  Voice Server Version: [VOICE_VERSION]  	</string>  	<string name="AboutTraffic">Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string>  	<string name="AboutTime">[month, datetime, slt] [day, datetime, slt] [year, datetime, slt] [hour, datetime, slt]:[min, datetime, slt]:[second,datetime,slt]</string>  	<string name="ErrorFetchingServerReleaseNotesURL">Error fetching server release notes URL.</string>  	<string name="BuildConfiguration">Build Configuration</string> - +	  	<!--  progress -->  	<string name="ProgressRestoring">Restoring...</string>  	<string name="ProgressChangingResolution">Changing resolution...</string> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index f3d89bb866..66d730d1ac 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -444,6 +444,11 @@ class Windows_i686_Manifest(ViewerManifest):              self.path("media_plugin_cef.dll")              self.end_prefix() +        # Media plugins - LibVLC +        if self.prefix(src='../media_plugins/libvlc/%s' % self.args['configuration'], dst="llplugin"): +            self.path("media_plugin_libvlc.dll") +            self.end_prefix() +          # winmm.dll shim          if self.prefix(src='../media_plugins/winmmshim/%s' % self.args['configuration'], dst=""):              self.path("winmm.dll") @@ -550,6 +555,12 @@ class Windows_i686_Manifest(ViewerManifest):              self.path("zh-TW.pak")              self.end_prefix() +            if self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'release'), dst="llplugin"): +                self.path("libvlc.dll") +                self.path("libvlccore.dll") +                self.path("plugins/") +                self.end_prefix() +          # pull in the crash logger and updater from other projects          # tag:"crash-logger" here as a cue to the exporter          self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'], @@ -1089,8 +1100,18 @@ class LinuxManifest(ViewerManifest):          # plugins          if self.prefix(src="", dst="bin/llplugin"):              self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so") +            self.path("../media_plugins/libvlc/libmedia_plugin_libvlc.so", "libmedia_plugin_libvlc.so")              self.end_prefix("bin/llplugin") +        if self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"): +            self.path( "plugins.dat" ) +            self.path( "*/*.so" ) +            self.end_prefix() + +        if self.prefix(src=os.path.join(os.pardir, 'packages', 'lib' ), dst="lib"): +            self.path( "libvlc*.so*" ) +            self.end_prefix() +          # llcommon          if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"):              print "Skipping llcommon.so (assuming llcommon was linked statically)" @@ -1144,7 +1165,7 @@ class LinuxManifest(ViewerManifest):      def strip_binaries(self):          if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer():              print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build" -            self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure +            self.run_command(r"find %(d)r/bin %(d)r/lib -type f \! -name update_install \! -name *.dat | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure  class Linux_i686_Manifest(LinuxManifest):      def construct(self): | 
