diff options
| -rw-r--r-- | indra/llcommon/llerrorcontrol.h | 2 | ||||
| -rw-r--r-- | indra/llcommon/llversionserver.h | 2 | ||||
| -rw-r--r-- | indra/llcommon/llversionviewer.h | 2 | ||||
| -rw-r--r-- | indra/llplugin/llpluginclassmedia.cpp | 23 | ||||
| -rw-r--r-- | indra/llplugin/llpluginclassmedia.h | 2 | ||||
| -rw-r--r-- | indra/media_plugins/quicktime/media_plugin_quicktime.cpp | 14 | ||||
| -rw-r--r-- | indra/newview/English.lproj/InfoPlist.strings | 4 | ||||
| -rw-r--r-- | indra/newview/Info-SecondLife.plist | 2 | ||||
| -rw-r--r-- | indra/newview/app_settings/settings.xml | 2 | ||||
| -rw-r--r-- | indra/newview/llmediadataclient.cpp | 24 | ||||
| -rw-r--r-- | indra/newview/llviewermedia.cpp | 3 | ||||
| -rw-r--r-- | indra/newview/llviewermediafocus.cpp | 5 | ||||
| -rw-r--r-- | indra/newview/res/viewerRes.rc | 8 | ||||
| -rw-r--r-- | indra/newview/tests/llmediadataclient_test.cpp | 68 | ||||
| -rwxr-xr-x | indra/newview/viewer_manifest.py | 2 | ||||
| -rw-r--r-- | indra/test_apps/llplugintest/CMakeLists.txt | 64 | ||||
| -rw-r--r-- | indra/test_apps/llplugintest/llmediaplugintest.cpp | 20 | 
17 files changed, 197 insertions, 50 deletions
| diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h index e069232798..233e9d3389 100644 --- a/indra/llcommon/llerrorcontrol.h +++ b/indra/llcommon/llerrorcontrol.h @@ -84,7 +84,7 @@ namespace LLError  	LL_COMMON_API void setFunctionLevel(const std::string& function_name, LLError::ELevel);  	LL_COMMON_API void setClassLevel(const std::string& class_name, LLError::ELevel);  	LL_COMMON_API void setFileLevel(const std::string& file_name, LLError::ELevel); -	void setTagLevel(const std::string& file_name, LLError::ELevel); +	LL_COMMON_API void setTagLevel(const std::string& file_name, LLError::ELevel);  	LL_COMMON_API void configure(const LLSD&);  		// the LLSD can configure all of the settings diff --git a/indra/llcommon/llversionserver.h b/indra/llcommon/llversionserver.h index aee7c6ee1e..71c6fc0591 100644 --- a/indra/llcommon/llversionserver.h +++ b/indra/llcommon/llversionserver.h @@ -36,7 +36,7 @@  const S32 LL_VERSION_MAJOR = 1;  const S32 LL_VERSION_MINOR = 31;  const S32 LL_VERSION_PATCH = 0; -const S32 LL_VERSION_BUILD = 2822; +const S32 LL_VERSION_BUILD = 3256;  const char * const LL_CHANNEL = "Second Life Server"; diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h index 9a230516d5..082d054ba2 100644 --- a/indra/llcommon/llversionviewer.h +++ b/indra/llcommon/llversionviewer.h @@ -36,7 +36,7 @@  const S32 LL_VERSION_MAJOR = 2;  const S32 LL_VERSION_MINOR = 0;  const S32 LL_VERSION_PATCH = 0; -const S32 LL_VERSION_BUILD = 2822; +const S32 LL_VERSION_BUILD = 3256;  const char * const LL_CHANNEL = "Second Life Developer"; diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index e019cdcf21..2a343fd0c9 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -133,6 +133,7 @@ void LLPluginClassMedia::reset()  	mCurrentTime = 0.0f;  	mDuration = 0.0f;  	mCurrentRate = 0.0f; +	mLoadedDuration = 0.0f;  }  void LLPluginClassMedia::idle(void) @@ -705,6 +706,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)  			bool time_duration_updated = false; +			int previous_percent = mProgressPercent;  			if(message.hasValue("current_time"))  			{ @@ -722,11 +724,32 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)  				mCurrentRate = message.getValueReal("current_rate");  			} +			if(message.hasValue("loaded_duration")) +			{ +				mLoadedDuration = message.getValueReal("loaded_duration"); +				time_duration_updated = true; +			} +			else +			{ +				// If the message doesn't contain a loaded_duration param, assume it's equal to duration +				mLoadedDuration = mDuration; +			} +			 +			// Calculate a percentage based on the loaded duration and total duration. +			if(mDuration != 0.0f)	// Don't divide by zero. +			{ +				mProgressPercent = (int)((mLoadedDuration * 100.0f)/mDuration); +			} +  			if(time_duration_updated)  			{  				mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_TIME_DURATION_UPDATED);  			} +			if(previous_percent != mProgressPercent) +			{ +				mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PROGRESS_UPDATED); +			}  		}  		else if(message_name == "media_status")  		{ diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index 97f2a11ef2..697deec353 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -231,6 +231,7 @@ public:  	F64 getCurrentTime(void) const { return mCurrentTime; };  	F64 getDuration(void) const { return mDuration; };  	F64 getCurrentPlayRate(void) { return mCurrentRate; }; +	F64 getLoadedDuration(void) const { return mLoadedDuration; };  	// Initialize the URL history of the plugin by sending  	// "init_history" message  @@ -339,6 +340,7 @@ protected:  	F64				mCurrentTime;  	F64				mDuration;  	F64				mCurrentRate; +	F64				mLoadedDuration;  }; diff --git a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp index fbda65120d..556865f771 100644 --- a/indra/media_plugins/quicktime/media_plugin_quicktime.cpp +++ b/indra/media_plugins/quicktime/media_plugin_quicktime.cpp @@ -103,6 +103,7 @@ private:  			message.setValueReal("current_time", getCurrentTime());  			message.setValueReal("duration", getDuration());  			message.setValueReal("current_rate", Fix2X(GetMovieRate(mMovieHandle))); +			message.setValueReal("loaded_duration", getLoadedDuration());  		}  		sendMessage(message); @@ -593,6 +594,19 @@ private:  		return (F64)duration / (F64)scale;  	}; +	F64 getLoadedDuration() +	{ +		TimeValue duration; +		if(GetMaxLoadedTimeInMovie( mMovieHandle, &duration ) != noErr) +		{ +			// If GetMaxLoadedTimeInMovie returns an error, return the full duration of the movie. +			duration = GetMovieDuration( mMovieHandle ); +		} +		TimeValue scale = GetMovieTimeScale( mMovieHandle ); + +		return (F64)duration / (F64)scale; +	}; +  	F64 getCurrentTime()  	{  		TimeValue curr_time = GetMovieTime( mMovieHandle, 0 ); diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings index afa5a877b5..dceaba9a43 100644 --- a/indra/newview/English.lproj/InfoPlist.strings +++ b/indra/newview/English.lproj/InfoPlist.strings @@ -2,6 +2,6 @@  CFBundleName = "Second Life"; -CFBundleShortVersionString = "Second Life version 2.0.0.2822"; -CFBundleGetInfoString = "Second Life version 2.0.0.2822, Copyright 2004-2009 Linden Research, Inc."; +CFBundleShortVersionString = "Second Life version 2.0.0.3256"; +CFBundleGetInfoString = "Second Life version 2.0.0.3256, Copyright 2004-2009 Linden Research, Inc."; diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist index 1df5102f5f..7aec8a343d 100644 --- a/indra/newview/Info-SecondLife.plist +++ b/indra/newview/Info-SecondLife.plist @@ -32,7 +32,7 @@  		</dict>  	</array>  	<key>CFBundleVersion</key> -	<string>2.0.0.2822</string> +	<string>2.0.0.3256</string>  	<key>CSResourcesFileMapped</key>  	<true/>  </dict> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ecad5dfe41..f1e5acdd74 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9981,7 +9981,7 @@        <key>Comment</key>        <string>Versioning Channel Name.</string>        <key>Persist</key> -      <integer>1</integer> +      <integer>0</integer>        <key>Type</key>        <string>String</string>        <key>Value</key> diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp index 3a1b47554c..f797f15865 100644 --- a/indra/newview/llmediadataclient.cpp +++ b/indra/newview/llmediadataclient.cpp @@ -182,15 +182,20 @@ LLMediaDataClient::Responder::RetryTimer::RetryTimer(F32 time, Responder *mdr)  LLMediaDataClient::Responder::RetryTimer::~RetryTimer()   {  	LL_DEBUGS("LLMediaDataClient") << "~RetryTimer" << *(mResponder->getRequest()) << LL_ENDL; + +	// XXX This is weird: Instead of doing the work in tick()  (which re-schedules +	// a timer, which might be risky), do it here, in the destructor.  Yes, it is very odd. +	// Instead of retrying, we just put the request back onto the queue +	LL_INFOS("LLMediaDataClient") << "RetryTimer fired for: " << *(mResponder->getRequest()) << "retrying" << LL_ENDL; +	mResponder->getRequest()->reEnqueue(); + +	// Release the ref to the responder.  	mResponder = NULL;  }  // virtual  BOOL LLMediaDataClient::Responder::RetryTimer::tick()  { -	// Instead of retrying, we just put the request back onto the queue -	LL_INFOS("LLMediaDataClient") << "RetryTimer fired for: " << *(mResponder->getRequest()) << "retrying" << LL_ENDL; -	mResponder->getRequest()->reEnqueue();  	// Don't fire again  	return TRUE;  } @@ -357,7 +362,7 @@ BOOL LLMediaDataClient::QueueTimer::tick()  		return TRUE;  	} -	LL_DEBUGS("LLMediaDataClient") << "QueueTimer::tick() started, queue is:	  " << queue << LL_ENDL; +	LL_INFOS("LLMediaDataClient") << "QueueTimer::tick() started, queue is:	  " << queue << LL_ENDL;  	// Peel one off of the items from the queue, and execute request  	request_ptr_t request = queue.top(); @@ -382,9 +387,13 @@ BOOL LLMediaDataClient::QueueTimer::tick()  		}  	}  	else { -		if (!object->hasMedia()) +		if (NULL == object)   		{ -			LL_INFOS("LLMediaDataClient") << "Not Sending request for " << *request << " hasMedia() is false!" << LL_ENDL; +			LL_WARNS("LLMediaDataClient") << "Not Sending request for " << *request << " NULL object!" << LL_ENDL; +		} +		else if (!object->hasMedia()) +		{ +			LL_WARNS("LLMediaDataClient") << "Not Sending request for " << *request << " hasMedia() is false!" << LL_ENDL;  		}  	}  	bool exceeded_retries = request->getRetryCount() > mMDC->mMaxNumRetries; @@ -414,6 +423,9 @@ void LLMediaDataClient::startQueueTimer()  		// LLEventTimer automagically takes care of the lifetime of this object  		new QueueTimer(mQueueTimerDelay, this);  	} +	else {  +		LL_DEBUGS("LLMediaDataClient") << "not starting queue timer (it's already running, right???)" << LL_ENDL; +	}  }  void LLMediaDataClient::stopQueueTimer() diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 3a503f22a0..6a40c76757 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -1017,6 +1017,9 @@ void LLViewerMediaImpl::navigateHome()  //////////////////////////////////////////////////////////////////////////////////////////  void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mime_type,  bool rediscover_type, bool server_request)  { +	// Helpful to have media urls in log file. Shouldn't be spammy. +	llinfos << "url=" << url << " mime_type=" << mime_type << llendl; +	  	if(server_request)  	{  		setNavState(MEDIANAVSTATE_SERVER_SENT); diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp index 1b1b7cedb1..db31714f16 100644 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -290,6 +290,11 @@ BOOL LLViewerMediaFocus::handleKey(KEY key, MASK mask, BOOL called_from_parent)  {  	if(mMediaImpl.notNull())  		mMediaImpl->handleKeyHere(key, mask); + +	if (key == KEY_ESCAPE && mMediaHUD.get()) +	{ +		mMediaHUD.get()->close(); +	}  	return true;  } diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc index 63b76d4f5d..433070ce34 100644 --- a/indra/newview/res/viewerRes.rc +++ b/indra/newview/res/viewerRes.rc @@ -134,8 +134,8 @@ TOOLMEDIAOPEN           CURSOR                  "toolmediaopen.cur"  //  VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,0,0,2822 - PRODUCTVERSION 2,0,0,2822 + FILEVERSION 2,0,0,3256 + PRODUCTVERSION 2,0,0,3256   FILEFLAGSMASK 0x3fL  #ifdef _DEBUG   FILEFLAGS 0x1L @@ -152,12 +152,12 @@ BEGIN          BEGIN              VALUE "CompanyName", "Linden Lab"              VALUE "FileDescription", "Second Life" -            VALUE "FileVersion", "2.0.0.2822" +            VALUE "FileVersion", "2.0.0.3256"              VALUE "InternalName", "Second Life"              VALUE "LegalCopyright", "Copyright © 2001-2008, Linden Research, Inc."              VALUE "OriginalFilename", "SecondLife.exe"              VALUE "ProductName", "Second Life" -            VALUE "ProductVersion", "2.0.0.2822" +            VALUE "ProductVersion", "2.0.0.3256"          END      END      BLOCK "VarFileInfo" diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp index a884ed0265..445ec7aa34 100644 --- a/indra/newview/tests/llmediadataclient_test.cpp +++ b/indra/newview/tests/llmediadataclient_test.cpp @@ -29,6 +29,8 @@   * COMPLETENESS OR PERFORMANCE.   * $/LicenseInfo$   */ + +#include "linden_common.h"  #include "../llviewerprecompiledheaders.h"  #include <iostream> @@ -46,7 +48,14 @@  #include "../../llprimitive/lltextureentry.cpp"  #include "../../llmessage/tests/llcurl_stub.cpp" +#if LL_WINDOWS +#pragma warning (push) +#pragma warning (disable : 4702) // boost::lexical_cast generates this warning +#endif  #include <boost/lexical_cast.hpp> +#if LL_WINDOWS +#pragma warning (pop) +#endif  #define VALID_OBJECT_ID   "3607d5c4-644b-4a8a-871a-8b78471af2a2"  #define VALID_OBJECT_ID_1 "11111111-1111-1111-1111-111111111111" @@ -186,6 +195,15 @@ private:  	int mNumBounceBacks;  }; +// This special timer delay should ensure that the timer will fire on the very +// next pump, no matter what (though this does make an assumption about the +// implementation of LLEventTimer::updateClass()): +const F32 NO_PERIOD = -1000.0f; + +static void pump_timers() +{ +	LLEventTimer::updateClass(); +}  namespace tut  { @@ -194,9 +212,9 @@ namespace tut  		mediadataclient() {  			gPostRecords = &mLLSD; -// 			LLError::setDefaultLevel(LLError::LEVEL_DEBUG); -// 			LLError::setClassLevel("LLMediaDataClient", LLError::LEVEL_DEBUG); -//			LLError::setTagLevel("MediaOnAPrim", LLError::LEVEL_DEBUG); + 			//LLError::setDefaultLevel(LLError::LEVEL_DEBUG); + 			//LLError::setClassLevel("LLMediaDataClient", LLError::LEVEL_DEBUG); +			//LLError::setTagLevel("MediaOnAPrim", LLError::LEVEL_DEBUG);  		}  		LLSD mLLSD;      }; @@ -256,14 +274,13 @@ namespace tut  		LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA);  		int num_refs_start = o->getNumRefs();  		{ -			// queue time w/ no delay ensures that LLEventTimer::updateClass() will hit the tick() -			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(0,0,4);   +			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);  			mdc->fetchMedia(o);  			// Make sure no posts happened yet...  			ensure("post records", gPostRecords->size(), 0); -			LLEventTimer::updateClass(); +			::pump_timers();  			ensure("post records", gPostRecords->size(), 1);  			ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_CAP_URL); @@ -288,11 +305,11 @@ namespace tut  		LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA);  		{ -			// queue time w/ no delay ensures that LLEventTimer::updateClass() will hit the tick() -			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(0,0,4);   +			// queue time w/ no delay ensures that ::pump_timers() will hit the tick() +			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);    			mdc->updateMedia(o);  			ensure("post records", gPostRecords->size(), 0); -			LLEventTimer::updateClass(); +			::pump_timers();  			ensure("post records", gPostRecords->size(), 1);  			ensure("post url", (*gPostRecords)[0]["url"], FAKE_OBJECT_MEDIA_CAP_URL); @@ -318,11 +335,11 @@ namespace tut  		LLMediaDataClientObject::ptr_t o = new LLMediaDataClientObjectTest(DATA);  		{		 -			LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(0,0,4); +			LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(NO_PERIOD,NO_PERIOD);  			const char *TEST_URL = "http://example.com";  			mdc->navigate(o, 0, TEST_URL);  			ensure("post records", gPostRecords->size(), 0); -			LLEventTimer::updateClass(); +			::pump_timers();  			// ensure no bounce back  			ensure("bounce back", dynamic_cast<LLMediaDataClientObjectTest*>(static_cast<LLMediaDataClientObject*>(o))->getNumBounceBacks(), 0); @@ -354,7 +371,7 @@ namespace tut  		LLMediaDataClientObject::ptr_t o3 = new LLMediaDataClientObjectTest(  			_DATA(VALID_OBJECT_ID_3,"2.0","1.0"));  		{ -			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(0,0,4);   +			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD);    			const char *ORDERED_OBJECT_IDS[] = { VALID_OBJECT_ID_2, VALID_OBJECT_ID_3, VALID_OBJECT_ID_1 };  			mdc->fetchMedia(o1);  			mdc->fetchMedia(o2); @@ -364,11 +381,11 @@ namespace tut  			ensure("post records", gPostRecords->size(), 0);  			// tick 3 times... -			LLEventTimer::updateClass(); +			::pump_timers();  			ensure("post records", gPostRecords->size(), 1); -			LLEventTimer::updateClass(); +			::pump_timers();  			ensure("post records", gPostRecords->size(), 2); -			LLEventTimer::updateClass(); +			::pump_timers();  			ensure("post records", gPostRecords->size(), 3);  			for( int i=0; i < 3; i++ ) @@ -405,7 +422,7 @@ namespace tut  		int num_refs_start = o->getNumRefs();  		{  			const int NUM_RETRIES = 5; -			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(0,0,NUM_RETRIES); +			LLPointer<LLObjectMediaDataClient> mdc = new LLObjectMediaDataClient(NO_PERIOD,NO_PERIOD,NUM_RETRIES);  			// This should generate a retry  			mdc->fetchMedia(o); @@ -418,15 +435,16 @@ namespace tut  			// Third, fires queue timer again  			for (int i=0; i<NUM_RETRIES; ++i)  			{ -				LLEventTimer::updateClass(); -				ensure("post records " + STR(i), gPostRecords->size(), i+1); -				LLEventTimer::updateClass(); +				::pump_timers();  // Should pump (fire) the queue timer, causing a retry timer to be scheduled +				// XXX This ensure is not guaranteed, because scheduling a timer might actually get it pumped in the same loop +				//ensure("post records " + STR(i), gPostRecords->size(), i+1); +				::pump_timers();  // Should pump (fire) the retry timer, scheduling the queue timer  			} -			// Do some extre pumps to make sure no other timer work occurs. -			LLEventTimer::updateClass(); -			LLEventTimer::updateClass(); -			LLEventTimer::updateClass(); +			// Do some extra pumps to make sure no other timer work occurs. +			::pump_timers(); +			::pump_timers(); +			::pump_timers();  			// Make sure there were 2 posts  			ensure("post records after", gPostRecords->size(), NUM_RETRIES); @@ -458,11 +476,11 @@ namespace tut  					   FAKE_OBJECT_MEDIA_CAP_URL,  					   FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR));  		{		 -			LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(0,0,4); +			LLPointer<LLObjectMediaNavigateClient> mdc = new LLObjectMediaNavigateClient(NO_PERIOD,NO_PERIOD);  			const char *TEST_URL = "http://example.com";  			mdc->navigate(o, 0, TEST_URL);  			ensure("post records", gPostRecords->size(), 0); -			LLEventTimer::updateClass(); +			::pump_timers();  			// ensure bounce back  			ensure("bounce back",  diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 41aa13614e..f2e89ef062 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -626,7 +626,7 @@ class DarwinManifest(ViewerManifest):          # make sure we don't have stale files laying about          self.remove(sparsename, finalname) -        self.run_command('hdiutil create "%(sparse)s" -volname "%(vol)s" -fs HFS+ -type SPARSE -megabytes 500 -layout SPUD' % { +        self.run_command('hdiutil create "%(sparse)s" -volname "%(vol)s" -fs HFS+ -type SPARSE -megabytes 700 -layout SPUD' % {                  'sparse':sparsename,                  'vol':volname}) diff --git a/indra/test_apps/llplugintest/CMakeLists.txt b/indra/test_apps/llplugintest/CMakeLists.txt index 295882c49a..88c4ba8ad9 100644 --- a/indra/test_apps/llplugintest/CMakeLists.txt +++ b/indra/test_apps/llplugintest/CMakeLists.txt @@ -28,7 +28,7 @@ include_directories(  if (DARWIN)      include(CMakeFindFrameworks) -    find_library(CARBON_LIBRARY Carbon) +    find_library(COREFOUNDATION_LIBRARY CoreFoundation)  endif (DARWIN)  ### demo_plugin @@ -261,6 +261,7 @@ set(llmediaplugintest_SOURCE_FILES  add_executable(llmediaplugintest      WIN32 +    MACOSX_BUNDLE      ${llmediaplugintest_SOURCE_FILES}  ) @@ -280,6 +281,13 @@ target_link_libraries(llmediaplugintest    ${PLUGIN_API_WINDOWS_LIBRARIES}  ) +if (DARWIN) +  # The testbed needs to use a couple of CoreFoundation calls now, to deal with being a bundled app. +  target_link_libraries(llmediaplugintest +    ${COREFOUNDATION_LIBRARY} +  ) +endif (DARWIN) +  add_dependencies(llmediaplugintest    stage_third_party_libs    SLPlugin @@ -300,22 +308,64 @@ endif (DARWIN OR LINUX)  # Gather build products of the various dependencies into the build directory for the testbed. +if (DARWIN) +  # path inside the app bundle where we'll need to copy plugins and other related files +  set(PLUGINS_DESTINATION_DIR +    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llmediaplugintest.app/Contents/Resources +  ) +   +  # create the Contents/Resources directory +  add_custom_command( +    TARGET llmediaplugintest POST_BUILD +    COMMAND ${CMAKE_COMMAND} +    ARGS +      -E +      make_directory +      ${PLUGINS_DESTINATION_DIR} +    COMMENT "Creating Resources directory in app bundle." +  ) + +  # copy the llcommon dylib and its dependencies to Contents/Resources. +  get_target_property(BUILT_LLCOMMON llcommon LOCATION) +  add_custom_command(TARGET llmediaplugintest POST_BUILD +    COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_LLCOMMON}  ${PLUGINS_DESTINATION_DIR} +    DEPENDS ${BUILT_LLCOMMON} +  ) +  # FIXME: these paths should come from somewhere reliable.  The canonical list seems to be in indra/newview/viewer_manifest.py +  add_custom_command(TARGET llmediaplugintest POST_BUILD +    COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.0.3.7.dylib  ${PLUGINS_DESTINATION_DIR} +    DEPENDS ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.0.3.7.dylib +  ) +  add_custom_command(TARGET llmediaplugintest POST_BUILD +    COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.0.3.8.dylib  ${PLUGINS_DESTINATION_DIR} +    DEPENDS ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.0.3.8.dylib +  ) +  add_custom_command(TARGET llmediaplugintest POST_BUILD +    COMMAND ${CMAKE_COMMAND} -E copy ${ARCH_PREBUILT_DIRS_RELEASE}/libexpat.0.5.0.dylib  ${PLUGINS_DESTINATION_DIR} +    DEPENDS ${ARCH_PREBUILT_DIRS_RELEASE}/libexpat.0.5.0.dylib +  ) +else (DARWIN) +  set(PLUGINS_DESTINATION_DIR +    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ +  ) +endif (DARWIN) +  get_target_property(BUILT_SLPLUGIN SLPlugin LOCATION)  add_custom_command(TARGET llmediaplugintest POST_BUILD -  COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_SLPLUGIN}  ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ +  COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_SLPLUGIN}  ${PLUGINS_DESTINATION_DIR}    DEPENDS ${BUILT_SLPLUGIN}  )  if (DARWIN OR WINDOWS)    get_target_property(BUILT_WEBKIT_PLUGIN media_plugin_webkit LOCATION)    add_custom_command(TARGET llmediaplugintest POST_BUILD -    COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_WEBKIT_PLUGIN}  ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ +    COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_WEBKIT_PLUGIN}  ${PLUGINS_DESTINATION_DIR}      DEPENDS ${BUILT_WEBKIT_PLUGIN}    )    get_target_property(BUILT_QUICKTIME_PLUGIN media_plugin_quicktime LOCATION)    add_custom_command(TARGET llmediaplugintest POST_BUILD -    COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_QUICKTIME_PLUGIN}  ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ +    COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_QUICKTIME_PLUGIN}  ${PLUGINS_DESTINATION_DIR}      DEPENDS ${BUILT_QUICKTIME_PLUGIN}    ) @@ -325,16 +375,16 @@ if (DARWIN OR WINDOWS)      COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/      DEPENDS ${BUILT_LLMEDIAPLUGINTEST}    ) -  # also copy it to the build configuration directory, which is what the mac wants... +  # also copy it to the same place as SLPlugin, which is what the mac wants...    add_custom_command(TARGET llmediaplugintest POST_BUILD -    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ +    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bookmarks.txt ${PLUGINS_DESTINATION_DIR}      DEPENDS ${BUILT_LLMEDIAPLUGINTEST}    )  endif (DARWIN OR WINDOWS)  if (DARWIN)    add_custom_command(TARGET llmediaplugintest POST_BUILD -    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ +    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib ${PLUGINS_DESTINATION_DIR}      DEPENDS ${CMAKE_SOURCE_DIR}/../libraries/universal-darwin/lib_release/libllqtwebkit.dylib    )  endif (DARWIN) diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp index f9568a9b5d..ba66b449f3 100644 --- a/indra/test_apps/llplugintest/llmediaplugintest.cpp +++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp @@ -44,6 +44,7 @@  #if __APPLE__  	#include <GLUT/glut.h> +	#include <CoreFoundation/CoreFoundation.h>  #else  	#define FREEGLUT_STATIC  	#include "GL/freeglut.h" @@ -2111,6 +2112,25 @@ void glutMouseButton( int button, int state, int x, int y )  //  int main( int argc, char* argv[] )  { +#if LL_DARWIN +	// Set the current working directory to <application bundle>/Contents/Resources/ +	CFURLRef resources_url = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); +	if(resources_url != NULL) +	{ +		CFStringRef resources_string = CFURLCopyFileSystemPath(resources_url, kCFURLPOSIXPathStyle); +		CFRelease(resources_url); +		if(resources_string != NULL) +		{ +			char buffer[PATH_MAX] = ""; +			if(CFStringGetCString(resources_string, buffer, sizeof(buffer), kCFStringEncodingUTF8)) +			{ +				chdir(buffer); +			} +			CFRelease(resources_string); +		} +	} +#endif +  	glutInit( &argc, argv );  	glutInitDisplayMode( GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB ); | 
