diff options
| author | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 19:04:52 +0200 |
|---|---|---|
| committer | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 19:04:52 +0200 |
| commit | 1b67dd855c41f5a0cda7ec2a68d98071986ca703 (patch) | |
| tree | ab243607f74f78200787bba5b9b88f07ef1b966f /indra/newview/llmediactrl.cpp | |
| parent | 6d6eabca44d08d5b97bfe3e941d2b9687c2246ea (diff) | |
| parent | e1623bb276f83a43ce7a197e388720c05bdefe61 (diff) | |
Merge remote-tracking branch 'origin/main' into DRTVWR-600-maint-A
# Conflicts:
# autobuild.xml
# indra/cmake/CMakeLists.txt
# indra/cmake/GoogleMock.cmake
# indra/llaudio/llaudioengine_fmodstudio.cpp
# indra/llaudio/llaudioengine_fmodstudio.h
# indra/llaudio/lllistener_fmodstudio.cpp
# indra/llaudio/lllistener_fmodstudio.h
# indra/llaudio/llstreamingaudio_fmodstudio.cpp
# indra/llaudio/llstreamingaudio_fmodstudio.h
# indra/llcharacter/llmultigesture.cpp
# indra/llcharacter/llmultigesture.h
# indra/llimage/llimage.cpp
# indra/llimage/llimagepng.cpp
# indra/llimage/llimageworker.cpp
# indra/llimage/tests/llimageworker_test.cpp
# indra/llmessage/tests/llmockhttpclient.h
# indra/llprimitive/llgltfmaterial.h
# indra/llrender/llfontfreetype.cpp
# indra/llui/llcombobox.cpp
# indra/llui/llfolderview.cpp
# indra/llui/llfolderviewmodel.h
# indra/llui/lllineeditor.cpp
# indra/llui/lllineeditor.h
# indra/llui/lltextbase.cpp
# indra/llui/lltextbase.h
# indra/llui/lltexteditor.cpp
# indra/llui/lltextvalidate.cpp
# indra/llui/lltextvalidate.h
# indra/llui/lluictrl.h
# indra/llui/llview.cpp
# indra/llwindow/llwindowmacosx.cpp
# indra/newview/app_settings/settings.xml
# indra/newview/llappearancemgr.cpp
# indra/newview/llappearancemgr.h
# indra/newview/llavatarpropertiesprocessor.cpp
# indra/newview/llavatarpropertiesprocessor.h
# indra/newview/llbreadcrumbview.cpp
# indra/newview/llbreadcrumbview.h
# indra/newview/llbreastmotion.cpp
# indra/newview/llbreastmotion.h
# indra/newview/llconversationmodel.h
# indra/newview/lldensityctrl.cpp
# indra/newview/lldensityctrl.h
# indra/newview/llface.inl
# indra/newview/llfloatereditsky.cpp
# indra/newview/llfloatereditwater.cpp
# indra/newview/llfloateremojipicker.h
# indra/newview/llfloaterimsessiontab.cpp
# indra/newview/llfloaterprofiletexture.cpp
# indra/newview/llfloaterprofiletexture.h
# indra/newview/llgesturemgr.cpp
# indra/newview/llgesturemgr.h
# indra/newview/llimpanel.cpp
# indra/newview/llimpanel.h
# indra/newview/llinventorybridge.cpp
# indra/newview/llinventorybridge.h
# indra/newview/llinventoryclipboard.cpp
# indra/newview/llinventoryclipboard.h
# indra/newview/llinventoryfunctions.cpp
# indra/newview/llinventoryfunctions.h
# indra/newview/llinventorygallery.cpp
# indra/newview/lllistbrowser.cpp
# indra/newview/lllistbrowser.h
# indra/newview/llpanelobjectinventory.cpp
# indra/newview/llpanelprofile.cpp
# indra/newview/llpanelprofile.h
# indra/newview/llpreviewgesture.cpp
# indra/newview/llsavedsettingsglue.cpp
# indra/newview/llsavedsettingsglue.h
# indra/newview/lltooldraganddrop.cpp
# indra/newview/llurllineeditorctrl.cpp
# indra/newview/llvectorperfoptions.cpp
# indra/newview/llvectorperfoptions.h
# indra/newview/llviewerparceloverlay.cpp
# indra/newview/llviewertexlayer.cpp
# indra/newview/llviewertexturelist.cpp
# indra/newview/macmain.h
# indra/test/test.cpp
Diffstat (limited to 'indra/newview/llmediactrl.cpp')
| -rw-r--r-- | indra/newview/llmediactrl.cpp | 2512 |
1 files changed, 1256 insertions, 1256 deletions
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp index 5461f98624..67412f1b38 100644 --- a/indra/newview/llmediactrl.cpp +++ b/indra/newview/llmediactrl.cpp @@ -1,1256 +1,1256 @@ -/** - * @file LLMediaCtrl.cpp - * @brief Web browser UI control - * - * $LicenseInfo:firstyear=2006&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" -#include "lltooltip.h" - -#include "llmediactrl.h" - -// viewer includes -#include "llfloaterworldmap.h" -#include "lluictrlfactory.h" -#include "llurldispatcher.h" -#include "llviewborder.h" -#include "llviewercontrol.h" -#include "llviewermedia.h" -#include "llviewertexture.h" -#include "llviewerwindow.h" -#include "lldebugmessagebox.h" -#include "llweb.h" -#include "llrender.h" -#include "llpluginclassmedia.h" -#include "llslurl.h" -#include "lluictrlfactory.h" // LLDefaultChildRegistry -#include "llkeyboard.h" -#include "llviewermenu.h" -#include "llviewermenufile.h" // LLFilePickerThread - -// linden library includes -#include "llfocusmgr.h" -#include "llsdutil.h" -#include "lllayoutstack.h" -#include "lliconctrl.h" -#include "llhttpconstants.h" -#include "lltextbox.h" -#include "llbutton.h" -#include "llcheckboxctrl.h" -#include "llnotifications.h" -#include "llnotificationsutil.h" -#include "lllineeditor.h" -#include "llfloaterwebcontent.h" -#include "llwindowshade.h" - -extern bool gRestoreGL; - -static LLDefaultChildRegistry::Register<LLMediaCtrl> r("web_browser"); - -LLMediaCtrl::Params::Params() -: start_url("start_url"), - border_visible("border_visible", true), - decouple_texture_size("decouple_texture_size", false), - texture_width("texture_width", 1024), - texture_height("texture_height", 1024), - caret_color("caret_color"), - initial_mime_type("initial_mime_type"), - error_page_url("error_page_url"), - media_id("media_id"), - trusted_content("trusted_content", false), - focus_on_click("focus_on_click", true) -{ -} - -LLMediaCtrl::LLMediaCtrl( const Params& p) : - LLPanel( p ), - LLInstanceTracker<LLMediaCtrl, LLUUID>(LLUUID::generateNewID()), - mTextureDepthBytes( 4 ), - mBorder(NULL), - mFrequentUpdates( true ), - mForceUpdate( false ), - mHomePageUrl( "" ), - mAlwaysRefresh( false ), - mMediaSource( 0 ), - mTakeFocusOnClick( p.focus_on_click ), - mCurrentNavUrl( "" ), - mStretchToFill( true ), - mMaintainAspectRatio ( true ), - mDecoupleTextureSize ( false ), - mUpdateScrolls( false ), - mTextureWidth ( 1024 ), - mTextureHeight ( 1024 ), - mClearCache(false), - mHomePageMimeType(p.initial_mime_type), - mErrorPageURL(p.error_page_url), - mTrusted(p.trusted_content), - mWindowShade(NULL), - mHoverTextChanged(false), - mAllowFileDownload(false) -{ - { - LLColor4 color = p.caret_color().get(); - setCaretColor( (unsigned int)color.mV[0], (unsigned int)color.mV[1], (unsigned int)color.mV[2] ); - } - - setHomePageUrl(p.start_url, p.initial_mime_type); - - setBorderVisible(p.border_visible); - - setDecoupleTextureSize(p.decouple_texture_size); - - setTextureSize(p.texture_width, p.texture_height); - - if(!getDecoupleTextureSize()) - { - S32 screen_width = ll_round((F32)getRect().getWidth() * LLUI::getScaleFactor().mV[VX]); - S32 screen_height = ll_round((F32)getRect().getHeight() * LLUI::getScaleFactor().mV[VY]); - - setTextureSize(screen_width, screen_height); - } - - mMediaTextureID = getKey(); - - // We don't need to create the media source up front anymore unless we have a non-empty home URL to navigate to. - if(!mHomePageUrl.empty()) - { - navigateHome(); - } - - LLWindowShade::Params params; - params.name = "notification_shade"; - params.rect = getLocalRect(); - params.follows.flags = FOLLOWS_ALL; - params.modal = true; - - mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params); - - addChild(mWindowShade); -} - -LLMediaCtrl::~LLMediaCtrl() -{ - auto menu = mContextMenuHandle.get(); - if (menu) - { - menu->die(); - mContextMenuHandle.markDead(); - } - - if (mMediaSource) - { - mMediaSource->remObserver( this ); - mMediaSource = NULL; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::setBorderVisible( bool border_visible ) -{ - if ( mBorder ) - { - mBorder->setVisible( border_visible ); - }; -}; - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::setTakeFocusOnClick( bool take_focus ) -{ - mTakeFocusOnClick = take_focus; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask ) -{ - if (LLPanel::handleHover(x, y, mask)) return true; - convertInputCoords(x, y); - - if (mMediaSource) - { - mMediaSource->mouseMove(x, y, mask); - gViewerWindow->setCursor(mMediaSource->getLastSetCursor()); - } - - // TODO: Is this the right way to handle hover text changes driven by the plugin? - if(mHoverTextChanged) - { - mHoverTextChanged = false; - handleToolTip(x, y, mask); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks ) -{ - if (LLPanel::handleScrollWheel(x, y, clicks)) return true; - if (mMediaSource && mMediaSource->hasMedia()) - { - convertInputCoords(x, y); - mMediaSource->scrollWheel(x, y, 0, clicks, gKeyboard->currentMask(true)); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::handleScrollHWheel(S32 x, S32 y, S32 clicks) -{ - if (LLPanel::handleScrollHWheel(x, y, clicks)) return true; - if (mMediaSource && mMediaSource->hasMedia()) - { - convertInputCoords(x, y); - mMediaSource->scrollWheel(x, y, clicks, 0, gKeyboard->currentMask(true)); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// virtual -bool LLMediaCtrl::handleToolTip(S32 x, S32 y, MASK mask) -{ - std::string hover_text; - - if (mMediaSource && mMediaSource->hasMedia()) - hover_text = mMediaSource->getMediaPlugin()->getHoverText(); - - if(hover_text.empty()) - { - return false; - } - else - { - S32 screen_x, screen_y; - - localPointToScreen(x, y, &screen_x, &screen_y); - LLRect sticky_rect_screen; - sticky_rect_screen.setCenterAndSize(screen_x, screen_y, 20, 20); - - LLToolTipMgr::instance().show(LLToolTip::Params() - .message(hover_text) - .sticky_rect(sticky_rect_screen)); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask ) -{ - if (LLPanel::handleMouseUp(x, y, mask)) return true; - convertInputCoords(x, y); - - if (mMediaSource) - { - mMediaSource->mouseUp(x, y, mask); - } - - gFocusMgr.setMouseCapture( NULL ); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask ) -{ - if (LLPanel::handleMouseDown(x, y, mask)) return true; - convertInputCoords(x, y); - - if (mMediaSource) - mMediaSource->mouseDown(x, y, mask); - - gFocusMgr.setMouseCapture( this ); - - if (mTakeFocusOnClick) - { - setFocus( true ); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask ) -{ - if (LLPanel::handleRightMouseUp(x, y, mask)) return true; - convertInputCoords(x, y); - - if (mMediaSource) - { - mMediaSource->mouseUp(x, y, mask, 1); - - // *HACK: LLMediaImplLLMozLib automatically takes focus on mouseup, - // in addition to the onFocusReceived() call below. Undo this. JC - if (!mTakeFocusOnClick) - { - mMediaSource->focus(false); - gViewerWindow->focusClient(); - } - } - - gFocusMgr.setMouseCapture( NULL ); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask ) -{ - if (LLPanel::handleRightMouseDown(x, y, mask)) return true; - - S32 media_x = x, media_y = y; - convertInputCoords(media_x, media_y); - - if (mMediaSource) - mMediaSource->mouseDown(media_x, media_y, mask, 1); - - gFocusMgr.setMouseCapture( this ); - - if (mTakeFocusOnClick) - { - setFocus( true ); - } - - auto menu = mContextMenuHandle.get(); - if (!menu) - { - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar; - registar.add("Open.WebInspector", boost::bind(&LLMediaCtrl::onOpenWebInspector, this)); - - // stinson 05/05/2014 : use this as the parent of the context menu if the static menu - // container has yet to be created - LLPanel* menuParent = (LLMenuGL::sMenuContainer != NULL) ? dynamic_cast<LLPanel*>(LLMenuGL::sMenuContainer) : dynamic_cast<LLPanel*>(this); - llassert(menuParent != NULL); - menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>( - "menu_media_ctrl.xml", menuParent, LLViewerMenuHolderGL::child_registry_t::instance()); - if (menu) - { - mContextMenuHandle = menu->getHandle(); - } - } - - if (menu) - { - // hide/show debugging options - bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging"); - menu->setItemVisible("open_webinspector", media_plugin_debugging_enabled ); - menu->setItemVisible("debug_separator", media_plugin_debugging_enabled ); - - menu->show(x, y); - LLMenuGL::showPopup(this, menu, x, y); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::handleDoubleClick( S32 x, S32 y, MASK mask ) -{ - if (LLPanel::handleDoubleClick(x, y, mask)) return true; - convertInputCoords(x, y); - - if (mMediaSource) - mMediaSource->mouseDoubleClick( x, y, mask); - - gFocusMgr.setMouseCapture( this ); - - if (mTakeFocusOnClick) - { - setFocus( true ); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::onFocusReceived() -{ - if (mMediaSource) - { - mMediaSource->focus(true); - - // Set focus for edit menu items - LLEditMenuHandler::gEditMenuHandler = mMediaSource; - } - - LLPanel::onFocusReceived(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::onFocusLost() -{ - if (mMediaSource) - { - mMediaSource->focus(false); - - if( LLEditMenuHandler::gEditMenuHandler == mMediaSource ) - { - // Clear focus for edit menu items - LLEditMenuHandler::gEditMenuHandler = NULL; - } - } - - gViewerWindow->focusClient(); - - LLPanel::onFocusLost(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::postBuild () -{ - setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChanged, this, _2)); - - return true; -} - -void LLMediaCtrl::onOpenWebInspector() -{ - if (mMediaSource && mMediaSource->hasMedia()) - mMediaSource->getMediaPlugin()->showWebInspector( true ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::handleKeyHere( KEY key, MASK mask ) -{ - bool result = false; - - if (mMediaSource) - { - result = mMediaSource->handleKeyHere(key, mask); - } - - if ( ! result ) - result = LLPanel::handleKeyHere(key, mask); - - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// -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; - if(mMediaSource) - { - mMediaSource->setVisible( new_visibility ); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char) -{ - bool result = false; - - if (mMediaSource) - { - result = mMediaSource->handleUnicodeCharHere(uni_char); - } - - if ( ! result ) - result = LLPanel::handleUnicodeCharHere(uni_char); - - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::onVisibilityChanged ( const LLSD& new_visibility ) -{ - // set state of frequent updates automatically if visibility changes - if ( new_visibility.asBoolean() ) - { - mFrequentUpdates = true; - } - else - { - mFrequentUpdates = false; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::reshape( S32 width, S32 height, bool called_from_parent ) -{ - if(!getDecoupleTextureSize()) - { - S32 screen_width = ll_round((F32)width * LLUI::getScaleFactor().mV[VX]); - S32 screen_height = ll_round((F32)height * LLUI::getScaleFactor().mV[VY]); - - // when floater is minimized, these sizes are negative - if ( screen_height > 0 && screen_width > 0 ) - { - setTextureSize(screen_width, screen_height); - } - } - - LLUICtrl::reshape( width, height, called_from_parent ); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::navigateBack() -{ - if (mMediaSource && mMediaSource->hasMedia()) - { - mMediaSource->getMediaPlugin()->browse_back(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::navigateForward() -{ - if (mMediaSource && mMediaSource->hasMedia()) - { - mMediaSource->getMediaPlugin()->browse_forward(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::navigateStop() -{ - if (mMediaSource && mMediaSource->hasMedia()) - { - mMediaSource->getMediaPlugin()->browse_stop(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::canNavigateBack() -{ - if (mMediaSource) - return mMediaSource->canNavigateBack(); - else - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::canNavigateForward() -{ - if (mMediaSource) - return mMediaSource->canNavigateForward(); - else - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::clearCache() -{ - if(mMediaSource) - { - mMediaSource->clearCache(); - } - else - { - mClearCache = true; - } - -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type, bool clean_browser) -{ - // don't browse to anything that starts with secondlife:// or sl:// - const std::string protocol1 = "secondlife://"; - const std::string protocol2 = "sl://"; - if ((LLStringUtil::compareInsensitive(url_in.substr(0, protocol1.length()), protocol1) == 0) || - (LLStringUtil::compareInsensitive(url_in.substr(0, protocol2.length()), protocol2) == 0)) - { - // TODO: Print out/log this attempt? - // LL_INFOS() << "Rejecting attempt to load restricted website :" << urlIn << LL_ENDL; - return; - } - - if (ensureMediaSourceExists()) - { - mCurrentNavUrl = url_in; - mMediaSource->setSize(mTextureWidth, mTextureHeight); - mMediaSource->navigateTo(url_in, mime_type, mime_type.empty(), false, clean_browser); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in ) -{ - std::string filename(gDirUtilp->add(subdir, filename_in)); - std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", filename); - - if (expanded_filename.empty()) - { - LL_WARNS() << "File " << filename << "not found" << LL_ENDL; - return; - } - if (ensureMediaSourceExists()) - { - mCurrentNavUrl = expanded_filename; - mMediaSource->setSize(mTextureWidth, mTextureHeight); - mMediaSource->navigateTo(expanded_filename, HTTP_CONTENT_TEXT_HTML, false); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::navigateHome() -{ - if (ensureMediaSourceExists()) - { - mMediaSource->setSize(mTextureWidth, mTextureHeight); - mMediaSource->navigateHome(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::setHomePageUrl( const std::string& urlIn, const std::string& mime_type ) -{ - mHomePageUrl = urlIn; - if (mMediaSource) - { - mMediaSource->setHomeURL(mHomePageUrl, mime_type); - } -} - -void LLMediaCtrl::setTarget(const std::string& target) -{ - mTarget = target; - if (mMediaSource) - { - mMediaSource->setTarget(mTarget); - } -} - -void LLMediaCtrl::setErrorPageURL(const std::string& url) -{ - mErrorPageURL = url; -} - -const std::string& LLMediaCtrl::getErrorPageURL() -{ - return mErrorPageURL; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned int blue) -{ - //NOOP - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::setTextureSize(S32 width, S32 height) -{ - mTextureWidth = width; - mTextureHeight = height; - - if(mMediaSource) - { - mMediaSource->setSize(mTextureWidth, mTextureHeight); - mForceUpdate = true; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// -std::string LLMediaCtrl::getHomePageUrl() -{ - return mHomePageUrl; -} - -//////////////////////////////////////////////////////////////////////////////// -// -bool LLMediaCtrl::ensureMediaSourceExists() -{ - if(mMediaSource.isNull()) - { - // If we don't already have a media source, try to create one. - mMediaSource = LLViewerMedia::getInstance()->newMediaImpl(mMediaTextureID, mTextureWidth, mTextureHeight); - if ( mMediaSource ) - { - mMediaSource->setUsedInUI(true); - mMediaSource->setHomeURL(mHomePageUrl, mHomePageMimeType); - mMediaSource->setTarget(mTarget); - mMediaSource->setVisible( getVisible() ); - mMediaSource->addObserver( this ); - mMediaSource->setBackgroundColor( getBackgroundColor() ); - mMediaSource->setTrustedBrowser(mTrusted); - - F32 scale_factor = LLUI::getScaleFactor().mV[ VX ]; - if (scale_factor != mMediaSource->getPageZoomFactor()) - { - mMediaSource->setPageZoomFactor( scale_factor ); - mUpdateScrolls = true; - } - - if(mClearCache) - { - mMediaSource->clearCache(); - mClearCache = false; - } - } - else - { - LL_WARNS() << "media source create failed " << LL_ENDL; - // return; - } - } - - return !mMediaSource.isNull(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::unloadMediaSource() -{ - mMediaSource = NULL; -} - -//////////////////////////////////////////////////////////////////////////////// -// -LLPluginClassMedia* LLMediaCtrl::getMediaPlugin() -{ - return mMediaSource.isNull() ? NULL : mMediaSource->getMediaPlugin(); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::draw() -{ - F32 alpha = getDrawContext().mAlpha; - - if ( gRestoreGL == 1 || mUpdateScrolls) - { - LLRect r = getRect(); - reshape( r.getWidth(), r.getHeight(), false ); - mUpdateScrolls = false; - return; - } - - // NOTE: optimization needed here - probably only need to do this once - // unless tearoffs change the parent which they probably do. - const LLUICtrl* ptr = findRootMostFocusRoot(); - if ( ptr && ptr->hasFocus() ) - { - setFrequentUpdates( true ); - } - else - { - setFrequentUpdates( false ); - }; - - bool draw_media = false; - - LLPluginClassMedia* media_plugin = NULL; - LLViewerMediaTexture* media_texture = NULL; - - if(mMediaSource && mMediaSource->hasMedia()) - { - media_plugin = mMediaSource->getMediaPlugin(); - - if(media_plugin && (media_plugin->textureValid())) - { - media_texture = LLViewerTextureManager::findMediaTexture(mMediaTextureID); - if(media_texture) - { - draw_media = true; - } - } - } - - bool background_visible = isBackgroundVisible(); - bool background_opaque = isBackgroundOpaque(); - - if(draw_media) - { - gGL.pushUIMatrix(); - { - F32 scale_factor = LLUI::getScaleFactor().mV[ VX ]; - if (scale_factor != mMediaSource->getPageZoomFactor()) - { - mMediaSource->setPageZoomFactor( scale_factor ); - mUpdateScrolls = true; - } - - // scale texture to fit the space using texture coords - gGL.getTexUnit(0)->bind(media_texture); - LLColor4 media_color = LLColor4::white % alpha; - gGL.color4fv( media_color.mV ); - F32 max_u = ( F32 )media_plugin->getWidth() / ( F32 )media_plugin->getTextureWidth(); - F32 max_v = ( F32 )media_plugin->getHeight() / ( F32 )media_plugin->getTextureHeight(); - - S32 x_offset, y_offset, width, height; - calcOffsetsAndSize(&x_offset, &y_offset, &width, &height); - - // draw the browser - gGL.begin( LLRender::QUADS ); - if (! media_plugin->getTextureCoordsOpenGL()) - { - // render using web browser reported width and height, instead of trying to invert GL scale - gGL.texCoord2f( max_u, 0.f ); - gGL.vertex2i( x_offset + width, y_offset + height ); - - gGL.texCoord2f( 0.f, 0.f ); - gGL.vertex2i( x_offset, y_offset + height ); - - gGL.texCoord2f( 0.f, max_v ); - gGL.vertex2i( x_offset, y_offset ); - - gGL.texCoord2f( max_u, max_v ); - gGL.vertex2i( x_offset + width, y_offset ); - } - else - { - // render using web browser reported width and height, instead of trying to invert GL scale - gGL.texCoord2f( max_u, max_v ); - gGL.vertex2i( x_offset + width, y_offset + height ); - - gGL.texCoord2f( 0.f, max_v ); - gGL.vertex2i( x_offset, y_offset + height ); - - gGL.texCoord2f( 0.f, 0.f ); - gGL.vertex2i( x_offset, y_offset ); - - gGL.texCoord2f( max_u, 0.f ); - gGL.vertex2i( x_offset + width, y_offset ); - } - gGL.end(); - } - gGL.popUIMatrix(); - - } - else - { - // Setting these will make LLPanel::draw draw the opaque background color. - setBackgroundVisible(true); - setBackgroundOpaque(true); - } - - // highlight if keyboard focus here. (TODO: this needs some work) - if ( mBorder && mBorder->getVisible() ) - mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) ); - - LLPanel::draw(); - - // Restore the previous values - setBackgroundVisible(background_visible); - setBackgroundOpaque(background_opaque); -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::calcOffsetsAndSize(S32 *x_offset, S32 *y_offset, S32 *width, S32 *height) -{ - const LLRect &r = getRect(); - *x_offset = *y_offset = 0; - - if (mStretchToFill) - { - if (mMaintainAspectRatio && mMediaSource && mMediaSource->getMediaPlugin()) - { - F32 media_aspect = (F32)(mMediaSource->getMediaPlugin()->getWidth()) / (F32)(mMediaSource->getMediaPlugin()->getHeight()); - F32 view_aspect = (F32)(r.getWidth()) / (F32)(r.getHeight()); - if (media_aspect > view_aspect) - { - // max width, adjusted height - *width = r.getWidth(); - *height = llmin(llmax(ll_round(*width / media_aspect), 0), r.getHeight()); - } - else - { - // max height, adjusted width - *height = r.getHeight(); - *width = llmin(llmax(ll_round(*height * media_aspect), 0), r.getWidth()); - } - } - else - { - *width = r.getWidth(); - *height = r.getHeight(); - } - } - else - { - *width = llmin(mMediaSource->getMediaPlugin()->getWidth(), r.getWidth()); - *height = llmin(mMediaSource->getMediaPlugin()->getHeight(), r.getHeight()); - } - - *x_offset = (r.getWidth() - *width) / 2; - *y_offset = (r.getHeight() - *height) / 2; -} - -//////////////////////////////////////////////////////////////////////////////// -// -void LLMediaCtrl::convertInputCoords(S32& x, S32& y) -{ - S32 x_offset, y_offset, width, height; - calcOffsetsAndSize(&x_offset, &y_offset, &width, &height); - - x -= x_offset; - y -= y_offset; - - bool coords_opengl = false; - - if(mMediaSource && mMediaSource->hasMedia()) - { - coords_opengl = mMediaSource->getMediaPlugin()->getTextureCoordsOpenGL(); - } - - x = ll_round((F32)x * LLUI::getScaleFactor().mV[VX]); - if ( ! coords_opengl ) - { - y = ll_round((F32)(y) * LLUI::getScaleFactor().mV[VY]); - } - else - { - y = ll_round((F32)(getRect().getHeight() - y) * LLUI::getScaleFactor().mV[VY]); - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// inherited from LLViewerMediaObserver -//virtual -void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event) -{ - switch(event) - { - case MEDIA_EVENT_CONTENT_UPDATED: - { - // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << LL_ENDL; - }; - break; - - case MEDIA_EVENT_TIME_DURATION_UPDATED: - { - // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << LL_ENDL; - }; - break; - - case MEDIA_EVENT_SIZE_CHANGED: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_SIZE_CHANGED " << LL_ENDL; - LLRect r = getRect(); - reshape( r.getWidth(), r.getHeight(), false ); - }; - break; - - case MEDIA_EVENT_CURSOR_CHANGED: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL; - } - break; - - case MEDIA_EVENT_NAVIGATE_BEGIN: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL; - hideNotification(); - }; - break; - - case MEDIA_EVENT_NAVIGATE_COMPLETE: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL; - if(mHidingInitialLoad) - { - mHidingInitialLoad = false; - } - }; - break; - - case MEDIA_EVENT_PROGRESS_UPDATED: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << LL_ENDL; - }; - break; - - case MEDIA_EVENT_STATUS_TEXT_CHANGED: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << LL_ENDL; - }; - break; - - case MEDIA_EVENT_LOCATION_CHANGED: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << LL_ENDL; - }; - break; - - case MEDIA_EVENT_NAVIGATE_ERROR_PAGE: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_ERROR_PAGE" << LL_ENDL; - if ( mErrorPageURL.length() > 0 ) - { - navigateTo(mErrorPageURL, HTTP_CONTENT_TEXT_HTML); - }; - }; - break; - - case MEDIA_EVENT_CLICK_LINK_HREF: - { - // retrieve the event parameters - std::string url = self->getClickURL(); - std::string target = self->isOverrideClickTarget() ? self->getOverrideClickTarget() : self->getClickTarget(); - std::string uuid = self->getClickUUID(); - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << target << "\", uri is " << url << LL_ENDL; - - // try as slurl first - if (!LLURLDispatcher::dispatch(url, "clicked", NULL, mTrusted)) - { - LLWeb::loadURL(url, target, uuid); - } - - // 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; - }; - - case MEDIA_EVENT_CLICK_LINK_NOFOLLOW: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL; - }; - break; - - case MEDIA_EVENT_PLUGIN_FAILED: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL; - }; - break; - - case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << LL_ENDL; - }; - break; - - case MEDIA_EVENT_NAME_CHANGED: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAME_CHANGED" << LL_ENDL; - }; - break; - - case MEDIA_EVENT_CLOSE_REQUEST: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << LL_ENDL; - } - break; - - case MEDIA_EVENT_PICK_FILE_REQUEST: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL; - } - break; - - case MEDIA_EVENT_GEOMETRY_CHANGE: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL; - } - break; - - case MEDIA_EVENT_AUTH_REQUEST: - { - LLNotification::Params auth_request_params; - auth_request_params.name = "AuthRequest"; - - // pass in host name and realm for site (may be zero length but will always exist) - LLSD args; - LLURL raw_url( self->getAuthURL().c_str() ); - args["HOST_NAME"] = raw_url.getAuthority(); - args["REALM"] = self->getAuthRealm(); - auth_request_params.substitutions = args; - - auth_request_params.payload = LLSD().with("media_id", mMediaTextureID); - auth_request_params.functor.function = boost::bind(&LLViewerMedia::authSubmitCallback, _1, _2); - LLNotifications::instance().add(auth_request_params); - }; - break; - - case MEDIA_EVENT_LINK_HOVERED: - { - LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << LL_ENDL; - mHoverTextChanged = true; - }; - break; - - case MEDIA_EVENT_FILE_DOWNLOAD: - { - if (mAllowFileDownload) - { - // pick a file from SAVE FILE dialog - // for now the only thing that should be allowed to save is 360s - std::string suggested_filename = self->getFileDownloadFilename(); - LLFilePicker::ESaveFilter filter = LLFilePicker::FFSAVE_ALL; - if (suggested_filename.find(".jpg") != std::string::npos || suggested_filename.find(".jpeg") != std::string::npos) - filter = LLFilePicker::FFSAVE_JPEG; - if (suggested_filename.find(".png") != std::string::npos) - filter = LLFilePicker::FFSAVE_PNG; - - (new LLMediaFilePicker(self, filter, suggested_filename))->getFile(); - } - else - { - // Media might be blocked, waiting for a file, - // send an empty response to unblock it - const std::vector<std::string> empty_response; - self->sendPickFileResponse(empty_response); - - LLNotificationsUtil::add("MediaFileDownloadUnsupported"); - } - }; - break; - - case MEDIA_EVENT_DEBUG_MESSAGE: - { - LL_INFOS("media") << self->getDebugMessageText() << LL_ENDL; - }; - break; - }; - - // chain all events to any potential observers of this object. - emitEvent(self, event); -} - -//////////////////////////////////////////////////////////////////////////////// -// -std::string LLMediaCtrl::getCurrentNavUrl() -{ - return mCurrentNavUrl; -} - -void LLMediaCtrl::onPopup(const LLSD& notification, const LLSD& response) -{ - if (response["open"]) - { - LLWeb::loadURL(notification["payload"]["url"], notification["payload"]["target"], notification["payload"]["uuid"]); - } - else - { - // Make sure the opening instance knows its window open request was denied, so it can clean things up. - LLViewerMedia::getInstance()->proxyWindowClosed(notification["payload"]["uuid"]); - } -} - -void LLMediaCtrl::showNotification(LLNotificationPtr notify) -{ - LLWindowShade* shade = getChild<LLWindowShade>("notification_shade"); - - if (notify->getIcon() == "Popup_Caution") - { - shade->setBackgroundImage(LLUI::getUIImage("Yellow_Gradient")); - shade->setTextColor(LLColor4::black); - shade->setCanClose(true); - } - else if (notify->getName() == "AuthRequest") - { - shade->setBackgroundImage(LLUI::getUIImage("Yellow_Gradient")); - shade->setTextColor(LLColor4::black); - shade->setCanClose(false); - } - else - { - //HACK: make this a property of the notification itself, "cancellable" - shade->setCanClose(false); - shade->setTextColor(LLUIColorTable::instance().getColor("LabelTextColor")); - } - - mWindowShade->show(notify); -} - -void LLMediaCtrl::hideNotification() -{ - if (mWindowShade) - { - mWindowShade->hide(); - } -} - -void LLMediaCtrl::setTrustedContent(bool trusted) -{ - mTrusted = trusted; - if (mMediaSource) - { - mMediaSource->setTrustedBrowser(trusted); - } -} - -bool LLMediaCtrl::wantsKeyUpKeyDown() const -{ - return true; -} - -bool LLMediaCtrl::wantsReturnKey() const -{ - return true; -} +/**
+ * @file LLMediaCtrl.cpp
+ * @brief Web browser UI control
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "lltooltip.h"
+
+#include "llmediactrl.h"
+
+// viewer includes
+#include "llfloaterworldmap.h"
+#include "lluictrlfactory.h"
+#include "llurldispatcher.h"
+#include "llviewborder.h"
+#include "llviewercontrol.h"
+#include "llviewermedia.h"
+#include "llviewertexture.h"
+#include "llviewerwindow.h"
+#include "lldebugmessagebox.h"
+#include "llweb.h"
+#include "llrender.h"
+#include "llpluginclassmedia.h"
+#include "llslurl.h"
+#include "lluictrlfactory.h" // LLDefaultChildRegistry
+#include "llkeyboard.h"
+#include "llviewermenu.h"
+#include "llviewermenufile.h" // LLFilePickerThread
+
+// linden library includes
+#include "llfocusmgr.h"
+#include "llsdutil.h"
+#include "lllayoutstack.h"
+#include "lliconctrl.h"
+#include "llhttpconstants.h"
+#include "lltextbox.h"
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "lllineeditor.h"
+#include "llfloaterwebcontent.h"
+#include "llwindowshade.h"
+
+extern bool gRestoreGL;
+
+static LLDefaultChildRegistry::Register<LLMediaCtrl> r("web_browser");
+
+LLMediaCtrl::Params::Params()
+: start_url("start_url"),
+ border_visible("border_visible", true),
+ decouple_texture_size("decouple_texture_size", false),
+ texture_width("texture_width", 1024),
+ texture_height("texture_height", 1024),
+ caret_color("caret_color"),
+ initial_mime_type("initial_mime_type"),
+ error_page_url("error_page_url"),
+ media_id("media_id"),
+ trusted_content("trusted_content", false),
+ focus_on_click("focus_on_click", true)
+{
+}
+
+LLMediaCtrl::LLMediaCtrl( const Params& p) :
+ LLPanel( p ),
+ LLInstanceTracker<LLMediaCtrl, LLUUID>(LLUUID::generateNewID()),
+ mTextureDepthBytes( 4 ),
+ mBorder(NULL),
+ mFrequentUpdates( true ),
+ mForceUpdate( false ),
+ mHomePageUrl( "" ),
+ mAlwaysRefresh( false ),
+ mMediaSource( 0 ),
+ mTakeFocusOnClick( p.focus_on_click ),
+ mCurrentNavUrl( "" ),
+ mStretchToFill( true ),
+ mMaintainAspectRatio ( true ),
+ mDecoupleTextureSize ( false ),
+ mUpdateScrolls( false ),
+ mTextureWidth ( 1024 ),
+ mTextureHeight ( 1024 ),
+ mClearCache(false),
+ mHomePageMimeType(p.initial_mime_type),
+ mErrorPageURL(p.error_page_url),
+ mTrusted(p.trusted_content),
+ mWindowShade(NULL),
+ mHoverTextChanged(false),
+ mAllowFileDownload(false)
+{
+ {
+ LLColor4 color = p.caret_color().get();
+ setCaretColor( (unsigned int)color.mV[0], (unsigned int)color.mV[1], (unsigned int)color.mV[2] );
+ }
+
+ setHomePageUrl(p.start_url, p.initial_mime_type);
+
+ setBorderVisible(p.border_visible);
+
+ setDecoupleTextureSize(p.decouple_texture_size);
+
+ setTextureSize(p.texture_width, p.texture_height);
+
+ if(!getDecoupleTextureSize())
+ {
+ S32 screen_width = ll_round((F32)getRect().getWidth() * LLUI::getScaleFactor().mV[VX]);
+ S32 screen_height = ll_round((F32)getRect().getHeight() * LLUI::getScaleFactor().mV[VY]);
+
+ setTextureSize(screen_width, screen_height);
+ }
+
+ mMediaTextureID = getKey();
+
+ // We don't need to create the media source up front anymore unless we have a non-empty home URL to navigate to.
+ if(!mHomePageUrl.empty())
+ {
+ navigateHome();
+ }
+
+ LLWindowShade::Params params;
+ params.name = "notification_shade";
+ params.rect = getLocalRect();
+ params.follows.flags = FOLLOWS_ALL;
+ params.modal = true;
+
+ mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params);
+
+ addChild(mWindowShade);
+}
+
+LLMediaCtrl::~LLMediaCtrl()
+{
+ auto menu = mContextMenuHandle.get();
+ if (menu)
+ {
+ menu->die();
+ mContextMenuHandle.markDead();
+ }
+
+ if (mMediaSource)
+ {
+ mMediaSource->remObserver( this );
+ mMediaSource = NULL;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::setBorderVisible( bool border_visible )
+{
+ if ( mBorder )
+ {
+ mBorder->setVisible( border_visible );
+ };
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::setTakeFocusOnClick( bool take_focus )
+{
+ mTakeFocusOnClick = take_focus;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )
+{
+ if (LLPanel::handleHover(x, y, mask)) return true;
+ convertInputCoords(x, y);
+
+ if (mMediaSource)
+ {
+ mMediaSource->mouseMove(x, y, mask);
+ gViewerWindow->setCursor(mMediaSource->getLastSetCursor());
+ }
+
+ // TODO: Is this the right way to handle hover text changes driven by the plugin?
+ if(mHoverTextChanged)
+ {
+ mHoverTextChanged = false;
+ handleToolTip(x, y, mask);
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )
+{
+ if (LLPanel::handleScrollWheel(x, y, clicks)) return true;
+ if (mMediaSource && mMediaSource->hasMedia())
+ {
+ convertInputCoords(x, y);
+ mMediaSource->scrollWheel(x, y, 0, clicks, gKeyboard->currentMask(true));
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::handleScrollHWheel(S32 x, S32 y, S32 clicks)
+{
+ if (LLPanel::handleScrollHWheel(x, y, clicks)) return true;
+ if (mMediaSource && mMediaSource->hasMedia())
+ {
+ convertInputCoords(x, y);
+ mMediaSource->scrollWheel(x, y, clicks, 0, gKeyboard->currentMask(true));
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// virtual
+bool LLMediaCtrl::handleToolTip(S32 x, S32 y, MASK mask)
+{
+ std::string hover_text;
+
+ if (mMediaSource && mMediaSource->hasMedia())
+ hover_text = mMediaSource->getMediaPlugin()->getHoverText();
+
+ if(hover_text.empty())
+ {
+ return false;
+ }
+ else
+ {
+ S32 screen_x, screen_y;
+
+ localPointToScreen(x, y, &screen_x, &screen_y);
+ LLRect sticky_rect_screen;
+ sticky_rect_screen.setCenterAndSize(screen_x, screen_y, 20, 20);
+
+ LLToolTipMgr::instance().show(LLToolTip::Params()
+ .message(hover_text)
+ .sticky_rect(sticky_rect_screen));
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask )
+{
+ if (LLPanel::handleMouseUp(x, y, mask)) return true;
+ convertInputCoords(x, y);
+
+ if (mMediaSource)
+ {
+ mMediaSource->mouseUp(x, y, mask);
+ }
+
+ gFocusMgr.setMouseCapture( NULL );
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+ if (LLPanel::handleMouseDown(x, y, mask)) return true;
+ convertInputCoords(x, y);
+
+ if (mMediaSource)
+ mMediaSource->mouseDown(x, y, mask);
+
+ gFocusMgr.setMouseCapture( this );
+
+ if (mTakeFocusOnClick)
+ {
+ setFocus( true );
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::handleRightMouseUp( S32 x, S32 y, MASK mask )
+{
+ if (LLPanel::handleRightMouseUp(x, y, mask)) return true;
+ convertInputCoords(x, y);
+
+ if (mMediaSource)
+ {
+ mMediaSource->mouseUp(x, y, mask, 1);
+
+ // *HACK: LLMediaImplLLMozLib automatically takes focus on mouseup,
+ // in addition to the onFocusReceived() call below. Undo this. JC
+ if (!mTakeFocusOnClick)
+ {
+ mMediaSource->focus(false);
+ gViewerWindow->focusClient();
+ }
+ }
+
+ gFocusMgr.setMouseCapture( NULL );
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+ if (LLPanel::handleRightMouseDown(x, y, mask)) return true;
+
+ S32 media_x = x, media_y = y;
+ convertInputCoords(media_x, media_y);
+
+ if (mMediaSource)
+ mMediaSource->mouseDown(media_x, media_y, mask, 1);
+
+ gFocusMgr.setMouseCapture( this );
+
+ if (mTakeFocusOnClick)
+ {
+ setFocus( true );
+ }
+
+ auto menu = mContextMenuHandle.get();
+ if (!menu)
+ {
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registar;
+ registar.add("Open.WebInspector", boost::bind(&LLMediaCtrl::onOpenWebInspector, this));
+
+ // stinson 05/05/2014 : use this as the parent of the context menu if the static menu
+ // container has yet to be created
+ LLPanel* menuParent = (LLMenuGL::sMenuContainer != NULL) ? dynamic_cast<LLPanel*>(LLMenuGL::sMenuContainer) : dynamic_cast<LLPanel*>(this);
+ llassert(menuParent != NULL);
+ menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
+ "menu_media_ctrl.xml", menuParent, LLViewerMenuHolderGL::child_registry_t::instance());
+ if (menu)
+ {
+ mContextMenuHandle = menu->getHandle();
+ }
+ }
+
+ if (menu)
+ {
+ // hide/show debugging options
+ bool media_plugin_debugging_enabled = gSavedSettings.getBOOL("MediaPluginDebugging");
+ menu->setItemVisible("open_webinspector", media_plugin_debugging_enabled );
+ menu->setItemVisible("debug_separator", media_plugin_debugging_enabled );
+
+ menu->show(x, y);
+ LLMenuGL::showPopup(this, menu, x, y);
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::handleDoubleClick( S32 x, S32 y, MASK mask )
+{
+ if (LLPanel::handleDoubleClick(x, y, mask)) return true;
+ convertInputCoords(x, y);
+
+ if (mMediaSource)
+ mMediaSource->mouseDoubleClick( x, y, mask);
+
+ gFocusMgr.setMouseCapture( this );
+
+ if (mTakeFocusOnClick)
+ {
+ setFocus( true );
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::onFocusReceived()
+{
+ if (mMediaSource)
+ {
+ mMediaSource->focus(true);
+
+ // Set focus for edit menu items
+ LLEditMenuHandler::gEditMenuHandler = mMediaSource;
+ }
+
+ LLPanel::onFocusReceived();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::onFocusLost()
+{
+ if (mMediaSource)
+ {
+ mMediaSource->focus(false);
+
+ if( LLEditMenuHandler::gEditMenuHandler == mMediaSource )
+ {
+ // Clear focus for edit menu items
+ LLEditMenuHandler::gEditMenuHandler = NULL;
+ }
+ }
+
+ gViewerWindow->focusClient();
+
+ LLPanel::onFocusLost();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::postBuild ()
+{
+ setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChanged, this, _2));
+
+ return true;
+}
+
+void LLMediaCtrl::onOpenWebInspector()
+{
+ if (mMediaSource && mMediaSource->hasMedia())
+ mMediaSource->getMediaPlugin()->showWebInspector( true );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::handleKeyHere( KEY key, MASK mask )
+{
+ bool result = false;
+
+ if (mMediaSource)
+ {
+ result = mMediaSource->handleKeyHere(key, mask);
+ }
+
+ if ( ! result )
+ result = LLPanel::handleKeyHere(key, mask);
+
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+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;
+ if(mMediaSource)
+ {
+ mMediaSource->setVisible( new_visibility );
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)
+{
+ bool result = false;
+
+ if (mMediaSource)
+ {
+ result = mMediaSource->handleUnicodeCharHere(uni_char);
+ }
+
+ if ( ! result )
+ result = LLPanel::handleUnicodeCharHere(uni_char);
+
+ return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::onVisibilityChanged ( const LLSD& new_visibility )
+{
+ // set state of frequent updates automatically if visibility changes
+ if ( new_visibility.asBoolean() )
+ {
+ mFrequentUpdates = true;
+ }
+ else
+ {
+ mFrequentUpdates = false;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::reshape( S32 width, S32 height, bool called_from_parent )
+{
+ if(!getDecoupleTextureSize())
+ {
+ S32 screen_width = ll_round((F32)width * LLUI::getScaleFactor().mV[VX]);
+ S32 screen_height = ll_round((F32)height * LLUI::getScaleFactor().mV[VY]);
+
+ // when floater is minimized, these sizes are negative
+ if ( screen_height > 0 && screen_width > 0 )
+ {
+ setTextureSize(screen_width, screen_height);
+ }
+ }
+
+ LLUICtrl::reshape( width, height, called_from_parent );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::navigateBack()
+{
+ if (mMediaSource && mMediaSource->hasMedia())
+ {
+ mMediaSource->getMediaPlugin()->browse_back();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::navigateForward()
+{
+ if (mMediaSource && mMediaSource->hasMedia())
+ {
+ mMediaSource->getMediaPlugin()->browse_forward();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::navigateStop()
+{
+ if (mMediaSource && mMediaSource->hasMedia())
+ {
+ mMediaSource->getMediaPlugin()->browse_stop();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::canNavigateBack()
+{
+ if (mMediaSource)
+ return mMediaSource->canNavigateBack();
+ else
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::canNavigateForward()
+{
+ if (mMediaSource)
+ return mMediaSource->canNavigateForward();
+ else
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::clearCache()
+{
+ if(mMediaSource)
+ {
+ mMediaSource->clearCache();
+ }
+ else
+ {
+ mClearCache = true;
+ }
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type, bool clean_browser)
+{
+ // don't browse to anything that starts with secondlife:// or sl://
+ const std::string protocol1 = "secondlife://";
+ const std::string protocol2 = "sl://";
+ if ((LLStringUtil::compareInsensitive(url_in.substr(0, protocol1.length()), protocol1) == 0) ||
+ (LLStringUtil::compareInsensitive(url_in.substr(0, protocol2.length()), protocol2) == 0))
+ {
+ // TODO: Print out/log this attempt?
+ // LL_INFOS() << "Rejecting attempt to load restricted website :" << urlIn << LL_ENDL;
+ return;
+ }
+
+ if (ensureMediaSourceExists())
+ {
+ mCurrentNavUrl = url_in;
+ mMediaSource->setSize(mTextureWidth, mTextureHeight);
+ mMediaSource->navigateTo(url_in, mime_type, mime_type.empty(), false, clean_browser);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::string& filename_in )
+{
+ std::string filename(gDirUtilp->add(subdir, filename_in));
+ std::string expanded_filename = gDirUtilp->findSkinnedFilename("html", filename);
+
+ if (expanded_filename.empty())
+ {
+ LL_WARNS() << "File " << filename << "not found" << LL_ENDL;
+ return;
+ }
+ if (ensureMediaSourceExists())
+ {
+ mCurrentNavUrl = expanded_filename;
+ mMediaSource->setSize(mTextureWidth, mTextureHeight);
+ mMediaSource->navigateTo(expanded_filename, HTTP_CONTENT_TEXT_HTML, false);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::navigateHome()
+{
+ if (ensureMediaSourceExists())
+ {
+ mMediaSource->setSize(mTextureWidth, mTextureHeight);
+ mMediaSource->navigateHome();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::setHomePageUrl( const std::string& urlIn, const std::string& mime_type )
+{
+ mHomePageUrl = urlIn;
+ if (mMediaSource)
+ {
+ mMediaSource->setHomeURL(mHomePageUrl, mime_type);
+ }
+}
+
+void LLMediaCtrl::setTarget(const std::string& target)
+{
+ mTarget = target;
+ if (mMediaSource)
+ {
+ mMediaSource->setTarget(mTarget);
+ }
+}
+
+void LLMediaCtrl::setErrorPageURL(const std::string& url)
+{
+ mErrorPageURL = url;
+}
+
+const std::string& LLMediaCtrl::getErrorPageURL()
+{
+ return mErrorPageURL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned int blue)
+{
+ //NOOP
+ return false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::setTextureSize(S32 width, S32 height)
+{
+ mTextureWidth = width;
+ mTextureHeight = height;
+
+ if(mMediaSource)
+ {
+ mMediaSource->setSize(mTextureWidth, mTextureHeight);
+ mForceUpdate = true;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+std::string LLMediaCtrl::getHomePageUrl()
+{
+ return mHomePageUrl;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+bool LLMediaCtrl::ensureMediaSourceExists()
+{
+ if(mMediaSource.isNull())
+ {
+ // If we don't already have a media source, try to create one.
+ mMediaSource = LLViewerMedia::getInstance()->newMediaImpl(mMediaTextureID, mTextureWidth, mTextureHeight);
+ if ( mMediaSource )
+ {
+ mMediaSource->setUsedInUI(true);
+ mMediaSource->setHomeURL(mHomePageUrl, mHomePageMimeType);
+ mMediaSource->setTarget(mTarget);
+ mMediaSource->setVisible( getVisible() );
+ mMediaSource->addObserver( this );
+ mMediaSource->setBackgroundColor( getBackgroundColor() );
+ mMediaSource->setTrustedBrowser(mTrusted);
+
+ F32 scale_factor = LLUI::getScaleFactor().mV[ VX ];
+ if (scale_factor != mMediaSource->getPageZoomFactor())
+ {
+ mMediaSource->setPageZoomFactor( scale_factor );
+ mUpdateScrolls = true;
+ }
+
+ if(mClearCache)
+ {
+ mMediaSource->clearCache();
+ mClearCache = false;
+ }
+ }
+ else
+ {
+ LL_WARNS() << "media source create failed " << LL_ENDL;
+ // return;
+ }
+ }
+
+ return !mMediaSource.isNull();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::unloadMediaSource()
+{
+ mMediaSource = NULL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+LLPluginClassMedia* LLMediaCtrl::getMediaPlugin()
+{
+ return mMediaSource.isNull() ? NULL : mMediaSource->getMediaPlugin();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::draw()
+{
+ F32 alpha = getDrawContext().mAlpha;
+
+ if ( gRestoreGL == 1 || mUpdateScrolls)
+ {
+ LLRect r = getRect();
+ reshape( r.getWidth(), r.getHeight(), false );
+ mUpdateScrolls = false;
+ return;
+ }
+
+ // NOTE: optimization needed here - probably only need to do this once
+ // unless tearoffs change the parent which they probably do.
+ const LLUICtrl* ptr = findRootMostFocusRoot();
+ if ( ptr && ptr->hasFocus() )
+ {
+ setFrequentUpdates( true );
+ }
+ else
+ {
+ setFrequentUpdates( false );
+ };
+
+ bool draw_media = false;
+
+ LLPluginClassMedia* media_plugin = NULL;
+ LLViewerMediaTexture* media_texture = NULL;
+
+ if(mMediaSource && mMediaSource->hasMedia())
+ {
+ media_plugin = mMediaSource->getMediaPlugin();
+
+ if(media_plugin && (media_plugin->textureValid()))
+ {
+ media_texture = LLViewerTextureManager::findMediaTexture(mMediaTextureID);
+ if(media_texture)
+ {
+ draw_media = true;
+ }
+ }
+ }
+
+ bool background_visible = isBackgroundVisible();
+ bool background_opaque = isBackgroundOpaque();
+
+ if(draw_media)
+ {
+ gGL.pushUIMatrix();
+ {
+ F32 scale_factor = LLUI::getScaleFactor().mV[ VX ];
+ if (scale_factor != mMediaSource->getPageZoomFactor())
+ {
+ mMediaSource->setPageZoomFactor( scale_factor );
+ mUpdateScrolls = true;
+ }
+
+ // scale texture to fit the space using texture coords
+ gGL.getTexUnit(0)->bind(media_texture);
+ LLColor4 media_color = LLColor4::white % alpha;
+ gGL.color4fv( media_color.mV );
+ F32 max_u = ( F32 )media_plugin->getWidth() / ( F32 )media_plugin->getTextureWidth();
+ F32 max_v = ( F32 )media_plugin->getHeight() / ( F32 )media_plugin->getTextureHeight();
+
+ S32 x_offset, y_offset, width, height;
+ calcOffsetsAndSize(&x_offset, &y_offset, &width, &height);
+
+ // draw the browser
+ gGL.begin( LLRender::QUADS );
+ if (! media_plugin->getTextureCoordsOpenGL())
+ {
+ // render using web browser reported width and height, instead of trying to invert GL scale
+ gGL.texCoord2f( max_u, 0.f );
+ gGL.vertex2i( x_offset + width, y_offset + height );
+
+ gGL.texCoord2f( 0.f, 0.f );
+ gGL.vertex2i( x_offset, y_offset + height );
+
+ gGL.texCoord2f( 0.f, max_v );
+ gGL.vertex2i( x_offset, y_offset );
+
+ gGL.texCoord2f( max_u, max_v );
+ gGL.vertex2i( x_offset + width, y_offset );
+ }
+ else
+ {
+ // render using web browser reported width and height, instead of trying to invert GL scale
+ gGL.texCoord2f( max_u, max_v );
+ gGL.vertex2i( x_offset + width, y_offset + height );
+
+ gGL.texCoord2f( 0.f, max_v );
+ gGL.vertex2i( x_offset, y_offset + height );
+
+ gGL.texCoord2f( 0.f, 0.f );
+ gGL.vertex2i( x_offset, y_offset );
+
+ gGL.texCoord2f( max_u, 0.f );
+ gGL.vertex2i( x_offset + width, y_offset );
+ }
+ gGL.end();
+ }
+ gGL.popUIMatrix();
+
+ }
+ else
+ {
+ // Setting these will make LLPanel::draw draw the opaque background color.
+ setBackgroundVisible(true);
+ setBackgroundOpaque(true);
+ }
+
+ // highlight if keyboard focus here. (TODO: this needs some work)
+ if ( mBorder && mBorder->getVisible() )
+ mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) );
+
+ LLPanel::draw();
+
+ // Restore the previous values
+ setBackgroundVisible(background_visible);
+ setBackgroundOpaque(background_opaque);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::calcOffsetsAndSize(S32 *x_offset, S32 *y_offset, S32 *width, S32 *height)
+{
+ const LLRect &r = getRect();
+ *x_offset = *y_offset = 0;
+
+ if (mStretchToFill)
+ {
+ if (mMaintainAspectRatio && mMediaSource && mMediaSource->getMediaPlugin())
+ {
+ F32 media_aspect = (F32)(mMediaSource->getMediaPlugin()->getWidth()) / (F32)(mMediaSource->getMediaPlugin()->getHeight());
+ F32 view_aspect = (F32)(r.getWidth()) / (F32)(r.getHeight());
+ if (media_aspect > view_aspect)
+ {
+ // max width, adjusted height
+ *width = r.getWidth();
+ *height = llmin(llmax(ll_round(*width / media_aspect), 0), r.getHeight());
+ }
+ else
+ {
+ // max height, adjusted width
+ *height = r.getHeight();
+ *width = llmin(llmax(ll_round(*height * media_aspect), 0), r.getWidth());
+ }
+ }
+ else
+ {
+ *width = r.getWidth();
+ *height = r.getHeight();
+ }
+ }
+ else
+ {
+ *width = llmin(mMediaSource->getMediaPlugin()->getWidth(), r.getWidth());
+ *height = llmin(mMediaSource->getMediaPlugin()->getHeight(), r.getHeight());
+ }
+
+ *x_offset = (r.getWidth() - *width) / 2;
+ *y_offset = (r.getHeight() - *height) / 2;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+void LLMediaCtrl::convertInputCoords(S32& x, S32& y)
+{
+ S32 x_offset, y_offset, width, height;
+ calcOffsetsAndSize(&x_offset, &y_offset, &width, &height);
+
+ x -= x_offset;
+ y -= y_offset;
+
+ bool coords_opengl = false;
+
+ if(mMediaSource && mMediaSource->hasMedia())
+ {
+ coords_opengl = mMediaSource->getMediaPlugin()->getTextureCoordsOpenGL();
+ }
+
+ x = ll_round((F32)x * LLUI::getScaleFactor().mV[VX]);
+ if ( ! coords_opengl )
+ {
+ y = ll_round((F32)(y) * LLUI::getScaleFactor().mV[VY]);
+ }
+ else
+ {
+ y = ll_round((F32)(getRect().getHeight() - y) * LLUI::getScaleFactor().mV[VY]);
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// inherited from LLViewerMediaObserver
+//virtual
+void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+ switch(event)
+ {
+ case MEDIA_EVENT_CONTENT_UPDATED:
+ {
+ // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CONTENT_UPDATED " << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_TIME_DURATION_UPDATED:
+ {
+ // LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_TIME_DURATION_UPDATED, time is " << self->getCurrentTime() << " of " << self->getDuration() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_SIZE_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_SIZE_CHANGED " << LL_ENDL;
+ LLRect r = getRect();
+ reshape( r.getWidth(), r.getHeight(), false );
+ };
+ break;
+
+ case MEDIA_EVENT_CURSOR_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL;
+ }
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_BEGIN:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL;
+ hideNotification();
+ };
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_COMPLETE:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_COMPLETE, result string is: " << self->getNavigateResultString() << LL_ENDL;
+ if(mHidingInitialLoad)
+ {
+ mHidingInitialLoad = false;
+ }
+ };
+ break;
+
+ case MEDIA_EVENT_PROGRESS_UPDATED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PROGRESS_UPDATED, loading at " << self->getProgressPercent() << "%" << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_STATUS_TEXT_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_STATUS_TEXT_CHANGED, new status text is: " << self->getStatusText() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_LOCATION_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LOCATION_CHANGED, new uri is: " << self->getLocation() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_NAVIGATE_ERROR_PAGE:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_ERROR_PAGE" << LL_ENDL;
+ if ( mErrorPageURL.length() > 0 )
+ {
+ navigateTo(mErrorPageURL, HTTP_CONTENT_TEXT_HTML);
+ };
+ };
+ break;
+
+ case MEDIA_EVENT_CLICK_LINK_HREF:
+ {
+ // retrieve the event parameters
+ std::string url = self->getClickURL();
+ std::string target = self->isOverrideClickTarget() ? self->getOverrideClickTarget() : self->getClickTarget();
+ std::string uuid = self->getClickUUID();
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << target << "\", uri is " << url << LL_ENDL;
+
+ // try as slurl first
+ if (!LLURLDispatcher::dispatch(url, "clicked", NULL, mTrusted))
+ {
+ LLWeb::loadURL(url, target, uuid);
+ }
+
+ // 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;
+ };
+
+ case MEDIA_EVENT_CLICK_LINK_NOFOLLOW:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is " << self->getClickURL() << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_PLUGIN_FAILED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED" << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_PLUGIN_FAILED_LAUNCH:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PLUGIN_FAILED_LAUNCH" << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_NAME_CHANGED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAME_CHANGED" << LL_ENDL;
+ };
+ break;
+
+ case MEDIA_EVENT_CLOSE_REQUEST:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CLOSE_REQUEST" << LL_ENDL;
+ }
+ break;
+
+ case MEDIA_EVENT_PICK_FILE_REQUEST:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_PICK_FILE_REQUEST" << LL_ENDL;
+ }
+ break;
+
+ case MEDIA_EVENT_GEOMETRY_CHANGE:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL;
+ }
+ break;
+
+ case MEDIA_EVENT_AUTH_REQUEST:
+ {
+ LLNotification::Params auth_request_params;
+ auth_request_params.name = "AuthRequest";
+
+ // pass in host name and realm for site (may be zero length but will always exist)
+ LLSD args;
+ LLURL raw_url( self->getAuthURL().c_str() );
+ args["HOST_NAME"] = raw_url.getAuthority();
+ args["REALM"] = self->getAuthRealm();
+ auth_request_params.substitutions = args;
+
+ auth_request_params.payload = LLSD().with("media_id", mMediaTextureID);
+ auth_request_params.functor.function = boost::bind(&LLViewerMedia::authSubmitCallback, _1, _2);
+ LLNotifications::instance().add(auth_request_params);
+ };
+ break;
+
+ case MEDIA_EVENT_LINK_HOVERED:
+ {
+ LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << LL_ENDL;
+ mHoverTextChanged = true;
+ };
+ break;
+
+ case MEDIA_EVENT_FILE_DOWNLOAD:
+ {
+ if (mAllowFileDownload)
+ {
+ // pick a file from SAVE FILE dialog
+ // for now the only thing that should be allowed to save is 360s
+ std::string suggested_filename = self->getFileDownloadFilename();
+ LLFilePicker::ESaveFilter filter = LLFilePicker::FFSAVE_ALL;
+ if (suggested_filename.find(".jpg") != std::string::npos || suggested_filename.find(".jpeg") != std::string::npos)
+ filter = LLFilePicker::FFSAVE_JPEG;
+ if (suggested_filename.find(".png") != std::string::npos)
+ filter = LLFilePicker::FFSAVE_PNG;
+
+ (new LLMediaFilePicker(self, filter, suggested_filename))->getFile();
+ }
+ else
+ {
+ // Media might be blocked, waiting for a file,
+ // send an empty response to unblock it
+ const std::vector<std::string> empty_response;
+ self->sendPickFileResponse(empty_response);
+
+ LLNotificationsUtil::add("MediaFileDownloadUnsupported");
+ }
+ };
+ break;
+
+ case MEDIA_EVENT_DEBUG_MESSAGE:
+ {
+ LL_INFOS("media") << self->getDebugMessageText() << LL_ENDL;
+ };
+ break;
+ };
+
+ // chain all events to any potential observers of this object.
+ emitEvent(self, event);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//
+std::string LLMediaCtrl::getCurrentNavUrl()
+{
+ return mCurrentNavUrl;
+}
+
+void LLMediaCtrl::onPopup(const LLSD& notification, const LLSD& response)
+{
+ if (response["open"])
+ {
+ LLWeb::loadURL(notification["payload"]["url"], notification["payload"]["target"], notification["payload"]["uuid"]);
+ }
+ else
+ {
+ // Make sure the opening instance knows its window open request was denied, so it can clean things up.
+ LLViewerMedia::getInstance()->proxyWindowClosed(notification["payload"]["uuid"]);
+ }
+}
+
+void LLMediaCtrl::showNotification(LLNotificationPtr notify)
+{
+ LLWindowShade* shade = getChild<LLWindowShade>("notification_shade");
+
+ if (notify->getIcon() == "Popup_Caution")
+ {
+ shade->setBackgroundImage(LLUI::getUIImage("Yellow_Gradient"));
+ shade->setTextColor(LLColor4::black);
+ shade->setCanClose(true);
+ }
+ else if (notify->getName() == "AuthRequest")
+ {
+ shade->setBackgroundImage(LLUI::getUIImage("Yellow_Gradient"));
+ shade->setTextColor(LLColor4::black);
+ shade->setCanClose(false);
+ }
+ else
+ {
+ //HACK: make this a property of the notification itself, "cancellable"
+ shade->setCanClose(false);
+ shade->setTextColor(LLUIColorTable::instance().getColor("LabelTextColor"));
+ }
+
+ mWindowShade->show(notify);
+}
+
+void LLMediaCtrl::hideNotification()
+{
+ if (mWindowShade)
+ {
+ mWindowShade->hide();
+ }
+}
+
+void LLMediaCtrl::setTrustedContent(bool trusted)
+{
+ mTrusted = trusted;
+ if (mMediaSource)
+ {
+ mMediaSource->setTrustedBrowser(trusted);
+ }
+}
+
+bool LLMediaCtrl::wantsKeyUpKeyDown() const
+{
+ return true;
+}
+
+bool LLMediaCtrl::wantsReturnKey() const
+{
+ return true;
+}
|
