summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorskolb <none@none>2009-10-15 13:58:16 -0700
committerskolb <none@none>2009-10-15 13:58:16 -0700
commite9f7205ba9f4dfb3422759218609b62d61972722 (patch)
treee7859943f67b0ab2f8e132cd64c0effbb3462206 /indra
parent1b1550f284316b244a10a4a6604fedb5d6b18965 (diff)
parent050ae3cf5107140a58f6aeae865d254b74a23d44 (diff)
Merge fix for DEV-39832
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llerrorcontrol.h2
-rw-r--r--indra/llcommon/llversionserver.h2
-rw-r--r--indra/llcommon/llversionviewer.h2
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp23
-rw-r--r--indra/llplugin/llpluginclassmedia.h2
-rw-r--r--indra/media_plugins/quicktime/media_plugin_quicktime.cpp14
-rw-r--r--indra/newview/English.lproj/InfoPlist.strings4
-rw-r--r--indra/newview/Info-SecondLife.plist2
-rw-r--r--indra/newview/app_settings/settings.xml2
-rw-r--r--indra/newview/llmediadataclient.cpp24
-rw-r--r--indra/newview/llviewermedia.cpp3
-rw-r--r--indra/newview/llviewermediafocus.cpp5
-rw-r--r--indra/newview/res/viewerRes.rc8
-rw-r--r--indra/newview/tests/llmediadataclient_test.cpp68
-rwxr-xr-xindra/newview/viewer_manifest.py2
-rw-r--r--indra/test_apps/llplugintest/CMakeLists.txt64
-rw-r--r--indra/test_apps/llplugintest/llmediaplugintest.cpp20
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 );