aboutsummaryrefslogtreecommitdiff
path: root/src/session-dbus.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/session-dbus.c')
-rw-r--r--src/session-dbus.c166
1 files changed, 142 insertions, 24 deletions
diff --git a/src/session-dbus.c b/src/session-dbus.c
index 20a0fa0..3c60a4e 100644
--- a/src/session-dbus.c
+++ b/src/session-dbus.c
@@ -23,26 +23,34 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include "config.h"
#endif
+#include <gio/gio.h>
+
#include "session-dbus.h"
#include "dbus-shared-names.h"
-static gboolean _session_dbus_server_get_icon (SessionDbus * service, gchar ** icon, GError ** error);
+static GVariant * get_icon (SessionDbus * service);
+static void bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data);
+static void bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data);
-#include "session-dbus-server.h"
+#include "gen-session-dbus.xml.h"
typedef struct _SessionDbusPrivate SessionDbusPrivate;
struct _SessionDbusPrivate {
gchar * name;
+ GDBusConnection * bus;
+ GCancellable * bus_cancel;
+ guint dbus_registration;
};
-/* Signals */
-enum {
- ICON_UPDATED,
- LAST_SIGNAL
+/* GDBus Stuff */
+static GDBusNodeInfo * node_info = NULL;
+static GDBusInterfaceInfo * interface_info = NULL;
+static GDBusInterfaceVTable interface_table = {
+ method_call: bus_method_call,
+ get_property: NULL, /* No properties */
+ set_property: NULL /* No properties */
};
-static guint signals[LAST_SIGNAL] = { 0 };
-
#define SESSION_DBUS_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), SESSION_DBUS_TYPE, SessionDbusPrivate))
@@ -63,15 +71,24 @@ session_dbus_class_init (SessionDbusClass *klass)
object_class->dispose = session_dbus_dispose;
object_class->finalize = session_dbus_finalize;
- signals[ICON_UPDATED] = g_signal_new ("icon-updated",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (SessionDbusClass, icon_updated),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1, G_TYPE_STRING);
+ /* Setting up the DBus interfaces */
+ if (node_info == NULL) {
+ GError * error = NULL;
+
+ node_info = g_dbus_node_info_new_for_xml(_session_dbus, &error);
+ if (error != NULL) {
+ g_error("Unable to parse Session Service Interface description: %s", error->message);
+ g_error_free(error);
+ }
+ }
+
+ if (interface_info == NULL) {
+ interface_info = g_dbus_node_info_lookup_interface(node_info, INDICATOR_SESSION_SERVICE_DBUS_IFACE);
- dbus_g_object_type_install_info(SESSION_DBUS_TYPE, &dbus_glib__session_dbus_server_object_info);
+ if (interface_info == NULL) {
+ g_error("Unable to find interface '" INDICATOR_SESSION_SERVICE_DBUS_IFACE "'");
+ }
+ }
return;
}
@@ -79,19 +96,104 @@ session_dbus_class_init (SessionDbusClass *klass)
static void
session_dbus_init (SessionDbus *self)
{
- DBusGConnection * session = dbus_g_bus_get(DBUS_BUS_SESSION, NULL);
- dbus_g_connection_register_g_object(session, INDICATOR_SESSION_SERVICE_DBUS_OBJECT, G_OBJECT(self));
-
SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(self);
priv->name = g_strdup(ICON_DEFAULT);
+ priv->bus = NULL;
+ priv->bus_cancel = NULL;
+ priv->dbus_registration = 0;
+
+ priv->bus_cancel = g_cancellable_new();
+ g_bus_get(G_BUS_TYPE_SESSION,
+ priv->bus_cancel,
+ bus_get_cb,
+ self);
return;
}
static void
+bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data)
+{
+ GError * error = NULL;
+ GDBusConnection * connection = g_bus_get_finish(res, &error);
+
+ if (error != NULL) {
+ g_error("OMG! Unable to get a connection to DBus: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(user_data);
+
+ g_warn_if_fail(priv->bus == NULL);
+ priv->bus = connection;
+
+ if (priv->bus_cancel != NULL) {
+ g_object_unref(priv->bus_cancel);
+ priv->bus_cancel = NULL;
+ }
+
+ /* Now register our object on our new connection */
+ priv->dbus_registration = g_dbus_connection_register_object(priv->bus,
+ INDICATOR_SESSION_SERVICE_DBUS_OBJECT,
+ interface_info,
+ &interface_table,
+ user_data,
+ NULL,
+ &error);
+
+ if (error != NULL) {
+ g_error("Unable to register the object to DBus: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+
+ return;
+}
+
+/* A method has been called from our dbus inteface. Figure out what it
+ is and dispatch it. */
+static void
+bus_method_call (GDBusConnection * connection, const gchar * sender,
+ const gchar * path, const gchar * interface,
+ const gchar * method, GVariant * params,
+ GDBusMethodInvocation * invocation, gpointer user_data)
+{
+ SessionDbus * service = SESSION_DBUS(user_data);
+ GVariant * retval = NULL;
+
+ if (g_strcmp0(method, "GetIcon") == 0) {
+ retval = get_icon(service);
+ } else {
+ g_warning("Calling method '%s' on the indicator service and it's unknown", method);
+ }
+
+ g_dbus_method_invocation_return_value(invocation, retval);
+ return;
+}
+
+static void
session_dbus_dispose (GObject *object)
{
+ SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(object);
+
+ if (priv->dbus_registration != 0) {
+ g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration);
+ /* Don't care if it fails, there's nothing we can do */
+ priv->dbus_registration = 0;
+ }
+
+ if (priv->bus != NULL) {
+ g_object_unref(priv->bus);
+ priv->bus = NULL;
+ }
+
+ if (priv->bus_cancel != NULL) {
+ g_cancellable_cancel(priv->bus_cancel);
+ g_object_unref(priv->bus_cancel);
+ priv->bus_cancel = NULL;
+ }
G_OBJECT_CLASS (session_dbus_parent_class)->dispose (object);
return;
@@ -111,12 +213,11 @@ session_dbus_finalize (GObject *object)
return;
}
-static gboolean
-_session_dbus_server_get_icon (SessionDbus * service, gchar ** icon, GError ** error)
+static GVariant *
+get_icon (SessionDbus * service)
{
SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(service);
- *icon = g_strdup(priv->name);
- return TRUE;
+ return g_variant_new("(s)", priv->name);
}
SessionDbus *
@@ -129,11 +230,28 @@ void
session_dbus_set_name (SessionDbus * session, const gchar * name)
{
SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(session);
+ GError * error = NULL;
if (priv->name != NULL) {
g_free(priv->name);
priv->name = NULL;
}
priv->name = g_strdup(name);
- g_signal_emit(G_OBJECT(session), signals[ICON_UPDATED], 0, priv->name, TRUE);
+
+ if (priv->bus != NULL) {
+ g_dbus_connection_emit_signal (priv->bus,
+ NULL,
+ INDICATOR_SESSION_SERVICE_DBUS_OBJECT,
+ INDICATOR_SESSION_SERVICE_DBUS_IFACE,
+ "IconUpdated",
+ g_variant_new ("(s)", priv->name, NULL),
+ &error);
+
+ if (error != NULL) {
+ g_error("Unable to send IconUpdated signal: %s", error->message);
+ g_error_free(error);
+ return;
+ }
+ }
+
return;
}