diff options
Diffstat (limited to 'indra')
23 files changed, 2095 insertions, 1819 deletions
| diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index cfccd29def..4cbf7aa043 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -102,7 +102,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")    # To support a different SDK update these Xcode settings:    set(CMAKE_OSX_DEPLOYMENT_TARGET 10.5)    set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk) -  set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "4.2") +  set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "4.0")    set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)    # NOTE: To attempt an i386/PPC Universal build, add this on the configure line: diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 39ae09650e..c156ed0cef 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -73,7 +73,7 @@ void set_default_colour_weights(kdu_params *siz);  const char* engineInfoLLImageJ2CKDU()  { -	std::string version = llformat("KDU %s", KDU_CORE_VERSION); +	static std::string version = llformat("KDU %s", KDU_CORE_VERSION);  	return version.c_str();  } diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp index 2103216536..8f161201f4 100644 --- a/indra/llplugin/llpluginclassmedia.cpp +++ b/indra/llplugin/llpluginclassmedia.cpp @@ -1,1335 +1,1436 @@ -/**  - * @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::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::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;
 +}
 +
 diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h index cf8d8b26b9..c061390699 100644 --- a/indra/llplugin/llpluginclassmedia.h +++ b/indra/llplugin/llpluginclassmedia.h @@ -1,416 +1,426 @@ -/**  - * @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); -	 -	// 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 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
 diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp index d6a31dc862..180ae4dfa6 100644 --- a/indra/llrender/llfontgl.cpp +++ b/indra/llrender/llfontgl.cpp @@ -554,7 +554,7 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch  	BOOL in_word = FALSE;  	// avoid S32 overflow when max_pixels == S32_MAX by staying in floating point -	F32 scaled_max_pixels =	ceil(max_pixels * sScaleX); +	F32 scaled_max_pixels =	max_pixels * sScaleX;  	F32 width_padding = 0.f;  	LLFontGlyphInfo* next_glyph = NULL; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 1cc3cc04d6..349dbc3405 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -280,7 +280,7 @@ bool LLTextBase::truncate()  	if (getLength() >= S32(mMaxTextByteLength / 4))  	{	  		// Have to check actual byte size -        LLWString text(getWText()); +		LLWString text(getWText());  		S32 utf8_byte_size = wstring_utf8_length(text);  		if ( utf8_byte_size > mMaxTextByteLength )  		{ @@ -547,8 +547,7 @@ void LLTextBase::drawText()  		}  		LLRect text_rect(line.mRect); -		text_rect.mRight = llmin(mDocumentView->getRect().getWidth(), text_rect.mRight); // clamp right edge to document extents -		text_rect.translate(mVisibleTextRect.mLeft, mVisibleTextRect.mBottom); // translate into display region of text widget +		text_rect.mRight = mDocumentView->getRect().getWidth(); // clamp right edge to document extents  		text_rect.translate(mDocumentView->getRect().mLeft, mDocumentView->getRect().mBottom); // adjust by scroll position  		// draw a single line of text @@ -655,7 +654,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s  	}  	text.insert(pos, wstr); -    getViewModel()->setDisplay(text); +	getViewModel()->setDisplay(text);  	if ( truncate() )  	{ @@ -670,7 +669,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s  S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)  { -    LLWString text(getWText()); +	LLWString text(getWText());  	segment_set_t::iterator seg_iter = getSegIterContaining(pos);  	while(seg_iter != mSegments.end())  	{ @@ -717,7 +716,7 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)  	}  	text.erase(pos, length); -    getViewModel()->setDisplay(text); +	getViewModel()->setDisplay(text);  	// recreate default segment in case we erased everything  	createDefaultSegment(); @@ -734,9 +733,9 @@ S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc)  	{  		return 0;  	} -    LLWString text(getWText()); +	LLWString text(getWText());  	text[pos] = wc; -    getViewModel()->setDisplay(text); +	getViewModel()->setDisplay(text);  	onValueChange(pos, pos + 1);  	needsReflow(pos); @@ -857,7 +856,7 @@ BOOL LLTextBase::handleMouseUp(S32 x, S32 y, MASK mask)  		// Did we just click on a link?  		if (mURLClickSignal  			&& cur_segment->getStyle() -		    && cur_segment->getStyle()->isLink()) +			&& cur_segment->getStyle()->isLink())  		{  			// *TODO: send URL here?  			(*mURLClickSignal)(this, LLSD() ); @@ -1035,27 +1034,27 @@ void LLTextBase::draw()  		gl_rect_2d(text_rect, bg_color % alpha, TRUE);  	} - 	bool should_clip = mClip || mScroller != NULL; - 	{ LLLocalClipRect clip(text_rect, should_clip); +	bool should_clip = mClip || mScroller != NULL; +	{ LLLocalClipRect clip(text_rect, should_clip); - 		// draw document view - 		if (mScroller) +		// draw document view +		if (mScroller) +		{ +			drawChild(mScroller); +		} +		else  		{ - 			drawChild(mScroller); - 		} - 		else - 		{ - 			drawChild(mDocumentView); - 		} +			drawChild(mDocumentView); +		}  		drawSelectionBackground();  		drawText();  		drawCursor();  	} - 	mDocumentView->setVisible(FALSE); - 	LLUICtrl::draw(); - 	mDocumentView->setVisible(TRUE); +	mDocumentView->setVisible(FALSE); +	LLUICtrl::draw(); +	mDocumentView->setVisible(TRUE);  } @@ -1119,8 +1118,7 @@ void LLTextBase::updateScrollFromCursor()  	// scroll so that the cursor is at the top of the page  	LLRect scroller_doc_window = getVisibleDocumentRect(); -	LLRect cursor_rect_doc = getLocalRectFromDocIndex(mCursorPos); -	cursor_rect_doc.translate(scroller_doc_window.mLeft, scroller_doc_window.mBottom); +	LLRect cursor_rect_doc = getDocRectFromDocIndex(mCursorPos);  	mScroller->scrollToShowRect(cursor_rect_doc, LLRect(0, scroller_doc_window.getHeight() - 5, scroller_doc_window.getWidth(), 5));  } @@ -1366,9 +1364,9 @@ S32 LLTextBase::getLineStart( S32 line ) const  {  	S32 num_lines = getLineCount();  	if (num_lines == 0) -    { +	{  		return 0; -    } +	}  	line = llclamp(line, 0, num_lines-1);  	return mLineInfoList[line].mDocIndexStart; @@ -1378,9 +1376,9 @@ S32 LLTextBase::getLineEnd( S32 line ) const  {  	S32 num_lines = getLineCount();  	if (num_lines == 0) -    { +	{  		return 0; -    } +	}  	line = llclamp(line, 0, num_lines-1);  	return mLineInfoList[line].mDocIndexEnd; @@ -1656,7 +1654,7 @@ void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Para  		LLUrlMatch match;  		std::string text = new_text;  		while ( LLUrlRegistry::instance().findUrl(text, match, -		        boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) ) +				boost::bind(&LLTextBase::replaceUrl, this, _1, _2, _3)) )  		{  			LLTextUtil::processUrlMatch(&match,this); @@ -1949,7 +1947,7 @@ void LLTextBase::setWText(const LLWString& text)  const LLWString& LLTextBase::getWText() const  { -    return getViewModel()->getDisplay(); +	return getViewModel()->getDisplay();  }  // If round is true, if the position is on the right half of a character, the cursor @@ -1960,9 +1958,12 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,  {  	// Figure out which line we're nearest to.  	LLRect visible_region = getVisibleDocumentRect(); +	LLRect doc_rect = mDocumentView->getRect(); + +	S32 doc_y = local_y - doc_rect.mBottom;  	// binary search for line that starts before local_y -	line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), local_y - mVisibleTextRect.mBottom + visible_region.mBottom, compare_bottom()); +	line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), doc_y, compare_bottom());  	if (line_iter == mLineInfoList.end())  	{ @@ -1970,7 +1971,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,  	}  	S32 pos = getLength(); -	S32 start_x = mVisibleTextRect.mLeft + line_iter->mRect.mLeft - visible_region.mLeft; +	S32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft;  	segment_set_t::iterator line_seg_iter;  	S32 line_seg_offset; @@ -1992,7 +1993,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round,  		}  		// if we've reached a line of text *below* the mouse cursor, doc index is first character on that line -		if (hit_past_end_of_line && local_y - mVisibleTextRect.mBottom + visible_region.mBottom > line_iter->mRect.mTop) +		if (hit_past_end_of_line && doc_y > line_iter->mRect.mTop)  		{  			pos = segment_line_start;  			break; @@ -2461,7 +2462,7 @@ LLRect LLTextBase::getVisibleDocumentRect() const  		LLRect doc_rect = mDocumentView->getLocalRect();  		doc_rect.mLeft -= mDocumentView->getRect().mLeft;  		// adjust for height of text above widget baseline -		doc_rect.mBottom = llmin(0, doc_rect.getHeight() - mVisibleTextRect.getHeight()); +		doc_rect.mBottom = doc_rect.getHeight() - mVisibleTextRect.getHeight();  		return doc_rect;  	}  } @@ -2575,21 +2576,21 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele  	LLColor4 color = (mEditor.getReadOnly() ? mStyle->getReadOnlyColor() : mStyle->getColor())  % alpha; -  	if( selection_start > seg_start ) +	if( selection_start > seg_start )  	{  		// Draw normally  		S32 start = seg_start;  		S32 end = llmin( selection_start, seg_end );  		S32 length =  end - start;  		font->render(text, start,  -			     rect,  -			     color,  -			     LLFontGL::LEFT, mEditor.mVAlign,  -			     LLFontGL::NORMAL,  -			     mStyle->getShadowType(),  -			     length, -			     &right_x,  -			     mEditor.getUseEllipses()); +				 rect,  +				 color,  +				 LLFontGL::LEFT, mEditor.mVAlign,  +				 LLFontGL::NORMAL,  +				 mStyle->getShadowType(),  +				 length, +				 &right_x,  +				 mEditor.getUseEllipses());  	}  	rect.mLeft = (S32)ceil(right_x); @@ -2601,14 +2602,14 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele  		S32 length = end - start;  		font->render(text, start,  -			     rect, -			     mStyle->getSelectedColor().get(), -			     LLFontGL::LEFT, mEditor.mVAlign,  -			     LLFontGL::NORMAL,  -			     LLFontGL::NO_SHADOW,  -			     length, -			     &right_x,  -			     mEditor.getUseEllipses()); +				 rect, +				 mStyle->getSelectedColor().get(), +				 LLFontGL::LEFT, mEditor.mVAlign,  +				 LLFontGL::NORMAL,  +				 LLFontGL::NO_SHADOW,  +				 length, +				 &right_x,  +				 mEditor.getUseEllipses());  	}  	rect.mLeft = (S32)ceil(right_x);  	if( selection_end < seg_end ) @@ -2618,14 +2619,14 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele  		S32 end = seg_end;  		S32 length = end - start;  		font->render(text, start,  -			     rect,  -			     color,  -			     LLFontGL::LEFT, mEditor.mVAlign,  -			     LLFontGL::NORMAL,  -			     mStyle->getShadowType(),  -			     length, -			     &right_x,  -			     mEditor.getUseEllipses()); +				 rect,  +				 color,  +				 LLFontGL::LEFT, mEditor.mVAlign,  +				 LLFontGL::NORMAL,  +				 mStyle->getShadowType(),  +				 length, +				 &right_x,  +				 mEditor.getUseEllipses());  	}  	return right_x;  } diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp index 9ba8edbb59..27f3c7260e 100644 --- a/indra/media_plugins/webkit/media_plugin_webkit.cpp +++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp @@ -1168,6 +1168,66 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)  				authResponse(message_in);  			}  			else +			if(message_name == "js_expose_object") +			{ +#if LLQTWEBKIT_API_VERSION >= 9 +				bool expose_object = message_in.getValueBoolean( "expose" ); +				LLQtWebKit::getInstance()->setExposeObject( expose_object ); +#endif +			} +			else +			if(message_name == "js_values_valid") +			{ +#if LLQTWEBKIT_API_VERSION >= 9 +				bool valid = message_in.getValueBoolean( "valid" ); +				LLQtWebKit::getInstance()->setValuesValid( valid ); +#endif +			} +			else +			if(message_name == "js_agent_location") +			{ +#if LLQTWEBKIT_API_VERSION >= 9 +				F32 x = message_in.getValueReal("x"); +				F32 y = message_in.getValueReal("y"); +				F32 z = message_in.getValueReal("z"); +				LLQtWebKit::getInstance()->setAgentLocation( x, y, z ); +#endif +			} +			else +			if(message_name == "js_agent_global_location") +			{ +#if LLQTWEBKIT_API_VERSION >= 9 +				F32 x = message_in.getValueReal("x"); +				F32 y = message_in.getValueReal("y"); +				F32 z = message_in.getValueReal("z"); +				LLQtWebKit::getInstance()->setAgentGlobalLocation( x, y, z ); +#endif +			} +			else			 +			if(message_name == "js_agent_orientation") +			{ +#if LLQTWEBKIT_API_VERSION >= 9 +				F32 angle = message_in.getValueReal("angle"); +				LLQtWebKit::getInstance()->setAgentOrientation( angle ); +#endif +			} +			else +			if(message_name == "js_agent_region") +			{ +#if LLQTWEBKIT_API_VERSION >= 9 +				const std::string& region = message_in.getValue("region"); +				LLQtWebKit::getInstance()->setAgentRegion( region ); +#endif +			} +			else +			if(message_name == "js_agent_maturity") +			{ +#if LLQTWEBKIT_API_VERSION >= 9 +				const std::string& maturity = message_in.getValue("maturity"); +				LLQtWebKit::getInstance()->setAgentMaturity( maturity ); +#endif +			} +			else  			{  //				std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl;  			} @@ -1324,4 +1384,3 @@ int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func, void  	return 0;  } - diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index eb6c77971b..cf5f522519 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -708,6 +708,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>BrowserEnableJSObject</key> +    <map> +      <key>Comment</key> +      <string>Enable or disable the viewer to Javascript bridge object.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>0</integer> +    </map>      <key>BlockAvatarAppearanceMessages</key>          <map>          <key>Comment</key> diff --git a/indra/newview/llfloatersounddevices.cpp b/indra/newview/llfloatersounddevices.cpp index 9fe7c7f9dd..e692f1735a 100644 --- a/indra/newview/llfloatersounddevices.cpp +++ b/indra/newview/llfloatersounddevices.cpp @@ -68,6 +68,9 @@ BOOL LLFloaterSoundDevices::postBuild()  	if (panel)  	{  		panel->setUseTuningMode(false); +		getChild<LLUICtrl>("voice_input_device")->setCommitCallback(boost::bind(&LLPanelVoiceDeviceSettings::apply, panel)); +		getChild<LLUICtrl>("voice_output_device")->setCommitCallback(boost::bind(&LLPanelVoiceDeviceSettings::apply, panel)); +		getChild<LLUICtrl>("mic_volume_slider")->setCommitCallback(boost::bind(&LLPanelVoiceDeviceSettings::apply, panel));  	}  	return TRUE;  } diff --git a/indra/newview/llpanelvoicedevicesettings.cpp b/indra/newview/llpanelvoicedevicesettings.cpp index dc87bd0077..4a80bbbe5e 100644 --- a/indra/newview/llpanelvoicedevicesettings.cpp +++ b/indra/newview/llpanelvoicedevicesettings.cpp @@ -191,7 +191,21 @@ void LLPanelVoiceDeviceSettings::refresh()  	mCtrlInputDevices = getChild<LLComboBox>("voice_input_device");  	mCtrlOutputDevices = getChild<LLComboBox>("voice_output_device"); -	if(!LLVoiceClient::getInstance()->deviceSettingsAvailable()) +	bool device_settings_available = LLVoiceClient::getInstance()->deviceSettingsAvailable(); + +	if (mCtrlInputDevices) +	{ +		mCtrlInputDevices->setEnabled(device_settings_available); +	} + +	if (mCtrlOutputDevices) +	{ +		mCtrlOutputDevices->setEnabled(device_settings_available); +	} + +	getChild<LLSlider>("mic_volume_slider")->setEnabled(device_settings_available); + +	if(!device_settings_available)  	{  		// The combo boxes are disabled, since we can't get the device settings from the daemon just now.  		// Put the currently set default (ONLY) in the box, and select it. @@ -207,6 +221,7 @@ void LLPanelVoiceDeviceSettings::refresh()  			mCtrlOutputDevices->add( mOutputDevice, ADD_BOTTOM );  			mCtrlOutputDevices->setSimple(mOutputDevice);  		} +		mDevicesUpdated = FALSE;  	}  	else if (!mDevicesUpdated)  	{ diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 79c6c8db75..1e53274cd6 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -62,6 +62,7 @@  #include "llmutelist.h"  #include "llpanelprofile.h"  #include "llappviewer.h" +#include "lllogininstance.h"   //#include "llfirstuse.h"  #include "llwindow.h" @@ -2343,6 +2344,65 @@ BOOL LLViewerMediaImpl::handleMouseUp(S32 x, S32 y, MASK mask)  }  ////////////////////////////////////////////////////////////////////////////////////////// +void LLViewerMediaImpl::updateJavascriptObject() +{ +	if ( mMediaSource ) +	{ +		// flag to expose this information to internal browser or not. +		bool expose_javascript_object = gSavedSettings.getBOOL("BrowserEnableJSObject"); +		mMediaSource->jsExposeObjectEvent( expose_javascript_object ); + +		// indicate if the values we have are valid (currently do this blanket-fashion for +		// everything depending on whether you are logged in or not - this may require a  +		// more granular approach once variables are added that ARE valid before login +		bool logged_in = LLLoginInstance::getInstance()->authSuccess(); +		mMediaSource->jsValuesValidEvent( logged_in ); + +		// current location within a region +		LLVector3 agent_pos = gAgent.getPositionAgent(); +		double x = agent_pos.mV[ VX ]; +		double y = agent_pos.mV[ VY ]; +		double z = agent_pos.mV[ VZ ]; +		mMediaSource->jsAgentLocationEvent( x, y, z ); + +		// current location within the grid +		LLVector3d agent_pos_global = gAgent.getLastPositionGlobal(); +		double global_x = agent_pos_global.mdV[ VX ]; +		double global_y = agent_pos_global.mdV[ VY ]; +		double global_z = agent_pos_global.mdV[ VZ ]; +		mMediaSource->jsAgentGlobalLocationEvent( global_x, global_y, global_z ); + +		// current agent orientation +		double rotation = atan2( gAgent.getAtAxis().mV[VX], gAgent.getAtAxis().mV[VY] ); +		double angle = rotation * RAD_TO_DEG; +		if ( angle < 0.0f ) angle = 360.0f + angle;	// TODO: has to be a better way to get orientation! +		mMediaSource->jsAgentOrientationEvent( angle ); + +		// current region agent is in +		std::string region_name(""); +		LLViewerRegion* region = gAgent.getRegion(); +		if ( region ) +		{ +			region_name = region->getName(); +		}; +		mMediaSource->jsAgentRegionEvent( region_name ); + +		// language code the viewer is set to +		mMediaSource->jsAgentLanguageEvent( LLUI::getLanguage() ); + +		// maturity setting the agent has selected +		if ( gAgent.prefersAdult() ) +			mMediaSource->jsAgentMaturityEvent( "GMA" );	// Adult means see adult, mature and general content +		else +		if ( gAgent.prefersMature() ) +			mMediaSource->jsAgentMaturityEvent( "GM" );	// Mature means see mature and general content +		else +		if ( gAgent.prefersPG() ) +			mMediaSource->jsAgentMaturityEvent( "G" );	// PG means only see General content +	} +} + +//////////////////////////////////////////////////////////////////////////////////////////  std::string LLViewerMediaImpl::getName() const   {   	if (mMediaSource) @@ -2640,6 +2700,9 @@ void LLViewerMediaImpl::update()  	{  		updateVolume(); +		// TODO: this is updated every frame - is this bad? +		updateJavascriptObject(); +  		// If we didn't just create the impl, it may need to get cookie updates.  		if(!sUpdatedCookies.empty())  		{ diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index e2e342cc45..a70c6f4887 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -339,7 +339,10 @@ public:  	LLVOVolume *getSomeObject();  	void setUpdated(BOOL updated) ;  	BOOL isUpdated() ; -	 + +	// updates the javascript object in the embedded browser with viewer values +	void updateJavascriptObject(); +		  	// Updates the "interest" value in this object  	void calculateInterest();  	F64 getInterest() const { return mInterest; }; diff --git a/indra/newview/skins/default/xui/da/language_settings.xml b/indra/newview/skins/default/xui/da/language_settings.xml index 3e46f69af1..0e3cbfd2d2 100644 --- a/indra/newview/skins/default/xui/da/language_settings.xml +++ b/indra/newview/skins/default/xui/da/language_settings.xml @@ -4,6 +4,7 @@  	<!-- Locale Information -->  	<string name="MicrosoftLocale">danish</string> +	<string name="MacLocale">da_DK.UTF-8</string>  	<string name="DarwinLocale">da_DK.UTF-8</string>  	<string name="LinuxLocale">da_DK.UTF-8</string> diff --git a/indra/newview/skins/default/xui/de/language_settings.xml b/indra/newview/skins/default/xui/de/language_settings.xml index d54f548fe1..f9346eef7d 100644 --- a/indra/newview/skins/default/xui/de/language_settings.xml +++ b/indra/newview/skins/default/xui/de/language_settings.xml @@ -4,6 +4,7 @@  	<!-- Locale Information -->  	<string name="MicrosoftLocale">german</string> +	<string name="MacLocale">de_DE.UTF-8</string>  	<string name="DarwinLocale">de_DE.UTF-8</string>  	<string name="LinuxLocale">de_DE.UTF-8</string> diff --git a/indra/newview/skins/default/xui/en/language_settings.xml b/indra/newview/skins/default/xui/en/language_settings.xml index c8a06fe401..51779e4bfd 100644 --- a/indra/newview/skins/default/xui/en/language_settings.xml +++ b/indra/newview/skins/default/xui/en/language_settings.xml @@ -4,6 +4,7 @@  	<!-- Locale Information -->  	<string name="MicrosoftLocale">english</string> +	<string name="MacLocale">C</string>  	<string name="DarwinLocale">C</string>  	<string name="LinuxLocale">C</string> diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 0d4a095e14..4c4ff3e5c4 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -183,11 +183,11 @@             parameter="http://join.secondlife.com/"/>          </menu_item_call>        <menu_item_call -       label="Web Content Floater Test" -       name="Web Content Floater Test"> +       label="Web Content Floater Debug Test" +       name="Web Content Floater Debug Test">          <menu_item_call.on_click           function="Advanced.WebContentTest" -         parameter="http://www.google.com"/> +         parameter="http://google.com"/>        </menu_item_call>        <menu_item_check          label="Show Grid Picker" diff --git a/indra/newview/skins/default/xui/es/language_settings.xml b/indra/newview/skins/default/xui/es/language_settings.xml index f172994077..997293a741 100644 --- a/indra/newview/skins/default/xui/es/language_settings.xml +++ b/indra/newview/skins/default/xui/es/language_settings.xml @@ -4,6 +4,7 @@  	<!-- Locale Information -->  	<string name="MicrosoftLocale">spanish</string> +	<string name="MacLocale">es_ES.UTF-8</string>  	<string name="DarwinLocale">es_ES.UTF-8</string>  	<string name="LinuxLocale">es_ES.UTF-8</string> diff --git a/indra/newview/skins/default/xui/fr/language_settings.xml b/indra/newview/skins/default/xui/fr/language_settings.xml index bd272e1f28..fdac9d65a7 100644 --- a/indra/newview/skins/default/xui/fr/language_settings.xml +++ b/indra/newview/skins/default/xui/fr/language_settings.xml @@ -4,6 +4,7 @@  	<!-- Locale Information -->  	<string name="MicrosoftLocale">french</string> +	<string name="MacLocale">fr_FR.UTF-8</string>  	<string name="DarwinLocale">fr_FR.UTF-8</string>  	<string name="LinuxLocale">fr_FR.UTF-8</string> diff --git a/indra/newview/skins/default/xui/it/language_settings.xml b/indra/newview/skins/default/xui/it/language_settings.xml index 312b8e21aa..5f448fa828 100644 --- a/indra/newview/skins/default/xui/it/language_settings.xml +++ b/indra/newview/skins/default/xui/it/language_settings.xml @@ -4,6 +4,7 @@  	<!-- Locale Information -->  	<string name="MicrosoftLocale">italian</string> +	<string name="MacLocale">it_IT.UTF-8</string>  	<string name="DarwinLocale">it_IT.UTF-8</string>  	<string name="LinuxLocale">it_IT.UTF-8</string> diff --git a/indra/newview/skins/default/xui/ja/language_settings.xml b/indra/newview/skins/default/xui/ja/language_settings.xml index a6023f9b56..91e8f4be7c 100644 --- a/indra/newview/skins/default/xui/ja/language_settings.xml +++ b/indra/newview/skins/default/xui/ja/language_settings.xml @@ -4,6 +4,7 @@  	<!-- Locale Information -->  	<string name="MicrosoftLocale">japanese</string> +	<string name="MacLocale">ja_JP.UTF-8</string>  	<string name="DarwinLocale">ja_JP.UTF-8</string>  	<string name="LinuxLocale">ja_JP.UTF-8</string> diff --git a/indra/newview/skins/default/xui/nl/language_settings.xml b/indra/newview/skins/default/xui/nl/language_settings.xml index 53501d5dcb..40f4d9178a 100644 --- a/indra/newview/skins/default/xui/nl/language_settings.xml +++ b/indra/newview/skins/default/xui/nl/language_settings.xml @@ -4,6 +4,7 @@  	<!-- Locale Information -->  	<string name="MicrosoftLocale">dutch</string> +	<string name="MacLocale">nl_NL.UTF-8</string>  	<string name="DarwinLocale">nl_NL.UTF-8</string>  	<string name="LinuxLocale">nl_NL.UTF-8</string> diff --git a/indra/newview/skins/default/xui/pl/language_settings.xml b/indra/newview/skins/default/xui/pl/language_settings.xml index 681b38e9cf..93051d1317 100644 --- a/indra/newview/skins/default/xui/pl/language_settings.xml +++ b/indra/newview/skins/default/xui/pl/language_settings.xml @@ -4,6 +4,7 @@  	<!-- Locale Information -->  	<string name="MicrosoftLocale">polish</string> +	<string name="MacLocale">pl_PL.UTF-8</string>  	<string name="DarwinLocale">pl_PL.UTF-8</string>  	<string name="LinuxLocale">pl_PL.UTF-8</string> diff --git a/indra/newview/skins/default/xui/pt/language_settings.xml b/indra/newview/skins/default/xui/pt/language_settings.xml index e1de6ffea7..8799475ace 100644 --- a/indra/newview/skins/default/xui/pt/language_settings.xml +++ b/indra/newview/skins/default/xui/pt/language_settings.xml @@ -4,6 +4,7 @@  	<!-- Locale Information -->  	<string name="MicrosoftLocale">portuguese</string> +	<string name="MacLocale">pt_PT.UTF-8</string>  	<string name="DarwinLocale">pt_PT.UTF-8</string>  	<string name="LinuxLocale">pt_PT.UTF-8</string> | 
