~ubuntu-branches/ubuntu/quantal/colord/quantal-proposed

1 by Christopher James Halse Rogers
Import upstream version 0.1.11
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2
 *
3
 * Copyright (C) 2010-2011 Richard Hughes <richard@hughsie.com>
4
 *
5
 * Licensed under the GNU Lesser General Public License Version 2.1
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
20
 */
21
22
/**
23
 * SECTION:cd-client
24
 * @short_description: Main client object for accessing the colord daemon
25
 *
26
 * A helper GObject to use for accessing colord information, and to be notified
27
 * when it is changed.
28
 *
29
 * See also: #CdDevice
30
 */
31
32
#include "config.h"
33
34
#include <fcntl.h>
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <sys/stat.h>
38
#include <sys/types.h>
39
40
#include <gio/gio.h>
41
#include <gio/gunixfdlist.h>
42
#include <glib/gstdio.h>
43
#include <glib.h>
44
45
#include "cd-enum.h"
46
#include "cd-client.h"
47
#include "cd-client-sync.h"
48
#include "cd-device.h"
49
#include "cd-device-sync.h"
50
#include "cd-sensor.h"
51
#include "cd-profile-sync.h"
52
53
static void	cd_client_class_init	(CdClientClass	*klass);
54
static void	cd_client_init		(CdClient	*client);
55
static void	cd_client_finalize	(GObject	*object);
56
57
#define CD_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), CD_TYPE_CLIENT, CdClientPrivate))
58
59
#define CD_CLIENT_MESSAGE_TIMEOUT	15000 /* ms */
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
60
#define CD_CLIENT_IMPORT_DAEMON_TIMEOUT	5000 /* ms */
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
61
#define COLORD_DBUS_SERVICE		"org.freedesktop.ColorManager"
62
#define COLORD_DBUS_PATH		"/org/freedesktop/ColorManager"
63
#define COLORD_DBUS_INTERFACE		"org.freedesktop.ColorManager"
64
65
/**
66
 * CdClientPrivate:
67
 *
68
 * Private #CdClient data
69
 **/
70
struct _CdClientPrivate
71
{
72
	GDBusProxy		*proxy;
73
	gchar			*daemon_version;
74
};
75
76
enum {
77
	SIGNAL_CHANGED,
78
	SIGNAL_DEVICE_ADDED,
79
	SIGNAL_DEVICE_REMOVED,
80
	SIGNAL_DEVICE_CHANGED,
81
	SIGNAL_PROFILE_ADDED,
82
	SIGNAL_PROFILE_REMOVED,
83
	SIGNAL_PROFILE_CHANGED,
84
	SIGNAL_SENSOR_ADDED,
85
	SIGNAL_SENSOR_REMOVED,
86
	SIGNAL_SENSOR_CHANGED,
87
	SIGNAL_LAST
88
};
89
90
enum {
91
	PROP_0,
92
	PROP_DAEMON_VERSION,
93
	PROP_CONNECTED,
94
	PROP_LAST
95
};
96
97
static guint signals [SIGNAL_LAST] = { 0 };
98
static gpointer cd_client_object = NULL;
99
100
G_DEFINE_TYPE (CdClient, cd_client, G_TYPE_OBJECT)
101
102
/**
103
 * cd_client_error_quark:
104
 *
105
 * Return value: An error quark.
106
 *
107
 * Since: 0.1.0
108
 **/
109
GQuark
110
cd_client_error_quark (void)
111
{
112
	static GQuark quark = 0;
1.2.1 by Sjoerd Simons
Import upstream version 0.1.13
113
	if (!quark) {
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
114
		quark = g_quark_from_static_string ("cd_client_error");
1.2.1 by Sjoerd Simons
Import upstream version 0.1.13
115
		g_dbus_error_register_error (quark,
116
					     CD_CLIENT_ERROR_FAILED,
117
					     COLORD_DBUS_SERVICE ".Failed");
118
		g_dbus_error_register_error (quark,
119
					     CD_CLIENT_ERROR_ALREADY_EXISTS,
120
					     COLORD_DBUS_SERVICE ".AlreadyExists");
121
	}
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
122
	return quark;
123
}
124
125
/**
126
 * cd_client_get_daemon_version:
127
 * @client: a #CdClient instance.
128
 *
129
 * Get colord daemon version.
130
 *
131
 * Return value: string containing the daemon version, e.g. "0.1.0"
132
 *
133
 * Since: 0.1.0
134
 **/
135
const gchar *
136
cd_client_get_daemon_version (CdClient *client)
137
{
138
	g_return_val_if_fail (CD_IS_CLIENT (client), NULL);
139
	g_return_val_if_fail (client->priv->proxy != NULL, NULL);
140
	return client->priv->daemon_version;
141
}
142
143
/**
144
 * cd_client_get_connected:
145
 * @client: a #CdClient instance.
146
 *
147
 * Gets if the client has been connected.
148
 *
149
 * Return value: %TRUE if properties are valid
150
 *
151
 * Since: 0.1.9
152
 **/
153
gboolean
154
cd_client_get_connected (CdClient *client)
155
{
156
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
157
	return client->priv->proxy != NULL;
158
}
159
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
160
/**
161
 * cd_client_get_has_server:
162
 * @client: a #CdClient instance.
163
 *
164
 * Gets if the colord server is currently running.
165
 *
166
 * Return value: %TRUE if the colord process is running
167
 *
168
 * Since: 0.1.12
169
 **/
170
gboolean
171
cd_client_get_has_server (CdClient *client)
172
{
173
	gboolean connected = FALSE;
174
	gchar *name_owner = NULL;
175
176
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
177
178
	/* not yet connected */
179
	if (client->priv->proxy == NULL)
180
		goto out;
181
182
	/* get name owner */
183
	name_owner = g_dbus_proxy_get_name_owner (client->priv->proxy);
184
	if (name_owner == NULL)
185
		goto out;
186
187
	/* just assume it's ready for use */
188
	connected = TRUE;
189
out:
190
	g_free (name_owner);
191
	return connected;
192
}
193
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
194
/**********************************************************************/
195
196
/**
197
 * cd_client_dbus_signal_cb:
198
 **/
199
static void
200
cd_client_dbus_signal_cb (GDBusProxy *proxy,
201
			  gchar      *sender_name,
202
			  gchar      *signal_name,
203
			  GVariant   *parameters,
204
			  CdClient   *client)
205
{
206
	CdDevice *device = NULL;
207
	CdProfile *profile = NULL;
208
	CdSensor *sensor = NULL;
209
	gchar *object_path_tmp = NULL;
210
211
	if (g_strcmp0 (signal_name, "Changed") == 0) {
212
		g_warning ("changed");
213
	} else if (g_strcmp0 (signal_name, "DeviceAdded") == 0) {
214
		g_variant_get (parameters, "(o)", &object_path_tmp);
215
		device = cd_device_new_with_object_path (object_path_tmp);
216
		g_signal_emit (client, signals[SIGNAL_DEVICE_ADDED], 0,
217
			       device);
218
	} else if (g_strcmp0 (signal_name, "DeviceRemoved") == 0) {
219
		g_variant_get (parameters, "(o)", &object_path_tmp);
220
		device = cd_device_new_with_object_path (object_path_tmp);
221
		g_signal_emit (client, signals[SIGNAL_DEVICE_REMOVED], 0,
222
			       device);
223
	} else if (g_strcmp0 (signal_name, "DeviceChanged") == 0) {
224
		g_variant_get (parameters, "(o)", &object_path_tmp);
225
		device = cd_device_new_with_object_path (object_path_tmp);
226
		g_signal_emit (client, signals[SIGNAL_DEVICE_CHANGED], 0,
227
			       device);
228
	} else if (g_strcmp0 (signal_name, "ProfileAdded") == 0) {
229
		g_variant_get (parameters, "(o)", &object_path_tmp);
230
		profile = cd_profile_new_with_object_path (object_path_tmp);
231
		g_signal_emit (client, signals[SIGNAL_PROFILE_ADDED], 0,
232
			       profile);
233
	} else if (g_strcmp0 (signal_name, "ProfileRemoved") == 0) {
234
		g_variant_get (parameters, "(o)", &object_path_tmp);
235
		profile = cd_profile_new_with_object_path (object_path_tmp);
236
		g_signal_emit (client, signals[SIGNAL_PROFILE_REMOVED], 0,
237
			       profile);
238
	} else if (g_strcmp0 (signal_name, "ProfileChanged") == 0) {
239
		g_variant_get (parameters, "(o)", &object_path_tmp);
240
		profile = cd_profile_new_with_object_path (object_path_tmp);
241
		g_signal_emit (client, signals[SIGNAL_PROFILE_CHANGED], 0,
242
			       profile);
243
	} else if (g_strcmp0 (signal_name, "SensorAdded") == 0) {
244
		g_variant_get (parameters, "(o)", &object_path_tmp);
245
		sensor = cd_sensor_new_with_object_path (object_path_tmp);
246
		g_signal_emit (client, signals[SIGNAL_SENSOR_ADDED], 0,
247
			       sensor);
248
	} else if (g_strcmp0 (signal_name, "SensorRemoved") == 0) {
249
		g_variant_get (parameters, "(o)", &object_path_tmp);
250
		sensor = cd_sensor_new_with_object_path (object_path_tmp);
251
		g_signal_emit (client, signals[SIGNAL_SENSOR_REMOVED], 0,
252
			       sensor);
253
	} else if (g_strcmp0 (signal_name, "SensorChanged") == 0) {
254
		g_variant_get (parameters, "(o)", &object_path_tmp);
255
		sensor = cd_sensor_new_with_object_path (object_path_tmp);
256
		g_signal_emit (client, signals[SIGNAL_SENSOR_CHANGED], 0,
257
			       sensor);
258
	} else {
259
		g_warning ("unhandled signal '%s'", signal_name);
260
	}
261
	g_free (object_path_tmp);
262
	if (device != NULL)
263
		g_object_unref (device);
264
	if (sensor != NULL)
265
		g_object_unref (sensor);
266
	if (profile != NULL)
267
		g_object_unref (profile);
268
}
269
270
/**
271
 * cd_client_owner_notify_cb:
272
 **/
273
static void
274
cd_client_owner_notify_cb (GObject *object,
275
			   GParamSpec *pspec,
276
			   CdClient *client)
277
{
278
	/* daemon has quit, clearing caches */
279
}
280
281
/**********************************************************************/
282
283
/**
284
 * cd_client_connect_finish:
285
 * @client: a #CdClient instance.
286
 * @res: the #GAsyncResult
287
 * @error: A #GError or %NULL
288
 *
289
 * Gets the result from the asynchronous function.
290
 *
291
 * Return value: success
292
 *
293
 * Since: 0.1.6
294
 **/
295
gboolean
296
cd_client_connect_finish (CdClient *client,
297
			  GAsyncResult *res,
298
			  GError **error)
299
{
300
	GSimpleAsyncResult *simple;
301
302
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
303
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
304
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
305
306
	simple = G_SIMPLE_ASYNC_RESULT (res);
307
	if (g_simple_async_result_propagate_error (simple, error))
308
		return FALSE;
309
310
	return g_simple_async_result_get_op_res_gboolean (simple);
311
}
312
313
static void
314
cd_client_connect_cb (GObject *source_object,
315
		      GAsyncResult *res,
316
		      gpointer user_data)
317
{
318
	GError *error = NULL;
319
	GVariant *daemon_version = NULL;
320
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
321
	CdClient *client = CD_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (user_data)));
322
323
	/* get result */
324
	client->priv->proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
325
	if (client->priv->proxy == NULL) {
326
		g_simple_async_result_set_from_error (G_SIMPLE_ASYNC_RESULT (res_source),
327
						      error);
328
		g_simple_async_result_complete (G_SIMPLE_ASYNC_RESULT (res_source));
329
		g_error_free (error);
330
		goto out;
331
	}
332
333
	/* get daemon version */
334
	daemon_version = g_dbus_proxy_get_cached_property (client->priv->proxy,
335
							   CD_CLIENT_PROPERTY_DAEMON_VERSION);
336
	if (daemon_version != NULL)
337
		client->priv->daemon_version = g_variant_dup_string (daemon_version, NULL);
338
339
	/* get signals from DBus */
340
	g_signal_connect (client->priv->proxy,
341
			  "g-signal",
342
			  G_CALLBACK (cd_client_dbus_signal_cb),
343
			  client);
344
345
	/* watch to see if it's fallen off the bus */
346
	g_signal_connect (client->priv->proxy,
347
			 "notify::g-name-owner",
348
			 G_CALLBACK (cd_client_owner_notify_cb),
349
			 client);
350
351
	/* success */
352
	g_simple_async_result_set_op_res_gboolean (res_source, TRUE);
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
353
	g_simple_async_result_complete_in_idle (res_source);
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
354
out:
355
	if (daemon_version != NULL)
356
		g_variant_unref (daemon_version);
357
	g_object_unref (res_source);
358
}
359
360
/**
361
 * cd_client_connect:
362
 * @client: a #CdClient instance
363
 * @cancellable: a #GCancellable or %NULL
364
 * @callback: the function to run on completion
365
 * @user_data: the data to pass to @callback
366
 *
367
 * Connects to the colord daemon.
368
 *
369
 * Since: 0.1.6
370
 **/
371
void
372
cd_client_connect (CdClient *client,
373
		   GCancellable *cancellable,
374
		   GAsyncReadyCallback callback,
375
		   gpointer user_data)
376
{
377
	GSimpleAsyncResult *res;
378
379
	g_return_if_fail (CD_IS_CLIENT (client));
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
380
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
381
382
	res = g_simple_async_result_new (G_OBJECT (client),
383
					 callback,
384
					 user_data,
385
					 cd_client_connect);
386
387
	/* already connected */
388
	if (client->priv->proxy != NULL) {
389
		g_simple_async_result_set_op_res_gboolean (res, TRUE);
390
		g_simple_async_result_complete_in_idle (res);
391
		return;
392
	}
393
394
	/* connect async */
395
	g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
396
				  G_DBUS_PROXY_FLAGS_NONE,
397
				  NULL,
398
				  COLORD_DBUS_SERVICE,
399
				  COLORD_DBUS_PATH,
400
				  COLORD_DBUS_INTERFACE,
401
				  cancellable,
402
				  cd_client_connect_cb,
403
				  res);
404
}
405
406
/**********************************************************************/
407
408
/**
409
 * cd_client_create_device_finish:
410
 * @client: a #CdClient instance.
411
 * @res: the #GAsyncResult
412
 * @error: A #GError or %NULL
413
 *
414
 * Gets the result from the asynchronous function.
415
 *
416
 * Return value: (transfer full): a #CdDevice or %NULL
417
 *
418
 * Since: 0.1.8
419
 **/
420
CdDevice *
421
cd_client_create_device_finish (CdClient *client,
422
				GAsyncResult *res,
423
				GError **error)
424
{
425
	GSimpleAsyncResult *simple;
426
427
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
428
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
429
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
430
431
	simple = G_SIMPLE_ASYNC_RESULT (res);
432
	if (g_simple_async_result_propagate_error (simple, error))
433
		return FALSE;
434
435
	return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
436
}
437
438
static void
439
cd_client_create_device_cb (GObject *source_object,
440
			    GAsyncResult *res,
441
			    gpointer user_data)
442
{
443
	GError *error = NULL;
444
	GVariant *result;
445
	gchar *object_path = NULL;
446
	CdDevice *device;
447
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
448
449
	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
450
					   res,
451
					   &error);
452
	if (result == NULL) {
1.2.1 by Sjoerd Simons
Import upstream version 0.1.13
453
		g_simple_async_result_set_from_error (res_source,
454
						      error);
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
455
		g_error_free (error);
456
		goto out;
457
	}
458
459
	/* create CdDevice object */
460
	g_variant_get (result, "(o)",
461
		       &object_path);
462
	device = cd_device_new ();
463
	cd_device_set_object_path (device, object_path);
464
465
	/* success */
466
	g_simple_async_result_set_op_res_gpointer (res_source,
467
						   device,
1.2.4 by Christopher James Halse Rogers
Import upstream version 0.1.18
468
						   (GDestroyNotify) g_object_unref);
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
469
	g_variant_unref (result);
470
out:
471
	g_free (object_path);
472
	g_simple_async_result_complete_in_idle (res_source);
473
	g_object_unref (res_source);
474
}
475
476
/**
477
 * cd_client_create_device:
478
 * @client: a #CdClient instance.
479
 * @id: identifier for the device
480
 * @scope: the scope of the device
481
 * @properties: properties to set on the device, or %NULL
482
 * @cancellable: a #GCancellable, or %NULL
483
 * @callback: the function to run on completion
484
 * @user_data: the data to pass to @callback
485
 *
486
 * Creates a color device.
487
 *
488
 * Since: 0.1.8
489
 **/
490
void
491
cd_client_create_device (CdClient *client,
492
			 const gchar *id,
493
			 CdObjectScope scope,
494
			 GHashTable *properties,
495
			 GCancellable *cancellable,
496
			 GAsyncReadyCallback callback,
497
			 gpointer user_data)
498
{
499
	GSimpleAsyncResult *res;
500
	GVariantBuilder builder;
501
	GList *list, *l;
502
503
	g_return_if_fail (CD_IS_CLIENT (client));
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
504
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
505
	g_return_if_fail (client->priv->proxy != NULL);
506
507
	res = g_simple_async_result_new (G_OBJECT (client),
508
					 callback,
509
					 user_data,
510
					 cd_client_create_device);
511
512
	/* add properties */
513
	g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
514
	if (properties != NULL) {
515
		list = g_hash_table_get_keys (properties);
516
		for (l = list; l != NULL; l = l->next) {
517
			g_variant_builder_add (&builder,
518
					       "{ss}",
519
					       l->data,
520
					       g_hash_table_lookup (properties,
521
								    l->data));
522
		}
523
		g_list_free (list);
524
	} else {
525
		/* just fake something here */
526
		g_variant_builder_add (&builder,
527
				       "{ss}",
528
				       CD_DEVICE_PROPERTY_KIND,
529
				       "unknown");
530
	}
531
532
	g_dbus_proxy_call (client->priv->proxy,
533
			   "CreateDevice",
534
			   g_variant_new ("(ssa{ss})",
535
					  id,
536
					  cd_object_scope_to_string (scope),
537
					  &builder),
538
			   G_DBUS_CALL_FLAGS_NONE,
539
			   -1,
540
			   cancellable,
541
			   cd_client_create_device_cb,
542
			   res);
543
}
544
545
/**********************************************************************/
546
547
/**
548
 * cd_client_create_profile_finish:
549
 * @client: a #CdClient instance.
550
 * @res: the #GAsyncResult
551
 * @error: A #GError or %NULL
552
 *
553
 * Gets the result from the asynchronous function.
554
 *
555
 * Return value: (transfer full): a #CdProfile or %NULL
556
 *
557
 * Since: 0.1.8
558
 **/
559
CdProfile *
560
cd_client_create_profile_finish (CdClient *client,
561
				 GAsyncResult *res,
562
				 GError **error)
563
{
564
	GSimpleAsyncResult *simple;
565
566
	g_return_val_if_fail (CD_IS_CLIENT (client), NULL);
567
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), NULL);
568
	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
569
570
	simple = G_SIMPLE_ASYNC_RESULT (res);
571
	if (g_simple_async_result_propagate_error (simple, error))
572
		return NULL;
573
574
	return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
575
}
576
577
static void
578
cd_client_create_profile_cb (GObject *source_object,
579
			     GAsyncResult *res,
580
			     gpointer user_data)
581
{
582
	GError *error = NULL;
583
	GDBusMessage *reply;
584
	gchar *object_path = NULL;
585
	CdProfile *profile;
586
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
587
588
	reply = g_dbus_connection_send_message_with_reply_finish (G_DBUS_CONNECTION (source_object),
589
								  res,
590
								  &error);
591
	if (reply == NULL) {
592
		g_simple_async_result_set_error (res_source,
593
						 CD_CLIENT_ERROR,
594
						 CD_CLIENT_ERROR_FAILED,
595
						 "Failed to CreateProfile: %s",
596
						 error->message);
597
		g_error_free (error);
598
		goto out;
599
	}
600
601
	/* this is an error message */
602
	if (g_dbus_message_get_message_type (reply) == G_DBUS_MESSAGE_TYPE_ERROR) {
603
		g_dbus_message_to_gerror (reply, &error);
1.2.1 by Sjoerd Simons
Import upstream version 0.1.13
604
		g_simple_async_result_set_from_error (res_source, error);
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
605
		g_error_free (error);
606
		goto out;
607
	}
608
609
	/* create thick CdDevice object */
610
	g_variant_get (g_dbus_message_get_body (reply), "(o)",
611
		       &object_path);
612
	profile = cd_profile_new ();
613
	cd_profile_set_object_path (profile, object_path);
614
615
	/* success */
616
	g_simple_async_result_set_op_res_gpointer (res_source,
617
						   profile,
1.2.4 by Christopher James Halse Rogers
Import upstream version 0.1.18
618
						   (GDestroyNotify) g_object_unref);
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
619
out:
620
	if (reply != NULL)
621
		g_object_unref (reply);
622
	g_free (object_path);
623
	g_simple_async_result_complete_in_idle (res_source);
624
	g_object_unref (res_source);
625
}
626
627
/**
628
 * cd_client_create_profile:
629
 * @client: a #CdClient instance.
630
 * @id: identifier for the profile
631
 * @scope: the scope of the profile
632
 * @properties: properties to set on the profile, or %NULL
633
 * @cancellable: a #GCancellable, or %NULL
634
 * @callback: the function to run on completion
635
 * @user_data: the data to pass to @callback
636
 *
637
 * Creates a color profile.
638
 *
639
 * Since: 0.1.8
640
 **/
641
void
642
cd_client_create_profile (CdClient *client,
643
			  const gchar *id,
644
			  CdObjectScope scope,
645
			  GHashTable *properties,
646
			  GCancellable *cancellable,
647
			  GAsyncReadyCallback callback,
648
			  gpointer user_data)
649
{
650
	const gchar *filename;
651
	GDBusConnection *connection;
652
	GDBusMessage *request = NULL;
653
	gint fd = -1;
654
	gint retval;
655
	GList *list, *l;
656
	GUnixFDList *fd_list = NULL;
657
	GVariant *body;
658
	GVariantBuilder builder;
659
	GSimpleAsyncResult *res;
660
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
661
	g_return_if_fail (CD_IS_CLIENT (client));
662
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
663
	g_return_if_fail (id != NULL);
664
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
665
	res = g_simple_async_result_new (G_OBJECT (client),
666
					 callback,
667
					 user_data,
668
					 cd_client_create_profile);
669
670
	/* add properties */
671
	g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
672
	if (properties != NULL &&
673
	    g_hash_table_size (properties) > 0) {
674
		list = g_hash_table_get_keys (properties);
675
		for (l = list; l != NULL; l = l->next) {
676
			g_variant_builder_add (&builder,
677
					       "{ss}",
678
					       l->data,
679
					       g_hash_table_lookup (properties,
680
								    l->data));
681
		}
682
		g_list_free (list);
683
	} else {
684
		/* just fake something here */
685
		g_variant_builder_add (&builder,
686
				       "{ss}",
687
				       CD_PROFILE_PROPERTY_QUALIFIER,
688
				       "");
689
	}
690
691
	/* do low level call */
692
	request = g_dbus_message_new_method_call (COLORD_DBUS_SERVICE,
693
						  COLORD_DBUS_PATH,
694
						  COLORD_DBUS_INTERFACE,
1.2.4 by Christopher James Halse Rogers
Import upstream version 0.1.18
695
						  "CreateProfileWithFd");
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
696
697
	/* get fd if possible top avoid open() in daemon */
698
	if (properties != NULL) {
699
		filename = g_hash_table_lookup (properties,
700
						CD_PROFILE_PROPERTY_FILENAME);
701
		if (filename != NULL) {
702
			fd = open (filename, O_RDONLY);
703
			if (fd < 0) {
704
				g_simple_async_result_set_error (res,
705
								 CD_CLIENT_ERROR,
706
								 CD_CLIENT_ERROR_FAILED,
707
								 "Failed to open %s",
708
								 filename);
709
				g_simple_async_result_complete_in_idle (res);
710
				goto out;
711
			}
712
713
			/* set out of band file descriptor */
714
			fd_list = g_unix_fd_list_new ();
715
			retval = g_unix_fd_list_append (fd_list, fd, NULL);
716
			g_assert (retval != -1);
717
			g_dbus_message_set_unix_fd_list (request, fd_list);
718
719
			/* g_unix_fd_list_append did a dup() already */
720
			close (fd);
721
		}
722
	}
723
724
	/* set parameters */
1.2.4 by Christopher James Halse Rogers
Import upstream version 0.1.18
725
	body = g_variant_new ("(ssha{ss})",
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
726
			      id,
727
			      cd_object_scope_to_string (scope),
1.2.4 by Christopher James Halse Rogers
Import upstream version 0.1.18
728
			      fd > -1 ? 0 : -1,
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
729
			      &builder);
730
	g_dbus_message_set_body (request, body);
731
732
	/* send sync message to the bus */
733
	connection = g_dbus_proxy_get_connection (client->priv->proxy);
734
	g_dbus_connection_send_message_with_reply (connection,
735
						   request,
736
						   G_DBUS_SEND_MESSAGE_FLAGS_NONE,
737
						   CD_CLIENT_MESSAGE_TIMEOUT,
738
						   NULL,
739
						   cancellable,
740
						   cd_client_create_profile_cb,
741
						   res);
742
out:
743
	if (fd_list != NULL)
744
		g_object_unref (fd_list);
745
	if (request != NULL)
746
		g_object_unref (request);
747
}
748
749
/**********************************************************************/
750
751
/**
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
752
 * cd_client_import_get_profile_destination:
753
 **/
754
static GFile *
755
cd_client_import_get_profile_destination (GFile *file)
756
{
757
	gchar *basename;
758
	gchar *destination;
759
	GFile *dest;
760
761
	g_return_val_if_fail (file != NULL, NULL);
762
763
	/* get destination filename for this source file */
764
	basename = g_file_get_basename (file);
765
	destination = g_build_filename (g_get_user_data_dir (), "icc", basename, NULL);
766
	dest = g_file_new_for_path (destination);
767
768
	g_free (basename);
769
	g_free (destination);
770
	return dest;
771
}
772
773
/**
774
 * cd_client_import_mkdir_and_copy:
775
 **/
776
static gboolean
777
cd_client_import_mkdir_and_copy (GFile *source,
778
				 GFile *destination,
779
				 GCancellable *cancellable,
780
				 GError **error)
781
{
782
	gboolean ret;
783
	GFile *parent;
784
785
	g_return_val_if_fail (source != NULL, FALSE);
786
	g_return_val_if_fail (destination != NULL, FALSE);
787
788
	/* get parent */
789
	parent = g_file_get_parent (destination);
790
791
	/* create directory */
792
	if (!g_file_query_exists (parent, cancellable)) {
793
		ret = g_file_make_directory_with_parents (parent, cancellable, error);
794
		if (!ret)
795
			goto out;
796
	}
797
798
	/* do the copy */
799
	ret = g_file_copy (source, destination,
800
			   G_FILE_COPY_OVERWRITE,
801
			   cancellable, NULL, NULL, error);
802
	if (!ret)
803
		goto out;
804
out:
805
	g_object_unref (parent);
806
	return ret;
807
}
808
809
typedef struct {
810
	CdClient		*client;
811
	GCancellable		*cancellable;
812
	GFile			*dest;
813
	GFile			*file;
814
	GSimpleAsyncResult	*res;
815
	guint			 hangcheck_id;
816
	guint			 profile_added_id;
817
} CdClientImportHelper;
818
819
/**
820
 * cd_client_import_profile_finish:
821
 * @client: a #CdClient instance.
822
 * @res: the #GAsyncResult
823
 * @error: A #GError or %NULL
824
 *
825
 * Gets the result from the asynchronous function.
826
 *
827
 * Return value: (transfer full): a #CdProfile or %NULL
828
 *
829
 * Since: 0.1.12
830
 **/
831
CdProfile *
832
cd_client_import_profile_finish (CdClient *client,
833
				 GAsyncResult *res,
834
				 GError **error)
835
{
836
	GSimpleAsyncResult *simple;
837
838
	g_return_val_if_fail (CD_IS_CLIENT (client), NULL);
839
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), NULL);
840
	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
841
842
	simple = G_SIMPLE_ASYNC_RESULT (res);
843
	if (g_simple_async_result_propagate_error (simple, error))
844
		return NULL;
845
846
	return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
847
}
848
849
static void
850
cd_client_import_free_helper (CdClientImportHelper *helper)
851
{
852
	g_object_unref (helper->file);
853
	g_object_unref (helper->dest);
854
	if (helper->cancellable != NULL)
855
		g_object_unref (helper->cancellable);
856
	if (helper->profile_added_id > 0)
857
		g_signal_handler_disconnect (helper->client, helper->profile_added_id);
858
	if (helper->hangcheck_id > 0)
859
		g_source_remove (helper->hangcheck_id);
860
	g_object_unref (helper->client);
861
	g_object_unref (helper->res);
862
	g_free (helper);
863
}
864
865
static void
866
cd_client_import_profile_added_cb (CdClient *client,
867
				   CdProfile *profile,
868
				   gpointer user_data)
869
{
870
	CdClientImportHelper *helper = (CdClientImportHelper *) user_data;
871
872
	/* success */
873
	g_simple_async_result_set_op_res_gpointer (helper->res,
874
						   g_object_ref (profile),
875
						   (GDestroyNotify) g_object_unref);
876
	g_simple_async_result_complete_in_idle (helper->res);
877
	cd_client_import_free_helper (helper);
878
}
879
880
static gboolean
881
cd_client_import_hangcheck_cb (gpointer user_data)
882
{
883
	CdClientImportHelper *helper = (CdClientImportHelper *) user_data;
884
	g_simple_async_result_set_error (helper->res,
885
					 CD_CLIENT_ERROR,
886
					 CD_CLIENT_ERROR_FAILED,
887
					 "The profile was not added in time");
888
	g_simple_async_result_complete_in_idle (helper->res);
889
	helper->hangcheck_id = 0;
890
	cd_client_import_free_helper (helper);
891
	return FALSE;
892
}
893
894
static void
895
cd_client_import_profile_find_filename_cb (GObject *source_object,
896
					   GAsyncResult *res,
897
					   gpointer user_data)
898
{
899
	CdProfile *profile;
900
	gboolean ret;
901
	gchar *filename = NULL;
902
	GError *error = NULL;
903
	CdClientImportHelper *helper = (CdClientImportHelper *) user_data;
904
905
	/* does the profile already exist */
906
	profile = cd_client_find_profile_by_filename_finish (CD_CLIENT (source_object),
907
							     res,
908
							     &error);
909
	if (profile != NULL) {
910
		filename = g_file_get_path (helper->dest);
911
		g_simple_async_result_set_error (helper->res,
912
						 CD_CLIENT_ERROR,
913
						 CD_CLIENT_ERROR_ALREADY_EXISTS,
914
						 "The profile %s already exists",
915
						 filename);
916
		g_simple_async_result_complete_in_idle (helper->res);
917
		cd_client_import_free_helper (helper);
918
		goto out;
919
	}
920
	if (error->domain != CD_CLIENT_ERROR ||
921
	    error->code != CD_CLIENT_ERROR_FAILED) {
922
		g_simple_async_result_set_error (helper->res,
923
						 CD_CLIENT_ERROR,
924
						 CD_CLIENT_ERROR_FAILED,
925
						 "Failed to import: %s",
926
						 error->message);
927
		g_simple_async_result_complete_in_idle (helper->res);
928
		cd_client_import_free_helper (helper);
929
		g_error_free (error);
930
		goto out;
931
	}
932
933
	/* reset the error */
934
	g_clear_error (&error);
935
936
	/* watch for a new profile to be detected and added,
937
	 * but time out after a couple of seconds */
938
	helper->hangcheck_id = g_timeout_add (CD_CLIENT_IMPORT_DAEMON_TIMEOUT,
939
					      cd_client_import_hangcheck_cb,
940
					      helper);
941
	helper->profile_added_id = g_signal_connect (helper->client, "profile-added",
942
						     G_CALLBACK (cd_client_import_profile_added_cb),
943
						     helper);
944
945
	/* copy profile to the correct place */
946
	ret = cd_client_import_mkdir_and_copy (helper->file,
947
					       helper->dest,
948
					       helper->cancellable,
949
					       &error);
950
	if (!ret) {
951
		g_simple_async_result_set_error (helper->res,
952
						 CD_CLIENT_ERROR,
953
						 CD_CLIENT_ERROR_FAILED,
954
						 "Failed to copy: %s",
955
						 error->message);
956
		g_error_free (error);
957
		g_simple_async_result_complete_in_idle (helper->res);
958
		cd_client_import_free_helper (helper);
959
		goto out;
960
	}
961
out:
962
	g_free (filename);
963
	if (profile != NULL)
964
		g_object_unref (profile);
965
}
966
967
static void
968
cd_client_import_profile_query_info_cb (GObject *source_object,
969
					GAsyncResult *res,
970
					gpointer user_data)
971
{
972
	const gchar *type;
973
	gchar *filename = NULL;
974
	GError *error = NULL;
975
	GFileInfo *info;
976
	CdClientImportHelper *helper = (CdClientImportHelper *) user_data;
977
978
	/* get the file info */
979
	filename = g_file_get_path (helper->dest);
980
	info = g_file_query_info_finish (G_FILE (source_object),
981
					 res,
982
					 &error);
983
	if (info == NULL) {
984
		g_simple_async_result_set_error (helper->res,
985
						 CD_CLIENT_ERROR,
986
						 CD_CLIENT_ERROR_FAILED,
987
						 "Cannot get content type for %s: %s",
988
						 filename,
989
						 error->message);
990
		g_error_free (error);
991
		g_simple_async_result_complete_in_idle (helper->res);
992
		cd_client_import_free_helper (helper);
993
		goto out;
994
	}
995
996
	/* check the content type */
997
	type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
998
	if (g_strcmp0 (type, "application/vnd.iccprofile") != 0) {
999
		g_simple_async_result_set_error (helper->res,
1000
						 CD_CLIENT_ERROR,
1001
						 CD_CLIENT_ERROR_FILE_INVALID,
1002
						 "Incorrect content type for %s, got %s",
1003
						 filename, type);
1004
		g_simple_async_result_complete_in_idle (helper->res);
1005
		cd_client_import_free_helper (helper);
1006
		goto out;
1007
	}
1008
1009
	/* does this profile already exist? */
1010
	cd_client_find_profile_by_filename (helper->client,
1011
					    filename,
1012
					    helper->cancellable,
1013
					    cd_client_import_profile_find_filename_cb,
1014
					    helper);
1015
out:
1016
	if (info != NULL)
1017
		g_object_unref (info);
1018
	g_free (filename);
1019
}
1020
1021
/**
1022
 * cd_client_import_profile:
1023
 * @client: a #CdClient instance.
1024
 * @file: a #GFile
1025
 * @cancellable: a #GCancellable, or %NULL
1026
 * @callback: the function to run on completion
1027
 * @user_data: the data to pass to @callback
1028
 *
1029
 * Imports a color profile into the users home directory.
1030
 *
1031
 * If the profile should be accessable for all users, then call
1032
 * cd_profile_install_system_wide() on the result.
1033
 *
1034
 * Since: 0.1.12
1035
 **/
1036
void
1037
cd_client_import_profile (CdClient *client,
1038
			  GFile *file,
1039
			  GCancellable *cancellable,
1040
			  GAsyncReadyCallback callback,
1041
			  gpointer user_data)
1042
{
1043
	CdClientImportHelper *helper;
1044
1045
	g_return_if_fail (CD_IS_CLIENT (client));
1046
	g_return_if_fail (G_IS_FILE (file));
1047
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1048
1049
	helper = g_new0 (CdClientImportHelper, 1);
1050
	helper->client = g_object_ref (client);
1051
	helper->res = g_simple_async_result_new (G_OBJECT (client),
1052
						 callback,
1053
						 user_data,
1054
						 cd_client_import_profile);
1055
	helper->file = g_object_ref (file);
1056
	helper->dest = cd_client_import_get_profile_destination (file);
1057
	if (cancellable != NULL)
1058
		helper->cancellable = g_object_ref (cancellable);
1059
1060
	/* check the file really is an ICC file */
1061
	g_file_query_info_async (helper->file,
1062
				 G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
1063
				 G_FILE_QUERY_INFO_NONE,
1064
				 G_PRIORITY_DEFAULT,
1065
				 helper->cancellable,
1066
				 cd_client_import_profile_query_info_cb,
1067
				 helper);
1068
}
1069
1070
/**********************************************************************/
1071
1072
/**
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
1073
 * cd_client_delete_device_finish:
1074
 * @client: a #CdClient instance.
1075
 * @res: the #GAsyncResult
1076
 * @error: A #GError or %NULL
1077
 *
1078
 * Gets the result from the asynchronous function.
1079
 *
1080
 * Return value: success
1081
 *
1082
 * Since: 0.1.8
1083
 **/
1084
gboolean
1085
cd_client_delete_device_finish (CdClient *client,
1086
				GAsyncResult *res,
1087
				GError **error)
1088
{
1089
	GSimpleAsyncResult *simple;
1090
1091
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
1092
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1093
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1094
1095
	simple = G_SIMPLE_ASYNC_RESULT (res);
1096
	if (g_simple_async_result_propagate_error (simple, error))
1097
		return FALSE;
1098
1099
	return g_simple_async_result_get_op_res_gboolean (simple);
1100
}
1101
1102
static void
1103
cd_client_delete_device_cb (GObject *source_object,
1104
			    GAsyncResult *res,
1105
			    gpointer user_data)
1106
{
1107
	GError *error = NULL;
1108
	GVariant *result;
1109
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
1110
1111
	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
1112
					   res,
1113
					   &error);
1114
	if (result == NULL) {
1115
		g_simple_async_result_set_error (res_source,
1116
						 CD_CLIENT_ERROR,
1117
						 CD_CLIENT_ERROR_FAILED,
1118
						 "Failed to DeleteDevice: %s",
1119
						 error->message);
1120
		g_error_free (error);
1121
		goto out;
1122
	}
1123
1124
	/* success */
1125
	g_simple_async_result_set_op_res_gboolean (res_source, TRUE);
1126
	g_variant_unref (result);
1127
out:
1128
	g_simple_async_result_complete_in_idle (res_source);
1129
	g_object_unref (res_source);
1130
}
1131
1132
/**
1133
 * cd_client_delete_device:
1134
 * @client: a #CdClient instance.
1135
 * @device: a #CdDevice
1136
 * @cancellable: a #GCancellable, or %NULL
1137
 * @callback: the function to run on completion
1138
 * @user_data: the data to pass to @callback
1139
 *
1140
 * Deletes a device.
1141
 *
1142
 * Since: 0.1.8
1143
 **/
1144
void
1145
cd_client_delete_device (CdClient *client,
1146
			 CdDevice *device,
1147
			 GCancellable *cancellable,
1148
			 GAsyncReadyCallback callback,
1149
			 gpointer user_data)
1150
{
1151
	GSimpleAsyncResult *res;
1152
1153
	g_return_if_fail (CD_IS_CLIENT (client));
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
1154
	g_return_if_fail (CD_IS_DEVICE (device));
1155
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
1156
	g_return_if_fail (client->priv->proxy != NULL);
1157
1158
	res = g_simple_async_result_new (G_OBJECT (client),
1159
					 callback,
1160
					 user_data,
1161
					 cd_client_delete_device);
1162
	g_dbus_proxy_call (client->priv->proxy,
1163
			   "DeleteDevice",
1164
			   g_variant_new ("(o)",
1165
			   		  cd_device_get_object_path (device)),
1166
			   G_DBUS_CALL_FLAGS_NONE,
1167
			   -1,
1168
			   cancellable,
1169
			   cd_client_delete_device_cb,
1170
			   res);
1171
}
1172
1173
/**********************************************************************/
1174
1175
/**
1176
 * cd_client_delete_profile_finish:
1177
 * @client: a #CdClient instance.
1178
 * @res: the #GAsyncResult
1179
 * @error: A #GError or %NULL
1180
 *
1181
 * Gets the result from the asynchronous function.
1182
 *
1183
 * Return value: success
1184
 *
1185
 * Since: 0.1.8
1186
 **/
1187
gboolean
1188
cd_client_delete_profile_finish (CdClient *client,
1189
				 GAsyncResult *res,
1190
				 GError **error)
1191
{
1192
	GSimpleAsyncResult *simple;
1193
1194
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
1195
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1196
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1197
1198
	simple = G_SIMPLE_ASYNC_RESULT (res);
1199
	if (g_simple_async_result_propagate_error (simple, error))
1200
		return FALSE;
1201
1202
	return g_simple_async_result_get_op_res_gboolean (simple);
1203
}
1204
1205
static void
1206
cd_client_delete_profile_cb (GObject *source_object,
1207
			    GAsyncResult *res,
1208
			    gpointer user_data)
1209
{
1210
	GError *error = NULL;
1211
	GVariant *result;
1212
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
1213
1214
	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
1215
					   res,
1216
					   &error);
1217
	if (result == NULL) {
1218
		g_simple_async_result_set_error (res_source,
1219
						 CD_CLIENT_ERROR,
1220
						 CD_CLIENT_ERROR_FAILED,
1221
						 "Failed to DeleteProfile: %s",
1222
						 error->message);
1223
		g_error_free (error);
1224
		goto out;
1225
	}
1226
1227
	/* success */
1228
	g_simple_async_result_set_op_res_gboolean (res_source, TRUE);
1229
	g_variant_unref (result);
1230
out:
1231
	g_simple_async_result_complete_in_idle (res_source);
1232
	g_object_unref (res_source);
1233
}
1234
1235
/**
1236
 * cd_client_delete_profile:
1237
 * @client: a #CdClient instance.
1238
 * @profile: a #CdProfile
1239
 * @cancellable: a #GCancellable, or %NULL
1240
 * @callback: the function to run on completion
1241
 * @user_data: the data to pass to @callback
1242
 *
1243
 * Deletes a profile.
1244
 *
1245
 * Since: 0.1.8
1246
 **/
1247
void
1248
cd_client_delete_profile (CdClient *client,
1249
			  CdProfile *profile,
1250
			  GCancellable *cancellable,
1251
			  GAsyncReadyCallback callback,
1252
			  gpointer user_data)
1253
{
1254
	GSimpleAsyncResult *res;
1255
1256
	g_return_if_fail (CD_IS_CLIENT (client));
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
1257
	g_return_if_fail (CD_IS_PROFILE (profile));
1258
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
1259
	g_return_if_fail (client->priv->proxy != NULL);
1260
1261
	res = g_simple_async_result_new (G_OBJECT (client),
1262
					 callback,
1263
					 user_data,
1264
					 cd_client_delete_profile);
1265
	g_dbus_proxy_call (client->priv->proxy,
1266
			   "DeleteProfile",
1267
			   g_variant_new ("(o)",
1268
			   		  cd_profile_get_object_path (profile)),
1269
			   G_DBUS_CALL_FLAGS_NONE,
1270
			   -1,
1271
			   cancellable,
1272
			   cd_client_delete_profile_cb,
1273
			   res);
1274
}
1275
1276
/**********************************************************************/
1277
1278
/**
1279
 * cd_client_find_device_finish:
1280
 * @client: a #CdClient instance.
1281
 * @res: the #GAsyncResult
1282
 * @error: A #GError or %NULL
1283
 *
1284
 * Gets the result from the asynchronous function.
1285
 *
1286
 * Return value: (transfer full): a #CdDevice or %NULL
1287
 *
1288
 * Since: 0.1.8
1289
 **/
1290
CdDevice *
1291
cd_client_find_device_finish (CdClient *client,
1292
			      GAsyncResult *res,
1293
			      GError **error)
1294
{
1295
	GSimpleAsyncResult *simple;
1296
1297
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
1298
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1299
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1300
1301
	simple = G_SIMPLE_ASYNC_RESULT (res);
1302
	if (g_simple_async_result_propagate_error (simple, error))
1303
		return FALSE;
1304
1305
	return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1306
}
1307
1308
static void
1309
cd_client_find_device_cb (GObject *source_object,
1310
			    GAsyncResult *res,
1311
			    gpointer user_data)
1312
{
1313
	GError *error = NULL;
1314
	GVariant *result;
1315
	CdDevice *device;
1316
	gchar *object_path = NULL;
1317
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
1318
1319
	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
1320
					   res,
1321
					   &error);
1322
	if (result == NULL) {
1323
		g_simple_async_result_set_error (res_source,
1324
						 CD_CLIENT_ERROR,
1325
						 CD_CLIENT_ERROR_FAILED,
1326
						 "Failed to FindDeviceById: %s",
1327
						 error->message);
1328
		g_error_free (error);
1329
		goto out;
1330
	}
1331
1332
	/* create a device object */
1333
	g_variant_get (result, "(o)",
1334
		       &object_path);
1335
	device = cd_device_new ();
1336
	cd_device_set_object_path (device, object_path);
1337
1338
	/* success */
1339
	g_simple_async_result_set_op_res_gpointer (res_source,
1340
						   device,
1341
						   (GDestroyNotify) g_object_unref);
1342
	g_variant_unref (result);
1343
out:
1344
	g_free (object_path);
1345
	g_simple_async_result_complete_in_idle (res_source);
1346
	g_object_unref (res_source);
1347
}
1348
1349
/**
1350
 * cd_client_find_device:
1351
 * @client: a #CdClient instance.
1352
 * @id: a device id
1353
 * @cancellable: a #GCancellable, or %NULL
1354
 * @callback: the function to run on completion
1355
 * @user_data: the data to pass to @callback
1356
 *
1357
 * Finds a device by an ID.
1358
 *
1359
 * Since: 0.1.8
1360
 **/
1361
void
1362
cd_client_find_device (CdClient *client,
1363
		       const gchar *id,
1364
		       GCancellable *cancellable,
1365
		       GAsyncReadyCallback callback,
1366
		       gpointer user_data)
1367
{
1368
	GSimpleAsyncResult *res;
1369
1370
	g_return_if_fail (CD_IS_CLIENT (client));
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
1371
	g_return_if_fail (id != NULL);
1372
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
1373
	g_return_if_fail (client->priv->proxy != NULL);
1374
1375
	res = g_simple_async_result_new (G_OBJECT (client),
1376
					 callback,
1377
					 user_data,
1378
					 cd_client_find_device);
1379
	g_dbus_proxy_call (client->priv->proxy,
1380
			   "FindDeviceById",
1381
			   g_variant_new ("(s)", id),
1382
			   G_DBUS_CALL_FLAGS_NONE,
1383
			   -1,
1384
			   cancellable,
1385
			   cd_client_find_device_cb,
1386
			   res);
1387
}
1388
1389
/**********************************************************************/
1390
1391
/**
1392
 * cd_client_find_device_by_property_finish:
1393
 * @client: a #CdClient instance.
1394
 * @res: the #GAsyncResult
1395
 * @error: A #GError or %NULL
1396
 *
1397
 * Gets the result from the asynchronous function.
1398
 *
1399
 * Return value: (transfer full): a #CdDevice or %NULL
1400
 *
1401
 * Since: 0.1.8
1402
 **/
1403
CdDevice *
1404
cd_client_find_device_by_property_finish (CdClient *client,
1405
					  GAsyncResult *res,
1406
					  GError **error)
1407
{
1408
	GSimpleAsyncResult *simple;
1409
1410
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
1411
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1412
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1413
1414
	simple = G_SIMPLE_ASYNC_RESULT (res);
1415
	if (g_simple_async_result_propagate_error (simple, error))
1416
		return FALSE;
1417
1418
	return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1419
}
1420
1421
static void
1422
cd_client_find_device_by_property_cb (GObject *source_object,
1423
				      GAsyncResult *res,
1424
				      gpointer user_data)
1425
{
1426
	GError *error = NULL;
1427
	GVariant *result;
1428
	CdDevice *device;
1429
	gchar *object_path = NULL;
1430
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
1431
1432
	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
1433
					   res,
1434
					   &error);
1435
	if (result == NULL) {
1436
		g_simple_async_result_set_error (res_source,
1437
						 CD_CLIENT_ERROR,
1438
						 CD_CLIENT_ERROR_FAILED,
1439
						 "Failed to FindDeviceByProperty: %s",
1440
						 error->message);
1441
		g_error_free (error);
1442
		goto out;
1443
	}
1444
1445
	/* create a device object */
1446
	g_variant_get (result, "(o)",
1447
		       &object_path);
1448
	device = cd_device_new ();
1449
	cd_device_set_object_path (device, object_path);
1450
1451
	/* success */
1452
	g_simple_async_result_set_op_res_gpointer (res_source,
1453
						   device,
1454
						   (GDestroyNotify) g_object_unref);
1455
	g_variant_unref (result);
1456
out:
1457
	g_free (object_path);
1458
	g_simple_async_result_complete_in_idle (res_source);
1459
	g_object_unref (res_source);
1460
}
1461
1462
/**
1463
 * cd_client_find_device_by_property:
1464
 * @client: a #CdClient instance.
1465
 * @key: the device property key
1466
 * @value: the device property value
1467
 * @cancellable: a #GCancellable, or %NULL
1468
 * @callback: the function to run on completion
1469
 * @user_data: the data to pass to @callback
1470
 *
1471
 * Finds a color device that has a property value.
1472
 *
1473
 * Since: 0.1.8
1474
 **/
1475
void
1476
cd_client_find_device_by_property (CdClient *client,
1477
				   const gchar *key,
1478
				   const gchar *value,
1479
				   GCancellable *cancellable,
1480
				   GAsyncReadyCallback callback,
1481
				   gpointer user_data)
1482
{
1483
	GSimpleAsyncResult *res;
1484
1485
	g_return_if_fail (CD_IS_CLIENT (client));
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
1486
	g_return_if_fail (key != NULL);
1487
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
1488
	g_return_if_fail (client->priv->proxy != NULL);
1489
1490
	res = g_simple_async_result_new (G_OBJECT (client),
1491
					 callback,
1492
					 user_data,
1493
					 cd_client_find_device_by_property);
1494
	g_dbus_proxy_call (client->priv->proxy,
1495
			   "FindDeviceByProperty",
1496
			   g_variant_new ("(ss)", key, value),
1497
			   G_DBUS_CALL_FLAGS_NONE,
1498
			   -1,
1499
			   cancellable,
1500
			   cd_client_find_device_by_property_cb,
1501
			   res);
1502
}
1503
1504
/**********************************************************************/
1505
1506
/**
1507
 * cd_client_find_profile_finish:
1508
 * @client: a #CdClient instance.
1509
 * @res: the #GAsyncResult
1510
 * @error: A #GError or %NULL
1511
 *
1512
 * Gets the result from the asynchronous function.
1513
 *
1514
 * Return value: (transfer full): a #CdProfile or %NULL
1515
 *
1516
 * Since: 0.1.8
1517
 **/
1518
CdProfile *
1519
cd_client_find_profile_finish (CdClient *client,
1520
			       GAsyncResult *res,
1521
			       GError **error)
1522
{
1523
	GSimpleAsyncResult *simple;
1524
1525
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
1526
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1527
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1528
1529
	simple = G_SIMPLE_ASYNC_RESULT (res);
1530
	if (g_simple_async_result_propagate_error (simple, error))
1531
		return FALSE;
1532
1533
	return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1534
}
1535
1536
static void
1537
cd_client_find_profile_cb (GObject *source_object,
1538
			   GAsyncResult *res,
1539
			   gpointer user_data)
1540
{
1541
	GError *error = NULL;
1542
	GVariant *result;
1543
	CdProfile *profile;
1544
	gchar *object_path = NULL;
1545
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
1546
1547
	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
1548
					   res,
1549
					   &error);
1550
	if (result == NULL) {
1551
		g_simple_async_result_set_error (res_source,
1552
						 CD_CLIENT_ERROR,
1553
						 CD_CLIENT_ERROR_FAILED,
1554
						 "Failed to FindProfileById: %s",
1555
						 error->message);
1556
		g_error_free (error);
1557
		goto out;
1558
	}
1559
1560
	/* create a profile object */
1561
	g_variant_get (result, "(o)",
1562
		       &object_path);
1563
	profile = cd_profile_new ();
1564
	cd_profile_set_object_path (profile, object_path);
1565
1566
	/* success */
1567
	g_simple_async_result_set_op_res_gpointer (res_source,
1568
						   profile,
1569
						   (GDestroyNotify) g_object_unref);
1570
	g_variant_unref (result);
1571
out:
1572
	g_free (object_path);
1573
	g_simple_async_result_complete_in_idle (res_source);
1574
	g_object_unref (res_source);
1575
}
1576
1577
/**
1578
 * cd_client_find_profile:
1579
 * @client: a #CdClient instance.
1580
 * @id: a profile id
1581
 * @cancellable: a #GCancellable, or %NULL
1582
 * @callback: the function to run on completion
1583
 * @user_data: the data to pass to @callback
1584
 *
1585
 * Finds a profile by an ID.
1586
 *
1587
 * Since: 0.1.8
1588
 **/
1589
void
1590
cd_client_find_profile (CdClient *client,
1591
			const gchar *id,
1592
			GCancellable *cancellable,
1593
			GAsyncReadyCallback callback,
1594
			gpointer user_data)
1595
{
1596
	GSimpleAsyncResult *res;
1597
1598
	g_return_if_fail (CD_IS_CLIENT (client));
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
1599
	g_return_if_fail (id != NULL);
1600
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
1601
	g_return_if_fail (client->priv->proxy != NULL);
1602
1603
	res = g_simple_async_result_new (G_OBJECT (client),
1604
					 callback,
1605
					 user_data,
1606
					 cd_client_find_profile);
1607
	g_dbus_proxy_call (client->priv->proxy,
1608
			   "FindProfileById",
1609
			   g_variant_new ("(s)", id),
1610
			   G_DBUS_CALL_FLAGS_NONE,
1611
			   -1,
1612
			   cancellable,
1613
			   cd_client_find_profile_cb,
1614
			   res);
1615
}
1616
1617
/**********************************************************************/
1618
1619
/**
1620
 * cd_client_find_profile_by_filename_finish:
1621
 * @client: a #CdClient instance.
1622
 * @res: the #GAsyncResult
1623
 * @error: A #GError or %NULL
1624
 *
1625
 * Gets the result from the asynchronous function.
1626
 *
1627
 * Return value: (transfer full): a #CdProfile or %NULL
1628
 *
1629
 * Since: 0.1.8
1630
 **/
1631
CdProfile *
1632
cd_client_find_profile_by_filename_finish (CdClient *client,
1633
					   GAsyncResult *res,
1634
					   GError **error)
1635
{
1636
	GSimpleAsyncResult *simple;
1637
1638
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
1639
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1640
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1641
1642
	simple = G_SIMPLE_ASYNC_RESULT (res);
1643
	if (g_simple_async_result_propagate_error (simple, error))
1644
		return FALSE;
1645
1646
	return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1647
}
1648
1649
static void
1650
cd_client_find_profile_by_filename_cb (GObject *source_object,
1651
				       GAsyncResult *res,
1652
				       gpointer user_data)
1653
{
1654
	GError *error = NULL;
1655
	GVariant *result;
1656
	CdProfile *profile;
1657
	gchar *object_path = NULL;
1658
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
1659
1660
	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
1661
					   res,
1662
					   &error);
1663
	if (result == NULL) {
1664
		g_simple_async_result_set_error (res_source,
1665
						 CD_CLIENT_ERROR,
1666
						 CD_CLIENT_ERROR_FAILED,
1667
						 "Failed to FindProfileByFilename: %s",
1668
						 error->message);
1669
		g_error_free (error);
1670
		goto out;
1671
	}
1672
1673
	/* create a profile object */
1674
	g_variant_get (result, "(o)",
1675
		       &object_path);
1676
	profile = cd_profile_new ();
1677
	cd_profile_set_object_path (profile, object_path);
1678
1679
	/* success */
1680
	g_simple_async_result_set_op_res_gpointer (res_source,
1681
						   profile,
1682
						   (GDestroyNotify) g_object_unref);
1683
	g_variant_unref (result);
1684
out:
1685
	g_free (object_path);
1686
	g_simple_async_result_complete_in_idle (res_source);
1687
	g_object_unref (res_source);
1688
}
1689
1690
/**
1691
 * cd_client_find_profile_by_filename:
1692
 * @client: a #CdClient instance.
1693
 * @filename: a #profile filename
1694
 * @cancellable: a #GCancellable, or %NULL
1695
 * @callback: the function to run on completion
1696
 * @user_data: the data to pass to @callback
1697
 *
1698
 * Finds a profile by a filename.
1699
 *
1700
 * Since: 0.1.8
1701
 **/
1702
void
1703
cd_client_find_profile_by_filename (CdClient *client,
1704
				    const gchar *filename,
1705
				    GCancellable *cancellable,
1706
				    GAsyncReadyCallback callback,
1707
				    gpointer user_data)
1708
{
1709
	GSimpleAsyncResult *res;
1710
1711
	g_return_if_fail (CD_IS_CLIENT (client));
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
1712
	g_return_if_fail (filename != NULL);
1713
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
1714
	g_return_if_fail (client->priv->proxy != NULL);
1715
1716
	res = g_simple_async_result_new (G_OBJECT (client),
1717
					 callback,
1718
					 user_data,
1719
					 cd_client_find_profile_by_filename);
1720
	g_dbus_proxy_call (client->priv->proxy,
1721
			   "FindProfileByFilename",
1722
			   g_variant_new ("(s)", filename),
1723
			   G_DBUS_CALL_FLAGS_NONE,
1724
			   -1,
1725
			   cancellable,
1726
			   cd_client_find_profile_by_filename_cb,
1727
			   res);
1728
}
1729
1730
/**********************************************************************/
1731
1732
/**
1733
 * cd_client_get_standard_space_finish:
1734
 * @client: a #CdClient instance.
1735
 * @res: the #GAsyncResult
1736
 * @error: A #GError or %NULL
1737
 *
1738
 * Gets the result from the asynchronous function.
1739
 *
1740
 * Return value: (transfer full): a #CdProfile or %NULL
1741
 *
1742
 * Since: 0.1.8
1743
 **/
1744
CdProfile *
1745
cd_client_get_standard_space_finish (CdClient *client,
1746
				     GAsyncResult *res,
1747
				     GError **error)
1748
{
1749
	GSimpleAsyncResult *simple;
1750
1751
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
1752
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1753
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1754
1755
	simple = G_SIMPLE_ASYNC_RESULT (res);
1756
	if (g_simple_async_result_propagate_error (simple, error))
1757
		return FALSE;
1758
1759
	return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1760
}
1761
1762
static void
1763
cd_client_get_standard_space_cb (GObject *source_object,
1764
				 GAsyncResult *res,
1765
				 gpointer user_data)
1766
{
1767
	GError *error = NULL;
1768
	GVariant *result;
1769
	CdProfile *profile;
1770
	gchar *object_path = NULL;
1771
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
1772
1773
	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
1774
					   res,
1775
					   &error);
1776
	if (result == NULL) {
1777
		g_simple_async_result_set_error (res_source,
1778
						 CD_CLIENT_ERROR,
1779
						 CD_CLIENT_ERROR_FAILED,
1780
						 "Failed to FindProfileById: %s",
1781
						 error->message);
1782
		g_error_free (error);
1783
		goto out;
1784
	}
1785
1786
	/* create a profile object */
1787
	g_variant_get (result, "(o)",
1788
		       &object_path);
1789
	profile = cd_profile_new ();
1790
	cd_profile_set_object_path (profile, object_path);
1791
1792
	/* success */
1793
	g_simple_async_result_set_op_res_gpointer (res_source,
1794
						   profile,
1795
						   (GDestroyNotify) g_object_unref);
1796
	g_variant_unref (result);
1797
out:
1798
	g_free (object_path);
1799
	g_simple_async_result_complete_in_idle (res_source);
1800
	g_object_unref (res_source);
1801
}
1802
1803
/**
1804
 * cd_client_get_standard_space:
1805
 * @client: a #CdStandardSpace instance.
1806
 * @standard_space: a #profile id
1807
 * @cancellable: a #GCancellable, or %NULL
1808
 * @callback: the function to run on completion
1809
 * @user_data: the data to pass to @callback
1810
 *
1811
 * Finds a standard profile space.
1812
 *
1813
 * Since: 0.1.8
1814
 **/
1815
void
1816
cd_client_get_standard_space (CdClient *client,
1817
			      CdStandardSpace standard_space,
1818
			      GCancellable *cancellable,
1819
			      GAsyncReadyCallback callback,
1820
			      gpointer user_data)
1821
{
1822
	GSimpleAsyncResult *res;
1823
1824
	g_return_if_fail (CD_IS_CLIENT (client));
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
1825
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
1826
	g_return_if_fail (client->priv->proxy != NULL);
1827
1828
	res = g_simple_async_result_new (G_OBJECT (client),
1829
					 callback,
1830
					 user_data,
1831
					 cd_client_get_standard_space);
1832
	g_dbus_proxy_call (client->priv->proxy,
1833
			   "GetStandardSpace",
1834
			   g_variant_new ("(s)",
1835
			   		  cd_standard_space_to_string (standard_space)),
1836
			   G_DBUS_CALL_FLAGS_NONE,
1837
			   -1,
1838
			   cancellable,
1839
			   cd_client_get_standard_space_cb,
1840
			   res);
1841
}
1842
1843
/**********************************************************************/
1844
1845
/**
1846
 * cd_client_get_device_array_from_variant:
1847
 **/
1848
static GPtrArray *
1849
cd_client_get_device_array_from_variant (CdClient *client,
1850
					 GVariant *result)
1851
{
1852
	CdDevice *device;
1853
	gchar *object_path_tmp;
1854
	GPtrArray *array = NULL;
1855
	guint i;
1856
	guint len;
1857
	GVariant *child = NULL;
1858
	GVariantIter iter;
1859
1860
	/* add each device */
1861
	array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
1862
	child = g_variant_get_child_value (result, 0);
1863
	len = g_variant_iter_init (&iter, child);
1864
	for (i=0; i < len; i++) {
1865
		g_variant_get_child (child, i,
1866
				     "o", &object_path_tmp);
1867
		device = cd_device_new_with_object_path (object_path_tmp);
1868
		g_ptr_array_add (array, device);
1869
		g_free (object_path_tmp);
1870
	}
1871
	g_variant_unref (child);
1872
	return array;
1873
}
1874
1875
/**
1876
 * cd_client_get_devices_finish:
1877
 * @client: a #CdClient instance.
1878
 * @res: the #GAsyncResult
1879
 * @error: A #GError or %NULL
1880
 *
1881
 * Gets the result from the asynchronous function.
1882
 *
1883
 * Return value: (element-type CdDevice) (transfer full): the devices
1884
 *
1885
 * Since: 0.1.8
1886
 **/
1887
GPtrArray *
1888
cd_client_get_devices_finish (CdClient *client,
1889
			      GAsyncResult *res,
1890
			      GError **error)
1891
{
1892
	GSimpleAsyncResult *simple;
1893
1894
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
1895
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
1896
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
1897
1898
	simple = G_SIMPLE_ASYNC_RESULT (res);
1899
	if (g_simple_async_result_propagate_error (simple, error))
1900
		return FALSE;
1901
1902
	return g_ptr_array_ref (g_simple_async_result_get_op_res_gpointer (simple));
1903
}
1904
1905
static void
1906
cd_client_get_devices_cb (GObject *source_object,
1907
			  GAsyncResult *res,
1908
			  gpointer user_data)
1909
{
1910
	GError *error = NULL;
1911
	GVariant *result;
1912
	GPtrArray *array;
1913
	gchar *object_path = NULL;
1914
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
1915
	CdClient *client = CD_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (res_source)));
1916
1917
	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
1918
					   res,
1919
					   &error);
1920
	if (result == NULL) {
1921
		g_simple_async_result_set_error (res_source,
1922
						 CD_CLIENT_ERROR,
1923
						 CD_CLIENT_ERROR_FAILED,
1924
						 "Failed to GetDevices: %s",
1925
						 error->message);
1926
		g_error_free (error);
1927
		goto out;
1928
	}
1929
1930
	/* create a profile object */
1931
	array = cd_client_get_device_array_from_variant (client, result);
1932
1933
	/* success */
1934
	g_simple_async_result_set_op_res_gpointer (res_source,
1935
						   array,
1936
						   (GDestroyNotify) g_ptr_array_unref);
1937
	g_variant_unref (result);
1938
out:
1939
	g_free (object_path);
1940
	g_simple_async_result_complete_in_idle (res_source);
1941
	g_object_unref (res_source);
1942
}
1943
1944
/**
1945
 * cd_client_get_devices:
1946
 * @client: a #CdClient instance.
1947
 * @cancellable: a #GCancellable, or %NULL
1948
 * @callback: the function to run on completion
1949
 * @user_data: the data to pass to @callback
1950
 *
1951
 * Gets an array of color devices.
1952
 *
1953
 * Since: 0.1.8
1954
 **/
1955
void
1956
cd_client_get_devices (CdClient *client,
1957
		       GCancellable *cancellable,
1958
		       GAsyncReadyCallback callback,
1959
		       gpointer user_data)
1960
{
1961
	GSimpleAsyncResult *res;
1962
1963
	g_return_if_fail (CD_IS_CLIENT (client));
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
1964
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
1965
	g_return_if_fail (client->priv->proxy != NULL);
1966
1967
	res = g_simple_async_result_new (G_OBJECT (client),
1968
					 callback,
1969
					 user_data,
1970
					 cd_client_get_devices);
1971
	g_dbus_proxy_call (client->priv->proxy,
1972
			   "GetDevices",
1973
			   NULL,
1974
			   G_DBUS_CALL_FLAGS_NONE,
1975
			   -1,
1976
			   cancellable,
1977
			   cd_client_get_devices_cb,
1978
			   res);
1979
}
1980
1981
/**********************************************************************/
1982
1983
/**
1984
 * cd_client_get_devices_by_kind_finish:
1985
 * @client: a #CdClient instance.
1986
 * @res: the #GAsyncResult
1987
 * @error: A #GError or %NULL
1988
 *
1989
 * Gets the result from the asynchronous function.
1990
 *
1991
 * Return value: (element-type CdDevice) (transfer full): the devices
1992
 *
1993
 * Since: 0.1.8
1994
 **/
1995
GPtrArray *
1996
cd_client_get_devices_by_kind_finish (CdClient *client,
1997
				      GAsyncResult *res,
1998
				      GError **error)
1999
{
2000
	GSimpleAsyncResult *simple;
2001
2002
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
2003
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
2004
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2005
2006
	simple = G_SIMPLE_ASYNC_RESULT (res);
2007
	if (g_simple_async_result_propagate_error (simple, error))
2008
		return FALSE;
2009
2010
	return g_ptr_array_ref (g_simple_async_result_get_op_res_gpointer (simple));
2011
}
2012
2013
static void
2014
cd_client_get_devices_by_kind_cb (GObject *source_object,
2015
				  GAsyncResult *res,
2016
				  gpointer user_data)
2017
{
2018
	GError *error = NULL;
2019
	GVariant *result;
2020
	GPtrArray *array;
2021
	gchar *object_path = NULL;
2022
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
2023
	CdClient *client = CD_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (res_source)));
2024
2025
	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
2026
					   res,
2027
					   &error);
2028
	if (result == NULL) {
2029
		g_simple_async_result_set_error (res_source,
2030
						 CD_CLIENT_ERROR,
2031
						 CD_CLIENT_ERROR_FAILED,
2032
						 "Failed to GetDevicesByKind: %s",
2033
						 error->message);
2034
		g_error_free (error);
2035
		goto out;
2036
	}
2037
2038
	/* create a profile object */
2039
	array = cd_client_get_device_array_from_variant (client, result);
2040
2041
	/* success */
2042
	g_simple_async_result_set_op_res_gpointer (res_source,
2043
						   array,
2044
						   (GDestroyNotify) g_ptr_array_unref);
2045
	g_variant_unref (result);
2046
out:
2047
	g_free (object_path);
2048
	g_simple_async_result_complete_in_idle (res_source);
2049
	g_object_unref (res_source);
2050
}
2051
2052
/**
2053
 * cd_client_get_devices_by_kind:
2054
 * @client: a #CdClient instance.
2055
 * @kind: the type of device.
2056
 * @cancellable: a #GCancellable, or %NULL
2057
 * @callback: the function to run on completion
2058
 * @user_data: the data to pass to @callback
2059
 *
2060
 * Gets an array of color devices.
2061
 *
2062
 * Since: 0.1.8
2063
 **/
2064
void
2065
cd_client_get_devices_by_kind (CdClient *client,
2066
			       CdDeviceKind kind,
2067
			       GCancellable *cancellable,
2068
			       GAsyncReadyCallback callback,
2069
			       gpointer user_data)
2070
{
2071
	GSimpleAsyncResult *res;
2072
2073
	g_return_if_fail (CD_IS_CLIENT (client));
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
2074
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
2075
	g_return_if_fail (client->priv->proxy != NULL);
2076
2077
	res = g_simple_async_result_new (G_OBJECT (client),
2078
					 callback,
2079
					 user_data,
2080
					 cd_client_get_devices_by_kind);
2081
	g_dbus_proxy_call (client->priv->proxy,
2082
			   "GetDevicesByKind",
2083
			   g_variant_new ("(s)",
2084
			   		  cd_device_kind_to_string (kind)),
2085
			   G_DBUS_CALL_FLAGS_NONE,
2086
			   -1,
2087
			   cancellable,
2088
			   cd_client_get_devices_by_kind_cb,
2089
			   res);
2090
}
2091
2092
/**********************************************************************/
2093
2094
/**
2095
 * cd_client_get_profile_array_from_variant:
2096
 **/
2097
static GPtrArray *
2098
cd_client_get_profile_array_from_variant (CdClient *client,
2099
					 GVariant *result)
2100
{
2101
	CdProfile *profile;
2102
	gchar *object_path_tmp;
2103
	GPtrArray *array = NULL;
2104
	guint i;
2105
	guint len;
2106
	GVariant *child = NULL;
2107
	GVariantIter iter;
2108
2109
	/* add each profile */
2110
	array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
2111
	child = g_variant_get_child_value (result, 0);
2112
	len = g_variant_iter_init (&iter, child);
2113
	for (i=0; i < len; i++) {
2114
		g_variant_get_child (child, i,
2115
				     "o", &object_path_tmp);
2116
		profile = cd_profile_new_with_object_path (object_path_tmp);
2117
		g_ptr_array_add (array, profile);
2118
		g_free (object_path_tmp);
2119
	}
2120
	g_variant_unref (child);
2121
	return array;
2122
}
2123
2124
/**
2125
 * cd_client_get_profiles_finish:
2126
 * @client: a #CdClient instance.
2127
 * @res: the #GAsyncResult
2128
 * @error: A #GError or %NULL
2129
 *
2130
 * Gets the result from the asynchronous function.
2131
 *
2132
 * Return value: (element-type CdProfile) (transfer full): the profiles
2133
 *
2134
 * Since: 0.1.8
2135
 **/
2136
GPtrArray *
2137
cd_client_get_profiles_finish (CdClient *client,
2138
			       GAsyncResult *res,
2139
			       GError **error)
2140
{
2141
	GSimpleAsyncResult *simple;
2142
2143
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
2144
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
2145
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2146
2147
	simple = G_SIMPLE_ASYNC_RESULT (res);
2148
	if (g_simple_async_result_propagate_error (simple, error))
2149
		return FALSE;
2150
2151
	return g_ptr_array_ref (g_simple_async_result_get_op_res_gpointer (simple));
2152
}
2153
2154
static void
2155
cd_client_get_profiles_cb (GObject *source_object,
2156
			   GAsyncResult *res,
2157
			   gpointer user_data)
2158
{
2159
	GError *error = NULL;
2160
	GVariant *result;
2161
	GPtrArray *array;
2162
	gchar *object_path = NULL;
2163
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
2164
	CdClient *client = CD_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (res_source)));
2165
2166
	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
2167
					   res,
2168
					   &error);
2169
	if (result == NULL) {
2170
		g_simple_async_result_set_error (res_source,
2171
						 CD_CLIENT_ERROR,
2172
						 CD_CLIENT_ERROR_FAILED,
2173
						 "Failed to GetProfiles: %s",
2174
						 error->message);
2175
		g_error_free (error);
2176
		goto out;
2177
	}
2178
2179
	/* create a profile object */
2180
	array = cd_client_get_profile_array_from_variant (client, result);
2181
2182
	/* success */
2183
	g_simple_async_result_set_op_res_gpointer (res_source,
2184
						   array,
2185
						   (GDestroyNotify) g_ptr_array_unref);
2186
	g_variant_unref (result);
2187
out:
2188
	g_free (object_path);
2189
	g_simple_async_result_complete_in_idle (res_source);
2190
	g_object_unref (res_source);
2191
}
2192
2193
/**
2194
 * cd_client_get_profiles:
2195
 * @client: a #CdClient instance.
2196
 * @cancellable: a #GCancellable, or %NULL
2197
 * @callback: the function to run on completion
2198
 * @user_data: the data to pass to @callback
2199
 *
2200
 * Gets an array of color profiles.
2201
 *
2202
 * Since: 0.1.8
2203
 **/
2204
void
2205
cd_client_get_profiles (CdClient *client,
2206
			GCancellable *cancellable,
2207
			GAsyncReadyCallback callback,
2208
			gpointer user_data)
2209
{
2210
	GSimpleAsyncResult *res;
2211
2212
	g_return_if_fail (CD_IS_CLIENT (client));
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
2213
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
2214
	g_return_if_fail (client->priv->proxy != NULL);
2215
2216
	res = g_simple_async_result_new (G_OBJECT (client),
2217
					 callback,
2218
					 user_data,
2219
					 cd_client_get_profiles);
2220
	g_dbus_proxy_call (client->priv->proxy,
2221
			   "GetProfiles",
2222
			   NULL,
2223
			   G_DBUS_CALL_FLAGS_NONE,
2224
			   -1,
2225
			   cancellable,
2226
			   cd_client_get_profiles_cb,
2227
			   res);
2228
}
2229
2230
/**********************************************************************/
2231
2232
/**
2233
 * cd_client_get_sensor_array_from_variant:
2234
 **/
2235
static GPtrArray *
2236
cd_client_get_sensor_array_from_variant (CdClient *client,
2237
					 GVariant *result)
2238
{
2239
	CdSensor *sensor;
2240
	gchar *object_path_tmp;
2241
	GPtrArray *array = NULL;
2242
	guint i;
2243
	guint len;
2244
	GVariant *child = NULL;
2245
	GVariantIter iter;
2246
2247
	/* add each sensor */
2248
	array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
2249
	child = g_variant_get_child_value (result, 0);
2250
	len = g_variant_iter_init (&iter, child);
2251
	for (i=0; i < len; i++) {
2252
		g_variant_get_child (child, i,
2253
				     "o", &object_path_tmp);
2254
		sensor = cd_sensor_new_with_object_path (object_path_tmp);
2255
		g_ptr_array_add (array, sensor);
2256
		g_free (object_path_tmp);
2257
	}
2258
	g_variant_unref (child);
2259
	return array;
2260
}
2261
2262
/**
2263
 * cd_client_get_sensors_finish:
2264
 * @client: a #CdClient instance.
2265
 * @res: the #GAsyncResult
2266
 * @error: A #GError or %NULL
2267
 *
2268
 * Gets the result from the asynchronous function.
2269
 *
2270
 * Return value: (element-type CdSensor) (transfer full): the sensors
2271
 *
2272
 * Since: 0.1.8
2273
 **/
2274
GPtrArray *
2275
cd_client_get_sensors_finish (CdClient *client,
2276
			      GAsyncResult *res,
2277
			      GError **error)
2278
{
2279
	GSimpleAsyncResult *simple;
2280
2281
	g_return_val_if_fail (CD_IS_CLIENT (client), FALSE);
2282
	g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
2283
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
2284
2285
	simple = G_SIMPLE_ASYNC_RESULT (res);
2286
	if (g_simple_async_result_propagate_error (simple, error))
2287
		return FALSE;
2288
2289
	return g_ptr_array_ref (g_simple_async_result_get_op_res_gpointer (simple));
2290
}
2291
2292
static void
2293
cd_client_get_sensors_cb (GObject *source_object,
2294
			  GAsyncResult *res,
2295
			  gpointer user_data)
2296
{
2297
	GError *error = NULL;
2298
	GVariant *result;
2299
	GPtrArray *array;
2300
	gchar *object_path = NULL;
2301
	GSimpleAsyncResult *res_source = G_SIMPLE_ASYNC_RESULT (user_data);
2302
	CdClient *client = CD_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (res_source)));
2303
2304
	result = g_dbus_proxy_call_finish (G_DBUS_PROXY (source_object),
2305
					   res,
2306
					   &error);
2307
	if (result == NULL) {
2308
		g_simple_async_result_set_error (res_source,
2309
						 CD_CLIENT_ERROR,
2310
						 CD_CLIENT_ERROR_FAILED,
2311
						 "Failed to GetSensors: %s",
2312
						 error->message);
2313
		g_error_free (error);
2314
		goto out;
2315
	}
2316
2317
	/* create a sensor object */
2318
	array = cd_client_get_sensor_array_from_variant (client, result);
2319
2320
	/* success */
2321
	g_simple_async_result_set_op_res_gpointer (res_source,
2322
						   array,
2323
						   (GDestroyNotify) g_ptr_array_unref);
2324
	g_variant_unref (result);
2325
out:
2326
	g_free (object_path);
2327
	g_simple_async_result_complete_in_idle (res_source);
2328
	g_object_unref (res_source);
2329
}
2330
2331
/**
2332
 * cd_client_get_sensors:
2333
 * @client: a #CdClient instance.
2334
 * @cancellable: a #GCancellable, or %NULL
2335
 * @callback: the function to run on completion
2336
 * @user_data: the data to pass to @callback
2337
 *
2338
 * Gets an array of color sensors.
2339
 *
2340
 * Since: 0.1.8
2341
 **/
2342
void
2343
cd_client_get_sensors (CdClient *client,
2344
		       GCancellable *cancellable,
2345
		       GAsyncReadyCallback callback,
2346
		       gpointer user_data)
2347
{
2348
	GSimpleAsyncResult *res;
2349
2350
	g_return_if_fail (CD_IS_CLIENT (client));
1.1.1 by Rodrigo Moya
Import upstream version 0.1.12
2351
	g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
2352
	g_return_if_fail (client->priv->proxy != NULL);
2353
2354
	res = g_simple_async_result_new (G_OBJECT (client),
2355
					 callback,
2356
					 user_data,
2357
					 cd_client_get_sensors);
2358
	g_dbus_proxy_call (client->priv->proxy,
2359
			   "GetSensors",
2360
			   NULL,
2361
			   G_DBUS_CALL_FLAGS_NONE,
2362
			   -1,
2363
			   cancellable,
2364
			   cd_client_get_sensors_cb,
2365
			   res);
2366
}
2367
2368
/**********************************************************************/
2369
2370
/*
2371
 * cd_client_get_property:
2372
 */
2373
static void
2374
cd_client_get_property (GObject *object,
2375
			 guint prop_id,
2376
			 GValue *value,
2377
			 GParamSpec *pspec)
2378
{
2379
	CdClient *client;
2380
	client = CD_CLIENT (object);
2381
2382
	switch (prop_id) {
2383
	case PROP_DAEMON_VERSION:
2384
		g_value_set_string (value, client->priv->daemon_version);
2385
		break;
2386
	case PROP_CONNECTED:
2387
		g_value_set_boolean (value, client->priv->proxy != NULL);
2388
		break;
2389
	default:
2390
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2391
		break;
2392
	}
2393
}
2394
2395
/*
2396
 * cd_client_class_init:
2397
 */
2398
static void
2399
cd_client_class_init (CdClientClass *klass)
2400
{
2401
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
2402
2403
	object_class->get_property = cd_client_get_property;
2404
	object_class->finalize = cd_client_finalize;
2405
2406
	/**
2407
	 * CdClient:daemon-version:
2408
	 *
2409
	 * The daemon version.
2410
	 *
2411
	 * Since: 0.1.0
2412
	 */
2413
	g_object_class_install_property (object_class,
2414
					 PROP_DAEMON_VERSION,
2415
					 g_param_spec_string ("daemon-version",
2416
							      "Daemon version",
2417
							      NULL,
2418
							      NULL,
2419
							      G_PARAM_READABLE));
2420
	/**
2421
	 * CdClient:connected:
2422
	 *
2423
	 * The if the object path has been connected as is valid for use.
2424
	 *
2425
	 * Since: 0.1.9
2426
	 **/
2427
	g_object_class_install_property (object_class,
2428
					 PROP_CONNECTED,
2429
					 g_param_spec_string ("connected",
2430
							      NULL, NULL,
2431
							      NULL,
2432
							      G_PARAM_READABLE));
2433
2434
	/**
2435
	 * CdClient::device-added:
2436
	 * @client: the #CdClient instance that emitted the signal
2437
	 * @device: the #CdDevice that was added.
2438
	 *
2439
	 * The ::device-added signal is emitted when a device is added.
2440
	 *
2441
	 * Since: 0.1.0
2442
	 **/
2443
	signals [SIGNAL_DEVICE_ADDED] =
2444
		g_signal_new ("device-added",
2445
			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
2446
			      G_STRUCT_OFFSET (CdClientClass, device_added),
2447
			      NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
2448
			      G_TYPE_NONE, 1, CD_TYPE_DEVICE);
2449
2450
	/**
2451
	 * CdClient::device-removed:
2452
	 * @client: the #CdClient instance that emitted the signal
2453
	 * @device: the #CdDevice that was removed.
2454
	 *
2455
	 * The ::device-added signal is emitted when a device is removed.
2456
	 *
2457
	 * Since: 0.1.0
2458
	 **/
2459
	signals [SIGNAL_DEVICE_REMOVED] =
2460
		g_signal_new ("device-removed",
2461
			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
2462
			      G_STRUCT_OFFSET (CdClientClass, device_removed),
2463
			      NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
2464
			      G_TYPE_NONE, 1, CD_TYPE_DEVICE);
2465
	/**
2466
	 * CdClient::device-changed:
2467
	 * @client: the #CdClient instance that emitted the signal
2468
	 * @device: the #CdDevice that was changed.
2469
	 *
2470
	 * The ::device-changed signal is emitted when a device is changed.
2471
	 *
2472
	 * Since: 0.1.2
2473
	 **/
2474
	signals [SIGNAL_DEVICE_CHANGED] =
2475
		g_signal_new ("device-changed",
2476
			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
2477
			      G_STRUCT_OFFSET (CdClientClass, device_changed),
2478
			      NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
2479
			      G_TYPE_NONE, 1, CD_TYPE_DEVICE);
2480
	/**
2481
	 * CdClient::profile-added:
2482
	 * @client: the #CdClient instance that emitted the signal
2483
	 * @profile: the #CdProfile that was added.
2484
	 *
2485
	 * The ::profile-added signal is emitted when a profile is added.
2486
	 *
2487
	 * Since: 0.1.2
2488
	 **/
2489
	signals [SIGNAL_PROFILE_ADDED] =
2490
		g_signal_new ("profile-added",
2491
			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
2492
			      G_STRUCT_OFFSET (CdClientClass, profile_added),
2493
			      NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
2494
			      G_TYPE_NONE, 1, CD_TYPE_PROFILE);
2495
2496
	/**
2497
	 * CdClient::profile-removed:
2498
	 * @client: the #CdClient instance that emitted the signal
2499
	 * @profile: the #CdProfile that was removed.
2500
	 *
2501
	 * The ::profile-added signal is emitted when a profile is removed.
2502
	 *
2503
	 * Since: 0.1.2
2504
	 **/
2505
	signals [SIGNAL_PROFILE_REMOVED] =
2506
		g_signal_new ("profile-removed",
2507
			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
2508
			      G_STRUCT_OFFSET (CdClientClass, profile_removed),
2509
			      NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
2510
			      G_TYPE_NONE, 1, CD_TYPE_PROFILE);
2511
	/**
2512
	 * CdClient::profile-changed:
2513
	 * @client: the #CdClient instance that emitted the signal
2514
	 * @profile: the #CdProfile that was removed.
2515
	 *
2516
	 * The ::profile-changed signal is emitted when a profile is changed.
2517
	 *
2518
	 * Since: 0.1.2
2519
	 **/
2520
	signals [SIGNAL_PROFILE_CHANGED] =
2521
		g_signal_new ("profile-changed",
2522
			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
2523
			      G_STRUCT_OFFSET (CdClientClass, profile_changed),
2524
			      NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
2525
			      G_TYPE_NONE, 1, CD_TYPE_PROFILE);
2526
2527
	/**
2528
	 * CdClient::sensor-added:
2529
	 * @client: the #CdClient instance that emitted the signal
2530
	 * @sensor: the #CdSensor that was added.
2531
	 *
2532
	 * The ::sensor-added signal is emitted when a sensor is added.
2533
	 *
2534
	 * Since: 0.1.6
2535
	 **/
2536
	signals [SIGNAL_SENSOR_ADDED] =
2537
		g_signal_new ("sensor-added",
2538
			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
2539
			      G_STRUCT_OFFSET (CdClientClass, sensor_added),
2540
			      NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
2541
			      G_TYPE_NONE, 1, CD_TYPE_SENSOR);
2542
2543
	/**
2544
	 * CdClient::sensor-removed:
2545
	 * @client: the #CdClient instance that emitted the signal
2546
	 * @sensor: the #CdSensor that was removed.
2547
	 *
2548
	 * The ::sensor-added signal is emitted when a sensor is removed.
2549
	 *
2550
	 * Since: 0.1.6
2551
	 **/
2552
	signals [SIGNAL_SENSOR_REMOVED] =
2553
		g_signal_new ("sensor-removed",
2554
			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
2555
			      G_STRUCT_OFFSET (CdClientClass, sensor_removed),
2556
			      NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
2557
			      G_TYPE_NONE, 1, CD_TYPE_SENSOR);
2558
	/**
2559
	 * CdClient::sensor-changed:
2560
	 * @client: the #CdClient instance that emitted the signal
2561
	 * @sensor: the #CdSensor that was removed.
2562
	 *
2563
	 * The ::sensor-changed signal is emitted when a sensor is changed.
2564
	 *
2565
	 * Since: 0.1.6
2566
	 **/
2567
	signals [SIGNAL_SENSOR_CHANGED] =
2568
		g_signal_new ("sensor-changed",
2569
			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
2570
			      G_STRUCT_OFFSET (CdClientClass, sensor_changed),
2571
			      NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
2572
			      G_TYPE_NONE, 1, CD_TYPE_SENSOR);
2573
2574
	/**
2575
	 * CdClient::changed:
2576
	 * @client: the #CdDevice instance that emitted the signal
2577
	 *
2578
	 * The ::changed signal is emitted when properties may have changed.
2579
	 *
2580
	 * Since: 0.1.0
2581
	 **/
2582
	signals [SIGNAL_CHANGED] =
2583
		g_signal_new ("changed",
2584
			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
2585
			      G_STRUCT_OFFSET (CdClientClass, changed),
2586
			      NULL, NULL, g_cclosure_marshal_VOID__VOID,
2587
			      G_TYPE_NONE, 0);
2588
2589
	g_type_class_add_private (klass, sizeof (CdClientPrivate));
2590
}
2591
2592
/*
2593
 * cd_client_init:
2594
 */
2595
static void
2596
cd_client_init (CdClient *client)
2597
{
2598
	client->priv = CD_CLIENT_GET_PRIVATE (client);
1.2.1 by Sjoerd Simons
Import upstream version 0.1.13
2599
2600
	/* ensure the remote errors are registered */
2601
	cd_client_error_quark ();
1 by Christopher James Halse Rogers
Import upstream version 0.1.11
2602
}
2603
2604
/*
2605
 * cd_client_finalize:
2606
 */
2607
static void
2608
cd_client_finalize (GObject *object)
2609
{
2610
	CdClient *client = CD_CLIENT (object);
2611
2612
	g_return_if_fail (CD_IS_CLIENT (object));
2613
2614
	g_free (client->priv->daemon_version);
2615
	if (client->priv->proxy != NULL)
2616
		g_object_unref (client->priv->proxy);
2617
2618
	G_OBJECT_CLASS (cd_client_parent_class)->finalize (object);
2619
}
2620
2621
/**
2622
 * cd_client_new:
2623
 *
2624
 * Creates a new #CdClient object.
2625
 *
2626
 * Return value: a new CdClient object.
2627
 *
2628
 * Since: 0.1.0
2629
 **/
2630
CdClient *
2631
cd_client_new (void)
2632
{
2633
	if (cd_client_object != NULL) {
2634
		g_object_ref (cd_client_object);
2635
	} else {
2636
		cd_client_object = g_object_new (CD_TYPE_CLIENT, NULL);
2637
		g_object_add_weak_pointer (cd_client_object, &cd_client_object);
2638
	}
2639
	return CD_CLIENT (cd_client_object);
2640
}
2641