xref: /onnv-gate/usr/src/cmd/hal/hald/device.c (revision 8100:1c162fabbdb8)
12912Sartem /***************************************************************************
22912Sartem  * CVSID: $Id$
32912Sartem  *
42912Sartem  * device.c : HalDevice methods
52912Sartem  *
62912Sartem  * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
72912Sartem  * Copyright (C) 2004 Novell, Inc.
82912Sartem  *
92912Sartem  * Licensed under the Academic Free License version 2.1
102912Sartem  *
112912Sartem  * This program is free software; you can redistribute it and/or modify
122912Sartem  * it under the terms of the GNU General Public License as published by
132912Sartem  * the Free Software Foundation; either version 2 of the License, or
142912Sartem  * (at your option) any later version.
152912Sartem  *
162912Sartem  * This program is distributed in the hope that it will be useful,
172912Sartem  * but WITHOUT ANY WARRANTY; without even the implied warranty of
182912Sartem  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
192912Sartem  * GNU General Public License for more details.
202912Sartem  *
212912Sartem  * You should have received a copy of the GNU General Public License
222912Sartem  * along with this program; if not, write to the Free Software
232912Sartem  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
242912Sartem  *
252912Sartem  **************************************************************************/
262912Sartem 
272912Sartem #ifdef HAVE_CONFIG_H
282912Sartem #  include <config.h>
292912Sartem #endif
302912Sartem 
312912Sartem #include <stdio.h>
322912Sartem #include <string.h>
332912Sartem 
342912Sartem #include "hald.h"
352912Sartem #include "device.h"
362912Sartem #include "hald_marshal.h"
372912Sartem #include "logger.h"
382912Sartem #include "hald_runner.h"
392912Sartem 
402912Sartem static GObjectClass *parent_class;
412912Sartem 
422912Sartem enum {
432912Sartem 	PROPERTY_CHANGED,
442912Sartem 	CAPABILITY_ADDED,
452912Sartem 	CALLOUTS_FINISHED,
462912Sartem 	CANCELLED,
472912Sartem 	LAST_SIGNAL
482912Sartem };
492912Sartem 
502912Sartem static guint signals[LAST_SIGNAL] = { 0 };
512912Sartem 
522912Sartem #ifdef HALD_MEMLEAK_DBG
532912Sartem int dbg_hal_device_object_delta = 0;
542912Sartem #endif
552912Sartem 
562912Sartem static void
hal_device_finalize(GObject * obj)572912Sartem hal_device_finalize (GObject *obj)
582912Sartem {
592912Sartem 	HalDevice *device = HAL_DEVICE (obj);
602912Sartem 
612912Sartem 	runner_device_finalized (device);
622912Sartem 
632912Sartem #ifdef HALD_MEMLEAK_DBG
642912Sartem 	dbg_hal_device_object_delta--;
652912Sartem 	printf ("************* in finalize for udi=%s\n", device->udi);
662912Sartem #endif
672912Sartem 
682912Sartem 
692912Sartem 	g_slist_foreach (device->properties, (GFunc) hal_property_free, NULL);
702912Sartem 
71*8100SLin.Guo@Sun.COM 	g_slist_free (device->properties);
72*8100SLin.Guo@Sun.COM 
732912Sartem 	g_free (device->udi);
742912Sartem 
752912Sartem 	if (parent_class->finalize)
762912Sartem 		parent_class->finalize (obj);
772912Sartem 
782912Sartem }
792912Sartem 
802912Sartem static void
hal_device_class_init(HalDeviceClass * klass)812912Sartem hal_device_class_init (HalDeviceClass *klass)
822912Sartem {
832912Sartem 	GObjectClass *obj_class = (GObjectClass *) klass;
842912Sartem 
852912Sartem 	parent_class = g_type_class_peek_parent (klass);
862912Sartem 
872912Sartem 	obj_class->finalize = hal_device_finalize;
882912Sartem 
892912Sartem 	signals[PROPERTY_CHANGED] =
902912Sartem 		g_signal_new ("property_changed",
912912Sartem 			      G_TYPE_FROM_CLASS (klass),
922912Sartem 			      G_SIGNAL_RUN_LAST,
932912Sartem 			      G_STRUCT_OFFSET (HalDeviceClass,
942912Sartem 					       property_changed),
952912Sartem 			      NULL, NULL,
962912Sartem 			      hald_marshal_VOID__STRING_BOOL_BOOL,
972912Sartem 			      G_TYPE_NONE, 3,
982912Sartem 			      G_TYPE_STRING,
992912Sartem 			      G_TYPE_BOOLEAN,
1002912Sartem 			      G_TYPE_BOOLEAN);
1012912Sartem 
1022912Sartem 	signals[CAPABILITY_ADDED] =
1032912Sartem 		g_signal_new ("capability_added",
1042912Sartem 			      G_TYPE_FROM_CLASS (klass),
1052912Sartem 			      G_SIGNAL_RUN_LAST,
1062912Sartem 			      G_STRUCT_OFFSET (HalDeviceClass,
1072912Sartem 					       capability_added),
1082912Sartem 			      NULL, NULL,
1092912Sartem 			      hald_marshal_VOID__STRING,
1102912Sartem 			      G_TYPE_NONE, 1,
1112912Sartem 			      G_TYPE_STRING);
1122912Sartem 
1132912Sartem 	signals[CALLOUTS_FINISHED] =
1142912Sartem 		g_signal_new ("callouts_finished",
1152912Sartem 			      G_TYPE_FROM_CLASS (klass),
1162912Sartem 			      G_SIGNAL_RUN_LAST,
1172912Sartem 			      G_STRUCT_OFFSET (HalDeviceClass,
1182912Sartem 					       callouts_finished),
1192912Sartem 			      NULL, NULL,
1202912Sartem 			      hald_marshal_VOID__VOID,
1212912Sartem 			      G_TYPE_NONE, 0);
1222912Sartem 
1232912Sartem 	signals[CANCELLED] =
1242912Sartem 		g_signal_new ("cancelled",
1252912Sartem 			      G_TYPE_FROM_CLASS (klass),
1262912Sartem 			      G_SIGNAL_RUN_LAST,
1272912Sartem 			      G_STRUCT_OFFSET (HalDeviceClass,
1282912Sartem 					       cancelled),
1292912Sartem 			      NULL, NULL,
1302912Sartem 			      hald_marshal_VOID__VOID,
1312912Sartem 			      G_TYPE_NONE, 0);
1322912Sartem }
1332912Sartem 
1342912Sartem static void
hal_device_init(HalDevice * device)1352912Sartem hal_device_init (HalDevice *device)
1362912Sartem {
1372912Sartem 	static int temp_device_counter = 0;
1382912Sartem 
1392912Sartem 	device->udi = g_strdup_printf ("/org/freedesktop/Hal/devices/temp/%d",
1402912Sartem 				       temp_device_counter++);
1412912Sartem 	device->num_addons = 0;
1422912Sartem 	device->num_addons_ready = 0;
1432912Sartem }
1442912Sartem 
1452912Sartem GType
hal_device_get_type(void)1462912Sartem hal_device_get_type (void)
1472912Sartem {
1482912Sartem 	static GType type = 0;
1492912Sartem 
1502912Sartem 	if (!type) {
1512912Sartem 		static GTypeInfo type_info = {
1522912Sartem 			sizeof (HalDeviceClass),
1532912Sartem 			NULL, NULL,
1542912Sartem 			(GClassInitFunc) hal_device_class_init,
1552912Sartem 			NULL, NULL,
1562912Sartem 			sizeof (HalDevice),
1572912Sartem 			0,
1582912Sartem 			(GInstanceInitFunc) hal_device_init,
1592912Sartem 			NULL
1602912Sartem 		};
1612912Sartem 
1622912Sartem 		type = g_type_register_static (G_TYPE_OBJECT,
1632912Sartem 					       "HalDevice",
1642912Sartem 					       &type_info,
1652912Sartem 					       0);
1662912Sartem 	}
1672912Sartem 
1682912Sartem 	return type;
1692912Sartem }
1702912Sartem 
1712912Sartem 
1722912Sartem HalDevice *
hal_device_new(void)1732912Sartem hal_device_new (void)
1742912Sartem {
1752912Sartem 	HalDevice *device;
1762912Sartem 
1772912Sartem 	device = g_object_new (HAL_TYPE_DEVICE, NULL, NULL);
1782912Sartem 
1792912Sartem #ifdef HALD_MEMLEAK_DBG
1802912Sartem 	dbg_hal_device_object_delta++;
1812912Sartem #endif
1822912Sartem 	return device;
1832912Sartem }
1842912Sartem 
1852912Sartem /** Merge all properties from source where the key starts with
1862912Sartem  *  source_namespace and put them onto target replacing source_namespace
1872912Sartem  *  with target_namespace
1882912Sartem  *
1892912Sartem  *  @param  target              Device to put properties onto
1902912Sartem  *  @param  source              Device to retrieve properties from
1912912Sartem  *  @param  target_namespace    Replace source namespace with this namespace
1922912Sartem  *  @param  source_namespace    Source namespace that property keys must match
1932912Sartem  */
1942912Sartem void
hal_device_merge_with_rewrite(HalDevice * target,HalDevice * source,const char * target_namespace,const char * source_namespace)1952912Sartem hal_device_merge_with_rewrite  (HalDevice    *target,
1962912Sartem 				HalDevice    *source,
1972912Sartem 				const char   *target_namespace,
1982912Sartem 				const char   *source_namespace)
1992912Sartem {
2002912Sartem 	GSList *iter;
2012912Sartem 	size_t source_ns_len;
2022912Sartem 
2032912Sartem 	source_ns_len = strlen (source_namespace);
2042912Sartem 
2052912Sartem 	/* doesn't handle info.capabilities */
2062912Sartem 
2072912Sartem 	/* device_property_atomic_update_begin (); */
2082912Sartem 
2092912Sartem 	for (iter = source->properties; iter != NULL; iter = iter->next) {
2102912Sartem 		HalProperty *p = iter->data;
2112912Sartem 		int type;
2122912Sartem 		const char *key;
2132912Sartem 		int target_type;
2142912Sartem 		gchar *target_key;
2152912Sartem 
2162912Sartem 		key = hal_property_get_key (p);
2172912Sartem 
2182912Sartem 		/* only care about properties that match source namespace */
2192912Sartem 		if (strncmp(key, source_namespace, source_ns_len) != 0)
2202912Sartem 			continue;
2212912Sartem 
2222912Sartem 		target_key = g_strdup_printf("%s%s", target_namespace,
2232912Sartem 					     key+source_ns_len);
2242912Sartem 
2252912Sartem 		type = hal_property_get_type (p);
2262912Sartem 
2272912Sartem 		/* only remove target if it exists with a different type */
2282912Sartem 		target_type = hal_device_property_get_type (target, key);
2292912Sartem 		if (target_type != HAL_PROPERTY_TYPE_INVALID && target_type != type)
2302912Sartem 			hal_device_property_remove (target, key);
2312912Sartem 
2322912Sartem 		switch (type) {
2332912Sartem 
2342912Sartem 		case HAL_PROPERTY_TYPE_STRING:
2352912Sartem 			hal_device_property_set_string (
2362912Sartem 				target, target_key,
2372912Sartem 				hal_property_get_string (p));
2382912Sartem 			break;
2392912Sartem 
2402912Sartem 		case HAL_PROPERTY_TYPE_INT32:
2412912Sartem 			hal_device_property_set_int (
2422912Sartem 				target, target_key,
2432912Sartem 				hal_property_get_int (p));
2442912Sartem 			break;
2452912Sartem 
2462912Sartem 		case HAL_PROPERTY_TYPE_UINT64:
2472912Sartem 			hal_device_property_set_uint64 (
2482912Sartem 				target, target_key,
2492912Sartem 				hal_property_get_uint64 (p));
2502912Sartem 			break;
2512912Sartem 
2522912Sartem 		case HAL_PROPERTY_TYPE_BOOLEAN:
2532912Sartem 			hal_device_property_set_bool (
2542912Sartem 				target, target_key,
2552912Sartem 				hal_property_get_bool (p));
2562912Sartem 			break;
2572912Sartem 
2582912Sartem 		case HAL_PROPERTY_TYPE_DOUBLE:
2592912Sartem 			hal_device_property_set_double (
2602912Sartem 				target, target_key,
2612912Sartem 				hal_property_get_double (p));
2622912Sartem 			break;
2632912Sartem 
2642912Sartem 		default:
2652912Sartem 			HAL_WARNING (("Unknown property type %d", type));
2662912Sartem 			break;
2672912Sartem 		}
2682912Sartem 
2692912Sartem 		g_free (target_key);
2702912Sartem 	}
2712912Sartem 
2722912Sartem 	/* device_property_atomic_update_end (); */
2732912Sartem 
2742912Sartem }
2752912Sartem 
2762912Sartem void
hal_device_merge(HalDevice * target,HalDevice * source)2772912Sartem hal_device_merge (HalDevice *target, HalDevice *source)
2782912Sartem {
2792912Sartem 	GSList *iter;
2802912Sartem 	GSList *caps;
2812912Sartem 
2822912Sartem 	/* device_property_atomic_update_begin (); */
2832912Sartem 
2842912Sartem 	for (iter = source->properties; iter != NULL; iter = iter->next) {
2852912Sartem 		HalProperty *p = iter->data;
2862912Sartem 		int type;
2872912Sartem 		const char *key;
2882912Sartem 		int target_type;
2892912Sartem 
2902912Sartem 		key = hal_property_get_key (p);
2912912Sartem 		type = hal_property_get_type (p);
2922912Sartem 
2932912Sartem 		/* handle info.capabilities in a special way */
2942912Sartem 		if (strcmp (key, "info.capabilities") == 0)
2952912Sartem 			continue;
2962912Sartem 
2972912Sartem 		/* only remove target if it exists with a different type */
2982912Sartem 		target_type = hal_device_property_get_type (target, key);
2992912Sartem 		if (target_type != HAL_PROPERTY_TYPE_INVALID && target_type != type)
3002912Sartem 			hal_device_property_remove (target, key);
3012912Sartem 
3022912Sartem 		switch (type) {
3032912Sartem 
3042912Sartem 		case HAL_PROPERTY_TYPE_STRING:
3052912Sartem 			hal_device_property_set_string (
3062912Sartem 				target, key,
3072912Sartem 				hal_property_get_string (p));
3082912Sartem 			break;
3092912Sartem 
3102912Sartem 		case HAL_PROPERTY_TYPE_INT32:
3112912Sartem 			hal_device_property_set_int (
3122912Sartem 				target, key,
3132912Sartem 				hal_property_get_int (p));
3142912Sartem 			break;
3152912Sartem 
3162912Sartem 		case HAL_PROPERTY_TYPE_UINT64:
3172912Sartem 			hal_device_property_set_uint64 (
3182912Sartem 				target, key,
3192912Sartem 				hal_property_get_uint64 (p));
3202912Sartem 			break;
3212912Sartem 
3222912Sartem 		case HAL_PROPERTY_TYPE_BOOLEAN:
3232912Sartem 			hal_device_property_set_bool (
3242912Sartem 				target, key,
3252912Sartem 				hal_property_get_bool (p));
3262912Sartem 			break;
3272912Sartem 
3282912Sartem 		case HAL_PROPERTY_TYPE_DOUBLE:
3292912Sartem 			hal_device_property_set_double (
3302912Sartem 				target, key,
3312912Sartem 				hal_property_get_double (p));
3322912Sartem 			break;
3332912Sartem 
3342912Sartem 		default:
3352912Sartem 			HAL_WARNING (("Unknown property type %d", type));
3362912Sartem 			break;
3372912Sartem 		}
3382912Sartem 	}
3392912Sartem 
3402912Sartem 	/* device_property_atomic_update_end (); */
3412912Sartem 
3422912Sartem 	caps = hal_device_property_get_strlist (source, "info.capabilities");
3432912Sartem 	for (iter = caps; iter != NULL; iter = iter->next) {
3442912Sartem 		if (!hal_device_has_capability (target, iter->data))
3452912Sartem 			hal_device_add_capability (target, iter->data);
3462912Sartem 	}
3472912Sartem }
3482912Sartem 
3492912Sartem gboolean
hal_device_matches(HalDevice * device1,HalDevice * device2,const char * namespace)3502912Sartem hal_device_matches (HalDevice *device1, HalDevice *device2,
3512912Sartem 		    const char *namespace)
3522912Sartem {
3532912Sartem 	int len;
3542912Sartem 	GSList *iter;
3552912Sartem 
3562912Sartem 	len = strlen (namespace);
3572912Sartem 
3582912Sartem 	for (iter = device1->properties; iter != NULL; iter = iter->next) {
3592912Sartem 		HalProperty *p;
3602912Sartem 		const char *key;
3612912Sartem 		int type;
3622912Sartem 
3632912Sartem 		p = (HalProperty *) iter->data;
3642912Sartem 		key = hal_property_get_key (p);
3652912Sartem 		type = hal_property_get_type (p);
3662912Sartem 
3672912Sartem 		if (strncmp (key, namespace, len) != 0)
3682912Sartem 			continue;
3692912Sartem 
3702912Sartem 		if (!hal_device_has_property (device2, key))
3712912Sartem 			return FALSE;
3722912Sartem 
3732912Sartem 		switch (type) {
3742912Sartem 
3752912Sartem 		case HAL_PROPERTY_TYPE_STRING:
3762912Sartem 			if (strcmp (hal_property_get_string (p),
3772912Sartem 				    hal_device_property_get_string (device2,
3782912Sartem 								    key)) != 0)
3792912Sartem 				return FALSE;
3802912Sartem 			break;
3812912Sartem 
3822912Sartem 		case HAL_PROPERTY_TYPE_INT32:
3832912Sartem 			if (hal_property_get_int (p) !=
3842912Sartem 			    hal_device_property_get_int (device2, key))
3852912Sartem 				return FALSE;
3862912Sartem 			break;
3872912Sartem 
3882912Sartem 		case HAL_PROPERTY_TYPE_UINT64:
3892912Sartem 			if (hal_property_get_uint64 (p) !=
3902912Sartem 				hal_device_property_get_uint64 (device2, key))
3912912Sartem 				return FALSE;
3922912Sartem 			break;
3932912Sartem 
3942912Sartem 		case HAL_PROPERTY_TYPE_BOOLEAN:
3952912Sartem 			if (hal_property_get_bool (p) !=
3962912Sartem 			    hal_device_property_get_bool (device2, key))
3972912Sartem 				return FALSE;
3982912Sartem 			break;
3992912Sartem 
4002912Sartem 		case HAL_PROPERTY_TYPE_DOUBLE:
4012912Sartem 			if (hal_property_get_double (p) !=
4022912Sartem 			    hal_device_property_get_double (device2, key))
4032912Sartem 				return FALSE;
4042912Sartem 			break;
4052912Sartem 
4062912Sartem 		default:
4072912Sartem 			HAL_WARNING (("Unknown property type %d", type));
4082912Sartem 			break;
4092912Sartem 		}
4102912Sartem 	}
4112912Sartem 
4122912Sartem 	return TRUE;
4132912Sartem }
4142912Sartem 
4152912Sartem const char *
hal_device_get_udi(HalDevice * device)4162912Sartem hal_device_get_udi (HalDevice *device)
4172912Sartem {
4182912Sartem 	return device->udi;
4192912Sartem }
4202912Sartem 
4212912Sartem void
hal_device_set_udi(HalDevice * device,const char * udi)4222912Sartem hal_device_set_udi (HalDevice *device, const char *udi)
4232912Sartem {
4242912Sartem 	if (device->udi != NULL)
4252912Sartem 		g_free (device->udi);
4262912Sartem 	device->udi = g_strdup (udi);
4272912Sartem }
4282912Sartem 
4292912Sartem void
hal_device_add_capability(HalDevice * device,const char * capability)4302912Sartem hal_device_add_capability (HalDevice *device, const char *capability)
4312912Sartem {
4322912Sartem 	if (hal_device_property_strlist_add (device, "info.capabilities", capability))
4332912Sartem 		g_signal_emit (device, signals[CAPABILITY_ADDED], 0, capability);
4342912Sartem }
4352912Sartem 
4362912Sartem gboolean
hal_device_has_capability(HalDevice * device,const char * capability)4372912Sartem hal_device_has_capability (HalDevice *device, const char *capability)
4382912Sartem {
4392912Sartem 	GSList *caps;
4402912Sartem 	GSList *iter;
4412912Sartem 	gboolean matched = FALSE;
4422912Sartem 
4432912Sartem 	caps = hal_device_property_get_strlist (device, "info.capabilities");
4442912Sartem 
4452912Sartem 	if (caps == NULL)
4462912Sartem 		return FALSE;
4472912Sartem 
4482912Sartem 	for (iter = caps; iter != NULL; iter = iter->next) {
4492912Sartem 		if (strcmp (iter->data, capability) == 0) {
4502912Sartem 			matched = TRUE;
4512912Sartem 			break;
4522912Sartem 		}
4532912Sartem 	}
4542912Sartem 
4552912Sartem 	return matched;
4562912Sartem }
4572912Sartem 
4582912Sartem gboolean
hal_device_has_property(HalDevice * device,const char * key)4592912Sartem hal_device_has_property (HalDevice *device, const char *key)
4602912Sartem {
4612912Sartem 	g_return_val_if_fail (device != NULL, FALSE);
4622912Sartem 	g_return_val_if_fail (key != NULL, FALSE);
4632912Sartem 
4642912Sartem 	return hal_device_property_find (device, key) != NULL;
4652912Sartem }
4662912Sartem 
4672912Sartem int
hal_device_num_properties(HalDevice * device)4682912Sartem hal_device_num_properties (HalDevice *device)
4692912Sartem {
4702912Sartem 	g_return_val_if_fail (device != NULL, -1);
4712912Sartem 
4722912Sartem 	return g_slist_length (device->properties);
4732912Sartem }
4742912Sartem 
4752912Sartem HalProperty *
hal_device_property_find(HalDevice * device,const char * key)4762912Sartem hal_device_property_find (HalDevice *device, const char *key)
4772912Sartem {
4782912Sartem 	GSList *iter;
4792912Sartem 
4802912Sartem 	g_return_val_if_fail (device != NULL, NULL);
4812912Sartem 	g_return_val_if_fail (key != NULL, NULL);
4822912Sartem 
4832912Sartem 	for (iter = device->properties; iter != NULL; iter = iter->next) {
4842912Sartem 		HalProperty *p = iter->data;
4852912Sartem 
4862912Sartem 		if (strcmp (hal_property_get_key (p), key) == 0)
4872912Sartem 			return p;
4882912Sartem 	}
4892912Sartem 
4902912Sartem 	return NULL;
4912912Sartem }
4922912Sartem 
4932912Sartem char *
hal_device_property_to_string(HalDevice * device,const char * key)4942912Sartem hal_device_property_to_string (HalDevice *device, const char *key)
4952912Sartem {
4962912Sartem 	HalProperty *prop;
4972912Sartem 
4982912Sartem 	prop = hal_device_property_find (device, key);
4992912Sartem 	if (!prop)
5002912Sartem 		return NULL;
5012912Sartem 
5022912Sartem 	return hal_property_to_string (prop);
5032912Sartem }
5042912Sartem 
5052912Sartem void
hal_device_property_foreach(HalDevice * device,HalDevicePropertyForeachFn callback,gpointer user_data)5062912Sartem hal_device_property_foreach (HalDevice *device,
5072912Sartem 			     HalDevicePropertyForeachFn callback,
5082912Sartem 			     gpointer user_data)
5092912Sartem {
5102912Sartem 	GSList *iter;
5112912Sartem 
5122912Sartem 	g_return_if_fail (device != NULL);
5132912Sartem 	g_return_if_fail (callback != NULL);
5142912Sartem 
5152912Sartem 	for (iter = device->properties; iter != NULL; iter = iter->next) {
5162912Sartem 		HalProperty *p = iter->data;
5172912Sartem 		gboolean cont;
5182912Sartem 
5192912Sartem 		cont = callback (device, p, user_data);
5202912Sartem 
5212912Sartem 		if (cont == FALSE)
5222912Sartem 			return;
5232912Sartem 	}
5242912Sartem }
5252912Sartem 
5262912Sartem int
hal_device_property_get_type(HalDevice * device,const char * key)5272912Sartem hal_device_property_get_type (HalDevice *device, const char *key)
5282912Sartem {
5292912Sartem 	HalProperty *prop;
5302912Sartem 
5312912Sartem 	g_return_val_if_fail (device != NULL, HAL_PROPERTY_TYPE_INVALID);
5322912Sartem 	g_return_val_if_fail (key != NULL, HAL_PROPERTY_TYPE_INVALID);
5332912Sartem 
5342912Sartem 	prop = hal_device_property_find (device, key);
5352912Sartem 
5362912Sartem 	if (prop != NULL)
5372912Sartem 		return hal_property_get_type (prop);
5382912Sartem 	else
5392912Sartem 		return HAL_PROPERTY_TYPE_INVALID;
5402912Sartem }
5412912Sartem 
5422912Sartem const char *
hal_device_property_get_string(HalDevice * device,const char * key)5432912Sartem hal_device_property_get_string (HalDevice *device, const char *key)
5442912Sartem {
5452912Sartem 	HalProperty *prop;
5462912Sartem 
5472912Sartem 	g_return_val_if_fail (device != NULL, NULL);
5482912Sartem 	g_return_val_if_fail (key != NULL, NULL);
5492912Sartem 
5502912Sartem 	prop = hal_device_property_find (device, key);
5512912Sartem 
5522912Sartem 	if (prop != NULL)
5532912Sartem 		return hal_property_get_string (prop);
5542912Sartem 	else
5552912Sartem 		return NULL;
5562912Sartem }
5572912Sartem 
5582912Sartem const char *
hal_device_property_get_as_string(HalDevice * device,const char * key,char * buf,size_t bufsize)5592912Sartem hal_device_property_get_as_string (HalDevice *device, const char *key, char *buf, size_t bufsize)
5602912Sartem {
5612912Sartem 	HalProperty *prop;
5622912Sartem 
5632912Sartem 	g_return_val_if_fail (device != NULL, NULL);
5642912Sartem 	g_return_val_if_fail (key != NULL, NULL);
5652912Sartem 	g_return_val_if_fail (buf != NULL, NULL);
5662912Sartem 
5672912Sartem 	prop = hal_device_property_find (device, key);
5682912Sartem 
5692912Sartem 	if (prop != NULL) {
5702912Sartem 		switch (hal_property_get_type (prop)) {
5712912Sartem 		case HAL_PROPERTY_TYPE_STRING:
5722912Sartem 			strncpy (buf, hal_property_get_string (prop), bufsize);
5732912Sartem 			break;
5742912Sartem 		case HAL_PROPERTY_TYPE_INT32:
5752912Sartem 			snprintf (buf, bufsize, "%d", hal_property_get_int (prop));
5762912Sartem 			break;
5772912Sartem 		case HAL_PROPERTY_TYPE_UINT64:
5782912Sartem 			snprintf (buf, bufsize, "%llu", (long long unsigned int) hal_property_get_uint64 (prop));
5792912Sartem 			break;
5802912Sartem 		case HAL_PROPERTY_TYPE_DOUBLE:
5812912Sartem 			snprintf (buf, bufsize, "%f", hal_property_get_double (prop));
5822912Sartem 			break;
5832912Sartem 		case HAL_PROPERTY_TYPE_BOOLEAN:
5842912Sartem 			strncpy (buf, hal_property_get_bool (prop) ? "true" : "false", bufsize);
5852912Sartem 			break;
5862912Sartem 
5872912Sartem 		case HAL_PROPERTY_TYPE_STRLIST:
5882912Sartem 			/* print out as "\tval1\tval2\val3\t" */
5892912Sartem 		        {
5902912Sartem 				GSList *iter;
5912912Sartem 				guint i;
5922912Sartem 
5932912Sartem 				if (bufsize > 0)
5942912Sartem 					buf[0] = '\t';
5952912Sartem 				i = 1;
5962912Sartem 				for (iter = hal_property_get_strlist (prop);
5972912Sartem 				     iter != NULL && i < bufsize;
5982912Sartem 				     iter = g_slist_next (iter)) {
5992912Sartem 					guint len;
6002912Sartem 					const char *str;
6012912Sartem 
6022912Sartem 					str = (const char *) iter->data;
6032912Sartem 					len = strlen (str);
6042912Sartem 					strncpy (buf + i, str, bufsize - i);
6052912Sartem 					i += len;
6062912Sartem 
6072912Sartem 					if (i < bufsize) {
6082912Sartem 						buf[i] = '\t';
6092912Sartem 						i++;
6102912Sartem 					}
6112912Sartem 				}
6122912Sartem 			}
6132912Sartem 			break;
6142912Sartem 		}
6152912Sartem 		return buf;
6162912Sartem 	} else {
6172912Sartem 		buf[0] = '\0';
6182912Sartem 		return NULL;
6192912Sartem 	}
6202912Sartem }
6212912Sartem 
6222912Sartem dbus_int32_t
hal_device_property_get_int(HalDevice * device,const char * key)6232912Sartem hal_device_property_get_int (HalDevice *device, const char *key)
6242912Sartem {
6252912Sartem 	HalProperty *prop;
6262912Sartem 
6272912Sartem 	g_return_val_if_fail (device != NULL, -1);
6282912Sartem 	g_return_val_if_fail (key != NULL, -1);
6292912Sartem 
6302912Sartem 	prop = hal_device_property_find (device, key);
6312912Sartem 
6322912Sartem 	if (prop != NULL)
6332912Sartem 		return hal_property_get_int (prop);
6342912Sartem 	else
6352912Sartem 		return -1;
6362912Sartem }
6372912Sartem 
6382912Sartem dbus_uint64_t
hal_device_property_get_uint64(HalDevice * device,const char * key)6392912Sartem hal_device_property_get_uint64 (HalDevice *device, const char *key)
6402912Sartem {
6412912Sartem 	HalProperty *prop;
6422912Sartem 
6432912Sartem 	g_return_val_if_fail (device != NULL, -1);
6442912Sartem 	g_return_val_if_fail (key != NULL, -1);
6452912Sartem 
6462912Sartem 	prop = hal_device_property_find (device, key);
6472912Sartem 
6482912Sartem 	if (prop != NULL)
6492912Sartem 		return hal_property_get_uint64 (prop);
6502912Sartem 	else
6512912Sartem 		return -1;
6522912Sartem }
6532912Sartem 
6542912Sartem dbus_bool_t
hal_device_property_get_bool(HalDevice * device,const char * key)6552912Sartem hal_device_property_get_bool (HalDevice *device, const char *key)
6562912Sartem {
6572912Sartem 	HalProperty *prop;
6582912Sartem 
6592912Sartem 	g_return_val_if_fail (device != NULL, FALSE);
6602912Sartem 	g_return_val_if_fail (key != NULL, FALSE);
6612912Sartem 
6622912Sartem 	prop = hal_device_property_find (device, key);
6632912Sartem 
6642912Sartem 	if (prop != NULL)
6652912Sartem 		return hal_property_get_bool (prop);
6662912Sartem 	else
6672912Sartem 		return FALSE;
6682912Sartem }
6692912Sartem 
6702912Sartem double
hal_device_property_get_double(HalDevice * device,const char * key)6712912Sartem hal_device_property_get_double (HalDevice *device, const char *key)
6722912Sartem {
6732912Sartem 	HalProperty *prop;
6742912Sartem 
6752912Sartem 	g_return_val_if_fail (device != NULL, -1.0);
6762912Sartem 	g_return_val_if_fail (key != NULL, -1.0);
6772912Sartem 
6782912Sartem 	prop = hal_device_property_find (device, key);
6792912Sartem 
6802912Sartem 	if (prop != NULL)
6812912Sartem 		return hal_property_get_double (prop);
6822912Sartem 	else
6832912Sartem 		return -1.0;
6842912Sartem }
6852912Sartem 
6862912Sartem gboolean
hal_device_property_set_string(HalDevice * device,const char * key,const char * value)6872912Sartem hal_device_property_set_string (HalDevice *device, const char *key,
6882912Sartem 				const char *value)
6892912Sartem {
6902912Sartem 	HalProperty *prop;
6912912Sartem 
6922912Sartem 	/* check if property already exists */
6932912Sartem 	prop = hal_device_property_find (device, key);
6942912Sartem 
6952912Sartem 	if (prop != NULL) {
6962912Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRING)
6972912Sartem 			return FALSE;
6982912Sartem 
6992912Sartem 		/* don't bother setting the same value */
7002912Sartem 		if (value != NULL &&
7012912Sartem 		    strcmp (hal_property_get_string (prop), value) == 0)
7022912Sartem 			return TRUE;
7032912Sartem 
7042912Sartem 		hal_property_set_string (prop, value);
7052912Sartem 
7062912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
7072912Sartem 			       key, FALSE, FALSE);
7082912Sartem 
7092912Sartem 	} else {
7102912Sartem 
7112912Sartem 		prop = hal_property_new_string (key, value);
7122912Sartem 
7132912Sartem 		device->properties = g_slist_prepend (device->properties, prop);
7142912Sartem 
7152912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
7162912Sartem 			       key, FALSE, TRUE);
7172912Sartem 	}
7182912Sartem 
7192912Sartem 	return TRUE;
7202912Sartem }
7212912Sartem 
7222912Sartem gboolean
hal_device_property_set_int(HalDevice * device,const char * key,dbus_int32_t value)7232912Sartem hal_device_property_set_int (HalDevice *device, const char *key,
7242912Sartem 			     dbus_int32_t value)
7252912Sartem {
7262912Sartem 	HalProperty *prop;
7272912Sartem 
7282912Sartem 	/* check if property already exists */
7292912Sartem 	prop = hal_device_property_find (device, key);
7302912Sartem 
7312912Sartem 	if (prop != NULL) {
7322912Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_INT32)
7332912Sartem 			return FALSE;
7342912Sartem 
7352912Sartem 		/* don't bother setting the same value */
7362912Sartem 		if (hal_property_get_int (prop) == value)
7372912Sartem 			return TRUE;
7382912Sartem 
7392912Sartem 		hal_property_set_int (prop, value);
7402912Sartem 
7412912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
7422912Sartem 			       key, FALSE, FALSE);
7432912Sartem 
7442912Sartem 	} else {
7452912Sartem 		prop = hal_property_new_int (key, value);
7462912Sartem 
7472912Sartem 		device->properties = g_slist_prepend (device->properties, prop);
7482912Sartem 
7492912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
7502912Sartem 			       key, FALSE, TRUE);
7512912Sartem 	}
7522912Sartem 
7532912Sartem 	return TRUE;
7542912Sartem }
7552912Sartem 
7562912Sartem gboolean
hal_device_property_set_uint64(HalDevice * device,const char * key,dbus_uint64_t value)7572912Sartem hal_device_property_set_uint64 (HalDevice *device, const char *key,
7582912Sartem 			     dbus_uint64_t value)
7592912Sartem {
7602912Sartem 	HalProperty *prop;
7612912Sartem 
7622912Sartem 	/* check if property already exists */
7632912Sartem 	prop = hal_device_property_find (device, key);
7642912Sartem 
7652912Sartem 	if (prop != NULL) {
7662912Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_UINT64)
7672912Sartem 			return FALSE;
7682912Sartem 
7692912Sartem 		/* don't bother setting the same value */
7702912Sartem 		if (hal_property_get_uint64 (prop) == value)
7712912Sartem 			return TRUE;
7722912Sartem 
7732912Sartem 		hal_property_set_uint64 (prop, value);
7742912Sartem 
7752912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
7762912Sartem 			       key, FALSE, FALSE);
7772912Sartem 
7782912Sartem 	} else {
7792912Sartem 		prop = hal_property_new_uint64 (key, value);
7802912Sartem 
7812912Sartem 		device->properties = g_slist_prepend (device->properties, prop);
7822912Sartem 
7832912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
7842912Sartem 			       key, FALSE, TRUE);
7852912Sartem 	}
7862912Sartem 
7872912Sartem 	return TRUE;
7882912Sartem }
7892912Sartem 
7902912Sartem gboolean
hal_device_property_set_bool(HalDevice * device,const char * key,dbus_bool_t value)7912912Sartem hal_device_property_set_bool (HalDevice *device, const char *key,
7922912Sartem 			     dbus_bool_t value)
7932912Sartem {
7942912Sartem 	HalProperty *prop;
7952912Sartem 
7962912Sartem 	/* check if property already exists */
7972912Sartem 	prop = hal_device_property_find (device, key);
7982912Sartem 
7992912Sartem 	if (prop != NULL) {
8002912Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_BOOLEAN)
8012912Sartem 			return FALSE;
8022912Sartem 
8032912Sartem 		/* don't bother setting the same value */
8042912Sartem 		if (hal_property_get_bool (prop) == value)
8052912Sartem 			return TRUE;
8062912Sartem 
8072912Sartem 		hal_property_set_bool (prop, value);
8082912Sartem 
8092912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
8102912Sartem 			       key, FALSE, FALSE);
8112912Sartem 
8122912Sartem 	} else {
8132912Sartem 		prop = hal_property_new_bool (key, value);
8142912Sartem 
8152912Sartem 		device->properties = g_slist_prepend (device->properties, prop);
8162912Sartem 
8172912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
8182912Sartem 			       key, FALSE, TRUE);
8192912Sartem 	}
8202912Sartem 
8212912Sartem 	return TRUE;
8222912Sartem }
8232912Sartem 
8242912Sartem gboolean
hal_device_property_set_double(HalDevice * device,const char * key,double value)8252912Sartem hal_device_property_set_double (HalDevice *device, const char *key,
8262912Sartem 				double value)
8272912Sartem {
8282912Sartem 	HalProperty *prop;
8292912Sartem 
8302912Sartem 	/* check if property already exists */
8312912Sartem 	prop = hal_device_property_find (device, key);
8322912Sartem 
8332912Sartem 	if (prop != NULL) {
8342912Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_DOUBLE)
8352912Sartem 			return FALSE;
8362912Sartem 
8372912Sartem 		/* don't bother setting the same value */
8382912Sartem 		if (hal_property_get_double (prop) == value)
8392912Sartem 			return TRUE;
8402912Sartem 
8412912Sartem 		hal_property_set_double (prop, value);
8422912Sartem 
8432912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
8442912Sartem 			       key, FALSE, FALSE);
8452912Sartem 
8462912Sartem 	} else {
8472912Sartem 		prop = hal_property_new_double (key, value);
8482912Sartem 
8492912Sartem 		device->properties = g_slist_prepend (device->properties, prop);
8502912Sartem 
8512912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
8522912Sartem 			       key, FALSE, TRUE);
8532912Sartem 	}
8542912Sartem 
8552912Sartem 	return TRUE;
8562912Sartem }
8572912Sartem 
8582912Sartem gboolean
hal_device_copy_property(HalDevice * from_device,const char * from,HalDevice * to_device,const char * to)8592912Sartem hal_device_copy_property (HalDevice *from_device, const char *from, HalDevice *to_device, const char *to)
8602912Sartem {
8612912Sartem 	gboolean rc;
8622912Sartem 
8632912Sartem 	rc = FALSE;
8642912Sartem 
8652912Sartem 	if (hal_device_has_property (from_device, from)) {
8662912Sartem 		switch (hal_device_property_get_type (from_device, from)) {
8672912Sartem 		case HAL_PROPERTY_TYPE_STRING:
8682912Sartem 			rc = hal_device_property_set_string (
8692912Sartem 				to_device, to, hal_device_property_get_string (from_device, from));
8702912Sartem 			break;
8712912Sartem 		case HAL_PROPERTY_TYPE_INT32:
8722912Sartem 			rc = hal_device_property_set_int (
8732912Sartem 				to_device, to, hal_device_property_get_int (from_device, from));
8742912Sartem 			break;
8752912Sartem 		case HAL_PROPERTY_TYPE_UINT64:
8762912Sartem 			rc = hal_device_property_set_uint64 (
8772912Sartem 				to_device, to, hal_device_property_get_uint64 (from_device, from));
8782912Sartem 			break;
8792912Sartem 		case HAL_PROPERTY_TYPE_BOOLEAN:
8802912Sartem 			rc = hal_device_property_set_bool (
8812912Sartem 				to_device, to, hal_device_property_get_bool (from_device, from));
8822912Sartem 			break;
8832912Sartem 		case HAL_PROPERTY_TYPE_DOUBLE:
8842912Sartem 			rc = hal_device_property_set_double (
8852912Sartem 				to_device, to, hal_device_property_get_double (from_device, from));
8862912Sartem 			break;
8872912Sartem 		}
8882912Sartem 	}
8892912Sartem 
8902912Sartem 	return rc;
8912912Sartem }
8922912Sartem 
8932912Sartem gboolean
hal_device_property_remove(HalDevice * device,const char * key)8942912Sartem hal_device_property_remove (HalDevice *device, const char *key)
8952912Sartem {
8962912Sartem 	HalProperty *prop;
8972912Sartem 
8982912Sartem 	prop = hal_device_property_find (device, key);
8992912Sartem 
9002912Sartem 	if (prop == NULL)
9012912Sartem 		return FALSE;
9022912Sartem 
9032912Sartem 	device->properties = g_slist_remove (device->properties, prop);
9042912Sartem 
9052912Sartem 	hal_property_free (prop);
9062912Sartem 
9072912Sartem 	g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
9082912Sartem 		       key, TRUE, FALSE);
9092912Sartem 
9102912Sartem 	return TRUE;
9112912Sartem }
9122912Sartem 
9132912Sartem gboolean
hal_device_property_set_attribute(HalDevice * device,const char * key,enum PropertyAttribute attr,gboolean val)9142912Sartem hal_device_property_set_attribute (HalDevice *device,
9152912Sartem 				   const char *key,
9162912Sartem 				   enum PropertyAttribute attr,
9172912Sartem 				   gboolean val)
9182912Sartem {
9192912Sartem 	HalProperty *prop;
9202912Sartem 
9212912Sartem 	prop = hal_device_property_find (device, key);
9222912Sartem 
9232912Sartem 	if (prop == NULL)
9242912Sartem 		return FALSE;
9252912Sartem 
9262912Sartem 	return TRUE;
9272912Sartem }
9282912Sartem 
9292912Sartem void
hal_device_print(HalDevice * device)9302912Sartem hal_device_print (HalDevice *device)
9312912Sartem {
9322912Sartem 	GSList *iter;
9332912Sartem 
9342912Sartem         fprintf (stderr, "device udi = %s\n", hal_device_get_udi (device));
9352912Sartem 
9362912Sartem 	for (iter = device->properties; iter != NULL; iter = iter->next) {
9372912Sartem 		HalProperty *p = iter->data;
9382912Sartem                 int type;
9392912Sartem                 const char *key;
9402912Sartem 
9412912Sartem                 key = hal_property_get_key (p);
9422912Sartem                 type = hal_property_get_type (p);
9432912Sartem 
9442912Sartem                 switch (type) {
9452912Sartem                 case HAL_PROPERTY_TYPE_STRING:
9462912Sartem                         fprintf (stderr, "  %s = '%s'  (string)\n", key,
9472912Sartem                                 hal_property_get_string (p));
9482912Sartem                         break;
9492912Sartem 
9502912Sartem                 case HAL_PROPERTY_TYPE_INT32:
9512912Sartem                         fprintf (stderr, "  %s = %d  0x%x  (int)\n", key,
9522912Sartem                                 hal_property_get_int (p),
9532912Sartem                                 hal_property_get_int (p));
9542912Sartem                         break;
9552912Sartem 
9562912Sartem                 case HAL_PROPERTY_TYPE_UINT64:
9572912Sartem                         fprintf (stderr, "  %s = %llu  0x%llx  (uint64)\n", key,
9582912Sartem                                 (long long unsigned int) hal_property_get_uint64 (p),
9592912Sartem                                 (long long unsigned int) hal_property_get_uint64 (p));
9602912Sartem                         break;
9612912Sartem 
9622912Sartem                 case HAL_PROPERTY_TYPE_DOUBLE:
9632912Sartem                         fprintf (stderr, "  %s = %g  (double)\n", key,
9642912Sartem                                 hal_property_get_double (p));
9652912Sartem                         break;
9662912Sartem 
9672912Sartem                 case HAL_PROPERTY_TYPE_BOOLEAN:
9682912Sartem                         fprintf (stderr, "  %s = %s  (bool)\n", key,
9692912Sartem                                 (hal_property_get_bool (p) ? "true" :
9702912Sartem                                  "false"));
9712912Sartem                         break;
9722912Sartem 
9732912Sartem                 default:
9742912Sartem                         HAL_WARNING (("Unknown property type %d", type));
9752912Sartem                         break;
9762912Sartem                 }
9772912Sartem         }
9782912Sartem         fprintf (stderr, "\n");
9792912Sartem }
9802912Sartem 
9812912Sartem 
9822912Sartem typedef struct {
9832912Sartem 	char *key;
9842912Sartem 	HalDevice *device;
9852912Sartem 	HalDeviceAsyncCallback callback;
9862912Sartem 	gpointer user_data;
9872912Sartem 
9882912Sartem 	guint prop_signal_id;
9892912Sartem 	guint timeout_id;
9902912Sartem } AsyncMatchInfo;
9912912Sartem 
9922912Sartem static void
destroy_async_match_info(AsyncMatchInfo * ai)9932912Sartem destroy_async_match_info (AsyncMatchInfo *ai)
9942912Sartem {
9952912Sartem 	g_free (ai->key);
9962912Sartem 	g_signal_handler_disconnect (ai->device, ai->prop_signal_id);
9972912Sartem 	g_source_remove (ai->timeout_id);
9982912Sartem 	g_object_unref (ai->device);
9992912Sartem 	g_free (ai);
10002912Sartem }
10012912Sartem 
10022912Sartem static void
prop_changed_cb(HalDevice * device,const char * key,gboolean removed,gboolean added,gpointer user_data)10032912Sartem prop_changed_cb (HalDevice *device, const char *key,
10042912Sartem 		 gboolean removed, gboolean added, gpointer user_data)
10052912Sartem {
10062912Sartem 	AsyncMatchInfo *ai = user_data;
10072912Sartem 
10082912Sartem 	if (strcmp (key, ai->key) != 0)
10092912Sartem 		return;
10102912Sartem 
10112912Sartem 	/* the property is no longer there */
10122912Sartem 	if (removed)
10132912Sartem 		goto cleanup;
10142912Sartem 
10152912Sartem 
10162912Sartem 	ai->callback (ai->device, ai->user_data, TRUE);
10172912Sartem 
10182912Sartem cleanup:
10192912Sartem 	destroy_async_match_info (ai);
10202912Sartem }
10212912Sartem 
10222912Sartem 
10232912Sartem static gboolean
async_wait_timeout(gpointer user_data)10242912Sartem async_wait_timeout (gpointer user_data)
10252912Sartem {
10262912Sartem 	AsyncMatchInfo *ai = (AsyncMatchInfo *) user_data;
10272912Sartem 
10282912Sartem 	ai->callback (ai->device, ai->user_data, FALSE);
10292912Sartem 
10302912Sartem 	destroy_async_match_info (ai);
10312912Sartem 
10322912Sartem 	return FALSE;
10332912Sartem }
10342912Sartem 
10352912Sartem void
hal_device_async_wait_property(HalDevice * device,const char * key,HalDeviceAsyncCallback callback,gpointer user_data,int timeout)10362912Sartem hal_device_async_wait_property (HalDevice    *device,
10372912Sartem 				const char   *key,
10382912Sartem 				HalDeviceAsyncCallback callback,
10392912Sartem 				gpointer     user_data,
10402912Sartem 				int          timeout)
10412912Sartem {
10422912Sartem 	HalProperty *prop;
10432912Sartem 	AsyncMatchInfo *ai;
10442912Sartem 
10452912Sartem 	/* check if property already exists */
10462912Sartem 	prop = hal_device_property_find (device, key);
10472912Sartem 
10482912Sartem 	if (prop != NULL || timeout==0) {
10492912Sartem 		callback (device, user_data, prop != NULL);
10502912Sartem 		return;
10512912Sartem 	}
10522912Sartem 
10532912Sartem 	ai = g_new0 (AsyncMatchInfo, 1);
10542912Sartem 
10552912Sartem 	ai->device = g_object_ref (device);
10562912Sartem 	ai->key = g_strdup (key);
10572912Sartem 	ai->callback = callback;
10582912Sartem 	ai->user_data = user_data;
10592912Sartem 
10602912Sartem 	ai->prop_signal_id = g_signal_connect (device, "property_changed",
10612912Sartem 					       G_CALLBACK (prop_changed_cb),
10622912Sartem 					       ai);
10632912Sartem 
10642912Sartem 	ai->timeout_id = g_timeout_add (timeout, async_wait_timeout, ai);
10652912Sartem }
10662912Sartem 
10672912Sartem void
hal_device_callouts_finished(HalDevice * device)10682912Sartem hal_device_callouts_finished (HalDevice *device)
10692912Sartem {
10702912Sartem 	g_signal_emit (device, signals[CALLOUTS_FINISHED], 0);
10712912Sartem }
10722912Sartem 
10732912Sartem /** Used when giving up on a device, e.g. if no device file appeared
10742912Sartem  */
10752912Sartem void
hal_device_cancel(HalDevice * device)10762912Sartem hal_device_cancel (HalDevice *device)
10772912Sartem {
10782912Sartem 	HAL_INFO (("udi=%s", device->udi));
10792912Sartem 	g_signal_emit (device, signals[CANCELLED], 0);
10802912Sartem }
10812912Sartem 
10822912Sartem 
10832912Sartem 
10842912Sartem 
10852912Sartem GSList *
hal_device_property_get_strlist(HalDevice * device,const char * key)10862912Sartem hal_device_property_get_strlist (HalDevice    *device,
10872912Sartem 				 const char   *key)
10882912Sartem {
10892912Sartem 	HalProperty *prop;
10902912Sartem 
10912912Sartem 	g_return_val_if_fail (device != NULL, NULL);
10922912Sartem 	g_return_val_if_fail (key != NULL, NULL);
10932912Sartem 
10942912Sartem 	prop = hal_device_property_find (device, key);
10952912Sartem 
10962912Sartem 	if (prop != NULL)
10972912Sartem 		return hal_property_get_strlist (prop);
10982912Sartem 	else
10992912Sartem 		return NULL;
11002912Sartem }
11012912Sartem 
11022912Sartem const char *
hal_device_property_get_strlist_elem(HalDevice * device,const char * key,guint index)11032912Sartem hal_device_property_get_strlist_elem (HalDevice    *device,
11042912Sartem 				      const char   *key,
11052912Sartem 				      guint index)
11062912Sartem {
11072912Sartem 	GSList *strlist;
11082912Sartem 	GSList *i;
11092912Sartem 
11102912Sartem 	strlist = hal_device_property_get_strlist (device, key);
11112912Sartem 	if (strlist == NULL)
11122912Sartem 		return NULL;
11132912Sartem 
11142912Sartem 	i = g_slist_nth (strlist, index);
11152912Sartem 	if (i == NULL)
11162912Sartem 		return NULL;
11172912Sartem 
11182912Sartem 	return (const char *) i->data;
11192912Sartem }
11202912Sartem 
11212912Sartem gboolean
hal_device_property_strlist_append(HalDevice * device,const char * key,const char * value)11222912Sartem hal_device_property_strlist_append (HalDevice    *device,
11232912Sartem 				    const char   *key,
11242912Sartem 				    const char *value)
11252912Sartem {
11262912Sartem 	HalProperty *prop;
11272912Sartem 
11282912Sartem 	/* check if property already exists */
11292912Sartem 	prop = hal_device_property_find (device, key);
11302912Sartem 
11312912Sartem 	if (prop != NULL) {
11322912Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
11332912Sartem 			return FALSE;
11342912Sartem 
11352912Sartem 		hal_property_strlist_append (prop, value);
11362912Sartem 
11372912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
11382912Sartem 			       key, FALSE, FALSE);
11392912Sartem 
11402912Sartem 	} else {
11412912Sartem 		prop = hal_property_new_strlist (key);
11422912Sartem 		hal_property_strlist_append (prop, value);
11432912Sartem 
11442912Sartem 		device->properties = g_slist_prepend (device->properties, prop);
11452912Sartem 
11462912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
11472912Sartem 			       key, FALSE, TRUE);
11482912Sartem 	}
11492912Sartem 
11502912Sartem 	return TRUE;
11512912Sartem }
11522912Sartem 
11532912Sartem gboolean
hal_device_property_strlist_prepend(HalDevice * device,const char * key,const char * value)11542912Sartem hal_device_property_strlist_prepend (HalDevice    *device,
11552912Sartem 				     const char   *key,
11562912Sartem 				     const char *value)
11572912Sartem {
11582912Sartem 	HalProperty *prop;
11592912Sartem 
11602912Sartem 	/* check if property already exists */
11612912Sartem 	prop = hal_device_property_find (device, key);
11622912Sartem 
11632912Sartem 	if (prop != NULL) {
11642912Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
11652912Sartem 			return FALSE;
11662912Sartem 
11672912Sartem 		hal_property_strlist_prepend (prop, value);
11682912Sartem 
11692912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
11702912Sartem 			       key, FALSE, FALSE);
11712912Sartem 
11722912Sartem 	} else {
11732912Sartem 		prop = hal_property_new_strlist (key);
11742912Sartem 		hal_property_strlist_prepend (prop, value);
11752912Sartem 
11762912Sartem 		device->properties = g_slist_prepend (device->properties, prop);
11772912Sartem 
11782912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
11792912Sartem 			       key, FALSE, TRUE);
11802912Sartem 	}
11812912Sartem 
11822912Sartem 	return TRUE;
11832912Sartem }
11842912Sartem 
11852912Sartem gboolean
hal_device_property_strlist_remove_elem(HalDevice * device,const char * key,guint index)11862912Sartem hal_device_property_strlist_remove_elem (HalDevice    *device,
11872912Sartem 					 const char   *key,
11882912Sartem 					 guint index)
11892912Sartem {
11902912Sartem 	HalProperty *prop;
11912912Sartem 
11922912Sartem 	/* check if property already exists */
11932912Sartem 	prop = hal_device_property_find (device, key);
11942912Sartem 
11952912Sartem 	if (prop == NULL)
11962912Sartem 		return FALSE;
11972912Sartem 
11982912Sartem 	if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
11992912Sartem 		return FALSE;
12002912Sartem 
12012912Sartem 	if (hal_property_strlist_remove_elem (prop, index)) {
12022912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
12032912Sartem 			       key, FALSE, FALSE);
12042912Sartem 		return TRUE;
12052912Sartem 	}
12062912Sartem 
12072912Sartem 	return FALSE;
12082912Sartem }
12092912Sartem 
12102912Sartem gboolean
hal_device_property_strlist_clear(HalDevice * device,const char * key)12112912Sartem hal_device_property_strlist_clear (HalDevice    *device,
12122912Sartem 				   const char   *key)
12132912Sartem {
12142912Sartem 	HalProperty *prop;
12152912Sartem 
12162912Sartem 	/* check if property already exists */
12172912Sartem 	prop = hal_device_property_find (device, key);
12182912Sartem 
12192912Sartem 	if (prop == NULL) {
12202912Sartem 		prop = hal_property_new_strlist (key);
12212912Sartem 
12222912Sartem 		device->properties = g_slist_prepend (device->properties, prop);
12232912Sartem 
12242912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
12252912Sartem 			       key, FALSE, TRUE);
12262912Sartem 
12272912Sartem 		return TRUE;
12282912Sartem 	}
12292912Sartem 
12302912Sartem 	if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
12312912Sartem 		return FALSE;
12322912Sartem 
12332912Sartem 	if (hal_property_strlist_clear (prop)) {
12342912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
12352912Sartem 			       key, FALSE, FALSE);
12362912Sartem 		return TRUE;
12372912Sartem 	}
12382912Sartem 
12392912Sartem 	return FALSE;
12402912Sartem }
12412912Sartem 
12422912Sartem 
12432912Sartem gboolean
hal_device_property_strlist_add(HalDevice * device,const char * key,const char * value)12442912Sartem hal_device_property_strlist_add (HalDevice *device,
12452912Sartem 				 const char *key,
12462912Sartem 				 const char *value)
12472912Sartem {
12482912Sartem 	HalProperty *prop;
12492912Sartem 	gboolean res;
12502912Sartem 
12512912Sartem 	res = FALSE;
12522912Sartem 
12532912Sartem 	/* check if property already exists */
12542912Sartem 	prop = hal_device_property_find (device, key);
12552912Sartem 
12562912Sartem 	if (prop != NULL) {
12572912Sartem 		if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
12582912Sartem 			goto out;
12592912Sartem 
12602912Sartem 		res = hal_property_strlist_add (prop, value);
12612912Sartem 		if (res) {
12622912Sartem 			g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
12632912Sartem 				       key, FALSE, FALSE);
12642912Sartem 		}
12652912Sartem 
12662912Sartem 	} else {
12672912Sartem 		prop = hal_property_new_strlist (key);
12682912Sartem 		hal_property_strlist_prepend (prop, value);
12692912Sartem 
12702912Sartem 		device->properties = g_slist_prepend (device->properties, prop);
12712912Sartem 
12722912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
12732912Sartem 			       key, FALSE, TRUE);
12742912Sartem 
12752912Sartem 		res = TRUE;
12762912Sartem 	}
12772912Sartem 
12782912Sartem out:
12792912Sartem 	return res;
12802912Sartem }
12812912Sartem 
12822912Sartem gboolean
hal_device_property_strlist_remove(HalDevice * device,const char * key,const char * value)12832912Sartem hal_device_property_strlist_remove (HalDevice *device,
12842912Sartem 				    const char *key,
12852912Sartem 				    const char *value)
12862912Sartem {
12872912Sartem 	HalProperty *prop;
12882912Sartem 
12892912Sartem 	/* check if property already exists */
12902912Sartem 	prop = hal_device_property_find (device, key);
12912912Sartem 
12922912Sartem 	if (prop == NULL)
12932912Sartem 		return FALSE;
12942912Sartem 
12952912Sartem 	if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST)
12962912Sartem 		return FALSE;
12972912Sartem 
12982912Sartem 	if (hal_property_strlist_remove (prop, value)) {
12992912Sartem 		g_signal_emit (device, signals[PROPERTY_CHANGED], 0,
13002912Sartem 			       key, FALSE, FALSE);
13012912Sartem 	}
13022912Sartem 
13032912Sartem 	return TRUE;
13042912Sartem }
13052912Sartem 
13062912Sartem gboolean
hal_device_property_strlist_is_empty(HalDevice * device,const char * key)13072912Sartem hal_device_property_strlist_is_empty (HalDevice    *device,
13082912Sartem 				      const char   *key)
13092912Sartem {
13102912Sartem 	GSList *strlist;
13112912Sartem 
13122912Sartem 	if ( hal_device_has_property (device, key)) {
13132912Sartem 		strlist = hal_device_property_get_strlist (device, key);
13142912Sartem 		if (strlist == NULL )
13152912Sartem 			return TRUE;
13162912Sartem 
13172912Sartem 		if (g_slist_length (strlist) > 0)
13182912Sartem 			return FALSE;
13192912Sartem 		else
13202912Sartem 			return TRUE;
13212912Sartem 	}
13222912Sartem 	return FALSE;
13232912Sartem }
13242912Sartem 
13252912Sartem void
hal_device_inc_num_addons(HalDevice * device)13262912Sartem hal_device_inc_num_addons (HalDevice *device)
13272912Sartem {
13282912Sartem 	device->num_addons++;
13292912Sartem }
13302912Sartem 
13312912Sartem gboolean
hal_device_inc_num_ready_addons(HalDevice * device)13322912Sartem hal_device_inc_num_ready_addons (HalDevice *device)
13332912Sartem {
13342912Sartem 	if (hal_device_are_all_addons_ready (device)) {
13352912Sartem 		HAL_ERROR (("In hal_device_inc_num_ready_addons for udi=%s but all addons are already ready!",
13362912Sartem 			    device->udi));
13372912Sartem 		return FALSE;
13382912Sartem 	}
13392912Sartem 
13402912Sartem 	device->num_addons_ready++;
13412912Sartem 	return TRUE;
13422912Sartem }
13432912Sartem 
13442912Sartem gboolean
hal_device_are_all_addons_ready(HalDevice * device)13452912Sartem hal_device_are_all_addons_ready (HalDevice *device)
13462912Sartem {
13472912Sartem 	if (device->num_addons_ready == device->num_addons) {
13482912Sartem 		return TRUE;
13492912Sartem 	} else {
13502912Sartem 		return FALSE;
13512912Sartem 	}
13522912Sartem }
1353