diff options
Diffstat (limited to 'indra')
86 files changed, 4335 insertions, 4378 deletions
| diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt index 310e6cbdd4..d1042d6e86 100644 --- a/indra/CMakeLists.txt +++ b/indra/CMakeLists.txt @@ -35,8 +35,10 @@ endif (NOT CMAKE_BUILD_TYPE)  # For the library installation process;  # see cmake/Prebuild.cmake for the counterpart code. -file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/temp) -file(WRITE ${CMAKE_BINARY_DIR}/temp/sentinel_installed "0") +if ("${CMAKE_SOURCE_DIR}/../autobuild.xml" IS_NEWER_THAN "${CMAKE_BINARY_DIR}/temp/sentinel_installed") +  file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/temp) +  file(WRITE ${CMAKE_BINARY_DIR}/temp/sentinel_installed "0") +endif ("${CMAKE_SOURCE_DIR}/../autobuild.xml" IS_NEWER_THAN "${CMAKE_BINARY_DIR}/temp/sentinel_installed")  add_subdirectory(cmake)  add_subdirectory(${LIBS_OPEN_PREFIX}llaudio) diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake index 15b827b217..faffdc8ccd 100644 --- a/indra/cmake/00-Common.cmake +++ b/indra/cmake/00-Common.cmake @@ -36,6 +36,13 @@ if (WINDOWS)    # Don't build DLLs.    set(BUILD_SHARED_LIBS OFF) +  # for "backwards compatibility", cmake sneaks in the Zm1000 option which royally +  # screws incredibuild. this hack disables it. +  # for details see: http://connect.microsoft.com/VisualStudio/feedback/details/368107/clxx-fatal-error-c1027-inconsistent-values-for-ym-between-creation-and-use-of-precompiled-headers +  # http://www.ogre3d.org/forums/viewtopic.php?f=2&t=60015 +  # http://www.cmake.org/pipermail/cmake/2009-September/032143.html +  string(REPLACE "/Zm1000" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) +    set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP -D_SCL_SECURE_NO_WARNINGS=1"        CACHE STRING "C++ compiler debug options" FORCE)    set(CMAKE_CXX_FLAGS_RELWITHDEBINFO  diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake index 3f259f6382..08feab6e36 100644 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -95,7 +95,7 @@ INCLUDE(GoogleMock)      IF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)        SET(${name}_test_additional_INCLUDE_DIRS "")      ENDIF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND) -    INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${name}_test_additional_INCLUDE_DIRS ) +    INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${${name}_test_additional_INCLUDE_DIRS} )      IF(LL_TEST_VERBOSE)        MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}")      ENDIF(LL_TEST_VERBOSE) diff --git a/indra/cmake/Prebuilt.cmake b/indra/cmake/Prebuilt.cmake index 1b60d176f1..dbb4dfc46c 100644 --- a/indra/cmake/Prebuilt.cmake +++ b/indra/cmake/Prebuilt.cmake @@ -1,35 +1,49 @@  # -*- cmake -*-  include(FindAutobuild) +if(INSTALL_PROPRIETARY) +  include(FindSCP) +endif(INSTALL_PROPRIETARY) +# The use_prebuilt_binary macro handles automated installation of package +# dependencies using autobuild.  The goal is that 'autobuild install' should +# only be run when we know we need to install a new package.  This should be +# the case in a clean checkout, or if autobuild.xml has been updated since the +# last run (encapsulated by the file ${CMAKE_BINARY_DIR}/temp/sentinel_installed), +# or if a previous attempt to install the package has failed (the exit status +# of previous attempts is serialized in the file +# ${CMAKE_BINARY_DIR}/temp/${_binary}_installed)  macro (use_prebuilt_binary _binary)    if (NOT DEFINED STANDALONE_${_binary})      set(STANDALONE_${_binary} ${STANDALONE})    endif (NOT DEFINED STANDALONE_${_binary})    if (NOT STANDALONE_${_binary}) -    if(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed) -      if(INSTALL_PROPRIETARY) -        include(FindSCP) -      endif(INSTALL_PROPRIETARY) -	  if(DEBUG_PREBUILT) -		message("cd ${CMAKE_SOURCE_DIR} && ${AUTOBUILD_EXECUTABLE} install -		--install-dir=${AUTOBUILD_INSTALL_DIR} -		--skip-license-check -		${_binary} ") -	  endif(DEBUG_PREBUILT) -	  execute_process(COMMAND "${AUTOBUILD_EXECUTABLE}" -		install -		--install-dir=${AUTOBUILD_INSTALL_DIR} -		--skip-license-check -		${_binary} -		WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" -		RESULT_VARIABLE ${_binary}_installed -		) +    if("${${_binary}_installed}" STREQUAL "" AND EXISTS "${CMAKE_BINARY_DIR}/temp/${_binary}_installed") +      file(READ ${CMAKE_BINARY_DIR}/temp/${_binary}_installed "${_binary}_installed") +      if(DEBUG_PREBUILT) +        message(STATUS "${_binary}_installed: \"${${_binary}_installed}\"") +      endif(DEBUG_PREBUILT) +    endif("${${_binary}_installed}" STREQUAL "" AND EXISTS "${CMAKE_BINARY_DIR}/temp/${_binary}_installed") + +    if(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed OR NOT ${${_binary}_installed} EQUAL 0) +      if(DEBUG_PREBUILT) +        message("cd ${CMAKE_SOURCE_DIR} && ${AUTOBUILD_EXECUTABLE} install +        --install-dir=${AUTOBUILD_INSTALL_DIR} +        --skip-license-check +        ${_binary} ") +      endif(DEBUG_PREBUILT) +      execute_process(COMMAND "${AUTOBUILD_EXECUTABLE}" +        install +        --install-dir=${AUTOBUILD_INSTALL_DIR} +        --skip-license-check +        ${_binary} +        WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" +        RESULT_VARIABLE ${_binary}_installed +        )        file(WRITE ${CMAKE_BINARY_DIR}/temp/${_binary}_installed "${${_binary}_installed}") -    else(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed) -      set(${_binary}_installed 0) -    endif(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed) +    endif(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed OR NOT ${${_binary}_installed} EQUAL 0) +      if(NOT ${_binary}_installed EQUAL 0)        message(FATAL_ERROR                "Failed to download or unpack prebuilt '${_binary}'." diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index 03428691cf..2f23e7c307 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -151,7 +151,7 @@ For more information, please see JIRA DEV-14943 - Cmake Linux cannot build both  endif (LINUX AND SERVER AND VIEWER) -set(USE_PRECOMPILED_HEADERS OFF CACHE BOOL "Enable use of precompiled header directives where supported.") +set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")  source_group("CMake Rules" FILES CMakeLists.txt) diff --git a/indra/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp index c34115ee80..217e26c3ca 100644 --- a/indra/integration_tests/llui_libtest/llui_libtest.cpp +++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp @@ -33,6 +33,7 @@  // linden library includes  #include "llcontrol.h"		// LLControlGroup  #include "lldir.h" +#include "lldiriterator.h"  #include "llerrorcontrol.h"  #include "llfloater.h"  #include "llfontfreetype.h" @@ -174,7 +175,9 @@ void export_test_floaters()  	std::string delim = gDirUtilp->getDirDelimiter();  	std::string xui_dir = get_xui_dir() + "en" + delim;  	std::string filename; -	while (gDirUtilp->getNextFileInDir(xui_dir, "floater_test_*.xml", filename)) + +	LLDirIterator iter(xui_dir, "floater_test_*.xml"); +	while (iter.next(filename))  	{  		if (filename.find("_new.xml") != std::string::npos)  		{ diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp index a81de0223c..eed00ac06e 100644 --- a/indra/linux_updater/linux_updater.cpp +++ b/indra/linux_updater/linux_updater.cpp @@ -33,6 +33,7 @@  #include "llerrorcontrol.h"  #include "llfile.h"  #include "lldir.h" +#include "lldiriterator.h"  #include "llxmlnode.h"  #include "lltrans.h" @@ -55,6 +56,8 @@ typedef struct _updater_app_state {  	std::string strings_dirs;  	std::string strings_file; +	LLDirIterator *image_dir_iter; +  	GtkWidget *window;  	GtkWidget *progress_bar;  	GtkWidget *image; @@ -115,7 +118,7 @@ bool translate_init(std::string comma_delim_path_list,  void updater_app_ui_init(void);  void updater_app_quit(UpdaterAppState *app_state);  void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state); -std::string next_image_filename(std::string& image_path); +std::string next_image_filename(std::string& image_path, LLDirIterator& iter);  void display_error(GtkWidget *parent, std::string title, std::string message);  BOOL install_package(std::string package_file, std::string destination);  BOOL spawn_viewer(UpdaterAppState *app_state); @@ -181,7 +184,7 @@ void updater_app_ui_init(UpdaterAppState *app_state)  		// load the first image  		app_state->image = gtk_image_new_from_file -			(next_image_filename(app_state->image_dir).c_str()); +			(next_image_filename(app_state->image_dir, *app_state->image_dir_iter).c_str());  		gtk_widget_set_size_request(app_state->image, 340, 310);  		gtk_container_add(GTK_CONTAINER(frame), app_state->image); @@ -212,7 +215,7 @@ gboolean rotate_image_cb(gpointer data)  	llassert(data != NULL);  	app_state = (UpdaterAppState *) data; -	filename = next_image_filename(app_state->image_dir); +	filename = next_image_filename(app_state->image_dir, *app_state->image_dir_iter);  	gdk_threads_enter();  	gtk_image_set_from_file(GTK_IMAGE(app_state->image), filename.c_str()); @@ -221,10 +224,10 @@ gboolean rotate_image_cb(gpointer data)  	return TRUE;  } -std::string next_image_filename(std::string& image_path) +std::string next_image_filename(std::string& image_path, LLDirIterator& iter)  {  	std::string image_filename; -	gDirUtilp->getNextFileInDir(image_path, "/*.jpg", image_filename); +	iter.next(image_filename);  	return image_path + "/" + image_filename;  } @@ -748,6 +751,7 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)  		else if ((!strcmp(argv[i], "--image-dir")) && (++i < argc))  		{  			app_state->image_dir = argv[i]; +			app_state->image_dir_iter = new LLDirIterator(argv[i], "/*.jpg");  		}  		else if ((!strcmp(argv[i], "--dest")) && (++i < argc))  		{ @@ -832,6 +836,7 @@ int main(int argc, char **argv)  	}  	bool success = !app_state->failure; +	delete app_state->image_dir_iter;  	delete app_state;  	return success ? 0 : 1;  } diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 39daefd1ad..ed192a9975 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -24,6 +24,10 @@   * $/LicenseInfo$   */ +#include "linden_common.h" + +#include "llapp.h" +  #include <cstdlib>  #ifdef LL_DARWIN @@ -32,9 +36,6 @@  #include <sys/sysctl.h>  #endif -#include "linden_common.h" -#include "llapp.h" -  #include "llcommon.h"  #include "llapr.h"  #include "llerrorcontrol.h" diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index 16aa49b653..0cfc393e05 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -27,7 +27,6 @@  #ifndef LL_LLBUTTON_H  #define LL_LLBUTTON_H -#include "lluuid.h"  #include "llcontrol.h"  #include "lluictrl.h"  #include "v4color.h" @@ -53,6 +52,8 @@ S32 round_up(S32 grid, S32 value);  class LLUICtrlFactory; +class LLUIImage; +class LLUUID;  //  // Classes diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h index 94387fb41a..8414b92113 100644 --- a/indra/llui/llfloaterreg.h +++ b/indra/llui/llfloaterreg.h @@ -27,14 +27,9 @@  #define LLFLOATERREG_H  /// llcommon -#include "llboost.h"  #include "llrect.h" -#include "llstl.h"  #include "llsd.h" -/// llui -#include "lluictrl.h" -  #include <boost/function.hpp>  //******************************************************* @@ -43,6 +38,7 @@  //  class LLFloater; +class LLUICtrl;  typedef boost::function<LLFloater* (const LLSD& key)> LLFloaterBuildFunc; diff --git a/indra/llui/llfocusmgr.cpp b/indra/llui/llfocusmgr.cpp index 43e5f6b051..724d190307 100644 --- a/indra/llui/llfocusmgr.cpp +++ b/indra/llui/llfocusmgr.cpp @@ -113,6 +113,16 @@ boost::signals2::connection	LLFocusableElement::setTopLostCallback(const focus_s +typedef std::list<LLHandle<LLView> > view_handle_list_t; +typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t; +struct LLFocusMgr::Impl +{ +	// caching list of keyboard focus ancestors for calling onFocusReceived and onFocusLost +	view_handle_list_t mCachedKeyboardFocusList; + +	focus_history_map_t mFocusHistory; +}; +  LLFocusMgr gFocusMgr;  LLFocusMgr::LLFocusMgr() @@ -123,10 +133,17 @@ LLFocusMgr::LLFocusMgr()  	mDefaultKeyboardFocus( NULL ),  	mKeystrokesOnly(FALSE),  	mTopCtrl( NULL ), -	mAppHasFocus(TRUE)   // Macs don't seem to notify us that we've gotten focus, so default to true +	mAppHasFocus(TRUE),   // Macs don't seem to notify us that we've gotten focus, so default to true +	mImpl(new LLFocusMgr::Impl)  {  } +LLFocusMgr::~LLFocusMgr() +{ +	mImpl->mFocusHistory.clear(); +	delete mImpl; +	mImpl = NULL; +}  void LLFocusMgr::releaseFocusIfNeeded( LLView* view )  { @@ -179,7 +196,7 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL  		mKeyboardFocus = new_focus;  		// list of the focus and it's ancestors -		view_handle_list_t old_focus_list = mCachedKeyboardFocusList; +		view_handle_list_t old_focus_list = mImpl->mCachedKeyboardFocusList;  		view_handle_list_t new_focus_list;  		// walk up the tree to root and add all views to the new_focus_list @@ -206,7 +223,7 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL  			LLView* old_focus_view = old_focus_iter->get();  			if (old_focus_view)  			{ -				mCachedKeyboardFocusList.pop_front(); +				mImpl->mCachedKeyboardFocusList.pop_front();  				old_focus_view->onFocusLost();  			}  		} @@ -219,7 +236,7 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL  			LLView* new_focus_view = new_focus_riter->get();  			if (new_focus_view)  			{ -                mCachedKeyboardFocusList.push_front(new_focus_view->getHandle()); +                mImpl->mCachedKeyboardFocusList.push_front(new_focus_view->getHandle());  				new_focus_view->onFocusReceived();  			}  		} @@ -254,7 +271,7 @@ void LLFocusMgr::setKeyboardFocus(LLFocusableElement* new_focus, BOOL lock, BOOL  		if (focus_subtree)  		{  			LLView* focused_view = dynamic_cast<LLView*>(mKeyboardFocus); -			mFocusHistory[focus_subtree->getHandle()] = focused_view ? focused_view->getHandle() : LLHandle<LLView>();  +			mImpl->mFocusHistory[focus_subtree->getHandle()] = focused_view ? focused_view->getHandle() : LLHandle<LLView>();   		}  	} @@ -456,8 +473,8 @@ LLUICtrl* LLFocusMgr::getLastFocusForGroup(LLView* subtree_root) const  {  	if (subtree_root)  	{ -		focus_history_map_t::const_iterator found_it = mFocusHistory.find(subtree_root->getHandle()); -		if (found_it != mFocusHistory.end()) +		focus_history_map_t::const_iterator found_it = mImpl->mFocusHistory.find(subtree_root->getHandle()); +		if (found_it != mImpl->mFocusHistory.end())  		{  			// found last focus for this subtree  			return static_cast<LLUICtrl*>(found_it->second.get()); @@ -470,6 +487,6 @@ void LLFocusMgr::clearLastFocusForGroup(LLView* subtree_root)  {  	if (subtree_root)  	{ -		mFocusHistory.erase(subtree_root->getHandle()); +		mImpl->mFocusHistory.erase(subtree_root->getHandle());  	}  } diff --git a/indra/llui/llfocusmgr.h b/indra/llui/llfocusmgr.h index 22c1895075..25ae1d2579 100644 --- a/indra/llui/llfocusmgr.h +++ b/indra/llui/llfocusmgr.h @@ -74,7 +74,7 @@ class LLFocusMgr  {  public:  	LLFocusMgr(); -	~LLFocusMgr() { mFocusHistory.clear(); } +	~LLFocusMgr();  	// Mouse Captor  	void			setMouseCapture(LLMouseHandler* new_captor);	// new_captor = NULL to release the mouse. @@ -120,6 +120,8 @@ public:  	bool			keyboardFocusHasAccelerators() const; +	struct Impl; +  private:  	LLUICtrl*			mLockedView; @@ -132,10 +134,6 @@ private:  	LLFocusableElement*	mDefaultKeyboardFocus;  	BOOL				mKeystrokesOnly; -	// caching list of keyboard focus ancestors for calling onFocusReceived and onFocusLost -	typedef std::list<LLHandle<LLView> > view_handle_list_t; -	view_handle_list_t mCachedKeyboardFocusList; -  	// Top View  	LLUICtrl*			mTopCtrl; @@ -143,8 +141,7 @@ private:  	BOOL				mAppHasFocus; -	typedef std::map<LLHandle<LLView>, LLHandle<LLView> > focus_history_map_t; -	focus_history_map_t mFocusHistory; +	Impl * mImpl;  };  extern LLFocusMgr gFocusMgr; diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h index 669e126266..efa0925a4a 100644 --- a/indra/llui/lliconctrl.h +++ b/indra/llui/lliconctrl.h @@ -30,6 +30,7 @@  #include "lluuid.h"  #include "v4color.h"  #include "lluictrl.h" +#include "lluiimage.h"  #include "stdenums.h"  class LLTextBox; diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h index 7b5fa218f2..fe191e5971 100644 --- a/indra/llui/lllineeditor.h +++ b/indra/llui/lllineeditor.h @@ -41,6 +41,7 @@  #include "lleditmenuhandler.h"  #include "lluictrl.h" +#include "lluiimage.h"  #include "lluistring.h"  #include "llviewborder.h" diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h index c0cb1cc74a..4c47cc267c 100644 --- a/indra/llui/llloadingindicator.h +++ b/indra/llui/llloadingindicator.h @@ -28,6 +28,7 @@  #define LL_LLLOADINGINDICATOR_H  #include "lluictrl.h" +#include "lluiimage.h"  ///////////////////////////////////////////////////////////////////////////////  // class LLLoadingIndicator diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index d4e6091ee0..f744e9db41 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -35,6 +35,7 @@  #include "llkeyboard.h"			// for the MASK constants  #include "llcontrol.h"  #include "lluictrlfactory.h" +#include "lluiimage.h"  #include <sstream> diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h index c1a1a06f39..7bbbeaf709 100644 --- a/indra/llui/llpanel.h +++ b/indra/llui/llpanel.h @@ -32,6 +32,7 @@  #include "llcallbackmap.h"  #include "lluictrl.h"  #include "llviewborder.h" +#include "lluiimage.h"  #include "lluistring.h"  #include "v4color.h"  #include <list> diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp index ead22686bc..84a890edfa 100644 --- a/indra/llui/llprogressbar.cpp +++ b/indra/llui/llprogressbar.cpp @@ -38,6 +38,7 @@  #include "llfocusmgr.h"  #include "lluictrlfactory.h" +#include "lluiimage.h"  static LLDefaultChildRegistry::Register<LLProgressBar> r("progress_bar"); diff --git a/indra/llui/llprogressbar.h b/indra/llui/llprogressbar.h index 3f308e7496..a8ec83ea00 100644 --- a/indra/llui/llprogressbar.h +++ b/indra/llui/llprogressbar.h @@ -27,8 +27,9 @@  #ifndef LL_LLPROGRESSBAR_H  #define LL_LLPROGRESSBAR_H -#include "lluictrl.h"  #include "llframetimer.h" +#include "lluictrl.h" +#include "lluiimage.h"  class LLProgressBar  	: public LLUICtrl diff --git a/indra/llui/llslider.h b/indra/llui/llslider.h index 68823ed68e..700c17ea3e 100644 --- a/indra/llui/llslider.h +++ b/indra/llui/llslider.h @@ -29,6 +29,7 @@  #include "llf32uictrl.h"  #include "v4color.h" +#include "lluiimage.h"  class LLSlider : public LLF32UICtrl  { diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp index 28a064e6b6..bb731f4f7e 100644 --- a/indra/llui/llstyle.cpp +++ b/indra/llui/llstyle.cpp @@ -88,7 +88,7 @@ void LLStyle::setVisible(BOOL is_visible)  	mVisible = is_visible;  } -LLUIImagePtr LLStyle::getImage() const +LLPointer<LLUIImage> LLStyle::getImage() const  {  	return mImagep;  } diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index 322edc343c..9f1eba79d8 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -30,6 +30,7 @@  #include "v4color.h"  #include "llui.h"  #include "llinitparam.h" +#include "lluiimage.h"  class LLFontGL; @@ -72,7 +73,7 @@ public:  	void setLinkHREF(const std::string& href);  	BOOL isLink() const; -	LLUIImagePtr getImage() const; +	LLPointer<LLUIImage> getImage() const;  	void setImage(const LLUUID& src);  	void setImage(const std::string& name); @@ -108,7 +109,7 @@ private:  	const LLFontGL*		mFont;  	std::string			mLink;  	bool				mIsLink; -	LLUIImagePtr		mImagep; +	LLPointer<LLUIImage> mImagep;  };  typedef LLPointer<LLStyle> LLStyleSP; diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp index 9d0ff9d5cb..58fa8a0828 100644 --- a/indra/llui/lltransutil.cpp +++ b/indra/llui/lltransutil.cpp @@ -26,10 +26,11 @@  #include "linden_common.h" +#include "lltransutil.h" +  #include "lltrans.h"  #include "lluictrlfactory.h" - -#include "lltransutil.h" +#include "llxmlnode.h"  bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<std::string>& default_args) diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 6a43477693..c583d58d5a 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -33,15 +33,12 @@  #include "llrect.h"  #include "llcontrol.h"  #include "llcoord.h" -#include "lluiimage.h"		// *TODO: break this dependency, need to add #include "lluiimage.h" to all widgets that hold an Optional<LLUIImage*> in their paramblocks  #include "llinitparam.h"  #include "llregistry.h"  #include "lluicolor.h"  #include "lluicolortable.h"  #include <boost/signals2.hpp>  #include "lllazyvalue.h" -#include "llhandle.h"		// *TODO: remove this dependency, added as a  -							// convenience when LLHandle moved to llhandle.h  #include "llframetimer.h"  // LLUIFactory @@ -265,8 +262,6 @@ private:  // Moved LLLocalClipRect to lllocalcliprect.h -// Moved all LLHandle-related code to llhandle.h -  //RN: maybe this needs to moved elsewhere?  class LLImageProviderInterface  { diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 61dc4b8030..8f167959b9 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -34,6 +34,7 @@  #include "stdtypes.h"  #include "llcoord.h"  #include "llfontgl.h" +#include "llhandle.h"  #include "llmortician.h"  #include "llmousehandler.h"  #include "llstring.h" diff --git a/indra/llui/llviewborder.cpp b/indra/llui/llviewborder.cpp index 89cd34c37c..32d7ea7c25 100644 --- a/indra/llui/llviewborder.cpp +++ b/indra/llui/llviewborder.cpp @@ -28,6 +28,7 @@  #include "llrender.h"  #include "llfocusmgr.h"  #include "lluictrlfactory.h" +#include "lluiimage.h"  static LLDefaultChildRegistry::Register<LLViewBorder> r("view_border"); diff --git a/indra/llui/llwindowshade.h b/indra/llui/llwindowshade.h index 0047195929..09ffc2cd54 100644 --- a/indra/llui/llwindowshade.h +++ b/indra/llui/llwindowshade.h @@ -29,6 +29,7 @@  #include "lluictrl.h"  #include "llnotifications.h" +#include "lluiimage.h"  class LLWindowShade : public LLUICtrl  { diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt index 722f4e2bfd..a3782d824b 100644 --- a/indra/llvfs/CMakeLists.txt +++ b/indra/llvfs/CMakeLists.txt @@ -12,6 +12,7 @@ include_directories(  set(llvfs_SOURCE_FILES      lldir.cpp +    lldiriterator.cpp      lllfsthread.cpp      llpidlock.cpp      llvfile.cpp @@ -24,6 +25,7 @@ set(llvfs_HEADER_FILES      lldir.h      lldirguard.h +    lldiriterator.h      lllfsthread.h      llpidlock.h      llvfile.h @@ -60,6 +62,11 @@ list(APPEND llvfs_SOURCE_FILES ${llvfs_HEADER_FILES})  add_library (llvfs ${llvfs_SOURCE_FILES}) +target_link_libraries(llvfs +    ${BOOST_FILESYSTEM_LIBRARY} +    ${BOOST_SYSTEM_LIBRARY} +    ) +  if (DARWIN)    include(CMakeFindFrameworks)    find_library(CARBON_LIBRARY Carbon) diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index 341c96f6ea..f3ac17d612 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -40,6 +40,8 @@  #include "lltimer.h"	// ms_sleep()  #include "lluuid.h" +#include "lldiriterator.h" +  #if LL_WINDOWS  #include "lldir_win32.h"  LLDir_Win32 gDirUtil; @@ -83,7 +85,9 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)  	std::string filename;   	std::string fullpath;  	S32 result; -	while (getNextFileInDir(dirname, mask, filename)) + +	LLDirIterator iter(dirname, mask); +	while (iter.next(filename))  	{  		fullpath = dirname;  		fullpath += getDirDelimiter(); diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h index 42996fd051..5ee8bdb542 100644 --- a/indra/llvfs/lldir.h +++ b/indra/llvfs/lldir.h @@ -75,31 +75,6 @@ class LLDir  // pure virtual functions  	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask) = 0; -    /// Walk the files in a directory, with file pattern matching -	virtual BOOL getNextFileInDir(const std::string& dirname, ///< directory path - must end in trailing slash! -                                  const std::string& mask,    ///< file pattern string (use "*" for all) -                                  std::string& fname          ///< output: found file name -                                  ) = 0; -    /**< -     * @returns true if a file was found, false if the entire directory has been scanned. -     * -     * @note that this function is NOT thread safe -     * -     * This function may not be used to scan part of a directory, then start a new search of a different -     * directory, and then restart the first search where it left off; the entire search must run to -     * completion or be abandoned - there is no restart. -     * -     * @bug: See http://jira.secondlife.com/browse/VWR-23697 -     *       and/or the tests in test/lldir_test.cpp -     *       This is known to fail with patterns that have both: -     *       a wildcard left of a . and more than one sequential ? right of a . -     *       the pattern foo.??x appears to work -     *       but *.??x or foo?.??x do not -     * -     * @todo this really should be rewritten as an iterator object, and the -     *       filtering should be done in a platform-independent way. -     */ -  	virtual std::string getCurPath() = 0;  	virtual BOOL fileExists(const std::string &filename) const = 0; diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp index 72b54f5380..407f3b93fb 100644 --- a/indra/llvfs/lldir_linux.cpp +++ b/indra/llvfs/lldir_linux.cpp @@ -242,68 +242,6 @@ U32 LLDir_Linux::countFilesInDir(const std::string &dirname, const std::string &  	return (file_count);  } -// get the next file in the directory -BOOL LLDir_Linux::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) -{ -	glob_t g; -	BOOL result = FALSE; -	fname = ""; -	 -	if(!(dirname == mCurrentDir)) -	{ -		// different dir specified, close old search -		mCurrentDirIndex = -1; -		mCurrentDirCount = -1; -		mCurrentDir = dirname; -	} -	 -	std::string tmp_str; -	tmp_str = dirname; -	tmp_str += mask; - -	if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0) -	{ -		if(g.gl_pathc > 0) -		{ -			if((int)g.gl_pathc != mCurrentDirCount) -			{ -				// Number of matches has changed since the last search, meaning a file has been added or deleted. -				// Reset the index. -				mCurrentDirIndex = -1; -				mCurrentDirCount = g.gl_pathc; -			} -	 -			mCurrentDirIndex++; -	 -			if(mCurrentDirIndex < (int)g.gl_pathc) -			{ -//				llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl; - -				// The API wants just the filename, not the full path. -				//fname = g.gl_pathv[mCurrentDirIndex]; - -				char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/'); -				 -				if(s == NULL) -					s = g.gl_pathv[mCurrentDirIndex]; -				else if(s[0] == '/') -					s++; -					 -				fname = s; -				 -				result = TRUE; -			} -		} -		 -		globfree(&g); -	} -	 -	return(result); -} - - - -  std::string LLDir_Linux::getCurPath()  {  	char tmp_str[LL_MAX_PATH];	/* Flawfinder: ignore */  diff --git a/indra/llvfs/lldir_linux.h b/indra/llvfs/lldir_linux.h index a34de1241d..7603239867 100644 --- a/indra/llvfs/lldir_linux.h +++ b/indra/llvfs/lldir_linux.h @@ -47,7 +47,6 @@ public:  	virtual std::string getCurPath();  	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask); -	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);  	/*virtual*/ BOOL fileExists(const std::string &filename) const;  	/*virtual*/ std::string getLLPluginLauncher(); diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp index f9369b043e..8f48f92e2a 100644 --- a/indra/llvfs/lldir_mac.cpp +++ b/indra/llvfs/lldir_mac.cpp @@ -258,67 +258,6 @@ U32 LLDir_Mac::countFilesInDir(const std::string &dirname, const std::string &ma  	return (file_count);  } -// get the next file in the directory -BOOL LLDir_Mac::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) -{ -	glob_t g; -	BOOL result = FALSE; -	fname = ""; -	 -	if(!(dirname == mCurrentDir)) -	{ -		// different dir specified, close old search -		mCurrentDirIndex = -1; -		mCurrentDirCount = -1; -		mCurrentDir = dirname; -	} -	 -	std::string tmp_str; -	tmp_str = dirname; -	tmp_str += mask; - -	if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0) -	{ -		if(g.gl_pathc > 0) -		{ -			if(g.gl_pathc != mCurrentDirCount) -			{ -				// Number of matches has changed since the last search, meaning a file has been added or deleted. -				// Reset the index. -				mCurrentDirIndex = -1; -				mCurrentDirCount = g.gl_pathc; -			} -	 -			mCurrentDirIndex++; -	 -			if(mCurrentDirIndex < g.gl_pathc) -			{ -//				llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl; - -				// The API wants just the filename, not the full path. -				//fname = g.gl_pathv[mCurrentDirIndex]; - -				char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/'); -				 -				if(s == NULL) -					s = g.gl_pathv[mCurrentDirIndex]; -				else if(s[0] == '/') -					s++; -					 -				fname = s; -				 -				result = TRUE; -			} -		} -		 -		globfree(&g); -	} -	 -	return(result); -} - - -  S32 LLDir_Mac::deleteFilesInDir(const std::string &dirname, const std::string &mask)  {  	glob_t g; diff --git a/indra/llvfs/lldir_mac.h b/indra/llvfs/lldir_mac.h index b456d3afca..bc3f0fac00 100644 --- a/indra/llvfs/lldir_mac.h +++ b/indra/llvfs/lldir_mac.h @@ -47,7 +47,6 @@ public:  	virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask);  	virtual std::string getCurPath();  	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask); -	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);  	virtual BOOL fileExists(const std::string &filename) const;  	/*virtual*/ std::string getLLPluginLauncher(); diff --git a/indra/llvfs/lldir_solaris.cpp b/indra/llvfs/lldir_solaris.cpp index 515fd66b6e..21f8c3acdb 100644 --- a/indra/llvfs/lldir_solaris.cpp +++ b/indra/llvfs/lldir_solaris.cpp @@ -260,68 +260,6 @@ U32 LLDir_Solaris::countFilesInDir(const std::string &dirname, const std::string  	return (file_count);  } -// get the next file in the directory -BOOL LLDir_Solaris::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) -{ -	glob_t g; -	BOOL result = FALSE; -	fname = ""; -	 -	if(!(dirname == mCurrentDir)) -	{ -		// different dir specified, close old search -		mCurrentDirIndex = -1; -		mCurrentDirCount = -1; -		mCurrentDir = dirname; -	} -	 -	std::string tmp_str; -	tmp_str = dirname; -	tmp_str += mask; - -	if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0) -	{ -		if(g.gl_pathc > 0) -		{ -			if((int)g.gl_pathc != mCurrentDirCount) -			{ -				// Number of matches has changed since the last search, meaning a file has been added or deleted. -				// Reset the index. -				mCurrentDirIndex = -1; -				mCurrentDirCount = g.gl_pathc; -			} -	 -			mCurrentDirIndex++; -	 -			if(mCurrentDirIndex < (int)g.gl_pathc) -			{ -//				llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl; - -				// The API wants just the filename, not the full path. -				//fname = g.gl_pathv[mCurrentDirIndex]; - -				char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/'); -				 -				if(s == NULL) -					s = g.gl_pathv[mCurrentDirIndex]; -				else if(s[0] == '/') -					s++; -					 -				fname = s; -				 -				result = TRUE; -			} -		} -		 -		globfree(&g); -	} -	 -	return(result); -} - - - -  std::string LLDir_Solaris::getCurPath()  {  	char tmp_str[LL_MAX_PATH];	/* Flawfinder: ignore */  diff --git a/indra/llvfs/lldir_solaris.h b/indra/llvfs/lldir_solaris.h index 70fac6f818..0b58a45b15 100644 --- a/indra/llvfs/lldir_solaris.h +++ b/indra/llvfs/lldir_solaris.h @@ -47,7 +47,6 @@ public:  	virtual std::string getCurPath();  	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask); -	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);  	/*virtual*/ BOOL fileExists(const std::string &filename) const;  private: diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp index 4e2a55f4b3..7709945123 100644 --- a/indra/llvfs/lldir_win32.cpp +++ b/indra/llvfs/lldir_win32.cpp @@ -240,67 +240,6 @@ U32 LLDir_Win32::countFilesInDir(const std::string &dirname, const std::string &  	return (file_count);  } - -// get the next file in the directory -BOOL LLDir_Win32::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) -{ -    BOOL fileFound = FALSE; -	fname = ""; - -	WIN32_FIND_DATAW FileData; -    llutf16string pathname = utf8str_to_utf16str(dirname) + utf8str_to_utf16str(mask); - -	if (pathname != mCurrentDir) -	{ -		// different dir specified, close old search -		if (!mCurrentDir.empty()) -		{ -			FindClose(mDirSearch_h); -		} -		mCurrentDir = pathname; - -		// and open new one -		// Check error opening Directory structure -		if ((mDirSearch_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE)    -		{ -           fileFound = TRUE; -		} -	} - -    // Loop to skip over the current (.) and parent (..) directory entries -    // (apparently returned in Win7 but not XP) -    do -    { -       if (   fileFound -           && (  (lstrcmp(FileData.cFileName, (LPCTSTR)TEXT(".")) == 0) -               ||(lstrcmp(FileData.cFileName, (LPCTSTR)TEXT("..")) == 0) -               ) -           ) -       { -          fileFound = FALSE; -       } -    } while (   mDirSearch_h != INVALID_HANDLE_VALUE -             && !fileFound -             && (fileFound = FindNextFile(mDirSearch_h, &FileData) -                 ) -             ); - -    if (!fileFound && GetLastError() == ERROR_NO_MORE_FILES) -    { -       // No more files, so reset to beginning of directory -       FindClose(mDirSearch_h); -       mCurrentDir[0] = '\000'; -    } - -    if (fileFound) -    { -        // convert from TCHAR to char -        fname = utf16str_to_utf8str(FileData.cFileName); -	} -     -	return fileFound; -} -  std::string LLDir_Win32::getCurPath()  {  	WCHAR w_str[MAX_PATH]; diff --git a/indra/llvfs/lldir_win32.h b/indra/llvfs/lldir_win32.h index b170ebbcd7..62fb4713ab 100644 --- a/indra/llvfs/lldir_win32.h +++ b/indra/llvfs/lldir_win32.h @@ -44,15 +44,12 @@ public:  	/*virtual*/ std::string getCurPath();  	/*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask); -	/*virtual*/ BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);  	/*virtual*/ BOOL fileExists(const std::string &filename) const;  	/*virtual*/ std::string getLLPluginLauncher();  	/*virtual*/ std::string getLLPluginFilename(std::string base_name);  private: -	BOOL getNextFileInDir(const llutf16string &dirname, const std::string &mask, std::string &fname); -  	void* mDirSearch_h;  	llutf16string mCurrentDir;  }; diff --git a/indra/llvfs/tests/lldir_test.cpp b/indra/llvfs/tests/lldir_test.cpp index 8788bd63e8..ea321c5ae9 100644 --- a/indra/llvfs/tests/lldir_test.cpp +++ b/indra/llvfs/tests/lldir_test.cpp @@ -28,6 +28,7 @@  #include "linden_common.h"  #include "../lldir.h" +#include "../lldiriterator.h"  #include "../test/lltut.h" @@ -259,13 +260,12 @@ namespace tut     std::string makeTestFile( const std::string& dir, const std::string& file )     { -      std::string delim = gDirUtilp->getDirDelimiter(); -      std::string path = dir + delim + file; +      std::string path = dir + file;        LLFILE* handle = LLFile::fopen( path, "w" );        ensure("failed to open test file '"+path+"'", handle != NULL );        // Harbison & Steele, 4th ed., p. 366: "If an error occurs, fputs        // returns EOF; otherwise, it returns some other, nonnegative value." -      ensure("failed to write to test file '"+path+"'", fputs("test file", handle) >= 0); +      ensure("failed to write to test file '"+path+"'", EOF != fputs("test file", handle) );        fclose(handle);        return path;     } @@ -290,7 +290,7 @@ namespace tut     }     static const char* DirScanFilename[5] = { "file1.abc", "file2.abc", "file1.xyz", "file2.xyz", "file1.mno" }; -    +     void scanTest(const std::string& directory, const std::string& pattern, bool correctResult[5])     { @@ -300,7 +300,8 @@ namespace tut        bool  filesFound[5] = { false, false, false, false, false };        //std::cerr << "searching '"+directory+"' for '"+pattern+"'\n"; -      while ( found <= 5 && gDirUtilp->getNextFileInDir(directory, pattern, scanResult) ) +      LLDirIterator iter(directory, pattern); +      while ( found <= 5 && iter.next(scanResult) )        {           found++;           //std::cerr << "  found '"+scanResult+"'\n"; @@ -334,15 +335,15 @@ namespace tut     template<> template<>     void LLDirTest_object_t::test<5>() -      // getNextFileInDir +      // LLDirIterator::next     {        std::string delim = gDirUtilp->getDirDelimiter();        std::string dirTemp = LLFile::tmpdir();        // Create the same 5 file names of the two directories -      std::string dir1 = makeTestDir(dirTemp + "getNextFileInDir"); -      std::string dir2 = makeTestDir(dirTemp + "getNextFileInDir"); +      std::string dir1 = makeTestDir(dirTemp + "LLDirIterator"); +      std::string dir2 = makeTestDir(dirTemp + "LLDirIterator");        std::string dir1files[5];        std::string dir2files[5];        for (int i=0; i<5; i++) @@ -380,19 +381,17 @@ namespace tut        scanTest(dir2, "file?.x?z", expected7);        // Scan dir2 and see if any file?.??c files are found -      // THESE FAIL ON Mac and Windows, SO ARE COMMENTED OUT FOR NOW -      //      bool  expected8[5] = { true, true, false, false, false }; -      //      scanTest(dir2, "file?.??c", expected8); -      //      scanTest(dir2, "*.??c", expected8); +      bool  expected8[5] = { true, true, false, false, false }; +      scanTest(dir2, "file?.??c", expected8); +      scanTest(dir2, "*.??c", expected8);        // Scan dir1 and see if any *.?n? files are found        bool  expected9[5] = { false, false, false, false, true };        scanTest(dir1, "*.?n?", expected9);        // Scan dir1 and see if any *.???? files are found -      // THIS ONE FAILS ON WINDOWS (returns three charater suffixes) SO IS COMMENTED OUT FOR NOW -      // bool  expected10[5] = { false, false, false, false, false }; -      // scanTest(dir1, "*.????", expected10); +      bool  expected10[5] = { false, false, false, false, false }; +      scanTest(dir1, "*.????", expected10);        // Scan dir1 and see if any ?????.* files are found        bool  expected11[5] = { true, true, true, true, true }; @@ -402,6 +401,15 @@ namespace tut        bool  expected12[5] = { false, false, true, true, false };        scanTest(dir1, "??l??.xyz", expected12); +      bool expected13[5] = { true, false, true, false, false }; +      scanTest(dir1, "file1.{abc,xyz}", expected13); + +      bool expected14[5] = { true, true, false, false, false }; +      scanTest(dir1, "file[0-9].abc", expected14); + +      bool expected15[5] = { true, true, false, false, false }; +      scanTest(dir1, "file[!a-z].abc", expected15); +        // clean up all test files and directories        for (int i=0; i<5; i++)        { diff --git a/indra/llxuixml/lltrans.cpp b/indra/llxuixml/lltrans.cpp index e13d73c640..b403b86048 100644 --- a/indra/llxuixml/lltrans.cpp +++ b/indra/llxuixml/lltrans.cpp @@ -30,6 +30,7 @@  #include "llfasttimer.h"	// for call count statistics  #include "llxuiparser.h" +#include "llxmlnode.h"  #include <map> diff --git a/indra/llxuixml/lltrans.h b/indra/llxuixml/lltrans.h index 5b127b53cf..b7091f77e8 100644 --- a/indra/llxuixml/lltrans.h +++ b/indra/llxuixml/lltrans.h @@ -29,8 +29,10 @@  #include <map> +#include "llpointer.h"  #include "llstring.h" -#include "llxmlnode.h" + +class LLXMLNode;  /**   * @brief String template loaded from strings.xml @@ -61,9 +63,9 @@ public:  	 * @param default_args Set of strings (expected to be in the file) to use as default replacement args, e.g. "SECOND_LIFE"  	 * @returns true if the file was parsed successfully, true if something went wrong  	 */ -	static bool parseStrings(LLXMLNodePtr& root, const std::set<std::string>& default_args); +	static bool parseStrings(LLPointer<LLXMLNode> & root, const std::set<std::string>& default_args); -	static bool parseLanguageStrings(LLXMLNodePtr &root); +	static bool parseLanguageStrings(LLPointer<LLXMLNode> & root);  	/**  	 * @brief Returns a translated string diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h index 7a748d8aea..0c38c4da93 100644 --- a/indra/llxuixml/llxuiparser.h +++ b/indra/llxuixml/llxuiparser.h @@ -28,7 +28,6 @@  #define LLXUIPARSER_H  #include "llinitparam.h" -#include "llfasttimer.h"  #include "llregistry.h"  #include "llpointer.h" @@ -95,6 +94,7 @@ public:  }; +class LLXUIParserImpl;  class LLXUIParser : public LLInitParam::Parser  { @@ -176,6 +176,7 @@ private:  // ordering of child elements from base file to localized diff file.  Then we can use a pair  // of coroutines to perform matching of xml nodes during parsing.  Not sure if the overhead  // of coroutines would offset the gain from SAX parsing +class LLSimpleXUIParserImpl;  class LLSimpleXUIParser : public LLInitParam::Parser  { diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 7319c0d902..8f5efcf941 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -25,10 +25,12 @@   */  #include "llviewerprecompiledheaders.h" +  #include "llagent.h"   #include "pipeline.h" +#include "llagentaccess.h"  #include "llagentcamera.h"  #include "llagentlistener.h"  #include "llagentwearables.h" @@ -36,6 +38,7 @@  #include "llanimationstates.h"  #include "llbottomtray.h"  #include "llcallingcard.h" +#include "llcapabilitylistener.h"  #include "llchannelmanager.h"  #include "llconsole.h"  #include "llfirstuse.h" @@ -55,8 +58,10 @@  #include "llpaneltopinfobar.h"  #include "llparcel.h"  #include "llrendersphere.h" +#include "llsdmessage.h"  #include "llsdutil.h"  #include "llsky.h" +#include "llslurl.h"  #include "llsmoothstep.h"  #include "llstartup.h"  #include "llstatusbar.h" @@ -74,6 +79,7 @@  #include "llviewerobjectlist.h"  #include "llviewerparcelmgr.h"  #include "llviewerstats.h" +#include "llviewerwindow.h"  #include "llvoavatarself.h"  #include "llwindow.h"  #include "llworld.h" @@ -172,7 +178,8 @@ LLAgent::LLAgent() :  	mbRunning(false),  	mbTeleportKeepsLookAt(false), -	mAgentAccess(gSavedSettings), +	mAgentAccess(new LLAgentAccess(gSavedSettings)), +	mTeleportSourceSLURL(new LLSLURL),  	mTeleportState( TELEPORT_NONE ),  	mRegionp(NULL), @@ -209,7 +216,7 @@ LLAgent::LLAgent() :  	mAutoPilotFinishedCallback(NULL),  	mAutoPilotCallbackData(NULL), -	mEffectColor(LLColor4(0.f, 1.f, 1.f, 1.f)), +	mEffectColor(new LLUIColor(LLColor4(0.f, 1.f, 1.f, 1.f))),  	mHaveHomePosition(FALSE),  	mHomeRegionHandle( 0 ), @@ -251,7 +258,7 @@ void LLAgent::init()  	setFlying( gSavedSettings.getBOOL("FlyingAtExit") ); -	mEffectColor = LLUIColorTable::instance().getColor("EffectColor"); +	*mEffectColor = LLUIColorTable::instance().getColor("EffectColor");  	gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2));  	gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2)); @@ -275,9 +282,16 @@ LLAgent::~LLAgent()  	cleanup();  	delete mMouselookModeInSignal; +	mMouselookModeInSignal = NULL;  	delete mMouselookModeOutSignal; +	mMouselookModeOutSignal = NULL; -	// *Note: this is where LLViewerCamera::getInstance() used to be deleted. +	delete mAgentAccess; +	mAgentAccess = NULL; +	delete mEffectColor; +	mEffectColor = NULL; +	delete mTeleportSourceSLURL; +	mTeleportSourceSLURL = NULL;  }  // Handle any actions that need to be performed when the main app gains focus @@ -2142,32 +2156,32 @@ void LLAgent::onAnimStop(const LLUUID& id)  bool LLAgent::isGodlike() const  { -	return mAgentAccess.isGodlike(); +	return mAgentAccess->isGodlike();  }  bool LLAgent::isGodlikeWithoutAdminMenuFakery() const  { -	return mAgentAccess.isGodlikeWithoutAdminMenuFakery(); +	return mAgentAccess->isGodlikeWithoutAdminMenuFakery();  }  U8 LLAgent::getGodLevel() const  { -	return mAgentAccess.getGodLevel(); +	return mAgentAccess->getGodLevel();  }  bool LLAgent::wantsPGOnly() const  { -	return mAgentAccess.wantsPGOnly(); +	return mAgentAccess->wantsPGOnly();  }  bool LLAgent::canAccessMature() const  { -	return mAgentAccess.canAccessMature(); +	return mAgentAccess->canAccessMature();  }  bool LLAgent::canAccessAdult() const  { -	return mAgentAccess.canAccessAdult(); +	return mAgentAccess->canAccessAdult();  }  bool LLAgent::canAccessMaturityInRegion( U64 region_handle ) const @@ -2202,37 +2216,37 @@ bool LLAgent::canAccessMaturityAtGlobal( LLVector3d pos_global ) const  bool LLAgent::prefersPG() const  { -	return mAgentAccess.prefersPG(); +	return mAgentAccess->prefersPG();  }  bool LLAgent::prefersMature() const  { -	return mAgentAccess.prefersMature(); +	return mAgentAccess->prefersMature();  }  bool LLAgent::prefersAdult() const  { -	return mAgentAccess.prefersAdult(); +	return mAgentAccess->prefersAdult();  }  bool LLAgent::isTeen() const  { -	return mAgentAccess.isTeen(); +	return mAgentAccess->isTeen();  }  bool LLAgent::isMature() const  { -	return mAgentAccess.isMature(); +	return mAgentAccess->isMature();  }  bool LLAgent::isAdult() const  { -	return mAgentAccess.isAdult(); +	return mAgentAccess->isAdult();  }  void LLAgent::setTeen(bool teen)  { -	mAgentAccess.setTeen(teen); +	mAgentAccess->setTeen(teen);  }  //static  @@ -2277,37 +2291,37 @@ bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity)  BOOL LLAgent::getAdminOverride() const	  {  -	return mAgentAccess.getAdminOverride();  +	return mAgentAccess->getAdminOverride();   }  void LLAgent::setMaturity(char text)  { -	mAgentAccess.setMaturity(text); +	mAgentAccess->setMaturity(text);  }  void LLAgent::setAdminOverride(BOOL b)	  {  -	mAgentAccess.setAdminOverride(b); +	mAgentAccess->setAdminOverride(b);  }  void LLAgent::setGodLevel(U8 god_level)	  {  -	mAgentAccess.setGodLevel(god_level); +	mAgentAccess->setGodLevel(god_level);  }  void LLAgent::setAOTransition()  { -	mAgentAccess.setTransition(); +	mAgentAccess->setTransition();  }  const LLAgentAccess& LLAgent::getAgentAccess()  { -	return mAgentAccess; +	return *mAgentAccess;  }  bool LLAgent::validateMaturity(const LLSD& newvalue)  { -	return mAgentAccess.canSetMaturity(newvalue.asInteger()); +	return mAgentAccess->canSetMaturity(newvalue.asInteger());  }  void LLAgent::handleMaturity(const LLSD& newvalue) @@ -2639,12 +2653,12 @@ BOOL LLAgent::allowOperation(PermissionBit op,  const LLColor4 &LLAgent::getEffectColor()  { -	return mEffectColor; +	return *mEffectColor;  }  void LLAgent::setEffectColor(const LLColor4 &color)  { -	mEffectColor = color; +	*mEffectColor = color;  }  void LLAgent::initOriginGlobal(const LLVector3d &origin_global) @@ -3472,7 +3486,7 @@ void LLAgent::setTeleportState(ETeleportState state)  		case TELEPORT_MOVING:  		// We're outa here. Save "back" slurl. -		LLAgentUI::buildSLURL(mTeleportSourceSLURL); +		LLAgentUI::buildSLURL(*mTeleportSourceSLURL);  			break;  		case TELEPORT_ARRIVING: @@ -3805,6 +3819,11 @@ void LLAgent::parseTeleportMessages(const std::string& xml_filename)  	}//end for (all message sets in xml file)  } +const void LLAgent::getTeleportSourceSLURL(LLSLURL& slurl) const +{ +	slurl = *mTeleportSourceSLURL; +} +  void LLAgent::sendAgentUpdateUserInfo(bool im_via_email, const std::string& directory_visibility )  {  	gMessageSystem->newMessageFast(_PREHASH_UpdateUserInfo); diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 896408c0dd..54c5649f97 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -29,15 +29,11 @@  #include "indra_constants.h"  #include "llevent.h" 				// LLObservable base class -#include "llagentaccess.h"  #include "llagentconstants.h"  #include "llagentdata.h" 			// gAgentID, gAgentSessionID -#include "llcharacter.h" 			// LLAnimPauseRequest +#include "llcharacter.h"  #include "llcoordframe.h"			// for mFrameAgent -#include "llpointer.h" -#include "lluicolor.h"  #include "llvoavatardefines.h" -#include "llslurl.h"  #include <boost/signals2.hpp> @@ -56,6 +52,10 @@ class LLFriendObserver;  class LLPickInfo;  class LLViewerObject;  class LLAgentDropGroupViewerNode; +class LLAgentAccess; +class LLSLURL; +class LLPauseRequestHandle; +class LLUIColor;  //--------------------------------------------------------------------  // Types @@ -80,6 +80,8 @@ struct LLGroupData  class LLAgentListener; +class LLAgentImpl; +  //------------------------------------------------------------------------  // LLAgent  //------------------------------------------------------------------------ @@ -420,7 +422,7 @@ private:  	camera_signal_t* mMouselookModeInSignal;  	camera_signal_t* mMouselookModeOutSignal;  	BOOL            mCustomAnim; 		// Current animation is ANIM_AGENT_CUSTOMIZE ? -	LLAnimPauseRequest mPauseRequest; +	LLPointer<LLPauseRequestHandle> mPauseRequest;  	BOOL			mViewsPushed; 		// Keep track of whether or not we have pushed views  /**                    Animation @@ -515,13 +517,13 @@ public:  public:  	static void 	parseTeleportMessages(const std::string& xml_filename); -	const void getTeleportSourceSLURL(LLSLURL& slurl) const { slurl = mTeleportSourceSLURL; } +	const void getTeleportSourceSLURL(LLSLURL& slurl) const;  public:  	// ! TODO ! Define ERROR and PROGRESS enums here instead of exposing the mappings.  	static std::map<std::string, std::string> sTeleportErrorMessages;  	static std::map<std::string, std::string> sTeleportProgressMessages;  private: -	LLSLURL	mTeleportSourceSLURL; 			// SLURL where last TP began +	LLSLURL * mTeleportSourceSLURL; 			// SLURL where last TP began  	//--------------------------------------------------------------------  	// Teleport Actions @@ -580,7 +582,7 @@ public:  	// ! BACKWARDS COMPATIBILITY ! This function can go away after the AO transition (see llstartup.cpp).  	void 			setAOTransition();  private: -	LLAgentAccess 	mAgentAccess; +	LLAgentAccess * mAgentAccess;  	//--------------------------------------------------------------------  	// God @@ -660,7 +662,7 @@ public:  	const LLColor4	&getEffectColor();  	void			setEffectColor(const LLColor4 &color);  private: -	LLUIColor 		mEffectColor; +	LLUIColor * mEffectColor;  /**                    Rendering   **                                                                            ** diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 9de2941c4a..3a7e8dff64 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -82,13 +82,14 @@  #include "lltextutil.h"  #include "lllogininstance.h"  #include "llprogressview.h" - +#include "llvocache.h"  #include "llweb.h"  #include "llsecondlifeurls.h"  #include "llupdaterservice.h"  // Linden library includes  #include "llavatarnamecache.h" +#include "lldiriterator.h"  #include "llimagej2c.h"  #include "llmemory.h"  #include "llprimitive.h" @@ -132,7 +133,6 @@  #include "lltoolmgr.h"  #include "llassetstorage.h"  #include "llpolymesh.h" -#include "llcachename.h"  #include "llaudioengine.h"  #include "llstreamingaudio.h"  #include "llviewermenu.h" @@ -3432,7 +3432,9 @@ void LLAppViewer::migrateCacheDirectory()  			S32 file_count = 0;  			std::string file_name;  			std::string mask = delimiter + "*.*"; -			while (gDirUtilp->getNextFileInDir(old_cache_dir, mask, file_name)) + +			LLDirIterator iter(old_cache_dir, mask); +			while (iter.next(file_name))  			{  				if (file_name == "." || file_name == "..") continue;  				std::string source_path = old_cache_dir + delimiter + file_name; @@ -3653,7 +3655,8 @@ bool LLAppViewer::initCache()  		dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"");  		std::string found_file; -		if (gDirUtilp->getNextFileInDir(dir, mask, found_file)) +		LLDirIterator iter(dir, mask); +		if (iter.next(found_file))  		{  			old_vfs_data_file = dir + gDirUtilp->getDirDelimiter() + found_file; diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp index 523c2e3adf..714e0e6163 100644 --- a/indra/newview/llappviewerlinux.cpp +++ b/indra/newview/llappviewerlinux.cpp @@ -30,6 +30,7 @@  #include "llcommandlineparser.h" +#include "lldiriterator.h"  #include "llmemtype.h"  #include "llurldispatcher.h"		// SLURL from other app instance  #include "llviewernetwork.h" @@ -504,7 +505,9 @@ std::string LLAppViewerLinux::generateSerialNumber()  	// trawl /dev/disk/by-uuid looking for a good-looking UUID to grab  	std::string this_name; -	while (gDirUtilp->getNextFileInDir(uuiddir, "*", this_name)) + +	LLDirIterator iter(uuiddir, "*"); +	while (iter.next(this_name))  	{  		if (this_name.length() > best.length() ||  		    (this_name.length() == best.length() && diff --git a/indra/newview/lleventnotifier.h b/indra/newview/lleventnotifier.h index 697a708762..3fee46c2f6 100644 --- a/indra/newview/lleventnotifier.h +++ b/indra/newview/lleventnotifier.h @@ -31,6 +31,7 @@  #include "v3dmath.h"  class LLEventNotification; +class LLMessageSystem;  class LLEventNotifier diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 7be4ebc690..0d0c1f594d 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -38,6 +38,7 @@  #include "message.h"  #include "llagent.h" +#include "llagentaccess.h"  #include "llbutton.h"  #include "llcheckboxctrl.h"  #include "llcombobox.h" diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index a096fb64cd..8a70fa24d8 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -43,11 +43,12 @@ class LLButton;  class LLCheckBoxCtrl;  class LLRadioGroup;  class LLComboBox; -class LLNameListCtrl; -class LLSpinCtrl;  class LLLineEditor; +class LLMessageSystem; +class LLNameListCtrl;  class LLRadioGroup;  class LLParcelSelectionObserver; +class LLSpinCtrl;  class LLTabContainer;  class LLTextBox;  class LLTextEditor; diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index add591895b..00dc7b1627 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -53,6 +53,7 @@  #include "llfloaterpostcard.h"  #include "llcheckboxctrl.h"  #include "llradiogroup.h" +#include "llslurl.h"  #include "lltoolfocus.h"  #include "lltoolmgr.h"  #include "llwebsharing.h" diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 0d8601410a..4c9c4cb154 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -35,6 +35,7 @@  #include "llfloateruipreview.h"			// Own header  // Internal utility +#include "lldiriterator.h"  #include "lleventtimer.h"  #include "llexternaleditor.h"  #include "llrender.h" @@ -481,9 +482,11 @@ BOOL LLFloaterUIPreview::postBuild()  	std::string language_directory;  	std::string xui_dir = get_xui_dir();	// directory containing localizations -- don't forget trailing delim  	mLanguageSelection->removeall();																				// clear out anything temporarily in list from XML + +	LLDirIterator iter(xui_dir, "*");  	while(found)																									// for every directory  	{ -		if((found = gDirUtilp->getNextFileInDir(xui_dir, "*", language_directory)))							// get next directory +		if((found = iter.next(language_directory)))							// get next directory  		{  			std::string full_path = xui_dir + language_directory;  			if(LLFile::isfile(full_path.c_str()))																	// if it's not a directory, skip it @@ -635,42 +638,51 @@ void LLFloaterUIPreview::refreshList()  	mFileList->clearRows();		// empty list  	std::string name;  	BOOL found = TRUE; + +	LLDirIterator floater_iter(getLocalizedDirectory(), "floater_*.xml");  	while(found)				// for every floater file that matches the pattern  	{ -		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "floater_*.xml", name)))	// get next file matching pattern +		if((found = floater_iter.next(name)))	// get next file matching pattern  		{  			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)  		}  	}  	found = TRUE; + +	LLDirIterator inspect_iter(getLocalizedDirectory(), "inspect_*.xml");  	while(found)				// for every inspector file that matches the pattern  	{ -		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "inspect_*.xml", name)))	// get next file matching pattern +		if((found = inspect_iter.next(name)))	// get next file matching pattern  		{  			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)  		}  	}  	found = TRUE; + +	LLDirIterator menu_iter(getLocalizedDirectory(), "menu_*.xml");  	while(found)				// for every menu file that matches the pattern  	{ -		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "menu_*.xml", name)))	// get next file matching pattern +		if((found = menu_iter.next(name)))	// get next file matching pattern  		{  			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)  		}  	}  	found = TRUE; + +	LLDirIterator panel_iter(getLocalizedDirectory(), "panel_*.xml");  	while(found)				// for every panel file that matches the pattern  	{ -		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "panel_*.xml", name)))	// get next file matching pattern +		if((found = panel_iter.next(name)))	// get next file matching pattern  		{  			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)  		}  	} -  	found = TRUE; + +	LLDirIterator sidepanel_iter(getLocalizedDirectory(), "sidepanel_*.xml");  	while(found)				// for every sidepanel file that matches the pattern  	{ -		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "sidepanel_*.xml", name)))	// get next file matching pattern +		if((found = sidepanel_iter.next(name)))	// get next file matching pattern  		{  			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)  		} diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h index 2006e094a8..fc941510ab 100644 --- a/indra/newview/llfolderviewitem.h +++ b/indra/newview/llfolderviewitem.h @@ -28,6 +28,7 @@  #include "llview.h"  #include "lldarray.h"  // *TODO: Eliminate, forward declare +#include "lluiimage.h"  class LLFontGL;  class LLFolderView; diff --git a/indra/newview/lllocationhistory.h b/indra/newview/lllocationhistory.h index 188fbf1f9b..9fef42c5df 100644 --- a/indra/newview/lllocationhistory.h +++ b/indra/newview/lllocationhistory.h @@ -33,6 +33,7 @@  #include <string>  #include <map>  #include <boost/function.hpp> +#include <boost/signals2.hpp>  class LLSD;  /** diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 2df683861a..efc4e23838 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -32,6 +32,7 @@  #include "lltrans.h"  #include "llviewercontrol.h" +#include "lldiriterator.h"  #include "llinstantmessage.h"  #include "llsingleton.h" // for LLSingleton @@ -602,7 +603,8 @@ std::string LLLogChat::oldLogFileName(std::string filename)  	//LL_INFOS("") << "Checking:" << directory << " for " << pattern << LL_ENDL;/* uncomment if you want to verify step, delete on commit */  	std::vector<std::string> allfiles; -    while (gDirUtilp->getNextFileInDir(directory, pattern, scanResult)) +	LLDirIterator iter(directory, pattern); +	while (iter.next(scanResult))      {  		//LL_INFOS("") << "Found   :" << scanResult << LL_ENDL;          allfiles.push_back(scanResult); diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h index 026803584d..2d23753d46 100644 --- a/indra/newview/lloutputmonitorctrl.h +++ b/indra/newview/lloutputmonitorctrl.h @@ -31,6 +31,7 @@  #include "llview.h"  #include "llmutelist.h"  #include "llspeakingindicatormanager.h" +#include "lluiimage.h"  class LLTextBox;  class LLUICtrlFactory; diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 73c4722b82..d58a1cb663 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -36,6 +36,7 @@  #include "llimview.h"  #include "llmenubutton.h"  #include "llnotificationsutil.h" +#include "llslurl.h"  #include "lltexteditor.h"  #include "lltexturectrl.h"  #include "lltoggleablemenu.h" diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index ec340dc258..1576ccccdf 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -44,6 +44,7 @@  #include "llnotificationsutil.h"  #include "llscrolllistitem.h"  #include "llspinctrl.h" +#include "llslurl.h"  #include "lltextbox.h"  #include "lltexteditor.h"  #include "lltexturectrl.h" diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 3dbc637318..fbe331c7ab 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -42,6 +42,7 @@  #include "llscrolllistctrl.h"  #include "llscrolllistitem.h"  #include "llscrolllistcell.h" +#include "llslurl.h"  #include "lltabcontainer.h"  #include "lltextbox.h"  #include "lltexteditor.h" diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp index 8e5beb33ce..9f5c55bad1 100644 --- a/indra/newview/llpreviewgesture.cpp +++ b/indra/newview/llpreviewgesture.cpp @@ -34,6 +34,7 @@  #include "llassetuploadresponders.h"  #include "llcheckboxctrl.h"  #include "llcombobox.h" +#include "lldatapacker.h"  #include "lldelayedgestureerror.h"  #include "llfloaterreg.h"  #include "llgesturemgr.h" diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp index c8c6858b81..fbd2f7ca83 100644 --- a/indra/newview/llsidepaneliteminfo.cpp +++ b/indra/newview/llsidepaneliteminfo.cpp @@ -39,6 +39,7 @@  #include "llinventoryobserver.h"  #include "lllineeditor.h"  #include "llradiogroup.h" +#include "llslurl.h"  #include "llviewercontrol.h"  #include "llviewerinventory.h"  #include "llviewerobjectlist.h" diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index ba243f258a..671a334600 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -35,7 +35,6 @@  #include "llagentwearables.h"  #include "llappearancemgr.h"  #include "lldictionary.h" -//#include "llfirstuse.h"  #include "llfloaterreg.h"  #include "llfloatertools.h"  #include "llgesturemgr.h" diff --git a/indra/newview/llviewerchat.cpp b/indra/newview/llviewerchat.cpp index e7a0d17c3a..e06fe7bda0 100644 --- a/indra/newview/llviewerchat.cpp +++ b/indra/newview/llviewerchat.cpp @@ -29,6 +29,8 @@  // newview includes  #include "llagent.h" 	// gAgent		 +#include "llslurl.h" +#include "lluicolor.h"  #include "lluicolortable.h"  #include "llviewercontrol.h" // gSavedSettings  #include "llviewerregion.h" diff --git a/indra/newview/llviewerkeyboard.h b/indra/newview/llviewerkeyboard.h index 925244e89b..ca73212ed1 100644 --- a/indra/newview/llviewerkeyboard.h +++ b/indra/newview/llviewerkeyboard.h @@ -28,6 +28,7 @@  #define LL_LLVIEWERKEYBOARD_H  #include "llkeyboard.h" // For EKeystate +#include "llinitparam.h"  const S32 MAX_NAMED_FUNCTIONS = 100;  const S32 MAX_KEY_BINDINGS = 128; // was 60 diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 62ae7ac6e2..2b9f32f6f5 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1,3742 +1,3744 @@ -/**
 - * @file llviewermedia.cpp
 - * @brief Client interface to the media engine
 - *
 - * $LicenseInfo:firstyear=2007&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 "llviewerprecompiledheaders.h"
 -
 -#include "llagent.h"
 -#include "llagentcamera.h"
 -#include "llviewermedia.h"
 -#include "llviewermediafocus.h"
 -#include "llmimetypes.h"
 -#include "llmediaentry.h"
 -#include "llversioninfo.h"
 -#include "llviewercontrol.h"
 -#include "llviewertexture.h"
 -#include "llviewerparcelmedia.h"
 -#include "llviewerparcelmgr.h"
 -#include "llviewertexturelist.h"
 -#include "llvovolume.h"
 -#include "llpluginclassmedia.h"
 -#include "llplugincookiestore.h"
 -#include "llviewerwindow.h"
 -#include "llfocusmgr.h"
 -#include "llcallbacklist.h"
 -#include "llparcel.h"
 -#include "llaudioengine.h"  // for gAudiop
 -#include "llurldispatcher.h"
 -#include "llvoavatar.h"
 -#include "llvoavatarself.h"
 -#include "llviewerregion.h"
 -#include "llwebsharing.h"	// For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this!
 -#include "llfilepicker.h"
 -#include "llnotifications.h"
 -#include "lldir.h"
 -#include "llevent.h"		// LLSimpleListener
 -#include "llnotificationsutil.h"
 -#include "lluuid.h"
 -#include "llkeyboard.h"
 -#include "llmutelist.h"
 -#include "llpanelprofile.h"
 -#include "llappviewer.h"
 -#include "lllogininstance.h" 
 -//#include "llfirstuse.h"
 -#include "llwindow.h"
 -
 -#include "llfloatermediabrowser.h"	// for handling window close requests and geometry change requests in media browser windows.
 -#include "llfloaterwebcontent.h"	// for handling window close requests and geometry change requests in media browser windows.
 -
 -#include <boost/bind.hpp>	// for SkinFolder listener
 -#include <boost/signals2.hpp>
 -
 -/*static*/ const char* LLViewerMedia::AUTO_PLAY_MEDIA_SETTING = "ParcelMediaAutoPlayEnable";
 -/*static*/ const char* LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING = "MediaShowOnOthers";
 -/*static*/ const char* LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING = "MediaShowWithinParcel";
 -/*static*/ const char* LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING = "MediaShowOutsideParcel";
 -
 -
 -// Move this to its own file.
 -
 -LLViewerMediaEventEmitter::~LLViewerMediaEventEmitter()
 -{
 -	observerListType::iterator iter = mObservers.begin();
 -
 -	while( iter != mObservers.end() )
 -	{
 -		LLViewerMediaObserver *self = *iter;
 -		iter++;
 -		remObserver(self);
 -	}
 -}
 -
 -///////////////////////////////////////////////////////////////////////////////
 -//
 -bool LLViewerMediaEventEmitter::addObserver( LLViewerMediaObserver* observer )
 -{
 -	if ( ! observer )
 -		return false;
 -
 -	if ( std::find( mObservers.begin(), mObservers.end(), observer ) != mObservers.end() )
 -		return false;
 -
 -	mObservers.push_back( observer );
 -	observer->mEmitters.push_back( this );
 -
 -	return true;
 -}
 -
 -///////////////////////////////////////////////////////////////////////////////
 -//
 -bool LLViewerMediaEventEmitter::remObserver( LLViewerMediaObserver* observer )
 -{
 -	if ( ! observer )
 -		return false;
 -
 -	mObservers.remove( observer );
 -	observer->mEmitters.remove(this);
 -
 -	return true;
 -}
 -
 -///////////////////////////////////////////////////////////////////////////////
 -//
 -void LLViewerMediaEventEmitter::emitEvent( LLPluginClassMedia* media, LLViewerMediaObserver::EMediaEvent event )
 -{
 -	// Broadcast the event to any observers.
 -	observerListType::iterator iter = mObservers.begin();
 -	while( iter != mObservers.end() )
 -	{
 -		LLViewerMediaObserver *self = *iter;
 -		++iter;
 -		self->handleMediaEvent( media, event );
 -	}
 -}
 -
 -// Move this to its own file.
 -LLViewerMediaObserver::~LLViewerMediaObserver()
 -{
 -	std::list<LLViewerMediaEventEmitter *>::iterator iter = mEmitters.begin();
 -
 -	while( iter != mEmitters.end() )
 -	{
 -		LLViewerMediaEventEmitter *self = *iter;
 -		iter++;
 -		self->remObserver( this );
 -	}
 -}
 -
 -
 -// Move this to its own file.
 -// helper class that tries to download a URL from a web site and calls a method
 -// on the Panel Land Media and to discover the MIME type
 -class LLMimeDiscoveryResponder : public LLHTTPClient::Responder
 -{
 -LOG_CLASS(LLMimeDiscoveryResponder);
 -public:
 -	LLMimeDiscoveryResponder( viewer_media_t media_impl)
 -		: mMediaImpl(media_impl),
 -		  mInitialized(false)
 -	{
 -		if(mMediaImpl->mMimeTypeProbe != NULL)
 -		{
 -			llerrs << "impl already has an outstanding responder" << llendl;
 -		}
 -		
 -		mMediaImpl->mMimeTypeProbe = this;
 -	}
 -
 -	~LLMimeDiscoveryResponder()
 -	{
 -		disconnectOwner();
 -	}
 -
 -	virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content)
 -	{
 -		std::string media_type = content["content-type"].asString();
 -		std::string::size_type idx1 = media_type.find_first_of(";");
 -		std::string mime_type = media_type.substr(0, idx1);
 -
 -		lldebugs << "status is " << status << ", media type \"" << media_type << "\"" << llendl;
 -		
 -		// 2xx status codes indicate success.
 -		// Most 4xx status codes are successful enough for our purposes.
 -		// 499 is the error code for host not found, timeout, etc.
 -		// 500 means "Internal Server error" but we decided it's okay to 
 -		//     accept this and go past it in the MIME type probe
 -		// 302 means the resource can be found temporarily in a different place - added this for join.secondlife.com
 -		// 499 is a code specifc to join.secondlife.com (????) apparently safe to ignore
 -//		if(	((status >= 200) && (status < 300))	||
 -//			((status >= 400) && (status < 499))	|| 
 -//			(status == 500) ||
 -//			(status == 302) ||
 -//			(status == 499) 
 -//			)
 -		// We now no longer check the error code returned from the probe.
 -		// If we have a mime type, use it.  If not, default to the web plugin and let it handle error reporting.
 -		if(1)
 -		{
 -			// The probe was successful.
 -			if(mime_type.empty())
 -			{
 -				// Some sites don't return any content-type header at all.
 -				// Treat an empty mime type as text/html.
 -				mime_type = "text/html";
 -			}
 -			
 -			completeAny(status, mime_type);
 -		}
 -		else
 -		{
 -			llwarns << "responder failed with status " << status << ", reason " << reason << llendl;
 -		
 -			if(mMediaImpl)
 -			{
 -				mMediaImpl->mMediaSourceFailed = true;
 -			}
 -		}
 -
 -	}
 -
 -	void completeAny(U32 status, const std::string& mime_type)
 -	{
 -		// the call to initializeMedia may disconnect the responder, which will clear mMediaImpl.
 -		// Make a local copy so we can call loadURI() afterwards.
 -		LLViewerMediaImpl *impl = mMediaImpl;
 -		
 -		if(impl && !mInitialized && ! mime_type.empty())
 -		{
 -			if(impl->initializeMedia(mime_type))
 -			{
 -				mInitialized = true;
 -				impl->loadURI();
 -				disconnectOwner();
 -			}
 -		}
 -	}
 -	
 -	void cancelRequest()
 -	{
 -		disconnectOwner();
 -	}
 -	
 -private:
 -	void disconnectOwner()
 -	{
 -		if(mMediaImpl)
 -		{
 -			if(mMediaImpl->mMimeTypeProbe != this)
 -			{
 -				llerrs << "internal error: mMediaImpl->mMimeTypeProbe != this" << llendl;
 -			}
 -
 -			mMediaImpl->mMimeTypeProbe = NULL;
 -		}
 -		mMediaImpl = NULL;
 -	}
 -	
 -	
 -public:
 -		LLViewerMediaImpl *mMediaImpl;
 -		bool mInitialized;
 -};
 -
 -class LLViewerMediaOpenIDResponder : public LLHTTPClient::Responder
 -{
 -LOG_CLASS(LLViewerMediaOpenIDResponder);
 -public:
 -	LLViewerMediaOpenIDResponder( )
 -	{
 -	}
 -
 -	~LLViewerMediaOpenIDResponder()
 -	{
 -	}
 -
 -	/* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
 -	{
 -		LL_DEBUGS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL;
 -		LL_DEBUGS("MediaAuth") << content << LL_ENDL;
 -		std::string cookie = content["set-cookie"].asString();
 -		
 -		LLViewerMedia::openIDCookieResponse(cookie);
 -	}
 -
 -	/* virtual */ void completedRaw(
 -		U32 status,
 -		const std::string& reason,
 -		const LLChannelDescriptors& channels,
 -		const LLIOPipe::buffer_ptr_t& buffer)
 -	{
 -		// This is just here to disable the default behavior (attempting to parse the response as llsd).
 -		// We don't care about the content of the response, only the set-cookie header.
 -	}
 -
 -};
 -
 -class LLViewerMediaWebProfileResponder : public LLHTTPClient::Responder
 -{
 -LOG_CLASS(LLViewerMediaWebProfileResponder);
 -public:
 -	LLViewerMediaWebProfileResponder(std::string host)
 -	{
 -		mHost = host;
 -	}
 -
 -	~LLViewerMediaWebProfileResponder()
 -	{
 -	}
 -
 -	/* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content)
 -	{
 -		LL_WARNS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL;
 -		LL_WARNS("MediaAuth") << content << LL_ENDL;
 -
 -		std::string cookie = content["set-cookie"].asString();
 -
 -		LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, mHost);
 -	}
 -
 -	 void completedRaw(
 -		U32 status,
 -		const std::string& reason,
 -		const LLChannelDescriptors& channels,
 -		const LLIOPipe::buffer_ptr_t& buffer)
 -	{
 -		// This is just here to disable the default behavior (attempting to parse the response as llsd).
 -		// We don't care about the content of the response, only the set-cookie header.
 -	}
 -
 -	std::string mHost;
 -};
 -
 -
 -LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL;
 -LLURL LLViewerMedia::sOpenIDURL;
 -std::string LLViewerMedia::sOpenIDCookie;
 -LLPluginClassMedia* LLViewerMedia::sSpareBrowserMediaSource = NULL;
 -static LLViewerMedia::impl_list sViewerMediaImplList;
 -static LLViewerMedia::impl_id_map sViewerMediaTextureIDMap;
 -static LLTimer sMediaCreateTimer;
 -static const F32 LLVIEWERMEDIA_CREATE_DELAY = 1.0f;
 -static F32 sGlobalVolume = 1.0f;
 -static F64 sLowestLoadableImplInterest = 0.0f;
 -static bool sAnyMediaShowing = false;
 -static boost::signals2::connection sTeleportFinishConnection;
 -static std::string sUpdatedCookies;
 -static const char *PLUGIN_COOKIE_FILE_NAME = "plugin_cookies.txt";
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -static void add_media_impl(LLViewerMediaImpl* media)
 -{
 -	sViewerMediaImplList.push_back(media);
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -static void remove_media_impl(LLViewerMediaImpl* media)
 -{
 -	LLViewerMedia::impl_list::iterator iter = sViewerMediaImplList.begin();
 -	LLViewerMedia::impl_list::iterator end = sViewerMediaImplList.end();
 -	
 -	for(; iter != end; iter++)
 -	{
 -		if(media == *iter)
 -		{
 -			sViewerMediaImplList.erase(iter);
 -			return;
 -		}
 -	}
 -}
 -
 -class LLViewerMediaMuteListObserver : public LLMuteListObserver
 -{
 -	/* virtual */ void onChange()  { LLViewerMedia::muteListChanged();}
 -};
 -
 -static LLViewerMediaMuteListObserver sViewerMediaMuteListObserver;
 -static bool sViewerMediaMuteListObserverInitialized = false;
 -static bool sInWorldMediaDisabled = false;
 -
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// LLViewerMedia
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -viewer_media_t LLViewerMedia::newMediaImpl(
 -											 const LLUUID& texture_id,
 -											 S32 media_width, 
 -											 S32 media_height, 
 -											 U8 media_auto_scale,
 -											 U8 media_loop)
 -{
 -	LLViewerMediaImpl* media_impl = getMediaImplFromTextureID(texture_id);
 -	if(media_impl == NULL || texture_id.isNull())
 -	{
 -		// Create the media impl
 -		media_impl = new LLViewerMediaImpl(texture_id, media_width, media_height, media_auto_scale, media_loop);
 -	}
 -	else
 -	{
 -		media_impl->unload();
 -		media_impl->setTextureID(texture_id);
 -		media_impl->mMediaWidth = media_width;
 -		media_impl->mMediaHeight = media_height;
 -		media_impl->mMediaAutoScale = media_auto_scale;
 -		media_impl->mMediaLoop = media_loop;
 -	}
 -
 -	return media_impl;
 -}
 -
 -viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const std::string& previous_url, bool update_from_self)
 -{	
 -	// Try to find media with the same media ID
 -	viewer_media_t media_impl = getMediaImplFromTextureID(media_entry->getMediaID());
 -	
 -	lldebugs << "called, current URL is \"" << media_entry->getCurrentURL() 
 -			<< "\", previous URL is \"" << previous_url 
 -			<< "\", update_from_self is " << (update_from_self?"true":"false")
 -			<< llendl;
 -			
 -	bool was_loaded = false;
 -	bool needs_navigate = false;
 -	
 -	if(media_impl)
 -	{	
 -		was_loaded = media_impl->hasMedia();
 -		
 -		media_impl->setHomeURL(media_entry->getHomeURL());
 -		
 -		media_impl->mMediaAutoScale = media_entry->getAutoScale();
 -		media_impl->mMediaLoop = media_entry->getAutoLoop();
 -		media_impl->mMediaWidth = media_entry->getWidthPixels();
 -		media_impl->mMediaHeight = media_entry->getHeightPixels();
 -		media_impl->mMediaAutoPlay = media_entry->getAutoPlay();
 -		media_impl->mMediaEntryURL = media_entry->getCurrentURL();
 -		if (media_impl->mMediaSource)
 -		{
 -			media_impl->mMediaSource->setAutoScale(media_impl->mMediaAutoScale);
 -			media_impl->mMediaSource->setLoop(media_impl->mMediaLoop);
 -			media_impl->mMediaSource->setSize(media_entry->getWidthPixels(), media_entry->getHeightPixels());
 -		}
 -		
 -		bool url_changed = (media_impl->mMediaEntryURL != previous_url);
 -		if(media_impl->mMediaEntryURL.empty())
 -		{
 -			if(url_changed)
 -			{
 -				// The current media URL is now empty.  Unload the media source.
 -				media_impl->unload();
 -			
 -				lldebugs << "Unloading media instance (new current URL is empty)." << llendl;
 -			}
 -		}
 -		else
 -		{
 -			// The current media URL is not empty.
 -			// If (the media was already loaded OR the media was set to autoplay) AND this update didn't come from this agent,
 -			// do a navigate.
 -			bool auto_play = media_impl->isAutoPlayable();			
 -			if((was_loaded || auto_play) && !update_from_self)
 -			{
 -				needs_navigate = url_changed;
 -			}
 -			
 -			lldebugs << "was_loaded is " << (was_loaded?"true":"false") 
 -					<< ", auto_play is " << (auto_play?"true":"false") 
 -					<< ", needs_navigate is " << (needs_navigate?"true":"false") << llendl;
 -		}
 -	}
 -	else
 -	{
 -		media_impl = newMediaImpl(
 -			media_entry->getMediaID(), 
 -			media_entry->getWidthPixels(),
 -			media_entry->getHeightPixels(), 
 -			media_entry->getAutoScale(), 
 -			media_entry->getAutoLoop());
 -		
 -		media_impl->setHomeURL(media_entry->getHomeURL());
 -		media_impl->mMediaAutoPlay = media_entry->getAutoPlay();
 -		media_impl->mMediaEntryURL = media_entry->getCurrentURL();
 -		if(media_impl->isAutoPlayable())
 -		{
 -			needs_navigate = true;
 -		}
 -	}
 -	
 -	if(media_impl)
 -	{
 -		if(needs_navigate)
 -		{
 -			media_impl->navigateTo(media_impl->mMediaEntryURL, "", true, true);
 -			lldebugs << "navigating to URL " << media_impl->mMediaEntryURL << llendl;
 -		}
 -		else if(!media_impl->mMediaURL.empty() && (media_impl->mMediaURL != media_impl->mMediaEntryURL))
 -		{
 -			// If we already have a non-empty media URL set and we aren't doing a navigate, update the media URL to match the media entry.
 -			media_impl->mMediaURL = media_impl->mMediaEntryURL;
 -
 -			// If this causes a navigate at some point (such as after a reload), it should be considered server-driven so it isn't broadcast.
 -			media_impl->mNavigateServerRequest = true;
 -
 -			lldebugs << "updating URL in the media impl to " << media_impl->mMediaEntryURL << llendl;
 -		}
 -	}
 -	
 -	return media_impl;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -LLViewerMediaImpl* LLViewerMedia::getMediaImplFromTextureID(const LLUUID& texture_id)
 -{
 -	LLViewerMediaImpl* result = NULL;
 -	
 -	// Look up the texture ID in the texture id->impl map.
 -	impl_id_map::iterator iter = sViewerMediaTextureIDMap.find(texture_id);
 -	if(iter != sViewerMediaTextureIDMap.end())
 -	{
 -		result = iter->second;
 -	}
 -
 -	return result;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -std::string LLViewerMedia::getCurrentUserAgent()
 -{
 -	// Don't use user-visible string to avoid 
 -	// punctuation and strange characters.
 -	std::string skin_name = gSavedSettings.getString("SkinCurrent");
 -
 -	// Just in case we need to check browser differences in A/B test
 -	// builds.
 -	std::string channel = LLVersionInfo::getChannel();
 -
 -	// append our magic version number string to the browser user agent id
 -	// See the HTTP 1.0 and 1.1 specifications for allowed formats:
 -	// http://www.ietf.org/rfc/rfc1945.txt section 10.15
 -	// http://www.ietf.org/rfc/rfc2068.txt section 3.8
 -	// This was also helpful:
 -	// http://www.mozilla.org/build/revised-user-agent-strings.html
 -	std::ostringstream codec;
 -	codec << "SecondLife/";
 -	codec << LLVersionInfo::getVersion();
 -	codec << " (" << channel << "; " << skin_name << " skin)";
 -	llinfos << codec.str() << llendl;
 -	
 -	return codec.str();
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::updateBrowserUserAgent()
 -{
 -	std::string user_agent = getCurrentUserAgent();
 -	
 -	impl_list::iterator iter = sViewerMediaImplList.begin();
 -	impl_list::iterator end = sViewerMediaImplList.end();
 -
 -	for(; iter != end; iter++)
 -	{
 -		LLViewerMediaImpl* pimpl = *iter;
 -		if(pimpl->mMediaSource && pimpl->mMediaSource->pluginSupportsMediaBrowser())
 -		{
 -			pimpl->mMediaSource->setBrowserUserAgent(user_agent);
 -		}
 -	}
 -
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -bool LLViewerMedia::handleSkinCurrentChanged(const LLSD& /*newvalue*/)
 -{
 -	// gSavedSettings is already updated when this function is called.
 -	updateBrowserUserAgent();
 -	return true;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -bool LLViewerMedia::textureHasMedia(const LLUUID& texture_id)
 -{
 -	impl_list::iterator iter = sViewerMediaImplList.begin();
 -	impl_list::iterator end = sViewerMediaImplList.end();
 -
 -	for(; iter != end; iter++)
 -	{
 -		LLViewerMediaImpl* pimpl = *iter;
 -		if(pimpl->getMediaTextureID() == texture_id)
 -		{
 -			return true;
 -		}
 -	}
 -	return false;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::setVolume(F32 volume)
 -{
 -	if(volume != sGlobalVolume)
 -	{
 -		sGlobalVolume = volume;
 -		impl_list::iterator iter = sViewerMediaImplList.begin();
 -		impl_list::iterator end = sViewerMediaImplList.end();
 -
 -		for(; iter != end; iter++)
 -		{
 -			LLViewerMediaImpl* pimpl = *iter;
 -			pimpl->updateVolume();
 -		}
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -F32 LLViewerMedia::getVolume()
 -{
 -	return sGlobalVolume;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::muteListChanged()
 -{
 -	// When the mute list changes, we need to check mute status on all impls.
 -	impl_list::iterator iter = sViewerMediaImplList.begin();
 -	impl_list::iterator end = sViewerMediaImplList.end();
 -
 -	for(; iter != end; iter++)
 -	{
 -		LLViewerMediaImpl* pimpl = *iter;
 -		pimpl->mNeedsMuteCheck = true;
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::setInWorldMediaDisabled(bool disabled)
 -{
 -	sInWorldMediaDisabled = disabled;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -bool LLViewerMedia::getInWorldMediaDisabled()
 -{
 -	return sInWorldMediaDisabled;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -bool LLViewerMedia::isInterestingEnough(const LLVOVolume *object, const F64 &object_interest)
 -{
 -	bool result = false;
 -	
 -	if (NULL == object)
 -	{
 -		result = false;
 -	}
 -	// Focused?  Then it is interesting!
 -	else if (LLViewerMediaFocus::getInstance()->getFocusedObjectID() == object->getID())
 -	{
 -		result = true;
 -	}
 -	// Selected?  Then it is interesting!
 -	// XXX Sadly, 'contains()' doesn't take a const :(
 -	else if (LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(object)))
 -	{
 -		result = true;
 -	}
 -	else 
 -	{
 -		lldebugs << "object interest = " << object_interest << ", lowest loadable = " << sLowestLoadableImplInterest << llendl;
 -		if(object_interest >= sLowestLoadableImplInterest)
 -			result = true;
 -	}
 -	
 -	return result;
 -}
 -
 -LLViewerMedia::impl_list &LLViewerMedia::getPriorityList()
 -{
 -	return sViewerMediaImplList;
 -}
 -
 -// This is the predicate function used to sort sViewerMediaImplList by priority.
 -bool LLViewerMedia::priorityComparitor(const LLViewerMediaImpl* i1, const LLViewerMediaImpl* i2)
 -{
 -	if(i1->isForcedUnloaded() && !i2->isForcedUnloaded())
 -	{
 -		// Muted or failed items always go to the end of the list, period.
 -		return false;
 -	}
 -	else if(i2->isForcedUnloaded() && !i1->isForcedUnloaded())
 -	{
 -		// Muted or failed items always go to the end of the list, period.
 -		return true;
 -	}
 -	else if(i1->hasFocus())
 -	{
 -		// The item with user focus always comes to the front of the list, period.
 -		return true;
 -	}
 -	else if(i2->hasFocus())
 -	{
 -		// The item with user focus always comes to the front of the list, period.
 -		return false;
 -	}
 -	else if(i1->isParcelMedia())
 -	{
 -		// The parcel media impl sorts above all other inworld media, unless one has focus.
 -		return true;
 -	}
 -	else if(i2->isParcelMedia())
 -	{
 -		// The parcel media impl sorts above all other inworld media, unless one has focus.
 -		return false;
 -	}
 -	else if(i1->getUsedInUI() && !i2->getUsedInUI())
 -	{
 -		// i1 is a UI element, i2 is not.  This makes i1 "less than" i2, so it sorts earlier in our list.
 -		return true;
 -	}
 -	else if(i2->getUsedInUI() && !i1->getUsedInUI())
 -	{
 -		// i2 is a UI element, i1 is not.  This makes i2 "less than" i1, so it sorts earlier in our list.
 -		return false;
 -	}
 -	else if(i1->isPlayable() && !i2->isPlayable())
 -	{
 -		// Playable items sort above ones that wouldn't play even if they got high enough priority
 -		return true;
 -	}
 -	else if(!i1->isPlayable() && i2->isPlayable())
 -	{
 -		// Playable items sort above ones that wouldn't play even if they got high enough priority
 -		return false;
 -	}
 -	else if(i1->getInterest() == i2->getInterest())
 -	{
 -		// Generally this will mean both objects have zero interest.  In this case, sort on distance.
 -		return (i1->getProximityDistance() < i2->getProximityDistance());
 -	}
 -	else
 -	{
 -		// The object with the larger interest value should be earlier in the list, so we reverse the sense of the comparison here.
 -		return (i1->getInterest() > i2->getInterest());
 -	}
 -}
 -
 -static bool proximity_comparitor(const LLViewerMediaImpl* i1, const LLViewerMediaImpl* i2)
 -{
 -	if(i1->getProximityDistance() < i2->getProximityDistance())
 -	{
 -		return true;
 -	}
 -	else if(i1->getProximityDistance() > i2->getProximityDistance())
 -	{
 -		return false;
 -	}
 -	else
 -	{
 -		// Both objects have the same distance.  This most likely means they're two faces of the same object.
 -		// They may also be faces on different objects with exactly the same distance (like HUD objects).
 -		// We don't actually care what the sort order is for this case, as long as it's stable and doesn't change when you enable/disable media.
 -		// Comparing the impl pointers gives a completely arbitrary ordering, but it will be stable.
 -		return (i1 < i2);
 -	}
 -}
 -
 -static LLFastTimer::DeclareTimer FTM_MEDIA_UPDATE("Update Media");
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::updateMedia(void *dummy_arg)
 -{
 -	LLFastTimer t1(FTM_MEDIA_UPDATE);
 -	
 -	// Enable/disable the plugin read thread
 -	LLPluginProcessParent::setUseReadThread(gSavedSettings.getBOOL("PluginUseReadThread"));
 -	
 -	// HACK: we always try to keep a spare running webkit plugin around to improve launch times.
 -	createSpareBrowserMediaSource();
 -	
 -	sAnyMediaShowing = false;
 -	sUpdatedCookies = getCookieStore()->getChangedCookies();
 -	if(!sUpdatedCookies.empty())
 -	{
 -		lldebugs << "updated cookies will be sent to all loaded plugins: " << llendl;
 -		lldebugs << sUpdatedCookies << llendl;
 -	}
 -	
 -	impl_list::iterator iter = sViewerMediaImplList.begin();
 -	impl_list::iterator end = sViewerMediaImplList.end();
 -
 -	for(; iter != end;)
 -	{
 -		LLViewerMediaImpl* pimpl = *iter++;
 -		pimpl->update();
 -		pimpl->calculateInterest();
 -	}
 -	
 -	// Let the spare media source actually launch
 -	if(sSpareBrowserMediaSource)
 -	{
 -		sSpareBrowserMediaSource->idle();
 -	}
 -		
 -	// Sort the static instance list using our interest criteria
 -	sViewerMediaImplList.sort(priorityComparitor);
 -
 -	// Go through the list again and adjust according to priority.
 -	iter = sViewerMediaImplList.begin();
 -	end = sViewerMediaImplList.end();
 -	
 -	F64 total_cpu = 0.0f;
 -	int impl_count_total = 0;
 -	int impl_count_interest_low = 0;
 -	int impl_count_interest_normal = 0;
 -	
 -	std::vector<LLViewerMediaImpl*> proximity_order;
 -	
 -	bool inworld_media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia");
 -	bool inworld_audio_enabled = gSavedSettings.getBOOL("AudioStreamingMusic");
 -	U32 max_instances = gSavedSettings.getU32("PluginInstancesTotal");
 -	U32 max_normal = gSavedSettings.getU32("PluginInstancesNormal");
 -	U32 max_low = gSavedSettings.getU32("PluginInstancesLow");
 -	F32 max_cpu = gSavedSettings.getF32("PluginInstancesCPULimit");
 -	// Setting max_cpu to 0.0 disables CPU usage checking.
 -	bool check_cpu_usage = (max_cpu != 0.0f);
 -	
 -	LLViewerMediaImpl* lowest_interest_loadable = NULL;
 -	
 -	// Notes on tweakable params:
 -	// max_instances must be set high enough to allow the various instances used in the UI (for the help browser, search, etc.) to be loaded.
 -	// If max_normal + max_low is less than max_instances, things will tend to get unloaded instead of being set to slideshow.
 -	
 -	for(; iter != end; iter++)
 -	{
 -		LLViewerMediaImpl* pimpl = *iter;
 -		
 -		LLPluginClassMedia::EPriority new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
 -
 -		if(pimpl->isForcedUnloaded() || (impl_count_total >= (int)max_instances))
 -		{
 -			// Never load muted or failed impls.
 -			// Hard limit on the number of instances that will be loaded at one time
 -			new_priority = LLPluginClassMedia::PRIORITY_UNLOADED;
 -		}
 -		else if(!pimpl->getVisible())
 -		{
 -			new_priority = LLPluginClassMedia::PRIORITY_HIDDEN;
 -		}
 -		else if(pimpl->hasFocus())
 -		{
 -			new_priority = LLPluginClassMedia::PRIORITY_HIGH;
 -			impl_count_interest_normal++;	// count this against the count of "normal" instances for priority purposes
 -		}
 -		else if(pimpl->getUsedInUI())
 -		{
 -			new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
 -			impl_count_interest_normal++;
 -		}
 -		else if(pimpl->isParcelMedia())
 -		{
 -			new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
 -			impl_count_interest_normal++;
 -		}
 -		else
 -		{
 -			// Look at interest and CPU usage for instances that aren't in any of the above states.
 -			
 -			// Heuristic -- if the media texture's approximate screen area is less than 1/4 of the native area of the texture,
 -			// turn it down to low instead of normal.  This may downsample for plugins that support it.
 -			bool media_is_small = false;
 -			F64 approximate_interest = pimpl->getApproximateTextureInterest();
 -			if(approximate_interest == 0.0f)
 -			{
 -				// this media has no current size, which probably means it's not loaded.
 -				media_is_small = true;
 -			}
 -			else if(pimpl->getInterest() < (approximate_interest / 4))
 -			{
 -				media_is_small = true;
 -			}
 -			
 -			if(pimpl->getInterest() == 0.0f)
 -			{
 -				// This media is completely invisible, due to being outside the view frustrum or out of range.
 -				new_priority = LLPluginClassMedia::PRIORITY_HIDDEN;
 -			}
 -			else if(check_cpu_usage && (total_cpu > max_cpu))
 -			{
 -				// Higher priority plugins have already used up the CPU budget.  Set remaining ones to slideshow priority.
 -				new_priority = LLPluginClassMedia::PRIORITY_SLIDESHOW;
 -			}
 -			else if((impl_count_interest_normal < (int)max_normal) && !media_is_small)
 -			{
 -				// Up to max_normal inworld get normal priority
 -				new_priority = LLPluginClassMedia::PRIORITY_NORMAL;
 -				impl_count_interest_normal++;
 -			}
 -			else if (impl_count_interest_low + impl_count_interest_normal < (int)max_low + (int)max_normal)
 -			{
 -				// The next max_low inworld get turned down
 -				new_priority = LLPluginClassMedia::PRIORITY_LOW;
 -				impl_count_interest_low++;
 -				
 -				// Set the low priority size for downsampling to approximately the size the texture is displayed at.
 -				{
 -					F32 approximate_interest_dimension = fsqrtf(pimpl->getInterest());
 -					
 -					pimpl->setLowPrioritySizeLimit(llround(approximate_interest_dimension));
 -				}
 -			}
 -			else
 -			{
 -				// Any additional impls (up to max_instances) get very infrequent time
 -				new_priority = LLPluginClassMedia::PRIORITY_SLIDESHOW;
 -			}
 -		}
 -		
 -		if(!pimpl->getUsedInUI() && (new_priority != LLPluginClassMedia::PRIORITY_UNLOADED))
 -		{
 -			// This is a loadable inworld impl -- the last one in the list in this class defines the lowest loadable interest.
 -			lowest_interest_loadable = pimpl;
 -			
 -			impl_count_total++;
 -		}
 -
 -		// Overrides if the window is minimized or we lost focus (taking care
 -		// not to accidentally "raise" the priority either)
 -		if (!gViewerWindow->getActive() /* viewer window minimized? */ 
 -			&& new_priority > LLPluginClassMedia::PRIORITY_HIDDEN)
 -		{
 -			new_priority = LLPluginClassMedia::PRIORITY_HIDDEN;
 -		}
 -		else if (!gFocusMgr.getAppHasFocus() /* viewer window lost focus? */
 -				 && new_priority > LLPluginClassMedia::PRIORITY_LOW)
 -		{
 -			new_priority = LLPluginClassMedia::PRIORITY_LOW;
 -		}
 -		
 -		if(!inworld_media_enabled)
 -		{
 -			// If inworld media is locked out, force all inworld media to stay unloaded.
 -			if(!pimpl->getUsedInUI())
 -			{
 -				new_priority = LLPluginClassMedia::PRIORITY_UNLOADED;
 -			}
 -		}
 -		// update the audio stream here as well
 -		if( !inworld_audio_enabled)
 -		{
 -			if(LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio())
 -			{
 -				gAudiop->stopInternetStream();
 -			}
 -		}
 -		pimpl->setPriority(new_priority);
 -		
 -		if(pimpl->getUsedInUI())
 -		{
 -			// Any impls used in the UI should not be in the proximity list.
 -			pimpl->mProximity = -1;
 -		}
 -		else
 -		{
 -			proximity_order.push_back(pimpl);
 -		}
 -
 -		total_cpu += pimpl->getCPUUsage();
 -		
 -		if (!pimpl->getUsedInUI() && pimpl->hasMedia())
 -		{
 -			sAnyMediaShowing = true;
 -		}
 -
 -	}
 -
 -	// Re-calculate this every time.
 -	sLowestLoadableImplInterest	= 0.0f;
 -
 -	// Only do this calculation if we've hit the impl count limit -- up until that point we always need to load media data.
 -	if(lowest_interest_loadable && (impl_count_total >= (int)max_instances))
 -	{
 -		// Get the interest value of this impl's object for use by isInterestingEnough
 -		LLVOVolume *object = lowest_interest_loadable->getSomeObject();
 -		if(object)
 -		{
 -			// NOTE: Don't use getMediaInterest() here.  We want the pixel area, not the total media interest,
 -			// 		so that we match up with the calculation done in LLMediaDataClient.
 -			sLowestLoadableImplInterest = object->getPixelArea();
 -		}
 -	}
 -	
 -	if(gSavedSettings.getBOOL("MediaPerformanceManagerDebug"))
 -	{
 -		// Give impls the same ordering as the priority list
 -		// they're already in the right order for this.
 -	}
 -	else
 -	{
 -		// Use a distance-based sort for proximity values.  
 -		std::stable_sort(proximity_order.begin(), proximity_order.end(), proximity_comparitor);
 -	}
 -
 -	// Transfer the proximity order to the proximity fields in the objects.
 -	for(int i = 0; i < (int)proximity_order.size(); i++)
 -	{
 -		proximity_order[i]->mProximity = i;
 -	}
 -	
 -	LL_DEBUGS("PluginPriority") << "Total reported CPU usage is " << total_cpu << llendl;
 -
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -bool LLViewerMedia::isAnyMediaShowing()
 -{
 -	return sAnyMediaShowing;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::setAllMediaEnabled(bool val)
 -{
 -	// Set "tentative" autoplay first.  We need to do this here or else
 -	// re-enabling won't start up the media below.
 -	gSavedSettings.setBOOL("MediaTentativeAutoPlay", val);
 -	
 -	// Then 
 -	impl_list::iterator iter = sViewerMediaImplList.begin();
 -	impl_list::iterator end = sViewerMediaImplList.end();
 -	
 -	for(; iter != end; iter++)
 -	{
 -		LLViewerMediaImpl* pimpl = *iter;
 -		if (!pimpl->getUsedInUI())
 -		{
 -			pimpl->setDisabled(!val);
 -		}
 -	}
 -	
 -	// Also do Parcel Media and Parcel Audio
 -	if (val)
 -	{
 -		if (!LLViewerMedia::isParcelMediaPlaying() && LLViewerMedia::hasParcelMedia())
 -		{	
 -			LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel());
 -		}
 -		
 -		if (gSavedSettings.getBOOL("AudioStreamingMusic") &&
 -			!LLViewerMedia::isParcelAudioPlaying() &&
 -			gAudiop && 
 -			LLViewerMedia::hasParcelAudio())
 -		{
 -			gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL());
 -		}
 -	}
 -	else {
 -		// This actually unloads the impl, as opposed to "stop"ping the media
 -		LLViewerParcelMedia::stop();
 -		if (gAudiop) gAudiop->stopInternetStream();
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -bool LLViewerMedia::isParcelMediaPlaying()
 -{
 -	return (LLViewerMedia::hasParcelMedia() && LLViewerParcelMedia::getParcelMedia() && LLViewerParcelMedia::getParcelMedia()->hasMedia());
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -bool LLViewerMedia::isParcelAudioPlaying()
 -{
 -	return (LLViewerMedia::hasParcelAudio() && gAudiop && LLAudioEngine::AUDIO_PLAYING == gAudiop->isInternetStreamPlaying());
 -}
 -
 -void LLViewerMedia::onAuthSubmit(const LLSD& notification, const LLSD& response)
 -{
 -	LLViewerMediaImpl *impl = LLViewerMedia::getMediaImplFromTextureID(notification["payload"]["media_id"]);
 -	if(impl)
 -	{
 -		LLPluginClassMedia* media = impl->getMediaPlugin();
 -		if(media)
 -		{
 -			if (response["ok"])
 -			{
 -				media->sendAuthResponse(true, response["username"], response["password"]);
 -			}
 -			else
 -			{
 -				media->sendAuthResponse(false, "", "");
 -			}
 -		}
 -	}
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::clearAllCookies()
 -{
 -	// Clear all cookies for all plugins
 -	impl_list::iterator iter = sViewerMediaImplList.begin();
 -	impl_list::iterator end = sViewerMediaImplList.end();
 -	for (; iter != end; iter++)
 -	{
 -		LLViewerMediaImpl* pimpl = *iter;
 -		if(pimpl->mMediaSource)
 -		{
 -			pimpl->mMediaSource->clear_cookies();
 -		}
 -	}
 -	
 -	// Clear all cookies from the cookie store
 -	getCookieStore()->setAllCookies("");
 -
 -	// FIXME: this may not be sufficient, since the on-disk cookie file won't get written until some browser instance exits cleanly.
 -	// It also won't clear cookies for other accounts, or for any account if we're not logged in, and won't do anything at all if there are no webkit plugins loaded.
 -	// Until such time as we can centralize cookie storage, the following hack should cover these cases:
 -	
 -	// HACK: Look for cookie files in all possible places and delete them.
 -	// NOTE: this assumes knowledge of what happens inside the webkit plugin (it's what adds 'browser_profile' to the path and names the cookie file)
 -	
 -	// Places that cookie files can be:
 -	// <getOSUserAppDir>/browser_profile/cookies
 -	// <getOSUserAppDir>/first_last/browser_profile/cookies  (note that there may be any number of these!)
 -	// <getOSUserAppDir>/first_last/plugin_cookies.txt  (note that there may be any number of these!)
 -	
 -	std::string base_dir = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter();
 -	std::string target;
 -	std::string filename;
 -	
 -	lldebugs << "base dir = " << base_dir << llendl;
 -
 -	// The non-logged-in version is easy
 -	target = base_dir;
 -	target += "browser_profile";
 -	target += gDirUtilp->getDirDelimiter();
 -	target += "cookies";
 -	lldebugs << "target = " << target << llendl;
 -	if(LLFile::isfile(target))
 -	{
 -		LLFile::remove(target);
 -	}
 -	
 -	// the hard part: iterate over all user directories and delete the cookie file from each one
 -	while(gDirUtilp->getNextFileInDir(base_dir, "*_*", filename))
 -	{
 -		target = base_dir;
 -		target += filename;
 -		target += gDirUtilp->getDirDelimiter();
 -		target += "browser_profile";
 -		target += gDirUtilp->getDirDelimiter();
 -		target += "cookies";
 -		lldebugs << "target = " << target << llendl;
 -		if(LLFile::isfile(target))
 -		{	
 -			LLFile::remove(target);
 -		}
 -		
 -		// Other accounts may have new-style cookie files too -- delete them as well
 -		target = base_dir;
 -		target += filename;
 -		target += gDirUtilp->getDirDelimiter();
 -		target += PLUGIN_COOKIE_FILE_NAME;
 -		lldebugs << "target = " << target << llendl;
 -		if(LLFile::isfile(target))
 -		{	
 -			LLFile::remove(target);
 -		}
 -	}
 -	
 -	// If we have an OpenID cookie, re-add it to the cookie store.
 -	setOpenIDCookie();
 -}
 -	
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static 
 -void LLViewerMedia::clearAllCaches()
 -{
 -	// Clear all plugins' caches
 -	impl_list::iterator iter = sViewerMediaImplList.begin();
 -	impl_list::iterator end = sViewerMediaImplList.end();
 -	for (; iter != end; iter++)
 -	{
 -		LLViewerMediaImpl* pimpl = *iter;
 -		pimpl->clearCache();
 -	}
 -}
 -	
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static 
 -void LLViewerMedia::setCookiesEnabled(bool enabled)
 -{
 -	// Set the "cookies enabled" flag for all loaded plugins
 -	impl_list::iterator iter = sViewerMediaImplList.begin();
 -	impl_list::iterator end = sViewerMediaImplList.end();
 -	for (; iter != end; iter++)
 -	{
 -		LLViewerMediaImpl* pimpl = *iter;
 -		if(pimpl->mMediaSource)
 -		{
 -			pimpl->mMediaSource->enable_cookies(enabled);
 -		}
 -	}
 -}
 -	
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static 
 -void LLViewerMedia::setProxyConfig(bool enable, const std::string &host, int port)
 -{
 -	// Set the proxy config for all loaded plugins
 -	impl_list::iterator iter = sViewerMediaImplList.begin();
 -	impl_list::iterator end = sViewerMediaImplList.end();
 -	for (; iter != end; iter++)
 -	{
 -		LLViewerMediaImpl* pimpl = *iter;
 -		if(pimpl->mMediaSource)
 -		{
 -			pimpl->mMediaSource->proxy_setup(enable, host, port);
 -		}
 -	}
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static 
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -LLPluginCookieStore *LLViewerMedia::getCookieStore()
 -{
 -	if(sCookieStore == NULL)
 -	{
 -		sCookieStore = new LLPluginCookieStore;
 -	}
 -	
 -	return sCookieStore;
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::loadCookieFile()
 -{
 -	// build filename for each user
 -	std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME);
 -
 -	if (resolved_filename.empty())
 -	{
 -		llinfos << "can't get path to plugin cookie file - probably not logged in yet." << llendl;
 -		return;
 -	}
 -	
 -	// open the file for reading
 -	llifstream file(resolved_filename);
 -	if (!file.is_open())
 -	{
 -		llwarns << "can't load plugin cookies from file \"" << PLUGIN_COOKIE_FILE_NAME << "\"" << llendl;
 -		return;
 -	}
 -	
 -	getCookieStore()->readAllCookies(file, true);
 -
 -	file.close();
 -	
 -	// send the clear_cookies message to all loaded plugins
 -	impl_list::iterator iter = sViewerMediaImplList.begin();
 -	impl_list::iterator end = sViewerMediaImplList.end();
 -	for (; iter != end; iter++)
 -	{
 -		LLViewerMediaImpl* pimpl = *iter;
 -		if(pimpl->mMediaSource)
 -		{
 -			pimpl->mMediaSource->clear_cookies();
 -		}
 -	}
 -	
 -	// If we have an OpenID cookie, re-add it to the cookie store.
 -	setOpenIDCookie();
 -}
 -
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::saveCookieFile()
 -{
 -	// build filename for each user
 -	std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME);
 -
 -	if (resolved_filename.empty())
 -	{
 -		llinfos << "can't get path to plugin cookie file - probably not logged in yet." << llendl;
 -		return;
 -	}
 -
 -	// open a file for writing
 -	llofstream file (resolved_filename);
 -	if (!file.is_open())
 -	{
 -		llwarns << "can't open plugin cookie file \"" << PLUGIN_COOKIE_FILE_NAME << "\" for writing" << llendl;
 -		return;
 -	}
 -
 -	getCookieStore()->writePersistentCookies(file);
 -
 -	file.close();
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::addCookie(const std::string &name, const std::string &value, const std::string &domain, const LLDate &expires, const std::string &path, bool secure)
 -{
 -	std::stringstream cookie;
 -	
 -	cookie << name << "=" << LLPluginCookieStore::quoteString(value);
 -	
 -	if(expires.notNull())
 -	{
 -		cookie << "; expires=" << expires.asRFC1123();
 -	}
 -	
 -	cookie << "; domain=" << domain;
 -
 -	cookie << "; path=" << path;
 -	
 -	if(secure)
 -	{
 -		cookie << "; secure";
 -	}
 -	
 -	getCookieStore()->setCookies(cookie.str());
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path, bool secure)
 -{
 -	// A session cookie just has a NULL date.
 -	addCookie(name, value, domain, LLDate(), path, secure);
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::removeCookie(const std::string &name, const std::string &domain, const std::string &path )
 -{
 -	// To remove a cookie, add one with the same name, domain, and path that expires in the past.
 -	
 -	addCookie(name, "", domain, LLDate(LLDate::now().secondsSinceEpoch() - 1.0), path);
 -}
 -
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::setOpenIDCookie()
 -{
 -	if(!sOpenIDCookie.empty())
 -	{
 -		// The LLURL can give me the 'authority', which is of the form: [username[:password]@]hostname[:port]
 -		// We want just the hostname for the cookie code, but LLURL doesn't seem to have a way to extract that.
 -		// We therefore do it here.
 -		std::string authority = sOpenIDURL.mAuthority;
 -		std::string::size_type host_start = authority.find('@'); 
 -		if(host_start == std::string::npos)
 -		{
 -			// no username/password
 -			host_start = 0;
 -		}
 -		else
 -		{
 -			// Hostname starts after the @. 
 -			// (If the hostname part is empty, this may put host_start at the end of the string.  In that case, it will end up passing through an empty hostname, which is correct.)
 -			++host_start;
 -		}
 -		std::string::size_type host_end = authority.rfind(':'); 
 -		if((host_end == std::string::npos) || (host_end < host_start))
 -		{
 -			// no port
 -			host_end = authority.size();
 -		}
 -		
 -		getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(host_start, host_end - host_start));
 -
 -		// *HACK: Doing this here is nasty, find a better way.
 -		LLWebSharing::instance().setOpenIDCookie(sOpenIDCookie);
 -
 -		// Do a web profile get so we can store the cookie 
 -		LLSD headers = LLSD::emptyMap();
 -		headers["Accept"] = "*/*";
 -		headers["Cookie"] = sOpenIDCookie;
 -		headers["User-Agent"] = getCurrentUserAgent();
 -
 -		std::string profile_url = getProfileURL("");
 -		LLURL raw_profile_url( profile_url.c_str() );
 -
 -		LLHTTPClient::get(profile_url,  
 -			new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),
 -			headers);
 -	}
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::openIDSetup(const std::string &openid_url, const std::string &openid_token)
 -{
 -	LL_DEBUGS("MediaAuth") << "url = \"" << openid_url << "\", token = \"" << openid_token << "\"" << LL_ENDL;
 -
 -	// post the token to the url 
 -	// the responder will need to extract the cookie(s).
 -
 -	// Save the OpenID URL for later -- we may need the host when adding the cookie.
 -	sOpenIDURL.init(openid_url.c_str());
 -	
 -	// We shouldn't ever do this twice, but just in case this code gets repurposed later, clear existing cookies.
 -	sOpenIDCookie.clear();
 -
 -	LLSD headers = LLSD::emptyMap();
 -	// Keep LLHTTPClient from adding an "Accept: application/llsd+xml" header
 -	headers["Accept"] = "*/*";
 -	// and use the expected content-type for a post, instead of the LLHTTPClient::postRaw() default of "application/octet-stream"
 -	headers["Content-Type"] = "application/x-www-form-urlencoded";
 -
 -	// postRaw() takes ownership of the buffer and releases it later, so we need to allocate a new buffer here.
 -	size_t size = openid_token.size();
 -	U8 *data = new U8[size];
 -	memcpy(data, openid_token.data(), size);
 -
 -	LLHTTPClient::postRaw( 
 -		openid_url, 
 -		data, 
 -		size, 
 -		new LLViewerMediaOpenIDResponder(),
 -		headers);
 -			
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::openIDCookieResponse(const std::string &cookie)
 -{
 -	LL_DEBUGS("MediaAuth") << "Cookie received: \"" << cookie << "\"" << LL_ENDL;
 -	
 -	sOpenIDCookie += cookie;
 -
 -	setOpenIDCookie();
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::proxyWindowOpened(const std::string &target, const std::string &uuid)
 -{
 -	if(uuid.empty())
 -		return;
 -		
 -	for (impl_list::iterator iter = sViewerMediaImplList.begin(); iter != sViewerMediaImplList.end(); iter++)
 -	{
 -		if((*iter)->mMediaSource && (*iter)->mMediaSource->pluginSupportsMediaBrowser())
 -		{
 -			(*iter)->mMediaSource->proxyWindowOpened(target, uuid);
 -		}
 -	}
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::proxyWindowClosed(const std::string &uuid)
 -{
 -	if(uuid.empty())
 -		return;
 -
 -	for (impl_list::iterator iter = sViewerMediaImplList.begin(); iter != sViewerMediaImplList.end(); iter++)
 -	{
 -		if((*iter)->mMediaSource && (*iter)->mMediaSource->pluginSupportsMediaBrowser())
 -		{
 -			(*iter)->mMediaSource->proxyWindowClosed(uuid);
 -		}
 -	}
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::createSpareBrowserMediaSource()
 -{
 -	// If we don't have a spare browser media source, create one.
 -	// However, if PluginAttachDebuggerToPlugins is set then don't spawn a spare
 -	// SLPlugin process in order to not be confused by an unrelated gdb terminal
 -	// popping up at the moment we start a media plugin.
 -	if (!sSpareBrowserMediaSource && !gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))
 -	{
 -		// The null owner will keep the browser plugin from fully initializing 
 -		// (specifically, it keeps LLPluginClassMedia from negotiating a size change, 
 -		// which keeps MediaPluginWebkit::initBrowserWindow from doing anything until we have some necessary data, like the background color)
 -		sSpareBrowserMediaSource = LLViewerMediaImpl::newSourceFromMediaType("text/html", NULL, 0, 0);
 -	}
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -LLPluginClassMedia* LLViewerMedia::getSpareBrowserMediaSource() 
 -{
 -	LLPluginClassMedia* result = sSpareBrowserMediaSource;
 -	sSpareBrowserMediaSource = NULL;
 -	return result; 
 -};
 -
 -bool LLViewerMedia::hasInWorldMedia()
 -{
 -	if (sInWorldMediaDisabled) return false;
 -	impl_list::iterator iter = sViewerMediaImplList.begin();
 -	impl_list::iterator end = sViewerMediaImplList.end();
 -	// This should be quick, because there should be very few non-in-world-media impls
 -	for (; iter != end; iter++)
 -	{
 -		LLViewerMediaImpl* pimpl = *iter;
 -		if (!pimpl->getUsedInUI() && !pimpl->isParcelMedia())
 -		{
 -			// Found an in-world media impl
 -			return true;
 -		}
 -	}
 -	return false;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -bool LLViewerMedia::hasParcelMedia()
 -{
 -	return !LLViewerParcelMedia::getURL().empty();
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -bool LLViewerMedia::hasParcelAudio()
 -{
 -	return !LLViewerMedia::getParcelAudioURL().empty();
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -std::string LLViewerMedia::getParcelAudioURL()
 -{
 -	return LLViewerParcelMgr::getInstance()->getAgentParcel()->getMusicURL();
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::initClass()
 -{
 -	gIdleCallbacks.addFunction(LLViewerMedia::updateMedia, NULL);	
 -	sTeleportFinishConnection = LLViewerParcelMgr::getInstance()->
 -		setTeleportFinishedCallback(boost::bind(&LLViewerMedia::onTeleportFinished));
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::cleanupClass()
 -{
 -	gIdleCallbacks.deleteFunction(LLViewerMedia::updateMedia, NULL);
 -	sTeleportFinishConnection.disconnect();
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// static
 -void LLViewerMedia::onTeleportFinished()
 -{
 -	// On teleport, clear this setting (i.e. set it to true)
 -	gSavedSettings.setBOOL("MediaTentativeAutoPlay", true);
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -// LLViewerMediaImpl
 -//////////////////////////////////////////////////////////////////////////////////////////
 -LLViewerMediaImpl::LLViewerMediaImpl(	  const LLUUID& texture_id, 
 -										  S32 media_width, 
 -										  S32 media_height, 
 -										  U8 media_auto_scale, 
 -										  U8 media_loop)
 -:	
 -	mMediaSource( NULL ),
 -	mMovieImageHasMips(false),
 -	mMediaWidth(media_width),
 -	mMediaHeight(media_height),
 -	mMediaAutoScale(media_auto_scale),
 -	mMediaLoop(media_loop),
 -	mNeedsNewTexture(true),
 -	mTextureUsedWidth(0),
 -	mTextureUsedHeight(0),
 -	mSuspendUpdates(false),
 -	mVisible(true),
 -	mLastSetCursor( UI_CURSOR_ARROW ),
 -	mMediaNavState( MEDIANAVSTATE_NONE ),
 -	mInterest(0.0f),
 -	mUsedInUI(false),
 -	mHasFocus(false),
 -	mPriority(LLPluginClassMedia::PRIORITY_UNLOADED),
 -	mNavigateRediscoverType(false),
 -	mNavigateServerRequest(false),
 -	mMediaSourceFailed(false),
 -	mRequestedVolume(1.0f),
 -	mIsMuted(false),
 -	mNeedsMuteCheck(false),
 -	mPreviousMediaState(MEDIA_NONE),
 -	mPreviousMediaTime(0.0f),
 -	mIsDisabled(false),
 -	mIsParcelMedia(false),
 -	mProximity(-1),
 -	mProximityDistance(0.0f),
 -	mMimeTypeProbe(NULL),
 -	mMediaAutoPlay(false),
 -	mInNearbyMediaList(false),
 -	mClearCache(false),
 -	mBackgroundColor(LLColor4::white),
 -	mNavigateSuspended(false),
 -	mNavigateSuspendedDeferred(false),
 -	mIsUpdated(false),
 -	mTrustedBrowser(false)
 -{ 
 -
 -	// Set up the mute list observer if it hasn't been set up already.
 -	if(!sViewerMediaMuteListObserverInitialized)
 -	{
 -		LLMuteList::getInstance()->addObserver(&sViewerMediaMuteListObserver);
 -		sViewerMediaMuteListObserverInitialized = true;
 -	}
 -	
 -	add_media_impl(this);
 -
 -	setTextureID(texture_id);
 -	
 -	// connect this media_impl to the media texture, creating it if it doesn't exist.0
 -	// This is necessary because we need to be able to use getMaxVirtualSize() even if the media plugin is not loaded.
 -	LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture(mTextureId);
 -	if(media_tex)
 -	{
 -		media_tex->setMediaImpl();
 -	}
 -
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -LLViewerMediaImpl::~LLViewerMediaImpl()
 -{
 -	destroyMediaSource();
 -	
 -	LLViewerMediaTexture::removeMediaImplFromTexture(mTextureId) ;
 -
 -	setTextureID();
 -	remove_media_impl(this);
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::emitEvent(LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event)
 -{
 -	// Broadcast to observers using the superclass version
 -	LLViewerMediaEventEmitter::emitEvent(plugin, event);
 -	
 -	// If this media is on one or more LLVOVolume objects, tell them about the event as well.
 -	std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
 -	while(iter != mObjectList.end())
 -	{
 -		LLVOVolume *self = *iter;
 -		++iter;
 -		self->mediaEvent(this, plugin, event);
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -bool LLViewerMediaImpl::initializeMedia(const std::string& mime_type)
 -{
 -	bool mimeTypeChanged = (mMimeType != mime_type);
 -	bool pluginChanged = (LLMIMETypes::implType(mCurrentMimeType) != LLMIMETypes::implType(mime_type));
 -	
 -	if(!mMediaSource || pluginChanged)
 -	{
 -		// We don't have a plugin at all, or the new mime type is handled by a different plugin than the old mime type.
 -		(void)initializePlugin(mime_type);
 -	}
 -	else if(mimeTypeChanged)
 -	{
 -		// The same plugin should be able to handle the new media -- just update the stored mime type.
 -		mMimeType = mime_type;
 -	}
 -
 -	return (mMediaSource != NULL);
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::createMediaSource()
 -{
 -	if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
 -	{
 -		// This media shouldn't be created yet.
 -		return;
 -	}
 -	
 -	if(! mMediaURL.empty())
 -	{
 -		navigateInternal();
 -	}
 -	else if(! mMimeType.empty())
 -	{
 -		if (!initializeMedia(mMimeType))
 -		{
 -			LL_WARNS("Media") << "Failed to initialize media for mime type " << mMimeType << LL_ENDL;
 -		}
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::destroyMediaSource()
 -{
 -	mNeedsNewTexture = true;
 -
 -	// Tell the viewer media texture it's no longer active
 -	LLViewerMediaTexture* oldImage = LLViewerTextureManager::findMediaTexture( mTextureId );
 -	if (oldImage)
 -	{
 -		oldImage->setPlaying(FALSE) ;
 -	}
 -	
 -	cancelMimeTypeProbe();
 -	
 -	if(mMediaSource)
 -	{
 -		mMediaSource->setDeleteOK(true) ;
 -		delete mMediaSource;
 -		mMediaSource = NULL;
 -	}	
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::setMediaType(const std::string& media_type)
 -{
 -	mMimeType = media_type;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -/*static*/
 -LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, const std::string target)
 -{
 -	std::string plugin_basename = LLMIMETypes::implType(media_type);
 -	LLPluginClassMedia* media_source = NULL;
 -	
 -	// HACK: we always try to keep a spare running webkit plugin around to improve launch times.
 -	// If a spare was already created before PluginAttachDebuggerToPlugins was set, don't use it.
 -	if(plugin_basename == "media_plugin_webkit" && !gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))
 -	{
 -		media_source = LLViewerMedia::getSpareBrowserMediaSource();
 -		if(media_source)
 -		{
 -			media_source->setOwner(owner);
 -			media_source->setTarget(target);
 -			media_source->setSize(default_width, default_height);
 -						
 -			return media_source;
 -		}
 -	}
 -	
 -	if(plugin_basename.empty())
 -	{
 -		LL_WARNS("Media") << "Couldn't find plugin for media type " << media_type << LL_ENDL;
 -	}
 -	else
 -	{
 -		std::string launcher_name = gDirUtilp->getLLPluginLauncher();
 -		std::string plugin_name = gDirUtilp->getLLPluginFilename(plugin_basename);
 -		std::string user_data_path = gDirUtilp->getOSUserAppDir();
 -		user_data_path += gDirUtilp->getDirDelimiter();
 -
 -		// Fix for EXT-5960 - make browser profile specific to user (cache, cookies etc.)
 -		// If the linden username returned is blank, that can only mean we are
 -		// at the login page displaying login Web page or Web browser test via Develop menu.
 -		// In this case we just use whatever gDirUtilp->getOSUserAppDir() gives us (this
 -		// is what we always used before this change)
 -		std::string linden_user_dir = gDirUtilp->getLindenUserDir();
 -		if ( ! linden_user_dir.empty() )
 -		{
 -			// gDirUtilp->getLindenUserDir() is whole path, not just Linden name
 -			user_data_path = linden_user_dir;
 -			user_data_path += gDirUtilp->getDirDelimiter();
 -		};
 -
 -		// See if the plugin executable exists
 -		llstat s;
 -		if(LLFile::stat(launcher_name, &s))
 -		{
 -			LL_WARNS("Media") << "Couldn't find launcher at " << launcher_name << LL_ENDL;
 -		}
 -		else if(LLFile::stat(plugin_name, &s))
 -		{
 -			LL_WARNS("Media") << "Couldn't find plugin at " << plugin_name << LL_ENDL;
 -		}
 -		else
 -		{
 -			media_source = new LLPluginClassMedia(owner);
 -			media_source->setSize(default_width, default_height);
 -			media_source->setUserDataPath(user_data_path);
 -			media_source->setLanguageCode(LLUI::getLanguage());
 -
 -			// collect 'cookies enabled' setting from prefs and send to embedded browser
 -			bool cookies_enabled = gSavedSettings.getBOOL( "CookiesEnabled" );
 -			media_source->enable_cookies( cookies_enabled );
 -
 -			// collect 'plugins enabled' setting from prefs and send to embedded browser
 -			bool plugins_enabled = gSavedSettings.getBOOL( "BrowserPluginsEnabled" );
 -			media_source->setPluginsEnabled( plugins_enabled );
 -
 -			// collect 'javascript enabled' setting from prefs and send to embedded browser
 -			bool javascript_enabled = gSavedSettings.getBOOL( "BrowserJavascriptEnabled" );
 -			media_source->setJavascriptEnabled( javascript_enabled );
 -			
 -			media_source->setTarget(target);
 -			
 -			const std::string plugin_dir = gDirUtilp->getLLPluginDir();
 -			if (media_source->init(launcher_name, plugin_dir, plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins")))
 -			{
 -				return media_source;
 -			}
 -			else
 -			{
 -				LL_WARNS("Media") << "Failed to init plugin.  Destroying." << LL_ENDL;
 -				delete media_source;
 -			}
 -		}
 -	}
 -	
 -	LL_WARNS("Plugin") << "plugin intialization failed for mime type: " << media_type << LL_ENDL;
 -	LLSD args;
 -	args["MIME_TYPE"] = media_type;
 -	LLNotificationsUtil::add("NoPlugin", args);
 -
 -	return NULL;
 -}							
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
 -{
 -	if(mMediaSource)
 -	{
 -		// Save the previous media source's last set size before destroying it.
 -		mMediaWidth = mMediaSource->getSetWidth();
 -		mMediaHeight = mMediaSource->getSetHeight();
 -	}
 -	
 -	// Always delete the old media impl first.
 -	destroyMediaSource();
 -	
 -	// and unconditionally set the mime type
 -	mMimeType = media_type;
 -
 -	if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
 -	{
 -		// This impl should not be loaded at this time.
 -		LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL;
 -		
 -		return false;
 -	}
 -
 -	// If we got here, we want to ignore previous init failures.
 -	mMediaSourceFailed = false;
 -
 -	// Save the MIME type that really caused the plugin to load
 -	mCurrentMimeType = mMimeType;
 -
 -	LLPluginClassMedia* media_source = newSourceFromMediaType(mMimeType, this, mMediaWidth, mMediaHeight, mTarget);
 -	
 -	if (media_source)
 -	{
 -		media_source->setDisableTimeout(gSavedSettings.getBOOL("DebugPluginDisableTimeout"));
 -		media_source->setLoop(mMediaLoop);
 -		media_source->setAutoScale(mMediaAutoScale);
 -		media_source->setBrowserUserAgent(LLViewerMedia::getCurrentUserAgent());
 -		media_source->focus(mHasFocus);
 -		media_source->setBackgroundColor(mBackgroundColor);
 -		
 -		if(gSavedSettings.getBOOL("BrowserIgnoreSSLCertErrors"))
 -		{
 -			media_source->ignore_ssl_cert_errors(true);
 -		}
 -
 -		// the correct way to deal with certs it to load ours from CA.pem and append them to the ones
 -		// Qt/WebKit loads from your system location.
 -		// Note: This needs the new CA.pem file with the Equifax Secure Certificate Authority 
 -		// cert at the bottom: (MIIDIDCCAomgAwIBAgIENd70zzANBg)
 -		std::string ca_path = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "CA.pem" );
 -		media_source->addCertificateFilePath( ca_path );
 -
 -		media_source->proxy_setup(gSavedSettings.getBOOL("BrowserProxyEnabled"), gSavedSettings.getString("BrowserProxyAddress"), gSavedSettings.getS32("BrowserProxyPort"));
 -		
 -		if(mClearCache)
 -		{
 -			mClearCache = false;
 -			media_source->clear_cache();
 -		}
 -		
 -		// TODO: Only send cookies to plugins that need them
 -		//  Ideally, the plugin should tell us whether it handles cookies or not -- either via the init response or through a separate message.
 -		//  Due to the ordering of messages, it's possible we wouldn't get that information back in time to send cookies before sending a navigate message,
 -		//  which could cause odd race conditions.
 -		std::string all_cookies = LLViewerMedia::getCookieStore()->getAllCookies();
 -		lldebugs << "setting cookies: " << all_cookies << llendl;
 -		if(!all_cookies.empty())
 -		{
 -			media_source->set_cookies(all_cookies);
 -		}
 -				
 -		mMediaSource = media_source;
 -		mMediaSource->setDeleteOK(false) ;
 -		updateVolume();
 -
 -		return true;
 -	}
 -
 -	// Make sure the timer doesn't try re-initing this plugin repeatedly until something else changes.
 -	mMediaSourceFailed = true;
 -
 -	return false;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::loadURI()
 -{
 -	if(mMediaSource)
 -	{
 -		// trim whitespace from front and back of URL - fixes EXT-5363
 -		LLStringUtil::trim( mMediaURL );
 -
 -		// *HACK: we don't know if the URI coming in is properly escaped
 -		// (the contract doesn't specify whether it is escaped or not.
 -		// but LLQtWebKit expects it to be, so we do our best to encode
 -		// special characters)
 -		// The strings below were taken right from http://www.ietf.org/rfc/rfc1738.txt
 -		// Note especially that '%' and '/' are there.
 -		std::string uri = LLURI::escape(mMediaURL,
 -										"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
 -										"0123456789"
 -										"$-_.+"
 -										"!*'(),"
 -										"{}|\\^~[]`"
 -										"<>#%"
 -										";/?:@&=",
 -										false);
 -		llinfos << "Asking media source to load URI: " << uri << llendl;
 -		
 -		mMediaSource->loadURI( uri );
 -		
 -		// A non-zero mPreviousMediaTime means that either this media was previously unloaded by the priority code while playing/paused, 
 -		// or a seek happened before the media loaded.  In either case, seek to the saved time.
 -		if(mPreviousMediaTime != 0.0f)
 -		{
 -			seek(mPreviousMediaTime);
 -		}
 -			
 -		if(mPreviousMediaState == MEDIA_PLAYING)
 -		{
 -			// This media was playing before this instance was unloaded.
 -			start();
 -		}
 -		else if(mPreviousMediaState == MEDIA_PAUSED)
 -		{
 -			// This media was paused before this instance was unloaded.
 -			pause();
 -		}
 -		else
 -		{
 -			// No relevant previous media play state -- if we're loading the URL, we want to start playing.
 -			start();
 -		}
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::setSize(int width, int height)
 -{
 -	mMediaWidth = width;
 -	mMediaHeight = height;
 -	if(mMediaSource)
 -	{
 -		mMediaSource->setSize(width, height);
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::showNotification(LLNotificationPtr notify)
 -{
 -	mNotification = notify;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::hideNotification()
 -{
 -	mNotification.reset();
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::play()
 -{
 -	// If the media source isn't there, try to initialize it and load an URL.
 -	if(mMediaSource == NULL)
 -	{
 -	 	if(!initializeMedia(mMimeType))
 -		{
 -			// This may be the case where the plugin's priority is PRIORITY_UNLOADED
 -			return;
 -		}
 -		
 -		// Only do this if the media source was just loaded.
 -		loadURI();
 -	}
 -	
 -	// always start the media
 -	start();
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::stop()
 -{
 -	if(mMediaSource)
 -	{
 -		mMediaSource->stop();
 -		// destroyMediaSource();
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::pause()
 -{
 -	if(mMediaSource)
 -	{
 -		mMediaSource->pause();
 -	}
 -	else
 -	{
 -		mPreviousMediaState = MEDIA_PAUSED;
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::start()
 -{
 -	if(mMediaSource)
 -	{
 -		mMediaSource->start();
 -	}
 -	else
 -	{
 -		mPreviousMediaState = MEDIA_PLAYING;
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::seek(F32 time)
 -{
 -	if(mMediaSource)
 -	{
 -		mMediaSource->seek(time);
 -	}
 -	else
 -	{
 -		// Save the seek time to be set when the media is loaded.
 -		mPreviousMediaTime = time;
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::skipBack(F32 step_scale)
 -{
 -	if(mMediaSource)
 -	{
 -		if(mMediaSource->pluginSupportsMediaTime())
 -		{
 -			F64 back_step = mMediaSource->getCurrentTime() - (mMediaSource->getDuration()*step_scale);
 -			if(back_step < 0.0)
 -			{
 -				back_step = 0.0;
 -			}
 -			mMediaSource->seek(back_step);
 -		}
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::skipForward(F32 step_scale)
 -{
 -	if(mMediaSource)
 -	{
 -		if(mMediaSource->pluginSupportsMediaTime())
 -		{
 -			F64 forward_step = mMediaSource->getCurrentTime() + (mMediaSource->getDuration()*step_scale);
 -			if(forward_step > mMediaSource->getDuration())
 -			{
 -				forward_step = mMediaSource->getDuration();
 -			}
 -			mMediaSource->seek(forward_step);
 -		}
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::setVolume(F32 volume)
 -{
 -	mRequestedVolume = volume;
 -	updateVolume();
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::updateVolume()
 -{
 -	if(mMediaSource)
 -	{
 -		// always scale the volume by the global media volume 
 -		F32 volume = mRequestedVolume * LLViewerMedia::getVolume();
 -
 -		if (mProximityCamera > 0) 
 -		{
 -			if (mProximityCamera > gSavedSettings.getF32("MediaRollOffMax"))
 -			{
 -				volume = 0;
 -			}
 -			else if (mProximityCamera > gSavedSettings.getF32("MediaRollOffMin"))
 -			{
 -				// attenuated_volume = 1 / (roll_off_rate * (d - min))^2
 -				// the +1 is there so that for distance 0 the volume stays the same
 -				F64 adjusted_distance = mProximityCamera - gSavedSettings.getF32("MediaRollOffMin");
 -				F64 attenuation = 1.0 + (gSavedSettings.getF32("MediaRollOffRate") * adjusted_distance);
 -				attenuation = 1.0 / (attenuation * attenuation);
 -				// the attenuation multiplier should never be more than one since that would increase volume
 -				volume = volume * llmin(1.0, attenuation);
 -			}
 -		}
 -
 -		mMediaSource->setVolume(volume);
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -F32 LLViewerMediaImpl::getVolume()
 -{
 -	return mRequestedVolume;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::focus(bool focus)
 -{
 -	mHasFocus = focus;
 -	
 -	if (mMediaSource)
 -	{
 -		// call focus just for the hell of it, even though this apopears to be a nop
 -		mMediaSource->focus(focus);
 -		if (focus)
 -		{
 -			// spoof a mouse click to *actually* pass focus
 -			// Don't do this anymore -- it actually clicks through now.
 -//			mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, 1, 1, 0);
 -//			mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, 1, 1, 0);
 -		}
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -bool LLViewerMediaImpl::hasFocus() const
 -{
 -	// FIXME: This might be able to be a bit smarter by hooking into LLViewerMediaFocus, etc.
 -	return mHasFocus;
 -}
 -
 -std::string LLViewerMediaImpl::getCurrentMediaURL()
 -{
 -	if(!mCurrentMediaURL.empty())
 -	{
 -		return mCurrentMediaURL;
 -	}
 -	
 -	return mMediaURL;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::clearCache()
 -{
 -	if(mMediaSource)
 -	{
 -		mMediaSource->clear_cache();
 -	}
 -	else
 -	{
 -		mClearCache = true;
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::mouseDown(S32 x, S32 y, MASK mask, S32 button)
 -{
 -	scaleMouse(&x, &y);
 -	mLastMouseX = x;
 -	mLastMouseY = y;
 -//	llinfos << "mouse down (" << x << ", " << y << ")" << llendl;
 -	if (mMediaSource)
 -	{
 -		mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, button, x, y, mask);
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::mouseUp(S32 x, S32 y, MASK mask, S32 button)
 -{
 -	scaleMouse(&x, &y);
 -	mLastMouseX = x;
 -	mLastMouseY = y;
 -//	llinfos << "mouse up (" << x << ", " << y << ")" << llendl;
 -	if (mMediaSource)
 -	{
 -		mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, button, x, y, mask);
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::mouseMove(S32 x, S32 y, MASK mask)
 -{
 -    scaleMouse(&x, &y);
 -	mLastMouseX = x;
 -	mLastMouseY = y;
 -//	llinfos << "mouse move (" << x << ", " << y << ")" << llendl;
 -	if (mMediaSource)
 -	{
 -		mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, x, y, mask);
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -//static 
 -void LLViewerMediaImpl::scaleTextureCoords(const LLVector2& texture_coords, S32 *x, S32 *y)
 -{
 -	F32 texture_x = texture_coords.mV[VX];
 -	F32 texture_y = texture_coords.mV[VY];
 -	
 -	// Deal with repeating textures by wrapping the coordinates into the range [0, 1.0)
 -	texture_x = fmodf(texture_x, 1.0f);
 -	if(texture_x < 0.0f)
 -		texture_x = 1.0 + texture_x;
 -		
 -	texture_y = fmodf(texture_y, 1.0f);
 -	if(texture_y < 0.0f)
 -		texture_y = 1.0 + texture_y;
 -
 -	// scale x and y to texel units.
 -	*x = llround(texture_x * mMediaSource->getTextureWidth());
 -	*y = llround((1.0f - texture_y) * mMediaSource->getTextureHeight());
 -
 -	// Adjust for the difference between the actual texture height and the amount of the texture in use.
 -	*y -= (mMediaSource->getTextureHeight() - mMediaSource->getHeight());
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::mouseDown(const LLVector2& texture_coords, MASK mask, S32 button)
 -{
 -	if(mMediaSource)
 -	{
 -		S32 x, y;
 -		scaleTextureCoords(texture_coords, &x, &y);
 -
 -		mouseDown(x, y, mask, button);
 -	}
 -}
 -
 -void LLViewerMediaImpl::mouseUp(const LLVector2& texture_coords, MASK mask, S32 button)
 -{
 -	if(mMediaSource)
 -	{		
 -		S32 x, y;
 -		scaleTextureCoords(texture_coords, &x, &y);
 -
 -		mouseUp(x, y, mask, button);
 -	}
 -}
 -
 -void LLViewerMediaImpl::mouseMove(const LLVector2& texture_coords, MASK mask)
 -{
 -	if(mMediaSource)
 -	{		
 -		S32 x, y;
 -		scaleTextureCoords(texture_coords, &x, &y);
 -
 -		mouseMove(x, y, mask);
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button)
 -{
 -	scaleMouse(&x, &y);
 -	mLastMouseX = x;
 -	mLastMouseY = y;
 -	if (mMediaSource)
 -	{
 -		mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOUBLE_CLICK, button, x, y, mask);
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::scrollWheel(S32 x, S32 y, MASK mask)
 -{
 -	scaleMouse(&x, &y);
 -	mLastMouseX = x;
 -	mLastMouseY = y;
 -	if (mMediaSource)
 -	{
 -		mMediaSource->scrollEvent(x, y, mask);
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::onMouseCaptureLost()
 -{
 -	if (mMediaSource)
 -	{
 -		mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, 0, mLastMouseX, mLastMouseY, 0);
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask) 
 -{ 
 -	// NOTE: this is called when the mouse is released when we have capture.
 -	// Due to the way mouse coordinates are mapped to the object, we can't use the x and y coordinates that come in with the event.
 -	
 -	if(hasMouseCapture())
 -	{
 -		// Release the mouse -- this will also send a mouseup to the media
 -		gFocusMgr.setMouseCapture( FALSE );
 -	}
 -
 -	return TRUE; 
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::updateJavascriptObject()
 -{
 -	if ( mMediaSource )
 -	{
 -		// flag to expose this information to internal browser or not.
 -		bool expose_javascript_object = gSavedSettings.getBOOL("BrowserEnableJSObject");
 -		mMediaSource->jsExposeObjectEvent( expose_javascript_object );
 -
 -		// indicate if the values we have are valid (currently do this blanket-fashion for
 -		// everything depending on whether you are logged in or not - this may require a 
 -		// more granular approach once variables are added that ARE valid before login
 -		bool logged_in = LLLoginInstance::getInstance()->authSuccess();
 -		mMediaSource->jsValuesValidEvent( logged_in );
 -
 -		// current location within a region
 -		LLVector3 agent_pos = gAgent.getPositionAgent();
 -		double x = agent_pos.mV[ VX ];
 -		double y = agent_pos.mV[ VY ];
 -		double z = agent_pos.mV[ VZ ];
 -		mMediaSource->jsAgentLocationEvent( x, y, z );
 -
 -		// current region agent is in
 -		std::string region_name("");
 -		LLViewerRegion* region = gAgent.getRegion();
 -		if ( region )
 -		{
 -			region_name = region->getName();
 -		};
 -		mMediaSource->jsAgentRegionEvent( region_name );
 -
 -		// language code the viewer is set to
 -		mMediaSource->jsAgentLanguageEvent( LLUI::getLanguage() );
 -
 -		// maturity setting the agent has selected
 -		if ( gAgent.prefersAdult() )
 -			mMediaSource->jsAgentMaturityEvent( "GMA" );	// Adult means see adult, mature and general content
 -		else
 -		if ( gAgent.prefersMature() )
 -			mMediaSource->jsAgentMaturityEvent( "GM" );	// Mature means see mature and general content
 -		else
 -		if ( gAgent.prefersPG() )
 -			mMediaSource->jsAgentMaturityEvent( "G" );	// PG means only see General content
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -std::string LLViewerMediaImpl::getName() const 
 -{ 
 -	if (mMediaSource)
 -	{
 -		return mMediaSource->getMediaName();
 -	}
 -	
 -	return LLStringUtil::null; 
 -};
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::navigateBack()
 -{
 -	if (mMediaSource)
 -	{
 -		mMediaSource->browse_back();
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::navigateForward()
 -{
 -	if (mMediaSource)
 -	{
 -		mMediaSource->browse_forward();
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::navigateReload()
 -{
 -	navigateTo(getCurrentMediaURL(), "", true, false);
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::navigateHome()
 -{
 -	bool rediscover_mimetype = mHomeMimeType.empty();
 -	navigateTo(mHomeURL, mHomeMimeType, rediscover_mimetype, false);
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::unload()
 -{
 -	// Unload the media impl and clear its state.
 -	destroyMediaSource();
 -	resetPreviousMediaState();
 -	mMediaURL.clear();
 -	mMimeType.clear();
 -	mCurrentMediaURL.clear();
 -	mCurrentMimeType.clear();
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mime_type,  bool rediscover_type, bool server_request)
 -{
 -	cancelMimeTypeProbe();
 -
 -	if(mMediaURL != url)
 -	{
 -		// Don't carry media play state across distinct URLs.
 -		resetPreviousMediaState();
 -	}
 -	
 -	// Always set the current URL and MIME type.
 -	mMediaURL = url;
 -	mMimeType = mime_type;
 -	
 -	// Clear the current media URL, since it will no longer be correct.
 -	mCurrentMediaURL.clear();
 -	
 -	// if mime type discovery was requested, we'll need to do it when the media loads
 -	mNavigateRediscoverType = rediscover_type;
 -	
 -	// and if this was a server request, the navigate on load will also need to be one.
 -	mNavigateServerRequest = server_request;
 -	
 -	// An explicit navigate resets the "failed" flag.
 -	mMediaSourceFailed = false;
 -
 -	if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
 -	{
 -		// Helpful to have media urls in log file. Shouldn't be spammy.
 -		llinfos << "NOT LOADING media id= " << mTextureId << " url=" << url << " mime_type=" << mime_type << llendl;
 -
 -		// This impl should not be loaded at this time.
 -		LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL;
 -		
 -		return;
 -	}
 -
 -	navigateInternal();
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::navigateInternal()
 -{
 -	// Helpful to have media urls in log file. Shouldn't be spammy.
 -	llinfos << "media id= " << mTextureId << " url=" << mMediaURL << " mime_type=" << mMimeType << llendl;
 -
 -	if(mNavigateSuspended)
 -	{
 -		llwarns << "Deferring navigate." << llendl;
 -		mNavigateSuspendedDeferred = true;
 -		return;
 -	}
 -	
 -	if(mMimeTypeProbe != NULL)
 -	{
 -		llwarns << "MIME type probe already in progress -- bailing out." << llendl;
 -		return;
 -	}
 -	
 -	if(mNavigateServerRequest)
 -	{
 -		setNavState(MEDIANAVSTATE_SERVER_SENT);
 -	}
 -	else
 -	{
 -		setNavState(MEDIANAVSTATE_NONE);
 -	}
 -			
 -	// If the caller has specified a non-empty MIME type, look that up in our MIME types list.
 -	// If we have a plugin for that MIME type, use that instead of attempting auto-discovery.
 -	// This helps in supporting legacy media content where the server the media resides on returns a bogus MIME type
 -	// but the parcel owner has correctly set the MIME type in the parcel media settings.
 -	
 -	if(!mMimeType.empty() && (mMimeType != LLMIMETypes::getDefaultMimeType()))
 -	{
 -		std::string plugin_basename = LLMIMETypes::implType(mMimeType);
 -		if(!plugin_basename.empty())
 -		{
 -			// We have a plugin for this mime type
 -			mNavigateRediscoverType = false;
 -		}
 -	}
 -
 -	if(mNavigateRediscoverType)
 -	{
 -
 -		LLURI uri(mMediaURL);
 -		std::string scheme = uri.scheme();
 -
 -		if(scheme.empty() || "http" == scheme || "https" == scheme)
 -		{
 -			// If we don't set an Accept header, LLHTTPClient will add one like this:
 -			//    Accept: application/llsd+xml
 -			// which is really not what we want.
 -			LLSD headers = LLSD::emptyMap();
 -			headers["Accept"] = "*/*";
 -			// Allow cookies in the response, to prevent a redirect loop when accessing join.secondlife.com
 -			headers["Cookie"] = "";
 -			LLHTTPClient::getHeaderOnly( mMediaURL, new LLMimeDiscoveryResponder(this), headers, 10.0f);
 -		}
 -		else if("data" == scheme || "file" == scheme || "about" == scheme)
 -		{
 -			// FIXME: figure out how to really discover the type for these schemes
 -			// We use "data" internally for a text/html url for loading the login screen
 -			if(initializeMedia("text/html"))
 -			{
 -				loadURI();
 -			}
 -		}
 -		else
 -		{
 -			// This catches 'rtsp://' urls
 -			if(initializeMedia(scheme))
 -			{
 -				loadURI();
 -			}
 -		}
 -	}
 -	else if(initializeMedia(mMimeType))
 -	{
 -		loadURI();
 -	}
 -	else
 -	{
 -		LL_WARNS("Media") << "Couldn't navigate to: " << mMediaURL << " as there is no media type for: " << mMimeType << LL_ENDL;
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::navigateStop()
 -{
 -	if(mMediaSource)
 -	{
 -		mMediaSource->browse_stop();
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask)
 -{
 -	bool result = false;
 -	
 -	if (mMediaSource)
 -	{
 -		// FIXME: THIS IS SO WRONG.
 -		// Menu keys should be handled by the menu system and not passed to UI elements, but this is how LLTextEditor and LLLineEditor do it...
 -		if( MASK_CONTROL & mask )
 -		{
 -			result = true;
 -		}
 -		
 -		if(!result)
 -		{
 -			
 -			LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData();
 -			
 -			result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN ,key, mask, native_key_data);
 -			// Since the viewer internal event dispatching doesn't give us key-up events, simulate one here.
 -			(void)mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_UP ,key, mask, native_key_data);
 -		}
 -	}
 -	
 -	return result;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char)
 -{
 -	bool result = false;
 -	
 -	if (mMediaSource)
 -	{
 -		// only accept 'printable' characters, sigh...
 -		if (uni_char >= 32 // discard 'control' characters
 -			&& uni_char != 127) // SDL thinks this is 'delete' - yuck.
 -		{
 -			LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData();
 -			
 -			mMediaSource->textInput(wstring_to_utf8str(LLWString(1, uni_char)), gKeyboard->currentMask(FALSE), native_key_data);
 -		}
 -	}
 -	
 -	return result;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -bool LLViewerMediaImpl::canNavigateForward()
 -{
 -	BOOL result = FALSE;
 -	if (mMediaSource)
 -	{
 -		result = mMediaSource->getHistoryForwardAvailable();
 -	}
 -	return result;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -bool LLViewerMediaImpl::canNavigateBack()
 -{
 -	BOOL result = FALSE;
 -	if (mMediaSource)
 -	{
 -		result = mMediaSource->getHistoryBackAvailable();
 -	}
 -	return result;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::update()
 -{
 -	if(mMediaSource == NULL)
 -	{
 -		if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)
 -		{
 -			// This media source should not be loaded.
 -		}
 -		else if(mPriority <= LLPluginClassMedia::PRIORITY_SLIDESHOW)
 -		{
 -			// Don't load new instances that are at PRIORITY_SLIDESHOW or below.  They're just kept around to preserve state.
 -		}
 -		else if(mMimeTypeProbe != NULL)
 -		{
 -			// this media source is doing a MIME type probe -- don't try loading it again.
 -		}
 -		else
 -		{
 -			// This media may need to be loaded.
 -			if(sMediaCreateTimer.hasExpired())
 -			{
 -				LL_DEBUGS("PluginPriority") << this << ": creating media based on timer expiration" << LL_ENDL;
 -				createMediaSource();
 -				sMediaCreateTimer.setTimerExpirySec(LLVIEWERMEDIA_CREATE_DELAY);
 -			}
 -			else
 -			{
 -				LL_DEBUGS("PluginPriority") << this << ": NOT creating media (waiting on timer)" << LL_ENDL;
 -			}
 -		}
 -	}
 -	else
 -	{
 -		updateVolume();
 -
 -		// TODO: this is updated every frame - is this bad?
 -		updateJavascriptObject();
 -
 -		// If we didn't just create the impl, it may need to get cookie updates.
 -		if(!sUpdatedCookies.empty())
 -		{
 -			// TODO: Only send cookies to plugins that need them
 -			mMediaSource->set_cookies(sUpdatedCookies);
 -		}
 -	}
 -
 -	
 -	if(mMediaSource == NULL)
 -	{
 -		return;
 -	}
 -	
 -	// Make sure a navigate doesn't happen during the idle -- it can cause mMediaSource to get destroyed, which can cause a crash.
 -	setNavigateSuspended(true);
 -	
 -	mMediaSource->idle();
 -
 -	setNavigateSuspended(false);
 -
 -	if(mMediaSource == NULL)
 -	{
 -		return;
 -	}
 -	
 -	if(mMediaSource->isPluginExited())
 -	{
 -		resetPreviousMediaState();
 -		destroyMediaSource();
 -		return;
 -	}
 -
 -	if(!mMediaSource->textureValid())
 -	{
 -		return;
 -	}
 -	
 -	if(mSuspendUpdates || !mVisible)
 -	{
 -		return;
 -	}
 -	
 -	LLViewerMediaTexture* placeholder_image = updatePlaceholderImage();
 -		
 -	if(placeholder_image)
 -	{
 -		LLRect dirty_rect;
 -		
 -		// Since we're updating this texture, we know it's playing.  Tell the texture to do its replacement magic so it gets rendered.
 -		placeholder_image->setPlaying(TRUE);
 -
 -		if(mMediaSource->getDirty(&dirty_rect))
 -		{
 -			// Constrain the dirty rect to be inside the texture
 -			S32 x_pos = llmax(dirty_rect.mLeft, 0);
 -			S32 y_pos = llmax(dirty_rect.mBottom, 0);
 -			S32 width = llmin(dirty_rect.mRight, placeholder_image->getWidth()) - x_pos;
 -			S32 height = llmin(dirty_rect.mTop, placeholder_image->getHeight()) - y_pos;
 -			
 -			if(width > 0 && height > 0)
 -			{
 -
 -				U8* data = mMediaSource->getBitsData();
 -
 -				// Offset the pixels pointer to match x_pos and y_pos
 -				data += ( x_pos * mMediaSource->getTextureDepth() * mMediaSource->getBitsWidth() );
 -				data += ( y_pos * mMediaSource->getTextureDepth() );
 -				
 -				placeholder_image->setSubImage(
 -						data, 
 -						mMediaSource->getBitsWidth(), 
 -						mMediaSource->getBitsHeight(),
 -						x_pos, 
 -						y_pos, 
 -						width, 
 -						height);
 -
 -			}
 -			
 -			mMediaSource->resetDirty();
 -		}
 -	}
 -}
 -
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::updateImagesMediaStreams()
 -{
 -}
 -
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage()
 -{
 -	if(mTextureId.isNull())
 -	{
 -		// The code that created this instance will read from the plugin's bits.
 -		return NULL;
 -	}
 -	
 -	LLViewerMediaTexture* placeholder_image = LLViewerTextureManager::getMediaTexture( mTextureId );
 -	
 -	if (mNeedsNewTexture 
 -		|| placeholder_image->getUseMipMaps()
 -		|| (placeholder_image->getWidth() != mMediaSource->getTextureWidth())
 -		|| (placeholder_image->getHeight() != mMediaSource->getTextureHeight())
 -		|| (mTextureUsedWidth != mMediaSource->getWidth())
 -		|| (mTextureUsedHeight != mMediaSource->getHeight())
 -		)
 -	{
 -		LL_DEBUGS("Media") << "initializing media placeholder" << LL_ENDL;
 -		LL_DEBUGS("Media") << "movie image id " << mTextureId << LL_ENDL;
 -
 -		int texture_width = mMediaSource->getTextureWidth();
 -		int texture_height = mMediaSource->getTextureHeight();
 -		int texture_depth = mMediaSource->getTextureDepth();
 -		
 -		// MEDIAOPT: check to see if size actually changed before doing work
 -		placeholder_image->destroyGLTexture();
 -		// MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work?
 -		placeholder_image->reinit(FALSE);	// probably not needed
 -
 -		// MEDIAOPT: seems insane that we actually have to make an imageraw then
 -		// immediately discard it
 -		LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth);
 -		// Clear the texture to the background color, ignoring alpha.
 -		// convert background color channels from [0.0, 1.0] to [0, 255];
 -		raw->clear(int(mBackgroundColor.mV[VX] * 255.0f), int(mBackgroundColor.mV[VY] * 255.0f), int(mBackgroundColor.mV[VZ] * 255.0f), 0xff);
 -		int discard_level = 0;
 -
 -		// ask media source for correct GL image format constants
 -		placeholder_image->setExplicitFormat(mMediaSource->getTextureFormatInternal(),
 -											 mMediaSource->getTextureFormatPrimary(),
 -											 mMediaSource->getTextureFormatType(),
 -											 mMediaSource->getTextureFormatSwapBytes());
 -
 -		placeholder_image->createGLTexture(discard_level, raw);
 -
 -		// MEDIAOPT: set this dynamically on play/stop
 -		// FIXME
 -//		placeholder_image->mIsMediaTexture = true;
 -		mNeedsNewTexture = false;
 -				
 -		// If the amount of the texture being drawn by the media goes down in either width or height, 
 -		// recreate the texture to avoid leaving parts of the old image behind.
 -		mTextureUsedWidth = mMediaSource->getWidth();
 -		mTextureUsedHeight = mMediaSource->getHeight();
 -	}
 -	
 -	return placeholder_image;
 -}
 -
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -LLUUID LLViewerMediaImpl::getMediaTextureID() const
 -{
 -	return mTextureId;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::setVisible(bool visible)
 -{
 -	mVisible = visible;
 -	
 -	if(mVisible)
 -	{
 -		if(mMediaSource && mMediaSource->isPluginExited())
 -		{
 -			destroyMediaSource();
 -		}
 -		
 -		if(!mMediaSource)
 -		{
 -			createMediaSource();
 -		}
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::mouseCapture()
 -{
 -	gFocusMgr.setMouseCapture(this);
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::scaleMouse(S32 *mouse_x, S32 *mouse_y)
 -{
 -#if 0
 -	S32 media_width, media_height;
 -	S32 texture_width, texture_height;
 -	getMediaSize( &media_width, &media_height );
 -	getTextureSize( &texture_width, &texture_height );
 -	S32 y_delta = texture_height - media_height;
 -
 -	*mouse_y -= y_delta;
 -#endif
 -}
 -
 -
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -bool LLViewerMediaImpl::isMediaTimeBased()
 -{
 -	bool result = false;
 -	
 -	if(mMediaSource)
 -	{
 -		result = mMediaSource->pluginSupportsMediaTime();
 -	}
 -	
 -	return result;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -bool LLViewerMediaImpl::isMediaPlaying()
 -{
 -	bool result = false;
 -	
 -	if(mMediaSource)
 -	{
 -		EMediaStatus status = mMediaSource->getStatus();
 -		if(status == MEDIA_PLAYING || status == MEDIA_LOADING)
 -			result = true;
 -	}
 -	
 -	return result;
 -}
 -//////////////////////////////////////////////////////////////////////////////////////////
 -bool LLViewerMediaImpl::isMediaPaused()
 -{
 -	bool result = false;
 -
 -	if(mMediaSource)
 -	{
 -		if(mMediaSource->getStatus() == MEDIA_PAUSED)
 -			result = true;
 -	}
 -	
 -	return result;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -//
 -bool LLViewerMediaImpl::hasMedia() const
 -{
 -	return mMediaSource != NULL;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -//
 -void LLViewerMediaImpl::resetPreviousMediaState()
 -{
 -	mPreviousMediaState = MEDIA_NONE;
 -	mPreviousMediaTime = 0.0f;
 -}
 -
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -//
 -void LLViewerMediaImpl::setDisabled(bool disabled, bool forcePlayOnEnable)
 -{
 -	if(mIsDisabled != disabled)
 -	{
 -		// Only do this on actual state transitions.
 -		mIsDisabled = disabled;
 -		
 -		if(mIsDisabled)
 -		{
 -			// We just disabled this media.  Clear all state.
 -			unload();
 -		}
 -		else
 -		{
 -			// We just (re)enabled this media.  Do a navigate if auto-play is in order.
 -			if(isAutoPlayable() || forcePlayOnEnable)
 -			{
 -				navigateTo(mMediaEntryURL, "", true, true);
 -			}
 -		}
 -
 -	}
 -};
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -//
 -bool LLViewerMediaImpl::isForcedUnloaded() const
 -{
 -	if(mIsMuted || mMediaSourceFailed || mIsDisabled)
 -	{
 -		return true;
 -	}
 -	
 -	if(sInWorldMediaDisabled)
 -	{
 -		// When inworld media is disabled, all instances that aren't marked as "used in UI" will not be loaded.
 -		if(!mUsedInUI)
 -		{
 -			return true;
 -		}
 -	}
 -	
 -	// If this media's class is not supposed to be shown, unload
 -	if (!shouldShowBasedOnClass())
 -	{
 -		return true;
 -	}
 -	
 -	return false;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -//
 -bool LLViewerMediaImpl::isPlayable() const
 -{
 -	if(isForcedUnloaded())
 -	{
 -		// All of the forced-unloaded criteria also imply not playable.
 -		return false;
 -	}
 -	
 -	if(hasMedia())
 -	{
 -		// Anything that's already playing is, by definition, playable.
 -		return true;
 -	}
 -	
 -	if(!mMediaURL.empty())
 -	{
 -		// If something has navigated the instance, it's ready to be played.
 -		return true;
 -	}
 -	
 -	return false;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent event)
 -{
 -	bool pass_through = true;
 -	switch(event)
 -	{
 -		case MEDIA_EVENT_CLICK_LINK_NOFOLLOW:
 -		{
 -			LL_DEBUGS("Media") << "MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is: " << plugin->getClickURL() << LL_ENDL; 
 -			std::string url = plugin->getClickURL();
 -			std::string nav_type = plugin->getClickNavType();
 -			LLURLDispatcher::dispatch(url, nav_type, NULL, mTrustedBrowser);
 -		}
 -		break;
 -		case MEDIA_EVENT_CLICK_LINK_HREF:
 -		{
 -			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << plugin->getClickTarget() << "\", uri is " << plugin->getClickURL() << LL_ENDL;
 -		};
 -		break;
 -		case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH:
 -		{
 -			// The plugin failed to load properly.  Make sure the timer doesn't retry.
 -			// TODO: maybe mark this plugin as not loadable somehow?
 -			mMediaSourceFailed = true;
 -
 -			// Reset the last known state of the media to defaults.
 -			resetPreviousMediaState();
 -			
 -			// TODO: may want a different message for this case?
 -			LLSD args;
 -			args["PLUGIN"] = LLMIMETypes::implType(mCurrentMimeType);
 -			LLNotificationsUtil::add("MediaPluginFailed", args);
 -		}
 -		break;
 -
 -		case MEDIA_EVENT_PLUGIN_FAILED:
 -		{
 -			// The plugin crashed.
 -			mMediaSourceFailed = true;
 -
 -			// Reset the last known state of the media to defaults.
 -			resetPreviousMediaState();
 -
 -			LLSD args;
 -			args["PLUGIN"] = LLMIMETypes::implType(mCurrentMimeType);
 -			// SJB: This is getting called every frame if the plugin fails to load, continuously respawining the alert!
 -			//LLNotificationsUtil::add("MediaPluginFailed", args);
 -		}
 -		break;
 -		
 -		case MEDIA_EVENT_CURSOR_CHANGED:
 -		{
 -			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << plugin->getCursorName() << LL_ENDL;
 -
 -			std::string cursor = plugin->getCursorName();
 -			
 -			if(cursor == "arrow")
 -				mLastSetCursor = UI_CURSOR_ARROW;
 -			else if(cursor == "ibeam")
 -				mLastSetCursor = UI_CURSOR_IBEAM;
 -			else if(cursor == "splith")
 -				mLastSetCursor = UI_CURSOR_SIZEWE;
 -			else if(cursor == "splitv")
 -				mLastSetCursor = UI_CURSOR_SIZENS;
 -			else if(cursor == "hand")
 -				mLastSetCursor = UI_CURSOR_HAND;
 -			else // for anything else, default to the arrow
 -				mLastSetCursor = UI_CURSOR_ARROW;
 -		}
 -		break;
 -
 -		case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_BEGIN:
 -		{
 -			LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_BEGIN, uri is: " << plugin->getNavigateURI() << LL_ENDL;
 -			hideNotification();
 -
 -			if(getNavState() == MEDIANAVSTATE_SERVER_SENT)
 -			{
 -				setNavState(MEDIANAVSTATE_SERVER_BEGUN);
 -			}
 -			else
 -			{
 -				setNavState(MEDIANAVSTATE_BEGUN);
 -			}
 -		}
 -		break;
 -
 -		case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE:
 -		{
 -			LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_COMPLETE, uri is: " << plugin->getNavigateURI() << LL_ENDL;
 -
 -			std::string url = plugin->getNavigateURI();
 -			if(getNavState() == MEDIANAVSTATE_BEGUN)
 -			{
 -				if(mCurrentMediaURL == url)
 -				{
 -					// This is a navigate that takes us to the same url as the previous navigate.
 -					setNavState(MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED_SPURIOUS);
 -				}
 -				else
 -				{
 -					mCurrentMediaURL = url;
 -					setNavState(MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED);
 -				}
 -			}
 -			else if(getNavState() == MEDIANAVSTATE_SERVER_BEGUN)
 -			{
 -				mCurrentMediaURL = url;
 -				setNavState(MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED);
 -			}
 -			else
 -			{
 -				// all other cases need to leave the state alone.
 -			}
 -		}
 -		break;
 -		
 -		case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED:
 -		{
 -			LL_DEBUGS("Media") << "MEDIA_EVENT_LOCATION_CHANGED, uri is: " << plugin->getLocation() << LL_ENDL;
 -
 -			std::string url = plugin->getLocation();
 -
 -			if(getNavState() == MEDIANAVSTATE_BEGUN)
 -			{
 -				if(mCurrentMediaURL == url)
 -				{
 -					// This is a navigate that takes us to the same url as the previous navigate.
 -					setNavState(MEDIANAVSTATE_FIRST_LOCATION_CHANGED_SPURIOUS);
 -				}
 -				else
 -				{
 -					mCurrentMediaURL = url;
 -					setNavState(MEDIANAVSTATE_FIRST_LOCATION_CHANGED);
 -				}
 -			}
 -			else if(getNavState() == MEDIANAVSTATE_SERVER_BEGUN)
 -			{
 -				mCurrentMediaURL = url;
 -				setNavState(MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED);
 -			}
 -			else
 -			{
 -				// Don't track redirects.
 -				setNavState(MEDIANAVSTATE_NONE);
 -			}
 -		}
 -		break;
 -
 -		case LLViewerMediaObserver::MEDIA_EVENT_PICK_FILE_REQUEST:
 -		{
 -			// Display a file picker
 -			std::string response;
 -			
 -			LLFilePicker& picker = LLFilePicker::instance();
 -			if (!picker.getOpenFile(LLFilePicker::FFLOAD_ALL))
 -			{
 -				// The user didn't pick a file -- the empty response string will indicate this.
 -			}
 -			
 -			response = picker.getFirstFile();
 -			
 -			plugin->sendPickFileResponse(response);
 -		}
 -		break;
 -
 -
 -		case LLViewerMediaObserver::MEDIA_EVENT_AUTH_REQUEST:
 -		{
 -			LLNotification::Params auth_request_params;
 -			auth_request_params.name = "AuthRequest";
 -
 -			// pass in host name and realm for site (may be zero length but will always exist)
 -			LLSD args;
 -			LLURL raw_url( plugin->getAuthURL().c_str() );
 -			args["HOST_NAME"] = raw_url.getAuthority();
 -			args["REALM"] = plugin->getAuthRealm();
 -			auth_request_params.substitutions = args;
 -
 -			auth_request_params.payload = LLSD().with("media_id", mTextureId);
 -			auth_request_params.functor.function = boost::bind(&LLViewerMedia::onAuthSubmit, _1, _2);
 -			LLNotifications::instance().add(auth_request_params);
 -		};
 -		break;
 -
 -		case LLViewerMediaObserver::MEDIA_EVENT_CLOSE_REQUEST:
 -		{
 -			std::string uuid = plugin->getClickUUID();
 -
 -			llinfos << "MEDIA_EVENT_CLOSE_REQUEST for uuid " << uuid << llendl;
 -
 -			if(uuid.empty())
 -			{
 -				// This close request is directed at this instance, let it fall through.
 -			}
 -			else
 -			{
 -				// This close request is directed at another instance
 -				pass_through = false;
 -				LLFloaterMediaBrowser::closeRequest(uuid);
 -				LLFloaterWebContent::closeRequest(uuid);
 -			}
 -		}
 -		break;
 -
 -		case LLViewerMediaObserver::MEDIA_EVENT_GEOMETRY_CHANGE:
 -		{
 -			std::string uuid = plugin->getClickUUID();
 -
 -			llinfos << "MEDIA_EVENT_GEOMETRY_CHANGE for uuid " << uuid << llendl;
 -
 -			if(uuid.empty())
 -			{
 -				// This geometry change request is directed at this instance, let it fall through.
 -			}
 -			else
 -			{
 -				// This request is directed at another instance
 -				pass_through = false;
 -				LLFloaterMediaBrowser::geometryChanged(uuid, plugin->getGeometryX(), plugin->getGeometryY(), plugin->getGeometryWidth(), plugin->getGeometryHeight());
 -				LLFloaterWebContent::geometryChanged(uuid, plugin->getGeometryX(), plugin->getGeometryY(), plugin->getGeometryWidth(), plugin->getGeometryHeight());
 -			}
 -		}
 -		break;
 -
 -		default:
 -		break;
 -	}
 -
 -	if(pass_through)
 -	{
 -		// Just chain the event to observers.
 -		emitEvent(plugin, event);
 -	}
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// virtual
 -void LLViewerMediaImpl::handleCookieSet(LLPluginClassMedia* self, const std::string &cookie)
 -{
 -	LLViewerMedia::getCookieStore()->setCookies(cookie);
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// virtual
 -void
 -LLViewerMediaImpl::cut()
 -{
 -	if (mMediaSource)
 -		mMediaSource->cut();
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// virtual
 -BOOL
 -LLViewerMediaImpl::canCut() const
 -{
 -	if (mMediaSource)
 -		return mMediaSource->canCut();
 -	else
 -		return FALSE;
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// virtual
 -void
 -LLViewerMediaImpl::copy()
 -{
 -	if (mMediaSource)
 -		mMediaSource->copy();
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// virtual
 -BOOL
 -LLViewerMediaImpl::canCopy() const
 -{
 -	if (mMediaSource)
 -		return mMediaSource->canCopy();
 -	else
 -		return FALSE;
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// virtual
 -void
 -LLViewerMediaImpl::paste()
 -{
 -	if (mMediaSource)
 -		mMediaSource->paste();
 -}
 -
 -////////////////////////////////////////////////////////////////////////////////
 -// virtual
 -BOOL
 -LLViewerMediaImpl::canPaste() const
 -{
 -	if (mMediaSource)
 -		return mMediaSource->canPaste();
 -	else
 -		return FALSE;
 -}
 -
 -void LLViewerMediaImpl::setUpdated(BOOL updated)
 -{
 -	mIsUpdated = updated ;
 -}
 -
 -BOOL LLViewerMediaImpl::isUpdated()
 -{
 -	return mIsUpdated ;
 -}
 -
 -void LLViewerMediaImpl::calculateInterest()
 -{
 -	LLViewerMediaTexture* texture = LLViewerTextureManager::findMediaTexture( mTextureId );
 -	
 -	if(texture != NULL)
 -	{
 -		mInterest = texture->getMaxVirtualSize();
 -	}
 -	else
 -	{
 -		// This will be a relatively common case now, since it will always be true for unloaded media.
 -		mInterest = 0.0f;
 -	}
 -	
 -	// Calculate distance from the avatar, for use in the proximity calculation.
 -	mProximityDistance = 0.0f;
 -	mProximityCamera = 0.0f;
 -	if(!mObjectList.empty())
 -	{
 -		// Just use the first object in the list.  We could go through the list and find the closest object, but this should work well enough.
 -		std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
 -		LLVOVolume* objp = *iter ;
 -		llassert_always(objp != NULL) ;
 -		
 -		// The distance calculation is invalid for HUD attachments -- leave both mProximityDistance and mProximityCamera at 0 for them.
 -		if(!objp->isHUDAttachment())
 -		{
 -			LLVector3d obj_global = objp->getPositionGlobal() ;
 -			LLVector3d agent_global = gAgent.getPositionGlobal() ;
 -			LLVector3d global_delta = agent_global - obj_global ;
 -			mProximityDistance = global_delta.magVecSquared();  // use distance-squared because it's cheaper and sorts the same.
 -
 -			LLVector3d camera_delta = gAgentCamera.getCameraPositionGlobal() - obj_global;
 -			mProximityCamera = camera_delta.magVec();
 -		}
 -	}
 -	
 -	if(mNeedsMuteCheck)
 -	{
 -		// Check all objects this instance is associated with, and those objects' owners, against the mute list
 -		mIsMuted = false;
 -		
 -		std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
 -		for(; iter != mObjectList.end() ; ++iter)
 -		{
 -			LLVOVolume *obj = *iter;
 -			llassert(obj);
 -			if (!obj) continue;
 -			if(LLMuteList::getInstance() &&
 -			   LLMuteList::getInstance()->isMuted(obj->getID()))
 -			{
 -				mIsMuted = true;
 -			}
 -			else
 -			{
 -				// We won't have full permissions data for all objects.  Attempt to mute objects when we can tell their owners are muted.
 -				if (LLSelectMgr::getInstance())
 -				{
 -					LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(obj);
 -					if(obj_perm)
 -					{
 -						if(LLMuteList::getInstance() &&
 -						   LLMuteList::getInstance()->isMuted(obj_perm->getOwner()))
 -							mIsMuted = true;
 -					}
 -				}
 -			}
 -		}
 -		
 -		mNeedsMuteCheck = false;
 -	}
 -}
 -
 -F64 LLViewerMediaImpl::getApproximateTextureInterest()
 -{
 -	F64 result = 0.0f;
 -	
 -	if(mMediaSource)
 -	{
 -		result = mMediaSource->getFullWidth();
 -		result *= mMediaSource->getFullHeight();
 -	}
 -	else
 -	{
 -		// No media source is loaded -- all we have to go on is the texture size that has been set on the impl, if any.
 -		result = mMediaWidth;
 -		result *= mMediaHeight;
 -	}
 -
 -	return result;
 -}
 -
 -void LLViewerMediaImpl::setUsedInUI(bool used_in_ui)
 -{
 -	mUsedInUI = used_in_ui; 
 -	
 -	// HACK: Force elements used in UI to load right away.
 -	// This fixes some issues where UI code that uses the browser instance doesn't expect it to be unloaded.
 -	if(mUsedInUI && (mPriority == LLPluginClassMedia::PRIORITY_UNLOADED))
 -	{
 -		if(getVisible())
 -		{
 -			setPriority(LLPluginClassMedia::PRIORITY_NORMAL);
 -		}
 -		else
 -		{
 -			setPriority(LLPluginClassMedia::PRIORITY_HIDDEN);
 -		}
 -
 -		createMediaSource();
 -	}
 -};
 -
 -void LLViewerMediaImpl::setBackgroundColor(LLColor4 color)
 -{
 -	mBackgroundColor = color; 
 -
 -	if(mMediaSource)
 -	{
 -		mMediaSource->setBackgroundColor(mBackgroundColor);
 -	}
 -};
 -
 -F64 LLViewerMediaImpl::getCPUUsage() const
 -{
 -	F64 result = 0.0f;
 -	
 -	if(mMediaSource)
 -	{
 -		result = mMediaSource->getCPUUsage();
 -	}
 -	
 -	return result;
 -}
 -
 -void LLViewerMediaImpl::setPriority(LLPluginClassMedia::EPriority priority)
 -{
 -	if(mPriority != priority)
 -	{
 -		LL_DEBUGS("PluginPriority")
 -			<< "changing priority of media id " << mTextureId
 -			<< " from " << LLPluginClassMedia::priorityToString(mPriority)
 -			<< " to " << LLPluginClassMedia::priorityToString(priority)
 -			<< LL_ENDL;
 -	}
 -	
 -	mPriority = priority;
 -	
 -	if(priority == LLPluginClassMedia::PRIORITY_UNLOADED)
 -	{
 -		if(mMediaSource)
 -		{
 -			// Need to unload the media source
 -			
 -			// First, save off previous media state
 -			mPreviousMediaState = mMediaSource->getStatus();
 -			mPreviousMediaTime = mMediaSource->getCurrentTime();
 -			
 -			destroyMediaSource();
 -		}
 -	}
 -
 -	if(mMediaSource)
 -	{
 -		mMediaSource->setPriority(mPriority);
 -	}
 -	
 -	// NOTE: loading (or reloading) media sources whose priority has risen above PRIORITY_UNLOADED is done in update().
 -}
 -
 -void LLViewerMediaImpl::setLowPrioritySizeLimit(int size)
 -{
 -	if(mMediaSource)
 -	{
 -		mMediaSource->setLowPrioritySizeLimit(size);
 -	}
 -}
 -
 -void LLViewerMediaImpl::setNavState(EMediaNavState state)
 -{
 -	mMediaNavState = state;
 -	
 -	switch (state) 
 -	{
 -		case MEDIANAVSTATE_NONE: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_NONE" << llendl; break;
 -		case MEDIANAVSTATE_BEGUN: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_BEGUN" << llendl; break;
 -		case MEDIANAVSTATE_FIRST_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_FIRST_LOCATION_CHANGED" << llendl; break;
 -		case MEDIANAVSTATE_FIRST_LOCATION_CHANGED_SPURIOUS: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_FIRST_LOCATION_CHANGED_SPURIOUS" << llendl; break;
 -		case MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED" << llendl; break;
 -		case MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED_SPURIOUS: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED_SPURIOUS" << llendl; break;
 -		case MEDIANAVSTATE_SERVER_SENT: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_SENT" << llendl; break;
 -		case MEDIANAVSTATE_SERVER_BEGUN: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_BEGUN" << llendl; break;
 -		case MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED" << llendl; break;
 -		case MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED" << llendl; break;
 -	}
 -}
 -
 -void LLViewerMediaImpl::setNavigateSuspended(bool suspend)
 -{
 -	if(mNavigateSuspended != suspend)
 -	{
 -		mNavigateSuspended = suspend;
 -		if(!suspend)
 -		{
 -			// We're coming out of suspend.  If someone tried to do a navigate while suspended, do one now instead.
 -			if(mNavigateSuspendedDeferred)
 -			{
 -				mNavigateSuspendedDeferred = false;
 -				navigateInternal();
 -			}
 -		}
 -	}
 -}
 -
 -void LLViewerMediaImpl::cancelMimeTypeProbe()
 -{
 -	if(mMimeTypeProbe != NULL)
 -	{
 -		// There doesn't seem to be a way to actually cancel an outstanding request.
 -		// Simulate it by telling the LLMimeDiscoveryResponder not to write back any results.
 -		mMimeTypeProbe->cancelRequest();
 -		
 -		// The above should already have set mMimeTypeProbe to NULL.
 -		if(mMimeTypeProbe != NULL)
 -		{
 -			llerrs << "internal error: mMimeTypeProbe is not NULL after cancelling request." << llendl;
 -		}
 -	}
 -}
 -
 -void LLViewerMediaImpl::addObject(LLVOVolume* obj) 
 -{
 -	std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
 -	for(; iter != mObjectList.end() ; ++iter)
 -	{
 -		if(*iter == obj)
 -		{
 -			return ; //already in the list.
 -		}
 -	}
 -
 -	mObjectList.push_back(obj) ;
 -	mNeedsMuteCheck = true;
 -}
 -	
 -void LLViewerMediaImpl::removeObject(LLVOVolume* obj) 
 -{
 -	mObjectList.remove(obj) ;	
 -	mNeedsMuteCheck = true;
 -}
 -	
 -const std::list< LLVOVolume* >* LLViewerMediaImpl::getObjectList() const 
 -{
 -	return &mObjectList ;
 -}
 -
 -LLVOVolume *LLViewerMediaImpl::getSomeObject()
 -{
 -	LLVOVolume *result = NULL;
 -	
 -	std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ;
 -	if(iter != mObjectList.end())
 -	{
 -		result = *iter;
 -	}
 -	
 -	return result;
 -}
 -
 -void LLViewerMediaImpl::setTextureID(LLUUID id)
 -{
 -	if(id != mTextureId)
 -	{
 -		if(mTextureId.notNull())
 -		{
 -			// Remove this item's entry from the map
 -			sViewerMediaTextureIDMap.erase(mTextureId);
 -		}
 -		
 -		if(id.notNull())
 -		{
 -			sViewerMediaTextureIDMap.insert(LLViewerMedia::impl_id_map::value_type(id, this));
 -		}
 -		
 -		mTextureId = id;
 -	}
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -//
 -bool LLViewerMediaImpl::isAutoPlayable() const
 -{
 -	return (mMediaAutoPlay && 
 -			gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) &&
 -			gSavedSettings.getBOOL("MediaTentativeAutoPlay"));
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -//
 -bool LLViewerMediaImpl::shouldShowBasedOnClass() const
 -{
 -	// If this is parcel media or in the UI, return true always
 -	if (getUsedInUI() || isParcelMedia()) return true;
 -	
 -	bool attached_to_another_avatar = isAttachedToAnotherAvatar();
 -	bool inside_parcel = isInAgentParcel();
 -	
 -	//	llinfos << " hasFocus = " << hasFocus() <<
 -	//	" others = " << (attached_to_another_avatar && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING)) <<
 -	//	" within = " << (inside_parcel && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING)) <<
 -	//	" outside = " << (!inside_parcel && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING)) << llendl;
 -	
 -	// If it has focus, we should show it
 -	// This is incorrect, and causes EXT-6750 (disabled attachment media still plays)
 -//	if (hasFocus())
 -//		return true;
 -	
 -	// If it is attached to an avatar and the pref is off, we shouldn't show it
 -	if (attached_to_another_avatar)
 -		return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING);
 -	
 -	if (inside_parcel)
 -		return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING);
 -	else 
 -		return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING);
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -//
 -bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const
 -{
 -	bool result = false;
 -	
 -	std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin();
 -	std::list< LLVOVolume* >::const_iterator end = mObjectList.end();
 -	for ( ; iter != end; iter++)
 -	{
 -		if (isObjectAttachedToAnotherAvatar(*iter))
 -		{
 -			result = true;
 -			break;
 -		}
 -	}
 -	return result;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -//
 -//static
 -bool LLViewerMediaImpl::isObjectAttachedToAnotherAvatar(LLVOVolume *obj)
 -{
 -	bool result = false;
 -	LLXform *xform = obj;
 -	// Walk up parent chain
 -	while (NULL != xform)
 -	{
 -		LLViewerObject *object = dynamic_cast<LLViewerObject*> (xform);
 -		if (NULL != object)
 -		{
 -			LLVOAvatar *avatar = object->asAvatar();
 -			if ((NULL != avatar) && (avatar != gAgentAvatarp))
 -			{
 -				result = true;
 -				break;
 -			}
 -		}
 -		xform = xform->getParent();
 -	}
 -	return result;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -//
 -bool LLViewerMediaImpl::isInAgentParcel() const
 -{
 -	bool result = false;
 -	
 -	std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin();
 -	std::list< LLVOVolume* >::const_iterator end = mObjectList.end();
 -	for ( ; iter != end; iter++)
 -	{
 -		LLVOVolume *object = *iter;
 -		if (LLViewerMediaImpl::isObjectInAgentParcel(object))
 -		{
 -			result = true;
 -			break;
 -		}
 -	}
 -	return result;
 -}
 -
 -LLNotificationPtr LLViewerMediaImpl::getCurrentNotification() const
 -{
 -	return mNotification;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////////////////
 -//
 -// static
 -bool LLViewerMediaImpl::isObjectInAgentParcel(LLVOVolume *obj)
 -{
 -	return (LLViewerParcelMgr::getInstance()->inAgentParcel(obj->getPositionGlobal()));
 -}
 +/** + * @file llviewermedia.cpp + * @brief Client interface to the media engine + * + * $LicenseInfo:firstyear=2007&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 "llviewerprecompiledheaders.h" + +#include "llagent.h" +#include "llagentcamera.h" +#include "llviewermedia.h" +#include "llviewermediafocus.h" +#include "llmimetypes.h" +#include "llmediaentry.h" +#include "llversioninfo.h" +#include "llviewercontrol.h" +#include "llviewertexture.h" +#include "llviewerparcelmedia.h" +#include "llviewerparcelmgr.h" +#include "llviewertexturelist.h" +#include "llvovolume.h" +#include "llpluginclassmedia.h" +#include "llplugincookiestore.h" +#include "llviewerwindow.h" +#include "llfocusmgr.h" +#include "llcallbacklist.h" +#include "llparcel.h" +#include "llaudioengine.h"  // for gAudiop +#include "llurldispatcher.h" +#include "llvoavatar.h" +#include "llvoavatarself.h" +#include "llviewerregion.h" +#include "llwebsharing.h"	// For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this! +#include "llfilepicker.h" +#include "llnotifications.h" +#include "lldir.h" +#include "lldiriterator.h" +#include "llevent.h"		// LLSimpleListener +#include "llnotificationsutil.h" +#include "lluuid.h" +#include "llkeyboard.h" +#include "llmutelist.h" +#include "llpanelprofile.h" +#include "llappviewer.h" +#include "lllogininstance.h"  +//#include "llfirstuse.h" +#include "llwindow.h" + +#include "llfloatermediabrowser.h"	// for handling window close requests and geometry change requests in media browser windows. +#include "llfloaterwebcontent.h"	// for handling window close requests and geometry change requests in media browser windows. + +#include <boost/bind.hpp>	// for SkinFolder listener +#include <boost/signals2.hpp> + +/*static*/ const char* LLViewerMedia::AUTO_PLAY_MEDIA_SETTING = "ParcelMediaAutoPlayEnable"; +/*static*/ const char* LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING = "MediaShowOnOthers"; +/*static*/ const char* LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING = "MediaShowWithinParcel"; +/*static*/ const char* LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING = "MediaShowOutsideParcel"; + + +// Move this to its own file. + +LLViewerMediaEventEmitter::~LLViewerMediaEventEmitter() +{ +	observerListType::iterator iter = mObservers.begin(); + +	while( iter != mObservers.end() ) +	{ +		LLViewerMediaObserver *self = *iter; +		iter++; +		remObserver(self); +	} +} + +/////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaEventEmitter::addObserver( LLViewerMediaObserver* observer ) +{ +	if ( ! observer ) +		return false; + +	if ( std::find( mObservers.begin(), mObservers.end(), observer ) != mObservers.end() ) +		return false; + +	mObservers.push_back( observer ); +	observer->mEmitters.push_back( this ); + +	return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaEventEmitter::remObserver( LLViewerMediaObserver* observer ) +{ +	if ( ! observer ) +		return false; + +	mObservers.remove( observer ); +	observer->mEmitters.remove(this); + +	return true; +} + +/////////////////////////////////////////////////////////////////////////////// +// +void LLViewerMediaEventEmitter::emitEvent( LLPluginClassMedia* media, LLViewerMediaObserver::EMediaEvent event ) +{ +	// Broadcast the event to any observers. +	observerListType::iterator iter = mObservers.begin(); +	while( iter != mObservers.end() ) +	{ +		LLViewerMediaObserver *self = *iter; +		++iter; +		self->handleMediaEvent( media, event ); +	} +} + +// Move this to its own file. +LLViewerMediaObserver::~LLViewerMediaObserver() +{ +	std::list<LLViewerMediaEventEmitter *>::iterator iter = mEmitters.begin(); + +	while( iter != mEmitters.end() ) +	{ +		LLViewerMediaEventEmitter *self = *iter; +		iter++; +		self->remObserver( this ); +	} +} + + +// Move this to its own file. +// helper class that tries to download a URL from a web site and calls a method +// on the Panel Land Media and to discover the MIME type +class LLMimeDiscoveryResponder : public LLHTTPClient::Responder +{ +LOG_CLASS(LLMimeDiscoveryResponder); +public: +	LLMimeDiscoveryResponder( viewer_media_t media_impl) +		: mMediaImpl(media_impl), +		  mInitialized(false) +	{ +		if(mMediaImpl->mMimeTypeProbe != NULL) +		{ +			llerrs << "impl already has an outstanding responder" << llendl; +		} +		 +		mMediaImpl->mMimeTypeProbe = this; +	} + +	~LLMimeDiscoveryResponder() +	{ +		disconnectOwner(); +	} + +	virtual void completedHeader(U32 status, const std::string& reason, const LLSD& content) +	{ +		std::string media_type = content["content-type"].asString(); +		std::string::size_type idx1 = media_type.find_first_of(";"); +		std::string mime_type = media_type.substr(0, idx1); + +		lldebugs << "status is " << status << ", media type \"" << media_type << "\"" << llendl; +		 +		// 2xx status codes indicate success. +		// Most 4xx status codes are successful enough for our purposes. +		// 499 is the error code for host not found, timeout, etc. +		// 500 means "Internal Server error" but we decided it's okay to  +		//     accept this and go past it in the MIME type probe +		// 302 means the resource can be found temporarily in a different place - added this for join.secondlife.com +		// 499 is a code specifc to join.secondlife.com (????) apparently safe to ignore +//		if(	((status >= 200) && (status < 300))	|| +//			((status >= 400) && (status < 499))	||  +//			(status == 500) || +//			(status == 302) || +//			(status == 499)  +//			) +		// We now no longer check the error code returned from the probe. +		// If we have a mime type, use it.  If not, default to the web plugin and let it handle error reporting. +		if(1) +		{ +			// The probe was successful. +			if(mime_type.empty()) +			{ +				// Some sites don't return any content-type header at all. +				// Treat an empty mime type as text/html. +				mime_type = "text/html"; +			} +			 +			completeAny(status, mime_type); +		} +		else +		{ +			llwarns << "responder failed with status " << status << ", reason " << reason << llendl; +		 +			if(mMediaImpl) +			{ +				mMediaImpl->mMediaSourceFailed = true; +			} +		} + +	} + +	void completeAny(U32 status, const std::string& mime_type) +	{ +		// the call to initializeMedia may disconnect the responder, which will clear mMediaImpl. +		// Make a local copy so we can call loadURI() afterwards. +		LLViewerMediaImpl *impl = mMediaImpl; +		 +		if(impl && !mInitialized && ! mime_type.empty()) +		{ +			if(impl->initializeMedia(mime_type)) +			{ +				mInitialized = true; +				impl->loadURI(); +				disconnectOwner(); +			} +		} +	} +	 +	void cancelRequest() +	{ +		disconnectOwner(); +	} +	 +private: +	void disconnectOwner() +	{ +		if(mMediaImpl) +		{ +			if(mMediaImpl->mMimeTypeProbe != this) +			{ +				llerrs << "internal error: mMediaImpl->mMimeTypeProbe != this" << llendl; +			} + +			mMediaImpl->mMimeTypeProbe = NULL; +		} +		mMediaImpl = NULL; +	} +	 +	 +public: +		LLViewerMediaImpl *mMediaImpl; +		bool mInitialized; +}; + +class LLViewerMediaOpenIDResponder : public LLHTTPClient::Responder +{ +LOG_CLASS(LLViewerMediaOpenIDResponder); +public: +	LLViewerMediaOpenIDResponder( ) +	{ +	} + +	~LLViewerMediaOpenIDResponder() +	{ +	} + +	/* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content) +	{ +		LL_DEBUGS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL; +		LL_DEBUGS("MediaAuth") << content << LL_ENDL; +		std::string cookie = content["set-cookie"].asString(); +		 +		LLViewerMedia::openIDCookieResponse(cookie); +	} + +	/* virtual */ void completedRaw( +		U32 status, +		const std::string& reason, +		const LLChannelDescriptors& channels, +		const LLIOPipe::buffer_ptr_t& buffer) +	{ +		// This is just here to disable the default behavior (attempting to parse the response as llsd). +		// We don't care about the content of the response, only the set-cookie header. +	} + +}; + +class LLViewerMediaWebProfileResponder : public LLHTTPClient::Responder +{ +LOG_CLASS(LLViewerMediaWebProfileResponder); +public: +	LLViewerMediaWebProfileResponder(std::string host) +	{ +		mHost = host; +	} + +	~LLViewerMediaWebProfileResponder() +	{ +	} + +	/* virtual */ void completedHeader(U32 status, const std::string& reason, const LLSD& content) +	{ +		LL_WARNS("MediaAuth") << "status = " << status << ", reason = " << reason << LL_ENDL; +		LL_WARNS("MediaAuth") << content << LL_ENDL; + +		std::string cookie = content["set-cookie"].asString(); + +		LLViewerMedia::getCookieStore()->setCookiesFromHost(cookie, mHost); +	} + +	 void completedRaw( +		U32 status, +		const std::string& reason, +		const LLChannelDescriptors& channels, +		const LLIOPipe::buffer_ptr_t& buffer) +	{ +		// This is just here to disable the default behavior (attempting to parse the response as llsd). +		// We don't care about the content of the response, only the set-cookie header. +	} + +	std::string mHost; +}; + + +LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL; +LLURL LLViewerMedia::sOpenIDURL; +std::string LLViewerMedia::sOpenIDCookie; +LLPluginClassMedia* LLViewerMedia::sSpareBrowserMediaSource = NULL; +static LLViewerMedia::impl_list sViewerMediaImplList; +static LLViewerMedia::impl_id_map sViewerMediaTextureIDMap; +static LLTimer sMediaCreateTimer; +static const F32 LLVIEWERMEDIA_CREATE_DELAY = 1.0f; +static F32 sGlobalVolume = 1.0f; +static F64 sLowestLoadableImplInterest = 0.0f; +static bool sAnyMediaShowing = false; +static boost::signals2::connection sTeleportFinishConnection; +static std::string sUpdatedCookies; +static const char *PLUGIN_COOKIE_FILE_NAME = "plugin_cookies.txt"; + +////////////////////////////////////////////////////////////////////////////////////////// +static void add_media_impl(LLViewerMediaImpl* media) +{ +	sViewerMediaImplList.push_back(media); +} + +////////////////////////////////////////////////////////////////////////////////////////// +static void remove_media_impl(LLViewerMediaImpl* media) +{ +	LLViewerMedia::impl_list::iterator iter = sViewerMediaImplList.begin(); +	LLViewerMedia::impl_list::iterator end = sViewerMediaImplList.end(); +	 +	for(; iter != end; iter++) +	{ +		if(media == *iter) +		{ +			sViewerMediaImplList.erase(iter); +			return; +		} +	} +} + +class LLViewerMediaMuteListObserver : public LLMuteListObserver +{ +	/* virtual */ void onChange()  { LLViewerMedia::muteListChanged();} +}; + +static LLViewerMediaMuteListObserver sViewerMediaMuteListObserver; +static bool sViewerMediaMuteListObserverInitialized = false; +static bool sInWorldMediaDisabled = false; + + +////////////////////////////////////////////////////////////////////////////////////////// +// LLViewerMedia + +////////////////////////////////////////////////////////////////////////////////////////// +// static +viewer_media_t LLViewerMedia::newMediaImpl( +											 const LLUUID& texture_id, +											 S32 media_width,  +											 S32 media_height,  +											 U8 media_auto_scale, +											 U8 media_loop) +{ +	LLViewerMediaImpl* media_impl = getMediaImplFromTextureID(texture_id); +	if(media_impl == NULL || texture_id.isNull()) +	{ +		// Create the media impl +		media_impl = new LLViewerMediaImpl(texture_id, media_width, media_height, media_auto_scale, media_loop); +	} +	else +	{ +		media_impl->unload(); +		media_impl->setTextureID(texture_id); +		media_impl->mMediaWidth = media_width; +		media_impl->mMediaHeight = media_height; +		media_impl->mMediaAutoScale = media_auto_scale; +		media_impl->mMediaLoop = media_loop; +	} + +	return media_impl; +} + +viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const std::string& previous_url, bool update_from_self) +{	 +	// Try to find media with the same media ID +	viewer_media_t media_impl = getMediaImplFromTextureID(media_entry->getMediaID()); +	 +	lldebugs << "called, current URL is \"" << media_entry->getCurrentURL()  +			<< "\", previous URL is \"" << previous_url  +			<< "\", update_from_self is " << (update_from_self?"true":"false") +			<< llendl; +			 +	bool was_loaded = false; +	bool needs_navigate = false; +	 +	if(media_impl) +	{	 +		was_loaded = media_impl->hasMedia(); +		 +		media_impl->setHomeURL(media_entry->getHomeURL()); +		 +		media_impl->mMediaAutoScale = media_entry->getAutoScale(); +		media_impl->mMediaLoop = media_entry->getAutoLoop(); +		media_impl->mMediaWidth = media_entry->getWidthPixels(); +		media_impl->mMediaHeight = media_entry->getHeightPixels(); +		media_impl->mMediaAutoPlay = media_entry->getAutoPlay(); +		media_impl->mMediaEntryURL = media_entry->getCurrentURL(); +		if (media_impl->mMediaSource) +		{ +			media_impl->mMediaSource->setAutoScale(media_impl->mMediaAutoScale); +			media_impl->mMediaSource->setLoop(media_impl->mMediaLoop); +			media_impl->mMediaSource->setSize(media_entry->getWidthPixels(), media_entry->getHeightPixels()); +		} +		 +		bool url_changed = (media_impl->mMediaEntryURL != previous_url); +		if(media_impl->mMediaEntryURL.empty()) +		{ +			if(url_changed) +			{ +				// The current media URL is now empty.  Unload the media source. +				media_impl->unload(); +			 +				lldebugs << "Unloading media instance (new current URL is empty)." << llendl; +			} +		} +		else +		{ +			// The current media URL is not empty. +			// If (the media was already loaded OR the media was set to autoplay) AND this update didn't come from this agent, +			// do a navigate. +			bool auto_play = media_impl->isAutoPlayable();			 +			if((was_loaded || auto_play) && !update_from_self) +			{ +				needs_navigate = url_changed; +			} +			 +			lldebugs << "was_loaded is " << (was_loaded?"true":"false")  +					<< ", auto_play is " << (auto_play?"true":"false")  +					<< ", needs_navigate is " << (needs_navigate?"true":"false") << llendl; +		} +	} +	else +	{ +		media_impl = newMediaImpl( +			media_entry->getMediaID(),  +			media_entry->getWidthPixels(), +			media_entry->getHeightPixels(),  +			media_entry->getAutoScale(),  +			media_entry->getAutoLoop()); +		 +		media_impl->setHomeURL(media_entry->getHomeURL()); +		media_impl->mMediaAutoPlay = media_entry->getAutoPlay(); +		media_impl->mMediaEntryURL = media_entry->getCurrentURL(); +		if(media_impl->isAutoPlayable()) +		{ +			needs_navigate = true; +		} +	} +	 +	if(media_impl) +	{ +		if(needs_navigate) +		{ +			media_impl->navigateTo(media_impl->mMediaEntryURL, "", true, true); +			lldebugs << "navigating to URL " << media_impl->mMediaEntryURL << llendl; +		} +		else if(!media_impl->mMediaURL.empty() && (media_impl->mMediaURL != media_impl->mMediaEntryURL)) +		{ +			// If we already have a non-empty media URL set and we aren't doing a navigate, update the media URL to match the media entry. +			media_impl->mMediaURL = media_impl->mMediaEntryURL; + +			// If this causes a navigate at some point (such as after a reload), it should be considered server-driven so it isn't broadcast. +			media_impl->mNavigateServerRequest = true; + +			lldebugs << "updating URL in the media impl to " << media_impl->mMediaEntryURL << llendl; +		} +	} +	 +	return media_impl; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +LLViewerMediaImpl* LLViewerMedia::getMediaImplFromTextureID(const LLUUID& texture_id) +{ +	LLViewerMediaImpl* result = NULL; +	 +	// Look up the texture ID in the texture id->impl map. +	impl_id_map::iterator iter = sViewerMediaTextureIDMap.find(texture_id); +	if(iter != sViewerMediaTextureIDMap.end()) +	{ +		result = iter->second; +	} + +	return result; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +std::string LLViewerMedia::getCurrentUserAgent() +{ +	// Don't use user-visible string to avoid  +	// punctuation and strange characters. +	std::string skin_name = gSavedSettings.getString("SkinCurrent"); + +	// Just in case we need to check browser differences in A/B test +	// builds. +	std::string channel = LLVersionInfo::getChannel(); + +	// append our magic version number string to the browser user agent id +	// See the HTTP 1.0 and 1.1 specifications for allowed formats: +	// http://www.ietf.org/rfc/rfc1945.txt section 10.15 +	// http://www.ietf.org/rfc/rfc2068.txt section 3.8 +	// This was also helpful: +	// http://www.mozilla.org/build/revised-user-agent-strings.html +	std::ostringstream codec; +	codec << "SecondLife/"; +	codec << LLVersionInfo::getVersion(); +	codec << " (" << channel << "; " << skin_name << " skin)"; +	llinfos << codec.str() << llendl; +	 +	return codec.str(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::updateBrowserUserAgent() +{ +	std::string user_agent = getCurrentUserAgent(); +	 +	impl_list::iterator iter = sViewerMediaImplList.begin(); +	impl_list::iterator end = sViewerMediaImplList.end(); + +	for(; iter != end; iter++) +	{ +		LLViewerMediaImpl* pimpl = *iter; +		if(pimpl->mMediaSource && pimpl->mMediaSource->pluginSupportsMediaBrowser()) +		{ +			pimpl->mMediaSource->setBrowserUserAgent(user_agent); +		} +	} + +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::handleSkinCurrentChanged(const LLSD& /*newvalue*/) +{ +	// gSavedSettings is already updated when this function is called. +	updateBrowserUserAgent(); +	return true; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::textureHasMedia(const LLUUID& texture_id) +{ +	impl_list::iterator iter = sViewerMediaImplList.begin(); +	impl_list::iterator end = sViewerMediaImplList.end(); + +	for(; iter != end; iter++) +	{ +		LLViewerMediaImpl* pimpl = *iter; +		if(pimpl->getMediaTextureID() == texture_id) +		{ +			return true; +		} +	} +	return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::setVolume(F32 volume) +{ +	if(volume != sGlobalVolume) +	{ +		sGlobalVolume = volume; +		impl_list::iterator iter = sViewerMediaImplList.begin(); +		impl_list::iterator end = sViewerMediaImplList.end(); + +		for(; iter != end; iter++) +		{ +			LLViewerMediaImpl* pimpl = *iter; +			pimpl->updateVolume(); +		} +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +F32 LLViewerMedia::getVolume() +{ +	return sGlobalVolume; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::muteListChanged() +{ +	// When the mute list changes, we need to check mute status on all impls. +	impl_list::iterator iter = sViewerMediaImplList.begin(); +	impl_list::iterator end = sViewerMediaImplList.end(); + +	for(; iter != end; iter++) +	{ +		LLViewerMediaImpl* pimpl = *iter; +		pimpl->mNeedsMuteCheck = true; +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::setInWorldMediaDisabled(bool disabled) +{ +	sInWorldMediaDisabled = disabled; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::getInWorldMediaDisabled() +{ +	return sInWorldMediaDisabled; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isInterestingEnough(const LLVOVolume *object, const F64 &object_interest) +{ +	bool result = false; +	 +	if (NULL == object) +	{ +		result = false; +	} +	// Focused?  Then it is interesting! +	else if (LLViewerMediaFocus::getInstance()->getFocusedObjectID() == object->getID()) +	{ +		result = true; +	} +	// Selected?  Then it is interesting! +	// XXX Sadly, 'contains()' doesn't take a const :( +	else if (LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(object))) +	{ +		result = true; +	} +	else  +	{ +		lldebugs << "object interest = " << object_interest << ", lowest loadable = " << sLowestLoadableImplInterest << llendl; +		if(object_interest >= sLowestLoadableImplInterest) +			result = true; +	} +	 +	return result; +} + +LLViewerMedia::impl_list &LLViewerMedia::getPriorityList() +{ +	return sViewerMediaImplList; +} + +// This is the predicate function used to sort sViewerMediaImplList by priority. +bool LLViewerMedia::priorityComparitor(const LLViewerMediaImpl* i1, const LLViewerMediaImpl* i2) +{ +	if(i1->isForcedUnloaded() && !i2->isForcedUnloaded()) +	{ +		// Muted or failed items always go to the end of the list, period. +		return false; +	} +	else if(i2->isForcedUnloaded() && !i1->isForcedUnloaded()) +	{ +		// Muted or failed items always go to the end of the list, period. +		return true; +	} +	else if(i1->hasFocus()) +	{ +		// The item with user focus always comes to the front of the list, period. +		return true; +	} +	else if(i2->hasFocus()) +	{ +		// The item with user focus always comes to the front of the list, period. +		return false; +	} +	else if(i1->isParcelMedia()) +	{ +		// The parcel media impl sorts above all other inworld media, unless one has focus. +		return true; +	} +	else if(i2->isParcelMedia()) +	{ +		// The parcel media impl sorts above all other inworld media, unless one has focus. +		return false; +	} +	else if(i1->getUsedInUI() && !i2->getUsedInUI()) +	{ +		// i1 is a UI element, i2 is not.  This makes i1 "less than" i2, so it sorts earlier in our list. +		return true; +	} +	else if(i2->getUsedInUI() && !i1->getUsedInUI()) +	{ +		// i2 is a UI element, i1 is not.  This makes i2 "less than" i1, so it sorts earlier in our list. +		return false; +	} +	else if(i1->isPlayable() && !i2->isPlayable()) +	{ +		// Playable items sort above ones that wouldn't play even if they got high enough priority +		return true; +	} +	else if(!i1->isPlayable() && i2->isPlayable()) +	{ +		// Playable items sort above ones that wouldn't play even if they got high enough priority +		return false; +	} +	else if(i1->getInterest() == i2->getInterest()) +	{ +		// Generally this will mean both objects have zero interest.  In this case, sort on distance. +		return (i1->getProximityDistance() < i2->getProximityDistance()); +	} +	else +	{ +		// The object with the larger interest value should be earlier in the list, so we reverse the sense of the comparison here. +		return (i1->getInterest() > i2->getInterest()); +	} +} + +static bool proximity_comparitor(const LLViewerMediaImpl* i1, const LLViewerMediaImpl* i2) +{ +	if(i1->getProximityDistance() < i2->getProximityDistance()) +	{ +		return true; +	} +	else if(i1->getProximityDistance() > i2->getProximityDistance()) +	{ +		return false; +	} +	else +	{ +		// Both objects have the same distance.  This most likely means they're two faces of the same object. +		// They may also be faces on different objects with exactly the same distance (like HUD objects). +		// We don't actually care what the sort order is for this case, as long as it's stable and doesn't change when you enable/disable media. +		// Comparing the impl pointers gives a completely arbitrary ordering, but it will be stable. +		return (i1 < i2); +	} +} + +static LLFastTimer::DeclareTimer FTM_MEDIA_UPDATE("Update Media"); + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::updateMedia(void *dummy_arg) +{ +	LLFastTimer t1(FTM_MEDIA_UPDATE); +	 +	// Enable/disable the plugin read thread +	LLPluginProcessParent::setUseReadThread(gSavedSettings.getBOOL("PluginUseReadThread")); +	 +	// HACK: we always try to keep a spare running webkit plugin around to improve launch times. +	createSpareBrowserMediaSource(); +	 +	sAnyMediaShowing = false; +	sUpdatedCookies = getCookieStore()->getChangedCookies(); +	if(!sUpdatedCookies.empty()) +	{ +		lldebugs << "updated cookies will be sent to all loaded plugins: " << llendl; +		lldebugs << sUpdatedCookies << llendl; +	} +	 +	impl_list::iterator iter = sViewerMediaImplList.begin(); +	impl_list::iterator end = sViewerMediaImplList.end(); + +	for(; iter != end;) +	{ +		LLViewerMediaImpl* pimpl = *iter++; +		pimpl->update(); +		pimpl->calculateInterest(); +	} +	 +	// Let the spare media source actually launch +	if(sSpareBrowserMediaSource) +	{ +		sSpareBrowserMediaSource->idle(); +	} +		 +	// Sort the static instance list using our interest criteria +	sViewerMediaImplList.sort(priorityComparitor); + +	// Go through the list again and adjust according to priority. +	iter = sViewerMediaImplList.begin(); +	end = sViewerMediaImplList.end(); +	 +	F64 total_cpu = 0.0f; +	int impl_count_total = 0; +	int impl_count_interest_low = 0; +	int impl_count_interest_normal = 0; +	 +	std::vector<LLViewerMediaImpl*> proximity_order; +	 +	bool inworld_media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia"); +	bool inworld_audio_enabled = gSavedSettings.getBOOL("AudioStreamingMusic"); +	U32 max_instances = gSavedSettings.getU32("PluginInstancesTotal"); +	U32 max_normal = gSavedSettings.getU32("PluginInstancesNormal"); +	U32 max_low = gSavedSettings.getU32("PluginInstancesLow"); +	F32 max_cpu = gSavedSettings.getF32("PluginInstancesCPULimit"); +	// Setting max_cpu to 0.0 disables CPU usage checking. +	bool check_cpu_usage = (max_cpu != 0.0f); +	 +	LLViewerMediaImpl* lowest_interest_loadable = NULL; +	 +	// Notes on tweakable params: +	// max_instances must be set high enough to allow the various instances used in the UI (for the help browser, search, etc.) to be loaded. +	// If max_normal + max_low is less than max_instances, things will tend to get unloaded instead of being set to slideshow. +	 +	for(; iter != end; iter++) +	{ +		LLViewerMediaImpl* pimpl = *iter; +		 +		LLPluginClassMedia::EPriority new_priority = LLPluginClassMedia::PRIORITY_NORMAL; + +		if(pimpl->isForcedUnloaded() || (impl_count_total >= (int)max_instances)) +		{ +			// Never load muted or failed impls. +			// Hard limit on the number of instances that will be loaded at one time +			new_priority = LLPluginClassMedia::PRIORITY_UNLOADED; +		} +		else if(!pimpl->getVisible()) +		{ +			new_priority = LLPluginClassMedia::PRIORITY_HIDDEN; +		} +		else if(pimpl->hasFocus()) +		{ +			new_priority = LLPluginClassMedia::PRIORITY_HIGH; +			impl_count_interest_normal++;	// count this against the count of "normal" instances for priority purposes +		} +		else if(pimpl->getUsedInUI()) +		{ +			new_priority = LLPluginClassMedia::PRIORITY_NORMAL; +			impl_count_interest_normal++; +		} +		else if(pimpl->isParcelMedia()) +		{ +			new_priority = LLPluginClassMedia::PRIORITY_NORMAL; +			impl_count_interest_normal++; +		} +		else +		{ +			// Look at interest and CPU usage for instances that aren't in any of the above states. +			 +			// Heuristic -- if the media texture's approximate screen area is less than 1/4 of the native area of the texture, +			// turn it down to low instead of normal.  This may downsample for plugins that support it. +			bool media_is_small = false; +			F64 approximate_interest = pimpl->getApproximateTextureInterest(); +			if(approximate_interest == 0.0f) +			{ +				// this media has no current size, which probably means it's not loaded. +				media_is_small = true; +			} +			else if(pimpl->getInterest() < (approximate_interest / 4)) +			{ +				media_is_small = true; +			} +			 +			if(pimpl->getInterest() == 0.0f) +			{ +				// This media is completely invisible, due to being outside the view frustrum or out of range. +				new_priority = LLPluginClassMedia::PRIORITY_HIDDEN; +			} +			else if(check_cpu_usage && (total_cpu > max_cpu)) +			{ +				// Higher priority plugins have already used up the CPU budget.  Set remaining ones to slideshow priority. +				new_priority = LLPluginClassMedia::PRIORITY_SLIDESHOW; +			} +			else if((impl_count_interest_normal < (int)max_normal) && !media_is_small) +			{ +				// Up to max_normal inworld get normal priority +				new_priority = LLPluginClassMedia::PRIORITY_NORMAL; +				impl_count_interest_normal++; +			} +			else if (impl_count_interest_low + impl_count_interest_normal < (int)max_low + (int)max_normal) +			{ +				// The next max_low inworld get turned down +				new_priority = LLPluginClassMedia::PRIORITY_LOW; +				impl_count_interest_low++; +				 +				// Set the low priority size for downsampling to approximately the size the texture is displayed at. +				{ +					F32 approximate_interest_dimension = fsqrtf(pimpl->getInterest()); +					 +					pimpl->setLowPrioritySizeLimit(llround(approximate_interest_dimension)); +				} +			} +			else +			{ +				// Any additional impls (up to max_instances) get very infrequent time +				new_priority = LLPluginClassMedia::PRIORITY_SLIDESHOW; +			} +		} +		 +		if(!pimpl->getUsedInUI() && (new_priority != LLPluginClassMedia::PRIORITY_UNLOADED)) +		{ +			// This is a loadable inworld impl -- the last one in the list in this class defines the lowest loadable interest. +			lowest_interest_loadable = pimpl; +			 +			impl_count_total++; +		} + +		// Overrides if the window is minimized or we lost focus (taking care +		// not to accidentally "raise" the priority either) +		if (!gViewerWindow->getActive() /* viewer window minimized? */  +			&& new_priority > LLPluginClassMedia::PRIORITY_HIDDEN) +		{ +			new_priority = LLPluginClassMedia::PRIORITY_HIDDEN; +		} +		else if (!gFocusMgr.getAppHasFocus() /* viewer window lost focus? */ +				 && new_priority > LLPluginClassMedia::PRIORITY_LOW) +		{ +			new_priority = LLPluginClassMedia::PRIORITY_LOW; +		} +		 +		if(!inworld_media_enabled) +		{ +			// If inworld media is locked out, force all inworld media to stay unloaded. +			if(!pimpl->getUsedInUI()) +			{ +				new_priority = LLPluginClassMedia::PRIORITY_UNLOADED; +			} +		} +		// update the audio stream here as well +		if( !inworld_audio_enabled) +		{ +			if(LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio()) +			{ +				gAudiop->stopInternetStream(); +			} +		} +		pimpl->setPriority(new_priority); +		 +		if(pimpl->getUsedInUI()) +		{ +			// Any impls used in the UI should not be in the proximity list. +			pimpl->mProximity = -1; +		} +		else +		{ +			proximity_order.push_back(pimpl); +		} + +		total_cpu += pimpl->getCPUUsage(); +		 +		if (!pimpl->getUsedInUI() && pimpl->hasMedia()) +		{ +			sAnyMediaShowing = true; +		} + +	} + +	// Re-calculate this every time. +	sLowestLoadableImplInterest	= 0.0f; + +	// Only do this calculation if we've hit the impl count limit -- up until that point we always need to load media data. +	if(lowest_interest_loadable && (impl_count_total >= (int)max_instances)) +	{ +		// Get the interest value of this impl's object for use by isInterestingEnough +		LLVOVolume *object = lowest_interest_loadable->getSomeObject(); +		if(object) +		{ +			// NOTE: Don't use getMediaInterest() here.  We want the pixel area, not the total media interest, +			// 		so that we match up with the calculation done in LLMediaDataClient. +			sLowestLoadableImplInterest = object->getPixelArea(); +		} +	} +	 +	if(gSavedSettings.getBOOL("MediaPerformanceManagerDebug")) +	{ +		// Give impls the same ordering as the priority list +		// they're already in the right order for this. +	} +	else +	{ +		// Use a distance-based sort for proximity values.   +		std::stable_sort(proximity_order.begin(), proximity_order.end(), proximity_comparitor); +	} + +	// Transfer the proximity order to the proximity fields in the objects. +	for(int i = 0; i < (int)proximity_order.size(); i++) +	{ +		proximity_order[i]->mProximity = i; +	} +	 +	LL_DEBUGS("PluginPriority") << "Total reported CPU usage is " << total_cpu << llendl; + +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isAnyMediaShowing() +{ +	return sAnyMediaShowing; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::setAllMediaEnabled(bool val) +{ +	// Set "tentative" autoplay first.  We need to do this here or else +	// re-enabling won't start up the media below. +	gSavedSettings.setBOOL("MediaTentativeAutoPlay", val); +	 +	// Then  +	impl_list::iterator iter = sViewerMediaImplList.begin(); +	impl_list::iterator end = sViewerMediaImplList.end(); +	 +	for(; iter != end; iter++) +	{ +		LLViewerMediaImpl* pimpl = *iter; +		if (!pimpl->getUsedInUI()) +		{ +			pimpl->setDisabled(!val); +		} +	} +	 +	// Also do Parcel Media and Parcel Audio +	if (val) +	{ +		if (!LLViewerMedia::isParcelMediaPlaying() && LLViewerMedia::hasParcelMedia()) +		{	 +			LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); +		} +		 +		if (gSavedSettings.getBOOL("AudioStreamingMusic") && +			!LLViewerMedia::isParcelAudioPlaying() && +			gAudiop &&  +			LLViewerMedia::hasParcelAudio()) +		{ +			gAudiop->startInternetStream(LLViewerMedia::getParcelAudioURL()); +		} +	} +	else { +		// This actually unloads the impl, as opposed to "stop"ping the media +		LLViewerParcelMedia::stop(); +		if (gAudiop) gAudiop->stopInternetStream(); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isParcelMediaPlaying() +{ +	return (LLViewerMedia::hasParcelMedia() && LLViewerParcelMedia::getParcelMedia() && LLViewerParcelMedia::getParcelMedia()->hasMedia()); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::isParcelAudioPlaying() +{ +	return (LLViewerMedia::hasParcelAudio() && gAudiop && LLAudioEngine::AUDIO_PLAYING == gAudiop->isInternetStreamPlaying()); +} + +void LLViewerMedia::onAuthSubmit(const LLSD& notification, const LLSD& response) +{ +	LLViewerMediaImpl *impl = LLViewerMedia::getMediaImplFromTextureID(notification["payload"]["media_id"]); +	if(impl) +	{ +		LLPluginClassMedia* media = impl->getMediaPlugin(); +		if(media) +		{ +			if (response["ok"]) +			{ +				media->sendAuthResponse(true, response["username"], response["password"]); +			} +			else +			{ +				media->sendAuthResponse(false, "", ""); +			} +		} +	} +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::clearAllCookies() +{ +	// Clear all cookies for all plugins +	impl_list::iterator iter = sViewerMediaImplList.begin(); +	impl_list::iterator end = sViewerMediaImplList.end(); +	for (; iter != end; iter++) +	{ +		LLViewerMediaImpl* pimpl = *iter; +		if(pimpl->mMediaSource) +		{ +			pimpl->mMediaSource->clear_cookies(); +		} +	} +	 +	// Clear all cookies from the cookie store +	getCookieStore()->setAllCookies(""); + +	// FIXME: this may not be sufficient, since the on-disk cookie file won't get written until some browser instance exits cleanly. +	// It also won't clear cookies for other accounts, or for any account if we're not logged in, and won't do anything at all if there are no webkit plugins loaded. +	// Until such time as we can centralize cookie storage, the following hack should cover these cases: +	 +	// HACK: Look for cookie files in all possible places and delete them. +	// NOTE: this assumes knowledge of what happens inside the webkit plugin (it's what adds 'browser_profile' to the path and names the cookie file) +	 +	// Places that cookie files can be: +	// <getOSUserAppDir>/browser_profile/cookies +	// <getOSUserAppDir>/first_last/browser_profile/cookies  (note that there may be any number of these!) +	// <getOSUserAppDir>/first_last/plugin_cookies.txt  (note that there may be any number of these!) +	 +	std::string base_dir = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter(); +	std::string target; +	std::string filename; +	 +	lldebugs << "base dir = " << base_dir << llendl; + +	// The non-logged-in version is easy +	target = base_dir; +	target += "browser_profile"; +	target += gDirUtilp->getDirDelimiter(); +	target += "cookies"; +	lldebugs << "target = " << target << llendl; +	if(LLFile::isfile(target)) +	{ +		LLFile::remove(target); +	} +	 +	// the hard part: iterate over all user directories and delete the cookie file from each one +	LLDirIterator dir_iter(base_dir, "*_*"); +	while (dir_iter.next(filename)) +	{ +		target = base_dir; +		target += filename; +		target += gDirUtilp->getDirDelimiter(); +		target += "browser_profile"; +		target += gDirUtilp->getDirDelimiter(); +		target += "cookies"; +		lldebugs << "target = " << target << llendl; +		if(LLFile::isfile(target)) +		{	 +			LLFile::remove(target); +		} +		 +		// Other accounts may have new-style cookie files too -- delete them as well +		target = base_dir; +		target += filename; +		target += gDirUtilp->getDirDelimiter(); +		target += PLUGIN_COOKIE_FILE_NAME; +		lldebugs << "target = " << target << llendl; +		if(LLFile::isfile(target)) +		{	 +			LLFile::remove(target); +		} +	} +	 +	// If we have an OpenID cookie, re-add it to the cookie store. +	setOpenIDCookie(); +} +	 +///////////////////////////////////////////////////////////////////////////////////////// +// static  +void LLViewerMedia::clearAllCaches() +{ +	// Clear all plugins' caches +	impl_list::iterator iter = sViewerMediaImplList.begin(); +	impl_list::iterator end = sViewerMediaImplList.end(); +	for (; iter != end; iter++) +	{ +		LLViewerMediaImpl* pimpl = *iter; +		pimpl->clearCache(); +	} +} +	 +///////////////////////////////////////////////////////////////////////////////////////// +// static  +void LLViewerMedia::setCookiesEnabled(bool enabled) +{ +	// Set the "cookies enabled" flag for all loaded plugins +	impl_list::iterator iter = sViewerMediaImplList.begin(); +	impl_list::iterator end = sViewerMediaImplList.end(); +	for (; iter != end; iter++) +	{ +		LLViewerMediaImpl* pimpl = *iter; +		if(pimpl->mMediaSource) +		{ +			pimpl->mMediaSource->enable_cookies(enabled); +		} +	} +} +	 +///////////////////////////////////////////////////////////////////////////////////////// +// static  +void LLViewerMedia::setProxyConfig(bool enable, const std::string &host, int port) +{ +	// Set the proxy config for all loaded plugins +	impl_list::iterator iter = sViewerMediaImplList.begin(); +	impl_list::iterator end = sViewerMediaImplList.end(); +	for (; iter != end; iter++) +	{ +		LLViewerMediaImpl* pimpl = *iter; +		if(pimpl->mMediaSource) +		{ +			pimpl->mMediaSource->proxy_setup(enable, host, port); +		} +	} +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static  +///////////////////////////////////////////////////////////////////////////////////////// +// static +LLPluginCookieStore *LLViewerMedia::getCookieStore() +{ +	if(sCookieStore == NULL) +	{ +		sCookieStore = new LLPluginCookieStore; +	} +	 +	return sCookieStore; +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::loadCookieFile() +{ +	// build filename for each user +	std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME); + +	if (resolved_filename.empty()) +	{ +		llinfos << "can't get path to plugin cookie file - probably not logged in yet." << llendl; +		return; +	} +	 +	// open the file for reading +	llifstream file(resolved_filename); +	if (!file.is_open()) +	{ +		llwarns << "can't load plugin cookies from file \"" << PLUGIN_COOKIE_FILE_NAME << "\"" << llendl; +		return; +	} +	 +	getCookieStore()->readAllCookies(file, true); + +	file.close(); +	 +	// send the clear_cookies message to all loaded plugins +	impl_list::iterator iter = sViewerMediaImplList.begin(); +	impl_list::iterator end = sViewerMediaImplList.end(); +	for (; iter != end; iter++) +	{ +		LLViewerMediaImpl* pimpl = *iter; +		if(pimpl->mMediaSource) +		{ +			pimpl->mMediaSource->clear_cookies(); +		} +	} +	 +	// If we have an OpenID cookie, re-add it to the cookie store. +	setOpenIDCookie(); +} + + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::saveCookieFile() +{ +	// build filename for each user +	std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME); + +	if (resolved_filename.empty()) +	{ +		llinfos << "can't get path to plugin cookie file - probably not logged in yet." << llendl; +		return; +	} + +	// open a file for writing +	llofstream file (resolved_filename); +	if (!file.is_open()) +	{ +		llwarns << "can't open plugin cookie file \"" << PLUGIN_COOKIE_FILE_NAME << "\" for writing" << llendl; +		return; +	} + +	getCookieStore()->writePersistentCookies(file); + +	file.close(); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::addCookie(const std::string &name, const std::string &value, const std::string &domain, const LLDate &expires, const std::string &path, bool secure) +{ +	std::stringstream cookie; +	 +	cookie << name << "=" << LLPluginCookieStore::quoteString(value); +	 +	if(expires.notNull()) +	{ +		cookie << "; expires=" << expires.asRFC1123(); +	} +	 +	cookie << "; domain=" << domain; + +	cookie << "; path=" << path; +	 +	if(secure) +	{ +		cookie << "; secure"; +	} +	 +	getCookieStore()->setCookies(cookie.str()); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::addSessionCookie(const std::string &name, const std::string &value, const std::string &domain, const std::string &path, bool secure) +{ +	// A session cookie just has a NULL date. +	addCookie(name, value, domain, LLDate(), path, secure); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::removeCookie(const std::string &name, const std::string &domain, const std::string &path ) +{ +	// To remove a cookie, add one with the same name, domain, and path that expires in the past. +	 +	addCookie(name, "", domain, LLDate(LLDate::now().secondsSinceEpoch() - 1.0), path); +} + + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::setOpenIDCookie() +{ +	if(!sOpenIDCookie.empty()) +	{ +		// The LLURL can give me the 'authority', which is of the form: [username[:password]@]hostname[:port] +		// We want just the hostname for the cookie code, but LLURL doesn't seem to have a way to extract that. +		// We therefore do it here. +		std::string authority = sOpenIDURL.mAuthority; +		std::string::size_type host_start = authority.find('@');  +		if(host_start == std::string::npos) +		{ +			// no username/password +			host_start = 0; +		} +		else +		{ +			// Hostname starts after the @.  +			// (If the hostname part is empty, this may put host_start at the end of the string.  In that case, it will end up passing through an empty hostname, which is correct.) +			++host_start; +		} +		std::string::size_type host_end = authority.rfind(':');  +		if((host_end == std::string::npos) || (host_end < host_start)) +		{ +			// no port +			host_end = authority.size(); +		} +		 +		getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(host_start, host_end - host_start)); + +		// *HACK: Doing this here is nasty, find a better way. +		LLWebSharing::instance().setOpenIDCookie(sOpenIDCookie); + +		// Do a web profile get so we can store the cookie  +		LLSD headers = LLSD::emptyMap(); +		headers["Accept"] = "*/*"; +		headers["Cookie"] = sOpenIDCookie; +		headers["User-Agent"] = getCurrentUserAgent(); + +		std::string profile_url = getProfileURL(""); +		LLURL raw_profile_url( profile_url.c_str() ); + +		LLHTTPClient::get(profile_url,   +			new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()), +			headers); +	} +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::openIDSetup(const std::string &openid_url, const std::string &openid_token) +{ +	LL_DEBUGS("MediaAuth") << "url = \"" << openid_url << "\", token = \"" << openid_token << "\"" << LL_ENDL; + +	// post the token to the url  +	// the responder will need to extract the cookie(s). + +	// Save the OpenID URL for later -- we may need the host when adding the cookie. +	sOpenIDURL.init(openid_url.c_str()); +	 +	// We shouldn't ever do this twice, but just in case this code gets repurposed later, clear existing cookies. +	sOpenIDCookie.clear(); + +	LLSD headers = LLSD::emptyMap(); +	// Keep LLHTTPClient from adding an "Accept: application/llsd+xml" header +	headers["Accept"] = "*/*"; +	// and use the expected content-type for a post, instead of the LLHTTPClient::postRaw() default of "application/octet-stream" +	headers["Content-Type"] = "application/x-www-form-urlencoded"; + +	// postRaw() takes ownership of the buffer and releases it later, so we need to allocate a new buffer here. +	size_t size = openid_token.size(); +	U8 *data = new U8[size]; +	memcpy(data, openid_token.data(), size); + +	LLHTTPClient::postRaw(  +		openid_url,  +		data,  +		size,  +		new LLViewerMediaOpenIDResponder(), +		headers); +			 +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::openIDCookieResponse(const std::string &cookie) +{ +	LL_DEBUGS("MediaAuth") << "Cookie received: \"" << cookie << "\"" << LL_ENDL; +	 +	sOpenIDCookie += cookie; + +	setOpenIDCookie(); +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::proxyWindowOpened(const std::string &target, const std::string &uuid) +{ +	if(uuid.empty()) +		return; +		 +	for (impl_list::iterator iter = sViewerMediaImplList.begin(); iter != sViewerMediaImplList.end(); iter++) +	{ +		if((*iter)->mMediaSource && (*iter)->mMediaSource->pluginSupportsMediaBrowser()) +		{ +			(*iter)->mMediaSource->proxyWindowOpened(target, uuid); +		} +	} +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::proxyWindowClosed(const std::string &uuid) +{ +	if(uuid.empty()) +		return; + +	for (impl_list::iterator iter = sViewerMediaImplList.begin(); iter != sViewerMediaImplList.end(); iter++) +	{ +		if((*iter)->mMediaSource && (*iter)->mMediaSource->pluginSupportsMediaBrowser()) +		{ +			(*iter)->mMediaSource->proxyWindowClosed(uuid); +		} +	} +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::createSpareBrowserMediaSource() +{ +	// If we don't have a spare browser media source, create one. +	// However, if PluginAttachDebuggerToPlugins is set then don't spawn a spare +	// SLPlugin process in order to not be confused by an unrelated gdb terminal +	// popping up at the moment we start a media plugin. +	if (!sSpareBrowserMediaSource && !gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins")) +	{ +		// The null owner will keep the browser plugin from fully initializing  +		// (specifically, it keeps LLPluginClassMedia from negotiating a size change,  +		// which keeps MediaPluginWebkit::initBrowserWindow from doing anything until we have some necessary data, like the background color) +		sSpareBrowserMediaSource = LLViewerMediaImpl::newSourceFromMediaType("text/html", NULL, 0, 0); +	} +} + +///////////////////////////////////////////////////////////////////////////////////////// +// static +LLPluginClassMedia* LLViewerMedia::getSpareBrowserMediaSource()  +{ +	LLPluginClassMedia* result = sSpareBrowserMediaSource; +	sSpareBrowserMediaSource = NULL; +	return result;  +}; + +bool LLViewerMedia::hasInWorldMedia() +{ +	if (sInWorldMediaDisabled) return false; +	impl_list::iterator iter = sViewerMediaImplList.begin(); +	impl_list::iterator end = sViewerMediaImplList.end(); +	// This should be quick, because there should be very few non-in-world-media impls +	for (; iter != end; iter++) +	{ +		LLViewerMediaImpl* pimpl = *iter; +		if (!pimpl->getUsedInUI() && !pimpl->isParcelMedia()) +		{ +			// Found an in-world media impl +			return true; +		} +	} +	return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::hasParcelMedia() +{ +	return !LLViewerParcelMedia::getURL().empty(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +bool LLViewerMedia::hasParcelAudio() +{ +	return !LLViewerMedia::getParcelAudioURL().empty(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +std::string LLViewerMedia::getParcelAudioURL() +{ +	return LLViewerParcelMgr::getInstance()->getAgentParcel()->getMusicURL(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::initClass() +{ +	gIdleCallbacks.addFunction(LLViewerMedia::updateMedia, NULL);	 +	sTeleportFinishConnection = LLViewerParcelMgr::getInstance()-> +		setTeleportFinishedCallback(boost::bind(&LLViewerMedia::onTeleportFinished)); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::cleanupClass() +{ +	gIdleCallbacks.deleteFunction(LLViewerMedia::updateMedia, NULL); +	sTeleportFinishConnection.disconnect(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// static +void LLViewerMedia::onTeleportFinished() +{ +	// On teleport, clear this setting (i.e. set it to true) +	gSavedSettings.setBOOL("MediaTentativeAutoPlay", true); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// LLViewerMediaImpl +////////////////////////////////////////////////////////////////////////////////////////// +LLViewerMediaImpl::LLViewerMediaImpl(	  const LLUUID& texture_id,  +										  S32 media_width,  +										  S32 media_height,  +										  U8 media_auto_scale,  +										  U8 media_loop) +:	 +	mMediaSource( NULL ), +	mMovieImageHasMips(false), +	mMediaWidth(media_width), +	mMediaHeight(media_height), +	mMediaAutoScale(media_auto_scale), +	mMediaLoop(media_loop), +	mNeedsNewTexture(true), +	mTextureUsedWidth(0), +	mTextureUsedHeight(0), +	mSuspendUpdates(false), +	mVisible(true), +	mLastSetCursor( UI_CURSOR_ARROW ), +	mMediaNavState( MEDIANAVSTATE_NONE ), +	mInterest(0.0f), +	mUsedInUI(false), +	mHasFocus(false), +	mPriority(LLPluginClassMedia::PRIORITY_UNLOADED), +	mNavigateRediscoverType(false), +	mNavigateServerRequest(false), +	mMediaSourceFailed(false), +	mRequestedVolume(1.0f), +	mIsMuted(false), +	mNeedsMuteCheck(false), +	mPreviousMediaState(MEDIA_NONE), +	mPreviousMediaTime(0.0f), +	mIsDisabled(false), +	mIsParcelMedia(false), +	mProximity(-1), +	mProximityDistance(0.0f), +	mMimeTypeProbe(NULL), +	mMediaAutoPlay(false), +	mInNearbyMediaList(false), +	mClearCache(false), +	mBackgroundColor(LLColor4::white), +	mNavigateSuspended(false), +	mNavigateSuspendedDeferred(false), +	mIsUpdated(false), +	mTrustedBrowser(false) +{  + +	// Set up the mute list observer if it hasn't been set up already. +	if(!sViewerMediaMuteListObserverInitialized) +	{ +		LLMuteList::getInstance()->addObserver(&sViewerMediaMuteListObserver); +		sViewerMediaMuteListObserverInitialized = true; +	} +	 +	add_media_impl(this); + +	setTextureID(texture_id); +	 +	// connect this media_impl to the media texture, creating it if it doesn't exist.0 +	// This is necessary because we need to be able to use getMaxVirtualSize() even if the media plugin is not loaded. +	LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture(mTextureId); +	if(media_tex) +	{ +		media_tex->setMediaImpl(); +	} + +} + +////////////////////////////////////////////////////////////////////////////////////////// +LLViewerMediaImpl::~LLViewerMediaImpl() +{ +	destroyMediaSource(); +	 +	LLViewerMediaTexture::removeMediaImplFromTexture(mTextureId) ; + +	setTextureID(); +	remove_media_impl(this); +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::emitEvent(LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event) +{ +	// Broadcast to observers using the superclass version +	LLViewerMediaEventEmitter::emitEvent(plugin, event); +	 +	// If this media is on one or more LLVOVolume objects, tell them about the event as well. +	std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ; +	while(iter != mObjectList.end()) +	{ +		LLVOVolume *self = *iter; +		++iter; +		self->mediaEvent(this, plugin, event); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::initializeMedia(const std::string& mime_type) +{ +	bool mimeTypeChanged = (mMimeType != mime_type); +	bool pluginChanged = (LLMIMETypes::implType(mCurrentMimeType) != LLMIMETypes::implType(mime_type)); +	 +	if(!mMediaSource || pluginChanged) +	{ +		// We don't have a plugin at all, or the new mime type is handled by a different plugin than the old mime type. +		(void)initializePlugin(mime_type); +	} +	else if(mimeTypeChanged) +	{ +		// The same plugin should be able to handle the new media -- just update the stored mime type. +		mMimeType = mime_type; +	} + +	return (mMediaSource != NULL); +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::createMediaSource() +{ +	if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED) +	{ +		// This media shouldn't be created yet. +		return; +	} +	 +	if(! mMediaURL.empty()) +	{ +		navigateInternal(); +	} +	else if(! mMimeType.empty()) +	{ +		if (!initializeMedia(mMimeType)) +		{ +			LL_WARNS("Media") << "Failed to initialize media for mime type " << mMimeType << LL_ENDL; +		} +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::destroyMediaSource() +{ +	mNeedsNewTexture = true; + +	// Tell the viewer media texture it's no longer active +	LLViewerMediaTexture* oldImage = LLViewerTextureManager::findMediaTexture( mTextureId ); +	if (oldImage) +	{ +		oldImage->setPlaying(FALSE) ; +	} +	 +	cancelMimeTypeProbe(); +	 +	if(mMediaSource) +	{ +		mMediaSource->setDeleteOK(true) ; +		delete mMediaSource; +		mMediaSource = NULL; +	}	 +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::setMediaType(const std::string& media_type) +{ +	mMimeType = media_type; +} + +////////////////////////////////////////////////////////////////////////////////////////// +/*static*/ +LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, const std::string target) +{ +	std::string plugin_basename = LLMIMETypes::implType(media_type); +	LLPluginClassMedia* media_source = NULL; +	 +	// HACK: we always try to keep a spare running webkit plugin around to improve launch times. +	// If a spare was already created before PluginAttachDebuggerToPlugins was set, don't use it. +	if(plugin_basename == "media_plugin_webkit" && !gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins")) +	{ +		media_source = LLViewerMedia::getSpareBrowserMediaSource(); +		if(media_source) +		{ +			media_source->setOwner(owner); +			media_source->setTarget(target); +			media_source->setSize(default_width, default_height); +						 +			return media_source; +		} +	} +	 +	if(plugin_basename.empty()) +	{ +		LL_WARNS("Media") << "Couldn't find plugin for media type " << media_type << LL_ENDL; +	} +	else +	{ +		std::string launcher_name = gDirUtilp->getLLPluginLauncher(); +		std::string plugin_name = gDirUtilp->getLLPluginFilename(plugin_basename); +		std::string user_data_path = gDirUtilp->getOSUserAppDir(); +		user_data_path += gDirUtilp->getDirDelimiter(); + +		// Fix for EXT-5960 - make browser profile specific to user (cache, cookies etc.) +		// If the linden username returned is blank, that can only mean we are +		// at the login page displaying login Web page or Web browser test via Develop menu. +		// In this case we just use whatever gDirUtilp->getOSUserAppDir() gives us (this +		// is what we always used before this change) +		std::string linden_user_dir = gDirUtilp->getLindenUserDir(); +		if ( ! linden_user_dir.empty() ) +		{ +			// gDirUtilp->getLindenUserDir() is whole path, not just Linden name +			user_data_path = linden_user_dir; +			user_data_path += gDirUtilp->getDirDelimiter(); +		}; + +		// See if the plugin executable exists +		llstat s; +		if(LLFile::stat(launcher_name, &s)) +		{ +			LL_WARNS("Media") << "Couldn't find launcher at " << launcher_name << LL_ENDL; +		} +		else if(LLFile::stat(plugin_name, &s)) +		{ +			LL_WARNS("Media") << "Couldn't find plugin at " << plugin_name << LL_ENDL; +		} +		else +		{ +			media_source = new LLPluginClassMedia(owner); +			media_source->setSize(default_width, default_height); +			media_source->setUserDataPath(user_data_path); +			media_source->setLanguageCode(LLUI::getLanguage()); + +			// collect 'cookies enabled' setting from prefs and send to embedded browser +			bool cookies_enabled = gSavedSettings.getBOOL( "CookiesEnabled" ); +			media_source->enable_cookies( cookies_enabled ); + +			// collect 'plugins enabled' setting from prefs and send to embedded browser +			bool plugins_enabled = gSavedSettings.getBOOL( "BrowserPluginsEnabled" ); +			media_source->setPluginsEnabled( plugins_enabled ); + +			// collect 'javascript enabled' setting from prefs and send to embedded browser +			bool javascript_enabled = gSavedSettings.getBOOL( "BrowserJavascriptEnabled" ); +			media_source->setJavascriptEnabled( javascript_enabled ); +			 +			media_source->setTarget(target); +			 +			const std::string plugin_dir = gDirUtilp->getLLPluginDir(); +			if (media_source->init(launcher_name, plugin_dir, plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))) +			{ +				return media_source; +			} +			else +			{ +				LL_WARNS("Media") << "Failed to init plugin.  Destroying." << LL_ENDL; +				delete media_source; +			} +		} +	} +	 +	LL_WARNS("Plugin") << "plugin intialization failed for mime type: " << media_type << LL_ENDL; +	LLSD args; +	args["MIME_TYPE"] = media_type; +	LLNotificationsUtil::add("NoPlugin", args); + +	return NULL; +}							 + +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) +{ +	if(mMediaSource) +	{ +		// Save the previous media source's last set size before destroying it. +		mMediaWidth = mMediaSource->getSetWidth(); +		mMediaHeight = mMediaSource->getSetHeight(); +	} +	 +	// Always delete the old media impl first. +	destroyMediaSource(); +	 +	// and unconditionally set the mime type +	mMimeType = media_type; + +	if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED) +	{ +		// This impl should not be loaded at this time. +		LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL; +		 +		return false; +	} + +	// If we got here, we want to ignore previous init failures. +	mMediaSourceFailed = false; + +	// Save the MIME type that really caused the plugin to load +	mCurrentMimeType = mMimeType; + +	LLPluginClassMedia* media_source = newSourceFromMediaType(mMimeType, this, mMediaWidth, mMediaHeight, mTarget); +	 +	if (media_source) +	{ +		media_source->setDisableTimeout(gSavedSettings.getBOOL("DebugPluginDisableTimeout")); +		media_source->setLoop(mMediaLoop); +		media_source->setAutoScale(mMediaAutoScale); +		media_source->setBrowserUserAgent(LLViewerMedia::getCurrentUserAgent()); +		media_source->focus(mHasFocus); +		media_source->setBackgroundColor(mBackgroundColor); +		 +		if(gSavedSettings.getBOOL("BrowserIgnoreSSLCertErrors")) +		{ +			media_source->ignore_ssl_cert_errors(true); +		} + +		// the correct way to deal with certs it to load ours from CA.pem and append them to the ones +		// Qt/WebKit loads from your system location. +		// Note: This needs the new CA.pem file with the Equifax Secure Certificate Authority  +		// cert at the bottom: (MIIDIDCCAomgAwIBAgIENd70zzANBg) +		std::string ca_path = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "CA.pem" ); +		media_source->addCertificateFilePath( ca_path ); + +		media_source->proxy_setup(gSavedSettings.getBOOL("BrowserProxyEnabled"), gSavedSettings.getString("BrowserProxyAddress"), gSavedSettings.getS32("BrowserProxyPort")); +		 +		if(mClearCache) +		{ +			mClearCache = false; +			media_source->clear_cache(); +		} +		 +		// TODO: Only send cookies to plugins that need them +		//  Ideally, the plugin should tell us whether it handles cookies or not -- either via the init response or through a separate message. +		//  Due to the ordering of messages, it's possible we wouldn't get that information back in time to send cookies before sending a navigate message, +		//  which could cause odd race conditions. +		std::string all_cookies = LLViewerMedia::getCookieStore()->getAllCookies(); +		lldebugs << "setting cookies: " << all_cookies << llendl; +		if(!all_cookies.empty()) +		{ +			media_source->set_cookies(all_cookies); +		} +				 +		mMediaSource = media_source; +		mMediaSource->setDeleteOK(false) ; +		updateVolume(); + +		return true; +	} + +	// Make sure the timer doesn't try re-initing this plugin repeatedly until something else changes. +	mMediaSourceFailed = true; + +	return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::loadURI() +{ +	if(mMediaSource) +	{ +		// trim whitespace from front and back of URL - fixes EXT-5363 +		LLStringUtil::trim( mMediaURL ); + +		// *HACK: we don't know if the URI coming in is properly escaped +		// (the contract doesn't specify whether it is escaped or not. +		// but LLQtWebKit expects it to be, so we do our best to encode +		// special characters) +		// The strings below were taken right from http://www.ietf.org/rfc/rfc1738.txt +		// Note especially that '%' and '/' are there. +		std::string uri = LLURI::escape(mMediaURL, +										"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +										"0123456789" +										"$-_.+" +										"!*'()," +										"{}|\\^~[]`" +										"<>#%" +										";/?:@&=", +										false); +		llinfos << "Asking media source to load URI: " << uri << llendl; +		 +		mMediaSource->loadURI( uri ); +		 +		// A non-zero mPreviousMediaTime means that either this media was previously unloaded by the priority code while playing/paused,  +		// or a seek happened before the media loaded.  In either case, seek to the saved time. +		if(mPreviousMediaTime != 0.0f) +		{ +			seek(mPreviousMediaTime); +		} +			 +		if(mPreviousMediaState == MEDIA_PLAYING) +		{ +			// This media was playing before this instance was unloaded. +			start(); +		} +		else if(mPreviousMediaState == MEDIA_PAUSED) +		{ +			// This media was paused before this instance was unloaded. +			pause(); +		} +		else +		{ +			// No relevant previous media play state -- if we're loading the URL, we want to start playing. +			start(); +		} +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::setSize(int width, int height) +{ +	mMediaWidth = width; +	mMediaHeight = height; +	if(mMediaSource) +	{ +		mMediaSource->setSize(width, height); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::showNotification(LLNotificationPtr notify) +{ +	mNotification = notify; +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::hideNotification() +{ +	mNotification.reset(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::play() +{ +	// If the media source isn't there, try to initialize it and load an URL. +	if(mMediaSource == NULL) +	{ +	 	if(!initializeMedia(mMimeType)) +		{ +			// This may be the case where the plugin's priority is PRIORITY_UNLOADED +			return; +		} +		 +		// Only do this if the media source was just loaded. +		loadURI(); +	} +	 +	// always start the media +	start(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::stop() +{ +	if(mMediaSource) +	{ +		mMediaSource->stop(); +		// destroyMediaSource(); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::pause() +{ +	if(mMediaSource) +	{ +		mMediaSource->pause(); +	} +	else +	{ +		mPreviousMediaState = MEDIA_PAUSED; +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::start() +{ +	if(mMediaSource) +	{ +		mMediaSource->start(); +	} +	else +	{ +		mPreviousMediaState = MEDIA_PLAYING; +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::seek(F32 time) +{ +	if(mMediaSource) +	{ +		mMediaSource->seek(time); +	} +	else +	{ +		// Save the seek time to be set when the media is loaded. +		mPreviousMediaTime = time; +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::skipBack(F32 step_scale) +{ +	if(mMediaSource) +	{ +		if(mMediaSource->pluginSupportsMediaTime()) +		{ +			F64 back_step = mMediaSource->getCurrentTime() - (mMediaSource->getDuration()*step_scale); +			if(back_step < 0.0) +			{ +				back_step = 0.0; +			} +			mMediaSource->seek(back_step); +		} +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::skipForward(F32 step_scale) +{ +	if(mMediaSource) +	{ +		if(mMediaSource->pluginSupportsMediaTime()) +		{ +			F64 forward_step = mMediaSource->getCurrentTime() + (mMediaSource->getDuration()*step_scale); +			if(forward_step > mMediaSource->getDuration()) +			{ +				forward_step = mMediaSource->getDuration(); +			} +			mMediaSource->seek(forward_step); +		} +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::setVolume(F32 volume) +{ +	mRequestedVolume = volume; +	updateVolume(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::updateVolume() +{ +	if(mMediaSource) +	{ +		// always scale the volume by the global media volume  +		F32 volume = mRequestedVolume * LLViewerMedia::getVolume(); + +		if (mProximityCamera > 0)  +		{ +			if (mProximityCamera > gSavedSettings.getF32("MediaRollOffMax")) +			{ +				volume = 0; +			} +			else if (mProximityCamera > gSavedSettings.getF32("MediaRollOffMin")) +			{ +				// attenuated_volume = 1 / (roll_off_rate * (d - min))^2 +				// the +1 is there so that for distance 0 the volume stays the same +				F64 adjusted_distance = mProximityCamera - gSavedSettings.getF32("MediaRollOffMin"); +				F64 attenuation = 1.0 + (gSavedSettings.getF32("MediaRollOffRate") * adjusted_distance); +				attenuation = 1.0 / (attenuation * attenuation); +				// the attenuation multiplier should never be more than one since that would increase volume +				volume = volume * llmin(1.0, attenuation); +			} +		} + +		mMediaSource->setVolume(volume); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +F32 LLViewerMediaImpl::getVolume() +{ +	return mRequestedVolume; +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::focus(bool focus) +{ +	mHasFocus = focus; +	 +	if (mMediaSource) +	{ +		// call focus just for the hell of it, even though this apopears to be a nop +		mMediaSource->focus(focus); +		if (focus) +		{ +			// spoof a mouse click to *actually* pass focus +			// Don't do this anymore -- it actually clicks through now. +//			mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, 1, 1, 0); +//			mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, 1, 1, 0); +		} +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::hasFocus() const +{ +	// FIXME: This might be able to be a bit smarter by hooking into LLViewerMediaFocus, etc. +	return mHasFocus; +} + +std::string LLViewerMediaImpl::getCurrentMediaURL() +{ +	if(!mCurrentMediaURL.empty()) +	{ +		return mCurrentMediaURL; +	} +	 +	return mMediaURL; +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::clearCache() +{ +	if(mMediaSource) +	{ +		mMediaSource->clear_cache(); +	} +	else +	{ +		mClearCache = true; +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::mouseDown(S32 x, S32 y, MASK mask, S32 button) +{ +	scaleMouse(&x, &y); +	mLastMouseX = x; +	mLastMouseY = y; +//	llinfos << "mouse down (" << x << ", " << y << ")" << llendl; +	if (mMediaSource) +	{ +		mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOWN, button, x, y, mask); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::mouseUp(S32 x, S32 y, MASK mask, S32 button) +{ +	scaleMouse(&x, &y); +	mLastMouseX = x; +	mLastMouseY = y; +//	llinfos << "mouse up (" << x << ", " << y << ")" << llendl; +	if (mMediaSource) +	{ +		mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, button, x, y, mask); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::mouseMove(S32 x, S32 y, MASK mask) +{ +    scaleMouse(&x, &y); +	mLastMouseX = x; +	mLastMouseY = y; +//	llinfos << "mouse move (" << x << ", " << y << ")" << llendl; +	if (mMediaSource) +	{ +		mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_MOVE, 0, x, y, mask); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +//static  +void LLViewerMediaImpl::scaleTextureCoords(const LLVector2& texture_coords, S32 *x, S32 *y) +{ +	F32 texture_x = texture_coords.mV[VX]; +	F32 texture_y = texture_coords.mV[VY]; +	 +	// Deal with repeating textures by wrapping the coordinates into the range [0, 1.0) +	texture_x = fmodf(texture_x, 1.0f); +	if(texture_x < 0.0f) +		texture_x = 1.0 + texture_x; +		 +	texture_y = fmodf(texture_y, 1.0f); +	if(texture_y < 0.0f) +		texture_y = 1.0 + texture_y; + +	// scale x and y to texel units. +	*x = llround(texture_x * mMediaSource->getTextureWidth()); +	*y = llround((1.0f - texture_y) * mMediaSource->getTextureHeight()); + +	// Adjust for the difference between the actual texture height and the amount of the texture in use. +	*y -= (mMediaSource->getTextureHeight() - mMediaSource->getHeight()); +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::mouseDown(const LLVector2& texture_coords, MASK mask, S32 button) +{ +	if(mMediaSource) +	{ +		S32 x, y; +		scaleTextureCoords(texture_coords, &x, &y); + +		mouseDown(x, y, mask, button); +	} +} + +void LLViewerMediaImpl::mouseUp(const LLVector2& texture_coords, MASK mask, S32 button) +{ +	if(mMediaSource) +	{		 +		S32 x, y; +		scaleTextureCoords(texture_coords, &x, &y); + +		mouseUp(x, y, mask, button); +	} +} + +void LLViewerMediaImpl::mouseMove(const LLVector2& texture_coords, MASK mask) +{ +	if(mMediaSource) +	{		 +		S32 x, y; +		scaleTextureCoords(texture_coords, &x, &y); + +		mouseMove(x, y, mask); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button) +{ +	scaleMouse(&x, &y); +	mLastMouseX = x; +	mLastMouseY = y; +	if (mMediaSource) +	{ +		mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_DOUBLE_CLICK, button, x, y, mask); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::scrollWheel(S32 x, S32 y, MASK mask) +{ +	scaleMouse(&x, &y); +	mLastMouseX = x; +	mLastMouseY = y; +	if (mMediaSource) +	{ +		mMediaSource->scrollEvent(x, y, mask); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::onMouseCaptureLost() +{ +	if (mMediaSource) +	{ +		mMediaSource->mouseEvent(LLPluginClassMedia::MOUSE_EVENT_UP, 0, mLastMouseX, mLastMouseY, 0); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask)  +{  +	// NOTE: this is called when the mouse is released when we have capture. +	// Due to the way mouse coordinates are mapped to the object, we can't use the x and y coordinates that come in with the event. +	 +	if(hasMouseCapture()) +	{ +		// Release the mouse -- this will also send a mouseup to the media +		gFocusMgr.setMouseCapture( FALSE ); +	} + +	return TRUE;  +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::updateJavascriptObject() +{ +	if ( mMediaSource ) +	{ +		// flag to expose this information to internal browser or not. +		bool expose_javascript_object = gSavedSettings.getBOOL("BrowserEnableJSObject"); +		mMediaSource->jsExposeObjectEvent( expose_javascript_object ); + +		// indicate if the values we have are valid (currently do this blanket-fashion for +		// everything depending on whether you are logged in or not - this may require a  +		// more granular approach once variables are added that ARE valid before login +		bool logged_in = LLLoginInstance::getInstance()->authSuccess(); +		mMediaSource->jsValuesValidEvent( logged_in ); + +		// current location within a region +		LLVector3 agent_pos = gAgent.getPositionAgent(); +		double x = agent_pos.mV[ VX ]; +		double y = agent_pos.mV[ VY ]; +		double z = agent_pos.mV[ VZ ]; +		mMediaSource->jsAgentLocationEvent( x, y, z ); + +		// current region agent is in +		std::string region_name(""); +		LLViewerRegion* region = gAgent.getRegion(); +		if ( region ) +		{ +			region_name = region->getName(); +		}; +		mMediaSource->jsAgentRegionEvent( region_name ); + +		// language code the viewer is set to +		mMediaSource->jsAgentLanguageEvent( LLUI::getLanguage() ); + +		// maturity setting the agent has selected +		if ( gAgent.prefersAdult() ) +			mMediaSource->jsAgentMaturityEvent( "GMA" );	// Adult means see adult, mature and general content +		else +		if ( gAgent.prefersMature() ) +			mMediaSource->jsAgentMaturityEvent( "GM" );	// Mature means see mature and general content +		else +		if ( gAgent.prefersPG() ) +			mMediaSource->jsAgentMaturityEvent( "G" );	// PG means only see General content +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +std::string LLViewerMediaImpl::getName() const  +{  +	if (mMediaSource) +	{ +		return mMediaSource->getMediaName(); +	} +	 +	return LLStringUtil::null;  +}; + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::navigateBack() +{ +	if (mMediaSource) +	{ +		mMediaSource->browse_back(); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::navigateForward() +{ +	if (mMediaSource) +	{ +		mMediaSource->browse_forward(); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::navigateReload() +{ +	navigateTo(getCurrentMediaURL(), "", true, false); +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::navigateHome() +{ +	bool rediscover_mimetype = mHomeMimeType.empty(); +	navigateTo(mHomeURL, mHomeMimeType, rediscover_mimetype, false); +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::unload() +{ +	// Unload the media impl and clear its state. +	destroyMediaSource(); +	resetPreviousMediaState(); +	mMediaURL.clear(); +	mMimeType.clear(); +	mCurrentMediaURL.clear(); +	mCurrentMimeType.clear(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mime_type,  bool rediscover_type, bool server_request) +{ +	cancelMimeTypeProbe(); + +	if(mMediaURL != url) +	{ +		// Don't carry media play state across distinct URLs. +		resetPreviousMediaState(); +	} +	 +	// Always set the current URL and MIME type. +	mMediaURL = url; +	mMimeType = mime_type; +	 +	// Clear the current media URL, since it will no longer be correct. +	mCurrentMediaURL.clear(); +	 +	// if mime type discovery was requested, we'll need to do it when the media loads +	mNavigateRediscoverType = rediscover_type; +	 +	// and if this was a server request, the navigate on load will also need to be one. +	mNavigateServerRequest = server_request; +	 +	// An explicit navigate resets the "failed" flag. +	mMediaSourceFailed = false; + +	if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED) +	{ +		// Helpful to have media urls in log file. Shouldn't be spammy. +		llinfos << "NOT LOADING media id= " << mTextureId << " url=" << url << " mime_type=" << mime_type << llendl; + +		// This impl should not be loaded at this time. +		LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL; +		 +		return; +	} + +	navigateInternal(); +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::navigateInternal() +{ +	// Helpful to have media urls in log file. Shouldn't be spammy. +	llinfos << "media id= " << mTextureId << " url=" << mMediaURL << " mime_type=" << mMimeType << llendl; + +	if(mNavigateSuspended) +	{ +		llwarns << "Deferring navigate." << llendl; +		mNavigateSuspendedDeferred = true; +		return; +	} +	 +	if(mMimeTypeProbe != NULL) +	{ +		llwarns << "MIME type probe already in progress -- bailing out." << llendl; +		return; +	} +	 +	if(mNavigateServerRequest) +	{ +		setNavState(MEDIANAVSTATE_SERVER_SENT); +	} +	else +	{ +		setNavState(MEDIANAVSTATE_NONE); +	} +			 +	// If the caller has specified a non-empty MIME type, look that up in our MIME types list. +	// If we have a plugin for that MIME type, use that instead of attempting auto-discovery. +	// This helps in supporting legacy media content where the server the media resides on returns a bogus MIME type +	// but the parcel owner has correctly set the MIME type in the parcel media settings. +	 +	if(!mMimeType.empty() && (mMimeType != LLMIMETypes::getDefaultMimeType())) +	{ +		std::string plugin_basename = LLMIMETypes::implType(mMimeType); +		if(!plugin_basename.empty()) +		{ +			// We have a plugin for this mime type +			mNavigateRediscoverType = false; +		} +	} + +	if(mNavigateRediscoverType) +	{ + +		LLURI uri(mMediaURL); +		std::string scheme = uri.scheme(); + +		if(scheme.empty() || "http" == scheme || "https" == scheme) +		{ +			// If we don't set an Accept header, LLHTTPClient will add one like this: +			//    Accept: application/llsd+xml +			// which is really not what we want. +			LLSD headers = LLSD::emptyMap(); +			headers["Accept"] = "*/*"; +			// Allow cookies in the response, to prevent a redirect loop when accessing join.secondlife.com +			headers["Cookie"] = ""; +			LLHTTPClient::getHeaderOnly( mMediaURL, new LLMimeDiscoveryResponder(this), headers, 10.0f); +		} +		else if("data" == scheme || "file" == scheme || "about" == scheme) +		{ +			// FIXME: figure out how to really discover the type for these schemes +			// We use "data" internally for a text/html url for loading the login screen +			if(initializeMedia("text/html")) +			{ +				loadURI(); +			} +		} +		else +		{ +			// This catches 'rtsp://' urls +			if(initializeMedia(scheme)) +			{ +				loadURI(); +			} +		} +	} +	else if(initializeMedia(mMimeType)) +	{ +		loadURI(); +	} +	else +	{ +		LL_WARNS("Media") << "Couldn't navigate to: " << mMediaURL << " as there is no media type for: " << mMimeType << LL_ENDL; +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::navigateStop() +{ +	if(mMediaSource) +	{ +		mMediaSource->browse_stop(); +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask) +{ +	bool result = false; +	 +	if (mMediaSource) +	{ +		// FIXME: THIS IS SO WRONG. +		// Menu keys should be handled by the menu system and not passed to UI elements, but this is how LLTextEditor and LLLineEditor do it... +		if( MASK_CONTROL & mask ) +		{ +			result = true; +		} +		 +		if(!result) +		{ +			 +			LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData(); +			 +			result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN ,key, mask, native_key_data); +			// Since the viewer internal event dispatching doesn't give us key-up events, simulate one here. +			(void)mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_UP ,key, mask, native_key_data); +		} +	} +	 +	return result; +} + +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char) +{ +	bool result = false; +	 +	if (mMediaSource) +	{ +		// only accept 'printable' characters, sigh... +		if (uni_char >= 32 // discard 'control' characters +			&& uni_char != 127) // SDL thinks this is 'delete' - yuck. +		{ +			LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData(); +			 +			mMediaSource->textInput(wstring_to_utf8str(LLWString(1, uni_char)), gKeyboard->currentMask(FALSE), native_key_data); +		} +	} +	 +	return result; +} + +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::canNavigateForward() +{ +	BOOL result = FALSE; +	if (mMediaSource) +	{ +		result = mMediaSource->getHistoryForwardAvailable(); +	} +	return result; +} + +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::canNavigateBack() +{ +	BOOL result = FALSE; +	if (mMediaSource) +	{ +		result = mMediaSource->getHistoryBackAvailable(); +	} +	return result; +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::update() +{ +	if(mMediaSource == NULL) +	{ +		if(mPriority == LLPluginClassMedia::PRIORITY_UNLOADED) +		{ +			// This media source should not be loaded. +		} +		else if(mPriority <= LLPluginClassMedia::PRIORITY_SLIDESHOW) +		{ +			// Don't load new instances that are at PRIORITY_SLIDESHOW or below.  They're just kept around to preserve state. +		} +		else if(mMimeTypeProbe != NULL) +		{ +			// this media source is doing a MIME type probe -- don't try loading it again. +		} +		else +		{ +			// This media may need to be loaded. +			if(sMediaCreateTimer.hasExpired()) +			{ +				LL_DEBUGS("PluginPriority") << this << ": creating media based on timer expiration" << LL_ENDL; +				createMediaSource(); +				sMediaCreateTimer.setTimerExpirySec(LLVIEWERMEDIA_CREATE_DELAY); +			} +			else +			{ +				LL_DEBUGS("PluginPriority") << this << ": NOT creating media (waiting on timer)" << LL_ENDL; +			} +		} +	} +	else +	{ +		updateVolume(); + +		// TODO: this is updated every frame - is this bad? +		updateJavascriptObject(); + +		// If we didn't just create the impl, it may need to get cookie updates. +		if(!sUpdatedCookies.empty()) +		{ +			// TODO: Only send cookies to plugins that need them +			mMediaSource->set_cookies(sUpdatedCookies); +		} +	} + +	 +	if(mMediaSource == NULL) +	{ +		return; +	} +	 +	// Make sure a navigate doesn't happen during the idle -- it can cause mMediaSource to get destroyed, which can cause a crash. +	setNavigateSuspended(true); +	 +	mMediaSource->idle(); + +	setNavigateSuspended(false); + +	if(mMediaSource == NULL) +	{ +		return; +	} +	 +	if(mMediaSource->isPluginExited()) +	{ +		resetPreviousMediaState(); +		destroyMediaSource(); +		return; +	} + +	if(!mMediaSource->textureValid()) +	{ +		return; +	} +	 +	if(mSuspendUpdates || !mVisible) +	{ +		return; +	} +	 +	LLViewerMediaTexture* placeholder_image = updatePlaceholderImage(); +		 +	if(placeholder_image) +	{ +		LLRect dirty_rect; +		 +		// Since we're updating this texture, we know it's playing.  Tell the texture to do its replacement magic so it gets rendered. +		placeholder_image->setPlaying(TRUE); + +		if(mMediaSource->getDirty(&dirty_rect)) +		{ +			// Constrain the dirty rect to be inside the texture +			S32 x_pos = llmax(dirty_rect.mLeft, 0); +			S32 y_pos = llmax(dirty_rect.mBottom, 0); +			S32 width = llmin(dirty_rect.mRight, placeholder_image->getWidth()) - x_pos; +			S32 height = llmin(dirty_rect.mTop, placeholder_image->getHeight()) - y_pos; +			 +			if(width > 0 && height > 0) +			{ + +				U8* data = mMediaSource->getBitsData(); + +				// Offset the pixels pointer to match x_pos and y_pos +				data += ( x_pos * mMediaSource->getTextureDepth() * mMediaSource->getBitsWidth() ); +				data += ( y_pos * mMediaSource->getTextureDepth() ); +				 +				placeholder_image->setSubImage( +						data,  +						mMediaSource->getBitsWidth(),  +						mMediaSource->getBitsHeight(), +						x_pos,  +						y_pos,  +						width,  +						height); + +			} +			 +			mMediaSource->resetDirty(); +		} +	} +} + + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::updateImagesMediaStreams() +{ +} + + +////////////////////////////////////////////////////////////////////////////////////////// +LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage() +{ +	if(mTextureId.isNull()) +	{ +		// The code that created this instance will read from the plugin's bits. +		return NULL; +	} +	 +	LLViewerMediaTexture* placeholder_image = LLViewerTextureManager::getMediaTexture( mTextureId ); +	 +	if (mNeedsNewTexture  +		|| placeholder_image->getUseMipMaps() +		|| (placeholder_image->getWidth() != mMediaSource->getTextureWidth()) +		|| (placeholder_image->getHeight() != mMediaSource->getTextureHeight()) +		|| (mTextureUsedWidth != mMediaSource->getWidth()) +		|| (mTextureUsedHeight != mMediaSource->getHeight()) +		) +	{ +		LL_DEBUGS("Media") << "initializing media placeholder" << LL_ENDL; +		LL_DEBUGS("Media") << "movie image id " << mTextureId << LL_ENDL; + +		int texture_width = mMediaSource->getTextureWidth(); +		int texture_height = mMediaSource->getTextureHeight(); +		int texture_depth = mMediaSource->getTextureDepth(); +		 +		// MEDIAOPT: check to see if size actually changed before doing work +		placeholder_image->destroyGLTexture(); +		// MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work? +		placeholder_image->reinit(FALSE);	// probably not needed + +		// MEDIAOPT: seems insane that we actually have to make an imageraw then +		// immediately discard it +		LLPointer<LLImageRaw> raw = new LLImageRaw(texture_width, texture_height, texture_depth); +		// Clear the texture to the background color, ignoring alpha. +		// convert background color channels from [0.0, 1.0] to [0, 255]; +		raw->clear(int(mBackgroundColor.mV[VX] * 255.0f), int(mBackgroundColor.mV[VY] * 255.0f), int(mBackgroundColor.mV[VZ] * 255.0f), 0xff); +		int discard_level = 0; + +		// ask media source for correct GL image format constants +		placeholder_image->setExplicitFormat(mMediaSource->getTextureFormatInternal(), +											 mMediaSource->getTextureFormatPrimary(), +											 mMediaSource->getTextureFormatType(), +											 mMediaSource->getTextureFormatSwapBytes()); + +		placeholder_image->createGLTexture(discard_level, raw); + +		// MEDIAOPT: set this dynamically on play/stop +		// FIXME +//		placeholder_image->mIsMediaTexture = true; +		mNeedsNewTexture = false; +				 +		// If the amount of the texture being drawn by the media goes down in either width or height,  +		// recreate the texture to avoid leaving parts of the old image behind. +		mTextureUsedWidth = mMediaSource->getWidth(); +		mTextureUsedHeight = mMediaSource->getHeight(); +	} +	 +	return placeholder_image; +} + + +////////////////////////////////////////////////////////////////////////////////////////// +LLUUID LLViewerMediaImpl::getMediaTextureID() const +{ +	return mTextureId; +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::setVisible(bool visible) +{ +	mVisible = visible; +	 +	if(mVisible) +	{ +		if(mMediaSource && mMediaSource->isPluginExited()) +		{ +			destroyMediaSource(); +		} +		 +		if(!mMediaSource) +		{ +			createMediaSource(); +		} +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::mouseCapture() +{ +	gFocusMgr.setMouseCapture(this); +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::scaleMouse(S32 *mouse_x, S32 *mouse_y) +{ +#if 0 +	S32 media_width, media_height; +	S32 texture_width, texture_height; +	getMediaSize( &media_width, &media_height ); +	getTextureSize( &texture_width, &texture_height ); +	S32 y_delta = texture_height - media_height; + +	*mouse_y -= y_delta; +#endif +} + + + +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::isMediaTimeBased() +{ +	bool result = false; +	 +	if(mMediaSource) +	{ +		result = mMediaSource->pluginSupportsMediaTime(); +	} +	 +	return result; +} + +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::isMediaPlaying() +{ +	bool result = false; +	 +	if(mMediaSource) +	{ +		EMediaStatus status = mMediaSource->getStatus(); +		if(status == MEDIA_PLAYING || status == MEDIA_LOADING) +			result = true; +	} +	 +	return result; +} +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::isMediaPaused() +{ +	bool result = false; + +	if(mMediaSource) +	{ +		if(mMediaSource->getStatus() == MEDIA_PAUSED) +			result = true; +	} +	 +	return result; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaImpl::hasMedia() const +{ +	return mMediaSource != NULL; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +void LLViewerMediaImpl::resetPreviousMediaState() +{ +	mPreviousMediaState = MEDIA_NONE; +	mPreviousMediaTime = 0.0f; +} + + +////////////////////////////////////////////////////////////////////////////////////////// +// +void LLViewerMediaImpl::setDisabled(bool disabled, bool forcePlayOnEnable) +{ +	if(mIsDisabled != disabled) +	{ +		// Only do this on actual state transitions. +		mIsDisabled = disabled; +		 +		if(mIsDisabled) +		{ +			// We just disabled this media.  Clear all state. +			unload(); +		} +		else +		{ +			// We just (re)enabled this media.  Do a navigate if auto-play is in order. +			if(isAutoPlayable() || forcePlayOnEnable) +			{ +				navigateTo(mMediaEntryURL, "", true, true); +			} +		} + +	} +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaImpl::isForcedUnloaded() const +{ +	if(mIsMuted || mMediaSourceFailed || mIsDisabled) +	{ +		return true; +	} +	 +	if(sInWorldMediaDisabled) +	{ +		// When inworld media is disabled, all instances that aren't marked as "used in UI" will not be loaded. +		if(!mUsedInUI) +		{ +			return true; +		} +	} +	 +	// If this media's class is not supposed to be shown, unload +	if (!shouldShowBasedOnClass()) +	{ +		return true; +	} +	 +	return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaImpl::isPlayable() const +{ +	if(isForcedUnloaded()) +	{ +		// All of the forced-unloaded criteria also imply not playable. +		return false; +	} +	 +	if(hasMedia()) +	{ +		// Anything that's already playing is, by definition, playable. +		return true; +	} +	 +	if(!mMediaURL.empty()) +	{ +		// If something has navigated the instance, it's ready to be played. +		return true; +	} +	 +	return false; +} + +////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent event) +{ +	bool pass_through = true; +	switch(event) +	{ +		case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: +		{ +			LL_DEBUGS("Media") << "MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is: " << plugin->getClickURL() << LL_ENDL;  +			std::string url = plugin->getClickURL(); +			std::string nav_type = plugin->getClickNavType(); +			LLURLDispatcher::dispatch(url, nav_type, NULL, mTrustedBrowser); +		} +		break; +		case MEDIA_EVENT_CLICK_LINK_HREF: +		{ +			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << plugin->getClickTarget() << "\", uri is " << plugin->getClickURL() << LL_ENDL; +		}; +		break; +		case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: +		{ +			// The plugin failed to load properly.  Make sure the timer doesn't retry. +			// TODO: maybe mark this plugin as not loadable somehow? +			mMediaSourceFailed = true; + +			// Reset the last known state of the media to defaults. +			resetPreviousMediaState(); +			 +			// TODO: may want a different message for this case? +			LLSD args; +			args["PLUGIN"] = LLMIMETypes::implType(mCurrentMimeType); +			LLNotificationsUtil::add("MediaPluginFailed", args); +		} +		break; + +		case MEDIA_EVENT_PLUGIN_FAILED: +		{ +			// The plugin crashed. +			mMediaSourceFailed = true; + +			// Reset the last known state of the media to defaults. +			resetPreviousMediaState(); + +			LLSD args; +			args["PLUGIN"] = LLMIMETypes::implType(mCurrentMimeType); +			// SJB: This is getting called every frame if the plugin fails to load, continuously respawining the alert! +			//LLNotificationsUtil::add("MediaPluginFailed", args); +		} +		break; +		 +		case MEDIA_EVENT_CURSOR_CHANGED: +		{ +			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << plugin->getCursorName() << LL_ENDL; + +			std::string cursor = plugin->getCursorName(); +			 +			if(cursor == "arrow") +				mLastSetCursor = UI_CURSOR_ARROW; +			else if(cursor == "ibeam") +				mLastSetCursor = UI_CURSOR_IBEAM; +			else if(cursor == "splith") +				mLastSetCursor = UI_CURSOR_SIZEWE; +			else if(cursor == "splitv") +				mLastSetCursor = UI_CURSOR_SIZENS; +			else if(cursor == "hand") +				mLastSetCursor = UI_CURSOR_HAND; +			else // for anything else, default to the arrow +				mLastSetCursor = UI_CURSOR_ARROW; +		} +		break; + +		case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_BEGIN: +		{ +			LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_BEGIN, uri is: " << plugin->getNavigateURI() << LL_ENDL; +			hideNotification(); + +			if(getNavState() == MEDIANAVSTATE_SERVER_SENT) +			{ +				setNavState(MEDIANAVSTATE_SERVER_BEGUN); +			} +			else +			{ +				setNavState(MEDIANAVSTATE_BEGUN); +			} +		} +		break; + +		case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_COMPLETE: +		{ +			LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_COMPLETE, uri is: " << plugin->getNavigateURI() << LL_ENDL; + +			std::string url = plugin->getNavigateURI(); +			if(getNavState() == MEDIANAVSTATE_BEGUN) +			{ +				if(mCurrentMediaURL == url) +				{ +					// This is a navigate that takes us to the same url as the previous navigate. +					setNavState(MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED_SPURIOUS); +				} +				else +				{ +					mCurrentMediaURL = url; +					setNavState(MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED); +				} +			} +			else if(getNavState() == MEDIANAVSTATE_SERVER_BEGUN) +			{ +				mCurrentMediaURL = url; +				setNavState(MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED); +			} +			else +			{ +				// all other cases need to leave the state alone. +			} +		} +		break; +		 +		case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED: +		{ +			LL_DEBUGS("Media") << "MEDIA_EVENT_LOCATION_CHANGED, uri is: " << plugin->getLocation() << LL_ENDL; + +			std::string url = plugin->getLocation(); + +			if(getNavState() == MEDIANAVSTATE_BEGUN) +			{ +				if(mCurrentMediaURL == url) +				{ +					// This is a navigate that takes us to the same url as the previous navigate. +					setNavState(MEDIANAVSTATE_FIRST_LOCATION_CHANGED_SPURIOUS); +				} +				else +				{ +					mCurrentMediaURL = url; +					setNavState(MEDIANAVSTATE_FIRST_LOCATION_CHANGED); +				} +			} +			else if(getNavState() == MEDIANAVSTATE_SERVER_BEGUN) +			{ +				mCurrentMediaURL = url; +				setNavState(MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED); +			} +			else +			{ +				// Don't track redirects. +				setNavState(MEDIANAVSTATE_NONE); +			} +		} +		break; + +		case LLViewerMediaObserver::MEDIA_EVENT_PICK_FILE_REQUEST: +		{ +			// Display a file picker +			std::string response; +			 +			LLFilePicker& picker = LLFilePicker::instance(); +			if (!picker.getOpenFile(LLFilePicker::FFLOAD_ALL)) +			{ +				// The user didn't pick a file -- the empty response string will indicate this. +			} +			 +			response = picker.getFirstFile(); +			 +			plugin->sendPickFileResponse(response); +		} +		break; + + +		case LLViewerMediaObserver::MEDIA_EVENT_AUTH_REQUEST: +		{ +			LLNotification::Params auth_request_params; +			auth_request_params.name = "AuthRequest"; + +			// pass in host name and realm for site (may be zero length but will always exist) +			LLSD args; +			LLURL raw_url( plugin->getAuthURL().c_str() ); +			args["HOST_NAME"] = raw_url.getAuthority(); +			args["REALM"] = plugin->getAuthRealm(); +			auth_request_params.substitutions = args; + +			auth_request_params.payload = LLSD().with("media_id", mTextureId); +			auth_request_params.functor.function = boost::bind(&LLViewerMedia::onAuthSubmit, _1, _2); +			LLNotifications::instance().add(auth_request_params); +		}; +		break; + +		case LLViewerMediaObserver::MEDIA_EVENT_CLOSE_REQUEST: +		{ +			std::string uuid = plugin->getClickUUID(); + +			llinfos << "MEDIA_EVENT_CLOSE_REQUEST for uuid " << uuid << llendl; + +			if(uuid.empty()) +			{ +				// This close request is directed at this instance, let it fall through. +			} +			else +			{ +				// This close request is directed at another instance +				pass_through = false; +				LLFloaterMediaBrowser::closeRequest(uuid); +				LLFloaterWebContent::closeRequest(uuid); +			} +		} +		break; + +		case LLViewerMediaObserver::MEDIA_EVENT_GEOMETRY_CHANGE: +		{ +			std::string uuid = plugin->getClickUUID(); + +			llinfos << "MEDIA_EVENT_GEOMETRY_CHANGE for uuid " << uuid << llendl; + +			if(uuid.empty()) +			{ +				// This geometry change request is directed at this instance, let it fall through. +			} +			else +			{ +				// This request is directed at another instance +				pass_through = false; +				LLFloaterMediaBrowser::geometryChanged(uuid, plugin->getGeometryX(), plugin->getGeometryY(), plugin->getGeometryWidth(), plugin->getGeometryHeight()); +				LLFloaterWebContent::geometryChanged(uuid, plugin->getGeometryX(), plugin->getGeometryY(), plugin->getGeometryWidth(), plugin->getGeometryHeight()); +			} +		} +		break; + +		default: +		break; +	} + +	if(pass_through) +	{ +		// Just chain the event to observers. +		emitEvent(plugin, event); +	} +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void LLViewerMediaImpl::handleCookieSet(LLPluginClassMedia* self, const std::string &cookie) +{ +	LLViewerMedia::getCookieStore()->setCookies(cookie); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void +LLViewerMediaImpl::cut() +{ +	if (mMediaSource) +		mMediaSource->cut(); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +BOOL +LLViewerMediaImpl::canCut() const +{ +	if (mMediaSource) +		return mMediaSource->canCut(); +	else +		return FALSE; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void +LLViewerMediaImpl::copy() +{ +	if (mMediaSource) +		mMediaSource->copy(); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +BOOL +LLViewerMediaImpl::canCopy() const +{ +	if (mMediaSource) +		return mMediaSource->canCopy(); +	else +		return FALSE; +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +void +LLViewerMediaImpl::paste() +{ +	if (mMediaSource) +		mMediaSource->paste(); +} + +//////////////////////////////////////////////////////////////////////////////// +// virtual +BOOL +LLViewerMediaImpl::canPaste() const +{ +	if (mMediaSource) +		return mMediaSource->canPaste(); +	else +		return FALSE; +} + +void LLViewerMediaImpl::setUpdated(BOOL updated) +{ +	mIsUpdated = updated ; +} + +BOOL LLViewerMediaImpl::isUpdated() +{ +	return mIsUpdated ; +} + +void LLViewerMediaImpl::calculateInterest() +{ +	LLViewerMediaTexture* texture = LLViewerTextureManager::findMediaTexture( mTextureId ); +	 +	if(texture != NULL) +	{ +		mInterest = texture->getMaxVirtualSize(); +	} +	else +	{ +		// This will be a relatively common case now, since it will always be true for unloaded media. +		mInterest = 0.0f; +	} +	 +	// Calculate distance from the avatar, for use in the proximity calculation. +	mProximityDistance = 0.0f; +	mProximityCamera = 0.0f; +	if(!mObjectList.empty()) +	{ +		// Just use the first object in the list.  We could go through the list and find the closest object, but this should work well enough. +		std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ; +		LLVOVolume* objp = *iter ; +		llassert_always(objp != NULL) ; +		 +		// The distance calculation is invalid for HUD attachments -- leave both mProximityDistance and mProximityCamera at 0 for them. +		if(!objp->isHUDAttachment()) +		{ +			LLVector3d obj_global = objp->getPositionGlobal() ; +			LLVector3d agent_global = gAgent.getPositionGlobal() ; +			LLVector3d global_delta = agent_global - obj_global ; +			mProximityDistance = global_delta.magVecSquared();  // use distance-squared because it's cheaper and sorts the same. + +			LLVector3d camera_delta = gAgentCamera.getCameraPositionGlobal() - obj_global; +			mProximityCamera = camera_delta.magVec(); +		} +	} +	 +	if(mNeedsMuteCheck) +	{ +		// Check all objects this instance is associated with, and those objects' owners, against the mute list +		mIsMuted = false; +		 +		std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ; +		for(; iter != mObjectList.end() ; ++iter) +		{ +			LLVOVolume *obj = *iter; +			llassert(obj); +			if (!obj) continue; +			if(LLMuteList::getInstance() && +			   LLMuteList::getInstance()->isMuted(obj->getID())) +			{ +				mIsMuted = true; +			} +			else +			{ +				// We won't have full permissions data for all objects.  Attempt to mute objects when we can tell their owners are muted. +				if (LLSelectMgr::getInstance()) +				{ +					LLPermissions* obj_perm = LLSelectMgr::getInstance()->findObjectPermissions(obj); +					if(obj_perm) +					{ +						if(LLMuteList::getInstance() && +						   LLMuteList::getInstance()->isMuted(obj_perm->getOwner())) +							mIsMuted = true; +					} +				} +			} +		} +		 +		mNeedsMuteCheck = false; +	} +} + +F64 LLViewerMediaImpl::getApproximateTextureInterest() +{ +	F64 result = 0.0f; +	 +	if(mMediaSource) +	{ +		result = mMediaSource->getFullWidth(); +		result *= mMediaSource->getFullHeight(); +	} +	else +	{ +		// No media source is loaded -- all we have to go on is the texture size that has been set on the impl, if any. +		result = mMediaWidth; +		result *= mMediaHeight; +	} + +	return result; +} + +void LLViewerMediaImpl::setUsedInUI(bool used_in_ui) +{ +	mUsedInUI = used_in_ui;  +	 +	// HACK: Force elements used in UI to load right away. +	// This fixes some issues where UI code that uses the browser instance doesn't expect it to be unloaded. +	if(mUsedInUI && (mPriority == LLPluginClassMedia::PRIORITY_UNLOADED)) +	{ +		if(getVisible()) +		{ +			setPriority(LLPluginClassMedia::PRIORITY_NORMAL); +		} +		else +		{ +			setPriority(LLPluginClassMedia::PRIORITY_HIDDEN); +		} + +		createMediaSource(); +	} +}; + +void LLViewerMediaImpl::setBackgroundColor(LLColor4 color) +{ +	mBackgroundColor = color;  + +	if(mMediaSource) +	{ +		mMediaSource->setBackgroundColor(mBackgroundColor); +	} +}; + +F64 LLViewerMediaImpl::getCPUUsage() const +{ +	F64 result = 0.0f; +	 +	if(mMediaSource) +	{ +		result = mMediaSource->getCPUUsage(); +	} +	 +	return result; +} + +void LLViewerMediaImpl::setPriority(LLPluginClassMedia::EPriority priority) +{ +	if(mPriority != priority) +	{ +		LL_DEBUGS("PluginPriority") +			<< "changing priority of media id " << mTextureId +			<< " from " << LLPluginClassMedia::priorityToString(mPriority) +			<< " to " << LLPluginClassMedia::priorityToString(priority) +			<< LL_ENDL; +	} +	 +	mPriority = priority; +	 +	if(priority == LLPluginClassMedia::PRIORITY_UNLOADED) +	{ +		if(mMediaSource) +		{ +			// Need to unload the media source +			 +			// First, save off previous media state +			mPreviousMediaState = mMediaSource->getStatus(); +			mPreviousMediaTime = mMediaSource->getCurrentTime(); +			 +			destroyMediaSource(); +		} +	} + +	if(mMediaSource) +	{ +		mMediaSource->setPriority(mPriority); +	} +	 +	// NOTE: loading (or reloading) media sources whose priority has risen above PRIORITY_UNLOADED is done in update(). +} + +void LLViewerMediaImpl::setLowPrioritySizeLimit(int size) +{ +	if(mMediaSource) +	{ +		mMediaSource->setLowPrioritySizeLimit(size); +	} +} + +void LLViewerMediaImpl::setNavState(EMediaNavState state) +{ +	mMediaNavState = state; +	 +	switch (state)  +	{ +		case MEDIANAVSTATE_NONE: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_NONE" << llendl; break; +		case MEDIANAVSTATE_BEGUN: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_BEGUN" << llendl; break; +		case MEDIANAVSTATE_FIRST_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_FIRST_LOCATION_CHANGED" << llendl; break; +		case MEDIANAVSTATE_FIRST_LOCATION_CHANGED_SPURIOUS: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_FIRST_LOCATION_CHANGED_SPURIOUS" << llendl; break; +		case MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED" << llendl; break; +		case MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED_SPURIOUS: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_COMPLETE_BEFORE_LOCATION_CHANGED_SPURIOUS" << llendl; break; +		case MEDIANAVSTATE_SERVER_SENT: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_SENT" << llendl; break; +		case MEDIANAVSTATE_SERVER_BEGUN: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_BEGUN" << llendl; break; +		case MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED" << llendl; break; +		case MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_SERVER_COMPLETE_BEFORE_LOCATION_CHANGED" << llendl; break; +	} +} + +void LLViewerMediaImpl::setNavigateSuspended(bool suspend) +{ +	if(mNavigateSuspended != suspend) +	{ +		mNavigateSuspended = suspend; +		if(!suspend) +		{ +			// We're coming out of suspend.  If someone tried to do a navigate while suspended, do one now instead. +			if(mNavigateSuspendedDeferred) +			{ +				mNavigateSuspendedDeferred = false; +				navigateInternal(); +			} +		} +	} +} + +void LLViewerMediaImpl::cancelMimeTypeProbe() +{ +	if(mMimeTypeProbe != NULL) +	{ +		// There doesn't seem to be a way to actually cancel an outstanding request. +		// Simulate it by telling the LLMimeDiscoveryResponder not to write back any results. +		mMimeTypeProbe->cancelRequest(); +		 +		// The above should already have set mMimeTypeProbe to NULL. +		if(mMimeTypeProbe != NULL) +		{ +			llerrs << "internal error: mMimeTypeProbe is not NULL after cancelling request." << llendl; +		} +	} +} + +void LLViewerMediaImpl::addObject(LLVOVolume* obj)  +{ +	std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ; +	for(; iter != mObjectList.end() ; ++iter) +	{ +		if(*iter == obj) +		{ +			return ; //already in the list. +		} +	} + +	mObjectList.push_back(obj) ; +	mNeedsMuteCheck = true; +} +	 +void LLViewerMediaImpl::removeObject(LLVOVolume* obj)  +{ +	mObjectList.remove(obj) ;	 +	mNeedsMuteCheck = true; +} +	 +const std::list< LLVOVolume* >* LLViewerMediaImpl::getObjectList() const  +{ +	return &mObjectList ; +} + +LLVOVolume *LLViewerMediaImpl::getSomeObject() +{ +	LLVOVolume *result = NULL; +	 +	std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ; +	if(iter != mObjectList.end()) +	{ +		result = *iter; +	} +	 +	return result; +} + +void LLViewerMediaImpl::setTextureID(LLUUID id) +{ +	if(id != mTextureId) +	{ +		if(mTextureId.notNull()) +		{ +			// Remove this item's entry from the map +			sViewerMediaTextureIDMap.erase(mTextureId); +		} +		 +		if(id.notNull()) +		{ +			sViewerMediaTextureIDMap.insert(LLViewerMedia::impl_id_map::value_type(id, this)); +		} +		 +		mTextureId = id; +	} +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaImpl::isAutoPlayable() const +{ +	return (mMediaAutoPlay &&  +			gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) && +			gSavedSettings.getBOOL("MediaTentativeAutoPlay")); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaImpl::shouldShowBasedOnClass() const +{ +	// If this is parcel media or in the UI, return true always +	if (getUsedInUI() || isParcelMedia()) return true; +	 +	bool attached_to_another_avatar = isAttachedToAnotherAvatar(); +	bool inside_parcel = isInAgentParcel(); +	 +	//	llinfos << " hasFocus = " << hasFocus() << +	//	" others = " << (attached_to_another_avatar && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING)) << +	//	" within = " << (inside_parcel && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING)) << +	//	" outside = " << (!inside_parcel && gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING)) << llendl; +	 +	// If it has focus, we should show it +	// This is incorrect, and causes EXT-6750 (disabled attachment media still plays) +//	if (hasFocus()) +//		return true; +	 +	// If it is attached to an avatar and the pref is off, we shouldn't show it +	if (attached_to_another_avatar) +		return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_ON_OTHERS_SETTING); +	 +	if (inside_parcel) +		return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_WITHIN_PARCEL_SETTING); +	else  +		return gSavedSettings.getBOOL(LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING); +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const +{ +	bool result = false; +	 +	std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin(); +	std::list< LLVOVolume* >::const_iterator end = mObjectList.end(); +	for ( ; iter != end; iter++) +	{ +		if (isObjectAttachedToAnotherAvatar(*iter)) +		{ +			result = true; +			break; +		} +	} +	return result; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +//static +bool LLViewerMediaImpl::isObjectAttachedToAnotherAvatar(LLVOVolume *obj) +{ +	bool result = false; +	LLXform *xform = obj; +	// Walk up parent chain +	while (NULL != xform) +	{ +		LLViewerObject *object = dynamic_cast<LLViewerObject*> (xform); +		if (NULL != object) +		{ +			LLVOAvatar *avatar = object->asAvatar(); +			if ((NULL != avatar) && (avatar != gAgentAvatarp)) +			{ +				result = true; +				break; +			} +		} +		xform = xform->getParent(); +	} +	return result; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +bool LLViewerMediaImpl::isInAgentParcel() const +{ +	bool result = false; +	 +	std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin(); +	std::list< LLVOVolume* >::const_iterator end = mObjectList.end(); +	for ( ; iter != end; iter++) +	{ +		LLVOVolume *object = *iter; +		if (LLViewerMediaImpl::isObjectInAgentParcel(object)) +		{ +			result = true; +			break; +		} +	} +	return result; +} + +LLNotificationPtr LLViewerMediaImpl::getCurrentNotification() const +{ +	return mNotification; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// +// static +bool LLViewerMediaImpl::isObjectInAgentParcel(LLVOVolume *obj) +{ +	return (LLViewerParcelMgr::getInstance()->inAgentParcel(obj->getPositionGlobal())); +} diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index d958551a0a..b4ec3c135b 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -37,6 +37,7 @@  // newview includes  #include "llagent.h" +#include "llagentaccess.h"  #include "llagentcamera.h"  #include "llagentwearables.h"  #include "llagentpilot.h" diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index c84a14f62c..5ae4e872f3 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -42,6 +42,7 @@  // Viewer includes  #include "llagent.h" +#include "llagentaccess.h"  #include "llviewerwindow.h"  #include "llviewercontrol.h"  //#include "llfirstuse.h" @@ -54,6 +55,7 @@  #include "llresmgr.h"  #include "llsdutil.h"  #include "llsdutil_math.h" +#include "llslurl.h"  #include "llstatusbar.h"  #include "llui.h"  #include "llviewertexture.h" diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h index ab07adce5d..45c9b3e91f 100644 --- a/indra/newview/llviewerprecompiledheaders.h +++ b/indra/newview/llviewerprecompiledheaders.h @@ -99,8 +99,6 @@  #include "llcoord.h"  #include "llcoordframe.h"  #include "llcrc.h" -#include "llinterp.h" -#include "llperlin.h"  #include "llplane.h"  #include "llquantize.h"  #include "llrand.h" @@ -109,7 +107,6 @@  #include "m3math.h"  #include "m4math.h"  #include "llquaternion.h" -#include "raytrace.h"  #include "v2math.h"  #include "v3color.h"  #include "v3dmath.h" @@ -117,16 +114,12 @@  #include "v4color.h"  #include "v4coloru.h"  #include "v4math.h" -////#include "vmath.h"  #include "xform.h"  // Library includes from llvfs  #include "lldir.h" - -// Library includes from llmessage project +
 +// Library includes from llmessage project
  #include "llcachename.h" -// llxuixml -#include "llinitparam.h" -  #endif diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index c53fdc3393..8909abf36e 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -46,6 +46,7 @@  #include "llagentcamera.h"  #include "llcallingcard.h"  #include "llcaphttpsender.h" +#include "llcapabilitylistener.h"  #include "llcommandhandler.h"  #include "lldir.h"  #include "lleventpoll.h" @@ -76,6 +77,71 @@  const F32 WATER_TEXTURE_SCALE = 8.f;			//  Number of times to repeat the water texture across a region  const S16 MAX_MAP_DIST = 10; +typedef std::map<std::string, std::string> CapabilityMap; + +class LLViewerRegionImpl { +public: +	LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host) +		:	mHost(host), +			mCompositionp(NULL), +			mEventPoll(NULL), +		    // I'd prefer to set the LLCapabilityListener name to match the region +		    // name -- it's disappointing that's not available at construction time. +		    // We could instead store an LLCapabilityListener*, making +		    // setRegionNameAndZone() replace the instance. Would that pose +		    // consistency problems? Can we even request a capability before calling +		    // setRegionNameAndZone()? +		    // For testability -- the new Michael Feathers paradigm -- +		    // LLCapabilityListener binds all the globals it expects to need at +		    // construction time. +		    mCapabilityListener(host.getString(), gMessageSystem, *region, +		                        gAgent.getID(), gAgent.getSessionID()) +	{ +	} + +	// The surfaces and other layers +	LLSurface*	mLandp; + +	// Region geometry data +	LLVector3d	mOriginGlobal;	// Location of southwest corner of region (meters) +	LLVector3d	mCenterGlobal;	// Location of center in world space (meters) +	LLHost		mHost; + +	// The unique ID for this region. +	LLUUID mRegionID; + +	// region/estate owner - usually null. +	LLUUID mOwnerID; + +	// Network statistics for the region's circuit... +	LLTimer mLastNetUpdate; + +	// Misc +	LLVLComposition *mCompositionp;		// Composition layer for the surface + +	LLVOCacheEntry::vocache_entry_map_t		mCacheMap; +	// time? +	// LRU info? + +	// Cache ID is unique per-region, across renames, moving locations, +	// etc. +	LLUUID mCacheID; + +	CapabilityMap mCapabilities; +	 +	LLEventPoll* mEventPoll; + +	/// Post an event to this LLCapabilityListener to invoke a capability message on +	/// this LLViewerRegion's server +	/// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities) +	LLCapabilityListener mCapabilityListener; + +	//spatial partitions for objects in this region +	std::vector<LLSpatialPartition*> mObjectPartition; + +	LLHTTPClient::ResponderPtr  mHttpResponderPtr ; +}; +  // support for secondlife:///app/region/{REGION} SLapps  // N.B. this is defined to work exactly like the classic secondlife://{REGION}  // However, the later syntax cannot support spaces in the region name because @@ -191,15 +257,12 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,  							   const U32 grids_per_region_edge,   							   const U32 grids_per_patch_edge,   							   const F32 region_width_meters) -:	mCenterGlobal(), +:	mImpl(new LLViewerRegionImpl(this, host)),  	mHandle(handle), -	mHost( host ),  	mTimeDilation(1.0f),  	mName(""),  	mZoning(""), -	mOwnerID(),  	mIsEstateManager(FALSE), -	mCompositionp(NULL),  	mRegionFlags( REGION_FLAGS_DEFAULT ),  	mSimAccess( SIM_ACCESS_MIN ),  	mBillableFactor(1.0), @@ -212,37 +275,27 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,  	mHttpUrl(""),  	mCacheLoaded(FALSE),  	mCacheDirty(FALSE), -	mCacheID(), -	mEventPoll(NULL),  	mReleaseNotesRequested(FALSE), -    // I'd prefer to set the LLCapabilityListener name to match the region -    // name -- it's disappointing that's not available at construction time. -    // We could instead store an LLCapabilityListener*, making -    // setRegionNameAndZone() replace the instance. Would that pose -    // consistency problems? Can we even request a capability before calling -    // setRegionNameAndZone()? -    // For testability -- the new Michael Feathers paradigm -- -    // LLCapabilityListener binds all the globals it expects to need at -    // construction time. -    mCapabilityListener(host.getString(), gMessageSystem, *this, -                        gAgent.getID(), gAgent.getSessionID()),  	mCapabilitiesReceived(false)  {  	mWidth = region_width_meters; -	mOriginGlobal = from_region_handle(handle);  +	mImpl->mOriginGlobal = from_region_handle(handle);   	updateRenderMatrix(); -	mLandp = new LLSurface('l', NULL); +	mImpl->mLandp = new LLSurface('l', NULL);  	// Create the composition layer for the surface -	mCompositionp = new LLVLComposition(mLandp, grids_per_region_edge, region_width_meters/grids_per_region_edge); -	mCompositionp->setSurface(mLandp); +	mImpl->mCompositionp = +		new LLVLComposition(mImpl->mLandp, +							grids_per_region_edge, +							region_width_meters / grids_per_region_edge); +	mImpl->mCompositionp->setSurface(mImpl->mLandp);  	// Create the surfaces -	mLandp->setRegion(this); -	mLandp->create(grids_per_region_edge, +	mImpl->mLandp->setRegion(this); +	mImpl->mLandp->create(grids_per_region_edge,  					grids_per_patch_edge, -					mOriginGlobal, +					mImpl->mOriginGlobal,  					mWidth);  	mParcelOverlay = new LLViewerParcelOverlay(this, region_width_meters); @@ -255,24 +308,24 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,  	//create object partitions  	//MUST MATCH declaration of eObjectPartitions -	mObjectPartition.push_back(new LLHUDPartition());		//PARTITION_HUD -	mObjectPartition.push_back(new LLTerrainPartition());	//PARTITION_TERRAIN -	mObjectPartition.push_back(new LLVoidWaterPartition());	//PARTITION_VOIDWATER -	mObjectPartition.push_back(new LLWaterPartition());		//PARTITION_WATER -	mObjectPartition.push_back(new LLTreePartition());		//PARTITION_TREE -	mObjectPartition.push_back(new LLParticlePartition());	//PARTITION_PARTICLE -	mObjectPartition.push_back(new LLCloudPartition());		//PARTITION_CLOUD -	mObjectPartition.push_back(new LLGrassPartition());		//PARTITION_GRASS -	mObjectPartition.push_back(new LLVolumePartition());	//PARTITION_VOLUME -	mObjectPartition.push_back(new LLBridgePartition());	//PARTITION_BRIDGE -	mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE -	mObjectPartition.push_back(NULL);						//PARTITION_NONE +	mImpl->mObjectPartition.push_back(new LLHUDPartition());		//PARTITION_HUD +	mImpl->mObjectPartition.push_back(new LLTerrainPartition());	//PARTITION_TERRAIN +	mImpl->mObjectPartition.push_back(new LLVoidWaterPartition());	//PARTITION_VOIDWATER +	mImpl->mObjectPartition.push_back(new LLWaterPartition());		//PARTITION_WATER +	mImpl->mObjectPartition.push_back(new LLTreePartition());		//PARTITION_TREE +	mImpl->mObjectPartition.push_back(new LLParticlePartition());	//PARTITION_PARTICLE +	mImpl->mObjectPartition.push_back(new LLCloudPartition());		//PARTITION_CLOUD +	mImpl->mObjectPartition.push_back(new LLGrassPartition());		//PARTITION_GRASS +	mImpl->mObjectPartition.push_back(new LLVolumePartition());	//PARTITION_VOLUME +	mImpl->mObjectPartition.push_back(new LLBridgePartition());	//PARTITION_BRIDGE +	mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE +	mImpl->mObjectPartition.push_back(NULL);						//PARTITION_NONE  }  void LLViewerRegion::initStats()  { -	mLastNetUpdate.reset(); +	mImpl->mLastNetUpdate.reset();  	mPacketsIn = 0;  	mBitsIn = 0;  	mLastBitsIn = 0; @@ -287,9 +340,9 @@ void LLViewerRegion::initStats()  LLViewerRegion::~LLViewerRegion()   { -	if(mHttpResponderPtr) +	if(mImpl->mHttpResponderPtr)  	{ -		(static_cast<BaseCapabilitiesComplete*>(mHttpResponderPtr.get()))->setRegion(NULL) ; +		(static_cast<BaseCapabilitiesComplete*>(mImpl->mHttpResponderPtr.get()))->setRegion(NULL) ;  	}  	gVLManager.cleanupData(this); @@ -301,21 +354,44 @@ LLViewerRegion::~LLViewerRegion()  	gObjectList.killObjects(this); -	delete mCompositionp; +	delete mImpl->mCompositionp;  	delete mParcelOverlay; -	delete mLandp; -	delete mEventPoll; -	LLHTTPSender::clearSender(mHost); +	delete mImpl->mLandp; +	delete mImpl->mEventPoll; +	LLHTTPSender::clearSender(mImpl->mHost);  	saveObjectCache(); -	std::for_each(mObjectPartition.begin(), mObjectPartition.end(), DeletePointer()); +	std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer()); + +	delete mImpl; +	mImpl = NULL; +} + +LLEventPump& LLViewerRegion::getCapAPI() const +{ +	return mImpl->mCapabilityListener.getCapAPI();  }  /*virtual*/   const LLHost&	LLViewerRegion::getHost() const				  {  -	return mHost;  +	return mImpl->mHost;  +} + +LLSurface & LLViewerRegion::getLand() const +{ +	return *mImpl->mLandp; +} + +const LLUUID& LLViewerRegion::getRegionID() const +{ +	return mImpl->mRegionID; +} + +void LLViewerRegion::setRegionID(const LLUUID& region_id) +{ +	mImpl->mRegionID = region_id;  }  void LLViewerRegion::loadObjectCache() @@ -330,7 +406,7 @@ void LLViewerRegion::loadObjectCache()  	if(LLVOCache::hasInstance())  	{ -		LLVOCache::getInstance()->readFromCache(mHandle, mCacheID, mCacheMap) ; +		LLVOCache::getInstance()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ;  	}  } @@ -342,32 +418,32 @@ void LLViewerRegion::saveObjectCache()  		return;  	} -	if (mCacheMap.empty()) +	if (mImpl->mCacheMap.empty())  	{  		return;  	}  	if(LLVOCache::hasInstance())  	{ -		LLVOCache::getInstance()->writeToCache(mHandle, mCacheID, mCacheMap, mCacheDirty) ; +		LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty) ;  		mCacheDirty = FALSE;  	} -	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mCacheMap.begin(); iter != mCacheMap.end(); ++iter) +	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)  	{  		delete iter->second;  	} -	mCacheMap.clear(); +	mImpl->mCacheMap.clear();  }  void LLViewerRegion::sendMessage()  { -	gMessageSystem->sendMessage(mHost); +	gMessageSystem->sendMessage(mImpl->mHost);  }  void LLViewerRegion::sendReliableMessage()  { -	gMessageSystem->sendReliable(mHost); +	gMessageSystem->sendReliable(mImpl->mHost);  }  void LLViewerRegion::setFlags(BOOL b, U32 flags) @@ -384,12 +460,12 @@ void LLViewerRegion::setFlags(BOOL b, U32 flags)  void LLViewerRegion::setWaterHeight(F32 water_level)  { -	mLandp->setWaterHeight(water_level); +	mImpl->mLandp->setWaterHeight(water_level);  }  F32 LLViewerRegion::getWaterHeight() const  { -	return mLandp->getWaterHeight(); +	return mImpl->mLandp->getWaterHeight();  }  BOOL LLViewerRegion::isVoiceEnabled() const @@ -405,9 +481,9 @@ void LLViewerRegion::setRegionFlags(U32 flags)  void LLViewerRegion::setOriginGlobal(const LLVector3d &origin_global)   {  -	mOriginGlobal = origin_global;  +	mImpl->mOriginGlobal = origin_global;   	updateRenderMatrix(); -	mLandp->setOriginGlobal(origin_global); +	mImpl->mLandp->setOriginGlobal(origin_global);  	mWind.setOriginGlobal(origin_global);  	mCloudLayer.setOriginGlobal(origin_global);  	calculateCenterGlobal(); @@ -423,16 +499,34 @@ void LLViewerRegion::setTimeDilation(F32 time_dilation)  	mTimeDilation = time_dilation;  } +const LLVector3d & LLViewerRegion::getOriginGlobal() const +{ +	return mImpl->mOriginGlobal; +}  LLVector3 LLViewerRegion::getOriginAgent() const  { -	return gAgent.getPosAgentFromGlobal(mOriginGlobal); +	return gAgent.getPosAgentFromGlobal(mImpl->mOriginGlobal);  } +const LLVector3d & LLViewerRegion::getCenterGlobal() const +{ +	return mImpl->mCenterGlobal; +}  LLVector3 LLViewerRegion::getCenterAgent() const  { -	return gAgent.getPosAgentFromGlobal(mCenterGlobal); +	return gAgent.getPosAgentFromGlobal(mImpl->mCenterGlobal); +} + +void LLViewerRegion::setOwner(const LLUUID& owner_id) +{ +	mImpl->mOwnerID = owner_id; +} + +const LLUUID& LLViewerRegion::getOwner() const +{ +	return mImpl->mOwnerID;  }  void LLViewerRegion::setRegionNameAndZone	(const std::string& name_zone) @@ -557,7 +651,10 @@ void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**)  	LLFloaterReporter::processRegionInfo(msg);  } - +void LLViewerRegion::setCacheID(const LLUUID& id) +{ +	mImpl->mCacheID = id; +}  S32 LLViewerRegion::renderPropertyLines()  { @@ -585,7 +682,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)  {  	LLMemType mt_ivr(LLMemType::MTYPE_IDLE_UPDATE_VIEWER_REGION);  	// did_update returns TRUE if we did at least one significant update -	BOOL did_update = mLandp->idleUpdate(max_update_time); +	BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time);  	if (mParcelOverlay)  	{ @@ -600,7 +697,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)  // As above, but forcibly do the update.  void LLViewerRegion::forceUpdate()  { -	mLandp->idleUpdate(0.f); +	mImpl->mLandp->idleUpdate(0.f);  	if (mParcelOverlay)  	{ @@ -610,17 +707,21 @@ void LLViewerRegion::forceUpdate()  void LLViewerRegion::connectNeighbor(LLViewerRegion *neighborp, U32 direction)  { -	mLandp->connectNeighbor(neighborp->mLandp, direction); +	mImpl->mLandp->connectNeighbor(neighborp->mImpl->mLandp, direction);  	mCloudLayer.connectNeighbor(&(neighborp->mCloudLayer), direction);  }  void LLViewerRegion::disconnectAllNeighbors()  { -	mLandp->disconnectAllNeighbors(); +	mImpl->mLandp->disconnectAllNeighbors();  	mCloudLayer.disconnectAllNeighbors();  } +LLVLComposition * LLViewerRegion::getComposition() const +{ +	return mImpl->mCompositionp; +}  F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const  { @@ -714,10 +815,10 @@ F32 LLViewerRegion::getCompositionXY(const S32 x, const S32 y) const  void LLViewerRegion::calculateCenterGlobal()   { -	mCenterGlobal = mOriginGlobal; -	mCenterGlobal.mdV[VX] += 0.5 * mWidth; -	mCenterGlobal.mdV[VY] += 0.5 * mWidth; -	mCenterGlobal.mdV[VZ] = 0.5*mLandp->getMinZ() + mLandp->getMaxZ(); +	mImpl->mCenterGlobal = mImpl->mOriginGlobal; +	mImpl->mCenterGlobal.mdV[VX] += 0.5 * mWidth; +	mImpl->mCenterGlobal.mdV[VY] += 0.5 * mWidth; +	mImpl->mCenterGlobal.mdV[VZ] = 0.5 * mImpl->mLandp->getMinZ() + mImpl->mLandp->getMaxZ();  }  void LLViewerRegion::calculateCameraDistance() @@ -728,7 +829,7 @@ void LLViewerRegion::calculateCameraDistance()  std::ostream& operator<<(std::ostream &s, const LLViewerRegion ®ion)  {  	s << "{ "; -	s << region.mHost; +	s << region.mImpl->mHost;  	s << " mOriginGlobal = " << region.getOriginGlobal()<< "\n";      std::string name(region.getName()), zone(region.getZoning());      if (! name.empty()) @@ -748,9 +849,9 @@ std::ostream& operator<<(std::ostream &s, const LLViewerRegion ®ion)  void LLViewerRegion::updateNetStats()  { -	F32 dt = mLastNetUpdate.getElapsedTimeAndResetF32(); +	F32 dt = mImpl->mLastNetUpdate.getElapsedTimeAndResetF32(); -	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mHost); +	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);  	if (!cdp)  	{  		mAlive = false; @@ -779,10 +880,10 @@ void LLViewerRegion::updateNetStats()  U32 LLViewerRegion::getPacketsLost() const  { -	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mHost); +	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mImpl->mHost);  	if (!cdp)  	{ -		llinfos << "LLViewerRegion::getPacketsLost couldn't find circuit for " << mHost << llendl; +		llinfos << "LLViewerRegion::getPacketsLost couldn't find circuit for " << mImpl->mHost << llendl;  		return 0;  	}  	else @@ -791,6 +892,16 @@ U32 LLViewerRegion::getPacketsLost() const  	}  } +void LLViewerRegion::setHttpResponderPtrNULL() +{ +	mImpl->mHttpResponderPtr = NULL; +} + +const LLHTTPClient::ResponderPtr LLViewerRegion::getHttpResponderPtr() const +{ +	return mImpl->mHttpResponderPtr; +} +  BOOL LLViewerRegion::pointInRegionGlobal(const LLVector3d &point_global) const  {  	LLVector3 pos_region = getPosRegionFromGlobal(point_global); @@ -817,7 +928,7 @@ BOOL LLViewerRegion::pointInRegionGlobal(const LLVector3d &point_global) const  LLVector3 LLViewerRegion::getPosRegionFromGlobal(const LLVector3d &point_global) const  {  	LLVector3 pos_region; -	pos_region.setVec(point_global - mOriginGlobal); +	pos_region.setVec(point_global - mImpl->mOriginGlobal);  	return pos_region;  } @@ -825,7 +936,7 @@ LLVector3d LLViewerRegion::getPosGlobalFromRegion(const LLVector3 &pos_region) c  {  	LLVector3d pos_region_d;  	pos_region_d.setVec(pos_region); -	return pos_region_d + mOriginGlobal; +	return pos_region_d + mImpl->mOriginGlobal;  }  LLVector3 LLViewerRegion::getPosAgentFromRegion(const LLVector3 &pos_region) const @@ -842,7 +953,7 @@ LLVector3 LLViewerRegion::getPosRegionFromAgent(const LLVector3 &pos_agent) cons  F32 LLViewerRegion::getLandHeightRegion(const LLVector3& region_pos)  { -	return mLandp->resolveHeightRegion( region_pos ); +	return mImpl->mLandp->resolveHeightRegion( region_pos );  }  bool LLViewerRegion::isAlive() @@ -994,7 +1105,7 @@ void LLViewerRegion::updateCoarseLocations(LLMessageSystem* msg)  		// treat the target specially for the map  		if(i == target_index)  		{ -			LLVector3d global_pos(mOriginGlobal); +			LLVector3d global_pos(mImpl->mOriginGlobal);  			global_pos.mdV[VX] += (F64)(x_pos);  			global_pos.mdV[VY] += (F64)(y_pos);  			global_pos.mdV[VZ] += (F64)(z_pos) * 4.0; @@ -1034,7 +1145,7 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec  	U32 local_id = objectp->getLocalID();  	U32 crc = objectp->getCRC(); -	LLVOCacheEntry* entry = get_if_there(mCacheMap, local_id, (LLVOCacheEntry*)NULL); +	LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);  	if (entry)  	{ @@ -1047,10 +1158,10 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec  		}  		// Update the cache entry -		mCacheMap.erase(local_id); +		mImpl->mCacheMap.erase(local_id);  		delete entry;  		entry = new LLVOCacheEntry(local_id, crc, dp); -		mCacheMap[local_id] = entry; +		mImpl->mCacheMap[local_id] = entry;  		return CACHE_UPDATE_CHANGED;  	} @@ -1058,15 +1169,15 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec  	// Create new entry and add to map  	eCacheUpdateResult result = CACHE_UPDATE_ADDED; -	if (mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) +	if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES)  	{ -		mCacheMap.erase(mCacheMap.begin()); +		mImpl->mCacheMap.erase(mImpl->mCacheMap.begin());  		result = CACHE_UPDATE_REPLACED;  	}  	entry = new LLVOCacheEntry(local_id, crc, dp); -	mCacheMap[local_id] = entry; +	mImpl->mCacheMap[local_id] = entry;  	return result;  } @@ -1076,7 +1187,7 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type)  {  	llassert(mCacheLoaded); -	LLVOCacheEntry* entry = get_if_there(mCacheMap, local_id, (LLVOCacheEntry*)NULL); +	LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL);  	if (entry)  	{ @@ -1203,7 +1314,7 @@ void LLViewerRegion::dumpCache()  	}  	LLVOCacheEntry *entry; -	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mCacheMap.begin(); iter != mCacheMap.end(); ++iter) +	for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter)  	{  		entry = iter->second ; @@ -1217,7 +1328,7 @@ void LLViewerRegion::dumpCache()  		change_bin[changes]++;  	} -	llinfos << "Count " << mCacheMap.size() << llendl; +	llinfos << "Count " << mImpl->mCacheMap.size() << llendl;  	for (i = 0; i < BINS; i++)  	{  		llinfos << "Hits " << i << " " << hit_bin[i] << llendl; @@ -1360,10 +1471,10 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  		return;      } -	delete mEventPoll; -	mEventPoll = NULL; +	delete mImpl->mEventPoll; +	mImpl->mEventPoll = NULL; -	mCapabilities.clear(); +	mImpl->mCapabilities.clear();  	setCapability("Seed", url);  	LLSD capabilityNames = LLSD::emptyArray(); @@ -1430,25 +1541,25 @@ void LLViewerRegion::setSeedCapability(const std::string& url)  	llinfos << "posting to seed " << url << llendl; -	mHttpResponderPtr = BaseCapabilitiesComplete::build(this) ; -	LLHTTPClient::post(url, capabilityNames, mHttpResponderPtr); +	mImpl->mHttpResponderPtr = BaseCapabilitiesComplete::build(this) ; +	LLHTTPClient::post(url, capabilityNames, mImpl->mHttpResponderPtr);  }  void LLViewerRegion::setCapability(const std::string& name, const std::string& url)  {  	if(name == "EventQueueGet")  	{ -		delete mEventPoll; -		mEventPoll = NULL; -		mEventPoll = new LLEventPoll(url, getHost()); +		delete mImpl->mEventPoll; +		mImpl->mEventPoll = NULL; +		mImpl->mEventPoll = new LLEventPoll(url, getHost());  	}  	else if(name == "UntrustedSimulatorMessage")  	{ -		LLHTTPSender::setSender(mHost, new LLCapHTTPSender(url)); +		LLHTTPSender::setSender(mImpl->mHost, new LLCapHTTPSender(url));  	}  	else  	{ -		mCapabilities[name] = url; +		mImpl->mCapabilities[name] = url;  		if(name == "GetTexture")  		{  			mHttpUrl = url ; @@ -1463,8 +1574,8 @@ bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)  std::string LLViewerRegion::getCapability(const std::string& name) const  { -	CapabilityMap::const_iterator iter = mCapabilities.find(name); -	if(iter == mCapabilities.end()) +	CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name); +	if(iter == mImpl->mCapabilities.end())  	{  		return "";  	} @@ -1485,7 +1596,7 @@ void LLViewerRegion::logActiveCapabilities() const  {  	int count = 0;  	CapabilityMap::const_iterator iter; -	for (iter = mCapabilities.begin(); iter != mCapabilities.end(); iter++, count++) +	for (iter = mImpl->mCapabilities.begin(); iter != mImpl->mCapabilities.end(); ++iter, ++count)  	{  		if (!iter->second.empty())  		{ @@ -1497,9 +1608,9 @@ void LLViewerRegion::logActiveCapabilities() const  LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)  { -	if (type < mObjectPartition.size()) +	if (type < mImpl->mObjectPartition.size())  	{ -		return mObjectPartition[type]; +		return mImpl->mObjectPartition[type];  	}  	return NULL;  } diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index dd40b876cd..9c5b85b77f 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -33,20 +33,16 @@  #include "lldarray.h"  #include "llwind.h" -#include "llbbox.h"  #include "llcloud.h"  #include "llstat.h"  #include "v3dmath.h" -#include "llhost.h"  #include "llstring.h"  #include "llregionflags.h"  #include "lluuid.h" -#include "lldatapacker.h" -#include "llvocache.h"  #include "llweb.h"  #include "llcapabilityprovider.h" -#include "llcapabilitylistener.h"  #include "m4math.h"					// LLMatrix4 +#include "llhttpclient.h"  // Surface id's  #define LAND  1 @@ -65,6 +61,13 @@ class LLVOCache;  class LLVOCacheEntry;  class LLSpatialPartition;  class LLEventPump; +class LLCapabilityListener; +class LLDataPacker; +class LLDataPackerBinaryBuffer; +class LLHost; +class LLBBox; + +class LLViewerRegionImpl;  class LLViewerRegion: public LLCapabilityProvider // implements this interface  { @@ -159,19 +162,19 @@ public:  	F32  getTimeDilation() const				{ return mTimeDilation; }  	// Origin height is at zero. -	const LLVector3d &getOriginGlobal() const	{ return mOriginGlobal; } +	const LLVector3d &getOriginGlobal() const;  	LLVector3 getOriginAgent() const;  	// Center is at the height of the water table. -	const LLVector3d &getCenterGlobal() const	{ return mCenterGlobal; } +	const LLVector3d &getCenterGlobal() const;  	LLVector3 getCenterAgent() const;  	void setRegionNameAndZone(const std::string& name_and_zone);  	const std::string& getName() const				{ return mName; }  	const std::string& getZoning() const			{ return mZoning; } -	void setOwner(const LLUUID& owner_id) { mOwnerID = owner_id; } -	const LLUUID& getOwner() const { return mOwnerID; } +	void setOwner(const LLUUID& owner_id); +	const LLUUID& getOwner() const;  	// Is the current agent on the estate manager list for this region?  	void setIsEstateManager(BOOL b) { mIsEstateManager = b; } @@ -206,7 +209,7 @@ public:  	// can process the message.  	static void processRegionInfo(LLMessageSystem* msg, void**); -	void setCacheID(const LLUUID& id)			{ mCacheID = id; } +	void setCacheID(const LLUUID& id);  	F32	getWidth() const						{ return mWidth; } @@ -222,8 +225,8 @@ public:  	U32	getPacketsLost() const; -	void setHttpResponderPtrNULL() {mHttpResponderPtr = NULL ;} -	const LLHTTPClient::ResponderPtr getHttpResponderPtr() const {return mHttpResponderPtr ;} +	void setHttpResponderPtrNULL(); +	const LLHTTPClient::ResponderPtr getHttpResponderPtr() const;  	// Get/set named capability URLs for this region.  	void setSeedCapability(const std::string& url); @@ -238,21 +241,19 @@ public:  	static bool isSpecialCapabilityName(const std::string &name);  	void logActiveCapabilities() const; -    /// Capability-request exception -    typedef LLCapabilityListener::ArgError ArgError;      /// Get LLEventPump on which we listen for capability requests      /// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities) -    LLEventPump& getCapAPI() { return mCapabilityListener.getCapAPI(); } +    LLEventPump& getCapAPI() const;      /// implements LLCapabilityProvider  	/*virtual*/ const LLHost& getHost() const;  	const U64 		&getHandle() const 			{ return mHandle; } -	LLSurface		&getLand() const			{ return *mLandp; } +	LLSurface		&getLand() const;  	// set and get the region id -	const LLUUID& getRegionID() const { return mRegionID; } -	void setRegionID(const LLUUID& region_id) { mRegionID = region_id; } +	const LLUUID& getRegionID() const; +	void setRegionID(const LLUUID& region_id);  	BOOL pointInRegionGlobal(const LLVector3d &point_global) const;  	LLVector3	getPosRegionFromGlobal(const LLVector3d &point_global) const; @@ -260,7 +261,7 @@ public:  	LLVector3	getPosAgentFromRegion(const LLVector3 ®ion_pos) const;  	LLVector3d	getPosGlobalFromRegion(const LLVector3 &offset) const; -	LLVLComposition *getComposition() const		{ return mCompositionp; } +	LLVLComposition *getComposition() const;  	F32 getCompositionXY(const S32 x, const S32 y) const;  	BOOL isOwnedSelf(const LLVector3& pos); @@ -347,34 +348,19 @@ public:  	LLDynamicArray<LLUUID> mMapAvatarIDs;  private: -	// The surfaces and other layers -	LLSurface*	mLandp; +	LLViewerRegionImpl * mImpl; -	// Region geometry data -	LLVector3d	mOriginGlobal;	// Location of southwest corner of region (meters) -	LLVector3d	mCenterGlobal;	// Location of center in world space (meters)  	F32			mWidth;			// Width of region on a side (meters) -  	U64			mHandle; -	LLHost		mHost; - -	// The unique ID for this region. -	LLUUID mRegionID; -  	F32			mTimeDilation;	// time dilation of physics simulation on simulator  	// simulator name  	std::string mName;  	std::string mZoning; -	// region/estate owner - usually null. -	LLUUID mOwnerID; -  	// Is this agent on the estate managers list for this region?  	BOOL mIsEstateManager; -	// Network statistics for the region's circuit... -	LLTimer mLastNetUpdate;  	U32		mPacketsIn;  	U32		mBitsIn;  	U32		mLastBitsIn; @@ -386,9 +372,6 @@ private:  	U32		mPingDelay;  	F32		mDeltaTime;				// Time since last measurement of lastPackets, Bits, etc -	// Misc -	LLVLComposition *mCompositionp;		// Composition layer for the surface -  	U32		mRegionFlags;			// includes damage flags  	U8		mSimAccess;  	F32 	mBillableFactor; @@ -398,46 +381,24 @@ private:  	// Information for Homestead / CR-53  	S32 mClassID;  	S32 mCPURatio; +  	std::string mColoName;  	std::string mProductSKU;  	std::string mProductName;  	std::string mHttpUrl ; -	  	// Maps local ids to cache entries.  	// Regions can have order 10,000 objects, so assume  	// a structure of size 2^14 = 16,000  	BOOL									mCacheLoaded;  	BOOL                                    mCacheDirty; -	LLVOCacheEntry::vocache_entry_map_t		mCacheMap; +  	LLDynamicArray<U32>						mCacheMissFull;  	LLDynamicArray<U32>						mCacheMissCRC; -	// time? -	// LRU info? -	// Cache ID is unique per-region, across renames, moving locations, -	// etc. -	LLUUID mCacheID; - -	typedef std::map<std::string, std::string> CapabilityMap; -	CapabilityMap mCapabilities; -	 -	LLEventPoll* mEventPoll; - -    /// Post an event to this LLCapabilityListener to invoke a capability message on -    /// this LLViewerRegion's server -    /// (https://wiki.lindenlab.com/wiki/Viewer:Messaging/Messaging_Notes#Capabilities) -    LLCapabilityListener mCapabilityListener; - -private:  	bool	mAlive;					// can become false if circuit disconnects  	bool	mCapabilitiesReceived; -	//spatial partitions for objects in this region -	std::vector<LLSpatialPartition*> mObjectPartition; - -	LLHTTPClient::ResponderPtr  mHttpResponderPtr ; -  	BOOL mReleaseNotesRequested;  }; diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 27aab0c081..d02b6be6b5 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -217,24 +217,24 @@ class LLUIImageList : public LLImageProviderInterface, public LLSingleton<LLUIIm  {  public:  	// LLImageProviderInterface -	/*virtual*/ LLUIImagePtr getUIImageByID(const LLUUID& id, S32 priority); -	/*virtual*/ LLUIImagePtr getUIImage(const std::string& name, S32 priority); +	/*virtual*/ LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority); +	/*virtual*/ LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority);  	void cleanUp();  	bool initFromFile(); -	LLUIImagePtr preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect); +	LLPointer<LLUIImage> preloadUIImage(const std::string& name, const std::string& filename, BOOL use_mips, const LLRect& scale_rect);  	static void onUIImageLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );  private: -	LLUIImagePtr loadUIImageByName(const std::string& name, const std::string& filename, +	LLPointer<LLUIImage> loadUIImageByName(const std::string& name, const std::string& filename,  		                           BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null,   		                           LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_UI); -	LLUIImagePtr loadUIImageByID(const LLUUID& id, +	LLPointer<LLUIImage> loadUIImageByID(const LLUUID& id,  								 BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null,   								 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_UI); -	LLUIImagePtr loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null); +	LLPointer<LLUIImage> loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null);  	struct LLUIImageLoadData diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index e020296842..7728958ed8 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -79,6 +79,7 @@  #include "lltooltip.h"  #include "llmediaentry.h"  #include "llurldispatcher.h" +#include "raytrace.h"  // newview includes  #include "llagent.h" @@ -234,17 +235,12 @@ BOOL				gDisplayCameraPos = FALSE;  BOOL				gDisplayFOV = FALSE;  BOOL				gDisplayBadge = FALSE; -S32 CHAT_BAR_HEIGHT = 28;  -S32 OVERLAY_BAR_HEIGHT = 20; - -const U8 NO_FACE = 255; +static const U8 NO_FACE = 255;  BOOL gQuietSnapshot = FALSE;  const F32 MIN_AFK_TIME = 2.f; // minimum time after setting away state before coming back -const F32 MAX_FAST_FRAME_TIME = 0.5f; -const F32 FAST_FRAME_INCREMENT = 0.1f; -const F32 MIN_DISPLAY_SCALE = 0.75f; +static const F32 MIN_DISPLAY_SCALE = 0.75f;  std::string	LLViewerWindow::sSnapshotBaseName;  std::string	LLViewerWindow::sSnapshotDir; diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 5eeb02b080..bb0023b787 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -38,13 +38,12 @@  #include "v3dmath.h"  #include "v2math.h" +#include "llcursortypes.h"  #include "llwindowcallbacks.h"  #include "lltimer.h"  #include "llstat.h"  #include "llmousehandler.h" -#include "llcursortypes.h"  #include "llhandle.h" -#include "llimage.h"  #include <boost/function.hpp>  #include <boost/signals2.hpp> @@ -59,6 +58,7 @@ class LLTool;  class LLVelocityBar;  class LLPanel;  class LLImageRaw; +class LLImageFormatted;  class LLHUDIcon;  class LLWindow;  class LLRootView; @@ -465,12 +465,6 @@ private:  	LLPointer<LLViewerObject>	mDragHoveredObject;  }; -void toggle_flying(void*); -void toggle_first_person(); -void toggle_build(void*); -void reset_viewer_state_on_sim(void); -void update_saved_window_size(const std::string& control,S32 delta_width, S32 delta_height); -  //  // Globals  // @@ -487,8 +481,6 @@ extern LLVector3        gDebugRaycastNormal;  extern LLVector3        gDebugRaycastBinormal;  extern S32				gDebugRaycastFaceHit; -extern S32 CHAT_BAR_HEIGHT;  -  extern BOOL			gDisplayCameraPos;  extern BOOL			gDisplayWindInfo;  extern BOOL			gDisplayFOV; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f1934933b5..79866dc5d2 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -38,9 +38,9 @@  #include <ctype.h>  #include "llaudioengine.h" -#include "llcachename.h"  #include "noise.h"  #include "sound_ids.h" +#include "raytrace.h"  #include "llagent.h" //  Get state values from here  #include "llagentcamera.h" diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index 37a974be28..46025b46be 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -50,6 +50,7 @@  #include "pipeline.h"  #include "llspatialpartition.h"  #include "llnotificationsutil.h" +#include "raytrace.h"  extern LLPipeline gPipeline; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index a207d3e050..ee54a938ba 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -63,6 +63,8 @@  #include "llmediadataclient.h"  #include "llagent.h"  #include "llviewermediafocus.h" +#include "lldatapacker.h" +#include "llvocache.h"  const S32 MIN_QUIET_FRAMES_COALESCE = 30;  const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp index 4b3a9a4dc3..67bb965f99 100644 --- a/indra/newview/llwaterparammanager.cpp +++ b/indra/newview/llwaterparammanager.cpp @@ -33,6 +33,7 @@  #include "pipeline.h"  #include "llsky.h" +#include "lldiriterator.h"  #include "llfloaterreg.h"  #include "llsliderctrl.h"  #include "llspinctrl.h" @@ -87,11 +88,12 @@ void LLWaterParamManager::loadAllPresets(const std::string& file_name)  	std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", ""));  	LL_DEBUGS2("AppInit", "Shaders") << "Loading Default water settings from " << path_name << LL_ENDL; -	bool found = true;			 +	bool found = true; +	LLDirIterator app_settings_iter(path_name, "*.xml");  	while(found)   	{  		std::string name; -		found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name); +		found = app_settings_iter.next(name);  		if(found)  		{ @@ -113,11 +115,12 @@ void LLWaterParamManager::loadAllPresets(const std::string& file_name)  	std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", ""));  	LL_DEBUGS2("AppInit", "Shaders") << "Loading User water settings from " << path_name2 << LL_ENDL; -	found = true;			 +	found = true; +	LLDirIterator user_settings_iter(path_name2, "*.xml");  	while(found)   	{  		std::string name; -		found = gDirUtilp->getNextFileInDir(path_name2, "*.xml", name); +		found = user_settings_iter.next(name);  		if(found)  		{  			name=name.erase(name.length()-4); diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp index e5f52dfc97..848efcbb49 100644 --- a/indra/newview/llwlparammanager.cpp +++ b/indra/newview/llwlparammanager.cpp @@ -31,6 +31,7 @@  #include "pipeline.h"  #include "llsky.h" +#include "lldiriterator.h"  #include "llfloaterreg.h"  #include "llsliderctrl.h"  #include "llspinctrl.h" @@ -100,11 +101,12 @@ void LLWLParamManager::loadPresets(const std::string& file_name)  	std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""));  	LL_DEBUGS2("AppInit", "Shaders") << "Loading Default WindLight settings from " << path_name << LL_ENDL; -	bool found = true;			 +	bool found = true; +	LLDirIterator app_settings_iter(path_name, "*.xml");  	while(found)   	{  		std::string name; -		found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name); +		found = app_settings_iter.next(name);  		if(found)  		{ @@ -126,11 +128,12 @@ void LLWLParamManager::loadPresets(const std::string& file_name)  	std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", ""));  	LL_DEBUGS2("AppInit", "Shaders") << "Loading User WindLight settings from " << path_name2 << LL_ENDL; -	found = true;			 +	found = true; +	LLDirIterator user_settings_iter(path_name2, "*.xml");  	while(found)   	{  		std::string name; -		found = gDirUtilp->getNextFileInDir(path_name2, "*.xml", name); +		found = user_settings_iter.next(name);  		if(found)  		{  			name=name.erase(name.length()-4); diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 8f50041474..fd42058c8a 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -50,6 +50,7 @@  #include "llviewerstats.h"  #include "llvlcomposition.h"  #include "llvoavatar.h" +#include "llvocache.h"  #include "llvowater.h"  #include "message.h"  #include "pipeline.h" diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 85182c1c28..d0603cb30e 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -1856,26 +1856,26 @@ even though the user gets a free copy.              <spinner               follows="left|top"               height="19" -             increment="0.025" +             increment="0.02"               initial_value="0"               label="B"               label_width="10"               layout="topleft"               left_delta="0" -             max_val="0.95" +             max_val="0.98"               name="Path Limit Begin"               top_pad="3"               width="68" />              <spinner               follows="left|top"               height="19" -             increment="0.025" +             increment="0.02"               initial_value="1"               label="E"               label_width="10"               layout="topleft"               left_pad="10" -             min_val="0.05" +             min_val="0.02"               name="Path Limit End"               top_delta="0"               width="68" /> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 06614dd218..d0dd639249 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6820,7 +6820,7 @@ Deed to group failed.     name="ReleaseLandThrottled"     type="notifytip">  The parcel [PARCEL_NAME] can not be abandoned at this time. -   tag>fail</tag> +   <tag>fail</tag>    </notification>    <notification diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml index 75126e74c5..5a913c4c9d 100644 --- a/indra/newview/skins/default/xui/es/strings.xml +++ b/indra/newview/skins/default/xui/es/strings.xml @@ -3588,6 +3588,9 @@ Si sigues recibiendo este mensaje, contacta con [SUPPORT_SITE].  	<string name="conference-title-incoming">  		Conferencia con [AGENT_NAME]  	</string> +	<string name="inventory_item_offered-im"> +		Ofrecido el item del inventario +	</string>  	<string name="no_session_message">  		(La sesión de MI no existe)  	</string> diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml index 6466f42c75..1dbbcafb0e 100644 --- a/indra/newview/skins/default/xui/pt/strings.xml +++ b/indra/newview/skins/default/xui/pt/strings.xml @@ -3587,6 +3587,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].  	<string name="conference-title-incoming">  		Conversa com [AGENT_NAME]  	</string> +	<string name="inventory_item_offered-im"> +		Oferta de item de inventário +	</string>  	<string name="no_session_message">  		(Sessão de MI inexistente)  	</string> diff --git a/indra/newview/skins/default/xui/zh/panel_login.xml b/indra/newview/skins/default/xui/zh/panel_login.xml new file mode 100644 index 0000000000..9d094ff731 --- /dev/null +++ b/indra/newview/skins/default/xui/zh/panel_login.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes"?> +<panel name="panel_login">	 +	<layout_stack name="login_widgets"> +		<layout_panel name="login"> +			<text name="username_text"> +				使用者名稱: +			</text>			 +			<text name="password_text"> +				密碼: +			</text> +			<check_box label="記住密碼" name="remember_check"/> +			<button label="登入" name="connect_btn"/> +			<text name="mode_selection_text"> +				模式: +			</text> +			<combo_box name="mode_combo" tool_tip="選擇一個登入模式"> +				<combo_box.item label="基礎" name="Basic"/> +				<combo_box.item label="進階" name="Advanced"/> +			</combo_box> +			<text name="start_location_text"> +				開始地點: +			</text> +			<combo_box name="start_location_combo"> +				<combo_box.item label="上一次的地點" name="MyLastLocation"/> +				<combo_box.item label="我的家" name="MyHome"/> +				<combo_box.item label="<輸入區域名>" name="Typeregionname"/> +			</combo_box> +		</layout_panel> +		<layout_panel name="links"> +			<text name="create_new_account_text"> +				註冊 +			</text> +			<text name="forgot_password_text"> +				忘記使用者名稱或密碼? +			</text> +			<text name="login_help"> +				如何登入? +			</text> +		</layout_panel> +	</layout_stack> +</panel> diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp index 9a6e08ee84..ed66066b0a 100644 --- a/indra/newview/tests/llremoteparcelrequest_test.cpp +++ b/indra/newview/tests/llremoteparcelrequest_test.cpp @@ -35,7 +35,6 @@  #include "llurlentry.h"  namespace { -	LLControlGroup s_saved_settings("dummy_settings");  	const LLUUID TEST_PARCEL_ID("11111111-1111-1111-1111-111111111111");  } @@ -64,13 +63,12 @@ LLMessageSystem * gMessageSystem;  char const* const _PREHASH_AgentID = 0;   // never dereferenced during this test  char const* const _PREHASH_AgentData = 0; // never dereferenced during this test  LLAgent gAgent; -LLAgent::LLAgent() : mAgentAccess(s_saved_settings) { } +LLAgent::LLAgent() : mAgentAccess(NULL) { }  LLAgent::~LLAgent() { }  void LLAgent::sendReliableMessage(void) { }  LLUUID gAgentSessionID;  LLUUID gAgentID;  LLUIColor::LLUIColor(void) { } -LLAgentAccess::LLAgentAccess(LLControlGroup & settings) : mSavedSettings(settings) { }  LLControlGroup::LLControlGroup(std::string const & name) : LLInstanceTracker<LLControlGroup, std::string>(name) { }  LLControlGroup::~LLControlGroup(void) { }  void LLUrlEntryParcel::processParcelInfo(const LLUrlEntryParcel::LLParcelData& parcel_data) { } diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp index b425b50c8b..710881d811 100644 --- a/indra/newview/tests/llviewerhelputil_test.cpp +++ b/indra/newview/tests/llviewerhelputil_test.cpp @@ -73,11 +73,9 @@ static void substitute_string(std::string &input, const std::string &search, con  }  #include "../llagent.h" -LLAgent::LLAgent() : mAgentAccess(gSavedSettings) { } +LLAgent::LLAgent() : mAgentAccess(NULL) { }  LLAgent::~LLAgent() { }  bool LLAgent::isGodlike() const { return FALSE; } -LLAgentAccess::LLAgentAccess(LLControlGroup& settings) : mSavedSettings(settings) { } -LLUIColor::LLUIColor() {}  LLAgent gAgent; diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp index 88ab5a2284..e19d5724f1 100644 --- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp +++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp @@ -59,12 +59,6 @@ class LLDir_Mock : public LLDir  		return 0;  	} -	BOOL getNextFileInDir(const std::string &dirname,  -						  const std::string &mask,  -						  std::string &fname)  -	{ -		return false; -	}  	void getRandomFileInDir(const std::string &dirname,   							const std::string &mask,   							std::string &fname) {} | 
