diff options
| author | Don Kjer <don@lindenlab.com> | 2011-04-26 18:01:18 +0000 | 
|---|---|---|
| committer | Don Kjer <don@lindenlab.com> | 2011-04-26 18:01:18 +0000 | 
| commit | c14b5c644d75df31a1ef151262480cf875134da2 (patch) | |
| tree | 9284620a254873585b637f625456c88e9e371436 | |
| parent | 77791a88a9811f71cc9af668d28a903645436be0 (diff) | |
| parent | b87cb90a55ed74d51587eec581fb57e29f510c41 (diff) | |
Merge with viewer-development
82 files changed, 2842 insertions, 2150 deletions
| @@ -101,6 +101,9 @@ d1203046bb653b763f835b04d184646949d8dd5c 2.6.2-beta1  ec32f1045e7c2644015245df3a9933620aa194b8 2.6.3-start  d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc DRTVWR-47_2.6.3-beta1  d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc 2.6.3-beta1 +0630e977504af5ea320c58d33cae4e1ddee793e9 DRTVWR-48_2.6.3-beta2 +0630e977504af5ea320c58d33cae4e1ddee793e9 2.6.3-beta2  74cd32a06837b0c2cb793b2e8d4d82f5d49462b2 2.6.4-start  74cd32a06837b0c2cb793b2e8d4d82f5d49462b2 2.6.4-start  f632f87bb71b0f13d21f2f64b0c42cedb008c749 2.6.4-start +800cefce8d364ffdd2f383cbecb91294da3ea424 2.6.6-start diff --git a/BuildParams b/BuildParams index 3b711397e3..2cb58755e5 100644 --- a/BuildParams +++ b/BuildParams @@ -67,11 +67,12 @@ viewer-pre-release.login_channel = "Second Life Release"  viewer-pre-release.build_debug_release_separately = true  viewer-pre-release.build_viewer_update_version_manager = true  #viewer-pre-release.release-viewer.jira = DRTVWR-13 +viewer-pre-release.release-viewer.jira = DRTVWR-46 +  # =======================================  # brad  # ======================================== -  debug-halting.email = cg@lindenlab.com  debug-halting.build_server = false  debug-halting.build_server_tests = false @@ -158,8 +159,10 @@ media.build_viewer_update_version_manager = false  oz_viewer-devreview.build_debug_release_separately = true  oz_project-1.build_debug_release_separately = true  oz_project-2.build_debug_release_separately = true -oz_project-3.build_debug_release_separately = true +oz-project-3.build_debug_release_separately = true + +oz_viewer-beta-review.build_debug_release_separately = true  # ========================================  # enus  # ======================================== diff --git a/autobuild.xml b/autobuild.xml index a9ab71da29..bd98d59766 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -510,9 +510,9 @@              <key>archive</key>              <map>                <key>hash</key> -              <string>9b58d1a9c15807a1301e42a313641010</string> +              <string>9f8a9dc39fd7c3da0fb3533782d1fddf</string>                <key>url</key> -              <string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/freetype-2.4.4-linux-20110310.tar.bz2</string> +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-freetype/rev/226814/arch/Linux/installer/freetype-2.3.9-linux-20110418.tar.bz2</string>              </map>              <key>name</key>              <string>linux</string> @@ -1242,9 +1242,9 @@              <key>archive</key>              <map>                <key>hash</key> -              <string>cc159598ef3fcd34fd33a8a0ef846165</string> +              <string>3d40be8566fa4b9df9a38e2a0f9ea467</string>                <key>url</key> -              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-openssl/rev/223711/arch/Linux/installer/openssl-0.9.8q-linux-20110314.tar.bz2</string> +              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-openssl/rev/226882/arch/Linux/installer/openssl-1.0.0d-linux-20110418.tar.bz2</string>              </map>              <key>name</key>              <string>linux</string> @@ -1592,6 +1592,7 @@                    <string>-DCMAKE_BUILD_TYPE:STRING=Debug</string>                    <string>-DWORD_SIZE:STRING=32</string>                    <string>-DROOT_PROJECT_NAME:STRING=SecondLife</string> +                  <string>-DINSTALL_PROPRIETARY=TRUE</string>                  </array>                </map>                <key>name</key> @@ -1632,6 +1633,7 @@                    <string>-DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo</string>                    <string>-DWORD_SIZE:STRING=32</string>                    <string>-DROOT_PROJECT_NAME:STRING=SecondLife</string> +                  <string>-DINSTALL_PROPRIETARY=TRUE</string>                  </array>                </map>                <key>name</key> @@ -1672,9 +1674,9 @@                    <string>-DCMAKE_BUILD_TYPE:STRING=Release</string>                    <string>-DWORD_SIZE:STRING=32</string>                    <string>-DROOT_PROJECT_NAME:STRING=SecondLife</string> -                  <string>-DINSTALL_PROPRIETARY=FALSE</string>                    <string>-DUSE_PRECOMPILED_HEADERS=ON</string>                    <string>-DLL_RELEASE_FOR_DOWNLOAD:BOOL=TRUE</string> +                  <string>-DINSTALL_PROPRIETARY=TRUE</string>                  </array>                </map>                <key>name</key> diff --git a/doc/contributions.txt b/doc/contributions.txt index e7db8c0ded..a19967fd4d 100644 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -424,6 +424,7 @@ Jonathan Yap  	STORM-1094  	STORM-1077  	STORM-953 +	STORM-1095  Kage Pixel  	VWR-11  Ken March @@ -588,7 +589,7 @@ Nicholaz Beresford  	VWR-2684  Nicky Perian  	OPEN-1 -	OPEN-1087 +	STORM-1087  	STORM-1090  Nounouch Hapmouche  	VWR-238 @@ -660,6 +661,7 @@ Robin Cornelius  	STORM-422  	STORM-960  	STORM-1019 +	STORM-1095  	VWR-2488  	VWR-9557  	VWR-10579 @@ -710,6 +712,7 @@ Shawn Kaufmat  	SNOW-240  Siana Gearz  	STORM-960 +	STORM-1088  SignpostMarv Martin  	VWR-153  	VWR-154 diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 4698116022..1c43c4ce12 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -243,7 +243,7 @@ elseif(LINUX)          libaprutil-1.so.0          libatk-1.0.so          libbreakpad_client.so.0 -        libcrypto.so.0.9.8 +        libcrypto.so.1.0.0          libdb-5.1.so          libexpat.so          libexpat.so.1 @@ -259,7 +259,7 @@ elseif(LINUX)          libtcmalloc.so          libuuid.so.16          libuuid.so.16.0.22 -        libssl.so.0.9.8 +        libssl.so.1.0.0          libfontconfig.so.1.4.4         ) diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 8c9c375790..03428691cf 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -102,7 +102,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")    set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)    set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk)    set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "4.2") -  set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "DWARF with dSYM File") +  set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)    # NOTE: To attempt an i386/PPC Universal build, add this on the configure line:    # -DCMAKE_OSX_ARCHITECTURES:STRING='i386;ppc' diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp index 365f5f758c..60ddf63b21 100644 --- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp +++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp @@ -53,12 +53,32 @@ static const char USAGE[] = "\n"  " -o, --output <file1 .. file2> OR <type>\n"  "        List of image files to create (assumes same order as for input files)\n"  "        OR 3 letters file type extension to convert each input file into.\n" +" -r, --region <x0, y0, x1, y1>\n" +"        Crop region applied to the input files in pixels.\n" +"        Only used for j2c images. Default is no region cropping.\n" +" -d, --discard_level <n>\n" +"        Discard level max used on input. 0 is highest resolution. Max discard level is 5.\n" +"        This allows the input image to be clamped in resolution when loading.\n" +"        Only valid for j2c images. Default is no discard.\n" +" -p, --precincts <n>\n" +"        Dimension of precincts in pixels. Precincts are assumed square and identical for\n" +"        all levels. Note that this option also add PLT and tile markers to the codestream, \n" +"        and uses RPCL order. Power of 2 must be used.\n" +"        Only valid for output j2c images. Default is no precincts used.\n" +" -b, --blocks <n>\n" +"        Dimension of coding blocks in pixels. Blocks are assumed square. Power of 2 must\n" +"        be used. Blocks must be smaller than precincts. Like precincts, this option adds\n" +"        PLT, tile markers and uses RPCL.\n" +"        Only valid for output j2c images. Default is 64.\n" +" -rev, --reversible\n" +"        Set the compression to be lossless (reversible in j2c parlance).\n" +"        Only valid for output j2c images.\n"  " -log, --logmetrics <metric>\n"  "        Log performance data for <metric>. Results in <metric>.slp\n"  "        Note: so far, only ImageCompressionTester has been tested.\n" -" -r, --analyzeperformance\n" +" -a, --analyzeperformance\n"  "        Create a report comparing <metric>_baseline.slp with current <metric>.slp\n" -"        Results in <metric>_report.csv" +"        Results in <metric>_report.csv\n"  " -s, --image-stats\n"  "        Output stats for each input and output image.\n"  "\n"; @@ -69,31 +89,8 @@ static bool sAllDone = false;  // Create an empty formatted image instance of the correct type from the filename  LLPointer<LLImageFormatted> create_image(const std::string &filename)  { -	std::string exten = gDirUtilp->getExtension(filename); -	U32 codec = LLImageBase::getCodecFromExtension(exten); -	 -	LLPointer<LLImageFormatted> image; -	switch (codec) -	{ -		case IMG_CODEC_BMP: -			image = new LLImageBMP(); -			break; -		case IMG_CODEC_TGA: -			image = new LLImageTGA(); -			break; -		case IMG_CODEC_JPEG: -			image = new LLImageJPEG(); -			break; -		case IMG_CODEC_J2C: -			image = new LLImageJ2C(); -			break; -		case IMG_CODEC_PNG: -			image = new LLImagePNG(); -			break; -		default: -			return NULL; -	} -	 +	std::string exten = gDirUtilp->getExtension(filename);	 +	LLPointer<LLImageFormatted> image = LLImageFormatted::createFromExtension(exten);  	return image;  } @@ -110,10 +107,11 @@ void output_image_stats(LLPointer<LLImageFormatted> image, const std::string &fi  }  // Load an image from file and return a raw (decompressed) instance of its data -LLPointer<LLImageRaw> load_image(const std::string &src_filename, bool output_stats) +LLPointer<LLImageRaw> load_image(const std::string &src_filename, int discard_level, int* region, bool output_stats)  {  	LLPointer<LLImageFormatted> image = create_image(src_filename); - +	 +	// This just loads the image file stream into a buffer. No decoding done.  	if (!image->load(src_filename))  	{  		return NULL; @@ -131,6 +129,15 @@ LLPointer<LLImageRaw> load_image(const std::string &src_filename, bool output_st  	}  	LLPointer<LLImageRaw> raw_image = new LLImageRaw; +	 +	// Set the image restriction on load in the case of a j2c image +	if ((image->getCodec() == IMG_CODEC_J2C) && ((discard_level != -1) || (region != NULL))) +	{ +		// That method doesn't exist (and likely, doesn't make sense) for any other image file format +		// hence the required cryptic cast. +		((LLImageJ2C*)(image.get()))->initDecode(*raw_image, discard_level, region); +	} +	  	if (!image->decode(raw_image, 0.0f))  	{  		return NULL; @@ -140,10 +147,22 @@ LLPointer<LLImageRaw> load_image(const std::string &src_filename, bool output_st  }  // Save a raw image instance into a file -bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_image, bool output_stats) +bool save_image(const std::string &dest_filename, LLPointer<LLImageRaw> raw_image, int blocks_size, int precincts_size, bool reversible, bool output_stats)  {  	LLPointer<LLImageFormatted> image = create_image(dest_filename); +	// Set the image codestream parameters on output in the case of a j2c image +	if (image->getCodec() == IMG_CODEC_J2C) +	{ +		// That method doesn't exist (and likely, doesn't make sense) for any other image file format +		// hence the required cryptic cast. +		if ((blocks_size != -1) || (precincts_size != -1)) +		{ +			((LLImageJ2C*)(image.get()))->initEncode(*raw_image, blocks_size, precincts_size); +		} +		((LLImageJ2C*)(image.get()))->setReversible(reversible); +	} +	  	if (!image->encode(raw_image, 0.0f))  	{  		return false; @@ -280,8 +299,14 @@ int main(int argc, char** argv)  	// List of input and output files  	std::list<std::string> input_filenames;  	std::list<std::string> output_filenames; +	// Other optional parsed arguments  	bool analyze_performance = false;  	bool image_stats = false; +	int* region = NULL; +	int discard_level = -1; +	int precincts_size = -1; +	int blocks_size = -1; +	bool reversible = false;  	// Init whatever is necessary  	ll_init_apr(); @@ -323,6 +348,85 @@ int main(int argc, char** argv)  				file_name = argv[arg+1];	// Next argument and loop over  			}  		} +		else if ((!strcmp(argv[arg], "--region") || !strcmp(argv[arg], "-r")) && arg < argc-1) +		{ +			std::string value_str = argv[arg+1]; +			int index = 0; +			region = new int[4]; +			while (value_str[0] != '-')		// if arg starts with '-', it's the next option +			{ +				int value = atoi(value_str.c_str()); +				region[index++] = value; +				arg += 1;					// Definitely skip that arg now we know it's a number +				if ((arg + 1) == argc)		// Break out of the loop if we reach the end of the arg list +					break; +				if (index == 4)				// Break out of the loop if we captured 4 values already +					break; +				value_str = argv[arg+1];	// Next argument and loop over +			} +			if (index != 4) +			{ +				std::cout << "--region arguments invalid" << std::endl; +				delete [] region; +				region = NULL; +			} +		} +		else if (!strcmp(argv[arg], "--discard_level") || !strcmp(argv[arg], "-d")) +		{ +			std::string value_str; +			if ((arg + 1) < argc) +			{ +				value_str = argv[arg+1]; +			} +			if (((arg + 1) >= argc) || (value_str[0] == '-')) +			{ +				std::cout << "No valid --discard_level argument given, discard_level ignored" << std::endl; +			} +			else +			{ +				discard_level = atoi(value_str.c_str()); +				// Clamp to the values accepted by the viewer +				discard_level = llclamp(discard_level,0,5); +			} +		} +		else if (!strcmp(argv[arg], "--precincts") || !strcmp(argv[arg], "-p")) +		{ +			std::string value_str; +			if ((arg + 1) < argc) +			{ +				value_str = argv[arg+1]; +			} +			if (((arg + 1) >= argc) || (value_str[0] == '-')) +			{ +				std::cout << "No valid --precincts argument given, precincts ignored" << std::endl; +			} +			else +			{ +				precincts_size = atoi(value_str.c_str()); +				// *TODO: make sure precincts_size is a power of 2 +			} +		} +		else if (!strcmp(argv[arg], "--blocks") || !strcmp(argv[arg], "-b")) +		{ +			std::string value_str; +			if ((arg + 1) < argc) +			{ +				value_str = argv[arg+1]; +			} +			if (((arg + 1) >= argc) || (value_str[0] == '-')) +			{ +				std::cout << "No valid --blocks argument given, blocks ignored" << std::endl; +			} +			else +			{ +				blocks_size = atoi(value_str.c_str()); +				// *TODO: make sure blocks_size is a power of 2 +			} +		} +		else if (!strcmp(argv[arg], "--reversible") || !strcmp(argv[arg], "-rev")) +		{ +			reversible = true; +		}  		else if (!strcmp(argv[arg], "--logmetrics") || !strcmp(argv[arg], "-log"))  		{  			// '--logmetrics' needs to be specified with a named test metric argument @@ -346,7 +450,7 @@ int main(int argc, char** argv)  					break;  			}  		} -		else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-r")) +		else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-a"))  		{  			analyze_performance = true;  		} @@ -364,7 +468,7 @@ int main(int argc, char** argv)  	}  	if (analyze_performance && !LLFastTimer::sMetricLog)  	{ -		std::cout << "Cannot create perf report if no perf gathered (i.e. use argument -log <perf> with -r) -> exit" << std::endl; +		std::cout << "Cannot create perf report if no perf gathered (i.e. use argument -log <perf> with -a) -> exit" << std::endl;  		return 0;  	} @@ -382,10 +486,10 @@ int main(int argc, char** argv)  	std::list<std::string>::iterator out_file = output_filenames.begin();  	std::list<std::string>::iterator in_end = input_filenames.end();  	std::list<std::string>::iterator out_end = output_filenames.end(); -	for (; in_file != in_end; ++in_file) +	for (; in_file != in_end; ++in_file, ++out_file)  	{  		// Load file -		LLPointer<LLImageRaw> raw_image = load_image(*in_file, image_stats); +		LLPointer<LLImageRaw> raw_image = load_image(*in_file, discard_level, region, image_stats);  		if (!raw_image)  		{  			std::cout << "Error: Image " << *in_file << " could not be loaded" << std::endl; @@ -395,7 +499,7 @@ int main(int argc, char** argv)  		// Save file  		if (out_file != out_end)  		{ -			if (!save_image(*out_file, raw_image, image_stats)) +			if (!save_image(*out_file, raw_image, blocks_size, precincts_size, reversible, image_stats))  			{  				std::cout << "Error: Image " << *out_file << " could not be saved" << std::endl;  			} @@ -403,29 +507,28 @@ int main(int argc, char** argv)  			{  				std::cout << *in_file << " -> " << *out_file << std::endl;  			} -			++out_file;  		}  	} -	// Stop the perf gathering system if needed -	if (LLFastTimer::sMetricLog) -	{ -		LLMetricPerformanceTesterBasic::deleteTester(LLFastTimer::sLogName); -		sAllDone = true; -	} -	  	// Output perf data if requested by user  	if (analyze_performance)  	{ -		std::cout << "Analyzing performance" << std::endl; -		  		std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp";  		std::string current_name  = LLFastTimer::sLogName + ".slp";   		std::string report_name   = LLFastTimer::sLogName + "_report.csv"; +		std::cout << "Analyzing performance, check report in : " << report_name << std::endl; +  		LLMetricPerformanceTesterBasic::doAnalysisMetrics(baseline_name, current_name, report_name);  	} +	// Stop the perf gathering system if needed +	if (LLFastTimer::sMetricLog) +	{ +		LLMetricPerformanceTesterBasic::deleteTester(LLFastTimer::sLogName); +		sAllDone = true; +	} +	  	// Cleanup and exit  	LLImage::cleanupClass();  	if (fast_timer_log_thread) diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index df5afcbf1c..58f96df8ab 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -29,7 +29,7 @@  const S32 LL_VERSION_MAJOR = 2;  const S32 LL_VERSION_MINOR = 6; -const S32 LL_VERSION_PATCH = 6; +const S32 LL_VERSION_PATCH = 7;  const S32 LL_VERSION_BUILD = 0;  const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index 39211bf7fa..f0d15d9607 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -1254,28 +1254,7 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip  		return false;  	} -	LLPointer<LLImageFormatted> image; -	switch(codec) -	{ -	  //case IMG_CODEC_RGB: -	  case IMG_CODEC_BMP: -		image = new LLImageBMP(); -		break; -	  case IMG_CODEC_TGA: -		image = new LLImageTGA(); -		break; -	  case IMG_CODEC_JPEG: -		image = new LLImageJPEG(); -		break; -	  case IMG_CODEC_J2C: -		image = new LLImageJ2C(); -		break; -	  case IMG_CODEC_DXT: -		image = new LLImageDXT(); -		break; -	  default: -		return false; -	} +	LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);  	llassert(image.notNull());  	U8 *buffer = image->allocateData(length); diff --git a/indra/llimage/llimagej2c.cpp b/indra/llimage/llimagej2c.cpp index 80fec7f8a0..a90df0f1c1 100644 --- a/indra/llimage/llimagej2c.cpp +++ b/indra/llimage/llimagej2c.cpp @@ -139,6 +139,15 @@ BOOL LLImageJ2C::updateData()  	return res;  } +BOOL LLImageJ2C::initDecode(LLImageRaw &raw_image, int discard_level, int* region) +{ +	return mImpl->initDecode(*this,raw_image,discard_level,region); +} + +BOOL LLImageJ2C::initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size) +{ +	return mImpl->initEncode(*this,raw_image,blocks_size,precincts_size); +}  BOOL LLImageJ2C::decode(LLImageRaw *raw_imagep, F32 decode_time)  { @@ -251,6 +260,9 @@ S32 LLImageJ2C::calcHeaderSizeJ2C()  //static  S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 rate)  { +	// Note: this only provides an *estimate* of the size in bytes of an image level +	// *TODO: find a way to read the true size (when available) and convey the fact +	// that the result is an estimate in the other cases  	if (rate <= 0.f) rate = .125f;  	while (discard_level > 0)  	{ diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h index dd5bec8b2e..6bba81aab5 100644 --- a/indra/llimage/llimagej2c.h +++ b/indra/llimage/llimagej2c.h @@ -56,6 +56,8 @@ public:  	/*virtual*/ void resetLastError();  	/*virtual*/ void setLastError(const std::string& message, const std::string& filename = std::string()); +	BOOL initDecode(LLImageRaw &raw_image, int discard_level, int* region); +	BOOL initEncode(LLImageRaw &raw_image, int blocks_size, int precincts_size);  	// Encode with comment text   	BOOL encode(const LLImageRaw *raw_imagep, const char* comment_text, F32 encode_time=0.0); @@ -117,6 +119,8 @@ protected:  	virtual BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count) = 0;  	virtual BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,  							BOOL reversible=FALSE) = 0; +	virtual BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL) = 0; +	virtual BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1) = 0;  	friend class LLImageJ2C;  }; diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index 13b12c0928..8288fa1f5c 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -107,6 +107,17 @@ LLImageJ2COJ::~LLImageJ2COJ()  {  } +BOOL LLImageJ2COJ::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) +{ +	// No specific implementation for this method in the OpenJpeg case +	return FALSE; +} + +BOOL LLImageJ2COJ::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size) +{ +	// No specific implementation for this method in the OpenJpeg case +	return FALSE; +}  BOOL LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count)  { diff --git a/indra/llimagej2coj/llimagej2coj.h b/indra/llimagej2coj/llimagej2coj.h index 9476665ccb..9c7cc09fcb 100644 --- a/indra/llimagej2coj/llimagej2coj.h +++ b/indra/llimagej2coj/llimagej2coj.h @@ -39,6 +39,8 @@ protected:  	/*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);  	/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,  								BOOL reversible = FALSE); +	/*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); +	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1);  };  #endif diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 10ea5685e8..ae456a48be 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -34,35 +34,35 @@  class kdc_flow_control { -public: // Member functions -    kdc_flow_control(kdu_image_in_base *img_in, kdu_codestream codestream); -    ~kdc_flow_control(); -    bool advance_components(); -    void process_components(); +public: +	kdc_flow_control(kdu_image_in_base *img_in, kdu_codestream codestream); +	~kdc_flow_control(); +	bool advance_components(); +	void process_components(); +	 +private: -private: // Data -     -    struct kdc_component_flow_control { -    public: // Data -        kdu_image_in_base *reader; -        int vert_subsampling; -        int ratio_counter;  /*  Initialized to 0, decremented by `count_delta'; +	struct kdc_component_flow_control { +	public: +		kdu_image_in_base *reader; +		int vert_subsampling; +		int ratio_counter;  /*  Initialized to 0, decremented by `count_delta';                                  when < 0, a new line must be processed, after                                  which it is incremented by `vert_subsampling'.  */ -        int initial_lines; -        int remaining_lines; -        kdu_line_buf *line; -    }; -     -    kdu_codestream codestream; -    kdu_dims valid_tile_indices; -    kdu_coords tile_idx; -    kdu_tile tile; -    int num_components; -    kdc_component_flow_control *components; -    int count_delta; // Holds the minimum of the `vert_subsampling' fields -    kdu_multi_analysis engine; -    kdu_long max_buffer_memory; +		int initial_lines; +		int remaining_lines; +		kdu_line_buf *line; +	}; +	 +	kdu_codestream codestream; +	kdu_dims valid_tile_indices; +	kdu_coords tile_idx; +	kdu_tile tile; +	int num_components; +	kdc_component_flow_control *components; +	int count_delta; // Holds the minimum of the `vert_subsampling' fields +	kdu_multi_analysis engine; +	kdu_long max_buffer_memory;  };  // @@ -72,7 +72,8 @@ void set_default_colour_weights(kdu_params *siz);  const char* engineInfoLLImageJ2CKDU()  { -	return "KDU v6.4.1"; +	std::string version = llformat("KDU %s", KDU_CORE_VERSION); +	return version.c_str();  }  LLImageJ2CKDU* createLLImageJ2CKDU() @@ -105,7 +106,11 @@ const char* fallbackEngineInfoLLImageJ2CImpl()  class LLKDUDecodeState  {  public: +	LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap); +	~LLKDUDecodeState(); +	BOOL processTileDecode(F32 decode_time, BOOL limit_time = TRUE); +private:  	S32 mNumComponents;  	BOOL mUseYCC;  	kdu_dims mDims; @@ -113,22 +118,12 @@ public:  	kdu_tile_comp mComps[4];  	kdu_line_buf mLines[4];  	kdu_pull_ifc mEngines[4]; -	bool mReversible[4]; // Some components may be reversible and others not. -	int mBitDepths[4]; // Original bit-depth may be quite different from 8. - +	bool mReversible[4]; // Some components may be reversible and others not +	int mBitDepths[4];   // Original bit-depth may be quite different from 8 +	  	kdu_tile mTile;  	kdu_byte *mBuf;  	S32 mRowGap; - -	LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap); -	~LLKDUDecodeState(); -	BOOL processTileDecode(F32 decode_time, BOOL limit_time = TRUE); - -public: -	int *AssignLayerBytes(siz_params *siz, int &num_specs); - -	void setupCodeStream(BOOL keep_codestream, LLImageJ2CKDU::ECodeStreamMode mode); -	BOOL initDecode(LLImageRaw &raw_image, F32 decode_time, LLImageJ2CKDU::ECodeStreamMode mode, S32 first_channel, S32 max_channel_count );  };  void ll_kdu_error( void ) @@ -153,7 +148,7 @@ class LLKDUMessageError : public kdu_message  public:  	/*virtual*/ void put_text(const char *s);  	/*virtual*/ void put_text(const kdu_uint16 *s); -	/*virtual*/ void flush(bool end_of_message=false); +	/*virtual*/ void flush(bool end_of_message = false);  	static LLKDUMessageError sDefaultMessage;  }; @@ -179,7 +174,7 @@ void LLKDUMessageError::put_text(const kdu_uint16 *s)  void LLKDUMessageError::flush(bool end_of_message)  { -	if( end_of_message )  +	if (end_of_message)   	{  		throw "KDU throwing an exception";  	} @@ -195,7 +190,9 @@ mCodeStreamp(NULL),  mTPosp(NULL),  mTileIndicesp(NULL),  mRawImagep(NULL), -mDecodeState(NULL) +mDecodeState(NULL), +mBlocksSize(-1), +mPrecinctsSize(-1)  {  } @@ -210,7 +207,7 @@ void transfer_bytes(kdu_byte *dest, kdu_line_buf &src, int gap, int precision);  void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode)  {  	S32 data_size = base.getDataSize(); -	S32 max_bytes = base.getMaxBytes() ? base.getMaxBytes() : data_size; +	S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size);  	//  	//  Initialization @@ -247,21 +244,21 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECod  	// Set the maximum number of bytes to use from the codestream  	mCodeStreamp->set_max_bytes(max_bytes); -	//    If you want to flip or rotate the image for some reason, change +	//	If you want to flip or rotate the image for some reason, change  	// the resolution, or identify a restricted region of interest, this is  	// the place to do it.  You may use "kdu_codestream::change_appearance"  	// and "kdu_codestream::apply_input_restrictions" for this purpose. -	//    If you wish to truncate the code-stream prior to decompression, you +	//	If you wish to truncate the code-stream prior to decompression, you  	// may use "kdu_codestream::set_max_bytes". -	//    If you wish to retain all compressed data so that the material +	//	If you wish to retain all compressed data so that the material  	// can be decompressed multiple times, possibly with different appearance  	// parameters, you should call "kdu_codestream::set_persistent" here. -	//    There are a variety of other features which must be enabled at +	//	There are a variety of other features which must be enabled at  	// this point if you want to take advantage of them.  See the  	// descriptions appearing with the "kdu_codestream" interface functions  	// in "kdu_compressed.h" for an itemized account of these capabilities. -	switch( mode ) +	switch (mode)  	{  	case MODE_FAST:  		mCodeStreamp->set_fast(); @@ -326,7 +323,19 @@ void LLImageJ2CKDU::cleanupCodeStream()  	mTileIndicesp = NULL;  } -BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count ) +BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level, int* region) +{ +	return initDecode(base,raw_image,0.0f,MODE_FAST,0,4,discard_level,region); +} + +BOOL LLImageJ2CKDU::initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size, int precincts_size) +{ +	mBlocksSize = blocks_size; +	mPrecinctsSize = precincts_size; +	return TRUE; +} + +BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level, int* region)  {  	base.resetLastError(); @@ -339,17 +348,36 @@ BOOL LLImageJ2CKDU::initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco  		mRawImagep = &raw_image;  		mCodeStreamp->change_appearance(false, true, false); -		mCodeStreamp->apply_input_restrictions(first_channel,max_channel_count,base.getRawDiscardLevel(),0,NULL); -		kdu_dims dims; mCodeStreamp->get_dims(0,dims); -		S32 channels = base.getComponents() - first_channel; -		if( channels > max_channel_count ) +		// Apply loading discard level and cropping if required +		kdu_dims* region_kdu = NULL; +		if (region != NULL)  		{ -			channels = max_channel_count; +			region_kdu = new kdu_dims; +			region_kdu->pos.x  = region[0]; +			region_kdu->pos.y  = region[1]; +			region_kdu->size.x = region[2] - region[0]; +			region_kdu->size.y = region[3] - region[1];  		} +		int discard = (discard_level != -1 ? discard_level : base.getRawDiscardLevel()); +		 +		// Apply loading restrictions +		mCodeStreamp->apply_input_restrictions( first_channel, max_channel_count, discard, 0, region_kdu); +		 +		// Clean-up +		if (region_kdu) +		{ +			delete region_kdu; +			region_kdu = NULL; +		} + +		// Resize raw_image according to the image to be decoded +		kdu_dims dims; mCodeStreamp->get_dims(0,dims); +		S32 channels = base.getComponents() - first_channel; +		channels = llmin(channels,max_channel_count);  		raw_image.resize(dims.size.x, dims.size.y, channels); +		//	llinfos << "Resizing raw_image to " << dims.size.x << ":" << dims.size.y << llendl; -		//	llinfos << "Resizing to " << dims.size.x << ":" << dims.size.y << llendl;  		if (!mTileIndicesp)  		{  			mTileIndicesp = new kdu_dims; @@ -426,7 +454,7 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco  					// canvas coordinate system.  Comparing the two tells  					// us where the current tile is in the buffer.  					S32 channels = base.getComponents() - first_channel; -					if( channels > max_channel_count ) +					if (channels > max_channel_count)  					{  						channels = max_channel_count;  					} @@ -452,14 +480,14 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco  					return FALSE;  				}  			} -			catch( const char* msg ) +			catch (const char* msg)  			{  				base.setLastError(ll_safe_string(msg));  				base.decodeFailed();  				cleanupCodeStream();  				return TRUE; // done  			} -			catch( ... ) +			catch (...)  			{  				base.setLastError( "Unknown J2C error" );  				base.decodeFailed(); @@ -482,28 +510,17 @@ BOOL LLImageJ2CKDU::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 deco  BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, BOOL reversible)  { -	// Collect simple arguments. -	bool transpose, vflip, hflip; -	bool allow_rate_prediction, mem, quiet, no_weights; -	int cpu_iterations; -	std::ostream *record_stream; - -	transpose = false; -	record_stream = NULL; -	allow_rate_prediction = true; -	no_weights = false; -	cpu_iterations = -1; -	mem = false; -	quiet = false; -	vflip = true; -	hflip = false; +	// Declare and set simple arguments +	bool transpose = false; +	bool vflip = true; +	bool hflip = false;  	try  	{ -		// Set up input image files. +		// Set up input image files  		siz_params siz; -		// Should set rate someplace here. +		// Should set rate someplace here  		LLKDUMemIn mem_in(raw_image.getData(),  			raw_image.getDataSize(),  			raw_image.getWidth(), @@ -521,26 +538,17 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co  		siz.set(Sprecision,0,0,8);  // Image samples have original bit-depth of 8  		siz.set(Ssigned,0,0,false); // Image samples are originally unsigned -		kdu_params *siz_ref = &siz; siz_ref->finalize(); -		siz_params transformed_siz; // Use this one to construct code-strea +		kdu_params *siz_ref = &siz;  +		siz_ref->finalize(); +		siz_params transformed_siz; // Use this one to construct code-stream  		transformed_siz.copy_from(&siz,-1,-1,-1,0,transpose,false,false); -		// Construct the `kdu_codestream' object and parse all remaining arguments. - +		// Construct the `kdu_codestream' object and parse all remaining arguments  		U32 max_output_size = base.getWidth()*base.getHeight()*base.getComponents(); -		if (max_output_size < 1000) -		{ -			max_output_size = 1000; -		} +		max_output_size = (max_output_size < 1000 ? 1000 : max_output_size);  		U8 *output_buffer = new U8[max_output_size]; - -		U32 output_size = max_output_size; // gets modified -		LLKDUMemTarget output(output_buffer, output_size, base.getWidth()*base.getHeight()*base.getComponents()); -		if (output_size > max_output_size) -		{ -			llerrs << llformat("LLImageJ2C::encode output_size(%d) > max_output_size(%d)", -				output_size,max_output_size) << llendl; -		} +		U32 output_size = 0; // Address updated by LLKDUMemTarget to give the final compressed buffer size +		LLKDUMemTarget output(output_buffer, output_size, max_output_size);  		kdu_codestream codestream;  		codestream.create(&transformed_siz,&output); @@ -558,16 +566,22 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co  		kdu_long layer_bytes[64];  		U32 max_bytes = 0; -		if ((num_components >= 3) && !no_weights) +		if (num_components >= 3)  		{ +			// Note that we always use YCC and not YUV +			// *TODO: Verify this doesn't screws up reversible textures (like sculpties) as YCC is not reversible but YUV is...  			set_default_colour_weights(codestream.access_siz());  		}  		if (reversible)  		{ -			// If we're doing reversible, assume we're not using quality layers. -			// Yes, I know this is incorrect!  			codestream.access_siz()->parse_string("Creversible=yes"); +			// *TODO: we should use yuv in reversible mode and one level since those images are small.  +			// Don't turn this on now though as both create problems on decoding for the moment +			//codestream.access_siz()->parse_string("Clevels=1"); +			//codestream.access_siz()->parse_string("Cycc=no"); +			// If we're doing reversible (i.e. lossless compression), assumes we're not using quality layers. +			// *TODO: this is incorrect and unecessary. Try using the regular layer setting.  			codestream.access_siz()->parse_string("Clayers=1");  			num_layer_specs = 1;  			layer_bytes[0] = 0; @@ -577,6 +591,7 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co  			// Rate is the argument passed into the LLImageJ2C which  			// specifies the target compression rate.  The default is 8:1.  			// Possibly if max_bytes < 500, we should just use the default setting? +			// *TODO: mRate is actually always 8:1 in the viewer. Test different values. Also force to reversible for small (< 500 bytes) textures.  			if (base.mRate != 0.f)  			{  				max_bytes = (U32)(base.mRate*base.getWidth()*base.getHeight()*base.getComponents()); @@ -617,42 +632,56 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co  				codestream.access_siz()->parse_string(layer_string.c_str());  			}  		} -		codestream.access_siz()->finalize_all(); -		if (cpu_iterations >= 0) +		 +		// Set up data ordering, markers, etc... if precincts or blocks specified +		if ((mBlocksSize != -1) || (mPrecinctsSize != -1))  		{ -			codestream.collect_timing_stats(cpu_iterations); +			if (mPrecinctsSize != -1) +			{ +				std::string precincts_string = llformat("Cprecincts={%d,%d}",mPrecinctsSize,mPrecinctsSize); +				codestream.access_siz()->parse_string(precincts_string.c_str()); +			} +			if (mBlocksSize != -1) +			{ +				std::string blocks_string = llformat("Cblk={%d,%d}",mBlocksSize,mBlocksSize); +				codestream.access_siz()->parse_string(blocks_string.c_str()); +			} +			std::string ordering_string = llformat("Corder=RPCL"); +			codestream.access_siz()->parse_string(ordering_string.c_str()); +			std::string PLT_string = llformat("ORGgen_plt=yes"); +			codestream.access_siz()->parse_string(PLT_string.c_str()); +			std::string Parts_string = llformat("ORGtparts=R"); +			codestream.access_siz()->parse_string(Parts_string.c_str());  		} +		 +		codestream.access_siz()->finalize_all();  		codestream.change_appearance(transpose,vflip,hflip);  		// Now we are ready for sample data processing. -        kdc_flow_control *tile = new kdc_flow_control(&mem_in,codestream); -        bool done = false; -        while (!done) -        {  -            // Process line by line -            done = true; -            if (tile->advance_components()) -            { -                done = false; -                tile->process_components(); -            } -        } +		kdc_flow_control *tile = new kdc_flow_control(&mem_in,codestream); +		bool done = false; +		while (!done) +		{  +			// Process line by line +			if (tile->advance_components()) +			{ +				tile->process_components(); +			} +			else +			{ +				done = true; +			} +		}  		// Produce the compressed output -        codestream.flush(layer_bytes,num_layer_specs); +		codestream.flush(layer_bytes,num_layer_specs);  		// Cleanup -        delete tile; - +		delete tile;  		codestream.destroy(); -		if (record_stream != NULL) -		{ -			delete record_stream; -		}  		// Now that we're done encoding, create the new data buffer for the compressed  		// image and stick it there. -  		base.copyData(output_buffer, output_size);  		base.updateData(); // set width, height  		delete[] output_buffer; @@ -674,19 +703,19 @@ BOOL LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co  BOOL LLImageJ2CKDU::getMetadata(LLImageJ2C &base)  {  	// *FIX: kdu calls our callback function if there's an error, and -	// then bombs.  To regain control, we throw an exception, and +	// then bombs. To regain control, we throw an exception, and  	// catch it here.  	try  	{  		setupCodeStream(base, FALSE, MODE_FAST);  		return TRUE;  	} -	catch( const char* msg ) +	catch (const char* msg)  	{  		base.setLastError(ll_safe_string(msg));  		return FALSE;  	} -	catch( ... ) +	catch (...)  	{  		base.setLastError( "Unknown J2C error" );  		return FALSE; @@ -699,37 +728,49 @@ void set_default_colour_weights(kdu_params *siz)  	assert(cod != NULL);  	bool can_use_ycc = true; -	bool rev0=false; -	int depth0=0, sub_x0=1, sub_y0=1; -	for (int c=0; c < 3; c++) +	bool rev0 = false; +	int depth0 = 0, sub_x0 = 1, sub_y0 = 1; +	for (int c = 0; c < 3; c++)  	{ -		int depth=0; siz->get(Sprecision,c,0,depth); -		int sub_y=1; siz->get(Ssampling,c,0,sub_y); -		int sub_x=1; siz->get(Ssampling,c,1,sub_x); +		int depth = 0; siz->get(Sprecision,c,0,depth); +		int sub_y = 1; siz->get(Ssampling,c,0,sub_y); +		int sub_x = 1; siz->get(Ssampling,c,1,sub_x);  		kdu_params *coc = cod->access_relation(-1,c); -		bool rev=false; coc->get(Creversible,0,0,rev); +		bool rev = false; coc->get(Creversible,0,0,rev);  		if (c == 0) -		{ rev0=rev; depth0=depth; sub_x0=sub_x; sub_y0=sub_y; } -		else if ((rev != rev0) || (depth != depth0) || -			(sub_x != sub_x0) || (sub_y != sub_y0)) +		{ +			rev0 = rev; depth0 = depth; sub_x0 = sub_x; sub_y0 = sub_y; +		} +		else if ((rev != rev0) || (depth != depth0) ||  +				 (sub_x != sub_x0) || (sub_y != sub_y0)) +		{  			can_use_ycc = false; +		}  	}  	if (!can_use_ycc) +	{  		return; +	}  	bool use_ycc;  	if (!cod->get(Cycc,0,0,use_ycc)) +	{  		cod->set(Cycc,0,0,use_ycc=true); +	}  	if (!use_ycc) +	{  		return; +	}  	float weight; -	if (cod->get(Clev_weights,0,0,weight) || -		cod->get(Cband_weights,0,0,weight)) -		return; // Weights already specified explicitly. +	if (cod->get(Clev_weights,0,0,weight) || cod->get(Cband_weights,0,0,weight)) +	{ +		// Weights already specified explicitly -> nothing to do +		return;  +	} -	/* These example weights are adapted from numbers generated by Marcus Nadenau -	at EPFL, for a viewing distance of 15 cm and a display resolution of -	300 DPI. */ +	// These example weights are adapted from numbers generated by Marcus Nadenau +	// at EPFL, for a viewing distance of 15 cm and a display resolution of +	// 300 DPI.  	cod->parse_string("Cband_weights:C0="  		"{0.0901},{0.2758},{0.2758}," @@ -775,7 +816,7 @@ all necessary level shifting, type conversion, rounding and truncation. */  				val += 128;  				if (val & ((-1)<<8))  				{ -					val = (val<0)?0:255; +					val = (val < 0 ? 0 : 255);  				}  				*dest = (kdu_byte) val;  			} @@ -793,7 +834,7 @@ all necessary level shifting, type conversion, rounding and truncation. */  				val += 128;  				if (val & ((-1)<<8))  				{ -					val = (val<0)?0:255; +					val = (val < 0 ? 0 : 255);  				}  				*dest = (kdu_byte) val;  			} @@ -816,7 +857,7 @@ all necessary level shifting, type conversion, rounding and truncation. */  					val += 128;  					if (val & ((-1)<<8))  					{ -						val = (val<0)?0:255; +						val = (val < 0 ? 0 : 255);  					}  					*dest = (kdu_byte) val;  				} @@ -835,7 +876,7 @@ all necessary level shifting, type conversion, rounding and truncation. */  					val += 128;  					if (val & ((-1)<<8))  					{ -						val = (val<0)?0:(256-(1<<upshift)); +						val = (val < 0 ? 0 : 256 - (1<<upshift));  					}  					*dest = (kdu_byte) val;  				} @@ -857,7 +898,7 @@ all necessary level shifting, type conversion, rounding and truncation. */  					val += 128;  					if (val & ((-1)<<8))  					{ -						val = (val<0)?0:255; +						val = (val < 0 ? 0 : 255);  					}  					*dest = (kdu_byte) val;  				} @@ -873,7 +914,7 @@ all necessary level shifting, type conversion, rounding and truncation. */  					val += 128;  					if (val & ((-1)<<8))  					{ -						val = (val<0)?0:(256-(1<<upshift)); +						val = (val < 0 ? 0 : 256 - (1<<upshift));  					}  					*dest = (kdu_byte) val;  				} @@ -892,17 +933,17 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap)  	mNumComponents = tile.get_num_components(); -	llassert(mNumComponents<=4); +	llassert(mNumComponents <= 4);  	mUseYCC = tile.get_ycc(); -	for (c=0; c<4; ++c) +	for (c = 0; c < 4; ++c)  	{  		mReversible[c] = false;  		mBitDepths[c] = 0;  	}  	// Open tile-components and create processing engines and resources -	for (c=0; c < mNumComponents; c++) +	for (c = 0; c < mNumComponents; c++)  	{  		mComps[c] = mTile.access_component(c);  		mReversible[c] = mComps[c].get_reversible(); @@ -929,7 +970,7 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap)  		}  	}  	mAllocator.finalize(); // Actually creates buffering resources -	for (c=0; c < mNumComponents; c++) +	for (c = 0; c < mNumComponents; c++)  	{  		mLines[c].create(); // Grabs resources from the allocator.  	} @@ -937,13 +978,11 @@ LLKDUDecodeState::LLKDUDecodeState(kdu_tile tile, kdu_byte *buf, S32 row_gap)  LLKDUDecodeState::~LLKDUDecodeState()  { -	S32 c;  	// Cleanup -	for (c=0; c < mNumComponents; c++) +	for (S32 c = 0; c < mNumComponents; c++)  	{  		mEngines[c].destroy(); // engines are interfaces; no default destructors  	} -  	mTile.close();  } @@ -962,7 +1001,7 @@ separation between consecutive rows in the real buffer. */  	LLTimer decode_timer;  	while (mDims.size.y--)  	{ -		for (c=0; c < mNumComponents; c++) +		for (c = 0; c < mNumComponents; c++)  		{  			mEngines[c].pull(mLines[c],true);  		} @@ -970,7 +1009,7 @@ separation between consecutive rows in the real buffer. */  		{  			kdu_convert_ycc_to_rgb(mLines[0],mLines[1],mLines[2]);  		} -		for (c=0; c < mNumComponents; c++) +		for (c = 0; c < mNumComponents; c++)  		{  			transfer_bytes(mBuf+c,mLines[c],mNumComponents,mBitDepths[c]);  		} @@ -990,96 +1029,100 @@ separation between consecutive rows in the real buffer. */  kdc_flow_control::kdc_flow_control (kdu_image_in_base *img_in, kdu_codestream codestream)  { -    int n; -     -    this->codestream = codestream; -    codestream.get_valid_tiles(valid_tile_indices); -    tile_idx = valid_tile_indices.pos; -    tile = codestream.open_tile(tile_idx,NULL); -     -    // Set up the individual components -    num_components = codestream.get_num_components(true); -    components = new kdc_component_flow_control[num_components]; -    count_delta = 0; -    kdc_component_flow_control *comp = components; -    for (n = 0; n < num_components; n++, comp++) -    { -        comp->line = NULL; -        comp->reader = img_in; -        kdu_coords subsampling;   -        codestream.get_subsampling(n,subsampling,true); -        kdu_dims dims;   -        codestream.get_tile_dims(tile_idx,n,dims,true); -        comp->vert_subsampling = subsampling.y; -        if ((n == 0) || (comp->vert_subsampling < count_delta)) -        { -            count_delta = comp->vert_subsampling; -        } -        comp->ratio_counter = 0; -        comp->remaining_lines = comp->initial_lines = dims.size.y; -    } -    assert(num_components >= 0); -     -    tile.set_components_of_interest(num_components); -    max_buffer_memory = engine.create(codestream,tile,false,NULL,false,1,NULL,NULL,false); +	int n; +	 +	this->codestream = codestream; +	codestream.get_valid_tiles(valid_tile_indices); +	tile_idx = valid_tile_indices.pos; +	tile = codestream.open_tile(tile_idx,NULL); +	 +	// Set up the individual components +	num_components = codestream.get_num_components(true); +	components = new kdc_component_flow_control[num_components]; +	count_delta = 0; +	kdc_component_flow_control *comp = components; +	for (n = 0; n < num_components; n++, comp++) +	{ +		comp->line = NULL; +		comp->reader = img_in; +		kdu_coords subsampling;   +		codestream.get_subsampling(n,subsampling,true); +		kdu_dims dims;   +		codestream.get_tile_dims(tile_idx,n,dims,true); +		comp->vert_subsampling = subsampling.y; +		if ((n == 0) || (comp->vert_subsampling < count_delta)) +		{ +			count_delta = comp->vert_subsampling; +		} +		comp->ratio_counter = 0; +		comp->remaining_lines = comp->initial_lines = dims.size.y; +	} +	assert(num_components >= 0); +	 +	tile.set_components_of_interest(num_components); +	max_buffer_memory = engine.create(codestream,tile,false,NULL,false,1,NULL,NULL,false);  }  kdc_flow_control::~kdc_flow_control()  { -    if (components != NULL) -        delete[] components; -    if (engine.exists()) -        engine.destroy(); +	if (components != NULL) +	{ +		delete[] components; +	} +	if (engine.exists()) +	{ +		engine.destroy(); +	}  }  bool kdc_flow_control::advance_components()  { -    bool found_line = false; -    while (!found_line) -    { -        bool all_done = true; -        kdc_component_flow_control *comp = components; -        for (int n = 0; n < num_components; n++, comp++) -        { -            assert(comp->ratio_counter >= 0); -            if (comp->remaining_lines > 0) -            { -                all_done = false; -                comp->ratio_counter -= count_delta; -                if (comp->ratio_counter < 0) -                { -                    found_line = true; -                    comp->line = engine.exchange_line(n,NULL,NULL); -                    assert(comp->line != NULL); +	bool found_line = false; +	while (!found_line) +	{ +		bool all_done = true; +		kdc_component_flow_control *comp = components; +		for (int n = 0; n < num_components; n++, comp++) +		{ +			assert(comp->ratio_counter >= 0); +			if (comp->remaining_lines > 0) +			{ +				all_done = false; +				comp->ratio_counter -= count_delta; +				if (comp->ratio_counter < 0) +				{ +					found_line = true; +					comp->line = engine.exchange_line(n,NULL,NULL); +					assert(comp->line != NULL);  					if (comp->line->get_width())  					{  						comp->reader->get(n,*(comp->line),0);  					} -                } -            } -        } -        if (all_done) -        { -            return false; -        } -    } -    return true; +				} +			} +		} +		if (all_done) +		{ +			return false; +		} +	} +	return true;  }  void kdc_flow_control::process_components()  { -    kdc_component_flow_control *comp = components; -    for (int n = 0; n < num_components; n++, comp++) -    { -        if (comp->ratio_counter < 0) -        { -            comp->ratio_counter += comp->vert_subsampling; -            assert(comp->ratio_counter >= 0); -            assert(comp->remaining_lines > 0); -            comp->remaining_lines--; -            assert(comp->line != NULL); -            engine.exchange_line(n,comp->line,NULL); -            comp->line = NULL; -        } -    } +	kdc_component_flow_control *comp = components; +	for (int n = 0; n < num_components; n++, comp++) +	{ +		if (comp->ratio_counter < 0) +		{ +			comp->ratio_counter += comp->vert_subsampling; +			assert(comp->ratio_counter >= 0); +			assert(comp->remaining_lines > 0); +			comp->remaining_lines--; +			assert(comp->line != NULL); +			engine.exchange_line(n,comp->line,NULL); +			comp->line = NULL; +		} +	}  } diff --git a/indra/llkdu/llimagej2ckdu.h b/indra/llkdu/llimagej2ckdu.h index 5628f69eeb..9fce58b762 100644 --- a/indra/llkdu/llimagej2ckdu.h +++ b/indra/llkdu/llimagej2ckdu.h @@ -58,17 +58,21 @@ protected:  	/*virtual*/ BOOL decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, S32 first_channel, S32 max_channel_count);  	/*virtual*/ BOOL encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time=0.0,  								BOOL reversible=FALSE); +	/*virtual*/ BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, int discard_level = -1, int* region = NULL); +	/*virtual*/ BOOL initEncode(LLImageJ2C &base, LLImageRaw &raw_image, int blocks_size = -1, int precincts_size = -1);  private: +	BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count, int discard_level = -1, int* region = NULL);  	void setupCodeStream(LLImageJ2C &base, BOOL keep_codestream, ECodeStreamMode mode);  	void cleanupCodeStream(); -	BOOL initDecode(LLImageJ2C &base, LLImageRaw &raw_image, F32 decode_time, ECodeStreamMode mode, S32 first_channel, S32 max_channel_count );  	// Encode variable  	LLKDUMemSource *mInputp;  	kdu_codestream *mCodeStreamp;  	kdu_coords *mTPosp; // tile position  	kdu_dims *mTileIndicesp; +	int mBlocksSize; +	int mPrecinctsSize;  	// Temporary variables for in-progress decodes...  	LLImageRaw *mRawImagep; diff --git a/indra/llkdu/llkdumem.cpp b/indra/llkdu/llkdumem.cpp index 1f549cbbe0..0347475559 100644 --- a/indra/llkdu/llkdumem.cpp +++ b/indra/llkdu/llkdumem.cpp @@ -47,12 +47,12 @@ LLKDUMemIn::LLKDUMemIn(const U8 *data,  	num_components = in_num_components;  	alignment_bytes = 0; -	for (n=0; n<3; ++n) +	for (n = 0; n < 3; ++n)  	{  		precision[n] = 0;  	} -	for (n=0; n < num_components; ++n) +	for (n = 0; n < num_components; ++n)  	{  		siz->set(Sdims,n,0,rows);  		siz->set(Sdims,n,1,cols); @@ -80,12 +80,12 @@ LLKDUMemIn::~LLKDUMemIn()  	}  	image_line_buf *tmp;  	while ((tmp=incomplete_lines) != NULL) -    { +	{  		incomplete_lines = tmp->next;  		delete tmp;   	}  	while ((tmp=free_lines) != NULL) -    { +	{  		free_lines = tmp->next;  		delete tmp;  	} @@ -98,16 +98,16 @@ bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum)  	assert((idx >= 0) && (idx < num_components));  	x_tnum = x_tnum*num_components+idx;  	image_line_buf *scan, *prev=NULL; -	for (scan=incomplete_lines; scan != NULL; prev=scan, scan=scan->next) -    { +	for (scan = incomplete_lines; scan != NULL; prev = scan, scan = scan->next) +	{  		assert(scan->next_x_tnum >= x_tnum);  		if (scan->next_x_tnum == x_tnum)  		{  			break;  		} -    } +	}  	if (scan == NULL) -    { // Need to read a new image line. +	{ // Need to read a new image line.  		assert(x_tnum == 0); // Must consume in very specific order.  		if (num_unread_rows == 0)  		{ @@ -134,7 +134,7 @@ bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum)  		num_unread_rows--;  		scan->accessed_samples = 0;  		scan->next_x_tnum = 0; -    } +	}  	assert((cols-scan->accessed_samples) >= line.get_width()); @@ -161,7 +161,7 @@ bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum)  		}  	}  	else -    { +	{  		kdu_sample16 *dp = line.get_buf16();  		if (line.is_absolute())  		{ // 16-bit absolute integers @@ -177,7 +177,7 @@ bool LLKDUMemIn::get(int comp_idx, kdu_line_buf &line, int x_tnum)  				dp->ival = (((kdu_int16)(*sp)) - 128) << (KDU_FIX_POINT-8);  			}  		} -    } +	}  	scan->next_x_tnum++;  	if (idx == (num_components-1)) diff --git a/indra/llkdu/llkdumem.h b/indra/llkdu/llkdumem.h index 7064de4408..9d923fc367 100644 --- a/indra/llkdu/llkdumem.h +++ b/indra/llkdu/llkdumem.h @@ -39,7 +39,7 @@  class LLKDUMemSource: public kdu_compressed_source  { -public: // Member functions +public:  	LLKDUMemSource(U8 *input_buffer, U32 size)  	{  		mData = input_buffer; @@ -47,11 +47,11 @@ public: // Member functions  		mCurPos = 0;  	} -    ~LLKDUMemSource() +	~LLKDUMemSource()  	{  	} -    int read(kdu_byte *buf, int num_bytes) +	int read(kdu_byte *buf, int num_bytes)  	{  		U32 num_out;  		num_out = num_bytes; @@ -70,7 +70,7 @@ public: // Member functions  		mCurPos = 0;  	} -private: // Data +private:  	U8 *mData;  	U32 mSize;  	U32 mCurPos; @@ -78,7 +78,7 @@ private: // Data  class LLKDUMemTarget: public kdu_compressed_target  { -public: // Member functions +public:  	LLKDUMemTarget(U8 *output_buffer, U32 &output_size, const U32 buffer_size)  	{  		mData = output_buffer; @@ -87,11 +87,11 @@ public: // Member functions  		mOutputSize = &output_size;  	} -    ~LLKDUMemTarget() -    { +	~LLKDUMemTarget() +	{  	} -    bool write(const kdu_byte *buf, int num_bytes) +	bool write(const kdu_byte *buf, int num_bytes)  	{  		U32 num_out;  		num_out = num_bytes; @@ -108,7 +108,7 @@ public: // Member functions  		return true;  	} -private: // Data +private:  	U8 *mData;  	U32 mSize;  	U32 mCurPos; @@ -117,27 +117,27 @@ private: // Data  class LLKDUMemIn : public kdu_image_in_base  { -public: // Member functions -    LLKDUMemIn(const U8 *data, +public: +	LLKDUMemIn(const U8 *data,  				const U32 size,  				const U16 rows,  				const U16 cols,  				U8 in_num_components,  				siz_params *siz); -    ~LLKDUMemIn(); +	~LLKDUMemIn(); -    bool get(int comp_idx, kdu_line_buf &line, int x_tnum); +	bool get(int comp_idx, kdu_line_buf &line, int x_tnum); -private: // Data +private:  	const U8 *mData; -    int first_comp_idx; -    int num_components; -    int rows, cols; -    int alignment_bytes; // Number of 0's at end of each line. -    int precision[3]; -    image_line_buf *incomplete_lines; // Each "sample" represents a full pixel -    image_line_buf *free_lines; -    int num_unread_rows; +	int first_comp_idx; +	int num_components; +	int rows, cols; +	int alignment_bytes; // Number of 0's at end of each line. +	int precision[3]; +	image_line_buf *incomplete_lines; // Each "sample" represents a full pixel +	image_line_buf *free_lines; +	int num_unread_rows;  	U32 mCurPos;  	U32 mDataSize; diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 767001b633..33e6709983 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -553,12 +553,10 @@ void LLAvatarNameCache::eraseUnrefreshed()      if (!sLastExpireCheck || sLastExpireCheck < max_unrefreshed)      {          sLastExpireCheck = now; -        cache_t::iterator it = sCache.begin(); -        while (it != sCache.end()) + +        for (cache_t::iterator it = sCache.begin(); it != sCache.end(); ++it)          { -            cache_t::iterator cur = it; -            ++it; -            const LLAvatarName& av_name = cur->second; +            const LLAvatarName& av_name = it->second;              if (av_name.mExpires < max_unrefreshed)              {                  const LLUUID& agent_id = it->first; @@ -566,7 +564,7 @@ void LLAvatarNameCache::eraseUnrefreshed()                                           << " user '" << av_name.mUsername << "' "                                           << "expired " << now - av_name.mExpires << " secs ago"                                           << LL_ENDL; -                sCache.erase(cur); +                sCache.erase(it);              }          }          LL_INFOS("AvNameCache") << sCache.size() << " cached avatar names" << LL_ENDL; diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp index 7b29d92ea0..c4eec1835c 100644 --- a/indra/llui/llloadingindicator.cpp +++ b/indra/llui/llloadingindicator.cpp @@ -39,56 +39,24 @@  //static LLDefaultChildRegistry::Register<LLLoadingIndicator> r("loading_indicator");  /////////////////////////////////////////////////////////////////////////////// -// LLLoadingIndicator::Data class +// LLLoadingIndicator class  /////////////////////////////////////////////////////////////////////////////// -/** - * Pre-loaded images shared by all instances of the widget - */ -class LLLoadingIndicator::Data: public LLSingleton<LLLoadingIndicator::Data> +LLLoadingIndicator::LLLoadingIndicator(const Params& p) +:	LLUICtrl(p),  +	mImagesPerSec(p.images_per_sec > 0 ? p.images_per_sec : 1.0f),  +	mCurImageIdx(0)  { -public: -	/*virtual*/ void		initSingleton(); // from LLSingleton - -	LLPointer<LLUIImage>	getNextImage(S8& idx) const; -	U8						getImagesCount() const	{ return NIMAGES; } -private: - -	static const U8			NIMAGES = 12; -	LLPointer<LLUIImage>	mImages[NIMAGES]; -}; +} -// virtual -// Called right after the instance gets constructed. -void LLLoadingIndicator::Data::initSingleton() +void LLLoadingIndicator::initFromParams(const Params& p)  { -	// Load images. -	for (U8 i = 0; i < NIMAGES; ++i) +	for (LLInitParam::ParamIterator<LLUIImage*>::const_iterator it = p.images().image.begin(), end_it = p.images().image.end(); +		it != end_it; +		++it)  	{ -		std::string img_name = llformat("Progress_%d", i+1); -		mImages[i] = LLUI::getUIImage(img_name, 0); -		llassert(mImages[i]); +		mImages.push_back(it->getValue());  	} -} - -LLPointer<LLUIImage> LLLoadingIndicator::Data::getNextImage(S8& idx) const -{ -	// Calculate next index, performing array bounds checking. -	idx = (idx >= NIMAGES || idx < 0) ? 0 : (idx + 1) % NIMAGES;  -	return mImages[idx]; -} - -/////////////////////////////////////////////////////////////////////////////// -// LLLoadingIndicator class -/////////////////////////////////////////////////////////////////////////////// - -LLLoadingIndicator::LLLoadingIndicator(const Params& p) -:	LLUICtrl(p) -	, mRotationsPerSec(p.rotations_per_sec > 0 ? p.rotations_per_sec : 1.0f) -	, mCurImageIdx(-1) -{ -	// Select initial image. -	mCurImagep = Data::instance().getNextImage(mCurImageIdx);  	// Start timer for switching images.  	start(); @@ -100,16 +68,21 @@ void LLLoadingIndicator::draw()  	if (mImageSwitchTimer.getStarted() && mImageSwitchTimer.hasExpired())  	{  		// Switch to the next image. -		mCurImagep = Data::instance().getNextImage(mCurImageIdx); +		if (!mImages.empty()) +		{ +			mCurImageIdx = (mCurImageIdx + 1) % mImages.size(); +		}  		// Restart timer.  		start();  	} +	LLUIImagePtr cur_image = mImages.empty() ? LLUIImagePtr(NULL) : mImages[mCurImageIdx]; +  	// Draw current image. -	if( mCurImagep.notNull() ) +	if( cur_image.notNull() )  	{ -		mCurImagep->draw(getLocalRect(), LLColor4::white % getDrawContext().mAlpha); +		cur_image->draw(getLocalRect(), LLColor4::white % getDrawContext().mAlpha);  	}  	LLUICtrl::draw(); @@ -123,6 +96,6 @@ void LLLoadingIndicator::stop()  void LLLoadingIndicator::start()  {  	mImageSwitchTimer.start(); -	F32 period = 1.0f / (Data::instance().getImagesCount() * mRotationsPerSec); +	F32 period = 1.0f / (mImages.size() * mImagesPerSec);  	mImageSwitchTimer.setTimerExpirySec(period);  } diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h index 4e4a224ef6..c0cb1cc74a 100644 --- a/indra/llui/llloadingindicator.h +++ b/indra/llui/llloadingindicator.h @@ -36,8 +36,8 @@  /**   * Perpetual loading indicator (a la MacOSX or YouTube)   *  - * Number of rotations per second can be overriden - * with the "roations_per_sec" parameter. + * Number of rotations per second can be overridden + * with the "images_per_sec" parameter.   *    * Can start/stop spinning.   *  @@ -49,11 +49,24 @@ class LLLoadingIndicator  {  	LOG_CLASS(LLLoadingIndicator);  public: + +	struct Images : public LLInitParam::Block<Images> +	{ +		Multiple<LLUIImage*>	image; + +		Images() +		:	image("image") +		{} +	}; +  	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>  	{ -		Optional<F32>	rotations_per_sec; +		Optional<F32>			images_per_sec; +		Batch<Images>			images; +  		Params() -		:	rotations_per_sec("rotations_per_sec", 1.0f) +		:	images_per_sec("images_per_sec", 1.0f), +			images("images")  		{}  	}; @@ -74,14 +87,15 @@ public:  private:  	LLLoadingIndicator(const Params&); -	friend class LLUICtrlFactory; +	void initFromParams(const Params&); -	class Data; +	friend class LLUICtrlFactory; -	F32						mRotationsPerSec; +	F32						mImagesPerSec;  	S8						mCurImageIdx; -	LLPointer<LLUIImage>	mCurImagep;  	LLFrameTimer			mImageSwitchTimer; + +	std::vector<LLUIImagePtr> mImages;  };  #endif // LL_LLLOADINGINDICATOR_H diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 82269282ef..fd7bb699f8 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -2022,11 +2022,10 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,  			pos = segment_line_start + offset;  			break;  		} -		else if (hit_past_end_of_line && segmentp->getEnd() > line_iter->mDocIndexEnd - 1)	 +		else if (hit_past_end_of_line && segmentp->getEnd() >= line_iter->mDocIndexEnd)  		{  			// segment wraps to next line, so just set doc pos to the end of the line -			// segment wraps to next line, so just set doc pos to start of next line (represented by mDocIndexEnd) -			pos = llmin(getLength(), line_iter->mDocIndexEnd); +			pos = llclamp(line_iter->mDocIndexEnd - 1, 0, getLength());  			break;  		}  		start_x += text_width; diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp index 87669574c2..8020ca802b 100644 --- a/indra/llui/llui.cpp +++ b/indra/llui/llui.cpp @@ -1626,8 +1626,8 @@ void LLUI::cleanupClass()  {  	if(sImageProvider)  	{ -		sImageProvider->cleanUp(); -	} +	sImageProvider->cleanUp(); +}  }  void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup,  const clear_popups_t& clear_popups) @@ -2074,32 +2074,32 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)  namespace LLInitParam  { -	TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, name, value, func, min_count, max_count), +	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color) +	:	super_t(color),  		red("red"),  		green("green"),  		blue("blue"),  		alpha("alpha"),  		control("")  	{ -		setBlockFromValue(); +		updateBlockFromValue();  	} -	void TypedParam<LLUIColor>::setValueFromBlock() const +	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()  	{  		if (control.isProvided())  		{ -			mData.mValue = LLUIColorTable::instance().getColor(control); +			updateValue(LLUIColorTable::instance().getColor(control));  		}  		else  		{ -			mData.mValue = LLColor4(red, green, blue, alpha); +			updateValue(LLColor4(red, green, blue, alpha));  		}  	} -	void TypedParam<LLUIColor>::setBlockFromValue() +	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()  	{ -		LLColor4 color = mData.mValue.get(); +		LLColor4 color = getValue();  		red.set(color.mV[VRED], false);  		green.set(color.mV[VGREEN], false);  		blue.set(color.mV[VBLUE], false); @@ -2107,38 +2107,32 @@ namespace LLInitParam  		control.set("", false);  	} -	void TypeValues<LLUIColor>::declareValues() -	{ -		declare("white", LLColor4::white); -		declare("black", LLColor4::black); -		declare("red", LLColor4::red); -		declare("green", LLColor4::green); -		declare("blue", LLColor4::blue); -	} -  	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)  	{  		return !(a->getFontDesc() < b->getFontDesc())  			&& !(b->getFontDesc() < a->getFontDesc());  	} -	TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, _name, value, func, min_count, max_count), +	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp) +	:	super_t(fontp),  		name("name"),  		size("size"),  		style("style")  	{ -		setBlockFromValue(); +		if (!fontp) +		{ +			updateValue(LLFontGL::getFontDefault()); +		}  		addSynonym(name, ""); -		setBlockFromValue(); +		updateBlockFromValue();  	} -	void TypedParam<const LLFontGL*>::setValueFromBlock() const +	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()  	{  		const LLFontGL* res_fontp = LLFontGL::getFontByName(name);  		if (res_fontp)  		{ -			mData.mValue = res_fontp; +			updateValue(res_fontp);  			return;  		} @@ -2148,22 +2142,26 @@ namespace LLInitParam  		const LLFontGL* fontp = LLFontGL::getFont(desc);  		if (fontp)  		{ -			mData.mValue = fontp; -		}		 +			updateValue(fontp); +		} +		else +		{ +			updateValue(LLFontGL::getFontDefault()); +		}  	} -	void TypedParam<const LLFontGL*>::setBlockFromValue() +	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()  	{ -		if (mData.mValue) +		if (getValue())  		{ -			name.set(LLFontGL::nameFromFont(mData.mValue), false); -			size.set(LLFontGL::sizeFromFont(mData.mValue), false); -			style.set(LLFontGL::getStringFromStyle(mData.mValue->getFontDesc().getStyle()), false); +			name.set(LLFontGL::nameFromFont(getValue()), false); +			size.set(LLFontGL::sizeFromFont(getValue()), false); +			style.set(LLFontGL::getStringFromStyle(getValue()->getFontDesc().getStyle()), false);  		}  	} -	TypedParam<LLRect>::TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, name, value, func, min_count, max_count), +	ParamValue<LLRect, TypeValues<LLRect> >::ParamValue(const LLRect& rect) +	:	super_t(rect),  		left("left"),  		top("top"),  		right("right"), @@ -2171,10 +2169,10 @@ namespace LLInitParam  		width("width"),  		height("height")  	{ -		setBlockFromValue(); +		updateBlockFromValue();  	} -	void TypedParam<LLRect>::setValueFromBlock() const +	void ParamValue<LLRect, TypeValues<LLRect> >::updateValueFromBlock()  	{  		LLRect rect; @@ -2235,40 +2233,41 @@ namespace LLInitParam  			rect.mBottom = bottom;  			rect.mTop = top;  		} -		mData.mValue = rect; +		updateValue(rect);  	} -	void TypedParam<LLRect>::setBlockFromValue() +	void ParamValue<LLRect, TypeValues<LLRect> >::updateBlockFromValue()  	{  		// because of the ambiguity in specifying a rect by position and/or dimensions  		// we clear the "provided" flag so that values from xui/etc have priority  		// over those calculated from the rect object -		left.set(mData.mValue.mLeft, false); -		right.set(mData.mValue.mRight, false); -		bottom.set(mData.mValue.mBottom, false); -		top.set(mData.mValue.mTop, false); -		width.set(mData.mValue.getWidth(), false); -		height.set(mData.mValue.getHeight(), false); +		LLRect& value = getValue(); +		left.set(value.mLeft, false); +		right.set(value.mRight, false); +		bottom.set(value.mBottom, false); +		top.set(value.mTop, false); +		width.set(value.getWidth(), false); +		height.set(value.getHeight(), false);  	} -	TypedParam<LLCoordGL>::TypedParam(BlockDescriptor& descriptor, const char* name, LLCoordGL value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, name, value, func, min_count, max_count), +	ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::ParamValue(const LLCoordGL& coord) +	:	super_t(coord),  		x("x"),  		y("y")  	{ -		setBlockFromValue(); +		updateBlockFromValue();  	} -	void TypedParam<LLCoordGL>::setValueFromBlock() const +	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateValueFromBlock()  	{ -		mData.mValue.set(x, y); +		updateValue(LLCoordGL(x, y));  	} -	void TypedParam<LLCoordGL>::setBlockFromValue() +	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateBlockFromValue()  	{ -		x.set(mData.mValue.mX, false); -		y.set(mData.mValue.mY, false); +		x.set(getValue().mX, false); +		y.set(getValue().mY, false);  	} diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 50cb9e6632..6a43477693 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -398,10 +398,10 @@ public:  namespace LLInitParam  {  	template<> -	class TypedParam<LLRect>  -	:	public BlockValue<LLRect> +	class ParamValue<LLRect, TypeValues<LLRect> >  +	:	public CustomParamValue<LLRect>  	{ -        typedef BlockValue<LLRect> super_t; +        typedef CustomParamValue<LLRect> super_t;  	public:  		Optional<S32>	left,  						top, @@ -410,62 +410,43 @@ namespace LLInitParam  						width,  						height; -		TypedParam(BlockDescriptor& descriptor, const char* name, const LLRect& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); +		ParamValue(const LLRect& value); -		void setValueFromBlock() const; -		void setBlockFromValue(); +		void updateValueFromBlock(); +		void updateBlockFromValue();  	};  	template<> -	struct TypeValues<LLUIColor> : public TypeValuesHelper<LLUIColor> +	class ParamValue<LLUIColor, TypeValues<LLUIColor> >  +	:	public CustomParamValue<LLUIColor>  	{ -		static void declareValues(); -	}; +        typedef CustomParamValue<LLUIColor> super_t; -	template<> -	class TypedParam<LLUIColor>  -	:	public BlockValue<LLUIColor> -	{ -        typedef BlockValue<LLUIColor> super_t;  	public: -		Optional<F32>	red, -						green, -						blue, -						alpha; -		Optional<std::string> control; - -		TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); -		void setValueFromBlock() const; -		void setBlockFromValue(); +		Optional<F32>			red, +								green, +								blue, +								alpha; +		Optional<std::string>	control; + +		ParamValue(const LLUIColor& color); +		void updateValueFromBlock(); +		void updateBlockFromValue();  	}; -	// provide a better default for Optional<const LLFontGL*> than NULL -	template <> -	struct DefaultInitializer<const LLFontGL*> -	{ -		// return reference to a single default instance of T -		// built-in types will be initialized to zero, default constructor otherwise -		static const LLFontGL* get()  -		{  -			static const LLFontGL* sDefaultFont = LLFontGL::getFontDefault();   -			return sDefaultFont; -		}  -	}; - -  	template<> -	class TypedParam<const LLFontGL*>  -	:	public BlockValue<const LLFontGL*> +	class ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >  +	:	public CustomParamValue<const LLFontGL* >  	{ -        typedef BlockValue<const LLFontGL*> super_t; +        typedef CustomParamValue<const LLFontGL*> super_t;  	public:  		Optional<std::string>	name,  								size,  								style; -		TypedParam(BlockDescriptor& descriptor, const char* name, const LLFontGL* const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); -		void setValueFromBlock() const; -		void setBlockFromValue(); +		ParamValue(const LLFontGL* value); +		void updateValueFromBlock(); +		void updateBlockFromValue();  	};  	template<> @@ -494,17 +475,17 @@ namespace LLInitParam  	template<> -	class TypedParam<LLCoordGL> -	:	public BlockValue<LLCoordGL> +	class ParamValue<LLCoordGL, TypeValues<LLCoordGL> > +	:	public CustomParamValue<LLCoordGL>  	{ -		typedef BlockValue<LLCoordGL> super_t; +		typedef CustomParamValue<LLCoordGL> super_t;  	public:  		Optional<S32>	x,  						y; -		TypedParam(BlockDescriptor& descriptor, const char* name, LLCoordGL value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count); -		void setValueFromBlock() const; -		void setBlockFromValue(); +		ParamValue(const LLCoordGL& val); +		void updateValueFromBlock(); +		void updateBlockFromValue();  	};  } diff --git a/indra/llui/lluiimage.cpp b/indra/llui/lluiimage.cpp index 1ffad4806e..f37947a50b 100644 --- a/indra/llui/lluiimage.cpp +++ b/indra/llui/lluiimage.cpp @@ -155,32 +155,32 @@ void LLUIImage::onImageLoaded()  namespace LLInitParam  { -	void TypedParam<LLUIImage*>::setValueFromBlock() const +	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()  	{  		// The keyword "none" is specifically requesting a null image  		// do not default to current value. Used to overwrite template images.   		if (name() == "none")  		{ -			mData.mValue = NULL; +			updateValue(NULL);  			return;  		}  		LLUIImage* imagep =  LLUI::getUIImage(name());  		if (imagep)  		{ -			mData.mValue = imagep; +			updateValue(imagep);  		}  	} -	void TypedParam<LLUIImage*>::setBlockFromValue() +	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()  	{ -		if (mData.mValue == NULL) +		if (getValue() == NULL)  		{  			name.set("none", false);  		}  		else  		{ -			name.set(mData.mValue->getName(), false); +			name.set(getValue()->getName(), false);  		}  	} diff --git a/indra/llui/lluiimage.h b/indra/llui/lluiimage.h index 38107c112d..139d88e0ac 100644 --- a/indra/llui/lluiimage.h +++ b/indra/llui/lluiimage.h @@ -92,22 +92,23 @@ protected:  namespace LLInitParam  {  	template<> -	class TypedParam<LLUIImage*, TypeValues<LLUIImage*>, false>  -	:	public BlockValue<LLUIImage*> +	class ParamValue<LLUIImage*, TypeValues<LLUIImage*> >  +	:	public CustomParamValue<LLUIImage*>  	{  		typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type	T_const_ref; -		typedef BlockValue<LLUIImage*> super_t; +		typedef CustomParamValue<LLUIImage*> super_t;  	public:  		Optional<std::string> name; -		TypedParam(BlockDescriptor& descriptor, const char* name, super_t::value_assignment_t value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -		:	super_t(descriptor, name, value, func, min_count, max_count) +		ParamValue(LLUIImage* const& image) +		:	super_t(image)  		{ -			setBlockFromValue(); +			updateBlockFromValue(); +			addSynonym(name, "name");  		} -		void setValueFromBlock() const; -		void setBlockFromValue(); +		void updateValueFromBlock(); +		void updateBlockFromValue();  	};  	// Need custom comparison function for our test app, which only loads diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp index ac2412c928..75946b2416 100644 --- a/indra/llui/tests/llurlentry_stub.cpp +++ b/indra/llui/tests/llurlentry_stub.cpp @@ -114,32 +114,30 @@ namespace LLInitParam  		const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);  		mEnclosingBlockOffset = (U16)(my_addr - block_addr);  	} -	void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {} +	void BaseBlock::paramChanged(const Param& last_param, bool user_provided) {} -	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){} +	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){} +	void BaseBlock::addSynonym(Param& param, const std::string& synonym) {}  	param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;}  	void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)  	{  		descriptor.mCurrentBlockPtr = this;  	} -	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; } -	bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; } -	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; } +	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; } +	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const {} +	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_value, S32 max_value) const { return true; }  	bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }  	bool BaseBlock::validateBlock(bool emit_errors) const { return true; } -	TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, name, value, func, min_count, max_count) +	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color) +	:	super_t(color)  	{} -	void TypedParam<LLUIColor>::setValueFromBlock() const +	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()   	{} -	void TypedParam<LLUIColor>::setBlockFromValue() -	{} - -	void TypeValues<LLUIColor>::declareValues() +	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()  	{}  	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b) @@ -147,14 +145,14 @@ namespace LLInitParam  		return false;  	} -	TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, _name, value, func, min_count, max_count) +	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp) +	:	super_t(fontp)  	{} -	void TypedParam<const LLFontGL*>::setValueFromBlock() const +	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()  	{} -	void TypedParam<const LLFontGL*>::setBlockFromValue() +	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()  	{}  	void TypeValues<LLFontGL::HAlign>::declareValues() @@ -166,10 +164,10 @@ namespace LLInitParam  	void TypeValues<LLFontGL::ShadowType>::declareValues()  	{} -	void TypedParam<LLUIImage*>::setValueFromBlock() const +	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()  	{} -	void TypedParam<LLUIImage*>::setBlockFromValue() +	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()  	{} diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp index 8f0a48018f..2f814f4200 100644 --- a/indra/llui/tests/llurlentry_test.cpp +++ b/indra/llui/tests/llurlentry_test.cpp @@ -70,6 +70,22 @@ S32 LLUIImage::getHeight() const  	return 0;  } +namespace LLInitParam +{ +	S32 Parser::sNextParseGeneration = 0; +	BlockDescriptor::BlockDescriptor() {} +	ParamDescriptor::ParamDescriptor(param_handle_t p,  +						merge_func_t merge_func,  +						deserialize_func_t deserialize_func,  +						serialize_func_t serialize_func, +						validation_func_t validation_func, +						inspect_func_t inspect_func, +						S32 min_count, +						S32 max_count){} +	ParamDescriptor::~ParamDescriptor() {} + +} +  namespace tut  {  	struct LLUrlEntryData diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp index fdaab00f18..aea605c9f2 100644 --- a/indra/llui/tests/llurlmatch_test.cpp +++ b/indra/llui/tests/llurlmatch_test.cpp @@ -66,11 +66,25 @@ namespace LLInitParam  	BaseBlock::BaseBlock() {}  	BaseBlock::~BaseBlock() {} -	void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) {} - -	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name){} +	S32 Parser::sNextParseGeneration = 0; + +	BlockDescriptor::BlockDescriptor() {} +	ParamDescriptor::ParamDescriptor(param_handle_t p,  +						merge_func_t merge_func,  +						deserialize_func_t deserialize_func,  +						serialize_func_t serialize_func, +						validation_func_t validation_func, +						inspect_func_t inspect_func, +						S32 min_count, +						S32 max_count){} +	ParamDescriptor::~ParamDescriptor() {} + +	void BaseBlock::paramChanged(const Param& last_param, bool user_provided) {} + +	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name){}  	param_handle_t BaseBlock::getHandleFromParam(const Param* param) const {return 0;} -	 +	void BaseBlock::addSynonym(Param& param, const std::string& synonym) {} +  	void BaseBlock::init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size)  	{  		descriptor.mCurrentBlockPtr = this; @@ -84,23 +98,20 @@ namespace LLInitParam  		mEnclosingBlockOffset = (U16)(my_addr - block_addr);  	} -	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack){ return true; } -	bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const { return true; } -	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const { return true; } +	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; } +	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const {} +	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const { return true; }  	bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }  	bool BaseBlock::validateBlock(bool emit_errors) const { return true; } -	TypedParam<LLUIColor >::TypedParam(BlockDescriptor& descriptor, const char* name, const LLUIColor& value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, name, value, func, min_count, max_count) +	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color) +	:	super_t(color)  	{} -	void TypedParam<LLUIColor>::setValueFromBlock() const +	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()  	{} -	void TypedParam<LLUIColor>::setBlockFromValue() -	{} - -	void TypeValues<LLUIColor>::declareValues() +	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue()  	{}  	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b) @@ -108,14 +119,15 @@ namespace LLInitParam  		return false;  	} -	TypedParam<const LLFontGL*>::TypedParam(BlockDescriptor& descriptor, const char* _name, const LLFontGL*const value, ParamDescriptor::validation_func_t func, S32 min_count, S32 max_count) -	:	super_t(descriptor, _name, value, func, min_count, max_count) + +	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp) +	:	super_t(fontp)  	{} -	void TypedParam<const LLFontGL*>::setValueFromBlock() const +	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()  	{} -	void TypedParam<const LLFontGL*>::setBlockFromValue() +	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue()  	{}  	void TypeValues<LLFontGL::HAlign>::declareValues() @@ -127,10 +139,10 @@ namespace LLInitParam  	void TypeValues<LLFontGL::ShadowType>::declareValues()  	{} -	void TypedParam<LLUIImage*>::setValueFromBlock() const +	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()  	{} -	void TypedParam<LLUIImage*>::setBlockFromValue() +	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue()  	{}  	bool ParamCompare<LLUIImage*, false>::equals( diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp index fcdbaa4309..3c4eb70a5d 100644 --- a/indra/llxuixml/llinitparam.cpp +++ b/indra/llxuixml/llinitparam.cpp @@ -44,8 +44,51 @@ namespace LLInitParam  	}  	// +	// ParamDescriptor +	// +	ParamDescriptor::ParamDescriptor(param_handle_t p,  +									merge_func_t merge_func,  +									deserialize_func_t deserialize_func,  +									serialize_func_t serialize_func, +									validation_func_t validation_func, +									inspect_func_t inspect_func, +									S32 min_count, +									S32 max_count) +	:	mParamHandle(p), +		mMergeFunc(merge_func), +		mDeserializeFunc(deserialize_func), +		mSerializeFunc(serialize_func), +		mValidationFunc(validation_func), +		mInspectFunc(inspect_func), +		mMinCount(min_count), +		mMaxCount(max_count), +		mGeneration(0), +		mUserData(NULL) +	{} + +	ParamDescriptor::ParamDescriptor() +	:	mParamHandle(0), +		mMergeFunc(NULL), +		mDeserializeFunc(NULL), +		mSerializeFunc(NULL), +		mValidationFunc(NULL), +		mInspectFunc(NULL), +		mMinCount(0), +		mMaxCount(0), +		mGeneration(0), +		mUserData(NULL) +	{} + +	ParamDescriptor::~ParamDescriptor() +	{ +		delete mUserData; +	} + +	//  	// Parser  	// +	S32 Parser::sNextParseGeneration = 0; +  	Parser::~Parser()  	{} @@ -73,6 +116,12 @@ namespace LLInitParam  		std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));  	} +	BlockDescriptor::BlockDescriptor() +	:	mMaxParamOffset(0), +		mInitializationState(UNINITIALIZED), +		mCurrentBlockPtr(NULL) +	{} +  	//  	// BaseBlock  	// @@ -115,7 +164,7 @@ namespace LLInitParam  	bool BaseBlock::submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent)  	{ -		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()))) +		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), -1))  		{  			if (!silent)  			{ @@ -145,7 +194,7 @@ namespace LLInitParam  		return true;  	} -	bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const +	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const  	{  		// named param is one like LLView::Params::follows  		// unnamed param is like LLView::Params::rect - implicit @@ -212,11 +261,9 @@ namespace LLInitParam  				name_stack.pop_back();  			}  		} - -		return true;  	} -	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack) const +	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const  	{  		// named param is one like LLView::Params::follows  		// unnamed param is like LLView::Params::rect - implicit @@ -273,11 +320,13 @@ namespace LLInitParam  		return true;  	} -	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack) +	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 parent_generation)  	{  		BlockDescriptor& block_data = mostDerivedBlockDescriptor();  		bool names_left = name_stack.first != name_stack.second; +		S32 parse_generation = name_stack.first == name_stack.second ? -1 : name_stack.first->second; +  		if (names_left)  		{  			const std::string& top_name = name_stack.first->first; @@ -294,7 +343,7 @@ namespace LLInitParam  				Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second);  				++new_name_stack.first; -				return deserialize_func(*paramp, p, new_name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second); +				return deserialize_func(*paramp, p, new_name_stack, parse_generation);  			}  		} @@ -306,7 +355,7 @@ namespace LLInitParam  			Param* paramp = getParamFromHandle((*it)->mParamHandle);  			ParamDescriptor::deserialize_func_t deserialize_func = (*it)->mDeserializeFunc; -			if (deserialize_func && deserialize_func(*paramp, p, name_stack, name_stack.first == name_stack.second ? -1 : name_stack.first->second)) +			if (deserialize_func && deserialize_func(*paramp, p, name_stack, parse_generation))  			{  				return true;  			} @@ -324,32 +373,32 @@ namespace LLInitParam  	}  	//static  -	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptor& in_param, const char* char_name) +	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name)  	{  		// create a copy of the paramdescriptor in allparams  		// so other data structures can store a pointer to it  		block_data.mAllParams.push_back(in_param); -		ParamDescriptor& param(block_data.mAllParams.back()); +		ParamDescriptorPtr param(block_data.mAllParams.back());  		std::string name(char_name); -		if ((size_t)param.mParamHandle > block_data.mMaxParamOffset) +		if ((size_t)param->mParamHandle > block_data.mMaxParamOffset)  		{  			llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;  		}  		if (name.empty())  		{ -			block_data.mUnnamedParams.push_back(¶m); +			block_data.mUnnamedParams.push_back(param);  		}  		else  		{  			// don't use insert, since we want to overwrite existing entries -			block_data.mNamedParams[name] = ¶m; +			block_data.mNamedParams[name] = param;  		} -		if (param.mValidationFunc) +		if (param->mValidationFunc)  		{ -			block_data.mValidationList.push_back(std::make_pair(param.mParamHandle, param.mValidationFunc)); +			block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));  		}  	} @@ -367,7 +416,7 @@ namespace LLInitParam  				llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;  			} -			ParamDescriptor* param_descriptor = findParamDescriptor(handle); +			ParamDescriptorPtr param_descriptor = findParamDescriptor(param);  			if (param_descriptor)  			{  				if (synonym.empty()) @@ -382,7 +431,7 @@ namespace LLInitParam  		}  	} -	void BaseBlock::setLastChangedParam(const Param& last_param, bool user_provided) +	void BaseBlock::paramChanged(const Param& changed_param, bool user_provided)  	{   		if (user_provided)  		{ @@ -404,17 +453,18 @@ namespace LLInitParam  		return LLStringUtil::null;  	} -	ParamDescriptor* BaseBlock::findParamDescriptor(param_handle_t handle) +	ParamDescriptorPtr BaseBlock::findParamDescriptor(const Param& param)  	{ +		param_handle_t handle = getHandleFromParam(¶m);  		BlockDescriptor& descriptor = mostDerivedBlockDescriptor();  		BlockDescriptor::all_params_list_t::iterator end_it = descriptor.mAllParams.end();  		for (BlockDescriptor::all_params_list_t::iterator it = descriptor.mAllParams.begin();  			it != end_it;  			++it)  		{ -			if (it->mParamHandle == handle) return &(*it); +			if ((*it)->mParamHandle == handle) return *it;  		} -		return NULL; +		return ParamDescriptorPtr();  	}  	// take all provided params from other and apply to self @@ -427,19 +477,14 @@ namespace LLInitParam  			it != end_it;  			++it)  		{ -			const Param* other_paramp = other.getParamFromHandle(it->mParamHandle); -			ParamDescriptor::merge_func_t merge_func = it->mMergeFunc; +			const Param* other_paramp = other.getParamFromHandle((*it)->mParamHandle); +			ParamDescriptor::merge_func_t merge_func = (*it)->mMergeFunc;  			if (merge_func)  			{ -				Param* paramp = getParamFromHandle(it->mParamHandle); +				Param* paramp = getParamFromHandle((*it)->mParamHandle);  				some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);  			}  		}  		return some_param_changed;  	} - -	bool ParamCompare<LLSD, false>::equals(const LLSD &a, const LLSD &b) -	{ -		return false; -	}  } diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h index 1f9045754a..858f8405b4 100644 --- a/indra/llxuixml/llinitparam.h +++ b/indra/llxuixml/llinitparam.h @@ -1,5 +1,5 @@  /**  -f * @file llinitparam.h + * @file llinitparam.h   * @brief parameter block abstraction for creating complex objects and    * parsing construction parameters from xml and LLSD   * @@ -29,18 +29,14 @@ f * @file llinitparam.h  #define LL_LLPARAM_H  #include <vector> - -#include <stddef.h>  #include <boost/function.hpp> -#include <boost/bind.hpp>  #include <boost/type_traits/is_convertible.hpp>  #include <boost/unordered_map.hpp> -#include "llregistry.h" -#include "llmemory.h" - +#include <boost/shared_ptr.hpp>  namespace LLInitParam  { +	template<typename T> const T& defaultValue() { static T value; return value; }  	template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >      struct ParamCompare  @@ -61,122 +57,119 @@ namespace LLInitParam  		}  	}; -	// default constructor adaptor for InitParam Values -	// constructs default instances of the given type, returned by const reference -	template <typename T> -	struct DefaultInitializer +	template<>  +	struct ParamCompare<LLSD, false>  	{ -		typedef const T&			T_const_ref; -		// return reference to a single default instance of T -		// built-in types will be initialized to zero, default constructor otherwise -		static T_const_ref get() { static T t = T(); return t; }  +		static bool equals(const LLSD &a, const LLSD &b) { return false; }  	};  	// helper functions and classes  	typedef ptrdiff_t param_handle_t; +	// empty default implementation of key cache +	// leverages empty base class optimization  	template <typename T>  	class TypeValues  	{  	public: -		// empty default implemenation of key cache -		class KeyCache +		typedef std::map<std::string, T> value_name_map_t; + +		void setValueName(const std::string& key) {} +		std::string getValueName() const { return ""; } +		void clearValueName() const {} + +		static bool getValueFromName(const std::string& name, T& value)  		{ -		public: -			void setKey(const std::string& key) {} -			std::string getKey() const { return ""; } -			void clearKey(){} -		}; +			return false; +		} -		static bool get(const std::string& name, T& value) +		static bool valueNamesExist()  		{  			return false;  		} -		static bool empty() +		static std::vector<std::string>* getPossibleValues()  		{ -			return true; +			return NULL;  		} -		static std::vector<std::string>* getPossibleValues() { return NULL; } +		static value_name_map_t* getValueNames() {return NULL;}  	};  	template <typename T, typename DERIVED_TYPE = TypeValues<T> >  	class TypeValuesHelper -	:	public LLRegistrySingleton<std::string, T, DERIVED_TYPE >  	{ -		typedef LLRegistrySingleton<std::string, T, DERIVED_TYPE>	super_t; -		typedef LLSingleton<DERIVED_TYPE>							singleton_t;  	public: +		typedef typename std::map<std::string, T> value_name_map_t;  		//TODO: cache key by index to save on param block size -		class KeyCache +		void setValueName(const std::string& value_name)   		{ -		public: -			void setKey(const std::string& key)  -			{ -				mKey = key;  -			} - -			void clearKey() -			{ -				mKey = ""; -			} +			mValueName = value_name;  +		} -			std::string getKey() const -			{  -				return mKey;  -			} +		std::string getValueName() const +		{  +			return mValueName;  +		} -		private: -			std::string mKey; -		}; +		void clearValueName() const +		{ +			mValueName.clear(); +		} -		static bool get(const std::string& name, T& value) +		static bool getValueFromName(const std::string& name, T& value)  		{ -			if (!singleton_t::instance().exists(name)) return false; +			value_name_map_t* map = getValueNames(); +			typename value_name_map_t::iterator found_it = map->find(name); +			if (found_it == map->end()) return false; -			value = *singleton_t::instance().getValue(name); +			value = found_it->second;  			return true;  		} -		static bool empty() +		static bool valueNamesExist()  		{ -			return singleton_t::instance().LLRegistry<std::string, T>::empty(); +			return !getValueNames()->empty();  		} -		//override this to add name value pairs -		static void declareValues() {} -	 -		void initSingleton() +		static value_name_map_t* getValueNames()  		{ -			DERIVED_TYPE::declareValues(); -		} +			static value_name_map_t sMap; +			static bool sInitialized = false; -		static const std::vector<std::string>* getPossibleValues()  -		{  -			// in order to return a pointer to a member, we lazily -			// evaluate the result and store it in mValues here -			if (singleton_t::instance().mValues.empty()) +			if (!sInitialized)  			{ -				typename super_t::Registrar::registry_map_t::const_iterator it; -				for (it = super_t::defaultRegistrar().beginItems(); it != super_t::defaultRegistrar().endItems(); ++it) -				{ -					singleton_t::instance().mValues.push_back(it->first); -				} +				sInitialized = true; +				DERIVED_TYPE::declareValues();  			} -			return &singleton_t::instance().mValues;  +			return &sMap;  		} +		static std::vector<std::string>* getPossibleValues() +		{ +			static std::vector<std::string> sValues; + +			value_name_map_t* map = getValueNames(); +			for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end(); +				 it != end_it; +				 ++it) +			{ +				sValues.push_back(it->first); +			} +			return &sValues; +		} -	protected:  		static void declare(const std::string& name, const T& value)  		{ -			super_t::defaultRegistrar().add(name, value); +			(*getValueNames())[name] = value;  		} -	private: -		std::vector<std::string> mValues; +	protected: +		static void getName(const std::string& name, const T& value) +		{} + +		mutable std::string	mValueName;  	};  	class Parser @@ -193,9 +186,9 @@ namespace LLInitParam  			}  		}; -		typedef std::vector<std::pair<std::string, S32> >			name_stack_t; +		typedef std::vector<std::pair<std::string, S32> >								name_stack_t;  		typedef std::pair<name_stack_t::const_iterator, name_stack_t::const_iterator>	name_stack_range_t; -		typedef std::vector<std::string>							possible_values_t; +		typedef std::vector<std::string>												possible_values_t;  		typedef bool (*parser_read_func_t)(Parser& parser, void* output);  		typedef bool (*parser_write_func_t)(Parser& parser, const void*, const name_stack_t&); @@ -207,7 +200,7 @@ namespace LLInitParam  		Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)  		:	mParseSilently(false), -			mParseGeneration(0), +			mParseGeneration(sNextParseGeneration),  			mParserReadFuncs(&read_map),  			mParserWriteFuncs(&write_map),  			mParserInspectFuncs(&inspect_map) @@ -252,7 +245,7 @@ namespace LLInitParam  		void setParseSilently(bool silent) { mParseSilently = silent; }  		S32 getParseGeneration() { return mParseGeneration; } -		S32 newParseGeneration() { return ++mParseGeneration; } +		S32 newParseGeneration() { return mParseGeneration = ++sNextParseGeneration; }  	protected: @@ -276,6 +269,8 @@ namespace LLInitParam  		parser_write_func_map_t*	mParserWriteFuncs;  		parser_inspect_func_map_t*	mParserInspectFuncs;  		S32	mParseGeneration; + +		static S32					sNextParseGeneration;  	};  	// used to indicate no matching value to a given name when parsing @@ -295,12 +290,13 @@ namespace LLInitParam  		Param(class BaseBlock* enclosing_block);  		// store pointer to enclosing block as offset to reduce space and allow for quick copying -		BaseBlock& enclosingBlock() const +		class BaseBlock& enclosingBlock() const  		{   			const U8* my_addr = reinterpret_cast<const U8*>(this);  			// get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class -			return *const_cast<BaseBlock*>( -							reinterpret_cast<const BaseBlock*>(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset)); +			return *const_cast<class BaseBlock*> +				(reinterpret_cast<const class BaseBlock*> +					(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));  		}  	private: @@ -313,7 +309,11 @@ namespace LLInitParam  	// various callbacks and constraints associated with an individual param  	struct ParamDescriptor  	{ -	public: +		struct UserData +		{ +			virtual ~UserData() {} +		}; +  		typedef bool(*merge_func_t)(Param&, const Param&, bool);  		typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, S32);  		typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param); @@ -321,40 +321,18 @@ namespace LLInitParam  		typedef bool(*validation_func_t)(const Param*);  		ParamDescriptor(param_handle_t p,  -				merge_func_t merge_func,  -				deserialize_func_t deserialize_func,  -				serialize_func_t serialize_func, -				validation_func_t validation_func, -				inspect_func_t inspect_func, -				S32 min_count, -				S32 max_count) -		:	mParamHandle(p), -			mMergeFunc(merge_func), -			mDeserializeFunc(deserialize_func), -			mSerializeFunc(serialize_func), -			mValidationFunc(validation_func), -			mInspectFunc(inspect_func), -			mMinCount(min_count), -			mMaxCount(max_count), -			mGeneration(0), -			mNumRefs(0) -		{} +						merge_func_t merge_func,  +						deserialize_func_t deserialize_func,  +						serialize_func_t serialize_func, +						validation_func_t validation_func, +						inspect_func_t inspect_func, +						S32 min_count, +						S32 max_count); -		ParamDescriptor() -		:	mParamHandle(0), -			mMergeFunc(NULL), -			mDeserializeFunc(NULL), -			mSerializeFunc(NULL), -			mValidationFunc(NULL), -			mInspectFunc(NULL), -			mMinCount(0), -			mMaxCount(0), -			mGeneration(0), -			mNumRefs(0) -		{} +		ParamDescriptor(); +		~ParamDescriptor();  		param_handle_t		mParamHandle; -	  		merge_func_t		mMergeFunc;  		deserialize_func_t	mDeserializeFunc;  		serialize_func_t	mSerializeFunc; @@ -364,17 +342,16 @@ namespace LLInitParam  		S32					mMaxCount;  		S32					mGeneration;  		S32					mNumRefs; +		UserData*			mUserData;  	}; +	typedef boost::shared_ptr<ParamDescriptor> ParamDescriptorPtr; +  	// each derived Block class keeps a static data structure maintaining offsets to various params  	class BlockDescriptor  	{  	public: -		BlockDescriptor() -		:	mMaxParamOffset(0), -			mInitializationState(UNINITIALIZED), -			mCurrentBlockPtr(NULL) -		{} +		BlockDescriptor();  		typedef enum e_initialization_state  		{ @@ -385,12 +362,10 @@ namespace LLInitParam  		void aggregateBlockData(BlockDescriptor& src_block_data); -	public: -		typedef boost::unordered_map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams -		typedef std::vector<ParamDescriptor*> param_list_t;  - -		typedef std::list<ParamDescriptor> all_params_list_t;// references param descriptors stored in mAllParams -		typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> > param_validation_list_t; +		typedef boost::unordered_map<const std::string, ParamDescriptorPtr>						param_map_t;  +		typedef std::vector<ParamDescriptorPtr>													param_list_t;  +		typedef std::list<ParamDescriptorPtr>														all_params_list_t; +		typedef std::vector<std::pair<param_handle_t, ParamDescriptor::validation_func_t> >		param_validation_list_t;  		param_map_t						mNamedParams;			// parameters with associated names  		param_list_t					mUnnamedParams;			// parameters with_out_ associated names @@ -456,6 +431,7 @@ namespace LLInitParam  		Param* getParamFromHandle(const param_handle_t param_handle)  		{  			if (param_handle == 0) return NULL; +  			U8* baseblock_address = reinterpret_cast<U8*>(this);  			return reinterpret_cast<Param*>(baseblock_address + param_handle);  		} @@ -469,14 +445,13 @@ namespace LLInitParam  		void addSynonym(Param& param, const std::string& synonym);  		// Blocks can override this to do custom tracking of changes -		virtual void setLastChangedParam(const Param& last_param, bool user_provided); +		virtual void paramChanged(const Param& changed_param, bool user_provided);  		S32 getLastChangeVersion() const { return mChangeVersion; } -		bool isDefault() const { return mChangeVersion == 0; } -		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack); -		bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const; -		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) const; +		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation); +		void serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const; +		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;  		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }  		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); } @@ -493,7 +468,10 @@ namespace LLInitParam  			return false;  		} -		static void addParam(BlockDescriptor& block_data, const ParamDescriptor& param, const char* name); +		static void addParam(BlockDescriptor& block_data, ParamDescriptorPtr param, const char* name); + +		ParamDescriptorPtr findParamDescriptor(const Param& param); +  	protected:  		void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size); @@ -512,63 +490,133 @@ namespace LLInitParam  	private:  		const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const; -		ParamDescriptor* findParamDescriptor(param_handle_t handle); -	}; - - -	template<typename T> -	struct ParamIterator -	{ -		typedef typename std::vector<T>::const_iterator		const_iterator; -		typedef typename std::vector<T>::iterator			iterator;  	};  	// these templates allow us to distinguish between template parameters  	// that derive from BaseBlock and those that don't -	// this is supposedly faster than boost::is_convertible and its ilk  	template<typename T, typename Void = void> -	struct IsBaseBlock +	struct IsBlock  	{  		static const bool value = false;  	};  	template<typename T> -	struct IsBaseBlock<T, typename T::baseblock_base_class_t> +	struct IsBlock<T, typename T::baseblock_base_class_t>  	{  		static const bool value = true;  	}; +	template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value> +	class ParamValue : public NAME_VALUE_LOOKUP +	{ +	public: +		typedef const T&							value_assignment_t; + +		ParamValue(): mValue() {} +		ParamValue(const T& other) : mValue(other) {} + +		void setValue(value_assignment_t val) +		{ +			mValue = val; +		} + +		value_assignment_t getValue() const +		{ +			return mValue; +		} + +		T& getValue() +		{ +			return mValue; +		} + +	private: +		T mValue; +	}; + +	template<typename T, typename NAME_VALUE_LOOKUP> +	class ParamValue<T, NAME_VALUE_LOOKUP, true>  +	:	public T, +		public NAME_VALUE_LOOKUP +	{ +	public: +		typedef const T&							value_assignment_t; + +		S32 			mKeyVersion; +		mutable S32 	mValidatedVersion; +		mutable bool 	mValidated; // lazy validation flag + +		ParamValue()  +		:	T(), +			mKeyVersion(0), +			mValidatedVersion(-1), +			mValidated(false) +		{} + +		ParamValue(const T& other) +		:	T(other), +			mKeyVersion(0), +			mValidatedVersion(-1), +			mValidated(false) +		{ +		} + +		void setValue(value_assignment_t val) +		{ +			*this = val; +		} + +		value_assignment_t getValue() const +		{ +			return *this; +		} + +		T& getValue() +		{ +			return *this; +		} +	}; + +	template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> > +	struct ParamIterator +	{ +		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator		const_iterator; +		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator			iterator; +	}; +  	// specialize for custom parsing/decomposition of specific classes  	// e.g. TypedParam<LLRect> has left, top, right, bottom, etc...  	template<typename	T,  			typename	NAME_VALUE_LOOKUP = TypeValues<T>,  			bool		HAS_MULTIPLE_VALUES = false, -			bool		VALUE_IS_BLOCK = IsBaseBlock<T>::value> +			bool		VALUE_IS_BLOCK = IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>  	class TypedParam  -	:	public Param +	:	public Param,  +		public ParamValue<T, NAME_VALUE_LOOKUP>  	{  	public: -		typedef const T&																	value_const_ref_t; -		typedef value_const_ref_t															value_assignment_t; -		typedef typename NAME_VALUE_LOOKUP::KeyCache										key_cache_t; +		typedef const T&																	value_assignment_t;  		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>		self_t; +		typedef NAME_VALUE_LOOKUP															name_value_lookup_t; +		typedef ParamValue<T, NAME_VALUE_LOOKUP>											param_value_t;  		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)   		:	Param(block_descriptor.mCurrentBlockPtr)  		{  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), + 				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),  												&mergeWith,  												&deserializeParam,  												&serializeParam,  												validate_func,  												&inspectParam, -												min_count, max_count); +												min_count, max_count));  				BaseBlock::addParam(block_descriptor, param_descriptor, name);  			} -			mData.mValue = value; +			setValue(value);  		}   		bool isProvided() const { return Param::anyProvided(); } @@ -579,27 +627,27 @@ namespace LLInitParam  			// no further names in stack, attempt to parse value now  			if (name_stack.first == name_stack.second)  			{ -				if (parser.readValue(typed_param.mData.mValue)) +				if (parser.readValue(typed_param.getValue()))  				{ -					typed_param.mData.clearKey(); +					typed_param.clearValueName();  					typed_param.setProvided(true); -					typed_param.enclosingBlock().setLastChangedParam(param, true); +					typed_param.enclosingBlock().paramChanged(param, true);  					return true;  				}  				// try to parse a known named value -				if(!NAME_VALUE_LOOKUP::empty()) +				if(name_value_lookup_t::valueNamesExist())  				{  					// try to parse a known named value  					std::string name;  					if (parser.readValue(name))  					{  						// try to parse a per type named value -						if (NAME_VALUE_LOOKUP::get(name, typed_param.mData.mValue)) +						if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))  						{ -							typed_param.mData.setKey(name); +							typed_param.setValueName(name);  							typed_param.setProvided(true); -							typed_param.enclosingBlock().setLastChangedParam(param, true); +							typed_param.enclosingBlock().paramChanged(param, true);  							return true;  						} @@ -619,13 +667,13 @@ namespace LLInitParam  				name_stack.back().second = parser.newParseGeneration();  			} -			std::string key = typed_param.mData.getKey(); +			std::string key = typed_param.getValueName();  			// first try to write out name of name/value pair  			if (!key.empty())  			{ -				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key)) +				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))  				{  					if (!parser.writeValue(key, name_stack))  					{ @@ -634,8 +682,9 @@ namespace LLInitParam  				}  			}  			// then try to serialize value directly -			else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), static_cast<const self_t*>(diff_param)->get()))					{ -				if (!parser.writeValue(typed_param.mData.mValue, name_stack))  +			else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), static_cast<const self_t*>(diff_param)->getValue())) +			{ +				if (!parser.writeValue(typed_param.getValue(), name_stack))   				{  					return;  				} @@ -647,18 +696,18 @@ namespace LLInitParam  			// tell parser about our actual type  			parser.inspectValue<T>(name_stack, min_count, max_count, NULL);  			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4) -			if (NAME_VALUE_LOOKUP::getPossibleValues()) +			if (name_value_lookup_t::getPossibleValues())  			{ -				parser.inspectValue<std::string>(name_stack, min_count, max_count, NAME_VALUE_LOOKUP::getPossibleValues()); +				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());  			}  		}  		void set(value_assignment_t val, bool flag_as_provided = true)  		{ -			mData.mValue = val; -			mData.clearKey(); +			setValue(val); +			param_value_t::clearValueName();  			setProvided(flag_as_provided); -			Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided); +			Param::enclosingBlock().paramChanged(*this, flag_as_provided);  		}  		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true) @@ -670,65 +719,56 @@ namespace LLInitParam  		}  		// implicit conversion -		operator value_assignment_t() const { return get(); }  +		operator value_assignment_t() const { return param_value_t::getValue(); }   		// explicit conversion -		value_assignment_t operator()() const { return get(); }  +		value_assignment_t operator()() const { return param_value_t::getValue(); }   	protected: -		value_assignment_t get() const -		{ -			return mData.mValue; -		}  		static bool mergeWith(Param& dst, const Param& src, bool overwrite)  		{  			const self_t& src_typed_param = static_cast<const self_t&>(src);  			self_t& dst_typed_param = static_cast<self_t&>(dst); +  			if (src_typed_param.isProvided()  				&& (overwrite || !dst_typed_param.isProvided()))  			{ -				dst_typed_param.mData.clearKey(); -				dst_typed_param.set(src_typed_param.get()); +				dst_typed_param.clearValueName(); +				dst_typed_param.set(src_typed_param.getValue());  				return true;  			}  			return false;  		} - -		struct Data : public key_cache_t -		{ -			T mValue; -		}; - -		Data		mData;  	};  	// parameter that is a block  	template <typename T, typename NAME_VALUE_LOOKUP>  	class TypedParam<T, NAME_VALUE_LOOKUP, false, true>  -	:	public T, -		public Param +	:	public Param, +		public ParamValue<T, NAME_VALUE_LOOKUP>  	{  	public:  		typedef const T											value_const_t;  		typedef T												value_t; -		typedef value_const_t&									value_const_ref_t; -		typedef value_const_ref_t								value_assignment_t; -		typedef typename NAME_VALUE_LOOKUP::KeyCache			key_cache_t; +		typedef value_const_t&									value_assignment_t;  		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true>	self_t; +		typedef NAME_VALUE_LOOKUP								name_value_lookup_t; +		typedef ParamValue<T, NAME_VALUE_LOOKUP>				param_value_t;  		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  		:	Param(block_descriptor.mCurrentBlockPtr), -			T(value) +			param_value_t(value)  		{  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),  												&mergeWith,  												&deserializeParam,  												&serializeParam,  												validate_func,   												&inspectParam, -												min_count, max_count); +												min_count, max_count));  				BaseBlock::addParam(block_descriptor, param_descriptor, name);  			}  		} @@ -737,25 +777,27 @@ namespace LLInitParam  		{   			self_t& typed_param = static_cast<self_t&>(param);  			// attempt to parse block... -			if(typed_param.deserializeBlock(parser, name_stack)) +			if(typed_param.deserializeBlock(parser, name_stack, generation))  			{ -				typed_param.mData.clearKey(); -				typed_param.enclosingBlock().setLastChangedParam(param, true); +				typed_param.clearValueName(); +				typed_param.enclosingBlock().paramChanged(param, true); +				typed_param.setProvided(true);  				return true;  			} -			if(!NAME_VALUE_LOOKUP::empty()) +			if(name_value_lookup_t::valueNamesExist())  			{  				// try to parse a known named value  				std::string name;  				if (parser.readValue(name))  				{  					// try to parse a per type named value -					if (NAME_VALUE_LOOKUP::get(name, typed_param)) +					if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))  					{ -						typed_param.enclosingBlock().setLastChangedParam(param, true); -						typed_param.mData.setKey(name); -						typed_param.mData.mKeyVersion = typed_param.getLastChangeVersion(); +						typed_param.enclosingBlock().paramChanged(param, true); +						typed_param.setValueName(name); +						typed_param.setProvided(true); +						typed_param.mKeyVersion = typed_param.getLastChangeVersion();  						return true;  					} @@ -767,13 +809,15 @@ namespace LLInitParam  		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)  		{  			const self_t& typed_param = static_cast<const self_t&>(param); +			if (!typed_param.isProvided()) return; +  			if (!name_stack.empty())  			{  				name_stack.back().second = parser.newParseGeneration();  			} -			std::string key = typed_param.mData.getKey(); -			if (!key.empty() && typed_param.mData.mKeyVersion == typed_param.getLastChangeVersion()) +			std::string key = typed_param.getValueName(); +			if (!key.empty() && typed_param.mKeyVersion == typed_param.getLastChangeVersion())  			{  				if (!parser.writeValue(key, name_stack))  				{ @@ -790,33 +834,33 @@ namespace LLInitParam  		{  			// I am a param that is also a block, so just recurse into my contents  			const self_t& typed_param = static_cast<const self_t&>(param); -			typed_param.inspectBlock(parser, name_stack); +			typed_param.inspectBlock(parser, name_stack, min_count, max_count);  		}  		// a param-that-is-a-block is provided when the user has set one of its child params  		// *and* the block as a whole validates  		bool isProvided() const   		{  -			// only validate block when it hasn't already passed validation and user has supplied *some* value -			if (Param::anyProvided() && mData.mValidatedVersion < T::getLastChangeVersion()) +			// only validate block when it hasn't already passed validation with current data +			if (Param::anyProvided() && param_value_t::mValidatedVersion < param_value_t::getLastChangeVersion())  			{  				// a sub-block is "provided" when it has been filled in enough to be valid -				mData.mValidated = T::validateBlock(false); -				mData.mValidatedVersion = T::getLastChangeVersion(); +				param_value_t::mValidated = param_value_t::validateBlock(false); +				param_value_t::mValidatedVersion = param_value_t::getLastChangeVersion();  			} -			return Param::anyProvided() && mData.mValidated; +			return Param::anyProvided() && param_value_t::mValidated;  		}  		// assign block contents to this param-that-is-a-block  		void set(value_assignment_t val, bool flag_as_provided = true)  		{ -			value_t::operator=(val); -			mData.clearKey(); +			setValue(val); +			param_value_t::clearValueName();  			// force revalidation of block by clearing known provided version  			// next call to isProvided() will update provision status based on validity -			mData.mValidatedVersion = 0; +			param_value_t::mValidatedVersion = -1;  			setProvided(flag_as_provided); -			Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided); +			Param::enclosingBlock().paramChanged(*this, flag_as_provided);  		}  		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true) @@ -828,10 +872,10 @@ namespace LLInitParam  		}  		// propagate changed status up to enclosing block -		/*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided) +		/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)  		{  -			T::setLastChangedParam(last_param, user_provided); -			Param::enclosingBlock().setLastChangedParam(*this, user_provided); +			ParamValue<T, NAME_VALUE_LOOKUP>::paramChanged(changed_param, user_provided); +			Param::enclosingBlock().paramChanged(*this, user_provided);  			if (user_provided)  			{  				// a child param has been explicitly changed @@ -841,41 +885,28 @@ namespace LLInitParam  		}  		// implicit conversion -		operator value_assignment_t() const { return get(); }  +		operator value_assignment_t() const { return param_value_t::getValue(); }   		// explicit conversion -		value_assignment_t operator()() const { return get(); }  +		value_assignment_t operator()() const { return param_value_t::getValue(); }   	protected: -		value_assignment_t get() const -		{ -			return *this; -		}  		static bool mergeWith(Param& dst, const Param& src, bool overwrite)  		{  			const self_t& src_typed_param = static_cast<const self_t&>(src);  			self_t& dst_typed_param = static_cast<self_t&>(dst); -			if (dst_typed_param.T::merge(T::selfBlockDescriptor(), src_typed_param, overwrite)) + +			if (src_typed_param.isProvided() +				&& (overwrite || !dst_typed_param.isProvided()))  			{ -				dst_typed_param.mData.clearKey(); -				return true; +				if (dst_typed_param.merge(param_value_t::selfBlockDescriptor(), src_typed_param, overwrite)) +				{ +					dst_typed_param.clearValueName(); +					return true; +				}  			}  			return false;  		} - -		struct Data : public key_cache_t -		{ -			S32 			mKeyVersion; -			mutable S32 	mValidatedVersion; -			mutable bool 	mValidated; // lazy validation flag - -			Data()  -			:	mKeyVersion(0), -				mValidatedVersion(0), -				mValidated(false) -			{} -		}; -		Data	mData;  	};  	// container of non-block parameters @@ -885,29 +916,28 @@ namespace LLInitParam  	{  	public:  		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>		self_t; -		typedef typename std::vector<VALUE_TYPE>							container_t; +		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>			param_value_t; +		typedef typename std::vector<param_value_t>							container_t;  		typedef const container_t&											value_assignment_t;  		typedef VALUE_TYPE													value_t; -		typedef value_t&													value_ref_t; -		typedef const value_t&												value_const_ref_t; +		typedef NAME_VALUE_LOOKUP											name_value_lookup_t; -		typedef typename NAME_VALUE_LOOKUP::KeyCache						key_cache_t; -  		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)  -		:	Param(block_descriptor.mCurrentBlockPtr), -			mValues(value) +		:	Param(block_descriptor.mCurrentBlockPtr)  		{ -			mCachedKeys.resize(mValues.size()); +			std::copy(value.begin(), value.end(), std::back_inserter(mValues)); +  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),  												&mergeWith,  												&deserializeParam,  												&serializeParam,  												validate_func,  												&inspectParam, -												min_count, max_count); +												min_count, max_count));  				BaseBlock::addParam(block_descriptor, param_descriptor, name);  			}  		}  @@ -924,29 +954,22 @@ namespace LLInitParam  				// attempt to read value directly  				if (parser.readValue(value))  				{ -					typed_param.mValues.push_back(value); -					// save an empty name/value key as a placeholder -					typed_param.mCachedKeys.push_back(key_cache_t()); -					typed_param.enclosingBlock().setLastChangedParam(param, true); -					typed_param.setProvided(true); +					typed_param.add(value);  					return true;  				}  				// try to parse a known named value -				if(!NAME_VALUE_LOOKUP::empty()) +				if(name_value_lookup_t::valueNamesExist())  				{  					// try to parse a known named value  					std::string name;  					if (parser.readValue(name))  					{  						// try to parse a per type named value -						if (NAME_VALUE_LOOKUP::get(name, typed_param.mValues)) +						if (name_value_lookup_t::getValueFromName(name, typed_param.mValues))  						{ -							typed_param.mValues.push_back(value); -							typed_param.mCachedKeys.push_back(key_cache_t()); -							typed_param.mCachedKeys.back().setKey(name); -							typed_param.enclosingBlock().setLastChangedParam(param, true); -							typed_param.setProvided(true); +							typed_param.add(value); +							typed_param.mValues.back().setValueName(name);  							return true;  						} @@ -961,25 +984,27 @@ namespace LLInitParam  			const self_t& typed_param = static_cast<const self_t&>(param);  			if (!typed_param.isProvided() || name_stack.empty()) return; -			const_iterator it = typed_param.mValues.begin(); -			for (typename std::vector<key_cache_t>::const_iterator key_it = typed_param.mCachedKeys.begin(); -				it != typed_param.mValues.end(); -				++key_it, ++it) +			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end(); +				it != end_it; +				++it)  			{ -				std::string key = key_it->get(); +				std::string key = it->getValue();  				name_stack.back().second = parser.newParseGeneration(); -				if(!key.empty()) +				if(key.empty()) +				// not parsed via name values, write out value directly  				{ -					if(!parser.writeValue(key, name_stack)) +					if (!parser.writeValue(*it, name_stack))  					{ -						return; +						break;  					}  				} -				// not parse via name values, write out value directly -				else if (!parser.writeValue(*it, name_stack)) +				else   				{ -					return; +					if(!parser.writeValue(key, name_stack)) +					{ +						break; +					}  				}  			}  		} @@ -987,19 +1012,17 @@ namespace LLInitParam  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)  		{  			parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL); -			if (NAME_VALUE_LOOKUP::getPossibleValues()) +			if (name_value_lookup_t::getPossibleValues())  			{ -				parser.inspectValue<std::string>(name_stack, min_count, max_count, NAME_VALUE_LOOKUP::getPossibleValues()); +				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());  			}  		}  		void set(value_assignment_t val, bool flag_as_provided = true)  		{  			mValues = val; -			mCachedKeys.clear(); -			mCachedKeys.resize(mValues.size());  			setProvided(flag_as_provided); -			Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided); +			Param::enclosingBlock().paramChanged(*this, flag_as_provided);  		} @@ -1011,23 +1034,23 @@ namespace LLInitParam  			}  		} -		value_ref_t add() +		value_t& add()  		{ -			mValues.push_back(value_t()); -			mCachedKeys.push_back(key_cache_t()); +			mValues.push_back(param_value_t(value_t()));  			setProvided(true); +			Param::enclosingBlock().paramChanged(*this, true);  			return mValues.back();  		} -		void add(value_const_ref_t item) +		void add(const value_t& item)  		{ -			mValues.push_back(item); -			mCachedKeys.push_back(key_cache_t()); +			mValues.push_back(param_value_t(item));  			setProvided(true); +			Param::enclosingBlock().paramChanged(*this, true);  		}  		// implicit conversion -		operator value_assignment_t() const { return self_t::get(); }  +		operator value_assignment_t() const { return mValues; }   		typedef typename container_t::iterator iterator;  		typedef typename container_t::const_iterator const_iterator; @@ -1044,27 +1067,25 @@ namespace LLInitParam  		}  	protected: -		value_assignment_t get() const -		{ -			return mValues; -		} -  		static bool mergeWith(Param& dst, const Param& src, bool overwrite)  		{  			const self_t& src_typed_param = static_cast<const self_t&>(src);  			self_t& dst_typed_param = static_cast<self_t&>(dst); -			if (src_typed_param.isProvided() -				&& (overwrite || !dst_typed_param.isProvided())) +			if (overwrite)  			{ -				dst_typed_param.set(src_typed_param.get()); -				return true; +				std::copy(src_typed_param.begin(), src_typed_param.end(), std::back_inserter(dst_typed_param.mValues));  			} -			return false; +			else +			{ +				container_t new_values(src_typed_param.mValues); +				std::copy(dst_typed_param.begin(), dst_typed_param.end(), std::back_inserter(new_values)); +				std::swap(dst_typed_param.mValues, new_values); +			} +			return true;  		}  		container_t		mValues; -		std::vector<key_cache_t>	mCachedKeys;  	};  	// container of block parameters @@ -1074,80 +1095,76 @@ namespace LLInitParam  	{  	public:  		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>	self_t; -		typedef typename std::vector<VALUE_TYPE>						container_t; +		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>				param_value_t; +		typedef typename std::vector<param_value_t>						container_t;  		typedef const container_t&										value_assignment_t; -  		typedef VALUE_TYPE												value_t; -		typedef value_t&												value_ref_t; -		typedef const value_t&											value_const_ref_t; - -		typedef typename NAME_VALUE_LOOKUP::KeyCache					key_cache_t; +		typedef NAME_VALUE_LOOKUP										name_value_lookup_t;  		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)   		:	Param(block_descriptor.mCurrentBlockPtr), -			mValues(value), -			mLastParamGeneration(0) +			mLastParseGeneration(0)  		{ -			mCachedKeys.resize(mValues.size()); +			std::copy(value.begin(), value.end(), back_inserter(mValues)); +  			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  			{ -				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),  												&mergeWith,  												&deserializeParam,  												&serializeParam,  												validate_func,  												&inspectParam, -												min_count, max_count); +												min_count, max_count));  				BaseBlock::addParam(block_descriptor, param_descriptor, name);  			}  		}   		bool isProvided() const { return Param::anyProvided(); } -		value_ref_t operator[](S32 index) { return mValues[index]; } -		value_const_ref_t operator[](S32 index) const { return mValues[index]; } -  		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)   		{   			self_t& typed_param = static_cast<self_t&>(param);  			bool new_value = false; -			if (generation != typed_param.mLastParamGeneration || typed_param.mValues.empty()) + +			if (generation != typed_param.mLastParseGeneration  +				|| typed_param.mValues.empty())  			{  				new_value = true;  				typed_param.mValues.push_back(value_t()); -				typed_param.mCachedKeys.push_back(Data());  			} -			value_ref_t value = typed_param.mValues.back(); +			param_value_t& value = typed_param.mValues.back();  			// attempt to parse block... -			if(value.deserializeBlock(parser, name_stack)) +			if(value.deserializeBlock(parser, name_stack, generation))  			{  				if (new_value)  				{	// successfully parsed new value, let's keep it -					typed_param.mLastParamGeneration = generation; +					typed_param.mLastParseGeneration = generation;  				} -				typed_param.enclosingBlock().setLastChangedParam(param, true); +				typed_param.enclosingBlock().paramChanged(param, true);  				typed_param.setProvided(true);  				return true;  			} -			else if(!NAME_VALUE_LOOKUP::empty()) +			else if(name_value_lookup_t::valueNamesExist())  			{  				// try to parse a known named value  				std::string name;  				if (parser.readValue(name))  				{  					// try to parse a per type named value -					if (NAME_VALUE_LOOKUP::get(name, value)) +					if (name_value_lookup_t::getValueFromName(name, value.getValue()))  					{  						if (new_value)  						{	// successfully parsed new value, let's keep it -							typed_param.mLastParamGeneration = generation; +							typed_param.mLastParseGeneration = generation;  						} -						typed_param.mCachedKeys.back().setKey(name); -						typed_param.mCachedKeys.back().mKeyVersion = value.getLastChangeVersion(); -						typed_param.enclosingBlock().setLastChangedParam(param, true); +						typed_param.mValues.back().setValueName(name); +						typed_param.mValues.back().mKeyVersion = value.getLastChangeVersion(); +						typed_param.enclosingBlock().paramChanged(param, true);  						typed_param.setProvided(true);  						return true;  					} @@ -1158,7 +1175,6 @@ namespace LLInitParam  			if (new_value)  			{	// failed to parse new value, pop it off  				typed_param.mValues.pop_back(); -				typed_param.mCachedKeys.pop_back();  			}  			return false; @@ -1169,26 +1185,22 @@ namespace LLInitParam  			const self_t& typed_param = static_cast<const self_t&>(param);  			if (!typed_param.isProvided() || name_stack.empty()) return; -			const_iterator it = typed_param.mValues.begin(); -			for (typename std::vector<Data>::const_iterator key_it = typed_param.mCachedKeys.begin(); -				it != typed_param.mValues.end(); -				++key_it, ++it) +			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end(); +				it != end_it; +				++it)  			{  				name_stack.back().second = parser.newParseGeneration(); -				std::string key = key_it->getKey(); -				if (!key.empty() && key_it->mKeyVersion == it->getLastChangeVersion()) +				std::string key = it->getValueName(); +				if (!key.empty() && it->mKeyVersion == it->getLastChangeVersion())  				{ -					if(!parser.writeValue(key, name_stack)) -					{ -						return; -					} +					parser.writeValue(key, name_stack);  				}  				// Not parsed via named values, write out value directly  				// NOTE: currently we don't worry about removing default values in Multiple -				else if (!it->serializeBlock(parser, name_stack, NULL)) +				else   				{ -					return; +					it->serializeBlock(parser, name_stack, NULL);  				}  			}  		} @@ -1196,16 +1208,14 @@ namespace LLInitParam  		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)  		{  			// I am a vector of blocks, so describe my contents recursively -			value_t().inspectBlock(parser, name_stack); +			param_value_t(value_t()).inspectBlock(parser, name_stack, min_count, max_count);  		}  		void set(value_assignment_t val, bool flag_as_provided = true)  		{  			mValues = val; -			mCachedKeys.clear(); -			mCachedKeys.resize(mValues.size());  			setProvided(flag_as_provided); -			Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided); +			Param::enclosingBlock().paramChanged(*this, flag_as_provided);  		}  		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true) @@ -1216,23 +1226,23 @@ namespace LLInitParam  			}  		} -		value_ref_t add() +		value_t& add()  		{  			mValues.push_back(value_t()); -			mCachedKeys.push_back(Data());  			setProvided(true); +			Param::enclosingBlock().paramChanged(*this, true);  			return mValues.back();  		} -		void add(value_const_ref_t item) +		void add(const value_t& item)  		{  			mValues.push_back(item); -			mCachedKeys.push_back(Data());  			setProvided(true); +			Param::enclosingBlock().paramChanged(*this, true);  		}  		// implicit conversion -		operator value_assignment_t() const { return self_t::get(); }  +		operator value_assignment_t() const { return mValues; }   		typedef typename container_t::iterator iterator;  		typedef typename container_t::const_iterator const_iterator; @@ -1246,8 +1256,8 @@ namespace LLInitParam  		U32 numValidElements() const  		{  			U32 count = 0; -			for (const_iterator it = mValues.begin(); -				it != mValues.end(); +			for (const_iterator it = mValues.begin(), end_it = mValues.end(); +				it != end_it;  				++it)  			{  				if(it->validateBlock(false)) count++; @@ -1256,43 +1266,35 @@ namespace LLInitParam  		}  	protected: -		value_assignment_t get() const -		{ -			return mValues; -		}  		static bool mergeWith(Param& dst, const Param& src, bool overwrite)  		{  			const self_t& src_typed_param = static_cast<const self_t&>(src);  			self_t& dst_typed_param = static_cast<self_t&>(dst); -			if (src_typed_param.isProvided() -				&& (overwrite || !dst_typed_param.isProvided())) +			if (overwrite)  			{ -				dst_typed_param.set(src_typed_param.get()); -				return true; +				std::copy(src_typed_param.begin(), src_typed_param.end(), std::back_inserter(dst_typed_param.mValues));  			} -			return false; +			else +			{ +				container_t new_values(src_typed_param.mValues); +				std::copy(dst_typed_param.begin(), dst_typed_param.end(), std::back_inserter(new_values)); +				std::swap(dst_typed_param.mValues, new_values); +			} +			return true;  		} -		struct Data : public key_cache_t -		{ -			S32 mKeyVersion;	// version of block for which key was last valid - -			Data() : mKeyVersion(0) {} -		}; -  		container_t			mValues; -		std::vector<Data>	mCachedKeys; -		S32			mLastParamGeneration; +		S32			mLastParseGeneration;  	};  	template <typename DERIVED_BLOCK>  	class Choice : public BaseBlock  	{ -		typedef Choice<DERIVED_BLOCK> self_t; -		typedef Choice<DERIVED_BLOCK> enclosing_block_t; +		typedef Choice<DERIVED_BLOCK>	self_t; +		typedef Choice<DERIVED_BLOCK>	enclosing_block_t;  		LOG_CLASS(self_t);  	public: @@ -1321,9 +1323,9 @@ namespace LLInitParam  		}  		// clear out old choice when param has changed -		/*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided) +		/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)  		{  -			param_handle_t changed_param_handle = BaseBlock::getHandleFromParam(&last_param); +			param_handle_t changed_param_handle = BaseBlock::getHandleFromParam(&changed_param);  			// if we have a new choice...  			if (changed_param_handle != mCurChoice)  			{ @@ -1335,7 +1337,7 @@ namespace LLInitParam  				}  				mCurChoice = changed_param_handle;  			} -			BaseBlock::setLastChangedParam(last_param, user_provided); +			BaseBlock::paramChanged(changed_param, user_provided);  		}  		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } @@ -1358,20 +1360,21 @@ namespace LLInitParam  			friend class Choice<DERIVED_BLOCK>;  			typedef Alternative<T, NAME_VALUE_LOOKUP>									self_t; -			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value>		super_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t;  			typedef typename super_t::value_assignment_t								value_assignment_t; -			explicit Alternative(const char* name, value_assignment_t val = DefaultInitializer<T>::get()) +			explicit Alternative(const char* name, value_assignment_t val = defaultValue<T>())  			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),  				mOriginalValue(val)  			{  				// assign initial choice to first declared option  				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr); -				if (LL_UNLIKELY( -						DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING -							&& blockp->mCurChoice == 0)) +				if (LL_UNLIKELY(DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))  				{ -					blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this); +					if(blockp->mCurChoice == 0) +					{ +						blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this); +					}  				}  			} @@ -1390,7 +1393,7 @@ namespace LLInitParam  			{   				if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)  				{ -					return super_t::get();  +					return super_t::getValue();   				}  				return mOriginalValue;  			}  @@ -1399,7 +1402,7 @@ namespace LLInitParam  			{   				if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)  				{ -					return super_t::get();  +					return super_t::getValue();   				}  				return mOriginalValue;  			}  @@ -1433,8 +1436,8 @@ namespace LLInitParam  	class Block   	:	public BASE_BLOCK  	{ -		typedef Block<DERIVED_BLOCK, BASE_BLOCK> self_t; -		typedef Block<DERIVED_BLOCK, BASE_BLOCK> block_t; +		typedef Block<DERIVED_BLOCK, BASE_BLOCK>	self_t; +		typedef Block<DERIVED_BLOCK, BASE_BLOCK>	block_t;  	public:  		typedef BASE_BLOCK base_block_t; @@ -1442,13 +1445,13 @@ namespace LLInitParam  		// take all provided params from other and apply to self  		bool overwriteFrom(const self_t& other)  		{ -			return BaseBlock::merge(selfBlockDescriptor(), other, true); +			return static_cast<DERIVED_BLOCK*>(this)->merge(selfBlockDescriptor(), other, true);  		}  		// take all provided params that are not already provided, and apply to self  		bool fillFrom(const self_t& other)  		{ -			return BaseBlock::merge(selfBlockDescriptor(), other, false); +			return static_cast<DERIVED_BLOCK*>(this)->merge(selfBlockDescriptor(), other, false);  		}  		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); } @@ -1468,10 +1471,10 @@ namespace LLInitParam  		class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>  		{  		public: -			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value>		super_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t;  			typedef typename super_t::value_assignment_t								value_assignment_t; -			explicit Optional(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get()) +			explicit Optional(const char* name = "", value_assignment_t val = defaultValue<T>())  			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1)  			{  				//#pragma message("Parsing LLInitParam::Block::Optional") @@ -1483,7 +1486,7 @@ namespace LLInitParam  				return *this;  			} -			DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val) +			DERIVED_BLOCK& operator()(value_assignment_t val)  			{  				super_t::set(val);  				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock()); @@ -1495,12 +1498,12 @@ namespace LLInitParam  		class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>  		{  		public: -			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBaseBlock<T>::value>		super_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t;  			typedef Mandatory<T, NAME_VALUE_LOOKUP>										self_t;  			typedef typename super_t::value_assignment_t								value_assignment_t;  			// mandatory parameters require a name to be parseable -			explicit Mandatory(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get()) +			explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue<T>())  			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1)  			{} @@ -1529,15 +1532,15 @@ namespace LLInitParam  		class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>  		{  		public: -			typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBaseBlock<T>::value>	super_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>	super_t;  			typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP>							self_t;  			typedef typename super_t::container_t									container_t;  			typedef typename super_t::value_assignment_t							value_assignment_t;  			typedef typename super_t::iterator										iterator;  			typedef typename super_t::const_iterator								const_iterator; -			explicit Multiple(const char* name = "", value_assignment_t val = DefaultInitializer<container_t>::get()) -			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, RANGE::minCount(), RANGE::maxCount()) +			explicit Multiple(const char* name = "") +			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount(), RANGE::maxCount())  			{}  			Multiple& operator=(value_assignment_t val) @@ -1545,7 +1548,7 @@ namespace LLInitParam  				set(val);  				return *this;  			} -			 +  			DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)  			{  				super_t::set(val); @@ -1559,6 +1562,96 @@ namespace LLInitParam  			}  		}; +		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> > +		class Batch : private TypedParam<T, NAME_VALUE_LOOKUP, false> +		{ +		public: +			typedef ParamValue<T, NAME_VALUE_LOOKUP>										param_value_t; +			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<param_value_t>::value>	super_t; +			typedef Batch<T, RANGE, NAME_VALUE_LOOKUP>										self_t; +			typedef typename super_t::value_assignment_t									value_assignment_t; +			typedef typename super_t::value_t												value_t; + +			struct BatchDefaultValue : public ParamDescriptor::UserData +			{ +				BatchDefaultValue(const T& value) +				:	mValue(value) +				{} + +				T mValue; +			}; + +			explicit Batch(const char* name, value_assignment_t val) +			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1), +				mLastParseGeneration(-1) +			{ +				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor(); +				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)) +				{ +					ParamDescriptorPtr param_descriptorp = block_descriptor.mCurrentBlockPtr->findParamDescriptor(*this); + +					if (param_descriptorp) +					{ +						param_descriptorp->mDeserializeFunc = &deserializeParam; +						param_descriptorp->mUserData = new BatchDefaultValue(new param_value_t(val)); +					} +				} +			} + +			explicit Batch(const char* name = "") +			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, defaultValue<T>(), NULL, 0, 1), +				mLastParseGeneration(-1) +			{ +				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor(); +				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)) +				{ +					ParamDescriptorPtr param_descriptorp = block_descriptor.mCurrentBlockPtr->findParamDescriptor(*this); + +					if (param_descriptorp) +					{ +						param_descriptorp->mDeserializeFunc = &deserializeParam; +					} +				} +			} + +			Batch& operator=(value_assignment_t val) +			{ +				set(val); +				return *this; +			} + +			DERIVED_BLOCK& operator()(value_assignment_t val) +			{ +				super_t::set(val); +				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock()); +			} + +			using super_t::operator(); + +		private: +			static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)  +			{ +				self_t& typed_param = static_cast<self_t&>(param); + +				if (generation != typed_param.mLastParseGeneration) +				{ +					ParamDescriptorPtr descriptor = typed_param.enclosingBlock().findParamDescriptor(param); +					if (descriptor && static_cast<BatchDefaultValue*>(descriptor->mUserData)) +					{ +						static_cast<param_value_t&>(typed_param) = (static_cast<BatchDefaultValue*>(descriptor->mUserData))->mValue; +					} +					else +					{ +						static_cast<param_value_t&>(typed_param) = param_value_t(value_t()); +					} +					typed_param.mLastParseGeneration = generation; +				} +				return super_t::deserializeParam(param, parser, name_stack, generation); +			} + +			S32 mLastParseGeneration; +		}; +  		class Deprecated : public Param  		{  		public: @@ -1568,13 +1661,14 @@ namespace LLInitParam  				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();  				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))  				{ -					ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), +					ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor( +													block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),  													NULL,  													&deserializeParam,  													NULL,  													NULL,  													NULL,  -													0, S32_MAX); +													0, S32_MAX));  					BaseBlock::addParam(block_descriptor, param_descriptor, name);  				}  			} @@ -1602,137 +1696,91 @@ namespace LLInitParam  		}  	}; -	template<typename T, typename DERIVED = TypedParam<T> > -	class BlockValue -	:	public Block<TypedParam<T, TypeValues<T>, false> >, -		public Param +	template<typename T> +	class CustomParamValue +	:	public Block<ParamValue<T, TypeValues<T> > >, +		public TypeValues<T>  	{  	public:  		typedef enum e_value_age  		{	 -			OLDER_THAN_BLOCK,	// mData.mValue needs to be refreshed from the block parameters -			NEWER_THAN_BLOCK,	// mData.mValue holds the authoritative value (which has been replicated to the block parameters via setBlockFromValue) -			SAME_AS_BLOCK		// mData.mValue is derived from the block parameters, which are authoritative +			VALUE_NEEDS_UPDATE,		// mValue needs to be refreshed from the block parameters +			VALUE_AUTHORITATIVE,	// mValue holds the authoritative value (which has been replicated to the block parameters via updateBlockFromValue) +			BLOCK_AUTHORITATIVE		// mValue is derived from the block parameters, which are authoritative  		} EValueAge; -		typedef BlockValue<T>										self_t; -		typedef Block<TypedParam<T, TypeValues<T>, false> >			block_t; -		typedef const T&											value_const_ref_t; -		typedef value_const_ref_t									value_assignment_t; -		typedef typename TypeValues<T>::KeyCache					key_cache_t; - -		BlockValue(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) -		:	Param(block_descriptor.mCurrentBlockPtr), -			mData(value, NEWER_THAN_BLOCK) -		{ -			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)) -			{ -				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this), -												&mergeWith, -												&deserializeParam, -												&serializeParam, -												validate_func, -												&inspectParam, -												min_count, max_count); -				BaseBlock::addParam(block_descriptor, param_descriptor, name); -			} -		} +		typedef ParamValue<T, TypeValues<T> >	derived_t; +		typedef CustomParamValue<T>				self_t; +		typedef Block<derived_t>		block_t; +		typedef const T&						value_assignment_t; -		// implicit conversion -		operator value_assignment_t() const { return get(); }  -		// explicit conversion -		value_assignment_t operator()() const { return get(); }  +		CustomParamValue(const T& value = T()) +		:	mValue(value), +			mValueAge(VALUE_AUTHORITATIVE), +			mKeyVersion(0), +			mValidatedVersion(-1) +		{} -		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) +		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack, S32 generation)  		{ -			DERIVED& typed_param = static_cast<DERIVED&>(param); +			derived_t& typed_param = static_cast<derived_t&>(*this);  			// type to apply parse direct value T  			if (name_stack.first == name_stack.second)  			{ -				if(parser.readValue(typed_param.mData.mValue)) +				if(parser.readValue(typed_param.mValue))  				{ -					typed_param.enclosingBlock().setLastChangedParam(param, true); -					typed_param.setProvided(true); -					typed_param.mData.clearKey(); -					typed_param.mData.mValueAge = NEWER_THAN_BLOCK; -					typed_param.setBlockFromValue(); +					typed_param.clearValueName(); +					typed_param.mValueAge = VALUE_AUTHORITATIVE; +					typed_param.updateBlockFromValue();  					return true;  				} - -				if(!TypeValues<T>::empty()) -				{ -					// try to parse a known named value -					std::string name; -					if (parser.readValue(name)) -					{ -						// try to parse a per type named value -						if (TypeValues<T>::get(name, typed_param.mData.mValue)) -						{ -							typed_param.mData.setKey(name); -							typed_param.enclosingBlock().setLastChangedParam(param, true); -							typed_param.setProvided(true); -							typed_param.mData.mValueAge = NEWER_THAN_BLOCK; -							typed_param.setBlockFromValue(); - -							return true; -						} -					} -				}  			}  			// fall back on parsing block components for T  			// if we deserialized at least one component... -			if (typed_param.BaseBlock::deserializeBlock(parser, name_stack)) +			if (typed_param.BaseBlock::deserializeBlock(parser, name_stack, generation))  			{ -				// ...our block is provided, and considered changed -				typed_param.enclosingBlock().setLastChangedParam(param, true); -				typed_param.setProvided(true);  				return true;  			} +  			return false;  		} -		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param) +		void serializeBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const  		{ -			const self_t& typed_param = static_cast<const self_t&>(param); +			const self_t& typed_param = static_cast<const self_t&>(*this); +			const self_t* diff_param = static_cast<const self_t*>(diff_block); -			if (!typed_param.isProvided()) return; -			 -			std::string key = typed_param.mData.getKey(); +			std::string key = typed_param.getValueName();  			// first try to write out name of name/value pair  			if (!key.empty())  			{ -				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->mData.getKey(), key)) +				if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key))  				{ -					if (!parser.writeValue(key, name_stack)) -					{ -						return; -					} +					parser.writeValue(key, name_stack);  				}  			}  			// then try to serialize value directly -			else if (!diff_param || !ParamCompare<T>::equals(typed_param.get(), (static_cast<const self_t*>(diff_param))->get()))	 +			else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))              { -				if (parser.writeValue(typed_param.mData.mValue, name_stack))  +				if (!parser.writeValue(typed_param.getValue(), name_stack))   				{ -					return; +					//RN: *always* serialize provided components of BlockValue (don't pass diff_param on), +					// since these tend to be viewed as the constructor arguments for the value T.  It seems +					// cleaner to treat the uniqueness of a BlockValue according to the generated value, and +					// not the individual components.  This way <color red="0" green="1" blue="0"/> will not +					// be exported as <color green="1"/>, since it was probably the intent of the user to  +					// be specific about the RGB color values.  This also fixes an issue where we distinguish +					// between rect.left not being provided and rect.left being explicitly set to 0 (same as default) +					block_t::serializeBlock(parser, name_stack, NULL);  				} - -				//RN: *always* serialize provided components of BlockValue (don't pass diff_param on), -				// since these tend to be viewed as the constructor arguments for the value T.  It seems -				// cleaner to treat the uniqueness of a BlockValue according to the generated value, and -				// not the individual components.  This way <color red="0" green="1" blue="0"/> will not -				// be exported as <color green="1"/>, since it was probably the intent of the user to  -				// be specific about the RGB color values.  This also fixes an issue where we distinguish -				// between rect.left not being provided and rect.left being explicitly set to 0 (same as default) -				typed_param.BaseBlock::serializeBlock(parser, name_stack, NULL);  			}  		} -		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count) +		bool inspectBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const  		{  			// first, inspect with actual type...  			parser.inspectValue<T>(name_stack, min_count, max_count, NULL); @@ -1742,25 +1790,19 @@ namespace LLInitParam  				parser.inspectValue<std::string>(name_stack, min_count, max_count, TypeValues<T>::getPossibleValues());  			}  			// then recursively inspect contents... -			const self_t& typed_param = static_cast<const self_t&>(param); -			typed_param.inspectBlock(parser, name_stack); +			return block_t::inspectBlock(parser, name_stack, min_count, max_count);  		} - -		bool isProvided() const  +		bool validateBlock(bool emit_errors = true) const  		{ -			if (!Param::anyProvided()) return false; - -			// block has an updated parameter -			// if cached value is stale, regenerate from params -			if (mData.mValueAge == OLDER_THAN_BLOCK) +			if (mValueAge == VALUE_NEEDS_UPDATE)  			{ -				if (block_t::validateBlock(false)) +				if (block_t::validateBlock(emit_errors))  				{ -					static_cast<const DERIVED*>(this)->setValueFromBlock();  					// clear stale keyword associated with old value -					mData.clearKey(); -					mData.mValueAge = SAME_AS_BLOCK; +					TypeValues<T>::clearValueName(); +					mValueAge = BLOCK_AUTHORITATIVE; +					static_cast<derived_t*>(const_cast<self_t*>(this))->updateValueFromBlock();  					return true;  				}  				else @@ -1777,104 +1819,75 @@ namespace LLInitParam  			}  		} -		void set(value_assignment_t val, bool flag_as_provided = true) -		{ -			Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided); -			 -			// set param version number to be up to date, so we ignore block contents -			mData.mValueAge = NEWER_THAN_BLOCK; - -			mData.mValue = val; -			mData.clearKey(); -			setProvided(flag_as_provided); -			static_cast<DERIVED*>(this)->setBlockFromValue(); -		} - -		void setIfNotProvided(value_assignment_t val, bool flag_as_provided = true) -		{ -			// don't override any user provided value -			if (!isProvided()) -			{ -				set(val, flag_as_provided); -			} -		} -   		// propagate change status up to enclosing block -		/*virtual*/ void setLastChangedParam(const Param& last_param, bool user_provided) +		/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)  		{  -			BaseBlock::setLastChangedParam(last_param, user_provided); -			Param::enclosingBlock().setLastChangedParam(*this, user_provided); +			BaseBlock::paramChanged(changed_param, user_provided);  			if (user_provided) -			{ -				setProvided(true);  // some component provided +		{  				// a parameter changed, so our value is out of date -				mData.mValueAge = OLDER_THAN_BLOCK; +				mValueAge = VALUE_NEEDS_UPDATE;  			}  		} - -	protected: -		value_assignment_t get() const +			 +		void setValue(value_assignment_t val)  		{ -			// if some parameters were provided, issue warnings on invalid blocks -			if (Param::anyProvided() && (mData.mValueAge == OLDER_THAN_BLOCK)) -			{ -				// go ahead and issue warnings at this point if any param is invalid -				if(block_t::validateBlock(true)) -				{ -					static_cast<const DERIVED*>(this)->setValueFromBlock(); -					mData.clearKey(); -					mData.mValueAge = SAME_AS_BLOCK; -				} -			} - -			return mData.mValue; +			derived_t& typed_param = static_cast<derived_t&>(*this); +			// set param version number to be up to date, so we ignore block contents +			mValueAge = VALUE_AUTHORITATIVE; +			mValue = val; +			typed_param.clearValueName(); +			static_cast<derived_t*>(const_cast<self_t*>(this))->updateBlockFromValue();  		} +		value_assignment_t getValue() const +		{ +			validateBlock(true); +			return mValue; +		} -		struct Data : public key_cache_t +		T& getValue()   		{ -			Data(const T& value, EValueAge age)  -			:	mValue(value), -				mValueAge(age) -			{} +			validateBlock(true); +			return mValue; +		} -			T			mValue; -			EValueAge	mValueAge; -		}; +		S32 				mKeyVersion; -		// mutable to allow lazy updates on get -		mutable Data		mData; +	protected: -	private: -		static bool mergeWith(Param& dst, const Param& src, bool overwrite) +		// use this from within updateValueFromBlock() to set the value without making it authoritative +		void updateValue(value_assignment_t value)  		{ -			const DERIVED& src_typed_param = static_cast<const DERIVED&>(src); -			DERIVED& dst_typed_param = static_cast<DERIVED&>(dst); +			mValue = value; +		} -			if (src_typed_param.isProvided() -				&& (overwrite || !dst_typed_param.isProvided())) +		bool merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) +		{ +			const derived_t& src_typed_param = static_cast<const derived_t&>(other); + +			if (src_typed_param.mValueAge == VALUE_AUTHORITATIVE)  			{ -				if (src_typed_param.mData.mValueAge == NEWER_THAN_BLOCK) -				{ -					// copy value over -					dst_typed_param.set(src_typed_param.get()); -				} -				else -				{ -					// merge individual parameters into destination -					dst_typed_param.merge(block_t::selfBlockDescriptor(), src_typed_param, overwrite); -				} +				// copy value over +				setValue(src_typed_param.getValue());  				return true;  			} -			return false; +			else +			{ +				// merge individual parameters into destination +				return block_t::merge(block_t::selfBlockDescriptor(), src_typed_param, overwrite); +			}  		} -	}; -	template<>  -	struct ParamCompare<LLSD, false> -	{ -		static bool equals(const LLSD &a, const LLSD &b); +		mutable S32			mValidatedVersion; +		mutable bool 		mValidated; // lazy validation flag + +	private: + +		mutable T			mValue; +		mutable EValueAge	mValueAge;  	};  } +  #endif // LL_LLPARAM_H diff --git a/indra/media_plugins/winmmshim/forwarding_api.cpp b/indra/media_plugins/winmmshim/forwarding_api.cpp index eff7e20451..495e08942b 100644 --- a/indra/media_plugins/winmmshim/forwarding_api.cpp +++ b/indra/media_plugins/winmmshim/forwarding_api.cpp @@ -389,90 +389,105 @@ void init_function_pointers(HMODULE winmm_handle)  extern "C" {  	LRESULT   WINAPI CloseDriver( HDRVR hDriver, LPARAM lParam1, LPARAM lParam2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"CloseDriver\n");  		return CloseDriver_orig( hDriver, lParam1, lParam2);  	}  	HDRVR     WINAPI OpenDriver( LPCWSTR szDriverName, LPCWSTR szSectionName, LPARAM lParam2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"OpenDriver\n");  		return OpenDriver_orig( szDriverName, szSectionName, lParam2);  	}  	LRESULT   WINAPI SendDriverMessage( HDRVR hDriver, UINT message, LPARAM lParam1, LPARAM lParam2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"SendDriverMessage\n");  		return SendDriverMessage_orig( hDriver, message, lParam1, lParam2);  	}  	HMODULE   WINAPI DrvGetModuleHandle( HDRVR hDriver)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"DrvGetModuleHandle\n");  		return DrvGetModuleHandle_orig( hDriver);  	}  	HMODULE   WINAPI GetDriverModuleHandle( HDRVR hDriver)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"GetDriverModuleHandle\n");  		return GetDriverModuleHandle_orig( hDriver);  	}  	LRESULT   WINAPI DefDriverProc( DWORD_PTR dwDriverIdentifier, HDRVR hdrvr, UINT uMsg, LPARAM lParam1, LPARAM lParam2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"DefDriverProc\n");  		return DefDriverProc_orig( dwDriverIdentifier, hdrvr, uMsg, lParam1, lParam2);  	}  	BOOL WINAPI DriverCallback( DWORD dwCallBack, DWORD dwFlags, HDRVR hdrvr, DWORD msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"DriverCallback\n");  		return DriverCallback_orig(dwCallBack, dwFlags, hdrvr, msg, dwUser, dwParam1, dwParam2);  	}  	UINT WINAPI mmsystemGetVersion(void)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmsystemGetVersion\n");  		return mmsystemGetVersion_orig();  	}  	BOOL WINAPI sndPlaySoundA( LPCSTR pszSound, UINT fuSound)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"sndPlaySoundA\n");  		return sndPlaySoundA_orig( pszSound, fuSound);  	}  	BOOL WINAPI sndPlaySoundW( LPCWSTR pszSound, UINT fuSound)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"sndPlaySoundW\n");  		return sndPlaySoundW_orig( pszSound, fuSound);  	}  	BOOL WINAPI PlaySoundA( LPCSTR pszSound, HMODULE hmod, DWORD fdwSound)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"PlaySoundA\n");  		return PlaySoundA_orig( pszSound, hmod, fdwSound);  	}  	BOOL WINAPI PlaySoundW( LPCWSTR pszSound, HMODULE hmod, DWORD fdwSound)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"PlaySoundW\n");  		return PlaySoundW_orig( pszSound, hmod, fdwSound);  	}  	UINT WINAPI waveOutGetNumDevs(void)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutGetNumDevs\n");  		return waveOutGetNumDevs_orig();  	}  	MMRESULT WINAPI waveOutGetDevCapsA( UINT_PTR uDeviceID, LPWAVEOUTCAPSA pwoc, UINT cbwoc)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutGetDevCapsA\n");  		return waveOutGetDevCapsA_orig( uDeviceID, pwoc, cbwoc);  	}  	MMRESULT WINAPI waveOutGetDevCapsW( UINT_PTR uDeviceID, LPWAVEOUTCAPSW pwoc, UINT cbwoc)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutGetDevCapsW\n");  		return waveOutGetDevCapsW_orig( uDeviceID, pwoc, cbwoc);  	} @@ -480,24 +495,28 @@ extern "C" {  	MMRESULT WINAPI waveOutGetVolume( HWAVEOUT hwo, LPDWORD pdwVolume)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutGetVolume\n");  		return waveOutGetVolume_orig( hwo, pdwVolume);  	}  	MMRESULT WINAPI waveOutSetVolume( HWAVEOUT hwo, DWORD dwVolume)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutSetVolume\n");  		return waveOutSetVolume_orig( hwo, dwVolume);  	}  	MMRESULT WINAPI waveOutGetErrorTextA( MMRESULT mmrError, LPSTR pszText, UINT cchText)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutGetErrorTextA\n");  		return waveOutGetErrorTextA_orig( mmrError, pszText, cchText);  	}  	MMRESULT WINAPI waveOutGetErrorTextW( MMRESULT mmrError, LPWSTR pszText, UINT cchText)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutGetErrorTextW\n");  		return waveOutGetErrorTextW_orig( mmrError, pszText, cchText);  	} @@ -516,12 +535,14 @@ extern "C" {  	MMRESULT WINAPI waveOutPrepareHeader( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutPrepareHeader\n");  		return waveOutPrepareHeader_orig( hwo, pwh, cbwh);  	}  	MMRESULT WINAPI waveOutUnprepareHeader( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutUnprepareHeader\n");  		return waveOutUnprepareHeader_orig( hwo, pwh, cbwh);  	} @@ -535,834 +556,973 @@ extern "C" {  	MMRESULT WINAPI waveOutPause( HWAVEOUT hwo)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutPause\n");  		return waveOutPause_orig( hwo);  	}  	MMRESULT WINAPI waveOutRestart( HWAVEOUT hwo)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutRestart\n");  		return waveOutRestart_orig( hwo);  	}  	MMRESULT WINAPI waveOutReset( HWAVEOUT hwo)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutReset\n");  		return waveOutReset_orig( hwo);  	}  	MMRESULT WINAPI waveOutBreakLoop( HWAVEOUT hwo)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutBreakLoop\n");  		return waveOutBreakLoop_orig( hwo);  	}  	MMRESULT WINAPI waveOutGetPosition( HWAVEOUT hwo, LPMMTIME pmmt, UINT cbmmt)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutGetPosition\n");  		return waveOutGetPosition_orig( hwo, pmmt, cbmmt);  	}  	MMRESULT WINAPI waveOutGetPitch( HWAVEOUT hwo, LPDWORD pdwPitch)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutGetPitch\n");  		return waveOutGetPitch_orig( hwo, pdwPitch);  	}  	MMRESULT WINAPI waveOutSetPitch( HWAVEOUT hwo, DWORD dwPitch)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutSetPitch\n");  		return waveOutSetPitch_orig( hwo, dwPitch);  	}  	MMRESULT WINAPI waveOutGetPlaybackRate( HWAVEOUT hwo, LPDWORD pdwRate)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutGetPlaybackRate\n");  		return waveOutGetPlaybackRate_orig( hwo, pdwRate);  	}  	MMRESULT WINAPI waveOutSetPlaybackRate( HWAVEOUT hwo, DWORD dwRate)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutSetPlaybackRate\n");  		return waveOutSetPlaybackRate_orig( hwo, dwRate);  	}  	MMRESULT WINAPI waveOutGetID( HWAVEOUT hwo, LPUINT puDeviceID)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutGetID\n");  		return waveOutGetID_orig( hwo, puDeviceID);  	}  	MMRESULT WINAPI waveOutMessage( HWAVEOUT hwo, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveOutMessage\n");  		return waveOutMessage_orig( hwo, uMsg, dw1, dw2);  	}  	UINT WINAPI waveInGetNumDevs(void)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInGetNumDevs\n");  		return waveInGetNumDevs_orig();  	}  	MMRESULT WINAPI waveInGetDevCapsA( UINT_PTR uDeviceID, LPWAVEINCAPSA pwic, UINT cbwic)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInGetDevCapsA\n");  		return waveInGetDevCapsA_orig( uDeviceID, pwic, cbwic);  	}  	MMRESULT WINAPI waveInGetDevCapsW( UINT_PTR uDeviceID, LPWAVEINCAPSW pwic, UINT cbwic)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInGetDevCapsW\n");  		return waveInGetDevCapsW_orig( uDeviceID, pwic, cbwic);  	}  	MMRESULT WINAPI waveInGetErrorTextA(MMRESULT mmrError, LPSTR pszText, UINT cchText)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInGetErrorTextA\n");  		return waveInGetErrorTextA_orig(mmrError, pszText, cchText);  	}  	MMRESULT WINAPI waveInGetErrorTextW(MMRESULT mmrError, LPWSTR pszText, UINT cchText)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInGetErrorTextW\n");  		return waveInGetErrorTextW_orig(mmrError, pszText, cchText);  	}  	MMRESULT WINAPI waveInOpen( LPHWAVEIN phwi, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInOpen\n");  		return waveInOpen_orig(phwi, uDeviceID, pwfx, dwCallback, dwInstance, fdwOpen);  	}  	MMRESULT WINAPI waveInClose( HWAVEIN hwi)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInClose\n");  		return waveInClose_orig( hwi);  	}  	MMRESULT WINAPI waveInPrepareHeader( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInPrepareHeader\n");  		return waveInPrepareHeader_orig( hwi, pwh, cbwh);  	}  	MMRESULT WINAPI waveInUnprepareHeader( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInUnprepareHeader\n");  		return waveInUnprepareHeader_orig( hwi, pwh, cbwh);  	}  	MMRESULT WINAPI waveInAddBuffer( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInAddBuffer\n");  		return waveInAddBuffer_orig( hwi, pwh, cbwh);  	}  	MMRESULT WINAPI waveInStart( HWAVEIN hwi)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInStart\n");  		return waveInStart_orig( hwi);  	}  	MMRESULT WINAPI waveInStop( HWAVEIN hwi)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInStop\n");  		return waveInStop_orig(hwi);  	}  	MMRESULT WINAPI waveInReset( HWAVEIN hwi)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInReset\n");  		return waveInReset_orig(hwi);  	}  	MMRESULT WINAPI waveInGetPosition( HWAVEIN hwi, LPMMTIME pmmt, UINT cbmmt)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInGetPosition\n");  		return waveInGetPosition_orig( hwi, pmmt, cbmmt);  	}  	MMRESULT WINAPI waveInGetID( HWAVEIN hwi, LPUINT puDeviceID)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInGetID\n");  		return waveInGetID_orig( hwi, puDeviceID);  	}  	MMRESULT WINAPI waveInMessage( HWAVEIN hwi, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"waveInMessage\n");  		return waveInMessage_orig( hwi, uMsg, dw1, dw2);  	}  	UINT WINAPI midiOutGetNumDevs(void)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutGetNumDevs\n");  		return midiOutGetNumDevs_orig();  	}  	MMRESULT WINAPI midiStreamOpen( LPHMIDISTRM phms, LPUINT puDeviceID, DWORD cMidi, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiStreamOpen\n");  		return midiStreamOpen_orig( phms, puDeviceID, cMidi, dwCallback, dwInstance, fdwOpen);  	}  	MMRESULT WINAPI midiStreamClose( HMIDISTRM hms)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiStreamClose\n");  		return midiStreamClose_orig( hms);  	}  	MMRESULT WINAPI midiStreamProperty( HMIDISTRM hms, LPBYTE lppropdata, DWORD dwProperty)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiStreamProperty\n");  		return midiStreamProperty_orig( hms, lppropdata, dwProperty);  	}  	MMRESULT WINAPI midiStreamPosition( HMIDISTRM hms, LPMMTIME lpmmt, UINT cbmmt)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiStreamPosition\n");  		return midiStreamPosition_orig( hms, lpmmt, cbmmt);  	}  	MMRESULT WINAPI midiStreamOut( HMIDISTRM hms, LPMIDIHDR pmh, UINT cbmh)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiStreamOut\n");  		return midiStreamOut_orig( hms, pmh, cbmh);  	}  	MMRESULT WINAPI midiStreamPause( HMIDISTRM hms)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiStreamPause\n");  		return midiStreamPause_orig( hms);  	}  	MMRESULT WINAPI midiStreamRestart( HMIDISTRM hms)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiStreamRestart\n");  		return midiStreamRestart_orig( hms);  	}  	MMRESULT WINAPI midiStreamStop( HMIDISTRM hms)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiStreamStop\n");  		return midiStreamStop_orig( hms);  	}  	MMRESULT WINAPI midiConnect( HMIDI hmi, HMIDIOUT hmo, LPVOID pReserved)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiConnect\n");  		return midiConnect_orig( hmi, hmo, pReserved);  	}  	MMRESULT WINAPI midiDisconnect( HMIDI hmi, HMIDIOUT hmo, LPVOID pReserved)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiDisconnect\n");  		return midiDisconnect_orig( hmi, hmo, pReserved);  	}  	MMRESULT WINAPI midiOutGetDevCapsA( UINT_PTR uDeviceID, LPMIDIOUTCAPSA pmoc, UINT cbmoc)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutGetDevCapsA\n");  		return midiOutGetDevCapsA_orig( uDeviceID, pmoc, cbmoc);  	}  	MMRESULT WINAPI midiOutGetDevCapsW( UINT_PTR uDeviceID, LPMIDIOUTCAPSW pmoc, UINT cbmoc)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutGetDevCapsW\n");  		return midiOutGetDevCapsW_orig( uDeviceID, pmoc, cbmoc);  	}  	MMRESULT WINAPI midiOutGetVolume( HMIDIOUT hmo, LPDWORD pdwVolume)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutGetVolume\n");  		return midiOutGetVolume_orig( hmo, pdwVolume);  	}  	MMRESULT WINAPI midiOutSetVolume( HMIDIOUT hmo, DWORD dwVolume)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutSetVolume\n");  		return midiOutSetVolume_orig( hmo, dwVolume);  	}  	MMRESULT WINAPI midiOutGetErrorTextA( MMRESULT mmrError, LPSTR pszText, UINT cchText)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutGetErrorTextA\n");  		return midiOutGetErrorTextA_orig( mmrError, pszText, cchText);  	}  	MMRESULT WINAPI midiOutGetErrorTextW( MMRESULT mmrError, LPWSTR pszText, UINT cchText)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutGetErrorTextW\n");  		return midiOutGetErrorTextW_orig( mmrError, pszText, cchText);  	}  	MMRESULT WINAPI midiOutOpen( LPHMIDIOUT phmo, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutOpen\n");  		return midiOutOpen_orig(phmo, uDeviceID, dwCallback, dwInstance, fdwOpen);  	}  	MMRESULT WINAPI midiOutClose( HMIDIOUT hmo)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutClose\n");  		return midiOutClose_orig( hmo);  	}  	MMRESULT WINAPI midiOutPrepareHeader( HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutPrepareHeader\n");  		return midiOutPrepareHeader_orig( hmo, pmh, cbmh);  	}  	MMRESULT WINAPI midiOutUnprepareHeader(HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutUnprepareHeader\n");  		return midiOutUnprepareHeader_orig(hmo, pmh, cbmh);  	}  	MMRESULT WINAPI midiOutShortMsg( HMIDIOUT hmo, DWORD dwMsg)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutShortMsg\n");  		return midiOutShortMsg_orig( hmo, dwMsg);  	}  	MMRESULT WINAPI midiOutLongMsg(HMIDIOUT hmo, LPMIDIHDR pmh, UINT cbmh)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutLongMsg\n");  		return midiOutLongMsg_orig(hmo, pmh, cbmh);  	}  	MMRESULT WINAPI midiOutReset( HMIDIOUT hmo)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutReset\n");  		return midiOutReset_orig( hmo);  	}  	MMRESULT WINAPI midiOutCachePatches( HMIDIOUT hmo, UINT uBank, LPWORD pwpa, UINT fuCache)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutCachePatches\n");  		return midiOutCachePatches_orig( hmo, uBank, pwpa, fuCache);  	}  	MMRESULT WINAPI midiOutCacheDrumPatches( HMIDIOUT hmo, UINT uPatch, LPWORD pwkya, UINT fuCache)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutCacheDrumPatches\n");  		return midiOutCacheDrumPatches_orig( hmo, uPatch, pwkya, fuCache);  	}  	MMRESULT WINAPI midiOutGetID( HMIDIOUT hmo, LPUINT puDeviceID)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutGetID\n");  		return midiOutGetID_orig( hmo, puDeviceID);  	}  	MMRESULT WINAPI midiOutMessage( HMIDIOUT hmo, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiOutMessage\n");  		return midiOutMessage_orig( hmo, uMsg, dw1, dw2);  	}  	UINT WINAPI midiInGetNumDevs(void)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInGetNumDevs\n");  		return midiInGetNumDevs_orig();  	}  	MMRESULT WINAPI midiInGetDevCapsA( UINT_PTR uDeviceID, LPMIDIINCAPSA pmic, UINT cbmic)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInGetDevCapsA\n");  		return midiInGetDevCapsA_orig( uDeviceID, pmic, cbmic);  	}  	MMRESULT WINAPI midiInGetDevCapsW( UINT_PTR uDeviceID, LPMIDIINCAPSW pmic, UINT cbmic)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInGetDevCapsW\n");  		return midiInGetDevCapsW_orig( uDeviceID, pmic, cbmic);  	}  	MMRESULT WINAPI midiInGetErrorTextA( MMRESULT mmrError, LPSTR pszText, UINT cchText)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInGetErrorTextA\n");  		return midiInGetErrorTextA_orig( mmrError, pszText, cchText);  	}  	MMRESULT WINAPI midiInGetErrorTextW( MMRESULT mmrError, LPWSTR pszText, UINT cchText)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInGetErrorTextW\n");  		return midiInGetErrorTextW_orig( mmrError, pszText, cchText);  	}  	MMRESULT WINAPI midiInOpen( LPHMIDIIN phmi, UINT uDeviceID, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInOpen\n");  		return midiInOpen_orig(phmi, uDeviceID, dwCallback, dwInstance, fdwOpen);  	}  	MMRESULT WINAPI midiInClose( HMIDIIN hmi)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInClose\n");  		return midiInClose_orig( hmi);  	}  	MMRESULT WINAPI midiInPrepareHeader( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInPrepareHeader\n");  		return midiInPrepareHeader_orig( hmi, pmh, cbmh);  	}  	MMRESULT WINAPI midiInUnprepareHeader( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInUnprepareHeader\n");  		return midiInUnprepareHeader_orig( hmi, pmh, cbmh);  	}  	MMRESULT WINAPI midiInAddBuffer( HMIDIIN hmi, LPMIDIHDR pmh, UINT cbmh)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInAddBuffer\n");  		return midiInAddBuffer_orig( hmi, pmh, cbmh);  	}  	MMRESULT WINAPI midiInStart( HMIDIIN hmi)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInStart\n");  		return midiInStart_orig( hmi);  	}  	MMRESULT WINAPI midiInStop( HMIDIIN hmi)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInStop\n");  		return midiInStop_orig(hmi);  	}  	MMRESULT WINAPI midiInReset( HMIDIIN hmi)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInReset\n");  		return midiInReset_orig( hmi);  	}  	MMRESULT WINAPI midiInGetID( HMIDIIN hmi, LPUINT puDeviceID)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInGetID\n");  		return midiInGetID_orig( hmi, puDeviceID);  	}  	MMRESULT WINAPI midiInMessage( HMIDIIN hmi, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"midiInMessage\n");  		return midiInMessage_orig( hmi, uMsg, dw1, dw2);  	}  	UINT WINAPI auxGetNumDevs(void)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"auxGetNumDevs\n");  		return auxGetNumDevs_orig();  	}  	MMRESULT WINAPI auxGetDevCapsA( UINT_PTR uDeviceID, LPAUXCAPSA pac, UINT cbac)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"auxGetDevCapsA\n");  		return auxGetDevCapsA_orig( uDeviceID, pac, cbac);  	}  	MMRESULT WINAPI auxGetDevCapsW( UINT_PTR uDeviceID, LPAUXCAPSW pac, UINT cbac)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"auxGetDevCapsW\n");  		return auxGetDevCapsW_orig( uDeviceID, pac, cbac);  	}  	MMRESULT WINAPI auxSetVolume( UINT uDeviceID, DWORD dwVolume)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"auxSetVolume\n");  		return auxSetVolume_orig( uDeviceID, dwVolume);  	}  	MMRESULT WINAPI auxGetVolume( UINT uDeviceID, LPDWORD pdwVolume)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"auxGetVolume\n");  		return auxGetVolume_orig( uDeviceID, pdwVolume);  	}  	MMRESULT WINAPI auxOutMessage( UINT uDeviceID, UINT uMsg, DWORD_PTR dw1, DWORD_PTR dw2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"auxOutMessage\n");  		return auxOutMessage_orig( uDeviceID, uMsg, dw1, dw2);  	}  	UINT WINAPI mixerGetNumDevs(void)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerGetNumDevs\n");  		return mixerGetNumDevs_orig();  	}  	MMRESULT WINAPI mixerGetDevCapsA( UINT_PTR uMxId, LPMIXERCAPSA pmxcaps, UINT cbmxcaps)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerGetDevCapsA\n");  		return mixerGetDevCapsA_orig( uMxId, pmxcaps, cbmxcaps);  	}  	MMRESULT WINAPI mixerGetDevCapsW( UINT_PTR uMxId, LPMIXERCAPSW pmxcaps, UINT cbmxcaps)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerGetDevCapsW\n");  		return mixerGetDevCapsW_orig( uMxId, pmxcaps, cbmxcaps);  	}  	MMRESULT WINAPI mixerOpen( LPHMIXER phmx, UINT uMxId, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerOpen\n");  		return mixerOpen_orig( phmx, uMxId, dwCallback, dwInstance, fdwOpen);  	}  	MMRESULT WINAPI mixerClose( HMIXER hmx)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerClose\n");  		return mixerClose_orig( hmx);  	}  	DWORD WINAPI mixerMessage( HMIXER hmx, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerMessage\n");  		return mixerMessage_orig( hmx, uMsg, dwParam1, dwParam2);  	}  	MMRESULT WINAPI mixerGetLineInfoA( HMIXEROBJ hmxobj, LPMIXERLINEA pmxl, DWORD fdwInfo)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerGetLineInfoA\n");  		return mixerGetLineInfoA_orig( hmxobj, pmxl, fdwInfo);  	}  	MMRESULT WINAPI mixerGetLineInfoW( HMIXEROBJ hmxobj, LPMIXERLINEW pmxl, DWORD fdwInfo)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerGetLineInfoW\n");  		return mixerGetLineInfoW_orig( hmxobj, pmxl, fdwInfo);  	}  	MMRESULT WINAPI mixerGetID( HMIXEROBJ hmxobj, UINT FAR *puMxId, DWORD fdwId)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerGetID\n");  		return mixerGetID_orig( hmxobj, puMxId, fdwId);  	}  	MMRESULT WINAPI mixerGetLineControlsA( HMIXEROBJ hmxobj, LPMIXERLINECONTROLSA pmxlc, DWORD fdwControls)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerGetLineControlsA\n");  		return mixerGetLineControlsA_orig( hmxobj, pmxlc, fdwControls);  	}  	MMRESULT WINAPI mixerGetLineControlsW( HMIXEROBJ hmxobj, LPMIXERLINECONTROLSW pmxlc, DWORD fdwControls)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerGetLineControlsW\n");  		return mixerGetLineControlsW_orig( hmxobj, pmxlc, fdwControls);  	}  	MMRESULT WINAPI mixerGetControlDetailsA( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerGetControlDetailsA\n");  		return mixerGetControlDetailsA_orig( hmxobj, pmxcd, fdwDetails);  	}  	MMRESULT WINAPI mixerGetControlDetailsW( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerGetControlDetailsW\n");  		return mixerGetControlDetailsW_orig( hmxobj, pmxcd, fdwDetails);  	}  	MMRESULT WINAPI mixerSetControlDetails( HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mixerSetControlDetails\n");  		return mixerSetControlDetails_orig( hmxobj, pmxcd, fdwDetails);  	}  	DWORD    WINAPI mmGetCurrentTask(void)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmGetCurrentTask\n");  		return mmGetCurrentTask_orig();  	}  	void WINAPI mmTaskBlock(DWORD val)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmTaskBlock\n");  		return mmTaskBlock_orig(val);  	}  	UINT WINAPI mmTaskCreate(LPTASKCALLBACK a, HANDLE* b, DWORD_PTR c)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmTaskCreate\n");  		return mmTaskCreate_orig(a, b, c);  	}  	BOOL WINAPI mmTaskSignal(DWORD a)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmTaskSignal\n");  		return mmTaskSignal_orig(a);  	}  	VOID WINAPI mmTaskYield()  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmTaskYield\n");  		mmTaskYield_orig();  	}  	MMRESULT WINAPI timeGetSystemTime( LPMMTIME pmmt, UINT cbmmt)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"timeGetSystemTime\n");  		return timeGetSystemTime_orig( pmmt, cbmmt);  	}  	DWORD WINAPI timeGetTime(void)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"timeGetTime\n");  		return timeGetTime_orig();  	}  	MMRESULT WINAPI timeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD_PTR dwUser, UINT fuEvent)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"timeSetEvent\n");  		return timeSetEvent_orig(uDelay, uResolution, fptc, dwUser, fuEvent);  	}  	MMRESULT WINAPI timeKillEvent( UINT uTimerID)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"timeKillEvent\n");  		return timeKillEvent_orig( uTimerID);  	}  	MMRESULT WINAPI timeGetDevCaps( LPTIMECAPS ptc, UINT cbtc)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"timeGetDevCaps\n");  		return timeGetDevCaps_orig( ptc, cbtc);  	}  	MMRESULT WINAPI timeBeginPeriod( UINT uPeriod)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"timeBeginPeriod\n");  		return timeBeginPeriod_orig( uPeriod);  	}  	MMRESULT WINAPI timeEndPeriod( UINT uPeriod)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"timeEndPeriod\n");  		return timeEndPeriod_orig( uPeriod);  	}  	UINT WINAPI joyGetNumDevs(void)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"joyGetNumDevs\n");  		return joyGetNumDevs_orig();  	}  	MMRESULT WINAPI joyConfigChanged(DWORD dwFlags)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"joyConfigChanged\n");  		return joyConfigChanged_orig(dwFlags);  	}  	MMRESULT WINAPI joyGetDevCapsA( UINT_PTR uJoyID, LPJOYCAPSA pjc, UINT cbjc)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"joyGetDevCapsA\n");  		return joyGetDevCapsA_orig( uJoyID, pjc, cbjc);  	}  	MMRESULT WINAPI joyGetDevCapsW( UINT_PTR uJoyID, LPJOYCAPSW pjc, UINT cbjc)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"joyGetDevCapsW\n");  		return joyGetDevCapsW_orig( uJoyID, pjc, cbjc);  	}  	MMRESULT WINAPI joyGetPos( UINT uJoyID, LPJOYINFO pji)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"joyGetPos\n");  		return joyGetPos_orig( uJoyID, pji);  	}  	MMRESULT WINAPI joyGetPosEx( UINT uJoyID, LPJOYINFOEX pji)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"joyGetPosEx\n");  		return joyGetPosEx_orig( uJoyID, pji);  	}  	MMRESULT WINAPI joyGetThreshold( UINT uJoyID, LPUINT puThreshold)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"joyGetThreshold\n");  		return joyGetThreshold_orig( uJoyID, puThreshold);  	}  	MMRESULT WINAPI joyReleaseCapture( UINT uJoyID)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"joyReleaseCapture\n");  		return joyReleaseCapture_orig( uJoyID);  	}  	MMRESULT WINAPI joySetCapture( HWND hwnd, UINT uJoyID, UINT uPeriod, BOOL fChanged)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"joySetCapture\n");  		return joySetCapture_orig(hwnd, uJoyID, uPeriod, fChanged);  	}  	MMRESULT WINAPI joySetThreshold( UINT uJoyID, UINT uThreshold)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"joySetThreshold\n");  		return joySetThreshold_orig( uJoyID, uThreshold);  	}  	BOOL WINAPI  mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciDriverNotify\n");  		return mciDriverNotify_orig(hwndCallback, uDeviceID, uStatus);  	}  	UINT WINAPI  mciDriverYield(UINT uDeviceID)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciDriverYield\n");  		return mciDriverYield_orig(uDeviceID);  	}	  	FOURCC WINAPI mmioStringToFOURCCA( LPCSTR sz, UINT uFlags)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioStringToFOURCCA\n");  		return mmioStringToFOURCCA_orig( sz, uFlags);  	}  	FOURCC WINAPI mmioStringToFOURCCW( LPCWSTR sz, UINT uFlags)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioStringToFOURCCW\n");  		return mmioStringToFOURCCW_orig( sz, uFlags);  	}  	LPMMIOPROC WINAPI mmioInstallIOProcA( FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioInstallIOProcA\n");  		return mmioInstallIOProcA_orig( fccIOProc, pIOProc, dwFlags);  	}  	LPMMIOPROC WINAPI mmioInstallIOProcW( FOURCC fccIOProc, LPMMIOPROC pIOProc, DWORD dwFlags)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioInstallIOProcW\n");  		return mmioInstallIOProcW_orig( fccIOProc, pIOProc, dwFlags);  	}  	HMMIO WINAPI mmioOpenA( LPSTR pszFileName, LPMMIOINFO pmmioinfo, DWORD fdwOpen)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioOpenA\n");  		return mmioOpenA_orig( pszFileName, pmmioinfo, fdwOpen);  	}  	HMMIO WINAPI mmioOpenW( LPWSTR pszFileName, LPMMIOINFO pmmioinfo, DWORD fdwOpen)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioOpenW\n");  		return mmioOpenW_orig( pszFileName, pmmioinfo, fdwOpen);  	}  	MMRESULT WINAPI mmioRenameA( LPCSTR pszFileName, LPCSTR pszNewFileName, LPCMMIOINFO pmmioinfo, DWORD fdwRename)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioRenameA\n");  		return mmioRenameA_orig( pszFileName, pszNewFileName, pmmioinfo, fdwRename);  	}  	MMRESULT WINAPI mmioRenameW( LPCWSTR pszFileName, LPCWSTR pszNewFileName, LPCMMIOINFO pmmioinfo, DWORD fdwRename)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioRenameW\n");  		return mmioRenameW_orig( pszFileName, pszNewFileName, pmmioinfo, fdwRename);  	}  	MMRESULT WINAPI mmioClose( HMMIO hmmio, UINT fuClose)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioClose\n");  		return mmioClose_orig( hmmio, fuClose);  	}  	LONG WINAPI mmioRead( HMMIO hmmio, HPSTR pch, LONG cch)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioRead\n");  		return mmioRead_orig( hmmio, pch, cch);  	}  	LONG WINAPI mmioWrite( HMMIO hmmio, const char _huge* pch, LONG cch)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioWrite\n");  		return mmioWrite_orig( hmmio, pch, cch);  	}  	LONG WINAPI mmioSeek( HMMIO hmmio, LONG lOffset, int iOrigin)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioSeek\n");  		return mmioSeek_orig(hmmio, lOffset, iOrigin);  	}  	MMRESULT WINAPI mmioGetInfo( HMMIO hmmio, LPMMIOINFO pmmioinfo, UINT fuInfo)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioGetInfo\n");  		return mmioGetInfo_orig( hmmio, pmmioinfo, fuInfo);  	}  	MMRESULT WINAPI mmioSetInfo( HMMIO hmmio, LPCMMIOINFO pmmioinfo, UINT fuInfo)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioSetInfo\n");  		return mmioSetInfo_orig( hmmio, pmmioinfo, fuInfo);  	}  	MMRESULT WINAPI mmioSetBuffer( HMMIO hmmio, LPSTR pchBuffer, LONG cchBuffer, UINT fuBuffer)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioSetBuffer\n");  		return mmioSetBuffer_orig(hmmio, pchBuffer, cchBuffer, fuBuffer);  	}  	MMRESULT WINAPI mmioFlush( HMMIO hmmio, UINT fuFlush)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioFlush\n");  		return mmioFlush_orig( hmmio, fuFlush);  	}  	MMRESULT WINAPI mmioAdvance( HMMIO hmmio, LPMMIOINFO pmmioinfo, UINT fuAdvance)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioAdvance\n");  		return mmioAdvance_orig( hmmio, pmmioinfo, fuAdvance);  	}  	LRESULT WINAPI mmioSendMessage( HMMIO hmmio, UINT uMsg, LPARAM lParam1, LPARAM lParam2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioSendMessage\n");  		return mmioSendMessage_orig(hmmio, uMsg, lParam1, lParam2);  	}  	MMRESULT WINAPI mmioDescend( HMMIO hmmio, LPMMCKINFO pmmcki, const MMCKINFO FAR* pmmckiParent, UINT fuDescend)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioDescend\n");  		return mmioDescend_orig(hmmio, pmmcki, pmmckiParent, fuDescend);  	}  	MMRESULT WINAPI mmioAscend( HMMIO hmmio, LPMMCKINFO pmmcki, UINT fuAscend)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioAscend\n");  		return mmioAscend_orig( hmmio, pmmcki, fuAscend);  	}  	MMRESULT WINAPI mmioCreateChunk(HMMIO hmmio, LPMMCKINFO pmmcki, UINT fuCreate)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mmioCreateChunk\n");  		return mmioCreateChunk_orig(hmmio, pmmcki, fuCreate);  	}  	MCIERROR WINAPI mciSendCommandA( MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciSendCommandA\n");  		return mciSendCommandA_orig( mciId, uMsg, dwParam1, dwParam2);  	}  	MCIERROR WINAPI mciSendCommandW( MCIDEVICEID mciId, UINT uMsg, DWORD_PTR dwParam1, DWORD_PTR dwParam2)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciSendCommandW\n");  		return mciSendCommandW_orig( mciId, uMsg, dwParam1, dwParam2);  	}  	MCIERROR  WINAPI mciSendStringA( LPCSTR lpstrCommand, LPSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciSendStringA\n");  		return mciSendStringA_orig( lpstrCommand, lpstrReturnString, uReturnLength, hwndCallback);  	}  	MCIERROR  WINAPI mciSendStringW( LPCWSTR lpstrCommand, LPWSTR lpstrReturnString, UINT uReturnLength, HWND hwndCallback)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciSendStringW\n");  		return mciSendStringW_orig( lpstrCommand, lpstrReturnString, uReturnLength, hwndCallback);  	} @@ -1375,72 +1535,84 @@ extern "C" {  	MCIDEVICEID WINAPI mciGetDeviceIDW( LPCWSTR pszDevice)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciGetDeviceIDW\n");  		return mciGetDeviceIDW_orig( pszDevice);  	}  	MCIDEVICEID WINAPI mciGetDeviceIDFromElementIDA( DWORD dwElementID, LPCSTR lpstrType )  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciGetDeviceIDFromElementIDA\n");  		return mciGetDeviceIDFromElementIDA_orig( dwElementID, lpstrType );  	}  	MCIDEVICEID WINAPI mciGetDeviceIDFromElementIDW( DWORD dwElementID, LPCWSTR lpstrType )  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciGetDeviceIDFromElementIDW\n");  		return mciGetDeviceIDFromElementIDW_orig( dwElementID, lpstrType );  	}  	DWORD_PTR WINAPI  mciGetDriverData(UINT uDeviceID)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciGetDriverData\n");  		return mciGetDriverData_orig(uDeviceID);  	}  	BOOL WINAPI mciGetErrorStringA( MCIERROR mcierr, LPSTR pszText, UINT cchText)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciGetErrorStringA\n");  		return mciGetErrorStringA_orig( mcierr, pszText, cchText);  	}  	BOOL WINAPI mciGetErrorStringW( MCIERROR mcierr, LPWSTR pszText, UINT cchText)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciGetErrorStringW\n");  		return mciGetErrorStringW_orig( mcierr, pszText, cchText);  	}  	BOOL WINAPI  mciSetDriverData(UINT uDeviceID, DWORD_PTR dwData)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciSetDriverData_type\n");  		return mciSetDriverData_orig( uDeviceID, dwData );  	}  	BOOL WINAPI mciSetYieldProc( MCIDEVICEID mciId, YIELDPROC fpYieldProc, DWORD dwYieldData)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciSetYieldProc\n");  		return mciSetYieldProc_orig(mciId, fpYieldProc, dwYieldData);  	}  	BOOL WINAPI  mciFreeCommandResource(UINT uTable)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciFreeCommandResource\n");  		return mciFreeCommandResource_orig(uTable);  	}  	HTASK WINAPI mciGetCreatorTask( MCIDEVICEID mciId)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciGetCreatorTask\n");  		return mciGetCreatorTask_orig( mciId);  	}  	YIELDPROC WINAPI mciGetYieldProc( MCIDEVICEID mciId, LPDWORD pdwYieldData)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciGetYieldProc\n");  		return mciGetYieldProc_orig( mciId, pdwYieldData);  	}  	UINT WINAPI mciLoadCommandResource(HINSTANCE hInstance, LPCWSTR lpResName, UINT uType)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciLoadCommandResource");  		return mciLoadCommandResource_orig(hInstance, lpResName, uType);  	} @@ -1448,6 +1620,7 @@ extern "C" {  	BOOL WINAPI mciExecute(LPCSTR pszCommand)  	{ +		ll_winmm_shim_initialize();  		//OutputDebugString(L"mciExecute\n");  		return mciExecute_orig(pszCommand);  	} diff --git a/indra/media_plugins/winmmshim/forwarding_api.h b/indra/media_plugins/winmmshim/forwarding_api.h index 89a6b347f3..076a08f769 100644 --- a/indra/media_plugins/winmmshim/forwarding_api.h +++ b/indra/media_plugins/winmmshim/forwarding_api.h @@ -30,6 +30,7 @@  #include <mmsystem.h>  void init_function_pointers(HMODULE winmm_handle); +void ll_winmm_shim_initialize();  typedef VOID (*LPTASKCALLBACK)(DWORD_PTR dwInst); diff --git a/indra/media_plugins/winmmshim/winmm_shim.cpp b/indra/media_plugins/winmmshim/winmm_shim.cpp index 9563a3b664..47a1e5c018 100644 --- a/indra/media_plugins/winmmshim/winmm_shim.cpp +++ b/indra/media_plugins/winmmshim/winmm_shim.cpp @@ -32,14 +32,21 @@ using std::wstring;  static float sVolumeLevel = 1.f;  static bool sMute = false; +static CRITICAL_SECTION sCriticalSection;  BOOL APIENTRY DllMain( HMODULE hModule,                         DWORD  ul_reason_for_call,                         LPVOID lpReserved  					 )  { +	InitializeCriticalSection(&sCriticalSection); +	return TRUE; +} + +void ll_winmm_shim_initialize(){  	static bool initialized = false;  	// do this only once +	EnterCriticalSection(&sCriticalSection);  	if (!initialized)  	{	// bind to original winmm.dll  		TCHAR system_path[MAX_PATH]; @@ -54,13 +61,15 @@ BOOL APIENTRY DllMain( HMODULE hModule,  		{	// we have a dll, let's get out pointers!  			initialized = true;  			init_function_pointers(winmm_handle); -			return true; +			::OutputDebugStringA("WINMM_SHIM.DLL: real winmm.dll initialized successfully\n"); +		} +		else +		{ +			// failed to initialize real winmm.dll +			::OutputDebugStringA("WINMM_SHIM.DLL: Failed to initialize real winmm.dll\n");  		} - -		// failed to initialize real winmm.dll -		return false;  	} -	return true; +	LeaveCriticalSection(&sCriticalSection);  } @@ -79,6 +88,7 @@ extern "C"  	MMRESULT WINAPI waveOutOpen( LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen)  	{ +		ll_winmm_shim_initialize();  		if (pwfx->wFormatTag != WAVE_FORMAT_PCM  			|| (pwfx->wBitsPerSample != 8 && pwfx->wBitsPerSample != 16))  		{ // uncompressed 8 and 16 bit sound are the only types we support @@ -97,6 +107,7 @@ extern "C"  	MMRESULT WINAPI waveOutClose( HWAVEOUT hwo)  	{ +		ll_winmm_shim_initialize();  		wave_out_map_t::iterator found_it = sWaveOuts.find(hwo);  		if (found_it != sWaveOuts.end())  		{	// forget what we know about this handle @@ -108,6 +119,7 @@ extern "C"  	MMRESULT WINAPI waveOutWrite( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh)  	{ +		ll_winmm_shim_initialize();  		MMRESULT result = MMSYSERR_NOERROR;  		if (sMute) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 32b49ed760..4c1b11fbfc 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -652,17 +652,6 @@        <key>Value</key>        <integer>1</integer>      </map> -  <key>AvatarPhysicsTest</key> -  <map> -    <key>Comment</key> -    <string>Simulate continuous physics behavior on all nearby avatars.</string> -    <key>Persist</key> -    <integer>1</integer> -    <key>Type</key> -    <string>Boolean</string> -    <key>Value</key> -    <integer>0</integer> -  </map>      <key>AvatarSex</key>      <map>        <key>Comment</key> @@ -12624,6 +12613,39 @@      <key>Value</key>      <integer>1</integer>    </map> +  <key>EnableInventory</key> +  <map> +    <key>Comment</key> +    <string>Enable opening inventory from web link</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map> +  <key>EnableSearch</key> +  <map> +    <key>Comment</key> +    <string>Enable opening search from web link</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map> +  <key>EnableAppearance</key> +  <map> +    <key>Comment</key> +    <string>Enable opening appearance from web link</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map>      <key>SearchFromAddressBar</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/settings_minimal.xml b/indra/newview/app_settings/settings_minimal.xml index 490da2c9d4..bc97ec00e9 100644 --- a/indra/newview/app_settings/settings_minimal.xml +++ b/indra/newview/app_settings/settings_minimal.xml @@ -303,6 +303,39 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>EnableInventory</key> +    <map> +      <key>Comment</key> +      <string>Enable opening inventory from web link</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>EnableSearch</key> +    <map> +      <key>Comment</key> +      <string>Enable opening search from web link</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map> +    <key>EnableAppearance</key> +    <map> +      <key>Comment</key> +      <string>Enable opening appearance from web link</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>DoubleClickShowWorldMap</key>      <map>        <key>Comment</key> diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index ec162e3608..ce15c4b8f7 100644 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -4352,8 +4352,8 @@       wearable="shape"       edit_group="driven"       value_default="0" -     value_min="-1.5" -     value_max="1.5"> +     value_min="-1.25" +     value_max="1.25">        <param_morph />      </param> @@ -11875,7 +11875,7 @@ render_pass="bump">       edit_group="physics_advanced"       value_default="0"       value_min="0" -     value_max=".1"> +     value_max="30">  	 <param_driver />      </param> @@ -11887,9 +11887,9 @@ render_pass="bump">       label="Breast Physics Drag"       wearable="physics"       edit_group="physics_advanced" -     value_default=".15" +     value_default="1"       value_min="0" -     value_max=".5"> +     value_max="10">  	 <param_driver />      </param> @@ -11914,9 +11914,9 @@ render_pass="bump">       label="Breast Physics UpDown Spring"       wearable="physics"       edit_group="physics_breasts_updown" -     value_default=".1" +     value_default="10"       value_min="0" -     value_max="3"> +     value_max="100">  	 <param_driver />      </param>      <param @@ -11940,11 +11940,9 @@ render_pass="bump">       label="Breast Physics UpDown Damping"       wearable="physics"       edit_group="physics_breasts_updown" -     value_default=".05" +     value_default=".2"       value_min="0" -     value_max=".1" -     camera_elevation=".3" -     camera_distance=".8"> +     value_max="1">  	 <param_driver />      </param> @@ -11969,9 +11967,9 @@ render_pass="bump">       label="Breast Physics InOut Spring"       wearable="physics"       edit_group="physics_breasts_inout" -     value_default=".1" +     value_default="10"       value_min="0" -     value_max="3"> +     value_max="100">  	 <param_driver />      </param>      <param @@ -11995,9 +11993,9 @@ render_pass="bump">       label="Breast Physics InOut Damping"       wearable="physics"       edit_group="physics_breasts_inout" -     value_default=".05" +     value_default=".2"       value_min="0" -     value_max=".1"> +     value_max="1">  	 <param_driver />      </param> @@ -12022,7 +12020,7 @@ render_pass="bump">       edit_group="physics_advanced"       value_default="0"       value_min="0" -     value_max=".1"> +     value_max="30">  	 <param_driver />      </param>     <param @@ -12032,9 +12030,9 @@ render_pass="bump">       label="Belly Physics Drag"       wearable="physics"       edit_group="physics_advanced" -     value_default=".15" +     value_default="1"       value_min="0" -     value_max=".5"> +     value_max="10">  	 <param_driver />      </param>     <param @@ -12056,9 +12054,9 @@ render_pass="bump">       label="Belly Physics UpDown Spring"       wearable="physics"       edit_group="physics_belly_updown" -     value_default=".1" +     value_default="10"       value_min="0" -     value_max="3"> +     value_max="100">  	 <param_driver />      </param>      <param @@ -12080,9 +12078,9 @@ render_pass="bump">       label="Belly Physics UpDown Damping"       wearable="physics"       edit_group="physics_belly_updown" -     value_default=".05" +     value_default=".2"       value_min="0" -     value_max=".1"> +     value_max="1">  	 <param_driver />      </param> @@ -12107,7 +12105,7 @@ render_pass="bump">       edit_group="physics_advanced"       value_default="0"       value_min="0" -     value_max=".1"> +     value_max="30">  	 <param_driver />      </param>     <param @@ -12117,9 +12115,9 @@ render_pass="bump">       label="Butt Physics Drag"       wearable="physics"       edit_group="physics_advanced" -     value_default=".15" +     value_default="1"       value_min="0" -     value_max=".5"> +     value_max="10">  	 <param_driver />      </param> @@ -12142,9 +12140,9 @@ render_pass="bump">       label="Butt Physics UpDown Spring"       wearable="physics"       edit_group="physics_butt_updown" -     value_default=".1" +     value_default="10"       value_min="0" -     value_max="3"> +     value_max="100">  	 <param_driver />      </param>      <param @@ -12166,9 +12164,9 @@ render_pass="bump">       label="Butt Physics UpDown Damping"       wearable="physics"       edit_group="physics_butt_updown" -     value_default=".05" +     value_default=".2"       value_min="0" -     value_max=".1"> +     value_max="1">  	 <param_driver />      </param> @@ -12191,9 +12189,9 @@ render_pass="bump">       label="Butt Physics LeftRight Spring"       wearable="physics"       edit_group="physics_butt_leftright" -     value_default=".1" +     value_default="10"       value_min="0" -     value_max="3"> +     value_max="100">  	 <param_driver />      </param>      <param @@ -12215,9 +12213,9 @@ render_pass="bump">       label="Butt Physics LeftRight Damping"       wearable="physics"       edit_group="physics_butt_leftright" -     value_default=".05" +     value_default=".2"       value_min="0" -     value_max=".1"> +     value_max="1">  	 <param_driver />      </param> @@ -12242,9 +12240,9 @@ render_pass="bump">       label="Breast Physics LeftRight Spring"       wearable="physics"       edit_group="physics_breasts_leftright" -     value_default=".1" +     value_default="10"       value_min="0" -     value_max="3"> +     value_max="100">  	 <param_driver />      </param>      <param @@ -12268,9 +12266,9 @@ render_pass="bump">       label="Breast Physics LeftRight Damping"       wearable="physics"       edit_group="physics_breasts_leftright" -     value_default=".05" +     value_default=".2"       value_min="0" -     value_max=".1"> +     value_max="1">  	 <param_driver />      </param> diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 15ad330418..af2d951bf7 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -132,7 +132,7 @@ list High  RenderAnisotropic			1	1  RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	1.0 -RenderAvatarPhysicsLODFactor 1	0.9 +RenderAvatarPhysicsLODFactor 1	1.0  RenderAvatarVP				1	1  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index a2cd4b834c..5da1495da9 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -26,6 +26,7 @@ list all  RenderAnisotropic			1	1  RenderAvatarCloth			1	1  RenderAvatarLODFactor		1	1.0 +RenderAvatarPhysicsLODFactor 1	1.0  RenderAvatarMaxVisible      1   12  RenderAvatarVP				1	1  RenderCubeMap				1	1 @@ -70,6 +71,7 @@ list Low  RenderAnisotropic			1	0  RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	0 +RenderAvatarPhysicsLODFactor 1	0  RenderAvatarMaxVisible      1   3  RenderAvatarVP				1	0  RenderFarClip				1	64 @@ -100,6 +102,7 @@ list Mid  RenderAnisotropic			1	0  RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	0.5 +RenderAvatarPhysicsLODFactor 1	0.75  RenderAvatarVP				1	1  RenderFarClip				1	96  RenderFlexTimeFactor		1	1.0 @@ -128,6 +131,7 @@ list High  RenderAnisotropic			1	1  RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	1.0 +RenderAvatarPhysicsLODFactor 1	1.0  RenderAvatarVP				1	1  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0 @@ -156,6 +160,7 @@ list Ultra  RenderAnisotropic			1	1  RenderAvatarCloth			1	1  RenderAvatarLODFactor		1	1.0 +RenderAvatarPhysicsLODFactor 1	1.0  RenderAvatarVP				1	1  RenderFarClip				1	256  RenderFlexTimeFactor		1	1.0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 3ad7f4e892..421f9c0973 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -26,6 +26,7 @@ list all  RenderAnisotropic				1	0  RenderAvatarCloth				0	0  RenderAvatarLODFactor			1	1.0 +RenderAvatarPhysicsLODFactor 1	1.0  RenderAvatarMaxVisible          1   12  RenderAvatarVP					1	0  RenderCubeMap					1	1 @@ -70,6 +71,7 @@ list Low  RenderAnisotropic			1	0  RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	0 +RenderAvatarPhysicsLODFactor 1	0  RenderAvatarMaxVisible      1   3  RenderAvatarVP				1	0  RenderFarClip				1	64 @@ -99,6 +101,7 @@ list Mid  RenderAnisotropic			1	0  RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	0.5 +RenderAvatarPhysicsLODFactor 1	0.75  RenderAvatarVP				1	1  RenderFarClip				1	96  RenderFlexTimeFactor		1	1.0 @@ -126,6 +129,7 @@ list High  RenderAnisotropic			1	1  RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	1.0 +RenderAvatarPhysicsLODFactor 1	1.0  RenderAvatarVP				1	1  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0 @@ -153,6 +157,7 @@ list Ultra  RenderAnisotropic			1	1  RenderAvatarCloth			1	1  RenderAvatarLODFactor		1	1.0 +RenderAvatarPhysicsLODFactor 1	1.0  RenderAvatarVP				1	1  RenderFarClip				1	256  RenderFlexTimeFactor		1	1.0 diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index 38e6bb1e5e..c2e5dfff9f 100644 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -26,6 +26,7 @@ list all  RenderAnisotropic			1	1  RenderAvatarCloth			1	1  RenderAvatarLODFactor		1	1.0 +RenderAvatarPhysicsLODFactor 1	1.0  RenderAvatarMaxVisible      1   12  RenderAvatarVP				1	1  RenderCubeMap				1	1 @@ -71,6 +72,7 @@ list Low  RenderAnisotropic			1	0  RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	0 +RenderAvatarPhysicsLODFactor 1	0  RenderAvatarMaxVisible      1   3  RenderAvatarVP				1	0  RenderFarClip				1	64 @@ -101,6 +103,7 @@ list Mid  RenderAnisotropic			1	0  RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	0.5 +RenderAvatarPhysicsLODFactor 1	0.75  RenderAvatarVP				1	1  RenderFarClip				1	96  RenderFlexTimeFactor		1	1.0 @@ -129,6 +132,7 @@ list High  RenderAnisotropic			1	1  RenderAvatarCloth			1	0  RenderAvatarLODFactor		1	1.0 +RenderAvatarPhysicsLODFactor 1	1.0  RenderAvatarVP				1	1  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0 @@ -157,6 +161,7 @@ list Ultra  RenderAnisotropic			1	1  RenderAvatarCloth			1	1  RenderAvatarLODFactor		1	1.0 +RenderAvatarPhysicsLODFactor 1	1.0  RenderAvatarVP				1	1  RenderFarClip				1	256  RenderFlexTimeFactor		1	1.0 diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 1cf552e42c..f9e850899a 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -110,6 +110,12 @@ public:  	{  		// support secondlife:///app/appearance/show, but for now we just  		// make all secondlife:///app/appearance SLapps behave this way +		if (!LLUI::sSettingGroups["config"]->getBOOL("EnableAppearance")) +		{ +			LLNotificationsUtil::add("NoAppearance", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); +			return true; +		} +  		LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD());  		return true;  	} diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 5e5c0f71db..747ea552b2 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3532,10 +3532,10 @@ bool LLAppViewer::initCache()  	LLAppViewer::getTextureCache()->setReadOnly(read_only) ;  	LLVOCache::getInstance()->setReadOnly(read_only); -	BOOL texture_cache_mismatch = FALSE ; +	bool texture_cache_mismatch = false;  	if (gSavedSettings.getS32("LocalCacheVersion") != LLAppViewer::getTextureCacheVersion())   	{ -		texture_cache_mismatch = TRUE ; +		texture_cache_mismatch = true;  		if(!read_only)   		{  			gSavedSettings.setS32("LocalCacheVersion", LLAppViewer::getTextureCacheVersion()); @@ -3549,7 +3549,9 @@ bool LLAppViewer::initCache()  			gSavedSettings.getBOOL("PurgeCacheOnNextStartup"))  		{  			gSavedSettings.setBOOL("PurgeCacheOnNextStartup", false); -		mPurgeCache = true; +			mPurgeCache = true; +			// STORM-1141 force purgeAllTextures to get called to prevent a crash here. -brad +			texture_cache_mismatch = true;  		}  		// We have moved the location of the cache directory over time. diff --git a/indra/newview/lldateutil.cpp b/indra/newview/lldateutil.cpp index fcc73a07bc..18ae6107e7 100644 --- a/indra/newview/lldateutil.cpp +++ b/indra/newview/lldateutil.cpp @@ -32,9 +32,9 @@  #include "llui.h"  static S32 DAYS_PER_MONTH_NOLEAP[] = -	{ 31, 28, 21, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };  static S32 DAYS_PER_MONTH_LEAP[] = -	{ 31, 29, 21, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; +	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };  static S32 days_from_month(S32 year, S32 month)  { diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index c7fbdd5745..d76e7885bc 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -325,122 +325,51 @@ void LLFloaterImagePreview::draw()  bool LLFloaterImagePreview::loadImage(const std::string& src_filename)  {  	std::string exten = gDirUtilp->getExtension(src_filename); -	 -	U32 codec = IMG_CODEC_INVALID; -	std::string temp_str; -	if( exten == "bmp") -	{ -		codec = IMG_CODEC_BMP; -	} -	else if( exten == "tga") -	{ -		codec = IMG_CODEC_TGA; -	} -	else if( exten == "jpg" || exten == "jpeg") -	{ -		codec = IMG_CODEC_JPEG; -	} -	else if( exten == "png" ) -	{ -		codec = IMG_CODEC_PNG; -	} +	U32 codec = LLImageBase::getCodecFromExtension(exten);  	LLImageDimensionsInfo image_info; -	if(!image_info.load(src_filename,codec)) +	if (!image_info.load(src_filename,codec))  	{  		mImageLoadError = image_info.getLastError();  		return false;  	}  	S32 max_width = gSavedSettings.getS32("max_texture_dimension_X"); -	S32 max_heigh = gSavedSettings.getS32("max_texture_dimension_Y"); +	S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y"); -	if(image_info.getWidth() > max_width|| image_info.getHeight() > max_heigh) +	if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))  	{  		LLStringUtil::format_map_t args;  		args["WIDTH"] = llformat("%d", max_width); -		args["HEIGHT"] = llformat("%d", max_heigh); +		args["HEIGHT"] = llformat("%d", max_height);  		mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args);  		return false;  	} - +	// Load the image +	LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec); +	if (image.isNull()) +	{ +		return false; +	} +	if (!image->load(src_filename)) +	{ +		return false; +	} +	// Decompress or expand it in a raw image structure  	LLPointer<LLImageRaw> raw_image = new LLImageRaw; - -	switch (codec) +	if (!image->decode(raw_image, 0.0f))  	{ -	case IMG_CODEC_BMP: -		{ -			LLPointer<LLImageBMP> bmp_image = new LLImageBMP; - -			if (!bmp_image->load(src_filename)) -			{ -				return false; -			} -			 -			if (!bmp_image->decode(raw_image, 0.0f)) -			{ -				return false; -			} -		} -		break; -	case IMG_CODEC_TGA: -		{ -			LLPointer<LLImageTGA> tga_image = new LLImageTGA; - -			if (!tga_image->load(src_filename)) -			{ -				return false; -			} -			 -			if (!tga_image->decode(raw_image)) -			{ -				return false; -			} - -			if(	(tga_image->getComponents() != 3) && -				(tga_image->getComponents() != 4) ) -			{ -				tga_image->setLastError( "Image files with less than 3 or more than 4 components are not supported." ); -				return false; -			} -		} -		break; -	case IMG_CODEC_JPEG: -		{ -			LLPointer<LLImageJPEG> jpeg_image = new LLImageJPEG; - -			if (!jpeg_image->load(src_filename)) -			{ -				return false; -			} -			 -			if (!jpeg_image->decode(raw_image, 0.0f)) -			{ -				return false; -			} -		} -		break; -	case IMG_CODEC_PNG: -		{ -			LLPointer<LLImagePNG> png_image = new LLImagePNG; - -			if (!png_image->load(src_filename)) -			{ -				return false; -			} -			 -			if (!png_image->decode(raw_image, 0.0f)) -			{ -				return false; -			} -		} -		break; -	default:  		return false;  	} - +	// Check the image constraints +	if ((image->getComponents() != 3) && (image->getComponents() != 4)) +	{ +		image->setLastError("Image files with less than 3 or more than 4 components are not supported."); +		return false; +	} +	  	raw_image->biasedScaleToPowerOfTwo(1024);  	mRawImagep = raw_image; diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 1a9d0af9af..c7fce83b03 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -43,6 +43,7 @@  #include "llcombobox.h"  #include "llcommandhandler.h"  #include "lldirpicker.h" +#include "lleventtimer.h"  #include "llfeaturemanager.h"  #include "llfocusmgr.h"  //#include "llfirstuse.h" @@ -73,6 +74,7 @@  #include "llviewerwindow.h"  #include "llviewermessage.h"  #include "llviewershadermgr.h" +#include "llviewerthrottle.h"  #include "llvotree.h"  #include "llvosky.h" @@ -109,6 +111,7 @@  const F32 MAX_USER_FAR_CLIP = 512.f;  const F32 MIN_USER_FAR_CLIP = 64.f; +const F32 BANDWIDTH_UPDATER_TIMEOUT = 0.5f;  //control value for middle mouse as talk2push button  const static std::string MIDDLE_MOUSE_CV = "MiddleMouse"; @@ -286,8 +289,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)  	mOriginalIMViaEmail(false),  	mLanguageChanged(false),  	mAvatarDataInitialized(false), -	mDoubleClickActionDirty(false), -	mFavoritesRecordMayExist(false) +	mDoubleClickActionDirty(false)  {  	//Build Floater is now Called from 	LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>); @@ -412,6 +414,8 @@ BOOL LLFloaterPreference::postBuild()  	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2)); +	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged)); +  	gSavedSettings.getControl("ChatBubbleOpacity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onNameTagOpacityChange, this, _2));  	LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core"); @@ -565,34 +569,6 @@ void LLFloaterPreference::apply()  		updateDoubleClickSettings();  		mDoubleClickActionDirty = false;  	} - -	if (mFavoritesRecordMayExist && !gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin")) -	{ -		removeFavoritesRecordOfUser();		 -	} -} - -void LLFloaterPreference::removeFavoritesRecordOfUser() -{ -	mFavoritesRecordMayExist = false; -	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); -	LLSD fav_llsd; -	llifstream file; -	file.open(filename); -	if (!file.is_open()) return; -	LLSDSerialize::fromXML(fav_llsd, file); -	 -	LLAvatarName av_name; -	LLAvatarNameCache::get( gAgentID, &av_name ); -	if (fav_llsd.has(av_name.getLegacyName())) -	{ -		fav_llsd.erase(av_name.getLegacyName()); -	} -	 -	llofstream out_file; -	out_file.open(filename); -	LLSDSerialize::toPrettyXML(fav_llsd, out_file); -  }  void LLFloaterPreference::cancel() @@ -678,11 +654,6 @@ void LLFloaterPreference::onOpen(const LLSD& key)  		getChildView("maturity_desired_combobox")->setVisible( false);  	} -	if (LLStartUp::getStartupState() == STATE_STARTED) -	{ -		mFavoritesRecordMayExist = gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"); -	} -  	// Forget previous language changes.  	mLanguageChanged = false; @@ -1558,10 +1529,56 @@ void LLFloaterPreference::setCacheLocation(const LLStringExplicit& location)  	cache_location_editor->setToolTip(location);  } +//------------------------------Updater--------------------------------------- + +static bool handleBandwidthChanged(const LLSD& newvalue) +{ +	gViewerThrottle.setMaxBandwidth((F32) newvalue.asReal()); +	return true; +} + +class LLPanelPreference::Updater : public LLEventTimer +{ + +public: + +	typedef boost::function<bool(const LLSD&)> callback_t; + +	Updater(callback_t cb, F32 period) +	:LLEventTimer(period), +	 mCallback(cb) +	{ +		mEventTimer.stop(); +	} + +	virtual ~Updater(){} + +	void update(const LLSD& new_value) +	{ +		mNewValue = new_value; +		mEventTimer.start(); +	} + +protected: + +	BOOL tick() +	{ +		mCallback(mNewValue); +		mEventTimer.stop(); + +		return FALSE; +	} + +private: + +	LLSD mNewValue; +	callback_t mCallback; +};  //----------------------------------------------------------------------------  static LLRegisterPanelClassWrapper<LLPanelPreference> t_places("panel_preference");  LLPanelPreference::LLPanelPreference() -: LLPanel() +: LLPanel(), +  mBandWidthUpdater(NULL)  {  	mCommitCallbackRegistrar.add("Pref.setControlFalse",	boost::bind(&LLPanelPreference::setControlFalse,this, _2));  	mCommitCallbackRegistrar.add("Pref.updateMediaAutoPlayCheckbox",	boost::bind(&LLPanelPreference::updateMediaAutoPlayCheckbox, this, _1)); @@ -1631,10 +1648,24 @@ BOOL LLPanelPreference::postBuild()  		}  	} +	//////////////////////PanelSetup /////////////////// +	if (hasChild("max_bandwidth")) +	{ +		mBandWidthUpdater = new LLPanelPreference::Updater(boost::bind(&handleBandwidthChanged, _1), BANDWIDTH_UPDATER_TIMEOUT); +		gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&LLPanelPreference::Updater::update, mBandWidthUpdater, _2)); +	} +  	apply();  	return true;  } +LLPanelPreference::~LLPanelPreference() +{ +	if (mBandWidthUpdater) +	{ +		delete mBandWidthUpdater; +	} +}  void LLPanelPreference::apply()  {  	// no-op diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 5d5e066ec5..5fe509fb37 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -159,8 +159,6 @@ public:  	void buildPopupLists();  	static void refreshSkin(void* data); -	// Remove record of current user's favorites from file on disk. -	void removeFavoritesRecordOfUser();  private:  	static std::string sSkin;  	// set true if state of double-click action checkbox or radio-group was changed by user @@ -172,8 +170,6 @@ private:  	bool mAvatarDataInitialized;  	bool mOriginalHideOnlineStatus; -	// Record of current user's favorites may be stored in file on disk. -	bool mFavoritesRecordMayExist;  	std::string mDirectoryVisibility;  	LLAvatarData mAvatarProperties; @@ -185,6 +181,8 @@ public:  	LLPanelPreference();  	/*virtual*/ BOOL postBuild(); +	virtual ~LLPanelPreference(); +  	virtual void apply();  	virtual void cancel();  	void setControlFalse(const LLSD& user_data); @@ -198,6 +196,7 @@ public:  	// cancel() can restore them.  	virtual void saveSettings(); +	class Updater;  private:  	//for "Only friends and groups can call or IM me"  	static void showFriendsOnlyWarning(LLUICtrl*, const LLSD&); @@ -209,6 +208,8 @@ private:  	typedef std::map<std::string, LLColor4> string_color_map_t;  	string_color_map_t mSavedColors; + +	Updater* mBandWidthUpdater;  };  class LLPanelPreferenceGraphics : public LLPanelPreference diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp index 2041fac8d8..d5806e375c 100644 --- a/indra/newview/llfloatersearch.cpp +++ b/indra/newview/llfloatersearch.cpp @@ -31,6 +31,7 @@  #include "llfloaterreg.h"  #include "llfloatersearch.h"  #include "llmediactrl.h" +#include "llnotificationsutil.h"  #include "lllogininstance.h"  #include "lluri.h"  #include "llagent.h" @@ -46,6 +47,12 @@ public:  	LLSearchHandler() : LLCommandHandler("search", UNTRUSTED_THROTTLE) { }  	bool handle(const LLSD& tokens, const LLSD& query_map, LLMediaCtrl* web)  	{ +		if (!LLUI::sSettingGroups["config"]->getBOOL("EnableSearch")) +		{ +			LLNotificationsUtil::add("NoSearch", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); +			return true; +		} +  		const size_t parts = tokens.size();  		// get the (optional) category for the search diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index e22363c2f6..dee15a1efd 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -510,9 +510,15 @@ void LLInventoryFilter::setHoursAgo(U32 hours)  {  	if (mFilterOps.mHoursAgo != hours)  	{ +		bool are_date_limits_valid = mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max(); + +		bool is_increasing = hours > mFilterOps.mHoursAgo; +		bool is_increasing_from_zero = is_increasing && !mFilterOps.mHoursAgo; +  		// *NOTE: need to cache last filter time, in case filter goes stale -		BOOL less_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours > mFilterOps.mHoursAgo); -		BOOL more_restrictive = (mFilterOps.mMinDate == time_min() && mFilterOps.mMaxDate == time_max() && hours <= mFilterOps.mHoursAgo); +		BOOL less_restrictive = (are_date_limits_valid && ((is_increasing && mFilterOps.mHoursAgo)) || !hours); +		BOOL more_restrictive = (are_date_limits_valid && (!is_increasing && hours) || is_increasing_from_zero); +  		mFilterOps.mHoursAgo = hours;  		mFilterOps.mMinDate = time_min();  		mFilterOps.mMaxDate = time_max(); diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index abcd8588dc..36c5d12897 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -558,6 +558,18 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia  	requested_options.append("buddy-list");  	requested_options.append("newuser-config");  	requested_options.append("ui-config"); + +	//send this info to login.cgi for stats gathering  +	//since viewerstats isn't reliable enough +	if (gSavedSettings.getString("SessionSettingsFile").empty()) +	{ +		requested_options.append("advanced-mode"); +	} +	else +	{ +		requested_options.append("basic-mode"); +	} +  #endif  	requested_options.append("max-agent-groups");	  	requested_options.append("map-server-url");	 diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index 572eeb8fc7..03ebc344f1 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -250,9 +250,13 @@ void LLNearbyChat::getAllowedRect(LLRect& rect)  void LLNearbyChat::updateChatHistoryStyle()  {  	mChatHistory->clear(); + +	LLSD do_not_log; +	do_not_log["do_not_log"] = true;  	for(std::vector<LLChat>::iterator it = mMessageArchive.begin();it!=mMessageArchive.end();++it)  	{ -		addMessage(*it,false); +		// Update the messages without re-writing them to a log file. +		addMessage(*it,false, do_not_log);  	}  } diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp index cf828306d8..4b961db5f9 100644 --- a/indra/newview/llnearbychatbar.cpp +++ b/indra/newview/llnearbychatbar.cpp @@ -47,6 +47,7 @@  #include "llwindow.h"  #include "llviewerwindow.h"  #include "llrootview.h" +#include "llviewerchat.h"  S32 LLNearbyChatBar::sLastSpecialChatChannel = 0; @@ -433,13 +434,26 @@ BOOL LLNearbyChatBar::postBuild()  	mChatBox->setPassDelete(TRUE);  	mChatBox->setReplaceNewlinesWithSpaces(FALSE);  	mChatBox->setEnableLineHistory(TRUE); +	mChatBox->setFont(LLViewerChat::getChatFont());  	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");  	mOutputMonitor->setVisible(FALSE); +	// Register for font change notifications +	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatBar::onChatFontChange, this, _1)); +  	return TRUE;  } +void LLNearbyChatBar::onChatFontChange(LLFontGL* fontp) +{ +	// Update things with the new font whohoo +	if (mChatBox) +	{ +		mChatBox->setFont(fontp); +	} +} +  //static  LLNearbyChatBar* LLNearbyChatBar::getInstance()  { diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h index 96ab45071b..efddec942f 100644 --- a/indra/newview/llnearbychatbar.h +++ b/indra/newview/llnearbychatbar.h @@ -127,6 +127,7 @@ protected:  	void sendChat( EChatType type );  	void onChatBoxCommit(); +	void onChatFontChange(LLFontGL* fontp);  	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);  	EChatType processChatTypeTriggers(EChatType type, std::string &str); diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index cb8fbd66b5..b73d97e4c4 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -1133,7 +1133,7 @@ void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show, BOOL dis                          LLScrollingPanelList *panel_list = getChild<LLScrollingPanelList>(scrolling_panel);                          LLAccordionCtrlTab *tab = getChild<LLAccordionCtrlTab>(accordion_tab); -         +			                          if (!panel_list)                          {                                  llwarns << "could not get scrolling panel list: " << scrolling_panel << llendl; @@ -1145,7 +1145,18 @@ void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show, BOOL dis                                  llwarns << "could not get llaccordionctrltab from UI with name: " << accordion_tab << llendl;                                  continue;                          } -         + +			// Don't show female subparts if you're not female, etc. +			if (!(gAgentAvatarp->getSex() & subpart_entry->mSex)) +			{ +				tab->setVisible(FALSE); +				continue; +			} +			else +			{ +				tab->setVisible(TRUE); +			} +			                          // what edit group do we want to extract params for?                          const std::string edit_group = subpart_entry->mEditGroup; diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp index 7820ac3ecd..979d96ca0d 100644 --- a/indra/newview/llpanellogin.cpp +++ b/indra/newview/llpanellogin.cpp @@ -81,6 +81,9 @@ const S32 MAX_PASSWORD = 16;  LLPanelLogin *LLPanelLogin::sInstance = NULL;  BOOL LLPanelLogin::sCapslockDidNotification = FALSE; +// Helper for converting a user name into the canonical "Firstname Lastname" form. +// For new accounts without a last name "Resident" is added as a last name. +static std::string canonicalize_username(const std::string& name);  class LLLoginRefreshHandler : public LLCommandHandler  { @@ -302,7 +305,14 @@ void LLPanelLogin::addFavoritesToStartLocation()  	for (LLSD::map_const_iterator iter = fav_llsd.beginMap();  		iter != fav_llsd.endMap(); ++iter)  	{ -		if(iter->first != getChild<LLComboBox>("username_combo")->getSimple()) continue; +		std::string user_defined_name = getChild<LLComboBox>("username_combo")->getSimple(); + +		// The account name in stored_favorites.xml has Resident last name even if user has +		// a single word account name, so it can be compared case-insensitive with the +		// user defined "firstname lastname". +		S32 res = LLStringUtil::compareInsensitive(canonicalize_username(user_defined_name), iter->first); +		if (res != 0) continue; +  		combo->addSeparator();  		LLSD user_llsd = iter->second;  		for (LLSD::array_const_iterator iter1 = user_llsd.beginArray(); @@ -1186,3 +1196,28 @@ void LLPanelLogin::onModeChangeConfirm(const LLSD& original_value, const LLSD& n  		break;  	}  } + +std::string canonicalize_username(const std::string& name) +{ +	std::string cname = name; +	LLStringUtil::trim(cname); + +	// determine if the username is a first/last form or not. +	size_t separator_index = cname.find_first_of(" ._"); +	std::string first = cname.substr(0, separator_index); +	std::string last; +	if (separator_index != cname.npos) +	{ +		last = cname.substr(separator_index+1, cname.npos); +		LLStringUtil::trim(last); +	} +	else +	{ +		// ...on Linden grids, single username users as considered to have +		// last name "Resident" +		last = "Resident"; +	} + +	// Username in traditional "firstname lastname" form. +	return first + ' ' + last; +} diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 0c3f2f3e31..90617b7dc7 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -81,7 +81,6 @@ public:  	BOOL getCheckSinceLogoff();  	static void onTimeAgo(LLUICtrl*, void *); -	static void onCheckSinceLogoff(LLUICtrl*, void *);  	static void onCloseBtn(void* user_data);  	static void selectAllTypes(void* user_data);  	static void selectNoTypes(void* user_data); @@ -619,20 +618,6 @@ LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* invento  	updateElementsFromFilter();  } - -void LLFloaterInventoryFinder::onCheckSinceLogoff(LLUICtrl *ctrl, void *user_data) -{ -	LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data; -	if (!self) return; - -	bool since_logoff= self->getChild<LLUICtrl>("check_since_logoff")->getValue(); -	 -	if (!since_logoff &&  -	    !(  self->mSpinSinceDays->get() ||  self->mSpinSinceHours->get() ) ) -	{ -		self->mSpinSinceHours->set(1.0f); -	}	 -}  BOOL LLFloaterInventoryFinder::postBuild()  {  	const LLRect& viewrect = mPanelMainInventory->getRect(); @@ -647,9 +632,6 @@ BOOL LLFloaterInventoryFinder::postBuild()  	mSpinSinceDays = getChild<LLSpinCtrl>("spin_days_ago");  	childSetCommitCallback("spin_days_ago", onTimeAgo, this); -	//	mCheckSinceLogoff   = getChild<LLSpinCtrl>("check_since_logoff"); -	childSetCommitCallback("check_since_logoff", onCheckSinceLogoff, this); -  	childSetAction("Close", onCloseBtn, this);  	updateElementsFromFilter(); @@ -660,12 +642,10 @@ void LLFloaterInventoryFinder::onTimeAgo(LLUICtrl *ctrl, void *user_data)  	LLFloaterInventoryFinder *self = (LLFloaterInventoryFinder *)user_data;  	if (!self) return; -	bool since_logoff=true;  	if ( self->mSpinSinceDays->get() ||  self->mSpinSinceHours->get() )  	{ -		since_logoff = false; +		self->getChild<LLUICtrl>("check_since_logoff")->setValue(false);  	} -	self->getChild<LLUICtrl>("check_since_logoff")->setValue(since_logoff);  }  void LLFloaterInventoryFinder::changeFilter(LLInventoryFilter* filter) diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp index 23fa0cbd9c..30a04109bc 100644 --- a/indra/newview/llphysicsmotion.cpp +++ b/indra/newview/llphysicsmotion.cpp @@ -43,7 +43,8 @@  typedef std::map<std::string, std::string> controller_map_t;  typedef std::map<std::string, F32> default_controller_map_t; -#define MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION 0.f; +#define MIN_REQUIRED_PIXEL_AREA_AVATAR_PHYSICS_MOTION 0.f +#define TIME_ITERATION_STEP 0.1f  inline F64 llsgn(const F64 a)  { @@ -122,12 +123,11 @@ protected:          }          void setParamValue(LLViewerVisualParam *param,                             const F32 new_value_local, -						   F32 behavior_maxeffect); +                                                   F32 behavior_maxeffect);          F32 toLocal(const LLVector3 &world); -        F32 calculateVelocity_local(const F32 time_delta); -        F32 calculateAcceleration_local(F32 velocity_local, -                                        const F32 time_delta); +        F32 calculateVelocity_local(); +        F32 calculateAcceleration_local(F32 velocity_local);  private:          const std::string mParamDriverName;          const std::string mParamControllerName; @@ -364,7 +364,7 @@ void LLPhysicsMotionController::addMotion(LLPhysicsMotion *motion)  F32 LLPhysicsMotionController::getMinPixelArea()   { -        return MIN_REQUIRED_PIXEL_AREA_BREAST_MOTION; +        return MIN_REQUIRED_PIXEL_AREA_AVATAR_PHYSICS_MOTION;  }  // Local space means "parameter space". @@ -378,19 +378,20 @@ F32 LLPhysicsMotion::toLocal(const LLVector3 &world)          return world * dir_world;  } -F32 LLPhysicsMotion::calculateVelocity_local(const F32 time_delta) +F32 LLPhysicsMotion::calculateVelocity_local()  { +	const F32 world_to_model_scale = 100.0f;          LLJoint *joint = mJointState->getJoint();          const LLVector3 position_world = joint->getWorldPosition();          const LLQuaternion rotation_world = joint->getWorldRotation();          const LLVector3 last_position_world = mPosition_world; -        const LLVector3 velocity_world = (position_world-last_position_world) / time_delta; +	const LLVector3 positionchange_world = (position_world-last_position_world) * world_to_model_scale; +        const LLVector3 velocity_world = positionchange_world;          const F32 velocity_local = toLocal(velocity_world);          return velocity_local;  } -F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local, -                                                 const F32 time_delta) +F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local)  {  //        const F32 smoothing = getParamValue("Smoothing");          static const F32 smoothing = 3.0f; // Removed smoothing param since it's probably not necessary @@ -446,7 +447,15 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)          //          const F32 time_delta = time - mLastTime; -        if (time_delta > 3.0 || time_delta <= 0.01) + +	// Don't update too frequently, to avoid precision errors from small time slices. +	if (time_delta <= .01) +	{ +		return FALSE; +	} +	 +	// If less than 1FPS, we don't want to be spending time updating physics at all. +        if (time_delta > 1.0)          {                  mLastTime = time;                  return FALSE; @@ -468,201 +477,207 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)          const F32 behavior_gain = getParamValue("Gain");          const F32 behavior_damping = getParamValue("Damping");          const F32 behavior_drag = getParamValue("Drag"); -        const BOOL physics_test = gSavedSettings.getBOOL("AvatarPhysicsTest") && gAgent.isGodlike(); +        const BOOL physics_test = FALSE; // Enable this to simulate bouncing on all parts.          F32 behavior_maxeffect = getParamValue("MaxEffect");          if (physics_test)                  behavior_maxeffect = 1.0f; -        // mPositon_local should be in normalized 0,1 range already.  Just making sure... -        F32 position_current_local = llclamp(mPosition_local, -                                             0.0f, -                                             1.0f); - -        // Normalize the param position to be from [0,1]. -        // We have to use normalized values because there may be more than one driven param, -        // and each of these driven params may have its own range. -        // This means we'll do all our calculations in normalized [0,1] local coordinates. -        F32 position_user_local = mParamDriver->getWeight(); -        position_user_local = (position_user_local - mParamDriver->getMinWeight()) / (mParamDriver->getMaxWeight() - mParamDriver->getMinWeight()); - -        // If the effect is turned off then don't process unless we need one more update -        // to set the position to the default (i.e. user) position. -        if ((behavior_maxeffect == 0) && (position_current_local == position_user_local)) -        { -            return FALSE; -        } - -        // -        // End parameters and settings -        //////////////////////////////////////////////////////////////////////////////// - - -        //////////////////////////////////////////////////////////////////////////////// -        // Calculate velocity and acceleration in parameter space. -        // +	// Normalize the param position to be from [0,1]. +	// We have to use normalized values because there may be more than one driven param, +	// and each of these driven params may have its own range. +	// This means we'll do all our calculations in normalized [0,1] local coordinates. +	const F32 position_user_local = (mParamDriver->getWeight() - mParamDriver->getMinWeight()) / (mParamDriver->getMaxWeight() - mParamDriver->getMinWeight()); +       	 +	// +	// End parameters and settings +	//////////////////////////////////////////////////////////////////////////////// +	 +	 +	//////////////////////////////////////////////////////////////////////////////// +	// Calculate velocity and acceleration in parameter space. +	// -        const F32 velocity_joint_local = calculateVelocity_local(time_delta); -        const F32 acceleration_joint_local = calculateAcceleration_local(velocity_joint_local, time_delta); - -        // -        // End velocity and acceleration -        //////////////////////////////////////////////////////////////////////////////// - - -        //////////////////////////////////////////////////////////////////////////////// -        // Calculate the total force  -        // - -        // Spring force is a restoring force towards the original user-set breast position. -        // F = kx -        const F32 spring_length = position_current_local - position_user_local; -        const F32 force_spring = -spring_length * behavior_spring; - -        // Acceleration is the force that comes from the change in velocity of the torso. -        // F = ma -        const F32 force_accel = behavior_gain * (acceleration_joint_local * behavior_mass); - -        // Gravity always points downward in world space. -        // F = mg -        const LLVector3 gravity_world(0,0,1); -        const F32 force_gravity = behavior_gain * (toLocal(gravity_world) * behavior_gravity * behavior_mass); +	//const F32 velocity_joint_local = calculateVelocity_local(time_iteration_step); +	const F32 velocity_joint_local = calculateVelocity_local(); +	const F32 acceleration_joint_local = calculateAcceleration_local(velocity_joint_local); +	 +	// +	// End velocity and acceleration +	//////////////////////////////////////////////////////////////////////////////// +	 +	BOOL update_visuals = FALSE; +	 +	// Break up the physics into a bunch of iterations so that differing framerates will show +	// roughly the same behavior. +	for (F32 time_iteration = 0; time_iteration <= time_delta; time_iteration += TIME_ITERATION_STEP) +	{ +		F32 time_iteration_step = TIME_ITERATION_STEP; +		if (time_iteration + TIME_ITERATION_STEP > time_delta) +		{ +			time_iteration_step = time_delta-time_iteration; +		} +		 +		// mPositon_local should be in normalized 0,1 range already.  Just making sure... +		const F32 position_current_local = llclamp(mPosition_local, +							   0.0f, +							   1.0f); +		// If the effect is turned off then don't process unless we need one more update +		// to set the position to the default (i.e. user) position. +		if ((behavior_maxeffect == 0) && (position_current_local == position_user_local)) +		{ +			return update_visuals; +		} + +		//////////////////////////////////////////////////////////////////////////////// +		// Calculate the total force  +		// + +		// Spring force is a restoring force towards the original user-set breast position. +		// F = kx +		const F32 spring_length = position_current_local - position_user_local; +		const F32 force_spring = -spring_length * behavior_spring; + +		// Acceleration is the force that comes from the change in velocity of the torso. +		// F = ma +		const F32 force_accel = behavior_gain * (acceleration_joint_local * behavior_mass); + +		// Gravity always points downward in world space. +		// F = mg +		const LLVector3 gravity_world(0,0,1); +		const F32 force_gravity = (toLocal(gravity_world) * behavior_gravity * behavior_mass); -        // Damping is a restoring force that opposes the current velocity. -        // F = -kv -        const F32 force_damping = -behavior_damping * mVelocity_local; +		// Damping is a restoring force that opposes the current velocity. +		// F = -kv +		const F32 force_damping = -behavior_damping * mVelocity_local; -        // Drag is a force imparted by velocity (intuitively it is similar to wind resistance) -        // F = .5kv^2 -        const F32 force_drag = .5*behavior_drag*velocity_joint_local*velocity_joint_local*llsgn(velocity_joint_local); +		// Drag is a force imparted by velocity (intuitively it is similar to wind resistance) +		// F = .5kv^2 +		const F32 force_drag = .5*behavior_drag*velocity_joint_local*velocity_joint_local*llsgn(velocity_joint_local); -        const F32 force_net = (force_accel +  -                               force_gravity + -                               force_spring +  -                               force_damping +  -                               force_drag); +		const F32 force_net = (force_accel +  +				       force_gravity + +				       force_spring +  +				       force_damping +  +				       force_drag); -        // -        // End total force -        //////////////////////////////////////////////////////////////////////////////// +		// +		// End total force +		//////////////////////////////////////////////////////////////////////////////// -        //////////////////////////////////////////////////////////////////////////////// -        // Calculate new params -        // - -        // Calculate the new acceleration based on the net force. -        // a = F/m -        const F32 acceleration_new_local = force_net / behavior_mass; -        static const F32 max_acceleration = 10.0f; // magic number, used to be customizable. -        F32 velocity_new_local = mVelocity_local + acceleration_new_local; -        velocity_new_local = llclamp(velocity_new_local,  -                                     -max_acceleration, max_acceleration); +		//////////////////////////////////////////////////////////////////////////////// +		// Calculate new params +		// + +		// Calculate the new acceleration based on the net force. +		// a = F/m +		const F32 acceleration_new_local = force_net / behavior_mass; +		static const F32 max_velocity = 100.0f; // magic number, used to be customizable. +		F32 velocity_new_local = mVelocity_local + acceleration_new_local*time_iteration_step; +		velocity_new_local = llclamp(velocity_new_local,  +					     -max_velocity, max_velocity); -        // Temporary debugging setting to cause all avatars to move, for profiling purposes. -        if (physics_test) -        { -                velocity_new_local = sin(time*4.0); -        } -        // Calculate the new parameters, or remain unchanged if max speed is 0. -        F32 position_new_local = position_current_local + velocity_new_local*time_delta; -        if (behavior_maxeffect == 0) -            position_new_local = position_user_local; - -        // Zero out the velocity if the param is being pushed beyond its limits. -        if ((position_new_local < 0 && velocity_new_local < 0) ||  -            (position_new_local > 1 && velocity_new_local > 0)) -        { -                velocity_new_local = 0; -        } +		// Temporary debugging setting to cause all avatars to move, for profiling purposes. +		if (physics_test) +		{ +			velocity_new_local = sin(time*4.0); +		} +		// Calculate the new parameters, or remain unchanged if max speed is 0. +		F32 position_new_local = position_current_local + velocity_new_local*time_iteration_step; +		if (behavior_maxeffect == 0) +			position_new_local = position_user_local; + +		// Zero out the velocity if the param is being pushed beyond its limits. +		if ((position_new_local < 0 && velocity_new_local < 0) ||  +		    (position_new_local > 1 && velocity_new_local > 0)) +		{ +			velocity_new_local = 0; +		} -	// Check for NaN values.  A NaN value is detected if the variables doesn't equal itself.   -	// If NaN, then reset everything. -	if ((mPosition_local != mPosition_local) || -	    (mVelocity_local != mVelocity_local) || -	    (position_new_local != position_new_local)) -	{ -		position_new_local = 0; -		position_current_local = 0; -		position_user_local = 0; -		mVelocity_local = 0; -		mVelocityJoint_local = 0; -		mAccelerationJoint_local = 0; -		mPosition_local = 0; -		mPosition_world = LLVector3(0,0,0); -	} - -        const F32 position_new_local_clamped = llclamp(position_new_local, -						       0.0f, -						       1.0f); - -        LLDriverParam *driver_param = dynamic_cast<LLDriverParam *>(mParamDriver); -        llassert_always(driver_param); -        if (driver_param) -        { -                // If this is one of our "hidden" driver params, then make sure it's -                // the default value. -                if ((driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && -                    (driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT)) -                { -                        mCharacter->setVisualParamWeight(driver_param, -                                                         0, -                                                         FALSE); -                } -                for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); -                     iter != driver_param->mDriven.end(); -                     ++iter) -                { -                        LLDrivenEntry &entry = (*iter); -                        LLViewerVisualParam *driven_param = entry.mParam; -                        setParamValue(driven_param,position_new_local_clamped, behavior_maxeffect); -                } -        } +		// Check for NaN values.  A NaN value is detected if the variables doesn't equal itself.   +		// If NaN, then reset everything. +		if ((mPosition_local != mPosition_local) || +		    (mVelocity_local != mVelocity_local) || +		    (position_new_local != position_new_local)) +		{ +			position_new_local = 0; +			mVelocity_local = 0; +			mVelocityJoint_local = 0; +			mAccelerationJoint_local = 0; +			mPosition_local = 0; +			mPosition_world = LLVector3(0,0,0); +		} + +		const F32 position_new_local_clamped = llclamp(position_new_local, +							       0.0f, +							       1.0f); + +		LLDriverParam *driver_param = dynamic_cast<LLDriverParam *>(mParamDriver); +		llassert_always(driver_param); +		if (driver_param) +		{ +			// If this is one of our "hidden" driver params, then make sure it's +			// the default value. +			if ((driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) && +			    (driver_param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT)) +			{ +				mCharacter->setVisualParamWeight(driver_param, +								 0, +								 FALSE); +			} +			for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin(); +			     iter != driver_param->mDriven.end(); +			     ++iter) +			{ +				LLDrivenEntry &entry = (*iter); +				LLViewerVisualParam *driven_param = entry.mParam; +				setParamValue(driven_param,position_new_local_clamped, behavior_maxeffect); +			} +		} -        // -        // End calculate new params -        //////////////////////////////////////////////////////////////////////////////// +		// +		// End calculate new params +		//////////////////////////////////////////////////////////////////////////////// -        //////////////////////////////////////////////////////////////////////////////// -        // Conditionally update the visual params -        // +		//////////////////////////////////////////////////////////////////////////////// +		// Conditionally update the visual params +		// -        // Updating the visual params (i.e. what the user sees) is fairly expensive. -        // So only update if the params have changed enough, and also take into account -        // the graphics LOD settings. +		// Updating the visual params (i.e. what the user sees) is fairly expensive. +		// So only update if the params have changed enough, and also take into account +		// the graphics LOD settings. -        BOOL update_visuals = FALSE; - -        // For non-self, if the avatar is small enough visually, then don't update. -        const F32 area_for_max_settings = 0.0; -        const F32 area_for_min_settings = 1400.0; -        const F32 area_for_this_setting = area_for_max_settings + (area_for_min_settings-area_for_max_settings)*(1.0-lod_factor); -        const F32 pixel_area = fsqrtf(mCharacter->getPixelArea()); +		// For non-self, if the avatar is small enough visually, then don't update. +		const F32 area_for_max_settings = 0.0; +		const F32 area_for_min_settings = 1400.0; +		const F32 area_for_this_setting = area_for_max_settings + (area_for_min_settings-area_for_max_settings)*(1.0-lod_factor); +		const F32 pixel_area = fsqrtf(mCharacter->getPixelArea()); -        const BOOL is_self = (dynamic_cast<LLVOAvatarSelf *>(mCharacter) != NULL); -        if ((pixel_area > area_for_this_setting) || is_self) -        { -                const F32 position_diff_local = llabs(mPositionLastUpdate_local-position_new_local_clamped); -                const F32 min_delta = (1.01f-lod_factor)*0.4f; -                if (llabs(position_diff_local) > min_delta) -                { -                        update_visuals = TRUE; -                        mPositionLastUpdate_local = position_new_local; -                } -        } - -        // -        // End update visual params -        //////////////////////////////////////////////////////////////////////////////// - -        mVelocityJoint_local = velocity_joint_local; - -        mVelocity_local = velocity_new_local; -        mAccelerationJoint_local = acceleration_joint_local; -        mPosition_local = position_new_local; +		const BOOL is_self = (dynamic_cast<LLVOAvatarSelf *>(mCharacter) != NULL); +		if ((pixel_area > area_for_this_setting) || is_self) +		{ +			const F32 position_diff_local = llabs(mPositionLastUpdate_local-position_new_local_clamped); +			const F32 min_delta = (1.0001f-lod_factor)*0.4f; +			if (llabs(position_diff_local) > min_delta) +			{ +				update_visuals = TRUE; +				mPositionLastUpdate_local = position_new_local; +			} +		} + +		// +		// End update visual params +		//////////////////////////////////////////////////////////////////////////////// + +		mVelocity_local = velocity_new_local; +		mAccelerationJoint_local = acceleration_joint_local; +		mPosition_local = position_new_local; +	} +	mLastTime = time; +	mPosition_world = joint->getWorldPosition(); +	mVelocityJoint_local = velocity_joint_local; -        mPosition_world = joint->getWorldPosition(); -        mLastTime = time;          /*            // Write out debugging info into a spreadsheet. diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 6cfb708112..18d6731fcb 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -143,10 +143,7 @@ void LLPreviewTexture::onSaveAsBtn(void* data)  void LLPreviewTexture::draw()  { -	if (mUpdateDimensions) -	{ -		updateDimensions(); -	} +	updateDimensions();  	LLPreview::draw(); @@ -396,27 +393,32 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success,  void LLPreviewTexture::updateDimensions()  {  	if (!mImage) +	{  		return; - -	if(mImage->getFullWidth() == 0 || mImage->getFullHeight() == 0) +	} +	if ((mImage->getFullWidth() * mImage->getFullHeight()) == 0)  	{  		return;  	} -	mUpdateDimensions = FALSE; - -	getChild<LLUICtrl>("dimensions")->setTextArg("[WIDTH]", llformat("%d", mImage->getFullWidth())); +	// Update the width/height display every time +	getChild<LLUICtrl>("dimensions")->setTextArg("[WIDTH]",  llformat("%d", mImage->getFullWidth()));  	getChild<LLUICtrl>("dimensions")->setTextArg("[HEIGHT]", llformat("%d", mImage->getFullHeight())); -	 -	//reshape floater -	reshape(getRect().getWidth(), getRect().getHeight()); +	// Reshape the floater only when required +	if (mUpdateDimensions) +	{ +		mUpdateDimensions = FALSE; +		 +		//reshape floater +		reshape(getRect().getWidth(), getRect().getHeight()); -	gFloaterView->adjustToFitScreen(this, FALSE); +		gFloaterView->adjustToFitScreen(this, FALSE); -	LLRect dim_rect(getChildView("dimensions")->getRect()); -	LLRect aspect_label_rect(getChildView("aspect_ratio")->getRect()); -	getChildView("aspect_ratio")->setVisible( dim_rect.mRight < aspect_label_rect.mLeft); +		LLRect dim_rect(getChildView("dimensions")->getRect()); +		LLRect aspect_label_rect(getChildView("aspect_ratio")->getRect()); +		getChildView("aspect_ratio")->setVisible( dim_rect.mRight < aspect_label_rect.mLeft); +	}  } diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 4f18ee1da2..e4c2293938 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -1192,6 +1192,38 @@ void LLSideTray::reshape(S32 width, S32 height, BOOL called_from_parent)  	arrange();  } +// This is just LLView::findChildView specialized to restrict the search to LLPanels. +// Optimization for EXT-4068 to avoid searching down to the individual item level +// when inventories are large. +LLPanel *findChildPanel(LLPanel *panel, const std::string& name, bool recurse) +{ +	for (LLView::child_list_const_iter_t child_it = panel->beginChild(); +		 child_it != panel->endChild(); ++child_it) +	{ +		LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it); +		if (!child_panel) +			continue; +		if (child_panel->getName() == name) +			return child_panel; +	} +	if (recurse) +	{ +		for (LLView::child_list_const_iter_t child_it = panel->beginChild(); +			 child_it != panel->endChild(); ++child_it) +		{ +			LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it); +			if (!child_panel) +				continue; +			LLPanel *found_panel = findChildPanel(child_panel,name,recurse); +			if (found_panel) +			{ +				return found_panel; +			} +		} +	} +	return NULL; +} +  /**   * Activate tab with "panel_name" panel   * if no such tab - return false, otherwise true. @@ -1221,23 +1253,50 @@ LLPanel*	LLSideTray::showPanel		(const std::string& panel_name, const LLSD& para  	return new_panel;  } -void LLSideTray::hidePanel(const std::string& panel_name) +bool LLSideTray::hidePanel(const std::string& panel_name)  { +	bool panelHidden = false; +	  	LLPanel* panelp = getPanel(panel_name); +  	if (panelp)  	{ -		if(isTabAttached(panel_name)) +		LLView* parentp = panelp->getParent(); +		 +		// Collapse the side bar if the panel or the panel's parent is an attached tab +		if (isTabAttached(panel_name) || (parentp && isTabAttached(parentp->getName())))  		{  			collapseSideBar(); +			panelHidden = true;  		}  		else  		{ -			LLFloaterReg::hideInstance("side_bar_tab", panel_name); +			panelHidden = LLFloaterReg::hideInstance("side_bar_tab", panel_name); +			 +			if (!panelHidden) +			{ +				// Look up the panel in the list of detached tabs. +				for (child_vector_const_iter_t child_it = mDetachedTabs.begin(); child_it != mDetachedTabs.end(); ++child_it) +				{ +					LLPanel *detached_panel = dynamic_cast<LLPanel*>(*child_it); +					 +					if (detached_panel) +					{ +						// Hide this detached panel if it is a parent of our panel +						if (findChildPanel(detached_panel, panel_name, true) != NULL) +						{ +							panelHidden = LLFloaterReg::hideInstance("side_bar_tab", detached_panel->getName()); +							break; +						} +					} +				} +			}  		}  	} +	 +	return panelHidden;  } -  void LLSideTray::togglePanel(LLPanel* &sub_panel, const std::string& panel_name, const LLSD& params)  {  	if(!sub_panel) @@ -1255,38 +1314,6 @@ void LLSideTray::togglePanel(LLPanel* &sub_panel, const std::string& panel_name,  	}  } -// This is just LLView::findChildView specialized to restrict the search to LLPanels. -// Optimization for EXT-4068 to avoid searching down to the individual item level -// when inventories are large. -LLPanel *findChildPanel(LLPanel *panel, const std::string& name, bool recurse) -{ -	for (LLView::child_list_const_iter_t child_it = panel->beginChild(); -		 child_it != panel->endChild(); ++child_it) -	{ -		LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it); -		if (!child_panel) -			continue; -		if (child_panel->getName() == name) -			return child_panel; -	} -	if (recurse) -	{ -		for (LLView::child_list_const_iter_t child_it = panel->beginChild(); -			 child_it != panel->endChild(); ++child_it) -		{ -			LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it); -			if (!child_panel) -				continue; -			LLPanel *found_panel = findChildPanel(child_panel,name,recurse); -			if (found_panel) -			{ -				return found_panel; -			} -		} -	} -	return NULL; -} -  LLPanel* LLSideTray::getPanel(const std::string& panel_name)  {  	// Look up the panel in the list of detached tabs. diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index 1dddd9e9bc..46765bfbcc 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -104,7 +104,7 @@ public:  	 */  	LLPanel*	showPanel		(const std::string& panel_name, const LLSD& params = LLSD()); -	void		hidePanel		(const std::string& panel_name); +	bool		hidePanel		(const std::string& panel_name);  	/**  	 * Toggling Side Tray tab which contains "sub_panel" child of "panel_name" panel. diff --git a/indra/newview/llsidetraylistener.cpp b/indra/newview/llsidetraylistener.cpp index 6db13e517d..cd6fa28948 100644 --- a/indra/newview/llsidetraylistener.cpp +++ b/indra/newview/llsidetraylistener.cpp @@ -4,8 +4,25 @@   * @date   2011-02-15   * @brief  Implementation for llsidetraylistener.   *  - * $LicenseInfo:firstyear=2011&license=lgpl$ - * Copyright (c) 2011, Linden Research, Inc. + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 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$   */ diff --git a/indra/newview/llsidetraylistener.h b/indra/newview/llsidetraylistener.h index 0dd2067433..51e2137762 100644 --- a/indra/newview/llsidetraylistener.h +++ b/indra/newview/llsidetraylistener.h @@ -4,8 +4,25 @@   * @date   2011-02-15   * @brief     *  - * $LicenseInfo:firstyear=2011&license=lgpl$ - * Copyright (c) 2011, Linden Research, Inc. + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 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$   */ diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 95bd210ae3..06e0d17b8c 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -639,6 +639,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)  	if (click_action == CLICK_ACTION_NONE				// not doing 1-click action  		&& gSavedSettings.getBOOL("ClickToWalk")		// click to walk enabled  		&& !gAgent.getFlying()							// don't auto-navigate while flying until that works +		&& !gAgentAvatarp->isSitting()  		&& !mBlockClickToWalk							// another behavior hasn't cancelled click to walk  		&& !mPick.mPosGlobal.isExactlyZero()			// valid coordinates for pick  		&& (mPick.mPickType == LLPickInfo::PICK_LAND	// we clicked on land diff --git a/indra/newview/llviewerchat.cpp b/indra/newview/llviewerchat.cpp index 86a29de403..a57eb3276e 100644 --- a/indra/newview/llviewerchat.cpp +++ b/indra/newview/llviewerchat.cpp @@ -36,6 +36,7 @@  #include "llinstantmessage.h" //SYSTEM_FROM  // LLViewerChat +LLViewerChat::font_change_signal_t LLViewerChat::sChatFontChangedSignal;  //static   void LLViewerChat::getChatColor(const LLChat& chat, LLColor4& r_color) @@ -264,3 +265,16 @@ std::string LLViewerChat::getObjectImSLURL(const LLChat& chat, const LLSD& args)  	return url;  } + +//static  +boost::signals2::connection LLViewerChat::setFontChangedCallback(const font_change_signal_t::slot_type& cb) +{ +	return sChatFontChangedSignal.connect(cb); +} + +//static +void LLViewerChat::signalChatFontChanged() +{ +	// Notify all observers that our font has changed +	sChatFontChangedSignal(getChatFont()); +} diff --git a/indra/newview/llviewerchat.h b/indra/newview/llviewerchat.h index 0f15d29f04..c05caf0a95 100644 --- a/indra/newview/llviewerchat.h +++ b/indra/newview/llviewerchat.h @@ -35,6 +35,8 @@  class LLViewerChat   {  public: +	typedef boost::signals2::signal<void (LLFontGL*)> font_change_signal_t; +  	static void getChatColor(const LLChat& chat, LLColor4& r_color);  	static void getChatColor(const LLChat& chat, std::string& r_color_name, F32& r_color_alpha);  	static LLFontGL* getChatFont(); @@ -42,8 +44,12 @@ public:  	static void formatChatMsg(const LLChat& chat, std::string& formated_msg);  	static std::string getSenderSLURL(const LLChat& chat, const LLSD& args); +	static boost::signals2::connection setFontChangedCallback(const font_change_signal_t::slot_type& cb); +	static void signalChatFontChanged(); +  private:  	static std::string getObjectImSLURL(const LLChat& chat, const LLSD& args); +	static font_change_signal_t sChatFontChangedSignal;  }; diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index ffe607f912..06c1520314 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -239,12 +239,6 @@ static bool handleVideoMemoryChanged(const LLSD& newvalue)  	return true;  } -static bool handleBandwidthChanged(const LLSD& newvalue) -{ -	gViewerThrottle.setMaxBandwidth((F32) newvalue.asReal()); -	return true; -} -  static bool handleChatFontSizeChanged(const LLSD& newvalue)  {  	if(gConsole) @@ -562,7 +556,6 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _2));  	gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _2));  	gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _2)); -	gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&handleBandwidthChanged, _2));  	gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _2));  	gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _2));  	gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2)); diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index 519514d99c..9e58acdcd3 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -183,6 +183,12 @@ public:  			return false;  		} +		if (!LLUI::sSettingGroups["config"]->getBOOL("EnableInventory")) +		{ +				LLNotificationsUtil::add("NoInventory", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit")); +				return true; +		} +  		// support secondlife:///app/inventory/show  		if (params[0].asString() == "show")  		{ @@ -1450,6 +1456,9 @@ private:  	void saveFavoritesSLURLs(); +	// Remove record of current user's favorites from file on disk. +	void removeFavoritesRecordOfUser(); +  	void onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark);  	void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl); @@ -1534,6 +1543,10 @@ void LLFavoritesOrderStorage::destroyClass()  	{  		LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();  	} +	else +	{ +		LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser(); +	}  }  void LLFavoritesOrderStorage::load() @@ -1602,6 +1615,28 @@ void LLFavoritesOrderStorage::saveFavoritesSLURLs()  	LLSDSerialize::toPrettyXML(fav_llsd, file);  } +void LLFavoritesOrderStorage::removeFavoritesRecordOfUser() +{ +	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml"); +	LLSD fav_llsd; +	llifstream file; +	file.open(filename); +	if (!file.is_open()) return; +	LLSDSerialize::fromXML(fav_llsd, file); + +	LLAvatarName av_name; +	LLAvatarNameCache::get( gAgentID, &av_name ); +	if (fav_llsd.has(av_name.getLegacyName())) +	{ +		fav_llsd.erase(av_name.getLegacyName()); +	} + +	llofstream out_file; +	out_file.open(filename); +	LLSDSerialize::toPrettyXML(fav_llsd, out_file); + +} +  void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark)  {  	if (!landmark) return; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index fda291f3c1..2cf8dbec89 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -493,6 +493,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,  	LLSD args;  	std::string exten = gDirUtilp->getExtension(src_filename); +	U32 codec = LLImageBase::getCodecFromExtension(exten);  	LLAssetType::EType asset_type = LLAssetType::AT_NONE;  	std::string error_message; @@ -510,66 +511,20 @@ void upload_new_resource(const std::string& src_filename, std::string name,   		upload_error(error_message, "NoFileExtension", filename, args);  		return;  	} -	else if( exten == "bmp") +	else if (codec != IMG_CODEC_INVALID)  	{ +		// It's an image file, the upload procedure is the same for all  		asset_type = LLAssetType::AT_TEXTURE; -		if (!LLViewerTextureList::createUploadFile(src_filename, -												 filename, -												 IMG_CODEC_BMP )) +		if (!LLViewerTextureList::createUploadFile(src_filename, filename, codec ))  		{  			error_message = llformat( "Problem with file %s:\n\n%s\n", -					src_filename.c_str(), LLImage::getLastError().c_str()); +									 src_filename.c_str(), LLImage::getLastError().c_str());  			args["FILE"] = src_filename;  			args["ERROR"] = LLImage::getLastError();  			upload_error(error_message, "ProblemWithFile", filename, args);  			return;  		}  	} -	else if( exten == "tga") -	{ -		asset_type = LLAssetType::AT_TEXTURE; -		if (!LLViewerTextureList::createUploadFile(src_filename, -												 filename, -												 IMG_CODEC_TGA )) -		{ -			error_message = llformat("Problem with file %s:\n\n%s\n", -					src_filename.c_str(), LLImage::getLastError().c_str()); -			args["FILE"] = src_filename; -			args["ERROR"] = LLImage::getLastError(); -			upload_error(error_message, "ProblemWithFile", filename, args); -			return; -		} -	} -	else if( exten == "jpg" || exten == "jpeg") -	{ -		asset_type = LLAssetType::AT_TEXTURE; -		if (!LLViewerTextureList::createUploadFile(src_filename, -												 filename, -												 IMG_CODEC_JPEG )) -		{ -			error_message = llformat("Problem with file %s:\n\n%s\n", -					src_filename.c_str(), LLImage::getLastError().c_str()); -			args["FILE"] = src_filename; -			args["ERROR"] = LLImage::getLastError(); -			upload_error(error_message, "ProblemWithFile", filename, args); -			return; -		} -	} - 	else if( exten == "png") - 	{ - 		asset_type = LLAssetType::AT_TEXTURE; - 		if (!LLViewerTextureList::createUploadFile(src_filename, - 												 filename, - 												 IMG_CODEC_PNG )) - 		{ - 			error_message = llformat("Problem with file %s:\n\n%s\n", - 					src_filename.c_str(), LLImage::getLastError().c_str()); - 			args["FILE"] = src_filename; - 			args["ERROR"] = LLImage::getLastError(); - 			upload_error(error_message, "ProblemWithFile", filename, args); - 			return; - 		} - 	}  	else if(exten == "wav")  	{  		asset_type = LLAssetType::AT_SOUND;  // tag it as audio diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 5792bf2c03..5802ac1d12 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -5519,7 +5519,11 @@ void process_alert_core(const std::string& message, BOOL modal)  	{  		LLSD args;  		std::string new_msg =LLNotifications::instance().getGlobalString(message); -		args["MESSAGE"] = new_msg; + +		std::string localized_msg; +		bool is_message_localized = LLTrans::findString(localized_msg, new_msg); + +		args["MESSAGE"] = is_message_localized ? localized_msg : new_msg;  		LLNotificationsUtil::add("SystemMessageTip", args);  	}  } diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 06f6ff23c2..5afed721ac 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -927,99 +927,43 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)  BOOL LLViewerTextureList::createUploadFile(const std::string& filename,  										 const std::string& out_filename,  										 const U8 codec) -{ -	// First, load the image. +{	 +	// Load the image +	LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec); +	if (image.isNull()) +	{ +		return FALSE; +	}	 +	if (!image->load(filename)) +	{ +		return FALSE; +	} +	// Decompress or expand it in a raw image structure  	LLPointer<LLImageRaw> raw_image = new LLImageRaw; -	 -	switch (codec) +	if (!image->decode(raw_image, 0.0f))  	{ -		case IMG_CODEC_BMP: -		{ -			LLPointer<LLImageBMP> bmp_image = new LLImageBMP; -			 -			if (!bmp_image->load(filename)) -			{ -				return FALSE; -			} -			 -			if (!bmp_image->decode(raw_image, 0.0f)) -			{ -				return FALSE; -			} -		} -			break; -		case IMG_CODEC_TGA: -		{ -			LLPointer<LLImageTGA> tga_image = new LLImageTGA; -			 -			if (!tga_image->load(filename)) -			{ -				return FALSE; -			} -			 -			if (!tga_image->decode(raw_image)) -			{ -				return FALSE; -			} -			 -			if(	(tga_image->getComponents() != 3) && -			   (tga_image->getComponents() != 4) ) -			{ -				tga_image->setLastError( "Image files with less than 3 or more than 4 components are not supported." ); -				return FALSE; -			} -		} -			break; -		case IMG_CODEC_JPEG: -		{ -			LLPointer<LLImageJPEG> jpeg_image = new LLImageJPEG; -			 -			if (!jpeg_image->load(filename)) -			{ -				return FALSE; -			} -			 -			if (!jpeg_image->decode(raw_image, 0.0f)) -			{ -				return FALSE; -			} -		} -			break; -		case IMG_CODEC_PNG: -		{ -			LLPointer<LLImagePNG> png_image = new LLImagePNG; -			 -			if (!png_image->load(filename)) -			{ -				return FALSE; -			} -			 -			if (!png_image->decode(raw_image, 0.0f)) -			{ -				return FALSE; -			} -		} -			break; -		default: -			return FALSE; +		return FALSE;  	} -	 -	LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image); -	 -	if( !compressedImage->save(out_filename) ) +	// Check the image constraints +	if ((image->getComponents() != 3) && (image->getComponents() != 4))  	{ -		llinfos << "Couldn't create output file " << out_filename << llendl; +		image->setLastError("Image files with less than 3 or more than 4 components are not supported.");  		return FALSE;  	} -	 -	// test to see if the encode and save worked. +	// Convert to j2c (JPEG2000) and save the file locally +	LLPointer<LLImageJ2C> compressedImage = convertToUploadFile(raw_image);	 +	if (!compressedImage->save(out_filename)) +	{ +		llinfos << "Couldn't create output file : " << out_filename << llendl; +		return FALSE; +	} +	// Test to see if the encode and save worked  	LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C; -	if( !integrity_test->loadAndValidate( out_filename ) ) +	if (!integrity_test->loadAndValidate( out_filename ))  	{ -		llinfos << "Image: " << out_filename << " is corrupt." << llendl; +		llinfos << "Image file : " << out_filename << " is corrupt" << llendl;  		return FALSE;  	} -	  	return TRUE;  } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 4305349ea2..e020296842 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -3968,7 +3968,9 @@ BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 p  	return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type);  } -// Saves the image from the screen to the specified filename and path. +// Saves the image from the screen to a raw image +// Since the required size might be bigger than the available screen, this method rerenders the scene in parts (called subimages) and copy +// the results over to the final raw image.  BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height,   								 BOOL keep_window_aspect, BOOL is_texture, BOOL show_ui, BOOL do_rebuild, ESnapshotType type, S32 max_size)  { @@ -3986,8 +3988,6 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	// Hide all the UI widgets first and draw a frame  	BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE; -	show_ui = show_ui ? TRUE : FALSE; -  	if ( prev_draw_ui != show_ui)  	{  		LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); @@ -4007,55 +4007,49 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	// from window  	LLRect window_rect = show_ui ? getWindowRectRaw() : getWorldViewRectRaw();  -	S32 snapshot_width = window_rect.getWidth(); +	S32 snapshot_width  = window_rect.getWidth();  	S32 snapshot_height = window_rect.getHeight();  	// SNAPSHOT -	S32 window_width = snapshot_width; +	S32 window_width  = snapshot_width;  	S32 window_height = snapshot_height; +	// Note: Scaling of the UI is currently *not* supported so we limit the output size if UI is requested  	if (show_ui)  	{ -		image_width = llmin(image_width, window_width); +		// If the user wants the UI, limit the output size to the available screen size +		image_width  = llmin(image_width, window_width);  		image_height = llmin(image_height, window_height);  	}  	F32 scale_factor = 1.0f ; -	if(!keep_window_aspect) //image cropping -	{		 +	if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height)) +	{	 +		// if image cropping or need to enlarge the scene, compute a scale_factor  		F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; -		snapshot_width = (S32)(ratio * image_width) ; +		snapshot_width  = (S32)(ratio * image_width) ;  		snapshot_height = (S32)(ratio * image_height) ;  		scale_factor = llmax(1.0f, 1.0f / ratio) ;  	} -	else //the scene(window) proportion needs to be maintained. -	{ -		if(image_width > window_width || image_height > window_height) //need to enlarge the scene -		{ -			F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ; -			snapshot_width = (S32)(ratio * image_width) ; -			snapshot_height = (S32)(ratio * image_height) ; -			scale_factor = llmax(1.0f, 1.0f / ratio) ;	 -		} -	}  	if (show_ui && scale_factor > 1.f)  	{ +		// Note: we should never get there...  		llwarns << "over scaling UI not supported." << llendl;  	} -	S32 buffer_x_offset = llfloor(((window_width - snapshot_width) * scale_factor) / 2.f); +	S32 buffer_x_offset = llfloor(((window_width  - snapshot_width)  * scale_factor) / 2.f);  	S32 buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f); -	S32 image_buffer_x = llfloor(snapshot_width*scale_factor) ; -	S32 image_buffer_y = llfloor(snapshot_height *scale_factor) ; +	S32 image_buffer_x = llfloor(snapshot_width  * scale_factor) ; +	S32 image_buffer_y = llfloor(snapshot_height * scale_factor) ; -	if(image_buffer_x > max_size || image_buffer_y > max_size) //boundary check to avoid memory overflow +	if ((image_buffer_x > max_size) || (image_buffer_y > max_size)) // boundary check to avoid memory overflow  	{  		scale_factor *= llmin((F32)max_size / image_buffer_x, (F32)max_size / image_buffer_y) ; -		image_buffer_x = llfloor(snapshot_width*scale_factor) ; -		image_buffer_y = llfloor(snapshot_height *scale_factor) ; +		image_buffer_x = llfloor(snapshot_width  * scale_factor) ; +		image_buffer_y = llfloor(snapshot_height * scale_factor) ;  	} -	if(image_buffer_x > 0 && image_buffer_y > 0) +	if ((image_buffer_x > 0) && (image_buffer_y > 0))  	{  		raw->resize(image_buffer_x, image_buffer_y, 3);  	} @@ -4063,7 +4057,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	{  		return FALSE ;  	} -	if(raw->isBufferInvalid()) +	if (raw->isBufferInvalid())  	{  		return FALSE ;  	} @@ -4071,6 +4065,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	BOOL high_res = scale_factor >= 2.f; // Font scaling is slow, only do so if rez is much higher  	if (high_res && show_ui)  	{ +		// Note: we should never get there...  		llwarns << "High res UI snapshot not supported. " << llendl;  		/*send_agent_pause();  		//rescale fonts @@ -4085,6 +4080,8 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  	gObjectList.generatePickList(*LLViewerCamera::getInstance()); +	// Subimages are in fact partial rendering of the final view. This happens when the final view is bigger than the screen. +	// In most common cases, scale_factor is 1 and there's no more than 1 iteration on x and y  	for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y)  	{  		S32 subimage_y_offset = llclamp(buffer_y_offset - (subimage_y * window_height), 0, window_height);; @@ -4098,69 +4095,70 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei  			gDisplaySwapBuffers = FALSE;  			gDepthDirty = TRUE; -			const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor)); - -			if (LLPipeline::sRenderDeferred) -			{ -					display(do_rebuild, scale_factor, subfield, TRUE); -			} -			else -			{ -				display(do_rebuild, scale_factor, subfield, TRUE); -					// Required for showing the GUI in snapshots and performing bloom composite overlay -					// Call even if show_ui is FALSE -				render_ui(scale_factor, subfield); -			} -  			S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width);  			// handle fractional rows  			U32 read_width = llmax(0, (window_width - subimage_x_offset) -  									llmax(0, (window_width * (subimage_x + 1)) - (buffer_x_offset + raw->getWidth()))); -			for(U32 out_y = 0; out_y < read_height ; out_y++) +			 +			// Skip rendering and sampling altogether if either width or height is degenerated to 0 (common in cropping cases) +			if (read_width && read_height)  			{ -				S32 output_buffer_offset = (  -							(out_y * (raw->getWidth())) // ...plus iterated y... -							+ (window_width * subimage_x) // ...plus subimage start in x... -							+ (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y... -							- output_buffer_offset_x // ...minus buffer padding x... -							- (output_buffer_offset_y * (raw->getWidth()))  // ...minus buffer padding y... -						) * raw->getComponents(); +				const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor)); +				display(do_rebuild, scale_factor, subfield, TRUE); -				// Ping the wathdog thread every 100 lines to keep us alive (arbitrary number, feel free to change) -				if (out_y % 100 == 0) +				if (!LLPipeline::sRenderDeferred)  				{ -					LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot"); +					// Required for showing the GUI in snapshots and performing bloom composite overlay +					// Call even if show_ui is FALSE +					render_ui(scale_factor, subfield);  				} -				if (type == SNAPSHOT_TYPE_COLOR) +				for (U32 out_y = 0; out_y < read_height ; out_y++)  				{ -					glReadPixels( -						subimage_x_offset, out_y + subimage_y_offset, -						read_width, 1, -						GL_RGB, GL_UNSIGNED_BYTE, -						raw->getData() + output_buffer_offset -					); -				} -				else // SNAPSHOT_TYPE_DEPTH -				{ -					LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values -					glReadPixels( -						subimage_x_offset, out_y + subimage_y_offset, -						read_width, 1, -						GL_DEPTH_COMPONENT, GL_FLOAT, -						depth_line_buffer->getData()// current output pixel is beginning of buffer... -					); - -					for (S32 i = 0; i < (S32)read_width; i++) +					S32 output_buffer_offset = (  +												(out_y * (raw->getWidth())) // ...plus iterated y... +												+ (window_width * subimage_x) // ...plus subimage start in x... +												+ (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y... +												- output_buffer_offset_x // ...minus buffer padding x... +												- (output_buffer_offset_y * (raw->getWidth()))  // ...minus buffer padding y... +												) * raw->getComponents(); +				 +					// Ping the watchdog thread every 100 lines to keep us alive (arbitrary number, feel free to change) +					if (out_y % 100 == 0)  					{ -						F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32))); -					 -						F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2)); -						U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar()); -						//write converted scanline out to result image -						for(S32 j = 0; j < raw->getComponents(); j++) +						LLAppViewer::instance()->pingMainloopTimeout("LLViewerWindow::rawSnapshot"); +					} +				 +					if (type == SNAPSHOT_TYPE_COLOR) +					{ +						glReadPixels( +									 subimage_x_offset, out_y + subimage_y_offset, +									 read_width, 1, +									 GL_RGB, GL_UNSIGNED_BYTE, +									 raw->getData() + output_buffer_offset +									 ); +					} +					else // SNAPSHOT_TYPE_DEPTH +					{ +						LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values +						glReadPixels( +									 subimage_x_offset, out_y + subimage_y_offset, +									 read_width, 1, +									 GL_DEPTH_COMPONENT, GL_FLOAT, +									 depth_line_buffer->getData()// current output pixel is beginning of buffer... +									 ); + +						for (S32 i = 0; i < (S32)read_width; i++)  						{ -							*(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte; +							F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32))); +					 +							F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2)); +							U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar()); +							// write converted scanline out to result image +							for (S32 j = 0; j < raw->getComponents(); j++) +							{ +								*(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte; +							}  						}  					}  				} diff --git a/indra/newview/llwearabletype.cpp b/indra/newview/llwearabletype.cpp index 9e95604712..c090ab5c3d 100644 --- a/indra/newview/llwearabletype.cpp +++ b/indra/newview/llwearabletype.cpp @@ -80,7 +80,7 @@ LLWearableDictionary::LLWearableDictionary()  	addEntry(LLWearableType::WT_ALPHA,        new WearableEntry("alpha",       "New Alpha",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE));  	addEntry(LLWearableType::WT_TATTOO,       new WearableEntry("tattoo",      "New Tattoo",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE)); -	addEntry(LLWearableType::WT_PHYSICS,      new WearableEntry("physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_PHYSICS, TRUE, FALSE)); +	addEntry(LLWearableType::WT_PHYSICS,      new WearableEntry("physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));  	addEntry(LLWearableType::WT_INVALID,      new WearableEntry("invalid",     "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryIcon::ICONNAME_NONE, FALSE, FALSE));  	addEntry(LLWearableType::WT_NONE,      	  new WearableEntry("none",        "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryIcon::ICONNAME_NONE, FALSE, FALSE)); diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 8494ce8b1b..64eef11fae 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -763,4 +763,21 @@      <color       name="DirectChatColor"       reference="LtOrange" /> +   +    <!-- Generic color names (legacy) --> +  <color +    name="white" +    value="1 1 1 1"/> +  <color +    name="black" +    value="0 0 0 1"/> +  <color +    name="red" +    value="1 0 0 1"/> +  <color +    name="green" +    value="0 1 0 1"/> +  <color +    name="blue" +    value="0 0 1 1"/>  </colors> diff --git a/indra/newview/skins/default/xui/en/floater_buy_contents.xml b/indra/newview/skins/default/xui/en/floater_buy_contents.xml index babbf0f5ca..92001534e7 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_contents.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_contents.xml @@ -34,7 +34,7 @@       layout="topleft"       name="contains_text"       width="276"> -        [NAME] contains: +        <nolink>[NAME]</nolink> contains:      </text>      <scroll_list       background_visible="true" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 51610c0ae0..a5115b0faa 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3113,6 +3113,16 @@               function="ToggleControl"               parameter="ImagePipelineUseHTTP" />          </menu_item_check> +        <menu_item_check +         label="HTTP Inventory" +         name="HTTP Inventory"> +            <menu_item_check.on_check +             function="CheckControl" +             parameter="UseHTTPInventory" /> +            <menu_item_check.on_click +             function="ToggleControl" +             parameter="UseHTTPInventory" /> +        </menu_item_check>          <menu_item_call           label="Compress Images"           name="Compress Images"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f83b2e3d9c..d3557cfd2a 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -7228,7 +7228,49 @@ The site at '<nolink>[HOST_NAME]</nolink>' in realm '     yestext="Quit"     notext="Don't Quit"/>    </notification> -   + +  <notification + name="NoInventory" + label="" + type="alertmodal" + unique="true"> +    <tag>fail</tag> +    <tag>confirm</tag> +    Viewing inventory is only available in Advanced mode. Would you like to logout and change modes? +    <usetemplate +   name="okcancelbuttons" +   yestext="Quit" +   notext="Don't Quit"/> +  </notification> + +  <notification + name="NoAppearance" + label="" + type="alertmodal" + unique="true"> +    <tag>fail</tag> +    <tag>confirm</tag> +    The appearance editor is only available in Advanced mode. Would you like to logout and change modes? +    <usetemplate +   name="okcancelbuttons" +   yestext="Quit" +   notext="Don't Quit"/> +  </notification> + +  <notification + name="NoSearch" + label="" + type="alertmodal" + unique="true"> +    <tag>fail</tag> +    <tag>confirm</tag> +    Search is only available in Advanced mode. Would you like to logout and change modes? +    <usetemplate +   name="okcancelbuttons" +   yestext="Quit" +   notext="Don't Quit"/> +  </notification> +    <global name="UnsupportedCPU">  - Your CPU speed does not meet the minimum requirements.    </global> diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml index a92cc886e7..c8882fd02c 100644 --- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml @@ -5,121 +5,121 @@   bg_opaque_color="DkGray"   chrome="true"   follows="left|bottom|right" - focus_root="true"  + focus_root="true"   height="33"   layout="topleft"   left="0"   name="bottom_tray"   top="28"   width="1310"> -    <string +  <string       name="DragIndicationImageName"       value="Accordion_ArrowOpened_Off" /> -    <string +  <string       name="SpeakBtnToolTip"       value="Turns microphone on/off" /> -    <string +  <string       name="VoiceControlBtnToolTip"       value="Shows/hides voice control panel" /> -    <layout_stack +  <layout_stack       border_size="0"       clip="false"       follows="all"       height="28" -     layout="topleft" -     left="0" +   layout="topleft" +   left="0"       mouse_opaque="false"       name="toolbar_stack"       orientation="horizontal"       top="0"       width="1310"> -        <layout_panel +    <layout_panel           auto_resize="false" -         user_resize="false"  +         user_resize="false"           min_width="2"           width="2" /> -        <layout_panel +    <layout_panel           auto_resize="false"           layout="topleft"           max_width="320"           min_width="214" -         height="28"  +         height="28"           mouse_opaque="false" -         name="chat_bar_layout_panel" +		 name="chat_bar_layout_panel"           user_resize="true" -         width="310" > -          <panel -            name="chat_bar" -            filename="panel_nearby_chat_bar.xml" -            left="0" -            height="28" -            width="308" -            top="0" -            mouse_opaque="false" -            follows="left|right" +     width="310" > +      <panel +		   name="chat_bar" +			  filename="panel_nearby_chat_bar.xml" +			  left="0" +			  height="28" +        width="308" +			  top="0" +			  mouse_opaque="false" +			  follows="left|right"            /> -        </layout_panel> -        <!-- +    </layout_panel> +    <!--           This 5px Panel is an indicator of where the resize handle is.           The panel provides a gap between the resize handle icon and a button to the right.            --> -        <layout_panel -         auto_resize="false" -         layout="topleft" -         max_width="5"  -         min_width="5" -         name="chat_bar_resize_handle_panel" -         user_resize="false" -         width="5"> -            <icon -             follows="top|right" -             height="25" -             image_name="ChatBarHandle" -             layout="topleft" -             left="-7" -             name="resize_handle" -             top="4" -             width="5" /> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="left|right" -         height="28" -         layout="topleft" -         min_height="28" -         min_width="59" -         mouse_opaque="false" -         name="speak_panel" -         top_delta="0" -         user_resize="false" -         width="108"> -            <talk_button -             follows="left|right" -             height="23" -             layout="topleft" -             left="0" -             name="talk" -             top="5" -             width="105"> -                <show_button -                 tab_stop="true"> -                    <init_callback -                     function="Button.SetDockableFloaterToggle" -                     parameter="voice_controls" /> -                </show_button> -                <!-- do not remove halign attribute with default value. otherwise it can't be overridden in other locales. +    <layout_panel +     auto_resize="false" +     layout="topleft" +     max_width="5" +     min_width="5" +     name="chat_bar_resize_handle_panel" +     user_resize="false" +     width="5"> +      <icon +       follows="top|right" +       height="25" +       image_name="ChatBarHandle" +       layout="topleft" +       left="-7" +       name="resize_handle" +       top="4" +       width="5" /> +    </layout_panel> +    <layout_panel +        auto_resize="false" +        follows="left|right" +        height="28" +        layout="topleft" +        min_height="28" +        min_width="59" +        mouse_opaque="false" +        name="speak_panel" +        top_delta="0" +        user_resize="false" +        width="108"> +      <talk_button +       follows="left|right" +       height="23" +       layout="topleft" +       left="0" +       name="talk" +       top="5" +       width="105"> +        <show_button +         tab_stop="true"> +          <init_callback +           function="Button.SetDockableFloaterToggle" +           parameter="voice_controls" /> +        </show_button> +        <!-- do not remove halign attribute with default value. otherwise it can't be overridden in other locales.                   & pad_right is default value for long label which can be right aligned. See EXT-6318 --> -                <speak_button -                 halign="center" -                 label="Speak" -                 label_selected="Speak" -                 name="speak_btn" -                 pad_right="20" -                 tab_stop="true" -                 use_ellipses="true" /> -            </talk_button> -        </layout_panel> -        <layout_panel +        <speak_button +         halign="center" +         label="Speak" +         label_selected="Speak" +         name="speak_btn" +         pad_right="20" +         tab_stop="true" +         use_ellipses="true" /> +      </talk_button> +    </layout_panel> +    <layout_panel           auto_resize="false"           follows="right"           height="28" @@ -131,7 +131,7 @@           top_delta="0"           user_resize="false"           width="85"> -            <gesture_combo_list +      <gesture_combo_list               follows="left|right"               height="23"               label="Gesture" @@ -141,46 +141,46 @@               tool_tip="Shows/hides gestures"               top="5"               width="82"> -                <combo_button +        <combo_button                   pad_right="10"                   use_ellipses="true" /> -                <combo_list +        <combo_list                   page_lines="17" /> -            </gesture_combo_list> -        </layout_panel> -        <layout_panel +      </gesture_combo_list> +    </layout_panel> +    <layout_panel           auto_resize="false" -         follows="right" -         height="28" -         layout="topleft" -         min_height="28" -         min_width="52" -         mouse_opaque="false" -         name="movement_panel" -         user_resize="false" -         width="83"> -            <bottomtray_button -             follows="left|right" -             height="23" -             image_pressed="PushButton_Press" -             image_pressed_selected="PushButton_Selected_Press" -             image_selected="PushButton_Selected_Press" -             is_toggle="true" -             label="Move" -             layout="topleft" -             name="movement_btn" -             tool_tip="Shows/hides movement controls" -             top="5" -             use_ellipses="true" -             width="80"> -                <init_callback -                 function="Button.SetDockableFloaterToggle" -                 parameter="moveview" /> -            </bottomtray_button> +     follows="right" +     height="28" +     layout="topleft" +     min_height="28" +     min_width="52" +     mouse_opaque="false" +     name="movement_panel" +     user_resize="false" +     width="83"> +      <bottomtray_button +       follows="left|right" +       height="23" +       image_pressed="PushButton_Press" +       image_pressed_selected="PushButton_Selected_Press" +       image_selected="PushButton_Selected_Press" +       is_toggle="true" +       label="Move" +       layout="topleft" +       name="movement_btn" +       tool_tip="Shows/hides movement controls" +       top="5" +       use_ellipses="true" +       width="80"> +        <init_callback +         function="Button.SetDockableFloaterToggle" +         parameter="moveview" /> +      </bottomtray_button> -        </layout_panel> -        <layout_panel -         auto_resize="false" +    </layout_panel> +    <layout_panel +     auto_resize="false"           follows="left|right"           height="28"           layout="topleft" @@ -190,7 +190,7 @@           name="cam_panel"           user_resize="false"           width="83"> -            <bottomtray_button +      <bottomtray_button               follows="left|right"               height="23"               image_pressed="PushButton_Press" @@ -205,180 +205,180 @@               top="5"               use_ellipses="true"               width="80"> -                <init_callback +        <init_callback                   function="Button.SetDockableFloaterToggle"                   parameter="camera" /> -            </bottomtray_button> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="left|right" -         height="28" -         layout="topleft" -         min_width="40" -         mouse_opaque="false" -         name="snapshot_panel" -         user_resize="false" -         width="39"> -            <bottomtray_button -             follows="left|right" -             height="23" -             image_overlay="Snapshot_Off" -             image_pressed="PushButton_Press" -             image_pressed_selected="PushButton_Selected_Press" -             image_selected="PushButton_Selected_Press" -             is_toggle="true" -             layout="topleft" -             left="0" -             name="snapshots" -             tool_tip="Take snapshot" -             top="5" -             width="36"> -                <init_callback -                 function="Button.SetFloaterToggle" -                 parameter="snapshot" /> -            </bottomtray_button> -        </layout_panel> -        <layout_panel +      </bottomtray_button> +    </layout_panel> +    <layout_panel           auto_resize="false"           follows="left|right"           height="28"           layout="topleft" -         min_height="28" -         min_width="52" -         mouse_opaque="false" -         name="build_btn_panel" -         user_resize="false" -         width="83"> -<!--*FIX: Build Floater is not opened with default registration. Will be fixed soon. +     min_width="40" +		  mouse_opaque="false" +     name="snapshot_panel" +		  user_resize="false" +     width="39"> +      <bottomtray_button +			follows="left|right" +			height="23" +       image_overlay="Snapshot_Off" +			image_pressed="PushButton_Press" +			image_pressed_selected="PushButton_Selected_Press" +			image_selected="PushButton_Selected_Press" +       is_toggle="true" +			layout="topleft" +			left="0" +       name="snapshots" +       tool_tip="Take snapshot" +			top="5" +       width="36"> +        <init_callback +         function="Button.SetFloaterToggle" +         parameter="snapshot" /> +      </bottomtray_button> +    </layout_panel> +    <layout_panel +		  auto_resize="false" +		  follows="left|right" +		  height="28" +		  layout="topleft" +		  min_height="28" +     min_width="52" +		  mouse_opaque="false" +     name="build_btn_panel" +		  user_resize="false" +     width="83"> +      <!--*FIX: Build Floater is not opened with default registration. Will be fixed soon.  Disabled for now.  --> -            <bottomtray_button -             follows="left|right" -             height="23" -             image_pressed="PushButton_Press" -             image_pressed_selected="PushButton_Selected_Press" -             image_selected="PushButton_Selected_Press" -             is_toggle="true" -             label="Build" -             layout="topleft" -             left="0" -             name="build_btn" -             tool_tip="Shows/hides Build Tools" -             top="5" -             use_ellipses="true" -             width="80"> -                <commit_callback -                 function="Build.Toggle" -                 parameter="build" /> -            </bottomtray_button> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="left|right" -         height="28" -         layout="topleft" -         min_height="28" -         min_width="52" -         mouse_opaque="false" -         name="search_btn_panel" -         user_resize="false" -         width="83"> -            <bottomtray_button -             follows="left|right" -             height="23" -             image_pressed="PushButton_Press" -             image_pressed_selected="PushButton_Selected_Press" -             image_selected="PushButton_Selected_Press" -             is_toggle="true" -             label="Search" -             layout="topleft" -             left="0" -             name="search_btn" -             tool_tip="Shows/hides Search" -             top="5" -             use_ellipses="true" -             width="80"> -                <init_callback -                 function="Button.SetFloaterToggle" -                 parameter="search" /> -            </bottomtray_button> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="left|right" -         height="28" -         layout="topleft" +      <bottomtray_button +			follows="left|right" +			height="23" +			image_pressed="PushButton_Press" +			image_pressed_selected="PushButton_Selected_Press" +			image_selected="PushButton_Selected_Press" +       is_toggle="true" +       label="Build" +			layout="topleft" +			left="0" +       name="build_btn" +       tool_tip="Shows/hides Build Tools" +			top="5" +			use_ellipses="true" +       width="80"> +        <commit_callback +         function="Build.Toggle" +         parameter="build" /> +      </bottomtray_button> +    </layout_panel> +    <layout_panel +		  auto_resize="false" +		  follows="left|right" +		  height="28" +		  layout="topleft"           min_height="28" -         min_width="52" +     min_width="52"           mouse_opaque="false" -         name="world_map_btn_panel" +     name="search_btn_panel"           user_resize="false" -         width="83"> -            <bottomtray_button -             follows="left|right" -             height="23" -             image_pressed="PushButton_Press" -             image_pressed_selected="PushButton_Selected_Press" -             image_selected="PushButton_Selected_Press" -             is_toggle="true" -             label="Map" -             layout="topleft" -             left="0" -             name="world_map_btn" -             tool_tip="Shows/hides World Map" -             top="5" -             use_ellipses="true" -             width="80"> -                <init_callback -                 function="Button.SetFloaterToggle" -                 parameter="world_map" /> -            </bottomtray_button> -        </layout_panel> -        <layout_panel -         auto_resize="false" -         follows="left|right" -         height="28" -         layout="topleft" -         min_height="28" -         min_width="52" -         mouse_opaque="false" -         name="mini_map_btn_panel" -         user_resize="false" -         width="83"> -            <bottomtray_button -             follows="left|right" -             height="23" -             image_pressed="PushButton_Press" -             image_pressed_selected="PushButton_Selected_Press" -             image_selected="PushButton_Selected_Press" -             is_toggle="true" -             label="Mini-Map" -             layout="topleft" -             left="0" -             name="mini_map_btn" -             tool_tip="Shows/hides Mini-Map" -             top="5" -             use_ellipses="true" -             width="80"> -                <init_callback -                 function="Button.SetFloaterToggle" -                 parameter="mini_map" /> -            </bottomtray_button> -        </layout_panel> -        <layout_panel -         follows="left|right" -         height="30" -         layout="topleft" -         min_width="95" -         mouse_opaque="false" -         name="chiclet_list_panel" -         top="0" -         user_resize="false" -         width="189"> -<!--*NOTE: min_width of the chiclet_panel (chiclet_list) must be the same +     width="83"> +      <bottomtray_button +			  follows="left|right" +			  height="23" +			  image_pressed="PushButton_Press" +			  image_pressed_selected="PushButton_Selected_Press" +			  image_selected="PushButton_Selected_Press" +       is_toggle="true" +       label="Search" +			  layout="topleft" +			  left="0" +       name="search_btn" +       tool_tip="Shows/hides Search" +			  top="5" +			  use_ellipses="true" +       width="80"> +        <init_callback +         function="Button.SetFloaterToggle" +         parameter="search" /> +      </bottomtray_button> +    </layout_panel> +    <layout_panel +		   auto_resize="false" +     follows="left|right" +		   height="28" +		   layout="topleft" +		   min_height="28" +     min_width="52" +		   mouse_opaque="false" +     name="world_map_btn_panel" +		   user_resize="false" +     width="83"> +      <bottomtray_button +			  follows="left|right" +			  height="23" +			  image_pressed="PushButton_Press" +			  image_pressed_selected="PushButton_Selected_Press" +			  image_selected="PushButton_Selected_Press" +       is_toggle="true" +       label="Map" +			  layout="topleft" +			  left="0" +       name="world_map_btn" +       tool_tip="Shows/hides World Map" +			  top="5" +			  use_ellipses="true" +       width="80"> +        <init_callback +         function="Button.SetFloaterToggle" +         parameter="world_map" /> +      </bottomtray_button> +    </layout_panel> +    <layout_panel +		   auto_resize="false" +     follows="left|right" +		   height="28" +		   layout="topleft" +		   min_height="28" +     min_width="52" +		   mouse_opaque="false" +     name="mini_map_btn_panel" +		   user_resize="false" +     width="83"> +      <bottomtray_button +			  follows="left|right" +			  height="23" +			  image_pressed="PushButton_Press" +			  image_pressed_selected="PushButton_Selected_Press" +			  image_selected="PushButton_Selected_Press" +       is_toggle="true" +       label="Mini-Map" +			  layout="topleft" +			  left="0" +       name="mini_map_btn" +       tool_tip="Shows/hides Mini-Map" +			  top="5" +			  use_ellipses="true" +       width="80"> +        <init_callback +         function="Button.SetFloaterToggle" +         parameter="mini_map" /> +      </bottomtray_button> +    </layout_panel> +    <layout_panel +		   follows="left|right" +		   height="30" +		   layout="topleft" +		   min_width="95" +		   mouse_opaque="false" +		   name="chiclet_list_panel" +		   top="0" +		   user_resize="false" +		   width="189"> +      <!--*NOTE: min_width of the chiclet_panel (chiclet_list) must be the same  as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly. EXT-991--> -            <chiclet_panel +      <chiclet_panel               chiclet_padding="4"               follows="left|right"               height="24" @@ -389,7 +389,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.               name="chiclet_list"               top="7"               width="189"> -                <button +        <button                   auto_resize="true"                   follows="right"                   height="29" @@ -406,7 +406,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.                   top="-28"                   visible="false"                   width="7" /> -                <button +        <button                   auto_resize="true"                   follows="right"                   height="29" @@ -423,13 +423,13 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.                   top="-28"                   visible="false"                   width="7" /> -            </chiclet_panel> -        </layout_panel> -        <layout_panel auto_resize="false" -                      user_resize="false"  +      </chiclet_panel> +    </layout_panel> +    <layout_panel auto_resize="false" +                      user_resize="false"                        width="4"                        min_width="4"/> -        <layout_panel +    <layout_panel           auto_resize="false"           follows="right"           height="28" @@ -440,7 +440,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.           top="0"           user_resize="false"           width="37"> -            <chiclet_im_well +      <chiclet_im_well               follows="right"               height="28"               layout="topleft" @@ -449,7 +449,7 @@ as for parent layout_panel (chiclet_list_panel) to resize bottom tray properly.               name="im_well"               top="0"               width="35"> -             <!-- +        <!--  Emulate 4 states of button by background images, see details in EXT-3147. The same should be for notification_well button  xml attribute           Description  image_unselected        "Unlit" - there are no new messages @@ -457,7 +457,7 @@ image_selected          "Unlit" + "Selected" - there are no new messages and the  image_pressed           "Lit" - there are new messages  image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well is open               --> -                <button +        <button                   auto_resize="true"                   follows="right"                   halign="center" @@ -472,13 +472,13 @@ image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well                   name="Unread IM messages"                   tool_tip="Conversations"                   width="34"> -                    <init_callback +          <init_callback                       function="Button.SetDockableFloaterToggle"                       parameter="im_well_window" /> -                </button> -            </chiclet_im_well> -        </layout_panel> -        <layout_panel +        </button> +      </chiclet_im_well> +    </layout_panel> +    <layout_panel           auto_resize="false"           follows="right"           height="28" @@ -489,7 +489,7 @@ image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well           top="0"           user_resize="false"           width="37"> -            <chiclet_notification +      <chiclet_notification               follows="right"               height="23"               layout="topleft" @@ -498,7 +498,7 @@ image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well               name="notification_well"               top="5"               width="35"> -                <button +        <button                   auto_resize="true"                   bottom_pad="3"                   follows="right" @@ -514,17 +514,17 @@ image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well                   name="Unread"                   tool_tip="Notifications"                   width="34"> -                    <init_callback +          <init_callback                       function="Button.SetDockableFloaterToggle"                       parameter="notification_well_window" /> -                </button> -            </chiclet_notification> -        </layout_panel> -      <layout_panel -         auto_resize="false" -         user_resize="false"  -         min_width="4" -         name="DUMMY2" -         width="8" /> -    </layout_stack> +        </button> +      </chiclet_notification> +    </layout_panel> +    <layout_panel +		   auto_resize="false" +		   user_resize="false" +		   min_width="4" +		   name="DUMMY2" +		   width="8" /> +  </layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 8ac65cee91..51c15455bd 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3223,6 +3223,8 @@ If you continue to receive this message, contact the [SUPPORT_SITE].  		The session initialization is timed out  	</string> +  <string name="Home position set.">Home position set.</string> +      <string name="voice_morphing_url">http://secondlife.com/landing/voicemorphing</string>    <!-- Financial operations strings --> diff --git a/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml b/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml index 6040d24128..ea1d89c975 100644 --- a/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml +++ b/indra/newview/skins/default/xui/en/widgets/loading_indicator.xml @@ -3,6 +3,20 @@      follows="left|top"      mouse_opaque="false"      name="loading_indicator" -    rotations_per_sec="1.0" -    tab_stop="false" -/> +    images_per_sec="1.0" +    tab_stop="false"> +  <images> +    <image name="Progress_1"/> +    <image name="Progress_2"/> +    <image name="Progress_3"/> +    <image name="Progress_4"/> +    <image name="Progress_5"/> +    <image name="Progress_6"/> +    <image name="Progress_7"/> +    <image name="Progress_8"/> +    <image name="Progress_9"/> +    <image name="Progress_10"/> +    <image name="Progress_11"/> +    <image name="Progress_12"/> +  </images> +</loading_indicator>
\ No newline at end of file diff --git a/indra/newview/skins/minimal/xui/en/panel_bottomtray.xml b/indra/newview/skins/minimal/xui/en/panel_bottomtray.xml index d0a77e8c2a..e0c0bd13d9 100644 --- a/indra/newview/skins/minimal/xui/en/panel_bottomtray.xml +++ b/indra/newview/skins/minimal/xui/en/panel_bottomtray.xml @@ -59,8 +59,8 @@  			  follows="left|right"            />  		</layout_panel> -		<layout_panel -         auto_resize="false" +    <layout_panel +        auto_resize="false"           follows="right"           height="28"           layout="topleft" @@ -163,7 +163,7 @@  			layout="topleft"  			left="0"  			name="destination_btn" -			tool_tip="Shows destinations" +			tool_tip="Shows destinations window"  			top="5"  			is_toggle="true"  			use_ellipses="true" diff --git a/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml b/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml index 53def54aca..c3f46f11e0 100644 --- a/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml +++ b/indra/newview/skins/minimal/xui/en/panel_im_control_panel.xml @@ -23,5 +23,69 @@       orientation="vertical"       top_pad="5"       width="145"> +      <layout_panel +       auto_resize="false" +       follows="top|left|right" +       height="20" +       layout="topleft" +       left="2" +       min_height="20" +       width="140" +       name="view_profile_btn_panel" +       top="0" +       user_resize="false"> +        <button +         follows="left|top|right" +         height="23" +         label="Profile" +         name="view_profile_btn" +         top="0" +         width="140" /> +      </layout_panel> +      <layout_panel +       auto_resize="false" +       follows="top|left|right" +       height="25" +       layout="topleft" +       min_height="25" +       width="140" +       name="add_friend_btn_panel" +       user_resize="false"> +        <button +         follows="left|top|right" +         height="23" +         label="Add Friend" +         name="add_friend_btn" +         top="5" +         width="140" /> +      </layout_panel> +      <layout_panel +       auto_resize="false" +       follows="top|left|right" +       height="25" +       layout="topleft" +       min_height="25" +       width="140" +       name="teleport_btn_panel" +       user_resize="false"> +        <button +             auto_resize="false" +             follows="left|top|right" +             height="23" +             label="Teleport" +             name="teleport_btn" +             tool_tip = "Offer to teleport this person" +             width="140" /> +      </layout_panel> +      <layout_panel +       mouse_opaque="false" +       auto_resize="true" +       follows="top|left" +       height="0" +       layout="topleft" +       min_height="0" +       width="140" +       name="spacer" +       user_resize="false" />      </layout_stack>  </panel> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index f0b1973fdf..f671c770ea 100644 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -939,9 +939,9 @@ class Linux_i686Manifest(LinuxManifest):              self.path("libdb-5.1.so")              self.path("libdb-5.so")              self.path("libdb.so") -            self.path("libcrypto.so.0.9.8") +            self.path("libcrypto.so.1.0.0")              self.path("libexpat.so.1.5.2") -            self.path("libssl.so.0.9.8") +            self.path("libssl.so.1.0.0")              self.path("libuuid.so")              self.path("libuuid.so.16")              self.path("libuuid.so.16.0.22") diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp index 7164934b26..884b00f0cc 100644 --- a/indra/test_apps/llplugintest/llmediaplugintest.cpp +++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp @@ -2154,6 +2154,10 @@ void LLMediaPluginTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e  		}  		break; +		case MEDIA_EVENT_NAVIGATE_ERROR_PAGE: +			std::cerr <<  "Media event:  MEDIA_EVENT_NAVIGATE_ERROR_PAGE, uri is: " << self->getClickURL() << std::endl; +		break; +			  		case MEDIA_EVENT_CLICK_LINK_HREF:  		{  			std::cerr <<  "Media event:  MEDIA_EVENT_CLICK_LINK_HREF, uri is " << self->getClickURL() << ", target is " << self->getClickTarget() << std::endl; | 
