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