[gnome-shell] Port to new GDBus bindings in gjs



commit 5350302b09ddbbfa98091a943ae878c9aaf9eb6e
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Tue Aug 16 14:19:59 2011 +0200

    Port to new GDBus bindings in gjs
    
    Rewrite code acquiring dbus names so that it uses GDBus, and rewrite
    ShellDBus so that it is exposed on the GDBus connection. Ports of
    the other objects will follow.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=648651

 configure.ac       |    8 +--
 js/ui/main.js      |    6 --
 js/ui/shellDBus.js |  151 +++++++++++++++++++++++++++++-----------------------
 src/main.c         |   71 ++++++++++++++----------
 4 files changed, 129 insertions(+), 107 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index a0fc338..1304baa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,8 +70,7 @@ GJS_MIN_VERSION=1.29.18
 MUTTER_MIN_VERSION=3.2.1
 FOLKS_MIN_VERSION=0.5.2
 GTK_MIN_VERSION=3.0.0
-GLIB_MIN_VERSION=2.31.0
-GIO_MIN_VERSION=2.29.10
+GIO_MIN_VERSION=2.31.0
 LIBECAL_MIN_VERSION=2.32.0
 LIBEDATASERVER_MIN_VERSION=1.2.0
 LIBEDATASERVERUI_MIN_VERSION=2.91.6
@@ -81,9 +80,8 @@ POLKIT_MIN_VERSION=0.100
 STARTUP_NOTIFICATION_MIN_VERSION=0.11
 
 # Collect more than 20 libraries for a prize!
-PKG_CHECK_MODULES(GNOME_SHELL, glib-2.0 >= $GLIB_MIN_VERSION
-                               gio-2.0 >= $GIO_MIN_VERSION
-                               gio-unix-2.0 dbus-glib-1 libxml-2.0
+PKG_CHECK_MODULES(GNOME_SHELL, gio-unix-2.0 >= $GIO_MIN_VERSION
+			       libxml-2.0
                                gtk+-3.0 >= $GTK_MIN_VERSION
                                folks >= $FOLKS_MIN_VERSION
                                libmutter >= $MUTTER_MIN_VERSION
diff --git a/js/ui/main.js b/js/ui/main.js
index e08de3d..6bd5f59 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -1,7 +1,6 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 
 const Clutter = imports.gi.Clutter;
-const DBus = imports.dbus;
 const Gdk = imports.gi.Gdk;
 const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
@@ -163,11 +162,6 @@ function start() {
     Gio.DesktopAppInfo.set_desktop_env('GNOME');
 
     shellDBusService = new ShellDBus.GnomeShell();
-    // Force a connection now; dbus.js will do this internally
-    // if we use its name acquisition stuff but we aren't right
-    // now; to do so we'd need to convert from its async calls
-    // back into sync ones.
-    DBus.session.flush();
 
     // Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
     // also initialize ShellAppSystem first.  ShellAppSystem
diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js
index 4f81c53..5a00a34 100644
--- a/js/ui/shellDBus.js
+++ b/js/ui/shellDBus.js
@@ -1,71 +1,70 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 
-const DBus = imports.dbus;
 const Lang = imports.lang;
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
 
 const Config = imports.misc.config;
 const ExtensionSystem = imports.ui.extensionSystem;
 const Main = imports.ui.main;
 
-const GnomeShellIface = {
-    name: 'org.gnome.Shell',
-    methods: [{ name: 'Eval',
-                inSignature: 's',
-                outSignature: 'bs'
-              },
-              { name: 'ListExtensions',
-                inSignature: '',
-                outSignature: 'a{sa{sv}}'
-              },
-              { name: 'GetExtensionInfo',
-                inSignature: 's',
-                outSignature: 'a{sv}'
-              },
-              { name: 'GetExtensionErrors',
-                inSignature: 's',
-                outSignature: 'as'
-              },
-              { name: 'ScreenshotArea',
-                inSignature: 'iiiis',
-                outSignature: 'b'
-              },
-              { name: 'ScreenshotWindow',
-                inSignature: 'bs',
-                outSignature: 'b'
-              },
-              { name: 'Screenshot',
-                inSignature: 's',
-                outSignature: 'b'
-              },
-              { name: 'EnableExtension',
-                inSignature: 's',
-                outSignature: ''
-              },
-              { name: 'DisableExtension',
-                inSignature: 's',
-                outSignature: ''
-              },
-              { name: 'InstallRemoteExtension',
-                inSignature: 'ss',
-                outSignature: ''
-              },
-              { name: 'UninstallExtension',
-                inSignature: 's',
-                outSignature: 'b'
-              }
-             ],
-    signals: [{ name: 'ExtensionStatusChanged',
-                inSignature: 'sis' }],
-    properties: [{ name: 'OverviewActive',
-                   signature: 'b',
-                   access: 'readwrite' },
-                 { name: 'ApiVersion',
-                   signature: 'i',
-                   access: 'read' },
-                 { name: 'ShellVersion',
-                   signature: 's',
-                   access: 'read' }]
-};
+const GnomeShellIface = <interface name="org.gnome.Shell">
+<method name="Eval">
+    <arg type="s" direction="in" name="script" />
+    <arg type="b" direction="out" name="success" />
+    <arg type="s" direction="out" name="result" />
+</method>
+<method name="ListExtensions">
+    <arg type="a{sa{sv}}" direction="out" name="extensions" />
+</method>
+<method name="GetExtensionInfo">
+    <arg type="s" direction="in" name="extension" />
+    <arg type="a{sv}" direction="out" name="info" />
+</method>
+<method name="GetExtensionErrors">
+    <arg type="s" direction="in" name="extension" />
+    <arg type="as" direction="out" name="errors" />
+</method>
+<method name="ScreenshotArea">
+    <arg type="i" direction="in" name="x"/>
+    <arg type="i" direction="in" name="y"/>
+    <arg type="i" direction="in" name="width"/>
+    <arg type="i" direction="in" name="height"/>
+    <arg type="s" direction="in" name="filename"/>
+    <arg type="b" direction="out" name="success"/>
+</method>
+<method name="ScreenshotWindow">
+    <arg type="b" direction="in" name="include_frame"/>
+    <arg type="s" direction="in" name="filename"/>
+    <arg type="b" direction="out" name="success"/>
+</method>
+<method name="Screenshot">
+    <arg type="s" direction="in" name="filename"/>
+    <arg type="b" direction="out" name="success"/>
+</method>
+<method name="EnableExtension">
+    <arg type="s" direction="in" name="uuid"/>
+</method>
+<method name="DisableExtension">
+    <arg type="s" direction="in" name="uuid"/>
+</method>
+<method name="InstallRemoteExtension">
+    <arg type="s" direction="in" name="uuid"/>
+    <arg type="s" direction="in" name="version"/>
+</method>
+<method name="UninstallExtension">
+    <arg type="s" direction="in" name="uuid"/>
+    <arg type="b" direction="out" name="success"/>
+</method>
+<property name="OverviewActive" type="b" access="readwrite" />
+<property name="ApiVersion" type="i" access="read" />
+<property name="ShellVersion" type="s" access="read" />
+<signal name="ExtensionStatusChanged">
+    <arg type="s" name="uuid"/>
+    <arg type="i" name="state"/>
+    <arg type="s" name="error"/>
+</signal>
+</interface>;
 
 function GnomeShell() {
     this._init();
@@ -73,7 +72,8 @@ function GnomeShell() {
 
 GnomeShell.prototype = {
     _init: function() {
-        DBus.session.exportObject('/org/gnome/Shell', this);
+        this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(GnomeShellIface, this);
+        this._dbusImpl.export(Gio.DBus.session, '/org/gnome/Shell');
         ExtensionSystem.connect('extension-state-changed',
                                 Lang.bind(this, this._extensionStateChanged));
     },
@@ -156,11 +156,33 @@ GnomeShell.prototype = {
     },
 
     ListExtensions: function() {
-        return ExtensionSystem.extensionMeta;
+        let out;
+        for (let uuid in ExtensionSystem.extensionMeta) {
+            let dbusObj = this.GetExtensionInfo(uuid);
+            out[uuid] = dbusObj;
+        }
+        return out;
     },
 
     GetExtensionInfo: function(uuid) {
-        return ExtensionSystem.extensionMeta[uuid] || {};
+        let meta = ExtensionSystem.extensionMeta[uuid] || {};
+        let out;
+        for (let key in meta) {
+            let val = meta[key];
+            let type;
+            switch (typeof val) {
+            case 'object':
+                throw Error('Extension had a nested object in the metadata. This is not supported');
+            case 'string':
+                type = 's';
+                break;
+            case 'number':
+                type = 'd';
+                break;
+            }
+            out[key] = GLib.Variant.new(type, val);
+        }
+        return out;
     },
 
     GetExtensionErrors: function(uuid) {
@@ -211,6 +233,3 @@ GnomeShell.prototype = {
                                  [newState.uuid, newState.state, newState.error]);
     }
 };
-
-DBus.conformExport(GnomeShell.prototype, GnomeShellIface);
-
diff --git a/src/main.c b/src/main.c
index d8cdff5..6cc66f8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -11,7 +11,6 @@
 #include <cogl-pango/cogl-pango.h>
 #include <clutter/clutter.h>
 #include <clutter/x11/clutter-x11.h>
-#include <dbus/dbus-glib.h>
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 #include <gtk/gtk.h>
@@ -36,35 +35,41 @@ extern GType gnome_shell_plugin_get_type (void);
 
 static gboolean is_gdm_mode = FALSE;
 
+#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
+#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4
+
 static void
-shell_dbus_acquire_name (DBusGProxy *bus,
+shell_dbus_acquire_name (GDBusProxy *bus,
                          guint32     request_name_flags,
                          guint32    *request_name_result,
                          gchar      *name,
                          gboolean    fatal)
 {
   GError *error = NULL;
-  if (!dbus_g_proxy_call (bus, "RequestName", &error,
-                          G_TYPE_STRING, name,
-                          G_TYPE_UINT, request_name_flags,
-                          G_TYPE_INVALID,
-                          G_TYPE_UINT, request_name_result,
-                          G_TYPE_INVALID))
+  GVariant *request_name_variant;
+
+  if (!(request_name_variant = g_dbus_proxy_call_sync (bus,
+                                                       "RequestName",
+                                                       g_variant_new ("(su)", name, request_name_flags),
+                                                       0, /* call flags */
+                                                       -1, /* timeout */
+                                                       NULL, /* cancellable */
+                                                       &error)))
     {
-      g_printerr ("failed to acquire %s: %s\n", name, error->message);
-      if (fatal)
-        exit (1);
+      g_printerr ("failed to acquire org.gnome.Shell: %s\n", error->message);
+      exit (1);
     }
+  g_variant_get (request_name_variant, "(u)", request_name_result);
 }
 
 static void
-shell_dbus_acquire_names (DBusGProxy *bus,
+shell_dbus_acquire_names (GDBusProxy *bus,
                           guint32     request_name_flags,
                           gchar      *name,
                           gboolean    fatal, ...) G_GNUC_NULL_TERMINATED;
 
 static void
-shell_dbus_acquire_names (DBusGProxy *bus,
+shell_dbus_acquire_names (GDBusProxy *bus,
                           guint32     request_name_flags,
                           gchar      *name,
                           gboolean    fatal, ...)
@@ -89,27 +94,32 @@ shell_dbus_acquire_names (DBusGProxy *bus,
 static void
 shell_dbus_init (gboolean replace)
 {
-  DBusGConnection *session;
-  DBusGProxy *bus;
+  GDBusConnection *session;
+  GDBusProxy *bus;
+  GError *error = NULL;
   guint32 request_name_flags;
   guint32 request_name_result;
 
-  /* TODO:
-   * In the future we should use GDBus for this.  However, in
-   * order to do that, we need to port all of the JavaScript
-   * code.  Otherwise, the name will be claimed on the wrong
-   * connection.
-   */
-  session = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
+  session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
 
-  bus = dbus_g_proxy_new_for_name (session,
-                                   DBUS_SERVICE_DBUS,
-                                   DBUS_PATH_DBUS,
-                                   DBUS_INTERFACE_DBUS);
+  if (error) {
+    g_printerr ("Failed to connect to session bus: %s", error->message);
+    exit (1);
+  }
+
+  bus = g_dbus_proxy_new_sync (session,
+                               G_DBUS_PROXY_FLAGS_NONE,
+                               NULL, /* interface info */
+                               "org.freedesktop.DBus",
+                               "/org/freedesktop/DBus",
+                               "org.freedesktop.DBus",
+                               NULL, /* cancellable */
+                               &error);
 
-  request_name_flags = DBUS_NAME_FLAG_DO_NOT_QUEUE | DBUS_NAME_FLAG_ALLOW_REPLACEMENT;
+  request_name_flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
   if (replace)
     request_name_flags |= DBUS_NAME_FLAG_REPLACE_EXISTING;
+
   shell_dbus_acquire_name (bus,
                            request_name_flags,
                            &request_name_result,
@@ -117,8 +127,7 @@ shell_dbus_init (gboolean replace)
   if (!(request_name_result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
         || request_name_result == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER))
     {
-      g_printerr ("%s already exists on bus and --replace not specified\n",
-                  SHELL_DBUS_SERVICE);
+      g_printerr (SHELL_DBUS_SERVICE " already exists on bus and --replace not specified\n");
       exit (1);
     }
 
@@ -126,7 +135,8 @@ shell_dbus_init (gboolean replace)
    * We always specify REPLACE_EXISTING to ensure we kill off
    * the existing service if it was running.
    */
-  request_name_flags |= DBUS_NAME_FLAG_REPLACE_EXISTING;
+  request_name_flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;
+
   shell_dbus_acquire_names (bus,
                             request_name_flags,
   /* Also grab org.gnome.Panel to replace any existing panel process */
@@ -142,6 +152,7 @@ shell_dbus_init (gboolean replace)
                            &request_name_result,
                            "org.gnome.Caribou.Keyboard", FALSE);
   g_object_unref (bus);
+  g_object_unref (session);
 }
 
 static void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]