diff options
author | Rider Linden <rider@lindenlab.com> | 2015-12-18 14:10:02 -0800 |
---|---|---|
committer | Rider Linden <rider@lindenlab.com> | 2015-12-18 14:10:02 -0800 |
commit | 909e4097433ab8e84a19e2119a9ecf05b3eebe64 (patch) | |
tree | fe11439e42d20f1f2eae81e772c68b0d9fdb2692 /indra/newview | |
parent | b98469bd7db06973e6058118551e500dc094d3c0 (diff) | |
parent | 6dd80980cfa5be214c143d125cfabd006ea7ebff (diff) |
Merge
Diffstat (limited to 'indra/newview')
30 files changed, 1050 insertions, 655 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 079751aaf7..2661dd759a 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -44,7 +44,6 @@ include(OPENAL) include(OpenGL) include(OpenSSL) include(PNG) -include(Prebuilt) include(TemplateCheck) include(UI) include(UnixInstall) @@ -62,9 +61,6 @@ if(FMODEX) include_directories(${FMODEX_INCLUDE_DIR}) endif(FMODEX) -# install SLPlugin host executable and its dynamic-library plugins -use_prebuilt_binary(slplugins) - include_directories( ${DBUSGLIB_INCLUDE_DIRS} ${JSONCPP_INCLUDE_DIR} @@ -1747,44 +1743,12 @@ if (WINDOWS) ${CMAKE_CURRENT_SOURCE_DIR}/featuretable.txt ${CMAKE_CURRENT_SOURCE_DIR}/featuretable_xp.txt ${ARCH_PREBUILT_DIRS_RELEASE}/libeay32.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/qtcore4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/qtgui4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/qtnetwork4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/qtopengl4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/qtwebkit4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/qtxmlpatterns4.dll ${ARCH_PREBUILT_DIRS_RELEASE}/ssleay32.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/imageformats/qgif4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/imageformats/qico4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/imageformats/qjpeg4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/imageformats/qmng4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/imageformats/qsvg4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/imageformats/qtiff4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qcncodecs4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qjpcodecs4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qkrcodecs4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qtwcodecs4.dll ${ARCH_PREBUILT_DIRS_DEBUG}/libeay32.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/qtcored4.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/qtguid4.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/qtnetworkd4.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/qtopengld4.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/qtwebkitd4.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/qtxmlpatternsd4.dll ${ARCH_PREBUILT_DIRS_DEBUG}/ssleay32.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/imageformats/qgifd4.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/imageformats/qicod4.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/imageformats/qjpegd4.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/imageformats/qmngd4.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/imageformats/qsvgd4.dll - ${ARCH_PREBUILT_DIRS_DEBUG}/imageformats/qtiffd4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qcncodecsd4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qjpcodecsd4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qkrcodecsd4.dll - ${ARCH_PREBUILT_DIRS_RELEASE}/codecs/qtwcodecsd4.dll SLPlugin media_plugin_quicktime - media_plugin_webkit + media_plugin_cef winmm_shim windows-crash-logger ) @@ -1829,10 +1793,10 @@ if (WINDOWS) add_dependencies(${VIEWER_BINARY_NAME} copy_win_scripts) endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts) -## add_dependencies(${VIEWER_BINARY_NAME} -## SLPlugin -## windows-crash-logger -## ) + add_dependencies(${VIEWER_BINARY_NAME} + SLPlugin + windows-crash-logger + ) # sets the 'working directory' for debugging from visual studio. if (NOT UNATTENDED) @@ -1999,9 +1963,8 @@ if (LINUX) set(COPY_INPUT_DEPENDENCIES ${VIEWER_BINARY_NAME} linux-crash-logger -## SLPlugin -## media_plugin_webkit -## media_plugin_gstreamer010 + SLPlugin + media_plugin_gstreamer010 llcommon ) @@ -2113,7 +2076,7 @@ if (DARWIN) ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py ) -##add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit mac-crash-logger) + add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_cef mac-crash-logger) add_dependencies(${VIEWER_BINARY_NAME} mac-crash-logger) if (ENABLE_SIGNING) @@ -2168,20 +2131,19 @@ if (PACKAGE) if (DARWIN) list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}") # *TODO: Generate these search dirs in the cmake files related to each binary. -## list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}") + list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}") list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}") -## list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}") -## list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}") -## list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/webkit/${CMAKE_CFG_INTDIR}") + list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}") + list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}") set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin.tar.bz2") -## set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger") + set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger") set(VIEWER_EXE_GLOBS "'Second Life' mac-crash-logger") set(VIEWER_LIB_GLOB "*.dylib") endif (DARWIN) if (LINUX) list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged") set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-linux.tar.bz2") -## set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin") + set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin") set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin") set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*") set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 4351a7e3a3..1454f6ed4b 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -3.8.7 +4.0.1 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 2ca090b179..d5549013fa 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -734,7 +734,7 @@ <string>F32</string> <key>Value</key> <integer>60</integer> - </map> + </map> <key>AvatarRotateThresholdFast</key> <map> <key>Comment</key> @@ -745,7 +745,7 @@ <string>F32</string> <key>Value</key> <integer>2</integer> - </map> + </map> <key>AvatarBakedTextureUploadTimeout</key> <map> <key>Comment</key> @@ -1339,7 +1339,7 @@ <string>String</string> <key>Value</key> <string /> - </map> + </map> <key>CacheNumberOfRegionsForObjects</key> <map> <key>Comment</key> @@ -3799,7 +3799,7 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> - </map> + </map> <key>FirstSelectedEnabledPopups</key> <map> <key>Comment</key> @@ -3810,7 +3810,7 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> - </map> + </map> <key>FixedWeather</key> <map> <key>Comment</key> @@ -3932,7 +3932,7 @@ <key>Value</key> <string>SW</string> </map> - + <key>FloaterStatisticsRect</key> <map> <key>Comment</key> @@ -4459,7 +4459,7 @@ <string>String</string> <key>Value</key> <string>http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/[GRID_LOWERCASE]/howto/index.html</string> - </map> + </map> <key>HomeSidePanelURL</key> <map> <key>Comment</key> @@ -4525,7 +4525,7 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> - </map> + </map> <key>HostID</key> <map> <key>Comment</key> @@ -4613,7 +4613,7 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> - </map> + </map> <key>IgnorePixelDepth</key> <map> <key>Comment</key> @@ -4668,7 +4668,7 @@ <string>F32</string> <key>Value</key> <real>0.5</real> - </map> + </map> <key>InspectorShowTime</key> <map> <key>Comment</key> @@ -4679,7 +4679,7 @@ <string>F32</string> <key>Value</key> <real>3.0</real> - </map> + </map> <key>InstallLanguage</key> <map> <key>Comment</key> @@ -5241,7 +5241,7 @@ <key>Value</key> <string>0.0.0</string> </map> - + <key>LastSnapshotToProfileHeight</key> <map> <key>Comment</key> @@ -6320,7 +6320,7 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> - </map> + </map> <key>MenuAccessKeyTime</key> <map> <key>Comment</key> @@ -6485,7 +6485,7 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> - </map> + </map> <key>MouseSun</key> <map> <key>Comment</key> @@ -6650,7 +6650,7 @@ <string>String</string> <key>Value</key> <string /> - </map> + </map> <key>NextLoginLocation</key> <map> <key>Comment</key> @@ -6774,7 +6774,7 @@ <string>String</string> <key>Value</key> <string>toast</string> - </map> + </map> <key>NotificationFriendIMOptions</key> <map> <key>Comment</key> @@ -6830,7 +6830,7 @@ <string>String</string> <key>Value</key> <string>toast</string> - </map> + </map> <key>NotificationObjectIMOptions</key> <map> <key>Comment</key> @@ -6844,7 +6844,7 @@ <string>String</string> <key>Value</key> <string>toast</string> - </map> + </map> <key>NotificationToastLifeTime</key> <map> <key>Comment</key> @@ -7403,7 +7403,7 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> - </map> + </map> <key>PlaySoundFriendIM</key> <map> <key>Comment</key> @@ -7514,7 +7514,7 @@ <key>Value</key> <real>0.9</real> </map> - + <key>PlainTextChatHistory</key> <map> <key>Comment</key> @@ -7526,7 +7526,7 @@ <key>Value</key> <integer>0</integer> </map> - + <key>PluginInstancesLow</key> <map> <key>Comment</key> @@ -7780,7 +7780,7 @@ <real>0.4</real> </array> </map> - + <key>PreviewDirection2</key> <map> <key>Comment</key> @@ -8092,7 +8092,7 @@ <key>Type</key> <string>F32</string> <key>Value</key> - <real>5.0</real> + <real>10.0</real> </map> <key>MediaRollOffMax</key> <map> @@ -8390,7 +8390,7 @@ <key>RenderComplexityStaticMax</key> <map> <key>Comment</key> - <string>Sets a static max value for scaling of RenderComplexity + <string>Sets a static max value for scaling of RenderComplexity display (-1 for dynamic scaling)</string> <key>Persist</key> <integer>1</integer> @@ -8468,7 +8468,7 @@ <key>Value</key> <integer>0</integer> </map> - + <key>RenderLocalLights</key> <map> <key>Comment</key> @@ -8695,7 +8695,7 @@ <key>Persist</key> <integer>1</integer> <key>Type</key> - <string>Boolean</string> + <string>Boolean</string> <key>Value</key> <integer>0</integer> </map> @@ -8732,7 +8732,7 @@ <key>Value</key> <integer>0</integer> </map> - + <key>RenderAnimateRes</key> <map> <key>Comment</key> @@ -8905,7 +8905,7 @@ <key>Value</key> <integer>0</integer> </map> - + <key>RenderDepthOfField</key> <map> <key>Comment</key> @@ -9034,7 +9034,7 @@ <key>Value</key> <real>0.1</real> </map> - + <key>RenderHighlightBrightness</key> <map> <key>Comment</key> @@ -9058,7 +9058,7 @@ <key>Value</key> <real>0.6</real> </map> - + <key>RenderHighlightColor</key> <map> <key>Comment</key> @@ -9087,7 +9087,7 @@ <key>Value</key> <integer>0</integer> </map> - + <key>RenderSpecularResX</key> <map> <key>Comment</key> @@ -9992,7 +9992,7 @@ <key>Value</key> <integer>1</integer> </map> - + <key>RenderAutoMuteByteLimit</key> <map> <key>Comment</key> @@ -10047,7 +10047,7 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> - </map> + </map> <key>RenderAutoHideSurfaceAreaLimit</key> <map> <key>Comment</key> @@ -10533,7 +10533,7 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> - </map> + </map> <key>SelectMovableOnly</key> <map> <key>Comment</key> @@ -10775,7 +10775,7 @@ <string>Boolean</string> <key>Value</key> <integer>1</integer> - </map> + </map> <key>ShowCrosshairs</key> <map> <key>Comment</key> @@ -10852,7 +10852,7 @@ <string>Boolean</string> <key>Value</key> <integer>0</integer> - </map> + </map> <key>ShowMiniMapButton</key> <map> <key>Comment</key> @@ -10919,7 +10919,7 @@ <key>Value</key> <integer>1</integer> </map> - <key>ShowObjectRenderingCost</key> + <key>ShowObjectRenderingCost</key> <map> <key>Comment</key> <string>Show the object rendering cost in build tools</string> @@ -10928,9 +10928,9 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> - </map> - <key>ShowNavbarFavoritesPanel</key> + <integer>1</integer> + </map> + <key>ShowNavbarFavoritesPanel</key> <map> <key>Comment</key> <string>Show/hide navigation bar favorites panel</string> @@ -10939,9 +10939,9 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <integer>1</integer> </map> - <key>ShowNavbarNavigationPanel</key> + <key>ShowNavbarNavigationPanel</key> <map> <key>Comment</key> <string>Show/hide navigation bar navigation panel</string> @@ -10950,7 +10950,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <integer>1</integer> + <integer>1</integer> </map> <key>ShowWorldMapButton</key> <map> @@ -11106,7 +11106,7 @@ <key>Value</key> <integer>1</integer> </map> - <key>ShowPGSearchAll</key> + <key>ShowPGSearchAll</key> <map> <key>Comment</key> <string>Display results of search All that are flagged as general</string> @@ -11622,7 +11622,7 @@ <string>S32</string> <key>Value</key> <integer>0</integer> - </map> + </map> <key>SnapshotQuality</key> <map> <key>Comment</key> @@ -12491,7 +12491,7 @@ <string>String</string> <key>Value</key> <string>B56AF90D-6684-48E4-B1E4-722D3DEB2CB6</string> - </map> + </map> <key>NearByChatChannelUUID</key> <map> <key>Comment</key> @@ -12502,7 +12502,7 @@ <string>String</string> <key>Value</key> <string>E1158BD6-661C-4981-9DAD-4DCBFF062502</string> - </map> + </map> <key>NotificationChannelUUID</key> <map> <key>Comment</key> @@ -12513,7 +12513,7 @@ <string>String</string> <key>Value</key> <string>AEED3193-8709-4693-8558-7452CCA97AE5</string> - </map> + </map> <key>AlertChannelUUID</key> <map> <key>Comment</key> @@ -12524,7 +12524,7 @@ <string>String</string> <key>Value</key> <string>F3E07BC8-A973-476D-8C7F-F3B7293975D1</string> - </map> + </map> <key>UIImgWhiteUUID</key> <map> <key>Comment</key> @@ -12546,7 +12546,7 @@ <string>S32</string> <key>Value</key> <integer>2</integer> - </map> + </map> <key>UIMaxComboWidth</key> <map> <key>Comment</key> @@ -13459,7 +13459,7 @@ <string>String</string> <key>Value</key> <string>[i800,i600]</string> - </map> + </map> <key>sourceid</key> <map> <key>Comment</key> @@ -14698,7 +14698,7 @@ <string>Boolean</string> <key>Value</key> <integer>1</integer> - </map> + </map> <key>EnablePlaceProfile</key> <map> <key>Comment</key> @@ -15520,7 +15520,7 @@ <key>Value</key> <integer>0</integer> </map> - + <key>PathfindingLineWidth</key> <map> <key>Comment</key> @@ -15561,7 +15561,7 @@ <real>1.0</real> </array> </map> - + <key>HideUIControls</key> <map> <key>Comment</key> diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 10caeb17c5..413cc413e6 100755 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -122,6 +122,9 @@ #include "llleap.h" #include "stringize.h" #include "llcoros.h" +#if !LL_LINUX +#include "cef/llceflib.h" +#endif // Third party library includes #include <boost/bind.hpp> @@ -129,7 +132,6 @@ #include <boost/algorithm/string.hpp> #include <boost/regex.hpp> - #if LL_WINDOWS # include <share.h> // For _SH_DENYWR in processMarkerFiles #else @@ -1700,6 +1702,9 @@ bool LLAppViewer::cleanup() // to ensure shutdown order LLMortician::setZealous(TRUE); + // Give any remaining SLPlugin instances a chance to exit cleanly. + LLPluginProcessParent::shutdown(); + LLVoiceClient::getInstance()->terminate(); disconnectViewer(); @@ -2752,7 +2757,7 @@ bool LLAppViewer::initConfiguration() #endif if (!gArgs.empty()) { - gWindowTitle += std::string(" ") + gArgs; + gWindowTitle += std::string(" ") + gArgs; } LLStringUtil::truncate(gWindowTitle, 255); @@ -3336,8 +3341,11 @@ LLSD LLAppViewer::getViewerInfo() const info["VOICE_VERSION"] = LLTrans::getString("NotConnected"); } - // TODO: Implement media plugin version query - info["QT_WEBKIT_VERSION"] = "4.7.1 (version number hard-coded)"; +#if !LL_LINUX + info["LLCEFLIB_VERSION"] = LLCEFLIB_VERSION; +#else + info["LLCEFLIB_VERSION"] = "Undefined"; +#endif S32 packets_in = LLViewerStats::instance().getRecording().getSum(LLStatViewer::PACKETS_IN); if (packets_in > 0) diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index dac610eda1..f7861fb4fd 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -108,6 +108,7 @@ #include "llpluginclassmedia.h" #include "llteleporthistorystorage.h" #include "llproxy.h" +#include "llweb.h" #include "lllogininstance.h" // to check if logged in yet #include "llsdserialize.h" @@ -1942,6 +1943,16 @@ BOOL LLPanelPreference::postBuild() gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&LLPanelPreference::Updater::update, mBandWidthUpdater, _2)); } +#ifdef EXTERNAL_TOS + LLRadioGroup* ext_browser_settings = getChild<LLRadioGroup>("preferred_browser_behavior"); + if (ext_browser_settings) + { + // turn off ability to set external/internal browser + ext_browser_settings->setSelectedByValue(LLWeb::BROWSER_EXTERNAL_ONLY, true); + ext_browser_settings->setEnabled(false); + } +#endif + apply(); return true; } diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp index 5fa4441914..1743d0fc69 100755 --- a/indra/newview/llfloatertos.cpp +++ b/indra/newview/llfloatertos.cpp @@ -84,6 +84,20 @@ BOOL LLFloaterTOS::postBuild() LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("tos_html"); if ( web_browser ) { +// if we are forced to send users to an external site in their system browser +// (e.g.) Linux users because of lack of media support for HTML ToS page +// remove exisiting UI and replace with a link to external page where users can accept ToS +#ifdef EXTERNAL_TOS + LLTextBox* header = getChild<LLTextBox>("tos_heading"); + if (header) + header->setVisible(false); + + LLTextBox* external_prompt = getChild<LLTextBox>("external_tos_required"); + if (external_prompt) + external_prompt->setVisible(true); + + web_browser->setVisible(false); +#else web_browser->addObserver(this); // Don't use the start_url parameter for this browser instance -- it may finish loading before we get to add our observer. @@ -95,6 +109,7 @@ BOOL LLFloaterTOS::postBuild() // All links from tos_html should be opened in external browser media_plugin->setOverrideClickTarget("_external"); } +#endif } return TRUE; @@ -102,6 +117,13 @@ BOOL LLFloaterTOS::postBuild() void LLFloaterTOS::setSiteIsAlive( bool alive ) { +// if we are forced to send users to an external site in their system browser +// (e.g.) Linux users because of lack of media support for HTML ToS page +// force the regular HTML UI to deactivate so alternative is rendered instead. +#ifdef EXTERNAL_TOS + mSiteAlive = false; +#else + mSiteAlive = alive; // only do this for TOS pages @@ -130,6 +152,7 @@ void LLFloaterTOS::setSiteIsAlive( bool alive ) tos_agreement->setEnabled( true ); } } +#endif } LLFloaterTOS::~LLFloaterTOS() diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 73faed7ef5..9cf3249983 100755 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -57,6 +57,7 @@ #include "llbutton.h" #include "llcheckboxctrl.h" #include "llnotifications.h" +#include "llnotificationsutil.h" #include "lllineeditor.h" #include "llfloaterwebcontent.h" #include "llwindowshade.h" @@ -428,6 +429,23 @@ BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask ) //////////////////////////////////////////////////////////////////////////////// // +BOOL LLMediaCtrl::handleKeyUpHere(KEY key, MASK mask) +{ + BOOL result = FALSE; + + if (mMediaSource) + { + result = mMediaSource->handleKeyUpHere(key, mask); + } + + if (!result) + result = LLPanel::handleKeyUpHere(key, mask); + + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +// void LLMediaCtrl::onVisibilityChange ( BOOL new_visibility ) { LL_INFOS() << "visibility changed to " << (new_visibility?"true":"false") << LL_ENDL; @@ -989,19 +1007,23 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) std::string uuid = self->getClickUUID(); LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << target << "\", uri is " << url << LL_ENDL; - LLNotification::Params notify_params; - notify_params.name = "PopupAttempt"; - notify_params.payload = LLSD().with("target", target).with("url", url).with("uuid", uuid).with("media_id", mMediaTextureID); - notify_params.functor.function = boost::bind(&LLMediaCtrl::onPopup, this, _1, _2); - - if (mTrusted) - { - LLNotifications::instance().forceResponse(notify_params, 0); - } - else - { - LLNotifications::instance().add(notify_params); - } + LLWeb::loadURL(url, target, std::string()); + + // CP: removing this code because we no longer support popups so this breaks the flow. + // replaced with a bare call to LLWeb::LoadURL(...) + //LLNotification::Params notify_params; + //notify_params.name = "PopupAttempt"; + //notify_params.payload = LLSD().with("target", target).with("url", url).with("uuid", uuid).with("media_id", mMediaTextureID); + //notify_params.functor.function = boost::bind(&LLMediaCtrl::onPopup, this, _1, _2); + + //if (mTrusted) + //{ + // LLNotifications::instance().forceResponse(notify_params, 0); + //} + //else + //{ + // LLNotifications::instance().add(notify_params); + //} break; }; @@ -1072,6 +1094,13 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) }; break; + case MEDIA_EVENT_FILE_DOWNLOAD: + { + //llinfos << "Media event - file download requested - filename is " << self->getFileDownloadFilename() << llendl; + //LLNotificationsUtil::add("MediaFileDownloadUnsupported"); + }; + break; + case MEDIA_EVENT_DEBUG_MESSAGE: { LL_INFOS("media") << self->getDebugMessageText() << LL_ENDL; @@ -1150,3 +1179,13 @@ void LLMediaCtrl::updateContextMenuParent(LLView* pNewParent) { mContextMenu->updateParent(pNewParent); } + +bool LLMediaCtrl::wantsKeyUpKeyDown() const +{ + return true; +} + +bool LLMediaCtrl::wantsReturnKey() const +{ + return true; +} diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h index 988733b85a..291d87073e 100755 --- a/indra/newview/llmediactrl.h +++ b/indra/newview/llmediactrl.h @@ -151,6 +151,7 @@ public: // over-rides virtual BOOL handleKeyHere( KEY key, MASK mask); + virtual BOOL handleKeyUpHere(KEY key, MASK mask); virtual void onVisibilityChange ( BOOL new_visibility ); virtual BOOL handleUnicodeCharHere(llwchar uni_char); virtual void reshape( S32 width, S32 height, BOOL called_from_parent = TRUE); @@ -171,6 +172,10 @@ public: void updateContextMenuParent(LLView* pNewParent); + // The Browser windows want keyup and keydown events. Overridden from LLFocusableElement to return true. + virtual bool wantsKeyUpKeyDown() const; + virtual bool wantsReturnKey() const; + protected: void convertInputCoords(S32& x, S32& y); diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 2081297717..4d41c792ca 100755 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -106,7 +106,7 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask) mMouseDownX = x; mMouseDownY = y; - //left mouse down always picks transparent + //left mouse down always picks transparent (but see handleMouseUp) mPick = gViewerWindow->pickImmediate(x, y, TRUE); mPick.mKeyMask = mask; @@ -661,30 +661,52 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask) && gAgentAvatarp && !gAgentAvatarp->isSitting() && !mBlockClickToWalk // another behavior hasn't cancelled click to walk - && !mPick.mPosGlobal.isExactlyZero() // valid coordinates for pick - && (mPick.mPickType == LLPickInfo::PICK_LAND // we clicked on land - || mPick.mObjectID.notNull())) // or on an object - { - // handle special cases of steering picks - LLViewerObject* avatar_object = mPick.getObject(); - - // get pointer to avatar - while (avatar_object && !avatar_object->isAvatar()) - { - avatar_object = (LLViewerObject*)avatar_object->getParent(); - } - - if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf()) - { - const F64 SELF_CLICK_WALK_DISTANCE = 3.0; - // pretend we picked some point a bit in front of avatar - mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE; - } - gAgentCamera.setFocusOnAvatar(TRUE, TRUE); - walkToClickedLocation(); - LLFirstUse::notMoving(false); - - return TRUE; + ) + { + // We may be doing click to walk, but we don't want to use a target on + // a transparent object because the user thought they were clicking on + // whatever they were seeing through it, so recompute what was clicked on + // ignoring transparent objects + LLPickInfo savedPick = mPick; + mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY, + FALSE /* ignore transparent */, + FALSE /* ignore particles */); + + if (!mPick.mPosGlobal.isExactlyZero() // valid coordinates for pick + && (mPick.mPickType == LLPickInfo::PICK_LAND // we clicked on land + || mPick.mObjectID.notNull())) // or on an object + { + // handle special cases of steering picks + LLViewerObject* avatar_object = mPick.getObject(); + + // get pointer to avatar + while (avatar_object && !avatar_object->isAvatar()) + { + avatar_object = (LLViewerObject*)avatar_object->getParent(); + } + + if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf()) + { + const F64 SELF_CLICK_WALK_DISTANCE = 3.0; + // pretend we picked some point a bit in front of avatar + mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE; + } + gAgentCamera.setFocusOnAvatar(TRUE, TRUE); + walkToClickedLocation(); + LLFirstUse::notMoving(false); + + return TRUE; + } + else + { + LL_DEBUGS("maint5901") << "walk target was " + << (mPick.mPosGlobal.isExactlyZero() ? "zero" : "not zero") + << ", pick type was " << (mPick.mPickType == LLPickInfo::PICK_LAND ? "land" : "not land") + << ", pick object was " << mPick.mObjectID + << LL_ENDL; + // we didn't click to walk, so restore the original target + mPick = savedPick; + } } gViewerWindow->setCursor(UI_CURSOR_ARROW); if (hasMouseCapture()) @@ -716,14 +738,33 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask) LL_INFOS() << "LLToolPie handleDoubleClick (becoming mouseDown)" << LL_ENDL; } + if (handleMediaDblClick(mPick)) + { + return TRUE; + } + if (gSavedSettings.getBOOL("DoubleClickAutoPilot")) { + // We may be doing double click to walk, but we don't want to use a target on + // a transparent object because the user thought they were clicking on + // whatever they were seeing through it, so recompute what was clicked on + // ignoring transparent objects + LLPickInfo savedPick = mPick; + mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY, + FALSE /* ignore transparent */, + FALSE /* ignore particles */); + if ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) || (mPick.mObjectID.notNull() && !mPick.mPosGlobal.isExactlyZero())) { walkToClickedLocation(); return TRUE; } + else + { + // restore the original pick for any other purpose + mPick = savedPick; + } } else if (gSavedSettings.getBOOL("DoubleClickTeleport")) { @@ -1404,56 +1445,110 @@ static void handle_click_action_play() bool LLToolPie::handleMediaClick(const LLPickInfo& pick) { - //FIXME: how do we handle object in different parcel than us? - LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); - LLPointer<LLViewerObject> objectp = pick.getObject(); - - - if (!parcel || - objectp.isNull() || - pick.mObjectFace < 0 || - pick.mObjectFace >= objectp->getNumTEs()) - { - LLViewerMediaFocus::getInstance()->clearFocus(); - - return false; - } - - // Does this face have media? - const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace); - if(!tep) - return false; - - LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL; - if(!mep) - return false; - - viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()); - - if (gSavedSettings.getBOOL("MediaOnAPrimUI")) - { - if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull()) - { - // It's okay to give this a null impl - LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal); - } - else - { - // Make sure keyboard focus is set to the media focus object. - gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance()); - LLEditMenuHandler::gEditMenuHandler = LLViewerMediaFocus::instance().getFocusedMediaImpl(); - - media_impl->mouseDown(pick.mUVCoords, gKeyboard->currentMask(TRUE)); - mMediaMouseCaptureID = mep->getMediaID(); - setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture. - } - - return true; - } - - LLViewerMediaFocus::getInstance()->clearFocus(); + //FIXME: how do we handle object in different parcel than us? + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + LLPointer<LLViewerObject> objectp = pick.getObject(); + + + if (!parcel || + objectp.isNull() || + pick.mObjectFace < 0 || + pick.mObjectFace >= objectp->getNumTEs()) + { + LLViewerMediaFocus::getInstance()->clearFocus(); + + return false; + } + + // Does this face have media? + const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace); + if (!tep) + return false; + + LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL; + if (!mep) + return false; + + viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()); + + if (gSavedSettings.getBOOL("MediaOnAPrimUI")) + { + if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull()) + { + // It's okay to give this a null impl + LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal); + } + else + { + // Make sure keyboard focus is set to the media focus object. + gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance()); + LLEditMenuHandler::gEditMenuHandler = LLViewerMediaFocus::instance().getFocusedMediaImpl(); + + media_impl->mouseDown(pick.mUVCoords, gKeyboard->currentMask(TRUE)); + mMediaMouseCaptureID = mep->getMediaID(); + setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture. + } + + return true; + } + + LLViewerMediaFocus::getInstance()->clearFocus(); + + return false; +} - return false; +bool LLToolPie::handleMediaDblClick(const LLPickInfo& pick) +{ + //FIXME: how do we handle object in different parcel than us? + LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); + LLPointer<LLViewerObject> objectp = pick.getObject(); + + + if (!parcel || + objectp.isNull() || + pick.mObjectFace < 0 || + pick.mObjectFace >= objectp->getNumTEs()) + { + LLViewerMediaFocus::getInstance()->clearFocus(); + + return false; + } + + // Does this face have media? + const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace); + if (!tep) + return false; + + LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL; + if (!mep) + return false; + + viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()); + + if (gSavedSettings.getBOOL("MediaOnAPrimUI")) + { + if (!LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) || media_impl.isNull()) + { + // It's okay to give this a null impl + LLViewerMediaFocus::getInstance()->setFocusFace(pick.getObject(), pick.mObjectFace, media_impl, pick.mNormal); + } + else + { + // Make sure keyboard focus is set to the media focus object. + gFocusMgr.setKeyboardFocus(LLViewerMediaFocus::getInstance()); + LLEditMenuHandler::gEditMenuHandler = LLViewerMediaFocus::instance().getFocusedMediaImpl(); + + media_impl->mouseDoubleClick(pick.mUVCoords, gKeyboard->currentMask(TRUE)); + mMediaMouseCaptureID = mep->getMediaID(); + setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture. + } + + return true; + } + + LLViewerMediaFocus::getInstance()->clearFocus(); + + return false; } bool LLToolPie::handleMediaHover(const LLPickInfo& pick) diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h index 68fe8bc4a5..c4a2f4a35b 100755 --- a/indra/newview/lltoolpie.h +++ b/indra/newview/lltoolpie.h @@ -88,7 +88,8 @@ private: ECursorType cursorFromObject(LLViewerObject* object); bool handleMediaClick(const LLPickInfo& info); - bool handleMediaHover(const LLPickInfo& info); + bool handleMediaDblClick(const LLPickInfo& info); + bool handleMediaHover(const LLPickInfo& info); bool handleMediaMouseUp(); BOOL handleTooltipLand(std::string line, std::string tooltip_msg); BOOL handleTooltipObject( LLViewerObject* hover_object, std::string line, std::string tooltip_msg); diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp index ada829eb4b..1ab672aafc 100755 --- a/indra/newview/llviewerkeyboard.cpp +++ b/indra/newview/llviewerkeyboard.cpp @@ -729,7 +729,10 @@ BOOL LLViewerKeyboard::handleKey(KEY translated_key, MASK translated_mask, BOOL return mKeyHandledByUI[translated_key]; } - +BOOL LLViewerKeyboard::handleKeyUp(KEY translated_key, MASK translated_mask) +{ + return gViewerWindow->handleKeyUp(translated_key, translated_mask); +} BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name) { diff --git a/indra/newview/llviewerkeyboard.h b/indra/newview/llviewerkeyboard.h index ca73212ed1..110dc89d28 100755 --- a/indra/newview/llviewerkeyboard.h +++ b/indra/newview/llviewerkeyboard.h @@ -89,6 +89,7 @@ public: LLViewerKeyboard(); BOOL handleKey(KEY key, MASK mask, BOOL repeated); + BOOL handleKeyUp(KEY key, MASK mask); S32 loadBindings(const std::string& filename); // returns number bound, 0 on error S32 loadBindingsXML(const std::string& filename); // returns number bound, 0 on error diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 4e8fa28b86..014cf5a6bf 100755 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -5,21 +5,21 @@ * $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$ */ @@ -66,6 +66,7 @@ #include "llvoavatar.h" #include "llvoavatarself.h" #include "llvovolume.h" +#include "llfloaterreg.h" #include "llwebprofile.h" #include "llwindow.h" #include "llvieweraudio.h" @@ -181,7 +182,7 @@ 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) @@ -208,8 +209,8 @@ static bool sViewerMediaMuteListObserverInitialized = false; // static viewer_media_t LLViewerMedia::newMediaImpl( const LLUUID& texture_id, - S32 media_width, - S32 media_height, + S32 media_width, + S32 media_height, U8 media_auto_scale, U8 media_loop) { @@ -233,24 +234,24 @@ viewer_media_t LLViewerMedia::newMediaImpl( } 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()); - - LL_DEBUGS() << "called, current URL is \"" << media_entry->getCurrentURL() - << "\", previous URL is \"" << previous_url + + LL_DEBUGS() << "called, current URL is \"" << media_entry->getCurrentURL() + << "\", previous URL is \"" << previous_url << "\", update_from_self is " << (update_from_self?"true":"false") << LL_ENDL; - + 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(); @@ -263,7 +264,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s 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()) { @@ -271,7 +272,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s { // The current media URL is now empty. Unload the media source. media_impl->unload(); - + LL_DEBUGS() << "Unloading media instance (new current URL is empty)." << LL_ENDL; } } @@ -280,26 +281,26 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s // 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(); + bool auto_play = media_impl->isAutoPlayable(); if((was_loaded || auto_play) && !update_from_self) { needs_navigate = url_changed; } - - LL_DEBUGS() << "was_loaded is " << (was_loaded?"true":"false") - << ", auto_play is " << (auto_play?"true":"false") + + LL_DEBUGS() << "was_loaded is " << (was_loaded?"true":"false") + << ", auto_play is " << (auto_play?"true":"false") << ", needs_navigate is " << (needs_navigate?"true":"false") << LL_ENDL; } } else { media_impl = newMediaImpl( - media_entry->getMediaID(), + media_entry->getMediaID(), media_entry->getWidthPixels(), - media_entry->getHeightPixels(), - media_entry->getAutoScale(), + 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(); @@ -308,7 +309,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s needs_navigate = true; } } - + if(media_impl) { if(needs_navigate) @@ -327,7 +328,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s LL_DEBUGS() << "updating URL in the media impl to " << media_impl->mMediaEntryURL << LL_ENDL; } } - + return media_impl; } @@ -336,7 +337,7 @@ viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const s 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()) @@ -351,7 +352,7 @@ LLViewerMediaImpl* LLViewerMedia::getMediaImplFromTextureID(const LLUUID& textur // static std::string LLViewerMedia::getCurrentUserAgent() { - // Don't use user-visible string to avoid + // Don't use user-visible string to avoid // punctuation and strange characters. std::string skin_name = gSavedSettings.getString("SkinCurrent"); @@ -370,7 +371,7 @@ std::string LLViewerMedia::getCurrentUserAgent() codec << LLVersionInfo::getVersion(); codec << " (" << channel << "; " << skin_name << " skin)"; LL_INFOS() << codec.str() << LL_ENDL; - + return codec.str(); } @@ -379,7 +380,7 @@ std::string LLViewerMedia::getCurrentUserAgent() void LLViewerMedia::updateBrowserUserAgent() { std::string user_agent = getCurrentUserAgent(); - + impl_list::iterator iter = sViewerMediaImplList.begin(); impl_list::iterator end = sViewerMediaImplList.end(); @@ -468,7 +469,7 @@ void LLViewerMedia::muteListChanged() bool LLViewerMedia::isInterestingEnough(const LLVOVolume *object, const F64 &object_interest) { bool result = false; - + if (NULL == object) { result = false; @@ -484,13 +485,13 @@ bool LLViewerMedia::isInterestingEnough(const LLVOVolume *object, const F64 &obj { result = true; } - else + else { LL_DEBUGS() << "object interest = " << object_interest << ", lowest loadable = " << sLowestLoadableImplInterest << LL_ENDL; if(object_interest >= sLowestLoadableImplInterest) result = true; } - + return result; } @@ -597,13 +598,13 @@ static LLTrace::BlockTimerStatHandle FTM_MEDIA_MISC("Misc"); void LLViewerMedia::updateMedia(void *dummy_arg) { LL_RECORD_BLOCK_TIME(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()) @@ -611,7 +612,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) LL_DEBUGS() << "updated cookies will be sent to all loaded plugins: " << LL_ENDL; LL_DEBUGS() << sUpdatedCookies << LL_ENDL; } - + impl_list::iterator iter = sViewerMediaImplList.begin(); impl_list::iterator end = sViewerMediaImplList.end(); @@ -624,14 +625,14 @@ void LLViewerMedia::updateMedia(void *dummy_arg) pimpl->calculateInterest(); } } - + // Let the spare media source actually launch if(sSpareBrowserMediaSource) { LL_RECORD_BLOCK_TIME(FTM_MEDIA_SPARE_IDLE); sSpareBrowserMediaSource->idle(); } - + { LL_RECORD_BLOCK_TIME(FTM_MEDIA_SORT); // Sort the static instance list using our interest criteria @@ -641,14 +642,14 @@ void LLViewerMedia::updateMedia(void *dummy_arg) // 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"); @@ -657,19 +658,19 @@ void LLViewerMedia::updateMedia(void *dummy_arg) 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. - + { LL_RECORD_BLOCK_TIME(FTM_MEDIA_MISC); for(; iter != end; iter++) { LLViewerMediaImpl* pimpl = *iter; - + LLPluginClassMedia::EPriority new_priority = LLPluginClassMedia::PRIORITY_NORMAL; if(pimpl->isForcedUnloaded() || (impl_count_total >= (int)max_instances)) @@ -700,7 +701,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) 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; @@ -714,7 +715,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) { 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. @@ -736,11 +737,11 @@ void LLViewerMedia::updateMedia(void *dummy_arg) // 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 = (F32) sqrt(pimpl->getInterest()); - + pimpl->setLowPrioritySizeLimit(ll_round(approximate_interest_dimension)); } } @@ -750,18 +751,18 @@ void LLViewerMedia::updateMedia(void *dummy_arg) 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? */ + if (!gViewerWindow->getActive() /* viewer window minimized? */ && new_priority > LLPluginClassMedia::PRIORITY_HIDDEN) { new_priority = LLPluginClassMedia::PRIORITY_HIDDEN; @@ -771,7 +772,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) { new_priority = LLPluginClassMedia::PRIORITY_LOW; } - + if(!inworld_media_enabled) { // If inworld media is locked out, force all inworld media to stay unloaded. @@ -789,7 +790,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) } } pimpl->setPriority(new_priority); - + if(pimpl->getUsedInUI()) { // Any impls used in the UI should not be in the proximity list. @@ -801,7 +802,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) } total_cpu += pimpl->getCPUUsage(); - + if (!pimpl->getUsedInUI() && pimpl->hasMedia()) { sAnyMediaShowing = true; @@ -825,7 +826,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) sLowestLoadableImplInterest = object->getPixelArea(); } } - + if(gSavedSettings.getBOOL("MediaPerformanceManagerDebug")) { // Give impls the same ordering as the priority list @@ -834,7 +835,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) else { LL_RECORD_BLOCK_TIME(FTM_MEDIA_SORT2); - // Use a distance-based sort for proximity values. + // Use a distance-based sort for proximity values. std::stable_sort(proximity_order.begin(), proximity_order.end(), proximity_comparitor); } @@ -843,7 +844,7 @@ void LLViewerMedia::updateMedia(void *dummy_arg) { proximity_order[i]->mProximity = i; } - + LL_DEBUGS("PluginPriority") << "Total reported CPU usage is " << total_cpu << LL_ENDL; } @@ -862,11 +863,11 @@ 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 + + // Then impl_list::iterator iter = sViewerMediaImplList.begin(); impl_list::iterator end = sViewerMediaImplList.end(); - + for(; iter != end; iter++) { LLViewerMediaImpl* pimpl = *iter; @@ -875,18 +876,18 @@ void LLViewerMedia::setAllMediaEnabled(bool val) 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 && + gAudiop && LLViewerMedia::hasParcelAudio()) { if (LLAudioEngine::AUDIO_PAUSED == gAudiop->isInternetStreamPlaying()) @@ -959,26 +960,26 @@ void LLViewerMedia::clearAllCookies() 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; - + LL_DEBUGS() << "base dir = " << base_dir << LL_ENDL; // The non-logged-in version is easy @@ -991,7 +992,7 @@ void LLViewerMedia::clearAllCookies() { 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)) @@ -1001,26 +1002,26 @@ void LLViewerMedia::clearAllCookies() gDirUtilp->append(target, "cookies"); LL_DEBUGS() << "target = " << target << LL_ENDL; if(LLFile::isfile(target)) - { + { LLFile::remove(target); } - + // Other accounts may have new-style cookie files too -- delete them as well target = gDirUtilp->add(base_dir, filename); gDirUtilp->append(target, PLUGIN_COOKIE_FILE_NAME); LL_DEBUGS() << "target = " << target << LL_ENDL; if(LLFile::isfile(target)) - { + { LLFile::remove(target); } } - + // If we have an OpenID cookie, re-add it to the cookie store. - setOpenIDCookie(); + setOpenIDCookie(std::string()); } - + ///////////////////////////////////////////////////////////////////////////////////////// -// static +// static void LLViewerMedia::clearAllCaches() { // Clear all plugins' caches @@ -1032,9 +1033,9 @@ void LLViewerMedia::clearAllCaches() pimpl->clearCache(); } } - + ///////////////////////////////////////////////////////////////////////////////////////// -// static +// static void LLViewerMedia::setCookiesEnabled(bool enabled) { // Set the "cookies enabled" flag for all loaded plugins @@ -1049,9 +1050,9 @@ void LLViewerMedia::setCookiesEnabled(bool enabled) } } } - + ///////////////////////////////////////////////////////////////////////////////////////// -// static +// static void LLViewerMedia::setProxyConfig(bool enable, const std::string &host, int port) { // Set the proxy config for all loaded plugins @@ -1068,7 +1069,7 @@ void LLViewerMedia::setProxyConfig(bool enable, const std::string &host, int por } ///////////////////////////////////////////////////////////////////////////////////////// -// static +// static ///////////////////////////////////////////////////////////////////////////////////////// // static LLPluginCookieStore *LLViewerMedia::getCookieStore() @@ -1077,7 +1078,7 @@ LLPluginCookieStore *LLViewerMedia::getCookieStore() { sCookieStore = new LLPluginCookieStore; } - + return sCookieStore; } @@ -1093,7 +1094,7 @@ void LLViewerMedia::loadCookieFile() LL_INFOS() << "can't get path to plugin cookie file - probably not logged in yet." << LL_ENDL; return; } - + // open the file for reading llifstream file(resolved_filename.c_str()); if (!file.is_open()) @@ -1101,11 +1102,11 @@ void LLViewerMedia::loadCookieFile() LL_WARNS() << "can't load plugin cookies from file \"" << PLUGIN_COOKIE_FILE_NAME << "\"" << LL_ENDL; 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(); @@ -1117,9 +1118,9 @@ void LLViewerMedia::loadCookieFile() pimpl->mMediaSource->clear_cookies(); } } - + // If we have an OpenID cookie, re-add it to the cookie store. - setOpenIDCookie(); + setOpenIDCookie(std::string()); } @@ -1154,23 +1155,23 @@ void LLViewerMedia::saveCookieFile() 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()); } @@ -1187,7 +1188,7 @@ void LLViewerMedia::addSessionCookie(const std::string &name, const std::string 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); } @@ -1205,6 +1206,30 @@ LLSD LLViewerMedia::getHeaders() return headers; } + ///////////////////////////////////////////////////////////////////////////////////////// + // static +bool LLViewerMedia::parseRawCookie(const std::string raw_cookie, std::string& name, std::string& value, std::string& path, bool& httponly, bool& secure) +{ + std::size_t name_pos = raw_cookie.find_first_of("="); + if (name_pos != std::string::npos) + { + name = raw_cookie.substr(0, name_pos); + std::size_t value_pos = raw_cookie.find_first_of(";", name_pos); + if (value_pos != std::string::npos) + { + value = raw_cookie.substr(name_pos + 1, value_pos - name_pos - 1); + path = "/"; // assume root path for now + + httponly = true; // hard coded for now + secure = true; + + return true; + } + } + + return false; +} + LLCore::HttpHeaders::ptr_t LLViewerMedia::getHttpHeaders() { LLCore::HttpHeaders::ptr_t headers(new LLCore::HttpHeaders); @@ -1217,9 +1242,10 @@ LLCore::HttpHeaders::ptr_t LLViewerMedia::getHttpHeaders() return headers; } + ///////////////////////////////////////////////////////////////////////////////////////// // static -void LLViewerMedia::setOpenIDCookie() +void LLViewerMedia::setOpenIDCookie(const std::string& url) { if(!sOpenIDCookie.empty()) { @@ -1260,6 +1286,7 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url) } else { // Hostname starts after the @. + // 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.) ++hostStart; } @@ -1271,7 +1298,30 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url) getCookieStore()->setCookiesFromHost(sOpenIDCookie, authority.substr(hostStart, hostEnd - hostStart)); - // Do a web profile get so we can store the cookie + if (url.length()) + { + LLMediaCtrl* media_instance = LLFloaterReg::getInstance("destinations")->getChild<LLMediaCtrl>("destination_guide_contents"); + if (media_instance) + { + std::string cookie_host = authority.substr(hostStart, hostEnd - hostStart); + std::string cookie_name = ""; + std::string cookie_value = ""; + std::string cookie_path = ""; + bool httponly = true; + bool secure = true; + if (parseRawCookie(sOpenIDCookie, cookie_name, cookie_value, cookie_path, httponly, secure) && + media_instance->getMediaPlugin()) + { + media_instance->getMediaPlugin()->setCookie(url, cookie_name, cookie_value, cookie_host, cookie_path, httponly, secure); + } + } + } + + // NOTE: this is the original OpenID cookie code, so of which is no longer needed now that we + // are using CEF - it's very intertwined with other code so, for the moment, I'm going to + // leave it alone and make a task to come back to it once we're sure the CEF cookie code is robust. + + // Do a web profile get so we can store the cookie httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, "*/*"); httpHeaders->append(HTTP_OUT_HEADER_COOKIE, sOpenIDCookie); httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, getCurrentUserAgent()); @@ -1332,10 +1382,11 @@ void LLViewerMedia::openIDSetupCoro(std::string openidUrl, std::string openidTok httpOpts->setWantHeaders(true); - // post the token to the url + // 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(openidUrl.c_str()); + // We shouldn't ever do this twice, but just in case this code gets repurposed later, clear existing cookies. sOpenIDCookie.clear(); @@ -1366,22 +1417,23 @@ void LLViewerMedia::openIDSetupCoro(std::string openidUrl, std::string openidTok } // We don't care about the content of the response, only the Set-Cookie header. - const std::string &cookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE]; + const std::string& cookie = resultHeaders[HTTP_IN_HEADER_SET_COOKIE].asString(); - // *TODO: What about bad status codes? Does this destroy previous cookies? - LLViewerMedia::openIDCookieResponse(cookie); + // *TODO: What about bad status codes? Does this destroy previous cookies? + LLViewerMedia::openIDCookieResponse(openidUrl, cookie); LL_DEBUGS("MediaAuth") << "OpenID cookie set." << LL_ENDL; + } ///////////////////////////////////////////////////////////////////////////////////////// // static -void LLViewerMedia::openIDCookieResponse(const std::string &cookie) +void LLViewerMedia::openIDCookieResponse(const std::string& url, const std::string &cookie) { LL_DEBUGS("MediaAuth") << "Cookie received: \"" << cookie << "\"" << LL_ENDL; - + sOpenIDCookie += cookie; - setOpenIDCookie(); + setOpenIDCookie(url); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -1390,7 +1442,7 @@ void LLViewerMedia::proxyWindowOpened(const std::string &target, const std::stri { if(uuid.empty()) return; - + for (impl_list::iterator iter = sViewerMediaImplList.begin(); iter != sViewerMediaImplList.end(); iter++) { if((*iter)->mMediaSource && (*iter)->mMediaSource->pluginSupportsMediaBrowser()) @@ -1427,7 +1479,7 @@ void LLViewerMedia::createSpareBrowserMediaSource() 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, + // (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(HTTP_CONTENT_TEXT_HTML, NULL, 0, 0); } @@ -1439,7 +1491,7 @@ LLPluginClassMedia* LLViewerMedia::getSpareBrowserMediaSource() { LLPluginClassMedia* result = sSpareBrowserMediaSource; sSpareBrowserMediaSource = NULL; - return result; + return result; }; bool LLViewerMedia::hasInWorldMedia() @@ -1528,12 +1580,12 @@ void LLViewerMedia::setOnlyAudibleMediaTextureID(const LLUUID& texture_id) ////////////////////////////////////////////////////////////////////////////////////////// // LLViewerMediaImpl ////////////////////////////////////////////////////////////////////////////////////////// -LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id, - S32 media_width, - S32 media_height, - U8 media_auto_scale, +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), @@ -1583,11 +1635,11 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id, 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); @@ -1602,7 +1654,7 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id, LLViewerMediaImpl::~LLViewerMediaImpl() { destroyMediaSource(); - + LLViewerMediaTexture::removeMediaImplFromTexture(mTextureId) ; setTextureID(); @@ -1614,7 +1666,7 @@ void LLViewerMediaImpl::emitEvent(LLPluginClassMedia* plugin, LLViewerMediaObser { // 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()) @@ -1630,7 +1682,7 @@ 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. @@ -1653,7 +1705,7 @@ void LLViewerMediaImpl::createMediaSource() // This media shouldn't be created yet. return; } - + if(! mMediaURL.empty()) { navigateInternal(); @@ -1679,15 +1731,15 @@ void LLViewerMediaImpl::destroyMediaSource() { oldImage->setPlaying(FALSE) ; } - + cancelMimeTypeProbe(); - + if(mMediaSource) { mMediaSource->setDeleteOK(true) ; delete mMediaSource; mMediaSource = NULL; - } + } } ////////////////////////////////////////////////////////////////////////////////////////// @@ -1702,11 +1754,11 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ { 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. // Do not use a spare if launching with full viewer control (e.g. Facebook, Twitter and few others) - if ((plugin_basename == "media_plugin_webkit") && + if ((plugin_basename == "media_plugin_cef") && !gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins") && !clean_browser) { media_source = LLViewerMedia::getSpareBrowserMediaSource(); @@ -1715,7 +1767,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ media_source->setOwner(owner); media_source->setTarget(target); media_source->setSize(default_width, default_height); - + return media_source; } } @@ -1727,8 +1779,12 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ { 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(); + + std::string user_data_path_cache = gDirUtilp->getCacheDir(false); + user_data_path_cache += gDirUtilp->getDirDelimiter(); + + std::string user_data_path_cookies = gDirUtilp->getOSUserAppDir(); + user_data_path_cookies += 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 @@ -1739,8 +1795,8 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ 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(); + user_data_path_cookies = linden_user_dir; + user_data_path_cookies += gDirUtilp->getDirDelimiter(); }; // See if the plugin executable exists @@ -1757,7 +1813,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ { media_source = new LLPluginClassMedia(owner); media_source->setSize(default_width, default_height); - media_source->setUserDataPath(user_data_path); + media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies); media_source->setLanguageCode(LLUI::getLanguage()); // collect 'cookies enabled' setting from prefs and send to embedded browser @@ -1771,12 +1827,15 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ // collect 'javascript enabled' setting from prefs and send to embedded browser bool javascript_enabled = gSavedSettings.getBOOL( "BrowserJavascriptEnabled" ); media_source->setJavascriptEnabled( javascript_enabled || clean_browser); - + bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging"); media_source->enableMediaPluginDebugging( media_plugin_debugging_enabled || clean_browser); + // need to set agent string here before instance created + media_source->setBrowserUserAgent(LLViewerMedia::getCurrentUserAgent()); + media_source->setTarget(target); - + const std::string plugin_dir = gDirUtilp->getLLPluginDir(); if (media_source->init(launcher_name, plugin_dir, plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins"))) { @@ -1789,14 +1848,14 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_ } } } - + LL_WARNS_ONCE("Plugin") << "plugin initialization 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) @@ -1807,10 +1866,10 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) mMediaWidth = mMediaSource->getSetWidth(); mMediaHeight = mMediaSource->getSetHeight(); } - + // Always delete the old media impl first. destroyMediaSource(); - + // and unconditionally set the mime type mMimeType = media_type; @@ -1818,7 +1877,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) { // This impl should not be loaded at this time. LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL; - + return false; } @@ -1829,7 +1888,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) mCurrentMimeType = mMimeType; LLPluginClassMedia* media_source = newSourceFromMediaType(mMimeType, this, mMediaWidth, mMediaHeight, mTarget, mCleanBrowser); - + if (media_source) { media_source->setDisableTimeout(gSavedSettings.getBOOL("DebugPluginDisableTimeout")); @@ -1838,7 +1897,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) media_source->setBrowserUserAgent(LLViewerMedia::getCurrentUserAgent()); media_source->focus(mHasFocus); media_source->setBackgroundColor(mBackgroundColor); - + if(gSavedSettings.getBOOL("BrowserIgnoreSSLCertErrors")) { media_source->ignore_ssl_cert_errors(true); @@ -1846,19 +1905,19 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) // 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 + // 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, @@ -1869,7 +1928,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type) { media_source->set_cookies(all_cookies); } - + mMediaSource = media_source; mMediaSource->setDeleteOK(false) ; updateVolume(); @@ -1912,16 +1971,16 @@ void LLViewerMediaImpl::loadURI() std::string sanitized_uri = (u.query().empty() ? uri : u.scheme() + "://" + u.authority() + u.path()); LL_INFOS() << "Asking media source to load URI: " << sanitized_uri << LL_ENDL; } - + mMediaSource->loadURI( uri ); - - // A non-zero mPreviousMediaTime means that either this media was previously unloaded by the priority code while playing/paused, + + // 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. @@ -1974,11 +2033,11 @@ void LLViewerMediaImpl::play() // 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(); } @@ -2079,10 +2138,10 @@ void LLViewerMediaImpl::updateVolume() { if(mMediaSource) { - // always scale the volume by the global media volume + // always scale the volume by the global media volume F32 volume = mRequestedVolume * LLViewerMedia::getVolume(); - if (mProximityCamera > 0) + if (mProximityCamera > 0) { if (mProximityCamera > gSavedSettings.getF32("MediaRollOffMax")) { @@ -2121,7 +2180,7 @@ F32 LLViewerMediaImpl::getVolume() 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 @@ -2149,7 +2208,7 @@ std::string LLViewerMediaImpl::getCurrentMediaURL() { return mCurrentMediaURL; } - + return mMediaURL; } @@ -2217,17 +2276,17 @@ void LLViewerMediaImpl::mouseMove(S32 x, S32 y, MASK mask) } ////////////////////////////////////////////////////////////////////////////////////////// -//static +//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; @@ -2255,7 +2314,7 @@ void LLViewerMediaImpl::mouseDown(const LLVector2& texture_coords, MASK mask, S3 void LLViewerMediaImpl::mouseUp(const LLVector2& texture_coords, MASK mask, S32 button) { if(mMediaSource) - { + { S32 x, y; scaleTextureCoords(texture_coords, &x, &y); @@ -2266,7 +2325,7 @@ void LLViewerMediaImpl::mouseUp(const LLVector2& texture_coords, MASK mask, S32 void LLViewerMediaImpl::mouseMove(const LLVector2& texture_coords, MASK mask) { if(mMediaSource) - { + { S32 x, y; scaleTextureCoords(texture_coords, &x, &y); @@ -2274,6 +2333,17 @@ void LLViewerMediaImpl::mouseMove(const LLVector2& texture_coords, MASK mask) } } +void LLViewerMediaImpl::mouseDoubleClick(const LLVector2& texture_coords, MASK mask) +{ + if (mMediaSource) + { + S32 x, y; + scaleTextureCoords(texture_coords, &x, &y); + + mouseDoubleClick(x, y, mask); + } +} + ////////////////////////////////////////////////////////////////////////////////////////// void LLViewerMediaImpl::mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button) { @@ -2308,18 +2378,18 @@ void LLViewerMediaImpl::onMouseCaptureLost() } ////////////////////////////////////////////////////////////////////////////////////////// -BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask) -{ +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; + return TRUE; } ////////////////////////////////////////////////////////////////////////////////////////// @@ -2395,14 +2465,14 @@ void LLViewerMediaImpl::updateJavascriptObject() } ////////////////////////////////////////////////////////////////////////////////////////// -const std::string& LLViewerMediaImpl::getName() const -{ +const std::string& LLViewerMediaImpl::getName() const +{ if (mMediaSource) { return mMediaSource->getMediaName(); } - - return LLStringUtil::null; + + return LLStringUtil::null; }; ////////////////////////////////////////////////////////////////////////////////////////// @@ -2458,21 +2528,21 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi // Don't carry media play state across distinct URLs. resetPreviousMediaState(); } - + // Always set the current URL and MIME type. mMediaURL = url; mMimeType = mime_type; mCleanBrowser = clean_browser; - + // 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; @@ -2488,7 +2558,7 @@ void LLViewerMediaImpl::navigateTo(const std::string& url, const std::string& mi // This impl should not be loaded at this time. LL_DEBUGS("PluginPriority") << this << "Not loading (PRIORITY_UNLOADED)" << LL_ENDL; - + return; } @@ -2519,7 +2589,7 @@ void LLViewerMediaImpl::navigateInternal() LL_WARNS() << "MIME type probe already in progress -- bailing out." << LL_ENDL; return; } - + if(mNavigateServerRequest) { setNavState(MEDIANAVSTATE_SERVER_SENT); @@ -2528,12 +2598,12 @@ void LLViewerMediaImpl::navigateInternal() { 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); @@ -2671,27 +2741,47 @@ void LLViewerMediaImpl::navigateStop() 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 && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END) + if (MASK_CONTROL & mask && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END) { result = true; } - - if(!result) + + if (!result) + { + LLSD native_key_data = gViewerWindow->getWindow()->getNativeKeyData(); + result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_DOWN, key, mask, native_key_data); + } + } + + return result; +} + +////////////////////////////////////////////////////////////////////////////////////////// +bool LLViewerMediaImpl::handleKeyUpHere(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 && key != KEY_LEFT && key != KEY_RIGHT && key != KEY_HOME && key != KEY_END) + { + 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); + result = mMediaSource->keyEvent(LLPluginClassMedia::KEY_EVENT_UP, key, mask, native_key_data); } } - + return result; } @@ -2699,7 +2789,7 @@ bool LLViewerMediaImpl::handleKeyHere(KEY key, MASK mask) bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char) { bool result = false; - + if (mMediaSource) { // only accept 'printable' characters, sigh... @@ -2707,11 +2797,11 @@ bool LLViewerMediaImpl::handleUnicodeCharHere(llwchar uni_char) && 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; } @@ -2790,15 +2880,15 @@ void LLViewerMediaImpl::update() } } - + 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); @@ -2807,7 +2897,7 @@ void LLViewerMediaImpl::update() { return; } - + if(mMediaSource->isPluginExited()) { resetPreviousMediaState(); @@ -2819,18 +2909,18 @@ void LLViewerMediaImpl::update() { 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); @@ -2841,7 +2931,7 @@ void LLViewerMediaImpl::update() 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) { @@ -2854,21 +2944,21 @@ void LLViewerMediaImpl::update() // Offset the pixels pointer to match x_pos and y_pos data += ( x_pos * mMediaSource->getTextureDepth() * mMediaSource->getBitsWidth() ); data += ( y_pos * mMediaSource->getTextureDepth() ); - + { LL_RECORD_BLOCK_TIME(FTM_MEDIA_SET_SUBIMAGE); placeholder_image->setSubImage( - data, - mMediaSource->getBitsWidth(), + data, + mMediaSource->getBitsWidth(), mMediaSource->getBitsHeight(), - x_pos, - y_pos, - width, + x_pos, + y_pos, + width, height); } } - + mMediaSource->resetDirty(); } } @@ -2889,10 +2979,10 @@ LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage() // The code that created this instance will read from the plugin's bits. return NULL; } - + LLViewerMediaTexture* placeholder_image = LLViewerTextureManager::getMediaTexture( mTextureId ); - - if (mNeedsNewTexture + + if (mNeedsNewTexture || placeholder_image->getUseMipMaps() || (placeholder_image->getWidth() != mMediaSource->getTextureWidth()) || (placeholder_image->getHeight() != mMediaSource->getTextureHeight()) @@ -2906,7 +2996,7 @@ LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage() 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? @@ -2932,13 +3022,13 @@ LLViewerMediaTexture* LLViewerMediaImpl::updatePlaceholderImage() // 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, + + // 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; } @@ -2953,14 +3043,14 @@ LLUUID LLViewerMediaImpl::getMediaTextureID() const void LLViewerMediaImpl::setVisible(bool visible) { mVisible = visible; - + if(mVisible) { if(mMediaSource && mMediaSource->isPluginExited()) { destroyMediaSource(); } - + if(!mMediaSource) { createMediaSource(); @@ -2994,12 +3084,12 @@ void LLViewerMediaImpl::scaleMouse(S32 *mouse_x, S32 *mouse_y) bool LLViewerMediaImpl::isMediaTimeBased() { bool result = false; - + if(mMediaSource) { result = mMediaSource->pluginSupportsMediaTime(); } - + return result; } @@ -3007,14 +3097,14 @@ bool LLViewerMediaImpl::isMediaTimeBased() bool LLViewerMediaImpl::isMediaPlaying() { bool result = false; - + if(mMediaSource) { EMediaStatus status = mMediaSource->getStatus(); if(status == MEDIA_PLAYING || status == MEDIA_LOADING) result = true; } - + return result; } ////////////////////////////////////////////////////////////////////////////////////////// @@ -3027,7 +3117,7 @@ bool LLViewerMediaImpl::isMediaPaused() if(mMediaSource->getStatus() == MEDIA_PAUSED) result = true; } - + return result; } @@ -3055,7 +3145,7 @@ void LLViewerMediaImpl::setDisabled(bool disabled, bool forcePlayOnEnable) { // Only do this on actual state transitions. mIsDisabled = disabled; - + if(mIsDisabled) { // We just disabled this media. Clear all state. @@ -3081,13 +3171,13 @@ bool LLViewerMediaImpl::isForcedUnloaded() const { return true; } - + // If this media's class is not supposed to be shown, unload if (!shouldShowBasedOnClass()) { return true; } - + return false; } @@ -3100,19 +3190,19 @@ bool LLViewerMediaImpl::isPlayable() const // 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; } @@ -3124,7 +3214,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla { case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: { - LL_DEBUGS("Media") << "MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is: " << plugin->getClickURL() << LL_ENDL; + 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); @@ -3143,7 +3233,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla // 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); @@ -3165,13 +3255,13 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla //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") @@ -3187,6 +3277,13 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla } break; + case LLViewerMediaObserver::MEDIA_EVENT_FILE_DOWNLOAD: + { + //llinfos << "Media event - file download requested - filename is " << self->getFileDownloadFilename() << llendl; + LLNotificationsUtil::add("MediaFileDownloadUnsupported"); + } + break; + case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_BEGIN: { LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_BEGIN, uri is: " << plugin->getNavigateURI() << LL_ENDL; @@ -3232,7 +3329,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla } } break; - + case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED: { LL_DEBUGS("Media") << "MEDIA_EVENT_LOCATION_CHANGED, uri is: " << plugin->getLocation() << LL_ENDL; @@ -3269,15 +3366,15 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla { // 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; @@ -3433,7 +3530,7 @@ void LLViewerMediaImpl::calculateInterest() { LL_RECORD_BLOCK_TIME(FTM_MEDIA_CALCULATE_INTEREST); LLViewerMediaTexture* texture = LLViewerTextureManager::findMediaTexture( mTextureId ); - + if(texture != NULL) { mInterest = texture->getMaxVirtualSize(); @@ -3443,7 +3540,7 @@ void LLViewerMediaImpl::calculateInterest() // 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; @@ -3453,7 +3550,7 @@ void LLViewerMediaImpl::calculateInterest() 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()) { @@ -3466,12 +3563,12 @@ void LLViewerMediaImpl::calculateInterest() 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) { @@ -3498,7 +3595,7 @@ void LLViewerMediaImpl::calculateInterest() } } } - + mNeedsMuteCheck = false; } } @@ -3506,7 +3603,7 @@ void LLViewerMediaImpl::calculateInterest() F64 LLViewerMediaImpl::getApproximateTextureInterest() { F64 result = 0.0f; - + if(mMediaSource) { result = mMediaSource->getFullWidth(); @@ -3524,8 +3621,8 @@ F64 LLViewerMediaImpl::getApproximateTextureInterest() void LLViewerMediaImpl::setUsedInUI(bool used_in_ui) { - mUsedInUI = 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)) @@ -3545,7 +3642,7 @@ void LLViewerMediaImpl::setUsedInUI(bool used_in_ui) void LLViewerMediaImpl::setBackgroundColor(LLColor4 color) { - mBackgroundColor = color; + mBackgroundColor = color; if(mMediaSource) { @@ -3556,12 +3653,12 @@ void LLViewerMediaImpl::setBackgroundColor(LLColor4 color) F64 LLViewerMediaImpl::getCPUUsage() const { F64 result = 0.0f; - + if(mMediaSource) { result = mMediaSource->getCPUUsage(); } - + return result; } @@ -3575,19 +3672,19 @@ void LLViewerMediaImpl::setPriority(LLPluginClassMedia::EPriority priority) << " 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(); } } @@ -3596,7 +3693,7 @@ void LLViewerMediaImpl::setPriority(LLPluginClassMedia::EPriority priority) { mMediaSource->setPriority(mPriority); } - + // NOTE: loading (or reloading) media sources whose priority has risen above PRIORITY_UNLOADED is done in update(). } @@ -3611,8 +3708,8 @@ void LLViewerMediaImpl::setLowPrioritySizeLimit(int size) void LLViewerMediaImpl::setNavState(EMediaNavState state) { mMediaNavState = state; - - switch (state) + + switch (state) { case MEDIANAVSTATE_NONE: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_NONE" << LL_ENDL; break; case MEDIANAVSTATE_BEGUN: LL_DEBUGS("Media") << "Setting nav state to MEDIANAVSTATE_BEGUN" << LL_ENDL; break; @@ -3650,9 +3747,10 @@ void LLViewerMediaImpl::cancelMimeTypeProbe() if (probeAdapter) probeAdapter->cancelSuspendedOperation(); + } -void LLViewerMediaImpl::addObject(LLVOVolume* obj) +void LLViewerMediaImpl::addObject(LLVOVolume* obj) { std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ; for(; iter != mObjectList.end() ; ++iter) @@ -3666,14 +3764,14 @@ void LLViewerMediaImpl::addObject(LLVOVolume* obj) mObjectList.push_back(obj) ; mNeedsMuteCheck = true; } - -void LLViewerMediaImpl::removeObject(LLVOVolume* obj) + +void LLViewerMediaImpl::removeObject(LLVOVolume* obj) { - mObjectList.remove(obj) ; + mObjectList.remove(obj) ; mNeedsMuteCheck = true; } - -const std::list< LLVOVolume* >* LLViewerMediaImpl::getObjectList() const + +const std::list< LLVOVolume* >* LLViewerMediaImpl::getObjectList() const { return &mObjectList ; } @@ -3681,13 +3779,13 @@ const std::list< LLVOVolume* >* LLViewerMediaImpl::getObjectList() const LLVOVolume *LLViewerMediaImpl::getSomeObject() { LLVOVolume *result = NULL; - + std::list< LLVOVolume* >::iterator iter = mObjectList.begin() ; if(iter != mObjectList.end()) { result = *iter; } - + return result; } @@ -3700,12 +3798,12 @@ void LLViewerMediaImpl::setTextureID(LLUUID id) // 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; } } @@ -3714,7 +3812,7 @@ void LLViewerMediaImpl::setTextureID(LLUUID id) // bool LLViewerMediaImpl::isAutoPlayable() const { - return (mMediaAutoPlay && + return (mMediaAutoPlay && gSavedSettings.getBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING) && gSavedSettings.getBOOL("MediaTentativeAutoPlay")); } @@ -3725,20 +3823,20 @@ 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(); - + // LL_INFOS() << " 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)) << LL_ENDL; - + // 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) { @@ -3751,7 +3849,7 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const return show_media_within_parcel; } - else + else { static LLCachedControl<bool> show_media_outside_parcel(gSavedSettings, LLViewerMedia::SHOW_MEDIA_OUTSIDE_PARCEL_SETTING, true); @@ -3764,7 +3862,7 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const 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++) @@ -3808,7 +3906,7 @@ bool LLViewerMediaImpl::isObjectAttachedToAnotherAvatar(LLVOVolume *obj) 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++) diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index d93eb3d6e0..b92977f093 100755 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -153,7 +153,7 @@ public: static void removeCookie(const std::string &name, const std::string &domain, const std::string &path = std::string("/") ); static void openIDSetup(const std::string &openid_url, const std::string &openid_token); - static void openIDCookieResponse(const std::string &cookie); + static void openIDCookieResponse(const std::string& url, const std::string &cookie); static void proxyWindowOpened(const std::string &target, const std::string &uuid); static void proxyWindowClosed(const std::string &uuid); @@ -167,7 +167,8 @@ public: static LLCore::HttpHeaders::ptr_t getHttpHeaders(); private: - static void setOpenIDCookie(); + static bool parseRawCookie(const std::string raw_cookie, std::string& name, std::string& value, std::string& path, bool& httponly, bool& secure); + static void setOpenIDCookie(const std::string& url); static void onTeleportFinished(); static void openIDSetupCoro(std::string openidUrl, std::string openidToken); @@ -231,7 +232,8 @@ public: void mouseDown(const LLVector2& texture_coords, MASK mask, S32 button = 0); void mouseUp(const LLVector2& texture_coords, MASK mask, S32 button = 0); void mouseMove(const LLVector2& texture_coords, MASK mask); - void mouseDoubleClick(S32 x,S32 y, MASK mask, S32 button = 0); + void mouseDoubleClick(const LLVector2& texture_coords, MASK mask); + void mouseDoubleClick(S32 x, S32 y, MASK mask, S32 button = 0); void scrollWheel(S32 x, S32 y, MASK mask); void mouseCapture(); @@ -244,6 +246,7 @@ public: void navigateInternal(); void navigateStop(); bool handleKeyHere(KEY key, MASK mask); + bool handleKeyUpHere(KEY key, MASK mask); bool handleUnicodeCharHere(llwchar uni_char); bool canNavigateForward(); bool canNavigateBack(); diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp index aa019dfdd8..7b4df3d3da 100755 --- a/indra/newview/llviewermediafocus.cpp +++ b/indra/newview/llviewermediafocus.cpp @@ -352,6 +352,18 @@ BOOL LLViewerMediaFocus::handleKey(KEY key, MASK mask, BOOL called_from_parent) return true; } +BOOL LLViewerMediaFocus::handleKeyUp(KEY key, MASK mask, BOOL called_from_parent) +{ + LLViewerMediaImpl* media_impl = getFocusedMediaImpl(); + if (media_impl) + { + media_impl->handleKeyUpHere(key, mask); + } + return true; +} + + + BOOL LLViewerMediaFocus::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent) { LLViewerMediaImpl* media_impl = getFocusedMediaImpl(); @@ -603,3 +615,13 @@ LLUUID LLViewerMediaFocus::getControlsMediaID() return LLUUID::null; } + +bool LLViewerMediaFocus::wantsKeyUpKeyDown() const +{ + return true; +} + +bool LLViewerMediaFocus::wantsReturnKey() const +{ + return true; +} diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h index f03dd8751e..0b2a64868e 100755 --- a/indra/newview/llviewermediafocus.h +++ b/indra/newview/llviewermediafocus.h @@ -56,6 +56,7 @@ public: /*virtual*/ bool getFocus(); /*virtual*/ BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent); + /*virtual*/ BOOL handleKeyUp(KEY key, MASK mask, BOOL called_from_parent); /*virtual*/ BOOL handleUnicodeChar(llwchar uni_char, BOOL called_from_parent); BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); @@ -87,6 +88,10 @@ public: // Return the ID of the media instance the controls are currently attached to (either focus or hover). LLUUID getControlsMediaID(); + // The MoaP object wants keyup and keydown events. Overridden to return true. + virtual bool wantsKeyUpKeyDown() const; + virtual bool wantsReturnKey() const; + protected: /*virtual*/ void onFocusReceived(); /*virtual*/ void onFocusLost(); diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp index 828271da7a..0ab3d2b4e7 100755 --- a/indra/newview/llviewerparcelmedia.cpp +++ b/indra/newview/llviewerparcelmedia.cpp @@ -594,7 +594,13 @@ void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL; } break; - + + case MEDIA_EVENT_FILE_DOWNLOAD: + { + LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_FILE_DOWNLOAD" << LL_ENDL; + } + break; + case MEDIA_EVENT_GEOMETRY_CHANGE: { LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index ba84d7aa2c..4d1cacca1f 100755 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1381,7 +1381,11 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key, MASK mask, BOOL repeated) // it's all entered/processed. if (key == KEY_RETURN && mask == MASK_NONE) { - return FALSE; + // RIDER: although, at times some of the controlls (in particular the CEF viewer + // would like to know about the KEYDOWN for an enter key... so ask and pass it along. + LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); + if (keyboard_focus && !keyboard_focus->wantsReturnKey()) + return FALSE; } return gViewerKeyboard.handleKey(key, mask, repeated); @@ -1399,10 +1403,9 @@ BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key, MASK mask) tool_inspectp->keyUp(key, mask); } - return FALSE; + return gViewerKeyboard.handleKeyUp(key, mask); } - void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) { LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true); @@ -2019,6 +2022,7 @@ void LLViewerWindow::initWorldUI() } gHUDView = new LLHUDView(hud_rect); getRootView()->addChild(gHUDView); + getRootView()->sendChildToBack(gHUDView); } LLPanel* panel_ssf_container = getRootView()->getChild<LLPanel>("state_management_buttons_container"); @@ -2544,21 +2548,67 @@ void LLViewerWindow::draw() //#endif } +// Takes a single keyup event, usually when UI is visible +BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask) +{ + LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); + + if (keyboard_focus + && !(mask & (MASK_CONTROL | MASK_ALT)) + && !gFocusMgr.getKeystrokesOnly()) + { + // We have keyboard focus, and it's not an accelerator + if (keyboard_focus && keyboard_focus->wantsKeyUpKeyDown()) + { + return keyboard_focus->handleKeyUp(key, mask, FALSE); + } + else if (key < 0x80) + { + // Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first. + return (gFocusMgr.getKeyboardFocus() != NULL); + } + } + + if (keyboard_focus) + { + if (keyboard_focus->handleKeyUp(key, mask, FALSE)) + { + LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned true" << LL_ENDL; + LLViewerEventRecorder::instance().logKeyEvent(key, mask); + return TRUE; + } + else { + LL_DEBUGS() << "LLviewerWindow::handleKeyUp - in 'traverse up' - no loops seen... just called keyboard_focus->handleKeyUp an it returned FALSE" << LL_ENDL; + } + } + + // don't pass keys on to world when something in ui has focus + return gFocusMgr.childHasKeyboardFocus(mRootView) + || LLMenuGL::getKeyboardMode() + || (gMenuBarView && gMenuBarView->getHighlightedItem() && gMenuBarView->getHighlightedItem()->isActive()); +} + // Takes a single keydown event, usually when UI is visible BOOL LLViewerWindow::handleKey(KEY key, MASK mask) { // hide tooltips on keypress LLToolTipMgr::instance().blockToolTips(); - if (gFocusMgr.getKeyboardFocus() + LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); + + if (keyboard_focus && !(mask & (MASK_CONTROL | MASK_ALT)) && !gFocusMgr.getKeystrokesOnly()) { // We have keyboard focus, and it's not an accelerator - if (key < 0x80) + if (keyboard_focus && keyboard_focus->wantsKeyUpKeyDown()) + { + return keyboard_focus->handleKey(key, mask, FALSE ); + } + else if (key < 0x80) { // Not a special key, so likely (we hope) to generate a character. Let it fall through to character handler first. - return (gFocusMgr.getKeyboardFocus() != NULL); + return (keyboard_focus != NULL); } } @@ -2572,7 +2622,6 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) return TRUE; } - LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus(); // give menus a chance to handle modified (Ctrl, Alt) shortcut keys before current focus // as long as focus isn't locked @@ -2598,7 +2647,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) // give floaters first chance to handle TAB key // so frontmost floater gets focus // if nothing has focus, go to first or last UI element as appropriate - if (key == KEY_TAB && (mask & MASK_CONTROL || gFocusMgr.getKeyboardFocus() == NULL)) + if (key == KEY_TAB && (mask & MASK_CONTROL || keyboard_focus == NULL)) { LL_WARNS() << "LLviewerWindow::handleKey give floaters first chance at tab key " << LL_ENDL; if (gMenuHolder) gMenuHolder->hideMenus(); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 7fde52d4e1..17e9ac2636 100755 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -314,6 +314,7 @@ public: LLView* getHintHolder() { return mHintHolder.get(); } LLView* getLoginPanelHolder() { return mLoginPanelHolder.get(); } BOOL handleKey(KEY key, MASK mask); + BOOL handleKeyUp(KEY key, MASK mask); void handleScrollWheel (S32 clicks); // add and remove views from "popup" layer diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp index 0be6e49834..b37e41fb85 100755 --- a/indra/newview/llweb.cpp +++ b/indra/newview/llweb.cpp @@ -234,6 +234,9 @@ std::string LLWeb::expandURLSubstitutions(const std::string &url, //static bool LLWeb::useExternalBrowser(const std::string &url) { +#ifdef EXTERNAL_TOS + return true; +#else if (gSavedSettings.getU32("PreferredBrowserBehavior") == BROWSER_EXTERNAL_ONLY) { return true; @@ -250,4 +253,5 @@ bool LLWeb::useExternalBrowser(const std::string &url) return !(boost::regex_search(uri_string, matches, pattern)); } return false; +#endif } diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml index af1617eb39..590d9d1844 100755 --- a/indra/newview/skins/default/xui/en/floater_tos.xml +++ b/indra/newview/skins/default/xui/en/floater_tos.xml @@ -57,6 +57,21 @@ width="552"> Please read the following Terms of Service and Privacy Policy carefully. To continue logging in to [SECOND_LIFE], you must accept the agreement. </text> + <text + type="string" + length="1" + follows="left|top" + font="SansSerif" + height="30" + layout="topleft" + left="16" + name="external_tos_required" + visible="false" + top="32" + word_wrap="true" + width="552"> + You will need to go to my.secondlife.com and log in to accept the Terms of Service before you can proceed. Thank you! + </text> <web_browser trusted_content="true" follows="left|top" diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 73ca7c529d..419ec359a6 100755 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -236,7 +236,7 @@ name="Web Content Floater Debug Test"> <menu_item_call.on_click function="Advanced.WebContentTest" - parameter="http://google.com"/> + parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/> </menu_item_call> <menu create_jump_keys="true" diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index f22986438c..a58fd54d4a 100755 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1431,7 +1431,7 @@ function="Floater.Show" parameter="bumps" /> </menu_item_call> - <menu_item_separator/> + <menu_item_separator/> <menu_item_call label="About [APP_NAME]" name="About Second Life"> @@ -3184,7 +3184,7 @@ shortcut="control|shift|Z"> <menu_item_call.on_click function="Advanced.WebContentTest" - parameter="http://google.com"/> + parameter="https://callum-linden.s3.amazonaws.com/ceftests.html"/> </menu_item_call> <menu_item_call label="FB Connect Test" diff --git a/indra/newview/skins/default/xui/en/mime_types.xml b/indra/newview/skins/default/xui/en/mime_types.xml index f5f2223330..7cb4a6e53b 100755 --- a/indra/newview/skins/default/xui/en/mime_types.xml +++ b/indra/newview/skins/default/xui/en/mime_types.xml @@ -7,7 +7,7 @@ none </defaultwidget> <defaultimpl> - media_plugin_webkit + media_plugin_cef </defaultimpl> <widgetset name="web"> <label name="web_label"> @@ -141,7 +141,7 @@ none </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="none/none"> @@ -152,7 +152,7 @@ none </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="audio/*"> @@ -185,7 +185,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> @@ -207,7 +207,7 @@ web </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/ogg"> @@ -229,7 +229,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/postscript"> @@ -240,7 +240,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/rtf"> @@ -251,7 +251,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/smil"> @@ -262,7 +262,7 @@ movie </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/xhtml+xml"> @@ -273,7 +273,7 @@ web </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/x-director"> @@ -284,7 +284,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="audio/mid"> @@ -339,7 +339,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="image/gif"> @@ -350,7 +350,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="image/jpeg"> @@ -361,7 +361,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="image/png"> @@ -372,7 +372,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="image/svg+xml"> @@ -383,7 +383,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="image/tiff"> @@ -394,7 +394,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="text/html"> @@ -405,7 +405,7 @@ web </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="text/plain"> @@ -416,7 +416,7 @@ text </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="text/xml"> @@ -427,7 +427,7 @@ text </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="video/mpeg"> diff --git a/indra/newview/skins/default/xui/en/mime_types_mac.xml b/indra/newview/skins/default/xui/en/mime_types_mac.xml index 90230f12dd..f71c24b2e4 100755 --- a/indra/newview/skins/default/xui/en/mime_types_mac.xml +++ b/indra/newview/skins/default/xui/en/mime_types_mac.xml @@ -7,7 +7,7 @@ none </defaultwidget> <defaultimpl> - media_plugin_webkit + media_plugin_cef </defaultimpl> <widgetset name="web"> <label name="web_label"> @@ -152,7 +152,7 @@ none </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="audio/*"> @@ -185,7 +185,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="video/vnd.secondlife.qt.legacy"> @@ -207,7 +207,7 @@ web </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/ogg"> @@ -229,7 +229,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/postscript"> @@ -240,7 +240,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/rtf"> @@ -251,7 +251,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/smil"> @@ -262,7 +262,7 @@ movie </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/xhtml+xml"> @@ -273,7 +273,7 @@ web </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="application/x-director"> @@ -284,7 +284,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="audio/mid"> @@ -339,7 +339,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="image/gif"> @@ -350,7 +350,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="image/jpeg"> @@ -361,7 +361,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="image/png"> @@ -372,7 +372,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="image/svg+xml"> @@ -383,7 +383,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="image/tiff"> @@ -394,7 +394,7 @@ image </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="text/html"> @@ -405,7 +405,7 @@ web </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="text/plain"> @@ -416,7 +416,7 @@ text </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype name="text/xml"> @@ -427,7 +427,7 @@ text </widgettype> <impl> - media_plugin_webkit + media_plugin_cef </impl> </mimetype> <mimetype menu="1" name="video/mpeg"> diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f79e8103b6..4a1336d2b5 100755 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1592,11 +1592,24 @@ The object may be out of range or may have been deleted. icon="alertmodal.tga" name="CannotDownloadFile" type="alertmodal"> -Unable to download file - <tag>fail</tag> + Unable to download file + <tag>fail</tag> </notification> <notification + name="MediaFileDownloadUnsupported" + label="" + type="alert"> + <unique/> + <tag>confirm</tag> + You have requested a file download, which is not supported within [SECOND_LIFE]. + <usetemplate + ignoretext="Warn about unsupported file downloads" + name="okignore" + yestext="OK"/> + </notification> + + <notification icon="alertmodal.tga" name="CannotWriteFile" type="alertmodal"> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml index b201e071ef..45b2b6ec27 100755 --- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml @@ -224,19 +224,6 @@ radio_style="false" width="400" top_pad="5"/> - <check_box - top_delta="4" - enabled="true" - follows="left|top" - height="14" - initial_value="false" - control_name="MediaEnablePopups" - label="Enable media browser pop-ups" - left_delta="0" - mouse_opaque="true" - name="media_popup_enabled" - width="400" - top_pad="5"/> <text type="string" length="1" diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 4eb6e2462d..f2eddbb38e 100755 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -50,7 +50,7 @@ OpenGL Version: [OPENGL_VERSION] libcurl Version: [LIBCURL_VERSION] J2C Decoder Version: [J2C_VERSION] Audio Driver Version: [AUDIO_DRIVER_VERSION] -Qt Webkit Version: [QT_WEBKIT_VERSION] +LLCEFLib/CEF Version: [LLCEFLIB_VERSION] Voice Server Version: [VOICE_VERSION] </string> <string name="AboutTraffic">Packets Lost: [PACKETS_LOST,number,0]/[PACKETS_IN,number,0] ([PACKETS_PCT,number,1]%)</string> diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp index 61120686e4..4c0acded9e 100755 --- a/indra/newview/tests/llmediadataclient_test.cpp +++ b/indra/newview/tests/llmediadataclient_test.cpp @@ -26,7 +26,7 @@ #include "linden_common.h" #include "../llviewerprecompiledheaders.h" - + #include <iostream> #include "../test/lltut.h" diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index fa80730407..9bcb6fce9f 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -340,9 +340,9 @@ class Windows_i686_Manifest(ViewerManifest): self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe()) # Plugin host application - # The current slplugin package places slplugin.exe right into the - # packages base directory. - self.path2basename(pkgdir, "slplugin.exe") + self.path2basename(os.path.join(os.pardir, + 'llplugin', 'slplugin', self.args['configuration']), + "slplugin.exe") self.path2basename("../viewer_components/updater/scripts/windows", "update_install.bat") # Get shared libs from the shared libs staging directory @@ -426,54 +426,121 @@ class Windows_i686_Manifest(ViewerManifest): self.path("featuretable_xp.txt") # Media plugins - QuickTime - # Media plugins - WebKit/Qt - if self.prefix(src=os.path.join(pkgdir, "llplugin"), dst="llplugin"): + if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"): self.path("media_plugin_quicktime.dll") - self.path("media_plugin_webkit.dll") - self.path("qtcore4.dll") - self.path("qtgui4.dll") - self.path("qtnetwork4.dll") - self.path("qtopengl4.dll") - self.path("qtwebkit4.dll") - self.path("qtxmlpatterns4.dll") - - # For WebKit/Qt plugin runtimes (image format plugins) - if self.prefix(src="imageformats", dst="imageformats"): - self.path("qgif4.dll") - self.path("qico4.dll") - self.path("qjpeg4.dll") - self.path("qmng4.dll") - self.path("qsvg4.dll") - self.path("qtiff4.dll") - self.end_prefix() - - # For WebKit/Qt plugin runtimes (codec/character encoding plugins) - if self.prefix(src="codecs", dst="codecs"): - self.path("qcncodecs4.dll") - self.path("qjpcodecs4.dll") - self.path("qkrcodecs4.dll") - self.path("qtwcodecs4.dll") - self.end_prefix() + self.end_prefix() - self.end_prefix() + # Media plugins - CEF + if self.prefix(src='../media_plugins/cef/%s' % self.args['configuration'], dst="llplugin"): + self.path("media_plugin_cef.dll") + self.end_prefix() # winmm.dll shim if self.prefix(src='../media_plugins/winmmshim/%s' % self.args['configuration'], dst=""): self.path("winmm.dll") self.end_prefix() + # CEF runtime files - debug if self.args['configuration'].lower() == 'debug': - if self.prefix(src=debpkgdir, dst="llplugin"): - self.path("libeay32.dll") - self.path("ssleay32.dll") + if self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'debug'), dst="llplugin"): + self.path("d3dcompiler_43.dll") + self.path("d3dcompiler_47.dll") + self.path("libcef.dll") + self.path("libEGL.dll") + self.path("libGLESv2.dll") + self.path("llceflib_host.exe") + self.path("natives_blob.bin") + self.path("snapshot_blob.bin") + self.path("widevinecdmadapter.dll") + self.path("wow_helper.exe") self.end_prefix() - else: - if self.prefix(src=relpkgdir, dst="llplugin"): - self.path("libeay32.dll") - self.path("ssleay32.dll") + # CEF runtime files - not debug (release, relwithdebinfo etc.) + if self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'release'), dst="llplugin"): + self.path("d3dcompiler_43.dll") + self.path("d3dcompiler_47.dll") + self.path("libcef.dll") + self.path("libEGL.dll") + self.path("libGLESv2.dll") + self.path("llceflib_host.exe") + self.path("natives_blob.bin") + self.path("snapshot_blob.bin") + self.path("widevinecdmadapter.dll") + self.path("wow_helper.exe") self.end_prefix() + # MSVC DLLs needed for CEF and have to be in same directory as plugin + if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', 'Release'), dst="llplugin"): + self.path("msvcp120.dll") + self.path("msvcr120.dll") + self.end_prefix() + + # CEF files common to all configurations + if self.prefix(src=os.path.join(os.pardir, 'packages', 'resources'), dst="llplugin"): + self.path("cef.pak") + self.path("cef_100_percent.pak") + self.path("cef_200_percent.pak") + self.path("cef_extensions.pak") + self.path("devtools_resources.pak") + self.path("icudtl.dat") + self.end_prefix() + + if self.prefix(src=os.path.join(os.pardir, 'packages', 'resources', 'locales'), dst=os.path.join('llplugin', 'locales')): + self.path("am.pak") + self.path("ar.pak") + self.path("bg.pak") + self.path("bn.pak") + self.path("ca.pak") + self.path("cs.pak") + self.path("da.pak") + self.path("de.pak") + self.path("el.pak") + self.path("en-GB.pak") + self.path("en-US.pak") + self.path("es-419.pak") + self.path("es.pak") + self.path("et.pak") + self.path("fa.pak") + self.path("fi.pak") + self.path("fil.pak") + self.path("fr.pak") + self.path("gu.pak") + self.path("he.pak") + self.path("hi.pak") + self.path("hr.pak") + self.path("hu.pak") + self.path("id.pak") + self.path("it.pak") + self.path("ja.pak") + self.path("kn.pak") + self.path("ko.pak") + self.path("lt.pak") + self.path("lv.pak") + self.path("ml.pak") + self.path("mr.pak") + self.path("ms.pak") + self.path("nb.pak") + self.path("nl.pak") + self.path("pl.pak") + self.path("pt-BR.pak") + self.path("pt-PT.pak") + self.path("ro.pak") + self.path("ru.pak") + self.path("sk.pak") + self.path("sl.pak") + self.path("sr.pak") + self.path("sv.pak") + self.path("sw.pak") + self.path("ta.pak") + self.path("te.pak") + self.path("th.pak") + self.path("tr.pak") + self.path("uk.pak") + self.path("vi.pak") + self.path("zh-CN.pak") + self.path("zh-TW.pak") + self.end_prefix() + # pull in the crash logger and updater from other projects # tag:"crash-logger" here as a cue to the exporter self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'], @@ -737,14 +804,13 @@ class Darwin_i386_Manifest(ViewerManifest): dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) # our apps - for app_bld_dir, app in ((os.path.join(os.pardir, - "mac_crash_logger", - self.args['configuration']), - "mac-crash-logger.app"), + for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"), # plugin launcher - (pkgdir, "SLPlugin.app"), + (os.path.join("llplugin", "slplugin"), "SLPlugin.app"), ): - self.path2basename(app_bld_dir, app) + self.path2basename(os.path.join(os.pardir, + app_bld_dir, self.args['configuration']), + app) # our apps dependencies on shared libs # for each app, for each dylib we collected in dylibs, @@ -757,46 +823,57 @@ class Darwin_i386_Manifest(ViewerManifest): symlinkf(src, dst) except OSError as err: print "Can't symlink %s -> %s: %s" % (src, dst, err) - # SLPlugin.app/Contents/Resources gets those Qt4 libraries it needs. - if self.prefix(src="", dst="SLPlugin.app/Contents/Resources"): - for libfile in ('libQtCore.4.dylib', - 'libQtCore.4.7.1.dylib', - 'libQtGui.4.dylib', - 'libQtGui.4.7.1.dylib', - 'libQtNetwork.4.dylib', - 'libQtNetwork.4.7.1.dylib', - 'libQtOpenGL.4.dylib', - 'libQtOpenGL.4.7.1.dylib', - 'libQtSvg.4.dylib', - 'libQtSvg.4.7.1.dylib', - 'libQtWebKit.4.dylib', - 'libQtWebKit.4.7.1.dylib', - 'libQtXml.4.dylib', - 'libQtXml.4.7.1.dylib'): - self.path2basename(relpkgdir, libfile) - self.end_prefix("SLPlugin.app/Contents/Resources") - - # Qt4 codecs go to llplugin. Not certain why but this is the first - # location probed according to dtruss so we'll go with that. - if self.prefix(src=os.path.join(pkgdir, "llplugin/codecs/"), dst="llplugin/codecs"): - self.path("libq*.dylib") - self.end_prefix("llplugin/codecs") - - # Similarly for imageformats. - if self.prefix(src=os.path.join(pkgdir, "llplugin/imageformats/"), dst="llplugin/imageformats"): - self.path("libq*.dylib") - self.end_prefix("llplugin/imageformats") - - # SLPlugin plugins proper - if self.prefix(src=os.path.join(pkgdir, "llplugin"), dst="llplugin"): - self.path("media_plugin_quicktime.dylib") - self.path("media_plugin_webkit.dylib") + + # LLCefLib helper apps go inside SLPlugin.app + if self.prefix(src="", dst="SLPlugin.app/Contents/Frameworks"): + for helperappfile in ('LLCefLib Helper.app', + 'LLCefLib Helper EH.app'): + self.path2basename(relpkgdir, helperappfile) + + pluginframeworkpath = self.dst_path_of('Chromium Embedded Framework.framework'); + + self.end_prefix() + + # SLPlugin plugins + if self.prefix(src="", dst="llplugin"): + self.path2basename("../media_plugins/quicktime/" + self.args['configuration'], + "media_plugin_quicktime.dylib") + self.path2basename("../media_plugins/cef/" + self.args['configuration'], + "media_plugin_cef.dylib") self.end_prefix("llplugin") self.end_prefix("Resources") + # CEF framework goes inside Second Life.app/Contents/Frameworks + if self.prefix(src="", dst="Frameworks"): + frameworkfile="Chromium Embedded Framework.framework" + self.path2basename(relpkgdir, frameworkfile) + self.end_prefix("Frameworks") + + # This code constructs a relative path from the + # target framework folder back to the location of the symlink. + # It needs to be relative so that the symlink still works when + # (as is normal) the user moves the app bunlde out of the DMG + # and into the /Applications folder. Note we also call 'raise' + # to terminate the process if we get an error since without + # this symlink, Second Life web media can't possibly work. + # Real Framework folder: + # Second Life.app/Contents/Frameworks/Chromium Embedded Framework.framework/ + # Location of symlink and why it'ds relavie + # Second Life.app/Contents/Resources/SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework/ + frameworkpath = os.path.join(os.pardir, os.pardir, os.pardir, os.pardir, "Frameworks", "Chromium Embedded Framework.framework") + try: + symlinkf(frameworkpath, pluginframeworkpath) + except OSError as err: + print "Can't symlink %s -> %s: %s" % (frameworkpath, pluginframeworkpath, err) + raise + self.end_prefix("Contents") + # fix up media_plugin.dylib so it knows where to look for CEF files it needs + self.run_command('install_name_tool -change "@executable_path/Chromium Embedded Framework" "@executable_path/../Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework" "%(config)s/Second Life.app/Contents/Resources/llplugin/media_plugin_cef.dylib"' % + { 'config' : self.args['configuration'] }) + # NOTE: the -S argument to strip causes it to keep enough info for # annotated backtraces (i.e. function names in the crash log). 'strip' with no # arguments yields a slightly smaller binary but makes crash logs mostly useless. @@ -806,7 +883,6 @@ class Darwin_i386_Manifest(ViewerManifest): self.run_command('strip -S %(viewer_binary)r' % { 'viewer_binary' : self.dst_path_of('Contents/MacOS/Second Life')}) - def copy_finish(self): # Force executable permissions to be set for scripts # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802 @@ -983,7 +1059,7 @@ class LinuxManifest(ViewerManifest): if self.prefix(src="", dst="bin"): self.path("secondlife-bin","do-not-directly-run-secondlife-bin") self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin") - self.path2basename(pkgdir, "SLPlugin") + self.path2basename("../llplugin/slplugin", "SLPlugin") self.path2basename("../viewer_components/updater/scripts/linux", "update_install") self.end_prefix("bin") @@ -1003,9 +1079,8 @@ class LinuxManifest(ViewerManifest): self.end_prefix(icon_path) # plugins - if self.prefix(src=os.path.join(pkgdir, "llplugin"), dst="bin/llplugin"): - self.path("libmedia_plugin_webkit.so") - self.path("libmedia_plugin_gstreamer.so") + if self.prefix(src="", dst="bin/llplugin"): + self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so") self.end_prefix("bin/llplugin") # llcommon @@ -1145,37 +1220,6 @@ class Linux_i686_Manifest(LinuxManifest): self.path("libvivoxplatform.so") self.end_prefix("lib") - # plugin runtime - if self.prefix(src=os.path.join(pkgdir, "lib"), dst="lib"): - self.path("libQtCore.so*") - self.path("libQtGui.so*") - self.path("libQtNetwork.so*") - self.path("libQtOpenGL.so*") - self.path("libQtSvg.so*") - self.path("libQtWebKit.so*") - self.path("libQtXml.so*") - self.end_prefix("lib") - - # For WebKit/Qt plugin runtimes (image format plugins) - if self.prefix(src=os.path.join(pkgdir, "llplugin", "imageformats"), - dst="bin/llplugin/imageformats"): - self.path("libqgif.so") - self.path("libqico.so") - self.path("libqjpeg.so") - self.path("libqmng.so") - self.path("libqsvg.so") - self.path("libqtiff.so") - self.end_prefix("bin/llplugin/imageformats") - - # For WebKit/Qt plugin runtimes (codec/character encoding plugins) - if self.prefix(src=os.path.join(pkgdir, "llplugin", "codecs"), - dst="bin/llplugin/codecs"): - self.path("libqcncodecs.so") - self.path("libqjpcodecs.so") - self.path("libqkrcodecs.so") - self.path("libqtwcodecs.so") - self.end_prefix("bin/llplugin/codecs") - self.strip_binaries() |