Mercurial > projects > xwrited
diff xwrited-unique.c @ 0:52694b49dcc4
Initial revision
author | Guido Berhoerster <guido+xwrited@berhoerster.name> |
---|---|
date | Sun, 27 Apr 2014 23:07:51 +0200 |
parents | |
children | c53bcdabbba7 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xwrited-unique.c Sun Apr 27 23:07:51 2014 +0200 @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2011 Guido Berhoerster <guido+xwrited@berhoerster.name> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#define _XOPEN_SOURCE 600 + +#include <glib.h> +#include <dbus/dbus-glib.h> +#include <dbus/dbus.h> + +#include "xwrited-unique.h" + +G_DEFINE_TYPE(XWritedUnique, xwrited_unique, G_TYPE_OBJECT) + +#define XWRITED_UNIQUE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \ + XWRITED_TYPE_UNIQUE, XWritedUniquePrivate)) + +struct _XWritedUniquePrivate { + DBusGConnection *session_bus; + DBusGProxy *session_bus_proxy; + gchar *name; + gboolean is_unique; +}; + +enum { + PROP_0, + PROP_NAME, + PROP_IS_XWRITED_UNIQUE +}; + +static gboolean +request_name(XWritedUnique *self) +{ + guint32 request_name_response; + GError *error = NULL; + + g_return_val_if_fail(self->priv->session_bus != NULL, FALSE); + g_return_val_if_fail(self->priv->session_bus_proxy != NULL, FALSE); + + if (dbus_g_proxy_call(self->priv->session_bus_proxy, "RequestName", + &error, G_TYPE_STRING, self->priv->name, G_TYPE_UINT, + DBUS_NAME_FLAG_DO_NOT_QUEUE, G_TYPE_INVALID, G_TYPE_UINT, + &request_name_response, G_TYPE_INVALID) == 0) { + g_warning("failed to acquire service name \"%s\": %s", + self->priv->name, error->message); + g_error_free(error); + return (FALSE); + } + + switch (request_name_response) { + case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: + return (TRUE); + case DBUS_REQUEST_NAME_REPLY_EXISTS: + break; + default: + g_warning("failed to acquire service name \"%s\"", + self->priv->name); + } + + return (FALSE); +} + +static void +xwrited_unique_get_property(GObject *gobject, guint property_id, GValue *value, + GParamSpec *pspec) +{ + XWritedUnique *app = XWRITED_UNIQUE(gobject); + + switch (property_id) { + case PROP_NAME: + g_value_set_string(value, app->priv->name); + break; + case PROP_IS_XWRITED_UNIQUE: + g_value_set_boolean(value, app->priv->is_unique); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, + pspec); + } +} + +static void +xwrited_unique_set_property(GObject *gobject, guint property_id, + const GValue *value, GParamSpec *pspec) +{ + XWritedUnique *app = XWRITED_UNIQUE(gobject); + + switch (property_id) { + case PROP_NAME: + app->priv->name = g_strdup(g_value_get_string(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, + pspec); + } +} + +static GObject * +xwrited_unique_constructor(GType gtype, guint n_params, + GObjectConstructParam *params) +{ + GObjectClass *parent_class; + GObject *gobject; + XWritedUnique *app; + GError *error = NULL; + + parent_class = G_OBJECT_CLASS(xwrited_unique_parent_class); + gobject = parent_class->constructor(gtype, n_params, params); + app = XWRITED_UNIQUE(gobject); + + app->priv->session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); + if (app->priv->session_bus == NULL) { + g_warning("failed to connect to DBus session bus: %s", + error->message); + g_error_free(error); + goto out; + } + + app->priv->session_bus_proxy = + dbus_g_proxy_new_for_name(app->priv->session_bus, + DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); + if (app->priv->session_bus_proxy == NULL) { + g_warning("failed to create DBus proxy"); + goto out; + } + + if (request_name(app)) { + app->priv->is_unique = TRUE; + } + +out: + return (gobject); +} + +static void +xwrited_unique_dispose(GObject *gobject) +{ + XWritedUnique *self = XWRITED_UNIQUE(gobject); + + if (self->priv->session_bus_proxy != NULL) { + g_object_unref(self->priv->session_bus_proxy); + self->priv->session_bus_proxy = NULL; + } + + G_OBJECT_CLASS(xwrited_unique_parent_class)->dispose(gobject); +} + +static void +xwrited_unique_finalize(GObject *gobject) +{ + XWritedUnique *self = XWRITED_UNIQUE(gobject); + + g_free(self->priv->name); + + G_OBJECT_CLASS(xwrited_unique_parent_class)->finalize(gobject); +} + +static void +xwrited_unique_class_init(XWritedUniqueClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + GParamSpec *pspec; + + gobject_class->constructor = xwrited_unique_constructor; + gobject_class->get_property = xwrited_unique_get_property; + gobject_class->set_property = xwrited_unique_set_property; + gobject_class->dispose = xwrited_unique_dispose; + gobject_class->finalize = xwrited_unique_finalize; + + pspec = g_param_spec_string("name", "Name", + "The unique name of the application", NULL, G_PARAM_READABLE | + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME | + G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB); + g_object_class_install_property(gobject_class, PROP_NAME, pspec); + + pspec = g_param_spec_boolean("is-unique", "Is unique", + "Whether the current application instance is unique", FALSE, + G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB); + g_object_class_install_property(gobject_class, PROP_IS_XWRITED_UNIQUE, + pspec); + + g_type_class_add_private(klass, sizeof (XWritedUniquePrivate)); +} + +static void +xwrited_unique_init(XWritedUnique *self) +{ + self->priv = XWRITED_UNIQUE_GET_PRIVATE(self); + + self->priv->is_unique = FALSE; + self->priv->session_bus_proxy = NULL; +} + +XWritedUnique * +xwrited_unique_new(const gchar *name) +{ + XWritedUnique *app; + + g_return_val_if_fail(name != NULL, NULL); + + app = g_object_new(XWRITED_TYPE_UNIQUE, "name", name, NULL); + if (app->priv->session_bus_proxy == NULL) { + g_object_unref(app); + return (NULL); + } + + return (app); +} + +gboolean +xwrited_unique_is_unique(XWritedUnique *self) +{ + g_return_val_if_fail(XWRITED_IS_UNIQUE(self), FALSE); + + return (self->priv->is_unique); +}