diff --git a/indra/aistatemachine/aistatemachine.cpp b/indra/aistatemachine/aistatemachine.cpp
index 134461e09..6afac951c 100644
--- a/indra/aistatemachine/aistatemachine.cpp
+++ b/indra/aistatemachine/aistatemachine.cpp
@@ -407,7 +407,7 @@ void AIEngine::setMaxCount(F32 StateMachineMaxTime)
sMaxCount = calc_clock_frequency() * StateMachineMaxTime / 1000;
}
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
char const* AIStateMachine::event_str(event_type event)
{
switch(event)
diff --git a/indra/aistatemachine/aistatemachine.h b/indra/aistatemachine/aistatemachine.h
index be73dec96..f60430ed9 100644
--- a/indra/aistatemachine/aistatemachine.h
+++ b/indra/aistatemachine/aistatemachine.h
@@ -330,7 +330,7 @@ public:
bool mDebugAdvanceStatePending; // True while advance_state() was called by not handled yet.
bool mDebugRefCalled; // True when ref() is called (or will be called within the critial area of mMultiplexMutex).
#endif
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
protected:
bool mSMDebug; // Print debug output only when true.
#endif
@@ -343,7 +343,7 @@ public:
mThreadId(AIThreadID::none), mDebugLastState(bs_killed), mDebugShouldRun(false), mDebugAborted(false), mDebugContPending(false),
mDebugSetStatePending(false), mDebugAdvanceStatePending(false), mDebugRefCalled(false),
#endif
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
mSMDebug(debug),
#endif
mRuntime(0)
@@ -428,7 +428,7 @@ public:
// Return stringified state, for debugging purposes.
char const* state_str(base_state_type state);
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
char const* event_str(event_type event);
#endif
diff --git a/indra/aistatemachine/aistatemachinethread.h b/indra/aistatemachine/aistatemachinethread.h
index 58b1e812a..193c2e0d4 100644
--- a/indra/aistatemachine/aistatemachinethread.h
+++ b/indra/aistatemachine/aistatemachinethread.h
@@ -182,7 +182,7 @@ class AIStateMachineThreadBase : public AIStateMachine {
protected:
AIStateMachineThreadBase(CWD_ONLY(bool debug))
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
: AIStateMachine(debug)
#endif
{ }
@@ -222,7 +222,7 @@ class AIStateMachineThread : public AIStateMachineThreadBase {
public:
// Constructor.
AIStateMachineThread(CWD_ONLY(bool debug))
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
: AIStateMachineThreadBase(debug)
#endif
{
diff --git a/indra/aistatemachine/aitimer.h b/indra/aistatemachine/aitimer.h
index f3623c1d9..97f3b297e 100644
--- a/indra/aistatemachine/aitimer.h
+++ b/indra/aistatemachine/aitimer.h
@@ -77,7 +77,7 @@ class AITimer : public AIStateMachine {
public:
AITimer(CWD_ONLY(bool debug = false)) :
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
AIStateMachine(debug),
#endif
mInterval(0) { DoutEntering(dc::statemachine(mSMDebug), "AITimer(void) [" << (void*)this << "]"); }
diff --git a/indra/cmake/OpenSSL.cmake b/indra/cmake/OpenSSL.cmake
index fffe868fd..51532054c 100644
--- a/indra/cmake/OpenSSL.cmake
+++ b/indra/cmake/OpenSSL.cmake
@@ -16,6 +16,8 @@ else (STANDALONE OR USE_SYSTEM_OPENSSL)
set(OPENSSL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
endif (STANDALONE OR USE_SYSTEM_OPENSSL)
-if (LINUX OR DARWIN)
+if (LINUX)
+ set(CRYPTO_LIBRARIES crypto dl)
+elseif (DARWIN)
set(CRYPTO_LIBRARIES crypto)
-endif (LINUX OR DARWIN)
+endif (LINUX)
diff --git a/indra/cmake/PNG.cmake b/indra/cmake/PNG.cmake
index 011b87f64..565c22cec 100644
--- a/indra/cmake/PNG.cmake
+++ b/indra/cmake/PNG.cmake
@@ -13,7 +13,25 @@ else (STANDALONE)
elseif(DARWIN)
set(PNG_LIBRARIES png15)
else(LINUX)
- set(PNG_LIBRARIES png15)
+ if (CMAKE_SIZEOF_VOID_P EQUAL 4) # Singu TODO: update png
+ set(PNG_LIBRARIES png15)
+ else ()
+ #
+ # When we have updated static libraries in competition with older
+ # shared libraries and we want the former to win, we need to do some
+ # extra work. The *_PRELOAD_ARCHIVES settings are invoked early
+ # and will pull in the entire archive to the binary giving it
+ # priority in symbol resolution. Beware of cmake moving the
+ # achive load itself to another place on the link command line. If
+ # that happens, you can try something like -Wl,-lpng16 here to hide
+ # the archive. Also be aware that the linker will not tolerate a
+ # second whole-archive load of the archive. See viewer's
+ # CMakeLists.txt for more information.
+ #
+ set(PNG_PRELOAD_ARCHIVES -Wl,--whole-archive png16 -Wl,--no-whole-archive)
+ set(PNG_LIBRARIES png16)
+ set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng16)
+ endif ()
endif()
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/)
endif (STANDALONE)
diff --git a/indra/cmake/WebKitLibPlugin.cmake b/indra/cmake/WebKitLibPlugin.cmake
index 5d1036c6f..7a6305f22 100644
--- a/indra/cmake/WebKitLibPlugin.cmake
+++ b/indra/cmake/WebKitLibPlugin.cmake
@@ -50,7 +50,6 @@ elseif (LINUX)
ssl
# qgif
# qjpeg
- jscore
jpeg
fontconfig
X11
@@ -58,5 +57,8 @@ elseif (LINUX)
Xext
GL
)
+ if (CMAKE_SIZEOF_VOID_P EQUAL 4) # Singu TODO: update webkit
+ set(WEBKIT_PLUGIN_LIBRARIES ${WEBKIT_PLUGIN_LIBRARIES} jscore)
+ endif (CMAKE_SIZEOF_VOID_P EQUAL 4)
endif (STANDALONE)
endif (WINDOWS)
diff --git a/indra/cwdebug/debug.h b/indra/cwdebug/debug.h
index 58e0c6ac9..93a037c92 100644
--- a/indra/cwdebug/debug.h
+++ b/indra/cwdebug/debug.h
@@ -28,97 +28,16 @@
#ifndef CWDEBUG
#ifdef DEBUG_CURLIO
-
-// If CWDEBUG is not defined, but DEBUG_CURLIO is, then replace
-// some of the cwd macro's with something that generates viewer
-// specific debug output. Note that this generates a LOT of
-// output and should not normally be defined.
-
-#include
-#include "llpreprocessor.h"
-
-namespace debug {
-namespace libcwd {
-
-struct buf2str {
- buf2str(char const* buf, int size) : mBuf(buf), mSize(size) { }
- char const* mBuf;
- int mSize;
-};
-
-struct libcwd_do_type {
- void on() const { }
-};
-extern LL_COMMON_API libcwd_do_type const libcw_do;
-
-} // namespace libcwd
-
-enum print_thread_id_t { print_thread_id };
-inline void init() { }
-struct Indent {
- int M_indent;
- static ll_thread_local int S_indentation;
- enum LL_COMMON_API print_nt { print };
- LL_COMMON_API Indent(int indent);
- LL_COMMON_API ~Indent();
-};
-
-extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, libcwd::buf2str const& b2s);
-extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, Indent::print_nt);
-extern LL_COMMON_API std::ostream& operator<<(std::ostream& os, print_thread_id_t);
-
-namespace dc {
-
-struct fake_channel {
- int mOn;
- char const* mLabel;
- fake_channel(int on, char const* label) : mOn(on), mLabel(label) { }
- fake_channel(void) : mOn(0) { }
- fake_channel& operator()(bool) { return *this; }
- fake_channel const& operator()(bool) const { return *this; }
- bool is_on() const { return !!mOn; }
- bool is_off() const { return !mOn; }
- void on() const { }
- void off() const { }
-};
-extern LL_COMMON_API fake_channel const warning;
-extern LL_COMMON_API fake_channel const curl;
-extern LL_COMMON_API fake_channel const curlio;
-extern LL_COMMON_API fake_channel const curltr;
-extern LL_COMMON_API fake_channel const statemachine;
-extern LL_COMMON_API fake_channel const notice;
-extern LL_COMMON_API fake_channel const snapshot;
-
-} // namespace dc
-} // namespace debug
-
-#define LIBCWD_DEBUG_CHANNELS debug
-#define LibcwDoutScopeBegin(a, b, c) do { using namespace debug; using namespace debug::libcwd; llinfos_nf << print_thread_id << (c).mLabel << ": " << Indent::print;
-#define LibcwDoutStream llcont
-#define LibcwDoutScopeEnd llcont << llendl; } while(0)
-
-#define Debug(x) do { using namespace debug; using namespace debug::libcwd; x; } while(0)
-#define Dout(a, b) do { using namespace debug; using namespace debug::libcwd; if ((a).mOn) { llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << b << llendl; } } while(0)
-#define DoutEntering(a, b) \
- int __slviewer_debug_indentation = 2; \
- { \
- using namespace debug; \
- using namespace debug::libcwd; \
- if ((a).mOn) \
- llinfos_nf << print_thread_id << (a).mLabel << ": " << Indent::print << "Entering " << b << llendl; \
- else \
- __slviewer_debug_indentation = 0; \
- } \
- debug::Indent __slviewer_debug_indent(__slviewer_debug_indentation);
-
-#else // !DEBUG_CURLIO
+#error DEBUG_CURLIO is not supported without libcwd.
+// In order to use DEBUG_CURLIO you must install and use libcwd.
+// Download libcwd:
+// git clone https://github.com/CarloWood/libcwd.git
+#endif
#define Debug(x)
#define Dout(a, b)
#define DoutEntering(a, b)
-#endif // !DEBUG_CURLIO
-
#ifndef DOXYGEN // No need to document this. See http://libcwd.sourceforge.net/ for more info.
#include
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
index 3d3420961..d26b45208 100644
--- a/indra/llappearance/llavatarappearance.cpp
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -182,9 +182,6 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :
}
mIsBuilt = FALSE;
-
- mNumCollisionVolumes = 0;
- mCollisionVolumes = NULL;
}
// virtual
@@ -294,7 +291,7 @@ LLAvatarAppearance::~LLAvatarAppearance()
mJointMap.clear();
clearSkeleton();
- deleteAndClearArray(mCollisionVolumes);
+ clearCollisionVolumes();
std::for_each(mPolyMeshes.begin(), mPolyMeshes.end(), DeletePairedPointer());
mPolyMeshes.clear();
@@ -575,12 +572,12 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent
}
else // collision volume
{
- if (volume_num >= (S32)mNumCollisionVolumes)
+ if (volume_num >= (S32)mCollisionVolumes.size())
{
llwarns << "Too many bones" << llendl;
return FALSE;
}
- joint = (&mCollisionVolumes[volume_num]);
+ joint = (mCollisionVolumes[volume_num]);
joint->setName( info->mName );
}
@@ -1250,12 +1247,12 @@ LLVector3 LLAvatarAppearance::getVolumePos(S32 joint_index, LLVector3& volume_of
return LLVector3::zero;
}
- if (joint_index > mNumCollisionVolumes)
+ if (joint_index > (S32)mCollisionVolumes.size())
{
return LLVector3::zero;
}
- return mCollisionVolumes[joint_index].getVolumePos(volume_offset);
+ return mCollisionVolumes[joint_index]->getVolumePos(volume_offset);
}
//-----------------------------------------------------------------------------
@@ -1266,12 +1263,12 @@ LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id)
//SNOW-488: As mNumCollisionVolumes is a S32 and we are casting from a U32 to a S32
//to compare we also need to be sure of the wrap around case producing (S32) <0
//or in terms of the U32 an out of bounds index in the array.
- if ((S32)volume_id > mNumCollisionVolumes || (S32)volume_id<0)
+ if ((S32)volume_id > (S32)mCollisionVolumes.size() || (S32)volume_id<0)
{
return NULL;
}
- return &mCollisionVolumes[volume_id];
+ return mCollisionVolumes[volume_id];
}
//-----------------------------------------------------------------------------
@@ -1279,9 +1276,9 @@ LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id)
//-----------------------------------------------------------------------------
S32 LLAvatarAppearance::getCollisionVolumeID(std::string &name)
{
- for (S32 i = 0; i < mNumCollisionVolumes; i++)
+ for (S32 i = 0; i < (S32)mCollisionVolumes.size(); i++)
{
- if (mCollisionVolumes[i].getName() == name)
+ if (mCollisionVolumes[i]->getName() == name)
{
return i;
}
@@ -1530,21 +1527,34 @@ LLTexLayerSet* LLAvatarAppearance::getAvatarLayerSet(EBakedTextureIndex baked_in
return mBakedTextureDatas[baked_index].mTexLayerSet;
}
+void LLAvatarAppearance::clearCollisionVolumes()
+{
+ std::for_each(mCollisionVolumes.begin(), mCollisionVolumes.end(),
+ DeletePointer());
+ mCollisionVolumes.clear();
+}
+
//-----------------------------------------------------------------------------
// allocateCollisionVolumes()
//-----------------------------------------------------------------------------
BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num )
{
- deleteAndClearArray(mCollisionVolumes);
- mNumCollisionVolumes = 0;
+ mCollisionVolumes.reserve(num);
- mCollisionVolumes = new LLAvatarJointCollisionVolume[num];
- if (!mCollisionVolumes)
+ LLAvatarJointCollisionVolume* cv;
+ for (U32 i = 0; i < num; ++i)
{
- return FALSE;
+ cv = new LLAvatarJointCollisionVolume();
+ if (cv)
+ {
+ mCollisionVolumes.push_back(cv);
+ }
+ else
+ {
+ clearCollisionVolumes();
+ return false;
+ }
}
-
- mNumCollisionVolumes = num;
return TRUE;
}
diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h
index b3a02e410..da4e09b42 100644
--- a/indra/llappearance/llavatarappearance.h
+++ b/indra/llappearance/llavatarappearance.h
@@ -337,9 +337,9 @@ protected:
// Collision volumes
//--------------------------------------------------------------------
public:
- S32 mNumCollisionVolumes;
- LLAvatarJointCollisionVolume* mCollisionVolumes;
+ std::vector mCollisionVolumes;
protected:
+ void clearCollisionVolumes();
BOOL allocateCollisionVolumes(U32 num);
/** Physics
diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp
index aeaf79f33..669c2e5fb 100644
--- a/indra/llappearance/llpolymorph.cpp
+++ b/indra/llappearance/llpolymorph.cpp
@@ -647,11 +647,11 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)
for (iter = getInfo()->mVolumeInfoList.begin(); iter != getInfo()->mVolumeInfoList.end(); iter++)
{
LLPolyVolumeMorphInfo *volume_info = &(*iter);
- for (S32 i = 0; i < avatarp->mNumCollisionVolumes; i++)
+ for (S32 i = 0; i < (S32)avatarp->mCollisionVolumes.size(); i++)
{
- if (avatarp->mCollisionVolumes[i].getName() == volume_info->mName)
+ if (avatarp->mCollisionVolumes[i]->getName() == volume_info->mName)
{
- mVolumeMorphs.push_back(LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i],
+ mVolumeMorphs.push_back(LLPolyVolumeMorph(avatarp->mCollisionVolumes[i],
volume_info->mScale,
volume_info->mPos));
break;
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 8ae5141a1..4b6059f86 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -386,12 +386,12 @@ void LLApp::setupErrorHandling()
// installing the handler.
installHandler = true;
}
- #endif
if(installHandler && (mExceptionHandler == 0))
{
mExceptionHandler = new google_breakpad::ExceptionHandler(mDumpPath, clear_CrashLoggerReserve_callback, &unix_post_minidump_callback, 0, true, 0);
}
+ #endif
#elif LL_LINUX
if(installHandler && (mExceptionHandler == 0))
{
diff --git a/indra/llcommon/llprocessor.cpp b/indra/llcommon/llprocessor.cpp
index a7d2eac67..e39fa373d 100644
--- a/indra/llcommon/llprocessor.cpp
+++ b/indra/llcommon/llprocessor.cpp
@@ -206,6 +206,7 @@ namespace
return "Unknown";
}
+#if LL_LINUX
std::string compute_CPUFamilyName(const char* cpu_vendor, int composed_family)
{
const char* intel_string = "GenuineIntel";
@@ -221,6 +222,7 @@ namespace
return "Unknown";
}
+#else
std::string compute_CPUFamilyName(const char* cpu_vendor, int family, int ext_family)
{
const char* intel_string = "GenuineIntel";
@@ -239,6 +241,7 @@ namespace
}
return "Unknown";
}
+#endif
} // end unnamed namespace
diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h
index ca6d76a98..bb0d60247 100644
--- a/indra/llcommon/llregistry.h
+++ b/indra/llcommon/llregistry.h
@@ -307,8 +307,10 @@ public:
virtual ~StaticRegistrar() {}
StaticRegistrar(ref_const_key_t key, ref_const_value_t value)
{
- if(!singleton_t::instance().mStaticScope)
- mStaticScope = new ScopedRegistrar();
+ if (singleton_t::instance().exists(key))
+ {
+ llerrs << "Duplicate registry entry under key \"" << key << "\"" << llendl;
+ }
singleton_t::instance().mStaticScope->add(key, value);
}
};
@@ -338,7 +340,7 @@ protected:
virtual void initSingleton()
{
- //mStaticScope = new ScopedRegistrar();
+ mStaticScope = new ScopedRegistrar();
}
virtual ~LLRegistrySingleton()
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index eb8e2c945..3d32d4771 100644
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -28,5 +28,5 @@
#include "llsingleton.h"
-std::map * LLSingletonRegistry::sSingletonMap = NULL;
+std::map* LLSingletonRegistry::sSingletonMap = NULL;
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index aa8efb1e0..b1e17fc13 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -33,34 +33,25 @@
/// @brief A global registry of all singletons to prevent duplicate allocations
/// across shared library boundaries
-class LLSingletonRegistry {
- private:
- typedef std::map TypeMap;
- static LL_COMMON_API TypeMap * sSingletonMap;
+class LL_COMMON_API LLSingletonRegistry
+{
+ typedef std::map TypeMap;
+ static TypeMap* sSingletonMap;
- static void checkInit()
- {
- if(sSingletonMap == NULL)
- {
- sSingletonMap = new TypeMap();
- }
- }
+public:
+ template static void * & get()
+ {
+ std::string name(typeid(T).name());
+ if (!sSingletonMap) sSingletonMap = new TypeMap();
- public:
- template static void * & get()
- {
- std::string name(typeid(T).name());
+ // the first entry of the pair returned by insert will be either the existing
+ // iterator matching our key, or the newly inserted NULL initialized entry
+ // see "Insert element" in http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
+ TypeMap::iterator result =
+ sSingletonMap->insert(std::make_pair(name, (void*)NULL)).first;
- checkInit();
-
- // the first entry of the pair returned by insert will be either the existing
- // iterator matching our key, or the newly inserted NULL initialized entry
- // see "Insert element" in http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html
- TypeMap::iterator result =
- sSingletonMap->insert(std::make_pair(name, (void*)NULL)).first;
-
- return result->second;
- }
+ return result->second;
+ }
};
// LLSingleton implements the getInstance() method part of the Singleton
@@ -90,7 +81,7 @@ class LLSingletonRegistry {
template
class LLSingleton : private boost::noncopyable
{
-
+
private:
typedef enum e_init_state
{
@@ -100,34 +91,46 @@ private:
INITIALIZED,
DELETED
} EInitState;
-
- // stores pointer to singleton instance
- // and tracks initialization state of singleton
- struct SingletonInstanceData
- {
- EInitState mInitState;
- DERIVED_TYPE* mSingletonInstance;
-
- SingletonInstanceData()
- : mSingletonInstance(NULL),
- mInitState(UNINITIALIZED)
- {}
- ~SingletonInstanceData()
+ static DERIVED_TYPE* constructSingleton()
+ {
+ return new DERIVED_TYPE();
+ }
+
+ struct SingletonData;
+
+ // stores pointer to singleton instance
+ struct SingletonLifetimeManager
+ {
+ SingletonLifetimeManager()
{
- if (mInitState != DELETED)
+ construct();
+ }
+
+ static void construct()
+ {
+ SingletonData& sData(getData());
+ sData.mInitState = CONSTRUCTING;
+ sData.mInstance = constructSingleton();
+ sData.mInitState = INITIALIZING;
+ }
+
+ ~SingletonLifetimeManager()
+ {
+ SingletonData& sData(getData());
+ if (sData.mInitState != DELETED)
{
deleteSingleton();
}
}
};
-
+
public:
virtual ~LLSingleton()
{
- SingletonInstanceData& data = getData();
- data.mSingletonInstance = NULL;
- data.mInitState = DELETED;
+ SingletonData& sData(getData());
+ sData.mInstance = NULL;
+ sData.mInitState = DELETED;
}
/**
@@ -152,37 +155,66 @@ public:
*/
static void deleteSingleton()
{
- DERIVED_TYPE* instance = getData().mSingletonInstance;
- getData().mInitState = DELETED;
- getData().mSingletonInstance = NULL;
- delete instance;
+ SingletonData& sData(getData());
+ delete sData.mInstance;
+ sData.mInstance = NULL;
+ sData.mInitState = DELETED;
}
- static SingletonInstanceData& getData()
+ static SingletonData& getData()
{
// this is static to cache the lookup results
static void * & registry = LLSingletonRegistry::get();
// *TODO - look into making this threadsafe
- if(NULL == registry)
+ if (!registry)
{
- static SingletonInstanceData data;
+ static SingletonData data;
registry = &data;
}
- return *static_cast(registry);
+ return *static_cast(registry);
}
static DERIVED_TYPE* getInstance()
{
- SingletonInstanceData& data = getData();
+ static SingletonLifetimeManager sLifeTimeMgr;
+ SingletonData& sData(getData());
- if (data.mInitState != INITIALIZED)
+ switch (sData.mInitState)
{
- createInstance(data);
+ case UNINITIALIZED:
+ // should never be uninitialized at this point
+ llassert(false);
+ return NULL;
+ case CONSTRUCTING:
+ llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << LL_ENDL;
+ return NULL;
+ case INITIALIZING:
+ // go ahead and flag ourselves as initialized so we can be reentrant during initialization
+ sData.mInitState = INITIALIZED;
+ // initialize singleton after constructing it so that it can reference other singletons which in turn depend on it,
+ // thus breaking cyclic dependencies
+ sData.mInstance->initSingleton();
+ return sData.mInstance;
+ case INITIALIZED:
+ return sData.mInstance;
+ case DELETED:
+ llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << LL_ENDL;
+ SingletonLifetimeManager::construct();
+ // same as first time construction
+ sData.mInitState = INITIALIZED;
+ sData.mInstance->initSingleton();
+ return sData.mInstance;
}
- return data.mSingletonInstance;
+ return NULL;
+ }
+
+ static DERIVED_TYPE* getIfExists()
+ {
+ SingletonData& sData(getData());
+ return sData.mInstance;
}
// Reference version of getInstance()
@@ -191,51 +223,34 @@ public:
{
return *getInstance();
}
-
+
// Has this singleton been created uet?
// Use this to avoid accessing singletons before the can safely be constructed
static bool instanceExists()
{
- return getData().mInitState == INITIALIZED;
+ SingletonData& sData(getData());
+ return sData.mInitState == INITIALIZED;
}
-
+
// Has this singleton already been deleted?
// Use this to avoid accessing singletons from a static object's destructor
static bool destroyed()
{
- return getData().mInitState == DELETED;
+ SingletonData& sData(getData());
+ return sData.mInitState == DELETED;
}
private:
- static void createInstance(SingletonInstanceData& data);
+
virtual void initSingleton() {}
+
+ struct SingletonData
+ {
+ // explicitly has a default constructor so that member variables are zero initialized in BSS
+ // and only changed by singleton logic, not constructor running during startup
+ EInitState mInitState;
+ DERIVED_TYPE* mInstance;
+ };
};
-// Moved this here cause it's too big to be inlined --Aleric.
-template
-void LLSingleton::createInstance(SingletonInstanceData& data)
-{
- if (data.mInitState == CONSTRUCTING)
- {
- llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << llendl;
- }
-
- if (data.mInitState == DELETED)
- {
- llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
- }
-
- if (data.mInitState == INITIALIZING)
- {
- llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from initSingleton(), using half-initialized object" << llendl;
- return;
- }
-
- data.mInitState = CONSTRUCTING;
- data.mSingletonInstance = new DERIVED_TYPE();
- data.mInitState = INITIALIZING;
- data.mSingletonInstance->initSingleton();
- data.mInitState = INITIALIZED;
-}
-
#endif
diff --git a/indra/llcommon/llversionviewer.h.in b/indra/llcommon/llversionviewer.h.in
index 68949cee3..76d53b926 100644
--- a/indra/llcommon/llversionviewer.h.in
+++ b/indra/llcommon/llversionviewer.h.in
@@ -35,7 +35,7 @@
const S32 LL_VERSION_MAJOR = 1;
const S32 LL_VERSION_MINOR = 8;
-const S32 LL_VERSION_PATCH = 5;
+const S32 LL_VERSION_PATCH = 6;
const S32 LL_VERSION_BUILD = ${vBUILD};
const char * const LL_CHANNEL = "${VIEWER_CHANNEL}";
diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp
index 34f553ffc..294f68b12 100644
--- a/indra/llimage/llimagepng.cpp
+++ b/indra/llimage/llimagepng.cpp
@@ -122,53 +122,27 @@ BOOL LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time)
// Image logical size
setSize(raw_image->getWidth(), raw_image->getHeight(), raw_image->getComponents());
+ // Temporary buffer to hold the encoded image. Note: the final image
+ // size should be much smaller due to compression.
U32 bufferSize = getWidth() * getHeight() * getComponents() + 1024;
-
- //New implementation
- allocateData(bufferSize); //Set to largest possible size.
- if(isBufferInvalid()) //Checking
- {
- setLastError("LLImagePNG::encode failed allocateData");
- return FALSE;
- }
-
- // Delegate actual encoding work to wrapper
- LLPngWrapper pngWrapper;
- if (! pngWrapper.writePng(raw_image, getData()))
- {
- setLastError(pngWrapper.getErrorMessage());
- deleteData();
- return FALSE;
- }
-
- // Resize internal buffer.
- if(!reallocateData(pngWrapper.getFinalSize())) //Shrink. Returns NULL on failure.
- {
- setLastError("LLImagePNG::encode failed reallocateData");
- deleteData();
- return FALSE;
- }
- return TRUE;
-
-
- /*U8* mTmpWriteBuffer = new U8[ bufferSize ];
+ U8* tmpWriteBuffer = new U8[ bufferSize ];
// Delegate actual encoding work to wrapper
LLPngWrapper pngWrapper;
- if (! pngWrapper.writePng(raw_image, mTmpWriteBuffer))
+ if (! pngWrapper.writePng(raw_image, tmpWriteBuffer))
{
setLastError(pngWrapper.getErrorMessage());
- delete[] mTmpWriteBuffer;
+ delete[] tmpWriteBuffer;
return FALSE;
}
// Resize internal buffer and copy from temp
U32 encodedSize = pngWrapper.getFinalSize();
allocateData(encodedSize);
- memcpy(getData(), mTmpWriteBuffer, encodedSize);
+ memcpy(getData(), tmpWriteBuffer, encodedSize);
- delete[] mTmpWriteBuffer;
+ delete[] tmpWriteBuffer;
- return TRUE;*/
+ return TRUE;
}
diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp
index 0776e2ebd..d33aa94fd 100644
--- a/indra/llimage/llpngwrapper.cpp
+++ b/indra/llimage/llpngwrapper.cpp
@@ -252,6 +252,7 @@ void LLPngWrapper::normalizeImage()
// Read out the image meta-data
void LLPngWrapper::updateMetaData()
{
+ png_set_interlace_handling(mReadPngPtr); //
png_read_update_info(mReadPngPtr, mReadInfoPtr);
mWidth = png_get_image_width(mReadPngPtr, mReadInfoPtr);
mHeight = png_get_image_height(mReadPngPtr, mReadInfoPtr);
diff --git a/indra/llimage/llpngwrapper.h b/indra/llimage/llpngwrapper.h
index 5f3ad0d5a..397d316d0 100644
--- a/indra/llimage/llpngwrapper.h
+++ b/indra/llimage/llpngwrapper.h
@@ -26,7 +26,7 @@
#ifndef LL_LLPNGWRAPPER_H
#define LL_LLPNGWRAPPER_H
-#ifdef LL_STANDALONE
+#if LL_STANDALONE || (LL_LINUX && defined(__x86_64__))
#include
#else
// Workaround for wrongly packaged prebuilt.
diff --git a/indra/llmessage/aicurl.cpp b/indra/llmessage/aicurl.cpp
index 68328c394..06efd3cb4 100644
--- a/indra/llmessage/aicurl.cpp
+++ b/indra/llmessage/aicurl.cpp
@@ -366,7 +366,7 @@ void initCurl(void)
if (ssl_version.find("OpenSSL") != std::string::npos)
gSSLlib = ssl_openssl; // See http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
else if (ssl_version.find("GnuTLS") != std::string::npos)
- gSSLlib = ssl_gnutls; // See http://www.gnu.org/software/gnutls/manual/html_node/Thread-safety.html
+ gSSLlib = ssl_gnutls; // See http://www.gnutls.org/manual/html_node/Thread-safety.html#Thread-safety
else if (ssl_version.find("NSS") != std::string::npos)
gSSLlib = ssl_nss; // Supposedly thread-safe without any requirements.
@@ -387,10 +387,10 @@ void initCurl(void)
}
case ssl_gnutls:
{
- // I don't think we ever get here, do we? --Aleric
- llassert_always(gSSLlib != ssl_gnutls);
- // If we do, then didn't curl_global_init already call gnutls_global_init?
- // It seems there is nothing to do for us here.
+ // Prior to GnuTLS version 3.3.0 mutex locks are setup by calling gnutls_global_init,
+ // however curl_global_init already called that for us.
+ // There is nothing to do for us here.
+ break;
}
case ssl_nss:
{
@@ -527,7 +527,7 @@ namespace AICurlPrivate {
using AICurlInterface::Stats;
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
// CURLOPT_DEBUGFUNCTION function.
extern int debug_callback(CURL*, curl_infotype infotype, char* buf, size_t size, void* user_ptr);
#endif
@@ -1087,7 +1087,10 @@ void CurlEasyRequest::applyDefaultOptions(void)
{
CertificateAuthority_rat CertificateAuthority_r(gCertificateAuthority);
setoptString(CURLOPT_CAINFO, CertificateAuthority_r->file);
- setSSLCtxCallback(&curlCtxCallback, NULL);
+ if (gSSLlib == ssl_openssl)
+ {
+ setSSLCtxCallback(&curlCtxCallback, NULL);
+ }
setopt(CURLOPT_NOSIGNAL, 1);
// Cache DNS look ups an hour. If we set it smaller we risk frequent connect timeouts in cases where DNS look ups are slow.
setopt(CURLOPT_DNS_CACHE_TIMEOUT, 3600);
@@ -1181,7 +1184,7 @@ void CurlEasyRequest::set_timeout_opts(void)
void CurlEasyRequest::create_timeout_object(void)
{
ThreadSafeBufferedCurlEasyRequest* lockobj = NULL;
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
lockobj = static_cast(this)->get_lockobj();
#endif
mTimeout = new curlthread::HTTPTimeout(mTimeoutPolicy, lockobj);
@@ -1352,7 +1355,7 @@ void BufferedCurlEasyRequest::aborted(U32 http_status, std::string const& reason
}
}
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
static AIPerServicePtr sConnections[64];
void BufferedCurlEasyRequest::connection_established(int connectionnr)
@@ -1510,7 +1513,7 @@ CurlMultiHandle::~CurlMultiHandle()
} // namespace AICurlPrivate
-#if LL_LINUX
+#if LL_LINUX && !defined(__x86_64__)
extern "C" {
// Keep linker happy.
diff --git a/indra/llmessage/aicurleasyrequeststatemachine.cpp b/indra/llmessage/aicurleasyrequeststatemachine.cpp
index 2642bb92c..6b7bcf654 100644
--- a/indra/llmessage/aicurleasyrequeststatemachine.cpp
+++ b/indra/llmessage/aicurleasyrequeststatemachine.cpp
@@ -250,7 +250,7 @@ void AICurlEasyRequestStateMachine::finish_impl(void)
}
AICurlEasyRequestStateMachine::AICurlEasyRequestStateMachine(CWD_ONLY(bool debug)) :
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
AIStateMachine(debug),
#endif
mTotalDelayTimeout(AIHTTPTimeoutPolicy::getDebugSettingsCurlTimeout().getTotalDelay())
diff --git a/indra/llmessage/aicurlprivate.h b/indra/llmessage/aicurlprivate.h
index 9af27a567..fe1ab864c 100644
--- a/indra/llmessage/aicurlprivate.h
+++ b/indra/llmessage/aicurlprivate.h
@@ -320,7 +320,7 @@ class CurlEasyRequest : public CurlEasyHandle {
LLPointer mTimeout;// Timeout administration object associated with last created CurlSocketInfo.
bool mTimeoutIsOrphan; // Set to true when mTimeout is not (yet) associated with a CurlSocketInfo.
bool mIsHttps; // Set if the url starts with "https:".
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
public:
bool mDebugIsHeadOrGetMethod;
#endif
@@ -342,7 +342,7 @@ class CurlEasyRequest : public CurlEasyHandle {
// This class may only be created as base class of BufferedCurlEasyRequest.
// Throws AICurlNoEasyHandle.
CurlEasyRequest(void) : mHeaders(NULL), mHandleEventsTarget(NULL), mContentLength(0), mResult(CURLE_FAILED_INIT), mTimeoutPolicy(NULL), mTimeoutIsOrphan(false)
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
, mDebugIsHeadOrGetMethod(false)
#endif
{ applyDefaultOptions(); }
@@ -475,7 +475,7 @@ class BufferedCurlEasyRequest : public CurlEasyRequest {
// Return true if any data was received.
bool received_data(void) const { return mTotalRawBytes > 0; }
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
// Connection accounting for debug purposes.
void connection_established(int connectionnr);
void connection_closed(int connectionnr);
diff --git a/indra/llmessage/aicurlthread.cpp b/indra/llmessage/aicurlthread.cpp
index b7057fe11..8bc56d6f0 100644
--- a/indra/llmessage/aicurlthread.cpp
+++ b/indra/llmessage/aicurlthread.cpp
@@ -730,7 +730,7 @@ bool MergeIterator::next(curl_socket_t& fd_out, int& ev_bitmask_out)
//-----------------------------------------------------------------------------
// CurlSocketInfo
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
#undef AI_CASE_RETURN
#define AI_CASE_RETURN(x) case x: return #x;
static char const* action_str(int action)
@@ -2373,7 +2373,7 @@ int BufferedCurlEasyRequest::curlProgressCallback(void* user_data, double dltota
return 0;
}
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
int debug_callback(CURL* handle, curl_infotype infotype, char* buf, size_t size, void* user_ptr)
{
BufferedCurlEasyRequest* request = (BufferedCurlEasyRequest*)user_ptr;
@@ -2441,7 +2441,6 @@ int debug_callback(CURL* handle, curl_infotype infotype, char* buf, size_t size,
}
#endif
-#ifdef CWDEBUG
using namespace ::libcwd;
std::ostringstream marker;
marker << (void*)request->get_lockobj() << ' ';
@@ -2450,14 +2449,6 @@ int debug_callback(CURL* handle, curl_infotype infotype, char* buf, size_t size,
if (!debug::channels::dc::curlio.is_on())
debug::channels::dc::curlio.on();
LibcwDoutScopeBegin(LIBCWD_DEBUGCHANNELS, libcw_do, dc::curlio|cond_nonewline_cf(infotype == CURLINFO_TEXT))
-#else
- if (infotype == CURLINFO_TEXT)
- {
- while (size > 0 && (buf[size - 1] == '\r' || buf[size - 1] == '\n'))
- --size;
- }
- LibcwDoutScopeBegin(LIBCWD_DEBUGCHANNELS, libcw_do, dc::curlio)
-#endif
switch (infotype)
{
case CURLINFO_TEXT:
@@ -2535,12 +2526,10 @@ int debug_callback(CURL* handle, curl_infotype infotype, char* buf, size_t size,
else
LibcwDoutStream << size << " bytes";
LibcwDoutScopeEnd;
-#ifdef CWDEBUG
libcw_do.pop_marker();
-#endif
return 0;
}
-#endif // defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#endif // CWDEBUG
} // namespace AICurlPrivate
diff --git a/indra/llmessage/aihttptimeout.cpp b/indra/llmessage/aihttptimeout.cpp
index f79e2a450..c41dc6575 100644
--- a/indra/llmessage/aihttptimeout.cpp
+++ b/indra/llmessage/aihttptimeout.cpp
@@ -86,7 +86,7 @@ public:
#include "aihttptimeout.h"
// If this is set, treat dc::curlio as off in the assertion below.
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
bool gCurlIo;
#endif
@@ -180,7 +180,7 @@ void HTTPTimeout::upload_finished(void)
// ^ ^ ^ ^ ^ ^ ^ ^
// | | | | | | | |
bool HTTPTimeout::data_received(size_t n/*,*/
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
ASSERT_ONLY_COMMA(bool upload_error_status)
#else
ASSERT_ONLY_COMMA(bool)
diff --git a/indra/llmessage/aihttptimeout.h b/indra/llmessage/aihttptimeout.h
index 1af96c9c7..9d894d16b 100644
--- a/indra/llmessage/aihttptimeout.h
+++ b/indra/llmessage/aihttptimeout.h
@@ -91,14 +91,14 @@ class HTTPTimeout : public LLRefCount {
static F64 const sClockWidth_10ms; // Time between two clock ticks in 10 ms units.
static F64 const sClockWidth_40ms; // Time between two clock ticks in 40 ms units.
static U64 sTime_10ms; // Time since the epoch in 10 ms units.
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
ThreadSafeBufferedCurlEasyRequest* mLockObj;
#endif
public:
HTTPTimeout(AIHTTPTimeoutPolicy const* policy, ThreadSafeBufferedCurlEasyRequest* lock_obj) :
mPolicy(policy), mNothingReceivedYet(true), mLowSpeedOn(false), mLastBytesSent(false), mBeingRedirected(false), mUploadFinished(false), mStalled((U64)-1)
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
, mLockObj(lock_obj)
#endif
{ }
@@ -127,7 +127,7 @@ class HTTPTimeout : public LLRefCount {
// Called from BufferedCurlEasyRequest::processOutput if a timeout occurred.
void print_diagnostics(CurlEasyRequest const* curl_easy_request, char const* eff_url);
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
void* get_lockobj(void) const { return mLockObj; }
#endif
@@ -146,7 +146,7 @@ class HTTPTimeout : public LLRefCount {
} // namespace curlthread
} // namespace AICurlPrivate
-#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
+#ifdef CWDEBUG
extern bool gCurlIo;
#endif
diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp
index a37a9f916..fbd143c30 100644
--- a/indra/llmessage/aihttptimeoutpolicy.cpp
+++ b/indra/llmessage/aihttptimeoutpolicy.cpp
@@ -905,28 +905,18 @@ AIHTTPTimeoutPolicy const* AIHTTPTimeoutPolicy::getTimeoutPolicyByName(std::stri
#define P2(n, b) AIHTTPTimeoutPolicy n##_timeout(#n, b)
// Policy name Policy
-//P(accountingCostResponder);
-P(agentStateResponder);
-P(appearanceChangeMetricsResponder);
-P(assetUploadResponder);
P(assetReportHandler);
-P(asyncConsoleResponder);
-P(avatarPickerResponder);
P(authHandler);
P(avatarNameResponder);
P2(baseCapabilitiesComplete, transfer_18s_connect_5s);
P(blockingLLSDPost);
P(blockingLLSDGet);
P(blockingRawGet);
-P(charactersResponder);
-P(checkAgentAppearanceServiceResponder);
P(classifiedStatsResponder);
-P(consoleResponder);
P(createInventoryCategoryResponder);
P(emeraldDicDownloader);
P(environmentApplyResponder);
P(environmentRequestResponder);
-P(estateChangeInfoResponder);
P2(eventPollResponder, reply_60s);
P(fetchInventoryResponder);
P(fetchScriptLimitsAttachmentInfoResponder);
@@ -960,12 +950,7 @@ P2(meshPhysicsShapeResponder, connect_30s);
P2(meshSkinInfoResponder, connect_30s);
P(mimeDiscoveryResponder);
P(moderationResponder);
-P(navMeshRebakeResponder);
-P(navMeshResponder);
-P(navMeshStatusResponder);
-P(newAgentInventoryVariablePriceResponder);
P(objectCostResponder);
-P(objectLinksetsResponder);
P(physicsFlagsResponder);
P(productInfoRequestResponder);
P(regionResponder);
@@ -977,7 +962,6 @@ P(setDisplayNameResponder);
P2(simulatorFeaturesReceived, transfer_22s_connect_10s);
P(startConferenceChatResponder);
P2(startGroupVoteResponder, transfer_300s);
-P(terrainLinksetsResponder);
P(translationReceiver);
P(uploadModelPremissionsResponder);
P(userReportResponder);
diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp
index c592fccfb..544966479 100644
--- a/indra/llui/llradiogroup.cpp
+++ b/indra/llui/llradiogroup.cpp
@@ -46,16 +46,36 @@
static LLRegisterWidget r("radio_group");
+/*
+ * A checkbox control with use_radio_style == true.
+ */
+class LLRadioCtrl : public LLCheckBoxCtrl
+{
+public:
+ LLRadioCtrl(const std::string& name, const LLRect& rect, const std::string& label, const std::string& value = "", const LLFontGL* font = NULL, commit_callback_t commit_callback = NULL);
+ /*virtual*/ ~LLRadioCtrl();
+
+ virtual LLXMLNodePtr getXML(bool save_children = true) const;
+ /*virtual*/ void setValue(const LLSD& value);
+
+ LLSD getPayload() { return mPayload; }
+protected:
+ friend class LLUICtrlFactory;
+
+ LLSD mPayload; // stores data that this item represents in the radio group
+};
+
LLRadioGroup::LLRadioGroup(const std::string& name, const LLRect& rect,
S32 initial_index, commit_callback_t commit_callback,
- BOOL border) :
+ bool border, bool allow_deselect) :
LLUICtrl(name, rect, TRUE, commit_callback, FOLLOWS_LEFT | FOLLOWS_TOP),
- mSelectedIndex(initial_index)
+ mSelectedIndex(initial_index),
+ mAllowDeselect(allow_deselect)
{
init(border);
}
-void LLRadioGroup::init(BOOL border)
+void LLRadioGroup::init(bool border)
{
if (border)
{
@@ -67,12 +87,19 @@ void LLRadioGroup::init(BOOL border)
}
-
-
LLRadioGroup::~LLRadioGroup()
{
}
+// virtual
+BOOL LLRadioGroup::postBuild()
+{
+ if (!mRadioButtons.empty())
+ {
+ mRadioButtons[0]->setTabStop(true);
+ }
+ return TRUE;
+}
// virtual
void LLRadioGroup::setEnabled(BOOL enabled)
@@ -133,16 +160,39 @@ void LLRadioGroup::setIndexEnabled(S32 index, BOOL enabled)
BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event)
{
- if (index < 0 || index >= (S32)mRadioButtons.size())
+ if ((S32)mRadioButtons.size() <= index )
{
return FALSE;
}
+ if (mSelectedIndex >= 0)
+ {
+ LLRadioCtrl* old_radio_item = mRadioButtons[mSelectedIndex];
+ old_radio_item->setTabStop(false);
+ old_radio_item->setValue( FALSE );
+ }
+ else
+ {
+ mRadioButtons[0]->setTabStop(false);
+ }
+
mSelectedIndex = index;
+ if (mSelectedIndex >= 0)
+ {
+ LLRadioCtrl* radio_item = mRadioButtons[mSelectedIndex];
+ radio_item->setTabStop(true);
+ radio_item->setValue( TRUE );
+
+ if (hasFocus())
+ {
+ radio_item->focusFirstItem(FALSE, FALSE);
+ }
+ }
+
if (!from_event)
{
- setControlValue(getSelectedIndex());
+ setControlValue(getValue());
}
return TRUE;
@@ -207,41 +257,23 @@ BOOL LLRadioGroup::handleKeyHere(KEY key, MASK mask)
return handled;
}
-void LLRadioGroup::draw()
+BOOL LLRadioGroup::handleMouseDown(S32 x, S32 y, MASK mask)
{
- S32 current_button = 0;
-
- BOOL take_focus = FALSE;
- if (gFocusMgr.childHasKeyboardFocus(this))
+ // grab focus preemptively, before child button takes mousecapture
+ //
+ if (hasTabStop())
{
- take_focus = TRUE;
+ focusFirstItem(FALSE, FALSE);
}
- for (button_list_t::iterator iter = mRadioButtons.begin();
- iter != mRadioButtons.end(); ++iter)
- {
- LLRadioCtrl* radio = *iter;
- BOOL selected = (current_button == mSelectedIndex);
- radio->setValue( selected );
- if (take_focus && selected && !gFocusMgr.childHasKeyboardFocus(radio))
- {
- // don't flash keyboard focus when navigating via keyboard
- BOOL DONT_FLASH = FALSE;
- radio->focusFirstItem(FALSE, DONT_FLASH);
- }
- current_button++;
- }
-
- LLView::draw();
+ return LLUICtrl::handleMouseDown(x, y, mask);
}
-
// When adding a button, we need to ensure that the radio
// group gets a message when the button is clicked.
-LLRadioCtrl* LLRadioGroup::addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font )
+LLRadioCtrl* LLRadioGroup::addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font, const std::string& payload)
{
- // Highlight will get fixed in draw method above
- LLRadioCtrl* radio = new LLRadioCtrl(name, rect, label, font, boost::bind(&LLRadioGroup::onClickButton, this, _1));
+ LLRadioCtrl* radio = new LLRadioCtrl(name, rect, label, payload, font, boost::bind(&LLRadioGroup::onClickButton, this, _1));
addChild(radio);
mRadioButtons.push_back(radio);
return radio;
@@ -252,7 +284,7 @@ LLRadioCtrl* LLRadioGroup::addRadioButton(const std::string& name, const std::st
void LLRadioGroup::onClickButton(LLUICtrl* ctrl)
{
- // llinfos << "LLRadioGroup::onClickButton" << llendl;
+ // LL_INFOS() << "LLRadioGroup::onClickButton" << LL_ENDL;
LLRadioCtrl* clicked_radio = dynamic_cast(ctrl);
if (!clicked_radio)
return;
@@ -263,9 +295,15 @@ void LLRadioGroup::onClickButton(LLUICtrl* ctrl)
LLRadioCtrl* radio = *iter;
if (radio == clicked_radio)
{
- // llinfos << "clicked button " << counter << llendl;
- setSelectedIndex(index);
- setControlValue(index);
+ if (index == mSelectedIndex && mAllowDeselect)
+ {
+ // don't select anything
+ setSelectedIndex(-1);
+ }
+ else
+ {
+ setSelectedIndex(index);
+ }
// BUG: Calls click callback even if button didn't actually change
onCommit();
@@ -281,13 +319,12 @@ void LLRadioGroup::onClickButton(LLUICtrl* ctrl)
void LLRadioGroup::setValue( const LLSD& value )
{
- std::string value_name = value.asString();
int idx = 0;
for (button_list_t::const_iterator iter = mRadioButtons.begin();
iter != mRadioButtons.end(); ++iter)
{
LLRadioCtrl* radio = *iter;
- if (radio->getName() == value_name)
+ if (radio->getPayload().asString() == value.asString())
{
setSelectedIndex(idx);
idx = -1;
@@ -304,8 +341,7 @@ void LLRadioGroup::setValue( const LLSD& value )
}
else
{
- llwarns << "LLRadioGroup::setValue: radio_item with name=\"" << value_name << "\" not found, radio_group values are set by radio_item name not value. Falling back on LLUICtrl::setValue." << llendl;
- LLUICtrl::setValue(value);
+ setSelectedIndex(-1, TRUE);
}
}
}
@@ -317,7 +353,7 @@ LLSD LLRadioGroup::getValue() const
for (button_list_t::const_iterator iter = mRadioButtons.begin();
iter != mRadioButtons.end(); ++iter)
{
- if (idx == index) return LLSD((*iter)->getName());
+ if (idx == index) return LLSD((*iter)->getPayload());
++idx;
}
return LLSD();
@@ -333,6 +369,7 @@ LLXMLNodePtr LLRadioGroup::getXML(bool save_children) const
// Attributes
node->createChild("draw_border", TRUE)->setBoolValue(mHasBorder);
+ node->createChild("allow_deselect", TRUE)->setBoolValue(mAllowDeselect);
// Contents
@@ -355,17 +392,21 @@ LLView* LLRadioGroup::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
U32 initial_value = 0;
node->getAttributeU32("initial_value", initial_value);
- BOOL draw_border = TRUE;
- node->getAttributeBOOL("draw_border", draw_border);
+ bool draw_border = true;
+ node->getAttribute_bool("draw_border", draw_border);
+
+ bool allow_deselect = false;
+ node->getAttribute_bool("allow_deselect", allow_deselect);
LLRect rect;
createRect(node, rect, parent, LLRect());
- LLRadioGroup* radio_group = new LLRadioGroup("radio_group",
+ LLRadioGroup* radio_group = new LLRadioGroup("radio_group",
rect,
initial_value,
NULL,
- draw_border);
+ draw_border,
+ allow_deselect);
const std::string& contents = node->getValue();
@@ -406,7 +447,13 @@ LLView* LLRadioGroup::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory
createRect(child, item_rect, radio_group, rect);
std::string item_label = child->getTextContents();
- LLRadioCtrl* radio = radio_group->addRadioButton("radio", item_label, item_rect, font);
+ child->getAttributeString("label", item_label);
+ std::string item_name("radio");
+ child->getAttributeString("name", item_name);
+ std::string payload(item_name); // Support old-style name as payload
+ child->getAttributeString("value", payload);
+ child->getAttributeString("initial_value", payload); // Synonym
+ LLRadioCtrl* radio = radio_group->addRadioButton(item_name, item_label, item_rect, font, payload);
radio->initFromXML(child, radio_group);
}
@@ -432,11 +479,10 @@ LLUUID LLRadioGroup::getCurrentID() const
BOOL LLRadioGroup::setSelectedByValue(const LLSD& value, BOOL selected)
{
S32 idx = 0;
- std::string value_string = value.asString();
for (button_list_t::const_iterator iter = mRadioButtons.begin();
iter != mRadioButtons.end(); ++iter)
{
- if((*iter)->getName() == value_string)
+ if((*iter)->getPayload().asString() == value.asString())
{
setSelectedIndex(idx);
return TRUE;
@@ -455,11 +501,10 @@ LLSD LLRadioGroup::getSelectedValue()
BOOL LLRadioGroup::isSelected(const LLSD& value) const
{
S32 idx = 0;
- std::string value_string = value.asString();
for (button_list_t::const_iterator iter = mRadioButtons.begin();
iter != mRadioButtons.end(); ++iter)
{
- if((*iter)->getName() == value_string)
+ if((*iter)->getPayload().asString() == value.asString())
{
if (idx == mSelectedIndex)
{
@@ -481,6 +526,17 @@ BOOL LLRadioGroup::operateOnAll(EOperation op)
return FALSE;
}
+LLRadioCtrl::LLRadioCtrl(const std::string& name, const LLRect& rect, const std::string& label, const std::string& value, const LLFontGL* font, commit_callback_t commit_callback)
+: LLCheckBoxCtrl(name, rect, label, font, commit_callback, FALSE, RADIO_STYLE),
+ mPayload(value)
+{
+ setTabStop(FALSE);
+ // use name as default "Value" for backwards compatibility
+ if (value.empty())
+ {
+ mPayload = name;
+ }
+}
LLRadioCtrl::~LLRadioCtrl()
{
@@ -499,7 +555,7 @@ LLXMLNodePtr LLRadioCtrl::getXML(bool save_children) const
node->setName(LL_RADIO_ITEM_TAG);
- node->setStringValue(getLabel());
+ node->createChild("value", TRUE)->setStringValue(mPayload);
return node;
}
diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h
index 3cc042217..e21c7bc1f 100644
--- a/indra/llui/llradiogroup.h
+++ b/indra/llui/llradiogroup.h
@@ -37,26 +37,6 @@
#include "llcheckboxctrl.h"
#include "llctrlselectioninterface.h"
-
-/*
- * A checkbox control with use_radio_style == true.
- */
-class LLRadioCtrl : public LLCheckBoxCtrl
-{
-public:
- LLRadioCtrl(const std::string& name, const LLRect& rect, const std::string& label, const LLFontGL* font = NULL,
- commit_callback_t commit_callback = NULL) :
- LLCheckBoxCtrl(name, rect, label, font, commit_callback, FALSE, RADIO_STYLE)
- {
- setTabStop(FALSE);
- }
- /*virtual*/ ~LLRadioCtrl();
-
- virtual LLXMLNodePtr getXML(bool save_children = true) const;
- /*virtual*/ void setValue(const LLSD& value);
-};
-
-
/*
* An invisible view containing multiple mutually exclusive toggling
* buttons (usually radio buttons). Automatically handles the mutex
@@ -66,25 +46,32 @@ class LLRadioGroup
: public LLUICtrl, public LLCtrlSelectionInterface
{
public:
- // Radio group constructor. Doesn't rely on
- // needing a control
+
+ // Radio group constructor. Doesn't rely on needing a control
LLRadioGroup(const std::string& name, const LLRect& rect,
S32 initial_index,
commit_callback_t commit_callback,
- BOOL border = TRUE);
+ bool border = true, bool allow_deselect = false);
+
+protected:
+ friend class LLUICtrlFactory;
+
+public:
virtual ~LLRadioGroup();
+ virtual BOOL postBuild();
+
+ virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+
virtual BOOL handleKeyHere(KEY key, MASK mask);
virtual void setEnabled(BOOL enabled);
virtual LLXMLNodePtr getXML(bool save_children = true) const;
static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
void setIndexEnabled(S32 index, BOOL enabled);
-
// return the index value of the selected item
S32 getSelectedIndex() const { return mSelectedIndex; }
-
// set the index value programatically
BOOL setSelectedIndex(S32 index, BOOL from_event = FALSE);
@@ -92,14 +79,10 @@ public:
virtual void setValue(const LLSD& value );
virtual LLSD getValue() const;
- // Draw the group, but also fix the highlighting based on the control.
- void draw();
-
// You must use this method to add buttons to a radio group.
// Don't use addChild -- it won't set the callback function
// correctly.
- LLRadioCtrl* addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font);
- LLRadioCtrl* getRadioButton(const S32& index) { return mRadioButtons[index]; }
+ class LLRadioCtrl* addRadioButton(const std::string& name, const std::string& label, const LLRect& rect, const LLFontGL* font, const std::string& payload = "");
// Update the control as needed. Userdata must be a pointer to the button.
void onClickButton(LLUICtrl* clicked_radio);
@@ -123,14 +106,15 @@ public:
private:
// protected function shared by the two constructors.
- void init(BOOL border);
+ void init(bool border);
S32 mSelectedIndex;
- typedef std::vector button_list_t;
+
+ typedef std::vector button_list_t;
button_list_t mRadioButtons;
- BOOL mHasBorder;
+ bool mHasBorder;
+ bool mAllowDeselect; // user can click on an already selected option to deselect it
};
-
#endif
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index 114dc0c47..b6ba5e308 100644
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -150,7 +150,7 @@ LLDir_Mac::LLDir_Mac()
CFURLRef resourcesURLRef = CFBundleCopyResourcesDirectoryURL(mainBundleRef);
CFURLRefToLLString(resourcesURLRef, mAppRODataDir, true);
- U32 build_dir_pos = mExecutableDir.rfind("/indra/build-darwin-");
+ size_t build_dir_pos = mExecutableDir.rfind("/indra/build-darwin-");
if (build_dir_pos != std::string::npos)
{
// ...we're in a dev checkout
diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h
index 80ac3acfc..c2def259b 100644
--- a/indra/llwindow/llkeyboard.h
+++ b/indra/llwindow/llkeyboard.h
@@ -28,6 +28,7 @@
#define LL_LLKEYBOARD_H
#include
+ LiruHighlightNewInventory
+
LiruLegacyDisplayMuteds
LiruLegacyLandmarks
+ LiruResizeRootWithScreen
+
LiruLegacyScrollToEnd
Value
0
+ ContextConeInAlpha
+
+ ContextConeOutAlpha
+
+ ContextConeFadeTime
+
CookiesEnabled
+ RadarAlertShowDist
+
RadarAlertSim
+ VivoxShutdownTimeout
+
+ VivoxLogDirectory
+
VivoxDebugSIPURIHostName
+ IMNameSystem
+
LandManagementNameSystem
+ AlchemyRainbowEffects
+
AlchemyRegionRestartShake
+ ToolbarVisibleQuit
+
ToolbarVisibleRadar
- AscentInstantMessageResponseRepeat
-
-
- AscentInstantMessageShowOnTyping
-
-
+ AscentInstantMessageResponseRepeat
+
AutoresponseAnyone
+
BusyModeResponseItemID