Branch data Line data Source code
1 : :
2 : : #include <gio/gio.h>
3 : :
4 : : /* ---------------------------------------------------------------------------------------------------- */
5 : : /* The D-Bus interface definition we want to create a GDBusProxy-derived type for: */
6 : : /* ---------------------------------------------------------------------------------------------------- */
7 : :
8 : : static const gchar introspection_xml[] =
9 : : "<node>"
10 : : " <interface name='org.freedesktop.Accounts.User'>"
11 : : " <method name='Frobnicate'>"
12 : : " <arg name='flux' type='s' direction='in'/>"
13 : : " <arg name='baz' type='s' direction='in'/>"
14 : : " <arg name='result' type='s' direction='out'/>"
15 : : " </method>"
16 : : " <signal name='Changed'/>"
17 : : " <property name='AutomaticLogin' type='b' access='readwrite'/>"
18 : : " <property name='RealName' type='s' access='read'/>"
19 : : " <property name='UserName' type='s' access='read'/>"
20 : : " </interface>"
21 : : "</node>";
22 : :
23 : : /* ---------------------------------------------------------------------------------------------------- */
24 : : /* Definition of the AccountsUser type */
25 : : /* ---------------------------------------------------------------------------------------------------- */
26 : :
27 : : #define ACCOUNTS_TYPE_USER (accounts_user_get_type ())
28 : : #define ACCOUNTS_USER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), ACCOUNTS_TYPE_USER, AccountsUser))
29 : : #define ACCOUNTS_USER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), ACCOUNTS_TYPE_USER, AccountsUserClass))
30 : : #define ACCOUNTS_USER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), ACCOUNTS_TYPE_USER, AccountsUserClass))
31 : : #define ACCOUNTS_IS_USER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), ACCOUNTS_TYPE_USER))
32 : : #define ACCOUNTS_IS_USER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), ACCOUNTS_TYPE_USER))
33 : :
34 : : typedef struct _AccountsUser AccountsUser;
35 : : typedef struct _AccountsUserClass AccountsUserClass;
36 : : typedef struct _AccountsUserPrivate AccountsUserPrivate;
37 : :
38 : : struct _AccountsUser
39 : : {
40 : : /*< private >*/
41 : : GDBusProxy parent_instance;
42 : : AccountsUserPrivate *priv;
43 : : };
44 : :
45 : : struct _AccountsUserClass
46 : : {
47 : : /*< private >*/
48 : : GDBusProxyClass parent_class;
49 : : void (*changed) (AccountsUser *user);
50 : : };
51 : :
52 : : GType accounts_user_get_type (void) G_GNUC_CONST;
53 : :
54 : : const gchar *accounts_user_get_user_name (AccountsUser *user);
55 : : const gchar *accounts_user_get_real_name (AccountsUser *user);
56 : : gboolean accounts_user_get_automatic_login (AccountsUser *user);
57 : :
58 : : void accounts_user_frobnicate (AccountsUser *user,
59 : : const gchar *flux,
60 : : gint baz,
61 : : GCancellable *cancellable,
62 : : GAsyncReadyCallback callback,
63 : : gpointer user_data);
64 : : gchar *accounts_user_frobnicate_finish (AccountsUser *user,
65 : : GAsyncResult *res,
66 : : GError **error);
67 : : gchar *accounts_user_frobnicate_sync (AccountsUser *user,
68 : : const gchar *flux,
69 : : gint baz,
70 : : GCancellable *cancellable,
71 : : GError **error);
72 : :
73 : : /* ---------------------------------------------------------------------------------------------------- */
74 : : /* Implementation of the AccountsUser type */
75 : : /* ---------------------------------------------------------------------------------------------------- */
76 : :
77 : : /* A more efficient approach than parsing XML is to use const static
78 : : * GDBusInterfaceInfo, GDBusMethodInfo, ... structures
79 : : */
80 : : static GDBusInterfaceInfo *
81 : 0 : accounts_user_get_interface_info (void)
82 : : {
83 : : static gsize has_info = 0;
84 : : static GDBusInterfaceInfo *info = NULL;
85 : 0 : if (g_once_init_enter (&has_info))
86 : : {
87 : : GDBusNodeInfo *introspection_data;
88 : 0 : introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
89 : 0 : info = introspection_data->interfaces[0];
90 : 0 : g_once_init_leave (&has_info, 1);
91 : : }
92 : 0 : return info;
93 : : }
94 : :
95 : : enum
96 : : {
97 : : PROP_0,
98 : : PROP_USER_NAME,
99 : : PROP_REAL_NAME,
100 : : PROP_AUTOMATIC_LOGIN,
101 : : };
102 : :
103 : : enum
104 : : {
105 : : CHANGED_SIGNAL,
106 : : LAST_SIGNAL
107 : : };
108 : :
109 : : static guint signals[LAST_SIGNAL] = {0};
110 : :
111 : 0 : G_DEFINE_TYPE (AccountsUser, accounts_user, G_TYPE_DBUS_PROXY)
112 : :
113 : : static void
114 : 0 : accounts_user_init (AccountsUser *user)
115 : : {
116 : : /* Sets the expected interface */
117 : 0 : g_dbus_proxy_set_interface_info (G_DBUS_PROXY (user), accounts_user_get_interface_info ());
118 : 0 : }
119 : :
120 : : static void
121 : 0 : accounts_user_get_property (GObject *object,
122 : : guint prop_id,
123 : : GValue *value,
124 : : GParamSpec *pspec)
125 : : {
126 : 0 : AccountsUser *user = ACCOUNTS_USER (object);
127 : :
128 : 0 : switch (prop_id)
129 : : {
130 : 0 : case PROP_USER_NAME:
131 : 0 : g_value_set_string (value, accounts_user_get_user_name (user));
132 : 0 : break;
133 : :
134 : 0 : case PROP_REAL_NAME:
135 : 0 : g_value_set_string (value, accounts_user_get_real_name (user));
136 : 0 : break;
137 : :
138 : 0 : case PROP_AUTOMATIC_LOGIN:
139 : 0 : g_value_set_boolean (value, accounts_user_get_automatic_login (user));
140 : 0 : break;
141 : :
142 : 0 : default:
143 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
144 : 0 : break;
145 : : }
146 : 0 : }
147 : :
148 : : const gchar *
149 : 0 : accounts_user_get_user_name (AccountsUser *user)
150 : : {
151 : : GVariant *value;
152 : : const gchar *ret;
153 : 0 : g_return_val_if_fail (ACCOUNTS_IS_USER (user), NULL);
154 : 0 : value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (user), "UserName");
155 : 0 : ret = g_variant_get_string (value, NULL);
156 : 0 : g_variant_unref (value);
157 : 0 : return ret;
158 : : }
159 : :
160 : : const gchar *
161 : 0 : accounts_user_get_real_name (AccountsUser *user)
162 : : {
163 : : GVariant *value;
164 : : const gchar *ret;
165 : 0 : g_return_val_if_fail (ACCOUNTS_IS_USER (user), NULL);
166 : 0 : value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (user), "RealName");
167 : 0 : ret = g_variant_get_string (value, NULL);
168 : 0 : g_variant_unref (value);
169 : 0 : return ret;
170 : : }
171 : :
172 : : gboolean
173 : 0 : accounts_user_get_automatic_login (AccountsUser *user)
174 : : {
175 : : GVariant *value;
176 : : gboolean ret;
177 : 0 : g_return_val_if_fail (ACCOUNTS_IS_USER (user), FALSE);
178 : 0 : value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (user), "AutomaticLogin");
179 : 0 : ret = g_variant_get_boolean (value);
180 : 0 : g_variant_unref (value);
181 : 0 : return ret;
182 : : }
183 : :
184 : : static void
185 : 0 : accounts_user_g_signal (GDBusProxy *proxy,
186 : : const gchar *sender_name,
187 : : const gchar *signal_name,
188 : : GVariant *parameters)
189 : : {
190 : 0 : AccountsUser *user = ACCOUNTS_USER (proxy);
191 : 0 : if (g_strcmp0 (signal_name, "Changed") == 0)
192 : 0 : g_signal_emit (user, signals[CHANGED_SIGNAL], 0);
193 : 0 : }
194 : :
195 : : static void
196 : 0 : accounts_user_g_properties_changed (GDBusProxy *proxy,
197 : : GVariant *changed_properties,
198 : : const gchar* const *invalidated_properties)
199 : : {
200 : 0 : AccountsUser *user = ACCOUNTS_USER (proxy);
201 : : GVariantIter *iter;
202 : : const gchar *key;
203 : :
204 : 0 : if (changed_properties != NULL)
205 : : {
206 : 0 : g_variant_get (changed_properties, "a{sv}", &iter);
207 : 0 : while (g_variant_iter_next (iter, "{&sv}", &key, NULL))
208 : : {
209 : 0 : if (g_strcmp0 (key, "AutomaticLogin") == 0)
210 : 0 : g_object_notify (G_OBJECT (user), "automatic-login");
211 : 0 : else if (g_strcmp0 (key, "RealName") == 0)
212 : 0 : g_object_notify (G_OBJECT (user), "real-name");
213 : 0 : else if (g_strcmp0 (key, "UserName") == 0)
214 : 0 : g_object_notify (G_OBJECT (user), "user-name");
215 : : }
216 : 0 : g_variant_iter_free (iter);
217 : : }
218 : 0 : }
219 : :
220 : : static void
221 : 0 : accounts_user_class_init (AccountsUserClass *klass)
222 : : {
223 : : GObjectClass *gobject_class;
224 : : GDBusProxyClass *proxy_class;
225 : :
226 : 0 : gobject_class = G_OBJECT_CLASS (klass);
227 : 0 : gobject_class->get_property = accounts_user_get_property;
228 : :
229 : 0 : proxy_class = G_DBUS_PROXY_CLASS (klass);
230 : 0 : proxy_class->g_signal = accounts_user_g_signal;
231 : 0 : proxy_class->g_properties_changed = accounts_user_g_properties_changed;
232 : :
233 : 0 : g_object_class_install_property (gobject_class,
234 : : PROP_USER_NAME,
235 : : g_param_spec_string ("user-name",
236 : : "User Name",
237 : : "The user name of the user",
238 : : NULL,
239 : : G_PARAM_READABLE |
240 : : G_PARAM_STATIC_STRINGS));
241 : :
242 : 0 : g_object_class_install_property (gobject_class,
243 : : PROP_REAL_NAME,
244 : : g_param_spec_string ("real-name",
245 : : "Real Name",
246 : : "The real name of the user",
247 : : NULL,
248 : : G_PARAM_READABLE |
249 : : G_PARAM_STATIC_STRINGS));
250 : :
251 : 0 : g_object_class_install_property (gobject_class,
252 : : PROP_AUTOMATIC_LOGIN,
253 : : g_param_spec_boolean ("automatic-login",
254 : : "Automatic Login",
255 : : "Whether the user is automatically logged in",
256 : : FALSE,
257 : : G_PARAM_READABLE |
258 : : G_PARAM_STATIC_STRINGS));
259 : :
260 : 0 : signals[CHANGED_SIGNAL] = g_signal_new ("changed",
261 : : ACCOUNTS_TYPE_USER,
262 : : G_SIGNAL_RUN_LAST,
263 : : G_STRUCT_OFFSET (AccountsUserClass, changed),
264 : : NULL,
265 : : NULL,
266 : : g_cclosure_marshal_VOID__VOID,
267 : : G_TYPE_NONE,
268 : : 0);
269 : 0 : }
270 : :
271 : : gchar *
272 : 0 : accounts_user_frobnicate_sync (AccountsUser *user,
273 : : const gchar *flux,
274 : : gint baz,
275 : : GCancellable *cancellable,
276 : : GError **error)
277 : : {
278 : : gchar *ret;
279 : : GVariant *value;
280 : :
281 : 0 : g_return_val_if_fail (ACCOUNTS_IS_USER (user), NULL);
282 : :
283 : 0 : ret = NULL;
284 : :
285 : 0 : value = g_dbus_proxy_call_sync (G_DBUS_PROXY (user),
286 : : "Frobnicate",
287 : : g_variant_new ("(si)",
288 : : flux,
289 : : baz),
290 : : G_DBUS_CALL_FLAGS_NONE,
291 : : -1,
292 : : cancellable,
293 : : error);
294 : 0 : if (value != NULL)
295 : : {
296 : 0 : g_variant_get (value, "(s)", &ret);
297 : 0 : g_variant_unref (value);
298 : : }
299 : 0 : return ret;
300 : : }
301 : :
302 : : void
303 : 0 : accounts_user_frobnicate (AccountsUser *user,
304 : : const gchar *flux,
305 : : gint baz,
306 : : GCancellable *cancellable,
307 : : GAsyncReadyCallback callback,
308 : : gpointer user_data)
309 : : {
310 : 0 : g_return_if_fail (ACCOUNTS_IS_USER (user));
311 : 0 : g_dbus_proxy_call (G_DBUS_PROXY (user),
312 : : "Frobnicate",
313 : : g_variant_new ("(si)",
314 : : flux,
315 : : baz),
316 : : G_DBUS_CALL_FLAGS_NONE,
317 : : -1,
318 : : cancellable,
319 : : callback,
320 : : user_data);
321 : : }
322 : :
323 : :
324 : : gchar *
325 : 0 : accounts_user_frobnicate_finish (AccountsUser *user,
326 : : GAsyncResult *res,
327 : : GError **error)
328 : : {
329 : : gchar *ret;
330 : : GVariant *value;
331 : :
332 : 0 : ret = NULL;
333 : 0 : value = g_dbus_proxy_call_finish (G_DBUS_PROXY (user), res, error);
334 : 0 : if (value != NULL)
335 : : {
336 : 0 : g_variant_get (value, "(s)", &ret);
337 : 0 : g_variant_unref (value);
338 : : }
339 : 0 : return ret;
340 : : }
341 : :
342 : : /* ---------------------------------------------------------------------------------------------------- */
343 : : /* Example usage of the AccountsUser type */
344 : : /* ---------------------------------------------------------------------------------------------------- */
345 : :
346 : : static void
347 : 0 : print_user (AccountsUser *user)
348 : : {
349 : 0 : g_print (" user-name = `%s'\n", accounts_user_get_user_name (user));
350 : 0 : g_print (" real-name = `%s'\n", accounts_user_get_real_name (user));
351 : 0 : g_print (" automatic-login = %s\n", accounts_user_get_automatic_login (user) ? "true" : "false");
352 : 0 : }
353 : :
354 : : static void
355 : 0 : on_changed (AccountsUser *user,
356 : : gpointer user_data)
357 : : {
358 : 0 : g_print ("+++ Received the AccountsUser::changed signal\n");
359 : 0 : print_user (user);
360 : 0 : }
361 : :
362 : : static void
363 : 0 : on_notify (GObject *object,
364 : : GParamSpec *pspec,
365 : : gpointer user_data)
366 : : {
367 : 0 : AccountsUser *user = ACCOUNTS_USER (object);
368 : 0 : g_print ("+++ Received the GObject::notify signal for property `%s'\n",
369 : : pspec->name);
370 : 0 : print_user (user);
371 : 0 : }
372 : :
373 : : static void
374 : 0 : on_accounts_proxy_available (GObject *object,
375 : : GAsyncResult *result,
376 : : gpointer user_data)
377 : : {
378 : 0 : GError *error = NULL;
379 : : GObject *user_object;
380 : : AccountsUser *user;
381 : :
382 : 0 : user_object = g_async_initable_new_finish (G_ASYNC_INITABLE (object),
383 : : result,
384 : : &error);
385 : 0 : if (!user_object)
386 : : {
387 : 0 : g_error ("Failed to create proxy: %s", error->message);
388 : : g_clear_error (&error);
389 : : return;
390 : : }
391 : 0 : user = ACCOUNTS_USER (user_object);
392 : :
393 : 0 : g_print ("+++ Acquired proxy for user\n");
394 : 0 : print_user (user);
395 : :
396 : 0 : g_signal_connect (user,
397 : : "notify",
398 : : G_CALLBACK (on_notify),
399 : : NULL);
400 : 0 : g_signal_connect (user,
401 : : "changed",
402 : : G_CALLBACK (on_changed),
403 : : NULL);
404 : : }
405 : :
406 : : static void
407 : 0 : on_accounts_appeared (GDBusConnection *connection,
408 : : const gchar *name,
409 : : const gchar *name_owner,
410 : : gpointer user_data)
411 : : {
412 : 0 : g_async_initable_new_async (ACCOUNTS_TYPE_USER, 0, NULL,
413 : : on_accounts_proxy_available,
414 : : "g-flags", 0,
415 : : "g-interface-info", NULL,
416 : : "g-unique-bus-name", name_owner,
417 : : "g-connection", connection,
418 : : "g-object-path", "/org/freedesktop/Accounts/User500",
419 : : "g-interface-name", "org.freedesktop.Accounts.User");
420 : 0 : }
421 : :
422 : : static void
423 : 0 : on_accounts_vanished (GDBusConnection *connection,
424 : : const gchar *name,
425 : : gpointer user_data)
426 : : {
427 : 0 : }
428 : :
429 : : /* ---------------------------------------------------------------------------------------------------- */
430 : :
431 : : gint
432 : 0 : main (gint argc, gchar *argv[])
433 : : {
434 : : guint watcher_id;
435 : : GMainLoop *loop;
436 : :
437 : 0 : watcher_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
438 : : "org.freedesktop.Accounts",
439 : : G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
440 : : on_accounts_appeared,
441 : : on_accounts_vanished,
442 : : NULL, NULL);
443 : :
444 : 0 : loop = g_main_loop_new (NULL, FALSE);
445 : 0 : g_main_loop_run (loop);
446 : 0 : g_main_loop_unref (loop);
447 : 0 : g_bus_unwatch_name (watcher_id);
448 : :
449 : 0 : return 0;
450 : : }
|