diff options
| author | Monty Brandenberg <monty@lindenlab.com> | 2014-04-03 18:56:46 -0400 |
|---|---|---|
| committer | Monty Brandenberg <monty@lindenlab.com> | 2014-04-03 18:56:46 -0400 |
| commit | d7481cd07c3e0b5eed54ff6a3539406d09ed0669 (patch) | |
| tree | 7e0d2a2a9733784f16518b977423deb225021651 /indra | |
| parent | 076761a03d7cb8b53e6e3d4f2120091eabeba37a (diff) | |
| parent | 31a3a3da5db077c4d9b8fe06a18de98c822db6ab (diff) | |
Merge. Refresh from viewer-release after 3.7.4 release.
Diffstat (limited to 'indra')
447 files changed, 19672 insertions, 7150 deletions
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index bdbfc55fa2..410d25ad97 100755 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -63,10 +63,11 @@ add_subdirectory(${VIEWER_PREFIX}test) # viewer media plugins add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins) -# llplugin testbed code (is this the right way to include it?) -if (LL_TESTS AND NOT LINUX) - add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest) -endif (LL_TESTS AND NOT LINUX) + # llplugin testbed code (is this the right way to include it?) + if (LL_TESTS AND NOT LINUX) + add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest) + add_subdirectory(${VIEWER_PREFIX}test_apps/llfbconnecttest) + endif (LL_TESTS AND NOT LINUX) if (LINUX) add_subdirectory(${VIEWER_PREFIX}linux_crash_logger) diff --git a/indra/cmake/BuildVersion.cmake b/indra/cmake/BuildVersion.cmake index af2063ce6d..e4b63dc7cb 100755 --- a/indra/cmake/BuildVersion.cmake +++ b/indra/cmake/BuildVersion.cmake @@ -16,22 +16,26 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n else (DEFINED ENV{revision}) find_program(MERCURIAL hg) - if (DEFINED MERCURIAL) + find_program(WORDCOUNT wc) + find_program(SED sed) + if (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED) execute_process( - COMMAND ${MERCURIAL} log -r tip --template "{rev}" + COMMAND ${MERCURIAL} log -r tip:0 --template '\\n' + COMMAND ${WORDCOUNT} -l + COMMAND ${SED} "s/ //g" OUTPUT_VARIABLE VIEWER_VERSION_REVISION OUTPUT_STRIP_TRAILING_WHITESPACE ) if ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$") message("Revision (from hg) ${VIEWER_VERSION_REVISION}") else ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$") + message("Revision not set (repository not found?); using 0") set(VIEWER_VERSION_REVISION 0 ) - message("Revision not set, repository not found, using ${VIEWER_VERSION_REVISION}") endif ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$") - else (DEFINED MERCURIAL) + else (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED) + message("Revision not set: 'hg', 'wc' or 'sed' not found; using 0") set(VIEWER_VERSION_REVISION 0) - message("Revision not set, 'hg' not found (${MERCURIAL}), using ${VIEWER_VERSION_REVISION}") - endif (DEFINED MERCURIAL) + endif (DEFINED MERCURIAL AND DEFINED WORDCOUNT AND DEFINED SED) endif (DEFINED ENV{revision}) message("Building '${VIEWER_CHANNEL}' Version ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}") else ( EXISTS ${VIEWER_VERSION_BASE_FILE} ) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 308e378db0..264039390c 100755 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -64,6 +64,7 @@ if(WINDOWS) endif(USE_TCMALLOC) if (FMODEX) + set(debug_files ${debug_files} fmodexL.dll) set(release_files ${release_files} fmodex.dll) endif (FMODEX) @@ -294,7 +295,8 @@ elseif(LINUX) endif (USE_TCMALLOC) if (FMODEX) - set(release_file ${release_files} "libfmodex.so") + set(debug_files ${debug_files} "libfmodexL.so") + set(release_files ${release_files} "libfmodex.so") endif (FMODEX) else(WINDOWS) diff --git a/indra/cmake/FMODEX.cmake b/indra/cmake/FMODEX.cmake index 65bc1cabeb..163260137b 100644 --- a/indra/cmake/FMODEX.cmake +++ b/indra/cmake/FMODEX.cmake @@ -39,7 +39,7 @@ if (FMODEX) optimized fmodex) endif (WINDOWS) set(FMODEX_LIBRARIES ${FMODEX_LIBRARY}) - set(FMODEX_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodex) + set(FMODEX_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/) endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR) endif (STANDALONE) endif (FMODEX) diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt index 513b4583a5..74c472dc0e 100755 --- a/indra/edit-me-to-trigger-new-build.txt +++ b/indra/edit-me-to-trigger-new-build.txt @@ -1 +1,4 @@ Thu, Oct 17, 2013 6:49:30 PM + + + diff --git a/indra/lib/python/indra/base/lluuid.py b/indra/lib/python/indra/base/lluuid.py index 369ae4e92f..7413ffe10d 100755 --- a/indra/lib/python/indra/base/lluuid.py +++ b/indra/lib/python/indra/base/lluuid.py @@ -72,7 +72,7 @@ class UUID(object): ip = '' try: ip = socket.gethostbyname(socket.gethostname()) - except(socket.gaierror): + except(socket.gaierror, socket.error): # no ip address, so just default to somewhere in 10.x.x.x ip = '10' for i in range(3): diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py index 54049b5545..1d85aa2978 100755 --- a/indra/lib/python/indra/util/llmanifest.py +++ b/indra/lib/python/indra/util/llmanifest.py @@ -85,7 +85,8 @@ def get_default_platform(dummy): }[sys.platform] DEFAULT_SRCTREE = os.path.dirname(sys.argv[0]) -RELEASE_CHANNEL = 'Second Life Release' +CHANNEL_VENDOR_BASE = 'Second Life' +RELEASE_CHANNEL = CHANNEL_VENDOR_BASE + ' Release' ARGUMENTS=[ dict(name='actions', @@ -112,13 +113,14 @@ ARGUMENTS=[ default="Release"), dict(name='dest', description='Destination directory.', default=DEFAULT_SRCTREE), dict(name='grid', - description="""Which grid the client will try to connect to. Even - though it's not strictly a grid, 'firstlook' is also an acceptable - value for this parameter.""", - default=""), + description="""Which grid the client will try to connect to.""", + default=None), dict(name='channel', description="""The channel to use for updates, packaging, settings name, etc.""", default='CHANNEL UNSET'), + dict(name='channel_suffix', + description="""Addition to the channel for packaging and channel value, but not application name (used internally)""", + default=None), dict(name='installer_name', description=""" The name of the file that the installer should be packaged up into. Only used on Linux at the moment.""", @@ -213,9 +215,9 @@ def main(): print "Unable to read versionfile '%s'" % args['versionfile'] raise - # default and agni are default - if args['grid'] in ['default', 'agni']: - args['grid'] = '' + # unspecified, default, and agni are default + if args['grid'] in ['', 'default', 'agni']: + args['grid'] = None if 'actions' in args: args['actions'] = args['actions'].split() @@ -224,15 +226,101 @@ def main(): for opt in args: print "Option:", opt, "=", args[opt] + # pass in sourceid as an argument now instead of an environment variable + try: + args['sourceid'] = os.environ["sourceid"] + except KeyError: + args['sourceid'] = "" + + # Build base package. + touch = args.get('touch') + if touch: + print 'Creating base package' + args['package_id'] = "" # base package has no package ID wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args) wm.do(*args['actions']) + # Store package file for later if making touched file. + base_package_file = "" + if touch: + print 'Created base package ', wm.package_file + base_package_file = "" + wm.package_file + # handle multiple packages if set + try: + additional_packages = os.environ["additional_packages"] + except KeyError: + additional_packages = "" + if additional_packages: + # Determine destination prefix / suffix for additional packages. + base_dest_postfix = args['dest'] + base_dest_prefix = "" + base_dest_parts = args['dest'].split(os.sep) + if len(base_dest_parts) > 1: + base_dest_postfix = base_dest_parts[len(base_dest_parts) - 1] + base_dest_prefix = base_dest_parts[0] + i = 1 + while i < len(base_dest_parts) - 1: + base_dest_prefix = base_dest_prefix + os.sep + base_dest_parts[i] + i = i + 1 + # Determine touched prefix / suffix for additional packages. + base_touch_postfix = "" + base_touch_prefix = "" + if touch: + base_touch_postfix = touch + base_touch_parts = touch.split('/') + if "arwin" in args['platform']: + if len(base_touch_parts) > 1: + base_touch_postfix = base_touch_parts[len(base_touch_parts) - 1] + base_touch_prefix = base_touch_parts[0] + i = 1 + while i < len(base_touch_parts) - 1: + base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i] + i = i + 1 + else: + if len(base_touch_parts) > 2: + base_touch_postfix = base_touch_parts[len(base_touch_parts) - 2] + '/' + base_touch_parts[len(base_touch_parts) - 1] + base_touch_prefix = base_touch_parts[0] + i = 1 + while i < len(base_touch_parts) - 2: + base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i] + i = i + 1 + # Store base channel name. + base_channel_name = args['channel'] + # Build each additional package. + package_id_list = additional_packages.split(" ") + args['channel'] = base_channel_name + for package_id in package_id_list: + try: + if package_id + "_viewer_channel_suffix" in os.environ: + args['channel_suffix'] = os.environ[package_id + "_viewer_channel_suffix"] + else: + args['channel_suffix'] = None + if package_id + "_sourceid" in os.environ: + args['sourceid'] = os.environ[package_id + "_sourceid"] + else: + args['sourceid'] = None + args['dest'] = base_dest_prefix + os.sep + package_id + os.sep + base_dest_postfix + except KeyError: + sys.stderr.write("Failed to create package for package_id: %s" % package_id) + sys.stderr.flush() + continue + if touch: + print 'Creating additional package for "', package_id, '" in ', args['dest'] + wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args) + wm.do(*args['actions']) + if touch: + print 'Created additional package ', wm.package_file, ' for ', package_id + faketouch = base_touch_prefix + '/' + package_id + '/' + base_touch_postfix + fp = open(faketouch, 'w') + fp.write('set package_file=%s\n' % wm.package_file) + fp.close() + # Write out the package file in this format, so that it can easily be called # and used in a .bat file - yeah, it sucks, but this is the simplest... touch = args.get('touch') if touch: fp = open(touch, 'w') - fp.write('set package_file=%s\n' % wm.package_file) + fp.write('set package_file=%s\n' % base_package_file) fp.close() print 'touched', touch return 0 @@ -249,7 +337,7 @@ class LLManifest(object): manifests = {} def for_platform(self, platform, arch = None): if arch: - platform = platform + '_' + arch + platform = platform + '_' + arch + '_' return self.manifests[platform.lower()] for_platform = classmethod(for_platform) @@ -266,8 +354,6 @@ class LLManifest(object): self.created_paths = [] self.package_name = "Unknown" - def default_grid(self): - return self.args.get('grid', None) == '' def default_channel(self): return self.args.get('channel', None) == RELEASE_CHANNEL diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 3bb759d458..0f5d729e77 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -81,6 +81,7 @@ public: ~LLAvatarBoneInfo() { std::for_each(mChildList.begin(), mChildList.end(), DeletePointer()); + mChildList.clear(); } BOOL parseXml(LLXmlTreeNode* node); @@ -108,6 +109,7 @@ public: ~LLAvatarSkeletonInfo() { std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer()); + mBoneInfoList.clear(); } BOOL parseXml(LLXmlTreeNode* node); S32 getNumBones() const { return mNumBones; } @@ -132,14 +134,26 @@ LLAvatarAppearance::LLAvatarXmlInfo::LLAvatarXmlInfo() LLAvatarAppearance::LLAvatarXmlInfo::~LLAvatarXmlInfo() { std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer()); + mMeshInfoList.clear(); + std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer()); + mSkeletalDistortionInfoList.clear(); + std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer()); + mAttachmentInfoList.clear(); + deleteAndClear(mTexSkinColorInfo); deleteAndClear(mTexHairColorInfo); deleteAndClear(mTexEyeColorInfo); + std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer()); + mLayerInfoList.clear(); + std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer()); + mDriverInfoList.clear(); + std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer()); + mMorphMaskInfoList.clear(); } @@ -291,10 +305,6 @@ LLAvatarAppearance::~LLAvatarAppearance() clearSkeleton(); deleteAndClearArray(mCollisionVolumes); - deleteAndClear(mTexSkinColor); - deleteAndClear(mTexHairColor); - deleteAndClear(mTexEyeColor); - std::for_each(mPolyMeshes.begin(), mPolyMeshes.end(), DeletePairedPointer()); mPolyMeshes.clear(); diff --git a/indra/llappearance/lltexglobalcolor.cpp b/indra/llappearance/lltexglobalcolor.cpp index f38b982104..16b0260d1a 100644 --- a/indra/llappearance/lltexglobalcolor.cpp +++ b/indra/llappearance/lltexglobalcolor.cpp @@ -120,6 +120,7 @@ LLTexGlobalColorInfo::LLTexGlobalColorInfo() LLTexGlobalColorInfo::~LLTexGlobalColorInfo() { for_each(mParamColorInfoList.begin(), mParamColorInfoList.end(), DeletePointer()); + mParamColorInfoList.clear(); } BOOL LLTexGlobalColorInfo::parseXml(LLXmlTreeNode* node) diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp index a3a8616864..63d01999f0 100644 --- a/indra/llappearance/lltexlayer.cpp +++ b/indra/llappearance/lltexlayer.cpp @@ -195,6 +195,7 @@ LLTexLayerSetInfo::LLTexLayerSetInfo() : LLTexLayerSetInfo::~LLTexLayerSetInfo( ) { std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer()); + mLayerInfoList.clear(); } BOOL LLTexLayerSetInfo::parseXml(LLXmlTreeNode* node) @@ -282,7 +283,10 @@ LLTexLayerSet::~LLTexLayerSet() { deleteCaches(); std::for_each(mLayerList.begin(), mLayerList.end(), DeletePointer()); + mLayerList.clear(); + std::for_each(mMaskLayerList.begin(), mMaskLayerList.end(), DeletePointer()); + mMaskLayerList.clear(); } //----------------------------------------------------------------------------- @@ -652,7 +656,9 @@ LLTexLayerInfo::LLTexLayerInfo() : LLTexLayerInfo::~LLTexLayerInfo( ) { std::for_each(mParamColorInfoList.begin(), mParamColorInfoList.end(), DeletePointer()); + mParamColorInfoList.clear(); std::for_each(mParamAlphaInfoList.begin(), mParamAlphaInfoList.end(), DeletePointer()); + mParamAlphaInfoList.clear(); } BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node) diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp index 6c97a64ed7..8c31f8b4de 100755 --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -135,7 +135,7 @@ int vfs_seek(void *datasource, ogg_int64_t offset, int whence) origin = -1; break; default: - llerrs << "Invalid whence argument to vfs_seek" << llendl; + LL_ERRS("AudioEngine") << "Invalid whence argument to vfs_seek" << LL_ENDL; return -1; } @@ -197,12 +197,12 @@ BOOL LLVorbisDecodeState::initDecode() vfs_callbacks.close_func = vfs_close; vfs_callbacks.tell_func = vfs_tell; - //llinfos << "Initing decode from vfile: " << mUUID << llendl; + LL_DEBUGS("AudioEngine") << "Initing decode from vfile: " << mUUID << LL_ENDL; mInFilep = new LLVFile(gVFS, mUUID, LLAssetType::AT_SOUND); if (!mInFilep || !mInFilep->getSize()) { - llwarns << "unable to open vorbis source vfile for reading" << llendl; + LL_WARNS("AudioEngine") << "unable to open vorbis source vfile for reading" << LL_ENDL; delete mInFilep; mInFilep = NULL; return FALSE; @@ -211,7 +211,7 @@ BOOL LLVorbisDecodeState::initDecode() int r = ov_open_callbacks(mInFilep, &mVF, NULL, 0, vfs_callbacks); if(r < 0) { - llwarns << r << " Input to vorbis decode does not appear to be an Ogg bitstream: " << mUUID << llendl; + LL_WARNS("AudioEngine") << r << " Input to vorbis decode does not appear to be an Ogg bitstream: " << mUUID << LL_ENDL; return(FALSE); } @@ -229,36 +229,36 @@ BOOL LLVorbisDecodeState::initDecode() if( vi->channels < 1 || vi->channels > LLVORBIS_CLIP_MAX_CHANNELS ) { abort_decode = true; - llwarns << "Bad channel count: " << vi->channels << llendl; + LL_WARNS("AudioEngine") << "Bad channel count: " << vi->channels << LL_ENDL; } } else // !vi { abort_decode = true; - llwarns << "No default bitstream found" << llendl; + LL_WARNS("AudioEngine") << "No default bitstream found" << LL_ENDL; } if( (size_t)sample_count > LLVORBIS_CLIP_REJECT_SAMPLES || (size_t)sample_count <= 0) { abort_decode = true; - llwarns << "Illegal sample count: " << sample_count << llendl; + LL_WARNS("AudioEngine") << "Illegal sample count: " << sample_count << LL_ENDL; } if( size_guess > LLVORBIS_CLIP_REJECT_SIZE || size_guess < 0) { abort_decode = true; - llwarns << "Illegal sample size: " << size_guess << llendl; + LL_WARNS("AudioEngine") << "Illegal sample size: " << size_guess << LL_ENDL; } if( abort_decode ) { - llwarns << "Canceling initDecode. Bad asset: " << mUUID << llendl; + LL_WARNS("AudioEngine") << "Canceling initDecode. Bad asset: " << mUUID << LL_ENDL; vorbis_comment* comment = ov_comment(&mVF,-1); if (comment && comment->vendor) { - llwarns << "Bad asset encoded by: " << comment->vendor << llendl; + LL_WARNS("AudioEngine") << "Bad asset encoded by: " << comment->vendor << LL_ENDL; } delete mInFilep; mInFilep = NULL; @@ -359,12 +359,12 @@ BOOL LLVorbisDecodeState::decodeSection() { if (!mInFilep) { - llwarns << "No VFS file to decode in vorbis!" << llendl; + LL_WARNS("AudioEngine") << "No VFS file to decode in vorbis!" << LL_ENDL; return TRUE; } if (mDone) { -// llwarns << "Already done with decode, aborting!" << llendl; +// LL_WARNS("AudioEngine") << "Already done with decode, aborting!" << LL_ENDL; return TRUE; } char pcmout[4096]; /*Flawfinder: ignore*/ @@ -377,14 +377,14 @@ BOOL LLVorbisDecodeState::decodeSection() eof = TRUE; mDone = TRUE; mValid = TRUE; -// llinfos << "Vorbis EOF" << llendl; +// LL_INFOS("AudioEngine") << "Vorbis EOF" << LL_ENDL; } else if (ret < 0) { /* error in the stream. Not a problem, just reporting it in case we (the app) cares. In this case, we don't. */ - llwarns << "BAD vorbis decode in decodeSection." << llendl; + LL_WARNS("AudioEngine") << "BAD vorbis decode in decodeSection." << LL_ENDL; mValid = FALSE; mDone = TRUE; @@ -393,7 +393,7 @@ BOOL LLVorbisDecodeState::decodeSection() } else { -// llinfos << "Vorbis read " << ret << "bytes" << llendl; +// LL_INFOS("AudioEngine") << "Vorbis read " << ret << "bytes" << LL_ENDL; /* we don't bother dealing with sample rate changes, etc, but. you'll have to*/ std::copy(pcmout, pcmout+ret, std::back_inserter(mWAVBuffer)); @@ -405,7 +405,7 @@ BOOL LLVorbisDecodeState::finishDecode() { if (!isValid()) { - llwarns << "Bogus vorbis decode state for " << getUUID() << ", aborting!" << llendl; + LL_WARNS("AudioEngine") << "Bogus vorbis decode state for " << getUUID() << ", aborting!" << LL_ENDL; return TRUE; // We've finished } @@ -480,7 +480,7 @@ BOOL LLVorbisDecodeState::finishDecode() if (36 == data_length) { - llwarns << "BAD Vorbis decode in finishDecode!" << llendl; + LL_WARNS("AudioEngine") << "BAD Vorbis decode in finishDecode!" << LL_ENDL; mValid = FALSE; return TRUE; // we've finished } @@ -497,7 +497,7 @@ BOOL LLVorbisDecodeState::finishDecode() { if (mBytesRead == 0) { - llwarns << "Unable to write file in LLVorbisDecodeState::finishDecode" << llendl; + LL_WARNS("AudioEngine") << "Unable to write file in LLVorbisDecodeState::finishDecode" << LL_ENDL; mValid = FALSE; return TRUE; // we've finished } @@ -515,7 +515,7 @@ BOOL LLVorbisDecodeState::finishDecode() LLVFile output(gVFS, mUUID, LLAssetType::AT_SOUND_WAV); output.write(&mWAVBuffer[0], mWAVBuffer.size()); #endif - //llinfos << "Finished decode for " << getUUID() << llendl; + LL_DEBUGS("AudioEngine") << "Finished decode for " << getUUID() << LL_ENDL; return TRUE; } @@ -524,7 +524,7 @@ void LLVorbisDecodeState::flushBadFile() { if (mInFilep) { - llwarns << "Flushing bad vorbis file from VFS for " << mUUID << llendl; + LL_WARNS("AudioEngine") << "Flushing bad vorbis file from VFS for " << mUUID << LL_ENDL; mInFilep->remove(); } } @@ -568,7 +568,7 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) if (mCurrentDecodep->isDone() && !mCurrentDecodep->isValid()) { // We had an error when decoding, abort. - llwarns << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << llendl; + LL_WARNS("AudioEngine") << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << LL_ENDL; mCurrentDecodep->flushBadFile(); LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID()); adp->setHasValidData(false); @@ -590,7 +590,7 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID()); if (!adp) { - llwarns << "Missing LLAudioData for decode of " << mCurrentDecodep->getUUID() << llendl; + LL_WARNS("AudioEngine") << "Missing LLAudioData for decode of " << mCurrentDecodep->getUUID() << LL_ENDL; } else if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone()) { @@ -601,12 +601,12 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) // At this point, we could see if anyone needs this sound immediately, but // I'm not sure that there's a reason to - we need to poll all of the playing // sounds anyway. - //llinfos << "Finished the vorbis decode, now what?" << llendl; + //LL_INFOS("AudioEngine") << "Finished the vorbis decode, now what?" << LL_ENDL; } else { adp->setHasCompletedDecode(true); - llinfos << "Vorbis decode failed for " << mCurrentDecodep->getUUID() << llendl; + LL_INFOS("AudioEngine") << "Vorbis decode failed for " << mCurrentDecodep->getUUID() << LL_ENDL; } mCurrentDecodep = NULL; } @@ -631,7 +631,7 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) continue; } - lldebugs << "Decoding " << uuid << " from audio queue!" << llendl; + lldebugs << "Decoding " << uuid << " from audio queue!" << LL_ENDL; std::string uuid_str; std::string d_path; @@ -674,19 +674,19 @@ BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid) if (gAudiop->hasDecodedFile(uuid)) { // Already have a decoded version, don't need to decode it. - //llinfos << "addDecodeRequest for " << uuid << " has decoded file already" << llendl; + LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has decoded file already" << LL_ENDL; return TRUE; } if (gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND)) { // Just put it on the decode queue. - //llinfos << "addDecodeRequest for " << uuid << " has local asset file already" << llendl; + LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has local asset file already" << LL_ENDL; mImpl->mDecodeQueue.push(uuid); return TRUE; } - //llinfos << "addDecodeRequest for " << uuid << " no file available" << llendl; + LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " no file available" << LL_ENDL; return FALSE; } diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index 06e752cf34..ca614f5395 100755 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -123,7 +123,7 @@ bool LLAudioEngine::init(const S32 num_channels, void* userdata) // Initialize the decode manager gAudioDecodeMgrp = new LLAudioDecodeMgr; - llinfos << "LLAudioEngine::init() AudioEngine successfully initialized" << llendl; + LL_INFOS("AudioEngine") << "LLAudioEngine::init() AudioEngine successfully initialized" << LL_ENDL; return true; } @@ -308,7 +308,7 @@ void LLAudioEngine::idle(F32 max_decode_time) LLAudioChannel *channelp = getFreeChannel(max_priority); if (channelp) { - //llinfos << "Replacing source in channel due to priority!" << llendl; + LL_DEBUGS("AudioEngine") << "Replacing source in channel due to priority!" << LL_ENDL; max_sourcep->setChannel(channelp); channelp->setSource(max_sourcep); if (max_sourcep->isSyncSlave()) @@ -479,7 +479,7 @@ void LLAudioEngine::idle(F32 max_decode_time) { if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f) { - //llinfos << "Flushing unused buffer!" << llendl; + LL_DEBUGS("AudioEngine") << "Flushing unused buffer!" << LL_ENDL; mBuffers[i]->mAudioDatap->mBufferp = NULL; delete mBuffers[i]; mBuffers[i] = NULL; @@ -591,8 +591,8 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer() if (buffer_id >= 0) { - lldebugs << "Taking over unused buffer " << buffer_id << llendl; - //llinfos << "Flushing unused buffer!" << llendl; + lldebugs << "Taking over unused buffer " << buffer_id << LL_ENDL; + LL_DEBUGS("AudioEngine") << "Flushing unused buffer!" << LL_ENDL; mBuffers[buffer_id]->mAudioDatap->mBufferp = NULL; delete mBuffers[buffer_id]; mBuffers[buffer_id] = createBuffer(); @@ -673,6 +673,8 @@ void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp) bool LLAudioEngine::preloadSound(const LLUUID &uuid) { + LL_DEBUGS("AudioEngine")<<"( "<<uuid<<" )"<<LL_ENDL; + gAudiop->getAudioData(uuid); // We don't care about the return value, this is just to make sure // that we have an entry, which will mean that the audio engine knows about this @@ -684,7 +686,7 @@ bool LLAudioEngine::preloadSound(const LLUUID &uuid) // At some point we need to have the audio/asset system check the static VFS // before it goes off and fetches stuff from the server. - //llwarns << "Used internal preload for non-local sound" << llendl; + LL_DEBUGS("AudioEngine") << "Used internal preload for non-local sound "<< uuid << LL_ENDL; return false; } @@ -815,7 +817,7 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i const S32 type, const LLVector3d &pos_global) { // Create a new source (since this can't be associated with an existing source. - //llinfos << "Localized: " << audio_uuid << llendl; + LL_DEBUGS("AudioEngine") << "Localized: " << audio_uuid << LL_ENDL; if (mMuted) { @@ -982,11 +984,14 @@ void LLAudioEngine::cleanupAudioSource(LLAudioSource *asp) iter = mAllSources.find(asp->getID()); if (iter == mAllSources.end()) { - llwarns << "Cleaning up unknown audio source!" << llendl; - return; + LL_WARNS("AudioEngine") << "Cleaning up unknown audio source!" << LL_ENDL; + } + else + { + LL_DEBUGS("AudioEngine") << "Cleaning up audio sources for "<< asp->getID() <<LL_ENDL; + delete asp; + mAllSources.erase(iter); } - delete asp; - mAllSources.erase(iter); } @@ -1013,16 +1018,18 @@ bool LLAudioEngine::hasDecodedFile(const LLUUID &uuid) bool LLAudioEngine::hasLocalFile(const LLUUID &uuid) { // See if it's in the VFS. - return gVFS->getExists(uuid, LLAssetType::AT_SOUND); + bool have_local = gVFS->getExists(uuid, LLAssetType::AT_SOUND); + LL_DEBUGS("AudioEngine") << "sound uuid "<<uuid<<" exists in VFS"<<LL_ENDL; + return have_local; } void LLAudioEngine::startNextTransfer() { - //llinfos << "LLAudioEngine::startNextTransfer()" << llendl; + //LL_DEBUGS("AudioEngine") << "LLAudioEngine::startNextTransfer()" << LL_ENDL; if (mCurrentTransfer.notNull() || getMuted()) { - //llinfos << "Transfer in progress, aborting" << llendl; + //LL_DEBUGS("AudioEngine") << "Transfer in progress, aborting" << LL_ENDL; return; } @@ -1203,7 +1210,7 @@ void LLAudioEngine::startNextTransfer() if (asset_id.notNull()) { - llinfos << "Getting asset data for: " << asset_id << llendl; + LL_INFOS("AudioEngine") << "Getting audio asset data for: " << asset_id << LL_ENDL; gAudiop->mCurrentTransfer = asset_id; gAudiop->mCurrentTransferTimer.reset(); gAssetStorage->getAssetData(asset_id, LLAssetType::AT_SOUND, @@ -1211,7 +1218,7 @@ void LLAudioEngine::startNextTransfer() } else { - //llinfos << "No pending transfers?" << llendl; + //LL_DEBUGS("AudioEngine") << "No pending transfers?" << LL_ENDL; } } @@ -1221,7 +1228,7 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E { if (result_code) { - llinfos << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << llendl; + LL_INFOS("AudioEngine") << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << LL_ENDL; // Need to mark data as bad to avoid constant rerequests. LLAudioData *adp = gAudiop->getAudioData(uuid); if (adp) @@ -1238,11 +1245,11 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E if (!adp) { // Should never happen - llwarns << "Got asset callback without audio data for " << uuid << llendl; + LL_WARNS("AudioEngine") << "Got asset callback without audio data for " << uuid << LL_ENDL; } else { - // llinfos << "Got asset callback with good audio data for " << uuid << ", making decode request" << llendl; + LL_DEBUGS("AudioEngine") << "Got asset callback with good audio data for " << uuid << ", making decode request" << LL_ENDL; adp->setHasValidData(true); adp->setHasLocalData(true); gAudioDecodeMgrp->addDecodeRequest(uuid); @@ -1321,7 +1328,7 @@ void LLAudioSource::update() } else if (adp->hasCompletedDecode()) // Only mark corrupted after decode is done { - llwarns << "Marking LLAudioSource corrupted for " << adp->getID() << llendl; + LL_WARNS("AudioEngine") << "Marking LLAudioSource corrupted for " << adp->getID() << LL_ENDL; mCorrupted = true ; } } @@ -1357,7 +1364,6 @@ bool LLAudioSource::setupChannel() if (!adp->getBuffer()) { // We're not ready to play back the sound yet, so don't try and allocate a channel for it. - //llwarns << "Aborting, no buffer" << llendl; return false; } @@ -1375,7 +1381,7 @@ bool LLAudioSource::setupChannel() // Ugh, we don't have any free channels. // Now we have to reprioritize. // For now, just don't play the sound. - //llwarns << "Aborting, no free channels" << llendl; + //llwarns << "Aborting, no free channels" << LL_ENDL; return false; } @@ -1474,7 +1480,7 @@ bool LLAudioSource::isDone() const { // We don't have a channel assigned, and it's been // over 15 seconds since we tried to play it. Don't bother. - //llinfos << "No channel assigned, source is done" << llendl; + LL_DEBUGS("AudioEngine") << "No channel assigned, source is done" << LL_ENDL; return true; } else @@ -1640,7 +1646,7 @@ LLAudioChannel::LLAudioChannel() : LLAudioChannel::~LLAudioChannel() { // Need to disconnect any sources which are using this channel. - //llinfos << "Cleaning up audio channel" << llendl; + LL_DEBUGS("AudioEngine") << "Cleaning up audio channel" << LL_ENDL; if (mCurrentSourcep) { mCurrentSourcep->setChannel(NULL); @@ -1651,29 +1657,29 @@ LLAudioChannel::~LLAudioChannel() void LLAudioChannel::setSource(LLAudioSource *sourcep) { - //llinfos << this << ": setSource(" << sourcep << ")" << llendl; - if (!sourcep) { // Clearing the source for this channel, don't need to do anything. - //llinfos << "Clearing source for channel" << llendl; + LL_DEBUGS("AudioEngine") << "Clearing source" << ( mCurrentSourcep ? mCurrentSourcep->getID() : LLUUID::null ) << LL_ENDL; cleanup(); mCurrentSourcep = NULL; mWaiting = false; - return; } - - if (sourcep == mCurrentSourcep) + else { - // Don't reallocate the channel, this will make FMOD goofy. - //llinfos << "Calling setSource with same source!" << llendl; - } - - mCurrentSourcep = sourcep; + LL_DEBUGS("AudioEngine") << "( id: " << sourcep->getID() << ")" << LL_ENDL; + if (sourcep == mCurrentSourcep) + { + // Don't reallocate the channel, this will make FMOD goofy. + //LL_DEBUGS("AudioEngine") << "Calling setSource with same source!" << LL_ENDL; + } - updateBuffer(); - update3DPosition(); + mCurrentSourcep = sourcep; + + updateBuffer(); + update3DPosition(); + } } @@ -1768,7 +1774,7 @@ bool LLAudioData::load() if (mBufferp) { // We already have this sound in a buffer, don't do anything. - llinfos << "Already have a buffer for this sound, don't bother loading!" << llendl; + LL_INFOS("AudioEngine") << "Already have a buffer for this sound, don't bother loading!" << LL_ENDL; return true; } @@ -1776,7 +1782,7 @@ bool LLAudioData::load() if (!mBufferp) { // No free buffers, abort. - llinfos << "Not able to allocate a new audio buffer, aborting." << llendl; + LL_INFOS("AudioEngine") << "Not able to allocate a new audio buffer, aborting." << LL_ENDL; return true; } diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp index e9b74b8f41..36e8044a25 100644 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ b/indra/llaudio/llaudioengine_fmodex.cpp @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -55,11 +55,13 @@ LLAudioEngine_FMODEX::LLAudioEngine_FMODEX(bool enable_profiler) mWindDSP = NULL; mSystem = NULL; mEnableProfiler = enable_profiler; + mWindDSPDesc = new FMOD_DSP_DESCRIPTION(); } LLAudioEngine_FMODEX::~LLAudioEngine_FMODEX() { + delete mWindDSPDesc; } @@ -320,8 +322,8 @@ void LLAudioEngine_FMODEX::shutdown() llinfos << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << llendl; if ( mSystem ) // speculative fix for MAINT-2657 { - mSystem->close(); - mSystem->release(); + mSystem->close(); + mSystem->release(); } llinfos << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << llendl; @@ -347,15 +349,14 @@ bool LLAudioEngine_FMODEX::initWind() if (!mWindDSP) { - FMOD_DSP_DESCRIPTION dspdesc; - memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); //Set everything to zero - strncpy(dspdesc.name,"Wind Unit", sizeof(dspdesc.name)); //Set name to "Wind Unit" - dspdesc.channels=2; - dspdesc.read = &windCallback; //Assign callback. - if(Check_FMOD_Error(mSystem->createDSP(&dspdesc, &mWindDSP), "FMOD::createDSP")) + memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero + strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name)); + mWindDSPDesc->channels = 2; + mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads + if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) return false; - if(mWindGen) + if (mWindGen) delete mWindGen; float frequency = 44100; @@ -364,6 +365,7 @@ bool LLAudioEngine_FMODEX::initWind() mWindDSP->setUserData((void*)mWindGen); } + // *TODO: Should this guard against multiple plays? if (mWindDSP) { mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0); @@ -741,6 +743,9 @@ void LLAudioChannelFMODEX::set3DMode(bool use3d) } } +// *NOTE: This is almost certainly being called on the mixer thread, +// not the main thread. May have implications for callees or audio +// engine shutdown. FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbuffer, float *newbuffer, unsigned int length, int inchannels, int outchannels) { diff --git a/indra/llaudio/llaudioengine_fmodex.h b/indra/llaudio/llaudioengine_fmodex.h index 415a9ed0ef..ca389d489f 100644 --- a/indra/llaudio/llaudioengine_fmodex.h +++ b/indra/llaudio/llaudioengine_fmodex.h @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -41,6 +41,7 @@ namespace FMOD class Sound; class DSP; } +typedef struct FMOD_DSP_DESCRIPTION FMOD_DSP_DESCRIPTION; //Interfaces class LLAudioEngine_FMODEX : public LLAudioEngine @@ -74,6 +75,7 @@ protected: LLWindGen<MIXBUFFERFORMAT> *mWindGen; + FMOD_DSP_DESCRIPTION *mWindDSPDesc; FMOD::DSP *mWindDSP; FMOD::System *mSystem; bool mEnableProfiler; diff --git a/indra/llaudio/lllistener_fmodex.cpp b/indra/llaudio/lllistener_fmodex.cpp index 2509a7aebc..31ab47a635 100644 --- a/indra/llaudio/lllistener_fmodex.cpp +++ b/indra/llaudio/lllistener_fmodex.cpp @@ -94,6 +94,11 @@ void LLListener_FMODEX::orient(LLVector3 up, LLVector3 at) //----------------------------------------------------------------------- void LLListener_FMODEX::commitDeferredChanges() { + if(!mSystem) + { + return; + } + mSystem->update(); } diff --git a/indra/llcharacter/llbvhloader.cpp b/indra/llcharacter/llbvhloader.cpp index 2a0df26384..8c02a25367 100755 --- a/indra/llcharacter/llbvhloader.cpp +++ b/indra/llcharacter/llbvhloader.cpp @@ -203,6 +203,7 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error LLBVHLoader::~LLBVHLoader() { std::for_each(mJoints.begin(),mJoints.end(),DeletePointer()); + mJoints.clear(); } //------------------------------------------------------------------------ diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 07ef52228e..2241a59513 100755 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -81,7 +81,9 @@ LLKeyframeMotion::JointMotionList::JointMotionList() LLKeyframeMotion::JointMotionList::~JointMotionList() { for_each(mConstraints.begin(), mConstraints.end(), DeletePointer()); + mConstraints.clear(); for_each(mJointMotionArray.begin(), mJointMotionArray.end(), DeletePointer()); + mJointMotionArray.clear(); } U32 LLKeyframeMotion::JointMotionList::dumpDiagInfo() @@ -447,6 +449,7 @@ LLKeyframeMotion::LLKeyframeMotion(const LLUUID &id) LLKeyframeMotion::~LLKeyframeMotion() { for_each(mConstraints.begin(), mConstraints.end(), DeletePointer()); + mConstraints.clear(); } //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llmultigesture.cpp b/indra/llcharacter/llmultigesture.cpp index e2d284834f..411bb094fd 100755 --- a/indra/llcharacter/llmultigesture.cpp +++ b/indra/llcharacter/llmultigesture.cpp @@ -59,6 +59,7 @@ LLMultiGesture::LLMultiGesture() LLMultiGesture::~LLMultiGesture() { std::for_each(mSteps.begin(), mSteps.end(), DeletePointer()); + mSteps.clear(); } void LLMultiGesture::reset() diff --git a/indra/llcharacter/llpose.cpp b/indra/llcharacter/llpose.cpp index 55e1b6e9ea..b1a7ebb159 100755 --- a/indra/llcharacter/llpose.cpp +++ b/indra/llcharacter/llpose.cpp @@ -461,6 +461,7 @@ LLPoseBlender::LLPoseBlender() LLPoseBlender::~LLPoseBlender() { for_each(mJointStateBlenderPool.begin(), mJointStateBlenderPool.end(), DeletePairedPointer()); + mJointStateBlenderPool.clear(); } //----------------------------------------------------------------------------- diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp index 642bd82e90..d12f157910 100755 --- a/indra/llcommon/llavatarname.cpp +++ b/indra/llcommon/llavatarname.cpp @@ -44,6 +44,7 @@ static const std::string DISPLAY_NAME_EXPIRES("display_name_expires"); static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update"); bool LLAvatarName::sUseDisplayNames = true; +bool LLAvatarName::sUseUsernames = true; // Minimum time-to-live (in seconds) for a name entry. // Avatar name should always guarantee to expire reasonably soon by default @@ -81,6 +82,16 @@ bool LLAvatarName::useDisplayNames() return sUseDisplayNames; } +void LLAvatarName::setUseUsernames(bool use) +{ + sUseUsernames = use; +} + +bool LLAvatarName::useUsernames() +{ + return sUseUsernames; +} + LLSD LLAvatarName::asLLSD() const { LLSD sd; @@ -168,7 +179,11 @@ std::string LLAvatarName::getCompleteName() const } else { - name = mDisplayName + " (" + mUsername + ")"; + name = mDisplayName; + if(sUseUsernames) + { + name += " (" + mUsername + ")"; + } } } else diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h index 5d2fccc5ba..1cb3ae421f 100755 --- a/indra/llcommon/llavatarname.h +++ b/indra/llcommon/llavatarname.h @@ -54,6 +54,9 @@ public: static void setUseDisplayNames(bool use); static bool useDisplayNames(); + static void setUseUsernames(bool use); + static bool useUsernames(); + // A name object is valid if not temporary and not yet expired (default is expiration not checked) bool isValidName(F64 max_unrefreshed = 0.0f) const { return !mIsTemporaryName && (mExpires >= max_unrefreshed); } @@ -128,6 +131,9 @@ private: // Global flag indicating if display name should be used or not // This will affect the output of the high level "get" methods static bool sUseDisplayNames; + + // Flag indicating if username should be shown after display name or not + static bool sUseUsernames; }; #endif diff --git a/indra/llcommon/lldeadmantimer.h b/indra/llcommon/lldeadmantimer.h index 0dde16b717..980976e176 100644 --- a/indra/llcommon/lldeadmantimer.h +++ b/indra/llcommon/lldeadmantimer.h @@ -155,11 +155,9 @@ public: /// void ringBell(time_type now, unsigned int count); - /// Checks on the status of the timer Declare that something interesting happened. This has two - /// effects on an unexpired-timer. 1) The expiration time - /// is extended for 'horizon' seconds after the 'now' value. - /// 2) An internal counter associated with the event is incremented. - /// This count is returned via the @see isExpired() method. + /// Checks the status of the timer. If the timer has expired, + /// also returns various timer-related stats. Unlike ringBell(), + /// does not extend the horizon, it only checks for expiration. /// /// @param now Current time as returned by @see /// LLTimer::getCurrentClockCount(). If zero, @@ -192,7 +190,7 @@ public: bool isExpired(time_type now, F64 & started, F64 & stopped, U64 & count, U64 & user_cpu, U64 & sys_cpu); - /// Identical to the six-arugment form except is does without the + /// Identical to the six-arugment form except it does without the /// CPU time return if the caller isn't interested in it. bool isExpired(time_type now, F64 & started, F64 & stopped, U64 & count); diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index d2af004cde..853f279c95 100755 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -429,8 +429,8 @@ namespace LLError ~Settings() { - for_each(recorders.begin(), recorders.end(), - DeletePointer()); + for_each(recorders.begin(), recorders.end(), DeletePointer()); + recorders.clear(); } static Settings*& getPtr(); diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index 01b6e60d2b..58db7d0d17 100755 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -119,6 +119,7 @@ public: ~NamedTimerFactory() { std::for_each(mTimers.begin(), mTimers.end(), DeletePairedPointer()); + mTimers.clear(); delete mTimerRoot; } diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 8276ec836a..f962485284 100755 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -506,6 +506,8 @@ namespace LLSD::array_iterator beginArray() { return mData.begin(); } LLSD::array_iterator endArray() { return mData.end(); } + LLSD::reverse_array_iterator rbeginArray() { return mData.rbegin(); } + LLSD::reverse_array_iterator rendArray() { return mData.rend(); } virtual LLSD::array_const_iterator beginArray() const { return mData.begin(); } virtual LLSD::array_const_iterator endArray() const { return mData.end(); } @@ -947,6 +949,9 @@ LLSD::array_iterator LLSD::endArray() { return makeArray(impl).endArray(); } LLSD::array_const_iterator LLSD::beginArray() const{ return safe(impl).beginArray(); } LLSD::array_const_iterator LLSD::endArray() const { return safe(impl).endArray(); } +LLSD::reverse_array_iterator LLSD::rbeginArray() { return makeArray(impl).rbeginArray(); } +LLSD::reverse_array_iterator LLSD::rendArray() { return makeArray(impl).rendArray(); } + namespace llsd { diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index 5eb69059ac..deb87d7497 100755 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -320,11 +320,15 @@ public: typedef std::vector<LLSD>::iterator array_iterator; typedef std::vector<LLSD>::const_iterator array_const_iterator; + typedef std::vector<LLSD>::reverse_iterator reverse_array_iterator; array_iterator beginArray(); array_iterator endArray(); array_const_iterator beginArray() const; array_const_iterator endArray() const; + + reverse_array_iterator rbeginArray(); + reverse_array_iterator rendArray(); //@} /** @name Type Testing */ diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h index d3941e1bc9..0a39288f5a 100755 --- a/indra/llcommon/llstl.h +++ b/indra/llcommon/llstl.h @@ -98,6 +98,7 @@ struct DeletePointerArray // The general form is: // // std::for_each(somemap.begin(), somemap.end(), DeletePairedPointer()); +// somemap.clear(); // Don't leave dangling pointers around struct DeletePairedPointer { diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 0730b2ed8b..e63045659e 100755 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -114,6 +114,9 @@ static const F32 MEM_INFO_THROTTLE = 20; static const F32 MEM_INFO_WINDOW = 10*60; #if LL_WINDOWS +// We cannot trust GetVersionEx function on Win8.1 , we should check this value when creating OS string +static const U32 WINNT_WINBLUE = 0x0603; + #ifndef DLLVERSIONINFO typedef struct _DllVersionInfo { @@ -214,6 +217,26 @@ static bool regex_search_no_exc(const S& string, M& match, const R& regex) } } +#if LL_WINDOWS +// GetVersionEx should not works correct with Windows 8.1 and the later version. We need to check this case +static bool check_for_version(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor) +{ + OSVERSIONINFOEXW osvi = { sizeof(osvi), 0, 0, 0, 0, {0}, 0, 0 }; + DWORDLONG const dwlConditionMask = VerSetConditionMask( + VerSetConditionMask( + VerSetConditionMask( + 0, VER_MAJORVERSION, VER_GREATER_EQUAL), + VER_MINORVERSION, VER_GREATER_EQUAL), + VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); + + osvi.dwMajorVersion = wMajorVersion; + osvi.dwMinorVersion = wMinorVersion; + osvi.wServicePackMajor = wServicePackMajor; + + return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE; +} +#endif + LLOSInfo::LLOSInfo() : mMajorVer(0), mMinorVer(0), mBuild(0), mOSVersionString("") @@ -222,6 +245,7 @@ LLOSInfo::LLOSInfo() : #if LL_WINDOWS OSVERSIONINFOEX osvi; BOOL bOsVersionInfoEx; + BOOL bShouldUseShellVersion = false; // Try calling GetVersionEx using the OSVERSIONINFOEX structure. ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); @@ -284,11 +308,19 @@ LLOSInfo::LLOSInfo() : } else if(osvi.dwMinorVersion == 2) { + if (check_for_version(HIBYTE(WINNT_WINBLUE), LOBYTE(WINNT_WINBLUE), 0)) + { + mOSStringSimple = "Microsoft Windows 8.1 "; + bShouldUseShellVersion = true; // GetVersionEx failed, going to use shell version + } + else + { if(osvi.wProductType == VER_NT_WORKSTATION) mOSStringSimple = "Microsoft Windows 8 "; else mOSStringSimple = "Windows Server 2012 "; } + } ///get native system info if available.. typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); ///function pointer for loading GetNativeSystemInfo @@ -354,9 +386,8 @@ LLOSInfo::LLOSInfo() : } else { - tmpstr = llformat("%s (Build %d)", - csdversion.c_str(), - (osvi.dwBuildNumber & 0xffff)); + tmpstr = !bShouldUseShellVersion ? llformat("%s (Build %d)", csdversion.c_str(), (osvi.dwBuildNumber & 0xffff)): + llformat("%s (Build %d)", csdversion.c_str(), shell32_build); } mOSString = mOSStringSimple + tmpstr; @@ -392,7 +423,7 @@ LLOSInfo::LLOSInfo() : std::string compatibility_mode; if(got_shell32_version) { - if(osvi.dwMajorVersion != shell32_major || osvi.dwMinorVersion != shell32_minor) + if((osvi.dwMajorVersion != shell32_major || osvi.dwMinorVersion != shell32_minor) && !bShouldUseShellVersion) { compatibility_mode = llformat(" compatibility mode. real ver: %d.%d (Build %d)", shell32_major, diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index fb2d43e3b0..aa66ceb4ec 100755 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -44,7 +44,7 @@ #include "llsdserialize.h" #include "llproxy.h" -LLPumpIO* gServicePump; +LLPumpIO* gServicePump = NULL; BOOL gBreak = false; BOOL gSent = false; @@ -80,7 +80,8 @@ LLCrashLogger::LLCrashLogger() : LLCrashLogger::~LLCrashLogger() { - + delete gServicePump; + gServicePump = NULL; } // TRIM_SIZE must remain larger than LINE_SEARCH_SIZE. diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp index 37c603348e..5eb5fb442d 100755 --- a/indra/llinventory/llparcel.cpp +++ b/indra/llinventory/llparcel.cpp @@ -414,117 +414,6 @@ BOOL LLParcel::allowTerraformBy(const LLUUID &agent_id) const } -bool LLParcel::isAgentBlockedFromParcel(LLParcel* parcelp, - const LLUUID& agent_id, - const uuid_vec_t& group_ids, - const BOOL is_agent_identified, - const BOOL is_agent_transacted, - const BOOL is_agent_ageverified) -{ - S32 current_group_access = parcelp->blockAccess(agent_id, LLUUID::null, is_agent_identified, is_agent_transacted, is_agent_ageverified); - S32 count; - bool is_allowed = (current_group_access == BA_ALLOWED) ? true: false; - LLUUID group_id; - - count = group_ids.size(); - for (int i = 0; i < count && !is_allowed; i++) - { - group_id = group_ids[i]; - current_group_access = parcelp->blockAccess(agent_id, group_id, is_agent_identified, is_agent_transacted, is_agent_ageverified); - - if (current_group_access == BA_ALLOWED) is_allowed = true; - } - - return !is_allowed; -} - -BOOL LLParcel::isAgentBanned(const LLUUID& agent_id) const -{ - // Test ban list - if (mBanList.find(agent_id) != mBanList.end()) - { - return TRUE; - } - - return FALSE; -} - -S32 LLParcel::blockAccess(const LLUUID& agent_id, const LLUUID& group_id, - const BOOL is_agent_identified, - const BOOL is_agent_transacted, - const BOOL is_agent_ageverified) const -{ - // Test ban list - if (isAgentBanned(agent_id)) - { - return BA_BANNED; - } - - // Always allow owner on (unless he banned himself, useful for - // testing). We will also allow estate owners/managers in if they - // are not explicitly banned. - if (agent_id == mOwnerID) - { - return BA_ALLOWED; - } - - // Special case when using pass list where group access is being restricted but not - // using access list. In this case group members are allowed only if they buy a pass. - // We return BA_NOT_IN_LIST if not in list - BOOL passWithGroup = getParcelFlag(PF_USE_PASS_LIST) && !getParcelFlag(PF_USE_ACCESS_LIST) - && getParcelFlag(PF_USE_ACCESS_GROUP) && !mGroupID.isNull() && group_id == mGroupID; - - - // Test group list - if (getParcelFlag(PF_USE_ACCESS_GROUP) - && !mGroupID.isNull() - && group_id == mGroupID - && !passWithGroup) - { - return BA_ALLOWED; - } - - // Test access list - if (getParcelFlag(PF_USE_ACCESS_LIST) || passWithGroup ) - { - if (mAccessList.find(agent_id) != mAccessList.end()) - { - return BA_ALLOWED; - } - - return BA_NOT_ON_LIST; - } - - // If we're not doing any other limitations, all users - // can enter, unless - if ( !getParcelFlag(PF_USE_ACCESS_GROUP) - && !getParcelFlag(PF_USE_ACCESS_LIST)) - { - //If the land is group owned, and you are in the group, bypass these checks - if(getIsGroupOwned() && group_id == mGroupID) - { - return BA_ALLOWED; - } - - // Test for "payment" access levels - // Anonymous - No Payment Info on File - if(getParcelFlag(PF_DENY_ANONYMOUS) && !is_agent_identified && !is_agent_transacted) - { - return BA_NO_ACCESS_LEVEL; - } - // AgeUnverified - Not Age Verified - if(getParcelFlag(PF_DENY_AGEUNVERIFIED) && !is_agent_ageverified) - { - return BA_NOT_AGE_VERIFIED; - } - - return BA_ALLOWED; - } - - return BA_NOT_IN_GROUP; - -} - void LLParcel::setArea(S32 area, S32 sim_object_limit) { diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h index 0279e8bef9..c4363a48df 100755 --- a/indra/llinventory/llparcel.h +++ b/indra/llinventory/llparcel.h @@ -527,23 +527,6 @@ public: // Can this agent change the shape of the land? BOOL allowTerraformBy(const LLUUID &agent_id) const; - // Returns 0 if access is OK, otherwise a BA_ return code above. - S32 blockAccess(const LLUUID& agent_id, - const LLUUID& group_id, - const BOOL is_agent_identified, - const BOOL is_agent_transacted, - const BOOL is_agent_ageverified) const; - - // Only checks if the agent is explicitly banned from this parcel - BOOL isAgentBanned(const LLUUID& agent_id) const; - - static bool isAgentBlockedFromParcel(LLParcel* parcelp, - const LLUUID& agent_id, - const uuid_vec_t& group_ids, - const BOOL is_agent_identified, - const BOOL is_agent_transacted, - const BOOL is_agent_ageverified); - bool operator==(const LLParcel &rhs) const; // Calculate rent - area * rent * discount rate diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 2b865b4a8e..cc5742ff7a 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -166,7 +166,8 @@ void calc_tangent_from_triangle( F32 rd = s1*t2-s2*t1; - float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero + float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd) + : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero llassert(llfinite(r)); llassert(!llisnan(r)); @@ -6746,7 +6747,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build) return TRUE; } -//adapted from Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”. Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html +//adapted from Lengyel, Eric. "Computing Tangent Space Basis Vectors for an Arbitrary Mesh". Terathon Software 3D Graphics Library, 2001. http://www.terathon.com/code/tangent.html void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVector4a *normal, const LLVector2 *texcoord, U32 triangleCount, const U16* index_array, LLVector4a *tangent) { @@ -6789,7 +6790,8 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe F32 rd = s1*t2-s2*t1; - float r = ((rd*rd) > FLT_EPSILON) ? 1.0F / rd : 1024.f; //some made up large ratio for division by zero + float r = ((rd*rd) > FLT_EPSILON) ? (1.0f / rd) + : ((rd > 0.0f) ? 1024.f : -1024.f); //some made up large ratio for division by zero llassert(llfinite(r)); llassert(!llisnan(r)); diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index b047f86e6e..8c8c315808 100755 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -50,7 +50,7 @@ class LLColor4 LLColor4(F32 r, F32 g, F32 b); // Initializes LLColor4 to (r, g, b, 1) LLColor4(F32 r, F32 g, F32 b, F32 a); // Initializes LLColor4 to (r. g, b, a) LLColor4(U32 clr); // Initializes LLColor4 to (r=clr>>24, etc)) - LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1) + LLColor4(const F32 *vec); // Initializes LLColor4 to (vec[0]. vec[1], vec[2], vec[3]) LLColor4(const LLColor3 &vec, F32 a = 1.f); // Initializes LLColor4 to (vec, a) explicit LLColor4(const LLSD& sd); explicit LLColor4(const LLColor4U& color4u); // "explicit" to avoid automatic conversion diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index 9a68093427..31dd264021 100755 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -680,6 +680,15 @@ void LLAvatarNameCache::setUseDisplayNames(bool use) } } +void LLAvatarNameCache::setUseUsernames(bool use) +{ + if (use != LLAvatarName::useUsernames()) + { + LLAvatarName::setUseUsernames(use); + mUseDisplayNamesSignal(); + } +} + void LLAvatarNameCache::erase(const LLUUID& agent_id) { sCache.erase(agent_id); diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 2a8eb46187..3a19cee3ed 100755 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -80,6 +80,8 @@ namespace LLAvatarNameCache // Set display name: flips the switch and triggers the callbacks. void setUseDisplayNames(bool use); + void setUseUsernames(bool use); + void insert(const LLUUID& agent_id, const LLAvatarName& av_name); void erase(const LLUUID& agent_id); diff --git a/indra/llmessage/llbuffer.cpp b/indra/llmessage/llbuffer.cpp index 01da20f060..aaa49d2ed6 100755 --- a/indra/llmessage/llbuffer.cpp +++ b/indra/llmessage/llbuffer.cpp @@ -225,7 +225,7 @@ LLBufferArray::LLBufferArray() : LLBufferArray::~LLBufferArray() { std::for_each(mBuffers.begin(), mBuffers.end(), DeletePointer()); - + mBuffers.clear(); delete mMutexp; } diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp index 267c48e1d2..13d779ff83 100755 --- a/indra/llmessage/llcachename.cpp +++ b/indra/llmessage/llcachename.cpp @@ -278,7 +278,9 @@ LLCacheName::Impl::Impl(LLMessageSystem* msg) LLCacheName::Impl::~Impl() { for_each(mCache.begin(), mCache.end(), DeletePairedPointer()); + mCache.clear(); for_each(mReplyQueue.begin(), mReplyQueue.end(), DeletePointer()); + mReplyQueue.clear(); } boost::signals2::connection LLCacheName::Impl::addPending(const LLUUID& id, const LLCacheNameCallback& callback) diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp index efbc804cbc..9e68c68858 100755 --- a/indra/llmessage/llcurl.cpp +++ b/indra/llmessage/llcurl.cpp @@ -296,7 +296,7 @@ LLCurl::Easy* LLCurl::Easy::getEasy() // Enable a brief cache period for now. This was zero for the longest time // which caused some routers grief and generated unneeded traffic. For the - // threded resolver, we're using system resolution libraries and non-zero values + // threaded resolver, we're using system resolution libraries and non-zero values // are preferred. The c-ares resolver is another matter and it might not // track server changes as well. CURLcode result = curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 15); @@ -1741,6 +1741,7 @@ void LLCurl::cleanupClass() #if SAFE_SSL CRYPTO_set_locking_callback(NULL); for_each(sSSLMutex.begin(), sSSLMutex.end(), DeletePointer()); + sSSLMutex.clear(); #endif LL_CHECK_MEMORY diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp index 6110b035dc..11648717ad 100755 --- a/indra/llmessage/llhttpclient.cpp +++ b/indra/llmessage/llhttpclient.cpp @@ -217,7 +217,8 @@ static void request( Injector* body_injector, LLCurl::ResponderPtr responder, const F32 timeout = HTTP_REQUEST_EXPIRY_SECS, - const LLSD& headers = LLSD() + const LLSD& headers = LLSD(), + bool follow_redirects = true ) { if (!LLHTTPClient::hasPump()) @@ -231,7 +232,7 @@ static void request( } LLPumpIO::chain_t chain; - LLURLRequest* req = new LLURLRequest(method, url); + LLURLRequest* req = new LLURLRequest(method, url, follow_redirects); if(!req->isValid())//failed { if (responder) @@ -334,7 +335,8 @@ void LLHTTPClient::getByteRange( S32 bytes, ResponderPtr responder, const LLSD& hdrs, - const F32 timeout) + const F32 timeout, + bool follow_redirects /* = true */) { LLSD headers = hdrs; if(offset > 0 || bytes > 0) @@ -342,37 +344,42 @@ void LLHTTPClient::getByteRange( std::string range = llformat("bytes=%d-%d", offset, offset+bytes-1); headers["Range"] = range; } - request(url,LLURLRequest::HTTP_GET, NULL, responder, timeout, headers); + request(url,LLURLRequest::HTTP_GET, NULL, responder, timeout, headers, follow_redirects); } void LLHTTPClient::head( const std::string& url, ResponderPtr responder, const LLSD& headers, - const F32 timeout) + const F32 timeout, + bool follow_redirects /* = true */) { - request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers); + request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers, follow_redirects); } -void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout) +void LLHTTPClient::get(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout, + bool follow_redirects /* = true */) { - request(url, LLURLRequest::HTTP_GET, NULL, responder, timeout, headers); + request(url, LLURLRequest::HTTP_GET, NULL, responder, timeout, headers, follow_redirects); } -void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const LLSD& headers, const F32 timeout) +void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const LLSD& headers, + const F32 timeout, bool follow_redirects /* = true */) { - request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers); + request(url, LLURLRequest::HTTP_HEAD, NULL, responder, timeout, headers, follow_redirects); } -void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const F32 timeout) +void LLHTTPClient::getHeaderOnly(const std::string& url, ResponderPtr responder, const F32 timeout, + bool follow_redirects /* = true */) { - getHeaderOnly(url, responder, LLSD(), timeout); + getHeaderOnly(url, responder, LLSD(), timeout, follow_redirects); } -void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const LLSD& headers, const F32 timeout) +void LLHTTPClient::get(const std::string& url, const LLSD& query, ResponderPtr responder, const LLSD& headers, + const F32 timeout, bool follow_redirects /* = true */) { LLURI uri; uri = LLURI::buildHTTP(url, LLSD::emptyArray(), query); - get(uri.asString(), responder, headers, timeout); + get(uri.asString(), responder, headers, timeout, follow_redirects); } // A simple class for managing data returned from a curl http request. diff --git a/indra/llmessage/llhttpclient.h b/indra/llmessage/llhttpclient.h index a7236ba169..5de257a4f6 100755 --- a/indra/llmessage/llhttpclient.h +++ b/indra/llmessage/llhttpclient.h @@ -63,10 +63,15 @@ public: const std::string& url, ResponderPtr, const LLSD& headers = LLSD(), - const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); - static void getByteRange(const std::string& url, S32 offset, S32 bytes, ResponderPtr, const LLSD& headers=LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); - static void get(const std::string& url, ResponderPtr, const LLSD& headers = LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); - static void get(const std::string& url, const LLSD& query, ResponderPtr, const LLSD& headers = LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); + const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, + bool follow_redirects = true); + static void getByteRange(const std::string& url, S32 offset, S32 bytes, ResponderPtr, + const LLSD& headers=LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, + bool follow_redirects = true); + static void get(const std::string& url, ResponderPtr, const LLSD& headers = LLSD(), + const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, bool follow_redirects = true); + static void get(const std::string& url, const LLSD& query, ResponderPtr, const LLSD& headers = LLSD(), + const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, bool follow_redirects = true); static void put( const std::string& url, @@ -74,8 +79,10 @@ public: ResponderPtr, const LLSD& headers = LLSD(), const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); - static void getHeaderOnly(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); - static void getHeaderOnly(const std::string& url, ResponderPtr, const LLSD& headers, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS); + static void getHeaderOnly(const std::string& url, ResponderPtr, const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, + bool follow_redirects = true); + static void getHeaderOnly(const std::string& url, ResponderPtr, const LLSD& headers, + const F32 timeout=HTTP_REQUEST_EXPIRY_SECS, bool follow_redirects = true); static void post( const std::string& url, diff --git a/indra/llmessage/llhttpnode.cpp b/indra/llmessage/llhttpnode.cpp index 5c2f73eccb..f6ccb5bdda 100755 --- a/indra/llmessage/llhttpnode.cpp +++ b/indra/llmessage/llhttpnode.cpp @@ -76,8 +76,8 @@ LLHTTPNode::LLHTTPNode() // virtual LLHTTPNode::~LLHTTPNode() { - std::for_each(impl.mNamedChildren.begin(), impl.mNamedChildren.end(), - DeletePairedPointer()); + std::for_each(impl.mNamedChildren.begin(), impl.mNamedChildren.end(), DeletePairedPointer()); + impl.mNamedChildren.clear(); delete impl.mWildcardChild; diff --git a/indra/llmessage/llhttpsender.cpp b/indra/llmessage/llhttpsender.cpp index c48cbc42a6..d0bd343db6 100755 --- a/indra/llmessage/llhttpsender.cpp +++ b/indra/llmessage/llhttpsender.cpp @@ -38,7 +38,7 @@ namespace { typedef std::map<LLHost, LLHTTPSender*> SenderMap; static SenderMap senderMap; - static LLHTTPSender* defaultSender = new LLHTTPSender(); + static LLPointer<LLHTTPSender> defaultSender(new LLHTTPSender()); } //virtual @@ -90,6 +90,5 @@ void LLHTTPSender::clearSender(const LLHost& host) //static void LLHTTPSender::setDefaultSender(LLHTTPSender* sender) { - delete defaultSender; defaultSender = sender; } diff --git a/indra/llmessage/llhttpsender.h b/indra/llmessage/llhttpsender.h index 88920db24d..ff8fa2f95b 100755 --- a/indra/llmessage/llhttpsender.h +++ b/indra/llmessage/llhttpsender.h @@ -32,7 +32,7 @@ class LLHost; class LLSD; -class LLHTTPSender +class LLHTTPSender : public LLThreadSafeRefCount { public: diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h index db4a38ea9e..f7118f8ccf 100755 --- a/indra/llmessage/llinstantmessage.h +++ b/indra/llmessage/llinstantmessage.h @@ -126,7 +126,7 @@ enum EInstantMessage IM_LURE_ACCEPTED = 23, IM_LURE_DECLINED = 24, IM_GODLIKE_LURE_USER = 25, - IM_YET_TO_BE_USED = 26, + IM_TELEPORT_REQUEST = 26, // IM that notifie of a new group election. // Name is name of person who called vote. diff --git a/indra/llmessage/llmessagetemplate.h b/indra/llmessage/llmessagetemplate.h index ae8e0087c1..005a49cedf 100755 --- a/indra/llmessage/llmessagetemplate.h +++ b/indra/llmessage/llmessagetemplate.h @@ -118,6 +118,7 @@ public: ~LLMsgData() { for_each(mMemberBlocks.begin(), mMemberBlocks.end(), DeletePairedPointer()); + mMemberBlocks.clear(); } void addBlock(LLMsgBlkData *blockp) diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp index ab91f74abe..94bc7cb045 100755 --- a/indra/llmessage/lltemplatemessagereader.cpp +++ b/indra/llmessage/lltemplatemessagereader.cpp @@ -91,15 +91,17 @@ void LLTemplateMessageReader::getData(const char *blockname, const char *varname } LLMsgBlkData *msg_block_data = iter->second; - LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep]; + LLMsgBlkData::msg_var_data_map_t &var_data_map = msg_block_data->mMemberVarData; - if (!vardata.getName()) + if (var_data_map.find(vnamep) == var_data_map.end()) { llerrs << "Variable "<< vnamep << " not in message " << mCurrentRMessageData->mName<< " block " << bnamep << llendl; return; } + LLMsgVarData& vardata = msg_block_data->mMemberVarData[vnamep]; + if (size && size != vardata.getSize()) { llerrs << "Msg " << mCurrentRMessageData->mName diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp index de9e2fe294..683065357d 100755 --- a/indra/llmessage/llurlrequest.cpp +++ b/indra/llmessage/llurlrequest.cpp @@ -150,16 +150,19 @@ std::string LLURLRequest::actionAsVerb(LLURLRequest::ERequestAction action) return VERBS[action]; } -LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action) : - mAction(action) +LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action, bool follow_redirects /* = true */) : + mAction(action), + mFollowRedirects(follow_redirects) { initialize(); } LLURLRequest::LLURLRequest( LLURLRequest::ERequestAction action, - const std::string& url) : - mAction(action) + const std::string& url, + bool follow_redirects /* = true */) : + mAction(action), + mFollowRedirects(follow_redirects) { initialize(); setURL(url); @@ -479,12 +482,18 @@ bool LLURLRequest::configure() case HTTP_HEAD: mDetail->mCurlRequest->setopt(CURLOPT_HEADER, 1); mDetail->mCurlRequest->setopt(CURLOPT_NOBODY, 1); - mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1); + if (mFollowRedirects) + { + mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1); + } rv = true; break; case HTTP_GET: mDetail->mCurlRequest->setopt(CURLOPT_HTTPGET, 1); - mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1); + if (mFollowRedirects) + { + mDetail->mCurlRequest->setopt(CURLOPT_FOLLOWLOCATION, 1); + } // Set Accept-Encoding to allow response compression mDetail->mCurlRequest->setoptString(CURLOPT_ENCODING, ""); diff --git a/indra/llmessage/llurlrequest.h b/indra/llmessage/llurlrequest.h index 44d358d906..20d6e30d17 100755 --- a/indra/llmessage/llurlrequest.h +++ b/indra/llmessage/llurlrequest.h @@ -95,7 +95,7 @@ public: * * @param action One of the ERequestAction enumerations. */ - LLURLRequest(ERequestAction action); + LLURLRequest(ERequestAction action, bool follow_redirects = true); /** * @brief Constructor. @@ -103,7 +103,7 @@ public: * @param action One of the ERequestAction enumerations. * @param url The url of the request. It should already be encoded. */ - LLURLRequest(ERequestAction action, const std::string& url); + LLURLRequest(ERequestAction action, const std::string& url, bool follow_redirects = true); /** * @brief Destructor. @@ -219,10 +219,11 @@ protected: }; EState mState; ERequestAction mAction; + bool mFollowRedirects; LLURLRequestDetail* mDetail; LLIOPipe::ptr_t mCompletionCallback; - S32 mRequestTransferedBytes; - S32 mResponseTransferedBytes; + S32 mRequestTransferedBytes; + S32 mResponseTransferedBytes; static CURLcode _sslCtxCallback(CURL * curl, void *sslctx, void *param); diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp index ae95087377..c3642ccbe8 100755 --- a/indra/llmessage/message.cpp +++ b/indra/llmessage/message.cpp @@ -3032,12 +3032,23 @@ void LLMessageSystem::setExceptionFunc(EMessageException e, BOOL LLMessageSystem::callExceptionFunc(EMessageException exception) { callbacks_t::iterator it = mExceptionCallbacks.find(exception); - if(it != mExceptionCallbacks.end()) + if(it == mExceptionCallbacks.end()) { - ((*it).second.first)(this, (*it).second.second,exception); - return TRUE; + return FALSE; } - return FALSE; + + exception_t& ex = it->second; + msg_exception_callback ex_cb = ex.first; + + if (!ex_cb) + { + LL_WARNS("Messaging") << "LLMessageSystem::callExceptionFunc: bad message exception callback." << llendl; + return FALSE; + } + + (ex_cb)(this, ex.second, exception); + + return TRUE; } void LLMessageSystem::setTimingFunc(msg_timing_callback func, void* data) diff --git a/indra/llplugin/llplugincookiestore.cpp b/indra/llplugin/llplugincookiestore.cpp index 82017ab3fa..9f4d65e723 100755 --- a/indra/llplugin/llplugincookiestore.cpp +++ b/indra/llplugin/llplugincookiestore.cpp @@ -87,6 +87,16 @@ std::string LLPluginCookieStore::Cookie::getKey() const return result; } +std::string LLPluginCookieStore::Cookie::getDomain() const +{ + std::string result; + if(mDomainEnd > mDomainStart) + { + result += mCookie.substr(mDomainStart, mDomainEnd - mDomainStart); + } + return result; +} + bool LLPluginCookieStore::Cookie::parse(const std::string &host) { bool first_field = true; @@ -662,3 +672,21 @@ void LLPluginCookieStore::removeCookie(const std::string &key) } } +void LLPluginCookieStore::removeCookiesByDomain(const std::string &domain) +{ + cookie_map_t::iterator iter = mCookies.begin(); + while(iter != mCookies.end()) + { + if(iter->second->getDomain() == domain) + { + cookie_map_t::iterator doErase = iter; + iter++; + delete doErase->second; + mCookies.erase(doErase); + } + else + { + iter++; + } + } +} diff --git a/indra/llplugin/llplugincookiestore.h b/indra/llplugin/llplugincookiestore.h index 91289d38a5..a2fdeab647 100755 --- a/indra/llplugin/llplugincookiestore.h +++ b/indra/llplugin/llplugincookiestore.h @@ -67,6 +67,8 @@ public: // quote or unquote a string as per the definition of 'quoted-string' in rfc2616 static std::string quoteString(const std::string &s); static std::string unquoteString(const std::string &s); + + void removeCookiesByDomain(const std::string &domain); private: @@ -79,6 +81,7 @@ private: // Construct a string from the cookie that uniquely represents it, to be used as a key in a std::map. std::string getKey() const; + std::string getDomain() const; const std::string &getCookie() const { return mCookie; }; bool isSessionCookie() const { return mDate.isNull(); }; diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 058bef43a5..84c782e958 100755 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -125,6 +125,7 @@ LLFontFreetype::~LLFontFreetype() // Delete glyph info std::for_each(mCharGlyphInfoMap.begin(), mCharGlyphInfoMap.end(), DeletePairedPointer()); + mCharGlyphInfoMap.clear(); // mFontBitmapCachep will be cleaned up by LLPointer destructor. // mFallbackFonts cleaned up by LLPointer destructor diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 35620bb656..1c50a51d02 100755 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -717,7 +717,14 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms) BOOL LLGLSLShader::link(BOOL suppress_errors) { - return LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors); + BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors); + + if (!suppress_errors) + { + LLShaderMgr::instance()->dumpObjectLog(mProgramObject, !success, mName); + } + + return success; } void LLGLSLShader::bind() diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 0ac30b4d63..b481cf7095 100755 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -2196,7 +2196,15 @@ void LLRender::texCoord2fv(const GLfloat* tc) void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a) { - mColorsp[mCount] = LLColor4U(r,g,b,a); + if (!LLGLSLShader::sCurBoundShaderPtr || + LLGLSLShader::sCurBoundShaderPtr->mAttributeMask & LLVertexBuffer::MAP_COLOR) + { + mColorsp[mCount] = LLColor4U(r,g,b,a); + } + else + { //not using shaders or shader reads color from a uniform + diffuseColor4ub(r,g,b,a); + } } void LLRender::color4ubv(const GLubyte* c) { diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index b82b370d6e..fe8110904d 100755 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -364,35 +364,55 @@ void LLRenderTarget::release() sBytesAllocated -= mResX*mResY*4; } - else if (mUseDepth && mFBO) - { //detach shared depth buffer + else if (mFBO) + { glBindFramebuffer(GL_FRAMEBUFFER, mFBO); - if (mStencil) - { //attached as a renderbuffer - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); - glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); - mStencil = false; + + if (mUseDepth) + { //detach shared depth buffer + if (mStencil) + { //attached as a renderbuffer + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + mStencil = false; + } + else + { //attached as a texture + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0); + } + mUseDepth = false; } - else - { //attached as a texture - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, LLTexUnit::getInternalType(mUsage), 0, 0); + } + + // Detach any extra color buffers (e.g. SRGB spec buffers) + // + if (mFBO && (mTex.size() > 1)) + { + S32 z; + for (z = mTex.size() - 1; z >= 1; z--) + { + sBytesAllocated -= mResX*mResY*4; + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+z, LLTexUnit::getInternalType(mUsage), 0, 0); + stop_glerror(); + LLImageGL::deleteTextures(1, &mTex[z]); } - mUseDepth = false; } if (mFBO) { glDeleteFramebuffers(1, (GLuint *) &mFBO); + stop_glerror(); mFBO = 0; } if (mTex.size() > 0) { - sBytesAllocated -= mResX*mResY*4*mTex.size(); - LLImageGL::deleteTextures(mTex.size(), &mTex[0]); + sBytesAllocated -= mResX*mResY*4; + LLImageGL::deleteTextures(1, &mTex[0]); + } + mTex.clear(); mInternalFormat.clear(); - } mResX = mResY = 0; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index d230574752..6e04fc82df 100755 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -505,9 +505,25 @@ static std::string get_object_log(GLhandleARB ret) return res; } -void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns) +void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns, const std::string& filename) { std::string log = get_object_log(ret); + + if (log.length() > 0 || warns) + { + if (!filename.empty()) + { + if (warns) + { + LL_WARNS("ShaderLoading") << "From " << filename << ":" << LL_ENDL; + } + else + { + LL_INFOS("ShaderLoading") << "From " << filename << ":" << LL_ENDL; + } + } + } + if ( log.length() > 0 ) { if (warns) @@ -558,7 +574,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade file = LLFile::fopen(fname.str(), "r"); /* Flawfinder: ignore */ if (file) { - LL_INFOS("ShaderLoading") << "Loading file: shaders/class" << gpu_class << "/" << filename << " (Want class " << gpu_class << ")" << LL_ENDL; + LL_DEBUGS("ShaderLoading") << "Loading file: shaders/class" << gpu_class << "/" << filename << " (Want class " << gpu_class << ")" << LL_ENDL; break; // done } } @@ -812,8 +828,8 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade if (error != GL_NO_ERROR || success == GL_FALSE) { //an error occured, print log - LL_WARNS("ShaderLoading") << "GLSL Compilation Error: (" << error << ") in " << filename << LL_ENDL; - dumpObjectLog(ret); + LL_WARNS("ShaderLoading") << "GLSL Compilation Error:" << LL_ENDL; + dumpObjectLog(ret, TRUE, filename); #if LL_WINDOWS std::stringstream ostr; //dump shader source for debugging @@ -938,11 +954,6 @@ BOOL LLShaderMgr::linkProgramObject(GLhandleARB obj, BOOL suppress_errors) suppress_errors = FALSE; } #endif - if (!suppress_errors) - { - dumpObjectLog(obj, !success); - } - return success; } @@ -1146,6 +1157,7 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("env_intensity"); mReservedUniforms.push_back("matrixPalette"); + mReservedUniforms.push_back("translationPalette"); mReservedUniforms.push_back("screenTex"); mReservedUniforms.push_back("screenDepth"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 51c27fc8b6..394b38f832 100755 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -176,6 +176,7 @@ public: ENVIRONMENT_INTENSITY, AVATAR_MATRIX, + AVATAR_TRANSLATION, WATER_SCREENTEX, WATER_SCREENDEPTH, @@ -224,7 +225,7 @@ DISPLAY_GAMMA, virtual void initAttribsAndUniforms(void); BOOL attachShaderFeatures(LLGLSLShader * shader); - void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE); + void dumpObjectLog(GLhandleARB ret, BOOL warns = TRUE, const std::string& filename = ""); BOOL linkProgramObject(GLhandleARB obj, BOOL suppress_errors = FALSE); BOOL validateProgramObject(GLhandleARB obj); GLhandleARB loadShaderFile(const std::string& filename, S32 & shader_level, GLenum type, boost::unordered_map<std::string, std::string>* defines = NULL, S32 texture_index_channels = -1); diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index 34a08603fa..589ceac501 100755 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -75,6 +75,7 @@ set(llui_SOURCE_FILES llmultislider.cpp llmultisliderctrl.cpp llnotifications.cpp + llnotificationslistener.cpp llnotificationsutil.cpp llpanel.cpp llprogressbar.cpp @@ -128,6 +129,7 @@ set(llui_SOURCE_FILES llviewmodel.cpp llview.cpp llviewquery.cpp + llviewereventrecorder.cpp llwindowshade.cpp llxuiparser.cpp ) @@ -183,6 +185,7 @@ set(llui_HEADER_FILES llmultislider.h llnotificationptr.h llnotifications.h + llnotificationslistener.h llnotificationsutil.h llnotificationtemplate.h llnotificationvisibilityrule.h @@ -240,6 +243,7 @@ set(llui_HEADER_FILES llviewinject.h llviewmodel.h llview.h + llviewereventrecorder.h llviewquery.h llwindowshade.h llxuiparser.h diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 44f2c1efe9..3cfe5ac57f 100755 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -49,6 +49,7 @@ #include "lluictrlfactory.h" #include "llhelp.h" #include "lldockablefloater.h" +#include "llviewereventrecorder.h" static LLDefaultChildRegistry::Register<LLButton> r("button"); @@ -443,6 +444,8 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask) */ LLUICtrl::handleMouseDown(x, y, mask); + LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); + if(mMouseDownSignal) (*mMouseDownSignal)(this, LLSD()); mMouseDownTimer.start(); @@ -473,6 +476,7 @@ BOOL LLButton::handleMouseUp(S32 x, S32 y, MASK mask) * by calling LLUICtrl::mMouseUpSignal(x, y, mask); */ LLUICtrl::handleMouseUp(x, y, mask); + LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); // Regardless of where mouseup occurs, handle callback if(mMouseUpSignal) (*mMouseUpSignal)(this, LLSD()); @@ -637,7 +641,7 @@ void LLButton::draw() bool use_glow_effect = FALSE; LLColor4 highlighting_color = LLColor4::white; - LLColor4 glow_color; + LLColor4 glow_color = LLColor4::white; LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA; LLUIImage* imagep = NULL; diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h index e67f39b21b..3f13691a30 100755 --- a/indra/llui/llchatentry.h +++ b/indra/llui/llchatentry.h @@ -62,8 +62,8 @@ public: virtual void draw(); virtual void onCommit(); - /*virtual*/ void onFocusReceived(); - /*virtual*/ void onFocusLost(); + /*virtual*/ void onFocusReceived(); + /*virtual*/ void onFocusLost(); void enableSingleLineMode(bool single_line_mode); boost::signals2::connection setTextExpandedCallback(const commit_signal_t::slot_type& cb); diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index d4e14d9419..56be52f69a 100755 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -534,6 +534,13 @@ void LLComboBox::createLineEditor(const LLComboBox::Params& p) } } +void LLComboBox::setLeftTextPadding(S32 pad) +{ + S32 left_pad, right_pad; + mTextEntry->getTextPadding(&left_pad, &right_pad); + mTextEntry->setTextPadding(pad, right_pad); +} + void* LLComboBox::getCurrentUserdata() { LLScrollListItem* item = mList->getFirstSelected(); diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h index 64dbaea306..67393504e7 100755 --- a/indra/llui/llcombobox.h +++ b/indra/llui/llcombobox.h @@ -191,6 +191,8 @@ public: //======================================================================== + void setLeftTextPadding(S32 pad); + void* getCurrentUserdata(); void setPrearrangeCallback( commit_callback_t cb ) { mPrearrangeCallback = cb; } diff --git a/indra/llui/lldraghandle.cpp b/indra/llui/lldraghandle.cpp index 5f69c6af31..304d21d0df 100755 --- a/indra/llui/lldraghandle.cpp +++ b/indra/llui/lldraghandle.cpp @@ -315,14 +315,15 @@ BOOL LLDragHandle::handleHover(S32 x, S32 y, MASK mask) S32 delta_y = screen_y - mDragLastScreenY; // if dragging a docked floater we want to undock - if (((LLFloater*)getParent())->isDocked()) + LLFloater * parent = dynamic_cast<LLFloater *>(getParent()); + if (parent && parent->isDocked()) { const S32 SLOP = 12; if (delta_y <= -SLOP || delta_y >= SLOP) { - ((LLFloater*)getParent())->setDocked(false, false); + parent->setDocked(false, false); return TRUE; } else diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 273ceb4038..c462b2aa52 100755 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -29,7 +29,7 @@ // mini-map floater, etc. #include "linden_common.h" - +#include "llviewereventrecorder.h" #include "llfloater.h" #include "llfocusmgr.h" @@ -528,7 +528,6 @@ LLFloater::~LLFloater() setVisible(false); // We're not visible if we're destroyed storeVisibilityControl(); storeDockStateControl(); - delete mMinimizeSignal; } @@ -642,7 +641,10 @@ void LLFloater::handleVisibilityChange ( BOOL new_visibility ) void LLFloater::openFloater(const LLSD& key) { - llinfos << "Opening floater " << getName() << llendl; + llinfos << "Opening floater " << getName() << " full path: " << getPathname() << llendl; + + LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), true,"floater"); // Last param is event subtype or empty string + mKey = key; // in case we need to open ourselves again if (getSoundFlags() != SILENT @@ -696,6 +698,7 @@ void LLFloater::openFloater(const LLSD& key) void LLFloater::closeFloater(bool app_quitting) { llinfos << "Closing floater " << getName() << llendl; + LLViewerEventRecorder::instance().logVisibilityChange( getPathname(), getName(), false,"floater"); // Last param is event subtype or empty string if (app_quitting) { LLFloater::sQuitting = true; @@ -1134,7 +1137,11 @@ void LLFloater::handleReshape(const LLRect& new_rect, bool by_user) if (by_user && !getHost()) { - static_cast<LLFloaterView*>(getParent())->adjustToFitScreen(this, !isMinimized()); + LLFloaterView * floaterVp = dynamic_cast<LLFloaterView*>(getParent()); + if (floaterVp) + { + floaterVp->adjustToFitScreen(this, !isMinimized()); + } } // if not minimized, adjust all snapped dependents to new shape @@ -1335,7 +1342,7 @@ void LLFloater::setFocus( BOOL b ) { return; } - LLUICtrl* last_focus = gFocusMgr.getLastFocusForGroup(this); + LLView* last_focus = gFocusMgr.getLastFocusForGroup(this); // a descendent already has focus BOOL child_had_focus = hasFocus(); @@ -1345,7 +1352,8 @@ void LLFloater::setFocus( BOOL b ) if (b) { // only push focused floaters to front of stack if not in midst of ctrl-tab cycle - if (!getHost() && !((LLFloaterView*)getParent())->getCycleMode()) + LLFloaterView * parent = dynamic_cast<LLFloaterView *>(getParent()); + if (!getHost() && parent && !parent->getCycleMode()) { if (!isFrontmost()) { @@ -1543,6 +1551,17 @@ BOOL LLFloater::handleScrollWheel(S32 x, S32 y, S32 clicks) } // virtual +BOOL LLFloater::handleMouseUp(S32 x, S32 y, MASK mask) +{ + lldebugs << "LLFloater::handleMouseUp calling LLPanel (really LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl; + BOOL handled = LLPanel::handleMouseUp(x,y,mask); // Not implemented in LLPanel so this actually calls LLView + if (handled) { + LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); + } + return handled; +} + +// virtual BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask) { if( mMinimized ) @@ -1562,7 +1581,11 @@ BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask) else { bringToFront( x, y ); - return LLPanel::handleMouseDown( x, y, mask ); + BOOL handled = LLPanel::handleMouseDown( x, y, mask ); + if (handled) { + LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); + } + return handled; } } @@ -1600,7 +1623,7 @@ void LLFloater::bringToFront( S32 x, S32 y ) } else { - LLFloaterView* parent = (LLFloaterView*) getParent(); + LLFloaterView* parent = dynamic_cast<LLFloaterView*>( getParent() ); if (parent) { parent->bringToFront( this ); @@ -1639,7 +1662,11 @@ void LLFloater::setFrontmost(BOOL take_focus) { // there are more than one floater view // so we need to query our parent directly - ((LLFloaterView*)getParent())->bringToFront(this, take_focus); + LLFloaterView * parent = dynamic_cast<LLFloaterView*>( getParent() ); + if (parent) + { + parent->bringToFront(this, take_focus); + } // Make sure to set the appropriate transparency type (STORM-732). updateTransparency(hasFocus() || getIsChrome() ? TT_ACTIVE : TT_INACTIVE); @@ -1802,7 +1829,7 @@ void LLFloater::onClickClose( LLFloater* self ) self->onClickCloseBtn(); } -void LLFloater::onClickCloseBtn() +void LLFloater::onClickCloseBtn(bool app_quitting) { closeFloater(false); } @@ -1932,6 +1959,7 @@ void LLFloater::drawShadow(LLPanel* panel) void LLFloater::updateTransparency(LLView* view, ETypeTransparency transparency_type) { + if (!view) return; child_list_t children = *view->getChildList(); child_list_t::iterator it = children.begin(); @@ -2368,6 +2396,9 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus) { + if (!child) + return; + if (mFrontChild == child) { if (give_focus && !gFocusMgr.childHasKeyboardFocus(child)) @@ -2723,8 +2754,6 @@ void LLFloaterView::refresh() } } -const S32 FLOATER_MIN_VISIBLE_PIXELS = 16; - void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_outside, BOOL snap_in_toolbars/* = false*/) { if (floater->getParent() != this) @@ -2777,11 +2806,29 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out } } + const LLRect& floater_rect = floater->getRect(); + + S32 delta_left = mToolbarLeftRect.notEmpty() ? mToolbarLeftRect.mRight - floater_rect.mRight : 0; + S32 delta_bottom = mToolbarBottomRect.notEmpty() ? mToolbarBottomRect.mTop - floater_rect.mTop : 0; + S32 delta_right = mToolbarRightRect.notEmpty() ? mToolbarRightRect.mLeft - floater_rect.mLeft : 0; + // move window fully onscreen if (floater->translateIntoRect( snap_in_toolbars ? getSnapRect() : gFloaterView->getRect(), allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX )) { floater->clearSnapTarget(); } + else if (delta_left > 0 && floater_rect.mTop < mToolbarLeftRect.mTop && floater_rect.mBottom > mToolbarLeftRect.mBottom) + { + floater->translate(delta_left, 0); + } + else if (delta_bottom > 0 && floater_rect.mLeft > mToolbarBottomRect.mLeft && floater_rect.mRight < mToolbarBottomRect.mRight) + { + floater->translate(0, delta_bottom); + } + else if (delta_right < 0 && floater_rect.mTop < mToolbarRightRect.mTop && floater_rect.mBottom > mToolbarRightRect.mBottom) + { + floater->translate(delta_right, 0); + } } void LLFloaterView::draw() @@ -2827,10 +2874,13 @@ LLFloater *LLFloaterView::getFocusedFloater() const { for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it) { - LLUICtrl* ctrlp = (*child_it)->isCtrl() ? static_cast<LLUICtrl*>(*child_it) : NULL; - if ( ctrlp && ctrlp->hasFocus() ) + if ((*child_it)->isCtrl()) { - return static_cast<LLFloater *>(ctrlp); + LLFloater* ctrlp = dynamic_cast<LLFloater*>(*child_it); + if ( ctrlp && ctrlp->hasFocus() ) + { + return ctrlp; + } } } return NULL; @@ -2981,6 +3031,25 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list) LLFloaterReg::blockShowFloaters(false); } +void LLFloaterView::setToolbarRect(LLToolBarEnums::EToolBarLocation tb, const LLRect& toolbar_rect) +{ + switch (tb) + { + case LLToolBarEnums::TOOLBAR_LEFT: + mToolbarLeftRect = toolbar_rect; + break; + case LLToolBarEnums::TOOLBAR_BOTTOM: + mToolbarBottomRect = toolbar_rect; + break; + case LLToolBarEnums::TOOLBAR_RIGHT: + mToolbarRightRect = toolbar_rect; + break; + default: + llwarns << "setToolbarRect() passed odd toolbar number " << (S32) tb << llendl; + break; + } +} + void LLFloater::setInstanceName(const std::string& name) { if (name != mInstanceName) diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h index 59448530d9..12eb3cdbfa 100755 --- a/indra/llui/llfloater.h +++ b/indra/llui/llfloater.h @@ -32,6 +32,7 @@ #define LL_FLOATER_H #include "llpanel.h" +#include "lltoolbar.h" #include "lluuid.h" //#include "llnotificationsutil.h" #include <set> @@ -289,6 +290,7 @@ public: S32 getHeaderHeight() const { return mHeaderHeight; } virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); + virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask); virtual BOOL handleMiddleMouseDown(S32 x, S32 y, MASK mask); @@ -389,7 +391,7 @@ protected: void destroy(); // Don't call this directly. You probably want to call closeFloater() - virtual void onClickCloseBtn(); + virtual void onClickCloseBtn(bool app_quitting = false); virtual void updateTitleButtons(); @@ -513,6 +515,8 @@ private: // LLFloaterView // Parent of all floating panels +const S32 FLOATER_MIN_VISIBLE_PIXELS = 16; + class LLFloaterView : public LLUICtrl { public: @@ -571,10 +575,15 @@ public: void setFloaterSnapView(LLHandle<LLView> snap_view) {mSnapView = snap_view; } LLFloater* getFrontmostClosableFloater(); + void setToolbarRect(LLToolBarEnums::EToolBarLocation tb, const LLRect& toolbar_rect); + private: void hiddenFloaterClosed(LLFloater* floater); LLRect mLastSnapRect; + LLRect mToolbarLeftRect; + LLRect mToolbarBottomRect; + LLRect mToolbarRightRect; LLHandle<LLView> mSnapView; BOOL mFocusCycleMode; S32 mSnapOffsetBottom; diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 724d190307..f03c8d444b 100755 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -469,7 +469,7 @@ void LLFocusMgr::setAppHasFocus(BOOL focus) mAppHasFocus = focus; } -LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const +LLView* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const { if (subtree_root) { @@ -477,7 +477,7 @@ LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const if (found_it != mImpl->mFocusHistory.end()) { // found last focus for this subtree - return static_cast<LLUICtrl*>(found_it->second.get()); + return found_it->second.get(); } } return NULL; diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h index 25ae1d2579..1c7326260c 100755 --- a/indra/llui/llfocusmgr.h +++ b/indra/llui/llfocusmgr.h @@ -97,7 +97,7 @@ public: void triggerFocusFlash(); BOOL getAppHasFocus() const { return mAppHasFocus; } void setAppHasFocus(BOOL focus); - LLUICtrl* getLastFocusForGroup(LLView* subtree_root) const; + LLView* getLastFocusForGroup(LLView* subtree_root) const; void clearLastFocusForGroup(LLView* subtree_root); // If setKeyboardFocus(NULL) is called, and there is a non-NULL default diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index cf449217f5..f32a52e6c6 100755 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -185,7 +185,7 @@ LLFolderView::LLFolderView(const Params& p) mAutoOpenCandidate = NULL; mAutoOpenTimer.stop(); mKeyboardSelection = FALSE; - mIndentation = p.folder_indentation; + mIndentation = getParentFolder() ? getParentFolder()->getIndentation() + mLocalIndentation : 0; //clear label // go ahead and render root folder as usual @@ -1613,7 +1613,7 @@ void LLFolderView::update() { getFolderViewModel()->getFilter().clearModified(); } - + // automatically show matching items, and select first one if we had a selection if (mNeedsAutoSelect) { @@ -1653,13 +1653,13 @@ void LLFolderView::update() BOOL is_visible = isInVisibleChain(); - // Puts folders/items in proper positions + //Puts folders/items in proper positions // arrange() takes the model filter flag into account and call sort() if necessary (CHUI-849) // It also handles the open/close folder animation - if (is_visible) + if ( is_visible ) { sanitizeSelection(); - if (needsArrange()) + if( needsArrange() ) { S32 height = 0; S32 width = 0; diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index 6c147ccc12..aa2343226c 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -307,7 +307,12 @@ std::set<LLFolderViewItem*> LLFolderViewItem::getSelectionList() const // addToFolder() returns TRUE if it succeeds. FALSE otherwise void LLFolderViewItem::addToFolder(LLFolderViewFolder* folder) { - folder->addItem(this); + folder->addItem(this); + + // Compute indentation since parent folder changed + mIndentation = (getParentFolder()) + ? getParentFolder()->getIndentation() + mLocalIndentation + : 0; } @@ -521,7 +526,7 @@ BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask ) BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask ) { - static LLCachedControl<S32> drag_and_drop_threshold(*LLUI::sSettingGroups["config"],"DragAndDropDistanceThreshold"); + static LLCachedControl<S32> drag_and_drop_threshold(*LLUI::sSettingGroups["config"],"DragAndDropDistanceThreshold", 3); mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight)); @@ -940,6 +945,11 @@ LLFolderViewFolder::~LLFolderViewFolder( void ) void LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder) { folder->addFolder(this); + + // Compute indentation since parent folder changed + mIndentation = (getParentFolder()) + ? getParentFolder()->getIndentation() + mLocalIndentation + : 0; } static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange"); @@ -1109,7 +1119,7 @@ S32 LLFolderViewFolder::arrange( S32* width, S32* height ) BOOL LLFolderViewFolder::needsArrange() { - return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); + return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); } // Passes selection information on to children and record selection diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp index 26d27d1f34..39153977bf 100755 --- a/indra/llui/llkeywords.cpp +++ b/indra/llui/llkeywords.cpp @@ -76,8 +76,11 @@ inline BOOL LLKeywordToken::isTail(const llwchar* s) const LLKeywords::~LLKeywords() { std::for_each(mWordTokenMap.begin(), mWordTokenMap.end(), DeletePairedPointer()); + mWordTokenMap.clear(); std::for_each(mLineTokenList.begin(), mLineTokenList.end(), DeletePointer()); + mLineTokenList.clear(); std::for_each(mDelimiterTokenList.begin(), mDelimiterTokenList.end(), DeletePointer()); + mDelimiterTokenList.clear(); } BOOL LLKeywords::loadFromFile( const std::string& filename ) diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index f854e1785d..6a57158eaa 100755 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -693,8 +693,11 @@ void LLMenuItemTearOffGL::onCommit() { if (getMenu()->getTornOff()) { - LLTearOffMenu* torn_off_menu = (LLTearOffMenu*)(getMenu()->getParent()); - torn_off_menu->closeFloater(); + LLTearOffMenu * torn_off_menu = dynamic_cast<LLTearOffMenu*>(getMenu()->getParent()); + if (torn_off_menu) + { + torn_off_menu->closeFloater(); + } } else { @@ -1097,7 +1100,8 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight ) BOOL auto_open = getEnabled() && (!branch->getVisible() || branch->getTornOff()); // torn off menus don't open sub menus on hover unless they have focus - if (getMenu()->getTornOff() && !((LLFloater*)getMenu()->getParent())->hasFocus()) + LLFloater * menu_parent = dynamic_cast<LLFloater *>(getMenu()->getParent()); + if (getMenu()->getTornOff() && menu_parent && !menu_parent->hasFocus()) { auto_open = FALSE; } @@ -1118,7 +1122,11 @@ void LLMenuItemBranchGL::setHighlight( BOOL highlight ) { if (branch->getTornOff()) { - ((LLFloater*)branch->getParent())->setFocus(FALSE); + LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent()); + if (branch_parent) + { + branch_parent->setFocus(FALSE); + } branch->clearHoverItem(); } else @@ -1175,11 +1183,19 @@ BOOL LLMenuItemBranchGL::handleKeyHere( KEY key, MASK mask ) BOOL handled = branch->clearHoverItem(); if (branch->getTornOff()) { - ((LLFloater*)branch->getParent())->setFocus(FALSE); + LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent()); + if (branch_parent) + { + branch_parent->setFocus(FALSE); + } } if (handled && getMenu()->getTornOff()) { - ((LLFloater*)getMenu()->getParent())->setFocus(TRUE); + LLFloater * menu_parent = dynamic_cast<LLFloater *>(getMenu()->getParent()); + if (menu_parent) + { + menu_parent->setFocus(TRUE); + } } return handled; } @@ -1219,9 +1235,13 @@ void LLMenuItemBranchGL::openMenu() if (branch->getTornOff()) { - gFloaterView->bringToFront((LLFloater*)branch->getParent()); - // this might not be necessary, as torn off branches don't get focus and hence no highligth - branch->highlightNextItem(NULL); + LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent()); + if (branch_parent) + { + gFloaterView->bringToFront(branch_parent); + // this might not be necessary, as torn off branches don't get focus and hence no highligth + branch->highlightNextItem(NULL); + } } else if( !branch->getVisible() ) { @@ -1348,7 +1368,11 @@ void LLMenuItemBranchDownGL::openMenu( void ) { if (branch->getTornOff()) { - gFloaterView->bringToFront((LLFloater*)branch->getParent()); + LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent()); + if (branch_parent) + { + gFloaterView->bringToFront(branch_parent); + } } else { @@ -1403,7 +1427,11 @@ void LLMenuItemBranchDownGL::setHighlight( BOOL highlight ) { if (branch->getTornOff()) { - ((LLFloater*)branch->getParent())->setFocus(FALSE); + LLFloater * branch_parent = dynamic_cast<LLFloater *>(branch->getParent()); + if (branch_parent) + { + branch_parent->setFocus(FALSE); + } branch->clearHoverItem(); } else @@ -1826,20 +1854,28 @@ BOOL LLMenuGL::jumpKeysActive() { LLMenuItemGL* highlighted_item = getHighlightedItem(); BOOL active = getVisible() && getEnabled(); - if (getTornOff()) - { - // activation of jump keys on torn off menus controlled by keyboard focus - active = active && ((LLFloater*)getParent())->hasFocus(); - } - else + if (active) { - // Are we the terminal active menu? - // Yes, if parent menu item deems us to be active (just being visible is sufficient for top-level menus) - // and we don't have a highlighted menu item pointing to an active sub-menu - active = active && (!getParentMenuItem() || getParentMenuItem()->isActive()) // I have a parent that is active... - && (!highlighted_item || !highlighted_item->isActive()); //... but no child that is active + if (getTornOff()) + { + // activation of jump keys on torn off menus controlled by keyboard focus + LLFloater * parent = dynamic_cast<LLFloater *>(getParent()); + if (parent) + { + active = parent->hasFocus(); + } + } + else + { + // Are we the terminal active menu? + // Yes, if parent menu item deems us to be active (just being visible is sufficient for top-level menus) + // and we don't have a highlighted menu item pointing to an active sub-menu + active = (!getParentMenuItem() || getParentMenuItem()->isActive()) // I have a parent that is active... + && (!highlighted_item || !highlighted_item->isActive()); //... but no child that is active + } } + return active; } @@ -1855,7 +1891,12 @@ BOOL LLMenuGL::isOpen() return TRUE; } // otherwise we are only active if we have keyboard focus - return ((LLFloater*)getParent())->hasFocus(); + LLFloater * parent = dynamic_cast<LLFloater *>(getParent()); + if (parent) + { + return parent->hasFocus(); + } + return FALSE; } else { @@ -2714,7 +2755,11 @@ LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disa // same as giving focus to it if (!cur_item && getTornOff()) { - ((LLFloater*)getParent())->setFocus(TRUE); + LLFloater * parent = dynamic_cast<LLFloater *>(getParent()); + if (parent) + { + parent->setFocus(TRUE); + } } // Current item position in the items list @@ -2816,7 +2861,11 @@ LLMenuItemGL* LLMenuGL::highlightPrevItem(LLMenuItemGL* cur_item, BOOL skip_disa // same as giving focus to it if (!cur_item && getTornOff()) { - ((LLFloater*)getParent())->setFocus(TRUE); + LLFloater * parent = dynamic_cast<LLFloater *>(getParent()); + if (parent) + { + parent->setFocus(TRUE); + } } // Current item reverse position from the end of the list diff --git a/indra/llui/llmodaldialog.cpp b/indra/llui/llmodaldialog.cpp index 8c2be44904..4d6e189b92 100755 --- a/indra/llui/llmodaldialog.cpp +++ b/indra/llui/llmodaldialog.cpp @@ -34,7 +34,7 @@ #include "llui.h" #include "llwindow.h" #include "llkeyboard.h" - +#include "llmenugl.h" // static std::list<LLModalDialog*> LLModalDialog::sModalStack; @@ -161,6 +161,18 @@ void LLModalDialog::setVisible( BOOL visible ) BOOL LLModalDialog::handleMouseDown(S32 x, S32 y, MASK mask) { + LLView* popup_menu = LLMenuGL::sMenuContainer->getVisibleMenu(); + if (popup_menu != NULL) + { + S32 mx, my; + LLUI::getMousePositionScreen(&mx, &my); + LLRect menu_screen_rc = popup_menu->calcScreenRect(); + if(!menu_screen_rc.pointInRect(mx, my)) + { + LLMenuGL::sMenuContainer->hideMenus(); + } + } + if (mModal) { if (!LLFloater::handleMouseDown(x, y, mask)) @@ -173,6 +185,8 @@ BOOL LLModalDialog::handleMouseDown(S32 x, S32 y, MASK mask) { LLFloater::handleMouseDown(x, y, mask); } + + return TRUE; } @@ -183,6 +197,22 @@ BOOL LLModalDialog::handleHover(S32 x, S32 y, MASK mask) getWindow()->setCursor(UI_CURSOR_ARROW); lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl; } + + LLView* popup_menu = LLMenuGL::sMenuContainer->getVisibleMenu(); + if (popup_menu != NULL) + { + S32 mx, my; + LLUI::getMousePositionScreen(&mx, &my); + LLRect menu_screen_rc = popup_menu->calcScreenRect(); + if(menu_screen_rc.pointInRect(mx, my)) + { + S32 local_x = mx - popup_menu->getRect().mLeft; + S32 local_y = my - popup_menu->getRect().mBottom; + popup_menu->handleHover(local_x, local_y, mask); + gFocusMgr.setMouseCapture(NULL); + } + } + return TRUE; } @@ -210,6 +240,7 @@ BOOL LLModalDialog::handleDoubleClick(S32 x, S32 y, MASK mask) BOOL LLModalDialog::handleRightMouseDown(S32 x, S32 y, MASK mask) { + LLMenuGL::sMenuContainer->hideMenus(); childrenHandleRightMouseDown(x, y, mask); return TRUE; } diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 3186c5460a..5c288c3f03 100755 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1206,6 +1206,7 @@ LLNotifications::LLNotifications() : LLNotificationChannelBase(LLNotificationFilters::includeEverything), mIgnoreAllNotifications(false) { + mListener.reset(new LLNotificationsListener(*this)); LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2)); } diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 3b620084ee..6ac4a98806 100755 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -98,6 +98,8 @@ #include "llrefcount.h" #include "llsdparam.h" +#include "llnotificationslistener.h" + class LLAvatarName; typedef enum e_notification_priority { @@ -978,6 +980,8 @@ private: bool mIgnoreAllNotifications; + boost::scoped_ptr<LLNotificationsListener> mListener; + std::vector<LLNotificationChannelPtr> mDefaultChannels; }; diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp new file mode 100644 index 0000000000..9e8e943ee6 --- /dev/null +++ b/indra/llui/llnotificationslistener.cpp @@ -0,0 +1,359 @@ +/** + * @file llnotificationslistener.cpp + * @author Brad Kittenbrink + * @date 2009-07-08 + * @brief Implementation for llnotificationslistener. + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "llnotificationslistener.h" +#include "llnotifications.h" +#include "llnotificationtemplate.h" +#include "llsd.h" +#include "llui.h" + +LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications) : + LLEventAPI("LLNotifications", + "LLNotifications listener to (e.g.) pop up a notification"), + mNotifications(notifications) +{ + add("requestAdd", + "Add a notification with specified [\"name\"], [\"substitutions\"] and [\"payload\"].\n" + "If optional [\"reply\"] specified, arrange to send user response on that LLEventPump.", + &LLNotificationsListener::requestAdd); + /* add("listChannels", + "Post to [\"reply\"] a map of info on existing channels", + &LLNotificationsListener::listChannels, + LLSD().with("reply", LLSD())); + */ + add("listChannelNotifications", + "Post to [\"reply\"] an array of info on notifications in channel [\"channel\"]", + &LLNotificationsListener::listChannelNotifications, + LLSD().with("reply", LLSD()).with("channel", LLSD())); + add("respond", + "Respond to notification [\"uuid\"] with data in [\"response\"]", + &LLNotificationsListener::respond, + LLSD().with("uuid", LLSD())); + add("cancel", + "Cancel notification [\"uuid\"]", + &LLNotificationsListener::cancel, + LLSD().with("uuid", LLSD())); + add("ignore", + "Ignore future notification [\"name\"]\n" + "(from <notification name= > in notifications.xml)\n" + "according to boolean [\"ignore\"].\n" + "If [\"name\"] is omitted or undefined, [un]ignore all future notifications.\n" + "Note that ignored notifications are not forwarded unless intercepted before\n" + "the \"Ignore\" channel.", + &LLNotificationsListener::ignore); + add("forward", + "Forward to [\"pump\"] future notifications on channel [\"channel\"]\n" + "according to boolean [\"forward\"]. When enabled, only types matching\n" + "[\"types\"] are forwarded, as follows:\n" + "omitted or undefined: forward all notifications\n" + "string: forward only the specific named [sig]type\n" + "array of string: forward any notification matching any named [sig]type.\n" + "When boolean [\"respond\"] is true, we auto-respond to each forwarded\n" + "notification.", + &LLNotificationsListener::forward, + LLSD().with("channel", LLSD())); +} + +// This is here in the .cpp file so we don't need the definition of class +// Forwarder in the header file. +LLNotificationsListener::~LLNotificationsListener() +{ +} + +void LLNotificationsListener::requestAdd(const LLSD& event_data) const +{ + if(event_data.has("reply")) + { + mNotifications.add(event_data["name"], + event_data["substitutions"], + event_data["payload"], + boost::bind(&LLNotificationsListener::NotificationResponder, + this, + event_data["reply"].asString(), + _1, _2 + ) + ); + } + else + { + mNotifications.add(event_data["name"], + event_data["substitutions"], + event_data["payload"]); + } +} + +void LLNotificationsListener::NotificationResponder(const std::string& reply_pump, + const LLSD& notification, + const LLSD& response) const +{ + LLSD reponse_event; + reponse_event["notification"] = notification; + reponse_event["response"] = response; + LLEventPumps::getInstance()->obtain(reply_pump).post(reponse_event); +} +/* +void LLNotificationsListener::listChannels(const LLSD& params) const +{ + LLReqID reqID(params); + LLSD response(reqID.makeResponse()); + for (LLNotifications:: + + + + for (LLNotifications::ChannelMap::const_iterator cmi(mNotifications.mChannels.begin()), + cmend(mNotifications.mChannels.end()); + cmi != cmend; ++cmi) + { + LLSD channelInfo; + channelInfo["parent"] = cmi->second->getParentChannelName(); + response[cmi->first] = channelInfo; + } + LLEventPumps::instance().obtain(params["reply"]).post(response); +} +*/ +void LLNotificationsListener::listChannelNotifications(const LLSD& params) const +{ + LLReqID reqID(params); + LLSD response(reqID.makeResponse()); + LLNotificationChannelPtr channel(mNotifications.getChannel(params["channel"])); + if (channel) + { + LLSD notifications(LLSD::emptyArray()); + for (LLNotificationChannel::Iterator ni(channel->begin()), nend(channel->end()); + ni != nend; ++ni) + { + notifications.append(asLLSD(*ni)); + } + response["notifications"] = notifications; + } + LLEventPumps::instance().obtain(params["reply"]).post(response); +} + +void LLNotificationsListener::respond(const LLSD& params) const +{ + LLNotificationPtr notification(mNotifications.find(params["uuid"])); + if (notification) + { + notification->respond(params["response"]); + } +} + +void LLNotificationsListener::cancel(const LLSD& params) const +{ + LLNotificationPtr notification(mNotifications.find(params["uuid"])); + if (notification) + { + mNotifications.cancel(notification); + } +} + +void LLNotificationsListener::ignore(const LLSD& params) const +{ + // Calling a method named "ignore", but omitting its "ignore" Boolean + // argument, should by default cause something to be ignored. Explicitly + // pass ["ignore"] = false to cancel ignore. + bool ignore = true; + if (params.has("ignore")) + { + ignore = params["ignore"].asBoolean(); + } + // This method can be used to affect either a single notification name or + // all future notifications. The two use substantially different mechanisms. + if (params["name"].isDefined()) + { + // ["name"] was passed: ignore just that notification + LLNotificationTemplatePtr templatep = mNotifications.getTemplate(params["name"]); + if (templatep) + { + templatep->mForm->setIgnored(ignore); + } + } + else + { + // no ["name"]: ignore all future notifications + mNotifications.setIgnoreAllNotifications(ignore); + } +} + +class LLNotificationsListener::Forwarder: public LLEventTrackable +{ + LOG_CLASS(LLNotificationsListener::Forwarder); +public: + Forwarder(LLNotifications& llnotifications, const std::string& channel): + mNotifications(llnotifications), + mRespond(false) + { + // Connect to the specified channel on construction. Because + // LLEventTrackable is a base, we should automatically disconnect when + // destroyed. + LLNotificationChannelPtr channelptr(llnotifications.getChannel(channel)); + if (channelptr) + { + // Insert our processing as a "passed filter" listener. This way + // we get to run before all the "changed" listeners, and we get to + // swipe it (hide it from the other listeners) if desired. + channelptr->connectPassedFilter(boost::bind(&Forwarder::handle, this, _1)); + } + } + + void setPumpName(const std::string& name) { mPumpName = name; } + void setTypes(const LLSD& types) { mTypes = types; } + void setRespond(bool respond) { mRespond = respond; } + +private: + bool handle(const LLSD& notification) const; + bool matchType(const LLSD& filter, const std::string& type) const; + + LLNotifications& mNotifications; + std::string mPumpName; + LLSD mTypes; + bool mRespond; +}; + +void LLNotificationsListener::forward(const LLSD& params) +{ + std::string channel(params["channel"]); + // First decide whether we're supposed to start forwarding or stop it. + // Default to true. + bool forward = true; + if (params.has("forward")) + { + forward = params["forward"].asBoolean(); + } + if (! forward) + { + // This is a request to stop forwarding notifications on the specified + // channel. The rest of the params don't matter. + // Because mForwarders contains scoped_ptrs, erasing the map entry + // DOES delete the heap Forwarder object. Because Forwarder derives + // from LLEventTrackable, destroying it disconnects it from the + // channel. + mForwarders.erase(channel); + return; + } + // From here on, we know we're being asked to start (or modify) forwarding + // on the specified channel. Find or create an appropriate Forwarder. + ForwarderMap::iterator + entry(mForwarders.insert(ForwarderMap::value_type(channel, ForwarderMap::mapped_type())).first); + if (! entry->second) + { + entry->second.reset(new Forwarder(mNotifications, channel)); + } + // Now, whether this Forwarder is brand-new or not, update it with the new + // request info. + Forwarder& fwd(*entry->second); + fwd.setPumpName(params["pump"]); + fwd.setTypes(params["types"]); + fwd.setRespond(params["respond"]); +} + +bool LLNotificationsListener::Forwarder::handle(const LLSD& notification) const +{ + LL_INFOS("LLNotificationsListener") << "handle(" << notification << ")" << LL_ENDL; + if (notification["sigtype"].asString() == "delete") + { + LL_INFOS("LLNotificationsListener") << "ignoring delete" << LL_ENDL; + // let other listeners see the "delete" operation + return false; + } + LLNotificationPtr note(mNotifications.find(notification["id"])); + if (! note) + { + LL_INFOS("LLNotificationsListener") << notification["id"] << " not found" << LL_ENDL; + return false; + } + if (! matchType(mTypes, note->getType())) + { + LL_INFOS("LLNotificationsListener") << "didn't match types " << mTypes << LL_ENDL; + // We're not supposed to intercept this particular notification. Let + // other listeners process it. + return false; + } + LL_INFOS("LLNotificationsListener") << "sending via '" << mPumpName << "'" << LL_ENDL; + // This is a notification we care about. Forward it through specified + // LLEventPump. + LLEventPumps::instance().obtain(mPumpName).post(asLLSD(note)); + // Are we also being asked to auto-respond? + if (mRespond) + { + LL_INFOS("LLNotificationsListener") << "should respond" << LL_ENDL; + note->respond(LLSD::emptyMap()); + // Did that succeed in removing the notification? Only cancel() if + // it's still around -- otherwise we get an LL_ERRS crash! + note = mNotifications.find(notification["id"]); + if (note) + { + LL_INFOS("LLNotificationsListener") << "respond() didn't clear, canceling" << LL_ENDL; + mNotifications.cancel(note); + } + } + // If we've auto-responded to this notification, then it's going to be + // deleted. Other listeners would get the change operation, try to look it + // up and be baffled by lookup failure. So when we auto-respond, suppress + // this notification: don't pass it to other listeners. + return mRespond; +} + +bool LLNotificationsListener::Forwarder::matchType(const LLSD& filter, const std::string& type) const +{ + // Decide whether this notification matches filter: + // undefined: forward all notifications + if (filter.isUndefined()) + { + return true; + } + // array of string: forward any notification matching any named type + if (filter.isArray()) + { + for (LLSD::array_const_iterator ti(filter.beginArray()), tend(filter.endArray()); + ti != tend; ++ti) + { + if (ti->asString() == type) + { + return true; + } + } + // Didn't match any entry in the array + return false; + } + // string: forward only the specific named type + return (filter.asString() == type); +} + +LLSD LLNotificationsListener::asLLSD(LLNotificationPtr note) +{ + LLSD notificationInfo(note->asLLSD()); + // For some reason the following aren't included in LLNotification::asLLSD(). + notificationInfo["summary"] = note->summarize(); + notificationInfo["id"] = note->id(); + notificationInfo["type"] = note->getType(); + notificationInfo["message"] = note->getMessage(); + notificationInfo["label"] = note->getLabel(); + return notificationInfo; +} diff --git a/indra/llui/llnotificationslistener.h b/indra/llui/llnotificationslistener.h new file mode 100644 index 0000000000..f9f7641de6 --- /dev/null +++ b/indra/llui/llnotificationslistener.h @@ -0,0 +1,69 @@ +/** + * @file llnotificationslistener.h + * @author Brad Kittenbrink + * @date 2009-07-08 + * @brief Wrap subset of LLNotifications API in event API for test scripts. + * + * $LicenseInfo:firstyear=2009&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLNOTIFICATIONSLISTENER_H +#define LL_LLNOTIFICATIONSLISTENER_H + +#include "lleventapi.h" +#include "llnotificationptr.h" +#include <boost/shared_ptr.hpp> +#include <map> +#include <string> + +class LLNotifications; +class LLSD; + +class LLNotificationsListener : public LLEventAPI +{ +public: + LLNotificationsListener(LLNotifications & notifications); + ~LLNotificationsListener(); + +private: + void requestAdd(LLSD const & event_data) const; + + void NotificationResponder(const std::string& replypump, + const LLSD& notification, + const LLSD& response) const; + + void listChannels(const LLSD& params) const; + void listChannelNotifications(const LLSD& params) const; + void respond(const LLSD& params) const; + void cancel(const LLSD& params) const; + void ignore(const LLSD& params) const; + void forward(const LLSD& params); + + static LLSD asLLSD(LLNotificationPtr); + + class Forwarder; + typedef std::map<std::string, boost::shared_ptr<Forwarder> > ForwarderMap; + ForwarderMap mForwarders; + LLNotifications & mNotifications; +}; + +#endif // LL_LLNOTIFICATIONSLISTENER_H diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index e63b41f97c..17b9b91ba7 100755 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -330,17 +330,16 @@ private: // local static instance for registering a particular panel class template<typename T> -class LLRegisterPanelClassWrapper -: public LLRegisterPanelClass + class LLPanelInjector { public: - // reigister with either the provided builder, or the generic templated builder - LLRegisterPanelClassWrapper(const std::string& tag); + // register with either the provided builder, or the generic templated builder + LLPanelInjector(const std::string& tag); }; template<typename T> -LLRegisterPanelClassWrapper<T>::LLRegisterPanelClassWrapper(const std::string& tag) + LLPanelInjector<T>::LLPanelInjector(const std::string& tag) { LLRegisterPanelClass::instance().addPanelClass(tag,&LLRegisterPanelClass::defaultPanelClassBuilder<T>); } diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index cbcce0ece5..238eae21c2 100755 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -519,7 +519,7 @@ bool LLScrollContainer::addChild(LLView* view, S32 tab_group) void LLScrollContainer::updateScroll() { - if (!mScrolledView) + if (!getVisible() || !mScrolledView) { return; } diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 6e03f604a2..d4bbea0f8e 100755 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -320,7 +320,9 @@ LLScrollListCtrl::~LLScrollListCtrl() delete mSortCallback; std::for_each(mItemList.begin(), mItemList.end(), DeletePointer()); + mItemList.clear(); std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer()); + mColumns.clear(); } @@ -1855,7 +1857,7 @@ void LLScrollListCtrl::showNameDetails(std::string id, bool is_group) // open the resident's details or the group details std::string sltype = is_group ? "group" : "agent"; std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about"; - LLUrlAction::clickAction(slurl); + LLUrlAction::clickAction(slurl, true); } void LLScrollListCtrl::copyNameToClipboard(std::string id, bool is_group) diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp index 5a1e96ab03..cc7f42e49a 100755 --- a/indra/llui/llscrolllistitem.cpp +++ b/indra/llui/llscrolllistitem.cpp @@ -50,6 +50,7 @@ LLScrollListItem::LLScrollListItem( const Params& p ) LLScrollListItem::~LLScrollListItem() { std::for_each(mColumns.begin(), mColumns.end(), DeletePointer()); + mColumns.clear(); } void LLScrollListItem::addColumn(const LLScrollListCell::Params& p) diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index fd98155704..2b9286f663 100755 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -27,7 +27,7 @@ #include "linden_common.h" #include "lltabcontainer.h" - +#include "llviewereventrecorder.h" #include "llfocusmgr.h" #include "lllocalcliprect.h" #include "llrect.h" @@ -281,6 +281,7 @@ LLTabContainer::LLTabContainer(const LLTabContainer::Params& p) LLTabContainer::~LLTabContainer() { std::for_each(mTabList.begin(), mTabList.end(), DeletePointer()); + mTabList.clear(); } //virtual @@ -578,6 +579,11 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) tab_button->setFocus(TRUE); } } + if (handled) { + // Note: May need to also capture local coords right here ? + LLViewerEventRecorder::instance().update_xui(getPathname( )); + } + return handled; } @@ -629,30 +635,33 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask ) BOOL handled = FALSE; BOOL has_scroll_arrows = (getMaxScrollPos() > 0) && !getTabsHidden(); + S32 local_x = x - getRect().mLeft; + S32 local_y = y - getRect().mBottom; + if (has_scroll_arrows) { if (mJumpPrevArrowBtn && mJumpPrevArrowBtn->getRect().pointInRect(x, y)) { - S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom; + local_x = x - mJumpPrevArrowBtn->getRect().mLeft; + local_y = y - mJumpPrevArrowBtn->getRect().mBottom; handled = mJumpPrevArrowBtn->handleMouseUp(local_x, local_y, mask); } else if (mJumpNextArrowBtn && mJumpNextArrowBtn->getRect().pointInRect(x, y)) { - S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom; + local_x = x - mJumpNextArrowBtn->getRect().mLeft; + local_y = y - mJumpNextArrowBtn->getRect().mBottom; handled = mJumpNextArrowBtn->handleMouseUp(local_x, local_y, mask); } else if (mPrevArrowBtn && mPrevArrowBtn->getRect().pointInRect(x, y)) { - S32 local_x = x - mPrevArrowBtn->getRect().mLeft; - S32 local_y = y - mPrevArrowBtn->getRect().mBottom; + local_x = x - mPrevArrowBtn->getRect().mLeft; + local_y = y - mPrevArrowBtn->getRect().mBottom; handled = mPrevArrowBtn->handleMouseUp(local_x, local_y, mask); } else if (mNextArrowBtn && mNextArrowBtn->getRect().pointInRect(x, y)) { - S32 local_x = x - mNextArrowBtn->getRect().mLeft; - S32 local_y = y - mNextArrowBtn->getRect().mBottom; + local_x = x - mNextArrowBtn->getRect().mLeft; + local_y = y - mNextArrowBtn->getRect().mBottom; handled = mNextArrowBtn->handleMouseUp(local_x, local_y, mask); } } @@ -676,6 +685,10 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask ) } gFocusMgr.setMouseCapture(NULL); } + if (handled) { + // Note: may need to capture local coords here + LLViewerEventRecorder::instance().update_xui(getPathname( )); + } return handled; } @@ -1059,21 +1072,21 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel) if (mIsVertical) { - p.name(std::string("vert tab button")); - p.image_unselected(mMiddleTabParams.tab_left_image_unselected); - p.image_selected(mMiddleTabParams.tab_left_image_selected); - p.follows.flags = p.follows.flags() | FOLLOWS_TOP; + p.name("vtab_"+std::string(child->getName())); + p.image_unselected(mMiddleTabParams.tab_left_image_unselected); + p.image_selected(mMiddleTabParams.tab_left_image_selected); + p.follows.flags = p.follows.flags() | FOLLOWS_TOP; } else - { - p.name(std::string(child->getName()) + " tab"); - p.visible(false); - p.image_unselected(tab_img); - p.image_selected(tab_selected_img); - p.follows.flags = p.follows.flags() | (getTabPosition() == TOP ? FOLLOWS_TOP : FOLLOWS_BOTTOM); - // Try to squeeze in a bit more text - p.pad_left( mLabelPadLeft ); - p.pad_right(2); + { + p.name("htab_"+std::string(child->getName())); + p.visible(false); + p.image_unselected(tab_img); + p.image_selected(tab_selected_img); + p.follows.flags = p.follows.flags() | (getTabPosition() == TOP ? FOLLOWS_TOP : FOLLOWS_BOTTOM); + // Try to squeeze in a bit more text + p.pad_left( mLabelPadLeft ); + p.pad_right(2); } // *TODO : It seems wrong not to use p in both cases considering the way p is initialized diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index cc171661ce..4144a42fd6 100755 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -167,6 +167,7 @@ LLTextBase::Params::Params() max_text_length("max_length", 255), font_shadow("font_shadow"), wrap("wrap"), + trusted_content("trusted_content", true), use_ellipses("use_ellipses", false), parse_urls("parse_urls", false), parse_highlights("parse_highlights", false) @@ -211,6 +212,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p) mLineSpacingPixels(p.line_spacing.pixels), mClip(p.clip), mClipPartial(p.clip_partial && !p.allow_scroll), + mTrustedContent(p.trusted_content), mTrackEnd( p.track_end ), mScrollIndex(-1), mSelectionStart( 0 ), @@ -1029,7 +1031,7 @@ BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLTextBase::handleMouseUp(S32 x, S32 y, MASK mask) { LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y); - if (cur_segment && cur_segment->handleMouseUp(x, y, mask)) + if (hasMouseCapture() && cur_segment && cur_segment->handleMouseUp(x, y, mask)) { // Did we just click on a link? if (mURLClickSignal @@ -3164,7 +3166,7 @@ BOOL LLNormalTextSegment::handleMouseUp(S32 x, S32 y, MASK mask) // Only process the click if it's actually in this segment, not to the right of the end-of-line. if(mEditor.getSegmentAtLocalPos(x, y, false) == this) { - LLUrlAction::clickAction(getStyle()->getLinkHREF()); + LLUrlAction::clickAction(getStyle()->getLinkHREF(), mEditor.isContentTrusted()); return TRUE; } } diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index a74e97cac8..3603f55c3f 100755 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -291,7 +291,8 @@ public: parse_urls, parse_highlights, clip, - clip_partial; + clip_partial, + trusted_content; Optional<S32> v_pad, h_pad; @@ -361,6 +362,7 @@ public: bool getWordWrap() { return mWordWrap; } bool getUseEllipses() { return mUseEllipses; } bool truncate(); // returns true of truncation occurred + bool isContentTrusted() {return mTrustedContent;} // TODO: move into LLTextSegment? void createUrlContextMenu(S32 x, S32 y, const std::string &url); // create a popup context menu for the given Url @@ -634,6 +636,7 @@ protected: bool mBGVisible; // render background? bool mClip; // clip text to widget rect bool mClipPartial; // false if we show lines that are partially inside bounding rect + bool mTrustedContent; // if false, does not allow to execute SURL links from this editor bool mPlainText; // didn't use Image or Icon segments bool mAutoIndent; S32 mMaxTextByteLength; // Maximum length mText is allowed to be in bytes diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 11cfa1d263..d175204e6d 100755 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -60,10 +60,13 @@ BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask) if (!handled && mClickedCallback) { + handled = TRUE; + } + + if (handled) + { // Route future Mouse messages here preemptively. (Release on mouse up.) gFocusMgr.setMouseCapture( this ); - - handled = TRUE; } return handled; @@ -71,7 +74,7 @@ BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask) { - BOOL handled = FALSE; + BOOL handled = LLTextBase::handleMouseUp(x, y, mask); if (getSoundFlags() & MOUSE_UP) { @@ -93,10 +96,6 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask) handled = TRUE; } } - else - { - handled = LLTextBase::handleMouseUp(x, y, mask); - } return handled; } diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index 0c16e06109..02c81c0744 100755 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -310,7 +310,7 @@ LLTextEditor::~LLTextEditor() // Scrollbar is deleted by LLView std::for_each(mUndoStack.begin(), mUndoStack.end(), DeletePointer()); - + mUndoStack.clear(); // context menu is owned by menu holder, not us //delete mContextMenu; } @@ -666,6 +666,14 @@ void LLTextEditor::selectAll() updatePrimary(); } +void LLTextEditor::selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_pos) +{ + setCursorPos(prev_cursor_pos); + startSelection(); + setCursorPos(next_cursor_pos); + endSelection(); +} + BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; @@ -713,7 +721,6 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) setCursorAtLocalPos( x, y, true ); startSelection(); } - gFocusMgr.setMouseCapture( this ); } handled = TRUE; @@ -722,6 +729,10 @@ BOOL LLTextEditor::handleMouseDown(S32 x, S32 y, MASK mask) // Delay cursor flashing resetCursorBlink(); + if (handled && !gFocusMgr.getMouseCapture()) + { + gFocusMgr.setMouseCapture( this ); + } return handled; } @@ -1609,7 +1620,7 @@ BOOL LLTextEditor::handleControlKey(const KEY key, const MASK mask) } } - if (handled) + if (handled && !gFocusMgr.getMouseCapture()) { updatePrimary(); } diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h index 32b543ec0e..d3b7bc0eb7 100755 --- a/indra/llui/lltexteditor.h +++ b/indra/llui/lltexteditor.h @@ -144,6 +144,8 @@ public: virtual void selectAll(); virtual BOOL canSelectAll() const; + void selectByCursorPosition(S32 prev_cursor_pos, S32 next_cursor_pos); + virtual bool canLoadOrSaveToFile(); void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp index 928e82cb8c..ee82e0403b 100755 --- a/indra/llui/lltoolbar.cpp +++ b/indra/llui/lltoolbar.cpp @@ -118,7 +118,8 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p) mButtonLeaveSignal(NULL), mButtonRemoveSignal(NULL), mDragAndDropTarget(false), - mCaretIcon(NULL) + mCaretIcon(NULL), + mCenterPanel(NULL) { mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_WITH_TEXT] = p.button_icon_and_text; mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_ONLY] = p.button_icon; @@ -200,14 +201,15 @@ void LLToolBar::initFromParams(const LLToolBar::Params& p) center_panel_p.auto_resize = false; center_panel_p.user_resize = false; center_panel_p.mouse_opaque = false; - LLLayoutPanel* center_panel = LLUICtrlFactory::create<LLLayoutPanel>(center_panel_p); - mCenteringStack->addChild(center_panel); + mCenterPanel = LLUICtrlFactory::create<LLCenterLayoutPanel>(center_panel_p); + mCenteringStack->addChild(mCenterPanel); LLPanel::Params button_panel_p(p.button_panel); - button_panel_p.rect = center_panel->getLocalRect(); - button_panel_p.follows.flags = FOLLOWS_BOTTOM|FOLLOWS_LEFT; + button_panel_p.rect = mCenterPanel->getLocalRect(); + button_panel_p.follows.flags = FOLLOWS_BOTTOM|FOLLOWS_LEFT; mButtonPanel = LLUICtrlFactory::create<LLPanel>(button_panel_p); - center_panel->addChild(mButtonPanel); + mCenterPanel->setButtonPanel(mButtonPanel); + mCenterPanel->addChild(mButtonPanel); mCenteringStack->addChild(LLUICtrlFactory::create<LLLayoutPanel>(border_panel_p)); @@ -1242,3 +1244,15 @@ const std::string LLToolBarButton::getToolTip() const return tooltip; } +void LLToolBar::LLCenterLayoutPanel::handleReshape(const LLRect& rect, bool by_user) +{ + LLLayoutPanel::handleReshape(rect, by_user); + + if (!mReshapeCallback.empty()) + { + LLRect r; + localRectToOtherView(mButtonPanel->getRect(), &r, gFloaterView); + r.stretch(FLOATER_MIN_VISIBLE_PIXELS); + mReshapeCallback(mLocationId, r); + } +} diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h index 743951a41f..9e17eaed8b 100755 --- a/indra/llui/lltoolbar.h +++ b/indra/llui/lltoolbar.h @@ -125,6 +125,19 @@ namespace LLToolBarEnums SIDE_TOP, }; + enum EToolBarLocation + { + TOOLBAR_NONE = 0, + TOOLBAR_LEFT, + TOOLBAR_RIGHT, + TOOLBAR_BOTTOM, + + TOOLBAR_COUNT, + + TOOLBAR_FIRST = TOOLBAR_LEFT, + TOOLBAR_LAST = TOOLBAR_BOTTOM, + }; + LLLayoutStack::ELayoutOrientation getOrientation(SideType sideType); } @@ -150,6 +163,30 @@ class LLToolBar { friend class LLToolBarButton; public: + + class LLCenterLayoutPanel : public LLLayoutPanel + { + public: + typedef struct LLLayoutPanel::Params Params; + typedef boost::function<void(LLToolBarEnums::EToolBarLocation tb, const LLRect& rect)> reshape_callback_t; + + virtual ~LLCenterLayoutPanel() {} + /*virtual*/ void handleReshape(const LLRect& rect, bool by_user); + + void setLocationId(LLToolBarEnums::EToolBarLocation id) { mLocationId = id; } + void setReshapeCallback(reshape_callback_t cb) { mReshapeCallback = cb; } + void setButtonPanel(LLPanel * panel) { mButtonPanel = panel; } + + protected: + friend class LLUICtrlFactory; + LLCenterLayoutPanel(const Params& params) : LLLayoutPanel(params), mButtonPanel(NULL) {} + + private: + reshape_callback_t mReshapeCallback; + LLToolBarEnums::EToolBarLocation mLocationId; + LLPanel * mButtonPanel; + }; + struct Params : public LLInitParam::Block<Params, LLUICtrl::Params> { Mandatory<LLToolBarEnums::ButtonType> button_display_mode; @@ -198,6 +235,7 @@ public: void setHandleDragCallback(tool_handledrag_callback_t cb) { mHandleDragItemCallback = cb; } void setHandleDropCallback(tool_handledrop_callback_t cb) { mHandleDropCallback = cb; } bool isReadOnly() const { return mReadOnly; } + LLCenterLayoutPanel * getCenterLayoutPanel() const { return mCenterPanel; } LLToolBarButton* createButton(const LLCommandId& id); @@ -270,6 +308,7 @@ private: // related widgets LLLayoutStack* mCenteringStack; + LLCenterLayoutPanel* mCenterPanel; LLPanel* mButtonPanel; LLHandle<class LLContextMenu> mPopupMenuHandle; LLHandle<class LLView> mRemoveButtonHandle; diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 0a0e0e164e..0bc4424a8c 100755 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -405,11 +405,6 @@ public: const std::string& comment = "Declared In Code") : LLCachedControl<T>(LLUI::getControlControlGroup(name), name, default_value, comment) {} - - // This constructor will signal an error if the control doesn't exist in the control group - LLUICachedControl(const std::string& name) - : LLCachedControl<T>(LLUI::getControlControlGroup(name), name) - {} }; namespace LLInitParam diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index b9c843e931..1722bf27bd 100755 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -29,7 +29,7 @@ #define LLUICTRL_CPP #include "lluictrl.h" - +#include "llviewereventrecorder.h" #include "llfocusmgr.h" #include "llpanel.h" #include "lluictrlfactory.h" @@ -308,22 +308,40 @@ void LLUICtrl::onMouseLeave(S32 x, S32 y, MASK mask) //virtual BOOL LLUICtrl::handleMouseDown(S32 x, S32 y, MASK mask) { + + lldebugs << "LLUICtrl::handleMouseDown calling LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl; + BOOL handled = LLView::handleMouseDown(x,y,mask); + if (mMouseDownSignal) { (*mMouseDownSignal)(this,x,y,mask); } + lldebugs << "LLUICtrl::handleMousedown - handled is returning as: " << handled << " " << llendl; + + if (handled) { + LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-56,-56,getPathname()); + } return handled; } //virtual BOOL LLUICtrl::handleMouseUp(S32 x, S32 y, MASK mask) { + + lldebugs << "LLUICtrl::handleMouseUp calling LLView)'s handleMouseUp (first initialized xui to: " << getPathname() << " )" << llendl; + BOOL handled = LLView::handleMouseUp(x,y,mask); + if (handled) { + LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-56,-56,getPathname()); + } if (mMouseUpSignal) { (*mMouseUpSignal)(this,x,y,mask); } + + lldebugs << "LLUICtrl::handleMouseUp - handled for xui " << getPathname() << " - is returning as: " << handled << " " << llendl; + return handled; } diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp index 23e574cb74..12537d9dd1 100755 --- a/indra/llui/llurlaction.cpp +++ b/indra/llui/llurlaction.cpp @@ -87,14 +87,14 @@ void LLUrlAction::executeSLURL(std::string url) { if (sExecuteSLURLCallback) { - sExecuteSLURLCallback(url); + sExecuteSLURLCallback(url ,true); } } -void LLUrlAction::clickAction(std::string url) +void LLUrlAction::clickAction(std::string url, bool trusted_content) { // Try to handle as SLURL first, then http Url - if ( (sExecuteSLURLCallback) && !sExecuteSLURLCallback(url) ) + if ( (sExecuteSLURLCallback) && !sExecuteSLURLCallback(url, trusted_content) ) { if (sOpenURLCallback) { diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h index e731376b95..5f3626490c 100755 --- a/indra/llui/llurlaction.h +++ b/indra/llui/llurlaction.h @@ -66,7 +66,7 @@ public: static void showLocationOnMap(std::string url); /// perform the appropriate action for left-clicking on a Url - static void clickAction(std::string url); + static void clickAction(std::string url, bool trusted_content); /// copy the label for a Url to the clipboard static void copyLabelToClipboard(std::string url); @@ -86,7 +86,7 @@ public: /// specify the callbacks to enable this class's functionality typedef boost::function<void (const std::string&)> url_callback_t; - typedef boost::function<bool(const std::string& url)> execute_url_callback_t; + typedef boost::function<bool(const std::string& url, bool trusted_content)> execute_url_callback_t; static void setOpenURLCallback(url_callback_t cb); static void setOpenURLInternalCallback(url_callback_t cb); diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp index b1cc502c4b..840f67968d 100755 --- a/indra/llui/llurlentry.cpp +++ b/indra/llui/llurlentry.cpp @@ -1067,7 +1067,8 @@ LLUrlEntrySLLabel::LLUrlEntrySLLabel() std::string LLUrlEntrySLLabel::getLabel(const std::string &url, const LLUrlLabelCallback &cb) { - return getLabelFromWikiLink(url); + std::string label = getLabelFromWikiLink(url); + return (!LLUrlRegistry::instance().hasUrl(label)) ? label : getUrl(url); } std::string LLUrlEntrySLLabel::getUrl(const std::string &string) const diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 3613a40e2c..5ee2169b66 100755 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -48,7 +48,9 @@ #include "lluictrlfactory.h" #include "lltooltip.h" #include "llsdutil.h" - +#include "llsdserialize.h" +#include "llviewereventrecorder.h" +#include "llkeyboard.h" // for ui edit hack #include "llbutton.h" #include "lllineeditor.h" @@ -642,13 +644,33 @@ void LLView::setVisible(BOOL visible) // virtual void LLView::handleVisibilityChange ( BOOL new_visibility ) { + BOOL old_visibility; + BOOL log_visibility_change = LLViewerEventRecorder::instance().getLoggingStatus(); BOOST_FOREACH(LLView* viewp, mChildList) { // only views that are themselves visible will have their overall visibility affected by their ancestors - if (viewp->getVisible()) + old_visibility=viewp->getVisible(); + + if(log_visibility_change) + { + if (old_visibility!=new_visibility) + { + LLViewerEventRecorder::instance().logVisibilityChange( viewp->getPathname(), viewp->getName(), new_visibility,"widget"); + } + } + + if (old_visibility) { viewp->handleVisibilityChange ( new_visibility ); } + + if(log_visibility_change) + { + // Consider changing returns to confirm success and know which widget grabbed it + // For now assume success and log at highest xui possible + // NOTE we log actual state - which may differ if it somehow failed to set visibility + lldebugs << "LLView::handleVisibilityChange - now: " << getVisible() << " xui: " << viewp->getPathname() << " name: " << viewp->getName() << llendl; + } } } @@ -697,6 +719,7 @@ bool LLView::visibleEnabledAndContains(S32 local_x, S32 local_y) && getEnabled(); } +// This is NOT event recording related void LLView::logMouseEvent() { if (sDebugMouseHandling) @@ -743,7 +766,14 @@ LLView* LLView::childrenHandleMouseEvent(const METHOD& method, S32 x, S32 y, XDA if ((viewp->*method)( local_x, local_y, extra ) || (allow_mouse_block && viewp->blockMouseEvent( local_x, local_y ))) { + lldebugs << "LLView::childrenHandleMouseEvent calling updatemouseeventinfo - local_x|global x "<< local_x << " " << x << "local/global y " << local_y << " " << y << llendl; + lldebugs << "LLView::childrenHandleMouseEvent getPathname for viewp result: " << viewp->getPathname() << "for this view: " << getPathname() << llendl; + + LLViewerEventRecorder::instance().updateMouseEventInfo(x,y,-55,-55,getPathname()); + + // This is NOT event recording related viewp->logMouseEvent(); + return viewp; } } @@ -766,6 +796,7 @@ LLView* LLView::childrenHandleToolTip(S32 x, S32 y, MASK mask) if (viewp->handleToolTip(local_x, local_y, mask) || viewp->blockMouseEvent(local_x, local_y)) { + // This is NOT event recording related viewp->logMouseEvent(); return viewp; } @@ -824,6 +855,7 @@ LLView* LLView::childrenHandleHover(S32 x, S32 y, MASK mask) if (viewp->handleHover(local_x, local_y, mask) || viewp->blockMouseEvent(local_x, local_y)) { + // This is NOT event recording related viewp->logMouseEvent(); return viewp; } @@ -907,10 +939,12 @@ BOOL LLView::handleKey(KEY key, MASK mask, BOOL called_from_parent) if (!handled) { + // For event logging we don't care which widget handles it + // So we capture the key at the end of this function once we know if it was handled handled = handleKeyHere( key, mask ); - if (handled && LLView::sDebugKeys) + if (handled) { - llinfos << "Key handled by " << getName() << llendl; + llwarns << "Key handled by " << getName() << llendl; } } } @@ -958,6 +992,11 @@ BOOL LLView::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) handled = mParentView->handleUnicodeChar(uni_char, FALSE); } + if (handled) + { + LLViewerEventRecorder::instance().logKeyUnicodeEvent(uni_char); + } + return handled; } @@ -987,12 +1026,16 @@ BOOL LLView::hasMouseCapture() BOOL LLView::handleMouseUp(S32 x, S32 y, MASK mask) { - return childrenHandleMouseUp( x, y, mask ) != NULL; + LLView* r = childrenHandleMouseUp( x, y, mask ); + + return (r!=NULL); } BOOL LLView::handleMouseDown(S32 x, S32 y, MASK mask) { - return childrenHandleMouseDown( x, y, mask ) != NULL; + LLView* r= childrenHandleMouseDown(x, y, mask ); + + return (r!=NULL); } BOOL LLView::handleDoubleClick(S32 x, S32 y, MASK mask) @@ -1065,7 +1108,7 @@ LLView* LLView::childrenHandleDoubleClick(S32 x, S32 y, MASK mask) LLView* LLView::childrenHandleMouseUp(S32 x, S32 y, MASK mask) { - return childrenHandleMouseEvent(&LLView::handleMouseUp, x, y, mask); + return childrenHandleMouseEvent(&LLView::handleMouseUp, x, y, mask); } LLView* LLView::childrenHandleRightMouseUp(S32 x, S32 y, MASK mask) @@ -1271,52 +1314,55 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent) // move child views according to reshape flags BOOST_FOREACH(LLView* viewp, mChildList) { - LLRect child_rect( viewp->mRect ); - - if (viewp->followsRight() && viewp->followsLeft()) - { - child_rect.mRight += delta_width; - } - else if (viewp->followsRight()) + if (viewp != NULL) { - child_rect.mLeft += delta_width; - child_rect.mRight += delta_width; - } - else if (viewp->followsLeft()) - { - // left is 0, don't need to adjust coords - } - else - { - // BUG what to do when we don't follow anyone? - // for now, same as followsLeft - } + LLRect child_rect( viewp->mRect ); - if (viewp->followsTop() && viewp->followsBottom()) - { - child_rect.mTop += delta_height; - } - else if (viewp->followsTop()) - { - child_rect.mTop += delta_height; - child_rect.mBottom += delta_height; - } - else if (viewp->followsBottom()) - { - // bottom is 0, so don't need to adjust coords - } - else - { - // BUG what to do when we don't follow? - // for now, same as bottom - } + if (viewp->followsRight() && viewp->followsLeft()) + { + child_rect.mRight += delta_width; + } + else if (viewp->followsRight()) + { + child_rect.mLeft += delta_width; + child_rect.mRight += delta_width; + } + else if (viewp->followsLeft()) + { + // left is 0, don't need to adjust coords + } + else + { + // BUG what to do when we don't follow anyone? + // for now, same as followsLeft + } - S32 delta_x = child_rect.mLeft - viewp->getRect().mLeft; - S32 delta_y = child_rect.mBottom - viewp->getRect().mBottom; - viewp->translate( delta_x, delta_y ); - if (child_rect.getWidth() != viewp->getRect().getWidth() || child_rect.getHeight() != viewp->getRect().getHeight()) - { - viewp->reshape(child_rect.getWidth(), child_rect.getHeight()); + if (viewp->followsTop() && viewp->followsBottom()) + { + child_rect.mTop += delta_height; + } + else if (viewp->followsTop()) + { + child_rect.mTop += delta_height; + child_rect.mBottom += delta_height; + } + else if (viewp->followsBottom()) + { + // bottom is 0, so don't need to adjust coords + } + else + { + // BUG what to do when we don't follow? + // for now, same as bottom + } + + S32 delta_x = child_rect.mLeft - viewp->getRect().mLeft; + S32 delta_y = child_rect.mBottom - viewp->getRect().mBottom; + viewp->translate( delta_x, delta_y ); + if (child_rect.getWidth() != viewp->getRect().getWidth() || child_rect.getHeight() != viewp->getRect().getHeight()) + { + viewp->reshape(child_rect.getWidth(), child_rect.getHeight()); + } } } } diff --git a/indra/llui/llviewereventrecorder.cpp b/indra/llui/llviewereventrecorder.cpp new file mode 100644 index 0000000000..546a0f5866 --- /dev/null +++ b/indra/llui/llviewereventrecorder.cpp @@ -0,0 +1,296 @@ +/** + * @file llviewereventrecorder.cpp + * @brief Viewer event recording and playback support for mouse and keyboard events + * + * $LicenseInfo:firstyear=2013&license=viewerlgpl$ + * + * Copyright (c) 2013, Linden Research, Inc. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + + +#include "llviewereventrecorder.h" +#include "llui.h" +#include "llleap.h" + +LLViewerEventRecorder::LLViewerEventRecorder() { + + clear(UNDEFINED); + logEvents = false; + // Remove any previous event log file + std::string old_log_ui_events_to_llsd_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.old"); + LLFile::remove(old_log_ui_events_to_llsd_file); + + + mLogFilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife_Events_log.llsd"); + LLFile::rename(mLogFilename, old_log_ui_events_to_llsd_file); + +} + + +bool LLViewerEventRecorder::displayViewerEventRecorderMenuItems() { + return LLUI::sSettingGroups["config"]->getBOOL("ShowEventRecorderMenuItems"); +} + + +void LLViewerEventRecorder::setEventLoggingOn() { + if (! mLog.is_open()) { + mLog.open(mLogFilename, llofstream::out); + } + logEvents=true; + lldebugs << "LLViewerEventRecorder::setEventLoggingOn event logging turned on" << llendl; +} + +void LLViewerEventRecorder::setEventLoggingOff() { + logEvents=false; + mLog.flush(); + mLog.close(); + lldebugs << "LLViewerEventRecorder::setEventLoggingOff event logging turned off" << llendl; +} + + + LLViewerEventRecorder::~LLViewerEventRecorder() { + if (mLog.is_open()) { + mLog.close(); + } +} + +void LLViewerEventRecorder::clear_xui() { + xui.clear(); +} + +void LLViewerEventRecorder::clear(S32 r) { + + xui.clear(); + + local_x=r; + local_y=r; + + global_x=r; + global_y=r; + + +} + +void LLViewerEventRecorder::setMouseLocalCoords(S32 x, S32 y) { + local_x=x; + local_y=y; +} + +void LLViewerEventRecorder::setMouseGlobalCoords(S32 x, S32 y) { + global_x=x; + global_y=y; +} + +void LLViewerEventRecorder::updateMouseEventInfo(S32 local_x, S32 local_y, S32 global_x, S32 global_y, std::string mName) { + + LLView * target_view = LLUI::resolvePath(LLUI::getRootView(), xui); + if (! target_view) { + lldebugs << "LLViewerEventRecorder::updateMouseEventInfo - xui path on file at moment is NOT valid - so DO NOT record these local coords" << llendl; + return; + } + lldebugs << "LLViewerEventRecorder::updateMouseEventInfo b4 updatemouseeventinfo - local_x|global x "<< this->local_x << " " << this->global_x << "local/global y " << this->local_y << " " << this->global_y << " mname: " << mName << " xui: " << xui << llendl; + + + if (this->local_x < 1 && this->local_y<1 && local_x && local_y) { + this->local_x=local_x; + this->local_y=local_y; + } + this->global_x=global_x; + this->global_y=global_y; + + // ONLY record deepest xui path for hierarchy searches - or first/only xui for floaters/panels reached via mouse captor - and llmousehandler + if (mName!="" && mName!="/" && xui=="") { + // xui=std::string("/")+mName+xui; + //xui=mName+xui; + xui = mName; // TODO review confirm we never call with partial path - also cAN REMOVE CHECK FOR "" - ON OTHER HAND IT'S PRETTY HARMLESS + } + + lldebugs << "LLViewerEventRecorder::updateMouseEventInfo after updatemouseeventinfo - local_x|global x "<< this->local_x << " " << this->global_x << "local/global y " << this->local_y << " " << this->global_y << " mname: " << mName << " xui: " << xui << llendl; +} + +void LLViewerEventRecorder::logVisibilityChange(std::string xui, std::string name, BOOL visibility, std::string event_subtype) { + + LLSD event=LLSD::emptyMap(); + + event.insert("event",LLSD(std::string("visibility"))); + + if (visibility) { + event.insert("visibility",LLSD(true)); + } else { + event.insert("visibility",LLSD(false)); + } + + if (event_subtype!="") { + event.insert("event_subtype", LLSD(event_subtype)); + } + + if(name!="") { + event.insert("name",LLSD(name)); + } + + if (xui!="") { + event.insert("path",LLSD(xui)); + } + + event.insert("timestamp",LLSD(LLDate::now().asString())); + recordEvent(event); +} + + +std::string LLViewerEventRecorder::get_xui() { + return xui; +} +void LLViewerEventRecorder::update_xui(std::string xui) { + if (xui!="" && this->xui=="" ) { + lldebugs << "LLViewerEventRecorder::update_xui to " << xui << llendl; + this->xui=xui; + } else { + lldebugs << "LLViewerEventRecorder::update_xui called with empty string" << llendl; + } +} + +void LLViewerEventRecorder::logKeyEvent(KEY key, MASK mask) { + + // NOTE: Event recording only logs keydown events - the viewer itself hides keyup events at a fairly low level in the code and does not appear to care about them anywhere + + LLSD event = LLSD::emptyMap(); + + event.insert("event",LLSD("type")); + + // keysym ...or + // keycode...or + // char + event.insert("keysym",LLSD(LLKeyboard::stringFromKey(key))); + + // path (optional) - for now we are not recording path for key events during record - should not be needed for full record and playback of recorded steps + // as a vita script - it does become useful if you edit the resulting vita script and wish to remove some steps leading to a key event - that sort of edit might + // break the test script and it would be useful to have more context to make these sorts of edits safer + + // TODO replace this with a call which extracts to an array of names of masks (just like vita expects during playback) + // This is looking more and more like an object is a good idea, for this part a handy method call to setMask(mask) would be nice :-) + // call the func - llkeyboard::llsdStringarrayFromMask + + LLSD key_mask=LLSD::emptyArray(); + + if (mask & MASK_CONTROL) { key_mask.append(LLSD("CTL")); } // Mac command key - has code of 0x1 in llcommon/indra_contstants + if (mask & MASK_ALT) { key_mask.append(LLSD("ALT")); } + if (mask & MASK_SHIFT) { key_mask.append(LLSD("SHIFT")); } + if (mask & MASK_MAC_CONTROL) { key_mask.append(LLSD("MAC_CONTROL")); } + + event.insert("mask",key_mask); + event.insert("timestamp",LLSD(LLDate::now().asString())); + + // Although vita has keyDown and keyUp requests it does not have type as a high-level concept + // (maybe it should) - instead it has a convenience method that generates the keydown and keyup events + // Here we will use "type" as our event type + + lldebugs << "LLVIewerEventRecorder::logKeyEvent Serialized LLSD for event " << event.asString() << "\n" << llendl; + + + //lldebugs << "[VITA] key_name: " << LLKeyboard::stringFromKey(key) << "mask: "<< mask << "handled by " << getName() << llendl; + lldebugs << "LLVIewerEventRecorder::logKeyEvent key_name: " << LLKeyboard::stringFromKey(key) << "mask: "<< mask << llendl; + + + recordEvent(event); + +} + +void LLViewerEventRecorder::playbackRecording() { + + LLSD LeapCommand; + + // ivita sets this on startup, it also sends commands to the viewer to make start, stop, and playback menu items visible in viewer + LeapCommand =LLUI::sSettingGroups["config"]->getLLSD("LeapPlaybackEventsCommand"); + + lldebugs << "[VITA] launching playback - leap command is: " << LLSDXMLStreamer(LeapCommand) << llendl; + LLLeap::create("", LeapCommand, false); // exception=false + +} + + +void LLViewerEventRecorder::recordEvent(LLSD event) { + lldebugs << "LLViewerEventRecorder::recordEvent event written to log: " << LLSDXMLStreamer(event) << llendl; + mLog << event << std::endl; + +} +void LLViewerEventRecorder::logKeyUnicodeEvent(llwchar uni_char) { + if (! logEvents) return; + + // Note: keyUp is not captured since the viewer seems to not care about keyUp events + + LLSD event=LLSD::emptyMap(); + + event.insert("timestamp",LLSD(LLDate::now().asString())); + + + // keysym ...or + // keycode...or + // char + + lldebugs << "Wrapped in conversion to wstring " << wstring_to_utf8str(LLWString( 1, uni_char)) << "\n" << llendl; + + event.insert("char", + LLSD( wstring_to_utf8str(LLWString( 1,uni_char)) ) + ); + + // path (optional) - for now we are not recording path for key events during record - should not be needed for full record and playback of recorded steps + // as a vita script - it does become useful if you edit the resulting vita script and wish to remove some steps leading to a key event - that sort of edit might + // break the test script and it would be useful to have more context to make these sorts of edits safer + + // TODO need to consider mask keys too? Doesn't seem possible - at least not easily at this point + + event.insert("event",LLSD("keyDown")); + + lldebugs << "[VITA] unicode key: " << uni_char << llendl; + lldebugs << "[VITA] dumpxml " << LLSDXMLStreamer(event) << "\n" << llendl; + + + recordEvent(event); + +} + +void LLViewerEventRecorder::logMouseEvent(std::string button_state,std::string button_name) +{ + if (! logEvents) return; + + LLSD event=LLSD::emptyMap(); + + event.insert("event",LLSD(std::string("mouse"+ button_state))); + event.insert("button",LLSD(button_name)); + if (xui!="") { + event.insert("path",LLSD(xui)); + } + + if (local_x>0 && local_y>0) { + event.insert("local_x",LLSD(local_x)); + event.insert("local_y",LLSD(local_y)); + } + + if (global_x>0 && global_y>0) { + event.insert("global_x",LLSD(global_x)); + event.insert("global_y",LLSD(global_y)); + } + event.insert("timestamp",LLSD(LLDate::now().asString())); + recordEvent(event); + + + clear(UNDEFINED); + + +} diff --git a/indra/llui/llviewereventrecorder.h b/indra/llui/llviewereventrecorder.h new file mode 100644 index 0000000000..375efcc3de --- /dev/null +++ b/indra/llui/llviewereventrecorder.h @@ -0,0 +1,103 @@ +/** + * @file llviewereventrecorder.h + * @brief Viewer event recording and playback support for mouse and keyboard events + * + * $LicenseInfo:firstyear=2013&license=viewerlgpl$ + * + * Copyright (c) 2013, Linden Research, Inc. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_VIEWER_EVENT_RECORDER +#define LL_VIEWER_EVENT_RECORDER + + +#include "linden_common.h" + +#include "lldir.h" +#include "llsd.h" +#include "llfile.h" +#include "llvfile.h" +#include "lldate.h" +#include "llsdserialize.h" +#include "llkeyboard.h" +#include "llstring.h" + +#include <sstream> + +#include "llsingleton.h" // includes llerror which we need here so we can skip the include here + +class LLViewerEventRecorder : public LLSingleton<LLViewerEventRecorder> +{ + + public: + + LLViewerEventRecorder(); // TODO Protect constructor better if we can (not happy in private section) - could add a factory... - we are singleton + ~LLViewerEventRecorder(); + + + void updateMouseEventInfo(S32 local_x,S32 local_y, S32 global_x, S32 global_y, std::string mName); + void setMouseLocalCoords(S32 x,S32 y); + void setMouseGlobalCoords(S32 x,S32 y); + + void logMouseEvent(std::string button_state, std::string button_name ); + void logKeyEvent(KEY key, MASK mask); + void logKeyUnicodeEvent(llwchar uni_char); + + void logVisibilityChange(std::string xui, std::string name, BOOL visibility, std::string event_subtype); + + void clear_xui(); + std::string get_xui(); + void update_xui(std::string xui); + + bool getLoggingStatus(){return logEvents;}; + void setEventLoggingOn(); + void setEventLoggingOff(); + + void playbackRecording(); + + bool displayViewerEventRecorderMenuItems(); + + + protected: + // On if we wish to log events at the moment - toggle via Develop/Recorder submenu + bool logEvents; + + std::string mLogFilename; + llofstream mLog; + + + private: + + // Mouse event info + S32 global_x; + S32 global_y; + S32 local_x; + S32 local_y; + + // XUI path of UI element + std::string xui; + + // Actually write the event out to llsd log file + void recordEvent(LLSD event); + + void clear(S32 r); + + static const S32 UNDEFINED=-1; +}; +#endif diff --git a/indra/llvfs/lldiriterator.cpp b/indra/llvfs/lldiriterator.cpp index 460d2a8b4f..229608231c 100755 --- a/indra/llvfs/lldiriterator.cpp +++ b/indra/llvfs/lldiriterator.cpp @@ -119,16 +119,25 @@ bool LLDirIterator::Impl::next(std::string &fname) fs::directory_iterator end_itr; // default construction yields past-the-end bool found = false; - while (mIter != end_itr && !found) + + // Check if path is a directory. + try { - boost::smatch match; - std::string name = mIter->path().filename().string(); - if (found = boost::regex_match(name, match, mFilterExp)) + while (mIter != end_itr && !found) { - fname = name; - } + boost::smatch match; + std::string name = mIter->path().filename().string(); + if (found = boost::regex_match(name, match, mFilterExp)) + { + fname = name; + } - ++mIter; + ++mIter; + } + } + catch (const fs::filesystem_error& e) + { + llwarns << e.what() << llendl; } return found; diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp index 82c926620a..7b589f5b96 100755 --- a/indra/llvfs/llvfs.cpp +++ b/indra/llvfs/llvfs.cpp @@ -578,6 +578,7 @@ LLVFS::~LLVFS() mFreeBlocksByLength.clear(); for_each(mFreeBlocksByLocation.begin(), mFreeBlocksByLocation.end(), DeletePairedPointer()); + mFreeBlocksByLocation.clear(); unlockAndClose(mDataFP); mDataFP = NULL; @@ -1835,6 +1836,7 @@ void LLVFS::audit() } for_each(audit_blocks.begin(), audit_blocks.end(), DeletePointer()); + audit_blocks.clear(); } diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index 3579b5d42f..b0f4bc5503 100755 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -171,6 +171,7 @@ std::string LLDXDriverFile::dump() LLDXDevice::~LLDXDevice() { for_each(mDriverFiles.begin(), mDriverFiles.end(), DeletePairedPointer()); + mDriverFiles.clear(); } std::string LLDXDevice::dump() @@ -230,6 +231,7 @@ LLDXHardware::LLDXHardware() void LLDXHardware::cleanup() { // for_each(mDevices.begin(), mDevices.end(), DeletePairedPointer()); + // mDevices.clear(); } /* diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 7415c9d8dc..b393a3796d 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -376,13 +376,6 @@ attributedStringInfo getSegments(NSAttributedString *str) [[self inputContext] handleEvent:theEvent]; } - if ([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSCarriageReturnCharacter || - [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSEnterCharacter) - { - // callKeyDown won't return the value we expect for enter or return. Handle them as a separate case. - [[self inputContext] handleEvent:theEvent]; - } - // OS X intentionally does not send us key-up information on cmd-key combinations. // This behaviour is not a bug, and only applies to cmd-combinations (no others). // Since SL assumes we receive those, we fake it here. diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index 9712ae1d91..eadff8a6b4 100755 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -122,6 +122,7 @@ void LLWindowCallbacks::handleResize(LLWindow *window, const S32 width, const S3 void LLWindowCallbacks::handleFocus(LLWindow *window) { + LL_WARNS("COCOA") << "Called handleFocus proto" << LL_ENDL; } void LLWindowCallbacks::handleFocusLost(LLWindow *window) diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index 2cae6f3f72..81b25601a9 100755 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -25,6 +25,9 @@ * $/LicenseInfo$ */ +#ifndef LL_LLWINDOWMACOSX_OBJC_H +#define LL_LLWINDOWMACOSX_OBJC_H + #include <map> #include <vector> @@ -144,3 +147,5 @@ NSWindowRef getMainAppWindow(); GLViewRef getGLView(); unsigned int getModifiers(); + +#endif // LL_LLWINDOWMACOSX_OBJC_H diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 56472e6b45..11c0b51086 100755 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -331,7 +331,16 @@ void callMouseExit() void callWindowFocus() { - gWindowImplementation->getCallbacks()->handleFocus(gWindowImplementation); + if ( gWindowImplementation && gWindowImplementation->getCallbacks() ) + { + gWindowImplementation->getCallbacks()->handleFocus (gWindowImplementation); + } + else + { + LL_WARNS("COCOA") << "Window Implementation or callbacks not yet initialized." << LL_ENDL; + } + + } void callWindowUnfocus() @@ -1300,6 +1309,8 @@ void LLWindowMacOSX::setupFailure(const std::string& text, const std::string& ca OSMessageBox(text, caption, type); } + // Note on event recording - QUIT is a known special case and we are choosing NOT to record it for the record and playback feature + // it is handled at a very low-level const char* cursorIDToName(int id) { switch (id) diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 16f2290787..97fad7feb0 100755 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -391,7 +391,7 @@ LLControlVariable* LLControlGroup::declareControl(const std::string& name, eCont } else { - llwarns << "Control named " << name << " already exists, ignoring new declaration." << llendl; + LL_WARNS("Settings") << "Control named " << name << " already exists, ignoring new declaration." << LL_ENDL; } return existing_control; } @@ -630,14 +630,14 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require if (!xml_controls.parseFile(filename)) { - llwarns << "Unable to open control file " << filename << llendl; + LL_WARNS("Settings") << "Unable to open control file " << filename << LL_ENDL; return 0; } LLXmlTreeNode* rootp = xml_controls.getRoot(); if (!rootp || !rootp->hasAttribute("version")) { - llwarns << "No valid settings header found in control file " << filename << llendl; + LL_WARNS("Settings") << "No valid settings header found in control file " << filename << LL_ENDL; return 0; } @@ -650,7 +650,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require // Check file version if (version != CURRENT_VERSION) { - llinfos << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << llendl; + LL_INFOS("Settings") << filename << " does not appear to be a version " << CURRENT_VERSION << " controls file" << LL_ENDL; return 0; } @@ -668,7 +668,7 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require if (!name.empty()) { //read in to end of line - llwarns << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << llendl; + LL_WARNS("Settings") << "LLControlGroup::loadFromFile() : Trying to set \"" << name << "\", setting doesn't exist." << LL_ENDL; } child_nodep = rootp->getNextChild(); continue; @@ -822,7 +822,7 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only LLControlVariable* control = iter->second; if (!control) { - llwarns << "Tried to save invalid control: " << iter->first << llendl; + LL_WARNS("Settings") << "Tried to save invalid control: " << iter->first << LL_ENDL; } else if( control->shouldSave(nondefault_only) ) { @@ -838,12 +838,12 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only { LLSDSerialize::toPrettyXML(settings, file); file.close(); - llinfos << "Saved to " << filename << llendl; + LL_INFOS("Settings") << "Saved to " << filename << LL_ENDL; } else { // This is a warning because sometime we want to use settings files which can't be written... - llwarns << "Unable to open settings file: " << filename << llendl; + LL_WARNS("Settings") << "Unable to open settings file: " << filename << LL_ENDL; return 0; } return num_saved; @@ -856,14 +856,14 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v infile.open(filename); if(!infile.is_open()) { - llwarns << "Cannot find file " << filename << " to load." << llendl; + LL_WARNS("Settings") << "Cannot find file " << filename << " to load." << LL_ENDL; return 0; } if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, infile)) { infile.close(); - llwarns << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << llendl; + LL_WARNS("Settings") << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << LL_ENDL; return loadFromFileLegacy(filename, TRUE, TYPE_STRING); } @@ -976,6 +976,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v ++validitems; } + LL_DEBUGS("Settings") << "Loaded " << validitems << " settings from " << filename << LL_ENDL; return validitems; } @@ -1012,7 +1013,7 @@ void main() BOOL_CONTROL baz; U32 count = gGlobals.loadFromFile("controls.ini"); - llinfos << "Loaded " << count << " controls" << llendl; + LL_INFOS("Settings") << "Loaded " << count << " controls" << LL_ENDL; // test insertion foo = new LLControlVariable<F32>("gFoo", 5.f, 1.f, 20.f); @@ -1273,19 +1274,19 @@ LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd, eControlType type, const st LLColor4 color(sd); if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f) { - llwarns << "Color " << control_name << " red value out of range: " << color << llendl; + LL_WARNS("Settings") << "Color " << control_name << " red value out of range: " << color << LL_ENDL; } else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f) { - llwarns << "Color " << control_name << " green value out of range: " << color << llendl; + LL_WARNS("Settings") << "Color " << control_name << " green value out of range: " << color << LL_ENDL; } else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f) { - llwarns << "Color " << control_name << " blue value out of range: " << color << llendl; + LL_WARNS("Settings") << "Color " << control_name << " blue value out of range: " << color << LL_ENDL; } else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f) { - llwarns << "Color " << control_name << " alpha value out of range: " << color << llendl; + LL_WARNS("Settings") << "Color " << control_name << " alpha value out of range: " << color << LL_ENDL; } return LLColor4(sd); diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index e1f9be80dd..f46d21408b 100755 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -408,16 +408,6 @@ public: } } - LLCachedControl(LLControlGroup& group, - const std::string& name) - { - mCachedControlPtr = LLControlCache<T>::getInstance(name); - if (mCachedControlPtr.isNull()) - { - mCachedControlPtr = new LLControlCache<T>(group, name); - } - } - operator const T&() const { return mCachedControlPtr->getValue(); } operator boost::function<const T&()> () const { return boost::function<const T&()>(*this); } const T& operator()() { return mCachedControlPtr->getValue(); } diff --git a/indra/media_plugins/winmmshim/winmm_shim.cpp b/indra/media_plugins/winmmshim/winmm_shim.cpp index aac349bf57..49a1c9dba3 100755 --- a/indra/media_plugins/winmmshim/winmm_shim.cpp +++ b/indra/media_plugins/winmmshim/winmm_shim.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2010&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2010-2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,8 +30,8 @@ using std::wstring; -static float sVolumeLevel = 1.f; -static bool sMute = false; +static float sVolumeLevel = 1.f; // Could be covered by critical section, +static bool sMute = false; // not needed with atomicity and alignment. static CRITICAL_SECTION sCriticalSection; BOOL APIENTRY DllMain( HMODULE hModule, @@ -39,37 +39,44 @@ BOOL APIENTRY DllMain( HMODULE hModule, LPVOID lpReserved ) { - InitializeCriticalSection(&sCriticalSection); + if (DLL_PROCESS_ATTACH == ul_reason_for_call) + { + InitializeCriticalSection(&sCriticalSection); + } return TRUE; } void ll_winmm_shim_initialize(){ - static bool initialized = false; - // do this only once - EnterCriticalSection(&sCriticalSection); + static volatile bool initialized = false; + + // do this only once using double-check locking if (!initialized) - { // bind to original winmm.dll - TCHAR system_path[MAX_PATH]; - TCHAR dll_path[MAX_PATH]; - ::GetSystemDirectory(system_path, MAX_PATH); + { + EnterCriticalSection(&sCriticalSection); + if (!initialized) + { // bind to original winmm.dll + TCHAR system_path[MAX_PATH]; + TCHAR dll_path[MAX_PATH]; + ::GetSystemDirectory(system_path, MAX_PATH); - // grab winmm.dll from system path, where it should live - wsprintf(dll_path, "%s\\winmm.dll", system_path); - HMODULE winmm_handle = ::LoadLibrary(dll_path); + // grab winmm.dll from system path, where it should live + wsprintf(dll_path, "%s\\winmm.dll", system_path); + HMODULE winmm_handle = ::LoadLibrary(dll_path); - if (winmm_handle != NULL) - { // we have a dll, let's get out pointers! - initialized = true; - init_function_pointers(winmm_handle); - ::OutputDebugStringA("WINMM_SHIM.DLL: real winmm.dll initialized successfully\n"); - } - else - { - // failed to initialize real winmm.dll - ::OutputDebugStringA("WINMM_SHIM.DLL: Failed to initialize real winmm.dll\n"); + if (winmm_handle != NULL) + { // we have a dll, let's get out pointers! + init_function_pointers(winmm_handle); + ::OutputDebugStringA("WINMM_SHIM.DLL: real winmm.dll initialized successfully\n"); + initialized = true; // Last thing after completing setup + } + else + { + // failed to initialize real winmm.dll + ::OutputDebugStringA("WINMM_SHIM.DLL: Failed to initialize real winmm.dll\n"); + } } + LeaveCriticalSection(&sCriticalSection); } - LeaveCriticalSection(&sCriticalSection); } @@ -84,7 +91,7 @@ extern "C" int mBitsPerSample; }; typedef std::map<HWAVEOUT, WaveOutFormat*> wave_out_map_t; - static wave_out_map_t sWaveOuts; + static wave_out_map_t sWaveOuts; // Covered by sCriticalSection MMRESULT WINAPI waveOutOpen( LPHWAVEOUT phwo, UINT uDeviceID, LPCWAVEFORMATEX pwfx, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen) { @@ -100,7 +107,9 @@ extern "C" && ((fdwOpen & WAVE_FORMAT_QUERY) == 0)) // not just querying for format support { // remember the requested bits per sample, and associate with the given handle WaveOutFormat* wave_outp = new WaveOutFormat(pwfx->wBitsPerSample); + EnterCriticalSection(&sCriticalSection); sWaveOuts.insert(std::make_pair(*phwo, wave_outp)); + LeaveCriticalSection(&sCriticalSection); } return result; } @@ -108,13 +117,15 @@ extern "C" MMRESULT WINAPI waveOutClose( HWAVEOUT hwo) { ll_winmm_shim_initialize(); + EnterCriticalSection(&sCriticalSection); wave_out_map_t::iterator found_it = sWaveOuts.find(hwo); if (found_it != sWaveOuts.end()) { // forget what we know about this handle delete found_it->second; sWaveOuts.erase(found_it); } - return waveOutClose_orig( hwo); + LeaveCriticalSection(&sCriticalSection); + return waveOutClose_orig(hwo); } MMRESULT WINAPI waveOutWrite( HWAVEOUT hwo, LPWAVEHDR pwh, UINT cbwh) @@ -128,11 +139,19 @@ extern "C" } else if (sVolumeLevel != 1.f) { // need to apply volume level + int bits_per_sample(0); + + EnterCriticalSection(&sCriticalSection); wave_out_map_t::iterator found_it = sWaveOuts.find(hwo); if (found_it != sWaveOuts.end()) { - WaveOutFormat* formatp = found_it->second; - switch (formatp->mBitsPerSample){ + bits_per_sample = found_it->second->mBitsPerSample; + } + LeaveCriticalSection(&sCriticalSection); + if (bits_per_sample) + { + switch (bits_per_sample) + { case 8: { char volume = (char)(sVolumeLevel * 127.f); diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index d3835a5b2a..17e340d136 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -191,6 +191,7 @@ set(viewer_SOURCE_FILES llexpandabletextbox.cpp llexternaleditor.cpp llface.cpp + llfacebookconnect.cpp llfasttimerview.cpp llfavoritesbar.cpp llfeaturemanager.cpp @@ -266,6 +267,7 @@ set(viewer_SOURCE_FILES llfloaterregiondebugconsole.cpp llfloaterregioninfo.cpp llfloaterreporter.cpp + llfloaterregionrestarting.cpp llfloaterscriptdebug.cpp llfloaterscriptlimits.cpp llfloatersearch.cpp @@ -273,6 +275,7 @@ set(viewer_SOURCE_FILES llfloatersettingsdebug.cpp llfloatersidepanelcontainer.cpp llfloatersnapshot.cpp + llfloatersocial.cpp llfloatersounddevices.cpp llfloaterspellchecksettings.cpp llfloatertelehub.cpp @@ -508,6 +511,7 @@ set(viewer_SOURCE_FILES llsidetraypanelcontainer.cpp llsky.cpp llslurl.cpp + llsnapshotlivepreview.cpp llspatialpartition.cpp llspeakers.cpp llspeakingindicatormanager.cpp @@ -776,6 +780,7 @@ set(viewer_HEADER_FILES llexpandabletextbox.h llexternaleditor.h llface.h + llfacebookconnect.h llfasttimerview.h llfavoritesbar.h llfeaturemanager.h @@ -851,6 +856,7 @@ set(viewer_HEADER_FILES llfloaterregiondebugconsole.h llfloaterregioninfo.h llfloaterreporter.h + llfloaterregionrestarting.h llfloaterscriptdebug.h llfloaterscriptlimits.h llfloatersearch.h @@ -858,6 +864,7 @@ set(viewer_HEADER_FILES llfloatersettingsdebug.h llfloatersidepanelcontainer.h llfloatersnapshot.h + llfloatersocial.h llfloatersounddevices.h llfloaterspellchecksettings.h llfloatertelehub.h @@ -1082,6 +1089,7 @@ set(viewer_HEADER_FILES llsidetraypanelcontainer.h llsky.h llslurl.h + llsnapshotlivepreview.h llspatialpartition.h llspeakers.h llspeakingindicatormanager.h @@ -1742,6 +1750,7 @@ if (WINDOWS) ARGS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py --actions=copy + --arch=${ARCH} --artwork=${ARTWORK_DIR} --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} @@ -1809,6 +1818,7 @@ if (WINDOWS) COMMAND ${PYTHON_EXECUTABLE} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py + --arch=${ARCH} --artwork=${ARTWORK_DIR} --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} @@ -1933,7 +1943,6 @@ if (LINUX) --configuration=${CMAKE_CFG_INTDIR} --dest=${CMAKE_CURRENT_BINARY_DIR}/packaged --grid=${GRID} - --installer_name=${product} --source=${CMAKE_CURRENT_SOURCE_DIR} --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched DEPENDS @@ -2011,6 +2020,7 @@ if (DARWIN) ARGS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py --actions=copy + --arch=${ARCH} --artwork=${ARTWORK_DIR} --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} @@ -2043,6 +2053,7 @@ if (DARWIN) COMMAND ${PYTHON_EXECUTABLE} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py + --arch=${ARCH} --artwork=${ARTWORK_DIR} --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index cff2619cfb..aaf18d2948 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.6.9 +3.7.5 diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index 4659673333..60c942094a 100755 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -216,6 +216,16 @@ is_running_function="Floater.IsOpen" is_running_parameters="snapshot" /> + <command name="social" + available_in_toybox="true" + icon="Command_Social_Icon" + label_ref="Command_Social_Label" + tooltip_ref="Command_Social_Tooltip" + execute_function="Floater.ToggleOrBringToFront" + execute_parameters="social" + is_running_function="Floater.IsOpen" + is_running_parameters="social" + /> <command name="speak" available_in_toybox="true" icon="Command_Speak_Icon" diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 0e9266dad4..d39bf6c3c2 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1203,7 +1203,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>0</integer> + <integer>1</integer> </map> <key>BulkChangeShareWithGroup</key> <map> @@ -3569,13 +3569,13 @@ <key>FPSLogFrequency</key> <map> <key>Comment</key> - <string>Seconds between display of FPS in log (0 for never)</string> + <string>Seconds between display of FPS in log (0 for never)</string> <key>Persist</key> - <integer>1</integer> + <integer>1</integer> <key>Type</key> - <string>F32</string> + <string>F32</string> <key>Value</key> - <real>10.0</real> + <real>10.0</real> </map> <key>FilterItemsMaxTimePerFrameVisible</key> <map> @@ -4941,6 +4941,16 @@ <key>Value</key> <array /> </map> + <key>LeapPlaybackEventsCommand</key> + <map> + <key>Comment</key> + <string>Command line to use leap to launch playback of event recordings</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>LLSD</string> + <key>Value</key> + </map> <key>LSLFindCaseInsensitivity</key> <map> <key>Comment</key> @@ -5932,6 +5942,17 @@ <key>Value</key> <real>1.6</real> </map> + <key>MaxPersistentNotifications</key> + <map> + <key>Comment</key> + <string>Maximum amount of persistent notifications</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <real>250</real> + </map> <key>MaxSelectDistance</key> <map> <key>Comment</key> @@ -8675,7 +8696,7 @@ <key>RenderDepthOfField</key> <map> <key>Comment</key> - <string>Whether to use depth of field effect when lighting and shadows are enabled</string> + <string>Whether to use depth of field effect when Advanced Lighting Model is enabled</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -9840,7 +9861,7 @@ <key>RenderUseVAO</key> <map> <key>Comment</key> - <string>[EXPERIMENTAL] Use GL Vertex Array Objects</string> + <string>[EXPERIMENTAL] Use GL Vertex Array Objects.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> @@ -9970,7 +9991,18 @@ <key>Value</key> <integer>0</integer> </map> - <key>RevokePermsOnStopAnimation</key> + <key>ReportBugURL</key> + <map> + <key>Comment</key> + <string>URL used for filing bugs from viewer</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>https://jira.secondlife.com/secure/CreateIssueDetails!init.jspa?pid=10610&issuetype=1&environment=[ENVIRONMENT]&customfield_10253=[LOCATION]</string> + </map> + <key>RevokePermsOnStopAnimation</key> <map> <key>Comment</key> <string>Clear animation permssions when choosing "Stop Animating Me"</string> @@ -10476,6 +10508,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>ShowEventRecorderMenuItems</key> + <map> + <key>Comment</key> + <string>Whether or not Event Recorder menu choices - Start / Stop event recording should appear in the (currently) Develop menu</string> + <key>Persist</key> + <integer>0</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>0</integer> + </map> <key>ShowGestureButton</key> <map> <key>Comment</key> @@ -12632,6 +12675,17 @@ <key>Value</key> <string>00000000-0000-0000-0000-000000000000</string> </map> + <key>UISndRestart</key> + <map> + <key>Comment</key> + <string>Sound file for region restarting (uuid for sound asset)</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>b92a0f64-7709-8811-40c5-16afd624a45f</string> + </map> <key>UISndSnapshot</key> <map> <key>Comment</key> @@ -13116,6 +13170,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>SocialPhotoResolution</key> + <map> + <key>Comment</key> + <string>Default resolution when sharing photo using the social floater</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>String</string> + <key>Value</key> + <string>[i800,i600]</string> + </map> <key>sourceid</key> <map> <key>Comment</key> @@ -13334,7 +13399,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>-1</string> + <string>0</string> </map> <key>VivoxDebugSIPURIHostName</key> <map> @@ -14860,17 +14925,6 @@ <key>Value</key> <integer>0</integer> </map> - <key>DisablePrecacheDelayAfterTeleporting</key> - <map> - <key>Comment</key> - <string>Disables the artificial delay in the viewer that precaches some incoming assets</string> - <key>Persist</key> - <integer>0</integer> - <key>Type</key> - <string>Boolean</string> - <key>Value</key> - <integer>0</integer> - </map> <key>FMODExProfilerEnable</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml index 636caf5ef3..500151c935 100755 --- a/indra/newview/app_settings/settings_per_account.xml +++ b/indra/newview/app_settings/settings_per_account.xml @@ -77,6 +77,17 @@ <key>Value</key> <integer>412</integer> </map> + <key>ConversationsParticipantListCollapsed</key> + <map> + <key>Comment</key> + <string>Stores the expanded/collapsed state of Nearby chat participant list</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>Boolean</string> + <key>Value</key> + <integer>true</integer> + </map> <key>InstantMessageLogPath</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl index bc63d07d72..c98e7d1cd3 100755 --- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl @@ -33,8 +33,8 @@ mat4 getSkinnedTransform() mat4 ret; int i = int(floor(weight.x)); float x = fract(weight.x); - - ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1], x); + + ret[0] = mix(matrixPalette[i+0], matrixPalette[i+1], x); ret[1] = mix(matrixPalette[i+15],matrixPalette[i+16], x); ret[2] = mix(matrixPalette[i+30],matrixPalette[i+31], x); ret[3] = vec4(0,0,0,1); diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl index efd0d03965..57129c3bd1 100755 --- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl +++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl @@ -22,27 +22,46 @@ * $/LicenseInfo$ */ - - ATTRIBUTE vec4 weight4; -uniform mat4 matrixPalette[32]; +uniform mat3 matrixPalette[52]; +uniform vec3 translationPalette[52]; mat4 getObjectSkinnedTransform() { - int i; + int i; vec4 w = fract(weight4); vec4 index = floor(weight4); + index = min(index, vec4(51.0)); + index = max(index, vec4( 0.0)); + float scale = 1.0/(w.x+w.y+w.z+w.w); w *= scale; - mat4 mat = matrixPalette[int(index.x)]*w.x; - mat += matrixPalette[int(index.y)]*w.y; - mat += matrixPalette[int(index.z)]*w.z; - mat += matrixPalette[int(index.w)]*w.w; + int i1 = int(index.x); + int i2 = int(index.y); + int i3 = int(index.z); + int i4 = int(index.w); - return mat; + mat3 mat = matrixPalette[i1]*w.x; + mat += matrixPalette[i2]*w.y; + mat += matrixPalette[i3]*w.z; + mat += matrixPalette[i4]*w.w; + + vec3 trans = translationPalette[i1]*w.x; + trans += translationPalette[i2]*w.y; + trans += translationPalette[i3]*w.z; + trans += translationPalette[i4]*w.w; + + mat4 ret; + + ret[0] = vec4(mat[0], 0); + ret[1] = vec4(mat[1], 0); + ret[2] = vec4(mat[2], 0); + ret[3] = vec4(trans, 1.0); + + return ret; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index e5f7366b70..2b5f001873 100755 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -534,6 +534,7 @@ void main() #ifdef FOR_IMPOSTOR vec4 color; color.rgb = diff.rgb; + color.a = 1.0; #ifdef USE_VERTEX_COLOR float final_alpha = diff.a * vertex_color.a; diff --git a/indra/llcommon/llversionviewer.h b/indra/newview/app_settings/shaders/class1/interface/benchmarkF.glsl index 6a5ff314e4..1936e0dcaa 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/newview/app_settings/shaders/class1/interface/benchmarkF.glsl @@ -1,10 +1,9 @@ /** - * @file llversionviewer.h - * @brief + * @file benchmarkF.glsl * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2011, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,18 +23,17 @@ * $/LicenseInfo$ */ -#ifndef LL_LLVERSIONVIEWER_H -#define LL_LLVERSIONVIEWER_H - -const S32 LL_VERSION_MAJOR = 3; -const S32 LL_VERSION_MINOR = 4; -const S32 LL_VERSION_PATCH = 6; -const S32 LL_VERSION_BUILD = 0; +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif -const char * const LL_CHANNEL = "Second Life Developer"; +uniform sampler2D diffuseMap; -#if LL_DARWIN -const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer"; -#endif +VARYING vec2 tc0; -#endif +void main() +{ + frag_color = texture2D(diffuseMap, tc0); +} diff --git a/indra/newview/app_settings/shaders/class1/interface/benchmarkV.glsl b/indra/newview/app_settings/shaders/class1/interface/benchmarkV.glsl new file mode 100644 index 0000000000..7beb20ede4 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/interface/benchmarkV.glsl @@ -0,0 +1,38 @@ +/** + * @file benchmarkV.glsl + * + * $LicenseInfo:firstyear=2007&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +uniform mat4 modelview_projection_matrix; + +ATTRIBUTE vec3 position; + +VARYING vec2 tc0; + +void main() +{ + gl_Position = vec4(position, 1.0); + + tc0 = (position.xy*0.5+0.5); +} + diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl index 67dc500493..da02534dbb 100755 --- a/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl @@ -31,12 +31,13 @@ out vec4 frag_color; uniform sampler2D tex0; -VARYING vec4 vertex_color; +uniform vec4 color; + VARYING vec2 vary_texcoord0; void main() { - float alpha = texture2D(tex0, vary_texcoord0.xy).a * vertex_color.a; + float alpha = texture2D(tex0, vary_texcoord0.xy).a * color.a; - frag_color = vec4(vertex_color.rgb, alpha); + frag_color = vec4(color.rgb, alpha); } diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl index c58f9dfdaf..f33115d78d 100755 --- a/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl @@ -26,16 +26,13 @@ uniform mat4 modelview_projection_matrix; ATTRIBUTE vec3 position; -ATTRIBUTE vec4 diffuse_color; ATTRIBUTE vec2 texcoord0; -VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; void main() { gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - vertex_color = diffuse_color; vary_texcoord0 = texcoord0; } diff --git a/indra/newview/app_settings/toolbars.xml b/indra/newview/app_settings/toolbars.xml index 29c019719d..86f9912815 100755 --- a/indra/newview/app_settings/toolbars.xml +++ b/indra/newview/app_settings/toolbars.xml @@ -6,6 +6,7 @@ <command name="speak"/> <command name="destinations"/> <command name="people"/> + <command name="social"/> <command name="profile"/> <command name="move"/> <command name="view"/> diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml index e5b385f4aa..5268498d56 100755 --- a/indra/newview/character/avatar_lad.xml +++ b/indra/newview/character/avatar_lad.xml @@ -3825,7 +3825,11 @@ <volume_morph name="BELLY" scale="0.075 0.04 0.03" - pos="0.07 0 -0.07"/> + pos="0.07 0 -0.02"/> + <volume_morph + name="PELVIS" + scale="0.075 0.04 0.03" + pos="0.07 0 -0.02"/> </param_morph> </param> @@ -3844,7 +3848,16 @@ camera_elevation=".1" camera_distance="1" camera_angle="15"> - <param_morph /> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0273 0.0273 0.0273" + pos="0.038 0.024 -0.016"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0273 0.0273 0.0273" + pos="0.038 -0.024 -0.016"/> + </param_morph> </param> <param @@ -3861,7 +3874,16 @@ value_max="1" camera_elevation="0" camera_distance=".28"> - <param_morph /> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="-0.05 0.0 0.0" + pos="-0.01 -0.01 -0.02"/> + <volume_morph + name="RIGHT_PEC" + scale="-0.05 0.0 0.0" + pos="-0.01 -0.01 -0.02"/> + </param_morph> </param> <param @@ -3878,7 +3900,16 @@ value_max="1" camera_elevation="0" camera_distance=".28"> - <param_morph /> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="-0.051 0.0 0.0" + pos="-0.02 -0.01 -0.03"/> + <volume_morph + name="RIGHT_PEC" + scale="-0.051 0.0 0.0" + pos="-0.02 -0.01 -0.03"/> + </param_morph> </param> <param @@ -3944,6 +3975,10 @@ scale="0.0 -0.01 0.0" pos="0.0 0.0 0"/> <volume_morph + name="UPPER_BACK" + scale="-0.01 -0.01 0.0" + pos="0.0 0.0 0"/> + <volume_morph name="CHEST" scale="-0.01 -0.01 0.0" pos="0.01 0.0 0"/> @@ -3994,6 +4029,10 @@ scale="-0.01 -0.01 0.0" pos="0.01 0.0 0"/> <volume_morph + name="UPPER_BACK" + scale="-0.01 -0.01 0.0" + pos="0.0 0.0 0"/> + <volume_morph name="CHEST" scale="-0.02 -0.02 0.0" pos="0.01 0.0 0"/> @@ -4042,6 +4081,32 @@ scale="0.02 0.03 0.03" pos="0 0 -0.03"/> <volume_morph + name="PELVIS" + scale="0.02 0.03 0.03" + pos="0 0 -0.03"/> + <volume_morph + name="UPPER_BACK" + scale="0.01 0.03 0.0" + pos="-0.03 0 0"/> + <volume_morph + name="LOWER_BACK" + scale="0.04 0.06 0.0" + pos="-0.06 0 0"/> + <volume_morph + name="LEFT_HANDLE" + pos="0.0 0.08 0.0"/> + <volume_morph + name="RIGHT_HANDLE" + pos="0.0 -0.08 0.0"/> + <volume_morph + name="LEFT_PEC" + scale="0.0367 0.0367 0.016" + pos="0.00 -0.005 -0.013"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0367 0.0367 0.016" + pos="0.00 0.005 -0.013"/> + <volume_morph name="BELLY" scale="0.09 0.08 0.07" pos="0 0 -0.05"/> @@ -4093,7 +4158,16 @@ value_max="2" camera_elevation=".3" camera_distance=".8"> - <param_morph /> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.004 0.0 -0.01"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.004 0.0 -0.01"/> + </param_morph> </param> <param @@ -4143,6 +4217,15 @@ <volume_morph name="BELLY" scale="0.0 0.02 0.0"/> + <volume_morph + name="LOWER_BACK" + scale="0.0 0.02 0.0"/> + <volume_morph + name="LEFT_HANDLE" + pos="0.0 0.025 0.0"/> + <volume_morph + name="RIGHT_HANDLE" + pos="0.0 -0.025 0.0"/> </param_morph> </param> @@ -4162,7 +4245,16 @@ value_max="1.3" camera_elevation=".3" camera_distance=".8"> - <param_morph /> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 -0.026 0.0"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.026 0.0"/> + </param_morph> </param> <param @@ -4177,11 +4269,20 @@ label_min="Big Pectorals" label_max="Sunken Chest" value_default="0" - value_min="-.5" + value_min="-1.0" value_max="1.1" camera_elevation=".3" camera_distance="1.2"> - <param_morph /> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="-0.03 -0.024 -0.01"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="-0.03 0.024 -0.01"/> + </param_morph> </param> <!-- ############# # @@ -4206,6 +4307,14 @@ scale="0.03 0.03 0.0" pos="-0.03 0 0.02"/> <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.008 -0.03 0.01"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.008 0.03 0.01"/> + <volume_morph name="L_CLAVICLE" scale="0.02 0.0 0.01" pos="-0.02 0 0"/> @@ -4376,7 +4485,16 @@ value_default="0" value_min="-3" value_max="3"> - <param_morph /> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.0 -0.01"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.0 -0.01"/> + </param_morph> </param> <param @@ -4389,7 +4507,16 @@ value_default="0" value_min="-1.25" value_max="1.25"> - <param_morph /> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 -0.026 0.0"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.026 -0.0"/> + </param_morph> </param> <param @@ -4402,7 +4529,12 @@ value_default="0" value_min="-1" value_max="1"> - <param_morph /> + <param_morph> + <volume_morph + name="BELLY" + scale="0.0 0.0 0.0" + pos="0.0 0.0 0.05"/> + </param_morph> </param> <param @@ -4415,7 +4547,16 @@ value_default="0" value_min="-2" value_max="2"> - <param_morph /> + <param_morph> + <volume_morph + name="LEFT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.03 0.0"/> + <volume_morph + name="RIGHT_PEC" + scale="0.0 0.0 0.0" + pos="0.0 0.03 0.0"/> + </param_morph> </param> <!-- @@ -4518,6 +4659,10 @@ name="PELVIS" scale="-0.01 0.0 0.0" pos="0.01 0 0.0"/> + <volume_morph + name="BUTT" + scale="0.0 0.0886 0.0" + pos="0.03 0 0.0"/> </param_morph> </param> @@ -4949,7 +5094,11 @@ value_default="0" value_min="-1" value_max="1"> - <param_morph /> + <param_morph> + <volume_morph + name="BUTT" + pos="0.0 0.0 0.05"/> + </param_morph> </param> <param @@ -4962,7 +5111,11 @@ value_default="0" value_min="-1" value_max="1"> - <param_morph /> + <param_morph> + <volume_morph + name="BUTT" + pos="0.0 0.05 0.0"/> + </param_morph> </param> <!-- diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml index 5e73804f2d..6b07bbc1d3 100755 --- a/indra/newview/character/avatar_skeleton.xml +++ b/indra/newview/character/avatar_skeleton.xml @@ -1,11 +1,18 @@ <?xml version="1.0" encoding="US-ASCII" standalone="yes"?> -<linden_skeleton version="1.0" num_bones="46" num_collision_volumes="19"> +<linden_skeleton version="1.0" num_bones="53" num_collision_volumes="26"> <bone name="mPelvis" pos="0.000 0.000 1.067" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 1.067015"> <collision_volume name="PELVIS" pos = "-0.01 0 -0.02" rot="0.000000 8.00000 0.000000" scale="0.12 0.16 0.17"/> + <collision_volume name="BUTT" pos = "-0.06 0 -0.1" rot="0.000000 0.00000 0.000000" scale="0.1 0.1 0.1"/> <bone name="mTorso" pos="0.000 0.000 0.084" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 0.000000 0.084073"> <collision_volume name="BELLY" pos = "0.028 0 0.04" rot="0.000000 8.00000 0.000000" scale="0.09 0.13 0.15"/> + <collision_volume name="LOWER_BACK" pos = "0.0 0.0 0.023" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15"/> + <collision_volume name="LEFT_HANDLE" pos = "0.0 0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/> + <collision_volume name="RIGHT_HANDLE" pos = "0.0 -0.10 0.058" rot="0.000000 0.00000 0.000000" scale="0.05 0.05 0.05"/> <bone name="mChest" pos="-0.015 0.000 0.205" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.015368 0.000000 0.204877"> <collision_volume name="CHEST" pos = "0.028 0 0.07" rot="0.000000 -10.00000 0.000000" scale="0.11 0.15 0.2"/> + <collision_volume name="UPPER_BACK" pos = "0.0 0.0 0.017" rot="0.000000 0.00000 0.000000" scale="0.09 0.13 0.15"/> + <collision_volume name="LEFT_PEC" pos = "0.119 0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05"/> + <collision_volume name="RIGHT_PEC" pos = "0.119 -0.082 0.042" rot="0.000000 4.29000 0.000000" scale="0.05 0.05 0.05"/> <bone name="mNeck" pos="-0.010 0.000 0.251" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="-0.009507 0.000000 0.251108"> <collision_volume name="NECK" pos = "0.0 0 0.02" rot="0.000000 0.000000 0.000000" scale="0.05 0.06 0.08"/> <bone name="mHead" pos="0.000 -0.000 0.076" rot="0.000000 0.000000 0.000000" scale="1.000 1.000 1.000" pivot="0.000000 -0.000000 0.075630"> diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 0bdd425504..a2d68eb550 100755 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 35 +version 36 // The version number above should be implemented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -628,3 +628,6 @@ Disregard128DefaultDrawDistance 1 0 list NVIDIA_GeForce_Go_7400 Disregard128DefaultDrawDistance 1 0 +list OSX_10_6_8 +RenderDeferred 0 0 + diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt index 23a065caff..8efc4ee87d 100755 --- a/indra/newview/gpu_table.txt +++ b/indra/newview/gpu_table.txt @@ -22,11 +22,11 @@ // // Class Numbers: // 0 - Defaults to low graphics settings. No shaders on by default -// 1 - Defaults to mid graphics settings. Basic shaders on by default -// 2 - Defaults to high graphics settings. Atmospherics on by default. -// 3 - Same as 2, but with lighting and shadows enabled. -// 4 - Same as 3, but with ambient occlusion enabled. -// 5 - Same as 4, but with shadows set to "Sun/Moon+Projectors." +// 1 - Defaults to low-mid graphics settings. Basic shaders on by default +// 2 - Defaults to mid graphics settings. Atmospherics on by default +// 3 - Defaults to mid-high graphics settings. Advanced Lighting Model on by default +// 4 - Defaults to high graphics settings. Ambient Occlusion on by default +// 5 - Defaults to high-ultra graphics settings. Shadows set to "Sun/Moon+Projectors." // // Supported Number: // 0 - We claim to not support this card. @@ -35,7 +35,9 @@ 3Dfx .*3Dfx.* 0 0 0 0 3Dlabs .*3Dlabs.* 0 0 0 0 +Hijacker .*Mohr.*Hijacker.* 0 0 0 0 ATI 3D-Analyze .*ATI.*3D-Analyze.* 0 0 0 0 +ATI ARES .*ATI.*ARES.* 0 0 0 0 ATI All-in-Wonder 7500 .*ATI.*All-in-Wonder 75.* 0 1 0 0 ATI All-in-Wonder 8500 .*ATI.*All-in-Wonder 85.* 0 1 0 0 ATI All-in-Wonder 9200 .*ATI.*All-in-Wonder 92.* 0 1 0 0 @@ -47,15 +49,14 @@ ATI All-in-Wonder X1800 .*ATI.*All-in-Wonder X18.* 3 1 0 0 ATI All-in-Wonder X1900 .*ATI.*All-in-Wonder X19.* 3 1 0 0 ATI All-in-Wonder PCI-E .*ATI.*All-in-Wonder.*PCI-E.* 1 1 0 0 ATI All-in-Wonder Radeon .*ATI.*All-in-Wonder Radeon.* 0 1 0 0 -ATI Radeon X1300 .*ATI.*(ASUS|Radeon).*X13.* 2 1 1 2.1 -ATI Radeon X1500 .*ATI.*(ASUS|Radeon).*X15.* 2 1 1 2.1 -ATI Radeon X1600 .*ATI.*(ASUS|Radeon).*X16.* 2 1 1 2.1 -ATI Radeon X1700 .*ATI.*(ASUS|Radeon).*X17.* 2 1 1 2.1 -ATI Radeon X1800 .*ATI.*(Radeon|Diamond) X18.* ?.* 3 1 1 2.1 -ATI Radeon X1900 .*ATI.*(Radeon|Diamond|ASUS) X19.* ?.* 2 1 1 2.1 -ATI Radeon X17xx .*ATI.*(Radeon|Diamond) X17.* ?.* 1 1 1 2.1 -ATI Radeon X16xx .*ATI.*(Radeon|Diamond) X17.* ?.* 1 1 1 2.1 -ATI Radeon X28xx .*ATI.*(Radeon|Diamond) X28.. ?.* 1 1 1 2.1 +ATI Radeon X1300 .*ATI.*(Radeon|Diamond|ASUS) *X13.* ?.* 2 1 1 2.1 +ATI Radeon X1400 .*ATI.*(Radeon|Diamond|ASUS) *X14.* ?.* 2 1 1 2.1 +ATI Radeon X1500 .*ATI.*(Radeon|Diamond|ASUS) *X15.* ?.* 2 1 1 2.1 +ATI Radeon X1600 .*ATI.*(Radeon|Diamond|ASUS) *X16.* ?.* 2 1 1 2.1 +ATI Radeon X1700 .*ATI.*(Radeon|Diamond|ASUS) *X17.* ?.* 2 1 1 2.1 +ATI Radeon X1800 .*ATI.*(Radeon|Diamond|ASUS) *X18.* ?.* 3 1 1 2.1 +ATI Radeon X1900 .*ATI.*(Radeon|Diamond|ASUS) *X19.* ?.* 2 1 1 2.1 +ATI Radeon X2800 .*ATI.*(Radeon|Diamond|ASUS) *X28.* ?.* 2 1 1 2.1 ATI Display Adapter .*ATI.*display adapter.* 1 1 1 4.1 ATI FireGL 5200 .*ATI.*FireGL V52.* 1 1 1 2.1 ATI FireGL 5xxx .*ATI.*FireGL V5.* 2 1 1 3.3 @@ -74,26 +75,6 @@ ATI M56 .*ATI.*M56.* 1 1 0 0 ATI M71 .*ATI.*M71.* 1 1 0 0 ATI M72 .*ATI.*M72.* 1 1 0 0 ATI M76 .*ATI.*M76.* 3 1 0 0 -ATI Radeon HD 6300M .*ATI.*AMD Radeon.* (HD|HD )63..M 2 1 1 4.2 -ATI Radeon HD 6400M .*ATI.*AMD Radeon.* (HD|HD )64..M 2 1 1 4.2 -ATI Radeon HD 6500M .*ATI.*AMD Radeon.* (HD|HD )65..M 2 1 1 4.2 -ATI Radeon HD 6600M .*ATI.*AMD Radeon.* (HD 6|6)6..M 3 1 1 4.2 -ATI Radeon HD 6700M .*ATI.*AMD Radeon.* (HD|HD )67..M 3 1 1 4.2 -ATI Radeon HD 6800M .*ATI.*AMD Radeon.* (HD|HD )68..M 3 1 1 4.2 -ATI Radeon HD 6300G .*ATI.*AMD Radeon.* (HD|HD )63..G 2 1 1 4.2 -ATI Radeon HD 6400G .*ATI.*AMD Radeon.* (HD|HD )64..G 2 1 1 4.2 -ATI Radeon HD 6500G .*ATI.*AMD Radeon.* (HD|HD )65..G 2 1 1 4.2 -ATI Radeon HD 6600G .*ATI.*AMD Radeon.* (HD|HD )66..G 3 1 1 4.2 -ATI Radeon HD 7100 .*ATI.*(Radeon|ASUS).* (HD|HD )71.* 2 1 0 0 -ATI Radeon HD 7200 .*ATI.*(Radeon|ASUS).* (HD|HD )72.* 2 1 0 4.2 -ATI Radeon HD 7300 .*ATI.*(Radeon|ASUS).* (HD|HD )73.* 2 1 0 4.2 -ATI Radeon HD 7400 .*ATI.*(Radeon|ASUS).* (HD|HD )74.* 2 1 0 4.2 -ATI Radeon HD 7500 .*ATI.*(Radeon|ASUS).* (HD|HD )75.* 3 1 1 4.2 -ATI Radeon HD 7600 .*ATI.*(Radeon|ASUS).* (HD|HD )76.* 3 1 0 4.2 -ATI Radeon HD 7700 .*ATI.*(Radeon|ASUS).* (HD|HD )77.* 4 1 1 4.2 -ATI Radeon HD 7800 .*ATI.*(Radeon|ASUS).* (HD|HD )78.* 5 1 1 4.2 -ATI Radeon HD 7900 .*ATI.*(Radeon|ASUS).* (HD|HD )79.* 5 1 1 4.2 -ATI Radeon HD 7000 Series .*ATI.*(Radeon|ASUS).* (HD|HD )7000 Series.* 3 1 1 4.2 ATI Mobility Radeon 4100 .*ATI.*Mobility.* 41.. 1 1 1 3.3 ATI Mobility Radeon 5000 .*ATI.*Mobility.* 50.. 1 1 1 4.2 ATI Mobility Radeon 7xxx .*ATI.*Mobility.*Radeon 7.* 0 1 1 1.3 @@ -128,42 +109,66 @@ ATI Mobility Radeon HD 5400 .*ATI.*Mobility.*HD 54.* 2 1 1 4.2 ATI Mobility Radeon HD 5500 .*ATI.*Mobility.*HD 55.* 3 1 0 4.2 ATI Mobility Radeon HD 5600 .*ATI.*Mobility.*HD 56.* 3 1 1 4.2 ATI Mobility Radeon HD 5700 .*ATI.*Mobility.*HD 57.* 3 1 1 4.1 -ATI Mobility Radeon HD 6200 .*ATI.*Mobility.*HD 62.* 3 1 0 0 -ATI Mobility Radeon HD 6300 .*ATI.*Mobility.*HD 63.* 3 1 1 4.2 -ATI Mobility Radeon HD 6400M .*ATI.*Mobility.*HD 64.* 3 1 0 0 -ATI Mobility Radeon HD 6500M .*ATI.*Mobility.*HD 65.* 5 1 1 4.2 -ATI Mobility Radeon HD 6600M .*ATI.*Mobility.*HD 66.* 5 1 0 0 -ATI Mobility Radeon HD 6700M .*ATI.*Mobility.*HD 67.* 5 1 0 0 -ATI Mobility Radeon HD 6800M .*ATI.*Mobility.*HD 68.* 5 1 0 0 -ATI Mobility Radeon HD 6900M .*ATI.*Mobility.*HD 69.* 5 1 0 0 -ATI Mobility Radeon Graphics .*ATI Mobility Radeon Graphics.* 1 1 0 4 +ATI Mobility Radeon X1000 .*ATI.*Mobility.*Radeon ?X1..* 2 1 0 2.1 +ATI Mobility Radeon X1200 .*ATI.*Mobility.*Radeon ?X12.* 2 1 0 2.1 +ATI Mobility Radeon X2000 .*ATI.*Mobility.*Radeon ?X20.* 2 1 0 2.1 +ATI Mobility Radeon X2300 .*ATI.*Mobility.*Radeon ?X23.* 2 1 0 2.1 +ATI Mobility Radeon X2500 .*ATI.*Mobility.*Radeon ?X25.* 2 1 0 2.1 +ATI Mobility Radeon XX000 .*ATI.*Mobility.*Radeon ?Xx.* 2 1 0 2.1 +ATI Radeon HD 5xx .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)5x. 1 1 1 4 +ATI Radeon HD 6200D/G/M .*ATI.*AMD Radeon.* (HD|HD )62..[DGM].* 3 1 0 4.2 +ATI Radeon HD 6300D/G/M .*ATI.*AMD Radeon.* (HD|HD )63..[DGM].* 3 1 1 4.2 +ATI Radeon HD 6400D/G/M .*ATI.*AMD Radeon.* (HD|HD )64..[DGM].* 3 1 0 4.2 +ATI Radeon HD 6500D/G/M .*ATI.*AMD Radeon.* (HD|HD )65..[DGM].* 4 1 1 4.2 +ATI Radeon HD 6600D/G/M .*ATI.*AMD Radeon.* (HD|HD )66..[DGM].* 4 1 0 4.2 +ATI Radeon HD 6700D/G/M .*ATI.*AMD Radeon.* (HD|HD )67..[DGM].* 4 1 0 4.2 +ATI Radeon HD 6800D/G/M .*ATI.*AMD Radeon.* (HD|HD )68..[DGM].* 4 1 0 4.2 +ATI Radeon HD 6900D/G/M .*ATI.*AMD Radeon.* (HD|HD )69..[DGM].* 4 1 0 4.2 +ATI Radeon HD 7200D/G/M .*ATI.*AMD Radeon.* (HD|HD )72..[DGM].* 3 1 0 4.2 +ATI Radeon HD 7300D/G/M .*ATI.*AMD Radeon.* (HD|HD )73..[DGM].* 3 1 0 4.2 +ATI Radeon HD 7400D/G/M .*ATI.*AMD Radeon.* (HD|HD )74..[DGM].* 3 1 0 4.2 +ATI Radeon HD 7500D/G/M .*ATI.*AMD Radeon.* (HD|HD )75..[DGM].* 4 1 0 4.2 +ATI Radeon HD 7600D/G/M .*ATI.*AMD Radeon.* (HD|HD )76..[DGM].* 4 1 0 4.2 +ATI Radeon HD 7700D/G/M .*ATI.*AMD Radeon.* (HD|HD )77..[DGM].* 4 1 0 4.2 +ATI Radeon HD 7800D/G/M .*ATI.*AMD Radeon.* (HD|HD )78..[DGM].* 4 1 0 4.2 +ATI Radeon HD 7900D/G/M .*ATI.*AMD Radeon.* (HD|HD )79..[DGM].* 4 1 0 4.2 +ATI Radeon HD 8200D/G/M .*ATI.*AMD Radeon.* (HD|HD )82..[DGM].* 3 1 0 4.2 +ATI Radeon HD 8300D/G/M .*ATI.*AMD Radeon.* (HD|HD )83..[DGM].* 3 1 0 4.2 +ATI Radeon HD 8400D/G/M .*ATI.*AMD Radeon.* (HD|HD )84..[DGM].* 4 1 0 4.2 +ATI Radeon HD 8500D/G/M .*ATI.*AMD Radeon.* (HD|HD )85..[DGM].* 4 1 0 4.2 +ATI Radeon HD 8600D/G/M .*ATI.*AMD Radeon.* (HD|HD )86..[DGM].* 4 1 0 4.2 +ATI Radeon HD 8700D/G/M .*ATI.*AMD Radeon.* (HD|HD )87..[DGM].* 4 1 0 4.2 +ATI Radeon HD 8800D/G/M .*ATI.*AMD Radeon.* (HD|HD )88..[DGM].* 4 1 0 4.2 +ATI Radeon HD 8900D/G/M .*ATI.*AMD Radeon.* (HD|HD )89..[DGM].* 4 1 0 4.2 ATI Radeon HD 2300 .*ATI.*Radeon.* (HD|HD )23.. 0 1 1 3.3 -ATI Radeon HD 2400 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)24.. 1 1 1 4 -ATI Radeon HD 2600 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)26.. 2 1 1 4 +ATI Radeon HD 2400 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)24.. 1 1 1 4 +ATI Radeon HD 2600 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)26.. 2 1 1 4 ATI Radeon HD 2900 .*ATI.*Radeon.* (HD|HD )29.. 3 1 1 3.3 ATI Radeon HD 3000 .*ATI.*Radeon.* (HD|HD )30.. 0 1 0 0 ATI Radeon HD 3100 .*ATI.*Radeon.* (HD|HD )31.. 1 1 0 0 ATI Radeon HD 3200 .*ATI.*Radeon.* (HD|HD )32.. 1 1 1 4 ATI Radeon HD 3300 .*ATI.*Radeon.* (HD|HD )33.. 1 1 1 3.3 -ATI Radeon HD 3400 .*ATI.*(Radeon|ASUS).* (HD|HD |AH|EAH)34.. 1 1 1 4 +ATI Radeon HD 3400 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |AH||AX|EAH)34.. 1 1 1 4 ATI Radeon HD 3500 .*ATI.*Radeon.* (HD|HD )35.. 2 1 0 0 -ATI Radeon HD 3600 .*ATI.*(Radeon|ASUS).* (HD|HD |AH|EAH)36.. 3 1 1 4 +ATI Radeon HD 3600 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |AH||AX|EAH)36.. 3 1 1 4 ATI Radeon HD 3700 .*ATI.*Radeon.* (HD|HD )37.. 3 1 0 3.3 ATI HD3700 .*ATI.* HD37.. 3 1 0 3.3 -ATI Radeon HD 3800 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)38.. 3 1 1 4 +ATI Radeon HD 3800 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH|AX|)38.. 3 1 1 4 ATI Radeon HD 4100 .*ATI.*Radeon.* (HD|HD )41.. 1 1 0 0 ATI Radeon HD 4200 .*ATI.*Radeon.* (HD|HD )42.. 1 1 1 4 -ATI Radeon HD 4300 .*ATI.*(Radeon|ASUS).* (HD4|HD 4|EAH4|4)3.. 2 1 1 4 +ATI Radeon HD 4300 .*ATI.*(Radeon|ASUS).* (AH|AX|HD4|HD 4|EAH4|4)3.. 2 1 1 4 ATI Radeon HD 4400 .*ATI.*Radeon.* (HD|HD )44.. 2 1 0 0 -ATI Radeon HD 4500 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)45.. 2 1 1 3.3 -ATI Radeon HD 4600 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)46.. 3 1 1 4 -ATI Radeon HD 4700 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)47.. 3 1 1 3.3 -ATI Radeon HD 4800 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)48.. 3 1 1 4 -ATI Radeon HD 5400 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)54.. 3 1 1 4.2 -ATI Radeon HD 5500 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)55.. 3 1 1 4.2 -ATI Radeon HD 5600 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)56.. 3 1 1 4.2 -ATI Radeon HD 5700 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)57.. 3 1 1 4.2 -ATI Radeon HD 5800 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)58.. 4 1 1 4.2 +ATI Radeon HD 4500 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)45.. 2 1 1 3.3 +ATI RADEON E4690 .*ATI.*RADEON.* E46.. 3 1 1 4 +ATI Radeon HD 4600 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)46.. 3 1 1 4 +ATI Radeon HD 4700 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)47.. 3 1 1 3.3 +ATI Radeon HD 4800 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)48.. 3 1 1 4 +ATI Radeon HD 5000 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)50.. 3 1 1 4.2 +ATI Radeon HD 5400 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)54.. 3 1 1 4.2 +ATI Radeon HD 5500 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)55.. 3 1 1 4.2 +ATI Radeon HD 5600 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)56.. 3 1 1 4.2 +ATI Radeon HD 5700 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)57.. 3 1 1 4.2 +ATI Radeon HD 5800 .*ATI.*(Radeon|ASUS).* (AH|AX|HD|HD |EAH)58.. 4 1 1 4.2 ATI Radeon HD 5900 .*ATI.*Radeon.* (HD|HD )59.. 4 1 1 4.2 ATI Radeon HD 6200 .*ATI.*Radeon.* (HD|HD )62.. 0 1 1 4.2 ATI Radeon HD 6300 .*ATI.*Radeon.* (HD|HD )63.. 1 1 1 4.2 @@ -173,11 +178,31 @@ ATI Radeon HD 6600 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)66.. 3 1 1 4.2 ATI Radeon HD 6700 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)67.. 3 1 1 4.2 ATI Radeon HD 6800 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)68.. 4 1 1 4.2 ATI Radeon HD 6900 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)69.. 5 1 1 4.2 +ATI Radeon HD 6x00 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)6x.. 5 1 1 4.2 +ATI Radeon HD 7100 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)71.* 2 1 0 0 +ATI Radeon HD 7200 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)72.* 2 1 0 4.2 +ATI Radeon HD 7300 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)73.* 2 1 0 4.2 +ATI Radeon HD 7400 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)74.* 2 1 0 4.2 +ATI Radeon HD 7500 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)75.* 3 1 1 4.2 +ATI Radeon HD 7600 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)76.* 3 1 0 4.2 +ATI Radeon HD 7700 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)77.* 4 1 1 4.2 +ATI Radeon HD 7800 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)78.* 5 1 1 4.2 +ATI Radeon HD 7900 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)79.* 5 1 1 4.2 +ATI Radeon HD 7000 Series .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)7000 Series.* 3 1 1 4.2 +ATI Radeon HD 8200 .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)82.* 2 1 0 4.2 +ATI Radeon HD 8300 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)83.* 2 1 0 4.2 +ATI Radeon HD 8400 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)84.* 2 1 0 4.2 +ATI Radeon HD 8500 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)85.* 3 1 1 4.2 +ATI Radeon HD 8600 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)86.* 3 1 0 4.2 +ATI Radeon HD 8700 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)87.* 4 1 1 4.2 +ATI Radeon HD 8800 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)88.* 5 1 1 4.2 +ATI Radeon HD 8900 (OEM) .*ATI.*(Radeon|ASUS).* (HD|HD |EAH)89.* 5 1 1 4.2 ATI Radeon OpenGL .*ATI.*Radeon OpenGL.* 0 0 0 0 ATI Radeon 2100 .*ATI.*Radeon 21.. 0 1 1 2.1 ATI Radeon 3000 .*ATI.*Radeon 30.. 1 1 1 4 ATI Radeon 3100 .*ATI.*Radeon 31.. 0 1 1 3.3 ATI Radeon 5xxx .*ATI.*Radeon 5... 3 1 0 0 +ATI Radeon 6xxx .*ATI.*Radeon 6... 0 1 0 0 ATI Radeon 7xxx .*ATI.*Radeon 7... 0 1 1 2 ATI Radeon 8xxx .*ATI.*Radeon 8... 0 1 0 0 ATI Radeon 9000 .*ATI.*Radeon 90.. 0 1 1 1.3 @@ -187,6 +212,8 @@ ATI Radeon 9500 .*ATI.*Radeon 95.. 0 1 1 2.1 ATI Radeon 9600 .*ATI.*Radeon 96.. 0 1 1 2.1 ATI Radeon 9700 .*ATI.*Radeon 97.. 1 1 0 0 ATI Radeon 9800 .*ATI.*Radeon 98.. 1 1 1 2.1 +ATI Radeon R7 .*ATI.*(Radeon|ASUS).* R7.* 4 1 0 4.2 +ATI Radeon R9 .*ATI.*(Radeon|ASUS).* R9.* 5 1 0 4.2 ATI Radeon RV250 .*ATI.*RV250.* 0 1 0 0 ATI Radeon RV600 .*ATI.*RV6.* 1 1 0 0 ATI Radeon RX700 .*ATI.*RX70.* 1 1 0 0 @@ -195,6 +222,7 @@ ATI RS880M .*ATI.*RS880M 1 1 0 0 ATI Radeon RX9550 .*ATI.*RX9550.* 1 1 0 0 ATI Radeon VE .*ATI.*Radeon.*VE.* 0 0 0 0 ATI Radeon X300 .*ATI.*Radeon X3.* 1 1 1 2.1 +ATI RADEON X300SE .*ATI.*RADEON[ ]*X300SE* 1 1 1 2.1 ATI Radeon X400 .*ATI.*Radeon ?X4.* 0 1 0 0 ATI Radeon X500 .*ATI.*Radeon ?X5.* 1 1 1 2.1 ATI Radeon X600 .*ATI.*(Radeon |ASUS Extreme A)X6.* 1 1 1 2.1 @@ -202,10 +230,14 @@ ATI Radeon X700 .*ATI.*Radeon ?X7.* 2 1 1 2.1 ATI Radeon X800 .*ATI.*Radeon ?X8.* 1 1 1 2.1 ATI Radeon X900 .*ATI.*Radeon ?X9.* 2 1 0 0 ATI Radeon X1000 .*ATI.*Radeon ?X10.* 2 1 0 2.1 +ATI Radeon X1100 .*ATI.*Radeon ?X11.* 2 1 0 2.1 ATI Radeon X1200 .*ATI.*Radeon ?X12.* 2 1 0 2.1 -ATI Radeon X1400 .*ATI.*Radeon ?X14.* 2 1 0 2.1 +ATI Radeon X1xxx .*ATI.*Radeon ?X1xx.* 2 1 0 2.1 +ATI Radeon X12xx .*ATI.*Radeon ?X12x.* 2 1 0 2.1 +ATI Radeon X2xxx .*ATI.*Radeon ?X2x.* 2 1 0 2.1 ATI Radeon X2300 .*ATI.*Radeon ?X23.* 2 1 0 2.1 ATI Radeon Xpress .*ATI.*Radeon Xpress.* 0 1 1 2.1 +ATI Radeon .*ATI.*Radeon$ 3 1 0 0 ATI Rage 128 .*ATI.*Rage 128.* 0 1 0 0 ATI R300 (9700) .*R300.* 0 1 1 2.1 ATI R350 (9800) .*R350.* 1 1 0 0 @@ -224,7 +256,9 @@ ATI RX480 (Xpress 200P) .*RX480.* 0 1 0 0 ATI RX700 .*RX700.* 1 1 0 0 AMD ANTILLES (HD 6990) .*(AMD|ATI).*Antilles.* 3 1 0 0 ATI ROBSON .*(AMD|ATI).*ROBSON.* 3 1 0 4 +AMD ARUBA (HD 6800) .*(AMD|ATI).*ARUBA.* 3 1 1 2.1 AMD BARTS (HD 6800) .*(AMD|ATI).*Barts.* 3 1 1 2.1 +AMD BA (HD 6800) .*(AMD|ATI).*BA.* 3 1 1 2.1 AMD WRESTLER .*(AMD|ATI).*WRESTLER.* 3 1 1 4 AMD SUMO .*(AMD|ATI).*SUMO.* 3 1 1 4.1 AMD CAICOS (HD 6400) .*(AMD|ATI).*Caicos.* 3 1 0 0 @@ -236,6 +270,8 @@ AMD JUNIPER (HD 5700) .*(AMD|ATI).*Juniper.* 3 1 0 0 AMD PARK .*(AMD|ATI).*Park.* 3 1 0 0 AMD REDWOOD (HD 5500/5600) .*(AMD|ATI).*Redwood.* 3 1 0 1.4 AMD TURKS (HD 6500/6600) .*(AMD|ATI).*Turks.* 3 1 0 2.1 +AMD PITCAIRN (HD 7870) .*(AMD|ATI).*Pitcairn.* 3 1 0 2.1 +AMD TAHITI (HD 7000) .*(AMD|ATI).*Tahiti.* 3 1 0 2.1 AMD RS780 (HD 3200) .*RS780.* 0 1 1 2.1 AMD RS880 (HD 4200) .*RS880.* 0 1 1 3.2 AMD RV610 (HD 2400) .*RV610.* 1 1 0 0 @@ -253,15 +289,15 @@ AMD RV790 (HD 4800) .*RV790.* 3 1 0 0 ATI 760G/Radeon 3000 .*ATI.*AMD 760G.* 1 1 1 3.3 ATI 780L/Radeon 3000 .*ATI.*AMD 780L.* 1 1 0 0 ATI Radeon DDR .*ATI.*Radeon ?DDR.* 0 1 0 0 -ATI FirePro 2000 .*ATI.*FirePro 2.* 2 1 1 4.2 -ATI FirePro 3000 .*ATI.*FirePro V3.* 2 1 0 0 -ATI FirePro 4000 .*ATI.*FirePro V4.* 2 1 0 4.1 -ATI FirePro 5000 .*ATI.*FirePro V5.* 3 1 0 0 -ATI FirePro 7000 .*ATI.*FirePro V7.* 3 1 0 0 +ATI FirePro 2000 .*ATI.*FirePro [V]*2.* 2 1 1 4.2 +ATI FirePro 3000 .*ATI.*FirePro [V]*3.* 2 1 0 0 +ATI FirePro 4000 .*ATI.*FirePro [V]*4.* 2 1 0 4.1 +ATI FirePro 5000 .*ATI.*FirePro [V]*5.* 3 1 0 0 +ATI FirePro 7000 .*ATI.*FirePro [V]*7.* 3 1 0 0 ATI FirePro M .*ATI.*FirePro M.* 3 1 1 4.2 -ATI R300 (9700) .*R300.* 0 1 1 2.1 Intel X3100 .*Intel.*X3100.* 1 1 1 2.1 Intel GMA 3600 .*Intel.* 3600.* 0 1 1 3 +Intel Royal BNA .*Intel.*Royal[ ]*BNA.* 0 0 0 0 Intel 830M .*Intel.*830M 0 0 0 0 Intel 845G .*Intel.*845G 0 0 1 1.4 Intel 855GM .*Intel.*855GM 0 0 1 1.4 @@ -282,11 +318,20 @@ Intel Brookdale .*Intel.*Brookdale.* 0 0 1 1.3 Intel Cantiga .*Intel.*Cantiga.* 0 0 1 2 Intel Eaglelake .*Intel.*Eaglelake.* 1 1 1 2 Intel Graphics Media HD .*Intel.*Graphics Media.*HD.* 1 1 1 2.1 -Intel HD Graphics 2000 .*Intel.*HD Graphics 2.* 2 1 0 4 +Intel HD Graphics 2500 .*Intel.*HD Graphics 25.* 2 1 0 4.2 +Intel HD Graphics 2000 .*Intel.*HD Graphics 2.* 2 1 0 3.1 Intel HD Graphics 3000 .*Intel.*HD Graphics 3.* 3 1 1 3.1 -Intel HD Graphics 4000 .*Intel.*HD Graphics 4.* 3 1 1 4 +Intel HD Graphics 4200 .*Intel.*HD Graphics 42.* 3 1 0 4.2 +Intel HD Graphics 4400 .*Intel.*HD Graphics 44.* 3 1 0 4.2 +Intel HD Graphics 4600 .*Intel.*HD Graphics 46.* 3 1 0 4.2 +Intel HD Graphics 4000 .*Intel.*HD Graphics 4.* 3 1 1 4.2 +Intel Intel Iris Pro Graphics 5200 .*Intel.*Iris Pro Graphics 52.* 4 1 0 4 +Intel Intel Iris Graphics 5100 .*Intel.*Iris Graphics 51.* 4 1 0 4 +Intel Intel Iris OpenGL Engine .*Intel.*Iris (Pro )*OpenGL.* 4 1 0 4 +Intel HD Graphics 5000 .*Intel.*HD Graphics 5.* 4 1 0 4 Intel HD Graphics .*Intel.*HD Graphics.* 2 1 1 4 Intel Mobile 4 Series .*Intel.*Mobile.* 4 Series.* 0 1 1 2.1 +Intel Mobile 45 Express .*Intel.*Mobile.* 45 Express Chipset.* 0 1 0 2.1 Intel 4 Series Internal .*Intel.* 4 Series Internal.* 1 1 1 2.1 Intel Media Graphics HD .*Intel.*Media Graphics HD.* 0 1 0 0 Intel Montara .*Intel.*Montara.* 0 0 1 1.3 @@ -299,116 +344,197 @@ Intel 3D-Analyze .*Intel.*3D-Analyze.* 2 1 0 0 Matrox .*Matrox.* 0 0 0 0 Mesa .*Mesa.* 1 0 1 3 Gallium .*Gallium.* 1 1 1 2.1 -NVIDIA G100M .*NVIDIA .* 10[0-9]M.* 4 1 1 3.3 -NVIDIA G 110M .*NVIDIA .* 11[0-9]M.* 1 1 1 3.3 -NVIDIA G 120M .*NVIDIA .* 12[0-9]M.* 1 1 1 3.3 -NVIDIA G 200M .*NVIDIA .* 20[0-9]M.* 1 1 0 0 -NVIDIA G 410M .*NVIDIA .* 41[0-9]M.* 3 1 1 4.2 -NVIDIA GT 130M .*NVIDIA .*GT 13[0-9]M.* 3 1 1 3.3 -NVIDIA GT 140M .*NVIDIA .*GT 14[0-9]M.* 3 1 1 3.3 -NVIDIA GT 150M .*NVIDIA .*GTS 15[0-9]M.* 2 1 0 0 -NVIDIA GTS 160M .*NVIDIA .*GTS 16[0-9]M.* 2 1 0 0 -NVIDIA G210M .*NVIDIA .*G21[0-9]M.* 3 1 0 3.3 +NVIDIA GeForce Pre-Release .*NVIDIA .*GeForce[ ]Pre-Release.* 2 1 1 3.3 +NVIDIA D1xP1 .*NVIDIA .*D1[0-4]P1.* 0 0 0 0 +NVIDIA Mystery PCI Card .*NVIDIA .Corporation [/]PCI]/]SSE2.* 0 0 0 0 +NVIDIA Quadro FX 770M .*Quadro.*FX 77[0-9]M.* 2 1 0 3.3 +NVIDIA Quadro FX 1500M .*Quadro.*FX 150[0-9]M.* 1 1 0 2.1 +NVIDIA Quadro FX 1600M .*Quadro.*FX 160[0-9]M.* 2 1 0 3.3 +NVIDIA Quadro FX 2500M .*Quadro.*FX 250[0-9]M.* 2 1 0 2.1 +NVIDIA Quadro FX 2700M .*Quadro.*FX 270[0-9]M.* 3 1 0 3.3 +NVIDIA Quadro FX 2800M .*Quadro.*FX 280[0-9]M.* 3 1 0 3.3 +NVIDIA Quadro FX 3500 .*Quadro.*FX 3500.* 2 1 0 2.1 +NVIDIA Quadro FX 3600 .*Quadro.*FX 3600.* 3 1 0 3.3 +NVIDIA Quadro FX 3700 .*Quadro.*FX 3700.* 3 1 0 3.3 +NVIDIA Quadro FX 3800 .*Quadro.*FX 3800.* 3 1 0 3.3 +NVIDIA Quadro FX 4500 .*Quadro.*FX 45.* 3 1 0 2.1 +NVIDIA Quadro FX 880M .*Quadro.*FX 88[0-9]M.* 3 1 0 3.3 +NVIDIA Quadro FX 4800 .*NVIDIA .*Quadro FX 4800.* 3 1 0 3.1 +NVIDIA Quadro FX .*NVIDIA .*Quadro FX.* 1 1 0 3.3 +NVIDIA Quadro NVS 1xxM .*NVIDIA .*(Quadro)* NVS *1.[05]M.* 0 1 1 3.3 +NVIDIA Quadro NVS 300M .*NVIDIA .*(Quadro)*[ ]+NVS *30[0-9]M.* 2 1 0 0 +NVIDIA Quadro NVS 320M .*NVIDIA .*(Quadro)*[ ]+NVS *32[0-9]M.* 2 1 0 0 +NVIDIA Quadro NVS 2100M .*NVIDIA .*(Quadro)*[ ]+NVS *210[0-9]M.* 2 1 0 3.3 +NVIDIA Quadro NVS 3100M .*NVIDIA .*(Quadro)*[ ]+NVS *310[0-9]M.* 2 1 0 3.3 +NVIDIA Quadro NVS 4200M .*NVIDIA .*(Quadro)*[ ]+NVS *420[0-9]M.* 2 1 0 4.2 +NVIDIA Quadro NVS 5100M .*NVIDIA .*(Quadro)*[ ]+NVS *510[0-9]M.* 2 1 0 0 +NVIDIA Quadro NVS 5200M .*NVIDIA .*(Quadro)*[ ]+NVS *520[0-9]M.* 2 1 0 0 +NVIDIA Quadro NVS 5400M .*NVIDIA .*(Quadro)*[ ]+NVS *540[0-9]M.* 2 1 0 0 +NVIDIA Quadro NVS .*NVIDIA .*(Quadro)*[ ]+NVS 0 1 0 4.2 +NVIDIA Quadro2 .*Quadro2.* 0 1 0 1.5 +NVIDIA Quadro 1000M .*Quadro.* (K1|1)00[0-9]M.* 2 1 0 4.2 +NVIDIA Quadro 1100M .*Quadro.* *110[0-9]M.* 2 1 0 3.3 +NVIDIA Quadro K600 .*Quadro.* (K6|6)0[0-9][^0].* 2 1 0 4.2 +NVIDIA Quadro K1000 .*Quadro.* (K1|1)00[0-9].* 2 1 0 4.2 +NVIDIA Quadro 2000 M/D .*Quadro.* (K2|2)000.* 3 1 0 4.2 +NVIDIA Quadro 3000M .*Quadro.* (K3|3)00[0-9]M.* 3 1 0 4.2 +NVIDIA Quadro 4000M .*Quadro.* (K4|4)00[0-9]M.* 3 1 0 4.2 +NVIDIA Quadro 4000 .*Quadro.* (K4|4)000.* 3 1 0 4.2 +NVIDIA Quadro 50x0 M .*Quadro.* (K5|5)0.0.* 3 1 0 4.2 +NVIDIA Quadro 6000 .*Quadro.* (K6|6)000.* 3 1 0 0 +NVIDIA Quadro 400 .*Quadro.* 400.* 2 1 0 3.3 +NVIDIA Quadro 600 .*Quadro.* 600.* 2 1 0 4.2 +NVIDIA Quadro4 .*Quadro4.* 0 1 0 1.5 +NVIDIA Quadro DCC .*Quadro DCC.* 0 1 0 0 +NVIDIA Quadro CX .*Quadro.*CX.* 3 1 0 0 +NVIDIA G 100M .*NVIDIA .*G *10[0-9]M.* 1 1 1 3.3 +NVIDIA G 110M .*NVIDIA .*G *11[0-9]M.* 1 1 1 3.3 +NVIDIA G 120M .*NVIDIA .*G *12[0-9]M.* 1 1 1 3.3 +NVIDIA G 200M .*NVIDIA .*G *20[0-9]M.* 1 1 0 0 +NVIDIA G 410M .*NVIDIA .*G *41[0-9]M.* 3 1 1 4.2 +NVIDIA GT 130M .*NVIDIA .*GT *13[0-9]M.* 3 1 1 3.3 +NVIDIA GT 140M .*NVIDIA .*GT *14[0-9]M.* 3 1 1 3.3 +NVIDIA GT 150M .*NVIDIA .*GTS *15[0-9]M.* 2 1 0 0 +NVIDIA GTS 160M .*NVIDIA .*GTS *16[0-9]M.* 2 1 0 0 +NVIDIA G210M .*NVIDIA .*G *21[0-9]M.* 3 1 0 3.3 NVIDIA GT 220M .*NVIDIA .*GT 22[0-9]M.* 3 1 1 3.3 NVIDIA GT 230M .*NVIDIA .*GT 23[0-9]M.* 3 1 1 3.3 NVIDIA GT 240M .*NVIDIA .*GT 24[0-9]M.* 3 1 1 3.3 +NVIDIA GT 260M .*NVIDIA .*GT 26[0-9]M.* 3 1 1 3.3 NVIDIA GTS 250M .*NVIDIA .*GTS 25[0-9]M.* 3 1 0 3.3 NVIDIA GTS 260M .*NVIDIA .*GTS 26[0-9]M.* 3 1 0 0 NVIDIA GTX 260M .*NVIDIA .*GTX 26[0-9]M.* 3 1 0 3.3 NVIDIA GTX 270M .*NVIDIA .*GTX 27[0-9]M.* 3 1 0 0 NVIDIA GTX 280M .*NVIDIA .*GTX 28[0-9]M.* 3 1 0 3.3 NVIDIA 300M .*NVIDIA .*GT 30[0-9]M.* 3 1 1 4.2 -NVIDIA G 310M .*NVIDIA .* 31[0-9]M.* 2 1 0 3.3 -NVIDIA GT 320M .*NVIDIA .* 32[0-9]M.* 3 1 0 3.3 -NVIDIA GT 330M .*NVIDIA .*GT 33[0-9]M.* 3 1 1 3.3 -NVIDIA GT 340M .*NVIDIA .*GT 34[0-9]M.* 4 1 1 3.3 +NVIDIA G 310M .*NVIDIA .*G[T]* 31[0-9]M.* 2 1 0 3.3 +NVIDIA GT 320M .*NVIDIA .*G[T]* 32[0-9]M.* 3 1 0 3.3 +NVIDIA GT 330M .*NVIDIA .*G[T]* 33[0-9]M.* 3 1 1 3.3 +NVIDIA GT 340M .*NVIDIA .*G[T]* 34[0-9]M.* 4 1 1 3.3 NVIDIA GTS 350M .*NVIDIA .*GTS 35[0-9]M.* 4 1 1 3.3 NVIDIA GTS 360M .*NVIDIA .*GTS 36[0-9]M.* 5 1 1 3.3 -NVIDIA 400M .*NVIDIA .* 40[0-9]M.* 2 1 0 0 -NVIDIA 410M .*NVIDIA .* 41[0-9]M.* 3 1 0 0 -NVIDIA GT 420M .*NVIDIA .*GT 42[0-9]M.* 3 1 1 4.2 -NVIDIA GT 430M .*NVIDIA .*GT 43[0-9]M.* 3 1 1 4.2 -NVIDIA GT 440M .*NVIDIA .*GT 44[0-9]M.* 3 1 1 4.2 -NVIDIA GT 450M .*NVIDIA .*GT 45[0-9]M.* 3 1 0 0 -NVIDIA GTX 460M .*NVIDIA .*GTX 46[0-9]M.* 4 1 1 4.3 -NVIDIA GTX 470M .*NVIDIA .*GTX 47[0-9]M.* 3 1 0 4.2 -NVIDIA GTX 480M .*NVIDIA .*GTX 48[0-9]M.* 3 1 1 4.2 -NVIDIA GT 520M .*NVIDIA .*GT 52[0-9]M.* 3 1 1 4.2 -NVIDIA GT 530M .*NVIDIA .*GT 53[0-9]M.* 3 1 1 4.2 -NVIDIA GT 540M .*NVIDIA .*GT 54[0-9]M.* 3 1 1 4.2 -NVIDIA GT 550M .*GeForce GT 55[0-9]M.* 3 1 1 4.2 -NVIDIA GTX 560M .*NVIDIA .*GTX 56[0-9]M.* 3 1 0 4.2 -NVIDIA GTX 570M .*NVIDIA .*GTX 57[0-9]M.* 5 1 0 4.2 -NVIDIA GTX 580M .*NVIDIA .*GTX 58[0-9]M.* 5 1 1 4.2 -NVIDIA 610M .*NVIDIA.* 61[0-9]M.* 3 1 1 4.2 -NVIDIA GT 620M .*NVIDIA .*GT 62[0-9]M.* 3 1 0 4.2 -NVIDIA GT 630M .*NVIDIA .*GT 63[0-9]M.* 3 1 0 4.2 -NVIDIA GT 640M .*NVIDIA .*GT 64[0-9]M.* 3 1 0 4.2 -NVIDIA GT 650M .*NVIDIA .*GT 65[0-9]M.* 3 1 0 4.2 -NVIDIA GTX 660M .*NVIDIA .*GTX 66[0-9]M.* 5 1 0 4.3 -NVIDIA GTX 670M .*NVIDIA .*GTX 67[0-9]M.* 5 1 1 4.2 -NVIDIA GTX 680M .*NVIDIA .*GTX 68[0-9]M.* 5 1 0 4.2 -NVIDIA GTX 690M .*NVIDIA .*GTX 69[0-9]M.* 5 1 0 0 +NVIDIA 310M .*NVIDIA .*31[0-9]M.* 2 1 0 3.3 +NVIDIA 320M .*NVIDIA .*320M.* 2 1 0 3.3 +NVIDIA 400M .*NVIDIA .*[ ]+40[0-9]M.* 2 1 0 0 +NVIDIA 410M .*NVIDIA .*[ ]+41[0-9]M.* 3 1 0 0 +NVIDIA GT 420M .*NVIDIA .*GT *42[0-9]M.* 3 1 1 4.3 +NVIDIA GT 430M .*NVIDIA .*GT *43[0-9]M.* 3 1 1 4.3 +NVIDIA GT 440M .*NVIDIA .*GT *44[0-9]M.* 3 1 1 4.3 +NVIDIA GT 450M .*NVIDIA .*GT *45[0-9]M.* 3 1 0 0 +NVIDIA GTX 460M .*NVIDIA .*GTX *46[0-9]M.* 4 1 1 4.3 +NVIDIA GTX 470M .*NVIDIA .*GTX *47[0-9]M.* 3 1 0 4.3 +NVIDIA GTX 480M .*NVIDIA .*GTX *48[0-9]M.* 3 1 1 4.3 +NVIDIA GT 520M .*NVIDIA .*GT *52[0-9]M.* 3 1 1 4.3 +NVIDIA GT 530M .*NVIDIA .*GT *53[0-9]M.* 3 1 1 4.3 +NVIDIA GT 540M .*NVIDIA .*GT *54[0-9]M.* 3 1 1 4.3 +NVIDIA GT 550M .*NVIDIA .*GT *55[0-9]M.* 3 1 1 4.3 +NVIDIA GTX 560M .*NVIDIA .*GTX *56[0-9]M.* 3 1 0 4.3 +NVIDIA GTX 570M .*NVIDIA .*GTX *57[0-9]M.* 5 1 0 4.3 +NVIDIA GTX 580M .*NVIDIA .*GTX *58[0-9]M.* 5 1 1 4.3 +NVIDIA 610M .*NVIDIA.* 61[0-9]M.* 3 1 1 4.3 +NVIDIA GT 620M .*NVIDIA .*GT *62[0-9]M.* 3 1 0 4.3 +NVIDIA GT 630M .*NVIDIA .*GT *63[0-9]M.* 3 1 0 4.3 +NVIDIA GT 640M .*NVIDIA .*GT *64[0-9]M.* 3 1 0 4.3 +NVIDIA GT 650M .*NVIDIA .*GT *65[0-9]M.* 3 1 0 4.3 +NVIDIA GTX 660M .*NVIDIA .*GTX *66[0-9]M.* 5 1 0 4.3 +NVIDIA GTX 670M .*NVIDIA .*GTX *67[0-9]M.* 5 1 1 4.3 +NVIDIA GTX 680M .*NVIDIA .*GTX *68[0-9]M.* 5 1 0 4.3 +NVIDIA GTX 690M .*NVIDIA .*GTX *69[0-9]M.* 5 1 0 4.3 +NVIDIA 710M .*NVIDIA.* 71[0-9]M.* 3 1 0 4.3 +NVIDIA GT 720M .*NVIDIA .*GT *72[0-9]M.* 3 1 0 4.3 +NVIDIA GT 730M .*NVIDIA .*GT *73[0-9]M.* 3 1 0 4.3 +NVIDIA GT 740M .*NVIDIA .*GT *74[0-9]M.* 3 1 0 4.3 +NVIDIA GT 750M .*NVIDIA .*GT *75[0-9]M.* 3 1 0 4.3 +NVIDIA GTX 760M .*NVIDIA .*GTX *76[0-9]M.* 5 1 0 4.3 +NVIDIA GTX 770M .*NVIDIA .*GTX *77[0-9]M.* 5 1 0 4.3 +NVIDIA GTX 780M .*NVIDIA .*GTX *78[0-9]M.* 5 1 0 4.3 NVIDIA G100 .*NVIDIA .*G10.* 3 1 1 4.2 NVIDIA GT 120 .*NVIDIA .*GT 12.* 2 1 0 3.3 NVIDIA GT 130 .*NVIDIA .*GT 13.* 2 1 0 3.3 NVIDIA GT 140 .*NVIDIA .*GT 14.* 2 1 0 3.3 +NVIDIA GT 150 .*NVIDIA .*GT 15.* 2 1 1 3.3 NVIDIA GTS 150 .*NVIDIA .*GTS 15.* 2 1 0 0 -NVIDIA 200 .*NVIDIA .*GeForce 20.* 2 1 1 3.3 -NVIDIA G200 .*NVIDIA .*GeForce G20.* 2 1 1 3.3 -NVIDIA G210 .*NVIDIA .*GeForce G210.* 3 1 1 3.3 -NVIDIA 210 .*NVIDIA .*GeForce 210.* 3 1 1 3.3 -NVIDIA GT 220 .*NVIDIA .*GT 22.* 2 1 1 3.3 -NVIDIA GT 230 .*NVIDIA .*GT 23.* 2 1 1 3.3 -NVIDIA GT 240 .*NVIDIA .*GT 24.* 4 1 1 3.3 -NVIDIA GTS 240 .*NVIDIA .*GTS 24.* 4 1 1 3.3 -NVIDIA GTS 250 .*NVIDIA .*GTS 25.* 4 1 1 3.3 -NVIDIA GTX 260 .*NVIDIA .*GTX 26.* 4 1 1 3.3 -NVIDIA GTX 270 .*NVIDIA .*GTX 27.* 4 1 0 3.3 -NVIDIA GTX 280 .*NVIDIA .*GTX 28.* 4 1 1 3.3 -NVIDIA GTX 290 .*NVIDIA .*GTX 29.* 5 1 0 3.3 -NVIDIA 310 .*NVIDIA .*GeForce 310.* 3 1 1 3.3 -NVIDIA 315 .*NVIDIA .*GeForce 315.* 3 1 1 3.3 -NVIDIA GT 320 .*NVIDIA .*GT 32.* 3 1 0 3.3 -NVIDIA GT 330 .*NVIDIA .*GT 33.* 3 1 0 3.3 -NVIDIA GT 340 .*NVIDIA .*GT 34.* 3 1 0 3.3 -NVIDIA 405 .*NVIDIA .* 405.* 3 1 0 3.3 -NVIDIA GT 420 .*NVIDIA .*GT 42.* 3 1 1 4.2 -NVIDIA GT 430 .*NVIDIA .*GT 43.* 3 1 1 4.3 -NVIDIA GT 440 .*NVIDIA .*GT 44.* 4 1 0 4.3 -NVIDIA GTS 450 .*NVIDIA .*GTS 45.* 4 1 1 4.2 -NVIDIA GTX 460 .*NVIDIA .*GTX 46.* 5 1 1 4.3 -NVIDIA GTX 470 .*NVIDIA .*GTX 47.* 5 1 1 4.2 -NVIDIA GTX 480 .*NVIDIA .*GTX 48.* 5 1 1 4.2 -NVIDIA 510 .*NVIDIA .* 510.* 3 1 0 4.2 -NVIDIA GT 520 .*NVIDIA .*GT 52.* 3 1 1 4.2 -NVIDIA GT 530 .*NVIDIA .*GT 53.* 3 1 1 4.2 -NVIDIA GT 540 .*NVIDIA .*GT 54.* 3 1 1 4.2 -NVIDIA GTX 550 .*NVIDIA .*GTX 55.* 5 1 1 4.3 -NVIDIA GTX 560 .*NVIDIA .*GTX 56.* 5 1 1 4.3 -NVIDIA GTX 570 .*NVIDIA .*GTX 57.* 5 1 1 4.2 -NVIDIA GTX 580 .*NVIDIA .*GTX 58.* 5 1 1 4.3 -NVIDIA GTX 590 .*NVIDIA .*GTX 59.* 5 1 1 4.2 -NVIDIA 605 .*NVIDIA .* 605.* 3 1 1 4.2 -NVIDIA GT 610 .*NVIDIA .*GT 61.* 3 1 1 4.2 -NVIDIA GT 620 .*NVIDIA .*GT 62.* 3 1 0 4.2 -NVIDIA GT 630 .*NVIDIA .*GT 63.* 3 1 0 4.2 -NVIDIA GT 640 .*NVIDIA .*GT 64.* 3 1 0 4.2 -NVIDIA GT 650 .*NVIDIA .*GT 65.* 3 1 1 4.2 -NVIDIA GTX 650 .*NVIDIA .*GTX 65.* 3 1 1 4.2 -NVIDIA GTX 660 .*NVIDIA .*GTX 66.* 5 1 0 4.3 -NVIDIA GTX 670 .*NVIDIA .*GTX 67.* 5 1 1 4.2 -NVIDIA GTX 680 .*NVIDIA .*GTX 68.* 5 1 1 4.2 -NVIDIA GTX 690 .*NVIDIA .*GTX 69.* 5 1 1 4.2 +NVIDIA 200 .*NVIDIA .[ ]+200[^0].* 2 1 1 3.3 +NVIDIA G200 .*NVIDIA .*G[ ]*200.* 2 1 1 3.3 +NVIDIA G210 .*NVIDIA .*G[ ]*210.* 3 1 1 3.3 +NVIDIA 205 .*NVIDIA .*205[^0]*.* 3 1 1 3.3 +NVIDIA 210 .*NVIDIA .*210$ 3 1 1 3.3 +NVIDIA GeForce 210 .*NVIDIA .*(GeForce)[ ]210[^0]*$ 3 1 1 3.3 +NVIDIA GT 220 .*NVIDIA .*GT *22.* 2 1 1 3.3 +NVIDIA GT 230 .*NVIDIA .*GT *23.* 2 1 1 3.3 +NVIDIA GT 240 .*NVIDIA .*GT *24.* 4 1 1 3.3 +NVIDIA GTS 240 .*NVIDIA .*GTS *24.* 4 1 1 3.3 +NVIDIA GTS 250 .*NVIDIA .*GTS *25.* 4 1 1 3.3 +NVIDIA GTS 360 .*NVIDIA .*GTS *36.* 4 1 1 3.3 +NVIDIA GTX 260 .*NVIDIA .*GTX *26.* 4 1 1 3.3 +NVIDIA GTX 270 .*NVIDIA .*GTX *27.* 4 1 0 3.3 +NVIDIA GTX 280 .*NVIDIA .*GTX *28.* 4 1 1 3.3 +NVIDIA GTX 290 .*NVIDIA .*GTX *29.* 5 1 0 3.3 +NVIDIA GT 320 .*NVIDIA .*GT *32.* 3 1 0 3.3 +NVIDIA GT 330 .*NVIDIA .*GT *33.* 3 1 0 3.3 +NVIDIA GT 340 .*NVIDIA .*GT *34.* 3 1 0 0 +NVIDIA 310 .*NVIDIA .*310[^0M]*.* 3 1 1 3.3 +NVIDIA 315 .*NVIDIA .*315[^0M]*.* 3 1 1 3.3 +NVIDIA 320 .*NVIDIA .*320[^0M]*.* 3 1 1 3.3 +NVIDIA 405 .*NVIDIA .*405[^0]*.* 3 1 0 3.3 +NVIDIA 410 .*NVIDIA .*410[^0]*.* 3 1 0 3.3 +NVIDIA GT 415 .*NVIDIA .*GT *415.* 3 1 1 4.3 +NVIDIA GT 420 .*NVIDIA .*GT *42.* 3 1 1 4.3 +NVIDIA GT 430 .*NVIDIA .*GT *43.* 3 1 1 4.3 +NVIDIA GT 440 .*NVIDIA .*GT *44.* 4 1 1 4.3 +NVIDIA GT 450 .*NVIDIA .*GT *45.* 4 1 1 4.3 +NVIDIA GTS 450 .*NVIDIA .*GTS *45.* 4 1 1 4.3 +NVIDIA GTX 460 .*NVIDIA .*GTX *46.* 5 1 1 4.3 +NVIDIA GTX 470 .*NVIDIA .*GTX *47.* 5 1 1 4.3 +NVIDIA GTX 480 .*NVIDIA .*GTX *48.* 5 1 1 4.3 +NVIDIA 505 .*NVIDIA .*505[^0]*.* 3 1 0 0 +NVIDIA 510 .*NVIDIA .*510[^0]*.* 3 1 0 0 +NVIDIA GT 520 .*NVIDIA .*GT *52.* 3 1 1 4.3 +NVIDIA GT 530 .*NVIDIA .*GT *53.* 3 1 1 4.3 +NVIDIA GT 540 .*NVIDIA .*GT *54.* 3 1 1 4.3 +NVIDIA GT 550 .*NVIDIA .*GT *55.* 3 1 1 4.3 +NVIDIA GTX 550 .*NVIDIA .*GTX *55.* 5 1 1 4.3 +NVIDIA GTX 560 .*NVIDIA .*GTX *56.* 5 1 1 4.3 +NVIDIA GTX 570 .*NVIDIA .*GTX *57.* 5 1 1 4.3 +NVIDIA GTX 580 .*NVIDIA .*GTX *58.* 5 1 1 4.3 +NVIDIA GTX 590 .*NVIDIA .*GTX *59.* 5 1 1 4.3 +NVIDIA 605 .*NVIDIA .*605[^0]*.* 3 1 1 4.3 +NVIDIA GT 61x .*NVIDIA .*GT 61.* 3 1 1 4.3 +NVIDIA GT 62x .*NVIDIA .*GT 62.* 3 1 0 4.3 +NVIDIA GT 63x .*NVIDIA .*GT 63.* 3 1 0 4.3 +NVIDIA GT 64x .*NVIDIA .*GT 64.* 3 1 0 4.3 +NVIDIA GT 65x .*NVIDIA .*GT 65.* 3 1 1 4.3 +NVIDIA GTX 64x .*NVIDIA .*GTX 64.* 3 1 1 4.3 +NVIDIA GTX 65x .*NVIDIA .*GTX 65.* 3 1 1 4.3 +NVIDIA GTX 66x .*NVIDIA .*GTX 66.* 5 1 0 4.3 +NVIDIA GTX 67x .*NVIDIA .*GTX 67.* 5 1 1 4.3 +NVIDIA GTX 68x .*NVIDIA .*GTX 68.* 5 1 1 4.3 +NVIDIA GTX 69x .*NVIDIA .*GTX 69.* 5 1 1 4.3 +NVIDIA GT 71x .*NVIDIA .*GT *71.* 3 1 0 4.3 +NVIDIA GT 72x .*NVIDIA .*GT *72.* 3 1 0 4.3 +NVIDIA GT 73x .*NVIDIA .*GT *73.* 3 1 0 4.3 +NVIDIA GT 74x .*NVIDIA .*GT *74.* 3 1 0 4.3 +NVIDIA GTX 75x .*NVIDIA .*GTX *75.* 3 1 0 4.3 +NVIDIA GTX 76x .*NVIDIA .*GTX *76.* 5 1 0 4.3 +NVIDIA GTX 77x .*NVIDIA .*GTX *77.* 5 1 0 4.3 +NVIDIA GTX 78x .*NVIDIA .*GTX *78.* 5 1 0 4.3 +NVIDIA GTX TITAN .*NVIDIA .*GTX *TITAN.* 5 1 0 4.3 NVIDIA C51 .*NVIDIA .*C51.* 0 1 1 2 NVIDIA G72 .*NVIDIA .*G72.* 1 1 0 0 NVIDIA G73 .*NVIDIA .*G73.* 1 1 0 0 NVIDIA G84 .*NVIDIA .*G84.* 2 1 0 0 NVIDIA G86 .*NVIDIA .*G86.* 3 1 0 0 NVIDIA G92 .*NVIDIA .*G92.* 3 1 0 0 +NVIDIA GK106 .*NVIDIA .*GK106.* 5 1 0 4.3 NVIDIA GeForce .*GeForce 256.* 0 0 0 0 NVIDIA GeForce 2 .*GeForce ?2 ?.* 0 1 1 1.5 +NVIDIA GeForce 3 .*GeForce ?3 ?.* 2 1 1 2.1 +NVIDIA GeForce 3 Ti .*GeForce ?3 Ti.* 0 1 0 0 NVIDIA GeForce 4 .*NVIDIA .*GeForce ?4.* 0 1 1 1.5 +NVIDIA GeForce 4 Go .*NVIDIA .*GeForce ?4.*Go.* 0 1 0 0 +NVIDIA GeForce 4 MX .*NVIDIA .*GeForce ?4 MX.* 0 1 0 0 +NVIDIA GeForce 4 PCX .*NVIDIA .*GeForce ?4 PCX.* 0 1 0 0 +NVIDIA GeForce 4 Ti .*NVIDIA .*GeForce ?4 Ti.* 0 1 0 0 NVIDIA GeForce 6100 .*NVIDIA .*GeForce 61.* 3 1 1 4.2 NVIDIA GeForce 6200 .*NVIDIA .*GeForce 62.* 0 1 1 2.1 NVIDIA GeForce 6500 .*NVIDIA .*GeForce 65.* 1 1 1 2.1 @@ -486,8 +612,6 @@ NVIDIA GeForce Go 7900 .*NVIDIA .*GeForce Go 79.* 1 1 1 2.1 NVIDIA D9M .*NVIDIA .*D9M.* 1 1 0 0 NVIDIA G94 .*NVIDIA .*G94.* 3 1 0 0 NVIDIA GeForce Go 6 .*GeForce Go 6.* 1 1 0 0 -NVIDIA ION 2 .*NVIDIA .*ION 2.* 2 1 0 0 -NVIDIA ION .*NVIDIA Corporation.*ION.* 2 1 1 3.3 NVIDIA NB8M .*NVIDIA .*NB8M.* 1 1 0 0 NVIDIA NB8P .*NVIDIA .*NB8P.* 2 1 0 0 NVIDIA NB9E .*NVIDIA .*NB9E.* 3 1 0 0 @@ -495,7 +619,9 @@ NVIDIA NB9M .*NVIDIA .*NB9M.* 1 1 0 0 NVIDIA NB9P .*NVIDIA .*NB9P.* 2 1 0 0 NVIDIA N10 .*NVIDIA .*N10.* 1 1 0 2.1 NVIDIA GeForce PCX .*GeForce PCX.* 0 1 0 1.5 -NVIDIA Generic .*NVIDIA .*Unknown.* 0 0 0 2.1 +NVIDIA PCI .*NVIDIA PCI[ ]* 0 0 0 2.1 +NVIDIA Generic .*NVIDIA Generic.* 0 0 0 2.1 +NVIDIA Generic Unknown .*NVIDIA .*Unknown.* 0 0 0 2.1 NVIDIA NV17 .*NVIDIA .*NV17.* 0 1 0 0 NVIDIA NV34 .*NVIDIA .*NV34.* 0 1 0 0 NVIDIA NV35 .*NVIDIA .*NV35.* 0 1 0 0 @@ -513,45 +639,14 @@ NVIDIA MCP77 .*NVIDIA .*MCP77.* 1 1 0 0 NVIDIA MCP78 .*NVIDIA .*MCP78.* 1 1 0 0 NVIDIA MCP79 .*NVIDIA .*MCP79.* 1 1 0 0 NVIDIA MCP7A .*NVIDIA .*MCP7A.* 1 1 0 0 -NVIDIA Quadro2 .*Quadro2.* 0 1 0 1.5 -NVIDIA Quadro 1000M .*Quadro.* (K1|1)00[0-9]M.* 2 1 0 4.2 -NVIDIA Quadro 2000 M/D .*Quadro.* (K2|2)000.* 3 1 0 4.2 -NVIDIA Quadro 3000M .*Quadro.* (K3|3)00[0-9]M.* 3 1 0 4.2 -NVIDIA Quadro 4000M .*Quadro.* (K4|4)00[0-9]M.* 3 1 0 4.2 -NVIDIA Quadro 4000 .*Quadro 4000.* 3 1 0 4.2 -NVIDIA Quadro 50x0 M .*Quadro.* 50.0.* 3 1 0 4.2 -NVIDIA Quadro 6000 .*Quadro.* 6000.* 3 1 0 0 -NVIDIA Quadro 400 .*Quadro.* 400.* 2 1 0 3.3 -NVIDIA Quadro 600 .*Quadro.* 600.* 2 1 0 4.2 -NVIDIA Quadro4 .*Quadro4.* 0 1 0 1.5 -NVIDIA Quadro DCC .*Quadro DCC.* 0 1 0 0 -NVIDIA Quadro CX .*Quadro.*CX.* 3 1 0 0 -NVIDIA Quadro FX 770M .*Quadro.*FX 77[0-9]M.* 2 1 0 3.3 -NVIDIA Quadro FX 1500M .*Quadro.*FX 150[0-9]M.* 1 1 0 2.1 -NVIDIA Quadro FX 1600M .*Quadro.*FX 160[0-9]M.* 2 1 0 3.3 -NVIDIA Quadro FX 2500M .*Quadro.*FX 250[0-9]M.* 2 1 0 2.1 -NVIDIA Quadro FX 2700M .*Quadro.*FX 270[0-9]M.* 3 1 0 3.3 -NVIDIA Quadro FX 2800M .*Quadro.*FX 280[0-9]M.* 3 1 0 3.3 -NVIDIA Quadro FX 3500 .*Quadro.*FX 3500.* 2 1 0 2.1 -NVIDIA Quadro FX 3600 .*Quadro.*FX 3600.* 3 1 0 3.3 -NVIDIA Quadro FX 3700 .*Quadro.*FX 3700.* 3 1 0 3.3 -NVIDIA Quadro FX 3800 .*Quadro.*FX 3800.* 3 1 0 3.3 -NVIDIA Quadro FX 4500 .*Quadro.*FX 45.* 3 1 0 2.1 -NVIDIA Quadro FX 880M .*Quadro.*FX 88[0-9]M.* 3 1 0 3.3 -NVIDIA Quadro FX 4800 .*NVIDIA .*Quadro FX 4800.* 3 1 0 3.1 -NVIDIA Quadro FX .*Quadro FX.* 1 1 0 3.3 -NVIDIA Quadro NVS 1xxM .*Quadro NVS 1.[05]M.* 0 1 1 3.3 -NVIDIA Quadro NVS 300M .*NVIDIA .*NVS 30[0-9]M.* 2 1 0 0 -NVIDIA Quadro NVS 320M .*NVIDIA .*NVS 32[0-9]M.* 2 1 0 0 -NVIDIA Quadro NVS 2100M .*NVIDIA .*NVS 210[0-9]M.* 2 1 0 3.3 -NVIDIA Quadro NVS 3100M .*NVIDIA .*NVS 310[0-9]M.* 2 1 0 3.3 -NVIDIA Quadro NVS 4200M .*NVIDIA .*NVS 420[0-9]M.* 2 1 0 4.2 -NVIDIA Quadro NVS 5100M .*NVIDIA .*NVS 510[0-9]M.* 2 1 0 0 -NVIDIA Quadro NVS .*NVIDIA .*NVS 0 1 0 4.2 NVIDIA Corporation N12P .*NVIDIA .*N12P.* 1 1 1 4.1 NVIDIA Corporation N11M .*NVIDIA .*N11M.* 2 1 0 3.1 NVIDIA RIVA TNT .*RIVA TNT.* 0 0 0 1.5 -S3 .*S3 Graphics.* 0 0 1 1.4 +NVIDIA GRID .*NVIDIA .*GRID.* 0 0 0 1.5 +NVIDIA ION 2 .*NVIDIA .* *[I][O][N] 2.* 2 1 0 0 +NVIDIA ION a .*NVIDIA .*[I][O][N]$ 2 1 1 3.3 +NVIDIA ION b .*NVIDIA .*(Corporation) [I][O][N].* 2 1 1 3.3 +S3 .*S3 *(Graphics)*.* 0 0 1 1.4 SiS SiS.* 0 0 1 1.5 Trident Trident.* 0 0 0 0 Tungsten Graphics Tungsten.* 0 0 0 0 @@ -559,5 +654,9 @@ XGI XGI.* 0 0 0 0 VIA VIA.* 0 0 0 0 Apple Generic Apple.*Generic.* 0 0 0 0 Apple Software Renderer Apple.*Software Renderer.* 0 0 0 0 +Oracle VirtualBox.* 0 1 1 2.1 Humper Humper.* 0 1 1 2.1 PowerVR SGX545 .*PowerVR SGX.* 1 1 1 3 +ATI GeForce Lulz .*ATI.*GeForce.* 0 0 0 0 + + diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 8a6114f0d5..c4f503ef4e 100755 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -72,16 +72,8 @@ LangString LanguageCode ${LANG_RUSSIAN} "ru" LangString LanguageCode ${LANG_TURKISH} "tr"
LangString LanguageCode ${LANG_TRADCHINESE} "zh"
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Tweak for different servers/builds (this placeholder is replaced by viewer_manifest.py)
-;; For example:
-;; !define INSTFLAGS "%(flags)s"
-;; !define INSTNAME "SecondLife%(grid_caps)s"
-;; !define SHORTCUT "Second Life (%(grid_caps)s)"
-;; !define URLNAME "secondlife%(grid)s"
-;; !define UNINSTALL_SETTINGS 1
-
-%%GRID_VARS%%
+;; this placeholder is replaced by viewer_manifest.py
+%%INST_VARS%%
Name ${INSTNAME}
@@ -109,7 +101,6 @@ Page instfiles ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Var INSTPROG
Var INSTEXE
-Var INSTFLAGS
Var INSTSHORTCUT
Var COMMANDLINE ; command line passed to this installer, set in .onInit
Var SHORTCUT_LANG_PARAM ; "--set InstallLanguage de", passes language to viewer
@@ -147,7 +138,7 @@ label_ask_launch: label_launch:
# Assumes SetOutPath $INSTDIR
- Exec '"$INSTDIR\$INSTEXE" $INSTFLAGS $SHORTCUT_LANG_PARAM'
+ Exec '"$INSTDIR\$INSTEXE" $SHORTCUT_LANG_PARAM'
label_no_launch:
Pop $R0
FunctionEnd
@@ -310,6 +301,23 @@ Function CheckNetworkConnection Return
FunctionEnd
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Function CheckOldExeName
+; Viewer versions < 3.6.12 used the name 'SecondLife.exe'
+; If that name is found in the install folder, delete it to invalidate any
+; old shortcuts to it that may be in non-standard locations, so that the user
+; does not end up running the old version (potentially getting caught in an
+; infinite update loop). See MAINT-3575
+; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+Function CheckOldExeName
+ IfFileExists "$INSTDIR\SecondLife.exe" CHECKOLDEXE_FOUND CHECKOLDEXE_DONE
+
+CHECKOLDEXE_FOUND:
+ Delete "$INSTDIR\SecondLife.exe"
+CHECKOLDEXE_DONE:
+FunctionEnd
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Function CheckWillUninstallV2
@@ -682,6 +690,9 @@ Delete "$INSTDIR\*.glsl" Delete "$INSTDIR\motions\*.lla"
Delete "$INSTDIR\trial\*.html"
Delete "$INSTDIR\newview.exe"
+Delete "$INSTDIR\SecondLife.exe"
+;; MAINT-3099 workaround - prevent these log files, if present, from causing a user alert
+Delete "$INSTDIR\VivoxVoiceService-*.log"
;; Remove entire help directory
Delete "$INSTDIR\help\Advanced\*"
RMDir "$INSTDIR\help\Advanced"
@@ -720,7 +731,6 @@ ShowUninstDetails show Section Uninstall
; Start with some default values.
-StrCpy $INSTFLAGS ""
StrCpy $INSTPROG "${INSTNAME}"
StrCpy $INSTEXE "${INSTEXE}"
StrCpy $INSTSHORTCUT "${SHORTCUT}"
@@ -919,7 +929,6 @@ Section "" ; (default section) SetShellVarContext all ; install for all users (if you change this, change it in the uninstall as well)
; Start with some default values.
-StrCpy $INSTFLAGS "${INSTFLAGS}"
StrCpy $INSTPROG "${INSTNAME}"
StrCpy $INSTEXE "${INSTEXE}"
StrCpy $INSTSHORTCUT "${SHORTCUT}"
@@ -931,6 +940,7 @@ Call CheckIfAlreadyCurrent ; Make sure that we haven't already installed this v Call CloseSecondLife ; Make sure we're not running
Call CheckNetworkConnection ; ping secondlife.com
Call CheckWillUninstallV2 ; See if a V2 install exists and will be removed.
+Call CheckOldExeName ; Clean up a previous version of the exe
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
StrCmp $DO_UNINSTALL_V2 "" PRESERVE_DONE
@@ -966,7 +976,7 @@ StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)" CreateDirectory "$SMPROGRAMS\$INSTSHORTCUT"
SetOutPath "$INSTDIR"
CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT.lnk" \
- "$INSTDIR\$INSTEXE" "$INSTFLAGS $SHORTCUT_LANG_PARAM"
+ "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM"
WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Create Account.url" \
@@ -985,9 +995,9 @@ CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\Uninstall $INSTSHORTCUT.lnk" \ ; Other shortcuts
SetOutPath "$INSTDIR"
CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \
- "$INSTDIR\$INSTEXE" "$INSTFLAGS $SHORTCUT_LANG_PARAM"
+ "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM"
CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \
- "$INSTDIR\$INSTEXE" "$INSTFLAGS $SHORTCUT_LANG_PARAM"
+ "$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM"
CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \
'"$INSTDIR\uninst.exe"' ''
@@ -996,7 +1006,6 @@ CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \ ; Write registry
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "" "$INSTDIR"
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version" "${VERSION_LONG}"
-WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Flags" "$INSTFLAGS"
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Shortcut" "$INSTSHORTCUT"
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Exe" "$INSTEXE"
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayName" "$INSTPROG (remove only)"
@@ -1009,13 +1018,13 @@ WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "URL Protocol" "" WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}\DefaultIcon" "" '"$INSTDIR\$INSTEXE"'
;; URL param must be last item passed to viewer, it ignores subsequent params
;; to avoid parameter injection attacks.
-WriteRegExpandStr HKEY_CLASSES_ROOT "${URLNAME}\shell\open\command" "" '"$INSTDIR\$INSTEXE" $INSTFLAGS -url "%1"'
+WriteRegExpandStr HKEY_CLASSES_ROOT "${URLNAME}\shell\open\command" "" '"$INSTDIR\$INSTEXE" -url "%1"'
WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info"(default)" "URL:Second Life"
WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info" "URL Protocol" ""
WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$INSTEXE"'
;; URL param must be last item passed to viewer, it ignores subsequent params
;; to avoid parameter injection attacks.
-WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$INSTEXE" $INSTFLAGS -url "%1"'
+WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$INSTEXE" -url "%1"'
; write out uninstaller
WriteUninstaller "$INSTDIR\uninst.exe"
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 49f77e6c34..f150ceda67 100755 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -259,11 +259,9 @@ bool handleSlowMotionAnimation(const LLSD& newvalue) return true; } -// static -void LLAgent::parcelChangedCallback() +void LLAgent::setCanEditParcel() // called via mParcelChangedSignal { bool can_edit = LLToolMgr::getInstance()->canEdit(); - gAgent.mCanEditParcel = can_edit; } @@ -425,6 +423,8 @@ LLAgent::LLAgent() : mListener.reset(new LLAgentListener(*this)); + addParcelChangedCallback(&setCanEditParcel); + mMoveTimer.stop(); } @@ -451,8 +451,6 @@ void LLAgent::init() mLastKnownRequestMaturity = mLastKnownResponseMaturity; mIsDoSendMaturityPreferenceToServer = true; - LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback)); - if (!mTeleportFinishedSlot.connected()) { mTeleportFinishedSlot = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLAgent::handleTeleportFinished, this)); @@ -835,22 +833,33 @@ void LLAgent::handleServerBakeRegionTransition(const LLUUID& region_id) } } +void LLAgent::changeParcels() +{ + LL_DEBUGS("AgentLocation") << "Calling ParcelChanged callbacks" << LL_ENDL; + // Notify anything that wants to know about parcel changes + mParcelChangedSignal(); +} + +boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_callback_t cb) +{ + return mParcelChangedSignal.connect(cb); +} + //----------------------------------------------------------------------------- // setRegion() //----------------------------------------------------------------------------- void LLAgent::setRegion(LLViewerRegion *regionp) { - bool teleport = true; - + bool notifyRegionChange; + llassert(regionp); if (mRegionp != regionp) { - // std::string host_name; - // host_name = regionp->getHost().getHostName(); - + notifyRegionChange = true; + std::string ip = regionp->getHost().getString(); - llinfos << "Moving agent into region: " << regionp->getName() - << " located at " << ip << llendl; + LL_INFOS("AgentLocation") << "Moving agent into region: " << regionp->getName() + << " located at " << ip << LL_ENDL; if (mRegionp) { // We've changed regions, we're now going to change our agent coordinate frame. @@ -878,9 +887,6 @@ void LLAgent::setRegion(LLViewerRegion *regionp) { gSky.mVOGroundp->setRegion(regionp); } - - // Notify windlight managers - teleport = (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE); } else { @@ -902,8 +908,14 @@ void LLAgent::setRegion(LLViewerRegion *regionp) // Pass new region along to metrics components that care about this level of detail. LLAppViewer::metricsUpdateRegion(regionp->getHandle()); } + else + { + notifyRegionChange = false; + } mRegionp = regionp; + // TODO - most of what follows probably should be moved into callbacks + // Pass the region host to LLUrlEntryParcel to resolve parcel name // with a server request. LLUrlEntryParcel::setRegionHost(getRegionHost()); @@ -922,15 +934,6 @@ void LLAgent::setRegion(LLViewerRegion *regionp) LLFloaterMove::sUpdateFlyingStatus(); - if (teleport) - { - LLEnvManagerNew::instance().onTeleport(); - } - else - { - LLEnvManagerNew::instance().onRegionCrossing(); - } - // If the newly entered region is using server bakes, and our // current appearance is non-baked, request appearance update from // server. @@ -943,6 +946,12 @@ void LLAgent::setRegion(LLViewerRegion *regionp) // Need to handle via callback after caps arrive. mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::handleServerBakeRegionTransition,this,_1)); } + + if (notifyRegionChange) + { + LL_DEBUGS("AgentLocation") << "Calling RegionChanged callbacks" << LL_ENDL; + mRegionChangedSignal(); + } } @@ -967,6 +976,16 @@ LLHost LLAgent::getRegionHost() const } } +boost::signals2::connection LLAgent::addRegionChangedCallback(const region_changed_signal_t::slot_type& cb) +{ + return mRegionChangedSignal.connect(cb); +} + +void LLAgent::removeRegionChangedCallback(boost::signals2::connection callback) +{ + mRegionChangedSignal.disconnect(callback); +} + //----------------------------------------------------------------------------- // inPrelude() //----------------------------------------------------------------------------- @@ -1092,10 +1111,18 @@ const LLVector3d &LLAgent::getPositionGlobal() const //----------------------------------------------------------------------------- const LLVector3 &LLAgent::getPositionAgent() { - if (isAgentAvatarValid() && !gAgentAvatarp->mDrawable.isNull()) + if (isAgentAvatarValid()) + { + if(gAgentAvatarp->mDrawable.isNull()) + { + mFrameAgent.setOrigin(gAgentAvatarp->getPositionAgent()); + } + else { mFrameAgent.setOrigin(gAgentAvatarp->getRenderPosition()); } + } + return mFrameAgent.getOrigin(); } diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 7fac17d098..0766407494 100755 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -231,15 +231,54 @@ private: LLVector3 mHomePosRegion; //-------------------------------------------------------------------- - // Region + // Parcel //-------------------------------------------------------------------- public: + void changeParcels(); // called by LLViewerParcelMgr when we cross a parcel boundary + + // Register a boost callback to be called when the agent changes parcels + typedef boost::function<void()> parcel_changed_callback_t; + boost::signals2::connection addParcelChangedCallback(parcel_changed_callback_t); + +private: + typedef boost::signals2::signal<void()> parcel_changed_signal_t; + parcel_changed_signal_t mParcelChangedSignal; + + //-------------------------------------------------------------------- + // Region + //-------------------------------------------------------------------- + public: void setRegion(LLViewerRegion *regionp); LLViewerRegion *getRegion() const; LLHost getRegionHost() const; BOOL inPrelude(); -private: + + /** + * Register a boost callback to be called when the agent changes regions + * Note that if you need to access a capability for the region, you may need to wait + * for the capabilities to be received, since in some cases your region changed + * callback will be called before the capabilities have been received. Your callback + * may need to look something like: + * + * LLViewerRegion* region = gAgent.getRegion(); + * if (region->capabilitiesReceived()) + * { + * useCapability(region); + * } + * else // Need to handle via callback after caps arrive. + * { + * region->setCapabilitiesReceivedCallback(boost::bind(&useCapability,region,_1)); + * // you may or may not want to remove that callback + * } + */ + typedef boost::signals2::signal<void()> region_changed_signal_t; + + boost::signals2::connection addRegionChangedCallback(const region_changed_signal_t::slot_type& cb); + void removeRegionChangedCallback(boost::signals2::connection callback); + + private: LLViewerRegion *mRegionp; + region_changed_signal_t mRegionChangedSignal; //-------------------------------------------------------------------- // History @@ -640,9 +679,10 @@ private: public: bool canEditParcel() const { return mCanEditParcel; } private: + static void setCanEditParcel(); bool mCanEditParcel; - static void parcelChangedCallback(); + /******************************************************************************** ** ** diff --git a/indra/newview/llagentui.cpp b/indra/newview/llagentui.cpp index b9ec304b7e..3410a37890 100755 --- a/indra/newview/llagentui.cpp +++ b/indra/newview/llagentui.cpp @@ -112,6 +112,11 @@ BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt,const case LOCATION_FORMAT_NORMAL: buffer = llformat("%s", region_name.c_str()); break; + case LOCATION_FORMAT_NORMAL_COORDS: + buffer = llformat("%s (%d, %d, %d)", + region_name.c_str(), + pos_x, pos_y, pos_z); + break; case LOCATION_FORMAT_NO_COORDS: buffer = llformat("%s%s%s", region_name.c_str(), @@ -143,6 +148,11 @@ BOOL LLAgentUI::buildLocationString(std::string& str, ELocationFormat fmt,const case LOCATION_FORMAT_NORMAL: buffer = llformat("%s, %s", parcel_name.c_str(), region_name.c_str()); break; + case LOCATION_FORMAT_NORMAL_COORDS: + buffer = llformat("%s (%d, %d, %d)", + parcel_name.c_str(), + pos_x, pos_y, pos_z); + break; case LOCATION_FORMAT_NO_MATURITY: buffer = llformat("%s, %s (%d, %d, %d)", parcel_name.c_str(), diff --git a/indra/newview/llagentui.h b/indra/newview/llagentui.h index dda5dc1fd1..bb48dad14c 100755 --- a/indra/newview/llagentui.h +++ b/indra/newview/llagentui.h @@ -35,6 +35,7 @@ public: enum ELocationFormat { LOCATION_FORMAT_NORMAL, // Parcel + LOCATION_FORMAT_NORMAL_COORDS, // Parcel (x, y, z) LOCATION_FORMAT_LANDMARK, // Parcel, Region LOCATION_FORMAT_NO_MATURITY, // Parcel, Region (x, y, z) LOCATION_FORMAT_NO_COORDS, // Parcel, Region - Maturity diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp index 1edbbe2a2e..fa810aac76 100755 --- a/indra/newview/llagentwearables.cpp +++ b/indra/newview/llagentwearables.cpp @@ -1538,7 +1538,11 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj std::set<LLUUID> requested_item_ids; std::set<LLUUID> current_item_ids; for (S32 i=0; i<obj_item_array.count(); i++) - requested_item_ids.insert(obj_item_array[i].get()->getLinkedUUID()); + { + const LLUUID & requested_id = obj_item_array[i].get()->getLinkedUUID(); + //llinfos << "Requested attachment id " << requested_id << llendl; + requested_item_ids.insert(requested_id); + } // Build up list of objects to be removed and items currently attached. llvo_vec_t objects_to_remove; @@ -1555,17 +1559,28 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj if (objectp) { LLUUID object_item_id = objectp->getAttachmentItemID(); + + bool remove_attachment = true; if (requested_item_ids.find(object_item_id) != requested_item_ids.end()) - { - // Object currently worn, was requested. + { // Object currently worn, was requested to keep it // Flag as currently worn so we won't have to add it again. - current_item_ids.insert(object_item_id); + remove_attachment = false; } - else + else if (objectp->isTempAttachment()) + { // Check if we should keep this temp attachment + remove_attachment = LLAppearanceMgr::instance().shouldRemoveTempAttachment(objectp->getID()); + } + + if (remove_attachment) { - // object currently worn, not requested. + // llinfos << "found object to remove, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << llendl; objects_to_remove.push_back(objectp); } + else + { + // llinfos << "found object to keep, id " << objectp->getID() << ", item " << objectp->getAttachmentItemID() << llendl; + current_item_ids.insert(object_item_id); + } } } } diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 91251ed7c0..988058aad3 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -40,6 +40,11 @@ [super dealloc]; } +- (void) applicationWillFinishLaunching:(NSNotification *)notification +{ + [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; +} + - (void) applicationDidFinishLaunching:(NSNotification *)notification { frameTimer = nil; @@ -55,7 +60,7 @@ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil]; - [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; + // [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; } - (void) handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent { diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index fd9236c8b3..da1609297e 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -3415,21 +3415,50 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) llwarns << "called with empty list, nothing to do" << llendl; } for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it) - { + { const LLUUID& id_to_remove = *it; const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove); removeCOFItemLinks(linked_item_id); - } - updateAppearanceFromCOF(); + addDoomedTempAttachment(linked_item_id); } + updateAppearanceFromCOF(); +} void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove) { LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove); removeCOFItemLinks(linked_item_id); + addDoomedTempAttachment(linked_item_id); updateAppearanceFromCOF(); } + +// Adds the given item ID to mDoomedTempAttachmentIDs iff it's a temp attachment +void LLAppearanceMgr::addDoomedTempAttachment(const LLUUID& id_to_remove) +{ + LLViewerObject * attachmentp = gAgentAvatarp->findAttachmentByID(id_to_remove); + if (attachmentp && + attachmentp->isTempAttachment()) + { // If this is a temp attachment and we want to remove it, record the ID + // so it will be deleted when attachments are synced up with COF + mDoomedTempAttachmentIDs.insert(id_to_remove); + //llinfos << "Will remove temp attachment id " << id_to_remove << llendl; + } +} + +// Find AND REMOVES the given UUID from mDoomedTempAttachmentIDs +bool LLAppearanceMgr::shouldRemoveTempAttachment(const LLUUID& item_id) +{ + doomed_temp_attachments_t::iterator iter = mDoomedTempAttachmentIDs.find(item_id); + if (iter != mDoomedTempAttachmentIDs.end()) + { + mDoomedTempAttachmentIDs.erase(iter); + return true; + } + return false; +} + + bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body) { if (!item || !item->isWearableType()) return false; diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h index 46252afbde..5ec80f1cf0 100755 --- a/indra/newview/llappearancemgr.h +++ b/indra/newview/llappearancemgr.h @@ -142,6 +142,9 @@ public: void removeAllClothesFromAvatar(); void removeAllAttachmentsFromAvatar(); + // Special handling of temp attachments, which are not in the COF + bool shouldRemoveTempAttachment(const LLUUID& item_id); + //has the current outfit changed since it was loaded? bool isOutfitDirty() { return mOutfitIsDirty; } @@ -239,6 +242,12 @@ private: std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer; + // Set of temp attachment UUIDs that should be removed + typedef std::set<LLUUID> doomed_temp_attachments_t; + doomed_temp_attachments_t mDoomedTempAttachmentIDs; + + void addDoomedTempAttachment(const LLUUID& id_to_remove); + ////////////////////////////////////////////////////////////////////////////////// // Item-specific convenience functions public: diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f67142d1ed..e3c89f1a5f 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -40,6 +40,7 @@ #include "llagent.h" #include "llagentcamera.h" #include "llagentlanguage.h" +#include "llagentui.h" #include "llagentwearables.h" #include "llfloaterimcontainer.h" #include "llwindow.h" @@ -60,6 +61,7 @@ #include "llcurl.h" #include "llcalc.h" #include "llconversationlog.h" +#include "lldxhardware.h" #include "lltexturestats.h" #include "lltexturestats.h" #include "llviewerwindow.h" @@ -75,10 +77,10 @@ #include "lluicolortable.h" #include "llurldispatcher.h" #include "llurlhistory.h" -//#include "llfirstuse.h" #include "llrender.h" #include "llteleporthistory.h" #include "lltoast.h" +#include "llsdutil_math.h" #include "lllocationhistory.h" #include "llfasttimerview.h" #include "llvector4a.h" @@ -223,6 +225,10 @@ #include "llmachineid.h" #include "llmainlooprepeater.h" + +#include "llviewereventrecorder.h" + + // *FIX: These extern globals should be cleaned up. // The globals either represent state/config/resource-storage of either // this app, or another 'component' of the viewer. App globals should be @@ -696,6 +702,7 @@ LLAppViewer::LLAppViewer() : LLAppViewer::~LLAppViewer() { delete mSettingsLocationList; + LLViewerEventRecorder::instance().~LLViewerEventRecorder(); LLLoginInstance::instance().setUpdaterService(0); @@ -750,7 +757,7 @@ bool LLAppViewer::init() initLoggingAndGetLastDuration(); processMarkerFiles(); - + // // OK to write stuff to logs now, we've now crash reported if necessary // @@ -1225,8 +1232,8 @@ void LLAppViewer::checkMemory() } mMemCheckTimer.reset() ; - //update the availability of memory - LLMemory::updateMemoryInfo() ; + //update the availability of memory + LLMemory::updateMemoryInfo() ; bool is_low = LLMemory::isMemoryPoolLow() ; @@ -1756,7 +1763,7 @@ bool LLAppViewer::cleanup() gAudiop->setStreamingAudioImpl(NULL); // shut down the audio subsystem - gAudiop->shutdown(); + gAudiop->shutdown(); delete gAudiop; gAudiop = NULL; @@ -2250,13 +2257,13 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, BOOST_FOREACH(const SettingsFile& file, group.files) { - llinfos << "Attempting to load settings for the group " << file.name() - << " - from location " << location_key << llendl; + LL_INFOS("Settings") << "Attempting to load settings for the group " << file.name() + << " - from location " << location_key << LL_ENDL; LLControlGroup* settings_group = LLControlGroup::getInstance(file.name); if(!settings_group) { - llwarns << "No matching settings group for name " << file.name() << llendl; + LL_WARNS("Settings") << "No matching settings group for name " << file.name() << LL_ENDL; continue; } @@ -2285,7 +2292,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent)) { // success! - llinfos << "Loaded settings file " << full_settings_path << llendl; + LL_INFOS("Settings") << "Loaded settings file " << full_settings_path << LL_ENDL; } else { // failed to load @@ -2299,7 +2306,7 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, // only complain if we actually have a filename at this point if (!full_settings_path.empty()) { - llinfos << "Cannot load " << full_settings_path << " - No settings found." << llendl; + LL_INFOS("Settings") << "Cannot load " << full_settings_path << " - No settings found." << LL_ENDL; } } } @@ -2395,8 +2402,6 @@ bool LLAppViewer::initConfiguration() gSavedSettings.setString("ClientSettingsFile", gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global"))); - gSavedSettings.setString("VersionChannelName", LLVersionInfo::getChannel()); - #ifndef LL_RELEASE_FOR_DOWNLOAD // provide developer build only overrides for these control variables that are not // persisted to settings.xml @@ -2460,8 +2465,8 @@ bool LLAppViewer::initConfiguration() gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, clp.getOption("settings")[0]); gSavedSettings.setString("ClientSettingsFile", user_settings_filename); - llinfos << "Using command line specified settings filename: " - << user_settings_filename << llendl; + LL_INFOS("Settings") << "Using command line specified settings filename: " + << user_settings_filename << LL_ENDL; } // - load overrides from user_settings @@ -2477,8 +2482,8 @@ bool LLAppViewer::initConfiguration() { std::string session_settings_filename = clp.getOption("sessionsettings")[0]; gSavedSettings.setString("SessionSettingsFile", session_settings_filename); - llinfos << "Using session settings filename: " - << session_settings_filename << llendl; + LL_INFOS("Settings") << "Using session settings filename: " + << session_settings_filename << LL_ENDL; } loadSettingsFromDirectory("Session"); @@ -2486,8 +2491,8 @@ bool LLAppViewer::initConfiguration() { std::string user_session_settings_filename = clp.getOption("usersessionsettings")[0]; gSavedSettings.setString("UserSessionSettingsFile", user_session_settings_filename); - llinfos << "Using user session settings filename: " - << user_session_settings_filename << llendl; + LL_INFOS("Settings") << "Using user session settings filename: " + << user_session_settings_filename << LL_ENDL; } loadSettingsFromDirectory("UserSession"); @@ -2571,8 +2576,12 @@ bool LLAppViewer::initConfiguration() { llwarns << "Failed --set " << name << ": setting name unknown." << llendl; } + } } } + + if (clp.hasOption("logevents")) { + LLViewerEventRecorder::instance().setEventLoggingOn(); } std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel")); @@ -2593,11 +2602,11 @@ bool LLAppViewer::initConfiguration() std::string test_name(gSavedSettings.getString("LogMetrics")); if (! test_name.empty()) { - LLFastTimer::sMetricLog = TRUE ; + LLFastTimer::sMetricLog = TRUE ; // '--logmetrics' is specified with a named test metric argument so the data gathering is done only on that test // In the absence of argument, every metric would be gathered (makes for a rather slow run and hard to decipher report...) llinfos << "'--logmetrics' argument : " << test_name << llendl; - LLFastTimer::sLogName = test_name; + LLFastTimer::sLogName = test_name; } if (clp.hasOption("graphicslevel")) @@ -2645,17 +2654,33 @@ bool LLAppViewer::initConfiguration() // What can happen is that someone can use IE (or potentially // other browsers) and do the rough equivalent of command // injection and steal passwords. Phoenix. SL-55321 + LLSLURL start_slurl; std::string CmdLineLoginLocation(gSavedSettings.getString("CmdLineLoginLocation")); if(! CmdLineLoginLocation.empty()) { - LLSLURL start_slurl(CmdLineLoginLocation); + start_slurl = CmdLineLoginLocation; LLStartUp::setStartSLURL(start_slurl); if(start_slurl.getType() == LLSLURL::LOCATION) - { + { LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid()); } } + //RN: if we received a URL, hand it off to the existing instance. + // don't call anotherInstanceRunning() when doing URL handoff, as + // it relies on checking a marker file which will not work when running + // out of different directories + + if (start_slurl.isValid() && + (gSavedSettings.getBOOL("SLURLPassToOtherInstance"))) + { + if (sendURLToOtherInstance(start_slurl.getSLURLString())) + { + // successfully handed off URL to existing instance, exit + return false; + } + } + const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent"); if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString()) { @@ -2795,7 +2820,7 @@ bool LLAppViewer::initConfiguration() LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL; LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation)); } - else if ((clp.hasOption("login") || clp.hasOption("autologin")) + else if ( ( clp.hasOption("login") || clp.hasOption("autologin")) && gSavedSettings.getString("CmdLineLoginLocation").empty()) { // If automatic login from command line with --login switch @@ -2971,26 +2996,26 @@ namespace { { LL_WARNS("UpdaterService") << "no info url supplied - defaulting to hard coded release notes pattern" << LL_ENDL; - // truncate version at the rightmost '.' - std::string version_short(data["version"]); - size_t short_length = version_short.rfind('.'); - if (short_length != std::string::npos) - { - version_short.resize(short_length); - } + // truncate version at the rightmost '.' + std::string version_short(data["version"]); + size_t short_length = version_short.rfind('.'); + if (short_length != std::string::npos) + { + version_short.resize(short_length); + } - LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]"); - relnotes_url.setArg("[VERSION_SHORT]", version_short); + LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]"); + relnotes_url.setArg("[VERSION_SHORT]", version_short); - // *TODO thread the update service's response through to this point - std::string const & channel = LLVersionInfo::getChannel(); - boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free); + // *TODO thread the update service's response through to this point + std::string const & channel = LLVersionInfo::getChannel(); + boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free); - relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get()); - relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL")); + relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get()); + relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL")); substitutions["INFO_URL"] = relnotes_url.getString(); } - + LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback); } @@ -3238,6 +3263,183 @@ void LLAppViewer::writeDebugInfo() out_file.close(); } +LLSD LLAppViewer::getViewerInfo() const +{ + // The point of having one method build an LLSD info block and the other + // construct the user-visible About string is to ensure that the same info + // is available to a getInfo() caller as to the user opening + // LLFloaterAbout. + LLSD info; + LLSD version; + version.append(LLVersionInfo::getMajor()); + version.append(LLVersionInfo::getMinor()); + version.append(LLVersionInfo::getPatch()); + version.append(LLVersionInfo::getBuild()); + info["VIEWER_VERSION"] = version; + info["VIEWER_VERSION_STR"] = LLVersionInfo::getVersion(); + info["BUILD_DATE"] = __DATE__; + info["BUILD_TIME"] = __TIME__; + info["CHANNEL"] = LLVersionInfo::getChannel(); + + // return a URL to the release notes for this viewer, such as: + // http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0.123456 + std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL"); + if (! LLStringUtil::endsWith(url, "/")) + url += "/"; + url += LLURI::escape(LLVersionInfo::getChannel()) + "/"; + url += LLURI::escape(LLVersionInfo::getVersion()); + + info["VIEWER_RELEASE_NOTES_URL"] = url; + +#if LL_MSVC + info["COMPILER"] = "MSVC"; + info["COMPILER_VERSION"] = _MSC_VER; +#elif LL_GNUC + info["COMPILER"] = "GCC"; + info["COMPILER_VERSION"] = GCC_VERSION; +#endif + + // Position + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + LLVector3d pos = gAgent.getPositionGlobal(); + info["POSITION"] = ll_sd_from_vector3d(pos); + info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos)); + info["REGION"] = gAgent.getRegion()->getName(); + info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName(); + info["HOSTIP"] = gAgent.getRegion()->getHost().getString(); + info["SERVER_VERSION"] = gLastVersionChannel; + LLSLURL slurl; + LLAgentUI::buildSLURL(slurl); + info["SLURL"] = slurl.getSLURLString(); + } + + // CPU + info["CPU"] = gSysCPU.getCPUString(); + info["MEMORY_MB"] = LLSD::Integer(gSysMemory.getPhysicalMemoryKB() / 1024); + // Moved hack adjustment to Windows memory size into llsys.cpp + info["OS_VERSION"] = LLAppViewer::instance()->getOSInfo().getOSString(); + info["GRAPHICS_CARD_VENDOR"] = (const char*)(glGetString(GL_VENDOR)); + info["GRAPHICS_CARD"] = (const char*)(glGetString(GL_RENDERER)); + +#if LL_WINDOWS + LLSD driver_info = gDXHardware.getDisplayInfo(); + if (driver_info.has("DriverVersion")) + { + info["GRAPHICS_DRIVER_VERSION"] = driver_info["DriverVersion"]; + } +#endif + + info["OPENGL_VERSION"] = (const char*)(glGetString(GL_VERSION)); + info["LIBCURL_VERSION"] = LLCurl::getVersionString(); + info["J2C_VERSION"] = LLImageJ2C::getEngineInfo(); + bool want_fullname = true; + info["AUDIO_DRIVER_VERSION"] = gAudiop ? LLSD(gAudiop->getDriverName(want_fullname)) : LLSD(); + if(LLVoiceClient::getInstance()->voiceEnabled()) + { + LLVoiceVersionInfo version = LLVoiceClient::getInstance()->getVersion(); + std::ostringstream version_string; + version_string << version.serverType << " " << version.serverVersion << std::endl; + info["VOICE_VERSION"] = version_string.str(); + } + else + { + info["VOICE_VERSION"] = LLTrans::getString("NotConnected"); + } + + // TODO: Implement media plugin version query + info["QT_WEBKIT_VERSION"] = "4.7.1 (version number hard-coded)"; + + if (gPacketsIn > 0) + { + info["PACKETS_LOST"] = LLViewerStats::getInstance()->mPacketsLostStat.getCurrent(); + info["PACKETS_IN"] = F32(gPacketsIn); + info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal(); + } + + if (mServerReleaseNotesURL.empty()) + { + if (gAgent.getRegion()) + { + info["SERVER_RELEASE_NOTES_URL"] = LLTrans::getString("RetrievingData"); + } + } + else if (LLStringUtil::startsWith(mServerReleaseNotesURL, "http")) // it's an URL + { + info["SERVER_RELEASE_NOTES_URL"] = "[" + LLWeb::escapeURL(mServerReleaseNotesURL) + " " + LLTrans::getString("ReleaseNotes") + "]"; + } + else + { + info["SERVER_RELEASE_NOTES_URL"] = mServerReleaseNotesURL; + } + + return info; +} + +std::string LLAppViewer::getViewerInfoString() const +{ + std::ostringstream support; + + LLSD info(getViewerInfo()); + + // Render the LLSD from getInfo() as a format_map_t + LLStringUtil::format_map_t args; + + // allow the "Release Notes" URL label to be localized + args["ReleaseNotes"] = LLTrans::getString("ReleaseNotes"); + + for (LLSD::map_const_iterator ii(info.beginMap()), iend(info.endMap()); + ii != iend; ++ii) + { + if (! ii->second.isArray()) + { + // Scalar value + if (ii->second.isUndefined()) + { + args[ii->first] = LLTrans::getString("none_text"); + } + else + { + // don't forget to render value asString() + args[ii->first] = ii->second.asString(); + } + } + else + { + // array value: build KEY_0, KEY_1 etc. entries + for (LLSD::Integer n(0), size(ii->second.size()); n < size; ++n) + { + args[STRINGIZE(ii->first << '_' << n)] = ii->second[n].asString(); + } + } + } + + // Now build the various pieces + support << LLTrans::getString("AboutHeader", args); + if (info.has("REGION")) + { + support << "\n\n" << LLTrans::getString("AboutPosition", args); + } + support << "\n\n" << LLTrans::getString("AboutSystem", args); + support << "\n"; + if (info.has("GRAPHICS_DRIVER_VERSION")) + { + support << "\n" << LLTrans::getString("AboutDriver", args); + } + support << "\n" << LLTrans::getString("AboutLibs", args); + if (info.has("COMPILER")) + { + support << "\n" << LLTrans::getString("AboutCompiler", args); + } + if (info.has("PACKETS_IN")) + { + support << '\n' << LLTrans::getString("AboutTraffic", args); + } + return support.str(); +} + + void LLAppViewer::cleanupSavedSettings() { gSavedSettings.setBOOL("MouseSun", FALSE); @@ -3462,9 +3664,9 @@ void LLAppViewer::handleViewerCrash() if (gDirUtilp) { std::string crash_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, - gLLErrorActivated - ? LLERROR_MARKER_FILE_NAME - : ERROR_MARKER_FILE_NAME); + gLLErrorActivated + ? LLERROR_MARKER_FILE_NAME + : ERROR_MARKER_FILE_NAME); LLAPRFile crash_marker_file ; crash_marker_file.open(crash_marker_file_name, LL_APR_WB); if (crash_marker_file.getFileHandle()) @@ -3475,7 +3677,7 @@ void LLAppViewer::handleViewerCrash() else { LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_marker_file_name << LL_ENDL; - } + } } else { @@ -3614,7 +3816,7 @@ void LLAppViewer::processMarkerFiles() } if (mSecondInstance) - { + { LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' owned by another instance" << LL_ENDL; } else if (marker_is_same_version) @@ -3628,7 +3830,7 @@ void LLAppViewer::processMarkerFiles() { LL_INFOS("MarkerFile") << "Exec marker '"<< mMarkerFileName << "' found, but versions did not match" << LL_ENDL; } - } + } else // marker did not exist... last exec (if any) did not freeze { // Create the marker file for this execution & lock it; it will be deleted on a clean exit @@ -3682,12 +3884,12 @@ void LLAppViewer::processMarkerFiles() { gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL; - } - else - { + } + else + { gLastExecEvent = LAST_EXEC_LLERROR_CRASH; LL_INFOS("MarkerFile") << "LLError marker '"<< llerror_marker_file << "' crashed, setting LastExecEvent to LLERROR_CRASH" << LL_ENDL; - } + } } else { @@ -3700,20 +3902,20 @@ void LLAppViewer::processMarkerFiles() if(LLAPRFile::isExist(error_marker_file, NULL, LL_APR_RB)) { if (markerIsSameVersion(error_marker_file)) - { + { if (gLastExecEvent == LAST_EXEC_LOGOUT_FROZE) - { + { gLastExecEvent = LAST_EXEC_LOGOUT_CRASH; LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to LOGOUT_CRASH" << LL_ENDL; - } - else - { - gLastExecEvent = LAST_EXEC_OTHER_CRASH; - LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; - } } else { + gLastExecEvent = LAST_EXEC_OTHER_CRASH; + LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' crashed, setting LastExecEvent to " << gLastExecEvent << LL_ENDL; + } + } + else + { LL_INFOS("MarkerFile") << "Error marker '"<< error_marker_file << "' marker found, but versions did not match" << LL_ENDL; } LLAPRFile::remove(error_marker_file); @@ -3725,29 +3927,29 @@ void LLAppViewer::removeMarkerFile(bool leave_logout_marker) if (!mSecondInstance) { LL_DEBUGS("MarkerFile") << (leave_logout_marker?"leave":"remove") <<" logout" << LL_ENDL; - if (mMarkerFile.getFileHandle()) - { + if (mMarkerFile.getFileHandle()) + { LL_DEBUGS("MarkerFile") << "removing exec marker '"<<mMarkerFileName<<"'"<< LL_ENDL; mMarkerFile.close() ; - LLAPRFile::remove( mMarkerFileName ); - } - else - { + LLAPRFile::remove( mMarkerFileName ); + } + else + { LL_WARNS("MarkerFile") << "marker '"<<mMarkerFileName<<"' not open"<< LL_ENDL; - } - if (!leave_logout_marker) + } + if (!leave_logout_marker) + { + if (mLogoutMarkerFile.getFileHandle()) { - if (mLogoutMarkerFile.getFileHandle()) - { LL_DEBUGS("MarkerFile") << "removing logout marker '"<<mLogoutMarkerFileName<<"'"<< LL_ENDL; - mLogoutMarkerFile.close(); - } - else - { + mLogoutMarkerFile.close(); + } + else + { LL_WARNS("MarkerFile") << "logout marker '"<<mLogoutMarkerFileName<<"' not open"<< LL_ENDL; - } - LLAPRFile::remove( mLogoutMarkerFileName ); } + LLAPRFile::remove( mLogoutMarkerFileName ); + } } else { @@ -4690,7 +4892,7 @@ void LLAppViewer::idle() if (!(logoutRequestSent() && hasSavedFinalSnapshot())) { - gObjectList.update(gAgent, *LLWorld::getInstance()); + gObjectList.update(gAgent); } } @@ -5379,7 +5581,7 @@ void LLAppViewer::handleLoginComplete() void LLAppViewer::launchUpdater() { - LLSD query_map = LLSD::emptyMap(); + LLSD query_map = LLSD::emptyMap(); query_map["os"] = gPlatform; // *TODO change userserver to be grid on both viewer and sim, since @@ -5576,7 +5778,7 @@ void LLAppViewer::metricsSend(bool enable_reporting) // Make a copy of the main stats to send into another thread. // Receiving thread takes ownership. LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStatsMain)); - + // Send a report request into 'thread1' to get the rest of the data // and provide some additional parameters while here. LLAppViewer::sTextureFetch->commandSendMetrics(caps_url, diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 3ae8a78845..05326c2baf 100755 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -86,6 +86,10 @@ public: const LLOSInfo& getOSInfo() const { return mSysOSInfo; } + void setServerReleaseNotesURL(const std::string& url) { mServerReleaseNotesURL = url; } + LLSD getViewerInfo() const; + std::string getViewerInfoString() const; + // Report true if under the control of a debugger. A null-op default. virtual bool beingDebugged() { return false; } @@ -246,6 +250,8 @@ private: LLOSInfo mSysOSInfo; bool mReportedCrash; + std::string mServerReleaseNotesURL; + // Thread objects. static LLTextureCache* sTextureCache; static LLImageDecodeThread* sImageDecodeThread; diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 3cf3c739d9..2764025d75 100755 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -172,21 +172,20 @@ void ll_nvapi_init(NvDRSSessionHandle hSession) nvapi_error(status); return; } + + // (5) Now we apply (or save) our changes to the system + status = NvAPI_DRS_SaveSettings(hSession); + if (status != NVAPI_OK) + { + nvapi_error(status); + return; + } } else if (status != NVAPI_OK) { nvapi_error(status); return; } - - - - // (5) Now we apply (or save) our changes to the system - status = NvAPI_DRS_SaveSettings(hSession); - if (status != NVAPI_OK) - { - nvapi_error(status); - } } //#define DEBUGGING_SEH_FILTER 1 @@ -201,14 +200,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, LPSTR lpCmdLine, int nCmdShow) { -#ifdef INCLUDE_VLD - // only works for debug builds (hard coded into vld.h) - #ifdef _DEBUG - // start with Visual Leak Detector turned off - VLDGlobalDisable(); - #endif // _DEBUG -#endif // INCLUDE_VLD - const S32 MAX_HEAPS = 255; DWORD heap_enable_lfh_error[MAX_HEAPS]; S32 num_heaps = 0; diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp index 1d72397cbc..dd9354fe3a 100755 --- a/indra/newview/llautoreplace.cpp +++ b/indra/newview/llautoreplace.cpp @@ -39,7 +39,7 @@ void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement replacement_length = 0; replacement_string.clear(); - static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace"); + static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace", 0); if (perform_autoreplace) { S32 word_end = cursor_pos - 1; @@ -679,7 +679,7 @@ bool LLAutoReplaceSettings::decreaseListPriority(std::string listName) std::string LLAutoReplaceSettings::replaceWord(const std::string currentWord) { std::string returnedWord = currentWord; // in case no replacement is found - static LLCachedControl<bool> autoreplace_enabled(gSavedSettings, "AutoReplace"); + static LLCachedControl<bool> autoreplace_enabled(gSavedSettings, "AutoReplace", false); if ( autoreplace_enabled ) { LL_DEBUGS("AutoReplace")<<"checking '"<<currentWord<<"'"<< LL_ENDL; diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index b513a52ff7..70cc48f12b 100755 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -73,6 +73,8 @@ #include "llcallingcard.h" #include "llslurl.h" // IDEVO #include "llsidepanelinventory.h" +#include "llavatarname.h" +#include "llagentui.h" // static void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name) @@ -391,6 +393,72 @@ void LLAvatarActions::pay(const LLUUID& id) } } +void LLAvatarActions::teleport_request_callback(const LLSD& notification, const LLSD& response) +{ + S32 option; + if (response.isInteger()) + { + option = response.asInteger(); + } + else + { + option = LLNotificationsUtil::getSelectedOption(notification, response); + } + + if (0 == option) + { + LLMessageSystem* msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_ImprovedInstantMessage); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + + msg->nextBlockFast(_PREHASH_MessageBlock); + msg->addBOOLFast(_PREHASH_FromGroup, FALSE); + msg->addUUIDFast(_PREHASH_ToAgentID, notification["substitutions"]["uuid"] ); + msg->addU8Fast(_PREHASH_Offline, IM_ONLINE); + msg->addU8Fast(_PREHASH_Dialog, IM_TELEPORT_REQUEST); + msg->addUUIDFast(_PREHASH_ID, LLUUID::null); + msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary + + std::string name; + LLAgentUI::buildFullname(name); + + msg->addStringFast(_PREHASH_FromAgentName, name); + msg->addStringFast(_PREHASH_Message, response["message"]); + msg->addU32Fast(_PREHASH_ParentEstateID, 0); + msg->addUUIDFast(_PREHASH_RegionID, LLUUID::null); + msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent()); + + gMessageSystem->addBinaryDataFast( + _PREHASH_BinaryBucket, + EMPTY_BINARY_BUCKET, + EMPTY_BINARY_BUCKET_SIZE); + + gAgent.sendReliableMessage(); + } +} + +// static +void LLAvatarActions::teleportRequest(const LLUUID& id) +{ + LLSD notification; + notification["uuid"] = id; + LLAvatarName av_name; + if (!LLAvatarNameCache::get(id, &av_name)) + { + // unlikely ... they just picked this name from somewhere... + LLAvatarNameCache::get(id, boost::bind(&LLAvatarActions::teleportRequest, id)); + return; // reinvoke this when the name resolves + } + notification["NAME"] = av_name.getCompleteName(); + + LLSD payload; + + LLNotificationsUtil::add("TeleportRequestPrompt", notification, payload, teleport_request_callback); +} + // static void LLAvatarActions::kick(const LLUUID& id) { diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h index 6e1198cd09..403414558e 100755 --- a/indra/newview/llavataractions.h +++ b/indra/newview/llavataractions.h @@ -111,6 +111,12 @@ public: static void pay(const LLUUID& id); /** + * Request teleport from other avatar + */ + static void teleportRequest(const LLUUID& id); + static void teleport_request_callback(const LLSD& notification, const LLSD& response); + + /** * Share items with the avatar. */ static void share(const LLUUID& id); diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index 9e3225a264..d6a72b0c05 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -256,7 +256,7 @@ void LLAvatarRenderInfoAccountant::sendRenderInfoToRegion(LLViewerRegion * regio { llinfos << "LRI: Sending avatar render info for " << avatar->getID() << ": " << info << llendl; - llinfos << "LRI: geometry " << avatar->getAttachmentGeometryBytes() + llinfos << "LRI: other info geometry " << avatar->getAttachmentGeometryBytes() << ", area " << avatar->getAttachmentSurfaceArea() << llendl; } @@ -336,7 +336,7 @@ void LLAvatarRenderInfoAccountant::idle() sRenderInfoReportTimer.resetWithExpiry(SECS_BETWEEN_REGION_SCANS); } - static LLCachedControl<U32> render_auto_mute_functions(gSavedSettings, "RenderAutoMuteFunctions"); + static LLCachedControl<U32> render_auto_mute_functions(gSavedSettings, "RenderAutoMuteFunctions", 0); static U32 prev_render_auto_mute_functions = (U32) -1; if (prev_render_auto_mute_functions != render_auto_mute_functions) { diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp index 066cb71677..3849fbeb54 100755 --- a/indra/newview/llblocklist.cpp +++ b/indra/newview/llblocklist.cpp @@ -41,10 +41,14 @@ static const LLBlockListNameTypeComparator NAME_TYPE_COMPARATOR; LLBlockList::LLBlockList(const Params& p) : LLFlatListViewEx(p), mSelectedItem(NULL), - mDirty(true) + mDirty(true), + mShouldAddAll(true), + mActionType(NONE), + mMuteListSize(0) { LLMuteList::getInstance()->addObserver(this); + mMuteListSize = LLMuteList::getInstance()->getMutes().size(); // Set up context menu. LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; @@ -73,6 +77,41 @@ LLBlockList::~LLBlockList() LLMuteList::getInstance()->removeObserver(this); } +void LLBlockList::createList() +{ + std::vector<LLMute> mutes = LLMuteList::instance().getMutes(); + std::vector<LLMute>::const_iterator mute_it = mutes.begin(); + + for (; mute_it != mutes.end(); ++mute_it) + { + addNewItem(&*mute_it); + } +} + +BlockListActionType LLBlockList::getCurrentMuteListActionType() +{ + BlockListActionType type = NONE; + U32 curSize = LLMuteList::getInstance()->getMutes().size(); + if( curSize > mMuteListSize) + type = ADD; + else if(curSize < mMuteListSize) + type = REMOVE; + + return type; +} + +void LLBlockList::onChangeDetailed(const LLMute &mute) +{ + mActionType = getCurrentMuteListActionType(); + + mCurItemId = mute.mID; + mCurItemName = mute.mName; + mCurItemType = mute.mType; + mCurItemFlags = mute.mFlags; + + refresh(); +} + BOOL LLBlockList::handleRightMouseDown(S32 x, S32 y, MASK mask) { BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask); @@ -88,6 +127,16 @@ BOOL LLBlockList::handleRightMouseDown(S32 x, S32 y, MASK mask) return handled; } +void LLBlockList::removeListItem(const LLMute* mute) +{ + removeItemByUUID(mute->mID); +} + +void LLBlockList::hideListItem(LLBlockedListItem* item, bool show) +{ + item->setVisible(show); +} + void LLBlockList::setNameFilter(const std::string& filter) { std::string filter_upper = filter; @@ -136,28 +185,56 @@ void LLBlockList::refresh() bool have_filter = !mNameFilter.empty(); // save selection to restore it after list rebuilt - LLUUID selected = getSelectedUUID(); + LLUUID selected = getSelectedUUID(), next_selected; - // calling refresh may be initiated by removing currently selected item - // so select next item and save the selection to restore it after list rebuilt + if(mShouldAddAll) // creating list of blockers + { + clear(); + createList(); + mShouldAddAll = false; + } + else + { + // handle remove/add functionality + LLMute mute(mCurItemId, mCurItemName, mCurItemType, mCurItemFlags); + if(mActionType == ADD) + { + addNewItem(&mute); + } + else if(mActionType == REMOVE) + { + if(selected == mute.mID) + { + // we are going to remove currently selected item, so select next item and save the selection to restore it if (!selectNextItemPair(false, true)) { selectNextItemPair(true, true); } - LLUUID next_selected = getSelectedUUID(); - - clear(); - - std::vector<LLMute> mutes = LLMuteList::instance().getMutes(); - std::vector<LLMute>::const_iterator mute_it = mutes.begin(); + next_selected = getSelectedUUID(); + } + removeListItem(&mute); + } + mActionType = NONE; + } - for (; mute_it != mutes.end(); ++mute_it) + // handle filter functionality + if(have_filter || (!have_filter && !mPrevNameFilter.empty())) { - if (have_filter && !findInsensitive(mute_it->mName, mNameFilter)) - continue; + // we should update visibility of our items if previous filter was not empty + std::vector < LLPanel* > allItems; + getItems(allItems); + std::vector < LLPanel* >::iterator it = allItems.begin(); - addNewItem(&*mute_it); + for(; it != allItems.end() ; ++it) + { + LLBlockedListItem * curItem = dynamic_cast<LLBlockedListItem *> (*it); + if(curItem) + { + hideListItem(curItem, findInsensitive(curItem->getName(), mNameFilter)); + } + } } + mPrevNameFilter = mNameFilter; if (getItemPair(selected)) { @@ -169,6 +246,7 @@ void LLBlockList::refresh() // previously selected item was removed, so select next item selectItemPair(getItemPair(next_selected), true); } + mMuteListSize = LLMuteList::getInstance()->getMutes().size(); // Sort the list. sort(); diff --git a/indra/newview/llblocklist.h b/indra/newview/llblocklist.h index 1a215710f4..bac79f869e 100755 --- a/indra/newview/llblocklist.h +++ b/indra/newview/llblocklist.h @@ -34,6 +34,8 @@ class LLBlockedListItem; class LLMute; +enum BlockListActionType {NONE, ADD, REMOVE}; + /** * List of blocked avatars and objects. * This list represents contents of the LLMuteList. @@ -56,7 +58,8 @@ public: LLToggleableMenu* getContextMenu() const { return mContextMenu.get(); } LLBlockedListItem* getBlockedItem() const; - virtual void onChange() { refresh(); } + virtual void onChange() { } + virtual void onChangeDetailed(const LLMute& ); virtual void draw(); void setNameFilter(const std::string& filter); @@ -67,18 +70,32 @@ public: private: void addNewItem(const LLMute* mute); + void removeListItem(const LLMute* mute); + void hideListItem(LLBlockedListItem* item, bool show); void setDirty(bool dirty = true) { mDirty = dirty; } bool findInsensitive(std::string haystack, const std::string& needle_upper); bool isActionEnabled(const LLSD& userdata); void onCustomAction (const LLSD& userdata); + void createList(); + BlockListActionType getCurrentMuteListActionType(); LLHandle<LLToggleableMenu> mContextMenu; LLBlockedListItem* mSelectedItem; std::string mNameFilter; bool mDirty; + bool mShouldAddAll; + BlockListActionType mActionType; + U32 mMuteListSize; + + // This data is used to save information about item that currently changed(added or removed) + LLUUID mCurItemId; + std::string mCurItemName; + LLMute::EType mCurItemType; + U32 mCurItemFlags; + std::string mPrevNameFilter; }; diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 14583e402d..91741c2a77 100755 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp |
