PageRenderTime 232ms CodeModel.GetById 86ms app.highlight 130ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llviewerwindow.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2155 lines | 1535 code | 363 blank | 257 comment | 167 complexity | 6b7f3bab0bbe41db25b1413e2a8947f2 MD5 | raw file
   1/** 
   2 * @file llviewerwindow.cpp
   3 * @brief Implementation of the LLViewerWindow class.
   4 *
   5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
   6 * Second Life Viewer Source Code
   7 * Copyright (C) 2010, Linden Research, Inc.
   8 * 
   9 * This library is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU Lesser General Public
  11 * License as published by the Free Software Foundation;
  12 * version 2.1 of the License only.
  13 * 
  14 * This library is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * Lesser General Public License for more details.
  18 * 
  19 * You should have received a copy of the GNU Lesser General Public
  20 * License along with this library; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  22 * 
  23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  24 * $/LicenseInfo$
  25 */
  26
  27#include "llviewerprecompiledheaders.h"
  28#include "llviewerwindow.h"
  29
  30#if LL_WINDOWS
  31#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
  32#endif
  33
  34// system library includes
  35#include <stdio.h>
  36#include <iostream>
  37#include <fstream>
  38#include <algorithm>
  39#include <boost/lambda/core.hpp>
  40
  41#include "llagent.h"
  42#include "llagentcamera.h"
  43#include "llfloaterreg.h"
  44#include "llmeshrepository.h"
  45#include "llpanellogin.h"
  46#include "llviewerkeyboard.h"
  47#include "llviewermenu.h"
  48
  49#include "llviewquery.h"
  50#include "llxmltree.h"
  51#include "llslurl.h"
  52//#include "llviewercamera.h"
  53#include "llrender.h"
  54
  55#include "llvoiceclient.h"	// for push-to-talk button handling
  56
  57//
  58// TODO: Many of these includes are unnecessary.  Remove them.
  59//
  60
  61// linden library includes
  62#include "llaudioengine.h"		// mute on minimize
  63#include "indra_constants.h"
  64#include "llassetstorage.h"
  65#include "llerrorcontrol.h"
  66#include "llfontgl.h"
  67#include "llmousehandler.h"
  68#include "llrect.h"
  69#include "llsky.h"
  70#include "llstring.h"
  71#include "llui.h"
  72#include "lluuid.h"
  73#include "llview.h"
  74#include "llxfermanager.h"
  75#include "message.h"
  76#include "object_flags.h"
  77#include "lltimer.h"
  78#include "timing.h"
  79#include "llviewermenu.h"
  80#include "lltooltip.h"
  81#include "llmediaentry.h"
  82#include "llurldispatcher.h"
  83#include "raytrace.h"
  84
  85// newview includes
  86#include "llagent.h"
  87#include "llbox.h"
  88#include "llchicletbar.h"
  89#include "llconsole.h"
  90#include "llviewercontrol.h"
  91#include "llcylinder.h"
  92#include "lldebugview.h"
  93#include "lldir.h"
  94#include "lldrawable.h"
  95#include "lldrawpoolalpha.h"
  96#include "lldrawpoolbump.h"
  97#include "lldrawpoolwater.h"
  98#include "llmaniptranslate.h"
  99#include "llface.h"
 100#include "llfeaturemanager.h"
 101#include "llfilepicker.h"
 102#include "llfirstuse.h"
 103#include "llfloater.h"
 104#include "llfloaterbuildoptions.h"
 105#include "llfloaterbuyland.h"
 106#include "llfloatercamera.h"
 107#include "llfloaterland.h"
 108#include "llfloaterinspect.h"
 109#include "llfloatermap.h"
 110#include "llfloaternamedesc.h"
 111#include "llfloaterpreference.h"
 112#include "llfloatersnapshot.h"
 113#include "llfloatertools.h"
 114#include "llfloaterworldmap.h"
 115#include "llfocusmgr.h"
 116#include "llfontfreetype.h"
 117#include "llgesturemgr.h"
 118#include "llglheaders.h"
 119#include "lltooltip.h"
 120#include "llhudmanager.h"
 121#include "llhudobject.h"
 122#include "llhudview.h"
 123#include "llimagebmp.h"
 124#include "llimagej2c.h"
 125#include "llimageworker.h"
 126#include "llkeyboard.h"
 127#include "lllineeditor.h"
 128#include "llmenugl.h"
 129#include "llmodaldialog.h"
 130#include "llmorphview.h"
 131#include "llmoveview.h"
 132#include "llnavigationbar.h"
 133#include "llpaneltopinfobar.h"
 134#include "llpopupview.h"
 135#include "llpreviewtexture.h"
 136#include "llprogressview.h"
 137#include "llresmgr.h"
 138#include "llselectmgr.h"
 139#include "llrootview.h"
 140#include "llrendersphere.h"
 141#include "llstartup.h"
 142#include "llstatusbar.h"
 143#include "llstatview.h"
 144#include "llsurface.h"
 145#include "llsurfacepatch.h"
 146#include "lltexlayer.h"
 147#include "lltextbox.h"
 148#include "lltexturecache.h"
 149#include "lltexturefetch.h"
 150#include "lltextureview.h"
 151#include "lltool.h"
 152#include "lltoolbarview.h"
 153#include "lltoolcomp.h"
 154#include "lltooldraganddrop.h"
 155#include "lltoolface.h"
 156#include "lltoolfocus.h"
 157#include "lltoolgrab.h"
 158#include "lltoolmgr.h"
 159#include "lltoolmorph.h"
 160#include "lltoolpie.h"
 161#include "lltoolselectland.h"
 162#include "lltrans.h"
 163#include "lluictrlfactory.h"
 164#include "llurldispatcher.h"		// SLURL from other app instance
 165#include "llversioninfo.h"
 166#include "llvieweraudio.h"
 167#include "llviewercamera.h"
 168#include "llviewergesture.h"
 169#include "llviewertexturelist.h"
 170#include "llviewerinventory.h"
 171#include "llviewerkeyboard.h"
 172#include "llviewermedia.h"
 173#include "llviewermediafocus.h"
 174#include "llviewermenu.h"
 175#include "llviewermessage.h"
 176#include "llviewerobjectlist.h"
 177#include "llviewerparcelmgr.h"
 178#include "llviewerregion.h"
 179#include "llviewershadermgr.h"
 180#include "llviewerstats.h"
 181#include "llvoavatarself.h"
 182#include "llvovolume.h"
 183#include "llworld.h"
 184#include "llworldmapview.h"
 185#include "pipeline.h"
 186#include "llappviewer.h"
 187#include "llviewerdisplay.h"
 188#include "llspatialpartition.h"
 189#include "llviewerjoystick.h"
 190#include "llviewernetwork.h"
 191#include "llpostprocess.h"
 192#include "llnearbychatbar.h"
 193#include "llagentui.h"
 194#include "llwearablelist.h"
 195
 196#include "llnotifications.h"
 197#include "llnotificationsutil.h"
 198#include "llnotificationmanager.h"
 199
 200#include "llfloaternotificationsconsole.h"
 201
 202#include "llnearbychat.h"
 203#include "llwindowlistener.h"
 204#include "llviewerwindowlistener.h"
 205#include "llpaneltopinfobar.h"
 206
 207#if LL_WINDOWS
 208#include <tchar.h> // For Unicode conversion methods
 209#endif
 210
 211//
 212// Globals
 213//
 214void render_ui(F32 zoom_factor = 1.f, int subfield = 0);
 215
 216extern BOOL gDebugClicks;
 217extern BOOL gDisplaySwapBuffers;
 218extern BOOL gDepthDirty;
 219extern BOOL gResizeScreenTexture;
 220
 221LLViewerWindow	*gViewerWindow = NULL;
 222
 223LLFrameTimer	gAwayTimer;
 224LLFrameTimer	gAwayTriggerTimer;
 225
 226BOOL			gShowOverlayTitle = FALSE;
 227
 228LLViewerObject*  gDebugRaycastObject = NULL;
 229LLVector3       gDebugRaycastIntersection;
 230LLVector2       gDebugRaycastTexCoord;
 231LLVector3       gDebugRaycastNormal;
 232LLVector3       gDebugRaycastBinormal;
 233S32				gDebugRaycastFaceHit;
 234LLVector3		gDebugRaycastStart;
 235LLVector3		gDebugRaycastEnd;
 236
 237// HUD display lines in lower right
 238BOOL				gDisplayWindInfo = FALSE;
 239BOOL				gDisplayCameraPos = FALSE;
 240BOOL				gDisplayFOV = FALSE;
 241BOOL				gDisplayBadge = FALSE;
 242
 243static const U8 NO_FACE = 255;
 244BOOL gQuietSnapshot = FALSE;
 245
 246static const F32 MIN_DISPLAY_SCALE = 0.75f;
 247
 248std::string	LLViewerWindow::sSnapshotBaseName;
 249std::string	LLViewerWindow::sSnapshotDir;
 250
 251std::string	LLViewerWindow::sMovieBaseName;
 252
 253class RecordToChatConsole : public LLError::Recorder, public LLSingleton<RecordToChatConsole>
 254{
 255public:
 256	virtual void recordMessage(LLError::ELevel level,
 257								const std::string& message)
 258	{
 259		//FIXME: this is NOT thread safe, and will do bad things when a warning is issued from a non-UI thread
 260
 261		// only log warnings to chat console
 262		//if (level == LLError::LEVEL_WARN)
 263		//{
 264			//LLFloaterChat* chat_floater = LLFloaterReg::findTypedInstance<LLFloaterChat>("chat");
 265			//if (chat_floater && gSavedSettings.getBOOL("WarningsAsChat"))
 266			//{
 267			//	LLChat chat;
 268			//	chat.mText = message;
 269			//	chat.mSourceType = CHAT_SOURCE_SYSTEM;
 270
 271			//	chat_floater->addChat(chat, FALSE, FALSE);
 272			//}
 273		//}
 274	}
 275};
 276
 277////////////////////////////////////////////////////////////////////////////
 278//
 279// LLDebugText
 280//
 281
 282class LLDebugText
 283{
 284private:
 285	struct Line
 286	{
 287		Line(const std::string& in_text, S32 in_x, S32 in_y) : text(in_text), x(in_x), y(in_y) {}
 288		std::string text;
 289		S32 x,y;
 290	};
 291
 292	LLViewerWindow *mWindow;
 293	
 294	typedef std::vector<Line> line_list_t;
 295	line_list_t mLineList;
 296	LLColor4 mTextColor;
 297	
 298	void addText(S32 x, S32 y, const std::string &text) 
 299	{
 300		mLineList.push_back(Line(text, x, y));
 301	}
 302	
 303	void clearText() { mLineList.clear(); }
 304	
 305public:
 306	LLDebugText(LLViewerWindow* window) : mWindow(window) {}
 307
 308	void update()
 309	{
 310		static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic") ;
 311
 312		std::string wind_vel_text;
 313		std::string wind_vector_text;
 314		std::string rwind_vel_text;
 315		std::string rwind_vector_text;
 316		std::string audio_text;
 317
 318		static const std::string beacon_particle = LLTrans::getString("BeaconParticle");
 319		static const std::string beacon_physical = LLTrans::getString("BeaconPhysical");
 320		static const std::string beacon_scripted = LLTrans::getString("BeaconScripted");
 321		static const std::string beacon_scripted_touch = LLTrans::getString("BeaconScriptedTouch");
 322		static const std::string beacon_sound = LLTrans::getString("BeaconSound");
 323		static const std::string beacon_media = LLTrans::getString("BeaconMedia");
 324		static const std::string particle_hiding = LLTrans::getString("ParticleHiding");
 325
 326		// Draw the statistics in a light gray
 327		// and in a thin font
 328		mTextColor = LLColor4( 0.86f, 0.86f, 0.86f, 1.f );
 329
 330		// Draw stuff growing up from right lower corner of screen
 331		U32 xpos = mWindow->getWorldViewWidthScaled() - 350;
 332		U32 ypos = 64;
 333		const U32 y_inc = 20;
 334
 335		clearText();
 336		
 337		if (gSavedSettings.getBOOL("DebugShowTime"))
 338		{
 339			const U32 y_inc2 = 15;
 340			for (std::map<S32,LLFrameTimer>::reverse_iterator iter = gDebugTimers.rbegin();
 341				 iter != gDebugTimers.rend(); ++iter)
 342			{
 343				S32 idx = iter->first;
 344				LLFrameTimer& timer = iter->second;
 345				F32 time = timer.getElapsedTimeF32();
 346				S32 hours = (S32)(time / (60*60));
 347				S32 mins = (S32)((time - hours*(60*60)) / 60);
 348				S32 secs = (S32)((time - hours*(60*60) - mins*60));
 349				std::string label = gDebugTimerLabel[idx];
 350				if (label.empty()) label = llformat("Debug: %d", idx);
 351				addText(xpos, ypos, llformat(" %s: %d:%02d:%02d", label.c_str(), hours,mins,secs)); ypos += y_inc2;
 352			}
 353			
 354			F32 time = gFrameTimeSeconds;
 355			S32 hours = (S32)(time / (60*60));
 356			S32 mins = (S32)((time - hours*(60*60)) / 60);
 357			S32 secs = (S32)((time - hours*(60*60) - mins*60));
 358			addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc;
 359		}
 360		
 361#if LL_WINDOWS
 362		if (gSavedSettings.getBOOL("DebugShowMemory"))
 363		{
 364			addText(xpos, ypos, llformat("Memory: %d (KB)", LLMemory::getWorkingSetSize() / 1024)); 
 365			ypos += y_inc;
 366		}
 367#endif
 368
 369		if (gDisplayCameraPos)
 370		{
 371			std::string camera_view_text;
 372			std::string camera_center_text;
 373			std::string agent_view_text;
 374			std::string agent_left_text;
 375			std::string agent_center_text;
 376			std::string agent_root_center_text;
 377
 378			LLVector3d tvector; // Temporary vector to hold data for printing.
 379
 380			// Update camera center, camera view, wind info every other frame
 381			tvector = gAgent.getPositionGlobal();
 382			agent_center_text = llformat("AgentCenter  %f %f %f",
 383										 (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
 384
 385			if (isAgentAvatarValid())
 386			{
 387				tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition());
 388				agent_root_center_text = llformat("AgentRootCenter %f %f %f",
 389												  (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
 390			}
 391			else
 392			{
 393				agent_root_center_text = "---";
 394			}
 395
 396
 397			tvector = LLVector4(gAgent.getFrameAgent().getAtAxis());
 398			agent_view_text = llformat("AgentAtAxis  %f %f %f",
 399									   (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
 400
 401			tvector = LLVector4(gAgent.getFrameAgent().getLeftAxis());
 402			agent_left_text = llformat("AgentLeftAxis  %f %f %f",
 403									   (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
 404
 405			tvector = gAgentCamera.getCameraPositionGlobal();
 406			camera_center_text = llformat("CameraCenter %f %f %f",
 407										  (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
 408
 409			tvector = LLVector4(LLViewerCamera::getInstance()->getAtAxis());
 410			camera_view_text = llformat("CameraAtAxis    %f %f %f",
 411										(F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
 412		
 413			addText(xpos, ypos, agent_center_text);  ypos += y_inc;
 414			addText(xpos, ypos, agent_root_center_text);  ypos += y_inc;
 415			addText(xpos, ypos, agent_view_text);  ypos += y_inc;
 416			addText(xpos, ypos, agent_left_text);  ypos += y_inc;
 417			addText(xpos, ypos, camera_center_text);  ypos += y_inc;
 418			addText(xpos, ypos, camera_view_text);  ypos += y_inc;
 419		}
 420
 421		if (gDisplayWindInfo)
 422		{
 423			wind_vel_text = llformat("Wind velocity %.2f m/s", gWindVec.magVec());
 424			wind_vector_text = llformat("Wind vector   %.2f %.2f %.2f", gWindVec.mV[0], gWindVec.mV[1], gWindVec.mV[2]);
 425			rwind_vel_text = llformat("RWind vel %.2f m/s", gRelativeWindVec.magVec());
 426			rwind_vector_text = llformat("RWind vec   %.2f %.2f %.2f", gRelativeWindVec.mV[0], gRelativeWindVec.mV[1], gRelativeWindVec.mV[2]);
 427
 428			addText(xpos, ypos, wind_vel_text);  ypos += y_inc;
 429			addText(xpos, ypos, wind_vector_text);  ypos += y_inc;
 430			addText(xpos, ypos, rwind_vel_text);  ypos += y_inc;
 431			addText(xpos, ypos, rwind_vector_text);  ypos += y_inc;
 432		}
 433		if (gDisplayWindInfo)
 434		{
 435			if (gAudiop)
 436			{
 437				audio_text= llformat("Audio for wind: %d", gAudiop->isWindEnabled());
 438			}
 439			addText(xpos, ypos, audio_text);  ypos += y_inc;
 440		}
 441		if (gDisplayFOV)
 442		{
 443			addText(xpos, ypos, llformat("FOV: %2.1f deg", RAD_TO_DEG * LLViewerCamera::getInstance()->getView()));
 444			ypos += y_inc;
 445		}
 446		if (gDisplayBadge)
 447		{
 448			addText(xpos, ypos+(y_inc/2), llformat("Hippos!", RAD_TO_DEG * LLViewerCamera::getInstance()->getView()));
 449			ypos += y_inc * 2;
 450		}
 451		
 452		/*if (LLViewerJoystick::getInstance()->getOverrideCamera())
 453		{
 454			addText(xpos + 200, ypos, llformat("Flycam"));
 455			ypos += y_inc;
 456		}*/
 457		
 458		if (gSavedSettings.getBOOL("DebugShowRenderInfo"))
 459		{
 460			if (gPipeline.getUseVertexShaders() == 0)
 461			{
 462				addText(xpos, ypos, "Shaders Disabled");
 463				ypos += y_inc;
 464			}
 465
 466			if (gGLManager.mHasATIMemInfo)
 467			{
 468				S32 meminfo[4];
 469				glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
 470
 471				addText(xpos, ypos, llformat("%.2f MB Texture Memory Free", meminfo[0]/1024.f));
 472				ypos += y_inc;
 473
 474				if (gGLManager.mHasVertexBufferObject)
 475				{
 476					glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, meminfo);
 477					addText(xpos, ypos, llformat("%.2f MB VBO Memory Free", meminfo[0]/1024.f));
 478					ypos += y_inc;
 479				}
 480			}
 481			else if (gGLManager.mHasNVXMemInfo)
 482			{
 483				S32 free_memory;
 484				glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
 485				addText(xpos, ypos, llformat("%.2f MB Video Memory Free", free_memory/1024.f));
 486				ypos += y_inc;
 487			}
 488
 489			//show streaming cost/triangle count of known prims in current region OR selection
 490			{
 491				F32 cost = 0.f;
 492				S32 count = 0;
 493				S32 vcount = 0;
 494				S32 object_count = 0;
 495				S32 total_bytes = 0;
 496				S32 visible_bytes = 0;
 497
 498				const char* label = "Region";
 499				if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 0)
 500				{ //region
 501					LLViewerRegion* region = gAgent.getRegion();
 502					if (region)
 503					{
 504						for (U32 i = 0; i < gObjectList.getNumObjects(); ++i)
 505						{
 506							LLViewerObject* object = gObjectList.getObject(i);
 507							if (object && 
 508								object->getRegion() == region &&
 509								object->getVolume())
 510							{
 511								object_count++;
 512								S32 bytes = 0;	
 513								S32 visible = 0;
 514								cost += object->getStreamingCost(&bytes, &visible);
 515								S32 vt = 0;
 516								count += object->getTriangleCount(&vt);
 517								vcount += vt;
 518								total_bytes += bytes;
 519								visible_bytes += visible;
 520							}
 521						}
 522					}
 523				}
 524				else
 525				{
 526					label = "Selection";
 527					cost = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectStreamingCost(&total_bytes, &visible_bytes);
 528					count = LLSelectMgr::getInstance()->getSelection()->getSelectedObjectTriangleCount(&vcount);
 529					object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
 530				}
 531					
 532				addText(xpos,ypos, llformat("%s streaming cost: %.1f", label, cost));
 533				ypos += y_inc;
 534
 535				addText(xpos, ypos, llformat("    %.3f KTris, %.3f KVerts, %.1f/%.1f KB, %d objects",
 536										count/1000.f, vcount/1000.f, visible_bytes/1024.f, total_bytes/1024.f, object_count));
 537				ypos += y_inc;
 538			
 539			}
 540
 541			addText(xpos, ypos, llformat("%d MB Vertex Data (%d MB Pooled)", LLVertexBuffer::sAllocatedBytes/(1024*1024), LLVBOPool::sBytesPooled/(1024*1024)));
 542			ypos += y_inc;
 543
 544			addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount));
 545			ypos += y_inc;
 546
 547			addText(xpos, ypos, llformat("%d Mapped Buffers", LLVertexBuffer::sMappedCount));
 548			ypos += y_inc;
 549
 550			addText(xpos, ypos, llformat("%d Vertex Buffer Binds", LLVertexBuffer::sBindCount));
 551			ypos += y_inc;
 552
 553			addText(xpos, ypos, llformat("%d Vertex Buffer Sets", LLVertexBuffer::sSetCount));
 554			ypos += y_inc;
 555
 556			addText(xpos, ypos, llformat("%d Texture Binds", LLImageGL::sBindCount));
 557			ypos += y_inc;
 558
 559			addText(xpos, ypos, llformat("%d Unique Textures", LLImageGL::sUniqueCount));
 560			ypos += y_inc;
 561
 562			addText(xpos, ypos, llformat("%d Render Calls", gPipeline.mBatchCount));
 563            ypos += y_inc;
 564
 565			addText(xpos, ypos, llformat("%d Matrix Ops", gPipeline.mMatrixOpCount));
 566			ypos += y_inc;
 567
 568			addText(xpos, ypos, llformat("%d Texture Matrix Ops", gPipeline.mTextureMatrixOps));
 569			ypos += y_inc;
 570
 571			gPipeline.mTextureMatrixOps = 0;
 572			gPipeline.mMatrixOpCount = 0;
 573
 574			if (gPipeline.mBatchCount > 0)
 575			{
 576				addText(xpos, ypos, llformat("Batch min/max/mean: %d/%d/%d", gPipeline.mMinBatchSize, gPipeline.mMaxBatchSize, 
 577					gPipeline.mTrianglesDrawn/gPipeline.mBatchCount));
 578
 579				gPipeline.mMinBatchSize = gPipeline.mMaxBatchSize;
 580				gPipeline.mMaxBatchSize = 0;
 581				gPipeline.mBatchCount = 0;
 582			}
 583            ypos += y_inc;
 584
 585			addText(xpos, ypos, llformat("UI Verts/Calls: %d/%d", LLRender::sUIVerts, LLRender::sUICalls));
 586			LLRender::sUICalls = LLRender::sUIVerts = 0;
 587			ypos += y_inc;
 588
 589			addText(xpos,ypos, llformat("%d/%d Nodes visible", gPipeline.mNumVisibleNodes, LLSpatialGroup::sNodeCount));
 590			
 591			ypos += y_inc;
 592
 593			if (!LLSpatialGroup::sPendingQueries.empty())
 594			{
 595				addText(xpos,ypos, llformat("%d Queries pending", LLSpatialGroup::sPendingQueries.size()));
 596				ypos += y_inc;
 597			}
 598
 599
 600			addText(xpos,ypos, llformat("%d Avatars visible", LLVOAvatar::sNumVisibleAvatars));
 601			
 602			ypos += y_inc;
 603
 604			addText(xpos,ypos, llformat("%d Lights visible", LLPipeline::sVisibleLightCount));
 605			
 606			ypos += y_inc;
 607
 608			if (gMeshRepo.meshRezEnabled())
 609			{
 610				addText(xpos, ypos, llformat("%.3f MB Mesh Data Received", LLMeshRepository::sBytesReceived/(1024.f*1024.f)));
 611				
 612				ypos += y_inc;
 613				
 614				addText(xpos, ypos, llformat("%d/%d Mesh HTTP Requests/Retries", LLMeshRepository::sHTTPRequestCount,
 615					LLMeshRepository::sHTTPRetryCount));
 616				
 617				ypos += y_inc;
 618
 619				addText(xpos, ypos, llformat("%.3f/%.3f MB Mesh Cache Read/Write ", LLMeshRepository::sCacheBytesRead/(1024.f*1024.f), LLMeshRepository::sCacheBytesWritten/(1024.f*1024.f)));
 620
 621				ypos += y_inc;
 622			}
 623
 624			LLVertexBuffer::sBindCount = LLImageGL::sBindCount = 
 625				LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount = 
 626				gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0;
 627		}
 628		if (gSavedSettings.getBOOL("DebugShowRenderMatrices"))
 629		{
 630			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLProjection[12], gGLProjection[13], gGLProjection[14], gGLProjection[15]));
 631			ypos += y_inc;
 632
 633			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLProjection[8], gGLProjection[9], gGLProjection[10], gGLProjection[11]));
 634			ypos += y_inc;
 635
 636			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLProjection[4], gGLProjection[5], gGLProjection[6], gGLProjection[7]));
 637			ypos += y_inc;
 638
 639			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLProjection[0], gGLProjection[1], gGLProjection[2], gGLProjection[3]));
 640			ypos += y_inc;
 641
 642			addText(xpos, ypos, "Projection Matrix");
 643			ypos += y_inc;
 644
 645
 646			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLModelView[12], gGLModelView[13], gGLModelView[14], gGLModelView[15]));
 647			ypos += y_inc;
 648
 649			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLModelView[8], gGLModelView[9], gGLModelView[10], gGLModelView[11]));
 650			ypos += y_inc;
 651
 652			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLModelView[4], gGLModelView[5], gGLModelView[6], gGLModelView[7]));
 653			ypos += y_inc;
 654
 655			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLModelView[0], gGLModelView[1], gGLModelView[2], gGLModelView[3]));
 656			ypos += y_inc;
 657
 658			addText(xpos, ypos, "View Matrix");
 659			ypos += y_inc;
 660		}
 661		if (gSavedSettings.getBOOL("DebugShowColor"))
 662		{
 663			U8 color[4];
 664			LLCoordGL coord = gViewerWindow->getCurrentMouse();
 665			glReadPixels(coord.mX, coord.mY, 1,1,GL_RGBA, GL_UNSIGNED_BYTE, color);
 666			addText(xpos, ypos, llformat("%d %d %d %d", color[0], color[1], color[2], color[3]));
 667			ypos += y_inc;
 668		}
 669
 670		if (gSavedSettings.getBOOL("DebugShowPrivateMem"))
 671		{
 672			LLPrivateMemoryPoolManager::getInstance()->updateStatistics() ;
 673			addText(xpos, ypos, llformat("Total Reserved(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalReservedSize / 1024));
 674			ypos += y_inc;
 675
 676			addText(xpos, ypos, llformat("Total Allocated(KB): %d", LLPrivateMemoryPoolManager::getInstance()->mTotalAllocatedSize / 1024));
 677			ypos += y_inc;
 678		}
 679
 680		// only display these messages if we are actually rendering beacons at this moment
 681		if (LLPipeline::getRenderBeacons(NULL) && LLFloaterReg::instanceVisible("beacons"))
 682		{
 683			if (LLPipeline::getRenderMOAPBeacons(NULL))
 684			{
 685				addText(xpos, ypos, "Viewing media beacons (white)");
 686				ypos += y_inc;
 687			}
 688
 689			if (LLPipeline::toggleRenderTypeControlNegated((void*)LLPipeline::RENDER_TYPE_PARTICLES))
 690			{
 691				addText(xpos, ypos, particle_hiding);
 692				ypos += y_inc;
 693			}
 694
 695			if (LLPipeline::getRenderParticleBeacons(NULL))
 696			{
 697				addText(xpos, ypos, "Viewing particle beacons (blue)");
 698				ypos += y_inc;
 699			}
 700
 701			if (LLPipeline::getRenderSoundBeacons(NULL))
 702			{
 703				addText(xpos, ypos, "Viewing sound beacons (yellow)");
 704				ypos += y_inc;
 705			}
 706
 707			if (LLPipeline::getRenderScriptedBeacons(NULL))
 708			{
 709				addText(xpos, ypos, beacon_scripted);
 710				ypos += y_inc;
 711			}
 712			else
 713				if (LLPipeline::getRenderScriptedTouchBeacons(NULL))
 714				{
 715					addText(xpos, ypos, beacon_scripted_touch);
 716					ypos += y_inc;
 717				}
 718
 719			if (LLPipeline::getRenderPhysicalBeacons(NULL))
 720			{
 721				addText(xpos, ypos, "Viewing physical object beacons (green)");
 722				ypos += y_inc;
 723			}
 724		}
 725
 726		if(log_texture_traffic)
 727		{	
 728			U32 old_y = ypos ;
 729			for(S32 i = LLViewerTexture::BOOST_NONE; i < LLViewerTexture::MAX_GL_IMAGE_CATEGORY; i++)
 730			{
 731				if(gTotalTextureBytesPerBoostLevel[i] > 0)
 732				{
 733					addText(xpos, ypos, llformat("Boost_Level %d:  %.3f MB", i, (F32)gTotalTextureBytesPerBoostLevel[i] / (1024 * 1024)));
 734					ypos += y_inc;
 735				}
 736			}
 737			if(ypos != old_y)
 738			{
 739				addText(xpos, ypos, "Network traffic for textures:");
 740				ypos += y_inc;
 741			}
 742		}				
 743
 744		if (gSavedSettings.getBOOL("DebugShowTextureInfo"))
 745		{
 746			LLViewerObject* objectp = NULL ;
 747			//objectp = = gAgentCamera.getFocusObject();
 748			
 749			LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode();
 750			if (nodep)
 751			{
 752				objectp = nodep->getObject();			
 753			}
 754			if (objectp && !objectp->isDead())
 755			{
 756				S32 num_faces = objectp->mDrawable->getNumFaces() ;
 757				
 758				for(S32 i = 0 ; i < num_faces; i++)
 759				{
 760					LLFace* facep = objectp->mDrawable->getFace(i) ;
 761					if(facep)
 762					{
 763						//addText(xpos, ypos, llformat("ts_min: %.3f ts_max: %.3f tt_min: %.3f tt_max: %.3f", facep->mTexExtents[0].mV[0], facep->mTexExtents[1].mV[0],
 764						//		facep->mTexExtents[0].mV[1], facep->mTexExtents[1].mV[1]));
 765						//ypos += y_inc;
 766						
 767						addText(xpos, ypos, llformat("v_size: %.3f:  p_size: %.3f", facep->getVirtualSize(), facep->getPixelArea()));
 768						ypos += y_inc;
 769						
 770						//const LLTextureEntry *tep = facep->getTextureEntry();
 771						//if(tep)
 772						//{
 773						//	addText(xpos, ypos, llformat("scale_s: %.3f:  scale_t: %.3f", tep->mScaleS, tep->mScaleT)) ;
 774						//	ypos += y_inc;
 775						//}
 776						
 777						LLViewerTexture* tex = facep->getTexture() ;
 778						if(tex)
 779						{
 780							addText(xpos, ypos, llformat("ID: %s v_size: %.3f", tex->getID().asString().c_str(), tex->getMaxVirtualSize()));
 781							ypos += y_inc;
 782						}
 783					}
 784				}
 785			}
 786		}
 787	}
 788
 789	void draw()
 790	{
 791		for (line_list_t::iterator iter = mLineList.begin();
 792			 iter != mLineList.end(); ++iter)
 793		{
 794			const Line& line = *iter;
 795			LLFontGL::getFontMonospace()->renderUTF8(line.text, 0, (F32)line.x, (F32)line.y, mTextColor,
 796											 LLFontGL::LEFT, LLFontGL::TOP,
 797											 LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
 798		}
 799		mLineList.clear();
 800	}
 801
 802};
 803
 804void LLViewerWindow::updateDebugText()
 805{
 806	mDebugText->update();
 807}
 808
 809////////////////////////////////////////////////////////////////////////////
 810//
 811// LLViewerWindow
 812//
 813
 814LLViewerWindow::Params::Params()
 815:	title("title"),
 816	name("name"),
 817	x("x"),
 818	y("y"),
 819	width("width"),
 820	height("height"),
 821	min_width("min_width"),
 822	min_height("min_height"),
 823	fullscreen("fullscreen", false),
 824	ignore_pixel_depth("ignore_pixel_depth", false)
 825{}
 826
 827
 828BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window,  LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
 829{
 830	const char* buttonname = "";
 831	const char* buttonstatestr = "";
 832	S32 x = pos.mX;
 833	S32 y = pos.mY;
 834	x = llround((F32)x / mDisplayScale.mV[VX]);
 835	y = llround((F32)y / mDisplayScale.mV[VY]);
 836
 837	// only send mouse clicks to UI if UI is visible
 838	if(gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
 839	{	
 840
 841		if (down)
 842		{
 843			buttonstatestr = "down" ;
 844		}
 845		else
 846		{
 847			buttonstatestr = "up" ;
 848		}
 849		
 850		switch (clicktype)
 851		{
 852		case LLMouseHandler::CLICK_LEFT:
 853			mLeftMouseDown = down;
 854			buttonname = "Left";
 855			break;
 856		case LLMouseHandler::CLICK_RIGHT:
 857			mRightMouseDown = down;
 858			buttonname = "Right";
 859			break;
 860		case LLMouseHandler::CLICK_MIDDLE:
 861			mMiddleMouseDown = down;
 862			buttonname = "Middle";
 863			break;
 864		case LLMouseHandler::CLICK_DOUBLELEFT:
 865			mLeftMouseDown = down;
 866			buttonname = "Left Double Click";
 867			break;
 868		}
 869		
 870		LLView::sMouseHandlerMessage.clear();
 871
 872		if (gMenuBarView)
 873		{
 874			// stop ALT-key access to menu
 875			gMenuBarView->resetMenuTrigger();
 876		}
 877
 878		if (gDebugClicks)
 879		{	
 880			llinfos << "ViewerWindow " << buttonname << " mouse " << buttonstatestr << " at " << x << "," << y << llendl;
 881		}
 882
 883		// Make sure we get a corresponding mouseup event, even if the mouse leaves the window
 884		if (down)
 885			mWindow->captureMouse();
 886		else
 887			mWindow->releaseMouse();
 888
 889		// Indicate mouse was active
 890		LLUI::resetMouseIdleTimer();
 891
 892		// Don't let the user move the mouse out of the window until mouse up.
 893		if( LLToolMgr::getInstance()->getCurrentTool()->clipMouseWhenDown() )
 894		{
 895			mWindow->setMouseClipping(down);
 896		}
 897
 898		LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
 899		if( mouse_captor )
 900		{
 901			S32 local_x;
 902			S32 local_y;
 903			mouse_captor->screenPointToLocal( x, y, &local_x, &local_y );
 904			if (LLView::sDebugMouseHandling)
 905			{
 906				llinfos << buttonname << " Mouse " << buttonstatestr << " handled by captor " << mouse_captor->getName() << llendl;
 907			}
 908			return mouse_captor->handleAnyMouseClick(local_x, local_y, mask, clicktype, down);
 909		}
 910
 911		// Topmost view gets a chance before the hierarchy
 912		//LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
 913		//if (top_ctrl)
 914		//{
 915		//	S32 local_x, local_y;
 916		//	top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
 917		//		if (top_ctrl->pointInView(local_x, local_y))
 918		//		{
 919		//			return top_ctrl->handleAnyMouseClick(local_x, local_y, mask, clicktype, down)	;
 920		//		}
 921		//		else
 922		//		{
 923		//		if (down)
 924		//		{
 925		//			gFocusMgr.setTopCtrl(NULL);
 926		//		}
 927		//	}
 928		//}
 929
 930		// Mark the click as handled and return if we aren't within the root view to avoid spurious bugs
 931		if( !mRootView->pointInView(x, y) )
 932		{
 933			return TRUE;
 934		}
 935		// Give the UI views a chance to process the click
 936		if( mRootView->handleAnyMouseClick(x, y, mask, clicktype, down) )
 937		{
 938			if (LLView::sDebugMouseHandling)
 939			{
 940				llinfos << buttonname << " Mouse " << buttonstatestr << " " << LLView::sMouseHandlerMessage << llendl;
 941			}
 942			return TRUE;
 943		}
 944		else if (LLView::sDebugMouseHandling)
 945		{
 946			llinfos << buttonname << " Mouse " << buttonstatestr << " not handled by view" << llendl;
 947		}
 948	}
 949
 950	// Do not allow tool manager to handle mouseclicks if we have disconnected	
 951	if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) )
 952	{
 953		return TRUE;
 954	}
 955	
 956
 957	// If we got this far on a down-click, it wasn't handled.
 958	// Up-clicks, though, are always handled as far as the OS is concerned.
 959	BOOL default_rtn = !down;
 960	return default_rtn;
 961}
 962
 963BOOL LLViewerWindow::handleMouseDown(LLWindow *window,  LLCoordGL pos, MASK mask)
 964{
 965	BOOL down = TRUE;
 966	return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
 967}
 968
 969BOOL LLViewerWindow::handleDoubleClick(LLWindow *window,  LLCoordGL pos, MASK mask)
 970{
 971	// try handling as a double-click first, then a single-click if that
 972	// wasn't handled.
 973	BOOL down = TRUE;
 974	if (handleAnyMouseClick(window, pos, mask,
 975				LLMouseHandler::CLICK_DOUBLELEFT, down))
 976	{
 977		return TRUE;
 978	}
 979	return handleMouseDown(window, pos, mask);
 980}
 981
 982BOOL LLViewerWindow::handleMouseUp(LLWindow *window,  LLCoordGL pos, MASK mask)
 983{
 984	BOOL down = FALSE;
 985	return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
 986}
 987
 988
 989BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window,  LLCoordGL pos, MASK mask)
 990{
 991	S32 x = pos.mX;
 992	S32 y = pos.mY;
 993	x = llround((F32)x / mDisplayScale.mV[VX]);
 994	y = llround((F32)y / mDisplayScale.mV[VY]);
 995
 996	BOOL down = TRUE;
 997	BOOL handle = handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down);
 998	if (handle)
 999		return handle;
1000
1001	// *HACK: this should be rolled into the composite tool logic, not
1002	// hardcoded at the top level.
1003	if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance())
1004	{
1005		// If the current tool didn't process the click, we should show
1006		// the pie menu.  This can be done by passing the event to the pie
1007		// menu tool.
1008		LLToolPie::getInstance()->handleRightMouseDown(x, y, mask);
1009		// show_context_menu( x, y, mask );
1010	}
1011
1012	return TRUE;
1013}
1014
1015BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window,  LLCoordGL pos, MASK mask)
1016{
1017	BOOL down = FALSE;
1018 	return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down);
1019}
1020
1021BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window,  LLCoordGL pos, MASK mask)
1022{
1023	BOOL down = TRUE;
1024	LLVoiceClient::getInstance()->middleMouseState(true);
1025 	handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
1026  
1027  	// Always handled as far as the OS is concerned.
1028	return TRUE;
1029}
1030
1031LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *window, LLCoordGL pos, MASK mask, LLWindowCallbacks::DragNDropAction action, std::string data)
1032{
1033	LLWindowCallbacks::DragNDropResult result = LLWindowCallbacks::DND_NONE;
1034
1035	const bool prim_media_dnd_enabled = gSavedSettings.getBOOL("PrimMediaDragNDrop");
1036	const bool slurl_dnd_enabled = gSavedSettings.getBOOL("SLURLDragNDrop");
1037	
1038	if ( prim_media_dnd_enabled || slurl_dnd_enabled )
1039	{
1040		switch(action)
1041		{
1042			// Much of the handling for these two cases is the same.
1043			case LLWindowCallbacks::DNDA_TRACK:
1044			case LLWindowCallbacks::DNDA_DROPPED:
1045			case LLWindowCallbacks::DNDA_START_TRACKING:
1046			{
1047				bool drop = (LLWindowCallbacks::DNDA_DROPPED == action);
1048					
1049				if (slurl_dnd_enabled)
1050				{
1051					LLSLURL dropped_slurl(data);
1052					if(dropped_slurl.isSpatial())
1053					{
1054						if (drop)
1055						{
1056							LLURLDispatcher::dispatch( dropped_slurl.getSLURLString(), "clicked", NULL, true );
1057							return LLWindowCallbacks::DND_MOVE;
1058						}
1059						return LLWindowCallbacks::DND_COPY;
1060					}
1061				}
1062
1063				if (prim_media_dnd_enabled)
1064				{
1065					LLPickInfo pick_info = pickImmediate( pos.mX, pos.mY,  TRUE /*BOOL pick_transparent*/ );
1066
1067					LLUUID object_id = pick_info.getObjectID();
1068					S32 object_face = pick_info.mObjectFace;
1069					std::string url = data;
1070
1071					lldebugs << "Object: picked at " << pos.mX << ", " << pos.mY << " - face = " << object_face << " - URL = " << url << llendl;
1072
1073					LLVOVolume *obj = dynamic_cast<LLVOVolume*>(static_cast<LLViewerObject*>(pick_info.getObject()));
1074				
1075					if (obj && !obj->getRegion()->getCapability("ObjectMedia").empty())
1076					{
1077						LLTextureEntry *te = obj->getTE(object_face);
1078
1079						// can modify URL if we can modify the object or we have navigate permissions
1080						bool allow_modify_url = obj->permModify() || obj->hasMediaPermission( te->getMediaData(), LLVOVolume::MEDIA_PERM_INTERACT );
1081
1082						if (te && allow_modify_url )
1083						{
1084							if (drop)
1085							{
1086								// object does NOT have media already
1087								if ( ! te->hasMedia() )
1088								{
1089									// we are allowed to modify the object
1090									if ( obj->permModify() )
1091									{
1092										// Create new media entry
1093										LLSD media_data;
1094										// XXX Should we really do Home URL too?
1095										media_data[LLMediaEntry::HOME_URL_KEY] = url;
1096										media_data[LLMediaEntry::CURRENT_URL_KEY] = url;
1097										media_data[LLMediaEntry::AUTO_PLAY_KEY] = true;
1098										obj->syncMediaData(object_face, media_data, true, true);
1099										// XXX This shouldn't be necessary, should it ?!?
1100										if (obj->getMediaImpl(object_face))
1101											obj->getMediaImpl(object_face)->navigateReload();
1102										obj->sendMediaDataUpdate();
1103
1104										result = LLWindowCallbacks::DND_COPY;
1105									}
1106								}
1107								else 
1108								// object HAS media already
1109								{
1110									// URL passes the whitelist
1111									if (te->getMediaData()->checkCandidateUrl( url ) )
1112									{
1113										// just navigate to the URL
1114										if (obj->getMediaImpl(object_face))
1115										{
1116											obj->getMediaImpl(object_face)->navigateTo(url);
1117										}
1118										else 
1119										{
1120											// This is very strange.  Navigation should
1121											// happen via the Impl, but we don't have one.
1122											// This sends it to the server, which /should/
1123											// trigger us getting it.  Hopefully.
1124											LLSD media_data;
1125											media_data[LLMediaEntry::CURRENT_URL_KEY] = url;
1126											obj->syncMediaData(object_face, media_data, true, true);
1127											obj->sendMediaDataUpdate();
1128										}
1129										result = LLWindowCallbacks::DND_LINK;
1130										
1131									}
1132								}
1133								LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
1134								mDragHoveredObject = NULL;
1135							
1136							}
1137							else 
1138							{
1139								// Check the whitelist, if there's media (otherwise just show it)
1140								if (te->getMediaData() == NULL || te->getMediaData()->checkCandidateUrl(url))
1141								{
1142									if ( obj != mDragHoveredObject)
1143									{
1144										// Highlight the dragged object
1145										LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
1146										mDragHoveredObject = obj;
1147										LLSelectMgr::getInstance()->highlightObjectOnly(mDragHoveredObject);
1148									}
1149									result = (! te->hasMedia()) ? LLWindowCallbacks::DND_COPY : LLWindowCallbacks::DND_LINK;
1150
1151								}
1152							}
1153						}
1154					}
1155				}
1156			}
1157			break;
1158			
1159			case LLWindowCallbacks::DNDA_STOP_TRACKING:
1160				// The cleanup case below will make sure things are unhilighted if necessary.
1161			break;
1162		}
1163
1164		if (prim_media_dnd_enabled &&
1165			result == LLWindowCallbacks::DND_NONE && !mDragHoveredObject.isNull())
1166		{
1167			LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
1168			mDragHoveredObject = NULL;
1169		}
1170	}
1171	
1172	return result;
1173}
1174  
1175BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window,  LLCoordGL pos, MASK mask)
1176{
1177	BOOL down = FALSE;
1178	LLVoiceClient::getInstance()->middleMouseState(false);
1179 	handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
1180  
1181  	// Always handled as far as the OS is concerned.
1182	return TRUE;
1183}
1184
1185// WARNING: this is potentially called multiple times per frame
1186void LLViewerWindow::handleMouseMove(LLWindow *window,  LLCoordGL pos, MASK mask)
1187{
1188	S32 x = pos.mX;
1189	S32 y = pos.mY;
1190
1191	x = llround((F32)x / mDisplayScale.mV[VX]);
1192	y = llround((F32)y / mDisplayScale.mV[VY]);
1193
1194	mMouseInWindow = TRUE;
1195
1196	// Save mouse point for access during idle() and display()
1197
1198	LLCoordGL mouse_point(x, y);
1199
1200	if (mouse_point != mCurrentMousePoint)
1201	{
1202		LLUI::resetMouseIdleTimer();
1203	}
1204
1205	saveLastMouse(mouse_point);
1206
1207	mWindow->showCursorFromMouseMove();
1208
1209	if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME
1210		&& !gDisconnected)
1211	{
1212		gAgent.clearAFK();
1213	}
1214}
1215
1216void LLViewerWindow::handleMouseLeave(LLWindow *window)
1217{
1218	// Note: we won't get this if we have captured the mouse.
1219	llassert( gFocusMgr.getMouseCapture() == NULL );
1220	mMouseInWindow = FALSE;
1221	LLToolTipMgr::instance().blockToolTips();
1222}
1223
1224BOOL LLViewerWindow::handleCloseRequest(LLWindow *window)
1225{
1226	// User has indicated they want to close, but we may need to ask
1227	// about modified documents.
1228	LLAppViewer::instance()->userQuit();
1229	// Don't quit immediately
1230	return FALSE;
1231}
1232
1233void LLViewerWindow::handleQuit(LLWindow *window)
1234{
1235	LLAppViewer::instance()->forceQuit();
1236}
1237
1238void LLViewerWindow::handleResize(LLWindow *window,  S32 width,  S32 height)
1239{
1240	reshape(width, height);
1241	mResDirty = true;
1242}
1243
1244// The top-level window has gained focus (e.g. via ALT-TAB)
1245void LLViewerWindow::handleFocus(LLWindow *window)
1246{
1247	gFocusMgr.setAppHasFocus(TRUE);
1248	LLModalDialog::onAppFocusGained();
1249
1250	gAgent.onAppFocusGained();
1251	LLToolMgr::getInstance()->onAppFocusGained();
1252
1253	// See if we're coming in with modifier keys held down
1254	if (gKeyboard)
1255	{
1256		gKeyboard->resetMaskKeys();
1257	}
1258
1259	// resume foreground running timer
1260	// since we artifically limit framerate when not frontmost
1261	gForegroundTime.unpause();
1262}
1263
1264// The top-level window has lost focus (e.g. via ALT-TAB)
1265void LLViewerWindow::handleFocusLost(LLWindow *window)
1266{
1267	gFocusMgr.setAppHasFocus(FALSE);
1268	//LLModalDialog::onAppFocusLost();
1269	LLToolMgr::getInstance()->onAppFocusLost();
1270	gFocusMgr.setMouseCapture( NULL );
1271
1272	if (gMenuBarView)
1273	{
1274		// stop ALT-key access to menu
1275		gMenuBarView->resetMenuTrigger();
1276	}
1277
1278	// restore mouse cursor
1279	showCursor();
1280	getWindow()->setMouseClipping(FALSE);
1281
1282	// If losing focus while keys are down, reset them.
1283	if (gKeyboard)
1284	{
1285		gKeyboard->resetKeys();
1286	}
1287
1288	// pause timer that tracks total foreground running time
1289	gForegroundTime.pause();
1290}
1291
1292
1293BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key,  MASK mask, BOOL repeated)
1294{
1295	// Let the voice chat code check for its PTT key.  Note that this never affects event processing.
1296	LLVoiceClient::getInstance()->keyDown(key, mask);
1297	
1298	if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
1299	{
1300		gAgent.clearAFK();
1301	}
1302
1303	// *NOTE: We want to interpret KEY_RETURN later when it arrives as
1304	// a Unicode char, not as a keydown.  Otherwise when client frame
1305	// rate is really low, hitting return sends your chat text before
1306	// it's all entered/processed.
1307	if (key == KEY_RETURN && mask == MASK_NONE)
1308	{
1309		return FALSE;
1310	}
1311
1312	return gViewerKeyboard.handleKey(key, mask, repeated);
1313}
1314
1315BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key,  MASK mask)
1316{
1317	// Let the voice chat code check for its PTT key.  Note that this never affects event processing.
1318	LLVoiceClient::getInstance()->keyUp(key, mask);
1319
1320	return FALSE;
1321}
1322
1323
1324void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
1325{
1326	LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
1327	return gViewerKeyboard.scanKey(key, key_down, key_up, key_level);
1328}
1329
1330
1331
1332
1333BOOL LLViewerWindow::handleActivate(LLWindow *window, BOOL activated)
1334{
1335	if (activated)
1336	{
1337		mActive = true;
1338		send_agent_resume();
1339		gAgent.clearAFK();
1340		
1341		// Unmute audio
1342		audio_update_volume();
1343	}
1344	else
1345	{
1346		mActive = false;
1347				
1348		// if the user has chosen to go Away automatically after some time, then go Away when minimizing
1349		if (gSavedSettings.getS32("AFKTimeout"))
1350		{
1351			gAgent.setAFK();
1352		}
1353		
1354		// SL-53351: Make sure we're not in mouselook when minimised, to prevent control issues
1355		if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
1356		{
1357			gAgentCamera.changeCameraToDefault();
1358		}
1359		
1360		send_agent_pause();
1361	
1362		// Mute audio
1363		audio_update_volume();
1364	}
1365	return TRUE;
1366}
1367
1368BOOL LLViewerWindow::handleActivateApp(LLWindow *window, BOOL activating)
1369{
1370	//if (!activating) gAgentCamera.changeCameraToDefault();
1371
1372	LLViewerJoystick::getInstance()->setNeedsReset(true);
1373	return FALSE;
1374}
1375
1376
1377void LLViewerWindow::handleMenuSelect(LLWindow *window,  S32 menu_item)
1378{
1379}
1380
1381
1382BOOL LLViewerWindow::handlePaint(LLWindow *window,  S32 x,  S32 y, S32 width,  S32 height)
1383{
1384	// *TODO: Enable similar information output for other platforms?  DK 2011-02-18
1385#if LL_WINDOWS
1386	if (gHeadlessClient)
1387	{
1388		HWND window_handle = (HWND)window->getPlatformWindow();
1389		PAINTSTRUCT ps; 
1390		HDC hdc; 
1391 
1392		RECT wnd_rect;
1393		wnd_rect.left = 0;
1394		wnd_rect.top = 0;
1395		wnd_rect.bottom = 200;
1396		wnd_rect.right = 500;
1397
1398		hdc = BeginPaint(window_handle, &ps); 
1399		//SetBKColor(hdc, RGB(255, 255, 255));
1400		FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255)));
1401
1402		std::string temp_str;
1403		temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f",		/* Flawfinder: ignore */
1404				LLViewerStats::getInstance()->mFPSStat.getMeanPerSec(),
1405				LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0),
1406				LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0));
1407		S32 len = temp_str.length();
1408		TextOutA(hdc, 0, 0, temp_str.c_str(), len); 
1409
1410
1411		LLVector3d pos_global = gAgent.getPositionGlobal();
1412		temp_str = llformat( "Avatar pos %6.1lf %6.1lf %6.1lf", pos_global.mdV[0], pos_global.mdV[1], pos_global.mdV[2]);
1413		len = temp_str.length();
1414		TextOutA(hdc, 0, 25, temp_str.c_str(), len); 
1415
1416		TextOutA(hdc, 0, 50, "Set \"HeadlessClient FALSE\" in settings.ini file to reenable", 61);
1417		EndPaint(window_handle, &ps); 
1418		return TRUE;
1419	}
1420#endif
1421	return FALSE;
1422}
1423
1424
1425void LLViewerWindow::handleScrollWheel(LLWindow *window,  S32 clicks)
1426{
1427	handleScrollWheel( clicks );
1428}
1429
1430void LLViewerWindow::handleWindowBlock(LLWindow *window)
1431{
1432	send_agent_pause();
1433}
1434
1435void LLViewerWindow::handleWindowUnblock(LLWindow *window)
1436{
1437	send_agent_resume();
1438}
1439
1440void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data)
1441{
1442	const S32 SLURL_MESSAGE_TYPE = 0;
1443	switch (data_type)
1444	{
1445	case SLURL_MESSAGE_TYPE:
1446		// received URL
1447		std::string url = (const char*)data;
1448		LLMediaCtrl* web = NULL;
1449		const bool trusted_browser = false;
1450		// don't treat slapps coming from external browsers as "clicks" as this would bypass throttling
1451		if (LLURLDispatcher::dispatch(url, "", web, trusted_browser))
1452		{
1453			// bring window to foreground, as it has just been "launched" from a URL
1454			mWindow->bringToFront();
1455		}
1456		break;
1457	}
1458}
1459
1460BOOL LLViewerWindow::handleTimerEvent(LLWindow *window)
1461{
1462	if (LLViewerJoystick::getInstance()->getOverrideCamera())
1463	{
1464		LLViewerJoystick::getInstance()->updateStatus();
1465		return TRUE;
1466	}
1467	return FALSE;
1468}
1469
1470BOOL LLViewerWindow::handleDeviceChange(LLWindow *window)
1471{
1472	// give a chance to use a joystick after startup (hot-plugging)
1473	if (!LLViewerJoystick::getInstance()->isJoystickInitialized() )
1474	{
1475		LLViewerJoystick::getInstance()->init(true);
1476		return TRUE;
1477	}
1478	return FALSE;
1479}
1480
1481void LLViewerWindow::handlePingWatchdog(LLWindow *window, const char * msg)
1482{
1483	LLAppViewer::instance()->pingMainloopTimeout(msg);
1484}
1485
1486
1487void LLViewerWindow::handleResumeWatchdog(LLWindow *window)
1488{
1489	LLAppViewer::instance()->resumeMainloopTimeout();
1490}
1491
1492void LLViewerWindow::handlePauseWatchdog(LLWindow *window)
1493{
1494	LLAppViewer::instance()->pauseMainloopTimeout();
1495}
1496
1497//virtual
1498std::string LLViewerWindow::translateString(const char* tag)
1499{
1500	return LLTrans::getString( std::string(tag) );
1501}
1502
1503//virtual
1504std::string LLViewerWindow::translateString(const char* tag,
1505		const std::map<std::string, std::string>& args)
1506{
1507	// LLTrans uses a special subclass of std::string for format maps,
1508	// but we must use std::map<> in these callbacks, otherwise we create
1509	// a dependency between LLWindow and LLFormatMapString.  So copy the data.
1510	LLStringUtil::format_map_t args_copy;
1511	std::map<std::string,std::string>::const_iterator it = args.begin();
1512	for ( ; it != args.end(); ++it)
1513	{
1514		args_copy[it->first] = it->second;
1515	}
1516	return LLTrans::getString( std::string(tag), args_copy);
1517}
1518
1519//
1520// Classes
1521//
1522LLViewerWindow::LLViewerWindow(const Params& p)
1523:	mWindow(NULL),
1524	mActive(true),
1525	mUIVisible(true),
1526	mWindowRectRaw(0, p.height, p.width, 0),
1527	mWindowRectScaled(0, p.height, p.width, 0),
1528	mWorldViewRectRaw(0, p.height, p.width, 0),
1529	mLeftMouseDown(FALSE),
1530	mMiddleMouseDown(FALSE),
1531	mRightMouseDown(FALSE),
1532	mMouseInWindow( FALSE ),
1533	mLastMask( MASK_NONE ),
1534	mToolStored( NULL ),
1535	mHideCursorPermanent( FALSE ),
1536	mCursorHidden(FALSE),
1537	mIgnoreActivate( FALSE ),
1538	mResDirty(false),
1539	mStatesDirty(false),
1540	mCurrResolutionIndex(0),
1541	// gKeyboard is still NULL, so it doesn't do LLWindowListener any good to
1542	// pass its value right now. Instead, pass it a nullary function that
1543	// will, when we later need it, return the value of gKeyboard.
1544	// boost::lambda::var() constructs such a functor on the fly.
1545	mWindowListener(new LLWindowListener(this, boost::lambda::var(gKeyboard))),
1546	mViewerWindowListener(new LLViewerWindowListener(this)),
1547	mProgressView(NULL)
1548{
1549	LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
1550	LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
1551
1552	LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert);
1553	LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert);
1554	LLNotifications::instance().setIgnoreAllNotifications(gSavedSettings.getBOOL("IgnoreAllNotifications"));
1555	llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl;
1556
1557	// Default to application directory.
1558	LLViewerWindow::sSnapshotBaseName = "Snapshot";
1559	LLViewerWindow::sMovieBaseName = "SLmovie";
1560	resetSnapshotLoc();
1561
1562	// create window
1563	mWindow = LLWindowManager::createWindow(this,
1564		p.title, p.name, p.x, p.y, p.width, p.height, 0,
1565		p.fullscreen, 
1566		gHeadlessClient,
1567		gSavedSettings.getBOOL("DisableVerticalSync"),
1568		!gHeadlessClient,
1569		p.ignore_pixel_depth,
1570		gSavedSettings.getBOOL("RenderDeferred") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled
1571
1572	if (!LLViewerShaderMgr::sInitialized)
1573	{ //immediately initialize shaders
1574		LLViewerShaderMgr::sInitialized = TRUE;
1575		LLViewerShaderMgr::instance()->setShaders();
1576	}
1577
1578	if (NULL == mWindow)
1579	{
1580		LLSplashScreen::update(LLTrans::getString("StartupRequireDriverUpdate"));
1581	
1582		LL_WARNS("Window") << "Failed to create window, to be shutting Down, be sure your graphics driver is updated." << llendl ;
1583
1584		ms_sleep(5000) ; //wait for 5 seconds.
1585
1586		LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
1587#if LL_LINUX || LL_SOLARIS
1588		llwarns << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly.  See README-linux.txt or README-solaris.txt for further information."
1589				<< llendl;
1590#else
1591		LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
1592				<< LL_ENDL;
1593#endif
1594        LLAppViewer::instance()->fastQuit(1);
1595	}
1596	
1597	if (!LLAppViewer::instance()->restoreErrorTrap())
1598	{
1599		LL_WARNS("Window") << " Someone took over my signal/exception handler (post createWindow)!" << LL_ENDL;
1600	}
1601
1602	const bool do_not_enforce = false;
1603	mWindow->setMinSize(p.min_width, p.min_height, do_not_enforce);  // root view not set 
1604	LLCoordScreen scr;
1605    mWindow->getSize(&scr);
1606
1607    if(p.fullscreen && ( scr.mX!=p.width || scr.mY!=p.height))
1608    {
1609		llwarns << "Fullscreen has forced us in to a different resolution now using "<<scr.mX<<" x "<<scr.mY<<llendl;
1610		gSavedSettings.setS32("FullScreenWidth",scr.mX);
1611		gSavedSettings.setS32("FullScreenHeight",scr.mY);
1612    }
1613
1614	// Get the real window rect the window was created with (since there are various OS-dependent reasons why
1615	// the size of a window or fullscreen context may have been adjusted slightly...)
1616	F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor");
1617	
1618	mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
1619	mDisplayScale *= ui_scale_factor;
1620	LLUI::setScaleFactor(mDisplayScale);
1621
1622	{
1623		LLCoordWindow size;
1624		mWindow->getSize(&size);
1625		mWindowRectRaw.set(0, size.mY, size.mX, 0);
1626		mWindowRectScaled.set(0, llround((F32)size.mY / mDisplayScale.mV[VY]), llround((F32)size.mX / mDisplayScale.mV[VX]), 0);
1627	}
1628	
1629	LLFontManager::initClass();
1630
1631	//
1632	// We want to set this stuff up BEFORE we initialize the pipeline, so we can turn off
1633	// stuff like AGP if we think that it'll crash the viewer.
1634	//
1635	LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL;
1636
1637	LLFeatureManager::getInstance()->init();
1638
1639	// Initialize OpenGL Renderer
1640	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
1641		!gGLManager.mHasVertexBufferObject)
1642	{
1643		gSavedSettings.setBOOL("RenderVBOEnable", FALSE);
1644	}
1645	LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
1646	LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ;
1647	gGL.init() ;
1648
1649	if (LLFeatureManager::getInstance()->isSafe()
1650		|| (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion())
1651		|| (gSavedSettings.getString("LastGPUString") != LLFeatureManager::getInstance()->getGPUString())
1652		|| (gSavedSettings.getBOOL("ProbeHardwareOnStartup")))
1653	{
1654		LLFeatureManager::getInstance()->applyRecommendedSettings();
1655		gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE);
1656	}
1657
1658	if (!gGLManager.mHasDepthClamp)
1659	{
1660		LL_INFOS("RenderInit") << "Missing feature GL_ARB_depth_clamp. Void water might disappear in rare cases." << LL_ENDL;
1661	}
1662	
1663	// If we crashed while initializng GL stuff last time, disable certain features
1664	if (gSavedSettings.getBOOL("RenderInitError"))
1665	{
1666		mInitAlert = "DisplaySettingsNoShaders";
1667		LLFeatureManager::getInstance()->setGraphicsLevel(0, false);
1668		gSavedSettings.setU32("RenderQualityPerformance", 0);		
1669	}
1670		
1671	// Init the image list.  Must happen after GL is initialized and before the images that
1672	// LLViewerWindow needs are requested.
1673	LLImageGL::initClass(LLViewerTexture::MAX_GL_IMAGE_CATEGORY) ;
1674	gTextureList.init();
1675	LLViewerTextureManager::init() ;
1676	gBumpImageList.init();
1677	
1678	// Init font system, but don't actually load the fonts yet
1679	// because our window isn't onscreen and they take several
1680	// seconds to parse.
1681	LLFontGL::initClass( gSavedSettings.getF32("FontScreenDPI"),
1682								mDisplayScale.mV[VX],
1683								mDisplayScale.mV[VY],
1684								gDirUtilp->getAppRODataDir(),
1685								LLUI::getXUIPaths());
1686	
1687	// Create container for all sub-views
1688	LLView::Params rvp;
1689	rvp.name("root");
1690	rvp.rect(mWindowRectScaled);
1691	rvp.mouse_opaque(false);
1692	rvp.follows.flags(FOLLOWS_NONE);
1693	mRootView = LLUICtrlFactory::create<LLRootView>(rvp);
1694	LLUI::setRootView(mRootView);
1695
1696	// Make avatar head look forward at start
1697	mCurrentMousePoint.mX = getWindowWidthScaled() / 2;
1698	mCurrentMousePoint.mY = getWindowHeightScaled() / 2;
1699
1700	gShowOverlayTitle = gSavedSettings.getBOOL("ShowOverlayTitle");
1701	mOverlayTitle = gSavedSettings.getString("OverlayTitle");
1702	// Can't have spaces in settings.ini strings, so use underscores instead and convert them.
1703	LLStringUtil::replaceChar(mOverlayTitle, '_', ' ');
1704
1705	// sync the keyboard's setting with the saved setting
1706	gSavedSettings.getControl("NumpadControl")->firePropertyChanged();
1707
1708	mDebugText = new LLDebugText(this);
1709
1710	mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
1711}
1712
1713void LLViewerWindow::initGLDefaults()
1714{
1715	gGL.setSceneBlendType(LLRender::BT_ALPHA);
1716
1717	if (!LLGLSLShader::sNoFixedFunction)
1718	{ //initialize fixed function state
1719		glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE );
1720
1721		glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,LLColor4::black.mV);
1722		glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,LLColor4::white.mV);
1723
1724		// lights for objects
1725		glShadeModel( GL_SMOOTH );
1726
1727		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
1728		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
1729	}
1730
1731	glPixelStorei(GL_PACK_ALIGNMENT,1);
1732	glPixelStorei(GL_UNPACK_ALIGNMENT,1);
1733
1734	gGL.setAmbientLightColor(LLColor4::black);
1735		
1736	glCullFace(GL_BACK);
1737
1738	// RN: Need this for translation and stretch manip.
1739	gBox.prerender();
1740}
1741
1742struct MainPanel : public LLPanel
1743{
1744};
1745
1746void LLViewerWindow::initBase()
1747{
1748	S32 height = getWindowHeightScaled();
1749	S32 width = getWindowWidthScaled();
1750
1751	LLRect full_window(0, height, width, 0);
1752
1753	////////////////////
1754	//
1755	// Set the gamma
1756	//
1757
1758	F32 gamma = gSavedSettings.getF32("RenderGamma");
1759	if (gamma != 0.0f)
1760	{
1761		getWindow()->setGamma(gamma);
1762	}
1763
1764	// Create global views
1765
1766	// Create the floater view at the start so that other views can add children to it. 
1767	// (But wait to add it as a child of the root view so that it will be in front of the 
1768	// other views.)
1769	MainPanel* main_view = new MainPanel();
1770	main_view->buildFromFile("main_view.xml");
1771	main_view->setShape(full_window);
1772	getRootView()->addChild(main_view);
1773
1774	// placeholder widget that controls where "world" is rendered
1775	mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle();
1776	mPopupView = main_view->getChild<LLPopupView>("popup_holder");
1777	mHintHolder = main_view->getChild<LLView>("hint_holder")->getHandle();
1778	mLoginPanelHolder = main_view->getChild<LLView>("login_panel_holder")->getHandle();
1779
1780	// Create the toolbar view
1781	// Get a pointer to the toolbar view holder
1782	LLPanel* panel_holder = main_view->getChild<LLPanel>("toolbar_view_holder");
1783	// Load the toolbar view from file 
1784	gToolBarView = LLUICtrlFactory::getInstance()->createFromFile<LLToolBarView>("panel_toolbar_view.xml", panel_holder, LLDefaultChildRegistry::instance());
1785	gToolBarView->setShape(panel_holder->getLocalRect());
1786	// Hide the toolbars for the moment: we'll make them visible after logging in world (see LLViewerWindow::initWorldUI())
1787	gToolBarView->setVisible(FALSE);
1788
1789	// Constrain floaters to inside the menu and status bar regions.
1790	gFloaterView = main_view->getChild<LLFloaterView>("Floater View");
1791	gFloaterView->setFloaterSnapView(main_view->getChild<LLView>("floater_snap_region")->getHandle());
1792	gSnapshotFloaterView = main_view->getChild<LLSnapshotFloaterView>("Snapshot Floater View");
1793	
1794
1795	// Console
1796	llassert( !gConsole );
1797	LLConsole::Params cp;
1798	cp.name("console");
1799	cp.max_lines(gSavedSettings.getS32("ConsoleBufferSize"));
1800	cp.rect(getChatConsoleRect());
1801	cp.persist_time(gSavedSettings.getF32("ChatPersistTime"));
1802	cp.font_size_index(gSavedSettings.getS32("ChatFontSize"));
1803	cp.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);
1804	gConsole = LLUICtrlFactory::create<LLConsole>(cp);
1805	getRootView()->addChild(gConsole);
1806
1807	// optionally forward warnings to chat console/chat floater
1808	// for qa runs and dev builds
1809#if  !LL_RELEASE_FOR_DOWNLOAD
1810	LLError::addRecorder(RecordToChatConsole::getInstance());
1811#else
1812	if(gSavedSettings.getBOOL("QAMode"))
1813	{
1814		LLError::addRecorder(RecordToChatConsole::getInstance());
1815	}
1816#endif
1817
1818	gDebugView = getRootView()->getChild<LLDebugView>("DebugView");
1819	gDebugView->init();
1820	gToolTipView = getRootView()->getChild<LLToolTipView>("tooltip view");
1821
1822	// Initialize busy response message when logged in
1823	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initBusyResponse));
1824
1825	// Add the progress bar view (startup view), which overrides everything
1826	mProgressView = getRootView()->findChild<LLProgressView>("progress_view");
1827	setShowProgress(FALSE);
1828	setProgressCancelButtonVisible(FALSE);
1829
1830	gMenuHolder = getRootView()->getChild<LLViewerMenuHolderGL>("Menu Holder");
1831
1832	LLMenuGL::sMenuContainer = gMenuHolder;
1833
1834}
1835
1836void LLViewerWindow::initWorldUI()
1837{
1838	S32 height = mRootView->getRect().getHeight();
1839	S32 width = mRootView->getRect().getWidth();
1840	LLRect full_window(0, height, width, 0);
1841
1842
1843	gIMMgr = LLIMMgr::getInstance();
1844
1845	//getRootView()->sendChildToFront(gFloaterView);
1846	//getRootView()->sendChildToFront(gSnapshotFloaterView);
1847
1848	LLPanel* chiclet_container = getRootView()->getChild<LLPanel>("chiclet_container");
1849	LLChicletBar* chiclet_bar = LLChicletBar::getInstance();
1850	chiclet_bar->setShape(chiclet_container->getLocalRect());
1851	chiclet_bar->setFollowsAll();
1852	chiclet_container->addChild(chiclet_bar);
1853	chiclet_container->setVisible(TRUE);
1854
1855	LLRect morph_view_rect = full_window;
1856	morph_view_rect.stretch( -STATUS_BAR_HEIGHT );
1857	morph_view_rect.mTop = full_window.mTop - 32;
1858	LLMorphView::Params mvp;
1859	mvp.name("MorphView");
1860	mvp.rect(morph_view_rect);
1861	mvp.visible(false);
1862	gMorphView = LLUICtrlFactory::create<LLMorphView>(mvp);
1863	getRootView()->addChild(gMorphView);
1864
1865	LLWorldMapView::initClass();
1866	
1867	// Force gFloaterWorldMap to initialize
1868	LLFloaterReg::getInstance("world_map");
1869
1870	// Force gFloaterTools to initialize
1871	LLFloaterReg::getInstance("build");
1872	LLFloaterReg::hideInstance("build");
1873
1874	// Status bar
1875	LLPanel* status_bar_container = getRootView()->getChild<LLPanel>("status_bar_container");
1876	gStatusBar = new LLStatusBar(status_bar_container->getLocalRect());
1877	gStatusBar->setFollowsAll();
1878	gStatusBar->setShape(status_bar_container->getLocalRect());
1879	// sync bg color with menu bar
1880	gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() );
1881	status_bar_container->addChildInBack(gStatusBar);
1882	status_bar_container->setVisible(TRUE);
1883
1884	// Navigation bar
1885	LLPanel* nav_bar_container = getRootView()->getChild<LLPanel>("nav_bar_container");
1886
1887	LLNavigationBar* navbar = LLNavigationBar::getInstance();
1888	navbar->setShape(nav_bar_container->getLocalRect());
1889	navbar->setBackgroundColor(gMenuBarView->getBackgroundColor().get());
1890	nav_bar_container->addChild(navbar);
1891	nav_bar_container->setVisible(TRUE);
1892	
1893	if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel"))
1894	{
1895		navbar->setVisible(FALSE);
1896	}
1897
1898	// Top Info bar
1899	LLPanel* topinfo_bar_container = getRootView()->getChild<LLPanel>("topinfo_bar_container");
1900	LLPanelTopInfoBar* topinfo_bar = LLPanelTopInfoBar::getInstance();
1901
1902	topinfo_bar->setShape(topinfo_bar_container->getLocalRect());
1903
1904	topinfo_bar_container->addChild(topinfo_bar);
1905	topinfo_bar_container->setVisible(TRUE);
1906
1907	if (!gSavedSettings.getBOOL("ShowMiniLocationPanel"))
1908	{
1909		topinfo_bar->setVisible(FALSE);
1910	}
1911
1912	if ( gHUDView == NULL )
1913	{
1914		LLRect hud_rect = full_window;
1915		hud_rect.mBottom += 50;
1916		if (gMenuBarView && gMenuBarView->isInVisibleChain())
1917		{
1918			hud_rect.mTop -= gMenuBarView->getRect().getHeight();
1919		}
1920		gHUDView = new LLHUDView(hud_rect);
1921		getRootView()->addChild(gHUDView);
1922	}
1923
1924	LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("stand_stop_flying_container");
1925	LLPanelStandStopFlying* panel_stand_stop_flying	= LLPanelStandStopFlying::getInstance();
1926	panel_ssf_container->addChild(panel_stand_stop_flying);
1927	panel_ssf_container->setVisible(TRUE);
1928
1929	// Load and make the toolbars visible
1930	// Note: we need to load the toolbars only *after* the user is logged in and IW
1931	if (gToolBarView)
1932	{
1933		gToolBarView->loadToolbars();
1934		gToolBarView->setVisible(TRUE);
1935	}
1936
1937	LLMediaCtrl* destinations = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents");
1938	if (destinations)
1939	{
1940		destinations->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
1941		std::string url = gSavedSettings.getString("DestinationGuideURL");
1942		url = LLWeb::expandURLSubstitutions(url, LLSD());
1943		destinations->navigateTo(url, "text/html");
1944	}
1945	LLMediaCtrl* avatar_picker = LLFloaterReg::getInstance("avatar")->findChild<LLMediaCtrl>("avatar_picker_contents");
1946	if (avatar_picker)
1947	{
1948		avatar_picker->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
1949		std::string url = gSavedSettings.getString("AvatarPickerURL");
1950		url = LLWeb::expandURLSubstitutions(url, LLSD());
1951		avatar_picker->navigateTo(url, "text/html");
1952	}
1953}
1954
1955// Destroy the UI
1956void LLViewerWindow::shutdownViews()
1957{
1958	// clean up warning logger
1959	LLError::removeRecorder(RecordToChatConsole::getInstance());
1960
1961	llinfos << "Warning logger is cleaned." << llendl ;
1962
1963	delete mDebugText;
1964	mDebugText = NULL;
1965	
1966	llinfos << "DebugText deleted." << llendl ;
1967
1968	// Cleanup global views
1969	if (gMorphView)
1970	{
1971		gMorphView->setVisible(FALSE);
1972	}
1973	llinfos << "Global views cleaned." << llendl ;
1974
1975	// DEV-40930: Clear sModalStack. Otherwise, any LLModalDialog left open
1976	// will crump with LL_ERRS.
1977	LLModalDialog::shutdownModals();
1978	llinfos << "LLModalDialog shut down." << llendl; 
1979
1980	// destroy the nav bar, not currently part of gViewerWindow
1981	// *TODO: Make LLNavigationBar part of gViewerWindow
1982	if (LLNavigationBar::instanceExists())
1983	{
1984		delete LLNavigationBar::getInstance();
1985	}
1986	llinfos << "LLNavigationBar destroyed." << llendl ;
1987
1988	// destroy menus after instantiating navbar above, as it needs
1989	// access to gMenuHolder
1990	cleanup_menus();
1991	llinfos << "menus destroyed." << llendl ;
1992
1993	// Delete all child views.
1994	delete mRootView;
1995	mRootView = NULL;
1996	llinfos << "RootView deleted." << llendl ;
1997
1998	// Automatically deleted as children of mRootView.  Fix the globals.
1999	gStatusBar = NULL;
2000	gIMMgr = NULL;
2001	gToolTipView = NULL;
2002
2003	gToolBarView = NULL;
2004	gFloaterView = NULL;
2005	gMorphView = NULL;
2006
2007	gHUDView = NULL;
2008}
2009
2010void LLViewerWindow::shutdownGL()
2011{
2012	//--------------------------------------------------------
2013	// Shutdown GL cleanly.  Order is very important here.
2014	//--------------------------------------------------------
2015	LLFontGL::destroyDefaultFonts();
2016	LLFontManager::cleanupClass();
2017	stop_glerror();
2018
2019	gSky.cleanup();
2020	stop_glerror();
2021
2022	LLWearableList::instance().cleanup() ;
2023
2024	gTextureList.shutdown();
2025	stop_glerror();
2026
2027	gBumpImageList.shutdown();
2028	stop_glerror();
2029
2030	LLWorldMapView::cleanupTextures();
2031
2032	llinfos << "Cleaning up pipeline" << llendl;
2033	gPipeline.cleanup();
2034	stop_glerror();
2035
2036	LLViewerTextureManager::cleanup() ;
2037	LLImageGL::cleanupClass() ;
2038
2039	llinfos << "All textures and llimagegl images are destroyed!" << llendl ;
2040
2041	llinfos << "Cleaning up select manager" << llendl;
2042	LLSelectMgr::getInstance()->cleanup();	
2043
2044	llinfos << "Stopping GL during shutdown" << llendl;
2045	stopGL(FALSE);
2046	stop_glerror();
2047
2048	gGL.shutdown();
2049
2050	LLVertexBuffer::cleanupClass();
2051
2052	llinfos << "LLVertexBuffer cleaned." << llendl ;
2053}
2054
2055// shutdownViews() and shutdownGL() need to be called first
2056LLViewerWindow::~LLViewerWindow()
2057{
2058	llinfos << "Destroying Window" << llendl;
2059	destroyWindow();
2060
2061	delete mDebugText;
2062	mDebugText = NULL;
2063}
2064
2065
2066void LLViewerWindow::setCursor( ECursorType c )
2067{
2068	mWindow->setCursor( c );
2069}
2070
2071void LLViewerWindow::showCursor()
2072{
2073	mWindow->showCursor();
2074	
2075	mCursorHidden = FALSE;
2076}
2077
2078void LLViewerWindow::hideCursor()
2079{
2080	// And hide the cursor
2081	mWindow->hideCursor();
2082
2083	mCursorHidden = TRUE;
2084}
2085
2086void LLViewerWindow::sendShapeToSim()
2087{
2088	LLMessageSystem* msg = gMessageSystem;
2089	if(!msg) return;
2090	msg->newMessageFast(_PREHASH_AgentHeightWidth);
2091	msg->nextBlockFast(_PREHASH_AgentData);
2092	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2093	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2094	msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
2095	msg->nextBlockFast(_PREHASH_HeightWidthBlock);
2096	msg->addU32Fast(_PREHASH_GenCounter, 0);
2097	U16 height16 = (U16) mWorldViewRectRaw.getHeight();
2098	U16 width16 = (U16) mWorldViewRectRaw.getWidth();
2099	msg->addU16Fast(_PREHASH_Height, height16);
2100	msg->addU16Fast(_PREHASH_Width, width16);
2101	gAgent.sendReliableMessage();
2102}
2103
2104// Must be called after window is created to set up agent
2105// camera variables and UI variables.
2106void LLViewerWindow::reshape(S32 width, S32 height)
2107{
2108	// Destroying the window at quit time generates spurious
2109	// reshape messages.  We don't care about these, and we
2110	// don't want to send messages because the message system
2111	// may have been destructed.
2112	if (!LLApp::isExiting())
2113	{
2114		gWindowResized = TRUE;
2115
2116		// update our window rectangle
2117		mWindowRectRaw.mRight = mWindowRectRaw.mLeft + width;
2118		mWindowRectRaw.mTop = mWindowRectRaw.mBottom + height;
2119
2120		//glViewport(0, 0, width, height );
2121
2122		if (height > 0)
2123		{ 
2124			LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
2125			LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
2126		}
2127
2128		calcDisplayScale();
2129	
2130		BOOL display_scale_changed = mDisplayScale != LLUI::sGLScaleFactor;
2131		LLUI::setScaleFactor(mDisplayScale);
2132
2133		// update our window rectangle
2134		mWindowRectScaled.mRight = mWindowRectScaled.mLeft + llround((F32)width / mDisplayScale.mV[VX]);
2135		mWindowRectScaled.mTop = mWindowRectScaled.mBottom + llround((F32)height / mDisplayScale.mV[VY]);
2136
2137		setup2DViewport();
2138
2139		// Inform lower views of the change
2140		// round up when converting coordinates to make sure there are no gaps at edge of window
2141		LLView::sForceReshape = display_scale_changed;
2142		mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY]));
2143		LLView::sForceReshape = FALSE;
2144
2145		// clear font width caches
2146		if (display_scale_changed)
2147		{
2148			LLHUDObject::reshapeAll();
2149		}
2150
2151		sendShapeToSim();
2152
2153		// store new settings for the mode we are in, regardless
2154		BOOL maximized = mWindow->getMaximized();
2155		gSavedSettings.setBOOL("WindowMaximized", maximized)