1 /***************************************************************************
4 * device.c : HalDevice methods
6 * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
7 * Copyright (C) 2004 Novell, Inc.
9 * Licensed under the Academic Free License version 2.1
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 **************************************************************************/
36 #include "hald_marshal.h"
38 #include "hald_runner.h"
40 static GObjectClass
*parent_class
;
50 static guint signals
[LAST_SIGNAL
] = { 0 };
52 #ifdef HALD_MEMLEAK_DBG
53 int dbg_hal_device_object_delta
= 0;
57 hal_device_finalize (GObject
*obj
)
59 HalDevice
*device
= HAL_DEVICE (obj
);
61 runner_device_finalized (device
);
63 #ifdef HALD_MEMLEAK_DBG
64 dbg_hal_device_object_delta
--;
65 printf ("************* in finalize for udi=%s\n", device
->udi
);
69 g_slist_foreach (device
->properties
, (GFunc
) hal_property_free
, NULL
);
71 g_slist_free (device
->properties
);
75 if (parent_class
->finalize
)
76 parent_class
->finalize (obj
);
81 hal_device_class_init (HalDeviceClass
*klass
)
83 GObjectClass
*obj_class
= (GObjectClass
*) klass
;
85 parent_class
= g_type_class_peek_parent (klass
);
87 obj_class
->finalize
= hal_device_finalize
;
89 signals
[PROPERTY_CHANGED
] =
90 g_signal_new ("property_changed",
91 G_TYPE_FROM_CLASS (klass
),
93 G_STRUCT_OFFSET (HalDeviceClass
,
96 hald_marshal_VOID__STRING_BOOL_BOOL
,
102 signals
[CAPABILITY_ADDED
] =
103 g_signal_new ("capability_added",
104 G_TYPE_FROM_CLASS (klass
),
106 G_STRUCT_OFFSET (HalDeviceClass
,
109 hald_marshal_VOID__STRING
,
113 signals
[CALLOUTS_FINISHED
] =
114 g_signal_new ("callouts_finished",
115 G_TYPE_FROM_CLASS (klass
),
117 G_STRUCT_OFFSET (HalDeviceClass
,
120 hald_marshal_VOID__VOID
,
124 g_signal_new ("cancelled",
125 G_TYPE_FROM_CLASS (klass
),
127 G_STRUCT_OFFSET (HalDeviceClass
,
130 hald_marshal_VOID__VOID
,
135 hal_device_init (HalDevice
*device
)
137 static int temp_device_counter
= 0;
139 device
->udi
= g_strdup_printf ("/org/freedesktop/Hal/devices/temp/%d",
140 temp_device_counter
++);
141 device
->num_addons
= 0;
142 device
->num_addons_ready
= 0;
146 hal_device_get_type (void)
148 static GType type
= 0;
151 static GTypeInfo type_info
= {
152 sizeof (HalDeviceClass
),
154 (GClassInitFunc
) hal_device_class_init
,
158 (GInstanceInitFunc
) hal_device_init
,
162 type
= g_type_register_static (G_TYPE_OBJECT
,
173 hal_device_new (void)
177 device
= g_object_new (HAL_TYPE_DEVICE
, NULL
, NULL
);
179 #ifdef HALD_MEMLEAK_DBG
180 dbg_hal_device_object_delta
++;
185 /** Merge all properties from source where the key starts with
186 * source_namespace and put them onto target replacing source_namespace
187 * with target_namespace
189 * @param target Device to put properties onto
190 * @param source Device to retrieve properties from
191 * @param target_namespace Replace source namespace with this namespace
192 * @param source_namespace Source namespace that property keys must match
195 hal_device_merge_with_rewrite (HalDevice
*target
,
197 const char *target_namespace
,
198 const char *source_namespace
)
201 size_t source_ns_len
;
203 source_ns_len
= strlen (source_namespace
);
205 /* doesn't handle info.capabilities */
207 /* device_property_atomic_update_begin (); */
209 for (iter
= source
->properties
; iter
!= NULL
; iter
= iter
->next
) {
210 HalProperty
*p
= iter
->data
;
216 key
= hal_property_get_key (p
);
218 /* only care about properties that match source namespace */
219 if (strncmp(key
, source_namespace
, source_ns_len
) != 0)
222 target_key
= g_strdup_printf("%s%s", target_namespace
,
225 type
= hal_property_get_type (p
);
227 /* only remove target if it exists with a different type */
228 target_type
= hal_device_property_get_type (target
, key
);
229 if (target_type
!= HAL_PROPERTY_TYPE_INVALID
&& target_type
!= type
)
230 hal_device_property_remove (target
, key
);
234 case HAL_PROPERTY_TYPE_STRING
:
235 hal_device_property_set_string (
237 hal_property_get_string (p
));
240 case HAL_PROPERTY_TYPE_INT32
:
241 hal_device_property_set_int (
243 hal_property_get_int (p
));
246 case HAL_PROPERTY_TYPE_UINT64
:
247 hal_device_property_set_uint64 (
249 hal_property_get_uint64 (p
));
252 case HAL_PROPERTY_TYPE_BOOLEAN
:
253 hal_device_property_set_bool (
255 hal_property_get_bool (p
));
258 case HAL_PROPERTY_TYPE_DOUBLE
:
259 hal_device_property_set_double (
261 hal_property_get_double (p
));
265 HAL_WARNING (("Unknown property type %d", type
));
272 /* device_property_atomic_update_end (); */
277 hal_device_merge (HalDevice
*target
, HalDevice
*source
)
282 /* device_property_atomic_update_begin (); */
284 for (iter
= source
->properties
; iter
!= NULL
; iter
= iter
->next
) {
285 HalProperty
*p
= iter
->data
;
290 key
= hal_property_get_key (p
);
291 type
= hal_property_get_type (p
);
293 /* handle info.capabilities in a special way */
294 if (strcmp (key
, "info.capabilities") == 0)
297 /* only remove target if it exists with a different type */
298 target_type
= hal_device_property_get_type (target
, key
);
299 if (target_type
!= HAL_PROPERTY_TYPE_INVALID
&& target_type
!= type
)
300 hal_device_property_remove (target
, key
);
304 case HAL_PROPERTY_TYPE_STRING
:
305 hal_device_property_set_string (
307 hal_property_get_string (p
));
310 case HAL_PROPERTY_TYPE_INT32
:
311 hal_device_property_set_int (
313 hal_property_get_int (p
));
316 case HAL_PROPERTY_TYPE_UINT64
:
317 hal_device_property_set_uint64 (
319 hal_property_get_uint64 (p
));
322 case HAL_PROPERTY_TYPE_BOOLEAN
:
323 hal_device_property_set_bool (
325 hal_property_get_bool (p
));
328 case HAL_PROPERTY_TYPE_DOUBLE
:
329 hal_device_property_set_double (
331 hal_property_get_double (p
));
335 HAL_WARNING (("Unknown property type %d", type
));
340 /* device_property_atomic_update_end (); */
342 caps
= hal_device_property_get_strlist (source
, "info.capabilities");
343 for (iter
= caps
; iter
!= NULL
; iter
= iter
->next
) {
344 if (!hal_device_has_capability (target
, iter
->data
))
345 hal_device_add_capability (target
, iter
->data
);
350 hal_device_matches (HalDevice
*device1
, HalDevice
*device2
,
351 const char *namespace)
356 len
= strlen (namespace);
358 for (iter
= device1
->properties
; iter
!= NULL
; iter
= iter
->next
) {
363 p
= (HalProperty
*) iter
->data
;
364 key
= hal_property_get_key (p
);
365 type
= hal_property_get_type (p
);
367 if (strncmp (key
, namespace, len
) != 0)
370 if (!hal_device_has_property (device2
, key
))
375 case HAL_PROPERTY_TYPE_STRING
:
376 if (strcmp (hal_property_get_string (p
),
377 hal_device_property_get_string (device2
,
382 case HAL_PROPERTY_TYPE_INT32
:
383 if (hal_property_get_int (p
) !=
384 hal_device_property_get_int (device2
, key
))
388 case HAL_PROPERTY_TYPE_UINT64
:
389 if (hal_property_get_uint64 (p
) !=
390 hal_device_property_get_uint64 (device2
, key
))
394 case HAL_PROPERTY_TYPE_BOOLEAN
:
395 if (hal_property_get_bool (p
) !=
396 hal_device_property_get_bool (device2
, key
))
400 case HAL_PROPERTY_TYPE_DOUBLE
:
401 if (hal_property_get_double (p
) !=
402 hal_device_property_get_double (device2
, key
))
407 HAL_WARNING (("Unknown property type %d", type
));
416 hal_device_get_udi (HalDevice
*device
)
422 hal_device_set_udi (HalDevice
*device
, const char *udi
)
424 if (device
->udi
!= NULL
)
425 g_free (device
->udi
);
426 device
->udi
= g_strdup (udi
);
430 hal_device_add_capability (HalDevice
*device
, const char *capability
)
432 if (hal_device_property_strlist_add (device
, "info.capabilities", capability
))
433 g_signal_emit (device
, signals
[CAPABILITY_ADDED
], 0, capability
);
437 hal_device_has_capability (HalDevice
*device
, const char *capability
)
441 gboolean matched
= FALSE
;
443 caps
= hal_device_property_get_strlist (device
, "info.capabilities");
448 for (iter
= caps
; iter
!= NULL
; iter
= iter
->next
) {
449 if (strcmp (iter
->data
, capability
) == 0) {
459 hal_device_has_property (HalDevice
*device
, const char *key
)
461 g_return_val_if_fail (device
!= NULL
, FALSE
);
462 g_return_val_if_fail (key
!= NULL
, FALSE
);
464 return hal_device_property_find (device
, key
) != NULL
;
468 hal_device_num_properties (HalDevice
*device
)
470 g_return_val_if_fail (device
!= NULL
, -1);
472 return g_slist_length (device
->properties
);
476 hal_device_property_find (HalDevice
*device
, const char *key
)
480 g_return_val_if_fail (device
!= NULL
, NULL
);
481 g_return_val_if_fail (key
!= NULL
, NULL
);
483 for (iter
= device
->properties
; iter
!= NULL
; iter
= iter
->next
) {
484 HalProperty
*p
= iter
->data
;
486 if (strcmp (hal_property_get_key (p
), key
) == 0)
494 hal_device_property_to_string (HalDevice
*device
, const char *key
)
498 prop
= hal_device_property_find (device
, key
);
502 return hal_property_to_string (prop
);
506 hal_device_property_foreach (HalDevice
*device
,
507 HalDevicePropertyForeachFn callback
,
512 g_return_if_fail (device
!= NULL
);
513 g_return_if_fail (callback
!= NULL
);
515 for (iter
= device
->properties
; iter
!= NULL
; iter
= iter
->next
) {
516 HalProperty
*p
= iter
->data
;
519 cont
= callback (device
, p
, user_data
);
527 hal_device_property_get_type (HalDevice
*device
, const char *key
)
531 g_return_val_if_fail (device
!= NULL
, HAL_PROPERTY_TYPE_INVALID
);
532 g_return_val_if_fail (key
!= NULL
, HAL_PROPERTY_TYPE_INVALID
);
534 prop
= hal_device_property_find (device
, key
);
537 return hal_property_get_type (prop
);
539 return HAL_PROPERTY_TYPE_INVALID
;
543 hal_device_property_get_string (HalDevice
*device
, const char *key
)
547 g_return_val_if_fail (device
!= NULL
, NULL
);
548 g_return_val_if_fail (key
!= NULL
, NULL
);
550 prop
= hal_device_property_find (device
, key
);
553 return hal_property_get_string (prop
);
559 hal_device_property_get_as_string (HalDevice
*device
, const char *key
, char *buf
, size_t bufsize
)
563 g_return_val_if_fail (device
!= NULL
, NULL
);
564 g_return_val_if_fail (key
!= NULL
, NULL
);
565 g_return_val_if_fail (buf
!= NULL
, NULL
);
567 prop
= hal_device_property_find (device
, key
);
570 switch (hal_property_get_type (prop
)) {
571 case HAL_PROPERTY_TYPE_STRING
:
572 strncpy (buf
, hal_property_get_string (prop
), bufsize
);
574 case HAL_PROPERTY_TYPE_INT32
:
575 snprintf (buf
, bufsize
, "%d", hal_property_get_int (prop
));
577 case HAL_PROPERTY_TYPE_UINT64
:
578 snprintf (buf
, bufsize
, "%llu", (long long unsigned int) hal_property_get_uint64 (prop
));
580 case HAL_PROPERTY_TYPE_DOUBLE
:
581 snprintf (buf
, bufsize
, "%f", hal_property_get_double (prop
));
583 case HAL_PROPERTY_TYPE_BOOLEAN
:
584 strncpy (buf
, hal_property_get_bool (prop
) ? "true" : "false", bufsize
);
587 case HAL_PROPERTY_TYPE_STRLIST
:
588 /* print out as "\tval1\tval2\val3\t" */
596 for (iter
= hal_property_get_strlist (prop
);
597 iter
!= NULL
&& i
< bufsize
;
598 iter
= g_slist_next (iter
)) {
602 str
= (const char *) iter
->data
;
604 strncpy (buf
+ i
, str
, bufsize
- i
);
623 hal_device_property_get_int (HalDevice
*device
, const char *key
)
627 g_return_val_if_fail (device
!= NULL
, -1);
628 g_return_val_if_fail (key
!= NULL
, -1);
630 prop
= hal_device_property_find (device
, key
);
633 return hal_property_get_int (prop
);
639 hal_device_property_get_uint64 (HalDevice
*device
, const char *key
)
643 g_return_val_if_fail (device
!= NULL
, -1);
644 g_return_val_if_fail (key
!= NULL
, -1);
646 prop
= hal_device_property_find (device
, key
);
649 return hal_property_get_uint64 (prop
);
655 hal_device_property_get_bool (HalDevice
*device
, const char *key
)
659 g_return_val_if_fail (device
!= NULL
, FALSE
);
660 g_return_val_if_fail (key
!= NULL
, FALSE
);
662 prop
= hal_device_property_find (device
, key
);
665 return hal_property_get_bool (prop
);
671 hal_device_property_get_double (HalDevice
*device
, const char *key
)
675 g_return_val_if_fail (device
!= NULL
, -1.0);
676 g_return_val_if_fail (key
!= NULL
, -1.0);
678 prop
= hal_device_property_find (device
, key
);
681 return hal_property_get_double (prop
);
687 hal_device_property_set_string (HalDevice
*device
, const char *key
,
692 /* check if property already exists */
693 prop
= hal_device_property_find (device
, key
);
696 if (hal_property_get_type (prop
) != HAL_PROPERTY_TYPE_STRING
)
699 /* don't bother setting the same value */
701 strcmp (hal_property_get_string (prop
), value
) == 0)
704 hal_property_set_string (prop
, value
);
706 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
711 prop
= hal_property_new_string (key
, value
);
713 device
->properties
= g_slist_prepend (device
->properties
, prop
);
715 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
723 hal_device_property_set_int (HalDevice
*device
, const char *key
,
728 /* check if property already exists */
729 prop
= hal_device_property_find (device
, key
);
732 if (hal_property_get_type (prop
) != HAL_PROPERTY_TYPE_INT32
)
735 /* don't bother setting the same value */
736 if (hal_property_get_int (prop
) == value
)
739 hal_property_set_int (prop
, value
);
741 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
745 prop
= hal_property_new_int (key
, value
);
747 device
->properties
= g_slist_prepend (device
->properties
, prop
);
749 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
757 hal_device_property_set_uint64 (HalDevice
*device
, const char *key
,
762 /* check if property already exists */
763 prop
= hal_device_property_find (device
, key
);
766 if (hal_property_get_type (prop
) != HAL_PROPERTY_TYPE_UINT64
)
769 /* don't bother setting the same value */
770 if (hal_property_get_uint64 (prop
) == value
)
773 hal_property_set_uint64 (prop
, value
);
775 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
779 prop
= hal_property_new_uint64 (key
, value
);
781 device
->properties
= g_slist_prepend (device
->properties
, prop
);
783 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
791 hal_device_property_set_bool (HalDevice
*device
, const char *key
,
796 /* check if property already exists */
797 prop
= hal_device_property_find (device
, key
);
800 if (hal_property_get_type (prop
) != HAL_PROPERTY_TYPE_BOOLEAN
)
803 /* don't bother setting the same value */
804 if (hal_property_get_bool (prop
) == value
)
807 hal_property_set_bool (prop
, value
);
809 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
813 prop
= hal_property_new_bool (key
, value
);
815 device
->properties
= g_slist_prepend (device
->properties
, prop
);
817 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
825 hal_device_property_set_double (HalDevice
*device
, const char *key
,
830 /* check if property already exists */
831 prop
= hal_device_property_find (device
, key
);
834 if (hal_property_get_type (prop
) != HAL_PROPERTY_TYPE_DOUBLE
)
837 /* don't bother setting the same value */
838 if (hal_property_get_double (prop
) == value
)
841 hal_property_set_double (prop
, value
);
843 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
847 prop
= hal_property_new_double (key
, value
);
849 device
->properties
= g_slist_prepend (device
->properties
, prop
);
851 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
859 hal_device_copy_property (HalDevice
*from_device
, const char *from
, HalDevice
*to_device
, const char *to
)
865 if (hal_device_has_property (from_device
, from
)) {
866 switch (hal_device_property_get_type (from_device
, from
)) {
867 case HAL_PROPERTY_TYPE_STRING
:
868 rc
= hal_device_property_set_string (
869 to_device
, to
, hal_device_property_get_string (from_device
, from
));
871 case HAL_PROPERTY_TYPE_INT32
:
872 rc
= hal_device_property_set_int (
873 to_device
, to
, hal_device_property_get_int (from_device
, from
));
875 case HAL_PROPERTY_TYPE_UINT64
:
876 rc
= hal_device_property_set_uint64 (
877 to_device
, to
, hal_device_property_get_uint64 (from_device
, from
));
879 case HAL_PROPERTY_TYPE_BOOLEAN
:
880 rc
= hal_device_property_set_bool (
881 to_device
, to
, hal_device_property_get_bool (from_device
, from
));
883 case HAL_PROPERTY_TYPE_DOUBLE
:
884 rc
= hal_device_property_set_double (
885 to_device
, to
, hal_device_property_get_double (from_device
, from
));
894 hal_device_property_remove (HalDevice
*device
, const char *key
)
898 prop
= hal_device_property_find (device
, key
);
903 device
->properties
= g_slist_remove (device
->properties
, prop
);
905 hal_property_free (prop
);
907 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
914 hal_device_property_set_attribute (HalDevice
*device
,
916 enum PropertyAttribute attr
,
921 prop
= hal_device_property_find (device
, key
);
930 hal_device_print (HalDevice
*device
)
934 fprintf (stderr
, "device udi = %s\n", hal_device_get_udi (device
));
936 for (iter
= device
->properties
; iter
!= NULL
; iter
= iter
->next
) {
937 HalProperty
*p
= iter
->data
;
941 key
= hal_property_get_key (p
);
942 type
= hal_property_get_type (p
);
945 case HAL_PROPERTY_TYPE_STRING
:
946 fprintf (stderr
, " %s = '%s' (string)\n", key
,
947 hal_property_get_string (p
));
950 case HAL_PROPERTY_TYPE_INT32
:
951 fprintf (stderr
, " %s = %d 0x%x (int)\n", key
,
952 hal_property_get_int (p
),
953 hal_property_get_int (p
));
956 case HAL_PROPERTY_TYPE_UINT64
:
957 fprintf (stderr
, " %s = %llu 0x%llx (uint64)\n", key
,
958 (long long unsigned int) hal_property_get_uint64 (p
),
959 (long long unsigned int) hal_property_get_uint64 (p
));
962 case HAL_PROPERTY_TYPE_DOUBLE
:
963 fprintf (stderr
, " %s = %g (double)\n", key
,
964 hal_property_get_double (p
));
967 case HAL_PROPERTY_TYPE_BOOLEAN
:
968 fprintf (stderr
, " %s = %s (bool)\n", key
,
969 (hal_property_get_bool (p
) ? "true" :
974 HAL_WARNING (("Unknown property type %d", type
));
978 fprintf (stderr
, "\n");
985 HalDeviceAsyncCallback callback
;
988 guint prop_signal_id
;
993 destroy_async_match_info (AsyncMatchInfo
*ai
)
996 g_signal_handler_disconnect (ai
->device
, ai
->prop_signal_id
);
997 g_source_remove (ai
->timeout_id
);
998 g_object_unref (ai
->device
);
1003 prop_changed_cb (HalDevice
*device
, const char *key
,
1004 gboolean removed
, gboolean added
, gpointer user_data
)
1006 AsyncMatchInfo
*ai
= user_data
;
1008 if (strcmp (key
, ai
->key
) != 0)
1011 /* the property is no longer there */
1016 ai
->callback (ai
->device
, ai
->user_data
, TRUE
);
1019 destroy_async_match_info (ai
);
1024 async_wait_timeout (gpointer user_data
)
1026 AsyncMatchInfo
*ai
= (AsyncMatchInfo
*) user_data
;
1028 ai
->callback (ai
->device
, ai
->user_data
, FALSE
);
1030 destroy_async_match_info (ai
);
1036 hal_device_async_wait_property (HalDevice
*device
,
1038 HalDeviceAsyncCallback callback
,
1045 /* check if property already exists */
1046 prop
= hal_device_property_find (device
, key
);
1048 if (prop
!= NULL
|| timeout
==0) {
1049 callback (device
, user_data
, prop
!= NULL
);
1053 ai
= g_new0 (AsyncMatchInfo
, 1);
1055 ai
->device
= g_object_ref (device
);
1056 ai
->key
= g_strdup (key
);
1057 ai
->callback
= callback
;
1058 ai
->user_data
= user_data
;
1060 ai
->prop_signal_id
= g_signal_connect (device
, "property_changed",
1061 G_CALLBACK (prop_changed_cb
),
1064 ai
->timeout_id
= g_timeout_add (timeout
, async_wait_timeout
, ai
);
1068 hal_device_callouts_finished (HalDevice
*device
)
1070 g_signal_emit (device
, signals
[CALLOUTS_FINISHED
], 0);
1073 /** Used when giving up on a device, e.g. if no device file appeared
1076 hal_device_cancel (HalDevice
*device
)
1078 HAL_INFO (("udi=%s", device
->udi
));
1079 g_signal_emit (device
, signals
[CANCELLED
], 0);
1086 hal_device_property_get_strlist (HalDevice
*device
,
1091 g_return_val_if_fail (device
!= NULL
, NULL
);
1092 g_return_val_if_fail (key
!= NULL
, NULL
);
1094 prop
= hal_device_property_find (device
, key
);
1097 return hal_property_get_strlist (prop
);
1103 hal_device_property_get_strlist_elem (HalDevice
*device
,
1110 strlist
= hal_device_property_get_strlist (device
, key
);
1111 if (strlist
== NULL
)
1114 i
= g_slist_nth (strlist
, index
);
1118 return (const char *) i
->data
;
1122 hal_device_property_strlist_append (HalDevice
*device
,
1128 /* check if property already exists */
1129 prop
= hal_device_property_find (device
, key
);
1132 if (hal_property_get_type (prop
) != HAL_PROPERTY_TYPE_STRLIST
)
1135 hal_property_strlist_append (prop
, value
);
1137 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
1141 prop
= hal_property_new_strlist (key
);
1142 hal_property_strlist_append (prop
, value
);
1144 device
->properties
= g_slist_prepend (device
->properties
, prop
);
1146 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
1154 hal_device_property_strlist_prepend (HalDevice
*device
,
1160 /* check if property already exists */
1161 prop
= hal_device_property_find (device
, key
);
1164 if (hal_property_get_type (prop
) != HAL_PROPERTY_TYPE_STRLIST
)
1167 hal_property_strlist_prepend (prop
, value
);
1169 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
1173 prop
= hal_property_new_strlist (key
);
1174 hal_property_strlist_prepend (prop
, value
);
1176 device
->properties
= g_slist_prepend (device
->properties
, prop
);
1178 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
1186 hal_device_property_strlist_remove_elem (HalDevice
*device
,
1192 /* check if property already exists */
1193 prop
= hal_device_property_find (device
, key
);
1198 if (hal_property_get_type (prop
) != HAL_PROPERTY_TYPE_STRLIST
)
1201 if (hal_property_strlist_remove_elem (prop
, index
)) {
1202 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
1211 hal_device_property_strlist_clear (HalDevice
*device
,
1216 /* check if property already exists */
1217 prop
= hal_device_property_find (device
, key
);
1220 prop
= hal_property_new_strlist (key
);
1222 device
->properties
= g_slist_prepend (device
->properties
, prop
);
1224 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
1230 if (hal_property_get_type (prop
) != HAL_PROPERTY_TYPE_STRLIST
)
1233 if (hal_property_strlist_clear (prop
)) {
1234 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
1244 hal_device_property_strlist_add (HalDevice
*device
,
1253 /* check if property already exists */
1254 prop
= hal_device_property_find (device
, key
);
1257 if (hal_property_get_type (prop
) != HAL_PROPERTY_TYPE_STRLIST
)
1260 res
= hal_property_strlist_add (prop
, value
);
1262 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
1267 prop
= hal_property_new_strlist (key
);
1268 hal_property_strlist_prepend (prop
, value
);
1270 device
->properties
= g_slist_prepend (device
->properties
, prop
);
1272 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
1283 hal_device_property_strlist_remove (HalDevice
*device
,
1289 /* check if property already exists */
1290 prop
= hal_device_property_find (device
, key
);
1295 if (hal_property_get_type (prop
) != HAL_PROPERTY_TYPE_STRLIST
)
1298 if (hal_property_strlist_remove (prop
, value
)) {
1299 g_signal_emit (device
, signals
[PROPERTY_CHANGED
], 0,
1307 hal_device_property_strlist_is_empty (HalDevice
*device
,
1312 if ( hal_device_has_property (device
, key
)) {
1313 strlist
= hal_device_property_get_strlist (device
, key
);
1314 if (strlist
== NULL
)
1317 if (g_slist_length (strlist
) > 0)
1326 hal_device_inc_num_addons (HalDevice
*device
)
1328 device
->num_addons
++;
1332 hal_device_inc_num_ready_addons (HalDevice
*device
)
1334 if (hal_device_are_all_addons_ready (device
)) {
1335 HAL_ERROR (("In hal_device_inc_num_ready_addons for udi=%s but all addons are already ready!",
1340 device
->num_addons_ready
++;
1345 hal_device_are_all_addons_ready (HalDevice
*device
)
1347 if (device
->num_addons_ready
== device
->num_addons
) {