diff options
| author | Don Kjer <don@lindenlab.com> | 2011-07-09 14:58:31 -0700 | 
|---|---|---|
| committer | Don Kjer <don@lindenlab.com> | 2011-07-09 14:58:31 -0700 | 
| commit | 121c4034db2de1b73bdab6777f49f302d89af3ca (patch) | |
| tree | 0e0cf941c3838a899d4a31433773e974eb9b4fd4 /indra/llplugin | |
| parent | 7029c8ff534419a3bcfd0e5fc39a4739e4cdc19c (diff) | |
| parent | 961d5b1d65fffff7075d0afbce003586b1f3b197 (diff) | |
Merge
Diffstat (limited to 'indra/llplugin')
| -rw-r--r-- | indra/llplugin/llpluginclassmedia.cpp | 2860 | ||||
| -rw-r--r-- | indra/llplugin/llpluginclassmedia.h | 851 | 
2 files changed, 1849 insertions, 1862 deletions
| diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 9f666369d4..d3d0403bbb 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -1,1436 +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::jsExposeObjectEvent( bool expose ) -{ -	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) -	{ -		return; -	} - -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_expose_object"); -	message.setValueBoolean( "expose", expose ); -	sendMessage( message ); -} - -void LLPluginClassMedia::jsValuesValidEvent( bool valid ) -{ -	if( ! mPlugin || !mPlugin->isRunning() || mPlugin->isBlocked() ) -	{ -		return; -	} - -	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "js_values_valid"); -	message.setValueBoolean( "valid", valid ); -	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 fea836aa68..f8ed89f644 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -1,426 +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); -	virtual ~LLPluginClassMedia(); - -	// local initialization, called by the media manager when creating a source -	virtual 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 -	virtual 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 jsExposeObjectEvent( bool expose ); -	void jsValuesValidEvent( bool valid ); -	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);
 +	virtual ~LLPluginClassMedia();
 +
 +	// local initialization, called by the media manager when creating a source
 +	virtual 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
 +	virtual 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
 | 
