svn merge -r 134922:134973 svn+ssh://svn.lindenlab.com/svn/linden/branches/media-on-a-prim/moap-7

Merging branches/media-on-a-prim/moap-7 down to viewer-2.0.
master
Monroe Williams 2009-10-01 02:35:53 +00:00
parent 8135ddac02
commit cf9239cabc
88 changed files with 6925 additions and 688 deletions

View File

@ -668,7 +668,14 @@
<key>FetchLib</key>
<boolean>true</boolean>
</map>
<key>ObjectMedia</key>
<boolean>false</boolean>
<key>ObjectMediaNavigate</key>
<boolean>false</boolean>
</map>
<key>messageBans</key>
<map>

View File

@ -202,5 +202,18 @@ const U32 CHANGED_OWNER = 0x80;
const U32 CHANGED_REGION = 0x100;
const U32 CHANGED_TELEPORT = 0x200;
const U32 CHANGED_REGION_START = 0x400;
const U32 CHANGED_MEDIA = 0x800;
// Possible error results
const U32 LSL_STATUS_OK = 0;
const U32 LSL_STATUS_MALFORMED_PARAMS = 1000;
const U32 LSL_STATUS_TYPE_MISMATCH = 1001;
const U32 LSL_STATUS_BOUNDS_ERROR = 1002;
const U32 LSL_STATUS_NOT_FOUND = 1003;
const U32 LSL_STATUS_NOT_SUPPORTED = 1004;
const U32 LSL_STATUS_INTERNAL_ERROR = 1999;
// Start per-function errors below, starting at 2000:
const U32 LSL_STATUS_WHITELIST_FAILED = 2001;
#endif

View File

@ -99,6 +99,8 @@ void LLPluginClassMedia::reset()
mSetMediaHeight = -1;
mRequestedMediaWidth = 0;
mRequestedMediaHeight = 0;
mFullMediaWidth = 0;
mFullMediaHeight = 0;
mTextureWidth = 0;
mTextureHeight = 0;
mMediaWidth = 0;
@ -266,8 +268,16 @@ unsigned char* LLPluginClassMedia::getBitsData()
void LLPluginClassMedia::setSize(int width, int height)
{
mSetMediaWidth = width;
mSetMediaHeight = height;
if((width > 0) && (height > 0))
{
mSetMediaWidth = width;
mSetMediaHeight = height;
}
else
{
mSetMediaWidth = -1;
mSetMediaHeight = -1;
}
setSizeInternal();
}
@ -279,16 +289,26 @@ void LLPluginClassMedia::setSizeInternal(void)
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))
@ -309,6 +329,12 @@ void LLPluginClassMedia::setSizeInternal(void)
mRequestedMediaWidth = nextPowerOf2(mRequestedMediaWidth);
mRequestedMediaHeight = nextPowerOf2(mRequestedMediaHeight);
}
if(mRequestedMediaWidth > 2048)
mRequestedMediaWidth = 2048;
if(mRequestedMediaHeight > 2048)
mRequestedMediaHeight = 2048;
}
void LLPluginClassMedia::setAutoScale(bool auto_scale)
@ -519,6 +545,10 @@ void LLPluginClassMedia::setPriority(EPriority priority)
std::string priority_string;
switch(priority)
{
case PRIORITY_UNLOADED:
priority_string = "unloaded";
mSleepTime = 1.0f;
break;
case PRIORITY_STOPPED:
priority_string = "stopped";
mSleepTime = 1.0f;
@ -527,6 +557,10 @@ void LLPluginClassMedia::setPriority(EPriority priority)
priority_string = "hidden";
mSleepTime = 1.0f;
break;
case PRIORITY_SLIDESHOW:
priority_string = "slideshow";
mSleepTime = 1.0f;
break;
case PRIORITY_LOW:
priority_string = "low";
mSleepTime = 1.0f / 50.0f;
@ -550,6 +584,8 @@ void LLPluginClassMedia::setPriority(EPriority priority)
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();
}
@ -557,15 +593,27 @@ void LLPluginClassMedia::setPriority(EPriority priority)
void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
{
if(mLowPrioritySizeLimit != size)
int power = nextPowerOf2(size);
if(mLowPrioritySizeLimit != power)
{
mLowPrioritySizeLimit = size;
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::cut()
{
@ -722,7 +770,7 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
mNaturalMediaWidth = width;
mNaturalMediaHeight = height;
setSize(width, height);
setSizeInternal();
}
else if(message_name == "size_change_response")
{

View File

@ -66,6 +66,8 @@ public:
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();
@ -138,9 +140,11 @@ public:
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_LOW, // media is in the far distance, may be rendered at reduced size
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;
@ -148,6 +152,8 @@ public:
void setPriority(EPriority priority);
void setLowPrioritySizeLimit(int size);
F64 getCPUUsage();
// Valid after a MEDIA_EVENT_CURSOR_CHANGED event
std::string getCursorName() const { return mCursorName; };
@ -230,6 +236,7 @@ public:
void initializeUrlHistory(const LLSD& url_history);
protected:
LLPluginClassMediaOwner *mOwner;
// Notify this object's owner that an event has occurred.
@ -266,7 +273,11 @@ protected:
int mSetMediaWidth;
int mSetMediaHeight;
// Actual media size being set (may be affected by auto-scale)
// 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;

View File

@ -33,6 +33,7 @@
#include "llpluginmessage.h"
#include "llsdserialize.h"
#include "u64.h"
LLPluginMessage::LLPluginMessage()
{
@ -93,6 +94,14 @@ void LLPluginMessage::setValueReal(const std::string &key, F64 value)
mMessage["params"][key] = value;
}
void LLPluginMessage::setValuePointer(const std::string &key, void* value)
{
std::stringstream temp;
// iostreams should output pointer values in hex with an initial 0x by default.
temp << value;
setValue(key, temp.str());
}
std::string LLPluginMessage::getClass(void) const
{
return mMessage["class"];
@ -189,6 +198,20 @@ F64 LLPluginMessage::getValueReal(const std::string &key) const
return result;
}
void* LLPluginMessage::getValuePointer(const std::string &key) const
{
void* result = NULL;
if(mMessage["params"].has(key))
{
std::string value = mMessage["params"][key].asString();
result = (void*)llstrtou64(value.c_str(), NULL, 16);
}
return result;
}
std::string LLPluginMessage::generate(void) const
{
std::ostringstream result;

View File

@ -57,6 +57,7 @@ public:
void setValueU32(const std::string &key, U32 value);
void setValueBoolean(const std::string &key, bool value);
void setValueReal(const std::string &key, F64 value);
void setValuePointer(const std::string &key, void *value);
std::string getClass(void) const;
std::string getName(void) const;
@ -82,6 +83,9 @@ public:
// get the value of a key as a float.
F64 getValueReal(const std::string &key) const;
// get the value of a key as a pointer.
void* getValuePointer(const std::string &key) const;
// Flatten the message into a string
std::string generate(void) const;

View File

@ -43,6 +43,7 @@ LLPluginProcessChild::LLPluginProcessChild()
mInstance = NULL;
mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
mSleepTime = 1.0f / 100.0f; // default: send idle messages at 100Hz
mCPUElapsed = 0.0f;
}
LLPluginProcessChild::~LLPluginProcessChild()
@ -130,6 +131,7 @@ void LLPluginProcessChild::idle(void)
{
mHeartbeat.start();
mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
mCPUElapsed = 0.0f;
setState(STATE_PLUGIN_LOADED);
}
else
@ -158,10 +160,22 @@ void LLPluginProcessChild::idle(void)
mInstance->idle();
if(mHeartbeat.checkExpirationAndReset(HEARTBEAT_SECONDS))
if(mHeartbeat.hasExpired())
{
// This just proves that we're not stuck down inside the plugin code.
sendMessageToParent(LLPluginMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat"));
LLPluginMessage heartbeat(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat");
// Calculate the approximage CPU usage fraction (floating point value between 0 and 1) used by the plugin this heartbeat cycle.
// Note that this will not take into account any threads or additional processes the plugin spawns, but it's a first approximation.
// If we could write OS-specific functions to query the actual CPU usage of this process, that would be a better approximation.
heartbeat.setValueReal("cpu_usage", mCPUElapsed / mHeartbeat.getElapsedTimeF64());
sendMessageToParent(heartbeat);
mHeartbeat.reset();
mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
mCPUElapsed = 0.0f;
}
}
// receivePluginMessage will transition to STATE_UNLOADING
@ -253,8 +267,11 @@ void LLPluginProcessChild::sendMessageToPlugin(const LLPluginMessage &message)
std::string buffer = message.generate();
LL_DEBUGS("Plugin") << "Sending to plugin: " << buffer << LL_ENDL;
LLTimer elapsed;
mInstance->sendMessage(buffer);
mCPUElapsed += elapsed.getElapsedTimeF64();
}
void LLPluginProcessChild::sendMessageToParent(const LLPluginMessage &message)
@ -317,12 +334,7 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
LLPluginMessage message("base", "shm_added");
message.setValue("name", name);
message.setValueS32("size", (S32)size);
// shm address is split into 2x32bit values because LLSD doesn't serialize 64bit values and we need to support 64-bit addressing.
void * address = region->getMappedAddress();
U32 address_lo = (U32)(U64(address) & 0xFFFFFFFF); // Extract the lower 32 bits
U32 address_hi = (U32)((U64(address)>>32) & 0xFFFFFFFF); // Extract the higher 32 bits
message.setValueU32("address", address_lo);
message.setValueU32("address_1", address_hi);
message.setValuePointer("address", region->getMappedAddress());
sendMessageToPlugin(message);
// and send the response to the parent
@ -380,7 +392,11 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
if(passMessage && mInstance != NULL)
{
LLTimer elapsed;
mInstance->sendMessage(message);
mCPUElapsed += elapsed.getElapsedTimeF64();
}
}
@ -454,6 +470,7 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
if(passMessage)
{
LL_DEBUGS("Plugin") << "Passing through to parent: " << message << LL_ENDL;
writeMessageRaw(message);
}
}

View File

@ -102,6 +102,7 @@ private:
LLTimer mHeartbeat;
F64 mSleepTime;
F64 mCPUElapsed;
};

View File

@ -38,7 +38,7 @@
#include "llapr.h"
// If we don't receive a heartbeat in this many seconds, we declare the plugin locked up.
static const F32 PLUGIN_LOCKED_UP_SECONDS = 10.0f;
static const F32 PLUGIN_LOCKED_UP_SECONDS = 15.0f;
// Somewhat longer timeout for initial launch.
static const F32 PLUGIN_LAUNCH_SECONDS = 20.0f;
@ -87,6 +87,7 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std
{
mProcess.setExecutable(launcher_filename);
mPluginFile = plugin_filename;
mCPUUsage = 0.0f;
setState(STATE_INITIALIZED);
}
@ -503,6 +504,11 @@ void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
{
// this resets our timer.
mHeartbeat.setTimerExpirySec(PLUGIN_LOCKED_UP_SECONDS);
mCPUUsage = message.getValueReal("cpu_usage");
LL_DEBUGS("Plugin") << "cpu usage reported as " << mCPUUsage << LL_ENDL;
}
else if(message_name == "shm_add_response")
{

View File

@ -96,6 +96,8 @@ public:
bool getDisableTimeout() { return mDisableTimeout; };
void setDisableTimeout(bool disable) { mDisableTimeout = disable; };
F64 getCPUUsage() { return mCPUUsage; };
private:
enum EState
@ -140,6 +142,7 @@ private:
LLTimer mHeartbeat;
F64 mSleepTime;
F64 mCPUUsage;
bool mDisableTimeout;
};

View File

@ -17,6 +17,7 @@ include_directories(
set(llprimitive_SOURCE_FILES
llmaterialtable.cpp
llmediaentry.cpp
llprimitive.cpp
llprimtexturelist.cpp
lltextureanim.cpp
@ -31,6 +32,7 @@ set(llprimitive_HEADER_FILES
legacy_object_types.h
llmaterialtable.h
llmediaentry.h
llprimitive.h
llprimtexturelist.h
lltextureanim.h
@ -49,3 +51,10 @@ set_source_files_properties(${llprimitive_HEADER_FILES}
list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES})
add_library (llprimitive ${llprimitive_SOURCE_FILES})
#add unit tests
INCLUDE(LLAddBuildTest)
SET(llprimitive_TEST_SOURCE_FILES
llmediaentry.cpp
)
LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}")

View File

@ -0,0 +1,597 @@
/**
* @file llmediaentry.cpp
* @brief This is a single instance of media data related to the face of a prim
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llmediaentry.h"
#include "lllslconstants.h"
#include <boost/regex.hpp>
// LLSD key defines
// DO NOT REORDER OR REMOVE THESE!
// Some LLSD keys. Do not change!
#define MEDIA_ALT_IMAGE_ENABLE_KEY_STR "alt_image_enable"
#define MEDIA_CONTROLS_KEY_STR "controls"
#define MEDIA_CURRENT_URL_KEY_STR "current_url"
#define MEDIA_HOME_URL_KEY_STR "home_url"
#define MEDIA_AUTO_LOOP_KEY_STR "auto_loop"
#define MEDIA_AUTO_PLAY_KEY_STR "auto_play"
#define MEDIA_AUTO_SCALE_KEY_STR "auto_scale"
#define MEDIA_AUTO_ZOOM_KEY_STR "auto_zoom"
#define MEDIA_FIRST_CLICK_INTERACT_KEY_STR "first_click_interact"
#define MEDIA_WIDTH_PIXELS_KEY_STR "width_pixels"
#define MEDIA_HEIGHT_PIXELS_KEY_STR "height_pixels"
// "security" fields
#define MEDIA_WHITELIST_ENABLE_KEY_STR "whitelist_enable"
#define MEDIA_WHITELIST_KEY_STR "whitelist"
// "permissions" fields
#define MEDIA_PERMS_INTERACT_KEY_STR "perms_interact"
#define MEDIA_PERMS_CONTROL_KEY_STR "perms_control"
// "general" fields
const char* LLMediaEntry::ALT_IMAGE_ENABLE_KEY = MEDIA_ALT_IMAGE_ENABLE_KEY_STR;
const char* LLMediaEntry::CONTROLS_KEY = MEDIA_CONTROLS_KEY_STR;
const char* LLMediaEntry::CURRENT_URL_KEY = MEDIA_CURRENT_URL_KEY_STR;
const char* LLMediaEntry::HOME_URL_KEY = MEDIA_HOME_URL_KEY_STR;
const char* LLMediaEntry::AUTO_LOOP_KEY = MEDIA_AUTO_LOOP_KEY_STR;
const char* LLMediaEntry::AUTO_PLAY_KEY = MEDIA_AUTO_PLAY_KEY_STR;
const char* LLMediaEntry::AUTO_SCALE_KEY = MEDIA_AUTO_SCALE_KEY_STR;
const char* LLMediaEntry::AUTO_ZOOM_KEY = MEDIA_AUTO_ZOOM_KEY_STR;
const char* LLMediaEntry::FIRST_CLICK_INTERACT_KEY = MEDIA_FIRST_CLICK_INTERACT_KEY_STR;
const char* LLMediaEntry::WIDTH_PIXELS_KEY = MEDIA_WIDTH_PIXELS_KEY_STR;
const char* LLMediaEntry::HEIGHT_PIXELS_KEY = MEDIA_HEIGHT_PIXELS_KEY_STR;
// "security" fields
const char* LLMediaEntry::WHITELIST_ENABLE_KEY = MEDIA_WHITELIST_ENABLE_KEY_STR;
const char* LLMediaEntry::WHITELIST_KEY = MEDIA_WHITELIST_KEY_STR;
// "permissions" fields
const char* LLMediaEntry::PERMS_INTERACT_KEY = MEDIA_PERMS_INTERACT_KEY_STR;
const char* LLMediaEntry::PERMS_CONTROL_KEY = MEDIA_PERMS_CONTROL_KEY_STR;
#define DEFAULT_URL_PREFIX "http://"
// Constructor(s)
LLMediaEntry::LLMediaEntry() :
mAltImageEnable(false),
mControls(STANDARD),
mCurrentURL(""),
mHomeURL(""),
mAutoLoop(false),
mAutoPlay(false),
mAutoScale(false),
mAutoZoom(false),
mFirstClickInteract(false),
mWidthPixels(0),
mHeightPixels(0),
mWhiteListEnable(false),
// mWhiteList
mPermsInteract(PERM_ALL),
mPermsControl(PERM_ALL),
mMediaIDp(NULL)
{
}
LLMediaEntry::LLMediaEntry(const LLMediaEntry &rhs) :
mMediaIDp(NULL)
{
// "general" fields
mAltImageEnable = rhs.mAltImageEnable;
mControls = rhs.mControls;
mCurrentURL = rhs.mCurrentURL;
mHomeURL = rhs.mHomeURL;
mAutoLoop = rhs.mAutoLoop;
mAutoPlay = rhs.mAutoPlay;
mAutoScale = rhs.mAutoScale;
mAutoZoom = rhs.mAutoZoom;
mFirstClickInteract = rhs.mFirstClickInteract;
mWidthPixels = rhs.mWidthPixels;
mHeightPixels = rhs.mHeightPixels;
// "security" fields
mWhiteListEnable = rhs.mWhiteListEnable;
mWhiteList = rhs.mWhiteList;
// "permissions" fields
mPermsInteract = rhs.mPermsInteract;
mPermsControl = rhs.mPermsControl;
}
LLMediaEntry::~LLMediaEntry()
{
if (NULL != mMediaIDp)
{
delete mMediaIDp;
}
}
LLSD LLMediaEntry::asLLSD() const
{
LLSD sd;
asLLSD(sd);
return sd;
}
//
// LLSD functions
//
void LLMediaEntry::asLLSD(LLSD& sd) const
{
// "general" fields
sd[ALT_IMAGE_ENABLE_KEY] = mAltImageEnable;
sd[CONTROLS_KEY] = (LLSD::Integer)mControls;
sd[CURRENT_URL_KEY] = mCurrentURL;
sd[HOME_URL_KEY] = mHomeURL;
sd[AUTO_LOOP_KEY] = mAutoLoop;
sd[AUTO_PLAY_KEY] = mAutoPlay;
sd[AUTO_SCALE_KEY] = mAutoScale;
sd[AUTO_ZOOM_KEY] = mAutoZoom;
sd[FIRST_CLICK_INTERACT_KEY] = mFirstClickInteract;
sd[WIDTH_PIXELS_KEY] = mWidthPixels;
sd[HEIGHT_PIXELS_KEY] = mHeightPixels;
// "security" fields
sd[WHITELIST_ENABLE_KEY] = mWhiteListEnable;
for (U32 i=0; i<mWhiteList.size(); i++)
{
sd[WHITELIST_KEY].append(mWhiteList[i]);
}
// "permissions" fields
sd[PERMS_INTERACT_KEY] = mPermsInteract;
sd[PERMS_CONTROL_KEY] = mPermsControl;
}
// static
bool LLMediaEntry::checkLLSD(const LLSD& sd)
{
if (sd.isUndefined()) return true;
LLMediaEntry temp;
return temp.fromLLSDInternal(sd, true);
}
void LLMediaEntry::fromLLSD(const LLSD& sd)
{
(void)fromLLSDInternal(sd, true);
}
void LLMediaEntry::mergeFromLLSD(const LLSD& sd)
{
(void)fromLLSDInternal(sd, false);
}
// *NOTE: returns true if NO failures to set occurred, false otherwise.
// However, be aware that if a failure to set does occur, it does
// not stop setting fields from the LLSD!
bool LLMediaEntry::fromLLSDInternal(const LLSD& sd, bool overwrite)
{
// *HACK: we sort of cheat here and assume that status is a
// bit field. We "or" into status and instead of returning
// it, we return whether it finishes off as LSL_STATUS_OK or not.
U32 status = LSL_STATUS_OK;
// "general" fields
if ( overwrite || sd.has(ALT_IMAGE_ENABLE_KEY) )
{
status |= setAltImageEnable( sd[ALT_IMAGE_ENABLE_KEY] );
}
if ( overwrite || sd.has(CONTROLS_KEY) )
{
status |= setControls( (MediaControls)(LLSD::Integer)sd[CONTROLS_KEY] );
}
if ( overwrite || sd.has(CURRENT_URL_KEY) )
{
// Don't check whitelist
status |= setCurrentURLInternal( sd[CURRENT_URL_KEY], false );
}
if ( overwrite || sd.has(HOME_URL_KEY) )
{
status |= setHomeURL( sd[HOME_URL_KEY] );
}
if ( overwrite || sd.has(AUTO_LOOP_KEY) )
{
status |= setAutoLoop( sd[AUTO_LOOP_KEY] );
}
if ( overwrite || sd.has(AUTO_PLAY_KEY) )
{
status |= setAutoPlay( sd[AUTO_PLAY_KEY] );
}
if ( overwrite || sd.has(AUTO_SCALE_KEY) )
{
status |= setAutoScale( sd[AUTO_SCALE_KEY] );
}
if ( overwrite || sd.has(AUTO_ZOOM_KEY) )
{
status |= setAutoZoom( sd[AUTO_ZOOM_KEY] );
}
if ( overwrite || sd.has(FIRST_CLICK_INTERACT_KEY) )
{
status |= setFirstClickInteract( sd[FIRST_CLICK_INTERACT_KEY] );
}
if ( overwrite || sd.has(WIDTH_PIXELS_KEY) )
{
status |= setWidthPixels( (LLSD::Integer)sd[WIDTH_PIXELS_KEY] );
}
if ( overwrite || sd.has(HEIGHT_PIXELS_KEY) )
{
status |= setHeightPixels( (LLSD::Integer)sd[HEIGHT_PIXELS_KEY] );
}
// "security" fields
if ( overwrite || sd.has(WHITELIST_ENABLE_KEY) )
{
status |= setWhiteListEnable( sd[WHITELIST_ENABLE_KEY] );
}
if ( overwrite || sd.has(WHITELIST_KEY) )
{
status |= setWhiteList( sd[WHITELIST_KEY] );
}
// "permissions" fields
if ( overwrite || sd.has(PERMS_INTERACT_KEY) )
{
status |= setPermsInteract( 0xff & (LLSD::Integer)sd[PERMS_INTERACT_KEY] );
}
if ( overwrite || sd.has(PERMS_CONTROL_KEY) )
{
status |= setPermsControl( 0xff & (LLSD::Integer)sd[PERMS_CONTROL_KEY] );
}
return LSL_STATUS_OK == status;
}
LLMediaEntry& LLMediaEntry::operator=(const LLMediaEntry &rhs)
{
if (this != &rhs)
{
// "general" fields
mAltImageEnable = rhs.mAltImageEnable;
mControls = rhs.mControls;
mCurrentURL = rhs.mCurrentURL;
mHomeURL = rhs.mHomeURL;
mAutoLoop = rhs.mAutoLoop;
mAutoPlay = rhs.mAutoPlay;
mAutoScale = rhs.mAutoScale;
mAutoZoom = rhs.mAutoZoom;
mFirstClickInteract = rhs.mFirstClickInteract;
mWidthPixels = rhs.mWidthPixels;
mHeightPixels = rhs.mHeightPixels;
// "security" fields
mWhiteListEnable = rhs.mWhiteListEnable;
mWhiteList = rhs.mWhiteList;
// "permissions" fields
mPermsInteract = rhs.mPermsInteract;
mPermsControl = rhs.mPermsControl;
}
return *this;
}
bool LLMediaEntry::operator==(const LLMediaEntry &rhs) const
{
return (
// "general" fields
mAltImageEnable == rhs.mAltImageEnable &&
mControls == rhs.mControls &&
mCurrentURL == rhs.mCurrentURL &&
mHomeURL == rhs.mHomeURL &&
mAutoLoop == rhs.mAutoLoop &&
mAutoPlay == rhs.mAutoPlay &&
mAutoScale == rhs.mAutoScale &&
mAutoZoom == rhs.mAutoZoom &&
mFirstClickInteract == rhs.mFirstClickInteract &&
mWidthPixels == rhs.mWidthPixels &&
mHeightPixels == rhs.mHeightPixels &&
// "security" fields
mWhiteListEnable == rhs.mWhiteListEnable &&
mWhiteList == rhs.mWhiteList &&
// "permissions" fields
mPermsInteract == rhs.mPermsInteract &&
mPermsControl == rhs.mPermsControl
);
}
bool LLMediaEntry::operator!=(const LLMediaEntry &rhs) const
{
return (
// "general" fields
mAltImageEnable != rhs.mAltImageEnable ||
mControls != rhs.mControls ||
mCurrentURL != rhs.mCurrentURL ||
mHomeURL != rhs.mHomeURL ||
mAutoLoop != rhs.mAutoLoop ||
mAutoPlay != rhs.mAutoPlay ||
mAutoScale != rhs.mAutoScale ||
mAutoZoom != rhs.mAutoZoom ||
mFirstClickInteract != rhs.mFirstClickInteract ||
mWidthPixels != rhs.mWidthPixels ||
mHeightPixels != rhs.mHeightPixels ||
// "security" fields
mWhiteListEnable != rhs.mWhiteListEnable ||
mWhiteList != rhs.mWhiteList ||
// "permissions" fields
mPermsInteract != rhs.mPermsInteract ||
mPermsControl != rhs.mPermsControl
);
}
U32 LLMediaEntry::setWhiteList( const std::vector<std::string> &whitelist )
{
// *NOTE: This code is VERY similar to the setWhitelist below.
// IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER!
U32 size = 0;
U32 count = 0;
// First count to make sure the size constraint is not violated
std::vector<std::string>::const_iterator iter = whitelist.begin();
std::vector<std::string>::const_iterator end = whitelist.end();
for ( ; iter < end; ++iter)
{
const std::string &entry = (*iter);
size += entry.length() + 1; // Include one for \0
count ++;
if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT)
{
return LSL_STATUS_BOUNDS_ERROR;
}
}
// Next clear the vector
mWhiteList.clear();
// Then re-iterate and copy entries
iter = whitelist.begin();
for ( ; iter < end; ++iter)
{
const std::string &entry = (*iter);
mWhiteList.push_back(entry);
}
return LSL_STATUS_OK;
}
U32 LLMediaEntry::setWhiteList( const LLSD &whitelist )
{
// If whitelist is undef, this is a no-op.
if (whitelist.isUndefined()) return LSL_STATUS_OK;
// However, if the whitelist is an empty array, erase it.
if (whitelist.isArray())
{
// *NOTE: This code is VERY similar to the setWhitelist above.
// IF YOU CHANGE THIS IMPLEMENTATION, BE SURE TO CHANGE THE OTHER!
U32 size = 0;
U32 count = 0;
// First check to make sure the size and count constraints are not violated
LLSD::array_const_iterator iter = whitelist.beginArray();
LLSD::array_const_iterator end = whitelist.endArray();
for ( ; iter < end; ++iter)
{
const std::string &entry = (*iter).asString();
size += entry.length() + 1; // Include one for \0
count ++;
if (size > MAX_WHITELIST_SIZE || count > MAX_WHITELIST_COUNT)
{
return LSL_STATUS_BOUNDS_ERROR;
}
}
// Next clear the vector
mWhiteList.clear();
// Then re-iterate and copy entries
iter = whitelist.beginArray();
for ( ; iter < end; ++iter)
{
const std::string &entry = (*iter).asString();
mWhiteList.push_back(entry);
}
return LSL_STATUS_OK;
}
else
{
return LSL_STATUS_MALFORMED_PARAMS;
}
}
static void prefix_with(std::string &str, const char *chars, const char *prefix)
{
// Given string 'str', prefix all instances of any character in 'chars'
// with 'prefix'
size_t found = str.find_first_of(chars);
size_t prefix_len = strlen(prefix);
while (found != std::string::npos)
{
str.insert(found, prefix, prefix_len);
found = str.find_first_of(chars, found+prefix_len+1);
}
}
static bool pattern_match(const std::string &candidate_str, const std::string &pattern)
{
// If the pattern is empty, it matches
if (pattern.empty()) return true;
// 'pattern' is a glob pattern, we only accept '*' chars
// copy it
std::string expression = pattern;
// Escape perl's regexp chars with a backslash, except all "*" chars
prefix_with(expression, ".[{()\\+?|^$", "\\");
prefix_with(expression, "*", ".");
// case-insensitive matching:
boost::regex regexp(expression, boost::regex::perl|boost::regex::icase);
return boost::regex_match(candidate_str, regexp);
}
bool LLMediaEntry::checkCandidateUrl(const std::string& url) const
{
if (getWhiteListEnable())
{
return checkUrlAgainstWhitelist(url, getWhiteList());
}
else
{
return true;
}
}
// static
bool LLMediaEntry::checkUrlAgainstWhitelist(const std::string& url,
const std::vector<std::string> &whitelist)
{
bool passes = true;
// *NOTE: no entries? Don't check
if (whitelist.size() > 0)
{
passes = false;
// Case insensitive: the reason why we toUpper both this and the
// filter
std::string candidate_url = url;
// Use lluri to see if there is a path part in the candidate URL. No path? Assume "/"
LLURI candidate_uri(candidate_url);
std::vector<std::string>::const_iterator iter = whitelist.begin();
std::vector<std::string>::const_iterator end = whitelist.end();
for ( ; iter < end; ++iter )
{
std::string filter = *iter;
LLURI filter_uri(filter);
bool scheme_passes = pattern_match( candidate_uri.scheme(), filter_uri.scheme() );
if (filter_uri.scheme().empty())
{
filter_uri = LLURI(DEFAULT_URL_PREFIX + filter);
}
bool authority_passes = pattern_match( candidate_uri.authority(), filter_uri.authority() );
bool path_passes = pattern_match( candidate_uri.escapedPath(), filter_uri.escapedPath() );
if (scheme_passes && authority_passes && path_passes)
{
passes = true;
break;
}
}
}
return passes;
}
U32 LLMediaEntry::setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit )
{
if ( value.length() > limit )
{
return LSL_STATUS_BOUNDS_ERROR;
}
else
{
field = value;
return LSL_STATUS_OK;
}
}
U32 LLMediaEntry::setControls(LLMediaEntry::MediaControls controls)
{
if (controls == STANDARD ||
controls == MINI)
{
mControls = controls;
return LSL_STATUS_OK;
}
return LSL_STATUS_BOUNDS_ERROR;
}
U32 LLMediaEntry::setPermsInteract( U8 val )
{
mPermsInteract = val & PERM_MASK;
return LSL_STATUS_OK;
}
U32 LLMediaEntry::setPermsControl( U8 val )
{
mPermsControl = val & PERM_MASK;
return LSL_STATUS_OK;
}
U32 LLMediaEntry::setCurrentURL(const std::string& current_url)
{
return setCurrentURLInternal( current_url, true );
}
U32 LLMediaEntry::setCurrentURLInternal(const std::string& current_url, bool check_whitelist)
{
if ( ! check_whitelist || checkCandidateUrl(current_url))
{
return setStringFieldWithLimit( mCurrentURL, current_url, MAX_URL_LENGTH );
}
else
{
return LSL_STATUS_WHITELIST_FAILED;
}
}
U32 LLMediaEntry::setHomeURL(const std::string& home_url)
{
return setStringFieldWithLimit( mHomeURL, home_url, MAX_URL_LENGTH );
}
U32 LLMediaEntry::setWidthPixels(U16 width)
{
if (width > MAX_WIDTH_PIXELS) return LSL_STATUS_BOUNDS_ERROR;
mWidthPixels = width;
return LSL_STATUS_OK;
}
U32 LLMediaEntry::setHeightPixels(U16 height)
{
if (height > MAX_HEIGHT_PIXELS) return LSL_STATUS_BOUNDS_ERROR;
mHeightPixels = height;
return LSL_STATUS_OK;
}
const LLUUID &LLMediaEntry::getMediaID() const
{
// Lazily generate media ID
if (NULL == mMediaIDp)
{
mMediaIDp = new LLUUID();
mMediaIDp->generate();
}
return *mMediaIDp;
}

View File

@ -0,0 +1,228 @@
/**
* @file llmediaentry.h
* @brief This is a single instance of media data related to the face of a prim
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLMEDIAENTRY_H
#define LL_LLMEDIAENTRY_H
#include "llsd.h"
#include "llstring.h"
// For return values of set*
#include "lllslconstants.h"
class LLMediaEntry
{
public:
enum MediaControls {
STANDARD = 0,
MINI
};
// Constructors
LLMediaEntry();
LLMediaEntry(const LLMediaEntry &rhs);
LLMediaEntry &operator=(const LLMediaEntry &rhs);
virtual ~LLMediaEntry();
bool operator==(const LLMediaEntry &rhs) const;
bool operator!=(const LLMediaEntry &rhs) const;
// Render as LLSD
LLSD asLLSD() const;
void asLLSD(LLSD& sd) const;
operator LLSD() const { return asLLSD(); }
// Returns false iff the given LLSD contains fields that violate any bounds
// limits.
static bool checkLLSD(const LLSD& sd);
// This doesn't merge, it overwrites the data, so will use
// LLSD defaults if need be. Note: does not check limits!
// Use checkLLSD() above first to ensure the LLSD is valid.
void fromLLSD(const LLSD& sd);
// This merges data from the incoming LLSD into our fields.
// Note that it also does NOT check limits! Use checkLLSD() above first.
void mergeFromLLSD(const LLSD& sd);
// "general" fields
bool getAltImageEnable() const { return mAltImageEnable; }
MediaControls getControls() const { return mControls; }
std::string getCurrentURL() const { return mCurrentURL; }
std::string getHomeURL() const { return mHomeURL; }
bool getAutoLoop() const { return mAutoLoop; }
bool getAutoPlay() const { return mAutoPlay; }
bool getAutoScale() const { return mAutoScale; }
bool getAutoZoom() const { return mAutoZoom; }
bool getFirstClickInteract() const { return mFirstClickInteract; }
U16 getWidthPixels() const { return mWidthPixels; }
U16 getHeightPixels() const { return mHeightPixels; }
// "security" fields
bool getWhiteListEnable() const { return mWhiteListEnable; }
const std::vector<std::string> &getWhiteList() const { return mWhiteList; }
// "permissions" fields
U8 getPermsInteract() const { return mPermsInteract; }
U8 getPermsControl() const { return mPermsControl; }
// Setters. Those that return a U32 return a status error code
// See lllslconstants.h
// "general" fields
U32 setAltImageEnable(bool alt_image_enable) { mAltImageEnable = alt_image_enable; return LSL_STATUS_OK; }
U32 setControls(MediaControls controls);
U32 setCurrentURL(const std::string& current_url);
U32 setHomeURL(const std::string& home_url);
U32 setAutoLoop(bool auto_loop) { mAutoLoop = auto_loop; return LSL_STATUS_OK; }
U32 setAutoPlay(bool auto_play) { mAutoPlay = auto_play; return LSL_STATUS_OK; }
U32 setAutoScale(bool auto_scale) { mAutoScale = auto_scale; return LSL_STATUS_OK; }
U32 setAutoZoom(bool auto_zoom) { mAutoZoom = auto_zoom; return LSL_STATUS_OK; }
U32 setFirstClickInteract(bool first_click) { mFirstClickInteract = first_click; return LSL_STATUS_OK; }
U32 setWidthPixels(U16 width);
U32 setHeightPixels(U16 height);
// "security" fields
U32 setWhiteListEnable( bool whitelist_enable ) { mWhiteListEnable = whitelist_enable; return LSL_STATUS_OK; }
U32 setWhiteList( const std::vector<std::string> &whitelist );
U32 setWhiteList( const LLSD &whitelist ); // takes an LLSD array
// "permissions" fields
U32 setPermsInteract( U8 val );
U32 setPermsControl( U8 val );
const LLUUID& getMediaID() const;
// Helper function to check a candidate URL against the whitelist
// Returns true iff candidate URL passes (or if there is no whitelist), false otherwise
bool checkCandidateUrl(const std::string& url) const;
public:
// Static function to check a URL against a whitelist
// Returns true iff url passes the given whitelist
static bool checkUrlAgainstWhitelist(const std::string &url,
const std::vector<std::string> &whitelist);
public:
// LLSD key defines
// "general" fields
static const char* ALT_IMAGE_ENABLE_KEY;
static const char* CONTROLS_KEY;
static const char* CURRENT_URL_KEY;
static const char* HOME_URL_KEY;
static const char* AUTO_LOOP_KEY;
static const char* AUTO_PLAY_KEY;
static const char* AUTO_SCALE_KEY;
static const char* AUTO_ZOOM_KEY;
static const char* FIRST_CLICK_INTERACT_KEY;
static const char* WIDTH_PIXELS_KEY;
static const char* HEIGHT_PIXELS_KEY;
// "security" fields
static const char* WHITELIST_ENABLE_KEY;
static const char* WHITELIST_KEY;
// "permissions" fields
static const char* PERMS_INTERACT_KEY;
static const char* PERMS_CONTROL_KEY;
// Field enumerations & constants
// *NOTE: DO NOT change the order of these, and do not insert values
// in the middle!
// Add values to the end, and make sure to change PARAM_MAX_ID!
enum Fields {
ALT_IMAGE_ENABLE_ID = 0,
CONTROLS_ID = 1,
CURRENT_URL_ID = 2,
HOME_URL_ID = 3,
AUTO_LOOP_ID = 4,
AUTO_PLAY_ID = 5,
AUTO_SCALE_ID = 6,
AUTO_ZOOM_ID = 7,
FIRST_CLICK_INTERACT_ID = 8,
WIDTH_PIXELS_ID = 9,
HEIGHT_PIXELS_ID = 10,
WHITELIST_ENABLE_ID = 11,
WHITELIST_ID = 12,
PERMS_INTERACT_ID = 13,
PERMS_CONTROL_ID = 14,
PARAM_MAX_ID = PERMS_CONTROL_ID
};
// "permissions" values
// (e.g. (PERM_OWNER | PERM_GROUP) sets permissions on for OWNER and GROUP
static const U8 PERM_NONE = 0x0;
static const U8 PERM_OWNER = 0x1;
static const U8 PERM_GROUP = 0x2;
static const U8 PERM_ANYONE = 0x4;
static const U8 PERM_ALL = PERM_OWNER|PERM_GROUP|PERM_ANYONE;
static const U8 PERM_MASK = PERM_OWNER|PERM_GROUP|PERM_ANYONE;
// Limits (in bytes)
static const U32 MAX_URL_LENGTH = 1024;
static const U32 MAX_WHITELIST_SIZE = 1024;
static const U32 MAX_WHITELIST_COUNT = 64;
static const U16 MAX_WIDTH_PIXELS = 2048;
static const U16 MAX_HEIGHT_PIXELS = 2048;
private:
U32 setStringFieldWithLimit( std::string &field, const std::string &value, U32 limit );
U32 setCurrentURLInternal( const std::string &url, bool check_whitelist);
bool fromLLSDInternal(const LLSD &sd, bool overwrite);
private:
// "general" fields
bool mAltImageEnable;
MediaControls mControls;
std::string mCurrentURL;
std::string mHomeURL;
bool mAutoLoop;
bool mAutoPlay;
bool mAutoScale;
bool mAutoZoom;
bool mFirstClickInteract;
U16 mWidthPixels;
U16 mHeightPixels;
// "security" fields
bool mWhiteListEnable;
std::vector<std::string> mWhiteList;
// "permissions" fields
U8 mPermsInteract;
U8 mPermsControl;
mutable LLUUID *mMediaIDp; // temporary id assigned to media on the viewer
};
#endif

View File

@ -1134,6 +1134,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con
color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f;
retval |= setTEColor(i, color);
}
return retval;

View File

@ -32,13 +32,31 @@
#include "linden_common.h"
#include "lluuid.h"
#include "llmediaentry.h"
#include "lltextureentry.h"
#include "llsdutil.h"
#include "v4color.h"
const U8 DEFAULT_BUMP_CODE = 0; // no bump or shininess
const LLTextureEntry LLTextureEntry::null;
// Some LLSD keys. Do not change these!
#define OBJECT_ID_KEY_STR "object_id"
#define TEXTURE_INDEX_KEY_STR "texture_index"
#define OBJECT_MEDIA_VERSION_KEY_STR "object_media_version"
#define OBJECT_MEDIA_DATA_KEY_STR "object_media_data"
#define TEXTURE_MEDIA_DATA_KEY_STR "media_data"
/*static*/ const char* LLTextureEntry::OBJECT_ID_KEY = OBJECT_ID_KEY_STR;
/*static*/ const char* LLTextureEntry::OBJECT_MEDIA_DATA_KEY = OBJECT_MEDIA_DATA_KEY_STR;
/*static*/ const char* LLTextureEntry::MEDIA_VERSION_KEY = OBJECT_MEDIA_VERSION_KEY_STR;
/*static*/ const char* LLTextureEntry::TEXTURE_INDEX_KEY = TEXTURE_INDEX_KEY_STR;
/*static*/ const char* LLTextureEntry::TEXTURE_MEDIA_DATA_KEY = TEXTURE_MEDIA_DATA_KEY_STR;
static const std::string MEDIA_VERSION_STRING_PREFIX = "x-mv:";
// static
LLTextureEntry* LLTextureEntry::newTextureEntry()
{
@ -47,16 +65,19 @@ LLTextureEntry* LLTextureEntry::newTextureEntry()
//===============================================================
LLTextureEntry::LLTextureEntry()
: mMediaEntry(NULL)
{
init(LLUUID::null,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLUUID& tex_id)
: mMediaEntry(NULL)
{
init(tex_id,1.f,1.f,0.f,0.f,0.f,DEFAULT_BUMP_CODE);
}
LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
: mMediaEntry(NULL)
{
mID = rhs.mID;
mScaleS = rhs.mScaleS;
@ -68,6 +89,10 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
mGlow = rhs.mGlow;
if (rhs.mMediaEntry != NULL) {
// Make a copy
mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
}
}
LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
@ -84,6 +109,16 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
mGlow = rhs.mGlow;
if (mMediaEntry != NULL) {
delete mMediaEntry;
}
if (rhs.mMediaEntry != NULL) {
// Make a copy
mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry);
}
else {
mMediaEntry = NULL;
}
}
return *this;
@ -103,10 +138,19 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of
mGlow = 0;
setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
if (mMediaEntry != NULL) {
delete mMediaEntry;
}
mMediaEntry = NULL;
}
LLTextureEntry::~LLTextureEntry()
{
if(mMediaEntry)
{
delete mMediaEntry;
mMediaEntry = NULL;
}
}
bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const
@ -158,10 +202,17 @@ void LLTextureEntry::asLLSD(LLSD& sd) const
sd["bump"] = getBumpShiny();
sd["fullbright"] = getFullbright();
sd["media_flags"] = mMediaFlags;
if (hasMedia()) {
LLSD mediaData;
if (NULL != getMediaData()) {
getMediaData()->asLLSD(mediaData);
}
sd[TEXTURE_MEDIA_DATA_KEY] = mediaData;
}
sd["glow"] = mGlow;
}
bool LLTextureEntry::fromLLSD(LLSD& sd)
bool LLTextureEntry::fromLLSD(const LLSD& sd)
{
const char *w, *x;
w = "imageid";
@ -206,6 +257,17 @@ bool LLTextureEntry::fromLLSD(LLSD& sd)
{
setMediaTexGen( sd[w].asInteger() );
} else goto fail;
// If the "has media" flag doesn't match the fact that
// media data exists, updateMediaData will "fix" it
// by either clearing or setting the flag
w = TEXTURE_MEDIA_DATA_KEY;
if (hasMedia() != sd.has(w))
{
llwarns << "LLTextureEntry::fromLLSD: media_flags (" << hasMedia() <<
") does not match presence of media_data (" << sd.has(w) << "). Fixing." << llendl;
}
updateMediaData(sd[w]);
w = "glow";
if (sd.has(w))
{
@ -370,7 +432,19 @@ S32 LLTextureEntry::setMediaTexGen(U8 media)
if (mMediaFlags != media)
{
mMediaFlags = media;
return TEM_CHANGE_TEXTURE;
// Special code for media handling
if( hasMedia() && mMediaEntry == NULL)
{
mMediaEntry = new LLMediaEntry;
}
else if ( ! hasMedia() && mMediaEntry != NULL)
{
delete mMediaEntry;
mMediaEntry = NULL;
}
return TEM_CHANGE_MEDIA;
}
return TEM_CHANGE_NONE;
}
@ -430,7 +504,19 @@ S32 LLTextureEntry::setMediaFlags(U8 media_flags)
{
mMediaFlags &= ~TEM_MEDIA_MASK;
mMediaFlags |= media_flags;
return TEM_CHANGE_TEXTURE;
// Special code for media handling
if( hasMedia() && mMediaEntry == NULL)
{
mMediaEntry = new LLMediaEntry;
}
else if ( ! hasMedia() && mMediaEntry != NULL)
{
delete mMediaEntry;
mMediaEntry = NULL;
}
return TEM_CHANGE_MEDIA;
}
return TEM_CHANGE_NONE;
}
@ -456,3 +542,107 @@ S32 LLTextureEntry::setGlow(F32 glow)
}
return TEM_CHANGE_NONE;
}
void LLTextureEntry::setMediaData(const LLMediaEntry &media_entry)
{
mMediaFlags |= MF_HAS_MEDIA;
if (NULL != mMediaEntry)
{
delete mMediaEntry;
}
mMediaEntry = new LLMediaEntry(media_entry);
}
bool LLTextureEntry::updateMediaData(const LLSD& media_data)
{
if (media_data.isUndefined())
{
// clear the media data
clearMediaData();
return false;
}
else {
mMediaFlags |= MF_HAS_MEDIA;
if (mMediaEntry == NULL)
{
mMediaEntry = new LLMediaEntry;
}
// *NOTE: this will *clobber* all of the fields in mMediaEntry
// with whatever fields are present (or not present) in media_data!
mMediaEntry->fromLLSD(media_data);
return true;
}
}
void LLTextureEntry::clearMediaData()
{
mMediaFlags &= ~MF_HAS_MEDIA;
if (mMediaEntry != NULL) {
delete mMediaEntry;
}
mMediaEntry = NULL;
}
void LLTextureEntry::mergeIntoMediaData(const LLSD& media_fields)
{
mMediaFlags |= MF_HAS_MEDIA;
if (mMediaEntry == NULL)
{
mMediaEntry = new LLMediaEntry;
}
// *NOTE: this will *merge* the data in media_fields
// with the data in our media entry
mMediaEntry->mergeFromLLSD(media_fields);
}
//static
std::string LLTextureEntry::touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id)
{
// XXX TODO: make media version string binary (base64-encoded?)
// Media "URL" is a representation of a version and the last-touched agent
// x-mv:nnnnn/agent-id
// where "nnnnn" is version number
// *NOTE: not the most efficient code in the world...
U32 current_version = getVersionFromMediaVersionString(in_version) + 1;
const size_t MAX_VERSION_LEN = 10; // 2^32 fits in 10 decimal digits
char buf[MAX_VERSION_LEN+1];
snprintf(buf, (int)MAX_VERSION_LEN+1, "%0*u", (int)MAX_VERSION_LEN, current_version); // added int cast to fix warning/breakage on mac.
return MEDIA_VERSION_STRING_PREFIX + buf + "/" + agent_id.asString();
}
//static
U32 LLTextureEntry::getVersionFromMediaVersionString(const std::string &version_string)
{
U32 version = 0;
if (!version_string.empty())
{
size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
if (found != std::string::npos)
{
found = version_string.find_first_of("/", found);
std::string v = version_string.substr(MEDIA_VERSION_STRING_PREFIX.length(), found);
version = strtoul(v.c_str(),NULL,10);
}
}
return version;
}
//static
LLUUID LLTextureEntry::getAgentIDFromMediaVersionString(const std::string &version_string)
{
LLUUID id;
if (!version_string.empty())
{
size_t found = version_string.find(MEDIA_VERSION_STRING_PREFIX);
if (found != std::string::npos)
{
found = version_string.find_first_of("/", found);
if (found != std::string::npos)
{
std::string v = version_string.substr(found + 1);
id.set(v);
}
}
}
return id;
}

View File

@ -37,10 +37,13 @@
#include "v4color.h"
#include "llsd.h"
// These bits are used while unpacking TEM messages to tell which aspects of
// the texture entry changed.
const S32 TEM_CHANGE_NONE = 0x0;
const S32 TEM_CHANGE_COLOR = 0x1;
const S32 TEM_CHANGE_TEXTURE = 0x2;
const S32 TEM_INVALID = 0x4;
const S32 TEM_CHANGE_MEDIA = 0x4;
const S32 TEM_INVALID = 0x8;
const S32 TEM_BUMPMAP_COUNT = 32;
@ -65,6 +68,8 @@ const S32 TEM_MEDIA_MASK = 0x01;
const S32 TEM_TEX_GEN_MASK = 0x06;
const S32 TEM_TEX_GEN_SHIFT = 1;
// forward declarations
class LLMediaEntry;
class LLTextureEntry
{
@ -92,7 +97,7 @@ public:
LLSD asLLSD() const;
void asLLSD(LLSD& sd) const;
operator LLSD() const { return asLLSD(); }
bool fromLLSD(LLSD& sd);
bool fromLLSD(const LLSD& sd);
virtual LLTextureEntry* newBlank() const;
virtual LLTextureEntry* newCopy() const;
@ -140,9 +145,35 @@ public:
U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; }
U8 getMediaTexGen() const { return mMediaFlags; }
F32 getGlow() const { return mGlow; }
// *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL.
// CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData()
// to NOT return NULL.
bool hasMedia() const { return (bool)(mMediaFlags & MF_HAS_MEDIA); }
LLMediaEntry* getMediaData() const { return mMediaEntry; }
// Completely change the media data on this texture entry.
void setMediaData(const LLMediaEntry &media_entry);
// Returns true if media data was updated, false if it was cleared
bool updateMediaData(const LLSD& media_data);
// Clears media data, and sets the media flags bit to 0
void clearMediaData();
// Merges the given LLSD of media fields with this media entry.
// Only those fields that are set that match the keys in
// LLMediaEntry will be affected. If no fields are set or if
// the LLSD is undefined, this is a no-op.
void mergeIntoMediaData(const LLSD& media_fields);
// Takes a media version string (an empty string or a previously-returned string)
// and returns a "touched" string, touched by agent_id
static std::string touchMediaVersionString(const std::string &in_version, const LLUUID &agent_id);
// Given a media version string, return the version
static U32 getVersionFromMediaVersionString(const std::string &version_string);
// Given a media version string, return the UUID of the agent
static LLUUID getAgentIDFromMediaVersionString(const std::string &version_string);
// Media flags
enum { MF_NONE = 0x0, MF_WEB_PAGE = 0x1 };
enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 };
public:
F32 mScaleS; // S, T offset
@ -152,6 +183,14 @@ public:
F32 mRotation; // anti-clockwise rotation in rad about the bottom left corner
static const LLTextureEntry null;
// LLSD key defines
static const char* OBJECT_ID_KEY;
static const char* OBJECT_MEDIA_DATA_KEY;
static const char* MEDIA_VERSION_KEY;
static const char* TEXTURE_INDEX_KEY;
static const char* TEXTURE_MEDIA_DATA_KEY;
protected:
LLUUID mID; // Texture GUID
LLColor4 mColor;
@ -159,6 +198,9 @@ protected:
U8 mMediaFlags; // replace with web page, movie, etc.
F32 mGlow;
// Note the media data is not sent via the same message structure as the rest of the TE
LLMediaEntry* mMediaEntry; // The media data for the face
// NOTE: when adding new data to this class, in addition to adding it to the serializers asLLSD/fromLLSD and the
// message packers (e.g. LLPrimitive::packTEMessage) you must also implement its copy in LLPrimitive::copyTEs()

View File

@ -0,0 +1,484 @@
/**
* @file llmediaentry_test.cpp
* @brief llmediaentry unit tests
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
* Copyright (c) 2001-2009, Linden Research, Inc.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "lltut.h"
#include "boost/lexical_cast.hpp"
#include "llstring.h"
#include "llsdutil.h"
#include "llsdserialize.h"
#include "../llmediaentry.h"
#include "lllslconstants.h"
#define DEFAULT_MEDIA_ENTRY "<llsd>\n\
<map>\n\
<key>alt_image_enable</key>\n\
<boolean>0</boolean>\n\
<key>auto_loop</key>\n\
<boolean>0</boolean>\n\
<key>auto_play</key>\n\
<boolean>0</boolean>\n\
<key>auto_scale</key>\n\
<boolean>0</boolean>\n\
<key>auto_zoom</key>\n\
<boolean>0</boolean>\n\
<key>controls</key>\n\
<integer>0</integer>\n\
<key>current_url</key>\n\
<string />\n\
<key>first_click_interact</key>\n\
<boolean>0</boolean>\n\
<key>height_pixels</key>\n\
<integer>0</integer>\n\
<key>home_url</key>\n\
<string />\n\
<key>perms_control</key>\n\
<integer>7</integer>\n\
<key>perms_interact</key>\n\
<integer>7</integer>\n\
<key>whitelist_enable</key>\n\
<boolean>0</boolean>\n\
<key>width_pixels</key>\n\
<integer>0</integer>\n\
</map>\n\
</llsd>"
#define EMPTY_MEDIA_ENTRY "<llsd>\n\
<map>\n\
<key>alt_image_enable</key>\n\
<boolean>0</boolean>\n\
<key>auto_loop</key>\n\
<boolean>0</boolean>\n\
<key>auto_play</key>\n\
<boolean>0</boolean>\n\
<key>auto_scale</key>\n\
<boolean>0</boolean>\n\
<key>auto_zoom</key>\n\
<boolean>0</boolean>\n\
<key>controls</key>\n\
<integer>0</integer>\n\
<key>current_url</key>\n\
<string />\n\
<key>first_click_interact</key>\n\
<boolean>0</boolean>\n\
<key>height_pixels</key>\n\
<integer>0</integer>\n\
<key>home_url</key>\n\
<string />\n\
<key>perms_control</key>\n\
<integer>0</integer>\n\
<key>perms_interact</key>\n\
<integer>0</integer>\n\
<key>whitelist_enable</key>\n\
<boolean>0</boolean>\n\
<key>width_pixels</key>\n\
<integer>0</integer>\n\
</map>\n\
</llsd>"
#define PARTIAL_MEDIA_ENTRY(CURRENT_URL) "<llsd>\n\
<map>\n\
<key>alt_image_enable</key>\n\
<boolean>0</boolean>\n\
<key>auto_loop</key>\n\
<boolean>0</boolean>\n\
<key>auto_play</key>\n\
<boolean>0</boolean>\n\
<key>auto_scale</key>\n\
<boolean>0</boolean>\n\
<key>auto_zoom</key>\n\
<boolean>0</boolean>\n\
<key>controls</key>\n\
<integer>0</integer>\n\
<key>current_url</key>\n\
<string>" CURRENT_URL "</string>\n\
<key>first_click_interact</key>\n\
<boolean>0</boolean>\n\
<key>height_pixels</key>\n\
<integer>0</integer>\n\
<key>home_url</key>\n\
<string />\n\
<key>perms_control</key>\n\
<integer>0</integer>\n\
<key>perms_interact</key>\n\
<integer>0</integer>\n\
<key>whitelist_enable</key>\n\
<boolean>0</boolean>\n\
<key>width_pixels</key>\n\
<integer>0</integer>\n\
</map>\n\
</llsd>"
namespace tut
{
// this is fixture data that gets created before each test and destroyed
// after each test. this is where we put all of the setup/takedown code
// and data needed for each test.
struct MediaEntry_test
{
MediaEntry_test() {
emptyMediaEntryStr = EMPTY_MEDIA_ENTRY;
std::istringstream e(EMPTY_MEDIA_ENTRY);
LLSDSerialize::fromXML(emptyMediaEntryLLSD, e);
defaultMediaEntryStr = DEFAULT_MEDIA_ENTRY;
std::istringstream d(DEFAULT_MEDIA_ENTRY);
LLSDSerialize::fromXML(defaultMediaEntryLLSD, d);
}
std::string emptyMediaEntryStr;
LLSD emptyMediaEntryLLSD;
std::string defaultMediaEntryStr;
LLSD defaultMediaEntryLLSD;
};
typedef test_group<MediaEntry_test, 55> factory;
typedef factory::object object;
}
namespace
{
// this is for naming our tests to make pretty output
tut::factory tf("MediaEntry Test");
}
namespace tut
{
bool llsd_equals(const LLSD& a, const LLSD& b) {
// cheesy, brute force, but it works
return std::string(ll_pretty_print_sd(a)) == std::string(ll_pretty_print_sd(b));
}
void ensure_llsd_equals(const std::string& msg, const LLSD& expected, const LLSD& actual)
{
if (! llsd_equals(expected, actual))
{
std::string message = msg;
message += ": actual: ";
message += ll_pretty_print_sd(actual);
message += "\n expected: ";
message += ll_pretty_print_sd(expected);
message += "\n";
ensure(message, false);
}
}
void ensure_string_equals(const std::string& msg, const std::string& expected, const std::string& actual)
{
if ( expected != actual )
{
std::string message = msg;
message += ": actual: ";
message += actual;
message += "\n expected: ";
message += expected;
message += "\n";
ensure(message, false);
}
}
void set_whitelist(LLMediaEntry &entry, const char *str)
{
std::vector<std::string> tokens;
LLStringUtil::getTokens(std::string(str), tokens, ",");
entry.setWhiteList(tokens);
}
void whitelist_test(bool enable, const char *whitelist, const char *candidate_url, bool expected_pass)
{
std::string message = "Whitelist test";
LLMediaEntry entry;
entry.setWhiteListEnable(enable);
set_whitelist(entry, whitelist);
bool passed_whitelist = entry.checkCandidateUrl(candidate_url);
if (passed_whitelist != expected_pass)
{
message += " failed: expected ";
message += (expected_pass) ? "" : "NOT ";
message += "to match\nwhitelist = ";
message += whitelist;
message += "\ncandidate_url = ";
message += candidate_url;
}
ensure(message, expected_pass == passed_whitelist);
}
void whitelist_test(const char *whitelist, const char *candidate_url, bool expected_pass)
{
whitelist_test(true, whitelist, candidate_url, expected_pass);
}
void whitelist_test(const char *whitelist, const char *candidate_url)
{
whitelist_test(true, whitelist, candidate_url, true);
}
template<> template<>
void object::test<1>()
{
set_test_name("Test LLMediaEntry Instantiation");
LLMediaEntry entry;
ensure_llsd_equals(get_test_name(), defaultMediaEntryLLSD, entry.asLLSD());
}
template<> template<>
void object::test<2>()
{
set_test_name("Test LLMediaEntry Instantiation from LLSD");
LLMediaEntry entry;
LLSD sd;
entry.fromLLSD(sd);
ensure_llsd_equals(get_test_name() + " failed", emptyMediaEntryLLSD, entry.asLLSD());
}
template<> template<>
void object::test<3>()
{
set_test_name("Test LLMediaEntry Partial Instantiation from LLSD");
LLMediaEntry entry;
LLSD sd;
sd[LLMediaEntry::CURRENT_URL_KEY] = "http://www.example.com";
entry.fromLLSD(sd);
LLSD golden;
std::istringstream p(PARTIAL_MEDIA_ENTRY("http://www.example.com"));
LLSDSerialize::fromXML(golden,p);
ensure_llsd_equals(get_test_name() + " failed", golden, entry.asLLSD());
}
// limit tests
const char *URL_OK = "http://www.example.com";
const char *URL_TOO_BIG = "http://www.example.com.qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq";
template<> template<>
void object::test<4>()
{
set_test_name("Test Limits on setting current URL");
LLMediaEntry entry;
U32 status = entry.setCurrentURL(URL_OK);
ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK);
status = entry.setCurrentURL(URL_TOO_BIG);
ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR);
}
template<> template<>
void object::test<5>()
{
set_test_name("Test Limits on setting home URL");
LLMediaEntry entry;
U32 status = entry.setHomeURL(URL_OK);
ensure(get_test_name() + " ok failed", status == LSL_STATUS_OK);
status = entry.setHomeURL(URL_TOO_BIG);
ensure(get_test_name() + " ok failed", status == LSL_STATUS_BOUNDS_ERROR);
}
template<> template<>
void object::test<6>()
{
set_test_name("Test Limits on setting whitelist");
// Test a valid list
LLMediaEntry entry;
std::vector<std::string> whitelist;
whitelist.push_back(std::string(URL_OK));
S32 status = entry.setWhiteList(whitelist);
ensure(get_test_name() + " invalid result", status == LSL_STATUS_OK);
ensure(get_test_name() + " failed", whitelist == entry.getWhiteList());
}
template<> template<>
void object::test<7>()
{
set_test_name("Test Limits on setting whitelist too big");
// Test an invalid list
LLMediaEntry entry;
std::vector<std::string> whitelist, empty;
whitelist.push_back(std::string(URL_OK));
whitelist.push_back(std::string(URL_TOO_BIG));
S32 status = entry.setWhiteList(whitelist);
ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR);
ensure(get_test_name() + " failed", empty == entry.getWhiteList());
}
template<> template<>
void object::test<8>()
{
set_test_name("Test Limits on setting whitelist too many");
// Test an invalid list
LLMediaEntry entry;
std::vector<std::string> whitelist, empty;
for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) {
whitelist.push_back("Q");
}
S32 status = entry.setWhiteList(whitelist);
ensure(get_test_name() + " invalid result", status == LSL_STATUS_BOUNDS_ERROR);
ensure(get_test_name() + " failed", empty == entry.getWhiteList());
}
template<> template<>
void object::test<9>()
{
set_test_name("Test to make sure both setWhiteList() functions behave the same");
// Test a valid list
std::vector<std::string> whitelist, empty;
LLSD whitelist_llsd;
whitelist.push_back(std::string(URL_OK));
whitelist_llsd.append(std::string(URL_OK));
LLMediaEntry entry1, entry2;
ensure(get_test_name() + " setWhiteList(s) don't match",
entry1.setWhiteList(whitelist) == LSL_STATUS_OK &&
entry2.setWhiteList(whitelist_llsd)== LSL_STATUS_OK );
ensure(get_test_name() + " failed",
entry1.getWhiteList() == entry2.getWhiteList());
}
template<> template<>
void object::test<10>()
{
set_test_name("Test to make sure both setWhiteList() functions behave the same");
// Test an invalid list
std::vector<std::string> whitelist, empty;
LLSD whitelist_llsd;
whitelist.push_back(std::string(URL_OK));
whitelist.push_back(std::string(URL_TOO_BIG));
whitelist_llsd.append(std::string(URL_OK));
whitelist_llsd.append(std::string(URL_TOO_BIG));
LLMediaEntry entry1, entry2;
ensure(get_test_name() + " setWhiteList(s) don't match",
entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR &&
entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR);
ensure(get_test_name() + " failed",
empty == entry1.getWhiteList() &&
empty == entry2.getWhiteList());
}
template<> template<>
void object::test<11>()
{
set_test_name("Test to make sure both setWhiteList() functions behave the same");
// Test an invalid list, too many
std::vector<std::string> whitelist, empty;
LLSD whitelist_llsd;
for (int i=0; i < LLMediaEntry::MAX_WHITELIST_SIZE+1; i++) {
whitelist.push_back("Q");
whitelist_llsd.append("Q");
}
LLMediaEntry entry1, entry2;
ensure(get_test_name() + " invalid result",
entry1.setWhiteList(whitelist) == LSL_STATUS_BOUNDS_ERROR &&
entry2.setWhiteList(whitelist_llsd) == LSL_STATUS_BOUNDS_ERROR);
ensure(get_test_name() + " failed",
empty == entry1.getWhiteList() &&
empty == entry2.getWhiteList());
}
// Whitelist check tests
// Check the "empty whitelist" case
template<> template<>
void object::test<12>() { whitelist_test("", "http://www.example.com", true); }
// Check the "missing scheme" case
template<> template<>
void object::test<13>() { whitelist_test("www.example.com", "http://www.example.com", true); }
// Check the "exactly the same" case
template<> template<>
void object::test<14>() { whitelist_test("http://example.com", "http://example.com", true); }
// Check the enable flag
template<> template<>
void object::test<15>() { whitelist_test(false, "www.example.com", "http://www.secondlife.com", true); }
template<> template<>
void object::test<16>() { whitelist_test(true, "www.example.com", "http://www.secondlife.com", false); }
// Check permutations of trailing slash:
template<> template<>
void object::test<17>() { whitelist_test("http://www.example.com", "http://www.example.com/", true); }
template<> template<>
void object::test<18>() { whitelist_test("http://www.example.com/", "http://www.example.com/", true); }
template<> template<>
void object::test<19>() { whitelist_test("http://www.example.com/", "http://www.example.com", false); }
template<> template<>
void object::test<20>() { whitelist_test("http://www.example.com", "http://www.example.com/foobar", true); }
template<> template<>
void object::test<21>() { whitelist_test("http://www.example.com/", "http://www.example.com/foobar", false); }
// More cases...
template<> template<>
void object::test<22>() { whitelist_test("http://example.com", "http://example.com/wiki", true); }
template<> template<>
void object::test<23>() { whitelist_test("www.example.com", "http://www.example.com/help", true); }
template<> template<>
void object::test<24>() { whitelist_test("http://www.example.com", "http://wwwexample.com", false); }
template<> template<>
void object::test<25>() { whitelist_test("http://www.example.com", "http://www.example.com/wiki", true); }
template<> template<>
void object::test<26>() { whitelist_test("example.com", "http://wwwexample.com", false); }
template<> template<>
void object::test<27>() { whitelist_test("http://www.example.com/", "http://www.amazon.com/wiki", false); }
template<> template<>
void object::test<28>() { whitelist_test("www.example.com", "http://www.amazon.com", false); }
// regexp cases
template<> template<>
void object::test<29>() { whitelist_test("*.example.com", "http://www.example.com", true); }
template<> template<>
void object::test<30>() { whitelist_test("*.example.com", "http://www.amazon.com", false); }
template<> template<>
void object::test<31>() { whitelist_test("*.example.com", "http://www.example.com/foo/bar", true); }
template<> template<>
void object::test<32>() { whitelist_test("*.example.com", "http:/example.com/foo/bar", false); }
template<> template<>
void object::test<33>() { whitelist_test("*example.com", "http://example.com/foo/bar", true); }
template<> template<>
void object::test<34>() { whitelist_test("*example.com", "http://my.virus.com/foo/bar?example.com", false); }
template<> template<>
void object::test<35>() { whitelist_test("example.com", "http://my.virus.com/foo/bar?example.com", false); }
template<> template<>
void object::test<36>() { whitelist_test("*example.com", "http://my.virus.com/foo/bar?*example.com", false); }
template<> template<>
void object::test<37>() { whitelist_test("http://*example.com", "http://www.example.com", true); }
template<> template<>
void object::test<38>() { whitelist_test("http://*.example.com", "http://www.example.com", true); }
template<> template<>
void object::test<39>() { whitelist_test("http://*.e$?^.com", "http://www.e$?^.com", true); }
template<> template<>
void object::test<40>() { whitelist_test("*.example.com/foo/bar", "http://www.example.com/", false); }
template<> template<>
void object::test<41>() { whitelist_test("*.example.com/foo/bar", "http://example.com/foo/bar", false); }
template<> template<>
void object::test<42>() { whitelist_test("http://*.example.com/foo/bar", "http://www.example.com", false); }
template<> template<>
void object::test<43>() { whitelist_test("http://*.example.com", "https://www.example.com", false); }
template<> template<>
void object::test<44>() { whitelist_test("http*://*.example.com", "rtsp://www.example.com", false); }
template<> template<>
void object::test<45>() { whitelist_test("http*://*.example.com", "https://www.example.com", true); }
template<> template<>
void object::test<46>() { whitelist_test("example.com", "http://www.example.com", false); }
template<> template<>
void object::test<47>() { whitelist_test("www.example.com", "http://www.example.com:80", false); }
template<> template<>
void object::test<48>() { whitelist_test("www.example.com", "http://www.example.com", true); }
template<> template<>
void object::test<49>() { whitelist_test("www.example.com/", "http://www.example.com", false); }
template<> template<>
void object::test<50>() { whitelist_test("www.example.com/foo/bar/*", "http://www.example.com/foo/bar/baz", true); }
// Path only
template<> template<>
void object::test<51>() { whitelist_test("/foo/*/baz", "http://www.example.com/foo/bar/baz", true); }
template<> template<>
void object::test<52>() { whitelist_test("/foo/*/baz", "http://www.example.com/foo/bar/", false); }
}

View File

@ -383,7 +383,7 @@ BOOL LLDir_Linux::fileExists(const std::string &filename) const
/*virtual*/ std::string LLDir_Linux::getLLPluginLauncher()
{
return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() +
"SLPlugin";
}

View File

@ -424,7 +424,7 @@ BOOL LLDir_Mac::fileExists(const std::string &filename) const
/*virtual*/ std::string LLDir_Mac::getLLPluginLauncher()
{
return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
return gDirUtilp->getAppRODataDir() + gDirUtilp->getDirDelimiter() +
"SLPlugin";
}

View File

@ -397,7 +397,7 @@ BOOL LLDir_Win32::fileExists(const std::string &filename) const
/*virtual*/ std::string LLDir_Win32::getLLPluginLauncher()
{
return gDirUtilp->getLLPluginDir() + gDirUtilp->getDirDelimiter() +
return gDirUtilp->getExecutableDir() + gDirUtilp->getDirDelimiter() +
"SLPlugin.exe";
}

View File

@ -5,6 +5,7 @@ include(LLCommon)
include(LLMath)
include(LLMessage)
include(LLInventory)
include(LLPrimitive)
include(LScript)
include(FindCygwin)
@ -41,6 +42,7 @@ include_directories(
${LLMATH_INCLUDE_DIRS}
${LLMESSAGE_INCLUDE_DIRS}
${LLINVENTORY_INCLUDE_DIRS}
${LLPRIMITIVE_INCLUDE_DIRS}
${LSCRIPT_INCLUDE_DIRS}
)

View File

@ -34,6 +34,7 @@ FS (f|F)
#include "llregionflags.h"
#include "lscript_http.h"
#include "llclickaction.h"
#include "llmediaentry.h"
void count();
void line_comment();
@ -233,7 +234,8 @@ extern "C" { int yyerror(const char *fmt, ...); }
"CHANGED_OWNER" { count(); yylval.ival = CHANGED_OWNER; return(INTEGER_CONSTANT); }
"CHANGED_REGION" { count(); yylval.ival = CHANGED_REGION; return(INTEGER_CONSTANT); }
"CHANGED_TELEPORT" { count(); yylval.ival = CHANGED_TELEPORT; return(INTEGER_CONSTANT); }
"CHANGED_REGION_START" { count(); yylval.ival = CHANGED_REGION_START; return(INTEGER_CONSTANT); }
"CHANGED_REGION_START" { count(); yylval.ival = CHANGED_REGION_START; return(INTEGER_CONSTANT); }
"CHANGED_MEDIA" { count(); yylval.ival = CHANGED_MEDIA; return(INTEGER_CONSTANT); }
"OBJECT_UNKNOWN_DETAIL" { count(); yylval.ival = OBJECT_UNKNOWN_DETAIL; return(INTEGER_CONSTANT); }
"OBJECT_NAME" { count(); yylval.ival = OBJECT_NAME; return(INTEGER_CONSTANT); }
@ -622,6 +624,45 @@ extern "C" { int yyerror(const char *fmt, ...); }
"TOUCH_INVALID_VECTOR" { count(); return(TOUCH_INVALID_VECTOR); }
"TOUCH_INVALID_TEXCOORD" { count(); return(TOUCH_INVALID_TEXCOORD); }
"PRIM_MEDIA_ALT_IMAGE_ENABLE" { count(); yylval.ival = LLMediaEntry::ALT_IMAGE_ENABLE_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_CONTROLS" { count(); yylval.ival = LLMediaEntry::CONTROLS_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_CURRENT_URL" { count(); yylval.ival = LLMediaEntry::CURRENT_URL_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_HOME_URL" { count(); yylval.ival = LLMediaEntry::HOME_URL_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_AUTO_LOOP" { count(); yylval.ival = LLMediaEntry::AUTO_LOOP_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_AUTO_PLAY" { count(); yylval.ival = LLMediaEntry::AUTO_PLAY_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_AUTO_SCALE" { count(); yylval.ival = LLMediaEntry::AUTO_SCALE_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_AUTO_ZOOM" { count(); yylval.ival = LLMediaEntry::AUTO_ZOOM_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_FIRST_CLICK_INTERACT" { count(); yylval.ival = LLMediaEntry::FIRST_CLICK_INTERACT_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_WIDTH_PIXELS" { count(); yylval.ival = LLMediaEntry::WIDTH_PIXELS_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_HEIGHT_PIXELS" { count(); yylval.ival = LLMediaEntry::HEIGHT_PIXELS_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_WHITELIST_ENABLE" { count(); yylval.ival = LLMediaEntry::WHITELIST_ENABLE_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_WHITELIST" { count(); yylval.ival = LLMediaEntry::WHITELIST_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PERMS_INTERACT" { count(); yylval.ival = LLMediaEntry::PERMS_INTERACT_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PERMS_CONTROL" { count(); yylval.ival = LLMediaEntry::PERMS_CONTROL_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PARAM_MAX" { count(); yylval.ival = LLMediaEntry::PARAM_MAX_ID; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_CONTROLS_STANDARD" { count(); yylval.ival = LLMediaEntry::STANDARD; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_CONTROLS_MINI" { count(); yylval.ival = LLMediaEntry::MINI; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PERM_NONE" { count(); yylval.ival = LLMediaEntry::PERM_NONE; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PERM_OWNER" { count(); yylval.ival = LLMediaEntry::PERM_OWNER; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PERM_GROUP" { count(); yylval.ival = LLMediaEntry::PERM_GROUP; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_PERM_ANYONE" { count(); yylval.ival = LLMediaEntry::PERM_ANYONE; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_MAX_URL_LENGTH" { count(); yylval.ival = LLMediaEntry::MAX_URL_LENGTH; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_MAX_WHITELIST_SIZE" { count(); yylval.ival = LLMediaEntry::MAX_WHITELIST_SIZE; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_MAX_WHITELIST_COUNT" { count(); yylval.ival = LLMediaEntry::MAX_WHITELIST_COUNT; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_MAX_WIDTH_PIXELS" { count(); yylval.ival = LLMediaEntry::MAX_WIDTH_PIXELS; return(INTEGER_CONSTANT); }
"PRIM_MEDIA_MAX_HEIGHT_PIXELS" { count(); yylval.ival = LLMediaEntry::MAX_HEIGHT_PIXELS; return(INTEGER_CONSTANT); }
"STATUS_OK" { count(); yylval.ival = LSL_STATUS_OK; return(INTEGER_CONSTANT); }
"STATUS_MALFORMED_PARAMS" { count(); yylval.ival = LSL_STATUS_MALFORMED_PARAMS; return(INTEGER_CONSTANT); }
"STATUS_TYPE_MISMATCH" { count(); yylval.ival = LSL_STATUS_TYPE_MISMATCH; return(INTEGER_CONSTANT); }
"STATUS_BOUNDS_ERROR" { count(); yylval.ival = LSL_STATUS_BOUNDS_ERROR; return(INTEGER_CONSTANT); }
"STATUS_NOT_FOUND" { count(); yylval.ival = LSL_STATUS_NOT_FOUND; return(INTEGER_CONSTANT); }
"STATUS_NOT_SUPPORTED" { count(); yylval.ival = LSL_STATUS_NOT_SUPPORTED; return(INTEGER_CONSTANT); }
"STATUS_INTERNAL_ERROR" { count(); yylval.ival = LSL_STATUS_INTERNAL_ERROR; return(INTEGER_CONSTANT); }
"STATUS_WHITELIST_FAILED" { count(); yylval.ival = LSL_STATUS_WHITELIST_FAILED; return(INTEGER_CONSTANT); }
{L}({L}|{N})* { count(); yylval.sval = new char[strlen(yytext) + 1]; strcpy(yylval.sval, yytext); return(IDENTIFIER); }

View File

@ -450,7 +450,12 @@ void LLScriptLibrary::init()
addFunction(10.f, 0.f, dummy_func, "llHTTPResponse", NULL, "kis");
addFunction(10.f, 0.f, dummy_func, "llGetHTTPHeader", "s", "ks");
// energy, sleep, dummy_func, name, return type, parameters, gods-only
// Prim media (see lscript_prim_media.h)
addFunction(10.f, 1.0f, dummy_func, "llSetPrimMediaParams", "i", "il");
addFunction(10.f, 1.0f, dummy_func, "llGetPrimMediaParams", "l", "il");
addFunction(10.f, 1.0f, dummy_func, "llClearPrimMedia", "i", "i");
// energy, sleep, dummy_func, name, return type, parameters, help text, gods-only
// IF YOU ADD NEW SCRIPT CALLS, YOU MUST PUT THEM AT THE END OF THIS LIST.
// Otherwise the bytecode numbers for each call will be wrong, and all
@ -495,7 +500,7 @@ void LLScriptLibData::print(std::ostream &s, BOOL b_prepend_comma)
s << ", ";
}
switch (mType)
{
{
case LST_INTEGER:
s << mInteger;
break;

View File

@ -975,10 +975,7 @@ void MediaPluginGStreamer010::receiveMessage(const char *message_string)
else if(message_name == "shm_added")
{
SharedSegmentInfo info;
U64 address_lo = message_in.getValueU32("address");
U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
info.mAddress = (void*)((address_lo) |
(address_hi * (U64(1)<<31)));
info.mAddress = message_in.getValuePointer("address");
info.mSize = (size_t)message_in.getValueS32("size");
std::string name = message_in.getValue("name");

View File

@ -772,10 +772,7 @@ void MediaPluginQuickTime::receiveMessage(const char *message_string)
else if(message_name == "shm_added")
{
SharedSegmentInfo info;
U64 address_lo = message_in.getValueU32("address");
U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
info.mAddress = (void*)((address_lo) |
(address_hi * (U64(1)<<31)));
info.mAddress = message_in.getValuePointer("address");
info.mSize = (size_t)message_in.getValueS32("size");
std::string name = message_in.getValue("name");

View File

@ -147,8 +147,11 @@ private:
#if LL_WINDOWS
// Enable plugins
LLQtWebKit::getInstance()->enablePlugins(true);
#else
LLQtWebKit::getInstance()->enablePlugins(false);
#elif LL_DARWIN
// Disable plugins
LLQtWebKit::getInstance()->enablePlugins(false);
#elif LL_LINUX
// Disable plugins
LLQtWebKit::getInstance()->enablePlugins(false);
#endif
@ -164,6 +167,11 @@ private:
// don't flip bitmap
LLQtWebKit::getInstance()->flipWindow( mBrowserWindowId, true );
// Set the background color to black
LLQtWebKit::getInstance()->
// set background color to be black - mostly for initial login page
LLQtWebKit::getInstance()->setBackgroundColor( mBrowserWindowId, 0x00, 0x00, 0x00 );
// go to the "home page"
// Don't do this here -- it causes the dreaded "white flash" when loading a browser instance.
@ -483,8 +491,8 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
mDepth = 4;
message.setMessage(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
message.setValueS32("default_width", 800);
message.setValueS32("default_height", 600);
message.setValueS32("default_width", 1024);
message.setValueS32("default_height", 1024);
message.setValueS32("depth", mDepth);
message.setValueU32("internalformat", GL_RGBA);
message.setValueU32("format", GL_RGBA);
@ -507,10 +515,7 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
else if(message_name == "shm_added")
{
SharedSegmentInfo info;
U64 address_lo = message_in.getValueU32("address");
U64 address_hi = message_in.hasValue("address_1") ? message_in.getValueU32("address_1") : 0;
info.mAddress = (void*)((address_lo) |
(address_hi * (U64(1)<<31)));
info.mAddress = message_in.getValuePointer("address");
info.mSize = (size_t)message_in.getValueS32("size");
std::string name = message_in.getValue("name");

View File

@ -171,6 +171,7 @@ set(viewer_SOURCE_FILES
llfloaterhardwaresettings.cpp
llfloaterhelpbrowser.cpp
llfloatermediabrowser.cpp
llfloatermediasettings.cpp
llfloaterhud.cpp
llfloaterimagepreview.cpp
llfloaterinspect.cpp
@ -207,6 +208,7 @@ set(viewer_SOURCE_FILES
llfloaterurlentry.cpp
llfloatervoicedevicesettings.cpp
llfloaterwater.cpp
llfloaterwhitelistentry.cpp
llfloaterwindlight.cpp
llfloaterworldmap.cpp
llfoldertype.cpp
@ -259,6 +261,9 @@ set(viewer_SOURCE_FILES
llmanipscale.cpp
llmaniptranslate.cpp
llmapresponders.cpp
llmediactrl.cpp
llmediadataresponder.cpp
llmediadatafetcher.cpp
llmediaremotectrl.cpp
llmemoryview.cpp
llmenucommands.cpp
@ -320,6 +325,9 @@ set(viewer_SOURCE_FILES
llpanelmediahud.cpp
llpanelmeprofile.cpp
llpanelmovetip.cpp
llpanelmediasettingsgeneral.cpp
llpanelmediasettingssecurity.cpp
llpanelmediasettingspermissions.cpp
llpanelobject.cpp
llpanelpeople.cpp
llpanelpeoplemenus.cpp
@ -491,7 +499,6 @@ set(viewer_SOURCE_FILES
llwearabledictionary.cpp
llwearablelist.cpp
llweb.cpp
llmediactrl.cpp
llwind.cpp
llwlanimator.cpp
llwldaycycle.cpp
@ -635,6 +642,7 @@ set(viewer_HEADER_FILES
llfloaterhardwaresettings.h
llfloaterhelpbrowser.h
llfloatermediabrowser.h
llfloatermediasettings.h
llfloaterhud.h
llfloaterimagepreview.h
llfloaterinspect.h
@ -671,6 +679,7 @@ set(viewer_HEADER_FILES
llfloaterurlentry.h
llfloatervoicedevicesettings.h
llfloaterwater.h
llfloaterwhitelistentry.h
llfloaterwindlight.h
llfloaterworldmap.h
llfoldertype.h
@ -723,6 +732,8 @@ set(viewer_HEADER_FILES
llmanipscale.h
llmaniptranslate.h
llmapresponders.h
llmediadataresponder.h
llmediadatafetcher.h
llmediaremotectrl.h
llmemoryview.h
llmenucommands.h
@ -781,6 +792,9 @@ set(viewer_HEADER_FILES
llpanelmediahud.h
llpanelmeprofile.h
llpanelmovetip.h
llpanelmediasettingsgeneral.h
llpanelmediasettingssecurity.h
llpanelmediasettingspermissions.h
llpanelobject.h
llpanelpeople.h
llpanelpeoplemenus.h
@ -1566,7 +1580,7 @@ if (WINDOWS)
-E
copy_if_different
${BUILT_SLPLUGIN}
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llplugin
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
COMMENT "Copying SLPlugin executable to the runtime folder."
)

View File

@ -47,7 +47,7 @@ moving_end moving_end():Triggered when task stops moving
on_rez on_rez(integer start_param):Triggered when task is rezed in from inventory or another task
object_rez object_rez(key id):Triggered when task rezes in another task
link_message link_message(integer sender_num, integer num, string str, key id):Triggered when task receives a link message via LLMessageLinked library function call
changed changed( integer change ):Triggered various event change the task:(test change with CHANGED_INVENTORY, CHANGED_COLOR, CHANGED_SHAPE, CHANGED_SCALE, CHANGED_TEXTURE, CHANGED_LINK, CHANGED_ALLOWED_DROP, CHANGED_OWNER, CHANGED_REGION, CHANGED_TELEPORT)
changed changed( integer change ):Triggered various event change the task:(test change with CHANGED_INVENTORY, CHANGED_COLOR, CHANGED_SHAPE, CHANGED_SCALE, CHANGED_TEXTURE, CHANGED_LINK, CHANGED_ALLOWED_DROP, CHANGED_OWNER, CHANGED_REGION, CHANGED_TELEPORT, CHANGED_REGION_START, CHANGED_MEDIA)
remote_data remote_data(integer event_type, key channel, key message_id, string sender,integer idata, string sdata):Triggered by various XML-RPC calls (event_type will be one of REMOTE_DATA_CHANNEL, REMOTE_DATA_REQUEST, REMOTE_DATA_REPLY)
http_response http_response(key request_id, integer status, list metadata, string body):Triggered when task receives a response to one of its llHTTPRequests
http_request http_request(key id, string method, string body):Triggered when task receives an http request against a public URL
@ -320,6 +320,7 @@ CHANGED_OWNER Parameter of changed event handler used to indicate change to tas
CHANGED_REGION Parameter of changed event handler used to indicate the region has changed
CHANGED_TELEPORT Parameter of changed event handler used to indicate teleport has completed
CHANGED_REGION_START Parameter of changed event handler used to indicate the region has been restarted
CHANGED_MEDIA Parameter of changed event handler used to indicate that media has changed on a face of the task
TYPE_INTEGER Indicates that the list entry is holding an integer
TYPE_FLOAT Indicates that the list entry is holding an float
@ -513,6 +514,46 @@ TOUCH_INVALID_TEXCOORD Value returned by llDetectedTouchUV() and llDetectedTouc
TOUCH_INVALID_VECTOR Value returned by llDetectedTouchPos(), llDetectedTouchNormal(), and llDetectedTouchBinormal() when the touch position is not valid.
TOUCH_INVALID_FACE Value returned by llDetectedTouchFace() when the touch position is not valid.
PRIM_MEDIA_ALT_IMAGE_ENABLE Used with ll{Get,Set}PrimMediaParams to enable the default alt image for media
PRIM_MEDIA_CONTROLS Used with ll{Get,Set}PrimMediaParams to determine the controls shown for media
PRIM_MEDIA_CURRENT_URL Used with ll{Get,Set}PrimMediaParams to navigate/access the current URL
PRIM_MEDIA_HOME_URL Used with ll{Get,Set}PrimMediaParams to access the home URL
PRIM_MEDIA_AUTO_LOOP Used with ll{Get,Set}PrimMediaParams to determine if media should auto-loop (if applicable)
PRIM_MEDIA_AUTO_PLAY Used with ll{Get,Set}PrimMediaParams to determine if media should start playing as soon as it is created
PRIM_MEDIA_AUTO_SCALE Used with ll{Get,Set}PrimMediaParams to determine if media should scale to fit the face it is on
PRIM_MEDIA_AUTO_ZOOM Used with ll{Get,Set}PrimMediaParams to determine if the user would zoom in when viewing media
PRIM_MEDIA_FIRST_CLICK_INTERACT Used with ll{Get,Set}PrimMediaParams to determine whether the user interacts with media or not when she first clicks it (versus selection)
PRIM_MEDIA_WIDTH_PIXELS Used with ll{Get,Set}PrimMediaParams to access the media's width in pixels
PRIM_MEDIA_HEIGHT_PIXELS Used with ll{Get,Set}PrimMediaParams to access the media's height in pixels
PRIM_MEDIA_WHITELIST_ENABLE Used with ll{Get,Set}PrimMediaParams to determine if the domain whitelist is enabled
PRIM_MEDIA_WHITELIST Used with ll{Get,Set}PrimMediaParams to access the media's list of allowable URL prefixes to navigate to
PRIM_MEDIA_PERMS_INTERACT Used with ll{Get,Set}PrimMediaParams to determine the permissions for who can interact with the media
PRIM_MEDIA_PERMS_CONTROL Used with ll{Get,Set}PrimMediaParams to determine the permissions for who has controls
PRIM_MEDIA_PARAM_MAX The value of the largest media param
PRIM_MEDIA_CONTROLS_STANDARD Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_CONTROLS value meaning "standard controls"
PRIM_MEDIA_CONTROLS_MINI Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_CONTROLS value meaning "mini controls"
PRIM_MEDIA_PERM_NONE Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, no permissions
PRIM_MEDIA_PERM_OWNER Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, owner permissions
PRIM_MEDIA_PERM_GROUP Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, group permissions
PRIM_MEDIA_PERM_ANYONE Used with ll{Get,Set}PrimMediaParams, a PRIM_MEDIA_PERMS_INTERACT or PRIM_MEDIA_PERMS_CONTROL bit, anyone has permissions
PRIM_MEDIA_MAX_URL_LENGTH Used with ll{Get,Set}PrimMediaParams, the maximum length of PRIM_MEDIA_CURRENT_URL or PRIM_MEDIA_HOME_URL
PRIM_MEDIA_MAX_WHITELIST_SIZE Used with ll{Get,Set}PrimMediaParams, the maximum length, in bytes, of PRIM_MEDIA_WHITELIST
PRIM_MEDIA_MAX_WHITELIST_COUNT Used with ll{Get,Set}PrimMediaParams, the maximum number of items allowed in PRIM_MEDIA_WHITELIST
PRIM_MEDIA_MAX_WIDTH_PIXELS Used with ll{Get,Set}PrimMediaParams, the maximum width allowed in PRIM_MEDIA_WIDTH_PIXELS
PRIM_MEDIA_MAX_HEIGHT_PIXELS Used with ll{Get,Set}PrimMediaParams, the maximum width allowed in PRIM_MEDIA_HEIGHT_PIXELS
STATUS_OK Result of function call was success
STATUS_MALFORMED_PARAMS Function was called with malformed params
STATUS_TYPE_MISMATCH Argument(s) passed to function had a type mismatch
STATUS_BOUNDS_ERROR Argument(s) passed to function had a bounds error
STATUS_NOT_FOUND Object or other item was not found
STATUS_NOT_SUPPORTED Feature not supported
STATUS_INTERNAL_ERROR An internal error occurred
STATUS_WHITELIST_FAILED URL failed to pass whitelist
# string constants
[word .1, .3, .5]
NULL_KEY Indicates an empty key

View File

@ -3994,6 +3994,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>LastMediaSettingsTab</key>
<map>
<key>Comment</key>
<string>Last selected tab in media settings window</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>S32</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>LastRunVersion</key>
<map>
<key>Comment</key>
@ -4455,7 +4466,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
<integer>1</integer>
</map>
<key>MemoryLogFrequency</key>
<map>
@ -5216,6 +5227,51 @@
<key>Value</key>
<integer>1</integer>
</map>
<key>PluginInstancesCPULimit</key>
<map>
<key>Comment</key>
<string>Amount of total plugin CPU usage before inworld plugins start getting turned down to "slideshow" priority. Set to 0 to disable this check.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>0.0</real>
</map>
<key>PluginInstancesLow</key>
<map>
<key>Comment</key>
<string>Limit on the number of inworld media plugins that will run at "low" priority</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>4</integer>
</map>
<key>PluginInstancesNormal</key>
<map>
<key>Comment</key>
<string>Limit on the number of inworld media plugins that will run at "normal" priority</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>4</integer>
</map>
<key>PluginInstancesTotal</key>
<map>
<key>Comment</key>
<string>Hard limit on the number of plugins that will be instantiated at once</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
<integer>16</integer>
</map>
<key>PrecachingDelay</key>
<map>
<key>Comment</key>
@ -5238,6 +5294,28 @@
<key>Value</key>
<integer>13</integer>
</map>
<key>PrimMediaFetchQueueDelay</key>
<map>
<key>Comment</key>
<string>Timer delay for fetching media from the queue (in seconds).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>1.0</real>
</map>
<key>PrimMediaRetryTimerDelay</key>
<map>
<key>Comment</key>
<string>Timer delay for retrying on media queries (in seconds).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
<real>5.0</real>
</map>
<key>ProbeHardwareOnStartup</key>
<map>
<key>Comment</key>

View File

@ -960,6 +960,30 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
return retval;
}
const S32 MIN_VIS_FRAME_RANGE = 2 ; //two frames:the current one and the last one.
//static
S32 LLDrawable::getMinVisFrameRange()
{
return MIN_VIS_FRAME_RANGE ;
}
BOOL LLDrawable::isRecentlyVisible() const
{
//currently visible or visible in the previous frame.
BOOL vis = isVisible() || (sCurVisible - mVisible < MIN_VIS_FRAME_RANGE) ;
if(!vis)
{
LLSpatialGroup* group = getSpatialGroup();
if (group && group->isRecentlyVisible())
{
mVisible = sCurVisible;
vis = TRUE ;
}
}
return vis ;
}
BOOL LLDrawable::isVisible() const
{

View File

@ -78,7 +78,8 @@ public:
BOOL isLight() const;
BOOL isVisible() const;
BOOL isVisible() const;
BOOL isRecentlyVisible() const;
virtual void setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results = NULL, BOOL for_select = FALSE);
@ -278,7 +279,8 @@ public:
S32 mQuietCount;
static S32 getCurrentFrame() { return sCurVisible; }
static S32 getMinVisFrameRange();
void setSpatialBridge(LLSpatialBridge* bridge) { mSpatialBridge = (LLDrawable*) bridge; }
LLSpatialBridge* getSpatialBridge() { return (LLSpatialBridge*) (LLDrawable*) mSpatialBridge; }

View File

@ -270,16 +270,34 @@ void LLFace::setTexture(LLViewerTexture* tex)
{
mTexture->removeFace(this) ;
removeAtlas() ;
}
}
mTexture = tex ;
if(mTexture.notNull())
{
mTexture->addFace(this) ;
}
}
void LLFace::switchTexture(LLViewerTexture* new_texture)
{
if(mTexture == new_texture)
{
return ;
}
if(!new_texture)
{
llerrs << "Can not switch to a null texture." << llendl ;
}
new_texture->addTextureStats(mTexture->getMaxVirtualSize()) ;
getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
setTexture(new_texture) ;
gPipeline.markTextured(getDrawable());
}
void LLFace::setTEOffset(const S32 te_offset)
{
mTEOffset = te_offset;

View File

@ -89,6 +89,7 @@ public:
U16 getGeomIndex() const { return mGeomIndex; } // index into draw pool
U16 getGeomStart() const { return mGeomIndex; } // index into draw pool
void setTexture(LLViewerTexture* tex) ;
void switchTexture(LLViewerTexture* new_texture);
LLXformMatrix* getXform() const { return mXform; }
BOOL hasGeometry() const { return mGeomCount > 0; }
LLVector3 getPositionAgent() const;

View File

@ -146,7 +146,10 @@ void LLFloaterMediaBrowser::buildURLHistory()
}
// initialize URL history in the plugin
mBrowser->getMediaPlugin()->initializeUrlHistory(browser_history);
if(mBrowser && mBrowser->getMediaPlugin())
{
mBrowser->getMediaPlugin()->initializeUrlHistory(browser_history);
}
}
std::string LLFloaterMediaBrowser::getSupportURL()

View File

@ -0,0 +1,249 @@
/**
* @file llfloatermediasettings.cpp
* @brief Tabbed dialog for media settings - class implementation
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterreg.h"
#include "llfloatermediasettings.h"
#include "llpanelmediasettingsgeneral.h"
#include "llpanelmediasettingssecurity.h"
#include "llpanelmediasettingspermissions.h"
#include "llviewercontrol.h"
#include "lluictrlfactory.h"
#include "llbutton.h"
#include "llselectmgr.h"
LLFloaterMediaSettings* LLFloaterMediaSettings::sInstance = NULL;
////////////////////////////////////////////////////////////////////////////////
//
LLFloaterMediaSettings::LLFloaterMediaSettings(const LLSD& key)
: LLFloater(key),
mTabContainer(NULL),
mPanelMediaSettingsGeneral(NULL),
mPanelMediaSettingsSecurity(NULL),
mPanelMediaSettingsPermissions(NULL),
mWaitingToClose( false )
{
// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_media_settings.xml");
}
////////////////////////////////////////////////////////////////////////////////
//
LLFloaterMediaSettings::~LLFloaterMediaSettings()
{
if ( mPanelMediaSettingsGeneral )
{
delete mPanelMediaSettingsGeneral;
mPanelMediaSettingsGeneral = NULL;
}
if ( mPanelMediaSettingsSecurity )
{
delete mPanelMediaSettingsSecurity;
mPanelMediaSettingsSecurity = NULL;
}
if ( mPanelMediaSettingsPermissions )
{
delete mPanelMediaSettingsPermissions;
mPanelMediaSettingsPermissions = NULL;
}
sInstance = NULL;
}
////////////////////////////////////////////////////////////////////////////////
//
BOOL LLFloaterMediaSettings::postBuild()
{
mCloseSignal.connect(boost::bind(&LLFloaterMediaSettings::onClose, this));
mApplyBtn = getChild<LLButton>("Apply");
mApplyBtn->setClickedCallback(onBtnApply, this);
mCancelBtn = getChild<LLButton>("Cancel");
mCancelBtn->setClickedCallback(onBtnCancel, this);
mOKBtn = getChild<LLButton>("OK");
mOKBtn->setClickedCallback(onBtnOK, this);
mTabContainer = getChild<LLTabContainer>( "tab_container" );
mPanelMediaSettingsGeneral = new LLPanelMediaSettingsGeneral();
mTabContainer->addTabPanel(
LLTabContainer::TabPanelParams().
panel(mPanelMediaSettingsGeneral));
mPanelMediaSettingsGeneral->setParent( this );
// note that "permissions" tab is really "Controls" tab - refs to 'perms' and
// 'permissions' not changed to 'controls' since we don't want to change
// shared files in server code and keeping everything the same seemed best.
mPanelMediaSettingsPermissions = new LLPanelMediaSettingsPermissions();
mTabContainer->addTabPanel(
LLTabContainer::TabPanelParams().
panel(mPanelMediaSettingsPermissions));
mPanelMediaSettingsSecurity = new LLPanelMediaSettingsSecurity();
mTabContainer->addTabPanel(
LLTabContainer::TabPanelParams().
panel(mPanelMediaSettingsSecurity));
// restore the last tab viewed from persistance variable storage
if (!mTabContainer->selectTab(gSavedSettings.getS32("LastMediaSettingsTab")))
{
mTabContainer->selectFirstTab();
};
sInstance = this;
return TRUE;
}
//static
LLFloaterMediaSettings* LLFloaterMediaSettings::getInstance()
{
if ( !sInstance )
{
sInstance = (LLFloaterReg::getTypedInstance<LLFloaterMediaSettings>("media_settings"));
}
return sInstance;
}
//static
void LLFloaterMediaSettings::apply()
{
LLSD settings;
sInstance->mPanelMediaSettingsGeneral->getValues( settings );
sInstance->mPanelMediaSettingsSecurity->getValues( settings );
sInstance->mPanelMediaSettingsPermissions->getValues( settings );
LLSelectMgr::getInstance()->selectionSetMedia( LLTextureEntry::MF_HAS_MEDIA );
LLSelectMgr::getInstance()->selectionSetMediaData(settings);
}
////////////////////////////////////////////////////////////////////////////////
void LLFloaterMediaSettings::onClose()
{
if(mPanelMediaSettingsGeneral)
{
mPanelMediaSettingsGeneral->onClose();
}
LLFloaterReg::hideInstance("whitelist_entry");
}
////////////////////////////////////////////////////////////////////////////////
//static
void LLFloaterMediaSettings::initValues( const LLSD& media_settings )
{
sInstance->clearValues();
// update all panels with values from simulator
sInstance->mPanelMediaSettingsGeneral->
initValues( sInstance->mPanelMediaSettingsGeneral, media_settings );
sInstance->mPanelMediaSettingsSecurity->
initValues( sInstance->mPanelMediaSettingsSecurity, media_settings );
sInstance->mPanelMediaSettingsPermissions->
initValues( sInstance->mPanelMediaSettingsPermissions, media_settings );
}
////////////////////////////////////////////////////////////////////////////////
//
void LLFloaterMediaSettings::commitFields()
{
if (hasFocus())
{
LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
if (cur_focus->acceptsTextInput())
{
cur_focus->onCommit();
};
};
}
////////////////////////////////////////////////////////////////////////////////
//static
void LLFloaterMediaSettings::clearValues()
{
// clean up all panels before updating
sInstance->mPanelMediaSettingsGeneral->clearValues(sInstance->mPanelMediaSettingsGeneral);
sInstance->mPanelMediaSettingsSecurity->clearValues(sInstance->mPanelMediaSettingsSecurity);
sInstance->mPanelMediaSettingsPermissions->clearValues(sInstance->mPanelMediaSettingsPermissions);
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLFloaterMediaSettings::onBtnOK( void* userdata )
{
sInstance->commitFields();
sInstance->apply();
sInstance->closeFloater();
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLFloaterMediaSettings::onBtnApply( void* userdata )
{
sInstance->commitFields();
sInstance->apply();
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLFloaterMediaSettings::onBtnCancel( void* userdata )
{
sInstance->closeFloater();
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLFloaterMediaSettings::onTabChanged(void* user_data, bool from_click)
{
LLTabContainer* self = (LLTabContainer*)user_data;
gSavedSettings.setS32("LastMediaSettingsTab", self->getCurrentPanelIndex());
}
////////////////////////////////////////////////////////////////////////////////
//
void LLFloaterMediaSettings::enableOkApplyBtns( bool enable )
{
setCtrlsEnabled( enable );
childSetEnabled( "OK", enable );
childSetEnabled( "Apply", enable );
}

View File

@ -0,0 +1,81 @@
/**
* @file llfloatermediasettings.cpp
* @brief Tabbed dialog for media settings - class definition
*
* $LicenseInfo:firstyear=2002&license=viewergpl$
*
* Copyright (c) 2002-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERMEDIASETTINGS_H
#define LL_LLFLOATERMEDIASETTINGS_H
#include "llfloater.h"
#include "lltabcontainer.h"
class LLPanelMediaSettingsGeneral;
class LLPanelMediaSettingsSecurity;
class LLPanelMediaSettingsPermissions;
class LLFloaterMediaSettings :
public LLFloater
{
public:
LLFloaterMediaSettings(const LLSD& key);
~LLFloaterMediaSettings();
virtual BOOL postBuild();
static LLFloaterMediaSettings* getInstance();
static void apply();
static void initValues( const LLSD& media_settings );
static void clearValues();
void enableOkApplyBtns( bool enable );
LLPanelMediaSettingsSecurity* getPanelSecurity(){return mPanelMediaSettingsSecurity;};
protected:
LLButton *mOKBtn;
LLButton *mCancelBtn;
LLButton *mApplyBtn;
LLTabContainer *mTabContainer;
LLPanelMediaSettingsGeneral* mPanelMediaSettingsGeneral;
LLPanelMediaSettingsSecurity* mPanelMediaSettingsSecurity;
LLPanelMediaSettingsPermissions* mPanelMediaSettingsPermissions;
void onClose();
static void onBtnOK(void*);
static void onBtnCancel(void*);
static void onBtnApply(void*);
static void onTabChanged(void* user_data, bool from_click);
void commitFields();
static LLFloaterMediaSettings* sInstance;
private:
bool mWaitingToClose;
};
#endif // LL_LLFLOATERMEDIASETTINGS_H

View File

@ -195,8 +195,8 @@ void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator);
viewer_media_t get_web_media()
{
viewer_media_t media_source = LLViewerMedia::newMediaImpl("", LLUUID::null, 0, 0, 0, 0, "text/html");
viewer_media_t media_source = LLViewerMedia::newMediaImpl(LLUUID::null);
media_source->initializeMedia("text/html");
return media_source;
}

View File

@ -44,9 +44,11 @@
#include "llcombobox.h"
#include "lldraghandle.h"
#include "llfloaterbuildoptions.h"
#include "llfloatermediasettings.h"
#include "llfloateropenobject.h"
#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llmediaentry.h"
#include "llmenugl.h"
#include "llpanelcontents.h"
#include "llpanelface.h"
@ -97,7 +99,7 @@ const std::string PANEL_NAMES[LLFloaterTools::PANEL_COUNT] =
};
// Local prototypes
void commit_select_component(LLUICtrl *ctrl, void *data);
void commit_select_component(void *data);
void click_show_more(void*);
void click_popup_info(void*);
void click_popup_done(void*);
@ -105,15 +107,14 @@ void click_popup_minimize(void*);
void click_popup_rotate_left(void*);
void click_popup_rotate_reset(void*);
void click_popup_rotate_right(void*);
void commit_slider_dozer_size(LLUICtrl *, void*);
void commit_slider_dozer_force(LLUICtrl *, void*);
void commit_slider_dozer_force(LLUICtrl *);
void click_apply_to_selection(void*);
void commit_radio_group_focus(LLUICtrl* ctrl, void* data);
void commit_radio_group_move(LLUICtrl* ctrl, void* data);
void commit_radio_group_edit(LLUICtrl* ctrl, void* data);
void commit_radio_group_land(LLUICtrl* ctrl, void* data);
void commit_grid_mode(LLUICtrl *, void*);
void commit_slider_zoom(LLUICtrl *, void*);
void commit_radio_group_focus(LLUICtrl* ctrl);
void commit_radio_group_move(LLUICtrl* ctrl);
void commit_radio_group_edit(LLUICtrl* ctrl);
void commit_radio_group_land(LLUICtrl* ctrl);
void commit_grid_mode(LLUICtrl *);
void commit_slider_zoom(LLUICtrl *ctrl);
//static
@ -210,43 +211,28 @@ BOOL LLFloaterTools::postBuild()
getDragHandle()->setEnabled( !gSavedSettings.getBOOL("ToolboxAutoMove") );
LLRect rect;
mBtnFocus = getChild<LLButton>("button focus");//btn;
childSetAction("button focus",LLFloaterTools::setEditTool, (void*)LLToolCamera::getInstance());
mBtnMove = getChild<LLButton>("button move");
childSetAction("button move",LLFloaterTools::setEditTool, (void*)LLToolGrab::getInstance());
mBtnEdit = getChild<LLButton>("button edit");
childSetAction("button edit",LLFloaterTools::setEditTool, (void*)LLToolCompTranslate::getInstance());
mBtnCreate = getChild<LLButton>("button create");
childSetAction("button create",LLFloaterTools::setEditTool, (void*)LLToolCompCreate::getInstance());
mBtnLand = getChild<LLButton>("button land" );
childSetAction("button land",LLFloaterTools::setEditTool, (void*)LLToolSelectLand::getInstance());
mTextStatus = getChild<LLTextBox>("text status");
childSetCommitCallback("slider zoom",commit_slider_zoom,this);
mRadioGroupFocus = getChild<LLRadioGroup>("focus_radio_group");
childSetCommitCallback("focus_radio_group", commit_radio_group_focus, this);
mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group");
childSetCommitCallback("move_radio_group", commit_radio_group_move, this);
mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group");
childSetCommitCallback("edit_radio_group", commit_radio_group_edit, this);
mCheckSelectIndividual = getChild<LLCheckBoxCtrl>("checkbox edit linked parts");
mBtnFocus = getChild<LLButton>("button focus");//btn;
mBtnMove = getChild<LLButton>("button move");
mBtnEdit = getChild<LLButton>("button edit");
mBtnCreate = getChild<LLButton>("button create");
mBtnLand = getChild<LLButton>("button land" );
mTextStatus = getChild<LLTextBox>("text status");
mRadioGroupFocus = getChild<LLRadioGroup>("focus_radio_group");
mRadioGroupMove = getChild<LLRadioGroup>("move_radio_group");
mRadioGroupEdit = getChild<LLRadioGroup>("edit_radio_group");
mBtnGridOptions = getChild<LLButton>("Options...");
mCheckSelectIndividual = getChild<LLCheckBoxCtrl>("checkbox edit linked parts");
childSetValue("checkbox edit linked parts",(BOOL)gSavedSettings.getBOOL("EditLinkedParts"));
childSetCommitCallback("checkbox edit linked parts",commit_select_component,this);
mCheckSnapToGrid = getChild<LLCheckBoxCtrl>("checkbox snap to grid");
mCheckSnapToGrid = getChild<LLCheckBoxCtrl>("checkbox snap to grid");
childSetValue("checkbox snap to grid",(BOOL)gSavedSettings.getBOOL("SnapEnabled"));
mBtnGridOptions = getChild<LLButton>("Options...");
childSetAction("Options...",onClickGridOptions, this);
mCheckStretchUniform = getChild<LLCheckBoxCtrl>("checkbox uniform");
mCheckStretchUniform = getChild<LLCheckBoxCtrl>("checkbox uniform");
childSetValue("checkbox uniform",(BOOL)gSavedSettings.getBOOL("ScaleUniform"));
mCheckStretchTexture = getChild<LLCheckBoxCtrl>("checkbox stretch textures");
mCheckStretchTexture = getChild<LLCheckBoxCtrl>("checkbox stretch textures");
childSetValue("checkbox stretch textures",(BOOL)gSavedSettings.getBOOL("ScaleStretchTextures"));
mTextGridMode = getChild<LLTextBox>("text ruler mode");
mComboGridMode = getChild<LLComboBox>("combobox grid mode");
childSetCommitCallback("combobox grid mode",commit_grid_mode, this);
mTextGridMode = getChild<LLTextBox>("text ruler mode");
mComboGridMode = getChild<LLComboBox>("combobox grid mode");
//
// Create Buttons
//
@ -271,18 +257,11 @@ BOOL LLFloaterTools::postBuild()
mCheckCopyRotates = getChild<LLCheckBoxCtrl>("checkbox copy rotates");
childSetValue("checkbox copy rotates",(BOOL)gSavedSettings.getBOOL("CreateToolCopyRotates"));
mRadioGroupLand = getChild<LLRadioGroup>("land_radio_group");
childSetCommitCallback("land_radio_group", commit_radio_group_land, this);
mBtnApplyToSelection = getChild<LLButton>("button apply to selection");
childSetAction("button apply to selection",click_apply_to_selection, (void*)0);
mSliderDozerSize = getChild<LLSlider>("slider brush size");
childSetCommitCallback("slider brush size", commit_slider_dozer_size, (void*)0);
mRadioGroupLand = getChild<LLRadioGroup>("land_radio_group");
mBtnApplyToSelection = getChild<LLButton>("button apply to selection");
mSliderDozerSize = getChild<LLSlider>("slider brush size");
childSetValue( "slider brush size", gSavedSettings.getF32("LandBrushSize"));
mSliderDozerForce = getChild<LLSlider>("slider force");
childSetCommitCallback("slider force",commit_slider_dozer_force, (void*)0);
mSliderDozerForce = getChild<LLSlider>("slider force");
// the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here
childSetValue( "slider force", log10(gSavedSettings.getF32("LandBrushForce")));
@ -369,6 +348,22 @@ LLFloaterTools::LLFloaterTools(const LLSD& key)
mFactoryMap["land info panel"] = LLCallbackMap(createPanelLandInfo, this);//LLPanelLandInfo
//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_tools.xml",FALSE);
mCommitCallbackRegistrar.add("BuildTool.setTool", boost::bind(&LLFloaterTools::setTool,this, _2));
mCommitCallbackRegistrar.add("BuildTool.commitZoom", boost::bind(&commit_slider_zoom, _1));
mCommitCallbackRegistrar.add("BuildTool.commitRadioFocus", boost::bind(&commit_radio_group_focus, _1));
mCommitCallbackRegistrar.add("BuildTool.commitRadioMove", boost::bind(&commit_radio_group_move,_1));
mCommitCallbackRegistrar.add("BuildTool.commitRadioEdit", boost::bind(&commit_radio_group_edit,_1));
mCommitCallbackRegistrar.add("BuildTool.selectComponent", boost::bind(&commit_select_component, this));
mCommitCallbackRegistrar.add("BuildTool.gridOptions", boost::bind(&LLFloaterTools::onClickGridOptions,this));
mCommitCallbackRegistrar.add("BuildTool.applyToSelection", boost::bind(&click_apply_to_selection, this));
mCommitCallbackRegistrar.add("BuildTool.gridMode", boost::bind(&commit_grid_mode,_1));
mCommitCallbackRegistrar.add("BuildTool.commitRadioLand", boost::bind(&commit_radio_group_land,_1));
mCommitCallbackRegistrar.add("BuildTool.LandBrushForce", boost::bind(&commit_slider_dozer_force,_1));
mCommitCallbackRegistrar.add("BuildTool.AddMedia", boost::bind(&LLFloaterTools::onClickBtnAddMedia,this));
mCommitCallbackRegistrar.add("BuildTool.DeleteMedia", boost::bind(&LLFloaterTools::onClickBtnDeleteMedia,this));
mCommitCallbackRegistrar.add("BuildTool.EditMedia", boost::bind(&LLFloaterTools::onClickBtnEditMedia,this));
}
LLFloaterTools::~LLFloaterTools()
@ -427,6 +422,7 @@ void LLFloaterTools::refresh()
mPanelObject->refresh();
mPanelVolume->refresh();
mPanelFace->refresh();
refreshMedia();
mPanelContents->refresh();
mPanelLandInfo->refresh();
}
@ -756,6 +752,7 @@ void LLFloaterTools::onClose()
LLToolMgr::getInstance()->getCurrentToolset()->selectFirstTool();
//gMenuBarView->setItemVisible("BuildTools", FALSE);
LLFloaterReg::hideInstance("media_settings");
}
void click_popup_info(void*)
@ -767,7 +764,7 @@ void click_popup_done(void*)
handle_reset_view();
}
void commit_radio_group_move(LLUICtrl* ctrl, void* data)
void commit_radio_group_move(LLUICtrl* ctrl)
{
LLRadioGroup* group = (LLRadioGroup*)ctrl;
std::string selected = group->getValue().asString();
@ -788,7 +785,7 @@ void commit_radio_group_move(LLUICtrl* ctrl, void* data)
}
}
void commit_radio_group_focus(LLUICtrl* ctrl, void* data)
void commit_radio_group_focus(LLUICtrl* ctrl)
{
LLRadioGroup* group = (LLRadioGroup*)ctrl;
std::string selected = group->getValue().asString();
@ -812,7 +809,7 @@ void commit_radio_group_focus(LLUICtrl* ctrl, void* data)
}
}
void commit_slider_zoom(LLUICtrl *ctrl, void*)
void commit_slider_zoom(LLUICtrl *ctrl)
{
// renormalize value, since max "volume" level is 0.5 for some reason
F32 zoom_level = (F32)ctrl->getValue().asReal() * 2.f; // / 0.5f;
@ -837,26 +834,19 @@ void click_popup_rotate_right(void*)
dialog_refresh_all();
}
void commit_slider_dozer_size(LLUICtrl *ctrl, void*)
{
F32 size = (F32)ctrl->getValue().asReal();
gSavedSettings.setF32("LandBrushSize", size);
}
void commit_slider_dozer_force(LLUICtrl *ctrl, void*)
void commit_slider_dozer_force(LLUICtrl *ctrl)
{
// the slider is logarithmic, so we exponentiate to get the actual force multiplier
F32 dozer_force = pow(10.f, (F32)ctrl->getValue().asReal());
gSavedSettings.setF32("LandBrushForce", dozer_force);
}
void click_apply_to_selection(void* user)
void click_apply_to_selection(void*)
{
LLToolBrushLand::getInstance()->modifyLandInSelectionGlobal();
}
void commit_radio_group_edit(LLUICtrl *ctrl, void *data)
void commit_radio_group_edit(LLUICtrl *ctrl)
{
S32 show_owners = gSavedSettings.getBOOL("ShowParcelOwners");
@ -881,7 +871,7 @@ void commit_radio_group_edit(LLUICtrl *ctrl, void *data)
gSavedSettings.setBOOL("ShowParcelOwners", show_owners);
}
void commit_radio_group_land(LLUICtrl* ctrl, void* data)
void commit_radio_group_land(LLUICtrl* ctrl)
{
LLRadioGroup* group = (LLRadioGroup*)ctrl;
std::string selected = group->getValue().asString();
@ -909,7 +899,7 @@ void commit_radio_group_land(LLUICtrl* ctrl, void* data)
}
}
void commit_select_component(LLUICtrl *ctrl, void *data)
void commit_select_component(void *data)
{
LLFloaterTools* floaterp = (LLFloaterTools*)data;
@ -933,7 +923,7 @@ void commit_select_component(LLUICtrl *ctrl, void *data)
}
}
void commit_grid_mode(LLUICtrl *ctrl, void *data)
void commit_grid_mode(LLUICtrl *ctrl)
{
LLComboBox* combo = (LLComboBox*)ctrl;
@ -948,10 +938,9 @@ void LLFloaterTools::setObjectType( LLPCode pcode )
gFocusMgr.setMouseCapture(NULL);
}
// static
void LLFloaterTools::onClickGridOptions(void* data)
void LLFloaterTools::onClickGridOptions()
{
//LLFloaterTools* floaterp = (LLFloaterTools*)data;
LLFloaterReg::showInstance("build_options");
// RN: this makes grid options dependent on build tools window
//floaterp->addDependentFloater(LLFloaterBuildOptions::getInstance(), FALSE);
@ -964,8 +953,558 @@ void LLFloaterTools::setEditTool(void* tool_pointer)
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( tool );
}
void LLFloaterTools::setTool(const LLSD& user_data)
{
std::string control_name = user_data.asString();
if(control_name == "Focus")
LLToolMgr::getInstance()->getCurrentToolset()->selectTool((LLTool *) LLToolCamera::getInstance() );
else if (control_name == "Move" )
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *)LLToolGrab::getInstance() );
else if (control_name == "Edit" )
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompTranslate::getInstance());
else if (control_name == "Create" )
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolCompCreate::getInstance());
else if (control_name == "Land" )
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( (LLTool *) LLToolSelectLand::getInstance());
else
llwarns<<" no parameter name "<<control_name<<" found!! No Tool selected!!"<< llendl;
}
void LLFloaterTools::onFocusReceived()
{
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
LLFloater::onFocusReceived();
}
// Media stuff
void LLFloaterTools::refreshMedia()
{
getMediaState();
LLFloaterMediaSettings::getInstance();
LLFloaterMediaSettings::initValues(mMediaSettings );
}
void LLFloaterTools::getMediaState()
{
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
if( !objectp )
{
childSetEnabled("media_tex", FALSE);
childSetEnabled("add_media", FALSE);
childSetEnabled("delete_media", FALSE);
childSetEnabled("edit_media", FALSE);
updateMediaSettings();
return;
}
bool editable = gAgent.isGodlike() || (objectp->permModify() && objectp->getPCode() == LL_PCODE_VOLUME);
// Media settings
U8 has_media = (U8)0;
struct media_functor : public LLSelectedTEGetFunctor<U8>
{
U8 get(LLViewerObject* object, S32 face)
{
return (object->getTE(face)->getMediaTexGen());
}
} func;
bool identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, has_media );
// update UI depending on whether "object" (prim or face) has media
// and whether or not you are allowed to edit it.
bool bool_has_media = (has_media & LLTextureEntry::MF_HAS_MEDIA);
childSetEnabled("media_tex", bool_has_media & editable);
childSetEnabled( "edit_media", bool_has_media & editable );
childSetEnabled( "delete_media", bool_has_media & editable );
childSetEnabled( "add_media", ( ! bool_has_media ) & editable );
// load values for media settings
updateMediaSettings();
// if identical is set, all faces are same
if ( identical )
{
// TODO: display a list of all media on the face - use 'identical' flag
};
}
//////////////////////////////////////////////////////////////////////////////
// called when a user wants to add media to a prim or prim face
void LLFloaterTools::onClickBtnAddMedia()
{
// check for the edit tool and now many faces are selected
LLTool *tool = LLToolMgr::getInstance()->getCurrentTool();
if((tool != LLToolFace::getInstance()) || LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
{
LLNotifications::instance().add("MultipleFacesSelected",LLSD(), LLSD(), multipleFacesSelectedConfirm);
}
else
{
onClickBtnEditMedia();
}
}
// static
bool LLFloaterTools::multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
switch( option )
{
case 0: // "Yes"
gFloaterTools->onClickBtnEditMedia();
break;
case 1: // "No"
default:
break;
}
return false;
}
//////////////////////////////////////////////////////////////////////////////
// called when a user wants to edit existing media settings on a prim or prim face
// TODO: test if there is media on the item and only allow editing if present
void LLFloaterTools::onClickBtnEditMedia()
{
refreshMedia();
LLFloaterReg::showInstance("media_settings");
}
//////////////////////////////////////////////////////////////////////////////
// called when a user wants to delete media from a prim or prim face
void LLFloaterTools::onClickBtnDeleteMedia()
{
LLNotifications::instance().add("DeleteMedia", LLSD(), LLSD(), deleteMediaConfirm);
}
// static
bool LLFloaterTools::deleteMediaConfirm(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
switch( option )
{
case 0: // "Yes"
LLSelectMgr::getInstance()->selectionSetMedia( 0 );
if(LLFloaterReg::instanceVisible("media_settings"))
{
LLFloaterReg::hideInstance("media_settings");
}
break;
case 1: // "No"
default:
break;
}
return false;
}
//////////////////////////////////////////////////////////////////////////////
//
void LLFloaterTools::updateMediaSettings()
{
bool identical( false );
std::string base_key( "" );
std::string value_str( "" );
int value_int = 0;
bool value_bool = false;
LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
// TODO: (CP) refactor this using something clever or boost or both !!
LLMediaEntry default_media_data;
// controls
U8 value_u8 = default_media_data.getControls();
struct functor_getter_controls : public LLSelectedTEGetFunctor< U8 >
{
U8 get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getControls();
LLMediaEntry default_media_data;
return default_media_data.getControls();
};
} func_controls;
identical = selected_objects->getSelectedTEValue( &func_controls, value_u8 );
base_key = std::string( LLMediaEntry::CONTROLS_KEY );
mMediaSettings[ base_key ] = value_u8;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// First click (formerly left click)
value_bool = default_media_data.getFirstClickInteract();
struct functor_getter_first_click : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getFirstClickInteract();
LLMediaEntry default_media_data;
return default_media_data.getFirstClickInteract();
};
} func_first_click;
identical = selected_objects->getSelectedTEValue( &func_first_click, value_bool );
base_key = std::string( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Home URL
value_str = default_media_data.getHomeURL();
struct functor_getter_home_url : public LLSelectedTEGetFunctor< std::string >
{
std::string get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getHomeURL();
LLMediaEntry default_media_data;
return default_media_data.getHomeURL();
};
} func_home_url;
identical = selected_objects->getSelectedTEValue( &func_home_url, value_str );
base_key = std::string( LLMediaEntry::HOME_URL_KEY );
mMediaSettings[ base_key ] = value_str;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
llwarns<<"Angela debug : home url string == "<<value_str<<llendl;
// Current URL
value_str = default_media_data.getCurrentURL();
struct functor_getter_current_url : public LLSelectedTEGetFunctor< std::string >
{
std::string get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getCurrentURL();
LLMediaEntry default_media_data;
return default_media_data.getCurrentURL();
};
} func_current_url;
identical = selected_objects->getSelectedTEValue( &func_current_url, value_str );
base_key = std::string( LLMediaEntry::CURRENT_URL_KEY );
mMediaSettings[ base_key ] = value_str;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Auto zoom
value_bool = default_media_data.getAutoZoom();
struct functor_getter_auto_zoom : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getAutoZoom();
LLMediaEntry default_media_data;
return default_media_data.getAutoZoom();
};
} func_auto_zoom;
identical = selected_objects->getSelectedTEValue( &func_auto_zoom, value_bool );
base_key = std::string( LLMediaEntry::AUTO_ZOOM_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Auto play
value_bool = default_media_data.getAutoPlay();
struct functor_getter_auto_play : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getAutoPlay();
LLMediaEntry default_media_data;
return default_media_data.getAutoPlay();
};
} func_auto_play;
identical = selected_objects->getSelectedTEValue( &func_auto_play, value_bool );
base_key = std::string( LLMediaEntry::AUTO_PLAY_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Auto scale
value_bool = default_media_data.getAutoScale();
struct functor_getter_auto_scale : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getAutoScale();
LLMediaEntry default_media_data;
return default_media_data.getAutoScale();;
};
} func_auto_scale;
identical = selected_objects->getSelectedTEValue( &func_auto_scale, value_bool );
base_key = std::string( LLMediaEntry::AUTO_SCALE_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Auto loop
value_bool = default_media_data.getAutoLoop();
struct functor_getter_auto_loop : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getAutoLoop();
LLMediaEntry default_media_data;
return default_media_data.getAutoLoop();
};
} func_auto_loop;
identical = selected_objects->getSelectedTEValue( &func_auto_loop, value_bool );
base_key = std::string( LLMediaEntry::AUTO_LOOP_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// width pixels (if not auto scaled)
value_int = default_media_data.getWidthPixels();
struct functor_getter_width_pixels : public LLSelectedTEGetFunctor< int >
{
int get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getWidthPixels();
LLMediaEntry default_media_data;
return default_media_data.getWidthPixels();
};
} func_width_pixels;
identical = selected_objects->getSelectedTEValue( &func_width_pixels, value_int );
base_key = std::string( LLMediaEntry::WIDTH_PIXELS_KEY );
mMediaSettings[ base_key ] = value_int;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// height pixels (if not auto scaled)
value_int = default_media_data.getHeightPixels();
struct functor_getter_height_pixels : public LLSelectedTEGetFunctor< int >
{
int get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getHeightPixels();
LLMediaEntry default_media_data;
return default_media_data.getHeightPixels();
};
} func_height_pixels;
identical = selected_objects->getSelectedTEValue( &func_height_pixels, value_int );
base_key = std::string( LLMediaEntry::HEIGHT_PIXELS_KEY );
mMediaSettings[ base_key ] = value_int;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Enable Alt image
value_bool = default_media_data.getAltImageEnable();
struct functor_getter_enable_alt_image : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getAltImageEnable();
LLMediaEntry default_media_data;
return default_media_data.getAltImageEnable();
};
} func_enable_alt_image;
identical = selected_objects->getSelectedTEValue( &func_enable_alt_image, value_bool );
base_key = std::string( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Perms - owner interact
value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
struct functor_getter_perms_owner_interact : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_OWNER));
LLMediaEntry default_media_data;
return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_OWNER );
};
} func_perms_owner_interact;
identical = selected_objects->getSelectedTEValue( &func_perms_owner_interact, value_bool );
base_key = std::string( LLPanelContents::PERMS_OWNER_INTERACT_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Perms - owner control
value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
struct functor_getter_perms_owner_control : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_OWNER));
LLMediaEntry default_media_data;
return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_OWNER );
};
} func_perms_owner_control;
identical = selected_objects ->getSelectedTEValue( &func_perms_owner_control, value_bool );
base_key = std::string( LLPanelContents::PERMS_OWNER_CONTROL_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Perms - group interact
value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
struct functor_getter_perms_group_interact : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_GROUP));
LLMediaEntry default_media_data;
return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_GROUP );
};
} func_perms_group_interact;
identical = selected_objects->getSelectedTEValue( &func_perms_group_interact, value_bool );
base_key = std::string( LLPanelContents::PERMS_GROUP_INTERACT_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Perms - group control
value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
struct functor_getter_perms_group_control : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_GROUP));
LLMediaEntry default_media_data;
return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_GROUP );
};
} func_perms_group_control;
identical = selected_objects->getSelectedTEValue( &func_perms_group_control, value_bool );
base_key = std::string( LLPanelContents::PERMS_GROUP_CONTROL_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Perms - anyone interact
value_bool = 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
struct functor_getter_perms_anyone_interact : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return (0 != (object->getTE(face)->getMediaData()->getPermsInteract() & LLMediaEntry::PERM_ANYONE));
LLMediaEntry default_media_data;
return 0 != ( default_media_data.getPermsInteract() & LLMediaEntry::PERM_ANYONE );
};
} func_perms_anyone_interact;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func_perms_anyone_interact, value_bool );
base_key = std::string( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// Perms - anyone control
value_bool = 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
struct functor_getter_perms_anyone_control : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return (0 != (object->getTE(face)->getMediaData()->getPermsControl() & LLMediaEntry::PERM_ANYONE));
LLMediaEntry default_media_data;
return 0 != ( default_media_data.getPermsControl() & LLMediaEntry::PERM_ANYONE );
};
} func_perms_anyone_control;
identical = selected_objects->getSelectedTEValue( &func_perms_anyone_control, value_bool );
base_key = std::string( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// security - whitelist enable
value_bool = default_media_data.getWhiteListEnable();
struct functor_getter_whitelist_enable : public LLSelectedTEGetFunctor< bool >
{
bool get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getWhiteListEnable();
LLMediaEntry default_media_data;
return default_media_data.getWhiteListEnable();
};
} func_whitelist_enable;
identical = selected_objects->getSelectedTEValue( &func_whitelist_enable, value_bool );
base_key = std::string( LLMediaEntry::WHITELIST_ENABLE_KEY );
mMediaSettings[ base_key ] = value_bool;
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
// security - whitelist URLs
std::vector<std::string> value_vector_str = default_media_data.getWhiteList();
struct functor_getter_whitelist_urls : public LLSelectedTEGetFunctor< std::vector<std::string> >
{
std::vector<std::string> get( LLViewerObject* object, S32 face )
{
if ( object )
if ( object->getTE(face) )
if ( object->getTE(face)->getMediaData() )
return object->getTE(face)->getMediaData()->getWhiteList();
LLMediaEntry default_media_data;
return default_media_data.getWhiteList();
};
} func_whitelist_urls;
identical = selected_objects->getSelectedTEValue( &func_whitelist_urls, value_vector_str );
base_key = std::string( LLMediaEntry::WHITELIST_KEY );
mMediaSettings[ base_key ].clear();
std::vector< std::string >::iterator iter = value_vector_str.begin();
while( iter != value_vector_str.end() )
{
std::string white_list_url = *iter;
mMediaSettings[ base_key ].append( white_list_url );
++iter;
};
mMediaSettings[ base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX ) ] = ! identical;
}

View File

@ -100,13 +100,24 @@ public:
void setStatusText(const std::string& text);
static void setEditTool(void* data);
void setTool(const LLSD& user_data);
void saveLastTool();
void onClickBtnDeleteMedia();
void onClickBtnAddMedia();
void onClickBtnEditMedia();
private:
void onClose();
void refresh();
void refreshMedia();
void getMediaState();
void updateMediaSettings();
void getMeidaState();
static bool deleteMediaConfirm(const LLSD& notification, const LLSD& response);
static bool multipleFacesSelectedConfirm(const LLSD& notification, const LLSD& response);
static void setObjectType( LLPCode pcode );
static void onClickGridOptions(void* data);
void onClickGridOptions();
public:
LLButton *mBtnFocus;
@ -175,6 +186,10 @@ private:
BOOL mDirty;
std::map<std::string, std::string> mStatusText;
protected:
LLSD mMediaSettings;
};
extern LLFloaterTools *gFloaterTools;

View File

@ -35,6 +35,7 @@
#include "llfloaterurlentry.h"
#include "llpanellandmedia.h"
#include "llpanelface.h"
// project includes
#include "llcombobox.h"
@ -145,13 +146,23 @@ void LLFloaterURLEntry::buildURLHistory()
void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_type)
{
LLPanelLandMedia* panel_media = (LLPanelLandMedia*)mPanelLandMediaHandle.get();
LLPanelLandMedia* panel_media = dynamic_cast<LLPanelLandMedia*>(mPanelLandMediaHandle.get());
if (panel_media)
{
// status is ignored for now -- error = "none/none"
panel_media->setMediaType(mime_type);
panel_media->setMediaURL(mMediaURLEdit->getValue().asString());
}
else
{
LLPanelFace* panel_face = dynamic_cast<LLPanelFace*>(mPanelLandMediaHandle.get());
if(panel_face)
{
panel_face->setMediaType(mime_type);
panel_face->setMediaURL(mMediaURLEdit->getValue().asString());
}
}
// Decrement the cursor
getWindow()->decBusyCount();
childSetVisible("loading_label", false);
@ -159,29 +170,18 @@ void LLFloaterURLEntry::headerFetchComplete(U32 status, const std::string& mime_
}
// static
LLHandle<LLFloater> LLFloaterURLEntry::show(LLHandle<LLPanel> parent)
LLHandle<LLFloater> LLFloaterURLEntry::show(LLHandle<LLPanel> parent, const std::string media_url)
{
if (sInstance)
{
sInstance->openFloater();
}
else
if (!sInstance)
{
sInstance = new LLFloaterURLEntry(parent);
}
sInstance->updateFromLandMediaPanel();
sInstance->openFloater();
sInstance->addURLToCombobox(media_url);
return sInstance->getHandle();
}
void LLFloaterURLEntry::updateFromLandMediaPanel()
{
LLPanelLandMedia* panel_media = (LLPanelLandMedia*)mPanelLandMediaHandle.get();
if (panel_media)
{
std::string media_url = panel_media->getMediaURL();
addURLToCombobox(media_url);
}
}
bool LLFloaterURLEntry::addURLToCombobox(const std::string& media_url)
{

View File

@ -44,10 +44,8 @@ class LLFloaterURLEntry : public LLFloater
public:
// Can only be shown by LLPanelLandMedia, and pushes data back into
// that panel via the handle.
static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle);
static LLHandle<LLFloater> show(LLHandle<LLPanel> panel_land_media_handle, const std::string media_url);
/*virtual*/ BOOL postBuild();
void updateFromLandMediaPanel();
void headerFetchComplete(U32 status, const std::string& mime_type);
bool addURLToCombobox(const std::string& media_url);

View File

@ -0,0 +1,97 @@
/**
* @file llfloaterwhitelistentry.cpp
* @brief LLFloaterWhistListEntry class implementation
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterreg.h"
#include "llfloatermediasettings.h"
#include "llfloaterwhitelistentry.h"
#include "llpanelmediasettingssecurity.h"
#include "lluictrlfactory.h"
#include "llwindow.h"
#include "llviewerwindow.h"
#include "lllineeditor.h"
///////////////////////////////////////////////////////////////////////////////
//
LLFloaterWhiteListEntry::LLFloaterWhiteListEntry( const LLSD& key ) :
LLFloater(key)
{
// LLUICtrlFactory::getInstance()->buildFloater(this, "floater_whitelist_entry.xml");
}
///////////////////////////////////////////////////////////////////////////////
//
LLFloaterWhiteListEntry::~LLFloaterWhiteListEntry()
{
}
///////////////////////////////////////////////////////////////////////////////
//
BOOL LLFloaterWhiteListEntry::postBuild()
{
mWhiteListEdit = getChild<LLLineEditor>("whitelist_entry");
childSetAction("cancel_btn", onBtnCancel, this);
childSetAction("ok_btn", onBtnOK, this);
setDefaultBtn("ok_btn");
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// static
void LLFloaterWhiteListEntry::onBtnOK( void* userdata )
{
LLFloaterWhiteListEntry *self =(LLFloaterWhiteListEntry *)userdata;
LLPanelMediaSettingsSecurity* panel = LLFloaterReg::getTypedInstance<LLFloaterMediaSettings>("media_settings")->getPanelSecurity();
if ( panel )
{
std::string white_list_item = self->mWhiteListEdit->getText();
panel->addWhiteListItem( white_list_item );
};
self->closeFloater();
}
///////////////////////////////////////////////////////////////////////////////
// static
void LLFloaterWhiteListEntry::onBtnCancel( void* userdata )
{
LLFloaterWhiteListEntry *self =(LLFloaterWhiteListEntry *)userdata;
self->closeFloater();
}

View File

@ -0,0 +1,56 @@
/**
* @file llfloaterwhitelistentry.h
* @brief LLFloaterWhiteListEntry class definition
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2007-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLFLOATERWHITELISTENTRY_H
#define LL_LLFLOATERWHITELISTENTRY_H
#include "llfloater.h"
class LLLineEditor;
class LLFloaterWhiteListEntry :
public LLFloater
{
public:
LLFloaterWhiteListEntry(const LLSD& key);
~LLFloaterWhiteListEntry();
BOOL postBuild();
private:
LLLineEditor* mWhiteListEdit;
static void onBtnOK(void*);
static void onBtnCancel(void*);
};
#endif // LL_LLFLOATERWHITELISTENTRY_H

View File

@ -43,6 +43,7 @@
#include "llviewborder.h"
#include "llviewercontrol.h"
#include "llviewermedia.h"
#include "llviewertexture.h"
#include "llviewerwindow.h"
#include "llnotifications.h"
#include "llweb.h"
@ -63,6 +64,9 @@ LLMediaCtrl::Params::Params()
border_visible("border_visible", true),
ignore_ui_scale("ignore_ui_scale", true),
hide_loading("hide_loading", false),
decouple_texture_size("decouple_texture_size", false),
texture_width("texture_width", 1024),
texture_height("texture_height", 1024),
caret_color("caret_color")
{}
@ -82,10 +86,12 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
mMediaSource( 0 ),
mTakeFocusOnClick( true ),
mCurrentNavUrl( "" ),
mLastSetCursor( UI_CURSOR_ARROW ),
mStretchToFill( true ),
mMaintainAspectRatio ( true ),
mHideLoading (false)
mHideLoading (false),
mDecoupleTextureSize ( false ),
mTextureWidth ( 1024 ),
mTextureHeight ( 1024 )
{
{
LLColor4 color = p.caret_color().get();
@ -99,24 +105,29 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
setBorderVisible(p.border_visible());
mHideLoading = p.hide_loading();
setDecoupleTextureSize(p.decouple_texture_size());
setTextureSize(p.texture_width(), p.texture_height());
S32 screen_width = mIgnoreUIScale ?
llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth();
S32 screen_height = mIgnoreUIScale ?
llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight();
if(!getDecoupleTextureSize())
{
S32 screen_width = mIgnoreUIScale ?
llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]) : getRect().getWidth();
S32 screen_height = mIgnoreUIScale ?
llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]) : getRect().getHeight();
setTextureSize(screen_width, screen_height);
}
mMediaTextureID.generate();
mMediaSource = LLViewerMedia::newMediaImpl(mHomePageUrl, mMediaTextureID, screen_width, screen_height, false, false, "text/html");
if ( !mMediaSource )
{
llwarns << "media source create failed " << llendl;
// return;
}
mMediaSource->setVisible( getVisible() );
mMediaSource->addObserver( this );
// We don't need to create the media source up front anymore unless we have a non-empty home URL to navigate to.
if(!mHomePageUrl.empty())
{
navigateHome();
}
// FIXME: How do we create a bevel now?
// LLRect border_rect( 0, getRect().getHeight() + 2, getRect().getWidth() + 2, 0 );
// mBorder = new LLViewBorder( std::string("web control border"), border_rect, LLViewBorder::BEVEL_IN );
@ -179,9 +190,10 @@ BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )
convertInputCoords(x, y);
if (mMediaSource)
{
mMediaSource->mouseMove(x, y);
gViewerWindow->setCursor(mLastSetCursor);
gViewerWindow->setCursor(mMediaSource->getLastSetCursor());
}
return TRUE;
}
@ -389,19 +401,19 @@ void LLMediaCtrl::onVisibilityChange ( const LLSD& new_visibility )
//
void LLMediaCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )
{
S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width;
S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height;
// llinfos << "reshape called with width = " << width << ", height = " << height << llendl;
// when floater is minimized, these sizes are negative
if ( screen_height > 0 && screen_width > 0 )
if(!getDecoupleTextureSize())
{
mMediaSource->setSize(screen_width, screen_height);
mForceUpdate = true;
}
S32 screen_width = mIgnoreUIScale ? llround((F32)width * LLUI::sGLScaleFactor.mV[VX]) : width;
S32 screen_height = mIgnoreUIScale ? llround((F32)height * LLUI::sGLScaleFactor.mV[VY]) : height;
LLPanel::reshape( width, height, called_from_parent );
// when floater is minimized, these sizes are negative
if ( screen_height > 0 && screen_width > 0 )
{
setTextureSize(screen_width, screen_height);
}
}
LLUICtrl::reshape( width, height, called_from_parent );
}
////////////////////////////////////////////////////////////////////////////////
@ -475,9 +487,10 @@ void LLMediaCtrl::navigateTo( std::string url_in, std::string mime_type)
return;
}
if (mMediaSource)
if (ensureMediaSourceExists())
{
mCurrentNavUrl = url_in;
mMediaSource->setSize(mTextureWidth, mTextureHeight);
mMediaSource->navigateTo(url_in, mime_type, mime_type.empty());
}
}
@ -513,9 +526,10 @@ void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::str
return;
}
}
if (mMediaSource)
if (ensureMediaSourceExists())
{
mCurrentNavUrl = expanded_filename;
mMediaSource->setSize(mTextureWidth, mTextureHeight);
mMediaSource->navigateTo(expanded_filename, "text/html", false);
}
@ -525,11 +539,11 @@ void LLMediaCtrl::navigateToLocalPage( const std::string& subdir, const std::str
//
void LLMediaCtrl::navigateHome()
{
if( mHomePageUrl.length() )
if (ensureMediaSourceExists())
{
if (mMediaSource)
mMediaSource->navigateTo(mHomePageUrl);
};
mMediaSource->setSize(mTextureWidth, mTextureHeight);
mMediaSource->navigateHome();
}
}
////////////////////////////////////////////////////////////////////////////////
@ -537,6 +551,10 @@ void LLMediaCtrl::navigateHome()
void LLMediaCtrl::setHomePageUrl( const std::string urlIn )
{
mHomePageUrl = urlIn;
if (mMediaSource)
{
mMediaSource->setHomeURL(mHomePageUrl);
}
}
////////////////////////////////////////////////////////////////////////////////
@ -546,6 +564,21 @@ bool LLMediaCtrl::setCaretColor(unsigned int red, unsigned int green, unsigned i
//NOOP
return false;
}
////////////////////////////////////////////////////////////////////////////////
//
void LLMediaCtrl::setTextureSize(S32 width, S32 height)
{
mTextureWidth = width;
mTextureHeight = height;
if(mMediaSource)
{
mMediaSource->setSize(mTextureWidth, mTextureHeight);
mForceUpdate = true;
}
}
////////////////////////////////////////////////////////////////////////////////
//
std::string LLMediaCtrl::getHomePageUrl()
@ -553,6 +586,38 @@ std::string LLMediaCtrl::getHomePageUrl()
return mHomePageUrl;
}
////////////////////////////////////////////////////////////////////////////////
//
bool LLMediaCtrl::ensureMediaSourceExists()
{
if(mMediaSource.isNull())
{
// If we don't already have a media source, try to create one.
mMediaSource = LLViewerMedia::newMediaImpl(mMediaTextureID, mTextureWidth, mTextureHeight);
if ( mMediaSource )
{
mMediaSource->setUsedInUI(true);
mMediaSource->setHomeURL(mHomePageUrl);
mMediaSource->setVisible( getVisible() );
mMediaSource->addObserver( this );
}
else
{
llwarns << "media source create failed " << llendl;
// return;
}
}
return !mMediaSource.isNull();
}
////////////////////////////////////////////////////////////////////////////////
//
void LLMediaCtrl::unloadMediaSource()
{
mMediaSource = NULL;
}
////////////////////////////////////////////////////////////////////////////////
//
LLPluginClassMedia* LLMediaCtrl::getMediaPlugin()
@ -574,13 +639,17 @@ void LLMediaCtrl::draw()
{
return;
}
if(!media_plugin || (!media_plugin->textureValid()))
{
// Don't try to draw without a valid texture
return;
}
LLViewerMediaTexture* media_texture = LLViewerTextureManager::findMediaTexture(mMediaTextureID);
if (!media_texture )
{
return;
}
if ( gRestoreGL == 1 )
{
@ -658,7 +727,7 @@ void LLMediaCtrl::draw()
width = llmin(media_plugin->getWidth(), r.getWidth());
height = llmin(media_plugin->getHeight(), r.getHeight());
}
x_offset = (r.getWidth() - width) / 2;
y_offset = (r.getHeight() - height) / 2;
@ -774,24 +843,9 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
case MEDIA_EVENT_CURSOR_CHANGED:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_CURSOR_CHANGED, new cursor is " << self->getCursorName() << LL_ENDL;
std::string cursor = self->getCursorName();
if(cursor == "arrow")
mLastSetCursor = UI_CURSOR_ARROW;
else if(cursor == "ibeam")
mLastSetCursor = UI_CURSOR_IBEAM;
else if(cursor == "splith")
mLastSetCursor = UI_CURSOR_SIZEWE;
else if(cursor == "splitv")
mLastSetCursor = UI_CURSOR_SIZENS;
else if(cursor == "hand")
mLastSetCursor = UI_CURSOR_HAND;
else // for anything else, default to the arrow
mLastSetCursor = UI_CURSOR_ARROW;
};
}
break;
case MEDIA_EVENT_NAVIGATE_BEGIN:
{
LL_DEBUGS("Media") << "Media event: MEDIA_EVENT_NAVIGATE_BEGIN, url is " << self->getNavigateURI() << LL_ENDL;

View File

@ -37,7 +37,6 @@
#include "lluictrl.h"
#include "llframetimer.h"
#include "lldynamictexture.h"
class LLViewBorder;
class LLUICtrlFactory;
@ -50,7 +49,6 @@ class LLMediaCtrl :
public LLViewerMediaEventEmitter
{
LOG_CLASS(LLMediaCtrl);
public:
struct Params : public LLInitParam::Block<Params, LLPanel::Params>
{
@ -58,7 +56,11 @@ public:
Optional<bool> border_visible,
ignore_ui_scale,
hide_loading;
hide_loading,
decouple_texture_size;
Optional<S32> texture_width,
texture_height;
Optional<LLUIColor> caret_color;
@ -127,9 +129,17 @@ public:
void setForceUpdate(bool force_update) { mForceUpdate = force_update; }
bool getForceUpdate() { return mForceUpdate; }
bool ensureMediaSourceExists();
void unloadMediaSource();
LLPluginClassMedia* getMediaPlugin();
bool setCaretColor( unsigned int red, unsigned int green, unsigned int blue );
void setDecoupleTextureSize(bool decouple) { mDecoupleTextureSize = decouple; }
bool getDecoupleTextureSize() { return mDecoupleTextureSize; }
void setTextureSize(S32 width, S32 height);
// over-rides
@ -173,10 +183,12 @@ public:
bool mAlwaysRefresh;
viewer_media_t mMediaSource;
bool mTakeFocusOnClick;
ECursorType mLastSetCursor;
bool mStretchToFill;
bool mMaintainAspectRatio;
bool mHideLoading;
bool mDecoupleTextureSize;
S32 mTextureWidth;
S32 mTextureHeight;
};
#endif // LL_LLMediaCtrl_H

View File

@ -72,6 +72,13 @@
//
// Globals
//
const char* LLPanelContents::TENTATIVE_SUFFIX = "_tentative";
const char* LLPanelContents::PERMS_OWNER_INTERACT_KEY = "perms_owner_interact";
const char* LLPanelContents::PERMS_OWNER_CONTROL_KEY = "perms_owner_control";
const char* LLPanelContents::PERMS_GROUP_INTERACT_KEY = "perms_group_interact";
const char* LLPanelContents::PERMS_GROUP_CONTROL_KEY = "perms_group_control";
const char* LLPanelContents::PERMS_ANYONE_INTERACT_KEY = "perms_anyone_interact";
const char* LLPanelContents::PERMS_ANYONE_CONTROL_KEY = "perms_anyone_control";
BOOL LLPanelContents::postBuild()
{
@ -83,7 +90,7 @@ BOOL LLPanelContents::postBuild()
childSetAction("button permissions",&LLPanelContents::onClickPermissions, this);
mPanelInventory = getChild<LLPanelInventory>("contents_inventory");
return TRUE;
}
@ -112,7 +119,7 @@ void LLPanelContents::getState(LLViewerObject *objectp )
LLSelectMgr::getInstance()->selectGetGroup(group_id); // sets group_id as a side effect SL-23488
// BUG? Check for all objects being editable?
BOOL editable = gAgent.isGodlike()
bool editable = gAgent.isGodlike()
|| (objectp->permModify()
&& ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) ))); // solves SL-23488
BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME );
@ -123,8 +130,8 @@ void LLPanelContents::getState(LLViewerObject *objectp )
all_volume &&
((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
|| (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)));
}
}
void LLPanelContents::refresh()
{
@ -135,7 +142,7 @@ void LLPanelContents::refresh()
if (mPanelInventory)
{
mPanelInventory->refresh();
}
}
}

View File

@ -51,11 +51,23 @@ public:
void refresh();
static void onClickNewScript( void* userdata);
static void onClickPermissions( void* userdata);
static void onClickNewScript(void*);
static void onClickPermissions(void*);
// Key suffix for "tentative" fields
static const char* TENTATIVE_SUFFIX;
// These aren't fields in LLMediaEntry, so we have to define them ourselves for checkbox control
static const char* PERMS_OWNER_INTERACT_KEY;
static const char* PERMS_OWNER_CONTROL_KEY;
static const char* PERMS_GROUP_INTERACT_KEY;
static const char* PERMS_GROUP_CONTROL_KEY;
static const char* PERMS_ANYONE_INTERACT_KEY;
static const char* PERMS_ANYONE_CONTROL_KEY;
protected:
void getState(LLViewerObject *object);
void getState(LLViewerObject *object);
public:
LLPanelInventory* mPanelInventory;

View File

@ -49,6 +49,7 @@
#include "llcombobox.h"
#include "lldrawpoolbump.h"
#include "lllineeditor.h"
#include "llmediaentry.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llspinctrl.h"
@ -61,6 +62,7 @@
#include "llviewermedia.h"
#include "llviewerobject.h"
#include "llviewerstats.h"
#include "llvovolume.h"
#include "lluictrlfactory.h"
#include "llpluginclassmedia.h"
@ -70,6 +72,18 @@
BOOL LLPanelFace::postBuild()
{
childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
childSetAction("button apply",&LLPanelFace::onClickApply,this);
childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
LLRect rect = this->getRect();
LLTextureCtrl* mTextureCtrl;
LLColorSwatchCtrl* mColorSwatch;
@ -91,7 +105,7 @@ BOOL LLPanelFace::postBuild()
mTextureCtrl->setCommitCallback( boost::bind(&LLPanelFace::onCommitTexture, this, _2) );
mTextureCtrl->setOnCancelCallback( boost::bind(&LLPanelFace::onCancelTexture, this, _2) );
mTextureCtrl->setOnSelectCallback( boost::bind(&LLPanelFace::onSelectTexture, this, _2) );
mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, _2));
mTextureCtrl->setDragCallback(boost::bind(&LLPanelFace::onDragTexture, this, _2));
mTextureCtrl->setFollowsTop();
mTextureCtrl->setFollowsLeft();
// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
@ -161,17 +175,6 @@ BOOL LLPanelFace::postBuild()
mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this);
}
childSetCommitCallback("combobox shininess",&LLPanelFace::onCommitShiny,this);
childSetCommitCallback("combobox bumpiness",&LLPanelFace::onCommitBump,this);
childSetCommitCallback("TexScaleU",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("checkbox flip s",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexScaleV",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("checkbox flip t",&LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexRot",&LLPanelFace::onCommitTextureInfo, this);
childSetAction("button apply",&onClickApply,this);
childSetCommitCallback("TexOffsetU",LLPanelFace::onCommitTextureInfo, this);
childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
childSetAction("button align",onClickAutoFix,this);
clearCtrls();
@ -382,10 +385,8 @@ void LLPanelFace::getState()
BOOL editable = objectp->permModify();
// only turn on auto-adjust button if there is a media renderer and the media is loaded
childSetEnabled("textbox autofix",FALSE);
//mLabelTexAutoFix->setEnabled ( FALSE );
childSetEnabled("button align",FALSE);
//mBtnAutoFix->setEnabled ( FALSE );
childSetEnabled("textbox autofix", editable);
childSetEnabled("button align", editable);
//if ( LLMediaEngine::getInstance()->getMediaRenderer () )
// if ( LLMediaEngine::getInstance()->getMediaRenderer ()->isLoaded () )
@ -785,6 +786,9 @@ void LLPanelFace::getState()
childSetEnabled("button align",FALSE);
childSetEnabled("button apply",FALSE);
childSetEnabled("has media", FALSE);
childSetEnabled("media info set", FALSE);
}
}
@ -862,7 +866,7 @@ void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata)
}
// static
BOOL LLPanelFace::onDragTexture(LLInventoryItem* item)
BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item)
{
BOOL accept = TRUE;
for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
@ -917,15 +921,25 @@ void LLPanelFace::onClickApply(void* userdata)
LLSelectMgr::getInstance()->selectionTexScaleAutofit( repeats_per_meter );
}
// commit the fit media texture to prim button
struct LLPanelFaceSetMediaFunctor : public LLSelectedTEFunctor
{
virtual bool apply(LLViewerObject* object, S32 te)
{
// TODO: the media impl pointer should actually be stored by the texture
viewer_media_t pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(object->getTE ( te )->getID());
// only do this if it's a media texture
viewer_media_t pMediaImpl;
const LLTextureEntry* tep = object->getTE(te);
const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
if ( mep )
{
pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
}
if ( pMediaImpl.isNull())
{
// If we didn't find face media for this face, check whether this face is showing parcel media.
pMediaImpl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
}
if ( pMediaImpl.notNull())
{
LLPluginClassMedia *media = pMediaImpl->getMediaPlugin();
@ -957,3 +971,14 @@ void LLPanelFace::onClickAutoFix(void* userdata)
LLPanelFaceSendFunctor sendfunc;
LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc);
}
// TODO: I don't know who put these in or what these are for???
void LLPanelFace::setMediaURL(const std::string& url)
{
}
void LLPanelFace::setMediaType(const std::string& mime_type)
{
}

View File

@ -47,6 +47,7 @@ class LLTextBox;
class LLTextureCtrl;
class LLUICtrl;
class LLViewerObject;
class LLFloater;
class LLPanelFace : public LLPanel
{
@ -56,6 +57,8 @@ public:
virtual ~LLPanelFace();
void refresh();
void setMediaURL(const std::string& url);
void setMediaType(const std::string& mime_type);
protected:
void getState();
@ -69,9 +72,10 @@ protected:
void sendShiny(); // applies and sends shininess
void sendFullbright(); // applies and sends full bright
void sendGlow();
void sendMedia();
// this function is to return TRUE if the drag should succeed.
static BOOL onDragTexture(LLInventoryItem* item);
static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item);
void onCommitTexture(const LLSD& data);
void onCancelTexture(const LLSD& data);
@ -87,10 +91,11 @@ protected:
static void onCommitShiny( LLUICtrl* ctrl, void* userdata);
static void onCommitFullbright( LLUICtrl* ctrl, void* userdata);
static void onCommitGlow( LLUICtrl* ctrl, void *userdata);
static void onClickApply(void*);
static void onClickAutoFix(void*);
static F32 valueGlow(LLViewerObject* object, S32 face);
};
#endif

View File

@ -122,9 +122,6 @@ BOOL LLPanelLandMedia::postBuild()
mSetURLButton = getChild<LLButton>("set_media_url");
childSetAction("set_media_url", onSetBtn, this);
mResetURLButton = getChild<LLButton>("reset_media_url");
childSetAction("reset_media_url", onResetBtn, this);
return TRUE;
}
@ -215,13 +212,7 @@ void LLPanelLandMedia::refresh()
mMediaTextureCtrl->setEnabled( can_change_media );
mSetURLButton->setEnabled( can_change_media );
mResetURLButton->setEnabled( can_change_media );
LLFloaterURLEntry* floater_url_entry = (LLFloaterURLEntry*)mURLEntryFloater.get();
if (floater_url_entry)
{
floater_url_entry->updateFromLandMediaPanel();
}
}
}
@ -341,7 +332,7 @@ void LLPanelLandMedia::onCommitAny(LLUICtrl*, void *userdata)
void LLPanelLandMedia::onSetBtn(void *userdata)
{
LLPanelLandMedia *self = (LLPanelLandMedia *)userdata;
self->mURLEntryFloater = LLFloaterURLEntry::show( self->getHandle() );
self->mURLEntryFloater = LLFloaterURLEntry::show( self->getHandle(), self->getMediaURL() );
LLFloater* parent_floater = gFloaterView->getParentFloater(self);
if (parent_floater)
{

View File

@ -63,8 +63,6 @@ private:
LLLineEditor* mMediaDescEdit;
LLComboBox* mMediaTypeCombo;
LLButton* mSetURLButton;
LLButton* mResetURLButton;
LLSpinCtrl* mMediaResetCtrl;
LLSpinCtrl* mMediaHeightCtrl;
LLSpinCtrl* mMediaWidthCtrl;
LLTextBox* mMediaResetCtrlLabel;
@ -74,13 +72,6 @@ private:
LLCheckBoxCtrl* mMediaLoopCheck;
LLCheckBoxCtrl* mMediaUrlCheck;
LLHandle<LLFloater> mURLEntryFloater;
LLCheckBoxCtrl* mMediaNavigateAllowCheck;
LLCheckBoxCtrl* mMediaURLFilterCheck;
LLLineEditor* mMediaURLFilterDomainEdit;
LLButton* mMediaURLFilterAddButton;
LLButton* mMediaURLFilterRemoveButton;
LLScrollListCtrl* mURLFilterList;
LLRadioGroup* mRadioNavigateControl;

View File

@ -70,6 +70,7 @@
#include "llmediactrl.h"
#include "llrootview.h"
#include "llfloatertos.h"
#include "lltrans.h"
#include "llglheaders.h"

View File

@ -0,0 +1,409 @@
/**
* @file llpanelmediasettingsgeneral.cpp
* @brief LLPanelMediaSettingsGeneral class implementation
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llpanelmediasettingsgeneral.h"
#include "llcombobox.h"
#include "llcheckboxctrl.h"
#include "llspinctrl.h"
#include "lluictrlfactory.h"
#include "llviewerwindow.h"
#include "llsdutil.h"
#include "llselectmgr.h"
#include "llbutton.h"
#include "lltexturectrl.h"
#include "llurl.h"
#include "llwindow.h"
#include "llmediaentry.h"
#include "llmediactrl.h"
#include "llpanelcontents.h"
#include "llpluginclassmedia.h"
#include "llfloatermediasettings.h"
////////////////////////////////////////////////////////////////////////////////
//
LLPanelMediaSettingsGeneral::LLPanelMediaSettingsGeneral() :
mControls( NULL ),
mAutoLoop( NULL ),
mFirstClick( NULL ),
mAutoZoom( NULL ),
mAutoPlay( NULL ),
mAutoScale( NULL ),
mWidthPixels( NULL ),
mHeightPixels( NULL ),
mHomeURL( NULL ),
mCurrentURL( NULL ),
mAltImageEnable( NULL ),
mParent( NULL )
{
// build dialog from XML
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_general.xml");
mCommitCallbackRegistrar.add("Media.ResetCurrentUrl", boost::bind(&LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl, this));
// mCommitCallbackRegistrar.add("Media.CommitHomeURL", boost::bind(&LLPanelMediaSettingsGeneral::onCommitHomeURL, this));
}
////////////////////////////////////////////////////////////////////////////////
//
BOOL LLPanelMediaSettingsGeneral::postBuild()
{
// connect member vars with UI widgets
mAltImageEnable = getChild< LLCheckBoxCtrl >( LLMediaEntry::ALT_IMAGE_ENABLE_KEY );
mAutoLoop = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_LOOP_KEY );
mAutoPlay = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_PLAY_KEY );
mAutoScale = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_SCALE_KEY );
mAutoZoom = getChild< LLCheckBoxCtrl >( LLMediaEntry::AUTO_ZOOM_KEY );
mControls = getChild< LLComboBox >( LLMediaEntry::CONTROLS_KEY );
mCurrentURL = getChild< LLLineEditor >( LLMediaEntry::CURRENT_URL_KEY );
mFirstClick = getChild< LLCheckBoxCtrl >( LLMediaEntry::FIRST_CLICK_INTERACT_KEY );
mHeightPixels = getChild< LLSpinCtrl >( LLMediaEntry::HEIGHT_PIXELS_KEY );
mHomeURL = getChild< LLLineEditor >( LLMediaEntry::HOME_URL_KEY );
mWidthPixels = getChild< LLSpinCtrl >( LLMediaEntry::WIDTH_PIXELS_KEY );
mPreviewMedia = getChild<LLMediaCtrl>("preview_media");
// watch commit action for HOME URL
childSetCommitCallback( LLMediaEntry::HOME_URL_KEY, onCommitHomeURL, this);
// interrogates controls and updates widgets as required
updateMediaPreview();
updateCurrentURL();
return true;
}
////////////////////////////////////////////////////////////////////////////////
// virtual
LLPanelMediaSettingsGeneral::~LLPanelMediaSettingsGeneral()
{
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsGeneral::draw()
{
// housekeeping
LLPanel::draw();
// enable/disable pixel values image entry based on auto scale checkbox
if ( mAutoScale->getValue().asBoolean() == false )
{
childSetEnabled( LLMediaEntry::WIDTH_PIXELS_KEY, true );
childSetEnabled( LLMediaEntry::HEIGHT_PIXELS_KEY, true );
}
else
{
childSetEnabled( LLMediaEntry::WIDTH_PIXELS_KEY, false );
childSetEnabled( LLMediaEntry::HEIGHT_PIXELS_KEY, false );
};
// enable/disable UI based on type of media
bool reset_button_is_active = true;
if( mPreviewMedia )
{
LLPluginClassMedia* media_plugin = mPreviewMedia->getMediaPlugin();
if( media_plugin )
{
// some controls are only appropriate for time or browser type plugins
// so we selectively enable/disable them - need to do it in draw
// because the information from plugins arrives assynchronously
bool show_time_controls = media_plugin->pluginSupportsMediaTime();
if ( show_time_controls )
{
childSetEnabled( LLMediaEntry::CURRENT_URL_KEY, false );
reset_button_is_active = false;
childSetEnabled( "current_url_label", false );
childSetEnabled( LLMediaEntry::AUTO_LOOP_KEY, true );
}
else
{
childSetEnabled( LLMediaEntry::CURRENT_URL_KEY, true );
reset_button_is_active = true;
childSetEnabled( "current_url_label", true );
childSetEnabled( LLMediaEntry::AUTO_LOOP_KEY, false );
};
};
};
// current URL can change over time.
updateCurrentURL();
// enable/disable RESRET button depending on permissions
// since this is the same as a navigate action
U32 owner_mask_on;
U32 owner_mask_off;
U32 valid_owner_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_OWNER,
&owner_mask_on, &owner_mask_off );
U32 group_mask_on;
U32 group_mask_off;
U32 valid_group_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_GROUP,
&group_mask_on, &group_mask_off );
U32 everyone_mask_on;
U32 everyone_mask_off;
S32 valid_everyone_perms = LLSelectMgr::getInstance()->selectGetPerm( PERM_EVERYONE,
&everyone_mask_on, &everyone_mask_off );
bool user_can_press_reset = false;
// if perms we got back are valid
if ( valid_owner_perms &&
valid_group_perms &&
valid_everyone_perms )
{
// if user is allowed to press the RESET button
if ( ( owner_mask_on & PERM_MODIFY ) ||
( group_mask_on & PERM_MODIFY ) ||
( group_mask_on & PERM_MODIFY ) )
{
user_can_press_reset = true;
}
else
// user is NOT allowed to press the RESET button
{
user_can_press_reset = false;
};
};
// several places modify this widget so we must collect states in one place
if ( reset_button_is_active )
{
// user has perms to press reset button and it is active
if ( user_can_press_reset )
{
childSetEnabled( "current_url_reset_btn", true );
}
// user does not has perms to press reset button and it is active
else
{
childSetEnabled( "current_url_reset_btn", false );
};
}
else
// reset button is inactive so we just slam it to off - other states don't matter
{
childSetEnabled( "current_url_reset_btn", false );
};
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsGeneral::clearValues( void* userdata )
{
LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
self->mAltImageEnable ->clear();
self->mAutoLoop->clear();
self->mAutoPlay->clear();
self->mAutoScale->clear();
self->mAutoZoom ->clear();
self->mControls->clear();
self->mCurrentURL->clear();
self->mFirstClick->clear();
self->mHeightPixels->clear();
self->mHomeURL->clear();
self->mWidthPixels->clear();
self->mPreviewMedia->unloadMediaSource();
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsGeneral::initValues( void* userdata, const LLSD& media_settings )
{
LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
//llinfos << "---------------" << llendl;
//llinfos << ll_pretty_print_sd(media_settings) << llendl;
//llinfos << "---------------" << llendl;
std::string base_key( "" );
std::string tentative_key( "" );
struct
{
std::string key_name;
LLUICtrl* ctrl_ptr;
std::string ctrl_type;
} data_set [] =
{
{ LLMediaEntry::AUTO_LOOP_KEY, self->mAutoLoop, "LLCheckBoxCtrl" },
{ LLMediaEntry::AUTO_PLAY_KEY, self->mAutoPlay, "LLCheckBoxCtrl" },
{ LLMediaEntry::AUTO_SCALE_KEY, self->mAutoScale, "LLCheckBoxCtrl" },
{ LLMediaEntry::AUTO_ZOOM_KEY, self->mAutoZoom, "LLCheckBoxCtrl" },
{ LLMediaEntry::CONTROLS_KEY, self->mControls, "LLComboBox" },
{ LLMediaEntry::CURRENT_URL_KEY, self->mCurrentURL, "LLLineEditor" },
{ LLMediaEntry::HEIGHT_PIXELS_KEY, self->mHeightPixels, "LLSpinCtrl" },
{ LLMediaEntry::HOME_URL_KEY, self->mHomeURL, "LLLineEditor" },
{ LLMediaEntry::FIRST_CLICK_INTERACT_KEY, self->mFirstClick, "LLCheckBoxCtrl" },
{ LLMediaEntry::WIDTH_PIXELS_KEY, self->mWidthPixels, "LLSpinCtrl" },
{ LLMediaEntry::ALT_IMAGE_ENABLE_KEY, self->mAltImageEnable, "LLCheckBoxCtrl" },
{ "", NULL , "" }
};
for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )
{
base_key = std::string( data_set[ i ].key_name );
tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX );
// TODO: CP - I bet there is a better way to do this using Boost
if ( media_settings[ base_key ].isDefined() )
{
if ( data_set[ i ].ctrl_type == "LLLineEditor" )
{
static_cast< LLLineEditor* >( data_set[ i ].ctrl_ptr )->
setText( media_settings[ base_key ].asString() );
}
else
if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" )
static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )->
setValue( media_settings[ base_key ].asBoolean() );
else
if ( data_set[ i ].ctrl_type == "LLComboBox" )
static_cast< LLComboBox* >( data_set[ i ].ctrl_ptr )->
setCurrentByIndex( media_settings[ base_key ].asInteger() );
else
if ( data_set[ i ].ctrl_type == "LLSpinCtrl" )
static_cast< LLSpinCtrl* >( data_set[ i ].ctrl_ptr )->
setValue( media_settings[ base_key ].asInteger() );
data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
};
};
// interrogates controls and updates widgets as required
self->updateMediaPreview();
self->updateCurrentURL();
}
////////////////////////////////////////////////////////////////////////////////
// Helper to set media control to media URL as required
void LLPanelMediaSettingsGeneral::updateMediaPreview()
{
if ( mHomeURL->getValue().asString().length() > 0 )
{
mPreviewMedia->navigateTo( mHomeURL->getValue().asString() );
}
else
// new home URL will be empty if media is deleted but
// we still need to clean out the preview.
{
mPreviewMedia->unloadMediaSource();
};
}
////////////////////////////////////////////////////////////////////////////////
// Helper to set current URL
void LLPanelMediaSettingsGeneral::updateCurrentURL()
{
if( mPreviewMedia )
{
LLPluginClassMedia* media_plugin = mPreviewMedia->getMediaPlugin();
if( media_plugin )
{
// get current URL from plugin and display
std::string current_location = media_plugin->getLocation();
if ( current_location.length() )
{
childSetText( "current_url", current_location );
}
else
// current location may be empty so we need to clear it
{
const std::string empty_string( "" );
childSetText( "current_url", empty_string );
};
};
};
}
////////////////////////////////////////////////////////////////////////////////
void LLPanelMediaSettingsGeneral::onClose()
{
if(mPreviewMedia)
{
mPreviewMedia->unloadMediaSource();
}
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsGeneral::onCommitHomeURL( LLUICtrl* ctrl, void *userdata )
{
LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata;
self->updateMediaPreview();
}
////////////////////////////////////////////////////////////////////////////////
void LLPanelMediaSettingsGeneral::onBtnResetCurrentUrl()
{
// TODO: reset home URL but need to consider permissions too
//LLPanelMediaSettingsGeneral* self =(LLPanelMediaSettingsGeneral *)userdata;
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsGeneral::apply( void* userdata )
{
LLPanelMediaSettingsGeneral *self =(LLPanelMediaSettingsGeneral *)userdata;
// build LLSD Fragment
LLSD media_data_general;
self->getValues(media_data_general);
// this merges contents of LLSD passed in with what's there so this is ok
LLSelectMgr::getInstance()->selectionSetMediaData( media_data_general );
}
////////////////////////////////////////////////////////////////////////////////
//
void LLPanelMediaSettingsGeneral::getValues( LLSD &fill_me_in )
{
fill_me_in[LLMediaEntry::ALT_IMAGE_ENABLE_KEY] = mAltImageEnable->getValue();
fill_me_in[LLMediaEntry::AUTO_LOOP_KEY] = mAutoLoop->getValue();
fill_me_in[LLMediaEntry::AUTO_PLAY_KEY] = mAutoPlay->getValue();
fill_me_in[LLMediaEntry::AUTO_SCALE_KEY] = mAutoScale->getValue();
fill_me_in[LLMediaEntry::AUTO_ZOOM_KEY] = mAutoZoom->getValue();
fill_me_in[LLMediaEntry::CONTROLS_KEY] = mControls->getCurrentIndex();
// XXX Don't send current URL!
//fill_me_in[LLMediaEntry::CURRENT_URL_KEY] = mCurrentURL->getValue();
fill_me_in[LLMediaEntry::HEIGHT_PIXELS_KEY] = mHeightPixels->getValue();
fill_me_in[LLMediaEntry::HOME_URL_KEY] = mHomeURL->getValue();
fill_me_in[LLMediaEntry::FIRST_CLICK_INTERACT_KEY] = mFirstClick->getValue();
fill_me_in[LLMediaEntry::WIDTH_PIXELS_KEY] = mWidthPixels->getValue();
}
////////////////////////////////////////////////////////////////////////////////
//
void LLPanelMediaSettingsGeneral::setParent( LLFloaterMediaSettings* parent )
{
mParent = parent;
};

View File

@ -0,0 +1,89 @@
/**
* @file llpanelmediasettingsgeneral.h
* @brief LLPanelMediaSettingsGeneral class definition
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLPANELMEDIAMEDIASETTINGSGENERAL_H
#define LL_LLPANELMEDIAMEDIASETTINGSGENERAL_H
#include "llpanel.h"
class LLButton;
class LLCheckBoxCtrl;
class LLComboBox;
class LLLineEditor;
class LLSpinCtrl;
class LLTextureCtrl;
class LLMediaCtrl;
class LLFloaterMediaSettings;
class LLPanelMediaSettingsGeneral : public LLPanel
{
public:
BOOL postBuild();
virtual void draw();
static void apply(void*);
void getValues(LLSD &fill_me_in);
LLPanelMediaSettingsGeneral();
~LLPanelMediaSettingsGeneral();
void setParent( LLFloaterMediaSettings* parent );
static void initValues( void* userdata, const LLSD& media_settings );
static void clearValues( void* userdata );
void updateMediaPreview();
void updateCurrentURL();
void onClose();
protected:
LLFloaterMediaSettings* mParent;
private:
void onBtnResetCurrentUrl();
static void onCommitHomeURL(LLUICtrl* ctrl, void *userdata );
LLComboBox* mControls;
LLCheckBoxCtrl* mAutoLoop;
LLCheckBoxCtrl* mFirstClick;
LLTextureCtrl* mMediaPreview;
LLCheckBoxCtrl* mAutoZoom;
LLCheckBoxCtrl* mAutoPlay;
LLCheckBoxCtrl* mAutoScale;
LLSpinCtrl* mWidthPixels;
LLSpinCtrl* mHeightPixels;
LLLineEditor* mHomeURL;
LLLineEditor* mCurrentURL;
LLCheckBoxCtrl* mAltImageEnable;
LLMediaCtrl* mPreviewMedia;
};
#endif // LL_LLPANELMEDIAMEDIASETTINGSGENERAL_H

View File

@ -0,0 +1,223 @@
/**
* @file llpanelmediasettingspermissions.cpp
* @brief LLPanelMediaSettingsPermissions class implementation
*
* note that "permissions" tab is really "Controls" tab - refs to 'perms' and
* 'permissions' not changed to 'controls' since we don't want to change
* shared files in server code and keeping everything the same seemed best.
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llpanelmediasettingspermissions.h"
#include "llpanelcontents.h"
#include "llcombobox.h"
#include "llcheckboxctrl.h"
#include "llspinctrl.h"
#include "llurlhistory.h"
#include "lluictrlfactory.h"
#include "llwindow.h"
#include "llviewerwindow.h"
#include "llsdutil.h"
#include "llselectmgr.h"
#include "llmediaentry.h"
#include "llnamebox.h"
////////////////////////////////////////////////////////////////////////////////
//
LLPanelMediaSettingsPermissions::LLPanelMediaSettingsPermissions() :
mPermsOwnerInteract( 0 ),
mPermsOwnerControl( 0 ),
mPermsGroupName( 0 ),
mPermsGroupInteract( 0 ),
mPermsGroupControl( 0 ),
mPermsWorldInteract( 0 ),
mPermsWorldControl( 0 )
{
// build dialog from XML
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_permissions.xml");
}
////////////////////////////////////////////////////////////////////////////////
//
BOOL LLPanelMediaSettingsPermissions::postBuild()
{
// connect member vars with UI widgets
mPermsOwnerInteract = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_OWNER_INTERACT_KEY );
mPermsOwnerControl = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_OWNER_CONTROL_KEY );
mPermsGroupInteract = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_GROUP_INTERACT_KEY );
mPermsGroupControl = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_GROUP_CONTROL_KEY );
mPermsWorldInteract = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_ANYONE_INTERACT_KEY );
mPermsWorldControl = getChild< LLCheckBoxCtrl >( LLPanelContents::PERMS_ANYONE_CONTROL_KEY );
mPermsGroupName = getChild< LLNameBox >( "perms_group_name" );
return true;
}
////////////////////////////////////////////////////////////////////////////////
// virtual
LLPanelMediaSettingsPermissions::~LLPanelMediaSettingsPermissions()
{
}
////////////////////////////////////////////////////////////////////////////////
// virtual
void LLPanelMediaSettingsPermissions::draw()
{
// housekeeping
LLPanel::draw();
childSetText("perms_group_name",LLStringUtil::null);
LLUUID group_id;
BOOL groups_identical = LLSelectMgr::getInstance()->selectGetGroup(group_id);
if (groups_identical)
{
if(mPermsGroupName)
{
mPermsGroupName->setNameID(group_id, true);
mPermsGroupName->setEnabled(true);
};
}
else
{
if(mPermsGroupName)
{
mPermsGroupName->setNameID(LLUUID::null, TRUE);
mPermsGroupName->refresh(LLUUID::null, LLStringUtil::null, LLStringUtil::null, true);
mPermsGroupName->setEnabled(false);
};
};
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsPermissions::clearValues( void* userdata )
{
LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata;
self->mPermsOwnerInteract->clear();
self->mPermsOwnerControl->clear();
self->mPermsGroupInteract ->clear();
self->mPermsGroupControl->clear();
self->mPermsWorldInteract ->clear();
self->mPermsWorldControl ->clear();
// mPermsGroupName ->setValue(0);
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsPermissions::initValues( void* userdata, const LLSD& media_settings )
{
LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata;
std::string base_key( "" );
std::string tentative_key( "" );
struct
{
std::string key_name;
LLUICtrl* ctrl_ptr;
std::string ctrl_type;
} data_set [] =
{
{ LLPanelContents::PERMS_OWNER_INTERACT_KEY, self->mPermsOwnerInteract, "LLCheckBoxCtrl" },
{ LLPanelContents::PERMS_OWNER_CONTROL_KEY, self->mPermsOwnerControl, "LLCheckBoxCtrl" },
{ LLPanelContents::PERMS_GROUP_INTERACT_KEY, self->mPermsGroupInteract, "LLCheckBoxCtrl" },
{ LLPanelContents::PERMS_GROUP_CONTROL_KEY, self->mPermsGroupControl, "LLCheckBoxCtrl" },
{ LLPanelContents::PERMS_ANYONE_INTERACT_KEY, self->mPermsWorldInteract, "LLCheckBoxCtrl" },
{ LLPanelContents::PERMS_ANYONE_CONTROL_KEY, self->mPermsWorldControl, "LLCheckBoxCtrl" },
{ "", NULL , "" }
};
for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )
{
base_key = std::string( data_set[ i ].key_name );
tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX );
// TODO: CP - I bet there is a better way to do this using Boost
if ( media_settings[ base_key ].isDefined() )
{
if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" )
{
// the sense of the checkboxes changed and it made sense
// to just reverse their sense back again here and avoid
// changing server code.
static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )->
setValue( ! media_settings[ base_key ].asBoolean() );
}
else
if ( data_set[ i ].ctrl_type == "LLComboBox" )
static_cast< LLComboBox* >( data_set[ i ].ctrl_ptr )->
setCurrentByIndex( media_settings[ base_key ].asInteger() );
data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
};
};
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsPermissions::apply( void* userdata )
{
LLPanelMediaSettingsPermissions *self =(LLPanelMediaSettingsPermissions *)userdata;
// build LLSD Fragment
LLSD media_data_permissions;
self->getValues(media_data_permissions);
// this merges contents of LLSD passed in with what's there so this is ok
LLSelectMgr::getInstance()->selectionSetMediaData( media_data_permissions );
}
////////////////////////////////////////////////////////////////////////////////
//
void LLPanelMediaSettingsPermissions::getValues( LLSD &fill_me_in )
{
// *NOTE: For some reason, gcc does not like these symbol references in the
// expressions below (inside the static_casts). I have NO idea why :(.
// For some reason, assigning them to const temp vars here fixes the link
// error. Bizarre.
const U8 none = LLMediaEntry::PERM_NONE;
const U8 owner = LLMediaEntry::PERM_OWNER;
const U8 group = LLMediaEntry::PERM_GROUP;
const U8 anyone = LLMediaEntry::PERM_ANYONE;
const LLSD::Integer control = static_cast<LLSD::Integer>(
(mPermsOwnerControl->getValue() ? none : owner ) |
(mPermsGroupControl->getValue() ? none : group ) |
(mPermsWorldControl->getValue() ? none : anyone ));
const LLSD::Integer interact = static_cast<LLSD::Integer>(
(mPermsOwnerInteract->getValue() ? none : owner ) |
(mPermsGroupInteract->getValue() ? none : group ) |
(mPermsWorldInteract->getValue() ? none : anyone ));
fill_me_in[LLMediaEntry::PERMS_CONTROL_KEY] = control;
fill_me_in[LLMediaEntry::PERMS_INTERACT_KEY] = interact;
}

View File

@ -0,0 +1,71 @@
/**
* @file llpanelmediasettingspermissions.h
* @brief LLPanelMediaSettingsPermissions class definition
*
* note that "permissions" tab is really "Controls" tab - refs to 'perms' and
* 'permissions' not changed to 'controls' since we don't want to change
* shared files in server code and keeping everything the same seemed best.
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLPANELMEDIAMEDIASETTINGSPERMISSIONS_H
#define LL_LLPANELMEDIAMEDIASETTINGSPERMISSIONS_H
#include "llpanel.h"
#include "lluuid.h"
class LLComboBox;
class LLCheckBoxCtrl;
class LLNameBox;
class LLPanelMediaSettingsPermissions : public LLPanel
{
public:
BOOL postBuild();
virtual void draw();
static void apply(void*);
void getValues(LLSD &fill_me_in);
LLPanelMediaSettingsPermissions();
~LLPanelMediaSettingsPermissions();
static void initValues( void* userdata, const LLSD& media_settings );
static void clearValues( void* userdata );
private:
LLCheckBoxCtrl* mPermsOwnerInteract;
LLCheckBoxCtrl* mPermsOwnerControl;
LLNameBox* mPermsGroupName;
LLCheckBoxCtrl* mPermsGroupInteract;
LLCheckBoxCtrl* mPermsGroupControl;
LLCheckBoxCtrl* mPermsWorldInteract;
LLCheckBoxCtrl* mPermsWorldControl;
};
#endif // LL_LLPANELMEDIAMEDIASETTINGSPERMISSIONS_H

View File

@ -0,0 +1,233 @@
/**
* @file llpanelmediasettingssecurity.cpp
* @brief LLPanelMediaSettingsSecurity class implementation
*
* $LicenseInfo:firstyear=2009&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfloaterreg.h"
#include "llpanelmediasettingssecurity.h"
#include "llpanelcontents.h"
#include "llcheckboxctrl.h"
#include "llscrolllistctrl.h"
#include "llscrolllistitem.h"
#include "lluictrlfactory.h"
#include "llwindow.h"
#include "llviewerwindow.h"
#include "llsdutil.h"
#include "llselectmgr.h"
#include "llmediaentry.h"
#include "llfloaterwhitelistentry.h"
////////////////////////////////////////////////////////////////////////////////
//
LLPanelMediaSettingsSecurity::LLPanelMediaSettingsSecurity()
{
// build dialog from XML
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_media_settings_security.xml");
mCommitCallbackRegistrar.add("Media.whitelistAdd", boost::bind(&LLPanelMediaSettingsSecurity::onBtnAdd, this));
mCommitCallbackRegistrar.add("Media.whitelistDelete", boost::bind(&LLPanelMediaSettingsSecurity::onBtnDel, this));
}
////////////////////////////////////////////////////////////////////////////////
//
BOOL LLPanelMediaSettingsSecurity::postBuild()
{
mEnableWhiteList = getChild< LLCheckBoxCtrl >( LLMediaEntry::WHITELIST_ENABLE_KEY );
mWhiteListList = getChild< LLScrollListCtrl >( LLMediaEntry::WHITELIST_KEY );
childSetAction("whitelist_add", onBtnAdd, this);
childSetAction("whitelist_del", onBtnDel, this);
setDefaultBtn("whitelist_add");
return true;
}
////////////////////////////////////////////////////////////////////////////////
// virtual
LLPanelMediaSettingsSecurity::~LLPanelMediaSettingsSecurity()
{
}
////////////////////////////////////////////////////////////////////////////////
//
void LLPanelMediaSettingsSecurity::draw()
{
// housekeeping
LLPanel::draw();
// if list is empty, disable DEL button and checkbox to enable use of list
if ( mWhiteListList->isEmpty() )
{
childSetEnabled( "whitelist_del", false );
childSetEnabled( LLMediaEntry::WHITELIST_KEY, false );
childSetEnabled( LLMediaEntry::WHITELIST_ENABLE_KEY, false );
}
else
{
childSetEnabled( "whitelist_del", true );
childSetEnabled( LLMediaEntry::WHITELIST_KEY, true );
childSetEnabled( LLMediaEntry::WHITELIST_ENABLE_KEY, true );
};
// if nothing is selected, disable DEL button
if ( mWhiteListList->getSelectedValue().asString().empty() )
{
childSetEnabled( "whitelist_del", false );
}
else
{
childSetEnabled( "whitelist_del", true );
};
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsSecurity::initValues( void* userdata, const LLSD& media_settings )
{
LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
std::string base_key( "" );
std::string tentative_key( "" );
struct
{
std::string key_name;
LLUICtrl* ctrl_ptr;
std::string ctrl_type;
} data_set [] =
{
{ LLMediaEntry::WHITELIST_ENABLE_KEY, self->mEnableWhiteList, "LLCheckBoxCtrl" },
{ LLMediaEntry::WHITELIST_KEY, self->mWhiteListList, "LLScrollListCtrl" },
{ "", NULL , "" }
};
for( int i = 0; data_set[ i ].key_name.length() > 0; ++i )
{
base_key = std::string( data_set[ i ].key_name );
tentative_key = base_key + std::string( LLPanelContents::TENTATIVE_SUFFIX );
// TODO: CP - I bet there is a better way to do this using Boost
if ( media_settings[ base_key ].isDefined() )
{
if ( data_set[ i ].ctrl_type == "LLCheckBoxCtrl" )
{
static_cast< LLCheckBoxCtrl* >( data_set[ i ].ctrl_ptr )->
setValue( media_settings[ base_key ].asBoolean() );
}
else
if ( data_set[ i ].ctrl_type == "LLScrollListCtrl" )
{
// get control
LLScrollListCtrl* list = static_cast< LLScrollListCtrl* >( data_set[ i ].ctrl_ptr );
list->deleteAllItems();
// points to list of white list URLs
LLSD url_list = media_settings[ base_key ];
// iterate over them and add to scroll list
LLSD::array_iterator iter = url_list.beginArray();
while( iter != url_list.endArray() )
{
// TODO: is iter guaranteed to be valid here?
std::string url = *iter;
list->addSimpleElement( url );
++iter;
};
};
data_set[ i ].ctrl_ptr->setTentative( media_settings[ tentative_key ].asBoolean() );
};
};
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsSecurity::clearValues( void* userdata )
{
LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
self->mEnableWhiteList->clear();
self->mWhiteListList->deleteAllItems();
}
////////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsSecurity::apply( void* userdata )
{
LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
// build LLSD Fragment
LLSD media_data_security;
self->getValues(media_data_security);
// this merges contents of LLSD passed in with what's there so this is ok
LLSelectMgr::getInstance()->selectionSetMediaData( media_data_security );
}
////////////////////////////////////////////////////////////////////////////////
//
void LLPanelMediaSettingsSecurity::getValues( LLSD &fill_me_in )
{
fill_me_in[LLMediaEntry::WHITELIST_ENABLE_KEY] = mEnableWhiteList->getValue();
// iterate over white list and extract items
std::vector< LLScrollListItem* > white_list_items = mWhiteListList->getAllData();
std::vector< LLScrollListItem* >::iterator iter = white_list_items.begin();
fill_me_in[LLMediaEntry::WHITELIST_KEY].clear();
while( iter != white_list_items.end() )
{
std::string white_list_url = (*iter)->getValue().asString();
fill_me_in[ LLMediaEntry::WHITELIST_KEY ].append( white_list_url );
++iter;
};
}
///////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsSecurity::addWhiteListItem(const std::string& url)
{
mWhiteListList->addSimpleElement( url );
}
///////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsSecurity::onBtnAdd( void* userdata )
{
LLFloaterReg::showInstance("whitelist_entry");
}
///////////////////////////////////////////////////////////////////////////////
// static
void LLPanelMediaSettingsSecurity::onBtnDel( void* userdata )
{
LLPanelMediaSettingsSecurity *self =(LLPanelMediaSettingsSecurity *)userdata;
self->mWhiteListList->deleteSelectedItems();
}

View File

@ -0,0 +1,64 @@
/**
* @file llpanelmediasettingssecurity.h
* @brief LLPanelMediaSettingsSecurity class definition
*
* $LicenseInfo:firstyear=2007&license=viewergpl$
*
* Copyright (c) 2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLPANELMEDIAMEDIASETTINGSSECURITY_H
#define LL_LLPANELMEDIAMEDIASETTINGSSECURITY_H
#include "llpanel.h"
class LLCheckBoxCtrl;
class LLScrollListCtrl;
class LLPanelMediaSettingsSecurity : public LLPanel
{
public:
BOOL postBuild();
virtual void draw();
static void apply(void*);
void getValues(LLSD &fill_me_in);
LLPanelMediaSettingsSecurity();
~LLPanelMediaSettingsSecurity();
static void initValues( void* userdata, const LLSD& media_settings );
static void clearValues( void* userdata );
void addWhiteListItem(const std::string& url);
private:
LLCheckBoxCtrl* mEnableWhiteList;
LLScrollListCtrl* mWhiteListList;
static void onBtnAdd(void*);
static void onBtnDel(void*);
};
#endif // LL_LLPANELMEDIAMEDIASETTINGSSECURITY_H

View File

@ -1721,13 +1721,8 @@ void LLSelectMgr::selectionSetFullbright(U8 fullbright)
getSelection()->applyToObjects(&sendfunc);
}
void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& media_url)
void LLSelectMgr::selectionSetMedia(U8 media_type)
{
U8 media_flags = LLTextureEntry::MF_NONE;
if (media_type == LLViewerObject::MEDIA_TYPE_WEB_PAGE)
{
media_flags = LLTextureEntry::MF_WEB_PAGE;
}
struct f : public LLSelectedTEFunctor
{
@ -1737,33 +1732,72 @@ void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string&
{
if (object->permModify())
{
// update viewer side color in anticipation of update from simulator
// update viewer has media
object->setTEMediaFlags(te, mMediaFlags);
}
return true;
}
} setfunc(media_flags);
} setfunc(media_type);
getSelection()->applyToTEs(&setfunc);
struct g : public LLSelectedObjectFunctor
struct f2 : public LLSelectedObjectFunctor
{
U8 media_type;
const std::string& media_url ;
g(U8 a, const std::string& b) : media_type(a), media_url(b) {}
virtual bool apply(LLViewerObject* object)
{
if (object->permModify())
{
object->sendTEUpdate();
object->setMediaType(media_type);
object->setMediaURL(media_url);
}
return true;
}
} sendfunc(media_type, media_url);
getSelection()->applyToObjects(&sendfunc);
} func2;
mSelectedObjects->applyToObjects( &func2 );
}
// This function expects media_data to be a map containing relevant
// media data name/value pairs (e.g. home_url, etc.)
void LLSelectMgr::selectionSetMediaData(const LLSD &media_data)
{
struct f : public LLSelectedTEFunctor
{
const LLSD &mMediaData;
f(const LLSD& t) : mMediaData(t) {}
bool apply(LLViewerObject* object, S32 te)
{
if (object->permModify())
{
LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
if (NULL != vo)
{
vo->syncMediaData(te, mMediaData, true/*merge*/, true/*ignore_agent*/);
}
}
return true;
}
} setfunc(media_data);
getSelection()->applyToTEs(&setfunc);
struct f2 : public LLSelectedObjectFunctor
{
virtual bool apply(LLViewerObject* object)
{
if (object->permModify())
{
LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
if (NULL != vo)
{
// Send updated media data FOR THE ENTIRE OBJECT
vo->sendMediaDataUpdate();
}
}
return true;
}
} func2;
getSelection()->applyToObjects(&func2);
}
void LLSelectMgr::selectionSetGlow(F32 glow)
{
struct f1 : public LLSelectedTEFunctor
@ -5057,7 +5091,15 @@ void LLSelectNode::selectTE(S32 te_index, BOOL selected)
{
return;
}
mTESelectMask |= 0x1 << te_index;
S32 mask = 0x1 << te_index;
if(selected)
{
mTESelectMask |= mask;
}
else
{
mTESelectMask &= ~mask;
}
mLastTESelected = te_index;
}
@ -6042,6 +6084,29 @@ bool LLObjectSelection::applyToRootNodes(LLSelectedNodeFunctor *func, bool first
return result;
}
BOOL LLObjectSelection::isMultipleTESelected()
{
BOOL te_selected = FALSE;
// ...all faces
for (LLObjectSelection::iterator iter = begin();
iter != end(); iter++)
{
LLSelectNode* nodep = *iter;
for (S32 i = 0; i < SELECT_MAX_TES; i++)
{
if(nodep->isTESelected(i))
{
if(te_selected)
{
return TRUE;
}
te_selected = TRUE;
}
}
}
return FALSE;
}
//-----------------------------------------------------------------------------
// contains()
//-----------------------------------------------------------------------------

View File

@ -307,6 +307,7 @@ public:
S32 getTECount();
S32 getRootObjectCount();
BOOL isMultipleTESelected();
BOOL contains(LLViewerObject* object);
BOOL contains(LLViewerObject* object, S32 te);
@ -504,7 +505,8 @@ public:
void selectionSetTexGen( U8 texgen );
void selectionSetShiny( U8 shiny );
void selectionSetFullbright( U8 fullbright );
void selectionSetMediaTypeAndURL( U8 media_type, const std::string& media_url );
void selectionSetMedia( U8 media_type );
void selectionSetMediaData(const LLSD &media_data); // NOTE: modifies media_data!!!
void selectionSetClickAction(U8 action);
void selectionSetIncludeInSearch(bool include_in_search);
void selectionSetGlow(const F32 glow);

View File

@ -433,6 +433,11 @@ void LLSpatialGroup::clearDrawMap()
mDrawMap.clear();
}
BOOL LLSpatialGroup::isRecentlyVisible() const
{
return (LLDrawable::getCurrentFrame() - (S32)mVisible) < LLDrawable::getMinVisFrameRange() ;
}
BOOL LLSpatialGroup::isVisible() const
{
return mVisible[LLViewerCamera::sCurCameraID] == LLDrawable::getCurrentFrame() ? TRUE : FALSE;

View File

@ -267,6 +267,7 @@ public:
BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);
BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
BOOL isVisible() const;
BOOL isRecentlyVisible() const;
void setVisible();
void shift(const LLVector3 &offset);
BOOL boundObjects(BOOL empty, LLVector3& newMin, LLVector3& newMax);

View File

@ -67,18 +67,20 @@ LLTool::~LLTool()
BOOL LLTool::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
{
// This is necessary to force clicks in the world to cause edit
// boxes that might have keyboard focus to relinquish it, and hence
// cause a commit to update their value. JC
if (down)
BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
// This behavior was moved here from LLViewerWindow::handleAnyMouseClick, so it can be selectively overridden by LLTool subclasses.
if(down && result)
{
// This is necessary to force clicks in the world to cause edit
// boxes that might have keyboard focus to relinquish it, and hence
// cause a commit to update their value. JC
gFocusMgr.setKeyboardFocus(NULL);
}
return LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
return result;
}
BOOL LLTool::handleMouseDown(S32 x, S32 y, MASK mask)
{
if (gDebugClicks)

View File

@ -48,6 +48,7 @@
#include "lltooltip.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
#include "llmediaentry.h"
#include "llmenugl.h"
#include "llmutelist.h"
#include "llselectmgr.h"
@ -75,8 +76,6 @@ extern void handle_buy(void*);
extern BOOL gDebugClicks;
static bool handle_media_click(const LLPickInfo& info);
static bool handle_media_hover(const LLPickInfo& info);
static void handle_click_action_play();
static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp);
static ECursorType cursor_from_parcel_media(U8 click_action);
@ -90,6 +89,16 @@ LLToolPie::LLToolPie()
{ }
BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down)
{
BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
// This override DISABLES the keyboard focus reset that LLTool::handleAnyMouseClick adds.
// LLToolPie will do the right thing in its pick callback.
return result;
}
BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
{
//left mouse down always picks transparent
@ -258,9 +267,9 @@ BOOL LLToolPie::pickLeftMouseDownCallback()
}
}
if (handle_media_click(mPick))
if (handleMediaClick(mPick))
{
return FALSE;
return TRUE;
}
// put focus back "in world"
@ -466,10 +475,7 @@ void LLToolPie::selectionPropertiesReceived()
BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
{
mHoverPick = gViewerWindow->pickImmediate(x, y, FALSE);
// FIXME: This was in the pluginapi branch, but I don't think it's correct.
// gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
LLViewerObject *parent = NULL;
LLViewerObject *object = mHoverPick.getObject();
@ -484,7 +490,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
gViewerWindow->setCursor(cursor);
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
}
else if (handle_media_hover(mHoverPick))
else if (handleMediaHover(mHoverPick))
{
// cursor set by media object
lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
@ -522,6 +528,9 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
{
LLViewerObject* obj = mPick.getObject();
handleMediaMouseUp();
U8 click_action = final_click_action(obj);
if (click_action != CLICK_ACTION_NONE)
{
@ -543,6 +552,7 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
break;
}
}
mGrabMouseButtonDown = FALSE;
LLToolMgr::getInstance()->clearTransientTool();
gAgent.setLookAt(LOOKAT_TARGET_CONVERSATION, obj); // maybe look at object/person clicked on
@ -1038,6 +1048,7 @@ void LLToolPie::stopEditing()
void LLToolPie::onMouseCaptureLost()
{
mMouseOutsideSlop = FALSE;
handleMediaMouseUp();
}
@ -1078,7 +1089,7 @@ static void handle_click_action_play()
}
}
static bool handle_media_click(const LLPickInfo& pick)
bool LLToolPie::handleMediaClick(const LLPickInfo& pick)
{
//FIXME: how do we handle object in different parcel than us?
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
@ -1104,22 +1115,25 @@ static bool handle_media_click(const LLPickInfo& pick)
// is media playing on this face?
const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
LLMediaEntry* mep = (tep->hasMedia()) ? tep->getMediaData() : NULL;
viewer_media_t media_impl = mep ? LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID()) : NULL;
viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
if (tep
&& media_impl.notNull()
&& media_impl->hasMedia()
&& gSavedSettings.getBOOL("MediaOnAPrimUI"))
if (tep
&& mep
&& gSavedSettings.getBOOL("MediaOnAPrimUI")
&& media_impl.notNull())
{
LLObjectSelectionHandle selection = LLViewerMediaFocus::getInstance()->getSelection();
if (! selection->contains(pick.getObject(), pick.mObjectFace))
// LLObjectSelectionHandle selection = /*LLViewerMediaFocus::getInstance()->getSelection()*/ LLSelectMgr::getInstance()->getSelection();
if (/*! selection->contains(pick.getObject(), pick.mObjectFace)*/
! LLViewerMediaFocus::getInstance()->isFocusedOnFace(pick.getObject(), pick.mObjectFace) )
{
LLViewerMediaFocus::getInstance()->setFocusFace(TRUE, pick.getObject(), pick.mObjectFace, media_impl);
}
else
{
media_impl->mouseDown(pick.mXYCoords.mX, pick.mXYCoords.mY);
media_impl->mouseCapture(); // the mouse-up will happen when capture is lost
media_impl->mouseDown(pick.mUVCoords);
mMediaMouseCaptureID = mep->getMediaID();
setMouseCapture(TRUE); // This object will send a mouse-up to the media when it loses capture.
}
return true;
@ -1131,7 +1145,7 @@ static bool handle_media_click(const LLPickInfo& pick)
return false;
}
static bool handle_media_hover(const LLPickInfo& pick)
bool LLToolPie::handleMediaHover(const LLPickInfo& pick)
{
//FIXME: how do we handle object in different parcel than us?
LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
@ -1156,15 +1170,20 @@ static bool handle_media_hover(const LLPickInfo& pick)
// is media playing on this face?
const LLTextureEntry* tep = objectp->getTE(pick.mObjectFace);
viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(tep->getID());
if (tep
&& media_impl.notNull()
&& media_impl->hasMedia()
const LLMediaEntry* mep = tep->hasMedia() ? tep->getMediaData() : NULL;
if (mep
&& gSavedSettings.getBOOL("MediaOnAPrimUI"))
{
if(LLViewerMediaFocus::getInstance()->getFocus())
{
viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mep->getMediaID());
if(LLViewerMediaFocus::getInstance()->getFocus() && media_impl.notNull())
{
media_impl->mouseMove(pick.mXYCoords.mX, pick.mXYCoords.mY);
media_impl->mouseMove(pick.mUVCoords);
gViewerWindow->setCursor(media_impl->getLastSetCursor());
}
else
{
gViewerWindow->setCursor(UI_CURSOR_ARROW);
}
// Set mouse over flag if unset
@ -1182,6 +1201,28 @@ static bool handle_media_hover(const LLPickInfo& pick)
return false;
}
bool LLToolPie::handleMediaMouseUp()
{
bool result = false;
if(mMediaMouseCaptureID.notNull())
{
// Face media needs to know the mouse went up.
viewer_media_t media_impl = LLViewerMedia::getMediaImplFromTextureID(mMediaMouseCaptureID);
if(media_impl)
{
// This will send a mouseUp event to the plugin using the last known mouse coordinate (from a mouseDown or mouseMove), which is what we want.
media_impl->onMouseCaptureLost();
}
mMediaMouseCaptureID.setNull();
setMouseCapture(FALSE);
result = true;
}
return result;
}
static void handle_click_action_open_media(LLPointer<LLViewerObject> objectp)
{

View File

@ -42,9 +42,12 @@ class LLObjectSelection;
class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
{
LOG_CLASS(LLToolPie);
public:
LLToolPie( );
// Virtual functions inherited from LLMouseHandler
virtual BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down);
virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
@ -81,9 +84,15 @@ private:
BOOL useClickAction (MASK mask, LLViewerObject* object,LLViewerObject* parent);
void showVisualContextMenuEffect();
bool handleMediaClick(const LLPickInfo& info);
bool handleMediaHover(const LLPickInfo& info);
bool handleMediaMouseUp();
private:
BOOL mGrabMouseButtonDown;
BOOL mMouseOutsideSlop; // for this drag, has mouse moved outside slop region
LLUUID mMediaMouseCaptureID;
LLPickInfo mPick;
LLPickInfo mHoverPick;
LLPointer<LLViewerObject> mClickActionObject;

View File

@ -67,6 +67,7 @@
#include "llfloaterhardwaresettings.h"
#include "llfloaterhelpbrowser.h"
#include "llfloatermediabrowser.h"
#include "llfloatermediasettings.h"
#include "llfloaterhud.h"
#include "llfloaterimagepreview.h"
#include "llimfloater.h"
@ -105,6 +106,7 @@
#include "llfloaterurldisplay.h"
#include "llfloatervoicedevicesettings.h"
#include "llfloaterwater.h"
#include "llfloaterwhitelistentry.h"
#include "llfloaterwindlight.h"
#include "llfloaterworldmap.h"
#include "llinspectavatar.h"
@ -178,6 +180,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>);
LLFloaterReg::add("media_browser", "floater_media_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaBrowser>);
LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaSettings>);
LLFloaterReg::add("message_critical", "floater_critical.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
LLFloaterReg::add("message_tos", "floater_tos.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTOS>);
LLFloaterReg::add("moveview", "floater_moveview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMove>);
@ -238,6 +241,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("voice_call", "floater_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCall>);
LLFloaterReg::add("whitelist_entry", "floater_whitelist_entry.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWhiteListEntry>);
LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWorldMap>);
// *NOTE: Please keep these alphabetized for easier merges

File diff suppressed because it is too large Load Diff

View File

@ -41,9 +41,13 @@
#include "llviewermediaobserver.h"
#include "llpluginclassmedia.h"
class LLViewerMediaImpl;
class LLUUID;
class LLViewerMediaTexture;
class LLMediaEntry;
class LLVOVolume ;
typedef LLPointer<LLViewerMediaImpl> viewer_media_t;
///////////////////////////////////////////////////////////////////////////////
@ -55,7 +59,7 @@ public:
bool addObserver( LLViewerMediaObserver* subject );
bool remObserver( LLViewerMediaObserver* subject );
void emitEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent event);
virtual void emitEvent(LLPluginClassMedia* self, LLViewerMediaObserver::EMediaEvent event);
private:
typedef std::list< LLViewerMediaObserver* > observerListType;
@ -69,15 +73,13 @@ class LLViewerMedia
// Special case early init for just web browser component
// so we can show login screen. See .cpp file for details. JC
static viewer_media_t newMediaImpl(const std::string& media_url,
const LLUUID& texture_id,
S32 media_width,
S32 media_height,
U8 media_auto_scale,
U8 media_loop,
std::string mime_type = "none/none");
static viewer_media_t newMediaImpl(const LLUUID& texture_id,
S32 media_width = 0,
S32 media_height = 0,
U8 media_auto_scale = false,
U8 media_loop = false);
static void removeMedia(LLViewerMediaImpl* media);
static viewer_media_t updateMediaImpl(LLMediaEntry* media_entry, const std::string& previous_url, bool update_from_self);
static LLViewerMediaImpl* getMediaImplFromTextureID(const LLUUID& texture_id);
static std::string getCurrentUserAgent();
static void updateBrowserUserAgent();
@ -102,15 +104,18 @@ class LLViewerMediaImpl
LOG_CLASS(LLViewerMediaImpl);
public:
LLViewerMediaImpl(const std::string& media_url,
LLViewerMediaImpl(
const LLUUID& texture_id,
S32 media_width,
S32 media_height,
U8 media_auto_scale,
U8 media_loop,
const std::string& mime_type);
U8 media_loop);
~LLViewerMediaImpl();
// Override inherited version from LLViewerMediaEventEmitter
virtual void emitEvent(LLPluginClassMedia* self, LLViewerMediaObserver::EMediaEvent event);
void createMediaSource();
void destroyMediaSource();
void setMediaType(const std::string& media_type);
@ -126,36 +131,44 @@ public:
void seek(F32 time);
void setVolume(F32 volume);
void focus(bool focus);
// True if the impl has user focus.
bool hasFocus() const;
void mouseDown(S32 x, S32 y);
void mouseUp(S32 x, S32 y);
void mouseMove(S32 x, S32 y);
void mouseDown(const LLVector2& texture_coords);
void mouseUp(const LLVector2& texture_coords);
void mouseMove(const LLVector2& texture_coords);
void mouseLeftDoubleClick(S32 x,S32 y );
void mouseCapture();
void navigateHome();
void navigateTo(const std::string& url, const std::string& mime_type = "", bool rediscover_type = false);
void navigateTo(const std::string& url, const std::string& mime_type = "", bool rediscover_type = false, bool server_request = false);
void navigateStop();
bool handleKeyHere(KEY key, MASK mask);
bool handleUnicodeCharHere(llwchar uni_char);
bool canNavigateForward();
bool canNavigateBack();
std::string getMediaURL() { return mMediaURL; }
std::string getMediaHomeURL() { return mHomeURL; }
std::string getHomeURL() { return mHomeURL; }
void setHomeURL(const std::string& home_url) { mHomeURL = home_url; };
std::string getMimeType() { return mMimeType; }
void scaleMouse(S32 *mouse_x, S32 *mouse_y);
void update();
void updateMovieImage(const LLUUID& image_id, BOOL active);
void updateImagesMediaStreams();
LLUUID getMediaTextureID();
void suspendUpdates(bool suspend) { mSuspendUpdates = suspend; };
void setVisible(bool visible);
bool getVisible() const { return mVisible; };
bool isMediaPlaying();
bool isMediaPaused();
bool hasMedia();
ECursorType getLastSetCursor() { return mLastSetCursor; };
// utility function to create a ready-to-use media instance from a desired media type.
static LLPluginClassMedia* newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height);
@ -191,7 +204,7 @@ public:
/*virtual*/ BOOL hasMouseCapture() { return gFocusMgr.getMouseCapture() == this; };
// Inherited from LLPluginClassMediaOwner
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, LLPluginClassMediaOwner::EMediaEvent);
/*virtual*/ void handleMediaEvent(LLPluginClassMedia* plugin, LLPluginClassMediaOwner::EMediaEvent);
// LLEditMenuHandler overrides
/*virtual*/ void cut();
@ -203,6 +216,45 @@ public:
/*virtual*/ void paste();
/*virtual*/ BOOL canPaste() const;
void addObject(LLVOVolume* obj) ;
void removeObject(LLVOVolume* obj) ;
const std::list< LLVOVolume* >* getObjectList() const ;
void setUpdated(BOOL updated) ;
BOOL isUpdated() ;
// Updates the "interest" value in this object
void calculateInterest();
F64 getInterest() const { return mInterest; };
F64 getApproximateTextureInterest();
// Mark this object as being used in a UI panel instead of on a prim
// This will be used as part of the interest sorting algorithm.
void setUsedInUI(bool used_in_ui);
bool getUsedInUI() const { return mUsedInUI; };
F64 getCPUUsage() const;
void setPriority(LLPluginClassMedia::EPriority priority);
LLPluginClassMedia::EPriority getPriority() { return mPriority; };
void setLowPrioritySizeLimit(int size);
typedef enum
{
MEDIANAVSTATE_NONE, // State is outside what we need to track for navigation.
MEDIANAVSTATE_BEGUN, // a MEDIA_EVENT_NAVIGATE_BEGIN has been received which was not server-directed
MEDIANAVSTATE_FIRST_LOCATION_CHANGED, // first LOCATION_CHANGED event after a non-server-directed BEGIN
MEDIANAVSTATE_SERVER_SENT, // server-directed nav has been requested, but MEDIA_EVENT_NAVIGATE_BEGIN hasn't been received yet
MEDIANAVSTATE_SERVER_BEGUN, // MEDIA_EVENT_NAVIGATE_BEGIN has been received which was server-directed
MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED // first LOCATION_CHANGED event after a server-directed BEGIN
}EMediaNavState;
// Returns the current nav state of the media.
// note that this will be updated BEFORE listeners and objects receive media messages
EMediaNavState getNavState() { return mMediaNavState; }
void setNavState(EMediaNavState state);
public:
// a single media url with some data and an impl.
LLPluginClassMedia* mMediaSource;
@ -220,8 +272,20 @@ public:
bool mNeedsNewTexture;
bool mSuspendUpdates;
bool mVisible;
ECursorType mLastSetCursor;
EMediaNavState mMediaNavState;
F64 mInterest;
bool mUsedInUI;
bool mHasFocus;
LLPluginClassMedia::EPriority mPriority;
bool mDoNavigateOnLoad;
bool mDoNavigateOnLoadServerRequest;
private:
BOOL mIsUpdated ;
std::list< LLVOVolume* > mObjectList ;
private:
LLViewerMediaTexture *updatePlaceholderImage();
};

View File

@ -47,6 +47,7 @@
#include "llparcel.h"
#include "llviewerparcelmgr.h"
#include "llweb.h"
#include "llmediaentry.h"
//
// LLViewerMediaFocus
//
@ -91,14 +92,38 @@ void LLViewerMediaFocus::cleanupClass()
void LLViewerMediaFocus::setFocusFace( BOOL b, LLPointer<LLViewerObject> objectp, S32 face, viewer_media_t media_impl )
{
LLParcel *parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
if(mMediaImpl.notNull())
{
mMediaImpl->focus(false);
}
if (b && media_impl.notNull())
{
bool face_auto_zoom = false;
mMediaImpl = media_impl;
mMediaImpl->focus(true);
LLSelectMgr::getInstance()->deselectAll();
LLSelectMgr::getInstance()->selectObjectOnly(objectp, face);
if(objectp.notNull())
{
LLTextureEntry* tep = objectp->getTE(face);
if(! tep->hasMedia())
{
// Error condition
}
LLMediaEntry* mep = tep->getMediaData();
face_auto_zoom = mep->getAutoZoom();
if(! mep->getAutoPlay())
{
std::string url = mep->getCurrentURL().empty() ? mep->getHomeURL() : mep->getCurrentURL();
media_impl->navigateTo(url, "", true);
}
}
mFocus = LLSelectMgr::getInstance()->getSelection();
if(mMediaHUD.get() && ! parcel->getMediaPreventCameraZoom())
if(mMediaHUD.get() && face_auto_zoom && ! parcel->getMediaPreventCameraZoom())
{
mMediaHUD.get()->resetZoomLevel();
mMediaHUD.get()->nextZoomLevel();
@ -108,6 +133,7 @@ void LLViewerMediaFocus::setFocusFace( BOOL b, LLPointer<LLViewerObject> objectp
gFocusMgr.setKeyboardFocus(this);
}
mObjectID = objectp->getID();
mObjectFace = face;
// LLViewerMedia::addObserver(this, mObjectID);
@ -133,6 +159,8 @@ void LLViewerMediaFocus::setFocusFace( BOOL b, LLPointer<LLViewerObject> objectp
// and null out the media impl
mMediaImpl = NULL;
mObjectID = LLUUID::null;
mObjectFace = 0;
}
if(mMediaHUD.get())
{
@ -230,6 +258,12 @@ void LLViewerMediaFocus::setMouseOverFlag(bool b, viewer_media_t media_impl)
gHUDView->addChild(media_hud);
}
mMediaHUD.get()->setMediaImpl(media_impl);
if(mMediaImpl.notNull() && (mMediaImpl != media_impl))
{
mMediaImpl->focus(false);
}
mMediaImpl = media_impl;
}
mMouseOverFlag = b;
@ -356,3 +390,8 @@ F32 LLViewerMediaFocus::getBBoxAspectRatio(const LLBBox& bbox, const LLVector3&
// Return the aspect ratio.
return *width / *height;
}
bool LLViewerMediaFocus::isFocusedOnFace(LLPointer<LLViewerObject> objectp, S32 face)
{
return objectp->getID() == mObjectID && face == mObjectFace;
}

View File

@ -72,6 +72,9 @@ public:
void setPickInfo(LLPickInfo pick_info) { mPickInfo = pick_info; }
F32 getBBoxAspectRatio(const LLBBox& bbox, const LLVector3& normal, F32* height, F32* width, F32* depth);
// TODO: figure out why selection mgr hates me
bool isFocusedOnFace(LLPointer<LLViewerObject> objectp, S32 face);
protected:
/*virtual*/ void onFocusReceived();
/*virtual*/ void onFocusLost();
@ -83,6 +86,7 @@ private:
LLPickInfo mPickInfo;
LLHandle<LLPanelMediaHUD> mMediaHUD;
LLUUID mObjectID;
S32 mObjectFace;
viewer_media_t mMediaImpl;
};

View File

@ -47,6 +47,7 @@
#include "llframetimer.h"
#include "llinventory.h"
#include "llmaterialtable.h"
#include "llmediadataresponder.h"
#include "llmutelist.h"
#include "llnamevalue.h"
#include "llprimitive.h"
@ -100,6 +101,8 @@
#include "llvowlsky.h"
#include "llmanip.h"
#include "lltrans.h"
#include "llsdutil.h"
#include "llmediaentry.h"
//#define DEBUG_UPDATE_TYPE
@ -470,6 +473,7 @@ void LLViewerObject::cleanupVOClasses()
LLVOWater::cleanupClass();
LLVOTree::cleanupClass();
LLVOAvatar::cleanupClass();
LLVOVolume::cleanupClass();
}
// Replaces all name value pairs with data from \n delimited list
@ -700,6 +704,42 @@ void LLViewerObject::hideExtraDisplayItems( BOOL hidden )
}
}
U32 LLViewerObject::checkMediaURL(const std::string &media_url)
{
U32 retval = (U32)0x0;
if (!mMedia && !media_url.empty())
{
retval |= MEDIA_URL_ADDED;
mMedia = new LLViewerObjectMedia;
mMedia->mMediaURL = media_url;
mMedia->mMediaType = LLViewerObject::MEDIA_SET;
mMedia->mPassedWhitelist = FALSE;
}
else if (mMedia)
{
if (media_url.empty())
{
retval |= MEDIA_URL_REMOVED;
delete mMedia;
mMedia = NULL;
}
else if (mMedia->mMediaURL != media_url) // <-- This is an optimization. If they are equal don't bother with below's test.
{
/*if (! (LLTextureEntry::getAgentIDFromMediaVersionString(media_url) == gAgent.getID() &&
LLTextureEntry::getVersionFromMediaVersionString(media_url) ==
LLTextureEntry::getVersionFromMediaVersionString(mMedia->mMediaURL) + 1))
*/
{
// If the media URL is different and WE were not the one who
// changed it, mark dirty.
retval |= MEDIA_URL_UPDATED;
}
mMedia->mMediaURL = media_url;
mMedia->mPassedWhitelist = FALSE;
}
}
return retval;
}
U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
@ -1045,35 +1085,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
std::string media_url;
mesgsys->getStringFast(_PREHASH_ObjectData, _PREHASH_MediaURL, media_url, block_num);
//if (!media_url.empty())
//{
// llinfos << "WEBONPRIM media_url " << media_url << llendl;
//}
if (!mMedia && !media_url.empty())
{
retval |= MEDIA_URL_ADDED;
mMedia = new LLViewerObjectMedia;
mMedia->mMediaURL = media_url;
mMedia->mMediaType = LLViewerObject::MEDIA_TYPE_WEB_PAGE;
mMedia->mPassedWhitelist = FALSE;
}
else if (mMedia)
{
if (media_url.empty())
{
retval |= MEDIA_URL_REMOVED;
delete mMedia;
mMedia = NULL;
}
else if (mMedia->mMediaURL != media_url)
{
// We just added or changed a web page.
retval |= MEDIA_URL_UPDATED;
mMedia->mMediaURL = media_url;
mMedia->mPassedWhitelist = FALSE;
}
}
retval |= checkMediaURL(media_url);
//
// Unpack particle system data
//
@ -1456,31 +1469,12 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
mText = NULL;
}
std::string media_url;
if (value & 0x200)
{
std::string media_url;
dp->unpackString(media_url, "MediaURL");
if (!mMedia)
{
retval |= MEDIA_URL_ADDED;
mMedia = new LLViewerObjectMedia;
mMedia->mMediaURL = media_url;
mMedia->mMediaType = LLViewerObject::MEDIA_TYPE_WEB_PAGE;
mMedia->mPassedWhitelist = FALSE;
}
else if (mMedia->mMediaURL != media_url)
{
retval |= MEDIA_URL_UPDATED;
mMedia->mMediaURL = media_url;
mMedia->mPassedWhitelist = FALSE;
}
}
else if (mMedia)
{
retval |= MEDIA_URL_REMOVED;
delete mMedia;
mMedia = NULL;
}
retval |= checkMediaURL(media_url);
//
// Unpack particle system data
@ -3472,7 +3466,7 @@ U8 LLViewerObject::getMediaType() const
}
else
{
return LLViewerObject::MEDIA_TYPE_NONE;
return LLViewerObject::MEDIA_NONE;
}
}
@ -3734,16 +3728,13 @@ S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost hos
}
void LLViewerObject::changeTEImage(const LLViewerTexture* old_image, LLViewerTexture* new_image)
void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
{
U32 end = getNumTEs() ;
for (U32 face = 0 ; face < end ; face++)
if(index < 0 || index >= getNumTEs())
{
if(old_image == mTEImages[face])
{
mTEImages[face] = new_image ;
}
return ;
}
mTEImages[index] = new_image ;
}
S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)

View File

@ -158,10 +158,16 @@ public:
virtual BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
// Types of media we can associate
enum { MEDIA_TYPE_NONE = 0, MEDIA_TYPE_WEB_PAGE = 1 };
enum { MEDIA_NONE = 0, MEDIA_SET = 1 };
// Return codes for processUpdateMessage
enum { MEDIA_URL_REMOVED = 0x1, MEDIA_URL_ADDED = 0x2, MEDIA_URL_UPDATED = 0x4, INVALID_UPDATE = 0x80000000 };
enum {
MEDIA_URL_REMOVED = 0x1,
MEDIA_URL_ADDED = 0x2,
MEDIA_URL_UPDATED = 0x4,
MEDIA_FLAGS_CHANGED = 0x8,
INVALID_UPDATE = 0x80000000
};
virtual U32 processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
@ -318,7 +324,7 @@ public:
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
/*virtual*/ BOOL setMaterial(const U8 material);
virtual void setTEImage(const U8 te, LLViewerTexture *imagep); // Not derived from LLPrimitive
void changeTEImage(const LLViewerTexture* old_image, LLViewerTexture* new_image) ;
void changeTEImage(S32 index, LLViewerTexture* new_image) ;
LLViewerTexture *getTEImage(const U8 te) const;
void fitFaceTexture(const U8 face);
@ -504,6 +510,10 @@ private:
ExtraParameter* getExtraParameterEntry(U16 param_type) const;
ExtraParameter* getExtraParameterEntryCreate(U16 param_type);
bool unpackParameterEntry(U16 param_type, LLDataPacker *dp);
// This function checks to see if the given media URL has changed its version
// and the update wasn't due to this agent's last action.
U32 checkMediaURL(const std::string &media_url);
public:
//

View File

@ -46,6 +46,7 @@
#include "llnotifications.h"
#include "llfirstuse.h"
#include "llpluginclassmedia.h"
#include "llviewertexture.h"
// Static Variables
@ -219,17 +220,25 @@ void LLViewerParcelMedia::play(LLParcel* parcel)
// Delete the old one first so they don't fight over the texture.
sMediaImpl->stop();
sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id,
media_width, media_height, media_auto_scale,
sMediaImpl = LLViewerMedia::newMediaImpl(
placeholder_texture_id,
media_width,
media_height,
media_auto_scale,
media_loop);
sMediaImpl->navigateTo(media_url);
}
}
else
{
// There is no media impl, make a new one
sMediaImpl = LLViewerMedia::newMediaImpl(media_url, placeholder_texture_id,
media_width, media_height, media_auto_scale,
sMediaImpl = LLViewerMedia::newMediaImpl(
placeholder_texture_id,
media_width,
media_height,
media_auto_scale,
media_loop);
sMediaImpl->navigateTo(media_url);
}
LLFirstUse::useMedia();

View File

@ -1428,6 +1428,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
capabilityNames.append("EventQueueGet");
capabilityNames.append("FetchInventory");
capabilityNames.append("WebFetchInventoryDescendents");
capabilityNames.append("ObjectMedia");
capabilityNames.append("ObjectMediaNavigate");
capabilityNames.append("FetchLib");
capabilityNames.append("FetchLibDescendents");
capabilityNames.append("GroupProposalBallot");

View File

@ -62,6 +62,10 @@
#include "llappviewer.h"
#include "lltextureatlas.h"
#include "lltextureatlasmanager.h"
#include "lltextureentry.h"
#include "llmediaentry.h"
#include "llvovolume.h"
#include "llviewermedia.h"
///////////////////////////////////////////////////////////////////////////////
// statics
@ -114,45 +118,18 @@ LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id)
LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id)
{
LLViewerMediaTexture::media_map_t::iterator iter = LLViewerMediaTexture::sMediaMap.find(media_id);
if(iter == LLViewerMediaTexture::sMediaMap.end())
return NULL;
((LLViewerMediaTexture*)(iter->second))->getLastReferencedTimer()->reset() ;
return iter->second;
return LLViewerMediaTexture::findMediaTexture(media_id) ;
}
LLViewerMediaTexture* LLViewerTextureManager::getMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image)
{
LLViewerMediaTexture* tex = LLViewerTextureManager::findMediaTexture(id) ;
LLViewerMediaTexture* tex = LLViewerMediaTexture::findMediaTexture(id) ;
if(!tex)
{
tex = LLViewerTextureManager::createMediaTexture(id, usemipmaps, gl_image) ;
}
LLViewerTexture* old_tex = tex->getOldTexture() ;
if(!old_tex)
{
//if there is a fetched texture with the same id, replace it by this media texture
old_tex = gTextureList.findImage(id) ;
if(old_tex)
{
tex->setOldTexture(old_tex) ;
}
}
if (gSavedSettings.getBOOL("ParcelMediaAutoPlayEnable") && gSavedSettings.getBOOL("AudioStreamingVideo"))
{
if(!tex->isPlaying())
{
if(old_tex)
{
old_tex->switchToTexture(tex) ;
}
tex->setPlaying(TRUE) ;
}
}
tex->getLastReferencedTimer()->reset() ;
tex->initVirtualSize() ;
return tex ;
}
@ -303,7 +280,7 @@ void LLViewerTextureManager::cleanup()
LLViewerFetchedTexture::sMissingAssetImagep = NULL;
LLViewerFetchedTexture::sWhiteImagep = NULL;
LLViewerMediaTexture::sMediaMap.clear() ;
LLViewerMediaTexture::cleanup() ;
}
//----------------------------------------------------------------------------------------------
@ -437,6 +414,7 @@ void LLViewerTexture::init(bool firstinit)
mTextureState = NO_DELETE ;
mDontDiscard = FALSE;
mMaxVirtualSize = 0.f;
mNeedsResetMaxVirtualSize = FALSE ;
}
//virtual
@ -538,33 +516,24 @@ void LLViewerTexture::resetTextureStats(BOOL zero)
}
}
//virtual
F32 LLViewerTexture::getMaxVirtualSize()
{
return mMaxVirtualSize ;
}
//virtual
void LLViewerTexture::addFace(LLFace* facep)
{
mFaceList.push_back(facep) ;
}
//virtual
void LLViewerTexture::removeFace(LLFace* facep)
{
mFaceList.remove(facep) ;
}
void LLViewerTexture::switchToTexture(LLViewerTexture* new_texture)
{
if(this == new_texture)
{
return ;
}
new_texture->addTextureStats(getMaxVirtualSize()) ;
for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); )
{
LLFace* facep = *iter++ ;
facep->setTexture(new_texture) ;
facep->getViewerObject()->changeTEImage(this, new_texture) ;
gPipeline.markTextured(facep->getDrawable());
}
}
void LLViewerTexture::forceActive()
{
mTextureState = ACTIVE ;
@ -613,7 +582,16 @@ BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* image
{
llassert_always(mGLTexturep.notNull()) ;
return mGLTexturep->createGLTexture(discard_level, imageraw, usename) ;
BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename) ;
if(ret)
{
mFullWidth = mGLTexturep->getCurrentWidth() ;
mFullHeight = mGLTexturep->getCurrentHeight() ;
mComponents = mGLTexturep->getComponents() ;
}
return ret ;
}
void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
@ -2142,18 +2120,59 @@ void LLViewerMediaTexture::updateClass()
for(media_map_t::iterator iter = sMediaMap.begin() ; iter != sMediaMap.end(); )
{
LLViewerMediaTexture* mediap = iter->second;
++iter ;
LLViewerMediaTexture* mediap = iter->second;
//
//Note: delay some time to delete the media textures to stop endlessly creating and immediately removing media texture.
//
if(mediap->getNumRefs() == 1 && mediap->getLastReferencedTimer()->getElapsedTimeF32() > MAX_INACTIVE_TIME) //one by sMediaMap
{
sMediaMap.erase(mediap->getID()) ;
media_map_t::iterator cur = iter++ ;
sMediaMap.erase(cur) ;
}
else
{
++iter ;
}
}
}
//static
void LLViewerMediaTexture::removeMediaImplFromTexture(const LLUUID& media_id)
{
LLViewerMediaTexture* media_tex = findMediaTexture(media_id) ;
if(media_tex)
{
media_tex->invalidateMediaImpl() ;
}
}
//static
void LLViewerMediaTexture::cleanup()
{
sMediaMap.clear() ;
}
//static
LLViewerMediaTexture* LLViewerMediaTexture::findMediaTexture(const LLUUID& media_id)
{
media_map_t::iterator iter = sMediaMap.find(media_id);
if(iter == sMediaMap.end())
{
return NULL;
}
LLViewerMediaTexture* media_tex = iter->second ;
media_tex->setMediaImpl() ;
media_tex->getLastReferencedTimer()->reset() ;
return media_tex;
}
LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image)
: LLViewerTexture(id, usemipmaps)
: LLViewerTexture(id, usemipmaps),
mMediaImplp(NULL),
mUpdateVirtualSizeTime(0)
{
sMediaMap.insert(std::make_pair(id, this));
@ -2165,6 +2184,13 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL
mGLTexturep->setNeedsAlphaAndPickMask(FALSE) ;
mIsPlaying = FALSE ;
setMediaImpl() ;
}
//virtual
LLViewerMediaTexture::~LLViewerMediaTexture()
{
}
void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */)
@ -2172,7 +2198,6 @@ void LLViewerMediaTexture::reinit(BOOL usemipmaps /* = TRUE */)
mGLTexturep = NULL ;
init(false);
mUseMipMaps = usemipmaps ;
mIsPlaying = FALSE ;
getLastReferencedTimer()->reset() ;
generateGLTexture() ;
@ -2195,14 +2220,336 @@ S8 LLViewerMediaTexture::getType() const
return LLViewerTexture::MEDIA_TEXTURE ;
}
void LLViewerMediaTexture::setOldTexture(LLViewerTexture* tex)
void LLViewerMediaTexture::invalidateMediaImpl()
{
mOldTexturep = tex ;
mMediaImplp = NULL ;
}
void LLViewerMediaTexture::setMediaImpl()
{
if(!mMediaImplp)
{
mMediaImplp = LLViewerMedia::getMediaImplFromTextureID(mID) ;
}
}
//return true if all faces to reference to this media texture are found
//Note: mMediaFaceList is valid only for the current instant
// because it does not check the face validity after the current frame.
BOOL LLViewerMediaTexture::findFaces()
{
mMediaFaceList.clear() ;
BOOL ret = TRUE ;
//for parcel media
LLViewerTexture* tex = gTextureList.findImage(mID) ;
if(tex)
{
const ll_face_list_t* face_list = tex->getFaceList() ;
for(ll_face_list_t::const_iterator iter = face_list->begin(); iter != face_list->end(); ++iter)
{
mMediaFaceList.push_back(*iter) ;
}
}
if(!mMediaImplp)
{
return TRUE ;
}
//for media on a face.
const std::list< LLVOVolume* >* obj_list = mMediaImplp->getObjectList() ;
std::list< LLVOVolume* >::const_iterator iter = obj_list->begin() ;
for(; iter != obj_list->end(); ++iter)
{
LLVOVolume* obj = *iter ;
if(obj->mDrawable.isNull())
{
ret = FALSE ;
continue ;
}
S32 face_id = -1 ;
while((face_id = obj->getFaceIndexWithMediaImpl(mMediaImplp, face_id)) > -1)
{
LLFace* facep = obj->mDrawable->getFace(face_id) ;
if(facep)
{
mMediaFaceList.push_back(facep) ;
}
else
{
ret = FALSE ;
}
}
}
return ret ;
}
void LLViewerMediaTexture::initVirtualSize()
{
if(mIsPlaying)
{
return ;
}
findFaces() ;
for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
{
addTextureStats((*iter)->getVirtualSize()) ;
}
}
void LLViewerMediaTexture::addMediaToFace(LLFace* facep)
{
if(!mIsPlaying)
{
return ; //no need to add the face because the media is not in playing.
}
switchTexture(facep) ;
}
LLViewerTexture* LLViewerMediaTexture::getOldTexture() const
void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)
{
return mOldTexturep ;
if(!mIsPlaying)
{
return ; //no need to remove the face because the media is not in playing.
}
if(!facep)
{
return ;
}
mIsPlaying = FALSE ; //set to remove the media from the face.
switchTexture(facep) ;
mIsPlaying = TRUE ; //set the flag back.
if(mFaceList.empty()) //no face referencing to this media
{
stopPlaying() ;
}
}
//virtual
void LLViewerMediaTexture::addFace(LLFace* facep)
{
LLViewerTexture::addFace(facep) ;
const LLTextureEntry* te = facep->getTextureEntry() ;
if(te)
{
LLViewerTexture* tex = gTextureList.findImage(te->getID()) ;
if(tex)
{
mTextureList.push_back(tex) ;//increase the reference number by one for tex to avoid deleting it.
return ;
}
}
llerrs << "The face does not have a valid texture before media texture." << llendl ;
}
//virtual
void LLViewerMediaTexture::removeFace(LLFace* facep)
{
LLViewerTexture::removeFace(facep) ;
const LLTextureEntry* te = facep->getTextureEntry() ;
if(te)
{
LLViewerTexture* tex = gTextureList.findImage(te->getID()) ;
if(tex)
{
for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
iter != mTextureList.end(); ++iter)
{
if(*iter == tex)
{
mTextureList.erase(iter) ; //decrease the reference number for tex by one.
return ;
}
}
//
//we have some trouble here: the texture of the face is changed.
//we need to find the former texture, and remove it from the list to avoid memory leaking.
if(mFaceList.empty())
{
mTextureList.clear() ;
return ;
}
S32 end = mFaceList.size() ;
std::vector<const LLTextureEntry*> te_list(end) ;
S32 i = 0 ;
for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
{
te_list[i++] = (*iter)->getTextureEntry() ;//all textures are in use.
}
for(std::list< LLPointer<LLViewerTexture> >::iterator iter = mTextureList.begin();
iter != mTextureList.end(); ++iter)
{
for(i = 0 ; i < end ; i++)
{
if(te_list[i] && te_list[i]->getID() == (*iter)->getID())//the texture is in use.
{
te_list[i] = NULL ;
break ;
}
}
if(i == end) //no hit for this texture, remove it.
{
mTextureList.erase(iter) ; //decrease the reference number for tex by one.
return ;
}
}
}
}
llerrs << "mTextureList texture reference number is corrupted." << llendl ;
}
void LLViewerMediaTexture::stopPlaying()
{
if(mMediaImplp)
{
mMediaImplp->stop() ;
}
mIsPlaying = FALSE ;
}
void LLViewerMediaTexture::switchTexture(LLFace* facep)
{
if(facep)
{
//check if another media is playing on this face.
if(facep->getTexture() && facep->getTexture() != this
&& facep->getTexture()->getType() == LLViewerTexture::MEDIA_TEXTURE)
{
if(mID == facep->getTexture()->getID()) //this is a parcel media
{
return ; //let the prim media win.
}
}
if(mIsPlaying) //old textures switch to the media texture
{
facep->switchTexture(this) ;
}
else //switch to old textures.
{
const LLTextureEntry* te = facep->getTextureEntry() ;
if(te)
{
LLViewerTexture* tex = gTextureList.findImage(te->getID()) ;
facep->switchTexture(tex) ;
}
}
}
}
void LLViewerMediaTexture::setPlaying(BOOL playing)
{
if(!mMediaImplp)
{
return ;
}
if(!playing && !mIsPlaying)
{
return ; //media is already off
}
if(playing == mIsPlaying && !mMediaImplp->isUpdated())
{
return ; //nothing has changed since last time.
}
mIsPlaying = playing ;
if(mIsPlaying) //is about to play this media
{
if(findFaces())
{
//about to update all faces.
mMediaImplp->setUpdated(FALSE) ;
}
if(mMediaFaceList.empty())//no face pointing to this media
{
stopPlaying() ;
return ;
}
for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
{
switchTexture(*iter) ;
}
}
else //stop playing this media
{
if(mFaceList.empty())
{
return ;
}
ll_face_list_t::iterator cur ;
for(ll_face_list_t::iterator iter = mFaceList.begin(); iter!= mFaceList.end(); )
{
cur = iter++ ;
switchTexture(*cur) ; //cur could be removed in this function.
}
}
return ;
}
//virtual
F32 LLViewerMediaTexture::getMaxVirtualSize()
{
if(LLFrameTimer::getFrameCount() == mUpdateVirtualSizeTime)
{
return mMaxVirtualSize ;
}
mUpdateVirtualSizeTime = LLFrameTimer::getFrameCount() ;
if(mNeedsResetMaxVirtualSize)
{
mMaxVirtualSize = 0.f ;//reset
mNeedsResetMaxVirtualSize = FALSE ;
}
if(mIsPlaying) //media is playing
{
if(mFaceList.size() > 0)
{
for(std::list<LLFace*>::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter)
{
LLFace* facep = *iter ;
if(facep->getDrawable()->isRecentlyVisible())
{
addTextureStats(facep->getVirtualSize()) ;
}
}
}
}
else //media is not in playing
{
findFaces() ;
if(!mMediaFaceList.empty())
{
for(std::list< LLFace* >::iterator iter = mMediaFaceList.begin(); iter!= mMediaFaceList.end(); ++iter)
{
LLFace* facep = *iter ;
if(facep->getDrawable()->isRecentlyVisible())
{
addTextureStats(facep->getVirtualSize()) ;
}
}
}
}
mNeedsResetMaxVirtualSize = TRUE ;
return mMaxVirtualSize ;
}
//----------------------------------------------------------------------------------------------
//end of LLViewerMediaTexture

View File

@ -49,6 +49,7 @@
class LLFace;
class LLImageGL ;
class LLViewerObject;
class LLViewerTexture;
class LLViewerFetchedTexture ;
class LLViewerMediaTexture ;
@ -58,7 +59,9 @@ typedef void (*loaded_callback_func)( BOOL success, LLViewerFetchedTexture *src_
class LLVFile;
class LLMessageSystem;
class LLViewerMediaImpl ;
class LLVOVolume ;
class LLLoadedCallbackEntry
{
public:
@ -123,6 +126,8 @@ public:
BOOST_MAX_LEVEL
};
typedef std::list<LLFace*> ll_face_list_t ;
protected:
virtual ~LLViewerTexture();
LOG_CLASS(LLViewerTexture);
@ -152,16 +157,17 @@ public:
//maxVirtualSize of the texture
void addTextureStats(F32 virtual_size) const ;
void resetTextureStats(BOOL zero = FALSE);
F32 getMaxVirtualSize()const {return mMaxVirtualSize ;}
virtual F32 getMaxVirtualSize() ;
LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;}
S32 getFullWidth() const { return mFullWidth; }
S32 getFullHeight() const { return mFullHeight; }
void addFace(LLFace* facep) ;
void removeFace(LLFace* facep) ;
virtual void addFace(LLFace* facep) ;
virtual void removeFace(LLFace* facep) ;
const ll_face_list_t* getFaceList() const {return &mFaceList ;}
void generateGLTexture() ;
void destroyGLTexture() ;
@ -206,8 +212,6 @@ public:
//end of functions to access LLImageGL
//---------------------------------------------------------------------------------------------
void switchToTexture(LLViewerTexture* new_texture) ; //make all faces pointing to this texture to point to new_texture.
//-----------------
/*virtual*/ void setActive() ;
void forceActive() ;
@ -233,10 +237,9 @@ protected:
BOOL mUseMipMaps ;
S8 mComponents;
mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need?
mutable BOOL mNeedsResetMaxVirtualSize ;
LLFrameTimer mLastReferencedTimer;
typedef std::list<LLFace*> ll_face_list_t ;
ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture
//GL texture
@ -498,34 +501,61 @@ private:
class LLViewerMediaTexture : public LLViewerTexture
{
protected:
/*virtual*/ ~LLViewerMediaTexture() {}
/*virtual*/ ~LLViewerMediaTexture() ;
public:
LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps = TRUE, LLImageGL* gl_image = NULL) ;
/*virtual*/ S8 getType() const;
void reinit(BOOL usemipmaps = TRUE);
BOOL getUseMipMaps() {return mUseMipMaps ; }
void setUseMipMaps(BOOL mipmap) ;
void setOldTexture(LLViewerTexture* tex) ;
LLViewerTexture* getOldTexture() const ;
void setPlaying(BOOL playing) {mIsPlaying = playing ;}
void setUseMipMaps(BOOL mipmap) ;
void setPlaying(BOOL playing) ;
BOOL isPlaying() const {return mIsPlaying;}
void setMediaImpl() ;
void initVirtualSize() ;
void invalidateMediaImpl() ;
void addMediaToFace(LLFace* facep) ;
void removeMediaFromFace(LLFace* facep) ;
/*virtual*/ void addFace(LLFace* facep) ;
/*virtual*/ void removeFace(LLFace* facep) ;
/*virtual*/ F32 getMaxVirtualSize() ;
private:
void switchTexture(LLFace* facep) ;
BOOL findFaces() ;
void stopPlaying() ;
private:
LLPointer<LLViewerTexture> mOldTexturep ; //the texture this media texture replaces.
//
//an instant list, recording all faces referencing or can reference to this media texture.
//NOTE: it is NOT thread safe.
//
std::list< LLFace* > mMediaFaceList ;
//an instant list keeping all textures which are replaced by the current media texture,
//is only used to avoid the removal of those textures from memory.
std::list< LLPointer<LLViewerTexture> > mTextureList ;
LLViewerMediaImpl* mMediaImplp ;
BOOL mIsPlaying ;
U32 mUpdateVirtualSizeTime ;
public:
static void updateClass() ;
static void cleanup() ;
public:
static LLViewerMediaTexture* findMediaTexture(const LLUUID& media_id) ;
static void removeMediaImplFromTexture(const LLUUID& media_id) ;
private:
typedef std::map< LLUUID, LLPointer<LLViewerMediaTexture> > media_map_t ;
static media_map_t sMediaMap ;
static media_map_t sMediaMap ;
};
//just an interface class, do not create instance from this class.

View File

@ -46,6 +46,8 @@
#include "llvolumemessage.h"
#include "material_codes.h"
#include "message.h"
#include "llmediadataresponder.h"
#include "llpluginclassmedia.h" // for code in the mediaEvent handler
#include "object_flags.h"
#include "llagentconstants.h"
#include "lldrawable.h"
@ -65,6 +67,10 @@
#include "llworld.h"
#include "llselectmgr.h"
#include "pipeline.h"
#include "llsdutil.h"
#include "llmediaentry.h"
#include "llmediadatafetcher.h"
#include "llagent.h"
const S32 MIN_QUIET_FRAMES_COALESCE = 30;
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
@ -100,6 +106,8 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mLODChanged = FALSE;
mSculptChanged = FALSE;
mSpotLightPriority = 0.f;
mMediaImplList.resize(getNumTEs());
}
LLVOVolume::~LLVOVolume()
@ -108,14 +116,31 @@ LLVOVolume::~LLVOVolume()
mTextureAnimp = NULL;
delete mVolumeImpl;
mVolumeImpl = NULL;
if(!mMediaImplList.empty())
{
for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
{
if(mMediaImplList[i].notNull())
{
mMediaImplList[i]->removeObject(this) ;
}
}
}
}
// static
void LLVOVolume::initClass()
{
LLMediaDataFetcher::initClass();
}
// static
void LLVOVolume::cleanupClass()
{
LLMediaDataFetcher::cleanupClass();
}
U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
@ -123,6 +148,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
LLDataPacker *dp)
{
LLColor4U color;
const S32 teDirtyBits = (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR|TEM_CHANGE_MEDIA);
// Do base class updates...
U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
@ -190,10 +216,15 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
//
// Unpack texture entry data
//
if (unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num) & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR))
S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
if (result & teDirtyBits)
{
updateTEData();
}
if (result & TEM_CHANGE_MEDIA)
{
retval |= MEDIA_FLAGS_CHANGED;
}
}
else
{
@ -226,9 +257,16 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
// llerrs << "Bogus TE data in " << getID() << ", crashing!" << llendl;
llwarns << "Bogus TE data in " << getID() << llendl;
}
else if (res2 & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR))
else
{
updateTEData();
if (res2 & teDirtyBits)
{
updateTEData();
}
if (res2 & TEM_CHANGE_MEDIA)
{
retval |= MEDIA_FLAGS_CHANGED;
}
}
U32 value = dp->getPassFlags();
@ -266,14 +304,29 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
U8 tdpbuffer[1024];
LLDataPackerBinaryBuffer tdp(tdpbuffer, 1024);
mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_TextureEntry, tdpbuffer, 0, block_num);
if ( unpackTEMessage(tdp) & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR))
S32 result = unpackTEMessage(tdp);
if (result & teDirtyBits)
{
updateTEData();
}
if (result & TEM_CHANGE_MEDIA)
{
retval |= MEDIA_FLAGS_CHANGED;
}
}
}
}
if (retval & (MEDIA_URL_REMOVED | MEDIA_URL_ADDED | MEDIA_URL_UPDATED | MEDIA_FLAGS_CHANGED)) {
// If the media changed at all, request new media data
if(mMedia)
{
llinfos << "Media URL: " << mMedia->mMediaURL << llendl;
}
requestMediaDataUpdate();
}
// ...and clean up any media impls
cleanUpMediaImpls();
return retval;
}
@ -1327,6 +1380,46 @@ BOOL LLVOVolume::isRootEdit() const
return TRUE;
}
//virtual
void LLVOVolume::setNumTEs(const U8 num_tes)
{
const U8 old_num_tes = getNumTEs() ;
if(old_num_tes && old_num_tes < num_tes) //new faces added
{
LLViewerObject::setNumTEs(num_tes) ;
if(mMediaImplList.size() >= old_num_tes && mMediaImplList[old_num_tes -1].notNull())//duplicate the last media textures if exists.
{
mMediaImplList.resize(num_tes) ;
const LLTextureEntry* te = getTE(old_num_tes - 1) ;
for(U8 i = old_num_tes; i < num_tes ; i++)
{
setTE(i, *te) ;
mMediaImplList[i] = mMediaImplList[old_num_tes -1] ;
}
mMediaImplList[old_num_tes -1]->setUpdated(TRUE) ;
}
}
else if(old_num_tes > num_tes && mMediaImplList.size() > num_tes) //old faces removed
{
U8 end = mMediaImplList.size() ;
for(U8 i = num_tes; i < end ; i++)
{
removeMediaImpl(i) ;
}
mMediaImplList.resize(num_tes) ;
LLViewerObject::setNumTEs(num_tes) ;
}
else
{
LLViewerObject::setNumTEs(num_tes) ;
}
return ;
}
void LLVOVolume::setTEImage(const U8 te, LLViewerTexture *imagep)
{
BOOL changed = (mTEImages[te] != imagep);
@ -1510,6 +1603,321 @@ void LLVOVolume::updateTEData()
}*/
}
bool LLVOVolume::hasMedia() const
{
bool result = false;
const U8 numTEs = getNumTEs();
for (U8 i = 0; i < numTEs; i++)
{
const LLTextureEntry* te = getTE(i);
if(te->hasMedia())
{
result = true;
break;
}
}
return result;
}
void LLVOVolume::requestMediaDataUpdate()
{
LLMediaDataFetcher::fetchMedia(this);
}
void LLVOVolume::cleanUpMediaImpls()
{
// Iterate through our TEs and remove any Impls that are no longer used
const U8 numTEs = getNumTEs();
for (U8 i = 0; i < numTEs; i++)
{
const LLTextureEntry* te = getTE(i);
if( ! te->hasMedia())
{
// Delete the media IMPL!
removeMediaImpl(i) ;
}
}
}
void LLVOVolume::updateObjectMediaData(const LLSD &media_data_array)
{
// media_data_array is an array of media entry maps
//llinfos << "updating:" << this->getID() << " " << ll_pretty_print_sd(media_data_array) << llendl;
LLSD::array_const_iterator iter = media_data_array.beginArray();
LLSD::array_const_iterator end = media_data_array.endArray();
U8 texture_index = 0;
for (; iter != end; ++iter, ++texture_index)
{
syncMediaData(texture_index, *iter, false/*merge*/, false/*ignore_agent*/);
}
}
void LLVOVolume::syncMediaData(S32 texture_index, const LLSD &media_data, bool merge, bool ignore_agent)
{
LLTextureEntry *te = getTE(texture_index);
//llinfos << "BEFORE: texture_index = " << texture_index
// << " hasMedia = " << te->hasMedia() << " : "
// << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << llendl;
std::string previous_url;
LLMediaEntry* mep = te->getMediaData();
if(mep)
{
// Save the "current url" from before the update so we can tell if
// it changes.
previous_url = mep->getCurrentURL();
}
if (merge)
{
te->mergeIntoMediaData(media_data);
}
else {
// XXX Question: what if the media data is undefined LLSD, but the
// update we got above said that we have media flags?? Here we clobber
// that, assuming the data from the service is more up-to-date.
te->updateMediaData(media_data);
}
mep = te->getMediaData();
if(mep)
{
bool update_from_self = false;
if (!ignore_agent)
{
LLUUID updating_agent = LLTextureEntry::getAgentIDFromMediaVersionString(getMediaURL());
update_from_self = (updating_agent == gAgent.getID());
}
viewer_media_t media_impl = LLViewerMedia::updateMediaImpl(mep, previous_url, update_from_self);
addMediaImpl(media_impl, texture_index) ;
}
//llinfos << "AFTER: texture_index = " << texture_index
// << " hasMedia = " << te->hasMedia() << " : "
// << ((NULL == te->getMediaData()) ? "NULL MEDIA DATA" : ll_pretty_print_sd(te->getMediaData()->asLLSD())) << llendl;
}
void LLVOVolume::mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event)
{
switch(event)
{
case LLViewerMediaObserver::MEDIA_EVENT_LOCATION_CHANGED:
{
switch(impl->getNavState())
{
case LLViewerMediaImpl::MEDIANAVSTATE_FIRST_LOCATION_CHANGED:
{
// This is the first location changed event after the start of a non-server-directed nav. It may need to be broadcast.
bool block_navigation = false;
// FIXME: if/when we allow the same media impl to be used by multiple faces, the logic here will need to be fixed
// to deal with multiple face indices.
int face_index = getFaceIndexWithMediaImpl(impl, -1);
std::string new_location = plugin->getLocation();
// Find the media entry for this navigate
LLMediaEntry* mep = NULL;
LLTextureEntry *te = getTE(face_index);
if(te)
{
mep = te->getMediaData();
}
if(mep)
{
if(!mep->checkCandidateUrl(new_location))
{
block_navigation = true;
}
}
else
{
llwarns << "Couldn't find media entry!" << llendl;
}
if(block_navigation)
{
llinfos << "blocking navigate to URI " << new_location << llendl;
// "bounce back" to the current URL from the media entry
// NOTE: the only way block_navigation can be true is if we found the media entry, so we're guaranteed here that mep is not NULL.
impl->navigateTo(mep->getCurrentURL());
}
else
{
llinfos << "broadcasting navigate with URI " << new_location << llendl;
// Post the navigate to the cap
std::string cap = getRegion()->getCapability("ObjectMediaNavigate");
if(cap.empty())
{
// XXX *TODO: deal with no cap! It may happen! (retry?)
LL_WARNS("Media") << "Can't broadcast navigate event -- ObjectMediaNavigate cap is not available" << LL_ENDL;
return;
}
// If we got here, the cap is available. Index through all faces that have this media and send the navigate message.
LLSD sd;
sd["object_id"] = mID;
sd["current_url"] = new_location;
sd["texture_index"] = face_index;
LLHTTPClient::post(cap, sd, new LLMediaDataResponder("ObjectMediaNavigate", sd, this));
}
}
break;
case LLViewerMediaImpl::MEDIANAVSTATE_SERVER_FIRST_LOCATION_CHANGED:
// This is the first location changed event after the start of a server-directed nav. Don't broadcast it.
llinfos << " NOT broadcasting navigate (server-directed)" << llendl;
break;
default:
// This is a subsequent location-changed due to a redirect. Don't broadcast.
llinfos << " NOT broadcasting navigate (redirect)" << llendl;
break;
}
}
break;
default:
break;
}
}
void LLVOVolume::sendMediaDataUpdate() const
{
std::string url = getRegion()->getCapability("ObjectMedia");
if (!url.empty())
{
LLSD sd_payload;
sd_payload["verb"] = "UPDATE";
sd_payload[LLTextureEntry::OBJECT_ID_KEY] = mID;
LLSD object_media_data;
for (int i=0; i < getNumTEs(); i++) {
LLTextureEntry *texture_entry = getTE(i);
llassert((texture_entry->getMediaData() != NULL) == texture_entry->hasMedia());
const LLSD &media_data =
(texture_entry->getMediaData() == NULL) ? LLSD() : texture_entry->getMediaData()->asLLSD();
object_media_data.append(media_data);
}
sd_payload[LLTextureEntry::OBJECT_MEDIA_DATA_KEY] = object_media_data;
llinfos << "Sending media data: " << getID() << " " << ll_pretty_print_sd(sd_payload) << llendl;
LLHTTPClient::post(url, sd_payload, new LLMediaDataResponder("ObjectMedia", sd_payload, this));
}
// XXX *TODO: deal with no cap! It may happen! (retry?)
}
void LLVOVolume::removeMediaImpl(S32 texture_index)
{
if(mMediaImplList.size() <= (U32)texture_index || mMediaImplList[texture_index].isNull())
{
return ;
}
//make the face referencing to mMediaImplList[texture_index] to point back to the old texture.
if(mDrawable)
{
LLFace* facep = mDrawable->getFace(texture_index) ;
if(facep)
{
LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
if(media_tex)
{
media_tex->removeMediaFromFace(facep) ;
}
}
}
//check if some other face(s) of this object reference(s)to this media impl.
S32 i ;
S32 end = (S32)mMediaImplList.size() ;
for(i = 0; i < end ; i++)
{
if( i != texture_index && mMediaImplList[i] == mMediaImplList[texture_index])
{
break ;
}
}
if(i == end) //this object does not need this media impl.
{
mMediaImplList[texture_index]->removeObject(this) ;
}
mMediaImplList[texture_index] = NULL ;
return ;
}
void LLVOVolume::addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index)
{
if((S32)mMediaImplList.size() < texture_index + 1)
{
mMediaImplList.resize(texture_index + 1) ;
}
if(mMediaImplList[texture_index].notNull())
{
if(mMediaImplList[texture_index] == media_impl)
{
return ;
}
removeMediaImpl(texture_index) ;
}
mMediaImplList[texture_index] = media_impl;
media_impl->addObject(this) ;
//add the face to show the media if it is in playing
if(mDrawable)
{
LLFace* facep = mDrawable->getFace(texture_index) ;
if(facep)
{
LLViewerMediaTexture* media_tex = LLViewerTextureManager::findMediaTexture(mMediaImplList[texture_index]->getMediaTextureID()) ;
if(media_tex)
{
media_tex->addMediaToFace(facep) ;
}
}
else //the face is not available now, start media on this face later.
{
media_impl->setUpdated(TRUE) ;
}
}
return ;
}
viewer_media_t LLVOVolume::getMediaImpl(U8 face_id) const
{
if(mMediaImplList.size() > face_id)
{
return mMediaImplList[face_id];
}
return NULL;
}
S32 LLVOVolume::getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id)
{
S32 end = (S32)mMediaImplList.size() ;
for(S32 face_id = start_face_id + 1; face_id < end; face_id++)
{
if(mMediaImplList[face_id] == media_impl)
{
return face_id ;
}
}
return -1 ;
}
//----------------------------------------------------------------------------
void LLVOVolume::setLightTextureID(LLUUID id)

View File

@ -35,6 +35,7 @@
#include "llviewerobject.h"
#include "llviewertexture.h"
#include "llviewermedia.h"
#include "llframetimer.h"
#include "llapr.h"
#include "m3math.h" // LLMatrix3
@ -45,6 +46,8 @@ class LLViewerTextureAnim;
class LLDrawPool;
class LLSelectNode;
typedef std::vector<viewer_media_t> media_list_t;
enum LLVolumeInterfaceType
{
INTERFACE_FLEXIBLE = 1,
@ -75,12 +78,14 @@ public:
// Class which embodies all Volume objects (with pcode LL_PCODE_VOLUME)
class LLVOVolume : public LLViewerObject
{
LOG_CLASS(LLVOVolume);
protected:
virtual ~LLVOVolume();
public:
static void initClass();
static void preUpdateGeom();
static void cleanupClass();
static void preUpdateGeom();
enum
{
@ -153,6 +158,7 @@ public:
/*virtual*/ void setScale(const LLVector3 &scale, BOOL damped);
/*virtual*/ void setNumTEs(const U8 num_tes);
/*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep);
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
@ -224,13 +230,31 @@ public:
BOOL isVolumeGlobal() const;
BOOL canBeFlexible() const;
BOOL setIsFlexible(BOOL is_flexible);
void updateObjectMediaData(const LLSD &media_data_duples);
void mediaEvent(LLViewerMediaImpl *impl, LLPluginClassMedia* plugin, LLViewerMediaObserver::EMediaEvent event);
// Sync the given media data with the impl and the given te
void syncMediaData(S32 te, const LLSD &media_data, bool merge, bool ignore_agent);
// Send media data update to the simulator.
void sendMediaDataUpdate() const;
viewer_media_t getMediaImpl(U8 face_id) const;
S32 getFaceIndexWithMediaImpl(const LLViewerMediaImpl* media_impl, S32 start_face_id);
bool hasMedia() const;
protected:
S32 computeLODDetail(F32 distance, F32 radius);
BOOL calcLOD();
LLFace* addFace(S32 face_index);
void updateTEData();
void requestMediaDataUpdate();
void cleanUpMediaImpls();
void addMediaImpl(LLViewerMediaImpl* media_impl, S32 texture_index) ;
void removeMediaImpl(S32 texture_index) ;
public:
LLViewerTextureAnim *mTextureAnimp;
U8 mTexAnimMode;
@ -251,6 +275,7 @@ private:
LLVolumeInterface *mVolumeImpl;
LLPointer<LLViewerFetchedTexture> mSculptTexture;
LLPointer<LLViewerFetchedTexture> mLightTexture;
media_list_t mMediaImplList;
// statics
public:

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater bottom="-666" can_close="true" can_drag_on_left="false" can_minimize="true"
can_resize="false" can_tear_off="true" default_tab_group="1" enabled="true"
width="365" height="535" left="330" min_height="430" min_width="620"
mouse_opaque="true" name="Medis Settings" title="Media Settings">
<button bottom="-525" enabled="true" follows="right|bottom" font="SansSerif"
halign="center" height="20" label="OK" label_selected="OK" left="75"
mouse_opaque="true" name="OK" scale_image="true" width="90" />
<button bottom_delta="0" enabled="true" follows="right|bottom" font="SansSerif"
halign="center" height="20" label="Cancel" label_selected="Cancel"
left_delta="93" mouse_opaque="true" name="Cancel" scale_image="true"
width="90" />
<button bottom_delta="0" enabled="true" follows="right|bottom" font="SansSerif"
halign="center" height="20" label="Apply" label_selected="Apply"
left_delta="93" mouse_opaque="true" name="Apply" scale_image="true"
width="90" />
<tab_container bottom="-500" enabled="true" follows="left|top|right|bottom" height="485"
left="0" mouse_opaque="false" name="tab_container" tab_group="1"
tab_position="top" tab_width="80" width="365" />
</floater>

View File

@ -74,7 +74,11 @@
name="button focus"
picture_style="true"
tool_tip="Focus"
width="20" />
width="20">
<button.commit_callback
function="BuildTool.setTool"
parameter="Focus" />
</button>
<button
follows="left|top"
height="20"
@ -87,7 +91,11 @@
name="button move"
picture_style="true"
tool_tip="Move"
width="20" />
width="20">
<button.commit_callback
function="BuildTool.setTool"
parameter="Move" />
</button>
<button
follows="left|top"
height="20"
@ -100,7 +108,11 @@
name="button edit"
picture_style="true"
tool_tip="Edit"
width="20" />
width="20">
<button.commit_callback
function="BuildTool.setTool"
parameter="Edit" />
</button>
<button
follows="left|top"
height="20"
@ -113,7 +125,11 @@
name="button create"
picture_style="true"
tool_tip="Create"
width="20" />
width="20">
<button.commit_callback
function="BuildTool.setTool"
parameter="Create" />
</button>
<button
follows="left|top"
height="20"
@ -126,7 +142,11 @@
name="button land"
picture_style="true"
tool_tip="Land"
width="20" />
width="20">
<button.commit_callback
function="BuildTool.setTool"
parameter="Land" />
</button>
<text
type="string"
text_color="LabelSelectedDisabledColor"
@ -160,6 +180,8 @@
label="Pan (Ctrl-Shift)"
layout="topleft"
name="radio pan" />
<radio_group.commit_callback
function="BuildTool.commitRadioFocus"/>
</radio_group>
<slider_bar
follows="left|top"
@ -171,7 +193,10 @@
top_delta="-2"
left_delta="100"
name="slider zoom"
width="134" />
width="134">
<slider_bar.commit_callback
function="BuildTool.commitZoom"/>
</slider_bar>
<radio_group
left="10"
height="70"
@ -193,6 +218,8 @@
label="Spin (Ctrl-Shift)"
layout="topleft"
name="radio spin" />
<radio_group.commit_callback
function="BuildTool.commitRadioMove"/>
</radio_group>
<radio_group
follows="left|top"
@ -220,6 +247,8 @@
label="Select Texture"
layout="topleft"
name="radio select face" />
<radio_group.commit_callback
function="BuildTool.commitRadioEdit"/>
</radio_group>
<check_box
left="10"
@ -227,7 +256,10 @@
control_name="EditLinkedParts"
label="Edit linked"
layout="topleft"
name="checkbox edit linked parts" />
name="checkbox edit linked parts" >
<check_box.commit_callback
function="BuildTool.selectComponent"/>
</check_box>
<combo_box
height="19"
left="10"
@ -248,6 +280,8 @@
label="Reference ruler"
name="Reference"
value="Reference" />
<combo_box.commit_callback
function="BuildTool.gridMode"/>
</combo_box>
<check_box
control_name="ScaleUniform"
@ -286,7 +320,10 @@
name="Options..."
tool_tip="Set the Grid Options"
width="26"
height="22" />
height="22" >
<button.commit_callback
function="BuildTool.gridOptions"/>
</button>
<button
follows="left|top"
height="20"
@ -597,8 +634,9 @@
name="radio revert"
top_delta="15"
width="114" />
<radio_group.commit_callback
function="BuildTool.commitRadioLand"/>
</radio_group>
<text
type="string"
length="1"
@ -624,6 +662,7 @@
Size
</text>
<slider_bar
control_name ="LandBrushSize"
follows="left|top"
height="19"
initial_value="2.0"
@ -656,7 +695,10 @@
min_val="-1"
name="slider force"
top_delta="-3"
width="80" />
width="80" >
<slider_bar.commit_callback
function="BuildTool.LandBrushForce"/>
</slider_bar>
<button
follows="left|top"
font="SansSerifSmall"
@ -668,7 +710,10 @@
left="135"
name="button apply to selection"
tool_tip="Modify Selected Land"
width="78" />
width="78">
<button.commit_callback
function="BuildTool.applyToSelection"/>
</button>
<text
type="string"
text_color="LabelSelectedDisabledColor"
@ -2215,7 +2260,7 @@
left="10"
name="texture control"
tool_tip="Click to choose a picture"
top="10"
top="8"
width="64" />
<color_swatch
border_color="0.45098 0.517647 0.607843 1"
@ -2237,7 +2282,7 @@
layout="topleft"
left_pad="20"
name="color trans"
top="10"
top="6"
width="100">
Transparency %
</text>
@ -2261,7 +2306,7 @@
layout="topleft"
left_delta="0"
name="glow label"
top_pad="4"
top_pad="2"
width="80">
Glow
</text>
@ -2281,7 +2326,7 @@
layout="topleft"
left_delta="0"
name="checkbox fullbright"
top_pad="7"
top_pad="4"
width="81" />
<text
type="string"
@ -2291,7 +2336,7 @@
layout="topleft"
left="10"
name="tex gen"
top_pad="10"
top_pad="5"
width="87">
Mapping
</text>
@ -2439,6 +2484,40 @@
name="weave"
value="weave" />
</combo_box>
<!--
<line_editor
bevel_style="in"
border_style="line"
border_thickness="1"
follows="left|top"
height="16"
layout="topleft"
left="10"
max_length="63"
name="Home Url"
select_on_focus="true"
top="134"
width="250" />
<check_box
height="16"
label="Media Face"
layout="topleft"
left_delta="0"
name="has media"
top_pad="6"
width="70" />
<button
follows="left|top"
font="SansSerifSmall"
height="20"
label="Set Media Info"
label_selected="Set Media Info"
layout="topleft"
left_pad="60"
name="media info set"
top_delta="-4"
width="120" />
-->
<text
type="string"
length="1"
@ -2447,7 +2526,7 @@
layout="topleft"
left="10"
name="tex scale"
top_pad="15"
top_pad="5"
width="200">
Repeats per Face
</text>
@ -2461,7 +2540,7 @@
left="20"
max_val="100"
name="TexScaleU"
top_pad="10"
top_pad="6"
width="160" />
<check_box
height="19"
@ -2469,7 +2548,7 @@
layout="topleft"
left_pad="10"
name="checkbox flip s"
top_delta="1"
top_delta="0"
width="70" />
<spinner
follows="left|top"
@ -2489,61 +2568,43 @@
layout="topleft"
left_pad="10"
name="checkbox flip t"
top_delta="1"
top_delta="0"
width="70" />
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
left="10"
name="tex rotate"
top_pad="20"
width="102">
Rotation (degrees)
</text>
<spinner
decimal_digits="2"
follows="left|top"
height="19"
increment="1"
initial_value="0"
label="Rotation (degrees)"
layout="topleft"
left_delta="102"
label_width="100"
left="10"
max_val="9999"
min_val="-9999"
name="TexRot"
top_delta="0"
width="68" />
<text
type="string"
length="1"
follows="left|top"
height="10"
layout="topleft"
left="10"
name="rpt"
top_pad="0"
width="160">
Repeats Per Meter
</text>
top_delta="25"
width="170" />
<spinner
decimal_digits="1"
follows="left|top"
height="19"
initial_value="1"
label="Repeats Per Meter"
layout="topleft"
left_delta="102"
label_width="100"
left="10"
max_val="10"
min_val="0.1"
name="rptctrl"
top_delta="0"
width="68" />
top_delta="20"
width="170" />
<button
follows="left|top"
font="SansSerifSmall"
height="22"
height="18"
label="Apply"
label_selected="Apply"
layout="topleft"
@ -2558,7 +2619,7 @@
layout="topleft"
left="10"
name="tex offset"
top_pad="20"
top_delta="20"
width="200">
Texture Offset
</text>
@ -2572,7 +2633,7 @@
left="20"
min_val="-1"
name="TexOffsetU"
top_pad="10"
top_pad="5"
width="160" />
<spinner
follows="left|top"
@ -2584,10 +2645,9 @@
left_delta="0"
min_val="-1"
name="TexOffsetV"
top_pad="2"
top_pad="1"
width="160" />
<!--TODO: KILL THIS-->
<!-- <text
<text
type="string"
length="1"
follows="left|top"
@ -2595,7 +2655,7 @@
layout="topleft"
left="10"
name="textbox autofix"
top="332"
top_pad="4"
width="160">
Align media texture
(must load first)
@ -2607,10 +2667,75 @@
label="Align"
label_selected="Align"
layout="topleft"
left="112"
left="122"
name="button align"
top="340"
width="68" />-->
top_pad="-19"
width="68" />
<text
type="string"
length="1"
follows="left|top"
height="12"
layout="topleft"
left="10"
top_pad="0"
name="media_tex"
width="100">
Media:
</text>
<line_editor
follows="left|top|right"
height="18"
layout="topleft"
left="20"
max_length="63"
name="media_info"
select_on_focus="true"
top_delta="12"
width="230" />
<button
follows="left|top"
font="SansSerifSmall"
height="13"
width="13"
image_unselected="add_btn.tga"
label=""
layout="topleft"
left="20"
name="add_media"
top_pad="3">
<button.commit_callback
function="BuildTool.AddMedia"/>
</button>
<button
follows="left|top"
font="SansSerifSmall"
height="13"
width="13"
image_unselected="del_btn.tga"
label=""
layout="topleft"
left_pad="10"
name="delete_media"
top_delta="0"
left_delta="10" >
<button.commit_callback
function="BuildTool.DeleteMedia"/>
</button>
<button
follows="left|top"
font="SansSerifSmall"
height="15"
width="15"
image_unselected="gear.tga"
label=""
layout="topleft"
name="edit_media"
top_delta="0"
left_delta="190">
<button.commit_callback
function="BuildTool.EditMedia"/>
</button>
</panel>
<panel
border="false"
@ -2642,13 +2767,13 @@
width="130" />
<panel_inventory
follows="left|top"
height="310"
height="210"
layout="topleft"
left="10"
name="contents_inventory"
top="50"
width="260" />
</panel>
</panel>
</tab_container>
<panel
follows="left|top"

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
can_minimize="false"
height="108"
layout="topleft"
name="whitelist_entry"
width="390">
<text type="string" length="1" bottom="20" follows="top|left" height="15" layout="topleft"
left="10" name="media_label" top="20">
Enter a URL or URL pattern to add to the list of allowed domains
</text>
<line_editor bottom_delta="40" enabled="true" follows="left|top" font="SansSerif"
height="20" left="10" name="whitelist_entry"
tool_tip="Enter a URL or URL pattern to White List"
width="350" />
<button follows="top|left" height="20" font="SansSerifSmall" label="OK"
layout="topleft" left="10" name="ok_btn" bottom_delta="28" width="64" />
<button follows="top|left" height="20" font="SansSerifSmall" label="Cancel"
layout="topleft" left_pad="5" name="cancel_btn" bottom_delta="0" width="64" />
</floater>

View File

@ -646,6 +646,21 @@ This entire region is damage enabled.
Scripts must be allowed to run for weapons to work.
</notification>
<notification
icon="alertmodal.tga"
name="MultipleFacesSelected"
type="alertmodal">
Multiple faces are currently selected.
If you continue this action, separate instances of media will be
set on multiple faces of the object.
To place the media on only one face, use Select Texture and click
on the face of that object and click Add.
<usetemplate
name="okcancelignore"
notext="Cancel"
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="MustBeInParcel"
@ -783,6 +798,21 @@ There is no reimbursement for fees paid.
yestext="OK"/>
</notification>
<notification
icon="alertmodal.tga"
name="DeleteMedia"
type="alertmodal">
You have selected to delete the media associated
with this face.
Are you sure you want to continue?
<usetemplate
ignoretext="Confirm before I delete media"
name="okcancelignore"
notext="No"
yestext="Yes"/>
</notification>
<notification
icon="alertmodal.tga"
name="ClassifiedSave"
@ -6485,6 +6515,17 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block
Unable to find the help topic for this element.
</notification>
<notification
icon="alertmodal.tga"
name="ObjectMediaFailure"
type="alertmodal">
Server Error: Media update or get failed.
&apos;[ERROR]&apos;
<usetemplate
name="okbutton"
yestext="Ok"/>
</notification>
<global name="UnsupportedCPU">
- Your CPU speed does not meet the minimum requirements.
</global>

View File

@ -26,9 +26,8 @@
layout="topleft"
left="0"
name="login_html"
hide_loading="true"
right="-1"
start_url="data:text/html,%3Chtml%3E%3Chead%3E%3C/head%3E%3Cbody bgcolor=%22#000000%22 text=%22ffffff%22%3E%3Ch1%3E%3Ctt%3Eloading...%3C/tt%3E%3C/h1%3E %3C/body%3E %3C/html%3E"
start_url=""
top="1" />
<text
type="string"

View File

@ -0,0 +1,199 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
border="true"
enabled="true"
follows="left|top|right|bottom"
height="500"
label="General"
left="102"
mouse_opaque="true"
name="Media Settings General"
width="365">
<text
bottom_delta="-17"
follows="top|left"
height="15"
left="10"
name="">
Home URL:
</text>
<line_editor
bottom_delta="-21"
enabled="true"
follows="left|top"
font="SansSerif"
height="20"
left="10"
name="home_url"
tool_tip="The home URL for this media source"
width="340">
<!-- <line_editor.commit_callback
function="Media.CommitHomeURL"/> -->
</line_editor>
<text
bottom_delta="-20"
follows="top|left"
height="15"
left="10"
name="current_url_label">
Current URL:
</text>
<line_editor
bottom_delta="-20"
enabled="false"
follows="left|top"
font="SansSerif"
height="20"
left="10"
name="current_url"
tool_tip="The current URL for this media source"
value=""
width="340" />
<button
bottom_delta="-20"
follows="top|left"
height="20"
label="Reset"
left_delta="233"
name="current_url_reset_btn"
width="110" >
<button.commit_callback
function="Media.ResetCurrentUrl"/>
</button>
<web_browser
border_visible="false"
bottom_delta="-120"
follows="top|left"
left="120"
name="preview_media"
width="128"
height="128"
start_url="about:blank"
decouple_texture_size="true" />
<text
bottom_delta="-15"
follows="top|left"
height="15"
left="164"
name="">
Preview
</text>
<text
bottom_delta="-20"
follows="top|left"
height="15"
left="10"
name="">
Controls:
</text>
<combo_box
allow_text_entry="false"
bottom_delta="-20"
enabled="true"
follows="left|top"
height="18"
left="10"
max_chars="20"
mouse_opaque="true"
name="controls"
width="120">
<combo_item
type="string"
length="1"
enabled="true"
name="Standard"
value="Standard">
Standard
</combo_item>
<combo_item
type="string"
length="1"
enabled="true"
name="Mini"
value="Mini">
Mini
</combo_item>
</combo_box>
<check_box
bottom_delta="-25"
enabled="true"
follows="left|top"
font="SansSerifSmall"
height="16"
initial_value="false"
label="Auto Loop"
left="10"
mouse_opaque="true"
name="auto_loop"
radio_style="false"
width="150" />
<check_box
bottom_delta="-25"
enabled="true"
follows="left|top"
font="SansSerifSmall"
height="16"
initial_value="false"
label="First Click Interacts"
left_delta="0"
mouse_opaque="true"
name="first_click_interact"
radio_style="false"
width="150" />
<check_box
bottom_delta="-25"
enabled="true"
follows="left|top"
font="SansSerifSmall"
height="16"
initial_value="false"
label="Auto Zoom"
left_delta="0"
mouse_opaque="true"
name="auto_zoom"
radio_style="false"
width="150" />
<check_box bottom_delta="-25" enabled="true" follows="left|top" font="SansSerifSmall"
height="16" initial_value="false"
label="Use Default Alternative Image" left="10" mouse_opaque="true"
name="alt_image_enable" radio_style="false" width="150" />
<check_box bottom_delta="-25" enabled="true" follows="left|top" font="SansSerifSmall"
height="16" initial_value="false"
label="Auto Play Media" left="10" mouse_opaque="true"
name="auto_play" radio_style="false" width="150" />
<text bottom_delta="-14" follows="top|left" height="15" left="30" width="340"
enabled="false" name="">
Note: Parcel Owners &amp; Residents can override this setting
</text>
<check_box bottom_delta="-25" enabled="true" follows="left|top" font="SansSerifSmall"
height="16" initial_value="false"
label="Auto Scale Media on Face of Object" left="10" mouse_opaque="true"
name="auto_scale" radio_style="false" width="150" />
<text bottom_delta="-20" follows="top|left" height="15" left="30" name="">
Size:
</text>
<spinner bottom_delta="0"
decimal_digits="0" enabled="true" follows="left|top" height="16"
increment="1" initial_val="256" label="" label_width="0"
left_delta="40" max_val="2000" min_val="0" mouse_opaque="true"
name="width_pixels" width="50" />
<text bottom_delta="0" follows="top|left" height="15" left_delta="60" name="">
X
</text>
<spinner bottom_delta="0"
decimal_digits="0" enabled="true" follows="left|top" height="16"
increment="1" initial_val="256" label="" label_width="0"
left_delta="20" max_val="2000" min_val="0" mouse_opaque="true"
name="height_pixels" width="50" />
</panel>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel border="true" enabled="true" follows="left|top|right|bottom"
height="500" label="Controls" left="102" mouse_opaque="true"
name="Media settings for controls" width="365">
<text bottom_delta="-50" follows="top|left" height="15" left="10" name="" enabled="false">
Owner
</text>
<check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
height="16" initial_value="false"
label="Disable Navigation &amp; Interactivity" left="30" mouse_opaque="true"
name="perms_owner_interact" radio_style="false" width="250" />
<check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
height="16" initial_value="false"
label="Hide Control Bar" left="30" mouse_opaque="true"
name="perms_owner_control" radio_style="false" width="250" />
<text bottom_delta="-36" follows="top|left" height="15" left="10" name="perms_group_name_label" enabled="false">
Group
</text>
<name_box bottom_delta="-5" enabled="false" follows="left|top" font="SansSerif"
height="20" left="60" name="perms_group_name"
value =""
width="200" />
<check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
height="16" initial_value="false"
label="Disable Navigation &amp; Interactivity" left="30" mouse_opaque="true"
name="perms_group_interact" radio_style="false" width="250" />
<check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
height="16" initial_value="false"
label="Hide Control Bar" left="30" mouse_opaque="true"
name="perms_group_control" radio_style="false" width="250" />
<text bottom_delta="-36" follows="top|left" height="15" left="10" name="" enabled="false">
Anyone
</text>
<check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
height="16" initial_value="false"
label="Disable Navigation &amp; Interactivity" left="30" mouse_opaque="true"
name="perms_anyone_interact" radio_style="false" width="250" />
<check_box bottom_delta="-22" enabled="true" follows="left|top" font="SansSerifSmall"
height="16" initial_value="false"
label="Hide Control Bar" left="30" mouse_opaque="true"
name="perms_anyone_control" radio_style="false" width="250" />
</panel>

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
border="true"
enabled="true"
follows="left|top|right|bottom"
height="500"
label="Security"
left="102"
mouse_opaque="true"
name="Media Settings Security"
width="365">
<check_box
bottom_delta="-40"
enabled="true"
follows="left|top"
font="SansSerifSmall"
height="16"
initial_value="false"
label="Only Allow Access to Specified URLs (by prefix)"
left="10"
mouse_opaque="true"
name="whitelist_enable"
radio_style="false"
width="250" />
<scroll_list
follows="top|left"
height="200"
left="30"
name="whitelist"
width="315"
enabled="true" />
<button
bottom_delta="-30"
follows="top|left"
height="20"
label="Add"
left="30"
name="whitelist_add"
width="70"
enabled="true">
<button.commit_callback
function="Media.whitelistAdd"/>
</button>
<button
bottom_delta="0"
follows="top|left"
height="20"
label="Delete"
left="275"
name="whitelist_del"
width="70"
enabled="true">
<button.commit_callback
function="Media.whitelistDelete"/>
</button>
</panel>

View File

@ -1728,13 +1728,25 @@ Releases the specified URL, it will no longer be usable
<string name="LSLTipText_llHTTPResponse">
llHTTPResponse(key request_id, integer status, string body)
Responds to request_id with status and body
</string>
</string>
<string name="LSLTipText_llGetHTTPHeader">
string llGetHTTPHeader(key request_id, string header)
Returns the value for header for request_id
</string>
<!-- Avatar busy/away mode -->
<string name="LSLTipText_llSetPrimMediaParams">
llSetPrimMediaParams(integer face, list params)
Set the media params for a particular face on an object. List is a set of name/value pairs (in no particular order). The possible names are below, along with the types of values and what they mean. If media is not already on this object, add it. Params not specified are unchanged, or if new media is added set to the default specified.
</string>
<string name="LSLTipText_llGetPrimMediaParams">
list llGetPrimMediaParams(integer face, list params)
Get the media params for a particular face on an object, given the desired list of names. Returns a list of values in the order requested. Returns an empty list if no media exists on the face.
</string>
<string name="LSLTipText_llClearPrimMedia">
llClearPrimMedia(integer face)
Clears (deletes) the media and all params from the given face.
</string>
<!-- Avatar busy/away mode -->
<string name="AvatarSetNotAway">Set Not Away</string>
<string name="AvatarSetAway">Set Away</string>
<string name="AvatarSetNotBusy">Set Not Busy</string>

View File

@ -169,6 +169,12 @@ class WindowsManifest(ViewerManifest):
# the final exe is complicated because we're not sure where it's coming from,
# nor do we have a fixed name for the executable
self.path(self.find_existing_file('debug/secondlife-bin.exe', 'release/secondlife-bin.exe', 'relwithdebinfo/secondlife-bin.exe'), dst=self.final_exe())
# Plugin host application
self.path(os.path.join(os.pardir,
'llplugin', 'slplugin', self.args['configuration'], "slplugin.exe"),
"slplugin.exe")
# need to get the kdu dll from any of the build directories as well
try:
self.path(self.find_existing_file('../llkdu/%s/llkdu.dll' % self.args['configuration'],
@ -193,11 +199,6 @@ class WindowsManifest(ViewerManifest):
self.path("openjpeg.dll")
self.end_prefix()
# Plugin host application
if self.prefix(src='../llplugin/slplugin/%s' % self.args['configuration'], dst="llplugin"):
self.path("slplugin.exe")
self.end_prefix()
# Media plugins - QuickTime
if self.prefix(src='../media_plugins/quicktime/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_quicktime.dll")
@ -487,9 +488,11 @@ class DarwinManifest(ViewerManifest):
self.path("../mac_crash_logger/" + self.args['configuration'] + "/mac-crash-logger.app", "mac-crash-logger.app")
self.path("../mac_updater/" + self.args['configuration'] + "/mac-updater.app", "mac-updater.app")
# plugin launcher
self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin")
# plugins
if self.prefix(src="", dst="llplugin"):
self.path("../llplugin/slplugin/" + self.args['configuration'] + "/SLPlugin", "SLPlugin")
self.path("../media_plugins/quicktime/" + self.args['configuration'] + "/media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib")
self.path("../media_plugins/webkit/" + self.args['configuration'] + "/media_plugin_webkit.dylib", "media_plugin_webkit.dylib")
self.path("../../libraries/universal-darwin/lib_release/libllqtwebkit.dylib", "libllqtwebkit.dylib")
@ -680,6 +683,7 @@ class Linux_i686Manifest(LinuxManifest):
self.path("secondlife-stripped","bin/do-not-directly-run-secondlife-bin")
self.path("../linux_crash_logger/linux-crash-logger-stripped","bin/linux-crash-logger.bin")
self.path("../linux_updater/linux-updater-stripped", "bin/linux-updater.bin")
self.path("../llplugin/slplugin/SLPlugin", "bin/SLPlugin")
if self.prefix("res-sdl"):
self.path("*")
# recurse
@ -687,7 +691,6 @@ class Linux_i686Manifest(LinuxManifest):
# plugins
if self.prefix(src="", dst="bin/llplugin"):
self.path("../llplugin/slplugin/SLPlugin", "SLPlugin")
self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so")
self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_quicktime.so")
self.end_prefix("bin/llplugin")