comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:52694b49dcc4
1 /*
2 * Copyright (C) 2011 Guido Berhoerster <guido+xwrited@berhoerster.name>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #define _XOPEN_SOURCE 600
25
26 #include <glib.h>
27 #include <dbus/dbus-glib.h>
28 #include <dbus/dbus.h>
29
30 #include "xwrited-unique.h"
31
32 G_DEFINE_TYPE(XWritedUnique, xwrited_unique, G_TYPE_OBJECT)
33
34 #define XWRITED_UNIQUE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
35 XWRITED_TYPE_UNIQUE, XWritedUniquePrivate))
36
37 struct _XWritedUniquePrivate {
38 DBusGConnection *session_bus;
39 DBusGProxy *session_bus_proxy;
40 gchar *name;
41 gboolean is_unique;
42 };
43
44 enum {
45 PROP_0,
46 PROP_NAME,
47 PROP_IS_XWRITED_UNIQUE
48 };
49
50 static gboolean
51 request_name(XWritedUnique *self)
52 {
53 guint32 request_name_response;
54 GError *error = NULL;
55
56 g_return_val_if_fail(self->priv->session_bus != NULL, FALSE);
57 g_return_val_if_fail(self->priv->session_bus_proxy != NULL, FALSE);
58
59 if (dbus_g_proxy_call(self->priv->session_bus_proxy, "RequestName",
60 &error, G_TYPE_STRING, self->priv->name, G_TYPE_UINT,
61 DBUS_NAME_FLAG_DO_NOT_QUEUE, G_TYPE_INVALID, G_TYPE_UINT,
62 &request_name_response, G_TYPE_INVALID) == 0) {
63 g_warning("failed to acquire service name \"%s\": %s",
64 self->priv->name, error->message);
65 g_error_free(error);
66 return (FALSE);
67 }
68
69 switch (request_name_response) {
70 case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
71 return (TRUE);
72 case DBUS_REQUEST_NAME_REPLY_EXISTS:
73 break;
74 default:
75 g_warning("failed to acquire service name \"%s\"",
76 self->priv->name);
77 }
78
79 return (FALSE);
80 }
81
82 static void
83 xwrited_unique_get_property(GObject *gobject, guint property_id, GValue *value,
84 GParamSpec *pspec)
85 {
86 XWritedUnique *app = XWRITED_UNIQUE(gobject);
87
88 switch (property_id) {
89 case PROP_NAME:
90 g_value_set_string(value, app->priv->name);
91 break;
92 case PROP_IS_XWRITED_UNIQUE:
93 g_value_set_boolean(value, app->priv->is_unique);
94 break;
95 default:
96 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id,
97 pspec);
98 }
99 }
100
101 static void
102 xwrited_unique_set_property(GObject *gobject, guint property_id,
103 const GValue *value, GParamSpec *pspec)
104 {
105 XWritedUnique *app = XWRITED_UNIQUE(gobject);
106
107 switch (property_id) {
108 case PROP_NAME:
109 app->priv->name = g_strdup(g_value_get_string(value));
110 break;
111 default:
112 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id,
113 pspec);
114 }
115 }
116
117 static GObject *
118 xwrited_unique_constructor(GType gtype, guint n_params,
119 GObjectConstructParam *params)
120 {
121 GObjectClass *parent_class;
122 GObject *gobject;
123 XWritedUnique *app;
124 GError *error = NULL;
125
126 parent_class = G_OBJECT_CLASS(xwrited_unique_parent_class);
127 gobject = parent_class->constructor(gtype, n_params, params);
128 app = XWRITED_UNIQUE(gobject);
129
130 app->priv->session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
131 if (app->priv->session_bus == NULL) {
132 g_warning("failed to connect to DBus session bus: %s",
133 error->message);
134 g_error_free(error);
135 goto out;
136 }
137
138 app->priv->session_bus_proxy =
139 dbus_g_proxy_new_for_name(app->priv->session_bus,
140 DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
141 if (app->priv->session_bus_proxy == NULL) {
142 g_warning("failed to create DBus proxy");
143 goto out;
144 }
145
146 if (request_name(app)) {
147 app->priv->is_unique = TRUE;
148 }
149
150 out:
151 return (gobject);
152 }
153
154 static void
155 xwrited_unique_dispose(GObject *gobject)
156 {
157 XWritedUnique *self = XWRITED_UNIQUE(gobject);
158
159 if (self->priv->session_bus_proxy != NULL) {
160 g_object_unref(self->priv->session_bus_proxy);
161 self->priv->session_bus_proxy = NULL;
162 }
163
164 G_OBJECT_CLASS(xwrited_unique_parent_class)->dispose(gobject);
165 }
166
167 static void
168 xwrited_unique_finalize(GObject *gobject)
169 {
170 XWritedUnique *self = XWRITED_UNIQUE(gobject);
171
172 g_free(self->priv->name);
173
174 G_OBJECT_CLASS(xwrited_unique_parent_class)->finalize(gobject);
175 }
176
177 static void
178 xwrited_unique_class_init(XWritedUniqueClass *klass)
179 {
180 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
181 GParamSpec *pspec;
182
183 gobject_class->constructor = xwrited_unique_constructor;
184 gobject_class->get_property = xwrited_unique_get_property;
185 gobject_class->set_property = xwrited_unique_set_property;
186 gobject_class->dispose = xwrited_unique_dispose;
187 gobject_class->finalize = xwrited_unique_finalize;
188
189 pspec = g_param_spec_string("name", "Name",
190 "The unique name of the application", NULL, G_PARAM_READABLE |
191 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME |
192 G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
193 g_object_class_install_property(gobject_class, PROP_NAME, pspec);
194
195 pspec = g_param_spec_boolean("is-unique", "Is unique",
196 "Whether the current application instance is unique", FALSE,
197 G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK |
198 G_PARAM_STATIC_BLURB);
199 g_object_class_install_property(gobject_class, PROP_IS_XWRITED_UNIQUE,
200 pspec);
201
202 g_type_class_add_private(klass, sizeof (XWritedUniquePrivate));
203 }
204
205 static void
206 xwrited_unique_init(XWritedUnique *self)
207 {
208 self->priv = XWRITED_UNIQUE_GET_PRIVATE(self);
209
210 self->priv->is_unique = FALSE;
211 self->priv->session_bus_proxy = NULL;
212 }
213
214 XWritedUnique *
215 xwrited_unique_new(const gchar *name)
216 {
217 XWritedUnique *app;
218
219 g_return_val_if_fail(name != NULL, NULL);
220
221 app = g_object_new(XWRITED_TYPE_UNIQUE, "name", name, NULL);
222 if (app->priv->session_bus_proxy == NULL) {
223 g_object_unref(app);
224 return (NULL);
225 }
226
227 return (app);
228 }
229
230 gboolean
231 xwrited_unique_is_unique(XWritedUnique *self)
232 {
233 g_return_val_if_fail(XWRITED_IS_UNIQUE(self), FALSE);
234
235 return (self->priv->is_unique);
236 }