1 /***************************************************************************
4 * libhal.c : HAL daemon C convenience library
6 * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
7 * Copyright (C) 2006 Sjoerd Simons, <sjoerd@luon.net>
8 * Copyright (C) 2007 Codethink Ltd. Author Rob Taylor <rob.taylor@codethink.co.uk>
10 * Licensed under the Academic Free License version 2.1
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 **************************************************************************/
35 #include <dbus/dbus.h>
41 # define _(String) dgettext (GETTEXT_PACKAGE, String)
43 # define N_(String) gettext_noop (String)
45 # define N_(String) (String)
48 /* Stubs that do something close enough. */
49 # define textdomain(String) (String)
50 # define gettext(String) (String)
51 # define dgettext(Domain,Message) (Message)
52 # define dcgettext(Domain,Message,Type) (Message)
53 # define bindtextdomain(Domain,Directory) (Domain)
55 # define N_(String) (String)
59 * LIBHAL_CHECK_PARAM_VALID:
60 * @_param_: the prameter to check for
61 * @_name_: the name of the prameter (for debug output)
62 * @_ret_: what to use for return value if the prameter is NULL
64 * Handy macro for checking whether a parameter is valid and not NULL.
66 #define LIBHAL_CHECK_PARAM_VALID(_param_,_name_,_ret_) \
68 if (_param_ == NULL) { \
70 "%s %d : invalid paramater. %s is NULL.\n", \
71 __FILE__, __LINE__, _name_); \
77 * LIBHAL_CHECK_UDI_VALID:
78 * @_udi_: the UID to check for
79 * @_ret_: what to use for return value if udi is invalid
81 * Handy macro for checking whether a UID is valid and not NULL.
83 #define LIBHAL_CHECK_UDI_VALID(_udi_,_ret_) \
85 if (_udi_ == NULL) { \
87 "%s %d : invalid udi %s. udi is NULL.\n", \
88 __FILE__, __LINE__, _udi_); \
91 if(strncmp(_udi_, "/org/freedesktop/Hal/devices/", 29) != 0) { \
93 "%s %d : invalid udi: %s doesn't start" \
94 "with '/org/freedesktop/Hal/devices/'. \n", \
95 __FILE__, __LINE__, _udi_); \
101 static char **libhal_get_string_array_from_iter (DBusMessageIter
*iter
, int *num_elements
);
103 static dbus_bool_t
libhal_property_fill_value_from_variant (LibHalProperty
*p
, DBusMessageIter
*var_iter
);
107 * libhal_free_string_array:
108 * @str_array: the array to be freed
110 * Frees a NULL-terminated array of strings. If passed NULL, does nothing.
113 libhal_free_string_array (char **str_array
)
115 if (str_array
!= NULL
) {
118 for (i
= 0; str_array
[i
] != NULL
; i
++) {
129 * libhal_get_string_array_from_iter:
130 * @iter: the message iterator to extract the strings from
131 * @num_elements: pointer to an integer where to store number of elements (can be NULL)
133 * Creates a NULL terminated array of strings from a dbus message iterator.
135 * Returns: pointer to the string array
138 libhal_get_string_array_from_iter (DBusMessageIter
*iter
, int *num_elements
)
145 buffer
= (char **)malloc (sizeof (char *) * 8);
151 while (dbus_message_iter_get_arg_type (iter
) == DBUS_TYPE_STRING
) {
155 if ((count
% 8) == 0 && count
!= 0) {
156 t
= realloc (buffer
, sizeof (char *) * (count
+ 8));
163 dbus_message_iter_get_basic (iter
, &value
);
164 str
= strdup (value
);
170 dbus_message_iter_next(iter
);
174 if ((count
% 8) == 0) {
175 t
= realloc (buffer
, sizeof (char *) * (count
+ 1));
182 buffer
[count
] = NULL
;
183 if (num_elements
!= NULL
)
184 *num_elements
= count
;
190 fprintf (stderr
, "%s %d : error allocating memory\n", __FILE__
, __LINE__
);
196 * libhal_free_string:
197 * @str: the nul-terminated sting to free
199 * Used to free strings returned by libhal.
202 libhal_free_string (char *str
)
214 * Represents a set of properties. Opaque; use the
215 * libhal_property_set_*() family of functions to access it.
217 struct LibHalPropertySet_s
{
218 unsigned int num_properties
; /**< Number of properties in set */
219 LibHalProperty
*properties_head
;
220 /**< Pointer to first property or NULL
221 * if there are no properties */
227 * Represents a property. Opaque.
229 struct LibHalProperty_s
{
230 LibHalPropertyType type
; /**< Type of property */
231 char *key
; /**< ASCII string */
233 /** Possible values of the property */
235 char *str_value
; /**< UTF-8 zero-terminated string */
236 dbus_int32_t int_value
;
237 /**< 32-bit signed integer */
238 dbus_uint64_t uint64_value
;
239 /**< 64-bit unsigned integer */
240 double double_value
; /**< IEEE754 double precision float */
241 dbus_bool_t bool_value
;
244 char **strlist_value
; /**< List of UTF-8 zero-terminated strings */
247 LibHalProperty
*next
; /**< Next property or NULL if this is
254 * Context for connection to the HAL daemon. Opaque, use the
255 * libhal_ctx_*() family of functions to access it.
257 struct LibHalContext_s
{
258 DBusConnection
*connection
; /**< D-BUS connection */
259 dbus_bool_t is_initialized
; /**< Are we initialised */
260 dbus_bool_t is_shutdown
; /**< Have we been shutdown */
261 dbus_bool_t cache_enabled
; /**< Is the cache enabled */
262 dbus_bool_t is_direct
; /**< Whether the connection to hald is direct */
265 LibHalDeviceAdded device_added
;
267 /** Device removed */
268 LibHalDeviceRemoved device_removed
;
270 /** Device got a new capability */
271 LibHalDeviceNewCapability device_new_capability
;
273 /** Device got a new capability */
274 LibHalDeviceLostCapability device_lost_capability
;
276 /** A property of a device changed */
277 LibHalDevicePropertyModified device_property_modified
;
279 /** A non-continous event on the device occured */
280 LibHalDeviceCondition device_condition
;
282 void *user_data
; /**< User data */
286 * libhal_ctx_set_user_data:
287 * @ctx: the context for the connection to hald
288 * @user_data: user data
290 * Set user data for the context.
292 * Returns: TRUE if user data was successfully set, FALSE if otherwise
295 libhal_ctx_set_user_data(LibHalContext
*ctx
, void *user_data
)
297 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
298 ctx
->user_data
= user_data
;
303 * libhal_ctx_get_user_data:
304 * @ctx: the context for the connection to hald
306 * Get user data for the context.
308 * Returns: opaque pointer stored through libhal_ctx_set_user_data() or NULL if not set.
311 libhal_ctx_get_user_data(LibHalContext
*ctx
)
313 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
314 return ctx
->user_data
;
319 * libhal_property_fill_value_from_variant:
320 * @p: the property to fill in
321 * @var_iter: variant iterator to extract the value from
323 * Fills in the value for the LibHalProperty given a variant iterator.
325 * Returns: Whether the value was put in.
328 libhal_property_fill_value_from_variant (LibHalProperty
*p
, DBusMessageIter
*var_iter
)
330 DBusMessageIter iter_array
;
332 LIBHAL_CHECK_PARAM_VALID(p
, "LibHalProperty *p", FALSE
);
333 LIBHAL_CHECK_PARAM_VALID(var_iter
, "DBusMessageIter *var_iter", FALSE
);
336 case DBUS_TYPE_ARRAY
:
337 if (dbus_message_iter_get_element_type (var_iter
) != DBUS_TYPE_STRING
)
340 dbus_message_iter_recurse (var_iter
, &iter_array
);
341 p
->v
.strlist_value
= libhal_get_string_array_from_iter (&iter_array
, NULL
);
343 p
->type
= LIBHAL_PROPERTY_TYPE_STRLIST
;
346 case DBUS_TYPE_STRING
:
350 dbus_message_iter_get_basic (var_iter
, &v
);
352 p
->v
.str_value
= strdup (v
);
353 if (p
->v
.str_value
== NULL
)
355 p
->type
= LIBHAL_PROPERTY_TYPE_STRING
;
359 case DBUS_TYPE_INT32
:
363 dbus_message_iter_get_basic (var_iter
, &v
);
366 p
->type
= LIBHAL_PROPERTY_TYPE_INT32
;
370 case DBUS_TYPE_UINT64
:
374 dbus_message_iter_get_basic (var_iter
, &v
);
376 p
->v
.uint64_value
= v
;
377 p
->type
= LIBHAL_PROPERTY_TYPE_UINT64
;
381 case DBUS_TYPE_DOUBLE
:
385 dbus_message_iter_get_basic (var_iter
, &v
);
387 p
->v
.double_value
= v
;
388 p
->type
= LIBHAL_PROPERTY_TYPE_DOUBLE
;
392 case DBUS_TYPE_BOOLEAN
:
396 dbus_message_iter_get_basic (var_iter
, &v
);
398 p
->v
.double_value
= v
;
399 p
->type
= LIBHAL_PROPERTY_TYPE_BOOLEAN
;
404 /** @todo report error */
412 * libhal_device_get_all_properties:
413 * @ctx: the context for the connection to hald
414 * @udi: the Unique id of device
415 * @error: pointer to an initialized dbus error object for returning errors or NULL
417 * Retrieve all the properties on a device.
419 * Returns: An object represent all properties. Must be freed with libhal_free_property_set().
422 libhal_device_get_all_properties (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
424 DBusMessage
*message
;
426 DBusMessageIter reply_iter
;
427 DBusMessageIter dict_iter
;
428 LibHalPropertySet
*result
;
429 LibHalProperty
*p_last
;
432 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
433 LIBHAL_CHECK_UDI_VALID(udi
, NULL
);
435 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
436 "org.freedesktop.Hal.Device",
439 if (message
== NULL
) {
441 "%s %d : Couldn't allocate D-BUS message\n",
446 dbus_error_init (&_error
);
447 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
451 dbus_move_error (&_error
, error
);
452 if (error
!= NULL
&& dbus_error_is_set (error
)) {
455 __FILE__
, __LINE__
, error
->message
);
457 dbus_message_unref (message
);
462 dbus_message_unref (message
);
466 dbus_message_iter_init (reply
, &reply_iter
);
468 result
= malloc (sizeof (LibHalPropertySet
));
473 result->properties = malloc(sizeof(LibHalProperty)*result->num_properties);
474 if( result->properties==NULL )
481 result
->properties_head
= NULL
;
482 result
->num_properties
= 0;
484 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_ARRAY
&&
485 dbus_message_iter_get_element_type (&reply_iter
) != DBUS_TYPE_DICT_ENTRY
) {
486 fprintf (stderr
, "%s %d : error, expecting an array of dict entries\n",
488 dbus_message_unref (message
);
489 dbus_message_unref (reply
);
493 dbus_message_iter_recurse (&reply_iter
, &dict_iter
);
497 while (dbus_message_iter_get_arg_type (&dict_iter
) == DBUS_TYPE_DICT_ENTRY
)
499 DBusMessageIter dict_entry_iter
, var_iter
;
503 dbus_message_iter_recurse (&dict_iter
, &dict_entry_iter
);
505 dbus_message_iter_get_basic (&dict_entry_iter
, &key
);
507 p
= malloc (sizeof (LibHalProperty
));
513 if (result
->num_properties
== 0)
514 result
->properties_head
= p
;
521 p
->key
= strdup (key
);
525 dbus_message_iter_next (&dict_entry_iter
);
527 dbus_message_iter_recurse (&dict_entry_iter
, &var_iter
);
530 p
->type
= dbus_message_iter_get_arg_type (&var_iter
);
532 result
->num_properties
++;
534 if(!libhal_property_fill_value_from_variant (p
, &var_iter
))
537 dbus_message_iter_next (&dict_iter
);
540 dbus_message_unref (message
);
541 dbus_message_unref (reply
);
547 "%s %d : error allocating memory\n",
549 /** @todo FIXME cleanup */
554 * libhal_free_property_set:
555 * @set: property-set to free
557 * Free a property set earlier obtained with libhal_device_get_all_properties().
560 libhal_free_property_set (LibHalPropertySet
* set
)
568 for (p
= set
->properties_head
; p
!= NULL
; p
= q
) {
570 if (p
->type
== DBUS_TYPE_STRING
)
571 free (p
->v
.str_value
);
572 if (p
->type
== LIBHAL_PROPERTY_TYPE_STRLIST
)
573 libhal_free_string_array (p
->v
.strlist_value
);
581 * libhal_property_set_get_num_elems:
582 * @set: property set to consider
584 * Get the number of properties in a property set.
586 * Returns: number of properties in given property set
589 libhal_property_set_get_num_elems (LibHalPropertySet
*set
)
591 unsigned int num_elems
;
594 LIBHAL_CHECK_PARAM_VALID(set
, "*set", 0);
597 for (p
= set
->properties_head
; p
!= NULL
; p
= p
->next
)
603 static LibHalProperty
*
604 property_set_lookup (const LibHalPropertySet
*set
, const char *key
)
608 LIBHAL_CHECK_PARAM_VALID(set
, "*set", NULL
);
609 LIBHAL_CHECK_PARAM_VALID(key
, "*key", NULL
);
611 for (p
= set
->properties_head
; p
!= NULL
; p
= p
->next
)
612 if (strcmp (key
, p
->key
) == 0)
619 * libhal_ps_get_type:
621 * @key: name of property to inspect
623 * Get the type of a given property.
625 * Returns: the #LibHalPropertyType of the given property,
626 * LIBHAL_PROPERTY_TYPE_INVALID if property is not in the set
629 libhal_ps_get_type (const LibHalPropertySet
*set
, const char *key
)
633 LIBHAL_CHECK_PARAM_VALID(set
, "*set", LIBHAL_PROPERTY_TYPE_INVALID
);
634 LIBHAL_CHECK_PARAM_VALID(key
, "*key", LIBHAL_PROPERTY_TYPE_INVALID
);
636 p
= property_set_lookup (set
, key
);
637 if (p
) return p
->type
;
638 else return LIBHAL_PROPERTY_TYPE_INVALID
;
642 * libhal_ps_get_string:
644 * @key: name of property to inspect
646 * Get the value of a property of type string.
648 * Returns: UTF8 nul-terminated string. This pointer is only valid
649 * until libhal_free_property_set() is invoked on the property set
650 * this property belongs to. NULL if property is not in the set or not a string
653 libhal_ps_get_string (const LibHalPropertySet
*set
, const char *key
)
657 LIBHAL_CHECK_PARAM_VALID(set
, "*set", NULL
);
658 LIBHAL_CHECK_PARAM_VALID(key
, "*key", NULL
);
660 p
= property_set_lookup (set
, key
);
661 if (p
&& p
->type
== LIBHAL_PROPERTY_TYPE_STRING
)
662 return p
->v
.str_value
;
669 * @key: name of property to inspect
671 * Get the value of a property of type signed integer.
673 * Returns: property value (32-bit signed integer)
676 libhal_ps_get_int32 (const LibHalPropertySet
*set
, const char *key
)
680 LIBHAL_CHECK_PARAM_VALID(set
, "*set", 0);
681 LIBHAL_CHECK_PARAM_VALID(key
, "*key", 0);
683 p
= property_set_lookup (set
, key
);
684 if (p
&& p
->type
== LIBHAL_PROPERTY_TYPE_INT32
)
685 return p
->v
.int_value
;
690 * libhal_ps_get_uint64:
692 * @key: name of property to inspect
694 * Get the value of a property of type unsigned integer.
696 * Returns: property value (64-bit unsigned integer)
699 libhal_ps_get_uint64 (const LibHalPropertySet
*set
, const char *key
)
703 LIBHAL_CHECK_PARAM_VALID(set
, "*set", 0);
704 LIBHAL_CHECK_PARAM_VALID(key
, "*key", 0);
706 p
= property_set_lookup (set
, key
);
707 if (p
&& p
->type
== LIBHAL_PROPERTY_TYPE_UINT64
)
708 return p
->v
.uint64_value
;
713 * libhal_ps_get_double:
715 * @key: name of property to inspect
717 * Get the value of a property of type double.
719 * Returns: property value (IEEE754 double precision float)
722 libhal_ps_get_double (const LibHalPropertySet
*set
, const char *key
)
726 LIBHAL_CHECK_PARAM_VALID(set
, "*set", 0.0);
727 LIBHAL_CHECK_PARAM_VALID(key
, "*key", 0.0);
729 p
= property_set_lookup (set
, key
);
730 if (p
&& p
->type
== LIBHAL_PROPERTY_TYPE_DOUBLE
)
731 return p
->v
.double_value
;
736 * libhal_ps_get_bool:
738 * @key: name of property to inspect
740 * Get the value of a property of type bool.
742 * Returns: property value (bool)
745 libhal_ps_get_bool (const LibHalPropertySet
*set
, const char *key
)
749 LIBHAL_CHECK_PARAM_VALID(set
, "*set", FALSE
);
750 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
752 p
= property_set_lookup (set
, key
);
753 if (p
&& p
->type
== LIBHAL_PROPERTY_TYPE_BOOLEAN
)
754 return p
->v
.bool_value
;
759 * libhal_ps_get_strlist:
761 * @key: name of property to inspect
763 * Get the value of a property of type string list.
765 * Returns: pointer to array of strings, this is owned by the property set
768 libhal_ps_get_strlist (const LibHalPropertySet
*set
, const char *key
)
772 LIBHAL_CHECK_PARAM_VALID(set
, "*set", NULL
);
773 LIBHAL_CHECK_PARAM_VALID(key
, "*key", NULL
);
775 p
= property_set_lookup (set
, key
);
776 if (p
&& p
->type
== LIBHAL_PROPERTY_TYPE_STRLIST
)
777 return (const char *const *) p
->v
.strlist_value
;
784 * @iter: iterator object
785 * @set: property set to iterate over
787 * Initialize a property set iterator.
791 libhal_psi_init (LibHalPropertySetIterator
* iter
, LibHalPropertySet
* set
)
798 iter
->cur_prop
= set
->properties_head
;
803 * libhal_psi_has_more:
804 * @iter: iterator object
806 * Determine whether there are more properties to iterate over.
808 * Returns: TRUE if there are more properties, FALSE otherwise.
811 libhal_psi_has_more (LibHalPropertySetIterator
* iter
)
813 return iter
->idx
< iter
->set
->num_properties
;
818 * @iter: iterator object
820 * Advance iterator to next property.
823 libhal_psi_next (LibHalPropertySetIterator
* iter
)
826 iter
->cur_prop
= iter
->cur_prop
->next
;
830 * libhal_psi_get_type:
831 * @iter: iterator object
833 * Get type of property.
835 * Returns: the property type at the iterator's position
838 libhal_psi_get_type (LibHalPropertySetIterator
* iter
)
840 return iter
->cur_prop
->type
;
844 * libhal_psi_get_key:
845 * @iter: iterator object
847 * Get the key of a property.
849 * Returns: ASCII nul-terminated string. This pointer is only valid
850 * until libhal_free_property_set() is invoked on the property set
851 * this property belongs to.
854 libhal_psi_get_key (LibHalPropertySetIterator
* iter
)
856 return iter
->cur_prop
->key
;
860 * libhal_psi_get_string:
861 * @iter: iterator object
863 * Get the value of a property of type string.
865 * Returns: UTF8 nul-terminated string. This pointer is only valid
866 * until libhal_free_property_set() is invoked on the property set
867 * this property belongs to.
870 libhal_psi_get_string (LibHalPropertySetIterator
* iter
)
872 return iter
->cur_prop
->v
.str_value
;
876 * libhal_psi_get_int:
877 * @iter: iterator object
879 * Get the value of a property of type signed integer.
881 * Returns: property value (32-bit signed integer)
884 libhal_psi_get_int (LibHalPropertySetIterator
* iter
)
886 return iter
->cur_prop
->v
.int_value
;
890 * libhal_psi_get_uint64:
891 * @iter: iterator object
893 * Get the value of a property of type unsigned integer.
895 * Returns: property value (64-bit unsigned integer)
898 libhal_psi_get_uint64 (LibHalPropertySetIterator
* iter
)
900 return iter
->cur_prop
->v
.uint64_value
;
904 * libhal_psi_get_double:
905 * @iter: iterator object
907 * Get the value of a property of type double.
909 * Returns: property value (IEEE754 double precision float)
912 libhal_psi_get_double (LibHalPropertySetIterator
* iter
)
914 return iter
->cur_prop
->v
.double_value
;
918 * libhal_psi_get_bool:
919 * @iter: iterator object
921 * Get the value of a property of type bool.
923 * Returns: property value (bool)
926 libhal_psi_get_bool (LibHalPropertySetIterator
* iter
)
928 return iter
->cur_prop
->v
.bool_value
;
932 * libhal_psi_get_strlist:
933 * @iter: iterator object
935 * Get the value of a property of type string list.
937 * Returns: pointer to array of strings
940 libhal_psi_get_strlist (LibHalPropertySetIterator
* iter
)
942 return iter
->cur_prop
->v
.strlist_value
;
946 static DBusHandlerResult
947 filter_func (DBusConnection
* connection
,
948 DBusMessage
* message
, void *user_data
)
950 const char *object_path
;
952 LibHalContext
*ctx
= (LibHalContext
*) user_data
;
954 if (ctx
->is_shutdown
)
955 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
957 dbus_error_init (&error
);
959 object_path
= dbus_message_get_path (message
);
961 /*fprintf (stderr, "*** libhal filer_func: connection=%p obj_path=%s interface=%s method=%s\n",
963 dbus_message_get_path (message),
964 dbus_message_get_interface (message),
965 dbus_message_get_member (message));
968 if (dbus_message_is_signal (message
, "org.freedesktop.Hal.Manager",
971 if (dbus_message_get_args (message
, &error
,
972 DBUS_TYPE_STRING
, &udi
,
973 DBUS_TYPE_INVALID
)) {
974 if (ctx
->device_added
!= NULL
) {
975 ctx
->device_added (ctx
, udi
);
978 LIBHAL_FREE_DBUS_ERROR(&error
);
980 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
981 } else if (dbus_message_is_signal (message
, "org.freedesktop.Hal.Manager", "DeviceRemoved")) {
983 if (dbus_message_get_args (message
, &error
,
984 DBUS_TYPE_STRING
, &udi
,
985 DBUS_TYPE_INVALID
)) {
986 if (ctx
->device_removed
!= NULL
) {
987 ctx
->device_removed (ctx
, udi
);
990 LIBHAL_FREE_DBUS_ERROR(&error
);
992 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
993 } else if (dbus_message_is_signal (message
, "org.freedesktop.Hal.Manager","NewCapability")) {
996 if (dbus_message_get_args (message
, &error
,
997 DBUS_TYPE_STRING
, &udi
,
998 DBUS_TYPE_STRING
, &capability
,
999 DBUS_TYPE_INVALID
)) {
1000 if (ctx
->device_new_capability
!= NULL
) {
1001 ctx
->device_new_capability (ctx
, udi
, capability
);
1004 LIBHAL_FREE_DBUS_ERROR(&error
);
1006 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
1007 } else if (dbus_message_is_signal (message
, "org.freedesktop.Hal.Device", "Condition")) {
1008 char *condition_name
;
1009 char *condition_detail
;
1010 if (dbus_message_get_args (message
, &error
,
1011 DBUS_TYPE_STRING
, &condition_name
,
1012 DBUS_TYPE_STRING
, &condition_detail
,
1013 DBUS_TYPE_INVALID
)) {
1014 if (ctx
->device_condition
!= NULL
) {
1015 ctx
->device_condition (ctx
, object_path
, condition_name
, condition_detail
);
1018 LIBHAL_FREE_DBUS_ERROR(&error
);
1020 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
1021 } else if (dbus_message_is_signal (message
, "org.freedesktop.Hal.Device", "PropertyModified")) {
1022 if (ctx
->device_property_modified
!= NULL
) {
1025 dbus_bool_t removed
;
1027 int num_modifications
;
1028 DBusMessageIter iter
;
1029 DBusMessageIter iter_array
;
1031 dbus_message_iter_init (message
, &iter
);
1032 dbus_message_iter_get_basic (&iter
, &num_modifications
);
1033 dbus_message_iter_next (&iter
);
1035 dbus_message_iter_recurse (&iter
, &iter_array
);
1037 for (i
= 0; i
< num_modifications
; i
++) {
1038 DBusMessageIter iter_struct
;
1040 dbus_message_iter_recurse (&iter_array
, &iter_struct
);
1042 dbus_message_iter_get_basic (&iter_struct
, &key
);
1043 dbus_message_iter_next (&iter_struct
);
1044 dbus_message_iter_get_basic (&iter_struct
, &removed
);
1045 dbus_message_iter_next (&iter_struct
);
1046 dbus_message_iter_get_basic (&iter_struct
, &added
);
1048 ctx
->device_property_modified (ctx
,
1053 dbus_message_iter_next (&iter_array
);
1057 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
1060 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
1063 /* for i18n purposes */
1064 static dbus_bool_t libhal_already_initialized_once
= FALSE
;
1068 * libhal_get_all_devices:
1069 * @ctx: the context for the connection to hald
1070 * @num_devices: the number of devices will be stored here
1071 * @error: pointer to an initialized dbus error object for returning errors or NULL
1073 * Get all devices in the Global Device List (GDL).
1075 * Returns: An array of device identifiers terminated with NULL. It is
1076 * the responsibility of the caller to free with
1077 * libhal_free_string_array(). If an error occurs NULL is returned.
1080 libhal_get_all_devices (LibHalContext
*ctx
, int *num_devices
, DBusError
*error
)
1082 DBusMessage
*message
;
1084 DBusMessageIter iter_array
, reply_iter
;
1085 char **hal_device_names
;
1088 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
1092 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
1093 "/org/freedesktop/Hal/Manager",
1094 "org.freedesktop.Hal.Manager",
1096 if (message
== NULL
) {
1097 fprintf (stderr
, "%s %d : Could not allocate D-BUS message\n", __FILE__
, __LINE__
);
1101 dbus_error_init (&_error
);
1102 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
, message
, -1, &_error
);
1104 dbus_message_unref (message
);
1106 dbus_move_error (&_error
, error
);
1107 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1110 if (reply
== NULL
) {
1114 /* now analyze reply */
1115 dbus_message_iter_init (reply
, &reply_iter
);
1117 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_ARRAY
) {
1118 fprintf (stderr
, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__
, __LINE__
);
1119 dbus_message_unref (reply
);
1123 dbus_message_iter_recurse (&reply_iter
, &iter_array
);
1125 hal_device_names
= libhal_get_string_array_from_iter (&iter_array
, num_devices
);
1127 dbus_message_unref (reply
);
1128 return hal_device_names
;
1132 * libhal_device_get_property_type:
1133 * @ctx: the context for the connection to hald
1134 * @udi: the Unique Device Id
1135 * @key: name of the property
1136 * @error: pointer to an initialized dbus error object for returning errors or NULL
1138 * Query a property type of a device.
1140 * Returns: A LibHalPropertyType. LIBHAL_PROPERTY_TYPE_INVALID is
1141 * return if the property doesn't exist.
1144 libhal_device_get_property_type (LibHalContext
*ctx
, const char *udi
, const char *key
, DBusError
*error
)
1146 DBusMessage
*message
;
1148 DBusMessageIter iter
, reply_iter
;
1149 LibHalPropertyType type
;
1152 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, LIBHAL_PROPERTY_TYPE_INVALID
); /* or return NULL? */
1153 LIBHAL_CHECK_UDI_VALID(udi
, LIBHAL_PROPERTY_TYPE_INVALID
);
1154 LIBHAL_CHECK_PARAM_VALID(key
, "*key", LIBHAL_PROPERTY_TYPE_INVALID
);
1156 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1157 "org.freedesktop.Hal.Device",
1159 if (message
== NULL
) {
1160 fprintf (stderr
, "%s %d : Couldn't allocate D-BUS message\n", __FILE__
, __LINE__
);
1161 return LIBHAL_PROPERTY_TYPE_INVALID
;
1164 dbus_message_iter_init_append (message
, &iter
);
1165 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1167 dbus_error_init (&_error
);
1168 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1172 dbus_message_unref (message
);
1174 dbus_move_error (&_error
, error
);
1175 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1176 return LIBHAL_PROPERTY_TYPE_INVALID
;
1178 if (reply
== NULL
) {
1179 return LIBHAL_PROPERTY_TYPE_INVALID
;
1182 dbus_message_iter_init (reply
, &reply_iter
);
1183 dbus_message_iter_get_basic (&reply_iter
, &type
);
1185 dbus_message_unref (reply
);
1190 * libhal_device_get_property_strlist:
1191 * @ctx: the context for the connection to hald
1192 * @udi: unique Device Id
1193 * @key: name of the property
1194 * @error: pointer to an initialized dbus error object for returning errors or NULL
1196 * Get the value of a property of type string list.
1198 * Returns: Array of pointers to UTF8 nul-terminated strings
1199 * terminated by NULL. The caller is responsible for freeing this
1200 * string array with the function libhal_free_string_array(). Returns
1201 * NULL if the property didn't exist or we are OOM
1204 libhal_device_get_property_strlist (LibHalContext
*ctx
, const char *udi
, const char *key
, DBusError
*error
)
1206 DBusMessage
*message
;
1208 DBusMessageIter iter
, iter_array
, reply_iter
;
1212 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
1213 LIBHAL_CHECK_UDI_VALID(udi
, NULL
);
1214 LIBHAL_CHECK_PARAM_VALID(key
, "*key", NULL
);
1216 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1217 "org.freedesktop.Hal.Device",
1218 "GetPropertyStringList");
1219 if (message
== NULL
) {
1221 "%s %d : Couldn't allocate D-BUS message\n",
1222 __FILE__
, __LINE__
);
1226 dbus_message_iter_init_append (message
, &iter
);
1227 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1229 dbus_error_init (&_error
);
1230 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1234 dbus_message_unref (message
);
1236 dbus_move_error (&_error
, error
);
1237 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1240 if (reply
== NULL
) {
1243 /* now analyse reply */
1244 dbus_message_iter_init (reply
, &reply_iter
);
1246 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_ARRAY
) {
1247 fprintf (stderr
, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__
, __LINE__
);
1248 dbus_message_unref (reply
);
1252 dbus_message_iter_recurse (&reply_iter
, &iter_array
);
1254 our_strings
= libhal_get_string_array_from_iter (&iter_array
, NULL
);
1256 dbus_message_unref (reply
);
1261 * libhal_device_get_property_string:
1262 * @ctx: the context for the connection to hald
1263 * @udi: the Unique Device Id
1264 * @key: the name of the property
1265 * @error: pointer to an initialized dbus error object for returning errors or NULL
1267 * Get the value of a property of type string.
1269 * Returns: UTF8 nul-terminated string. The caller is responsible for
1270 * freeing this string with the function libhal_free_string(). Returns
1271 * NULL if the property didn't exist or we are OOM.
1274 libhal_device_get_property_string (LibHalContext
*ctx
,
1275 const char *udi
, const char *key
, DBusError
*error
)
1277 DBusMessage
*message
;
1279 DBusMessageIter iter
, reply_iter
;
1284 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
1285 LIBHAL_CHECK_UDI_VALID(udi
, NULL
);
1286 LIBHAL_CHECK_PARAM_VALID(key
, "*key", NULL
);
1288 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1289 "org.freedesktop.Hal.Device",
1290 "GetPropertyString");
1292 if (message
== NULL
) {
1294 "%s %d : Couldn't allocate D-BUS message\n",
1295 __FILE__
, __LINE__
);
1299 dbus_message_iter_init_append (message
, &iter
);
1300 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1302 dbus_error_init (&_error
);
1303 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1307 dbus_message_unref (message
);
1309 dbus_move_error (&_error
, error
);
1310 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1313 if (reply
== NULL
) {
1317 dbus_message_iter_init (reply
, &reply_iter
);
1319 /* now analyze reply */
1320 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
1322 dbus_message_unref (reply
);
1326 dbus_message_iter_get_basic (&reply_iter
, &dbus_str
);
1327 value
= (char *) ((dbus_str
!= NULL
) ? strdup (dbus_str
) : NULL
);
1328 if (value
== NULL
) {
1329 fprintf (stderr
, "%s %d : error allocating memory\n",
1330 __FILE__
, __LINE__
);
1333 dbus_message_unref (reply
);
1338 * libhal_device_get_property_int:
1339 * @ctx: the context for the connection to hald
1340 * @udi: the Unique Device Id
1341 * @key: name of the property
1342 * @error: pointer to an initialized dbus error object for returning errors or NULL
1344 * Get the value of a property of type integer.
1346 * Returns: Property value (32-bit signed integer)
1349 libhal_device_get_property_int (LibHalContext
*ctx
,
1350 const char *udi
, const char *key
, DBusError
*error
)
1352 DBusMessage
*message
;
1354 DBusMessageIter iter
, reply_iter
;
1358 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, -1);
1359 LIBHAL_CHECK_UDI_VALID(udi
, -1);
1360 LIBHAL_CHECK_PARAM_VALID(key
, "*key", -1);
1362 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1363 "org.freedesktop.Hal.Device",
1364 "GetPropertyInteger");
1365 if (message
== NULL
) {
1367 "%s %d : Couldn't allocate D-BUS message\n",
1368 __FILE__
, __LINE__
);
1372 dbus_message_iter_init_append (message
, &iter
);
1373 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1375 dbus_error_init (&_error
);
1376 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1380 dbus_message_unref (message
);
1382 dbus_move_error (&_error
, error
);
1383 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1386 if (reply
== NULL
) {
1390 dbus_message_iter_init (reply
, &reply_iter
);
1392 /* now analyze reply */
1393 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
1396 "%s %d : property '%s' for device '%s' is not "
1397 "of type integer\n", __FILE__
, __LINE__
, key
,
1399 dbus_message_unref (reply
);
1402 dbus_message_iter_get_basic (&reply_iter
, &value
);
1404 dbus_message_unref (reply
);
1409 * libhal_device_get_property_uint64:
1410 * @ctx: the context for the connection to hald
1411 * @udi: the Unique Device Id
1412 * @key: name of the property
1413 * @error: pointer to an initialized dbus error object for returning errors or NULL
1415 * Get the value of a property of type signed integer.
1417 * Returns: Property value (64-bit unsigned integer)
1420 libhal_device_get_property_uint64 (LibHalContext
*ctx
,
1421 const char *udi
, const char *key
, DBusError
*error
)
1423 DBusMessage
*message
;
1425 DBusMessageIter iter
, reply_iter
;
1426 dbus_uint64_t value
;
1429 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, -1);
1430 LIBHAL_CHECK_UDI_VALID(udi
, -1);
1431 LIBHAL_CHECK_PARAM_VALID(key
, "*key", -1);
1433 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1434 "org.freedesktop.Hal.Device",
1435 "GetPropertyInteger");
1436 if (message
== NULL
) {
1438 "%s %d : Couldn't allocate D-BUS message\n",
1439 __FILE__
, __LINE__
);
1443 dbus_message_iter_init_append (message
, &iter
);
1444 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1446 dbus_error_init (&_error
);
1447 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1451 dbus_message_unref (message
);
1453 dbus_move_error (&_error
, error
);
1454 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1457 if (reply
== NULL
) {
1461 dbus_message_iter_init (reply
, &reply_iter
);
1462 /* now analyze reply */
1463 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
1466 "%s %d : property '%s' for device '%s' is not "
1467 "of type integer\n", __FILE__
, __LINE__
, key
,
1469 dbus_message_unref (reply
);
1472 dbus_message_iter_get_basic (&reply_iter
, &value
);
1474 dbus_message_unref (reply
);
1479 * libhal_device_get_property_double:
1480 * @ctx: the context for the connection to hald
1481 * @udi: the Unique Device Id
1482 * @key: name of the property
1483 * @error: pointer to an initialized dbus error object for returning errors or NULL
1485 * Get the value of a property of type double.
1487 * Returns: Property value (IEEE754 double precision float)
1490 libhal_device_get_property_double (LibHalContext
*ctx
,
1491 const char *udi
, const char *key
, DBusError
*error
)
1493 DBusMessage
*message
;
1495 DBusMessageIter iter
, reply_iter
;
1499 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, -1.0);
1500 LIBHAL_CHECK_UDI_VALID(udi
, -1.0);
1501 LIBHAL_CHECK_PARAM_VALID(key
, "*key", -1.0);
1503 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1504 "org.freedesktop.Hal.Device",
1505 "GetPropertyDouble");
1506 if (message
== NULL
) {
1508 "%s %d : Couldn't allocate D-BUS message\n",
1509 __FILE__
, __LINE__
);
1513 dbus_message_iter_init_append (message
, &iter
);
1514 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1516 dbus_error_init (&_error
);
1517 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1521 dbus_message_unref (message
);
1523 dbus_move_error (&_error
, error
);
1524 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1527 if (reply
== NULL
) {
1531 dbus_message_iter_init (reply
, &reply_iter
);
1533 /* now analyze reply */
1534 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
1537 "%s %d : property '%s' for device '%s' is not "
1538 "of type double\n", __FILE__
, __LINE__
, key
, udi
);
1539 dbus_message_unref (reply
);
1542 dbus_message_iter_get_basic (&reply_iter
, &value
);
1544 dbus_message_unref (reply
);
1545 return (double) value
;
1549 * libhal_device_get_property_bool:
1550 * @ctx: the context for the connection to hald
1551 * @udi: the Unique Device Id
1552 * @key: name of the property
1553 * @error: pointer to an initialized dbus error object for returning errors or NULL
1555 * Get the value of a property of type bool.
1557 * Returns: Property value (boolean)
1560 libhal_device_get_property_bool (LibHalContext
*ctx
,
1561 const char *udi
, const char *key
, DBusError
*error
)
1563 DBusMessage
*message
;
1565 DBusMessageIter iter
, reply_iter
;
1569 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1570 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1571 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1573 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1574 "org.freedesktop.Hal.Device",
1575 "GetPropertyBoolean");
1576 if (message
== NULL
) {
1578 "%s %d : Couldn't allocate D-BUS message\n",
1579 __FILE__
, __LINE__
);
1583 dbus_message_iter_init_append (message
, &iter
);
1584 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1586 dbus_error_init (&_error
);
1587 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1591 dbus_message_unref (message
);
1593 dbus_move_error (&_error
, error
);
1594 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1597 if (reply
== NULL
) {
1601 dbus_message_iter_init (reply
, &reply_iter
);
1603 /* now analyze reply */
1604 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
1605 DBUS_TYPE_BOOLEAN
) {
1607 "%s %d : property '%s' for device '%s' is not "
1608 "of type bool\n", __FILE__
, __LINE__
, key
, udi
);
1609 dbus_message_unref (reply
);
1612 dbus_message_iter_get_basic (&reply_iter
, &value
);
1614 dbus_message_unref (reply
);
1619 /* generic helper */
1621 libhal_device_set_property_helper (LibHalContext
*ctx
,
1625 const char *str_value
,
1626 dbus_int32_t int_value
,
1627 dbus_uint64_t uint64_value
,
1628 double double_value
,
1629 dbus_bool_t bool_value
,
1632 DBusMessage
*message
;
1634 DBusMessageIter iter
;
1635 char *method_name
= NULL
;
1637 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1638 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1639 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1641 /** @todo sanity check incoming params */
1643 case DBUS_TYPE_INVALID
:
1644 method_name
= "RemoveProperty";
1646 case DBUS_TYPE_STRING
:
1647 method_name
= "SetPropertyString";
1649 case DBUS_TYPE_INT32
:
1650 case DBUS_TYPE_UINT64
:
1651 method_name
= "SetPropertyInteger";
1653 case DBUS_TYPE_DOUBLE
:
1654 method_name
= "SetPropertyDouble";
1656 case DBUS_TYPE_BOOLEAN
:
1657 method_name
= "SetPropertyBoolean";
1661 /* cannot happen; is not callable from outside this file */
1665 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1666 "org.freedesktop.Hal.Device",
1668 if (message
== NULL
) {
1670 "%s %d : Couldn't allocate D-BUS message\n",
1671 __FILE__
, __LINE__
);
1675 dbus_message_iter_init_append (message
, &iter
);
1676 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1678 case DBUS_TYPE_STRING
:
1679 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &str_value
);
1681 case DBUS_TYPE_INT32
:
1682 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_INT32
, &int_value
);
1684 case DBUS_TYPE_UINT64
:
1685 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_UINT64
, &uint64_value
);
1687 case DBUS_TYPE_DOUBLE
:
1688 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_DOUBLE
, &double_value
);
1690 case DBUS_TYPE_BOOLEAN
:
1691 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_BOOLEAN
, &bool_value
);
1696 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1700 dbus_message_unref (message
);
1702 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1705 if (reply
== NULL
) {
1709 dbus_message_unref (reply
);
1715 * libhal_device_set_property_string:
1716 * @ctx: the context for the connection to hald
1717 * @udi: the Unique Device Id
1718 * @key: name of the property
1719 * @value: value of the property; a UTF8 string
1720 * @error: pointer to an initialized dbus error object for returning errors or NULL
1722 * Set a property of type string.
1724 * Returns: TRUE if the property was set, FALSE if the device didn't
1725 * exist or the property had a different type.
1728 libhal_device_set_property_string (LibHalContext
*ctx
,
1734 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1735 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1736 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1737 LIBHAL_CHECK_PARAM_VALID(value
, "*value", FALSE
);
1739 return libhal_device_set_property_helper (ctx
, udi
, key
,
1741 value
, 0, 0, 0.0f
, FALSE
, error
);
1745 * libhal_device_set_property_int:
1746 * @ctx: the context for the connection to hald
1747 * @udi: the Unique Device Id
1748 * @key: name of the property
1749 * @value: value of the property
1750 * @error: pointer to an initialized dbus error object for returning errors or NULL
1752 * Set a property of type signed integer.
1754 * Returns: TRUE if the property was set, FALSE if the device didn't
1755 * exist or the property had a different type.
1758 libhal_device_set_property_int (LibHalContext
*ctx
, const char *udi
,
1759 const char *key
, dbus_int32_t value
, DBusError
*error
)
1761 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1762 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1763 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1765 return libhal_device_set_property_helper (ctx
, udi
, key
,
1767 NULL
, value
, 0, 0.0f
, FALSE
, error
);
1771 * libhal_device_set_property_uint64:
1772 * @ctx: the context for the connection to hald
1773 * @udi: the Unique Device Id
1774 * @key: name of the property
1775 * @value: value of the property
1776 * @error: pointer to an initialized dbus error object for returning errors or NULL
1778 * Set a property of type unsigned integer.
1780 * Returns: TRUE if the property was set, FALSE if the device didn't
1781 * exist or the property had a different type.
1784 libhal_device_set_property_uint64 (LibHalContext
*ctx
, const char *udi
,
1785 const char *key
, dbus_uint64_t value
, DBusError
*error
)
1787 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1788 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1789 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1791 return libhal_device_set_property_helper (ctx
, udi
, key
,
1793 NULL
, 0, value
, 0.0f
, FALSE
, error
);
1797 * libhal_device_set_property_double:
1798 * @ctx: the context for the connection to hald
1799 * @udi: the Unique Device Id
1800 * @key: name of the property
1801 * @value: value of the property
1802 * @error: pointer to an initialized dbus error object for returning errors or NULL
1804 * Set a property of type double.
1806 * Returns: TRUE if the property was set, FALSE if the device didn't
1807 * exist or the property had a different type.
1810 libhal_device_set_property_double (LibHalContext
*ctx
, const char *udi
,
1811 const char *key
, double value
, DBusError
*error
)
1813 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1814 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1815 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1817 return libhal_device_set_property_helper (ctx
, udi
, key
,
1819 NULL
, 0, 0, value
, FALSE
, error
);
1823 * libhal_device_set_property_bool:
1824 * @ctx: the context for the connection to hald
1825 * @udi: the Unique Device Id
1826 * @key: name of the property
1827 * @value: value of the property
1828 * @error: pointer to an initialized dbus error object for returning errors or NULL
1830 * Set a property of type bool.
1832 * Returns: TRUE if the property was set, FALSE if the device didn't
1833 * exist or the property had a different type.
1836 libhal_device_set_property_bool (LibHalContext
*ctx
, const char *udi
,
1837 const char *key
, dbus_bool_t value
, DBusError
*error
)
1839 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1840 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1841 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1843 return libhal_device_set_property_helper (ctx
, udi
, key
,
1845 NULL
, 0, 0, 0.0f
, value
, error
);
1850 * libhal_device_remove_property:
1851 * @ctx: the context for the connection to hald
1852 * @udi: the Unique Device Id
1853 * @key: name of the property
1854 * @error: pointer to an initialized dbus error object for returning errors or NULL
1856 * Remove a property.
1858 * Returns: TRUE if the property was set, FALSE if the device didn't
1862 libhal_device_remove_property (LibHalContext
*ctx
,
1863 const char *udi
, const char *key
, DBusError
*error
)
1865 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1866 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1867 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1869 return libhal_device_set_property_helper (ctx
, udi
, key
, DBUS_TYPE_INVALID
,
1870 /* DBUS_TYPE_INVALID means remove */
1871 NULL
, 0, 0, 0.0f
, FALSE
, error
);
1875 * libhal_device_property_strlist_append:
1876 * @ctx: the context for the connection to hald
1877 * @udi: the Unique Device Id
1878 * @key: name of the property
1879 * @value: value to append to property
1880 * @error: pointer to an initialized dbus error object for returning errors or NULL
1882 * Append to a property of type strlist.
1884 * Returns: TRUE if the value was appended, FALSE if the device didn't
1885 * exist or the property had a different type.
1888 libhal_device_property_strlist_append (LibHalContext
*ctx
,
1894 DBusMessage
*message
;
1896 DBusMessageIter iter
;
1898 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1899 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1900 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1901 LIBHAL_CHECK_PARAM_VALID(value
, "*value", FALSE
);
1903 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1904 "org.freedesktop.Hal.Device",
1905 "StringListAppend");
1906 if (message
== NULL
) {
1908 "%s %d : Couldn't allocate D-BUS message\n",
1909 __FILE__
, __LINE__
);
1912 dbus_message_iter_init_append (message
, &iter
);
1913 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1914 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &value
);
1916 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1920 dbus_message_unref (message
);
1922 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1925 if (reply
== NULL
) {
1929 dbus_message_unref (reply
);
1934 * libhal_device_property_strlist_prepend:
1935 * @ctx: the context for the connection to hald
1936 * @udi: the Unique Device Id
1937 * @key: name of the property
1938 * @value: value to prepend to property
1939 * @error: pointer to an initialized dbus error object for returning errors or NULL
1941 * Prepend to a property of type strlist.
1943 * Returns: TRUE if the value was prepended, FALSE if the device
1944 * didn't exist or the property had a different type.
1947 libhal_device_property_strlist_prepend (LibHalContext
*ctx
,
1953 DBusMessage
*message
;
1955 DBusMessageIter iter
;
1957 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1958 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1959 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1960 LIBHAL_CHECK_PARAM_VALID(value
, "*value", FALSE
);
1962 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1963 "org.freedesktop.Hal.Device",
1964 "StringListPrepend");
1965 if (message
== NULL
) {
1967 "%s %d : Couldn't allocate D-BUS message\n",
1968 __FILE__
, __LINE__
);
1971 dbus_message_iter_init_append (message
, &iter
);
1972 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1973 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &value
);
1975 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1979 dbus_message_unref (message
);
1981 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1984 if (reply
== NULL
) {
1988 dbus_message_unref (reply
);
1993 * libhal_device_property_strlist_remove_index:
1994 * @ctx: the context for the connection to hald
1995 * @udi: the Unique Device Id
1996 * @key: name of the property
1997 * @idx: index of string to remove in the strlist
1998 * @error: pointer to an initialized dbus error object for returning errors or NULL
2000 * Remove a specified string from a property of type strlist.
2002 * Returns: TRUE if the string was removed, FALSE if the device didn't
2003 * exist or the property had a different type.
2006 libhal_device_property_strlist_remove_index (LibHalContext
*ctx
,
2012 DBusMessage
*message
;
2014 DBusMessageIter iter
;
2016 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2017 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2018 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
2020 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
2021 "org.freedesktop.Hal.Device",
2022 "StringListRemoveIndex");
2023 if (message
== NULL
) {
2025 "%s %d : Couldn't allocate D-BUS message\n",
2026 __FILE__
, __LINE__
);
2029 dbus_message_iter_init_append (message
, &iter
);
2030 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
2031 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_UINT32
, &idx
);
2033 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2037 dbus_message_unref (message
);
2039 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2042 if (reply
== NULL
) {
2046 dbus_message_unref (reply
);
2051 * libhal_device_property_strlist_remove:
2052 * @ctx: the context for the connection to hald
2053 * @udi: the Unique Device Id
2054 * @key: name of the property
2055 * @value: the string to remove
2056 * @error: pointer to an initialized dbus error object for returning errors or NULL
2058 * Remove a specified string from a property of type strlist.
2060 * Returns: TRUE if the string was removed, FALSE if the device didn't
2061 * exist or the property had a different type.
2064 libhal_device_property_strlist_remove (LibHalContext
*ctx
,
2067 const char *value
, DBusError
*error
)
2069 DBusMessage
*message
;
2071 DBusMessageIter iter
;
2073 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2074 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2075 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
2076 LIBHAL_CHECK_PARAM_VALID(value
, "*value", FALSE
);
2078 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
2079 "org.freedesktop.Hal.Device",
2080 "StringListRemove");
2081 if (message
== NULL
) {
2083 "%s %d : Couldn't allocate D-BUS message\n",
2084 __FILE__
, __LINE__
);
2087 dbus_message_iter_init_append (message
, &iter
);
2088 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
2089 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &value
);
2091 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2095 dbus_message_unref (message
);
2097 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2100 if (reply
== NULL
) {
2104 dbus_message_unref (reply
);
2110 * libhal_device_lock:
2111 * @ctx: the context for the connection to hald
2112 * @udi: the Unique Device Id
2113 * @reason_to_lock: a user-presentable reason why the device is locked.
2114 * @reason_why_locked: a pointer to store the reason why the device cannot be locked on failure, or NULL
2115 * @error: pointer to an initialized dbus error object for returning errors or NULL
2117 * Take an advisory lock on the device.
2119 * Returns: TRUE if the lock was obtained, FALSE otherwise
2122 libhal_device_lock (LibHalContext
*ctx
,
2124 const char *reason_to_lock
,
2125 char **reason_why_locked
, DBusError
*error
)
2127 DBusMessage
*message
;
2128 DBusMessageIter iter
;
2131 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2132 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2134 if (reason_why_locked
!= NULL
)
2135 *reason_why_locked
= NULL
;
2137 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2139 "org.freedesktop.Hal.Device",
2142 if (message
== NULL
) {
2144 "%s %d : Couldn't allocate D-BUS message\n",
2145 __FILE__
, __LINE__
);
2149 dbus_message_iter_init_append (message
, &iter
);
2150 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &reason_to_lock
);
2153 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2157 dbus_message_unref (message
);
2159 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2160 if (strcmp (error
->name
,
2161 "org.freedesktop.Hal.DeviceAlreadyLocked") == 0) {
2162 if (reason_why_locked
!= NULL
) {
2163 *reason_why_locked
=
2164 dbus_malloc0 (strlen (error
->message
) + 1);
2165 if (*reason_why_locked
== NULL
)
2167 strcpy (*reason_why_locked
, error
->message
);
2176 dbus_message_unref (reply
);
2182 * libhal_device_unlock:
2183 * @ctx: the context for the connection to hald
2184 * @udi: the Unique Device Id
2185 * @error: pointer to an initialized dbus error object for returning errors or NULL
2187 * Release an advisory lock on the device.
2189 * Returns: TRUE if the device was successfully unlocked,
2193 libhal_device_unlock (LibHalContext
*ctx
,
2194 const char *udi
, DBusError
*error
)
2196 DBusMessage
*message
;
2199 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2200 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2202 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2204 "org.freedesktop.Hal.Device",
2207 if (message
== NULL
) {
2209 "%s %d : Couldn't allocate D-BUS message\n",
2210 __FILE__
, __LINE__
);
2215 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2219 dbus_message_unref (message
);
2221 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2227 dbus_message_unref (reply
);
2234 * libhal_new_device:
2235 * @ctx: the context for the connection to hald
2236 * @error: pointer to an initialized dbus error object for returning errors or NULL
2238 * Create a new device object which will be hidden from applications
2239 * until the CommitToGdl(), ie. libhal_device_commit_to_gdl(), method
2240 * is called. Note that the program invoking this method needs to run
2241 * with super user privileges.
2243 * Returns: Temporary device unique id or NULL if there was a
2244 * problem. This string must be freed by the caller.
2247 libhal_new_device (LibHalContext
*ctx
, DBusError
*error
)
2249 DBusMessage
*message
;
2251 DBusMessageIter reply_iter
;
2255 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
2257 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2258 "/org/freedesktop/Hal/Manager",
2259 "org.freedesktop.Hal.Manager",
2261 if (message
== NULL
) {
2263 "%s %d : Couldn't allocate D-BUS message\n",
2264 __FILE__
, __LINE__
);
2269 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2273 dbus_message_unref (message
);
2275 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2278 if (reply
== NULL
) {
2282 dbus_message_iter_init (reply
, &reply_iter
);
2284 /* now analyze reply */
2285 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_STRING
) {
2287 "%s %d : expected a string in reply to NewDevice\n",
2288 __FILE__
, __LINE__
);
2289 dbus_message_unref (reply
);
2293 dbus_message_iter_get_basic (&reply_iter
, &dbus_str
);
2294 value
= (char *) ((dbus_str
!= NULL
) ? strdup (dbus_str
) : NULL
);
2295 if (value
== NULL
) {
2296 fprintf (stderr
, "%s %d : error allocating memory\n",
2297 __FILE__
, __LINE__
);
2300 dbus_message_unref (reply
);
2306 * libhal_device_commit_to_gdl:
2307 * @ctx: the context for the connection to hald
2308 * @temp_udi: the temporary unique device id as returned by libhal_new_device()
2309 * @udi: the new unique device id.
2310 * @error: pointer to an initialized dbus error object for returning errors or NULL
2312 * When a hidden device has been built using the NewDevice method,
2313 * ie. libhal_new_device(), and the org.freedesktop.Hal.Device
2314 * interface this function will commit it to the global device list.
2316 * This means that the device object will be visible to applications
2317 * and the HAL daemon will possibly attempt to boot the device
2318 * (depending on the property RequireEnable).
2320 * Note that the program invoking this method needs to run with super
2323 * Returns: FALSE if the given unique device id is already in use.
2326 libhal_device_commit_to_gdl (LibHalContext
*ctx
,
2327 const char *temp_udi
, const char *udi
, DBusError
*error
)
2329 DBusMessage
*message
;
2331 DBusMessageIter iter
;
2333 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2334 LIBHAL_CHECK_UDI_VALID(temp_udi
, FALSE
);
2335 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2337 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2338 "/org/freedesktop/Hal/Manager",
2339 "org.freedesktop.Hal.Manager",
2341 if (message
== NULL
) {
2343 "%s %d : Couldn't allocate D-BUS message\n",
2344 __FILE__
, __LINE__
);
2348 dbus_message_iter_init_append (message
, &iter
);
2349 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &temp_udi
);
2350 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &udi
);
2353 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2357 dbus_message_unref (message
);
2359 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2362 if (reply
== NULL
) {
2366 dbus_message_unref (reply
);
2371 * libhal_remove_device:
2372 * @ctx: the context for the connection to hald
2373 * @udi: the Unique device id.
2374 * @error: pointer to an initialized dbus error object for returning errors or NULL
2376 * This method can be invoked when a device is removed. The HAL daemon
2377 * will shut down the device. Note that the device may still be in the
2378 * device list if the Persistent property is set to true.
2380 * Note that the program invoking this method needs to run with super
2383 * Returns: TRUE if the device was removed, FALSE otherwise
2386 libhal_remove_device (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
2388 DBusMessage
*message
;
2390 DBusMessageIter iter
;
2392 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2393 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2395 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2396 "/org/freedesktop/Hal/Manager",
2397 "org.freedesktop.Hal.Manager",
2399 if (message
== NULL
) {
2401 "%s %d : Couldn't allocate D-BUS message\n",
2402 __FILE__
, __LINE__
);
2406 dbus_message_iter_init_append (message
, &iter
);
2407 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &udi
);
2410 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2414 dbus_message_unref (message
);
2416 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2419 if (reply
== NULL
) {
2423 dbus_message_unref (reply
);
2428 * libhal_device_exists:
2429 * @ctx: the context for the connection to hald
2430 * @udi: the Unique device id.
2431 * @error: pointer to an initialized dbus error object for returning errors or NULL
2433 * Determine if a device exists.
2435 * Returns: TRUE if the device exists
2438 libhal_device_exists (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
2440 DBusMessage
*message
;
2442 DBusMessageIter iter
, reply_iter
;
2446 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2447 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2449 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2450 "/org/freedesktop/Hal/Manager",
2451 "org.freedesktop.Hal.Manager",
2453 if (message
== NULL
) {
2455 "%s %d : Couldn't allocate D-BUS message\n",
2456 __FILE__
, __LINE__
);
2460 dbus_message_iter_init_append (message
, &iter
);
2461 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &udi
);
2463 dbus_error_init (&_error
);
2464 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2468 dbus_message_unref (message
);
2470 dbus_move_error (&_error
, error
);
2471 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2474 if (reply
== NULL
) {
2478 dbus_message_iter_init (reply
, &reply_iter
);
2480 /* now analyze reply */
2481 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_BOOLEAN
) {
2483 "%s %d : expected a bool in reply to DeviceExists\n",
2484 __FILE__
, __LINE__
);
2485 dbus_message_unref (reply
);
2489 dbus_message_iter_get_basic (&reply_iter
, &value
);
2491 dbus_message_unref (reply
);
2496 * libhal_device_property_exists:
2497 * @ctx: the context for the connection to hald
2498 * @udi: the Unique device id.
2499 * @key: name of the property
2500 * @error: pointer to an initialized dbus error object for returning errors or NULL
2502 * Determine if a property on a device exists.
2504 * Returns: TRUE if the device exists, FALSE otherwise
2507 libhal_device_property_exists (LibHalContext
*ctx
,
2508 const char *udi
, const char *key
, DBusError
*error
)
2510 DBusMessage
*message
;
2512 DBusMessageIter iter
, reply_iter
;
2516 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2517 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2518 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
2520 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
2521 "org.freedesktop.Hal.Device",
2523 if (message
== NULL
) {
2525 "%s %d : Couldn't allocate D-BUS message\n",
2526 __FILE__
, __LINE__
);
2530 dbus_message_iter_init_append (message
, &iter
);
2531 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
2533 dbus_error_init (&_error
);
2534 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2538 dbus_message_unref (message
);
2540 dbus_move_error (&_error
, error
);
2541 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2544 if (reply
== NULL
) {
2548 dbus_message_iter_init (reply
, &reply_iter
);
2550 /* now analyse reply */
2551 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_BOOLEAN
) {
2552 fprintf (stderr
, "%s %d : expected a bool in reply to "
2553 "PropertyExists\n", __FILE__
, __LINE__
);
2554 dbus_message_unref (reply
);
2558 dbus_message_iter_get_basic (&reply_iter
, &value
);
2560 dbus_message_unref (reply
);
2565 * libhal_merge_properties:
2566 * @ctx: the context for the connection to hald
2567 * @target_udi: the Unique device id of target device to merge to
2568 * @source_udi: the Unique device id of device to merge from
2569 * @error: pointer to an initialized dbus error object for returning errors or NULL
2571 * Merge properties from one device to another.
2573 * Returns: TRUE if the properties were merged, FALSE otherwise
2576 libhal_merge_properties (LibHalContext
*ctx
,
2577 const char *target_udi
, const char *source_udi
, DBusError
*error
)
2579 DBusMessage
*message
;
2581 DBusMessageIter iter
;
2583 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2584 LIBHAL_CHECK_UDI_VALID(target_udi
, FALSE
);
2585 LIBHAL_CHECK_UDI_VALID(source_udi
, FALSE
);
2587 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2588 "/org/freedesktop/Hal/Manager",
2589 "org.freedesktop.Hal.Manager",
2591 if (message
== NULL
) {
2593 "%s %d : Couldn't allocate D-BUS message\n",
2594 __FILE__
, __LINE__
);
2598 dbus_message_iter_init_append (message
, &iter
);
2599 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &target_udi
);
2600 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &source_udi
);
2603 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2607 dbus_message_unref (message
);
2609 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2612 if (reply
== NULL
) {
2616 dbus_message_unref (reply
);
2621 * libhal_device_matches:
2622 * @ctx: the context for the connection to hald
2623 * @udi1: the Unique Device Id for device 1
2624 * @udi2: the Unique Device Id for device 2
2625 * @property_namespace: the namespace for set of devices, e.g. "usb"
2626 * @error: pointer to an initialized dbus error object for returning errors or NULL
2628 * Check a set of properties for two devices matches.
2630 * Checks that all properties where keys, starting with a given value
2631 * (namespace), of the first device is in the second device and that
2632 * they got the same value and type.
2634 * Note that the other inclusion isn't tested, so there could be
2635 * properties (from the given namespace) in the second device not
2636 * present in the first device.
2638 * Returns: TRUE if all properties starting with the given namespace
2639 * parameter from one device is in the other and have the same value.
2642 libhal_device_matches (LibHalContext
*ctx
,
2643 const char *udi1
, const char *udi2
,
2644 const char *property_namespace
, DBusError
*error
)
2646 DBusMessage
*message
;
2648 DBusMessageIter iter
, reply_iter
;
2652 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2653 LIBHAL_CHECK_UDI_VALID(udi1
, FALSE
);
2654 LIBHAL_CHECK_UDI_VALID(udi2
, FALSE
);
2655 LIBHAL_CHECK_PARAM_VALID(property_namespace
, "*property_namespace", FALSE
);
2657 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2658 "/org/freedesktop/Hal/Manager",
2659 "org.freedesktop.Hal.Manager",
2661 if (message
== NULL
) {
2663 "%s %d : Couldn't allocate D-BUS message\n",
2664 __FILE__
, __LINE__
);
2668 dbus_message_iter_init_append (message
, &iter
);
2669 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, udi1
);
2670 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, udi2
);
2671 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, property_namespace
);
2673 dbus_error_init (&_error
);
2674 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2678 dbus_message_unref (message
);
2680 dbus_move_error (&_error
, error
);
2681 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2684 if (reply
== NULL
) {
2687 /* now analyse reply */
2688 dbus_message_iter_init (reply
, &reply_iter
);
2690 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_BOOLEAN
) {
2692 "%s %d : expected a bool in reply to DeviceMatches\n",
2693 __FILE__
, __LINE__
);
2694 dbus_message_unref (reply
);
2698 dbus_message_iter_get_basic (&reply_iter
, &value
);
2700 dbus_message_unref (reply
);
2705 * libhal_device_print:
2706 * @ctx: the context for the connection to hald
2707 * @udi: the Unique Device Id
2708 * @error: pointer to an initialized dbus error object for returning errors or NULL
2710 * Print a device to stdout; useful for debugging.
2712 * Returns: TRUE if device's information could be obtained, FALSE otherwise
2715 libhal_device_print (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
2719 LibHalPropertySet
*pset
;
2720 LibHalPropertySetIterator i
;
2722 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2723 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2725 printf ("device_id = %s\n", udi
);
2727 if ((pset
= libhal_device_get_all_properties (ctx
, udi
, error
)) == NULL
)
2730 for (libhal_psi_init (&i
, pset
); libhal_psi_has_more (&i
);
2731 libhal_psi_next (&i
)) {
2732 type
= libhal_psi_get_type (&i
);
2733 key
= libhal_psi_get_key (&i
);
2736 case LIBHAL_PROPERTY_TYPE_STRING
:
2737 printf (" %s = '%s' (string)\n", key
,
2738 libhal_psi_get_string (&i
));
2740 case LIBHAL_PROPERTY_TYPE_INT32
:
2741 printf (" %s = %d = 0x%x (int)\n", key
,
2742 libhal_psi_get_int (&i
),
2743 libhal_psi_get_int (&i
));
2745 case LIBHAL_PROPERTY_TYPE_UINT64
:
2746 printf (" %s = %llu = 0x%llx (uint64)\n", key
,
2747 (long long unsigned int) libhal_psi_get_uint64 (&i
),
2748 (long long unsigned int) libhal_psi_get_uint64 (&i
));
2750 case LIBHAL_PROPERTY_TYPE_BOOLEAN
:
2751 printf (" %s = %s (bool)\n", key
,
2752 (libhal_psi_get_bool (&i
) ? "true" :
2755 case LIBHAL_PROPERTY_TYPE_DOUBLE
:
2756 printf (" %s = %g (double)\n", key
,
2757 libhal_psi_get_double (&i
));
2759 case LIBHAL_PROPERTY_TYPE_STRLIST
:
2764 str_list
= libhal_psi_get_strlist (&i
);
2765 printf (" %s = [", key
);
2766 for (j
= 0; str_list
[j
] != NULL
; j
++) {
2767 printf ("'%s'", str_list
[j
]);
2768 if (str_list
[j
+1] != NULL
)
2771 printf ("] (string list)\n");
2776 printf (" *** unknown type for key %s\n", key
);
2781 libhal_free_property_set (pset
);
2787 * libhal_manager_find_device_string_match:
2788 * @ctx: the context for the connection to hald
2789 * @key: name of the property
2790 * @value: the value to match
2791 * @num_devices: pointer to store number of devices
2792 * @error: pointer to an initialized dbus error object for returning errors or NULL
2794 * Find a device in the GDL where a single string property matches a
2797 * Returns: UDI of devices; free with libhal_free_string_array()
2800 libhal_manager_find_device_string_match (LibHalContext
*ctx
,
2802 const char *value
, int *num_devices
, DBusError
*error
)
2804 DBusMessage
*message
;
2806 DBusMessageIter iter
, iter_array
, reply_iter
;
2807 char **hal_device_names
;
2810 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
2811 LIBHAL_CHECK_PARAM_VALID(key
, "*key", NULL
);
2812 LIBHAL_CHECK_PARAM_VALID(value
, "*value", NULL
);
2814 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2815 "/org/freedesktop/Hal/Manager",
2816 "org.freedesktop.Hal.Manager",
2817 "FindDeviceStringMatch");
2818 if (message
== NULL
) {
2820 "%s %d : Couldn't allocate D-BUS message\n",
2821 __FILE__
, __LINE__
);
2825 dbus_message_iter_init_append (message
, &iter
);
2826 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
2827 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &value
);
2829 dbus_error_init (&_error
);
2830 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2834 dbus_message_unref (message
);
2836 dbus_move_error (&_error
, error
);
2837 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2840 if (reply
== NULL
) {
2843 /* now analyse reply */
2844 dbus_message_iter_init (reply
, &reply_iter
);
2846 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_ARRAY
) {
2847 fprintf (stderr
, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__
, __LINE__
);
2851 dbus_message_iter_recurse (&reply_iter
, &iter_array
);
2853 hal_device_names
= libhal_get_string_array_from_iter (&iter_array
, num_devices
);
2855 dbus_message_unref (reply
);
2856 return hal_device_names
;
2861 * libhal_device_add_capability:
2862 * @ctx: the context for the connection to hald
2863 * @udi: the Unique Device Id
2864 * @capability: the capability name to add
2865 * @error: pointer to an initialized dbus error object for returning errors or NULL
2867 * Assign a capability to a device.
2869 * Returns: TRUE if the capability was added, FALSE if the device didn't exist
2872 libhal_device_add_capability (LibHalContext
*ctx
,
2873 const char *udi
, const char *capability
, DBusError
*error
)
2875 DBusMessage
*message
;
2877 DBusMessageIter iter
;
2879 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2880 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2881 LIBHAL_CHECK_PARAM_VALID(capability
, "*capability", FALSE
);
2883 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
2884 "org.freedesktop.Hal.Device",
2886 if (message
== NULL
) {
2888 "%s %d : Couldn't allocate D-BUS message\n",
2889 __FILE__
, __LINE__
);
2893 dbus_message_iter_init_append (message
, &iter
);
2894 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &capability
);
2897 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2901 dbus_message_unref (message
);
2903 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2906 if (reply
== NULL
) {
2910 dbus_message_unref (reply
);
2915 * libhal_device_query_capability:
2916 * @ctx: the context for the connection to hald
2917 * @udi: the Unique Device Id
2918 * @capability: the capability name
2919 * @error: pointer to an initialized dbus error object for returning errors or NULL
2921 * Check if a device has a capability. The result is undefined if the
2922 * device doesn't exist.
2924 * Returns: TRUE if the device has the capability, otherwise FALSE
2927 libhal_device_query_capability (LibHalContext
*ctx
, const char *udi
, const char *capability
, DBusError
*error
)
2933 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2934 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2935 LIBHAL_CHECK_PARAM_VALID(capability
, "*capability", FALSE
);
2939 caps
= libhal_device_get_property_strlist (ctx
, udi
, "info.capabilities", error
);
2941 for (i
= 0; caps
[i
] != NULL
; i
++) {
2942 if (strcmp (caps
[i
], capability
) == 0) {
2947 libhal_free_string_array (caps
);
2954 * libhal_find_device_by_capability:
2955 * @ctx: the context for the connection to hald
2956 * @capability: the capability name
2957 * @num_devices: pointer to store number of devices
2958 * @error: pointer to an initialized dbus error object for returning errors or NULL
2960 * Find devices with a given capability.
2962 * Returns: UDI of devices; free with libhal_free_string_array()
2965 libhal_find_device_by_capability (LibHalContext
*ctx
,
2966 const char *capability
, int *num_devices
, DBusError
*error
)
2968 DBusMessage
*message
;
2970 DBusMessageIter iter
, iter_array
, reply_iter
;
2971 char **hal_device_names
;
2974 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
2975 LIBHAL_CHECK_PARAM_VALID(capability
, "*capability", NULL
);
2977 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2978 "/org/freedesktop/Hal/Manager",
2979 "org.freedesktop.Hal.Manager",
2980 "FindDeviceByCapability");
2981 if (message
== NULL
) {
2983 "%s %d : Couldn't allocate D-BUS message\n",
2984 __FILE__
, __LINE__
);
2988 dbus_message_iter_init_append (message
, &iter
);
2989 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &capability
);
2991 dbus_error_init (&_error
);
2992 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2996 dbus_message_unref (message
);
2998 dbus_move_error (&_error
, error
);
2999 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3002 if (reply
== NULL
) {
3005 /* now analyse reply */
3006 dbus_message_iter_init (reply
, &reply_iter
);
3008 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_ARRAY
) {
3009 fprintf (stderr
, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__
, __LINE__
);
3013 dbus_message_iter_recurse (&reply_iter
, &iter_array
);
3015 hal_device_names
= libhal_get_string_array_from_iter (&iter_array
, num_devices
);
3017 dbus_message_unref (reply
);
3018 return hal_device_names
;
3022 * libhal_device_property_watch_all:
3023 * @ctx: the context for the connection to hald
3024 * @error: pointer to an initialized dbus error object for returning errors or NULL
3026 * Watch all devices, ie. the device_property_changed callback is
3027 * invoked when the properties on any device changes.
3029 * Returns: TRUE only if the operation succeeded
3032 libhal_device_property_watch_all (LibHalContext
*ctx
, DBusError
*error
)
3034 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3036 dbus_bus_add_match (ctx
->connection
,
3038 "interface='org.freedesktop.Hal.Device',"
3039 "sender='org.freedesktop.Hal'", error
);
3040 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3048 * libhal_device_add_property_watch:
3049 * @ctx: the context for the connection to hald
3050 * @udi: the Unique Device Id
3051 * @error: pointer to an initialized dbus error object for returning errors or NULL
3053 * Add a watch on a device, so the device_property_changed callback is
3054 * invoked when the properties on the given device changes.
3056 * The application itself is responsible for deleting the watch, using
3057 * libhal_device_remove_property_watch, if the device is removed.
3059 * Returns: TRUE only if the operation succeeded
3062 libhal_device_add_property_watch (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
3066 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3067 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3071 "interface='org.freedesktop.Hal.Device',"
3072 "sender='org.freedesktop.Hal'," "path=%s", udi
);
3074 dbus_bus_add_match (ctx
->connection
, buf
, error
);
3075 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3083 * libhal_device_remove_property_watch:
3084 * @ctx: the context for the connection to hald
3085 * @udi: the Unique Device Id
3086 * @error: pointer to an initialized dbus error object for returning errors or NULL
3088 * Remove a watch on a device.
3090 * Returns: TRUE only if the operation succeeded
3093 libhal_device_remove_property_watch (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
3097 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3098 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3102 "interface='org.freedesktop.Hal.Device',"
3103 "sender='org.freedesktop.Hal'," "path=%s", udi
);
3105 dbus_bus_remove_match (ctx
->connection
, buf
, error
);
3106 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3116 * Create a new LibHalContext
3118 * Returns: a new uninitialized LibHalContext object
3121 libhal_ctx_new (void)
3125 if (!libhal_already_initialized_once
) {
3126 bindtextdomain (GETTEXT_PACKAGE
, PACKAGE_LOCALE_DIR
);
3127 bind_textdomain_codeset (GETTEXT_PACKAGE
, "UTF-8");
3129 libhal_already_initialized_once
= TRUE
;
3132 ctx
= calloc (1, sizeof (LibHalContext
));
3135 "%s %d : Failed to allocate %lu bytes\n",
3136 __FILE__
, __LINE__
, (unsigned long) sizeof (LibHalContext
));
3140 ctx
->is_initialized
= FALSE
;
3141 ctx
->is_shutdown
= FALSE
;
3142 ctx
->connection
= NULL
;
3143 ctx
->is_direct
= FALSE
;
3149 * libhal_ctx_set_cache:
3150 * @ctx: context to enable/disable cache for
3151 * @use_cache: whether or not to use cache
3153 * Enable or disable caching. Note: Caching is not actually
3156 * Returns: TRUE if cache was successfully enabled/disabled, FALSE otherwise
3159 libhal_ctx_set_cache (LibHalContext
*ctx
, dbus_bool_t use_cache
)
3161 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3163 ctx
->cache_enabled
= use_cache
;
3168 * libhal_ctx_set_dbus_connection:
3169 * @ctx: context to set connection for
3170 * @conn: DBus connection to use
3172 * Set DBus connection to use to talk to hald.
3174 * Returns: TRUE if connection was successfully set, FALSE otherwise
3177 libhal_ctx_set_dbus_connection (LibHalContext
*ctx
, DBusConnection
*conn
)
3179 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3184 ctx
->connection
= conn
;
3189 * libhal_ctx_get_dbus_connection:
3190 * @ctx: context to get connection for
3192 * Get DBus connection used for talking to hald.
3194 * Returns: DBus connection to use or NULL
3197 libhal_ctx_get_dbus_connection (LibHalContext
*ctx
)
3199 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
3201 return ctx
->connection
;
3207 * @ctx: Context for connection to hald (D-BUS connection should be set with libhal_ctx_set_dbus_connection)
3208 * @error: pointer to an initialized dbus error object for returning errors or NULL
3210 * Initialize the connection to hald.
3212 * Returns: TRUE if initialization succeeds, FALSE otherwise
3215 libhal_ctx_init (LibHalContext
*ctx
, DBusError
*error
)
3218 dbus_bool_t hald_exists
;
3220 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3222 if (ctx
->connection
== NULL
)
3225 dbus_error_init (&_error
);
3226 hald_exists
= dbus_bus_name_has_owner (ctx
->connection
, "org.freedesktop.Hal", &_error
);
3227 dbus_move_error (&_error
, error
);
3228 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3237 if (!dbus_connection_add_filter (ctx
->connection
, filter_func
, ctx
, NULL
)) {
3241 dbus_bus_add_match (ctx
->connection
,
3243 "interface='org.freedesktop.Hal.Manager',"
3244 "sender='org.freedesktop.Hal',"
3245 "path='/org/freedesktop/Hal/Manager'", &_error
);
3246 dbus_move_error (&_error
, error
);
3247 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3250 ctx
->is_initialized
= TRUE
;
3251 ctx
->is_direct
= FALSE
;
3257 * libhal_ctx_init_direct:
3258 * @error: pointer to an initialized dbus error object for returning errors or NULL
3260 * Create an already initialized connection to hald. This function should only be used by HAL helpers.
3262 * Returns: A pointer to an already initialized LibHalContext
3265 libhal_ctx_init_direct (DBusError
*error
)
3271 ctx
= libhal_ctx_new ();
3275 if (((hald_addr
= getenv ("HALD_DIRECT_ADDR"))) == NULL
) {
3276 libhal_ctx_free (ctx
);
3281 dbus_error_init (&_error
);
3282 ctx
->connection
= dbus_connection_open (hald_addr
, &_error
);
3283 dbus_move_error (&_error
, error
);
3284 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3285 libhal_ctx_free (ctx
);
3290 ctx
->is_initialized
= TRUE
;
3291 ctx
->is_direct
= TRUE
;
3298 * libhal_ctx_shutdown:
3299 * @ctx: the context for the connection to hald
3300 * @error: pointer to an initialized dbus error object for returning errors or NULL
3302 * Shut down a connection to hald.
3304 * Returns: TRUE if connection successfully shut down, FALSE otherwise
3307 libhal_ctx_shutdown (LibHalContext
*ctx
, DBusError
*error
)
3311 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3313 if (ctx
->is_direct
) {
3314 /* for some reason dbus_connection_set_exit_on_disconnect doesn't work yet so don't unref */
3315 /*dbus_connection_unref (ctx->connection);*/
3317 dbus_error_init (&myerror
);
3318 dbus_bus_remove_match (ctx
->connection
,
3320 "interface='org.freedesktop.Hal.Manager',"
3321 "sender='org.freedesktop.Hal',"
3322 "path='/org/freedesktop/Hal/Manager'", &myerror
);
3323 dbus_move_error (&myerror
, error
);
3324 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3325 fprintf (stderr
, "%s %d : Error unsubscribing to signals, error=%s\n",
3326 __FILE__
, __LINE__
, error
->message
);
3327 /** @todo clean up */
3330 /* TODO: remove other matches */
3332 dbus_connection_remove_filter (ctx
->connection
, filter_func
, ctx
);
3335 ctx
->is_initialized
= FALSE
;
3342 * @ctx: pointer to a LibHalContext
3344 * Free a LibHalContext resource.
3349 libhal_ctx_free (LibHalContext
*ctx
)
3356 * libhal_ctx_set_device_added:
3357 * @ctx: the context for the connection to hald
3358 * @callback: the function to call when a device is added
3360 * Set the callback for when a device is added
3362 * Returns: TRUE if callback was successfully set, FALSE otherwise
3365 libhal_ctx_set_device_added (LibHalContext
*ctx
, LibHalDeviceAdded callback
)
3367 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3369 ctx
->device_added
= callback
;
3374 * libhal_ctx_set_device_removed:
3375 * @ctx: the context for the connection to hald
3376 * @callback: the function to call when a device is removed
3378 * Set the callback for when a device is removed.
3380 * Returns: TRUE if callback was successfully set, FALSE otherwise
3383 libhal_ctx_set_device_removed (LibHalContext
*ctx
, LibHalDeviceRemoved callback
)
3385 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3387 ctx
->device_removed
= callback
;
3392 * libhal_ctx_set_device_new_capability:
3393 * @ctx: the context for the connection to hald
3394 * @callback: the function to call when a device gains a new capability
3396 * Set the callback for when a device gains a new capability.
3398 * Returns: TRUE if callback was successfully set, FALSE otherwise
3401 libhal_ctx_set_device_new_capability (LibHalContext
*ctx
, LibHalDeviceNewCapability callback
)
3403 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3405 ctx
->device_new_capability
= callback
;
3410 * libhal_ctx_set_device_lost_capability:
3411 * @ctx: the context for the connection to hald
3412 * @callback: the function to call when a device loses a capability
3414 * Set the callback for when a device loses a capability
3416 * Returns: TRUE if callback was successfully set, FALSE otherwise
3419 libhal_ctx_set_device_lost_capability (LibHalContext
*ctx
, LibHalDeviceLostCapability callback
)
3421 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3423 ctx
->device_lost_capability
= callback
;
3428 * libhal_ctx_set_device_property_modified:
3429 * @ctx: the context for the connection to hald
3430 * @callback: the function to call when a property is modified on a device
3432 * Set the callback for when a property is modified on a device.
3434 * Returns: TRUE if callback was successfully set, FALSE otherwise
3437 libhal_ctx_set_device_property_modified (LibHalContext
*ctx
, LibHalDevicePropertyModified callback
)
3439 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3441 ctx
->device_property_modified
= callback
;
3446 * libhal_ctx_set_device_condition:
3447 * @ctx: the context for the connection to hald
3448 * @callback: the function to call when a device emits a condition
3450 * Set the callback for when a device emits a condition
3452 * Returns: TRUE if callback was successfully set, FALSE otherwise
3455 libhal_ctx_set_device_condition (LibHalContext
*ctx
, LibHalDeviceCondition callback
)
3457 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3459 ctx
->device_condition
= callback
;
3464 * libhal_string_array_length:
3465 * @str_array: array of strings to consider
3467 * Get the length of an array of strings.
3469 * Returns: Number of strings in array
3472 libhal_string_array_length (char **str_array
)
3476 if (str_array
== NULL
)
3479 for (i
= 0; str_array
[i
] != NULL
; i
++)
3487 * libhal_device_rescan:
3488 * @ctx: the context for the connection to hald
3489 * @udi: the Unique id of device
3490 * @error: pointer to an initialized dbus error object for returning errors or NULL
3494 * Returns: Whether the operation succeeded
3497 libhal_device_rescan (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
3499 DBusMessage
*message
;
3500 DBusMessageIter reply_iter
;
3504 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3505 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3507 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
3508 "org.freedesktop.Hal.Device",
3511 if (message
== NULL
) {
3513 "%s %d : Couldn't allocate D-BUS message\n",
3514 __FILE__
, __LINE__
);
3518 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
3522 dbus_message_unref (message
);
3524 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3530 dbus_message_iter_init (reply
, &reply_iter
);
3531 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
3532 DBUS_TYPE_BOOLEAN
) {
3533 dbus_message_unref (reply
);
3536 dbus_message_iter_get_basic (&reply_iter
, &result
);
3538 dbus_message_unref (reply
);
3544 * libhal_device_reprobe:
3545 * @ctx: the context for the connection to hald
3546 * @udi: the Unique id of device
3547 * @error: pointer to an initialized dbus error object for returning errors or NULL
3551 * Returns: Whether the operation succeeded
3554 libhal_device_reprobe (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
3556 DBusMessage
*message
;
3557 DBusMessageIter reply_iter
;
3561 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3562 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3564 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
3566 "org.freedesktop.Hal.Device",
3569 if (message
== NULL
) {
3571 "%s %d : Couldn't allocate D-BUS message\n",
3572 __FILE__
, __LINE__
);
3576 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
3580 dbus_message_unref (message
);
3582 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3588 dbus_message_iter_init (reply
, &reply_iter
);
3589 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
3590 DBUS_TYPE_BOOLEAN
) {
3591 dbus_message_unref (reply
);
3594 dbus_message_iter_get_basic (&reply_iter
, &result
);
3596 dbus_message_unref (reply
);
3602 * libhal_device_emit_condition:
3603 * @ctx: the context for the connection to hald
3604 * @udi: the Unique Device Id
3605 * @condition_name: user-readable name of condition
3606 * @condition_details: user-readable details of condition
3607 * @error: pointer to an initialized dbus error object for returning errors or NULL
3609 * Emit a condition from a device. Can only be used from hald helpers.
3611 * Returns: TRUE if condition successfully emitted,
3614 dbus_bool_t
libhal_device_emit_condition (LibHalContext
*ctx
,
3616 const char *condition_name
,
3617 const char *condition_details
,
3620 DBusMessage
*message
;
3621 DBusMessageIter iter
;
3622 DBusMessageIter reply_iter
;
3626 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3627 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3628 LIBHAL_CHECK_PARAM_VALID(condition_name
, "*condition_name", FALSE
);
3629 LIBHAL_CHECK_PARAM_VALID(condition_details
, "*condition_details", FALSE
);
3631 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
3633 "org.freedesktop.Hal.Device",
3636 if (message
== NULL
) {
3638 "%s %d : Couldn't allocate D-BUS message\n",
3639 __FILE__
, __LINE__
);
3643 dbus_message_iter_init_append (message
, &iter
);
3644 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &condition_name
);
3645 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &condition_details
);
3647 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
3651 dbus_message_unref (message
);
3653 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3655 "%s %d : Failure sending D-BUS message: %s: %s\n",
3656 __FILE__
, __LINE__
, error
->name
, error
->message
);
3660 if (reply
== NULL
) {
3662 "%s %d : Got no reply\n",
3663 __FILE__
, __LINE__
);
3667 dbus_message_iter_init (reply
, &reply_iter
);
3668 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
3669 DBUS_TYPE_BOOLEAN
) {
3670 dbus_message_unref (reply
);
3672 "%s %d : Malformed reply\n",
3673 __FILE__
, __LINE__
);
3676 dbus_message_iter_get_basic (&reply_iter
, &result
);
3678 dbus_message_unref (reply
);
3684 * libhal_device_addon_is_ready:
3685 * @ctx: the context for the connection to hald
3686 * @udi: the Unique Device Id this addon is handling
3687 * @error: pointer to an initialized dbus error object for returning errors or NULL
3689 * HAL addon's must call this method when they are done initializing the device object. The HAL
3690 * daemon will wait for all addon's to call this.
3692 * Can only be used from hald helpers.
3694 * Returns: TRUE if the HAL daemon received the message, FALSE otherwise
3697 libhal_device_addon_is_ready (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
3699 DBusMessage
*message
;
3700 DBusMessageIter iter
;
3701 DBusMessageIter reply_iter
;
3705 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3706 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3708 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
3710 "org.freedesktop.Hal.Device",
3713 if (message
== NULL
) {
3715 "%s %d : Couldn't allocate D-BUS message\n",
3716 __FILE__
, __LINE__
);
3720 dbus_message_iter_init_append (message
, &iter
);
3722 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
3726 dbus_message_unref (message
);
3728 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3734 dbus_message_iter_init (reply
, &reply_iter
);
3735 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_BOOLEAN
) {
3736 dbus_message_unref (reply
);
3739 dbus_message_iter_get_basic (&reply_iter
, &result
);
3741 dbus_message_unref (reply
);
3746 * libhal_device_claim_interface:
3747 * @ctx: the context for the connection to hald
3748 * @udi: the Unique Device Id
3749 * @interface_name: Name of interface to claim, e.g. org.freedesktop.Hal.Device.FoobarKindOfThing
3750 * @introspection_xml: Introspection XML containing what would be inside the interface XML tag
3751 * @error: pointer to an initialized dbus error object for returning errors or NULL
3753 * Claim an interface for a device. All messages to this interface
3754 * will be forwarded to the helper. Can only be used from hald
3757 * Returns: TRUE if interface was claimed, FALSE otherwise
3760 libhal_device_claim_interface (LibHalContext
*ctx
,
3762 const char *interface_name
,
3763 const char *introspection_xml
,
3766 DBusMessage
*message
;
3767 DBusMessageIter iter
;
3768 DBusMessageIter reply_iter
;
3772 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3773 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3774 LIBHAL_CHECK_PARAM_VALID(interface_name
, "*interface_name", FALSE
);
3776 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
3778 "org.freedesktop.Hal.Device",
3781 if (message
== NULL
) {
3783 "%s %d : Couldn't allocate D-BUS message\n",
3784 __FILE__
, __LINE__
);
3788 dbus_message_iter_init_append (message
, &iter
);
3789 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &interface_name
);
3790 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &introspection_xml
);
3792 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
3796 dbus_message_unref (message
);
3798 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3804 dbus_message_iter_init (reply
, &reply_iter
);
3805 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
3806 DBUS_TYPE_BOOLEAN
) {
3807 dbus_message_unref (reply
);
3810 dbus_message_iter_get_basic (&reply_iter
, &result
);
3812 dbus_message_unref (reply
);
3819 struct LibHalChangeSetElement_s
;
3821 typedef struct LibHalChangeSetElement_s LibHalChangeSetElement
;
3823 struct LibHalChangeSetElement_s
{
3828 dbus_int32_t val_int
;
3829 dbus_uint64_t val_uint64
;
3831 dbus_bool_t val_bool
;
3834 LibHalChangeSetElement
*next
;
3835 LibHalChangeSetElement
*prev
;
3838 struct LibHalChangeSet_s
{
3840 LibHalChangeSetElement
*head
;
3841 LibHalChangeSetElement
*tail
;
3845 * libhal_device_new_changeset:
3846 * @udi: unique device identifier
3848 * Request a new changeset object. Used for changing multiple properties at once. Useful when
3849 * performance is critical and also for atomically updating several properties.
3851 * Returns: A new changeset object or NULL on error
3854 libhal_device_new_changeset (const char *udi
)
3856 LibHalChangeSet
*changeset
;
3858 LIBHAL_CHECK_UDI_VALID(udi
, NULL
);
3860 changeset
= calloc (1, sizeof (LibHalChangeSet
));
3861 if (changeset
== NULL
)
3864 changeset
->udi
= strdup (udi
);
3865 if (changeset
->udi
== NULL
) {
3871 changeset
->head
= NULL
;
3872 changeset
->tail
= NULL
;
3879 libhal_changeset_append (LibHalChangeSet
*changeset
, LibHalChangeSetElement
*elem
)
3881 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", );
3882 LIBHAL_CHECK_PARAM_VALID(elem
, "*elem", );
3884 if (changeset
->head
== NULL
) {
3885 changeset
->head
= elem
;
3886 changeset
->tail
= elem
;
3890 elem
->prev
= changeset
->tail
;
3892 elem
->prev
->next
= elem
;
3893 changeset
->tail
= elem
;
3899 * libhal_changeset_set_property_string:
3900 * @changeset: the changeset
3901 * @key: key of property
3902 * @value: the value to set
3906 * Returns: FALSE on OOM
3909 libhal_changeset_set_property_string (LibHalChangeSet
*changeset
, const char *key
, const char *value
)
3911 LibHalChangeSetElement
*elem
;
3913 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", FALSE
);
3914 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
3915 LIBHAL_CHECK_PARAM_VALID(value
, "*value", FALSE
);
3917 elem
= calloc (1, sizeof (LibHalChangeSetElement
));
3920 elem
->key
= strdup (key
);
3921 if (elem
->key
== NULL
) {
3927 elem
->change_type
= LIBHAL_PROPERTY_TYPE_STRING
;
3928 elem
->value
.val_str
= strdup (value
);
3929 if (elem
->value
.val_str
== NULL
) {
3936 libhal_changeset_append (changeset
, elem
);
3938 return elem
!= NULL
;
3942 * libhal_changeset_set_property_int:
3943 * @changeset: the changeset
3944 * @key: key of property
3945 * @value: the value to set
3949 * Returns: FALSE on OOM
3952 libhal_changeset_set_property_int (LibHalChangeSet
*changeset
, const char *key
, dbus_int32_t value
)
3954 LibHalChangeSetElement
*elem
;
3956 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", FALSE
);
3957 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
3959 elem
= calloc (1, sizeof (LibHalChangeSetElement
));
3962 elem
->key
= strdup (key
);
3963 if (elem
->key
== NULL
) {
3969 elem
->change_type
= LIBHAL_PROPERTY_TYPE_INT32
;
3970 elem
->value
.val_int
= value
;
3972 libhal_changeset_append (changeset
, elem
);
3974 return elem
!= NULL
;
3978 * libhal_changeset_set_property_uint64:
3979 * @changeset: the changeset
3980 * @key: key of property
3981 * @value: the value to set
3985 * Returns: FALSE on OOM
3988 libhal_changeset_set_property_uint64 (LibHalChangeSet
*changeset
, const char *key
, dbus_uint64_t value
)
3990 LibHalChangeSetElement
*elem
;
3992 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", FALSE
);
3993 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
3995 elem
= calloc (1, sizeof (LibHalChangeSetElement
));
3998 elem
->key
= strdup (key
);
3999 if (elem
->key
== NULL
) {
4005 elem
->change_type
= LIBHAL_PROPERTY_TYPE_UINT64
;
4006 elem
->value
.val_uint64
= value
;
4008 libhal_changeset_append (changeset
, elem
);
4010 return elem
!= NULL
;
4014 * libhal_changeset_set_property_double:
4015 * @changeset: the changeset
4016 * @key: key of property
4017 * @value: the value to set
4021 * Returns: FALSE on OOM
4024 libhal_changeset_set_property_double (LibHalChangeSet
*changeset
, const char *key
, double value
)
4026 LibHalChangeSetElement
*elem
;
4028 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", FALSE
);
4029 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
4031 elem
= calloc (1, sizeof (LibHalChangeSetElement
));
4034 elem
->key
= strdup (key
);
4035 if (elem
->key
== NULL
) {
4041 elem
->change_type
= LIBHAL_PROPERTY_TYPE_DOUBLE
;
4042 elem
->value
.val_double
= value
;
4044 libhal_changeset_append (changeset
, elem
);
4046 return elem
!= NULL
;
4050 * libhal_changeset_set_property_bool:
4051 * @changeset: the changeset
4052 * @key: key of property
4053 * @value: the value to set
4057 * Returns: FALSE on OOM
4060 libhal_changeset_set_property_bool (LibHalChangeSet
*changeset
, const char *key
, dbus_bool_t value
)
4062 LibHalChangeSetElement
*elem
;
4064 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", FALSE
);
4065 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
4067 elem
= calloc (1, sizeof (LibHalChangeSetElement
));
4070 elem
->key
= strdup (key
);
4071 if (elem
->key
== NULL
) {
4077 elem
->change_type
= LIBHAL_PROPERTY_TYPE_BOOLEAN
;
4078 elem
->value
.val_bool
= value
;
4080 libhal_changeset_append (changeset
, elem
);
4082 return elem
!= NULL
;
4086 * libhal_changeset_set_property_strlist:
4087 * @changeset: the changeset
4088 * @key: key of property
4089 * @value: the value to set - NULL terminated array of strings
4093 * Returns: FALSE on OOM
4096 libhal_changeset_set_property_strlist (LibHalChangeSet
*changeset
, const char *key
, const char **value
)
4098 LibHalChangeSetElement
*elem
;
4103 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", FALSE
);
4104 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
4106 elem
= calloc (1, sizeof (LibHalChangeSetElement
));
4109 elem
->key
= strdup (key
);
4110 if (elem
->key
== NULL
) {
4116 for (i
= 0; value
[i
] != NULL
; i
++)
4120 value_copy
= calloc (len
+ 1, sizeof (char *));
4121 if (value_copy
== NULL
) {
4128 for (i
= 0; i
< len
; i
++) {
4129 value_copy
[i
] = strdup (value
[i
]);
4130 if (value_copy
[i
] == NULL
) {
4131 for (j
= 0; j
< i
; j
++) {
4132 free (value_copy
[j
]);
4141 value_copy
[i
] = NULL
;
4143 elem
->change_type
= LIBHAL_PROPERTY_TYPE_STRLIST
;
4144 elem
->value
.val_strlist
= value_copy
;
4146 libhal_changeset_append (changeset
, elem
);
4148 return elem
!= NULL
;
4152 * libhal_device_commit_changeset:
4153 * @ctx: the context for the connection to hald
4154 * @changeset: the changeset to commit
4155 * @error: pointer to an initialized dbus error object for returning errors or NULL
4157 * Commit a changeset to the daemon.
4159 * Returns: True if the changeset was committed on the daemon side
4162 libhal_device_commit_changeset (LibHalContext
*ctx
, LibHalChangeSet
*changeset
, DBusError
*error
)
4164 LibHalChangeSetElement
*elem
;
4165 DBusMessage
*message
;
4168 DBusMessageIter iter
;
4169 DBusMessageIter sub
;
4170 DBusMessageIter sub2
;
4171 DBusMessageIter sub3
;
4172 DBusMessageIter sub4
;
4175 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
4176 LIBHAL_CHECK_UDI_VALID(changeset
->udi
, FALSE
);
4178 if (changeset
->head
== NULL
) {
4182 message
= dbus_message_new_method_call ("org.freedesktop.Hal", changeset
->udi
,
4183 "org.freedesktop.Hal.Device",
4184 "SetMultipleProperties");
4186 if (message
== NULL
) {
4187 fprintf (stderr
, "%s %d : Couldn't allocate D-BUS message\n", __FILE__
, __LINE__
);
4191 dbus_message_iter_init_append (message
, &iter
);
4193 dbus_message_iter_open_container (&iter
,
4195 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
4196 DBUS_TYPE_STRING_AS_STRING
4197 DBUS_TYPE_VARIANT_AS_STRING
4198 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
,
4201 for (elem
= changeset
->head
; elem
!= NULL
; elem
= elem
->next
) {
4202 dbus_message_iter_open_container (&sub
,
4203 DBUS_TYPE_DICT_ENTRY
,
4206 dbus_message_iter_append_basic (&sub2
, DBUS_TYPE_STRING
, &(elem
->key
));
4208 switch (elem
->change_type
) {
4209 case LIBHAL_PROPERTY_TYPE_STRING
:
4210 dbus_message_iter_open_container (&sub2
, DBUS_TYPE_VARIANT
, DBUS_TYPE_STRING_AS_STRING
, &sub3
);
4211 dbus_message_iter_append_basic (&sub3
, DBUS_TYPE_STRING
, &(elem
->value
.val_str
));
4212 dbus_message_iter_close_container (&sub2
, &sub3
);
4214 case LIBHAL_PROPERTY_TYPE_STRLIST
:
4215 dbus_message_iter_open_container (&sub2
, DBUS_TYPE_VARIANT
,
4216 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING
, &sub3
);
4217 dbus_message_iter_open_container (&sub3
, DBUS_TYPE_ARRAY
,
4218 DBUS_TYPE_STRING_AS_STRING
, &sub4
);
4219 for (i
= 0; elem
->value
.val_strlist
[i
] != NULL
; i
++) {
4220 dbus_message_iter_append_basic (&sub4
, DBUS_TYPE_STRING
,
4221 &(elem
->value
.val_strlist
[i
]));
4223 dbus_message_iter_close_container (&sub3
, &sub4
);
4224 dbus_message_iter_close_container (&sub2
, &sub3
);
4226 case LIBHAL_PROPERTY_TYPE_INT32
:
4227 dbus_message_iter_open_container (&sub2
, DBUS_TYPE_VARIANT
, DBUS_TYPE_INT32_AS_STRING
, &sub3
);
4228 dbus_message_iter_append_basic (&sub3
, DBUS_TYPE_INT32
, &(elem
->value
.val_int
));
4229 dbus_message_iter_close_container (&sub2
, &sub3
);
4231 case LIBHAL_PROPERTY_TYPE_UINT64
:
4232 dbus_message_iter_open_container (&sub2
, DBUS_TYPE_VARIANT
, DBUS_TYPE_UINT64_AS_STRING
, &sub3
);
4233 dbus_message_iter_append_basic (&sub3
, DBUS_TYPE_UINT64
, &(elem
->value
.val_uint64
));
4234 dbus_message_iter_close_container (&sub2
, &sub3
);
4236 case LIBHAL_PROPERTY_TYPE_DOUBLE
:
4237 dbus_message_iter_open_container (&sub2
, DBUS_TYPE_VARIANT
, DBUS_TYPE_DOUBLE_AS_STRING
, &sub3
);
4238 dbus_message_iter_append_basic (&sub3
, DBUS_TYPE_DOUBLE
, &(elem
->value
.val_double
));
4239 dbus_message_iter_close_container (&sub2
, &sub3
);
4241 case LIBHAL_PROPERTY_TYPE_BOOLEAN
:
4242 dbus_message_iter_open_container (&sub2
, DBUS_TYPE_VARIANT
, DBUS_TYPE_BOOLEAN_AS_STRING
,&sub3
);
4243 dbus_message_iter_append_basic (&sub3
, DBUS_TYPE_BOOLEAN
, &(elem
->value
.val_bool
));
4244 dbus_message_iter_close_container (&sub2
, &sub3
);
4247 fprintf (stderr
, "%s %d : unknown change_type %d\n", __FILE__
, __LINE__
, elem
->change_type
);
4250 dbus_message_iter_close_container (&sub
, &sub2
);
4253 dbus_message_iter_close_container (&iter
, &sub
);
4256 dbus_error_init (&_error
);
4257 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
4261 dbus_message_unref (message
);
4263 dbus_move_error (&_error
, error
);
4264 if (error
!= NULL
&& dbus_error_is_set (error
)) {
4267 __FILE__
, __LINE__
, error
->message
);
4271 if (reply
== NULL
) {
4275 dbus_message_unref (reply
);
4280 * libhal_device_free_changeset:
4281 * @changeset: the changeset to free
4286 libhal_device_free_changeset (LibHalChangeSet
*changeset
)
4288 LibHalChangeSetElement
*elem
;
4289 LibHalChangeSetElement
*elem2
;
4291 for (elem
= changeset
->head
; elem
!= NULL
; elem
= elem2
) {
4294 switch (elem
->change_type
) {
4295 case LIBHAL_PROPERTY_TYPE_STRING
:
4296 free (elem
->value
.val_str
);
4298 case LIBHAL_PROPERTY_TYPE_STRLIST
:
4299 libhal_free_string_array (elem
->value
.val_strlist
);
4301 /* explicit fallthrough */
4302 case LIBHAL_PROPERTY_TYPE_INT32
:
4303 case LIBHAL_PROPERTY_TYPE_UINT64
:
4304 case LIBHAL_PROPERTY_TYPE_DOUBLE
:
4305 case LIBHAL_PROPERTY_TYPE_BOOLEAN
:
4308 fprintf (stderr
, "%s %d : unknown change_type %d\n", __FILE__
, __LINE__
, elem
->change_type
);
4315 free (changeset
->udi
);