diff options
Diffstat (limited to 'indra/llplugin')
| -rw-r--r-- | indra/llplugin/llpluginclassmedia.cpp | 2848 | ||||
| -rw-r--r-- | indra/llplugin/llpluginclassmedia.h | 850 | 
2 files changed, 1849 insertions, 1849 deletions
| diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index d3d0403bbb..d081109acc 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -1,1424 +1,1424 @@ -/** 
 - * @file llpluginclassmedia.cpp
 - * @brief LLPluginClassMedia handles a plugin which knows about the "media" message class.
 - *
 - * @cond
 - * $LicenseInfo:firstyear=2008&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$
 - * @endcond
 - */
 -
 -#include "linden_common.h"
 -#include "indra_constants.h"
 -
 -#include "llpluginclassmedia.h"
 -#include "llpluginmessageclasses.h"
 -
 -#include "llqtwebkit.h"
 -
 -static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256;
 -
 -static int nextPowerOf2( int value )
 -{
 -	int next_power_of_2 = 1;
 -	while ( next_power_of_2 < value )
 -	{
 -		next_power_of_2 <<= 1;
 -	}
 -	
 -	return next_power_of_2;
 -}
 -
 -LLPluginClassMedia::LLPluginClassMedia(LLPluginClassMediaOwner *owner)
 -{
 -	mOwner = owner;
 -	mPlugin = NULL;
 -	reset();
 -
 -	//debug use
 -	mDeleteOK = true ;
 -}
 -
 -
 -LLPluginClassMedia::~LLPluginClassMedia()
 -{
 -	llassert_always(mDeleteOK) ;
 -	reset();
 -}
 -
 -bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_dir, const std::string &plugin_filename, bool debug)
 -{	
 -	LL_DEBUGS("Plugin") << "launcher: " << launcher_filename << LL_ENDL;
 -	LL_DEBUGS("Plugin") << "dir: " << plugin_dir << LL_ENDL;
 -	LL_DEBUGS("Plugin") << "plugin: " << plugin_filename << LL_ENDL;
 -	
 -	mPlugin = new LLPluginProcessParent(this);
 -	mPlugin->setSleepTime(mSleepTime);
 -	
 -	// Queue up the media init message -- it will be sent after all the currently queued messages.
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "init");
 -	message.setValue("target", mTarget);
 -	sendMessage(message);
 -	
 -	mPlugin->init(launcher_filename, plugin_dir, plugin_filename, debug);
 -
 -	return true;
 -}
 -
 -
 -void LLPluginClassMedia::reset()
 -{
 -	if(mPlugin != NULL)
 -	{
 -		delete mPlugin;
 -		mPlugin = NULL;
 -	}
 -
 -	mTextureParamsReceived = false;
 -	mRequestedTextureDepth = 0;
 -	mRequestedTextureInternalFormat = 0;
 -	mRequestedTextureFormat = 0;
 -	mRequestedTextureType = 0;
 -	mRequestedTextureSwapBytes = false;
 -	mRequestedTextureCoordsOpenGL = false;
 -	mTextureSharedMemorySize = 0;
 -	mTextureSharedMemoryName.clear();
 -	mDefaultMediaWidth = 0;
 -	mDefaultMediaHeight = 0;
 -	mNaturalMediaWidth = 0;
 -	mNaturalMediaHeight = 0;
 -	mSetMediaWidth = -1;
 -	mSetMediaHeight = -1;
 -	mRequestedMediaWidth = 0;
 -	mRequestedMediaHeight = 0;
 -	mRequestedTextureWidth = 0;
 -	mRequestedTextureHeight = 0;
 -	mFullMediaWidth = 0;
 -	mFullMediaHeight = 0;
 -	mTextureWidth = 0;
 -	mTextureHeight = 0;
 -	mMediaWidth = 0;
 -	mMediaHeight = 0;
 -	mDirtyRect = LLRect::null;	
 -	mAutoScaleMedia = false;
 -	mRequestedVolume = 1.0f;
 -	mPriority = PRIORITY_NORMAL;
 -	mLowPrioritySizeLimit = LOW_PRIORITY_TEXTURE_SIZE_DEFAULT;
 -	mAllowDownsample = false;
 -	mPadding = 0;
 -	mLastMouseX = 0;
 -	mLastMouseY = 0;
 -	mStatus = LLPluginClassMediaOwner::MEDIA_NONE;
 -	mSleepTime = 1.0f / 100.0f;
 -	mCanCut = false;
 -	mCanCopy = false;
 -	mCanPaste = false;
 -	mMediaName.clear();
 -	mMediaDescription.clear();
 -	mBackgroundColor = LLColor4(1.0f, 1.0f, 1.0f, 1.0f);
 -	
 -	// media_browser class
 -	mNavigateURI.clear();
 -	mNavigateResultCode = -1;
 -	mNavigateResultString.clear();
 -	mHistoryBackAvailable = false;
 -	mHistoryForwardAvailable = false;
 -	mStatusText.clear();
 -	mProgressPercent = 0;	
 -	mClickURL.clear();
 -	mClickNavType.clear();
 -	mClickTarget.clear();
 -	mClickUUID.clear();
 -	mStatusCode = 0;
 -	
 -	// media_time class
 -	mCurrentTime = 0.0f;
 -	mDuration = 0.0f;
 -	mCurrentRate = 0.0f;
 -	mLoadedDuration = 0.0f;
 -}
 -
 -void LLPluginClassMedia::idle(void)
 -{
 -	if(mPlugin)
 -	{
 -		mPlugin->idle();
 -	}
 -	
 -	if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked()) || (mOwner == NULL))
 -	{
 -		// Can't process a size change at this time
 -	}
 -	else if((mRequestedMediaWidth != mMediaWidth) || (mRequestedMediaHeight != mMediaHeight))
 -	{
 -		// Calculate the correct size for the media texture
 -		mRequestedTextureHeight = mRequestedMediaHeight;
 -		if(mPadding < 0)
 -		{
 -			// negative values indicate the plugin wants a power of 2
 -			mRequestedTextureWidth = nextPowerOf2(mRequestedMediaWidth);
 -		}
 -		else
 -		{
 -			mRequestedTextureWidth = mRequestedMediaWidth;
 -			
 -			if(mPadding > 1)
 -			{
 -				// Pad up to a multiple of the specified number of bytes per row
 -				int rowbytes = mRequestedTextureWidth * mRequestedTextureDepth;
 -				int pad = rowbytes % mPadding;
 -				if(pad != 0)
 -				{
 -					rowbytes += mPadding - pad;
 -				}
 -				
 -				if(rowbytes % mRequestedTextureDepth == 0)
 -				{
 -					mRequestedTextureWidth = rowbytes / mRequestedTextureDepth;
 -				}
 -				else
 -				{
 -					LL_WARNS("Plugin") << "Unable to pad texture width, padding size " << mPadding << "is not a multiple of pixel size " << mRequestedTextureDepth << LL_ENDL;
 -				}
 -			}
 -		}
 -
 -		
 -		// Size change has been requested but not initiated yet.
 -		size_t newsize = mRequestedTextureWidth * mRequestedTextureHeight * mRequestedTextureDepth;
 -
 -		// Add an extra line for padding, just in case.
 -		newsize += mRequestedTextureWidth * mRequestedTextureDepth;
 -
 -		if(newsize != mTextureSharedMemorySize)
 -		{
 -			if(!mTextureSharedMemoryName.empty())
 -			{
 -				// Tell the plugin to remove the old memory segment
 -				mPlugin->removeSharedMemory(mTextureSharedMemoryName);
 -				mTextureSharedMemoryName.clear();
 -			}
 -			
 -			mTextureSharedMemorySize = newsize;
 -			mTextureSharedMemoryName = mPlugin->addSharedMemory(mTextureSharedMemorySize);
 -			if(!mTextureSharedMemoryName.empty())
 -			{
 -				void *addr = mPlugin->getSharedMemoryAddress(mTextureSharedMemoryName);
 -				
 -				// clear texture memory to avoid random screen visual fuzz from uninitialized texture data
 -				memset( addr, 0x00, newsize );
 -				
 -				// We could do this to force an update, but textureValid() will still be returning false until the first roundtrip to the plugin,
 -				// so it may not be worthwhile.
 -				// mDirtyRect.setOriginAndSize(0, 0, mRequestedMediaWidth, mRequestedMediaHeight);
 -			}
 -		}
 -		
 -		// This is our local indicator that a change is in progress.
 -		mTextureWidth = -1;
 -		mTextureHeight = -1;
 -		mMediaWidth = -1;
 -		mMediaHeight = -1;
 -
 -		// This invalidates any existing dirty rect.
 -		resetDirty();
 -		
 -		// Send a size change message to the plugin
 -		{
 -			LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change");
 -			message.setValue("name", mTextureSharedMemoryName);
 -			message.setValueS32("width", mRequestedMediaWidth);
 -			message.setValueS32("height", mRequestedMediaHeight);
 -			message.setValueS32("texture_width", mRequestedTextureWidth);
 -			message.setValueS32("texture_height", mRequestedTextureHeight);
 -			message.setValueReal("background_r", mBackgroundColor.mV[VX]);
 -			message.setValueReal("background_g", mBackgroundColor.mV[VY]);
 -			message.setValueReal("background_b", mBackgroundColor.mV[VZ]);
 -			message.setValueReal("background_a", mBackgroundColor.mV[VW]);
 -			mPlugin->sendMessage(message);	// DO NOT just use sendMessage() here -- we want this to jump ahead of the queue.
 -			
 -			LL_DEBUGS("Plugin") << "Sending size_change" << LL_ENDL;
 -		}
 -	}
 -	
 -	if(mPlugin && mPlugin->isRunning())
 -	{
 -		// Send queued messages
 -		while(!mSendQueue.empty())
 -		{
 -			LLPluginMessage message = mSendQueue.front();
 -			mSendQueue.pop();
 -			mPlugin->sendMessage(message);
 -		}
 -	}
 -}
 -
 -int LLPluginClassMedia::getTextureWidth() const
 -{
 -	return nextPowerOf2(mTextureWidth);
 -}
 -
 -int LLPluginClassMedia::getTextureHeight() const
 -{
 -	return nextPowerOf2(mTextureHeight);
 -}
 -
 -unsigned char* LLPluginClassMedia::getBitsData()
 -{
 -	unsigned char *result = NULL;
 -	if((mPlugin != NULL) && !mTextureSharedMemoryName.empty())
 -	{
 -		result = (unsigned char*)mPlugin->getSharedMemoryAddress(mTextureSharedMemoryName);
 -	}
 -	return result;
 -}
 -
 -void LLPluginClassMedia::setSize(int width, int height)
 -{
 -	if((width > 0) && (height > 0))
 -	{
 -		mSetMediaWidth = width;
 -		mSetMediaHeight = height;
 -	}
 -	else
 -	{
 -		mSetMediaWidth = -1;
 -		mSetMediaHeight = -1;
 -	}
 -
 -	setSizeInternal();
 -}
 -
 -void LLPluginClassMedia::setSizeInternal(void)
 -{
 -	if((mSetMediaWidth > 0) && (mSetMediaHeight > 0))
 -	{
 -		mRequestedMediaWidth = mSetMediaWidth;
 -		mRequestedMediaHeight = mSetMediaHeight;
 -	}
 -	else if((mNaturalMediaWidth > 0) && (mNaturalMediaHeight > 0))
 -	{
 -		mRequestedMediaWidth = mNaturalMediaWidth;
 -		mRequestedMediaHeight = mNaturalMediaHeight;
 -	}
 -	else
 -	{
 -		mRequestedMediaWidth = mDefaultMediaWidth;
 -		mRequestedMediaHeight = mDefaultMediaHeight;
 -	}
 -	
 -	// Save these for size/interest calculations
 -	mFullMediaWidth = mRequestedMediaWidth;
 -	mFullMediaHeight = mRequestedMediaHeight;
 -	
 -	if(mAllowDownsample)
 -	{
 -		switch(mPriority)
 -		{
 -			case PRIORITY_SLIDESHOW:
 -			case PRIORITY_LOW:
 -				// Reduce maximum texture dimension to (or below) mLowPrioritySizeLimit
 -				while((mRequestedMediaWidth > mLowPrioritySizeLimit) || (mRequestedMediaHeight > mLowPrioritySizeLimit))
 -				{
 -					mRequestedMediaWidth /= 2;
 -					mRequestedMediaHeight /= 2;
 -				}
 -			break;
 -			
 -			default:
 -				// Don't adjust texture size
 -			break;
 -		}
 -	}
 -	
 -	if(mAutoScaleMedia)
 -	{
 -		mRequestedMediaWidth = nextPowerOf2(mRequestedMediaWidth);
 -		mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight);
 -	}
 -	
 -	if(mRequestedMediaWidth > 2048)
 -		mRequestedMediaWidth = 2048;
 -
 -	if(mRequestedMediaHeight > 2048)
 -		mRequestedMediaHeight = 2048;
 -}
 -
 -void LLPluginClassMedia::setAutoScale(bool auto_scale)
 -{
 -	if(auto_scale != mAutoScaleMedia)
 -	{
 -		mAutoScaleMedia = auto_scale;
 -		setSizeInternal();
 -	}
 -}
 -
 -bool LLPluginClassMedia::textureValid(void)
 -{
 -	if(
 -		!mTextureParamsReceived ||
 -		mTextureWidth <= 0 ||
 -		mTextureHeight <= 0 ||
 -		mMediaWidth <= 0 ||
 -		mMediaHeight <= 0 ||
 -		mRequestedMediaWidth != mMediaWidth ||
 -		mRequestedMediaHeight != mMediaHeight ||
 -		getBitsData() == NULL
 -	)	
 -		return false;
 -	
 -	return true;
 -}
 -
 -bool LLPluginClassMedia::getDirty(LLRect *dirty_rect)
 -{
 -	bool result = !mDirtyRect.isEmpty();
 -
 -	if(dirty_rect != NULL)
 -	{
 -		*dirty_rect = mDirtyRect;
 -	}
 -
 -	return result;
 -}
 -
 -void LLPluginClassMedia::resetDirty(void)
 -{
 -	mDirtyRect = LLRect::null;
 -}
 -
 -std::string LLPluginClassMedia::translateModifiers(MASK modifiers)
 -{
 -	std::string result;
 -	
 -	
 -	if(modifiers & MASK_CONTROL)
 -	{
 -		result += "control|";
 -	}
 -
 -	if(modifiers & MASK_ALT)
 -	{
 -		result += "alt|";
 -	}
 -
 -	if(modifiers & MASK_SHIFT)
 -	{
 -		result += "shift|";
 -	}
 -
 -	// TODO: should I deal with platform differences here or in callers?
 -	// TODO: how do we deal with the Mac "command" key?
 -/*
 -	if(modifiers & MASK_SOMETHING)
 -	{
 -		result += "meta|";
 -	}
 -*/	
 -	return result;
 -}
 -
 -void LLPluginClassMedia::jsEnableObject( bool enable )
 -{
 -	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() )
 -	{
 -		return;
 -	}
 -
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_enable_object");
 -	message.setValueBoolean( "enable", enable );
 -	sendMessage( message );
 -}
 -
 -void LLPluginClassMedia::jsAgentLocationEvent( double x, double y, double z )
 -{
 -	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() )
 -	{
 -		return;
 -	}
 -
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_location");
 -	message.setValueReal( "x", x );
 -	message.setValueReal( "y", y );
 -	message.setValueReal( "z", z );
 -	sendMessage( message );
 -}
 -
 -void LLPluginClassMedia::jsAgentGlobalLocationEvent( double x, double y, double z )
 -{
 -	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() )
 -	{
 -		return;
 -	}
 -
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_global_location");
 -	message.setValueReal( "x", x );
 -	message.setValueReal( "y", y );
 -	message.setValueReal( "z", z );
 -	sendMessage( message );
 -}
 -
 -void LLPluginClassMedia::jsAgentOrientationEvent( double angle )
 -{
 -	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() )
 -	{
 -		return;
 -	}
 -
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_orientation");
 -	message.setValueReal( "angle", angle );
 -
 -	sendMessage( message );
 -}
 -
 -void LLPluginClassMedia::jsAgentLanguageEvent( const std::string& language )
 -{
 -	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() )
 -	{
 -		return;
 -	}
 -
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_language");
 -	message.setValue( "language", language );
 -	sendMessage( message );
 -}
 -
 -void LLPluginClassMedia::jsAgentRegionEvent( const std::string& region )
 -{
 -	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() )
 -	{
 -		return;
 -	}
 -
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_region");
 -	message.setValue( "region", region );
 -	sendMessage( message );
 -}
 -
 -void LLPluginClassMedia::jsAgentMaturityEvent( const std::string& maturity )
 -{
 -	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() )
 -	{
 -		return;
 -	}
 -
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_maturity");
 -	message.setValue( "maturity", maturity );
 -	sendMessage( message );
 -}
 -
 -void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int y, MASK modifiers)
 -{
 -	if(type == MOUSE_EVENT_MOVE)
 -	{
 -		if(!mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked())
 -		{
 -			// Don't queue up mouse move events that can't be delivered.
 -			return;
 -		}
 -
 -		if((x == mLastMouseX) && (y == mLastMouseY))
 -		{
 -			// Don't spam unnecessary mouse move events.
 -			return;
 -		}
 -		
 -		mLastMouseX = x;
 -		mLastMouseY = y;
 -	}
 -	
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "mouse_event");
 -	std::string temp;
 -	switch(type)
 -	{
 -		case MOUSE_EVENT_DOWN:			temp = "down";			break;
 -		case MOUSE_EVENT_UP:			temp = "up";			break;
 -		case MOUSE_EVENT_MOVE:			temp = "move";			break;
 -		case MOUSE_EVENT_DOUBLE_CLICK:	temp = "double_click";	break;
 -	}
 -	message.setValue("event", temp);
 -
 -	message.setValueS32("button", button);
 -
 -	message.setValueS32("x", x);
 -	
 -	// Incoming coordinates are OpenGL-style ((0,0) = lower left), so flip them here if the plugin has requested it.
 -	if(!mRequestedTextureCoordsOpenGL)
 -	{
 -		// TODO: Should I use mMediaHeight or mRequestedMediaHeight here?
 -		y = mMediaHeight - y;
 -	}
 -	message.setValueS32("y", y);
 -
 -	message.setValue("modifiers", translateModifiers(modifiers));
 -	
 -	sendMessage(message);
 -}
 -
 -bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data)
 -{
 -	bool result = true;
 -	
 -	// FIXME:
 -	// HACK: we don't have an easy way to tell if the plugin is going to handle a particular keycode.
 -	// For now, return false for the ones the webkit plugin won't handle properly.
 -	
 -	switch(key_code)
 -	{
 -		case KEY_BACKSPACE:		
 -		case KEY_TAB:			
 -		case KEY_RETURN:		
 -		case KEY_PAD_RETURN:	
 -		case KEY_SHIFT:			
 -		case KEY_CONTROL:		
 -		case KEY_ALT:			
 -		case KEY_CAPSLOCK:		
 -		case KEY_ESCAPE:		
 -		case KEY_PAGE_UP:		
 -		case KEY_PAGE_DOWN:		
 -		case KEY_END:			
 -		case KEY_HOME:			
 -		case KEY_LEFT:			
 -		case KEY_UP:			
 -		case KEY_RIGHT:			
 -		case KEY_DOWN:			
 -		case KEY_INSERT:		
 -		case KEY_DELETE:
 -			// These will be handled		
 -		break;
 -		
 -		default:
 -			// regular ASCII characters will also be handled
 -			if(key_code >= KEY_SPECIAL)
 -			{
 -				// Other "special" codes will not work properly.
 -				result = false;
 -			}
 -		break;
 -	}
 -
 -#if LL_DARWIN	
 -	if(modifiers & MASK_ALT)
 -	{
 -		// Option-key modified characters should be handled by the unicode input path instead of this one.
 -		result = false;
 -	}
 -#endif
 -
 -	if(result)
 -	{
 -		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "key_event");
 -		std::string temp;
 -		switch(type)
 -		{
 -			case KEY_EVENT_DOWN:			temp = "down";			break;
 -			case KEY_EVENT_UP:				temp = "up";			break;
 -			case KEY_EVENT_REPEAT:			temp = "repeat";		break;
 -		}
 -		message.setValue("event", temp);
 -		
 -		message.setValueS32("key", key_code);
 -
 -		message.setValue("modifiers", translateModifiers(modifiers));
 -		message.setValueLLSD("native_key_data", native_key_data);
 -		
 -		sendMessage(message);
 -	}
 -		
 -	return result;
 -}
 -
 -void LLPluginClassMedia::scrollEvent(int x, int y, MASK modifiers)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "scroll_event");
 -
 -	message.setValueS32("x", x);
 -	message.setValueS32("y", y);
 -	message.setValue("modifiers", translateModifiers(modifiers));
 -	
 -	sendMessage(message);
 -}
 -	
 -bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers, LLSD native_key_data)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "text_event");
 -
 -	message.setValue("text", text);
 -	message.setValue("modifiers", translateModifiers(modifiers));
 -	message.setValueLLSD("native_key_data", native_key_data);
 -	
 -	sendMessage(message);
 -	
 -	return true;
 -}
 -
 -void LLPluginClassMedia::loadURI(const std::string &uri)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "load_uri");
 -
 -	message.setValue("uri", uri);
 -	
 -	sendMessage(message);
 -}
 -
 -const char* LLPluginClassMedia::priorityToString(EPriority priority)
 -{
 -	const char* result = "UNKNOWN";
 -	switch(priority)
 -	{
 -		case PRIORITY_UNLOADED:		result = "unloaded";	break;
 -		case PRIORITY_STOPPED:		result = "stopped";		break;
 -		case PRIORITY_HIDDEN:		result = "hidden";		break;
 -		case PRIORITY_SLIDESHOW:	result = "slideshow";	break;
 -		case PRIORITY_LOW:			result = "low";			break;
 -		case PRIORITY_NORMAL:		result = "normal";		break;
 -		case PRIORITY_HIGH:			result = "high";		break;
 -	}
 -	
 -	return result;
 -}
 -
 -void LLPluginClassMedia::setPriority(EPriority priority)
 -{
 -	if(mPriority != priority)
 -	{
 -		mPriority = priority;
 -
 -		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_priority");
 -		
 -		std::string priority_string = priorityToString(priority);
 -		switch(priority)
 -		{
 -			case PRIORITY_UNLOADED:	
 -				mSleepTime = 1.0f;
 -			break;
 -			case PRIORITY_STOPPED:	
 -				mSleepTime = 1.0f;
 -			break;
 -			case PRIORITY_HIDDEN:	
 -				mSleepTime = 1.0f;
 -			break;
 -			case PRIORITY_SLIDESHOW:
 -				mSleepTime = 1.0f;
 -			break;
 -			case PRIORITY_LOW:		
 -				mSleepTime = 1.0f / 25.0f;
 -			break;
 -			case PRIORITY_NORMAL:	
 -				mSleepTime = 1.0f / 50.0f;
 -			break;
 -			case PRIORITY_HIGH:		
 -				mSleepTime = 1.0f / 100.0f;
 -			break;
 -		}
 -		
 -		message.setValue("priority", priority_string);
 -
 -		sendMessage(message);
 -		
 -		if(mPlugin)
 -		{
 -			mPlugin->setSleepTime(mSleepTime);
 -		}
 -		
 -		LL_DEBUGS("PluginPriority") << this << ": setting priority to " << priority_string << LL_ENDL;
 -		
 -		// This may affect the calculated size, so recalculate it here.
 -		setSizeInternal();
 -	}
 -}
 -
 -void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
 -{
 -	int power = nextPowerOf2(size);
 -	if(mLowPrioritySizeLimit != power)
 -	{
 -		mLowPrioritySizeLimit = power;
 -
 -		// This may affect the calculated size, so recalculate it here.
 -		setSizeInternal();
 -	}
 -}
 -
 -F64 LLPluginClassMedia::getCPUUsage()
 -{
 -	F64 result = 0.0f;
 -	
 -	if(mPlugin)
 -	{
 -		result = mPlugin->getCPUUsage();
 -	}
 -	
 -	return result;
 -}
 -
 -void LLPluginClassMedia::sendPickFileResponse(const std::string &file)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response");
 -	message.setValue("file", file);
 -	if(mPlugin && mPlugin->isBlocked())
 -	{
 -		// If the plugin sent a blocking pick-file request, the response should unblock it.
 -		message.setValueBoolean("blocking_response", true);
 -	}
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::sendAuthResponse(bool ok, const std::string &username, const std::string &password)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_response");
 -	message.setValueBoolean("ok", ok);
 -	message.setValue("username", username);
 -	message.setValue("password", password);
 -	if(mPlugin && mPlugin->isBlocked())
 -	{
 -		// If the plugin sent a blocking pick-file request, the response should unblock it.
 -		message.setValueBoolean("blocking_response", true);
 -	}
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::cut()
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut");
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::copy()
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_copy");
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::paste()
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_paste");
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_user_data_path");
 -	message.setValue("path", user_data_path);
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::setLanguageCode(const std::string &language_code)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_language_code");
 -	message.setValue("language", language_code);
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::setPluginsEnabled(const bool enabled)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "plugins_enabled");
 -	message.setValueBoolean("enable", enabled);
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::setJavascriptEnabled(const bool enabled)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "javascript_enabled");
 -	message.setValueBoolean("enable", enabled);
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::setTarget(const std::string &target)
 -{
 -	mTarget = target;
 -}
 -
 -/* virtual */ 
 -void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 -{
 -	std::string message_class = message.getClass();
 -	
 -	if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
 -	{
 -		std::string message_name = message.getName();
 -		if(message_name == "texture_params")
 -		{
 -			mRequestedTextureDepth = message.getValueS32("depth");
 -			mRequestedTextureInternalFormat = message.getValueU32("internalformat");
 -			mRequestedTextureFormat = message.getValueU32("format");
 -			mRequestedTextureType = message.getValueU32("type");
 -			mRequestedTextureSwapBytes = message.getValueBoolean("swap_bytes");
 -			mRequestedTextureCoordsOpenGL = message.getValueBoolean("coords_opengl");			
 -			
 -			// These two are optional, and will default to 0 if they're not specified.
 -			mDefaultMediaWidth = message.getValueS32("default_width");
 -			mDefaultMediaHeight = message.getValueS32("default_height");
 -			
 -			mAllowDownsample = message.getValueBoolean("allow_downsample");
 -			mPadding = message.getValueS32("padding");
 -
 -			setSizeInternal();
 -			
 -			mTextureParamsReceived = true;
 -		}
 -		else if(message_name == "updated")
 -		{			
 -			if(message.hasValue("left"))
 -			{
 -				LLRect newDirtyRect;
 -				newDirtyRect.mLeft = message.getValueS32("left");
 -				newDirtyRect.mTop = message.getValueS32("top");
 -				newDirtyRect.mRight = message.getValueS32("right");
 -				newDirtyRect.mBottom = message.getValueS32("bottom");
 -							
 -				// The plugin is likely to have top and bottom switched, due to vertical flip and OpenGL coordinate confusion.
 -				// If they're backwards, swap them.
 -				if(newDirtyRect.mTop < newDirtyRect.mBottom)
 -				{
 -					S32 temp = newDirtyRect.mTop;
 -					newDirtyRect.mTop = newDirtyRect.mBottom;
 -					newDirtyRect.mBottom = temp;
 -				}
 -				
 -				if(mDirtyRect.isEmpty())
 -				{
 -					mDirtyRect = newDirtyRect;
 -				}
 -				else
 -				{
 -					mDirtyRect.unionWith(newDirtyRect);
 -				}
 -
 -				LL_DEBUGS("Plugin") << "adjusted incoming rect is: (" 
 -					<< newDirtyRect.mLeft << ", "
 -					<< newDirtyRect.mTop << ", "
 -					<< newDirtyRect.mRight << ", "
 -					<< newDirtyRect.mBottom << "), new dirty rect is: ("
 -					<< mDirtyRect.mLeft << ", "
 -					<< mDirtyRect.mTop << ", "
 -					<< mDirtyRect.mRight << ", "
 -					<< mDirtyRect.mBottom << ")"
 -					<< LL_ENDL;
 -				
 -				mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CONTENT_UPDATED);
 -			}			
 -			
 -
 -			bool time_duration_updated = false;
 -			int previous_percent = mProgressPercent;
 -
 -			if(message.hasValue("current_time"))
 -			{
 -				mCurrentTime = message.getValueReal("current_time");
 -				time_duration_updated = true;
 -			}
 -			if(message.hasValue("duration"))
 -			{
 -				mDuration = message.getValueReal("duration");
 -				time_duration_updated = true;
 -			}
 -
 -			if(message.hasValue("current_rate"))
 -			{
 -				mCurrentRate = message.getValueReal("current_rate");
 -			}
 -			
 -			if(message.hasValue("loaded_duration"))
 -			{
 -				mLoadedDuration = message.getValueReal("loaded_duration");
 -				time_duration_updated = true;
 -			}
 -			else
 -			{
 -				// If the message doesn't contain a loaded_duration param, assume it's equal to duration
 -				mLoadedDuration = mDuration;
 -			}
 -			
 -			// Calculate a percentage based on the loaded duration and total duration.
 -			if(mDuration != 0.0f)	// Don't divide by zero.
 -			{
 -				mProgressPercent = (int)((mLoadedDuration * 100.0f)/mDuration);
 -			}
 -
 -			if(time_duration_updated)
 -			{
 -				mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_TIME_DURATION_UPDATED);
 -			}
 -			
 -			if(previous_percent != mProgressPercent)
 -			{
 -				mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PROGRESS_UPDATED);
 -			}
 -		}
 -		else if(message_name == "media_status")
 -		{
 -			std::string status = message.getValue("status");
 -			
 -			LL_DEBUGS("Plugin") << "Status changed to: " << status << LL_ENDL;
 -			
 -			if(status == "loading")
 -			{
 -				mStatus = LLPluginClassMediaOwner::MEDIA_LOADING;
 -			}
 -			else if(status == "loaded")
 -			{
 -				mStatus = LLPluginClassMediaOwner::MEDIA_LOADED;
 -			}
 -			else if(status == "error")
 -			{
 -				mStatus = LLPluginClassMediaOwner::MEDIA_ERROR;
 -			}
 -			else if(status == "playing")
 -			{
 -				mStatus = LLPluginClassMediaOwner::MEDIA_PLAYING;
 -			}
 -			else if(status == "paused")
 -			{
 -				mStatus = LLPluginClassMediaOwner::MEDIA_PAUSED;
 -			}
 -			else if(status == "done")
 -			{
 -				mStatus = LLPluginClassMediaOwner::MEDIA_DONE;
 -			}
 -			else
 -			{
 -				// empty string or any unknown string
 -				mStatus = LLPluginClassMediaOwner::MEDIA_NONE;
 -			}
 -		}
 -		else if(message_name == "size_change_request")
 -		{
 -			S32 width = message.getValueS32("width");
 -			S32 height = message.getValueS32("height");
 -			std::string name = message.getValue("name");
 -
 -			// TODO: check that name matches?
 -			mNaturalMediaWidth = width;
 -			mNaturalMediaHeight = height;
 -			
 -			setSizeInternal();
 -		}
 -		else if(message_name == "size_change_response")
 -		{
 -			std::string name = message.getValue("name");
 -			
 -			// TODO: check that name matches?
 -			
 -			mTextureWidth = message.getValueS32("texture_width");
 -			mTextureHeight = message.getValueS32("texture_height");
 -			mMediaWidth = message.getValueS32("width");
 -			mMediaHeight = message.getValueS32("height");
 -			
 -			// This invalidates any existing dirty rect.
 -			resetDirty();
 -			
 -			// TODO: should we verify that the plugin sent back the right values?  
 -			// Two size changes in a row may cause them to not match, due to queueing, etc.
 -
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_SIZE_CHANGED);
 -		}
 -		else if(message_name == "cursor_changed")
 -		{
 -			mCursorName = message.getValue("name");
 -
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CURSOR_CHANGED);
 -		}
 -		else if(message_name == "edit_state")
 -		{
 -			if(message.hasValue("cut"))
 -			{
 -				mCanCut = message.getValueBoolean("cut");
 -			}
 -			if(message.hasValue("copy"))
 -			{
 -				mCanCopy = message.getValueBoolean("copy");
 -			}
 -			if(message.hasValue("paste"))
 -			{
 -				mCanPaste = message.getValueBoolean("paste");
 -			}
 -		}
 -		else if(message_name == "name_text")
 -		{
 -			mMediaName = message.getValue("name");
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAME_CHANGED);
 -		}
 -		else if(message_name == "pick_file")
 -		{
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST);
 -		}
 -		else if(message_name == "auth_request")
 -		{
 -			mAuthURL = message.getValue("url");
 -			mAuthRealm = message.getValue("realm");
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_AUTH_REQUEST);
 -		}
 -		else
 -		{
 -			LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
 -		}
 -	}
 -	else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
 -	{
 -		std::string message_name = message.getName();
 -		if(message_name == "navigate_begin")
 -		{
 -			mNavigateURI = message.getValue("uri");
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_BEGIN);
 -		}
 -		else if(message_name == "navigate_complete")
 -		{
 -			mNavigateURI = message.getValue("uri");
 -			mNavigateResultCode = message.getValueS32("result_code");
 -			mNavigateResultString = message.getValue("result_string");
 -			mHistoryBackAvailable = message.getValueBoolean("history_back_available");
 -			mHistoryForwardAvailable = message.getValueBoolean("history_forward_available");
 -			
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_COMPLETE);
 -		}
 -		else if(message_name == "progress")
 -		{
 -			mProgressPercent = message.getValueS32("percent");
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PROGRESS_UPDATED);
 -		}
 -		else if(message_name == "status_text")
 -		{
 -			mStatusText = message.getValue("status");
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_STATUS_TEXT_CHANGED);
 -		}
 -		else if(message_name == "location_changed")
 -		{
 -			mLocation = message.getValue("uri");
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_LOCATION_CHANGED);
 -		}
 -		else if(message_name == "click_href")
 -		{
 -			mClickURL = message.getValue("uri");
 -			mClickTarget = message.getValue("target");
 -			mClickUUID = message.getValue("uuid");
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF);
 -		}
 -		else if(message_name == "click_nofollow")
 -		{
 -			mClickURL = message.getValue("uri");
 -			mClickNavType = message.getValue("nav_type");
 -			mClickTarget.clear();
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW);
 -		}
 -		else if(message_name == "navigate_error_page")
 -		{
 -			mStatusCode = message.getValueS32("status_code");
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_ERROR_PAGE);
 -		}
 -		else if(message_name == "cookie_set")
 -		{
 -			if(mOwner)
 -			{
 -				mOwner->handleCookieSet(this, message.getValue("cookie"));
 -			}
 -		}
 -		else if(message_name == "close_request")
 -		{
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLOSE_REQUEST);
 -		}
 -		else if(message_name == "geometry_change")
 -		{
 -			mClickUUID = message.getValue("uuid");
 -			mGeometryX = message.getValueS32("x");
 -			mGeometryY = message.getValueS32("y");
 -			mGeometryWidth = message.getValueS32("width");
 -			mGeometryHeight = message.getValueS32("height");
 -				
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_GEOMETRY_CHANGE);
 -		}
 -		else if(message_name == "link_hovered")
 -		{
 -			// text is not currently used -- the tooltip hover text is taken from the "title".
 -			mHoverLink = message.getValue("link");
 -			mHoverText = message.getValue("title");
 -			// message.getValue("text");
 -				
 -			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_LINK_HOVERED);
 -		}
 -		else
 -		{
 -			LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
 -		}
 -	}
 -	else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
 -	{
 -		std::string message_name = message.getName();
 -
 -		// This class hasn't defined any incoming messages yet.
 -//		if(message_name == "message_name")
 -//		{
 -//		}
 -//		else 
 -		{
 -			LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
 -		}
 -	}
 -
 -}
 -
 -/* virtual */ 
 -void LLPluginClassMedia::pluginLaunchFailed()
 -{
 -	mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED_LAUNCH);
 -}
 -
 -/* virtual */ 
 -void LLPluginClassMedia::pluginDied()
 -{
 -	mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED);
 -}
 -
 -void LLPluginClassMedia::mediaEvent(LLPluginClassMediaOwner::EMediaEvent event)
 -{
 -	if(mOwner)
 -	{
 -		mOwner->handleMediaEvent(this, event);
 -	}
 -}
 -
 -void LLPluginClassMedia::sendMessage(const LLPluginMessage &message)
 -{
 -	if(mPlugin && mPlugin->isRunning())
 -	{
 -		mPlugin->sendMessage(message);
 -	}
 -	else
 -	{
 -		// The plugin isn't set up yet -- queue this message to be sent after initialization.
 -		mSendQueue.push(message);
 -	}
 -}
 -
 -////////////////////////////////////////////////////////////
 -// MARK: media_browser class functions
 -bool LLPluginClassMedia::pluginSupportsMediaBrowser(void)
 -{
 -	std::string version = mPlugin->getMessageClassVersion(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER);
 -	return !version.empty();
 -}
 -
 -void LLPluginClassMedia::focus(bool focused)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "focus");
 -
 -	message.setValueBoolean("focused", focused);
 -	
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::clear_cache()
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "clear_cache");
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::clear_cookies()
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "clear_cookies");
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::set_cookies(const std::string &cookies)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_cookies");
 -	message.setValue("cookies", cookies);	
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::enable_cookies(bool enable)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "enable_cookies");
 -	message.setValueBoolean("enable", enable);
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::proxy_setup(bool enable, const std::string &host, int port)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_setup");
 -
 -	message.setValueBoolean("enable", enable);
 -	message.setValue("host", host);
 -	message.setValueS32("port", port);
 -
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::browse_stop()
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_stop");
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::browse_reload(bool ignore_cache)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_reload");
 -
 -	message.setValueBoolean("ignore_cache", ignore_cache);
 -	
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::browse_forward()
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_forward");
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::browse_back()
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_back");
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::setBrowserUserAgent(const std::string& user_agent)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_user_agent");
 -
 -	message.setValue("user_agent", user_agent);
 -
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::proxyWindowOpened(const std::string &target, const std::string &uuid)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_window_opened");
 -
 -	message.setValue("target", target);
 -	message.setValue("uuid", uuid);
 -
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::proxyWindowClosed(const std::string &uuid)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_window_closed");
 -
 -	message.setValue("uuid", uuid);
 -
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::ignore_ssl_cert_errors(bool ignore)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "ignore_ssl_cert_errors");
 -	message.setValueBoolean("ignore", ignore);
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::addCertificateFilePath(const std::string& path)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "add_certificate_file_path");
 -	message.setValue("path", path);
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::crashPlugin()
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "crash");
 -
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::hangPlugin()
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "hang");
 -
 -	sendMessage(message);
 -}
 -
 -
 -////////////////////////////////////////////////////////////
 -// MARK: media_time class functions
 -bool LLPluginClassMedia::pluginSupportsMediaTime(void)
 -{
 -	std::string version = mPlugin->getMessageClassVersion(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME);
 -	return !version.empty();
 -}
 -
 -void LLPluginClassMedia::stop()
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "stop");
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::start(float rate)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "start");
 -
 -	message.setValueReal("rate", rate);
 -
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::pause()
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "pause");
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::seek(float time)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek");
 -
 -	message.setValueReal("time", time);
 -	
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::setLoop(bool loop)
 -{
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "set_loop");
 -
 -	message.setValueBoolean("loop", loop);
 -
 -	sendMessage(message);
 -}
 -
 -void LLPluginClassMedia::setVolume(float volume)
 -{
 -	if(volume != mRequestedVolume)
 -	{
 -		mRequestedVolume = volume;
 -		
 -		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "set_volume");
 -
 -		message.setValueReal("volume", volume);
 -		
 -		sendMessage(message);
 -	}
 -}
 -
 -float LLPluginClassMedia::getVolume()
 -{
 -	return mRequestedVolume;
 -}
 -
 -void LLPluginClassMedia::initializeUrlHistory(const LLSD& url_history)
 -{
 -	// Send URL history to plugin
 -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "init_history");
 -	message.setValueLLSD("history", url_history);
 -	sendMessage(message);
 -
 -	LL_DEBUGS("Plugin") << "Sending history" << LL_ENDL;
 -}
 -
 +/**  + * @file llpluginclassmedia.cpp + * @brief LLPluginClassMedia handles a plugin which knows about the "media" message class. + * + * @cond + * $LicenseInfo:firstyear=2008&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$ + * @endcond + */ + +#include "linden_common.h" +#include "indra_constants.h" + +#include "llpluginclassmedia.h" +#include "llpluginmessageclasses.h" + +#include "llqtwebkit.h" + +static int LOW_PRIORITY_TEXTURE_SIZE_DEFAULT = 256; + +static int nextPowerOf2( int value ) +{ +	int next_power_of_2 = 1; +	while ( next_power_of_2 < value ) +	{ +		next_power_of_2 <<= 1; +	} +	 +	return next_power_of_2; +} + +LLPluginClassMedia::LLPluginClassMedia(LLPluginClassMediaOwner *owner) +{ +	mOwner = owner; +	mPlugin = NULL; +	reset(); + +	//debug use +	mDeleteOK = true ; +} + + +LLPluginClassMedia::~LLPluginClassMedia() +{ +	llassert_always(mDeleteOK) ; +	reset(); +} + +bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_dir, const std::string &plugin_filename, bool debug) +{	 +	LL_DEBUGS("Plugin") << "launcher: " << launcher_filename << LL_ENDL; +	LL_DEBUGS("Plugin") << "dir: " << plugin_dir << LL_ENDL; +	LL_DEBUGS("Plugin") << "plugin: " << plugin_filename << LL_ENDL; +	 +	mPlugin = new LLPluginProcessParent(this); +	mPlugin->setSleepTime(mSleepTime); +	 +	// Queue up the media init message -- it will be sent after all the currently queued messages. +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "init"); +	message.setValue("target", mTarget); +	sendMessage(message); +	 +	mPlugin->init(launcher_filename, plugin_dir, plugin_filename, debug); + +	return true; +} + + +void LLPluginClassMedia::reset() +{ +	if(mPlugin != NULL) +	{ +		delete mPlugin; +		mPlugin = NULL; +	} + +	mTextureParamsReceived = false; +	mRequestedTextureDepth = 0; +	mRequestedTextureInternalFormat = 0; +	mRequestedTextureFormat = 0; +	mRequestedTextureType = 0; +	mRequestedTextureSwapBytes = false; +	mRequestedTextureCoordsOpenGL = false; +	mTextureSharedMemorySize = 0; +	mTextureSharedMemoryName.clear(); +	mDefaultMediaWidth = 0; +	mDefaultMediaHeight = 0; +	mNaturalMediaWidth = 0; +	mNaturalMediaHeight = 0; +	mSetMediaWidth = -1; +	mSetMediaHeight = -1; +	mRequestedMediaWidth = 0; +	mRequestedMediaHeight = 0; +	mRequestedTextureWidth = 0; +	mRequestedTextureHeight = 0; +	mFullMediaWidth = 0; +	mFullMediaHeight = 0; +	mTextureWidth = 0; +	mTextureHeight = 0; +	mMediaWidth = 0; +	mMediaHeight = 0; +	mDirtyRect = LLRect::null;	 +	mAutoScaleMedia = false; +	mRequestedVolume = 1.0f; +	mPriority = PRIORITY_NORMAL; +	mLowPrioritySizeLimit = LOW_PRIORITY_TEXTURE_SIZE_DEFAULT; +	mAllowDownsample = false; +	mPadding = 0; +	mLastMouseX = 0; +	mLastMouseY = 0; +	mStatus = LLPluginClassMediaOwner::MEDIA_NONE; +	mSleepTime = 1.0f / 100.0f; +	mCanCut = false; +	mCanCopy = false; +	mCanPaste = false; +	mMediaName.clear(); +	mMediaDescription.clear(); +	mBackgroundColor = LLColor4(1.0f, 1.0f, 1.0f, 1.0f); +	 +	// media_browser class +	mNavigateURI.clear(); +	mNavigateResultCode = -1; +	mNavigateResultString.clear(); +	mHistoryBackAvailable = false; +	mHistoryForwardAvailable = false; +	mStatusText.clear(); +	mProgressPercent = 0;	 +	mClickURL.clear(); +	mClickNavType.clear(); +	mClickTarget.clear(); +	mClickUUID.clear(); +	mStatusCode = 0; +	 +	// media_time class +	mCurrentTime = 0.0f; +	mDuration = 0.0f; +	mCurrentRate = 0.0f; +	mLoadedDuration = 0.0f; +} + +void LLPluginClassMedia::idle(void) +{ +	if(mPlugin) +	{ +		mPlugin->idle(); +	} +	 +	if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked()) || (mOwner == NULL)) +	{ +		// Can't process a size change at this time +	} +	else if((mRequestedMediaWidth != mMediaWidth) || (mRequestedMediaHeight != mMediaHeight)) +	{ +		// Calculate the correct size for the media texture +		mRequestedTextureHeight = mRequestedMediaHeight; +		if(mPadding < 0) +		{ +			// negative values indicate the plugin wants a power of 2 +			mRequestedTextureWidth = nextPowerOf2(mRequestedMediaWidth); +		} +		else +		{ +			mRequestedTextureWidth = mRequestedMediaWidth; +			 +			if(mPadding > 1) +			{ +				// Pad up to a multiple of the specified number of bytes per row +				int rowbytes = mRequestedTextureWidth * mRequestedTextureDepth; +				int pad = rowbytes % mPadding; +				if(pad != 0) +				{ +					rowbytes += mPadding - pad; +				} +				 +				if(rowbytes % mRequestedTextureDepth == 0) +				{ +					mRequestedTextureWidth = rowbytes / mRequestedTextureDepth; +				} +				else +				{ +					LL_WARNS("Plugin") << "Unable to pad texture width, padding size " << mPadding << "is not a multiple of pixel size " << mRequestedTextureDepth << LL_ENDL; +				} +			} +		} + +		 +		// Size change has been requested but not initiated yet. +		size_t newsize = mRequestedTextureWidth * mRequestedTextureHeight * mRequestedTextureDepth; + +		// Add an extra line for padding, just in case. +		newsize += mRequestedTextureWidth * mRequestedTextureDepth; + +		if(newsize != mTextureSharedMemorySize) +		{ +			if(!mTextureSharedMemoryName.empty()) +			{ +				// Tell the plugin to remove the old memory segment +				mPlugin->removeSharedMemory(mTextureSharedMemoryName); +				mTextureSharedMemoryName.clear(); +			} +			 +			mTextureSharedMemorySize = newsize; +			mTextureSharedMemoryName = mPlugin->addSharedMemory(mTextureSharedMemorySize); +			if(!mTextureSharedMemoryName.empty()) +			{ +				void *addr = mPlugin->getSharedMemoryAddress(mTextureSharedMemoryName); +				 +				// clear texture memory to avoid random screen visual fuzz from uninitialized texture data +				memset( addr, 0x00, newsize ); +				 +				// We could do this to force an update, but textureValid() will still be returning false until the first roundtrip to the plugin, +				// so it may not be worthwhile. +				// mDirtyRect.setOriginAndSize(0, 0, mRequestedMediaWidth, mRequestedMediaHeight); +			} +		} +		 +		// This is our local indicator that a change is in progress. +		mTextureWidth = -1; +		mTextureHeight = -1; +		mMediaWidth = -1; +		mMediaHeight = -1; + +		// This invalidates any existing dirty rect. +		resetDirty(); +		 +		// Send a size change message to the plugin +		{ +			LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change"); +			message.setValue("name", mTextureSharedMemoryName); +			message.setValueS32("width", mRequestedMediaWidth); +			message.setValueS32("height", mRequestedMediaHeight); +			message.setValueS32("texture_width", mRequestedTextureWidth); +			message.setValueS32("texture_height", mRequestedTextureHeight); +			message.setValueReal("background_r", mBackgroundColor.mV[VX]); +			message.setValueReal("background_g", mBackgroundColor.mV[VY]); +			message.setValueReal("background_b", mBackgroundColor.mV[VZ]); +			message.setValueReal("background_a", mBackgroundColor.mV[VW]); +			mPlugin->sendMessage(message);	// DO NOT just use sendMessage() here -- we want this to jump ahead of the queue. +			 +			LL_DEBUGS("Plugin") << "Sending size_change" << LL_ENDL; +		} +	} +	 +	if(mPlugin && mPlugin->isRunning()) +	{ +		// Send queued messages +		while(!mSendQueue.empty()) +		{ +			LLPluginMessage message = mSendQueue.front(); +			mSendQueue.pop(); +			mPlugin->sendMessage(message); +		} +	} +} + +int LLPluginClassMedia::getTextureWidth() const +{ +	return nextPowerOf2(mTextureWidth); +} + +int LLPluginClassMedia::getTextureHeight() const +{ +	return nextPowerOf2(mTextureHeight); +} + +unsigned char* LLPluginClassMedia::getBitsData() +{ +	unsigned char *result = NULL; +	if((mPlugin != NULL) && !mTextureSharedMemoryName.empty()) +	{ +		result = (unsigned char*)mPlugin->getSharedMemoryAddress(mTextureSharedMemoryName); +	} +	return result; +} + +void LLPluginClassMedia::setSize(int width, int height) +{ +	if((width > 0) && (height > 0)) +	{ +		mSetMediaWidth = width; +		mSetMediaHeight = height; +	} +	else +	{ +		mSetMediaWidth = -1; +		mSetMediaHeight = -1; +	} + +	setSizeInternal(); +} + +void LLPluginClassMedia::setSizeInternal(void) +{ +	if((mSetMediaWidth > 0) && (mSetMediaHeight > 0)) +	{ +		mRequestedMediaWidth = mSetMediaWidth; +		mRequestedMediaHeight = mSetMediaHeight; +	} +	else if((mNaturalMediaWidth > 0) && (mNaturalMediaHeight > 0)) +	{ +		mRequestedMediaWidth = mNaturalMediaWidth; +		mRequestedMediaHeight = mNaturalMediaHeight; +	} +	else +	{ +		mRequestedMediaWidth = mDefaultMediaWidth; +		mRequestedMediaHeight = mDefaultMediaHeight; +	} +	 +	// Save these for size/interest calculations +	mFullMediaWidth = mRequestedMediaWidth; +	mFullMediaHeight = mRequestedMediaHeight; +	 +	if(mAllowDownsample) +	{ +		switch(mPriority) +		{ +			case PRIORITY_SLIDESHOW: +			case PRIORITY_LOW: +				// Reduce maximum texture dimension to (or below) mLowPrioritySizeLimit +				while((mRequestedMediaWidth > mLowPrioritySizeLimit) || (mRequestedMediaHeight > mLowPrioritySizeLimit)) +				{ +					mRequestedMediaWidth /= 2; +					mRequestedMediaHeight /= 2; +				} +			break; +			 +			default: +				// Don't adjust texture size +			break; +		} +	} +	 +	if(mAutoScaleMedia) +	{ +		mRequestedMediaWidth = nextPowerOf2(mRequestedMediaWidth); +		mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight); +	} +	 +	if(mRequestedMediaWidth > 2048) +		mRequestedMediaWidth = 2048; + +	if(mRequestedMediaHeight > 2048) +		mRequestedMediaHeight = 2048; +} + +void LLPluginClassMedia::setAutoScale(bool auto_scale) +{ +	if(auto_scale != mAutoScaleMedia) +	{ +		mAutoScaleMedia = auto_scale; +		setSizeInternal(); +	} +} + +bool LLPluginClassMedia::textureValid(void) +{ +	if( +		!mTextureParamsReceived || +		mTextureWidth <= 0 || +		mTextureHeight <= 0 || +		mMediaWidth <= 0 || +		mMediaHeight <= 0 || +		mRequestedMediaWidth != mMediaWidth || +		mRequestedMediaHeight != mMediaHeight || +		getBitsData() == NULL +	)	 +		return false; +	 +	return true; +} + +bool LLPluginClassMedia::getDirty(LLRect *dirty_rect) +{ +	bool result = !mDirtyRect.isEmpty(); + +	if(dirty_rect != NULL) +	{ +		*dirty_rect = mDirtyRect; +	} + +	return result; +} + +void LLPluginClassMedia::resetDirty(void) +{ +	mDirtyRect = LLRect::null; +} + +std::string LLPluginClassMedia::translateModifiers(MASK modifiers) +{ +	std::string result; +	 +	 +	if(modifiers & MASK_CONTROL) +	{ +		result += "control|"; +	} + +	if(modifiers & MASK_ALT) +	{ +		result += "alt|"; +	} + +	if(modifiers & MASK_SHIFT) +	{ +		result += "shift|"; +	} + +	// TODO: should I deal with platform differences here or in callers? +	// TODO: how do we deal with the Mac "command" key? +/* +	if(modifiers & MASK_SOMETHING) +	{ +		result += "meta|"; +	} +*/	 +	return result; +} + +void LLPluginClassMedia::jsEnableObject( bool enable ) +{ +	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) +	{ +		return; +	} + +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_enable_object"); +	message.setValueBoolean( "enable", enable ); +	sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentLocationEvent( double x, double y, double z ) +{ +	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) +	{ +		return; +	} + +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_location"); +	message.setValueReal( "x", x ); +	message.setValueReal( "y", y ); +	message.setValueReal( "z", z ); +	sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentGlobalLocationEvent( double x, double y, double z ) +{ +	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) +	{ +		return; +	} + +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_global_location"); +	message.setValueReal( "x", x ); +	message.setValueReal( "y", y ); +	message.setValueReal( "z", z ); +	sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentOrientationEvent( double angle ) +{ +	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) +	{ +		return; +	} + +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_orientation"); +	message.setValueReal( "angle", angle ); + +	sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentLanguageEvent( const std::string& language ) +{ +	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) +	{ +		return; +	} + +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_language"); +	message.setValue( "language", language ); +	sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentRegionEvent( const std::string& region ) +{ +	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) +	{ +		return; +	} + +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_region"); +	message.setValue( "region", region ); +	sendMessage( message ); +} + +void LLPluginClassMedia::jsAgentMaturityEvent( const std::string& maturity ) +{ +	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) +	{ +		return; +	} + +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_agent_maturity"); +	message.setValue( "maturity", maturity ); +	sendMessage( message ); +} + +void LLPluginClassMedia::mouseEvent(EMouseEventType type, int button, int x, int y, MASK modifiers) +{ +	if(type == MOUSE_EVENT_MOVE) +	{ +		if(!mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked()) +		{ +			// Don't queue up mouse move events that can't be delivered. +			return; +		} + +		if((x == mLastMouseX) && (y == mLastMouseY)) +		{ +			// Don't spam unnecessary mouse move events. +			return; +		} +		 +		mLastMouseX = x; +		mLastMouseY = y; +	} +	 +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "mouse_event"); +	std::string temp; +	switch(type) +	{ +		case MOUSE_EVENT_DOWN:			temp = "down";			break; +		case MOUSE_EVENT_UP:			temp = "up";			break; +		case MOUSE_EVENT_MOVE:			temp = "move";			break; +		case MOUSE_EVENT_DOUBLE_CLICK:	temp = "double_click";	break; +	} +	message.setValue("event", temp); + +	message.setValueS32("button", button); + +	message.setValueS32("x", x); +	 +	// Incoming coordinates are OpenGL-style ((0,0) = lower left), so flip them here if the plugin has requested it. +	if(!mRequestedTextureCoordsOpenGL) +	{ +		// TODO: Should I use mMediaHeight or mRequestedMediaHeight here? +		y = mMediaHeight - y; +	} +	message.setValueS32("y", y); + +	message.setValue("modifiers", translateModifiers(modifiers)); +	 +	sendMessage(message); +} + +bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data) +{ +	bool result = true; +	 +	// FIXME: +	// HACK: we don't have an easy way to tell if the plugin is going to handle a particular keycode. +	// For now, return false for the ones the webkit plugin won't handle properly. +	 +	switch(key_code) +	{ +		case KEY_BACKSPACE:		 +		case KEY_TAB:			 +		case KEY_RETURN:		 +		case KEY_PAD_RETURN:	 +		case KEY_SHIFT:			 +		case KEY_CONTROL:		 +		case KEY_ALT:			 +		case KEY_CAPSLOCK:		 +		case KEY_ESCAPE:		 +		case KEY_PAGE_UP:		 +		case KEY_PAGE_DOWN:		 +		case KEY_END:			 +		case KEY_HOME:			 +		case KEY_LEFT:			 +		case KEY_UP:			 +		case KEY_RIGHT:			 +		case KEY_DOWN:			 +		case KEY_INSERT:		 +		case KEY_DELETE: +			// These will be handled		 +		break; +		 +		default: +			// regular ASCII characters will also be handled +			if(key_code >= KEY_SPECIAL) +			{ +				// Other "special" codes will not work properly. +				result = false; +			} +		break; +	} + +#if LL_DARWIN	 +	if(modifiers & MASK_ALT) +	{ +		// Option-key modified characters should be handled by the unicode input path instead of this one. +		result = false; +	} +#endif + +	if(result) +	{ +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "key_event"); +		std::string temp; +		switch(type) +		{ +			case KEY_EVENT_DOWN:			temp = "down";			break; +			case KEY_EVENT_UP:				temp = "up";			break; +			case KEY_EVENT_REPEAT:			temp = "repeat";		break; +		} +		message.setValue("event", temp); +		 +		message.setValueS32("key", key_code); + +		message.setValue("modifiers", translateModifiers(modifiers)); +		message.setValueLLSD("native_key_data", native_key_data); +		 +		sendMessage(message); +	} +		 +	return result; +} + +void LLPluginClassMedia::scrollEvent(int x, int y, MASK modifiers) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "scroll_event"); + +	message.setValueS32("x", x); +	message.setValueS32("y", y); +	message.setValue("modifiers", translateModifiers(modifiers)); +	 +	sendMessage(message); +} +	 +bool LLPluginClassMedia::textInput(const std::string &text, MASK modifiers, LLSD native_key_data) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "text_event"); + +	message.setValue("text", text); +	message.setValue("modifiers", translateModifiers(modifiers)); +	message.setValueLLSD("native_key_data", native_key_data); +	 +	sendMessage(message); +	 +	return true; +} + +void LLPluginClassMedia::loadURI(const std::string &uri) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "load_uri"); + +	message.setValue("uri", uri); +	 +	sendMessage(message); +} + +const char* LLPluginClassMedia::priorityToString(EPriority priority) +{ +	const char* result = "UNKNOWN"; +	switch(priority) +	{ +		case PRIORITY_UNLOADED:		result = "unloaded";	break; +		case PRIORITY_STOPPED:		result = "stopped";		break; +		case PRIORITY_HIDDEN:		result = "hidden";		break; +		case PRIORITY_SLIDESHOW:	result = "slideshow";	break; +		case PRIORITY_LOW:			result = "low";			break; +		case PRIORITY_NORMAL:		result = "normal";		break; +		case PRIORITY_HIGH:			result = "high";		break; +	} +	 +	return result; +} + +void LLPluginClassMedia::setPriority(EPriority priority) +{ +	if(mPriority != priority) +	{ +		mPriority = priority; + +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_priority"); +		 +		std::string priority_string = priorityToString(priority); +		switch(priority) +		{ +			case PRIORITY_UNLOADED:	 +				mSleepTime = 1.0f; +			break; +			case PRIORITY_STOPPED:	 +				mSleepTime = 1.0f; +			break; +			case PRIORITY_HIDDEN:	 +				mSleepTime = 1.0f; +			break; +			case PRIORITY_SLIDESHOW: +				mSleepTime = 1.0f; +			break; +			case PRIORITY_LOW:		 +				mSleepTime = 1.0f / 25.0f; +			break; +			case PRIORITY_NORMAL:	 +				mSleepTime = 1.0f / 50.0f; +			break; +			case PRIORITY_HIGH:		 +				mSleepTime = 1.0f / 100.0f; +			break; +		} +		 +		message.setValue("priority", priority_string); + +		sendMessage(message); +		 +		if(mPlugin) +		{ +			mPlugin->setSleepTime(mSleepTime); +		} +		 +		LL_DEBUGS("PluginPriority") << this << ": setting priority to " << priority_string << LL_ENDL; +		 +		// This may affect the calculated size, so recalculate it here. +		setSizeInternal(); +	} +} + +void LLPluginClassMedia::setLowPrioritySizeLimit(int size) +{ +	int power = nextPowerOf2(size); +	if(mLowPrioritySizeLimit != power) +	{ +		mLowPrioritySizeLimit = power; + +		// This may affect the calculated size, so recalculate it here. +		setSizeInternal(); +	} +} + +F64 LLPluginClassMedia::getCPUUsage() +{ +	F64 result = 0.0f; +	 +	if(mPlugin) +	{ +		result = mPlugin->getCPUUsage(); +	} +	 +	return result; +} + +void LLPluginClassMedia::sendPickFileResponse(const std::string &file) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response"); +	message.setValue("file", file); +	if(mPlugin && mPlugin->isBlocked()) +	{ +		// If the plugin sent a blocking pick-file request, the response should unblock it. +		message.setValueBoolean("blocking_response", true); +	} +	sendMessage(message); +} + +void LLPluginClassMedia::sendAuthResponse(bool ok, const std::string &username, const std::string &password) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_response"); +	message.setValueBoolean("ok", ok); +	message.setValue("username", username); +	message.setValue("password", password); +	if(mPlugin && mPlugin->isBlocked()) +	{ +		// If the plugin sent a blocking pick-file request, the response should unblock it. +		message.setValueBoolean("blocking_response", true); +	} +	sendMessage(message); +} + +void LLPluginClassMedia::cut() +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut"); +	sendMessage(message); +} + +void LLPluginClassMedia::copy() +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_copy"); +	sendMessage(message); +} + +void LLPluginClassMedia::paste() +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_paste"); +	sendMessage(message); +} + +void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_user_data_path"); +	message.setValue("path", user_data_path); +	sendMessage(message); +} + +void LLPluginClassMedia::setLanguageCode(const std::string &language_code) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_language_code"); +	message.setValue("language", language_code); +	sendMessage(message); +} + +void LLPluginClassMedia::setPluginsEnabled(const bool enabled) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "plugins_enabled"); +	message.setValueBoolean("enable", enabled); +	sendMessage(message); +} + +void LLPluginClassMedia::setJavascriptEnabled(const bool enabled) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "javascript_enabled"); +	message.setValueBoolean("enable", enabled); +	sendMessage(message); +} + +void LLPluginClassMedia::setTarget(const std::string &target) +{ +	mTarget = target; +} + +/* virtual */  +void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message) +{ +	std::string message_class = message.getClass(); +	 +	if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA) +	{ +		std::string message_name = message.getName(); +		if(message_name == "texture_params") +		{ +			mRequestedTextureDepth = message.getValueS32("depth"); +			mRequestedTextureInternalFormat = message.getValueU32("internalformat"); +			mRequestedTextureFormat = message.getValueU32("format"); +			mRequestedTextureType = message.getValueU32("type"); +			mRequestedTextureSwapBytes = message.getValueBoolean("swap_bytes"); +			mRequestedTextureCoordsOpenGL = message.getValueBoolean("coords_opengl");			 +			 +			// These two are optional, and will default to 0 if they're not specified. +			mDefaultMediaWidth = message.getValueS32("default_width"); +			mDefaultMediaHeight = message.getValueS32("default_height"); +			 +			mAllowDownsample = message.getValueBoolean("allow_downsample"); +			mPadding = message.getValueS32("padding"); + +			setSizeInternal(); +			 +			mTextureParamsReceived = true; +		} +		else if(message_name == "updated") +		{			 +			if(message.hasValue("left")) +			{ +				LLRect newDirtyRect; +				newDirtyRect.mLeft = message.getValueS32("left"); +				newDirtyRect.mTop = message.getValueS32("top"); +				newDirtyRect.mRight = message.getValueS32("right"); +				newDirtyRect.mBottom = message.getValueS32("bottom"); +							 +				// The plugin is likely to have top and bottom switched, due to vertical flip and OpenGL coordinate confusion. +				// If they're backwards, swap them. +				if(newDirtyRect.mTop < newDirtyRect.mBottom) +				{ +					S32 temp = newDirtyRect.mTop; +					newDirtyRect.mTop = newDirtyRect.mBottom; +					newDirtyRect.mBottom = temp; +				} +				 +				if(mDirtyRect.isEmpty()) +				{ +					mDirtyRect = newDirtyRect; +				} +				else +				{ +					mDirtyRect.unionWith(newDirtyRect); +				} + +				LL_DEBUGS("Plugin") << "adjusted incoming rect is: ("  +					<< newDirtyRect.mLeft << ", " +					<< newDirtyRect.mTop << ", " +					<< newDirtyRect.mRight << ", " +					<< newDirtyRect.mBottom << "), new dirty rect is: (" +					<< mDirtyRect.mLeft << ", " +					<< mDirtyRect.mTop << ", " +					<< mDirtyRect.mRight << ", " +					<< mDirtyRect.mBottom << ")" +					<< LL_ENDL; +				 +				mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CONTENT_UPDATED); +			}			 +			 + +			bool time_duration_updated = false; +			int previous_percent = mProgressPercent; + +			if(message.hasValue("current_time")) +			{ +				mCurrentTime = message.getValueReal("current_time"); +				time_duration_updated = true; +			} +			if(message.hasValue("duration")) +			{ +				mDuration = message.getValueReal("duration"); +				time_duration_updated = true; +			} + +			if(message.hasValue("current_rate")) +			{ +				mCurrentRate = message.getValueReal("current_rate"); +			} +			 +			if(message.hasValue("loaded_duration")) +			{ +				mLoadedDuration = message.getValueReal("loaded_duration"); +				time_duration_updated = true; +			} +			else +			{ +				// If the message doesn't contain a loaded_duration param, assume it's equal to duration +				mLoadedDuration = mDuration; +			} +			 +			// Calculate a percentage based on the loaded duration and total duration. +			if(mDuration != 0.0f)	// Don't divide by zero. +			{ +				mProgressPercent = (int)((mLoadedDuration * 100.0f)/mDuration); +			} + +			if(time_duration_updated) +			{ +				mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_TIME_DURATION_UPDATED); +			} +			 +			if(previous_percent != mProgressPercent) +			{ +				mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PROGRESS_UPDATED); +			} +		} +		else if(message_name == "media_status") +		{ +			std::string status = message.getValue("status"); +			 +			LL_DEBUGS("Plugin") << "Status changed to: " << status << LL_ENDL; +			 +			if(status == "loading") +			{ +				mStatus = LLPluginClassMediaOwner::MEDIA_LOADING; +			} +			else if(status == "loaded") +			{ +				mStatus = LLPluginClassMediaOwner::MEDIA_LOADED; +			} +			else if(status == "error") +			{ +				mStatus = LLPluginClassMediaOwner::MEDIA_ERROR; +			} +			else if(status == "playing") +			{ +				mStatus = LLPluginClassMediaOwner::MEDIA_PLAYING; +			} +			else if(status == "paused") +			{ +				mStatus = LLPluginClassMediaOwner::MEDIA_PAUSED; +			} +			else if(status == "done") +			{ +				mStatus = LLPluginClassMediaOwner::MEDIA_DONE; +			} +			else +			{ +				// empty string or any unknown string +				mStatus = LLPluginClassMediaOwner::MEDIA_NONE; +			} +		} +		else if(message_name == "size_change_request") +		{ +			S32 width = message.getValueS32("width"); +			S32 height = message.getValueS32("height"); +			std::string name = message.getValue("name"); + +			// TODO: check that name matches? +			mNaturalMediaWidth = width; +			mNaturalMediaHeight = height; +			 +			setSizeInternal(); +		} +		else if(message_name == "size_change_response") +		{ +			std::string name = message.getValue("name"); +			 +			// TODO: check that name matches? +			 +			mTextureWidth = message.getValueS32("texture_width"); +			mTextureHeight = message.getValueS32("texture_height"); +			mMediaWidth = message.getValueS32("width"); +			mMediaHeight = message.getValueS32("height"); +			 +			// This invalidates any existing dirty rect. +			resetDirty(); +			 +			// TODO: should we verify that the plugin sent back the right values?   +			// Two size changes in a row may cause them to not match, due to queueing, etc. + +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_SIZE_CHANGED); +		} +		else if(message_name == "cursor_changed") +		{ +			mCursorName = message.getValue("name"); + +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CURSOR_CHANGED); +		} +		else if(message_name == "edit_state") +		{ +			if(message.hasValue("cut")) +			{ +				mCanCut = message.getValueBoolean("cut"); +			} +			if(message.hasValue("copy")) +			{ +				mCanCopy = message.getValueBoolean("copy"); +			} +			if(message.hasValue("paste")) +			{ +				mCanPaste = message.getValueBoolean("paste"); +			} +		} +		else if(message_name == "name_text") +		{ +			mMediaName = message.getValue("name"); +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAME_CHANGED); +		} +		else if(message_name == "pick_file") +		{ +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST); +		} +		else if(message_name == "auth_request") +		{ +			mAuthURL = message.getValue("url"); +			mAuthRealm = message.getValue("realm"); +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_AUTH_REQUEST); +		} +		else +		{ +			LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; +		} +	} +	else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER) +	{ +		std::string message_name = message.getName(); +		if(message_name == "navigate_begin") +		{ +			mNavigateURI = message.getValue("uri"); +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_BEGIN); +		} +		else if(message_name == "navigate_complete") +		{ +			mNavigateURI = message.getValue("uri"); +			mNavigateResultCode = message.getValueS32("result_code"); +			mNavigateResultString = message.getValue("result_string"); +			mHistoryBackAvailable = message.getValueBoolean("history_back_available"); +			mHistoryForwardAvailable = message.getValueBoolean("history_forward_available"); +			 +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_COMPLETE); +		} +		else if(message_name == "progress") +		{ +			mProgressPercent = message.getValueS32("percent"); +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PROGRESS_UPDATED); +		} +		else if(message_name == "status_text") +		{ +			mStatusText = message.getValue("status"); +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_STATUS_TEXT_CHANGED); +		} +		else if(message_name == "location_changed") +		{ +			mLocation = message.getValue("uri"); +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_LOCATION_CHANGED); +		} +		else if(message_name == "click_href") +		{ +			mClickURL = message.getValue("uri"); +			mClickTarget = message.getValue("target"); +			mClickUUID = message.getValue("uuid"); +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_HREF); +		} +		else if(message_name == "click_nofollow") +		{ +			mClickURL = message.getValue("uri"); +			mClickNavType = message.getValue("nav_type"); +			mClickTarget.clear(); +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLICK_LINK_NOFOLLOW); +		} +		else if(message_name == "navigate_error_page") +		{ +			mStatusCode = message.getValueS32("status_code"); +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_NAVIGATE_ERROR_PAGE); +		} +		else if(message_name == "cookie_set") +		{ +			if(mOwner) +			{ +				mOwner->handleCookieSet(this, message.getValue("cookie")); +			} +		} +		else if(message_name == "close_request") +		{ +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_CLOSE_REQUEST); +		} +		else if(message_name == "geometry_change") +		{ +			mClickUUID = message.getValue("uuid"); +			mGeometryX = message.getValueS32("x"); +			mGeometryY = message.getValueS32("y"); +			mGeometryWidth = message.getValueS32("width"); +			mGeometryHeight = message.getValueS32("height"); +				 +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_GEOMETRY_CHANGE); +		} +		else if(message_name == "link_hovered") +		{ +			// text is not currently used -- the tooltip hover text is taken from the "title". +			mHoverLink = message.getValue("link"); +			mHoverText = message.getValue("title"); +			// message.getValue("text"); +				 +			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_LINK_HOVERED); +		} +		else +		{ +			LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; +		} +	} +	else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME) +	{ +		std::string message_name = message.getName(); + +		// This class hasn't defined any incoming messages yet. +//		if(message_name == "message_name") +//		{ +//		} +//		else  +		{ +			LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL; +		} +	} + +} + +/* virtual */  +void LLPluginClassMedia::pluginLaunchFailed() +{ +	mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED_LAUNCH); +} + +/* virtual */  +void LLPluginClassMedia::pluginDied() +{ +	mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PLUGIN_FAILED); +} + +void LLPluginClassMedia::mediaEvent(LLPluginClassMediaOwner::EMediaEvent event) +{ +	if(mOwner) +	{ +		mOwner->handleMediaEvent(this, event); +	} +} + +void LLPluginClassMedia::sendMessage(const LLPluginMessage &message) +{ +	if(mPlugin && mPlugin->isRunning()) +	{ +		mPlugin->sendMessage(message); +	} +	else +	{ +		// The plugin isn't set up yet -- queue this message to be sent after initialization. +		mSendQueue.push(message); +	} +} + +//////////////////////////////////////////////////////////// +// MARK: media_browser class functions +bool LLPluginClassMedia::pluginSupportsMediaBrowser(void) +{ +	std::string version = mPlugin->getMessageClassVersion(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER); +	return !version.empty(); +} + +void LLPluginClassMedia::focus(bool focused) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "focus"); + +	message.setValueBoolean("focused", focused); +	 +	sendMessage(message); +} + +void LLPluginClassMedia::clear_cache() +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "clear_cache"); +	sendMessage(message); +} + +void LLPluginClassMedia::clear_cookies() +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "clear_cookies"); +	sendMessage(message); +} + +void LLPluginClassMedia::set_cookies(const std::string &cookies) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_cookies"); +	message.setValue("cookies", cookies);	 +	sendMessage(message); +} + +void LLPluginClassMedia::enable_cookies(bool enable) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "enable_cookies"); +	message.setValueBoolean("enable", enable); +	sendMessage(message); +} + +void LLPluginClassMedia::proxy_setup(bool enable, const std::string &host, int port) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_setup"); + +	message.setValueBoolean("enable", enable); +	message.setValue("host", host); +	message.setValueS32("port", port); + +	sendMessage(message); +} + +void LLPluginClassMedia::browse_stop() +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_stop"); +	sendMessage(message); +} + +void LLPluginClassMedia::browse_reload(bool ignore_cache) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_reload"); + +	message.setValueBoolean("ignore_cache", ignore_cache); +	 +	sendMessage(message); +} + +void LLPluginClassMedia::browse_forward() +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_forward"); +	sendMessage(message); +} + +void LLPluginClassMedia::browse_back() +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "browse_back"); +	sendMessage(message); +} + +void LLPluginClassMedia::setBrowserUserAgent(const std::string& user_agent) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_user_agent"); + +	message.setValue("user_agent", user_agent); + +	sendMessage(message); +} + +void LLPluginClassMedia::proxyWindowOpened(const std::string &target, const std::string &uuid) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_window_opened"); + +	message.setValue("target", target); +	message.setValue("uuid", uuid); + +	sendMessage(message); +} + +void LLPluginClassMedia::proxyWindowClosed(const std::string &uuid) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "proxy_window_closed"); + +	message.setValue("uuid", uuid); + +	sendMessage(message); +} + +void LLPluginClassMedia::ignore_ssl_cert_errors(bool ignore) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "ignore_ssl_cert_errors"); +	message.setValueBoolean("ignore", ignore); +	sendMessage(message); +} + +void LLPluginClassMedia::addCertificateFilePath(const std::string& path) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "add_certificate_file_path"); +	message.setValue("path", path); +	sendMessage(message); +} + +void LLPluginClassMedia::crashPlugin() +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "crash"); + +	sendMessage(message); +} + +void LLPluginClassMedia::hangPlugin() +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "hang"); + +	sendMessage(message); +} + + +//////////////////////////////////////////////////////////// +// MARK: media_time class functions +bool LLPluginClassMedia::pluginSupportsMediaTime(void) +{ +	std::string version = mPlugin->getMessageClassVersion(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME); +	return !version.empty(); +} + +void LLPluginClassMedia::stop() +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "stop"); +	sendMessage(message); +} + +void LLPluginClassMedia::start(float rate) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "start"); + +	message.setValueReal("rate", rate); + +	sendMessage(message); +} + +void LLPluginClassMedia::pause() +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "pause"); +	sendMessage(message); +} + +void LLPluginClassMedia::seek(float time) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "seek"); + +	message.setValueReal("time", time); +	 +	sendMessage(message); +} + +void LLPluginClassMedia::setLoop(bool loop) +{ +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "set_loop"); + +	message.setValueBoolean("loop", loop); + +	sendMessage(message); +} + +void LLPluginClassMedia::setVolume(float volume) +{ +	if(volume != mRequestedVolume) +	{ +		mRequestedVolume = volume; +		 +		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME, "set_volume"); + +		message.setValueReal("volume", volume); +		 +		sendMessage(message); +	} +} + +float LLPluginClassMedia::getVolume() +{ +	return mRequestedVolume; +} + +void LLPluginClassMedia::initializeUrlHistory(const LLSD& url_history) +{ +	// Send URL history to plugin +	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "init_history"); +	message.setValueLLSD("history", url_history); +	sendMessage(message); + +	LL_DEBUGS("Plugin") << "Sending history" << LL_ENDL; +} + diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index ade88a5623..d32cb0afe9 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -1,425 +1,425 @@ -/** 
 - * @file llpluginclassmedia.h
 - * @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class.
 - *
 - * @cond
 - * $LicenseInfo:firstyear=2008&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$
 - * @endcond
 - */
 -
 -#ifndef LL_LLPLUGINCLASSMEDIA_H
 -#define LL_LLPLUGINCLASSMEDIA_H
 -
 -#include "llgltypes.h"
 -#include "llpluginprocessparent.h"
 -#include "llrect.h"
 -#include "llpluginclassmediaowner.h"
 -#include <queue>
 -#include "v4color.h"
 -
 -class LLPluginClassMedia : public LLPluginProcessParentOwner
 -{
 -	LOG_CLASS(LLPluginClassMedia);
 -public:
 -	LLPluginClassMedia(LLPluginClassMediaOwner *owner);
 -	~LLPluginClassMedia();
 -
 -	// local initialization, called by the media manager when creating a source
 -	bool init(const std::string &launcher_filename, 
 -					  const std::string &plugin_dir, 
 -					  const std::string &plugin_filename, 
 -					  bool debug);
 -
 -	// undoes everything init() didm called by the media manager when destroying a source
 -	void reset();
 -	
 -	void idle(void);
 -	
 -	// All of these may return 0 or an actual valid value.
 -	// Callers need to check the return for 0, and not use the values in that case.
 -	int getWidth() const { return (mMediaWidth > 0) ? mMediaWidth : 0; };
 -	int getHeight() const { return (mMediaHeight > 0) ? mMediaHeight : 0; };
 -	int getNaturalWidth() const { return mNaturalMediaWidth; };
 -	int getNaturalHeight() const { return mNaturalMediaHeight; };
 -	int getSetWidth() const { return mSetMediaWidth; };
 -	int getSetHeight() const { return mSetMediaHeight; };
 -	int getBitsWidth() const { return (mTextureWidth > 0) ? mTextureWidth : 0; };
 -	int getBitsHeight() const { return (mTextureHeight > 0) ? mTextureHeight : 0; };
 -	int getTextureWidth() const;
 -	int getTextureHeight() const;
 -	int getFullWidth() const { return mFullMediaWidth; };
 -	int getFullHeight() const { return mFullMediaHeight; };
 -	
 -	// This may return NULL.  Callers need to check for and handle this case.
 -	unsigned char* getBitsData();
 -
 -	// gets the format details of the texture data
 -	// These may return 0 if they haven't been set up yet.  The caller needs to detect this case.
 -	int getTextureDepth() const { return mRequestedTextureDepth; };
 -	int getTextureFormatInternal() const { return mRequestedTextureInternalFormat; };
 -	int getTextureFormatPrimary() const { return mRequestedTextureFormat; };
 -	int getTextureFormatType() const { return mRequestedTextureType; };
 -	bool getTextureFormatSwapBytes() const { return mRequestedTextureSwapBytes; };
 -	bool getTextureCoordsOpenGL() const { return mRequestedTextureCoordsOpenGL; };
 -
 -	void setSize(int width, int height);
 -	void setAutoScale(bool auto_scale);
 -	
 -	void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; };
 -	
 -	void setOwner(LLPluginClassMediaOwner *owner) { mOwner = owner; };
 -	
 -	// Returns true if all of the texture parameters (depth, format, size, and texture size) are set up and consistent.
 -	// This will initially be false, and will also be false for some time after setSize while the resize is processed.
 -	// Note that if this returns true, it is safe to use all the get() functions above without checking for invalid return values
 -	// until you call idle() again.
 -	bool textureValid(void);
 -	
 -	bool getDirty(LLRect *dirty_rect = NULL);
 -	void resetDirty(void);
 -	
 -	typedef enum 
 -	{
 -		MOUSE_EVENT_DOWN,
 -		MOUSE_EVENT_UP,
 -		MOUSE_EVENT_MOVE,
 -		MOUSE_EVENT_DOUBLE_CLICK
 -	}EMouseEventType;
 -	
 -	void mouseEvent(EMouseEventType type, int button, int x, int y, MASK modifiers);
 -
 -	typedef enum 
 -	{
 -		KEY_EVENT_DOWN,
 -		KEY_EVENT_UP,
 -		KEY_EVENT_REPEAT
 -	}EKeyEventType;
 -	
 -	bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data);
 -
 -	void scrollEvent(int x, int y, MASK modifiers);
 -
 -	// Javascript <-> viewer events
 -	void jsEnableObject( bool enable );
 -	void jsAgentLocationEvent( double x, double y, double z );
 -	void jsAgentGlobalLocationEvent( double x, double y, double z );
 -	void jsAgentOrientationEvent( double angle );
 -	void jsAgentLanguageEvent( const std::string& language );
 -	void jsAgentRegionEvent( const std::string& region_name );
 -	void jsAgentMaturityEvent( const std::string& maturity );
 -		
 -	// Text may be unicode (utf8 encoded)
 -	bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data);
 -	
 -	void loadURI(const std::string &uri);
 -	
 -	// "Loading" means uninitialized or any state prior to fully running (processing commands)
 -	bool isPluginLoading(void) { return mPlugin?mPlugin->isLoading():false; };
 -
 -	// "Running" means the steady state -- i.e. processing messages
 -	bool isPluginRunning(void) { return mPlugin?mPlugin->isRunning():false; };
 -	
 -	// "Exited" means any regular or error state after "Running" (plugin may have crashed or exited normally)
 -	bool isPluginExited(void) { return mPlugin?mPlugin->isDone():false; };
 -
 -	std::string getPluginVersion() { return mPlugin?mPlugin->getPluginVersion():std::string(""); };
 -
 -	bool getDisableTimeout() { return mPlugin?mPlugin->getDisableTimeout():false; };
 -	void setDisableTimeout(bool disable) { if(mPlugin) mPlugin->setDisableTimeout(disable); };
 -	
 -	// Inherited from LLPluginProcessParentOwner
 -	/* virtual */ void receivePluginMessage(const LLPluginMessage &message);
 -	/* virtual */ void pluginLaunchFailed();
 -	/* virtual */ void pluginDied();
 -	
 -	
 -	typedef enum 
 -	{
 -		PRIORITY_UNLOADED,	// media plugin isn't even loaded.
 -		PRIORITY_STOPPED,	// media is not playing, shouldn't need to update at all.
 -		PRIORITY_HIDDEN,	// media is not being displayed or is out of view, don't need to do graphic updates, but may still update audio, playhead, etc.
 -		PRIORITY_SLIDESHOW,	// media is in the far distance, updates very infrequently
 -		PRIORITY_LOW,		// media is in the distance, may be rendered at reduced size
 -		PRIORITY_NORMAL,	// normal (default) priority
 -		PRIORITY_HIGH		// media has user focus and/or is taking up most of the screen
 -	}EPriority;
 -
 -	static const char* priorityToString(EPriority priority);
 -	void setPriority(EPriority priority);
 -	void setLowPrioritySizeLimit(int size);
 -	
 -	F64 getCPUUsage();
 -	
 -	void sendPickFileResponse(const std::string &file);
 -
 -	void sendAuthResponse(bool ok, const std::string &username, const std::string &password);
 -
 -	// Valid after a MEDIA_EVENT_CURSOR_CHANGED event
 -	std::string getCursorName() const { return mCursorName; };
 -
 -	LLPluginClassMediaOwner::EMediaStatus getStatus() const { return mStatus; }
 -
 -	void	cut();
 -	bool	canCut() const { return mCanCut; };
 -
 -	void	copy();
 -	bool	canCopy() const { return mCanCopy; };
 -
 -	void	paste();
 -	bool	canPaste() const { return mCanPaste; };
 -	
 -	// These can be called before init(), and they will be queued and sent before the media init message.
 -	void	setUserDataPath(const std::string &user_data_path);
 -	void	setLanguageCode(const std::string &language_code);
 -	void	setPluginsEnabled(const bool enabled);
 -	void	setJavascriptEnabled(const bool enabled);
 -	void	setTarget(const std::string &target);
 -	
 -	///////////////////////////////////
 -	// media browser class functions
 -	bool pluginSupportsMediaBrowser(void);
 -	
 -	void focus(bool focused);
 -	void clear_cache();
 -	void clear_cookies();
 -	void set_cookies(const std::string &cookies);
 -	void enable_cookies(bool enable);
 -	void proxy_setup(bool enable, const std::string &host = LLStringUtil::null, int port = 0);
 -	void browse_stop();
 -	void browse_reload(bool ignore_cache = false);
 -	void browse_forward();
 -	void browse_back();
 -	void setBrowserUserAgent(const std::string& user_agent);
 -	void proxyWindowOpened(const std::string &target, const std::string &uuid);
 -	void proxyWindowClosed(const std::string &uuid);
 -	void ignore_ssl_cert_errors(bool ignore);
 -	void addCertificateFilePath(const std::string& path);
 -	
 -	// This is valid after MEDIA_EVENT_NAVIGATE_BEGIN or MEDIA_EVENT_NAVIGATE_COMPLETE
 -	std::string	getNavigateURI() const { return mNavigateURI; };
 -
 -	// These are valid after MEDIA_EVENT_NAVIGATE_COMPLETE
 -	S32			getNavigateResultCode() const { return mNavigateResultCode; };
 -	std::string getNavigateResultString() const { return mNavigateResultString; };
 -	bool		getHistoryBackAvailable() const { return mHistoryBackAvailable; };
 -	bool		getHistoryForwardAvailable() const { return mHistoryForwardAvailable; };
 -
 -	// This is valid after MEDIA_EVENT_PROGRESS_UPDATED
 -	int			getProgressPercent() const { return mProgressPercent; };
 -	
 -	// This is valid after MEDIA_EVENT_STATUS_TEXT_CHANGED
 -	std::string getStatusText() const { return mStatusText; };
 -	
 -	// This is valid after MEDIA_EVENT_LOCATION_CHANGED
 -	std::string getLocation() const { return mLocation; };
 -	
 -	// This is valid after MEDIA_EVENT_CLICK_LINK_HREF or MEDIA_EVENT_CLICK_LINK_NOFOLLOW
 -	std::string getClickURL() const { return mClickURL; };
 -
 -	// This is valid after MEDIA_EVENT_CLICK_LINK_NOFOLLOW
 -	std::string getClickNavType() const { return mClickNavType; };
 -
 -	// This is valid after MEDIA_EVENT_CLICK_LINK_HREF
 -	std::string getClickTarget() const { return mClickTarget; };
 -
 -	// This is valid during MEDIA_EVENT_CLICK_LINK_HREF and MEDIA_EVENT_GEOMETRY_CHANGE
 -	std::string getClickUUID() const { return mClickUUID; };
 -
 -	// This is valid after MEDIA_EVENT_NAVIGATE_ERROR_PAGE
 -	S32 getStatusCode() const { return mStatusCode; };
 -	
 -	// These are valid during MEDIA_EVENT_GEOMETRY_CHANGE
 -	S32 getGeometryX() const { return mGeometryX; };
 -	S32 getGeometryY() const { return mGeometryY; };
 -	S32 getGeometryWidth() const { return mGeometryWidth; };
 -	S32 getGeometryHeight() const { return mGeometryHeight; };
 -	
 -	// These are valid during MEDIA_EVENT_AUTH_REQUEST
 -	std::string	getAuthURL() const { return mAuthURL; };
 -	std::string	getAuthRealm() const { return mAuthRealm; };
 -
 -	// These are valid during MEDIA_EVENT_LINK_HOVERED
 -	std::string	getHoverText() const { return mHoverText; };
 -	std::string	getHoverLink() const { return mHoverLink; };
 -	
 -	std::string getMediaName() const { return mMediaName; };
 -	std::string getMediaDescription() const { return mMediaDescription; };
 -
 -	// Crash the plugin.  If you use this outside of a testbed, you will be punished.
 -	void		crashPlugin();
 -	
 -	// Hang the plugin.  If you use this outside of a testbed, you will be punished.
 -	void		hangPlugin();
 -
 -	///////////////////////////////////
 -	// media time class functions
 -	bool pluginSupportsMediaTime(void);
 -	void stop();
 -	void start(float rate = 0.0f);
 -	void pause();
 -	void seek(float time);
 -	void setLoop(bool loop);
 -	void setVolume(float volume);
 -	float getVolume();
 -	
 -	F64 getCurrentTime(void) const { return mCurrentTime; };
 -	F64 getDuration(void) const { return mDuration; };
 -	F64 getCurrentPlayRate(void) { return mCurrentRate; };
 -	F64 getLoadedDuration(void) const { return mLoadedDuration; };
 -	
 -	// Initialize the URL history of the plugin by sending
 -	// "init_history" message 
 -	void initializeUrlHistory(const LLSD& url_history);
 -
 -protected:
 -
 -	LLPluginClassMediaOwner *mOwner;
 -
 -	// Notify this object's owner that an event has occurred.
 -	void mediaEvent(LLPluginClassMediaOwner::EMediaEvent event);
 -		
 -	void sendMessage(const LLPluginMessage &message);  // Send message internally, either queueing or sending directly.
 -	std::queue<LLPluginMessage> mSendQueue;		// Used to queue messages while the plugin initializes.
 -	
 -	void setSizeInternal(void);
 -
 -	bool		mTextureParamsReceived;		// the mRequestedTexture* fields are only valid when this is true
 -	S32 		mRequestedTextureDepth;
 -	LLGLenum	mRequestedTextureInternalFormat;
 -	LLGLenum	mRequestedTextureFormat;
 -	LLGLenum	mRequestedTextureType;
 -	bool		mRequestedTextureSwapBytes;
 -	bool		mRequestedTextureCoordsOpenGL;
 -	
 -	std::string mTextureSharedMemoryName;
 -	size_t		mTextureSharedMemorySize;
 -	
 -	// True to scale requested media up to the full size of the texture (i.e. next power of two)
 -	bool		mAutoScaleMedia;
 -
 -	// default media size for the plugin, from the texture_params message.
 -	int			mDefaultMediaWidth;
 -	int			mDefaultMediaHeight;
 -
 -	// Size that has been requested by the plugin itself
 -	int			mNaturalMediaWidth;
 -	int			mNaturalMediaHeight;
 -
 -	// Size that has been requested with setSize()
 -	int			mSetMediaWidth;
 -	int			mSetMediaHeight;
 -	
 -	// Full calculated media size (before auto-scale and downsample calculations)
 -	int			mFullMediaWidth;
 -	int			mFullMediaHeight;
 -
 -	// Actual media size being set (after auto-scale)
 -	int			mRequestedMediaWidth;
 -	int			mRequestedMediaHeight;
 -	
 -	// Texture size calculated from actual media size
 -	int			mRequestedTextureWidth;
 -	int			mRequestedTextureHeight;
 -	
 -	// Size that the plugin has acknowledged
 -	int			mTextureWidth;
 -	int			mTextureHeight;
 -	int			mMediaWidth;
 -	int			mMediaHeight;
 -	
 -	float		mRequestedVolume;
 -	
 -	// Priority of this media stream
 -	EPriority	mPriority;
 -	int			mLowPrioritySizeLimit;
 -	
 -	bool		mAllowDownsample;
 -	int			mPadding;
 -	
 -	
 -	LLPluginProcessParent *mPlugin;
 -	
 -	LLRect mDirtyRect;
 -	
 -	std::string translateModifiers(MASK modifiers);
 -	
 -	std::string mCursorName;
 -	int			mLastMouseX;
 -	int			mLastMouseY;
 -
 -	LLPluginClassMediaOwner::EMediaStatus mStatus;
 -	
 -	F64				mSleepTime;
 -
 -	bool			mCanCut;
 -	bool			mCanCopy;
 -	bool			mCanPaste;
 -	
 -	std::string		mMediaName;
 -	std::string		mMediaDescription;
 -	
 -	LLColor4		mBackgroundColor;
 -	
 -	std::string		mTarget;
 -	
 -	/////////////////////////////////////////
 -	// media_browser class
 -	std::string		mNavigateURI;
 -	S32				mNavigateResultCode;
 -	std::string		mNavigateResultString;
 -	bool			mHistoryBackAvailable;
 -	bool			mHistoryForwardAvailable;
 -	std::string		mStatusText;
 -	int				mProgressPercent;
 -	std::string		mLocation;
 -	std::string		mClickURL;
 -	std::string		mClickNavType;
 -	std::string		mClickTarget;
 -	std::string		mClickUUID;
 -	S32				mGeometryX;
 -	S32				mGeometryY;
 -	S32				mGeometryWidth;
 -	S32				mGeometryHeight;
 -	S32				mStatusCode;
 -	std::string		mAuthURL;
 -	std::string		mAuthRealm;
 -	std::string		mHoverText;
 -	std::string		mHoverLink;
 -	
 -	/////////////////////////////////////////
 -	// media_time class
 -	F64				mCurrentTime;
 -	F64				mDuration;
 -	F64				mCurrentRate;
 -	F64				mLoadedDuration;
 -	
 -//--------------------------------------
 -	//debug use only
 -	//
 -private:
 -	bool  mDeleteOK ;
 -public:
 -	void setDeleteOK(bool flag) { mDeleteOK = flag ;}
 -//--------------------------------------
 -};
 -
 -#endif // LL_LLPLUGINCLASSMEDIA_H
 +/**  + * @file llpluginclassmedia.h + * @brief LLPluginClassMedia handles interaction with a plugin which knows about the "media" message class. + * + * @cond + * $LicenseInfo:firstyear=2008&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$ + * @endcond + */ + +#ifndef LL_LLPLUGINCLASSMEDIA_H +#define LL_LLPLUGINCLASSMEDIA_H + +#include "llgltypes.h" +#include "llpluginprocessparent.h" +#include "llrect.h" +#include "llpluginclassmediaowner.h" +#include <queue> +#include "v4color.h" + +class LLPluginClassMedia : public LLPluginProcessParentOwner +{ +	LOG_CLASS(LLPluginClassMedia); +public: +	LLPluginClassMedia(LLPluginClassMediaOwner *owner); +	~LLPluginClassMedia(); + +	// local initialization, called by the media manager when creating a source +	bool init(const std::string &launcher_filename,  +					  const std::string &plugin_dir,  +					  const std::string &plugin_filename,  +					  bool debug); + +	// undoes everything init() didm called by the media manager when destroying a source +	void reset(); +	 +	void idle(void); +	 +	// All of these may return 0 or an actual valid value. +	// Callers need to check the return for 0, and not use the values in that case. +	int getWidth() const { return (mMediaWidth > 0) ? mMediaWidth : 0; }; +	int getHeight() const { return (mMediaHeight > 0) ? mMediaHeight : 0; }; +	int getNaturalWidth() const { return mNaturalMediaWidth; }; +	int getNaturalHeight() const { return mNaturalMediaHeight; }; +	int getSetWidth() const { return mSetMediaWidth; }; +	int getSetHeight() const { return mSetMediaHeight; }; +	int getBitsWidth() const { return (mTextureWidth > 0) ? mTextureWidth : 0; }; +	int getBitsHeight() const { return (mTextureHeight > 0) ? mTextureHeight : 0; }; +	int getTextureWidth() const; +	int getTextureHeight() const; +	int getFullWidth() const { return mFullMediaWidth; }; +	int getFullHeight() const { return mFullMediaHeight; }; +	 +	// This may return NULL.  Callers need to check for and handle this case. +	unsigned char* getBitsData(); + +	// gets the format details of the texture data +	// These may return 0 if they haven't been set up yet.  The caller needs to detect this case. +	int getTextureDepth() const { return mRequestedTextureDepth; }; +	int getTextureFormatInternal() const { return mRequestedTextureInternalFormat; }; +	int getTextureFormatPrimary() const { return mRequestedTextureFormat; }; +	int getTextureFormatType() const { return mRequestedTextureType; }; +	bool getTextureFormatSwapBytes() const { return mRequestedTextureSwapBytes; }; +	bool getTextureCoordsOpenGL() const { return mRequestedTextureCoordsOpenGL; }; + +	void setSize(int width, int height); +	void setAutoScale(bool auto_scale); +	 +	void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; }; +	 +	void setOwner(LLPluginClassMediaOwner *owner) { mOwner = owner; }; +	 +	// Returns true if all of the texture parameters (depth, format, size, and texture size) are set up and consistent. +	// This will initially be false, and will also be false for some time after setSize while the resize is processed. +	// Note that if this returns true, it is safe to use all the get() functions above without checking for invalid return values +	// until you call idle() again. +	bool textureValid(void); +	 +	bool getDirty(LLRect *dirty_rect = NULL); +	void resetDirty(void); +	 +	typedef enum  +	{ +		MOUSE_EVENT_DOWN, +		MOUSE_EVENT_UP, +		MOUSE_EVENT_MOVE, +		MOUSE_EVENT_DOUBLE_CLICK +	}EMouseEventType; +	 +	void mouseEvent(EMouseEventType type, int button, int x, int y, MASK modifiers); + +	typedef enum  +	{ +		KEY_EVENT_DOWN, +		KEY_EVENT_UP, +		KEY_EVENT_REPEAT +	}EKeyEventType; +	 +	bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data); + +	void scrollEvent(int x, int y, MASK modifiers); + +	// Javascript <-> viewer events +	void jsEnableObject( bool enable ); +	void jsAgentLocationEvent( double x, double y, double z ); +	void jsAgentGlobalLocationEvent( double x, double y, double z ); +	void jsAgentOrientationEvent( double angle ); +	void jsAgentLanguageEvent( const std::string& language ); +	void jsAgentRegionEvent( const std::string& region_name ); +	void jsAgentMaturityEvent( const std::string& maturity ); +		 +	// Text may be unicode (utf8 encoded) +	bool textInput(const std::string &text, MASK modifiers, LLSD native_key_data); +	 +	void loadURI(const std::string &uri); +	 +	// "Loading" means uninitialized or any state prior to fully running (processing commands) +	bool isPluginLoading(void) { return mPlugin?mPlugin->isLoading():false; }; + +	// "Running" means the steady state -- i.e. processing messages +	bool isPluginRunning(void) { return mPlugin?mPlugin->isRunning():false; }; +	 +	// "Exited" means any regular or error state after "Running" (plugin may have crashed or exited normally) +	bool isPluginExited(void) { return mPlugin?mPlugin->isDone():false; }; + +	std::string getPluginVersion() { return mPlugin?mPlugin->getPluginVersion():std::string(""); }; + +	bool getDisableTimeout() { return mPlugin?mPlugin->getDisableTimeout():false; }; +	void setDisableTimeout(bool disable) { if(mPlugin) mPlugin->setDisableTimeout(disable); }; +	 +	// Inherited from LLPluginProcessParentOwner +	/* virtual */ void receivePluginMessage(const LLPluginMessage &message); +	/* virtual */ void pluginLaunchFailed(); +	/* virtual */ void pluginDied(); +	 +	 +	typedef enum  +	{ +		PRIORITY_UNLOADED,	// media plugin isn't even loaded. +		PRIORITY_STOPPED,	// media is not playing, shouldn't need to update at all. +		PRIORITY_HIDDEN,	// media is not being displayed or is out of view, don't need to do graphic updates, but may still update audio, playhead, etc. +		PRIORITY_SLIDESHOW,	// media is in the far distance, updates very infrequently +		PRIORITY_LOW,		// media is in the distance, may be rendered at reduced size +		PRIORITY_NORMAL,	// normal (default) priority +		PRIORITY_HIGH		// media has user focus and/or is taking up most of the screen +	}EPriority; + +	static const char* priorityToString(EPriority priority); +	void setPriority(EPriority priority); +	void setLowPrioritySizeLimit(int size); +	 +	F64 getCPUUsage(); +	 +	void sendPickFileResponse(const std::string &file); + +	void sendAuthResponse(bool ok, const std::string &username, const std::string &password); + +	// Valid after a MEDIA_EVENT_CURSOR_CHANGED event +	std::string getCursorName() const { return mCursorName; }; + +	LLPluginClassMediaOwner::EMediaStatus getStatus() const { return mStatus; } + +	void	cut(); +	bool	canCut() const { return mCanCut; }; + +	void	copy(); +	bool	canCopy() const { return mCanCopy; }; + +	void	paste(); +	bool	canPaste() const { return mCanPaste; }; +	 +	// These can be called before init(), and they will be queued and sent before the media init message. +	void	setUserDataPath(const std::string &user_data_path); +	void	setLanguageCode(const std::string &language_code); +	void	setPluginsEnabled(const bool enabled); +	void	setJavascriptEnabled(const bool enabled); +	void	setTarget(const std::string &target); +	 +	/////////////////////////////////// +	// media browser class functions +	bool pluginSupportsMediaBrowser(void); +	 +	void focus(bool focused); +	void clear_cache(); +	void clear_cookies(); +	void set_cookies(const std::string &cookies); +	void enable_cookies(bool enable); +	void proxy_setup(bool enable, const std::string &host = LLStringUtil::null, int port = 0); +	void browse_stop(); +	void browse_reload(bool ignore_cache = false); +	void browse_forward(); +	void browse_back(); +	void setBrowserUserAgent(const std::string& user_agent); +	void proxyWindowOpened(const std::string &target, const std::string &uuid); +	void proxyWindowClosed(const std::string &uuid); +	void ignore_ssl_cert_errors(bool ignore); +	void addCertificateFilePath(const std::string& path); +	 +	// This is valid after MEDIA_EVENT_NAVIGATE_BEGIN or MEDIA_EVENT_NAVIGATE_COMPLETE +	std::string	getNavigateURI() const { return mNavigateURI; }; + +	// These are valid after MEDIA_EVENT_NAVIGATE_COMPLETE +	S32			getNavigateResultCode() const { return mNavigateResultCode; }; +	std::string getNavigateResultString() const { return mNavigateResultString; }; +	bool		getHistoryBackAvailable() const { return mHistoryBackAvailable; }; +	bool		getHistoryForwardAvailable() const { return mHistoryForwardAvailable; }; + +	// This is valid after MEDIA_EVENT_PROGRESS_UPDATED +	int			getProgressPercent() const { return mProgressPercent; }; +	 +	// This is valid after MEDIA_EVENT_STATUS_TEXT_CHANGED +	std::string getStatusText() const { return mStatusText; }; +	 +	// This is valid after MEDIA_EVENT_LOCATION_CHANGED +	std::string getLocation() const { return mLocation; }; +	 +	// This is valid after MEDIA_EVENT_CLICK_LINK_HREF or MEDIA_EVENT_CLICK_LINK_NOFOLLOW +	std::string getClickURL() const { return mClickURL; }; + +	// This is valid after MEDIA_EVENT_CLICK_LINK_NOFOLLOW +	std::string getClickNavType() const { return mClickNavType; }; + +	// This is valid after MEDIA_EVENT_CLICK_LINK_HREF +	std::string getClickTarget() const { return mClickTarget; }; + +	// This is valid during MEDIA_EVENT_CLICK_LINK_HREF and MEDIA_EVENT_GEOMETRY_CHANGE +	std::string getClickUUID() const { return mClickUUID; }; + +	// This is valid after MEDIA_EVENT_NAVIGATE_ERROR_PAGE +	S32 getStatusCode() const { return mStatusCode; }; +	 +	// These are valid during MEDIA_EVENT_GEOMETRY_CHANGE +	S32 getGeometryX() const { return mGeometryX; }; +	S32 getGeometryY() const { return mGeometryY; }; +	S32 getGeometryWidth() const { return mGeometryWidth; }; +	S32 getGeometryHeight() const { return mGeometryHeight; }; +	 +	// These are valid during MEDIA_EVENT_AUTH_REQUEST +	std::string	getAuthURL() const { return mAuthURL; }; +	std::string	getAuthRealm() const { return mAuthRealm; }; + +	// These are valid during MEDIA_EVENT_LINK_HOVERED +	std::string	getHoverText() const { return mHoverText; }; +	std::string	getHoverLink() const { return mHoverLink; }; +	 +	std::string getMediaName() const { return mMediaName; }; +	std::string getMediaDescription() const { return mMediaDescription; }; + +	// Crash the plugin.  If you use this outside of a testbed, you will be punished. +	void		crashPlugin(); +	 +	// Hang the plugin.  If you use this outside of a testbed, you will be punished. +	void		hangPlugin(); + +	/////////////////////////////////// +	// media time class functions +	bool pluginSupportsMediaTime(void); +	void stop(); +	void start(float rate = 0.0f); +	void pause(); +	void seek(float time); +	void setLoop(bool loop); +	void setVolume(float volume); +	float getVolume(); +	 +	F64 getCurrentTime(void) const { return mCurrentTime; }; +	F64 getDuration(void) const { return mDuration; }; +	F64 getCurrentPlayRate(void) { return mCurrentRate; }; +	F64 getLoadedDuration(void) const { return mLoadedDuration; }; +	 +	// Initialize the URL history of the plugin by sending +	// "init_history" message  +	void initializeUrlHistory(const LLSD& url_history); + +protected: + +	LLPluginClassMediaOwner *mOwner; + +	// Notify this object's owner that an event has occurred. +	void mediaEvent(LLPluginClassMediaOwner::EMediaEvent event); +		 +	void sendMessage(const LLPluginMessage &message);  // Send message internally, either queueing or sending directly. +	std::queue<LLPluginMessage> mSendQueue;		// Used to queue messages while the plugin initializes. +	 +	void setSizeInternal(void); + +	bool		mTextureParamsReceived;		// the mRequestedTexture* fields are only valid when this is true +	S32 		mRequestedTextureDepth; +	LLGLenum	mRequestedTextureInternalFormat; +	LLGLenum	mRequestedTextureFormat; +	LLGLenum	mRequestedTextureType; +	bool		mRequestedTextureSwapBytes; +	bool		mRequestedTextureCoordsOpenGL; +	 +	std::string mTextureSharedMemoryName; +	size_t		mTextureSharedMemorySize; +	 +	// True to scale requested media up to the full size of the texture (i.e. next power of two) +	bool		mAutoScaleMedia; + +	// default media size for the plugin, from the texture_params message. +	int			mDefaultMediaWidth; +	int			mDefaultMediaHeight; + +	// Size that has been requested by the plugin itself +	int			mNaturalMediaWidth; +	int			mNaturalMediaHeight; + +	// Size that has been requested with setSize() +	int			mSetMediaWidth; +	int			mSetMediaHeight; +	 +	// Full calculated media size (before auto-scale and downsample calculations) +	int			mFullMediaWidth; +	int			mFullMediaHeight; + +	// Actual media size being set (after auto-scale) +	int			mRequestedMediaWidth; +	int			mRequestedMediaHeight; +	 +	// Texture size calculated from actual media size +	int			mRequestedTextureWidth; +	int			mRequestedTextureHeight; +	 +	// Size that the plugin has acknowledged +	int			mTextureWidth; +	int			mTextureHeight; +	int			mMediaWidth; +	int			mMediaHeight; +	 +	float		mRequestedVolume; +	 +	// Priority of this media stream +	EPriority	mPriority; +	int			mLowPrioritySizeLimit; +	 +	bool		mAllowDownsample; +	int			mPadding; +	 +	 +	LLPluginProcessParent *mPlugin; +	 +	LLRect mDirtyRect; +	 +	std::string translateModifiers(MASK modifiers); +	 +	std::string mCursorName; +	int			mLastMouseX; +	int			mLastMouseY; + +	LLPluginClassMediaOwner::EMediaStatus mStatus; +	 +	F64				mSleepTime; + +	bool			mCanCut; +	bool			mCanCopy; +	bool			mCanPaste; +	 +	std::string		mMediaName; +	std::string		mMediaDescription; +	 +	LLColor4		mBackgroundColor; +	 +	std::string		mTarget; +	 +	///////////////////////////////////////// +	// media_browser class +	std::string		mNavigateURI; +	S32				mNavigateResultCode; +	std::string		mNavigateResultString; +	bool			mHistoryBackAvailable; +	bool			mHistoryForwardAvailable; +	std::string		mStatusText; +	int				mProgressPercent; +	std::string		mLocation; +	std::string		mClickURL; +	std::string		mClickNavType; +	std::string		mClickTarget; +	std::string		mClickUUID; +	S32				mGeometryX; +	S32				mGeometryY; +	S32				mGeometryWidth; +	S32				mGeometryHeight; +	S32				mStatusCode; +	std::string		mAuthURL; +	std::string		mAuthRealm; +	std::string		mHoverText; +	std::string		mHoverLink; +	 +	///////////////////////////////////////// +	// media_time class +	F64				mCurrentTime; +	F64				mDuration; +	F64				mCurrentRate; +	F64				mLoadedDuration; +	 +//-------------------------------------- +	//debug use only +	// +private: +	bool  mDeleteOK ; +public: +	void setDeleteOK(bool flag) { mDeleteOK = flag ;} +//-------------------------------------- +}; + +#endif // LL_LLPLUGINCLASSMEDIA_H | 
