summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2016-04-04 17:34:03 +0200
committerStephan Bergmann <sbergman@redhat.com>2016-04-04 17:35:32 +0200
commit5da71ff3b088f224cd3a731ce51c620e0cd3e5d3 (patch)
tree1629a7525395269a58ed2f1b4bc2b21d248bec42
parentPrepare for using other IPC mechanisms besides an osl::Pipe (diff)
downloadcore-5da71ff3b088f224cd3a731ce51c620e0cd3e5d3.tar.gz
core-5da71ff3b088f224cd3a731ce51c620e0cd3e5d3.zip
Add DBus-based IPC mechanism for xdg-app
first cut; triggered on LIBO_XDGAPP env var for now Change-Id: If4586aedb58499e36a5d87cc8d171400ce7e9499
-rw-r--r--desktop/Library_sofficeapp.mk5
-rw-r--r--desktop/source/app/officeipcthread.cxx691
-rw-r--r--desktop/source/app/officeipcthread.hxx3
-rw-r--r--desktop/unx/source/start.c2
4 files changed, 500 insertions, 201 deletions
diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk
index 30dc9073ba6d..04bc4913a370 100644
--- a/desktop/Library_sofficeapp.mk
+++ b/desktop/Library_sofficeapp.mk
@@ -23,7 +23,10 @@ $(eval $(call gb_Library_add_libs,sofficeapp,\
) \
))
-$(eval $(call gb_Library_use_external,sofficeapp,boost_headers))
+$(eval $(call gb_Library_use_externals,sofficeapp, \
+ boost_headers \
+ dbus \
+))
ifeq ($(ENABLE_BREAKPAD),TRUE)
$(eval $(call gb_Library_use_external,sofficeapp,breakpad))
diff --git a/desktop/source/app/officeipcthread.cxx b/desktop/source/app/officeipcthread.cxx
index c4f50f4bbbea..a5d9ac7b6f5f 100644
--- a/desktop/source/app/officeipcthread.cxx
+++ b/desktop/source/app/officeipcthread.cxx
@@ -17,6 +17,9 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <sal/config.h>
+
+#include <config_dbus.h>
#include <config_features.h>
#include "app.hxx"
@@ -44,8 +47,13 @@
#include <tools/getprocessworkingdir.hxx>
#include <cassert>
+#include <cstdlib>
#include <memory>
+#if ENABLE_DBUS
+#include <dbus/dbus.h>
+#endif
+
using namespace desktop;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
@@ -365,6 +373,8 @@ protected:
virtual ~IpcThread() {}
+ bool process(OString const & arguments, bool * wait);
+
RequestHandler * handler_;
};
@@ -386,6 +396,262 @@ private:
osl::Pipe pipe_;
};
+#if ENABLE_DBUS
+
+namespace {
+
+struct DbusConnectionHolder {
+ explicit DbusConnectionHolder(DBusConnection * theConnection):
+ connection(theConnection)
+ {}
+
+ ~DbusConnectionHolder() { clear(); }
+
+ void clear() {
+ if (connection != nullptr) {
+ dbus_connection_unref(connection);
+ }
+ connection = nullptr;
+ }
+
+ DBusConnection * connection;
+
+private:
+ DbusConnectionHolder(DbusConnectionHolder &) = delete;
+ void operator =(DbusConnectionHolder) = delete;
+};
+
+struct DbusMessageHolder {
+ explicit DbusMessageHolder(DBusMessage * theMessage): message(theMessage) {}
+
+ ~DbusMessageHolder() { clear(); }
+
+ void clear() {
+ if (message != nullptr) {
+ dbus_message_unref(message);
+ }
+ message = nullptr;
+ }
+
+ DBusMessage * message;
+
+private:
+ DbusMessageHolder(DbusMessageHolder &) = delete;
+ void operator =(DbusMessageHolder) = delete;
+};
+
+}
+
+class DbusIpcThread: public IpcThread {
+public:
+ static RequestHandler::Status enable(rtl::Reference<IpcThread> * thread);
+
+private:
+ explicit DbusIpcThread(DBusConnection * connection):
+ IpcThread("DbusIPC"), connection_(connection)
+ {}
+
+ virtual ~DbusIpcThread() {}
+
+ void execute() override;
+
+ void close() override;
+
+ DbusConnectionHolder connection_;
+};
+
+RequestHandler::Status DbusIpcThread::enable(rtl::Reference<IpcThread> * thread)
+{
+ assert(thread != nullptr);
+ if (!dbus_threads_init_default()) {
+ SAL_WARN("desktop.app", "dbus_threads_init_default failed");
+ return RequestHandler::IPC_STATUS_BOOTSTRAP_ERROR;
+ }
+ DBusError e;
+ dbus_error_init(&e);
+ DbusConnectionHolder con(dbus_bus_get(DBUS_BUS_SESSION, &e));
+ assert((con.connection == nullptr) == bool(dbus_error_is_set(&e)));
+ if (con.connection == nullptr) {
+ SAL_WARN(
+ "desktop.app",
+ "dbus_bus_get failed with: " << e.name << ": " << e.message);
+ dbus_error_free(&e);
+ return RequestHandler::IPC_STATUS_BOOTSTRAP_ERROR;
+ }
+ for (;;) {
+ int n = dbus_bus_request_name(
+ con.connection, "org.libreoffice.LibreOfficeIpc0",
+ DBUS_NAME_FLAG_DO_NOT_QUEUE, &e);
+ assert((n == -1) == bool(dbus_error_is_set(&e)));
+ switch (n) {
+ case -1:
+ SAL_WARN(
+ "desktop.app",
+ "dbus_bus_request_name failed with: " << e.name << ": "
+ << e.message);
+ dbus_error_free(&e);
+ return RequestHandler::IPC_STATUS_BOOTSTRAP_ERROR;
+ case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
+ *thread = new DbusIpcThread(con.connection);
+ con.connection = nullptr;
+ return RequestHandler::IPC_STATUS_OK;
+ case DBUS_REQUEST_NAME_REPLY_EXISTS:
+ {
+ OStringBuffer buf(ARGUMENT_PREFIX);
+ OUString arg;
+ if (!(tools::getProcessWorkingDir(arg)
+ && addArgument(buf, '1', arg)))
+ {
+ buf.append('0');
+ }
+ sal_uInt32 narg = rtl_getAppCommandArgCount();
+ for (sal_uInt32 i = 0; i != narg; ++i) {
+ rtl_getAppCommandArg(i, &arg.pData);
+ if (!addArgument(buf, ',', arg)) {
+ return RequestHandler::IPC_STATUS_BOOTSTRAP_ERROR;
+ }
+ }
+ char const * argstr = buf.getStr();
+ DbusMessageHolder msg(
+ dbus_message_new_method_call(
+ "org.libreoffice.LibreOfficeIpc0",
+ "/org/libreoffice/LibreOfficeIpc0",
+ "org.libreoffice.LibreOfficeIpcIfc0", "Execute"));
+ if (msg.message == nullptr) {
+ SAL_WARN(
+ "desktop.app", "dbus_message_new_method_call failed");
+ return RequestHandler::IPC_STATUS_BOOTSTRAP_ERROR;
+ }
+ DBusMessageIter it;
+ dbus_message_iter_init_append(msg.message, &it);
+ if (!dbus_message_iter_append_basic(
+ &it, DBUS_TYPE_STRING, &argstr))
+ {
+ SAL_WARN(
+ "desktop.app", "dbus_message_iter_append_basic failed");
+ return RequestHandler::IPC_STATUS_BOOTSTRAP_ERROR;
+ }
+ DbusMessageHolder repl(
+ dbus_connection_send_with_reply_and_block(
+ con.connection, msg.message, DBUS_TIMEOUT_INFINITE,
+ &e));
+ assert(
+ (repl.message == nullptr) == bool(dbus_error_is_set(&e)));
+ if (repl.message == nullptr) {
+ SAL_INFO(
+ "desktop.app",
+ "dbus_connection_send_with_reply_and_block failed"
+ " with: " << e.name << ": " << e.message);
+ dbus_error_free(&e);
+ break;
+ }
+ return RequestHandler::IPC_STATUS_2ND_OFFICE;
+ }
+ default:
+ assert(false);
+ // fall through
+ case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
+ case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
+ SAL_WARN(
+ "desktop.app",
+ "dbus_bus_request_name failed with unexpected " << +n);
+ return RequestHandler::IPC_STATUS_BOOTSTRAP_ERROR;
+ }
+ }
+}
+
+void DbusIpcThread::execute()
+{
+ assert(handler_ != nullptr);
+ handler_->cReady.wait();
+ for (;;) {
+ {
+ osl::MutexGuard g(RequestHandler::GetMutex());
+ if (handler_->mState == RequestHandler::State::Downing) {
+ break;
+ }
+ }
+ dbus_connection_read_write(connection_.connection, 0);
+ DbusMessageHolder msg(
+ dbus_connection_pop_message(connection_.connection));
+ if (msg.message == nullptr) {
+ continue;
+ }
+ if (!dbus_message_is_method_call(
+ msg.message, "org.libreoffice.LibreOfficeIpcIfc0", "Execute"))
+ {
+ SAL_INFO("desktop.app", "unknown DBus message ignored");
+ continue;
+ }
+ DBusMessageIter it;
+ if (!dbus_message_iter_init(msg.message, &it)) {
+ SAL_WARN("desktop.app", "DBus message without argument ignored");
+ continue;
+ }
+ if (dbus_message_iter_get_arg_type(&it) != DBUS_TYPE_STRING) {
+ SAL_WARN(
+ "desktop.app", "DBus message with non-string argument ignored");
+ continue;
+ }
+ char const * argstr;
+ dbus_message_iter_get_basic(&it, &argstr);
+ bool wait = false;
+ {
+ osl::MutexGuard g(RequestHandler::GetMutex());
+ if (!process(argstr, &wait)) {
+ continue;
+ }
+ }
+ if (wait) {
+ handler_->cProcessed.wait();
+ }
+ DbusMessageHolder repl(dbus_message_new_method_return(msg.message));
+ if (repl.message == nullptr) {
+ SAL_WARN("desktop.app", "dbus_message_new_method_return failed");
+ continue;
+ }
+ dbus_uint32_t serial = 0;
+ if (!dbus_connection_send(
+ connection_.connection, repl.message, &serial)) {
+ SAL_WARN("desktop.app", "dbus_connection_send failed");
+ continue;
+ }
+ dbus_connection_flush(connection_.connection);
+ }
+}
+
+void DbusIpcThread::close() {
+ assert(connection_.connection != nullptr);
+ DBusError e;
+ dbus_error_init(&e);
+ int n = dbus_bus_release_name(
+ connection_.connection, "org.libreoffice.LibreOfficeIpc0", &e);
+ assert((n == -1) == bool(dbus_error_is_set(&e)));
+ switch (n) {
+ case -1:
+ SAL_WARN(
+ "desktop.app",
+ "dbus_bus_release_name failed with: " << e.name << ": "
+ << e.message);
+ dbus_error_free(&e);
+ break;
+ case DBUS_RELEASE_NAME_REPLY_RELEASED:
+ break;
+ default:
+ assert(false);
+ // fall through
+ case DBUS_RELEASE_NAME_REPLY_NOT_OWNER:
+ case DBUS_RELEASE_NAME_REPLY_NON_EXISTENT:
+ SAL_WARN(
+ "desktop.app",
+ "dbus_bus_release_name failed with unexpected " << +n);
+ break;
+ }
+ connection_.clear();
+}
+
+#endif
+
namespace
{
class theRequestHandlerMutex
@@ -462,8 +728,27 @@ RequestHandler::Status RequestHandler::Enable(bool ipc)
return IPC_STATUS_OK;
}
+ enum class Kind { Pipe, Dbus };
+ Kind kind = Kind::Pipe;
+#if ENABLE_DBUS
+ if (std::getenv("LIBO_XDGAPP") != nullptr) {
+ kind = Kind::Dbus;
+ }
+#endif
rtl::Reference<IpcThread> thread;
- Status stat = PipeIpcThread::enable(&thread);
+ Status stat;
+ switch (kind) {
+ case Kind::Pipe:
+ stat = PipeIpcThread::enable(&thread);
+ break;
+ case Kind::Dbus:
+#if ENABLE_DBUS
+ stat = DbusIpcThread::enable(&thread);
+ break;
+#endif
+ default:
+ assert(false);
+ }
assert(thread.is() == (stat == IPC_STATUS_OK));
if (stat == IPC_STATUS_OK) {
pGlobal = new RequestHandler;
@@ -656,6 +941,209 @@ void RequestHandler::WaitForReady()
}
}
+bool IpcThread::process(OString const & arguments, bool * wait) {
+ assert(wait != nullptr);
+
+ std::unique_ptr< CommandLineArgs > aCmdLineArgs;
+ try
+ {
+ Parser p(arguments);
+ aCmdLineArgs.reset( new CommandLineArgs( p ) );
+ }
+ catch ( const CommandLineArgs::Supplier::Exception & )
+ {
+ SAL_WARN("desktop.app", "Error in received command line arguments");
+ return false;
+ }
+
+ bool bDocRequestSent = false;
+
+ OUString aUnknown( aCmdLineArgs->GetUnknown() );
+ if ( !aUnknown.isEmpty() || aCmdLineArgs->IsHelp() )
+ {
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent(ApplicationEvent::TYPE_HELP, aUnknown);
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+ else if ( aCmdLineArgs->IsVersion() )
+ {
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent(ApplicationEvent::TYPE_VERSION);
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+ else
+ {
+ const CommandLineArgs &rCurrentCmdLineArgs = Desktop::GetCommandLineArgs();
+
+ if ( aCmdLineArgs->IsQuickstart() )
+ {
+ // we have to use application event, because we have to start quickstart service in main thread!!
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent(ApplicationEvent::TYPE_QUICKSTART);
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+
+ // handle request for acceptor
+ std::vector< OUString > const & accept = aCmdLineArgs->GetAccept();
+ for (std::vector< OUString >::const_iterator i(accept.begin());
+ i != accept.end(); ++i)
+ {
+ ApplicationEvent* pAppEvent = new ApplicationEvent(
+ ApplicationEvent::TYPE_ACCEPT, *i);
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+ // handle acceptor removal
+ std::vector< OUString > const & unaccept = aCmdLineArgs->GetUnaccept();
+ for (std::vector< OUString >::const_iterator i(unaccept.begin());
+ i != unaccept.end(); ++i)
+ {
+ ApplicationEvent* pAppEvent = new ApplicationEvent(
+ ApplicationEvent::TYPE_UNACCEPT, *i);
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+
+ ProcessDocumentsRequest* pRequest = new ProcessDocumentsRequest(
+ aCmdLineArgs->getCwdUrl());
+ handler_->cProcessed.reset();
+ pRequest->pcProcessed = &handler_->cProcessed;
+
+ // Print requests are not dependent on the --invisible cmdline argument as they are
+ // loaded with the "hidden" flag! So they are always checked.
+ pRequest->aPrintList = aCmdLineArgs->GetPrintList();
+ bDocRequestSent |= !pRequest->aPrintList.empty();
+ pRequest->aPrintToList = aCmdLineArgs->GetPrintToList();
+ pRequest->aPrinterName = aCmdLineArgs->GetPrinterName();
+ bDocRequestSent |= !( pRequest->aPrintToList.empty() || pRequest->aPrinterName.isEmpty() );
+
+ if ( !rCurrentCmdLineArgs.IsInvisible() )
+ {
+ // Read cmdline args that can open/create documents. As they would open a window
+ // they are only allowed if the "--invisible" is currently not used!
+ pRequest->aOpenList = aCmdLineArgs->GetOpenList();
+ bDocRequestSent |= !pRequest->aOpenList.empty();
+ pRequest->aViewList = aCmdLineArgs->GetViewList();
+ bDocRequestSent |= !pRequest->aViewList.empty();
+ pRequest->aStartList = aCmdLineArgs->GetStartList();
+ bDocRequestSent |= !pRequest->aStartList.empty();
+ pRequest->aForceOpenList = aCmdLineArgs->GetForceOpenList();
+ bDocRequestSent |= !pRequest->aForceOpenList.empty();
+ pRequest->aForceNewList = aCmdLineArgs->GetForceNewList();
+ bDocRequestSent |= !pRequest->aForceNewList.empty();
+
+ // Special command line args to create an empty document for a given module
+
+ // #i18338# (lo)
+ // we only do this if no document was specified on the command line,
+ // since this would be inconsistent with the behaviour of
+ // the first process, see OpenClients() (call to OpenDefault()) in app.cxx
+ if ( aCmdLineArgs->HasModuleParam() && !bDocRequestSent )
+ {
+ SvtModuleOptions aOpt;
+ SvtModuleOptions::EFactory eFactory = SvtModuleOptions::EFactory::WRITER;
+ if ( aCmdLineArgs->IsWriter() )
+ eFactory = SvtModuleOptions::EFactory::WRITER;
+ else if ( aCmdLineArgs->IsCalc() )
+ eFactory = SvtModuleOptions::EFactory::CALC;
+ else if ( aCmdLineArgs->IsDraw() )
+ eFactory = SvtModuleOptions::EFactory::DRAW;
+ else if ( aCmdLineArgs->IsImpress() )
+ eFactory = SvtModuleOptions::EFactory::IMPRESS;
+ else if ( aCmdLineArgs->IsBase() )
+ eFactory = SvtModuleOptions::EFactory::DATABASE;
+ else if ( aCmdLineArgs->IsMath() )
+ eFactory = SvtModuleOptions::EFactory::MATH;
+ else if ( aCmdLineArgs->IsGlobal() )
+ eFactory = SvtModuleOptions::EFactory::WRITERGLOBAL;
+ else if ( aCmdLineArgs->IsWeb() )
+ eFactory = SvtModuleOptions::EFactory::WRITERWEB;
+
+ if ( !pRequest->aOpenList.empty() )
+ pRequest->aModule = aOpt.GetFactoryName( eFactory );
+ else
+ pRequest->aOpenList.push_back( aOpt.GetFactoryEmptyDocumentURL( eFactory ) );
+ bDocRequestSent = true;
+ }
+ }
+
+ if ( !aCmdLineArgs->IsQuickstart() ) {
+ bool bShowHelp = false;
+ OUStringBuffer aHelpURLBuffer;
+ if (aCmdLineArgs->IsHelpWriter()) {
+ bShowHelp = true;
+ aHelpURLBuffer.append("vnd.sun.star.help://swriter/start");
+ } else if (aCmdLineArgs->IsHelpCalc()) {
+ bShowHelp = true;
+ aHelpURLBuffer.append("vnd.sun.star.help://scalc/start");
+ } else if (aCmdLineArgs->IsHelpDraw()) {
+ bShowHelp = true;
+ aHelpURLBuffer.append("vnd.sun.star.help://sdraw/start");
+ } else if (aCmdLineArgs->IsHelpImpress()) {
+ bShowHelp = true;
+ aHelpURLBuffer.append("vnd.sun.star.help://simpress/start");
+ } else if (aCmdLineArgs->IsHelpBase()) {
+ bShowHelp = true;
+ aHelpURLBuffer.append("vnd.sun.star.help://sdatabase/start");
+ } else if (aCmdLineArgs->IsHelpBasic()) {
+ bShowHelp = true;
+ aHelpURLBuffer.append("vnd.sun.star.help://sbasic/start");
+ } else if (aCmdLineArgs->IsHelpMath()) {
+ bShowHelp = true;
+ aHelpURLBuffer.append("vnd.sun.star.help://smath/start");
+ }
+ if (bShowHelp) {
+ aHelpURLBuffer.append("?Language=");
+ aHelpURLBuffer.append(utl::ConfigManager::getLocale());
+#if defined UNX
+ aHelpURLBuffer.append("&System=UNX");
+#elif defined WNT
+ aHelpURLBuffer.appendAscii("&System=WIN");
+#endif
+ ApplicationEvent* pAppEvent = new ApplicationEvent(
+ ApplicationEvent::TYPE_OPENHELPURL,
+ aHelpURLBuffer.makeStringAndClear());
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+ }
+
+ if ( bDocRequestSent )
+ {
+ // Send requests to dispatch watcher if we have at least one. The receiver
+ // is responsible to delete the request after processing it.
+ if ( aCmdLineArgs->HasModuleParam() )
+ {
+ SvtModuleOptions aOpt;
+
+ // Support command line parameters to start a module (as preselection)
+ if ( aCmdLineArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
+ pRequest->aModule = aOpt.GetFactoryName( SvtModuleOptions::EFactory::WRITER );
+ else if ( aCmdLineArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
+ pRequest->aModule = aOpt.GetFactoryName( SvtModuleOptions::EFactory::CALC );
+ else if ( aCmdLineArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
+ pRequest->aModule= aOpt.GetFactoryName( SvtModuleOptions::EFactory::IMPRESS );
+ else if ( aCmdLineArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
+ pRequest->aModule= aOpt.GetFactoryName( SvtModuleOptions::EFactory::DRAW );
+ }
+
+ ImplPostProcessDocumentsEvent( pRequest );
+ }
+ else
+ {
+ // delete not used request again
+ delete pRequest;
+ pRequest = nullptr;
+ }
+ if (aCmdLineArgs->IsEmpty())
+ {
+ // no document was sent, just bring Office to front
+ ApplicationEvent* pAppEvent =
+ new ApplicationEvent(ApplicationEvent::TYPE_APPEAR);
+ ImplPostForeignAppEvent( pAppEvent );
+ }
+ }
+ *wait = bDocRequestSent;
+ return true;
+}
+
void PipeIpcThread::execute()
{
assert(handler_ != nullptr);
@@ -700,210 +1188,15 @@ void PipeIpcThread::execute()
if (aArguments.isEmpty())
continue;
- std::unique_ptr< CommandLineArgs > aCmdLineArgs;
- try
- {
- Parser p(aArguments);
- aCmdLineArgs.reset( new CommandLineArgs( p ) );
- }
- catch ( const CommandLineArgs::Supplier::Exception & )
- {
- SAL_WARN("desktop.app", "Error in received command line arguments");
+ bool wait = false;
+ if (!process(aArguments, &wait)) {
continue;
}
- bool bDocRequestSent = false;
-
- OUString aUnknown( aCmdLineArgs->GetUnknown() );
- if ( !aUnknown.isEmpty() || aCmdLineArgs->IsHelp() )
- {
- ApplicationEvent* pAppEvent =
- new ApplicationEvent(ApplicationEvent::TYPE_HELP, aUnknown);
- ImplPostForeignAppEvent( pAppEvent );
- }
- else if ( aCmdLineArgs->IsVersion() )
- {
- ApplicationEvent* pAppEvent =
- new ApplicationEvent(ApplicationEvent::TYPE_VERSION);
- ImplPostForeignAppEvent( pAppEvent );
- }
- else
- {
- const CommandLineArgs &rCurrentCmdLineArgs = Desktop::GetCommandLineArgs();
-
- if ( aCmdLineArgs->IsQuickstart() )
- {
- // we have to use application event, because we have to start quickstart service in main thread!!
- ApplicationEvent* pAppEvent =
- new ApplicationEvent(ApplicationEvent::TYPE_QUICKSTART);
- ImplPostForeignAppEvent( pAppEvent );
- }
-
- // handle request for acceptor
- std::vector< OUString > const & accept = aCmdLineArgs->
- GetAccept();
- for (std::vector< OUString >::const_iterator i(accept.begin());
- i != accept.end(); ++i)
- {
- ApplicationEvent* pAppEvent = new ApplicationEvent(
- ApplicationEvent::TYPE_ACCEPT, *i);
- ImplPostForeignAppEvent( pAppEvent );
- }
- // handle acceptor removal
- std::vector< OUString > const & unaccept = aCmdLineArgs->
- GetUnaccept();
- for (std::vector< OUString >::const_iterator i(
- unaccept.begin());
- i != unaccept.end(); ++i)
- {
- ApplicationEvent* pAppEvent = new ApplicationEvent(
- ApplicationEvent::TYPE_UNACCEPT, *i);
- ImplPostForeignAppEvent( pAppEvent );
- }
-
- ProcessDocumentsRequest* pRequest = new ProcessDocumentsRequest(
- aCmdLineArgs->getCwdUrl());
- handler_->cProcessed.reset();
- pRequest->pcProcessed = &handler_->cProcessed;
-
- // Print requests are not dependent on the --invisible cmdline argument as they are
- // loaded with the "hidden" flag! So they are always checked.
- pRequest->aPrintList = aCmdLineArgs->GetPrintList();
- bDocRequestSent |= !pRequest->aPrintList.empty();
- pRequest->aPrintToList = aCmdLineArgs->GetPrintToList();
- pRequest->aPrinterName = aCmdLineArgs->GetPrinterName();
- bDocRequestSent |= !( pRequest->aPrintToList.empty() || pRequest->aPrinterName.isEmpty() );
-
- if ( !rCurrentCmdLineArgs.IsInvisible() )
- {
- // Read cmdline args that can open/create documents. As they would open a window
- // they are only allowed if the "--invisible" is currently not used!
- pRequest->aOpenList = aCmdLineArgs->GetOpenList();
- bDocRequestSent |= !pRequest->aOpenList.empty();
- pRequest->aViewList = aCmdLineArgs->GetViewList();
- bDocRequestSent |= !pRequest->aViewList.empty();
- pRequest->aStartList = aCmdLineArgs->GetStartList();
- bDocRequestSent |= !pRequest->aStartList.empty();
- pRequest->aForceOpenList = aCmdLineArgs->GetForceOpenList();
- bDocRequestSent |= !pRequest->aForceOpenList.empty();
- pRequest->aForceNewList = aCmdLineArgs->GetForceNewList();
- bDocRequestSent |= !pRequest->aForceNewList.empty();
-
- // Special command line args to create an empty document for a given module
-
- // #i18338# (lo)
- // we only do this if no document was specified on the command line,
- // since this would be inconsistent with the behaviour of
- // the first process, see OpenClients() (call to OpenDefault()) in app.cxx
- if ( aCmdLineArgs->HasModuleParam() && !bDocRequestSent )
- {
- SvtModuleOptions aOpt;
- SvtModuleOptions::EFactory eFactory = SvtModuleOptions::EFactory::WRITER;
- if ( aCmdLineArgs->IsWriter() )
- eFactory = SvtModuleOptions::EFactory::WRITER;
- else if ( aCmdLineArgs->IsCalc() )
- eFactory = SvtModuleOptions::EFactory::CALC;
- else if ( aCmdLineArgs->IsDraw() )
- eFactory = SvtModuleOptions::EFactory::DRAW;
- else if ( aCmdLineArgs->IsImpress() )
- eFactory = SvtModuleOptions::EFactory::IMPRESS;
- else if ( aCmdLineArgs->IsBase() )
- eFactory = SvtModuleOptions::EFactory::DATABASE;
- else if ( aCmdLineArgs->IsMath() )
- eFactory = SvtModuleOptions::EFactory::MATH;
- else if ( aCmdLineArgs->IsGlobal() )
- eFactory = SvtModuleOptions::EFactory::WRITERGLOBAL;
- else if ( aCmdLineArgs->IsWeb() )
- eFactory = SvtModuleOptions::EFactory::WRITERWEB;
-
- if ( !pRequest->aOpenList.empty() )
- pRequest->aModule = aOpt.GetFactoryName( eFactory );
- else
- pRequest->aOpenList.push_back( aOpt.GetFactoryEmptyDocumentURL( eFactory ) );
- bDocRequestSent = true;
- }
- }
-
- if ( !aCmdLineArgs->IsQuickstart() ) {
- bool bShowHelp = false;
- OUStringBuffer aHelpURLBuffer;
- if (aCmdLineArgs->IsHelpWriter()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://swriter/start");
- } else if (aCmdLineArgs->IsHelpCalc()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://scalc/start");
- } else if (aCmdLineArgs->IsHelpDraw()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://sdraw/start");
- } else if (aCmdLineArgs->IsHelpImpress()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://simpress/start");
- } else if (aCmdLineArgs->IsHelpBase()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://sdatabase/start");
- } else if (aCmdLineArgs->IsHelpBasic()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://sbasic/start");
- } else if (aCmdLineArgs->IsHelpMath()) {
- bShowHelp = true;
- aHelpURLBuffer.append("vnd.sun.star.help://smath/start");
- }
- if (bShowHelp) {
- aHelpURLBuffer.append("?Language=");
- aHelpURLBuffer.append(utl::ConfigManager::getLocale());
-#if defined UNX
- aHelpURLBuffer.append("&System=UNX");
-#elif defined WNT
- aHelpURLBuffer.appendAscii("&System=WIN");
-#endif
- ApplicationEvent* pAppEvent = new ApplicationEvent(
- ApplicationEvent::TYPE_OPENHELPURL,
- aHelpURLBuffer.makeStringAndClear());
- ImplPostForeignAppEvent( pAppEvent );
- }
- }
-
- if ( bDocRequestSent )
- {
- // Send requests to dispatch watcher if we have at least one. The receiver
- // is responsible to delete the request after processing it.
- if ( aCmdLineArgs->HasModuleParam() )
- {
- SvtModuleOptions aOpt;
-
- // Support command line parameters to start a module (as preselection)
- if ( aCmdLineArgs->IsWriter() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
- pRequest->aModule = aOpt.GetFactoryName( SvtModuleOptions::EFactory::WRITER );
- else if ( aCmdLineArgs->IsCalc() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
- pRequest->aModule = aOpt.GetFactoryName( SvtModuleOptions::EFactory::CALC );
- else if ( aCmdLineArgs->IsImpress() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
- pRequest->aModule= aOpt.GetFactoryName( SvtModuleOptions::EFactory::IMPRESS );
- else if ( aCmdLineArgs->IsDraw() && aOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
- pRequest->aModule= aOpt.GetFactoryName( SvtModuleOptions::EFactory::DRAW );
- }
-
- ImplPostProcessDocumentsEvent( pRequest );
- }
- else
- {
- // delete not used request again
- delete pRequest;
- pRequest = nullptr;
- }
- if (aCmdLineArgs->IsEmpty())
- {
- // no document was sent, just bring Office to front
- ApplicationEvent* pAppEvent =
- new ApplicationEvent(ApplicationEvent::TYPE_APPEAR);
- ImplPostForeignAppEvent( pAppEvent );
- }
- }
-
// we don't need the mutex any longer...
aGuard.clear();
// wait for processing to finish
- if (bDocRequestSent)
+ if (wait)
handler_->cProcessed.wait();
// processing finished, inform the requesting end:
n = aStreamPipe.write(
diff --git a/desktop/source/app/officeipcthread.hxx b/desktop/source/app/officeipcthread.hxx
index 55e5fc383e25..1d3b2ccd9fb8 100644
--- a/desktop/source/app/officeipcthread.hxx
+++ b/desktop/source/app/officeipcthread.hxx
@@ -69,10 +69,13 @@ struct ProcessDocumentsRequest
class DispatchWatcher;
class IpcThread;
class PipeIpcThread;
+class DbusIpcThread;
class RequestHandler: public salhelper::SimpleReferenceObject
{
+ friend IpcThread;
friend PipeIpcThread;
+ friend DbusIpcThread;
private:
static rtl::Reference< RequestHandler > pGlobal;
diff --git a/desktop/unx/source/start.c b/desktop/unx/source/start.c
index a988fc852262..3b23124bf4b6 100644
--- a/desktop/unx/source/start.c
+++ b/desktop/unx/source/start.c
@@ -757,7 +757,7 @@ SAL_IMPLEMENT_MAIN_WITH_ARGS( argc, argv )
if ( pUsePlugin && !strcmp(pUsePlugin, "svp") )
args->bInhibitSplash = sal_True;
- if ( !args->bInhibitPipe )
+ if ( !args->bInhibitPipe && getenv("LIBO_XDGAPP") == NULL )
{
int fd = 0;
pPipePath = get_pipe_path( args->pAppPath );