diff options
author | Ansariel <ansariel.hiller@phoenixviewer.com> | 2024-05-22 21:25:21 +0200 |
---|---|---|
committer | Andrey Lihatskiy <alihatskiy@productengine.com> | 2024-05-22 22:40:26 +0300 |
commit | e2e37cced861b98de8c1a7c9c0d3a50d2d90e433 (patch) | |
tree | 1bb897489ce524986f6196201c10ac0d8861aa5f /indra/newview/llmediactrl.cpp | |
parent | 069ea06848f766466f1a281144c82a0f2bd79f3a (diff) |
Fix line endlings
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 67412f1b38..b39a976ebd 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; +} |