Merge branch 'master' of https://vcs.firestormviewer.org/phoenix-firestorm
commit
7458601374
|
|
@ -106,3 +106,5 @@ my_autobuild.xml
|
|||
*.srctrlprj
|
||||
|
||||
compile_commands.json
|
||||
# ignore tracy for now
|
||||
indra/tracy
|
||||
|
|
@ -448,9 +448,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>322dd6c45c384d454ae14ef127984a4e</string>
|
||||
<string>ae90d19cdcddf539f6d0b41cab12f918</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65457/612879/bugsplat-1.0.7.546418-darwin64-546418.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72773/702861/bugsplat-1.0.7.552580-darwin64-552580.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -460,9 +460,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>010a0e73c0fddaa2316411803fad8e69</string>
|
||||
<string>f5936eceb6a33ff0f1cc31996a40f29c</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65456/612876/bugsplat-3.6.0.8.546418-windows-546418.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72774/702905/bugsplat-3.6.0.8.552580-windows-552580.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -472,16 +472,16 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>7e8530762e7b50663708a888c23b8780</string>
|
||||
<string>9cd940754e53e0670030b3da5ba8f373</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65455/612874/bugsplat-3.6.0.8.546418-windows64-546418.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72775/702906/bugsplat-3.6.0.8.552580-windows64-552580.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>3.6.0.8.546418</string>
|
||||
<string>3.6.0.8.552580</string>
|
||||
</map>
|
||||
<key>colladadom</key>
|
||||
<map>
|
||||
|
|
@ -2375,18 +2375,18 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>9f4687d7d328b0c13a9e651e805e880a</string>
|
||||
<string>c541838a933e0714a954e9ef6c89345d</string>
|
||||
<key>hash_algorithm</key>
|
||||
<string>md5</string>
|
||||
<key>url</key>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/71501/691487/llca-202011010215.551526-common-551526.tar.bz2</string>
|
||||
<string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/73387/708088/llca-202012011600.553112-common-553112.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>common</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>202011010215.551526</string>
|
||||
<string>202012011600.553112</string>
|
||||
</map>
|
||||
<key>llphysicsextensions_source</key>
|
||||
<map>
|
||||
|
|
|
|||
2
build.sh
2
build.sh
|
|
@ -477,10 +477,12 @@ then
|
|||
fi
|
||||
|
||||
# Run upload extensions
|
||||
# Ex: bugsplat
|
||||
if [ -d ${build_dir}/packages/upload-extensions ]; then
|
||||
for extension in ${build_dir}/packages/upload-extensions/*.sh; do
|
||||
begin_section "Upload Extension $extension"
|
||||
. $extension
|
||||
[ $? -eq 0 ] || fatal "Upload of extension $extension failed"
|
||||
end_section "Upload Extension $extension"
|
||||
done
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -171,10 +171,9 @@ LLAvatarAppearance::LLAvatarXmlInfo::~LLAvatarXmlInfo()
|
|||
//-----------------------------------------------------------------------------
|
||||
// Static Data
|
||||
//-----------------------------------------------------------------------------
|
||||
LLXmlTree LLAvatarAppearance::sXMLTree;
|
||||
LLXmlTree LLAvatarAppearance::sSkeletonXMLTree;
|
||||
LLAvatarSkeletonInfo* LLAvatarAppearance::sAvatarSkeletonInfo = NULL;
|
||||
LLAvatarAppearance::LLAvatarXmlInfo* LLAvatarAppearance::sAvatarXmlInfo = NULL;
|
||||
LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary* LLAvatarAppearance::sAvatarDictionary = NULL;
|
||||
|
||||
|
||||
LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :
|
||||
|
|
@ -202,7 +201,7 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :
|
|||
mBakedTextureDatas[i].mIsLoaded = false;
|
||||
mBakedTextureDatas[i].mIsUsed = false;
|
||||
mBakedTextureDatas[i].mMaskTexName = 0;
|
||||
mBakedTextureDatas[i].mTextureIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i);
|
||||
mBakedTextureDatas[i].mTextureIndex = sAvatarDictionary->bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -215,8 +214,8 @@ void LLAvatarAppearance::initInstance()
|
|||
mRoot = createAvatarJoint();
|
||||
mRoot->setName( "mRoot" );
|
||||
|
||||
for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
|
||||
iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
|
||||
for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = sAvatarDictionary->getMeshEntries().begin();
|
||||
iter != sAvatarDictionary->getMeshEntries().end();
|
||||
++iter)
|
||||
{
|
||||
const EMeshIndex mesh_index = iter->first;
|
||||
|
|
@ -261,8 +260,8 @@ void LLAvatarAppearance::initInstance()
|
|||
//-------------------------------------------------------------------------
|
||||
// associate baked textures with meshes
|
||||
//-------------------------------------------------------------------------
|
||||
for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
|
||||
iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
|
||||
for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = sAvatarDictionary->getMeshEntries().begin();
|
||||
iter != sAvatarDictionary->getMeshEntries().end();
|
||||
++iter)
|
||||
{
|
||||
const EMeshIndex mesh_index = iter->first;
|
||||
|
|
@ -346,6 +345,12 @@ void LLAvatarAppearance::initClass()
|
|||
//static
|
||||
void LLAvatarAppearance::initClass(const std::string& avatar_file_name_arg, const std::string& skeleton_file_name_arg)
|
||||
{
|
||||
// init dictionary (don't repeat on second login attempt)
|
||||
if (!sAvatarDictionary)
|
||||
{
|
||||
sAvatarDictionary = new LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary();
|
||||
}
|
||||
|
||||
std::string avatar_file_name;
|
||||
|
||||
if (!avatar_file_name_arg.empty())
|
||||
|
|
@ -356,14 +361,15 @@ void LLAvatarAppearance::initClass(const std::string& avatar_file_name_arg, cons
|
|||
{
|
||||
avatar_file_name = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR + "_lad.xml");
|
||||
}
|
||||
BOOL success = sXMLTree.parseFile( avatar_file_name, FALSE );
|
||||
LLXmlTree xml_tree;
|
||||
BOOL success = xml_tree.parseFile( avatar_file_name, FALSE );
|
||||
if (!success)
|
||||
{
|
||||
LL_ERRS() << "Problem reading avatar configuration file:" << avatar_file_name << LL_ENDL;
|
||||
}
|
||||
|
||||
// now sanity check xml file
|
||||
LLXmlTreeNode* root = sXMLTree.getRoot();
|
||||
LLXmlTreeNode* root = xml_tree.getRoot();
|
||||
if (!root)
|
||||
{
|
||||
LL_ERRS() << "No root node found in avatar configuration file: " << avatar_file_name << LL_ENDL;
|
||||
|
|
@ -410,8 +416,9 @@ void LLAvatarAppearance::initClass(const std::string& avatar_file_name_arg, cons
|
|||
}
|
||||
|
||||
std::string skeleton_path;
|
||||
LLXmlTree skeleton_xml_tree;
|
||||
skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name);
|
||||
if (!parseSkeletonFile(skeleton_path))
|
||||
if (!parseSkeletonFile(skeleton_path, skeleton_xml_tree))
|
||||
{
|
||||
LL_ERRS() << "Error parsing skeleton file: " << skeleton_path << LL_ENDL;
|
||||
}
|
||||
|
|
@ -424,7 +431,7 @@ void LLAvatarAppearance::initClass(const std::string& avatar_file_name_arg, cons
|
|||
delete sAvatarSkeletonInfo;
|
||||
}
|
||||
sAvatarSkeletonInfo = new LLAvatarSkeletonInfo;
|
||||
if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))
|
||||
if (!sAvatarSkeletonInfo->parseXml(skeleton_xml_tree.getRoot()))
|
||||
{
|
||||
LL_ERRS() << "Error parsing skeleton XML file: " << skeleton_path << LL_ENDL;
|
||||
}
|
||||
|
|
@ -463,9 +470,8 @@ void LLAvatarAppearance::initClass(const std::string& avatar_file_name_arg, cons
|
|||
void LLAvatarAppearance::cleanupClass()
|
||||
{
|
||||
delete_and_clear(sAvatarXmlInfo);
|
||||
// *TODO: What about sAvatarSkeletonInfo ???
|
||||
sSkeletonXMLTree.cleanup();
|
||||
sXMLTree.cleanup();
|
||||
delete_and_clear(sAvatarDictionary);
|
||||
delete_and_clear(sAvatarSkeletonInfo);
|
||||
}
|
||||
|
||||
using namespace LLAvatarAppearanceDefines;
|
||||
|
|
@ -598,12 +604,12 @@ F32 LLAvatarAppearance::getAvatarOffset() /*const*/
|
|||
//-----------------------------------------------------------------------------
|
||||
// parseSkeletonFile()
|
||||
//-----------------------------------------------------------------------------
|
||||
BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename)
|
||||
BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename, LLXmlTree& skeleton_xml_tree)
|
||||
{
|
||||
//-------------------------------------------------------------------------
|
||||
// parse the file
|
||||
//-------------------------------------------------------------------------
|
||||
BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE );
|
||||
BOOL parsesuccess = skeleton_xml_tree.parseFile( filename, FALSE );
|
||||
|
||||
if (!parsesuccess)
|
||||
{
|
||||
|
|
@ -612,7 +618,7 @@ BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename)
|
|||
}
|
||||
|
||||
// now sanity check xml file
|
||||
LLXmlTreeNode* root = sSkeletonXMLTree.getRoot();
|
||||
LLXmlTreeNode* root = skeleton_xml_tree.getRoot();
|
||||
if (!root)
|
||||
{
|
||||
LL_ERRS() << "No root node found in avatar skeleton file: " << filename << LL_ENDL;
|
||||
|
|
@ -1021,7 +1027,7 @@ BOOL LLAvatarAppearance::loadAvatar()
|
|||
{
|
||||
LLAvatarXmlInfo::LLAvatarMorphInfo *info = *iter;
|
||||
|
||||
EBakedTextureIndex baked = LLAvatarAppearanceDictionary::findBakedByRegionName(info->mRegion);
|
||||
EBakedTextureIndex baked = sAvatarDictionary->findBakedByRegionName(info->mRegion);
|
||||
if (baked != BAKED_NUM_INDICES)
|
||||
{
|
||||
LLVisualParam* morph_param;
|
||||
|
|
@ -1157,8 +1163,8 @@ BOOL LLAvatarAppearance::loadMeshNodes()
|
|||
switch(lod)
|
||||
case 0:
|
||||
mesh = &mHairMesh0; */
|
||||
for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator mesh_iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
|
||||
mesh_iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
|
||||
for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator mesh_iter = sAvatarDictionary->getMeshEntries().begin();
|
||||
mesh_iter != sAvatarDictionary->getMeshEntries().end();
|
||||
++mesh_iter)
|
||||
{
|
||||
const EMeshIndex mesh_index = mesh_iter->first;
|
||||
|
|
@ -1286,8 +1292,8 @@ BOOL LLAvatarAppearance::loadLayersets()
|
|||
|
||||
// scan baked textures and associate the layerset with the appropriate one
|
||||
EBakedTextureIndex baked_index = BAKED_NUM_INDICES;
|
||||
for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
|
||||
baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
|
||||
for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = sAvatarDictionary->getBakedTextures().begin();
|
||||
baked_iter != sAvatarDictionary->getBakedTextures().end();
|
||||
++baked_iter)
|
||||
{
|
||||
const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ public:
|
|||
|
||||
|
||||
protected:
|
||||
static BOOL parseSkeletonFile(const std::string& filename);
|
||||
static BOOL parseSkeletonFile(const std::string& filename, LLXmlTree& skeleton_xml_tree);
|
||||
virtual void buildCharacter();
|
||||
virtual BOOL loadAvatar();
|
||||
// [RLVa:KB] - Checked: 2013-03-03 (RLVa-1.4.8)
|
||||
|
|
@ -222,9 +222,6 @@ public:
|
|||
// XML parse tree
|
||||
//--------------------------------------------------------------------
|
||||
protected:
|
||||
static LLXmlTree sXMLTree; // avatar config file
|
||||
static LLXmlTree sSkeletonXMLTree; // avatar skeleton file
|
||||
|
||||
static LLAvatarSkeletonInfo* sAvatarSkeletonInfo;
|
||||
static LLAvatarXmlInfo* sAvatarXmlInfo;
|
||||
|
||||
|
|
@ -272,6 +269,7 @@ public:
|
|||
public:
|
||||
virtual void updateMeshTextures() = 0;
|
||||
virtual void dirtyMesh() = 0; // Dirty the avatar mesh
|
||||
static const LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary *getDictionary() { return sAvatarDictionary; }
|
||||
protected:
|
||||
virtual void dirtyMesh(S32 priority) = 0; // Dirty the avatar mesh, with priority
|
||||
|
||||
|
|
@ -280,6 +278,9 @@ protected:
|
|||
polymesh_map_t mPolyMeshes;
|
||||
avatar_joint_list_t mMeshLOD;
|
||||
|
||||
// mesh entries and backed textures
|
||||
static LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary* sAvatarDictionary;
|
||||
|
||||
/** Meshes
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
|
|
|||
|
|
@ -260,19 +260,17 @@ LLAvatarAppearanceDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index,
|
|||
va_end( argp ); // <FS:ND/> Needs to be freed when done.
|
||||
}
|
||||
|
||||
// static
|
||||
ETextureIndex LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index)
|
||||
ETextureIndex LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index) const
|
||||
{
|
||||
return LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
|
||||
return getBakedTexture(index)->mTextureIndex;
|
||||
}
|
||||
|
||||
// static
|
||||
EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByRegionName(std::string name)
|
||||
{
|
||||
U8 index = 0;
|
||||
while (index < BAKED_NUM_INDICES)
|
||||
{
|
||||
const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
|
||||
const BakedEntry *be = getBakedTexture((EBakedTextureIndex) index);
|
||||
if (be && be->mName.compare(name) == 0)
|
||||
{
|
||||
// baked texture found
|
||||
|
|
@ -284,16 +282,15 @@ EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByRegionName(std::stri
|
|||
return BAKED_NUM_INDICES;
|
||||
}
|
||||
|
||||
// static
|
||||
EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::string name)
|
||||
{
|
||||
U8 index = 0;
|
||||
while (index < BAKED_NUM_INDICES)
|
||||
{
|
||||
const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
|
||||
const BakedEntry *be = getBakedTexture((EBakedTextureIndex) index);
|
||||
if (be)
|
||||
{
|
||||
const TextureEntry *te = LLAvatarAppearanceDictionary::getInstance()->getTexture(be->mTextureIndex);
|
||||
const TextureEntry *te = getTexture(be->mTextureIndex);
|
||||
if (te && te->mDefaultImageName.compare(name) == 0)
|
||||
{
|
||||
// baked texture found
|
||||
|
|
@ -306,10 +303,9 @@ EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::strin
|
|||
return BAKED_NUM_INDICES;
|
||||
}
|
||||
|
||||
// static
|
||||
LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index )
|
||||
LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index ) const
|
||||
{
|
||||
return getInstance()->getTexture(index)->mWearableType;
|
||||
return getTexture(index)->mWearableType;
|
||||
}
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -143,13 +143,14 @@ typedef std::vector<LLWearableType::EType> wearables_vec_t;
|
|||
//
|
||||
// This holds const data - it is initialized once and the contents never change after that.
|
||||
//------------------------------------------------------------------------
|
||||
class LLAvatarAppearanceDictionary : public LLSingleton<LLAvatarAppearanceDictionary>
|
||||
class LLAvatarAppearanceDictionary
|
||||
{
|
||||
//--------------------------------------------------------------------
|
||||
// Constructors and Destructors
|
||||
//--------------------------------------------------------------------
|
||||
LLSINGLETON(LLAvatarAppearanceDictionary);
|
||||
virtual ~LLAvatarAppearanceDictionary();
|
||||
public:
|
||||
LLAvatarAppearanceDictionary();
|
||||
~LLAvatarAppearanceDictionary();
|
||||
private:
|
||||
void createAssociations();
|
||||
|
||||
|
|
@ -235,14 +236,14 @@ public:
|
|||
//--------------------------------------------------------------------
|
||||
public:
|
||||
// Convert from baked texture to associated texture; e.g. BAKED_HEAD -> TEX_HEAD_BAKED
|
||||
static ETextureIndex bakedToLocalTextureIndex(EBakedTextureIndex t);
|
||||
ETextureIndex bakedToLocalTextureIndex(EBakedTextureIndex t) const;
|
||||
|
||||
// find a baked texture index based on its name
|
||||
static EBakedTextureIndex findBakedByRegionName(std::string name);
|
||||
static EBakedTextureIndex findBakedByImageName(std::string name);
|
||||
EBakedTextureIndex findBakedByRegionName(std::string name);
|
||||
EBakedTextureIndex findBakedByImageName(std::string name);
|
||||
|
||||
// Given a texture entry, determine which wearable type owns it.
|
||||
static LLWearableType::EType getTEWearableType(ETextureIndex index);
|
||||
LLWearableType::EType getTEWearableType(ETextureIndex index) const;
|
||||
|
||||
static BOOL isBakedImageId(const LLUUID& id);
|
||||
static EBakedTextureIndex assetIdToBakedTextureIndex(const LLUUID& id);
|
||||
|
|
|
|||
|
|
@ -735,8 +735,8 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
|
|||
/* if ("upper_shirt" == local_texture_name)
|
||||
mLocalTexture = TEX_UPPER_SHIRT; */
|
||||
mLocalTexture = TEX_NUM_INDICES;
|
||||
for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
|
||||
iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
|
||||
for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
|
||||
iter != LLAvatarAppearance::getDictionary()->getTextures().end();
|
||||
iter++)
|
||||
{
|
||||
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
|
||||
|
|
@ -986,7 +986,7 @@ LLWearableType::EType LLTexLayerInterface::getWearableType() const
|
|||
|
||||
return type;
|
||||
}
|
||||
return LLAvatarAppearanceDictionary::getTEWearableType(te);
|
||||
return LLAvatarAppearance::getDictionary()->getTEWearableType(te);
|
||||
}
|
||||
|
||||
LLTexLayerInterface::ERenderPass LLTexLayerInterface::getRenderPass() const
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ void LLWearable::createVisualParams(LLAvatarAppearance *avatarp)
|
|||
void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
|
||||
{
|
||||
LLTexLayerSet *layer_set = NULL;
|
||||
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
|
||||
const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)te);
|
||||
if (texture_dict && texture_dict->mIsUsedByBakedTexture)
|
||||
{
|
||||
const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
|
||||
|
|
@ -613,7 +613,7 @@ void LLWearable::syncImages(te_map_t &src, te_map_t &dst)
|
|||
// Deep copy of src (copies only those tes that are current, filling in defaults where needed)
|
||||
for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
|
||||
{
|
||||
if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
|
||||
if (LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex) te) == mType)
|
||||
{
|
||||
te_map_t::const_iterator iter = src.find(te);
|
||||
LLUUID image_id;
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ U32 LLWearableData::getWearableCount(const LLWearableType::EType type) const
|
|||
|
||||
U32 LLWearableData::getWearableCount(const U32 tex_index) const
|
||||
{
|
||||
const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((LLAvatarAppearanceDefines::ETextureIndex)tex_index);
|
||||
const LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((LLAvatarAppearanceDefines::ETextureIndex)tex_index);
|
||||
return getWearableCount(wearable_type);
|
||||
}
|
||||
|
||||
|
|
@ -360,7 +360,7 @@ LLUUID LLWearableData::computeBakedTextureHash(LLAvatarAppearanceDefines::EBaked
|
|||
LLUUID hash_id;
|
||||
bool hash_computed = false;
|
||||
LLMD5 hash;
|
||||
const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index);
|
||||
const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearance::getDictionary()->getBakedTexture(baked_index);
|
||||
|
||||
for (U8 i=0; i < baked_dict->mWearables.size(); i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -359,10 +359,11 @@ void LLThread::setQuitting()
|
|||
}
|
||||
|
||||
// static
|
||||
LLThread::id_t LLThread::currentID()
|
||||
{
|
||||
return std::this_thread::get_id();
|
||||
}
|
||||
// <FS:Beq> give this a better chance to inline
|
||||
// LLThread::id_t LLThread::currentID()
|
||||
// {
|
||||
// return std::this_thread::get_id();
|
||||
// }
|
||||
|
||||
// static
|
||||
void LLThread::yield()
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ public:
|
|||
bool isQuitting() const { return (QUITTING == mStatus); }
|
||||
bool isStopped() const { return (STOPPED == mStatus) || (CRASHED == mStatus); }
|
||||
bool isCrashed() const { return (CRASHED == mStatus); }
|
||||
|
||||
static id_t currentID(); // Return ID of current thread
|
||||
// <FS:Beq> Try to encourage the inlining
|
||||
static LL_FORCE_INLINE id_t currentID(){return std::this_thread::get_id();}; // Return ID of current thread
|
||||
static void yield(); // Static because it can be called by the main thread, which doesn't have an LLThread data structure.
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -577,16 +577,9 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
// Use the viewer-based thread-safe API which has a
|
||||
// fast/safe check for proxy enable. Would like to
|
||||
// encapsulate this someway...
|
||||
if (LLProxy::instanceExists())
|
||||
{
|
||||
// Make sure proxy won't be initialized from here,
|
||||
// it might conflict with LLStartUp::startLLProxy()
|
||||
LLProxy::getInstance()->applyProxySettings(mCurlHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Proxy is not initialized!" << LL_ENDL;
|
||||
}
|
||||
// Make sure proxy won't be getInstance() from here,
|
||||
// it is not thread safe
|
||||
LLProxy::applyProxySettings(mCurlHandle);
|
||||
|
||||
}
|
||||
else if (gpolicy.mHttpProxy.size())
|
||||
|
|
@ -827,6 +820,7 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void
|
|||
|
||||
const size_t do_size((std::min)(req_size, body_size - op->mCurlBodyPos));
|
||||
const size_t read_size(op->mReqBody->read(op->mCurlBodyPos, static_cast<char *>(data), do_size));
|
||||
// FIXME: singleton's instance() is Thread unsafe! Even if stats accumulators inside are.
|
||||
HTTPStats::instance().recordDataUp(read_size);
|
||||
op->mCurlBodyPos += read_size;
|
||||
return read_size;
|
||||
|
|
|
|||
|
|
@ -583,29 +583,39 @@ static void bilinear_scale(const U8 *src, U32 srcW, U32 srcH, U32 srcCh, U32 src
|
|||
// LLImage
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
LLImage::LLImage(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent)
|
||||
//static
|
||||
std::string LLImage::sLastErrorMessage;
|
||||
LLMutex* LLImage::sMutex = NULL;
|
||||
bool LLImage::sUseNewByteRange = false;
|
||||
S32 LLImage::sMinimalReverseByteRangePercent = 75;
|
||||
|
||||
//static
|
||||
void LLImage::initClass(bool use_new_byte_range, S32 minimal_reverse_byte_range_percent)
|
||||
{
|
||||
mMutex = new LLMutex();
|
||||
mUseNewByteRange = use_new_byte_range;
|
||||
mMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent;
|
||||
sUseNewByteRange = use_new_byte_range;
|
||||
sMinimalReverseByteRangePercent = minimal_reverse_byte_range_percent;
|
||||
sMutex = new LLMutex();
|
||||
}
|
||||
|
||||
LLImage::~LLImage()
|
||||
//static
|
||||
void LLImage::cleanupClass()
|
||||
{
|
||||
delete mMutex;
|
||||
mMutex = NULL;
|
||||
delete sMutex;
|
||||
sMutex = NULL;
|
||||
}
|
||||
|
||||
const std::string& LLImage::getLastErrorMessage()
|
||||
//static
|
||||
const std::string& LLImage::getLastError()
|
||||
{
|
||||
static const std::string noerr("No Error");
|
||||
return mLastErrorMessage.empty() ? noerr : mLastErrorMessage;
|
||||
return sLastErrorMessage.empty() ? noerr : sLastErrorMessage;
|
||||
}
|
||||
|
||||
void LLImage::setLastErrorMessage(const std::string& message)
|
||||
//static
|
||||
void LLImage::setLastError(const std::string& message)
|
||||
{
|
||||
LLMutexLock m(mMutex);
|
||||
mLastErrorMessage = message;
|
||||
LLMutexLock m(sMutex);
|
||||
sLastErrorMessage = message;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#include "lluuid.h"
|
||||
#include "llstring.h"
|
||||
#include "llpointer.h"
|
||||
#include "llsingleton.h"
|
||||
#include "lltrace.h"
|
||||
|
||||
const S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
|
||||
|
|
@ -88,26 +87,25 @@ typedef enum e_image_codec
|
|||
|
||||
//============================================================================
|
||||
// library initialization class
|
||||
// LLImage is frequently used in threads so do not convert it to LLSingleton
|
||||
|
||||
class LLImage : public LLParamSingleton<LLImage>
|
||||
class LLImage
|
||||
{
|
||||
LLSINGLETON(LLImage, bool use_new_byte_range = false, S32 minimal_reverse_byte_range_percent = 75);
|
||||
~LLImage();
|
||||
public:
|
||||
static void initClass(bool use_new_byte_range = false, S32 minimal_reverse_byte_range_percent = 75);
|
||||
static void cleanupClass();
|
||||
|
||||
const std::string& getLastErrorMessage();
|
||||
static const std::string& getLastError() { return getInstance()->getLastErrorMessage(); };
|
||||
void setLastErrorMessage(const std::string& message);
|
||||
static void setLastError(const std::string& message) { getInstance()->setLastErrorMessage(message); }
|
||||
|
||||
bool useNewByteRange() { return mUseNewByteRange; }
|
||||
S32 getReverseByteRangePercent() { return mMinimalReverseByteRangePercent; }
|
||||
|
||||
private:
|
||||
LLMutex* mMutex;
|
||||
std::string mLastErrorMessage;
|
||||
bool mUseNewByteRange;
|
||||
S32 mMinimalReverseByteRangePercent;
|
||||
static const std::string& getLastError();
|
||||
static void setLastError(const std::string& message);
|
||||
|
||||
static bool useNewByteRange() { return sUseNewByteRange; }
|
||||
static S32 getReverseByteRangePercent() { return sMinimalReverseByteRangePercent; }
|
||||
|
||||
protected:
|
||||
static LLMutex* sMutex;
|
||||
static std::string sLastErrorMessage;
|
||||
static bool sUseNewByteRange;
|
||||
static S32 sMinimalReverseByteRangePercent;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ S32 LLImageJ2C::calcDataSizeJ2C(S32 w, S32 h, S32 comp, S32 discard_level, F32 r
|
|||
S32 bytes;
|
||||
S32 new_bytes = (S32) (sqrt((F32)(w*h))*(F32)(comp)*rate*1000.f/layer_factor);
|
||||
S32 old_bytes = (S32)((F32)(w*h*comp)*rate);
|
||||
bytes = (LLImage::getInstance()->useNewByteRange() && (new_bytes < old_bytes) ? new_bytes : old_bytes);
|
||||
bytes = (LLImage::useNewByteRange() && (new_bytes < old_bytes) ? new_bytes : old_bytes);
|
||||
bytes = llmax(bytes, calcHeaderSizeJ2C());
|
||||
return bytes;
|
||||
}
|
||||
|
|
@ -322,7 +322,7 @@ S32 LLImageJ2C::calcDiscardLevelBytes(S32 bytes)
|
|||
{
|
||||
S32 bytes_needed = calcDataSize(discard_level);
|
||||
// Use TextureReverseByteRange percent (see settings.xml) of the optimal size to qualify as correct rendering for the given discard level
|
||||
if (bytes >= (bytes_needed*LLImage::getInstance()->getReverseByteRangePercent()/100))
|
||||
if (bytes >= (bytes_needed*LLImage::getReverseByteRangePercent()/100))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,12 +306,27 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName&
|
|||
return;
|
||||
}
|
||||
|
||||
bool updated_account = true; // assume obsolete value for new arrivals by default
|
||||
|
||||
std::map<LLUUID, LLAvatarName>::iterator it = mCache.find(agent_id);
|
||||
if (it != mCache.end()
|
||||
&& (*it).second.getAccountName() == av_name.getAccountName())
|
||||
{
|
||||
updated_account = false;
|
||||
}
|
||||
|
||||
// Add to the cache
|
||||
mCache[agent_id] = av_name;
|
||||
|
||||
// Suppress request from the queue
|
||||
mPendingQueue.erase(agent_id);
|
||||
|
||||
// notify mute list about changes
|
||||
if (updated_account && mAccountNameChangedCallback)
|
||||
{
|
||||
mAccountNameChangedCallback(agent_id, av_name);
|
||||
}
|
||||
|
||||
// Signal everyone waiting on this name
|
||||
signal_map_t::iterator sig_it = mSignalMap.find(agent_id);
|
||||
if (sig_it != mSignalMap.end())
|
||||
|
|
@ -324,6 +339,8 @@ void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName&
|
|||
delete signal;
|
||||
signal = NULL;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void LLAvatarNameCache::requestNamesViaCapability()
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ class LLAvatarNameCache : public LLSingleton<LLAvatarNameCache>
|
|||
~LLAvatarNameCache();
|
||||
public:
|
||||
typedef boost::signals2::signal<void (void)> use_display_name_signal_t;
|
||||
typedef boost::function<void (const LLUUID id, const LLAvatarName& av_name)> account_name_changed_callback_t;
|
||||
|
||||
// Import/export the name cache to file.
|
||||
bool importFile(std::istream& istr);
|
||||
|
|
@ -113,6 +114,8 @@ public:
|
|||
|
||||
void addUseDisplayNamesCallback(const use_display_name_signal_t::slot_type& cb);
|
||||
|
||||
void setAccountNameChangedCallback(const account_name_changed_callback_t& cb) { mAccountNameChangedCallback = cb; }
|
||||
|
||||
// <FS:Ansariel> FIRE-6659: Legacy "Resident" name toggle
|
||||
void clearCache();
|
||||
|
||||
|
|
@ -154,6 +157,7 @@ private:
|
|||
private:
|
||||
|
||||
use_display_name_signal_t mUseDisplayNamesSignal;
|
||||
account_name_changed_callback_t mAccountNameChangedCallback;
|
||||
|
||||
// Cache starts in a paused state until we can determine if the
|
||||
// current region supports display names.
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpd
|
|||
// workaround until we get mutex into initializePool
|
||||
initializePool("AssetStorage");
|
||||
initializePool("Upload");
|
||||
initializePool("ExpCache"); // <FS:Ansariel> FIRE-30731: ExpCache coroutine pool crash
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
// incoming packet just to do a simple bool test. The getter for this
|
||||
// member is also static
|
||||
bool LLProxy::sUDPProxyEnabled = false;
|
||||
LLProxy* LLProxy::sProxyInstance = NULL;
|
||||
|
||||
// Some helpful TCP static functions.
|
||||
static apr_status_t tcp_blocking_handshake(LLSocket::ptr_t handle, char * dataout, apr_size_t outlen, char * datain, apr_size_t maxinlen); // Do a TCP data handshake
|
||||
|
|
@ -60,11 +61,21 @@ LLProxy::LLProxy():
|
|||
|
||||
LLProxy::~LLProxy()
|
||||
{
|
||||
if (ll_apr_is_initialized())
|
||||
{
|
||||
stopSOCKSProxy();
|
||||
disableHTTPProxy();
|
||||
}
|
||||
if (ll_apr_is_initialized())
|
||||
{
|
||||
// locks mutex
|
||||
stopSOCKSProxy();
|
||||
disableHTTPProxy();
|
||||
}
|
||||
// The primary safety of sProxyInstance is the fact that by the
|
||||
// point SUBSYSTEM_CLEANUP(LLProxy) gets called, nothing should
|
||||
// be capable of using proxy
|
||||
sProxyInstance = NULL;
|
||||
}
|
||||
|
||||
void LLProxy::initSingleton()
|
||||
{
|
||||
sProxyInstance = this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -424,28 +435,28 @@ void LLProxy::cleanupClass()
|
|||
void LLProxy::applyProxySettings(CURL* handle)
|
||||
{
|
||||
// Do a faster unlocked check to see if we are supposed to proxy.
|
||||
if (mHTTPProxyEnabled)
|
||||
if (sProxyInstance && sProxyInstance->mHTTPProxyEnabled)
|
||||
{
|
||||
// We think we should proxy, lock the proxy mutex.
|
||||
LLMutexLock lock(&mProxyMutex);
|
||||
// We think we should proxy, lock the proxy mutex. sProxyInstance is not protected by mutex
|
||||
LLMutexLock lock(&sProxyInstance->mProxyMutex);
|
||||
// Now test again to verify that the proxy wasn't disabled between the first check and the lock.
|
||||
if (mHTTPProxyEnabled)
|
||||
if (sProxyInstance->mHTTPProxyEnabled)
|
||||
{
|
||||
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, mHTTPProxy.getIPString().c_str()), CURLOPT_PROXY);
|
||||
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, mHTTPProxy.getPort()), CURLOPT_PROXYPORT);
|
||||
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXY, sProxyInstance->mHTTPProxy.getIPString().c_str()), CURLOPT_PROXY);
|
||||
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYPORT, sProxyInstance->mHTTPProxy.getPort()), CURLOPT_PROXYPORT);
|
||||
|
||||
if (mProxyType == LLPROXY_SOCKS)
|
||||
if (sProxyInstance->mProxyType == LLPROXY_SOCKS)
|
||||
{
|
||||
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5), CURLOPT_PROXYTYPE);
|
||||
if (mAuthMethodSelected == METHOD_PASSWORD)
|
||||
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5), CURLOPT_PROXYTYPE);
|
||||
if (sProxyInstance->mAuthMethodSelected == METHOD_PASSWORD)
|
||||
{
|
||||
std::string auth_string = mSocksUsername + ":" + mSocksPassword;
|
||||
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()), CURLOPT_PROXYUSERPWD);
|
||||
std::string auth_string = sProxyInstance->mSocksUsername + ":" + sProxyInstance->mSocksPassword;
|
||||
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYUSERPWD, auth_string.c_str()), CURLOPT_PROXYUSERPWD);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP), CURLOPT_PROXYTYPE);
|
||||
LLCore::LLHttp::check_curl_code(curl_easy_setopt(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP), CURLOPT_PROXYTYPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -226,6 +226,8 @@ class LLProxy: public LLSingleton<LLProxy>
|
|||
LLSINGLETON(LLProxy);
|
||||
LOG_CLASS(LLProxy);
|
||||
|
||||
/*virtual*/ void initSingleton();
|
||||
|
||||
public:
|
||||
// Static check for enabled status for UDP packets. Call from main thread only.
|
||||
static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; }
|
||||
|
|
@ -251,7 +253,7 @@ public:
|
|||
|
||||
// Apply the current proxy settings to a curl request. Doesn't do anything if mHTTPProxyEnabled is false.
|
||||
// Safe to call from any thread.
|
||||
void applyProxySettings(CURL* handle);
|
||||
static void applyProxySettings(CURL* handle);
|
||||
// Start a connection to the SOCKS 5 proxy. Call from main thread only.
|
||||
S32 startSOCKSProxy(LLHost host);
|
||||
|
||||
|
|
@ -344,6 +346,10 @@ private:
|
|||
/*###########################################################################################
|
||||
END OF SHARED MEMBERS
|
||||
###########################################################################################*/
|
||||
|
||||
// A hack to get arround getInstance() and capture_dependency() which are unsafe to use inside threads
|
||||
// set/reset on init/cleanup, strictly for use in applyProxySettings
|
||||
static LLProxy* sProxyInstance;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -154,8 +154,18 @@ void LLPluginProcessParent::shutdown()
|
|||
mapInstances_t::iterator it;
|
||||
for (it = sInstances.begin(); it != sInstances.end(); ++it)
|
||||
{
|
||||
(*it).second->setState(STATE_GOODBYE);
|
||||
(*it).second->idle();
|
||||
EState state = (*it).second->mState;
|
||||
if (state != STATE_CLEANUP
|
||||
|| state != STATE_EXITING
|
||||
|| state != STATE_DONE
|
||||
|| state != STATE_ERROR)
|
||||
{
|
||||
(*it).second->setState(STATE_GOODBYE);
|
||||
}
|
||||
if (state != STATE_DONE)
|
||||
{
|
||||
(*it).second->idle();
|
||||
}
|
||||
}
|
||||
sInstances.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1535,7 +1535,8 @@ void LLDAELoader::processDomModel(LLModel* model, DAE* dae, daeElement* root, do
|
|||
std::string lookingForJoint = (*jointIt).c_str();
|
||||
//Look for the joint xform that we extracted from the skeleton, using the jointIt as the key
|
||||
//and store it in the alternate bind matrix
|
||||
if ( mJointMap.find( lookingForJoint ) != mJointMap.end() )
|
||||
if (mJointMap.find(lookingForJoint) != mJointMap.end()
|
||||
&& model->mSkinInfo.mInvBindMatrix.size() > i)
|
||||
{
|
||||
LLMatrix4 newInverse = model->mSkinInfo.mInvBindMatrix[i];
|
||||
newInverse.setTranslation( mJointList[lookingForJoint].getTranslation() );
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ bool font_desc_init_from_xml(LLXMLNodePtr node, LLFontDescriptor& desc);
|
|||
bool init_from_xml(LLFontRegistry* registry, LLXMLNodePtr node);
|
||||
|
||||
const std::string MACOSX_FONT_PATH_LIBRARY = "/Library/Fonts/";
|
||||
const std::string MACOSX_FONT_SUPPLEMENTAL = "Supplemental/";
|
||||
|
||||
LLFontDescriptor::LLFontDescriptor():
|
||||
mStyle(0)
|
||||
|
|
@ -512,6 +513,8 @@ LLFontGL *LLFontRegistry::createFont(const LLFontDescriptor& desc)
|
|||
font_paths.push_back(usr_path + *file_name_it);
|
||||
#if LL_DARWIN
|
||||
font_paths.push_back(MACOSX_FONT_PATH_LIBRARY + *file_name_it);
|
||||
font_paths.push_back(MACOSX_FONT_PATH_LIBRARY + MACOSX_FONT_SUPPLEMENTAL + *file_name_it);
|
||||
font_paths.push_back(sys_path + MACOSX_FONT_SUPPLEMENTAL + *file_name_it);
|
||||
#endif
|
||||
|
||||
bool is_ft_collection = (std::find(ft_collection_list.begin(), ft_collection_list.end(), *file_name_it) != ft_collection_list.end());
|
||||
|
|
|
|||
|
|
@ -970,6 +970,80 @@ std::string LLGLManager::getRawGLString()
|
|||
return gl_string;
|
||||
}
|
||||
|
||||
void LLGLManager::asLLSD(LLSD& info)
|
||||
{
|
||||
// Currently these are duplicates of fields in "system".
|
||||
info["gpu_vendor"] = mGLVendorShort;
|
||||
info["gpu_version"] = mDriverVersionVendorString;
|
||||
info["opengl_version"] = mGLVersionString;
|
||||
|
||||
info["vram"] = mVRAM;
|
||||
|
||||
// Extensions used by everyone
|
||||
info["has_multitexture"] = mHasMultitexture;
|
||||
info["has_ati_mem_info"] = mHasATIMemInfo;
|
||||
info["has_nvx_mem_info"] = mHasNVXMemInfo;
|
||||
info["num_texture_units"] = mNumTextureUnits;
|
||||
info["has_mip_map_generation"] = mHasMipMapGeneration;
|
||||
info["has_compressed_textures"] = mHasCompressedTextures;
|
||||
info["has_framebuffer_object"] = mHasFramebufferObject;
|
||||
info["max_samples"] = mMaxSamples;
|
||||
info["has_blend_func_separate"] = mHasBlendFuncSeparate;
|
||||
|
||||
// ARB Extensions
|
||||
info["has_vertex_buffer_object"] = mHasVertexBufferObject;
|
||||
info["has_vertex_array_object"] = mHasVertexArrayObject;
|
||||
info["has_sync"] = mHasSync;
|
||||
info["has_map_buffer_range"] = mHasMapBufferRange;
|
||||
info["has_flush_buffer_range"] = mHasFlushBufferRange;
|
||||
info["has_pbuffer"] = mHasPBuffer;
|
||||
info["has_shader_objects"] = mHasShaderObjects;
|
||||
info["has_vertex_shader"] = mHasVertexShader;
|
||||
info["has_fragment_shader"] = mHasFragmentShader;
|
||||
info["num_texture_image_units"] = mNumTextureImageUnits;
|
||||
info["has_occlusion_query"] = mHasOcclusionQuery;
|
||||
info["has_timer_query"] = mHasTimerQuery;
|
||||
info["has_occlusion_query2"] = mHasOcclusionQuery2;
|
||||
info["has_point_parameters"] = mHasPointParameters;
|
||||
info["has_draw_buffers"] = mHasDrawBuffers;
|
||||
info["has_depth_clamp"] = mHasDepthClamp;
|
||||
info["has_texture_rectangle"] = mHasTextureRectangle;
|
||||
info["has_texture_multisample"] = mHasTextureMultisample;
|
||||
info["has_transform_feedback"] = mHasTransformFeedback;
|
||||
info["max_sample_mask_words"] = mMaxSampleMaskWords;
|
||||
info["max_color_texture_samples"] = mMaxColorTextureSamples;
|
||||
info["max_depth_texture_samples"] = mMaxDepthTextureSamples;
|
||||
info["max_integer_samples"] = mMaxIntegerSamples;
|
||||
|
||||
// Other extensions.
|
||||
info["has_anisotropic"] = mHasAnisotropic;
|
||||
info["has_arb_env_combine"] = mHasARBEnvCombine;
|
||||
info["has_cube_map"] = mHasCubeMap;
|
||||
info["has_debug_output"] = mHasDebugOutput;
|
||||
info["has_srgb_texture"] = mHassRGBTexture;
|
||||
info["has_srgb_framebuffer"] = mHassRGBFramebuffer;
|
||||
info["has_texture_srgb_decode"] = mHasTexturesRGBDecode;
|
||||
|
||||
// Vendor-specific extensions
|
||||
info["is_ati"] = mIsATI;
|
||||
info["is_nvidia"] = mIsNVIDIA;
|
||||
info["is_intel"] = mIsIntel;
|
||||
info["is_gf2or4mx"] = mIsGF2or4MX;
|
||||
info["is_gf3"] = mIsGF3;
|
||||
info["is_gf_gfx"] = mIsGFFX;
|
||||
info["ati_offset_vertical_lines"] = mATIOffsetVerticalLines;
|
||||
info["ati_old_driver"] = mATIOldDriver;
|
||||
|
||||
// Other fields
|
||||
info["has_requirements"] = mHasRequirements;
|
||||
info["has_separate_specular_color"] = mHasSeparateSpecularColor;
|
||||
info["debug_gpu"] = mDebugGPU;
|
||||
info["max_vertex_range"] = mGLMaxVertexRange;
|
||||
info["max_index_range"] = mGLMaxIndexRange;
|
||||
info["max_texture_size"] = mGLMaxTextureSize;
|
||||
info["gl_renderer"] = mGLRenderer;
|
||||
}
|
||||
|
||||
void LLGLManager::shutdownGL()
|
||||
{
|
||||
if (mInited)
|
||||
|
|
|
|||
|
|
@ -175,6 +175,8 @@ public:
|
|||
void printGLInfoString();
|
||||
void getGLInfo(LLSD& info);
|
||||
|
||||
void asLLSD(LLSD& info);
|
||||
|
||||
// In ALL CAPS
|
||||
std::string mGLVendor;
|
||||
std::string mGLVendorShort;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "llpointer.h" // LLPointer<>
|
||||
#include "llrect.h"
|
||||
#include "llsingleton.h"
|
||||
#include "llglslshader.h"
|
||||
|
||||
class LLColor4;
|
||||
|
|
|
|||
|
|
@ -329,12 +329,11 @@ void LLFloater::initFloater(const Params& p)
|
|||
mButtonsEnabled[BUTTON_CLOSE] = TRUE;
|
||||
}
|
||||
|
||||
// Help button: '?'
|
||||
if ( !mHelpTopic.empty() )
|
||||
{
|
||||
mButtonsEnabled[BUTTON_HELP] = TRUE;
|
||||
}
|
||||
|
||||
// Help button: '?'
|
||||
//SL-14050 Disable all Help question marks
|
||||
// <FS:Ansariel> Nope!
|
||||
mButtonsEnabled[BUTTON_HELP] = !mHelpTopic.empty();// FALSE;
|
||||
|
||||
// Minimize button only for top draggers
|
||||
if ( !mDragOnLeft && mCanMinimize )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -296,7 +296,7 @@ public:
|
|||
typedef std::list<LLFolderViewModelItem*> child_list_t;
|
||||
|
||||
virtual void addChild(LLFolderViewModelItem* child)
|
||||
{
|
||||
{
|
||||
mChildren.push_back(child);
|
||||
child->setParent(this);
|
||||
dirtyFilter();
|
||||
|
|
|
|||
|
|
@ -851,16 +851,22 @@ void LLScrollListCtrl::updateColumns(bool force_update)
|
|||
}
|
||||
}
|
||||
|
||||
bool header_changed_width = false;
|
||||
// expand last column header we encountered to full list width
|
||||
// <FS:KC> Fixed last column on LLScrollListCtrl expanding on control resize when column width should be fixed or dynamic
|
||||
//if (last_header)
|
||||
if (last_header && last_header->canResize())
|
||||
{
|
||||
S32 old_width = last_header->getColumn()->getWidth();
|
||||
S32 new_width = llmax(0, mItemListRect.mRight - last_header->getRect().mLeft);
|
||||
last_header->reshape(new_width, last_header->getRect().getHeight());
|
||||
last_header->setVisible(mDisplayColumnHeaders && new_width > 0);
|
||||
last_header->getColumn()->setWidth(new_width);
|
||||
}
|
||||
if (old_width != new_width)
|
||||
{
|
||||
last_header->getColumn()->setWidth(new_width);
|
||||
header_changed_width = true;
|
||||
}
|
||||
}
|
||||
|
||||
// propagate column widths to individual cells
|
||||
if (columns_changed_width || force_update)
|
||||
|
|
@ -879,6 +885,20 @@ void LLScrollListCtrl::updateColumns(bool force_update)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (header_changed_width)
|
||||
{
|
||||
item_list::iterator iter;
|
||||
S32 index = last_header->getColumn()->mIndex; // Not always identical to last column!
|
||||
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
|
||||
{
|
||||
LLScrollListItem *itemp = *iter;
|
||||
LLScrollListCell* cell = itemp->getColumn(index);
|
||||
if (cell)
|
||||
{
|
||||
cell->setWidth(last_header->getColumn()->getWidth());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLScrollListCtrl::setHeadingHeight(S32 heading_height)
|
||||
|
|
@ -1526,18 +1546,34 @@ BOOL LLScrollListCtrl::setSelectedByValue(const LLSD& value, BOOL selected)
|
|||
for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
|
||||
{
|
||||
LLScrollListItem* item = *iter;
|
||||
if (item->getEnabled() && (item->getValue().asString() == value.asString()))
|
||||
if (item->getEnabled())
|
||||
{
|
||||
if (selected)
|
||||
{
|
||||
selectItem(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
deselectItem(item);
|
||||
}
|
||||
found = TRUE;
|
||||
break;
|
||||
if (value.isBinary())
|
||||
{
|
||||
if (item->getValue().isBinary())
|
||||
{
|
||||
LLSD::Binary data1 = value.asBinary();
|
||||
LLSD::Binary data2 = item->getValue().asBinary();
|
||||
found = std::equal(data1.begin(), data1.end(), data2.begin()) ? TRUE : FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
found = item->getValue().asString() == value.asString() ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (selected)
|
||||
{
|
||||
selectItem(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
deselectItem(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2917,8 +2953,16 @@ void LLScrollListCtrl::sortByColumnIndex(U32 column, BOOL ascending)
|
|||
|
||||
void LLScrollListCtrl::updateSort() const
|
||||
{
|
||||
if (hasSortOrder() && !isSorted())
|
||||
// <FS:Beq> FIRE-30667 et al. Group hang issues
|
||||
// if (hasSortOrder() && !isSorted())
|
||||
// {
|
||||
static LLUICachedControl<U32> sortDeferFrameCount("FSSortDeferalFrames");
|
||||
if ( hasSortOrder() && !isSorted() && ( mLastUpdateFrame > 1 && ( LLFrameTimer::getFrameCount() - mLastUpdateFrame ) >= sortDeferFrameCount ) )
|
||||
// encoding two (unlikely) special values into mLastUpdateFrame 1 means we've sorted and 0 means we've nothing new to do.
|
||||
// 0 is set after sorting, 1 can be set by a parent for any post sorting action.
|
||||
{
|
||||
mLastUpdateFrame=0;
|
||||
// </FS:Beq>
|
||||
// do stable sort to preserve any previous sorts
|
||||
std::stable_sort(
|
||||
mItemList.begin(),
|
||||
|
|
|
|||
|
|
@ -412,7 +412,9 @@ public:
|
|||
void sortOnce(S32 column, BOOL ascending);
|
||||
|
||||
// manually call this whenever editing list items in place to flag need for resorting
|
||||
void setNeedsSort(bool val = true) { mSorted = !val; }
|
||||
// <FS:Beq/> FIRE-30667 et al. Avoid hangs on large list updates
|
||||
// void setNeedsSort(bool val = true) { mSorted = !val; }
|
||||
void setNeedsSort(bool val = true) { mSorted = !val; mLastUpdateFrame = LLFrameTimer::getFrameCount(); }
|
||||
void dirtyColumns(); // some operation has potentially affected column layout or ordering
|
||||
|
||||
boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb )
|
||||
|
|
@ -452,6 +454,8 @@ protected:
|
|||
|
||||
public:
|
||||
void updateLineHeight();
|
||||
// <FS:Beq/> FIRE-30667 et al. Avoid hangs on large list updates
|
||||
mutable U32 mLastUpdateFrame;
|
||||
|
||||
private:
|
||||
void selectPrevItem(BOOL extend_selection);
|
||||
|
|
@ -478,6 +482,7 @@ private:
|
|||
static void copyNameToClipboard(std::string id, bool is_group);
|
||||
static void copySLURLToClipboard(std::string id, bool is_group);
|
||||
|
||||
|
||||
S32 mLineHeight; // the max height of a single line
|
||||
S32 mScrollLines; // how many lines we've scrolled down
|
||||
S32 mPageLines; // max number of lines is it possible to see on the screen given mRect and mLineHeight
|
||||
|
|
|
|||
|
|
@ -1738,4 +1738,43 @@ void LLUrlEntryExperienceProfile::onExperienceDetails( const LLSD& experience_de
|
|||
callObservers(experience_details[LLExperienceCache::EXPERIENCE_ID].asString(), name, LLStringUtil::null);
|
||||
}
|
||||
|
||||
//
|
||||
// LLUrlEntryEmail Describes an IPv6 address
|
||||
//
|
||||
LLUrlEntryIPv6::LLUrlEntryIPv6()
|
||||
: LLUrlEntryBase()
|
||||
{
|
||||
mHostPath = "https?://\\[([a-f0-9:]+:+)+[a-f0-9]+]";
|
||||
mPattern = boost::regex(mHostPath + "(:\\d{1,5})?(/\\S*)?",
|
||||
boost::regex::perl | boost::regex::icase);
|
||||
mMenuName = "menu_url_http.xml";
|
||||
mTooltip = LLTrans::getString("TooltipHttpUrl");
|
||||
}
|
||||
|
||||
std::string LLUrlEntryIPv6::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
|
||||
{
|
||||
boost::regex regex = boost::regex(mHostPath, boost::regex::perl | boost::regex::icase);
|
||||
boost::match_results<std::string::const_iterator> matches;
|
||||
|
||||
if (boost::regex_search(url, matches, regex))
|
||||
{
|
||||
return url.substr(0, matches[0].length());
|
||||
}
|
||||
else
|
||||
{
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
std::string LLUrlEntryIPv6::getQuery(const std::string &url) const
|
||||
{
|
||||
boost::regex regex = boost::regex(mHostPath, boost::regex::perl | boost::regex::icase);
|
||||
boost::match_results<std::string::const_iterator> matches;
|
||||
|
||||
return boost::regex_replace(url, regex, "");
|
||||
}
|
||||
|
||||
std::string LLUrlEntryIPv6::getUrl(const std::string &string) const
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -600,6 +600,20 @@ public:
|
|||
/*virtual*/ std::string getUrl(const std::string &string) const;
|
||||
};
|
||||
|
||||
///
|
||||
/// LLUrlEntryEmail Describes an IPv6 address
|
||||
///
|
||||
class LLUrlEntryIPv6 : public LLUrlEntryBase
|
||||
{
|
||||
public:
|
||||
LLUrlEntryIPv6();
|
||||
/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
|
||||
/*virtual*/ std::string getUrl(const std::string &string) const;
|
||||
/*virtual*/ std::string getQuery(const std::string &url) const;
|
||||
|
||||
std::string mHostPath;
|
||||
};
|
||||
|
||||
///
|
||||
/// LLUrlEntryJira Describes Jira issue names -KC
|
||||
///
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ LLUrlRegistry::LLUrlRegistry()
|
|||
{
|
||||
// mUrlEntry.reserve(20);
|
||||
// [RLVa:KB] - Checked: 2010-11-01 (RLVa-1.2.2a) | Added: RLVa-1.2.2a
|
||||
mUrlEntry.reserve(28);
|
||||
mUrlEntry.reserve(29);
|
||||
// [/RLVa:KB]
|
||||
|
||||
// Urls are matched in the order that they were registered
|
||||
|
|
@ -96,6 +96,7 @@ LLUrlRegistry::LLUrlRegistry()
|
|||
// <FS:Ansariel> Allow URLs with no protocol again
|
||||
registerUrl(new LLUrlEntryHTTPNoProtocol());
|
||||
registerUrl(new LLUrlEntryEmail());
|
||||
registerUrl(new LLUrlEntryIPv6());
|
||||
// parse jira issue names to links -KC
|
||||
registerUrl(new LLUrlEntryJira());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -903,4 +903,38 @@ namespace tut
|
|||
"and even no www something lindenlab.com",
|
||||
"");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<16>()
|
||||
{
|
||||
//
|
||||
// test LLUrlEntryIPv6
|
||||
//
|
||||
LLUrlEntryIPv6 url;
|
||||
|
||||
// Regex tests.
|
||||
testRegex("match urls with a protocol", url,
|
||||
"this url should match http://[::1]",
|
||||
"http://[::1]");
|
||||
|
||||
testRegex("match urls with a protocol and query", url,
|
||||
"this url should match http://[::1]/file.mp3",
|
||||
"http://[::1]/file.mp3");
|
||||
|
||||
testRegex("match urls with a protocol", url,
|
||||
"this url should match http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]",
|
||||
"http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]");
|
||||
|
||||
testRegex("match urls with port", url,
|
||||
"let's specify some port http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]:8080",
|
||||
"http://[2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d]:8080");
|
||||
|
||||
testRegex("don't match urls w/o protocol", url,
|
||||
"looks like an url something [2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d] but no https prefix",
|
||||
"");
|
||||
|
||||
testRegex("don't match incorrect urls", url,
|
||||
"http://[ 2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d ]",
|
||||
"");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,6 +178,9 @@ public:
|
|||
|
||||
static std::vector<std::string> getDisplaysResolutionList();
|
||||
|
||||
// windows only DirectInput8 for joysticks
|
||||
virtual void* getDirectInput8() { return NULL; };
|
||||
virtual bool getInputDevices(U32 device_type_filter, void * devices_callback, void* userdata) { return false; };
|
||||
protected:
|
||||
LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags);
|
||||
virtual ~LLWindow();
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@
|
|||
|
||||
#include <dinput.h>
|
||||
#include <Dbt.h.>
|
||||
#include <InitGuid.h> // needed for llurlentry test to build on some systems
|
||||
#pragma comment(lib, "dxguid.lib") // needed for llurlentry test to build on some systems
|
||||
#pragma comment(lib, "dinput8")
|
||||
|
||||
const S32 MAX_MESSAGE_PER_UPDATE = 20;
|
||||
const S32 BITS_PER_PIXEL = 32;
|
||||
|
|
@ -77,6 +80,7 @@ const F32 ICON_FLASH_TIME = 0.5f;
|
|||
extern BOOL gDebugWindowProc;
|
||||
|
||||
LPWSTR gIconResource = IDI_APPLICATION;
|
||||
LPDIRECTINPUT8 gDirectInput8;
|
||||
|
||||
LLW32MsgCallback gAsyncMsgCallback = NULL;
|
||||
|
||||
|
|
@ -535,6 +539,21 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
|
|||
mhInstance = GetModuleHandle(NULL);
|
||||
mWndProc = NULL;
|
||||
|
||||
// Init Direct Input - needed for joystick / Spacemouse
|
||||
|
||||
LPDIRECTINPUT8 di8_interface;
|
||||
HRESULT status = DirectInput8Create(
|
||||
mhInstance, // HINSTANCE hinst,
|
||||
DIRECTINPUT_VERSION, // DWORD dwVersion,
|
||||
IID_IDirectInput8, // REFIID riidltf,
|
||||
(LPVOID*)&di8_interface, // LPVOID * ppvOut,
|
||||
NULL // LPUNKNOWN punkOuter
|
||||
);
|
||||
if (status == DI_OK)
|
||||
{
|
||||
gDirectInput8 = di8_interface;
|
||||
}
|
||||
|
||||
mSwapMethod = SWAP_METHOD_UNDEFINED;
|
||||
|
||||
// No WPARAM yet.
|
||||
|
|
@ -4317,6 +4336,28 @@ void LLWindowWin32::setDPIAwareness()
|
|||
}
|
||||
}
|
||||
|
||||
void* LLWindowWin32::getDirectInput8()
|
||||
{
|
||||
return &gDirectInput8;
|
||||
}
|
||||
|
||||
bool LLWindowWin32::getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata)
|
||||
{
|
||||
if (gDirectInput8 != NULL)
|
||||
{
|
||||
// Enumerate devices
|
||||
HRESULT status = gDirectInput8->EnumDevices(
|
||||
(DWORD) device_type_filter, // DWORD dwDevType,
|
||||
(LPDIENUMDEVICESCALLBACK)di8_devices_callback, // LPDIENUMDEVICESCALLBACK lpCallback, // BOOL DIEnumDevicesCallback( LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef ) // BOOL CALLBACK DinputDevice::DevicesCallback
|
||||
(LPVOID*)userdata, // LPVOID pvRef
|
||||
DIEDFL_ATTACHEDONLY // DWORD dwFlags
|
||||
);
|
||||
|
||||
return status == DI_OK;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
F32 LLWindowWin32::getSystemUISize()
|
||||
{
|
||||
F32 scale_value = 1.f;
|
||||
|
|
|
|||
|
|
@ -122,6 +122,9 @@ public:
|
|||
static std::vector<std::string> getDisplaysResolutionList();
|
||||
static std::vector<std::string> getDynamicFallbackFontList();
|
||||
static void setDPIAwareness();
|
||||
|
||||
/*virtual*/ void* getDirectInput8();
|
||||
/*virtual*/ bool getInputDevices(U32 device_type_filter, void * di8_devices_callback, void* userdata);
|
||||
protected:
|
||||
LLWindowWin32(LLWindowCallbacks* callbacks,
|
||||
const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags,
|
||||
|
|
|
|||
|
|
@ -743,6 +743,24 @@ LLSD LLControlGroup::getLLSD(const std::string& name)
|
|||
return get<LLSD>(name);
|
||||
}
|
||||
|
||||
LLSD LLControlGroup::asLLSD(bool diffs_only)
|
||||
{
|
||||
// Dump all stored values as LLSD
|
||||
LLSD result = LLSD::emptyArray();
|
||||
for (ctrl_name_table_t::iterator iter = mNameTable.begin();
|
||||
iter != mNameTable.end(); iter++)
|
||||
{
|
||||
LLControlVariable *control = iter->second;
|
||||
if (!control || control->isType(TYPE_STRING) || (diffs_only && control->isDefault()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const std::string& name = iter->first;
|
||||
result[name] = getLLSD(name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL LLControlGroup::controlExists(const std::string& name)
|
||||
{
|
||||
ctrl_name_table_t::iterator iter = mNameTable.find(name);
|
||||
|
|
|
|||
|
|
@ -286,6 +286,8 @@ public:
|
|||
LLColor4 getColor4(const std::string& name);
|
||||
LLColor3 getColor3(const std::string& name);
|
||||
|
||||
LLSD asLLSD(bool diffs_only);
|
||||
|
||||
// generic getter
|
||||
template<typename T> T get(const std::string& name)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -344,6 +344,17 @@
|
|||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>FSSortDeferalFrames</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>How many frames after an update should we wait before sorting</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>2</integer>
|
||||
</map>
|
||||
<key>FSGroupNotifyNoTransparency</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -7444,6 +7455,17 @@
|
|||
<key>Backup</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>JoystickDeviceUUID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Preffered device ID.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string />
|
||||
</map>
|
||||
<key>JoystickMouselookYaw</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ void FSPanelGroupControlPanel::setSessionId(const LLUUID& session_id)
|
|||
if(!mParticipantList)
|
||||
{
|
||||
LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id);
|
||||
// <FS:Beq/> potential crash avoidance. getSpeakerManager can return NULL, the constructor does not check
|
||||
if ( speaker_manager == nullptr ){ return;}
|
||||
mParticipantList = new FSParticipantList(speaker_manager, getChild<LLAvatarList>("grp_speakers_list"), true,false);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1029,6 +1029,18 @@ boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_cal
|
|||
return mParcelChangedSignal.connect(cb);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLAgent::capabilityReceivedCallback(const LLUUID ®ion_id)
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region && region->getRegionID() == region_id)
|
||||
{
|
||||
region->requestSimulatorFeatures();
|
||||
LLAppViewer::instance()->updateNameLookupUrl();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// setRegion()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -1079,10 +1091,11 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
|
|||
if (regionp->capabilitiesReceived())
|
||||
{
|
||||
regionp->requestSimulatorFeatures();
|
||||
LLAppViewer::instance()->updateNameLookupUrl();
|
||||
}
|
||||
else
|
||||
{
|
||||
regionp->setCapabilitiesReceivedCallback(boost::bind(&LLViewerRegion::requestSimulatorFeatures, regionp));
|
||||
regionp->setCapabilitiesReceivedCallback(LLAgent::capabilityReceivedCallback);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1101,6 +1114,15 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
|
|||
|
||||
// Update all of the regions.
|
||||
LLWorld::getInstance()->updateAgentOffset(mAgentOriginGlobal);
|
||||
|
||||
if (regionp->capabilitiesReceived())
|
||||
{
|
||||
LLAppViewer::instance()->updateNameLookupUrl();
|
||||
}
|
||||
else
|
||||
{
|
||||
regionp->setCapabilitiesReceivedCallback([](const LLUUID ®ion_id) {LLAppViewer::instance()->updateNameLookupUrl(); });
|
||||
}
|
||||
}
|
||||
|
||||
// Pass new region along to metrics components that care about this level of detail.
|
||||
|
|
@ -5967,8 +5989,8 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
|
|||
|
||||
|
||||
if ((S32)texture_index < TEX_NUM_INDICES )
|
||||
{
|
||||
const LLAvatarAppearanceDictionary::TextureEntry *texture_entry = LLAvatarAppearanceDictionary::instance().getTexture((ETextureIndex)texture_index);
|
||||
{
|
||||
const LLAvatarAppearanceDictionary::TextureEntry *texture_entry = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)texture_index);
|
||||
if (texture_entry)
|
||||
{
|
||||
EBakedTextureIndex baked_index = texture_entry->mBakedTextureIndex;
|
||||
|
|
@ -6034,8 +6056,8 @@ void LLAgent::dumpSentAppearance(const std::string& dump_prefix)
|
|||
F32 value = appearance_version_param->getWeight();
|
||||
dump_visual_param(file, appearance_version_param, value);
|
||||
}
|
||||
for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
|
||||
iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
|
||||
for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
|
||||
iter != LLAvatarAppearance::getDictionary()->getTextures().end();
|
||||
++iter)
|
||||
{
|
||||
const ETextureIndex index = iter->first;
|
||||
|
|
@ -6144,7 +6166,7 @@ void LLAgent::sendAgentSetAppearance()
|
|||
{
|
||||
for(U8 baked_index = 0; baked_index < gAgentAvatarp->getNumBakes(); baked_index++ )
|
||||
{
|
||||
const ETextureIndex texture_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
|
||||
const ETextureIndex texture_index = LLAvatarAppearance::getDictionary()->bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
|
||||
|
||||
// if we're not wearing a skirt, we don't need the texture to be baked
|
||||
if (texture_index == TEX_SKIRT_BAKED && !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
|
||||
|
|
@ -6203,7 +6225,7 @@ void LLAgent::sendAgentSetAppearance()
|
|||
const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash);
|
||||
if (hash.notNull())
|
||||
{
|
||||
ETextureIndex texture_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
|
||||
ETextureIndex texture_index = LLAvatarAppearance::getDictionary()->bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
|
||||
msg->nextBlockFast(_PREHASH_WearableData);
|
||||
msg->addUUIDFast(_PREHASH_CacheID, hash);
|
||||
msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
|
||||
|
|
|
|||
|
|
@ -258,6 +258,8 @@ public:
|
|||
boost::signals2::connection addParcelChangedCallback(parcel_changed_callback_t);
|
||||
|
||||
private:
|
||||
static void capabilityReceivedCallback(const LLUUID ®ion_id);
|
||||
|
||||
typedef boost::signals2::signal<void()> parcel_changed_signal_t;
|
||||
parcel_changed_signal_t mParcelChangedSignal;
|
||||
|
||||
|
|
|
|||
|
|
@ -2141,7 +2141,7 @@ void LLAgentWearables::queryWearableCache()
|
|||
num_queries++;
|
||||
// *NOTE: make sure at least one request gets packed
|
||||
|
||||
ETextureIndex te_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
|
||||
ETextureIndex te_index = LLAvatarAppearance::getDictionary()->bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
|
||||
|
||||
//LL_INFOS() << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << LL_ENDL;
|
||||
gMessageSystem->nextBlockFast(_PREHASH_WearableData);
|
||||
|
|
|
|||
|
|
@ -2066,7 +2066,7 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
|
|||
}
|
||||
|
||||
// Moved from LLWearableList::ContextMenu for wider utility.
|
||||
bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids)
|
||||
bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids) const
|
||||
{
|
||||
// TODO: investigate wearables may not be loaded at this point EXT-8231
|
||||
|
||||
|
|
@ -2076,7 +2076,7 @@ bool LLAppearanceMgr::canAddWearables(const uuid_vec_t& item_ids)
|
|||
// Count given clothes (by wearable type) and objects.
|
||||
for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it)
|
||||
{
|
||||
LLViewerInventoryItem* item = gInventory.getItem(*it);
|
||||
const LLViewerInventoryItem* item = gInventory.getItem(*it);
|
||||
if (!item)
|
||||
{
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ public:
|
|||
bool getCanReplaceCOF(const LLUUID& outfit_cat_id);
|
||||
|
||||
// Can we add all referenced items to the avatar?
|
||||
bool canAddWearables(const uuid_vec_t& item_ids);
|
||||
bool canAddWearables(const uuid_vec_t& item_ids) const;
|
||||
|
||||
// Copy all items in a category.
|
||||
void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ extern BOOL gHiDPISupport;
|
|||
////////////////////////////////////////////////////////////
|
||||
// All from the last globals push...
|
||||
|
||||
F32 gSimLastTime; // Used in LLAppViewer::init and send_stats()
|
||||
F32 gSimLastTime; // Used in LLAppViewer::init and send_viewer_stats()
|
||||
F32 gSimFrames;
|
||||
|
||||
BOOL gShowObjectUpdates = FALSE;
|
||||
|
|
@ -753,6 +753,7 @@ LLAppViewer::LLAppViewer()
|
|||
mPurgeCacheOnExit(false),
|
||||
mPurgeUserDataOnExit(false),
|
||||
mSecondInstance(false),
|
||||
mUpdaterNotFound(false),
|
||||
mSavedFinalSnapshot(false),
|
||||
mSavePerAccountSettings(false), // don't save settings on logout unless login succeeded.
|
||||
mQuitRequested(false),
|
||||
|
|
@ -766,6 +767,7 @@ LLAppViewer::LLAppViewer()
|
|||
mFastTimerLogThread(NULL),
|
||||
mSettingsLocationList(NULL),
|
||||
mIsFirstRun(false),
|
||||
//mMinMicroSecPerFrame(0.f), // <FS:Ansariel> FIRE-22297: FPS limiter not working properly on Mac/Linux
|
||||
mSaveSettingsOnExit(true), // <FS:Zi> Backup Settings
|
||||
mPurgeTextures(false) // <FS:Ansariel> FIRE-13066
|
||||
{
|
||||
|
|
@ -1370,78 +1372,101 @@ bool LLAppViewer::init()
|
|||
|
||||
gGLActive = FALSE;
|
||||
|
||||
// <FS:Ansariel> Disable updater
|
||||
// <FS:Ansariel> Disable updater
|
||||
//#if LL_RELEASE_FOR_DOWNLOAD
|
||||
// if (!gSavedSettings.getBOOL("CmdLineSkipUpdater"))
|
||||
// {
|
||||
// LLProcess::Params updater;
|
||||
// updater.desc = "updater process";
|
||||
// // Because it's the updater, it MUST persist beyond the lifespan of the
|
||||
// // viewer itself.
|
||||
// updater.autokill = false;
|
||||
// LLProcess::Params updater;
|
||||
// updater.desc = "updater process";
|
||||
// // Because it's the updater, it MUST persist beyond the lifespan of the
|
||||
// // viewer itself.
|
||||
// updater.autokill = false;
|
||||
// std::string updater_file;
|
||||
//#if LL_WINDOWS
|
||||
// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker.exe");
|
||||
// updater_file = "SLVersionChecker.exe";
|
||||
// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, updater_file);
|
||||
//#elif LL_DARWIN
|
||||
// // explicitly run the system Python interpreter on SLVersionChecker.py
|
||||
// updater.executable = "python";
|
||||
// updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "SLVersionChecker.py"));
|
||||
// // explicitly run the system Python interpreter on SLVersionChecker.py
|
||||
// updater.executable = "python";
|
||||
// updater_file = "SLVersionChecker.py";
|
||||
// updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", updater_file));
|
||||
//#else
|
||||
// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker");
|
||||
// updater_file = "SLVersionChecker";
|
||||
// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, updater_file);
|
||||
//#endif
|
||||
// // add LEAP mode command-line argument to whichever of these we selected
|
||||
// updater.args.add("leap");
|
||||
// // UpdaterServiceSettings
|
||||
// updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
|
||||
// // channel
|
||||
// updater.args.add(LLVersionInfo::getChannel());
|
||||
// // testok
|
||||
// updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
|
||||
// // ForceAddressSize
|
||||
// updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
|
||||
//#if LL_WINDOWS && !LL_RELEASE_FOR_DOWNLOAD && !LL_SEND_CRASH_REPORTS
|
||||
// // This is neither a release package, nor crash-reporting enabled test build
|
||||
// // try to run version updater, but don't bother if it fails (file might be missing)
|
||||
// LLLeap *leap_p = LLLeap::create(updater, false);
|
||||
// if (!leap_p)
|
||||
// {
|
||||
// LL_WARNS("LLLeap") << "Failed to run LLLeap" << LL_ENDL;
|
||||
// // add LEAP mode command-line argument to whichever of these we selected
|
||||
// updater.args.add("leap");
|
||||
// // UpdaterServiceSettings
|
||||
// updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
|
||||
// // channel
|
||||
// updater.args.add(LLVersionInfo::instance().getChannel());
|
||||
// // testok
|
||||
// updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest")));
|
||||
// // ForceAddressSize
|
||||
// updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// // Run the updater. An exception from launching the updater should bother us.
|
||||
// LLLeap::create(updater, true);
|
||||
// mUpdaterNotFound = false;
|
||||
// }
|
||||
// catch (...)
|
||||
// {
|
||||
// LLUIString details = LLNotifications::instance().getGlobalString("LLLeapUpdaterFailure");
|
||||
// details.setArg("[UPDATER_APP]", updater_file);
|
||||
// OSMessageBox(
|
||||
// details.getString(),
|
||||
// LLStringUtil::null,
|
||||
// OSMB_OK);
|
||||
// mUpdaterNotFound = true;
|
||||
// }
|
||||
// }
|
||||
//#else
|
||||
// // Run the updater. An exception from launching the updater should bother us.
|
||||
// LLLeap::create(updater, true);
|
||||
//#endif
|
||||
// else
|
||||
// {
|
||||
// LL_WARNS("InitInfo") << "Skipping updater check." << LL_ENDL;
|
||||
// }
|
||||
//
|
||||
// if (mUpdaterNotFound)
|
||||
// {
|
||||
// LL_WARNS("InitInfo") << "Failed to launch updater. Skipping Leap commands." << LL_ENDL;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // Iterate over --leap command-line options. But this is a bit tricky: if
|
||||
// // there's only one, it won't be an array at all.
|
||||
// LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand"));
|
||||
// LL_DEBUGS("InitInfo") << "LeapCommand: " << LeapCommand << LL_ENDL;
|
||||
// if (LeapCommand.isDefined() && !LeapCommand.isArray())
|
||||
// {
|
||||
// // If LeapCommand is actually a scalar value, make an array of it.
|
||||
// // Have to do it in two steps because LeapCommand.append(LeapCommand)
|
||||
// // trashes content! :-P
|
||||
// LLSD item(LeapCommand);
|
||||
// LeapCommand.append(item);
|
||||
// }
|
||||
// BOOST_FOREACH(const std::string& leap, llsd::inArray(LeapCommand))
|
||||
// {
|
||||
// LL_INFOS("InitInfo") << "processing --leap \"" << leap << '"' << LL_ENDL;
|
||||
// // We don't have any better description of this plugin than the
|
||||
// // user-specified command line. Passing "" causes LLLeap to derive a
|
||||
// // description from the command line itself.
|
||||
// // Suppress LLLeap::Error exception: trust LLLeap's own logging. We
|
||||
// // don't consider any one --leap command mission-critical, so if one
|
||||
// // fails, log it, shrug and carry on.
|
||||
// LLLeap::create("", leap, false); // exception=false
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0)
|
||||
// {
|
||||
// LL_WARNS("InitInfo") << "QAModeEventHostPort DEPRECATED: "
|
||||
// << "lleventhost no longer supported as a dynamic library"
|
||||
// << LL_ENDL;
|
||||
// }
|
||||
//#endif //LL_RELEASE_FOR_DOWNLOAD
|
||||
// </FS:Ansariel>
|
||||
|
||||
// Iterate over --leap command-line options. But this is a bit tricky: if
|
||||
// there's only one, it won't be an array at all.
|
||||
LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand"));
|
||||
LL_DEBUGS("InitInfo") << "LeapCommand: " << LeapCommand << LL_ENDL;
|
||||
if (LeapCommand.isDefined() && ! LeapCommand.isArray())
|
||||
{
|
||||
// If LeapCommand is actually a scalar value, make an array of it.
|
||||
// Have to do it in two steps because LeapCommand.append(LeapCommand)
|
||||
// trashes content! :-P
|
||||
LLSD item(LeapCommand);
|
||||
LeapCommand.append(item);
|
||||
}
|
||||
BOOST_FOREACH(const std::string& leap, llsd::inArray(LeapCommand))
|
||||
{
|
||||
LL_INFOS("InitInfo") << "processing --leap \"" << leap << '"' << LL_ENDL;
|
||||
// We don't have any better description of this plugin than the
|
||||
// user-specified command line. Passing "" causes LLLeap to derive a
|
||||
// description from the command line itself.
|
||||
// Suppress LLLeap::Error exception: trust LLLeap's own logging. We
|
||||
// don't consider any one --leap command mission-critical, so if one
|
||||
// fails, log it, shrug and carry on.
|
||||
LLLeap::create("", leap, false); // exception=false
|
||||
}
|
||||
|
||||
if (gSavedSettings.getBOOL("QAMode") && gSavedSettings.getS32("QAModeEventHostPort") > 0)
|
||||
{
|
||||
LL_WARNS("InitInfo") << "QAModeEventHostPort DEPRECATED: "
|
||||
<< "lleventhost no longer supported as a dynamic library"
|
||||
<< LL_ENDL;
|
||||
}
|
||||
|
||||
LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match;
|
||||
|
||||
//EXT-7013 - On windows for some locale (Japanese) standard
|
||||
|
|
@ -1495,6 +1520,12 @@ bool LLAppViewer::init()
|
|||
|
||||
joystick = LLViewerJoystick::getInstance();
|
||||
joystick->setNeedsReset(true);
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
// <FS:Ansariel> FIRE-22297: FPS limiter not working properly on Mac/Linux
|
||||
//gSavedSettings.getControl("FramePerSecondLimit")->getSignal()->connect(boost::bind(&LLAppViewer::onChangeFrameLimit, this, _2));
|
||||
//onChangeFrameLimit(gSavedSettings.getLLSD("FramePerSecondLimit"));
|
||||
// </FS:Ansariel>
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1772,6 +1803,23 @@ bool LLAppViewer::doFrame()
|
|||
|
||||
display();
|
||||
|
||||
// <FS:Ansariel> FIRE-22297: FPS limiter not working properly on Mac/Linux
|
||||
//static U64 last_call = 0;
|
||||
//if (!gTeleportDisplay)
|
||||
//{
|
||||
// // Frame/draw throttling, controlled by FramePerSecondLimit
|
||||
// U64 elapsed_time = LLTimer::getTotalTime() - last_call;
|
||||
// if (elapsed_time < mMinMicroSecPerFrame)
|
||||
// {
|
||||
// LL_RECORD_BLOCK_TIME(FTM_SLEEP);
|
||||
// // llclamp for when time function gets funky
|
||||
// U64 sleep_time = llclamp(mMinMicroSecPerFrame - elapsed_time, (U64)1, (U64)1e6);
|
||||
// micro_sleep(sleep_time, 0);
|
||||
// }
|
||||
//}
|
||||
//last_call = LLTimer::getTotalTime();
|
||||
// </FS:Ansariel>
|
||||
|
||||
pingMainloopTimeout("Main:Snapshot");
|
||||
LLFloaterSnapshot::update(); // take snapshots
|
||||
LLFloaterOutfitSnapshot::update();
|
||||
|
|
@ -2214,9 +2262,6 @@ bool LLAppViewer::cleanup()
|
|||
|
||||
SUBSYSTEM_CLEANUP(LLAvatarAppearance);
|
||||
|
||||
// <FS:Ansariel> Comment out duplicate clean up
|
||||
//SUBSYSTEM_CLEANUP(LLAvatarAppearance);
|
||||
|
||||
SUBSYSTEM_CLEANUP(LLPostProcess);
|
||||
|
||||
LLTracker::cleanupInstance();
|
||||
|
|
@ -2456,6 +2501,7 @@ bool LLAppViewer::cleanup()
|
|||
LLUIImageList::getInstance()->cleanUp();
|
||||
|
||||
// This should eventually be done in LLAppViewer
|
||||
SUBSYSTEM_CLEANUP(LLImage);
|
||||
SUBSYSTEM_CLEANUP(LLVFSThread);
|
||||
SUBSYSTEM_CLEANUP(LLLFSThread);
|
||||
|
||||
|
|
@ -2499,6 +2545,7 @@ bool LLAppViewer::cleanup()
|
|||
LLWeb::loadURLExternal( gLaunchFileOnQuit, false );
|
||||
LL_INFOS() << "File launched." << LL_ENDL;
|
||||
}
|
||||
// make sure nothing uses applyProxySettings by this point.
|
||||
LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL;
|
||||
SUBSYSTEM_CLEANUP(LLProxy);
|
||||
LLCore::LLHttp::cleanup();
|
||||
|
|
@ -2554,7 +2601,7 @@ bool LLAppViewer::initThreads()
|
|||
{
|
||||
static const bool enable_threads = true;
|
||||
|
||||
LLImage::initParamSingleton(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
|
||||
LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
|
||||
|
||||
LLVFSThread::initClass(enable_threads && false);
|
||||
LLLFSThread::initClass(enable_threads && false);
|
||||
|
|
@ -3783,7 +3830,7 @@ LLSD LLAppViewer::getViewerInfo() const
|
|||
info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos));
|
||||
info["REGION"] = gAgent.getRegion()->getName();
|
||||
boost::regex regex("\\.(secondlife|lindenlab)\\..*");
|
||||
info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getHost().getHostName(), regex, "");
|
||||
info["HOSTNAME"] = boost::regex_replace(gAgent.getRegion()->getSimHostName(), regex, "");
|
||||
LLSLURL slurl;
|
||||
LLAgentUI::buildSLURL(slurl);
|
||||
info["SLURL"] = slurl.getSLURLString();
|
||||
|
|
@ -4375,7 +4422,7 @@ void LLAppViewer::handleViewerCrash()
|
|||
|
||||
if(gAgent.getRegion())
|
||||
{
|
||||
gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
|
||||
gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegion()->getSimHostName();
|
||||
gDebugInfo["Dynamic"]["CurrentRegion"] = gAgent.getRegion()->getName();
|
||||
|
||||
const LLVector3& loc = gAgent.getPositionAgent();
|
||||
|
|
@ -4782,7 +4829,11 @@ void LLAppViewer::requestQuit()
|
|||
gFloaterView->closeAllChildren(true);
|
||||
}
|
||||
|
||||
send_stats();
|
||||
// Send preferences once, when exiting
|
||||
// <FS:Ansariel> Don't send all non-default settings which might result in a violation of GDPR
|
||||
//bool include_preferences = true;
|
||||
bool include_preferences = false;
|
||||
send_viewer_stats(include_preferences);
|
||||
|
||||
gLogoutTimer.reset();
|
||||
mQuitRequested = true;
|
||||
|
|
@ -5660,7 +5711,8 @@ void LLAppViewer::idle()
|
|||
if (viewer_stats_timer.getElapsedTimeF32() >= SEND_STATS_PERIOD && !gDisconnected)
|
||||
{
|
||||
LL_INFOS() << "Transmitting sessions stats" << LL_ENDL;
|
||||
send_stats();
|
||||
bool include_preferences = false;
|
||||
send_viewer_stats(include_preferences);
|
||||
viewer_stats_timer.reset();
|
||||
}
|
||||
|
||||
|
|
@ -6081,11 +6133,56 @@ void LLAppViewer::sendLogoutRequest()
|
|||
}
|
||||
}
|
||||
|
||||
void LLAppViewer::updateNameLookupUrl()
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (!region || !region->capabilitiesReceived())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLAvatarNameCache *name_cache = LLAvatarNameCache::getInstance();
|
||||
bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();
|
||||
std::string name_lookup_url;
|
||||
name_lookup_url.reserve(128); // avoid a memory allocation below
|
||||
name_lookup_url = region->getCapability("GetDisplayNames");
|
||||
bool have_capability = !name_lookup_url.empty();
|
||||
if (have_capability)
|
||||
{
|
||||
// we have support for display names, use it
|
||||
U32 url_size = name_lookup_url.size();
|
||||
// capabilities require URLs with slashes before query params:
|
||||
// https://<host>:<port>/cap/<uuid>/?ids=<blah>
|
||||
// but the caps are granted like:
|
||||
// https://<host>:<port>/cap/<uuid>
|
||||
if (url_size > 0 && name_lookup_url[url_size - 1] != '/')
|
||||
{
|
||||
name_lookup_url += '/';
|
||||
}
|
||||
name_cache->setNameLookupURL(name_lookup_url);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Display names not available on this region
|
||||
name_cache->setNameLookupURL(std::string());
|
||||
}
|
||||
|
||||
// Error recovery - did we change state?
|
||||
if (had_capability != have_capability)
|
||||
{
|
||||
// name tags are persistant on screen, so make sure they refresh
|
||||
LLVOAvatar::invalidateNameTags();
|
||||
}
|
||||
}
|
||||
|
||||
void LLAppViewer::idleNameCache()
|
||||
{
|
||||
// Neither old nor new name cache can function before agent has a region
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (!region) return;
|
||||
if (!region)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// deal with any queued name requests and replies.
|
||||
gCacheName->processPending();
|
||||
|
|
@ -6093,47 +6190,12 @@ void LLAppViewer::idleNameCache()
|
|||
// Can't run the new cache until we have the list of capabilities
|
||||
// for the agent region, and can therefore decide whether to use
|
||||
// display names or fall back to the old name system.
|
||||
if (!region->capabilitiesReceived()) return;
|
||||
if (!region->capabilitiesReceived())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Agent may have moved to a different region, so need to update cap URL
|
||||
// for name lookups. Can't do this in the cap grant code, as caps are
|
||||
// granted to neighbor regions before the main agent gets there. Can't
|
||||
// do it in the move-into-region code because cap not guaranteed to be
|
||||
// granted yet, for example on teleport.
|
||||
LLAvatarNameCache *name_cache = LLAvatarNameCache::getInstance();
|
||||
bool had_capability = LLAvatarNameCache::getInstance()->hasNameLookupURL();
|
||||
std::string name_lookup_url;
|
||||
name_lookup_url.reserve(128); // avoid a memory allocation below
|
||||
name_lookup_url = region->getCapability("GetDisplayNames");
|
||||
bool have_capability = !name_lookup_url.empty();
|
||||
if (have_capability)
|
||||
{
|
||||
// we have support for display names, use it
|
||||
U32 url_size = name_lookup_url.size();
|
||||
// capabilities require URLs with slashes before query params:
|
||||
// https://<host>:<port>/cap/<uuid>/?ids=<blah>
|
||||
// but the caps are granted like:
|
||||
// https://<host>:<port>/cap/<uuid>
|
||||
if (url_size > 0 && name_lookup_url[url_size-1] != '/')
|
||||
{
|
||||
name_lookup_url += '/';
|
||||
}
|
||||
name_cache->setNameLookupURL(name_lookup_url);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Display names not available on this region
|
||||
name_cache->setNameLookupURL( std::string() );
|
||||
}
|
||||
|
||||
// Error recovery - did we change state?
|
||||
if (had_capability != have_capability)
|
||||
{
|
||||
// name tags are persistant on screen, so make sure they refresh
|
||||
LLVOAvatar::invalidateNameTags();
|
||||
}
|
||||
|
||||
name_cache->idle();
|
||||
LLAvatarNameCache::getInstance()->idle();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -6144,6 +6206,7 @@ void LLAppViewer::idleNameCache()
|
|||
|
||||
#ifdef TIME_THROTTLE_MESSAGES
|
||||
#define CHECK_MESSAGES_DEFAULT_MAX_TIME .020f // 50 ms = 50 fps (just for messages!)
|
||||
#define CHECK_MESSAGES_MAX_TIME_LIMIT 1.0f // 1 second, a long time but still able to stay connected
|
||||
static F32 CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
|
||||
#endif
|
||||
|
||||
|
|
@ -6209,11 +6272,24 @@ void LLAppViewer::idleNetwork()
|
|||
#ifdef TIME_THROTTLE_MESSAGES
|
||||
if (total_time >= CheckMessagesMaxTime)
|
||||
{
|
||||
// Increase CheckMessagesMaxTime so that we will eventually catch up
|
||||
CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames
|
||||
// <FS:Beq> Don't allow busy network to excessively starve rendering loop
|
||||
// // Increase CheckMessagesMaxTime so that we will eventually catch up
|
||||
// CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
if( CheckMessagesMaxTime < CHECK_MESSAGES_MAX_TIME_LIMIT ) // cap the increase to avoid logout through ping starvation
|
||||
{// Increase CheckMessagesMaxTime so that we will eventually catch up
|
||||
CheckMessagesMaxTime *= 1.035f; // 3.5% ~= x2 in 20 frames, ~8x in 60 frames
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckMessagesMaxTime = CHECK_MESSAGES_MAX_TIME_LIMIT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// </FS:Beq>
|
||||
// Reset CheckMessagesMaxTime to default value
|
||||
CheckMessagesMaxTime = CHECK_MESSAGES_DEFAULT_MAX_TIME;
|
||||
}
|
||||
|
|
@ -6355,6 +6431,21 @@ void LLAppViewer::disconnectViewer()
|
|||
LLUrlEntryParcel::setDisconnected(gDisconnected);
|
||||
}
|
||||
|
||||
// <FS:Ansariel> FIRE-22297: FPS limiter not working properly on Mac/Linux
|
||||
//bool LLAppViewer::onChangeFrameLimit(LLSD const & evt)
|
||||
//{
|
||||
// if (evt.asInteger() > 0)
|
||||
// {
|
||||
// mMinMicroSecPerFrame = (U64)(1000000.0f / F32(evt.asInteger()));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// mMinMicroSecPerFrame = 0;
|
||||
// }
|
||||
// return false;
|
||||
//}
|
||||
// </FS:Ansariel>
|
||||
|
||||
void LLAppViewer::forceErrorLLError()
|
||||
{
|
||||
LL_ERRS() << "This is a deliberate llerror" << LL_ENDL;
|
||||
|
|
@ -6524,7 +6615,7 @@ void LLAppViewer::handleLoginComplete()
|
|||
/*
|
||||
if(gAgent.getRegion())
|
||||
{
|
||||
gDebugInfo["CurrentSimHost"] = gAgent.getRegionHost().getHostName();
|
||||
gDebugInfo["CurrentSimHost"] = gAgent.getRegion()->getSimHostName();
|
||||
gDebugInfo["CurrentRegion"] = gAgent.getRegion()->getName();
|
||||
}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ public:
|
|||
bool quitRequested() { return mQuitRequested; }
|
||||
bool logoutRequestSent() { return mLogoutRequestSent; }
|
||||
bool isSecondInstance() { return mSecondInstance; }
|
||||
bool isUpdaterMissing() { return mUpdaterNotFound; }
|
||||
|
||||
void writeDebugInfo(bool isStatic=true);
|
||||
|
||||
|
|
@ -217,7 +218,9 @@ public:
|
|||
|
||||
// llcorehttp init/shutdown/config information.
|
||||
LLAppCoreHttp & getAppCoreHttp() { return mAppCoreHttp; }
|
||||
|
||||
|
||||
void updateNameLookupUrl();
|
||||
|
||||
protected:
|
||||
virtual bool initWindow(); // Initialize the viewer's window.
|
||||
virtual void initLoggingAndGetLastDuration(); // Initialize log files, logging system
|
||||
|
|
@ -266,11 +269,15 @@ private:
|
|||
void sendLogoutRequest();
|
||||
void disconnectViewer();
|
||||
|
||||
// <FS:Ansariel> FIRE-22297: FPS limiter not working properly on Mac/Linux
|
||||
//bool onChangeFrameLimit(LLSD const & evt);
|
||||
|
||||
// *FIX: the app viewer class should be some sort of singleton, no?
|
||||
// Perhaps its child class is the singleton and this should be an abstract base.
|
||||
static LLAppViewer* sInstance;
|
||||
|
||||
bool mSecondInstance; // Is this a second instance of the app?
|
||||
bool mUpdaterNotFound; // True when attempt to start updater failed
|
||||
|
||||
std::string mMarkerFileName;
|
||||
LLAPRFile mMarkerFile; // A file created to indicate the app is running.
|
||||
|
|
@ -332,7 +339,11 @@ private:
|
|||
// llcorehttp library init/shutdown helper
|
||||
LLAppCoreHttp mAppCoreHttp;
|
||||
|
||||
bool mIsFirstRun;
|
||||
bool mIsFirstRun;
|
||||
// <FS:Ansariel> FIRE-22297: FPS limiter not working properly on Mac/Linux
|
||||
//U64 mMinMicroSecPerFrame; // frame throttling
|
||||
|
||||
|
||||
// <FS:Zi> Backup Settings
|
||||
public:
|
||||
void setSaveSettingsOnExit(bool state) {mSaveSettingsOnExit = state; };
|
||||
|
|
|
|||
|
|
@ -560,8 +560,11 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
|
|||
return false;
|
||||
}
|
||||
bool purge_required = false;
|
||||
|
||||
char buffer[MAX_STRING];
|
||||
// <FS:Beq> FIRE-30705 protect against silly display names that cause lines to exceed max string length
|
||||
// char buffer[MAX_STRING];
|
||||
static constexpr int BUFFER_1K { 1024 }; // long enough to handle the most extreme Unicode nonsense and some to spare
|
||||
char buffer[BUFFER_1K];
|
||||
// </FS:Beq>
|
||||
char conv_name_buffer[MAX_STRING];
|
||||
char part_id_buffer[MAX_STRING];
|
||||
char conv_id_buffer[MAX_STRING];
|
||||
|
|
@ -572,12 +575,21 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
|
|||
// before CHUI-348 it was a flag of conversation voice state
|
||||
int prereserved_unused;
|
||||
|
||||
while (!feof(fp) && fgets(buffer, MAX_STRING, fp))
|
||||
// <FS:Beq/> FIRE-30705 protect against silly display names that cause lines to exceed max string length
|
||||
// while (!feof(fp) && fgets(buffer, MAX_STRING, fp))
|
||||
// {
|
||||
// conv_name_buffer[0] = '\0';
|
||||
// part_id_buffer[0] = '\0';
|
||||
// conv_id_buffer[0] = '\0';
|
||||
memset( buffer, '\0', BUFFER_1K );
|
||||
while (!feof(fp) && fgets(buffer, BUFFER_1K, fp))
|
||||
{
|
||||
conv_name_buffer[0] = '\0';
|
||||
part_id_buffer[0] = '\0';
|
||||
conv_id_buffer[0] = '\0';
|
||||
|
||||
// force blank for added safety
|
||||
memset( conv_name_buffer, '\0', MAX_STRING );
|
||||
memset( part_id_buffer, '\0', MAX_STRING );
|
||||
memset( conv_id_buffer, '\0', MAX_STRING );
|
||||
memset( history_file_name, '\0', MAX_STRING );
|
||||
// </FS:Beq>
|
||||
sscanf(buffer, "[%lld] %d %d %d %[^|]| %s %s %[^|]|",
|
||||
&time,
|
||||
&stype,
|
||||
|
|
@ -615,6 +627,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
|
|||
}
|
||||
|
||||
mConversations.push_back(conversation);
|
||||
memset( buffer, '\0', BUFFER_1K ); // <FS:Beq> FIRE-30705 clear buffer down
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
|
|
|
|||
|
|
@ -612,6 +612,11 @@ bool LLCurrencyUIManager::bought()
|
|||
return impl.mBought;
|
||||
}
|
||||
|
||||
void LLCurrencyUIManager::clearError()
|
||||
{
|
||||
impl.clearError();
|
||||
}
|
||||
|
||||
bool LLCurrencyUIManager::hasError()
|
||||
{
|
||||
return impl.mError;
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ public:
|
|||
bool buying(); // are we in the process of buying?
|
||||
bool bought(); // did the buy() transaction complete successfully
|
||||
|
||||
void clearError();
|
||||
|
||||
bool hasError();
|
||||
std::string errorMessage();
|
||||
std::string errorURI();
|
||||
|
|
|
|||
|
|
@ -1110,7 +1110,7 @@ void LLEnvironment::onRegionChange()
|
|||
}
|
||||
if (!cur_region->capabilitiesReceived())
|
||||
{
|
||||
cur_region->setCapabilitiesReceivedCallback([](LLUUID region_id) { LLEnvironment::instance().requestRegion(); });
|
||||
cur_region->setCapabilitiesReceivedCallback([](const LLUUID ®ion_id) { LLEnvironment::instance().requestRegion(); });
|
||||
return;
|
||||
}
|
||||
requestRegion();
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ BOOL LLFloaterAvatarTextures::postBuild()
|
|||
{
|
||||
for (U32 i=0; i < TEX_NUM_INDICES; i++)
|
||||
{
|
||||
const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(ETextureIndex(i))->mName;
|
||||
const std::string tex_name = LLAvatarAppearance::getDictionary()->getTexture(ETextureIndex(i))->mName;
|
||||
mTextures[i] = getChild<LLTextureCtrl>(tex_name);
|
||||
// <FS:Ansariel> Mask avatar textures and disable
|
||||
mTextures[i]->setIsMasked(TRUE);
|
||||
|
|
@ -85,7 +85,7 @@ static void update_texture_ctrl(LLVOAvatar* avatarp,
|
|||
ETextureIndex te)
|
||||
{
|
||||
LLUUID id = IMG_DEFAULT_AVATAR;
|
||||
const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture(te);
|
||||
const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearance::getDictionary()->getTexture(te);
|
||||
if (tex_entry && tex_entry->mIsLocalTexture)
|
||||
{
|
||||
if (avatarp->isSelf())
|
||||
|
|
@ -180,14 +180,14 @@ void LLFloaterAvatarTextures::onClickDump(void* data)
|
|||
const LLTextureEntry* te = avatarp->getTE(i);
|
||||
if (!te) continue;
|
||||
|
||||
const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)(i));
|
||||
const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearance::getDictionary()->getTexture((ETextureIndex)(i));
|
||||
if (!tex_entry)
|
||||
continue;
|
||||
|
||||
if (LLVOAvatar::isIndexLocalTexture((ETextureIndex)i))
|
||||
{
|
||||
LLUUID id = IMG_DEFAULT_AVATAR;
|
||||
LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType((ETextureIndex)i);
|
||||
LLWearableType::EType wearable_type = LLAvatarAppearance::getDictionary()->getTEWearableType((ETextureIndex)i);
|
||||
if (avatarp->isSelf())
|
||||
{
|
||||
LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, 0);
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ void LLFloaterBuyCurrencyUI::updateUI()
|
|||
#endif
|
||||
// </FS:Beq>
|
||||
LLNotificationsUtil::add("CouldNotBuyCurrency", args);
|
||||
mManager.clearError();
|
||||
closeFloater();
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -59,8 +59,17 @@ BOOL LLFloaterDeletePrefPreset::postBuild()
|
|||
void LLFloaterDeletePrefPreset::onOpen(const LLSD& key)
|
||||
{
|
||||
mSubdirectory = key.asString();
|
||||
std::string floater_title = getString(std::string("title_") + mSubdirectory);
|
||||
setTitle(floater_title);
|
||||
std::string title_type = std::string("title_") + mSubdirectory;
|
||||
if (hasString(title_type))
|
||||
{
|
||||
std::string floater_title = getString(title_type);
|
||||
setTitle(floater_title);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << title_type << " not found" << LL_ENDL;
|
||||
setTitle(title_type);
|
||||
}
|
||||
|
||||
LLComboBox* combo = getChild<LLComboBox>("preset_combo");
|
||||
EDefaultOptions option = DEFAULT_HIDE;
|
||||
|
|
|
|||
|
|
@ -468,19 +468,23 @@ void LLFloaterIMContainer::idleUpdate()
|
|||
const LLConversationItem *current_session = getCurSelectedViewModelItem();
|
||||
if (current_session)
|
||||
{
|
||||
// Update moderator options visibility
|
||||
LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin();
|
||||
LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd();
|
||||
bool is_moderator = isGroupModerator();
|
||||
bool can_ban = haveAbilityToBan();
|
||||
while (current_participant_model != end_participant_model)
|
||||
if (current_session->getType() == LLConversationItem::CONV_SESSION_GROUP)
|
||||
{
|
||||
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
|
||||
participant_model->setModeratorOptionsVisible(is_moderator);
|
||||
participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
|
||||
// Update moderator options visibility
|
||||
LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin();
|
||||
LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd();
|
||||
bool is_moderator = isGroupModerator();
|
||||
bool can_ban = haveAbilityToBan();
|
||||
while (current_participant_model != end_participant_model)
|
||||
{
|
||||
LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
|
||||
participant_model->setModeratorOptionsVisible(is_moderator);
|
||||
participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
|
||||
|
||||
current_participant_model++;
|
||||
current_participant_model++;
|
||||
}
|
||||
}
|
||||
|
||||
// Update floater's title as required by the currently selected session or use the default title
|
||||
LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(current_session->getUUID());
|
||||
setTitle(conversation_floaterp && conversation_floaterp->needsTitleOverwrite() ? conversation_floaterp->getTitle() : mGeneralTitle);
|
||||
|
|
|
|||
|
|
@ -165,7 +165,6 @@ void LLFloaterIMSession::onClickCloseBtn(bool)
|
|||
else
|
||||
{
|
||||
LL_WARNS() << "Empty session with id: " << (mSessionID.asString()) << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLFloaterIMSessionTab::onClickCloseBtn();
|
||||
|
|
|
|||
|
|
@ -40,7 +40,17 @@
|
|||
#include "llviewercontrol.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llviewerjoystick.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llwindow.h"
|
||||
#include "llcheckboxctrl.h"
|
||||
#include "llcombobox.h"
|
||||
|
||||
#if LL_WINDOWS && !LL_MESA_HEADLESS
|
||||
// Require DirectInput version 8
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
|
||||
#include <dinput.h>
|
||||
#endif
|
||||
|
||||
static LLTrace::SampleStatHandle<> sJoystickAxis0("Joystick axis 0"),
|
||||
sJoystickAxis1("Joystick axis 1"),
|
||||
|
|
@ -58,8 +68,33 @@ static LLTrace::SampleStatHandle<>* sJoystickAxes[6] =
|
|||
&sJoystickAxis5
|
||||
};
|
||||
|
||||
|
||||
#if LL_WINDOWS && !LL_MESA_HEADLESS
|
||||
|
||||
BOOL CALLBACK di8_list_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, LPVOID pvRef)
|
||||
{
|
||||
// Note: If a single device can function as more than one DirectInput
|
||||
// device type, it is enumerated as each device type that it supports.
|
||||
// Capable of detecting devices like Oculus Rift
|
||||
if (device_instance_ptr && pvRef)
|
||||
{
|
||||
std::string product_name = utf16str_to_utf8str(llutf16string(device_instance_ptr->tszProductName));
|
||||
S32 size = sizeof(GUID);
|
||||
LLSD::Binary data; //just an std::vector
|
||||
data.resize(size);
|
||||
memcpy(&data[0], &device_instance_ptr->guidInstance /*POD _GUID*/, size);
|
||||
|
||||
LLFloaterJoystick * floater = (LLFloaterJoystick*)pvRef;
|
||||
LLSD value = data;
|
||||
floater->addDevice(product_name, value);
|
||||
}
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
LLFloaterJoystick::LLFloaterJoystick(const LLSD& data)
|
||||
: LLFloater(data)
|
||||
: LLFloater(data),
|
||||
mHasDeviceList(false)
|
||||
{
|
||||
if (!LLViewerJoystick::getInstance()->isJoystickInitialized())
|
||||
{
|
||||
|
|
@ -71,14 +106,13 @@ LLFloaterJoystick::LLFloaterJoystick(const LLSD& data)
|
|||
|
||||
void LLFloaterJoystick::draw()
|
||||
{
|
||||
bool joystick_inited = LLViewerJoystick::getInstance()->isJoystickInitialized();
|
||||
getChildView("enable_joystick")->setEnabled(joystick_inited);
|
||||
getChildView("joystick_type")->setEnabled(joystick_inited);
|
||||
std::string desc = LLViewerJoystick::getInstance()->getDescription();
|
||||
if (desc.empty()) desc = getString("NoDevice");
|
||||
getChild<LLUICtrl>("joystick_type")->setValue(desc);
|
||||
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
|
||||
bool joystick_inited = joystick->isJoystickInitialized();
|
||||
if (joystick_inited != mHasDeviceList)
|
||||
{
|
||||
refreshListOfDevices();
|
||||
}
|
||||
|
||||
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
|
||||
for (U32 i = 0; i < 6; i++)
|
||||
{
|
||||
F32 value = joystick->getJoystickAxis(i);
|
||||
|
|
@ -117,8 +151,8 @@ BOOL LLFloaterJoystick::postBuild()
|
|||
}
|
||||
}
|
||||
|
||||
mCheckJoystickEnabled = getChild<LLCheckBoxCtrl>("enable_joystick");
|
||||
childSetCommitCallback("enable_joystick",onCommitJoystickEnabled,this);
|
||||
mJoysticksCombo = getChild<LLComboBox>("joystick_combo");
|
||||
childSetCommitCallback("joystick_combo",onCommitJoystickEnabled,this);
|
||||
mCheckFlycamEnabled = getChild<LLCheckBoxCtrl>("JoystickFlycamEnabled");
|
||||
childSetCommitCallback("JoystickFlycamEnabled",onCommitJoystickEnabled,this);
|
||||
|
||||
|
|
@ -127,6 +161,7 @@ BOOL LLFloaterJoystick::postBuild()
|
|||
childSetAction("ok_btn", onClickOK, this);
|
||||
|
||||
refresh();
|
||||
refreshListOfDevices();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -143,6 +178,7 @@ void LLFloaterJoystick::apply()
|
|||
void LLFloaterJoystick::initFromSettings()
|
||||
{
|
||||
mJoystickEnabled = gSavedSettings.getBOOL("JoystickEnabled");
|
||||
mJoystickId = gSavedSettings.getLLSD("JoystickDeviceUUID");
|
||||
|
||||
mJoystickAxis[0] = gSavedSettings.getS32("JoystickAxis0");
|
||||
mJoystickAxis[1] = gSavedSettings.getS32("JoystickAxis1");
|
||||
|
|
@ -212,12 +248,80 @@ void LLFloaterJoystick::initFromSettings()
|
|||
void LLFloaterJoystick::refresh()
|
||||
{
|
||||
LLFloater::refresh();
|
||||
|
||||
initFromSettings();
|
||||
}
|
||||
|
||||
void LLFloaterJoystick::addDevice(std::string &name, LLSD& value)
|
||||
{
|
||||
mJoysticksCombo->add(name, value, ADD_BOTTOM, 1);
|
||||
}
|
||||
|
||||
void LLFloaterJoystick::refreshListOfDevices()
|
||||
{
|
||||
mJoysticksCombo->removeall();
|
||||
std::string no_device = getString("JoystickDisabled");
|
||||
LLSD value = LLSD::Integer(0);
|
||||
addDevice(no_device, value);
|
||||
|
||||
mHasDeviceList = false;
|
||||
|
||||
// di8_devices_callback callback is immediate and happens in scope of getInputDevices()
|
||||
#if LL_WINDOWS && !LL_MESA_HEADLESS
|
||||
// space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
|
||||
U32 device_type = DI8DEVCLASS_GAMECTRL;
|
||||
void* callback = &di8_list_devices_callback;
|
||||
#else
|
||||
// MAC doesn't support device search yet
|
||||
// On MAC there is an ndof_idsearch and it is possible to specify product
|
||||
// and manufacturer in NDOF_Device for ndof_init_first to pick specific one
|
||||
U32 device_type = 0;
|
||||
void* callback = NULL;
|
||||
#endif
|
||||
if (gViewerWindow->getWindow()->getInputDevices(device_type, callback, this))
|
||||
{
|
||||
mHasDeviceList = true;
|
||||
}
|
||||
|
||||
bool is_device_id_set = LLViewerJoystick::getInstance()->isDeviceUUIDSet();
|
||||
|
||||
if (LLViewerJoystick::getInstance()->isJoystickInitialized() &&
|
||||
(!mHasDeviceList || !is_device_id_set))
|
||||
{
|
||||
#if LL_WINDOWS && !LL_MESA_HEADLESS
|
||||
LL_WARNS() << "NDOF connected to device without using SL provided handle" << LL_ENDL;
|
||||
#endif
|
||||
std::string desc = LLViewerJoystick::getInstance()->getDescription();
|
||||
if (!desc.empty())
|
||||
{
|
||||
LLSD value = LLSD::Integer(0);
|
||||
addDevice(desc, value);
|
||||
mHasDeviceList = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (gSavedSettings.getBOOL("JoystickEnabled") && mHasDeviceList)
|
||||
{
|
||||
if (is_device_id_set)
|
||||
{
|
||||
LLSD guid = LLViewerJoystick::getInstance()->getDeviceUUID();
|
||||
mJoysticksCombo->selectByValue(guid);
|
||||
}
|
||||
else
|
||||
{
|
||||
mJoysticksCombo->selectByValue(LLSD::Integer(1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mJoysticksCombo->selectByValue(LLSD::Integer(0));
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterJoystick::cancel()
|
||||
{
|
||||
gSavedSettings.setBOOL("JoystickEnabled", mJoystickEnabled);
|
||||
gSavedSettings.setLLSD("JoystickDeviceUUID", mJoystickId);
|
||||
|
||||
gSavedSettings.setS32("JoystickAxis0", mJoystickAxis[0]);
|
||||
gSavedSettings.setS32("JoystickAxis1", mJoystickAxis[1]);
|
||||
|
|
@ -287,7 +391,21 @@ void LLFloaterJoystick::cancel()
|
|||
void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
|
||||
{
|
||||
LLFloaterJoystick* self = (LLFloaterJoystick*)joy_panel;
|
||||
BOOL joystick_enabled = self->mCheckJoystickEnabled->get();
|
||||
|
||||
LLSD value = self->mJoysticksCombo->getValue();
|
||||
bool joystick_enabled = true;
|
||||
if (value.isInteger())
|
||||
{
|
||||
// ndof already has a device selected, we are just setting it enabled or disabled
|
||||
joystick_enabled = value.asInteger();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerJoystick::getInstance()->initDevice(value);
|
||||
// else joystick is enabled, because combobox holds id of device
|
||||
joystick_enabled = true;
|
||||
}
|
||||
gSavedSettings.setBOOL("JoystickEnabled", joystick_enabled);
|
||||
BOOL flycam_enabled = self->mCheckFlycamEnabled->get();
|
||||
|
||||
if (!joystick_enabled || !flycam_enabled)
|
||||
|
|
@ -299,6 +417,12 @@ void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel)
|
|||
joystick->toggleFlycam();
|
||||
}
|
||||
}
|
||||
|
||||
std::string device_id = LLViewerJoystick::getInstance()->getDeviceUUIDString();
|
||||
gSavedSettings.setString("JoystickDeviceUUID", device_id);
|
||||
LL_DEBUGS("Joystick") << "Selected " << device_id << " as joystick." << LL_ENDL;
|
||||
|
||||
self->refreshListOfDevices();
|
||||
}
|
||||
|
||||
void LLFloaterJoystick::onClickRestoreSNDefaults(void *joy_panel)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "llstatview.h"
|
||||
|
||||
class LLCheckBoxCtrl;
|
||||
class LLComboBox;
|
||||
|
||||
class LLFloaterJoystick : public LLFloater
|
||||
{
|
||||
|
|
@ -45,8 +46,11 @@ public:
|
|||
virtual void draw();
|
||||
static void setSNDefaults();
|
||||
|
||||
void addDevice(std::string &name, LLSD& value);
|
||||
|
||||
protected:
|
||||
|
||||
void refreshListOfDevices();
|
||||
void onClose(bool app_quitting);
|
||||
void onClickCloseBtn(bool app_quitting);
|
||||
|
||||
|
|
@ -65,6 +69,7 @@ private:
|
|||
private:
|
||||
// Device prefs
|
||||
bool mJoystickEnabled;
|
||||
LLSD mJoystickId;
|
||||
S32 mJoystickAxis[7];
|
||||
bool m3DCursor;
|
||||
bool mAutoLeveling;
|
||||
|
|
@ -85,8 +90,10 @@ private:
|
|||
F32 mFlycamFeathering;
|
||||
|
||||
// Controls that can disable the flycam
|
||||
LLCheckBoxCtrl *mCheckJoystickEnabled;
|
||||
LLCheckBoxCtrl *mCheckFlycamEnabled;
|
||||
LLComboBox *mJoysticksCombo;
|
||||
|
||||
bool mHasDeviceList;
|
||||
|
||||
// stats view
|
||||
LLStatBar* mAxisStatsBar[6];
|
||||
|
|
|
|||
|
|
@ -58,9 +58,17 @@ BOOL LLFloaterLoadPrefPreset::postBuild()
|
|||
void LLFloaterLoadPrefPreset::onOpen(const LLSD& key)
|
||||
{
|
||||
mSubdirectory = key.asString();
|
||||
std::string floater_title = getString(std::string("title_") + mSubdirectory);
|
||||
|
||||
setTitle(floater_title);
|
||||
std::string title_type = std::string("title_") + mSubdirectory;
|
||||
if (hasString(title_type))
|
||||
{
|
||||
std::string floater_title = getString(title_type);
|
||||
setTitle(floater_title);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << title_type << " not found" << LL_ENDL;
|
||||
setTitle(title_type);
|
||||
}
|
||||
|
||||
LLComboBox* combo = getChild<LLComboBox>("preset_combo");
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ void LLFloaterSidePanelContainer::onOpen(const LLSD& key)
|
|||
void LLFloaterSidePanelContainer::closeFloater(bool app_quitting)
|
||||
{
|
||||
LLPanelOutfitEdit* panel_outfit_edit =
|
||||
dynamic_cast<LLPanelOutfitEdit*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfit_edit"));
|
||||
dynamic_cast<LLPanelOutfitEdit*>(LLFloaterSidePanelContainer::findPanel("appearance", "panel_outfit_edit"));
|
||||
if (panel_outfit_edit)
|
||||
{
|
||||
LLFloater *parent = gFloaterView->getParentFloater(panel_outfit_edit);
|
||||
|
|
@ -171,7 +171,6 @@ LLPanel* LLFloaterSidePanelContainer::getPanel(const std::string& floater_name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Convenience method
|
||||
LLPanel* LLFloaterSidePanelContainer::findPanel(const std::string& floater_name, const std::string& panel_name)
|
||||
{
|
||||
LLFloaterSidePanelContainer* floaterp = LLFloaterReg::findTypedInstance<LLFloaterSidePanelContainer>(floater_name);
|
||||
|
|
@ -183,4 +182,3 @@ LLPanel* LLFloaterSidePanelContainer::findPanel(const std::string& floater_name,
|
|||
|
||||
return NULL;
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
|
|
|||
|
|
@ -67,6 +67,8 @@ public:
|
|||
static void showPanel(const std::string& floater_name, const std::string& panel_name, const LLSD& key);
|
||||
|
||||
static LLPanel* getPanel(const std::string& floater_name, const std::string& panel_name = sMainPanelName);
|
||||
|
||||
static LLPanel* findPanel(const std::string& floater_name, const std::string& panel_name = sMainPanelName);
|
||||
|
||||
/**
|
||||
* Gets the panel of given type T (doesn't show it or do anything else with it).
|
||||
|
|
@ -86,9 +88,6 @@ public:
|
|||
return panel;
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Convenience method
|
||||
static LLPanel* findPanel(const std::string& floater_name, const std::string& panel_name = sMainPanelName);
|
||||
|
||||
template <typename T>
|
||||
static T* findPanel(const std::string& floater_name, const std::string& panel_name = sMainPanelName)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -136,23 +136,14 @@ bool LLGiveInventory::isInventoryGiveAcceptable(const LLInventoryItem* item)
|
|||
switch(item->getType())
|
||||
{
|
||||
case LLAssetType::AT_OBJECT:
|
||||
if (get_is_item_worn(item->getUUID()))
|
||||
{
|
||||
acceptable = false;
|
||||
}
|
||||
break;
|
||||
case LLAssetType::AT_BODYPART:
|
||||
case LLAssetType::AT_CLOTHING:
|
||||
{
|
||||
BOOL copyable = false;
|
||||
if (item->getPermissions().allowCopyBy(gAgentID)) copyable = true;
|
||||
|
||||
if (!copyable && get_is_item_worn(item->getUUID()))
|
||||
if (get_is_item_worn(item->getUUID()))
|
||||
{
|
||||
// worn no-copy items can't be transfered,
|
||||
// but it is valid to transfer a copy of a worn item
|
||||
acceptable = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -2540,6 +2540,19 @@ BOOL LLOutgoingCallDialog::postBuild()
|
|||
// Class LLIncomingCallDialog
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
const std::array<std::string, 4> voice_call_types =
|
||||
{
|
||||
"VoiceInviteP2P",
|
||||
"VoiceInviteGroup",
|
||||
"VoiceInviteAdHoc",
|
||||
"InviteAdHoc"
|
||||
};
|
||||
|
||||
bool is_voice_call_type(const std::string &value)
|
||||
{
|
||||
return std::find(voice_call_types.begin(), voice_call_types.end(), value) != voice_call_types.end();
|
||||
}
|
||||
|
||||
LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) :
|
||||
LLCallDialog(payload),
|
||||
mAvatarNameCacheConnection()
|
||||
|
|
@ -2569,9 +2582,28 @@ BOOL LLIncomingCallDialog::postBuild()
|
|||
{
|
||||
LLCallDialog::postBuild();
|
||||
|
||||
if (!mPayload.isMap() || mPayload.size() == 0)
|
||||
{
|
||||
LL_INFOS("IMVIEW") << "IncomingCall: invalid argument" << LL_ENDL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LLUUID session_id = mPayload["session_id"].asUUID();
|
||||
LLSD caller_id = mPayload["caller_id"];
|
||||
std::string caller_name = mPayload["caller_name"].asString();
|
||||
|
||||
if (session_id.isNull() && caller_id.asUUID().isNull())
|
||||
{
|
||||
LL_INFOS("IMVIEW") << "IncomingCall: invalid ids" << LL_ENDL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
std::string notify_box_type = mPayload["notify_box_type"].asString();
|
||||
if (!is_voice_call_type(notify_box_type))
|
||||
{
|
||||
LL_INFOS("IMVIEW") << "IncomingCall: notify_box_type was not provided" << LL_ENDL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// init notification's lifetime
|
||||
std::istringstream ss( getString("lifetime") );
|
||||
|
|
@ -2588,15 +2620,14 @@ BOOL LLIncomingCallDialog::postBuild()
|
|||
if (gAgent.getGroupData(session_id, data))
|
||||
{
|
||||
args["[GROUP]"] = data.mName;
|
||||
call_type = getString(mPayload["notify_box_type"], args);
|
||||
call_type = getString(notify_box_type, args);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
call_type = getString(mPayload["notify_box_type"]);
|
||||
call_type = getString(notify_box_type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// check to see if this is an Avaline call
|
||||
bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(session_id);
|
||||
if (caller_name == "anonymous")
|
||||
|
|
@ -2626,7 +2657,6 @@ BOOL LLIncomingCallDialog::postBuild()
|
|||
childSetAction("Start IM", onStartIM, this);
|
||||
setDefaultBtn("Accept");
|
||||
|
||||
std::string notify_box_type = mPayload["notify_box_type"].asString();
|
||||
if(notify_box_type != "VoiceInviteGroup" && notify_box_type != "VoiceInviteAdHoc")
|
||||
{
|
||||
// starting notification's timer for P2P and AVALINE invitations
|
||||
|
|
@ -2780,10 +2810,10 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
|
|||
correct_session_name.append(ADHOC_NAME_SUFFIX);
|
||||
}
|
||||
}
|
||||
LL_INFOS() << "Corrected session name is " << correct_session_name << LL_ENDL;
|
||||
LL_INFOS("IMVIEW") << "Corrected session name is " << correct_session_name << LL_ENDL;
|
||||
break;
|
||||
default:
|
||||
LL_WARNS() << "Received an empty session name from a server and failed to generate a new proper session name" << LL_ENDL;
|
||||
LL_WARNS("IMVIEW") << "Received an empty session name from a server and failed to generate a new proper session name" << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -3005,6 +3035,14 @@ void LLIMMgr::addMessage(
|
|||
|
||||
if (new_session)
|
||||
{
|
||||
// Group chat session was initiated by muted resident, do not start this session viewerside
|
||||
// do not send leave msg either, so we are able to get group messages from other participants
|
||||
if ((IM_SESSION_INVITE == dialog) && gAgent.isInGroup(new_session_id) &&
|
||||
LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !from_linden)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
LLAvatarName av_name;
|
||||
if (LLAvatarNameCache::get(other_participant_id, &av_name) && !name_is_setted)
|
||||
{
|
||||
|
|
@ -3087,7 +3125,7 @@ void LLIMMgr::addMessage(
|
|||
LL_WARNS() << "Leaving IM session from initiating muted resident " << from << LL_ENDL;
|
||||
if (!gIMMgr->leaveSession(new_session_id))
|
||||
{
|
||||
LL_INFOS() << "Session " << new_session_id << " does not exist." << LL_ENDL;
|
||||
LL_INFOS("IMVIEW") << "Session " << new_session_id << " does not exist." << LL_ENDL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -3419,7 +3457,7 @@ LLUUID LLIMMgr::addSession(
|
|||
//we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions
|
||||
if (!new_session) return session_id;
|
||||
|
||||
LL_INFOS() << "LLIMMgr::addSession, new session added, name = " << name << ", session id = " << session_id << LL_ENDL;
|
||||
LL_INFOS("IMVIEW") << "LLIMMgr::addSession, new session added, name = " << name << ", session id = " << session_id << LL_ENDL;
|
||||
|
||||
//Per Plan's suggestion commented "explicit offline status warning" out to make Dessie happier (see EXT-3609)
|
||||
//*TODO After February 2010 remove this commented out line if no one will be missing that warning
|
||||
|
|
@ -3479,7 +3517,7 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
|
|||
|
||||
LLIMModel::getInstance()->clearSession(session_id);
|
||||
|
||||
LL_INFOS() << "LLIMMgr::removeSession, session removed, session id = " << session_id << LL_ENDL;
|
||||
LL_INFOS("IMVIEW") << "LLIMMgr::removeSession, session removed, session id = " << session_id << LL_ENDL;
|
||||
|
||||
notifyObserverSessionRemoved(session_id);
|
||||
}
|
||||
|
|
@ -3545,13 +3583,13 @@ void LLIMMgr::inviteToSession(
|
|||
if (LLMuteList::getInstance()->isMuted(caller_id, LLMute::flagVoiceChat)
|
||||
&& voice_invite && "VoiceInviteQuestionDefault" == question_type)
|
||||
{
|
||||
LL_INFOS() << "Rejecting voice call from initiating muted resident " << caller_name << LL_ENDL;
|
||||
LL_INFOS("IMVIEW") << "Rejecting voice call from initiating muted resident " << caller_name << LL_ENDL;
|
||||
LLIncomingCallDialog::processCallResponse(1, payload);
|
||||
return;
|
||||
}
|
||||
else if (LLMuteList::getInstance()->isMuted(caller_id, LLMute::flagAll & ~LLMute::flagVoiceChat) && !voice_invite)
|
||||
{
|
||||
LL_INFOS() << "Rejecting session invite from initiating muted resident " << caller_name << LL_ENDL;
|
||||
LL_INFOS("IMVIEW") << "Rejecting session invite from initiating muted resident " << caller_name << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8455,11 +8455,11 @@ void LLFolderViewGroupedItemBridge::groupFilterContextMenu(folder_view_item_dequ
|
|||
disable_context_entries_if_present(menu, disabled_items);
|
||||
}
|
||||
|
||||
bool LLFolderViewGroupedItemBridge::canWearSelected(uuid_vec_t item_ids)
|
||||
bool LLFolderViewGroupedItemBridge::canWearSelected(const uuid_vec_t& item_ids) const
|
||||
{
|
||||
for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it)
|
||||
{
|
||||
LLViewerInventoryItem* item = gInventory.getItem(*it);
|
||||
const LLViewerInventoryItem* item = gInventory.getItem(*it);
|
||||
// <FS:Ansariel> Fix broken add wearable check
|
||||
//if (!item || (item->getType() >= LLAssetType::AT_COUNT) || (item->getType() <= LLAssetType::AT_NONE))
|
||||
if (!item || (item->getType() != LLAssetType::AT_CLOTHING && item->getType() != LLAssetType::AT_OBJECT && item->getType() != LLAssetType::AT_BODYPART && item->getType() != LLAssetType::AT_GESTURE))
|
||||
|
|
|
|||
|
|
@ -823,7 +823,7 @@ class LLFolderViewGroupedItemBridge: public LLFolderViewGroupedItemModel
|
|||
public:
|
||||
LLFolderViewGroupedItemBridge();
|
||||
virtual void groupFilterContextMenu(folder_view_item_deque& selected_items, LLMenuGL& menu);
|
||||
bool canWearSelected(uuid_vec_t item_ids);
|
||||
bool canWearSelected(const uuid_vec_t& item_ids) const;
|
||||
};
|
||||
|
||||
#endif // LL_LLINVENTORYBRIDGE_H
|
||||
|
|
|
|||
|
|
@ -2700,24 +2700,19 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
|
|||
{
|
||||
bool open_multi_preview = true;
|
||||
|
||||
for (std::set<LLFolderViewItem*>::iterator set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
|
||||
if ("open" == action)
|
||||
{
|
||||
LLFolderViewItem* folder_item = *set_iter;
|
||||
if (folder_item)
|
||||
for (std::set<LLFolderViewItem*>::iterator set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
|
||||
{
|
||||
LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(folder_item->getViewModelItem());
|
||||
// <FS:Ansariel> FIRE-30518: Multi-preview not working for contents of rezzed objects
|
||||
// This should prevent multi-previews of settings, but for object inventory items
|
||||
// this check is always false, since content items in object inventories
|
||||
// have LLTaskInvFVBridges instead of LLInvFVBridges. Since settings can't be
|
||||
// opened from inside objects anyway, so restrict the check for actions performed
|
||||
// on avatar inventories.
|
||||
//if (!bridge || !bridge->isMultiPreviewAllowed())
|
||||
if ("open" == action && (!bridge || !bridge->isMultiPreviewAllowed()))
|
||||
// </FS:Ansariel>
|
||||
LLFolderViewItem* folder_item = *set_iter;
|
||||
if (folder_item)
|
||||
{
|
||||
open_multi_preview = false;
|
||||
break;
|
||||
LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(folder_item->getViewModelItem());
|
||||
if (!bridge || !bridge->isMultiPreviewAllowed())
|
||||
{
|
||||
open_multi_preview = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,7 +161,8 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
|
|||
mShowEmptyMessage(p.show_empty_message),
|
||||
mSuppressFolderMenu(p.suppress_folder_menu),
|
||||
mSuppressOpenItemAction(false),
|
||||
mViewsInitialized(false),
|
||||
mBuildViewsOnInit(p.preinitialize_views),
|
||||
mViewsInitialized(VIEWS_UNINITIALIZED),
|
||||
mInvFVBridgeBuilder(NULL),
|
||||
mInventoryViewModel(p.name),
|
||||
mGroupedItemBridge(new LLFolderViewGroupedItemBridge)
|
||||
|
|
@ -306,14 +307,22 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
|
|||
mCompletionObserver = new LLInvPanelComplObserver(boost::bind(&LLInventoryPanel::onItemsCompletion, this));
|
||||
mInventory->addObserver(mCompletionObserver);
|
||||
|
||||
// Build view of inventory if we need default full hierarchy and inventory ready, otherwise do in onIdle.
|
||||
// Initializing views takes a while so always do it onIdle if viewer already loaded.
|
||||
if (mInventory->isInventoryUsable() && !mViewsInitialized && LLStartUp::getStartupState() <= STATE_WEARABLES_WAIT)
|
||||
{
|
||||
initializeViews();
|
||||
}
|
||||
|
||||
gIdleCallbacks.addFunction(onIdle, (void*)this);
|
||||
if (mBuildViewsOnInit)
|
||||
{
|
||||
// Build view of inventory if we need default full hierarchy and inventory is ready, otherwise do in onIdle.
|
||||
// Initializing views takes a while so always do it onIdle if viewer already loaded.
|
||||
if (mInventory->isInventoryUsable()
|
||||
&& mViewsInitialized == VIEWS_UNINITIALIZED
|
||||
&& LLStartUp::getStartupState() <= STATE_WEARABLES_WAIT)
|
||||
{
|
||||
initializeViews();
|
||||
}
|
||||
else if (mViewsInitialized != VIEWS_INITIALIZING)
|
||||
{
|
||||
mViewsInitialized = VIEWS_INITIALIZING;
|
||||
gIdleCallbacks.addFunction(onIdle, (void*)this);
|
||||
}
|
||||
}
|
||||
|
||||
if (mSortOrderSetting != INHERIT_SORT_ORDER)
|
||||
{
|
||||
|
|
@ -374,6 +383,17 @@ LLInventoryPanel::~LLInventoryPanel()
|
|||
clearFolderRoot();
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
void LLInventoryPanel::onVisibilityChange(BOOL new_visibility)
|
||||
{
|
||||
if (new_visibility && mViewsInitialized == VIEWS_UNINITIALIZED)
|
||||
{
|
||||
mViewsInitialized = VIEWS_INITIALIZING;
|
||||
gIdleCallbacks.addFunction(onIdle, (void*)this);
|
||||
}
|
||||
LLPanel::onVisibilityChange(new_visibility);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::draw()
|
||||
{
|
||||
// Select the desired item (in case it wasn't loaded when the selection was requested)
|
||||
|
|
@ -711,7 +731,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
|
|||
{
|
||||
LL_RECORD_BLOCK_TIME(FTM_REFRESH);
|
||||
|
||||
if (!mViewsInitialized) return;
|
||||
if (mViewsInitialized != VIEWS_INITIALIZED) return;
|
||||
|
||||
const LLInventoryModel* model = getModel();
|
||||
if (!model) return;
|
||||
|
|
@ -777,11 +797,11 @@ void LLInventoryPanel::onIdle(void *userdata)
|
|||
|
||||
LLInventoryPanel *self = (LLInventoryPanel*)userdata;
|
||||
// Inventory just initialized, do complete build
|
||||
if (!self->mViewsInitialized)
|
||||
if (self->mViewsInitialized != VIEWS_INITIALIZED)
|
||||
{
|
||||
self->initializeViews();
|
||||
}
|
||||
if (self->mViewsInitialized)
|
||||
if (self->mViewsInitialized == VIEWS_INITIALIZED)
|
||||
{
|
||||
gIdleCallbacks.deleteFunction(onIdle, (void*)self);
|
||||
}
|
||||
|
|
@ -864,7 +884,7 @@ void LLInventoryPanel::initializeViews()
|
|||
|
||||
gIdleCallbacks.addFunction(idle, this);
|
||||
|
||||
mViewsInitialized = true;
|
||||
mViewsInitialized = VIEWS_INITIALIZED;
|
||||
|
||||
openStartFolderOrMyInventory();
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,10 @@ public:
|
|||
Optional<LLFolderViewFolder::Params> folder;
|
||||
Optional<LLFolderViewItem::Params> item;
|
||||
|
||||
// All item and folder views will be initialized on init if true (default)
|
||||
// Will initialize on visibility change otherwise.
|
||||
Optional<bool> preinitialize_views;
|
||||
|
||||
Params()
|
||||
: sort_order_setting("sort_order_setting"),
|
||||
inventory("", &gInventory),
|
||||
|
|
@ -126,7 +130,8 @@ public:
|
|||
accepts_drag_and_drop("accepts_drag_and_drop"),
|
||||
folder_view("folder_view"),
|
||||
folder("folder"),
|
||||
item("item")
|
||||
item("item"),
|
||||
preinitialize_views("preinitialize_views", true)
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
@ -154,6 +159,7 @@ public:
|
|||
LLFolderViewModelInventory& getRootViewModel() { return mInventoryViewModel; }
|
||||
|
||||
// LLView methods
|
||||
/*virtual*/ void onVisibilityChange(BOOL new_visibility);
|
||||
void draw();
|
||||
/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
|
||||
BOOL handleHover(S32 x, S32 y, MASK mask);
|
||||
|
|
@ -322,7 +328,7 @@ public:
|
|||
void addHideFolderType(LLFolderType::EType folder_type);
|
||||
|
||||
public:
|
||||
BOOL getIsViewsInitialized() const { return mViewsInitialized; }
|
||||
bool getViewsInitialized() const { return mViewsInitialized == VIEWS_INITIALIZED; }
|
||||
|
||||
protected:
|
||||
// Builds the UI. Call this once the inventory is usable.
|
||||
|
|
@ -359,8 +365,15 @@ private:
|
|||
LLFolderViewItem *target_view,
|
||||
LLFolderViewFolder *parent_folder_view);
|
||||
|
||||
bool mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
|
||||
bool mViewsInitialized; // Views have been generated
|
||||
typedef enum e_views_initialization_state
|
||||
{
|
||||
VIEWS_UNINITIALIZED = 0,
|
||||
VIEWS_INITIALIZING,
|
||||
VIEWS_INITIALIZED,
|
||||
} EViewsInitializationState;
|
||||
|
||||
bool mBuildViewsOnInit;
|
||||
EViewsInitializationState mViewsInitialized; // Whether views have been generated
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -308,6 +308,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
|
|||
LLButton::Params maturity_button = p.maturity_button;
|
||||
mMaturityButton = LLUICtrlFactory::create<LLButton>(maturity_button);
|
||||
addChild(mMaturityButton);
|
||||
// <FS:Ansariel> Keep help links
|
||||
mMaturityButton->setClickedCallback(boost::bind(&LLLocationInputCtrl::onMaturityButtonClicked, this));
|
||||
|
||||
LLButton::Params for_sale_button = p.for_sale_button;
|
||||
|
|
@ -705,10 +706,12 @@ void LLLocationInputCtrl::onAgentParcelChange()
|
|||
refresh();
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Keep help links
|
||||
void LLLocationInputCtrl::onMaturityButtonClicked()
|
||||
{
|
||||
LLUI::getInstance()->mHelpImpl->showTopic(mMaturityHelpTopic);
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
void LLLocationInputCtrl::onRegionBoundaryCrossed()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ private:
|
|||
void onForSaleButtonClicked();
|
||||
void onAddLandmarkButtonClicked();
|
||||
void onAgentParcelChange();
|
||||
void onMaturityButtonClicked();
|
||||
void onMaturityButtonClicked(); // <FS:Ansariel> Keep help links
|
||||
void onRegionBoundaryCrossed();
|
||||
void onNavMeshStatusChange(const LLPathfindingNavMeshStatus &pNavMeshStatus);
|
||||
// callbacks
|
||||
|
|
|
|||
|
|
@ -459,6 +459,7 @@ void LLLoginInstance::handleLoginSuccess(const LLSD& event)
|
|||
LL_INFOS("LLLogin") << "LLLoginInstance::handleLoginSuccess" << LL_ENDL;
|
||||
|
||||
attemptComplete();
|
||||
mRequestData.clear();
|
||||
}
|
||||
|
||||
void LLLoginInstance::handleDisconnect(const LLSD& event)
|
||||
|
|
|
|||
|
|
@ -172,6 +172,14 @@ LLMuteList::LLMuteList() :
|
|||
gMessageSystem.callWhenReady(boost::bind(&LLMessageSystem::setHandlerFuncFast, _1,
|
||||
_PREHASH_UseCachedMuteList, processUseCachedMuteList,
|
||||
static_cast<void**>(NULL)));
|
||||
|
||||
// make sure mute list's instance gets initialized before we start any name requests
|
||||
LLAvatarNameCache::getInstance()->setAccountNameChangedCallback([this](const LLUUID& id, const LLAvatarName& av_name)
|
||||
{
|
||||
// it would be better to just pass LLAvatarName instead of doing unnesssesary copies
|
||||
// but this way is just more convinient
|
||||
onAccountNameChanged(id, av_name.getUserName());
|
||||
});
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -182,6 +190,11 @@ LLMuteList::~LLMuteList()
|
|||
|
||||
}
|
||||
|
||||
void LLMuteList::cleanupSingleton()
|
||||
{
|
||||
LLAvatarNameCache::getInstance()->setAccountNameChangedCallback(NULL);
|
||||
}
|
||||
|
||||
BOOL LLMuteList::isLinden(const std::string& name) const
|
||||
{
|
||||
std::string username = boost::replace_all_copy(name, ".", " ");
|
||||
|
|
@ -235,8 +248,8 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
|
|||
LL_WARNS() << "Trying to self; ignored" << LL_ENDL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
S32 mute_list_limit = gSavedSettings.getS32("MuteListLimit");
|
||||
|
||||
static LLCachedControl<S32> mute_list_limit(gSavedSettings, "MuteListLimit", 1000);
|
||||
if (getMutes().size() >= mute_list_limit)
|
||||
{
|
||||
LL_WARNS() << "Mute limit is reached; ignored" << LL_ENDL;
|
||||
|
|
@ -376,6 +389,10 @@ void LLMuteList::updateAdd(const LLMute& mute, bool show_message /* = true */)
|
|||
msg->addU32("MuteFlags", mute.mFlags);
|
||||
gAgent.sendReliableMessage();
|
||||
|
||||
if (!mIsLoaded)
|
||||
{
|
||||
LL_WARNS() << "Added elements to non-initialized block list" << LL_ENDL;
|
||||
}
|
||||
mIsLoaded = TRUE; // why is this here? -MG
|
||||
|
||||
// <FS:Ansariel> FIRE-15746: Show block report in nearby chat
|
||||
|
|
@ -418,6 +435,8 @@ BOOL LLMuteList::remove(const LLMute& mute, U32 flags)
|
|||
else
|
||||
{
|
||||
// The caller didn't pass any flags -- just remove the mute entry entirely.
|
||||
// set flags to notify observers with (flag being present means that something is allowed)
|
||||
localmute.mFlags = LLMute::flagAll;
|
||||
}
|
||||
|
||||
// Always remove the entry from the set -- it will be re-added with new flags if necessary.
|
||||
|
|
@ -441,8 +460,8 @@ BOOL LLMuteList::remove(const LLMute& mute, U32 flags)
|
|||
}
|
||||
|
||||
// Must be after erase.
|
||||
notifyObservers();
|
||||
notifyObserversDetailed(localmute);
|
||||
setLoaded(); // why is this here? -MG
|
||||
|
||||
// <FS:Ansariel> Return correct return value
|
||||
found = TRUE;
|
||||
|
|
@ -458,8 +477,8 @@ BOOL LLMuteList::remove(const LLMute& mute, U32 flags)
|
|||
updateRemove(mute);
|
||||
mLegacyMutes.erase(legacy_it);
|
||||
// Must be after erase.
|
||||
notifyObservers();
|
||||
notifyObserversDetailed(mute);
|
||||
setLoaded(); // why is this here? -MG
|
||||
|
||||
// <FS:Ansariel> Return correct return value
|
||||
found = TRUE;
|
||||
|
|
@ -629,6 +648,19 @@ BOOL LLMuteList::loadFromFile(const std::string& filename)
|
|||
}
|
||||
fclose(fp);
|
||||
setLoaded();
|
||||
|
||||
// server does not maintain up-to date account names (not display names!)
|
||||
// in this list, so it falls to viewer.
|
||||
pending_names_t::iterator iter = mPendingAgentNameUpdates.begin();
|
||||
pending_names_t::iterator end = mPendingAgentNameUpdates.end();
|
||||
while (iter != end)
|
||||
{
|
||||
// this will send updates to server, make sure mIsLoaded is set
|
||||
onAccountNameChanged(iter->first, iter->second);
|
||||
iter++;
|
||||
}
|
||||
mPendingAgentNameUpdates.clear();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -828,6 +860,48 @@ void LLMuteList::onFileMuteList(void** user_data, S32 error_code, LLExtStat ext_
|
|||
delete local_filename_and_path;
|
||||
}
|
||||
|
||||
void LLMuteList::onAccountNameChanged(const LLUUID& id, const std::string& username)
|
||||
{
|
||||
if (mIsLoaded)
|
||||
{
|
||||
LLMute mute(id, username, LLMute::AGENT);
|
||||
mute_set_t::iterator mute_it = mMutes.find(mute);
|
||||
if (mute_it != mMutes.end()
|
||||
&& mute_it->mName != mute.mName
|
||||
&& mute_it->mType == LLMute::AGENT) // just in case, it is std::set, not map
|
||||
{
|
||||
// existing mute, but name changed, copy data
|
||||
mute.mFlags = mute_it->mFlags;
|
||||
|
||||
// erase old variant
|
||||
mMutes.erase(mute_it);
|
||||
|
||||
// (re)add the mute entry.
|
||||
{
|
||||
std::pair<mute_set_t::iterator, bool> result = mMutes.insert(mute);
|
||||
if (result.second)
|
||||
{
|
||||
LL_INFOS() << "Muting " << mute.mName << " id " << mute.mID << " flags " << mute.mFlags << LL_ENDL;
|
||||
updateAdd(mute);
|
||||
// Do not notify observers here, observers do not know or need to handle name changes
|
||||
// Example: block list considers notifyObserversDetailed as a selection update;
|
||||
// Various chat/voice statuses care only about id and flags
|
||||
// Since apropriate update time for account names is considered to be in 'hours' it is
|
||||
// fine not to update UI (will be fine after restart or couple other changes)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Delay update until we load file
|
||||
// Ex: Buddies list can arrive too early since we prerequest
|
||||
// names from Buddies list before we load blocklist
|
||||
mPendingAgentNameUpdates[id] = username;
|
||||
}
|
||||
}
|
||||
|
||||
void LLMuteList::addObserver(LLMuteListObserver* observer)
|
||||
{
|
||||
mObservers.insert(observer);
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ class LLMuteList : public LLSingleton<LLMuteList>
|
|||
{
|
||||
LLSINGLETON(LLMuteList);
|
||||
~LLMuteList();
|
||||
/*virtual*/ void cleanupSingleton();
|
||||
public:
|
||||
// reasons for auto-unmuting a resident
|
||||
enum EAutoReason
|
||||
|
|
@ -134,6 +135,7 @@ private:
|
|||
static void processUseCachedMuteList(LLMessageSystem* msg, void**);
|
||||
|
||||
static void onFileMuteList(void** user_data, S32 code, LLExtStat ext_status);
|
||||
void onAccountNameChanged(const LLUUID& id, const std::string& username);
|
||||
|
||||
private:
|
||||
struct compare_by_name
|
||||
|
|
@ -158,7 +160,9 @@ private:
|
|||
};
|
||||
typedef std::set<LLMute, compare_by_id> mute_set_t;
|
||||
mute_set_t mMutes;
|
||||
|
||||
typedef std::map<LLUUID, std::string> pending_names_t;
|
||||
pending_names_t mPendingAgentNameUpdates;
|
||||
|
||||
typedef std::set<std::string> string_set_t;
|
||||
string_set_t mLegacyMutes;
|
||||
|
||||
|
|
|
|||
|
|
@ -351,10 +351,14 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
|
|||
}
|
||||
}
|
||||
|
||||
void LLOutputMonitorCtrl::onChange()
|
||||
void LLOutputMonitorCtrl::onChangeDetailed(const LLMute& mute)
|
||||
{
|
||||
// check only blocking on voice. EXT-3542
|
||||
mIsMuted = LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat);
|
||||
if (mute.mID == mSpeakerId)
|
||||
{
|
||||
// Check only blocking on voice.
|
||||
// Logic goes in reverse, if flag is set, action is allowed
|
||||
mIsMuted = !(LLMute::flagVoiceChat & mute.mFlags);
|
||||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
|
|||
|
|
@ -108,7 +108,8 @@ public:
|
|||
void setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id = LLUUID::null, bool show_other_participants_speaking = false);
|
||||
|
||||
//called by mute list
|
||||
virtual void onChange();
|
||||
virtual void onChange() {};
|
||||
virtual void onChangeDetailed(const LLMute& mute);
|
||||
|
||||
/**
|
||||
* Implementation of LLSpeakingIndicator interface.
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include "lltrans.h"
|
||||
#include "llviewerassettype.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llviewermenu.h" // <FS> Script reset in edit floater
|
||||
#include "llviewerobject.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewerwindow.h"
|
||||
|
|
@ -86,6 +87,7 @@ BOOL LLPanelContents::postBuild()
|
|||
|
||||
childSetAction("button new script",&LLPanelContents::onClickNewScript, this);
|
||||
childSetAction("button permissions",&LLPanelContents::onClickPermissions, this);
|
||||
childSetAction("btn_reset_scripts", &LLPanelContents::onClickResetScripts, this); // <FS> Script reset in edit floater
|
||||
childSetAction("button refresh",&LLPanelContents::onClickRefresh, this);
|
||||
|
||||
mPanelInventoryObject = getChild<LLPanelObjectInventory>("contents_inventory");
|
||||
|
|
@ -111,7 +113,7 @@ void LLPanelContents::getState(LLViewerObject *objectp )
|
|||
if( !objectp )
|
||||
{
|
||||
getChildView("button new script")->setEnabled(FALSE);
|
||||
getChildView("button reset scripts")->setEnabled(FALSE);
|
||||
getChildView("btn_reset_scripts")->setEnabled(FALSE); // <FS> Script reset in edit floater
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -143,21 +145,22 @@ void LLPanelContents::getState(LLViewerObject *objectp )
|
|||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
// Edit/reset script buttons - ok if object is editable and there's an unambiguous destination for the object.
|
||||
// Edit script buttons - ok if object is editable and there's an unambiguous destination for the object.
|
||||
// <FS:PP> FIRE-3219: Reset Scripts button in Build floater
|
||||
// getChildView("button new script")->setEnabled(
|
||||
// editable &&
|
||||
// all_volume &&
|
||||
// ((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
|
||||
// || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)));
|
||||
bool objectIsOK = FALSE;
|
||||
|
||||
BOOL objectIsOK = FALSE;
|
||||
if( editable && all_volume && ( (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1) || (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1) ) )
|
||||
{
|
||||
objectIsOK = TRUE;
|
||||
}
|
||||
|
||||
getChildView("button new script")->setEnabled(objectIsOK);
|
||||
getChildView("button reset scripts")->setEnabled(objectIsOK);
|
||||
getChildView("btn_reset_scripts")->setEnabled(objectIsOK);
|
||||
// </FS:PP>
|
||||
|
||||
getChildView("button permissions")->setEnabled(!objectp->isPermanentEnforced());
|
||||
|
|
@ -257,6 +260,14 @@ void LLPanelContents::onClickPermissions(void *userdata)
|
|||
gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterReg::showInstance("bulk_perms"));
|
||||
}
|
||||
|
||||
// <FS> Script reset in edit floater
|
||||
// static
|
||||
void LLPanelContents::onClickResetScripts(void *userdata)
|
||||
{
|
||||
handle_selected_script_action("reset");
|
||||
}
|
||||
// </FS>
|
||||
|
||||
// static
|
||||
void LLPanelContents::onClickRefresh(void *userdata)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ public:
|
|||
|
||||
static void onClickNewScript(void*);
|
||||
static void onClickPermissions(void*);
|
||||
static void onClickResetScripts(void*); // <FS> Script reset in edit floater
|
||||
static void onClickRefresh(void*);
|
||||
|
||||
// Key suffix for "tentative" fields
|
||||
|
|
|
|||
|
|
@ -667,6 +667,13 @@ void LLPanelGroup::draw()
|
|||
{
|
||||
LLPanel::draw();
|
||||
|
||||
// <FS:Beq> FIRE-30667 - group hang fixes
|
||||
LLPanelGroupNotices* panel_notices = findChild<LLPanelGroupNotices>("group_notices_tab_panel");
|
||||
if(panel_notices)
|
||||
{
|
||||
panel_notices->updateSelected();
|
||||
}
|
||||
// </FS:Beq>
|
||||
if (mRefreshTimer.hasExpired())
|
||||
{
|
||||
mRefreshTimer.stop();
|
||||
|
|
|
|||
|
|
@ -203,15 +203,15 @@ std::string build_notice_date(const U32& the_time)
|
|||
time(&t);
|
||||
}
|
||||
|
||||
// <FS:Ansariel> FIRE-17649: Localizable date formats for group notices
|
||||
//std::string dateStr = "["+LLTrans::getString("LTimeYear")+"]/["
|
||||
// +LLTrans::getString("LTimeMthNum")+"]/["
|
||||
// +LLTrans::getString("LTimeDay")+"] ["
|
||||
// +LLTrans::getString("LTimeHour")+"]:["
|
||||
// +LLTrans::getString("LTimeMin")+"]:["
|
||||
// +LLTrans::getString("LTimeSec")+"]";
|
||||
std::string dateStr = LLTrans::getString("GroupNoticesPanelDateString");
|
||||
// </FS:Ansariel>
|
||||
// <FS:Ansariel> FIRE-17649: Localizable date formats for group notices
|
||||
//std::string dateStr = "["+ LLTrans::getString("LTimeYear") + "]/["
|
||||
// + LLTrans::getString("LTimeMthNum") + "]/["
|
||||
// + LLTrans::getString("LTimeDay") + "] ["
|
||||
// + LLTrans::getString("LTimeHour") + "]:["
|
||||
// + LLTrans::getString("LTimeMin") + "]:["
|
||||
// + LLTrans::getString("LTimeSec") + "]";
|
||||
std::string dateStr = LLTrans::getString("GroupNoticesPanelDateString");
|
||||
// </FS:Ansariel>
|
||||
|
||||
LLSD substitution;
|
||||
substitution["datetime"] = (S32) t;
|
||||
|
|
@ -473,6 +473,8 @@ void LLPanelGroupNotices::clearNoticeList()
|
|||
{
|
||||
mPrevSelectedNotice = mNoticesList->getStringUUIDSelectedItem();
|
||||
mNoticesList->deleteAllItems();
|
||||
// <FS:Beq/> FIRE-30766 group hang prevention.
|
||||
mNoticeIDs.clear();
|
||||
}
|
||||
|
||||
void LLPanelGroupNotices::onClickRefreshNotices(void* data)
|
||||
|
|
@ -536,7 +538,8 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
|
|||
|
||||
//save sort state and set unsorted state to prevent unnecessary
|
||||
//sorting while adding notices
|
||||
bool save_sort = mNoticesList->isSorted();
|
||||
// <FS:Beq> FIRE-30667 et al. we will need sorting at the end
|
||||
// bool save_sort = mNoticesList->isSorted();
|
||||
mNoticesList->setNeedsSort(false);
|
||||
|
||||
for (;i<count;++i)
|
||||
|
|
@ -552,9 +555,12 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
|
|||
|
||||
//with some network delays we can receive notice list more then once...
|
||||
//so add only unique notices
|
||||
S32 pos = mNoticesList->getItemIndex(id);
|
||||
|
||||
if(pos!=-1)//if items with this ID already in the list - skip it
|
||||
// <FS:Beq> FIRE-30667 et al. add a set for tracking to avoid the linear time lookup
|
||||
// S32 pos = mNoticesList->getItemIndex(id);
|
||||
// if(pos!=-1)//if items with this ID already in the list - skip it
|
||||
auto exists = mNoticeIDs.emplace(id);
|
||||
if (!exists.second)
|
||||
// </FS:Beq>
|
||||
continue;
|
||||
|
||||
msg->getString("Data","Subject",subj,i);
|
||||
|
|
@ -596,15 +602,32 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
|
|||
mNoticesList->addElement(row, ADD_BOTTOM);
|
||||
}
|
||||
|
||||
mNoticesList->setNeedsSort(save_sort);
|
||||
mNoticesList->updateSort();
|
||||
if (mPanelViewNotice->getVisible())
|
||||
mNoticesList->setNeedsSort(true);
|
||||
// <FS:Beq> FIRE-30667 et al. defer sorting and updating selection
|
||||
// mNoticesList->updateSort();
|
||||
// if (mPanelViewNotice->getVisible())
|
||||
// {
|
||||
// if (!mNoticesList->selectByID(mPrevSelectedNotice))
|
||||
// {
|
||||
// mNoticesList->selectFirstItem();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void LLPanelGroupNotices::updateSelected()
|
||||
{
|
||||
if( mNoticesList->mLastUpdateFrame == 0 )
|
||||
{
|
||||
if (!mNoticesList->selectByID(mPrevSelectedNotice))
|
||||
if (mPanelViewNotice->getVisible())
|
||||
{
|
||||
mNoticesList->selectFirstItem();
|
||||
if (!mNoticesList->selectByID(mPrevSelectedNotice))
|
||||
{
|
||||
mNoticesList->selectFirstItem();
|
||||
}
|
||||
}
|
||||
mNoticesList->mLastUpdateFrame = 1;
|
||||
}
|
||||
// </FS:Beq>
|
||||
}
|
||||
|
||||
void LLPanelGroupNotices::onSelectNotice(LLUICtrl* ctrl, void* data)
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ public:
|
|||
LLOfferInfo* inventory_offer);
|
||||
|
||||
void refreshNotices();
|
||||
void updateSelected(); // FS:Beq FIRE-30667 group notices hang
|
||||
|
||||
void clearNoticeList();
|
||||
|
||||
|
|
@ -111,6 +112,7 @@ private:
|
|||
//LLIconCtrl *mViewInventoryIcon;
|
||||
|
||||
LLScrollListCtrl *mNoticesList;
|
||||
std::set<LLUUID> mNoticeIDs; // FS:Beq FIRE-30667 group notices hang
|
||||
|
||||
std::string mNoNoticesStr;
|
||||
|
||||
|
|
|
|||
|
|
@ -1349,8 +1349,10 @@ void LLPanelLogin::onSelectServer()
|
|||
switch (index)
|
||||
{
|
||||
case 0: // last location
|
||||
LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_LAST));
|
||||
break;
|
||||
case 1: // home location
|
||||
// do nothing - these are grid-agnostic locations
|
||||
LLStartUp::setStartSLURL(LLSLURL(LLSLURL::SIM_LOCATION_HOME));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -234,6 +234,7 @@ BOOL LLPanelMainInventory::postBuild()
|
|||
recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER));
|
||||
// </FS:Zi>
|
||||
recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
//recent_items_panel->setFilterLinks(LLInventoryFilter::FILTERLINK_EXCLUDE_LINKS); // <FS:Ansariel> Undo nonsense change
|
||||
LLInventoryFilter& recent_filter = recent_items_panel->getFilter();
|
||||
recent_filter.setFilterObjectTypes(recent_filter.getFilterObjectTypes() & ~(0x1 << LLInventoryType::IT_CATEGORY));
|
||||
recent_filter.setEmptyLookupMessage("InventoryNoMatchingRecentItems");
|
||||
|
|
|
|||
|
|
@ -574,6 +574,8 @@ BOOL LLPanelOutfitEdit::postBuild()
|
|||
mAvatarComplexityAddingLabel = getChild<LLTextBox>("avatar_complexity_adding_label");
|
||||
|
||||
mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));
|
||||
|
||||
onOutfitChanging(gAgentWearables.isCOFChangeInProgress());
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -718,6 +720,10 @@ void LLPanelOutfitEdit::onListViewFilterCommitted(LLUICtrl* ctrl)
|
|||
S32 curr_filter_type = mListViewFilterCmbBox->getCurrentIndex();
|
||||
if (curr_filter_type < 0) return;
|
||||
|
||||
if (curr_filter_type >= LVIT_SHAPE)
|
||||
{
|
||||
mWearableItemsList->setMenuWearableType(LLWearableType::EType(curr_filter_type - LVIT_SHAPE));
|
||||
}
|
||||
mWearableListManager->setFilterCollector(mListViewItemTypes[curr_filter_type]->collector);
|
||||
}
|
||||
|
||||
|
|
@ -1297,6 +1303,7 @@ void LLPanelOutfitEdit::showFilteredWearablesListView(LLWearableType::EType type
|
|||
|
||||
//e_list_view_item_type implicitly contains LLWearableType::EType starting from LVIT_SHAPE
|
||||
applyListViewFilter(static_cast<EListViewItemType>(LVIT_SHAPE + type));
|
||||
mWearableItemsList->setMenuWearableType(type);
|
||||
}
|
||||
|
||||
static void update_status_widget_rect(LLView * widget, S32 right_border)
|
||||
|
|
|
|||
|
|
@ -630,7 +630,7 @@ void LLPanelPermissions::refresh()
|
|||
}
|
||||
else
|
||||
{
|
||||
// FIRE-777: allow batch edit for name and description
|
||||
// FIRE-777: allow batch edit for name and description
|
||||
// getChild<LLUICtrl>("Object Name")->setValue(LLStringUtil::null);
|
||||
// LineEditorObjectDesc->setText(LLStringUtil::null);
|
||||
if (keyboard_focus_view != LineEditorObjectName)
|
||||
|
|
@ -650,7 +650,7 @@ void LLPanelPermissions::refresh()
|
|||
|
||||
// figure out the contents of the name, description, & category
|
||||
BOOL edit_name_desc = FALSE;
|
||||
// FIRE-777: allow batch edit for name and description
|
||||
// FIRE-777: allow batch edit for name and description
|
||||
// if (is_one_object && objectp->permModify() && !objectp->isPermanentEnforced())
|
||||
if (objectp->permModify())
|
||||
// /FIRE-777
|
||||
|
|
@ -910,7 +910,7 @@ void LLPanelPermissions::refresh()
|
|||
getChildView("checkbox allow everyone copy")->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
// <FS:CR> Opensim export permissions - Codeblock courtesy of Liru Færs.
|
||||
// <FS:CR> Opensim export permissions - Codeblock courtesy of Liru Færs.
|
||||
// Is this user allowed to toggle export on this object?
|
||||
if (LFSimFeatureHandler::instance().simSupportsExport()
|
||||
&& self_owned && mCreatorID == mOwnerID
|
||||
|
|
@ -1173,13 +1173,45 @@ void LLPanelPermissions::refresh()
|
|||
getChildView("clickaction")->setEnabled(is_perm_modify && is_nonpermanent_enforced && all_volume);
|
||||
}
|
||||
|
||||
//// Shorten name if it doesn't fit into max_pixels of two lines
|
||||
//void shorten_name(std::string &name, const LLStyle::Params& style_params, S32 max_pixels)
|
||||
//{
|
||||
// const LLFontGL* font = style_params.font();
|
||||
//
|
||||
// LLWString wline = utf8str_to_wstring(name);
|
||||
// // panel supports two lines long names
|
||||
// S32 segment_length = font->maxDrawableChars(wline.c_str(), max_pixels, wline.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE);
|
||||
// if (segment_length == wline.length())
|
||||
// {
|
||||
// // no work needed
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// S32 first_line_length = segment_length;
|
||||
// segment_length = font->maxDrawableChars(wline.substr(first_line_length).c_str(), max_pixels, wline.length(), LLFontGL::ANYWHERE);
|
||||
// if (segment_length + first_line_length == wline.length())
|
||||
// {
|
||||
// // no work needed
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // name does not fit, cut it, add ...
|
||||
// const LLWString dots_pad(utf8str_to_wstring(std::string("....")));
|
||||
// S32 elipses_width = font->getWidthF32(dots_pad.c_str());
|
||||
// segment_length = font->maxDrawableChars(wline.substr(first_line_length).c_str(), max_pixels - elipses_width, wline.length(), LLFontGL::ANYWHERE);
|
||||
//
|
||||
// name = name.substr(0, segment_length + first_line_length) + std::string("...");
|
||||
//}
|
||||
//
|
||||
//void LLPanelPermissions::updateOwnerName(const LLUUID& owner_id, const LLAvatarName& owner_name, const LLStyle::Params& style_params)
|
||||
//{
|
||||
// if (mOwnerCacheConnection.connected())
|
||||
// {
|
||||
// mOwnerCacheConnection.disconnect();
|
||||
// }
|
||||
// mLabelOwnerName->setText(owner_name.getCompleteName(), style_params);
|
||||
// std::string name = owner_name.getCompleteName();
|
||||
// shorten_name(name, style_params, mLabelOwnerName->getLocalRect().getWidth());
|
||||
// mLabelOwnerName->setText(name, style_params);
|
||||
//}
|
||||
//
|
||||
//void LLPanelPermissions::updateCreatorName(const LLUUID& creator_id, const LLAvatarName& creator_name, const LLStyle::Params& style_params)
|
||||
|
|
@ -1188,7 +1220,9 @@ void LLPanelPermissions::refresh()
|
|||
// {
|
||||
// mCreatorCacheConnection.disconnect();
|
||||
// }
|
||||
// mLabelCreatorName->setText(creator_name.getCompleteName(), style_params);
|
||||
// std::string name = creator_name.getCompleteName();
|
||||
// shorten_name(name, style_params, mLabelCreatorName->getLocalRect().getWidth());
|
||||
// mLabelCreatorName->setText(name, style_params);
|
||||
//}
|
||||
|
||||
// static
|
||||
|
|
|
|||
|
|
@ -798,8 +798,10 @@ void LLScriptEdCore::initMenu()
|
|||
menuItem = getChild<LLMenuItemCallGL>("Go to line...");
|
||||
menuItem->setClickCallback(boost::bind(&LLFloaterGotoLine::show, this));
|
||||
|
||||
// <FS:Ansariel> Keep help links
|
||||
menuItem = getChild<LLMenuItemCallGL>("Help...");
|
||||
menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnHelp, this));
|
||||
// </FS:Ansariel>
|
||||
|
||||
menuItem = getChild<LLMenuItemCallGL>("Keyword Help...");
|
||||
menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnDynamicHelp, this));
|
||||
|
|
@ -1362,10 +1364,12 @@ bool LLScriptEdCore::handleSaveChangesDialog(const LLSD& notification, const LLS
|
|||
return false;
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Keep help links
|
||||
void LLScriptEdCore::onBtnHelp()
|
||||
{
|
||||
LLUI::getInstance()->mHelpImpl->showTopic(HELP_LSL_PORTAL_TOPIC);
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
void LLScriptEdCore::onBtnDynamicHelp()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ private:
|
|||
void performAction(const std::string& action);
|
||||
bool enableAction(const std::string& action);
|
||||
// NaCl End
|
||||
void onBtnHelp();
|
||||
void onBtnHelp(); // <FS:Ansariel> Keep help links
|
||||
void onBtnDynamicHelp();
|
||||
void onBtnUndoChanges();
|
||||
|
||||
|
|
|
|||
|
|
@ -577,7 +577,7 @@ void LLPreviewTexture::onFileLoadedForSaveTGA(BOOL success,
|
|||
// <FS:Ansariel> Undo MAINT-2897 and use our own texture format selection
|
||||
//const U32 ext_length = 3;
|
||||
//std::string extension = self->mSaveFileName.substr( self->mSaveFileName.length() - ext_length);
|
||||
|
||||
//LLStringUtil::toLower(extension);
|
||||
//// We only support saving in PNG or TGA format
|
||||
//LLPointer<LLImageFormatted> image;
|
||||
//if(extension == "png")
|
||||
|
|
|
|||
|
|
@ -513,9 +513,10 @@ void LLProgressView::initLogos()
|
|||
|
||||
// 108x41
|
||||
icon_width = 74;
|
||||
icon_height = default_height;
|
||||
loadLogo(temp_str + "vivox_logo.png",
|
||||
image_codec,
|
||||
LLRect(texture_start_x, texture_start_y + default_height, texture_start_x + icon_width, texture_start_y),
|
||||
LLRect(texture_start_x, texture_start_y + icon_height, texture_start_x + icon_width, texture_start_y),
|
||||
default_clip,
|
||||
default_clip);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -526,8 +526,7 @@ void LLSceneMonitor::fetchQueryResult()
|
|||
|
||||
//dump results to a file _scene_xmonitor_results.csv
|
||||
void LLSceneMonitor::dumpToFile(std::string file_name)
|
||||
{ using namespace LLTrace;
|
||||
|
||||
{
|
||||
if (!hasResults()) return;
|
||||
|
||||
LL_INFOS("SceneMonitor") << "Saving scene load stats to " << file_name << LL_ENDL;
|
||||
|
|
@ -536,7 +535,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
|
|||
|
||||
os << std::setprecision(10);
|
||||
|
||||
PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults();
|
||||
LLTrace::PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults();
|
||||
const U32 frame_count = scene_load_recording.getNumRecordedPeriods();
|
||||
|
||||
F64Seconds frame_time;
|
||||
|
|
@ -558,7 +557,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
|
|||
os << '\n';
|
||||
|
||||
|
||||
typedef StatType<CountAccumulator> trace_count;
|
||||
typedef LLTrace::StatType<LLTrace::CountAccumulator> trace_count;
|
||||
for (auto& it : trace_count::instance_snapshot())
|
||||
{
|
||||
std::ostringstream row;
|
||||
|
|
@ -576,7 +575,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
|
|||
|
||||
for (S32 frame = 1; frame <= frame_count; frame++)
|
||||
{
|
||||
Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
|
||||
LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
|
||||
samples += recording.getSampleCount(it);
|
||||
row << ", " << recording.getSum(it);
|
||||
}
|
||||
|
|
@ -589,7 +588,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
|
|||
}
|
||||
}
|
||||
|
||||
typedef StatType<EventAccumulator> trace_event;
|
||||
typedef LLTrace::StatType<LLTrace::EventAccumulator> trace_event;
|
||||
|
||||
for (auto& it : trace_event::instance_snapshot())
|
||||
{
|
||||
|
|
@ -607,7 +606,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
|
|||
|
||||
for (S32 frame = 1; frame <= frame_count; frame++)
|
||||
{
|
||||
Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
|
||||
LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
|
||||
samples += recording.getSampleCount(it);
|
||||
F64 mean = recording.getMean(it);
|
||||
if (llisnan(mean))
|
||||
|
|
@ -628,7 +627,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
|
|||
}
|
||||
}
|
||||
|
||||
typedef StatType<SampleAccumulator> trace_sample;
|
||||
typedef LLTrace::StatType<LLTrace::SampleAccumulator> trace_sample;
|
||||
|
||||
for (auto& it : trace_sample::instance_snapshot())
|
||||
{
|
||||
|
|
@ -646,7 +645,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
|
|||
|
||||
for (S32 frame = 1; frame <= frame_count; frame++)
|
||||
{
|
||||
Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
|
||||
LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
|
||||
samples += recording.getSampleCount(it);
|
||||
F64 mean = recording.getMean(it);
|
||||
if (llisnan(mean))
|
||||
|
|
@ -667,7 +666,7 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
|
|||
}
|
||||
}
|
||||
|
||||
typedef StatType<MemAccumulator> trace_mem;
|
||||
typedef LLTrace::StatType<LLTrace::MemAccumulator> trace_mem;
|
||||
for (auto& it : trace_mem::instance_snapshot())
|
||||
{
|
||||
os << it.getName() << "(KiB)";
|
||||
|
|
|
|||
|
|
@ -145,6 +145,8 @@ BOOL LLSidepanelAppearance::postBuild()
|
|||
|
||||
setVisibleCallback(boost::bind(&LLSidepanelAppearance::onVisibilityChanged,this,_2));
|
||||
|
||||
setWearablesLoading(gAgentWearables.isCOFChangeInProgress());
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1011,8 +1011,8 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
|
|||
}
|
||||
|
||||
LLSpatialGroup* group = drawablep->getSpatialGroup();
|
||||
llassert(group != NULL);
|
||||
|
||||
// <FS:Beq/> avoid crash for race condition with unseating of an avatar
|
||||
// llassert(group != NULL);
|
||||
if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING))
|
||||
{
|
||||
group->setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS);
|
||||
|
|
|
|||
|
|
@ -2135,46 +2135,6 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
|
|||
return raw;
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
|
||||
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
|
||||
|
||||
U32 exception_dupe_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
|
||||
{
|
||||
if (code == STATUS_MSC_EXCEPTION)
|
||||
{
|
||||
// C++ exception, go on
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle it
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
}
|
||||
|
||||
//due to unwinding
|
||||
void dupe(LLPointer<LLImageRaw> &raw)
|
||||
{
|
||||
raw = raw->duplicate();
|
||||
}
|
||||
|
||||
void logExceptionDupplicate(LLPointer<LLImageRaw> &raw)
|
||||
{
|
||||
__try
|
||||
{
|
||||
dupe(raw);
|
||||
}
|
||||
__except (exception_dupe_filter(GetExceptionCode(), GetExceptionInformation()))
|
||||
{
|
||||
// convert to C++ styled exception
|
||||
char integer_string[32];
|
||||
sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
|
||||
throw std::exception(integer_string);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//return the fast cache location
|
||||
bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
|
||||
{
|
||||
|
|
@ -2191,7 +2151,8 @@ bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImage
|
|||
c = raw->getComponents();
|
||||
|
||||
S32 i = 0 ;
|
||||
|
||||
|
||||
// Search for a discard level that will fit into fast cache
|
||||
while(((w >> i) * (h >> i) * c) > TEXTURE_FAST_CACHE_DATA_SIZE)
|
||||
{
|
||||
++i ;
|
||||
|
|
@ -2204,30 +2165,7 @@ bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImage
|
|||
if(w * h *c > 0) //valid
|
||||
{
|
||||
// Make a duplicate to keep the original raw image untouched.
|
||||
// Might be good idea to do a copy during writeToCache() call instead of here
|
||||
try
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
// Temporary diagnostics for scale/duplicate crash
|
||||
logExceptionDupplicate(raw);
|
||||
#else
|
||||
raw = raw->duplicate();
|
||||
#endif
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
removeFromCache(image_id);
|
||||
LL_WARNS() << "Failed to cache image: " << image_id
|
||||
<< " local id: " << id
|
||||
<< " Exception: " << boost::current_exception_diagnostic_information()
|
||||
<< " Image new width: " << w
|
||||
<< " Image new height: " << h
|
||||
<< " Image new components: " << c
|
||||
<< " Image discard difference: " << i
|
||||
<< LL_ENDL;
|
||||
|
||||
return false;
|
||||
}
|
||||
raw = raw->duplicate();
|
||||
|
||||
if (raw->isBufferInvalid())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -430,8 +430,8 @@ void LLAvatarTexBar::draw()
|
|||
LLColor4 color;
|
||||
|
||||
U32 line_num = 1;
|
||||
for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
|
||||
baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
|
||||
for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearance::getDictionary()->getBakedTextures().begin();
|
||||
baked_iter != LLAvatarAppearance::getDictionary()->getBakedTextures().end();
|
||||
++baked_iter)
|
||||
{
|
||||
const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
|
||||
|
|
|
|||
|
|
@ -322,34 +322,35 @@ bool LLResourceUploadInfo::findAssetTypeOfExtension(const std::string& exten, LL
|
|||
bool LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(const std::string& exten, LLAssetType::EType& asset_type, U32& codec, bool bulk_upload)
|
||||
{
|
||||
bool succ = false;
|
||||
|
||||
codec = LLImageBase::getCodecFromExtension(exten);
|
||||
std::string exten_lc(exten);
|
||||
LLStringUtil::toLower(exten_lc);
|
||||
codec = LLImageBase::getCodecFromExtension(exten_lc);
|
||||
if (codec != IMG_CODEC_INVALID)
|
||||
{
|
||||
asset_type = LLAssetType::AT_TEXTURE;
|
||||
succ = true;
|
||||
}
|
||||
else if (exten == "wav")
|
||||
else if (exten_lc == "wav")
|
||||
{
|
||||
asset_type = LLAssetType::AT_SOUND;
|
||||
succ = true;
|
||||
}
|
||||
else if (exten == "anim")
|
||||
else if (exten_lc == "anim")
|
||||
{
|
||||
asset_type = LLAssetType::AT_ANIMATION;
|
||||
succ = true;
|
||||
}
|
||||
else if (!bulk_upload && (exten == "bvh"))
|
||||
else if (!bulk_upload && (exten_lc == "bvh"))
|
||||
{
|
||||
asset_type = LLAssetType::AT_ANIMATION;
|
||||
succ = true;
|
||||
}
|
||||
else if (exten == "ogg")
|
||||
else if (exten_lc == "ogg")
|
||||
{
|
||||
asset_type = LLAssetType::AT_SOUND;
|
||||
succ = true;
|
||||
}
|
||||
else if (exten == "j2k")
|
||||
else if (exten_lc == "j2k")
|
||||
{
|
||||
asset_type = LLAssetType::AT_TEXTURE;
|
||||
succ = true;
|
||||
|
|
|
|||
|
|
@ -42,11 +42,21 @@
|
|||
#include "lltoolmgr.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "llviewermenu.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llwindow.h"
|
||||
#include "llagent.h"
|
||||
#include "llagentcamera.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "llmoveview.h"
|
||||
|
||||
#if LL_WINDOWS && !LL_MESA_HEADLESS
|
||||
// Require DirectInput version 8
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
|
||||
#include <dinput.h>
|
||||
#endif
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Constants
|
||||
|
||||
|
|
@ -68,6 +78,7 @@ F32 LLViewerJoystick::sDelta[] = {0,0,0,0,0,0,0};
|
|||
#define MAX_SPACENAVIGATOR_INPUT 3000.0f
|
||||
#define MAX_JOYSTICK_INPUT_VALUE MAX_SPACENAVIGATOR_INPUT
|
||||
|
||||
|
||||
#if LIB_NDOF
|
||||
std::ostream& operator<<(std::ostream& out, NDOF_Device* ptr)
|
||||
{
|
||||
|
|
@ -105,6 +116,126 @@ std::ostream& operator<<(std::ostream& out, NDOF_Device* ptr)
|
|||
}
|
||||
#endif // LIB_NDOF
|
||||
|
||||
|
||||
#if LL_WINDOWS && !LL_MESA_HEADLESS
|
||||
// this should reflect ndof and set axises, see ndofdev_win.cpp from ndof package
|
||||
BOOL CALLBACK EnumObjectsCallback(const DIDEVICEOBJECTINSTANCE* inst, VOID* user_data)
|
||||
{
|
||||
if (inst->dwType & DIDFT_AXIS)
|
||||
{
|
||||
LPDIRECTINPUTDEVICE8 device = *((LPDIRECTINPUTDEVICE8 *)user_data);
|
||||
DIPROPRANGE diprg;
|
||||
diprg.diph.dwSize = sizeof(DIPROPRANGE);
|
||||
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||
diprg.diph.dwHow = DIPH_BYID;
|
||||
diprg.diph.dwObj = inst->dwType; // specify the enumerated axis
|
||||
|
||||
// Set the range for the axis
|
||||
diprg.lMin = (long)-MAX_JOYSTICK_INPUT_VALUE;
|
||||
diprg.lMax = (long)+MAX_JOYSTICK_INPUT_VALUE;
|
||||
HRESULT hr = device->SetProperty(DIPROP_RANGE, &diprg.diph);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
}
|
||||
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
BOOL CALLBACK di8_devices_callback(LPCDIDEVICEINSTANCE device_instance_ptr, LPVOID pvRef)
|
||||
{
|
||||
// Note: If a single device can function as more than one DirectInput
|
||||
// device type, it is enumerated as each device type that it supports.
|
||||
// Capable of detecting devices like Oculus Rift
|
||||
if (device_instance_ptr)
|
||||
{
|
||||
std::string product_name = utf16str_to_utf8str(llutf16string(device_instance_ptr->tszProductName));
|
||||
|
||||
LLSD guid = LLViewerJoystick::getInstance()->getDeviceUUID();
|
||||
|
||||
bool init_device = false;
|
||||
if (guid.isBinary())
|
||||
{
|
||||
std::vector<U8> bin_bucket = guid.asBinary();
|
||||
init_device = memcmp(&bin_bucket[0], &device_instance_ptr->guidInstance, sizeof(GUID)) == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// It might be better to init space navigator here, but if system doesn't has one,
|
||||
// ndof will pick a random device, it is simpler to pick first device now to have an id
|
||||
init_device = true;
|
||||
}
|
||||
|
||||
if (init_device)
|
||||
{
|
||||
LL_DEBUGS("Joystick") << "Found and attempting to use device: " << product_name << LL_ENDL;
|
||||
LPDIRECTINPUT8 di8_interface = *((LPDIRECTINPUT8 *)gViewerWindow->getWindow()->getDirectInput8());
|
||||
LPDIRECTINPUTDEVICE8 device = NULL;
|
||||
|
||||
HRESULT status = di8_interface->CreateDevice(
|
||||
device_instance_ptr->guidInstance, // REFGUID rguid,
|
||||
&device, // LPDIRECTINPUTDEVICE * lplpDirectInputDevice,
|
||||
NULL // LPUNKNOWN pUnkOuter
|
||||
);
|
||||
|
||||
if (status == DI_OK)
|
||||
{
|
||||
// prerequisite for aquire()
|
||||
LL_DEBUGS("Joystick") << "Device created" << LL_ENDL;
|
||||
status = device->SetDataFormat(&c_dfDIJoystick); // c_dfDIJoystick2
|
||||
}
|
||||
|
||||
if (status == DI_OK)
|
||||
{
|
||||
// set properties
|
||||
LL_DEBUGS("Joystick") << "Format set" << LL_ENDL;
|
||||
status = device->EnumObjects(EnumObjectsCallback, &device, DIDFT_ALL);
|
||||
}
|
||||
|
||||
if (status == DI_OK)
|
||||
{
|
||||
LL_DEBUGS("Joystick") << "Properties updated" << LL_ENDL;
|
||||
|
||||
S32 size = sizeof(GUID);
|
||||
LLSD::Binary data; //just an std::vector
|
||||
data.resize(size);
|
||||
memcpy(&data[0], &device_instance_ptr->guidInstance /*POD _GUID*/, size);
|
||||
LLViewerJoystick::getInstance()->initDevice(&device, product_name, LLSD(data));
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Joystick") << "Found device: " << product_name << LL_ENDL;
|
||||
}
|
||||
}
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
// Windows guids
|
||||
// This is GUID2 so teoretically it can be memcpy copied into LLUUID
|
||||
void guid_from_string(GUID &guid, const std::string &input)
|
||||
{
|
||||
CLSIDFromString(utf8str_to_utf16str(input).c_str(), &guid);
|
||||
}
|
||||
|
||||
std::string string_from_guid(const GUID &guid)
|
||||
{
|
||||
OLECHAR* guidString; //wchat
|
||||
StringFromCLSID(guid, &guidString);
|
||||
|
||||
// use guidString...
|
||||
|
||||
std::string res = utf16str_to_utf8str(llutf16string(guidString));
|
||||
// ensure memory is freed
|
||||
::CoTaskMemFree(guidString);
|
||||
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void LLViewerJoystick::updateEnabled(bool autoenable)
|
||||
{
|
||||
|
|
@ -114,7 +245,8 @@ void LLViewerJoystick::updateEnabled(bool autoenable)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (isLikeSpaceNavigator() && autoenable)
|
||||
// autoenable if user specifically chose this device
|
||||
if (autoenable && (isLikeSpaceNavigator() || isDeviceUUIDSet()))
|
||||
{
|
||||
gSavedSettings.setBOOL("JoystickEnabled", TRUE );
|
||||
}
|
||||
|
|
@ -150,14 +282,14 @@ NDOF_HotPlugResult LLViewerJoystick::HotPlugAddCallback(NDOF_Device *dev)
|
|||
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
|
||||
if (joystick->mDriverState == JDS_UNINITIALIZED)
|
||||
{
|
||||
LL_INFOS("joystick") << "HotPlugAddCallback: will use device:" << LL_ENDL;
|
||||
LL_INFOS("Joystick") << "HotPlugAddCallback: will use device:" << LL_ENDL;
|
||||
|
||||
// <FS:ND> Disable for Linux till vs017 gets merged in to no having to support multiple version of libndofdev
|
||||
#ifndef LL_LINUX
|
||||
ndof_dump(stderr, dev);
|
||||
#endif
|
||||
// </FS:ND>
|
||||
|
||||
|
||||
joystick->mNdofDev = dev;
|
||||
joystick->mDriverState = JDS_INITIALIZED;
|
||||
res = NDOF_KEEP_HOTPLUGGED;
|
||||
|
|
@ -174,7 +306,7 @@ void LLViewerJoystick::HotPlugRemovalCallback(NDOF_Device *dev)
|
|||
LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
|
||||
if (joystick->mNdofDev == dev)
|
||||
{
|
||||
LL_INFOS("joystick") << "HotPlugRemovalCallback: joystick->mNdofDev="
|
||||
LL_INFOS("Joystick") << "HotPlugRemovalCallback: joystick->mNdofDev="
|
||||
<< joystick->mNdofDev << "; removed device:" << LL_ENDL;
|
||||
|
||||
// <FS:ND> Disable for Linux till vs017 gets merged in to no having to support multiple version of libndofdev
|
||||
|
|
@ -207,6 +339,8 @@ LLViewerJoystick::LLViewerJoystick()
|
|||
|
||||
// factor in bandwidth? bandwidth = gViewerStats->mKBitStat
|
||||
mPerfScale = 4000.f / gSysCPU.getMHz(); // hmm. why?
|
||||
|
||||
mLastDeviceUUID = LLSD::Integer(1);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -225,12 +359,14 @@ void LLViewerJoystick::init(bool autoenable)
|
|||
static bool libinit = false;
|
||||
mDriverState = JDS_INITIALIZING;
|
||||
|
||||
loadDeviceIdFromSettings();
|
||||
|
||||
if (libinit == false)
|
||||
{
|
||||
// Note: The HotPlug callbacks are not actually getting called on Windows
|
||||
if (ndof_libinit(HotPlugAddCallback,
|
||||
HotPlugRemovalCallback,
|
||||
NULL))
|
||||
gViewerWindow->getWindow()->getDirectInput8()))
|
||||
{
|
||||
mDriverState = JDS_UNINITIALIZED;
|
||||
}
|
||||
|
|
@ -247,41 +383,33 @@ void LLViewerJoystick::init(bool autoenable)
|
|||
if (libinit)
|
||||
{
|
||||
if (mNdofDev)
|
||||
{
|
||||
LL_DEBUGS("joystick") << "ndof_create() returned: " << mNdofDev << LL_ENDL;
|
||||
// Different joysticks will return different ranges of raw values.
|
||||
// Since we want to handle every device in the same uniform way,
|
||||
// we initialize the mNdofDev struct and we set the range
|
||||
// of values we would like to receive.
|
||||
//
|
||||
// HACK: On Windows, libndofdev passes our range to DI with a
|
||||
// SetProperty call. This works but with one notable exception, the
|
||||
// SpaceNavigator, who doesn't seem to care about the SetProperty
|
||||
// call. In theory, we should handle this case inside libndofdev.
|
||||
// However, the range we're setting here is arbitrary anyway,
|
||||
// so let's just use the SpaceNavigator range for our purposes.
|
||||
mNdofDev->axes_min = (long)-MAX_JOYSTICK_INPUT_VALUE;
|
||||
mNdofDev->axes_max = (long)+MAX_JOYSTICK_INPUT_VALUE;
|
||||
|
||||
// libndofdev could be used to return deltas. Here we choose to
|
||||
// just have the absolute values instead.
|
||||
mNdofDev->absolute = 1;
|
||||
|
||||
LL_DEBUGS("joystick") << "ndof_init_first() received: " << mNdofDev << LL_ENDL;
|
||||
// init & use the first suitable NDOF device found on the USB chain
|
||||
if (ndof_init_first(mNdofDev, NULL))
|
||||
{
|
||||
mDriverState = JDS_UNINITIALIZED;
|
||||
LL_WARNS("joystick") << "ndof_init_first FAILED" << LL_ENDL;
|
||||
#ifndef LL_LINUX
|
||||
ndof_dump_list(stderr);
|
||||
{
|
||||
// di8_devices_callback callback is immediate and happens in scope of getInputDevices()
|
||||
#if LL_WINDOWS && !LL_MESA_HEADLESS
|
||||
// space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
|
||||
U32 device_type = DI8DEVCLASS_GAMECTRL;
|
||||
void* callback = &di8_devices_callback;
|
||||
#else
|
||||
// MAC doesn't support device search yet
|
||||
// On MAC there is an ndof_idsearch and it is possible to specify product
|
||||
// and manufacturer in NDOF_Device for ndof_init_first to pick specific one
|
||||
U32 device_type = 0;
|
||||
void* callback = NULL;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
mDriverState = JDS_INITIALIZED;
|
||||
}
|
||||
LL_DEBUGS("joystick") << "ndof_init_first() left: " << mNdofDev << LL_ENDL;
|
||||
if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL))
|
||||
{
|
||||
LL_INFOS("Joystick") << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL;
|
||||
// Failed to gather devices from windows, init first suitable one
|
||||
mLastDeviceUUID = LLSD();
|
||||
void *preffered_device = NULL;
|
||||
initDevice(preffered_device);
|
||||
}
|
||||
|
||||
if (mDriverState == JDS_INITIALIZING)
|
||||
{
|
||||
LL_INFOS("Joystick") << "Found no matching joystick devices." << LL_ENDL;
|
||||
mDriverState = JDS_UNINITIALIZED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -320,11 +448,92 @@ void LLViewerJoystick::init(bool autoenable)
|
|||
// No device connected, don't change any settings
|
||||
}
|
||||
|
||||
LL_INFOS("joystick") << "ndof: mDriverState=" << mDriverState << "; mNdofDev="
|
||||
LL_INFOS("Joystick") << "ndof: mDriverState=" << mDriverState << "; mNdofDev="
|
||||
<< mNdofDev << "; libinit=" << libinit << LL_ENDL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLViewerJoystick::initDevice(LLSD &guid)
|
||||
{
|
||||
#if LIB_NDOF
|
||||
mLastDeviceUUID = guid;
|
||||
|
||||
#if LL_WINDOWS && !LL_MESA_HEADLESS
|
||||
// space navigator is marked as DI8DEVCLASS_GAMECTRL in ndof lib
|
||||
U32 device_type = DI8DEVCLASS_GAMECTRL;
|
||||
void* callback = &di8_devices_callback;
|
||||
#else
|
||||
// MAC doesn't support device search yet
|
||||
// On MAC there is an ndof_idsearch and it is possible to specify product
|
||||
// and manufacturer in NDOF_Device for ndof_init_first to pick specific one
|
||||
U32 device_type = 0;
|
||||
void* callback = NULL;
|
||||
#endif
|
||||
|
||||
mDriverState = JDS_INITIALIZING;
|
||||
if (!gViewerWindow->getWindow()->getInputDevices(device_type, callback, NULL))
|
||||
{
|
||||
LL_INFOS("Joystick") << "Failed to gather devices from window. Falling back to ndof's init" << LL_ENDL;
|
||||
// Failed to gather devices from windows, init first suitable one
|
||||
void *preffered_device = NULL;
|
||||
mLastDeviceUUID = LLSD();
|
||||
initDevice(preffered_device);
|
||||
}
|
||||
|
||||
if (mDriverState == JDS_INITIALIZING)
|
||||
{
|
||||
LL_INFOS("Joystick") << "Found no matching joystick devices." << LL_ENDL;
|
||||
mDriverState = JDS_UNINITIALIZED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLViewerJoystick::initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid)
|
||||
{
|
||||
#if LIB_NDOF
|
||||
mLastDeviceUUID = guid;
|
||||
|
||||
strncpy(mNdofDev->product, name.c_str(), sizeof(mNdofDev->product));
|
||||
mNdofDev->manufacturer[0] = '\0';
|
||||
|
||||
initDevice(preffered_device);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLViewerJoystick::initDevice(void * preffered_device /* LPDIRECTINPUTDEVICE8* */)
|
||||
{
|
||||
#if LIB_NDOF
|
||||
// Different joysticks will return different ranges of raw values.
|
||||
// Since we want to handle every device in the same uniform way,
|
||||
// we initialize the mNdofDev struct and we set the range
|
||||
// of values we would like to receive.
|
||||
//
|
||||
// HACK: On Windows, libndofdev passes our range to DI with a
|
||||
// SetProperty call. This works but with one notable exception, the
|
||||
// SpaceNavigator, who doesn't seem to care about the SetProperty
|
||||
// call. In theory, we should handle this case inside libndofdev.
|
||||
// However, the range we're setting here is arbitrary anyway,
|
||||
// so let's just use the SpaceNavigator range for our purposes.
|
||||
mNdofDev->axes_min = (long)-MAX_JOYSTICK_INPUT_VALUE;
|
||||
mNdofDev->axes_max = (long)+MAX_JOYSTICK_INPUT_VALUE;
|
||||
|
||||
// libndofdev could be used to return deltas. Here we choose to
|
||||
// just have the absolute values instead.
|
||||
mNdofDev->absolute = 1;
|
||||
// init & use the first suitable NDOF device found on the USB chain
|
||||
// On windows preffered_device needs to be a pointer to LPDIRECTINPUTDEVICE8
|
||||
if (ndof_init_first(mNdofDev, preffered_device))
|
||||
{
|
||||
mDriverState = JDS_UNINITIALIZED;
|
||||
LL_WARNS() << "ndof_init_first FAILED" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
mDriverState = JDS_INITIALIZED;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void LLViewerJoystick::terminate()
|
||||
{
|
||||
|
|
@ -334,7 +543,7 @@ void LLViewerJoystick::terminate()
|
|||
ndof_libcleanup(); // frees alocated memory in mNdofDev
|
||||
mDriverState = JDS_UNINITIALIZED;
|
||||
mNdofDev = NULL;
|
||||
LL_INFOS("joystick") << "Terminated connection with NDOF device." << LL_ENDL;
|
||||
LL_INFOS("Joystick") << "Terminated connection with NDOF device." << LL_ENDL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1132,6 +1341,74 @@ void LLViewerJoystick::scanJoystick()
|
|||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
bool LLViewerJoystick::isDeviceUUIDSet()
|
||||
{
|
||||
#if LL_WINDOWS && !LL_MESA_HEADLESS
|
||||
// for ease of comparison and to dial less with platform specific variables, we store id as LLSD binary
|
||||
return mLastDeviceUUID.isBinary();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
LLSD LLViewerJoystick::getDeviceUUID()
|
||||
{
|
||||
return mLastDeviceUUID;
|
||||
}
|
||||
|
||||
std::string LLViewerJoystick::getDeviceUUIDString()
|
||||
{
|
||||
#if LL_WINDOWS && !LL_MESA_HEADLESS
|
||||
// Might be simpler to just convert _GUID into string everywhere, store and compare as string
|
||||
if (mLastDeviceUUID.isBinary())
|
||||
{
|
||||
S32 size = sizeof(GUID);
|
||||
LLSD::Binary data = mLastDeviceUUID.asBinary();
|
||||
GUID guid;
|
||||
memcpy(&guid, &data[0], size);
|
||||
return string_from_guid(guid);
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
#else
|
||||
return std::string();
|
||||
// return mLastDeviceUUID;
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLViewerJoystick::loadDeviceIdFromSettings()
|
||||
{
|
||||
#if LL_WINDOWS && !LL_MESA_HEADLESS
|
||||
// We can't save binary data to gSavedSettings, somebody editing the file will corrupt it,
|
||||
// so _GUID data gets converted to string (we probably can convert it to LLUUID with memcpy)
|
||||
// and here we need to convert it back to binary from string
|
||||
std::string device_string = gSavedSettings.getString("JoystickDeviceUUID");
|
||||
if (device_string.empty())
|
||||
{
|
||||
mLastDeviceUUID = LLSD();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("Joystick") << "Looking for device by id: " << device_string << LL_ENDL;
|
||||
GUID guid;
|
||||
guid_from_string(guid, device_string);
|
||||
S32 size = sizeof(GUID);
|
||||
LLSD::Binary data; //just an std::vector
|
||||
data.resize(size);
|
||||
memcpy(&data[0], &guid /*POD _GUID*/, size);
|
||||
// We store this data in LLSD since LLSD is versatile and will be able to handle both GUID2
|
||||
// and any data MAC will need for device selection
|
||||
mLastDeviceUUID = LLSD(data);
|
||||
}
|
||||
#else
|
||||
mLastDeviceUUID = LLSD();
|
||||
//mLastDeviceUUID = gSavedSettings.getLLSD("JoystickDeviceUUID");
|
||||
#endif
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
std::string LLViewerJoystick::getDescription()
|
||||
{
|
||||
|
|
@ -1173,7 +1450,7 @@ void LLViewerJoystick::setSNDefaults()
|
|||
#endif
|
||||
|
||||
//gViewerWindow->alertXml("CacheWillClear");
|
||||
LL_INFOS("joystick") << "restoring SpaceNavigator defaults..." << LL_ENDL;
|
||||
LL_INFOS("Joystick") << "restoring SpaceNavigator defaults..." << LL_ENDL;
|
||||
|
||||
gSavedSettings.setS32("JoystickAxis0", 1); // z (at)
|
||||
gSavedSettings.setS32("JoystickAxis1", 0); // x (slide)
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@ class LLViewerJoystick : public LLSingleton<LLViewerJoystick>
|
|||
|
||||
public:
|
||||
void init(bool autoenable);
|
||||
void initDevice(LLSD &guid);
|
||||
void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/);
|
||||
void initDevice(void * preffered_device /*LPDIRECTINPUTDEVICE8*/, std::string &name, LLSD &guid);
|
||||
void terminate();
|
||||
|
||||
void updateStatus();
|
||||
|
|
@ -68,8 +71,11 @@ public:
|
|||
void setOverrideCamera(bool val);
|
||||
bool toggleFlycam();
|
||||
void setSNDefaults();
|
||||
bool isDeviceUUIDSet();
|
||||
LLSD getDeviceUUID(); //unconverted, OS dependent value wrapped into LLSD, for comparison/search
|
||||
std::string getDeviceUUIDString(); // converted readable value for settings
|
||||
std::string getDescription();
|
||||
|
||||
|
||||
protected:
|
||||
void updateEnabled(bool autoenable);
|
||||
void handleRun(F32 inc);
|
||||
|
|
@ -80,6 +86,7 @@ protected:
|
|||
void agentYaw(F32 yaw_inc);
|
||||
void agentJump();
|
||||
void resetDeltas(S32 axis[]);
|
||||
void loadDeviceIdFromSettings();
|
||||
#if LIB_NDOF
|
||||
static NDOF_HotPlugResult HotPlugAddCallback(NDOF_Device *dev);
|
||||
static void HotPlugRemovalCallback(NDOF_Device *dev);
|
||||
|
|
@ -95,6 +102,7 @@ private:
|
|||
bool mCameraUpdated;
|
||||
bool mOverrideCamera;
|
||||
U32 mJoystickRun;
|
||||
LLSD mLastDeviceUUID; // _GUID as U8 binary map, integer 1 for no device/ndof's device
|
||||
|
||||
static F32 sLastDelta[7];
|
||||
static F32 sDelta[7];
|
||||
|
|
|
|||
|
|
@ -194,8 +194,6 @@ static F32 sGlobalVolume = 1.0f;
|
|||
static bool sForceUpdate = false;
|
||||
static LLUUID sOnlyAudibleTextureID = LLUUID::null;
|
||||
static F64 sLowestLoadableImplInterest = 0.0f;
|
||||
// <FS:ND/> Unused
|
||||
//static bool sAnyMediaShowing = false;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
static void add_media_impl(LLViewerMediaImpl* media)
|
||||
|
|
@ -883,10 +881,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
|
|||
|
||||
if (!pimpl->getUsedInUI() && pimpl->hasMedia())
|
||||
{
|
||||
// <FS:ND> Need to set the right instance var
|
||||
// sAnyMediaShowing = true;
|
||||
mAnyMediaShowing = true;
|
||||
// </FS:ND>
|
||||
mAnyMediaShowing = true;
|
||||
}
|
||||
|
||||
if (!pimpl->getUsedInUI() && pimpl->hasMedia() && (pimpl->isMediaPlaying() || !pimpl->isMediaTimeBased()))
|
||||
|
|
|
|||
|
|
@ -340,7 +340,8 @@ BOOL LLViewerMediaFocus::handleKey(KEY key, MASK mask, BOOL called_from_parent)
|
|||
|
||||
clearFocus();
|
||||
}
|
||||
|
||||
|
||||
// <FS:Ansariel> Keep help links
|
||||
if ( KEY_F1 == key && LLUI::getInstance()->mHelpImpl && mMediaControls.get())
|
||||
{
|
||||
std::string help_topic;
|
||||
|
|
@ -349,6 +350,7 @@ BOOL LLViewerMediaFocus::handleKey(KEY key, MASK mask, BOOL called_from_parent)
|
|||
LLUI::getInstance()->mHelpImpl->showTopic(help_topic);
|
||||
}
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue