Split plugin classes and derive AIFilePicker from BasicPluginBase (part 2).
This commit contains all changes to indra/llplugin. Since there were no differences at all between Singularity and imprudence before this patch, it's a perfect port.
This commit is contained in:
@@ -24,6 +24,7 @@ include_directories(
|
||||
)
|
||||
|
||||
set(llplugin_SOURCE_FILES
|
||||
llpluginclassbasic.cpp
|
||||
llpluginclassmedia.cpp
|
||||
llplugincookiestore.cpp
|
||||
llplugininstance.cpp
|
||||
@@ -37,6 +38,7 @@ set(llplugin_SOURCE_FILES
|
||||
set(llplugin_HEADER_FILES
|
||||
CMakeLists.txt
|
||||
|
||||
llpluginclassbasic.h
|
||||
llpluginclassmedia.h
|
||||
llpluginclassmediaowner.h
|
||||
llplugincookiestore.h
|
||||
|
||||
189
indra/llplugin/llpluginclassbasic.cpp
Normal file
189
indra/llplugin/llpluginclassbasic.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
/**
|
||||
* @file llpluginclassbasic.cpp
|
||||
* @brief LLPluginClassBasic handles a plugin which knows about the "basic" message class.
|
||||
*
|
||||
* @cond
|
||||
* $LicenseInfo:firstyear=2010&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2010, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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$
|
||||
*
|
||||
* @endcond
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "indra_constants.h"
|
||||
|
||||
#include "llpluginclassbasic.h"
|
||||
#include "llpluginmessageclasses.h"
|
||||
|
||||
LLPluginClassBasic::LLPluginClassBasic(void) : mPlugin(NULL), mDeleteOK(true)
|
||||
{
|
||||
// Note that this only initializes the base class, the derived class doesn't exist yet!
|
||||
// Derived classes must therefore call their own reset_impl() from their constructor.
|
||||
reset();
|
||||
}
|
||||
|
||||
LLPluginClassBasic::~LLPluginClassBasic()
|
||||
{
|
||||
llassert_always(mDeleteOK);
|
||||
delete mPlugin;
|
||||
}
|
||||
|
||||
bool LLPluginClassBasic::init(std::string const& launcher_filename, std::string const& plugin_filename, bool debug)
|
||||
{
|
||||
LL_DEBUGS("Plugin") << "launcher: " << launcher_filename << LL_ENDL;
|
||||
LL_DEBUGS("Plugin") << "plugin: " << plugin_filename << LL_ENDL;
|
||||
|
||||
mPlugin = new LLPluginProcessParent(this);
|
||||
mPlugin->setSleepTime(mSleepTime);
|
||||
|
||||
mPlugin->init(launcher_filename, plugin_filename, debug);
|
||||
|
||||
return init_impl();
|
||||
}
|
||||
|
||||
void LLPluginClassBasic::reset()
|
||||
{
|
||||
if (mPlugin != NULL)
|
||||
{
|
||||
delete mPlugin;
|
||||
mPlugin = NULL;
|
||||
}
|
||||
mSleepTime = 1.0f / 50.0f;
|
||||
mPriority = PRIORITY_NORMAL;
|
||||
reset_impl();
|
||||
}
|
||||
|
||||
void LLPluginClassBasic::idle(void)
|
||||
{
|
||||
if(mPlugin)
|
||||
{
|
||||
mPlugin->idle();
|
||||
}
|
||||
|
||||
idle_impl();
|
||||
|
||||
if(mPlugin && mPlugin->isRunning())
|
||||
{
|
||||
// Send queued messages
|
||||
while(!mSendQueue.empty())
|
||||
{
|
||||
LLPluginMessage message = mSendQueue.front();
|
||||
mSendQueue.pop();
|
||||
mPlugin->sendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char const* LLPluginClassBasic::priorityToString(EPriority priority)
|
||||
{
|
||||
const char* result = "UNKNOWN";
|
||||
switch(priority)
|
||||
{
|
||||
case PRIORITY_SLEEP: result = "sleep"; break;
|
||||
case PRIORITY_LOW: result = "low"; break;
|
||||
case PRIORITY_NORMAL: result = "normal"; break;
|
||||
case PRIORITY_HIGH: result = "high"; break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void LLPluginClassBasic::setPriority(EPriority priority)
|
||||
{
|
||||
if (mPriority != priority)
|
||||
{
|
||||
mPriority = priority;
|
||||
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_BASIC, "set_priority");
|
||||
|
||||
std::string priority_string = priorityToString(priority);
|
||||
switch(priority)
|
||||
{
|
||||
case PRIORITY_SLEEP:
|
||||
mSleepTime = 1.0f;
|
||||
break;
|
||||
case PRIORITY_LOW:
|
||||
mSleepTime = 1.0f / 25.0f;
|
||||
break;
|
||||
case PRIORITY_NORMAL:
|
||||
mSleepTime = 1.0f / 50.0f;
|
||||
break;
|
||||
case PRIORITY_HIGH:
|
||||
mSleepTime = 1.0f / 100.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
message.setValue("priority", priority_string);
|
||||
sendMessage(message);
|
||||
|
||||
if(mPlugin)
|
||||
{
|
||||
mPlugin->setSleepTime(mSleepTime);
|
||||
}
|
||||
|
||||
LL_DEBUGS("PluginPriority") << this << ": setting priority to " << priority_string << LL_ENDL;
|
||||
|
||||
priorityChanged(mPriority);
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
void LLPluginClassBasic::receivePluginMessage(const LLPluginMessage &message)
|
||||
{
|
||||
std::string message_class = message.getClass();
|
||||
|
||||
if (message_class == LLPLUGIN_MESSAGE_CLASS_BASIC)
|
||||
{
|
||||
std::string message_name = message.getName();
|
||||
|
||||
// This class hasn't defined any incoming messages yet.
|
||||
// if (message_name == "message_name")
|
||||
// {
|
||||
// }
|
||||
// else
|
||||
{
|
||||
LL_WARNS("Plugin") << "Unknown " << message_class << " class message: " << message_name << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is the viewer process (the parent process)
|
||||
//
|
||||
// Call this function to send a message to a plugin.
|
||||
// It calls LLPluginProcessParent::sendMessage.
|
||||
void LLPluginClassBasic::sendMessage(LLPluginMessage const& message)
|
||||
{
|
||||
if(mPlugin && mPlugin->isRunning())
|
||||
{
|
||||
mPlugin->sendMessage(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The plugin isn't set up yet -- queue this message to be sent after initialization.
|
||||
mSendQueue.push(message);
|
||||
}
|
||||
}
|
||||
126
indra/llplugin/llpluginclassbasic.h
Normal file
126
indra/llplugin/llpluginclassbasic.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* @file llpluginclassbasic.h
|
||||
* @brief LLPluginClassBasic handles interaction with a plugin which knows about the "basic" message class.
|
||||
*
|
||||
* @cond
|
||||
* $LicenseInfo:firstyear=2010&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2010, 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://secondlife.com/developers/opensource/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://secondlife.com/developers/opensource/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$
|
||||
*
|
||||
* @endcond
|
||||
*/
|
||||
|
||||
#ifndef LL_LLPLUGINCLASSBASIC_H
|
||||
#define LL_LLPLUGINCLASSBASIC_H
|
||||
|
||||
#include "llerror.h" // Needed for LOG_CLASS
|
||||
#include "stdtypes.h" // Needed for F64
|
||||
#include "llpluginprocessparent.h"
|
||||
#include "llpluginclassmediaowner.h"
|
||||
#include "llpluginmessage.h"
|
||||
#include <string>
|
||||
#include <queue>
|
||||
|
||||
class LLPluginClassBasic : public LLPluginProcessParentOwner
|
||||
{
|
||||
LOG_CLASS(LLPluginClassBasic);
|
||||
|
||||
public:
|
||||
LLPluginClassBasic(void);
|
||||
virtual ~LLPluginClassBasic();
|
||||
|
||||
// Local initialization, called when creating a plugin process. Return true if successful.
|
||||
bool init(std::string const& launcher_filename, std::string const& plugin_filename, bool debug);
|
||||
|
||||
// Undoes everything init did. Called when destroying a plugin process.
|
||||
void reset(void);
|
||||
|
||||
void idle(void);
|
||||
|
||||
// Send message to the plugin, either queueing or sending directly.
|
||||
void sendMessage(LLPluginMessage const& message);
|
||||
|
||||
// "Loading" means uninitialized or any state prior to fully running (processing commands).
|
||||
bool isPluginLoading(void) const { return mPlugin ? mPlugin->isLoading() : false; }
|
||||
|
||||
// "Running" means the steady state -- i.e. processing messages.
|
||||
bool isPluginRunning(void) const { return mPlugin ? mPlugin->isRunning() : false; }
|
||||
|
||||
// "Exited" means any regular or error state after "Running" (plugin may have crashed or exited normally).
|
||||
bool isPluginExited(void) const { return mPlugin ? mPlugin->isDone() : false; }
|
||||
|
||||
std::string getPluginVersion() const { return mPlugin ? mPlugin->getPluginVersion() : std::string(""); }
|
||||
|
||||
bool getDisableTimeout() const { return mPlugin ? mPlugin->getDisableTimeout() : false; }
|
||||
|
||||
void setDisableTimeout(bool disable) { if (mPlugin) mPlugin->setDisableTimeout(disable); }
|
||||
|
||||
enum EPriority
|
||||
{
|
||||
PRIORITY_SLEEP, // Sleep 1 second every message.
|
||||
PRIORITY_LOW, // Sleep 1/25 second.
|
||||
PRIORITY_NORMAL, // Sleep 1/50 second.
|
||||
PRIORITY_HIGH // Sleep 1/100 second.
|
||||
};
|
||||
|
||||
static char const* priorityToString(EPriority priority);
|
||||
void setPriority(EPriority priority);
|
||||
|
||||
protected:
|
||||
EPriority mPriority;
|
||||
LLPluginProcessParent* mPlugin;
|
||||
|
||||
private:
|
||||
F64 mSleepTime;
|
||||
std::queue<LLPluginMessage> mSendQueue; // Used to queue messages while the plugin initializes.
|
||||
|
||||
protected:
|
||||
// Called as last function when calling 'init()'.
|
||||
virtual bool init_impl(void) { return true; }
|
||||
|
||||
// Called as last function when calling 'reset()'.
|
||||
virtual void reset_impl(void) { }
|
||||
|
||||
// Called from idle() before flushing messages to the plugin.
|
||||
virtual void idle_impl(void) { }
|
||||
|
||||
// Called from setPriority.
|
||||
virtual void priorityChanged(EPriority priority) { }
|
||||
|
||||
// Inherited from LLPluginProcessParentOwner.
|
||||
/*virtual*/ void receivePluginMessage(LLPluginMessage const&);
|
||||
|
||||
//--------------------------------------
|
||||
// Debug use only
|
||||
//
|
||||
private:
|
||||
bool mDeleteOK;
|
||||
|
||||
public:
|
||||
void setDeleteOK(bool flag) { mDeleteOK = flag; }
|
||||
};
|
||||
|
||||
#endif // LL_LLPLUGINCLASSBASIC_H
|
||||
@@ -54,49 +54,24 @@ static int nextPowerOf2( int value )
|
||||
return next_power_of_2;
|
||||
}
|
||||
|
||||
LLPluginClassMedia::LLPluginClassMedia(LLPluginClassMediaOwner *owner)
|
||||
LLPluginClassMedia::LLPluginClassMedia(LLPluginClassMediaOwner *owner): mOwner(owner)
|
||||
{
|
||||
mOwner = owner;
|
||||
mPlugin = NULL;
|
||||
reset();
|
||||
|
||||
//debug use
|
||||
mDeleteOK = true ;
|
||||
// Most initialization is done with reset_impl(), which we call here
|
||||
// in order to avoid code duplication.
|
||||
LLPluginClassMedia::reset_impl();
|
||||
}
|
||||
|
||||
|
||||
LLPluginClassMedia::~LLPluginClassMedia()
|
||||
bool LLPluginClassMedia::init_impl(void)
|
||||
{
|
||||
llassert_always(mDeleteOK) ;
|
||||
reset();
|
||||
}
|
||||
|
||||
bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug)
|
||||
{
|
||||
LL_DEBUGS("Plugin") << "launcher: " << launcher_filename << LL_ENDL;
|
||||
LL_DEBUGS("Plugin") << "plugin: " << plugin_filename << LL_ENDL;
|
||||
|
||||
mPlugin = new LLPluginProcessParent(this);
|
||||
mPlugin->setSleepTime(mSleepTime);
|
||||
|
||||
// Queue up the media init message -- it will be sent after all the currently queued messages.
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "init");
|
||||
sendMessage(message);
|
||||
|
||||
mPlugin->init(launcher_filename, plugin_filename, debug);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LLPluginClassMedia::reset()
|
||||
void LLPluginClassMedia::reset_impl(void)
|
||||
{
|
||||
if(mPlugin != NULL)
|
||||
{
|
||||
delete mPlugin;
|
||||
mPlugin = NULL;
|
||||
}
|
||||
|
||||
mTextureParamsReceived = false;
|
||||
mRequestedTextureDepth = 0;
|
||||
mRequestedTextureInternalFormat = 0;
|
||||
@@ -125,14 +100,12 @@ void LLPluginClassMedia::reset()
|
||||
mDirtyRect = LLRect::null;
|
||||
mAutoScaleMedia = false;
|
||||
mRequestedVolume = 1.0f;
|
||||
mPriority = PRIORITY_NORMAL;
|
||||
mLowPrioritySizeLimit = LOW_PRIORITY_TEXTURE_SIZE_DEFAULT;
|
||||
mAllowDownsample = false;
|
||||
mPadding = 0;
|
||||
mLastMouseX = 0;
|
||||
mLastMouseY = 0;
|
||||
mStatus = LLPluginClassMediaOwner::MEDIA_NONE;
|
||||
mSleepTime = 1.0f / 100.0f;
|
||||
mCanCut = false;
|
||||
mCanCopy = false;
|
||||
mCanPaste = false;
|
||||
@@ -158,13 +131,8 @@ void LLPluginClassMedia::reset()
|
||||
mLoadedDuration = 0.0f;
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::idle(void)
|
||||
void LLPluginClassMedia::idle_impl(void)
|
||||
{
|
||||
if(mPlugin)
|
||||
{
|
||||
mPlugin->idle();
|
||||
}
|
||||
|
||||
if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked()))
|
||||
{
|
||||
// Can't process a size change at this time
|
||||
@@ -260,17 +228,6 @@ void LLPluginClassMedia::idle(void)
|
||||
LL_DEBUGS("Plugin") << "Sending size_change" << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
if(mPlugin && mPlugin->isRunning())
|
||||
{
|
||||
// Send queued messages
|
||||
while(!mSendQueue.empty())
|
||||
{
|
||||
LLPluginMessage message = mSendQueue.front();
|
||||
mSendQueue.pop();
|
||||
mPlugin->sendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int LLPluginClassMedia::getTextureWidth() const
|
||||
@@ -295,18 +252,16 @@ unsigned char* LLPluginClassMedia::getBitsData()
|
||||
|
||||
void LLPluginClassMedia::setSize(int width, int height)
|
||||
{
|
||||
if((width > 0) && (height > 0))
|
||||
if (width <= 0 || height <= 0)
|
||||
{
|
||||
width = height = -1;
|
||||
}
|
||||
if (mSetMediaWidth != width || mSetMediaHeight != height)
|
||||
{
|
||||
mSetMediaWidth = width;
|
||||
mSetMediaHeight = height;
|
||||
setSizeInternal();
|
||||
}
|
||||
else
|
||||
{
|
||||
mSetMediaWidth = -1;
|
||||
mSetMediaHeight = -1;
|
||||
}
|
||||
|
||||
setSizeInternal();
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::setSizeInternal(void)
|
||||
@@ -335,7 +290,7 @@ void LLPluginClassMedia::setSizeInternal(void)
|
||||
{
|
||||
switch(mPriority)
|
||||
{
|
||||
case PRIORITY_SLIDESHOW:
|
||||
case PRIORITY_SLEEP:
|
||||
case PRIORITY_LOW:
|
||||
// Reduce maximum texture dimension to (or below) mLowPrioritySizeLimit
|
||||
while((mRequestedMediaWidth > mLowPrioritySizeLimit) || (mRequestedMediaHeight > mLowPrioritySizeLimit))
|
||||
@@ -584,71 +539,10 @@ void LLPluginClassMedia::loadURI(const std::string &uri)
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
const char* LLPluginClassMedia::priorityToString(EPriority priority)
|
||||
void LLPluginClassMedia::priorityChanged(EPriority priority)
|
||||
{
|
||||
const char* result = "UNKNOWN";
|
||||
switch(priority)
|
||||
{
|
||||
case PRIORITY_UNLOADED: result = "unloaded"; break;
|
||||
case PRIORITY_STOPPED: result = "stopped"; break;
|
||||
case PRIORITY_HIDDEN: result = "hidden"; break;
|
||||
case PRIORITY_SLIDESHOW: result = "slideshow"; break;
|
||||
case PRIORITY_LOW: result = "low"; break;
|
||||
case PRIORITY_NORMAL: result = "normal"; break;
|
||||
case PRIORITY_HIGH: result = "high"; break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::setPriority(EPriority priority)
|
||||
{
|
||||
if(mPriority != priority)
|
||||
{
|
||||
mPriority = priority;
|
||||
|
||||
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "set_priority");
|
||||
|
||||
std::string priority_string = priorityToString(priority);
|
||||
switch(priority)
|
||||
{
|
||||
case PRIORITY_UNLOADED:
|
||||
mSleepTime = 1.0f;
|
||||
break;
|
||||
case PRIORITY_STOPPED:
|
||||
mSleepTime = 1.0f;
|
||||
break;
|
||||
case PRIORITY_HIDDEN:
|
||||
mSleepTime = 1.0f;
|
||||
break;
|
||||
case PRIORITY_SLIDESHOW:
|
||||
mSleepTime = 1.0f;
|
||||
break;
|
||||
case PRIORITY_LOW:
|
||||
mSleepTime = 1.0f / 25.0f;
|
||||
break;
|
||||
case PRIORITY_NORMAL:
|
||||
mSleepTime = 1.0f / 50.0f;
|
||||
break;
|
||||
case PRIORITY_HIGH:
|
||||
mSleepTime = 1.0f / 100.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
message.setValue("priority", priority_string);
|
||||
|
||||
sendMessage(message);
|
||||
|
||||
if(mPlugin)
|
||||
{
|
||||
mPlugin->setSleepTime(mSleepTime);
|
||||
}
|
||||
|
||||
LL_DEBUGS("PluginPriority") << this << ": setting priority to " << priority_string << LL_ENDL;
|
||||
|
||||
// This may affect the calculated size, so recalculate it here.
|
||||
setSizeInternal();
|
||||
}
|
||||
// This may affect the calculated size, so recalculate it here.
|
||||
setSizeInternal();
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
|
||||
@@ -657,7 +551,6 @@ void LLPluginClassMedia::setLowPrioritySizeLimit(int size)
|
||||
if(mLowPrioritySizeLimit != power)
|
||||
{
|
||||
mLowPrioritySizeLimit = power;
|
||||
|
||||
// This may affect the calculated size, so recalculate it here.
|
||||
setSizeInternal();
|
||||
}
|
||||
@@ -726,7 +619,11 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
{
|
||||
std::string message_class = message.getClass();
|
||||
|
||||
if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
|
||||
if (message_class == LLPLUGIN_MESSAGE_CLASS_BASIC)
|
||||
{
|
||||
LLPluginClassBasic::receivePluginMessage(message);
|
||||
}
|
||||
else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
|
||||
{
|
||||
std::string message_name = message.getName();
|
||||
if(message_name == "texture_params")
|
||||
@@ -1003,10 +900,9 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
|
||||
// }
|
||||
// else
|
||||
{
|
||||
LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
|
||||
LL_WARNS("Plugin") << "Unknown " << message_class << " class message: " << message_name << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
@@ -1029,19 +925,6 @@ void LLPluginClassMedia::mediaEvent(LLPluginClassMediaOwner::EMediaEvent event)
|
||||
}
|
||||
}
|
||||
|
||||
void LLPluginClassMedia::sendMessage(const LLPluginMessage &message)
|
||||
{
|
||||
if(mPlugin && mPlugin->isRunning())
|
||||
{
|
||||
mPlugin->sendMessage(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The plugin isn't set up yet -- queue this message to be sent after initialization.
|
||||
mSendQueue.push(message);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// MARK: media_browser class functions
|
||||
bool LLPluginClassMedia::pluginSupportsMediaBrowser(void)
|
||||
|
||||
@@ -36,29 +36,17 @@
|
||||
#ifndef LL_LLPLUGINCLASSMEDIA_H
|
||||
#define LL_LLPLUGINCLASSMEDIA_H
|
||||
|
||||
#include "llpluginclassbasic.h"
|
||||
#include "llgltypes.h"
|
||||
#include "llpluginprocessparent.h"
|
||||
#include "llrect.h"
|
||||
#include "llpluginclassmediaowner.h"
|
||||
#include <queue>
|
||||
#include "v4color.h"
|
||||
|
||||
class LLPluginClassMedia : public LLPluginProcessParentOwner
|
||||
class LLPluginClassMedia : public LLPluginClassBasic
|
||||
{
|
||||
LOG_CLASS(LLPluginClassMedia);
|
||||
|
||||
public:
|
||||
LLPluginClassMedia(LLPluginClassMediaOwner *owner);
|
||||
virtual ~LLPluginClassMedia();
|
||||
|
||||
// local initialization, called by the media manager when creating a source
|
||||
virtual bool init(const std::string &launcher_filename,
|
||||
const std::string &plugin_filename,
|
||||
bool debug);
|
||||
|
||||
// undoes everything init() didm called by the media manager when destroying a source
|
||||
virtual void reset();
|
||||
|
||||
void idle(void);
|
||||
|
||||
// All of these may return 0 or an actual valid value.
|
||||
// Callers need to check the return for 0, and not use the values in that case.
|
||||
@@ -101,22 +89,22 @@ public:
|
||||
bool getDirty(LLRect *dirty_rect = NULL);
|
||||
void resetDirty(void);
|
||||
|
||||
typedef enum
|
||||
enum EMouseEventType
|
||||
{
|
||||
MOUSE_EVENT_DOWN,
|
||||
MOUSE_EVENT_UP,
|
||||
MOUSE_EVENT_MOVE,
|
||||
MOUSE_EVENT_DOUBLE_CLICK
|
||||
}EMouseEventType;
|
||||
};
|
||||
|
||||
void mouseEvent(EMouseEventType type, int button, int x, int y, MASK modifiers);
|
||||
|
||||
typedef enum
|
||||
enum EKeyEventType
|
||||
{
|
||||
KEY_EVENT_DOWN,
|
||||
KEY_EVENT_UP,
|
||||
KEY_EVENT_REPEAT
|
||||
}EKeyEventType;
|
||||
};
|
||||
|
||||
bool keyEvent(EKeyEventType type, int key_code, MASK modifiers, LLSD native_key_data);
|
||||
|
||||
@@ -127,39 +115,13 @@ public:
|
||||
|
||||
void loadURI(const std::string &uri);
|
||||
|
||||
// "Loading" means uninitialized or any state prior to fully running (processing commands)
|
||||
bool isPluginLoading(void) { return mPlugin?mPlugin->isLoading():false; };
|
||||
|
||||
// "Running" means the steady state -- i.e. processing messages
|
||||
bool isPluginRunning(void) { return mPlugin?mPlugin->isRunning():false; };
|
||||
|
||||
// "Exited" means any regular or error state after "Running" (plugin may have crashed or exited normally)
|
||||
bool isPluginExited(void) { return mPlugin?mPlugin->isDone():false; };
|
||||
|
||||
std::string getPluginVersion() { return mPlugin?mPlugin->getPluginVersion():std::string(""); };
|
||||
|
||||
bool getDisableTimeout() { return mPlugin?mPlugin->getDisableTimeout():false; };
|
||||
void setDisableTimeout(bool disable) { if(mPlugin) mPlugin->setDisableTimeout(disable); };
|
||||
|
||||
// Inherited from LLPluginProcessParentOwner
|
||||
/* virtual */ void receivePluginMessage(const LLPluginMessage &message);
|
||||
/* virtual */ void pluginLaunchFailed();
|
||||
/* virtual */ void pluginDied();
|
||||
// Inherited from LLPluginClassBasic
|
||||
/* virtual */ void priorityChanged(EPriority priority);
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PRIORITY_UNLOADED, // media plugin isn't even loaded.
|
||||
PRIORITY_STOPPED, // media is not playing, shouldn't need to update at all.
|
||||
PRIORITY_HIDDEN, // media is not being displayed or is out of view, don't need to do graphic updates, but may still update audio, playhead, etc.
|
||||
PRIORITY_SLIDESHOW, // media is in the far distance, updates very infrequently
|
||||
PRIORITY_LOW, // media is in the distance, may be rendered at reduced size
|
||||
PRIORITY_NORMAL, // normal (default) priority
|
||||
PRIORITY_HIGH // media has user focus and/or is taking up most of the screen
|
||||
}EPriority;
|
||||
|
||||
static const char* priorityToString(EPriority priority);
|
||||
void setPriority(EPriority priority);
|
||||
void setLowPrioritySizeLimit(int size);
|
||||
|
||||
F64 getCPUUsage();
|
||||
@@ -256,17 +218,18 @@ public:
|
||||
void initializeUrlHistory(const LLSD& url_history);
|
||||
|
||||
protected:
|
||||
|
||||
LLPluginClassMediaOwner *mOwner;
|
||||
virtual bool init_impl(void);
|
||||
virtual void reset_impl(void);
|
||||
virtual void idle_impl(void);
|
||||
|
||||
// Notify this object's owner that an event has occurred.
|
||||
void mediaEvent(LLPluginClassMediaOwner::EMediaEvent event);
|
||||
|
||||
void sendMessage(const LLPluginMessage &message); // Send message internally, either queueing or sending directly.
|
||||
std::queue<LLPluginMessage> mSendQueue; // Used to queue messages while the plugin initializes.
|
||||
|
||||
void setSizeInternal(void);
|
||||
|
||||
protected:
|
||||
LLPluginClassMediaOwner *mOwner;
|
||||
|
||||
bool mTextureParamsReceived; // the mRequestedTexture* fields are only valid when this is true
|
||||
S32 mRequestedTextureDepth;
|
||||
LLGLenum mRequestedTextureInternalFormat;
|
||||
@@ -313,16 +276,11 @@ protected:
|
||||
|
||||
float mRequestedVolume;
|
||||
|
||||
// Priority of this media stream
|
||||
EPriority mPriority;
|
||||
int mLowPrioritySizeLimit;
|
||||
|
||||
bool mAllowDownsample;
|
||||
int mPadding;
|
||||
|
||||
|
||||
LLPluginProcessParent *mPlugin;
|
||||
|
||||
LLRect mDirtyRect;
|
||||
|
||||
std::string translateModifiers(MASK modifiers);
|
||||
@@ -332,8 +290,6 @@ protected:
|
||||
int mLastMouseY;
|
||||
|
||||
LLPluginClassMediaOwner::EMediaStatus mStatus;
|
||||
|
||||
F64 mSleepTime;
|
||||
|
||||
bool mCanCut;
|
||||
bool mCanCopy;
|
||||
@@ -363,15 +319,6 @@ protected:
|
||||
F64 mDuration;
|
||||
F64 mCurrentRate;
|
||||
F64 mLoadedDuration;
|
||||
|
||||
//--------------------------------------
|
||||
//debug use only
|
||||
//
|
||||
private:
|
||||
bool mDeleteOK ;
|
||||
public:
|
||||
void setDeleteOK(bool flag) { mDeleteOK = flag ;}
|
||||
//--------------------------------------
|
||||
};
|
||||
|
||||
#endif // LL_LLPLUGINCLASSMEDIA_H
|
||||
|
||||
@@ -55,8 +55,8 @@ const char *LLPluginInstance::PLUGIN_INIT_FUNCTION_NAME = "LLPluginInitEntryPoin
|
||||
*/
|
||||
LLPluginInstance::LLPluginInstance(LLPluginInstanceMessageListener *owner) :
|
||||
mDSOHandle(NULL),
|
||||
mPluginUserData(NULL),
|
||||
mPluginSendMessageFunction(NULL)
|
||||
mPluginObject(NULL),
|
||||
mReceiveMessageFunction(NULL)
|
||||
{
|
||||
mOwner = owner;
|
||||
}
|
||||
@@ -109,9 +109,9 @@ int LLPluginInstance::load(std::string &plugin_file)
|
||||
|
||||
if(result == APR_SUCCESS)
|
||||
{
|
||||
result = init_function(staticReceiveMessage, (void*)this, &mPluginSendMessageFunction, &mPluginUserData);
|
||||
result = init_function(&LLPluginInstance::staticReceiveMessage, this, &mReceiveMessageFunction, &mPluginObject);
|
||||
|
||||
if(result != APR_SUCCESS)
|
||||
if(result != 0)
|
||||
{
|
||||
LL_WARNS("Plugin") << "call to init function failed with error " << result << LL_ENDL;
|
||||
}
|
||||
@@ -120,6 +120,14 @@ int LLPluginInstance::load(std::string &plugin_file)
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
// This is the SLPlugin process (the child process).
|
||||
// This is not part of a DSO.
|
||||
//
|
||||
// This function is called from LLPluginProcessChild::receiveMessageRaw
|
||||
// for messages received from the viewer that are not internal.
|
||||
//
|
||||
// It sends the message to the DSO by calling the registered 'received'
|
||||
// function (for example, FilepickerPlugin::receiveMessage).
|
||||
/**
|
||||
* Sends a message to the plugin.
|
||||
*
|
||||
@@ -127,10 +135,10 @@ int LLPluginInstance::load(std::string &plugin_file)
|
||||
*/
|
||||
void LLPluginInstance::sendMessage(const std::string &message)
|
||||
{
|
||||
if(mPluginSendMessageFunction)
|
||||
if(mReceiveMessageFunction)
|
||||
{
|
||||
LL_DEBUGS("Plugin") << "sending message to plugin: \"" << message << "\"" << LL_ENDL;
|
||||
mPluginSendMessageFunction(message.c_str(), &mPluginUserData);
|
||||
mReceiveMessageFunction(message.c_str(), &mPluginObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -147,14 +155,19 @@ void LLPluginInstance::idle(void)
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPluginInstance::staticReceiveMessage(const char *message_string, void **user_data)
|
||||
void LLPluginInstance::staticReceiveMessage(char const* message_string, LLPluginInstance** self_ptr)
|
||||
{
|
||||
// TODO: validate that the user_data argument is still a valid LLPluginInstance pointer
|
||||
// TODO: validate that the self argument is still a valid LLPluginInstance pointer
|
||||
// we could also use a key that's looked up in a map (instead of a direct pointer) for safety, but that's probably overkill
|
||||
LLPluginInstance *self = (LLPluginInstance*)*user_data;
|
||||
self->receiveMessage(message_string);
|
||||
(*self_ptr)->receiveMessage(message_string);
|
||||
}
|
||||
|
||||
// This is the SLPlugin process.
|
||||
// This is not part of a DSO.
|
||||
//
|
||||
// This function is called by a loaded DSO (through a function pointer, it
|
||||
// is called from BasicPluginBase::sendMessage) for messages it wants to
|
||||
// send to the viewer. It calls LLPluginProcessChild::receivePluginMessage.
|
||||
/**
|
||||
* Plugin receives message from plugin loader shell.
|
||||
*
|
||||
|
||||
@@ -51,6 +51,8 @@ public:
|
||||
virtual void receivePluginMessage(const std::string &message) = 0;
|
||||
};
|
||||
|
||||
class BasicPluginBase;
|
||||
|
||||
/**
|
||||
* @brief LLPluginInstance handles loading the dynamic library of a plugin and setting up its entry points for message passing.
|
||||
*/
|
||||
@@ -79,26 +81,28 @@ public:
|
||||
* @param[in] message_string Null-terminated C string
|
||||
* @param[in] user_data The opaque reference that the callee supplied during setup.
|
||||
*/
|
||||
typedef void (*sendMessageFunction) (const char *message_string, void **user_data);
|
||||
typedef void (*receiveMessageFunction)(char const* message_string, BasicPluginBase** plugin_object);
|
||||
|
||||
typedef void (*sendMessageFunction)(char const* message_string, LLPluginInstance** plugin_instance);
|
||||
|
||||
/** The signature of the plugin init function. TODO:DOC check direction (pluging loader shell to plugin?)
|
||||
*
|
||||
* @param[in] host_user_data Data from plugin loader shell.
|
||||
* @param[in] plugin_send_function Function for sending from the plugin loader shell to plugin.
|
||||
*/
|
||||
typedef int (*pluginInitFunction) (sendMessageFunction host_send_func, void *host_user_data, sendMessageFunction *plugin_send_func, void **plugin_user_data);
|
||||
typedef int (*pluginInitFunction)(sendMessageFunction send_message_function, LLPluginInstance* plugin_instance, receiveMessageFunction* receive_message_function, BasicPluginBase** plugin_object);
|
||||
|
||||
/** Name of plugin init function */
|
||||
static const char *PLUGIN_INIT_FUNCTION_NAME;
|
||||
|
||||
private:
|
||||
static void staticReceiveMessage(const char *message_string, void **user_data);
|
||||
static void staticReceiveMessage(char const* message_string, LLPluginInstance** plugin_instance);
|
||||
void receiveMessage(const char *message_string);
|
||||
|
||||
apr_dso_handle_t *mDSOHandle;
|
||||
|
||||
void *mPluginUserData;
|
||||
sendMessageFunction mPluginSendMessageFunction;
|
||||
BasicPluginBase* mPluginObject;
|
||||
receiveMessageFunction mReceiveMessageFunction;
|
||||
|
||||
LLPluginInstanceMessageListener *mOwner;
|
||||
};
|
||||
|
||||
@@ -99,8 +99,10 @@ public:
|
||||
// (this clears out all existing state before starting the parse)
|
||||
// Returns -1 on failure, otherwise returns the number of key/value pairs in the message.
|
||||
int parse(const std::string &message);
|
||||
|
||||
|
||||
|
||||
// For debugging purposes.
|
||||
friend std::ostream& operator<<(std::ostream& os, LLPluginMessage const& message) { return os << message.mMessage; }
|
||||
|
||||
private:
|
||||
|
||||
LLSD mMessage;
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
#define LLPLUGIN_MESSAGE_CLASS_BASE "base"
|
||||
#define LLPLUGIN_MESSAGE_CLASS_BASE_VERSION "1.0"
|
||||
|
||||
#define LLPLUGIN_MESSAGE_CLASS_BASIC "basic"
|
||||
#define LLPLUGIN_MESSAGE_CLASS_BASIC_VERSION "1.0"
|
||||
|
||||
#define LLPLUGIN_MESSAGE_CLASS_MEDIA "media"
|
||||
#define LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION "1.0"
|
||||
|
||||
|
||||
@@ -286,6 +286,11 @@ bool LLPluginProcessChild::isDone(void)
|
||||
return result;
|
||||
}
|
||||
|
||||
// This is the SLPlugin process.
|
||||
// This is not part of a DSO.
|
||||
//
|
||||
// This function is called by SLPlugin to send a message (originating from
|
||||
// SLPlugin itself) to the loaded DSO. It calls LLPluginInstance::sendMessage.
|
||||
void LLPluginProcessChild::sendMessageToPlugin(const LLPluginMessage &message)
|
||||
{
|
||||
if (mInstance)
|
||||
@@ -305,15 +310,26 @@ void LLPluginProcessChild::sendMessageToPlugin(const LLPluginMessage &message)
|
||||
}
|
||||
}
|
||||
|
||||
// This is the SLPlugin process (the child process).
|
||||
// This is not part of a DSO.
|
||||
//
|
||||
// This function is called by SLPlugin to send 'message' to the viewer (the parent process).
|
||||
void LLPluginProcessChild::sendMessageToParent(const LLPluginMessage &message)
|
||||
{
|
||||
std::string buffer = message.generate();
|
||||
|
||||
LL_DEBUGS("Plugin") << "Sending to parent: " << buffer << LL_ENDL;
|
||||
|
||||
// Write the serialized message to the pipe.
|
||||
writeMessageRaw(buffer);
|
||||
}
|
||||
|
||||
// This is the SLPlugin process (the child process).
|
||||
// This is not part of a DSO.
|
||||
//
|
||||
// This function is called when the serialized message 'message' was received from the viewer.
|
||||
// It parses the message and handles LLPLUGIN_MESSAGE_CLASS_INTERNAL.
|
||||
// Other message classes are passed on to LLPluginInstance::sendMessage.
|
||||
void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
|
||||
{
|
||||
// Incoming message from the TCP Socket
|
||||
@@ -449,7 +465,17 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */
|
||||
// This is the SLPlugin process.
|
||||
// This is not part of a DSO.
|
||||
//
|
||||
// This function is called from LLPluginInstance::receiveMessage
|
||||
// for messages from a loaded DSO that have to be passed to the
|
||||
// viewer.
|
||||
//
|
||||
// It handles the base messages that are responses to messages sent by this
|
||||
// class, and passes the rest on to LLPluginMessagePipeOwner::writeMessageRaw
|
||||
// to be written to the pipe.
|
||||
/* virtual */
|
||||
void LLPluginProcessChild::receivePluginMessage(const std::string &message)
|
||||
{
|
||||
LL_DEBUGS("Plugin") << "Received from plugin: " << message << LL_ENDL;
|
||||
|
||||
@@ -579,6 +579,9 @@ void LLPluginProcessParent::setSleepTime(F64 sleep_time, bool force_send)
|
||||
}
|
||||
}
|
||||
|
||||
// This is the viewer process (the parent process)
|
||||
//
|
||||
// This function is called to send a message to the plugin.
|
||||
void LLPluginProcessParent::sendMessage(const LLPluginMessage &message)
|
||||
{
|
||||
if(message.hasValue("blocking_response"))
|
||||
@@ -588,6 +591,11 @@ void LLPluginProcessParent::sendMessage(const LLPluginMessage &message)
|
||||
// reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked.
|
||||
mHeartbeat.setTimerExpirySec(mPluginLockupTimeout);
|
||||
}
|
||||
if (message.hasValue("gorgon"))
|
||||
{
|
||||
// After this message it is expected that the plugin will not send any more messages for a long time.
|
||||
mBlocked = true;
|
||||
}
|
||||
|
||||
std::string buffer = message.generate();
|
||||
LL_DEBUGS("Plugin") << "Sending: " << buffer << LL_ENDL;
|
||||
@@ -636,6 +644,16 @@ void LLPluginProcessParent::setMessagePipe(LLPluginMessagePipe *message_pipe)
|
||||
}
|
||||
}
|
||||
|
||||
apr_status_t LLPluginProcessParent::socketError(apr_status_t error)
|
||||
{
|
||||
mSocketError = error;
|
||||
if (APR_STATUS_IS_EPIPE(error))
|
||||
{
|
||||
errorState();
|
||||
}
|
||||
return error;
|
||||
};
|
||||
|
||||
//static
|
||||
void LLPluginProcessParent::dirtyPollSet()
|
||||
{
|
||||
@@ -852,6 +870,10 @@ void LLPluginProcessParent::servicePoll()
|
||||
}
|
||||
}
|
||||
|
||||
// This the viewer process (the parent process).
|
||||
//
|
||||
// This function is called when a message is received from a plugin.
|
||||
// It parses the message and passes it on to LLPluginProcessParent::receiveMessage.
|
||||
void LLPluginProcessParent::receiveMessageRaw(const std::string &message)
|
||||
{
|
||||
LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL;
|
||||
@@ -863,6 +885,13 @@ void LLPluginProcessParent::receiveMessageRaw(const std::string &message)
|
||||
{
|
||||
mBlocked = true;
|
||||
}
|
||||
if(parsed.hasValue("perseus"))
|
||||
{
|
||||
mBlocked = false;
|
||||
|
||||
// reset the heartbeat timer, since there will have been no heartbeats while the plugin was blocked.
|
||||
mHeartbeat.setTimerExpirySec(mPluginLockupTimeout);
|
||||
}
|
||||
|
||||
if(mPolledInput)
|
||||
{
|
||||
@@ -905,6 +934,12 @@ void LLPluginProcessParent::receiveMessageEarly(const LLPluginMessage &message)
|
||||
}
|
||||
}
|
||||
|
||||
// This is the viewer process (the parent process).
|
||||
//
|
||||
// This function is called for messages that have to
|
||||
// be written to the plugin.
|
||||
// Note that LLPLUGIN_MESSAGE_CLASS_INTERNAL messages
|
||||
// are not sent to the plugin, but are handled here.
|
||||
void LLPluginProcessParent::receiveMessage(const LLPluginMessage &message)
|
||||
{
|
||||
std::string message_class = message.getClass();
|
||||
|
||||
@@ -99,6 +99,7 @@ public:
|
||||
/*virtual*/ void receiveMessageRaw(const std::string &message);
|
||||
/*virtual*/ void receiveMessageEarly(const LLPluginMessage &message);
|
||||
/*virtual*/ void setMessagePipe(LLPluginMessagePipe *message_pipe) ;
|
||||
/*virtual*/ apr_status_t socketError(apr_status_t error);
|
||||
|
||||
// This adds a memory segment shared with the client, generating a name for the segment. The name generated is guaranteed to be unique on the host.
|
||||
// The caller must call removeSharedMemory first (and wait until getSharedMemorySize returns 0 for the indicated name) before re-adding a segment with the same name.
|
||||
|
||||
Reference in New Issue
Block a user