From f654a43b5d33a50ac63c15178c75c2a9d80b6012 Mon Sep 17 00:00:00 2001 From: Ali Abdallah <aliov@xfce.org> Date: Fri, 22 Jan 2010 16:14:41 +0100 Subject: [PATCH] Added GObject for handling unique instances of xfpm via D-Bus. --- libdbus/Makefile.am | 11 +- libdbus/org.xfce.unique.xml | 10 ++ libdbus/xfpm-dbus.c | 45 ------- libdbus/xfpm-dbus.h | 8 -- libdbus/xfpm-unique.c | 243 ++++++++++++++++++++++++++++++++++++ libdbus/xfpm-unique.h | 57 +++++++++ 6 files changed, 319 insertions(+), 55 deletions(-) create mode 100644 libdbus/org.xfce.unique.xml create mode 100644 libdbus/xfpm-unique.c create mode 100644 libdbus/xfpm-unique.h diff --git a/libdbus/Makefile.am b/libdbus/Makefile.am index 3ab62d2c..6a47cbb9 100644 --- a/libdbus/Makefile.am +++ b/libdbus/Makefile.am @@ -6,8 +6,11 @@ libxfpmdbus_la_SOURCES = \ xfpm-dbus.h \ xfpm-dbus-monitor.c \ xfpm-dbus-monitor.h \ + xfpm-unique.c \ + xfpm-unique.h \ xfpm-dbus-marshal.c \ - xfpm-dbus-marshal.h + xfpm-dbus-marshal.h \ + org.xfce.unique.h libxfpmdbus_la_CFLAGS = \ $(GLIB_CFLAGS) \ @@ -18,7 +21,8 @@ if MAINTAINER_MODE BUILT_SOURCES = \ xfpm-dbus-marshal.c \ - xfpm-dbus-marshal.h + xfpm-dbus-marshal.h \ + org.xfce.unique.h xfpm-dbus-marshal.c: xfpm-dbus-marshal.list echo "#include \"xfpm-dbus-marshal.h\"" > $@ && \ @@ -27,6 +31,9 @@ xfpm-dbus-marshal.c: xfpm-dbus-marshal.list xfpm-dbus-marshal.h: xfpm-dbus-marshal.list glib-genmarshal $< --prefix=_xfpm_dbus_marshal --header > $@ +org.xfce.unique.h: org.xfce.unique.xml + dbus-binding-tool --mode=glib-server --prefix=xfce_unique $< >$@ + endif EXTRA_DIST = \ diff --git a/libdbus/org.xfce.unique.xml b/libdbus/org.xfce.unique.xml new file mode 100644 index 00000000..323e4052 --- /dev/null +++ b/libdbus/org.xfce.unique.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<node name="/"> + <interface name="org.xfce.unique"> + + <method name="Ping"> + </method> + + </interface> +</node> diff --git a/libdbus/xfpm-dbus.c b/libdbus/xfpm-dbus.c index ccbe5dcc..1f0e6235 100644 --- a/libdbus/xfpm-dbus.c +++ b/libdbus/xfpm-dbus.c @@ -91,48 +91,3 @@ gboolean xfpm_dbus_release_name(DBusConnection *connection, const gchar *name) return TRUE; } - - -GHashTable *xfpm_dbus_get_interface_properties (DBusGProxy *proxy_prop, const gchar *iface_name) -{ - gboolean ret; - GError *error = NULL; - GHashTable *props = NULL; - - props = NULL; - - ret = dbus_g_proxy_call (proxy_prop, "GetAll", &error, - G_TYPE_STRING, iface_name, - G_TYPE_INVALID, - dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &props, - G_TYPE_INVALID); - - if (!ret) - { - g_warning ("Unable to get interface properties for : %s : %s", iface_name, error->message); - g_error_free (error); - } - - return props; -} - -GValue xfpm_dbus_get_interface_property (DBusGProxy *proxy, const gchar *iface_name, const gchar *prop_name) -{ - gboolean ret; - GError *error = NULL; - GValue value = { 0, }; - - ret = dbus_g_proxy_call (proxy, "Get", &error, - G_TYPE_STRING, iface_name, - G_TYPE_STRING, prop_name, - G_TYPE_INVALID, - G_TYPE_VALUE, &value, G_TYPE_INVALID); - - if (!ret) - { - g_warning ("Unable to get property %s on interface %s : %s", prop_name, iface_name, error->message); - g_error_free (error); - } - - return value; -} diff --git a/libdbus/xfpm-dbus.h b/libdbus/xfpm-dbus.h index 0f005f7f..dff2ef11 100644 --- a/libdbus/xfpm-dbus.h +++ b/libdbus/xfpm-dbus.h @@ -33,12 +33,4 @@ gboolean xfpm_dbus_register_name (DBusConnection *bus, gboolean xfpm_dbus_release_name (DBusConnection *bus, const gchar *name); - -GHashTable *xfpm_dbus_get_interface_properties (DBusGProxy *proxy_prop, - const gchar *iface_name); - -GValue xfpm_dbus_get_interface_property (DBusGProxy *proxy, - const gchar *iface_name, - const gchar *prop_name); - #endif /* __XFPM_DBUS_H */ diff --git a/libdbus/xfpm-unique.c b/libdbus/xfpm-unique.c new file mode 100644 index 00000000..9addfb70 --- /dev/null +++ b/libdbus/xfpm-unique.c @@ -0,0 +1,243 @@ +/* + * * Copyright (C) 2010 Ali <aliov@xfce.org> + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xfpm-unique.h" +#include "xfpm-dbus.h" + +#include <dbus/dbus-glib-lowlevel.h> + +static void xfpm_unique_dbus_class_init (XfpmUniqueClass *klass); +static void xfpm_unique_dbus_init (XfpmUnique *unique); + +static void xfpm_unique_finalize (GObject *object); + +#define XFPM_UNIQUE_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), XFPM_TYPE_UNIQUE, XfpmUniquePrivate)) + +struct XfpmUniquePrivate +{ + DBusGConnection *bus; + + gchar *name; +}; + +enum +{ + PROP_0, + PROP_NAME +}; + +enum +{ + PING_RECEIVED, + LAST_SIGNAL +}; + +static guint signals [LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (XfpmUnique, xfpm_unique, G_TYPE_OBJECT) + +static void xfpm_unique_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + XfpmUnique *unique; + unique = XFPM_UNIQUE (object); + + switch (prop_id) + { + case PROP_NAME: + g_value_set_string (value, unique->priv->name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } + +} + +static void xfpm_unique_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + + XfpmUnique *unique; + unique = XFPM_UNIQUE (object); + + switch (prop_id) + { + case PROP_NAME: + unique->priv->name = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +xfpm_unique_class_init (XfpmUniqueClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = xfpm_unique_finalize; + + object_class->set_property = xfpm_unique_set_property; + object_class->get_property = xfpm_unique_get_property; + + signals [PING_RECEIVED] = + g_signal_new ("ping-received", + XFPM_TYPE_UNIQUE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (XfpmUniqueClass, ping_received), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0, G_TYPE_NONE); + + g_object_class_install_property (object_class, + PROP_NAME, + g_param_spec_string ("name", + NULL, NULL, + NULL, + G_PARAM_READWRITE| + G_PARAM_CONSTRUCT_ONLY)); + + g_type_class_add_private (klass, sizeof (XfpmUniquePrivate)); + + xfpm_unique_dbus_class_init (klass); +} + +static void +xfpm_unique_init (XfpmUnique *unique) +{ + GError *error = NULL; + + unique->priv = XFPM_UNIQUE_GET_PRIVATE (unique); + + unique->priv->name = NULL; + + unique->priv->bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + + if ( error ) + g_error ("Failed to connect to the session bus : %s", error->message); + + xfpm_unique_dbus_init (unique); +} + +static void +xfpm_unique_finalize (GObject *object) +{ + XfpmUnique *unique; + + unique = XFPM_UNIQUE (object); + + xfpm_dbus_release_name (dbus_g_connection_get_connection (unique->priv->bus), + unique->priv->name); + + dbus_g_connection_unref (unique->priv->bus); + g_free (unique->priv->name); + + G_OBJECT_CLASS (xfpm_unique_parent_class)->finalize (object); +} + +XfpmUnique * +xfpm_unique_new (const gchar *name) +{ + XfpmUnique *unique = NULL; + + unique = g_object_new (XFPM_TYPE_UNIQUE, "name", name, NULL); + + return unique; +} + +gboolean xfpm_unique_app_is_running (XfpmUnique *unique) +{ + g_return_val_if_fail (XFPM_IS_UNIQUE (unique), FALSE); + + if (xfpm_dbus_name_has_owner (dbus_g_connection_get_connection (unique->priv->bus), + unique->priv->name)) + { + DBusGProxy *proxy; + GError *error = NULL; + + proxy = dbus_g_proxy_new_for_name (unique->priv->bus, + unique->priv->name, + "/org/xfce/unique", + "org.xfce.unique"); + + /*Shoudln't happen, but check anyway*/ + if ( !proxy ) + { + g_critical ("Unable to create proxy for %s", unique->priv->name); + return FALSE; + } + + dbus_g_proxy_call (proxy, "Ping", &error, + G_TYPE_INVALID, + G_TYPE_INVALID); + + if ( error ) + { + g_warning ("Failed to 'Ping' %s", unique->priv->name); + + } + + g_object_unref (proxy); + return TRUE; + } + + xfpm_dbus_register_name (dbus_g_connection_get_connection (unique->priv->bus), + unique->priv->name); + + return FALSE; +} + +static gboolean xfce_unique_ping (XfpmUnique *unique, + GError *error); + +#include "org.xfce.unique.h" + +static void xfpm_unique_dbus_class_init (XfpmUniqueClass *klass) +{ + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), + &dbus_glib_xfce_unique_object_info); +} + +static void xfpm_unique_dbus_init (XfpmUnique *unique) +{ + dbus_g_connection_register_g_object (unique->priv->bus, + "/org/xfce/unique", + G_OBJECT (unique)); +} + +static gboolean xfce_unique_ping (XfpmUnique *unique, + GError *error) +{ + g_signal_emit (unique, signals[PING_RECEIVED], 0); + return TRUE; +} diff --git a/libdbus/xfpm-unique.h b/libdbus/xfpm-unique.h new file mode 100644 index 00000000..147b4149 --- /dev/null +++ b/libdbus/xfpm-unique.h @@ -0,0 +1,57 @@ +/* + * * Copyright (C) 2010 Ali <aliov@xfce.org> + * + * Licensed under the GNU General Public License Version 2 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __XFPM_UNIQUE_H +#define __XFPM_UNIQUE_H + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define XFPM_TYPE_UNIQUE (xfpm_unique_get_type () ) +#define XFPM_UNIQUE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), XFPM_TYPE_UNIQUE, XfpmUnique)) +#define XFPM_IS_UNIQUE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), XFPM_TYPE_UNIQUE)) + +typedef struct XfpmUniquePrivate XfpmUniquePrivate; + +typedef struct +{ + GObject parent; + XfpmUniquePrivate *priv; + +} XfpmUnique; + +typedef struct +{ + GObjectClass parent_class; + + void (*ping_received) (XfpmUnique *unique); + +} XfpmUniqueClass; + +GType xfpm_unique_get_type (void) G_GNUC_CONST; + +XfpmUnique *xfpm_unique_new (const gchar *name); + +gboolean xfpm_unique_app_is_running (XfpmUnique *unique); + +G_END_DECLS + +#endif /* __XFPM_UNIQUE_H */ -- GitLab