diff options
| author | Steven Bennetts <steve@lindenlab.com> | 2007-11-07 22:55:27 +0000 | 
|---|---|---|
| committer | Steven Bennetts <steve@lindenlab.com> | 2007-11-07 22:55:27 +0000 | 
| commit | 050dad0ce35207a4ac1562175e853590ad9b7681 (patch) | |
| tree | be5dc291d2313112e5733d8c004edfe67da6fc54 | |
| parent | 6fd04521d720a3a4904069d10e8ed970d870ba7f (diff) | |
merge svn+ssh://steve@svn/svn/linden/branches/viewer-cleanup-3 -r 73026:73079
140 files changed, 7420 insertions, 520 deletions
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 305531b9cc..829ea25e38 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -36,11 +36,23 @@  #include "../llmath/llmath.h"  #include "llformat.h" +#ifndef LL_RELEASE_FOR_DOWNLOAD +#define NAME_UNNAMED_NAMESPACE +#endif + +#ifdef NAME_UNNAMED_NAMESPACE +namespace LLSDUnnamedNamespace { +#else  namespace { +#endif  	class ImplMap;  	class ImplArray;  } +#ifdef NAME_UNNAMED_NAMESPACE +using namespace LLSDUnnamedNamespace; +#endif +  class LLSD::Impl  	/**< This class is the abstract base class of the implementation of LLSD  		 It provides the reference counting implementation, and the default @@ -125,7 +137,11 @@ public:  	static U32 sOutstandingCount;  }; +#ifdef NAME_UNNAMED_NAMESPACE +namespace LLSDUnnamedNamespace { +#else  namespace { +#endif  	template<LLSD::Type T, class Data, class DataRef = Data>  	class ImplBase : public LLSD::Impl  		///< This class handles most of the work for a subclass of Impl @@ -632,7 +648,11 @@ U32 LLSD::Impl::sOutstandingCount = 0; +#ifdef NAME_UNNAMED_NAMESPACE +namespace LLSDUnnamedNamespace { +#else  namespace { +#endif  	inline LLSD::Impl& safe(LLSD::Impl* impl)  		{ return LLSD::Impl::safe(impl); } diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index 01976b12f1..9b5e6cd4e6 100644 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -367,6 +367,11 @@ LLCurl::getByteRange(const std::string& url, S32 offset, S32 length, ResponderPt  	mainMulti()->getByteRange(url, offset, length, responder);  } +void LLCurl::initClass() +{ +    curl_global_init(CURL_GLOBAL_ALL); +} +  void  LLCurl::process()  { diff --git a/indra/llmessage/llcurl.h b/indra/llmessage/llcurl.h index d21cdc4e47..53287c2988 100644 --- a/indra/llmessage/llcurl.h +++ b/indra/llmessage/llcurl.h @@ -130,8 +130,9 @@ public:  	static void get(const std::string& url, ResponderPtr);  	static void getByteRange(const std::string& url, S32 offset, S32 length, ResponderPtr responder); +    static void initClass(); // *NOTE:Mani - not thread safe!  	static void process(); -	static void cleanup(); +	static void cleanup(); // *NOTE:Mani - not thread safe!  };  namespace boost diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 36ccc32255..26ce473e08 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -368,9 +368,6 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask)  				(*mClickedCallback)( mCallbackUserData );  			}			  		} - -		mMouseDownTimer.stop(); -		mMouseDownTimer.reset();  	}  	return TRUE; diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index c0b0788c0b..efd42455e5 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -49,6 +49,9 @@ LLTextBox::LLTextBox(const LLString& name, const LLRect& rect, const LLString& t  	mDisabledColor(		LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ),  	mBackgroundColor(	LLUI::sColorsGroup->getColor( "DefaultBackgroundColor" ) ),  	mBorderColor(		LLUI::sColorsGroup->getColor( "DefaultHighlightLight" ) ), +	mHoverColor(		LLUI::sColorsGroup->getColor( "LabelSelectedColor" ) ), +	mHoverActive( FALSE ), +	mHasHover( FALSE ),  	mBackgroundVisible( FALSE ),  	mBorderVisible( FALSE ),  	mFontStyle(LLFontGL::DROP_SHADOW_SOFT), @@ -74,6 +77,9 @@ LLTextBox::LLTextBox(const LLString& name, const LLString& text, F32 max_width,  	mDisabledColor(LLUI::sColorsGroup->getColor("LabelDisabledColor")),  	mBackgroundColor(LLUI::sColorsGroup->getColor("DefaultBackgroundColor")),  	mBorderColor(LLUI::sColorsGroup->getColor("DefaultHighlightLight")), +	mHoverColor( LLUI::sColorsGroup->getColor( "LabelSelectedColor" ) ), +	mHoverActive( FALSE ), +	mHasHover( FALSE ),  	mBackgroundVisible(FALSE),  	mBorderVisible(FALSE),  	mFontStyle(LLFontGL::DROP_SHADOW_SOFT), @@ -161,6 +167,16 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask)  	return handled;  } +BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask) +{ +	if(mHoverActive) +	{ +		mHasHover = TRUE; // This should be set every frame during a hover. +		return TRUE; +	} +	return FALSE; +} +  void LLTextBox::setText(const LLStringExplicit& text)  {  	mText.assign(text); @@ -334,7 +350,15 @@ void LLTextBox::draw()  		if ( getEnabled() )  		{ -			drawText( text_x, text_y, mTextColor ); +			if(mHasHover) +			{ +				drawText( text_x, text_y, mHoverColor ); +			} +			else +			{ +				drawText( text_x, text_y, mTextColor ); +			}				 +  		}  		else  		{ @@ -346,6 +370,8 @@ void LLTextBox::draw()  			drawDebugRect();  		}  	} + +	mHasHover = FALSE; // This is reset every frame.  }  void LLTextBox::reshape(S32 width, S32 height, BOOL called_from_parent) @@ -468,5 +494,20 @@ LLView* LLTextBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f  		text_box->setColor(color);  	} +	if(node->hasAttribute("hover_color")) +	{ +		LLColor4 color; +		LLUICtrlFactory::getAttributeColor(node, "hover_color", color); +		text_box->setHoverColor(color); +		text_box->setHoverActive(true); +	} + +	BOOL hover_active = FALSE; +	if(node->getAttributeBOOL("hover", hover_active)) +	{ +		text_box->setHoverActive(hover_active); +	} + +  	return text_box;  } diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h index 7e7018ac52..c7c79464a0 100644 --- a/indra/llui/lltextbox.h +++ b/indra/llui/lltextbox.h @@ -66,11 +66,16 @@ public:  	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);  	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask); +	virtual BOOL	handleHover(S32 x, S32 y, MASK mask);  	void			setColor( const LLColor4& c )			{ mTextColor = c; }  	void			setDisabledColor( const LLColor4& c)	{ mDisabledColor = c; }  	void			setBackgroundColor( const LLColor4& c)	{ mBackgroundColor = c; }	  	void			setBorderColor( const LLColor4& c)		{ mBorderColor = c; }	 + +	void			setHoverColor( const LLColor4& c )		{ mHoverColor = c; } +	void			setHoverActive( BOOL active )			{ mHoverActive = active; } +  	void			setText( const LLStringExplicit& text );  	void			setWrappedText(const LLStringExplicit& text, F32 max_width = -1.0);  						// default width means use existing control width @@ -108,10 +113,12 @@ protected:  	const LLFontGL*	mFontGL;  	LLColor4		mTextColor;  	LLColor4		mDisabledColor; -  	LLColor4		mBackgroundColor;  	LLColor4		mBorderColor; -	 +	LLColor4		mHoverColor; + +	BOOL			mHoverActive;	 +	BOOL			mHasHover;  	BOOL			mBackgroundVisible;  	BOOL			mBorderVisible; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index a19107dd9c..54f6741fee 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -112,6 +112,7 @@  #include "llviewerregion.h"  #include "llviewerstats.h"  #include "llviewerwindow.h" +#include "llviewerdisplay.h"  #include "llvoavatar.h"  #include "llvoground.h"  #include "llvosky.h" @@ -121,7 +122,8 @@  #include "llworldmap.h"  #include "pipeline.h"  #include "roles_constants.h" -#include "viewer.h" +#include "llviewercontrol.h" +#include "llappviewer.h"  #include "llvoiceclient.h"  // Ventrella @@ -130,7 +132,6 @@  extern LLMenuBarGL* gMenuBarView;  extern U8 gLastPickAlpha; -extern F32 gFrameDTClamped;  //drone wandering constants  const F32 MAX_WANDER_TIME = 20.f;						// seconds @@ -222,6 +223,9 @@ const LLUUID BAKED_TEXTURE_HASH[BAKED_TEXTURE_COUNT] =  	LLUUID("ea800387-ea1a-14e0-56cb-24f2022f969a")  }; +// The agent instance. +LLAgent gAgent; +  //  // Statics  // @@ -2545,8 +2549,8 @@ void LLAgent::updateLookAt(const S32 mouse_x, const S32 mouse_y)  		LLVector3 headLookAxis;  		LLCoordFrame frameCamera = *((LLCoordFrame*)gCamera); -		F32 x_from_center = mouse_x_from_center( mouse_x );	// range from -0.5 to 0.5 -		F32 y_from_center = mouse_y_from_center( mouse_y );	// range from -0.5 to 0.5 +		F32 x_from_center = ((F32) mouse_x / (F32) gViewerWindow->getWindowWidth() ) - 0.5f; +		F32 y_from_center = ((F32) mouse_y / (F32) gViewerWindow->getWindowHeight() ) - 0.5f;  		if (cameraMouselook())  		{ @@ -2811,7 +2815,7 @@ void LLAgent::endAnimationUpdateUI()  		// HACK: If we're quitting, and we were in customize avatar, don't  		// let the mini-map go visible again. JC -		if (!gQuitRequested) +        if (!LLAppViewer::instance()->quitRequested())  		{  			gFloaterMap->popVisible();  		} @@ -5828,7 +5832,7 @@ void LLAgent::requestEnterGodMode()  	msg->addBOOLFast(_PREHASH_Godlike, TRUE);  	msg->addUUIDFast(_PREHASH_Token, LLUUID::null); -	// simulator and userserver need to know about your request +	// simulators need to know about your request  	sendReliableMessage();  } @@ -5843,7 +5847,7 @@ void LLAgent::requestLeaveGodMode()  	msg->addBOOLFast(_PREHASH_Godlike, FALSE);  	msg->addUUIDFast(_PREHASH_Token, LLUUID::null); -	// simulator and userserver need to know about your request +	// simulator needs to know about your request  	sendReliableMessage();  } diff --git a/indra/newview/llagentpilot.cpp b/indra/newview/llagentpilot.cpp index 9637c54a6d..f0bd452109 100644 --- a/indra/newview/llagentpilot.cpp +++ b/indra/newview/llagentpilot.cpp @@ -38,7 +38,7 @@  #include "llagentpilot.h"  #include "llagent.h"  #include "llframestats.h" -#include "viewer.h" +#include "llappviewer.h"  #include "llviewercontrol.h"  LLAgentPilot gAgentPilot; @@ -221,7 +221,7 @@ void LLAgentPilot::updateTarget()  						else if (mQuitAfterRuns)  						{  							llinfos << "Done with all runs, quitting viewer!" << llendl; -							app_force_quit(NULL); +							LLAppViewer::instance()->forceQuit();  						}  						else  						{ diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp new file mode 100644 index 0000000000..c763ff928c --- /dev/null +++ b/indra/newview/llappviewer.cpp @@ -0,0 +1,3894 @@ +/**  + * @file llappviewer.cpp + * @brief The LLAppViewer class definitions + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#include "llviewerprecompiledheaders.h" +#include "llappviewer.h" + +#include "llversionviewer.h" +#include "llfeaturemanager.h" +#include "llvieweruictrlfactory.h" +#include "llalertdialog.h" +#include "llerrorcontrol.h" +#include "llviewerimagelist.h" +#include "llgroupmgr.h" +#include "llagent.h" +#include "llwindow.h" +#include "llviewerstats.h" +#include "llmd5.h" +#include "llpumpio.h" +#include "llfloateractivespeakers.h" +#include "llimpanel.h" +#include "llstartup.h" +#include "llfocusmgr.h" +#include "llviewerjoystick.h" +#include "llcurl.h" +#include "llfloatersnapshot.h" +#include "llviewerwindow.h" +#include "llviewerdisplay.h" +#include "llviewermessage.h" +#include "llviewerobjectlist.h" +#include "llworldmap.h" +#include "llmutelist.h" + +#include "llweb.h" +#include "llsecondlifeurls.h" + +#if LL_WINDOWS +	#include "llwindebug.h" +#endif + +#if LL_WINDOWS +#	include <share.h> // For _SH_DENYWR in initMarkerFile +#else +#   include <sys/file.h> // For initMarkerFile support +#endif + + + +#include "llnotify.h" +#include "llmediaengine.h" +#include "llviewerkeyboard.h" +#include "lllfsthread.h" +#include "llworkerthread.h" +#include "lltexturecache.h" +#include "lltexturefetch.h" +#include "llimageworker.h" + +// The files below handle dependencies from cleanup. +#include "llkeyframemotion.h" +#include "llworldmap.h" +#include "llhudmanager.h" +#include "lltoolmgr.h" +#include "llassetstorage.h" +#include "llpolymesh.h" +#include "lleconomy.h" +#include "llcachename.h" +#include "audioengine.h" +#include "llviewermenu.h" +#include "llselectmgr.h" +#include "lltracker.h" +#include "llmozlib.h" +#include "llviewerparcelmgr.h" +#include "llworldmapview.h" + +#include "lldebugview.h" +#include "llconsole.h" +#include "llcontainerview.h" +#include "llhoverview.h" + +#if LL_WINDOWS && LL_LCD_COMPILE +	#include "lllcd.h" +#endif + +#if LL_QUICKTIME_ENABLED +	#if LL_DARWIN +		#include <QuickTime/QuickTime.h> +	#else +		// quicktime specific includes +		#include "MacTypes.h" +		#include "QTML.h" +		#include "Movies.h" +		#include "FixMath.h" +	#endif +#endif + +#include "llworld.h" +#include "llhudeffecttrail.h" +#include "llvectorperfoptions.h" +#include "llurlsimstring.h" + +// Included so that constants/settings might be initialized +// in save_settings_to_globals() +#include "llbutton.h" +#include "llcombobox.h" +#include "llstatusbar.h" +#include "llsurface.h" +#include "llvosky.h" +#include "llvotree.h" +#include "llvoavatar.h" +#include "llfolderview.h" +#include "lltoolbar.h" +#include "llframestats.h" +#include "llagentpilot.h" +#include "llsrv.h" + +// includes for idle() idleShutdown() +#include "llviewercontrol.h" +#include "lleventnotifier.h" +#include "llcallbacklist.h" +#include "pipeline.h" +#include "llgesturemgr.h" +#include "llsky.h" +#include "llvlmanager.h" +#include "llviewercamera.h" +#include "lldrawpoolbump.h" +#include "llvieweraudio.h" +#include "llimview.h" +#include "llviewerthrottle.h" +//  + +#include "llinventoryview.h" + +// *FIX: Remove these once the command line params thing is figured out. +// Yuck! +static int gTempArgC = 0; +static char** gTempArgV; + +// *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  +// moved into the app class, where as the other globals should be  +// moved out of here. +// If a global symbol reference seems valid, it will be included +// via header files above. + +//---------------------------------------------------------------------------- +// llviewernetwork.h +#include "llviewernetwork.h" +// extern EGridInfo gGridChoice; + +//---------------------------------------------------------------------------- +// viewer.cpp - these are only used in viewer, should be easily moved. +extern void disable_win_error_reporting(); + +//#define APPLE_PREVIEW // Define this if you're doing a preview build on the Mac +#if LL_RELEASE_FOR_DOWNLOAD +// Default userserver for production builds is agni +#ifndef APPLE_PREVIEW +static EGridInfo GridDefaultChoice = GRID_INFO_AGNI; +#else +static EGridInfo GridDefaultChoice = GRID_INFO_ADITI; +#endif +#else +// Default userserver for development builds is dmz +static EGridInfo GridDefaultChoice = GRID_INFO_DMZ; +#endif + +#if LL_WINDOWS +extern void create_console(); +#endif + + +#if LL_DARWIN +#include <Carbon/Carbon.h> +extern void init_apple_menu(const char* product); +extern OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn); +extern OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn); +extern OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata); +extern OSStatus DisplayReleaseNotes(void); +#include <boost/tokenizer.hpp> +#endif // LL_DARWIN + + +#include "moviemaker.h" +extern BOOL gbCapturing; + +#if !LL_SOLARIS +	extern MovieMaker gMovieMaker; +#endif + +extern BOOL gRandomizeFramerate; +extern BOOL gPeriodicSlowFrame; + +#if LL_GSTREAMER_ENABLED +void UnloadGStreamer(); +#endif + +extern void send_stats(); +//////////////////////////////////////////////////////////// +// All from the last globals push... +bool gVerifySSLCert = true; +BOOL gHandleKeysAsync = FALSE; + +BOOL gProbeHardware = TRUE; // Use DirectX 9 to probe for hardware + +S32 gYieldMS = 0; // set in parse_args, used in mainLoop +BOOL gYieldTime = FALSE; + +const F32 DEFAULT_AFK_TIMEOUT = 5.f * 60.f; // time with no input before user flagged as Away From Keyboard + +F32 gSimLastTime; // Used in LLAppViewer::init and send_stats() +F32 gSimFrames; + +LLString gDisabledMessage; // Set in LLAppViewer::initConfiguration used in idle_startup + +BOOL gHideLinks = FALSE; // Set in LLAppViewer::initConfiguration, used externally + +BOOL gInProductionGrid	= FALSE;  + +BOOL				gAllowIdleAFK = TRUE; +F32					gAFKTimeout = DEFAULT_AFK_TIMEOUT; +BOOL				gShowObjectUpdates = FALSE; +BOOL gLogMessages = FALSE; +std::string gChannelName = LL_CHANNEL; +BOOL gUseAudio = TRUE; +LLString gCmdLineFirstName; +LLString gCmdLineLastName; +LLString gCmdLinePassword; + +BOOL				gAutoLogin = FALSE; + +const char*			DEFAULT_SETTINGS_FILE = "settings.xml"; +BOOL gRequestInventoryLibrary = TRUE; +BOOL gGodConnect = FALSE; +BOOL gAcceptTOS = FALSE; +BOOL gAcceptCriticalMessage = FALSE; + +LLUUID				gViewerDigest;	// MD5 digest of the viewer's executable file. +BOOL gLastExecFroze = FALSE; + +U32	gFrameCount = 0; +U32 gForegroundFrameCount = 0; // number of frames that app window was in foreground +LLPumpIO*			gServicePump = NULL; + +BOOL gPacificDaylightTime = FALSE; + +U64 gFrameTime = 0; +F32 gFrameTimeSeconds = 0.f; +F32 gFrameIntervalSeconds = 0.f; +F32		gFPSClamped = 10.f;						// Pretend we start at target rate. +F32		gFrameDTClamped = 0.f;					// Time between adjacent checks to network for packets +U64	gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds + +LLTimer gRenderStartTime; +LLFrameTimer gForegroundTime; +LLTimer				gLogoutTimer; +static const F32			LOGOUT_REQUEST_TIME = 6.f;  // this will be cut short by the LogoutReply msg. +F32					gLogoutMaxTime = LOGOUT_REQUEST_TIME; + +LLUUID gInventoryLibraryOwner; +LLUUID gInventoryLibraryRoot; + +BOOL				gDisableVoice = FALSE; +BOOL				gDisconnected = FALSE; + +// Map scale in pixels per region +F32 				gMapScale = 128.f; +F32 				gMiniMapScale = 128.f; + +// used to restore texture state after a mode switch +LLFrameTimer	gRestoreGLTimer; +BOOL			gRestoreGL = FALSE; +BOOL				gUseWireframe = FALSE; + +F32					gMouseSensitivity = 3.f; +BOOL				gInvertMouse = FALSE; + +// VFS globals - see llappviewer.h +LLVFS* gStaticVFS = NULL; + +LLMemoryInfo gSysMemory; + +bool gPreloadImages = true; +bool gPreloadSounds = true; + +LLString gLastVersionChannel; + +LLVector3			gWindVec(3.0, 3.0, 0.0); +LLVector3			gRelativeWindVec(0.0, 0.0, 0.0); + +U32		gPacketsIn = 0; + +BOOL				gPrintMessagesThisFrame = FALSE; + +BOOL gUseConsole = TRUE; + +BOOL gRandomizeFramerate = FALSE; +BOOL gPeriodicSlowFrame = FALSE; + +BOOL gQAMode = FALSE; + +//////////////////////////////////////////////////////////// +// Internal globals... that should be removed. +static F32 gQuitAfterSeconds = 0.f; +static BOOL gRotateRight = FALSE; +static BOOL gIgnorePixelDepth = FALSE; + +// Allow multiple viewers in ReleaseForDownload +#if LL_RELEASE_FOR_DOWNLOAD +static BOOL gMultipleViewersOK = FALSE; +#else +static BOOL gMultipleViewersOK = TRUE; +#endif + +static std::map<std::string, std::string> gCommandLineSettings; +static std::map<std::string, std::string> gCommandLineForcedSettings; + +static LLString gArgs; + +static LLString gOldSettingsFileName; +static const char* LEGACY_DEFAULT_SETTINGS_FILE = "settings.ini"; +static BOOL gDoDisconnect = FALSE; +static LLString gLaunchFileOnQuit; + +//---------------------------------------------------------------------------- +// File scope definitons +const char *VFS_DATA_FILE_BASE = "data.db2.x."; +const char *VFS_INDEX_FILE_BASE = "index.db2.x."; + +static LLString gSecondLife; +static LLString gWindowTitle; +#ifdef LL_WINDOWS +	static char sWindowClass[] = "Second Life"; +#endif + +std::vector<std::string> gLoginURIs; +static std::string gHelperURI; + +static const char USAGE[] = "\n" +"usage:\tviewer [options]\n" +"options:\n" +" -login <first> <last> <password>     log in as a user\n" +" -autologin                           log in as last saved user\n" +" -loginuri <URI>                      login server and CGI script to use\n" +" -helperuri <URI>                     helper web CGI prefix to use\n" +" -settings <filename>                 specify the filename of a\n" +"                                        configuration file\n" +"                                        default is settings.xml\n" +" -setdefault <variable> <value>       specify the value of a particular\n" +"                                        configuration variable which can be\n" +"                                        overridden by settings.xml\n" +" -set <variable> <value>              specify the value of a particular\n" +"                                        configuration variable that\n" +"                                        overrides all other settings\n" +" -user <user_server_ip>               specify userserver in dotted quad\n" +#if !LL_RELEASE_FOR_DOWNLOAD +" -sim <simulator_ip>                  specify the simulator ip address\n" +#endif +" -god		                           log in as god if you have god access\n" +" -purge                               delete files in cache\n" +" -safe                                reset preferences, run in safe mode\n" +" -noutc                               logs in local time, not UTC\n" +" -nothread                            run vfs in single thread\n" +" -noinvlib                            Do not request inventory library\n" +" -multiple                            allow multiple viewers\n" +" -nomultiple                          block multiple viewers\n" +" -novoice                             disable voice\n" +" -ignorepixeldepth                    ignore pixel depth settings\n" +" -cooperative [ms]                    yield some idle time to local host\n" +" -skin                                ui/branding skin folder to use\n" +#if LL_WINDOWS +" -noprobe                             disable hardware probe\n" +#endif +" -noquicktime                         disable QuickTime movies, speeds startup\n" +" -nopreload                           don't preload UI images or sounds, speeds startup\n" +// these seem to be unused +//" -noenv                               turn off environmental effects\n" +//" -proxy <proxy_ip>                    specify the proxy ip address\n" +"\n"; + +void idle_afk_check() +{ +	// check idle timers +	if (gAllowIdleAFK && (gAwayTriggerTimer.getElapsedTimeF32() > gAFKTimeout)) +	{ +		gAgent.setAFK(); +	} +} + +// A callback set in LLAppViewer::init() +static void ui_audio_callback(const LLUUID& uuid) +{ +	if (gAudiop) +	{ +		F32 volume = gSavedSettings.getF32("AudioLevelUI"); +		gAudiop->triggerSound(uuid, gAgent.getID(), volume); +	} +} + +void request_initial_instant_messages() +{ +	static BOOL requested = FALSE; +	if (!requested +		&& gMuteListp +		&& gMuteListp->isLoaded() +		&& gAgent.getAvatarObject()) +	{ +		// Auto-accepted inventory items may require the avatar object +		// to build a correct name.  Likewise, inventory offers from +		// muted avatars require the mute list to properly mute. +		LLMessageSystem* msg = gMessageSystem; +		msg->newMessageFast(_PREHASH_RetrieveInstantMessages); +		msg->nextBlockFast(_PREHASH_AgentData); +		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +		gAgent.sendReliableMessage(); +		requested = TRUE; +	} +} + +// Use these strictly for things that are constructed at startup, +// or for things that are performance critical.  JC +static void saved_settings_to_globals() +{ +	LLBUTTON_H_PAD		= gSavedSettings.getS32("ButtonHPad"); +	LLBUTTON_V_PAD		= gSavedSettings.getS32("ButtonVPad"); +	BTN_HEIGHT_SMALL	= gSavedSettings.getS32("ButtonHeightSmall"); +	BTN_HEIGHT			= gSavedSettings.getS32("ButtonHeight"); + +	MENU_BAR_HEIGHT		= gSavedSettings.getS32("MenuBarHeight"); +	MENU_BAR_WIDTH		= gSavedSettings.getS32("MenuBarWidth"); +	STATUS_BAR_HEIGHT	= gSavedSettings.getS32("StatusBarHeight"); + +	LLCOMBOBOX_HEIGHT	= BTN_HEIGHT - 2; +	LLCOMBOBOX_WIDTH	= 128; + +	LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize")); + +	LLVOSky::sNighttimeBrightness		= gSavedSettings.getF32("RenderNightBrightness"); +	 +	LLImageGL::sGlobalUseAnisotropic	= gSavedSettings.getBOOL("RenderAnisotropic"); +	LLVOVolume::sLODFactor				= gSavedSettings.getF32("RenderVolumeLODFactor"); +	LLVOVolume::sDistanceFactor			= 1.f-LLVOVolume::sLODFactor * 0.1f; +	LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor"); +	LLVOTree::sTreeFactor				= gSavedSettings.getF32("RenderTreeLODFactor"); +	LLVOAvatar::sLODFactor				= gSavedSettings.getF32("RenderAvatarLODFactor"); +	LLVOAvatar::sMaxVisible				= gSavedSettings.getS32("RenderAvatarMaxVisible"); +	LLVOAvatar::sVisibleInFirstPerson	= gSavedSettings.getBOOL("FirstPersonAvatarVisible"); +	// clamp auto-open time to some minimum usable value +	LLFolderView::sAutoOpenTime			= llmax(0.25f, gSavedSettings.getF32("FolderAutoOpenDelay")); +	LLToolBar::sInventoryAutoOpenTime	= gSavedSettings.getF32("InventoryAutoOpenDelay"); +	LLSelectMgr::sRectSelectInclusive	= gSavedSettings.getBOOL("RectangleSelectInclusive"); +	LLSelectMgr::sRenderHiddenSelections = gSavedSettings.getBOOL("RenderHiddenSelections"); +	LLSelectMgr::sRenderLightRadius = gSavedSettings.getBOOL("RenderLightRadius"); + +	gFrameStats.setTrackStats(gSavedSettings.getBOOL("StatsSessionTrackFrameStats")); +	gAgentPilot.mNumRuns		= gSavedSettings.getS32("StatsNumRuns"); +	gAgentPilot.mQuitAfterRuns	= gSavedSettings.getBOOL("StatsQuitAfterRuns"); +	gAgent.mHideGroupTitle		= gSavedSettings.getBOOL("RenderHideGroupTitle"); + +	gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc"); +	gAllowIdleAFK = gSavedSettings.getBOOL("AllowIdleAFK"); +	gAFKTimeout = gSavedSettings.getF32("AFKTimeout"); +	gMouseSensitivity = gSavedSettings.getF32("MouseSensitivity"); +	gInvertMouse = gSavedSettings.getBOOL("InvertMouse"); +	gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); +	gMapScale = gSavedSettings.getF32("MapScale"); +	gMiniMapScale = gSavedSettings.getF32("MiniMapScale"); +	gHandleKeysAsync = gSavedSettings.getBOOL("AsyncKeyboard"); +	LLHoverView::sShowHoverTips = gSavedSettings.getBOOL("ShowHoverTips"); + +#if LL_VECTORIZE +	if (gSysCPU.hasAltivec()) +	{ +		gSavedSettings.setBOOL("VectorizeEnable", TRUE ); +		gSavedSettings.setU32("VectorizeProcessor", 0 ); +	} +	else +	if (gSysCPU.hasSSE2()) +	{ +		gSavedSettings.setBOOL("VectorizeEnable", TRUE ); +		gSavedSettings.setU32("VectorizeProcessor", 2 ); +	} +	else +	if (gSysCPU.hasSSE()) +	{ +		gSavedSettings.setBOOL("VectorizeEnable", TRUE ); +		gSavedSettings.setU32("VectorizeProcessor", 1 ); +	} +	else +	{ +		// Don't bother testing or running if CPU doesn't support it. JC +		gSavedSettings.setBOOL("VectorizePerfTest", FALSE ); +		gSavedSettings.setBOOL("VectorizeEnable", FALSE ); +		gSavedSettings.setU32("VectorizeProcessor", 0 ); +		gSavedSettings.setBOOL("VectorizeSkin", FALSE); +	} +#else +	// This build target doesn't support SSE, don't test/run. +	gSavedSettings.setBOOL("VectorizePerfTest", FALSE ); +	gSavedSettings.setBOOL("VectorizeEnable", FALSE ); +	gSavedSettings.setU32("VectorizeProcessor", 0 ); +	gSavedSettings.setBOOL("VectorizeSkin", FALSE); +#endif + +	// propagate push to talk preference to current status +	gSavedSettings.setBOOL("PTTCurrentlyEnabled", gSavedSettings.getBOOL("EnablePushToTalk")); + +	settings_setup_listeners(); + +	// gAgent.init() also loads from saved settings. +} + +int parse_args(int argc, char **argv) +{ +	// Sometimes IP addresses passed in on the command line have leading +	// or trailing white space.  Use LLString to clean that up. +	LLString ip_string; +	S32 j; + +	for (j = 1; j < argc; j++)  +	{ +		gArgs += argv[j]; +		gArgs += " "; + +		LLString argument = argv[j]; +		if ((!strcmp(argv[j], "-port")) && (++j < argc))  +		{ +			sscanf(argv[j], "%u", &(gAgent.mViewerPort)); +		} +		else if ((!strcmp(argv[j], "-drop")) && (++j < argc))  +		{ +			sscanf(argv[j], "%f", &gPacketDropPercentage); +		} +		else if ((!strcmp(argv[j], "-inbw")) && (++j < argc)) +		{ +			sscanf(argv[j], "%f", &gInBandwidth); +		} +		else if ((!strcmp(argv[j], "-outbw")) && (++j < argc)) +		{ +			sscanf(argv[j], "%f", &gOutBandwidth); +		} +		else if (!strcmp(argv[j], "--aditi")) +		{ +			gGridChoice = GRID_INFO_ADITI; +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore +		} +		else if (!strcmp(argv[j], "--agni")) +		{ +			gGridChoice = GRID_INFO_AGNI; +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore +		} +		else if (!strcmp(argv[j], "--dmz")) +		{ +			gGridChoice = GRID_INFO_DMZ; +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore +		} +		else if (!strcmp(argv[j], "--siva")) +		{ +			gGridChoice = GRID_INFO_SIVA; +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore +		} +		else if (!strcmp(argv[j], "--shakti")) +		{ +			gGridChoice = GRID_INFO_SHAKTI; +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore +		} +		else if (!strcmp(argv[j], "--durga")) +		{ +			gGridChoice = GRID_INFO_DURGA; +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore +		} +		else if (!strcmp(argv[j], "--soma")) +		{ +			gGridChoice = GRID_INFO_SOMA; +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[gGridChoice].mName);		// Flawfinder: ignore +		} +		else if (!strcmp(argv[j], "--ganga")) +		{ +			gGridChoice = GRID_INFO_GANGA; +			sprintf(gGridName,"%s", gGridInfo[gGridChoice].mName); +		} +		else if (!strcmp(argv[j], "--vaak")) +		{ +			gGridChoice = GRID_INFO_VAAK; +			sprintf(gGridName,"%s", gGridInfo[gGridChoice].mName); +		} +		else if (!strcmp(argv[j], "--uma")) +		{ +			gGridChoice = GRID_INFO_UMA; +			sprintf(gGridName,"%s", gGridInfo[gGridChoice].mName); +		} +		else if (!strcmp(argv[j], "-user") && (++j < argc))  +		{ +			if (!strcmp(argv[j], "-")) +			{ +				gGridChoice = GRID_INFO_LOCAL; +				snprintf(gGridName, MAX_STRING, "%s", LOOPBACK_ADDRESS_STRING);		// Flawfinder: ignore +			} +			else +			{ +				gGridChoice = GRID_INFO_OTHER; +				ip_string.assign( argv[j] ); +				LLString::trim(ip_string); +				snprintf(gGridName, MAX_STRING, "%s", ip_string.c_str());		// Flawfinder: ignore +			} +		} +		else if (!strcmp(argv[j], "-loginuri") && (++j < argc)) +		{ +            LLAppViewer::instance()->addLoginURI(utf8str_trim(argv[j])); +		} +		else if (!strcmp(argv[j], "-helperuri") && (++j < argc)) +		{ +            LLAppViewer::instance()->setHelperURI(utf8str_trim(argv[j])); +		} +		else if (!strcmp(argv[j], "-debugviews")) +		{ +			LLView::sDebugRects = TRUE; +		} +		else if (!strcmp(argv[j], "-skin") && (++j < argc)) +		{ +			std::string folder(argv[j]); +			gDirUtilp->setSkinFolder(folder); +		} +		else if (!strcmp(argv[j], "-autologin") || !strcmp(argv[j], "--autologin")) // keep --autologin for compatibility +		{ +			gAutoLogin = TRUE; +		} +		else if (!strcmp(argv[j], "-quitafter") && (++j < argc)) +		{ +			gQuitAfterSeconds = (F32)atof(argv[j]); +		} +		else if (!strcmp(argv[j], "-rotate")) +		{ +			gRotateRight = TRUE; +		} +//		else if (!strcmp(argv[j], "-noenv"))  +//		{ +			//turn OFF environmental effects for slow machines/video cards +//			gRequestParaboloidMap = FALSE; +//		} +		else if (!strcmp(argv[j], "-noaudio")) +		{ +			gUseAudio = FALSE; +		} +		else if (!strcmp(argv[j], "-nosound"))  // tends to be popular cmdline on Linux. +		{ +			gUseAudio = FALSE; +		} +		else if (!strcmp(argv[j], "-noprobe")) +		{ +			gProbeHardware = FALSE; +		} +		else if (!strcmp(argv[j], "-noquicktime")) +		{ +			// Developers can log in faster if they don't load all the +			// quicktime dlls. +			gUseQuickTime = false; +		} +		else if (!strcmp(argv[j], "-nopreload")) +		{ +			// Developers can log in faster if they don't decode sounds +			// or images on startup, ~5 seconds faster. +			gPreloadSounds = false; +			gPreloadImages = false; +		} +		else if (!strcmp(argv[j], "-purge")) +		{ +			LLAppViewer::instance()->purgeCache(); +		} +		else if(!strcmp(argv[j], "-noinvlib")) +		{ +			gRequestInventoryLibrary = FALSE; +		} +		else if (!strcmp(argv[j], "-log")) +		{ +			gLogMessages = TRUE; +			continue; +		} +		else if (!strcmp(argv[j], "-logfile") && (++j < argc))  +		{ +			// *NOTE: This buffer size is hard coded into scanf() below. +			char logfile[256];	// Flawfinder: ignore +			sscanf(argv[j], "%255s", logfile);	// Flawfinder: ignore +			llinfos << "Setting log file to " << logfile << llendl; +			LLFile::remove(logfile); +			LLError::logToFile(logfile); +		} +		else if (!strcmp(argv[j], "-settings") && (++j < argc))  +		{ +			gSettingsFileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, argv[j]); +		} +		else if (!strcmp(argv[j], "-setdefault") && (j + 2 < argc))  +		{ +			std::string control_name; +			std::string control_value; +			 +			j++; +			if (argv[j]) control_name = std::string(argv[j]); + +			j++; +			if (argv[j]) control_value = std::string(argv[j]); +			 +			// grab control name and value +			if (!control_name.empty()) +			{ +				gCommandLineSettings[control_name] = control_value; +			} +		} +		else if (!strcmp(argv[j], "-set") && (j + 2 < argc))  +		{ +			std::string control_name; +			std::string control_value; +			 +			j++; +			if (argv[j]) control_name = std::string(argv[j]); + +			j++; +			if (argv[j]) control_value = std::string(argv[j]); +			 +			// grab control name and value +			if (!control_name.empty()) +			{ +				gCommandLineForcedSettings[control_name] = control_value; +			} +		} +		else if (!strcmp(argv[j], "-login")) +		{ +			if (j + 3 < argc) +			{ +				j++; +				gCmdLineFirstName = argv[j]; +				j++; +				gCmdLineLastName = argv[j]; +				j++; +				gCmdLinePassword = argv[j]; +			} +			else +			{ +				// only works if -login is last parameter on command line +				llerrs << "Not enough parameters to -login. Did you mean -loginuri?" << llendl; +			} +		} +		else if (!strcmp(argv[j], "-god")) +		{ +			gGodConnect = TRUE; +		} +		else if (!strcmp(argv[j], "-noconsole")) +		{ +			gUseConsole = FALSE; +		} +		else if (!strcmp(argv[j], "-safe")) +		{ +			llinfos << "Setting viewer feature table to run in safe mode, resetting prefs" << llendl; +			gFeatureManagerp->setSafe(TRUE); +		} +		else if (!strcmp(argv[j], "-multiple")) +		{ +			gMultipleViewersOK = TRUE; +		} +		else if (!strcmp(argv[j], "-nomultiple")) +		{ +			gMultipleViewersOK = FALSE; +		} +		else if (!strcmp(argv[j], "-novoice")) +		{ +			gDisableVoice = TRUE; +		} +		else if (!strcmp(argv[j], "-nothread")) +		{ +			LLVFile::ALLOW_ASYNC = FALSE; +			llinfos << "Running VFS in nothread mode" << llendl; +		} +		// some programs don't respect the command line options in protocol handlers (I'm looking at you, Opera) +		// so this allows us to parse the URL straight off the command line without a "-url" paramater +		else if (!argument.compare(0, std::string( "secondlife://" ).length(), std::string("secondlife://"))) +		{ +			// *NOTE: After setting the url, bail. What can happen is +			// that someone can use IE (or potentially other browsers) +			// and do the rough equivalent of command injection and +			// steal passwords. Phoenix. SL-55321 +			LLURLSimString::setString(argv[j]); +			gArgs += argv[j]; +			return 0; +		} +		else if (!strcmp(argv[j], "-url") && (++j < argc))  +		{ +			// *NOTE: After setting the url, bail. What can happen is +			// that someone can use IE (or potentially other browsers) +			// and do the rough equivalent of command injection and +			// steal passwords. Phoenix. SL-55321 +			LLURLSimString::setString(argv[j]); +			gArgs += argv[j]; +			return 0; +		} +		else if (!strcmp(argv[j], "-ignorepixeldepth")) +		{ +			gIgnorePixelDepth = TRUE; +		} +		else if (!strcmp(argv[j], "-cooperative")) +		{ +			S32 ms_to_yield = 0; +			if(++j < argc) +			{ +				S32 rv = sscanf(argv[j], "%d", &ms_to_yield); +				if(0 == rv) +				{ +					--j; +				} +			} +			else +			{ +				--j; +			} +			gYieldMS = ms_to_yield; +			gYieldTime = TRUE; +		} +		else if (!strcmp(argv[j], "-no-verify-ssl-cert")) +		{ +			gVerifySSLCert = false; +		} +		else if ( (!strcmp(argv[j], "--channel") || !strcmp(argv[j], "-channel"))  && (++j < argc))  +		{ +			gChannelName = argv[j]; +		} +#if LL_DARWIN +		else if (!strncmp(argv[j], "-psn_", 5)) +		{ +			// this is the Finder passing the process session number +			// we ignore this +		} +#endif +		else if(!strncmp(argv[j], "-qa", 3)) +		{ +			gQAMode = TRUE; +		} +		else +		{ + +			// DBC - Mac OS X passes some stuff by default on the command line (e.g. psn). +			// Second Life URLs are passed this way as well? +			llwarns << "Possible unknown keyword " << argv[j] << llendl; + +			// print usage information +			llinfos << USAGE << llendl; +			// return 1; +		} +	} +	return 0; +} + +bool send_url_to_other_instance(const std::string& url) +{ +#if LL_WINDOWS +	wchar_t window_class[256]; /* Flawfinder: ignore */   // Assume max length < 255 chars. +	mbstowcs(window_class, sWindowClass, 255); +	window_class[255] = 0; +	// Use the class instead of the window name. +	HWND other_window = FindWindow(window_class, NULL); +	if (other_window != NULL) +	{ +		lldebugs << "Found other window with the name '" << gWindowTitle << "'" << llendl; +		COPYDATASTRUCT cds; +		const S32 SLURL_MESSAGE_TYPE = 0; +		cds.dwData = SLURL_MESSAGE_TYPE; +		cds.cbData = url.length() + 1; +		cds.lpData = (void*)url.c_str(); + +		LRESULT msg_result = SendMessage(other_window, WM_COPYDATA, NULL, (LPARAM)&cds); +		lldebugs << "SendMessage(WM_COPYDATA) to other window '"  +				 << gWindowTitle << "' returned " << msg_result << llendl; +		return true; +	} +#endif +	return false; +} + +//---------------------------------------------------------------------------- +// LLAppViewer definition + +// Static members. +// The single viewer app. +LLAppViewer* LLAppViewer::sInstance = NULL; + +LLTextureCache* LLAppViewer::sTextureCache = NULL;  +LLWorkerThread* LLAppViewer::sImageDecodeThread = NULL;  +LLTextureFetch* LLAppViewer::sTextureFetch = NULL;  + +LLAppViewer::LLAppViewer() :  +	mMarkerFile(NULL), +	mLastExecFroze(false), +	mDebugFile(NULL), +	mCrashBehavior(CRASH_BEHAVIOR_ASK), +	mReportedCrash(false), +	mNumSessions(0), +	mPurgeCache(false), +    mPurgeOnExit(false), +    mSecondInstance(false), +	mSavedFinalSnapshot(false), +    mQuitRequested(false), +    mLogoutRequestSent(false) +{ +	if(NULL != sInstance) +	{ +		llerrs << "Oh no! An instance of LLAppViewer already exists! LLAppViewer is sort of like a singleton." << llendl; +	} + +	sInstance = this; +} + +LLAppViewer::~LLAppViewer() +{ +	// If we got to this destructor somehow, the app didn't hang. +	removeMarkerFile(); +} + +bool LLAppViewer::tempStoreCommandOptions(int argc, char** argv) +{ +	gTempArgC = argc; +	gTempArgV = argv; +	return true; +} + +bool LLAppViewer::init() +{ +    // *NOTE:Mani - LLCurl::initClass is not thread safe.  +    // Called before threads are created. +    LLCurl::initClass(); + +    initThreads(); + +	initEarlyConfiguration(); + +	// +	// Start of the application +	// +	// IMPORTANT! Do NOT put anything that will write +	// into the log files during normal startup until AFTER +	// we run the "program crashed last time" error handler below. +	// + +	// Need to do this initialization before we do anything else, since anything +	// that touches files should really go through the lldir API +	gDirUtilp->initAppDirs("SecondLife"); + + +	initLogging(); +	 +	// +	// OK to write stuff to logs now, we've now crash reported if necessary +	// + +	// Set up some defaults... +	gSettingsFileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, DEFAULT_SETTINGS_FILE); +	gOldSettingsFileName = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, LEGACY_DEFAULT_SETTINGS_FILE); + +    initConfiguration(); + +	////////////////////////////////////////////////////////////////////////////// +	////////////////////////////////////////////////////////////////////////////// +	////////////////////////////////////////////////////////////////////////////// +	////////////////////////////////////////////////////////////////////////////// +	// *FIX: The following code isn't grouped into functions yet. + +	// +	// Write system information into the debug log (CPU, OS, etc.) +	// +	writeSystemInfo(); + +	// Build a string representing the current version number. +	gCurrentVersion = llformat("%d.%d.%d", LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH ); +	 +	// +	// Load the feature tables +	// +	llinfos << "Loading feature tables." << llendl; +	 +	gFeatureManagerp->loadFeatureTables(); +	gFeatureManagerp->initCPUFeatureMasks(); + +	// Merge with the command line overrides +	gSavedSettings.applyOverrides(gCommandLineSettings); + +	// Need to do this before calling parseAlerts +	gUICtrlFactory = new LLViewerUICtrlFactory(); +	 +	// Pre-load alerts.xml to define the warnings settings (always loads from skins/xui/en-us/) +	// Do this *before* loading the settings file +	LLAlertDialog::parseAlerts("alerts.xml", &gSavedSettings, TRUE); +	 +	// Overwrite default settings with user settings +	llinfos << "Loading configuration file " << gSettingsFileName << llendl; +	if (0 == gSavedSettings.loadFromFile(gSettingsFileName)) +	{ +		llinfos << "Failed to load settings from " << gSettingsFileName << llendl; +		llinfos << "Loading legacy settings from " << gOldSettingsFileName << llendl; +		gSavedSettings.loadFromFileLegacy(gOldSettingsFileName); +	} + +	// need to do this here - need to have initialized global settings first +	LLString nextLoginLocation = gSavedSettings.getString( "NextLoginLocation" ); +	if ( nextLoginLocation.length() ) +	{ +		LLURLSimString::setString( nextLoginLocation.c_str() ); +	}; + +	// Merge with the command line overrides +	gSavedSettings.applyOverrides(gCommandLineForcedSettings); + +	gLastRunVersion = gSavedSettings.getString("LastRunVersion"); + +	fixup_settings(); +	 +	// Get the single value from the crash settings file, if it exists +	std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE); +	gCrashSettings.loadFromFile(crash_settings_filename.c_str()); + +	///////////////////////////////////////////////// +	// OS-specific login dialogs +	///////////////////////////////////////////////// +#if LL_WINDOWS +	/* +	// Display initial login screen, comes up quickly. JC +	{ +		LLSplashScreen::hide(); + +		INT_PTR result = DialogBox(hInstance, L"CONNECTBOX", NULL, login_dialog_func); +		if (result < 0) +		{ +			llwarns << "Connect dialog box failed, returned " << result << llendl; +			return 1; +		} +		// success, result contains which button user clicked +		llinfos << "Connect dialog box clicked " << result << llendl; + +		LLSplashScreen::show(); +	} +	*/ +#endif + +	// track number of times that app has run +	mNumSessions = gSavedSettings.getS32("NumSessions"); +	mNumSessions++; +	gSavedSettings.setS32("NumSessions", mNumSessions); + +	gSavedSettings.setString("HelpLastVisitedURL",gSavedSettings.getString("HelpHomeURL")); + +	if (gSavedSettings.getBOOL("VerboseLogs")) +	{ +		LLError::setPrintLocation(true); +	} + +#if !LL_RELEASE_FOR_DOWNLOAD +	if (gGridChoice == GRID_INFO_NONE) +	{ +		// Development version: load last server choice by default (overridden by cmd line args) +		 +		S32 server = gSavedSettings.getS32("ServerChoice"); +		if (server != 0) +			gGridChoice = (EGridInfo)llclamp(server, 0, (S32)GRID_INFO_COUNT - 1); +		if (server == GRID_INFO_OTHER) +		{ +			LLString custom_server = gSavedSettings.getString("CustomServer"); +			if (custom_server.empty()) +			{ +				snprintf(gGridName, MAX_STRING, "none");		/* Flawfinder: ignore */ +			} +			else +			{ +				snprintf(gGridName, MAX_STRING, "%s", custom_server.c_str());		/* Flawfinder: ignore */ +			} +		} +	} +#endif + +	if (gGridChoice == GRID_INFO_NONE) +	{ +		gGridChoice = GridDefaultChoice; +	} +	 +	// Load art UUID information, don't require these strings to be declared in code. +	LLString viewer_art_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"viewerart.xml"); +	llinfos << "Loading art table from " << viewer_art_filename << llendl; +	gViewerArt.loadFromFile(viewer_art_filename.c_str(), FALSE); +	LLString textures_filename = gDirUtilp->getExpandedFilename(LL_PATH_SKINS, "textures", "textures.xml"); +	llinfos << "Loading art table from " << textures_filename << llendl; +	gViewerArt.loadFromFile(textures_filename.c_str(), FALSE); + +	LLString colors_base_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "colors_base.xml"); +	llinfos << "Loading base colors from " << colors_base_filename << llendl; +	gColors.loadFromFile(colors_base_filename.c_str(), FALSE, TYPE_COL4U); + +	// Load overrides from user colors file +	LLString user_colors_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "colors.xml"); +	llinfos << "Loading user colors from " << user_colors_filename << llendl; +	if (gColors.loadFromFile(user_colors_filename.c_str(), FALSE, TYPE_COL4U) == 0) +	{ +		llinfos << "Failed to load user colors from " << user_colors_filename << llendl; +		LLString user_legacy_colors_filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "colors.ini"); +		llinfos << "Loading legacy colors from " << user_legacy_colors_filename << llendl; +		gColors.loadFromFileLegacy(user_legacy_colors_filename.c_str(), FALSE, TYPE_COL4U); +	} + +	// Widget construction depends on LLUI being initialized +	LLUI::initClass(&gSavedSettings,  +					&gColors,  +					&gViewerArt, +					&gImageList, +					ui_audio_callback, +					&LLUI::sGLScaleFactor); + +	gUICtrlFactory->setupPaths(); // update paths with correct language set +	 +	///////////////////////////////////////////////// +	// +	// Load settings files +	// +	// +	LLGroupMgr::parseRoleActions("role_actions.xml"); + +	LLAgent::parseTeleportMessages("teleport_strings.xml"); + +	mCrashBehavior = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING); + +	LLVectorPerformanceOptions::initClass(); + +	// Move certain saved settings into global variables for speed +	saved_settings_to_globals(); + + +	// Find partition serial number (Windows) or hardware serial (Mac) +	mSerialNumber = generateSerialNumber(); + +	if(false == initHardwareTest()) +	{ +		// Early out from user choice. +		return false; +	} + +	// Always fetch the Ethernet MAC address, needed both for login +	// and password load. +	LLUUID::getNodeID(gMACAddress); + +	// Prepare for out-of-memory situations, during which we will crash on +	// purpose and save a dump. +#if LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP +	MemSetErrorHandler(first_mem_error_handler); +#endif // LL_WINDOWS && LL_RELEASE_FOR_DOWNLOAD && LL_USE_SMARTHEAP + +	gViewerStats = new LLViewerStats(); + +	// +	// Initialize the VFS, and gracefully handle initialization errors +	// + +	if (!initCache()) +	{ +		std::ostringstream msg; +		msg << +			gSecondLife << " is unable to access a file that it needs.\n" +			"\n" +			"This can be because you somehow have multiple copies running, " +			"or your system incorrectly thinks a file is open. " +			"If this message persists, restart your computer and try again. " +			"If it continues to persist, you may need to completely uninstall " << +			gSecondLife << " and reinstall it."; +		OSMessageBox( +			msg.str().c_str(), +			NULL, +			OSMB_OK); +		return 1; +	} +	 +#if LL_DARWIN +	// Display the release notes for the current version +	if(!gHideLinks && gCurrentVersion != gLastRunVersion) +	{ +		// Current version and last run version don't match exactly.  Display the release notes. +		DisplayReleaseNotes(); +	} +#endif + +	// +	// Initialize the window +	// +	initWindow(); + +	#if LL_WINDOWS && LL_LCD_COMPILE +		// start up an LCD window on a logitech keyboard, if there is one +		HINSTANCE hInstance = GetModuleHandle(NULL); +		gLcdScreen = new llLCD(hInstance); +		CreateLCDDebugWindows(); +	#endif + +	writeDebug(gGLManager.getGLInfoString()); +	llinfos << gGLManager.getGLInfoString() << llendl; + +	//load key settings +	bind_keyboard_functions(); + +	// Load Default bindings +	if (!gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"keys.ini").c_str())) +	{ +		llerrs << "Unable to open keys.ini" << llendl; +	} +	// Load Custom bindings (override defaults) +	gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"custom_keys.ini").c_str()); + +	// Calculate the digest for the executable (takes < 90ms on a fast machine). +	FILE* app_file = LLFile::fopen( gDirUtilp->getExecutablePathAndName().c_str(), "rb" );		/* Flawfinder: ignore */ +	if( app_file ) +	{ +		LLMD5 app_md5; +		app_md5.update( app_file ); // Automatically closes the file +		app_md5.finalize(); +		app_md5.raw_digest( gViewerDigest.mData ); +	} +	llinfos << "Viewer Digest: " << gViewerDigest << llendl; + +	// If we don't have the right GL requirements, exit. +	// BUG: This should just be changed to a generic GL "Not good enough" flag +	if (!gGLManager.mHasMultitexture && !gNoRender) +	{ +		std::ostringstream msg; +		msg << +			"You do not appear to have the proper hardware requirements " +			"for " << gSecondLife << ". " << gSecondLife << " requires an OpenGL graphics " +			"card that has multitexture support. If this is the case, " +			"you may want to make sure that you have the latest drivers for " +			"your graphics card, and service packs and patches for your " +			"operating system.\n" +			"If you continue to have problems, please go to: " +			"www.secondlife.com/support "; +		OSMessageBox( +			msg.str().c_str(), +			NULL, +			OSMB_OK); +		return 0; +	} + +	// Save the current version to the prefs file +	gSavedSettings.setString("LastRunVersion", gCurrentVersion); + +	gSimLastTime = gRenderStartTime.getElapsedTimeF32(); +	gSimFrames = (F32)gFrameCount; + +	return true; +} + +bool LLAppViewer::mainLoop() +{ +	//------------------------------------------- +	// Run main loop until time to quit +	//------------------------------------------- + +	// Create IO Pump to use for HTTP Requests. +	gServicePump = new LLPumpIO(gAPRPoolp); +	LLHTTPClient::setPump(*gServicePump); +	LLHTTPClient::setCABundle(gDirUtilp->getCAFile()); +	 +	// initialize voice stuff here +	gLocalSpeakerMgr = new LLLocalSpeakerMgr(); +	gActiveChannelSpeakerMgr = new LLActiveSpeakerMgr(); + +	LLVoiceChannel::initClass(); +	LLVoiceClient::init(gServicePump); +				 +	LLMemType mt1(LLMemType::MTYPE_MAIN); +	LLTimer frameTimer,idleTimer; +	LLTimer debugTime; +	 +	// Handle messages +	while (!LLApp::isExiting()) +	{ +		LLFastTimer::reset(); // Should be outside of any timer instances +		{ +			LLFastTimer t(LLFastTimer::FTM_FRAME); + +			{ +				LLFastTimer t2(LLFastTimer::FTM_MESSAGES); +			#if LL_WINDOWS +				if (!LLWinDebug::setupExceptionHandler()) +				{ +					llwarns << " Someone took over my exception handler (post messagehandling)!" << llendl; +				} +			#endif + +				gViewerWindow->mWindow->gatherInput(); +			} + +#if 1 && !RELEASE_FOR_DOWNLOAD +			// once per second debug info +			if (debugTime.getElapsedTimeF32() > 1.f) +			{ +				debugTime.reset(); +			} +#endif +			if (!LLApp::isExiting()) +			{ +				// 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 (gViewerWindow->mWindow->getVisible()  +					&& gViewerWindow->getActive() +					&& !gViewerWindow->mWindow->getMinimized() +					&& LLStartUp::getStartupState() == STATE_STARTED +					&& !gViewerWindow->getShowProgress() +					&& !gFocusMgr.focusLocked()) +				{ +					gKeyboard->scanKeyboard(); +					LLViewerJoystick::scanJoystick(); +				} + +				// Update state based on messages, user input, object idle. +				{ +					LLFastTimer t3(LLFastTimer::FTM_IDLE); +					idle(); +					LLCurl::process(); +					// this pump is necessary to make the login screen show up +					gServicePump->pump(); +					gServicePump->callback(); +				} + +				if (gDoDisconnect && (LLStartUp::getStartupState() == STATE_STARTED)) +				{ +					saveFinalSnapshot(); +					disconnectViewer(); +				} + +				// Render scene. +				if (!LLApp::isExiting()) +				{ +					display(); + +					LLFloaterSnapshot::update(); // take snapshots +					 +#if !LL_SOLARIS +					if (gbCapturing) +					{ +						gMovieMaker.Snap(); +					} +#endif +#if LL_WINDOWS && LL_LCD_COMPILE +					// update LCD Screen +					gLcdScreen->UpdateDisplay(); +#endif +				} + +			} + +			// Sleep and run background threads +			{ +				LLFastTimer t2(LLFastTimer::FTM_SLEEP); +				bool run_multiple_threads = gSavedSettings.getBOOL("RunMultipleThreads"); + +				// yield some time to the os based on command line option +				if(gYieldTime) +				{ +					ms_sleep(gYieldMS); +				} + +				// yield cooperatively when not running as foreground window +				if (   gNoRender +						|| !gViewerWindow->mWindow->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(); +					} +				} +				 +				if (gRandomizeFramerate) +				{ +					ms_sleep(rand() % 200); +				} + +				if (gPeriodicSlowFrame +					&& (gFrameCount % 10 == 0)) +				{ +					llinfos << "Periodic slow frame - sleeping 500 ms" << llendl; +					ms_sleep(500); +				} + + +				const F64 min_frame_time = 0.0; //(.0333 - .0010); // max video frame rate = 30 fps +				const F64 min_idle_time = 0.0; //(.0010); // min idle time = 1 ms +				const F64 max_idle_time = run_multiple_threads ? min_idle_time : .005; // 5 ms +				idleTimer.reset(); +				while(1) +				{ +					S32 work_pending = 0; +					S32 io_pending = 0; + 					work_pending += LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread + 					work_pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread + 					work_pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread +					io_pending += LLVFSThread::updateClass(1); +					io_pending += LLLFSThread::updateClass(1); +					if (io_pending > 1000) +					{ +						ms_sleep(llmin(io_pending/100,100)); // give the vfs some time to catch up +					} + +					F64 frame_time = frameTimer.getElapsedTimeF64(); +					F64 idle_time = idleTimer.getElapsedTimeF64(); +					if (frame_time >= min_frame_time && +						idle_time >= min_idle_time && +						(!work_pending || idle_time >= max_idle_time)) +					{ +						break; +					} +				} +				frameTimer.reset(); + +				 // Prevent the worker threads from running while rendering. +				// if (LLThread::processorCount()==1) //pause() should only be required when on a single processor client... +				if (run_multiple_threads == FALSE) +				{ +					LLAppViewer::getTextureCache()->pause(); +					LLAppViewer::getImageDecodeThread()->pause(); +					// LLAppViewer::getTextureFetch()->pause(); // Don't pause the fetch (IO) thread +				} +				//LLVFSThread::sLocal->pause(); // Prevent the VFS thread from running while rendering. +				//LLLFSThread::sLocal->pause(); // Prevent the LFS thread from running while rendering. +			} +						 +		} +	} + +	// Save snapshot for next time, if we made it through initialization +	if (STATE_STARTED == LLStartUp::getStartupState()) +	{ +		saveFinalSnapshot(); +	} +	 +	delete gServicePump; + +	llinfos << "Exiting main_loop" << llendflush; + +	return true; +} + +bool LLAppViewer::cleanup() +{ +	//flag all elements as needing to be destroyed immediately +	// to ensure shutdown order +	LLMortician::setZealous(TRUE); + +	LLVoiceClient::terminate(); +	 +	disconnectViewer(); + +	llinfos << "Viewer disconnected" << llendflush; + +	display_cleanup();  + +	release_start_screen(); // just in case + +	LLError::logToFixedBuffer(NULL); + +	llinfos << "Cleaning Up" << llendflush; + +	LLKeyframeDataCache::clear(); +	 +	// Must clean up texture references before viewer window is destroyed. +	LLHUDObject::cleanupHUDObjects(); +	llinfos << "HUD Objects cleaned up" << llendflush; + + 	// End TransferManager before deleting systems it depends on (Audio, VFS, AssetStorage) +#if 0 // this seems to get us stuck in an infinite loop... +	gTransferManager.cleanup(); +#endif +	 +	// Clean up map data storage +	delete gWorldMap; +	gWorldMap = NULL; + +	delete gHUDManager; +	gHUDManager = NULL; + +	delete gToolMgr; +	gToolMgr = NULL; + +	delete gAssetStorage; +	gAssetStorage = NULL; + +	LLPolyMesh::freeAllMeshes(); + +	delete gCacheName; +	gCacheName = NULL; + +	delete gGlobalEconomy; +	gGlobalEconomy = NULL; + +	delete gLocalSpeakerMgr; +	gLocalSpeakerMgr = NULL; + +	LLNotifyBox::cleanup(); + +	llinfos << "Global stuff deleted" << llendflush; + +#if !LL_RELEASE_FOR_DOWNLOAD +	if (gAudiop) +	{ +		gAudiop->shutdown(); +	} +#else +	// This hack exists because fmod likes to occasionally hang forever +	// when shutting down for no apparent reason. +	llwarns << "Hack, skipping audio engine cleanup" << llendflush; +#endif + + +	// moved to main application shutdown for now because it's non-trivial and only needs to be done once +	// (even though it goes against the media framework design) + +	LLMediaEngine::cleanupClass(); +	 +#if LL_QUICKTIME_ENABLED +	if (gQuickTimeInitialized) +	{ +		// clean up media stuff +		llinfos << "Cleaning up QuickTime" << llendl; +		ExitMovies (); +		#if LL_WINDOWS +			// Only necessary/available on Windows. +			TerminateQTML (); +		#endif +	} +	llinfos << "Quicktime cleaned up" << llendflush; +#endif + +#if LL_GSTREAMER_ENABLED +	llinfos << "Cleaning up GStreamer" << llendl; +	UnloadGStreamer(); +	llinfos << "GStreamer cleaned up" << llendflush;	 +#endif + +	llinfos << "Cleaning up feature manager" << llendflush; +	delete gFeatureManagerp; +	gFeatureManagerp = NULL; + +	// Patch up settings for next time +	// Must do this before we delete the viewer window, +	// such that we can suck rectangle information out of +	// it. +	cleanupSavedSettings(); +	llinfos << "Settings patched up" << llendflush; + +	delete gAudiop; +	gAudiop = NULL; + +	// delete some of the files left around in the cache. +	removeCacheFiles("*.wav"); +	removeCacheFiles("*.tmp"); +	removeCacheFiles("*.lso"); +	removeCacheFiles("*.out"); +	removeCacheFiles("*.dsf"); +	removeCacheFiles("*.bodypart"); +	removeCacheFiles("*.clothing"); + +	llinfos << "Cache files removed" << llendflush; + + +	cleanup_menus(); + +	// Wait for any pending VFS IO +	while (1) +	{ +		S32 pending = LLVFSThread::updateClass(0); +		pending += LLLFSThread::updateClass(0); +		if (!pending) +		{ +			break; +		} +		llinfos << "Waiting for pending IO to finish: " << pending << llendflush; +		ms_sleep(100); +	} +	llinfos << "Shutting down." << llendflush; +	 +	// Destroy Windows(R) window, and make sure we're not fullscreen +	// This may generate window reshape and activation events. +	// Therefore must do this before destroying the message system. +	delete gViewerWindow; +	gViewerWindow = NULL; +	llinfos << "ViewerWindow deleted" << llendflush; + +	// viewer UI relies on keyboard so keep it aound until viewer UI isa gone +	delete gKeyboard; +	gKeyboard = NULL; + +	// Clean up selection managers after UI is destroyed, as UI +	// may be observing them. +	LLSelectMgr::cleanupGlobals(); + +	LLViewerObject::cleanupVOClasses(); +		 +	LLTracker::cleanupInstance(); +	 +#if LL_LIBXUL_ENABLED +	// this must be done after floater cleanup (delete gViewerWindow) since  +	// floaters  potentially need the manager to destroy their contents. +	LLMozLib::getInstance()->reset(); +#endif + +	// *FIX: This is handled in LLAppViewerWin32::cleanup(). +	// I'm keeping the comment to remember its order in cleanup, +	// in case of unforseen dependency. +//#if LL_WINDOWS +//	gDXHardware.cleanup(); +//#endif // LL_WINDOWS + +#if LL_WINDOWS && LL_LCD_COMPILE +	// shut down the LCD window on a logitech keyboard, if there is one +	delete gLcdScreen; +	gLcdScreen = NULL; +#endif + +	if (!gVolumeMgr->cleanup()) +	{ +		llwarns << "Remaining references in the volume manager!" << llendflush; +	} + +	LLViewerParcelMgr::cleanupGlobals(); + +	delete gViewerStats; +	gViewerStats = NULL; + + 	//end_messaging_system(); + +	LLFollowCamMgr::cleanupClass(); +	LLVolumeMgr::cleanupClass(); +	LLWorldMapView::cleanupClass(); +	LLUI::cleanupClass(); +	 +	// +	// Shut down the VFS's AFTER the decode manager cleans up (since it cleans up vfiles). +	// Also after viewerwindow is deleted, since it may have image pointers (which have vfiles) +	// Also after shutting down the messaging system since it has VFS dependencies +	// +	LLVFile::cleanupClass(); +	llinfos << "VFS cleaned up" << llendflush; + +	// Store the time of our current logoff +	gSavedPerAccountSettings.setU32("LastLogoff", time_corrected()); + +	// Must do this after all panels have been deleted because panels that have persistent rects +	// save their rects on delete. +	gSavedSettings.saveToFile(gSettingsFileName, TRUE); +	if (!gPerAccountSettingsFileName.empty()) +	{ +		gSavedPerAccountSettings.saveToFile(gPerAccountSettingsFileName, TRUE); +	} +	llinfos << "Saved settings" << llendflush; + +	std::string crash_settings_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, CRASH_SETTINGS_FILE); +	// save all settings, even if equals defaults +	gCrashSettings.saveToFile(crash_settings_filename.c_str(), FALSE); + +	delete gUICtrlFactory; +	gUICtrlFactory = NULL; + +	gSavedSettings.cleanup(); +	gViewerArt.cleanup(); +	gColors.cleanup(); +	gCrashSettings.cleanup(); + +	if (gMuteListp) +	{ +		// save mute list +		gMuteListp->cache(gAgent.getID()); + +		delete gMuteListp; +		gMuteListp = NULL; +	} + +	if (mPurgeOnExit) +	{ +		llinfos << "Purging all cache files on exit" << llendflush; +		char mask[LL_MAX_PATH];		/* Flawfinder: ignore */ +		snprintf(mask, LL_MAX_PATH, "%s*.*", gDirUtilp->getDirDelimiter().c_str());		/* Flawfinder: ignore */ +		gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"").c_str(),mask); +	} + +	removeMarkerFile(); // Any crashes from here on we'll just have to ignore +	 +	closeDebug(); + +	// Let threads finish +	LLTimer idleTimer; +	idleTimer.reset(); +	const F64 max_idle_time = 5.f; // 5 seconds +	while(1) +	{ +		S32 pending = 0; +		pending += LLAppViewer::getTextureCache()->update(1); // unpauses the worker thread +		pending += LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread +		pending += LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread +		pending += LLVFSThread::updateClass(0); +		pending += LLLFSThread::updateClass(0); +		F64 idle_time = idleTimer.getElapsedTimeF64(); +		if (!pending || idle_time >= max_idle_time) +		{ +			llwarns << "Quitting with pending background tasks." << llendl; +			break; +		} +	} +	 +	// Delete workers first +	// shotdown all worker threads before deleting them in case of co-dependencies +	sTextureCache->shutdown(); +	sTextureFetch->shutdown(); +	sImageDecodeThread->shutdown(); +	delete sTextureCache; +    sTextureCache = NULL; +	delete sTextureFetch; +    sTextureFetch = NULL; +	delete sImageDecodeThread; +    sImageDecodeThread = NULL; + +	gImageList.shutdown(); // shutdown again in case a callback added something +	 +	// This should eventually be done in LLAppViewer +	LLImageJ2C::closeDSO(); +	LLImageFormatted::cleanupClass(); +	LLVFSThread::cleanupClass(); +	LLLFSThread::cleanupClass(); + +	llinfos << "VFS Thread finished" << llendflush; + +#ifndef LL_RELEASE_FOR_DOWNLOAD +	llinfos << "Auditing VFS" << llendl; +	gVFS->audit(); +#endif + +	// For safety, the LLVFS has to be deleted *after* LLVFSThread. This should be cleaned up. +	// (LLVFS doesn't know about LLVFSThread so can't kill pending requests) -Steve +	delete gStaticVFS; +	gStaticVFS = NULL; +	delete gVFS; +	gVFS = NULL; +	 +	end_messaging_system(); + +    // *NOTE:Mani - The following call is not thread safe.  +    LLCurl::cleanup(); + +    // If we're exiting to launch an URL, do that here so the screen +	// is at the right resolution before we launch IE. +	if (!gLaunchFileOnQuit.empty()) +	{ +#if LL_WINDOWS +		// Indicate an application is starting. +		SetCursor(LoadCursor(NULL, IDC_WAIT)); +#endif + +		// HACK: Attempt to wait until the screen res. switch is complete. +		ms_sleep(1000); + +		LLWeb::loadURLExternal( gLaunchFileOnQuit ); +	} + + +    llinfos << "Goodbye" << llendflush; +	// return 0; +	return true; +} + +bool LLAppViewer::initEarlyConfiguration() +{ +	// *FIX: globals - This method sets a bunch of globals early in the init process. +	int argc = gTempArgC; +	char** argv = gTempArgV; + +	// HACK! We REALLY want to know what grid they were trying to connect to if they +	// crashed hard. +	// So we walk through the command line args ONLY looking for the +	// userserver arguments first.  And we don't do ANYTHING but set +	// the gGridName (which gets passed to the crash reporter). +	// We're assuming that they're trying to log into the same grid as last +	// time, which seems fairly reasonable. +	snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GridDefaultChoice].mName);		// Flawfinder: ignore +	S32 j; +	for (j = 1; j < argc; j++)  +	{ +		if (!strcmp(argv[j], "--aditi")) +		{ +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_ADITI].mName);		// Flawfinder: ignore +		} +		else if (!strcmp(argv[j], "--agni")) +		{ +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_AGNI].mName);		// Flawfinder: ignore +		} +		else if (!strcmp(argv[j], "--dmz")) +		{ +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_DMZ].mName);		// Flawfinder: ignore +		} +		else if (!strcmp(argv[j], "--siva")) +		{ +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_SIVA].mName);		// Flawfinder: ignore +		} +		else if (!strcmp(argv[j], "--shakti")) +		{ +			sprintf(gGridName,"%s", gGridInfo[GRID_INFO_SHAKTI].mName); +		} +		else if (!strcmp(argv[j], "--durga")) +		{ +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_DURGA].mName);		// Flawfinder: ignore +		} +		else if (!strcmp(argv[j], "--soma")) +		{ +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_SOMA].mName);		// Flawfinder: ignore +		} +		else if (!strcmp(argv[j], "--ganga")) +		{ +			snprintf(gGridName, MAX_STRING, "%s", gGridInfo[GRID_INFO_GANGA].mName);		// Flawfinder: ignore  +		} +		else if (!strcmp(argv[j], "--vaak")) +		{ +			sprintf(gGridName,"%s", gGridInfo[GRID_INFO_VAAK].mName); +		} +		else if (!strcmp(argv[j], "--uma")) +		{ +			sprintf(gGridName,"%s", gGridInfo[GRID_INFO_UMA].mName); +		} +		else if (!strcmp(argv[j], "-user") && (++j < argc)) +		{ +			if (!strcmp(argv[j], "-")) +			{ +				snprintf(gGridName, MAX_STRING, "%s", LOOPBACK_ADDRESS_STRING);		// Flawfinder: ignore  +			} +			else +			{ +				snprintf(gGridName, MAX_STRING, "%s", argv[j]);		// Flawfinder: ignore  +			} +		} +		else if (!strcmp(argv[j], "-multiple")) +		{ +			// Hack to detect -multiple so we can disable the marker file check (which will always fail) +			gMultipleViewersOK = TRUE; +		} +		else if (!strcmp(argv[j], "-novoice")) +		{ +			// May need to know this early also +			gDisableVoice = TRUE; +		} +		else if (!strcmp(argv[j], "-url") && (++j < argc))  +		{ +			LLURLSimString::setString(argv[j]); +		} +	} + +	return true; +} + +bool LLAppViewer::initThreads() +{ +#if MEM_TRACK_MEM +	static const bool enable_threads = false; +#else +	static const bool enable_threads = true; +#endif +	LLVFSThread::initClass(enable_threads && true); +	LLLFSThread::initClass(enable_threads && true); + +	// Image decoding +	LLAppViewer::sImageDecodeThread = new LLWorkerThread("ImageDecode", enable_threads && true); +	LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true); +	LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), enable_threads && false); +	LLImageWorker::initClass(LLAppViewer::getImageDecodeThread()); +	LLImageJ2C::openDSO(); + +	// *FIX: no error handling here! +	return true; +} + +void errorCallback(const std::string &error_string) +{ +#ifndef LL_RELEASE_FOR_DOWNLOAD +	OSMessageBox(error_string.c_str(), "Fatal Error", OSMB_OK); +#endif +	LLError::crashAndLoop(error_string); +} + +bool LLAppViewer::initLogging() +{ +	// +	// Set up logging defaults for the viewer +	// +	LLError::initForApplication( +				gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); +	LLError::setFatalFunction(errorCallback); +	 +	// Remove the last ".old" log file. +	std::string old_log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, +							     "SecondLife.old"); +	LLFile::remove(old_log_file.c_str()); + +	// Rename current log file to ".old" +	std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, +							     "SecondLife.log"); +	LLFile::rename(log_file.c_str(), old_log_file.c_str()); + +	// Set the log file to SecondLife.log + +	LLError::logToFile(log_file); + +	// *FIX:Mani no error handling here! +	return true; +} + +bool LLAppViewer::initConfiguration() +{ +	// Ye olde parse_args()... +	if(!doConfigFromCommandLine()) +	{ +		return false; +	} +	 +	// XUI:translate +	gSecondLife = "Second Life"; + +	// Read skin/branding settings if specified. +	if (! gDirUtilp->getSkinDir().empty() ) +	{ +		std::string skin_def_file = gDirUtilp->getExpandedFilename(LL_PATH_TOP_SKIN, "skin.xml"); +		LLXmlTree skin_def_tree; + +		if (!skin_def_tree.parseFile(skin_def_file)) +		{ +			llerrs << "Failed to parse skin definition." << llendl; +		} + +		LLXmlTreeNode* rootp = skin_def_tree.getRoot(); +		LLXmlTreeNode* disabled_message_node = rootp->getChildByName("disabled_message");	 +		if (disabled_message_node) +		{ +			gDisabledMessage = disabled_message_node->getContents(); +		} + +		static LLStdStringHandle hide_links_string = LLXmlTree::addAttributeString("hide_links"); +		rootp->getFastAttributeBOOL(hide_links_string, gHideLinks); + +		// Legacy string.  This flag really meant we didn't want to expose references to "Second Life". +		// Just set gHideLinks instead. +		static LLStdStringHandle silent_string = LLXmlTree::addAttributeString("silent_update"); +		BOOL silent_update; +		rootp->getFastAttributeBOOL(silent_string, silent_update); +		gHideLinks = (gHideLinks || silent_update); +	} + +#if LL_DARWIN +	// Initialize apple menubar and various callbacks +	init_apple_menu(gSecondLife.c_str()); + +#if __ppc__ +	// If the CPU doesn't have Altivec (i.e. it's not at least a G4), don't go any further. +	// Only test PowerPC - all Intel Macs have SSE. +	if(!gSysCPU.hasAltivec()) +	{ +		std::ostringstream msg; +		msg << gSecondLife << " requires a processor with AltiVec (G4 or later)."; +		OSMessageBox( +			msg.str().c_str(), +			NULL, +			OSMB_OK); +		removeMarkerFile(); +		return false; +	} +#endif +	 +#endif // LL_DARWIN + +	// Display splash screen.  Must be after above check for previous +	// crash as this dialog is always frontmost. +	std::ostringstream splash_msg; +	splash_msg << "Loading " << gSecondLife << "..."; +	LLSplashScreen::show(); +	LLSplashScreen::update(splash_msg.str().c_str()); + +	LLVolumeMgr::initClass(); + +	// Initialize the feature manager +	// The feature manager is responsible for determining what features +	// are turned on/off in the app. +	gFeatureManagerp = new LLFeatureManager; + +	gStartTime = totalTime(); + +	//////////////////////////////////////// +	// +	// Process ini files +	// + +	// declare all possible setting variables +	declare_settings(); + +#if !LL_RELEASE_FOR_DOWNLOAD +//	only write the defaults for non-release builds! +	gSavedSettings.saveToFile(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings_default.xml").c_str(), FALSE); +#endif + +	// +	// Set the name of the window +	// +#if LL_RELEASE_FOR_DOWNLOAD +	gWindowTitle = gSecondLife; +#elif LL_DEBUG +	gWindowTitle = gSecondLife + LLString(" [DEBUG] ") + gArgs; +#else +	gWindowTitle = gSecondLife + LLString(" ") + gArgs; +#endif +	LLString::truncate(gWindowTitle, 255); + +	if (!gMultipleViewersOK) +	{ +	    // +	    // Check for another instance of the app running +	    // +		//RN: if we received a URL, hand it off to the existing instance +		// don't call anotherInstanceRunning() when doing URL handoff, as +		// it relies on checking a marker file which will not work when running +		// out of different directories +		std::string slurl; +		if (!LLStartUp::sSLURLCommand.empty()) +		{ +			slurl = LLStartUp::sSLURLCommand; +		} +		else if (LLURLSimString::parse()) +		{ +			slurl = LLURLSimString::getURL(); +		} +		if (!slurl.empty()) +		{ +			if (send_url_to_other_instance(slurl)) +			{ +				// successfully handed off URL to existing instance, exit +				return 1; +			} +		} +		 +		mSecondInstance = anotherInstanceRunning(); +		 +		if (mSecondInstance) +		{ +			std::ostringstream msg; +			msg <<  +				gSecondLife << " is already running.\n" +				"\n" +				"Check your task bar for a minimized copy of the program.\n" +				"If this message persists, restart your computer.", +			OSMessageBox( +				msg.str().c_str(), +				NULL, +				OSMB_OK); +			return 1; +		} + +		initMarkerFile(); + +#if LL_SEND_CRASH_REPORTS +		if (gLastExecFroze) +		{ +			llinfos << "Last execution froze, requesting to send crash report." << llendl; +			// +			// Pop up a freeze or crash warning dialog +			// +			std::ostringstream msg; +			msg << gSecondLife +				<< " appears to have frozen or crashed on the previous run.\n" +				<< "Would you like to send a crash report?"; +			std::string alert; +			alert = gSecondLife; +			alert += " Alert"; +			S32 choice = OSMessageBox(msg.str().c_str(), +				alert.c_str(), +				OSMB_YESNO); +			if (OSBTN_YES == choice) +			{ +				llinfos << "Sending crash report." << llendl; + + 				removeMarkerFile(); +#if LL_WINDOWS +				std::string exe_path = gDirUtilp->getAppRODataDir(); +				exe_path += gDirUtilp->getDirDelimiter(); +				exe_path += "win_crash_logger.exe"; + +				std::string arg_string = "-previous -user "; +				arg_string += gGridName; +				arg_string += " -name \""; +				arg_string += gSecondLife; +				arg_string += "\""; +				// Spawn crash logger. +				// NEEDS to wait until completion, otherwise log files will get smashed. +				_spawnl(_P_WAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL); +#elif LL_DARWIN +				std::string command_str; +				command_str = "crashreporter.app/Contents/MacOS/crashreporter "; +				command_str += "-previous -user "; +				command_str += gGridName; +				// XXX -- We need to exit fullscreen mode for this to work. +				// XXX -- system() also doesn't wait for completion.  Hmm... +				system(command_str.c_str());		/* Flawfinder: Ignore */ +#elif LL_LINUX || LL_SOLARIS +				std::string cmd =gDirUtilp->getAppRODataDir(); +				cmd += gDirUtilp->getDirDelimiter(); +#if LL_LINUX +				cmd += "linux-crash-logger.bin"; +#else // LL_SOLARIS +				cmd += "bin/solaris-crash-logger"; +#endif +				char* const cmdargv[] = +					{(char*)cmd.c_str(), +					 (char*)"-previous", +					 (char*)"-user", +					 (char*)gGridName, +					 (char*)"-name", +					 (char*)gSecondLife.c_str(), +					 NULL}; +				pid_t pid = fork(); +				if (pid == 0) +				{ // child +					execv(cmd.c_str(), cmdargv);		/* Flawfinder: Ignore */ +					llwarns << "execv failure when trying to start " << cmd << llendl; +					_exit(1); // avoid atexit() +				} else { +					if (pid > 0) +					{ +						// wait for child proc to die +						int childExitStatus; +						waitpid(pid, &childExitStatus, 0); +					} else { +						llwarns << "fork failure." << llendl; +					} +				} +#endif +			} +			else +			{ +				llinfos << "Not sending crash report." << llendl; +			} +		} +#endif // #if LL_SEND_CRASH_REPORTS +	} +	else +	{ +		mSecondInstance = anotherInstanceRunning(); +		 +		if (mSecondInstance) +		{ +			gDisableVoice = TRUE; +			/* Don't start another instance if using -multiple +			//RN: if we received a URL, hand it off to the existing instance +		    if (LLURLSimString::parse()) +		    { +			    LLURLSimString::send_to_other_instance(); +				return 1; +			} +			*/ +		} + +		initMarkerFile(); +	} + +	return true; // Config was successful. +} + +bool LLAppViewer::doConfigFromCommandLine() +{ +	// *FIX: This is what parse args used to do, minus the arg reading part. +	// Now the arg parsing is handled by LLApp::parseCommandOptions() and this +	// method need only interpret settings. Perhaps some day interested parties  +	// can ask an app about a setting rather than have the app set  +	// a gazzillion globals. +	 +	///////////////////////////////////////// +	// +	// Process command line arguments +	// +	S32 args_result = 0; + +#if LL_DARWIN +	{ +		// On the Mac, read in arguments.txt (if it exists) and process it for additional arguments. +		LLString args; +		if(_read_file_into_string(args, "arguments.txt"))		/* Flawfinder: ignore*/ +		{ +			// The arguments file exists.   +			// It should consist of command line arguments separated by newlines. +			// Split it into individual arguments and build a fake argv[] to pass to parse_args. +			std::vector<std::string> arglist; +			 +			arglist.push_back("newview"); +			 +			llinfos << "Reading additional command line arguments from arguments.txt..." << llendl; +			 +			typedef boost::tokenizer<boost::escaped_list_separator<char> > tokenizer; +			boost::escaped_list_separator<char> sep("\\", "\r\n ", "\"'"); +			tokenizer tokens(args, sep); +			tokenizer::iterator token_iter; + +			for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter) +			{ +				llinfos << "argument: '" << (token_iter->c_str()) << "'" << llendl; +				 +				arglist.push_back(*token_iter); +			} + +			char **fakeargv = new char*[arglist.size()]; +			int i; +			for(i=0; i < arglist.size(); i++) +				fakeargv[i] = const_cast<char*>(arglist[i].c_str()); +				 +			args_result = parse_args(arglist.size(), fakeargv); +			delete[] fakeargv; +		} +		 +		// Get the user's preferred language string based on the Mac OS localization mechanism. +		// To add a new localization: +			// go to the "Resources" section of the project +			// get info on "language.txt" +			// in the "General" tab, click the "Add Localization" button +			// create a new localization for the language you're adding +			// set the contents of the new localization of the file to the string corresponding to our localization +			//   (i.e. "en-us", "ja", etc.  Use the existing ones as a guide.) +		CFURLRef url = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("language"), CFSTR("txt"), NULL); +		char path[MAX_PATH]; +		if(CFURLGetFileSystemRepresentation(url, false, (UInt8 *)path, sizeof(path))) +		{ +			LLString lang; +			if(_read_file_into_string(lang, path))		/* Flawfinder: ignore*/ +			{ +				gCommandLineForcedSettings["SystemLanguage"] = lang; +			} +		} +		CFRelease(url); +	} +#endif + +	int argc = gTempArgC; +	char** argv = gTempArgV; + +	// +	// Parse the command line arguments +	// +	args_result |= parse_args(argc, argv); +	if (args_result) +	{ +		removeMarkerFile(); +		return false; +	} +	 +	if (!strcmp(gGridName, gGridInfo[GRID_INFO_AGNI].mName)) +	{ +		gInProductionGrid = TRUE; +	} + +	return true; +} + +bool LLAppViewer::initWindow() +{ +	llinfos << "Initializing window..." << llendl; + +	// store setting in a global for easy access and modification +	gNoRender = gSavedSettings.getBOOL("DisableRendering"); + +	// Hide the splash screen +	LLSplashScreen::hide(); + +	// HACK: Need a non-const char * for stupid window name (propagated deep down) +	char window_title_str[256];		/* Flawfinder: ignore */ +	strncpy(window_title_str, gWindowTitle.c_str(), sizeof(window_title_str) - 1);		/* Flawfinder: ignore */ +	window_title_str[sizeof(window_title_str) - 1] = '\0'; + +	// always start windowed +	gViewerWindow = new LLViewerWindow(window_title_str, "Second Life", +		gSavedSettings.getS32("WindowX"), gSavedSettings.getS32("WindowY"), +		gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"), +		FALSE, gIgnorePixelDepth); +		 +	if (gSavedSettings.getBOOL("FullScreen")) +	{ +		gViewerWindow->toggleFullscreen(FALSE); +			// request to go full screen... which will be delayed until login +	} +	 +	if (gSavedSettings.getBOOL("WindowMaximized")) +	{ +		gViewerWindow->mWindow->maximize(); +		gViewerWindow->getWindow()->setNativeAspectRatio(gSavedSettings.getF32("FullScreenAspectRatio")); +	} + +	LLUI::sWindow = gViewerWindow->getWindow(); + +	LLAlertDialog::parseAlerts("alerts.xml"); +	LLNotifyBox::parseNotify("notify.xml"); + +	LLMediaEngine::initClass(); +	 +	// +	// Clean up the feature manager lookup table - settings were updated +	// in the LLViewerWindow constructor +	// +	gFeatureManagerp->cleanupFeatureTables(); + +	// Show watch cursor +	gViewerWindow->setCursor(UI_CURSOR_WAIT); + +	// Finish view initialization +	gViewerWindow->initBase(); + +	// show viewer window +	gViewerWindow->mWindow->show(); +	 +	return true; +} + +void LLAppViewer::writeDebug(const char *str) +{ +	if (!mDebugFile) +	{ +		std::string debug_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"debug_info.log"); +		llinfos << "Opening debug file " << debug_filename << llendl; +		mDebugFile = LLFile::fopen(debug_filename.c_str(), "w");		/* Flawfinder: ignore */ +        if (!mDebugFile) +        { +		    llinfos << "Opening debug file " << debug_filename << " failed. Using stderr." << llendl; +            mDebugFile = stderr; +        } +	} +	fputs(str, mDebugFile); +	fflush(mDebugFile); +} + +void LLAppViewer::closeDebug() +{ +	if (mDebugFile) +	{ +		fclose(mDebugFile); +	} +	mDebugFile = NULL; +} + +void LLAppViewer::cleanupSavedSettings() +{ +	gSavedSettings.setBOOL("MouseSun", FALSE); + +	gSavedSettings.setBOOL("FlyBtnState", FALSE); + +	gSavedSettings.setBOOL("FirstPersonBtnState", FALSE); +	gSavedSettings.setBOOL("ThirdPersonBtnState", TRUE); +	gSavedSettings.setBOOL("BuildBtnState", FALSE); + +	gSavedSettings.setBOOL("UseEnergy", TRUE);				// force toggle to turn off, since sends message to simulator + +	gSavedSettings.setBOOL("DebugWindowProc", gDebugWindowProc); +		 +	gSavedSettings.setBOOL("AllowIdleAFK", gAllowIdleAFK); +	gSavedSettings.setBOOL("ShowObjectUpdates", gShowObjectUpdates); +	 +	if (!gNoRender) +	{ +		if (gDebugView) +		{ +			gSavedSettings.setBOOL("ShowDebugConsole", gDebugView->mDebugConsolep->getVisible()); +			gSavedSettings.setBOOL("ShowDebugStats", gDebugView->mStatViewp->getVisible()); +		} +	} + +	// save window position if not fullscreen +	// as we don't track it in callbacks +	BOOL fullscreen = gViewerWindow->mWindow->getFullscreen(); +	BOOL maximized = gViewerWindow->mWindow->getMaximized(); +	if (!fullscreen && !maximized) +	{ +		LLCoordScreen window_pos; + +		if (gViewerWindow->mWindow->getPosition(&window_pos)) +		{ +			gSavedSettings.setS32("WindowX", window_pos.mX); +			gSavedSettings.setS32("WindowY", window_pos.mY); +		} +	} + +	gSavedSettings.setF32("MapScale", gMapScale ); +	gSavedSettings.setF32("MiniMapScale", gMiniMapScale ); +	gSavedSettings.setBOOL("AsyncKeyboard", gHandleKeysAsync); +	gSavedSettings.setBOOL("ShowHoverTips", LLHoverView::sShowHoverTips); + +	// Some things are cached in LLAgent. +	if (gAgent.mInitialized) +	{ +		gSavedSettings.setF32("RenderFarClip", gAgent.mDrawDistance); +	} + +	// *REMOVE: This is now done via LLAppViewer::setCrashBehavior() +	// Left vestigially in case I borked it. +	// gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, gCrashBehavior); +} + +void LLAppViewer::removeCacheFiles(const char* file_mask) +{ +	char mask[LL_MAX_PATH];		/* Flawfinder: ignore */ +	snprintf(mask, LL_MAX_PATH, "%s%s", gDirUtilp->getDirDelimiter().c_str(), file_mask);		/* Flawfinder: ignore */ +	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "").c_str(), mask); +} + +void LLAppViewer::writeSystemInfo() +{ +	writeDebug("SL Log: "); +	writeDebug(LLError::logFileName()); +	writeDebug("\n"); + +	std::string tmp_str = gSecondLife +		+ llformat(" version %d.%d.%d build %d", +				   LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VERSION_BUILD); +	writeDebug(tmp_str.c_str()); +	writeDebug("\n"); +	writeDebug(gSysCPU.getCPUString()); +	writeDebug("\n"); +	 +	tmp_str = llformat("RAM: %u KB\n", gSysMemory.getPhysicalMemoryKB()); +	writeDebug(tmp_str.c_str()); +	writeDebug("OS: "); +	writeDebug(getOSInfo().getOSString().c_str()); +	writeDebug("\n"); + +	// Dump some debugging info +	llinfos << gSecondLife << " version " +		<< LL_VERSION_MAJOR << "." +		<< LL_VERSION_MINOR << "." +		<< LL_VERSION_PATCH +		<< llendl; + +	// Dump the local time and time zone +	time_t now; +	time(&now); +	char tbuffer[256];		/* Flawfinder: ignore */ +	strftime(tbuffer, 256, "%Y-%m-%dT%H:%M:%S %Z", localtime(&now)); +	llinfos << "Local time: " << tbuffer << llendl; + +	// query some system information +	llinfos << "CPU info:\n" << gSysCPU << llendl; +	llinfos << "Memory info:\n" << gSysMemory << llendl; +	llinfos << "OS info: " << getOSInfo() << llendl; +} + +void LLAppViewer::handleViewerCrash() +{ +	LLAppViewer* pApp = LLAppViewer::instance(); +	if (pApp->beingDebugged()) +	{ +		// This will drop us into the debugger. +		abort(); +	} + +	// Returns whether a dialog was shown. +	// Only do the logic in here once +	if (pApp->mReportedCrash) +	{ +		return; +	} +	pApp->mReportedCrash = TRUE; + +	BOOL do_crash_report = FALSE; + +	do_crash_report = TRUE; + +	pApp->writeDebug("Viewer exe: "); +	pApp->writeDebug(gDirUtilp->getExecutablePathAndName().c_str()); +	pApp->writeDebug("\n"); +	pApp->writeDebug("Cur path: "); +	pApp->writeDebug(gDirUtilp->getCurPath().c_str()); +	pApp->writeDebug("\n\n"); + +	if (gMessageSystem && gDirUtilp) +	{ +		std::string filename; +		filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "stats.log"); +		llofstream file(filename.c_str(), llofstream::binary); +		if(file.good()) +		{ +			gMessageSystem->summarizeLogs(file); +		} +	} + +	if (gMessageSystem) +	{ +		pApp->writeDebug(gMessageSystem->getCircuitInfoString()); +		gMessageSystem->stopLogging(); +	} +	pApp->writeDebug("\n"); +	if (gWorldp) +	{ +		pApp->writeDebug(gWorldp->getInfoString()); +	} + +	// Close the debug file +	pApp->closeDebug(); +	LLError::logToFile(""); + +	// Close the SecondLife.log +	//pApp->removeMarkerFile(); + +	// Call to pure virtual, handled by platform specifc llappviewer instance. +	pApp->handleCrashReporting();  + +	return; +} + +void LLAppViewer::setCrashBehavior(S32 cb)  +{  +	mCrashBehavior = cb;  +	gCrashSettings.setS32(CRASH_BEHAVIOR_SETTING, mCrashBehavior); +}  + +bool LLAppViewer::anotherInstanceRunning() +{ +		// We create a marker file when the program starts and remove the file when it finishes. +	// If the file is currently locked, that means another process is already running. + +	std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker"); +	llinfos << "Checking marker file for lock..." << llendl; + +	// If file doesn't exist, we create it +	// If file does exist, try to get writing privilages +	FILE* fMarker = LLFile::fopen(marker_file.c_str(), "rb");		// Flawfinder: ignore +	if (fMarker != NULL) +	{ +		// File exists, try opening with write permissions +		fclose(fMarker); +		fMarker = LLFile::fopen(marker_file.c_str(), "wb");		// Flawfinder: ignore +		if (fMarker == NULL) +		{ +			llinfos << "Marker file is locked." << llendl; +			return TRUE; +		} + +		// *FIX:Mani - rather than have this exception here,  +		// LLFile::fopen() have consistent behavior across platforms? +#if LL_DARWIN +		// Try to lock it. On Mac, this is the only way to test if it's actually locked. +		if (flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1) +		{ +			// Lock failed - somebody else has it. +			fclose(fMarker); +			llinfos << "Marker file is locked." << llendl; +			return TRUE; +		} +#endif +		fclose(fMarker); +	} +	llinfos << "Marker file isn't locked." << llendl; +	return FALSE; + +} + +void LLAppViewer::initMarkerFile() +{ +	// *FIX:Mani - an actually cross platform LLFile lib would be nice. + +#if LL_SOLARIS +        struct flock fl; +        fl.l_whence = SEEK_SET; +        fl.l_start = 0; +        fl.l_len = 1; +#endif +	// We create a marker file when the program starts and remove the file when it finishes. +	// If the file is currently locked, that means another process is already running. +	// If the file exists and isn't locked, we crashed on the last run. + +	std::string marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker"); +	llinfos << "Checking marker file for lock..." << llendl; + +	FILE* fMarker = LLFile::fopen(marker_file.c_str(), "rb");		// Flawfinder: ignore +	if (fMarker != NULL) +	{ +		// File exists, try opening with write permissions +		fclose(fMarker); +		fMarker = LLFile::fopen(marker_file.c_str(), "wb");		// Flawfinder: ignxore +		if (fMarker == NULL) +		{ +			// Another instance is running. Skip the rest of these operations. +			llinfos << "Marker file is locked." << llendl; +			return; +		} +#if LL_DARWIN +		// Try to lock it. On Mac, this is the only way to test if it's actually locked. +		if (flock(fileno(fMarker), LOCK_EX | LOCK_NB) == -1) +		{ +			// Lock failed - somebody else has it. +			fclose(fMarker); +			llinfos << "Marker file is locked." << llendl; +			return; +		} +#endif + +		// No other instances; we'll lock this file now & delete on quit. +		fclose(fMarker); +		gLastExecFroze = TRUE; +		llinfos << "Exec marker found: program froze on previous execution" << llendl; +	} + +	// Create the marker file for this execution & lock it +// 	FILE *fp_executing_marker; +#if LL_WINDOWS +	mMarkerFile = LLFile::_fsopen(marker_file.c_str(), "w", _SH_DENYWR); +#else +	mMarkerFile = LLFile::fopen(marker_file.c_str(), "w");		// Flawfinder: ignore +	if (mMarkerFile) +	{ +		int fd = fileno(mMarkerFile); +		// Attempt to lock +#if LL_SOLARIS +		fl.l_type = F_WRLCK; +		if (fcntl(fd, F_SETLK, &fl) == -1) +#else +		if (flock(fd, LOCK_EX | LOCK_NB) == -1) +#endif +		{ +			llinfos << "Failed to lock file." << llendl; +		} +	} +#endif +	if (mMarkerFile) +	{ +		llinfos << "Marker file created." << llendl; +	} +	else +	{ +		llinfos << "Failed to create marker file." << llendl; +	} + +#if LL_WINDOWS +	// Clean up SecondLife.dmp files, to avoid confusion +	llinfos << "Removing SecondLife.dmp" << llendl; +	std::string dmp_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.dmp"); +	LLFile::remove(dmp_filename.c_str()); +#endif + +	// This is to keep the crash reporter from constantly sending stale message logs +	// We wipe the message file now. +	llinfos << "Removing message.log" << llendl; +	std::string message_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "message.log"); +	LLFile::remove(message_filename.c_str()); + +	llinfos << "Exiting initMarkerFile()." << llendl; +} + +void LLAppViewer::removeMarkerFile() +{ +	llinfos << "removeMarkerFile()" << llendl; +	if (mMarkerFile != NULL) +	{ +		fclose(mMarkerFile); +		mMarkerFile = NULL; +	} +	if( gDirUtilp ) +	{ +		LLString marker_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLife.exec_marker"); +		ll_apr_file_remove( marker_file ); +	} +} + +void LLAppViewer::forceQuit() +{  +	LLApp::setQuitting();  +} + +void LLAppViewer::requestQuit() +{ +	llinfos << "requestQuit" << llendl; + +	LLViewerRegion* region = gAgent.getRegion(); +	 +	if( (LLStartUp::getStartupState() < STATE_STARTED) || !region ) +	{ +		// Quit immediately +		forceQuit(); +		return; +	} + +	if (gHUDManager) +	{ +		LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); +		effectp->setPositionGlobal(gAgent.getPositionGlobal()); +		effectp->setColor(LLColor4U(gAgent.getEffectColor())); +		gHUDManager->sendEffects(); +	} + +	// Attempt to close all floaters that might be +	// editing things. +	if (gFloaterView) +	{ +		// application is quitting +		gFloaterView->closeAllChildren(true); +	} + +	send_stats(); + +	gLogoutTimer.reset(); +	mQuitRequested = true; +} + +static void finish_quit(S32 option, void *userdata) +{ +	if (option == 0) +	{ +		LLAppViewer::instance()->requestQuit(); +	} +} + +void LLAppViewer::userQuit() +{ +	gViewerWindow->alertXml("ConfirmQuit", finish_quit, NULL); +} + +static void finish_early_exit(S32 option, void* userdata) +{ +	LLAppViewer::instance()->forceQuit(); +} + +void LLAppViewer::earlyExit(const LLString& msg) +{ +   	llwarns << "app_early_exit: " << msg << llendl; +	gDoDisconnect = TRUE; +// 	LLStringBase<char>::format_map_t args; +// 	args["[MESSAGE]"] = mesg; +// 	gViewerWindow->alertXml("AppEarlyExit", args, finish_early_exit); +	LLAlertDialog::showCritical(msg, finish_early_exit, NULL); +} + +void LLAppViewer::forceExit(S32 arg) +{ +    removeMarkerFile(); +     +    // *FIX:Mani - This kind of exit hardly seems appropriate. +    exit(arg); +} + +void LLAppViewer::abortQuit() +{ +    llinfos << "abortQuit()" << llendl; +	mQuitRequested = false; +} + +bool LLAppViewer::initCache() +{ +	mPurgeCache = false; +	// Purge cache if user requested it +	if (gSavedSettings.getBOOL("PurgeCacheOnStartup") || +		gSavedSettings.getBOOL("PurgeCacheOnNextStartup")) +	{ +		gSavedSettings.setBOOL("PurgeCacheOnNextStartup", false); +		mPurgeCache = true; +	} +	// Purge cache if it belongs to an old version +	else +	{ +		static const S32 cache_version = 5; +		if (gSavedSettings.getS32("LocalCacheVersion") != cache_version) +		{ +			mPurgeCache = true; +			gSavedSettings.setS32("LocalCacheVersion", cache_version); +		} +	} +	 +	// Setup and verify the cache location +	LLString cache_location = gSavedSettings.getString("CacheLocation"); +	LLString new_cache_location = gSavedSettings.getString("NewCacheLocation"); +	if (new_cache_location != cache_location) +	{ +		gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation")); +		purgeCache(); // purge old cache +		gSavedSettings.setString("CacheLocation", new_cache_location); +	} +	 +	if (!gDirUtilp->setCacheDir(gSavedSettings.getString("CacheLocation"))) +	{ +		llwarns << "Unable to set cache location" << llendl; +		gSavedSettings.setString("CacheLocation", ""); +	} +	 +	if (mPurgeCache) +	{ +		LLSplashScreen::update("Clearing cache..."); +		purgeCache(); +	} + +	LLSplashScreen::update("Initializing Texture Cache..."); +	 +	// Init the texture cache +	// Allocate 80% of the cache size for textures +	BOOL read_only = mSecondInstance ? true : false; +	const S32 MB = 1024*1024; +	S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB; +	const S64 MAX_CACHE_SIZE = 1024*MB; +	cache_size = llmin(cache_size, MAX_CACHE_SIZE); +	S64 texture_cache_size = ((cache_size * 8)/10); +	S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, read_only); +	texture_cache_size -= extra; + +	LLSplashScreen::update("Initializing VFS..."); +	 +	// Init the VFS +	S64 vfs_size = cache_size - texture_cache_size; +	const S64 MAX_VFS_SIZE = 1024 * MB; // 1 GB +	vfs_size = llmin(vfs_size, MAX_VFS_SIZE); +	vfs_size = (vfs_size / MB) * MB; // make sure it is MB aligned +	U32 vfs_size_u32 = (U32)vfs_size; +	U32 old_vfs_size = gSavedSettings.getU32("VFSOldSize") * MB; +	bool resize_vfs = (vfs_size_u32 != old_vfs_size); +	if (resize_vfs) +	{ +		gSavedSettings.setU32("VFSOldSize", vfs_size_u32/MB); +	} +	llinfos << "VFS CACHE SIZE: " << vfs_size/(1024*1024) << " MB" << llendl; +	 +	// This has to happen BEFORE starting the vfs +	//time_t	ltime; +	srand(time(NULL));		// Flawfinder: ignore +	U32 old_salt = gSavedSettings.getU32("VFSSalt"); +	U32 new_salt; +	char old_vfs_data_file[LL_MAX_PATH];		// Flawfinder: ignore +	char old_vfs_index_file[LL_MAX_PATH];	// Flawfinder: ignore		 +	char new_vfs_data_file[LL_MAX_PATH];		// Flawfinder: ignore +	char new_vfs_index_file[LL_MAX_PATH];	// Flawfinder: ignore +	char static_vfs_index_file[LL_MAX_PATH];	// Flawfinder: ignore +	char static_vfs_data_file[LL_MAX_PATH];	// Flawfinder: ignore + +	if (gMultipleViewersOK) +	{ +		// don't mess with renaming the VFS in this case +		new_salt = old_salt; +	} +	else +	{ +		do +		{ +			new_salt = rand(); +		} while( new_salt == old_salt ); +	} + +	snprintf(old_vfs_data_file,  LL_MAX_PATH, "%s%u",		// Flawfinder: ignore +		gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_DATA_FILE_BASE).c_str(), +		old_salt); + +	// make sure this file exists +	llstat s; +	S32 stat_result = LLFile::stat(old_vfs_data_file, &s); +	if (stat_result) +	{ +		// doesn't exist, look for a data file +		std::string mask; +		mask = gDirUtilp->getDirDelimiter(); +		mask += VFS_DATA_FILE_BASE; +		mask += "*"; + +		std::string dir; +		dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""); + +		std::string found_file; +		if (gDirUtilp->getNextFileInDir(dir, mask, found_file, false)) +		{ +			snprintf(old_vfs_data_file, LL_MAX_PATH, "%s%s%s", dir.c_str(), gDirUtilp->getDirDelimiter().c_str(), found_file.c_str());		// Flawfinder: ignore + +			S32 start_pos; +			S32 length = strlen(found_file.c_str());		/* Flawfinder: ignore*/ +			for (start_pos = length - 1; start_pos >= 0; start_pos--) +			{ +				if (found_file[start_pos] == '.') +				{ +					start_pos++; +					break; +				} +			} +			if (start_pos > 0) +			{ +				sscanf(found_file.c_str() + start_pos, "%d", &old_salt); +			} +			llinfos << "Default vfs data file not present, found " << old_vfs_data_file << llendl; +			llinfos << "Old salt: " << old_salt << llendl; +		} +	} + +	snprintf(old_vfs_index_file, LL_MAX_PATH, "%s%u",		// Flawfinder: ignore +			gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_INDEX_FILE_BASE).c_str(), +			old_salt); + +	stat_result = LLFile::stat(old_vfs_index_file, &s); +	if (stat_result) +	{ +		// We've got a bad/missing index file, nukem! +		llwarns << "Bad or missing vfx index file " << old_vfs_index_file << llendl; +		llwarns << "Removing old vfs data file " << old_vfs_data_file << llendl; +		LLFile::remove(old_vfs_data_file); +		LLFile::remove(old_vfs_index_file); +		 +		// Just in case, nuke any other old cache files in the directory. +		std::string dir; +		dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""); + +		std::string mask; +		mask = gDirUtilp->getDirDelimiter(); +		mask += VFS_DATA_FILE_BASE; +		mask += "*"; + +		gDirUtilp->deleteFilesInDir(dir, mask); + +		mask = gDirUtilp->getDirDelimiter(); +		mask += VFS_INDEX_FILE_BASE; +		mask += "*"; + +		gDirUtilp->deleteFilesInDir(dir, mask); +	} + +	snprintf(new_vfs_data_file, LL_MAX_PATH, "%s%u",		// Flawfinder: ignore +		gDirUtilp->getExpandedFilename(LL_PATH_CACHE,VFS_DATA_FILE_BASE).c_str(), +		new_salt); + +	snprintf(new_vfs_index_file, LL_MAX_PATH, "%s%u", gDirUtilp->getExpandedFilename(LL_PATH_CACHE, VFS_INDEX_FILE_BASE).c_str(),		// Flawfinder: ignore +		new_salt); + + +	strncpy(static_vfs_data_file, gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"static_data.db2").c_str(), LL_MAX_PATH -1);		// Flawfinder: ignore +	static_vfs_data_file[LL_MAX_PATH -1] = '\0'; +	strncpy(static_vfs_index_file, gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"static_index.db2").c_str(), LL_MAX_PATH -1);		// Flawfinder: ignore +	static_vfs_index_file[LL_MAX_PATH -1] = '\0'; + +	if (resize_vfs) +	{ +		llinfos << "Removing old vfs and re-sizing" << llendl; +		 +		LLFile::remove(old_vfs_data_file); +		LLFile::remove(old_vfs_index_file); +	} +	else if (old_salt != new_salt) +	{ +		// move the vfs files to a new name before opening +		llinfos << "Renaming " << old_vfs_data_file << " to " << new_vfs_data_file << llendl; +		llinfos << "Renaming " << old_vfs_index_file << " to " << new_vfs_index_file << llendl; +		LLFile::rename(old_vfs_data_file, new_vfs_data_file); +		LLFile::rename(old_vfs_index_file, new_vfs_index_file); +	} + +	// Startup the VFS... +	gSavedSettings.setU32("VFSSalt", new_salt); + +	// Don't remove VFS after viewer crashes.  If user has corrupt data, they can reinstall. JC +	gVFS = new LLVFS(new_vfs_index_file, new_vfs_data_file, false, vfs_size_u32, false); +	if( VFSVALID_BAD_CORRUPT == gVFS->getValidState() ) +	{ +		// Try again with fresh files  +		// (The constructor deletes corrupt files when it finds them.) +		llwarns << "VFS corrupt, deleted.  Making new VFS." << llendl; +		delete gVFS; +		gVFS = new LLVFS(new_vfs_index_file, new_vfs_data_file, false, vfs_size_u32, false); +	} + +	gStaticVFS = new LLVFS(static_vfs_index_file, static_vfs_data_file, true, 0, false); + +	BOOL success = gVFS->isValid() && gStaticVFS->isValid(); +	if( !success ) +	{ +		return false; +	} +	else +	{ +		LLVFile::initClass(); +		return true; +	} +} + +void LLAppViewer::purgeCache() +{ +	llinfos << "Purging Texture Cache..." << llendl; +	LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE); +	llinfos << "Purging Cache..." << llendl; +	std::string mask = gDirUtilp->getDirDelimiter() + "*.*"; +	gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"").c_str(),mask); +} + +const LLString& LLAppViewer::getSecondLifeTitle() const +{ +	return gSecondLife; +} + +const LLString& LLAppViewer::getWindowTitle() const  +{ +	return gWindowTitle; +} + +void LLAppViewer::resetURIs() const +{ +    // Clear URIs when picking a new server +	gLoginURIs.clear(); +	gHelperURI.clear(); +} + +const std::vector<std::string>& LLAppViewer::getLoginURIs() const +{ +	if (gLoginURIs.empty()) +	{ +		// not specified on the command line, use value from table +		gLoginURIs = LLSRV::rewriteURI(gGridInfo[gGridChoice].mLoginURI); +	} +	return gLoginURIs; +} + +const std::string& LLAppViewer::getHelperURI() const +{ +	if (gHelperURI.empty()) +	{ +		// not specified on the command line, use value from table +		gHelperURI = gGridInfo[gGridChoice].mHelperURI; +	} +	return gHelperURI; +} + +void LLAppViewer::addLoginURI(const std::string& uri) +{ +    gLoginURIs.push_back(uri); +} + +void LLAppViewer::setHelperURI(const std::string& uri) +{ +    gHelperURI = uri; +} + +// Callback from a dialog indicating user was logged out.   +void finish_disconnect(S32 option, void* userdata) +{ +	if (1 == option) +	{ +        LLAppViewer::instance()->forceQuit(); +	} +} + +// Callback from an early disconnect dialog, force an exit +void finish_forced_disconnect(S32 /* option */, void* /* userdata */) +{ +	LLAppViewer::instance()->forceQuit(); +} + + +void LLAppViewer::forceDisconnect(const LLString& mesg) +{ +	if (gDoDisconnect) +    { +		// Already popped up one of these dialogs, don't +		// do this again. +		return; +    } +	 +	// Translate the message if possible +	LLString big_reason = LLAgent::sTeleportErrorMessages[mesg]; +	if ( big_reason.size() == 0 ) +	{ +		big_reason = mesg; +	} + +	LLStringBase<char>::format_map_t args; +	gDoDisconnect = TRUE; + +	if (LLStartUp::getStartupState() < STATE_STARTED) +	{ +		// Tell users what happened +		args["[ERROR_MESSAGE]"] = big_reason; +		gViewerWindow->alertXml("ErrorMessage", args, finish_forced_disconnect); +	} +	else +	{ +		args["[MESSAGE]"] = big_reason; +		gViewerWindow->alertXml("YouHaveBeenLoggedOut", args, finish_disconnect ); +	} +} + +void LLAppViewer::badNetworkHandler() +{ +	// Dump the packet +	gMessageSystem->dumpPacketToLog(); + +	// Flush all of our caches on exit in the case of disconnect due to +	// invalid packets. + +	mPurgeOnExit = TRUE; + +#if LL_WINDOWS +	// Generates the minidump. +	LLWinDebug::handleException(NULL); +#endif +	LLAppViewer::handleViewerCrash(); + +	std::ostringstream message; +	message << +		"The viewer has detected mangled network data indicative\n" +		"of a bad upstream network connection or an incomplete\n" +		"local installation of " << LLAppViewer::instance()->getSecondLifeTitle() << ". \n" +		" \n" +		"Try uninstalling and reinstalling to see if this resolves \n" +		"the issue. \n" +		" \n" +		"If the problem continues, see the Tech Support FAQ at: \n" +		"www.secondlife.com/support"; +	forceDisconnect(message.str()); +} + +// This routine may get called more than once during the shutdown process. +// This can happen because we need to get the screenshot before the window +// is destroyed. +void LLAppViewer::saveFinalSnapshot() +{ +	if (!mSavedFinalSnapshot && !gNoRender) +	{ +		gSavedSettings.setVector3d("FocusPosOnLogout", gAgent.calcFocusPositionTargetGlobal()); +		gSavedSettings.setVector3d("CameraPosOnLogout", gAgent.calcCameraPositionTargetGlobal()); +		gViewerWindow->setCursor(UI_CURSOR_WAIT); +		gAgent.changeCameraToThirdPerson( FALSE );	// don't animate, need immediate switch +		gSavedSettings.setBOOL("ShowParcelOwners", FALSE); +		idle(); + +		LLString snap_filename = gDirUtilp->getLindenUserDir(); +		snap_filename += gDirUtilp->getDirDelimiter(); +		snap_filename += SCREEN_LAST_FILENAME; +		gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidth(), gViewerWindow->getWindowHeight(), FALSE, TRUE); +		mSavedFinalSnapshot = TRUE; +	} +} + +void LLAppViewer::loadNameCache() +{ +	if (!gCacheName) return; + +	std::string name_cache; +	name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache"); +	FILE* name_cache_fp = LLFile::fopen(name_cache.c_str(), "r");		// Flawfinder: ignore +	if (name_cache_fp) +	{ +		gCacheName->importFile(name_cache_fp); +		fclose(name_cache_fp); +	} +} + +void LLAppViewer::saveNameCache() +{ +	if (!gCacheName) return; + +	std::string name_cache; +	name_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "name.cache"); +	FILE* name_cache_fp = LLFile::fopen(name_cache.c_str(), "w");		// Flawfinder: ignore +	if (name_cache_fp) +	{ +		gCacheName->exportFile(name_cache_fp); +		fclose(name_cache_fp); +	} +} + +/////////////////////////////////////////////////////// +// idle() +// +// Called every time the window is not doing anything. +// Receive packets, update statistics, and schedule a redisplay. +/////////////////////////////////////////////////////// +void LLAppViewer::idle() +{ +	// Update frame timers +	static LLTimer idle_timer; + +	LLControlBase::updateAllListeners(); + +	LLFrameTimer::updateFrameTime(); +	LLEventTimer::updateClass(); +	LLCriticalDamp::updateInterpolants(); +	LLMortician::updateClass(); +	F32 dt_raw = idle_timer.getElapsedTimeAndResetF32(); + +	// Cap out-of-control frame times +	// Too low because in menus, swapping, debugger, etc. +	// Too high because idle called with no objects in view, etc. +	const F32 MIN_FRAME_RATE = 1.f; +	const F32 MAX_FRAME_RATE = 200.f; + +	F32 frame_rate_clamped = 1.f / dt_raw; +	frame_rate_clamped = llclamp(frame_rate_clamped, MIN_FRAME_RATE, MAX_FRAME_RATE); +	gFrameDTClamped = 1.f / frame_rate_clamped; + +	// Global frame timer +	// Smoothly weight toward current frame +	gFPSClamped = (frame_rate_clamped + (4.f * gFPSClamped)) / 5.f; + +	if (gQuitAfterSeconds > 0.f) +	{ +		if (gRenderStartTime.getElapsedTimeF32() > gQuitAfterSeconds) +		{ +			LLAppViewer::instance()->forceQuit(); +		} +	} + +	// Must wait until both have avatar object and mute list, so poll +	// here. +	request_initial_instant_messages(); + +	/////////////////////////////////// +	// +	// Special case idle if still starting up +	// + +	if (LLStartUp::getStartupState() < STATE_STARTED) +	{ +		// Skip rest if idle startup returns false (essentially, no world yet) +		if (!idle_startup()) +		{ +			return; +		} +	} + +	 +    F32 yaw = 0.f;				// radians + +	if (!gDisconnected) +	{ +		LLFastTimer t(LLFastTimer::FTM_NETWORK); +		 +	    // Update spaceserver timeinfo +	    gWorldp->setSpaceTimeUSec(gWorldp->getSpaceTimeUSec() + (U32)(dt_raw * SEC_TO_MICROSEC)); +     +     +	    ////////////////////////////////////// +	    // +	    // Update simulator agent state +	    // + +		if (gRotateRight) +		{ +			gAgent.moveYaw(-1.f); +		} + +	    // Handle automatic walking towards points +	    gAgentPilot.updateTarget(); +	    gAgent.autoPilot(&yaw); +     +	    static LLFrameTimer agent_update_timer; +	    static U32 				last_control_flags; +     +	    //	When appropriate, update agent location to the simulator. +	    F32 agent_update_time = agent_update_timer.getElapsedTimeF32(); +	    BOOL flags_changed = gAgent.controlFlagsDirty() || (last_control_flags != gAgent.getControlFlags()); +     +	    if (flags_changed || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND))) +	    { +		    // Send avatar and camera info +		    last_control_flags = gAgent.getControlFlags(); +		    send_agent_update(TRUE); +		    agent_update_timer.reset(); +	    } +	} + +	////////////////////////////////////// +	// +	// Manage statistics +	// +	// + +	{ +		static LLFrameTimer	viewer_stats_timer; +		reset_statistics(); + +		// Update session stats every large chunk of time +		// *FIX: (???) SAMANTHA +		if (viewer_stats_timer.getElapsedTimeF32() >= 300.f && !gDisconnected) +		{ +			llinfos << "Transmitting sessions stats" << llendl; +			send_stats(); +			viewer_stats_timer.reset(); +		} + +		// Print the object debugging stats +		static LLFrameTimer object_debug_timer; +		if (object_debug_timer.getElapsedTimeF32() > 5.f) +		{ +			object_debug_timer.reset(); +			if (gObjectList.mNumDeadObjectUpdates) +			{ +				llinfos << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << llendl; +				gObjectList.mNumDeadObjectUpdates = 0; +			} +			if (gObjectList.mNumUnknownKills) +			{ +				llinfos << "Kills on unknown objects: " << gObjectList.mNumUnknownKills << llendl; +				gObjectList.mNumUnknownKills = 0; +			} +			if (gObjectList.mNumUnknownUpdates) +			{ +				llinfos << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << llendl; +				gObjectList.mNumUnknownUpdates = 0; +			} +		} +		gFrameStats.addFrameData(); +	} +	 +	if (!gDisconnected) +	{ +		LLFastTimer t(LLFastTimer::FTM_NETWORK); +	 +	    //////////////////////////////////////////////// +	    // +	    // Network processing +	    // +	    // NOTE: Starting at this point, we may still have pointers to "dead" objects +	    // floating throughout the various object lists. +	    // +     +	    gFrameStats.start(LLFrameStats::IDLE_NETWORK); +		idleNetwork(); +	    stop_glerror(); +	         +	    gFrameStats.start(LLFrameStats::AGENT_MISC); + +		// Check for away from keyboard, kick idle agents. +		idle_afk_check(); + +		//  Update statistics for this frame +		update_statistics(gFrameCount); + +		gViewerWindow->updateDebugText(); +	} + +	//////////////////////////////////////// +	// +	// Handle the regular UI idle callbacks as well as +	// hover callbacks +	// + +	{ +// 		LLFastTimer t(LLFastTimer::FTM_IDLE_CB); + +		// Do event notifications if necessary.  Yes, we may want to move this elsewhere. +		gEventNotifier.update(); +		 +		gIdleCallbacks.callFunctions(); +	} +	 +	if (gDisconnected) +    { +		return; +    } + +	gViewerWindow->handlePerFrameHover(); + +	/////////////////////////////////////// +	// Agent and camera movement +	// +		LLCoordGL current_mouse = gViewerWindow->getCurrentMouse(); + +// 		BOOL was_in_prelude = gAgent.inPrelude(); + +	{ +		//LLFastTimer t(LLFastTimer::FTM_TEMP1); +		 +		// After agent and camera moved, figure out if we need to +		// deselect objects. +		gSelectMgr->deselectAllIfTooFar(); + +	} + +	{ +		LLFastTimer t(LLFastTimer::FTM_RESET_DRAWORDER); +			 +		////////////////////////////////////////////// +		// +		// Clear draw orders +		// +		// Should actually be done after render, but handlePerFrameHover actually does a "render" +		// to do its selection. +		// + +		gPipeline.resetDrawOrders(); +	} +	{ +		// Handle pending gesture processing +		gGestureManager.update(); + +		gAgent.updateAgentPosition(gFrameDTClamped, yaw, current_mouse.mX, current_mouse.mY); +	} + +	{ +		LLFastTimer t(LLFastTimer::FTM_OBJECTLIST_UPDATE); // Actually "object update" +		gFrameStats.start(LLFrameStats::OBJECT_UPDATE); +		 +        if (!(logoutRequestSent() && hasSavedFinalSnapshot())) +		{ +			gObjectList.update(gAgent, *gWorldp); +		} +	} +	 +	{ +		LLFastTimer t(LLFastTimer::FTM_UPDATE_SKY);	 +		gSky.updateSky(); +	} + +	////////////////////////////////////// +	// +	// Deletes objects... +	// Has to be done after doing idleUpdates (which can kill objects) +	// + +	{ +		LLFastTimer t(LLFastTimer::FTM_CLEANUP); +		gFrameStats.start(LLFrameStats::CLEAN_DEAD); +		gObjectList.cleanDeadObjects(); +		LLDrawable::cleanupDeadDrawables(); +	} +	 +	// +	// After this point, in theory we should never see a dead object +	// in the various object/drawable lists. +	// + +	////////////////////////////////////// +	// +	// Update/send HUD effects +	// +	// At this point, HUD effects may clean up some references to +	// dead objects. +	// + +	{ +		//LLFastTimer t(LLFastTimer::FTM_TEMP3); +		 +		gFrameStats.start(LLFrameStats::UPDATE_EFFECTS); +		gSelectMgr->updateEffects(); +		gHUDManager->cleanupEffects(); +		gHUDManager->sendEffects(); +	} + +	stop_glerror(); + +	//////////////////////////////////////// +	// +	// Unpack layer data that we've received +	// + +	{ +		LLFastTimer t(LLFastTimer::FTM_NETWORK); +		gVLManager.unpackData(); +	} +	 +	///////////////////////// +	// +	// Update surfaces, and surface textures as well. +	// + +	gWorldp->updateVisibilities(); +	{ +		const F32 max_region_update_time = .001f; // 1ms +		LLFastTimer t(LLFastTimer::FTM_REGION_UPDATE); +		gWorldp->updateRegions(max_region_update_time); +	} +	 +	///////////////////////// +	// +	// Update weather effects +	// + +	if (!gNoRender) +	{ +		gWorldp->updateClouds(gFrameDTClamped); +		gSky.propagateHeavenlyBodies(gFrameDTClamped);				// moves sun, moon, and planets + +		// Update wind vector  +		LLVector3 wind_position_region; +		static LLVector3 average_wind; + +		LLViewerRegion *regionp; +		regionp = gWorldp->resolveRegionGlobal(wind_position_region, gAgent.getPositionGlobal());	// puts agent's local coords into wind_position	 +		if (regionp) +		{ +			gWindVec = regionp->mWind.getVelocity(wind_position_region); + +			// Compute average wind and use to drive motion of water +			 +			average_wind = regionp->mWind.getAverage(); +			F32 cloud_density = regionp->mCloudLayer.getDensityRegion(wind_position_region); +			 +			gSky.setCloudDensityAtAgent(cloud_density); +			gSky.setWind(average_wind); +			//LLVOWater::setWind(average_wind); +		} +		else +		{ +			gWindVec.setVec(0.0f, 0.0f, 0.0f); +		} +	} +	stop_glerror(); +	 +	////////////////////////////////////// +	// +	// Update images, using the image stats generated during object update/culling +	// +	// Can put objects onto the retextured list. +	// +	gFrameStats.start(LLFrameStats::IMAGE_UPDATE); + +	LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE); +	 +	LLViewerImage::updateClass(gCamera->getVelocityStat()->getMean(), +								gCamera->getAngularVelocityStat()->getMean()); + +	gBumpImageList.updateImages();  // must be called before gImageList version so that it's textures are thrown out first. + +	const F32 max_image_decode_time = 0.005f; // 5 ms decode time +	gImageList.updateImages(max_image_decode_time); +	stop_glerror(); + +	////////////////////////////////////// +	// +	// Sort and cull in the new renderer are moved to pipeline.cpp +	// Here, particles are updated and drawables are moved. +	// +	 +	if (!gNoRender) +	{ +		gFrameStats.start(LLFrameStats::UPDATE_MOVE); +		gPipeline.updateMove(); + +		gFrameStats.start(LLFrameStats::UPDATE_PARTICLES); +		gWorldp->updateParticles(); +	} +	stop_glerror(); + +	if (!LLViewerJoystick::sOverrideCamera) +	{ +		gAgent.updateCamera(); +	} +	else +	{ +		LLViewerJoystick::updateCamera(); +	} + +	// objects and camera should be in sync, do LOD calculations now +	{ +		LLFastTimer t(LLFastTimer::FTM_LOD_UPDATE); +		gObjectList.updateApparentAngles(gAgent); +	} + +	{ +		gFrameStats.start(LLFrameStats::AUDIO); +		LLFastTimer t(LLFastTimer::FTM_AUDIO_UPDATE); +		 +		if (gAudiop) +		{ +		    audio_update_volume(false); +			audio_update_listener(); +			audio_update_wind(false); + +			// this line actually commits the changes we've made to source positions, etc. +			const F32 max_audio_decode_time = 0.002f; // 2 ms decode time +			gAudiop->idle(max_audio_decode_time); +		} +	} +	 +	// Handle shutdown process, for example,  +	// wait for floaters to close, send quit message, +	// forcibly quit if it has taken too long +	if (mQuitRequested) +	{ +		idleShutdown(); +	} + +	stop_glerror(); +} + +void LLAppViewer::idleShutdown() +{ +	// Wait for all modal alerts to get resolved +	if (LLModalDialog::activeCount() > 0) +	{ +		return; +	} + +	// close IM interface +	if(gIMMgr) +	{ +		gIMMgr->disconnectAllSessions(); +	} +	 +	// Wait for all floaters to get resolved +	if (gFloaterView +		&& !gFloaterView->allChildrenClosed()) +	{ +		return; +	} + +	static bool saved_snapshot = false; +	if (!saved_snapshot) +	{ +		saved_snapshot = true; +		saveFinalSnapshot(); +		return; +	} + +	const F32 SHUTDOWN_UPLOAD_SAVE_TIME = 5.f; + +	S32 pending_uploads = gAssetStorage->getNumPendingUploads(); +	if (pending_uploads > 0 +		&& gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME +		&& !logoutRequestSent()) +	{ +		static S32 total_uploads = 0; +		// Sometimes total upload count can change during logout. +		total_uploads = llmax(total_uploads, pending_uploads); +		gViewerWindow->setShowProgress(TRUE); +		S32 finished_uploads = total_uploads - pending_uploads; +		F32 percent = 100.f * finished_uploads / total_uploads; +		gViewerWindow->setProgressPercent(percent); +		char buffer[MAX_STRING];		// Flawfinder: ignore +		snprintf(buffer, MAX_STRING, "Saving final data...");		// Flawfinder: ignore +		gViewerWindow->setProgressString(buffer); +		return; +	} + +	// All floaters are closed.  Tell server we want to quit. +	if( !logoutRequestSent() ) +	{ +		sendLogoutRequest(); + +		// Wait for a LogoutReply message +		gViewerWindow->setShowProgress(TRUE); +		gViewerWindow->setProgressPercent(100.f); +		gViewerWindow->setProgressString("Logging out..."); +		return; +	} + +	// Make sure that we quit if we haven't received a reply from the server. +	if( logoutRequestSent()  +		&& gLogoutTimer.getElapsedTimeF32() > gLogoutMaxTime ) +	{ +		forceQuit(); +		return; +	} +} + +void LLAppViewer::sendLogoutRequest() +{ +	if(!mLogoutRequestSent) +	{ +		LLMessageSystem* msg = gMessageSystem; +		msg->newMessageFast(_PREHASH_LogoutRequest); +		msg->nextBlockFast(_PREHASH_AgentData); +		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); +		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +		gAgent.sendReliableMessage(); + +		gLogoutTimer.reset(); +		gLogoutMaxTime = LOGOUT_REQUEST_TIME; +		mLogoutRequestSent = TRUE; +		 +		gVoiceClient->leaveChannel(); +	} +} + +// +// Handle messages, and all message related stuff +// + +#define TIME_THROTTLE_MESSAGES + +#ifdef TIME_THROTTLE_MESSAGES +#define CHECK_MESSAGES_DEFAULT_MAX_TIME .020f // 50 ms = 50 fps (just for messages!) +static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; +#endif + +void LLAppViewer::idleNetwork() +{ +	gObjectList.mNumNewObjects = 0; +	S32 total_decoded = 0; + +	if (!gSavedSettings.getBOOL("SpeedTest")) +	{ +		LLFastTimer t(LLFastTimer::FTM_IDLE_NETWORK); // decode +		 +		// deal with any queued name requests and replies. +		gCacheName->processPending(); + +		LLTimer check_message_timer; +		//  Read all available packets from network  +		stop_glerror(); +		const S64 frame_count = gFrameCount;  // U32->S64 +		F32 total_time = 0.0f; +   		while (gMessageSystem->checkAllMessages(frame_count, gServicePump))  +		{ +			if (gDoDisconnect) +			{ +				// We're disconnecting, don't process any more messages from the server +				// We're usually disconnecting due to either network corruption or a +				// server going down, so this is OK. +				break; +			} +			stop_glerror(); + +			total_decoded++; +			gPacketsIn++; + +			if (total_decoded > MESSAGE_MAX_PER_FRAME) +			{ +				break; +			} + +#ifdef TIME_THROTTLE_MESSAGES +			// Prevent slow packets from completely destroying the frame rate. +			// This usually happens due to clumps of avatars taking huge amount +			// of network processing time (which needs to be fixed, but this is +			// a good limit anyway). +			total_time = check_message_timer.getElapsedTimeF32(); +			if (total_time >= CheckMessagesMaxTime) +				break; +#endif +		} +		// Handle per-frame message system processing. +		gMessageSystem->processAcks(); + +#ifdef TIME_THROTTLE_MESSAGES +		if (total_time >= CheckMessagesMaxTime) +		{ +			// Increase CheckMessagesMaxTime so that we will eventually catch up +			CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames +		} +		else +		{ +			// Reset CheckMessagesMaxTime to default value +			CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME; +		} +#endif +		 + + +		// we want to clear the control after sending out all necessary agent updates +		gAgent.resetControlFlags(); +		stop_glerror(); + +		 +		// Decode enqueued messages... +		S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded; + +		if( remaining_possible_decodes <= 0 ) +		{ +			llinfos << "Maxed out number of messages per frame at " << MESSAGE_MAX_PER_FRAME << llendl; +		} + +		if (gPrintMessagesThisFrame) +		{ +			llinfos << "Decoded " << total_decoded << " msgs this frame!" << llendl; +			gPrintMessagesThisFrame = FALSE; +		} +	} + +	gObjectList.mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects); + +	// Retransmit unacknowledged packets. +	gXferManager->retransmitUnackedPackets(); +	gAssetStorage->checkForTimeouts(); + +	gViewerThrottle.updateDynamicThrottle(); +} + +void LLAppViewer::disconnectViewer() +{ +	if (gDisconnected) +	{ +		return; +	} +	// +	// Cleanup after quitting. +	//	 +	// Save snapshot for next time, if we made it through initialization + +	llinfos << "Disconnecting viewer!" << llendl; + +	// Dump our frame statistics +	gFrameStats.dump(); + +	// Remember if we were flying +	gSavedSettings.setBOOL("FlyingAtExit", gAgent.getFlying() ); + +	// Un-minimize all windows so they don't get saved minimized +	if (!gNoRender) +	{ +		if (gFloaterView) +		{ +			gFloaterView->restoreAll(); +		} +	} + +	if (gSelectMgr) +	{ +		gSelectMgr->deselectAll(); +	} + +	if (!gNoRender) +	{ +		// save inventory if appropriate +		gInventory.cache(gAgent.getInventoryRootID(), gAgent.getID()); +		if(gInventoryLibraryRoot.notNull() && gInventoryLibraryOwner.notNull()) +		{ +			gInventory.cache(gInventoryLibraryRoot, gInventoryLibraryOwner); +		} +	} + +	saveNameCache(); + +	// close inventory interface, close all windows +	LLInventoryView::cleanup(); + +	// Also writes cached agent settings to gSavedSettings +	gAgent.cleanup(); + +	gObjectList.destroy(); +	delete gWorldp; +	gWorldp = NULL; + +	cleanup_xfer_manager(); +	gDisconnected = TRUE; +} + +void LLAppViewer::forceErrorLLError() +{ +   	llerrs << "This is an llerror" << llendl; +} + +void LLAppViewer::forceErrorBreakpoint() +{ +#ifdef LL_WINDOWS +    DebugBreak(); +#endif +    return; +} + +void LLAppViewer::forceErrorBadMemoryAccess() +{ +    S32* crash = NULL; +    *crash = 0xDEADBEEF; +    return; +} + +void LLAppViewer::forceErrorInifiniteLoop() +{ +    while(true) +    { +        ; +    } +    return; +} +  +void LLAppViewer::forceErrorSoftwareException() +{ +    // *FIX: Any way to insure it won't be handled? +    throw;  +} diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h new file mode 100644 index 0000000000..227a27a8ac --- /dev/null +++ b/indra/newview/llappviewer.h @@ -0,0 +1,298 @@ +/**  + * @file llappviewer.h + * @brief The LLAppViewer class declaration + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_LLAPPVIEWER_H +#define LL_LLAPPVIEWER_H + +class LLTextureCache; +class LLWorkerThread; +class LLTextureFetch; + +class LLAppViewer : public LLApp +{ +public: +	LLAppViewer(); +	virtual ~LLAppViewer(); + +	// *NOTE:Mani - Don't use this! +	// Having  +	static LLAppViewer* instance() {return sInstance; }  + +	// +	// Main application logic +	// +	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. + +	// Application control +	void forceQuit(); // Puts the viewer into 'shutting down without error' mode. +	void requestQuit(); // Request a quit. A kinder, gentler quit. +	void userQuit(); // The users asks to quit. Confirm, then requestQuit() +    void earlyExit(const LLString& msg); // Display an error dialog and forcibly quit. +    void forceExit(S32 arg); // exit() immediately (after some cleanup). +    void abortQuit();  // Called to abort a quit request. + +    bool quitRequested() { return mQuitRequested; } +    bool logoutRequestSent() { return mLogoutRequestSent; } + +	// *FIX: This is meant to stay only until the command line issues are hashed out with repect to LLApp::parseCommandLine +	// This version stores the argc and argv for later usage, make sure the params passed in last as long as this class. +	bool tempStoreCommandOptions(int argc, char** argv); + +	// write string to "debug_info.log", used for crash reporting. +	void writeDebug(const char *str);  +	void writeDebug(const std::string& str) { writeDebug(str.c_str()); }; +	void closeDebug(); + +	const LLOSInfo& getOSInfo() const { return mSysOSInfo; } + +	// Report true if under the control of a debugger. A null-op default. +	virtual bool beingDebugged() { return false; }  + +	S32 getCrashBehavior() const { return mCrashBehavior; }  +	void setCrashBehavior(S32 cb); +	virtual void handleCrashReporting() = 0; // What to do with crash report? +	static void handleViewerCrash(); // Hey! The viewer crashed. Do this. + +	// Thread accessors +	static LLTextureCache* getTextureCache() { return sTextureCache; } +	static LLWorkerThread* getImageDecodeThread() { return sImageDecodeThread; } +	static LLTextureFetch* getTextureFetch() { return sTextureFetch; } + +	const std::string& getSerialNumber() { return mSerialNumber; } +	 +	// *FIX:Mani purgeCache was made public for parse_args(). +	// If that beast is gone, make it private. +	void purgeCache(); // Clear the local cache.  +	bool getPurgeCache() const { return mPurgeCache; } +	 +	const LLString& getSecondLifeTitle() const; // The Second Life title. +	const LLString& getWindowTitle() const; // The window display name. + +    // Helpers for URIs +    void addLoginURI(const std::string& uri); +    void setHelperURI(const std::string& uri); +    const std::vector<std::string>& getLoginURIs() const; +    const std::string& getHelperURI() const; +    void resetURIs() const; + +    void forceDisconnect(const LLString& msg); // Force disconnection, with a message to the user. +    void badNetworkHandler(); // Cause a crash state due to bad network packet. + +	bool hasSavedFinalSnapshot() { return mSavedFinalSnapshot; } +	void saveFinalSnapshot();  + +    void loadNameCache(); +    void saveNameCache(); + +    // LLAppViewer testing helpers. +    // *NOTE: These will potentially crash the viewer. Only for debugging. +    virtual void forceErrorLLError(); +    virtual void forceErrorBreakpoint(); +    virtual void forceErrorBadMemoryAccess(); +    virtual void forceErrorInifiniteLoop(); +    virtual void forceErrorSoftwareException(); + +protected: +	virtual bool initWindow(); // Initialize the viewer's window. +	virtual bool initLogging(); // Initialize log files, logging system, return false on failure. +	virtual bool initHardwareTest() { return true; } // A false result indicates the app should quit. +	 +	virtual std::string generateSerialNumber() = 0; // Platforms specific classes generate this. + + +private: + +	bool initEarlyConfiguration(); // Initialize setting needed by crash reporting. +	bool initThreads(); // Initialize viewer threads, return false on failure. +	bool initConfiguration(); // Initialize settings from the command line/config file. + +	bool initCache(); // Initialize local client cache. + +	bool doConfigFromCommandLine(); // calls parse args. + +	void cleanupSavedSettings(); // Sets some config data to current or default values during cleanup. +	void removeCacheFiles(const char *filemask); // Deletes cached files the match the given wildcard. + +	void writeSystemInfo(); // Write system info to "debug_info.log" + +	bool anotherInstanceRunning();  +	void initMarkerFile();  +	void removeMarkerFile(); +     +    void idle();  +    void idleShutdown(); +    void idleNetwork(); + +    void sendLogoutRequest(); +    void disconnectViewer(); + +	// *FIX: the app viewer class should be some sort of singleton, no? +	// Perhaps its child class is the singleton and this should be an abstract base. +	static LLAppViewer* sInstance;  + +    bool mSecondInstance; // Is this a second instance of the app? + +	FILE *mMarkerFile; // A file created to indicate the app is running. +	bool mLastExecFroze; // Set on init if the marker file was found. + +	FILE* mDebugFile; // output stream written to via writeDebug() + +	LLOSInfo mSysOSInfo;  +	S32 mCrashBehavior; +	bool mReportedCrash; + +	// Thread objects. +	static LLTextureCache* sTextureCache;  +	static LLWorkerThread* sImageDecodeThread;  +	static LLTextureFetch* sTextureFetch;  + +	S32 mNumSessions; + +	std::string mSerialNumber; +	bool mPurgeCache; +    bool mPurgeOnExit; + +	bool mSavedFinalSnapshot; + +    bool mQuitRequested;				// User wants to quit, may have modified documents open. +    bool mLogoutRequestSent;			// Disconnect message sent to simulator, no longer safe to send messages to the sim. +}; + +// consts from viewer.h +const S32 AGENT_UPDATES_PER_SECOND  = 10; + +// Globals with external linkage. From viewer.h +// *NOTE:Mani - These will be removed as the Viewer App Cleanup project continues. +// +// "// llstartup" indicates that llstartup is the only client for this global. + +extern bool gVerifySSLCert; // parse_args setting used by llxmlrpctransaction.cpp +extern BOOL gHandleKeysAsync; // gSavedSettings used by llviewerdisplay.cpp & llviewermenu.cpp +extern BOOL gProbeHardware; +extern LLString gDisabledMessage; // llstartup +extern BOOL gHideLinks; // used by llpanellogin, lllfloaterbuycurrency, llstartup +extern BOOL gInProductionGrid;  + +extern BOOL	gAllowIdleAFK; +extern F32 gAFKTimeout; +extern BOOL	gShowObjectUpdates; + +extern BOOL gLogMessages; // llstartup  +extern std::string gChannelName; +extern BOOL gUseAudio; // llstartup + +extern LLString gCmdLineFirstName; // llstartup +extern LLString gCmdLineLastName; +extern LLString gCmdLinePassword; + +extern BOOL gAutoLogin; // llstartup +extern const char* DEFAULT_SETTINGS_FILE; // llstartup + +extern BOOL gRequestInventoryLibrary; // llstartup +extern BOOL gGodConnect; // llstartup + +extern BOOL gAcceptTOS; +extern BOOL gAcceptCriticalMessage; + +extern LLUUID	gViewerDigest;  // MD5 digest of the viewer's executable file. +extern BOOL gLastExecFroze; // llstartup + +extern U32 gFrameCount; +extern U32 gForegroundFrameCount; + +extern LLPumpIO* gServicePump; + +// Is the Pacific time zone (aka server time zone) +// currently in daylight savings time? +extern BOOL gPacificDaylightTime; + +extern U64      gFrameTime;					// The timestamp of the most-recently-processed frame +extern F32		gFrameTimeSeconds;			// Loses msec precision after ~4.5 hours... +extern F32		gFrameIntervalSeconds;		// Elapsed time between current and previous gFrameTimeSeconds +extern F32		gFPSClamped;						// Frames per second, smoothed, weighted toward last frame +extern F32		gFrameDTClamped; +extern U64		gStartTime; + +extern LLTimer gRenderStartTime; +extern LLFrameTimer gForegroundTime; + +extern F32 gLogoutMaxTime; +extern LLTimer gLogoutTimer; + +extern F32 gSimLastTime;  +extern F32 gSimFrames; + +extern LLUUID gInventoryLibraryOwner; +extern LLUUID gInventoryLibraryRoot; + +extern BOOL		gDisconnected; +extern BOOL		gDisableVoice; + +// Map scale in pixels per region +extern F32 gMapScale; +extern F32 gMiniMapScale; + +extern LLFrameTimer	gRestoreGLTimer; +extern BOOL			gRestoreGL; +extern BOOL		gUseWireframe; + +extern F32 gMouseSensitivity; +extern BOOL gInvertMouse; + +// VFS globals - gVFS is for general use +// gStaticVFS is read-only and is shipped w/ the viewer +// it has pre-cache data like the UI .TGAs +extern LLVFS	*gStaticVFS; + +extern LLMemoryInfo gSysMemory; + +extern bool gPreloadImages; +extern bool gPreloadSounds; + +extern LLString gLastVersionChannel; + +extern LLVector3 gWindVec; +extern LLVector3 gRelativeWindVec; +extern U32	gPacketsIn; +extern BOOL gPrintMessagesThisFrame; + +extern LLUUID gSunTextureID; +extern LLUUID gMoonTextureID; + +extern BOOL gUseConsole;  + +extern BOOL gRandomizeFramerate; +extern BOOL gPeriodicSlowFrame; + +extern BOOL gQAMode; +#endif // LL_LLAPPVIEWER_H diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp new file mode 100644 index 0000000000..1993fd0a76 --- /dev/null +++ b/indra/newview/llappviewerlinux.cpp @@ -0,0 +1,414 @@ +/** + * @file llappviewerlinux.cpp + * @brief The LLAppViewerWin32 class definitions + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */  + +#include "llviewerprecompiledheaders.h" + +#include "llmemtype.h" +#include "llappviewerlinux.h" + +#include "llviewernetwork.h" +#include "llmd5.h" + +  #if LL_LINUX +  #	include <dlfcn.h>		// RTLD_LAZY +  #     include <execinfo.h>            // backtrace - glibc only +  #     ifndef LL_ELFBIN +  #define LL_ELFBIN 1 +  #     endif // LL_ELFBIN +  #     if LL_ELFBIN +  #          include <cxxabi.h>         // for symbol demangling +  #          include "ELFIO.h"          // for better backtraces +  #     endif // LL_ELFBIN +  #elif LL_SOLARIS +  #     include <sys/types.h> +  #     include <unistd.h> +  #     include <fcntl.h> +  #     include <ucontext.h> +  #endif + +int main( int argc, char **argv )  +{ +	LLMemType mt1(LLMemType::MTYPE_STARTUP); + +#if LL_SOLARIS && defined(__sparc) +	asm ("ta\t6");		 // NOTE:  Make sure memory alignment is enforced on SPARC +#endif + +	LLAppViewer* viewer_app_ptr = new LLAppViewerLinux(); + +	viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); + +	bool ok = viewer_app_ptr->tempStoreCommandOptions(argc, argv); +	if(!ok) +	{ +		llwarns << "Unable to parse command line." << llendl; +		return -1; +	} + +	ok = viewer_app_ptr->init(); +	if(!ok) +	{ +		llwarns << "Application init failed." << llendl; +		return -1; +	} + +		// Run the application main loop +	if(!LLApp::isQuitting())  +	{ +		viewer_app_ptr->mainLoop(); +	} + +	if (!LLApp::isError()) +	{ +		// +		// We don't want to do cleanup here if the error handler got called - +		// the assumption is that the error handler is responsible for doing +		// app cleanup if there was a problem. +		// +		viewer_app_ptr->cleanup(); +	} +	delete viewer_app_ptr; +	viewer_app_ptr = NULL; +	return 0; +} + +#ifdef LL_SOLARIS +static inline BOOL do_basic_glibc_backtrace() +{ +	BOOL success = FALSE; + +	std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); +	llinfos << "Opening stack trace file " << strace_filename << llendl; +	FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w"); +	if (!StraceFile) +	{ +		llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl; +		StraceFile = stderr; +	} + +	printstack(fileno(StraceFile)); + +	if (StraceFile != stderr) +		fclose(StraceFile); + +	return success; +} +#else +#define MAX_STACK_TRACE_DEPTH 40 +// This uses glibc's basic built-in stack-trace functions for a not very +// amazing backtrace. +static inline BOOL do_basic_glibc_backtrace() +{ +	void *array[MAX_STACK_TRACE_DEPTH]; +	size_t size; +	char **strings; +	size_t i; +	BOOL success = FALSE; + +	size = backtrace(array, MAX_STACK_TRACE_DEPTH); +	strings = backtrace_symbols(array, size); + +	std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); +	llinfos << "Opening stack trace file " << strace_filename << llendl; +	FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w");		// Flawfinder: ignore +        if (!StraceFile) +	{ +		llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl; +		StraceFile = stderr; +	} + +	if (size) +	{ +		for (i = 0; i < size; i++) +			fputs((std::string(strings[i])+"\n").c_str(), +			      StraceFile); + +		success = TRUE; +	} +	 +	if (StraceFile != stderr) +		fclose(StraceFile); + +	free (strings); +	return success; +} + +#if LL_ELFBIN +// This uses glibc's basic built-in stack-trace functions together with +// ELFIO's ability to parse the .symtab ELF section for better symbol +// extraction without exporting symbols (which'd cause subtle, fatal bugs). +static inline BOOL do_elfio_glibc_backtrace() +{ +	void *array[MAX_STACK_TRACE_DEPTH]; +	size_t btsize; +	char **strings; +	BOOL success = FALSE; + +	std::string appfilename = gDirUtilp->getExecutablePathAndName(); + +	std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); +	llinfos << "Opening stack trace file " << strace_filename << llendl; +	FILE* StraceFile = LLFile::fopen(strace_filename.c_str(), "w");		// Flawfinder: ignore +        if (!StraceFile) +	{ +		llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl; +		StraceFile = stderr; +	} + +	// get backtrace address list and basic symbol info +	btsize = backtrace(array, MAX_STACK_TRACE_DEPTH); +	strings = backtrace_symbols(array, btsize); + +	// create ELF reader for our app binary +	IELFI* pReader; +	const IELFISection* pSec = NULL; +	IELFISymbolTable* pSymTbl = 0; +	if (ERR_ELFIO_NO_ERROR != ELFIO::GetInstance()->CreateELFI(&pReader) || +	    ERR_ELFIO_NO_ERROR != pReader->Load(appfilename.c_str()) || +	    // find symbol table, create reader-object +	    NULL == (pSec = pReader->GetSection( ".symtab" )) || +	    ERR_ELFIO_NO_ERROR != pReader->CreateSectionReader(IELFI::ELFI_SYMBOL, pSec, (void**)&pSymTbl) ) +	{ +		// Failed to open our binary and read its symbol table somehow +		llinfos << "Could not initialize ELF symbol reading - doing basic backtrace." << llendl; +		if (StraceFile != stderr) +			fclose(StraceFile); +		// note that we may be leaking some of the above ELFIO +		// objects now, but it's expected that we'll be dead soon +		// and we want to tread delicately until we get *some* kind +		// of useful backtrace. +		return do_basic_glibc_backtrace(); +	} + +	// iterate over trace and symtab, looking for plausible symbols +	std::string   name; +	Elf32_Addr    value; +	Elf32_Word    ssize; +	unsigned char bind; +	unsigned char type; +	Elf32_Half    section; +	int nSymNo = pSymTbl->GetSymbolNum(); +	size_t btpos; +	for (btpos = 0; btpos < btsize; ++btpos) +	{ +		fprintf(StraceFile, "%d:\t", btpos); +		int symidx; +		for (symidx = 0; symidx < nSymNo; ++symidx) +		{ +			if (ERR_ELFIO_NO_ERROR == +			    pSymTbl->GetSymbol(symidx, name, value, ssize, +					       bind, type, section)) +			{ +				// check if trace address within symbol range +				if (uintptr_t(array[btpos]) >= value && +				    uintptr_t(array[btpos]) < value+ssize) +				{ +					char *demangled_str = NULL; +					int demangle_result = 1; +					demangled_str = +						abi::__cxa_demangle +						(name.c_str(), NULL, NULL, +						 &demangle_result); +					if (0 == demangle_result && +					    NULL != demangled_str) { +						fprintf(StraceFile, +							"ELF(%s", demangled_str); +						free(demangled_str); +					} +					else // failed demangle; print it raw +					{ +						fprintf(StraceFile, +							"ELF(%s", name.c_str()); +					} +					// print offset from symbol start +					fprintf(StraceFile, +						"+0x%lx) [%p]\n", +						uintptr_t(array[btpos]) - +						value, +						array[btpos]); +					goto got_sym; // early escape +				} +			} +		} +		// Fallback: +		// Didn't find a suitable symbol in the binary - it's probably +		// a symbol in a DSO; use glibc's idea of what it should be. +		fprintf(StraceFile, "%s\n", strings[btpos]); +	got_sym:; +	} +	 +	if (StraceFile != stderr) +		fclose(StraceFile); + +	pSymTbl->Release(); +	pSec->Release(); +	pReader->Release(); + +	free(strings); + +	llinfos << "Finished generating stack trace." << llendl; + +	success = TRUE; +	return success; +} +#endif // LL_ELFBIN + +#endif // LL_SOLARIS + + +LLAppViewerLinux::LLAppViewerLinux() +{ +} + +LLAppViewerLinux::~LLAppViewerLinux() +{ +} + +bool LLAppViewerLinux::init() +{ +	return LLAppViewer::init(); +} + +void LLAppViewerLinux::handleCrashReporting() +{ + +	// Always generate the report, have the logger do the asking, and +	// don't wait for the logger before exiting (-> total cleanup). +	if (CRASH_BEHAVIOR_NEVER_SEND != LLAppViewer::instance()->getCrashBehavior()) +	{	 +		// This backtrace writes into stack_trace.log +#  if LL_ELFBIN +		do_elfio_glibc_backtrace(); // more useful backtrace +#  else +		do_basic_glibc_backtrace(); // only slightly useful backtrace +#  endif // LL_ELFBIN +		// launch the actual crash logger +		char* ask_dialog = "-dialog"; +		if (CRASH_BEHAVIOR_ASK != LLAppViewer::instance()->getCrashBehavior()) +			ask_dialog = ""; // omit '-dialog' option +		std::string cmd =gDirUtilp->getAppRODataDir(); +		cmd += gDirUtilp->getDirDelimiter(); +		cmd += "linux-crash-logger.bin"; +		char* const cmdargv[] = +			{(char*)cmd.c_str(), +			 ask_dialog, +			 (char*)"-user", +			 (char*)gGridName, +			 (char*)"-name", +			 (char*)LLAppViewer::instance()->getSecondLifeTitle().c_str(), +			 NULL}; +		pid_t pid = fork(); +		if (pid == 0) +		{ // child +			execv(cmd.c_str(), cmdargv);		/* Flawfinder: ignore */ +			llwarns << "execv failure when trying to start " << cmd << llendl; +			_exit(1); // avoid atexit() +		}  +		else +		{ +			if (pid > 0) +			{ +				// DO NOT wait for child proc to die; we want +				// the logger to outlive us while we quit to +				// free up the screen/keyboard/etc. +				////int childExitStatus; +				////waitpid(pid, &childExitStatus, 0); +			}  +			else +			{ +				llwarns << "fork failure." << llendl; +			} +		} +	} +	// Sometimes signals don't seem to quit the viewer.   +	// Make sure we exit so as to not totally confuse the user. +	exit(1); +} + +bool LLAppViewerLinux::beingDebugged() +{ +	static enum {unknown, no, yes} debugged = unknown; +	 +	if (debugged == unknown) +	{ +		pid_t ppid = getppid(); +		char *name; +		int ret; + +		ret = asprintf(&name, "/proc/%d/exe", ppid); +		if (ret != -1) +		{ +			char buf[1024]; +			ssize_t n; +			 +			n = readlink(name, buf, sizeof(buf) - 1); +			if (n != -1) +			{ +				char *base = strrchr(buf, '/'); +				buf[n + 1] = '\0'; +				if (base == NULL) +				{ +					base = buf; +				} else { +					base += 1; +				} +				 +				if (strcmp(base, "gdb") == 0) +				{ +					debugged = yes; +				} +			} +			free(name); +		} +	} + +	return debugged == yes; +} + +bool LLAppViewerLinux::initLogging() +{ +	// Remove the last stack trace, if any +	std::string old_stack_file = +		gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); +	LLFile::remove(old_stack_file.c_str()); + +	return LLAppViewer::initLogging(); +} + +std::string LLAppViewerLinux::generateSerialNumber() +{ +	char serial_md5[MD5HEX_STR_SIZE]; +	serial_md5[0] = 0; + +	// TODO + +	return serial_md5; +} diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h new file mode 100644 index 0000000000..f38a64a8cd --- /dev/null +++ b/indra/newview/llappviewerlinux.h @@ -0,0 +1,59 @@ +/** + * @file llappviewerlinux.h + * @brief The LLAppViewerLinux class declaration + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */  + +#ifndef LL_LLAPPVIEWERLINUX_H +#define LL_LLAPPVIEWERLINUX_H + +#ifndef LL_LLAPPVIEWER_H +#include "llappviewer.h" +#endif + +class LLAppViewerLinux : public LLAppViewer +{ +public: +	LLAppViewerLinux(); +	virtual ~LLAppViewerLinux(); + +	// +	// Main application logic +	// +	virtual bool init();			// Override to do application initialization +	std::string generateSerialNumber(); + +protected: +	virtual bool beingDebugged(); + +	virtual void handleCrashReporting(); + +	virtual bool initLogging(); +}; + +#endif // LL_LLAPPVIEWERLINUX_H diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp new file mode 100644 index 0000000000..63e7a6b129 --- /dev/null +++ b/indra/newview/llappviewermacosx.cpp @@ -0,0 +1,388 @@ +/** + * @file llappviewermacosx.cpp + * @brief The LLAppViewerWin32 class definitions + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */  + +#include "llviewerprecompiledheaders.h" + +#if !defined LL_DARWIN +	#error "Use only with Mac OS X" +#endif + +#include "llappviewermacosx.h" +#include "llmemtype.h" + +#include "llviewernetwork.h" +#include "llmd5.h" +#include "llurlsimstring.h" +#include "llfloaterworldmap.h" +#include <Carbon/Carbon.h> + + +int main( int argc, char **argv )  +{ +	LLMemType mt1(LLMemType::MTYPE_STARTUP); + +#if LL_SOLARIS && defined(__sparc) +	asm ("ta\t6");		 // NOTE:  Make sure memory alignment is enforced on SPARC +#endif + +	// Set the working dir to <bundle>/Contents/Resources +	(void) chdir(gDirUtilp->getAppRODataDir().c_str()); + +	LLAppViewerMacOSX* viewer_app_ptr = new LLAppViewerMacOSX(); + +	viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); + +	bool ok = viewer_app_ptr->tempStoreCommandOptions(argc, argv); +	if(!ok) +	{ +		llwarns << "Unable to parse command line." << llendl; +		return -1; +	} + +	ok = viewer_app_ptr->init(); +	if(!ok) +	{ +		llwarns << "Application init failed." << llendl; +		return -1; +	} + +		// Run the application main loop +	if(!LLApp::isQuitting())  +	{ +		viewer_app_ptr->mainLoop(); +	} + +	if (!LLApp::isError()) +	{ +		// +		// We don't want to do cleanup here if the error handler got called - +		// the assumption is that the error handler is responsible for doing +		// app cleanup if there was a problem. +		// +		viewer_app_ptr->cleanup(); +	} +	delete viewer_app_ptr; +	viewer_app_ptr = NULL; +	return 0; +} + +LLAppViewerMacOSX::LLAppViewerMacOSX() +{ +} + +LLAppViewerMacOSX::~LLAppViewerMacOSX() +{ +} + +bool LLAppViewerMacOSX::init() +{ +	return LLAppViewer::init(); +} + +void LLAppViewerMacOSX::handleCrashReporting() +{ +	// Macintosh +	LLString command_str; +	command_str = "crashreporter.app/Contents/MacOS/crashreporter "; +	command_str += "-user "; +	command_str += gGridName; +	command_str += " &";	// This backgrounds the command so system() doesn't block until the crashreporter exits. +	system(command_str.c_str());		/* Flawfinder: ignore */ +		 +	// Sometimes signals don't seem to quit the viewer.   +	// Make sure we exit so as to not totally confuse the user. +	exit(1); +} + +std::string LLAppViewerMacOSX::generateSerialNumber() +{ +	char serial_md5[MD5HEX_STR_SIZE];		// Flawfinder: ignore +	serial_md5[0] = 0; + +	// JC: Sample code from http://developer.apple.com/technotes/tn/tn1103.html +	CFStringRef serialNumber = NULL; +	io_service_t    platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, +																 IOServiceMatching("IOPlatformExpertDevice")); +	if (platformExpert) { +		serialNumber = (CFStringRef) IORegistryEntryCreateCFProperty(platformExpert, +																	 CFSTR(kIOPlatformSerialNumberKey), +																	 kCFAllocatorDefault, 0);		 +		IOObjectRelease(platformExpert); +	} +	 +	if (serialNumber) +	{ +		char buffer[MAX_STRING];		// Flawfinder: ignore +		if (CFStringGetCString(serialNumber, buffer, MAX_STRING, kCFStringEncodingASCII)) +		{ +			LLMD5 md5( (unsigned char*)buffer ); +			md5.hex_digest(serial_md5); +		} +		CFRelease(serialNumber); +	} + +	return serial_md5; +} + +OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) +{ +	OSErr result = noErr; +	DescType actualType; +	char buffer[1024];		// Flawfinder: ignore +	Size size; +	 +	result = AEGetParamPtr ( +		messagein, +		keyDirectObject, +		typeCString, +		&actualType, +		(Ptr)buffer, +		sizeof(buffer), +		&size);	 +	 +	if(result == noErr) +	{ +		// Got the URL out of the event. +		// secondlife:// + +		// Parse it and stash in globals. +		LLURLSimString::setString(buffer); +		 +		if(gFloaterWorldMap != NULL) +		{ +			// If the viewer's already logged in, pass it along directly. +			if (LLURLSimString::parse()) +			{ +				gFloaterWorldMap->trackURL(LLURLSimString::sInstance.mSimName, +										   LLURLSimString::sInstance.mX, +										   LLURLSimString::sInstance.mY, +										   LLURLSimString::sInstance.mZ); +				LLFloaterWorldMap::show(NULL, TRUE); +			} +		} +	} +	 +	return(result); +} + +OSErr AEQuitHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn) +{ +	OSErr result = noErr; +	 +	LLAppViewer::instance()->userQuit(); +	 +	return(result); +} + +OSStatus simpleDialogHandler(EventHandlerCallRef handler, EventRef event, void *userdata) +{ +	OSStatus result = eventNotHandledErr; +	OSStatus err; +	UInt32 evtClass = GetEventClass(event); +	UInt32 evtKind = GetEventKind(event); +	WindowRef window = (WindowRef)userdata; +	 +	if((evtClass == kEventClassCommand) && (evtKind == kEventCommandProcess)) +	{ +		HICommand cmd; +		err = GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL, sizeof(cmd), NULL, &cmd); +		 +		if(err == noErr) +		{ +			switch(cmd.commandID) +			{ +				case kHICommandOK: +					QuitAppModalLoopForWindow(window); +					result = noErr; +				break; +				 +				case kHICommandCancel: +					QuitAppModalLoopForWindow(window); +					result = userCanceledErr; +				break; +			} +		} +	} +	 +	return(result); +} + +OSStatus DisplayReleaseNotes(void) +{ +	OSStatus err; +	IBNibRef nib = NULL; +	WindowRef window = NULL; +	 +	err = CreateNibReference(CFSTR("SecondLife"), &nib); +	 +	if(err == noErr) +	{ +		CreateWindowFromNib(nib, CFSTR("Release Notes"), &window); +	} +		 +	if(err == noErr) +	{ +		// Get the text view control +		HIViewRef textView; +		ControlID id; + +		id.signature = 'text'; +		id.id = 0; + +		LLString releaseNotesText; +		 +		_read_file_into_string(releaseNotesText, "releasenotes.txt");		// Flawfinder: ignore + +		err = HIViewFindByID(HIViewGetRoot(window), id, &textView); +		 +		if(err == noErr) +		{ +			// Convert from the encoding used in the release notes. +			CFStringRef str = CFStringCreateWithBytes( +				NULL,  +				(const UInt8*)releaseNotesText.c_str(),  +				releaseNotesText.size(),  +				kCFStringEncodingWindowsLatin1, 		// This matches the way the Windows version displays the release notes. +				FALSE); +			 +			if(str != NULL) +			{ +				int size = CFStringGetLength(str); + +				if(size > 0) +				{ +					UniChar *chars = new UniChar[size + 1]; +					CFStringGetCharacters(str, CFRangeMake(0, size), chars); +				 +					err = TXNSetData(HITextViewGetTXNObject(textView), kTXNUnicodeTextData, chars, size * sizeof(UniChar), kTXNStartOffset, kTXNStartOffset); +					 +					delete[] chars; +				} +				 +				CFRelease(str); +			} +			else +			{ +				// Creating the string failed.  Probably an encoding problem.  Display SOMETHING... +				err = TXNSetData(HITextViewGetTXNObject(textView), kTXNTextData, releaseNotesText.c_str(), releaseNotesText.size(), kTXNStartOffset, kTXNStartOffset); +			} +		} +		 +		// Set the selection to the beginning of the text and scroll it into view. +		if(err == noErr) +		{ +			err = TXNSetSelection(HITextViewGetTXNObject(textView), kTXNStartOffset, kTXNStartOffset); +		} +		 +		if(err == noErr) +		{ +			// This function returns void. +			TXNShowSelection(HITextViewGetTXNObject(textView), false); +		} +	} + +	if(err == noErr) +	{ +		ShowWindow(window); +	} + +	if(err == noErr) +	{ +		// Set up an event handler for the window. +		EventHandlerRef handler = NULL; +		EventTypeSpec handlerEvents[] =  +		{ +			{ kEventClassCommand, kEventCommandProcess } +		}; + +		InstallWindowEventHandler( +				window,  +				NewEventHandlerUPP(simpleDialogHandler),  +				GetEventTypeCount (handlerEvents),  +				handlerEvents,  +				(void*)window,  +				&handler); +	} +			 +	if(err == noErr) +	{ +		RunAppModalLoopForWindow(window); +	} +			 +	if(window != NULL) +	{ +		DisposeWindow(window); +	} +	 +	if(nib != NULL) +	{ +		DisposeNibReference(nib); +	} + +	return(err); +} + +void init_apple_menu(const char* product) +{ +	// Load up a proper menu bar. +	{ +		OSStatus err; +		IBNibRef nib = NULL; +		// NOTE: DO NOT translate or brand this string.  It's an internal name in the .nib file, and MUST match exactly. +		err = CreateNibReference(CFSTR("SecondLife"), &nib); +		 +		if(err == noErr) +		{ +			// NOTE: DO NOT translate or brand this string.  It's an internal name in the .nib file, and MUST match exactly. +			SetMenuBarFromNib(nib, CFSTR("MenuBar")); +		} + +		if(nib != NULL) +		{ +			DisposeNibReference(nib); +		} +	} +	 +	// Install a handler for 'gurl' AppleEvents.  This is how secondlife:// URLs get passed to the viewer. +	 +	if(AEInstallEventHandler('GURL', 'GURL', NewAEEventHandlerUPP(AEGURLHandler),0, false) != noErr) +	{ +		// Couldn't install AppleEvent handler.  This error shouldn't be fatal. +		llinfos << "Couldn't install 'GURL' AppleEvent handler.  Continuing..." << llendl; +	} + +	// Install a handler for 'quit' AppleEvents.  This makes quitting the application from the dock work. +	if(AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP(AEQuitHandler),0, false) != noErr) +	{ +		// Couldn't install AppleEvent handler.  This error shouldn't be fatal. +		llinfos << "Couldn't install Quit AppleEvent handler.  Continuing..." << llendl; +	} +} diff --git a/indra/newview/llappviewermacosx.h b/indra/newview/llappviewermacosx.h new file mode 100644 index 0000000000..2c61e5a01c --- /dev/null +++ b/indra/newview/llappviewermacosx.h @@ -0,0 +1,56 @@ +/** + * @file llappviewermacosx.h + * @brief The LLAppViewerMacOSX class declaration + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */  + +#ifndef LL_LLAPPVIEWERMACOSX_H +#define LL_LLAPPVIEWERMACOSX_H + +#ifndef LL_LLAPPVIEWER_H +#include "llappviewer.h" +#endif + +class LLAppViewerMacOSX : public LLAppViewer +{ +public: +	LLAppViewerMacOSX(); +	virtual ~LLAppViewerMacOSX(); + +	// +	// Main application logic +	// +	virtual bool init();			// Override to do application initialization + + +protected: +	virtual void handleCrashReporting();  +	std::string generateSerialNumber(); +}; + +#endif // LL_LLAPPVIEWERMACOSX_H diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp new file mode 100644 index 0000000000..1d7a6690fc --- /dev/null +++ b/indra/newview/llappviewerwin32.cpp @@ -0,0 +1,454 @@ +/** + * @file llappviewerwin32.cpp + * @brief The LLAppViewerWin32 class definitions + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */  + +#include "llviewerprecompiledheaders.h" + +#include "llappviewerwin32.h" + +#include "llmemtype.h" + +#include "llwindowwin32.cpp" // *FIX: for setting gIconResource. +#include "res/resource.h" // *FIX: for setting gIconResource. + +#include <fcntl.h>		//_O_APPEND +#include <io.h>			//_open_osfhandle() +#include <errorrep.h>	// for AddERExcludedApplicationA() +#include <process.h>	// _spawnl() +#include <tchar.h>		// For TCHAR support + +#include "llviewercontrol.h" +#include "lldxhardware.h" + +#include "llweb.h" +#include "llsecondlifeurls.h" + +#include "llwindebug.h" + +#include "llviewernetwork.h" +#include "llmd5.h" + +void fill_args(int& argc, char** argv, const S32 max_args, LPSTR cmd_line) +{ +	char *token = NULL; +	if( cmd_line[0] == '\"' ) +	{ +		// Exe name is enclosed in quotes +		token = strtok( cmd_line, "\"" ); +		argv[argc++] = token; +		token = strtok( NULL, " \t," ); +	} +	else +	{ +		// Exe name is not enclosed in quotes +		token = strtok( cmd_line, " \t," ); +	} + +	while( (token != NULL) && (argc < max_args) ) +	{ +		argv[argc++] = token; +		/* Get next token: */ +		if (*(token + strlen(token) + 1) == '\"')		/* Flawfinder: ignore*/ +		{ +			token = strtok( NULL, "\""); +		} +		else +		{ +			token = strtok( NULL, " \t," ); +		} +	} +} + +// *NOTE:Mani - this code is stolen from LLApp, where its never actually used. +LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop) +{ +	// Translate the signals/exceptions into cross-platform stuff +	// Windows implementation +	llinfos << "Entering Windows Exception Handler..." << llendl; + +	// Make sure the user sees something to indicate that the app crashed. +	LONG retval; + +	if (LLApp::isError()) +	{ +		llwarns << "Got another fatal signal while in the error handler, die now!" << llendl; +		retval = EXCEPTION_EXECUTE_HANDLER; +		return retval; +	} + +	// Generate a minidump if we can. +	// Before we wake the error thread... +	// Which will start the crash reporting. +	LLWinDebug::handleException(exception_infop); +	 +	// Flag status to error, so thread_error starts its work +	LLApp::setError(); + +	// Block in the exception handler until the app has stopped +	// This is pretty sketchy, but appears to work just fine +	while (!LLApp::isStopped()) +	{ +		ms_sleep(10); +	} + +	// +	// At this point, we always want to exit the app.  There's no graceful +	// recovery for an unhandled exception. +	//  +	// Just kill the process. +	retval = EXCEPTION_EXECUTE_HANDLER;	 +	return retval; +} + +int APIENTRY WinMain(HINSTANCE hInstance, +                     HINSTANCE hPrevInstance, +                     LPSTR     lpCmdLine, +                     int       nCmdShow) +{ +	LLMemType mt1(LLMemType::MTYPE_STARTUP); +	 +	// *FIX: global +	gIconResource = MAKEINTRESOURCE(IDI_LL_ICON); + +	// In Win32, we need to generate argc and argv ourselves... +	// Note: GetCommandLine() returns a  potentially return a LPTSTR +	// which can resolve to a LPWSTR (unicode string). +	// (That's why it's different from lpCmdLine which is a LPSTR.) +	// We don't currently do unicode, so call the non-unicode version +	// directly. +	LPSTR cmd_line_including_exe_name = GetCommandLineA(); + +	const S32	MAX_ARGS = 100; +	int argc = 0; +	char* argv[MAX_ARGS];		/* Flawfinder: ignore */ + +	fill_args(argc, argv, MAX_ARGS, cmd_line_including_exe_name); + +	LLAppViewerWin32* viewer_app_ptr = new LLAppViewerWin32(); + +	// *FIX:Mani This method is poorly named, since the exception +	// is now handled by LLApp.  +	bool ok = LLWinDebug::setupExceptionHandler();  +	 +	// Actually here's the exception setup. +	LPTOP_LEVEL_EXCEPTION_FILTER prev_filter; +	prev_filter = SetUnhandledExceptionFilter(viewer_windows_exception_handler); +	if (!prev_filter) +	{ +		llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with NULL!" << llendl; +		ok = FALSE; +	} +	if (prev_filter != LLWinDebug::handleException) +	{ +		llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with " << prev_filter << "!" << llendl; +		ok = FALSE; +	} + +	viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); + +	ok = viewer_app_ptr->tempStoreCommandOptions(argc, argv); +	if(!ok) +	{ +		llwarns << "Unable to parse command line." << llendl; +		return -1; +	} + +	ok = viewer_app_ptr->init(); +	if(!ok) +	{ +		llwarns << "Application init failed." << llendl; +		return -1; +	} + +		// Run the application main loop +	if(!LLApp::isQuitting())  +	{ +		viewer_app_ptr->mainLoop(); +	} + +	if (!LLApp::isError()) +	{ +		// +		// We don't want to do cleanup here if the error handler got called - +		// the assumption is that the error handler is responsible for doing +		// app cleanup if there was a problem. +		// +		viewer_app_ptr->cleanup(); +	} +	delete viewer_app_ptr; +	viewer_app_ptr = NULL; +	return 0; +} + +void LLAppViewerWin32::disableWinErrorReporting() +{ +	const char win_xp_string[] = "Microsoft Windows XP"; +	BOOL is_win_xp = ( getOSInfo().getOSString().substr(0, strlen(win_xp_string) ) == win_xp_string );		/* Flawfinder: ignore*/ +	if( is_win_xp ) +	{ +		// Note: we need to use run-time dynamic linking, because load-time dynamic linking will fail +		// on systems that don't have the library installed (all non-Windows XP systems) +		HINSTANCE fault_rep_dll_handle = LoadLibrary(L"faultrep.dll");		/* Flawfinder: ignore */ +		if( fault_rep_dll_handle ) +		{ +			pfn_ADDEREXCLUDEDAPPLICATIONA pAddERExcludedApplicationA  = (pfn_ADDEREXCLUDEDAPPLICATIONA) GetProcAddress(fault_rep_dll_handle, "AddERExcludedApplicationA"); +			if( pAddERExcludedApplicationA ) +			{ + +				// Strip the path off the name +				const char* executable_name = gDirUtilp->getExecutableFilename().c_str(); + +				if( 0 == pAddERExcludedApplicationA( executable_name ) ) +				{ +					U32 error_code = GetLastError(); +					llinfos << "AddERExcludedApplication() failed with error code " << error_code << llendl; +				} +				else +				{ +					llinfos << "AddERExcludedApplication() success for " << executable_name << llendl; +				} +			} +			FreeLibrary( fault_rep_dll_handle ); +		} +	} +} + +const S32 MAX_CONSOLE_LINES = 500; + +void create_console() +{ +	int h_con_handle; +	long l_std_handle; + +	CONSOLE_SCREEN_BUFFER_INFO coninfo; +	FILE *fp; + +	// allocate a console for this app +	AllocConsole(); + +	// set the screen buffer to be big enough to let us scroll text +	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); +	coninfo.dwSize.Y = MAX_CONSOLE_LINES; +	SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize); + +	// redirect unbuffered STDOUT to the console +	l_std_handle = (long)GetStdHandle(STD_OUTPUT_HANDLE); +	h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); +	fp = _fdopen( h_con_handle, "w" ); +	*stdout = *fp; +	setvbuf( stdout, NULL, _IONBF, 0 ); + +	// redirect unbuffered STDIN to the console +	l_std_handle = (long)GetStdHandle(STD_INPUT_HANDLE); +	h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); +	fp = _fdopen( h_con_handle, "r" ); +	*stdin = *fp; +	setvbuf( stdin, NULL, _IONBF, 0 ); + +	// redirect unbuffered STDERR to the console +	l_std_handle = (long)GetStdHandle(STD_ERROR_HANDLE); +	h_con_handle = _open_osfhandle(l_std_handle, _O_TEXT); +	fp = _fdopen( h_con_handle, "w" ); +	*stderr = *fp; +	setvbuf( stderr, NULL, _IONBF, 0 ); +} + +LLAppViewerWin32::LLAppViewerWin32() +{ +} + +LLAppViewerWin32::~LLAppViewerWin32() +{ +} + +bool LLAppViewerWin32::init() +{ +	// Platform specific initialization. +	 +	// Turn off Windows XP Error Reporting +	// (Don't send our data to Microsoft--at least until we are Logo approved and have a way +	// of getting the data back from them.) +	// +	llinfos << "Turning off Windows error reporting." << llendl; +	disableWinErrorReporting(); + +	return LLAppViewer::init(); +} + +bool LLAppViewerWin32::cleanup() +{ +	bool result = LLAppViewer::cleanup(); + +	gDXHardware.cleanup(); + +	return result; +} + +bool LLAppViewerWin32::initWindow() +{ +	// pop up debug console if necessary +	if (gUseConsole && gSavedSettings.getBOOL("ShowConsoleWindow")) +	{ +		create_console(); +	} + +	return LLAppViewer::initWindow(); +} + +void write_debug_callback(const char* str) +{ +	LLAppViewer::instance()->writeDebug(str); +} + +bool LLAppViewerWin32::initHardwareTest() +{ +	// +	// Do driver verification and initialization based on DirectX +	// hardware polling and driver versions +	// +	if (gProbeHardware) +	{ +		BOOL vram_only = !gSavedSettings.getBOOL("ProbeHardwareOnStartup"); + +		LLSplashScreen::update("Detecting hardware..."); + +		llinfos << "Attempting to poll DirectX for hardware info" << llendl; +		gDXHardware.setWriteDebugFunc(write_debug_callback); +		BOOL probe_ok = gDXHardware.getInfo(vram_only); + +		if (!probe_ok +			&& gSavedSettings.getWarning("AboutDirectX9")) +		{ +			llinfos << "DirectX probe failed, alerting user." << llendl; + +			// Warn them that runnin without DirectX 9 will +			// not allow us to tell them about driver issues +			std::ostringstream msg; +			msg <<  +				LLAppViewer::instance()->getSecondLifeTitle() << " is unable to detect DirectX 9.0b or greater.\n" +				"\n" << +				LLAppViewer::instance()->getSecondLifeTitle() << " uses DirectX to detect hardware and/or\n" +				"outdated drivers that can cause stability problems,\n" +				"poor performance and crashes.  While you can run\n" << +				LLAppViewer::instance()->getSecondLifeTitle() << " without it, we highly recommend running\n" +				"with DirectX 9.0b\n" +				"\n" +				"Do you wish to continue?\n"; +			S32 button = OSMessageBox( +				msg.str().c_str(), +				"Warning", +				OSMB_YESNO); +			if (OSBTN_NO== button) +			{ +				llinfos << "User quitting after failed DirectX 9 detection" << llendl; +				LLWeb::loadURLExternal(DIRECTX_9_URL); +				return false; +			} +			gSavedSettings.setWarning("AboutDirectX9", FALSE); +		} +		llinfos << "Done polling DirectX for hardware info" << llendl; + +		// Only probe once after installation +		gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE); + +		// Disable so debugger can work +		std::ostringstream splash_msg; +		splash_msg << "Loading " << LLAppViewer::instance()->getSecondLifeTitle() << "..."; + +		LLSplashScreen::update(splash_msg.str().c_str()); +	} + +	if (!LLWinDebug::setupExceptionHandler()) +	{ +		llwarns << " Someone took over my exception handler (post hardware probe)!" << llendl; +	} + +	gGLManager.mVRAM = gDXHardware.getVRAM(); +	llinfos << "Detected VRAM: " << gGLManager.mVRAM << llendl; + +	return true; +} + +void LLAppViewerWin32::handleCrashReporting() +{ +	// Windows only behaivor. Spawn win crash reporter. +	std::string exe_path = gDirUtilp->getAppRODataDir(); +	exe_path += gDirUtilp->getDirDelimiter(); +	exe_path += "win_crash_logger.exe"; + +	std::string arg_string = "-user "; +	arg_string += gGridName; + +	switch(getCrashBehavior()) +	{ +	case CRASH_BEHAVIOR_ASK: +	default: +		arg_string += " -dialog "; +		_spawnl(_P_NOWAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL); +		break; + +	case CRASH_BEHAVIOR_ALWAYS_SEND: +		_spawnl(_P_NOWAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL); +		break; + +	case CRASH_BEHAVIOR_NEVER_SEND: +		break; +	} +} + +std::string LLAppViewerWin32::generateSerialNumber() +{ +	char serial_md5[MD5HEX_STR_SIZE];		// Flawfinder: ignore +	serial_md5[0] = 0; + +	DWORD serial = 0; +	DWORD flags = 0; +	BOOL success = GetVolumeInformation( +			L"C:\\", +			NULL,		// volume name buffer +			0,			// volume name buffer size +			&serial,	// volume serial +			NULL,		// max component length +			&flags,		// file system flags +			NULL,		// file system name buffer +			0);			// file system name buffer size +	if (success) +	{ +		LLMD5 md5; +		md5.update( (unsigned char*)&serial, sizeof(DWORD)); +		md5.finalize(); +		md5.hex_digest(serial_md5); +	} +	else +	{ +		llwarns << "GetVolumeInformation failed" << llendl; +	} +	return serial_md5; +}
\ No newline at end of file diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h new file mode 100644 index 0000000000..23e7337618 --- /dev/null +++ b/indra/newview/llappviewerwin32.h @@ -0,0 +1,63 @@ +/** + * @file llappviewerwin32.h + * @brief The LLAppViewerWin32 class declaration + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + *  + * Copyright (c) 2007, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */  + +#ifndef LL_LLAPPVIEWERWIN32_H +#define LL_LLAPPVIEWERWIN32_H + +#ifndef LL_LLAPPVIEWER_H +#include "llappviewer.h" +#endif + +class LLAppViewerWin32 : public LLAppViewer +{ +public: +	LLAppViewerWin32(); +	virtual ~LLAppViewerWin32(); + +	// +	// Main application logic +	// +	virtual bool init(); // Override to do application initialization +	virtual bool cleanup(); + +protected: +	virtual bool initWindow(); // Initialize the viewer's window. +	virtual bool initHardwareTest(); // Win32 uses DX9 to test hardware. +	virtual void handleCrashReporting();  + +	std::string generateSerialNumber(); + +private: +	void disableWinErrorReporting(); + +}; + +#endif // LL_LLAPPVIEWERWIN32_H diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index 866fa34038..c3c892a572 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -52,7 +52,6 @@  #include "llviewerobjectlist.h"  #include "llviewermenufile.h"  #include "llviewerwindow.h" -#include "viewer.h"  void dialog_refresh_all(); diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index b80c2bb5e3..6d0244e55e 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -466,7 +466,7 @@ void LLAvatarTracker::findAgent()  	msg->nextBlockFast(_PREHASH_AgentBlock);  	msg->addUUIDFast(_PREHASH_Hunter, gAgentID);  	msg->addUUIDFast(_PREHASH_Prey, mTrackingData->mAvatarID); -	msg->addU32Fast(_PREHASH_SpaceIP, 0); // will get filled in by userserver +	msg->addU32Fast(_PREHASH_SpaceIP, 0); // will get filled in by simulator  	msg->nextBlockFast(_PREHASH_LocationBlock);  	const F64 NO_LOCATION = 0.0;  	msg->addF64Fast(_PREHASH_GlobalX, NO_LOCATION); diff --git a/indra/newview/llclassifiedinfo.cpp b/indra/newview/llclassifiedinfo.cpp index a49af23426..28d5f506c9 100644 --- a/indra/newview/llclassifiedinfo.cpp +++ b/indra/newview/llclassifiedinfo.cpp @@ -32,7 +32,6 @@  #include "llviewerprecompiledheaders.h"  #include "llclassifiedinfo.h" -#include "viewer.h"	// for gPacificDaylightTime  #include "lluuid.h"  LLClassifiedInfo::cat_map LLClassifiedInfo::sCategories; diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp index 1e97df0b8b..eeb970e38b 100644 --- a/indra/newview/llcurrencyuimanager.cpp +++ b/indra/newview/llcurrencyuimanager.cpp @@ -44,8 +44,7 @@  #include "lllineeditor.h"  #include "llviewchildren.h"  #include "llxmlrpctransaction.h" -#include "viewer.h" - +#include "llappviewer.h"  const F64 CURRENCY_ESTIMATE_FREQUENCY = 2.0; @@ -239,7 +238,7 @@ void LLCurrencyUIManager::Impl::startTransaction(TransactionType type,  	static std::string transactionURI;  	if (transactionURI.empty())  	{ -		transactionURI = getHelperURI() + "currency.php"; +		transactionURI = LLAppViewer::instance()->getHelperURI() + "currency.php";  	}  	delete mTransaction; diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index a63c687633..367293929d 100644 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -32,7 +32,6 @@  #include "llviewerprecompiledheaders.h"  #include "lldirpicker.h" -//#include "viewer.h"  //#include "llviewermessage.h"  #include "llworld.h"  #include "llviewerwindow.h" diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index c10c49cd2c..52082ad5b5 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -48,6 +48,7 @@  #include "llstat.h"  #include "llviewerobject.h"  #include "llrect.h" +#include "llappviewer.h" // for gFrameTimeSeconds  class LLCamera;  class LLDrawPool; @@ -59,8 +60,6 @@ class LLSpatialPartition;  class LLVOVolume;  class LLViewerImage; -extern F32 gFrameTimeSeconds; -  // Can have multiple silhouettes for each object  const U32 SILHOUETTE_HIGHLIGHT = 0; diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 67a379d04d..9df9c11531 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -45,13 +45,13 @@  #include "noise.h"  #include "pipeline.h"  #include "llglslshader.h" +#include "llappviewer.h"  static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;  static U32 sBufferUsage = GL_STREAM_DRAW_ARB;  static U32 sShaderLevel = 0;  static LLGLSLShader* sVertexProgram = NULL; -extern F32 gFrameDTClamped;  extern BOOL gUseGLPick;  F32 CLOTHING_GRAVITY_EFFECT = 0.7f; diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 54a33f27a0..4a7760f15c 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -50,7 +50,6 @@  #include "llvowater.h"  #include "llworld.h"  #include "pipeline.h" -#include "viewer.h"			// gSunTextureID, gMoonTextureID  #include "llglslshader.h"  const LLUUID WATER_TEST("2bfd3884-7e27-69b9-ba3a-3e673f680004"); diff --git a/indra/newview/lleventinfo.cpp b/indra/newview/lleventinfo.cpp index 17b33f127c..0e69891731 100644 --- a/indra/newview/lleventinfo.cpp +++ b/indra/newview/lleventinfo.cpp @@ -32,7 +32,7 @@  #include "llviewerprecompiledheaders.h"  #include "lleventinfo.h" -#include "viewer.h"	// for gPacificDaylightTime +#include "llappviewer.h"	// for gPacificDaylightTime  #include "lluuid.h"  #include "message.h" diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 424f47e9e4..ee9177c18d 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -40,7 +40,7 @@  #include "llmath.h"  #include "llfontgl.h" -#include "viewer.h" +#include "llappviewer.h"  #include "llviewerimagelist.h"  #include "llui.h"  #include "llviewercontrol.h" diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 6b6eacdefa..1bcd1e1ab4 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -58,8 +58,6 @@  //  extern LLMemoryInfo gSysMemory;  extern LLCPUInfo gSysCPU; -extern void write_debug(const char *str); -extern void write_debug(const std::string& str);  #if LL_DARWIN  const char FEATURE_TABLE_FILENAME[] = "featuretable_mac.txt"; @@ -493,8 +491,6 @@ void LLFeatureManager::initGraphicsFeatureMasks()  	}  } -extern LLOSInfo gSysOS; -  void LLFeatureManager::applyRecommendedFeatures()  {  	// see featuretable.txt / featuretable_linux.txt / featuretable_mac.txt diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp index 0782586ef2..2772a13416 100644 --- a/indra/newview/llfirstuse.cpp +++ b/indra/newview/llfirstuse.cpp @@ -41,7 +41,7 @@  #include "llfloatervoicewizard.h"  #include "llviewercontrol.h"  #include "llui.h" -#include "viewer.h" +#include "llappviewer.h"  // static  std::set<LLString> LLFirstUse::sConfigVariables; diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 460b719094..01e529078f 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -47,7 +47,7 @@  #include "llversionviewer.h"  #include "llviewerbuild.h"  #include "llvieweruictrlfactory.h" -#include "viewer.h"	// for gViewerDigest +#include "llappviewer.h"   #if LL_LIBXUL_ENABLED  #include "llmozlib.h" @@ -57,7 +57,6 @@  extern LLCPUInfo gSysCPU;  extern LLMemoryInfo gSysMemory; -extern LLOSInfo gSysOS;  extern U32 gPacketsIn;  ///---------------------------------------------------------------------------- @@ -78,13 +77,13 @@ LLFloaterAbout::LLFloaterAbout()  	// Support for changing product name.  	LLString title("About "); -	title += gSecondLife; +	title += LLAppViewer::instance()->getSecondLifeTitle();  	setTitle(title);  	LLString support;  	// Version string -	LLString version = gSecondLife +	LLString version = LLAppViewer::instance()->getSecondLifeTitle()  		+ llformat(" %d.%d.%d (%d) %s %s (%s)",  				   LL_VERSION_MAJOR, LL_VERSION_MINOR, LL_VERSION_PATCH, LL_VIEWER_BUILD,  				   __DATE__, __TIME__, @@ -133,7 +132,7 @@ LLFloaterAbout::LLFloaterAbout()  	support.append(mem_text);  	support.append("OS Version: "); -	support.append( gSysOS.getOSString().c_str() ); +	support.append( LLAppViewer::instance()->getOSInfo().getOSString().c_str() );  	support.append("\n");  	support.append("Graphics Card Vendor: "); diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp index 71c221775e..693ffe091b 100644 --- a/indra/newview/llfloateranimpreview.cpp +++ b/indra/newview/llfloateranimpreview.cpp @@ -60,7 +60,6 @@  #include "llviewermenufile.h"	// upload_new_resource()  #include "llvoavatar.h"  #include "pipeline.h" -#include "viewer.h"  #include "llvieweruictrlfactory.h"  S32 LLFloaterAnimPreview::sUploadAmount = 10; diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp index bc00565a28..e044ead818 100644 --- a/indra/newview/llfloaterauction.cpp +++ b/indra/newview/llfloaterauction.cpp @@ -50,7 +50,8 @@  #include "llviewerregion.h"  #include "llvieweruictrlfactory.h"  #include "llviewerwindow.h" -#include "viewer.h" +#include "llviewerdisplay.h" +#include "llviewercontrol.h"  #include "llui.h"  ///---------------------------------------------------------------------------- diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 50f7387777..a2ea8c2794 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -42,7 +42,7 @@  #include "llscrolllistctrl.h"  #include "lltextbox.h"  #include "llvieweruictrlfactory.h" -#include "viewer.h" +#include "llagent.h"  const S32 MIN_WIDTH = 200;  const S32 MIN_HEIGHT = 340; @@ -265,13 +265,13 @@ void LLFloaterAvatarPicker::find()  	msg->newMessage("AvatarPickerRequest");  	msg->nextBlock("AgentData"); -	msg->addUUID("AgentID", agent_get_id()); -	msg->addUUID("SessionID", agent_get_session_id()); +	msg->addUUID("AgentID", gAgent.getID()); +	msg->addUUID("SessionID", gAgent.getSessionID());  	msg->addUUID("QueryID", mQueryID);	// not used right now  	msg->nextBlock("Data");  	msg->addString("Name", text); -	agent_send_reliable_message(); +	gAgent.sendReliableMessage();  	if (mListNames)  	{ @@ -309,7 +309,7 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*  	msg->getUUID("AgentData", "QueryID", query_id);  	// Not for us -	if (agent_id != agent_get_id()) return; +	if (agent_id != gAgent.getID()) return;  	// Dialog already closed  	LLFloaterAvatarPicker *self = sInstance; diff --git a/indra/newview/llfloaterbump.cpp b/indra/newview/llfloaterbump.cpp index e891bbe203..abae92a854 100644 --- a/indra/newview/llfloaterbump.cpp +++ b/indra/newview/llfloaterbump.cpp @@ -37,7 +37,7 @@  #include "llscrolllistctrl.h"  #include "llvieweruictrlfactory.h" -#include "viewer.h"		// gPacificDaylightTime +#include "llappviewer.h"		// gPacificDaylightTime  ///----------------------------------------------------------------------------  /// Local function declarations, constants, enums, and typedefs diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp index a7233c310a..4b5bb3548b 100644 --- a/indra/newview/llfloaterbuycurrency.cpp +++ b/indra/newview/llfloaterbuycurrency.cpp @@ -43,7 +43,7 @@  #include "llvieweruictrlfactory.h"  #include "llweb.h"  #include "llwindow.h" -#include "viewer.h" +#include "llappviewer.h"  static const S32 STANDARD_BUY_AMOUNT = 1000;  static const S32 MINIMUM_BALANCE_AMOUNT = 0; diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp index 9ae634c76f..12722b6d95 100644 --- a/indra/newview/llfloaterbuyland.cpp +++ b/indra/newview/llfloaterbuyland.cpp @@ -62,7 +62,7 @@  #include "llwindow.h"  #include "llworld.h"  #include "llxmlrpctransaction.h" -#include "viewer.h" +#include "llappviewer.h"  #include "roles_constants.h"  // NOTE: This is duplicated in lldatamoney.cpp ... @@ -847,7 +847,7 @@ void LLFloaterBuyLandUI::startTransaction(TransactionType type,  	static std::string transaction_uri;  	if (transaction_uri.empty())  	{ -		transaction_uri = getHelperURI() + "landtool.php"; +		transaction_uri = LLAppViewer::instance()->getHelperURI() + "landtool.php";  	}  	const char* method; diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index 03e3a2e967..324da688f8 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -46,7 +46,6 @@  #include "v4coloru.h"  #include "llbutton.h"  #include "llviewercontrol.h" -#include "viewer.h"  #include "llvieweruictrlfactory.h"  #include "llviewerwindow.h"  #include "llgl.h" diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index c24d435132..53779b6970 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -51,7 +51,6 @@  #include "llviewerwindow.h"  #include "llvoavatar.h"  #include "pipeline.h" -#include "viewer.h"  #include "llvieweruictrlfactory.h"  #include "llviewerimagelist.h" diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp index 399d0b684c..04a5cf6a24 100644 --- a/indra/newview/llfloaterlagmeter.cpp +++ b/indra/newview/llfloaterlagmeter.cpp @@ -37,7 +37,8 @@  #include "llviewerstats.h"  #include "llviewerimage.h"  #include "llviewercontrol.h" -#include "viewer.h" +#include "llappviewer.h" +  #include "lltexturefetch.h"  #include "llbutton.h" @@ -189,7 +190,7 @@ void LLFloaterLagMeter::determineClient()  		{  			mClientCause->setText( childGetText("client_draw_distance_cause_msg") );  		} -		else if(gTextureFetch->getNumRequests() > 2) +		else if(LLAppViewer::instance()->getTextureFetch()->getNumRequests() > 2)  		{  			mClientCause->setText( childGetText("client_texture_loading_cause_msg") );  		} diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index a158000da5..ef628be471 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -63,7 +63,7 @@  #include "llviewerparceloverlay.h"  #include "llviewerregion.h"  #include "llviewerstats.h" -#include "viewer.h" +#include "llurlsimstring.h"  #include "llglheaders.h" @@ -178,7 +178,7 @@ void LLFloaterMap::onClose(bool app_quitting)  BOOL LLFloaterMap::canClose()  { -	return !gQuit; +	return !LLApp::isExiting();  } diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp index cab9d37cf7..a00f512515 100644 --- a/indra/newview/llfloaterpostcard.cpp +++ b/indra/newview/llfloaterpostcard.cpp @@ -60,7 +60,6 @@  #include "llimagej2c.h"  #include "llvfile.h"  #include "llvfs.h" -#include "viewer.h"  #include "llassetuploadresponders.h" diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp index a7cd2114e0..bd5438e10f 100644 --- a/indra/newview/llfloaterreporter.cpp +++ b/indra/newview/llfloaterreporter.cpp @@ -81,7 +81,7 @@  #include "llselectmgr.h"  #include "llviewerbuild.h"  #include "llvieweruictrlfactory.h" -#include "viewer.h" +#include "llappviewer.h"  #include "llassetuploadresponders.h" diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 3bc172c830..71e94cce93 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -51,7 +51,6 @@  #include "llsliderctrl.h"  #include "llspinctrl.h"  #include "llviewercontrol.h" -#include "viewer.h"  #include "llvieweruictrlfactory.h"  #include "llviewerstats.h"  #include "llviewercamera.h" diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 4f8ed08a69..22581c6576 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -76,7 +76,6 @@  #include "llviewerparcelmgr.h"  #include "llviewerwindow.h"  #include "llviewercontrol.h" -#include "viewer.h"  #include "llvieweruictrlfactory.h" @@ -752,7 +751,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)  BOOL LLFloaterTools::canClose()  {  	// don't close when quitting, so camera will stay put -	return !gQuit; +	return !LLApp::isExiting();  }  // virtual diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index 9e86c92bef..20f9e1ecd4 100644 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -38,7 +38,7 @@  #include "llvfile.h"  #include "lltextbox.h"  #include "llviewertexteditor.h" -#include "viewer.h" +#include "llappviewer.h"  #include "llstartup.h"  #include "message.h"  #include "llagent.h" diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index b411bb293f..53b43effec 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -84,7 +84,7 @@  #include "llworldmapview.h"  #include "llurl.h"  #include "llvieweruictrlfactory.h" -#include "viewer.h" +#include "llappviewer.h"  #include "llmapimagetype.h"  #include "llweb.h" diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index c6a27103a8..eb9addcf5c 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -66,7 +66,7 @@  // We need these because some of the code below relies on things like  // gAgent root folder. Remove them once the abstraction leak is fixed.  #include "llagent.h" -#include "viewer.h" +#include "llappviewer.h"  ///----------------------------------------------------------------------------  /// Local function declarations, constants, enums, and typedefs diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp index 3e17ecf06e..537cadf1d1 100644 --- a/indra/newview/llgesturemgr.cpp +++ b/indra/newview/llgesturemgr.cpp @@ -55,7 +55,6 @@  #include "llviewermessage.h"  #include "llvoavatar.h"  #include "llviewerstats.h" -#include "viewer.h"  LLGestureManager gGestureManager; diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index da3f7aad46..ba56d70c0a 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -56,7 +56,6 @@  #include "llviewerobjectlist.h"  #include "lltoolselectrect.h"  #include "llviewerwindow.h" -#include "viewer.h"  #include "llcompass.h"  #include "llsurface.h"  #include "llwind.h" diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index d1116b66e1..c213d26848 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -47,7 +47,6 @@  #include "roles_constants.h"  #include "lltransactiontypes.h"  #include "llstatusbar.h" -#include "viewer.h"  #include "lleconomy.h"  #include "llviewerwindow.h"  #include "llfloaterdirectory.h" @@ -806,8 +805,7 @@ void LLGroupMgr::processGroupMembersReply(LLMessageSystem* msg, void** data)  	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );  	if (gAgent.getID() != agent_id)  	{ -		llwarns << "Got group properties reply for another agent!" -			<< " Probably a userserver bug!" << llendl; +		llwarns << "Got group properties reply for another agent!" << llendl;  		return;  	} @@ -895,8 +893,7 @@ void LLGroupMgr::processGroupPropertiesReply(LLMessageSystem* msg, void** data)  	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );  	if (gAgent.getID() != agent_id)  	{ -		llwarns << "Got group properties reply for another agent!" -			<< " Probably a userserver bug!" << llendl; +		llwarns << "Got group properties reply for another agent!" << llendl;  		return;  	} @@ -963,8 +960,7 @@ void LLGroupMgr::processGroupRoleDataReply(LLMessageSystem* msg, void** data)  	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );  	if (gAgent.getID() != agent_id)  	{ -		llwarns << "Got group properties reply for another agent!" -			<< " Probably a userserver bug!" << llendl; +		llwarns << "Got group properties reply for another agent!" << llendl;  		return;  	} @@ -1031,8 +1027,7 @@ void LLGroupMgr::processGroupRoleMembersReply(LLMessageSystem* msg, void** data)  	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );  	if (gAgent.getID() != agent_id)  	{ -		llwarns << "Got group properties reply for another agent!" -			<< " Probably a userserver bug!" << llendl; +		llwarns << "Got group properties reply for another agent!" << llendl;  		return;  	} @@ -1142,8 +1137,7 @@ void LLGroupMgr::processGroupTitlesReply(LLMessageSystem* msg, void** data)  	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );  	if (gAgent.getID() != agent_id)  	{ -		llwarns << "Got group properties reply for another agent!" -			<< " Probably a userserver bug!" << llendl; +		llwarns << "Got group properties reply for another agent!" << llendl;  		return;  	} diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 1ebe813cf7..1d68441231 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -48,7 +48,6 @@  #include "llviewerobject.h"  #include "llvovolume.h"  #include "llviewerwindow.h" -#include "viewer.h"  #include "llstatusbar.h"  #include "llmenugl.h"  #include "pipeline.h" diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index b259b80116..810d3a26a1 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -61,7 +61,7 @@  #include "llviewertexteditor.h"  #include "llviewermessage.h"  #include "llviewerstats.h" -#include "viewer.h" +#include "llviewercontrol.h"  #include "llvieweruictrlfactory.h"  #include "lllogchat.h"  #include "llfloaterhtml.h" diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index a6e2a1393d..9c37f1f333 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -55,7 +55,7 @@  #include "llimpanel.h"  #include "llresizebar.h"  #include "lltabcontainer.h" -#include "viewer.h" +#include "llviewercontrol.h"  #include "llfloater.h"  #include "llmutelist.h"  #include "llresizehandle.h" diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index f777e09813..12617efb67 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -78,7 +78,6 @@  #include "llviewerwindow.h"  #include "llwearable.h"  #include "llwearablelist.h" -#include "viewer.h"  #include "llviewermessage.h"   #include "llviewerregion.h"  #include "lltabcontainer.h" diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 4e54e78430..ca65b879bc 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -47,7 +47,7 @@  #include "llviewerinventory.h"  #include "llviewermessage.h"  #include "llviewerwindow.h" -#include "viewer.h" +#include "llappviewer.h"  #include "lldbstrings.h"  #include "llviewerstats.h"  #include "llmutelist.h" diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 8620446d4a..d89ec791f1 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -32,7 +32,7 @@  #include "llviewerprecompiledheaders.h"  #include "lllogchat.h" -#include "viewer.h" +#include "llappviewer.h"  const S32 LOG_RECALL_SIZE = 2048; diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 953befcd30..44b919aa61 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -55,7 +55,6 @@  #include "llvoavatar.h"  #include "llworld.h"		// for gWorldPointer  #include "llresmgr.h" -#include "viewer.h"			// for gFPS  #include "pipeline.h"  #include "llglheaders.h" diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp index fb3de3ab56..2e4f66c929 100644 --- a/indra/newview/llmaniprotate.cpp +++ b/indra/newview/llmaniprotate.cpp @@ -60,7 +60,6 @@  #include "llviewerwindow.h"  #include "llworld.h"  #include "pipeline.h" -#include "viewer.h"  #include "lldrawable.h"  #include "llglheaders.h" @@ -513,8 +512,6 @@ LLVector3 LLManipRotate::projectToSphere( F32 x, F32 y, BOOL* on_sphere )  	return LLVector3( x, y, z );  } -extern U32 gFrameCount; -  // Freeform rotation  void LLManipRotate::drag( S32 x, S32 y )  { diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp index 1963b1a8f5..36e3f9a5e9 100644 --- a/indra/newview/llmaniptranslate.cpp +++ b/indra/newview/llmaniptranslate.cpp @@ -61,7 +61,6 @@  #include "llviewerwindow.h"  #include "llvoavatar.h"  #include "llworld.h" -#include "viewer.h"  #include "llui.h"  #include "pipeline.h" diff --git a/indra/newview/llmemoryview.cpp b/indra/newview/llmemoryview.cpp index 53582ac54b..a698c53f7f 100644 --- a/indra/newview/llmemoryview.cpp +++ b/indra/newview/llmemoryview.cpp @@ -41,7 +41,6 @@  #include "llfontgl.h"  #include "llmemtype.h" -#include "viewer.h"  #include "llui.h"  #include "llviewercontrol.h"  #include "llstat.h" diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp index 92c7832e4f..68bbe53090 100644 --- a/indra/newview/llmenucommands.cpp +++ b/indra/newview/llmenucommands.cpp @@ -67,7 +67,6 @@  #include "llviewerwindow.h"  #include "llworld.h"  #include "llworldmap.h" -#include "viewer.h"  #include "llfocusmgr.h"  void handle_track_avatar(const LLUUID& agent_id, const std::string& name) diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp index d69968d7ea..81e677433b 100644 --- a/indra/newview/llmorphview.cpp +++ b/indra/newview/llmorphview.cpp @@ -49,7 +49,6 @@  #include "llvoavatar.h"  #include "llviewerwindow.h"  #include "pipeline.h" -#include "viewer.h"  LLMorphView *gMorphView = NULL; diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index e115f10d06..4f1d7bb514 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -39,7 +39,7 @@  // Viewer includes  #include "llagent.h"  #include "llcallbacklist.h" -#include "viewer.h" +#include "llviewercontrol.h"  #include "llfontgl.h"  #include "llbutton.h"  #include "llviewerwindow.h" diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp index 118fd4225b..f36e282ea0 100644 --- a/indra/newview/llmutelist.cpp +++ b/indra/newview/llmutelist.cpp @@ -61,7 +61,6 @@  #include "llfloatermute.h"  #include "llviewergenericmessage.h"	// for gGenericDispatcher  #include "llviewerwindow.h" -#include "viewer.h"  #include "llworld.h" //for particle system banning  LLMuteList* gMuteListp = NULL; diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index edf2567c8c..c3128652fe 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -65,7 +65,7 @@  #include "llvoavatar.h"  #include "llworld.h"  #include "llworldmapview.h"		// shared draw code -#include "viewer.h"				// Only for constants! +#include "llappviewer.h"				// Only for constants!  #include "llglheaders.h" diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index bcdb6c63f4..15c993e552 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -57,7 +57,6 @@  #include "llvoavatar.h"  #include "llvoiceremotectrl.h"  #include "llwebbrowserctrl.h" -#include "viewer.h"  //  // Globals diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index dc2f14fcef..706e05328c 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -69,6 +69,7 @@  #include "lltooldraganddrop.h"  #include "lluiconstants.h"  #include "llvoavatar.h" +#include "llviewercontrol.h"  #include "llviewermenu.h"		// *FIX: for is_agent_friend()  #include "llviewergenericmessage.h"	// send_generic_message  #include "llviewerobjectlist.h" @@ -76,7 +77,6 @@  #include "llviewborder.h"  #include "llweb.h"  #include "llinventorymodel.h" -#include "viewer.h"				// for gUserServer  #include "roles_constants.h"  #define	kArraySize( _kArray ) ( sizeof( (_kArray) ) / sizeof( _kArray[0] ) ) diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index cb75f1606e..821eaf1a72 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -66,7 +66,7 @@  #include "llviewergenericmessage.h"	// send_generic_message  #include "llviewerregion.h"  #include "llviewerwindow.h"	// for window width, height -#include "viewer.h"	// app_abort_quit() +#include "llappviewer.h"	// abortQuit()  const S32 MINIMUM_PRICE_FOR_LISTING = 50;	// L$ @@ -314,7 +314,7 @@ void LLPanelClassified::saveCallback(S32 option, void* data)  		case 2: // Cancel  		default: -			app_abort_quit(); +            LLAppViewer::instance()->abortQuit();  			break;  	}  } diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index 50ff7bd9eb..fa7cdfbc97 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -65,7 +65,6 @@  #include "lltoolmgr.h"  #include "lltoolcomp.h"  #include "llpanelinventory.h" -#include "viewer.h"  //  // Imported globals diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp index 99744c9653..76fbada562 100644 --- a/indra/newview/llpanelgroup.cpp +++ b/indra/newview/llpanelgroup.cpp @@ -44,7 +44,7 @@  #include "llviewermessage.h"  #include "llvieweruictrlfactory.h"  #include "llviewerwindow.h" -#include "viewer.h" +#include "llappviewer.h"  // static  void* LLPanelGroupTab::createTab(void* data) @@ -530,7 +530,7 @@ void LLPanelGroup::handleNotifyCallback(S32 option)  	default:  		// Do nothing.  The user is canceling the action.  		// If we were quitting, we didn't really mean it. -		app_abort_quit(); +		LLAppViewer::instance()->abortQuit();  		break;  	}  } diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp index 4c12aa2218..0152990798 100644 --- a/indra/newview/llpanelgrouplandmoney.cpp +++ b/indra/newview/llpanelgrouplandmoney.cpp @@ -1115,8 +1115,7 @@ void LLPanelGroupLandMoney::processGroupAccountDetailsReply(LLMessageSystem* msg  	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );  	if (gAgent.getID() != agent_id)  	{ -		llwarns << "Got group L$ history reply for another agent!" -			<< " Probably a userserver bug!" << llendl; +		llwarns << "Got group L$ history reply for another agent!" << llendl;  		return;  	} @@ -1292,8 +1291,7 @@ void LLPanelGroupLandMoney::processGroupAccountTransactionsReply(LLMessageSystem  	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );  	if (gAgent.getID() != agent_id)  	{ -		llwarns << "Got group L$ history reply for another agent!" -			<< " Probably a userserver bug!" << llendl; +		llwarns << "Got group L$ history reply for another agent!" << llendl;  		return;  	} @@ -1463,8 +1461,7 @@ void LLPanelGroupLandMoney::processGroupAccountSummaryReply(LLMessageSystem* msg  	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );  	if (gAgent.getID() != agent_id)  	{ -		llwarns << "Got group L$ history reply for another agent!" -			<< " Probably a userserver bug!" << llendl; +		llwarns << "Got group L$ history reply for another agent!" << llendl;  		return;  	} diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 292f5c36f8..fe07175529 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -61,7 +61,8 @@  #include "llviewernetwork.h"  #include "llviewerwindow.h"			// to link into child list  #include "llnotify.h" -#include "viewer.h"					// for gHideLinks +#include "llappviewer.h"					// for gHideLinks +#include "llurlsimstring.h"  #include "llvieweruictrlfactory.h"  #include "llhttpclient.h"  #include "llweb.h" @@ -72,6 +73,7 @@  #include "llglheaders.h" +  const S32 BLACK_BORDER_HEIGHT = 160;  const S32 MAX_PASSWORD = 16; @@ -155,7 +157,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,  	mLogoImage = gImageList.getImage("startup_logo.tga", LLUUID::null, MIPMAP_FALSE, TRUE);  	gUICtrlFactory->buildPanel(this, "panel_login.xml"); -	setRect(rect); +	//setRect(rect);  	reshape(rect.getWidth(), rect.getHeight());  	childSetPrevalidate("first_name_edit", LLLineEditor::prevalidatePrintableNoSpace); @@ -214,26 +216,17 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,  	childSetAction("quit_btn", onClickQuit, this); -	LLTextBox* text = LLUICtrlFactory::getTextBoxByName(this, "version_text"); -	if (text) +	LLTextBox* version_text = LLUICtrlFactory::getTextBoxByName(this, "version_text"); +	if (version_text)  	{  		LLString version = llformat("%d.%d.%d (%d)",  			LL_VERSION_MAJOR,  			LL_VERSION_MINOR,  			LL_VERSION_PATCH,  			LL_VIEWER_BUILD ); -		text->setText(version); -		text->setClickedCallback(onClickVersion); -		text->setCallbackUserData(this); - -		// HACK to move to the lower-right of the window -		// replace/remove this logic when we have dynamic layouts -		S32 right = getRect().mRight; -		LLRect r = text->getRect(); -		const S32 PAD = 2; -		r.setOriginAndSize( right - r.getWidth() - PAD, PAD,  -			r.getWidth(), r.getHeight() ); -		text->setRect(r); +		version_text->setText(version); +		version_text->setClickedCallback(onClickVersion); +		version_text->setCallbackUserData(this);  	}  	LLTextBox* channel_text = LLUICtrlFactory::getTextBoxByName(this, "channel_text"); @@ -242,25 +235,14 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,  		channel_text->setText(gChannelName);  		channel_text->setClickedCallback(onClickVersion);  		channel_text->setCallbackUserData(this); - -		// HACK to move to the right of the window, above the version string, -		// replace/remove this logic when we have dynamic layouts -		S32 right = getRect().mRight; -		LLRect r = channel_text->getRect(); -		const S32 PAD = 2; -		S32 version_string_top = r.mTop; -		if(text) -		{ -			version_string_top = text->getRect().mTop; -		} -		r.setOriginAndSize(  -			right - r.getWidth() - PAD, -			version_string_top,  -			r.getWidth(),  -			r.getHeight()); -		channel_text->setRect(r);  	} +	LLTextBox* forgot_password_text = LLUICtrlFactory::getTextBoxByName(this, "forgot_password_text"); +	if (forgot_password_text) +	{ +		forgot_password_text->setClickedCallback(onClickForgotPassword); +	} +      	// get the web browser control  	#if LL_LIBXUL_ENABLED  	LLWebBrowserCtrl* web_browser = LLUICtrlFactory::getWebBrowserCtrlByName(this, "login_html"); @@ -635,15 +617,15 @@ BOOL LLPanelLogin::getServer(LLString &server, S32 &domain_name)  			{  				domain_name = combo->getValue().asInteger(); -				if ((S32)USERSERVER_OTHER == domain_name) +				if ((S32)GRID_INFO_OTHER == domain_name)  				{ -					server = gUserServerName; +					server = gGridName;  				}  			}  			else  			{  				// no valid selection, return other -				domain_name = (S32)USERSERVER_OTHER; +				domain_name = (S32)GRID_INFO_OTHER;  				server = combo_val.asString();  			}  			user_picked = combo->isDirty(); @@ -740,7 +722,7 @@ void LLPanelLogin::onClickConnect(void *)  			if (combo)  			{  				S32 selected_server = combo->getValue(); -				if (selected_server == USERSERVER_NONE) +				if (selected_server == GRID_INFO_NONE)  				{  					LLString custom_server = combo->getValue().asString();  					gSavedSettings.setString("CustomServer", custom_server); @@ -808,6 +790,15 @@ void LLPanelLogin::onClickVersion(void*)  	LLFloaterAbout::show(NULL);  } +void LLPanelLogin::onClickForgotPassword(void*) +{ +	if (sInstance ) +	{ +		LLWeb::loadURL(sInstance->childGetValue( "forgot_password_url" ).asString()); +	} +} + +  // static  void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)  { diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h index 94e746eb69..447b9ea01c 100644 --- a/indra/newview/llpanellogin.h +++ b/indra/newview/llpanellogin.h @@ -88,8 +88,9 @@ private:  	static void newAccountAlertCallback(S32 option, void*);  	static void onClickQuit(void*);  	static void onClickVersion(void*); +	static void onClickForgotPassword(void*);  	static void onPassKey(LLLineEditor* caller, void* user_data); - +	  private:  	LLPointer<LLViewerImage> mLogoImage; diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index cf507098f7..c3d949d3df 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -68,7 +68,7 @@  #include "llvovolume.h"  #include "llworld.h"  #include "pipeline.h" -#include "viewer.h" +#include "llviewercontrol.h"  #include "llvieweruictrlfactory.h"  #include "llfirstuse.h" diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 69e0fde823..c288c6aaed 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -72,7 +72,6 @@  #include "llvovolume.h"  #include "llworld.h"  #include "pipeline.h" -#include "viewer.h"  #include "lldrawpool.h"  #include "llvieweruictrlfactory.h" diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 720963cb0f..051e328a6b 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -65,7 +65,7 @@  #include "llviewerregion.h"  #include "llviewerstats.h"  #include "llviewerwindow.h"		// busycount -#include "viewer.h"			// gVFS +#include "llappviewer.h"			// gVFS  #include "llresmgr.h" @@ -342,7 +342,7 @@ void LLPreviewGesture::handleSaveChangesDialog(S32 option, void* data)  	case 2: // "Cancel"  	default:  		// If we were quitting, we didn't really mean it. -		app_abort_quit(); +		LLAppViewer::instance()->abortQuit();  		break;  	}  } diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp index 620be8f8c6..dc56494d7f 100644 --- a/indra/newview/llpreviewnotecard.cpp +++ b/indra/newview/llpreviewnotecard.cpp @@ -55,7 +55,8 @@  #include "lldir.h"  //#include "llfloaterchat.h"  #include "llviewerstats.h" -#include "viewer.h"		// app_abort_quit() +#include "llviewercontrol.h"		// gSavedSettings +#include "llappviewer.h"		// app_abort_quit()  #include "lllineeditor.h"  #include "llvieweruictrlfactory.h" @@ -636,7 +637,7 @@ void LLPreviewNotecard::handleSaveChangesDialog(S32 option, void* userdata)  	case 2: // "Cancel"  	default:  		// If we were quitting, we didn't really mean it. -		app_abort_quit(); +		LLAppViewer::instance()->abortQuit();  		break;  	}  } diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index 7eac589640..6c377009f2 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -72,7 +72,6 @@  #include "llscrolllistctrl.h"  #include "lltextbox.h"  #include "llslider.h" -#include "viewer.h"  #include "lldir.h"  #include "llcombobox.h"  //#include "llfloaterchat.h" @@ -83,7 +82,8 @@  #include "llwebbrowserctrl.h"  #include "lluictrlfactory.h" -#include "viewer.h" +#include "llviewercontrol.h" +#include "llappviewer.h"  #include "llpanelinventory.h" @@ -629,7 +629,7 @@ void LLScriptEdCore::handleSaveChangesDialog( S32 option, void* userdata )  	case 2: // "Cancel"  	default:  		// If we were quitting, we didn't really mean it. -		app_abort_quit(); +        LLAppViewer::instance()->abortQuit();  		break;  	}  } diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index d855f7508e..cc9c3fa503 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -49,7 +49,7 @@  #include "llviewercontrol.h"  #include "llviewerimagelist.h"  #include "llviewerwindow.h" -#include "viewer.h" +#include "llappviewer.h"  LLProgressView* LLProgressView::sInstance = NULL; @@ -127,7 +127,7 @@ BOOL LLProgressView::handleKeyHere(KEY key, MASK mask, BOOL called_from_parent)  		// Suck up all keystokes except CTRL-Q.  		if( ('Q' == key) && (MASK_CONTROL == mask) )  		{ -			app_user_quit(); +			LLAppViewer::instance()->userQuit();  		}  		return TRUE;  	} @@ -228,7 +228,7 @@ void LLProgressView::draw()  	F32 alpha = 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32()));  	// background_color.mV[3] = background_color.mV[3]*alpha; -	LLString top_line = gSecondLife; +	LLString top_line = LLAppViewer::instance()->getSecondLifeTitle();  	font->renderUTF8(top_line, 0,  		line_x, line_one_y, @@ -338,7 +338,7 @@ void LLProgressView::onCancelButtonClicked(void*)  {  	if (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE)  	{ -		app_request_quit(); +		LLAppViewer::instance()->requestQuit();  	}  	else  	{ diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp index eadac8a9eb..ee3890e50a 100644 --- a/indra/newview/llsky.cpp +++ b/indra/newview/llsky.cpp @@ -64,6 +64,7 @@ extern LLPipeline gPipeline;  F32 azimuth_from_vector(const LLVector3 &v);  F32 elevation_from_vector(const LLVector3 &v); +LLSky				gSky;  // ---------------- LLSky ----------------  ////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 6cd1aceeb7..abb8d973aa 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -38,7 +38,7 @@  #include "llvovolume.h"  #include "llviewercamera.h"  #include "llface.h" -#include "viewer.h" +#include "llviewercontrol.h"  #include "llagent.h"  #include "llviewerregion.h"  #include "llcamera.h" diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp index 332a5aa218..827493d1b5 100644 --- a/indra/newview/llsprite.cpp +++ b/indra/newview/llsprite.cpp @@ -48,7 +48,6 @@  #include "llface.h"  #include "llviewercamera.h"  #include "llviewerimagelist.h" -#include "viewer.h"  LLVector3 LLSprite::sCameraUp(0.0f,0.0f,1.0f);  LLVector3 LLSprite::sCameraRight(1.0f,0.0f,0.0f); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index dad8046e50..0111676a97 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -134,6 +134,7 @@  #include "llurlsimstring.h"  #include "llurlwhitelist.h"  #include "lluserauth.h" +#include "llvieweraudio.h"  #include "llviewerassetstorage.h"  #include "llviewercamera.h"  #include "llviewerdisplay.h" @@ -155,12 +156,16 @@  #include "llworldmap.h"  #include "llxfermanager.h"  #include "pipeline.h" -#include "viewer.h" +#include "llappviewer.h"  #include "llmediaengine.h"  #include "llfasttimerview.h"  #include "llfloatermap.h"  #include "llweb.h"  #include "llvoiceclient.h" +#include "llnamelistctrl.h" +#include "llnamebox.h" +#include "llnameeditor.h" +#include "llurlsimstring.h"  #if LL_LIBXUL_ENABLED  #include "llmozlib.h" @@ -186,13 +191,7 @@  //  // exported globals  // - -// HACK: Allow server to change sun and moon IDs. -// I can't figure out how to pass the appropriate -// information into the LLVOSky constructor.  JC -LLUUID gSunTextureID = IMG_SUN; -LLUUID gMoonTextureID = IMG_MOON; -LLUUID gCloudTextureID = IMG_CLOUD_POOF; +BOOL gAgentMovementCompleted = FALSE;  const char* SCREEN_HOME_FILENAME = "screen_home.bmp";  const char* SCREEN_LAST_FILENAME = "screen_last.bmp"; @@ -202,7 +201,6 @@ const char* SCREEN_LAST_FILENAME = "screen_last.bmp";  //  extern S32 gStartImageWidth;  extern S32 gStartImageHeight; -extern std::string gSerialNumber;  //  // local globals @@ -250,6 +248,17 @@ void init_start_screen(S32 location_id);  void release_start_screen();  void reset_login(); +void callback_cache_name(const LLUUID& id, const char* firstname, const char* lastname, BOOL is_group, void* data) +{ +	LLNameListCtrl::refreshAll(id, firstname, lastname, is_group); +	LLNameBox::refreshAll(id, firstname, lastname, is_group); +	LLNameEditor::refreshAll(id, firstname, lastname, is_group); +	 +	// TODO: Actually be intelligent about the refresh. +	// For now, just brute force refresh the dialogs. +	dialog_refresh_all(); +} +  //  // exported functionality  // @@ -288,9 +297,9 @@ public:  void update_texture_fetch()  { -	gTextureCache->update(1); // unpauses the texture cache thread -	gImageDecodeThread->update(1); // unpauses the image thread -	gTextureFetch->update(1); // unpauses the texture fetch thread +	LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread +	LLAppViewer::getImageDecodeThread()->update(1); // unpauses the image thread +	LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread  	gImageList.updateImages(0.10f);  } @@ -372,7 +381,7 @@ BOOL idle_startup()  		/////////////////////////////////////////////////  		// -		// Initialize stuff that doesn't need data from userserver/simulators +		// Initialize stuff that doesn't need data from simulators  		//  		if (gFeatureManagerp->isSafe()) @@ -412,7 +421,7 @@ BOOL idle_startup()  			// *TODO:translate (maybe - very unlikely error message)  			// Note: alerts.xml may be invalid - if this gets translated it will need to be in the code  			LLString bad_xui_msg = "An error occured while updating Second Life. Please download the latest version from www.secondlife.com."; -			app_early_exit(bad_xui_msg); +            LLAppViewer::instance()->earlyExit(bad_xui_msg);  		}  		//  		// Statistics stuff @@ -465,13 +474,13 @@ BOOL idle_startup()  				   std::string()))  			{  				std::string msg = llformat("Unable to start networking, error %d", gMessageSystem->getErrorCode()); -				app_early_exit(msg); +				LLAppViewer::instance()->earlyExit(msg);  			}  			LLMessageConfig::initClass("viewer", gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));  		}  		else  		{ -			app_early_exit("Unable to initialize communications."); +			LLAppViewer::instance()->earlyExit("Unable to initialize communications.");  		}  		if(gMessageSystem && gMessageSystem->isOK()) @@ -651,7 +660,7 @@ BOOL idle_startup()  		else  		{  			// if not automatically logging in, display login dialog -			// until a valid userserver is selected +			// a valid grid is selected  			firstname = gSavedSettings.getString("FirstName");  			lastname = gSavedSettings.getString("LastName");  			password = load_password_from_disk(); @@ -731,11 +740,11 @@ BOOL idle_startup()  			gSavedSettings.setString("LastName", lastname);  			llinfos << "Attempting login as: " << firstname << " " << lastname << llendl; -			write_debug("Attempting login as: "); -			write_debug(firstname); -			write_debug(" "); -			write_debug(lastname); -			write_debug("\n"); +			LLAppViewer::instance()->writeDebug("Attempting login as: "); +			LLAppViewer::instance()->writeDebug(firstname); +			LLAppViewer::instance()->writeDebug(" "); +			LLAppViewer::instance()->writeDebug(lastname); +			LLAppViewer::instance()->writeDebug("\n");  		}  		// create necessary directories @@ -783,17 +792,17 @@ BOOL idle_startup()  			LLString server_label;  			S32 domain_name_index;  			BOOL user_picked_server = LLPanelLogin::getServer( server_label, domain_name_index ); -			gUserServerChoice = (EUserServerDomain) domain_name_index; -			gSavedSettings.setS32("ServerChoice", gUserServerChoice); -			if (gUserServerChoice == USERSERVER_OTHER) +			gGridChoice = (EGridInfo) domain_name_index; +			gSavedSettings.setS32("ServerChoice", gGridChoice); +			if (gGridChoice == GRID_INFO_OTHER)  			{ -				snprintf(gUserServerName, MAX_STRING, "%s", server_label.c_str());			/* Flawfinder: ignore */ +				snprintf(gGridName, MAX_STRING, "%s", server_label.c_str());			/* Flawfinder: ignore */  			}  			if ( user_picked_server ) -			{	// User picked a grid from the popup, so clear the stored urls and they will be re-generated from gUserServerChoice +			{	// User picked a grid from the popup, so clear the stored urls and they will be re-generated from gGridChoice  				sAuthUris.clear(); -				resetURIs(); +                LLAppViewer::instance()->resetURIs();  			}  			LLString location; @@ -908,12 +917,12 @@ BOOL idle_startup()  		}  		if (sAuthUris.empty())  		{ -			sAuthUris = getLoginURIs(); +			sAuthUris = LLAppViewer::instance()->getLoginURIs();  		}  		sAuthUriNum = 0;  		auth_method = "login_to_simulator";  		auth_desc = "Logging in.  "; -		auth_desc += gSecondLife; +		auth_desc += LLAppViewer::instance()->getSecondLifeTitle();  		auth_desc += " may appear frozen.  Please wait.";  		LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );  	} @@ -966,7 +975,7 @@ BOOL idle_startup()  			gLastExecFroze,  			requested_options,  			hashed_mac_string, -			gSerialNumber); +			LLAppViewer::instance()->getSerialNumber());  		// reset globals  		gAcceptTOS = FALSE;  		gAcceptCriticalMessage = FALSE; @@ -1167,7 +1176,7 @@ BOOL idle_startup()  		default:  			if (sAuthUriNum >= (int) sAuthUris.size() - 1)  			{ -				emsg << "Unable to connect to " << gSecondLife << ".\n"; +				emsg << "Unable to connect to " << LLAppViewer::instance()->getSecondLifeTitle() << ".\n";  				emsg << gUserAuthp->errorMessage();  			} else {  				sAuthUriNum++; @@ -1187,7 +1196,7 @@ BOOL idle_startup()  		{  			delete gUserAuthp;  			gUserAuthp = NULL; -			app_force_quit(NULL); +			LLAppViewer::instance()->forceQuit();  			return FALSE;  		} @@ -1202,15 +1211,15 @@ BOOL idle_startup()  			const char* text;  			text = gUserAuthp->getResponse("agent_id");  			if(text) gAgentID.set(text); -			write_debug("AgentID: "); -			write_debug(text); -			write_debug("\n"); +			LLAppViewer::instance()->writeDebug("AgentID: "); +			LLAppViewer::instance()->writeDebug(text); +			LLAppViewer::instance()->writeDebug("\n");  			text = gUserAuthp->getResponse("session_id");  			if(text) gAgentSessionID.set(text); -			write_debug("SessionID: "); -			write_debug(text); -			write_debug("\n"); +			LLAppViewer::instance()->writeDebug("SessionID: "); +			LLAppViewer::instance()->writeDebug(text); +			LLAppViewer::instance()->writeDebug("\n");  			text = gUserAuthp->getResponse("secure_session_id");  			if(text) gAgent.mSecureSessionID.set(text); @@ -1238,7 +1247,6 @@ BOOL idle_startup()  			}  			gSavedSettings.setBOOL("RememberPassword", remember_password);  			gSavedSettings.setBOOL("LoginLastLocation", gSavedSettings.getBOOL("LoginLastLocation")); -			gSavedSettings.setBOOL("LoggedIn", TRUE);  			text = gUserAuthp->getResponse("agent_access");  			if(text && (text[0] == 'M')) @@ -1587,7 +1595,7 @@ BOOL idle_startup()  			gCacheName->addObserver(callback_cache_name);  			// Load stored cache if possible -			load_name_cache(); +            LLAppViewer::instance()->loadNameCache();  		}  		// Data storage for map of world. @@ -1985,22 +1993,8 @@ BOOL idle_startup()  		gAgent.sendReliableMessage();  		// request all group information -		// *FIX: This will not do the right thing if the message -		// gets there before the requestuserserverconnection -		// circuit is completed.  		gAgent.sendAgentDataUpdateRequest(); - -		// NOTE: removed as part of user-privacy -		// enhancements. this information should be available from -		// login. 2006-10-16 Phoenix. -		// get the users that have been granted modify powers -		//msg->newMessageFast(_PREHASH_RequestGrantedProxies); -		//msg->nextBlockFast(_PREHASH_AgentData); -		//msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); -		//msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); -		//gAgent.sendReliableMessage(); -  		BOOL shown_at_exit = gSavedSettings.getBOOL("ShowInventory");  		// Create the inventory views @@ -2136,7 +2130,6 @@ BOOL idle_startup()  		//msg->setHandlerFuncFast(_PREHASH_AttachedSoundCutoffRadius,	process_attached_sound_cutoff_radius);  		llinfos << "Initialization complete" << llendl; -		gInitializationComplete = TRUE;  		gRenderStartTime.reset();  		gForegroundTime.reset(); @@ -2352,27 +2345,27 @@ void login_show()  	llinfos << "Setting Servers" << llendl; -	if( USERSERVER_OTHER == gUserServerChoice ) +	if( GRID_INFO_OTHER == gGridChoice )  	{ -		LLPanelLogin::addServer( gUserServerName, USERSERVER_OTHER ); +		LLPanelLogin::addServer( gGridName, GRID_INFO_OTHER );  	}  	else  	{ -		LLPanelLogin::addServer( gUserServerDomainName[gUserServerChoice].mLabel, gUserServerChoice ); +		LLPanelLogin::addServer( gGridInfo[gGridChoice].mLabel, gGridChoice );  	}  	// Arg!  We hate loops! -	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_DMZ].mLabel,	USERSERVER_DMZ ); -	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_LOCAL].mLabel,	USERSERVER_LOCAL ); -	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_AGNI].mLabel,	USERSERVER_AGNI ); -	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_ADITI].mLabel,	USERSERVER_ADITI ); -	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SIVA].mLabel,	USERSERVER_SIVA ); -	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_DURGA].mLabel,	USERSERVER_DURGA ); -	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SHAKTI].mLabel,	USERSERVER_SHAKTI ); -	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_GANGA].mLabel,	USERSERVER_GANGA ); -	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_UMA].mLabel,	USERSERVER_UMA ); -	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_SOMA].mLabel,	USERSERVER_SOMA ); -	LLPanelLogin::addServer( gUserServerDomainName[USERSERVER_VAAK].mLabel,	USERSERVER_VAAK ); +	LLPanelLogin::addServer( gGridInfo[GRID_INFO_DMZ].mLabel,	GRID_INFO_DMZ ); +	LLPanelLogin::addServer( gGridInfo[GRID_INFO_LOCAL].mLabel,	GRID_INFO_LOCAL ); +	LLPanelLogin::addServer( gGridInfo[GRID_INFO_AGNI].mLabel,	GRID_INFO_AGNI ); +	LLPanelLogin::addServer( gGridInfo[GRID_INFO_ADITI].mLabel,	GRID_INFO_ADITI ); +	LLPanelLogin::addServer( gGridInfo[GRID_INFO_SIVA].mLabel,	GRID_INFO_SIVA ); +	LLPanelLogin::addServer( gGridInfo[GRID_INFO_DURGA].mLabel,	GRID_INFO_DURGA ); +	LLPanelLogin::addServer( gGridInfo[GRID_INFO_SHAKTI].mLabel,	GRID_INFO_SHAKTI ); +	LLPanelLogin::addServer( gGridInfo[GRID_INFO_GANGA].mLabel,	GRID_INFO_GANGA ); +	LLPanelLogin::addServer( gGridInfo[GRID_INFO_UMA].mLabel,	GRID_INFO_UMA ); +	LLPanelLogin::addServer( gGridInfo[GRID_INFO_SOMA].mLabel,	GRID_INFO_SOMA ); +	LLPanelLogin::addServer( gGridInfo[GRID_INFO_VAAK].mLabel,	GRID_INFO_VAAK );  }  // Callback for when login screen is closed.  Option 0 = connect, option 1 = quit. @@ -2405,7 +2398,7 @@ void login_callback(S32 option, void *userdata)  		LLPanelLogin::close();  		// Next iteration through main loop should shut down the app cleanly. -		gQuit = TRUE; +		LLAppViewer::instance()->userQuit(); // gQuit = TRUE;  		return;  	} @@ -2660,7 +2653,7 @@ void update_dialog_callback(S32 option, void *userdata)  		// ...user doesn't want to do it  		if (mandatory)  		{ -			app_force_quit(); +			LLAppViewer::instance()->forceQuit();  			// Bump them back to the login screen.  			//reset_login();  		} @@ -2680,7 +2673,9 @@ void update_dialog_callback(S32 option, void *userdata)  #elif LL_LINUX  	query_map["os"] = "lnx";  #endif -	query_map["userserver"] = gUserServerName; +	// *TODO change userserver to be grid on both viewer and sim, since +	// userserver no longer exists. +	query_map["userserver"] = gGridName;  	query_map["channel"] = gChannelName;  	// *TODO constantize this guy  	LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map); @@ -2691,7 +2686,7 @@ void update_dialog_callback(S32 option, void *userdata)  	{  		// We're hosed, bail  		llwarns << "LLDir::getTempFilename() failed" << llendl; -		app_force_quit(NULL); +		LLAppViewer::instance()->forceQuit();  		return;  	} @@ -2709,7 +2704,7 @@ void update_dialog_callback(S32 option, void *userdata)  	if (!CopyFileA(updater_source.c_str(), update_exe_path.c_str(), FALSE))  	{  		llinfos << "Unable to copy the updater!" << llendl; -		app_force_quit(NULL); +		LLAppViewer::instance()->forceQuit();  		return;  	} @@ -2742,13 +2737,14 @@ void update_dialog_callback(S32 option, void *userdata)  			program_name = "SecondLife";  		} -		params << " -silent -name \"" << gSecondLife << "\""; +		params << " -silent -name \"" << LLAppViewer::instance()->getSecondLifeTitle() << "\"";  		params << " -program \"" << program_name << "\"";  	}  	llinfos << "Calling updater: " << update_exe_path << " " << params.str() << llendl; - 	remove_marker_file(); // In case updater fails +	// *REMOVE:Mani The following call is handled through ~LLAppViewer. + 	// remove_marker_file(); // In case updater fails  	// Use spawn() to run asynchronously  	int retval = _spawnl(_P_NOWAIT, update_exe_path.c_str(), update_exe_path.c_str(), params.str().c_str(), NULL); @@ -2767,13 +2763,14 @@ void update_dialog_callback(S32 option, void *userdata)  	update_exe_path += "/AutoUpdater.app/Contents/MacOS/AutoUpdater' -url \"";  	update_exe_path += update_url.asString();  	update_exe_path += "\" -name \""; -	update_exe_path += gSecondLife; +	update_exe_path += LLAppViewer::instance()->getSecondLifeTitle();  	update_exe_path += "\" &";  	llinfos << "Calling updater: " << update_exe_path << llendl; - - 	remove_marker_file(); // In case updater fails +	// *REMOVE:Mani The following call is handled through ~LLAppViewer. + 	// remove_marker_file(); // In case updater fails +  	// Run the auto-updater.  	system(update_exe_path.c_str());		/* Flawfinder: ignore */ @@ -2781,16 +2778,18 @@ void update_dialog_callback(S32 option, void *userdata)  	OSMessageBox("Automatic updating is not yet implemented for Linux.\n"  		"Please download the latest version from www.secondlife.com.",  		NULL, OSMB_OK); -	remove_marker_file(); + +	// *REMOVE:Mani The following call is handled through ~LLAppViewer. +	// remove_marker_file();  #endif -	app_force_quit(NULL); +	LLAppViewer::instance()->forceQuit();  }  void use_circuit_callback(void**, S32 result)  {  	// bail if we're quitting. -	if(gQuit) return; +	if(LLApp::isExiting()) return;  	if( !gUseCircuitCallbackCalled )  	{  		gUseCircuitCallbackCalled = true; @@ -3689,3 +3688,8 @@ bool LLStartUp::dispatchURL()  	}  	return false;  } + +void login_alert_done(S32 option, void* user_data) +{ +	LLPanelLogin::giveFocus(); +} diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h index ad27b28a21..08f2f6002c 100644 --- a/indra/newview/llstartup.h +++ b/indra/newview/llstartup.h @@ -36,9 +36,9 @@  // functions  BOOL idle_startup(); -void cleanup_app();  LLString load_password_from_disk();  void release_start_screen(); +void login_alert_done(S32 option, void* user_data);  // constants, variables,  & enumerations  extern const char* SCREEN_HOME_FILENAME; diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 8c50eca9af..27081d15dc 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -78,7 +78,7 @@  #include "lltoolmgr.h"  #include "llfocusmgr.h" -#include "viewer.h" +#include "llappviewer.h"  //#include "llfirstuse.h" diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp index e9643ebe26..e9aa9b0232 100644 --- a/indra/newview/llsurface.cpp +++ b/indra/newview/llsurface.cpp @@ -41,7 +41,7 @@  #include "llviewerobjectlist.h"  #include "llregionhandle.h"  #include "llagent.h" -#include "viewer.h" +#include "llappviewer.h"  #include "llworld.h"  #include "llviewercontrol.h"  #include "llviewerimage.h" @@ -67,8 +67,6 @@ S32 LLSurface::sTexelsUpdated = 0;  F32 LLSurface::sTextureUpdateTime = 0.f;  LLStat LLSurface::sTexelsUpdatedPerSecStat; -extern void bad_network_handler(); -  // ---------------- LLSurface:: Public Members ---------------  LLSurface::LLSurface(U32 type, LLViewerRegion *regionp) : @@ -776,7 +774,7 @@ void LLSurface::decompressDCTPatch(LLBitPack &bitpack, LLGroupHeader *gopp, BOOL  				<< " quant_wbits " << (S32)ph.quant_wbits  				<< " patchids " << (S32)ph.patchids  				<< llendl; -			bad_network_handler(); +            LLAppViewer::instance()->badNetworkHandler();  			return;  		} diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp index 097682fa13..5330e8dfac 100644 --- a/indra/newview/lltexlayer.cpp +++ b/indra/newview/lltexlayer.cpp @@ -52,7 +52,6 @@  #include "llxmltree.h"  #include "pipeline.h"  #include "v4coloru.h" -#include "viewer.h"  //#include "../tools/imdebug/imdebug.h" diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 7d5e6ab185..ae42ec60d3 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -46,7 +46,6 @@  #include "llviewerimagelist.h"  #include "llviewerimage.h"  #include "llviewerregion.h" -#include "viewer.h"  ////////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 4df5444d66..06a4ea097f 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -49,7 +49,7 @@  #include "llviewerobject.h"  #include "llviewerimage.h"  #include "llviewerimagelist.h" -#include "viewer.h" +#include "llappviewer.h"  extern F32 texmem_lower_bound_scale; @@ -145,7 +145,7 @@ void LLTextureBar::draw()  	}  	LLColor4 color; -	if (mImagep->getID() == gTextureFetch->mDebugID) +	if (mImagep->getID() == LLAppViewer::getTextureFetch()->mDebugID)  	{  		color = LLColor4::cyan2;  	} @@ -347,7 +347,7 @@ BOOL LLTextureBar::handleMouseDown(S32 x, S32 y, MASK mask)  {  	if ((mask & (MASK_CONTROL|MASK_SHIFT|MASK_ALT)) == MASK_ALT)  	{ -		gTextureFetch->mDebugID = mImagep->getID(); +		LLAppViewer::getTextureFetch()->mDebugID = mImagep->getID();  		return TRUE;  	}  	return LLView::handleMouseDown(x,y,mask); @@ -469,9 +469,9 @@ void LLGLTexMemBar::draw()  	text = llformat("Textures: Count: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d(%d) RAW:%d",  					gImageList.getNumImages(), -					gTextureFetch->getNumRequests(), gTextureFetch->getNumDeletes(), -					gTextureFetch->mPacketCount, gTextureFetch->mBadPacketCount,  -					gTextureCache->getNumReads(), gTextureCache->getNumWrites(), +					LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(), +					LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount,  +					LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(),  					LLLFSThread::sLocal->getPending(),  					LLImageWorker::sCount, LLImageWorker::getWorkerThread()->getNumDeletes(),  					LLImageRaw::sRawImageCount); @@ -480,7 +480,7 @@ void LLGLTexMemBar::draw()  									 text_color, LLFontGL::LEFT, LLFontGL::TOP);  	S32 dx1 = 0; -	if (gTextureFetch->mDebugPause) +	if (LLAppViewer::getTextureFetch()->mDebugPause)  	{  		LLFontGL::sMonospace->renderUTF8("!", 0, title_x1, line_height,  										 text_color, LLFontGL::LEFT, LLFontGL::TOP); @@ -781,7 +781,7 @@ BOOL LLTextureView::handleMouseDown(S32 x, S32 y, MASK mask)  	}  	if ((mask & (MASK_CONTROL|MASK_SHIFT|MASK_ALT)) == (MASK_CONTROL|MASK_SHIFT))  	{ -		gTextureFetch->mDebugPause = !gTextureFetch->mDebugPause; +		LLAppViewer::getTextureFetch()->mDebugPause = !LLAppViewer::getTextureFetch()->mDebugPause;  		return TRUE;  	}  	if (mask & MASK_SHIFT) diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp index 71e8aec78d..e7a5445ef6 100644 --- a/indra/newview/lltoolbar.cpp +++ b/indra/newview/lltoolbar.cpp @@ -59,7 +59,6 @@  #include "llviewerparcelmgr.h"  #include "llvieweruictrlfactory.h"  #include "llviewerwindow.h" -#include "viewer.h"  #include "lltoolgrab.h"  #if LL_DARWIN diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp index a56bf42cee..189996e871 100644 --- a/indra/newview/lltoolbrush.cpp +++ b/indra/newview/lltoolbrush.cpp @@ -53,7 +53,7 @@  #include "llviewerregion.h"  #include "llviewerwindow.h"  #include "llworld.h" -#include "viewer.h" +#include "llappviewer.h"  #include "llparcel.h"  #include "llglheaders.h" diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 1f607def58..e6eca31cd0 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -63,7 +63,6 @@  #include "llvolume.h"  #include "llworld.h"  #include "object_flags.h" -#include "viewer.h"  LLToolDragAndDrop *gToolDragAndDrop = NULL; diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp index 2ac2b33945..43c8e1a8d1 100644 --- a/indra/newview/lltoolfocus.cpp +++ b/indra/newview/lltoolfocus.cpp @@ -55,7 +55,6 @@  #include "llviewercamera.h"  #include "llviewerobject.h"  #include "llviewerwindow.h" -#include "viewer.h"  #include "llvoavatar.h"  #include "llmorphview.h" diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp index 13977ee3ac..3f19ed4330 100644 --- a/indra/newview/lltoolgrab.cpp +++ b/indra/newview/lltoolgrab.cpp @@ -62,7 +62,6 @@  #include "llviewerwindow.h"  #include "llvoavatar.h"  #include "llworld.h" -#include "viewer.h"  const S32 SLOP_DIST_SQ = 4; diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp index c7e598ecb2..ebe22fc43c 100644 --- a/indra/newview/lltoolgun.cpp +++ b/indra/newview/lltoolgun.cpp @@ -37,7 +37,6 @@  #include "llagent.h"  #include "llviewercontrol.h"  #include "llsky.h" -#include "viewer.h"  #include "llresmgr.h"  #include "llfontgl.h"  #include "llui.h" diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp index d3cd997e74..3a56a9fd63 100644 --- a/indra/newview/lltoolmorph.cpp +++ b/indra/newview/lltoolmorph.cpp @@ -62,7 +62,6 @@  #include "llviewerwindow.h"  #include "llvoavatar.h"  #include "pipeline.h" -#include "viewer.h"  //LLToolMorph *gToolMorph = NULL; diff --git a/indra/newview/lltoolobjpicker.cpp b/indra/newview/lltoolobjpicker.cpp index 8e8abfe3d1..a8876da131 100644 --- a/indra/newview/lltoolobjpicker.cpp +++ b/indra/newview/lltoolobjpicker.cpp @@ -38,7 +38,6 @@  #include "llagent.h"  #include "llselectmgr.h"  #include "llworld.h" -#include "viewer.h"				// for gFPSClamped, pie menus  #include "llviewercontrol.h"  #include "llmenugl.h"  #include "lltoolmgr.h" diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index ee5d08f128..d26bdab921 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -50,9 +50,22 @@  #include "llviewerregion.h"  #include "llviewerwindow.h"  #include "llworld.h" -#include "viewer.h"  #include "llui.h" +//Headers added for functions moved from viewer.cpp +#include "llvograss.h" +#include "llvotree.h" +#include "llvolumemessage.h" +#include "llhudmanager.h" +#include "llagent.h" +#include "audioengine.h" +#include "llhudeffecttrail.h" +#include "llviewerobjectlist.h" +#include "llviewercamera.h" +#include "llviewerstats.h" + +const LLVector3 DEFAULT_OBJECT_SCALE(0.5f, 0.5f, 0.5f); +  //static   LLPCode	LLToolPlacer::sObjectType = LL_PCODE_CUBE; @@ -61,9 +74,366 @@ LLToolPlacer::LLToolPlacer()  {  } +BOOL LLToolPlacer::raycastForNewObjPos( S32 x, S32 y, LLViewerObject** hit_obj, S32* hit_face,  +							 BOOL* b_hit_land, LLVector3* ray_start_region, LLVector3* ray_end_region, LLViewerRegion** region ) +{ +	F32 max_dist_from_camera = gSavedSettings.getF32( "MaxSelectDistance" ) - 1.f; + +	// Viewer-side pick to find the right sim to create the object on.   +	// First find the surface the object will be created on. +	gViewerWindow->hitObjectOrLandGlobalImmediate(x, y, NULL, FALSE); +	 +	// Note: use the frontmost non-flora version because (a) plants usually have lots of alpha and (b) pants' Havok +	// representations (if any) are NOT the same as their viewer representation. +	*hit_obj = gObjectList.findObject( gLastHitNonFloraObjectID ); +	*hit_face = gLastHitNonFloraObjectFace; +	*b_hit_land = !(*hit_obj) && !gLastHitNonFloraPosGlobal.isExactlyZero(); +	LLVector3d land_pos_global = gLastHitNonFloraPosGlobal; + +	// Make sure there's a surface to place the new object on. +	BOOL bypass_sim_raycast = FALSE; +	LLVector3d	surface_pos_global; +	if (*b_hit_land) +	{ +		surface_pos_global = land_pos_global;  +		bypass_sim_raycast = TRUE; +	} +	else  +	if (*hit_obj) +	{ +		surface_pos_global = (*hit_obj)->getPositionGlobal(); +	} +	else +	{ +		return FALSE; +	} + +	// Make sure the surface isn't too far away. +	LLVector3d ray_start_global = gAgent.getCameraPositionGlobal(); +	F32 dist_to_surface_sq = (F32)((surface_pos_global - ray_start_global).magVecSquared()); +	if( dist_to_surface_sq > (max_dist_from_camera * max_dist_from_camera) ) +	{ +		return FALSE; +	} + +	// Find the sim where the surface lives. +	LLViewerRegion *regionp = gWorldp->getRegionFromPosGlobal(surface_pos_global); +	if (!regionp) +	{ +		llwarns << "Trying to add object outside of all known regions!" << llendl; +		return FALSE; +	} + +	// Find the simulator-side ray that will be used to place the object accurately +	LLVector3d		mouse_direction; +	mouse_direction.setVec( gViewerWindow->mouseDirectionGlobal( x, y ) ); + +	*region = regionp; +	*ray_start_region =	regionp->getPosRegionFromGlobal( ray_start_global ); +	F32 near_clip = gCamera->getNear() + 0.01f;  // Include an epsilon to avoid rounding issues. +	*ray_start_region += gCamera->getAtAxis() * near_clip; + +	if( bypass_sim_raycast ) +	{ +		// Hack to work around Havok's inability to ray cast onto height fields +		*ray_end_region = regionp->getPosRegionFromGlobal( surface_pos_global );  // ray end is the viewer's intersection point +	} +	else +	{ +		LLVector3d		ray_end_global = ray_start_global + (1.f + max_dist_from_camera) * mouse_direction;  // add an epsilon to the sim version of the ray to avoid rounding problems. +		*ray_end_region = regionp->getPosRegionFromGlobal( ray_end_global ); +	} + +	return TRUE; +} + + +BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics ) +{ +	LLVector3 ray_start_region; +	LLVector3 ray_end_region; +	LLViewerRegion* regionp = NULL; +	BOOL b_hit_land = FALSE; +	S32 hit_face = -1; +	LLViewerObject* hit_obj = NULL; +	U8 state = 0; +	BOOL success = raycastForNewObjPos( x, y, &hit_obj, &hit_face, &b_hit_land, &ray_start_region, &ray_end_region, ®ionp ); +	if( !success ) +	{ +		return FALSE; +	} + +	if( hit_obj && (hit_obj->isAvatar() || hit_obj->isAttachment()) ) +	{ +		// Can't create objects on avatars or attachments +		return FALSE; +	} + +	if (NULL == regionp) +	{ +		llwarns << "regionp was NULL; aborting function." << llendl; +		return FALSE; +	} + +	if (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX) +	{ +		LLFirstUse::useSandbox(); +	} + +	// Set params for new object based on its PCode. +	LLQuaternion	rotation; +	LLVector3		scale = DEFAULT_OBJECT_SCALE; +	U8				material = LL_MCODE_WOOD; +	BOOL			create_selected = FALSE; +	LLVolumeParams	volume_params; +	 +	switch (pcode)  +	{ +	case LL_PCODE_LEGACY_GRASS: +		//  Randomize size of grass patch  +		scale.setVec(10.f + ll_frand(20.f), 10.f + ll_frand(20.f),  1.f + ll_frand(2.f)); +		state = rand() % LLVOGrass::sMaxGrassSpecies; +		break; + + +	case LL_PCODE_LEGACY_TREE: +	case LL_PCODE_TREE_NEW: +		state = rand() % LLVOTree::sMaxTreeSpecies; +		break; + +	case LL_PCODE_SPHERE: +	case LL_PCODE_CONE: +	case LL_PCODE_CUBE: +	case LL_PCODE_CYLINDER: +	case LL_PCODE_TORUS: +	case LLViewerObject::LL_VO_SQUARE_TORUS: +	case LLViewerObject::LL_VO_TRIANGLE_TORUS: +	default: +		create_selected = TRUE; +		break; +	} + +	// Play creation sound +	if (gAudiop) +	{ +		F32 volume = gSavedSettings.getF32("AudioLevelUI"); +		gAudiop->triggerSound( LLUUID(gSavedSettings.getString("UISndObjectCreate")), gAgent.getID(), volume); +	} + +	gMessageSystem->newMessageFast(_PREHASH_ObjectAdd); +	gMessageSystem->nextBlockFast(_PREHASH_AgentData); +	gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +	gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); +	gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); +	gMessageSystem->nextBlockFast(_PREHASH_ObjectData); +	gMessageSystem->addU8Fast(_PREHASH_Material,	material); + +	U32 flags = 0;		// not selected +	if (use_physics) +	{ +		flags |= FLAGS_USE_PHYSICS; +	} +	if (create_selected) +	{ +		flags |= FLAGS_CREATE_SELECTED; +	} +	gMessageSystem->addU32Fast(_PREHASH_AddFlags, flags ); + +	LLPCode volume_pcode;	// ...PCODE_VOLUME, or the original on error +	switch (pcode) +	{ +	case LL_PCODE_SPHERE: +		rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); + +		volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE ); +		volume_params.setBeginAndEndS( 0.f, 1.f ); +		volume_params.setBeginAndEndT( 0.f, 1.f ); +		volume_params.setRatio	( 1, 1 ); +		volume_params.setShear	( 0, 0 ); +		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); +		volume_pcode = LL_PCODE_VOLUME; +		break; + +	case LL_PCODE_TORUS: +		rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); + +		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE ); +		volume_params.setBeginAndEndS( 0.f, 1.f ); +		volume_params.setBeginAndEndT( 0.f, 1.f ); +		volume_params.setRatio	( 1.f, 0.25f );	// "top size" +		volume_params.setShear	( 0, 0 ); +		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); +		volume_pcode = LL_PCODE_VOLUME; +		break; + +	case LLViewerObject::LL_VO_SQUARE_TORUS: +		rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); + +		volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_CIRCLE ); +		volume_params.setBeginAndEndS( 0.f, 1.f ); +		volume_params.setBeginAndEndT( 0.f, 1.f ); +		volume_params.setRatio	( 1.f, 0.25f );	// "top size" +		volume_params.setShear	( 0, 0 ); +		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); +		volume_pcode = LL_PCODE_VOLUME; +		break; + +	case LLViewerObject::LL_VO_TRIANGLE_TORUS: +		rotation.setQuat(90.f * DEG_TO_RAD, LLVector3::y_axis); + +		volume_params.setType( LL_PCODE_PROFILE_EQUALTRI, LL_PCODE_PATH_CIRCLE ); +		volume_params.setBeginAndEndS( 0.f, 1.f ); +		volume_params.setBeginAndEndT( 0.f, 1.f ); +		volume_params.setRatio	( 1.f, 0.25f );	// "top size" +		volume_params.setShear	( 0, 0 ); +		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); +		volume_pcode = LL_PCODE_VOLUME; +		break; + +	case LL_PCODE_SPHERE_HEMI: +		volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE ); +		//volume_params.setBeginAndEndS( 0.5f, 1.f ); +		volume_params.setBeginAndEndT( 0.f, 0.5f ); +		volume_params.setRatio	( 1, 1 ); +		volume_params.setShear	( 0, 0 ); +		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); +		volume_pcode = LL_PCODE_VOLUME; +		break; + +	case LL_PCODE_CUBE: +		volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE ); +		volume_params.setBeginAndEndS( 0.f, 1.f ); +		volume_params.setBeginAndEndT( 0.f, 1.f ); +		volume_params.setRatio	( 1, 1 ); +		volume_params.setShear	( 0, 0 ); +		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); +		volume_pcode = LL_PCODE_VOLUME; +		break; + +	case LL_PCODE_PRISM: +		volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE ); +		volume_params.setBeginAndEndS( 0.f, 1.f ); +		volume_params.setBeginAndEndT( 0.f, 1.f ); +		volume_params.setRatio	( 0, 1 ); +		volume_params.setShear	( -0.5f, 0 ); +		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); +		volume_pcode = LL_PCODE_VOLUME; +		break; + +	case LL_PCODE_PYRAMID: +		volume_params.setType( LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE ); +		volume_params.setBeginAndEndS( 0.f, 1.f ); +		volume_params.setBeginAndEndT( 0.f, 1.f ); +		volume_params.setRatio	( 0, 0 ); +		volume_params.setShear	( 0, 0 ); +		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); +		volume_pcode = LL_PCODE_VOLUME; +		break; + +	case LL_PCODE_TETRAHEDRON: +		volume_params.setType( LL_PCODE_PROFILE_EQUALTRI, LL_PCODE_PATH_LINE ); +		volume_params.setBeginAndEndS( 0.f, 1.f ); +		volume_params.setBeginAndEndT( 0.f, 1.f ); +		volume_params.setRatio	( 0, 0 ); +		volume_params.setShear	( 0, 0 ); +		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); +		volume_pcode = LL_PCODE_VOLUME; +		break; + +	case LL_PCODE_CYLINDER: +		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); +		volume_params.setBeginAndEndS( 0.f, 1.f ); +		volume_params.setBeginAndEndT( 0.f, 1.f ); +		volume_params.setRatio	( 1, 1 ); +		volume_params.setShear	( 0, 0 ); +		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); +		volume_pcode = LL_PCODE_VOLUME; +		break; + +	case LL_PCODE_CYLINDER_HEMI: +		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); +		volume_params.setBeginAndEndS( 0.25f, 0.75f ); +		volume_params.setBeginAndEndT( 0.f, 1.f ); +		volume_params.setRatio	( 1, 1 ); +		volume_params.setShear	( 0, 0 ); +		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); +		volume_pcode = LL_PCODE_VOLUME; +		break; + +	case LL_PCODE_CONE: +		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); +		volume_params.setBeginAndEndS( 0.f, 1.f ); +		volume_params.setBeginAndEndT( 0.f, 1.f ); +		volume_params.setRatio	( 0, 0 ); +		volume_params.setShear	( 0, 0 ); +		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); +		volume_pcode = LL_PCODE_VOLUME; +		break; + +	case LL_PCODE_CONE_HEMI: +		volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); +		volume_params.setBeginAndEndS( 0.25f, 0.75f ); +		volume_params.setBeginAndEndT( 0.f, 1.f ); +		volume_params.setRatio	( 0, 0 ); +		volume_params.setShear	( 0, 0 ); +		LLVolumeMessage::packVolumeParams(&volume_params, gMessageSystem); +		volume_pcode = LL_PCODE_VOLUME; +		break; + +	default: +		LLVolumeMessage::packVolumeParams(0, gMessageSystem); +		volume_pcode = pcode; +		break; +	} +	gMessageSystem->addU8Fast(_PREHASH_PCode, volume_pcode); + +	gMessageSystem->addVector3Fast(_PREHASH_Scale,			scale ); +	gMessageSystem->addQuatFast(_PREHASH_Rotation,			rotation ); +	gMessageSystem->addVector3Fast(_PREHASH_RayStart,		ray_start_region ); +	gMessageSystem->addVector3Fast(_PREHASH_RayEnd,			ray_end_region ); +	gMessageSystem->addU8Fast(_PREHASH_BypassRaycast,		(U8)b_hit_land ); +	gMessageSystem->addU8Fast(_PREHASH_RayEndIsIntersection, (U8)FALSE ); +	gMessageSystem->addU8Fast(_PREHASH_State, state); + +	// Limit raycast to a single object.   +	// Speeds up server raycast + avoid problems with server ray hitting objects +	// that were clipped by the near plane or culled on the viewer. +	LLUUID ray_target_id; +	if( hit_obj ) +	{ +		ray_target_id = hit_obj->getID(); +	} +	else +	{ +		ray_target_id.setNull(); +	} +	gMessageSystem->addUUIDFast(_PREHASH_RayTargetID,			ray_target_id ); +	 +	// Pack in name value pairs +	gMessageSystem->sendReliable(regionp->getHost()); + +	// Spawns a message, so must be after above send +	if (create_selected) +	{ +		gSelectMgr->deselectAll(); +		gViewerWindow->getWindow()->incBusyCount(); +	} + +	// VEFFECT: AddObject +	LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE); +	effectp->setSourceObject((LLViewerObject*)gAgent.getAvatarObject()); +	effectp->setPositionGlobal(regionp->getPosGlobalFromRegion(ray_end_region)); +	effectp->setDuration(LL_HUD_DUR_SHORT); +	effectp->setColor(LLColor4U(gAgent.getEffectColor())); + +	gViewerStats->incStat(LLViewerStats::ST_CREATE_COUNT); + +	return TRUE; +} +  // Used by the placer tool to add copies of the current selection.  // Inspired by add_object().  JC -BOOL add_duplicate(S32 x, S32 y) +BOOL LLToolPlacer::addDuplicate(S32 x, S32 y)  {  	LLVector3 ray_start_region;  	LLVector3 ray_end_region; @@ -71,7 +441,7 @@ BOOL add_duplicate(S32 x, S32 y)  	BOOL b_hit_land = FALSE;  	S32 hit_face = -1;  	LLViewerObject* hit_obj = NULL; -	BOOL success = raycast_for_new_obj_pos( x, y, &hit_obj, &hit_face, &b_hit_land, &ray_start_region, &ray_end_region, ®ionp ); +	BOOL success = raycastForNewObjPos( x, y, &hit_obj, &hit_face, &b_hit_land, &ray_start_region, &ray_end_region, ®ionp );  	if( !success )  	{  		make_ui_sound("UISndInvalidOp"); @@ -123,11 +493,11 @@ BOOL LLToolPlacer::placeObject(S32 x, S32 y, MASK mask)  	if (gSavedSettings.getBOOL("CreateToolCopySelection"))  	{ -		added = add_duplicate(x, y); +		added = addDuplicate(x, y);  	}  	else  	{ -		added = add_object( sObjectType, x, y, NO_PHYSICS ); +		added = addObject( sObjectType, x, y, FALSE );  	}  	// ...and go back to the default tool diff --git a/indra/newview/lltoolplacer.h b/indra/newview/lltoolplacer.h index d6d21cbf70..b016470129 100644 --- a/indra/newview/lltoolplacer.h +++ b/indra/newview/lltoolplacer.h @@ -37,6 +37,7 @@  #include "lltool.h"  class LLButton; +class LLViewerRegion;  ////////////////////////////////////////////////////  // LLToolPlacer @@ -57,6 +58,12 @@ public:  protected:  	static LLPCode	sObjectType; + +private: +	BOOL addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics ); +	BOOL raycastForNewObjPos( S32 x, S32 y, LLViewerObject** hit_obj, S32* hit_face,  +							  BOOL* b_hit_land, LLVector3* ray_start_region, LLVector3* ray_end_region, LLViewerRegion** region ); +	BOOL addDuplicate(S32 x, S32 y);  };  //////////////////////////////////////////////////// diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index f77202f1bc..37c8b00ed2 100644 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -49,7 +49,6 @@  #include "llviewerwindow.h"  #include "llvoavatar.h"  #include "llworld.h" -#include "viewer.h"				// for gFPSClamped, pie menus  // Globals  LLToolSelect		*gToolSelect = NULL; diff --git a/indra/newview/lltoolselectland.cpp b/indra/newview/lltoolselectland.cpp index dae8288810..bbbda58cf0 100644 --- a/indra/newview/lltoolselectland.cpp +++ b/indra/newview/lltoolselectland.cpp @@ -45,7 +45,6 @@  #include "lltoolview.h"  #include "llviewerparcelmgr.h"  #include "llviewerwindow.h" -#include "viewer.h"  // Globals  LLToolSelectLand *gToolParcel = NULL; diff --git a/indra/newview/lltoolselectrect.cpp b/indra/newview/lltoolselectrect.cpp index 505039d3d3..dd1a01f8dd 100644 --- a/indra/newview/lltoolselectrect.cpp +++ b/indra/newview/lltoolselectrect.cpp @@ -48,7 +48,6 @@  #include "llviewerobjectlist.h"  #include "llviewerwindow.h"  #include "llviewercamera.h" -#include "viewer.h"  #include "llglheaders.h" diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp index a35d7b5c08..4bab92269c 100644 --- a/indra/newview/lltracker.cpp +++ b/indra/newview/lltracker.cpp @@ -45,7 +45,7 @@  #include "v4color.h"  // viewer includes -#include "viewer.h" +#include "llappviewer.h"  #include "lltracker.h"  #include "llagent.h"  #include "llcallingcard.h" @@ -62,6 +62,7 @@  #include "llviewerinventory.h"  #include "llworld.h"  #include "llworldmapview.h" +#include "llviewercontrol.h"  const F32 DESTINATION_REACHED_RADIUS    = 3.0f;  const F32 DESTINATION_VISITED_RADIUS    = 6.0f; diff --git a/indra/newview/llvectorperfoptions.cpp b/indra/newview/llvectorperfoptions.cpp new file mode 100644 index 0000000000..0952e8b314 --- /dev/null +++ b/indra/newview/llvectorperfoptions.cpp @@ -0,0 +1,108 @@ +/**  + * @file llvectorperfoptions.cpp + * @brief Control of vector perfomance options. + * + * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llvectorperfoptions.h" +#include "llviewerjointmesh.h" +#include "llviewercontrol.h" + +// Initially, we test the performance of the vectorization code, then +// turn it off if it ends up being slower. JC +BOOL	gVectorizePerfTest	= TRUE; +BOOL	gVectorizeEnable	= FALSE; +U32		gVectorizeProcessor	= 0; +BOOL	gVectorizeSkin		= FALSE; + +void update_vector_performances(void) +{ +	char *vp; +	 +	switch(gVectorizeProcessor) +	{ +		case 2: vp = "SSE2"; break;					// *TODO: replace the magic #s +		case 1: vp = "SSE"; break; +		default: vp = "COMPILER DEFAULT"; break; +	} +	llinfos << "Vectorization         : " << ( gVectorizeEnable ? "ENABLED" : "DISABLED" ) << llendl ; +	llinfos << "Vector Processor      : " << vp << llendl ; +	llinfos << "Vectorized Skinning   : " << ( gVectorizeSkin ? "ENABLED" : "DISABLED" ) << llendl ; +	 +	if(gVectorizeEnable && gVectorizeSkin) +	{ +		switch(gVectorizeProcessor) +		{ +			case 2: +				LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometrySSE2; +				break; +			case 1: +				LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometrySSE; +				break; +			default: +				LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometryVectorized; +				break; +		} +	} +	else +	{ +		LLViewerJointMesh::sUpdateGeometryFunc = &LLViewerJointMesh::updateGeometryOriginal; +	} +} + + +class LLVectorizationEnableListener: public LLSimpleListener +{ +	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) +	{ +		gVectorizeEnable = event->getValue().asBoolean(); +		update_vector_performances(); +		return true; +	} +}; +static LLVectorizationEnableListener vectorization_enable_listener; + +class LLVectorizeSkinListener: public LLSimpleListener +{ +	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) +	{ +		gVectorizeSkin = event->getValue().asBoolean(); +		update_vector_performances(); +		return true; +	} +}; +static LLVectorizeSkinListener vectorize_skin_listener; + +class LLVectorProcessorListener: public LLSimpleListener +{ +	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) +	{ +		gVectorizeProcessor = event->getValue().asInteger(); +		update_vector_performances(); +		return true; +	} +}; +static LLVectorProcessorListener vector_processor_listener; + +void LLVectorPerformanceOptions::initClass() +{ +	gVectorizePerfTest = gSavedSettings.getBOOL("VectorizePerfTest"); +	gVectorizeEnable = gSavedSettings.getBOOL("VectorizeEnable"); +	gVectorizeProcessor = gSavedSettings.getU32("VectorizeProcessor"); +	gVectorizeSkin = gSavedSettings.getBOOL("VectorizeSkin"); +	update_vector_performances(); + +	// these are currently static in this file, so they can't move to settings_setup_listeners +	gSavedSettings.getControl("VectorizeEnable")->addListener(&vectorization_enable_listener); +	gSavedSettings.getControl("VectorizeProcessor")->addListener(&vector_processor_listener); +	gSavedSettings.getControl("VectorizeSkin")->addListener(&vectorize_skin_listener); +} + +void LLVectorPerformanceOptions::cleanupClass() +{ +} + diff --git a/indra/newview/llvectorperfoptions.h b/indra/newview/llvectorperfoptions.h new file mode 100644 index 0000000000..ebd1f8248d --- /dev/null +++ b/indra/newview/llvectorperfoptions.h @@ -0,0 +1,18 @@ +/**  + * @file llvectorperfoptions.h + * @brief Control of vector performance options + * + * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LL_VECTORPERFOPTIONS_H +#define LL_VECTORPERFOPTIONS_H + +namespace LLVectorPerformanceOptions +{ +	void initClass(); // Run after configuration files are read. +	void cleanupClass(); +}; + +#endif diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp new file mode 100644 index 0000000000..ac90a06a57 --- /dev/null +++ b/indra/newview/llvieweraudio.cpp @@ -0,0 +1,215 @@ +/**  + * @file llvieweraudio.cpp + * @brief Audio functions moved from viewer.cpp + * + * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llvieweraudio.h" +#include "audioengine.h" +#include "llviewercontrol.h" +#include "llmediaengine.h" +#include "llagent.h" +#include "llappviewer.h" +#include "llvoiceclient.h" +#include "llviewerwindow.h" +#include "llviewercamera.h" + +///////////////////////////////////////////////////////// + +void init_audio()  +{ +	if (!gAudiop)  +	{ +		llwarns << "Failed to create an appropriate Audio Engine" << llendl; +		return; +	} +	LLVector3d lpos_global = gAgent.getCameraPositionGlobal(); +	LLVector3 lpos_global_f; + +	lpos_global_f.setVec(lpos_global); +					 +	gAudiop->setListener(lpos_global_f, +						  LLVector3::zero,	// gCamera->getVelocity(),    // !!! BUG need to replace this with smoothed velocity! +						  gCamera->getUpAxis(), +						  gCamera->getAtAxis()); + +// load up our initial set of sounds we'll want so they're in memory and ready to be played + +	BOOL mute_audio = gSavedSettings.getBOOL("MuteAudio"); + +	if (!mute_audio && gPreloadSounds) +	{ +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndAlert"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndBadKeystroke"))); +		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndChatFromObject"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndClick"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndClickRelease"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndHealthReductionF"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndHealthReductionM"))); +		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndIncomingChat"))); +		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndIncomingIM"))); +		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndInvApplyToObject"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndInvalidOp"))); +		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndInventoryCopyToInv"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndMoneyChangeDown"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndMoneyChangeUp"))); +		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectCopyToInv"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectCreate"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectDelete"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectRezIn"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndObjectRezOut"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuAppear"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuHide"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight0"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight1"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight2"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight3"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight4"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight5"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight6"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndPieMenuSliceHighlight7"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndSnapshot"))); +		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartAutopilot"))); +		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartFollowpilot"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStartIM"))); +		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndStopAutopilot"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTeleportOut"))); +		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTextureApplyToObject"))); +		//gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTextureCopyToInv"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndTyping"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowClose"))); +		gAudiop->preloadSound(LLUUID(gSavedSettings.getString("UISndWindowOpen"))); +	} + +	audio_update_volume(true); +} + +void audio_update_volume(bool force_update) +{ +	F32 master_volume = gSavedSettings.getF32("AudioLevelMaster"); +	BOOL mute_audio = gSavedSettings.getBOOL("MuteAudio"); +	if (!gViewerWindow->getActive() && (gSavedSettings.getBOOL("MuteWhenMinimized"))) +	{ +		mute_audio = TRUE; +	} +	F32 mute_volume = mute_audio ? 0.0f : 1.0f; + +	// Sound Effects +	if (gAudiop)  +	{ +		gAudiop->setMasterGain ( master_volume ); + +		gAudiop->setDopplerFactor(gSavedSettings.getF32("AudioLevelDoppler")); +		gAudiop->setDistanceFactor(gSavedSettings.getF32("AudioLevelDistance"));  +		gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff")); +#ifdef kAUDIO_ENABLE_WIND +		gAudiop->enableWind(!mute_audio); +#endif + +		gAudiop->setMuted(mute_audio); +		 +		if (force_update) +		{ +			audio_update_wind(true); +		} +	} + +	// Streaming Music +	if (gAudiop)  +	{		 +		F32 music_volume = gSavedSettings.getF32("AudioLevelMusic"); +		music_volume = mute_volume * master_volume * (music_volume*music_volume); +		gAudiop->setInternetStreamGain ( music_volume ); +	} + +	// Streaming Media +	if(LLMediaEngine::getInstance()) +	{ +		F32 media_volume = gSavedSettings.getF32("AudioLevelMedia"); +		media_volume = mute_volume * master_volume * (media_volume*media_volume); +		LLMediaEngine::getInstance()->setVolume(media_volume); +	} + +	// Voice +	if (gVoiceClient) +	{ +		F32 voice_volume = gSavedSettings.getF32("AudioLevelVoice"); +		voice_volume = mute_volume * master_volume * voice_volume; +		gVoiceClient->setVoiceVolume(voice_volume); +		gVoiceClient->setMicGain(gSavedSettings.getF32("AudioLevelMic")); + +		if (!gViewerWindow->getActive() && (gSavedSettings.getBOOL("MuteWhenMinimized"))) +		{ +			gVoiceClient->setMuteMic(true); +		} +		else +		{ +			gVoiceClient->setMuteMic(false); +		} +	} +} + +void audio_update_listener() +{ +	if (gAudiop) +	{ +		// update listener position because agent has moved	 +		LLVector3d lpos_global = gAgent.getCameraPositionGlobal();		 +		LLVector3 lpos_global_f; +		lpos_global_f.setVec(lpos_global); +	 +		gAudiop->setListener(lpos_global_f, +							 // gCameraVelocitySmoothed,  +							 // LLVector3::zero,	 +							 gAgent.getVelocity(),    // !!! *TODO: need to replace this with smoothed velocity! +							 gCamera->getUpAxis(), +							 gCamera->getAtAxis()); +	} +} + +void audio_update_wind(bool force_update) +{ +#ifdef kAUDIO_ENABLE_WIND +	// +	//  Extract height above water to modulate filter by whether above/below water  +	//  +	LLViewerRegion* region = gAgent.getRegion(); +	if (region) +	{ +		static F32 last_camera_water_height = -1000.f; +		LLVector3 camera_pos = gAgent.getCameraPositionAgent(); +		F32 camera_water_height = camera_pos.mV[VZ] - region->getWaterHeight(); +		 +		// +		//  Don't update rolloff factor unless water surface has been crossed +		// +		if (force_update || (last_camera_water_height * camera_water_height) < 0.f) +		{ +			if (camera_water_height < 0.f) +			{ +				gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff") * LL_ROLLOFF_MULTIPLIER_UNDER_WATER); +			} +			else  +			{ +				gAudiop->setRolloffFactor(gSavedSettings.getF32("AudioLevelRolloff")); +			} +		} +		// this line rotates the wind vector to be listener (agent) relative +		// unfortunately we have to pre-translate to undo the translation that +		// occurs in the transform call +		gRelativeWindVec = gAgent.getFrameAgent().rotateToLocal(gWindVec - gAgent.getVelocity()); + +		// don't use the setter setMaxWindGain() because we don't +		// want to screw up the fade-in on startup by setting actual source gain +		// outside the fade-in. +		gAudiop->mMaxWindGain = gSavedSettings.getF32("AudioLevelAmbient"); +		 +		last_camera_water_height = camera_water_height; +		gAudiop->updateWind(gRelativeWindVec, camera_water_height); +	} +#endif +} diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h new file mode 100644 index 0000000000..4aba50ec74 --- /dev/null +++ b/indra/newview/llvieweraudio.h @@ -0,0 +1,17 @@ +/**  + * @file llvieweraudio.h + * @brief Audio functions originally in viewer.cpp + * + * Copyright (c) 2000-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#ifndef LL_VIEWERAUDIO_H +#define LL_VIEWERAUDIO_H + +void init_audio(); +void audio_update_volume(bool force_update = true); +void audio_update_listener(); +void audio_update_wind(bool force_update = true); + +#endif //LL_VIEWER_H diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index a5b7b6fc8f..5a655cba1a 100644 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -47,6 +47,9 @@ const F32 OGL_TO_CFR_ROTATION[16] = {  0.f,  0.f, -1.f,  0.f, 	// -Z becomes X  									   0.f,  1.f,  0.f,  0.f,	//  Y becomes Z  									   0.f,  0.f,  0.f,  1.f }; +const BOOL FOR_SELECTION = TRUE; +const BOOL NOT_FOR_SELECTION = FALSE; +  class LLViewerCamera : public LLCamera  {  public: diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 79ec70fb1c..250b250a7a 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -50,6 +50,10 @@  #include "llspinctrl.h"  #include "llcolorswatch.h" +#ifdef TOGGLE_HACKED_GODLIKE_VIEWER +BOOL 				gHackGodmode = FALSE; +#endif +  LLFloaterSettingsDebug* LLFloaterSettingsDebug::sInstance = NULL;  LLControlGroup gSavedSettings;	// saved at end of session diff --git a/indra/newview/llviewercontrol.h b/indra/newview/llviewercontrol.h index 3151261ec3..8a3191d3bb 100644 --- a/indra/newview/llviewercontrol.h +++ b/indra/newview/llviewercontrol.h @@ -36,6 +36,13 @@  #include "llfloater.h"  #include "lltexteditor.h" +// Enabled this definition to compile a 'hacked' viewer that +// allows a hacked godmode to be toggled on and off. +#define TOGGLE_HACKED_GODLIKE_VIEWER  +#ifdef TOGGLE_HACKED_GODLIKE_VIEWER +extern BOOL gHackGodmode; +#endif +  class LLFloaterSettingsDebug : public LLFloater  {  public: diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 24b8105916..60184312a7 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -62,7 +62,7 @@  #include "llvograss.h"  #include "llworld.h"  #include "pipeline.h" -#include "viewer.h" +#include "llappviewer.h"  #include "llstartup.h"  #include "llfasttimer.h"  #include "llfloatertools.h" @@ -72,14 +72,11 @@  #include "llviewerregion.h"  #include "lldrawpoolwater.h" -extern U32 gFrameCount;  extern LLPointer<LLImageGL> gStartImageGL; -extern LLPointer<LLImageGL> gDisconnectedImagep; -extern BOOL gLogoutRequestSent; -extern LLTimer gLogoutTimer; -extern BOOL gHaveSavedSnapshot;  extern BOOL gDisplaySwapBuffers; +LLPointer<LLImageGL> gDisconnectedImagep = NULL; +  // used to toggle renderer back on after teleport  const F32 TELEPORT_RENDER_DELAY = 20.f; // Max time a teleport is allowed to take before we raise the curtain  const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. @@ -99,7 +96,7 @@ void render_ui_3d();  void render_ui_2d();  void render_disconnected_background(); -void process_keystrokes_async(); // in viewer.cpp +void process_keystrokes_async();  void display_startup()  { @@ -331,7 +328,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield)  			break;  		}  	} -	else if(gLogoutRequestSent) +    else if(LLAppViewer::instance()->logoutRequestSent())  	{  		F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime;  		if (percent_done > 100.f) @@ -339,7 +336,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield)  			percent_done = 100.f;  		} -		if( gQuit ) +		if( LLApp::isExiting() )  		{  			percent_done = 100.f;  		} @@ -358,7 +355,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield)  		else  		{ -			if( gQuit ) +			if( LLApp::isExiting() )  			{  				percent_done = 100.f;  			} @@ -554,7 +551,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield)  	//	glPopMatrix();  	//} -	if (!(gLogoutRequestSent && gHaveSavedSnapshot)  +	if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())   			&& !gRestoreGL  			&& !gDisconnected)  	{ @@ -745,6 +742,74 @@ void render_ui_and_swap()  	}  } +void renderCoordinateAxes() +{ +	LLGLSNoTexture gls_no_texture; +	glBegin(GL_LINES); +		glColor3f(1.0f, 0.0f, 0.0f);   // i direction = X-Axis = red +		glVertex3f(0.0f, 0.0f, 0.0f); +		glVertex3f(2.0f, 0.0f, 0.0f); +		glVertex3f(3.0f, 0.0f, 0.0f); +		glVertex3f(5.0f, 0.0f, 0.0f); +		glVertex3f(6.0f, 0.0f, 0.0f); +		glVertex3f(8.0f, 0.0f, 0.0f); +		// Make an X +		glVertex3f(11.0f, 1.0f, 1.0f); +		glVertex3f(11.0f, -1.0f, -1.0f); +		glVertex3f(11.0f, 1.0f, -1.0f); +		glVertex3f(11.0f, -1.0f, 1.0f); + +		glColor3f(0.0f, 1.0f, 0.0f);   // j direction = Y-Axis = green +		glVertex3f(0.0f, 0.0f, 0.0f); +		glVertex3f(0.0f, 2.0f, 0.0f); +		glVertex3f(0.0f, 3.0f, 0.0f); +		glVertex3f(0.0f, 5.0f, 0.0f); +		glVertex3f(0.0f, 6.0f, 0.0f); +		glVertex3f(0.0f, 8.0f, 0.0f); +		// Make a Y +		glVertex3f(1.0f, 11.0f, 1.0f); +		glVertex3f(0.0f, 11.0f, 0.0f); +		glVertex3f(-1.0f, 11.0f, 1.0f); +		glVertex3f(0.0f, 11.0f, 0.0f); +		glVertex3f(0.0f, 11.0f, 0.0f); +		glVertex3f(0.0f, 11.0f, -1.0f); + +		glColor3f(0.0f, 0.0f, 1.0f);   // Z-Axis = blue +		glVertex3f(0.0f, 0.0f, 0.0f); +		glVertex3f(0.0f, 0.0f, 2.0f); +		glVertex3f(0.0f, 0.0f, 3.0f); +		glVertex3f(0.0f, 0.0f, 5.0f); +		glVertex3f(0.0f, 0.0f, 6.0f); +		glVertex3f(0.0f, 0.0f, 8.0f); +		// Make a Z +		glVertex3f(-1.0f, 1.0f, 11.0f); +		glVertex3f(1.0f, 1.0f, 11.0f); +		glVertex3f(1.0f, 1.0f, 11.0f); +		glVertex3f(-1.0f, -1.0f, 11.0f); +		glVertex3f(-1.0f, -1.0f, 11.0f); +		glVertex3f(1.0f, -1.0f, 11.0f); +	glEnd(); +} + + +void draw_axes()  +{ +	LLGLSUIDefault gls_ui; +	LLGLSNoTexture gls_no_texture; +	// A vertical white line at origin +	LLVector3 v = gAgent.getPositionAgent(); +	glBegin(GL_LINES); +		glColor3f(1.0f, 1.0f, 1.0f);  +		glVertex3f(0.0f, 0.0f, 0.0f); +		glVertex3f(0.0f, 0.0f, 40.0f); +	glEnd(); +	// Some coordinate axes +	glPushMatrix(); +		glTranslatef( v.mV[VX], v.mV[VY], v.mV[VZ] ); +		renderCoordinateAxes(); +	glPopMatrix(); +} +  void render_ui_3d()  {  	LLGLSPipeline gls_pipeline; @@ -841,73 +906,6 @@ void render_ui_2d()  	LLFontGL::sCurOrigin.set(0, 0);  } -void renderCoordinateAxes() -{ -	LLGLSNoTexture gls_no_texture; -	glBegin(GL_LINES); -		glColor3f(1.0f, 0.0f, 0.0f);   // i direction = X-Axis = red -		glVertex3f(0.0f, 0.0f, 0.0f); -		glVertex3f(2.0f, 0.0f, 0.0f); -		glVertex3f(3.0f, 0.0f, 0.0f); -		glVertex3f(5.0f, 0.0f, 0.0f); -		glVertex3f(6.0f, 0.0f, 0.0f); -		glVertex3f(8.0f, 0.0f, 0.0f); -		// Make an X -		glVertex3f(11.0f, 1.0f, 1.0f); -		glVertex3f(11.0f, -1.0f, -1.0f); -		glVertex3f(11.0f, 1.0f, -1.0f); -		glVertex3f(11.0f, -1.0f, 1.0f); - -		glColor3f(0.0f, 1.0f, 0.0f);   // j direction = Y-Axis = green -		glVertex3f(0.0f, 0.0f, 0.0f); -		glVertex3f(0.0f, 2.0f, 0.0f); -		glVertex3f(0.0f, 3.0f, 0.0f); -		glVertex3f(0.0f, 5.0f, 0.0f); -		glVertex3f(0.0f, 6.0f, 0.0f); -		glVertex3f(0.0f, 8.0f, 0.0f); -		// Make a Y -		glVertex3f(1.0f, 11.0f, 1.0f); -		glVertex3f(0.0f, 11.0f, 0.0f); -		glVertex3f(-1.0f, 11.0f, 1.0f); -		glVertex3f(0.0f, 11.0f, 0.0f); -		glVertex3f(0.0f, 11.0f, 0.0f); -		glVertex3f(0.0f, 11.0f, -1.0f); - -		glColor3f(0.0f, 0.0f, 1.0f);   // Z-Axis = blue -		glVertex3f(0.0f, 0.0f, 0.0f); -		glVertex3f(0.0f, 0.0f, 2.0f); -		glVertex3f(0.0f, 0.0f, 3.0f); -		glVertex3f(0.0f, 0.0f, 5.0f); -		glVertex3f(0.0f, 0.0f, 6.0f); -		glVertex3f(0.0f, 0.0f, 8.0f); -		// Make a Z -		glVertex3f(-1.0f, 1.0f, 11.0f); -		glVertex3f(1.0f, 1.0f, 11.0f); -		glVertex3f(1.0f, 1.0f, 11.0f); -		glVertex3f(-1.0f, -1.0f, 11.0f); -		glVertex3f(-1.0f, -1.0f, 11.0f); -		glVertex3f(1.0f, -1.0f, 11.0f); -	glEnd(); -} - -void draw_axes()  -{ -	LLGLSUIDefault gls_ui; -	LLGLSNoTexture gls_no_texture; -	// A vertical white line at origin -	LLVector3 v = gAgent.getPositionAgent(); -	glBegin(GL_LINES); -		glColor3f(1.0f, 1.0f, 1.0f);  -		glVertex3f(0.0f, 0.0f, 0.0f); -		glVertex3f(0.0f, 0.0f, 40.0f); -	glEnd(); -	// Some coordinate axes -	glPushMatrix(); -		glTranslatef( v.mV[VX], v.mV[VY], v.mV[VZ] ); -		renderCoordinateAxes(); -	glPopMatrix(); -} -  void render_disconnected_background()  { @@ -984,3 +982,48 @@ void render_disconnected_background()  		glPopMatrix();  	}  } + +void display_cleanup() +{ +	gDisconnectedImagep = NULL; +} + +void process_keystrokes_async() +{ +#if LL_WINDOWS +	MSG			msg; +	// look through all input messages, leaving them in the event queue +	while( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD)) +	{ +		// on first mouse message, break out +		if (msg.message >= WM_MOUSEFIRST &&  +			msg.message <= WM_MOUSELAST || +			msg.message == WM_QUIT) +		{ +			break; +		} + +		// this is a message we want to handle now, so remove it from the event queue +		PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE | PM_NOYIELD); +		//		if (msg.message == WM_KEYDOWN) +		//		{ +		//			llinfos << "Process async key down " << (U32)msg.wParam << llendl; +		//		} +		TranslateMessage(&msg); +		DispatchMessage(&msg); +	} + +	// 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 (gViewerWindow->mWindow->getVisible()  +		&& gViewerWindow->getActive() +		&& !gViewerWindow->mWindow->getMinimized() +		&& LLStartUp::getStartupState() == STATE_STARTED +		&& !gViewerWindow->getShowProgress() +		&& !gFocusMgr.focusLocked()) +	{ +		gKeyboard->scanKeyboard(); +	} +#endif +} diff --git a/indra/newview/llviewerdisplay.h b/indra/newview/llviewerdisplay.h index b42c6e9bda..2bf784c575 100644 --- a/indra/newview/llviewerdisplay.h +++ b/indra/newview/llviewerdisplay.h @@ -33,8 +33,13 @@  #define LL_LLVIEWERDISPLAY_H  void display_startup(); +void display_cleanup(); -extern BOOL gDisplaySwapBuffers; +void display(BOOL rebuild = TRUE, F32 zoom_factor = 1.f, int subfield = 0); +extern BOOL gDisplaySwapBuffers; +extern BOOL	gTeleportDisplay; +extern LLFrameTimer	gTeleportDisplayTimer; +extern BOOL			gForceRenderLandFence;  #endif // LL_LLVIEWERDISPLAY_H diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index b43646541b..43e8589176 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -41,7 +41,6 @@  #include "llinventorymodel.h"  #include "llnotify.h"  #include "llimview.h" -#include "viewer.h"  #include "llgesturemgr.h"  #include "llinventoryview.h" diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index c3c504f672..27e71c23c9 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -34,7 +34,7 @@  #include "llviewerwindow.h"  #include "llviewercamera.h"  #include "llviewerjoystick.h" -#include "viewer.h" +#include "llappviewer.h"  #include "llkeyboard.h"  static LLQuaternion sFlycamRotation; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index d344f687d4..c052d18f0b 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -191,7 +191,7 @@  #include "llworldmap.h"  #include "object_flags.h"  #include "pipeline.h" -#include "viewer.h" +#include "llappviewer.h"  #include "roles_constants.h"  #include "llviewerjoystick.h" @@ -218,8 +218,6 @@ LLVOAvatar* find_avatar_from_object( const LLUUID& object_id );  void handle_test_load_url(void*); -extern void disconnect_viewer(void *); -  //  // Evil hackish imported globals  // @@ -227,8 +225,6 @@ extern BOOL	gRenderLightGlows;  extern BOOL gRenderAvatar;  extern BOOL	gHideSelectedObjects;  extern BOOL gShowOverlayTitle; -extern BOOL gRandomizeFramerate; -extern BOOL gPeriodicSlowFrame;  extern BOOL gOcclusionCull;  extern BOOL gAllowSelectAvatar; @@ -408,11 +404,16 @@ void handle_claim_public_land(void*);  void handle_god_request_havok(void *);  void handle_god_request_avatar_geometry(void *);	// Hack for easy testing of new avatar geometry  void reload_personal_settings_overrides(void *); -void force_breakpoint(void *);  void reload_vertex_shader(void *);  void slow_mo_animations(void *);  void handle_disconnect_viewer(void *); +void force_error_breakpoint(void *); +void force_error_llerror(void *); +void force_error_bad_memory_access(void *); +void force_error_infinite_loop(void *); +void force_error_software_exception(void *); +  void handle_stopall(void*);  //void handle_hinge(void*);  //void handle_ptop(void*); @@ -422,6 +423,7 @@ void handle_stopall(void*);  BOOL enable_dehinge(void*);  void handle_force_delete(void*);  void print_object_info(void*); +void print_agent_nvpairs(void*);  void show_debug_menus();  void toggle_debug_menus(void*);  void toggle_map( void* user_data ); @@ -446,7 +448,6 @@ void handle_force_unlock(void*);  void handle_selected_texture_info(void*);  void handle_dump_image_list(void*); -void handle_fullscreen_debug(void*);  void handle_crash(void*);  void handle_dump_followcam(void*);  void handle_toggle_flycam(void*); @@ -1061,16 +1062,18 @@ void init_client_menu(LLMenuGL* menu)  										&menu_check_control,  										(void*)"ShowConsoleWindow")); -#ifndef LL_RELEASE_FOR_DOWNLOAD +	if(gQAMode && !gInProductionGrid)  	{  		LLMenuGL* sub = NULL;  		sub = new LLMenuGL("Debugging"); -		sub->append(new LLMenuItemCallGL("Force Breakpoint", &force_breakpoint, NULL, NULL, 'B', MASK_CONTROL | MASK_ALT)); -		sub->append(new LLMenuItemCallGL("LLError And Crash", &handle_crash)); +        sub->append(new LLMenuItemCallGL("Force Breakpoint", &force_error_breakpoint, NULL, NULL, 'B', MASK_CONTROL | MASK_ALT)); +		sub->append(new LLMenuItemCallGL("Force LLError And Crash", &force_error_llerror)); +        sub->append(new LLMenuItemCallGL("Force Bad Memory Access", &force_error_bad_memory_access)); +		sub->append(new LLMenuItemCallGL("Force Infinite Loop", &force_error_infinite_loop)); +		// *NOTE:Mani this isn't handled yet... sub->append(new LLMenuItemCallGL("Force Software Exception", &force_error_unhandled_exception));   		sub->createJumpKeys();  		menu->appendMenu(sub);  	} -#endif	  	// TomY Temporary menu item so we can test this floater  	menu->append(new LLMenuItemCheckGL("Clothing...",  @@ -2372,7 +2375,6 @@ void callback_leave_group(S32 option, void *userdata)  		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());  		msg->nextBlockFast(_PREHASH_GroupData);  		msg->addUUIDFast(_PREHASH_GroupID, gAgent.mGroupID ); -		//msg->sendReliable( gUserServer );  		gAgent.sendReliableMessage();  	}  } @@ -4689,6 +4691,24 @@ void print_object_info(void*)  	gSelectMgr->selectionDump();  } +void print_agent_nvpairs(void*) +{ +	LLViewerObject *objectp; + +	llinfos << "Agent Name Value Pairs" << llendl; + +	objectp = gObjectList.findObject(gAgentID); +	if (objectp) +	{ +		objectp->printNameValuePairs(); +	} +	else +	{ +		llinfos << "Can't find agent object" << llendl; +	} + +	llinfos << "Camera at " << gAgent.getCameraPositionGlobal() << llendl; +}  void show_debug_menus()  { @@ -5174,18 +5194,6 @@ void handle_force_unlock(void*)  	gSelectMgr->getSelection()->applyToObjects(&func);  } -// Fullscreen debug stuff -void handle_fullscreen_debug(void*) -{ -	llinfos << "Width " << gViewerWindow->getWindowWidth() << " Height " << gViewerWindow->getWindowHeight() << llendl; -	llinfos << "mouse_x_from_center(100) " << mouse_x_from_center(100) << " y " << mouse_y_from_center(100) << llendl; -} - -void handle_crash(void*) -{ -	llerrs << "This is an llerror" << llendl; -} -  class LLWorldForceSun : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) @@ -6811,13 +6819,6 @@ void reload_personal_settings_overrides(void *)  	gSavedSettings.loadFromFile(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,"overrides.xml"));  } -void force_breakpoint(void *) -{ -#if LL_WINDOWS // Forcing a breakpoint -	DebugBreak(); -#endif -} -  void reload_vertex_shader(void *)  {  	//THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought	- DaveP @@ -6994,9 +6995,33 @@ void handle_disconnect_viewer(void *)  	snprintf(message, sizeof(message), "Testing viewer disconnect");		/* Flawfinder: ignore */ -	do_disconnect(message); +	LLAppViewer::instance()->forceDisconnect(message);  } +void force_error_breakpoint(void *) +{ +    LLAppViewer::instance()->forceErrorBreakpoint(); +} + +void force_error_llerror(void *) +{ +    LLAppViewer::instance()->forceErrorLLError(); +} + +void force_error_bad_memory_access(void *) +{ +    LLAppViewer::instance()->forceErrorBadMemoryAccess(); +} + +void force_error_infinite_loop(void *) +{ +    LLAppViewer::instance()->forceErrorInifiniteLoop(); +} + +void force_error_software_exception(void *) +{ +    LLAppViewer::instance()->forceErrorSoftwareException(); +}  class LLToolsUseSelectionForGrid : public view_listener_t  { diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 97b11fde8b..ac4ac77f0c 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -52,7 +52,8 @@  #include "llviewerregion.h"  #include "llviewerstats.h"  #include "llviewerwindow.h" -#include "viewer.h"	// app_request_quit() +#include "llappviewer.h" +  // linden libraries  #include "llassetuploadresponders.h" @@ -439,7 +440,7 @@ class LLFileQuit : public view_listener_t  {  	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)  	{ -		app_user_quit(); +		LLAppViewer::instance()->userQuit();  		return true;  	}  }; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index bd959b9dea..ce3a3f1ae9 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -129,8 +129,9 @@  #include "llweb.h"  #include "llworld.h"  #include "pipeline.h" -#include "viewer.h" +#include "llappviewer.h"  #include "llfloaterworldmap.h" +#include "llviewerdisplay.h"  #include <boost/tokenizer.hpp> @@ -146,8 +147,6 @@ const F32 SIT_DISTANCE_FROM_TARGET = 0.25f;  static const F32 LOGOUT_REPLY_TIME = 3.f;	// Wait this long after LogoutReply before quitting.  extern BOOL gDebugClicks; -extern void bad_network_handler(); -  // function prototypes  void open_offer(const std::vector<LLUUID>& items, const std::string& from_name);  void friendship_offer_callback(S32 option, void* user_data); @@ -202,8 +201,8 @@ void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_  		LLMessageSystem* msg = gMessageSystem;  		msg->newMessageFast(_PREHASH_MoneyTransferRequest);  		msg->nextBlockFast(_PREHASH_AgentData); -		msg->addUUIDFast(_PREHASH_AgentID, agent_get_id()); -		msg->addUUIDFast(_PREHASH_SessionID, agent_get_session_id()); +		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); +        msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());  		msg->nextBlockFast(_PREHASH_MoneyData);  		msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID() );  		msg->addUUIDFast(_PREHASH_DestID, uuid); @@ -241,7 +240,7 @@ void process_logout_reply(LLMessageSystem* msg, void**)  	msg->getUUID("AgentData", "AgentID", agent_id);  	LLUUID session_id;  	msg->getUUID("AgentData", "SessionID", session_id); -	if((agent_id != agent_get_id()) || (session_id != agent_get_session_id())) +	if((agent_id != gAgent.getID()) || (session_id != gAgent.getSessionID()))  	{  		llwarns << "Bogus Logout Reply" << llendl;  	} @@ -278,7 +277,7 @@ void process_logout_reply(LLMessageSystem* msg, void**)  		gInventory.accountForUpdate(parents);  		gInventory.notifyObservers();  	} -	app_force_quit(NULL); +    LLAppViewer::instance()->forceQuit();  }  void process_layer_data(LLMessageSystem *mesgsys, void **user_data) @@ -782,7 +781,7 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)  				// Use the name of the last item giver, who is probably the person  				// spamming you. JC  				std::ostringstream message; -				message << gSecondLife; +				message << LLAppViewer::instance()->getSecondLifeTitle();  				if (!from_name.empty())  				{  					message << ": Items coming in too fast from " << from_name; @@ -2708,7 +2707,7 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)  			<< x << ":" << y   			<< " current pos " << gAgent.getPositionGlobal()  			<< llendl; -		do_disconnect("You were sent to an invalid region."); +		LLAppViewer::instance()->forceDisconnect("You were sent to an invalid region.");  		return;  	} @@ -2888,7 +2887,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)  	}  	// We have already requested to log out.  Don't send agent updates. -	if(gLogoutRequestSent) +	if(LLAppViewer::instance()->logoutRequestSent())  	{  		return;  	} @@ -3235,10 +3234,13 @@ void process_time_synch(LLMessageSystem *mesgsys, void **user_data)  	F32 phase;  	U64	space_time_usec; +    U32 seconds_per_day; +    U32 seconds_per_year; +  	// "SimulatorViewerTimeMessage"  	mesgsys->getU64Fast(_PREHASH_TimeInfo, _PREHASH_UsecSinceStart, space_time_usec); -	mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerDay, gSecondsPerDay); -	mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerYear, gSecondsPerYear); +	mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerDay, seconds_per_day); +	mesgsys->getU32Fast(_PREHASH_TimeInfo, _PREHASH_SecPerYear, seconds_per_year);  	// This should eventually be moved to an "UpdateHeavenlyBodies" message  	mesgsys->getF32Fast(_PREHASH_TimeInfo, _PREHASH_SunPhase, phase); @@ -3923,7 +3925,7 @@ void process_kick_user(LLMessageSystem *msg, void** /*user_data*/)  	msg->getStringFast(_PREHASH_UserInfo, _PREHASH_Reason, 2048, message); -	do_disconnect(message); +	LLAppViewer::instance()->forceDisconnect(message);  } @@ -5337,7 +5339,7 @@ void invalid_message_callback(LLMessageSystem* msg,  								   void*,  								   EMessageException exception)  { -	bad_network_handler(); +    LLAppViewer::instance()->badNetworkHandler();  }  // Please do not add more message handlers here. This file is huge. diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp index 046f1f6c4f..caa61d6418 100644 --- a/indra/newview/llviewernetwork.cpp +++ b/indra/newview/llviewernetwork.cpp @@ -34,47 +34,47 @@  #include "llviewernetwork.h" -LLUserServerData gUserServerDomainName[USERSERVER_COUNT] =  +LLGridData gGridInfo[GRID_INFO_COUNT] =   {  	{ "None", "", "", ""},  	{ "Aditi",  -	  "userserver.aditi.lindenlab.com",  +	  "util.aditi.lindenlab.com",   	  "https://login.aditi.lindenlab.com/cgi-bin/login.cgi",  	  "http://aditi-secondlife.webdev.lindenlab.com/helpers/" },  	{ "Agni",  -	  "userserver.agni.lindenlab.com",  +	  "util.agni.lindenlab.com",   	  "https://login.agni.lindenlab.com/cgi-bin/login.cgi",  	  "https://secondlife.com/helpers/" },  	{ "DMZ",   -	  "userserver.dmz.lindenlab.com",  +	  "util.dmz.lindenlab.com",   	  "https://login.dmz.lindenlab.com/cgi-bin/login.cgi",  	  "http://dmz-secondlife.webdev.lindenlab.com/helpers/" },  	{ "Siva",  -	  "userserver.siva.lindenlab.com", +	  "util.siva.lindenlab.com",  	  "https://login.siva.lindenlab.com/cgi-bin/login.cgi",  	  "http://siva-secondlife.webdev.lindenlab.com/helpers/" },  	{ "Durga", -	  "userserver.durga.lindenlab.com", +	  "util.durga.lindenlab.com",  	  "https://login.durga.lindenlab.com/cgi-bin/login.cgi",  	  "http://durga-secondlife.webdev.lindenlab.com/helpers/" },  	{ "Shakti", -	  "userserver.shakti.lindenlab.com", +	  "util.shakti.lindenlab.com",  	  "https://login.shakti.lindenlab.com/cgi-bin/login.cgi",  	  "http://shakti-secondlife.webdev.lindenlab.com/helpers/" },  	{ "Soma", -	  "userserver.soma.lindenlab.com", +	  "util.soma.lindenlab.com",  	  "https://login.soma.lindenlab.com/cgi-bin/login.cgi",  	  "http://soma-secondlife.webdev.lindenlab.com/helpers/" },  	{ "Ganga", -	  "userserver.ganga.lindenlab.com", +	  "util.ganga.lindenlab.com",  	  "https://login.ganga.lindenlab.com/cgi-bin/login.cgi",  	  "http://ganga-secondlife.webdev.lindenlab.com/helpers/" },  	{ "Vaak", -	  "userserver.vaak.lindenlab.com", +	  "util.vaak.lindenlab.com",  	  "https://login.vaak.lindenlab.com/cgi-bin/login.cgi",  	  "http://vaak-secondlife.webdev.lindenlab.com/helpers/" },  	{ "Uma", -	  "userserver.uma.lindenlab.com", +	  "util.uma.lindenlab.com",  	  "https://login.uma.lindenlab.com/cgi-bin/login.cgi",  	  "http://uma-secondlife.webdev.lindenlab.com/helpers/" },  	{ "Local",  @@ -89,10 +89,8 @@ LLUserServerData gUserServerDomainName[USERSERVER_COUNT] =  // Use this to figure out which domain name and login URI to use. -EUserServerDomain gUserServerChoice = USERSERVER_NONE; -char gUserServerName[MAX_STRING];		/* Flawfinder: ignore */ - -LLHost gUserServer; +EGridInfo gGridChoice = GRID_INFO_NONE; +char gGridName[MAX_STRING];		/* Flawfinder: ignore */  F32 gPacketDropPercentage = 0.f;  F32 gInBandwidth = 0.f; diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h index 1f73fe2967..118897aebc 100644 --- a/indra/newview/llviewernetwork.h +++ b/indra/newview/llviewernetwork.h @@ -35,26 +35,26 @@  class LLHost; -enum EUserServerDomain +enum EGridInfo  { -	USERSERVER_NONE, -	USERSERVER_ADITI, -	USERSERVER_AGNI, -	USERSERVER_DMZ, -	USERSERVER_SIVA, -	USERSERVER_DURGA, -	USERSERVER_SHAKTI, -	USERSERVER_SOMA, -	USERSERVER_GANGA, -	USERSERVER_VAAK, -	USERSERVER_UMA, -	USERSERVER_LOCAL, -	USERSERVER_OTHER, // IP address set via -user or other command line option -	USERSERVER_COUNT +	GRID_INFO_NONE, +	GRID_INFO_ADITI, +	GRID_INFO_AGNI, +	GRID_INFO_DMZ, +	GRID_INFO_SIVA, +	GRID_INFO_DURGA, +	GRID_INFO_SHAKTI, +	GRID_INFO_SOMA, +	GRID_INFO_GANGA, +	GRID_INFO_VAAK, +	GRID_INFO_UMA, +	GRID_INFO_LOCAL, +	GRID_INFO_OTHER, // IP address set via -user or other command line option +	GRID_INFO_COUNT  }; -struct LLUserServerData +struct LLGridData  {  	const char* mLabel;  	const char* mName; @@ -65,9 +65,9 @@ struct LLUserServerData  extern F32 gPacketDropPercentage;  extern F32 gInBandwidth;  extern F32 gOutBandwidth; -extern EUserServerDomain gUserServerChoice; -extern LLUserServerData gUserServerDomainName[]; -extern char gUserServerName[MAX_STRING];		/* Flawfinder: ignore */ +extern EGridInfo gGridChoice; +extern LLGridData gGridInfo[]; +extern char gGridName[MAX_STRING];		/* Flawfinder: ignore */  const S32 MAC_ADDRESS_BYTES = 6;  extern unsigned char gMACAddress[MAC_ADDRESS_BYTES];		/* Flawfinder: ignore */ diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 0c9ca0152f..4c6f27944f 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -95,13 +95,12 @@  #include "llworld.h"  #include "llui.h"  #include "pipeline.h" -#include "viewer.h" +#include "llappviewer.h"  //#define DEBUG_UPDATE_TYPE -extern BOOL		gVelocityInterpolate; -extern BOOL		gPingInterpolate; -extern U32		gFrameCount; +BOOL gVelocityInterpolate = TRUE; +BOOL gPingInterpolate = TRUE;   U32			LLViewerObject::sNumZombieObjects = 0;  S32			LLViewerObject::sNumObjects = 0; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 9ce417d0e6..b30bf7e1b8 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -692,4 +692,7 @@ public:  	virtual void updateDrawable(BOOL force_damped);  }; +extern BOOL gVelocityInterpolate; +extern BOOL gPingInterpolate; +  #endif diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 967f018f0d..38efb5de11 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -42,7 +42,6 @@  #include "llvoavatar.h"  #include "llviewerobject.h"  #include "llviewerwindow.h" -#include "viewer.h"  #include "llnetmap.h"  #include "llagent.h"  #include "pipeline.h" @@ -71,11 +70,9 @@  #endif  #include "object_flags.h" -extern BOOL gVelocityInterpolate; -extern BOOL gPingInterpolate; +#include "llappviewer.h" +  extern F32 gMinObjectDistance; -extern U32 gFrameCount; -extern LLTimer gRenderStartTime;  extern BOOL gAnimateTextures;  void dialog_refresh_all(); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 5e17ff0a57..95a1db12df 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -63,7 +63,6 @@  #include "llvocache.h"  #include "llvoclouds.h"  #include "llworld.h" -#include "viewer.h"  // Viewer object cache version, change if object update  // format changes. JC diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 96f52a1382..81c10d161c 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -37,10 +37,28 @@  #include "message.h"  #include "lltimer.h" -LLViewerStats *gViewerStats = NULL; +#include "llappviewer.h" + +#include "pipeline.h"  +#include "llviewerobjectlist.h"  +#include "llviewerimagelist.h"  +#include "lltexlayer.h" +#include "llsurface.h" +#include "llvlmanager.h" +#include "llagent.h" +#include "llviewercontrol.h" +#include "llfloatertools.h" +#include "lldebugview.h" +#include "llfasttimerview.h" +#include "llviewerregion.h" +#include "llfloaterhtmlhelp.h" +#include "llworld.h" +#include "llfeaturemanager.h" +#if LL_WINDOWS && LL_LCD_COMPILE +	#include "lllcd.h" +#endif -extern U32 gFrameCount; -extern LLTimer gRenderStartTime; +LLViewerStats *gViewerStats = NULL;  class StatAttributes  { @@ -323,3 +341,399 @@ const char *LLViewerStats::statTypeToText(EStatType type)  		return "Unknown statistic";  	}  } + +// *NOTE:Mani The following methods used to exist in viewer.cpp +// Moving them here, but not merging them into LLViewerStats yet. +void reset_statistics() +{ +	gPipeline.resetFrameStats();	// Reset per-frame statistics. +	if (LLSurface::sTextureUpdateTime) +	{ +		LLSurface::sTexelsUpdatedPerSecStat.addValue(0.001f*(LLSurface::sTexelsUpdated / LLSurface::sTextureUpdateTime)); +		LLSurface::sTexelsUpdated = 0; +		LLSurface::sTextureUpdateTime = 0.f; +	} +} + + +void output_statistics(void*) +{ +	llinfos << "Number of orphans: " << gObjectList.getOrphanCount() << llendl; +	llinfos << "Number of dead objects: " << gObjectList.mNumDeadObjects << llendl; +	llinfos << "Num images: " << gImageList.getNumImages() << llendl; +	llinfos << "Texture usage: " << LLImageGL::sGlobalTextureMemory << llendl; +	llinfos << "Texture working set: " << LLImageGL::sBoundTextureMemory << llendl; +	llinfos << "Raw usage: " << LLImageRaw::sGlobalRawMemory << llendl; +	llinfos << "Formatted usage: " << LLImageFormatted::sGlobalFormattedMemory << llendl; +	llinfos << "Zombie Viewer Objects: " << LLViewerObject::getNumZombieObjects() << llendl; +	llinfos << "Number of lights: " << gPipeline.getLightCount() << llendl; + +	llinfos << "Memory Usage:" << llendl; +	llinfos << "--------------------------------" << llendl; +	llinfos << "Pipeline:" << llendl; +	llinfos << llendl; + +#if LL_SMARTHEAP +	llinfos << "--------------------------------" << llendl; +	{ +		llinfos << "sizeof(LLVOVolume) = " << sizeof(LLVOVolume) << llendl; + +		U32 total_pool_size = 0; +		U32 total_used_size = 0; +		MEM_POOL_INFO pool_info; +		MEM_POOL_STATUS pool_status; +		U32 pool_num = 0; +		for(pool_status = MemPoolFirst( &pool_info, 1 );  +			pool_status != MEM_POOL_END;  +			pool_status = MemPoolNext( &pool_info, 1 ) ) +		{ +			llinfos << "Pool #" << pool_num << llendl; +			if( MEM_POOL_OK != pool_status ) +			{ +				llwarns << "Pool not ok" << llendl; +				continue; +			} + +			llinfos << "Pool blockSizeFS " << pool_info.blockSizeFS +				<< " pageSize " << pool_info.pageSize +				<< llendl; + +			U32 pool_count = MemPoolCount(pool_info.pool); +			llinfos << "Blocks " << pool_count << llendl; + +			U32 pool_size = MemPoolSize( pool_info.pool ); +			if( pool_size == MEM_ERROR_RET ) +			{ +				llinfos << "MemPoolSize() failed (" << pool_num << ")" << llendl; +			} +			else +			{ +				llinfos << "MemPool Size " << pool_size / 1024 << "K" << llendl; +			} + +			total_pool_size += pool_size; + +			if( !MemPoolLock( pool_info.pool ) ) +			{ +				llinfos << "MemPoolLock failed (" << pool_num << ") " << llendl; +				continue; +			} + +			U32 used_size = 0;  +			MEM_POOL_ENTRY entry; +			entry.entry = NULL; +			while( MemPoolWalk( pool_info.pool, &entry ) == MEM_POOL_OK ) +			{ +				if( entry.isInUse ) +				{ +					used_size += entry.size; +				} +			} + +			MemPoolUnlock( pool_info.pool ); + +			llinfos << "MemPool Used " << used_size/1024 << "K" << llendl; +			total_used_size += used_size; +			pool_num++; +		} +		 +		llinfos << "Total Pool Size " << total_pool_size/1024 << "K" << llendl; +		llinfos << "Total Used Size " << total_used_size/1024 << "K" << llendl; + +	} +#endif + +	llinfos << "--------------------------------" << llendl; +	llinfos << "Avatar Memory (partly overlaps with above stats):" << llendl; +	gTexStaticImageList.dumpByteCount(); +	LLVOAvatar::dumpScratchTextureByteCount(); +	LLTexLayerSetBuffer::dumpTotalByteCount(); +	LLVOAvatar::dumpTotalLocalTextureByteCount(); +	LLTexLayerParamAlpha::dumpCacheByteCount(); +	LLVOAvatar::dumpBakedStatus(); + +	llinfos << llendl; + +	llinfos << "Object counts:" << llendl; +	S32 i; +	S32 obj_counts[256]; +//	S32 app_angles[256]; +	for (i = 0; i < 256; i++) +	{ +		obj_counts[i] = 0; +	} +	for (i = 0; i < gObjectList.getNumObjects(); i++) +	{ +		LLViewerObject *objectp = gObjectList.getObject(i); +		if (objectp) +		{ +			obj_counts[objectp->getPCode()]++; +		} +	} +	for (i = 0; i < 256; i++) +	{ +		if (obj_counts[i]) +		{ +			llinfos << LLPrimitive::pCodeToString(i) << ":" << obj_counts[i] << llendl; +		} +	} +} + + +U32		gTotalLandIn = 0, gTotalLandOut = 0; +U32		gTotalWaterIn = 0, gTotalWaterOut = 0; + +F32		gAveLandCompression = 0.f, gAveWaterCompression = 0.f; +F32		gBestLandCompression = 1.f, gBestWaterCompression = 1.f; +F32		gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f; + + + +U32		gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0; +U32		gObjectBits = 0; +F32		gAvgSimPing = 0.f; + + +extern U32  gVisCompared; +extern U32  gVisTested; + +std::map<S32,LLFrameTimer> gDebugTimers; + +void update_statistics(U32 frame_count) +{ +	gTotalWorldBytes += gVLManager.getTotalBytes(); +	gTotalObjectBytes += gObjectBits / 8; +	gTotalTextureBytes += LLViewerImageList::sTextureBits / 8; + +	// make sure we have a valid time delta for this frame +	if (gFrameIntervalSeconds > 0.f) +	{ +		if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK) +		{ +			gViewerStats->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds); +		} +		else if (gAgent.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR) +		{ +			gViewerStats->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds); +		} +		else if (gFloaterTools && gFloaterTools->getVisible()) +		{ +			gViewerStats->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds); +		} +	} +	gViewerStats->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); +	gViewerStats->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail")); +	gViewerStats->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip")); +	gViewerStats->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); +#if 0 // 1.9.2 +	gViewerStats->setStat(LLViewerStats::ST_SHADER_OBJECTS, (F64)gSavedSettings.getS32("VertexShaderLevelObject")); +	gViewerStats->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar")); +	gViewerStats->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment")); +#endif +	gViewerStats->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_FRAME)); +	F64 idle_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IDLE); +	F64 network_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_NETWORK); +	gViewerStats->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs); +	gViewerStats->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs); +	gViewerStats->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IMAGE_UPDATE)); +	gViewerStats->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_REBUILD)); +	gViewerStats->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_RENDER_GEOMETRY)); +		 +	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); +	if (cdp) +	{ +		gViewerStats->mSimPingStat.addValue(cdp->getPingDelay()); +		gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1); +		gSimPingCount++; +	} +	else +	{ +		gViewerStats->mSimPingStat.addValue(10000); +	} + +	gViewerStats->mFPSStat.addValue(1); +	F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); +	gViewerStats->mLayersKBitStat.addValue(layer_bits/1024.f); +	gViewerStats->mObjectKBitStat.addValue(gObjectBits/1024.f); +	gViewerStats->mTextureKBitStat.addValue(LLViewerImageList::sTextureBits/1024.f); +	gViewerStats->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); +	gViewerStats->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); +	gTransferManager.resetTransferBitsIn(LLTCT_ASSET); + +	static S32 tex_bits_idle_count = 0; +	if (LLViewerImageList::sTextureBits == 0) +	{ +		if (++tex_bits_idle_count >= 30) +			gDebugTimers[0].pause(); +	} +	else +	{ +		tex_bits_idle_count = 0; +		gDebugTimers[0].unpause(); +	} +	 +	gViewerStats->mTexturePacketsStat.addValue(LLViewerImageList::sTexturePackets); + +	// log when the LibXUL (aka Mozilla) widget is used and opened so we can monitor framerate changes +	#if LL_LIBXUL_ENABLED +	{ +		BOOL result = gViewerHtmlHelp.getFloaterOpened(); +		gViewerStats->setStat(LLViewerStats::ST_LIBXUL_WIDGET_USED, (F64)result); +	} +	#endif + +	{ +		static F32 visible_avatar_frames = 0.f; +		static F32 avg_visible_avatars = 0; +		F32 visible_avatars = (F32)LLVOAvatar::sNumVisibleAvatars; +		if (visible_avatars > 0.f) +		{ +			visible_avatar_frames = 1.f; +			avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames; +		} +		gViewerStats->setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars); +	} +	gWorldp->updateNetStats(); +	gWorldp->requestCacheMisses(); +	 +	// Reset all of these values. +	gVLManager.resetBitCounts(); +	gObjectBits = 0; +//	gDecodedBits = 0; + +	LLViewerImageList::sTextureBits = 0; +	LLViewerImageList::sTexturePackets = 0; + +#if LL_WINDOWS && LL_LCD_COMPILE +	bool LCDenabled = gLcdScreen->Enabled(); +	gViewerStats->setStat(LLViewerStats::ST_LOGITECH_LCD, LCDenabled); +#else +	gViewerStats->setStat(LLViewerStats::ST_LOGITECH_LCD, false); +#endif +} + +class ViewerStatsResponder : public LLHTTPClient::Responder +{ +public: +    ViewerStatsResponder() { } + +    void error(U32 statusNum, const std::string& reason) +    { +		llinfos << "ViewerStatsResponder::error " << statusNum << " " +				<< reason << llendl; +    } + +    void result(const LLSD& content) +    { +		llinfos << "ViewerStatsResponder::result" << llendl; +	} +}; + +/* + * The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats. + * + * There's also a compatibility shim for the old fixed-format sim + * stats in newsim/llagentinfo.cpp:processViewerStats. + * + * If you move stats around here, make the corresponding changes in + * those locations, too. + */ +void send_stats() +{ +	// IW 9/23/02 I elected not to move this into LLViewerStats +	// because it depends on too many viewer.cpp globals. +	// Someday we may want to merge all our stats into a central place +	// but that day is not today. + +	// Only send stats if the agent is connected to a region. +	if (!gAgent.getRegion() || gNoRender) +	{ +		return; +	} + +	LLSD body; +	std::string url = gAgent.getRegion()->getCapability("ViewerStats"); + +	if (url.empty()) { +		llwarns << "Could not get ViewerStats capability" << llendl; +		return; +	} +	 +	body["session_id"] = gAgentSessionID; +	 +	LLSD &agent = body["agent"]; +	 +	time_t ltime; +	time(<ime); +	F32 run_time = F32(LLFrameTimer::getElapsedSeconds()); + +	agent["start_time"] = ltime - run_time; +	agent["run_time"] = run_time; +	// send fps only for time app spends in foreground +	agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32(); +	agent["version"] = gCurrentVersion; +	 +	agent["sim_fps"] = ((F32) gFrameCount - gSimFrames) / +		(F32) (gRenderStartTime.getElapsedTimeF32() - gSimLastTime); + +	gSimLastTime = gRenderStartTime.getElapsedTimeF32(); +	gSimFrames   = (F32) gFrameCount; + +	agent["agents_in_view"] = LLVOAvatar::sNumVisibleAvatars; +	agent["ping"] = gAvgSimPing; +	agent["meters_traveled"] = gAgent.getDistanceTraveled(); +	agent["regions_visited"] = gAgent.getRegionsVisited(); +	agent["mem_use"] = getCurrentRSS() / 1024.0; + +	LLSD &system = body["system"]; +	 +	system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB(); +	system["os"] = LLAppViewer::instance()->getOSInfo().getOSString(); +	system["cpu"] = gSysCPU.getCPUString(); + +	std::string gpu_desc = llformat( +		"%-6s Class %d ", +		gGLManager.mGLVendorShort.substr(0,6).c_str(), +		gFeatureManagerp->getGPUClass()) +		+ gFeatureManagerp->getGPUString(); + +	system["gpu"] = gpu_desc; +	system["gpu_class"] = gFeatureManagerp->getGPUClass(); +	system["gpu_vendor"] = gGLManager.mGLVendorShort; +	system["gpu_version"] = gGLManager.mDriverVersionVendorString; + +	LLSD &download = body["downloads"]; + +	download["world_kbytes"] = gTotalWorldBytes / 1024.0; +	download["object_kbytes"] = gTotalObjectBytes / 1024.0; +	download["texture_kbytes"] = gTotalTextureBytes / 1024.0; + +	LLSD &in = body["stats"]["net"]["in"]; + +	in["kbytes"] = gMessageSystem->mTotalBytesIn / 1024.0; +	in["packets"] = (S32) gMessageSystem->mPacketsIn; +	in["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsIn; +	in["savings"] = (gMessageSystem->mUncompressedBytesIn - +					 gMessageSystem->mCompressedBytesIn) / 1024.0; +	 +	LLSD &out = body["stats"]["net"]["out"]; +	 +	out["kbytes"] = gMessageSystem->mTotalBytesOut / 1024.0; +	out["packets"] = (S32) gMessageSystem->mPacketsOut; +	out["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsOut; +	out["savings"] = (gMessageSystem->mUncompressedBytesOut - +					  gMessageSystem->mCompressedBytesOut) / 1024.0; + +	LLSD &fail = body["stats"]["failures"]; + +	fail["send_packet"] = (S32) gMessageSystem->mSendPacketFailureCount; +	fail["dropped"] = (S32) gMessageSystem->mDroppedPackets; +	fail["resent"] = (S32) gMessageSystem->mResentPackets; +	fail["failed_resends"] = (S32) gMessageSystem->mFailedResendPackets; +	fail["off_circuit"] = (S32) gMessageSystem->mOffCircuitPackets; +	fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets; + +	gViewerStats->addToMessage(body); + +	LLHTTPClient::post(url, body, new ViewerStatsResponder()); +} diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h index 3c959a5350..735da59150 100644 --- a/indra/newview/llviewerstats.h +++ b/indra/newview/llviewerstats.h @@ -94,7 +94,6 @@ public:  	LLStat mSimPingStat; -	LLStat mUserserverPingStat;  	void resetStats();  public: @@ -188,4 +187,10 @@ private:  extern LLViewerStats *gViewerStats; +// The following are from (older?) statistics code found in appviewer. +void reset_statistics(); +void output_statistics(void*); +void update_statistics(U32 frame_count); + +extern std::map<S32,LLFrameTimer> gDebugTimers;  #endif // LL_LLVIEWERSTATS_H diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index 1e75e421a1..81de1eb9a8 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -58,7 +58,7 @@  #include "llmemorystream.h"  #include "llmenugl.h" -extern BOOL gPacificDaylightTime; +#include "llappviewer.h" // for gPacificDaylightTime  ///----------------------------------------------------------------------------  /// Class LLEmbeddedNotecardOpener diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 7aaf9c0652..e7e2151353 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -161,6 +161,7 @@  #include "llvieweruictrlfactory.h"  #include "lluploaddialog.h"  #include "llurldispatcher.h"		// SLURL from other app instance +#include "llvieweraudio.h"  #include "llviewercamera.h"  #include "llviewergesture.h"  #include "llviewerimagelist.h" @@ -178,7 +179,9 @@  #include "llworldmapview.h"  #include "moviemaker.h"  #include "pipeline.h" -#include "viewer.h" +#include "llappviewer.h" +#include "llurlsimstring.h" +#include "llviewerdisplay.h"  #if LL_WINDOWS  #include "llwindebug.h" @@ -240,6 +243,12 @@ BOOL			gbCapturing = FALSE;  MovieMaker		gMovieMaker;  #endif +// HUD display lines in lower right +BOOL				gDisplayWindInfo = FALSE; +BOOL				gDisplayCameraPos = FALSE; +BOOL				gDisplayNearestWater = FALSE; +BOOL				gDisplayFOV = FALSE; +  S32 CHAT_BAR_HEIGHT = 28;   S32 OVERLAY_BAR_HEIGHT = 20; @@ -1192,14 +1201,14 @@ BOOL LLViewerWindow::handleCloseRequest(LLWindow *window)  {  	// User has indicated they want to close, but we may need to ask  	// about modified documents. -	app_user_quit(); +	LLAppViewer::instance()->userQuit();  	// Don't quit immediately  	return FALSE;  }  void LLViewerWindow::handleQuit(LLWindow *window)  { -	app_force_quit(NULL); +	LLAppViewer::instance()->forceQuit();  }  void LLViewerWindow::handleResize(LLWindow *window,  S32 width,  S32 height) @@ -1315,7 +1324,7 @@ BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated)  		gAgent.clearAFK();  		if (mWindow->getFullscreen() && !mIgnoreActivate)  		{ -			if (!gQuit) +			if (!LLApp::isExiting() )  			{  				if (LLStartUp::getStartupState() >= STATE_STARTED)  				{ @@ -1505,7 +1514,7 @@ LLViewerWindow::LLViewerWindow(  		llwarns << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"  				<< llendl;  #endif -		app_force_exit(1); +        LLAppViewer::instance()->forceExit(1);  	}  	// Get the real window rect the window was created with (since there are various OS-dependent reasons why @@ -2107,7 +2116,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)  	// reshape messages.  We don't care about these, and we  	// don't want to send messages because the message system  	// may have been destructed. -	if (!gQuit) +	if (!LLApp::isExiting())  	{  		if (gNoRender)  		{ @@ -4715,9 +4724,9 @@ void LLViewerWindow::stopGL(BOOL save_state)  		llinfos << "Shutting down GL..." << llendl;  		// Pause texture decode threads (will get unpaused during main loop) -		gTextureCache->pause(); -		gImageDecodeThread->pause(); -		gTextureFetch->pause(); +		LLAppViewer::getTextureCache()->pause(); +		LLAppViewer::getImageDecodeThread()->pause(); +		LLAppViewer::getTextureFetch()->pause();  		gSky.destroyGL();  		stop_glerror(); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index fcd15974f6..faab518879 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -416,4 +416,10 @@ extern BOOL				gPickTransparent;  extern BOOL				gDebugFastUIRender;  extern S32 CHAT_BAR_HEIGHT;  + +extern BOOL			gDisplayCameraPos; +extern BOOL			gDisplayWindInfo; +extern BOOL			gDisplayNearestWater; +extern BOOL			gDisplayFOV; +  #endif diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 4905ff82b9..7a225c8a12 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -114,7 +114,7 @@  #include "llworld.h"  #include "pipeline.h"  #include "llglslshader.h" -#include "viewer.h" +#include "llappviewer.h"  #include "lscript_byteformat.h"  //#include "vtune/vtuneapi.h" @@ -1622,7 +1622,6 @@ BOOL LLVOAvatar::buildSkeleton(LLVOAvatarSkeletonInfo *info)  // LLVOAvatar::buildCharacter()  // Deferred initialization and rebuild of the avatar.  //----------------------------------------------------------------------------- -extern BOOL gPrintMessagesThisFrame;  void LLVOAvatar::buildCharacter()  {  	LLMemType mt(LLMemType::MTYPE_AVATAR); @@ -7439,7 +7438,7 @@ void LLVOAvatar::onCustomizeEnd()  		avatar->updateMeshTextures(); -		if( !gQuit ) +		if( !LLApp::isExiting())  		{  			avatar->requestLayerSetUploads();  		} diff --git a/indra/newview/llvoclouds.cpp b/indra/newview/llvoclouds.cpp index 07cfcea8bc..7a2ba609e8 100644 --- a/indra/newview/llvoclouds.cpp +++ b/indra/newview/llvoclouds.cpp @@ -49,7 +49,9 @@  #include "llvosky.h"  #include "llworld.h"  #include "pipeline.h" -#include "viewer.h" + +LLUUID gCloudTextureID = IMG_CLOUD_POOF; +  LLVOClouds::LLVOClouds(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)  :	LLAlphaObject(id, LL_VO_CLOUDS, regionp) diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index f6f7ce7d5b..cf6b13e74c 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -42,12 +42,12 @@  #include "expat/expat.h"  #include "llcallbacklist.h"  #include "llviewerregion.h" -#include "llviewernetwork.h"		// for gUserServerChoice +#include "llviewernetwork.h"		// for gGridChoice  #include "llfloateractivespeakers.h"	// for LLSpeakerMgr  #include "llbase64.h"  #include "llviewercontrol.h"  #include "llkeyboard.h" -#include "viewer.h"	// for gDisconnected, gDisableVoice +#include "llappviewer.h"	// for gDisconnected, gDisableVoice  #include "llmutelist.h"  // to check for muted avatars  #include "llagent.h"  #include "llcachename.h" @@ -1052,10 +1052,10 @@ void LLVoiceClient::userAuthorized(const std::string& firstName, const std::stri  	llinfos << "name \"" << mAccountDisplayName << "\" , ID " << agentID << llendl; -	std::string userserver = gUserServerName; -	LLString::toLower(userserver); -	if((gUserServerChoice == USERSERVER_AGNI) ||  -		((gUserServerChoice == USERSERVER_OTHER) && (userserver.find("agni") != std::string::npos))) +	std::string gridname = gGridName; +	LLString::toLower(gridname); +	if((gGridChoice == GRID_INFO_AGNI) ||  +		((gGridChoice == GRID_INFO_OTHER) && (gridname.find("agni") != std::string::npos)))  	{  		sConnectingToAgni = true;  	} diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index d3c24a6e72..b8d994d095 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -53,7 +53,6 @@  #include "llviewerregion.h"  #include "llworld.h"  #include "pipeline.h" -#include "viewer.h"		// for gSunTextureID  const S32 NUM_TILES_X = 8;  const S32 NUM_TILES_Y = 4; @@ -72,6 +71,10 @@ const LLVector2 TEX01 = LLVector2(0.f, 1.f);  const LLVector2 TEX10 = LLVector2(1.f, 0.f);  const LLVector2 TEX11 = LLVector2(1.f, 1.f); +// Exported globals +LLUUID gSunTextureID = IMG_SUN; +LLUUID gMoonTextureID = IMG_MOON; +  //static   LLColor3 LLHaze::sAirScaSeaLevel; diff --git a/indra/newview/llvosky.h b/indra/newview/llvosky.h index 4020114ce5..f3bceb0653 100644 --- a/indra/newview/llvosky.h +++ b/indra/newview/llvosky.h @@ -69,6 +69,12 @@ const F32 fsigma	= (6.f + 3.f * sigma) / (6.f-7.f*sigma);  const F64 Ndens		= 2.55e25;  const F64 Ndens2	= Ndens*Ndens; +// HACK: Allow server to change sun and moon IDs. +// I can't figure out how to pass the appropriate +// information into the LLVOSky constructor.  JC +extern LLUUID gSunTextureID; +extern LLUUID gMoonTextureID; +  LL_FORCE_INLINE LLColor3 color_div(const LLColor3 &col1, const LLColor3 &col2)  { diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 4222e843b2..b4e79109ac 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -48,9 +48,6 @@  #include "llvoavatar.h"  #include "llwearable.h" -//#include "viewer.h" -//#include "llvfs.h" -  // static  S32 LLWearable::sCurrentDefinitionVersion = 1; diff --git a/indra/newview/llwind.cpp b/indra/newview/llwind.cpp index b04299b924..96a985f694 100644 --- a/indra/newview/llwind.cpp +++ b/indra/newview/llwind.cpp @@ -48,7 +48,6 @@  // viewer  #include "noise.h"  #include "v4color.h" -#include "viewer.h"  #include "llagent.h"  #include "llworld.h" diff --git a/indra/newview/llwindebug.cpp b/indra/newview/llwindebug.cpp index b65262c15c..88ba5822eb 100644 --- a/indra/newview/llwindebug.cpp +++ b/indra/newview/llwindebug.cpp @@ -37,12 +37,8 @@  #include "llviewercontrol.h"  #include "lldir.h" -// From viewer.h -extern BOOL gInProductionGrid; +#include "llappviewer.h" -extern void (*gCrashCallback)(void); -extern void write_debug(const char *str); -extern void write_debug(const std::string &str);  // based on dbghelp.h  typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, @@ -123,7 +119,7 @@ BOOL LLWinDebug::setupExceptionHandler()  			msg += local_dll_name;  			msg += "!\n"; -			write_debug(msg.c_str()); +			LLAppViewer::instance()->writeDebug(msg.c_str());  			ok = FALSE;  		} @@ -133,7 +129,7 @@ BOOL LLWinDebug::setupExceptionHandler()  			if (!f_mdwp)  			{ -				write_debug("No MiniDumpWriteDump!\n"); +				LLAppViewer::instance()->writeDebug("No MiniDumpWriteDump!\n");  				FreeLibrary(hDll);  				hDll = NULL;  				ok = FALSE; @@ -143,25 +139,29 @@ BOOL LLWinDebug::setupExceptionHandler()  		gEmergencyMemoryReserve.reserve();  	} -	LPTOP_LEVEL_EXCEPTION_FILTER prev_filter; -	prev_filter = SetUnhandledExceptionFilter(LLWinDebug::handleException); +	// *REMOVE: LLApp now handles the exception handing.  +	//            LLAppViewerWin32 calls SetUnhandledExceptionFilter() + +	//LPTOP_LEVEL_EXCEPTION_FILTER prev_filter; +	//prev_filter = SetUnhandledExceptionFilter(LLWinDebug::handleException); + +	//if (s_first_run) +	//{ +	//	// We're fine, this is the first run. +	//	s_first_run = FALSE; +	//	return ok; +	//} +	//if (!prev_filter) +	//{ +	//	llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with NULL!" << llendl; +	//	ok = FALSE; +	//} +	//if (prev_filter != LLWinDebug::handleException) +	//{ +	//	llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with " << prev_filter << "!" << llendl; +	//	ok = FALSE; +	//} -	if (s_first_run) -	{ -		// We're fine, this is the first run. -		s_first_run = FALSE; -		return ok; -	} -	if (!prev_filter) -	{ -		llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with NULL!" << llendl; -		ok = FALSE; -	} -	if (prev_filter != LLWinDebug::handleException) -	{ -		llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with " << prev_filter << "!" << llendl; -		ok = FALSE; -	}  	return ok;  #else  	// Internal builds don't mess with exception handling. @@ -173,11 +173,11 @@ void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMAT  {  	if(f_mdwp == NULL)   	{ -		write_debug("No way to generate a minidump, no MiniDumpWriteDump function!\n"); +		LLAppViewer::instance()->writeDebug("No way to generate a minidump, no MiniDumpWriteDump function!\n");  	}  	else if(gDirUtilp == NULL)  	{ -		write_debug("No way to generate a minidump, no gDirUtilp!\n"); +		LLAppViewer::instance()->writeDebug("No way to generate a minidump, no gDirUtilp!\n");  	}  	else  	{ @@ -212,6 +212,8 @@ void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMAT  // static  LONG LLWinDebug::handleException(struct _EXCEPTION_POINTERS *exception_infop)  { +	// *NOTE:Mani - This method is no longer the initial exception handler. +	// It is called from viewer_windows_exception_handler() and other places.  	//   	// Let go of a bunch of reserved memory to give library calls etc @@ -257,15 +259,6 @@ LONG LLWinDebug::handleException(struct _EXCEPTION_POINTERS *exception_infop)  	}  	// -	// Call the newview crash callback, which will spawn the crash -	// reporter.  It may or may not spawn a dialog. -	// -	if (gCrashCallback) -	{ -		gCrashCallback(); -	} - -	//  	// At this point, we always want to exit the app.  There's no graceful  	// recovery for an unhandled exception.  	//  diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index dd3223ce78..36be05fe7f 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -56,7 +56,7 @@  #include "llvowater.h"  #include "message.h"  #include "pipeline.h" -#include "viewer.h"		// for do_disconnect() +#include "llappviewer.h"		// for do_disconnect()  //  // Globals @@ -248,7 +248,7 @@ void LLWorld::removeRegion(const LLHost &host)  		llwarns << "gFrameTimeSeconds " << gFrameTimeSeconds << llendl;  		llwarns << "Disabling region " << regionp->getName() << " that agent is in!" << llendl; -		do_disconnect("You have been disconnected from the region you were in."); +		LLAppViewer::instance()->forceDisconnect("You have been disconnected from the region you were in.");  		return;  	} diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp index 6ba10ea0a9..50c9ceeb0a 100644 --- a/indra/newview/llworldmap.cpp +++ b/indra/newview/llworldmap.cpp @@ -36,7 +36,7 @@  #include "llregionhandle.h"  #include "message.h" -#include "viewer.h"	// for gPacificDaylightTime +#include "llappviewer.h"	// for gPacificDaylightTime  #include "llagent.h"  #include "llmapresponders.h"  #include "llviewercontrol.h" diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index dc689102f3..dac693885f 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -61,7 +61,7 @@  #include "llviewerwindow.h"  #include "llworld.h"  #include "llworldmap.h" -#include "viewer.h"				// Only for constants! +#include "llappviewer.h"				// Only for constants!  #include "llglheaders.h" diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index 905e35cb22..3df2073c6a 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -39,7 +39,7 @@  #include <curl/curl.h>  #include <xmlrpc-epi/xmlrpc.h> -#include "viewer.h" +#include "llappviewer.h"  LLXMLRPCValue LLXMLRPCValue::operator[](const char* id) const  { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 758455df6a..559db5fc89 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -91,11 +91,11 @@  #include "llvotree.h"  #include "llvopartgroup.h"  #include "llworld.h" -#include "viewer.h"  #include "llcubemap.h"  #include "lldebugmessagebox.h"  #include "llglslshader.h"  #include "llviewerjoystick.h" +#include "llviewerdisplay.h"  #ifdef _DEBUG  // Debug indices is disabled for now for debug performance - djs 4/24/02 @@ -135,6 +135,8 @@ S32		gTrivialAccepts = 0;  BOOL	gRenderForSelect = FALSE; +LLPipeline gPipeline; +  //----------------------------------------  void stamp(F32 x, F32 y, F32 xs, F32 ys)  | 
