summaryrefslogtreecommitdiff
path: root/indra/llplugin
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llplugin')
-rw-r--r--indra/llplugin/CMakeLists.txt2
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp54
-rw-r--r--indra/llplugin/llpluginclassmedia.h25
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp169
-rw-r--r--indra/llplugin/llpluginprocessparent.h9
-rw-r--r--indra/llplugin/slplugin/CMakeLists.txt39
6 files changed, 172 insertions, 126 deletions
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index 7fa5c957b6..0525e3d9ea 100644
--- a/indra/llplugin/CMakeLists.txt
+++ b/indra/llplugin/CMakeLists.txt
@@ -35,7 +35,7 @@ list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES})
add_library (llplugin ${llplugin_SOURCE_FILES})
target_include_directories( llplugin INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
-target_link_libraries( llplugin llcommon llmath llrender llmessage )
+target_link_libraries( llplugin llcommon llmath llmessage llxml )
add_subdirectory(slplugin)
include(LibraryInstall)
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 17f403e8e8..53a338b3d6 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -33,9 +33,7 @@
#include "llpluginmessageclasses.h"
#include "llcontrol.h"
-#if LL_DARWIN || LL_LINUX || __FreeBSD__
extern LLControlGroup gSavedSettings;
-#endif
#if LL_DARWIN
extern bool gHiDPISupport;
#endif
@@ -134,9 +132,13 @@ void LLPluginClassMedia::reset()
mLastMouseY = 0;
mStatus = LLPluginClassMediaOwner::MEDIA_NONE;
mSleepTime = 1.0f / 100.0f;
+ mCanUndo = false;
+ mCanRedo = false;
mCanCut = false;
mCanCopy = false;
mCanPaste = false;
+ mCanDoDelete = false;
+ mCanSelectAll = false;
mMediaName.clear();
mMediaDescription.clear();
mBackgroundColor = LLColor4(1.0f, 1.0f, 1.0f, 1.0f);
@@ -909,6 +911,18 @@ void LLPluginClassMedia::sendAuthResponse(bool ok, const std::string &username,
sendMessage(message);
}
+void LLPluginClassMedia::undo()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_undo");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::redo()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_redo");
+ sendMessage(message);
+}
+
void LLPluginClassMedia::cut()
{
LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_cut");
@@ -927,6 +941,24 @@ void LLPluginClassMedia::paste()
sendMessage(message);
}
+void LLPluginClassMedia::doDelete()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_delete");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::selectAll()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_select_all");
+ sendMessage(message);
+}
+
+void LLPluginClassMedia::showPageSource()
+{
+ LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "edit_show_source");
+ sendMessage(message);
+}
+
void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache,
const std::string &username,
const std::string &user_data_path_cef_log)
@@ -936,10 +968,8 @@ void LLPluginClassMedia::setUserDataPath(const std::string &user_data_path_cache
message.setValue("username", username); // cef shares cache between users but creates user-based contexts
message.setValue("cef_log_file", user_data_path_cef_log);
-#if LL_DARWIN || LL_LINUX || __FreeBSD__
bool cef_verbose_log = gSavedSettings.getBOOL("CefVerboseLog");
message.setValueBoolean("cef_verbose_log", cef_verbose_log);
-#endif
sendMessage(message);
}
@@ -1191,6 +1221,14 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
}
else if(message_name == "edit_state")
{
+ if(message.hasValue("undo"))
+ {
+ mCanUndo = message.getValueBoolean("undo");
+ }
+ if(message.hasValue("redo"))
+ {
+ mCanRedo = message.getValueBoolean("redo");
+ }
if(message.hasValue("cut"))
{
mCanCut = message.getValueBoolean("cut");
@@ -1203,6 +1241,14 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
{
mCanPaste = message.getValueBoolean("paste");
}
+ if (message.hasValue("delete"))
+ {
+ mCanDoDelete = message.getValueBoolean("delete");
+ }
+ if (message.hasValue("select_all"))
+ {
+ mCanSelectAll = message.getValueBoolean("select_all");
+ }
}
else if(message_name == "name_text")
{
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 80862284ff..6c512003cc 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -29,7 +29,6 @@
#ifndef LL_LLPLUGINCLASSMEDIA_H
#define LL_LLPLUGINCLASSMEDIA_H
-#include "llgltypes.h"
#include "llpluginprocessparent.h"
#include "llrect.h"
#include "llpluginclassmediaowner.h"
@@ -205,6 +204,12 @@ public:
LLPluginClassMediaOwner::EMediaStatus getStatus() const { return mStatus; }
+ void undo();
+ bool canUndo() const { return mCanUndo; };
+
+ void redo();
+ bool canRedo() const { return mCanRedo; };
+
void cut();
bool canCut() const { return mCanCut; };
@@ -214,6 +219,14 @@ public:
void paste();
bool canPaste() const { return mCanPaste; };
+ void doDelete();
+ bool canDoDelete() const { return mCanDoDelete; };
+
+ void selectAll();
+ bool canSelectAll() const { return mCanSelectAll; };
+
+ void showPageSource();
+
// These can be called before init(), and they will be queued and sent before the media init message.
void setUserDataPath(const std::string &user_data_path_cache, const std::string &username, const std::string &user_data_path_cef_log);
void setLanguageCode(const std::string &language_code);
@@ -357,9 +370,9 @@ protected:
bool mTextureParamsReceived; // the mRequestedTexture* fields are only valid when this is true
S32 mRequestedTextureDepth;
- LLGLenum mRequestedTextureInternalFormat;
- LLGLenum mRequestedTextureFormat;
- LLGLenum mRequestedTextureType;
+ U32 mRequestedTextureInternalFormat;
+ U32 mRequestedTextureFormat;
+ U32 mRequestedTextureType;
bool mRequestedTextureSwapBytes;
bool mRequestedTextureCoordsOpenGL;
@@ -425,9 +438,13 @@ protected:
F64 mSleepTime;
+ bool mCanUndo;
+ bool mCanRedo;
bool mCanCut;
bool mCanCopy;
bool mCanPaste;
+ bool mCanDoDelete;
+ bool mCanSelectAll;
std::string mMediaName;
std::string mMediaTitle;
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 00abcf740f..63f1de8d6a 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -34,6 +34,9 @@
#include "llpluginmessageclasses.h"
#include "llsdserialize.h"
#include "stringize.h"
+#include "threadpool.h"
+#include "workqueue.h"
+
#include "llapr.h"
//virtual
@@ -45,7 +48,7 @@ LLPluginProcessParentOwner::~LLPluginProcessParentOwner()
bool LLPluginProcessParent::sUseReadThread = false;
apr_pollset_t *LLPluginProcessParent::sPollSet = NULL;
bool LLPluginProcessParent::sPollsetNeedsRebuild = false;
-LLCoros::Mutex *LLPluginProcessParent::sInstancesMutex;
+LLCoros::Mutex *LLPluginProcessParent::sInstancesMutex = nullptr;
LLPluginProcessParent::mapInstances_t LLPluginProcessParent::sInstances;
LLThread *LLPluginProcessParent::sReadThread = NULL;
@@ -79,29 +82,8 @@ protected:
};
-
-class LLPluginProcessCreationThread : public LLThread
-{
-public:
- LLPluginProcessCreationThread(LLPluginProcessParent *parent) :
- LLThread("LLPluginProcessCreationThread", gAPRPoolp),
- pParent(parent)
- {
- }
-protected:
- // Inherited from LLThread, should run once
- /*virtual*/ void run(void)
- {
- pParent->createPluginProcess();
- }
-private:
- LLPluginProcessParent *pParent;
-
-};
-
LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
- mIncomingQueueMutex(),
- pProcessCreationThread(NULL)
+ mIncomingQueueMutex()
{
if(!sInstancesMutex)
{
@@ -130,18 +112,6 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner):
LLPluginProcessParent::~LLPluginProcessParent()
{
LL_DEBUGS("Plugin") << "destructor" << LL_ENDL;
- if (pProcessCreationThread)
- {
- if (!pProcessCreationThread->isStopped())
- {
- // Shouldn't happen at this stage
- LL_WARNS("Plugin") << "Shutting down active pProcessCreationThread" << LL_ENDL;
- pProcessCreationThread->shutdown();
- ms_sleep(20);
- }
- delete pProcessCreationThread;
- pProcessCreationThread = NULL;
- }
// Destroy any remaining shared memory regions
sharedMemoryRegionsType::iterator iter;
@@ -185,6 +155,12 @@ LLPluginProcessParent::ptr_t LLPluginProcessParent::create(LLPluginProcessParent
/*static*/
void LLPluginProcessParent::shutdown()
{
+ if (!sInstancesMutex)
+ {
+ // setup was not complete, skip shutdown
+ return;
+ }
+
LLCoros::LockType lock(*sInstancesMutex);
mapInstances_t::iterator it;
@@ -299,6 +275,9 @@ void LLPluginProcessParent::init(const std::string &launcher_filename, const std
{
mProcessParams.executable = launcher_filename;
mProcessParams.cwd = plugin_dir;
+#if LL_WINDOWS
+ mProcessParams.envs.add(llformat("SYSTEMROOT=%s", getenv("SYSTEMROOT")));
+#endif
mPluginFile = plugin_filename;
mPluginDir = plugin_dir;
mCPUUsage = 0.0f;
@@ -352,35 +331,6 @@ bool LLPluginProcessParent::accept()
return result;
}
-bool LLPluginProcessParent::createPluginProcess()
-{
- if (!mProcess)
- {
- // Only argument to the launcher is the port number we're listening on
- mProcessParams.args.add(stringize(mBoundPort));
- mProcess = LLProcess::create(mProcessParams);
- return mProcess != NULL;
- }
-
- return false;
-}
-
-void LLPluginProcessParent::clearProcessCreationThread()
-{
- if (pProcessCreationThread)
- {
- if (!pProcessCreationThread->isStopped())
- {
- pProcessCreationThread->shutdown();
- }
- else
- {
- delete pProcessCreationThread;
- pProcessCreationThread = NULL;
- }
- }
-}
-
void LLPluginProcessParent::idle(void)
{
bool idle_again;
@@ -453,9 +403,14 @@ void LLPluginProcessParent::idle(void)
apr_sockaddr_t* addr = NULL;
mListenSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
mBoundPort = 0;
+ if (!mListenSocket)
+ {
+ killSockets();
+ errorState();
+ break;
+ }
// This code is based on parts of LLSocket::create() in lliosocket.cpp.
-
status = apr_sockaddr_info_get(
&addr,
"127.0.0.1",
@@ -542,30 +497,72 @@ void LLPluginProcessParent::idle(void)
case STATE_LISTENING:
{
+ // Only argument to the launcher is the port number we're listening on
+ mProcessParams.args.add(stringize(mBoundPort));
+
// Launch the plugin process.
- if (mDebug && !pProcessCreationThread)
+ if (mDebug && !mProcess)
{
- createPluginProcess();
- if (!mProcess)
+ if (!(mProcess = LLProcess::create(mProcessParams)))
{
errorState();
}
}
- else if (pProcessCreationThread == NULL)
+ else if (!mProcess && !mProcessCreationRequested)
{
- // exe plugin process allocation can be hindered by a number
- // of factors, don't hold whole viewer because of it, use thread
- pProcessCreationThread = new LLPluginProcessCreationThread(this);
- pProcessCreationThread->start();
- }
- else if (!mProcess && pProcessCreationThread->isStopped())
- {
- delete pProcessCreationThread;
- pProcessCreationThread = NULL;
- errorState();
+ mProcessCreationRequested = true;
+ LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
+ // *NOTE: main_queue->postTo casts this refcounted smart pointer to a weak
+ // pointer
+ LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
+ llassert_always(main_queue);
+ llassert_always(general_queue);
+
+ auto process_params = mProcessParams;
+
+ bool posted = main_queue->postTo(
+ general_queue,
+ [process_params]() // Work done on general queue
+ {
+ return LLProcess::create(process_params);
+ },
+ [this](LLProcessPtr new_process) // Callback to main thread
+ mutable {
+ ptr_t that;
+ {
+ // this grabs a copy of the smart pointer to ourselves to ensure that we do not
+ // get destroyed until after this method returns.
+ LLCoros::LockType lock(*sInstancesMutex);
+ mapInstances_t::iterator it = sInstances.find(this);
+ if (it != sInstances.end())
+ that = (*it).second;
+ }
+
+ if (that)
+ {
+ if (new_process)
+ {
+ that->mProcess = new_process;
+ }
+ else
+ {
+ that->mProcessCreationRequested = false;
+ that->errorState();
+ }
+ }
+
+ });
+ if (!posted)
+ {
+ LL_WARNS("Plugin") << "Failed to dispath process creation to threadpool" << LL_ENDL;
+ if (!(mProcess = LLProcess::create(mProcessParams)))
+ {
+ mProcessCreationRequested = false;
+ errorState();
+ }
+ }
}
-
if (mProcess)
{
if(mDebug)
@@ -581,7 +578,7 @@ void LLPluginProcessParent::idle(void)
params.args.add("-e");
params.args.add("tell application \"Terminal\"");
params.args.add("-e");
- params.args.add(STRINGIZE("set win to do script \"lldb -pid "
+ params.args.add(STRINGIZE("set win to do script \"lldb -p "
<< mProcess->getProcessID() << "\""));
params.args.add("-e");
params.args.add("do script \"continue\" in win");
@@ -595,15 +592,6 @@ void LLPluginProcessParent::idle(void)
// This will allow us to time out if the process never starts.
mHeartbeat.start();
mHeartbeat.setTimerExpirySec(mPluginLaunchTimeout);
-
- // pProcessCreationThread should have stopped by this point,
- // but check just in case it paused on statistics sync
- if (pProcessCreationThread && pProcessCreationThread->isStopped())
- {
- delete pProcessCreationThread;
- pProcessCreationThread = NULL;
- }
-
setState(STATE_LAUNCHED);
}
}
@@ -706,7 +694,6 @@ void LLPluginProcessParent::idle(void)
killSockets();
setState(STATE_DONE);
dirtyPollSet();
- clearProcessCreationThread();
break;
case STATE_DONE:
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index d1c4933d81..334f1411af 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -69,11 +69,6 @@ public:
const std::string &plugin_filename,
bool debug);
- // Creates a process
- // returns true if process already exists or if created,
- // false if failed to create
- bool createPluginProcess();
-
void idle(void);
// returns true if the plugin is on its way to steady state
@@ -168,15 +163,13 @@ private:
bool accept();
- void clearProcessCreationThread();
-
LLSocket::ptr_t mListenSocket;
LLSocket::ptr_t mSocket;
U32 mBoundPort;
LLProcess::Params mProcessParams;
LLProcessPtr mProcess;
- LLThread *pProcessCreationThread;
+ bool mProcessCreationRequested = false;
std::string mPluginFile;
std::string mPluginDir;
diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index 3ad6d10336..38f4c92b09 100644
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -30,18 +30,6 @@ add_executable(SLPlugin
${SLPlugin_SOURCE_FILES}
)
-if (WINDOWS)
-set_target_properties(SLPlugin
- PROPERTIES
- LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMTD\""
- )
-else ()
-set_target_properties(SLPlugin
- PROPERTIES
- MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist
- )
-endif ()
-
target_link_libraries(SLPlugin
llplugin
llmessage
@@ -49,7 +37,20 @@ target_link_libraries(SLPlugin
ll::pluginlibraries
)
-if (DARWIN)
+if (WINDOWS)
+ set_target_properties(SLPlugin
+ PROPERTIES
+ LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMTD\""
+ )
+elseif (DARWIN)
+ set_target_properties(SLPlugin
+ PROPERTIES
+ BUILD_WITH_INSTALL_RPATH 1
+ INSTALL_RPATH "@executable_path/../../../../Frameworks;@executable_path/../Frameworks;@executable_path/../Frameworks/plugins"
+ MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/slplugin_info.plist
+ XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym"
+ )
+
# Make sure the app bundle has a Resources directory (it will get populated by viewer-manifest.py later)
add_custom_command(
TARGET SLPlugin POST_BUILD
@@ -58,7 +59,7 @@ if (DARWIN)
-p
${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/SLPlugin.app/Contents/Frameworks
)
-endif (DARWIN)
+endif ()
if (BUILD_SHARED_LIBS)
set_target_properties(SLPlugin PROPERTIES LINK_FLAGS_RELEASE
@@ -66,12 +67,14 @@ if (BUILD_SHARED_LIBS)
endif ()
if (INSTALL)
- if (DARWIN)
+ if (DARWIN OR WINDOWS)
install(TARGETS ${PROJECT_NAME} DESTINATION .)
- else (DARWIN)
+ elseif (${LINUX_DISTRO} MATCHES arch)
+ install(TARGETS ${PROJECT_NAME} DESTINATION lib/${VIEWER_BINARY_NAME})
+ else ()
install(TARGETS ${PROJECT_NAME} DESTINATION libexec/${VIEWER_BINARY_NAME})
- endif (DARWIN)
-endif (INSTALL)
+ endif ()
+endif ()
if (LL_TESTS)
ll_deploy_sharedlibs_command(SLPlugin)