Commits

Merov Linden committed beb6986 Merge

Pull from viewer-development

  • Participants
  • Parent commits 8f14c1c, aed94e8

Comments (0)

Files changed (178)

 54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33_2.5.0-beta2
 b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-beta3
 b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-34_2.5.0-beta3
+b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-release
+b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-31_2.5.0-release
+92e58e51776a4f8c29069b1a62ff21454d2085f0 2.6.0-start
+63a6aedfce785a6c760377bf685b2dae616797d2 2.5.1-start

doc/contributions.txt

 	VWR-24320
     VWR-24321
  	VWR-24354
+	VWR-24366
 	VWR-24519
 	SNOW-84
 	SNOW-477
 	CT-193
 Ardy Lay
 	VWR-19499
+	VWR-24917
 Argent Stonecutter
 	VWR-68
 Armin Weatherwax
 blino Nakamura
 	VWR-17
 Boroondas Gupte
+	OPEN-29
 	SNOW-278
 	SNOW-503
 	SNOW-510
 	STORM-812
 	STORM-829
 	STORM-844
+	STORM-953
+	STORM-954
+	STORM-960
 	STORM-869
+	STORM-974
+	STORM-975
+	STORM-977
+	STORM-979
+	STORM-980
+	STORM-1040
 	VWR-17801
 	VWR-24347
-	STORM-844
-	STORM-643
-	STORM-960
-	STORM-953
+	STORM-990
 Kage Pixel
 	VWR-11
 Ken March
 	STORM-467
 	STORM-844
 	STORM-643
+	STORM-954
 Vadim Bigbear
 	VWR-2681
 Vector Hastings
 	STORM-102
 	STORM-103
 	STORM-143
+	STORM-236
 	STORM-255
 	STORM-256
 	STORM-288

indra/CMakeLists.txt

   add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
 
   # llplugin testbed code (is this the right way to include it?)
-  if (NOT LINUX)
+  if (LL_TESTS AND NOT LINUX)
     add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
-  endif (NOT LINUX)
+  endif (LL_TESTS AND NOT LINUX)
 
   if (LINUX)
     add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)

indra/cmake/GoogleMock.cmake

     ${LIBS_PREBUILT_DIR}/include)
 
 if (LINUX)
+	# VWR-24366: gmock is underlinked, it needs gtest.
     set(GOOGLEMOCK_LIBRARIES 
-        gmock  
-        gtest)
+        gmock -Wl,--no-as-needed
+        gtest -Wl,--as-needed)
 elseif(WINDOWS)
     set(GOOGLEMOCK_LIBRARIES 
         gmock)

indra/cmake/LLAddBuildTest.cmake

     ${CMAKE_SOURCE_DIR}/test/test.h
     )
 
-  # Use the default flags
-  if (LINUX)
-    SET(CMAKE_EXE_LINKER_FLAGS "")
-  endif (LINUX)
-
   # start the source test executable definitions
   SET(${project}_TEST_OUTPUT "")
   FOREACH (source ${sources})

indra/cmake/run_build_test.py

-#!/usr/bin/python
+#!/usr/bin/env python
 """\
 @file   run_build_test.py
 @author Nat Goodspeed

indra/copy_win_scripts/start-client.py

 #!/usr/bin/env python
+"""\
+@file   start-client.py
+
+$LicenseInfo:firstyear=2010&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2010-2011, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+$/LicenseInfo$
+"""
 import sys, getopt
 import os
 import llstart
 #!/usr/bin/env python
-#
-# @file develop.py
-# @authors Bryan O'Sullivan, Mark Palange, Aaron Brashears
-# @brief Fire and forget script to appropriately configure cmake for SL.
-#
-# $LicenseInfo:firstyear=2007&license=viewerlgpl$
-# Second Life Viewer Source Code
-# Copyright (C) 2010, Linden Research, Inc.
-# 
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation;
-# version 2.1 of the License only.
-# 
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-# 
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-# 
-# Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-# $/LicenseInfo$
+"""\
+@file develop.py
+@authors Bryan O'Sullivan, Mark Palange, Aaron Brashears
+@brief Fire and forget script to appropriately configure cmake for SL.
+
+$LicenseInfo:firstyear=2007&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2007-2011, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+$/LicenseInfo$
+"""
 
 
 import errno

indra/lib/python/indra/util/llperformance.py

-#!/usr/bin/python
+#!/usr/bin/env python
+"""\
+@file   llperformance.py
+
+$LicenseInfo:firstyear=2010&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2010-2011, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+$/LicenseInfo$
+"""
 
 # ------------------------------------------------
 # Sim metrics utility functions.

indra/lib/python/indra/util/llversion.py

-"""@file llversion.py
-@brief Utility for parsing llcommon/llversion${server}.h
-       for the version string and channel string
-       Utility that parses hg or svn info for branch and revision
+#!/usr/bin/env python
+"""\
+@file  llversion.py
+@brief Parses llcommon/llversionserver.h and llcommon/llversionviewer.h
+       for the version string and channel string.
+       Parses hg info for branch and revision.
 
 $LicenseInfo:firstyear=2006&license=mit$
 
 $/LicenseInfo$
 """
 
-import re, sys, os, commands
+import re, sys, os, subprocess
 
 # Methods for gathering version information from
 # llversionviewer.h and llversionserver.h
 def get_server_channel():
     return get_channel('server')
 
-# Methods for gathering subversion information
-def get_svn_status_matching(regular_expression):
-    # Get the subversion info from the working source tree
-    status, output = commands.getstatusoutput('svn info %s' % get_src_root())
-    m = regular_expression.search(output)
-    if not m:
-        print >> sys.stderr, "Failed to parse svn info output, result follows:"
-        print >> sys.stderr, output
-        raise Exception, "No matching svn status in "+src_root
-    return m.group(1)
-
-def get_svn_branch():
-    branch_re = re.compile('URL: (\S+)')
-    return get_svn_status_matching(branch_re)
-
-def get_svn_revision():
-    last_rev_re = re.compile('Last Changed Rev: (\d+)')
-    return get_svn_status_matching(last_rev_re)
-
+# Methods for gathering hg information
 def get_hg_repo():
-    status, output = commands.getstatusoutput('hg showconfig paths.default')
+    child = subprocess.Popen(["hg","showconfig","paths.default"], stdout=subprocess.PIPE)
+    output, error = child.communicate()
+    status = child.returncode
     if status:
-        print >> sys.stderr, output
+        print >> sys.stderr, error
         sys.exit(1)
     if not output:
         print >> sys.stderr, 'ERROR: cannot find repo we cloned from'
     return output
 
 def get_hg_changeset():
-    # The right thing to do:
-    # status, output = commands.getstatusoutput('hg id -i')
-    # if status:
-    #     print >> sys.stderr, output
-    #    sys.exit(1)
-
-    # The temporary hack:
-    status, output = commands.getstatusoutput('hg parents --template "{rev}"')
+    # The right thing to do would be to use the *global* revision id:
+    #     "hg id -i"
+    # For the moment though, we use the parent revision:
+    child = subprocess.Popen(["hg","parents","--template","{rev}"], stdout=subprocess.PIPE)
+    output, error = child.communicate()
+    status = child.returncode
     if status:
-        print >> sys.stderr, output
+        print >> sys.stderr, error
         sys.exit(1)
     lines = output.splitlines()
     if len(lines) > 1:
         print >> sys.stderr, 'ERROR: working directory has %d parents' % len(lines)
     return lines[0]
 
-def using_svn():
-    return os.path.isdir(os.path.join(get_src_root(), '.svn'))
-
 def using_hg():
     return os.path.isdir(os.path.join(get_src_root(), '.hg'))

indra/lib/python/indra/util/simperf_host_xml_parser.py

File contents unchanged.

indra/lib/python/indra/util/simperf_oprof_interface.py

File contents unchanged.

indra/lib/python/indra/util/simperf_proc_interface.py

-#!/usr/bin/python
+#!/usr/bin/env python
 """\
 @file simperf_proc_interface.py
 @brief Utility to extract log messages from *.<pid>.llsd files containing performance statistics.

indra/lib/python/indra/util/test_win32_manifest.py

 #!/usr/bin/env python
-# @file test_win32_manifest.py
-# @brief Test an assembly binding version and uniqueness in a windows dll or exe.  
-#
-# $LicenseInfo:firstyear=2009&license=viewerlgpl$
-# Second Life Viewer Source Code
-# Copyright (C) 2010, Linden Research, Inc.
-# 
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation;
-# version 2.1 of the License only.
-# 
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-# 
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-# 
-# Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-# $/LicenseInfo$
+"""\
+@file test_win32_manifest.py
+@brief Test an assembly binding version and uniqueness in a windows dll or exe.  
 
+$LicenseInfo:firstyear=2009&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2009-2011, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+$/LicenseInfo$
+"""
 import sys, os
 import tempfile
 from xml.dom.minidom import parse

indra/llcommon/llavatarname.cpp

 std::string LLAvatarName::getCompleteName() const
 {
 	std::string name;
-	if (!mUsername.empty())
+	if (mUsername.empty() || mIsDisplayNameDefault)
+	// If the display name feature is off
+	// OR this particular display name is defaulted (i.e. based on user name),
+	// then display only the easier to read instance of the person's name.
 	{
-		name = mDisplayName + " (" + mUsername + ")";
+		name = mDisplayName;
 	}
 	else
 	{
-		// ...display names are off, legacy name is in mDisplayName
-		name = mDisplayName;
+		name = mDisplayName + " (" + mUsername + ")";
 	}
 	return name;
 }

indra/llcommon/llversionviewer.h

 #define LL_LLVERSIONVIEWER_H
 
 const S32 LL_VERSION_MAJOR = 2;
-const S32 LL_VERSION_MINOR = 6;
-const S32 LL_VERSION_PATCH = 0;
+const S32 LL_VERSION_MINOR = 5;
+const S32 LL_VERSION_PATCH = 2;
 const S32 LL_VERSION_BUILD = 0;
 
 const char * const LL_CHANNEL = "Second Life Developer";

indra/llinventory/llparcel.cpp

     "shopping",
     "stage",
     "other",
+	"rental"
 };
 static const std::string PARCEL_CATEGORY_UI_STRING[LLParcel::C_COUNT + 1] =
 {
     "Shopping",
     "Stage",
     "Other",
+	"Rental",
     "Any",	 // valid string for parcel searches
 };
 
 	mMediaID.setNull();
 	mMediaAutoScale = 0;
 	mMediaLoop = TRUE;
-	mObscureMedia = 1;
-	mObscureMusic = 1;
 	mMediaWidth = 0;
 	mMediaHeight = 0;
 	setMediaCurrentURL(LLStringUtil::null);
 	msg["auto_scale"] = getMediaAutoScale();
 	msg["media_loop"] = getMediaLoop();
 	msg["media_current_url"] = getMediaCurrentURL();
-	msg["obscure_media"] = getObscureMedia();
-	msg["obscure_music"] = getObscureMusic();
+	msg["obscure_media"] = false; // OBSOLETE - no longer used
+	msg["obscure_music"] = false; // OBSOLETE - no longer used
 	msg["media_id"] = getMediaID();
 	msg["media_allow_navigate"] = getMediaAllowNavigate();
 	msg["media_prevent_camera_zoom"] = getMediaPreventCameraZoom();
 		msg->getS32("MediaData", "MediaWidth", mMediaWidth);
 		msg->getS32("MediaData", "MediaHeight", mMediaHeight);
 		msg->getU8 ( "MediaData", "MediaLoop", mMediaLoop );
-		msg->getU8 ( "MediaData", "ObscureMedia", mObscureMedia );
-		msg->getU8 ( "MediaData", "ObscureMusic", mObscureMusic );
+		// the ObscureMedia and ObscureMusic flags previously set here are no longer used
 	}
 	else
 	{
 		setMediaType(std::string("video/vnd.secondlife.qt.legacy"));
 		setMediaDesc(std::string("No Description available without Server Upgrade"));
 		mMediaLoop = true;
-		mObscureMedia = true;
-		mObscureMusic = true;
 	}
 
 	if(msg->getNumberOfBlocks("MediaLinkSharing") > 0)
     setMediaDesc(LLStringUtil::null);
 	setMediaAutoScale(0);
 	setMediaLoop(TRUE);
-	mObscureMedia = 1;
-	mObscureMusic = 1;
 	mMediaWidth = 0;
 	mMediaHeight = 0;
 	setMediaCurrentURL(LLStringUtil::null);

indra/llinventory/llparcel.h

 		C_SHOPPING,
 		C_STAGE,
 		C_OTHER,
+		C_RENTAL,
 		C_COUNT,
 		C_ANY = -1		// only useful in queries
 	};
 	void	setMediaID(const LLUUID& id) { mMediaID = id; }
 	void	setMediaAutoScale ( U8 flagIn ) { mMediaAutoScale = flagIn; }
 	void    setMediaLoop (U8 loop) { mMediaLoop = loop; }
-	void	setObscureMedia( U8 flagIn ) { mObscureMedia = flagIn; }
-	void	setObscureMusic( U8 flagIn ) { mObscureMusic = flagIn; }
 	void setMediaWidth(S32 width);
 	void setMediaHeight(S32 height);
 	void setMediaCurrentURL(const std::string& url);
 	U8				getMediaAutoScale() const	{ return mMediaAutoScale; }
 	U8              getMediaLoop() const        { return mMediaLoop; }
 	const std::string&  getMediaCurrentURL() const { return mMediaCurrentURL; }
-	U8				getObscureMedia() const		{ return mObscureMedia; }
-	U8				getObscureMusic() const		{ return mObscureMusic; }
 	U8              getMediaURLFilterEnable() const   { return mMediaURLFilterEnable; }
 	LLSD            getMediaURLFilterList() const     { return mMediaURLFilterList; }
 	U8              getMediaAllowNavigate() const { return mMediaAllowNavigate; }
 	U8					mMediaAutoScale;
 	U8                  mMediaLoop;
 	std::string         mMediaCurrentURL;
-	U8					mObscureMedia;
-	U8					mObscureMusic;
 	LLUUID				mMediaID;
 	U8                  mMediaURLFilterEnable;
 	LLSD                mMediaURLFilterList;

indra/llmessage/tests/llhost_test.cpp

 	void host_object::test<9>()
 	{
 //		skip("setHostByName(\"google.com\"); getHostName() -> (e.g.) \"yx-in-f100.1e100.net\"");
-		std::string hostStr = "linux.org";		
+		std::string hostStr = "lindenlab.com";		
 		LLHost host;
 		host.setHostByName(hostStr);	
 

indra/llmessage/tests/test_llsdmessage_peer.py

-#!/usr/bin/python
+#!/usr/bin/env python
 """\
 @file   test_llsdmessage_peer.py
 @author Nat Goodspeed

indra/llmessage/tests/testrunner.py

-#!/usr/bin/python
+#!/usr/bin/env python
 """\
 @file   testrunner.py
 @author Nat Goodspeed

indra/llrender/llvertexbuffer.cpp

 S32 LLVertexBuffer::sCount = 0;
 S32 LLVertexBuffer::sGLCount = 0;
 S32 LLVertexBuffer::sMappedCount = 0;
+BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ;
 BOOL LLVertexBuffer::sEnableVBOs = TRUE;
 U32 LLVertexBuffer::sGLRenderBuffer = 0;
 U32 LLVertexBuffer::sGLRenderIndices = 0;
 void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 {
 	llassert(mRequestedNumIndices >= 0);
+
 	if (indices_offset >= (U32) mRequestedNumIndices ||
 	    indices_offset + count > (U32) mRequestedNumIndices)
 	{
 void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 {
 	llassert(mRequestedNumVerts >= 0);
+
 	if (first >= (U32) mRequestedNumVerts ||
 	    first + count > (U32) mRequestedNumVerts)
 	{
 }
 
 //static
-void LLVertexBuffer::initClass(bool use_vbo)
+void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping)
 {
-	sEnableVBOs = use_vbo;
+	sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject ;
+	if(sEnableVBOs)
+	{
+		//llassert_always(glBindBufferARB) ; //double check the extention for VBO is loaded.
+
+		llinfos << "VBO is enabled." << llendl ;
+	}
+	else
+	{
+		llinfos << "VBO is disabled." << llendl ;
+	}
+
+	sDisableVBOMapping = sEnableVBOs && no_vbo_mapping ;
 	LLGLNamePool::registerPool(&sDynamicVBOPool);
 	LLGLNamePool::registerPool(&sDynamicIBOPool);
 	LLGLNamePool::registerPool(&sStreamVBOPool);
 	mGLBuffer(0),
 	mGLIndices(0), 
 	mMappedData(NULL),
-	mMappedIndexData(NULL), mLocked(FALSE),
+	mMappedIndexData(NULL), 
+	mVertexLocked(FALSE),
+	mIndexLocked(FALSE),
 	mFinal(FALSE),
 	mFilthy(FALSE),
 	mEmpty(TRUE),
 	destroyGLBuffer();
 	destroyGLIndices();
 	sCount--;
+
+	llassert_always(!mMappedData && !mMappedIndexData) ;
 };
 
 //----------------------------------------------------------------------------
 	{
 		if (useVBOs())
 		{
+			freeClientBuffer() ;
+
 			if (mMappedData || mMappedIndexData)
 			{
 				llerrs << "Vertex buffer destroyed while mapped!" << llendl;
 	{
 		if (useVBOs())
 		{
+			freeClientBuffer() ;
+
 			if (mMappedData || mMappedIndexData)
 			{
 				llerrs << "Vertex buffer destroyed while mapped." << llendl;
 			}
-			releaseIndices();
+			releaseIndices();			
 		}
 		else
 		{
 
 	if (mResized && useVBOs())
 	{
+		freeClientBuffer() ;
 		setBuffer(0);
 	}
 }
 }
 
 //----------------------------------------------------------------------------
+void LLVertexBuffer::freeClientBuffer()
+{
+	if(useVBOs() && sDisableVBOMapping && (mMappedData || mMappedIndexData))
+	{
+		delete[] mMappedData ;
+		delete[] mMappedIndexData ;
+		mMappedData = NULL ;
+		mMappedIndexData = NULL ;
+	}
+}
+
+void LLVertexBuffer::allocateClientVertexBuffer()
+{
+	if(!mMappedData)
+	{
+		U32 size = getSize() ;
+		mMappedData = new U8[size];
+		memset(mMappedData, 0, size);
+	}
+}
+
+void LLVertexBuffer::allocateClientIndexBuffer()
+{
+	if(!mMappedIndexData)
+	{
+		U32 size = getIndicesSize();
+		mMappedIndexData = new U8[size];
+		memset(mMappedIndexData, 0, size);
+	}
+}
 
 // Map for data access
-U8* LLVertexBuffer::mapBuffer(S32 access)
+U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 access)
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
 	if (mFinal)
 	{
-		llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl;
+		llerrs << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << llendl;
 	}
 	if (!useVBOs() && !mMappedData && !mMappedIndexData)
 	{
-		llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl;
+		llerrs << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << llendl;
 	}
 		
-	if (!mLocked && useVBOs())
+	if (!mVertexLocked && useVBOs())
 	{
 		{
 			LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES);
-			setBuffer(0);
-			mLocked = TRUE;
+			setBuffer(0, type);
+			mVertexLocked = TRUE;
 			stop_glerror();	
-			mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+
+			if(sDisableVBOMapping)
+			{
+				allocateClientVertexBuffer() ;
+			}
+			else
+			{
+				mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+			}
 			stop_glerror();
 		}
-		{
-			LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
-			mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
-			stop_glerror();
-		}
-
+		
 		if (!mMappedData)
 		{
 			log_glerror();
 			llinfos << "Available physical mwmory(KB): " << avail_phy_mem << llendl ; 
 			llinfos << "Available virtual memory(KB): " << avail_vir_mem << llendl;
 
-			//--------------------
-			//print out more debug info before crash
-			llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
-			GLint size ;
-			glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
-			llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
-			//--------------------
+			if(!sDisableVBOMapping)
+			{
+				//--------------------
+				//print out more debug info before crash
+				llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ;
+				GLint size ;
+				glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ;
+				llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ;
+				//--------------------
 
-			GLint buff;
-			glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
-			if ((GLuint)buff != mGLBuffer)
+				GLint buff;
+				glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff);
+				if ((GLuint)buff != mGLBuffer)
+				{
+					llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+				}
+
+				
+				llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
+			}
+			else
 			{
-				llerrs << "Invalid GL vertex buffer bound: " << buff << llendl;
+				llerrs << "memory allocation for vertex data failed." << llendl ;
 			}
+		}
+		sMappedCount++;
+	}
+	
+	return mMappedData;
+}
 
-			
-			llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl;
+U8* LLVertexBuffer::mapIndexBuffer(S32 access)
+{
+	LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER);
+	if (mFinal)
+	{
+		llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl;
+	}
+	if (!useVBOs() && !mMappedData && !mMappedIndexData)
+	{
+		llerrs << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << llendl;
+	}
+
+	if (!mIndexLocked && useVBOs())
+	{
+		{
+			LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES);
+
+			setBuffer(0, TYPE_INDEX);
+			mIndexLocked = TRUE;
+			stop_glerror();	
+
+			if(sDisableVBOMapping)
+			{
+				allocateClientIndexBuffer() ;
+			}
+			else
+			{
+				mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+			}
+			stop_glerror();
 		}
 
 		if (!mMappedIndexData)
 		{
 			log_glerror();
 
-			GLint buff;
-			glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
-			if ((GLuint)buff != mGLIndices)
+			if(!sDisableVBOMapping)
 			{
-				llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+				GLint buff;
+				glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff);
+				if ((GLuint)buff != mGLIndices)
+				{
+					llerrs << "Invalid GL index buffer bound: " << buff << llendl;
+				}
+
+				llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
 			}
-
-			llerrs << "glMapBuffer returned NULL (no index data)" << llendl;
+			else
+			{
+				llerrs << "memory allocation for Index data failed. " << llendl ;
+			}
 		}
 
 		sMappedCount++;
 	}
-	
-	return mMappedData;
+
+	return mMappedIndexData ;
 }
 
-void LLVertexBuffer::unmapBuffer()
+void LLVertexBuffer::unmapBuffer(S32 type)
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER);
-	if (mMappedData || mMappedIndexData)
+	if (!useVBOs())
 	{
-		if (useVBOs() && mLocked)
+		return ; //nothing to unmap
+	}
+
+	bool updated_all = false ;
+	if (mMappedData && mVertexLocked && type != TYPE_INDEX)
+	{
+		updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating
+
+		if(sDisableVBOMapping)
+		{
+			stop_glerror();
+			glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, getSize(), mMappedData);
+			stop_glerror();
+		}
+		else
 		{
 			stop_glerror();
 			glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
 			stop_glerror();
+
+			mMappedData = NULL;
+		}
+
+		mVertexLocked = FALSE ;
+		sMappedCount--;
+	}
+
+	if(mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX))
+	{
+		if(sDisableVBOMapping)
+		{
+			stop_glerror();
+			glBufferSubDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0, getIndicesSize(), mMappedIndexData);
+			stop_glerror();
+		}
+		else
+		{
+			stop_glerror();
 			glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
 			stop_glerror();
 
-			/*if (!sMapped)
+			mMappedIndexData = NULL ;
+		}
+
+		mIndexLocked = FALSE ;
+		sMappedCount--;
+	}
+
+	if(updated_all)
+	{
+		if(mUsage == GL_STATIC_DRAW_ARB)
+		{
+			//static draw buffers can only be mapped a single time
+			//throw out client data (we won't be using it again)
+			mEmpty = TRUE;
+			mFinal = TRUE;
+
+			if(sDisableVBOMapping)
 			{
-				llerrs << "Redundantly unmapped VBO!" << llendl;
+				freeClientBuffer() ;
 			}
-			sMapped = FALSE;*/
-			sMappedCount--;
-
-			if (mUsage == GL_STATIC_DRAW_ARB)
-			{ //static draw buffers can only be mapped a single time
-				//throw out client data (we won't be using it again)
-				mEmpty = TRUE;
-				mFinal = TRUE;
-			}
-			else
-			{
-				mEmpty = FALSE;
-			}
-
-			mMappedIndexData = NULL;
-			mMappedData = NULL;
-			
-			mLocked = FALSE;
+		}
+		else
+		{
+			mEmpty = FALSE;
 		}
 	}
 }
 					strider_t& strider, 
 					S32 index)
 	{
-		if (vbo.mapBuffer() == NULL)
-		{
-			llwarns << "mapBuffer failed!" << llendl;
-			return FALSE;
-		}
-
 		if (type == LLVertexBuffer::TYPE_INDEX)
 		{
 			S32 stride = sizeof(T);
+
+			if (vbo.mapIndexBuffer() == NULL)
+			{
+				llwarns << "mapIndexBuffer failed!" << llendl;
+				return FALSE;
+			}
+
 			strider = (T*)(vbo.getMappedIndices() + index*stride);
 			strider.setStride(0);
 			return TRUE;
 		else if (vbo.hasDataType(type))
 		{
 			S32 stride = vbo.getStride();
+
+			if (vbo.mapVertexBuffer(type) == NULL)
+			{
+				llwarns << "mapVertexBuffer failed!" << llendl;
+				return FALSE;
+			}
+
 			strider = (T*)(vbo.getMappedData() + vbo.getOffset(type) + index*stride);
 			strider.setStride(stride);
 			return TRUE;
 //----------------------------------------------------------------------------
 
 // Set for rendering
-void LLVertexBuffer::setBuffer(U32 data_mask)
+void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
 {
 	LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER);
 	//set up pointers if the data mask is different ...
 		{
 			ll_fail("LLVertexBuffer::mapBuffer failed");
 		}
-		unmapBuffer();
+		unmapBuffer(type);
 	}
 	else
 	{		

indra/llrender/llvertexbuffer.h

 
 	static BOOL	sUseStreamDraw;
 
-	static void initClass(bool use_vbo);
+	static void initClass(bool use_vbo, bool no_vbo_mapping);
 	static void cleanupClass();
 	static void setupClientArrays(U32 data_mask);
  	static void clientCopy(F64 max_time = 0.005); //copy data from client to GL
 	void	updateNumVerts(S32 nverts);
 	void	updateNumIndices(S32 nindices); 
 	virtual BOOL	useVBOs() const;
-	void	unmapBuffer();
-		
+	void	unmapBuffer(S32 type);
+	void freeClientBuffer() ;
+	void allocateClientVertexBuffer() ;
+	void allocateClientIndexBuffer() ;
+
 public:
 	LLVertexBuffer(U32 typemask, S32 usage);
 	
 	// map for data access
-	U8*		mapBuffer(S32 access = -1);
+	U8*		mapVertexBuffer(S32 type = -1, S32 access = -1);
+	U8*		mapIndexBuffer(S32 access = -1);
+
 	// set for rendering
-	virtual void	setBuffer(U32 data_mask); 	// calls  setupVertexBuffer() if data_mask is not 0
+	virtual void	setBuffer(U32 data_mask, S32 type = -1); 	// calls  setupVertexBuffer() if data_mask is not 0
 	// allocate buffer
 	void	allocateBuffer(S32 nverts, S32 nindices, bool create);
 	virtual void resizeBuffer(S32 newnverts, S32 newnindices);
-		
+			
 	// Only call each getVertexPointer, etc, once before calling unmapBuffer()
 	// call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
 	// example:
 	bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0);
 	
 	BOOL isEmpty() const					{ return mEmpty; }
-	BOOL isLocked() const					{ return mLocked; }
+	BOOL isLocked() const					{ return mVertexLocked || mIndexLocked; }
 	S32 getNumVerts() const					{ return mNumVerts; }
 	S32 getNumIndices() const				{ return mNumIndices; }
 	S32 getRequestedVerts() const			{ return mRequestedNumVerts; }
 	U32		mGLIndices;		// GL IBO handle
 	U8*		mMappedData;	// pointer to currently mapped data (NULL if unmapped)
 	U8*		mMappedIndexData;	// pointer to currently mapped indices (NULL if unmapped)
-	BOOL	mLocked;			// if TRUE, buffer is being or has been written to in client memory
+	BOOL	mVertexLocked;			// if TRUE, vertex buffer is being or has been written to in client memory
+	BOOL	mIndexLocked;			// if TRUE, index buffer is being or has been written to in client memory
 	BOOL	mFinal;			// if TRUE, buffer can not be mapped again
 	BOOL	mFilthy;		// if TRUE, entire buffer must be copied (used to prevent redundant dirty flags)
-	BOOL	mEmpty;			// if TRUE, client buffer is empty (or NULL). Old values have been discarded.
-	S32		mOffsets[TYPE_MAX];
+	BOOL	mEmpty;			// if TRUE, client buffer is empty (or NULL). Old values have been discarded.	
 	BOOL	mResized;		// if TRUE, client buffer has been resized and GL buffer has not
 	BOOL	mDynamicSize;	// if TRUE, buffer has been resized at least once (and should be padded)
+	S32		mOffsets[TYPE_MAX];
 
 	class DirtyRegion
 	{
 	static std::vector<U32> sDeleteList;
 	typedef std::list<LLVertexBuffer*> buffer_list_t;
 		
+	static BOOL sDisableVBOMapping; //disable glMapBufferARB
 	static BOOL sEnableVBOs;
+	static BOOL sVBOActive;
+	static BOOL sIBOActive;
 	static S32 sTypeOffsets[TYPE_MAX];
 	static U32 sGLMode[LLRender::NUM_MODES];
 	static U32 sGLRenderBuffer;
-	static U32 sGLRenderIndices;
-	static BOOL sVBOActive;
-	static BOOL sIBOActive;
+	static U32 sGLRenderIndices;	
 	static U32 sLastMask;
 	static U32 sAllocatedBytes;
 	static U32 sBindCount;

indra/llui/llcombobox.cpp

 		LLScrollListItem* item = mList->getFirstSelected();
 		if (item)
 		{
-			setLabel(getSelectedItemLabel());
+			updateLabel();
 		}
 		mLastSelectedIndex = mList->getFirstSelectedIndex();
 	}
 	}
 }
 
+void LLComboBox::updateLabel()
+{
+	// Update the combo editor with the selected
+	// item label.
+	if (mTextEntry)
+	{
+		mTextEntry->setText(getSelectedItemLabel());
+		mTextEntry->setTentative(FALSE);
+	}
+
+	// If combo box doesn't allow text entry update
+	// the combo button label.
+	if (!mAllowTextEntry)
+	{
+		mButton->setLabel(getSelectedItemLabel());
+	}
+}
 
 BOOL LLComboBox::remove(const std::string& name)
 {
 	mLastSelectedIndex = getCurrentIndex();
 	if (mLastSelectedIndex != -1)
 	{
-		setLabel(getSelectedItemLabel());
+		updateLabel();
 
 		if (mAllowTextEntry)
-	{
-		gFocusMgr.setKeyboardFocus(mTextEntry);
-		mTextEntry->selectAll();
-	}
+		{
+			gFocusMgr.setKeyboardFocus(mTextEntry);
+			mTextEntry->selectAll();
+		}
 	}
 	// hiding the list reasserts the old value stored in the text editor/dropdown button
 	hideList();

indra/llui/llcombobox.h

 	// This is probably a UI abuse.
 	void			setLabel(const LLStringExplicit& name);
 
+	// Updates the combobox label to match the selected list item.
+	void			updateLabel();
+
 	BOOL			remove(const std::string& name);	// remove item "name", return TRUE if found and removed
 	
 	BOOL			setCurrentByIndex( S32 index );

indra/llui/lldockcontrol.cpp

 			case TOP:
 			{
 				// check is dock inside parent rect
+				// assume that parent for all dockable flaoters
+				// is the root view
 				LLRect dockParentRect =
-						mDockWidget->getParent()->calcScreenRect();
+						mDockWidget->getRootView()->calcScreenRect();
 				if (dockRect.mRight <= dockParentRect.mLeft
 						|| dockRect.mLeft >= dockParentRect.mRight)
 				{

indra/llui/lllayoutstack.cpp

 	}
 
 	// update resize bars with new limits
-	LLResizeBar* last_resize_bar = NULL;
+	LLLayoutPanel* last_resizeable_panel = NULL;
 	for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
 	{
 		LLPanel* panelp = (*panel_it);
 		BOOL resize_bar_enabled = panelp->getVisible() && (*panel_it)->mUserResize;
 		(*panel_it)->mResizeBar->setVisible(resize_bar_enabled);
 
-		if (resize_bar_enabled)
+		if ((*panel_it)->mUserResize || (*panel_it)->mAutoResize)
 		{
-			last_resize_bar = (*panel_it)->mResizeBar;
+			last_resizeable_panel = (*panel_it);
 		}
 	}
 
 	// hide last resize bar as there is nothing past it
 	// resize bars need to be in between two resizable panels
-	if (last_resize_bar)
+	if (last_resizeable_panel)
 	{
-		last_resize_bar->setVisible(FALSE);
+		last_resizeable_panel->mResizeBar->setVisible(FALSE);
 	}
 
 	// not enough room to fit existing contents

indra/llvfs/lldir_linux.h

 /** 
  * @file lldir_linux.h
- * @brief Definition of directory utilities class for linux 
+ * @brief Definition of directory utilities class for linux
  *
  * $LicenseInfo:firstyear=2000&license=viewerlgpl$
  * Second Life Viewer Source Code
  * $/LicenseInfo$
  */
 
+#if !LL_LINUX
+#error This header must not be included when compiling for any target other than Linux. Consider including lldir.h instead.
+#endif // !LL_LINUX
+
 #ifndef LL_LLDIR_LINUX_H
 #define LL_LLDIR_LINUX_H
 
 
 	/*virtual*/ void initAppDirs(const std::string &app_name,
 		const std::string& app_read_only_data_dir);
-public:	
+
 	virtual std::string getCurPath();
 	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
 	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
 	DIR *mDirp;
 	int mCurrentDirIndex;
 	int mCurrentDirCount;
-	std::string mCurrentDir;	
+	std::string mCurrentDir;
 };
 
 #endif // LL_LLDIR_LINUX_H

indra/llvfs/lldir_mac.h

  * $/LicenseInfo$
  */
 
+#if !LL_DARWIN
+#error This header must not be included when compiling for any target other than Mac OS. Consider including lldir.h instead.
+#endif // !LL_DARWIN
+
 #ifndef LL_LLDIR_MAC_H
 #define LL_LLDIR_MAC_H
 
 
 	/*virtual*/ void initAppDirs(const std::string &app_name,
 		const std::string& app_read_only_data_dir);
-public:	
+
 	virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask);
 	virtual std::string getCurPath();
 	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);

indra/llvfs/lldir_solaris.h

  * $/LicenseInfo$
  */
 
+#if !LL_SOLARIS
+#error This header must not be included when compiling for any target other than Solaris. Consider including lldir.h instead.
+#endif // !LL_SOLARIS
+
 #ifndef LL_LLDIR_SOLARIS_H
 #define LL_LLDIR_SOLARIS_H
 
 
 	/*virtual*/ void initAppDirs(const std::string &app_name,
 		const std::string& app_read_only_data_dir);
-public:	
+
 	virtual std::string getCurPath();
 	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
 	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
 	DIR *mDirp;
 	int mCurrentDirIndex;
 	int mCurrentDirCount;
-	std::string mCurrentDir;	
+	std::string mCurrentDir;
 };
 
 #endif // LL_LLDIR_SOLARIS_H

indra/llvfs/lldir_win32.h

  * $/LicenseInfo$
  */
 
+#if !LL_WINDOWS
+#error This header must not be included when compiling for any target other than Windows. Consider including lldir.h instead.
+#endif // !LL_WINDOWS
+
 #ifndef LL_LLDIR_WIN32_H
 #define LL_LLDIR_WIN32_H
 
 	/*virtual*/ std::string getLLPluginFilename(std::string base_name);
 
 private:
-	BOOL LLDir_Win32::getNextFileInDir(const llutf16string &dirname, const std::string &mask, std::string &fname);
-	
+	BOOL getNextFileInDir(const llutf16string &dirname, const std::string &mask, std::string &fname);
+
 	void* mDirSearch_h;
 	llutf16string mCurrentDir;
 };

indra/newview/app_settings/settings.xml

       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>RenderVBOMappingDisable</key>
+    <map>
+      <key>Comment</key>
+      <string>Disable VBO glMapBufferARB</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
   <key>RenderUseStreamVBO</key>
   <map>
     <key>Comment</key>

indra/newview/generate_breakpad_symbols.py

 #!/usr/bin/env python
-# @file generate_breakpad_symbols.py
-# @author Brad Kittenbrink <brad@lindenlab.com>
-# @brief Simple tool for generating google_breakpad symbol information
-#        for the crash reporter.
-#
-# $LicenseInfo:firstyear=2010&license=viewerlgpl$
-# Second Life Viewer Source Code
-# Copyright (C) 2010, Linden Research, Inc.
-# 
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation;
-# version 2.1 of the License only.
-# 
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# Lesser General Public License for more details.
-# 
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-# 
-# Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-# $/LicenseInfo$
+"""\
+@file generate_breakpad_symbols.py
+@author Brad Kittenbrink <brad@lindenlab.com>
+@brief Simple tool for generating google_breakpad symbol information
+       for the crash reporter.
+
+$LicenseInfo:firstyear=2010&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2010-2011, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+$/LicenseInfo$
+"""
 
 
 import collections

indra/newview/llappviewer.cpp

 
 	// Delete workers first
 	// shotdown all worker threads before deleting them in case of co-dependencies
-	sTextureCache->shutdown();
 	sTextureFetch->shutdown();
+	sTextureCache->shutdown();	
 	sImageDecodeThread->shutdown();
 	
 	sTextureFetch->shutDownTextureCacheThread() ;

indra/newview/llavatarlist.cpp

 	LLAvalineListItem* item = new LLAvalineListItem(/*hide_number=*/false);
 	item->setAvatarId(item_id, session_id, true, false);
 	item->setName(item_name);
+	item->showLastInteractionTime(mShowLastInteractionTime);
+	item->showSpeakingIndicator(mShowSpeakingIndicator);
+	item->setOnline(false);
 
 	addItem(item, item_id);
 	mIDs.push_back(item_id);
 			{
 				// *NOTE: If you change the UI to show a different string,
 				// be sure to change the filter code below.
-				addNewItem(buddy_id, 
-					       av_name.mDisplayName.empty() ? waiting_str : av_name.mDisplayName, 
-						   LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+				if (LLRecentPeople::instance().isAvalineCaller(buddy_id))
+				{
+					const LLSD& call_data = LLRecentPeople::instance().getData(buddy_id);
+					addAvalineItem(buddy_id, call_data["session_id"].asUUID(), call_data["call_number"].asString());
+				}
+				else
+				{
+					addNewItem(buddy_id, 
+						av_name.mDisplayName.empty() ? waiting_str : av_name.mDisplayName, 
+						LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+				}
+				
 				modified = true;
 				nadded++;
 			}
 BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
 	BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
-	if ( mContextMenu )
+	if ( mContextMenu && !isAvalineItemSelected())
 	{
 		uuid_vec_t selected_uuids;
 		getSelectedUUIDs(selected_uuids);
 	return handled;
 }
 
+bool LLAvatarList::isAvalineItemSelected()
+{
+	std::vector<LLPanel*> selected_items;
+	getSelectedItems(selected_items);
+	std::vector<LLPanel*>::iterator it = selected_items.begin();
+	
+	for(; it != selected_items.end(); ++it)
+	{
+		if (dynamic_cast<LLAvalineListItem*>(*it))
+			return true;
+	}
+
+	return false;
+}
+
 void LLAvatarList::setVisible(BOOL visible)
 {
 	if ( visible == FALSE && mContextMenu )

indra/newview/llavatarlist.h

 
 private:
 
+	bool isAvalineItemSelected();
+
 	bool mIgnoreOnlineStatus;
 	bool mShowLastInteractionTime;
 	bool mDirty;

indra/newview/llbottomtray.cpp

 {
 	if (mCanDrag)
 	{
-	S32 screenX, screenY;
-	localPointToScreen(x, y, &screenX, &screenY);
-	// pass hover to bottomtray
-	LLBottomTray::getInstance()->onDraggableButtonHover(screenX, screenY);
+		// pass hover to bottomtray
+		S32 screenX, screenY;
+		localPointToScreen(x, y, &screenX, &screenY);
+		LLBottomTray::getInstance()->onDraggableButtonHover(screenX, screenY);
+
 		return TRUE;
 	}
 	else
 	mSpeakBtn(NULL),
 	mNearbyChatBar(NULL),
 	mChatBarContainer(NULL),
+	mNearbyCharResizeHandlePanel(NULL),
 	mToolbarStack(NULL),
 	mMovementButton(NULL),
 	mResizeState(RS_NORESIZE),
 	setTrayButtonVisibleIfPossible(RS_BUTTON_SNAPSHOT, visible);
 }
 
+void LLBottomTray::showSpeakButton(bool visible)
+{
+	// Show/hide the button
+	setTrayButtonVisible(RS_BUTTON_SPEAK, visible);
+
+	// and adjust other panels according to the occupied/freed space.
+	const S32 panel_width = mSpeakPanel->getRect().getWidth();
+	if (visible)
+	{
+		processWidthDecreased(-panel_width);
+	}
+	else
+	{
+		processWidthIncreased(panel_width);
+	}
+}
+
 void LLBottomTray::toggleMovementControls()
 {
 	if (mMovementButton)
 	LLHints::registerHintTarget("chat_bar", mNearbyChatBar->LLView::getHandle());
 
 	mChatBarContainer = getChild<LLLayoutPanel>("chat_bar_layout_panel");
+	mNearbyCharResizeHandlePanel = getChild<LLPanel>("chat_bar_resize_handle_panel");
 
 	mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
 	mMovementButton = getChild<LLButton>("movement_btn");
 			gViewerWindow->getWindow()->setCursor(UI_CURSOR_NO);
 		}
 	}
+	else
+	{
+		// Reset cursor in case you move your mouse from the drag handle to a button.
+		getWindow()->setCursor(UI_CURSOR_ARROW);
+
+	}
 }
 
 bool LLBottomTray::isCursorOverDraggableArea(S32 x, S32 y)
 {
+	// Draggable area lasts from the nearby chat input resize handle
+	// to the chiclet area (exlusively).
 	bool result = getRect().pointInRect(x, y);
-	result = result && mNearbyChatBar->calcScreenRect().mRight < x;
+	result = result && mNearbyCharResizeHandlePanel->calcScreenRect().mRight < x;
 	result = result && mChicletPanel->calcScreenRect().mRight > x;
 	return result;
 }
 	// (and according to future possible changes in the way button order is saved between sessions).
 	state_object_map_t::const_iterator it = mStateProcessedObjectMap.begin();
 	state_object_map_t::const_iterator it_end = mStateProcessedObjectMap.end();
-	// Speak button is currently the only draggable button not in mStateProcessedObjectMap,
-	// so if dragged_state is not found in that map, it should be RS_BUTTON_SPEAK. Change this code if any other
-	// exclusions from mStateProcessedObjectMap will become draggable.
-	EResizeState dragged_state = RS_BUTTON_SPEAK;
+	EResizeState dragged_state = RS_NORESIZE;
 	EResizeState landing_state = RS_NORESIZE;
 	bool landing_state_found = false;
 	// Find states for dragged item and landing tab
 			landing_state_found = true;
 		}
 	}
-	
+
+	if (dragged_state == RS_NORESIZE)
+	{
+		llwarns << "Cannot determine what button is being dragged" << llendl;
+		llassert(dragged_state != RS_NORESIZE);
+		return;
+	}
+
+	lldebugs << "Will place " << resizeStateToString(dragged_state)
+		<< " before " << resizeStateToString(landing_state) << llendl;
+
 	// Update order of buttons according to drag'n'drop
 	mButtonsOrder.erase(std::find(mButtonsOrder.begin(), mButtonsOrder.end(), dragged_state));
 	if (!landing_state_found && mLandingTab == getChild<LLPanel>(PANEL_CHICLET_NAME))
 	}
 	else
 	{
-		if (!landing_state_found) landing_state = RS_BUTTON_SPEAK;
+		if (!landing_state_found) landing_state = RS_BUTTON_SPEAK; // just a random fallback
 		mButtonsOrder.insert(std::find(mButtonsOrder.begin(), mButtonsOrder.end(), landing_state), dragged_state);
 	}
+
 	// Synchronize button process order with their order
 	resize_state_vec_t::const_iterator it1 = mButtonsOrder.begin();
 	const resize_state_vec_t::const_iterator it_end1 = mButtonsOrder.end();
 	// placing panels in layout stack according to button order which we loaded in previous for
 	for (resize_state_vec_t::const_reverse_iterator it = mButtonsOrder.rbegin(); it != it_end; ++it, ++i)
 	{
-		LLPanel* panel_to_move = *it == RS_BUTTON_SPEAK ? mSpeakPanel : mStateProcessedObjectMap[*it];
+		LLPanel* panel_to_move = getButtonPanel(*it);
 		mToolbarStack->movePanel(panel_to_move, NULL, true); // prepend 		
 	}
 	// Nearbychat is not stored in order settings file, but it must be the first of the panels, so moving it
-	// manually here
+	// (along with its drag handle) manually here.
+	mToolbarStack->movePanel(getChild<LLLayoutPanel>("chat_bar_resize_handle_panel"), NULL, true);
 	mToolbarStack->movePanel(mChatBarContainer, NULL, true);
 }
 
 bool LLBottomTray::processShowButton(EResizeState shown_object_type, S32& available_width)
 {
 	lldebugs << "Trying to show object type: " << shown_object_type << llendl;
-	llassert(mStateProcessedObjectMap[shown_object_type] != NULL);
 
-	LLPanel* panel = mStateProcessedObjectMap[shown_object_type];
+	LLPanel* panel = getButtonPanel(shown_object_type);
 	if (NULL == panel)
 	{
 		lldebugs << "There is no object to process for state: " << shown_object_type << llendl;
 void LLBottomTray::processHideButton(EResizeState processed_object_type, S32& required_width, S32& buttons_freed_width)
 {
 	lldebugs << "Trying to hide object type: " << processed_object_type << llendl;
-	llassert(mStateProcessedObjectMap[processed_object_type] != NULL);
-
-	LLPanel* panel = mStateProcessedObjectMap[processed_object_type];
+	LLPanel* panel = getButtonPanel(processed_object_type);
 	if (NULL == panel)
 	{
 		lldebugs << "There is no object to process for state: " << processed_object_type << llendl;
 	// then shrink Speak button
 	if (required_width < 0)
 	{
-
 		S32 panel_min_width = 0;
 		std::string panel_name = mSpeakPanel->getName();
 		bool success = mToolbarStack->getPanelMinSize(panel_name, &panel_min_width);
 
 void LLBottomTray::processShrinkButton(EResizeState processed_object_type, S32& required_width)
 {
-	llassert(mStateProcessedObjectMap[processed_object_type] != NULL);
-	LLPanel* panel = mStateProcessedObjectMap[processed_object_type];
+	LLPanel* panel = getButtonPanel(processed_object_type);
 	if (NULL == panel)
 	{
 		lldebugs << "There is no object to process for type: " << processed_object_type << llendl;
 
 void LLBottomTray::processExtendButton(EResizeState processed_object_type, S32& available_width)
 {
-	llassert(mStateProcessedObjectMap[processed_object_type] != NULL);
-	LLPanel* panel = mStateProcessedObjectMap[processed_object_type];
+	LLPanel* panel = getButtonPanel(processed_object_type);
 	if (NULL == panel)
 	{
 		lldebugs << "There is no object to process for type: " << processed_object_type << llendl;
 void LLBottomTray::initResizeStateContainers()
 {
 	// init map with objects should be processed for each type
+	mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_SPEAK, getChild<LLPanel>("speak_panel")));
 	mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_GESTURES, getChild<LLPanel>("gesture_panel")));
 	mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_MOVEMENT, getChild<LLPanel>("movement_panel")));
 	mStateProcessedObjectMap.insert(std::make_pair(RS_BUTTON_CAMERA, getChild<LLPanel>("cam_panel")));
 	{
 		const EResizeState button_type = *it;
 		// is there an appropriate object?
-		llassert(mStateProcessedObjectMap.count(button_type) > 0);
-		if (0 == mStateProcessedObjectMap.count(button_type)) continue;
+		LLPanel* button_panel = getButtonPanel(button_type);
+		if (!button_panel) continue;
 
 		// set default width for it.
-		mObjectDefaultWidthMap[button_type] = mStateProcessedObjectMap[button_type]->getRect().getWidth();
+		mObjectDefaultWidthMap[button_type] = button_panel->getRect().getWidth();
 	}
 
 	// ... and add Speak button because it also can be shrunk.
 	mObjectDefaultWidthMap[RS_BUTTON_SPEAK]	   = mSpeakPanel->getRect().getWidth();
-
 }
 
 // this method must be called before restoring of the chat entry field on startup
 // because it resets chatbar's width according to resize logic.
 void LLBottomTray::initButtonsVisibility()
 {
+	setVisibleAndFitWidths(RS_BUTTON_SPEAK, gSavedSettings.getBOOL("EnableVoiceChat"));
 	setVisibleAndFitWidths(RS_BUTTON_GESTURES, gSavedSettings.getBOOL("ShowGestureButton"));
 	setVisibleAndFitWidths(RS_BUTTON_MOVEMENT, gSavedSettings.getBOOL("ShowMoveButton"));
 	setVisibleAndFitWidths(RS_BUTTON_CAMERA, gSavedSettings.getBOOL("ShowCameraButton"));
 
 void LLBottomTray::setButtonsControlsAndListeners()
 {
+	gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_SPEAK, _2));
 	gSavedSettings.getControl("ShowGestureButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_GESTURES, _2));
 	gSavedSettings.getControl("ShowMoveButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_MOVEMENT, _2));
 	gSavedSettings.getControl("ShowCameraButton")->getSignal()->connect(boost::bind(&LLBottomTray::toggleShowButton, RS_BUTTON_CAMERA, _2));
 
 void LLBottomTray::setTrayButtonVisible(EResizeState shown_object_type, bool visible)
 {
-	llassert(mStateProcessedObjectMap[shown_object_type] != NULL);
-	LLPanel* panel = mStateProcessedObjectMap[shown_object_type];
+	LLPanel* panel = getButtonPanel(shown_object_type);
 	if (NULL == panel)
 	{
 		lldebugs << "There is no object to show for state: " << shown_object_type << llendl;
 
 bool LLBottomTray::setVisibleAndFitWidths(EResizeState object_type, bool visible)
 {
-	LLPanel* cur_panel = mStateProcessedObjectMap[object_type];
+	// The Speak button is treated specially: if voice is enabled,
+	// the button should be displayed no matter how much space we've got.
+	if (object_type == RS_BUTTON_SPEAK)
+	{
+		showSpeakButton(visible);
+		return true;
+	}
+
+	LLPanel* cur_panel = getButtonPanel(object_type);
 	if (NULL == cur_panel)