xref: /titanic_50/usr/src/cmd/hal/hald/device.c (revision 605ae3838bfc53109099d50ccc905e4ea0eb15b7)
118c2aff7Sartem /***************************************************************************
218c2aff7Sartem  * CVSID: $Id$
318c2aff7Sartem  *
418c2aff7Sartem  * device.c : HalDevice methods
518c2aff7Sartem  *
618c2aff7Sartem  * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
718c2aff7Sartem  * Copyright (C) 2004 Novell, Inc.
818c2aff7Sartem  *
918c2aff7Sartem  * Licensed under the Academic Free License version 2.1
1018c2aff7Sartem  *
1118c2aff7Sartem  * This program is free software; you can redistribute it and/or modify
1218c2aff7Sartem  * it under the terms of the GNU General Public License as published by
1318c2aff7Sartem  * the Free Software Foundation; either version 2 of the License, or
1418c2aff7Sartem  * (at your option) any later version.
1518c2aff7Sartem  *
1618c2aff7Sartem  * This program is distributed in the hope that it will be useful,
1718c2aff7Sartem  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1818c2aff7Sartem  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1918c2aff7Sartem  * GNU General Public License for more details.
2018c2aff7Sartem  *
2118c2aff7Sartem  * You should have received a copy of the GNU General Public License
2218c2aff7Sartem  * along with this program; if not, write to the Free Software
2318c2aff7Sartem  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
2418c2aff7Sartem  *
2518c2aff7Sartem  **************************************************************************/
2618c2aff7Sartem 
2718c2aff7Sartem #ifdef HAVE_CONFIG_H
2818c2aff7Sartem #  include <config.h>
2918c2aff7Sartem #endif
3018c2aff7Sartem 
3118c2aff7Sartem #include <stdio.h>
3218c2aff7Sartem #include <string.h>
3318c2aff7Sartem 
3418c2aff7Sartem #include "hald.h"
3518c2aff7Sartem #include "device.h"
3618c2aff7Sartem #include "hald_marshal.h"
3718c2aff7Sartem #include "logger.h"
3818c2aff7Sartem #include "hald_runner.h"
3918c2aff7Sartem 
4018c2aff7Sartem static GObjectClass *parent_class;
4118c2aff7Sartem 
4218c2aff7Sartem enum {
4318c2aff7Sartem 	PROPERTY_CHANGED,
4418c2aff7Sartem 	CAPABILITY_ADDED,
4518c2aff7Sartem 	CALLOUTS_FINISHED,
4618c2aff7Sartem 	CANCELLED,
4718c2aff7Sartem 	LAST_SIGNAL
4818c2aff7Sartem };
4918c2aff7Sartem 
5018c2aff7Sartem static guint signals[LAST_SIGNAL] = { 0 };
5118c2aff7Sartem 
5218c2aff7Sartem #ifdef HALD_MEMLEAK_DBG
5318c2aff7Sartem int dbg_hal_device_object_delta = 0;
5418c2aff7Sartem #endif
5518c2aff7Sartem 
5618c2aff7Sartem static void
hal_device_finalize(GObject * obj)5718c2aff7Sartem hal_device_finalize (GObject *obj)
5818c2aff7Sartem {
5918c2aff7Sartem 	HalDevice *device = HAL_DEVICE (obj);
6018c2aff7Sartem 
6118c2aff7Sartem 	runner_device_finalized (device);
6218c2aff7Sartem 
6318c2aff7Sartem #ifdef HALD_MEMLEAK_DBG
6418c2aff7Sartem 	dbg_hal_device_object_delta--;
6518c2aff7Sartem 	printf ("************* in finalize for udi=%s\n", device->udi);
6618c2aff7Sartem #endif
6718c2aff7Sartem 
6818c2aff7Sartem 
6918c2aff7Sartem 	g_slist_foreach (device->properties, (GFunc) hal_property_free, NULL);
7018c2aff7Sartem 
718b80e8cbSLin Guo - Sun Microsystems 	g_slist_free (device->properties);
728b80e8cbSLin Guo - Sun Microsystems 
7318c2aff7Sartem 	g_free (device->udi);
7418c2aff7Sartem 
7518c2aff7Sartem 	if (parent_class->finalize)
7618c2aff7Sartem 		parent_class->finalize (obj);
7718c2aff7Sartem 
7818c2aff7Sartem }
7918c2aff7Sartem 
8018c2aff7Sartem static void
hal_device_class_init(HalDeviceClass * klass)8118c2aff7Sartem hal_device_class_init (HalDeviceClass *klass)
8218c2aff7Sartem {
8318c2aff7Sartem 	GObjectClass *obj_class = (GObjectClass *) klass;
8418c2aff7Sartem 
8518c2aff7Sartem 	parent_class = g_type_class_peek_parent (klass);
8618c2aff7Sartem 
8718c2aff7Sartem 	obj_class->finalize = hal_device_finalize;
8818c2aff7Sartem 
8918c2aff7Sartem 	signals[PROPERTY_CHANGED] =
9018c2aff7Sartem 		g_signal_new ("property_changed",
9118c2aff7Sartem 			      G_TYPE_FROM_CLASS (klass),
9218c2aff7Sartem 			      G_SIGNAL_RUN_LAST,
9318c2aff7Sartem 			      G_STRUCT_OFFSET (HalDeviceClass,
9418c2aff7Sartem 					       property_changed),
9518c2aff7Sartem 			      NULL, NULL,
96*605ae383SAndy Fiddaman 			      hald_marshal_VOID__STRING_BOOLEAN_BOOLEAN,
9718c2aff7Sartem 			      G_TYPE_NONE, 3,
9818c2aff7Sartem 			      G_TYPE_STRING,
9918c2aff7Sartem 			      G_TYPE_BOOLEAN,
10018c2aff7Sartem 			      G_TYPE_BOOLEAN);
10118c2aff7Sartem 
10218c2aff7Sartem 	signals[CAPABILITY_ADDED] =
10318c2aff7Sartem 		g_signal_new ("capability_added",
10418c2aff7Sartem 			      G_TYPE_FROM_CLASS (klass),
10518c2aff7Sartem 			      G_SIGNAL_RUN_LAST,
10618c2aff7Sartem 			      G_STRUCT_OFFSET (HalDeviceClass,
10718c2aff7Sartem 					       capability_added),
10818c2aff7Sartem 			      NULL, NULL,
10918c2aff7Sartem 			      hald_marshal_VOID__STRING,
11018c2aff7Sartem 			      G_TYPE_NONE, 1,
11118c2aff7Sartem 			      G_TYPE_STRING);
11218c2aff7Sartem 
11318c2aff7Sartem 	signals[CALLOUTS_FINISHED] =
11418c2aff7Sartem 		g_signal_new ("callouts_finished",
11518c2aff7Sartem 			      G_TYPE_FROM_CLASS (klass),
11618c2aff7Sartem 			      G_SIGNAL_RUN_LAST,
11718c2aff7Sartem 			      G_STRUCT_OFFSET (HalDeviceClass,
11818c2aff7Sartem 					       callouts_finished),
11918c2aff7Sartem 			      NULL, NULL,
12018c2aff7Sartem 			      hald_marshal_VOID__VOID,
12118c2aff7Sartem 			      G_TYPE_NONE, 0);
12218c2aff7Sartem 
12318c2aff7Sartem 	signals[CANCELLED] =
12418c2aff7Sartem 		g_signal_new ("cancelled",
12518c2aff7Sartem 			      G_TYPE_FROM_CLASS (klass),
12618c2aff7Sartem 			      G_SIGNAL_RUN_LAST,
12718c2aff7Sartem 			      G_STRUCT_OFFSET (HalDeviceClass,
12818c2aff7Sartem 					       cancelled),
12918c2aff7Sartem 			      NULL, NULL,
13018c2aff7Sartem 			      hald_marshal_VOID__VOID,
13118c2aff7Sartem 			      G_TYPE_NONE, 0);
13218c2aff7Sartem }
13318c2aff7Sartem 
13418c2aff7Sartem static void
hal_device_init(HalDevice * device)13518c2aff7Sartem hal_device_init (HalDevice *device)
13618c2aff7Sartem {
13718c2aff7Sartem 	static int temp_device_counter = 0;
13818c2aff7Sartem 
13918c2aff7Sartem 	device->udi = g_strdup_printf ("/org/freedesktop/Hal/devices/temp/%d",
14018c2aff7Sartem 				       temp_device_counter++);
14118c2aff7Sartem 	device->num_addons = 0;
14218c2aff7Sartem 	device->num_addons_ready = 0;
14318c2aff7Sartem }
14418c2aff7Sartem 
14518c2aff7Sartem GType
hal_device_get_type(void)14618c2aff7Sartem hal_device_get_type (void)
14718c2aff7Sartem {
14818c2aff7Sartem 	static GType type = 0;
14918c2aff7Sartem 
15018c2aff7Sartem 	if (!type) {
15118c2aff7Sartem 		static GTypeInfo type_info = {
15218c2aff7Sartem 			sizeof (HalDeviceClass),
15318c2aff7Sartem 			NULL, NULL,
15418c2aff7Sartem 			(GClassInitFunc) hal_device_class_init,
15518c2aff7Sartem 			NULL, NULL,
15618c2aff7Sartem 			sizeof (HalDevice),
15718c2aff7Sartem 			0,
15818c2aff7Sartem 			(GInstanceInitFunc) hal_device_init,
15918c2aff7Sartem 			NULL
16018c2aff7Sartem 		};
16118c2aff7Sartem 
16218c2aff7Sartem 		type = g_type_register_static (G_TYPE_OBJECT,
16318c2aff7Sartem 					       "HalDevice",
16418c2aff7Sartem 					       &type_info,
16518c2aff7Sartem 					       0);
16618c2aff7Sartem 	}
16718c2aff7Sartem 
16818c2aff7Sartem 	return type;
16918c2aff7Sartem }
17018c2aff7Sartem 
17118c2aff7Sartem 
17218c2aff7Sartem HalDevice *
hal_device_new(void)17318c2aff7Sartem hal_device_new (void)
17418c2aff7Sartem {
17518c2aff7Sartem 	HalDevice *device;
17618c2aff7Sartem 
17718c2aff7Sartem 	device = g_object_new (HAL_TYPE_DEVICE, NULL, NULL);
17818c2aff7Sartem 
17918c2aff7Sartem #ifdef HALD_MEMLEAK_DBG
18018c2aff7Sartem 	dbg_hal_device_object_delta++;
18118c2aff7Sartem #endif
18218c2aff7Sartem 	return device;
18318c2aff7Sartem }
18418c2aff7Sartem 
18518c2aff7Sartem /** Merge all properties from source where the key starts with
18618c2aff7Sartem  *  source_namespace and put them onto target replacing source_namespace
18718c2aff7Sartem  *  with target_namespace
18818c2aff7Sartem  *
18918c2aff7Sartem  *  @param  target              Device to put properties onto
19018c2aff7Sartem  *  @param  source              Device to retrieve properties from
19118c2aff7Sartem  *  @param  target_namespace    Replace source namespace with this namespace
19218c2aff7Sartem  *  @param  source_namespace    Source namespace that property keys must match
19318c2aff7Sartem  */
19418c2aff7Sartem void
hal_device_merge_with_rewrite(HalDevice * target,HalDevice * source,const char * target_namespace,const char * source_namespace)19518c2aff7Sartem hal_device_merge_with_rewrite  (HalDevice    *target,
19618c2aff7Sartem 				HalDevice    *source,
19718c2aff7Sartem 				const char   *target_namespace,
19818c2aff7Sartem 				const char   *source_namespace)
19918c2aff7Sartem {
20018c2aff7Sartem 	GSList *iter;
20118c2aff7Sartem 	size_t source_ns_len;
20218c2aff7Sartem 
20318c2aff7Sartem 	source_ns_len = strlen (source_namespace);
20418c2aff7Sartem 
20518c2aff7Sartem 	/* doesn't handle info.capabilities */
20618c2aff7Sartem 
20718c2aff7Sartem 	/* device_property_atomic_update_begin (); */
20818c2aff7Sartem 
20918c2aff7Sartem 	for (iter = source->properties; iter != NULL; iter = iter->next) {
21018c2aff7Sartem 		HalProperty *p = iter->data;
21118c2aff7Sartem 		int type;
21218c2aff7Sartem 		const char *key;
21318c2aff7Sartem 		int target_type;
21418c2aff7Sartem 		gchar *target_key;
21518c2aff7Sartem 
21618c2aff7Sartem 		key = hal_property_get_key (p);
21718c2aff7Sartem 
21818c2aff7Sartem 		/* only care about properties that match source namespace */
21918c2aff7Sartem 		if (strncmp(key, source_namespace, source_ns_len) != 0)
22018c2aff7Sartem 			continue;
22118c2aff7Sartem 
22218c2aff7Sartem 		target_key = g_strdup_printf("%s%s", target_namespace,
22318c2aff7Sartem 					     key+source_ns_len);
22418c2aff7Sartem 
22518c2aff7Sartem 		type = hal_property_get_type (p);
22618c2aff7Sartem 
22718c2aff7Sartem 		/* only remove target if it exists with a different type */
22818c2aff7Sartem 		target_type = hal_device_property_get_type (target, key);
22918c2aff7Sartem 		if (target_type != HAL_PROPERTY_TYPE_INVALID && target_type != type)
23018c2aff7Sartem 			hal_device_property_remove (target, key);
23118c2aff7Sartem 
23218c2aff7Sartem 		switch (type) {
23318c2aff7Sartem 
23418c2aff7Sartem 		case HAL_PROPERTY_TYPE_STRING:
23518c2aff7Sartem 			hal_device_property_set_string (
23618c2aff7Sartem 				target, target_key,
23718c2aff7Sartem 				hal_property_get_string (p));
23818c2aff7Sartem 			break;
23918c2aff7Sartem 
24018c2aff7Sartem 		case HAL_PROPERTY_TYPE_INT32:
24118c2aff7Sartem 			hal_device_property_set_int (
24218c2aff7Sartem 				target, target_key,
24318c2aff7Sartem 				hal_property_get_int (p));
24418c2aff7Sartem 			break;
24518c2aff7Sartem 
24618c2aff7Sartem 		case HAL_PROPERTY_TYPE_UINT64:
24718c2aff7Sartem 			hal_device_property_set_uint64 (
24818c2aff7Sartem 				target, target_key,
24918c2aff7Sartem 				hal_property_get_uint64 (p));
25018c2aff7Sartem 			break;
25118c2aff7Sartem 
25218c2aff7Sartem 		case HAL_PROPERTY_TYPE_BOOLEAN:
25318c2aff7Sartem 			hal_device_property_set_bool (
25418c2aff7Sartem 				target, target_key,
25518c2aff7Sartem 				hal_property_get_bool (p));
25618c2aff7Sartem 			break;
25718c2aff7Sartem 
25818c2aff7Sartem 		case HAL_PROPERTY_TYPE_DOUBLE:
25918c2aff7Sartem 			hal_device_property_set_double (
26018c2aff7Sartem 				target, target_key,
26118c2aff7Sartem 				hal_property_get_double (p));
26218c2aff7Sartem 			break;
26318c2aff7Sartem 
26418c2aff7Sartem 		default:
26518c2aff7Sartem 			HAL_WARNING (("Unknown property type %d", type));
26618c2aff7Sartem 			break;
26718c2aff7Sartem 		}
26818c2aff7Sartem 
26918c2aff7Sartem 		g_free (target_key);
27018c2aff7Sartem 	}
27118c2aff7Sartem 
27218c2aff7Sartem 	/* device_property_atomic_update_end (); */
27318c2aff7Sartem 
27418c2aff7Sartem }
27518c2aff7Sartem 
27618c2aff7Sartem void
hal_device_merge(HalDevice * target,HalDevice * source)27718c2aff7Sartem hal_device_merge (HalDevice *target, HalDevice *source)
27818c2aff7Sartem {
27918c2aff7Sartem 	GSList *iter;
28018c2aff7Sartem 	GSList *caps;
28118c2aff7Sartem 
28218c2aff7Sartem 	/* device_property_atomic_update_begin (); */
28318c2aff7Sartem 
28418c2aff7Sartem 	for (iter = source->properties; iter != NULL; iter = iter->next) {
28518c2aff7Sartem 		HalProperty *p = iter->data;
28618c2aff7Sartem 		int type;
28718c2aff7Sartem 		const char *key;
28818c2aff7Sartem 		int target_type;
28918c2aff7Sartem 
29018c2aff7Sartem 		key = hal_property_get_key (p);
29118c2aff7Sartem 		type = hal_property_get_type (p);
29218c2aff7Sartem 
29318c2aff7Sartem 		/* handle info.capabilities in a special way */
29418c2aff7Sartem 		if (strcmp (key, "info.capabilities") == 0)
29518c2aff7Sartem 			continue;
29618c2aff7Sartem 
29718c2aff7Sartem 		/* only remove target if it exists with a different type */
29818c2aff7Sartem 		target_type = hal_device_property_get_type (target, key);
29918c2aff7Sartem 		if (target_type != HAL_PROPERTY_TYPE_INVALID && target_type != type)
30018c2aff7Sartem 			hal_device_property_remove (target, key);
30118c2aff7Sartem 
30218c2aff7Sartem 		switch (type) {
30318c2aff7Sartem 
30418c2aff7Sartem 		case HAL_PROPERTY_TYPE_STRING:
30518c2aff7Sartem 			hal_device_property_set_string (
30618c2aff7Sartem 				target, key,
30718c2aff7Sartem 				hal_property_get_string (p));
30818c2aff7Sartem 			break;
30918c2aff7Sartem 
31018c2aff7Sartem 		case HAL_PROPERTY_TYPE_INT32:
31118c2aff7Sartem 			hal_device_property_set_int (
31218c2aff7Sartem 				target, key,
31318c2aff7Sartem 				hal_property_get_int (p));
31418c2aff7Sartem 			break;
31518c2aff7Sartem 
31618c2aff7Sartem 		case HAL_PROPERTY_TYPE_UINT64:
31718c2aff7Sartem 			hal_device_property_set_uint64 (
31818c2aff7Sartem 				target, key,
31918c2aff7Sartem 				hal_property_get_uint64 (p));
32018c2aff7Sartem 			break;
32118c2aff7Sartem 
32218c2aff7Sartem 		case HAL_PROPERTY_TYPE_BOOLEAN:
32318c2aff7Sartem 			hal_device_property_set_bool (
32418c2aff7Sartem 				target, key,
32518c2aff7Sartem 				hal_property_get_bool (p));
32618c2aff7Sartem 			break;
32718c2aff7Sartem 
32818c2aff7Sartem 		case HAL_PROPERTY_TYPE_DOUBLE:
32918c2aff7Sartem 			hal_device_property_set_double (
33018c2aff7Sartem 				target, key,
33118c2aff7Sartem 				hal_property_get_double (p));
33218c2aff7Sartem 			break;
33318c2aff7Sartem 
33418c2aff7Sartem 		default:
33518c2aff7Sartem 			HAL_WARNING (("Unknown property type %d", type));
33618c2aff7Sartem 			break;
33718c2aff7Sartem 		}
33818c2aff7Sartem 	}
33918c2aff7Sartem 
34018c2aff7Sartem 	/* device_property_atomic_update_end (); */
34118c2aff7Sartem 
34218c2aff7Sartem 	caps = hal_device_property_get_strlist (source, "info.capabilities");
34318c2aff7Sartem 	for (iter = caps; iter != NULL; iter = iter->next) {
34418c2aff7Sartem 		if (!hal_device_has_capability (target, iter->data))
34518c2aff7Sartem 			hal_device_add_capability (target, iter->data);
34618c2aff7Sartem 	}
34718c2aff7Sartem }
34818c2aff7Sartem 
34918c2aff7Sartem gboolean
hal_device_matches(HalDevice * device1,HalDevice * device2,const char * namespace)35018c2aff7Sartem hal_device_matches (HalDevice *device1, HalDevice *device2,
35118c2aff7Sartem 		    const char *namespace)
35218c2aff7Sartem {
35318c2aff7Sartem 	int len;
35418c2aff7Sartem 	GSList *iter;
35518c2aff7Sartem 
35618c2aff7Sartem 	len = strlen (namespace);
35718c2aff7Sartem 
35818c2aff7Sartem 	for (iter = device1->properties; iter != NULL; iter = iter->next) {
35918c2aff7Sartem 		HalProperty *p;
36018c2aff7Sartem 		const char *key;
36118c2aff7Sartem 		int type;
36218c2aff7Sartem 
36318c2aff7Sartem 		p = (HalProperty *) iter->data;
36418c2aff7Sartem 		key = hal_property_get_key (p);
36518c2aff7Sartem 		type = hal_property_get_type (p);
36618c2aff7Sartem 
36718c2aff7Sartem 		if (strncmp (key, namespace, len) != 0)
36818c2aff7Sartem 			continue;
36918c2aff7Sartem 
37018c2aff7Sartem 		if (!hal_device_has_property (device2, key))
37118c2aff7Sartem 			return FALSE;
37218c2aff7Sartem 
37318c2aff7Sartem 		switch (type) {
37418c2aff7Sartem 
37518c2aff7Sartem 		case HAL_PROPERTY_TYPE_STRING:
37618c2aff7Sartem 			if (strcmp (hal_property_get_string (p),
37718c2aff7Sartem 				    hal_device_property_get_string (device2,
37818c2aff7Sartem 								    key)) != 0)
37918c2aff7Sartem 				return FALSE;
38018c2aff7Sartem 			break;
38118c2aff7Sartem 
38218c2aff7Sartem 		case HAL_PROPERTY_TYPE_INT32:
38318c2aff7Sartem 			if (hal_property_get_int (p) !=
38418c2aff7Sartem 			    hal_device_property_get_int (device2, key))
38518c2aff7Sartem 				return FALSE;
38618c2aff7Sartem 			break;
38718c2aff7Sartem 
38818c2aff7Sartem 		case HAL_PROPERTY_TYPE_UINT64:
38918c2aff7Sartem 			if (hal_property_get_uint64 (p) !=
39018c2aff7Sartem 				hal_device_property_get_uint64 (device2, key))
39118c2aff7Sartem 				return FALSE;
39218c2aff7Sartem 			break;
39318c2aff7Sartem 
39418c2aff7Sartem 		case HAL_PROPERTY_TYPE_BOOLEAN:
39518c2aff7Sartem 			if (hal_property_get_bool (p) !=
39618c2aff7Sartem 			    hal_device_property_get_bool (device2, key))
39718c2aff7Sartem 				return FALSE;
39818c2aff7Sartem 			break;
39918c2aff7Sartem 
40018c2aff7Sartem 		case HAL_PROPERTY_TYPE_DOUBLE:
40118c2aff7Sartem 			if (hal_property_get_double (p) !=
40218c2aff7Sartem 			    hal_device_property_get_double (device2, key))
40318c2aff7Sartem 				return FALSE;
40418c2aff7Sartem 			break;
40518c2aff7Sartem 
40618c2aff7Sartem 		default:
40718c2aff7Sartem 			HAL_WARNING (("Unknown property type %d", type));
40818c2aff7Sartem 			break;
40918c2aff7Sartem 		}
41018c2aff7Sartem 	}
41118c2aff7Sartem 
41218c2aff7Sartem 	return TRUE;
41318c2aff7Sartem }
41418c2aff7Sartem 
41518c2aff7Sartem const char *
hal_device_get_udi(HalDevice * device)41618c2aff7Sartem hal_device_get_udi (HalDevice *device)
41718c2aff7Sartem {
41818c2aff7Sartem 	return device->udi;
41918c2aff7Sartem }
42018c2aff7Sartem 
42118c2aff7Sartem void
hal_device_set_udi(HalDevice * device,const char * udi)42218c2aff7Sartem hal_device_set_udi (HalDevice *device, const char *udi)
42318c2aff7Sartem {
42418c2aff7Sartem 	if (device->udi != NULL)
42518c2aff7Sartem 		g_free (device->udi);
42618c2aff7Sartem 	device->udi = g_strdup (udi);
42718c2aff7Sartem }
42818c2aff7Sartem 
42918c2aff7Sartem void
hal_device_add_capability(HalDevice * device,const char * capability)43018c2aff7Sartem hal_device_add_capability (HalDevice *device, const char *capability)
43118c2aff7Sartem {
43218c2aff7Sartem 	if (hal_device_property_strlist_add (device, "info.capabilities", capability))
43318c2aff7Sartem 		g_signal_emit (device, signals[CAPABILITY_ADDED], 0, capability);
43418c2aff7Sartem }
43518c2aff7Sartem 
43618c2aff7Sartem gboolean
hal_device_has_capability(HalDevice * device,const char * capability)43718c2aff7Sartem hal_device_has_capability (HalDevice *device, const char *capability)
43818c2aff7Sartem {
43918c2aff7Sartem 	GSList *caps;
44018c2aff7Sartem 	GSList *iter;
44118c2aff7Sartem 	gboolean matched = FALSE;
44218c2aff7Sartem 
44318c2aff7Sartem 	caps = hal_device_property_get_strlist (device, "info.capabilities");
44418c2aff7Sartem 
44518c2aff7Sartem 	if (caps == NULL)
44618c2aff7Sartem 		return FALSE;
44718c2aff7Sartem 
44818c2aff7Sartem 	for (iter = caps; iter != NULL; iter = iter->next) {
44918c2aff7Sartem 		if (strcmp (iter->data, capability) == 0) {
45018c2aff7Sartem 			matched = TRUE;
45118c2aff7Sartem 			break;
45218c2aff7Sartem 		}
45318c2aff7Sartem 	}
45418c2aff7Sartem 
45518c2aff7Sartem 	return matched;
45618c2aff7Sartem }
45718c2aff7Sartem 
45818c2aff7Sartem gboolean
hal_device_has_property(HalDevice * device,const char * key)45918c2aff7Sartem hal_device_has_property (HalDevice *device, const char *key)
46018c2aff7Sartem {
46118c2aff7Sartem 	g_return_val_if_fail (device != NULL, FALSE);
46218c2aff7Sartem 	g_return_val_if_fail (key != NULL, FALSE);
46318c2aff7Sartem 
46418c2aff7Sartem 	return hal_device_property_find (device, key) != NULL;
46518c2aff7Sartem }
46618c2aff7Sartem 
46718c2aff7Sartem int
hal_device_num_properties(HalDevice * device)46818c2aff7Sartem hal_device_num_properties (HalDevice *device)
46918c2aff7Sartem {
47018c2aff7Sartem 	g_return_val_if_fail (device != NULL, -1);
47118c2aff7Sartem 
47218c2aff7Sartem 	return g_slist_length (device->properties);
47318c2aff7Sartem }
47418c2aff7Sartem 
47518c2aff7Sartem HalProperty *
hal_device_property_find(HalDevice * device,const char * key)47618c2aff7Sartem hal_device_property_find (HalDevice *device, const char *key)
47718c2aff7Sartem {
47818c2aff7Sartem 	GSList *iter;
47918c2aff7Sartem 
48018c2aff7Sartem 	g_return_val_if_fail (device != NULL, NULL);
48118c2aff7Sartem 	g_return_val_if_fail (key != NULL, NULL);
48218c2aff7Sartem 
48318c2aff7Sartem 	for (iter = device->properties; iter != NULL; iter = iter->next) {
48418c2aff7Sartem 		HalProperty *p = iter->data;
48518c2aff7Sartem 
48618c2aff7Sartem 		if (strcmp (hal_property_get_key (p), key) == 0)
48718c2aff7Sartem 			return p;
48818c2aff7Sartem 	}
48918c2aff7Sartem 
49018c2aff7Sartem 	return NULL;
49118c2aff7Sartem }
49218c2aff7Sartem 
49318c2aff7Sartem char *
hal_device_property_to_string(HalDevice * device,const char * key)49418c2aff7Sartem hal_device_property_to_string (HalDevice *device, const char *key)
49518c2aff7Sartem {
49618c2aff7Sartem 	HalProperty *prop;
49718c2aff7Sartem 
49818c2aff7Sartem 	prop = hal_device_property_find (device, key);
49918c2aff7Sartem 	if (!prop)
50018c2aff7Sartem 		return NULL;
50118c2aff7Sartem 
50218c2aff7Sartem 	return hal_property_to_string (prop);
50318c2aff7Sartem }
50418c2aff7Sartem 
50518c2aff7Sartem void
hal_device_property_foreach(HalDevice * device,HalDevicePropertyForeachFn callback,gpointer user_data)50618c2aff7Sartem hal_device_property_foreach (HalDevice *device,
50718c2aff7Sartem 			     HalDevicePropertyForeachFn callback,
50818c2aff7Sartem 			     gpointer user_data)
50918c2aff7Sartem {
51018c2aff7Sartem 	GSList *iter;
51118c2aff7Sartem 
51218c2aff7Sartem 	g_return_if_fail (device != NULL);
51318c2aff7Sartem 	g_return_if_fail (callback != NULL);
51418c2aff7Sartem 
51518c2aff7Sartem 	for (iter = device->properties; iter != NULL; iter = iter->next) {
51618c2aff7Sartem 		HalProperty *p = iter->data;
51718c2aff7Sartem 		gboolean cont;
51818c2aff7Sartem 
51918c2aff7Sartem 		cont = callback (device, p, user_data);
52018c2aff7Sartem 
52118c2aff7Sartem 		if (cont == FALSE)
52218c2aff7Sartem 			return;
52318c2aff7Sartem 	}
52418c2aff7Sartem }
52518c2aff7Sartem 
52618c2aff7Sartem int
hal_device_property_get_type(HalDevice * device,const char * key)52718c2aff7Sartem hal_device_property_get_type (HalDevice *device, const char *key)
52818c2aff7Sartem {
52918c2aff7Sartem 	HalProperty *prop;
53018c2aff7Sartem 
53118c2aff7Sartem 	g_return_val_if_fail (device != NULL, HAL_PROPERTY_TYPE_INVALID);
53218c2aff7Sartem 	g_return_val_if_fail (key != NULL, HAL_PROPERTY_TYPE_INVALID);
53318c2aff7Sartem 
53418c2aff7Sartem 	prop = hal_device_property_find (device, key);
53518c2aff7Sartem 
53618c2aff7Sartem 	if (prop != NULL)
53718c2aff7Sartem 		return hal_property_get_type (prop);
53818c2aff7Sartem 	else
53918c2aff7Sartem 		return HAL_PROPERTY_TYPE_INVALID;
54018c2aff7Sartem }
54118c2aff7Sartem 
54218c2aff7Sartem const char *
hal_device_property_get_string(HalDevice * device,const char * key)54318c2aff7Sartem hal_device_property_get_string (HalDevice *device, const char *key)
54418c2aff7Sartem {
54518c2aff7Sartem 	HalProperty *prop;
54618c2aff7Sartem 
54718c2aff7Sartem 	g_return_val_if_fail (device != NULL, NULL);
54818c2aff7Sartem 	g_return_val_if_fail (key != NULL, NULL);
54918c2aff7Sartem 
55018c2aff7Sartem 	prop = hal_device_property_find (device, key);
55118c2aff7Sartem 
55218c2aff7Sartem 	if (prop != NULL)
55318c2aff7Sartem 		return hal_property_get_string (prop);
55418c2aff7Sartem 	else
55518c2aff7Sartem 		return NULL;
55618c2aff7Sartem }
55718c2aff7Sartem 
55818c2aff7Sartem const char *
hal_device_property_get_as_string(HalDevice * device,const char * key,char * buf,size_t bufsize)55918c2aff7Sartem hal_device_property_get_as_string (HalDevice *device, const char *key, char *buf, size_t bufsize)
56018c2aff7Sartem {
56118c2aff7Sartem 	HalProperty *prop;
56218c2aff7Sartem 
56318c2aff7Sartem 	g_return_val_if_fail (device != NULL, NULL);
56418c2aff7Sartem 	g_return_val_if_fail (key != NULL, NULL);
56518c2aff7Sartem 	g_return_val_if_fail (buf != NULL, NULL);
56618c2aff7Sartem 
56718c2aff7Sartem 	prop = hal_device_property_find (device, key);
56818c2aff7Sartem 
56918c2aff7Sartem 	if (prop != NULL) {
57018c2aff7Sartem 		switch (hal_property_get_type (prop)) {
57118c2aff7Sartem 		case HAL_PROPERTY_TYPE_STRING:
57218c2aff7Sartem 			strncpy (buf, hal_property_get_string (prop), bufsize);
57318c2aff7Sartem 			break;
57418c2aff7Sartem 		case HAL_PROPERTY_TYPE_INT32:
57518c2aff7Sartem 			snprintf (buf, bufsize, "%d", hal_property_get_int (prop));
57618c2aff7Sartem 			break;
57718c2aff7Sartem 		case HAL_PROPERTY_TYPE_UINT64:
57818c2aff7Sartem 			snprintf (buf, bufsize, "%llu", (long long unsigned int) hal_property_get_uint64 (prop));
57918c2aff7Sartem 			break;
58018c2aff7Sartem 		case HAL_PROPERTY_TYPE_DOUBLE:
58118c2aff7Sartem 			snprintf (buf, bufsize, "%f", hal_property_get_double (prop));
58218c2aff7Sartem 			break;
58318c2aff7Sartem 		case HAL_PROPERTY_TYPE_BOOLEAN:
58418c2aff7Sartem 			strncpy (buf, hal_property_get_bool (prop) ? "true" : "false", bufsize);
58518c2aff7Sartem 			break;
58618c2aff7Sartem 
58718c2aff7Sartem 		case HAL_PROPERTY_TYPE_STRLIST:
58818c2aff7Sartem 			/* print out as "\tval1\tval2\val3\t" */
58918c2aff7Sartem 		        {
59018c2aff7Sartem 				GSList *iter;
59118c2aff7Sartem 				guint i;
59218c2aff7Sartem 
59318c2aff7Sartem 				if (bufsize > 0)
59418c2aff7Sartem 					buf[0] = '\t';
59518c2aff7Sartem 				i = 1;
59618c2aff7Sartem 				for (iter = hal_property_get_strlist (prop);
59718c2aff7Sartem 				     iter != NULL && i < bufsize;
59818c2aff7Sartem 				     iter = g_slist_next (iter)) {
59918c2aff7Sartem 					guint len;
60018c2aff7Sartem 					const char *str;
60118c2aff7Sartem 
60218c2aff7Sartem 					str = (const char *) iter->data;
60318c2aff7Sartem 					len = strlen (str);
60418c2aff7Sartem 					strncpy (buf + i, str, bufsize - i);
60518c2aff7Sartem 					i += len;
60618c2aff7Sartem 
60718c2aff7Sartem 					if (i < bufsize) {
60818c2aff7Sartem 						buf[i] = '\t';
60918c2aff7Sartem 						i++;
61018c2aff7Sartem 					}
61118c2aff7Sartem 				}
61218c2aff7Sartem 			}
61318c2aff7Sartem 			break;
61418c2aff7Sartem 		}
61518c2aff7Sartem 		return buf;
61618c2aff7Sartem 	} else {
61718c2aff7Sartem 		buf[0] = '\0';
61818c2aff7Sartem 		return NULL;
61918c2aff7Sartem 	}
62018c2aff7Sartem }
62118c2aff7Sartem 
62218c2aff7Sartem dbus_int32_t
hal_device_property_get_int(HalDevice * device,const char * key)62318c2aff7Sartem hal_device_property_get_int (HalDevice *device, const char *key)
62418c2aff7Sartem {
62518c2aff7Sartem 	HalProperty *prop;
62618c2aff7Sartem 
62718c2aff7Sartem 	g_return_val_if_fail (device != NULL, -1);
62818c2aff7Sartem 	g_return_val_if_fail (key != NULL, -1);
62918c2aff7Sartem 
63018c2aff7Sartem 	prop = hal_device_property_find (device, key);
63118c2aff7Sartem 
63218c2aff7Sartem 	if (prop != NULL)
63318c2aff7Sartem 		return hal_property_get_int (prop);
63418c2aff7Sartem 	else
63518c2aff7Sartem 		return -1;
63618c2aff7Sartem }
63718c2aff7Sartem 
63818c2aff7Sartem dbus_uint64_t
hal_device_property_get_uint64(HalDevice * device,const char * key)63918c2aff7Sartem hal_device_property_get_uint64 (HalDevice *device, const char *key)
64018c2aff7Sartem {
64118c2aff7Sartem 	HalProperty *prop;
64218c2aff7Sartem 
64318c2aff7Sartem 	g_return_val_if_fail (device != NULL, -1);
64418c2aff7Sartem 	g_return_val_if_fail (key != NULL, -1);
64518c2aff7Sartem 
64618c2aff7Sartem 	prop = hal_device_property_find (device, key);
64718c2aff7Sartem 
64818c2aff7Sartem 	if (prop != NULL)
64918c2aff7Sartem 		return hal_property_get_uint64 (prop);
65018c2aff7Sartem 	else
65118c2aff7Sartem 		return -1;
65218c2aff7Sartem }
65318c2aff7Sartem 
65418c2aff7Sartem dbus_bool_t
hal_device_property_get_bool(HalDevice * device,const char * key)65518c2aff7Sartem hal_device_property_get_bool (HalDevice *device, const char *key)
65618c2aff7Sartem {
65718c2aff7Sartem 	HalProperty *prop;
65818c2aff7Sartem 
65918c2aff7Sartem 	g_return_val_if_fail (device != NULL, FALSE);
66018c2aff7Sartem 	g_return_val_if_fail (key != NULL, FALSE);
66118c2aff7Sartem 
66218c2aff7Sartem 	prop = hal_device_property_find (device, key);
66318c2aff7Sartem 
66418c2aff7Sartem 	if (prop != NULL)
66518c2aff7Sartem 		return hal_property_get_bool (prop);
66618c2aff7Sartem 	else
66718c2aff7Sartem 		return FALSE;
66818c2aff7Sartem }
66918c2aff7Sartem 
67018c2aff7Sartem double
hal_device_property_get_double(HalDevice * device,const char * key)67118c2aff7Sartem hal_device_property_get_double (HalDevice *device, const char *key)
67218c2aff7Sartem {
67318c2aff7Sartem 	HalProperty *prop;
67418c2aff7Sartem 
67518c2aff7Sartem 	g_return_val_if_fail (device != NULL, -1.0);
67618c2aff7Sartem 	g_return_val_if_fail (key != NULL, -1.0);
67718c2aff7Sartem 
67818c2aff7Sartem 	prop = hal_device_property_find (device, key);
67918c2aff7Sartem 
68018c2aff7Sartem 	if (prop != NULL)
68118c2aff7Sartem 		return hal_property_get_double (prop);
68218c2aff7Sartem 	else
68318c2aff7Sartem 		return -1.0;
68418c2aff7Sartem }
68518c2aff7Sartem 
68618c2aff7Sartem gboolean
hal_device_property_set_string(HalDevice * device,const char * key,const char * value)68718c2aff7Sartem hal_device_property_set_string (HalDevice *device, const char *key,
68818c2aff7Sartem 				const char *value)
68918c2aff7Sartem {
69018c2aff7Sartem 	HalProperty *prop;
69118c2aff7Sartem 
69218c2aff7Sartem 	/* check if property already exists */
69318c2aff7Sartem 	prop = hal_device_property_find (device, key);
69418c2aff7Sartem 
69518c2aff7Sartem 	if (prop != NULL) {
69618c2aff7Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRING)
69718c2aff7Sartem 			return FALSE;
69818c2aff7Sartem 
69918c2aff7Sartem 		/* don't bother setting the same value */
70018c2aff7Sartem 		if (value != NULL &&
70118c2aff7Sartem 		    strcmp (hal_property_get_string (prop), value) == 0)
70218c2aff7Sartem 			return TRUE;
70318c2aff7Sartem 
70418c2aff7Sartem 		hal_property_set_string (prop, value);
70518c2aff7Sartem 
70618c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
70718c2aff7Sartem 			       key, FALSE, FALSE);
70818c2aff7Sartem 
70918c2aff7Sartem 	} else {
71018c2aff7Sartem 
71118c2aff7Sartem 		prop = hal_property_new_string (key, value);
71218c2aff7Sartem 
71318c2aff7Sartem 		device->properties = g_slist_prepend (device->properties, prop);
71418c2aff7Sartem 
71518c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
71618c2aff7Sartem 			       key, FALSE, TRUE);
71718c2aff7Sartem 	}
71818c2aff7Sartem 
71918c2aff7Sartem 	return TRUE;
72018c2aff7Sartem }
72118c2aff7Sartem 
72218c2aff7Sartem gboolean
hal_device_property_set_int(HalDevice * device,const char * key,dbus_int32_t value)72318c2aff7Sartem hal_device_property_set_int (HalDevice *device, const char *key,
72418c2aff7Sartem 			     dbus_int32_t value)
72518c2aff7Sartem {
72618c2aff7Sartem 	HalProperty *prop;
72718c2aff7Sartem 
72818c2aff7Sartem 	/* check if property already exists */
72918c2aff7Sartem 	prop = hal_device_property_find (device, key);
73018c2aff7Sartem 
73118c2aff7Sartem 	if (prop != NULL) {
73218c2aff7Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_INT32)
73318c2aff7Sartem 			return FALSE;
73418c2aff7Sartem 
73518c2aff7Sartem 		/* don't bother setting the same value */
73618c2aff7Sartem 		if (hal_property_get_int (prop) == value)
73718c2aff7Sartem 			return TRUE;
73818c2aff7Sartem 
73918c2aff7Sartem 		hal_property_set_int (prop, value);
74018c2aff7Sartem 
74118c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
74218c2aff7Sartem 			       key, FALSE, FALSE);
74318c2aff7Sartem 
74418c2aff7Sartem 	} else {
74518c2aff7Sartem 		prop = hal_property_new_int (key, value);
74618c2aff7Sartem 
74718c2aff7Sartem 		device->properties = g_slist_prepend (device->properties, prop);
74818c2aff7Sartem 
74918c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
75018c2aff7Sartem 			       key, FALSE, TRUE);
75118c2aff7Sartem 	}
75218c2aff7Sartem 
75318c2aff7Sartem 	return TRUE;
75418c2aff7Sartem }
75518c2aff7Sartem 
75618c2aff7Sartem gboolean
hal_device_property_set_uint64(HalDevice * device,const char * key,dbus_uint64_t value)75718c2aff7Sartem hal_device_property_set_uint64 (HalDevice *device, const char *key,
75818c2aff7Sartem 			     dbus_uint64_t value)
75918c2aff7Sartem {
76018c2aff7Sartem 	HalProperty *prop;
76118c2aff7Sartem 
76218c2aff7Sartem 	/* check if property already exists */
76318c2aff7Sartem 	prop = hal_device_property_find (device, key);
76418c2aff7Sartem 
76518c2aff7Sartem 	if (prop != NULL) {
76618c2aff7Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_UINT64)
76718c2aff7Sartem 			return FALSE;
76818c2aff7Sartem 
76918c2aff7Sartem 		/* don't bother setting the same value */
77018c2aff7Sartem 		if (hal_property_get_uint64 (prop) == value)
77118c2aff7Sartem 			return TRUE;
77218c2aff7Sartem 
77318c2aff7Sartem 		hal_property_set_uint64 (prop, value);
77418c2aff7Sartem 
77518c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
77618c2aff7Sartem 			       key, FALSE, FALSE);
77718c2aff7Sartem 
77818c2aff7Sartem 	} else {
77918c2aff7Sartem 		prop = hal_property_new_uint64 (key, value);
78018c2aff7Sartem 
78118c2aff7Sartem 		device->properties = g_slist_prepend (device->properties, prop);
78218c2aff7Sartem 
78318c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
78418c2aff7Sartem 			       key, FALSE, TRUE);
78518c2aff7Sartem 	}
78618c2aff7Sartem 
78718c2aff7Sartem 	return TRUE;
78818c2aff7Sartem }
78918c2aff7Sartem 
79018c2aff7Sartem gboolean
hal_device_property_set_bool(HalDevice * device,const char * key,dbus_bool_t value)79118c2aff7Sartem hal_device_property_set_bool (HalDevice *device, const char *key,
79218c2aff7Sartem 			     dbus_bool_t value)
79318c2aff7Sartem {
79418c2aff7Sartem 	HalProperty *prop;
79518c2aff7Sartem 
79618c2aff7Sartem 	/* check if property already exists */
79718c2aff7Sartem 	prop = hal_device_property_find (device, key);
79818c2aff7Sartem 
79918c2aff7Sartem 	if (prop != NULL) {
80018c2aff7Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_BOOLEAN)
80118c2aff7Sartem 			return FALSE;
80218c2aff7Sartem 
80318c2aff7Sartem 		/* don't bother setting the same value */
80418c2aff7Sartem 		if (hal_property_get_bool (prop) == value)
80518c2aff7Sartem 			return TRUE;
80618c2aff7Sartem 
80718c2aff7Sartem 		hal_property_set_bool (prop, value);
80818c2aff7Sartem 
80918c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
81018c2aff7Sartem 			       key, FALSE, FALSE);
81118c2aff7Sartem 
81218c2aff7Sartem 	} else {
81318c2aff7Sartem 		prop = hal_property_new_bool (key, value);
81418c2aff7Sartem 
81518c2aff7Sartem 		device->properties = g_slist_prepend (device->properties, prop);
81618c2aff7Sartem 
81718c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
81818c2aff7Sartem 			       key, FALSE, TRUE);
81918c2aff7Sartem 	}
82018c2aff7Sartem 
82118c2aff7Sartem 	return TRUE;
82218c2aff7Sartem }
82318c2aff7Sartem 
82418c2aff7Sartem gboolean
hal_device_property_set_double(HalDevice * device,const char * key,double value)82518c2aff7Sartem hal_device_property_set_double (HalDevice *device, const char *key,
82618c2aff7Sartem 				double value)
82718c2aff7Sartem {
82818c2aff7Sartem 	HalProperty *prop;
82918c2aff7Sartem 
83018c2aff7Sartem 	/* check if property already exists */
83118c2aff7Sartem 	prop = hal_device_property_find (device, key);
83218c2aff7Sartem 
83318c2aff7Sartem 	if (prop != NULL) {
83418c2aff7Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_DOUBLE)
83518c2aff7Sartem 			return FALSE;
83618c2aff7Sartem 
83718c2aff7Sartem 		/* don't bother setting the same value */
83818c2aff7Sartem 		if (hal_property_get_double (prop) == value)
83918c2aff7Sartem 			return TRUE;
84018c2aff7Sartem 
84118c2aff7Sartem 		hal_property_set_double (prop, value);
84218c2aff7Sartem 
84318c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
84418c2aff7Sartem 			       key, FALSE, FALSE);
84518c2aff7Sartem 
84618c2aff7Sartem 	} else {
84718c2aff7Sartem 		prop = hal_property_new_double (key, value);
84818c2aff7Sartem 
84918c2aff7Sartem 		device->properties = g_slist_prepend (device->properties, prop);
85018c2aff7Sartem 
85118c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
85218c2aff7Sartem 			       key, FALSE, TRUE);
85318c2aff7Sartem 	}
85418c2aff7Sartem 
85518c2aff7Sartem 	return TRUE;
85618c2aff7Sartem }
85718c2aff7Sartem 
85818c2aff7Sartem gboolean
hal_device_copy_property(HalDevice * from_device,const char * from,HalDevice * to_device,const char * to)85918c2aff7Sartem hal_device_copy_property (HalDevice *from_device, const char *from, HalDevice *to_device, const char *to)
86018c2aff7Sartem {
86118c2aff7Sartem 	gboolean rc;
86218c2aff7Sartem 
86318c2aff7Sartem 	rc = FALSE;
86418c2aff7Sartem 
86518c2aff7Sartem 	if (hal_device_has_property (from_device, from)) {
86618c2aff7Sartem 		switch (hal_device_property_get_type (from_device, from)) {
86718c2aff7Sartem 		case HAL_PROPERTY_TYPE_STRING:
86818c2aff7Sartem 			rc = hal_device_property_set_string (
86918c2aff7Sartem 				to_device, to, hal_device_property_get_string (from_device, from));
87018c2aff7Sartem 			break;
87118c2aff7Sartem 		case HAL_PROPERTY_TYPE_INT32:
87218c2aff7Sartem 			rc = hal_device_property_set_int (
87318c2aff7Sartem 				to_device, to, hal_device_property_get_int (from_device, from));
87418c2aff7Sartem 			break;
87518c2aff7Sartem 		case HAL_PROPERTY_TYPE_UINT64:
87618c2aff7Sartem 			rc = hal_device_property_set_uint64 (
87718c2aff7Sartem 				to_device, to, hal_device_property_get_uint64 (from_device, from));
87818c2aff7Sartem 			break;
87918c2aff7Sartem 		case HAL_PROPERTY_TYPE_BOOLEAN:
88018c2aff7Sartem 			rc = hal_device_property_set_bool (
88118c2aff7Sartem 				to_device, to, hal_device_property_get_bool (from_device, from));
88218c2aff7Sartem 			break;
88318c2aff7Sartem 		case HAL_PROPERTY_TYPE_DOUBLE:
88418c2aff7Sartem 			rc = hal_device_property_set_double (
88518c2aff7Sartem 				to_device, to, hal_device_property_get_double (from_device, from));
88618c2aff7Sartem 			break;
88718c2aff7Sartem 		}
88818c2aff7Sartem 	}
88918c2aff7Sartem 
89018c2aff7Sartem 	return rc;
89118c2aff7Sartem }
89218c2aff7Sartem 
89318c2aff7Sartem gboolean
hal_device_property_remove(HalDevice * device,const char * key)89418c2aff7Sartem hal_device_property_remove (HalDevice *device, const char *key)
89518c2aff7Sartem {
89618c2aff7Sartem 	HalProperty *prop;
89718c2aff7Sartem 
89818c2aff7Sartem 	prop = hal_device_property_find (device, key);
89918c2aff7Sartem 
90018c2aff7Sartem 	if (prop == NULL)
90118c2aff7Sartem 		return FALSE;
90218c2aff7Sartem 
90318c2aff7Sartem 	device->properties = g_slist_remove (device->properties, prop);
90418c2aff7Sartem 
90518c2aff7Sartem 	hal_property_free (prop);
90618c2aff7Sartem 
90718c2aff7Sartem 	g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
90818c2aff7Sartem 		       key, TRUE, FALSE);
90918c2aff7Sartem 
91018c2aff7Sartem 	return TRUE;
91118c2aff7Sartem }
91218c2aff7Sartem 
91318c2aff7Sartem gboolean
hal_device_property_set_attribute(HalDevice * device,const char * key,enum PropertyAttribute attr,gboolean val)91418c2aff7Sartem hal_device_property_set_attribute (HalDevice *device,
91518c2aff7Sartem 				   const char *key,
91618c2aff7Sartem 				   enum PropertyAttribute attr,
91718c2aff7Sartem 				   gboolean val)
91818c2aff7Sartem {
91918c2aff7Sartem 	HalProperty *prop;
92018c2aff7Sartem 
92118c2aff7Sartem 	prop = hal_device_property_find (device, key);
92218c2aff7Sartem 
92318c2aff7Sartem 	if (prop == NULL)
92418c2aff7Sartem 		return FALSE;
92518c2aff7Sartem 
92618c2aff7Sartem 	return TRUE;
92718c2aff7Sartem }
92818c2aff7Sartem 
92918c2aff7Sartem void
hal_device_print(HalDevice * device)93018c2aff7Sartem hal_device_print (HalDevice *device)
93118c2aff7Sartem {
93218c2aff7Sartem 	GSList *iter;
93318c2aff7Sartem 
93418c2aff7Sartem         fprintf (stderr, "device udi = %s\n", hal_device_get_udi (device));
93518c2aff7Sartem 
93618c2aff7Sartem 	for (iter = device->properties; iter != NULL; iter = iter->next) {
93718c2aff7Sartem 		HalProperty *p = iter->data;
93818c2aff7Sartem                 int type;
93918c2aff7Sartem                 const char *key;
94018c2aff7Sartem 
94118c2aff7Sartem                 key = hal_property_get_key (p);
94218c2aff7Sartem                 type = hal_property_get_type (p);
94318c2aff7Sartem 
94418c2aff7Sartem                 switch (type) {
94518c2aff7Sartem                 case HAL_PROPERTY_TYPE_STRING:
94618c2aff7Sartem                         fprintf (stderr, "  %s = '%s'  (string)\n", key,
94718c2aff7Sartem                                 hal_property_get_string (p));
94818c2aff7Sartem                         break;
94918c2aff7Sartem 
95018c2aff7Sartem                 case HAL_PROPERTY_TYPE_INT32:
95118c2aff7Sartem                         fprintf (stderr, "  %s = %d  0x%x  (int)\n", key,
95218c2aff7Sartem                                 hal_property_get_int (p),
95318c2aff7Sartem                                 hal_property_get_int (p));
95418c2aff7Sartem                         break;
95518c2aff7Sartem 
95618c2aff7Sartem                 case HAL_PROPERTY_TYPE_UINT64:
95718c2aff7Sartem                         fprintf (stderr, "  %s = %llu  0x%llx  (uint64)\n", key,
95818c2aff7Sartem                                 (long long unsigned int) hal_property_get_uint64 (p),
95918c2aff7Sartem                                 (long long unsigned int) hal_property_get_uint64 (p));
96018c2aff7Sartem                         break;
96118c2aff7Sartem 
96218c2aff7Sartem                 case HAL_PROPERTY_TYPE_DOUBLE:
96318c2aff7Sartem                         fprintf (stderr, "  %s = %g  (double)\n", key,
96418c2aff7Sartem                                 hal_property_get_double (p));
96518c2aff7Sartem                         break;
96618c2aff7Sartem 
96718c2aff7Sartem                 case HAL_PROPERTY_TYPE_BOOLEAN:
96818c2aff7Sartem                         fprintf (stderr, "  %s = %s  (bool)\n", key,
96918c2aff7Sartem                                 (hal_property_get_bool (p) ? "true" :
97018c2aff7Sartem                                  "false"));
97118c2aff7Sartem                         break;
97218c2aff7Sartem 
97318c2aff7Sartem                 default:
97418c2aff7Sartem                         HAL_WARNING (("Unknown property type %d", type));
97518c2aff7Sartem                         break;
97618c2aff7Sartem                 }
97718c2aff7Sartem         }
97818c2aff7Sartem         fprintf (stderr, "\n");
97918c2aff7Sartem }
98018c2aff7Sartem 
98118c2aff7Sartem 
98218c2aff7Sartem typedef struct {
98318c2aff7Sartem 	char *key;
98418c2aff7Sartem 	HalDevice *device;
98518c2aff7Sartem 	HalDeviceAsyncCallback callback;
98618c2aff7Sartem 	gpointer user_data;
98718c2aff7Sartem 
98818c2aff7Sartem 	guint prop_signal_id;
98918c2aff7Sartem 	guint timeout_id;
99018c2aff7Sartem } AsyncMatchInfo;
99118c2aff7Sartem 
99218c2aff7Sartem static void
destroy_async_match_info(AsyncMatchInfo * ai)99318c2aff7Sartem destroy_async_match_info (AsyncMatchInfo *ai)
99418c2aff7Sartem {
99518c2aff7Sartem 	g_free (ai->key);
99618c2aff7Sartem 	g_signal_handler_disconnect (ai->device, ai->prop_signal_id);
99718c2aff7Sartem 	g_source_remove (ai->timeout_id);
99818c2aff7Sartem 	g_object_unref (ai->device);
99918c2aff7Sartem 	g_free (ai);
100018c2aff7Sartem }
100118c2aff7Sartem 
100218c2aff7Sartem static void
prop_changed_cb(HalDevice * device,const char * key,gboolean removed,gboolean added,gpointer user_data)100318c2aff7Sartem prop_changed_cb (HalDevice *device, const char *key,
100418c2aff7Sartem 		 gboolean removed, gboolean added, gpointer user_data)
100518c2aff7Sartem {
100618c2aff7Sartem 	AsyncMatchInfo *ai = user_data;
100718c2aff7Sartem 
100818c2aff7Sartem 	if (strcmp (key, ai->key) != 0)
100918c2aff7Sartem 		return;
101018c2aff7Sartem 
101118c2aff7Sartem 	/* the property is no longer there */
101218c2aff7Sartem 	if (removed)
101318c2aff7Sartem 		goto cleanup;
101418c2aff7Sartem 
101518c2aff7Sartem 
101618c2aff7Sartem 	ai->callback (ai->device, ai->user_data, TRUE);
101718c2aff7Sartem 
101818c2aff7Sartem cleanup:
101918c2aff7Sartem 	destroy_async_match_info (ai);
102018c2aff7Sartem }
102118c2aff7Sartem 
102218c2aff7Sartem 
102318c2aff7Sartem static gboolean
async_wait_timeout(gpointer user_data)102418c2aff7Sartem async_wait_timeout (gpointer user_data)
102518c2aff7Sartem {
102618c2aff7Sartem 	AsyncMatchInfo *ai = (AsyncMatchInfo *) user_data;
102718c2aff7Sartem 
102818c2aff7Sartem 	ai->callback (ai->device, ai->user_data, FALSE);
102918c2aff7Sartem 
103018c2aff7Sartem 	destroy_async_match_info (ai);
103118c2aff7Sartem 
103218c2aff7Sartem 	return FALSE;
103318c2aff7Sartem }
103418c2aff7Sartem 
103518c2aff7Sartem void
hal_device_async_wait_property(HalDevice * device,const char * key,HalDeviceAsyncCallback callback,gpointer user_data,int timeout)103618c2aff7Sartem hal_device_async_wait_property (HalDevice    *device,
103718c2aff7Sartem 				const char   *key,
103818c2aff7Sartem 				HalDeviceAsyncCallback callback,
103918c2aff7Sartem 				gpointer     user_data,
104018c2aff7Sartem 				int          timeout)
104118c2aff7Sartem {
104218c2aff7Sartem 	HalProperty *prop;
104318c2aff7Sartem 	AsyncMatchInfo *ai;
104418c2aff7Sartem 
104518c2aff7Sartem 	/* check if property already exists */
104618c2aff7Sartem 	prop = hal_device_property_find (device, key);
104718c2aff7Sartem 
104818c2aff7Sartem 	if (prop != NULL || timeout==0) {
104918c2aff7Sartem 		callback (device, user_data, prop != NULL);
105018c2aff7Sartem 		return;
105118c2aff7Sartem 	}
105218c2aff7Sartem 
105318c2aff7Sartem 	ai = g_new0 (AsyncMatchInfo, 1);
105418c2aff7Sartem 
105518c2aff7Sartem 	ai->device = g_object_ref (device);
105618c2aff7Sartem 	ai->key = g_strdup (key);
105718c2aff7Sartem 	ai->callback = callback;
105818c2aff7Sartem 	ai->user_data = user_data;
105918c2aff7Sartem 
106018c2aff7Sartem 	ai->prop_signal_id = g_signal_connect (device, "property_changed",
106118c2aff7Sartem 					       G_CALLBACK (prop_changed_cb),
106218c2aff7Sartem 					       ai);
106318c2aff7Sartem 
106418c2aff7Sartem 	ai->timeout_id = g_timeout_add (timeout, async_wait_timeout, ai);
106518c2aff7Sartem }
106618c2aff7Sartem 
106718c2aff7Sartem void
hal_device_callouts_finished(HalDevice * device)106818c2aff7Sartem hal_device_callouts_finished (HalDevice *device)
106918c2aff7Sartem {
107018c2aff7Sartem 	g_signal_emit (device, signals[CALLOUTS_FINISHED], 0);
107118c2aff7Sartem }
107218c2aff7Sartem 
107318c2aff7Sartem /** Used when giving up on a device, e.g. if no device file appeared
107418c2aff7Sartem  */
107518c2aff7Sartem void
hal_device_cancel(HalDevice * device)107618c2aff7Sartem hal_device_cancel (HalDevice *device)
107718c2aff7Sartem {
107818c2aff7Sartem 	HAL_INFO (("udi=%s", device->udi));
107918c2aff7Sartem 	g_signal_emit (device, signals[CANCELLED], 0);
108018c2aff7Sartem }
108118c2aff7Sartem 
108218c2aff7Sartem 
108318c2aff7Sartem 
108418c2aff7Sartem 
108518c2aff7Sartem GSList *
hal_device_property_get_strlist(HalDevice * device,const char * key)108618c2aff7Sartem hal_device_property_get_strlist (HalDevice    *device,
108718c2aff7Sartem 				 const char   *key)
108818c2aff7Sartem {
108918c2aff7Sartem 	HalProperty *prop;
109018c2aff7Sartem 
109118c2aff7Sartem 	g_return_val_if_fail (device != NULL, NULL);
109218c2aff7Sartem 	g_return_val_if_fail (key != NULL, NULL);
109318c2aff7Sartem 
109418c2aff7Sartem 	prop = hal_device_property_find (device, key);
109518c2aff7Sartem 
109618c2aff7Sartem 	if (prop != NULL)
109718c2aff7Sartem 		return hal_property_get_strlist (prop);
109818c2aff7Sartem 	else
109918c2aff7Sartem 		return NULL;
110018c2aff7Sartem }
110118c2aff7Sartem 
110218c2aff7Sartem const char *
hal_device_property_get_strlist_elem(HalDevice * device,const char * key,guint index)110318c2aff7Sartem hal_device_property_get_strlist_elem (HalDevice    *device,
110418c2aff7Sartem 				      const char   *key,
110518c2aff7Sartem 				      guint index)
110618c2aff7Sartem {
110718c2aff7Sartem 	GSList *strlist;
110818c2aff7Sartem 	GSList *i;
110918c2aff7Sartem 
111018c2aff7Sartem 	strlist = hal_device_property_get_strlist (device, key);
111118c2aff7Sartem 	if (strlist == NULL)
111218c2aff7Sartem 		return NULL;
111318c2aff7Sartem 
111418c2aff7Sartem 	i = g_slist_nth (strlist, index);
111518c2aff7Sartem 	if (i == NULL)
111618c2aff7Sartem 		return NULL;
111718c2aff7Sartem 
111818c2aff7Sartem 	return (const char *) i->data;
111918c2aff7Sartem }
112018c2aff7Sartem 
112118c2aff7Sartem gboolean
hal_device_property_strlist_append(HalDevice * device,const char * key,const char * value)112218c2aff7Sartem hal_device_property_strlist_append (HalDevice    *device,
112318c2aff7Sartem 				    const char   *key,
112418c2aff7Sartem 				    const char *value)
112518c2aff7Sartem {
112618c2aff7Sartem 	HalProperty *prop;
112718c2aff7Sartem 
112818c2aff7Sartem 	/* check if property already exists */
112918c2aff7Sartem 	prop = hal_device_property_find (device, key);
113018c2aff7Sartem 
113118c2aff7Sartem 	if (prop != NULL) {
113218c2aff7Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
113318c2aff7Sartem 			return FALSE;
113418c2aff7Sartem 
113518c2aff7Sartem 		hal_property_strlist_append (prop, value);
113618c2aff7Sartem 
113718c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
113818c2aff7Sartem 			       key, FALSE, FALSE);
113918c2aff7Sartem 
114018c2aff7Sartem 	} else {
114118c2aff7Sartem 		prop = hal_property_new_strlist (key);
114218c2aff7Sartem 		hal_property_strlist_append (prop, value);
114318c2aff7Sartem 
114418c2aff7Sartem 		device->properties = g_slist_prepend (device->properties, prop);
114518c2aff7Sartem 
114618c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
114718c2aff7Sartem 			       key, FALSE, TRUE);
114818c2aff7Sartem 	}
114918c2aff7Sartem 
115018c2aff7Sartem 	return TRUE;
115118c2aff7Sartem }
115218c2aff7Sartem 
115318c2aff7Sartem gboolean
hal_device_property_strlist_prepend(HalDevice * device,const char * key,const char * value)115418c2aff7Sartem hal_device_property_strlist_prepend (HalDevice    *device,
115518c2aff7Sartem 				     const char   *key,
115618c2aff7Sartem 				     const char *value)
115718c2aff7Sartem {
115818c2aff7Sartem 	HalProperty *prop;
115918c2aff7Sartem 
116018c2aff7Sartem 	/* check if property already exists */
116118c2aff7Sartem 	prop = hal_device_property_find (device, key);
116218c2aff7Sartem 
116318c2aff7Sartem 	if (prop != NULL) {
116418c2aff7Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
116518c2aff7Sartem 			return FALSE;
116618c2aff7Sartem 
116718c2aff7Sartem 		hal_property_strlist_prepend (prop, value);
116818c2aff7Sartem 
116918c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
117018c2aff7Sartem 			       key, FALSE, FALSE);
117118c2aff7Sartem 
117218c2aff7Sartem 	} else {
117318c2aff7Sartem 		prop = hal_property_new_strlist (key);
117418c2aff7Sartem 		hal_property_strlist_prepend (prop, value);
117518c2aff7Sartem 
117618c2aff7Sartem 		device->properties = g_slist_prepend (device->properties, prop);
117718c2aff7Sartem 
117818c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
117918c2aff7Sartem 			       key, FALSE, TRUE);
118018c2aff7Sartem 	}
118118c2aff7Sartem 
118218c2aff7Sartem 	return TRUE;
118318c2aff7Sartem }
118418c2aff7Sartem 
118518c2aff7Sartem gboolean
hal_device_property_strlist_remove_elem(HalDevice * device,const char * key,guint index)118618c2aff7Sartem hal_device_property_strlist_remove_elem (HalDevice    *device,
118718c2aff7Sartem 					 const char   *key,
118818c2aff7Sartem 					 guint index)
118918c2aff7Sartem {
119018c2aff7Sartem 	HalProperty *prop;
119118c2aff7Sartem 
119218c2aff7Sartem 	/* check if property already exists */
119318c2aff7Sartem 	prop = hal_device_property_find (device, key);
119418c2aff7Sartem 
119518c2aff7Sartem 	if (prop == NULL)
119618c2aff7Sartem 		return FALSE;
119718c2aff7Sartem 
119818c2aff7Sartem 	if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
119918c2aff7Sartem 		return FALSE;
120018c2aff7Sartem 
120118c2aff7Sartem 	if (hal_property_strlist_remove_elem (prop, index)) {
120218c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
120318c2aff7Sartem 			       key, FALSE, FALSE);
120418c2aff7Sartem 		return TRUE;
120518c2aff7Sartem 	}
120618c2aff7Sartem 
120718c2aff7Sartem 	return FALSE;
120818c2aff7Sartem }
120918c2aff7Sartem 
121018c2aff7Sartem gboolean
hal_device_property_strlist_clear(HalDevice * device,const char * key)121118c2aff7Sartem hal_device_property_strlist_clear (HalDevice    *device,
121218c2aff7Sartem 				   const char   *key)
121318c2aff7Sartem {
121418c2aff7Sartem 	HalProperty *prop;
121518c2aff7Sartem 
121618c2aff7Sartem 	/* check if property already exists */
121718c2aff7Sartem 	prop = hal_device_property_find (device, key);
121818c2aff7Sartem 
121918c2aff7Sartem 	if (prop == NULL) {
122018c2aff7Sartem 		prop = hal_property_new_strlist (key);
122118c2aff7Sartem 
122218c2aff7Sartem 		device->properties = g_slist_prepend (device->properties, prop);
122318c2aff7Sartem 
122418c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
122518c2aff7Sartem 			       key, FALSE, TRUE);
122618c2aff7Sartem 
122718c2aff7Sartem 		return TRUE;
122818c2aff7Sartem 	}
122918c2aff7Sartem 
123018c2aff7Sartem 	if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
123118c2aff7Sartem 		return FALSE;
123218c2aff7Sartem 
123318c2aff7Sartem 	if (hal_property_strlist_clear (prop)) {
123418c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
123518c2aff7Sartem 			       key, FALSE, FALSE);
123618c2aff7Sartem 		return TRUE;
123718c2aff7Sartem 	}
123818c2aff7Sartem 
123918c2aff7Sartem 	return FALSE;
124018c2aff7Sartem }
124118c2aff7Sartem 
124218c2aff7Sartem 
124318c2aff7Sartem gboolean
hal_device_property_strlist_add(HalDevice * device,const char * key,const char * value)124418c2aff7Sartem hal_device_property_strlist_add (HalDevice *device,
124518c2aff7Sartem 				 const char *key,
124618c2aff7Sartem 				 const char *value)
124718c2aff7Sartem {
124818c2aff7Sartem 	HalProperty *prop;
124918c2aff7Sartem 	gboolean res;
125018c2aff7Sartem 
125118c2aff7Sartem 	res = FALSE;
125218c2aff7Sartem 
125318c2aff7Sartem 	/* check if property already exists */
125418c2aff7Sartem 	prop = hal_device_property_find (device, key);
125518c2aff7Sartem 
125618c2aff7Sartem 	if (prop != NULL) {
125718c2aff7Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
125818c2aff7Sartem 			goto out;
125918c2aff7Sartem 
126018c2aff7Sartem 		res = hal_property_strlist_add (prop, value);
126118c2aff7Sartem 		if (res) {
126218c2aff7Sartem 			g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
126318c2aff7Sartem 				       key, FALSE, FALSE);
126418c2aff7Sartem 		}
126518c2aff7Sartem 
126618c2aff7Sartem 	} else {
126718c2aff7Sartem 		prop = hal_property_new_strlist (key);
126818c2aff7Sartem 		hal_property_strlist_prepend (prop, value);
126918c2aff7Sartem 
127018c2aff7Sartem 		device->properties = g_slist_prepend (device->properties, prop);
127118c2aff7Sartem 
127218c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
127318c2aff7Sartem 			       key, FALSE, TRUE);
127418c2aff7Sartem 
127518c2aff7Sartem 		res = TRUE;
127618c2aff7Sartem 	}
127718c2aff7Sartem 
127818c2aff7Sartem out:
127918c2aff7Sartem 	return res;
128018c2aff7Sartem }
128118c2aff7Sartem 
128218c2aff7Sartem gboolean
hal_device_property_strlist_remove(HalDevice * device,const char * key,const char * value)128318c2aff7Sartem hal_device_property_strlist_remove (HalDevice *device,
128418c2aff7Sartem 				    const char *key,
128518c2aff7Sartem 				    const char *value)
128618c2aff7Sartem {
128718c2aff7Sartem 	HalProperty *prop;
128818c2aff7Sartem 
128918c2aff7Sartem 	/* check if property already exists */
129018c2aff7Sartem 	prop = hal_device_property_find (device, key);
129118c2aff7Sartem 
129218c2aff7Sartem 	if (prop == NULL)
129318c2aff7Sartem 		return FALSE;
129418c2aff7Sartem 
129518c2aff7Sartem 	if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
129618c2aff7Sartem 		return FALSE;
129718c2aff7Sartem 
129818c2aff7Sartem 	if (hal_property_strlist_remove (prop, value)) {
129918c2aff7Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
130018c2aff7Sartem 			       key, FALSE, FALSE);
130118c2aff7Sartem 	}
130218c2aff7Sartem 
130318c2aff7Sartem 	return TRUE;
130418c2aff7Sartem }
130518c2aff7Sartem 
130618c2aff7Sartem gboolean
hal_device_property_strlist_is_empty(HalDevice * device,const char * key)130718c2aff7Sartem hal_device_property_strlist_is_empty (HalDevice    *device,
130818c2aff7Sartem 				      const char   *key)
130918c2aff7Sartem {
131018c2aff7Sartem 	GSList *strlist;
131118c2aff7Sartem 
131218c2aff7Sartem 	if ( hal_device_has_property (device, key)) {
131318c2aff7Sartem 		strlist = hal_device_property_get_strlist (device, key);
131418c2aff7Sartem 		if (strlist == NULL )
131518c2aff7Sartem 			return TRUE;
131618c2aff7Sartem 
131718c2aff7Sartem 		if (g_slist_length (strlist) > 0)
131818c2aff7Sartem 			return FALSE;
131918c2aff7Sartem 		else
132018c2aff7Sartem 			return TRUE;
132118c2aff7Sartem 	}
132218c2aff7Sartem 	return FALSE;
132318c2aff7Sartem }
132418c2aff7Sartem 
132518c2aff7Sartem void
hal_device_inc_num_addons(HalDevice * device)132618c2aff7Sartem hal_device_inc_num_addons (HalDevice *device)
132718c2aff7Sartem {
132818c2aff7Sartem 	device->num_addons++;
132918c2aff7Sartem }
133018c2aff7Sartem 
133118c2aff7Sartem gboolean
hal_device_inc_num_ready_addons(HalDevice * device)133218c2aff7Sartem hal_device_inc_num_ready_addons (HalDevice *device)
133318c2aff7Sartem {
133418c2aff7Sartem 	if (hal_device_are_all_addons_ready (device)) {
133518c2aff7Sartem 		HAL_ERROR (("In hal_device_inc_num_ready_addons for udi=%s but all addons are already ready!",
133618c2aff7Sartem 			    device->udi));
133718c2aff7Sartem 		return FALSE;
133818c2aff7Sartem 	}
133918c2aff7Sartem 
134018c2aff7Sartem 	device->num_addons_ready++;
134118c2aff7Sartem 	return TRUE;
134218c2aff7Sartem }
134318c2aff7Sartem 
134418c2aff7Sartem gboolean
hal_device_are_all_addons_ready(HalDevice * device)134518c2aff7Sartem hal_device_are_all_addons_ready (HalDevice *device)
134618c2aff7Sartem {
134718c2aff7Sartem 	if (device->num_addons_ready == device->num_addons) {
134818c2aff7Sartem 		return TRUE;
134918c2aff7Sartem 	} else {
135018c2aff7Sartem 		return FALSE;
135118c2aff7Sartem 	}
135218c2aff7Sartem }
1353