From 788c18c00db8dabdbcdc0ab1af2cf35c24eec8e9 Mon Sep 17 00:00:00 2001
From: Brian McGroarty <soft@lindenlab.com>
Date: Thu, 11 Oct 2007 19:43:20 +0000
Subject: [PATCH] Merge maint-viewer @ r71064

---
 doc/contributions.txt                   |  1 +
 indra/llimage/llimagej2c.cpp            | 41 ++++++++++---
 indra/llimage/llimagej2c.h              |  1 +
 indra/llimagej2coj/llimagej2coj.cpp     |  6 ++
 indra/llmath/llcoordframe.cpp           | 81 ++++++++++++++++---------
 indra/llmath/xform.h                    | 67 +++++++-------------
 indra/newview/linux_tools/launch_url.sh |  3 +-
 indra/newview/linux_tools/wrapper.sh    |  3 +-
 indra/newview/llfloatersnapshot.cpp     | 16 +++--
 9 files changed, 126 insertions(+), 93 deletions(-)

diff --git a/doc/contributions.txt b/doc/contributions.txt
index 208bc534bfd..2d3fa99c8b6 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -102,6 +102,7 @@ Gigs Taggart
 	VWR-1217
 	VWR-1434
 	VWR-1987
+	VWR-2065
 Ginko Bayliss
 	VWR-4
 Grazer Kline
diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp
index dc8df049b55..0911c436740 100644
--- a/indra/llimage/llimagej2c.cpp
+++ b/indra/llimage/llimagej2c.cpp
@@ -38,11 +38,13 @@
 
 typedef LLImageJ2CImpl* (*CreateLLImageJ2CFunction)();
 typedef void (*DestroyLLImageJ2CFunction)(LLImageJ2CImpl*);
+typedef const char* (*EngineInfoLLImageJ2CFunction)();
 
 //some "private static" variables so we only attempt to load
 //dynamic libaries once
 CreateLLImageJ2CFunction j2cimpl_create_func;
 DestroyLLImageJ2CFunction j2cimpl_destroy_func;
+EngineInfoLLImageJ2CFunction j2cimpl_engineinfo_func;
 apr_pool_t *j2cimpl_dso_memory_pool;
 apr_dso_handle_t *j2cimpl_dso_handle;
 
@@ -52,9 +54,10 @@ apr_dso_handle_t *j2cimpl_dso_handle;
 //function should ever be included
 LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl();
 void fallbackDestroyLLImageJ2CImpl(LLImageJ2CImpl* impl);
+const char* fallbackEngineInfoLLImageJ2CImpl();
 
 //static
-//Loads the required "create" and "destroy" functions needed
+//Loads the required "create", "destroy" and "engineinfo" functions needed
 void LLImageJ2C::openDSO()
 {
 	//attempt to load a DSO and get some functions from it
@@ -73,8 +76,8 @@ void LLImageJ2C::openDSO()
 #endif
 
 	dso_path = gDirUtilp->findFile(dso_name,
-								   gDirUtilp->getAppRODataDir(),
-								   gDirUtilp->getExecutableDir());
+				       gDirUtilp->getAppRODataDir(),
+				       gDirUtilp->getExecutableDir());
 
 	j2cimpl_dso_handle      = NULL;
 	j2cimpl_dso_memory_pool = NULL;
@@ -92,6 +95,7 @@ void LLImageJ2C::openDSO()
 		//now we want to load the functions we're interested in
 		CreateLLImageJ2CFunction  create_func = NULL;
 		DestroyLLImageJ2CFunction dest_func = NULL;
+		EngineInfoLLImageJ2CFunction engineinfo_func = NULL;
 
 		rv = apr_dso_sym((apr_dso_handle_sym_t*)&create_func,
 						 j2cimpl_dso_handle,
@@ -103,13 +107,21 @@ void LLImageJ2C::openDSO()
 			//so lets check for a destruction function
 			rv = apr_dso_sym((apr_dso_handle_sym_t*)&dest_func,
 							 j2cimpl_dso_handle,
-							 "destroyLLImageJ2CKDU");
+						       "destroyLLImageJ2CKDU");
 			if ( rv == APR_SUCCESS )
 			{
-				//k, everything is loaded alright
-				j2cimpl_create_func  = create_func;
-				j2cimpl_destroy_func = dest_func;
-				all_functions_loaded = true;
+				//we've loaded the destroy function ok
+				rv = apr_dso_sym((apr_dso_handle_sym_t*)&engineinfo_func,
+						 j2cimpl_dso_handle,
+						 "engineInfoLLImageJ2CKDU");
+				if ( rv == APR_SUCCESS )
+				{
+					//ok, everything is loaded alright
+					j2cimpl_create_func  = create_func;
+					j2cimpl_destroy_func = dest_func;
+					j2cimpl_engineinfo_func = engineinfo_func;
+					all_functions_loaded = true;
+				}
 			}
 		}
 	}
@@ -152,6 +164,15 @@ void LLImageJ2C::closeDSO()
 	if (j2cimpl_dso_memory_pool) apr_pool_destroy(j2cimpl_dso_memory_pool);
 }
 
+//static
+std::string LLImageJ2C::getEngineInfo()
+{
+	if (!j2cimpl_engineinfo_func)
+		j2cimpl_engineinfo_func = fallbackEngineInfoLLImageJ2CImpl;
+
+	return j2cimpl_engineinfo_func();
+}
+
 LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),
 							mMaxBytes(0),
 							mRawDiscardLevel(-1),
@@ -159,7 +180,7 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),
 							mReversible(FALSE)
 	
 {
-	//We assume here that if we wanted to destory via
+	//We assume here that if we wanted to create via
 	//a dynamic library that the approriate open calls were made
 	//before any calls to this constructor.
 
@@ -178,7 +199,7 @@ LLImageJ2C::LLImageJ2C() : 	LLImageFormatted(IMG_CODEC_J2C),
 // virtual
 LLImageJ2C::~LLImageJ2C()
 {
-	//We assume here that if we wanted to destory via
+	//We assume here that if we wanted to destroy via
 	//a dynamic library that the approriate open calls were made
 	//before any calls to this destructor.
 
diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h
index eeb6599f5c7..35b4d6b8b40 100644
--- a/indra/llimage/llimagej2c.h
+++ b/indra/llimage/llimagej2c.h
@@ -71,6 +71,7 @@ class LLImageJ2C : public LLImageFormatted
 
 	static void openDSO();
 	static void closeDSO();
+	static std::string getEngineInfo();
 	
 protected:
 	friend class LLImageJ2CImpl;
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp
index fe53715509a..7a323c83541 100644
--- a/indra/llimagej2coj/llimagej2coj.cpp
+++ b/indra/llimagej2coj/llimagej2coj.cpp
@@ -38,6 +38,12 @@
 #include "lltimer.h"
 #include "llmemory.h"
 
+const char* fallbackEngineInfoLLImageJ2CImpl()
+{
+	return (std::string("OpenJPEG: " OPENJPEG_VERSION ", Runtime: ")
+		+ opj_version()).c_str();
+}
+
 LLImageJ2CImpl* fallbackCreateLLImageJ2CImpl()
 {
 	return new LLImageJ2COJ();
diff --git a/indra/llmath/llcoordframe.cpp b/indra/llmath/llcoordframe.cpp
index 92f12a29462..70d4646264a 100644
--- a/indra/llmath/llcoordframe.cpp
+++ b/indra/llmath/llcoordframe.cpp
@@ -63,7 +63,8 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin) :
 {
 	if( !mOrigin.isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
 	}
 }
 
@@ -74,7 +75,8 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLVector3 &direction)
 	
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
 	}
 }
 
@@ -88,7 +90,8 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &x_axis,
 {
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
 	}
 }
 
@@ -103,7 +106,8 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin,
 {
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
 	}
 }
 
@@ -117,7 +121,8 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin,
 {
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
 	}
 }
 
@@ -131,7 +136,8 @@ LLCoordFrame::LLCoordFrame(const LLQuaternion &q) :
 
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
 	}
 }
 
@@ -145,7 +151,8 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLQuaternion &q) :
 
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
 	}
 }
 
@@ -157,7 +164,8 @@ LLCoordFrame::LLCoordFrame(const LLMatrix4 &mat) :
 {
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
 	}
 }
 
@@ -172,7 +180,8 @@ LLCoordFrame::LLCoordFrame(const F32 *origin, const F32 *rotation) :
 {
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
 	}
 }
 */
@@ -186,7 +195,8 @@ LLCoordFrame::LLCoordFrame(const F32 *origin_and_rotation) :
 {
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::LLCoordFrame()" << llendl;
 	}
 }
 */
@@ -214,7 +224,8 @@ void LLCoordFrame::setOrigin(F32 x, F32 y, F32 z)
 
 	if( !mOrigin.isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::setOrigin()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::setOrigin()" << llendl;
 	}
 }
 
@@ -223,7 +234,8 @@ void LLCoordFrame::setOrigin(const LLVector3 &new_origin)
 	mOrigin = new_origin; 
 	if( !mOrigin.isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::setOrigin()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::setOrigin()" << llendl;
 	}
 }
 
@@ -235,7 +247,8 @@ void LLCoordFrame::setOrigin(const F32 *origin)
 
 	if( !mOrigin.isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::setOrigin()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::setOrigin()" << llendl;
 	}
 }
 
@@ -245,7 +258,8 @@ void LLCoordFrame::setOrigin(const LLCoordFrame &frame)
 
 	if( !mOrigin.isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::setOrigin()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::setOrigin()" << llendl;
 	}
 }
 
@@ -261,7 +275,8 @@ void LLCoordFrame::setAxes(const LLVector3 &x_axis,
 	mZAxis = z_axis;
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::setAxes()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::setAxes()" << llendl;
 	}
 }
 
@@ -273,7 +288,8 @@ void LLCoordFrame::setAxes(const LLMatrix3 &rotation_matrix)
 	mZAxis.setVec(rotation_matrix.mMatrix[VZ]);
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::setAxes()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::setAxes()" << llendl;
 	}
 }
 
@@ -284,7 +300,8 @@ void LLCoordFrame::setAxes(const LLQuaternion &q )
 	setAxes(rotation_matrix);
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::setAxes()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::setAxes()" << llendl;
 	}
 }
 
@@ -303,7 +320,8 @@ void LLCoordFrame::setAxes(  const F32 *rotation_matrix )
 
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::setAxes()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::setAxes()" << llendl;
 	}
 }
 
@@ -316,7 +334,8 @@ void LLCoordFrame::setAxes(const LLCoordFrame &frame)
 
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::setAxes()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::setAxes()" << llendl;
 	}
 }
 
@@ -331,7 +350,8 @@ void LLCoordFrame::translate(F32 x, F32 y, F32 z)
 
 	if( !mOrigin.isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::translate()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::translate()" << llendl;
 	}
 }
 
@@ -342,7 +362,8 @@ void LLCoordFrame::translate(const LLVector3 &v)
 
 	if( !mOrigin.isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::translate()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::translate()" << llendl;
 	}
 }
 
@@ -355,7 +376,8 @@ void LLCoordFrame::translate(const F32 *origin)
 
 	if( !mOrigin.isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::translate()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::translate()" << llendl;
 	}
 }
 
@@ -391,7 +413,8 @@ void LLCoordFrame::rotate(const LLMatrix3 &rotation_matrix)
 
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::rotate()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::rotate()" << llendl;
 	}
 }
 
@@ -404,7 +427,8 @@ void LLCoordFrame::roll(F32 angle)
 
 	if( !mYAxis.isFinite() || !mZAxis.isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::roll()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::roll()" << llendl;
 	}
 }
 
@@ -416,7 +440,8 @@ void LLCoordFrame::pitch(F32 angle)
 
 	if( !mXAxis.isFinite() || !mZAxis.isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::pitch()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::pitch()" << llendl;
 	}
 }
 
@@ -428,7 +453,8 @@ void LLCoordFrame::yaw(F32 angle)
 
 	if( !mXAxis.isFinite() || !mYAxis.isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::yaw()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::yaw()" << llendl;
 	}
 }
 
@@ -487,7 +513,8 @@ size_t LLCoordFrame::readOrientation(const char *buffer)
 
 	if( !isFinite() )
 	{
-		llerrs << "Non Finite in LLCoordFrame::readOrientation()" << llendl;
+		reset();
+		llwarns << "Non Finite in LLCoordFrame::readOrientation()" << llendl;
 	}
 
 	return 12*sizeof(F32);
diff --git a/indra/llmath/xform.h b/indra/llmath/xform.h
index e0e566b6c4b..9a5c99140ef 100644
--- a/indra/llmath/xform.h
+++ b/indra/llmath/xform.h
@@ -35,9 +35,6 @@
 #include "m4math.h"
 #include "llquaternion.h"
 
-#define CHECK_FOR_FINITE
-
-
 const F32 MAX_OBJECT_Z 		= 768.f;
 const F32 MIN_OBJECT_Z 		= -256.f;
 const F32 MIN_OBJECT_SCALE 	= 0.01f;
@@ -183,26 +180,15 @@ BOOL LLXform::setParent(LLXform* parent)
 	return TRUE;
 }
 
-
-// Don't blow up on release versions
-#if LL_RELEASE_FOR_DOWNLOAD
-	#define llxformtrouble(msg, num)	llwarning(msg, num)
-#else
-	#define llxformtrouble(msg, num)	llerror(msg, num)
-#endif
-
-
-#ifdef CHECK_FOR_FINITE
 void LLXform::setPosition(const LLVector3& pos)			
 {
 	setChanged(TRANSLATED);
 	if (pos.isFinite())
-	{
 		mPosition = pos; 
-	}
 	else
 	{
-		llxformtrouble("Non Finite in LLXform::setPosition(LLVector3)", 0);
+		mPosition.clearVec();
+		llwarns << "Non Finite in LLXform::setPosition(LLVector3)" << llendl;
 	}
 }
 
@@ -210,12 +196,11 @@ void LLXform::setPosition(const F32 x, const F32 y, const F32 z)
 {
 	setChanged(TRANSLATED);
 	if (llfinite(x) && llfinite(y) && llfinite(z))
-	{
 		mPosition.setVec(x,y,z); 
-	}
 	else
 	{
-		llxformtrouble("Non Finite in LLXform::setPosition(F32,F32,F32)", 0);
+		mPosition.clearVec();
+		llwarns << "Non Finite in LLXform::setPosition(F32,F32,F32)" << llendl;
 	}
 }
 
@@ -223,12 +208,11 @@ void LLXform::setPositionX(const F32 x)
 { 
 	setChanged(TRANSLATED);
 	if (llfinite(x))
-	{
 		mPosition.mV[VX] = x; 
-	}
 	else
 	{
-		llxformtrouble("Non Finite in LLXform::setPositionX", 0);
+		mPosition.mV[VX] = 0.f;
+		llwarns << "Non Finite in LLXform::setPositionX" << llendl;
 	}
 }
 
@@ -236,12 +220,11 @@ void LLXform::setPositionY(const F32 y)
 { 
 	setChanged(TRANSLATED);
 	if (llfinite(y))
-	{
 		mPosition.mV[VY] = y; 
-	}
 	else
 	{
-		llxformtrouble("Non Finite in LLXform::setPositionY", 0);
+		mPosition.mV[VY] = 0.f;
+		llwarns << "Non Finite in LLXform::setPositionY" << llendl;
 	}
 }
 
@@ -249,12 +232,11 @@ void LLXform::setPositionZ(const F32 z)
 { 
 	setChanged(TRANSLATED);
 	if (llfinite(z))
-	{
 		mPosition.mV[VZ] = z; 
-	}
 	else
 	{
-		llxformtrouble("Non Finite in LLXform::setPositionZ", 0);
+		mPosition.mV[VZ] = 0.f;
+		llwarns << "Non Finite in LLXform::setPositionZ" << llendl;
 	}
 }
 
@@ -262,49 +244,42 @@ void LLXform::addPosition(const LLVector3& pos)
 { 
 	setChanged(TRANSLATED);
 	if (pos.isFinite())
-	{
 		mPosition += pos; 
-	}
 	else
-	{
-		llxformtrouble("Non Finite in LLXform::addPosition", 0);
-	}
+		llwarns << "Non Finite in LLXform::addPosition" << llendl;
 }
 
 void LLXform::setScale(const LLVector3& scale)
 { 
 	setChanged(SCALED);
 	if (scale.isFinite())
-	{
 		mScale = scale; 
-	}
 	else
 	{
-		llxformtrouble("Non Finite in LLXform::setScale(LLVector)", 0);
+		mScale.setVec(1.f, 1.f, 1.f);
+		llwarns << "Non Finite in LLXform::setScale" << llendl;
 	}
 }
 void LLXform::setScale(const F32 x, const F32 y, const F32 z)
 { 
 	setChanged(SCALED);
 	if (llfinite(x) && llfinite(y) && llfinite(z))
-	{
 		mScale.setVec(x,y,z); 
-	}
 	else
 	{
-		llxformtrouble("Non Finite in LLXform::setScale(F32,F32,F32)", 0);
+		mScale.setVec(1.f, 1.f, 1.f);
+		llwarns << "Non Finite in LLXform::setScale" << llendl;
 	}
 }
 void LLXform::setRotation(const LLQuaternion& rot)
 { 
 	setChanged(ROTATED);
 	if (rot.isFinite())
-	{
 		mRotation = rot; 
-	}
 	else
 	{
-		llxformtrouble("Non Finite in LLXform::setRotation(LLQuaternion)", 0);
+		mRotation.loadIdentity();
+		llwarns << "Non Finite in LLXform::setRotation" << llendl;
 	}
 }
 void LLXform::setRotation(const F32 x, const F32 y, const F32 z) 
@@ -316,7 +291,8 @@ void LLXform::setRotation(const F32 x, const F32 y, const F32 z)
 	}
 	else
 	{
-		llxformtrouble("Non Finite in LLXform::setRotation(F32,F32,F32)", 0);
+		mRotation.loadIdentity();
+		llwarns << "Non Finite in LLXform::setRotation" << llendl;
 	}
 }
 void LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s) 
@@ -328,10 +304,9 @@ void LLXform::setRotation(const F32 x, const F32 y, const F32 z, const F32 s)
 	}
 	else
 	{
-		llxformtrouble("Non Finite in LLXform::setRotation(F32,F32,F32,F32)", 0);
+		mRotation.loadIdentity();
+		llwarns << "Non Finite in LLXform::setRotation" << llendl;
 	}
 }
 
 #endif
-
-#endif
diff --git a/indra/newview/linux_tools/launch_url.sh b/indra/newview/linux_tools/launch_url.sh
index a1c6f5dbd92..e6450ad5ff0 100755
--- a/indra/newview/linux_tools/launch_url.sh
+++ b/indra/newview/linux_tools/launch_url.sh
@@ -1,5 +1,4 @@
-#!/bin/sh
-# Script tested with: bash 1.14, bash 3.1.17, zsh 4.2.5, ksh 1993-12-28
+#!/bin/bash
 
 # This script loads a web page in the 'default' graphical web browser.
 # It MUST return immediately (or soon), so the browser should be
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index f720fc0ec1f..10041ee2553 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -1,5 +1,4 @@
-#!/bin/sh
-# Script tested with: bash 1.14, bash 3.1.17, zsh 4.2.5, ksh 1993-12-28
+#!/bin/bash
 
 ## Here are some configuration options for Linux Client Alpha Testers.
 ## These options are for self-assisted troubleshooting during this alpha
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index d0a21d2da66..3bc172c8309 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -1141,7 +1141,8 @@ void LLFloaterSnapshot::Impl::onCommitResolution(LLUICtrl* ctrl, void* data)
 		}
 		else if (width == -1 || height == -1)
 		{
-			// leave width and height when entering custom value				
+			// load last custom value
+			previewp->setSize(gSavedSettings.getS32("LastSnapshotWidth"), gSavedSettings.getS32("LastSnapshotHeight"));
 		}
 		else
 		{
@@ -1202,15 +1203,18 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat
 	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;		
 	if (view)
 	{
+		S32 w = llfloor((F32)view->childGetValue("snapshot_width").asReal());
+		S32 h = llfloor((F32)view->childGetValue("snapshot_height").asReal());
+
+		gSavedSettings.setS32("LastSnapshotWidth", w);
+		gSavedSettings.setS32("LastSnapshotHeight", h);
+
 		LLSnapshotLivePreview* previewp = getPreviewView(view);
 		if (previewp)
 		{
 			S32 curw,curh;
 			previewp->getSize(curw, curh);
 			
-			S32 w = llfloor((F32)view->childGetValue("snapshot_width").asReal());
-			S32 h = llfloor((F32)view->childGetValue("snapshot_height").asReal());
-			
 			if (w != curw || h != curh)
 			{
 				previewp->setSize(w,h);
@@ -1294,8 +1298,8 @@ BOOL LLFloaterSnapshot::postBuild()
 	childSetValue("layer_types", "colors");
 	childSetEnabled("layer_types", FALSE);
 
-	childSetValue("snapshot_width", gViewerWindow->getWindowDisplayWidth());
-	childSetValue("snapshot_height", gViewerWindow->getWindowDisplayHeight());
+	childSetValue("snapshot_width", gSavedSettings.getS32("LastSnapshotWidth"));
+	childSetValue("snapshot_height", gSavedSettings.getS32("LastSnapshotHeight"));
 
 	childSetValue("freeze_frame_check", gSavedSettings.getBOOL("UseFreezeFrame"));
 	childSetCommitCallback("freeze_frame_check", Impl::onCommitFreezeFrame, this);
-- 
GitLab