summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorSteven Bennetts <steve@lindenlab.com>2007-11-07 22:55:27 +0000
committerSteven Bennetts <steve@lindenlab.com>2007-11-07 22:55:27 +0000
commit050dad0ce35207a4ac1562175e853590ad9b7681 (patch)
treebe5dc291d2313112e5733d8c004edfe67da6fc54 /indra
parent6fd04521d720a3a4904069d10e8ed970d870ba7f (diff)
merge svn+ssh://steve@svn/svn/linden/branches/viewer-cleanup-3 -r 73026:73079
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llsd.cpp20
-rw-r--r--indra/llmessage/llcurl.cpp5
-rw-r--r--indra/llmessage/llcurl.h3
-rw-r--r--indra/llui/llbutton.cpp3
-rw-r--r--indra/llui/lltextbox.cpp43
-rw-r--r--indra/llui/lltextbox.h11
-rw-r--r--indra/newview/llagent.cpp18
-rw-r--r--indra/newview/llagentpilot.cpp4
-rw-r--r--indra/newview/llappviewer.cpp3894
-rw-r--r--indra/newview/llappviewer.h298
-rw-r--r--indra/newview/llappviewerlinux.cpp414
-rw-r--r--indra/newview/llappviewerlinux.h59
-rw-r--r--indra/newview/llappviewermacosx.cpp388
-rw-r--r--indra/newview/llappviewermacosx.h56
-rw-r--r--indra/newview/llappviewerwin32.cpp454
-rw-r--r--indra/newview/llappviewerwin32.h63
-rw-r--r--indra/newview/llassetuploadresponders.cpp1
-rw-r--r--indra/newview/llcallingcard.cpp2
-rw-r--r--indra/newview/llclassifiedinfo.cpp1
-rw-r--r--indra/newview/llcurrencyuimanager.cpp5
-rw-r--r--indra/newview/lldirpicker.cpp1
-rw-r--r--indra/newview/lldrawable.h3
-rw-r--r--indra/newview/lldrawpoolavatar.cpp2
-rw-r--r--indra/newview/lldrawpoolwater.cpp1
-rw-r--r--indra/newview/lleventinfo.cpp2
-rw-r--r--indra/newview/llfasttimerview.cpp2
-rw-r--r--indra/newview/llfeaturemanager.cpp4
-rw-r--r--indra/newview/llfirstuse.cpp2
-rw-r--r--indra/newview/llfloaterabout.cpp9
-rw-r--r--indra/newview/llfloateranimpreview.cpp1
-rw-r--r--indra/newview/llfloaterauction.cpp3
-rw-r--r--indra/newview/llfloateravatarpicker.cpp10
-rw-r--r--indra/newview/llfloaterbump.cpp2
-rw-r--r--indra/newview/llfloaterbuycurrency.cpp2
-rw-r--r--indra/newview/llfloaterbuyland.cpp4
-rw-r--r--indra/newview/llfloatercolorpicker.cpp1
-rw-r--r--indra/newview/llfloaterimagepreview.cpp1
-rw-r--r--indra/newview/llfloaterlagmeter.cpp5
-rw-r--r--indra/newview/llfloatermap.cpp4
-rw-r--r--indra/newview/llfloaterpostcard.cpp1
-rw-r--r--indra/newview/llfloaterreporter.cpp2
-rw-r--r--indra/newview/llfloatersnapshot.cpp1
-rw-r--r--indra/newview/llfloatertools.cpp3
-rw-r--r--indra/newview/llfloatertos.cpp2
-rw-r--r--indra/newview/llfloaterworldmap.cpp2
-rw-r--r--indra/newview/llfolderview.cpp2
-rw-r--r--indra/newview/llgesturemgr.cpp1
-rw-r--r--indra/newview/llglsandbox.cpp1
-rw-r--r--indra/newview/llgroupmgr.cpp16
-rw-r--r--indra/newview/llhudtext.cpp1
-rw-r--r--indra/newview/llimpanel.cpp2
-rw-r--r--indra/newview/llimview.cpp2
-rw-r--r--indra/newview/llinventorybridge.cpp1
-rw-r--r--indra/newview/llinventorymodel.cpp2
-rw-r--r--indra/newview/lllogchat.cpp2
-rw-r--r--indra/newview/llmanip.cpp1
-rw-r--r--indra/newview/llmaniprotate.cpp3
-rw-r--r--indra/newview/llmaniptranslate.cpp1
-rw-r--r--indra/newview/llmemoryview.cpp1
-rw-r--r--indra/newview/llmenucommands.cpp1
-rw-r--r--indra/newview/llmorphview.cpp1
-rw-r--r--indra/newview/llmoveview.cpp2
-rw-r--r--indra/newview/llmutelist.cpp1
-rw-r--r--indra/newview/llnetmap.cpp2
-rw-r--r--indra/newview/lloverlaybar.cpp1
-rw-r--r--indra/newview/llpanelavatar.cpp2
-rw-r--r--indra/newview/llpanelclassified.cpp4
-rw-r--r--indra/newview/llpanelcontents.cpp1
-rw-r--r--indra/newview/llpanelgroup.cpp4
-rw-r--r--indra/newview/llpanelgrouplandmoney.cpp9
-rw-r--r--indra/newview/llpanellogin.cpp65
-rw-r--r--indra/newview/llpanellogin.h3
-rw-r--r--indra/newview/llpanelobject.cpp2
-rw-r--r--indra/newview/llpanelvolume.cpp1
-rw-r--r--indra/newview/llpreviewgesture.cpp4
-rw-r--r--indra/newview/llpreviewnotecard.cpp5
-rw-r--r--indra/newview/llpreviewscript.cpp6
-rw-r--r--indra/newview/llprogressview.cpp8
-rw-r--r--indra/newview/llsky.cpp1
-rw-r--r--indra/newview/llspatialpartition.cpp2
-rw-r--r--indra/newview/llsprite.cpp1
-rw-r--r--indra/newview/llstartup.cpp170
-rw-r--r--indra/newview/llstartup.h2
-rw-r--r--indra/newview/llstatusbar.cpp2
-rw-r--r--indra/newview/llsurface.cpp6
-rw-r--r--indra/newview/lltexlayer.cpp1
-rw-r--r--indra/newview/lltexturefetch.cpp1
-rw-r--r--indra/newview/lltextureview.cpp16
-rw-r--r--indra/newview/lltoolbar.cpp1
-rw-r--r--indra/newview/lltoolbrush.cpp2
-rw-r--r--indra/newview/lltooldraganddrop.cpp1
-rw-r--r--indra/newview/lltoolfocus.cpp1
-rw-r--r--indra/newview/lltoolgrab.cpp1
-rw-r--r--indra/newview/lltoolgun.cpp1
-rw-r--r--indra/newview/lltoolmorph.cpp1
-rw-r--r--indra/newview/lltoolobjpicker.cpp1
-rw-r--r--indra/newview/lltoolplacer.cpp380
-rw-r--r--indra/newview/lltoolplacer.h7
-rw-r--r--indra/newview/lltoolselect.cpp1
-rw-r--r--indra/newview/lltoolselectland.cpp1
-rw-r--r--indra/newview/lltoolselectrect.cpp1
-rw-r--r--indra/newview/lltracker.cpp3
-rw-r--r--indra/newview/llvectorperfoptions.cpp108
-rw-r--r--indra/newview/llvectorperfoptions.h18
-rw-r--r--indra/newview/llvieweraudio.cpp215
-rw-r--r--indra/newview/llvieweraudio.h17
-rw-r--r--indra/newview/llviewercamera.h3
-rw-r--r--indra/newview/llviewercontrol.cpp4
-rw-r--r--indra/newview/llviewercontrol.h7
-rw-r--r--indra/newview/llviewerdisplay.cpp199
-rw-r--r--indra/newview/llviewerdisplay.h7
-rw-r--r--indra/newview/llviewerinventory.cpp1
-rw-r--r--indra/newview/llviewerjoystick.cpp2
-rw-r--r--indra/newview/llviewermenu.cpp89
-rw-r--r--indra/newview/llviewermenufile.cpp5
-rw-r--r--indra/newview/llviewermessage.cpp30
-rw-r--r--indra/newview/llviewernetwork.cpp28
-rw-r--r--indra/newview/llviewernetwork.h38
-rw-r--r--indra/newview/llviewerobject.cpp7
-rw-r--r--indra/newview/llviewerobject.h3
-rw-r--r--indra/newview/llviewerobjectlist.cpp7
-rw-r--r--indra/newview/llviewerregion.cpp1
-rw-r--r--indra/newview/llviewerstats.cpp420
-rw-r--r--indra/newview/llviewerstats.h7
-rw-r--r--indra/newview/llviewertexteditor.cpp2
-rw-r--r--indra/newview/llviewerwindow.cpp27
-rw-r--r--indra/newview/llviewerwindow.h6
-rw-r--r--indra/newview/llvoavatar.cpp5
-rw-r--r--indra/newview/llvoclouds.cpp4
-rw-r--r--indra/newview/llvoiceclient.cpp12
-rw-r--r--indra/newview/llvosky.cpp5
-rw-r--r--indra/newview/llvosky.h6
-rw-r--r--indra/newview/llwearable.cpp3
-rw-r--r--indra/newview/llwind.cpp1
-rw-r--r--indra/newview/llwindebug.cpp65
-rw-r--r--indra/newview/llworld.cpp4
-rw-r--r--indra/newview/llworldmap.cpp2
-rw-r--r--indra/newview/llworldmapview.cpp2
-rw-r--r--indra/newview/llxmlrpctransaction.cpp2
-rw-r--r--indra/newview/pipeline.cpp4
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, &regionp );
+ 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, &regionp );
+ BOOL success = raycastForNewObjPos( x, y, &hit_obj, &hit_face, &b_hit_land, &ray_start_region, &ray_end_region, &regionp );
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(&ltime);
+ 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)