diff options
Diffstat (limited to 'indra')
254 files changed, 4359 insertions, 5412 deletions
diff --git a/indra/cmake/CARes.cmake b/indra/cmake/CARes.cmake index 8a2dc01561..1850b706ac 100644 --- a/indra/cmake/CARes.cmake +++ b/indra/cmake/CARes.cmake @@ -9,6 +9,7 @@ if (STANDALONE)    include(FindCARes)  else (STANDALONE)      use_prebuilt_binary(ares) +    add_definitions("-DCARES_STATICLIB")      if (WINDOWS)          set(CARES_LIBRARIES areslib)      elseif (DARWIN) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index faf9da8b14..89422fbdb2 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -19,7 +19,7 @@ if(WINDOWS)      set(vivox_src_dir "${CMAKE_SOURCE_DIR}/newview/vivox-runtime/i686-win32")      set(vivox_files          SLVoice.exe -	libsndfile-1.dll +        libsndfile-1.dll          vivoxplatform.dll          vivoxsdk.dll          ortp.dll @@ -167,6 +167,7 @@ elseif(DARWIN)          libexpat.dylib          libllqtwebkit.dylib          libndofdev.dylib +        libexception_handler.dylib         )      # fmod is statically linked on darwin @@ -216,6 +217,7 @@ elseif(LINUX)          libapr-1.so.0          libaprutil-1.so.0          libatk-1.0.so +        libbreakpad_client.so.0          libcrypto.so.0.9.7          libdb-4.2.so          libexpat.so diff --git a/indra/cmake/GoogleBreakpad.cmake b/indra/cmake/GoogleBreakpad.cmake new file mode 100644 index 0000000000..8270c0fabb --- /dev/null +++ b/indra/cmake/GoogleBreakpad.cmake @@ -0,0 +1,19 @@ +# -*- cmake -*- +include(Prebuilt) + +if (STANDALONE) +  MESSAGE(FATAL_ERROR "*TODO standalone support for google breakad is unimplemented") +  # *TODO - implement this include(FindGoogleBreakpad) +else (STANDALONE) +  use_prebuilt_binary(google_breakpad) +  if (DARWIN) +    set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES exception_handler) +  endif (DARWIN) +  if (LINUX) +    set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES breakpad_client) +  endif (LINUX) +  if (WINDOWS) +    set(BREAKPAD_EXCEPTION_HANDLER_LIBRARIES exception_handler crash_generation_client common) +  endif (WINDOWS) +endif (STANDALONE) + diff --git a/indra/linux_crash_logger/llcrashloggerlinux.cpp b/indra/linux_crash_logger/llcrashloggerlinux.cpp index 039b70ec4a..ce03ea0d6f 100644 --- a/indra/linux_crash_logger/llcrashloggerlinux.cpp +++ b/indra/linux_crash_logger/llcrashloggerlinux.cpp @@ -120,7 +120,6 @@ LLCrashLoggerLinux::~LLCrashLoggerLinux(void)  void LLCrashLoggerLinux::gatherPlatformSpecificFiles()  { -	mFileMap["CrashLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log").c_str();  }  bool LLCrashLoggerLinux::mainLoop() diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index b92ccd1d77..9f4c108dff 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -548,12 +548,11 @@ void LLAudioEngine::enableWind(bool enable)  {  	if (enable && (!mEnableWind))  	{ -		initWind(); -		mEnableWind = enable; +		mEnableWind = initWind();  	}  	else if (mEnableWind && (!enable))  	{ -		mEnableWind = enable; +		mEnableWind = false;  		cleanupWind();  	}  } diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index d287104204..5876cef4ea 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -195,7 +195,7 @@ protected:  	virtual LLAudioBuffer *createBuffer() = 0;  	virtual LLAudioChannel *createChannel() = 0; -	virtual void initWind() = 0; +	virtual bool initWind() = 0;  	virtual void cleanupWind() = 0;  	virtual void setInternalGain(F32 gain) = 0; diff --git a/indra/llaudio/llaudioengine_fmod.cpp b/indra/llaudio/llaudioengine_fmod.cpp index d7f58defca..7a8a04afa1 100644 --- a/indra/llaudio/llaudioengine_fmod.cpp +++ b/indra/llaudio/llaudioengine_fmod.cpp @@ -54,13 +54,12 @@ extern "C" {  	void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata);  } -FSOUND_DSPUNIT *gWindDSP = NULL; -  LLAudioEngine_FMOD::LLAudioEngine_FMOD()  {  	mInited = false;  	mWindGen = NULL; +	mWindDSP = NULL;  } @@ -258,10 +257,10 @@ void LLAudioEngine_FMOD::allocateListener(void)  void LLAudioEngine_FMOD::shutdown()  { -	if (gWindDSP) +	if (mWindDSP)  	{ -		FSOUND_DSP_SetActive(gWindDSP,false); -		FSOUND_DSP_Free(gWindDSP); +		FSOUND_DSP_SetActive(mWindDSP,false); +		FSOUND_DSP_Free(mWindDSP);  	}  	stopInternetStream(); @@ -289,29 +288,66 @@ LLAudioChannel * LLAudioEngine_FMOD::createChannel()  } -void LLAudioEngine_FMOD::initWind() +bool LLAudioEngine_FMOD::initWind()  { -	mWindGen = new LLWindGen<MIXBUFFERFORMAT>; +	if (!mWindGen) +	{ +		bool enable; +		 +		switch (FSOUND_GetMixer()) +		{ +			case FSOUND_MIXER_MMXP5: +			case FSOUND_MIXER_MMXP6: +			case FSOUND_MIXER_QUALITY_MMXP5: +			case FSOUND_MIXER_QUALITY_MMXP6: +				enable = (typeid(MIXBUFFERFORMAT) == typeid(S16)); +				break; +			case FSOUND_MIXER_BLENDMODE: +				enable = (typeid(MIXBUFFERFORMAT) == typeid(S32)); +				break; +			case FSOUND_MIXER_QUALITY_FPU: +				enable = (typeid(MIXBUFFERFORMAT) == typeid(F32)); +				break; +			default: +				// FSOUND_GetMixer() does not return a valid mixer type on Darwin +				LL_INFOS("AppInit") << "Unknown FMOD mixer type, assuming default" << LL_ENDL; +				enable = true; +				break; +		} +		 +		if (enable) +		{ +			mWindGen = new LLWindGen<MIXBUFFERFORMAT>(FSOUND_GetOutputRate()); +		} +		else +		{ +			LL_WARNS("AppInit") << "Incompatible FMOD mixer type, wind noise disabled" << LL_ENDL; +		} +	} + +	mNextWindUpdate = 0.0; -	if (!gWindDSP) +	if (mWindGen && !mWindDSP)  	{ -		gWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, mWindGen); +		mWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, mWindGen);  	} -	if (gWindDSP) +	if (mWindDSP)  	{ -		FSOUND_DSP_SetActive(gWindDSP, true); +		FSOUND_DSP_SetActive(mWindDSP, true); +		return true;  	} -	mNextWindUpdate = 0.0; +	 +	return false;  }  void LLAudioEngine_FMOD::cleanupWind()  { -	if (gWindDSP) +	if (mWindDSP)  	{ -		FSOUND_DSP_SetActive(gWindDSP, false); -		FSOUND_DSP_Free(gWindDSP); -		gWindDSP = NULL; +		FSOUND_DSP_SetActive(mWindDSP, false); +		FSOUND_DSP_Free(mWindDSP); +		mWindDSP = NULL;  	}  	delete mWindGen; @@ -740,30 +776,12 @@ void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int len  	// originalbuffer = fmod's original mixbuffer.  	// newbuffer = the buffer passed from the previous DSP unit.  	// length = length in samples at this mix time. -	// param = user parameter passed through in FSOUND_DSP_Create. -	// -	// modify the buffer in some fashion +	// userdata = user parameter passed through in FSOUND_DSP_Create.  	LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *windgen =  		(LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *)userdata; -	U8 stride; - -#if LL_DARWIN -	stride = sizeof(LLAudioEngine_FMOD::MIXBUFFERFORMAT); -#else -	int mixertype = FSOUND_GetMixer(); -	if (mixertype == FSOUND_MIXER_BLENDMODE || -	    mixertype == FSOUND_MIXER_QUALITY_FPU) -	{ -		stride = 4; -	} -	else -	{ -		stride = 2; -	} -#endif - -	newbuffer = windgen->windGenerate((LLAudioEngine_FMOD::MIXBUFFERFORMAT *)newbuffer, length, stride); +	 +	newbuffer = windgen->windGenerate((LLAudioEngine_FMOD::MIXBUFFERFORMAT *)newbuffer, length);  	return newbuffer;  } diff --git a/indra/llaudio/llaudioengine_fmod.h b/indra/llaudio/llaudioengine_fmod.h index 3968657cba..0e386a3884 100644 --- a/indra/llaudio/llaudioengine_fmod.h +++ b/indra/llaudio/llaudioengine_fmod.h @@ -55,15 +55,15 @@ public:  	virtual void shutdown(); -	/*virtual*/ void initWind(); +	/*virtual*/ bool initWind();  	/*virtual*/ void cleanupWind();  	/*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water);  #if LL_DARWIN -        typedef S32 MIXBUFFERFORMAT; +	typedef S32 MIXBUFFERFORMAT;  #else -        typedef S16 MIXBUFFERFORMAT; +	typedef S16 MIXBUFFERFORMAT;  #endif  protected: @@ -83,6 +83,7 @@ protected:  	void* mUserData;  	LLWindGen<MIXBUFFERFORMAT> *mWindGen; +	FSOUND_DSPUNIT *mWindDSP;  }; diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp index a5982ccbd6..887c791790 100644 --- a/indra/llaudio/llaudioengine_openal.cpp +++ b/indra/llaudio/llaudioengine_openal.cpp @@ -370,7 +370,7 @@ U32 LLAudioBufferOpenAL::getLength()  // ------------ -void LLAudioEngine_OpenAL::initWind() +bool LLAudioEngine_OpenAL::initWind()  {  	ALenum error;  	llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl; @@ -397,10 +397,12 @@ void LLAudioEngine_OpenAL::initWind()  	if(mWindBuf==NULL)  	{  		llerrs << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << llendl; -		mEnableWind=false; +		return false;  	}  	llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl; + +	return true;  }  void LLAudioEngine_OpenAL::cleanupWind() @@ -508,14 +510,14 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude)  		alGenBuffers(1,&buffer);  		if((error=alGetError()) != AL_NO_ERROR)  		{ -			llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << llendl; +			llwarns << "LLAudioEngine_OpenAL::updateWind() Error creating wind buffer: " << error << llendl;  			break;  		}  		alBufferData(buffer,  			     AL_FORMAT_STEREO16,  			     mWindGen->windGenerate(mWindBuf, -						    mWindBufSamples, 2), +						    mWindBufSamples),  			     mWindBufBytes,  			     mWindBufFreq);  		error = alGetError(); diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h index 5aca03e195..16125b2476 100644 --- a/indra/llaudio/llaudioengine_openal.h +++ b/indra/llaudio/llaudioengine_openal.h @@ -57,23 +57,23 @@ class LLAudioEngine_OpenAL : public LLAudioEngine  		LLAudioBuffer* createBuffer();  		LLAudioChannel* createChannel(); -		/*virtual*/ void initWind(); +		/*virtual*/ bool initWind();  		/*virtual*/ void cleanupWind();  		/*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude);  	private:  		void * windDSP(void *newbuffer, int length); -	        typedef S16 WIND_SAMPLE_T; -        	LLWindGen<WIND_SAMPLE_T> *mWindGen; -        	S16 *mWindBuf; -        	U32 mWindBufFreq; -        	U32 mWindBufSamples; -        	U32 mWindBufBytes; -        	ALuint mWindSource; -	        int mNumEmptyWindALBuffers; - -        	static const int MAX_NUM_WIND_BUFFERS = 80; -        	static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec +        typedef S16 WIND_SAMPLE_T; +    	LLWindGen<WIND_SAMPLE_T> *mWindGen; +    	S16 *mWindBuf; +    	U32 mWindBufFreq; +    	U32 mWindBufSamples; +    	U32 mWindBufBytes; +    	ALuint mWindSource; +        int mNumEmptyWindALBuffers; + +    	static const int MAX_NUM_WIND_BUFFERS = 80; +    	static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec  };  class LLAudioChannelOpenAL : public LLAudioChannel diff --git a/indra/llaudio/llwindgen.h b/indra/llaudio/llwindgen.h index 847bfa6e9d..1908b2545f 100644 --- a/indra/llaudio/llwindgen.h +++ b/indra/llaudio/llwindgen.h @@ -33,104 +33,149 @@  #define WINDGEN_H  #include "llcommon.h" -#include "llrand.h"  template <class MIXBUFFERFORMAT_T>  class LLWindGen  {  public: -	LLWindGen() : +	LLWindGen(const U32 sample_rate = 44100) :  		mTargetGain(0.f),  		mTargetFreq(100.f),  		mTargetPanGainR(0.5f), -		mbuf0(0.0), -		mbuf1(0.0), -		mbuf2(0.0), -		mbuf3(0.0), -		mbuf4(0.0), -		mbuf5(0.0), -		mY0(0.0), -		mY1(0.0), +		mInputSamplingRate(sample_rate), +		mSubSamples(2), +		mFilterBandWidth(50.f), +		mBuf0(0.0f), +		mBuf1(0.0f), +		mBuf2(0.0f), +		mY0(0.0f), +		mY1(0.0f),  		mCurrentGain(0.f),  		mCurrentFreq(100.f), -		mCurrentPanGainR(0.5f) {}; - -	static const U32 getInputSamplingRate() {return mInputSamplingRate;} +		mCurrentPanGainR(0.5f) +	{ +		mSamplePeriod = (F32)mSubSamples / (F32)mInputSamplingRate; +		mB2 = expf(-F_TWO_PI * mFilterBandWidth * mSamplePeriod); +	} +	const U32 getInputSamplingRate() { return mInputSamplingRate; } +	  	// newbuffer = the buffer passed from the previous DSP unit.  	// numsamples = length in samples-per-channel at this mix time. -	// stride = number of bytes between start of each sample.  	// NOTE: generates L/R interleaved stereo -	MIXBUFFERFORMAT_T* windGenerate(MIXBUFFERFORMAT_T *newbuffer, int numsamples, int stride) +	MIXBUFFERFORMAT_T* windGenerate(MIXBUFFERFORMAT_T *newbuffer, int numsamples)  	{ -		U8 *cursamplep = (U8*)newbuffer; +		MIXBUFFERFORMAT_T *cursamplep = newbuffer; +		 +		// Filter coefficients +		F32 a0 = 0.0f, b1 = 0.0f; -		double bandwidth = 50.0F; -		double a0,b1,b2; +		// No need to clip at normal volumes +		bool clip = mCurrentGain > 2.0f; -		// calculate resonant filter coeffs -		b2 = exp(-(F_TWO_PI) * (bandwidth / mInputSamplingRate)); +		bool interp_freq = false;  -		while (numsamples--) +		//if the frequency isn't changing much, we don't need to interpolate in the inner loop +		if (llabs(mTargetFreq - mCurrentFreq) < (mCurrentFreq * 0.112))  		{ -			mCurrentFreq = (float)((0.999 * mCurrentFreq) + (0.001 * mTargetFreq)); -			mCurrentGain = (float)((0.999 * mCurrentGain) + (0.001 * mTargetGain)); -			mCurrentPanGainR = (float)((0.999 * mCurrentPanGainR) + (0.001 * mTargetPanGainR)); -			b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (mCurrentFreq / mInputSamplingRate)); -			a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2)); -			double nextSample; +			// calculate resonant filter coefficients +			mCurrentFreq = mTargetFreq; +			b1 = (-4.0f * mB2) / (1.0f + mB2) * cosf(F_TWO_PI * (mCurrentFreq * mSamplePeriod)); +			a0 = (1.0f - mB2) * sqrtf(1.0f - (b1 * b1) / (4.0f * mB2)); +		} +		else +		{ +			interp_freq = true; +		} +		 +		while (numsamples) +		{ +			F32 next_sample; +			 +			// Start with white noise +			// This expression is fragile, rearrange it and it will break! +			next_sample = (F32)rand() * (1.0f / (F32)(RAND_MAX / (U16_MAX / 8))) + (F32)(S16_MIN / 8); -			// start with white noise -			nextSample = ll_frand(2.0f) - 1.0f; +			// Apply a pinking filter +			// Magic numbers taken from PKE method at http://www.firstpr.com.au/dsp/pink-noise/ +			mBuf0 = mBuf0 * 0.99765f + next_sample * 0.0990460f; +			mBuf1 = mBuf1 * 0.96300f + next_sample * 0.2965164f; +			mBuf2 = mBuf2 * 0.57000f + next_sample * 1.0526913f; -			// apply pinking filter -			mbuf0 = 0.997f * mbuf0 + 0.0126502f * nextSample;  -			mbuf1 = 0.985f * mbuf1 + 0.0139083f * nextSample; -			mbuf2 = 0.950f * mbuf2 + 0.0205439f * nextSample; -			mbuf3 = 0.850f * mbuf3 + 0.0387225f * nextSample; -			mbuf4 = 0.620f * mbuf4 + 0.0465932f * nextSample; -			mbuf5 = 0.250f * mbuf5 + 0.1093477f * nextSample; +			next_sample = mBuf0 + mBuf1 + mBuf2 + next_sample * 0.1848f; -			nextSample = mbuf0 + mbuf1 + mbuf2 + mbuf3 + mbuf4 + mbuf5; +			if (interp_freq) +			{ +				// calculate and interpolate resonant filter coefficients +				mCurrentFreq = (0.999f * mCurrentFreq) + (0.001f * mTargetFreq); +				b1 = (-4.0f * mB2) / (1.0f + mB2) * cosf(F_TWO_PI * (mCurrentFreq * mSamplePeriod)); +				a0 = (1.0f - mB2) * sqrtf(1.0f - (b1 * b1) / (4.0f * mB2)); +			} -			// do a resonant filter on the noise -			nextSample = (double)( a0 * nextSample - b1 * mY0 - b2 * mY1 ); +			// Apply a resonant low-pass filter on the pink noise +	        next_sample = a0 * next_sample - b1 * mY0 - mB2 * mY1;  			mY1 = mY0; -			mY0 = nextSample; +			mY0 = next_sample; -			nextSample *= mCurrentGain; +			mCurrentGain = (0.999f * mCurrentGain) + (0.001f * mTargetGain); +			mCurrentPanGainR = (0.999f * mCurrentPanGainR) + (0.001f * mTargetPanGainR); -			MIXBUFFERFORMAT_T	sample; +			// For a 3dB pan law use: +			// next_sample *= mCurrentGain * ((mCurrentPanGainR*(mCurrentPanGainR-1)*1.652+1.413); +		    next_sample *= mCurrentGain; -			sample = llfloor(((F32)nextSample*32768.f*(1.0f - mCurrentPanGainR))+0.5f); -			*(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767); -			cursamplep += stride; - -			sample = llfloor(((F32)nextSample*32768.f*mCurrentPanGainR)+0.5f); -			*(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767); -			cursamplep += stride; +			// delta is used to interpolate between synthesized samples +			F32 delta = (next_sample - mLastSample) / (F32)mSubSamples; +			 +			// Fill the audio buffer, clipping if necessary +			for (U8 i=mSubSamples; i && numsamples; --i, --numsamples)  +			{ +				mLastSample = mLastSample + delta; +				S32	sample_right = (S32)(mLastSample * mCurrentPanGainR); +				S32	sample_left = (S32)mLastSample - sample_right; +				 +				if (!clip) +				{ +					*cursamplep = (MIXBUFFERFORMAT_T)sample_left; +					++cursamplep; +					*cursamplep = (MIXBUFFERFORMAT_T)sample_right; +					++cursamplep; +				} +				else +				{ +					*cursamplep = (MIXBUFFERFORMAT_T)llclamp(sample_left, (S32)S16_MIN, (S32)S16_MAX); +					++cursamplep; +					*cursamplep = (MIXBUFFERFORMAT_T)llclamp(sample_right, (S32)S16_MIN, (S32)S16_MAX); +					++cursamplep; +				} +			}  		}  		return newbuffer;  	} - +	 +public:  	F32 mTargetGain;  	F32 mTargetFreq;  	F32 mTargetPanGainR; - +	  private: -	static const U32 mInputSamplingRate = 44100; -	F64 mbuf0; -	F64 mbuf1; -	F64 mbuf2; -	F64 mbuf3; -	F64 mbuf4; -	F64 mbuf5; -	F64 mY0; -	F64 mY1; +	U32 mInputSamplingRate; +	U8  mSubSamples; +	F32 mSamplePeriod; +	F32 mFilterBandWidth; +	F32 mB2; +	 +	F32 mBuf0; +	F32 mBuf1; +	F32 mBuf2; +	F32 mY0; +	F32 mY1; +	  	F32 mCurrentGain;  	F32 mCurrentFreq;  	F32 mCurrentPanGainR; +	F32 mLastSample;  };  #endif diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 3c689930b8..2a036df06e 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -9,6 +9,7 @@ include(Linking)  include(Boost)  include(Pth)  include(LLSharedLibs) +include(GoogleBreakpad)  include(GooglePerfTools)  include(Copy3rdPartyLibs) @@ -232,7 +233,6 @@ set(llcommon_HEADER_FILES      metaclasst.h      metaproperty.h      metapropertyt.h -    processor.h      reflective.h      reflectivet.h      roles_constants.h @@ -259,6 +259,7 @@ endif(LLCOMMON_LINK_SHARED)  target_link_libraries(      llcommon +    ${BREAKPAD_EXCEPTION_HANDLER_LIBRARIES}      ${APRUTIL_LIBRARIES}      ${APR_LIBRARIES}      ${EXPAT_LIBRARIES} @@ -290,6 +291,7 @@ if (LL_TESTS)    LL_ADD_INTEGRATION_TEST(llframetimer "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(llinstancetracker "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(lllazy "" "${test_libs}") +  LL_ADD_INTEGRATION_TEST(llprocessor "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(llrand "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(llsdserialize "" "${test_libs}")    LL_ADD_INTEGRATION_TEST(llstring "" "${test_libs}") diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 6b2d1b7c20..eedec0b24e 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -30,6 +30,8 @@   * $/LicenseInfo$   */ +#include <cstdlib> +  #include "linden_common.h"  #include "llapp.h" @@ -41,8 +43,11 @@  #include "lllivefile.h"  #include "llmemory.h"  #include "llstl.h" // for DeletePointer() +#include "llstring.h"  #include "lleventtimer.h" +#include "google_breakpad/exception_handler.h" +  //  // Signal handling  // @@ -51,11 +56,22 @@  #if LL_WINDOWS  LONG WINAPI default_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop);  BOOL ConsoleCtrlHandler(DWORD fdwCtrlType); +bool windows_post_minidump_callback(const wchar_t* dump_path, +									const wchar_t* minidump_id, +									void* context, +									EXCEPTION_POINTERS* exinfo, +									MDRawAssertionInfo* assertion, +									bool succeeded);  #else  # include <signal.h>  # include <unistd.h> // for fork()  void setup_signals();  void default_unix_signal_handler(int signum, siginfo_t *info, void *); + +// Called by breakpad exception handler after the minidump has been generated. +bool unix_post_minidump_callback(const char *dump_dir, +					  const char *minidump_id, +					  void *context, bool succeeded);  # if LL_DARWIN  /* OSX doesn't support SIGRT* */  S32 LL_SMACKDOWN_SIGNAL = SIGUSR1; @@ -81,7 +97,6 @@ BOOL LLApp::sLogInSignal = FALSE;  // static  LLApp::EAppStatus LLApp::sStatus = LLApp::APP_STATUS_STOPPED; // Keeps track of application status  LLAppErrorHandler LLApp::sErrorHandler = NULL; -LLAppErrorHandler LLApp::sSyncErrorHandler = NULL;  BOOL LLApp::sErrorThreadRunning = FALSE;  #if !LL_WINDOWS  LLApp::child_map LLApp::sChildMap; @@ -123,7 +138,12 @@ void LLApp::commonCtor()  	// Set the application to this instance.  	sApplication = this; - +	 +	mExceptionHandler = 0; +	 +	// initialize the buffer to write the minidump filename to +	// (this is used to avoid allocating memory in the crash handler) +	memset(minidump_path, 0, MAX_MINDUMP_PATH_LENGTH);  }  LLApp::LLApp(LLErrorThread *error_thread) : @@ -152,6 +172,8 @@ LLApp::~LLApp()  		delete mThreadErrorp;  		mThreadErrorp = NULL;  	} +	 +	if(mExceptionHandler != 0) delete mExceptionHandler;  	LLCommon::cleanupClass();  } @@ -262,19 +284,18 @@ void LLApp::setupErrorHandling()  	// occasionally checks to see if the app is in an error state, and sees if it needs to be run.  #if LL_WINDOWS -	// Windows doesn't have the same signal handling mechanisms as UNIX, thus APR doesn't provide -	// a signal handling thread implementation. -	// What we do is install an unhandled exception handler, which will try to do the right thing -	// in the case of an error (generate a minidump) - -	// Disable this until the viewer gets ported so server crashes can be JIT debugged. -	//LPTOP_LEVEL_EXCEPTION_FILTER prev_filter; -	//prev_filter = SetUnhandledExceptionFilter(default_windows_exception_handler); -  	// This sets a callback to handle w32 signals to the console window.  	// The viewer shouldn't be affected, sicne its a windowed app.  	SetConsoleCtrlHandler( (PHANDLER_ROUTINE) ConsoleCtrlHandler, TRUE); +	// Install the Google Breakpad crash handler for Windows +	if(mExceptionHandler == 0) +	{ +		llwarns << "adding breakpad exception handler" << llendl; +		mExceptionHandler = new google_breakpad::ExceptionHandler( +			L"C:\\Temp\\", 0, windows_post_minidump_callback, 0, google_breakpad::ExceptionHandler::HANDLER_ALL); +	} +  #else  	//  	// Start up signal handling. @@ -282,9 +303,14 @@ void LLApp::setupErrorHandling()  	// There are two different classes of signals.  Synchronous signals are delivered to a specific  	// thread, asynchronous signals can be delivered to any thread (in theory)  	// -  	setup_signals(); - +	 +	// Add google breakpad exception handler configured for Darwin/Linux. +	if(mExceptionHandler == 0) +	{ +		std::string dumpPath = "/tmp/"; +		mExceptionHandler = new google_breakpad::ExceptionHandler(dumpPath, 0, &unix_post_minidump_callback, 0, true); +	}  #endif  	startErrorThread(); @@ -310,21 +336,6 @@ void LLApp::setErrorHandler(LLAppErrorHandler handler)  	LLApp::sErrorHandler = handler;  } - -void LLApp::setSyncErrorHandler(LLAppErrorHandler handler) -{ -	LLApp::sSyncErrorHandler = handler; -} - -// static -void LLApp::runSyncErrorHandler() -{ -	if (LLApp::sSyncErrorHandler) -	{ -		LLApp::sSyncErrorHandler(); -	} -} -  // static  void LLApp::runErrorHandler()  { @@ -337,7 +348,6 @@ void LLApp::runErrorHandler()  	LLApp::setStopped();  } -  // static  void LLApp::setStatus(EAppStatus status)  { @@ -348,15 +358,27 @@ void LLApp::setStatus(EAppStatus status)  // static  void LLApp::setError()  { -	if (!isError()) -	{ -		// perform any needed synchronous error-handling -		runSyncErrorHandler(); -		// set app status to ERROR so that the LLErrorThread notices -		setStatus(APP_STATUS_ERROR); -	} +	// set app status to ERROR so that the LLErrorThread notices +	setStatus(APP_STATUS_ERROR);  } +void LLApp::setMiniDumpDir(const std::string &path) +{ +	llassert(mExceptionHandler); +#ifdef LL_WINDOWS +	wchar_t buffer[MAX_MINDUMP_PATH_LENGTH]; +	mbstowcs(buffer, path.c_str(), MAX_MINDUMP_PATH_LENGTH); +	mExceptionHandler->set_dump_path(std::wstring(buffer)); +#else +	mExceptionHandler->set_dump_path(path); +#endif +} + +void LLApp::writeMiniDump() +{ +	llassert(mExceptionHandler); +	mExceptionHandler->WriteMinidump(); +}  // static  void LLApp::setQuitting() @@ -587,6 +609,7 @@ void setup_signals()  	// Asynchronous signals that result in core  	sigaction(SIGQUIT, &act, NULL); +	  }  void clear_signals() @@ -765,4 +788,97 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)  	}  } +bool unix_post_minidump_callback(const char *dump_dir, +					  const char *minidump_id, +					  void *context, bool succeeded) +{ +	// Copy minidump file path into fixed buffer in the app instance to avoid +	// heap allocations in a crash handler. +	 +	// path format: <dump_dir>/<minidump_id>.dmp +	int dirPathLength = strlen(dump_dir); +	int idLength = strlen(minidump_id); +	 +	// The path must not be truncated. +	llassert((dirPathLength + idLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH); +	 +	char * path = LLApp::instance()->getMiniDumpFilename(); +	S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; +	strncpy(path, dump_dir, remaining); +	remaining -= dirPathLength; +	path += dirPathLength; +	if (remaining > 0 && dirPathLength > 0 && path[-1] != '/') +	{ +		*path++ = '/'; +		--remaining; +	} +	if (remaining > 0) +	{ +		strncpy(path, minidump_id, remaining); +		remaining -= idLength; +		path += idLength; +		strncpy(path, ".dmp", remaining); +	} +	 +	llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl; +	LLApp::runErrorHandler(); +	return true; +}  #endif // !WINDOWS + +#ifdef LL_WINDOWS +bool windows_post_minidump_callback(const wchar_t* dump_path, +									const wchar_t* minidump_id, +									void* context, +									EXCEPTION_POINTERS* exinfo, +									MDRawAssertionInfo* assertion, +									bool succeeded) +{ +	char * path = LLApp::instance()->getMiniDumpFilename(); +	S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; +	size_t bytesUsed; + +	bytesUsed = wcstombs(path, dump_path, static_cast<size_t>(remaining)); +	remaining -= bytesUsed; +	path += bytesUsed; +	if(remaining > 0 && bytesUsed > 0 && path[-1] != '\\') +	{ +		*path++ = '\\'; +		--remaining; +	} +	if(remaining > 0) +	{ +		bytesUsed = wcstombs(path, minidump_id, static_cast<size_t>(remaining)); +		remaining -= bytesUsed; +		path += bytesUsed; +	} +	if(remaining > 0) +	{ +		strncpy(path, ".dmp", remaining); +	} + +	llinfos << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << llendl; +    // *NOTE:Mani - this code is stolen from LLApp, where its never actually used. +	//OSMessageBox("Attach Debugger Now", "Error", OSMB_OK); +    // *TODO: Translate the signals/exceptions into cross-platform stuff +	// Windows implementation +	llinfos << "Entering Windows Exception Handler..." << llendl; + +	if (LLApp::isError()) +	{ +		llwarns << "Got another fatal signal while in the error handler, die now!" << llendl; +	} + +	// Flag status to error, so thread_error starts its work +	LLApp::setError(); + +	// Block in the exception handler until the app has stopped +	// This is pretty sketchy, but appears to work just fine +	while (!LLApp::isStopped()) +	{ +		ms_sleep(10); +	} + +	return true; +} +#endif diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index e5b8edf9c3..fef05a7939 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -66,6 +66,10 @@ public:  };  #endif +namespace google_breakpad { +	class ExceptionHandler; // See exception_handler.h +} +  class LL_COMMON_API LLApp : public LLOptionInterface  {  	friend class LLErrorThread; @@ -227,8 +231,20 @@ public:  	void setupErrorHandling();  	void setErrorHandler(LLAppErrorHandler handler); -	void setSyncErrorHandler(LLAppErrorHandler handler); +	static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred.  	//@} +	 +	// the maximum length of the minidump filename returned by getMiniDumpFilename() +	static const U32 MAX_MINDUMP_PATH_LENGTH = 256; + +	// change the directory where Breakpad minidump files are written to +	void setMiniDumpDir(const std::string &path); + +	// Return the Google Breakpad minidump filename after a crash. +	char *getMiniDumpFilename() { return minidump_path; } + +	// Write out a Google Breakpad minidump file. +	void writeMiniDump();  #if !LL_WINDOWS  	// @@ -286,15 +302,14 @@ protected:  private:  	void startErrorThread(); -	static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred. -	static void runSyncErrorHandler(); // run IMMEDIATELY when we get an error, ran in the context of the faulting thread. +	// Contains the filename of the minidump file after a crash. +	char minidump_path[MAX_MINDUMP_PATH_LENGTH];  	// *NOTE: On Windows, we need a routine to reset the structured  	// exception handler when some evil driver has taken it over for  	// their own purposes  	typedef int(*signal_handler_func)(int signum);  	static LLAppErrorHandler sErrorHandler; -	static LLAppErrorHandler sSyncErrorHandler;  	// Default application threads  	LLErrorThread* mThreadErrorp;		// Waits for app to go to status ERROR, then runs the error callback @@ -315,6 +330,8 @@ private:  private:  	// the static application instance if it was created.  	static LLApp* sApplication; +	 +	google_breakpad::ExceptionHandler * mExceptionHandler;  #if !LL_WINDOWS diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp index de7f2ead74..a7ef28b431 100644 --- a/indra/llcommon/lldate.cpp +++ b/indra/llcommon/lldate.cpp @@ -248,8 +248,27 @@ bool LLDate::fromStream(std::istream& s)  		s >> fractional;  		seconds_since_epoch += fractional;  	} -	c = s.get(); // skip the Z -	if (c != 'Z') { return false; } + +	c = s.peek(); // check for offset +	if (c == '+' || c == '-') +	{ +		S32 offset_sign = (c == '+') ? 1 : -1; +		S32 offset_hours = 0; +		S32 offset_minutes = 0; +		S32 offset_in_seconds = 0; + +		s >> offset_hours; + +		c = s.get(); // skip the colon a get the minutes if there are any +		if (c == ':') +		{		 +			s >> offset_minutes; +		} +		 +		offset_in_seconds =  (offset_hours * 60 + offset_sign * offset_minutes) * 60; +		seconds_since_epoch -= offset_in_seconds; +	} +	else if (c != 'Z') { return false; } // skip the Z  	mSecondsSinceEpoch = seconds_since_epoch;  	return true; diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp index f39a4e6619..20727dd76e 100644 --- a/indra/llcommon/llfasttimer_class.cpp +++ b/indra/llcommon/llfasttimer_class.cpp @@ -238,7 +238,7 @@ U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer  #else // windows or x86-mac or x86-linux or x86-solaris  U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer  { -	static U64 sCPUClockFrequency = U64(CProcessor().GetCPUFrequency(50)); +	static U64 sCPUClockFrequency = U64(LLProcessorInfo().getCPUFrequency());  	// we drop the low-order byte in our timers, so report a lower frequency  	return sCPUClockFrequency >> 8; diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp index f6ab55a6b5..d3ba215751 100644 --- a/indra/llcommon/llprocessor.cpp +++ b/indra/llcommon/llprocessor.cpp @@ -30,139 +30,389 @@   * $/LicenseInfo$   */ -// Filename: Processor.cpp -// ======================= -// Author: Benjamin Jurke -// File history: 27.02.2002  - File created. Support for Intel and AMD processors -//               05.03.2002  - Fixed the CPUID bug: On Pre-Pentium CPUs the CPUID -//                             command is not available -//                           - The CProcessor::WriteInfoTextFile function do not  -//                             longer use Win32 file functions (-> os independend) -//                           - Optional include of the windows.h header which is -//                             still need for CProcessor::GetCPUFrequency. -//               06.03.2002  - My birthday (18th :-)) -//                           - Replaced the '\r\n' line endings in function  -//                             CProcessor::CPUInfoToText by '\n' -//                           - Replaced unsigned __int64 by signed __int64 for -//                             solving some compiler conversion problems -//                           - Fixed a bug at family=6, model=6 (Celeron -> P2) -////////////////////////////////////////////////////////////////////////////////// -  #include "linden_common.h" +#include "llprocessor.h" -#include "processor.h" +#include "llerror.h" -#include <memory> +//#include <memory>  #if LL_WINDOWS  #	define WIN32_LEAN_AND_MEAN  #	include <winsock2.h>  #	include <windows.h> +#	define _interlockedbittestandset _renamed_interlockedbittestandset +#	define _interlockedbittestandreset _renamed_interlockedbittestandreset +#	include <intrin.h> +#	undef _interlockedbittestandset +#	undef _interlockedbittestandreset  #endif -#if LL_LINUX -#include "llsys.h" -#endif // LL_LINUX +#include "llsd.h" + +#if LL_MSVC && _M_X64 +#      define LL_X86_64 1 +#      define LL_X86 1 +#elif LL_MSVC && _M_IX86 +#      define LL_X86 1 +#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) ) +#      define LL_X86_64 1 +#      define LL_X86 1 +#elif LL_GNUC && ( defined(__i386__) ) +#      define LL_X86 1 +#elif LL_GNUC && ( defined(__powerpc__) || defined(__ppc__) ) +#      define LL_PPC 1 +#endif + +class LLProcessorInfoImpl; // foward declaration for the mImpl; + +namespace  +{ +	enum cpu_info +	{ +		eBrandName = 0, +		eFrequency, +		eVendor, +		eStepping, +		eFamily, +		eExtendedFamily, +		eModel, +		eExtendedModel, +		eType, +		eBrandID, +		eFamilyName +	}; +		 + +	const char* cpu_info_names[] =  +	{ +		"Processor Name", +		"Frequency", +		"Vendor", +		"Stepping", +		"Family", +		"Extended Family", +		"Model", +		"Extended Model", +		"Type", +		"Brand ID", +		"Family Name" +	}; + +	enum cpu_config +	{ +		eMaxID, +		eMaxExtID, +		eCLFLUSHCacheLineSize, +		eAPICPhysicalID, +		eCacheLineSize, +		eL2Associativity, +		eCacheSizeK, +		eFeatureBits, +		eExtFeatureBits +	}; + +	const char* cpu_config_names[] = +	{ +		"Max Supported CPUID level", +		"Max Supported Ext. CPUID level", +		"CLFLUSH cache line size", +		"APIC Physical ID", +		"Cache Line Size",  +		"L2 Associativity", +		"Cache Size", +		"Feature Bits", +		"Ext. Feature Bits" +	}; -#if !LL_DARWIN && !LL_SOLARIS -#ifdef PROCESSOR_FREQUENCY_MEASURE_AVAILABLE -// We need the QueryPerformanceCounter and Sleep functions -#define FORCEINLINE __forceinline -#else -#define FORCEINLINE  -#endif +	// *NOTE:Mani - this contains the elements we reference directly and extensions beyond the first 32. +	// The rest of the names are referenced by bit maks returned from cpuid. +	enum cpu_features  +	{ +		eSSE_Ext=25, +		eSSE2_Ext=26, + +		eSSE3_Features=32, +		eMONTIOR_MWAIT=33, +		eCPLDebugStore=34, +		eThermalMonitor2=35, +		eAltivec=36 +	}; -// Some macros we often need -//////////////////////////// -#define CheckBit(var, bit)   ((var & (1 << bit)) ? true : false) +	const char* cpu_feature_names[] = +	{ +		"x87 FPU On Chip", +		"Virtual-8086 Mode Enhancement", +		"Debugging Extensions", +		"Page Size Extensions", +		"Time Stamp Counter", +		"RDMSR and WRMSR Support", +		"Physical Address Extensions", +		"Machine Check Exception", +		"CMPXCHG8B Instruction", +		"APIC On Chip", +		"Unknown1", +		"SYSENTER and SYSEXIT", +		"Memory Type Range Registers", +		"PTE Global Bit", +		"Machine Check Architecture", +		"Conditional Move/Compare Instruction", +		"Page Attribute Table", +		"Page Size Extension", +		"Processor Serial Number", +		"CFLUSH Extension", +		"Unknown2", +		"Debug Store", +		"Thermal Monitor and Clock Ctrl", +		"MMX Technology", +		"FXSAVE/FXRSTOR", +		"SSE Extensions", +		"SSE2 Extensions", +		"Self Snoop", +		"Hyper-threading Technology", +		"Thermal Monitor", +		"Unknown4", +		"Pend. Brk. EN.", // 31 End of FeatureInfo bits + +		"SSE3 New Instructions", // 32 +		"MONITOR/MWAIT",  +		"CPL Qualified Debug Store", +		"Thermal Monitor 2", + +		"Altivec" +	}; + +	std::string intel_CPUFamilyName(int composed_family)  +	{ +		switch(composed_family) +		{ +		case 3: return "Intel i386"; +		case 4: return "Intel i486"; +		case 5: return "Intel Pentium"; +		case 6: return "Intel Pentium Pro/2/3, Core"; +		case 7: return "Intel Itanium (IA-64)"; +		case 0xF: return "Intel Pentium 4"; +		case 0x10: return "Intel Itanium 2 (IA-64)"; +		} +		return "Unknown"; +	} +	 +	std::string amd_CPUFamilyName(int composed_family)  +	{ +		switch(composed_family) +		{ +		case 4: return "AMD 80486/5x86"; +		case 5: return "AMD K5/K6"; +		case 6: return "AMD K7"; +		case 0xF: return "AMD K8"; +		case 0x10: return "AMD K8L"; +		} +   		return "Unknown"; +	} + +	std::string compute_CPUFamilyName(const char* cpu_vendor, int composed_family)  +	{ +		const char* intel_string = "GenuineIntel"; +		const char* amd_string = "AuthenticAMD"; +		if(!strncmp(cpu_vendor, intel_string, strlen(intel_string))) +		{ +			return intel_CPUFamilyName(composed_family); +		} +		else if(!strncmp(cpu_vendor, amd_string, strlen(amd_string))) +		{ +			return amd_CPUFamilyName(composed_family); +		} +		return "Unknown"; +	} + +	std::string compute_CPUFamilyName(const char* cpu_vendor, int family, int ext_family)  +	{ +		const char* intel_string = "GenuineIntel"; +		const char* amd_string = "AuthenticAMD"; +		if(!strncmp(cpu_vendor, intel_string, strlen(intel_string))) +		{ +			U32 composed_family = family + ext_family; +			return intel_CPUFamilyName(composed_family); +		} +		else if(!strncmp(cpu_vendor, amd_string, strlen(amd_string))) +		{ +			U32 composed_family = (family == 0xF)  +				? family + ext_family +				: family; +			return amd_CPUFamilyName(composed_family); +		} +		return "Unknown"; +	} + +} // end unnamed namespace + +// The base class for implementations. +// Each platform should override this class. +class LLProcessorInfoImpl +{ +public: +	LLProcessorInfoImpl()  +	{ +		mProcessorInfo["info"] = LLSD::emptyMap(); +		mProcessorInfo["config"] = LLSD::emptyMap(); +		mProcessorInfo["extension"] = LLSD::emptyMap();		 +	} +	virtual ~LLProcessorInfoImpl() {} + +	F64 getCPUFrequency() const  +	{  +		return getInfo(eFrequency, 0).asReal();  +	} + +	bool hasSSE() const  +	{  +		return hasExtension(cpu_feature_names[eSSE_Ext]); +	} + +	bool hasSSE2() const +	{  +		return hasExtension(cpu_feature_names[eSSE2_Ext]); +	} + +	bool hasAltivec() const  +	{ +		return hasExtension("Altivec");  +	} + +	std::string getCPUFamilyName() const { return getInfo(eFamilyName, "Unknown").asString(); } +	std::string getCPUBrandName() const { return getInfo(eBrandName, "Unknown").asString(); } + +	// This is virtual to support a different linux format. +	// *NOTE:Mani - I didn't want to screw up server use of this data... +	virtual std::string getCPUFeatureDescription() const  +	{ +		std::ostringstream out; +		out << std::endl << std::endl; +		out << "// CPU General Information" << std::endl; +		out << "//////////////////////////" << std::endl; +		out << "Processor Name:   " << getCPUBrandName() << std::endl; +		out << "Frequency:        " << getCPUFrequency() << " MHz" << std::endl; +		out << "Vendor:			  " << getInfo(eVendor, "Unknown").asString() << std::endl; +		out << "Family:           " << getCPUFamilyName() << " (" << getInfo(eFamily, 0) << ")" << std::endl; +		out << "Extended family:  " << getInfo(eExtendedFamily, 0) << std::endl; +		out << "Model:            " << getInfo(eModel, 0) << std::endl; +		out << "Extended model:   " << getInfo(eExtendedModel, 0) << std::endl; +		out << "Type:             " << getInfo(eType, 0) << std::endl; +		out << "Brand ID:         " << getInfo(eBrandID, 0) << std::endl; +		out << std::endl; +		out << "// CPU Configuration" << std::endl; +		out << "//////////////////////////" << std::endl; +		 +		// Iterate through the dictionary of configuration options. +		LLSD configs = mProcessorInfo["config"]; +		for(LLSD::map_const_iterator cfgItr = configs.beginMap(); cfgItr != configs.endMap(); ++cfgItr) +		{ +			out << cfgItr->first << " = " << cfgItr->second << std::endl; +		} +		out << std::endl; +		 +		out << "// CPU Extensions" << std::endl; +		out << "//////////////////////////" << std::endl; +		 +		for(LLSD::map_const_iterator itr = mProcessorInfo["extension"].beginMap(); itr != mProcessorInfo["extension"].endMap(); ++itr) +		{ +			out << "  " << itr->first << std::endl;			 +		} +		return out.str();  +	} + +protected: +	void setInfo(cpu_info info_type, const LLSD& value)  +	{ +		setInfo(cpu_info_names[info_type], value); +	} +    LLSD getInfo(cpu_info info_type, const LLSD& defaultVal) const +	{ +		return getInfo(cpu_info_names[info_type], defaultVal); +	} + +	void setConfig(cpu_config config_type, const LLSD& value)  +	{  +		setConfig(cpu_config_names[config_type], value); +	} +	LLSD getConfig(cpu_config config_type, const LLSD& defaultVal) const +	{  +		return getConfig(cpu_config_names[config_type], defaultVal); +	} + +	void setExtension(const std::string& name) { mProcessorInfo["extension"][name] = "true"; } +	bool hasExtension(const std::string& name) const +	{  +		return mProcessorInfo["extension"].has(name); +	} + +private: +	void setInfo(const std::string& name, const LLSD& value) { mProcessorInfo["info"][name]=value; } +	LLSD getInfo(const std::string& name, const LLSD& defaultVal) const +	{  +		if(mProcessorInfo["info"].has(name)) +		{ +			return mProcessorInfo["info"][name]; +		} +		return defaultVal; +	} +	void setConfig(const std::string& name, const LLSD& value) { mProcessorInfo["config"][name]=value; } +	LLSD getConfig(const std::string& name, const LLSD& defaultVal) const +	{  +		LLSD r = mProcessorInfo["config"].get(name); +		return r.isDefined() ? r : defaultVal; +	} + +private: + +	LLSD mProcessorInfo; +}; + + +#ifdef LL_MSVC +// LL_MSVC and not LLWINDOWS because some of the following code  +// uses the MSVC compiler intrinsics __cpuid() and __rdtsc(). -#ifdef PROCESSOR_FREQUENCY_MEASURE_AVAILABLE  // Delays for the specified amount of milliseconds -static	void	_Delay(unsigned int ms) +static void _Delay(unsigned int ms)  { -   LARGE_INTEGER	freq, c1, c2; -	__int64		x; +	LARGE_INTEGER freq, c1, c2; +	__int64 x; -   // Get High-Res Timer frequency +	// Get High-Res Timer frequency  	if (!QueryPerformanceFrequency(&freq))	  		return; -		 +  	// Convert ms to High-Res Timer value  	x = freq.QuadPart/1000*ms;		 -   // Get first snapshot of High-Res Timer value +	// Get first snapshot of High-Res Timer value  	QueryPerformanceCounter(&c1);		  	do  	{ -            // Get second snapshot -	    QueryPerformanceCounter(&c2);	 +		// Get second snapshot +		QueryPerformanceCounter(&c2);	  	}while(c2.QuadPart-c1.QuadPart < x);  	// Loop while (second-first < x)	  } -#endif - -// CProcessor::CProcessor -// ====================== -// Class constructor: -///////////////////////// -CProcessor::CProcessor() -{ -	uqwFrequency = 0; -	strCPUName[0] = 0; -	memset(&CPUInfo, 0, sizeof(CPUInfo)); -} -// unsigned __int64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs) -// ========================================================================= -// Function to measure the current CPU frequency -//////////////////////////////////////////////////////////////////////////// -F64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs) +static F64 calculate_cpu_frequency(U32 measure_msecs)  { -#if LL_LINUX -	// use the shinier LLCPUInfo interface -	return 1000000.0F * gSysCPU.getMHz(); -#endif - -#ifndef PROCESSOR_FREQUENCY_MEASURE_AVAILABLE -	return 0; -#else -	// If there are invalid measure time parameters, zero msecs for example, -	// we've to exit the function -	if (uiMeasureMSecs < 1) +	if(measure_msecs == 0)  	{ -		// If theres already a measured frequency available, we return it -        if (uqwFrequency > 0) -			return uqwFrequency; -		else -			return 0; -	} - -	// Now we check if the CPUID command is available -	if (!CheckCPUIDPresence())  		return 0; - -	// First we get the CPUID standard level 0x00000001 -	unsigned long reg; -	__asm -	{ -		mov eax, 1 -        cpuid -		mov reg, edx  	} -	// Then we check, if the RDTSC (Real Date Time Stamp Counter) is available. -	// This function is necessary for our measure process. -	if (!(reg & (1 << 4))) -		return 0; -  	// After that we declare some vars and check the frequency of the high  	// resolution timer for the measure process. -	// If there's no high-res timer, we exit. -	__int64 starttime, endtime, timedif, freq, start, end, dif; +	// If there"s no high-res timer, we exit. +	unsigned __int64 starttime, endtime, timedif, freq, start, end, dif;  	if (!QueryPerformanceFrequency((LARGE_INTEGER *) &freq)) +	{  		return 0; +	}  	// Now we can init the measure process. We set the process and thread priority  	// to the highest available level (Realtime priority). Also we focus the @@ -178,35 +428,27 @@ F64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs)  	SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL);  	SetProcessAffinityMask(hProcess, dwNewMask); -	// Now we call a CPUID to ensure, that all other prior called functions are -	// completed now (serialization) -	__asm cpuid +	//// Now we call a CPUID to ensure, that all other prior called functions are +	//// completed now (serialization) +	//__asm cpuid +	int cpu_info[4] = {-1}; +	__cpuid(cpu_info, 0);  	// We ask the high-res timer for the start time  	QueryPerformanceCounter((LARGE_INTEGER *) &starttime);  	// Then we get the current cpu clock and store it -	__asm  -	{ -		rdtsc -		mov dword ptr [start+4], edx -		mov dword ptr [start], eax -	} +	start = __rdtsc();  	// Now we wart for some msecs -	_Delay(uiMeasureMSecs); -//	Sleep(uiMeasureMSecs); +	_Delay(measure_msecs); +	//	Sleep(uiMeasureMSecs);  	// We ask for the end time  	QueryPerformanceCounter((LARGE_INTEGER *) &endtime);  	// And also for the end cpu clock -	__asm  -	{ -		rdtsc -		mov dword ptr [end+4], edx -		mov dword ptr [end], eax -	} +	end = __rdtsc();  	// Now we can restore the default process and thread priorities  	SetProcessAffinityMask(hProcess, dwProcessMask); @@ -219,2075 +461,433 @@ F64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs)  	// And finally the frequency is the clock difference divided by the time  	// difference.  -	uqwFrequency = (F64)dif / (((F64)timedif) / freq); +	F64 frequency = (F64)dif / (((F64)timedif) / freq);  	// At last we just return the frequency that is also stored in the call -	// member var uqwFrequency -	return uqwFrequency; -#endif +	// member var uqwFrequency - converted to MHz +	return frequency  / (F64)1000000;  } -// bool CProcessor::AnalyzeIntelProcessor() -// ======================================== -// Private class function for analyzing an Intel processor -////////////////////////////////////////////////////////// -bool CProcessor::AnalyzeIntelProcessor() +// Windows implementation +class LLProcessorInfoWindowsImpl : public LLProcessorInfoImpl  { -#if LL_WINDOWS -	unsigned long eaxreg, ebxreg, edxreg; - -	// First we check if the CPUID command is available -	if (!CheckCPUIDPresence()) -		return false; - -	// Now we get the CPUID standard level 0x00000001 -	__asm +public: +	LLProcessorInfoWindowsImpl()  	{ -		mov eax, 1 -		cpuid -		mov eaxreg, eax -		mov ebxreg, ebx -		mov edxreg, edx +		getCPUIDInfo(); +		setInfo(eFrequency, calculate_cpu_frequency(50));  	} -     -	// Then get the cpu model, family, type, stepping and brand id by masking -	// the eax and ebx register -	CPUInfo.uiStepping = eaxreg & 0xF; -	CPUInfo.uiModel    = (eaxreg >> 4) & 0xF; -	CPUInfo.uiFamily   = (eaxreg >> 8) & 0xF; -	CPUInfo.uiType     = (eaxreg >> 12) & 0x3; -	CPUInfo.uiBrandID  = ebxreg & 0xF; - -	static const char* INTEL_BRAND[] = -	{ -		/* 0x00 */ "", -		/* 0x01 */ "0.18 micron Intel Celeron", -		/* 0x02 */ "0.18 micron Intel Pentium III", -		/* 0x03 */ "0.13 micron Intel Celeron", -		/* 0x04 */ "0.13 micron Intel Pentium III", -		/* 0x05 */ "", -		/* 0x06 */ "0.13 micron Intel Pentium III Mobile", -		/* 0x07 */ "0.13 micron Intel Celeron Mobile", -		/* 0x08 */ "0.18 micron Intel Pentium 4", -		/* 0x09 */ "0.13 micron Intel Pentium 4", -		/* 0x0A */ "0.13 micron Intel Celeron", -		/* 0x0B */ "0.13 micron Intel Pentium 4 Xeon", -		/* 0x0C */ "Intel Xeon MP", -		/* 0x0D */ "", -		/* 0x0E */ "0.18 micron Intel Pentium 4 Xeon", -		/* 0x0F */ "Mobile Intel Celeron", -		/* 0x10 */ "", -		/* 0x11 */ "Mobile Genuine Intel", -		/* 0x12 */ "Intel Celeron M", -		/* 0x13 */ "Mobile Intel Celeron", -		/* 0x14 */ "Intel Celeron", -		/* 0x15 */ "Mobile Genuine Intel", -		/* 0x16 */ "Intel Pentium M", -		/* 0x17 */ "Mobile Intel Celeron", -	}; -	// Only override the brand if we have it in the lookup table.  We should -	// already have a string here from GetCPUInfo().  JC -	if ( CPUInfo.uiBrandID < LL_ARRAY_SIZE(INTEL_BRAND) ) +private: +	void getCPUIDInfo()  	{ -		strncpy(CPUInfo.strBrandID, INTEL_BRAND[CPUInfo.uiBrandID], sizeof(CPUInfo.strBrandID)-1); -		CPUInfo.strBrandID[sizeof(CPUInfo.strBrandID)-1]='\0'; +		// http://msdn.microsoft.com/en-us/library/hskdteyh(VS.80).aspx + +		// __cpuid with an InfoType argument of 0 returns the number of +		// valid Ids in cpu_info[0] and the CPU identification string in +		// the other three array elements. The CPU identification string is +		// not in linear order. The code below arranges the information  +		// in a human readable form. +		int cpu_info[4] = {-1}; +		__cpuid(cpu_info, 0); +		unsigned int ids = (unsigned int)cpu_info[0]; +		setConfig(eMaxID, (S32)ids); + +		char cpu_vendor[0x20]; +		memset(cpu_vendor, 0, sizeof(cpu_vendor)); +		*((int*)cpu_vendor) = cpu_info[1]; +		*((int*)(cpu_vendor+4)) = cpu_info[3]; +		*((int*)(cpu_vendor+8)) = cpu_info[2]; +		setInfo(eVendor, cpu_vendor); -		if (CPUInfo.uiBrandID == 3 && CPUInfo.uiModel == 6) +		// Get the information associated with each valid Id +		for(unsigned int i=0; i<=ids; ++i)  		{ -			strcpy(CPUInfo.strBrandID, "0.18 micron Intel Pentium III Xeon"); -		} -	} +			__cpuid(cpu_info, i); -	// Then we translate the cpu family -    switch (CPUInfo.uiFamily) -	{ -		case 3:			// Family = 3:  i386 (80386) processor family -			strcpy(CPUInfo.strFamily, "Intel i386");	/* Flawfinder: ignore */	 -			break; -		case 4:			// Family = 4:  i486 (80486) processor family -			strcpy(CPUInfo.strFamily, "Intel i486");	/* Flawfinder: ignore */	 -			break; -		case 5:			// Family = 5:  Pentium (80586) processor family -			strcpy(CPUInfo.strFamily, "Intel Pentium");	/* Flawfinder: ignore */	 -			break; -		case 6:			// Family = 6:  Pentium Pro (80686) processor family -			strcpy(CPUInfo.strFamily, "Intel Pentium Pro/2/3, Core");	/* Flawfinder: ignore */	 -			break; -		case 15:		// Family = 15:  Extended family specific -			// Masking the extended family -			CPUInfo.uiExtendedFamily = (eaxreg >> 20) & 0xFF; -			switch (CPUInfo.uiExtendedFamily) -			{ -				case 0:			// Family = 15, Ext. Family = 0:  Pentium 4 (80786 ??) processor family -					strcpy(CPUInfo.strFamily, "Intel Pentium 4");	/* Flawfinder: ignore */	 -					break; -				case 1:			// Family = 15, Ext. Family = 1:  McKinley (64-bit) processor family -					strcpy(CPUInfo.strFamily, "Intel McKinley (IA-64)");	/* Flawfinder: ignore */	 -					break; -				default:		// Sure is sure -					strcpy(CPUInfo.strFamily, "Unknown Intel Pentium 4+");	/* Flawfinder: ignore */	 -					break; -			} -			break; -		default:		// Failsave -			strcpy(CPUInfo.strFamily, "Unknown");	/* Flawfinder: ignore */ -			break; -    } - -	// Now we come to the big deal, the exact model name -	switch (CPUInfo.uiFamily) -	{ -		case 3:			// i386 (80386) processor family -			strcpy(CPUInfo.strModel, "Unknown Intel i386");	/* Flawfinder: ignore */ -			strncat(strCPUName, "Intel i386", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */		 -			break; -		case 4:			// i486 (80486) processor family -			switch (CPUInfo.uiModel) -			{ -				case 0:			// Model = 0:  i486 DX-25/33 processor model -					strcpy(CPUInfo.strModel, "Intel i486 DX-25/33");	/* Flawfinder: ignore */			 -					strncat(strCPUName, "Intel i486 DX-25/33", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */		 -					break; -				case 1:			// Model = 1:  i486 DX-50 processor model -					strcpy(CPUInfo.strModel, "Intel i486 DX-50");	/* Flawfinder: ignore */		 -					strncat(strCPUName, "Intel i486 DX-50", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */		 -					break; -				case 2:			// Model = 2:  i486 SX processor model -					strcpy(CPUInfo.strModel, "Intel i486 SX");	/* Flawfinder: ignore */		 -					strncat(strCPUName, "Intel i486 SX", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */		 -					break; -				case 3:			// Model = 3:  i486 DX2 (with i487 numeric coprocessor) processor model -					strcpy(CPUInfo.strModel, "Intel i486 487/DX2");	/* Flawfinder: ignore */		 -					strncat(strCPUName, "Intel i486 DX2 with i487 numeric coprocessor", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */		 -					break; -				case 4:			// Model = 4:  i486 SL processor model (never heard ?!?) -					strcpy(CPUInfo.strModel, "Intel i486 SL");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel i486 SL", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				case 5:			// Model = 5:  i486 SX2 processor model -					strcpy(CPUInfo.strModel, "Intel i486 SX2");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel i486 SX2", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				case 7:			// Model = 7:  i486 write-back enhanced DX2 processor model -					strcpy(CPUInfo.strModel, "Intel i486 write-back enhanced DX2");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel i486 write-back enhanced DX2", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				case 8:			// Model = 8:  i486 DX4 processor model -					strcpy(CPUInfo.strModel, "Intel i486 DX4");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel i486 DX4", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				case 9:			// Model = 9:  i486 write-back enhanced DX4 processor model -					strcpy(CPUInfo.strModel, "Intel i486 write-back enhanced DX4");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel i486 DX4", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				default:		// ... -					strcpy(CPUInfo.strModel, "Unknown Intel i486");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel i486 (Unknown model)", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -			} -			break; -		case 5:			// Pentium (80586) processor family -			switch (CPUInfo.uiModel) -			{ -				case 0:			// Model = 0:  Pentium (P5 A-Step) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium (P5 A-Step)");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel Pentium (P5 A-Step core)", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break;		// Famous for the DIV bug, as far as I know -				case 1:			// Model = 1:  Pentium 60/66 processor model -					strcpy(CPUInfo.strModel, "Intel Pentium 60/66 (P5)");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel Pentium 60/66 (P5 core)", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				case 2:			// Model = 2:  Pentium 75-200 (P54C) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium 75-200 (P54C)");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel Pentium 75-200 (P54C core)", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -					break; -				case 3:			// Model = 3:  Pentium overdrive for 486 systems processor model -					strcpy(CPUInfo.strModel, "Intel Pentium for 486 system (P24T Overdrive)");	/* Flawfinder: ignore */	 -					strncat(strCPUName, "Intel Pentium for 486 (P24T overdrive core)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 4:			// Model = 4:  Pentium MMX processor model -					strcpy(CPUInfo.strModel, "Intel Pentium MMX (P55C)");	/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium MMX (P55C core)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 7:			// Model = 7:  Pentium processor model (don't know difference to Model=2) -					strcpy(CPUInfo.strModel, "Intel Pentium (P54C)");		/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium (P54C core)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 8:			// Model = 8:  Pentium MMX (0.25 micron) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium MMX (P55C), 0.25 micron");		/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium MMX (P55C core), 0.25 micron", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				default:		// ... -					strcpy(CPUInfo.strModel, "Unknown Intel Pentium");	/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium (Unknown P5-model)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -			} -			break; -		case 6:			// Pentium Pro (80686) processor family -			switch (CPUInfo.uiModel) -			{ -				case 0:			// Model = 0:  Pentium Pro (P6 A-Step) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium Pro (P6 A-Step)");		/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium Pro (P6 A-Step core)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 1:			// Model = 1:  Pentium Pro -					strcpy(CPUInfo.strModel, "Intel Pentium Pro (P6)");		/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium Pro (P6 core)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 3:			// Model = 3:  Pentium II (66 MHz FSB, I think) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium II Model 3, 0.28 micron");		/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium II (Model 3 core, 0.28 micron process)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 5:			// Model = 5:  Pentium II/Xeon/Celeron (0.25 micron) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium II Model 5/Xeon/Celeron, 0.25 micron");		/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium II/Xeon/Celeron (Model 5 core, 0.25 micron process)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 6:			// Model = 6:  Pentium II with internal L2 cache -					strcpy(CPUInfo.strModel, "Intel Pentium II - internal L2 cache");	/*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium II with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 7:			// Model = 7:  Pentium III/Xeon (extern L2 cache) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium III/Pentium III Xeon - external L2 cache, 0.25 micron");		 /*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium III/Pentium III Xeon (0.25 micron process) with external L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 8:			// Model = 8:  Pentium III/Xeon/Celeron (256 KB on-die L2 cache) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium III/Celeron/Pentium III Xeon - internal L2 cache, 0.18 micron");	 /*Flawfinder: ignore*/ -					// We want to know it exactly: -					switch (CPUInfo.uiBrandID) -					{ -						case 1:			// Model = 8, Brand id = 1:  Celeron (on-die L2 cache) processor model -							strncat(strCPUName, "Intel Celeron (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -                        case 2:			// Model = 8, Brand id = 2:  Pentium III (on-die L2 cache) processor model (my current cpu :-)) -							strncat(strCPUName, "Intel Pentium III (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -						case 3:			// Model = 8, Brand id = 3:  Pentium III Xeon (on-die L2 cache) processor model -                            strncat(strCPUName, "Intel Pentium III Xeon (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -						default:		// ... -							strncat(strCPUName, "Intel Pentium III core (unknown model, 0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -					} -					break; -				case 9:		// Model = 9:  Intel Pentium M processor, Intel Celeron M processor, model 9 -					strcpy(CPUInfo.strModel, "Intel Pentium M Series Processor");	 /*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium M Series Processor", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 0xA:		// Model = 0xA:  Pentium III/Xeon/Celeron (1 or 2 MB on-die L2 cache) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium III/Celeron/Pentium III Xeon - internal L2 cache, 0.18 micron");	 /*Flawfinder: ignore*/ -					// Exact detection: -					switch (CPUInfo.uiBrandID) -					{ -						case 1:			// Model = 0xA, Brand id = 1:  Celeron (1 or 2 MB on-die L2 cache (does it exist??)) processor model -							strncat(strCPUName, "Intel Celeron (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -                        case 2:			// Model = 0xA, Brand id = 2:  Pentium III (1 or 2 MB on-die L2 cache (never seen...)) processor model -							strncat(strCPUName, "Intel Pentium III (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -						case 3:			// Model = 0xA, Brand id = 3:  Pentium III Xeon (1 or 2 MB on-die L2 cache) processor model -                            strncat(strCPUName, "Intel Pentium III Xeon (0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -						default:		// Getting bored of this............ -							strncat(strCPUName, "Intel Pentium III core (unknown model, 0.18 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -					} -					break; -				case 0xB:		// Model = 0xB: Pentium III/Xeon/Celeron (Tualatin core, on-die cache) processor model -					strcpy(CPUInfo.strModel, "Intel Pentium III/Celeron/Pentium III Xeon - internal L2 cache, 0.13 micron");	 /*Flawfinder: ignore*/ -					// Omniscient: ;-) -					switch (CPUInfo.uiBrandID) -					{ -						case 3:			// Model = 0xB, Brand id = 3:  Celeron (Tualatin core) processor model -							strncat(strCPUName, "Intel Celeron (Tualatin core, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -                        case 4:			// Model = 0xB, Brand id = 4:  Pentium III (Tualatin core) processor model -							strncat(strCPUName, "Intel Pentium III (Tualatin core, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -						case 7:			// Model = 0xB, Brand id = 7:  Celeron mobile (Tualatin core) processor model -                            strncat(strCPUName, "Intel Celeron mobile (Tualatin core, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -						default:		// *bored* -							strncat(strCPUName, "Intel Pentium III Tualatin core (unknown model, 0.13 micron process) with internal L2 cache", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -							break; -					} -					break; -				case 0xD:		// Model = 0xD:  Intel Pentium M processor, Intel Celeron M processor, model D -					strcpy(CPUInfo.strModel, "Intel Pentium M Series Processor");	 /*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium M Series Processor", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -				case 0xE:		// Model = 0xE:  Intel Core Duo processor, Intel Core Solo processor, model E -					strcpy(CPUInfo.strModel, "Intel Core Series Processor");	 /*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Core Series Processor", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break;	 -				case 0xF:		// Model = 0xF:  Intel Core 2 Duo processor, model F -					strcpy(CPUInfo.strModel, "Intel Core 2 Series Processor");	 /*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Core 2 Series Processor", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break;	 -				default:		// *more bored* -					strcpy(CPUInfo.strModel, "Unknown Intel Pentium Pro/2/3, Core"); /*Flawfinder: ignore*/ -					strncat(strCPUName, "Intel Pentium Pro/2/3, Core (Unknown model)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					break; -			} -			break; -		case 15:		// Extended processor family -			// Masking the extended model -			CPUInfo.uiExtendedModel = (eaxreg >> 16) & 0xFF; -			switch (CPUInfo.uiModel) +			// Interpret CPU feature information. +			if  (i == 1)  			{ -				case 0:			// Model = 0:  Pentium 4 Willamette (A-Step) core -					if ((CPUInfo.uiBrandID) == 8)	// Brand id = 8:  P4 Willamette -					{ -						strcpy(CPUInfo.strModel, "Intel Pentium 4 Willamette (A-Step)"); /*Flawfinder: ignore*/ -						strncat(strCPUName, "Intel Pentium 4 Willamette (A-Step)", sizeof(strCPUName)-(strlen(strCPUName)-1)); /*Flawfinder: ignore*/ -					} -					else							// else Xeon -					{ -						strcpy(CPUInfo.strModel, "Intel Pentium 4 Willamette Xeon (A-Step)");		/* Flawfinder: ignore */ -						strncat(strCPUName, "Intel Pentium 4 Willamette Xeon (A-Step)", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */	 -					} -					break; -				case 1:			// Model = 1:  Pentium 4 Willamette core -					if ((CPUInfo.uiBrandID) == 8)	// Brand id = 8:  P4 Willamette +				setInfo(eStepping, cpu_info[0] & 0xf); +				setInfo(eModel, (cpu_info[0] >> 4) & 0xf); +				int family = (cpu_info[0] >> 8) & 0xf; +				setInfo(eFamily, family); +				setInfo(eType, (cpu_info[0] >> 12) & 0x3); +				setInfo(eExtendedModel, (cpu_info[0] >> 16) & 0xf); +				int ext_family = (cpu_info[0] >> 20) & 0xff; +				setInfo(eExtendedFamily, ext_family); +				setInfo(eBrandID, cpu_info[1] & 0xff); + +				setInfo(eFamilyName, compute_CPUFamilyName(cpu_vendor, family, ext_family)); + +				setConfig(eCLFLUSHCacheLineSize, ((cpu_info[1] >> 8) & 0xff) * 8); +				setConfig(eAPICPhysicalID, (cpu_info[1] >> 24) & 0xff); +				 +				if(cpu_info[2] & 0x1) +				{ +					setExtension(cpu_feature_names[eSSE3_Features]); +				} + +				if(cpu_info[2] & 0x8) +				{ +					setExtension(cpu_feature_names[eMONTIOR_MWAIT]); +				} +				 +				if(cpu_info[2] & 0x10) +				{ +					setExtension(cpu_feature_names[eCPLDebugStore]); +				} +				 +				if(cpu_info[2] & 0x100) +				{ +					setExtension(cpu_feature_names[eThermalMonitor2]); +				} +						 +				unsigned int feature_info = (unsigned int) cpu_info[3]; +				for(unsigned int index = 0, bit = 1; index < eSSE3_Features; ++index, bit <<= 1) +				{ +					if(feature_info & bit)  					{ -						strcpy(CPUInfo.strModel, "Intel Pentium 4 Willamette");		/* Flawfinder: ignore */ -						strncat(strCPUName, "Intel Pentium 4 Willamette", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */ +						setExtension(cpu_feature_names[index]);  					} -					else							// else Xeon -					{ -						strcpy(CPUInfo.strModel, "Intel Pentium 4 Willamette Xeon");		/* Flawfinder: ignore */ -						strncat(strCPUName, "Intel Pentium 4 Willamette Xeon", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */ -					} -					break; -				case 2:			// Model = 2:  Pentium 4 Northwood core -					if (((CPUInfo.uiBrandID) == 9) || ((CPUInfo.uiBrandID) == 0xA))		// P4 Willamette -					{ -						strcpy(CPUInfo.strModel, "Intel Pentium 4 Northwood");		/* Flawfinder: ignore */ -						strncat(strCPUName, "Intel Pentium 4 Northwood", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */ -					} -					else							// Xeon -					{ -						strcpy(CPUInfo.strModel, "Intel Pentium 4 Northwood Xeon");		/* Flawfinder: ignore */ -						strncat(strCPUName, "Intel Pentium 4 Northwood Xeon", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */ -					} -					break; -				default:		// Silly stupid never used failsave option -					strcpy(CPUInfo.strModel, "Unknown Intel Pentium 4");		/* Flawfinder: ignore */ -					strncat(strCPUName, "Intel Pentium 4 (Unknown model)", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */ -					break; +				}  			} -			break; -		default:		// *grmpf* -			strcpy(CPUInfo.strModel, "Unknown Intel model");		/* Flawfinder: ignore */ -			strncat(strCPUName, "Intel (Unknown model)", sizeof(strCPUName) - strlen(strCPUName) - 1);		/* Flawfinder: ignore */ -			break; -    } - -	// After the long processor model block we now come to the processors serial -	// number. -	// First of all we check if the processor supports the serial number -	if (CPUInfo.MaxSupportedLevel >= 3) -	{ -		// If it supports the serial number CPUID level 0x00000003 we read the data -		unsigned long sig1, sig2, sig3; -		__asm -		{ -			mov eax, 1 -			cpuid -			mov sig1, eax -			mov eax, 3 -			cpuid -			mov sig2, ecx -			mov sig3, edx  		} -		// Then we convert the data to a readable string -		snprintf(	/* Flawfinder: ignore */ -			CPUInfo.strProcessorSerial, -			sizeof(CPUInfo.strProcessorSerial), -			"%04lX-%04lX-%04lX-%04lX-%04lX-%04lX", -			sig1 >> 16, -			sig1 & 0xFFFF, -			sig3 >> 16, -			sig3 & 0xFFFF, -			sig2 >> 16, sig2 & 0xFFFF); -	} -	else -	{ -		// If there's no serial number support we just put "No serial number" -		snprintf(	/* Flawfinder: ignore */ -			CPUInfo.strProcessorSerial, -			sizeof(CPUInfo.strProcessorSerial), -			"No Processor Serial Number");	 -	} - -	// Now we get the standard processor extensions -	GetStandardProcessorExtensions(); -	// And finally the processor configuration (caches, TLBs, ...) and translate -	// the data to readable strings -	GetStandardProcessorConfiguration(); -	TranslateProcessorConfiguration(); +		// Calling __cpuid with 0x80000000 as the InfoType argument +		// gets the number of valid extended IDs. +		__cpuid(cpu_info, 0x80000000); +		unsigned int ext_ids = cpu_info[0]; +		setConfig(eMaxExtID, 0); -	// At last... -	return true; -#else -	return FALSE; -#endif -} +		char cpu_brand_string[0x40]; +		memset(cpu_brand_string, 0, sizeof(cpu_brand_string)); -// bool CProcessor::AnalyzeAMDProcessor() -// ====================================== -// Private class function for analyzing an AMD processor -//////////////////////////////////////////////////////// -bool CProcessor::AnalyzeAMDProcessor() -{ -#if LL_WINDOWS -	unsigned long eaxreg, ebxreg, ecxreg, edxreg; - -	// First of all we check if the CPUID command is available -	if (!CheckCPUIDPresence()) -		return 0; - -	// Now we get the CPUID standard level 0x00000001 -	__asm -	{ -		mov eax, 1 -		cpuid -		mov eaxreg, eax -		mov ebxreg, ebx -		mov edxreg, edx -	} -     -	// Then we mask the model, family, stepping and type (AMD does not support brand id) -	CPUInfo.uiStepping = eaxreg & 0xF; -	CPUInfo.uiModel    = (eaxreg >> 4) & 0xF; -	CPUInfo.uiFamily   = (eaxreg >> 8) & 0xF; -	CPUInfo.uiType     = (eaxreg >> 12) & 0x3; - -	// Now we check if the processor supports the brand id string extended CPUID level -	if (CPUInfo.MaxSupportedExtendedLevel >= 0x80000004) -	{ -		// If it supports the extended CPUID level 0x80000004 we read the data -		char tmp[52];		/* Flawfinder: ignore */ -		memset(tmp, 0, sizeof(tmp)); -        __asm +		// Get the information associated with each extended ID. +		for(unsigned int i=0x80000000; i<=ext_ids; ++i)  		{ -			mov eax, 0x80000002 -			cpuid -			mov dword ptr [tmp], eax -			mov dword ptr [tmp+4], ebx -			mov dword ptr [tmp+8], ecx -			mov dword ptr [tmp+12], edx -			mov eax, 0x80000003 -			cpuid -			mov dword ptr [tmp+16], eax -			mov dword ptr [tmp+20], ebx -			mov dword ptr [tmp+24], ecx -			mov dword ptr [tmp+28], edx -			mov eax, 0x80000004 -			cpuid -			mov dword ptr [tmp+32], eax -			mov dword ptr [tmp+36], ebx -			mov dword ptr [tmp+40], ecx -			mov dword ptr [tmp+44], edx -		} -		// And copy it to the brand id string -		strncpy(CPUInfo.strBrandID, tmp,sizeof(CPUInfo.strBrandID)-1); -		CPUInfo.strBrandID[sizeof(CPUInfo.strBrandID)-1]='\0'; -	} -	else -	{ -		// Or just tell there is no brand id string support -		strcpy(CPUInfo.strBrandID, "");		/* Flawfinder: ignore */ -	} - -	// After that we translate the processor family -    switch(CPUInfo.uiFamily) -	{ -		case 4:			// Family = 4:  486 (80486) or 5x86 (80486) processor family -			switch (CPUInfo.uiModel) +			__cpuid(cpu_info, i); + +			// Interpret CPU brand string and cache information. +			if  (i == 0x80000002) +				memcpy(cpu_brand_string, cpu_info, sizeof(cpu_info)); +			else if  (i == 0x80000003) +				memcpy(cpu_brand_string + 16, cpu_info, sizeof(cpu_info)); +			else if  (i == 0x80000004)  			{ -				case 3:			// Thanks to AMD for this nice form of family -				case 7:			// detection.... *grmpf* -				case 8: -				case 9: -					strcpy(CPUInfo.strFamily, "AMD 80486");		/* Flawfinder: ignore */ -					break; -				case 0xE: -				case 0xF: -					strcpy(CPUInfo.strFamily, "AMD 5x86");		/* Flawfinder: ignore */ -					break; -				default: -					strcpy(CPUInfo.strFamily, "Unknown family");		/* Flawfinder: ignore */ -					break; +				memcpy(cpu_brand_string + 32, cpu_info, sizeof(cpu_info)); +				setInfo(eBrandName, cpu_brand_string);  			} -			break; -		case 5:			// Family = 5:  K5 or K6 processor family -			switch (CPUInfo.uiModel) +			else if  (i == 0x80000006)  			{ -				case 0: -				case 1: -				case 2: -				case 3: -					strcpy(CPUInfo.strFamily, "AMD K5");		/* Flawfinder: ignore */ -					break; -				case 6: -				case 7: -				case 8: -				case 9: -					strcpy(CPUInfo.strFamily, "AMD K6");		/* Flawfinder: ignore */ -					break; -				default: -					strcpy(CPUInfo.strFamily, "Unknown family");		/* Flawfinder: ignore */ -					break; +				setConfig(eCacheLineSize, cpu_info[2] & 0xff); +				setConfig(eL2Associativity, (cpu_info[2] >> 12) & 0xf); +				setConfig(eCacheSizeK, (cpu_info[2] >> 16) & 0xffff);  			} -			break; -		case 6:			// Family = 6:  K7 (Athlon, ...) processor family -			strcpy(CPUInfo.strFamily, "AMD K7");		/* Flawfinder: ignore */ -			break; -		default:		// For security -			strcpy(CPUInfo.strFamily, "Unknown family");		/* Flawfinder: ignore */ -			break; +		}  	} +}; -	// After the family detection we come to the specific processor model -	// detection -	switch (CPUInfo.uiFamily) -	{ -		case 4:			// Family = 4:  486 (80486) or 5x85 (80486) processor family -			switch (CPUInfo.uiModel) -			{ -				case 3:			// Model = 3:  80486 DX2 -					strcpy(CPUInfo.strModel, "AMD 80486 DX2");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 80486 DX2", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 7:			// Model = 7:  80486 write-back enhanced DX2 -					strcpy(CPUInfo.strModel, "AMD 80486 write-back enhanced DX2");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 80486 write-back enhanced DX2", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 8:			// Model = 8:  80486 DX4 -					strcpy(CPUInfo.strModel, "AMD 80486 DX4");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 80486 DX4", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 9:			// Model = 9:  80486 write-back enhanced DX4 -					strcpy(CPUInfo.strModel, "AMD 80486 write-back enhanced DX4");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 80486 write-back enhanced DX4", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 0xE:		// Model = 0xE:  5x86 -					strcpy(CPUInfo.strModel, "AMD 5x86");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 5x86", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 0xF:		// Model = 0xF:  5x86 write-back enhanced (oh my god.....) -					strcpy(CPUInfo.strModel, "AMD 5x86 write-back enhanced");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 5x86 write-back enhanced", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				default:		// ... -					strcpy(CPUInfo.strModel, "Unknown AMD 80486 or 5x86 model");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD 80486 or 5x86 (Unknown model)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -			} -			break; -		case 5:			// Family = 5:  K5 / K6 processor family -			switch (CPUInfo.uiModel) -			{ -				case 0:			// Model = 0:  K5 SSA 5 (Pentium Rating *ggg* 75, 90 and 100 MHz) -					strcpy(CPUInfo.strModel, "AMD K5 SSA5 (PR75, PR90, PR100)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K5 SSA5 (PR75, PR90, PR100)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 1:			// Model = 1:  K5 5k86 (PR 120 and 133 MHz) -					strcpy(CPUInfo.strModel, "AMD K5 5k86 (PR120, PR133)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K5 5k86 (PR120, PR133)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 2:			// Model = 2:  K5 5k86 (PR 166 MHz) -					strcpy(CPUInfo.strModel, "AMD K5 5k86 (PR166)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K5 5k86 (PR166)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 3:			// Model = 3:  K5 5k86 (PR 200 MHz) -					strcpy(CPUInfo.strModel, "AMD K5 5k86 (PR200)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K5 5k86 (PR200)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 6:			// Model = 6:  K6 -					strcpy(CPUInfo.strModel, "AMD K6 (0.30 micron)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K6 (0.30 micron)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 7:			// Model = 7:  K6 (0.25 micron) -					strcpy(CPUInfo.strModel, "AMD K6 (0.25 micron)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K6 (0.25 micron)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 8:			// Model = 8:  K6-2 -					strcpy(CPUInfo.strModel, "AMD K6-2");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K6-2", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 9:			// Model = 9:  K6-III -					strcpy(CPUInfo.strModel, "AMD K6-III");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K6-III", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 0xD:		// Model = 0xD:  K6-2+ / K6-III+ -					strcpy(CPUInfo.strModel, "AMD K6-2+ or K6-III+ (0.18 micron)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K6-2+ or K6-III+ (0.18 micron)", sizeof(strCPUName) - strlen(strCPUName) -1);	/* Flawfinder: ignore */ -					break; -				default:		// ... -					strcpy(CPUInfo.strModel, "Unknown AMD K5 or K6 model");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K5 or K6 (Unknown model)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -			} -			break; -		case 6:			// Family = 6:  K7 processor family (AMDs first good processors) -			switch (CPUInfo.uiModel) +#elif LL_DARWIN + +#include <mach/machine.h> +#include <sys/sysctl.h> + +class LLProcessorInfoDarwinImpl : public LLProcessorInfoImpl +{ +public: +	LLProcessorInfoDarwinImpl()  +	{ +		getCPUIDInfo(); +		uint64_t frequency = getSysctlInt64("hw.cpufrequency"); +		setInfo(eFrequency, (F64)frequency  / (F64)1000000); +	} + +	virtual ~LLProcessorInfoDarwinImpl() {} + +private: +	int getSysctlInt(const char* name) +   	{ +		int result = 0; +		size_t len = sizeof(int); +		int error = sysctlbyname(name, (void*)&result, &len, NULL, 0); +		return error == -1 ? 0 : result; +   	} + +	uint64_t getSysctlInt64(const char* name) +   	{ +		uint64_t value = 0; +		size_t size = sizeof(value); +		int result = sysctlbyname(name, (void*)&value, &size, NULL, 0); +		if ( result == 0 )  +		{  +			if ( size == sizeof( uint64_t ) )  +				;  +			else if ( size == sizeof( uint32_t ) )  +				value = (uint64_t)(( uint32_t *)&value);  +			else if ( size == sizeof( uint16_t ) )  +				value =  (uint64_t)(( uint16_t *)&value);  +			else if ( size == sizeof( uint8_t ) )  +				value =  (uint64_t)(( uint8_t *)&value);  +			else  			{ -				case 1:			// Athlon -					strcpy(CPUInfo.strModel, "AMD Athlon (0.25 micron)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD Athlon (0.25 micron)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 2:			// Athlon (0.18 micron) -					strcpy(CPUInfo.strModel, "AMD Athlon (0.18 micron)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD Athlon (0.18 micron)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 3:			// Duron (Spitfire core) -					strcpy(CPUInfo.strModel, "AMD Duron (Spitfire)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD Duron (Spitfire core)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 4:			// Athlon (Thunderbird core) -					strcpy(CPUInfo.strModel, "AMD Athlon (Thunderbird)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD Athlon (Thunderbird core)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 6:			// Athlon MP / Mobile Athlon (Palomino core) -					strcpy(CPUInfo.strModel, "AMD Athlon MP/Mobile Athlon (Palomino)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD Athlon MP/Mobile Athlon (Palomino core)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				case 7:			// Mobile Duron (Morgan core) -					strcpy(CPUInfo.strModel, "AMD Mobile Duron (Morgan)");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD Mobile Duron (Morgan core)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; -				default:		// ... -					strcpy(CPUInfo.strModel, "Unknown AMD K7 model");		/* Flawfinder: ignore */ -					strncat(strCPUName, "AMD K7 (Unknown model)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -					break; +				LL_WARNS("Unknown type returned from sysctl!") << LL_ENDL;  			} -			break; -		default:		// ... -			strcpy(CPUInfo.strModel, "Unknown AMD model");		/* Flawfinder: ignore */ -			strncat(strCPUName, "AMD (Unknown model)", sizeof(strCPUName) - strlen(strCPUName) -1);		/* Flawfinder: ignore */ -			break; -    } - -	// Now we read the standard processor extension that are stored in the same -	// way the Intel standard extensions are -	GetStandardProcessorExtensions(); - -	// Then we check if theres an extended CPUID level support -	if (CPUInfo.MaxSupportedExtendedLevel >= 0x80000001) -	{ -		// If we can access the extended CPUID level 0x80000001 we get the -		// edx register -		__asm -		{ -			mov eax, 0x80000001 -			cpuid -			mov edxreg, edx  		} - -		// Now we can mask some AMD specific cpu extensions -		CPUInfo._Ext.EMMX_MultimediaExtensions					= CheckBit(edxreg, 22); -		CPUInfo._Ext.AA64_AMD64BitArchitecture					= CheckBit(edxreg, 29); -		CPUInfo._Ext._E3DNOW_InstructionExtensions				= CheckBit(edxreg, 30); -		CPUInfo._Ext._3DNOW_InstructionExtensions				= CheckBit(edxreg, 31); -	} - -	// After that we check if the processor supports the ext. CPUID level -	// 0x80000006 -	if (CPUInfo.MaxSupportedExtendedLevel >= 0x80000006) +				 +		return result == -1 ? 0 : value; +   	} +	 +	void getCPUIDInfo()  	{ -		// If it's present, we read it out -        __asm -		{ -            mov eax, 0x80000005 -			cpuid -			mov eaxreg, eax -			mov ebxreg, ebx -			mov ecxreg, ecx -			mov edxreg, edx -		} +		size_t len = 0; -		// Then we mask the L1 Data TLB information -		if ((ebxreg >> 16) && (eaxreg >> 16)) -		{ -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 KB / 2 MB / 4MB"); 	/*Flawfinder: ignore*/ -			CPUInfo._Data.uiAssociativeWays = (eaxreg >> 24) & 0xFF; -			CPUInfo._Data.uiEntries = (eaxreg >> 16) & 0xFF; -		} -		else if (eaxreg >> 16) -		{ -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "2 MB / 4MB");		/*Flawfinder: ignore*/ -			CPUInfo._Data.uiAssociativeWays = (eaxreg >> 24) & 0xFF; -			CPUInfo._Data.uiEntries = (eaxreg >> 16) & 0xFF; -		} -		else if (ebxreg >> 16) -		{ -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 KB");		/*Flawfinder: ignore*/ -			CPUInfo._Data.uiAssociativeWays = (ebxreg >> 24) & 0xFF; -			CPUInfo._Data.uiEntries = (ebxreg >> 16) & 0xFF; -		} -		if (CPUInfo._Data.uiAssociativeWays == 0xFF) -			CPUInfo._Data.uiAssociativeWays = (unsigned int) -1; - -		// Now the L1 Instruction/Code TLB information -		if ((ebxreg & 0xFFFF) && (eaxreg & 0xFFFF)) -		{ -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 KB / 2 MB / 4MB");		/*Flawfinder: ignore*/ -			CPUInfo._Instruction.uiAssociativeWays = (eaxreg >> 8) & 0xFF; -			CPUInfo._Instruction.uiEntries = eaxreg & 0xFF; -		} -		else if (eaxreg & 0xFFFF) -		{ -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "2 MB / 4MB");		/*Flawfinder: ignore*/ -			CPUInfo._Instruction.uiAssociativeWays = (eaxreg >> 8) & 0xFF; -			CPUInfo._Instruction.uiEntries = eaxreg & 0xFF; -		} -		else if (ebxreg & 0xFFFF) -		{ -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 KB");	/*Flawfinder: ignore*/ -			CPUInfo._Instruction.uiAssociativeWays = (ebxreg >> 8) & 0xFF; -			CPUInfo._Instruction.uiEntries = ebxreg & 0xFF; -		} -		if (CPUInfo._Instruction.uiAssociativeWays == 0xFF) -			CPUInfo._Instruction.uiAssociativeWays = (unsigned int) -1; +		char cpu_brand_string[0x40]; +		len = sizeof(cpu_brand_string); +		memset(cpu_brand_string, 0, len); +		sysctlbyname("machdep.cpu.brand_string", (void*)cpu_brand_string, &len, NULL, 0); +		cpu_brand_string[0x3f] = 0; +		setInfo(eBrandName, cpu_brand_string); -		// Then we read the L1 data cache information -		if ((ecxreg >> 24) > 0) -		{ -			CPUInfo._L1.Data.bPresent = true; -			snprintf(CPUInfo._L1.Data.strSize, sizeof(CPUInfo._L1.Data.strSize), "%d KB", ecxreg >> 24);		/* Flawfinder: ignore */ -			CPUInfo._L1.Data.uiAssociativeWays = (ecxreg >> 15) & 0xFF; -			CPUInfo._L1.Data.uiLineSize = ecxreg & 0xFF; -		} -		// After that we read the L2 instruction/code cache information -		if ((edxreg >> 24) > 0) -		{ -			CPUInfo._L1.Instruction.bPresent = true; -			snprintf(CPUInfo._L1.Instruction.strSize, sizeof(CPUInfo._L1.Instruction.strSize), "%d KB", edxreg >> 24); 	/* Flawfinder: ignore */ -			CPUInfo._L1.Instruction.uiAssociativeWays = (edxreg >> 15) & 0xFF; -			CPUInfo._L1.Instruction.uiLineSize = edxreg & 0xFF; -		} - -		// Note: I'm not absolutely sure that the L1 page size code (the -		// 'if/else if/else if' structs above) really detects the real page -		// size for the TLB. Somebody should check it.... - -		// Now we read the ext. CPUID level 0x80000006 -        __asm -		{ -			mov eax, 0x80000006 -			cpuid -			mov eaxreg, eax -			mov ebxreg, ebx -			mov ecxreg, ecx -		} +		char cpu_vendor[0x20]; +		len = sizeof(cpu_vendor); +		memset(cpu_vendor, 0, len); +		sysctlbyname("machdep.cpu.vendor", (void*)cpu_vendor, &len, NULL, 0); +		cpu_vendor[0x1f] = 0; +		setInfo(eVendor, cpu_vendor); + +		setInfo(eStepping, getSysctlInt("machdep.cpu.stepping")); +		setInfo(eModel, getSysctlInt("machdep.cpu.model")); +		int family = getSysctlInt("machdep.cpu.family"); +		int ext_family = getSysctlInt("machdep.cpu.extfamily"); +		setInfo(eFamily, family); +		setInfo(eExtendedFamily, ext_family); +		setInfo(eFamilyName, compute_CPUFamilyName(cpu_vendor, family, ext_family)); +		setInfo(eExtendedModel, getSysctlInt("machdep.cpu.extmodel")); +		setInfo(eBrandID, getSysctlInt("machdep.cpu.brand")); +		setInfo(eType, 0); // ? where to find this? + +		//setConfig(eCLFLUSHCacheLineSize, ((cpu_info[1] >> 8) & 0xff) * 8); +		//setConfig(eAPICPhysicalID, (cpu_info[1] >> 24) & 0xff); +		setConfig(eCacheLineSize, getSysctlInt("machdep.cpu.cache.linesize")); +		setConfig(eL2Associativity, getSysctlInt("machdep.cpu.cache.L2_associativity")); +		setConfig(eCacheSizeK, getSysctlInt("machdep.cpu.cache.size")); +		 +		uint64_t feature_info = getSysctlInt64("machdep.cpu.feature_bits"); +		S32 *feature_infos = (S32*)(&feature_info); +		 +		setConfig(eFeatureBits, feature_infos[0]); -		// We only mask the unified L2 cache masks (never heard of an -		// L2 cache that is divided in data and code parts) -		if (((ecxreg >> 12) & 0xF) > 0) +		for(unsigned int index = 0, bit = 1; index < eSSE3_Features; ++index, bit <<= 1)  		{ -			CPUInfo._L2.bPresent = true; -			snprintf(CPUInfo._L2.strSize, sizeof(CPUInfo._L2.strSize), "%d KB", ecxreg >> 16);		/* Flawfinder: ignore */ -			switch ((ecxreg >> 12) & 0xF) +			if(feature_info & bit)  			{ -				case 1: -					CPUInfo._L2.uiAssociativeWays = 1; -					break; -				case 2: -					CPUInfo._L2.uiAssociativeWays = 2; -					break; -				case 4: -					CPUInfo._L2.uiAssociativeWays = 4; -					break; -				case 6: -					CPUInfo._L2.uiAssociativeWays = 8; -					break; -				case 8: -					CPUInfo._L2.uiAssociativeWays = 16; -					break; -				case 0xF: -					CPUInfo._L2.uiAssociativeWays = (unsigned int) -1; -					break; -				default: -					CPUInfo._L2.uiAssociativeWays = 0; -					break; +				setExtension(cpu_feature_names[index]);  			} -			CPUInfo._L2.uiLineSize = ecxreg & 0xFF;  		} -	} -	else -	{ -		// If we could not detect the ext. CPUID level 0x80000006 we -		// try to read the standard processor configuration. -		GetStandardProcessorConfiguration(); -	} -	// After reading we translate the configuration to strings -	TranslateProcessorConfiguration(); - -	// And finally exit -	return true; -#else -	return FALSE; -#endif -} - -// bool CProcessor::AnalyzeUnknownProcessor() -// ========================================== -// Private class function to analyze an unknown (No Intel or AMD) processor -/////////////////////////////////////////////////////////////////////////// -bool CProcessor::AnalyzeUnknownProcessor() -{ -#if LL_WINDOWS -	unsigned long eaxreg, ebxreg; - -	// We check if the CPUID command is available -	if (!CheckCPUIDPresence()) -		return false; - -	// First of all we read the standard CPUID level 0x00000001 -	// This level should be available on every x86-processor clone -	__asm -	{ -        mov eax, 1 -		cpuid -		mov eaxreg, eax -		mov ebxreg, ebx -	} -	// Then we mask the processor model, family, type and stepping -	CPUInfo.uiStepping = eaxreg & 0xF; -	CPUInfo.uiModel    = (eaxreg >> 4) & 0xF; -	CPUInfo.uiFamily   = (eaxreg >> 8) & 0xF; -	CPUInfo.uiType     = (eaxreg >> 12) & 0x3; - -	// To have complete information we also mask the brand id -	CPUInfo.uiBrandID  = ebxreg & 0xF; - -	// Then we get the standard processor extensions -	GetStandardProcessorExtensions(); - -	// Now we mark everything we do not know as unknown -	strcpy(strCPUName, "Unknown");		/*Flawfinder: ignore*/ - -	strcpy(CPUInfo._Data.strTLB, "Unknown");	/*Flawfinder: ignore*/ -	strcpy(CPUInfo._Instruction.strTLB, "Unknown");		/*Flawfinder: ignore*/ -	 -	strcpy(CPUInfo._Trace.strCache, "Unknown");		/*Flawfinder: ignore*/ -	strcpy(CPUInfo._L1.Data.strCache, "Unknown");		/*Flawfinder: ignore*/ -	strcpy(CPUInfo._L1.Instruction.strCache, "Unknown");	/*Flawfinder: ignore*/ -	strcpy(CPUInfo._L2.strCache, "Unknown");		/*Flawfinder: ignore*/ -	strcpy(CPUInfo._L3.strCache, "Unknown");		/*Flawfinder: ignore*/ - -	strcpy(CPUInfo.strProcessorSerial, "Unknown / Not supported");	/*Flawfinder: ignore*/ - -	// For the family, model and brand id we can only print the numeric value -	snprintf(CPUInfo.strBrandID, sizeof(CPUInfo.strBrandID), "Brand-ID number %d", CPUInfo.uiBrandID);		/* Flawfinder: ignore */ -	snprintf(CPUInfo.strFamily, sizeof(CPUInfo.strFamily), "Family number %d", CPUInfo.uiFamily);		/* Flawfinder: ignore */ -	snprintf(CPUInfo.strModel, sizeof(CPUInfo.strModel), "Model number %d", CPUInfo.uiModel);		/* Flawfinder: ignore */ - -	// And thats it -	return true; -#else -	return FALSE; -#endif -} - -// bool CProcessor::CheckCPUIDPresence() -// ===================================== -// This function checks if the CPUID command is available on the current -// processor -//////////////////////////////////////////////////////////////////////// -bool CProcessor::CheckCPUIDPresence() -{ -#if LL_WINDOWS -	unsigned long BitChanged; -	 -	// We've to check if we can toggle the flag register bit 21 -	// If we can't the processor does not support the CPUID command -	__asm -	{ -		pushfd -		pop eax -		mov ebx, eax -		xor eax, 0x00200000  -		push eax -		popfd -		pushfd -		pop eax -		xor eax,ebx  -		mov BitChanged, eax -	} -	return ((BitChanged) ? true : false); -#else -	return FALSE; -#endif -} +		// *NOTE:Mani - I didn't find any docs that assure me that machdep.cpu.feature_bits will always be +		// The feature bits I think it is. Here's a test: +#ifndef LL_RELEASE_FOR_DOWNLOAD +	#if defined(__i386__) && defined(__PIC__) +			/* %ebx may be the PIC register.  */ +		#define __cpuid(level, a, b, c, d)			\ +		__asm__ ("xchgl\t%%ebx, %1\n\t"			\ +				"cpuid\n\t"					\ +				"xchgl\t%%ebx, %1\n\t"			\ +				: "=a" (a), "=r" (b), "=c" (c), "=d" (d)	\ +				: "0" (level)) +	#else +		#define __cpuid(level, a, b, c, d)			\ +		__asm__ ("cpuid\n\t"					\ +				 : "=a" (a), "=b" (b), "=c" (c), "=d" (d)	\ +				 : "0" (level)) +	#endif + +		unsigned int eax, ebx, ecx, edx; +		__cpuid(0x1, eax, ebx, ecx, edx); +		if(feature_infos[0] != (S32)edx) +		{ +			llerrs << "machdep.cpu.feature_bits doesn't match expected cpuid result!" << llendl; +		}  +#endif // LL_RELEASE_FOR_DOWNLOAD 	 -// void CProcessor::DecodeProcessorConfiguration(unsigned int cfg) -// =============================================================== -// This function (or switch ?!) just translates a one-byte processor configuration -// byte to understandable values -////////////////////////////////////////////////////////////////////////////////// -void CProcessor::DecodeProcessorConfiguration(unsigned int cfg) -{ -	// First we ensure that there's only one single byte -	cfg &= 0xFF; -	// Then we do a big switch -	switch(cfg) -	{ -		case 0:			// cfg = 0:  Unused -			break; -		case 0x1:		// cfg = 0x1:  code TLB present, 4 KB pages, 4 ways, 32 entries -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 KB");	/*Flawfinder: ignore*/ -			CPUInfo._Instruction.uiAssociativeWays = 4; -			CPUInfo._Instruction.uiEntries = 32; -			break; -		case 0x2:		// cfg = 0x2:  code TLB present, 4 MB pages, fully associative, 2 entries -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 MB");	/*Flawfinder: ignore*/ -			CPUInfo._Instruction.uiAssociativeWays = 4; -			CPUInfo._Instruction.uiEntries = 2; -			break; -		case 0x3:		// cfg = 0x3:  data TLB present, 4 KB pages, 4 ways, 64 entries -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 KB");		/*Flawfinder: ignore*/ -			CPUInfo._Data.uiAssociativeWays = 4; -			CPUInfo._Data.uiEntries = 64; -			break; -		case 0x4:		// cfg = 0x4:  data TLB present, 4 MB pages, 4 ways, 8 entries -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 MB");	/*Flawfinder: ignore*/ -			CPUInfo._Data.uiAssociativeWays = 4; -			CPUInfo._Data.uiEntries = 8; -			break; -		case 0x6:		// cfg = 0x6:  code L1 cache present, 8 KB, 4 ways, 32 byte lines -			CPUInfo._L1.Instruction.bPresent = true; -			strcpy(CPUInfo._L1.Instruction.strSize, "8 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L1.Instruction.uiAssociativeWays = 4; -			CPUInfo._L1.Instruction.uiLineSize = 32; -			break; -		case 0x8:		// cfg = 0x8:  code L1 cache present, 16 KB, 4 ways, 32 byte lines -			CPUInfo._L1.Instruction.bPresent = true; -			strcpy(CPUInfo._L1.Instruction.strSize, "16 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L1.Instruction.uiAssociativeWays = 4; -			CPUInfo._L1.Instruction.uiLineSize = 32; -			break; -		case 0xA:		// cfg = 0xA:  data L1 cache present, 8 KB, 2 ways, 32 byte lines -			CPUInfo._L1.Data.bPresent = true; -			strcpy(CPUInfo._L1.Data.strSize, "8 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L1.Data.uiAssociativeWays = 2; -			CPUInfo._L1.Data.uiLineSize = 32; -			break; -		case 0xC:		// cfg = 0xC:  data L1 cache present, 16 KB, 4 ways, 32 byte lines -			CPUInfo._L1.Data.bPresent = true; -			strcpy(CPUInfo._L1.Data.strSize, "16 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L1.Data.uiAssociativeWays = 4; -			CPUInfo._L1.Data.uiLineSize = 32; -			break; -		case 0x22:		// cfg = 0x22:  code and data L3 cache present, 512 KB, 4 ways, 64 byte lines, sectored -			CPUInfo._L3.bPresent = true; -			strcpy(CPUInfo._L3.strSize, "512 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L3.uiAssociativeWays = 4; -			CPUInfo._L3.uiLineSize = 64; -			CPUInfo._L3.bSectored = true; -			break; -		case 0x23:		// cfg = 0x23:  code and data L3 cache present, 1024 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L3.bPresent = true; -			strcpy(CPUInfo._L3.strSize, "1024 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L3.uiAssociativeWays = 8; -			CPUInfo._L3.uiLineSize = 64; -			CPUInfo._L3.bSectored = true; -			break; -		case 0x25:		// cfg = 0x25:  code and data L3 cache present, 2048 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L3.bPresent = true; -			strcpy(CPUInfo._L3.strSize, "2048 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L3.uiAssociativeWays = 8; -			CPUInfo._L3.uiLineSize = 64; -			CPUInfo._L3.bSectored = true; -			break; -		case 0x29:		// cfg = 0x29:  code and data L3 cache present, 4096 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L3.bPresent = true; -			strcpy(CPUInfo._L3.strSize, "4096 KB");	/*Flawfinder: ignore*/ -			CPUInfo._L3.uiAssociativeWays = 8; -			CPUInfo._L3.uiLineSize = 64; -			CPUInfo._L3.bSectored = true; -			break; -		case 0x40:		// cfg = 0x40:  no integrated L2 cache (P6 core) or L3 cache (P4 core) -			break; -		case 0x41:		// cfg = 0x41:  code and data L2 cache present, 128 KB, 4 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "128 KB");		/*Flawfinder: ignore*/ -			CPUInfo._L2.uiAssociativeWays = 4; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x42:		// cfg = 0x42:  code and data L2 cache present, 256 KB, 4 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "256 KB");		/*Flawfinder: ignore*/ -			CPUInfo._L2.uiAssociativeWays = 4; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x43:		// cfg = 0x43:  code and data L2 cache present, 512 KB, 4 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "512 KB");		/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 4; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x44:		// cfg = 0x44:  code and data L2 cache present, 1024 KB, 4 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "1 MB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 4; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x45:		// cfg = 0x45:  code and data L2 cache present, 2048 KB, 4 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "2 MB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 4; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x50:		// cfg = 0x50:  code TLB present, 4 KB / 4 MB / 2 MB pages, fully associative, 64 entries -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 KB / 2 MB / 4 MB");	/* Flawfinder: ignore */ -			CPUInfo._Instruction.uiAssociativeWays = (unsigned int) -1; -			CPUInfo._Instruction.uiEntries = 64; -			break; -		case 0x51:		// cfg = 0x51:  code TLB present, 4 KB / 4 MB / 2 MB pages, fully associative, 128 entries -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 KB / 2 MB / 4 MB");	/* Flawfinder: ignore */ -			CPUInfo._Instruction.uiAssociativeWays = (unsigned int) -1; -			CPUInfo._Instruction.uiEntries = 128; -			break; -		case 0x52:		// cfg = 0x52:  code TLB present, 4 KB / 4 MB / 2 MB pages, fully associative, 256 entries -			CPUInfo._Instruction.bPresent = true; -			strcpy(CPUInfo._Instruction.strPageSize, "4 KB / 2 MB / 4 MB");	/* Flawfinder: ignore */ -			CPUInfo._Instruction.uiAssociativeWays = (unsigned int) -1; -			CPUInfo._Instruction.uiEntries = 256; -			break; -		case 0x5B:		// cfg = 0x5B:  data TLB present, 4 KB / 4 MB pages, fully associative, 64 entries -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 KB / 4 MB");	/* Flawfinder: ignore */ -			CPUInfo._Data.uiAssociativeWays = (unsigned int) -1; -			CPUInfo._Data.uiEntries = 64; -			break; -		case 0x5C:		// cfg = 0x5C:  data TLB present, 4 KB / 4 MB pages, fully associative, 128 entries -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 KB / 4 MB");	/* Flawfinder: ignore */ -			CPUInfo._Data.uiAssociativeWays = (unsigned int) -1; -			CPUInfo._Data.uiEntries = 128; -			break; -		case 0x5d:		// cfg = 0x5D:  data TLB present, 4 KB / 4 MB pages, fully associative, 256 entries -			CPUInfo._Data.bPresent = true; -			strcpy(CPUInfo._Data.strPageSize, "4 KB / 4 MB");	/* Flawfinder: ignore */ -			CPUInfo._Data.uiAssociativeWays = (unsigned int) -1; -			CPUInfo._Data.uiEntries = 256; -			break; -		case 0x66:		// cfg = 0x66:  data L1 cache present, 8 KB, 4 ways, 64 byte lines, sectored -			CPUInfo._L1.Data.bPresent = true; -			strcpy(CPUInfo._L1.Data.strSize, "8 KB");	/* Flawfinder: ignore */ -			CPUInfo._L1.Data.uiAssociativeWays = 4; -			CPUInfo._L1.Data.uiLineSize = 64; -			break; -		case 0x67:		// cfg = 0x67:  data L1 cache present, 16 KB, 4 ways, 64 byte lines, sectored -			CPUInfo._L1.Data.bPresent = true; -			strcpy(CPUInfo._L1.Data.strSize, "16 KB");	/* Flawfinder: ignore */ -			CPUInfo._L1.Data.uiAssociativeWays = 4; -			CPUInfo._L1.Data.uiLineSize = 64; -			break; -		case 0x68:		// cfg = 0x68:  data L1 cache present, 32 KB, 4 ways, 64 byte lines, sectored -			CPUInfo._L1.Data.bPresent = true; -			strcpy(CPUInfo._L1.Data.strSize, "32 KB");	/* Flawfinder: ignore */ -			CPUInfo._L1.Data.uiAssociativeWays = 4; -			CPUInfo._L1.Data.uiLineSize = 64; -			break; -		case 0x70:		// cfg = 0x70:  trace L1 cache present, 12 KuOPs, 4 ways -			CPUInfo._Trace.bPresent = true; -			strcpy(CPUInfo._Trace.strSize, "12 K-micro-ops");	/* Flawfinder: ignore */ -			CPUInfo._Trace.uiAssociativeWays = 4; -			break; -		case 0x71:		// cfg = 0x71:  trace L1 cache present, 16 KuOPs, 4 ways -			CPUInfo._Trace.bPresent = true; -			strcpy(CPUInfo._Trace.strSize, "16 K-micro-ops");	/* Flawfinder: ignore */ -			CPUInfo._Trace.uiAssociativeWays = 4; -			break; -		case 0x72:		// cfg = 0x72:  trace L1 cache present, 32 KuOPs, 4 ways -			CPUInfo._Trace.bPresent = true; -			strcpy(CPUInfo._Trace.strSize, "32 K-micro-ops");	/* Flawfinder: ignore */ -			CPUInfo._Trace.uiAssociativeWays = 4; -			break; -		case 0x79:		// cfg = 0x79:  code and data L2 cache present, 128 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "128 KB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 64; -			CPUInfo._L2.bSectored = true; -			break; -		case 0x7A:		// cfg = 0x7A:  code and data L2 cache present, 256 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "256 KB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 64; -			CPUInfo._L2.bSectored = true; -			break; -		case 0x7B:		// cfg = 0x7B:  code and data L2 cache present, 512 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "512 KB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 64; -			CPUInfo._L2.bSectored = true; -			break; -		case 0x7C:		// cfg = 0x7C:  code and data L2 cache present, 1024 KB, 8 ways, 64 byte lines, sectored -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "1 MB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 64; -			CPUInfo._L2.bSectored = true; -			break; -		case 0x81:		// cfg = 0x81:  code and data L2 cache present, 128 KB, 8 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "128 KB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x82:		// cfg = 0x82:  code and data L2 cache present, 256 KB, 8 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "256 KB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x83:		// cfg = 0x83:  code and data L2 cache present, 512 KB, 8 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "512 KB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x84:		// cfg = 0x84:  code and data L2 cache present, 1024 KB, 8 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "1 MB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 32; -			break; -		case 0x85:		// cfg = 0x85:  code and data L2 cache present, 2048 KB, 8 ways, 32 byte lines -			CPUInfo._L2.bPresent = true; -			strcpy(CPUInfo._L2.strSize, "2 MB");	/* Flawfinder: ignore */ -			CPUInfo._L2.uiAssociativeWays = 8; -			CPUInfo._L2.uiLineSize = 32; -			break; +		uint64_t ext_feature_info = getSysctlInt64("machdep.cpu.extfeature_bits"); +		S32 *ext_feature_infos = (S32*)(&ext_feature_info); +		setConfig(eExtFeatureBits, ext_feature_infos[0]);  	} -} +}; -FORCEINLINE static char *TranslateAssociativeWays(unsigned int uiWays, char *buf) -{ -	// We define 0xFFFFFFFF (= -1) as fully associative -    if (uiWays == ((unsigned int) -1)) -		strcpy(buf, "fully associative");	/* Flawfinder: ignore */ -	else -	{ -		if (uiWays == 1)			// A one way associative cache is just direct mapped -			strcpy(buf, "direct mapped");	/* Flawfinder: ignore */ -		else if (uiWays == 0)		// This should not happen... -			strcpy(buf, "unknown associative ways");	/* Flawfinder: ignore */ -		else						// The x-way associative cache -			sprintf(buf, "%d ways associative", uiWays);	/* Flawfinder: ignore */ -	} -	// To ease the function use we return the buffer -	return buf; -} -FORCEINLINE static void TranslateTLB(ProcessorTLB *tlb) -{ -	char buf[64];	/* Flawfinder: ignore */ +#elif LL_LINUX +const char CPUINFO_FILE[] = "/proc/cpuinfo"; -	// We just check if the TLB is present -	if (tlb->bPresent) -        snprintf(tlb->strTLB,sizeof(tlb->strTLB), "%s page size, %s, %d entries", tlb->strPageSize, TranslateAssociativeWays(tlb->uiAssociativeWays, buf), tlb->uiEntries);	/* Flawfinder: ignore */ -	else -        strcpy(tlb->strTLB, "Not present");	/* Flawfinder: ignore */ -} -FORCEINLINE static void TranslateCache(ProcessorCache *cache) +class LLProcessorInfoLinuxImpl : public LLProcessorInfoImpl  { -	char buf[64];	/* Flawfinder: ignore */ - -	// We just check if the cache is present -    if (cache->bPresent) -	{ -		// If present we construct the string -		snprintf(cache->strCache, sizeof(cache->strCache), "%s cache size, %s, %d bytes line size", cache->strSize, TranslateAssociativeWays(cache->uiAssociativeWays, buf), cache->uiLineSize);	/* Flawfinder: ignore */ -		if (cache->bSectored) -			strncat(cache->strCache, ", sectored", sizeof(cache->strCache)-strlen(cache->strCache)-1);	/* Flawfinder: ignore */ -	} -	else +public: +	LLProcessorInfoLinuxImpl()   	{ -		// Else we just say "Not present" -		strcpy(cache->strCache, "Not present");	/* Flawfinder: ignore */ +		get_proc_cpuinfo();  	} -} - -// void CProcessor::TranslateProcessorConfiguration() -// ================================================== -// Private class function to translate the processor configuration values -// to strings -///////////////////////////////////////////////////////////////////////// -void CProcessor::TranslateProcessorConfiguration() -{ -	// We just call the small functions defined above -	TranslateTLB(&CPUInfo._Data); -	TranslateTLB(&CPUInfo._Instruction); -	TranslateCache(&CPUInfo._Trace); +	virtual ~LLProcessorInfoLinuxImpl() {} +private: -	TranslateCache(&CPUInfo._L1.Instruction); -	TranslateCache(&CPUInfo._L1.Data); -	TranslateCache(&CPUInfo._L2); -	TranslateCache(&CPUInfo._L3); -} - -// void CProcessor::GetStandardProcessorConfiguration() -// ==================================================== -// Private class function to read the standard processor configuration -////////////////////////////////////////////////////////////////////// -void CProcessor::GetStandardProcessorConfiguration() -{ -#if LL_WINDOWS -	unsigned long eaxreg, ebxreg, ecxreg, edxreg; - -	// We check if the CPUID function is available -	if (!CheckCPUIDPresence()) -		return; - -	// First we check if the processor supports the standard -	// CPUID level 0x00000002 -	if (CPUInfo.MaxSupportedLevel >= 2) +	void get_proc_cpuinfo()  	{ -		// Now we go read the std. CPUID level 0x00000002 the first time -		unsigned long count, num = 255; -		for (count = 0; count < num; count++) +		std::map< std::string, std::string > cpuinfo; +		LLFILE* cpuinfo_fp = LLFile::fopen(CPUINFO_FILE, "rb"); +		if(cpuinfo_fp)  		{ -			__asm -			{ -				mov eax, 2 -				cpuid -				mov eaxreg, eax -				mov ebxreg, ebx -				mov ecxreg, ecx -				mov edxreg, edx -			} -			// We have to repeat this reading for 'num' times -			num = eaxreg & 0xFF; - -			// Then we call the big decode switch function -			DecodeProcessorConfiguration(eaxreg >> 8); -			DecodeProcessorConfiguration(eaxreg >> 16); -			DecodeProcessorConfiguration(eaxreg >> 24); - -			// If ebx contains additional data we also decode it -			if ((ebxreg & 0x80000000) == 0) +			char line[MAX_STRING]; +			memset(line, 0, MAX_STRING); +			while(fgets(line, MAX_STRING, cpuinfo_fp))  			{ -				DecodeProcessorConfiguration(ebxreg); -				DecodeProcessorConfiguration(ebxreg >> 8); -				DecodeProcessorConfiguration(ebxreg >> 16); -				DecodeProcessorConfiguration(ebxreg >> 24); -			} -			// And also the ecx register -			if ((ecxreg & 0x80000000) == 0) -			{ -				DecodeProcessorConfiguration(ecxreg); -				DecodeProcessorConfiguration(ecxreg >> 8); -				DecodeProcessorConfiguration(ecxreg >> 16); -				DecodeProcessorConfiguration(ecxreg >> 24); -			} -			// At last the edx processor register -			if ((edxreg & 0x80000000) == 0) -			{ -				DecodeProcessorConfiguration(edxreg); -				DecodeProcessorConfiguration(edxreg >> 8); -				DecodeProcessorConfiguration(edxreg >> 16); -				DecodeProcessorConfiguration(edxreg >> 24); +				// /proc/cpuinfo on Linux looks like: +				// name\t*: value\n +				char* tabspot = strchr( line, '\t' ); +				if (tabspot == NULL) +					continue; +				char* colspot = strchr( tabspot, ':' ); +				if (colspot == NULL) +					continue; +				char* spacespot = strchr( colspot, ' ' ); +				if (spacespot == NULL) +					continue; +				char* nlspot = strchr( line, '\n' ); +				if (nlspot == NULL) +					nlspot = line + strlen( line ); // Fallback to terminating NUL +				std::string linename( line, tabspot ); +				std::string llinename(linename); +				LLStringUtil::toLower(llinename); +				std::string lineval( spacespot + 1, nlspot ); +				cpuinfo[ llinename ] = lineval;  			} +			fclose(cpuinfo_fp); +		} +# if LL_X86 + +// *NOTE:Mani - eww, macros! srry. +#define LLPI_SET_INFO_STRING(llpi_id, cpuinfo_id) \ +		if (!cpuinfo[cpuinfo_id].empty()) \ +		{ setInfo(llpi_id, cpuinfo[cpuinfo_id]);} + +#define LLPI_SET_INFO_INT(llpi_id, cpuinfo_id) \ +		{\ +			S32 result; \ +			if (!cpuinfo[cpuinfo_id].empty() \ +				&& LLStringUtil::convertToS32(cpuinfo[cpuinfo_id], result))	\ +		    { setInfo(llpi_id, result);} \ +		} +		 +		F64 mhz; +		if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz) +			&& 200.0 < mhz && mhz < 10000.0) +		{ +		    setInfo(eFrequency,(F64)(mhz));  		} -	} -#endif -} -// void CProcessor::GetStandardProcessorExtensions() -// ================================================= -// Private class function to read the standard processor extensions -/////////////////////////////////////////////////////////////////// -void CProcessor::GetStandardProcessorExtensions() -{ -#if LL_WINDOWS -	unsigned long ebxreg, edxreg; +		LLPI_SET_INFO_STRING(eBrandName, "model name");		 +		LLPI_SET_INFO_STRING(eVendor, "vendor_id"); -	// We check if the CPUID command is available -	if (!CheckCPUIDPresence()) -		return; -	// We just get the standard CPUID level 0x00000001 which should be -	// available on every x86 processor -	__asm -	{ -		mov eax, 1 -		cpuid -		mov ebxreg, ebx -		mov edxreg, edx -	} -     -	// Then we mask some bits -	CPUInfo._Ext.FPU_FloatingPointUnit							= CheckBit(edxreg, 0); -	CPUInfo._Ext.VME_Virtual8086ModeEnhancements				= CheckBit(edxreg, 1); -	CPUInfo._Ext.DE_DebuggingExtensions							= CheckBit(edxreg, 2); -	CPUInfo._Ext.PSE_PageSizeExtensions							= CheckBit(edxreg, 3); -	CPUInfo._Ext.TSC_TimeStampCounter							= CheckBit(edxreg, 4); -	CPUInfo._Ext.MSR_ModelSpecificRegisters						= CheckBit(edxreg, 5); -	CPUInfo._Ext.PAE_PhysicalAddressExtension					= CheckBit(edxreg, 6); -	CPUInfo._Ext.MCE_MachineCheckException						= CheckBit(edxreg, 7); -	CPUInfo._Ext.CX8_COMPXCHG8B_Instruction						= CheckBit(edxreg, 8); -	CPUInfo._Ext.APIC_AdvancedProgrammableInterruptController	= CheckBit(edxreg, 9); -	CPUInfo._Ext.APIC_ID = (ebxreg >> 24) & 0xFF; -	CPUInfo._Ext.SEP_FastSystemCall								= CheckBit(edxreg, 11); -	CPUInfo._Ext.MTRR_MemoryTypeRangeRegisters					= CheckBit(edxreg, 12); -	CPUInfo._Ext.PGE_PTE_GlobalFlag								= CheckBit(edxreg, 13); -	CPUInfo._Ext.MCA_MachineCheckArchitecture					= CheckBit(edxreg, 14); -	CPUInfo._Ext.CMOV_ConditionalMoveAndCompareInstructions		= CheckBit(edxreg, 15); -	CPUInfo._Ext.FGPAT_PageAttributeTable						= CheckBit(edxreg, 16); -	CPUInfo._Ext.PSE36_36bitPageSizeExtension					= CheckBit(edxreg, 17); -	CPUInfo._Ext.PN_ProcessorSerialNumber						= CheckBit(edxreg, 18); -	CPUInfo._Ext.CLFSH_CFLUSH_Instruction						= CheckBit(edxreg, 19); -	CPUInfo._Ext.CLFLUSH_InstructionCacheLineSize = (ebxreg >> 8) & 0xFF; -	CPUInfo._Ext.DS_DebugStore									= CheckBit(edxreg, 21); -	CPUInfo._Ext.ACPI_ThermalMonitorAndClockControl				= CheckBit(edxreg, 22); -	CPUInfo._Ext.MMX_MultimediaExtensions						= CheckBit(edxreg, 23); -	CPUInfo._Ext.FXSR_FastStreamingSIMD_ExtensionsSaveRestore	= CheckBit(edxreg, 24); -	CPUInfo._Ext.SSE_StreamingSIMD_Extensions					= CheckBit(edxreg, 25); -	CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions					= CheckBit(edxreg, 26); -	CPUInfo._Ext.Altivec_Extensions = false; -	CPUInfo._Ext.SS_SelfSnoop									= CheckBit(edxreg, 27); -	CPUInfo._Ext.HT_HyperThreading								= CheckBit(edxreg, 28); -	CPUInfo._Ext.HT_HyterThreadingSiblings = (ebxreg >> 16) & 0xFF; -	CPUInfo._Ext.TM_ThermalMonitor								= CheckBit(edxreg, 29); -	CPUInfo._Ext.IA64_Intel64BitArchitecture					= CheckBit(edxreg, 30); -#endif -} +		LLPI_SET_INFO_INT(eStepping, "stepping"); +		LLPI_SET_INFO_INT(eModel, "model"); -// const ProcessorInfo *CProcessor::GetCPUInfo() -// ============================================= -// Calls all the other detection function to create an detailed -// processor information -/////////////////////////////////////////////////////////////// -const ProcessorInfo *CProcessor::GetCPUInfo() -{ -#if LL_WINDOWS -	unsigned long eaxreg, ebxreg, ecxreg, edxreg; +		 +		S32 family;							  +		if (!cpuinfo["cpu family"].empty()  +			&& LLStringUtil::convertToS32(cpuinfo["cpu family"], family))	 +		{  +			setInfo(eFamily, family); +		} -	// First of all we check if the CPUID command is available -	if (!CheckCPUIDPresence()) -		return NULL; +		setInfo(eFamilyName, compute_CPUFamilyName(cpuinfo["vendor_id"].c_str(), family)); -	// We read the standard CPUID level 0x00000000 which should -	// be available on every x86 processor -	__asm -	{ -		mov eax, 0 -		cpuid -		mov eaxreg, eax -		mov ebxreg, ebx -		mov edxreg, edx -		mov ecxreg, ecx -	} -	// Then we connect the single register values to the vendor string -	*((unsigned long *) CPUInfo.strVendor) = ebxreg; -	*((unsigned long *) (CPUInfo.strVendor+4)) = edxreg; -	*((unsigned long *) (CPUInfo.strVendor+8)) = ecxreg; -	// Null terminate for string comparisons below. -	CPUInfo.strVendor[12] = 0; - -	// We can also read the max. supported standard CPUID level -	CPUInfo.MaxSupportedLevel = eaxreg & 0xFFFF; - -	// Then we read the ext. CPUID level 0x80000000 -	__asm -	{ -        mov eax, 0x80000000 -		cpuid -		mov eaxreg, eax -	} -	// ...to check the max. supportted extended CPUID level -	CPUInfo.MaxSupportedExtendedLevel = eaxreg; - -	// Then we switch to the specific processor vendors -	// See http://www.sandpile.org/ia32/cpuid.htm -	if (!strcmp(CPUInfo.strVendor, "GenuineIntel")) -	{ -		AnalyzeIntelProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "AuthenticAMD")) -	{ -		AnalyzeAMDProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "UMC UMC UMC")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "CyrixInstead")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "NexGenDriven")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "CentaurHauls")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "RiseRiseRise")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "SiS SiS SiS")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "GenuineTMx86")) -	{ -		// Transmeta -		AnalyzeUnknownProcessor(); -	} -	else if (!strcmp(CPUInfo.strVendor, "Geode by NSC")) -	{ -		AnalyzeUnknownProcessor(); -	} -	else -	{ -		AnalyzeUnknownProcessor(); -	} -#endif -	// After all we return the class CPUInfo member var -	return (&CPUInfo); -} +		// setInfo(eExtendedModel, getSysctlInt("machdep.cpu.extmodel")); +		// setInfo(eBrandID, getSysctlInt("machdep.cpu.brand")); +		// setInfo(eType, 0); // ? where to find this? -#elif LL_SOLARIS -#include <kstat.h> - -#if defined(__i386) -#include <sys/auxv.h> -#endif - -// ====================== -// Class constructor: -///////////////////////// -CProcessor::CProcessor() -{ -	uqwFrequency = 0; -	strCPUName[0] = 0; -	memset(&CPUInfo, 0, sizeof(CPUInfo)); -} - -// unsigned __int64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs) -// ========================================================================= -// Function to query the current CPU frequency -//////////////////////////////////////////////////////////////////////////// -F64 CProcessor::GetCPUFrequency(unsigned int /*uiMeasureMSecs*/) -{ -	if(uqwFrequency == 0){ -		GetCPUInfo(); -	} - -	return uqwFrequency; -} - -// const ProcessorInfo *CProcessor::GetCPUInfo() -// ============================================= -// Calls all the other detection function to create an detailed -// processor information -/////////////////////////////////////////////////////////////// -const ProcessorInfo *CProcessor::GetCPUInfo() -{ -					// In Solaris the CPU info is in the kstats -					// try "psrinfo" or "kstat cpu_info" to see all -					// that's available -	int ncpus=0, i;  -	kstat_ctl_t	*kc; -	kstat_t 	*ks; -	kstat_named_t   *ksinfo, *ksi; -	kstat_t 	*CPU_stats_list; - -	kc = kstat_open(); - -	if((int)kc == -1){ -		llwarns << "kstat_open(0 failed!" << llendl; -		return (&CPUInfo); -	} - -	for (ks = kc->kc_chain; ks != NULL; ks = ks->ks_next) { -		if (strncmp(ks->ks_module, "cpu_info", 8) == 0 && -			strncmp(ks->ks_name, "cpu_info", 8) == 0) -			ncpus++; -	} -	 -	if(ncpus < 1){ -		llwarns << "No cpus found in kstats!" << llendl; -		return (&CPUInfo); -	} - -	for (ks = kc->kc_chain; ks; ks = ks->ks_next) { -		if (strncmp(ks->ks_module, "cpu_info", 8) == 0  -		&&  strncmp(ks->ks_name, "cpu_info", 8) == 0  -		&&  kstat_read(kc, ks, NULL) != -1){      -			CPU_stats_list = ks;	// only looking at the first CPU -			 -			break; -		} -	} - -	if(ncpus > 1) -        	snprintf(strCPUName, sizeof(strCPUName), "%d x ", ncpus);  - -	kstat_read(kc, CPU_stats_list, NULL); -	ksinfo = (kstat_named_t *)CPU_stats_list->ks_data; -	for(i=0; i < (int)(CPU_stats_list->ks_ndata); ++i){ // Walk the kstats for this cpu gathering what we need -		ksi = ksinfo++; -		if(!strcmp(ksi->name, "brand")){ -			strncat(strCPUName, (char *)KSTAT_NAMED_STR_PTR(ksi), -				sizeof(strCPUName)-strlen(strCPUName)-1); -			strncat(CPUInfo.strFamily, (char *)KSTAT_NAMED_STR_PTR(ksi), -				sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1); -			strncpy(CPUInfo.strBrandID, strCPUName,sizeof(CPUInfo.strBrandID)-1); -			CPUInfo.strBrandID[sizeof(CPUInfo.strBrandID)-1]='\0'; -			// DEBUG llinfos << "CPU brand: " << strCPUName << llendl; -			continue; -		} +		//setConfig(eCLFLUSHCacheLineSize, ((cpu_info[1] >> 8) & 0xff) * 8); +		//setConfig(eAPICPhysicalID, (cpu_info[1] >> 24) & 0xff); +		//setConfig(eCacheLineSize, getSysctlInt("machdep.cpu.cache.linesize")); +		//setConfig(eL2Associativity, getSysctlInt("machdep.cpu.cache.L2_associativity")); +		//setConfig(eCacheSizeK, getSysctlInt("machdep.cpu.cache.size")); +		 +		// Read extensions +		std::string flags = " " + cpuinfo["flags"] + " "; +		LLStringUtil::toLower(flags); -		if(!strcmp(ksi->name, "clock_MHz")){ -#if defined(__sparc) -			llinfos << "Raw kstat clock rate is: " << ksi->value.l << llendl; -			uqwFrequency = (F64)(ksi->value.l * 1000000); -#else -			uqwFrequency = (F64)(ksi->value.i64 * 1000000); -#endif -			//DEBUG llinfos << "CPU frequency: " << uqwFrequency << llendl; -			continue; +		if( flags.find( " sse " ) != std::string::npos ) +		{ +			setExtension(cpu_feature_names[eSSE_Ext]);   		} -#if defined(__i386) -		if(!strcmp(ksi->name, "vendor_id")){ -			strncpy(CPUInfo.strVendor, (char *)KSTAT_NAMED_STR_PTR(ksi), sizeof(CPUInfo.strVendor)-1); -			// DEBUG llinfos << "CPU vendor: " << CPUInfo.strVendor << llendl; -			continue; +		if( flags.find( " sse2 " ) != std::string::npos ) +		{ +			setExtension(cpu_feature_names[eSSE2_Ext]);  		} -#endif -	} - -	kstat_close(kc); - -#if defined(__sparc)		// SPARC does not define a vendor string in kstat -	strncpy(CPUInfo.strVendor, "Sun Microsystems, Inc.", sizeof(CPUInfo.strVendor)-1); -#endif - -	// DEBUG llinfo << "The system has " << ncpus << " CPUs with a clock rate of " <<  uqwFrequency << "MHz." << llendl; -	 -#if defined (__i386)  //  we really don't care about the CPU extensions on SPARC but on x86... - -	// Now get cpu extensions - -	uint_t ui; - -	(void) getisax(&ui, 1); -	if(ui & AV_386_FPU) -		CPUInfo._Ext.FPU_FloatingPointUnit = true; -	if(ui & AV_386_CX8) -		CPUInfo._Ext.CX8_COMPXCHG8B_Instruction = true; -	if(ui & AV_386_MMX) -		CPUInfo._Ext.MMX_MultimediaExtensions = true; -	if(ui & AV_386_AMD_MMX) -		CPUInfo._Ext.MMX_MultimediaExtensions = true; -	if(ui & AV_386_FXSR) -		CPUInfo._Ext.FXSR_FastStreamingSIMD_ExtensionsSaveRestore = true; -	if(ui & AV_386_SSE) -		 CPUInfo._Ext.SSE_StreamingSIMD_Extensions = true; -	if(ui & AV_386_SSE2) -		CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions = true; -/* Left these here since they may get used later -	if(ui & AV_386_SSE3) -		CPUInfo._Ext.... = true; -	if(ui & AV_386_AMD_3DNow) -		CPUInfo._Ext.... = true; -	if(ui & AV_386_AMD_3DNowx) -		CPUInfo._Ext.... = true; -*/ -#endif -	return (&CPUInfo); -} - -#else -// LL_DARWIN - -#include <mach/machine.h> -#include <sys/sysctl.h> - -static char *TranslateAssociativeWays(unsigned int uiWays, char *buf) -{ -	// We define 0xFFFFFFFF (= -1) as fully associative -    if (uiWays == ((unsigned int) -1)) -		strcpy(buf, "fully associative");	/* Flawfinder: ignore */ -	else -	{ -		if (uiWays == 1)			// A one way associative cache is just direct mapped -			strcpy(buf, "direct mapped");	/* Flawfinder: ignore */ -		else if (uiWays == 0)		// This should not happen... -			strcpy(buf, "unknown associative ways");	/* Flawfinder: ignore */ -		else						// The x-way associative cache -			sprintf(buf, "%d ways associative", uiWays);	/* Flawfinder: ignore */ +# endif // LL_X86  	} -	// To ease the function use we return the buffer -	return buf; -} -static void TranslateTLB(ProcessorTLB *tlb) -{ -	char buf[64];	/* Flawfinder: ignore */ - -	// We just check if the TLB is present -	if (tlb->bPresent) -        snprintf(tlb->strTLB, sizeof(tlb->strTLB), "%s page size, %s, %d entries", tlb->strPageSize, TranslateAssociativeWays(tlb->uiAssociativeWays, buf), tlb->uiEntries);	/* Flawfinder: ignore */ -	else -        strcpy(tlb->strTLB, "Not present");	/* Flawfinder: ignore */ -} -static void TranslateCache(ProcessorCache *cache) -{ -	char buf[64];	/* Flawfinder: ignore */ -	// We just check if the cache is present -    if (cache->bPresent) +	std::string getCPUFeatureDescription() const   	{ -		// If present we construct the string -		snprintf(cache->strCache,sizeof(cache->strCache), "%s cache size, %s, %d bytes line size", cache->strSize, TranslateAssociativeWays(cache->uiAssociativeWays, buf), cache->uiLineSize);	/* Flawfinder: ignore */ -		if (cache->bSectored) -			strncat(cache->strCache, ", sectored", sizeof(cache->strCache)-strlen(cache->strCache)-1);	/* Flawfinder: ignore */ -	} -	else -	{ -		// Else we just say "Not present" -		strcpy(cache->strCache, "Not present");	/* Flawfinder: ignore */ -	} -} - -// void CProcessor::TranslateProcessorConfiguration() -// ================================================== -// Private class function to translate the processor configuration values -// to strings -///////////////////////////////////////////////////////////////////////// -void CProcessor::TranslateProcessorConfiguration() -{ -	// We just call the small functions defined above -	TranslateTLB(&CPUInfo._Data); -	TranslateTLB(&CPUInfo._Instruction); - -	TranslateCache(&CPUInfo._Trace); +		std::ostringstream s; -	TranslateCache(&CPUInfo._L1.Instruction); -	TranslateCache(&CPUInfo._L1.Data); -	TranslateCache(&CPUInfo._L2); -	TranslateCache(&CPUInfo._L3); -} - -// CProcessor::CProcessor -// ====================== -// Class constructor: -///////////////////////// -CProcessor::CProcessor() -{ -	uqwFrequency = 0; -	strCPUName[0] = 0; -	memset(&CPUInfo, 0, sizeof(CPUInfo)); -} - -// unsigned __int64 CProcessor::GetCPUFrequency(unsigned int uiMeasureMSecs) -// ========================================================================= -// Function to query the current CPU frequency -//////////////////////////////////////////////////////////////////////////// -F64 CProcessor::GetCPUFrequency(unsigned int /*uiMeasureMSecs*/) -{ -	U64 frequency = 0; -	size_t len = sizeof(frequency); -	 -	if(sysctlbyname("hw.cpufrequency", &frequency, &len, NULL, 0) == 0) -	{ -		uqwFrequency = (F64)frequency; -	} -	 -	return uqwFrequency; -} - -static bool hasFeature(const char *name) -{ -	bool result = false; -	int val = 0; -	size_t len = sizeof(val); -	 -	if(sysctlbyname(name, &val, &len, NULL, 0) == 0) -	{ -		if(val != 0) -			result = true; -	} -	 -	return result; -} - -// const ProcessorInfo *CProcessor::GetCPUInfo() -// ============================================= -// Calls all the other detection function to create an detailed -// processor information -/////////////////////////////////////////////////////////////// -const ProcessorInfo *CProcessor::GetCPUInfo() -{ -	int pagesize = 0; -	int cachelinesize = 0; -	int l1icachesize = 0; -	int l1dcachesize = 0; -	int l2settings = 0; -	int l2cachesize = 0; -	int l3settings = 0; -	int l3cachesize = 0; -	int ncpu = 0; -	int cpusubtype = 0; -	 -	// sysctl knows all. -	int mib[2]; -	size_t len; -	mib[0] = CTL_HW; -	 -	mib[1] = HW_PAGESIZE; -	len = sizeof(pagesize); -	sysctl(mib, 2, &pagesize, &len, NULL, 0); - -	mib[1] = HW_CACHELINE; -	len = sizeof(cachelinesize); -	sysctl(mib, 2, &cachelinesize, &len, NULL, 0); -	 -	mib[1] = HW_L1ICACHESIZE; -	len = sizeof(l1icachesize); -	sysctl(mib, 2, &l1icachesize, &len, NULL, 0); -	 -	mib[1] = HW_L1DCACHESIZE; -	len = sizeof(l1dcachesize); -	sysctl(mib, 2, &l1dcachesize, &len, NULL, 0); -	 -	mib[1] = HW_L2SETTINGS; -	len = sizeof(l2settings); -	sysctl(mib, 2, &l2settings, &len, NULL, 0); -	 -	mib[1] = HW_L2CACHESIZE; -	len = sizeof(l2cachesize); -	sysctl(mib, 2, &l2cachesize, &len, NULL, 0); -	 -	mib[1] = HW_L3SETTINGS; -	len = sizeof(l3settings); -	sysctl(mib, 2, &l3settings, &len, NULL, 0); -	 -	mib[1] = HW_L3CACHESIZE; -	len = sizeof(l3cachesize); -	sysctl(mib, 2, &l3cachesize, &len, NULL, 0); -	 -	mib[1] = HW_NCPU; -	len = sizeof(ncpu); -	sysctl(mib, 2, &ncpu, &len, NULL, 0); -	 -	sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0); -	 -	strCPUName[0] = 0; -	 -	if((ncpu == 0) || (ncpu == 1)) -	{ -		// Uhhh... -	} -	else if(ncpu == 2) -	{ -		strncat(strCPUName, "Dual ", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -	} -	else -	{ -		snprintf(strCPUName, sizeof(strCPUName), "%d x ", ncpu);	/* Flawfinder: ignore */ -	} -	 -#if __ppc__ -	switch(cpusubtype) -	{ -		case CPU_SUBTYPE_POWERPC_601://         ((cpu_subtype_t) 1) -			strncat(strCPUName, "PowerPC 601", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -			 -		break; -		case CPU_SUBTYPE_POWERPC_602://         ((cpu_subtype_t) 2) -			strncat(strCPUName, "PowerPC 602", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_603://         ((cpu_subtype_t) 3) -			strncat(strCPUName, "PowerPC 603", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_603e://        ((cpu_subtype_t) 4) -			strncat(strCPUName, "PowerPC 603e", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_603ev://       ((cpu_subtype_t) 5) -			strncat(strCPUName, "PowerPC 603ev", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_604://         ((cpu_subtype_t) 6) -			strncat(strCPUName, "PowerPC 604", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_604e://        ((cpu_subtype_t) 7) -			strncat(strCPUName, "PowerPC 604e", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_620://			((cpu_subtype_t) 8) -			strncat(strCPUName, "PowerPC 620", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_750://         ((cpu_subtype_t) 9) -			strncat(strCPUName, "PowerPC 750", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC G3", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_7400://        ((cpu_subtype_t) 10) -			strncat(strCPUName, "PowerPC 7400", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC G4", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_7450://        ((cpu_subtype_t) 11) -			strncat(strCPUName, "PowerPC 7450", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC G4", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; -		case CPU_SUBTYPE_POWERPC_970://         ((cpu_subtype_t) 100) -			strncat(strCPUName, "PowerPC 970", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -			strncat(CPUInfo.strFamily, "PowerPC G5", sizeof(CPUInfo.strFamily)-strlen(CPUInfo.strFamily)-1);	/* Flawfinder: ignore */ -		break; - -		default: -			strncat(strCPUName, "PowerPC (Unknown)", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */ -		break; -	} - -	CPUInfo._Ext.EMMX_MultimediaExtensions =  -	CPUInfo._Ext.MMX_MultimediaExtensions =  -	CPUInfo._Ext.SSE_StreamingSIMD_Extensions = -	CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions = false; - -	CPUInfo._Ext.Altivec_Extensions = hasFeature("hw.optional.altivec"); - -#endif - -#if __i386__ -	// MBW -- XXX -- TODO -- make this call AnalyzeIntelProcessor()? -	switch(cpusubtype) -	{ -		default: -			strncat(strCPUName, "i386 (Unknown)", sizeof(strCPUName)-strlen(strCPUName)-1);	/* Flawfinder: ignore */	 -		break; -	} - -	CPUInfo._Ext.EMMX_MultimediaExtensions = hasFeature("hw.optional.mmx");  // MBW -- XXX -- this may be wrong... -	CPUInfo._Ext.MMX_MultimediaExtensions = hasFeature("hw.optional.mmx"); -	CPUInfo._Ext.SSE_StreamingSIMD_Extensions = hasFeature("hw.optional.sse"); -	CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions = hasFeature("hw.optional.sse2"); -	CPUInfo._Ext.Altivec_Extensions = false; -	CPUInfo._Ext.AA64_AMD64BitArchitecture = hasFeature("hw.optional.x86_64"); - -#endif - -	// Terse CPU info uses this string... -	strncpy(CPUInfo.strBrandID, strCPUName,sizeof(CPUInfo.strBrandID)-1);	/* Flawfinder: ignore */	 -	CPUInfo.strBrandID[sizeof(CPUInfo.strBrandID)-1]='\0'; -	 -	// Fun cache config stuff... -	 -	if(l1dcachesize != 0) -	{ -		CPUInfo._L1.Data.bPresent = true; -		snprintf(CPUInfo._L1.Data.strSize, sizeof(CPUInfo._L1.Data.strSize), "%d KB", l1dcachesize / 1024);	/* Flawfinder: ignore */ -//		CPUInfo._L1.Data.uiAssociativeWays = ???; -		CPUInfo._L1.Data.uiLineSize = cachelinesize; +		// *NOTE:Mani - This is for linux only. +		LLFILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, "rb"); +		if(cpuinfo) +		{ +			char line[MAX_STRING]; +			memset(line, 0, MAX_STRING); +			while(fgets(line, MAX_STRING, cpuinfo)) +			{ +				line[strlen(line)-1] = ' '; +				s << line; +				s << std::endl; +			} +			fclose(cpuinfo); +			s << std::endl; +		} +		else +		{ +			s << "Unable to collect processor information" << std::endl; +		} +		return s.str();  	} +		 +}; -	if(l1icachesize != 0) -	{ -		CPUInfo._L1.Instruction.bPresent = true; -		snprintf(CPUInfo._L1.Instruction.strSize, sizeof(CPUInfo._L1.Instruction.strSize), "%d KB", l1icachesize / 1024);	/* Flawfinder: ignore */ -//		CPUInfo._L1.Instruction.uiAssociativeWays = ???; -		CPUInfo._L1.Instruction.uiLineSize = cachelinesize; -	} -	if(l2cachesize != 0) -	{ -		CPUInfo._L2.bPresent = true; -		snprintf(CPUInfo._L2.strSize, sizeof(CPUInfo._L2.strSize), "%d KB", l2cachesize / 1024);	/* Flawfinder: ignore */ -//		CPUInfo._L2.uiAssociativeWays = ???; -		CPUInfo._L2.uiLineSize = cachelinesize; -	} +#endif // LL_MSVC elif LL_DARWIN elif LL_LINUX -	if(l3cachesize != 0) -	{ -		CPUInfo._L2.bPresent = true; -		snprintf(CPUInfo._L2.strSize, sizeof(CPUInfo._L2.strSize), "%d KB", l3cachesize / 1024);	/* Flawfinder: ignore */ -//		CPUInfo._L2.uiAssociativeWays = ???; -		CPUInfo._L2.uiLineSize = cachelinesize; +////////////////////////////////////////////////////// +// Interface definition +LLProcessorInfo::LLProcessorInfo() : mImpl(NULL) +{ +	// *NOTE:Mani - not thread safe. +	if(!mImpl) +	{ +#ifdef LL_MSVC +		static LLProcessorInfoWindowsImpl the_impl;  +		mImpl = &the_impl; +#elif LL_DARWIN +		static LLProcessorInfoDarwinImpl the_impl;  +		mImpl = &the_impl; +#else +		static LLProcessorInfoLinuxImpl the_impl;  +		mImpl = &the_impl;		 +#endif // LL_MSVC  	} -	 -	CPUInfo._Ext.FPU_FloatingPointUnit = hasFeature("hw.optional.floatingpoint"); - -//	printf("pagesize = 0x%x\n", pagesize); -//	printf("cachelinesize = 0x%x\n", cachelinesize); -//	printf("l1icachesize = 0x%x\n", l1icachesize); -//	printf("l1dcachesize = 0x%x\n", l1dcachesize); -//	printf("l2settings = 0x%x\n", l2settings); -//	printf("l2cachesize = 0x%x\n", l2cachesize); -//	printf("l3settings = 0x%x\n", l3settings); -//	printf("l3cachesize = 0x%x\n", l3cachesize); -	 -	// After reading we translate the configuration to strings -	TranslateProcessorConfiguration(); - -	// After all we return the class CPUInfo member var -	return (&CPUInfo);  } -#endif // LL_DARWIN -// bool CProcessor::CPUInfoToText(char *strBuffer, unsigned int uiMaxLen) -// ====================================================================== -// Gets the frequency and processor information and writes it to a string -///////////////////////////////////////////////////////////////////////// -bool CProcessor::CPUInfoToText(char *strBuffer, unsigned int uiMaxLen) -{ -#define LENCHECK                len = (unsigned int) strlen(buf); if (len >= uiMaxLen) return false; strcpy(strBuffer, buf); strBuffer += len;     /*Flawfinder: ignore*/ -#define COPYADD(str)            strcpy(buf, str); LENCHECK;    /* Flawfinder: ignore */ -#define FORMATADD(format, var)  sprintf(buf, format, var); LENCHECK;    /* Flawfinder: ignore */ -#define BOOLADD(str, boolvar)   COPYADD(str); if (boolvar) { COPYADD(" Yes\n"); } else { COPYADD(" No\n"); } - -	char buf[1024];	/* Flawfinder: ignore */	 -	unsigned int len; - -	// First we have to get the frequency -    GetCPUFrequency(50); - -	// Then we get the processor information -	GetCPUInfo(); - -    // Now we construct the string (see the macros at function beginning) -	strBuffer[0] = 0; - -	COPYADD("// CPU General Information\n//////////////////////////\n"); -	FORMATADD("Processor name:   %s\n", strCPUName); -	FORMATADD("Frequency:        %.2f MHz\n\n", (float) uqwFrequency / 1000000.0f); -	FORMATADD("Vendor:           %s\n", CPUInfo.strVendor); -	FORMATADD("Family:           %s\n", CPUInfo.strFamily); -	FORMATADD("Extended family:  %d\n", CPUInfo.uiExtendedFamily); -	FORMATADD("Model:            %s\n", CPUInfo.strModel); -	FORMATADD("Extended model:   %d\n", CPUInfo.uiExtendedModel); -	FORMATADD("Type:             %s\n", CPUInfo.strType); -	FORMATADD("Brand ID:         %s\n", CPUInfo.strBrandID); -	if (CPUInfo._Ext.PN_ProcessorSerialNumber) -	{ -		FORMATADD("Processor Serial: %s\n", CPUInfo.strProcessorSerial); -	} -	else -	{ -	  COPYADD("Processor Serial: Disabled\n"); -	} -#if !LL_SOLARIS		//  NOTE: Why bother printing all this when it's irrelavent - -	COPYADD("\n\n// CPU Configuration\n////////////////////\n"); -	FORMATADD("L1 instruction cache:           %s\n", CPUInfo._L1.Instruction.strCache); -	FORMATADD("L1 data cache:                  %s\n", CPUInfo._L1.Data.strCache); -	FORMATADD("L2 cache:                       %s\n", CPUInfo._L2.strCache); -	FORMATADD("L3 cache:                       %s\n", CPUInfo._L3.strCache); -	FORMATADD("Trace cache:                    %s\n", CPUInfo._Trace.strCache); -	FORMATADD("Instruction TLB:                %s\n", CPUInfo._Instruction.strTLB); -	FORMATADD("Data TLB:                       %s\n", CPUInfo._Data.strTLB); -	FORMATADD("Max Supported CPUID-Level:      0x%08lX\n", CPUInfo.MaxSupportedLevel); -	FORMATADD("Max Supported Ext. CPUID-Level: 0x%08lX\n", CPUInfo.MaxSupportedExtendedLevel); - -	COPYADD("\n\n// CPU Extensions\n/////////////////\n"); -	BOOLADD("AA64   AMD 64-bit Architecture:                    ", CPUInfo._Ext.AA64_AMD64BitArchitecture); -	BOOLADD("ACPI   Thermal Monitor And Clock Control:          ", CPUInfo._Ext.ACPI_ThermalMonitorAndClockControl); -	BOOLADD("APIC   Advanced Programmable Interrupt Controller: ", CPUInfo._Ext.APIC_AdvancedProgrammableInterruptController); -	FORMATADD("       APIC-ID:                                     %d\n", CPUInfo._Ext.APIC_ID); -	BOOLADD("CLFSH  CLFLUSH Instruction Presence:               ", CPUInfo._Ext.CLFSH_CFLUSH_Instruction); -	FORMATADD("       CLFLUSH Instruction Cache Line Size:         %d\n", CPUInfo._Ext.CLFLUSH_InstructionCacheLineSize); -	BOOLADD("CMOV   Conditional Move And Compare Instructions:  ", CPUInfo._Ext.CMOV_ConditionalMoveAndCompareInstructions); -	BOOLADD("CX8    COMPXCHG8B Instruction:                     ", CPUInfo._Ext.CX8_COMPXCHG8B_Instruction); -	BOOLADD("DE     Debugging Extensions:                       ", CPUInfo._Ext.DE_DebuggingExtensions); -	BOOLADD("DS     Debug Store:                                ", CPUInfo._Ext.DS_DebugStore); -	BOOLADD("FGPAT  Page Attribute Table:                       ", CPUInfo._Ext.FGPAT_PageAttributeTable); -	BOOLADD("FPU    Floating Point Unit:                        ", CPUInfo._Ext.FPU_FloatingPointUnit); -	BOOLADD("FXSR   Fast Streaming SIMD Extensions Save/Restore:", CPUInfo._Ext.FXSR_FastStreamingSIMD_ExtensionsSaveRestore); -	BOOLADD("HT     Hyper Threading:                            ", CPUInfo._Ext.HT_HyperThreading); -	BOOLADD("IA64   Intel 64-Bit Architecture:                  ", CPUInfo._Ext.IA64_Intel64BitArchitecture); -	BOOLADD("MCA    Machine Check Architecture:                 ", CPUInfo._Ext.MCA_MachineCheckArchitecture); -	BOOLADD("MCE    Machine Check Exception:                    ", CPUInfo._Ext.MCE_MachineCheckException); -	BOOLADD("MMX    Multimedia Extensions:                      ", CPUInfo._Ext.MMX_MultimediaExtensions); -	BOOLADD("MMX+   Multimedia Extensions:                      ", CPUInfo._Ext.EMMX_MultimediaExtensions); -	BOOLADD("MSR    Model Specific Registers:                   ", CPUInfo._Ext.MSR_ModelSpecificRegisters); -	BOOLADD("MTRR   Memory Type Range Registers:                ", CPUInfo._Ext.MTRR_MemoryTypeRangeRegisters); -	BOOLADD("PAE    Physical Address Extension:                 ", CPUInfo._Ext.PAE_PhysicalAddressExtension); -	BOOLADD("PGE    PTE Global Flag:                            ", CPUInfo._Ext.PGE_PTE_GlobalFlag); -	if (CPUInfo._Ext.PN_ProcessorSerialNumber) -	{ -		FORMATADD("PN     Processor Serial Number:                     %s\n", CPUInfo.strProcessorSerial); -	} -	else -	{ -		COPYADD("PN     Processor Serial Number:                     Disabled\n"); -	} -	BOOLADD("PSE    Page Size Extensions:                       ", CPUInfo._Ext.PSE_PageSizeExtensions); -	BOOLADD("PSE36  36-bit Page Size Extension:                 ", CPUInfo._Ext.PSE36_36bitPageSizeExtension); -	BOOLADD("SEP    Fast System Call:                           ", CPUInfo._Ext.SEP_FastSystemCall); -	BOOLADD("SS     Self Snoop:                                 ", CPUInfo._Ext.SS_SelfSnoop); -	BOOLADD("SSE    Streaming SIMD Extensions:                  ", CPUInfo._Ext.SSE_StreamingSIMD_Extensions); -	BOOLADD("SSE2   Streaming SIMD 2 Extensions:                ", CPUInfo._Ext.SSE2_StreamingSIMD2_Extensions); -	BOOLADD("ALTVEC Altivec Extensions:                         ", CPUInfo._Ext.Altivec_Extensions); -	BOOLADD("TM     Thermal Monitor:                            ", CPUInfo._Ext.TM_ThermalMonitor); -	BOOLADD("TSC    Time Stamp Counter:                         ", CPUInfo._Ext.TSC_TimeStampCounter); -	BOOLADD("VME    Virtual 8086 Mode Enhancements:             ", CPUInfo._Ext.VME_Virtual8086ModeEnhancements); -	BOOLADD("3DNow! Instructions:                               ", CPUInfo._Ext._3DNOW_InstructionExtensions); -	BOOLADD("Enhanced 3DNow! Instructions:                      ", CPUInfo._Ext._E3DNOW_InstructionExtensions); -#endif -	// Yippie!!! -	return true; -} +LLProcessorInfo::~LLProcessorInfo() {} +F64 LLProcessorInfo::getCPUFrequency() const { return mImpl->getCPUFrequency(); } +bool LLProcessorInfo::hasSSE() const { return mImpl->hasSSE(); } +bool LLProcessorInfo::hasSSE2() const { return mImpl->hasSSE2(); } +bool LLProcessorInfo::hasAltivec() const { return mImpl->hasAltivec(); } +std::string LLProcessorInfo::getCPUFamilyName() const { return mImpl->getCPUFamilyName(); } +std::string LLProcessorInfo::getCPUBrandName() const { return mImpl->getCPUBrandName(); } +std::string LLProcessorInfo::getCPUFeatureDescription() const { return mImpl->getCPUFeatureDescription(); } -// bool CProcessor::WriteInfoTextFile(const std::string& strFilename) -// =========================================================== -// Takes use of CProcessor::CPUInfoToText and saves the string to a -// file -/////////////////////////////////////////////////////////////////// -bool CProcessor::WriteInfoTextFile(const std::string& strFilename) -{ -	char buf[16384];	/* Flawfinder: ignore */	 - -	// First we get the string -	if (!CPUInfoToText(buf, 16383)) -		return false; - -	// Then we create a new file (CREATE_ALWAYS) -	LLFILE *file = LLFile::fopen(strFilename, "w");	/* Flawfinder: ignore */	 -	if (!file) -		return false; - -	// After that we write the string to the file -	unsigned long dwBytesToWrite, dwBytesWritten; -	dwBytesToWrite = (unsigned long) strlen(buf);	 /*Flawfinder: ignore*/ -	dwBytesWritten = (unsigned long) fwrite(buf, 1, dwBytesToWrite, file); -	fclose(file); -	if (dwBytesToWrite != dwBytesWritten) -		return false; - -	// Done -	return true; -} diff --git a/indra/llcommon/llprocessor.h b/indra/llcommon/llprocessor.h index 746d007a7f..fc2c8dacfb 100644 --- a/indra/llcommon/llprocessor.h +++ b/indra/llcommon/llprocessor.h @@ -30,167 +30,26 @@   * $/LicenseInfo$   */ -// Author: Benjamin Jurke -// File history: 27.02.2002   File created. -/////////////////////////////////////////// -  #ifndef LLPROCESSOR_H  #define LLPROCESSOR_H +class LLProcessorInfoImpl; -// Options: -/////////// -#if LL_WINDOWS -#define PROCESSOR_FREQUENCY_MEASURE_AVAILABLE -#endif - -#if LL_MSVC && _M_X64 -#      define LL_X86_64 1 -#      define LL_X86 1 -#elif LL_MSVC && _M_IX86 -#      define LL_X86 1 -#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) ) -#      define LL_X86_64 1 -#      define LL_X86 1 -#elif LL_GNUC && ( defined(__i386__) ) -#      define LL_X86 1 -#elif LL_GNUC && ( defined(__powerpc__) || defined(__ppc__) ) -#      define LL_PPC 1 -#endif - - -struct ProcessorExtensions -{ -	bool FPU_FloatingPointUnit; -	bool VME_Virtual8086ModeEnhancements; -	bool DE_DebuggingExtensions; -	bool PSE_PageSizeExtensions; -	bool TSC_TimeStampCounter; -	bool MSR_ModelSpecificRegisters; -	bool PAE_PhysicalAddressExtension; -	bool MCE_MachineCheckException; -	bool CX8_COMPXCHG8B_Instruction; -	bool APIC_AdvancedProgrammableInterruptController; -	unsigned int APIC_ID; -	bool SEP_FastSystemCall; -	bool MTRR_MemoryTypeRangeRegisters; -	bool PGE_PTE_GlobalFlag; -	bool MCA_MachineCheckArchitecture; -	bool CMOV_ConditionalMoveAndCompareInstructions; -	bool FGPAT_PageAttributeTable; -	bool PSE36_36bitPageSizeExtension; -	bool PN_ProcessorSerialNumber; -	bool CLFSH_CFLUSH_Instruction; -	unsigned int CLFLUSH_InstructionCacheLineSize; -	bool DS_DebugStore; -	bool ACPI_ThermalMonitorAndClockControl; -	bool EMMX_MultimediaExtensions; -	bool MMX_MultimediaExtensions; -	bool FXSR_FastStreamingSIMD_ExtensionsSaveRestore; -	bool SSE_StreamingSIMD_Extensions; -	bool SSE2_StreamingSIMD2_Extensions; -	bool Altivec_Extensions; -	bool SS_SelfSnoop; -	bool HT_HyperThreading; -	unsigned int HT_HyterThreadingSiblings; -	bool TM_ThermalMonitor; -	bool IA64_Intel64BitArchitecture; -	bool _3DNOW_InstructionExtensions; -	bool _E3DNOW_InstructionExtensions; -	bool AA64_AMD64BitArchitecture; -}; - -struct ProcessorCache -{ -	bool bPresent; -	char strSize[32];	/* Flawfinder: ignore */	 -	unsigned int uiAssociativeWays; -	unsigned int uiLineSize; -	bool bSectored; -	char strCache[128];	/* Flawfinder: ignore */	 -}; - -struct ProcessorL1Cache -{ -    ProcessorCache Instruction; -	ProcessorCache Data; -}; - -struct ProcessorTLB +class LL_COMMON_API LLProcessorInfo  { -	bool bPresent; -	char strPageSize[32];	/* Flawfinder: ignore */	 -	unsigned int uiAssociativeWays; -	unsigned int uiEntries; -	char strTLB[128];	/* Flawfinder: ignore */	 -}; - -struct ProcessorInfo -{ -	char strVendor[16];	/* Flawfinder: ignore */	 -	unsigned int uiFamily; -	unsigned int uiExtendedFamily; -	char strFamily[64];	/* Flawfinder: ignore */	 -	unsigned int uiModel; -	unsigned int uiExtendedModel; -	char strModel[128];	/* Flawfinder: ignore */	 -	unsigned int uiStepping; -	unsigned int uiType; -	char strType[64];	/* Flawfinder: ignore */	 -	unsigned int uiBrandID; -	char strBrandID[64];	/* Flawfinder: ignore */	 -	char strProcessorSerial[64];	/* Flawfinder: ignore */	 -	unsigned long MaxSupportedLevel; -	unsigned long MaxSupportedExtendedLevel; -	ProcessorExtensions _Ext; -	ProcessorL1Cache _L1; -	ProcessorCache _L2; -	ProcessorCache _L3; -	ProcessorCache _Trace; -	ProcessorTLB _Instruction; -	ProcessorTLB _Data; -}; - - -// CProcessor -// ========== -// Class for detecting the processor name, type and available -// extensions as long as it's speed. -///////////////////////////////////////////////////////////// -class CProcessor -{ -// Constructor / Destructor: -////////////////////////////  public: -	CProcessor(); - -// Private vars: -//////////////// -public: -	F64 uqwFrequency; -	char strCPUName[128];	/* Flawfinder: ignore */	 -	ProcessorInfo CPUInfo; - -// Private functions: -///////////////////// +	LLProcessorInfo();  + 	~LLProcessorInfo(); + +	F64 getCPUFrequency() const; +	bool hasSSE() const; +	bool hasSSE2() const; +	bool hasAltivec() const; +	std::string getCPUFamilyName() const; +	std::string getCPUBrandName() const; +	std::string getCPUFeatureDescription() const;  private: -	bool AnalyzeIntelProcessor(); -	bool AnalyzeAMDProcessor(); -	bool AnalyzeUnknownProcessor(); -	bool CheckCPUIDPresence(); -	void DecodeProcessorConfiguration(unsigned int cfg); -	void TranslateProcessorConfiguration(); -	void GetStandardProcessorConfiguration(); -	void GetStandardProcessorExtensions(); - -// Public functions: -//////////////////// -public: -	F64 GetCPUFrequency(unsigned int uiMeasureMSecs); -	const ProcessorInfo *GetCPUInfo(); -	bool CPUInfoToText(char *strBuffer, unsigned int uiMaxLen); -	bool WriteInfoTextFile(const std::string& strFilename); +	LLProcessorInfoImpl* mImpl;  }; - -#endif +#endif // LLPROCESSOR_H diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 52b1b63209..d41d0c8a3f 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -58,7 +58,6 @@  #	include <unistd.h>  #	include <sys/sysinfo.h>  const char MEMINFO_FILE[] = "/proc/meminfo"; -const char CPUINFO_FILE[] = "/proc/cpuinfo";  #elif LL_SOLARIS  #	include <stdio.h>  #	include <unistd.h> @@ -513,71 +512,21 @@ U32 LLOSInfo::getProcessResidentSizeKB()  LLCPUInfo::LLCPUInfo()  {  	std::ostringstream out; -	CProcessor proc; -	const ProcessorInfo* info = proc.GetCPUInfo(); +	LLProcessorInfo proc;  	// proc.WriteInfoTextFile("procInfo.txt"); -	mHasSSE = info->_Ext.SSE_StreamingSIMD_Extensions; -	mHasSSE2 = info->_Ext.SSE2_StreamingSIMD2_Extensions; -	mHasAltivec = info->_Ext.Altivec_Extensions; -	mCPUMHz = (F64)(proc.GetCPUFrequency(50)/1000000.0F); -	mFamily.assign( info->strFamily ); +	mHasSSE = proc.hasSSE(); +	mHasSSE2 = proc.hasSSE2(); +	mHasAltivec = proc.hasAltivec(); +	mCPUMHz = (F64)proc.getCPUFrequency(); +	mFamily = proc.getCPUFamilyName();  	mCPUString = "Unknown"; -#if LL_WINDOWS || LL_DARWIN || LL_SOLARIS -	out << proc.strCPUName; +	out << proc.getCPUBrandName();  	if (200 < mCPUMHz && mCPUMHz < 10000)           // *NOTE: cpu speed is often way wrong, do a sanity check  	{  		out << " (" << mCPUMHz << " MHz)";  	}  	mCPUString = out.str(); -	 -#elif LL_LINUX -	std::map< std::string, std::string > cpuinfo; -	LLFILE* cpuinfo_fp = LLFile::fopen(CPUINFO_FILE, "rb"); -	if(cpuinfo_fp) -	{ -		char line[MAX_STRING]; -		memset(line, 0, MAX_STRING); -		while(fgets(line, MAX_STRING, cpuinfo_fp)) -		{ -			// /proc/cpuinfo on Linux looks like: -			// name\t*: value\n -			char* tabspot = strchr( line, '\t' ); -			if (tabspot == NULL) -				continue; -			char* colspot = strchr( tabspot, ':' ); -			if (colspot == NULL) -				continue; -			char* spacespot = strchr( colspot, ' ' ); -			if (spacespot == NULL) -				continue; -			char* nlspot = strchr( line, '\n' ); -			if (nlspot == NULL) -				nlspot = line + strlen( line ); // Fallback to terminating NUL -			std::string linename( line, tabspot ); -			std::string llinename(linename); -			LLStringUtil::toLower(llinename); -			std::string lineval( spacespot + 1, nlspot ); -			cpuinfo[ llinename ] = lineval; -		} -		fclose(cpuinfo_fp); -	} -# if LL_X86 -	std::string flags = " " + cpuinfo["flags"] + " "; -	LLStringUtil::toLower(flags); -	mHasSSE = ( flags.find( " sse " ) != std::string::npos ); -	mHasSSE2 = ( flags.find( " sse2 " ) != std::string::npos ); -	 -	F64 mhz; -	if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz) -	    && 200.0 < mhz && mhz < 10000.0) -	{ -		mCPUMHz = (F64)(mhz); -	} -	if (!cpuinfo["model name"].empty()) -		mCPUString = cpuinfo["model name"]; -# endif // LL_X86 -#endif // LL_LINUX  }  bool LLCPUInfo::hasAltivec() const @@ -607,38 +556,9 @@ std::string LLCPUInfo::getCPUString() const  void LLCPUInfo::stream(std::ostream& s) const  { -#if LL_WINDOWS || LL_DARWIN || LL_SOLARIS  	// gather machine information. -	char proc_buf[CPUINFO_BUFFER_SIZE];		/* Flawfinder: ignore */ -	CProcessor proc; -	if(proc.CPUInfoToText(proc_buf, CPUINFO_BUFFER_SIZE)) -	{ -		s << proc_buf; -	} -	else -	{ -		s << "Unable to collect processor information" << std::endl; -	} -#else -	// *NOTE: This works on linux. What will it do on other systems? -	LLFILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, "rb"); -	if(cpuinfo) -	{ -		char line[MAX_STRING]; -		memset(line, 0, MAX_STRING); -		while(fgets(line, MAX_STRING, cpuinfo)) -		{ -			line[strlen(line)-1] = ' '; -			s << line; -		} -		fclose(cpuinfo); -		s << std::endl; -	} -	else -	{ -		s << "Unable to collect processor information" << std::endl; -	} -#endif +	s << LLProcessorInfo().getCPUFeatureDescription(); +  	// These are interesting as they reflect our internal view of the  	// CPU's attributes regardless of platform  	s << "->mHasSSE:     " << (U32)mHasSSE << std::endl; diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index adef1a9192..dbb8ec5231 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -135,7 +135,7 @@ class LL_COMMON_API LLMutex  {  public:  	LLMutex(apr_pool_t *apr_poolp); // NULL pool constructs a new pool for the mutex -	~LLMutex(); +	virtual ~LLMutex();  	void lock();		// blocks  	void unlock(); diff --git a/indra/llcommon/llversionserver.h b/indra/llcommon/llversionserver.h index e3663544db..87fe7001e0 100644 --- a/indra/llcommon/llversionserver.h +++ b/indra/llcommon/llversionserver.h @@ -33,10 +33,10 @@  #ifndef LL_LLVERSIONSERVER_H  #define LL_LLVERSIONSERVER_H -const S32 LL_VERSION_MAJOR = 1; -const S32 LL_VERSION_MINOR = 31; +const S32 LL_VERSION_MAJOR = 2; +const S32 LL_VERSION_MINOR = 1;  const S32 LL_VERSION_PATCH = 0; -const S32 LL_VERSION_BUILD = 203110; +const S32 LL_VERSION_BUILD = 0;  const char * const LL_CHANNEL = "Second Life Server"; diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index fc3ce6df7e..6e341b83a1 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -34,8 +34,8 @@  #define LL_LLVERSIONVIEWER_H  const S32 LL_VERSION_MAJOR = 2; -const S32 LL_VERSION_MINOR = 0; -const S32 LL_VERSION_PATCH = 2; +const S32 LL_VERSION_MINOR = 1; +const S32 LL_VERSION_PATCH = 0;  const S32 LL_VERSION_BUILD = 0;  const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llcommon/tests/llprocessor_test.cpp b/indra/llcommon/tests/llprocessor_test.cpp new file mode 100644 index 0000000000..a9e312b70b --- /dev/null +++ b/indra/llcommon/tests/llprocessor_test.cpp @@ -0,0 +1,67 @@ +/**  + * @file llprocessor_test.cpp + * @date 2010-06-01 + * + * $LicenseInfo:firstyear=2010&license=viewergpl$ + *  + * Copyright (c) 2010, Linden Research, Inc. + *  + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab.  Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + *  + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at + * http://secondlifegrid.net/programs/open_source/licensing/flossexception + *  + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + *  + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../test/lltut.h" + +#include "../llprocessor.h" + + +namespace tut +{ +	struct processor +	{ +	}; + +	typedef test_group<processor> processor_t; +	typedef processor_t::object processor_object_t; +	tut::processor_t tut_processor("processor"); + +	template<> template<> +	void processor_object_t::test<1>() +	{ +		set_test_name("LLProcessorInfo regression test"); + +		LLProcessorInfo pi; +		F64 freq =  pi.getCPUFrequency(); +		//bool sse =  pi.hasSSE(); +		//bool sse2 = pi.hasSSE2(); +		//bool alitvec = pi.hasAltivec(); +		std::string family = pi.getCPUFamilyName(); +		std::string brand =  pi.getCPUBrandName(); +		//std::string steam =  pi.getCPUFeatureDescription(); + +		ensure_not_equals("Unknown Brand name", brand, "Unknown");  +		ensure_not_equals("Unknown Family name", family, "Unknown");  +		ensure("Reasonable CPU Frequency > 100 && < 10000", freq > 100 && freq < 10000); +	} +} diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index c1022c1195..51e5f14bfe 100755 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -155,25 +155,6 @@ std::string getStartupStateFromLog(std::string& sllog)  void LLCrashLogger::gatherFiles()  { - -	/* -	//TODO:This function needs to be reimplemented somewhere in here... -	if(!previous_crash && is_crash_log) -	{ -		// Make sure the file isn't too old. -		double age = difftime(gLaunchTime, stat_data.st_mtimespec.tv_sec); -		 -		//			llinfos << "age is " << age << llendl; -		 -		if(age > 60.0) -		{ -				// The file was last modified more than 60 seconds before the crash reporter was launched.  Assume it's stale. -			llwarns << "File " << mFilename << " is too old!" << llendl; -			return; -		} -	} -	*/ -  	updateApplication("Gathering logs...");  	// Figure out the filename of the debug log @@ -209,11 +190,9 @@ void LLCrashLogger::gatherFiles()  		mFileMap["SettingsXml"] = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"settings.xml");  	} -#if !LL_DARWIN  	if(mCrashInPreviousExec) -#else -#endif  	{ +		// Restarting after freeze.  		// Replace the log file ext with .old, since the   		// instance that launched this process has overwritten  		// SecondLife.log @@ -225,7 +204,12 @@ void LLCrashLogger::gatherFiles()  	gatherPlatformSpecificFiles();  	//Use the debug log to reconstruct the URL to send the crash report to -	if(mDebugLog.has("CurrentSimHost")) +	if(mDebugLog.has("CrashHostUrl")) +	{ +		// Crash log receiver has been manually configured. +		mCrashHost = mDebugLog["CrashHostUrl"].asString(); +	} +	else if(mDebugLog.has("CurrentSimHost"))  	{  		mCrashHost = "https://";  		mCrashHost += mDebugLog["CurrentSimHost"].asString(); @@ -247,7 +231,6 @@ void LLCrashLogger::gatherFiles()  	mCrashInfo["DebugLog"] = mDebugLog;  	mFileMap["StatsLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stats.log"); -	mFileMap["StackTrace"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");  	updateApplication("Encoding files..."); @@ -272,8 +255,30 @@ void LLCrashLogger::gatherFiles()  			trimSLLog(crash_info);  		} -		mCrashInfo[(*itr).first] = rawstr_to_utf8(crash_info); +		mCrashInfo[(*itr).first] = LLStringFn::strip_invalid_xml(rawstr_to_utf8(crash_info)); +	} +	 +	// Add minidump as binary. +	std::string minidump_path = mDebugLog["MinidumpPath"]; +	if(minidump_path != "") +	{ +		std::ifstream minidump_stream(minidump_path.c_str(), std::ios_base::in | std::ios_base::binary); +		if(minidump_stream.is_open()) +		{ +			minidump_stream.seekg(0, std::ios::end); +			size_t length = minidump_stream.tellg(); +			minidump_stream.seekg(0, std::ios::beg); +			 +			LLSD::Binary data; +			data.resize(length); +			 +			minidump_stream.read(reinterpret_cast<char *>(&(data[0])),length); +			minidump_stream.close(); +			 +			mCrashInfo["Minidump"] = data; +		}  	} +	mCrashInfo["DebugLog"].erase("MinidumpPath");  }  LLSD LLCrashLogger::constructPostData() diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp index b5de104e61..a6ab246a2c 100644 --- a/indra/llimage/llimagepng.cpp +++ b/indra/llimage/llimagepng.cpp @@ -135,6 +135,7 @@ BOOL LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time)  	if (! pngWrapper.writePng(raw_image, mTmpWriteBuffer))  	{  		setLastError(pngWrapper.getErrorMessage()); +		delete[] mTmpWriteBuffer;  		return FALSE;  	} diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp index 2c767a4857..53830b1a14 100644 --- a/indra/llinventory/llinventory.cpp +++ b/indra/llinventory/llinventory.cpp @@ -85,10 +85,7 @@ LLInventoryObject::LLInventoryObject(const LLUUID& uuid,  	mType(type),  	mName(name)  { -	LLStringUtil::replaceNonstandardASCII(mName, ' '); -	LLStringUtil::replaceChar(mName, '|', ' '); -	LLStringUtil::trim(mName); -	LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN); +	correctInventoryName(mName);  }  LLInventoryObject::LLInventoryObject() : @@ -155,12 +152,8 @@ void LLInventoryObject::setUUID(const LLUUID& new_uuid)  void LLInventoryObject::rename(const std::string& n)  {  	std::string new_name(n); -	LLStringUtil::replaceNonstandardASCII(new_name, ' '); -	LLStringUtil::replaceChar(new_name, '|', ' '); -	LLStringUtil::trim(new_name); -	LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN); - -	if( new_name != mName ) +	correctInventoryName(new_name); +	if( !new_name.empty() && new_name != mName )  	{  		mName = new_name;  	} @@ -221,10 +214,7 @@ BOOL LLInventoryObject::importLegacyStream(std::istream& input_stream)  				" %254s %254[^|]",  				keyword, valuestr);  			mName.assign(valuestr); -			LLStringUtil::replaceNonstandardASCII(mName, ' '); -			LLStringUtil::replaceChar(mName, '|', ' '); -			LLStringUtil::trim(mName); -			LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN); +			correctInventoryName(mName);  		}  		else  		{ @@ -284,6 +274,15 @@ void LLInventoryObject::updateServer(BOOL) const  	llwarns << "LLInventoryObject::updateServer() called.  Doesn't do anything." << llendl;  } +inline +void LLInventoryObject::correctInventoryName(std::string& name) +{ +	LLStringUtil::replaceNonstandardASCII(name, ' '); +	LLStringUtil::replaceChar(name, '|', ' '); +	LLStringUtil::trim(name); +	LLStringUtil::truncate(name, DB_INV_ITEM_NAME_STR_LEN); +} +  ///----------------------------------------------------------------------------  /// Class LLInventoryItem diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h index b083e305b1..4c6ac83ab8 100644 --- a/indra/llinventory/llinventory.h +++ b/indra/llinventory/llinventory.h @@ -92,9 +92,13 @@ public:  	void setParent(const LLUUID& new_parent);  	void setType(LLAssetType::EType type); +private: +	// in place correction for inventory name string +	void correctInventoryName(std::string& name); +  	//--------------------------------------------------------------------  	// File Support -	//   Implemented here so that a minimal information set can be transmitted  +	//   Implemented here so that a minimal information set can be transmitted  	//   between simulator and viewer.  	//--------------------------------------------------------------------  public: diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h index 209b506c30..c3c15e1374 100644 --- a/indra/llmath/llmath.h +++ b/indra/llmath/llmath.h @@ -61,11 +61,11 @@  #endif  // Single Precision Floating Point Routines -#ifndef fsqrtf -#define fsqrtf(x)		((F32)sqrt((F64)(x))) -#endif  #ifndef sqrtf -#define sqrtf(x)		((F32)sqrt((F64)(x))) +#define sqrtf(x)	((F32)sqrt((F64)(x))) +#endif +#ifndef fsqrtf +#define fsqrtf(x)	sqrtf(x)  #endif  #ifndef cosf @@ -78,11 +78,14 @@  #define tanf(x)		((F32)tan((F64)(x)))  #endif  #ifndef acosf -#define acosf(x)		((F32)acos((F64)(x))) +#define acosf(x)	((F32)acos((F64)(x)))  #endif  #ifndef powf -#define powf(x,y) ((F32)pow((F64)(x),(F64)(y))) +#define powf(x,y)	((F32)pow((F64)(x),(F64)(y))) +#endif +#ifndef expf +#define expf(x)		((F32)exp((F64)(x)))  #endif  const F32	GRAVITY			= -9.8f; diff --git a/indra/llmath/tests/mathmisc_test.cpp b/indra/llmath/tests/mathmisc_test.cpp index ea42f6e001..68d9ddc0fe 100644 --- a/indra/llmath/tests/mathmisc_test.cpp +++ b/indra/llmath/tests/mathmisc_test.cpp @@ -334,6 +334,8 @@ namespace tut  	template<> template<>  	void sphere_object::test<2>()  	{ +		skip("See SNOW-620.  Neither the test nor the code being tested seem good.  Also sim-only."); +  		// test LLSphere::getBoundingSphere()  		S32 number_of_tests = 100;  		S32 number_of_spheres = 10; diff --git a/indra/llmessage/llares.cpp b/indra/llmessage/llares.cpp index 00e77d20e9..5b7e5138ef 100644 --- a/indra/llmessage/llares.cpp +++ b/indra/llmessage/llares.cpp @@ -108,7 +108,8 @@ LLAres::LLAres() :      mInitSuccess(false),      mListener(new LLAresListener(this))  { -	if (ares_init(&chan_) != ARES_SUCCESS) +	if (ares_library_init( ARES_LIB_INIT_ALL ) != ARES_SUCCESS || +		ares_init(&chan_) != ARES_SUCCESS)  	{  		llwarns << "Could not succesfully initialize ares!" << llendl;  		return; @@ -120,6 +121,7 @@ LLAres::LLAres() :  LLAres::~LLAres()  {  	ares_destroy(chan_); +	ares_library_cleanup();  }  void LLAres::cancel() @@ -473,7 +475,7 @@ bool LLAres::process(U64 timeout)  		ll_init_apr();  	} -	int socks[ARES_GETSOCK_MAXNUM]; +	ares_socket_t socks[ARES_GETSOCK_MAXNUM];  	apr_pollfd_t aprFds[ARES_GETSOCK_MAXNUM];  	apr_int32_t nsds = 0;	  	int nactive = 0; diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 9c2e4b5658..e8dc207114 100644 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -199,6 +199,7 @@ namespace  			fileBuffer = new U8 [fileSize];              vfile.read(fileBuffer, fileSize);              ostream.write((char*)fileBuffer, fileSize); +			delete [] fileBuffer;  			eos = true;  			return STATUS_DONE;  		} diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp index 6bf1347514..fc93793ed8 100644 --- a/indra/llui/llaccordionctrl.cpp +++ b/indra/llui/llaccordionctrl.cpp @@ -352,7 +352,7 @@ void LLAccordionCtrl::addCollapsibleCtrl(LLView* view)  	mAccordionTabs.push_back(accordion_tab);  	accordion_tab->setDropDownStateChangedCallback( boost::bind(&LLAccordionCtrl::onCollapseCtrlCloseOpen, this, mAccordionTabs.size() - 1) ); - +	arrange();	  }  void LLAccordionCtrl::removeCollapsibleCtrl(LLView* view) @@ -523,6 +523,8 @@ void	LLAccordionCtrl::arrangeMultiple()  void LLAccordionCtrl::arrange()  { +	updateNoTabsHelpTextVisibility(); +  	if( mAccordionTabs.size() == 0)  	{  		//We do not arrange if we do not have what should be arranged @@ -541,6 +543,8 @@ void LLAccordionCtrl::arrange()  		S32 panel_height = getRect().getHeight() - 2*BORDER_MARGIN; +		if (accordion_tab->getFitParent()) +			panel_height = accordion_tab->getRect().getHeight();  		ctrlSetLeftTopAndSize(accordion_tab,panel_rect.mLeft,panel_top,panel_width,panel_height);  		show_hide_scrollbar(getRect().getWidth(),getRect().getHeight()); @@ -816,7 +820,7 @@ void	LLAccordionCtrl::setFilterSubString(const std::string& filter_string)  {  	LLStringUtil::format_map_t args;  	args["[SEARCH_TERM]"] = LLURI::escape(filter_string); -	std::string text = mNoVisibleTabsOrigString; +	std::string text = filter_string.empty() ? LLStringUtil::null : mNoVisibleTabsOrigString;  	LLStringUtil::format(text, args);  	mNoVisibleTabsHelpText->setValue(text); diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp index 1bc8086a27..be231fd8cf 100644 --- a/indra/llui/llaccordionctrltab.cpp +++ b/indra/llui/llaccordionctrltab.cpp @@ -968,3 +968,16 @@ BOOL LLAccordionCtrlTab::handleToolTip(S32 x, S32 y, MASK mask)  	}  	return LLUICtrl::handleToolTip(x, y, mask);  } +BOOL LLAccordionCtrlTab::handleScrollWheel		( S32 x, S32 y, S32 clicks ) +{ +	if( LLUICtrl::handleScrollWheel(x,y,clicks)) +	{ +		return TRUE; +	} +	if( mScrollbar->getVisible() && mScrollbar->handleScrollWheel( 0, 0, clicks ) ) +	{ +		return TRUE; +	} +	return FALSE; +} + diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h index 82e0234bfc..19d4ec0a1c 100644 --- a/indra/llui/llaccordionctrltab.h +++ b/indra/llui/llaccordionctrltab.h @@ -166,6 +166,8 @@ public:  	virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);  	virtual BOOL handleToolTip(S32 x, S32 y, MASK mask); +	virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks ); +  	virtual bool addChild(LLView* child, S32 tab_group); @@ -190,6 +192,7 @@ public:  	void showAndFocusHeader();  	void setFitPanel( bool fit ) { mFitPanel = true; } +	bool getFitParent() const { return mFitPanel; }  protected:  	void adjustContainerPanel	(const LLRect& child_rect); diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 341debc9a8..9a56372e68 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -347,7 +347,7 @@ void LLFloater::layoutDragHandle()  	{  		rect = getLocalRect();  	} -	mDragHandle->setRect(rect); +	mDragHandle->setShape(rect);  	updateTitleButtons();  } diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 45f9de8e8d..c93ca1af88 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -377,7 +377,10 @@ void LLLineEditor::setText(const LLStringExplicit &new_text)  	setCursor(llmin((S32)mText.length(), getCursor()));  	// Set current history line to end of history. -	mCurrentHistoryLine = mLineHistory.end() - 1; +	if(mLineHistory.end() != mLineHistory.begin()) +	{ +		mCurrentHistoryLine = mLineHistory.end() - 1; +	}  	mPrevText = mText;  } diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 72f3a14822..3c6c7d3e82 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -2791,7 +2791,7 @@ bool LLImageTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& width  	height = llceil(mStyle->getFont()->getLineHeight());;  	LLUIImagePtr image = mStyle->getImage(); -	if( image.notNull()) +	if( num_chars>0 && image.notNull())  	{  		width += image->getWidth() + IMAGE_HPAD;  		height = llmax(height, image->getHeight() + IMAGE_HPAD ); @@ -2803,13 +2803,13 @@ S32	 LLImageTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin  {  	LLUIImagePtr image = mStyle->getImage();  	S32 image_width = image->getWidth(); -	if(num_pixels>image_width + IMAGE_HPAD) +	if(line_offset == 0 || num_pixels>image_width + IMAGE_HPAD)  	{  		return 1;  	} -  	return 0;  } +  F32	LLImageTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect)  {  	if ( (start >= 0) && (end <= mEnd - mStart)) diff --git a/indra/mac_crash_logger/llcrashloggermac.cpp b/indra/mac_crash_logger/llcrashloggermac.cpp index 16efa4fe2c..90de39ba27 100644 --- a/indra/mac_crash_logger/llcrashloggermac.cpp +++ b/indra/mac_crash_logger/llcrashloggermac.cpp @@ -211,89 +211,6 @@ bool LLCrashLoggerMac::init(void)  void LLCrashLoggerMac::gatherPlatformSpecificFiles()  {  	updateApplication("Gathering hardware information..."); -	char path[MAX_PATH];		 -	FSRef folder; -	 -	if(FSFindFolder(kUserDomain, kLogsFolderType, false, &folder) == noErr) -	{ -		// folder is an FSRef to ~/Library/Logs/ -		if(FSRefMakePath(&folder, (UInt8*)&path, sizeof(path)) == noErr) -		{ -			struct stat dw_stat; -			std::string mBuf; -			bool isLeopard = false; -			// Try the 10.3 path first... -			std::string dw_file_name = std::string(path) + std::string("/CrashReporter/Second Life.crash.log"); -			int res = stat(dw_file_name.c_str(), &dw_stat); - -			if (res) -			{ -				// Try the 10.2 one next... -				dw_file_name = std::string(path) + std::string("/Second Life.crash.log"); -				res = stat(dw_file_name.c_str(), &dw_stat); -			} -	 -			if(res) -			{ -				//10.5: Like 10.3+, except it puts the crash time in the file instead of dividing it up -				//using asterisks. Get a directory listing, search for files starting with second life, -				//use the last one found. -				std::string old_file_name, current_file_name, pathname, mask; -				pathname = std::string(path) + std::string("/CrashReporter/"); -				mask = "Second Life*"; -				while(gDirUtilp->getNextFileInDir(pathname, mask, current_file_name, false)) -				{ -					old_file_name = current_file_name; -				} -				if(old_file_name != "") -				{ -					dw_file_name = pathname + old_file_name; -					res=stat(dw_file_name.c_str(), &dw_stat); -					isLeopard = true; -				} -			} -			 -			if (!res) -			{ -				std::ifstream fp(dw_file_name.c_str()); -				std::stringstream str; -				if(!fp.is_open()) return; -				str << fp.rdbuf(); -				mBuf = str.str(); -				 -				if(!isLeopard) -				{ -					// Crash logs consist of a number of entries, one per crash. -					// Each entry is preceeded by "**********" on a line by itself. -					// We want only the most recent (i.e. last) one. -					const char *sep = "**********"; -					const char *start = mBuf.c_str(); -					const char *cur = start; -					const char *temp = strstr(cur, sep); -				 -					while(temp != NULL) -					{ -						// Skip past the marker we just found -						cur = temp + strlen(sep);		/* Flawfinder: ignore */ -						 -						// and try to find another -						temp = strstr(cur, sep); -					} -				 -					// If there's more than one entry in the log file, strip all but the last one. -					if(cur != start) -					{ -						mBuf.erase(0, cur - start); -					} -				} -				mCrashInfo["CrashLog"] = mBuf; -			} -			else -			{ -				llwarns << "Couldn't find any CrashReporter files..." << llendl; -			} -		} -	}  }  bool LLCrashLoggerMac::mainLoop() diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt index 3b73e04786..9f0ff654fc 100644 --- a/indra/media_plugins/gstreamer010/CMakeLists.txt +++ b/indra/media_plugins/gstreamer010/CMakeLists.txt @@ -42,12 +42,12 @@ set(media_plugin_gstreamer010_HEADER_FILES      llmediaimplgstreamertriviallogging.h      ) -if (${CXX_VERSION_NUMBER} MATCHES "4[23].") +if (${CXX_VERSION_NUMBER} MATCHES "4[23456789].")      # Work around a bad interaction between broken gstreamer headers and -    # g++ 4.3's increased strictness. +    # g++ >= 4.2's increased strictness.      set_source_files_properties(llmediaimplgstreamervidplug.cpp PROPERTIES                                  COMPILE_FLAGS -Wno-write-strings) -endif (${CXX_VERSION_NUMBER} MATCHES "4[23].") +endif (${CXX_VERSION_NUMBER} MATCHES "4[23456789].")  add_library(media_plugin_gstreamer010      SHARED diff --git a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp index 033c4ba2f3..e6d2ad3edc 100644 --- a/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp +++ b/indra/media_plugins/gstreamer010/media_plugin_gstreamer010.cpp @@ -544,8 +544,12 @@ MediaPluginGStreamer010::pause()  {  	DEBUGMSG("pausing media...");  	// todo: error-check this? -	llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); -	return true; +	if (mDoneInit && mPlaybin) +	{ +		llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); +		return true; +	} +	return false;  }  bool @@ -553,8 +557,12 @@ MediaPluginGStreamer010::stop()  {  	DEBUGMSG("stopping media...");  	// todo: error-check this? -	llgst_element_set_state(mPlaybin, GST_STATE_READY); -	return true; +	if (mDoneInit && mPlaybin) +	{ +		llgst_element_set_state(mPlaybin, GST_STATE_READY); +		return true; +	} +	return false;  }  bool @@ -564,8 +572,12 @@ MediaPluginGStreamer010::play(double rate)          DEBUGMSG("playing media... rate=%f", rate);  	// todo: error-check this? -	llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); -	return true; +	if (mDoneInit && mPlaybin) +	{ +		llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); +		return true; +	} +	return false;  }  bool @@ -608,7 +620,7 @@ bool  MediaPluginGStreamer010::getTimePos(double &sec_out)  {  	bool got_position = false; -	if (mPlaybin) +	if (mDoneInit && mPlaybin)  	{  		gint64 pos;  		GstFormat timefmt = GST_FORMAT_TIME; @@ -688,6 +700,7 @@ MediaPluginGStreamer010::load()  					   this);  	llgst_object_unref (bus); +#if 0 // not quite stable/correct yet  	// get a visualizer element (bonus feature!)  	char* vis_name = getenv("LL_GST_VIS_NAME");  	if (!vis_name || @@ -714,6 +727,7 @@ MediaPluginGStreamer010::load()  			}  		}  	} +#endif  	if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) {  		// instantiate a custom video sink diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 3c98cd5b85..24811db3cb 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1072,7 +1072,6 @@ set(viewer_HEADER_FILES      llwearabletype.h      llweb.h      llwind.h -    llwindebug.h      llwlanimator.h      llwldaycycle.h      llwlparammanager.h @@ -1146,12 +1145,10 @@ endif (LINUX)  if (WINDOWS)      list(APPEND viewer_SOURCE_FILES           llappviewerwin32.cpp -         llwindebug.cpp           )      list(APPEND viewer_HEADER_FILES           llappviewerwin32.h -         llwindebug.h           )      # precompiled header configuration @@ -1708,6 +1705,29 @@ if (LINUX)      add_dependencies(package linux-updater-target)      check_message_template(package)    endif (NOT INSTALL) + +  add_custom_command( +    OUTPUT  ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.copy_touched +    COMMAND ${PYTHON_EXECUTABLE} +    ARGS +      ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py +      --arch=${ARCH} +      --actions=copy +      --artwork=${ARTWORK_DIR} +      --build=${CMAKE_CURRENT_BINARY_DIR} +      --buildtype=${CMAKE_BUILD_TYPE} +      --configuration=${CMAKE_CFG_INTDIR} +      --dest=${CMAKE_CURRENT_BINARY_DIR}/packaged +      --grid=${GRID} +      --source=${CMAKE_CURRENT_SOURCE_DIR} +    DEPENDS  +      ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py +      ${COPY_INPUT_DEPENDENCIES} +    COMMENT "Performing viewer_manifest copy" +    ) +     +  add_custom_target(copy_l_viewer_manifest ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.copy_touched)  +  add_dependencies(copy_l_viewer_manifest "${VIEWER_BINARY_NAME}" linux-crash-logger-target linux-updater-target)  endif (LINUX)  if (DARWIN) @@ -1742,52 +1762,30 @@ if (DARWIN)      DEPENDS ${VIEWER_BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py      ) -  add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit) +  add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit mac-updater mac-crash-logger)    if (PACKAGE)        add_custom_target(package ALL DEPENDS ${VIEWER_BINARY_NAME})         check_message_template(package) -      add_dependencies(package mac-updater mac-crash-logger)        add_custom_command(          TARGET package POST_BUILD          COMMAND ${PYTHON_EXECUTABLE}          ARGS            ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py -          --grid=${GRID} -          --buildtype=${CMAKE_BUILD_TYPE} -          --configuration=${CMAKE_CFG_INTDIR} -          --channel=${VIEWER_CHANNEL} -          --login_channel=${VIEWER_LOGIN_CHANNEL} -          --source=${CMAKE_CURRENT_SOURCE_DIR}            --artwork=${ARTWORK_DIR}            --build=${CMAKE_CURRENT_BINARY_DIR} -          --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app -          --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched -        DEPENDS -          ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py -      ) - - -      add_custom_command( -        TARGET package POST_BUILD -        COMMAND ${PYTHON_EXECUTABLE} -        ARGS -          ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py -          --grid=${GRID}            --buildtype=${CMAKE_BUILD_TYPE} -          --configuration=${CMAKE_CFG_INTDIR}            --channel=${VIEWER_CHANNEL} +          --configuration=${CMAKE_CFG_INTDIR} +          --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app +          --grid=${GRID}            --login_channel=${VIEWER_LOGIN_CHANNEL}            --source=${CMAKE_CURRENT_SOURCE_DIR} -          --artwork=${ARTWORK_DIR} -          --build=${CMAKE_CURRENT_BINARY_DIR} -          --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app            --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched          DEPENDS            ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py        ) -    endif (PACKAGE)  endif (DARWIN) @@ -1795,6 +1793,45 @@ if (INSTALL)    include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)  endif (INSTALL) +if (PACKAGE) +  if (WINDOWS) +    set(VIEWER_DIST_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}") +    set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-windows.tar.bz2") +    set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe") +    set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}") +    set(VIEWER_COPY_MANIFEST copy_w_viewer_manifest) +  endif (WINDOWS) +  if (DARWIN) +    set(VIEWER_DIST_DIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app") +    set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin.tar.bz2") +    set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin") +    set(VIEWER_LIB_GLOB "*.dylib") +  endif (DARWIN) +  if (LINUX) +    set(VIEWER_DIST_DIR "${CMAKE_CURRENT_BINARY_DIR}/packaged") +    set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-linux.tar.bz2") +    set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin") +    set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*") +    set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest) +  endif (LINUX) + +  add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}" +    COMMAND "${PYTHON_EXECUTABLE}" +    ARGS +      "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py" +      "${VIEWER_DIST_DIR}" +      "${VIEWER_EXE_GLOBS}" +      "${VIEWER_LIB_GLOB}" +      "${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/bin/dump_syms" +      "${VIEWER_SYMBOL_FILE}" +    DEPENDS generate_breakpad_symbols.py +    VERBATIM +  ) +  add_custom_target(generate_breakpad_symbols ALL DEPENDS "${VIEWER_SYMBOL_FILE}") +  add_dependencies(generate_breakpad_symbols "${VIEWER_BINARY_NAME}" "${VIEWER_COPY_MANIFEST}") +  add_dependencies(package generate_breakpad_symbols) +endif (PACKAGE) +  if (LL_TESTS)    # To add a viewer unit test, just add the test .cpp file below    # This creates a separate test project per file listed. diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index 4831dc7273..fc531f93d4 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -2,6 +2,6 @@  CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 2.0.2.0"; -CFBundleGetInfoString = "Second Life version 2.0.2.0, Copyright 2004-2009 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version 2.1.0.0"; +CFBundleGetInfoString = "Second Life version 2.1.0.0, Copyright 2004-2009 Linden Research, Inc."; diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index fa2adac10c..97e24a0bd5 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -60,7 +60,7 @@  		</dict>  	</array>  	<key>CFBundleVersion</key> -	<string>2.0.2.0</string> +	<string>2.1.0.0</string>  	<key>CSResourcesFileMapped</key>  	<true/>  </dict> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 864a79c38a..4506ee6e0c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1,6 +1,17 @@  <?xml version="1.0" ?>  <llsd>  <map> +	<key>CrashHostUrl</key> +    <map> +      <key>Comment</key> +      <string>A URL pointing to a crash report handler; overrides cluster negotiation to locate crash handler.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>String</string> +      <key>Value</key> +      <string /> +    </map>      <key>AFKTimeout</key>      <map>        <key>Comment</key> @@ -583,7 +594,7 @@        <key>Type</key>        <string>U32</string>        <key>Value</key> -      <integer>180</integer> +      <integer>120</integer>      </map>      <key>AvatarSex</key>      <map> @@ -11417,5 +11428,27 @@        <key>Value</key>        <integer>1</integer>      </map> +    <key>OutfitOperationsTimeout</key> +    <map> +      <key>Comment</key> +      <string>Timeout for outfit related operations.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>180</integer> +    </map> +    <key>HeightUnits</key> +    <map> +      <key>Comment</key> +      <string>Determines which metric units are used: 1(TRUE) for meter and 0(FALSE) for foot.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map>  </map>  </llsd> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index d4000e9253..dc76a4e518 100644 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -1,26 +1,26 @@  <llsd>      <map> -    <key>BusyModeResponse</key> +    <key>BusyResponseChanged</key>          <map>          <key>Comment</key> -            <string>Auto response to instant messages while in busy mode.</string> +            <string>Does user's busy mode message differ from default?</string>          <key>Persist</key>              <integer>1</integer>          <key>Type</key> -            <string>String</string> +            <string>Boolean</string>          <key>Value</key> -            <string>The Resident you messaged is in 'busy mode' which means they have requested not to be disturbed.  Your message will still be shown in their IM panel for later viewing.</string> +            <integer>0</integer>          </map> -    <key>BusyModeResponse2</key> +    <key>BusyModeResponse</key>          <map>          <key>Comment</key> -            <string>Auto response to instant messages while in busy mode, clean (unencoded) version of BusyModeResponse</string> +            <string>Auto response to instant messages while in busy mode.</string>          <key>Persist</key>              <integer>1</integer>          <key>Type</key>              <string>String</string>          <key>Value</key> -            <string>|TOKEN COPY BusyModeResponse|</string> +            <string>The Resident you messaged is in 'busy mode' which means they have requested not to be disturbed.  Your message will still be shown in their IM panel for later viewing.</string>          </map>      <key>InstantMessageLogPath</key>          <map> diff --git a/indra/newview/generate_breakpad_symbols.py b/indra/newview/generate_breakpad_symbols.py new file mode 100644 index 0000000000..1f42004bb7 --- /dev/null +++ b/indra/newview/generate_breakpad_symbols.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python +# @file generate_breakpad_symbols.py +# @author Brad Kittenbrink <brad@lindenlab.com> +# @brief Simple tool for generating google_breakpad symbol information +#        for the crash reporter. +# +# $LicenseInfo:firstyear=2010&license=viewergpl$ +#  +# Copyright (c) 2010-2010, Linden Research, Inc. +#  +# Second Life Viewer Source Code +# The source code in this file ("Source Code") is provided by Linden Lab +# to you under the terms of the GNU General Public License, version 2.0 +# ("GPL"), unless you have obtained a separate licensing agreement +# ("Other License"), formally executed by you and Linden Lab.  Terms of +# the GPL can be found in doc/GPL-license.txt in this distribution, or +# online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 +#  +# There are special exceptions to the terms and conditions of the GPL as +# it is applied to this Source Code. View the full text of the exception +# in the file doc/FLOSS-exception.txt in this software distribution, or +# online at +# http://secondlifegrid.net/programs/open_source/licensing/flossexception +#  +# By copying, modifying or distributing this software, you acknowledge +# that you have read and understood your obligations described above, +# and agree to abide by those obligations. +#  +# ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +# WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +# COMPLETENESS OR PERFORMANCE. +# $/LicenseInfo$ + + +import collections +import fnmatch +import itertools +import operator +import os +import sys +import shlex +import subprocess +import tarfile +import StringIO + +def usage(): +    print >>sys.stderr, "usage: %s viewer_dir viewer_exes libs_suffix dump_syms_tool viewer_symbol_file" % sys.argv[0] + +class MissingModuleError(Exception): +    def __init__(self, modules): +        Exception.__init__(self, "Failed to find required modules: %r" % modules) +        self.modules = modules + +def main(viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file): +    print "generate_breakpad_symbols run with args: %s" % str((viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file)) + +    # split up list of viewer_exes +    # "'Second Life' SLPlugin" becomes ['Second Life', 'SLPlugin'] +    viewer_exes = shlex.split(viewer_exes) + +    found_required = dict([(module, False) for module in viewer_exes]) + +    def matches(f): +        if f in viewer_exes: +            found_required[f] = True +            return True +        return fnmatch.fnmatch(f, libs_suffix) + +    def list_files(): +        for (dirname, subdirs, filenames) in os.walk(viewer_dir): +            #print "scanning '%s' for modules..." % dirname +            for f in itertools.ifilter(matches, filenames): +                yield os.path.join(dirname, f) + +    def dump_module(m): +        print "dumping module '%s' with '%s'..." % (m, dump_syms_tool) +        child = subprocess.Popen([dump_syms_tool, m] , stdout=subprocess.PIPE) +        out, err = child.communicate() +        return (m,child.returncode, out, err) + +    out = tarfile.open(viewer_symbol_file, 'w:bz2') + +    for (filename,status,symbols,err) in itertools.imap(dump_module, list_files()): +        if status == 0: +            module_line = symbols[:symbols.index('\n')] +            module_line = module_line.split() +            hash_id = module_line[3] +            module = ' '.join(module_line[4:]) +            if sys.platform in ['win32', 'cygwin']: +                mod_name = module[:module.rindex('.pdb')] +            else: +                mod_name = module +            symbolfile = StringIO.StringIO(symbols) +            info = tarfile.TarInfo("%(module)s/%(hash_id)s/%(mod_name)s.sym" % dict(module=module, hash_id=hash_id, mod_name=mod_name)) +            info.size = symbolfile.len +            out.addfile(info, symbolfile) +        else: +            print >>sys.stderr, "warning: failed to dump symbols for '%s': %s" % (filename, err) + +    out.close() + +    missing_modules = [m for (m,_) in +        itertools.ifilter(lambda (k,v): not v, found_required.iteritems()) +    ] +    if missing_modules: +        print >> sys.stderr, "failed to generate %s" % viewer_symbol_file +        os.remove(viewer_symbol_file) +        raise MissingModuleError(missing_modules) + +    symbols = tarfile.open(viewer_symbol_file, 'r:bz2') +    tarfile_members = symbols.getnames() +    symbols.close() + +    for required_module in viewer_exes: +        def match_module_basename(m): +            return os.path.splitext(required_module)[0].lower() \ +                   == os.path.splitext(os.path.basename(m))[0].lower() +        # there must be at least one .sym file in tarfile_members that matches +        # each required module (ignoring file extensions) +        if not reduce(operator.or_, itertools.imap(match_module_basename, tarfile_members)): +            print >> sys.stderr, "failed to find required %s in generated %s" \ +                    % (required_module, viewer_symbol_file) +            os.remove(viewer_symbol_file) +            raise MissingModuleError([required_module]) + +    print "successfully generated %s including required modules '%s'" % (viewer_symbol_file, viewer_exes) + +    return 0 + +if __name__ == "__main__": +    if len(sys.argv) != 6: +        usage() +        sys.exit(1) +    sys.exit(main(*sys.argv[1:])) + diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 644363826a..977f1c9fa8 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2312,12 +2312,6 @@ void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL came  		startCameraAnimation();  	} -	// Remove any pitch from the avatar -	//LLVector3 at = gAgent.getFrameAgent().getAtAxis(); -	//at.mV[VZ] = 0.f; -	//at.normalize(); -	//gAgent.resetAxes(at); -  	if (mCameraMode != CAMERA_MODE_CUSTOMIZE_AVATAR)  	{  		updateLastCamera(); @@ -2338,9 +2332,11 @@ void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL came  	if (isAgentAvatarValid())  	{  		if(avatar_animate) -		{ -			// Remove any pitch from the avatar -			LLVector3 at = gAgent.getFrameAgent().getAtAxis(); +		{	 +			// slamming the avatar's axis to the camera so that when the rotation +			// completes it correctly points to the front of the avatar +			// Remove any pitch or rotation from the avatar +			LLVector3 at = LLViewerCamera::getInstance()->getAtAxis();  			at.mV[VZ] = 0.f;  			at.normalize();  			gAgent.resetAxes(at); @@ -2360,6 +2356,11 @@ void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL came  				mAnimationDuration = gSavedSettings.getF32("ZoomTime");  			}  		} + +		// this is what sets the avatar as the mFocusTargetGlobal +		setFocusGlobal(LLVector3d::zero); +		 +		gAgentAvatarp->updateMeshTextures();  	}  	else  	{ diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index d823a3cbbb..557b3b0a77 100644 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -64,6 +64,25 @@ BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE;  using namespace LLVOAvatarDefines; +/////////////////////////////////////////////////////////////////////////////// + +// Callback to wear and start editing an item that has just been created. +class LLWearAndEditCallback : public LLInventoryCallback +{ +	void fire(const LLUUID& inv_item) +	{ +		if (inv_item.isNull()) return; + +		// Request editing the item after it gets worn. +		gAgentWearables.requestEditingWearable(inv_item); + +		// Wear it. +		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item); +	} +}; + +/////////////////////////////////////////////////////////////////////////////// +  // HACK: For EXT-3923: Pants item shows in inventory with skin icon and messes with "current look"  // Some db items are corrupted, have inventory flags = 0, implying wearable type = shape, even though  // wearable type stored in asset is some other value. @@ -732,7 +751,7 @@ U32 LLAgentWearables::pushWearable(const LLWearableType::EType type, LLWearable  void LLAgentWearables::wearableUpdated(LLWearable *wearable)  { -	gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE); +	gAgentAvatarp->wearableUpdated(wearable->getType(), FALSE);  	wearable->refreshName();  	wearable->setLabelUpdated(); @@ -776,7 +795,7 @@ void LLAgentWearables::popWearable(const LLWearableType::EType type, U32 index)  	if (wearable)  	{  		mWearableDatas[type].erase(mWearableDatas[type].begin() + index); -		gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE); +		gAgentAvatarp->wearableUpdated(wearable->getType(), FALSE);  		wearable->setLabelUpdated();  	}  } @@ -1987,10 +2006,12 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos  // static  void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, const LLUUID& parent_id)  { +	if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return; +  	LLWearable* wearable = LLWearableList::instance().createNewWearable(type);  	LLAssetType::EType asset_type = wearable->getAssetType();  	LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE; -	LLPointer<LLInventoryCallback> cb = wear ? new WearOnAvatarCallback : NULL; +	LLPointer<LLInventoryCallback> cb = wear ? new LLWearAndEditCallback : NULL;  	LLUUID folder_id;  	if (parent_id.notNull()) @@ -2013,17 +2034,44 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con  // static  void LLAgentWearables::editWearable(const LLUUID& item_id)  { -	LLViewerInventoryItem* item; -	LLWearable* wearable; +	LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); +	if (!item) +	{ +		llwarns << "Failed to get linked item" << llendl; +		return; +	} + +	LLWearable* wearable = gAgentWearables.getWearableFromItemID(item_id); +	if (!wearable) +	{ +		llwarns << "Cannot get wearable" << llendl; +		return; +	} + +	if (!gAgentWearables.isWearableModifiable(item->getUUID())) +	{ +		llwarns << "Cannot modify wearable" << llendl; +		return; +	} + +	LLPanel* panel = LLSideTray::getInstance()->getPanel("sidepanel_appearance"); +	LLSidepanelAppearance::editWearable(wearable, panel); +} + +// Request editing the item after it gets worn. +void LLAgentWearables::requestEditingWearable(const LLUUID& item_id) +{ +	mItemToEdit = gInventory.getLinkedItemID(item_id); +} -	if ((item = gInventory.getLinkedItem(item_id)) && -		(wearable = gAgentWearables.getWearableFromAssetID(item->getAssetUUID())) && -		gAgentWearables.isWearableModifiable(item->getUUID()) && -		item->isFinished()) +// Start editing the item if previously requested. +void LLAgentWearables::editWearableIfRequested(const LLUUID& item_id) +{ +	if (mItemToEdit.notNull() && +		mItemToEdit == gInventory.getLinkedItemID(item_id))  	{ -		LLPanel* panel = LLSideTray::getInstance()->showPanel("panel_outfit_edit", LLSD()); -		// copied from LLPanelOutfitEdit::onEditWearableClicked() -		LLSidepanelAppearance::editWearable(wearable, panel->getParent()); +		LLAgentWearables::editWearable(item_id); +		mItemToEdit.setNull();  	}  } @@ -2051,7 +2099,19 @@ void LLAgentWearables::populateMyOutfitsFolder(void)  	}  } +boost::signals2::connection LLAgentWearables::addLoadingStartedCallback(loading_started_callback_t cb) +{ +	return mLoadingStartedSignal.connect(cb); +} +  boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_t cb)  {  	return mLoadedSignal.connect(cb);  } + +void LLAgentWearables::notifyLoadingStarted() +{ +	mLoadingStartedSignal(); +} + +// EOF diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h index 679ecefa6f..3295544e04 100644 --- a/indra/newview/llagentwearables.h +++ b/indra/newview/llagentwearables.h @@ -148,6 +148,12 @@ public:  	static void		editWearable(const LLUUID& item_id);  	bool			moveWearable(const LLViewerInventoryItem* item, bool closer_to_body); +	void			requestEditingWearable(const LLUUID& item_id); +	void			editWearableIfRequested(const LLUUID& item_id); + +private: +	LLUUID			mItemToEdit; +  	//--------------------------------------------------------------------  	// Removing wearables  	//-------------------------------------------------------------------- @@ -218,11 +224,18 @@ public:  	// Signals  	//--------------------------------------------------------------------  public: +	typedef boost::function<void()>			loading_started_callback_t; +	typedef boost::signals2::signal<void()>	loading_started_signal_t; +	boost::signals2::connection				addLoadingStartedCallback(loading_started_callback_t cb); +  	typedef boost::function<void()>			loaded_callback_t;  	typedef boost::signals2::signal<void()>	loaded_signal_t;  	boost::signals2::connection				addLoadedCallback(loaded_callback_t cb); +	void									notifyLoadingStarted(); +  private: +	loading_started_signal_t				mLoadingStartedSignal; // should be called before wearables are changed  	loaded_signal_t							mLoadedSignal; // emitted when all agent wearables get loaded  	//-------------------------------------------------------------------- diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index a899926938..a7206095d3 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -38,11 +38,13 @@  #include "llagentwearables.h"  #include "llappearancemgr.h"  #include "llcommandhandler.h" +#include "lleventtimer.h"  #include "llgesturemgr.h"  #include "llinventorybridge.h"  #include "llinventoryfunctions.h"  #include "llinventoryobserver.h"  #include "llnotificationsutil.h" +#include "lloutfitobserver.h"  #include "llpaneloutfitsinventory.h"  #include "llselectmgr.h"  #include "llsidepanelappearance.h" @@ -55,6 +57,34 @@  char ORDER_NUMBER_SEPARATOR('@'); +class LLOutfitUnLockTimer: public LLEventTimer +{ +public: +	LLOutfitUnLockTimer(F32 period) : LLEventTimer(period) +	{ +		// restart timer on BOF changed event +		LLOutfitObserver::instance().addBOFChangedCallback(boost::bind( +				&LLOutfitUnLockTimer::reset, this)); +		stop(); +	} + +	/*virtual*/ +	BOOL tick() +	{ +		if(mEventTimer.hasExpired()) +		{ +			LLAppearanceMgr::instance().setOutfitLocked(false); +		} +		return FALSE; +	} +	void stop() { mEventTimer.stop(); } +	void start() { mEventTimer.start(); } +	void reset() { mEventTimer.reset(); } +	BOOL getStarted() { return mEventTimer.getStarted(); } + +	LLTimer&  getEventTimer() { return mEventTimer;} +}; +  // support for secondlife:///app/appearance SLapps  class LLAppearanceHandler : public LLCommandHandler  { @@ -614,6 +644,13 @@ const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink()  		const LLViewerInventoryCategory *cat = item->getLinkedCategory();  		if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)  		{ +			const LLUUID parent_id = cat->getParentUUID(); +			LLViewerInventoryCategory*  parent_cat =  gInventory.getCategory(parent_id); +			// if base outfit moved to trash it means that we don't have base outfit +			if (parent_cat != NULL && parent_cat->getPreferredType() == LLFolderType::FT_TRASH) +			{ +				return NULL; +			}  			return item;  		}  	} @@ -762,6 +799,27 @@ void LLAppearanceMgr::onOutfitRename(const LLSD& notification, const LLSD& respo  	}  } +void LLAppearanceMgr::setOutfitLocked(bool locked) +{ +	if (mOutfitLocked == locked) +	{ +		return; +	} + +	mOutfitLocked = locked; +	if (locked) +	{ +		mUnlockOutfitTimer->reset(); +		mUnlockOutfitTimer->start(); +	} +	else +	{ +		mUnlockOutfitTimer->stop(); +	} + +	LLOutfitObserver::instance().notifyOutfitLockChanged(); +} +  void LLAppearanceMgr::addCategoryToCurrentOutfit(const LLUUID& cat_id)  {  	LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); @@ -914,18 +972,10 @@ bool LLAppearanceMgr::getCanRemoveOutfit(const LLUUID& outfit_cat_id)  		return false;  	} -	// Check if the folder contains worn items. -	LLInventoryModel::cat_array_t cats; -	LLInventoryModel::item_array_t items; -	LLFindWorn filter_worn; -	gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_worn); -	if (!items.empty()) -	{ -		return false; -	} -  	// Check for the folder's non-removable descendants.  	LLFindNonRemovableObjects filter_non_removable; +	LLInventoryModel::cat_array_t cats; +	LLInventoryModel::item_array_t items;  	LLInventoryModel::item_array_t::const_iterator it;  	gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_non_removable);  	if (!cats.empty() || !items.empty()) @@ -1357,6 +1407,7 @@ void LLAppearanceMgr::getUserDescendents(const LLUUID& category,  void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append)  { +	gAgentWearables.notifyLoadingStarted();  	if(!category) return;  	llinfos << "wearInventoryCategory( " << category->getName() @@ -1810,6 +1861,14 @@ void LLAppearanceMgr::onFirstFullyVisible()  bool LLAppearanceMgr::updateBaseOutfit()  { +	if (isOutfitLocked()) +	{ +		// don't allow modify locked outfit +		llassert(!isOutfitLocked()); +		return false; +	} +	setOutfitLocked(true); +  	const LLUUID base_outfit_id = getBaseOutfitUUID();  	if (base_outfit_id.isNull()) return false; @@ -1941,13 +2000,19 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id)  class LLShowCreatedOutfit: public LLInventoryCallback  {  public: -	LLShowCreatedOutfit(LLUUID& folder_id): mFolderID(folder_id) +	LLShowCreatedOutfit(LLUUID& folder_id, bool show_panel = true): mFolderID(folder_id), mShowPanel(show_panel)  	{}  	virtual ~LLShowCreatedOutfit()  	{  		LLSD key; -		LLSideTray::getInstance()->showPanel("panel_outfits_inventory", key); +		 +		//EXT-7727. For new accounts LLShowCreatedOutfit is created during login process +		// add may be processed after login process is finished +		if (mShowPanel) +		{ +			LLSideTray::getInstance()->showPanel("panel_outfits_inventory", key); +		}  		LLPanelOutfitsInventory *outfit_panel =  			dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));  		if (outfit_panel) @@ -1971,9 +2036,10 @@ public:  private:  	LLUUID mFolderID; +	bool mShowPanel;  }; -LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name) +LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)  {  	if (!isAgentAvatarValid()) return LLUUID::null; @@ -1986,7 +2052,7 @@ LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name)  	updateClothingOrderingInfo(); -	LLPointer<LLInventoryCallback> cb = new LLShowCreatedOutfit(folder_id); +	LLPointer<LLInventoryCallback> cb = new LLShowCreatedOutfit(folder_id,show_panel);  	shallowCopyCategoryContents(getCOF(),folder_id, cb);  	createBaseOutfitLink(folder_id, cb); @@ -2080,7 +2146,7 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b  	bool result = false;  	if (result = gAgentWearables.moveWearable(item, closer_to_body))  	{ -		gAgentAvatarp->wearableUpdated(item->getWearableType(), TRUE); +		gAgentAvatarp->wearableUpdated(item->getWearableType(), FALSE);  	}  	setOutfitDirty(true); @@ -2138,6 +2204,14 @@ LLAppearanceMgr::LLAppearanceMgr():  	mAttachmentInvLinkEnabled(false),  	mOutfitIsDirty(false)  { +	LLOutfitObserver& outfit_observer = LLOutfitObserver::instance(); + +	// unlock outfit on save operation completed +	outfit_observer.addCOFSavedCallback(boost::bind( +			&LLAppearanceMgr::setOutfitLocked, this, false)); + +	mUnlockOutfitTimer.reset(new LLOutfitUnLockTimer(gSavedSettings.getS32( +			"OutfitOperationsTimeout")));  }  LLAppearanceMgr::~LLAppearanceMgr() diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index f1beef5857..e42f9f7d6f 100644 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -42,10 +42,12 @@  class LLWearable;  class LLWearableHoldingPattern;  class LLInventoryCallback; +class LLOutfitUnLockTimer;  class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>  {  	friend class LLSingleton<LLAppearanceMgr>; +	friend class LLOutfitUnLockTimer;  public:  	typedef std::vector<LLInventoryModel::item_array_t> wearables_by_type_t; @@ -149,7 +151,7 @@ public:  	void removeItemFromAvatar(const LLUUID& item_id); -	LLUUID makeNewOutfitLinks(const std::string& new_folder_name); +	LLUUID makeNewOutfitLinks(const std::string& new_folder_name,bool show_panel = true);  	bool moveWearable(LLViewerInventoryItem* item, bool closer_to_body); @@ -162,6 +164,8 @@ public:  	// COF is processed if cat_id is not specified  	void updateClothingOrderingInfo(LLUUID cat_id = LLUUID::null); +	bool isOutfitLocked() { return mOutfitLocked; } +  protected:  	LLAppearanceMgr();  	~LLAppearanceMgr(); @@ -186,10 +190,20 @@ private:  	static void onOutfitRename(const LLSD& notification, const LLSD& response); +	void setOutfitLocked(bool locked); +  	std::set<LLUUID> mRegisteredAttachments;  	bool mAttachmentInvLinkEnabled;  	bool mOutfitIsDirty; +	/** +	 * Lock for blocking operations on outfit until server reply or timeout exceed +	 * to avoid unsynchronized outfit state or performing duplicate operations. +	 */ +	bool mOutfitLocked; + +	std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer; +  	//////////////////////////////////////////////////////////////////////////////////  	// Item-specific convenience functions   public: diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 95084666bb..f4004d5664 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -103,8 +103,8 @@  // Third party library includes  #include <boost/bind.hpp> +  #if LL_WINDOWS -	#include "llwindebug.h"  #	include <share.h> // For _SH_DENYWR in initMarkerFile  #else  #   include <sys/file.h> // For initMarkerFile support @@ -331,10 +331,6 @@ const char *VFS_INDEX_FILE_BASE = "index.db2.x.";  static std::string gWindowTitle; -std::string gLoginPage; -std::vector<std::string> gLoginURIs; -static std::string gHelperURI; -  LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ;  void idle_afk_check() @@ -603,6 +599,11 @@ bool LLAppViewer::init()  	if (!initConfiguration())  		return false; +	// write Google Breakpad minidump files to our log directory +	std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); +	logdir += gDirUtilp->getDirDelimiter(); +	setMiniDumpDir(logdir); +  	// Although initLogging() is the right place to mess with  	// setFatalFunction(), we can't query gSavedSettings until after  	// initConfiguration(). @@ -1243,6 +1244,14 @@ bool LLAppViewer::cleanup()  	// workaround for DEV-35406 crash on shutdown  	LLEventPumps::instance().reset(); +	// remove any old breakpad minidump files from the log directory +	if (! isError()) +	{ +		std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, ""); +		logdir += gDirUtilp->getDirDelimiter(); +		gDirUtilp->deleteFilesInDir(logdir, "*-*-*-*-*.dmp"); +	} +  	// *TODO - generalize this and move DSO wrangling to a helper class -brad  	std::set<struct apr_dso_handle_t *>::const_iterator i;  	for(i = mPlugins.begin(); i != mPlugins.end(); ++i) @@ -2299,17 +2308,7 @@ void LLAppViewer::checkForCrash(void)  {  #if LL_SEND_CRASH_REPORTS -	//*NOTE:Mani The current state of the crash handler has the MacOSX -	// sending all crash reports as freezes, in order to let  -	// the MacOSX CrashRepoter generate stacks before spawning the  -	// SL crash logger. -	// The Linux and Windows clients generate their own stacks and -	// spawn the SL crash logger immediately. This may change in the future.  -#if LL_DARWIN -	if(gLastExecEvent != LAST_EXEC_NORMAL) -#else		  	if (gLastExecEvent == LAST_EXEC_FROZE) -#endif      {          llinfos << "Last execution froze, requesting to send crash report." << llendl;          // @@ -2519,6 +2518,15 @@ void LLAppViewer::writeSystemInfo()  	// If the crash is handled by LLAppViewer::handleViewerCrash, ie not a freeze,  	// then the value of "CrashNotHandled" will be set to true.  	gDebugInfo["CrashNotHandled"] = (LLSD::Boolean)true; + +	// Insert crash host url (url to post crash log to) if configured. This insures +	// that the crash report will go to the proper location in the case of a  +	// prior freeze. +	std::string crashHostUrl = gSavedSettings.get<std::string>("CrashHostUrl"); +	if(crashHostUrl != "") +	{ +		gDebugInfo["CrashHostUrl"] = crashHostUrl; +	}  	// Dump some debugging info  	LL_INFOS("SystemInfo") << LLTrans::getString("APP_NAME") @@ -2540,13 +2548,6 @@ void LLAppViewer::writeSystemInfo()  	writeDebugInfo(); // Save out debug_info.log early, in case of crash.  } -void LLAppViewer::handleSyncViewerCrash() -{ -	LLAppViewer* pApp = LLAppViewer::instance(); -	// Call to pure virtual, handled by platform specific llappviewer instance. -	pApp->handleSyncCrashTrace();  -} -  void LLAppViewer::handleViewerCrash()  {  	llinfos << "Handle viewer crash entry." << llendl; @@ -2570,9 +2571,13 @@ void LLAppViewer::handleViewerCrash()  		return;  	}  	pApp->mReportedCrash = TRUE; - -	// Make sure the watchdog gets turned off... -// 	pApp->destroyMainloopTimeout(); // SJB: Bah. This causes the crash handler to hang, not sure why. +	 +	// Insert crash host url (url to post crash log to) if configured. +	std::string crashHostUrl = gSavedSettings.get<std::string>("CrashHostUrl"); +	if(crashHostUrl != "") +	{ +		gDebugInfo["CrashHostUrl"] = crashHostUrl; +	}  	//We already do this in writeSystemInfo(), but we do it again here to make /sure/ we have a version  	//to check against no matter what @@ -2604,6 +2609,12 @@ void LLAppViewer::handleViewerCrash()  	gDebugInfo["FirstLogin"] = (LLSD::Boolean) gAgent.isFirstLogin();  	gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall"); +	char *minidump_file = pApp->getMiniDumpFilename(); +	if(minidump_file && minidump_file[0] != 0) +	{ +		gDebugInfo["MinidumpPath"] = minidump_file; +	} +	  	if(gLogoutInProgress)  	{  		gDebugInfo["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH; @@ -2681,10 +2692,6 @@ void LLAppViewer::handleViewerCrash()  	LLError::logToFile(""); -// On Mac, we send the report on the next run, since we need macs crash report -// for a stack trace, so we have to let it the app fail. -#if !LL_DARWIN -  	// Remove the marker file, since otherwise we'll spawn a process that'll keep it locked  	if(gDebugInfo["LastExecEvent"].asInteger() == LAST_EXEC_LOGOUT_CRASH)  	{ @@ -2697,8 +2704,6 @@ void LLAppViewer::handleViewerCrash()  	// Call to pure virtual, handled by platform specific llappviewer instance.  	pApp->handleCrashReporting();  - -#endif //!LL_DARWIN  	return;  } @@ -3342,13 +3347,6 @@ void LLAppViewer::badNetworkHandler()  	mPurgeOnExit = TRUE; -#if LL_WINDOWS -	// Generates the minidump. -	LLWinDebug::generateCrashStacks(NULL); -#endif -	LLAppViewer::handleSyncViewerCrash(); -	LLAppViewer::handleViewerCrash(); -  	std::ostringstream message;  	message <<  		"The viewer has detected mangled network data indicative\n" @@ -3361,6 +3359,8 @@ void LLAppViewer::badNetworkHandler()  		"If the problem continues, see the Tech Support FAQ at: \n"  		"www.secondlife.com/support";  	forceDisconnect(message.str()); +	 +	LLApp::instance()->writeMiniDump();  }  // This routine may get called more than once during the shutdown process. diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 5acd6e11c4..0b862a92a1 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -92,9 +92,7 @@ public:  	virtual bool restoreErrorTrap() = 0; // Require platform specific override to reset error handling mechanism.  	                                     // return false if the error trap needed restoration.  	virtual void handleCrashReporting(bool reportFreeze = false) = 0; // What to do with crash report? -	virtual void handleSyncCrashTrace() = 0; // any low-level crash-prep that has to happen in the context of the crashing thread before the crash report is delivered.  	static void handleViewerCrash(); // Hey! The viewer crashed. Do this, soon. -	static void handleSyncViewerCrash(); // Hey! The viewer crashed. Do this right NOW in the context of the crashing thread.      void checkForCrash();  	// Thread accessors diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 78b0f7ba83..78afdc8995 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -46,23 +46,6 @@  #include <exception> -#if LL_LINUX -# include <dlfcn.h>		// RTLD_LAZY -# include <execinfo.h>  // backtrace - glibc only -#elif LL_SOLARIS -# include <sys/types.h> -# include <unistd.h> -# include <fcntl.h> -# include <ucontext.h> -#endif - -#ifdef LL_ELFBIN -# ifdef __GNUC__ -#  include <cxxabi.h>			// for symbol demangling -# endif -# include "ELFIO/ELFIO.h"		// for better backtraces -#endif -  #if LL_DBUS_ENABLED  # include "llappviewerlinux_api_dbus.h" @@ -86,7 +69,6 @@ static void exceptionTerminateHandler()  	// reinstall default terminate() handler in case we re-terminate.  	if (gOldTerminateHandler) std::set_terminate(gOldTerminateHandler);  	// treat this like a regular viewer crash, with nice stacktrace etc. -	LLAppViewer::handleSyncViewerCrash();  	LLAppViewer::handleViewerCrash();  	// we've probably been killed-off before now, but...  	gOldTerminateHandler(); // call old terminate() handler @@ -109,7 +91,6 @@ int main( int argc, char **argv )  	gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler);  	// install crash handlers  	viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); -	viewer_app_ptr->setSyncErrorHandler(LLAppViewer::handleSyncViewerCrash);  	bool ok = viewer_app_ptr->init();  	if(!ok) @@ -138,201 +119,6 @@ int main( int argc, char **argv )  	return 0;  } -#ifdef LL_SOLARIS -static inline BOOL do_basic_glibc_backtrace() -{ -	BOOL success = FALSE; - -	std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); -	llinfos << "Opening stack trace file " << strace_filename << llendl; -	LLFILE* StraceFile = LLFile::fopen(strace_filename, "w"); -	if (!StraceFile) -	{ -		llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl; -		StraceFile = stderr; -	} - -	printstack(fileno(StraceFile)); - -	if (StraceFile != stderr) -		fclose(StraceFile); - -	return success; -} -#else -#define MAX_STACK_TRACE_DEPTH 40 -// This uses glibc's basic built-in stack-trace functions for a not very -// amazing backtrace. -static inline BOOL do_basic_glibc_backtrace() -{ -	void *stackarray[MAX_STACK_TRACE_DEPTH]; -	size_t size; -	char **strings; -	size_t i; -	BOOL success = FALSE; - -	size = backtrace(stackarray, MAX_STACK_TRACE_DEPTH); -	strings = backtrace_symbols(stackarray, size); - -	std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); -	llinfos << "Opening stack trace file " << strace_filename << llendl; -	LLFILE* StraceFile = LLFile::fopen(strace_filename, "w");		// Flawfinder: ignore -        if (!StraceFile) -	{ -		llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl; -		StraceFile = stderr; -	} - -	if (size) -	{ -		for (i = 0; i < size; i++) -		{ -			// the format of the StraceFile is very specific, to allow (kludgy) machine-parsing -			fprintf(StraceFile, "%-3lu ", (unsigned long)i); -			fprintf(StraceFile, "%-32s\t", "unknown"); -			fprintf(StraceFile, "%p ", stackarray[i]); -			fprintf(StraceFile, "%s\n", strings[i]); -		} - -		success = TRUE; -	} -	 -	if (StraceFile != stderr) -		fclose(StraceFile); - -	free (strings); -	return success; -} - -#if LL_ELFBIN -// This uses glibc's basic built-in stack-trace functions together with -// ELFIO's ability to parse the .symtab ELF section for better symbol -// extraction without exporting symbols (which'd cause subtle, fatal bugs). -static inline BOOL do_elfio_glibc_backtrace() -{ -	void *stackarray[MAX_STACK_TRACE_DEPTH]; -	size_t btsize; -	char **strings; -	BOOL success = FALSE; - -	std::string appfilename = gDirUtilp->getExecutablePathAndName(); - -	std::string strace_filename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log"); -	llinfos << "Opening stack trace file " << strace_filename << llendl; -	LLFILE* StraceFile = LLFile::fopen(strace_filename, "w");		// Flawfinder: ignore -        if (!StraceFile) -	{ -		llinfos << "Opening stack trace file " << strace_filename << " failed. Using stderr." << llendl; -		StraceFile = stderr; -	} - -	// get backtrace address list and basic symbol info -	btsize = backtrace(stackarray, MAX_STACK_TRACE_DEPTH); -	strings = backtrace_symbols(stackarray, btsize); - -	// create ELF reader for our app binary -	IELFI* pReader; -	const IELFISection* pSec = NULL; -	IELFISymbolTable* pSymTbl = 0; -	if (ERR_ELFIO_NO_ERROR != ELFIO::GetInstance()->CreateELFI(&pReader) || -	    ERR_ELFIO_NO_ERROR != pReader->Load(appfilename.c_str()) || -	    // find symbol table, create reader-object -	    NULL == (pSec = pReader->GetSection( ".symtab" )) || -	    ERR_ELFIO_NO_ERROR != pReader->CreateSectionReader(IELFI::ELFI_SYMBOL, pSec, (void**)&pSymTbl) ) -	{ -		// Failed to open our binary and read its symbol table somehow -		llinfos << "Could not initialize ELF symbol reading - doing basic backtrace." << llendl; -		if (StraceFile != stderr) -			fclose(StraceFile); -		// note that we may be leaking some of the above ELFIO -		// objects now, but it's expected that we'll be dead soon -		// and we want to tread delicately until we get *some* kind -		// of useful backtrace. -		return do_basic_glibc_backtrace(); -	} - -	// iterate over trace and symtab, looking for plausible symbols -	std::string   name; -	Elf32_Addr    value; -	Elf32_Word    ssize; -	unsigned char bind; -	unsigned char type; -	Elf32_Half    section; -	int nSymNo = pSymTbl->GetSymbolNum(); -	size_t btpos; -	for (btpos = 0; btpos < btsize; ++btpos) -	{ -		// the format of the StraceFile is very specific, to allow (kludgy) machine-parsing -		fprintf(StraceFile, "%-3ld ", (long)btpos); -		int symidx; -		for (symidx = 0; symidx < nSymNo; ++symidx) -		{ -			if (ERR_ELFIO_NO_ERROR == -			    pSymTbl->GetSymbol(symidx, name, value, ssize, -					       bind, type, section)) -			{ -				// check if trace address within symbol range -				if (uintptr_t(stackarray[btpos]) >= value && -				    uintptr_t(stackarray[btpos]) < value+ssize) -				{ -					// symbol is inside viewer -					fprintf(StraceFile, "%-32s\t", "com.secondlife.indra.viewer"); -					fprintf(StraceFile, "%p ", stackarray[btpos]); - -					char *demangled_str = NULL; -					int demangle_result = 1; -					demangled_str = -						abi::__cxa_demangle -						(name.c_str(), NULL, NULL, -						 &demangle_result); -					if (0 == demangle_result && -					    NULL != demangled_str) { -						fprintf(StraceFile, -							"%s", demangled_str); -						free(demangled_str); -					} -					else // failed demangle; print it raw -					{ -						fprintf(StraceFile, -							"%s", name.c_str()); -					} -					// print offset from symbol start -					fprintf(StraceFile, -						" + %lu\n", -						uintptr_t(stackarray[btpos]) - -						value); -					goto got_sym; // early escape -				} -			} -		} -		// Fallback: -		// Didn't find a suitable symbol in the binary - it's probably -		// a symbol in a DSO; use glibc's idea of what it should be. -		fprintf(StraceFile, "%-32s\t", "unknown"); -		fprintf(StraceFile, "%p ", stackarray[btpos]); -		fprintf(StraceFile, "%s\n", strings[btpos]); -	got_sym:; -	} -	 -	if (StraceFile != stderr) -		fclose(StraceFile); - -	pSymTbl->Release(); -	pSec->Release(); -	pReader->Release(); - -	free(strings); - -	llinfos << "Finished generating stack trace." << llendl; - -	success = TRUE; -	return success; -} -#endif // LL_ELFBIN - -#endif // LL_SOLARIS - -  LLAppViewerLinux::LLAppViewerLinux()  {  } @@ -541,16 +327,6 @@ bool LLAppViewerLinux::sendURLToOtherInstance(const std::string& url)  }  #endif // LL_DBUS_ENABLED -void LLAppViewerLinux::handleSyncCrashTrace() -{ -	// This backtrace writes into stack_trace.log -#  if LL_ELFBIN -	do_elfio_glibc_backtrace(); // more useful backtrace -#  else -	do_basic_glibc_backtrace(); // only slightly useful backtrace -#  endif // LL_ELFBIN -} -  void LLAppViewerLinux::handleCrashReporting(bool reportFreeze)  {  	std::string cmd =gDirUtilp->getExecutableDir(); @@ -686,6 +462,8 @@ bool LLAppViewerLinux::beingDebugged()  bool LLAppViewerLinux::initLogging()  {  	// Remove the last stack trace, if any +	// This file is no longer created, since the move to Google Breakpad +	// The code is left here to clean out any old state in the log dir  	std::string old_stack_file =  		gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"stack_trace.log");  	LLFile::remove(old_stack_file); diff --git a/indra/newview/llappviewerlinux.h b/indra/newview/llappviewerlinux.h index 230c0dc24b..b17380d4d8 100644 --- a/indra/newview/llappviewerlinux.h +++ b/indra/newview/llappviewerlinux.h @@ -68,7 +68,6 @@ protected:  	virtual bool restoreErrorTrap();  	virtual void handleCrashReporting(bool reportFreeze); -	virtual void handleSyncCrashTrace();  	virtual bool initLogging();  	virtual bool initParseCommandLine(LLCommandLineParser& clp); diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 0b5f18c330..1e66e55f3d 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -264,11 +264,6 @@ bool LLAppViewerMacOSX::restoreErrorTrap()  	return reset_count == 0;  } -void LLAppViewerMacOSX::handleSyncCrashTrace() -{ -	// do nothing -} -  static OSStatus CarbonEventHandler(EventHandlerCallRef inHandlerCallRef,   								   EventRef inEvent,   								   void* inUserData) @@ -384,38 +379,6 @@ void LLAppViewerMacOSX::handleCrashReporting(bool reportFreeze)  		}  	} - -	if(!reportFreeze) -	{ -		_exit(1); -	} -	 -	// TODO from palmer: Find a better way to handle managing old crash logs -	// when this is a separate imbedable module.  Ideally just sort crash stack -	// logs based on date, and grab the latest one as opposed to deleting them -	// for thoughts on what the module would look like. -	// See: https://wiki.lindenlab.com/wiki/Viewer_Crash_Reporter_Round_4 -	 -	// Remove the crash stack log from previous executions. -	// Since we've started logging a new instance of the app, we can assume  -	// The old crash stack is invalid for the next crash report. -	char path[MAX_PATH];		 -	FSRef folder; -	if(FSFindFolder(kUserDomain, kLogsFolderType, false, &folder) == noErr) -	{ -		// folder is an FSRef to ~/Library/Logs/ -		if(FSRefMakePath(&folder, (UInt8*)&path, sizeof(path)) == noErr) -		{ -			std::string pathname = std::string(path) + std::string("/CrashReporter/"); -			std::string mask = "Second Life*"; -			std::string file_name; -			while(gDirUtilp->getNextFileInDir(pathname, mask, file_name, false)) -			{ -				LLFile::remove(pathname + file_name); -			} -		} -	} -	  }  std::string LLAppViewerMacOSX::generateSerialNumber() diff --git a/indra/newview/llappviewermacosx.h b/indra/newview/llappviewermacosx.h index cbf7e6c209..3d7bb55556 100644 --- a/indra/newview/llappviewermacosx.h +++ b/indra/newview/llappviewermacosx.h @@ -55,7 +55,6 @@ public:  protected:  	virtual bool restoreErrorTrap();  	virtual void handleCrashReporting(bool reportFreeze);  -	virtual void handleSyncCrashTrace();  	std::string generateSerialNumber();  	virtual bool initParseCommandLine(LLCommandLineParser& clp); diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 60a6d2f072..e3ef04d03d 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -57,8 +57,6 @@  #include "llweb.h"  #include "llsecondlifeurls.h" -#include "llwindebug.h" -  #include "llviewernetwork.h"  #include "llmd5.h"  #include "llfindlocale.h" @@ -81,51 +79,6 @@ extern "C" {  const std::string LLAppViewerWin32::sWindowClass = "Second Life"; -LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop) -{ -    // *NOTE:Mani - this code is stolen from LLApp, where its never actually used. -	//OSMessageBox("Attach Debugger Now", "Error", OSMB_OK); -    // *TODO: Translate the signals/exceptions into cross-platform stuff -	// Windows implementation -    _tprintf( _T("Entering Windows Exception Handler...\n") ); -	llinfos << "Entering Windows Exception Handler..." << llendl; - -	// Make sure the user sees something to indicate that the app crashed. -	LONG retval; - -	if (LLApp::isError()) -	{ -	    _tprintf( _T("Got another fatal signal while in the error handler, die now!\n") ); -		llwarns << "Got another fatal signal while in the error handler, die now!" << llendl; - -		retval = EXCEPTION_EXECUTE_HANDLER; -		return retval; -	} - -	// Generate a minidump if we can. -	// Before we wake the error thread... -	// Which will start the crash reporting. -	LLWinDebug::generateCrashStacks(exception_infop); -	 -	// Flag status to error, so thread_error starts its work -	LLApp::setError(); - -	// Block in the exception handler until the app has stopped -	// This is pretty sketchy, but appears to work just fine -	while (!LLApp::isStopped()) -	{ -		ms_sleep(10); -	} - -	// -	// At this point, we always want to exit the app.  There's no graceful -	// recovery for an unhandled exception. -	//  -	// Just kill the process. -	retval = EXCEPTION_EXECUTE_HANDLER;	 -	return retval; -} -  // Create app mutex creates a unique global windows object.   // If the object can be created it returns true, otherwise  // it returns false. The false result can be used to determine  @@ -191,8 +144,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,  	gIconResource = MAKEINTRESOURCE(IDI_LL_ICON);  	LLAppViewerWin32* viewer_app_ptr = new LLAppViewerWin32(lpCmdLine); - -	LLWinDebug::initExceptionHandler(viewer_windows_exception_handler);   	viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); @@ -405,12 +356,6 @@ bool LLAppViewerWin32::cleanup()  bool LLAppViewerWin32::initLogging()  { -	// Remove the crash stack log from previous executions. -	// Since we've started logging a new instance of the app, we can assume  -	// *NOTE: This should happen before the we send a 'previous instance froze' -	// crash report, but it must happen after we initialize the DirUtil. -	LLWinDebug::clearCrashStacks(); -  	return LLAppViewer::initLogging();  } @@ -529,13 +474,9 @@ bool LLAppViewerWin32::initParseCommandLine(LLCommandLineParser& clp)  }  bool LLAppViewerWin32::restoreErrorTrap() -{ -	return LLWinDebug::checkExceptionHandler(); -} - -void LLAppViewerWin32::handleSyncCrashTrace() -{ -	// do nothing +{	 +	return true; +	//return LLWinDebug::checkExceptionHandler();  }  void LLAppViewerWin32::handleCrashReporting(bool reportFreeze) diff --git a/indra/newview/llappviewerwin32.h b/indra/newview/llappviewerwin32.h index 13454edeec..52dcc583a4 100644 --- a/indra/newview/llappviewerwin32.h +++ b/indra/newview/llappviewerwin32.h @@ -57,7 +57,6 @@ protected:  	virtual bool restoreErrorTrap();  	virtual void handleCrashReporting(bool reportFreeze);  -	virtual void handleSyncCrashTrace();  	virtual bool sendURLToOtherInstance(const std::string& url); diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 01d6c3a8d5..2dafe295fe 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -656,6 +656,8 @@ void LLAvatarActions::shareWithAvatars()  	LLFloaterAvatarPicker* picker =  		LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE);  	picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable)); +	picker->openFriendsTab(); +	LLNotificationsUtil::add("ShareNotification");  }  // static diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 0bd03571da..18c69b5130 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -243,7 +243,7 @@ public:  		gCacheName->get(mAvatarID, FALSE, boost::bind(&LLChatHistoryHeader::nameUpdatedCallback, this, _1, _2, _3, _4));  		//*TODO overly defensive thing, source type should be maintained out there -		if((chat.mFromID.isNull() && chat.mFromName.empty()) || chat.mFromName == SYSTEM_FROM) +		if((chat.mFromID.isNull() && chat.mFromName.empty()) || chat.mFromName == SYSTEM_FROM && chat.mFromID.isNull())  		{  			mSourceType = CHAT_SOURCE_SYSTEM;  		} @@ -667,7 +667,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL  				// (don't let object names with hyperlinks override our objectim Url)  				LLStyle::Params link_params(style_params);  				link_params.color.control = "HTMLLinkColor"; -				link_params.link_href = url; +				link_params.link_href = LLURI::escape(url);  				mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>"  + delimiter,  									false, link_params);  			} diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 916d53da3c..611396b0e5 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -58,13 +58,19 @@ static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR;  class CofContextMenu : public LLListContextMenu  {  protected: -	static void updateCreateWearableLabel(LLMenuGL* menu, const LLUUID& item_id) +	CofContextMenu(LLCOFWearables* cof_wearables) +	:	mCOFWearables(cof_wearables) +	{ +		llassert(mCOFWearables); +	} + +	void updateCreateWearableLabel(LLMenuGL* menu, const LLUUID& item_id)  	{  		LLMenuItemGL* menu_item = menu->getChild<LLMenuItemGL>("create_new"); +		LLWearableType::EType w_type = getWearableType(item_id);  		// Hide the "Create new <WEARABLE_TYPE>" if it's irrelevant. -		LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); -		if (!item || !item->isWearableType()) +		if (w_type == LLWearableType::WT_NONE)  		{  			menu_item->setVisible(FALSE);  			return; @@ -72,25 +78,67 @@ protected:  		// Set proper label for the "Create new <WEARABLE_TYPE>" menu item.  		LLStringUtil::format_map_t args; -		LLWearableType::EType w_type = item->getWearableType();  		args["[WEARABLE_TYPE]"] = LLWearableType::getTypeDefaultNewName(w_type);  		std::string new_label = LLTrans::getString("CreateNewWearable", args);  		menu_item->setLabel(new_label);  	} -	static void createNew(const LLUUID& item_id) +	void createNew(const LLUUID& item_id)  	{ -		LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); -		if (!item || !item->isWearableType()) return; +		LLAgentWearables::createWearable(getWearableType(item_id), true); +	} + +	// Get wearable type of the given item. +	// +	// There is a special case: so-called "dummy items" +	// (i.e. the ones that are there just to indicate that you're not wearing +	// any wearables of the corresponding type. They are currently grayed out +	// and suffixed with "not worn"). +	// Those items don't have an UUID, but they do have an associated wearable type. +	// If the user has invoked context menu for such item, +	// we ignore the passed item_id and retrieve wearable type from the item. +	LLWearableType::EType getWearableType(const LLUUID& item_id) +	{ +		if (!isDummyItem(item_id)) +		{ +			LLViewerInventoryItem* item = gInventory.getLinkedItem(item_id); +			if (item && item->isWearableType()) +			{ +				return item->getWearableType(); +			} +		} +		else if (mCOFWearables) // dummy item selected +		{ +			LLPanelDummyClothingListItem* item; + +			item = dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem()); +			if (item) +			{ +				return item->getWearableType(); +			} +		} + +		return LLWearableType::WT_NONE; +	} -		LLAgentWearables::createWearable(item->getWearableType(), true); +	static bool isDummyItem(const LLUUID& item_id) +	{ +		return item_id.isNull();  	} + +	LLCOFWearables* mCOFWearables;  };  ////////////////////////////////////////////////////////////////////////// -class CofAttachmentContextMenu : public LLListContextMenu +class CofAttachmentContextMenu : public CofContextMenu  { +public: +	CofAttachmentContextMenu(LLCOFWearables* cof_wearables) +	:	CofContextMenu(cof_wearables) +	{ +	} +  protected:  	/*virtual*/ LLContextMenu* createMenu() @@ -108,8 +156,13 @@ protected:  class CofClothingContextMenu : public CofContextMenu  { -protected: +public: +	CofClothingContextMenu(LLCOFWearables* cof_wearables) +	:	CofContextMenu(cof_wearables) +	{ +	} +protected:  	/*virtual*/ LLContextMenu* createMenu()  	{  		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; @@ -121,7 +174,7 @@ protected:  		registrar.add("Clothing.MoveUp", boost::bind(moveWearable, selected_id, false));  		registrar.add("Clothing.MoveDown", boost::bind(moveWearable, selected_id, true));  		registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id)); -		registrar.add("Clothing.Create", boost::bind(createNew, selected_id)); +		registrar.add("Clothing.Create", boost::bind(&CofClothingContextMenu::createNew, this, selected_id));  		enable_registrar.add("Clothing.OnEnable", boost::bind(&CofClothingContextMenu::onEnable, this, _2)); @@ -171,8 +224,13 @@ protected:  class CofBodyPartContextMenu : public CofContextMenu  { -protected: +public: +	CofBodyPartContextMenu(LLCOFWearables* cof_wearables) +	:	CofContextMenu(cof_wearables) +	{ +	} +protected:  	/*virtual*/ LLContextMenu* createMenu()  	{  		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; @@ -184,7 +242,7 @@ protected:  		LLPanelOutfitEdit* panel_oe = dynamic_cast<LLPanelOutfitEdit*>(LLSideTray::getInstance()->getPanel("panel_outfit_edit"));  		registrar.add("BodyPart.Replace", boost::bind(&LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked, panel_oe, selected_id));  		registrar.add("BodyPart.Edit", boost::bind(LLAgentWearables::editWearable, selected_id)); -		registrar.add("BodyPart.Create", boost::bind(createNew, selected_id)); +		registrar.add("BodyPart.Create", boost::bind(&CofBodyPartContextMenu::createNew, this, selected_id));  		enable_registrar.add("BodyPart.OnEnable", boost::bind(&CofBodyPartContextMenu::onEnable, this, _2)); @@ -219,9 +277,9 @@ LLCOFWearables::LLCOFWearables() : LLPanel(),  	mBodyParts(NULL),  	mLastSelectedList(NULL)  { -	mClothingMenu = new CofClothingContextMenu(); -	mAttachmentMenu = new CofAttachmentContextMenu(); -	mBodyPartMenu = new CofBodyPartContextMenu(); +	mClothingMenu = new CofClothingContextMenu(this); +	mAttachmentMenu = new CofAttachmentContextMenu(this); +	mBodyPartMenu = new CofBodyPartContextMenu(this);  };  LLCOFWearables::~LLCOFWearables() diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 96364f9418..8f6816b845 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -446,6 +446,19 @@ BOOL LLFloaterAvatarPicker::handleDragAndDrop(S32 x, S32 y, MASK mask,  	return TRUE;  } + +void LLFloaterAvatarPicker::openFriendsTab() +{ +	LLTabContainer* tab_container = getChild<LLTabContainer>("ResidentChooserTabs"); +	if (tab_container == NULL) +	{ +		llassert(tab_container != NULL); +		return; +	} + +	tab_container->selectTabByName("FriendsPanel"); +} +  // static   void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void**)  { diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h index e69b814f9f..0af72e85a0 100644 --- a/indra/newview/llfloateravatarpicker.h +++ b/indra/newview/llfloateravatarpicker.h @@ -66,6 +66,8 @@ public:  						   void *cargo_data, EAcceptance *accept,  						   std::string& tooltip_msg); +	void openFriendsTab(); +  private:  	void editKeystroke(class LLLineEditor* caller, void* user_data); diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp index 46b3695511..d359856443 100644 --- a/indra/newview/llfloaterbuy.cpp +++ b/indra/newview/llfloaterbuy.cpp @@ -254,7 +254,6 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,  		std::string icon_name = LLInventoryIcon::getIconName(inv_item->getType(),   							 inv_item->getInventoryType(), -							 inv_item->getIsLinkType(),  							 inv_item->getFlags(),  							 item_is_multi);  		row["columns"][0]["column"] = "icon"; diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp index c35653178a..9bde3b1dac 100644 --- a/indra/newview/llfloaterbuycontents.cpp +++ b/indra/newview/llfloaterbuycontents.cpp @@ -223,7 +223,6 @@ void LLFloaterBuyContents::inventoryChanged(LLViewerObject* obj,  		std::string icon_name = LLInventoryIcon::getIconName(inv_item->getType(),   								 inv_item->getInventoryType(), -								 inv_item->getIsLinkType(),  								 inv_item->getFlags(),  								 item_is_multi);  		row["columns"][0]["column"] = "icon"; diff --git a/indra/newview/llfloaterbuycurrencyhtml.cpp b/indra/newview/llfloaterbuycurrencyhtml.cpp index 5815df36d1..7f41a64064 100644 --- a/indra/newview/llfloaterbuycurrencyhtml.cpp +++ b/indra/newview/llfloaterbuycurrencyhtml.cpp @@ -87,6 +87,9 @@ void LLFloaterBuyCurrencyHTML::navigateToFinalURL()  	replace[ "[MSG]" ] = LLURI::escape( mMessage );  	LLStringUtil::format( buy_currency_url, replace ); +	// write final URL to debug console +	llinfos << "Buy currency HTML prased URL is " << buy_currency_url << llendl; +  	// kick off the navigation  	mBrowser->navigateTo( buy_currency_url );  } @@ -98,6 +101,9 @@ void LLFloaterBuyCurrencyHTML::handleMediaEvent( LLPluginClassMedia* self, EMedi  	// placeholder for now - just in case we want to catch media events  	if ( LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_COMPLETE == event )  	{ +		// update currency after we complete a navigation since there are many ways  +		// this can result in a different L$ balance +		LLStatusBar::sendMoneyBalanceRequest();  	};  } @@ -105,6 +111,9 @@ void LLFloaterBuyCurrencyHTML::handleMediaEvent( LLPluginClassMedia* self, EMedi  //  void LLFloaterBuyCurrencyHTML::onClose( bool app_quitting )  { +	// update L$ balanace one more time +	LLStatusBar::sendMoneyBalanceRequest(); +  	destroy();  } diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp index ca346138fb..d6effb2b21 100644 --- a/indra/newview/llfloatercamera.cpp +++ b/indra/newview/llfloatercamera.cpp @@ -49,6 +49,9 @@  static LLDefaultChildRegistry::Register<LLPanelCameraItem> r("panel_camera_item"); +const F32 NUDGE_TIME = 0.25f;		// in seconds +const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed +  // Constants  const F32 CAMERA_BUTTON_DELAY = 0.0f; @@ -75,6 +78,7 @@ protected:  	void	onZoomPlusHeldDown();  	void	onZoomMinusHeldDown();  	void	onSliderValueChanged(); +	F32		getOrbitRate(F32 time);  private:  	LLButton*	mPlusBtn; @@ -155,8 +159,8 @@ LLPanelCameraZoom::LLPanelCameraZoom()  	mMinusBtn( NULL ),  	mSlider( NULL )  { -	mCommitCallbackRegistrar.add("Zoom.minus", boost::bind(&LLPanelCameraZoom::onZoomPlusHeldDown, this)); -	mCommitCallbackRegistrar.add("Zoom.plus", boost::bind(&LLPanelCameraZoom::onZoomMinusHeldDown, this)); +	mCommitCallbackRegistrar.add("Zoom.minus", boost::bind(&LLPanelCameraZoom::onZoomMinusHeldDown, this)); +	mCommitCallbackRegistrar.add("Zoom.plus", boost::bind(&LLPanelCameraZoom::onZoomPlusHeldDown, this));  	mCommitCallbackRegistrar.add("Slider.value_changed", boost::bind(&LLPanelCameraZoom::onSliderValueChanged, this));  } @@ -179,9 +183,9 @@ void LLPanelCameraZoom::onZoomPlusHeldDown()  	F32 val = mSlider->getValueF32();  	F32 inc = mSlider->getIncrement();  	mSlider->setValue(val - inc); -	// commit only if value changed -	if (val != mSlider->getValueF32()) -		mSlider->onCommit(); +	F32 time = mPlusBtn->getHeldDownTime(); +	gAgentCamera.unlockView(); +	gAgentCamera.setOrbitInKey(getOrbitRate(time));  }  void LLPanelCameraZoom::onZoomMinusHeldDown() @@ -189,9 +193,22 @@ void LLPanelCameraZoom::onZoomMinusHeldDown()  	F32 val = mSlider->getValueF32();  	F32 inc = mSlider->getIncrement();  	mSlider->setValue(val + inc); -	// commit only if value changed -	if (val != mSlider->getValueF32()) -		mSlider->onCommit(); +	F32 time = mMinusBtn->getHeldDownTime(); +	gAgentCamera.unlockView(); +	gAgentCamera.setOrbitOutKey(getOrbitRate(time)); +} + +F32 LLPanelCameraZoom::getOrbitRate(F32 time) +{ +	if( time < NUDGE_TIME ) +	{ +		F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME; +		return rate; +	} +	else +	{ +		return 1; +	}  }  void  LLPanelCameraZoom::onSliderValueChanged() diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h index 8fa7a53996..564e38d02d 100644 --- a/indra/newview/llfloatercamera.h +++ b/indra/newview/llfloatercamera.h @@ -39,7 +39,6 @@  #include "llflatlistview.h"  class LLJoystickCameraRotate; -class LLJoystickCameraZoom;  class LLJoystickCameraTrack;  class LLFloaterReg;  class LLPanelCameraZoom; diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index c259659083..e74bfae026 100644 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -54,7 +54,10 @@  // Constants  //  const F32 MAP_MINOR_DIR_THRESHOLD = 0.08f; - +const S32 MAP_PADDING_LEFT = 0; +const S32 MAP_PADDING_TOP = 2; +const S32 MAP_PADDING_RIGHT = 2; +const S32 MAP_PADDING_BOTTOM = 0;  //  // Member functions  // @@ -106,7 +109,8 @@ BOOL LLFloaterMap::postBuild()  		mPopupMenu->setItemEnabled ("Stop Tracking", false);  	} -	stretchMiniMap(getRect().getWidth(),getRect().getHeight()); +	stretchMiniMap(getRect().getWidth() - MAP_PADDING_LEFT - MAP_PADDING_RIGHT +		,getRect().getHeight() - MAP_PADDING_TOP - MAP_PADDING_BOTTOM);  	updateMinorDirections(); @@ -238,7 +242,7 @@ void LLFloaterMap::stretchMiniMap(S32 width,S32 height)  	if(mMap)  	{  		LLRect map_rect; -		map_rect.setLeftTopAndSize( 0, getRect().getHeight(), width, height); +		map_rect.setLeftTopAndSize( MAP_PADDING_LEFT, getRect().getHeight() - MAP_PADDING_TOP, width, height);  		mMap->reshape( width, height, 1);  		mMap->setRect(map_rect);  	} @@ -248,7 +252,8 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)  {  	LLFloater::reshape(width, height, called_from_parent); -	stretchMiniMap(width, height); +	stretchMiniMap(width - MAP_PADDING_LEFT - MAP_PADDING_RIGHT +		,height - MAP_PADDING_TOP - MAP_PADDING_BOTTOM);  	updateMinorDirections();  } diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 5fbbb2c1a8..2299cd719c 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -330,9 +330,28 @@ BOOL LLFloaterPreference::postBuild()  	std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");  	childSetText("cache_location", cache_location); +	// if floater is opened before login set default localized busy message +	if (LLStartUp::getStartupState() < STATE_STARTED) +	{ +		gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault")); +	} +  	return TRUE;  } +void LLFloaterPreference::onBusyResponseChanged() +{ +	// set "BusyResponseChanged" TRUE if user edited message differs from default, FALSE otherwise +	if(LLTrans::getString("BusyModeResponseDefault") != getChild<LLUICtrl>("busy_response")->getValue().asString()) +	{ +		gSavedPerAccountSettings.setBOOL("BusyResponseChanged", TRUE ); +	} +	else +	{ +		gSavedPerAccountSettings.setBOOL("BusyResponseChanged", FALSE ); +	} +} +  LLFloaterPreference::~LLFloaterPreference()  {  	// clean up user data @@ -487,6 +506,22 @@ void LLFloaterPreference::cancel()  void LLFloaterPreference::onOpen(const LLSD& key)  { +	// this variable and if that follows it are used to properly handle busy mode response message +	static bool initialized = FALSE; +	// if user is logged in and we haven't initialized busy_response yet, do it +	if (!initialized && LLStartUp::getStartupState() == STATE_STARTED) +	{ +		// Special approach is used for busy response localization, because "BusyModeResponse" is +		// in non-localizable xml, and also because it may be changed by user and in this case it shouldn't be localized. +		// To keep track of whether busy response is default or changed by user additional setting BusyResponseChanged +		// was added into per account settings. + +		// initialization should happen once,so setting variable to TRUE +		initialized = TRUE; +		// this connection is needed to properly set "BusyResponseChanged" setting when user makes changes in +		// busy response message. +		gSavedPerAccountSettings.getControl("BusyModeResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onBusyResponseChanged, this)); +	}  	gAgent.sendAgentUserInfoRequest();  	/////////////////////////// From LLPanelGeneral ////////////////////////// @@ -540,6 +575,16 @@ void LLFloaterPreference::onVertexShaderEnable()  	refreshEnabledGraphics();  } +//static +void LLFloaterPreference::initBusyResponse() +	{ +		if (!gSavedPerAccountSettings.getBOOL("BusyResponseChanged")) +		{ +			//LLTrans::getString("BusyModeResponseDefault") is used here for localization (EXT-5885) +			gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault")); +		} +	} +  void LLFloaterPreference::setHardwareDefaults()  {  	LLFeatureManager::getInstance()->applyRecommendedSettings(); @@ -960,18 +1005,6 @@ void LLFloaterPreference::onChangeQuality(const LLSD& data)  	refresh();  } -// static -// DEV-24146 -  needs to be removed at a later date. jan-2009 -void LLFloaterPreference::cleanupBadSetting() -{ -	if (gSavedPerAccountSettings.getString("BusyModeResponse2") == "|TOKEN COPY BusyModeResponse|") -	{ -		llinfos << "cleaning old BusyModeResponse" << llendl; -		//LLTrans::getString("BusyModeResponseDefault") is used here for localization (EXT-5885) -		gSavedPerAccountSettings.setString("BusyModeResponse2", LLTrans::getString("BusyModeResponseDefault")); -	} -} -  void LLFloaterPreference::onClickSetKey()  {  	LLVoiceSetKeyDialog* dialog = LLFloaterReg::showTypedInstance<LLVoiceSetKeyDialog>("voice_set_key", LLSD(), TRUE); diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 71aa5d3189..b45e09db7d 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -80,6 +80,9 @@ public:  	// refresh all the graphics preferences menus  	static void refreshEnabledGraphics(); +	// translate user's busy response message according to current locale if message is default, otherwise do nothing +	static void initBusyResponse(); +  protected:	  	void		onBtnOK();  	void		onBtnCancel(); @@ -87,6 +90,9 @@ protected:  	void		onClickBrowserClearCache(); +	// set value of "BusyResponseChanged" in account settings depending on whether busy response +	// string differs from default after user changes. +	void onBusyResponseChanged();  	// if the custom settings box is clicked  	void onChangeCustom();  	void updateMeterText(LLUICtrl* ctrl); @@ -140,7 +146,6 @@ public:  	void buildPopupLists();  	static void refreshSkin(void* data); -	static void cleanupBadSetting();  private:  	static std::string sSkin;  	bool mGotPersonalInfo; diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp index a87f7288fa..74034cfbf7 100644 --- a/indra/newview/llfolderview.cpp +++ b/indra/newview/llfolderview.cpp @@ -88,6 +88,10 @@ const S32 MIN_ITEM_WIDTH_VISIBLE = LLFolderViewItem::ICON_WIDTH  			+ /*first few characters*/ 40;  const S32 MINIMUM_RENAMER_WIDTH = 80; +// *TODO: move in params in xml if necessary. Requires modification of LLFolderView & LLInventoryPanel Params. +const S32 STATUS_TEXT_HPAD = 6; +const S32 STATUS_TEXT_VPAD = 8; +  enum {  	SIGNAL_NO_KEYBOARD_FOCUS = 1,  	SIGNAL_KEYBOARD_FOCUS = 2 @@ -246,6 +250,10 @@ LLFolderView::LLFolderView(const Params& p)  	text_p.font(font);  	text_p.visible(false);  	text_p.allow_html(true); +	text_p.wrap(true); // allow multiline text. See EXT-7564, EXT-7047 +	// set text padding the same as in People panel. EXT-7047, EXT-4837 +	text_p.h_pad(STATUS_TEXT_HPAD); +	text_p.v_pad(STATUS_TEXT_VPAD);  	mStatusTextBox = LLUICtrlFactory::create<LLTextBox> (text_p);  	mStatusTextBox->setFollowsLeft();  	mStatusTextBox->setFollowsTop(); @@ -953,6 +961,23 @@ void LLFolderView::draw()  		}  		mStatusTextBox->setValue(mStatusText);  		mStatusTextBox->setVisible( TRUE ); + +		// firstly reshape message textbox with current size. This is necessary to +		// LLTextBox::getTextPixelHeight works properly +		const LLRect local_rect = getLocalRect(); +		mStatusTextBox->setShape(local_rect); + +		// get preferable text height... +		S32 pixel_height = mStatusTextBox->getTextPixelHeight(); +		bool height_changed = local_rect.getHeight() != pixel_height; +		if (height_changed) +		{ +			// ... if it does not match current height, lets rearrange current view. +			// This will indirectly call ::arrange and reshape of the status textbox. +			// We should call this method to also notify parent about required rect. +			// See EXT-7564, EXT-7047. +			arrangeFromRoot(); +		}  	} @@ -2310,7 +2335,7 @@ void LLFolderView::updateRenamerPosition()  bool LLFolderView::selectFirstItem()  {  	for (folders_t::iterator iter = mFolders.begin(); -		 iter != mFolders.end();) +		 iter != mFolders.end();++iter)  	{  		LLFolderViewFolder* folder = (*iter );  		if (folder->getVisible()) @@ -2347,7 +2372,7 @@ bool LLFolderView::selectLastItem()  		}  	}  	for (folders_t::reverse_iterator iter = mFolders.rbegin(); -		 iter != mFolders.rend();) +		 iter != mFolders.rend();++iter)  	{  		LLFolderViewFolder* folder = (*iter);  		if (folder->getVisible()) diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h index a2ef8c1d12..82f8a10cf3 100644 --- a/indra/newview/llfoldervieweventlistener.h +++ b/indra/newview/llfoldervieweventlistener.h @@ -37,6 +37,7 @@  #include "llinventorytype.h"  #include "llpermissionsflags.h"  #include "llpointer.h" +#include "llwearabletype.h"  class LLFolderViewItem; @@ -89,6 +90,7 @@ public:  	virtual BOOL hasChildren() const = 0;  	virtual LLInventoryType::EType getInventoryType() const = 0;  	virtual void performAction(LLInventoryModel* model, std::string action) = 0; +	virtual LLWearableType::EType getWearableType() const = 0;  	// This method should be called when a drag begins. returns TRUE  	// if the drag can begin, otherwise FALSE. diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp index 54e9bd5383..0c437cf035 100644 --- a/indra/newview/llfolderviewitem.cpp +++ b/indra/newview/llfolderviewitem.cpp @@ -96,6 +96,7 @@ void LLFolderViewItem::cleanupClass()  LLFolderViewItem::Params::Params()  :	icon(),  	icon_open(), +	icon_overlay(),  	root(),  	listener(),  	folder_arrow_image("folder_arrow_image"), @@ -133,6 +134,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)  	mCreationDate(p.creation_date),  	mIcon(p.icon),  	mIconOpen(p.icon_open), +	mIconOverlay(p.icon_overlay),  	mListener(p.listener),  	mHidden(false),  	mShowLoadStatus(false) @@ -617,6 +619,7 @@ const std::string& LLFolderViewItem::getSearchableLabel() const  LLViewerInventoryItem * LLFolderViewItem::getInventoryItem(void)  { +	if (!getListener()) return NULL;  	return gInventory.getItem(getListener()->getUUID());  } @@ -948,7 +951,8 @@ void LLFolderViewItem::draw()  		mDragAndDropTarget = FALSE;  	} -	 +	const LLViewerInventoryItem *item = getInventoryItem(); +	const BOOL highlight_link = mIconOverlay && item && item->getIsLinkType();  	//--------------------------------------------------------------------------------//  	// Draw open icon  	// @@ -962,6 +966,10 @@ void LLFolderViewItem::draw()   		mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);   	} +	if (highlight_link) +	{ +		mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1); +	}  	//--------------------------------------------------------------------------------//  	// Exit if no label to draw @@ -972,8 +980,7 @@ void LLFolderViewItem::draw()  	}  	LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor; -	const LLViewerInventoryItem *item = getInventoryItem(); -	if (item && item->getIsLinkType()) color = sLinkColor; +	if (highlight_link) color = sLinkColor;  	if (in_library) color = sLibraryColor;  	F32 right_x  = 0; diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index 57c722afa4..d6e4b2f556 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -97,6 +97,7 @@ public:  	{  		Optional<LLUIImage*>					icon;  		Optional<LLUIImage*>					icon_open;  // used for folders +		Optional<LLUIImage*>					icon_overlay;  // for links  		Optional<LLFolderView*>					root;  		Optional<LLFolderViewEventListener*>	listener; @@ -147,6 +148,7 @@ protected:  	LLUIImagePtr				mIcon;  	std::string					mStatusText;  	LLUIImagePtr				mIconOpen; +	LLUIImagePtr				mIconOverlay;  	BOOL						mHasVisibleChildren;  	S32							mIndentation;  	S32							mItemHeight; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 3a9c5ba698..7ce96a6ac1 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -65,6 +65,7 @@  #include "llsidetray.h"  #include "lltrans.h"  #include "llviewerassettype.h" +#include "llviewerfoldertype.h"  #include "llviewermenu.h"  #include "llviewermessage.h"  #include "llviewerobjectlist.h" @@ -2208,13 +2209,7 @@ void LLFolderBridge::determineFolderType()  BOOL LLFolderBridge::isItemRenameable() const  { -	LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)getCategory(); -	if(cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) -	   && (cat->getOwnerID() == gAgent.getID())) -	{ -		return TRUE; -	} -	return FALSE; +	return get_is_category_renameable(getInventoryModel(), mUUID);  }  void LLFolderBridge::restoreItem() @@ -2255,58 +2250,14 @@ LLUIImagePtr LLFolderBridge::getIcon() const  }  // static -LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type, BOOL is_link) +LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type)  { -	// Bypassing LLViewerFolderType::lookup() since -	// we aren't using different system folder icons -	if (is_link) -	{ -		if (preferred_type == LLFolderType::FT_OUTFIT) -			return LLUI::getUIImage("Inv_LookFolderClosed_Link"); -		else  -			return LLUI::getUIImage("Inv_FolderClosed_Link"); -	} - -	switch (preferred_type) -	{ -	case LLFolderType::FT_OUTFIT: -		return LLUI::getUIImage("Inv_LookFolderClosed"); -	case LLFolderType::FT_LOST_AND_FOUND: -		return LLUI::getUIImage("Inv_LostClosed"); -	case LLFolderType::FT_TRASH: -		return LLUI::getUIImage("Inv_TrashClosed"); -	case LLFolderType::FT_NONE: -		return LLUI::getUIImage("Inv_FolderClosed"); -	default: -		return LLUI::getUIImage("Inv_SysClosed"); -	} +	return LLUI::getUIImage(LLViewerFolderType::lookupIconName(preferred_type, FALSE));  }  LLUIImagePtr LLFolderBridge::getOpenIcon() const  { -	// Bypassing LLViewerFolderType::lookup() since -	// we aren't using different system folder icons -	if (isLink()) -	{ -		if (getPreferredType() == LLFolderType::FT_OUTFIT) -			return LLUI::getUIImage("Inv_LookFolderOpen_Link"); -		else  -			return LLUI::getUIImage("Inv_FolderOpen_Link"); -	} - -	switch (getPreferredType()) -	{ -	case LLFolderType::FT_OUTFIT: -		return LLUI::getUIImage("Inv_LookFolderOpen"); -	case LLFolderType::FT_LOST_AND_FOUND: -		return LLUI::getUIImage("Inv_LostOpen"); -	case LLFolderType::FT_TRASH: -		return LLUI::getUIImage("Inv_TrashOpen"); -	case LLFolderType::FT_NONE: -		return LLUI::getUIImage("Inv_FolderOpen"); -	default: -		return LLUI::getUIImage("Inv_SysOpen"); -	} +	return LLUI::getUIImage(LLViewerFolderType::lookupIconName(getPreferredType(), TRUE));  } @@ -3176,7 +3127,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,  LLUIImagePtr LLTextureBridge::getIcon() const  { -	return LLInventoryIcon::getIcon(LLAssetType::AT_TEXTURE, mInvType, mIsLink); +	return LLInventoryIcon::getIcon(LLAssetType::AT_TEXTURE, mInvType);  }  void LLTextureBridge::openItem() @@ -3328,7 +3279,7 @@ LLLandmarkBridge::LLLandmarkBridge(LLInventoryPanel* inventory,  LLUIImagePtr LLLandmarkBridge::getIcon() const  { -	return LLInventoryIcon::getIcon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, mIsLink, mVisited, FALSE); +	return LLInventoryIcon::getIcon(LLAssetType::AT_LANDMARK, LLInventoryType::IT_LANDMARK, mVisited, FALSE);  }  void LLLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags) @@ -3520,7 +3471,7 @@ LLUIImagePtr LLCallingCardBridge::getIcon() const  	{  		online = LLAvatarTracker::instance().isBuddyOnline(item->getCreatorUUID());  	} -	return LLInventoryIcon::getIcon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, mIsLink, online, FALSE); +	return LLInventoryIcon::getIcon(LLAssetType::AT_CALLINGCARD, LLInventoryType::IT_CALLINGCARD, online, FALSE);  }  std::string LLCallingCardBridge::getLabelSuffix() const @@ -3959,7 +3910,7 @@ LLObjectBridge::LLObjectBridge(LLInventoryPanel* inventory,  LLUIImagePtr LLObjectBridge::getIcon() const  { -	return LLInventoryIcon::getIcon(LLAssetType::AT_OBJECT, mInvType, mIsLink, mAttachPt, mIsMultiObject); +	return LLInventoryIcon::getIcon(LLAssetType::AT_OBJECT, mInvType, mAttachPt, mIsMultiObject);  }  LLInventoryObject* LLObjectBridge::getObject() const @@ -4426,7 +4377,7 @@ std::string LLWearableBridge::getLabelSuffix() const  LLUIImagePtr LLWearableBridge::getIcon() const  { -	return LLInventoryIcon::getIcon(mAssetType, mInvType, mIsLink, mWearableType, FALSE); +	return LLInventoryIcon::getIcon(mAssetType, mInvType, mWearableType, FALSE);  }  // virtual @@ -4851,7 +4802,7 @@ LLUIImagePtr LLLinkFolderBridge::getIcon() const  			}  		}  	} -	return LLFolderBridge::getIcon(folder_type, TRUE); +	return LLFolderBridge::getIcon(folder_type);  }  void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags) diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index a342a2da14..757808eb93 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -123,6 +123,7 @@ public:  							EDragAndDropType cargo_type,  							void* cargo_data) { return FALSE; }  	virtual LLInventoryType::EType getInventoryType() const { return mInvType; } +	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }  	//--------------------------------------------------------------------  	// Convenience functions for adding various common menu options. @@ -245,7 +246,7 @@ public:  	virtual LLFolderType::EType getPreferredType() const;  	virtual LLUIImagePtr getIcon() const;  	virtual LLUIImagePtr getOpenIcon() const; -	static LLUIImagePtr getIcon(LLFolderType::EType preferred_type, BOOL is_link = FALSE); +	static LLUIImagePtr getIcon(LLFolderType::EType preferred_type);  	virtual BOOL renameItem(const std::string& new_name); @@ -471,6 +472,7 @@ public:  	virtual void	buildContextMenu(LLMenuGL& menu, U32 flags);  	virtual std::string getLabelSuffix() const;  	virtual BOOL renameItem(const std::string& new_name); +	virtual LLWearableType::EType getWearableType() const { return mWearableType; }  	static void		onWearOnAvatar( void* userdata );	// Access to wearOnAvatar() from menu  	static BOOL		canWearOnAvatar( void* userdata ); diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index c90919e8fd..6e829f2dc2 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -49,6 +49,7 @@  LLInventoryFilter::FilterOps::FilterOps() :  	mFilterObjectTypes(0xffffffffffffffffULL),  	mFilterCategoryTypes(0xffffffffffffffffULL), +	mFilterWearableTypes(0xffffffffffffffffULL),  	mMinDate(time_min()),  	mMaxDate(time_max()),  	mHoursAgo(0), @@ -139,8 +140,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con  			return FALSE;  		}  	} -	// -	////////////////////////////////////////////////////////////////////////////////  	//////////////////////////////////////////////////////////////////////////////// @@ -164,8 +163,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con  		if ((1LL << cat->getPreferredType() & mFilterOps.mFilterCategoryTypes) == U64(0))  			return FALSE;  	} -	// -	////////////////////////////////////////////////////////////////////////////////  	//////////////////////////////////////////////////////////////////////////////// @@ -178,8 +175,6 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con  		if (object->getLinkedUUID() != mFilterOps.mFilterUUID)  			return FALSE;  	} -	// -	////////////////////////////////////////////////////////////////////////////////  	//////////////////////////////////////////////////////////////////////////////// @@ -201,8 +196,18 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con  			listener->getCreationDate() > mFilterOps.mMaxDate)  			return FALSE;  	} -	// +  	//////////////////////////////////////////////////////////////////////////////// +	// FILTERTYPE_WEARABLE +	// Pass if this item is a wearable of the appropriate type +	if (filterTypes & FILTERTYPE_WEARABLE) +	{ +		LLWearableType::EType type = listener->getWearableType(); +		if ((0x1LL << type & mFilterOps.mFilterWearableTypes) == 0) +		{ +			return FALSE; +		} +	}  	return TRUE;  } @@ -238,6 +243,8 @@ std::string::size_type LLInventoryFilter::getStringMatchOffset() const  BOOL LLInventoryFilter::isNotDefault() const  {  	return mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes  +		|| mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes  +		|| mFilterOps.mFilterWearableTypes != mDefaultFilterOps.mFilterWearableTypes   		|| mFilterOps.mFilterTypes != FILTERTYPE_OBJECT  		|| mFilterSubString.size()   		|| mFilterOps.mPermissions != mDefaultFilterOps.mPermissions @@ -249,6 +256,8 @@ BOOL LLInventoryFilter::isNotDefault() const  BOOL LLInventoryFilter::isActive() const  {  	return mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL +		|| mFilterOps.mFilterCategoryTypes != 0xffffffffffffffffULL +		|| mFilterOps.mFilterWearableTypes != 0xffffffffffffffffULL  		|| mFilterOps.mFilterTypes != FILTERTYPE_OBJECT  		|| mFilterSubString.size()   		|| mFilterOps.mPermissions != PERM_NONE  @@ -322,7 +331,35 @@ void LLInventoryFilter::setFilterCategoryTypes(U64 types)  			setModified(FILTER_MORE_RESTRICTIVE);  		}  	} -	mFilterOps.mFilterTypes |= FILTERTYPE_CATEGORY; +	mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT; +} + +void LLInventoryFilter::setFilterWearableTypes(U64 types) +{ +	if (mFilterOps.mFilterWearableTypes != types) +	{ +		// keep current items only if no type bits getting turned off +		BOOL fewer_bits_set = (mFilterOps.mFilterWearableTypes & ~types); +		BOOL more_bits_set = (~mFilterOps.mFilterWearableTypes & types); + +		mFilterOps.mFilterWearableTypes = types; +		if (more_bits_set && fewer_bits_set) +		{ +			// neither less or more restrive, both simultaneously +			// so we need to filter from scratch +			setModified(FILTER_RESTART); +		} +		else if (more_bits_set) +		{ +			// target is only one of all requested types so more type bits == less restrictive +			setModified(FILTER_LESS_RESTRICTIVE); +		} +		else if (fewer_bits_set) +		{ +			setModified(FILTER_MORE_RESTRICTIVE); +		} +	} +	mFilterOps.mFilterTypes |= FILTERTYPE_WEARABLE;  }  void LLInventoryFilter::setFilterUUID(const LLUUID& object_id) diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h index 3ef51baefc..f740a6b333 100644 --- a/indra/newview/llinventoryfilter.h +++ b/indra/newview/llinventoryfilter.h @@ -59,10 +59,11 @@ public:  	enum EFilterType  	{  		FILTERTYPE_NONE = 0, -		FILTERTYPE_OBJECT = 1,		// normal default search-by-object-type -		FILTERTYPE_CATEGORY = 2,	// search by folder type -		FILTERTYPE_UUID	= 4,		// find the object with UUID and any links to it -		FILTERTYPE_DATE = 8			// search by date range +		FILTERTYPE_OBJECT = 0x1 << 0,	// normal default search-by-object-type +		FILTERTYPE_CATEGORY = 0x1 << 1,	// search by folder type +		FILTERTYPE_UUID	= 0x1 << 2,		// find the object with UUID and any links to it +		FILTERTYPE_DATE = 0x1 << 3,		// search by date range +		FILTERTYPE_WEARABLE = 0x1 << 4	// search by wearable type  	};  	// REFACTOR: Change this to an enum. @@ -81,6 +82,7 @@ public:  	BOOL 				isFilterObjectTypesWith(LLInventoryType::EType t) const;  	void 				setFilterCategoryTypes(U64 types);  	void 				setFilterUUID(const LLUUID &object_id); +	void				setFilterWearableTypes(U64 types);  	void 				setFilterSubString(const std::string& string);  	const std::string& 	getFilterSubString(BOOL trim = FALSE) const; @@ -168,6 +170,7 @@ private:  		U32 			mFilterTypes;  		U64				mFilterObjectTypes; // For _OBJECT +		U64				mFilterWearableTypes;  		U64				mFilterCategoryTypes; // For _CATEGORY  		LLUUID      	mFilterUUID; // for UUID diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index ca6cede7e9..c86d463a08 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -309,6 +309,11 @@ BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)  BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id)  { +	if (!model) +	{ +		return FALSE; +	} +  	LLViewerInventoryCategory* cat = model->getCategory(id);  	if (cat && !LLFolderType::lookupIsProtectedType(cat->getPreferredType()) && diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index c82ebd1439..93c56e1b8a 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -271,6 +271,32 @@ public:  //  //  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +class LLFindByMask : public LLInventoryCollectFunctor +{ +public: +	LLFindByMask(U64 mask) +		: mFilterMask(mask) +	{} + +	virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item) +	{ +		if(item && (mFilterMask & (1LL << item->getInventoryType())) ) +		{ +			return true; +		} + +		return false; +	} + +private: +	U64 mFilterMask; +}; + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// Class LLFindNonLinksByMask +// +// +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  class LLFindNonLinksByMask : public LLInventoryCollectFunctor  {  public: diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp index 2fb55f4c1f..3090371a73 100644 --- a/indra/newview/llinventoryicon.cpp +++ b/indra/newview/llinventoryicon.cpp @@ -40,13 +40,10 @@  struct IconEntry : public LLDictionaryEntry  { -	IconEntry(const std::string &item_name, -			  const std::string &link_name) +	IconEntry(const std::string &item_name)  		: -		LLDictionaryEntry(item_name), -		mLinkName(link_name) +		LLDictionaryEntry(item_name)  	{} -	const std::string mLinkName;  };  class LLIconDictionary : public LLSingleton<LLIconDictionary>, @@ -58,52 +55,51 @@ public:  LLIconDictionary::LLIconDictionary()  { -	addEntry(LLInventoryIcon::ICONNAME_TEXTURE, 				new IconEntry("Inv_Texture", 		"Inv_Texture_Link")); -	addEntry(LLInventoryIcon::ICONNAME_SOUND, 					new IconEntry("Inv_Texture", 		"Inv_Texture_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_ONLINE, 		new IconEntry("Inv_CallingCard", 	"Inv_CallingCard_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_OFFLINE, 	new IconEntry("Inv_CallingCard", 	"Inv_CallingCard_Link")); -	addEntry(LLInventoryIcon::ICONNAME_LANDMARK, 				new IconEntry("Inv_Landmark", 		"Inv_Landmark_Link")); -	addEntry(LLInventoryIcon::ICONNAME_LANDMARK_VISITED, 		new IconEntry("Inv_Landmark", 		"Inv_Landmark_Link")); -	addEntry(LLInventoryIcon::ICONNAME_SCRIPT, 					new IconEntry("Inv_Script", 		"Inv_Script_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING, 				new IconEntry("Inv_Clothing", 		"Inv_Clothing_Link")); -	addEntry(LLInventoryIcon::ICONNAME_OBJECT, 					new IconEntry("Inv_Object", 		"Inv_Object_Link")); -	addEntry(LLInventoryIcon::ICONNAME_OBJECT_MULTI, 			new IconEntry("Inv_Object_Multi", 	"Inv_Object_Multi_Link")); -	addEntry(LLInventoryIcon::ICONNAME_NOTECARD, 				new IconEntry("Inv_Notecard", 		"Inv_Notecard_Link")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART, 				new IconEntry("Inv_Skin", 			"Inv_Skin_Link")); -	addEntry(LLInventoryIcon::ICONNAME_SNAPSHOT, 				new IconEntry("Inv_Snapshot", 		"Inv_Snapshot_Link")); +	addEntry(LLInventoryIcon::ICONNAME_TEXTURE, 				new IconEntry("Inv_Texture")); +	addEntry(LLInventoryIcon::ICONNAME_SOUND, 					new IconEntry("Inv_Texture")); +	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_ONLINE, 		new IconEntry("Inv_CallingCard")); +	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_OFFLINE, 	new IconEntry("Inv_CallingCard")); +	addEntry(LLInventoryIcon::ICONNAME_LANDMARK, 				new IconEntry("Inv_Landmark")); +	addEntry(LLInventoryIcon::ICONNAME_LANDMARK_VISITED, 		new IconEntry("Inv_Landmark")); +	addEntry(LLInventoryIcon::ICONNAME_SCRIPT, 					new IconEntry("Inv_Script")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING, 				new IconEntry("Inv_Clothing")); +	addEntry(LLInventoryIcon::ICONNAME_OBJECT, 					new IconEntry("Inv_Object")); +	addEntry(LLInventoryIcon::ICONNAME_OBJECT_MULTI, 			new IconEntry("Inv_Object_Multi")); +	addEntry(LLInventoryIcon::ICONNAME_NOTECARD, 				new IconEntry("Inv_Notecard")); +	addEntry(LLInventoryIcon::ICONNAME_BODYPART, 				new IconEntry("Inv_Skin")); +	addEntry(LLInventoryIcon::ICONNAME_SNAPSHOT, 				new IconEntry("Inv_Snapshot")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SHAPE, 			new IconEntry("Inv_BodyShape", 		"Inv_BodyShape_Link")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SKIN, 			new IconEntry("Inv_Skin", 			"Inv_Skin_Link")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART_HAIR, 			new IconEntry("Inv_Hair", 			"Inv_Hair_Link")); -	addEntry(LLInventoryIcon::ICONNAME_BODYPART_EYES, 			new IconEntry("Inv_Eye", 			"Inv_Eye_Link")); +	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SHAPE, 			new IconEntry("Inv_BodyShape")); +	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SKIN, 			new IconEntry("Inv_Skin")); +	addEntry(LLInventoryIcon::ICONNAME_BODYPART_HAIR, 			new IconEntry("Inv_Hair")); +	addEntry(LLInventoryIcon::ICONNAME_BODYPART_EYES, 			new IconEntry("Inv_Eye")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, 			new IconEntry("Inv_Shirt", 			"Inv_Shirt_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PANTS, 			new IconEntry("Inv_Pants", 			"Inv_Pants_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHOES, 			new IconEntry("Inv_Shoe", 			"Inv_Shoe_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, 			new IconEntry("Inv_Socks", 			"Inv_Socks_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_JACKET, 		new IconEntry("Inv_Jacket", 		"Inv_Jacket_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, 		new IconEntry("Inv_Gloves", 		"Inv_Gloves_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, 	new IconEntry("Inv_Undershirt", 	"Inv_Undershirt_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, 	new IconEntry("Inv_Underpants", 	"Inv_Underpants_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, 			new IconEntry("Inv_Skirt", 			"Inv_Skirt_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, 			new IconEntry("Inv_Alpha", 			"Inv_Alpha_Link")); -	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, 		new IconEntry("Inv_Tattoo", 		"Inv_Tattoo_Link")); -	addEntry(LLInventoryIcon::ICONNAME_ANIMATION, 				new IconEntry("Inv_Animation", 		"Inv_Animation_Link")); -	addEntry(LLInventoryIcon::ICONNAME_GESTURE, 				new IconEntry("Inv_Gesture", 		"Inv_Gesture_Link")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, 			new IconEntry("Inv_Shirt")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PANTS, 			new IconEntry("Inv_Pants")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHOES, 			new IconEntry("Inv_Shoe")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, 			new IconEntry("Inv_Socks")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_JACKET, 		new IconEntry("Inv_Jacket")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, 		new IconEntry("Inv_Gloves")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, 	new IconEntry("Inv_Undershirt")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, 	new IconEntry("Inv_Underpants")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, 			new IconEntry("Inv_Skirt")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, 			new IconEntry("Inv_Alpha")); +	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, 		new IconEntry("Inv_Tattoo")); +	addEntry(LLInventoryIcon::ICONNAME_ANIMATION, 				new IconEntry("Inv_Animation")); +	addEntry(LLInventoryIcon::ICONNAME_GESTURE, 				new IconEntry("Inv_Gesture")); -	addEntry(LLInventoryIcon::ICONNAME_LINKITEM, 				new IconEntry("Inv_LinkItem", 		"Inv_LinkItem")); -	addEntry(LLInventoryIcon::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkItem", 		"Inv_LinkItem")); +	addEntry(LLInventoryIcon::ICONNAME_LINKITEM, 				new IconEntry("Inv_LinkItem")); +	addEntry(LLInventoryIcon::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkItem")); -	addEntry(LLInventoryIcon::ICONNAME_NONE, 					new IconEntry("NONE", 				"NONE")); +	addEntry(LLInventoryIcon::ICONNAME_NONE, 					new IconEntry("NONE"));  }  LLUIImagePtr LLInventoryIcon::getIcon(LLAssetType::EType asset_type,  									  LLInventoryType::EType inventory_type, -									  BOOL item_is_link,  									  U32 misc_flag,  									  BOOL item_is_multi)  { -	const std::string& icon_name = getIconName(asset_type, inventory_type, item_is_link, misc_flag, item_is_multi); +	const std::string& icon_name = getIconName(asset_type, inventory_type, misc_flag, item_is_multi);  	return LLUI::getUIImage(icon_name);  } @@ -114,7 +110,6 @@ LLUIImagePtr LLInventoryIcon::getIcon(EIconName idx)  const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,  												LLInventoryType::EType inventory_type, -												BOOL item_is_link,  												U32 misc_flag,  												BOOL item_is_multi)  { @@ -169,14 +164,13 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,  			break;  	} -	return getIconName(idx, item_is_link); +	return getIconName(idx);  } -const std::string& LLInventoryIcon::getIconName(EIconName idx, BOOL item_is_link) +const std::string& LLInventoryIcon::getIconName(EIconName idx)  {  	const IconEntry *entry = LLIconDictionary::instance().lookup(idx); -	if (item_is_link) return entry->mLinkName;  	return entry->mName;  } diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h index 4cb7a123c4..6e29012c4c 100644 --- a/indra/newview/llinventoryicon.h +++ b/indra/newview/llinventoryicon.h @@ -86,15 +86,12 @@ public:  	static const std::string& getIconName(LLAssetType::EType asset_type,  										  LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE, -										  BOOL item_is_link = FALSE,  										  U32 misc_flag = 0, // different meanings depending on item type  										  BOOL item_is_multi = FALSE); -	static const std::string& getIconName(EIconName idx,  -										  BOOL item_is_link = FALSE); +	static const std::string& getIconName(EIconName idx);  	static LLUIImagePtr getIcon(LLAssetType::EType asset_type,  								LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE, -								BOOL item_is_link = FALSE,  								U32 misc_flag = 0, // different meanings depending on item type  								BOOL item_is_multi = FALSE);  	static LLUIImagePtr getIcon(EIconName idx); diff --git a/indra/newview/llinventoryitemslist.cpp b/indra/newview/llinventoryitemslist.cpp index cd0e976a79..23ea786484 100644 --- a/indra/newview/llinventoryitemslist.cpp +++ b/indra/newview/llinventoryitemslist.cpp @@ -70,16 +70,20 @@ void LLPanelInventoryListItemBase::draw()  {  	if (getNeedsRefresh())  	{ -		updateItem(); +		if (mItem) +		{ +			updateItem(mItem->getName()); +		}  		setNeedsRefresh(false);  	}  	LLPanel::draw();  } -void LLPanelInventoryListItemBase::updateItem() +// virtual +void LLPanelInventoryListItemBase::updateItem(const std::string& name)  {  	setIconImage(mIconImage); -	setTitle(mItem->getName(), mHighlightedText); +	setTitle(name, mHighlightedText);  }  void LLPanelInventoryListItemBase::addWidgetToLeftSide(const std::string& name, bool show_widget/* = true*/) @@ -132,8 +136,11 @@ BOOL LLPanelInventoryListItemBase::postBuild()  	setIconCtrl(getChild<LLIconCtrl>("item_icon"));  	setTitleCtrl(getChild<LLTextBox>("item_name")); -	BOOL show_links = mForceNoLinksOnIcons ? FALSE : mItem->getIsLinkType(); -	mIconImage = LLInventoryIcon::getIcon(mItem->getType(), mItem->getInventoryType(), show_links, mItem->getFlags(), FALSE); +	if (mItem) +	{ +		mIconImage = LLInventoryIcon::getIcon(mItem->getType(), mItem->getInventoryType(), mItem->getFlags(), FALSE); +		updateItem(mItem->getName()); +	}  	setNeedsRefresh(true); @@ -162,6 +169,42 @@ void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask)  	LLPanel::onMouseLeave(x, y, mask);  } +const std::string& LLPanelInventoryListItemBase::getItemName() const +{ +	if (!mItem) +	{ +		return LLStringUtil::null; +	} +	return mItem->getName(); +} + +LLAssetType::EType LLPanelInventoryListItemBase::getType() const +{ +	if (!mItem) +	{ +		return LLAssetType::AT_NONE; +	} +	return mItem->getType(); +} + +LLWearableType::EType LLPanelInventoryListItemBase::getWearableType() const +{ +	if (!mItem) +	{ +		return LLWearableType::WT_NONE; +	} +	return mItem->getWearableType(); +} + +const std::string& LLPanelInventoryListItemBase::getDescription() const +{ +	if (!mItem) +	{ +		return LLStringUtil::null; +	} +	return mItem->getDescription(); +} +  S32 LLPanelInventoryListItemBase::notify(const LLSD& info)  {  	S32 rv = 0; @@ -169,7 +212,7 @@ S32 LLPanelInventoryListItemBase::notify(const LLSD& info)  	{  		mHighlightedText = info["match_filter"].asString(); -		std::string test(mItem->getName()); +		std::string test(mTitleCtrl->getText());  		LLStringUtil::toUpper(test);  		if(mHighlightedText.empty() || std::string::npos != test.find(mHighlightedText)) @@ -199,7 +242,6 @@ LLPanelInventoryListItemBase::LLPanelInventoryListItemBase(LLViewerInventoryItem  , mLeftWidgetsWidth(0)  , mRightWidgetsWidth(0)  , mNeedsRefresh(false) -, mForceNoLinksOnIcons(false)  {  } diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h index 2c60d38cb5..d6132717e8 100644 --- a/indra/newview/llinventoryitemslist.h +++ b/indra/newview/llinventoryitemslist.h @@ -122,16 +122,16 @@ public:  	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);  	/** Get the name of a corresponding inventory item */ -	const std::string& getItemName() const { return mItem->getName(); } +	const std::string& getItemName() const;  	/** Get the asset type of a corresponding inventory item */ -	LLAssetType::EType getType() const { return mItem->getType(); } +	LLAssetType::EType getType() const;  	/** Get the wearable type of a corresponding inventory item */ -	LLWearableType::EType getWearableType() const { return mItem->getWearableType(); } +	LLWearableType::EType getWearableType() const;  	/** Get the description of a corresponding inventory item */ -	const std::string& getDescription() const { return mItem->getDescription(); } +	const std::string& getDescription() const;  	/** Get the associated inventory item */  	LLViewerInventoryItem* getItem() const { return mItem; } @@ -152,7 +152,7 @@ protected:  	/**  	 * Called after inventory item was updated, update panel widgets to reflect inventory changes.  	 */ -	virtual void updateItem(); +	virtual void updateItem(const std::string& name);  	/** setter for mIconCtrl */  	void setIconCtrl(LLIconCtrl* icon) { mIconCtrl = icon; } @@ -182,9 +182,6 @@ protected:  	LLViewerInventoryItem* mItem; -	// force not showing link icon on item's icon -	bool mForceNoLinksOnIcons; -  private:  	/** reshape left side widgets diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 6fc5804a48..15760bf155 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -721,8 +721,20 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item)  			// Valid UUID; set the item UUID and rename it  			new_item->setCreator(id);  			std::string avatar_name; -			// Fetch the currect name -			gCacheName->get(id, FALSE, boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(), _1, _2, _3)); + +			if (gCacheName->getFullName(id, avatar_name)) +			{ +				new_item->rename(avatar_name); +				mask |= LLInventoryObserver::LABEL; +			} +			else +			{ +				// Fetch the current name +				gCacheName->get(id, FALSE, +					boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(), +					_1, _2, _3)); +			} +  		}  	}  	else if (new_item->getType() == LLAssetType::AT_GESTURE) diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp index b4f0947b2c..ce44e37017 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.cpp +++ b/indra/newview/llinventorymodelbackgroundfetch.cpp @@ -33,15 +33,14 @@  #include "llviewerprecompiledheaders.h"  #include "llinventorymodelbackgroundfetch.h" -// Seraph clean this up  #include "llagent.h" +#include "llappviewer.h" +#include "llcallbacklist.h"  #include "llinventorypanel.h"  #include "llviewercontrol.h"  #include "llviewermessage.h" -#include "llviewerwindow.h" -#include "llappviewer.h"  #include "llviewerregion.h" -#include "llcallbacklist.h" +#include "llviewerwindow.h"  const F32 MAX_TIME_FOR_SINGLE_FETCH = 10.f;  const S32 MAX_FETCH_RETRIES = 10; @@ -63,47 +62,47 @@ LLInventoryModelBackgroundFetch::~LLInventoryModelBackgroundFetch()  {  } -bool LLInventoryModelBackgroundFetch::isBulkFetchProcessingComplete() +bool LLInventoryModelBackgroundFetch::isBulkFetchProcessingComplete() const  {  	return mFetchQueue.empty() && mBulkFetchCount<=0;  } -bool LLInventoryModelBackgroundFetch::libraryFetchStarted() +bool LLInventoryModelBackgroundFetch::libraryFetchStarted() const  {  	return mRecursiveLibraryFetchStarted;  } -bool LLInventoryModelBackgroundFetch::libraryFetchCompleted() +bool LLInventoryModelBackgroundFetch::libraryFetchCompleted() const  {  	return libraryFetchStarted() && fetchQueueContainsNoDescendentsOf(gInventory.getLibraryRootFolderID());  } -bool LLInventoryModelBackgroundFetch::libraryFetchInProgress() +bool LLInventoryModelBackgroundFetch::libraryFetchInProgress() const  {  	return libraryFetchStarted() && !libraryFetchCompleted();  } -bool LLInventoryModelBackgroundFetch::inventoryFetchStarted() +bool LLInventoryModelBackgroundFetch::inventoryFetchStarted() const  {  	return mRecursiveInventoryFetchStarted;  } -bool LLInventoryModelBackgroundFetch::inventoryFetchCompleted() +bool LLInventoryModelBackgroundFetch::inventoryFetchCompleted() const  {  	return inventoryFetchStarted() && fetchQueueContainsNoDescendentsOf(gInventory.getRootFolderID());  } -bool LLInventoryModelBackgroundFetch::inventoryFetchInProgress() +bool LLInventoryModelBackgroundFetch::inventoryFetchInProgress() const  {  	return inventoryFetchStarted() && !inventoryFetchCompleted();  } -bool LLInventoryModelBackgroundFetch::isEverythingFetched() +bool LLInventoryModelBackgroundFetch::isEverythingFetched() const  {  	return mAllFoldersFetched;  } -BOOL LLInventoryModelBackgroundFetch::backgroundFetchActive() +BOOL LLInventoryModelBackgroundFetch::backgroundFetchActive() const  {  	return mBackgroundFetchActive;  } @@ -132,7 +131,7 @@ void LLInventoryModelBackgroundFetch::start(const LLUUID& cat_id, BOOL recursive  		}  		else  		{ -			// specific folder requests go to front of queue +			// Specific folder requests go to front of queue.  			if (mFetchQueue.empty() || mFetchQueue.front().mCatUUID != cat_id)  			{  				mFetchQueue.push_front(FetchQueueInfo(cat_id, recursive)); @@ -187,7 +186,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  {  	if (mBackgroundFetchActive && gAgent.getRegion())  	{ -		//If we'll be using the capability, we'll be sending batches and the background thing isn't as important. +		// If we'll be using the capability, we'll be sending batches and the background thing isn't as important.  		std::string url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents");     		if (!url.empty())   		{ @@ -195,8 +194,12 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  			return;  		} -		//DEPRECATED OLD CODE FOLLOWS. -		// no more categories to fetch, stop fetch process +#if 1 +		//-------------------------------------------------------------------------------- +		// DEPRECATED OLD CODE +		// + +		// No more categories to fetch, stop fetch process.  		if (mFetchQueue.empty())  		{  			llinfos << "Inventory fetch completed" << llendl; @@ -209,11 +212,11 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  		F32 slow_fetch_time = lerp(mMinTimeBetweenFetches, mMaxTimeBetweenFetches, 0.5f);  		if (mTimelyFetchPending && mFetchTimer.getElapsedTimeF32() > slow_fetch_time)  		{ -			// double timeouts on failure +			// Double timeouts on failure.  			mMinTimeBetweenFetches = llmin(mMinTimeBetweenFetches * 2.f, 10.f);  			mMaxTimeBetweenFetches = llmin(mMaxTimeBetweenFetches * 2.f, 120.f);  			llinfos << "Inventory fetch times grown to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << llendl; -			// fetch is no longer considered "timely" although we will wait for full time-out +			// fetch is no longer considered "timely" although we will wait for full time-out.  			mTimelyFetchPending = FALSE;  		} @@ -226,14 +229,14 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  			if(gDisconnected)  			{ -				// just bail if we are disconnected. +				// Just bail if we are disconnected.  				break;  			}  			const FetchQueueInfo info = mFetchQueue.front();  			LLViewerInventoryCategory* cat = gInventory.getCategory(info.mCatUUID); -			// category has been deleted, remove from queue. +			// Category has been deleted, remove from queue.  			if (!cat)  			{  				mFetchQueue.pop_front(); @@ -243,8 +246,8 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  			if (mFetchTimer.getElapsedTimeF32() > mMinTimeBetweenFetches &&   				LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion())  			{ -				// category exists but has no children yet, fetch the descendants -				// for now, just request every time and rely on retry timer to throttle +				// Category exists but has no children yet, fetch the descendants +				// for now, just request every time and rely on retry timer to throttle.  				if (cat->fetch())  				{  					mFetchTimer.reset(); @@ -258,13 +261,13 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  					break;  				}  			} -			// do I have all my children? +			// Do I have all my children?  			else if (gInventory.isCategoryComplete(info.mCatUUID))  			{ -				// finished with this category, remove from queue +				// Finished with this category, remove from queue.  				mFetchQueue.pop_front(); -				// add all children to queue +				// Add all children to queue.  				LLInventoryModel::cat_array_t* categories;  				LLInventoryModel::item_array_t* items;  				gInventory.getDirectDescendentsOf(cat->getUUID(), categories, items); @@ -275,10 +278,10 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  					mFetchQueue.push_back(FetchQueueInfo((*it)->getUUID(),info.mRecursive));  				} -				// we received a response in less than the fast time +				// We received a response in less than the fast time.  				if (mTimelyFetchPending && mFetchTimer.getElapsedTimeF32() < fast_fetch_time)  				{ -					// shrink timeouts based on success +					// Shrink timeouts based on success.  					mMinTimeBetweenFetches = llmax(mMinTimeBetweenFetches * 0.8f, 0.3f);  					mMaxTimeBetweenFetches = llmax(mMaxTimeBetweenFetches * 0.8f, 10.f);  					//llinfos << "Inventory fetch times shrunk to (" << mMinTimeBetweenFetches << ", " << mMaxTimeBetweenFetches << ")" << llendl; @@ -289,8 +292,8 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  			}  			else if (mFetchTimer.getElapsedTimeF32() > mMaxTimeBetweenFetches)  			{ -				// received first packet, but our num descendants does not match db's num descendants -				// so try again later +				// Received first packet, but our num descendants does not match db's num descendants +				// so try again later.  				mFetchQueue.pop_front();  				if (mNumFetchRetries++ < MAX_FETCH_RETRIES) @@ -303,9 +306,14 @@ void LLInventoryModelBackgroundFetch::backgroundFetch()  				break;  			} -			// not enough time has elapsed to do a new fetch +			// Not enough time has elapsed to do a new fetch  			break;  		} + +		// +		// DEPRECATED OLD CODE +		//-------------------------------------------------------------------------------- +#endif  	}  } @@ -333,10 +341,10 @@ protected:  	BOOL getIsRecursive(const LLUUID& cat_id) const;  private:  	LLSD mRequestSD; -	uuid_vec_t mRecursiveCatUUIDs; // Hack for storing away which cat fetches are recursive. +	uuid_vec_t mRecursiveCatUUIDs; // hack for storing away which cat fetches are recursive  }; -//If we get back a normal response, handle it here +// If we get back a normal response, handle it here.  void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)  {  	LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance(); @@ -428,7 +436,7 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)  				gInventory.updateItem(titem);  			} -			// set version and descendentcount according to message. +			// Set version and descendentcount according to message.  			LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id);  			if(cat)  			{ @@ -448,7 +456,7 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)  		{	  			LLSD folder_sd = *folder_it; -			//These folders failed on the dataserver.  We probably don't want to retry them. +			// These folders failed on the dataserver.  We probably don't want to retry them.  			llinfos << "Folder " << folder_sd["folder_id"].asString()   					<< "Error: " << folder_sd["error"].asString() << llendl;  		} @@ -465,7 +473,7 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)  	gInventory.notifyObservers("fetchDescendents");  } -//If we get back an error (not found, etc...), handle it here +// If we get back an error (not found, etc...), handle it here.  void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::string& reason)  {  	LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance(); @@ -475,7 +483,7 @@ void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::str  	fetcher->incrBulkFetch(-1); -	if (status==499) // Timed out. +	if (status==499) // timed out  	{  		for(LLSD::array_const_iterator folder_it = mRequestSD["folders"].beginArray();  			folder_it != mRequestSD["folders"].endArray(); @@ -502,7 +510,8 @@ BOOL LLInventoryModelFetchDescendentsResponder::getIsRecursive(const LLUUID& cat  	return (std::find(mRecursiveCatUUIDs.begin(),mRecursiveCatUUIDs.end(), cat_id) != mRecursiveCatUUIDs.end());  } -//static   Bundle up a bunch of requests to send all at once. +// Bundle up a bunch of requests to send all at once. +// static     void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)  {  	//Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped. @@ -521,7 +530,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)  		(mBulkFetchCount > max_concurrent_fetches) ||  		(mFetchTimer.getElapsedTimeF32() < mMinTimeBetweenFetches))  	{ -		return; // just bail if we are disconnected. +		return; // just bail if we are disconnected  	}	  	U32 folder_count=0; diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h index c1e37eda8f..04f96586d7 100644 --- a/indra/newview/llinventorymodelbackgroundfetch.h +++ b/indra/newview/llinventorymodelbackgroundfetch.h @@ -33,39 +33,15 @@  #ifndef LL_LLINVENTORYMODELBACKGROUNDFETCH_H  #define LL_LLINVENTORYMODELBACKGROUNDFETCH_H -// Seraph clean this up -#include "llassettype.h" -#include "llfoldertype.h" -#include "lldarray.h" -#include "llframetimer.h" -#include "llhttpclient.h" +#include "llsingleton.h"  #include "lluuid.h" -#include "llpermissionsflags.h" -#include "llstring.h" -#include <map> -#include <set> -#include <string> -#include <vector> - -// Seraph clean this up -class LLInventoryObserver; -class LLInventoryObject; -class LLInventoryItem; -class LLInventoryCategory; -class LLViewerInventoryItem; -class LLViewerInventoryCategory; -class LLViewerInventoryItem; -class LLViewerInventoryCategory; -class LLMessageSystem; -class LLInventoryCollectFunctor; -  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  // Class LLInventoryModelBackgroundFetch  // -// This class handles background fetch. +// This class handles background fetches, which are fetches of +// inventory folder.  Fetches can be recursive or not.  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -  class LLInventoryModelBackgroundFetch : public LLSingleton<LLInventoryModelBackgroundFetch>  {  	friend class LLInventoryModelFetchDescendentsResponder; @@ -75,48 +51,37 @@ public:  	~LLInventoryModelBackgroundFetch();  	// Start and stop background breadth-first fetching of inventory contents. -	// This gets triggered when performing a filter-search +	// This gets triggered when performing a filter-search.  	void start(const LLUUID& cat_id = LLUUID::null, BOOL recursive = TRUE); -	BOOL backgroundFetchActive(); -	bool isEverythingFetched(); -	void incrBulkFetch(S16 fetching); -	void stopBackgroundFetch(); // stop fetch process -	bool isBulkFetchProcessingComplete(); -	// Add categories to a list to be fetched in bulk. -	void bulkFetch(std::string url); +	BOOL backgroundFetchActive() const; +	bool isEverythingFetched() const; // completing the fetch once per session should be sufficient -	bool libraryFetchStarted(); -	bool libraryFetchCompleted(); -	bool libraryFetchInProgress(); +	bool libraryFetchStarted() const; +	bool libraryFetchCompleted() const; +	bool libraryFetchInProgress() const; -	bool inventoryFetchStarted(); -	bool inventoryFetchCompleted(); -	bool inventoryFetchInProgress(); -    void findLostItems(); +	bool inventoryFetchStarted() const; +	bool inventoryFetchCompleted() const; +	bool inventoryFetchInProgress() const; -	void setAllFoldersFetched(); +    void findLostItems();	 +protected: +	void incrBulkFetch(S16 fetching); +	bool isBulkFetchProcessingComplete() const; +	void bulkFetch(std::string url); -	static void backgroundFetchCB(void*); // background fetch idle function  	void backgroundFetch(); -	 -	struct FetchQueueInfo -	{ -		FetchQueueInfo(const LLUUID& id, BOOL recursive) : -			mCatUUID(id), mRecursive(recursive) -		{ -		} -		LLUUID mCatUUID; -		BOOL mRecursive; -	}; -protected: +	static void backgroundFetchCB(void*); // background fetch idle function +	void stopBackgroundFetch(); // stop fetch process + +	void setAllFoldersFetched();  	bool fetchQueueContainsNoDescendentsOf(const LLUUID& cat_id) const;  private:   	BOOL mRecursiveInventoryFetchStarted;  	BOOL mRecursiveLibraryFetchStarted;  	BOOL mAllFoldersFetched; -	// completing the fetch once per session should be sufficient  	BOOL mBackgroundFetchActive;  	S16 mBulkFetchCount;  	BOOL mTimelyFetchPending; @@ -126,6 +91,15 @@ private:  	F32 mMinTimeBetweenFetches;  	F32 mMaxTimeBetweenFetches; +	struct FetchQueueInfo +	{ +		FetchQueueInfo(const LLUUID& id, BOOL recursive) : +			mCatUUID(id), mRecursive(recursive) +		{ +		} +		LLUUID mCatUUID; +		BOOL mRecursive; +	};  	typedef std::deque<FetchQueueInfo> fetch_queue_t;  	fetch_queue_t mFetchQueue;  }; diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index bb3f34dde2..83c57d5bb2 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -87,6 +87,7 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :  	mSortOrderSetting(p.sort_order_setting),  	mInventory(p.inventory),  	mAllowMultiSelect(p.allow_multi_select), +	mShowItemLinkOverlays(p.show_item_link_overlays),  	mViewsInitialized(false),  	mStartFolderString(p.start_folder),	  	mBuildDefaultHierarchy(true), @@ -188,6 +189,8 @@ LLInventoryPanel::~LLInventoryPanel()  		}  	} +	gIdleCallbacks.deleteFunction(onIdle, this); +  	// LLView destructor will take care of the sub-views.  	mInventory->removeObserver(mInventoryObserver);  	delete mInventoryObserver; @@ -223,6 +226,11 @@ void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask)  	getFilter()->setFilterPermissions(filter_perm_mask);  } +void LLInventoryPanel::setFilterWearableTypes(U64 types) +{ +	getFilter()->setFilterWearableTypes(types); +} +  void LLInventoryPanel::setFilterSubString(const std::string& string)  {  	getFilter()->setFilterSubString(string); @@ -522,6 +530,10 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)  				params.name = new_listener->getDisplayName();  				params.icon = new_listener->getIcon();  				params.icon_open = new_listener->getOpenIcon(); +				if (mShowItemLinkOverlays) // if false, then links show up just like normal items +				{ +					params.icon_overlay = LLUI::getUIImage("Inv_Link"); +				}  				params.root = mFolderRoot;  				params.listener = new_listener;  				params.tool_tip = params.name; @@ -560,6 +572,10 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)  				params.name = new_listener->getDisplayName();  				params.icon = new_listener->getIcon();  				params.icon_open = new_listener->getOpenIcon(); +				if (mShowItemLinkOverlays) // if false, then links show up just like normal items +				{ +					params.icon_overlay = LLUI::getUIImage("Inv_Link"); +				}  				params.creation_date = new_listener->getCreationDate();  				params.root = mFolderRoot;  				params.listener = new_listener; diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h index 4373cedf66..52e9ef799e 100644 --- a/indra/newview/llinventorypanel.h +++ b/indra/newview/llinventorypanel.h @@ -84,6 +84,7 @@ public:  		Optional<std::string>				sort_order_setting;  		Optional<LLInventoryModel*>			inventory;  		Optional<bool>						allow_multi_select; +		Optional<bool>						show_item_link_overlays;  		Optional<Filter>					filter;  		Optional<std::string>               start_folder; @@ -91,6 +92,7 @@ public:  		:	sort_order_setting("sort_order_setting"),  			inventory("", &gInventory),  			allow_multi_select("allow_multi_select", true), +			show_item_link_overlays("show_item_link_overlays", false),  			filter("filter"),  			start_folder("start_folder")  		{} @@ -136,6 +138,7 @@ public:  	U32 getFilterObjectTypes() const { return mFolderRoot->getFilterObjectTypes(); }  	void setFilterPermMask(PermissionMask filter_perm_mask);  	U32 getFilterPermMask() const { return mFolderRoot->getFilterPermissions(); } +	void setFilterWearableTypes(U64 filter);  	void setFilterSubString(const std::string& string);  	const std::string getFilterSubString() { return mFolderRoot->getFilterSubString(); }  	void setSinceLogoff(BOOL sl); @@ -177,6 +180,7 @@ protected:  	LLInventoryModel*			mInventory;  	LLInventoryObserver*		mInventoryObserver;  	BOOL 						mAllowMultiSelect; +	BOOL 						mShowItemLinkOverlays; // Shows link graphic over inventory item icons  	LLFolderView*				mFolderRoot;  	LLScrollContainer*			mScroller; diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp index 9e1dc3a4b0..c2a1923dfe 100644 --- a/indra/newview/lljoystickbutton.cpp +++ b/indra/newview/lljoystickbutton.cpp @@ -53,7 +53,6 @@  static LLDefaultChildRegistry::Register<LLJoystickAgentSlide> r1("joystick_slide");  static LLDefaultChildRegistry::Register<LLJoystickAgentTurn> r2("joystick_turn");  static LLDefaultChildRegistry::Register<LLJoystickCameraRotate> r3("joystick_rotate"); -static LLDefaultChildRegistry::Register<LLJoystickCameraZoom> r4("joystick_zoom");  static LLDefaultChildRegistry::Register<LLJoystickCameraTrack> r5("joystick_track"); @@ -647,155 +646,3 @@ void LLJoystickCameraTrack::onHeldDown()  		gAgentCamera.setPanDownKey(getOrbitRate());  	}  } - - - -//------------------------------------------------------------------------------- -// LLJoystickCameraZoom -//------------------------------------------------------------------------------- - -LLJoystickCameraZoom::LLJoystickCameraZoom(const LLJoystickCameraZoom::Params& p) -:	LLJoystick(p), -	mInTop( FALSE ), -	mInBottom( FALSE ), -	mPlusInImage(p.plus_image), -	mMinusInImage(p.minus_image) -{ -} - -BOOL LLJoystickCameraZoom::handleMouseDown(S32 x, S32 y, MASK mask) -{ -	BOOL handled = LLJoystick::handleMouseDown(x, y, mask); - -	if( handled ) -	{ -		if (mFirstMouse.mY > getRect().getHeight() / 2) -		{ -			mInitialQuadrant = JQ_UP; -		} -		else -		{ -			mInitialQuadrant = JQ_DOWN; -		} -	} -	return handled; -} - - -void LLJoystickCameraZoom::onHeldDown() -{ -	updateSlop(); - -	const F32 FAST_RATE = 2.5f; // two and a half times the normal rate - -	S32 dy = mLastMouse.mY - mFirstMouse.mY + mInitialOffset.mY; - -	if (dy > mVertSlopFar) -	{ -		// Zoom in fast -		gAgentCamera.unlockView(); -		gAgentCamera.setOrbitInKey(FAST_RATE); -	} -	else if (dy > mVertSlopNear) -	{ -		// Zoom in slow -		gAgentCamera.unlockView(); -		gAgentCamera.setOrbitInKey(getOrbitRate()); -	} -	else if (dy < -mVertSlopFar) -	{ -		// Zoom out fast -		gAgentCamera.unlockView(); -		gAgentCamera.setOrbitOutKey(FAST_RATE); -	} -	else if (dy < -mVertSlopNear) -	{ -		// Zoom out slow -		gAgentCamera.unlockView(); -		gAgentCamera.setOrbitOutKey(getOrbitRate()); -	} -} - -// Only used for drawing -void LLJoystickCameraZoom::setToggleState( BOOL top, BOOL bottom ) -{ -	mInTop = top; -	mInBottom = bottom; -} - -void LLJoystickCameraZoom::draw() -{ -	if( mInTop ) -	{ -		mPlusInImage->draw(0,0); -	} -	else -	if( mInBottom ) -	{ -		mMinusInImage->draw(0,0); -	} -	else -	{ -		getImageUnselected()->draw( 0, 0 ); -	} -} - -void LLJoystickCameraZoom::updateSlop() -{ -	mVertSlopNear = getRect().getHeight() / 4; -	mVertSlopFar = getRect().getHeight() / 2; - -	mHorizSlopNear = getRect().getWidth() / 4; -	mHorizSlopFar = getRect().getWidth() / 2; - -	// Compute initial mouse offset based on initial quadrant. -	// Place the mouse evenly between the near and far zones. -	switch (mInitialQuadrant) -	{ -	case JQ_ORIGIN: -		mInitialOffset.set(0, 0); -		break; - -	case JQ_UP: -		mInitialOffset.mX = 0; -		mInitialOffset.mY = (mVertSlopNear + mVertSlopFar) / 2; -		break; - -	case JQ_DOWN: -		mInitialOffset.mX = 0; -		mInitialOffset.mY = - (mVertSlopNear + mVertSlopFar) / 2; -		break; - -	case JQ_LEFT: -		mInitialOffset.mX = - (mHorizSlopNear + mHorizSlopFar) / 2; -		mInitialOffset.mY = 0; -		break; - -	case JQ_RIGHT: -		mInitialOffset.mX = (mHorizSlopNear + mHorizSlopFar) / 2; -		mInitialOffset.mY = 0; -		break; - -	default: -		llerrs << "LLJoystick::LLJoystick() - bad switch case" << llendl; -		break; -	} - -	return; -} - - -F32 LLJoystickCameraZoom::getOrbitRate() -{ -	F32 time = getElapsedHeldDownTime(); -	if( time < NUDGE_TIME ) -	{ -		F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME; -//		llinfos << "rate " << rate << " time " << time << llendl; -		return rate; -	} -	else -	{ -		return 1; -	} -} diff --git a/indra/newview/lljoystickbutton.h b/indra/newview/lljoystickbutton.h index 2b071a8999..1dd30036ab 100644 --- a/indra/newview/lljoystickbutton.h +++ b/indra/newview/lljoystickbutton.h @@ -183,44 +183,4 @@ public:  	virtual void	onHeldDown();  }; - -// Zoom the camera in and out -class LLJoystickCameraZoom -:	public LLJoystick -{ -public: -	struct Params  -	:	public LLInitParam::Block<Params, LLJoystick::Params> -	{ -		Optional<LLUIImage*>	plus_image; -		Optional<LLUIImage*>	minus_image; - -		Params() -		: plus_image ("plus_image", NULL), -		  minus_image ("minus_image", NULL) -		{ -			held_down_delay.seconds(0.0); -		} -	}; -	LLJoystickCameraZoom(const Params&); - -	virtual void	setToggleState( BOOL top, BOOL bottom ); - -	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask); -	virtual void	onHeldDown(); -	virtual void	draw(); - -protected: -	virtual void updateSlop(); -	F32				getOrbitRate(); - -protected: -	BOOL			mInTop; -	BOOL			mInBottom; -	LLUIImagePtr	mPlusInImage; -	LLUIImagePtr	mMinusInImage; -}; - - -  #endif  // LL_LLJOYSTICKBUTTON_H diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp index f1c13de8bb..1beaaf3cb4 100644 --- a/indra/newview/llnearbychat.cpp +++ b/indra/newview/llnearbychat.cpp @@ -49,7 +49,6 @@  #include "llchannelmanager.h"  #include "llagent.h" 			// gAgent -#include "llfloaterscriptdebug.h"  #include "llchathistory.h"  #include "llstylemap.h" @@ -163,25 +162,6 @@ std::string appendTime()  void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)  { -	if (chat.mChatType == CHAT_TYPE_DEBUG_MSG) -	{ -		if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE) -			return; -		if (gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)// show error in window //("ScriptErrorsAsChat")) -		{ - -			LLColor4 txt_color; - -			LLViewerChat::getChatColor(chat,txt_color); -			 -			LLFloaterScriptDebug::addScriptLine(chat.mText, -												chat.mFromName,  -												txt_color,  -												chat.mFromID); -			return; -		} -	} -  	LLChat& tmp_chat = const_cast<LLChat&>(chat);  	if(tmp_chat.mTimeStr.empty()) diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp index 9824517ed1..1fadb126e4 100644 --- a/indra/newview/llnearbychathandler.cpp +++ b/indra/newview/llnearbychathandler.cpp @@ -32,10 +32,12 @@  #include "llviewerprecompiledheaders.h" +#include "llagentdata.h" // for gAgentID  #include "llnearbychathandler.h"  #include "llbottomtray.h"  #include "llchatitemscontainerctrl.h" +#include "llfloaterscriptdebug.h"  #include "llnearbychat.h"  #include "llrecentpeople.h" @@ -287,7 +289,7 @@ void LLNearbyChatScreenChannel::showToastsBottom()  		toast_rect.setLeftTopAndSize(getRect().mLeft , bottom + toast_rect.getHeight(), toast_rect.getWidth() ,toast_rect.getHeight());  		toast->setRect(toast_rect); -		bottom += toast_rect.getHeight() + margin; +		bottom += toast_rect.getHeight() - toast->getTopPad() + margin;  	}  	// use reverse order to provide correct z-order and avoid toast blinking @@ -358,6 +360,36 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args)  		//if(tmp_chat.mFromName.empty() && tmp_chat.mFromID!= LLUUID::null)  		//	tmp_chat.mFromName = tmp_chat.mFromID.asString();  	} + +	// don't show toast and add message to chat history on receive debug message +	// with disabled setting showing script errors or enabled setting to show script +	// errors in separate window. +	if (chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG) +	{ +		if(gSavedSettings.getBOOL("ShowScriptErrors") == FALSE) +			return; + +		// don't process debug messages from not owned objects, see EXT-7762 +		if (gAgentID != chat_msg.mOwnerID) +		{ +			return; +		} + +		if (gSavedSettings.getS32("ShowScriptErrorsLocation")== 1)// show error in window //("ScriptErrorsAsChat")) +		{ + +			LLColor4 txt_color; + +			LLViewerChat::getChatColor(chat_msg,txt_color); + +			LLFloaterScriptDebug::addScriptLine(chat_msg.mText, +												chat_msg.mFromName, +												txt_color, +												chat_msg.mFromID); +			return; +		} +	} +  	nearby_chat->addMessage(chat_msg, true, args);  	if( nearby_chat->getVisible()  		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT diff --git a/indra/newview/lloutfitobserver.cpp b/indra/newview/lloutfitobserver.cpp index 848b595613..03414b9964 100644 --- a/indra/newview/lloutfitobserver.cpp +++ b/indra/newview/lloutfitobserver.cpp @@ -56,12 +56,9 @@ void LLOutfitObserver::changed(U32 mask)  	if (!gInventory.isInventoryUsable())  		return; -	bool panel_updated = checkCOF(); +	checkCOF(); -	if (!panel_updated) -	{ -		checkBaseOutfit(); -	} +	checkBaseOutfit();  }  // static @@ -74,6 +71,16 @@ S32 LLOutfitObserver::getCategoryVersion(const LLUUID& cat_id)  	return cat->getVersion();  } +// static +const std::string& LLOutfitObserver::getCategoryName(const LLUUID& cat_id) +{ +	LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id); +	if (!cat) +		return LLStringUtil::null; + +	return cat->getName(); +} +  bool LLOutfitObserver::checkCOF()  {  	LLUUID cof = LLAppearanceMgr::getInstance()->getCOF(); @@ -87,6 +94,7 @@ bool LLOutfitObserver::checkCOF()  	mCOFLastVersion = cof_version; +	// dirtiness state should be updated before sending signal  	LLAppearanceMgr::getInstance()->updateIsDirty();  	mCOFChanged(); @@ -104,8 +112,11 @@ void LLOutfitObserver::checkBaseOutfit()  			return;  		const S32 baseoutfit_ver = getCategoryVersion(baseoutfit_id); +		const std::string& baseoutfit_name = getCategoryName(baseoutfit_id); -		if (baseoutfit_ver == mBaseOutfitLastVersion) +		if (baseoutfit_ver == mBaseOutfitLastVersion +				// renaming category doesn't change version, so it's need to check it +				&& baseoutfit_name == mLastBaseOutfitName)  			return;  	}  	else @@ -115,11 +126,22 @@ void LLOutfitObserver::checkBaseOutfit()  		if (baseoutfit_id.isNull())  			return; - -		mBaseOutfitLastVersion = getCategoryVersion(mBaseOutfitId);  	} +	mBaseOutfitLastVersion = getCategoryVersion(mBaseOutfitId); +	mLastBaseOutfitName = getCategoryName(baseoutfit_id); +  	LLAppearanceMgr& app_mgr = LLAppearanceMgr::instance(); +	// dirtiness state should be updated before sending signal  	app_mgr.updateIsDirty();  	mBOFChanged(); + +	if (mLastOutfitDirtiness != app_mgr.isOutfitDirty()) +	{ +		if(!app_mgr.isOutfitDirty()) +		{ +			mCOFSaved(); +		} +		mLastOutfitDirtiness = app_mgr.isOutfitDirty(); +	}  } diff --git a/indra/newview/lloutfitobserver.h b/indra/newview/lloutfitobserver.h index 4cb40ead15..3a66b5ea9f 100644 --- a/indra/newview/lloutfitobserver.h +++ b/indra/newview/lloutfitobserver.h @@ -48,6 +48,8 @@ public:  	virtual void changed(U32 mask); +	void notifyOutfitLockChanged() { mOutfitLockChanged();  } +  	typedef boost::signals2::signal<void (void)> signal_t;  	void addBOFReplacedCallback(const signal_t::slot_type& cb) { mBOFReplaced.connect(cb); } @@ -56,12 +58,18 @@ public:  	void addCOFChangedCallback(const signal_t::slot_type& cb) { mCOFChanged.connect(cb); } +	void addCOFSavedCallback(const signal_t::slot_type& cb) { mCOFSaved.connect(cb); } + +	void addOutfitLockChangedCallback(const signal_t::slot_type& cb) { mOutfitLockChanged.connect(cb); } +  protected:  	LLOutfitObserver();  	/** Get a version of an inventory category specified by its UUID */  	static S32 getCategoryVersion(const LLUUID& cat_id); +	static const std::string& getCategoryName(const LLUUID& cat_id); +  	bool checkCOF();  	void checkBaseOutfit(); @@ -72,11 +80,20 @@ protected:  	LLUUID mBaseOutfitId;  	S32 mBaseOutfitLastVersion; +	std::string mLastBaseOutfitName; + +	bool mLastOutfitDirtiness;  private:  	signal_t mBOFReplaced;  	signal_t mBOFChanged;  	signal_t mCOFChanged; +	signal_t mCOFSaved; + +	/** +	 * Signal for changing state of outfit lock. +	 */ +	signal_t mOutfitLockChanged;  };  #endif /* LL_OUTFITOBSERVER_H */ diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index e20b2e26be..03df2d2b20 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -44,6 +44,7 @@  #include "llinventorymodel.h"  #include "lllistcontextmenu.h"  #include "llnotificationsutil.h" +#include "lloutfitobserver.h"  #include "llsidetray.h"  #include "lltransutil.h"  #include "llviewermenu.h" @@ -89,17 +90,33 @@ protected:  		registrar.add("Outfit.Delete", boost::bind(deleteOutfit, selected_id));  		enable_registrar.add("Outfit.OnEnable", boost::bind(&OutfitContextMenu::onEnable, this, _2)); +		enable_registrar.add("Outfit.OnVisible", boost::bind(&OutfitContextMenu::onVisible, this, _2));  		return createFromFile("menu_outfit_tab.xml");  	} -	bool onEnable(const LLSD& data) +	bool onEnable(LLSD::String param) +	{ +		LLUUID outfit_cat_id = mUUIDs.back(); + +		if ("rename" == param) +		{ +			return get_is_category_renameable(&gInventory, outfit_cat_id); +		} + +		return true; +	} + +	bool onVisible(LLSD::String param)  	{ -		std::string param = data.asString();  		LLUUID outfit_cat_id = mUUIDs.back();  		bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == outfit_cat_id; -		if ("wear_replace" == param) +		if ("edit" == param) +		{ +			return is_worn; +		} +		else if ("wear_replace" == param)  		{  			return !is_worn;  		} @@ -111,14 +128,6 @@ protected:  		{  			return is_worn;  		} -		else if ("edit" == param) -		{ -			return is_worn; -		} -		else if ("rename" == param) -		{ -			return get_is_category_renameable(&gInventory, outfit_cat_id); -		}  		else if ("delete" == param)  		{  			return LLAppearanceMgr::instance().getCanRemoveOutfit(outfit_cat_id); @@ -199,6 +208,9 @@ void LLOutfitsList::onOpen(const LLSD& /*info*/)  		mCategoriesObserver->addCategory(outfits,  			boost::bind(&LLOutfitsList::refreshList, this, outfits)); +		// Start observing changes in Current Outfit to update items worn state. +		LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLOutfitsList::onCOFChanged, this)); +  		// Fetch "My Outfits" contents and refresh the list to display  		// initially fetched items. If not all items are fetched now  		// the observer will refresh the list as soon as the new items @@ -322,7 +334,7 @@ void LLOutfitsList::refreshList(const LLUUID& category_id)  			// 3. Reset currently selected outfit id if it is being removed.  			if (outfit_id == mSelectedOutfitUUID)  			{ -				mSelectedOutfitUUID = LLUUID(); +				setSelectedOutfitUUID(LLUUID());  			}  			// 4. Remove category UUID to accordion tab mapping. @@ -385,6 +397,11 @@ void LLOutfitsList::setFilterSubString(const std::string& string)  	mFilterSubString = string;  } +boost::signals2::connection LLOutfitsList::addSelectionChangeCallback(selection_change_callback_t cb) +{ +	return mSelectionChangeSignal.connect(cb); +} +  //////////////////////////////////////////////////////////////////////////  // Private methods  ////////////////////////////////////////////////////////////////////////// @@ -471,7 +488,12 @@ void LLOutfitsList::changeOutfitSelection(LLWearableItemsList* list, const LLUUI  	}  	mSelectedListsMap.insert(wearables_lists_map_value_t(category_id, list)); -	mSelectedOutfitUUID = category_id; +	setSelectedOutfitUUID(category_id); +} + +void LLOutfitsList::setSelectedOutfitUUID(const LLUUID& category_id) +{ +	mSelectionChangeSignal(mSelectedOutfitUUID = category_id);  }  void LLOutfitsList::onFilteredWearableItemsListRefresh(LLUICtrl* ctrl) @@ -645,6 +667,43 @@ void LLOutfitsList::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y)  	LLWearableItemsList::ContextMenu::instance().show(list, selected_uuids, x, y);  } +void LLOutfitsList::onCOFChanged() +{ +	LLInventoryModel::changed_items_t changed_linked_items; + +	const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs(); +	for (LLInventoryModel::changed_items_t::const_iterator iter = changed_items.begin(); +		 iter != changed_items.end(); +		 ++iter) +	{ +		LLViewerInventoryItem* item = gInventory.getItem(*iter); +		if (item) +		{ +			// From gInventory we get the UUIDs of new links added to COF +			// or removed from COF. These links UUIDs are not the same UUIDs +			// that we have in each wearable items list. So we collect base items +			// UUIDs to find all items or links that point to same base items in wearable +			// items lists and update their worn state there. +			changed_linked_items.insert(item->getLinkedUUID()); +		} +	} + +	for (outfits_map_t::iterator iter = mOutfitsMap.begin(); +			iter != mOutfitsMap.end(); +			++iter) +	{ +		LLAccordionCtrlTab* tab = iter->second; +		if (!tab) continue; + +		LLWearableItemsList* list = dynamic_cast<LLWearableItemsList*>(tab->getAccordionView()); +		if (!list) continue; + +		// Every list updates the labels of changed items  or +		// the links that point to these items. +		list->updateChangedItems(changed_linked_items); +	} +} +  bool is_tab_header_clicked(LLAccordionCtrlTab* tab, S32 y)  {  	if(!tab || !tab->getHeaderVisible()) return false; diff --git a/indra/newview/lloutfitslist.h b/indra/newview/lloutfitslist.h index bb516446d2..478eaa50b3 100644 --- a/indra/newview/lloutfitslist.h +++ b/indra/newview/lloutfitslist.h @@ -71,6 +71,9 @@ public:  class LLOutfitsList : public LLPanel  {  public: +	typedef boost::function<void (const LLUUID&)> selection_change_callback_t; +	typedef boost::signals2::signal<void (const LLUUID&)> selection_change_signal_t; +  	LLOutfitsList();  	virtual ~LLOutfitsList(); @@ -86,6 +89,8 @@ public:  	const LLUUID& getSelectedOutfitUUID() const { return mSelectedOutfitUUID; } +	boost::signals2::connection addSelectionChangeCallback(selection_change_callback_t cb); +  private:  	/**  	 * Reads xml with accordion tab and Flat list from xml file. @@ -110,6 +115,11 @@ private:  	void changeOutfitSelection(LLWearableItemsList* list, const LLUUID& category_id);  	/** +	 * Saves newly selected outfit ID. +	 */ +	void setSelectedOutfitUUID(const LLUUID& category_id); + +	/**  	 * Called upon list refresh event to update tab visibility depending on  	 * the results of applying filter to the title and list items of the tab.  	 */ @@ -123,6 +133,7 @@ private:  	void onAccordionTabRightClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);  	void onAccordionTabDoubleClick(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& cat_id);  	void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y); +	void onCOFChanged();  	void onSelectionChange(LLUICtrl* ctrl); @@ -138,6 +149,7 @@ private:  	wearables_lists_map_t			mSelectedListsMap;  	LLUUID							mSelectedOutfitUUID; +	selection_change_signal_t		mSelectionChangeSignal;  	std::string 					mFilterSubString; diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp index a1a9300ec2..1aedfec86f 100644 --- a/indra/newview/llpaneleditwearable.cpp +++ b/indra/newview/llpaneleditwearable.cpp @@ -61,6 +61,9 @@  #include "llagentcamera.h"  #include "llmorphview.h" +#include "llcommandhandler.h" +#include "lltextutil.h" +  // register panel with appropriate XML  static LLRegisterPanelClassWrapper<LLPanelEditWearable> t_edit_wearable("panel_edit_wearable"); @@ -608,6 +611,36 @@ LLPanelEditWearable::~LLPanelEditWearable()  } +bool LLPanelEditWearable::changeHeightUnits(const LLSD& new_value) +{ +	updateMetricLayout( new_value.asBoolean() ); +	updateTypeSpecificControls(LLWearableType::WT_SHAPE); +	return true; +} + +void LLPanelEditWearable::updateMetricLayout(BOOL new_value) +{ +	LLUIString current_metric, replacment_metric; +	current_metric = new_value ? mMeters : mFeet; +	replacment_metric = new_value ? mFeet : mMeters; +	mHeigthValue.setArg( "[METRIC1]", current_metric.getString() ); +	mReplacementMetricUrl.setArg( "[URL_METRIC2]", std::string("[secondlife:///app/metricsystem ") + replacment_metric.getString() + std::string("]")); +} + +void LLPanelEditWearable::updateAvatarHeightLabel() +{ +	mTxtAvatarHeight->setText(LLStringUtil::null); +	LLStyle::Params param; +	param.color = mAvatarHeigthLabelColor; +	mTxtAvatarHeight->appendText(mHeigth, false, param); +	param.color = mAvatarHeigthValueLabelColor; +	mTxtAvatarHeight->appendText(mHeigthValue, false, param); +	param.color = mAvatarHeigthLabelColor; // using mAvatarHeigthLabelColor for '/' separator +	mTxtAvatarHeight->appendText(" / ", false, param); +	mTxtAvatarHeight->appendText(this->mReplacementMetricUrl, false, param); +} + +  // virtual   BOOL LLPanelEditWearable::postBuild()  { @@ -700,6 +733,20 @@ BOOL LLPanelEditWearable::postBuild()  		for_each_picker_ctrl_entry <LLTextureCtrl>     (getPanel(type), type, boost::bind(init_texture_ctrl, this, _1, _2));  	} +	// init all strings +	mMeters		= mPanelShape->getString("meters"); +	mFeet		= mPanelShape->getString("feet"); +	mHeigth		= mPanelShape->getString("height") + " "; +	mHeigthValue	= "[HEIGHT] [METRIC1]"; +	mReplacementMetricUrl	= "[URL_METRIC2]"; + +	std::string color = mPanelShape->getString("heigth_label_color"); +	mAvatarHeigthLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green); +	color = mPanelShape->getString("heigth_value_label_color"); +	mAvatarHeigthValueLabelColor = LLUIColorTable::instance().getColor(color, LLColor4::green); +	gSavedSettings.getControl("HeightUnits")->getSignal()->connect(boost::bind(&LLPanelEditWearable::changeHeightUnits, this, _2)); +	updateMetricLayout(gSavedSettings.getBOOL("HeightUnits")); +  	return TRUE;  } @@ -1107,12 +1154,22 @@ void LLPanelEditWearable::toggleTypeSpecificControls(LLWearableType::EType type)  void LLPanelEditWearable::updateTypeSpecificControls(LLWearableType::EType type)  { +	const F32 ONE_METER = 1.0; +	const F32 ONE_FOOT = 0.3048 * ONE_METER; // in meters  	// Update controls specific to shape editing panel.  	if (type == LLWearableType::WT_SHAPE)  	{  		// Update avatar height -		std::string avatar_height_str = llformat("%.2f", gAgentAvatarp->mBodySize.mV[VZ]); -		mTxtAvatarHeight->setTextArg("[HEIGHT]", avatar_height_str); +		F32 new_size = gAgentAvatarp->mBodySize.mV[VZ]; +		if (gSavedSettings.getBOOL("HeightUnits") == FALSE) +		{ +			// convert meters to feet +			new_size = new_size / ONE_FOOT; +		} + +		std::string avatar_height_str = llformat("%.2f", new_size); +		mHeigthValue.setArg("[HEIGHT]", avatar_height_str); +		updateAvatarHeightLabel();  	}  	if (LLWearableType::WT_ALPHA == type) @@ -1381,4 +1438,21 @@ void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLVOAvatarDefines::EText  	}  } +// handle secondlife:///app/metricsystem +class LLMetricSystemHandler : public LLCommandHandler +{ +public: +	LLMetricSystemHandler() : LLCommandHandler("metricsystem", UNTRUSTED_THROTTLE) { } + +	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web) +	{ +		// change height units TRUE for meters and FALSE for feet +		BOOL new_value = (gSavedSettings.getBOOL("HeightUnits") == FALSE) ? TRUE : FALSE; +		gSavedSettings.setBOOL("HeightUnits", new_value); +		return true; +	} +}; + +LLMetricSystemHandler gMetricSystemHandler; +  // EOF diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h index 54f729fa7a..c63671fcc9 100644 --- a/indra/newview/llpaneleditwearable.h +++ b/indra/newview/llpaneleditwearable.h @@ -104,6 +104,15 @@ private:  	void initPreviousAlphaTextures();  	void initPreviousAlphaTextureEntry(LLVOAvatarDefines::ETextureIndex te); +	// callback for HeightUnits parameter. +	bool changeHeightUnits(const LLSD& new_value); + +	// updates current metric and replacemet metric label text +	void updateMetricLayout(BOOL new_value); + +	// updates avatar height label +	void updateAvatarHeightLabel(); +  	// the pointer to the wearable we're editing. NULL means we're not editing a wearable.  	LLWearable *mWearablePtr;  	LLViewerInventoryItem* mWearableItem; @@ -117,6 +126,18 @@ private:  	LLTextBox *mTxtAvatarHeight; +	// localized and parametrized strings that used to build avatar_height_label +	std::string mMeters; +	std::string mFeet; +	std::string mHeigth; +	LLUIString  mHeigthValue; +	LLUIString  mReplacementMetricUrl; + +	// color for mHeigth string +	LLUIColor mAvatarHeigthLabelColor; +	// color for mHeigthValue string +	LLUIColor mAvatarHeigthValueLabelColor; +  	// This text editor reference will change each time we edit a new wearable -   	// it will be grabbed from the currently visible panel  	LLTextEditor *mTextEditor; diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index 42ff514f09..ba50081fb2 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -338,7 +338,6 @@ void LLPanelGroupNotices::setItem(LLPointer<LLInventoryItem> inv_item)  	std::string icon_name = LLInventoryIcon::getIconName(inv_item->getType(),  										inv_item->getInventoryType(),  										inv_item->getFlags(), -										inv_item->getIsLinkType(),  										item_is_multi );  	mCreateInventoryIcon->setValue(icon_name); diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index b356fe6bfd..26e8a932aa 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -815,6 +815,8 @@ void LLPanelGroupRolesSubTab::setGroupID(const LLUUID& id)  	if(mRoleDescription) mRoleDescription->clear();  	if(mRoleTitle) mRoleTitle->clear(); +	mHasRoleChange = FALSE; +  	setFooterEnabled(FALSE);  	LLPanelGroupSubTab::setGroupID(id); diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp index 7fb46fc84f..ce1131f45c 100644 --- a/indra/newview/llpanellandmarks.cpp +++ b/indra/newview/llpanellandmarks.cpp @@ -334,7 +334,7 @@ void LLLandmarksPanel::updateVerbs()  	bool landmark_selected = isLandmarkSelected();  	mTeleportBtn->setEnabled(landmark_selected && isActionEnabled("teleport"));  	mShowProfile->setEnabled(landmark_selected && isActionEnabled("more_info")); -	mShowOnMapBtn->setEnabled(true); +	mShowOnMapBtn->setEnabled(landmark_selected && isActionEnabled("show_on_map"));  	// TODO: mantipov: Uncomment when mShareBtn is supported  	// Share button should be enabled when neither a folder nor a landmark is selected diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index c557e9b85d..da809b7baa 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -135,6 +135,8 @@ public:  	virtual BOOL isUpToDate() const { return TRUE; }  	virtual BOOL hasChildren() const { return FALSE; }  	virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; } +	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; } +  	// LLDragAndDropBridge functionality  	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;  	virtual BOOL dragOrDrop(MASK mask, BOOL drop, @@ -184,6 +186,7 @@ void LLTaskInvFVBridge::showProperties()  		floater->setObjectID(mPanel->getTaskUUID());  	}  	*/ +	  }  struct LLBuyInvItemData @@ -351,7 +354,7 @@ LLUIImagePtr LLTaskInvFVBridge::getIcon() const  {  	const BOOL item_is_multi = (mFlags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS); -	return LLInventoryIcon::getIcon(mAssetType, mInventoryType, FALSE, 0, item_is_multi ); +	return LLInventoryIcon::getIcon(mAssetType, mInventoryType, 0, item_is_multi );  }  void LLTaskInvFVBridge::openItem() @@ -1236,7 +1239,7 @@ public:  LLUIImagePtr LLTaskWearableBridge::getIcon() const  { -	return LLInventoryIcon::getIcon(mAssetType, mInventoryType, FALSE, mFlags, FALSE ); +	return LLInventoryIcon::getIcon(mAssetType, mInventoryType, mFlags, FALSE );  } diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp index ce382541c6..1454a2f6af 100644 --- a/indra/newview/llpaneloutfitedit.cpp +++ b/indra/newview/llpaneloutfitedit.cpp @@ -65,6 +65,7 @@  #include "llsaveoutfitcombobtn.h"  #include "llscrolllistctrl.h"  #include "lltextbox.h" +#include "lltrans.h"  #include "lluictrlfactory.h"  #include "llsdutil.h"  #include "llsidepanelappearance.h" @@ -188,8 +189,8 @@ LLPanelOutfitEdit::LLPanelOutfitEdit()  	mCOFDragAndDropObserver(NULL),  	mInitialized(false),  	mAddWearablesPanel(NULL), -	mWearableListMaskCollector(NULL), -	mWearableListTypeCollector(NULL) +	mFolderViewFilterCmbBox(NULL), +	mListViewFilterCmbBox(NULL)  {  	mSavedFolderState = new LLSaveFolderState();  	mSavedFolderState->setApply(FALSE); @@ -198,14 +199,14 @@ LLPanelOutfitEdit::LLPanelOutfitEdit()  	LLOutfitObserver& observer = LLOutfitObserver::instance();  	observer.addBOFReplacedCallback(boost::bind(&LLPanelOutfitEdit::updateCurrentOutfitName, this));  	observer.addBOFChangedCallback(boost::bind(&LLPanelOutfitEdit::updateVerbs, this)); +	observer.addOutfitLockChangedCallback(boost::bind(&LLPanelOutfitEdit::updateVerbs, this));  	observer.addCOFChangedCallback(boost::bind(&LLPanelOutfitEdit::update, this)); -	mLookItemTypes.reserve(NUM_LOOK_ITEM_TYPES); -	for (U32 i = 0; i < NUM_LOOK_ITEM_TYPES; i++) +	mFolderViewItemTypes.reserve(NUM_FOLDER_VIEW_ITEM_TYPES); +	for (U32 i = 0; i < NUM_FOLDER_VIEW_ITEM_TYPES; i++)  	{ -		mLookItemTypes.push_back(LLLookItemType()); +		mFolderViewItemTypes.push_back(LLLookItemType());  	} -	  } @@ -215,17 +216,40 @@ LLPanelOutfitEdit::~LLPanelOutfitEdit()  	delete mCOFDragAndDropObserver; -	delete mWearableListMaskCollector; -	delete mWearableListTypeCollector; +	while (!mListViewItemTypes.empty()) { +		delete mListViewItemTypes.back(); +		mListViewItemTypes.pop_back(); +	}  }  BOOL LLPanelOutfitEdit::postBuild()  {  	// gInventory.isInventoryUsable() no longer needs to be tested per Richard's fix for race conditions between inventory and panels - -	mLookItemTypes[LIT_ALL] = LLLookItemType(getString("Filter.All"), ALL_ITEMS_MASK); -	mLookItemTypes[LIT_WEARABLE] = LLLookItemType(getString("Filter.Clothes/Body"), WEARABLE_MASK); -	mLookItemTypes[LIT_ATTACHMENT] = LLLookItemType(getString("Filter.Objects"), ATTACHMENT_MASK); +	 +	mFolderViewItemTypes[FVIT_ALL] = LLLookItemType(getString("Filter.All"), ALL_ITEMS_MASK); +	mFolderViewItemTypes[FVIT_WEARABLE] = LLLookItemType(getString("Filter.Clothes/Body"), WEARABLE_MASK); +	mFolderViewItemTypes[FVIT_ATTACHMENT] = LLLookItemType(getString("Filter.Objects"), ATTACHMENT_MASK); + +	//order is important, see EListViewItemType for order information +	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.All"), new LLFindByMask(ALL_ITEMS_MASK))); +	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.Clothing"), new LLIsType(LLAssetType::AT_CLOTHING))); +	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.Bodyparts"), new LLIsType(LLAssetType::AT_BODYPART))); +	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.Objects"), new LLFindByMask(ATTACHMENT_MASK)));; +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("shape"), new LLFindActualWearablesOfType(LLWearableType::WT_SHAPE))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("skin"), new LLFindActualWearablesOfType(LLWearableType::WT_SKIN))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("hair"), new LLFindActualWearablesOfType(LLWearableType::WT_HAIR))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("eyes"), new LLFindActualWearablesOfType(LLWearableType::WT_EYES))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("shirt"), new LLFindActualWearablesOfType(LLWearableType::WT_SHIRT))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("pants"), new LLFindActualWearablesOfType(LLWearableType::WT_PANTS))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("shoes"), new LLFindActualWearablesOfType(LLWearableType::WT_SHOES))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("socks"), new LLFindActualWearablesOfType(LLWearableType::WT_SOCKS))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("jacket"), new LLFindActualWearablesOfType(LLWearableType::WT_JACKET))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("gloves"), new LLFindActualWearablesOfType(LLWearableType::WT_GLOVES))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("undershirt"), new LLFindActualWearablesOfType(LLWearableType::WT_UNDERSHIRT))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("underpants"), new LLFindActualWearablesOfType(LLWearableType::WT_UNDERPANTS))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("skirt"), new LLFindActualWearablesOfType(LLWearableType::WT_SKIRT))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("alpha"), new LLFindActualWearablesOfType(LLWearableType::WT_ALPHA))); +	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("tattoo"), new LLFindActualWearablesOfType(LLWearableType::WT_TATTOO)));  	mCurrentOutfitName = getChild<LLTextBox>("curr_outfit_name");   	mStatus = getChild<LLTextBox>("status"); @@ -234,12 +258,13 @@ BOOL LLPanelOutfitEdit::postBuild()  	mListViewBtn = getChild<LLButton>("list_view_btn");  	childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL); -	childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredFolderWearablesPanel, this), NULL); -	childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredWearablesPanel, this), NULL); +	childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::showWearablesFolderView, this), NULL); +	childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showWearablesListView, this), NULL);  	childSetCommitCallback("wearables_gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL); +	childSetCommitCallback("gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);  	mCOFWearables = getChild<LLCOFWearables>("cof_wearables_list"); -	mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onOutfitItemSelectionChange, this)); +	mCOFWearables->setCommitCallback(boost::bind(&LLPanelOutfitEdit::filterWearablesBySelectedItem, this));  	mCOFWearables->getCOFCallbacks().mAddWearable = boost::bind(&LLPanelOutfitEdit::onAddWearableClicked, this);  	mCOFWearables->getCOFCallbacks().mEditWearable = boost::bind(&LLPanelOutfitEdit::onEditWearableClicked, this); @@ -249,7 +274,7 @@ BOOL LLPanelOutfitEdit::postBuild()  	mAddWearablesPanel = getChild<LLPanel>("add_wearables_panel"); -	mInventoryItemsPanel = getChild<LLInventoryPanel>("inventory_items"); +	mInventoryItemsPanel = getChild<LLInventoryPanel>("folder_view");  	mInventoryItemsPanel->setFilterTypes(ALL_ITEMS_MASK);  	mInventoryItemsPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);  	mInventoryItemsPanel->setSelectCallback(boost::bind(&LLPanelOutfitEdit::onInventorySelectionChange, this, _1, _2)); @@ -257,19 +282,29 @@ BOOL LLPanelOutfitEdit::postBuild()  	mCOFDragAndDropObserver = new LLCOFDragAndDropObserver(mInventoryItemsPanel->getModel()); -	LLComboBox* type_filter = getChild<LLComboBox>("filter_wearables_combobox"); -	type_filter->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onTypeFilterChanged, this, _1)); -	type_filter->removeall(); -	for (U32 i = 0; i < mLookItemTypes.size(); ++i) +	mFolderViewFilterCmbBox = getChild<LLComboBox>("folder_view_filter_combobox"); +	mFolderViewFilterCmbBox->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onFolderViewFilterCommitted, this, _1)); +	mFolderViewFilterCmbBox->removeall(); +	for (U32 i = 0; i < mFolderViewItemTypes.size(); ++i)  	{ -		type_filter->add(mLookItemTypes[i].displayName); +		mFolderViewFilterCmbBox->add(mFolderViewItemTypes[i].displayName);  	} -	type_filter->setCurrentByIndex(LIT_ALL); +	mFolderViewFilterCmbBox->setCurrentByIndex(FVIT_ALL); +	mListViewFilterCmbBox = getChild<LLComboBox>("list_view_filter_combobox"); +	mListViewFilterCmbBox->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onListViewFilterCommitted, this, _1)); +	mListViewFilterCmbBox->removeall(); +	for (U32 i = 0; i < mListViewItemTypes.size(); ++i) +	{ +		mListViewFilterCmbBox->add(mListViewItemTypes[i]->displayName); +	} +	mListViewFilterCmbBox->setCurrentByIndex(LVIT_ALL); +  	mSearchFilter = getChild<LLFilterEditor>("look_item_filter");  	mSearchFilter->setCommitCallback(boost::bind(&LLPanelOutfitEdit::onSearchEdit, this, _2)); -	childSetAction("show_add_wearables_btn", boost::bind(&LLPanelOutfitEdit::toggleAddWearablesPanel, this)); +	childSetAction("show_add_wearables_btn", boost::bind(&LLPanelOutfitEdit::onAddMoreButtonClicked, this)); +  	childSetAction("add_to_outfit_btn", boost::bind(&LLPanelOutfitEdit::onAddToOutfitClicked, this));  	mEditWearableBtn = getChild<LLButton>("edit_wearable_btn"); @@ -279,11 +314,8 @@ BOOL LLPanelOutfitEdit::postBuild()  	childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance())); -	mWearableListMaskCollector = new LLFindNonLinksByMask(ALL_ITEMS_MASK); -	mWearableListTypeCollector = new LLFindActualWearablesOfType(LLWearableType::WT_NONE); - -	mWearableItemsPanel = getChild<LLPanel>("filtered_wearables_panel"); -	mWearableItemsList = getChild<LLInventoryItemsList>("filtered_wearables_list"); +	mWearablesListViewPanel = getChild<LLPanel>("filtered_wearables_panel"); +	mWearableItemsList = getChild<LLInventoryItemsList>("list_view");  	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));  	return TRUE; @@ -296,7 +328,7 @@ void LLPanelOutfitEdit::onOpen(const LLSD& key)  	{  		// *TODO: this method is called even panel is not visible to user because its parent layout panel is hidden.  		// So, we can defer initializing a bit. -		mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, mWearableListMaskCollector); +		mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, mListViewItemTypes[LVIT_ALL]->collector);  		mWearableListManager->populateList();  		displayCurrentOutfit();  		mInitialized = true; @@ -324,13 +356,17 @@ void LLPanelOutfitEdit::showAddWearablesPanel(bool show_add_wearables)  	childSetValue("show_add_wearables_btn", show_add_wearables); -	childSetVisible("filter_wearables_combobox", show_add_wearables); +	updateFiltersVisibility();  	childSetVisible("filter_button", show_add_wearables);  	//search filter should be disabled  	if (!show_add_wearables)  	{  		childSetValue("filter_button", false); + +		mFolderViewFilterCmbBox->setVisible(false); +		mListViewFilterCmbBox->setVisible(false); +  		showWearablesFilter();  	} @@ -352,41 +388,43 @@ void LLPanelOutfitEdit::showWearablesFilter()  	}  } -void LLPanelOutfitEdit::showFilteredWearablesPanel() +void LLPanelOutfitEdit::showWearablesListView()  { -	if(switchPanels(mInventoryItemsPanel, mWearableItemsPanel)) +	if(switchPanels(mInventoryItemsPanel, mWearablesListViewPanel))  	{  		mFolderViewBtn->setToggleState(FALSE);  		mFolderViewBtn->setImageOverlay(getString("folder_view_off"), mFolderViewBtn->getImageOverlayHAlign());  		mListViewBtn->setImageOverlay(getString("list_view_on"), mListViewBtn->getImageOverlayHAlign()); +		updateFiltersVisibility();  	}  	mListViewBtn->setToggleState(TRUE);  } -void LLPanelOutfitEdit::showFilteredFolderWearablesPanel() +void LLPanelOutfitEdit::showWearablesFolderView()  { -	if(switchPanels(mWearableItemsPanel, mInventoryItemsPanel)) +	if(switchPanels(mWearablesListViewPanel, mInventoryItemsPanel))  	{  		mListViewBtn->setToggleState(FALSE);  		mListViewBtn->setImageOverlay(getString("list_view_off"), mListViewBtn->getImageOverlayHAlign());  		mFolderViewBtn->setImageOverlay(getString("folder_view_on"), mFolderViewBtn->getImageOverlayHAlign()); +		updateFiltersVisibility();  	}  	mFolderViewBtn->setToggleState(TRUE);  } -void LLPanelOutfitEdit::onTypeFilterChanged(LLUICtrl* ctrl) +void LLPanelOutfitEdit::updateFiltersVisibility()  { -	LLComboBox* type_filter = dynamic_cast<LLComboBox*>(ctrl); -	llassert(type_filter); -	if (type_filter) -	{ -		U32 curr_filter_type = type_filter->getCurrentIndex(); -		mInventoryItemsPanel->setFilterTypes(mLookItemTypes[curr_filter_type].inventoryMask); +	mListViewFilterCmbBox->setVisible(mWearablesListViewPanel->getVisible()); +	mFolderViewFilterCmbBox->setVisible(mInventoryItemsPanel->getVisible()); +} + +void LLPanelOutfitEdit::onFolderViewFilterCommitted(LLUICtrl* ctrl) +{ +	S32 curr_filter_type = mFolderViewFilterCmbBox->getCurrentIndex(); +	if (curr_filter_type < 0) return; + +	mInventoryItemsPanel->setFilterTypes(mFolderViewItemTypes[curr_filter_type].inventoryMask); -		mWearableListMaskCollector->setFilterMask(mLookItemTypes[curr_filter_type].inventoryMask); -		mWearableListManager->setFilterCollector(mWearableListMaskCollector); -	} -	  	mSavedFolderState->setApply(TRUE);  	mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState); @@ -397,6 +435,14 @@ void LLPanelOutfitEdit::onTypeFilterChanged(LLUICtrl* ctrl)  	LLInventoryModelBackgroundFetch::instance().start();  } +void LLPanelOutfitEdit::onListViewFilterCommitted(LLUICtrl* ctrl) +{ +	S32 curr_filter_type = mListViewFilterCmbBox->getCurrentIndex(); +	if (curr_filter_type < 0) return; + +	mWearableListManager->setFilterCollector(mListViewItemTypes[curr_filter_type]->collector); +} +  void LLPanelOutfitEdit::onSearchEdit(const std::string& string)  {  	if (mSearchString != string) @@ -454,7 +500,7 @@ void LLPanelOutfitEdit::onAddToOutfitClicked(void)  		selected_id = listenerp->getUUID();  	} -	else if (mWearableItemsPanel->getVisible()) +	else if (mWearablesListViewPanel->getVisible())  	{  		selected_id = mWearableItemsList->getSelectedUUID();  	} @@ -470,7 +516,7 @@ void LLPanelOutfitEdit::onAddWearableClicked(void)  	if(item)  	{ -		showFilteredWearableItemsList(item->getWearableType()); +		showFilteredWearablesListView(item->getWearableType());  	}  } @@ -480,7 +526,7 @@ void LLPanelOutfitEdit::onReplaceBodyPartMenuItemClicked(LLUUID selected_item_id  	if (item && item->getType() == LLAssetType::AT_BODYPART)  	{ -		showFilteredWearableItemsList(item->getWearableType()); +		showFilteredWearablesListView(item->getWearableType());  	}  } @@ -494,35 +540,10 @@ void LLPanelOutfitEdit::onRemoveFromOutfitClicked(void)  void LLPanelOutfitEdit::onEditWearableClicked(void)  { -	LLUUID id_to_edit = mCOFWearables->getSelectedUUID(); -	LLViewerInventoryItem * item_to_edit = gInventory.getItem(id_to_edit); - -	if (item_to_edit) +	LLUUID selected_item_id = mCOFWearables->getSelectedUUID(); +	if (selected_item_id.notNull())  	{ -		// returns null if not a wearable (attachment, etc). -		LLWearable* wearable_to_edit = gAgentWearables.getWearableFromAssetID(item_to_edit->getAssetUUID()); -		if(wearable_to_edit) -		{ -			bool can_modify = false; -			bool is_complete = item_to_edit->isFinished(); -			// if item_to_edit is a link, its properties are not appropriate,  -			// lets get original item with actual properties -			LLViewerInventoryItem* original_item = gInventory.getItem(wearable_to_edit->getItemID()); -			if(original_item) -			{ -				can_modify = original_item->getPermissions().allowModifyBy(gAgentID); -				is_complete = original_item->isFinished(); -			} - -			if (can_modify && is_complete) -			{											  -				LLSidepanelAppearance::editWearable(wearable_to_edit, getParent()); -				if (mEditWearableBtn->getVisible()) -				{ -					mEditWearableBtn->setVisible(FALSE); -				} -			} -		} +		gAgentWearables.editWearable(selected_item_id);  	}  } @@ -562,24 +583,87 @@ void LLPanelOutfitEdit::onInventorySelectionChange(const std::deque<LLFolderView  	current_item->addChild(mAddToLookBtn); */  } -void LLPanelOutfitEdit::onOutfitItemSelectionChange(void) -{	 -	LLUUID item_id = mCOFWearables->getSelectedUUID(); -	//*TODO show Edit Wearable Button +void LLPanelOutfitEdit::applyFolderViewFilter(EFolderViewItemType type) +{ +	mFolderViewFilterCmbBox->setCurrentByIndex(type); +	mFolderViewFilterCmbBox->onCommit(); +} + +void LLPanelOutfitEdit::applyListViewFilter(EListViewItemType type) +{ +	mListViewFilterCmbBox->setCurrentByIndex(type); +	mListViewFilterCmbBox->onCommit(); +} -	LLViewerInventoryItem* item_to_remove = gInventory.getItem(item_id); -	if (!item_to_remove) return; +void LLPanelOutfitEdit::filterWearablesBySelectedItem(void) +{ +	if (!mAddWearablesPanel->getVisible()) return; +	 +	uuid_vec_t ids; +	mCOFWearables->getSelectedUUIDs(ids); -	switch (item_to_remove->getType()) +	bool nothing_selected = ids.empty(); +	bool one_selected = ids.size() == 1; +	bool more_than_one_selected = ids.size() > 1; +	bool is_dummy_item = (ids.size() && dynamic_cast<LLPanelDummyClothingListItem*>(mCOFWearables->getSelectedItem())); + +	//resetting selection if no item is selected or than one item is selected +	if (nothing_selected || more_than_one_selected)  	{ -	case LLAssetType::AT_CLOTHING: -	case LLAssetType::AT_OBJECT: -	default: -		break; +		if (nothing_selected) +		{ +			showWearablesFolderView(); +			applyFolderViewFilter(FVIT_ALL); +		} + +		if (more_than_one_selected) +		{ +			showWearablesListView(); +			applyListViewFilter(LVIT_ALL); +		} + +		return;  	} + + +	//filter wearables by a type represented by a dummy item +	if (one_selected && is_dummy_item) +	{ +		onAddWearableClicked(); +		return; +	} + +	LLViewerInventoryItem* item = gInventory.getItem(ids[0]); +	if (!item && ids[0].notNull()) +	{ +		//Inventory misses an item with non-zero id +		showWearablesListView(); +		applyListViewFilter(LVIT_ALL); +		return; +	} + +	if (one_selected && !is_dummy_item) +	{ +		if (item->isWearableType()) +		{ +			//single clothing or bodypart item is selected +			showFilteredWearablesListView(item->getWearableType()); +			return; +		} +		else +		{ +			//attachment is selected +			showWearablesListView(); +			applyListViewFilter(LVIT_ATTACHMENT); +			return; +		} +	} +  } + +  void LLPanelOutfitEdit::update()  {  	mCOFWearables->refresh(); @@ -666,15 +750,17 @@ void LLPanelOutfitEdit::updateCurrentOutfitName()  void LLPanelOutfitEdit::updateVerbs()  {  	bool outfit_is_dirty = LLAppearanceMgr::getInstance()->isOutfitDirty(); +	bool outfit_locked = LLAppearanceMgr::getInstance()->isOutfitLocked();  	bool has_baseoutfit = LLAppearanceMgr::getInstance()->getBaseOutfitUUID().notNull(); -	mSaveComboBtn->setSaveBtnEnabled(outfit_is_dirty); +	mSaveComboBtn->setSaveBtnEnabled(!outfit_locked && outfit_is_dirty);  	childSetEnabled(REVERT_BTN, outfit_is_dirty && has_baseoutfit); -	mSaveComboBtn->setMenuItemEnabled("save_outfit", outfit_is_dirty); +	mSaveComboBtn->setMenuItemEnabled("save_outfit", !outfit_locked && outfit_is_dirty);  	mStatus->setText(outfit_is_dirty ? getString("unsaved_changes") : getString("now_editing")); +	updateCurrentOutfitName();  }  bool LLPanelOutfitEdit::switchPanels(LLPanel* switch_from_panel, LLPanel* switch_to_panel) @@ -699,12 +785,21 @@ void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button)  	LLMenuGL::showPopup(clicked_button, mGearMenu, 0, menu_y);  } -void LLPanelOutfitEdit::showFilteredWearableItemsList(LLWearableType::EType type) +void LLPanelOutfitEdit::onAddMoreButtonClicked() +{ +	toggleAddWearablesPanel(); +	filterWearablesBySelectedItem(); +} + +void LLPanelOutfitEdit::showFilteredWearablesListView(LLWearableType::EType type)  { -	mWearableListTypeCollector->setType(type); -	mWearableListManager->setFilterCollector(mWearableListTypeCollector);  	showAddWearablesPanel(true); -	showFilteredWearablesPanel(); +	showWearablesListView(); + +	//e_list_view_item_type implicitly contains LLWearableType::EType starting from LVIT_SHAPE +	applyListViewFilter((EListViewItemType) (LVIT_SHAPE + type));  } + +  // EOF diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h index 24ecf75c18..56c6c6d680 100644 --- a/indra/newview/llpaneloutfitedit.h +++ b/indra/newview/llpaneloutfitedit.h @@ -42,11 +42,13 @@  #include "llremoteparcelrequest.h"  #include "llinventory.h" +#include "llinventoryfunctions.h"  #include "llinventoryitemslist.h"  #include "llinventorymodel.h"  class LLButton;  class LLCOFWearables; +class LLComboBox;  class LLTextBox;  class LLInventoryCategory;  class LLOutfitObserver; @@ -68,21 +70,59 @@ class LLPanelOutfitEdit : public LLPanel  	LOG_CLASS(LLPanelOutfitEdit);  public: -	// NOTE: initialize mLookItemTypes at the index of any new enum you add in the LLPanelOutfitEdit() constructor -	typedef enum e_look_item_type +	// NOTE: initialize mFolderViewItemTypes at the index of any new enum you add in the LLPanelOutfitEdit() constructor +	typedef enum e_folder_view_item_type  	{ -		LIT_ALL = 0, -		LIT_WEARABLE, // clothing or shape -		LIT_ATTACHMENT, -		NUM_LOOK_ITEM_TYPES -	} ELookItemType;  +		FVIT_ALL = 0, +		FVIT_WEARABLE, // clothing or shape +		FVIT_ATTACHMENT, +		NUM_FOLDER_VIEW_ITEM_TYPES +	} EFolderViewItemType;  +	//should reflect order from LLWearableType::EType +	typedef enum e_list_view_item_type +	{ +		LVIT_ALL = 0, +		LVIT_CLOTHING, +		LVIT_BODYPART, +		LVIT_ATTACHMENT, +		LVIT_SHAPE, +		LVIT_SKIN, +		LVIT_HAIR, +		LVIT_EYES, +		LVIT_SHIRT, +		LVIT_PANTS, +		LVIT_SHOES, +		LVIT_SOCKS, +		LVIT_JACKET, +		LVIT_GLOVES, +		LVIT_UNDERSHIRT, +		LVIT_UNDERPANTS, +		LVIT_SKIRT, +		LVIT_ALPHA, +		LVIT_TATTOO, +		NUM_LIST_VIEW_ITEM_TYPES +	} EListViewItemType;  +  	struct LLLookItemType {  		std::string displayName;  		U64 inventoryMask;  		LLLookItemType() : displayName("NONE"), inventoryMask(0) {}  		LLLookItemType(std::string name, U64 mask) : displayName(name), inventoryMask(mask) {}  	}; + +	struct LLFilterItem { +		std::string displayName; +		LLInventoryCollectFunctor* collector; +		LLFilterItem() : displayName("NONE"), collector(NULL) {} +		LLFilterItem(std::string name, LLInventoryCollectFunctor* _collector) : displayName(name), collector(_collector) {} +		~LLFilterItem() { delete collector; } + +	//the struct is not supposed to by copied, either way the destructor kills collector +	//LLPointer is not used as it requires LLInventoryCollectFunctor to extend LLRefCount what it doesn't do +	private: +		LLFilterItem(const LLFilterItem& filter_item) {}; +	};  	LLPanelOutfitEdit();  	/*virtual*/ ~LLPanelOutfitEdit(); @@ -94,15 +134,31 @@ public:  	void toggleAddWearablesPanel();  	void showAddWearablesPanel(bool show__add_wearables); + +	//following methods operate with "add wearables" panel  	void showWearablesFilter(); -	void showFilteredWearablesPanel(); -	void showFilteredFolderWearablesPanel(); +	void showWearablesListView(); +	void showWearablesFolderView(); -	void onTypeFilterChanged(LLUICtrl* ctrl); +	void updateFiltersVisibility(); + +	void onFolderViewFilterCommitted(LLUICtrl* ctrl); +	void onListViewFilterCommitted(LLUICtrl* ctrl);  	void onSearchEdit(const std::string& string);  	void onInventorySelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);  	void onAddToOutfitClicked(void); -	void onOutfitItemSelectionChange(void); + +	void applyFolderViewFilter(EFolderViewItemType type); +	void applyListViewFilter(EListViewItemType type); + +	/** +	 * Filter items in views of Add Wearables Panel and show appropriate view depending on currently selected COF item(s) +	 * No COF items selected - shows the folder view, reset filter +	 * 1 COF item selected - shows the list view and filters wearables there by a wearable type of the selected item +	 * More than 1 COF item selected - shows the list view and filters it by a type of the selected item (attachment or clothing) +	 */ +	void filterWearablesBySelectedItem(void); +  	void onRemoveFromOutfitClicked(void);  	void onEditWearableClicked(void);  	void onAddWearableClicked(void); @@ -132,7 +188,8 @@ public:  private:  	void onGearButtonClick(LLUICtrl* clicked_button); -	void showFilteredWearableItemsList(LLWearableType::EType type); +	void onAddMoreButtonClicked(); +	void showFilteredWearablesListView(LLWearableType::EType type);  	LLTextBox*			mCurrentOutfitName; @@ -145,23 +202,26 @@ private:  	LLButton*			mFolderViewBtn;  	LLButton*			mListViewBtn;  	LLPanel*			mAddWearablesPanel; - -	LLFindNonLinksByMask*  mWearableListMaskCollector; -	LLFindWearablesOfType* mWearableListTypeCollector; +	 +	LLComboBox*			mFolderViewFilterCmbBox; +	LLComboBox*			mListViewFilterCmbBox;  	LLFilteredWearableListManager* 	mWearableListManager;  	LLInventoryItemsList* 			mWearableItemsList; -	LLPanel*						mWearableItemsPanel; +	LLPanel*						mWearablesListViewPanel;  	LLCOFDragAndDropObserver* mCOFDragAndDropObserver; -	std::vector<LLLookItemType> mLookItemTypes; +	std::vector<LLLookItemType> mFolderViewItemTypes; +	std::vector<LLFilterItem*> mListViewItemTypes;  	LLCOFWearables*		mCOFWearables;  	LLMenuGL*			mGearMenu;  	bool				mInitialized;  	std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn; + +  };  #endif // LL_LLPANELOUTFITEDIT_H diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 8836672f91..5563214407 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -91,6 +91,7 @@ public:  		registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2));  		enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenu::onEnable, this, _2)); +		enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenu::onVisible, this, _2));  		mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(  			"menu_outfit_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); @@ -99,6 +100,28 @@ public:  	LLMenuGL* getMenu() { return mMenu; } +	void show(LLView* spawning_view) +	{ +		if (!mMenu) return; + +		updateItemsVisibility(); +		mMenu->buildDrawLabels(); +		mMenu->updateParent(LLMenuGL::sMenuContainer); +		S32 menu_x = 0; +		S32 menu_y = spawning_view->getRect().getHeight() + mMenu->getRect().getHeight(); +		LLMenuGL::showPopup(spawning_view, mMenu, menu_x, menu_y); +	} + +	void updateItemsVisibility() +	{ +		if (!mMenu) return; + +		bool have_selection = getSelectedOutfitID().notNull(); +		mMenu->setItemVisible("sepatator1", have_selection); +		mMenu->setItemVisible("sepatator2", have_selection); +		mMenu->arrangeAndClear(); // update menu height +	} +  private:  	const LLUUID& getSelectedOutfitID()  	{ @@ -169,6 +192,31 @@ private:  	bool onEnable(LLSD::String param)  	{  		const LLUUID& selected_outfit_id = getSelectedOutfitID(); +		if (selected_outfit_id.isNull()) // no selection or invalid outfit selected +		{ +			return false; +		} + +		if ("rename" == param) +		{ +			return get_is_category_renameable(&gInventory, selected_outfit_id); +		} +		else if ("delete" == param) +		{ +			return LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit_id); +		} + +		return true; +	} + +	bool onVisible(LLSD::String param) +	{ +		const LLUUID& selected_outfit_id = getSelectedOutfitID(); +		if (selected_outfit_id.isNull()) // no selection or invalid outfit selected +		{ +			return false; +		} +  		bool is_worn = LLAppearanceMgr::instance().getBaseOutfitUUID() == selected_outfit_id;  		if ("wear" == param) @@ -179,14 +227,6 @@ private:  		{  			return is_worn;  		} -		else if ("rename" == param) -		{ -			return get_is_category_renameable(&gInventory, selected_outfit_id); -		} -		else if ("delete" == param) -		{ -			return LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit_id); -		}  		return true;  	} @@ -205,10 +245,12 @@ LLPanelOutfitsInventory::LLPanelOutfitsInventory() :  	mSavedFolderState = new LLSaveFolderState();  	mSavedFolderState->setApply(FALSE);  	gAgentWearables.addLoadedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoaded, this)); +	gAgentWearables.addLoadingStartedCallback(boost::bind(&LLPanelOutfitsInventory::onWearablesLoading, this));  	LLOutfitObserver& observer = LLOutfitObserver::instance();  	observer.addBOFChangedCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));  	observer.addCOFChangedCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this)); +	observer.addOutfitLockChangedCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));  }  LLPanelOutfitsInventory::~LLPanelOutfitsInventory() @@ -341,7 +383,6 @@ void LLPanelOutfitsInventory::onWearButtonClick()  	if (!isCOFPanelActive())  	{  		mMyOutfitsPanel->performAction("replaceoutfit"); -		setWearablesLoading(true);  	}  	else  	{ @@ -522,28 +563,21 @@ void LLPanelOutfitsInventory::updateListCommands()  {  	bool trash_enabled = isActionEnabled("delete");  	bool wear_enabled = isActionEnabled("wear"); -	bool make_outfit_enabled = isActionEnabled("make_outfit"); +	bool wear_visible = !isCOFPanelActive(); +	bool make_outfit_enabled = isActionEnabled("save_outfit");  	mListCommands->childSetEnabled("trash_btn", trash_enabled);  	mListCommands->childSetEnabled("wear_btn", wear_enabled); -	mListCommands->childSetVisible("wear_btn", wear_enabled); +	mListCommands->childSetVisible("wear_btn", wear_visible);  	mSaveComboBtn->setMenuItemEnabled("save_outfit", make_outfit_enabled);  }  void LLPanelOutfitsInventory::showGearMenu()  { -	LLMenuGL* menu = mGearMenu ? mGearMenu->getMenu() : NULL; -	if (menu) -	{ -		menu->buildDrawLabels(); -		menu->updateParent(LLMenuGL::sMenuContainer); -		LLView* spawning_view = getChild<LLView>("options_gear_btn"); -		S32 menu_x, menu_y; -		//show menu in co-ordinates of panel -		spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this); -		menu_y += menu->getRect().getHeight(); -		LLMenuGL::showPopup(this, menu, menu_x, menu_y); -	} +	if (!mGearMenu) return; + +	LLView* spawning_view = getChild<LLView>("options_gear_btn"); +	mGearMenu->show(spawning_view);  }  void LLPanelOutfitsInventory::onTrashButtonClick() @@ -554,11 +588,25 @@ void LLPanelOutfitsInventory::onTrashButtonClick()  void LLPanelOutfitsInventory::onClipboardAction(const LLSD& userdata)  {  	std::string command_name = userdata.asString(); -	// TODO: add handling "My Outfits" tab.  	if (isCOFPanelActive())  	{  		getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);  	} +	else // "My Outfits" tab active +	{ +		if (command_name == "delete") +		{ +			const LLUUID& selected_outfit_id = mMyOutfitsPanel->getSelectedOutfitUUID(); +			if (selected_outfit_id.notNull()) +			{ +				remove_category(&gInventory, selected_outfit_id); +			} +		} +		else +		{ +			llwarns << "Unrecognized action" << llendl; +		} +	}  	updateListCommands();  	updateVerbs();  } @@ -613,7 +661,6 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)  	{  		BOOL can_delete = FALSE; -		// TODO: add handling "My Outfits" tab.  		if (isCOFPanelActive())  		{  			LLFolderView* root = getActivePanel()->getRootFolder(); @@ -629,10 +676,15 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)  					LLFolderViewItem *item = root->getItemByID(item_id);  					can_delete &= item->getListener()->isItemRemovable();  				} -				return can_delete;  			}  		} -		return FALSE; +		else // "My Outfits" tab active +		{ +			const LLUUID& selected_outfit = mMyOutfitsPanel->getSelectedOutfitUUID(); +			can_delete = LLAppearanceMgr::instance().getCanRemoveOutfit(selected_outfit); +		} + +		return can_delete;  	}  	if (command_name == "remove_link")  	{ @@ -667,10 +719,14 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)  		{  			return FALSE;  		} +		return hasItemsSelected();  	} -	if (command_name == "make_outfit") +	if (command_name == "save_outfit")  	{ -		return LLAppearanceMgr::getInstance()->isOutfitDirty(); +		bool outfit_locked = LLAppearanceMgr::getInstance()->isOutfitLocked(); +		bool outfit_dirty =LLAppearanceMgr::getInstance()->isOutfitDirty(); +		// allow save only if outfit isn't locked and is dirty +		return !outfit_locked && outfit_dirty;  	}  	if (command_name == "edit" ||  @@ -686,7 +742,6 @@ bool LLPanelOutfitsInventory::hasItemsSelected()  {  	bool has_items_selected = false; -	// TODO: add handling "My Outfits" tab.  	if (isCOFPanelActive())  	{  		LLFolderView* root = getActivePanel()->getRootFolder(); @@ -696,6 +751,10 @@ bool LLPanelOutfitsInventory::hasItemsSelected()  			has_items_selected = (selection_set.size() > 0);  		}  	} +	else // My Outfits Tab is active +	{ +		has_items_selected = mMyOutfitsPanel->getSelectedOutfitUUID().notNull(); +	}  	return has_items_selected;  } @@ -726,6 +785,7 @@ void LLPanelOutfitsInventory::initTabPanels()  	mCurrentOutfitPanel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onTabSelectionChange, this, mCurrentOutfitPanel, _1, _2));  	mMyOutfitsPanel = getChild<LLOutfitsList>(OUTFITS_TAB_NAME); +	mMyOutfitsPanel->addSelectionChangeCallback(boost::bind(&LLPanelOutfitsInventory::updateVerbs, this));  	mAppearanceTabs = getChild<LLTabContainer>("appearance_tabs");  	mAppearanceTabs->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::onTabChange, this)); @@ -794,6 +854,11 @@ void LLPanelOutfitsInventory::onWearablesLoaded()  	setWearablesLoading(false);  } +void LLPanelOutfitsInventory::onWearablesLoading() +{ +	setWearablesLoading(true); +} +  // static  LLSidepanelAppearance* LLPanelOutfitsInventory::getAppearanceSP()  { diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h index d58ae554b0..863dc9dd7c 100644 --- a/indra/newview/llpaneloutfitsinventory.h +++ b/indra/newview/llpaneloutfitsinventory.h @@ -127,6 +127,7 @@ protected:  	bool hasItemsSelected();  	void setWearablesLoading(bool val);  	void onWearablesLoaded(); +	void onWearablesLoading();  private:  	LLPanel*					mListCommands;  	LLOutfitListGearMenu*		mGearMenu; diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp index c8abcc83c4..1f979b0ef1 100644 --- a/indra/newview/llpanelplaceprofile.cpp +++ b/indra/newview/llpanelplaceprofile.cpp @@ -84,7 +84,9 @@ LLPanelPlaceProfile::LLPanelPlaceProfile()  // virtual  LLPanelPlaceProfile::~LLPanelPlaceProfile() -{} +{ +	gIdleCallbacks.deleteFunction(&LLPanelPlaceProfile::updateYouAreHereBanner, this); +}  // virtual  BOOL LLPanelPlaceProfile::postBuild() diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp index e8b6c6bfe5..494cba8c6f 100644 --- a/indra/newview/llpanelteleporthistory.cpp +++ b/indra/newview/llpanelteleporthistory.cpp @@ -564,6 +564,7 @@ void LLTeleportHistoryPanel::updateVerbs()  	{  		mTeleportBtn->setEnabled(false);  		mShowProfile->setEnabled(false); +		mShowOnMapBtn->setEnabled(false);  		return;  	} @@ -571,7 +572,7 @@ void LLTeleportHistoryPanel::updateVerbs()  	mTeleportBtn->setEnabled(NULL != itemp);  	mShowProfile->setEnabled(NULL != itemp); -	mShowOnMapBtn->setEnabled(true); +	mShowOnMapBtn->setEnabled(NULL != itemp);  }  void LLTeleportHistoryPanel::getNextTab(const LLDate& item_date, S32& tab_idx, LLDate& tab_date) diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp index a27afeab7c..8fe78a0f81 100644 --- a/indra/newview/llparticipantlist.cpp +++ b/indra/newview/llparticipantlist.cpp @@ -52,6 +52,18 @@  static const LLAvatarItemAgentOnTopComparator AGENT_ON_TOP_NAME_COMPARATOR; +// helper function to update AvatarList Item's indicator in the voice participant list +static void update_speaker_indicator(const LLAvatarList* const avatar_list, const LLUUID& avatar_uuid, bool is_muted) +{ +	LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(avatar_list->getItemByValue(avatar_uuid)); +	if (item) +	{ +		LLOutputMonitorCtrl* indicator = item->getChild<LLOutputMonitorCtrl>("speaking_indicator"); +		indicator->setIsMuted(is_muted); +	} +} + +  // See EXT-4301.  /**   * class LLAvalineUpdater - observe the list of voice participants in session and check @@ -354,6 +366,20 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)  				}  			}  		} + +		// update voice mute state of all items. See EXT-7235 +		LLSpeakerMgr::speaker_list_t speaker_list; + +		// Use also participants which are not in voice session now (the second arg is TRUE). +		// They can already have mModeratorMutedVoice set from the previous voice session +		// and LLSpeakerVoiceModerationEvent will not be sent when speaker manager is updated next time. +		mSpeakerMgr->getSpeakerList(&speaker_list, TRUE); +		for(LLSpeakerMgr::speaker_list_t::iterator it = speaker_list.begin(); it != speaker_list.end(); it++) +		{ +			const LLPointer<LLSpeaker>& speakerp = *it; + +			update_speaker_indicator(list, speakerp->mID, speakerp->mModeratorMutedVoice); +		}  	}  } @@ -506,12 +532,7 @@ bool LLParticipantList::onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event  	// update UI on confirmation of moderator mutes  	if (event->getValue().asString() == "voice")  	{ -		LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(mAvatarList->getItemByValue(speakerp->mID)); -		if (item) -		{ -			LLOutputMonitorCtrl* indicator = item->getChild<LLOutputMonitorCtrl>("speaking_indicator"); -			indicator->setIsMuted(speakerp->mModeratorMutedVoice); -		} +		update_speaker_indicator(mAvatarList, speakerp->mID, speakerp->mModeratorMutedVoice);  	}  	return true;  } diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp index e23643da0b..e2d4f5ad45 100644 --- a/indra/newview/llsidepanelappearance.cpp +++ b/indra/newview/llsidepanelappearance.cpp @@ -83,6 +83,7 @@ LLSidepanelAppearance::LLSidepanelAppearance() :  	mOpened(false)  {  	LLOutfitObserver& outfit_observer =  LLOutfitObserver::instance(); +	outfit_observer.addBOFReplacedCallback(boost::bind(&LLSidepanelAppearance::refreshCurrentOutfitName, this, ""));  	outfit_observer.addBOFChangedCallback(boost::bind(&LLSidepanelAppearance::refreshCurrentOutfitName, this, ""));  	outfit_observer.addCOFChangedCallback(boost::bind(&LLSidepanelAppearance::refreshCurrentOutfitName, this, ""));  } @@ -352,12 +353,12 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we  	if (visible)  	{ -		mEditWearable->setWearable(wearable); -		mEditWearable->onOpen(LLSD()); // currently no-op, just for consistency  		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )  		{  			gAgentCamera.changeCameraToCustomizeAvatar();  		} +		mEditWearable->setWearable(wearable); +		mEditWearable->onOpen(LLSD()); // currently no-op, just for consistency  	}  	else  	{ diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp index 9406f80b75..fed39c362e 100644 --- a/indra/newview/llsidetray.cpp +++ b/indra/newview/llsidetray.cpp @@ -35,6 +35,7 @@  #include "lltextbox.h"  #include "llagentcamera.h" +#include "llappviewer.h"  #include "llbottomtray.h"  #include "llsidetray.h"  #include "llviewerwindow.h" @@ -272,9 +273,18 @@ BOOL LLSideTray::postBuild()  		collapseSideBar();  	setMouseOpaque(false); + +	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLSideTray::handleLoginComplete, this)); +  	return true;  } +void LLSideTray::handleLoginComplete() +{ +	//reset tab to "home" tab if it was changesd during login process +	selectTabByName("sidebar_home"); +} +  LLSideTrayTab* LLSideTray::getTab(const std::string& name)  {  	return getChild<LLSideTrayTab>(name,false); diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h index e176ff5aff..3a8d308425 100644 --- a/indra/newview/llsidetray.h +++ b/indra/newview/llsidetray.h @@ -161,6 +161,8 @@ public:  	commit_signal_t& getCollapseSignal() { return mCollapseSignal; } +	void		handleLoginComplete(); +  protected:  	LLSideTrayTab* getTab		(const std::string& name); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index e51e6363dd..df5be34e39 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -199,7 +199,6 @@  #include "llstartuplistener.h"  #if LL_WINDOWS -#include "llwindebug.h"  #include "lldxhardware.h"  #endif @@ -781,9 +780,6 @@ bool idle_startup()  		gViewerWindow->getWindow()->show();  		display_startup(); -		//DEV-10530.  do cleanup.  remove at some later date.  jan-2009 -		LLFloaterPreference::cleanupBadSetting(); -  		// DEV-16927.  The following code removes errant keystrokes that happen while the window is being   		// first made visible.  #ifdef _WIN32 @@ -2498,8 +2494,7 @@ void LLStartUp::saveInitialOutfit()  	{  		sWearablesLoadedCon.disconnect();  	} - -	LLAppearanceMgr::getInstance()->makeNewOutfitLinks(sInitialOutfit); +	LLAppearanceMgr::getInstance()->makeNewOutfitLinks(sInitialOutfit,false);  }  std::string& LLStartUp::getInitialOutfitName() diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp index 6c6eda2e68..db1f4dc4cb 100644 --- a/indra/newview/lltoastalertpanel.cpp +++ b/indra/newview/lltoastalertpanel.cpp @@ -172,6 +172,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal  	params.tab_stop(false);  	params.wrap(true);  	params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP); +	params.allow_scroll(true);  	LLTextBox * msg_box = LLUICtrlFactory::create<LLTextBox> (params);  	// Compute max allowable height for the dialog text, so we can allocate @@ -180,9 +181,16 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal  			gFloaterView->getRect().getHeight()  			- LINE_HEIGHT			// title bar  			- 3*VPAD - BTN_HEIGHT; +	// reshape to calculate real text width and height  	msg_box->reshape( MAX_ALLOWED_MSG_WIDTH, max_allowed_msg_height );  	msg_box->setValue(msg); -	msg_box->reshapeToFitText(); + +	S32 pixel_width = msg_box->getTextPixelWidth(); +	S32 pixel_height = msg_box->getTextPixelHeight(); + +	// We should use some space to prevent set textbox's scroller visible when it is unnecessary. +	msg_box->reshape( llmin(MAX_ALLOWED_MSG_WIDTH,pixel_width + 2 * msg_box->getHPad() + HPAD), +		llmin(max_allowed_msg_height,pixel_height + 2 * msg_box->getVPad())  ) ;  	const LLRect& text_rect = msg_box->getRect();  	S32 dialog_width = llmax( btn_total_width, text_rect.getWidth() ) + 2 * HPAD; diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp index 033d35d80a..56b5d7467c 100644 --- a/indra/newview/llviewerfoldertype.cpp +++ b/indra/newview/llviewerfoldertype.cpp @@ -43,13 +43,16 @@ struct ViewerFolderEntry : public LLDictionaryEntry  {  	// Constructor for non-ensembles  	ViewerFolderEntry(const std::string &new_category_name, // default name when creating a new category of this type -					  const std::string &icon_name,			// name of the folder icon -					  BOOL is_quiet							// folder doesn't need a UI update when changed +					  const std::string &icon_name_open,	// name of the folder icon +					  const std::string &icon_name_closed, +					  BOOL is_quiet,						// folder doesn't need a UI update when changed +					  const std::string &dictionary_name = empty_string // no reverse lookup needed on non-ensembles, so in most cases just leave this blank  		)   		: -		LLDictionaryEntry(empty_string), // no reverse lookup needed on non-ensembles, so just leave this blank -		mIconName(icon_name), +		LLDictionaryEntry(dictionary_name),  		mNewCategoryName(new_category_name), +		mIconNameOpen(icon_name_open), +		mIconNameClosed(icon_name_closed),  		mIsQuiet(is_quiet)  	{  		mAllowedNames.clear(); @@ -63,7 +66,11 @@ struct ViewerFolderEntry : public LLDictionaryEntry  		)   		:  		LLDictionaryEntry(xui_name), -		mIconName(icon_name), +		/* Just use default icons until we actually support ensembles +		mIconNameOpen(icon_name), +		mIconNameClosed(icon_name), +		*/ +		mIconNameOpen("Inv_FolderOpen"), mIconNameClosed("Inv_FolderClosed"),  		mNewCategoryName(new_category_name),  		mIsQuiet(FALSE)  	{ @@ -84,7 +91,8 @@ struct ViewerFolderEntry : public LLDictionaryEntry  		}  		return false;  	} -	const std::string mIconName; +	const std::string mIconNameOpen; +	const std::string mIconNameClosed;  	const std::string mNewCategoryName;  	typedef std::vector<std::string> name_vec_t;  	name_vec_t mAllowedNames; @@ -104,31 +112,31 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()  {  	initEnsemblesFromFile(); -	//       													    	  NEW CATEGORY NAME         FOLDER ICON NAME                QUIET? -	//      												  		     |-------------------------|-------------------------------|-----------| -	addEntry(LLFolderType::FT_TEXTURE, 				new ViewerFolderEntry("Textures",				"inv_folder_texture.tga",		FALSE)); -	addEntry(LLFolderType::FT_SOUND, 				new ViewerFolderEntry("Sounds",					"inv_folder_sound.tga",			FALSE)); -	addEntry(LLFolderType::FT_CALLINGCARD, 			new ViewerFolderEntry("Calling Cards",			"inv_folder_callingcard.tga",	FALSE)); -	addEntry(LLFolderType::FT_LANDMARK, 			new ViewerFolderEntry("Landmarks",				"inv_folder_landmark.tga",		FALSE)); -	addEntry(LLFolderType::FT_CLOTHING, 			new ViewerFolderEntry("Clothing",				"inv_folder_clothing.tga",		FALSE)); -	addEntry(LLFolderType::FT_OBJECT, 				new ViewerFolderEntry("Objects",				"inv_folder_object.tga",		FALSE)); -	addEntry(LLFolderType::FT_NOTECARD, 			new ViewerFolderEntry("Notecards",				"inv_folder_notecard.tga",		FALSE)); -	addEntry(LLFolderType::FT_ROOT_INVENTORY, 		new ViewerFolderEntry("My Inventory",			"",								FALSE)); -	addEntry(LLFolderType::FT_LSL_TEXT, 			new ViewerFolderEntry("Scripts",				"inv_folder_script.tga",		FALSE)); -	addEntry(LLFolderType::FT_BODYPART, 			new ViewerFolderEntry("Body Parts",				"inv_folder_bodypart.tga",		FALSE)); -	addEntry(LLFolderType::FT_TRASH, 				new ViewerFolderEntry("Trash",					"inv_folder_trash.tga",			TRUE)); -	addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, 	new ViewerFolderEntry("Photo Album",			"inv_folder_snapshot.tga",		FALSE)); -	addEntry(LLFolderType::FT_LOST_AND_FOUND, 		new ViewerFolderEntry("Lost And Found",	   		"inv_folder_lostandfound.tga",	TRUE)); -	addEntry(LLFolderType::FT_ANIMATION, 			new ViewerFolderEntry("Animations",				"inv_folder_animation.tga",		FALSE)); -	addEntry(LLFolderType::FT_GESTURE, 				new ViewerFolderEntry("Gestures",				"inv_folder_gesture.tga",		FALSE)); -	addEntry(LLFolderType::FT_FAVORITE, 			new ViewerFolderEntry("Favorites",				"inv_folder_plain_closed.tga",	FALSE)); +	//       													    	  NEW CATEGORY NAME         FOLDER OPEN             FOLDER CLOSED          QUIET? +	//      												  		     |-------------------------|-----------------------|----------------------|-----------| +	addEntry(LLFolderType::FT_TEXTURE, 				new ViewerFolderEntry("Textures",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_SOUND, 				new ViewerFolderEntry("Sounds",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_CALLINGCARD, 			new ViewerFolderEntry("Calling Cards",			"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_LANDMARK, 			new ViewerFolderEntry("Landmarks",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_CLOTHING, 			new ViewerFolderEntry("Clothing",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_OBJECT, 				new ViewerFolderEntry("Objects",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_NOTECARD, 			new ViewerFolderEntry("Notecards",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_ROOT_INVENTORY, 		new ViewerFolderEntry("My Inventory",			"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_LSL_TEXT, 			new ViewerFolderEntry("Scripts",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_BODYPART, 			new ViewerFolderEntry("Body Parts",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_TRASH, 				new ViewerFolderEntry("Trash",					"Inv_TrashOpen",		"Inv_TrashClosed",		TRUE)); +	addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, 	new ViewerFolderEntry("Photo Album",			"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_LOST_AND_FOUND, 		new ViewerFolderEntry("Lost And Found",	   		"Inv_LostOpen",			"Inv_LostClosed",		TRUE)); +	addEntry(LLFolderType::FT_ANIMATION, 			new ViewerFolderEntry("Animations",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_GESTURE, 				new ViewerFolderEntry("Gestures",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); +	addEntry(LLFolderType::FT_FAVORITE, 			new ViewerFolderEntry("Favorites",				"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); -	addEntry(LLFolderType::FT_CURRENT_OUTFIT, 		new ViewerFolderEntry("Current Outfit",			"inv_folder_current_outfit.tga",TRUE)); -	addEntry(LLFolderType::FT_OUTFIT, 				new ViewerFolderEntry("New Outfit",				"inv_folder_outfit.tga",		TRUE)); -	addEntry(LLFolderType::FT_MY_OUTFITS, 			new ViewerFolderEntry("My Outfits",				"inv_folder_my_outfits.tga",	TRUE)); -	addEntry(LLFolderType::FT_INBOX, 				new ViewerFolderEntry("Inbox",					"inv_folder_inbox.tga",			FALSE)); +	addEntry(LLFolderType::FT_CURRENT_OUTFIT, 		new ViewerFolderEntry("Current Outfit",			"Inv_SysOpen",			"Inv_SysClosed",		TRUE)); +	addEntry(LLFolderType::FT_OUTFIT, 				new ViewerFolderEntry("New Outfit",				"Inv_LookFolderOpen",	"Inv_LookFolderClosed",	TRUE)); +	addEntry(LLFolderType::FT_MY_OUTFITS, 			new ViewerFolderEntry("My Outfits",				"Inv_SysOpen",			"Inv_SysClosed",		TRUE)); +	addEntry(LLFolderType::FT_INBOX, 				new ViewerFolderEntry("Inbox",					"Inv_SysOpen",			"Inv_SysClosed",		FALSE)); -	addEntry(LLFolderType::FT_NONE, 				new ViewerFolderEntry("New Folder",				"inv_folder_plain_closed.tga",	FALSE)); +	addEntry(LLFolderType::FT_NONE, 				new ViewerFolderEntry("New Folder",				"Inv_FolderOpen",		"Inv_FolderClosed",		FALSE, "default"));  }  bool LLViewerFolderDictionary::initEnsemblesFromFile() @@ -213,12 +221,15 @@ LLFolderType::EType LLViewerFolderType::lookupTypeFromXUIName(const std::string  	return LLViewerFolderDictionary::getInstance()->lookup(name);  } -const std::string &LLViewerFolderType::lookupIconName(LLFolderType::EType folder_type) +const std::string &LLViewerFolderType::lookupIconName(LLFolderType::EType folder_type, BOOL is_open)  {  	const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type);  	if (entry)  	{ -		return entry->mIconName; +		if (is_open) +			return entry->mIconNameOpen; +		else +			return entry->mIconNameClosed;  	}  	return badLookup();  } diff --git a/indra/newview/llviewerfoldertype.h b/indra/newview/llviewerfoldertype.h index dd9360da90..3744ac20f8 100644 --- a/indra/newview/llviewerfoldertype.h +++ b/indra/newview/llviewerfoldertype.h @@ -44,7 +44,7 @@ public:  	static const std::string&   lookupXUIName(EType folder_type); // name used by the UI  	static LLFolderType::EType 	lookupTypeFromXUIName(const std::string& name); -	static const std::string&   lookupIconName(EType folder_type); // folder icon name +	static const std::string&   lookupIconName(EType folder_type, BOOL is_open = FALSE); // folder icon name  	static BOOL					lookupIsQuietType(EType folder_type); // folder doesn't require UI update when changes have occured  	static const std::string&	lookupNewCategoryName(EType folder_type); // default name when creating new category  	static LLFolderType::EType	lookupTypeFromNewCategoryName(const std::string& name); // default name when creating new category diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index face7124c2..40f15fe86a 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -883,12 +883,8 @@ void ModifiedCOFCallback::fire(const LLUUID& inv_item)  {  	LLAppearanceMgr::instance().updateAppearanceFromCOF(); -	if (LLSideTray::getInstance()->isPanelActive("sidepanel_appearance")) -	{ -		// *HACK: Edit the wearable that has just been worn -		//        only if the Appearance SP is currently opened. -		LLAgentWearables::editWearable(inv_item); -	} +	// Start editing the item if previously requested. +	gAgentWearables.editWearableIfRequested(inv_item);  	// TODO: camera mode may not be changed if a debug setting is tweaked  	if( gAgentCamera.cameraCustomizeAvatar() ) diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 5836aff4e7..3d107555bf 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -109,10 +109,6 @@  #include <boost/algorithm/string/split.hpp> //  #include <boost/regex.hpp> -#if LL_WINDOWS // For Windows specific error handler -#include "llwindebug.h"	// For the invalid message handler -#endif -  #include "llnotificationmanager.h" //  #if LL_MSVC @@ -2063,7 +2059,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)  				// initiated by the other party) then...  				std::string my_name;  				LLAgentUI::buildFullname(my_name); -				std::string response = gSavedPerAccountSettings.getString("BusyModeResponse2"); +				std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");  				pack_instant_message(  					gMessageSystem,  					gAgent.getID(), @@ -2736,7 +2732,7 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id)  	{  		std::string my_name;  		LLAgentUI::buildFullname(my_name); -		std::string response = gSavedPerAccountSettings.getString("BusyModeResponse2"); +		std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");  		pack_instant_message(  			gMessageSystem,  			gAgent.getID(), diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 7e779986df..9b5b210bf7 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -541,11 +541,6 @@ void LLViewerTexture::setBoostLevel(S32 level)  		if(mBoostLevel != LLViewerTexture::BOOST_NONE)  		{  			setNoDelete() ;		 - -			if(LLViewerTexture::BOOST_AVATAR_BAKED_SELF == mBoostLevel || LLViewerTexture::BOOST_AVATAR_BAKED == mBoostLevel) -			{ -				mCanResetMaxVirtualSize = false ; -			}  		}  		if(gAuditTexture)  		{ @@ -596,6 +591,11 @@ void LLViewerTexture::forceImmediateUpdate()  {  } +void LLViewerTexture::setResetMaxVirtualSizeFlag(bool flag)  +{ +	mCanResetMaxVirtualSize = flag ; +} +  void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const   {  	if(needs_gltexture) diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 1bd4cc793d..361f56e02f 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -166,6 +166,7 @@ public:  	void addTextureStats(F32 virtual_size, BOOL needs_gltexture = TRUE) const;  	void resetTextureStats();	 +	void setResetMaxVirtualSizeFlag(bool flag) ;  	virtual F32  getMaxVirtualSize() ; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 83556452c0..0a65cb7330 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1591,6 +1591,9 @@ void LLViewerWindow::initBase()  	gDebugView->init();  	gToolTipView = getRootView()->getChild<LLToolTipView>("tooltip view"); +	// Initialize busy response message when logged in +	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initBusyResponse)); +  	// Add the progress bar view (startup view), which overrides everything  	mProgressView = getRootView()->getChild<LLProgressView>("progress_view");  	setShowProgress(FALSE); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 1fa953f157..3e93dc1a90 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -4210,9 +4210,14 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel  	mMaxPixelArea = llmax(pixel_area, mMaxPixelArea);  	mMinPixelArea = llmin(pixel_area, mMinPixelArea);  	imagep->resetTextureStats(); +	imagep->setResetMaxVirtualSizeFlag(false) ;  	imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures.  	imagep->addTextureStats(pixel_area / texel_area_ratio);  	imagep->setBoostLevel(boost_level); +	if(boost_level == LLViewerTexture::BOOST_AVATAR_BAKED_SELF) +	{ +		imagep->setAdditionalDecodePriority(1.0f) ; +	}  }  //virtual	 diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index eae92f8992..a4d888cd72 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -975,12 +975,6 @@ void LLVOAvatarSelf::wearableUpdated( LLWearableType::EType type, BOOL upload_re  		const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;  		const LLVOAvatarDefines::EBakedTextureIndex index = baked_iter->first; -		// if we're editing our appearance, ensure that we're not using baked textures -		// The baked texture for alpha masks is set explicitly when you hit "save" -		if (gAgentCamera.cameraCustomizeAvatar()) -		{ -			setNewBakedTexture(index,IMG_DEFAULT_AVATAR); -		}  		if (baked_dict)  		{  			for (LLVOAvatarDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin(); @@ -2036,7 +2030,11 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe  			F32 desired_pixels;  			desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());  			imagep->setBoostLevel(getAvatarBoostLevel()); + +			imagep->resetTextureStats(); +			imagep->setResetMaxVirtualSizeFlag(false) ;  			imagep->addTextureStats( desired_pixels / texel_area_ratio ); +			imagep->setAdditionalDecodePriority(1.0f) ;  			imagep->forceUpdateBindStats() ;  			if (imagep->getDiscardLevel() < 0)  			{ diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 96bde129ee..4dc9edb247 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -402,19 +402,16 @@ void LLVivoxVoiceClient::init(LLPumpIO *pump)  void LLVivoxVoiceClient::terminate()  { - -//	leaveAudioSession(); -	logout(); -	// As of SDK version 4885, this should no longer be necessary.  It will linger after the socket close if it needs to. -	// ms_sleep(2000); -	connectorShutdown(); -	closeSocket();		// Need to do this now -- bad things happen if the destructor does it later. -	 -	// This will do unpleasant things on windows. -//	killGateway(); -	 - - +	if(mConnected) +	{ +		logout(); +		connectorShutdown(); +		closeSocket();		// Need to do this now -- bad things happen if the destructor does it later.	 +	} +	else +	{ +		killGateway(); +	}  }  const LLVoiceVersionInfo& LLVivoxVoiceClient::getVersion() @@ -5287,6 +5284,7 @@ void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)  			LLVoiceChannel::getCurrentVoiceChannel()->deactivate();  			status = LLVoiceClientStatusObserver::STATUS_VOICE_DISABLED;  		} +		notifyStatusObservers(status);		  	}  } diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp index 121e691710..46c736c853 100644 --- a/indra/newview/llwearable.cpp +++ b/indra/newview/llwearable.cpp @@ -705,7 +705,7 @@ void LLWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake  	}  	gAgentAvatarp->updateVisualParams(); -	gAgentAvatarp->wearableUpdated(type, TRUE); +	gAgentAvatarp->wearableUpdated(type, FALSE);  //	if( upload_bake )  //	{ diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index 6c410cf7a5..f86838194e 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -38,7 +38,6 @@  #include "llagentwearables.h"  #include "llappearancemgr.h"  #include "llinventoryfunctions.h" -#include "llinventorymodel.h"  #include "llmenugl.h" // for LLContextMenu  #include "lltransutil.h"  #include "llviewerattachmenu.h" @@ -89,8 +88,6 @@ void LLPanelWearableListItem::onMouseLeave(S32 x, S32 y, MASK mask)  LLPanelWearableListItem::LLPanelWearableListItem(LLViewerInventoryItem* item)  : LLPanelInventoryListItemBase(item)  { -	// icons should not be shown for this type of items (EXT-7511) -	mForceNoLinksOnIcons = true;  }  ////////////////////////////////////////////////////////////////////////// @@ -129,6 +126,19 @@ BOOL LLPanelWearableOutfitItem::handleDoubleClick(S32 x, S32 y, MASK mask)  	return LLUICtrl::handleDoubleClick(x, y, mask);  } +// virtual +void LLPanelWearableOutfitItem::updateItem(const std::string& name) +{ +	std::string search_label = name; + +	if (mItem && get_is_item_worn(mItem->getUUID())) +	{ +		search_label += LLTrans::getString("worn"); +	} + +	LLPanelInventoryListItemBase::updateItem(search_label); +} +  LLPanelWearableOutfitItem::LLPanelWearableOutfitItem(LLViewerInventoryItem* item)  : LLPanelInventoryListItemBase(item)  { @@ -295,22 +305,16 @@ LLPanelDummyClothingListItem* LLPanelDummyClothingListItem::create(LLWearableTyp  	return list_item;  } -void LLPanelDummyClothingListItem::updateItem() -{ -	std::string title = wearableTypeToString(mWearableType); -	setTitle(title, LLStringUtil::null); -} -  BOOL LLPanelDummyClothingListItem::postBuild()  {  	LLIconCtrl* icon = getChild<LLIconCtrl>("item_icon");  	setIconCtrl(icon);  	setTitleCtrl(getChild<LLTextBox>("item_name")); -	addWidgetToRightSide("btn_add"); +	addWidgetToRightSide("btn_add_panel"); -	setIconImage(LLInventoryIcon::getIcon(LLAssetType::AT_CLOTHING, LLInventoryType::IT_NONE, FALSE, mWearableType, FALSE)); -	updateItem(); +	setIconImage(LLInventoryIcon::getIcon(LLAssetType::AT_CLOTHING, LLInventoryType::IT_NONE, mWearableType, FALSE)); +	updateItem(wearableTypeToString(mWearableType));  	// Make it look loke clothing item - reserve space for 'delete' button  	setLeftWidgetsWidth(icon->getRect().mLeft); @@ -455,15 +459,17 @@ static const LLWearableItemTypeNameComparator WEARABLE_TYPE_NAME_COMPARATOR;  static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list");  LLWearableItemsList::Params::Params() -:	use_internal_context_menu("use_internal_context_menu", true) +:	standalone("standalone", true)  {}  LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)  :	LLInventoryItemsList(p)  {  	setComparator(&WEARABLE_TYPE_NAME_COMPARATOR); -	if (p.use_internal_context_menu) +	mIsStandalone = p.standalone; +	if (mIsStandalone)  	{ +		// Use built-in context menu.  		setRightMouseDownCallback(boost::bind(&LLWearableItemsList::onRightClick, this, _2, _3));  	}  } @@ -510,6 +516,37 @@ void LLWearableItemsList::updateList(const LLUUID& category_id)  	refreshList(item_array);  } +void LLWearableItemsList::updateChangedItems(const LLInventoryModel::changed_items_t& changed_items_uuids) +{ +	typedef std::vector<LLPanel*> item_panel_list_t; + +	item_panel_list_t items; +	getItems(items); + +	for (item_panel_list_t::iterator items_iter = items.begin(); +			items_iter != items.end(); +			++items_iter) +	{ +		LLPanelInventoryListItemBase* item = dynamic_cast<LLPanelInventoryListItemBase*>(*items_iter); +		if (!item) continue; + +		LLViewerInventoryItem* inv_item = item->getItem(); +		if (!inv_item) continue; + +		LLUUID linked_uuid = inv_item->getLinkedUUID(); + +		for (LLInventoryModel::changed_items_t::const_iterator iter = changed_items_uuids.begin(); +				iter != changed_items_uuids.end(); +				++iter) +		{ +			if (linked_uuid == *iter) +			{ +				item->setNeedsRefresh(true); +			} +		} +	} +} +  void LLWearableItemsList::onRightClick(S32 x, S32 y)  {  	uuid_vec_t selected_uuids; @@ -527,6 +564,18 @@ void LLWearableItemsList::onRightClick(S32 x, S32 y)  /// ContextMenu  ////////////////////////////////////////////////////////////////////////// +LLWearableItemsList::ContextMenu::ContextMenu() +:	mParent(NULL) +{ +} + +void LLWearableItemsList::ContextMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y) +{ +	mParent = dynamic_cast<LLWearableItemsList*>(spawning_view); +	LLListContextMenu::show(spawning_view, uuids, x, y); +	mParent = NULL; // to avoid dereferencing an invalid pointer +} +  // virtual  LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()  { @@ -614,17 +663,21 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu  		}  	} // for +	bool standalone = mParent ? mParent->isStandalone() : false; +  	// *TODO: eliminate multiple traversals over the menu items +	setMenuItemVisible(menu, "wear_add",			mask == MASK_CLOTHING && n_worn == 0);  	setMenuItemVisible(menu, "wear",				n_worn == 0); -	setMenuItemVisible(menu, "edit",				mask & (MASK_CLOTHING|MASK_BODYPART) && n_items == 1); -	setMenuItemEnabled(menu, "edit",				n_editable == 1 && n_worn == 1); +	setMenuItemVisible(menu, "edit",				!standalone && mask & (MASK_CLOTHING|MASK_BODYPART)); +	setMenuItemEnabled(menu, "edit",				n_editable == 1 && n_worn == 1 && n_items == 1);  	setMenuItemVisible(menu, "create_new",			mask & (MASK_CLOTHING|MASK_BODYPART) && n_items == 1); +	setMenuItemVisible(menu, "show_original",		!standalone);  	setMenuItemEnabled(menu, "show_original",		n_items == 1 && n_links == n_items);  	setMenuItemVisible(menu, "take_off",			mask == MASK_CLOTHING && n_worn == n_items);  	setMenuItemVisible(menu, "detach",				mask == MASK_ATTACHMENT && n_worn == n_items);  	setMenuItemVisible(menu, "take_off_or_detach",	mask == (MASK_ATTACHMENT|MASK_CLOTHING));  	setMenuItemEnabled(menu, "take_off_or_detach",	n_worn == n_items); -	setMenuItemVisible(menu, "object_profile",		mask & (MASK_ATTACHMENT|MASK_CLOTHING)); +	setMenuItemVisible(menu, "object_profile",		!standalone);  	setMenuItemEnabled(menu, "object_profile",		n_items == 1);  	// Populate or hide the "Attach to..." / "Attach to HUD..." submenus. diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index f03336186c..2f95c733aa 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -56,13 +56,13 @@ class LLPanelWearableListItem : public LLPanelInventoryListItemBase  public:  	/** -	* Shows buttons when mouse is over -	*/ +	 * Shows buttons when mouse is over +	 */  	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);  	/** -	* Hides buttons when mouse is out -	*/ +	 * Hides buttons when mouse is out +	 */  	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);  protected: @@ -84,11 +84,16 @@ public:  	static LLPanelWearableOutfitItem* create(LLViewerInventoryItem* item);  	/** -	* Puts item on if it is not worn by agent -	* otherwise takes it off on double click. -	*/ +	 * Puts item on if it is not worn by agent +	 * otherwise takes it off on double click. +	 */  	/*virtual*/ BOOL handleDoubleClick(S32 x, S32 y, MASK mask); +	/** +	 * Updates item name and (worn) suffix. +	 */ +	/*virtual*/ void updateItem(const std::string& name); +  protected:  	LLPanelWearableOutfitItem(LLViewerInventoryItem* item); @@ -198,7 +203,6 @@ class LLPanelDummyClothingListItem : public LLPanelWearableListItem  public:  	static LLPanelDummyClothingListItem* create(LLWearableType::EType w_type); -	/*virtual*/ void updateItem();  	/*virtual*/ BOOL postBuild();  	LLWearableType::EType getWearableType() const; @@ -325,6 +329,10 @@ public:  	 */  	class ContextMenu : public LLListContextMenu, public LLSingleton<ContextMenu>  	{ +	public: +		ContextMenu(); +		/*virtual*/ void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y); +  	protected:  		enum {  			MASK_CLOTHING		= 0x01, @@ -340,11 +348,13 @@ public:  		static void setMenuItemEnabled(LLContextMenu* menu, const std::string& name, bool val);  		static void updateMask(U32& mask, LLAssetType::EType at);  		static void createNewWearable(const LLUUID& item_id); + +		LLWearableItemsList*	mParent;  	};  	struct Params : public LLInitParam::Block<Params, LLInventoryItemsList::Params>  	{ -		Optional<bool> use_internal_context_menu; +		Optional<bool> standalone;  		Params();  	}; @@ -355,11 +365,21 @@ public:  	void updateList(const LLUUID& category_id); +	/** +	 * Update items that match UUIDs from changed_items_uuids +	 * or links that point at such items. +	 */ +	void updateChangedItems(const LLInventoryModel::changed_items_t& changed_items_uuids); + +	bool isStandalone() const { return mIsStandalone; } +  protected:  	friend class LLUICtrlFactory;  	LLWearableItemsList(const LLWearableItemsList::Params& p);  	void onRightClick(S32 x, S32 y); + +	bool mIsStandalone;  };  #endif //LL_LLWEARABLEITEMSLIST_H diff --git a/indra/newview/llwindebug.cpp b/indra/newview/llwindebug.cpp deleted file mode 100644 index 59bc9dc62b..0000000000 --- a/indra/newview/llwindebug.cpp +++ /dev/null @@ -1,912 +0,0 @@ -/**  - * @file llwindebug.cpp - * @brief Windows debugging functions - * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - *  - * Copyright (c) 2004-2009, Linden Research, Inc. - *  - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab.  Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - *  - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - *  - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - *  - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include <tchar.h> -#include <tlhelp32.h> -#include "llwindebug.h" -#include "llviewercontrol.h" -#include "lldir.h" -#include "llsd.h" -#include "llsdserialize.h" - -#pragma warning(disable: 4200)	//nonstandard extension used : zero-sized array in struct/union -#pragma warning(disable: 4100)	//unreferenced formal parameter - - -/* -LLSD Block for Windows Dump Information -<llsd> -  <map> -    <key>Platform</key> -    <string></string> -    <key>Process</key> -    <string></string> -    <key>Module</key> -    <string></string> -    <key>DateModified</key> -    <string></string> -    <key>ExceptionCode</key> -    <string></string> -    <key>ExceptionRead/WriteAddress</key> -    <string></string> -    <key>Instruction</key> -    <string></string> -    <key>Registers</key> -    <map> -      <!-- Continued for all registers --> -      <key>EIP</key> -      <string>...</string> -      <!-- ... --> -    </map> -    <key>Call Stack</key> -    <array> -      <!-- One map per stack frame --> -      <map> -	<key>ModuleName</key> -	<string></string> -	<key>ModuleBaseAddress</key> -	<string></string> -	<key>ModuleOffsetAddress</key> -	<string></string> -	<key>Parameters</key> -	<array> -	  <string></string> -	</array> -      </map> -      <!-- ... --> -    </array> -  </map> -</llsd> - -*/ - - -extern void (*gCrashCallback)(void); - -// based on dbghelp.h -typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, -									CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, -									CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, -									CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam -									); - -MINIDUMPWRITEDUMP f_mdwp = NULL; - -#undef UNICODE - -static LPTOP_LEVEL_EXCEPTION_FILTER gFilterFunc = NULL; - -HMODULE	hDbgHelp; - -// Tool Help functions. -typedef	HANDLE (WINAPI * CREATE_TOOL_HELP32_SNAPSHOT)(DWORD dwFlags, DWORD th32ProcessID); -typedef	BOOL (WINAPI * MODULE32_FIRST)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); -typedef	BOOL (WINAPI * MODULE32_NEST)(HANDLE hSnapshot, LPMODULEENTRY32 lpme); - -CREATE_TOOL_HELP32_SNAPSHOT	CreateToolhelp32Snapshot_; -MODULE32_FIRST	Module32First_; -MODULE32_NEST	Module32Next_; - -#define	DUMP_SIZE_MAX	8000	//max size of our dump -#define	CALL_TRACE_MAX	((DUMP_SIZE_MAX - 2000) / (MAX_PATH + 40))	//max number of traced calls -#define	NL				L"\r\n"	//new line - - -typedef struct STACK -{ -	STACK *	Ebp; -	PBYTE	Ret_Addr; -	DWORD	Param[0]; -} STACK, * PSTACK; - -BOOL WINAPI Get_Module_By_Ret_Addr(PBYTE Ret_Addr, LPWSTR Module_Name, PBYTE & Module_Addr); -void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record,  -						   const CONTEXT* context_record,  -						   LLSD& info); - -void printError( CHAR* msg ) -{ -  DWORD eNum; -  TCHAR sysMsg[256]; -  TCHAR* p; - -  eNum = GetLastError( ); -  FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, -         NULL, eNum, -         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language -         sysMsg, 256, NULL ); - -  // Trim the end of the line and terminate it with a null -  p = sysMsg; -  while( ( *p > 31 ) || ( *p == 9 ) ) -    ++p; -  do { *p-- = 0; } while( ( p >= sysMsg ) && -                          ( ( *p == '.' ) || ( *p < 33 ) ) ); - -  // Display the message -  printf( "\n  WARNING: %s failed with error %d (%s)", msg, eNum, sysMsg ); -} - -BOOL GetProcessThreadIDs(DWORD process_id, std::vector<DWORD>& thread_ids)  -{  -  HANDLE hThreadSnap = INVALID_HANDLE_VALUE;  -  THREADENTRY32 te32;  -  -  // Take a snapshot of all running threads   -  hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );  -  if( hThreadSnap == INVALID_HANDLE_VALUE )  -    return( FALSE );  -  -  // Fill in the size of the structure before using it.  -  te32.dwSize = sizeof(THREADENTRY32 );  -  -  // Retrieve information about the first thread, -  // and exit if unsuccessful -  if( !Thread32First( hThreadSnap, &te32 ) )  -  { -    printError( "Thread32First" );  // Show cause of failure -    CloseHandle( hThreadSnap );     // Must clean up the snapshot object! -    return( FALSE ); -  } - -  // Now walk the thread list of the system, -  // and display information about each thread -  // associated with the specified process -  do  -  {  -    if( te32.th32OwnerProcessID == process_id ) -    { -      thread_ids.push_back(te32.th32ThreadID);  -    } -  } while( Thread32Next(hThreadSnap, &te32 ) );  - -//  Don't forget to clean up the snapshot object. -  CloseHandle( hThreadSnap ); -  return( TRUE ); -} - -BOOL GetThreadCallStack(DWORD thread_id, LLSD& info) -{ -    if(GetCurrentThreadId() == thread_id) -    { -        // Early exit for the current thread. -        // Suspending the current thread would be a bad idea. -        // Plus you can't retrieve a valid current thread context. -        return false; -    } - -    HANDLE thread_handle = INVALID_HANDLE_VALUE;  -    thread_handle = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_id); -    if(INVALID_HANDLE_VALUE == thread_handle) -    { -        return FALSE; -    } - -    BOOL result = false; -    if(-1 != SuspendThread(thread_handle)) -    { -        CONTEXT context_struct; -        context_struct.ContextFlags = CONTEXT_FULL; -        if(GetThreadContext(thread_handle, &context_struct)) -        { -            Get_Call_Stack(NULL, &context_struct, info); -            result = true; -        } -        ResumeThread(thread_handle); -    } -    else -    { -        // Couldn't suspend thread. -    } - -    CloseHandle(thread_handle); -    return result; -} - - -//Windows Call Stack Construction idea from  -//http://www.codeproject.com/tools/minidump.asp - -//**************************************************************************************** -BOOL WINAPI Get_Module_By_Ret_Addr(PBYTE Ret_Addr, LPWSTR Module_Name, PBYTE & Module_Addr) -//**************************************************************************************** -// Find module by Ret_Addr (address in the module). -// Return Module_Name (full path) and Module_Addr (start address). -// Return TRUE if found. -{ -	MODULEENTRY32	M = {sizeof(M)}; -	HANDLE	hSnapshot; - -	bool found = false; -	 -	if (CreateToolhelp32Snapshot_) -	{ -		hSnapshot = CreateToolhelp32Snapshot_(TH32CS_SNAPMODULE, 0); -		 -		if ((hSnapshot != INVALID_HANDLE_VALUE) && -			Module32First_(hSnapshot, &M)) -		{ -			do -			{ -				if (DWORD(Ret_Addr - M.modBaseAddr) < M.modBaseSize) -				{ -					lstrcpyn(Module_Name, M.szExePath, MAX_PATH); -					Module_Addr = M.modBaseAddr; -					found = true; -					break; -				} -			} while (Module32Next_(hSnapshot, &M)); -		} - -		CloseHandle(hSnapshot); -	} - -	return found; -} //Get_Module_By_Ret_Addr - -bool has_valid_call_before(PDWORD cur_stack_loc) -{ -	PBYTE p_first_byte = (PBYTE)(*cur_stack_loc - 1); -	PBYTE p_second_byte = (PBYTE)(*cur_stack_loc -2); -	PBYTE p_fifth_byte = (PBYTE)(*cur_stack_loc - 5); -	PBYTE p_sixth_byte = (PBYTE)(*cur_stack_loc - 6); - -	// make sure we can read it -	if(IsBadReadPtr(p_sixth_byte, 6 * sizeof(BYTE))) -	{ -		return false; -	} - -	// check for 9a + 4 bytes -	if(*p_fifth_byte == 0x9A) -	{ -		return true; -	} - -	// Check for E8 + 4 bytes and last byte is 00 or FF -	if(*p_fifth_byte == 0xE8 && (*p_first_byte == 0x00 || *p_first_byte == 0xFF)) -	{ -		return true; -	} -	 -	// the other is six bytes -	if(*p_sixth_byte == 0xFF || *p_second_byte == 0xFF) -	{ -		return true; -	} - -	return false; -} - -PBYTE get_valid_frame(PBYTE esp) -{ -	PDWORD cur_stack_loc = NULL; -	const int max_search = 400; -	WCHAR	module_name[MAX_PATH]; -	PBYTE	module_addr = 0; - -	// round to highest multiple of four -	esp = (esp + (4 - ((int)esp % 4)) % 4); - -	// scroll through stack a few hundred places. -	for (cur_stack_loc = (PDWORD) esp; cur_stack_loc < (PDWORD)esp + max_search; cur_stack_loc += 1) -	{ -		// if you can read the pointer, -		if (IsBadReadPtr(cur_stack_loc, sizeof(PDWORD))) -		{ -			continue; -		} - -		//  check if it's in a module -		if (!Get_Module_By_Ret_Addr((PBYTE)*cur_stack_loc, module_name, module_addr)) -		{ -			continue; -		} - -		// check if the code before the instruction ptr is a call  -		if(!has_valid_call_before(cur_stack_loc)) -		{ -			continue; -		} -		 -		// if these all pass, return that ebp, otherwise continue till we're dead -		return (PBYTE)(cur_stack_loc - 1); -	} - -	return NULL; -} - -bool shouldUseStackWalker(PSTACK Ebp, int max_depth) -{ -	WCHAR	Module_Name[MAX_PATH]; -	PBYTE	Module_Addr = 0; -	int depth = 0; - -	while (depth < max_depth)  -	{ -		if (IsBadReadPtr(Ebp, sizeof(PSTACK)) ||  -			IsBadReadPtr(Ebp->Ebp, sizeof(PSTACK)) || -			Ebp->Ebp < Ebp || -			Ebp->Ebp - Ebp > 0xFFFFFF || -			IsBadCodePtr(FARPROC(Ebp->Ebp->Ret_Addr)) || -			!Get_Module_By_Ret_Addr(Ebp->Ebp->Ret_Addr, Module_Name, Module_Addr)) -		{ -			return true; -		} -		depth++; -		Ebp = Ebp->Ebp; -	} - -	return false; -} - -//****************************************************************** -void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record,  -						   const CONTEXT* context_record,  -						   LLSD& info) -//****************************************************************** -// Fill Str with call stack info. -// pException can be either GetExceptionInformation() or NULL. -// If pException = NULL - get current call stack. -{ -	LPWSTR	Module_Name = new WCHAR[MAX_PATH]; -	PBYTE	Module_Addr = 0; -	LLSD params; -	PBYTE	Esp = NULL; -	LLSD tmp_info; - -	bool fake_frame = false; -	bool ebp_used = false; -	const int HEURISTIC_MAX_WALK = 20; -	int heuristic_walk_i = 0; -	int Ret_Addr_I = 0; - -	STACK	Stack = {0, 0}; -	PSTACK	Ebp; - -	if (exception_record && context_record)		//fake frame for exception address -	{ -		Stack.Ebp = (PSTACK)(context_record->Ebp); -		Stack.Ret_Addr = (PBYTE)exception_record->ExceptionAddress; -		Ebp = &Stack; -		Esp = (PBYTE) context_record->Esp; -		fake_frame = true; -	} -	else if(context_record) -	{ -        Ebp = (PSTACK)(context_record->Ebp); -		Esp = (PBYTE)(context_record->Esp); -	} -	else -	{ -		Ebp = (PSTACK)&exception_record - 1;	//frame addr of Get_Call_Stack() -		Esp = (PBYTE)&exception_record; - -		// Skip frame of Get_Call_Stack(). -		if (!IsBadReadPtr(Ebp, sizeof(PSTACK))) -			Ebp = Ebp->Ebp;		//caller ebp -	} - -	// Trace CALL_TRACE_MAX calls maximum - not to exceed DUMP_SIZE_MAX. -	// Break trace on wrong stack frame. -	for (Ret_Addr_I = 0; -		heuristic_walk_i < HEURISTIC_MAX_WALK &&  -		Ret_Addr_I < CALL_TRACE_MAX && !IsBadReadPtr(Ebp, sizeof(PSTACK)) && !IsBadCodePtr(FARPROC(Ebp->Ret_Addr)); -		Ret_Addr_I++) -	{ -		// If module with Ebp->Ret_Addr found. -		if (Get_Module_By_Ret_Addr(Ebp->Ret_Addr, Module_Name, Module_Addr)) -		{ -			// Save module's address and full path. -			tmp_info["CallStack"][Ret_Addr_I]["ModuleName"] = ll_convert_wide_to_string(Module_Name); -			tmp_info["CallStack"][Ret_Addr_I]["ModuleAddress"] = (int)Module_Addr; -			tmp_info["CallStack"][Ret_Addr_I]["CallOffset"] = (int)(Ebp->Ret_Addr - Module_Addr); - -			// Save 5 params of the call. We don't know the real number of params. -			if (fake_frame && !Ret_Addr_I)	//fake frame for exception address -				params[0] = "Exception Offset"; -			else if (!IsBadReadPtr(Ebp, sizeof(PSTACK) + 5 * sizeof(DWORD))) -			{ -				for(int j = 0; j < 5; ++j) -				{ -					params[j] = (int)Ebp->Param[j]; -				} -			} -			tmp_info["CallStack"][Ret_Addr_I]["Parameters"] = params; -		} - -		tmp_info["CallStack"][Ret_Addr_I]["ReturnAddress"] = (int)Ebp->Ret_Addr; - -		// get ready for next frame -		// Set ESP to just after return address.  Not the real esp, but just enough after the return address -		if(!fake_frame) { -			Esp = (PBYTE)Ebp + 8; -		}  -		else -		{ -			fake_frame = false; -		} - -		// is next ebp valid? -		// only run if we've never found a good ebp -		// and make sure the one after is valid as well -		if(	!ebp_used &&  -			shouldUseStackWalker(Ebp, 2)) -		{ -			heuristic_walk_i++; -			PBYTE new_ebp = get_valid_frame(Esp); -			if (new_ebp != NULL) -			{ -				Ebp = (PSTACK)new_ebp; -			} -		} -		else -		{ -			ebp_used = true; -			Ebp = Ebp->Ebp; -		} -	} -/* TODO remove or turn this code back on to edit the stack after i see a few raw ones. -Palmer -	// Now go back through and edit out heuristic stacks that could very well be bogus. -	// Leave the top and the last 3 stack chosen by the heuristic, however. -	if(heuristic_walk_i > 2) -	{ -		info["CallStack"][0] = tmp_info["CallStack"][0]; -		std::string ttest = info["CallStack"][0]["ModuleName"]; -		for(int cur_frame = 1;  -			(cur_frame + heuristic_walk_i - 2 < Ret_Addr_I);  -			++cur_frame) -		{ -			// edit out the middle heuristic found frames -			info["CallStack"][cur_frame] = tmp_info["CallStack"][cur_frame + heuristic_walk_i - 2]; -		} -	} -	else -	{ -		info = tmp_info; -	} -*/ -	info = tmp_info; -	info["HeuristicWalkI"] = heuristic_walk_i; -	info["EbpUsed"] = ebp_used; - -} //Get_Call_Stack - -//*********************************** -void WINAPI Get_Version_Str(LLSD& info) -//*********************************** -// Fill Str with Windows version. -{ -	OSVERSIONINFOEX	V = {sizeof(OSVERSIONINFOEX)};	//EX for NT 5.0 and later - -	if (!GetVersionEx((POSVERSIONINFO)&V)) -	{ -		ZeroMemory(&V, sizeof(V)); -		V.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); -		GetVersionEx((POSVERSIONINFO)&V); -	} - -	if (V.dwPlatformId != VER_PLATFORM_WIN32_NT) -		V.dwBuildNumber = LOWORD(V.dwBuildNumber);	//for 9x HIWORD(dwBuildNumber) = 0x04xx - -	info["Platform"] = llformat("Windows:  %d.%d.%d, SP %d.%d, Product Type %d",	//SP - service pack, Product Type - VER_NT_WORKSTATION,... -		V.dwMajorVersion, V.dwMinorVersion, V.dwBuildNumber, V.wServicePackMajor, V.wServicePackMinor, V.wProductType); -} //Get_Version_Str - -//************************************************************* -LLSD WINAPI Get_Exception_Info(PEXCEPTION_POINTERS pException) -//************************************************************* -// Allocate Str[DUMP_SIZE_MAX] and return Str with dump, if !pException - just return call stack in Str. -{ -	LLSD info; -	LPWSTR		Str; -	int			Str_Len; -//	int			i; -	LPWSTR		Module_Name = new WCHAR[MAX_PATH]; -	PBYTE		Module_Addr; -	HANDLE		hFile; -	FILETIME	Last_Write_Time; -	FILETIME	Local_File_Time; -	SYSTEMTIME	T; - -	Str = new WCHAR[DUMP_SIZE_MAX]; -	Str_Len = 0; -	if (!Str) -		return NULL; -	 -	Get_Version_Str(info); -	 -	GetModuleFileName(NULL, Str, MAX_PATH); -	info["Process"] = ll_convert_wide_to_string(Str); -	info["ThreadID"] = (S32)GetCurrentThreadId(); - -	// If exception occurred. -	if (pException) -	{ -		EXCEPTION_RECORD &	E = *pException->ExceptionRecord; -		CONTEXT &			C = *pException->ContextRecord; - -		// If module with E.ExceptionAddress found - save its path and date. -		if (Get_Module_By_Ret_Addr((PBYTE)E.ExceptionAddress, Module_Name, Module_Addr)) -		{ -			info["Module"] = ll_convert_wide_to_string(Module_Name); - -			if ((hFile = CreateFile(Module_Name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, -				FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) -			{ -				if (GetFileTime(hFile, NULL, NULL, &Last_Write_Time)) -				{ -					FileTimeToLocalFileTime(&Last_Write_Time, &Local_File_Time); -					FileTimeToSystemTime(&Local_File_Time, &T); - -					info["DateModified"] = llformat("%02d/%02d/%d", T.wMonth, T.wDay, T.wYear); -				} -				CloseHandle(hFile); -			} -		} -		else -		{ -			info["ExceptionAddr"] = (int)E.ExceptionAddress; -		} -		 -		info["ExceptionCode"] = (int)E.ExceptionCode; -		 -		/* -		//TODO: Fix this -		if (E.ExceptionCode == EXCEPTION_ACCESS_VIOLATION) -		{ -			// Access violation type - Write/Read. -			LLSD exception_info; -			exception_info["Type"] = E.ExceptionInformation[0] ? "Write" : "Read"; -			exception_info["Address"] = llformat("%08x", E.ExceptionInformation[1]); -			info["Exception Information"] = exception_info; -		} -		*/ - -		 -		// Save instruction that caused exception. -		/* -		std::string str; -		for (i = 0; i < 16; i++) -			str += llformat(" %02X", PBYTE(E.ExceptionAddress)[i]); -		info["Instruction"] = str; -		*/ -		LLSD registers; -		registers["EAX"] = (int)C.Eax; -		registers["EBX"] = (int)C.Ebx; -		registers["ECX"] = (int)C.Ecx; -		registers["EDX"] = (int)C.Edx; -		registers["ESI"] = (int)C.Esi; -		registers["EDI"] = (int)C.Edi; -		registers["ESP"] = (int)C.Esp; -		registers["EBP"] = (int)C.Ebp; -		registers["EIP"] = (int)C.Eip; -		registers["EFlags"] = (int)C.EFlags; -		info["Registers"] = registers; -	} //if (pException) -	 -	// Save call stack info. -	Get_Call_Stack(pException->ExceptionRecord, pException->ContextRecord, info); - -	return info; -} //Get_Exception_Info - -#define UNICODE - - -class LLMemoryReserve { -public: -	LLMemoryReserve(); -	~LLMemoryReserve(); -	void reserve(); -	void release(); -protected: -	unsigned char *mReserve; -	static const size_t MEMORY_RESERVATION_SIZE; -}; - -LLMemoryReserve::LLMemoryReserve() : -	mReserve(NULL) -{ -}; - -LLMemoryReserve::~LLMemoryReserve() -{ -	release(); -} - -// I dunno - this just seemed like a pretty good value. -const size_t LLMemoryReserve::MEMORY_RESERVATION_SIZE = 5 * 1024 * 1024; - -void LLMemoryReserve::reserve() -{ -	if(NULL == mReserve) -		mReserve = new unsigned char[MEMORY_RESERVATION_SIZE]; -}; - -void LLMemoryReserve::release() -{ -	delete [] mReserve; -	mReserve = NULL; -}; - -static LLMemoryReserve gEmergencyMemoryReserve; - -#ifndef _M_IX86 -	#error "The following code only works for x86!" -#endif -LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter( -	LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter) -{ -	if(lpTopLevelExceptionFilter ==  gFilterFunc) -		return gFilterFunc; - -	llinfos << "Someone tried to set the exception filter. Listing call stack modules" << llendl; -	LLSD cs_info; -	Get_Call_Stack(NULL, NULL, cs_info); -	 -	if(cs_info.has("CallStack") && cs_info["CallStack"].isArray()) -	{ -		LLSD cs = cs_info["CallStack"]; -		for(LLSD::array_iterator i = cs.beginArray();  -			i != cs.endArray();  -			++i) -		{ -			llinfos << "Module: " << (*i)["ModuleName"] << llendl; -		} -	} -	 -	return gFilterFunc; -} - -BOOL PreventSetUnhandledExceptionFilter() -{ -	HMODULE hKernel32 = LoadLibrary(_T("kernel32.dll")); -	if (hKernel32 == NULL)  -		return FALSE; - -	void *pOrgEntry = GetProcAddress(hKernel32, "SetUnhandledExceptionFilter"); -	if(pOrgEntry == NULL)  -		return FALSE; -	 -	unsigned char newJump[ 100 ]; -	DWORD dwOrgEntryAddr = (DWORD)pOrgEntry; -	dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far -	void *pNewFunc = &MyDummySetUnhandledExceptionFilter; -	DWORD dwNewEntryAddr = (DWORD) pNewFunc; -	DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr; - -	newJump[ 0 ] = 0xE9;  // JMP absolute -	memcpy(&newJump[ 1 ], &dwRelativeAddr, sizeof(pNewFunc)); -	SIZE_T bytesWritten; -	BOOL bRet = WriteProcessMemory(GetCurrentProcess(), -	pOrgEntry, newJump, sizeof(pNewFunc) + 1, &bytesWritten); -	return bRet; -} - -// static -void  LLWinDebug::initExceptionHandler(LPTOP_LEVEL_EXCEPTION_FILTER filter_func) -{ - -	static bool s_first_run = true; -	// Load the dbghelp dll now, instead of waiting for the crash. -	// Less potential for stack mangling - -	if (s_first_run) -	{ -		// First, try loading from the directory that the app resides in. -		std::string local_dll_name = gDirUtilp->findFile("dbghelp.dll", gDirUtilp->getWorkingDir(), gDirUtilp->getExecutableDir()); - -		HMODULE hDll = NULL; -		hDll = LoadLibraryA(local_dll_name.c_str()); -		if (!hDll) -		{ -			hDll = LoadLibrary(L"dbghelp.dll"); -		} - -		if (!hDll) -		{ -			LL_WARNS("AppInit") << "Couldn't find dbghelp.dll!" << LL_ENDL; -		} -		else -		{ -			f_mdwp = (MINIDUMPWRITEDUMP) GetProcAddress(hDll, "MiniDumpWriteDump"); - -			if (!f_mdwp) -			{ -				FreeLibrary(hDll); -				hDll = NULL; -			} -		} - -		gEmergencyMemoryReserve.reserve(); - -		s_first_run = false; -	} - -	// Try to get Tool Help library functions. -	HMODULE hKernel32; -	hKernel32 = GetModuleHandle(_T("KERNEL32")); -	CreateToolhelp32Snapshot_ = (CREATE_TOOL_HELP32_SNAPSHOT)GetProcAddress(hKernel32, "CreateToolhelp32Snapshot"); -	Module32First_ = (MODULE32_FIRST)GetProcAddress(hKernel32, "Module32FirstW"); -	Module32Next_ = (MODULE32_NEST)GetProcAddress(hKernel32, "Module32NextW"); - -    LPTOP_LEVEL_EXCEPTION_FILTER prev_filter; -	prev_filter = SetUnhandledExceptionFilter(filter_func); - -	// *REMOVE:Mani -	//PreventSetUnhandledExceptionFilter(); - -	if(prev_filter != gFilterFunc) -	{ -		LL_WARNS("AppInit")  -			<< "Replacing unknown exception (" << (void *)prev_filter << ") with (" << (void *)filter_func << ") !" << LL_ENDL; -	} -	 -	gFilterFunc = filter_func; -} - -bool LLWinDebug::checkExceptionHandler() -{ -	bool ok = true; -	LPTOP_LEVEL_EXCEPTION_FILTER prev_filter; -	prev_filter = SetUnhandledExceptionFilter(gFilterFunc); - -	if (prev_filter != gFilterFunc) -	{ -		LL_WARNS("AppInit") << "Our exception handler (" << (void *)gFilterFunc << ") replaced with " << prev_filter << "!" << LL_ENDL; -		ok = false; -	} - -	if (prev_filter == NULL) -	{ -		ok = FALSE; -		if (gFilterFunc == NULL) -		{ -			LL_WARNS("AppInit") << "Exception handler uninitialized." << LL_ENDL; -		} -		else -		{ -			LL_WARNS("AppInit") << "Our exception handler (" << (void *)gFilterFunc << ") replaced with NULL!" << LL_ENDL; -		} -	} - -	return ok; -} - -void LLWinDebug::writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const std::string& filename) -{ -	if(f_mdwp == NULL || gDirUtilp == NULL)  -	{ -		return; -		//write_debug("No way to generate a minidump, no MiniDumpWriteDump function!\n"); -	} -	else -	{ -		std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, filename); - -		HANDLE hFile = CreateFileA(dump_path.c_str(), -									GENERIC_WRITE, -									FILE_SHARE_WRITE, -									NULL, -									CREATE_ALWAYS, -									FILE_ATTRIBUTE_NORMAL, -									NULL); - -		if (hFile != INVALID_HANDLE_VALUE) -		{ -			// Write the dump, ignoring the return value -			f_mdwp(GetCurrentProcess(), -					GetCurrentProcessId(), -					hFile, -					type, -					ExInfop, -					NULL, -					NULL); - -			CloseHandle(hFile); -		} - -	} -} - -// static -void LLWinDebug::generateCrashStacks(struct _EXCEPTION_POINTERS *exception_infop) -{ -	// *NOTE:Mani - This method is no longer the exception handler. -	// Its called from viewer_windows_exception_handler() and other places. - -	//  -	// Let go of a bunch of reserved memory to give library calls etc -	// a chance to execute normally in the case that we ran out of -	// memory. -	// -	LLSD info; -	std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, -												"SecondLifeException"); -	std::string log_path = dump_path + ".log"; - -	if (exception_infop) -	{ -		// Since there is exception info... Release the hounds. -		gEmergencyMemoryReserve.release(); - -		if(gSavedSettings.getControl("SaveMinidump").notNull() && gSavedSettings.getBOOL("SaveMinidump")) -		{ -			_MINIDUMP_EXCEPTION_INFORMATION ExInfo; - -			ExInfo.ThreadId = ::GetCurrentThreadId(); -			ExInfo.ExceptionPointers = exception_infop; -			ExInfo.ClientPointers = NULL; - -			writeDumpToFile(MiniDumpNormal, &ExInfo, "SecondLife.dmp"); -			writeDumpToFile((MINIDUMP_TYPE)(MiniDumpWithDataSegs | MiniDumpWithIndirectlyReferencedMemory), &ExInfo, "SecondLifePlus.dmp"); -		} - -		info = Get_Exception_Info(exception_infop); -	} - -	LLSD threads; -    std::vector<DWORD> thread_ids; -    GetProcessThreadIDs(GetCurrentProcessId(), thread_ids); - -    for(std::vector<DWORD>::iterator th_itr = thread_ids.begin();  -                th_itr != thread_ids.end(); -                ++th_itr) -    { -        LLSD thread_info; -        if(*th_itr != GetCurrentThreadId()) -        { -            GetThreadCallStack(*th_itr, thread_info); -        } - -        if(thread_info) -        { -            threads[llformat("ID %d", *th_itr)] = thread_info; -        } -    } - -    info["Threads"] = threads; - -	llofstream out_file(log_path); -	LLSDSerialize::toPrettyXML(info, out_file); -	out_file.close(); -} - -void LLWinDebug::clearCrashStacks() -{ -	LLSD info; -	std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLifeException.log"); -	LLFile::remove(dump_path); -} diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h deleted file mode 100644 index f4a6a2d54d..0000000000 --- a/indra/newview/llwindebug.h +++ /dev/null @@ -1,75 +0,0 @@ -/**  - * @file llwindebug.h - * @brief LLWinDebug class header file - * - * $LicenseInfo:firstyear=2004&license=viewergpl$ - *  - * Copyright (c) 2004-2009, Linden Research, Inc. - *  - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab.  Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - *  - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - *  - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - *  - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_LLWINDEBUG_H -#define LL_LLWINDEBUG_H - -#include "stdtypes.h" -#include <dbghelp.h> - -class LLWinDebug -{ -public: - -	/**  -	* @brief initialize the llwindebug exception filter callback -	*  -	* Hand a windows unhandled exception filter to LLWinDebug -	* This method should only be called to change the -	* exception filter used by llwindebug. -	* -	* Setting filter_func to NULL will clear any custom filters. -	**/ -	static void initExceptionHandler(LPTOP_LEVEL_EXCEPTION_FILTER filter_func); - -	/**  -	* @brief check the status of the exception filter. -	* -	* Resets unhandled exception filter to the filter specified  -	* w/ initExceptionFilter).  -	* Returns false if the exception filter was modified. -	* -	* *NOTE:Mani In the past mozlib has been accused of -	* overriding the exception filter. If the mozlib filter  -	* is required, perhaps we can chain calls from our  -	* filter to mozlib's. -	**/ -	static bool checkExceptionHandler(); - -	static void generateCrashStacks(struct _EXCEPTION_POINTERS *pExceptionInfo = NULL); -	static void clearCrashStacks(); // Delete the crash stack file(s). - -	static void writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const std::string& filename); -private: -}; - -#endif // LL_LLWINDEBUG_H diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index a8ac0c0c90..1d10ec7b28 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -513,7 +513,7 @@ void LLXMLRPCTransaction::Impl::setStatus(EStatus status,  				// Usually this means that there's a problem with the login server,  				// not with the client.  Direct user to status page.  				mStatusMessage = LLTrans::getString("server_is_down"); -				mStatusURI = "http://secondlife.com/status/"; +				mStatusURI = "http://status.secondlifegrid.net/";  		}  	}  } diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index 731953f9bb..df2fb2a6ea 100644 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -129,8 +129,8 @@ TOOLSIT                 CURSOR                  "toolsit.cur"  //  VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,0,2,0 - PRODUCTVERSION 2,0,2,0 + FILEVERSION 2,1,0,0 + PRODUCTVERSION 2,1,0,0   FILEFLAGSMASK 0x3fL  #ifdef _DEBUG   FILEFLAGS 0x1L @@ -147,12 +147,12 @@ BEGIN          BEGIN              VALUE "CompanyName", "Linden Lab"              VALUE "FileDescription", "Second Life" -            VALUE "FileVersion", "2.0.2.0" +            VALUE "FileVersion", "2.1.0.0"              VALUE "InternalName", "Second Life"              VALUE "LegalCopyright", "Copyright  2001-2008, Linden Research, Inc."              VALUE "OriginalFilename", "SecondLife.exe"              VALUE "ProductName", "Second Life" -            VALUE "ProductVersion", "2.0.2.0" +            VALUE "ProductVersion", "2.1.0.0"          END      END      BLOCK "VarFileInfo" diff --git a/indra/newview/skins/default/textures/icons/Inv_Link.png b/indra/newview/skins/default/textures/icons/Inv_Link.png Binary files differnew file mode 100644 index 0000000000..c1543dacb5 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/Inv_Link.png diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 85ccf0f564..c02bf5741e 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -228,39 +228,7 @@ with the same filename but different name    <texture name="Inv_TrashOpen" file_name="icons/Inv_TrashOpen.png" preload="false" />    <texture name="Inv_Underpants" file_name="icons/Inv_Underpants.png" preload="false" />    <texture name="Inv_Undershirt" file_name="icons/Inv_Undershirt.png" preload="false" /> - -  <texture name="Inv_Alpha_Link" file_name="icons/Inv_Alpha_Link.png" preload="false" /> -  <texture name="Inv_Animation_Link" file_name="icons/Inv_Animation_Link.png" preload="false" /> -  <texture name="Inv_BodyShape_Link" file_name="icons/Inv_BodyShape_Link.png" preload="false" /> -  <texture name="Inv_CallingCard_Link" file_name="icons/Inv_CallingCard_Link.png" preload="false" /> -  <texture name="Inv_Clothing_Link" file_name="icons/Inv_Clothing_Link.png" preload="false" /> -  <texture name="Inv_Eye_Link" file_name="icons/Inv_Eye_Link.png" preload="false" /> -  <texture name="Inv_FolderClosed_Link" file_name="icons/Inv_FolderClosed_Link.png" preload="false" /> -  <texture name="Inv_FolderOpen_Link" file_name="icons/Inv_FolderOpen_Link.png" preload="false" /> -  <texture name="Inv_Gesture_Link" file_name="icons/Inv_Gesture_Link.png" preload="false" /> -  <texture name="Inv_Gloves_Link" file_name="icons/Inv_Gloves_Link.png" preload="false" /> -  <texture name="Inv_Hair_Link" file_name="icons/Inv_Hair_Link.png" preload="false" /> -  <texture name="Inv_LinkFolder_Link" file_name="icons/Inv_LinkFolder_Link.png" preload="false" /> -  <texture name="Inv_Jacket_Link" file_name="icons/Inv_Jacket_Link.png" preload="false" /> -  <texture name="Inv_LookFolderOpen_Link" file_name="icons/Inv_LookFolderOpen_Link.png" preload="false" /> -  <texture name="Inv_LookFolderClosed_Link" file_name="icons/Inv_LookFolderClosed_Link.png" preload="false" /> -  <texture name="Inv_Landmark_Link" file_name="icons/Inv_Landmark_Link.png" preload="false" /> -  <texture name="Inv_Notecard_Link" file_name="icons/Inv_Notecard_Link.png" preload="false" /> -  <texture name="Inv_Object_Link" file_name="icons/Inv_Object_Link.png" preload="false" /> -  <texture name="Inv_Object_Multi_Link" file_name="icons/Inv_Object_Multi_Link.png" preload="false" /> -  <texture name="Inv_Pants_Link" file_name="icons/Inv_Pants_Link.png" preload="false" /> -  <texture name="Inv_Script_Link" file_name="icons/Inv_Script_Link.png" preload="false" /> -  <texture name="Inv_Shirt_Link" file_name="icons/Inv_Shirt_Link.png" preload="false" /> -  <texture name="Inv_Shoe_Link" file_name="icons/Inv_Shoe_Link.png" preload="false" /> -  <texture name="Inv_Skin_Link" file_name="icons/Inv_Skin_Link.png" preload="false" /> -  <texture name="Inv_Skirt_Link" file_name="icons/Inv_Skirt_Link.png" preload="false" /> -  <texture name="Inv_Snapshot_Link" file_name="icons/Inv_Snapshot_Link.png" preload="false" /> -  <texture name="Inv_Socks_Link" file_name="icons/Inv_Socks_Link.png" preload="false" /> -  <texture name="Inv_Sound_Link" file_name="icons/Inv_Sound_Link.png" preload="false" /> -  <texture name="Inv_Tattoo_Link" file_name="icons/Inv_Tattoo_Link.png" preload="false" /> -  <texture name="Inv_Texture_Link" file_name="icons/Inv_Texture_Link.png" preload="false" /> -  <texture name="Inv_Underpants_Link" file_name="icons/Inv_Underpants_Link.png" preload="false" /> -  <texture name="Inv_Undershirt_Link" file_name="icons/Inv_Undershirt_Link.png" preload="false" /> +  <texture name="Inv_Link" file_name="icons/Inv_Link.png" preload="false" />    <texture name="Linden_Dollar_Alert" file_name="widgets/Linden_Dollar_Alert.png"/>    <texture name="Linden_Dollar_Background" file_name="widgets/Linden_Dollar_Background.png"/> diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml index 4643f66bd8..4b990fa566 100644 --- a/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml +++ b/indra/newview/skins/default/xui/en/floater_buy_currency_html.xml @@ -1,27 +1,27 @@  <?xml version="1.0" encoding="utf-8" standalone="yes" ?>  <floater - legacy_header_height="18"   can_resize="false" - height="280" + can_close="true" + width="422" + height="202"   layout="topleft" - min_height="280" - min_width="450"   name="floater_buy_currency_html"   help_topic="floater_buy_currency_html"   save_rect="true"   single_instance="true"   title="BUY CURRENCY" - width="452"> - <floater.string -      name="buy_currency_url" translate="false"> -        https://quick-buy-www.jeff.ooze.lindenlab.com/en/display - </floater.string> -    <web_browser -     bottom="278" -     follows="left|right|top|bottom" -     layout="topleft" -     left="2" -     name="browser" -     top="18" -     width="450" /> +> +  <floater.string +    name="buy_currency_url" translate="false"> +    https://quick-buy.secondlife.com/[LANGUAGE]/display/?sa=[SPECIFIC_AMOUNT]&sum=[SUM]&msg=[MSG]&bal=[BAL] +  </floater.string> +  <web_browser +    follows="all" +    layout="topleft" +    left="1" +    right="-1"  +    top="1" +    bottom="-1"  +    ignore_ui_scale="false" +    name="browser"/>  </floater> diff --git a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml index 4e6a07d020..62365f7cc2 100644 --- a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml +++ b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml @@ -61,14 +61,6 @@      <menu_item_separator       layout="topleft" />      <menu_item_call -     label="Empty Trash" -     layout="topleft" -     name="empty_trash"> -        <on_click -         function="Inventory.GearDefault.Custom.Action" -         parameter="empty_trash" /> -    </menu_item_call> -    <menu_item_call       label="Empty Lost and Found"       layout="topleft"       name="empty_lostnfound"> @@ -111,4 +103,15 @@  			 function="Inventory.GearDefault.Enable"  			 parameter="find_links" />          </menu_item_call> +    <menu_item_separator +     layout="topleft" /> + +    <menu_item_call +     label="Empty Trash" +     layout="topleft" +     name="empty_trash"> +        <on_click +         function="Inventory.GearDefault.Custom.Action" +         parameter="empty_trash" /> +    </menu_item_call>  </menu> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml index b5eda8e999..8e7ef7f0b5 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_gear.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_gear.xml @@ -11,6 +11,9 @@          <on_enable           function="Gear.OnEnable"           parameter="wear" /> +        <on_visible +         function="Gear.OnVisible" +         parameter="wear" />      </menu_item_call>      <menu_item_call       label="Take Off - Remove from Current Outfit" @@ -21,9 +24,12 @@          <on_enable           function="Gear.OnEnable"           parameter="take_off" /> +        <on_visible +         function="Gear.OnVisible" +         parameter="take_off" />      </menu_item_call> -            <menu_item_separator /> +            <menu_item_separator name="sepatator1" />              <!-- copied (with minor modifications) from menu_inventory_add.xml -->              <!--  *TODO: generate dynamically? -->              <menu @@ -168,9 +174,9 @@              </menu>              <!-- copied from menu_inventory_add.xml --> -    <menu_item_separator /> +    <menu_item_separator name="sepatator2" />      <menu_item_call -     label="Rename" +     label="Rename Outfit"       layout="topleft"       name="rename">          <on_click @@ -178,6 +184,9 @@          <on_enable           function="Gear.OnEnable"           parameter="rename" /> +        <on_visible +         function="Gear.OnVisible" +         parameter="rename" />      </menu_item_call>      <menu_item_call       label="Delete Outfit" @@ -188,5 +197,8 @@          <on_enable           function="Gear.OnEnable"           parameter="delete" /> +        <on_visible +         function="Gear.OnVisible" +         parameter="delete" />      </menu_item_call>  </menu> diff --git a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml index 67559638d9..e084216a69 100644 --- a/indra/newview/skins/default/xui/en/menu_outfit_tab.xml +++ b/indra/newview/skins/default/xui/en/menu_outfit_tab.xml @@ -8,8 +8,8 @@       name="wear_replace">          <on_click           function="Outfit.WearReplace" /> -        <on_enable -         function="Outfit.OnEnable" +        <on_visible +         function="Outfit.OnVisible"           parameter="wear_replace" />      </menu_item_call>      <menu_item_call @@ -18,8 +18,8 @@       name="wear_add">          <on_click           function="Outfit.WearAdd" /> -        <on_enable -         function="Outfit.OnEnable" +        <on_visible +         function="Outfit.OnVisible"           parameter="wear_add" />      </menu_item_call>      <menu_item_call @@ -28,8 +28,8 @@       name="take_off">          <on_click           function="Outfit.TakeOff" /> -        <on_enable -         function="Outfit.OnEnable" +        <on_visible +         function="Outfit.OnVisible"           parameter="take_off" />      </menu_item_call>      <menu_item_call @@ -38,8 +38,8 @@       name="edit">          <on_click           function="Outfit.Edit" /> -        <on_enable -         function="Outfit.OnEnable" +        <on_visible +         function="Outfit.OnVisible"           parameter="edit" />      </menu_item_call>      <menu_item_separator /> @@ -59,8 +59,8 @@       name="delete">          <on_click           function="Outfit.Delete" /> -        <on_enable -         function="Outfit.OnEnable" +        <on_visible +         function="Outfit.OnVisible"           parameter="delete" />      </menu_item_call>  </context_menu> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 2641ce4ee4..3557318705 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -927,7 +927,7 @@          <menu_item_check           label="Show Advanced Menu"           name="Show Advanced Menu" -         shortcut="control|alt|D"> +         shortcut="control|alt|shift|D">            <on_check             function="CheckControl"             parameter="UseDebugMenus" /> @@ -1477,6 +1477,18 @@                  <menu_item_call.on_click                   function="View.DefaultUISize" />              </menu_item_call> +            <!-- This second, alternative shortcut for Show Advanced Menu is for backward compatibility.  The main shortcut has been changed so it's Linux-friendly, where the old shortcut is typically eaten by the window manager. --> +            <menu_item_check +               label="Show Advanced Menu - legacy shortcut" +               name="Show Advanced Menu - legacy shortcut" +               shortcut="control|alt|D"> +              <on_check +		 function="CheckControl" +		 parameter="UseDebugMenus" /> +              <on_click +		 function="ToggleControl" +		 parameter="UseDebugMenus" /> +            </menu_item_check>              <menu_item_separator/>              <menu_item_check               label="Always Run" @@ -1652,7 +1664,6 @@               function="ToggleControl"               parameter="QAMode" />          </menu_item_check> -          </menu>      <menu       create_jump_keys="true" @@ -3278,4 +3289,4 @@              </menu>          </menu>      </menu> -</menu_bar>
\ No newline at end of file +</menu_bar> diff --git a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml index fa5ca60a19..430a7b6444 100644 --- a/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/en/menu_wearable_list_item.xml @@ -38,13 +38,6 @@       layout="topleft"       name="wearable_attach_to_hud" />      <menu_item_call -     label="Object Profile" -     layout="topleft" -     name="object_profile"> -        <on_click -         function="Attachment.Profile" /> -    </menu_item_call> -    <menu_item_call       label="Take Off"       layout="topleft"       name="take_off"> @@ -59,6 +52,13 @@           function="Wearable.Edit" />      </menu_item_call>      <menu_item_call +     label="Object Profile" +     layout="topleft" +     name="object_profile"> +        <on_click +         function="Attachment.Profile" /> +    </menu_item_call> +    <menu_item_call       label="Show Original"       layout="topleft"       name="show_original"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 439f67e7b1..cf3097cb06 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1397,8 +1397,7 @@ Unable to encode file: [FILE]     icon="alertmodal.tga"     name="CorruptedProtectedDataStore"     type="alertmodal"> -  We are unable to read your protected data so it is being reset. -   This may happen when you change network setup. +   We can't fill in your username and password.  This may happen when you change network setup      <usetemplate       name="okbutton" @@ -2066,6 +2065,7 @@ Would you be my friend?         name="Cancel"         text="Cancel"/>      </form> +    <unique/>    </notification>    <notification @@ -6207,7 +6207,7 @@ The button will be shown when there is enough space for it.     icon="notifytip.tga"     name="ShareNotification"     type="notifytip"> -Drag items from inventory onto a person in the resident picker +Select residents to share with.    </notification>    <notification     icon="notifytip.tga" diff --git a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml index 44437d01eb..bdfa928b1d 100644 --- a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml +++ b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml @@ -19,6 +19,6 @@       multi_select="true"       name="wearable_items_list"       translate="false" -     use_internal_context_menu="false" +     standalone="false"      />  </accordion_tab> diff --git a/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml index 4e5f594ffe..4f989a6f6f 100644 --- a/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_body_parts_list_item.xml @@ -57,7 +57,8 @@       left="0"       height="23"       width="23" -     tab_stop="false"> +     tab_stop="false" +     tool_tip="You don't have permission to edit">          <icon            name="btn_lock1"           layout="topleft" @@ -88,7 +89,8 @@            left="0"            height="23"            width="23" -          tab_stop="false" /> +          tab_stop="false" +          tool_tip="Edit this shape"/>        </panel>      <icon       follows="left|right|top" diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml index 859cc82e81..976f6d6cd0 100644 --- a/indra/newview/skins/default/xui/en/panel_classified_info.xml +++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml @@ -47,7 +47,7 @@       layout="topleft"       name="back_btn"       picture_style="true" -     left="9" +     left="10"       tab_stop="false"       top="2"       width="30" /> @@ -56,7 +56,7 @@       font="SansSerifHugeBold"       height="26"       layout="topleft" -     left_pad="10" +     left_pad="4"       name="title"       text_color="LtGray"       top="0" diff --git a/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml index 5d81aebbd5..93d7720c57 100644 --- a/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_clothing_list_item.xml @@ -37,7 +37,8 @@       left="0"       height="18"       width="18" -     tab_stop="false" /> +     tab_stop="false" +     tool_tip="Remove from outfit" />      <icon       height="16"       follows="top|left" @@ -88,7 +89,8 @@       left="0"       height="23"       width="23" -     tab_stop="false"> +     tab_stop="false" +     tool_tip="You don't have permission to edit">          <icon            name="btn_lock1"           layout="topleft" @@ -119,7 +121,8 @@           left="0"           height="23"           width="23" -         tab_stop="false" /> +         tab_stop="false" +         tool_tip="Edit this wearable"/>        </panel>      <icon       follows="left|right|top" diff --git a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml index d36c2a4e6f..f016c27b0a 100644 --- a/indra/newview/skins/default/xui/en/panel_cof_wearables.xml +++ b/indra/newview/skins/default/xui/en/panel_cof_wearables.xml @@ -28,7 +28,7 @@               allow_select="true"               follows="all"               height="10" -             item_pad="2" +             item_pad="3"               layout="topleft"               left="0"               multi_select="true" @@ -44,7 +44,7 @@               allow_select="true"               follows="all"               height="10" -             item_pad="2" +             item_pad="3"               layout="topleft"               left="0"               multi_select="true" @@ -60,7 +60,7 @@               allow_select="true"               follows="all"               height="10" -             item_pad="2" +             item_pad="3"               layout="topleft"               left="0"               multi_select="true" diff --git a/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml index 45031859f1..75b5fd1532 100644 --- a/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_deletable_wearable_list_item.xml @@ -37,7 +37,8 @@       left="0"       height="18"       width="18" -     tab_stop="false" /> +     tab_stop="false" +     tool_tip="Remove from outfit"/>      <icon       height="16"       follows="top|left" diff --git a/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml index 20652df918..a5dd34bd22 100644 --- a/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_dummy_clothing_list_item.xml @@ -49,16 +49,27 @@       top="4"       value="..."       width="359" /> -    <button  -     name="btn_add" +    <panel +     name="btn_add_panel"       layout="topleft"       follows="top|right" -     image_overlay="AddItem_Off"       top="0"       left="0"       height="23" -     width="23" -     tab_stop="false" /> +     width="26" +     tab_stop="false"> +      <button  +       name="btn_add" +       layout="topleft" +       follows="top|right" +       image_overlay="AddItem_Off" +       top="0" +       left="0" +       height="23" +       width="23" +       tab_stop="false" +       tool_tip="Add more items of this type" /> +    </panel>      <icon       follows="left|right|top"       height="3" diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml index 1b4f547f9d..6744a7b9c2 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml @@ -31,7 +31,7 @@       layout="topleft"       name="back_btn"       picture_style="true" -     left="7" +     left="10"       tab_stop="false"       top="2"       width="30" /> @@ -42,7 +42,7 @@       font="SansSerifHugeBold"       height="26"       layout="topleft" -     left_pad="10" +     left_pad="4"       name="title"       text_color="LtGray"       top="0" diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml index 589ea10e8d..dc83b334b5 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml @@ -24,7 +24,7 @@       image_unselected="BackButton_Off"       layout="topleft"       name="back_btn" -     left="7" +     left="10"       tab_stop="false"       top="2"       width="30" /> @@ -35,10 +35,10 @@       font="SansSerifHugeBold"       height="26"       layout="topleft" -     left_pad="10" +     left_pad="4"       name="title"       text_color="LtGray" -     top="0" +     top="2"       width="250">          Edit Pick      </text> diff --git a/indra/newview/skins/default/xui/en/panel_edit_shape.xml b/indra/newview/skins/default/xui/en/panel_edit_shape.xml index cf15fb0455..d295f5fe4a 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_shape.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_shape.xml @@ -8,19 +8,22 @@  	 name="edit_shape_panel"  	 top_pad="10"  	 width="333" > -	 <text -		 follows="top|left|right" -		 font="SansSerifSmallBold" -		 halign="right" -		 height="12" -		 layout="topleft" -		 left="0" -		 name="avatar_height" -		 text_color="EmphasisColor" -		 top="0" -		 width="310"> -		 [HEIGHT] Meters tall -	 </text> +     <string name="meters">Meters</string> +     <string name="feet">Feet</string> +     <string name="height">Height:</string> +     <string name="heigth_label_color" translate="false">White_50</string> +     <string name="heigth_value_label_color" translate="false">White</string> +     <text +         follows="top|left|right" +         font="SansSerifSmallBold" +         halign="right" +         height="12" +         layout="topleft" +         left="0" +         name="avatar_height" +         top="0" +         width="310"> +     </text>       <panel           border="false"           bg_alpha_color="DkGray2" diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml index 645ee8a435..950c4a5fdb 100644 --- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml @@ -141,15 +141,16 @@ left="0"       layout="topleft"       name="back_btn"       left="11" -     top="7" /> +     top="3" />  	<text  	 follows="top|left"  	 font="SansSerifHugeBold"  	 height="22"  	 layout="topleft" -	 left_pad="15" +	 left_pad="8"  	 name="edit_wearable_title"  	 text_color="white" +   top="3"   	 value="Editing Shape"  	 width="270" />       <panel diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml index 58b78cfa02..e4eb9afb29 100644 --- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml +++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml @@ -57,9 +57,9 @@ background_visible="true"        font="SansSerifHugeBold"       h_pad="0"        height="26" -      left_pad="10" +      left_pad="8"       text_color="LtGray" -      top="0" +      top="1"       use_ellipses="true"        width="275"        follows="top|left|right" diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml index 19fe2ea874..6523b0d491 100644 --- a/indra/newview/skins/default/xui/en/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml @@ -74,16 +74,14 @@ Maximum 200 per group daily      </text>        <button         follows="top|left" -       height="18" -       image_selected="AddItem_Press" -       image_unselected="AddItem_Off" -       image_disabled="AddItem_Disabled" +       height="23" +       image_overlay="AddItem_Off"         layout="topleft"         left="5"         name="create_new_notice"         tool_tip="Create a new notice" -     top_delta="-3" -       width="18" /> +       top_delta="-3" +       width="23" />       <button       follows="top|left"       height="23" diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml index bb73360e0b..55fef5aaf7 100644 --- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml +++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml @@ -63,7 +63,7 @@       image_pressed="BackButton_Press"       image_unselected="BackButton_Off"       layout="topleft" -     left="8" +     left="9"       name="back_btn"       tool_tip="Back"       tab_stop="false" @@ -74,10 +74,10 @@       font="SansSerifHugeBold"       height="26"       layout="topleft" -     left_pad="10" +     left_pad="7"       name="title"       text_color="LtGray" -     top="2" +     top="3"       use_ellipses="true"       value="Place Profile"       width="280" /> diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml index d65b86f007..2a53b3e2fa 100644 --- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml @@ -42,7 +42,7 @@    <filter_editor     text_pad_left="10"     follows="left|top|right" - height="23" +   height="23"     label="Filter Inventory"     layout="topleft"     left="10" @@ -68,10 +68,10 @@       top_pad="10"       width="312">      <inventory_panel -        bg_opaque_color="DkGray2" -   bg_alpha_color="DkGray2" -   background_visible="true" -   background_opaque="true" +     bg_opaque_color="DkGray2" +     bg_alpha_color="DkGray2" +     background_visible="true" +     background_opaque="true"       border="false"       bevel_style="none"       follows="all" @@ -82,13 +82,14 @@       left="0"       name="All Items"       sort_order_setting="InventorySortOrder" +	 show_item_link_overlays="true"       top="16"       width="288" />      <recent_inventory_panel -        bg_opaque_color="DkGray2" -   bg_alpha_color="DkGray2" -   background_visible="true" -   background_opaque="true" +     bg_opaque_color="DkGray2" +     bg_alpha_color="DkGray2" +     background_visible="true" +     background_opaque="true"       border="false"       bevel_style="none"       follows="all" @@ -98,6 +99,7 @@       layout="topleft"       left_delta="0"       name="Recent Items" +	 show_item_link_overlays="true"       width="290" />    </tab_container>    <layout_stack diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml index c9802a269c..ed3b176267 100644 --- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml @@ -51,6 +51,8 @@      <string name="Filter.All" value="All"/>      <string name="Filter.Clothes/Body" value="Clothes/Body"/>      <string name="Filter.Objects" value="Objects"/> +    <string name="Filter.Clothing" value="Clothing"/> +    <string name="Filter.Bodyparts" value="Body parts"/>      <button @@ -63,14 +65,14 @@       name="back_btn"       left="5"       tab_stop="false" -     top="2" +     top="1"       width="30" />      <text       follows="top|right"       font="SansSerifHugeBold"       height="26"       layout="topleft" -     left_pad="20" +     left_pad="10"       name="title"       text_color="LtGray"       top="0" @@ -210,6 +212,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap                       left="2"                       name="show_add_wearables_btn"                       top_pad="2" +                     tool_tip="Open/Close"                       width="125" />                      <combo_box @@ -217,11 +220,20 @@ It is calculated as border_size + 2*UIResizeBarOverlap                       height="22"                       layout="topleft"                       left_pad="5" -                     name="filter_wearables_combobox" +                     name="list_view_filter_combobox"                       top_delta="0"                       visible="false"                       width="152"/> - +                    <combo_box +                     follows="left|right|bottom" +                     height="22" +                     layout="topleft" +                     left_delta="0" +                     name="folder_view_filter_combobox" +                     top_delta="0" +                     visible="false" +                     width="152"/> +                                          <button                       follows="bottom|right"                       height="22" @@ -299,7 +311,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap               layout="topleft"               left="0"               mouse_opaque="false" -             name="inventory_items" +             name="folder_view"               top_pad="5"               width="310"               visible="false"/> @@ -318,7 +330,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap               visible="true">                  <wearable_items_list                   color="0.107 0.107 0.107 1" -                 name="filtered_wearables_list" +                 name="list_view"                   allow_select="true"                   layout="topleft"                   follows="all" @@ -482,6 +494,7 @@ It is calculated as border_size + 2*UIResizeBarOverlap           layout="topleft"           name="revert_btn"           top="0" +         tool_tip="Revert to last saved version"           width="147" />      </panel>  </panel> diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml index de1f2cf31b..37eb5eaa98 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml @@ -83,18 +83,18 @@        width="241"          /> -        <dnd_button -         follows="bottom|right" -         height="25" -         image_hover_unselected="Toolbar_Right_Over" -          image_overlay="TrashItem_Off" -          image_selected="Toolbar_Right_Selected" -          image_unselected="Toolbar_Right_Off" -         layout="topleft" -         left_pad="1" -         name="trash_btn" -         tool_tip="Remove selected item" -         width="31"/>          +     <dnd_button +      follows="bottom|right" +      height="25" +      image_hover_unselected="Toolbar_Right_Over" +      image_overlay="TrashItem_Off" +      image_selected="Toolbar_Right_Selected" +      image_unselected="Toolbar_Right_Off" +      layout="topleft" +      left_pad="1" +      name="trash_btn" +      tool_tip="Delete selected outfit" +      width="31"/>       <button         follows="bottom|left"         height="23" diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml index 49e1d16f6a..1d01bcb8a5 100644 --- a/indra/newview/skins/default/xui/en/panel_pick_info.xml +++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml @@ -18,7 +18,7 @@       image_unselected="BackButton_Off"       layout="topleft"       name="back_btn" -     left="7" +     left="10"       tab_stop="false"       top="2"       width="30" /> @@ -27,10 +27,10 @@       font="SansSerifHugeBold"       height="26"       layout="topleft" -     left_pad="10" +     left_pad="4"       name="title"       text_color="LtGray" -     top="0" +     top="2"       value="Pick Info"       use_ellipses="true"       width="275" /> diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml index 59f1f6d638..55e0184282 100644 --- a/indra/newview/skins/default/xui/en/panel_place_profile.xml +++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml @@ -160,7 +160,7 @@       image_pressed="BackButton_Press"       image_unselected="BackButton_Off"       layout="topleft" -     left="7" +     left="8"       name="back_btn"       tool_tip="Back"       tab_stop="false" @@ -174,7 +174,7 @@       left_pad="10"       name="title"       text_color="LtGray" -     top="2" +     top="4"       use_ellipses="true"       value="Place Profile"       width="280" /> diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml index 33f895e13a..638e190e8f 100644 --- a/indra/newview/skins/default/xui/en/panel_places.xml +++ b/indra/newview/skins/default/xui/en/panel_places.xml @@ -37,6 +37,7 @@ background_visible="true"       left="6"       name="Places Tabs"       tab_min_width="80" +     tab_max_width="157"       tab_height="30"       tab_group="1"       tab_position="top" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml index 1c68d59993..a69e8d29b0 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml @@ -348,7 +348,7 @@         Busy mode response:      </text>      <text_editor -     control_name="BusyModeResponse2" +     control_name="BusyModeResponse"        text_readonly_color="LabelDisabledColor"        bg_writeable_color="LtGray"        use_ellipses="false" diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml index cc5ba334d6..d9030fc0d6 100644 --- a/indra/newview/skins/default/xui/en/panel_profile_view.xml +++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml @@ -24,7 +24,7 @@       image_unselected="BackButton_Off"       layout="topleft"       name="back" -     left="9" +     left="10"       tab_stop="false"       top="2"       width="30" /> @@ -38,10 +38,10 @@        font="SansSerifHugeBold"        height="26"        layout="topleft" -      left_pad="10" +      left_pad="5"        name="user_name"        text_color="LtGray" -      top="0" +      top="2"        value="(Loading...)"        use_ellipses="true"        width="275" /> diff --git a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml index ae08a13793..e189d11d35 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_appearance.xml @@ -92,6 +92,7 @@ width="333">        layout="topleft"        left="265"        name="edit_outfit_btn" +      tool_tip="Edit this outfit"        top="7"        width="30" />        <loading_indicator @@ -144,7 +145,7 @@ width="333">     left="5"     min_height="410"     name="panel_outfit_edit" -   top="5" +   top="2"     visible="false"      width="320"/>     <panel diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml index c816fd1479..e2bd6f375e 100644 --- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml +++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml @@ -55,10 +55,10 @@       font="SansSerifHugeBold"       height="26"       layout="topleft" -     left_pad="10" +     left_pad="3"       name="title"       text_color="LtGray" -     top="0" +     top="2"       use_ellipses="true"       value="Object Profile"       width="275" /> @@ -395,7 +395,7 @@ top_pad="10"  			    label_width="75"  			    left="120"  			    width="170" -			    min_val="1" +			    min_val="0"  			    height="23"  			    max_val="999999999"  			    top_pad="10"/> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 0d14a6b3c8..294267d43b 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3181,12 +3181,12 @@ Abuse Report</string>    <!-- language specific white-space characters, delimiters, spacers, item separation symbols -->    <string name="sentences_separator" value=" "></string> -  <string name="words_separator">, </string> +  <string name="words_separator" value=", "/>    <string name="server_is_down">  	Despite our best efforts, something unexpected has gone wrong. -	Please check secondlife.com/status to see if there is a known problem with the service.   +	Please check status.secondlifegrid.net to see if there is a known problem with the service.            If you continue to experience problems, please check your network and firewall setup.    </string> diff --git a/indra/newview/skins/default/xui/en/widgets/accordion.xml b/indra/newview/skins/default/xui/en/widgets/accordion.xml index b817ba56ca..05d7447a6f 100644 --- a/indra/newview/skins/default/xui/en/widgets/accordion.xml +++ b/indra/newview/skins/default/xui/en/widgets/accordion.xml @@ -8,7 +8,6 @@       height="100"       h_pad="10"       name="no_visible_items_msg" -     value="There are no visible content here."       v_pad="15"       width="200"       wrap="true "/> diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml index 55e699612c..026b7b7616 100644 --- a/indra/newview/skins/default/xui/it/floater_about.xml +++ b/indra/newview/skins/default/xui/it/floater_about.xml @@ -27,9 +27,9 @@ Scheda grafica: [GRAPHICS_CARD]  Versione libcurl: [LIBCURL_VERSION]  Versione J2C Decoder: [J2C_VERSION] -Versione Audio Driver: [AUDIO_DRIVER_VERSION] +Versione Driver audio: [AUDIO_DRIVER_VERSION]  Versione Qt Webkit: [QT_WEBKIT_VERSION] -Versione Vivox: [VIVOX_VERSION] +Versione Server voice: [VOICE_VERSION]  	</floater.string>  	<floater.string name="none">  		(nessuno) diff --git a/indra/newview/skins/default/xui/it/floater_about_land.xml b/indra/newview/skins/default/xui/it/floater_about_land.xml index c55f79738e..942b79b7d3 100644 --- a/indra/newview/skins/default/xui/it/floater_about_land.xml +++ b/indra/newview/skins/default/xui/it/floater_about_land.xml @@ -63,6 +63,9 @@  				Nessun appezzamento selezionato.  Vai al menu Mondo > Informazioni sul terreno oppure seleziona un altro appezzamento per vederne i dettagli.  			</panel.string> +			<panel.string name="time_stamp_template"> +				[wkday,datetime,local] [day,datetime,local] [mth,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] +			</panel.string>  			<text name="Name:">  				Nome:  			</text> diff --git a/indra/newview/skins/default/xui/it/floater_avatar_textures.xml b/indra/newview/skins/default/xui/it/floater_avatar_textures.xml index 2935f0fdb6..b6376973cd 100644 --- a/indra/newview/skins/default/xui/it/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/it/floater_avatar_textures.xml @@ -3,41 +3,48 @@  	<floater.string name="InvalidAvatar">  		AVATAR NON VALIDO  	</floater.string> -	<text name="composite_label"> -		Texture Composite -	</text> -	<button label="Deposito" label_selected="Deposito" name="Dump"/>  	<scroll_container name="profile_scroll">  		<panel name="scroll_content_panel"> -			<texture_picker label="Capigliature" name="hair-baked"/> -			<texture_picker label="Capigliature" name="hair_grain"/> -			<texture_picker label="Alpha dei capelli" name="hair_alpha"/> -			<texture_picker label="Testa" name="head-baked"/> -			<texture_picker label="Makeup" name="head_bodypaint"/> -			<texture_picker label="Alpha della testa" name="head_alpha"/> -			<texture_picker label="Tatuaggio della testa" name="head_tattoo"/> -			<texture_picker label="Occhi" name="eyes-baked"/> -			<texture_picker label="Occhio" name="eyes_iris"/> -			<texture_picker label="Alpha degli occhi" name="eyes_alpha"/> -			<texture_picker label="Parte superiore del corpo" name="upper-baked"/> -			<texture_picker label="Bodypaint parte superiore del corpo" name="upper_bodypaint"/> -			<texture_picker label="Maglietta intima" name="upper_undershirt"/> -			<texture_picker label="Guanti" name="upper_gloves"/> -			<texture_picker label="Camicia" name="upper_shirt"/> -			<texture_picker label="Parte superiore della giacca" name="upper_jacket"/> -			<texture_picker label="Alpha superiore" name="upper_alpha"/> -			<texture_picker label="Tatuaggio superiore" name="upper_tattoo"/> -			<texture_picker label="Parte inferiore del corpo" name="lower-baked"/> -			<texture_picker label="Bodypaint parte inferiore del corpo" name="lower_bodypaint"/> -			<texture_picker label="Slip" name="lower_underpants"/> -			<texture_picker label="Calzini" name="lower_socks"/> -			<texture_picker label="Scarpe" name="lower_shoes"/> -			<texture_picker label="Pantaloni" name="lower_pants"/> -			<texture_picker label="Giacca" name="lower_jacket"/> -			<texture_picker label="Alpha inferiore" name="lower_alpha"/> -			<texture_picker label="Tattuaggio inferiore" name="lower_tattoo"/> -			<texture_picker label="Gonna" name="skirt-baked"/> -			<texture_picker label="Gonna" name="skirt"/> +			<text name="label"> +				Baking delle +texture +			</text> +			<text name="composite_label"> +				Composito +Texture +			</text> +			<button label="Memorizza gli ID sulla console" label_selected="Dump" name="Dump"/> +			<panel name="scroll_content_panel"> +				<texture_picker label="Capigliature" name="hair-baked"/> +				<texture_picker label="Capigliature" name="hair_grain"/> +				<texture_picker label="Alpha dei capelli" name="hair_alpha"/> +				<texture_picker label="Testa" name="head-baked"/> +				<texture_picker label="Makeup" name="head_bodypaint"/> +				<texture_picker label="Alpha della testa" name="head_alpha"/> +				<texture_picker label="Tatuaggio della testa" name="head_tattoo"/> +				<texture_picker label="Occhi" name="eyes-baked"/> +				<texture_picker label="Occhio" name="eyes_iris"/> +				<texture_picker label="Alpha degli occhi" name="eyes_alpha"/> +				<texture_picker label="Parte superiore del corpo" name="upper-baked"/> +				<texture_picker label="Bodypaint parte superiore del corpo" name="upper_bodypaint"/> +				<texture_picker label="Maglietta intima" name="upper_undershirt"/> +				<texture_picker label="Guanti" name="upper_gloves"/> +				<texture_picker label="Camicia" name="upper_shirt"/> +				<texture_picker label="Parte superiore della giacca" name="upper_jacket"/> +				<texture_picker label="Alpha superiore" name="upper_alpha"/> +				<texture_picker label="Tatuaggio superiore" name="upper_tattoo"/> +				<texture_picker label="Parte inferiore del corpo" name="lower-baked"/> +				<texture_picker label="BodyPaint parte inferiore del corpo" name="lower_bodypaint"/> +				<texture_picker label="Slip" name="lower_underpants"/> +				<texture_picker label="Calzini" name="lower_socks"/> +				<texture_picker label="Scarpe" name="lower_shoes"/> +				<texture_picker label="Pantaloni" name="lower_pants"/> +				<texture_picker label="Giacca" name="lower_jacket"/> +				<texture_picker label="Alpha inferiore" name="lower_alpha"/> +				<texture_picker label="Tattuaggio inferiore" name="lower_tattoo"/> +				<texture_picker label="Gonna" name="skirt-baked"/> +				<texture_picker label="Gonna" name="skirt"/> +			</panel>  		</panel>  	</scroll_container>  </floater> diff --git a/indra/newview/skins/default/xui/it/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/it/floater_buy_currency_html.xml new file mode 100644 index 0000000000..4a1bf33403 --- /dev/null +++ b/indra/newview/skins/default/xui/it/floater_buy_currency_html.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_buy_currency_html" title="ACQUISTA VALUTA"/> diff --git a/indra/newview/skins/default/xui/it/floater_map.xml b/indra/newview/skins/default/xui/it/floater_map.xml index 70ab8dcb5a..d1e9c98e79 100644 --- a/indra/newview/skins/default/xui/it/floater_map.xml +++ b/indra/newview/skins/default/xui/it/floater_map.xml @@ -1,5 +1,5 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Map" title="Mini mappa"> +<floater name="Map" title="">  	<floater.string name="mini_map_north">  		N  	</floater.string> diff --git a/indra/newview/skins/default/xui/it/floater_moveview.xml b/indra/newview/skins/default/xui/it/floater_moveview.xml index 26d861c566..cdafdb0089 100644 --- a/indra/newview/skins/default/xui/it/floater_moveview.xml +++ b/indra/newview/skins/default/xui/it/floater_moveview.xml @@ -6,18 +6,48 @@  	<string name="walk_back_tooltip">  		Cammina indietro (premi freccia giù o S)  	</string> +	<string name="walk_left_tooltip"> +		Cammina a sinistra (premi Maiusc + freccia sinistra o A) +	</string> +	<string name="walk_right_tooltip"> +		Cammina a destra (premi Maiusc + freccia destra o D) +	</string>  	<string name="run_forward_tooltip">  		Corri in avanti (premi freccia su o W)  	</string>  	<string name="run_back_tooltip">  		Corri indietro (premi freccia giù o S)  	</string> +	<string name="run_left_tooltip"> +		Corri a sinistra (premi Maiusc + freccia sinistra o A) +	</string> +	<string name="run_right_tooltip"> +		Corri a destra (premi Maiusc + freccia destra o D) +	</string>  	<string name="fly_forward_tooltip">  		Vola in avanti (premi freccia su o W)  	</string>  	<string name="fly_back_tooltip">  		Vola indietro (premi freccia giù o S)  	</string> +	<string name="fly_left_tooltip"> +		Vola a sinistra (premi Maiusc + freccia sinistra o A) +	</string> +	<string name="fly_right_tooltip"> +		Vola a destra (premi Maiusc + freccia destra o D) +	</string> +	<string name="fly_up_tooltip"> +		Vola in alto (premi E) +	</string> +	<string name="fly_down_tooltip"> +		Vola in basso (premi C) +	</string> +	<string name="jump_tooltip"> +		Salta (premi E) +	</string> +	<string name="crouch_tooltip"> +		Accovacciarsi (premi C) +	</string>  	<string name="walk_title">  		Cammina  	</string> @@ -28,10 +58,12 @@  		Vola  	</string>  	<panel name="panel_actions"> +		<button label="" label_selected="" name="move up btn" tool_tip="Vola in alto (premi E)"/>  		<button label="" label_selected="" name="turn left btn" tool_tip="Gira a sinistra (premi freccia sinistra o A)"/> +		<joystick_slide name="move left btn" tool_tip="Cammina a sinistra (premi Maiusc + freccia sinistra o A)"/> +		<button label="" label_selected="" name="move down btn" tool_tip="Vola in basso (premi C)"/>  		<button label="" label_selected="" name="turn right btn" tool_tip="Gira a destra (premi freccia destra o D)"/> -		<button label="" label_selected="" name="move up btn" tool_tip="Vola in alto, premi E"/> -		<button label="" label_selected="" name="move down btn" tool_tip="Vola in basso, premi C"/> +		<joystick_slide name="move right btn" tool_tip="Cammina a destra (premi Maiusc + freccia destra o D)"/>  		<joystick_turn name="forward btn" tool_tip="Cammina in avanti (premi freccia su o W)"/>  		<joystick_turn name="backward btn" tool_tip="Cammina indietro (premi freccia giù o S)"/>  	</panel> diff --git a/indra/newview/skins/default/xui/it/floater_preview_notecard.xml b/indra/newview/skins/default/xui/it/floater_preview_notecard.xml index 70e28dde35..7ec229f9d3 100644 --- a/indra/newview/skins/default/xui/it/floater_preview_notecard.xml +++ b/indra/newview/skins/default/xui/it/floater_preview_notecard.xml @@ -9,9 +9,6 @@  	<floater.string name="Title">  		Biglietto: [NAME]  	</floater.string> -	<floater.string label="Salva" label_selected="Salva" name="Save"> -		Salva -	</floater.string>  	<text name="desc txt">  		Descrizione:  	</text> @@ -19,4 +16,5 @@  		In caricamento...  	</text_editor>  	<button label="Salva" label_selected="Salva" name="Save"/> +	<button label="Elimina" label_selected="Elimina" name="Delete"/>  </floater> diff --git a/indra/newview/skins/default/xui/it/floater_tools.xml b/indra/newview/skins/default/xui/it/floater_tools.xml index 04d61b97ff..68d193ff33 100644 --- a/indra/newview/skins/default/xui/it/floater_tools.xml +++ b/indra/newview/skins/default/xui/it/floater_tools.xml @@ -67,9 +67,9 @@  	<text name="RenderingCost" tool_tip="Mostra il costo di rendering calcolato per questo oggetto">  		þ: [COUNT]  	</text> -	<check_box name="checkbox uniform"/> -	<text name="checkbox uniform label"> -		Ridimens. simmetricamente +	<check_box label="" name="checkbox uniform"/> +	<text label="Allunga entrambi i lati" name="checkbox uniform label"> +		Allunga entrambi i lati  	</text>  	<check_box initial_value="true" label="Ridimensiona le texture" name="checkbox stretch textures"/>  	<check_box initial_value="true" label="Posiziona nella griglia" name="checkbox snap to grid"/> @@ -445,8 +445,8 @@  			<check_box label="Inverti" name="checkbox flip s"/>  			<spinner label="Verticale (V)" name="TexScaleV"/>  			<check_box label="Inverti" name="checkbox flip t"/> -			<spinner label="Rotazione˚" name="TexRot" /> -			<spinner label="Ripetizioni / Metro" name="rptctrl" /> +			<spinner label="Rotazione˚" name="TexRot"/> +			<spinner label="Ripetizioni / Metro" name="rptctrl"/>  			<button label="Applica" label_selected="Applica" name="button apply"/>  			<text name="tex offset">  				Bilanciamento della texture diff --git a/indra/newview/skins/default/xui/it/menu_attachment_self.xml b/indra/newview/skins/default/xui/it/menu_attachment_self.xml index 054f4802e6..c480a2fe0e 100644 --- a/indra/newview/skins/default/xui/it/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/it/menu_attachment_self.xml @@ -5,7 +5,7 @@  	<menu_item_call label="Stacca" name="Detach"/>  	<menu_item_call label="Lascia" name="Drop"/>  	<menu_item_call label="Alzati" name="Stand Up"/> -	<menu_item_call label="Il mio aspetto" name="Appearance..."/> +	<menu_item_call label="Cambia vestiario" name="Change Outfit"/>  	<menu_item_call label="I miei amici..." name="Friends..."/>  	<menu_item_call label="I miei gruppi" name="Groups..."/>  	<menu_item_call label="Il mio profilo" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/it/menu_avatar_self.xml b/indra/newview/skins/default/xui/it/menu_avatar_self.xml index d73d97d499..7796d41286 100644 --- a/indra/newview/skins/default/xui/it/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/it/menu_avatar_self.xml @@ -20,7 +20,9 @@  		<context_menu label="Stacca  ▶" name="Object Detach"/>  		<menu_item_call label="Stacca tutto" name="Detach All"/>  	</context_menu> -	<menu_item_call label="Il mio aspetto" name="Appearance..."/> +	<menu_item_call label="Cambia vestiario" name="Chenge Outfit"/> +	<menu_item_call label="Modifica il mio vestiario" name="Edit Outfit"/> +	<menu_item_call label="Modifica la figura corporea" name="Edit My Shape"/>  	<menu_item_call label="I miei amici..." name="Friends..."/>  	<menu_item_call label="I miei gruppi" name="Groups..."/>  	<menu_item_call label="Il mio profilo" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/it/menu_bottomtray.xml b/indra/newview/skins/default/xui/it/menu_bottomtray.xml index 7203d002d2..8ca5b24b48 100644 --- a/indra/newview/skins/default/xui/it/menu_bottomtray.xml +++ b/indra/newview/skins/default/xui/it/menu_bottomtray.xml @@ -4,6 +4,11 @@  	<menu_item_check label="Tasto Movimento" name="ShowMoveButton"/>  	<menu_item_check label="Tasto Visuale" name="ShowCameraButton"/>  	<menu_item_check label="Tasto Foto" name="ShowSnapshotButton"/> +	<menu_item_check label="Pulsante barra laterale" name="ShowSidebarButton"/> +	<menu_item_check label="Pulsante Costruisci" name="ShowBuildButton"/> +	<menu_item_check label="Pulsante Cerca" name="ShowSearchButton"/> +	<menu_item_check label="Pulsante Mappa" name="ShowWorldMapButton"/> +	<menu_item_check label="Pulsante Mini mappa" name="ShowMiniMapButton"/>  	<menu_item_call label="Taglia" name="NearbyChatBar_Cut"/>  	<menu_item_call label="Copia" name="NearbyChatBar_Copy"/>  	<menu_item_call label="Incolla" name="NearbyChatBar_Paste"/> diff --git a/indra/newview/skins/default/xui/it/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/it/menu_inspect_self_gear.xml index 33229bb7c0..80edae8a2b 100644 --- a/indra/newview/skins/default/xui/it/menu_inspect_self_gear.xml +++ b/indra/newview/skins/default/xui/it/menu_inspect_self_gear.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8"?>  <menu name="Gear Menu">  	<menu_item_call label="Alzati" name="stand_up"/> -	<menu_item_call label="Il mio aspetto" name="my_appearance"/> +	<menu_item_call label="Cambia vestiario" name="change_outfit"/>  	<menu_item_call label="Il mio profilo" name="my_profile"/>  	<menu_item_call label="I miei amici..." name="my_friends"/>  	<menu_item_call label="I miei gruppi" name="my_groups"/> diff --git a/indra/newview/skins/default/xui/it/menu_inventory.xml b/indra/newview/skins/default/xui/it/menu_inventory.xml index 3b36198774..b127f8b816 100644 --- a/indra/newview/skins/default/xui/it/menu_inventory.xml +++ b/indra/newview/skins/default/xui/it/menu_inventory.xml @@ -54,6 +54,7 @@  	<menu_item_call label="Elimina oggetto" name="Purge Item"/>  	<menu_item_call label="Ripristina oggetto" name="Restore Item"/>  	<menu_item_call label="Apri" name="Open"/> +	<menu_item_call label="Apri originale" name="Open Original"/>  	<menu_item_call label="Proprietà" name="Properties"/>  	<menu_item_call label="Rinomina" name="Rename"/>  	<menu_item_call label="Copia UUID dell'oggetto" name="Copy Asset UUID"/> diff --git a/indra/newview/skins/default/xui/it/menu_login.xml b/indra/newview/skins/default/xui/it/menu_login.xml index 904b819198..0a6d803058 100644 --- a/indra/newview/skins/default/xui/it/menu_login.xml +++ b/indra/newview/skins/default/xui/it/menu_login.xml @@ -2,7 +2,7 @@  <menu_bar name="Login Menu">  	<menu label="Io" name="File">  		<menu_item_call label="Preferenze" name="Preferences..."/> -		<menu_item_call label="Chiudi" name="Quit"/> +		<menu_item_call label="Esci da [APP_NAME]" name="Quit"/>  	</menu>  	<menu label="Aiuto" name="Help">  		<menu_item_call label="Aiuto di [SECOND_LIFE]" name="Second Life Help"/> diff --git a/indra/newview/skins/default/xui/it/menu_participant_list.xml b/indra/newview/skins/default/xui/it/menu_participant_list.xml index 71f1a9a0da..f70b886a1e 100644 --- a/indra/newview/skins/default/xui/it/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/it/menu_participant_list.xml @@ -14,8 +14,8 @@  	<context_menu label="Opzioni moderatore  >" name="Moderator Options">  		<menu_item_check label="Consenti chat di testo" name="AllowTextChat"/>  		<menu_item_call label="Disattiva audio di questo participante" name="ModerateVoiceMuteSelected"/> -		<menu_item_call label="Disattiva audio di tutti gli altri" name="ModerateVoiceMuteOthers"/>  		<menu_item_call label="Riattiva audio di questo participante" name="ModerateVoiceUnMuteSelected"/> -		<menu_item_call label="Riattiva audio di tutti gli altri" name="ModerateVoiceUnMuteOthers"/> +		<menu_item_call label="Disattiva audio di tutti" name="ModerateVoiceMute"/> +		<menu_item_call label="Riattiva audio di tutti" name="ModerateVoiceUnmute"/>  	</context_menu>  </context_menu> diff --git a/indra/newview/skins/default/xui/it/menu_viewer.xml b/indra/newview/skins/default/xui/it/menu_viewer.xml index a5923ac42b..999f89a80d 100644 --- a/indra/newview/skins/default/xui/it/menu_viewer.xml +++ b/indra/newview/skins/default/xui/it/menu_viewer.xml @@ -7,7 +7,7 @@  		</menu_item_call>  		<menu_item_call label="Compra L$" name="Buy and Sell L$"/>  		<menu_item_call label="Il mio profilo" name="Profile"/> -		<menu_item_call label="Il mio aspetto" name="Appearance"/> +		<menu_item_call label="Cambia vestiario" name="ChangeOutfit"/>  		<menu_item_check label="Il mio inventario" name="Inventory"/>  		<menu_item_check label="Il mio inventario" name="ShowSidetrayInventory"/>  		<menu_item_check label="Le mie gesture" name="Gestures"/> @@ -162,6 +162,7 @@  			<menu_item_check label="Oggetti flessibili" name="Flexible Objects"/>  		</menu>  		<menu_item_check label="Esegui thread multipli" name="Run Multiple Threads"/> +		<menu_item_check label="Usa thread lettura plugin" name="Use Plugin Read Thread"/>  		<menu_item_call label="Pulisci cache di gruppo" name="ClearGroupCache"/>  		<menu_item_check label="Fluidità mouse" name="Mouse Smoothing"/>  		<menu label="Scorciatoie" name="Shortcuts"> @@ -188,7 +189,6 @@  			<menu_item_call label="Zoom avanti" name="Zoom In"/>  			<menu_item_call label="Zoom predefinito" name="Zoom Default"/>  			<menu_item_call label="Zoom indietro" name="Zoom Out"/> -			<menu_item_call label="Alterna schermo intero" name="Toggle Fullscreen"/>  		</menu>  		<menu_item_call label="Mostra impostazioni di debug" name="Debug Settings"/>  		<menu_item_check label="Mostra menu sviluppo" name="Debug Mode"/> diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml index 4739e5cce9..058353da38 100644 --- a/indra/newview/skins/default/xui/it/notifications.xml +++ b/indra/newview/skins/default/xui/it/notifications.xml @@ -326,6 +326,9 @@ Hai bisogno di un account per entrare in [SECOND_LIFE]. Ne vuoi creare uno adess  		</url>  		<usetemplate name="okcancelbuttons" notext="Riprova" yestext="Crea un nuovo account"/>  	</notification> +	<notification name="InvalidCredentialFormat"> +		Immetti sia il nome che il cognome del tuo avatar nel campo del nome utente, quindi effettua l'accesso. +	</notification>  	<notification name="AddClassified">  		L'inserzione comparirà nella sezione 'Annunci' della Ricerca e su [http://secondlife.com/community/classifieds secondlife.com] per una settimana.  Compila la tua inserzione, quindi clicca 'Pubblica...' per aggiungerla all'elenco degli annunci. @@ -608,6 +611,11 @@ Attese [VALIDS]  	<notification name="CannotEncodeFile">  		Impossibile codificare il file: [FILE]  	</notification> +	<notification name="CorruptedProtectedDataStore"> +		Poiché non è possibile leggere i dati protetti, ora verranno ripristinati. +   Ciò può succedere alla modifica delle impostazioni di rete. +		<usetemplate name="okbutton" yestext="OK"/> +	</notification>  	<notification name="CorruptResourceFile">  		File risorsa corrotto: [FILE]  	</notification> @@ -968,6 +976,12 @@ su TUTTI I TERRENI di questa sim?  Introduci un prezzo più alto.  	</notification> +	<notification name="ConfirmItemDeleteHasLinks"> +		Almeno uno degli oggetti selezionati è collegato tramite link ad altri oggetti.  Se elimini l'oggetto, i relativi link non funzioneranno più.  Pertanto si consiglia vivamente di eliminare prima i link. + +Sei sicuro di volere eliminare gli oggetti? +		<usetemplate name="okcancelbuttons" notext="Annulla" yestext="OK"/> +	</notification>  	<notification name="ConfirmObjectDeleteLock">  		Almeno uno degli elementi selezionati è bloccato. @@ -1117,6 +1131,42 @@ Premi F1 in qualunque momento per la guida o per apprendere altre cose di [SECON  Scegli un avatar maschile o femminile. Puoi sempre cambiare idea più tardi.  		<usetemplate name="okcancelbuttons" notext="Femminile" yestext="Maschile"/>  	</notification> +	<notification name="CantTeleportToGrid"> +		Impossibile effettuare il teleport su [SLURL], in quanto si trova su una griglia ([GRID]) diversa da quella attuale ([CURRENT_GRID]).  Chiudi il viewer e prova nuovamente. +		<usetemplate name="okbutton" yestext="OK"/> +	</notification> +	<notification name="GeneralCertificateError"> +		Impossibile collegarsi al server. +[REASON] + +Nome oggetto: [SUBJECT_NAME_STRING] +Nome emittente: [ISSUER_NAME_STRING] +Valido da: [VALID_FROM] +Valido fino a: [VALID_TO] +Impronta MD5: [SHA1_DIGEST] +Impronta SHA1: [MD5_DIGEST] +Uso chiave: [KEYUSAGE] +Uso chiave estesa: [EXTENDEDKEYUSAGE] +Identificatore chiave oggetto: [SUBJECTKEYIDENTIFIER] +		<usetemplate name="okbutton" yestext="OK"/> +	</notification> +	<notification name="TrustCertificateError"> +		Autorità di certificazione di questo server sconosciuta. + +Informazioni sul certificato: +Nome oggetto: [SUBJECT_NAME_STRING] +Nome emittente: [ISSUER_NAME_STRING] +Valido da: [VALID_FROM] +Valido fino a: [VALID_TO] +Impronta MD5: [SHA1_DIGEST] +Impronta SHA1: [MD5_DIGEST] +Uso chiave: [KEYUSAGE] +Uso chiave estesa: [EXTENDEDKEYUSAGE] +Identificatore chiave oggetto: [SUBJECTKEYIDENTIFIER] + +Accettare questa autorità? +		<usetemplate name="okcancelbuttons" notext="Annulla" yestext="Accetta"/> +	</notification>  	<notification name="NotEnoughCurrency">  		[NAME] [PRICE]L$ Non hai abbastanza L$ per farlo.  	</notification> @@ -1512,7 +1562,7 @@ Vuoi andare alla Knowledge Base per ulteriori informazioni sulle categorie di ac  	<notification name="RegionEntryAccessBlocked_Change">  		Non ti è consentito entrare in quella regione a causa della tua categoria di accesso impostata nelle preferenze. -Puoi cliccare su Cambia preferenze per modificare la categoria di accesso e quindi riuscire ad entrare. Da adesso potrai accedere ai contenuti [REGIONMATURITY] ed effettuare ricerche in questa categoria. Se in seguito tu volessi cambiare di nuovo le tue impostazioni, apri la finestra di dialogo da Io > Preferenze > Generale. +Clicca su Cambia preferenze per modificare la categoria di accesso e potere entrare subito. Ciò ti consentirà di effettuare ricerche di contenuti di categoria [REGIONMATURITY]. Potrai modificare queste impostazioni in un secondo momento da Io > Preferenze > Generali.  		<form name="form">  			<button name="OK" text="Cambia preferenza"/>  			<button default="true" name="Cancel" text="Chiudi"/> @@ -2283,15 +2333,6 @@ Riprova tra qualche istante.  			<button name="Mute" text="Blocca"/>  		</form>  	</notification> -	<notification name="ObjectGiveItemUnknownUser"> -		Un oggetto chiamato [OBJECTFROMNAME] di proprietà di (residente sconosciuto) ti ha dato questo [OBJECTTYPE]: -[ITEM_SLURL] -		<form name="form"> -			<button name="Keep" text="Prendi"/> -			<button name="Discard" text="Rifiuta"/> -			<button name="Mute" text="Blocca"/> -		</form> -	</notification>  	<notification name="UserGiveItem">  		[NAME_SLURL] ti ha dato questo [OBJECTTYPE]:  [ITEM_SLURL] @@ -2604,8 +2645,52 @@ Il pulsante verrà visualizzato quando lo spazio sarà sufficiente.  	<notification name="ShareNotification">  		Trascina articoli dell'inventario su una persona nel selettore residenti  	</notification> +	<notification name="DeedToGroupFail"> +		Cessione al gruppo non riuscita. +	</notification>  	<notification name="AvatarRezNotification"> -		Avatar '[NAME]' rezzato in [TIME] secondi. +		( presente da [EXISTENCE] secondi ) +Nuvola avatar '[NAME]' risolta in [TIME] secondi. +	</notification> +	<notification name="AvatarRezSelfNotification"> +		( presente da [EXISTENCE] secondi ) +Baking dei vestiti eseguito in [TIME] secondi. +	</notification> +	<notification name="AvatarRezCloudNotification"> +		( presente da [EXISTENCE] secondi ) +Avatar '[NAME]' trasformato in nuvola. +	</notification> +	<notification name="AvatarRezArrivedNotification"> +		( presente da [EXISTENCE] secondi ) +È comparso l'avatar '[NAME]'. +	</notification> +	<notification name="AvatarRezLeftCloudNotification"> +		( presente da [EXISTENCE] secondi ) +Avatar '[NAME]' partito dopo [TIME] secondi sotto forma di nuvola. +	</notification> +	<notification name="AvatarRezEnteredAppearanceNotification"> +		( presente da [EXISTENCE] secondi ) +Avatar '[NAME]' è entrato nella modalità aspetto. +	</notification> +	<notification name="AvatarRezLeftAppearanceNotification"> +		( presente da [EXISTENCE] secondi ) +Avatar '[NAME]' ha lasciato la modalità aspetto. +	</notification> +	<notification name="AvatarRezLeftNotification"> +		( presente da [EXISTENCE] secondi ) +Avatar '[NAME]' è partito completamente caricato. +	</notification> +	<notification name="ConfirmLeaveCall"> +		Sei sicuro di volere uscire dalla chiamata? +		<usetemplate ignoretext="Conferma prima di uscire dalla chiamata" name="okcancelignore" notext="No" yestext="Sì"/> +	</notification> +	<notification name="ConfirmMuteAll"> +		Hai scelto di disattivare l'audio di tutti i partecipanti alla chiamata di gruppo. +In questo modo verrà disattivato l'audio anche di tutti i residenti che si +uniscono alla chiamata in un secondo momento, anche dopo che tu ti fossi scollegato. + +Disattiva audio di tutti? +		<usetemplate ignoretext="Conferma prima di disattivare l'audio di tutti i partecipanti alla chiamata di gruppo" name="okcancelignore" notext="Ok" yestext="Annulla"/>  	</notification>  	<global name="UnsupportedCPU">  		- La velocità della tua CPU non soddisfa i requisiti minimi. diff --git a/indra/newview/skins/default/xui/it/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/it/panel_body_parts_list_item.xml new file mode 100644 index 0000000000..de764d8025 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_body_parts_list_item.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="wearable_item"> +	<text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/it/panel_bodyparts_list_button_bar.xml new file mode 100644 index 0000000000..8fc23d34f1 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_bodyparts_list_button_bar.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="clothing_list_button_bar_panel"> +	<button label="Cambia" name="switch_btn"/> +	<button label="Acquista >" name="bodyparts_shop_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_bottomtray.xml b/indra/newview/skins/default/xui/it/panel_bottomtray.xml index c0218fad5e..e4d99cc402 100644 --- a/indra/newview/skins/default/xui/it/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/it/panel_bottomtray.xml @@ -1,11 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="bottom_tray"> -	<string name="SpeakBtnToolTip"> -		Accende o spegne il microfono -	</string> -	<string name="VoiceControlBtnToolTip"> -		Mostra o nasconde il pannello di regolazione voce -	</string> +	<string name="SpeakBtnToolTip" value="Accende o spegne il microfono"/> +	<string name="VoiceControlBtnToolTip" value="Mostra o nasconde il pannello di regolazione voce"/>  	<layout_stack name="toolbar_stack">  		<layout_panel name="speak_panel">  			<talk_button name="talk"> @@ -24,6 +20,21 @@  		<layout_panel name="snapshot_panel">  			<button label="" name="snapshots" tool_tip="Scatta una foto"/>  		</layout_panel> +		<layout_panel name="sidebar_btn_panel"> +			<button label="Barra laterale" name="sidebar_btn" tool_tip="Mostra o nasconde la barra laterale"/> +		</layout_panel> +		<layout_panel name="build_btn_panel"> +			<button label="Costruisci" name="build_btn" tool_tip="Mostra o nasconde gli strumenti di costruzione"/> +		</layout_panel> +		<layout_panel name="search_btn_panel"> +			<button label="Cerca" name="search_btn" tool_tip="Mostra o nasconde la ricerca"/> +		</layout_panel> +		<layout_panel name="world_map_btn_panel"> +			<button label="Mappa" name="world_map_btn" tool_tip="Mostra o nasconde la mappa del mondo"/> +		</layout_panel> +		<layout_panel name="mini_map_btn_panel"> +			<button label="Mini mappa" name="mini_map_btn" tool_tip="Mostra o nasconde la mini mappa"/> +		</layout_panel>  		<layout_panel name="im_well_panel">  			<chiclet_im_well name="im_well">  				<button name="Unread IM messages" tool_tip="Conversazioni"/> diff --git a/indra/newview/skins/default/xui/it/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/it/panel_clothing_list_button_bar.xml new file mode 100644 index 0000000000..e9d9795b3a --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_clothing_list_button_bar.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="clothing_list_button_bar_panel"> +	<button label="Aggiungi +" name="add_btn"/> +	<button label="Acquista >" name="clothing_shop_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/it/panel_clothing_list_item.xml new file mode 100644 index 0000000000..de764d8025 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_clothing_list_item.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="wearable_item"> +	<text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_cof_wearables.xml b/indra/newview/skins/default/xui/it/panel_cof_wearables.xml new file mode 100644 index 0000000000..d914a5740f --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_cof_wearables.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="cof_wearables"> +	<accordion name="cof_wearables_accordion"> +		<accordion_tab name="tab_attachments" title="Allegati"/> +		<accordion_tab name="tab_clothing" title="Vestiario"/> +		<accordion_tab name="tab_body_parts" title="Parti del corpo"/> +	</accordion> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/it/panel_deletable_wearable_list_item.xml new file mode 100644 index 0000000000..91d90a5660 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_deletable_wearable_list_item.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="deletable_wearable_item"> +	<text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/it/panel_dummy_clothing_list_item.xml new file mode 100644 index 0000000000..6af84de0c7 --- /dev/null +++ b/indra/newview/skins/default/xui/it/panel_dummy_clothing_list_item.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="dummy_clothing_item"> +	<text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/it/panel_edit_shape.xml b/indra/newview/skins/default/xui/it/panel_edit_shape.xml index 7e1ba43756..ab77548f26 100644 --- a/indra/newview/skins/default/xui/it/panel_edit_shape.xml +++ b/indra/newview/skins/default/xui/it/panel_edit_shape.xml @@ -1,14 +1,8 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="edit_shape_panel"> -	<panel name="avatar_sex_panel"> -		<text name="gender_text"> -			Sesso: -		</text> -		<radio_group name="sex_radio"> -			<radio_item label="Femmina" name="radio"/> -			<radio_item label="Maschio" name="radio2"/> -		</radio_group> -	</panel> +	<text name="avatar_height"> +		Statura: [HEIGHT] metri +	</text>  	<panel label="Camicia" name="accordion_panel">  		<accordion name="wearable_accordion">  			<accordion_tab name="shape_body_tab" title="Corpo"/> diff --git a/indra/newview/skins/default/xui/it/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/it/panel_edit_tattoo.xml index d8cfa15b25..d76fb62c53 100644 --- a/indra/newview/skins/default/xui/it/panel_edit_tattoo.xml +++ b/indra/newview/skins/default/xui/it/panel_edit_tattoo.xml @@ -4,5 +4,6 @@  		<texture_picker label="Tatuaggio della testa" name="Head Tattoo" tool_tip="Clicca per scegliere una fotografia"/>  		<texture_picker label="Tatuaggio superiore" name="Upper Tattoo" tool_tip="Clicca per scegliere una fotografia"/>  		<texture_picker label="Tattuaggio inferiore" name="Lower Tattoo" tool_tip="Clicca per scegliere una fotografia"/> +		<color_swatch label="Colore/Tinta" name="Color/Tint" tool_tip="Clicca per aprire il selettore dei colori"/>  	</panel>  </panel> diff --git a/indra/newview/skins/default/xui/it/panel_edit_wearable.xml b/indra/newview/skins/default/xui/it/panel_edit_wearable.xml index 1135a582f5..3d8aa858db 100644 --- a/indra/newview/skins/default/xui/it/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/it/panel_edit_wearable.xml @@ -93,6 +93,12 @@  	<text name="edit_wearable_title" value="Modifica della figura corporea"/>  	<panel label="Camicia" name="wearable_type_panel">  		<text name="description_text" value="Figura corporea:"/> +		<radio_group name="sex_radio"> +			<radio_item label="" name="sex_male" tool_tip="Maschio" value="1"/> +			<radio_item label="" name="sex_female" tool_tip="Femmina" value="0"/> +		</radio_group> +		<icon name="male_icon" tool_tip="Maschio"/> +		<icon name="female_icon" tool_tip="Femmina"/>  	</panel>  	<panel label="gear_buttom_panel" name="gear_buttom_panel">  		<button name="friends_viewsort_btn" tool_tip="Opzioni"/> diff --git a/indra/newview/skins/default/xui/it/panel_group_land_money.xml b/indra/newview/skins/default/xui/it/panel_group_land_money.xml index 1e3ef5e657..16cc91cd9d 100644 --- a/indra/newview/skins/default/xui/it/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/it/panel_group_land_money.xml @@ -6,6 +6,9 @@  	<panel.string name="cant_view_group_land_text">  		Non sei autorizzato a vedere quali terreni appartengono al gruppo.  	</panel.string> +	<panel.string name="epmty_view_group_land_text"> +		Nessuna voce +	</panel.string>  	<panel.string name="cant_view_group_accounting_text">  		Non sei autorizzato a visionare le informazioni finanziarie del gruppo.  	</panel.string> diff --git a/indra/newview/skins/default/xui/it/panel_group_notices.xml b/indra/newview/skins/default/xui/it/panel_group_notices.xml index 9dac282de9..8dd945830e 100644 --- a/indra/newview/skins/default/xui/it/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/it/panel_group_notices.xml @@ -40,6 +40,7 @@ Massimo 200 per gruppo al giorno  		<text name="string">  			Trascina e rilascia qui l'oggetto da allegare:  		</text> +		<button label="Inventario" name="open_inventory" tool_tip="Apri l'inventario"/>  		<button label="Rimuovi" label_selected="Rimuovi allegato" name="remove_attachment" tool_tip="Rimuovi allegato dal tuo avviso"/>  		<button label="Invia" label_selected="Invia" name="send_notice"/>  		<group_drop_target name="drop_target" tool_tip="Trascina un oggetto dall'inventario ín questa casella per spedirlo con questo avviso. Devi avere i diritti per la copia e il trasferimento per poter allegare l'oggetto."/> diff --git a/indra/newview/skins/default/xui/it/panel_login.xml b/indra/newview/skins/default/xui/it/panel_login.xml index 287e938d57..473bcfa88d 100644 --- a/indra/newview/skins/default/xui/it/panel_login.xml +++ b/indra/newview/skins/default/xui/it/panel_login.xml @@ -8,18 +8,15 @@  	</panel.string>  	<layout_stack name="login_widgets">  		<layout_panel name="login"> -			<text name="first_name_text"> -				Nome: +			<text name="username_text"> +				Nome utente:  			</text> -			<line_editor label="Nome" name="first_name_edit" tool_tip="[SECOND_LIFE] First Name"/> -			<text name="last_name_text"> -				Cognome: -			</text> -			<line_editor label="Cognome" name="last_name_edit" tool_tip="[SECOND_LIFE] Last Name"/> +			<line_editor label="Nome utente" name="username_edit" tool_tip="Nome utente [SECOND_LIFE]"/>  			<text name="password_text">  				Password:  			</text>  			<check_box label="Ricorda password" name="remember_check"/> +			<button label="Accedi" name="connect_btn"/>  			<text name="start_location_text">  				Inizia da:  			</text> @@ -28,7 +25,6 @@  				<combo_box.item label="Casa mia" name="MyHome"/>  				<combo_box.item label="<Scrivi nome regione>" name="Typeregionname"/>  			</combo_box> -			<button label="Accedi" name="connect_btn"/>  		</layout_panel>  		<layout_panel name="links">  			<text name="create_new_account_text"> diff --git a/indra/newview/skins/default/xui/it/panel_main_inventory.xml b/indra/newview/skins/default/xui/it/panel_main_inventory.xml index 878daf1e6b..446b51ffa3 100644 --- a/indra/newview/skins/default/xui/it/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/it/panel_main_inventory.xml @@ -9,62 +9,20 @@  	<text name="ItemcountText">  		Oggetti:  	</text> -	<menu_bar name="Inventory Menu"> -		<menu label="File" name="File"> -			<menu_item_call label="Apri" name="Open"/> -			<menu label="Carica nel server" name="upload"> -				<menu_item_call label="Immagine ([COST]L$)..." name="Upload Image"/> -				<menu_item_call label="Suono ([COST]L$)..." name="Upload Sound"/> -				<menu_item_call label="Animazione ([COST]L$)..." name="Upload Animation"/> -				<menu_item_call label="In blocco ([COST]L$ per file)..." name="Bulk Upload"/> -			</menu> -			<menu_item_call label="Nuova finestra" name="New Window"/> -			<menu_item_call label="Mostra filtri" name="Show Filters"/> -			<menu_item_call label="Ripristina filtri" name="Reset Current"/> -			<menu_item_call label="Chiudi tutte le cartelle" name="Close All Folders"/> -			<menu_item_call label="Svuota cestino" name="Empty Trash"/> -			<menu_item_call label="Svuota oggetti smarriti" name="Empty Lost And Found"/> -		</menu> -		<menu label="Crea" name="Create"> -			<menu_item_call label="Nuova cartella" name="New Folder"/> -			<menu_item_call label="Nuovo script" name="New Script"/> -			<menu_item_call label="Nuovo biglietto" name="New Note"/> -			<menu_item_call label="Nuova gesture" name="New Gesture"/> -			<menu label="Maglietta intima" name="New Clothes"> -				<menu_item_call label="Nuova camicia" name="New Shirt"/> -				<menu_item_call label="Nuovi pantaloni" name="New Pants"/> -				<menu_item_call label="Nuove scarpe" name="New Shoes"/> -				<menu_item_call label="Nuove calze" name="New Socks"/> -				<menu_item_call label="Nuova giacca" name="New Jacket"/> -				<menu_item_call label="Nuova gonna" name="New Skirt"/> -				<menu_item_call label="Nuovi guanti" name="New Gloves"/> -				<menu_item_call label="Nuova maglietta intima" name="New Undershirt"/> -				<menu_item_call label="Nuovi slip" name="New Underpants"/> -				<menu_item_call label="Nuovo Alfa (trasparenza)" name="New Alpha"/> -				<menu_item_call label="Nuovo tatuaggio" name="New Tattoo"/> -			</menu> -			<menu label="Nuove parti del corpo" name="New Body Parts"> -				<menu_item_call label="Nuova figura corporea" name="New Shape"/> -				<menu_item_call label="Nuova pelle" name="New Skin"/> -				<menu_item_call label="Nuovi capelli" name="New Hair"/> -				<menu_item_call label="Nuovi occhi" name="New Eyes"/> -			</menu> -		</menu> -		<menu label="Ordina" name="Sort"> -			<menu_item_check label="In base al nome" name="By Name"/> -			<menu_item_check label="In base alla data" name="By Date"/> -			<menu_item_check label="Cartelle sempre in base al nome" name="Folders Always By Name"/> -			<menu_item_check label="Cartelle di sistema all'inizio" name="System Folders To Top"/> -		</menu> -	</menu_bar>  	<filter_editor label="Filtro" name="inventory search editor"/>  	<tab_container name="inventory filter tabs">  		<inventory_panel label="Tutti gli elementi" name="All Items"/> -		<inventory_panel label="Elementi recenti" name="Recent Items"/> +		<recent_inventory_panel label="Elementi recenti" name="Recent Items"/>  	</tab_container> -	<panel name="bottom_panel"> -		<button name="options_gear_btn" tool_tip="Mostra opzioni addizionali"/> -		<button name="add_btn" tool_tip="Aggiungi nuovo elemento"/> -		<dnd_button name="trash_btn" tool_tip="Rimuovi l'articolo selezionato"/> -	</panel> +	<layout_stack name="bottom_panel"> +		<layout_panel name="options_gear_btn_panel"> +			<button name="options_gear_btn" tool_tip="Mostra opzioni addizionali"/> +		</layout_panel> +		<layout_panel name="add_btn_panel"> +			<button name="add_btn" tool_tip="Aggiungi nuovo elemento"/> +		</layout_panel> +		<layout_panel name="trash_btn_panel"> +			<dnd_button name="trash_btn" tool_tip="Rimuovi l'articolo selezionato"/> +		</layout_panel> +	</layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/it/panel_outfit_edit.xml b/indra/newview/skins/default/xui/it/panel_outfit_edit.xml index 516181e0e9..bd2202b60e 100644 --- a/indra/newview/skins/default/xui/it/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/it/panel_outfit_edit.xml @@ -2,6 +2,8 @@  <!-- Side tray Outfit Edit panel -->  <panel label="Modifica del vestiario" name="outfit_edit">  	<string name="No Outfit" value="Nessun vestiario"/> +	<string name="unsaved_changes" value="Modifiche non salvate"/> +	<string name="now_editing" value="Modifica di"/>  	<panel.string name="not_available">  		(non pert.)  	</panel.string> @@ -15,24 +17,19 @@  	<text name="title" value="Modifica vestiario"/>  	<panel label="bottom_panel" name="header_panel">  		<panel label="bottom_panel" name="outfit_name_and_status"> -			<text name="status" value="Modifica..."/> +			<text name="status" value="Modifica di..."/>  			<text name="curr_outfit_name" value="[Current Outfit]"/>  		</panel>  	</panel>  	<layout_stack name="im_panels">  		<layout_panel label="Pannello di controllo IM" name="outfit_wearables_panel"> -			<scroll_list name="look_items_list"> -				<scroll_list.columns label="Articolo look" name="look_item"/> -				<scroll_list.columns label="Ordina in base agli articoli del vestiario" name="look_item_sort"/> -			</scroll_list>  			<panel label="bottom_panel" name="edit_panel"/>  		</layout_panel>  		<layout_panel name="add_wearables_panel"> -			<filter_editor label="Filtro" name="look_item_filter"/> +			<text name="add_to_outfit_label" value="Aggiungi al vestiario:"/>  			<layout_stack name="filter_panels"> -				<layout_panel label="Pannello di controllo IM" name="filter_button_panel"> -					<text name="add_to_outfit_label" value="Aggiungi al vestiario:"/> -					<button label="V" name="filter_button"/> +				<layout_panel label="Pannello di controllo IM" name="filter_panel"> +					<filter_editor label="Filtro" name="look_item_filter"/>  				</layout_panel>  			</layout_stack>  			<panel label="add_wearables_button_bar" name="add_wearables_button_bar"> diff --git a/indra/newview/skins/default/xui/it/panel_people.xml b/indra/newview/skins/default/xui/it/panel_people.xml index c469da014a..056e424436 100644 --- a/indra/newview/skins/default/xui/it/panel_people.xml +++ b/indra/newview/skins/default/xui/it/panel_people.xml @@ -2,9 +2,9 @@  <!-- Side tray panel -->  <panel label="Persone" name="people_panel">  	<string name="no_recent_people" value="Nessuna persona recente. Stai cercando persone da frequentare? Prova la [secondlife:///app/search/people Ricerca] o la [secondlife:///app/worldmap Mappa del mondo]."/> -	<string name="no_filtered_recent_people" value="Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/people Cerca]."/> +	<string name="no_filtered_recent_people" value="Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/people/[SEARCH_TERM] Cerca]."/>  	<string name="no_one_near" value="Nessuno vicino. Stai cercando persone da frequentare? Try la [secondlife:///app/search/people Ricerca] o la [secondlife:///app/worldmap Mappa del mondo]."/> -	<string name="no_one_filtered_near" value="Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/people Cerca]."/> +	<string name="no_one_filtered_near" value="Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/people/[SEARCH_TERM] Cerca]."/>  	<string name="no_friends_online" value="Nessun amico online"/>  	<string name="no_friends" value="Nessun amico"/>  	<string name="no_friends_msg"> @@ -12,11 +12,11 @@  Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa del mondo].  	</string>  	<string name="no_filtered_friends_msg"> -		Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/people Cerca]. +		Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/people/[SEARCH_TERM] Cerca].  	</string>  	<string name="people_filter_label" value="Filtro persone"/>  	<string name="groups_filter_label" value="Filtro gruppi"/> -	<string name="no_filtered_groups_msg" value="Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/groups Cerca]."/> +	<string name="no_filtered_groups_msg" value="Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/groups/[SEARCH_TERM] Cerca]."/>  	<string name="no_groups_msg" value="Stai cercando gruppi di cui far parte? Prova [secondlife:///app/search/groups Cerca]."/>  	<filter_editor label="Filtro" name="filter_input"/>  	<tab_container name="tabs"> @@ -55,7 +55,7 @@ Stai cercando persone da frequentare? Prova la [secondlife:///app/worldmap Mappa  		<button label="Profilo" name="view_profile_btn" tool_tip="Mostra immagine, gruppi e altre informazioni del residente"/>  		<button label="IM" name="im_btn" tool_tip="Apri una sessione messaggio istantaneo"/>  		<button label="Chiama" name="call_btn" tool_tip="Chiama questo residente"/> -		<button label="Condividi" name="share_btn"/> +		<button label="Condividi" name="share_btn" tool_tip="Condividi un oggetto dell'inventario"/>  		<button label="Teleport" name="teleport_btn" tool_tip="Offri teleport"/>  		<button label="Profilo del gruppo" name="group_info_btn" tool_tip="Mostra informazioni gruppo"/>  		<button label="Chat di gruppo" name="chat_btn" tool_tip="Apri sessione chat"/> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml index 09e19f4bc0..7c3f32ad7b 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_advanced.xml @@ -13,6 +13,7 @@  	</text>  	<check_box label="Costruire/Modificare" name="edit_camera_movement" tool_tip="Utilizza il posizionamento automatico della fotocamera entrando o uscendo dalla modalità modifica"/>  	<check_box label="Aspetto fisico" name="appearance_camera_movement" tool_tip="Utilizza il posizionamento automatico della camera in modalità modifica"/> +	<check_box initial_value="1" label="Barra laterale" name="appearance_sidebar_positioning" tool_tip="Utilizza il posizionamento automatico della fotocamera per la barra laterale"/>  	<check_box label="Visualizzami in modalità soggettiva" name="first_person_avatar_visible"/>  	<check_box label="Le frecce di direzione mi fanno sempre spostare" name="arrow_keys_move_avatar_check"/>  	<check_box label="Doppio click e tieni premuto per correre" name="tap_tap_hold_to_run"/> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml index 28df9d2e43..fb8ddf607d 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_chat.xml @@ -45,6 +45,7 @@  	</text>  	<check_box initial_value="true" label="Simula la battitura tasti quando scrivi" name="play_typing_animation"/>  	<check_box label="Quando sono OFF-LINE, spediscimi gli IM in una e-mail" name="send_im_to_email"/> +	<check_box label="Attiva IM in testo semplice e cronologia chat" name="plain_text_chat_history"/>  	<text name="show_ims_in_label">  		Mostra gli IM in:  	</text> diff --git a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml index 5bd0cfb106..37857473aa 100644 --- a/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/it/panel_preferences_graphics1.xml @@ -1,8 +1,5 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel label="Grafica" name="Display panel"> -	<text name="UI Size:"> -		Dimensioni UI: -	</text>  	<text name="QualitySpeed">  		Qualità e velocità:  	</text> @@ -52,6 +49,10 @@  			m  		</text>  		<slider label="Conteggio massimo particelle:" name="MaxParticleCount"/> +		<slider label="Distanza visual. max avatar:" name="MaxAvatarDrawDistance"/> +		<text name="DrawDistanceMeterText3"> +			m +		</text>  		<slider label="Qualità in post-produzione:" name="RenderPostProcess"/>  		<text name="MeshDetailText">  			Dettagli reticolo: diff --git a/indra/newview/skins/default/xui/it/sidepanel_appearance.xml b/indra/newview/skins/default/xui/it/sidepanel_appearance.xml index c2e99b5573..df25772ffb 100644 --- a/indra/newview/skins/default/xui/it/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/it/sidepanel_appearance.xml @@ -1,9 +1,13 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel label="Vestiario" name="appearance panel">  	<string name="No Outfit" value="Nessun vestiario"/> +	<string name="Unsaved Changes" value="Modifiche non salvate"/> +	<string name="Now Wearing" value="Abbigliamento attuale..."/>  	<panel name="panel_currentlook"> -		<text name="currentlook_title"> -			(non salvato) +		<button label="M" name="editappearance_btn"/> +		<button label="A" name="openoutfit_btn"/> +		<text name="currentlook_status"> +			(Stato)  		</text>  	</panel>  	<filter_editor label="Filtri per il vestiario" name="Filter"/> diff --git a/indra/newview/skins/default/xui/it/sidepanel_inventory.xml b/indra/newview/skins/default/xui/it/sidepanel_inventory.xml index 8a391c882c..0d862a0ff7 100644 --- a/indra/newview/skins/default/xui/it/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/it/sidepanel_inventory.xml @@ -4,6 +4,7 @@  		<panel name="button_panel">  			<button label="Profilo" name="info_btn"/>  			<button label="Condividi" name="share_btn"/> +			<button label="Acquisti" name="shop_btn"/>  			<button label="Indossa" name="wear_btn"/>  			<button label="Riproduci" name="play_btn"/>  			<button label="Teleport" name="teleport_btn"/> diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml index 9a6c648c8e..67cd4c35b2 100644 --- a/indra/newview/skins/default/xui/it/strings.xml +++ b/indra/newview/skins/default/xui/it/strings.xml @@ -94,6 +94,24 @@  	<string name="LoginDownloadingClothing">  		Sto caricando i vestiti...  	</string> +	<string name="InvalidCertificate"> +		Il server ha inviato un certificato non valido o errato. Rivolgiti all'amministratore della griglia. +	</string> +	<string name="CertInvalidHostname"> +		Per accedere al server è stato utilizzato un nome host non valido; controlla lo SLURL o il nome host della griglia. +	</string> +	<string name="CertExpired"> +		Il certificato inviato dalla griglia sembra essere scaduto.  Controlla l'orologio del sistema o rivolgiti all'amministratore della griglia. +	</string> +	<string name="CertKeyUsage"> +		Impossibile utilizzare per SSl il certificato inviato dal server.  Rivolgiti all'amministratore della griglia. +	</string> +	<string name="CertBasicConstraints"> +		Nella catena dei certificati del server erano presenti troppi certificati.  Rivolgiti all'amministratore della griglia. +	</string> +	<string name="CertInvalidSignature"> +		Impossibile verificare la firma del certificato inviato dal server della griglia.  Rivolgiti all'amministratore della griglia. +	</string>  	<string name="LoginFailedNoNetwork">  		Errore di rete: Non è stato possibile stabilire un collegamento, controlla la tua connessione.  	</string> @@ -825,6 +843,42 @@  	<string name="invalid">  		non valido  	</string> +	<string name="shirt_not_worn"> +		Camicia non indossata +	</string> +	<string name="pants_not_worn"> +		Pantaloni non indossati +	</string> +	<string name="shoes_not_worn"> +		Scarpe non indossate +	</string> +	<string name="socks_not_worn"> +		Calzini non indossati +	</string> +	<string name="jacket_not_worn"> +		Giacca non indossata +	</string> +	<string name="gloves_not_worn"> +		Guanti non indossati +	</string> +	<string name="undershirt_not_worn"> +		Maglietta intima non indossata +	</string> +	<string name="underpants_not_worn"> +		Slip non indossati +	</string> +	<string name="skirt_not_worn"> +		Gonna non indossata +	</string> +	<string name="alpha_not_worn"> +		Alpha non portato +	</string> +	<string name="tattoo_not_worn"> +		Tatuaggio non portato +	</string> +	<string name="invalid_not_worn"> +		non valido +	</string>  	<string name="NewWearable">  		Nuovo [WEARABLE_ITEM]  	</string> @@ -895,7 +949,10 @@  		Premi ESC per tornare in visualizzazione normale  	</string>  	<string name="InventoryNoMatchingItems"> -		Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/all Cerca]. +		Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/all/[SEARCH_TERM] Cerca]. +	</string> +	<string name="PlacesNoMatchingItems"> +		Non riesci a trovare quello che cerchi? Prova [secondlife:///app/search/places/[SEARCH_TERM] Cerca].  	</string>  	<string name="FavoritesNoMatchingItems">  		Trascina qui un punto di riferimento per aggiungerlo ai Preferiti. @@ -925,6 +982,7 @@  	<string name="Wave" value="Saluta con la mano"/>  	<string name="HelloAvatar" value="Ciao, avatar!"/>  	<string name="ViewAllGestures" value="Visualizza tutto >>"/> +	<string name="GetMoreGestures" value="Altre >>"/>  	<string name="Animations" value="Animazioni,"/>  	<string name="Calling Cards" value="Biglietti da visita,"/>  	<string name="Clothing" value="Vestiti,"/> @@ -1537,16 +1595,19 @@  		Il residente al quale hai inviato un messaggio è in modalità 'occupato', ovvero ha chiesto di non essere disturbato.  Il tuo messaggio comparirà nel suo pannello IM, dove potrà essere letto in un secondo momento.  	</string>  	<string name="MuteByName"> -		(in base al nome) +		(In base al nome)  	</string>  	<string name="MuteAgent">  		(Residente)  	</string>  	<string name="MuteObject"> -		(oggetto) +		(Oggetto)  	</string>  	<string name="MuteGroup"> -		(gruppo) +		(Gruppo) +	</string> +	<string name="MuteExternal"> +		(esterno)  	</string>  	<string name="RegionNoCovenant">  		Non esiste alcun regolamento per questa proprietà. @@ -3306,11 +3367,14 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].  	<string name="answered_call">  		Risposto alla chiamata  	</string> -	<string name="started_call"> -		Chiamata vocale iniziata +	<string name="you_started_call"> +		Hai iniziato una chiamata vocale +	</string> +	<string name="you_joined_call"> +		Ti sei collegato alla chiamata in voce  	</string> -	<string name="joined_call"> -		Si è collegato alla chiamata in voce +	<string name="name_started_call"> +		[NAME] ha iniziato una chiamata vocale  	</string>  	<string name="ringing-im">  		Collegamento alla chiamata vocale... @@ -3509,6 +3573,90 @@ Segnala abuso  	<string name="Contents">  		Contenuto  	</string> +	<string name="Gesture"> +		Gesture +	</string> +	<string name="Male Gestures"> +		Gesture maschili +	</string> +	<string name="Female Gestures"> +		Gesture femminili +	</string> +	<string name="Other Gestures"> +		Altre gesture +	</string> +	<string name="Speech Gestures"> +		Gesture del parlato +	</string> +	<string name="Common Gestures"> +		Gesture comuni +	</string> +	<string name="Male - Excuse me"> +		Maschio - Chiedere scusa +	</string> +	<string name="Male - Get lost"> +		Maschio - Levati dai piedi! +	</string> +	<string name="Male - Blow kiss"> +		Maschio - Butta un bacio +	</string> +	<string name="Male - Boo"> +		Maschio - Bu +	</string> +	<string name="Male - Bored"> +		Maschio - Annoiato +	</string> +	<string name="Male - Hey"> +		Maschio - Ehi +	</string> +	<string name="Male - Laugh"> +		Maschio - Ridere +	</string> +	<string name="Male - Repulsed"> +		Maschio - Disgustato +	</string> +	<string name="Male - Shrug"> +		Maschio - Spallucce +	</string> +	<string name="Male - Stick tougue out"> +		Maschio - Tira fuori la lingua +	</string> +	<string name="Male - Wow"> +		Maschio - Accipicchia +	</string> +	<string name="FeMale - Excuse me"> +		Femmina - Chiedere scusa +	</string> +	<string name="FeMale - Get lost"> +		Femmina - Levati dai piedi! +	</string> +	<string name="FeMale - Blow kiss"> +		Femmina - Butta un bacio +	</string> +	<string name="FeMale - Boo"> +		Femmina - Bu +	</string> +	<string name="Female - Bored"> +		Femmina - Annoiata +	</string> +	<string name="Female - Hey"> +		Femmina - Ehi +	</string> +	<string name="Female - Laugh"> +		Femmina - Ridere +	</string> +	<string name="Female - Repulsed"> +		Femmina - Disgustata +	</string> +	<string name="Female - Shrug"> +		Femmina - Spallucce +	</string> +	<string name="Female - Stick tougue out"> +		Femmina - Tira fuori la lingua +	</string> +	<string name="Female - Wow"> +		Femmina - Accipicchia +	</string>  	<string name="AvatarBirthDateFormat">  		[day,datetime,slt]/[mthnum,datetime,slt]/[year,datetime,slt]  	</string> diff --git a/indra/newview/skins/default/xui/ja/menu_bottomtray.xml b/indra/newview/skins/default/xui/ja/menu_bottomtray.xml index 0e69671f06..e5703c559b 100644 --- a/indra/newview/skins/default/xui/ja/menu_bottomtray.xml +++ b/indra/newview/skins/default/xui/ja/menu_bottomtray.xml @@ -4,11 +4,11 @@  	<menu_item_check label="移動ボタン" name="ShowMoveButton"/>  	<menu_item_check label="視界ボタン" name="ShowCameraButton"/>  	<menu_item_check label="スナップショットボタン" name="ShowSnapshotButton"/> -	<menu_item_check label="サイドバーのボタン" name="ShowSidebarButton"/> -	<menu_item_check label="制作のボタン" name="ShowBuildButton"/> -	<menu_item_check label="検索のボタン" name="ShowSearchButton"/> -	<menu_item_check label="地図のボタン" name="ShowWorldMapButton"/> -	<menu_item_check label="ミニマップのボタン" name="ShowMiniMapButton"/> +	<menu_item_check label="サイドバーボタン" name="ShowSidebarButton"/> +	<menu_item_check label="制作ボタン" name="ShowBuildButton"/> +	<menu_item_check label="検索ボタン" name="ShowSearchButton"/> +	<menu_item_check label="地図ボタン" name="ShowWorldMapButton"/> +	<menu_item_check label="ミニマップボタン" name="ShowMiniMapButton"/>  	<menu_item_call label="切り取り" name="NearbyChatBar_Cut"/>  	<menu_item_call label="コピー" name="NearbyChatBar_Copy"/>  	<menu_item_call label="貼り付け" name="NearbyChatBar_Paste"/> diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml index 1ac7677b07..c82f1198a4 100644 --- a/indra/newview/skins/default/xui/ja/notifications.xml +++ b/indra/newview/skins/default/xui/ja/notifications.xml @@ -349,7 +349,7 @@ L$ が不足しているのでこのグループに参加することができ  		<usetemplate name="okcancelbuttons" notext="もう一度試す" yestext="新しいアカウントを作成"/>  	</notification>  	<notification name="InvalidCredentialFormat"> -		「ユーザー名」欄にアバターのファーストネームとラストネーム両方を入力してからログインしてください。 +		「ユーザーネーム」欄にアバターのファーストネームとラストネーム両方を入力してからログインしてください。  	</notification>  	<notification name="AddClassified">  		クラシファイド広告は、検索ディレクトリと [http://secondlife.com/community/classifieds secondlife.com] の「クラシファイド広告」セクションに一週間掲載されます。 diff --git a/indra/newview/skins/default/xui/ja/panel_login.xml b/indra/newview/skins/default/xui/ja/panel_login.xml index f0ebc67ef5..47d7a88b4c 100644 --- a/indra/newview/skins/default/xui/ja/panel_login.xml +++ b/indra/newview/skins/default/xui/ja/panel_login.xml @@ -9,9 +9,9 @@  	<layout_stack name="login_widgets">  		<layout_panel name="login">  			<text name="username_text"> -				ユーザー名: +				ユーザーネーム:  			</text> -			<line_editor label="ユーザー名" name="username_edit" tool_tip="[SECOND_LIFE] ユーザー名"/> +			<line_editor label="ユーザーネーム" name="username_edit" tool_tip="[SECOND_LIFE] ユーザーネーム"/>  			<text name="password_text">  				パスワード:  			</text> diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml index 7671f58691..4044110b47 100644 --- a/indra/newview/skins/default/xui/pt/floater_about.xml +++ b/indra/newview/skins/default/xui/pt/floater_about.xml @@ -26,9 +26,9 @@ Placa gráfica: [GRAPHICS_CARD]  Versão libcurl: [LIBCURL_VERSION]  Versão J2C Decoder: [J2C_VERSION] -Versão do driver de áudio: [AUDIO_DRIVER_VERSION]  +Versão do driver de áudio: [AUDIO_DRIVER_VERSION]  Versão Qt Webkit: [QT_WEBKIT_VERSION] -Versão Vivox: [VIVOX_VERSION] +Versão do servidor de voz: [VOICE_VERSION]  	</floater.string>  	<floater.string name="none">  		(nenhum) diff --git a/indra/newview/skins/default/xui/pt/floater_about_land.xml b/indra/newview/skins/default/xui/pt/floater_about_land.xml index 787836a8bd..56ffcbdece 100644 --- a/indra/newview/skins/default/xui/pt/floater_about_land.xml +++ b/indra/newview/skins/default/xui/pt/floater_about_land.xml @@ -63,6 +63,9 @@  				Nenhum lote selecionado.  Vá para o menu Mundo > Sobre o terreno ou selecione outro lote para mostrar os detalhes.  			</panel.string> +			<panel.string name="time_stamp_template"> +				[wkday,datetime,local] [mth,datetime,local] [day,datetime,local] [hour,datetime,local]:[min,datetime,local]:[second,datetime,local] [year,datetime,local] +			</panel.string>  			<text name="Name:">  				Nome:  			</text> diff --git a/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml b/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml index 5fb64f64b3..9473ee7ce9 100644 --- a/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml +++ b/indra/newview/skins/default/xui/pt/floater_avatar_textures.xml @@ -3,41 +3,48 @@  	<floater.string name="InvalidAvatar">  		AVATAR INVÁLIDO  	</floater.string> -	<text name="composite_label"> -		Texturas compostas -	</text> -	<button label="Tombar" label_selected="Tombar" name="Dump"/>  	<scroll_container name="profile_scroll">  		<panel name="scroll_content_panel"> -			<texture_picker label="Cabelo" name="hair-baked"/> -			<texture_picker label="Cabelo" name="hair_grain"/> -			<texture_picker label="Cabelo alpha" name="hair_alpha"/> -			<texture_picker label="Cabeça" name="head-baked"/> -			<texture_picker label="Maquilagem" name="head_bodypaint"/> -			<texture_picker label="Cabeça Alpha" name="head_alpha"/> -			<texture_picker label="Tatuagem na cabeça" name="head_tattoo"/> -			<texture_picker label="Olhos" name="eyes-baked"/> -			<texture_picker label="Olho" name="eyes_iris"/> -			<texture_picker label="Olhos Alpha" name="eyes_alpha"/> -			<texture_picker label="Cintura acima" name="upper-baked"/> -			<texture_picker label="Pintura corporal, cintura para cima" name="upper_bodypaint"/> -			<texture_picker label="Camiseta" name="upper_undershirt"/> -			<texture_picker label="Luvas" name="upper_gloves"/> -			<texture_picker label="Camisa" name="upper_shirt"/> -			<texture_picker label="Jaqueta (cima)" name="upper_jacket"/> -			<texture_picker label="Alpha de cima" name="upper_alpha"/> -			<texture_picker label="Tatuagem parte de cima" name="upper_tattoo"/> -			<texture_picker label="Cintura para baixo" name="lower-baked"/> -			<texture_picker label="Pintura corporal, cintura para baixo" name="lower_bodypaint"/> -			<texture_picker label="Roupa de baixo" name="lower_underpants"/> -			<texture_picker label="Meias" name="lower_socks"/> -			<texture_picker label="Sapatos" name="lower_shoes"/> -			<texture_picker label="Calças" name="lower_pants"/> -			<texture_picker label="Jaqueta" name="lower_jacket"/> -			<texture_picker label="Alpha inferior" name="lower_alpha"/> -			<texture_picker label="Tatuagem de baixo" name="lower_tattoo"/> -			<texture_picker label="Saia" name="skirt-baked"/> -			<texture_picker label="Saia" name="skirt"/> +			<text name="label"> +				Pronto +Texturas +			</text> +			<text name="composite_label"> +				Compósito: +Texturas +			</text> +			<button label="Enviar IDs para painel" label_selected="Dump" name="Dump"/> +			<panel name="scroll_content_panel"> +				<texture_picker label="Cabelo" name="hair-baked"/> +				<texture_picker label="Cabelo" name="hair_grain"/> +				<texture_picker label="Cabelo alpha" name="hair_alpha"/> +				<texture_picker label="Cabeça" name="head-baked"/> +				<texture_picker label="Maquilagem" name="head_bodypaint"/> +				<texture_picker label="Cabeça Alpha" name="head_alpha"/> +				<texture_picker label="Tatuagem na cabeça" name="head_tattoo"/> +				<texture_picker label="Olhos" name="eyes-baked"/> +				<texture_picker label="Olho" name="eyes_iris"/> +				<texture_picker label="Olhos Alpha" name="eyes_alpha"/> +				<texture_picker label="Cintura acima" name="upper-baked"/> +				<texture_picker label="Pintura corporal, cintura para cima" name="upper_bodypaint"/> +				<texture_picker label="Camiseta" name="upper_undershirt"/> +				<texture_picker label="Luvas" name="upper_gloves"/> +				<texture_picker label="Camisa" name="upper_shirt"/> +				<texture_picker label="Jaqueta (cima)" name="upper_jacket"/> +				<texture_picker label="Alpha de cima" name="upper_alpha"/> +				<texture_picker label="Tatuagem parte de cima" name="upper_tattoo"/> +				<texture_picker label="Cintura para baixo" name="lower-baked"/> +				<texture_picker label="Cintura para baixo" name="lower_bodypaint"/> +				<texture_picker label="Roupa de baixo" name="lower_underpants"/> +				<texture_picker label="Meias" name="lower_socks"/> +				<texture_picker label="Sapatos" name="lower_shoes"/> +				<texture_picker label="Calças" name="lower_pants"/> +				<texture_picker label="Jaqueta" name="lower_jacket"/> +				<texture_picker label="Alpha inferior" name="lower_alpha"/> +				<texture_picker label="Tatuagem de baixo" name="lower_tattoo"/> +				<texture_picker label="Saia" name="skirt-baked"/> +				<texture_picker label="Saia" name="skirt"/> +			</panel>  		</panel>  	</scroll_container>  </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_buy_currency_html.xml b/indra/newview/skins/default/xui/pt/floater_buy_currency_html.xml new file mode 100644 index 0000000000..24e41ac8c8 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/floater_buy_currency_html.xml @@ -0,0 +1,2 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<floater name="floater_buy_currency_html" title="COMPRAR MOEDA"/> diff --git a/indra/newview/skins/default/xui/pt/floater_map.xml b/indra/newview/skins/default/xui/pt/floater_map.xml index 3a04528228..f8e4e76752 100644 --- a/indra/newview/skins/default/xui/pt/floater_map.xml +++ b/indra/newview/skins/default/xui/pt/floater_map.xml @@ -1,5 +1,5 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?> -<floater name="Map" title="Mini Mapa"> +<floater name="Map" title="">  	<floater.string name="mini_map_north">  		N  	</floater.string> diff --git a/indra/newview/skins/default/xui/pt/floater_moveview.xml b/indra/newview/skins/default/xui/pt/floater_moveview.xml index 9c02570076..b1dc65e3af 100644 --- a/indra/newview/skins/default/xui/pt/floater_moveview.xml +++ b/indra/newview/skins/default/xui/pt/floater_moveview.xml @@ -6,18 +6,48 @@  	<string name="walk_back_tooltip">  		Andar para trás (flecha para baixo ou S)  	</string> +	<string name="walk_left_tooltip"> +		Andar para a esquerda (Shift + Seta esquerda ou A) +	</string> +	<string name="walk_right_tooltip"> +		Andar para a direita (Shift + Seta direita ou D) +	</string>  	<string name="run_forward_tooltip">  		Correr para frente (flecha para cima ou W)  	</string>  	<string name="run_back_tooltip">  		Correr para trás (flecha para baixo ou S)  	</string> +	<string name="run_left_tooltip"> +		Correr para a esquerda (Shift + Seta esquerda ou A) +	</string> +	<string name="run_right_tooltip"> +		Correr para a direita (Shift + Seta direita ou D) +	</string>  	<string name="fly_forward_tooltip">  		Voar para frente (flecha para cima ou W)  	</string>  	<string name="fly_back_tooltip">  		Voar para trás (flecha para baixo ou S)  	</string> +	<string name="fly_left_tooltip"> +		Voar para a esquerda (Shift + Seta esquerda ou A) +	</string> +	<string name="fly_right_tooltip"> +		Voar para a direita (Shift + Seta direita ou D) +	</string> +	<string name="fly_up_tooltip"> +		Voar para cima (tecla E) +	</string> +	<string name="fly_down_tooltip"> +		Voar para baixo (tecla C) +	</string> +	<string name="jump_tooltip"> +		Pular (tecla E) +	</string> +	<string name="crouch_tooltip"> +		Agachar (tecla C) +	</string>  	<string name="walk_title">  		Andar  	</string> @@ -28,10 +58,12 @@  		Voar  	</string>  	<panel name="panel_actions"> -		<button label="" label_selected="" name="turn left btn" tool_tip="Virar à esquerda (flecha ESQ ou A)"/> -		<button label="" label_selected="" name="turn right btn" tool_tip="Virar à direita (flecha DIR ou D)"/>  		<button label="" label_selected="" name="move up btn" tool_tip="Voar para cima (tecla E)"/> +		<button label="" label_selected="" name="turn left btn" tool_tip="Virar à esquerda (flecha ESQ ou A)"/> +		<joystick_slide name="move left btn" tool_tip="Andar para a esquerda (Shift + Seta esquerda ou A)"/>  		<button label="" label_selected="" name="move down btn" tool_tip="Voar para baixo (tecla C)"/> +		<button label="" label_selected="" name="turn right btn" tool_tip="Virar à direita (flecha DIR ou D)"/> +		<joystick_slide name="move right btn" tool_tip="Andar para a direita (Shift + Seta direita ou D)"/>  		<joystick_turn name="forward btn" tool_tip="Andar para frente (flecha para cima ou W)"/>  		<joystick_turn name="backward btn" tool_tip="Andar para trás (flecha para baixo ou S)"/>  	</panel> diff --git a/indra/newview/skins/default/xui/pt/floater_preview_notecard.xml b/indra/newview/skins/default/xui/pt/floater_preview_notecard.xml index e648a7d873..d094c1b63a 100644 --- a/indra/newview/skins/default/xui/pt/floater_preview_notecard.xml +++ b/indra/newview/skins/default/xui/pt/floater_preview_notecard.xml @@ -9,9 +9,6 @@  	<floater.string name="Title">  		Anotação: [NAME]  	</floater.string> -	<floater.string label="Salvar" label_selected="Salvar" name="Save"> -		Salvar -	</floater.string>  	<text name="desc txt">  		Descrição:  	</text> @@ -19,4 +16,5 @@  		Carregando...  	</text_editor>  	<button label="Salvar" label_selected="Salvar" name="Save"/> +	<button label="Excluir" label_selected="Excluir" name="Delete"/>  </floater> diff --git a/indra/newview/skins/default/xui/pt/floater_tools.xml b/indra/newview/skins/default/xui/pt/floater_tools.xml index 74b45f1d1e..dbc8b3ffbe 100644 --- a/indra/newview/skins/default/xui/pt/floater_tools.xml +++ b/indra/newview/skins/default/xui/pt/floater_tools.xml @@ -67,9 +67,9 @@  	<text name="RenderingCost" tool_tip="Mostra o cálculo do custo de renderização do objeto">  		þ: [COUNT]  	</text> -	<check_box name="checkbox uniform"/> -	<text name="checkbox uniform label"> -		Esticar ambos os lados +	<check_box label="" name="checkbox uniform"/> +	<text label="Esticar ambos lados" name="checkbox uniform label"> +		Esticar ambos lados  	</text>  	<check_box initial_value="true" label="Esticar texturas" name="checkbox stretch textures"/>  	<check_box initial_value="true" label="Mostrar na grade" name="checkbox snap to grid"/> diff --git a/indra/newview/skins/default/xui/pt/menu_attachment_self.xml b/indra/newview/skins/default/xui/pt/menu_attachment_self.xml index de3178b946..5cb1b211cf 100644 --- a/indra/newview/skins/default/xui/pt/menu_attachment_self.xml +++ b/indra/newview/skins/default/xui/pt/menu_attachment_self.xml @@ -5,7 +5,7 @@  	<menu_item_call label="Tirar" name="Detach"/>  	<menu_item_call label="Largar" name="Drop"/>  	<menu_item_call label="Ficar de pé" name="Stand Up"/> -	<menu_item_call label="Minha aparência" name="Appearance..."/> +	<menu_item_call label="Trocar de look" name="Change Outfit"/>  	<menu_item_call label="Meus amigos" name="Friends..."/>  	<menu_item_call label="Meus grupos" name="Groups..."/>  	<menu_item_call label="Meu perfil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/pt/menu_avatar_self.xml b/indra/newview/skins/default/xui/pt/menu_avatar_self.xml index ccbb921ebc..62055303b5 100644 --- a/indra/newview/skins/default/xui/pt/menu_avatar_self.xml +++ b/indra/newview/skins/default/xui/pt/menu_avatar_self.xml @@ -20,7 +20,9 @@  		<context_menu label="Tirar  ▶" name="Object Detach"/>  		<menu_item_call label="Tirar tudo" name="Detach All"/>  	</context_menu> -	<menu_item_call label="Minha aparência" name="Appearance..."/> +	<menu_item_call label="Trocar de look" name="Chenge Outfit"/> +	<menu_item_call label="Editar meu look" name="Edit Outfit"/> +	<menu_item_call label="Editar meu corpo" name="Edit My Shape"/>  	<menu_item_call label="Meus amigos" name="Friends..."/>  	<menu_item_call label="Meus grupos" name="Groups..."/>  	<menu_item_call label="Meu perfil" name="Profile..."/> diff --git a/indra/newview/skins/default/xui/pt/menu_bottomtray.xml b/indra/newview/skins/default/xui/pt/menu_bottomtray.xml index 43b446a67e..479d02512f 100644 --- a/indra/newview/skins/default/xui/pt/menu_bottomtray.xml +++ b/indra/newview/skins/default/xui/pt/menu_bottomtray.xml @@ -4,6 +4,11 @@  	<menu_item_check label="Botão de movimento" name="ShowMoveButton"/>  	<menu_item_check label="Botão de ver" name="ShowCameraButton"/>  	<menu_item_check label="Botão de fotos" name="ShowSnapshotButton"/> +	<menu_item_check label="Botão da Barra lateral" name="ShowSidebarButton"/> +	<menu_item_check label="Botão Construir" name="ShowBuildButton"/> +	<menu_item_check label="Botão Buscar" name="ShowSearchButton"/> +	<menu_item_check label="Botão Mapa" name="ShowWorldMapButton"/> +	<menu_item_check label="Botão do Mini Mapa" name="ShowMiniMapButton"/>  	<menu_item_call label="Cortar" name="NearbyChatBar_Cut"/>  	<menu_item_call label="Copiar" name="NearbyChatBar_Copy"/>  	<menu_item_call label="Colar" name="NearbyChatBar_Paste"/> diff --git a/indra/newview/skins/default/xui/pt/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/pt/menu_inspect_self_gear.xml index effc970eb8..c3e0608954 100644 --- a/indra/newview/skins/default/xui/pt/menu_inspect_self_gear.xml +++ b/indra/newview/skins/default/xui/pt/menu_inspect_self_gear.xml @@ -1,7 +1,7 @@  <?xml version="1.0" encoding="utf-8"?>  <menu name="Gear Menu">  	<menu_item_call label="Ficar de pé" name="stand_up"/> -	<menu_item_call label="Minha aparência" name="my_appearance"/> +	<menu_item_call label="Trocar de look" name="change_outfit"/>  	<menu_item_call label="Meu perfil" name="my_profile"/>  	<menu_item_call label="Meus amigos" name="my_friends"/>  	<menu_item_call label="Meus grupos" name="my_groups"/> diff --git a/indra/newview/skins/default/xui/pt/menu_inventory.xml b/indra/newview/skins/default/xui/pt/menu_inventory.xml index 345534261a..1b86b37075 100644 --- a/indra/newview/skins/default/xui/pt/menu_inventory.xml +++ b/indra/newview/skins/default/xui/pt/menu_inventory.xml @@ -54,6 +54,7 @@  	<menu_item_call label="Remover item" name="Purge Item"/>  	<menu_item_call label="Restaurar item" name="Restore Item"/>  	<menu_item_call label="Abrir" name="Open"/> +	<menu_item_call label="Abrir original" name="Open Original"/>  	<menu_item_call label="Propriedades" name="Properties"/>  	<menu_item_call label="Renomear" name="Rename"/>  	<menu_item_call label="Copiar item UUID" name="Copy Asset UUID"/> diff --git a/indra/newview/skins/default/xui/pt/menu_login.xml b/indra/newview/skins/default/xui/pt/menu_login.xml index 8ea87a06d1..a43ac271a9 100644 --- a/indra/newview/skins/default/xui/pt/menu_login.xml +++ b/indra/newview/skins/default/xui/pt/menu_login.xml @@ -2,7 +2,7 @@  <menu_bar name="Login Menu">  	<menu label="Eu" name="File">  		<menu_item_call label="Preferências" name="Preferences..."/> -		<menu_item_call label="Sair" name="Quit"/> +		<menu_item_call label="Sair do [APP_NAME]" name="Quit"/>  	</menu>  	<menu label="Ajuda" name="Help">  		<menu_item_call label="Ajuda do [SECOND_LIFE]" name="Second Life Help"/> diff --git a/indra/newview/skins/default/xui/pt/menu_participant_list.xml b/indra/newview/skins/default/xui/pt/menu_participant_list.xml index c0db7752af..01f1d4ef80 100644 --- a/indra/newview/skins/default/xui/pt/menu_participant_list.xml +++ b/indra/newview/skins/default/xui/pt/menu_participant_list.xml @@ -14,8 +14,8 @@  	<context_menu label="Opções do moderador >" name="Moderator Options">  		<menu_item_check label="Pode bater papo por escrito" name="AllowTextChat"/>  		<menu_item_call label="Silenciar este participante" name="ModerateVoiceMuteSelected"/> -		<menu_item_call label="Silenciar os demais" name="ModerateVoiceMuteOthers"/>  		<menu_item_call label="Desfazer silenciar deste participante" name="ModerateVoiceUnMuteSelected"/> -		<menu_item_call label="Desfazer silenciar dos demais" name="ModerateVoiceUnMuteOthers"/> +		<menu_item_call label="Silenciar todos" name="ModerateVoiceMute"/> +		<menu_item_call label="Desfazer silenciar para todos" name="ModerateVoiceUnmute"/>  	</context_menu>  </context_menu> diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml index 84ad056df6..b091cc2c97 100644 --- a/indra/newview/skins/default/xui/pt/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml @@ -7,7 +7,7 @@  		</menu_item_call>  		<menu_item_call label="Comprar L$" name="Buy and Sell L$"/>  		<menu_item_call label="Meu perfil" name="Profile"/> -		<menu_item_call label="Minha aparência" name="Appearance"/> +		<menu_item_call label="Trocar de look" name="ChangeOutfit"/>  		<menu_item_check label="Meu inventário" name="Inventory"/>  		<menu_item_check label="Meu inventário" name="ShowSidetrayInventory"/>  		<menu_item_check label="Meus gestos" name="Gestures"/> @@ -162,6 +162,7 @@  			<menu_item_check label="Objetos flexíveis" name="Flexible Objects"/>  		</menu>  		<menu_item_check label="Executar diversas instâncias" name="Run Multiple Threads"/> +		<menu_item_check label="Usar plugin de leitura de threads" name="Use Plugin Read Thread"/>  		<menu_item_call label="Limpar cache de grupo" name="ClearGroupCache"/>  		<menu_item_check label="Smoothing de mouse" name="Mouse Smoothing"/>  		<menu label="Atalhos" name="Shortcuts"> @@ -188,7 +189,6 @@  			<menu_item_call label="Mais zoom" name="Zoom In"/>  			<menu_item_call label="Zoom padrão" name="Zoom Default"/>  			<menu_item_call label="Menos zoom" name="Zoom Out"/> -			<menu_item_call label="Alternar tela inteira" name="Toggle Fullscreen"/>  		</menu>  		<menu_item_call label="Mostrar configurações de depuração" name="Debug Settings"/>  		<menu_item_check label="Show Develop Menu" name="Debug Mode"/> diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml index 462dcf2b21..e64940ecb1 100644 --- a/indra/newview/skins/default/xui/pt/notifications.xml +++ b/indra/newview/skins/default/xui/pt/notifications.xml @@ -323,6 +323,9 @@ Você precisa de uma conta para entrar no [SECOND_LIFE]. Você gostaria de abrir  		</url>  		<usetemplate name="okcancelbuttons" notext="Tentar novamente" yestext="Abrir conta"/>  	</notification> +	<notification name="InvalidCredentialFormat"> +		Digite o nome e sobrenome do seu avatar no campo Nome de usuário, depois faça o login novamente. +	</notification>  	<notification name="AddClassified">  		Os anúncios serão publicados na seção 'Classificados' das buscas e em [http://secondlife.com/community/classifieds secondlife.com] durante uma semana.  Escreva seu anúncio e clique em 'Publicar...'  @@ -603,6 +606,11 @@ Esperada [VALIDS]  	<notification name="CannotEncodeFile">  		Impossível codificar o arquivo: [FILE]  	</notification> +	<notification name="CorruptedProtectedDataStore"> +		Não foi possível fazer a leitura dos dados protegidos, redefinindo. +   Isso pode ocorrer após mudanças na configuração da rede. +		<usetemplate name="okbutton" yestext="OK"/> +	</notification>  	<notification name="CorruptResourceFile">  		Fonte do arquivo corrompida: [FILE]  	</notification> @@ -962,6 +970,12 @@ em TODOS OS TERRENOS deste sim?  Por favor, insira um valor maior.  	</notification> +	<notification name="ConfirmItemDeleteHasLinks"> +		Pelo menos um dos itens possui links que levam a ele.  Ao excluir o item, os links não funcionarão mais.   Por isso, recomendamos excluir os links primeiro. + +Tem certeza de que quer excluir estes items? +		<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="OK"/> +	</notification>  	<notification name="ConfirmObjectDeleteLock">  		Pelo menos um dos itens que você selecionou está trancado. @@ -1103,6 +1117,42 @@ Pressione a tecla F1 para ajuda ou aprender mais sobre [SECOND_LIFE].  Por favor, escolha se o seu avatar é feminino ou masculino. Você pode mudar de idéia depois.  		<usetemplate name="okcancelbuttons" notext="Feminino" yestext="Masculino"/>  	</notification> +	<notification name="CantTeleportToGrid"> +		Não foi possível ir para [SLURL], que fica em outro grid ([GRID]) em relação ao grid atual, ([CURRENT_GRID]).  Feche o Visualizador e tente novamente. +		<usetemplate name="okbutton" yestext="OK"/> +	</notification> +	<notification name="GeneralCertificateError"> +		Falha de conexão com o servidor. +[REASON] + +SubjectName: [SUBJECT_NAME_STRING] +IssuerName: [ISSUER_NAME_STRING] +Válido de: [VALID_FROM] +Válido até: [VALID_TO] +MD5 Fingerprint: [SHA1_DIGEST] +Impressão digital SHA1: [MD5_DIGEST] +Uso da chave: [KEYUSAGE] +Uso estendido da chave: [EXTENDEDKEYUSAGE] +Identificador chave de assunto: [SUBJECTKEYIDENTIFIER] +		<usetemplate name="okbutton" yestext="OK"/> +	</notification> +	<notification name="TrustCertificateError"> +		A autoridade de certificação deste servidor é desconhecida. + +Dados do certificado: +SubjectName: [SUBJECT_NAME_STRING] +IssuerName: [ISSUER_NAME_STRING] +Válido de: [VALID_FROM] +Válido até: [VALID_TO] +MD5 Fingerprint: [SHA1_DIGEST] +Impressão digital SHA1: [MD5_DIGEST] +Uso da chave: [KEYUSAGE] +Uso estendido da chave: [EXTENDEDKEYUSAGE] +Identificador chave de assunto: [SUBJECTKEYIDENTIFIER] + +Confiar nesta autoridade? +		<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Confiança"/> +	</notification>  	<notification name="NotEnoughCurrency">  		[NAME] L$ [PRICE] Você não possui suficientes L$ para fazer isso.  	</notification> @@ -1493,9 +1543,9 @@ Ir para o Banco de Conhecimento para maiores informações sobre Classificaçõe  		Você não é permitido nesta região devido à sua Classificação de maturidade.  	</notification>  	<notification name="RegionEntryAccessBlocked_Change"> -		Você não pode entrar nessa região devido à sua seleção de maturidade.  +		Você não pode entrar nessa região devido à sua seleção de maturidade. -Clique em 'Mudar preferência' para aumentar o nível de maturidade e entrar nessa região.  De agora em diante você pode buscar e acessar conteúdo [REGIONMATURITY] .  Para modificar esta configuração, vá à Eu > Preferências > Geral. +Clique em 'Mudar preferência' para aumentar seu nível de maturidade e ganhar acesso imediato. Você então poderá fazer buscas e acessar conteúdo [REGIONMATURITY]. Para modificar o nível de maturidade, use o menu Eu > Preferências > Gerais.  		<form name="form">  			<button name="OK" text="Mudar preferência"/>  			<button default="true" name="Cancel" text="Fechar"/> @@ -2262,15 +2312,6 @@ Por favor, tente novamente em alguns instantes.  			<button name="Mute" text="Bloquear"/>  		</form>  	</notification> -	<notification name="ObjectGiveItemUnknownUser"> -		Um objeto chamado [OBJECTFROMNAME] de (residente desconhecido) lhe deu [OBJECTTYPE]: -[ITEM_SLURL] -		<form name="form"> -			<button name="Keep" text="Segure"/> -			<button name="Discard" text="Descarte"/> -			<button name="Mute" text="Bloquear"/> -		</form> -	</notification>  	<notification name="UserGiveItem">  		[NAME_SLURL] lhe deu [OBJECTTYPE]:  [ITEM_SLURL] @@ -2583,8 +2624,52 @@ O botão será exibido quando houver espaço suficente.  	<notification name="ShareNotification">  		Arraste itens do inventário para uma pessoa no seletor de residentes  	</notification> +	<notification name="DeedToGroupFail"> +		Ocorreu uma falha durante a doação ao grupo. +	</notification>  	<notification name="AvatarRezNotification"> -		O avatar de '[NAME]' renderizou em [TIME] s. +		( [EXISTENCE] segundos de vida ) +O avatar de '[NAME]' emergiu em [TIME] segundos. +	</notification> +	<notification name="AvatarRezSelfNotification"> +		( [EXISTENCE] segundos de vida ) +Você confeccionou seu look em [TIME] segundos. +	</notification> +	<notification name="AvatarRezCloudNotification"> +		( [EXISTENCE] segundos de vida ) +Avatar '[NAME]' transformou-se em nuvem. +	</notification> +	<notification name="AvatarRezArrivedNotification"> +		( [EXISTENCE] segundos de vida ) +Avatar '[NAME]' surgiu. +	</notification> +	<notification name="AvatarRezLeftCloudNotification"> +		( [EXISTENCE] segundos de vida ) +O avatar de '[NAME]' transformou-se em nuvem depois de [TIME] segundos. +	</notification> +	<notification name="AvatarRezEnteredAppearanceNotification"> +		( [EXISTENCE] segundos de vida ) +Avatar '[NAME]' entrou no modo aparência. +	</notification> +	<notification name="AvatarRezLeftAppearanceNotification"> +		( [EXISTENCE] segundos de vida ) +Avatar '[NAME]' sair do modo aparecer. +	</notification> +	<notification name="AvatarRezLeftNotification"> +		( [EXISTENCE] segundos de vida ) +Avatar '[NAME]' saiu totalmente carregado. +	</notification> +	<notification name="ConfirmLeaveCall"> +		Tem certeza de que quer sair desta ligação? +		<usetemplate ignoretext="Confirmar antes de deixar ligação" name="okcancelignore" notext="Não" yestext="Sim"/> +	</notification> +	<notification name="ConfirmMuteAll"> +		Você silenciou todos os participantes de uma ligação de grupo. +Todos os demais residentes que entrarem na ligação mais tarde também serão silenciados, mesmo se você sair da ligação. + + +Silenciar todos? +		<usetemplate ignoretext="Confirmar antes de silenciar todos os participantes em ligações de grupo." name="okcancelignore" notext="OK" yestext="Cancelar"/>  	</notification>  	<global name="UnsupportedCPU">  		- A velocidade da sua CPU não suporta os requisitos mínimos exigidos. diff --git a/indra/newview/skins/default/xui/pt/panel_body_parts_list_item.xml b/indra/newview/skins/default/xui/pt/panel_body_parts_list_item.xml new file mode 100644 index 0000000000..de764d8025 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_body_parts_list_item.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="wearable_item"> +	<text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_bodyparts_list_button_bar.xml b/indra/newview/skins/default/xui/pt/panel_bodyparts_list_button_bar.xml new file mode 100644 index 0000000000..094a03553b --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_bodyparts_list_button_bar.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="clothing_list_button_bar_panel"> +	<button label="Trocar" name="switch_btn"/> +	<button label="Comprar >" name="bodyparts_shop_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_bottomtray.xml b/indra/newview/skins/default/xui/pt/panel_bottomtray.xml index 092135bd42..9fd7da55df 100644 --- a/indra/newview/skins/default/xui/pt/panel_bottomtray.xml +++ b/indra/newview/skins/default/xui/pt/panel_bottomtray.xml @@ -1,11 +1,7 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="bottom_tray"> -	<string name="SpeakBtnToolTip"> -		Liga e desliga o microfone -	</string> -	<string name="VoiceControlBtnToolTip"> -		Mostra/oculta os controles de voz -	</string> +	<string name="SpeakBtnToolTip" value="Liga e desliga o microfone"/> +	<string name="VoiceControlBtnToolTip" value="Mostra/oculta os controles de voz"/>  	<layout_stack name="toolbar_stack">  		<layout_panel name="speak_panel">  			<talk_button name="talk"> @@ -24,6 +20,21 @@  		<layout_panel name="snapshot_panel">  			<button label="" name="snapshots" tool_tip="Tirar foto"/>  		</layout_panel> +		<layout_panel name="sidebar_btn_panel"> +			<button label="Barra lateral" name="sidebar_btn" tool_tip="Mostra/oculta a barra lateral"/> +		</layout_panel> +		<layout_panel name="build_btn_panel"> +			<button label="Construir" name="build_btn" tool_tip="Mostra/oculta ferramentas de Construção"/> +		</layout_panel> +		<layout_panel name="search_btn_panel"> +			<button label="Busca" name="search_btn" tool_tip="Mostra/oculta os gestos"/> +		</layout_panel> +		<layout_panel name="world_map_btn_panel"> +			<button label="Mapa" name="world_map_btn" tool_tip="Mostra/oculta o Mapa Múndi"/> +		</layout_panel> +		<layout_panel name="mini_map_btn_panel"> +			<button label="Mini Mapa" name="mini_map_btn" tool_tip="Mostra/oculta o Mini Mapa"/> +		</layout_panel>  		<layout_panel name="im_well_panel">  			<chiclet_im_well name="im_well">  				<button name="Unread IM messages" tool_tip="Conversas"/> diff --git a/indra/newview/skins/default/xui/pt/panel_clothing_list_button_bar.xml b/indra/newview/skins/default/xui/pt/panel_clothing_list_button_bar.xml new file mode 100644 index 0000000000..bfdc7290d2 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_clothing_list_button_bar.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="clothing_list_button_bar_panel"> +	<button label="Adicionar +" name="add_btn"/> +	<button label="Comprar >" name="clothing_shop_btn"/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_clothing_list_item.xml b/indra/newview/skins/default/xui/pt/panel_clothing_list_item.xml new file mode 100644 index 0000000000..de764d8025 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_clothing_list_item.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="wearable_item"> +	<text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_cof_wearables.xml b/indra/newview/skins/default/xui/pt/panel_cof_wearables.xml new file mode 100644 index 0000000000..3e4b12b001 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_cof_wearables.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="cof_wearables"> +	<accordion name="cof_wearables_accordion"> +		<accordion_tab name="tab_attachments" title="Anexos"/> +		<accordion_tab name="tab_clothing" title="Vestuário"/> +		<accordion_tab name="tab_body_parts" title="Corpo"/> +	</accordion> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_deletable_wearable_list_item.xml b/indra/newview/skins/default/xui/pt/panel_deletable_wearable_list_item.xml new file mode 100644 index 0000000000..91d90a5660 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_deletable_wearable_list_item.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="deletable_wearable_item"> +	<text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_dummy_clothing_list_item.xml b/indra/newview/skins/default/xui/pt/panel_dummy_clothing_list_item.xml new file mode 100644 index 0000000000..6af84de0c7 --- /dev/null +++ b/indra/newview/skins/default/xui/pt/panel_dummy_clothing_list_item.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="dummy_clothing_item"> +	<text name="item_name" value="..."/> +</panel> diff --git a/indra/newview/skins/default/xui/pt/panel_edit_shape.xml b/indra/newview/skins/default/xui/pt/panel_edit_shape.xml index 504486c3bb..6b9ac94cac 100644 --- a/indra/newview/skins/default/xui/pt/panel_edit_shape.xml +++ b/indra/newview/skins/default/xui/pt/panel_edit_shape.xml @@ -1,14 +1,8 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel name="edit_shape_panel"> -	<panel name="avatar_sex_panel"> -		<text name="gender_text"> -			Sexo: -		</text> -		<radio_group name="sex_radio"> -			<radio_item label="Feminino" name="radio"/> -			<radio_item label="Masculino" name="radio2"/> -		</radio_group> -	</panel> +	<text name="avatar_height"> +		[HEIGHT] metros de altura +	</text>  	<panel label="Camisa" name="accordion_panel">  		<accordion name="wearable_accordion">  			<accordion_tab name="shape_body_tab" title="Corpo"/> diff --git a/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml index 23cde50acc..f85bb3c499 100644 --- a/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml +++ b/indra/newview/skins/default/xui/pt/panel_edit_tattoo.xml @@ -4,5 +4,6 @@  		<texture_picker label="Tatuagem de cabeça" name="Head Tattoo" tool_tip="Clique para escolher uma foto"/>  		<texture_picker label="Tatuagem superior" name="Upper Tattoo" tool_tip="Selecione uma foto"/>  		<texture_picker label="Tatuagem inferior" name="Lower Tattoo" tool_tip="Selecione uma foto"/> +		<color_swatch label="Cor/Tonalidade" name="Color/Tint" tool_tip="Selecionar a cor"/>  	</panel>  </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml b/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml index a78539f274..f14a04f440 100644 --- a/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml +++ b/indra/newview/skins/default/xui/pt/panel_edit_wearable.xml @@ -93,6 +93,12 @@  	<text name="edit_wearable_title" value="Editando forma"/>  	<panel label="Camisa" name="wearable_type_panel">  		<text name="description_text" value="Forma:"/> +		<radio_group name="sex_radio"> +			<radio_item label="" name="sex_male" tool_tip="Masculino" value="1"/> +			<radio_item label="" name="sex_female" tool_tip="Feminino" value="0"/> +		</radio_group> +		<icon name="male_icon" tool_tip="Masculino"/> +		<icon name="female_icon" tool_tip="Feminino"/>  	</panel>  	<panel label="gear_buttom_panel" name="gear_buttom_panel">  		<button name="friends_viewsort_btn" tool_tip="Opções"/> diff --git a/indra/newview/skins/default/xui/pt/panel_group_land_money.xml b/indra/newview/skins/default/xui/pt/panel_group_land_money.xml index 6f21b78b10..e57a85a726 100644 --- a/indra/newview/skins/default/xui/pt/panel_group_land_money.xml +++ b/indra/newview/skins/default/xui/pt/panel_group_land_money.xml @@ -6,6 +6,9 @@  	<panel.string name="cant_view_group_land_text">  		Você não está autorizado a acessar terrenos de grupos  	</panel.string> +	<panel.string name="epmty_view_group_land_text"> +		Nada consta +	</panel.string>  	<panel.string name="cant_view_group_accounting_text">  		Você não está autorizado a acessar os dados de contabilidade do grupo.  	</panel.string> diff --git a/indra/newview/skins/default/xui/pt/panel_group_notices.xml b/indra/newview/skins/default/xui/pt/panel_group_notices.xml index 4b5a00c761..9ccb85cdf6 100644 --- a/indra/newview/skins/default/xui/pt/panel_group_notices.xml +++ b/indra/newview/skins/default/xui/pt/panel_group_notices.xml @@ -39,6 +39,7 @@ Cada grupo pode enviar no máximo 200 avisos/dia  		<text name="string">  			Arrastar e soltar o item aqui para anexá-lo:  		</text> +		<button label="Inventário" name="open_inventory" tool_tip="Inventário aberto"/>  		<button label="Tirar" label_selected="Remover o anexo" name="remove_attachment" tool_tip="Remover anexo da notificação."/>  		<button label="Enviar" label_selected="Enviar" name="send_notice"/>  		<group_drop_target name="drop_target" tool_tip="Arrastar um item do inventário para a caixa para enviá-lo com o aviso. É preciso ter autorização de cópia e transferência do item para anexá-lo ao aviso."/> diff --git a/indra/newview/skins/default/xui/pt/panel_login.xml b/indra/newview/skins/default/xui/pt/panel_login.xml index 588b8deaa3..94a885960a 100644 --- a/indra/newview/skins/default/xui/pt/panel_login.xml +++ b/indra/newview/skins/default/xui/pt/panel_login.xml @@ -8,18 +8,15 @@  	</panel.string>  	<layout_stack name="login_widgets">  		<layout_panel name="login"> -			<text name="first_name_text"> -				Primeiro nome: +			<text name="username_text"> +				Nome de usuário:  			</text> -			<line_editor label="Nome" name="first_name_edit" tool_tip="[SECOND_LIFE] First Name"/> -			<text name="last_name_text"> -				Sobrenome: -			</text> -			<line_editor label="Sobrenome" name="last_name_edit" tool_tip="[SECOND_LIFE] Last Name"/> +			<line_editor label="Nome de usuário" name="username_edit" tool_tip="[SECOND_LIFE] Nome de usuário"/>  			<text name="password_text">  				Senha:  			</text>  			<check_box label="Lembrar senha" name="remember_check"/> +			<button label="conectar" name="connect_btn"/>  			<text name="start_location_text">  				Começar em:  			</text> @@ -27,7 +24,6 @@  				<combo_box.item label="Última posição" name="MyLastLocation"/>  				<combo_box.item label="Meu início" name="MyHome"/>  			</combo_box> -			<button label="conectar" name="connect_btn"/>  		</layout_panel>  		<layout_panel name="links">  			<text name="create_new_account_text"> diff --git a/indra/newview/skins/default/xui/pt/panel_main_inventory.xml b/indra/newview/skins/default/xui/pt/panel_main_inventory.xml index 104c3bface..dbf8e4fa52 100644 --- a/indra/newview/skins/default/xui/pt/panel_main_inventory.xml +++ b/indra/newview/skins/default/xui/pt/panel_main_inventory.xml @@ -9,62 +9,20 @@  	<text name="ItemcountText">  		Itens:  	</text> -	<menu_bar name="Inventory Menu"> -		<menu label="Arquivo" name="File"> -			<menu_item_call label="Abrir" name="Open"/> -			<menu label="Upload" name="upload"> -				<menu_item_call label="Imagem (L$[COST])..." name="Upload Image"/> -				<menu_item_call label="Som (L$[COST])..." name="Upload Sound"/> -				<menu_item_call label="Animação (L$[COST])..." name="Upload Animation"/> -				<menu_item_call label="Volume (L$[COST] per file)..." name="Bulk Upload"/> -			</menu> -			<menu_item_call label="Nova janela" name="New Window"/> -			<menu_item_call label="Mostrar filtros" name="Show Filters"/> -			<menu_item_call label="Restabelecer filtros" name="Reset Current"/> -			<menu_item_call label="Fechar todas as pastas" name="Close All Folders"/> -			<menu_item_call label="Esvaziar lixeira" name="Empty Trash"/> -			<menu_item_call label="Esvaziar achados e perdidos" name="Empty Lost And Found"/> -		</menu> -		<menu label="Crie" name="Create"> -			<menu_item_call label="Nova pasta" name="New Folder"/> -			<menu_item_call label="Novo script" name="New Script"/> -			<menu_item_call label="Nova anotação" name="New Note"/> -			<menu_item_call label="Novo gesto" name="New Gesture"/> -			<menu label="Novas roupas" name="New Clothes"> -				<menu_item_call label="Nova camisa" name="New Shirt"/> -				<menu_item_call label="Novas calças" name="New Pants"/> -				<menu_item_call label="Novos sapatos" name="New Shoes"/> -				<menu_item_call label="Novas meias" name="New Socks"/> -				<menu_item_call label="Nova blusa" name="New Jacket"/> -				<menu_item_call label="Nova saia" name="New Skirt"/> -				<menu_item_call label="Novas luvas" name="New Gloves"/> -				<menu_item_call label="Nova camiseta" name="New Undershirt"/> -				<menu_item_call label="Novas roupa de baixo" name="New Underpants"/> -				<menu_item_call label="Novo alpha" name="New Alpha"/> -				<menu_item_call label="Nova tatuagem" name="New Tattoo"/> -			</menu> -			<menu label="Nova parte do corpo" name="New Body Parts"> -				<menu_item_call label="Nova forma" name="New Shape"/> -				<menu_item_call label="Nova pele" name="New Skin"/> -				<menu_item_call label="Novo cabelo" name="New Hair"/> -				<menu_item_call label="Novos olhos" name="New Eyes"/> -			</menu> -		</menu> -		<menu label="Classificar" name="Sort"> -			<menu_item_check label="Por nome" name="By Name"/> -			<menu_item_check label="Por data" name="By Date"/> -			<menu_item_check label="Pastas sempre por nome" name="Folders Always By Name"/> -			<menu_item_check label="Pastas do sistema no topo" name="System Folders To Top"/> -		</menu> -	</menu_bar>  	<filter_editor label="Filtro" name="inventory search editor"/>  	<tab_container name="inventory filter tabs">  		<inventory_panel label="Todos os itens" name="All Items"/> -		<inventory_panel label="Itens recentes" name="Recent Items"/> +		<recent_inventory_panel label="Itens recentes" name="Recent Items"/>  	</tab_container> -	<panel name="bottom_panel"> -		<button name="options_gear_btn" tool_tip="Mostrar opções adicionais"/> -		<button name="add_btn" tool_tip="Adicionar novo item"/> -		<dnd_button name="trash_btn" tool_tip="Remover item selecionado"/> -	</panel> +	<layout_stack name="bottom_panel"> +		<layout_panel name="options_gear_btn_panel"> +			<button name="options_gear_btn" tool_tip="Mostrar opções adicionais"/> +		</layout_panel> +		<layout_panel name="add_btn_panel"> +			<button name="add_btn" tool_tip="Adicionar novo item"/> +		</layout_panel> +		<layout_panel name="trash_btn_panel"> +			<dnd_button name="trash_btn" tool_tip="Remover item selecionado"/> +		</layout_panel> +	</layout_stack>  </panel> diff --git a/indra/newview/skins/default/xui/pt/panel_outfit_edit.xml b/indra/newview/skins/default/xui/pt/panel_outfit_edit.xml index 3dc8b4cc75..61e470586e 100644 --- a/indra/newview/skins/default/xui/pt/panel_outfit_edit.xml +++ b/indra/newview/skins/default/xui/pt/panel_outfit_edit.xml @@ -2,6 +2,8 @@  <!-- Side tray Outfit Edit panel -->  <panel label="Editar look" name="outfit_edit">  	<string name="No Outfit" value="Nenhum"/> +	<string name="unsaved_changes" value="Mudanças não salvas"/> +	<string name="now_editing" value="Editando..."/>  	<panel.string name="not_available">  		(N\A)  	</panel.string> @@ -21,18 +23,13 @@  	</panel>  	<layout_stack name="im_panels">  		<layout_panel label="Painel de controle de MIs" name="outfit_wearables_panel"> -			<scroll_list name="look_items_list"> -				<scroll_list.columns label="Ver item" name="look_item"/> -				<scroll_list.columns label="Ordenar itens" name="look_item_sort"/> -			</scroll_list>  			<panel label="bottom_panel" name="edit_panel"/>  		</layout_panel>  		<layout_panel name="add_wearables_panel"> -			<filter_editor label="Filtro" name="look_item_filter"/> +			<text name="add_to_outfit_label" value="Adicionar ao look:"/>  			<layout_stack name="filter_panels"> -				<layout_panel label="Painel de controle de MIs" name="filter_button_panel"> -					<text name="add_to_outfit_label" value="Adicionar ao look:"/> -					<button label="O" name="filter_button"/> +				<layout_panel label="Painel de controle de MIs" name="filter_panel"> +					<filter_editor label="Filtro" name="look_item_filter"/>  				</layout_panel>  			</layout_stack>  			<panel label="add_wearables_button_bar" name="add_wearables_button_bar"> diff --git a/indra/newview/skins/default/xui/pt/panel_people.xml b/indra/newview/skins/default/xui/pt/panel_people.xml index 17f5b6cbac..efeea89fa9 100644 --- a/indra/newview/skins/default/xui/pt/panel_people.xml +++ b/indra/newview/skins/default/xui/pt/panel_people.xml @@ -2,9 +2,9 @@  <!-- Side tray panel -->  <panel label="Pessoas" name="people_panel">  	<string name="no_recent_people" value="Ninguém, recentemente. Em busca de alguém para conversar? Use a [secondlife:///app/search/people Busca] ou o [secondlife:///app/worldmap Mapa-Múndi]."/> -	<string name="no_filtered_recent_people" value="Não encontrou o que procura? Tente fazer uma [secondlife:///app/search/groups Busca]."/> +	<string name="no_filtered_recent_people" value="Não encontrou o que procura? Tente buscar no [secondlife:///app/search/people/[SEARCH_TERM] Search]."/>  	<string name="no_one_near" value="Ninguém por perto Em busca de alguém para conversar? Use a [secondlife:///app/search/people Busca] ou o [secondlife:///app/worldmap Mapa-Múndi]."/> -	<string name="no_one_filtered_near" value="Não encontrou o que procura? Tente fazer uma [secondlife:///app/search/groups Busca]."/> +	<string name="no_one_filtered_near" value="Não encontrou o que procura? Tente buscar no [secondlife:///app/search/people/[SEARCH_TERM] Search]."/>  	<string name="no_friends_online" value="Nenhum amigo online"/>  	<string name="no_friends" value="Nenhum amigo"/>  	<string name="no_friends_msg"> @@ -12,11 +12,11 @@  Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-Múndi].  	</string>  	<string name="no_filtered_friends_msg"> -		Não encontrou o que procura? Tente fazer uma [secondlife:///app/search/groups Busca]. +		Não encontrou o que procura? Tente buscar no [secondlife:///app/search/people/[SEARCH_TERM] Search].  	</string>  	<string name="people_filter_label" value="Filtro de pessoas"/>  	<string name="groups_filter_label" value="Filtro de grupos"/> -	<string name="no_filtered_groups_msg" value="Não encontrou o que procura? Tente fazer uma [secondlife:///app/search/groups Busca]."/> +	<string name="no_filtered_groups_msg" value="Não encontrou o que procura? Tente buscar no [secondlife:///app/search/groups/[SEARCH_TERM] Search]."/>  	<string name="no_groups_msg" value="À procura de grupos interessantes? Tente fazer uma [secondlife:///app/search/groups Busca]."/>  	<filter_editor label="Filtro" name="filter_input"/>  	<tab_container name="tabs"> @@ -55,8 +55,8 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-  		<button label="Perfil" name="view_profile_btn" tool_tip="Exibir fotografia, grupos e outras informações dos residentes" width="50"/>  		<button label="MI" name="im_btn" tool_tip="Iniciar MI" width="24"/>  		<button label="Chamada" name="call_btn" tool_tip="Ligar para este residente" width="61"/> -		<button label="Compartilhar" name="share_btn" width="82"/> -		<button label="Teletransporte" name="teleport_btn" tool_tip="Oferecer teletransporte"  width="86"/> +		<button label="Compartilhar" name="share_btn" tool_tip="Compartilhar item de inventário" width="82"/> +		<button label="Teletransporte" name="teleport_btn" tool_tip="Oferecer teletransporte" width="86"/>  		<button label="Perfil do grupo" name="group_info_btn" tool_tip="Exibir informação de grupo"/>  		<button label="Bate-papo de grupo" name="chat_btn" tool_tip="Iniciar bate-papo"/>  		<button label="Ligar para o grupo" name="group_call_btn" tool_tip="Ligar para este grupo"/> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml index 6f2cae0476..885aafc350 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml @@ -13,6 +13,7 @@  	</text>  	<check_box label="Construção/Edição" name="edit_camera_movement" tool_tip="Use o posicionamento automático da câmera quando entrar e sair do modo de edição"/>  	<check_box label="Aparência" name="appearance_camera_movement" tool_tip="Use o posicionamento automático da câmera quando em modo de edição"/> +	<check_box initial_value="1" label="Barra lateral" name="appearance_sidebar_positioning" tool_tip="Usar posicionamento automático da câmera na barra lateral"/>  	<check_box label="Mostre-me em visão de mouse" name="first_person_avatar_visible"/>  	<check_box label="Teclas de seta sempre me movem" name="arrow_keys_move_avatar_check"/>  	<check_box label="Dê dois toques e pressione para correr" name="tap_tap_hold_to_run"/> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml index e566fde27c..02b0ef35fe 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml @@ -45,6 +45,7 @@  	</text>  	<check_box initial_value="true" label="Executar animação digitada quando estiver conversando" name="play_typing_animation"/>  	<check_box label="Enviar MIs por email se estiver desconectado" name="send_im_to_email"/> +	<check_box label="Ativar MIs e bate-papos de texto simples" name="plain_text_chat_history"/>  	<text name="show_ims_in_label">  		Mostrar MIs em:  	</text> diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml index eb38323940..ccf213099e 100644 --- a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml @@ -1,8 +1,5 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel label="Gráficos" name="Display panel"> -	<text name="UI Size:"> -		Interface: -	</text>  	<text name="QualitySpeed">  		Qualidade e velocidade:  	</text> @@ -53,6 +50,10 @@ rápido  			m  		</text>  		<slider label="Contador máx. de partículas:" name="MaxParticleCount"/> +		<slider label="Distância máx. desenho avatar:" name="MaxAvatarDrawDistance"/> +		<text name="DrawDistanceMeterText3"> +			m +		</text>  		<slider label="Qualidade de Pós-processamento:" name="RenderPostProcess"/>  		<text name="MeshDetailText">  			Detalhes de Malha: diff --git a/indra/newview/skins/default/xui/pt/sidepanel_appearance.xml b/indra/newview/skins/default/xui/pt/sidepanel_appearance.xml index b8bbb4051a..f075f45b8f 100644 --- a/indra/newview/skins/default/xui/pt/sidepanel_appearance.xml +++ b/indra/newview/skins/default/xui/pt/sidepanel_appearance.xml @@ -1,9 +1,13 @@  <?xml version="1.0" encoding="utf-8" standalone="yes"?>  <panel label="Looks" name="appearance panel">  	<string name="No Outfit" value="Nenhum"/> +	<string name="Unsaved Changes" value="Mudanças não salvas"/> +	<string name="Now Wearing" value="Look atual..."/>  	<panel name="panel_currentlook"> -		<text name="currentlook_title"> -			(não salvo) +		<button label="E" name="editappearance_btn"/> +		<button label="O" name="openoutfit_btn"/> +		<text name="currentlook_status"> +			(Status)  		</text>  	</panel>  	<filter_editor label="Filtrar looks" name="Filter"/> diff --git a/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml b/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml index f634236cd2..31c96cad4c 100644 --- a/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml +++ b/indra/newview/skins/default/xui/pt/sidepanel_inventory.xml @@ -4,6 +4,7 @@  		<panel name="button_panel">  			<button label="Perfil" name="info_btn"/>  			<button label="Compartilhar" name="share_btn"/> +			<button label="Comprar" name="shop_btn"/>  			<button label="Vestir" name="wear_btn"/>  			<button label="Tocar" name="play_btn"/>  			<button label="Teletransportar" name="teleport_btn"/> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 51b6581d42..f865124009 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -88,6 +88,24 @@  	<string name="LoginDownloadingClothing">  		Baixando roupas...  	</string> +	<string name="InvalidCertificate"> +		O servidor respondeu com um certificado inválido ou corrompido. Por favor contate o administrador do Grid. +	</string> +	<string name="CertInvalidHostname"> +		Um hostname inválido foi usado para acessar o servidor. Verifique o SLURL ou hostname do Grid. +	</string> +	<string name="CertExpired"> +		O certificado dado pelo Grid parece estar vencido.  Verifique o relógio do sistema ou contate o administrador do Grid. +	</string> +	<string name="CertKeyUsage"> +		O certificado dado pelo servidor não pôde ser usado para SSL.  Por favor contate o administrador do Grid. +	</string> +	<string name="CertBasicConstraints"> +		A cadeia de certificados do servidor tinha certificados demais.  Por favor contate o administrador do Grid. +	</string> +	<string name="CertInvalidSignature"> +		A assinatura do certificado dado pelo servidor do Grid não pôde ser verificada.  Por favor contate o administrador do Grid. +	</string>  	<string name="LoginFailedNoNetwork">  		Erro de rede: Não foi possível estabelecer a conexão, verifique sua conexão de rede.  	</string> @@ -819,6 +837,42 @@  	<string name="invalid">  		Inválido  	</string> +	<string name="shirt_not_worn"> +		Camisa não vestida +	</string> +	<string name="pants_not_worn"> +		Calças não vestidas +	</string> +	<string name="shoes_not_worn"> +		Sapatos não calçados +	</string> +	<string name="socks_not_worn"> +		Meias não calçadas +	</string> +	<string name="jacket_not_worn"> +		Jaqueta não vestida +	</string> +	<string name="gloves_not_worn"> +		Luvas não calçadas +	</string> +	<string name="undershirt_not_worn"> +		Camiseta não vestida +	</string> +	<string name="underpants_not_worn"> +		Roupa de baixo não vestida +	</string> +	<string name="skirt_not_worn"> +		Saia não vestida +	</string> +	<string name="alpha_not_worn"> +		Alpha não vestido +	</string> +	<string name="tattoo_not_worn"> +		Tatuagem não usada +	</string> +	<string name="invalid_not_worn"> +		inválido +	</string>  	<string name="NewWearable">  		Novo [WEARABLE_ITEM]  	</string> @@ -889,7 +943,10 @@  		Pressione ESC para retornar para visão do mundo  	</string>  	<string name="InventoryNoMatchingItems"> -		Não encontrou o que procura? Tente fazer uma [secondlife:///app/search/groups Busca]. +		Não encontrou o que procura? Tente buscar no [secondlife:///app/search/people/[SEARCH_TERM] Search]. +	</string> +	<string name="PlacesNoMatchingItems"> +		Não encontrou o que procura? Tente buscar no [secondlife:///app/search/groups/[SEARCH_TERM] Search].  	</string>  	<string name="FavoritesNoMatchingItems">  		Arraste um marco para adicioná-lo aos seus favoritos. @@ -919,6 +976,7 @@  	<string name="Wave" value="Acenar"/>  	<string name="HelloAvatar" value="Olá, avatar!"/>  	<string name="ViewAllGestures" value="Ver todos>>"/> +	<string name="GetMoreGestures" value="Mais >>"/>  	<string name="Animations" value="Animações,"/>  	<string name="Calling Cards" value="Cartões de visitas,"/>  	<string name="Clothing" value="Vestuário,"/> @@ -1542,6 +1600,9 @@  	<string name="MuteGroup">  		(grupo)  	</string> +	<string name="MuteExternal"> +		(Externo) +	</string>  	<string name="RegionNoCovenant">  		Não foi definido um contrato para essa região.  	</string> @@ -3299,11 +3360,14 @@ If you continue to receive this message, contact the [SUPPORT_SITE].  	<string name="answered_call">  		Ligação atendida  	</string> -	<string name="started_call"> -		Iniciou uma ligação de voz +	<string name="you_started_call"> +		Você iniciou uma ligação de voz +	</string> +	<string name="you_joined_call"> +		Você entrou na ligação  	</string> -	<string name="joined_call"> -		Entrou na ligação +	<string name="name_started_call"> +		[NAME] iniciou uma ligação de voz  	</string>  	<string name="ringing-im">  		Entrando em ligação de voz... @@ -3502,6 +3566,90 @@ Denunciar abuso  	<string name="Contents">  		Conteúdo  	</string> +	<string name="Gesture"> +		Gesto +	</string> +	<string name="Male Gestures"> +		Gestos masculinos +	</string> +	<string name="Female Gestures"> +		Gestos femininos +	</string> +	<string name="Other Gestures"> +		Outros gestos +	</string> +	<string name="Speech Gestures"> +		Gestos da fala +	</string> +	<string name="Common Gestures"> +		Gestos comuns +	</string> +	<string name="Male - Excuse me"> +		Perdão - masculino +	</string> +	<string name="Male - Get lost"> +		Deixe-me em paz - masculino +	</string> +	<string name="Male - Blow kiss"> +		Mandar beijo - masculino +	</string> +	<string name="Male - Boo"> +		Vaia - masculino +	</string> +	<string name="Male - Bored"> +		Maçante - masculino +	</string> +	<string name="Male - Hey"> +		Ôpa! - masculino +	</string> +	<string name="Male - Laugh"> +		Risada - masculino +	</string> +	<string name="Male - Repulsed"> +		Quero distância! - masculino +	</string> +	<string name="Male - Shrug"> +		Encolher de ombros - masculino +	</string> +	<string name="Male - Stick tougue out"> +		Mostrar a língua - masculino +	</string> +	<string name="Male - Wow"> +		Wow - masculino +	</string> +	<string name="FeMale - Excuse me"> +		Perdão - masc/fem +	</string> +	<string name="FeMale - Get lost"> +		Deixe-me em paz - feminino +	</string> +	<string name="FeMale - Blow kiss"> +		Mandar beijo - masc/fem +	</string> +	<string name="FeMale - Boo"> +		Vaia - masc/fem +	</string> +	<string name="Female - Bored"> +		Maçante - feminino +	</string> +	<string name="Female - Hey"> +		Ôpa - feminino +	</string> +	<string name="Female - Laugh"> +		Risada - feminina +	</string> +	<string name="Female - Repulsed"> +		Quero distância! - feminino +	</string> +	<string name="Female - Shrug"> +		Encolher ombros - feminino +	</string> +	<string name="Female - Stick tougue out"> +		Mostrar a língua - feminino +	</string> +	<string name="Female - Wow"> +		Wow - feminino +	</string>  	<string name="AvatarBirthDateFormat">  		[mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt]  	</string> diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 8c089c0b79..0fd3cf5b3b 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -41,9 +41,12 @@ from llmanifest import LLManifest, main, proper_windows_path, path_ancestors  class ViewerManifest(LLManifest):      def is_packaging_viewer(self): -        # This is overridden by the WindowsManifest sub-class, -        # which has different behavior if it is not packaging the viewer. -        return True +        # Some commands, files will only be included +        # if we are packaging the viewer on windows. +        # This manifest is also used to copy +        # files during the build (see copy_w_viewer_manifest +        # and copy_l_viewer_manifest targets) +        return 'package' in self.args['actions']      def construct(self):          super(ViewerManifest, self).construct() @@ -175,13 +178,6 @@ class WindowsManifest(ViewerManifest):          else:              return ''.join(self.channel().split()) + '.exe' -    def is_packaging_viewer(self): -        # Some commands, files will only be included -        # if we are packaging the viewer on windows. -        # This manifest is also used to copy -        # files during the build. -        return 'package' in self.args['actions'] -      def test_msvcrt_and_copy_action(self, src, dst):          # This is used to test a dll manifest.          # It is used as a temporary override during the construct method @@ -563,6 +559,10 @@ class WindowsManifest(ViewerManifest):  class DarwinManifest(ViewerManifest): +    def is_packaging_viewer(self): +        # darwin requires full app bundle packaging even for debugging. +        return True +      def construct(self):          # copy over the build result (this is a no-op if run within the xcode script)          self.path(self.args['configuration'] + "/Second Life.app", dst="") @@ -641,7 +641,9 @@ class DarwinManifest(ViewerManifest):                  if dylibs["llcommon"]:                      for libfile in ("libapr-1.0.3.7.dylib",                                      "libaprutil-1.0.3.8.dylib", -                                    "libexpat.0.5.0.dylib"): +                                    "libexpat.0.5.0.dylib", +                                    "libexception_handler.dylib", +                                    ):                          self.path(os.path.join(libdir, libfile), libfile)                  #libfmodwrapper.dylib @@ -662,7 +664,9 @@ class DarwinManifest(ViewerManifest):                      for libfile in ("libllcommon.dylib",                                      "libapr-1.0.3.7.dylib",                                      "libaprutil-1.0.3.8.dylib", -                                    "libexpat.0.5.0.dylib"): +                                    "libexpat.0.5.0.dylib", +                                    "libexception_handler.dylib", +                                    ):                          target_lib = os.path.join('../../..', libfile)                          self.run_command("ln -sf %(target)r %(link)r" %                                            {'target': target_lib, @@ -893,6 +897,7 @@ class Linux_i686Manifest(LinuxManifest):          if self.prefix("../../libraries/i686-linux/lib_release_client", dst="lib"):              self.path("libapr-1.so.0")              self.path("libaprutil-1.so.0") +            self.path("libbreakpad_client.so.0.0.0", "libbreakpad_client.so.0")              self.path("libdb-4.2.so")              self.path("libcrypto.so.0.9.7")              self.path("libexpat.so.1") @@ -930,7 +935,7 @@ class Linux_i686Manifest(LinuxManifest):                      self.path("libvivoxplatform.so")                      self.end_prefix("lib") -        if self.args['buildtype'].lower() == 'release': +        if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer():              print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build"              self.run_command("find %(d)r/bin %(d)r/lib -type f | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure diff --git a/indra/win_crash_logger/llcrashloggerwindows.cpp b/indra/win_crash_logger/llcrashloggerwindows.cpp index c9e01c8418..2884231299 100644 --- a/indra/win_crash_logger/llcrashloggerwindows.cpp +++ b/indra/win_crash_logger/llcrashloggerwindows.cpp @@ -299,7 +299,6 @@ void LLCrashLoggerWindows::gatherPlatformSpecificFiles()  	// At this point we're responsive enough the user could click the close button  	SetCursor(gCursorArrow);  	mDebugLog["DisplayDeviceInfo"] = gDXHardware.getDisplayInfo(); -	mFileMap["CrashLog"] = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"SecondLifeException.log");  }  bool LLCrashLoggerWindows::mainLoop()  | 
