summaryrefslogtreecommitdiffstats
path: root/src/extension/dbus/dbus-init.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/extension/dbus/dbus-init.cpp')
-rw-r--r--src/extension/dbus/dbus-init.cpp235
1 files changed, 235 insertions, 0 deletions
diff --git a/src/extension/dbus/dbus-init.cpp b/src/extension/dbus/dbus-init.cpp
new file mode 100644
index 0000000..c83caac
--- /dev/null
+++ b/src/extension/dbus/dbus-init.cpp
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * This is where Inkscape connects to the DBus when it starts and
+ * registers the main interface.
+ *
+ * Also where new interfaces are registered when a new document is created.
+ * (Not called directly by application-interface but called indirectly.)
+ *
+ * Authors:
+ * Soren Berg <Glimmer07@gmail.com>
+ *
+ * Copyright (C) 2009 Soren Berg
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#include <dbus/dbus-glib.h>
+// this is required so that giomm headers won't barf
+#undef DBUS_MESSAGE_TYPE_INVALID
+#include "dbus-init.h"
+
+#include "application-interface.h"
+#include "application-server-glue.h"
+
+#include "document-interface.h"
+#include "document-server-glue.h"
+
+#include "inkscape.h"
+#include "document.h"
+#include "desktop.h"
+#include "file.h"
+#include "verbs.h"
+#include "helper/action.h"
+
+#include <algorithm>
+#include <iostream>
+#include <sstream>
+
+
+namespace
+{
+ // This stores the bus name to use for this app instance. By default, it
+ // will be set to org.inkscape. However, users may provide other names by
+ // setting command-line parameters when starting Inkscape, so that more
+ // than one instance of Inkscape may be used by external scripts.
+ gchar *instance_bus_name = NULL;
+}
+
+namespace Inkscape {
+namespace Extension {
+namespace Dbus {
+
+/* PRIVATE get a connection to the session bus */
+DBusGConnection *
+dbus_get_connection() {
+ GError *error = NULL;
+ DBusGConnection *connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if (error) {
+ fprintf(stderr, "Failed to get connection");
+ return NULL;
+ }
+ else
+ return connection;
+}
+
+/* PRIVATE create a proxy object for a bus.*/
+DBusGProxy *
+dbus_get_proxy(DBusGConnection *connection) {
+ return dbus_g_proxy_new_for_name (connection,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+}
+
+/* PRIVATE register an object on a bus */
+static gpointer
+dbus_register_object (DBusGConnection *connection,
+ DBusGProxy *proxy,
+ GType object_type,
+ const DBusGObjectInfo *info,
+ const gchar *path)
+{
+ GObject *object = (GObject*)g_object_new (object_type, NULL);
+ dbus_g_object_type_install_info (object_type, info);
+ dbus_g_connection_register_g_object (connection, path, object);
+ return object;
+}
+
+/*
+ * PRIVATE register a document interface for the document in the given ActionContext, if none exists.
+ * Return the DBus path to the interface (something like /org/inkscape/document_0).
+ * Note that while a DocumentInterface could be used either for a document with no desktop, or a
+ * document with a desktop, this function is only used for creating interfaces in the former case.
+ * Desktop-associated DocumentInterfaces are named /org/inkscape/desktop_0, etc.
+ * FIXME: This state of affairs probably needs tidying up at some point in the future.
+ */
+static gchar *
+dbus_register_document(Inkscape::ActionContext const & target)
+{
+ SPDocument *doc = target.getDocument();
+ g_assert(doc != NULL);
+
+ // Document name is not suitable for DBus name, as it might contain invalid chars
+ std::string name("/org/inkscape/document_");
+ std::stringstream ss;
+ ss << doc->serial();
+ name.append(ss.str());
+
+ DBusGConnection *connection = dbus_get_connection();
+ DBusGProxy *proxy = dbus_get_proxy(connection);
+
+ // Has the document already been registered?
+ if (!dbus_g_connection_lookup_g_object(connection, name.c_str())) {
+ // No - register it
+ DocumentInterface *doc_interface = (DocumentInterface*) dbus_register_object (connection,
+ proxy,
+ TYPE_DOCUMENT_INTERFACE,
+ &dbus_glib_document_interface_object_info,
+ name.c_str());
+
+ // Set the document info for this interface
+ doc_interface->target = target;
+ }
+ return strdup(name.c_str());
+}
+
+/* Initialize a Dbus service */
+void
+init (void)
+{
+ if (instance_bus_name == NULL) {
+ // Set the bus name to the default
+ instance_bus_name = strdup("org.inkscape");
+ }
+
+ guint result;
+ GError *error = NULL;
+ DBusGConnection *connection;
+ DBusGProxy *proxy;
+ connection = dbus_get_connection();
+ proxy = dbus_get_proxy(connection);
+ org_freedesktop_DBus_request_name (proxy,
+ instance_bus_name,
+ DBUS_NAME_FLAG_DO_NOT_QUEUE, &result, &error);
+ //create interface for application
+ dbus_register_object (connection,
+ proxy,
+ TYPE_APPLICATION_INTERFACE,
+ &dbus_glib_application_interface_object_info,
+ DBUS_APPLICATION_INTERFACE_PATH);
+}
+
+gchar *
+init_document (void)
+{
+ // This is for command-line use only
+ g_assert(!INKSCAPE.use_gui());
+
+ // Create a blank document and get its selection model etc in an ActionContext
+ SPDocument *doc = SPDocument::createNewDoc(NULL, 1, TRUE);
+ INKSCAPE.add_document(doc);
+ return dbus_register_document(INKSCAPE.action_context_for_document(doc));
+}
+
+gchar *
+init_active_document()
+{
+ SPDocument *doc = INKSCAPE.active_document();
+ if (!doc) {
+ return NULL;
+ }
+
+ return dbus_register_document(INKSCAPE.active_action_context());
+}
+
+gchar *
+dbus_init_desktop_interface (SPDesktop * dt)
+{
+ DBusGConnection *connection;
+ DBusGProxy *proxy;
+
+ std::string name("/org/inkscape/desktop_");
+ std::stringstream out;
+ out << dt->dkey;
+ name.append(out.str());
+
+ //printf("DKEY: %d\n, NUMBER %d\n NAME: %s\n", dt->dkey, dt->number, name.c_str());
+
+ connection = dbus_get_connection();
+ proxy = dbus_get_proxy(connection);
+
+ if (!dbus_g_connection_lookup_g_object(connection, name.c_str())) {
+ DocumentInterface *doc_interface = (DocumentInterface*) dbus_register_object (connection,
+ proxy,
+ TYPE_DOCUMENT_INTERFACE,
+ &dbus_glib_document_interface_object_info,
+ name.c_str());
+
+ // Set the document info for this interface
+ doc_interface->target = Inkscape::ActionContext(dt);
+ doc_interface->updates = TRUE;
+ dt->dbus_document_interface=doc_interface;
+ }
+ return strdup(name.c_str());
+}
+
+gchar *
+init_desktop (void) {
+ //this function will create a new desktop and call
+ //dbus_init_desktop_interface.
+ SPDesktop * dt = sp_file_new_default();
+
+ std::string name("/org/inkscape/desktop_");
+ std::stringstream out;
+ out << dt->dkey;
+ name.append(out.str());
+ return strdup(name.c_str());
+}
+
+void
+dbus_set_bus_name(gchar const * bus_name)
+{
+ g_assert(bus_name != NULL);
+ g_assert(instance_bus_name == NULL);
+ instance_bus_name = strdup(bus_name);
+}
+
+gchar *
+dbus_get_bus_name()
+{
+ g_assert(instance_bus_name != NULL);
+ return instance_bus_name;
+}
+
+} } } /* namespace Inkscape::Extension::Dbus */