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
= reallocarray(buffer
, count
+ 8, sizeof (char *));
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
= reallocarray(buffer
, (count
+ 1), sizeof(char *));
182 buffer
[count
] = NULL
;
183 if (num_elements
!= NULL
)
184 *num_elements
= count
;
189 fprintf (stderr
, "%s %d : error allocating memory\n", __FILE__
, __LINE__
);
195 * libhal_free_string:
196 * @str: the nul-terminated sting to free
198 * Used to free strings returned by libhal.
201 libhal_free_string (char *str
)
213 * Represents a set of properties. Opaque; use the
214 * libhal_property_set_*() family of functions to access it.
216 struct LibHalPropertySet_s
{
217 unsigned int num_properties
; /**< Number of properties in set */
218 LibHalProperty
*properties_head
;
219 /**< Pointer to first property or NULL
220 * if there are no properties */
226 * Represents a property. Opaque.
228 struct LibHalProperty_s
{
229 LibHalPropertyType type
; /**< Type of property */
230 char *key
; /**< ASCII string */
232 /** Possible values of the property */
234 char *str_value
; /**< UTF-8 zero-terminated string */
235 dbus_int32_t int_value
;
236 /**< 32-bit signed integer */
237 dbus_uint64_t uint64_value
;
238 /**< 64-bit unsigned integer */
239 double double_value
; /**< IEEE754 double precision float */
240 dbus_bool_t bool_value
;
243 char **strlist_value
; /**< List of UTF-8 zero-terminated strings */
246 LibHalProperty
*next
; /**< Next property or NULL if this is
253 * Context for connection to the HAL daemon. Opaque, use the
254 * libhal_ctx_*() family of functions to access it.
256 struct LibHalContext_s
{
257 DBusConnection
*connection
; /**< D-BUS connection */
258 dbus_bool_t is_initialized
; /**< Are we initialised */
259 dbus_bool_t is_shutdown
; /**< Have we been shutdown */
260 dbus_bool_t cache_enabled
; /**< Is the cache enabled */
261 dbus_bool_t is_direct
; /**< Whether the connection to hald is direct */
264 LibHalDeviceAdded device_added
;
266 /** Device removed */
267 LibHalDeviceRemoved device_removed
;
269 /** Device got a new capability */
270 LibHalDeviceNewCapability device_new_capability
;
272 /** Device got a new capability */
273 LibHalDeviceLostCapability device_lost_capability
;
275 /** A property of a device changed */
276 LibHalDevicePropertyModified device_property_modified
;
278 /** A non-continous event on the device occured */
279 LibHalDeviceCondition device_condition
;
281 void *user_data
; /**< User data */
285 * libhal_ctx_set_user_data:
286 * @ctx: the context for the connection to hald
287 * @user_data: user data
289 * Set user data for the context.
291 * Returns: TRUE if user data was successfully set, FALSE if otherwise
294 libhal_ctx_set_user_data(LibHalContext
*ctx
, void *user_data
)
296 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
297 ctx
->user_data
= user_data
;
302 * libhal_ctx_get_user_data:
303 * @ctx: the context for the connection to hald
305 * Get user data for the context.
307 * Returns: opaque pointer stored through libhal_ctx_set_user_data() or NULL if not set.
310 libhal_ctx_get_user_data(LibHalContext
*ctx
)
312 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
313 return ctx
->user_data
;
318 * libhal_property_fill_value_from_variant:
319 * @p: the property to fill in
320 * @var_iter: variant iterator to extract the value from
322 * Fills in the value for the LibHalProperty given a variant iterator.
324 * Returns: Whether the value was put in.
327 libhal_property_fill_value_from_variant (LibHalProperty
*p
, DBusMessageIter
*var_iter
)
329 DBusMessageIter iter_array
;
331 LIBHAL_CHECK_PARAM_VALID(p
, "LibHalProperty *p", FALSE
);
332 LIBHAL_CHECK_PARAM_VALID(var_iter
, "DBusMessageIter *var_iter", FALSE
);
335 case DBUS_TYPE_ARRAY
:
336 if (dbus_message_iter_get_element_type (var_iter
) != DBUS_TYPE_STRING
)
339 dbus_message_iter_recurse (var_iter
, &iter_array
);
340 p
->v
.strlist_value
= libhal_get_string_array_from_iter (&iter_array
, NULL
);
342 p
->type
= LIBHAL_PROPERTY_TYPE_STRLIST
;
345 case DBUS_TYPE_STRING
:
349 dbus_message_iter_get_basic (var_iter
, &v
);
351 p
->v
.str_value
= strdup (v
);
352 if (p
->v
.str_value
== NULL
)
354 p
->type
= LIBHAL_PROPERTY_TYPE_STRING
;
358 case DBUS_TYPE_INT32
:
362 dbus_message_iter_get_basic (var_iter
, &v
);
365 p
->type
= LIBHAL_PROPERTY_TYPE_INT32
;
369 case DBUS_TYPE_UINT64
:
373 dbus_message_iter_get_basic (var_iter
, &v
);
375 p
->v
.uint64_value
= v
;
376 p
->type
= LIBHAL_PROPERTY_TYPE_UINT64
;
380 case DBUS_TYPE_DOUBLE
:
384 dbus_message_iter_get_basic (var_iter
, &v
);
386 p
->v
.double_value
= v
;
387 p
->type
= LIBHAL_PROPERTY_TYPE_DOUBLE
;
391 case DBUS_TYPE_BOOLEAN
:
395 dbus_message_iter_get_basic (var_iter
, &v
);
397 p
->v
.double_value
= v
;
398 p
->type
= LIBHAL_PROPERTY_TYPE_BOOLEAN
;
403 /** @todo report error */
411 * libhal_device_get_all_properties:
412 * @ctx: the context for the connection to hald
413 * @udi: the Unique id of device
414 * @error: pointer to an initialized dbus error object for returning errors or NULL
416 * Retrieve all the properties on a device.
418 * Returns: An object represent all properties. Must be freed with libhal_free_property_set().
421 libhal_device_get_all_properties (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
423 DBusMessage
*message
;
425 DBusMessageIter reply_iter
;
426 DBusMessageIter dict_iter
;
427 LibHalPropertySet
*result
;
428 LibHalProperty
*p_last
;
431 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
432 LIBHAL_CHECK_UDI_VALID(udi
, NULL
);
434 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
435 "org.freedesktop.Hal.Device",
438 if (message
== NULL
) {
440 "%s %d : Couldn't allocate D-BUS message\n",
445 dbus_error_init (&_error
);
446 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
450 dbus_move_error (&_error
, error
);
451 if (error
!= NULL
&& dbus_error_is_set (error
)) {
454 __FILE__
, __LINE__
, error
->message
);
456 dbus_message_unref (message
);
461 dbus_message_unref (message
);
465 dbus_message_iter_init (reply
, &reply_iter
);
467 result
= malloc (sizeof (LibHalPropertySet
));
472 result->properties = malloc(sizeof(LibHalProperty)*result->num_properties);
473 if( result->properties==NULL )
480 result
->properties_head
= NULL
;
481 result
->num_properties
= 0;
483 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_ARRAY
&&
484 dbus_message_iter_get_element_type (&reply_iter
) != DBUS_TYPE_DICT_ENTRY
) {
485 fprintf (stderr
, "%s %d : error, expecting an array of dict entries\n",
487 dbus_message_unref (message
);
488 dbus_message_unref (reply
);
492 dbus_message_iter_recurse (&reply_iter
, &dict_iter
);
496 while (dbus_message_iter_get_arg_type (&dict_iter
) == DBUS_TYPE_DICT_ENTRY
)
498 DBusMessageIter dict_entry_iter
, var_iter
;
502 dbus_message_iter_recurse (&dict_iter
, &dict_entry_iter
);
504 dbus_message_iter_get_basic (&dict_entry_iter
, &key
);
506 p
= malloc (sizeof (LibHalProperty
));
512 if (result
->num_properties
== 0)
513 result
->properties_head
= p
;
520 p
->key
= strdup (key
);
524 dbus_message_iter_next (&dict_entry_iter
);
526 dbus_message_iter_recurse (&dict_entry_iter
, &var_iter
);
529 p
->type
= dbus_message_iter_get_arg_type (&var_iter
);
531 result
->num_properties
++;
533 if(!libhal_property_fill_value_from_variant (p
, &var_iter
))
536 dbus_message_iter_next (&dict_iter
);
539 dbus_message_unref (message
);
540 dbus_message_unref (reply
);
546 "%s %d : error allocating memory\n",
548 /** @todo FIXME cleanup */
553 * libhal_free_property_set:
554 * @set: property-set to free
556 * Free a property set earlier obtained with libhal_device_get_all_properties().
559 libhal_free_property_set (LibHalPropertySet
* set
)
567 for (p
= set
->properties_head
; p
!= NULL
; p
= q
) {
569 if (p
->type
== DBUS_TYPE_STRING
)
570 free (p
->v
.str_value
);
571 if (p
->type
== LIBHAL_PROPERTY_TYPE_STRLIST
)
572 libhal_free_string_array (p
->v
.strlist_value
);
580 * libhal_property_set_get_num_elems:
581 * @set: property set to consider
583 * Get the number of properties in a property set.
585 * Returns: number of properties in given property set
588 libhal_property_set_get_num_elems (LibHalPropertySet
*set
)
590 unsigned int num_elems
;
593 LIBHAL_CHECK_PARAM_VALID(set
, "*set", 0);
596 for (p
= set
->properties_head
; p
!= NULL
; p
= p
->next
)
602 static LibHalProperty
*
603 property_set_lookup (const LibHalPropertySet
*set
, const char *key
)
607 LIBHAL_CHECK_PARAM_VALID(set
, "*set", NULL
);
608 LIBHAL_CHECK_PARAM_VALID(key
, "*key", NULL
);
610 for (p
= set
->properties_head
; p
!= NULL
; p
= p
->next
)
611 if (strcmp (key
, p
->key
) == 0)
618 * libhal_ps_get_type:
620 * @key: name of property to inspect
622 * Get the type of a given property.
624 * Returns: the #LibHalPropertyType of the given property,
625 * LIBHAL_PROPERTY_TYPE_INVALID if property is not in the set
628 libhal_ps_get_type (const LibHalPropertySet
*set
, const char *key
)
632 LIBHAL_CHECK_PARAM_VALID(set
, "*set", LIBHAL_PROPERTY_TYPE_INVALID
);
633 LIBHAL_CHECK_PARAM_VALID(key
, "*key", LIBHAL_PROPERTY_TYPE_INVALID
);
635 p
= property_set_lookup (set
, key
);
636 if (p
) return p
->type
;
637 else return LIBHAL_PROPERTY_TYPE_INVALID
;
641 * libhal_ps_get_string:
643 * @key: name of property to inspect
645 * Get the value of a property of type string.
647 * Returns: UTF8 nul-terminated string. This pointer is only valid
648 * until libhal_free_property_set() is invoked on the property set
649 * this property belongs to. NULL if property is not in the set or not a string
652 libhal_ps_get_string (const LibHalPropertySet
*set
, const char *key
)
656 LIBHAL_CHECK_PARAM_VALID(set
, "*set", NULL
);
657 LIBHAL_CHECK_PARAM_VALID(key
, "*key", NULL
);
659 p
= property_set_lookup (set
, key
);
660 if (p
&& p
->type
== LIBHAL_PROPERTY_TYPE_STRING
)
661 return p
->v
.str_value
;
668 * @key: name of property to inspect
670 * Get the value of a property of type signed integer.
672 * Returns: property value (32-bit signed integer)
675 libhal_ps_get_int32 (const LibHalPropertySet
*set
, const char *key
)
679 LIBHAL_CHECK_PARAM_VALID(set
, "*set", 0);
680 LIBHAL_CHECK_PARAM_VALID(key
, "*key", 0);
682 p
= property_set_lookup (set
, key
);
683 if (p
&& p
->type
== LIBHAL_PROPERTY_TYPE_INT32
)
684 return p
->v
.int_value
;
689 * libhal_ps_get_uint64:
691 * @key: name of property to inspect
693 * Get the value of a property of type unsigned integer.
695 * Returns: property value (64-bit unsigned integer)
698 libhal_ps_get_uint64 (const LibHalPropertySet
*set
, const char *key
)
702 LIBHAL_CHECK_PARAM_VALID(set
, "*set", 0);
703 LIBHAL_CHECK_PARAM_VALID(key
, "*key", 0);
705 p
= property_set_lookup (set
, key
);
706 if (p
&& p
->type
== LIBHAL_PROPERTY_TYPE_UINT64
)
707 return p
->v
.uint64_value
;
712 * libhal_ps_get_double:
714 * @key: name of property to inspect
716 * Get the value of a property of type double.
718 * Returns: property value (IEEE754 double precision float)
721 libhal_ps_get_double (const LibHalPropertySet
*set
, const char *key
)
725 LIBHAL_CHECK_PARAM_VALID(set
, "*set", 0.0);
726 LIBHAL_CHECK_PARAM_VALID(key
, "*key", 0.0);
728 p
= property_set_lookup (set
, key
);
729 if (p
&& p
->type
== LIBHAL_PROPERTY_TYPE_DOUBLE
)
730 return p
->v
.double_value
;
735 * libhal_ps_get_bool:
737 * @key: name of property to inspect
739 * Get the value of a property of type bool.
741 * Returns: property value (bool)
744 libhal_ps_get_bool (const LibHalPropertySet
*set
, const char *key
)
748 LIBHAL_CHECK_PARAM_VALID(set
, "*set", FALSE
);
749 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
751 p
= property_set_lookup (set
, key
);
752 if (p
&& p
->type
== LIBHAL_PROPERTY_TYPE_BOOLEAN
)
753 return p
->v
.bool_value
;
758 * libhal_ps_get_strlist:
760 * @key: name of property to inspect
762 * Get the value of a property of type string list.
764 * Returns: pointer to array of strings, this is owned by the property set
767 libhal_ps_get_strlist (const LibHalPropertySet
*set
, const char *key
)
771 LIBHAL_CHECK_PARAM_VALID(set
, "*set", NULL
);
772 LIBHAL_CHECK_PARAM_VALID(key
, "*key", NULL
);
774 p
= property_set_lookup (set
, key
);
775 if (p
&& p
->type
== LIBHAL_PROPERTY_TYPE_STRLIST
)
776 return (const char *const *) p
->v
.strlist_value
;
783 * @iter: iterator object
784 * @set: property set to iterate over
786 * Initialize a property set iterator.
790 libhal_psi_init (LibHalPropertySetIterator
* iter
, LibHalPropertySet
* set
)
797 iter
->cur_prop
= set
->properties_head
;
802 * libhal_psi_has_more:
803 * @iter: iterator object
805 * Determine whether there are more properties to iterate over.
807 * Returns: TRUE if there are more properties, FALSE otherwise.
810 libhal_psi_has_more (LibHalPropertySetIterator
* iter
)
812 return iter
->idx
< iter
->set
->num_properties
;
817 * @iter: iterator object
819 * Advance iterator to next property.
822 libhal_psi_next (LibHalPropertySetIterator
* iter
)
825 iter
->cur_prop
= iter
->cur_prop
->next
;
829 * libhal_psi_get_type:
830 * @iter: iterator object
832 * Get type of property.
834 * Returns: the property type at the iterator's position
837 libhal_psi_get_type (LibHalPropertySetIterator
* iter
)
839 return iter
->cur_prop
->type
;
843 * libhal_psi_get_key:
844 * @iter: iterator object
846 * Get the key of a property.
848 * Returns: ASCII nul-terminated string. This pointer is only valid
849 * until libhal_free_property_set() is invoked on the property set
850 * this property belongs to.
853 libhal_psi_get_key (LibHalPropertySetIterator
* iter
)
855 return iter
->cur_prop
->key
;
859 * libhal_psi_get_string:
860 * @iter: iterator object
862 * Get the value of a property of type string.
864 * Returns: UTF8 nul-terminated string. This pointer is only valid
865 * until libhal_free_property_set() is invoked on the property set
866 * this property belongs to.
869 libhal_psi_get_string (LibHalPropertySetIterator
* iter
)
871 return iter
->cur_prop
->v
.str_value
;
875 * libhal_psi_get_int:
876 * @iter: iterator object
878 * Get the value of a property of type signed integer.
880 * Returns: property value (32-bit signed integer)
883 libhal_psi_get_int (LibHalPropertySetIterator
* iter
)
885 return iter
->cur_prop
->v
.int_value
;
889 * libhal_psi_get_uint64:
890 * @iter: iterator object
892 * Get the value of a property of type unsigned integer.
894 * Returns: property value (64-bit unsigned integer)
897 libhal_psi_get_uint64 (LibHalPropertySetIterator
* iter
)
899 return iter
->cur_prop
->v
.uint64_value
;
903 * libhal_psi_get_double:
904 * @iter: iterator object
906 * Get the value of a property of type double.
908 * Returns: property value (IEEE754 double precision float)
911 libhal_psi_get_double (LibHalPropertySetIterator
* iter
)
913 return iter
->cur_prop
->v
.double_value
;
917 * libhal_psi_get_bool:
918 * @iter: iterator object
920 * Get the value of a property of type bool.
922 * Returns: property value (bool)
925 libhal_psi_get_bool (LibHalPropertySetIterator
* iter
)
927 return iter
->cur_prop
->v
.bool_value
;
931 * libhal_psi_get_strlist:
932 * @iter: iterator object
934 * Get the value of a property of type string list.
936 * Returns: pointer to array of strings
939 libhal_psi_get_strlist (LibHalPropertySetIterator
* iter
)
941 return iter
->cur_prop
->v
.strlist_value
;
945 static DBusHandlerResult
946 filter_func (DBusConnection
* connection
,
947 DBusMessage
* message
, void *user_data
)
949 const char *object_path
;
951 LibHalContext
*ctx
= (LibHalContext
*) user_data
;
953 if (ctx
->is_shutdown
)
954 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
956 dbus_error_init (&error
);
958 object_path
= dbus_message_get_path (message
);
960 /*fprintf (stderr, "*** libhal filer_func: connection=%p obj_path=%s interface=%s method=%s\n",
962 dbus_message_get_path (message),
963 dbus_message_get_interface (message),
964 dbus_message_get_member (message));
967 if (dbus_message_is_signal (message
, "org.freedesktop.Hal.Manager",
970 if (dbus_message_get_args (message
, &error
,
971 DBUS_TYPE_STRING
, &udi
,
972 DBUS_TYPE_INVALID
)) {
973 if (ctx
->device_added
!= NULL
) {
974 ctx
->device_added (ctx
, udi
);
977 LIBHAL_FREE_DBUS_ERROR(&error
);
979 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
980 } else if (dbus_message_is_signal (message
, "org.freedesktop.Hal.Manager", "DeviceRemoved")) {
982 if (dbus_message_get_args (message
, &error
,
983 DBUS_TYPE_STRING
, &udi
,
984 DBUS_TYPE_INVALID
)) {
985 if (ctx
->device_removed
!= NULL
) {
986 ctx
->device_removed (ctx
, udi
);
989 LIBHAL_FREE_DBUS_ERROR(&error
);
991 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
992 } else if (dbus_message_is_signal (message
, "org.freedesktop.Hal.Manager","NewCapability")) {
995 if (dbus_message_get_args (message
, &error
,
996 DBUS_TYPE_STRING
, &udi
,
997 DBUS_TYPE_STRING
, &capability
,
998 DBUS_TYPE_INVALID
)) {
999 if (ctx
->device_new_capability
!= NULL
) {
1000 ctx
->device_new_capability (ctx
, udi
, capability
);
1003 LIBHAL_FREE_DBUS_ERROR(&error
);
1005 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
1006 } else if (dbus_message_is_signal (message
, "org.freedesktop.Hal.Device", "Condition")) {
1007 char *condition_name
;
1008 char *condition_detail
;
1009 if (dbus_message_get_args (message
, &error
,
1010 DBUS_TYPE_STRING
, &condition_name
,
1011 DBUS_TYPE_STRING
, &condition_detail
,
1012 DBUS_TYPE_INVALID
)) {
1013 if (ctx
->device_condition
!= NULL
) {
1014 ctx
->device_condition (ctx
, object_path
, condition_name
, condition_detail
);
1017 LIBHAL_FREE_DBUS_ERROR(&error
);
1019 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
1020 } else if (dbus_message_is_signal (message
, "org.freedesktop.Hal.Device", "PropertyModified")) {
1021 if (ctx
->device_property_modified
!= NULL
) {
1024 dbus_bool_t removed
;
1026 int num_modifications
;
1027 DBusMessageIter iter
;
1028 DBusMessageIter iter_array
;
1030 dbus_message_iter_init (message
, &iter
);
1031 dbus_message_iter_get_basic (&iter
, &num_modifications
);
1032 dbus_message_iter_next (&iter
);
1034 dbus_message_iter_recurse (&iter
, &iter_array
);
1036 for (i
= 0; i
< num_modifications
; i
++) {
1037 DBusMessageIter iter_struct
;
1039 dbus_message_iter_recurse (&iter_array
, &iter_struct
);
1041 dbus_message_iter_get_basic (&iter_struct
, &key
);
1042 dbus_message_iter_next (&iter_struct
);
1043 dbus_message_iter_get_basic (&iter_struct
, &removed
);
1044 dbus_message_iter_next (&iter_struct
);
1045 dbus_message_iter_get_basic (&iter_struct
, &added
);
1047 ctx
->device_property_modified (ctx
,
1052 dbus_message_iter_next (&iter_array
);
1056 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
1059 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED
;
1062 /* for i18n purposes */
1063 static dbus_bool_t libhal_already_initialized_once
= FALSE
;
1067 * libhal_get_all_devices:
1068 * @ctx: the context for the connection to hald
1069 * @num_devices: the number of devices will be stored here
1070 * @error: pointer to an initialized dbus error object for returning errors or NULL
1072 * Get all devices in the Global Device List (GDL).
1074 * Returns: An array of device identifiers terminated with NULL. It is
1075 * the responsibility of the caller to free with
1076 * libhal_free_string_array(). If an error occurs NULL is returned.
1079 libhal_get_all_devices (LibHalContext
*ctx
, int *num_devices
, DBusError
*error
)
1081 DBusMessage
*message
;
1083 DBusMessageIter iter_array
, reply_iter
;
1084 char **hal_device_names
;
1087 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
1091 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
1092 "/org/freedesktop/Hal/Manager",
1093 "org.freedesktop.Hal.Manager",
1095 if (message
== NULL
) {
1096 fprintf (stderr
, "%s %d : Could not allocate D-BUS message\n", __FILE__
, __LINE__
);
1100 dbus_error_init (&_error
);
1101 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
, message
, -1, &_error
);
1103 dbus_message_unref (message
);
1105 dbus_move_error (&_error
, error
);
1106 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1109 if (reply
== NULL
) {
1113 /* now analyze reply */
1114 dbus_message_iter_init (reply
, &reply_iter
);
1116 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_ARRAY
) {
1117 fprintf (stderr
, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__
, __LINE__
);
1118 dbus_message_unref (reply
);
1122 dbus_message_iter_recurse (&reply_iter
, &iter_array
);
1124 hal_device_names
= libhal_get_string_array_from_iter (&iter_array
, num_devices
);
1126 dbus_message_unref (reply
);
1127 return hal_device_names
;
1131 * libhal_device_get_property_type:
1132 * @ctx: the context for the connection to hald
1133 * @udi: the Unique Device Id
1134 * @key: name of the property
1135 * @error: pointer to an initialized dbus error object for returning errors or NULL
1137 * Query a property type of a device.
1139 * Returns: A LibHalPropertyType. LIBHAL_PROPERTY_TYPE_INVALID is
1140 * return if the property doesn't exist.
1143 libhal_device_get_property_type (LibHalContext
*ctx
, const char *udi
, const char *key
, DBusError
*error
)
1145 DBusMessage
*message
;
1147 DBusMessageIter iter
, reply_iter
;
1148 LibHalPropertyType type
;
1151 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, LIBHAL_PROPERTY_TYPE_INVALID
); /* or return NULL? */
1152 LIBHAL_CHECK_UDI_VALID(udi
, LIBHAL_PROPERTY_TYPE_INVALID
);
1153 LIBHAL_CHECK_PARAM_VALID(key
, "*key", LIBHAL_PROPERTY_TYPE_INVALID
);
1155 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1156 "org.freedesktop.Hal.Device",
1158 if (message
== NULL
) {
1159 fprintf (stderr
, "%s %d : Couldn't allocate D-BUS message\n", __FILE__
, __LINE__
);
1160 return LIBHAL_PROPERTY_TYPE_INVALID
;
1163 dbus_message_iter_init_append (message
, &iter
);
1164 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1166 dbus_error_init (&_error
);
1167 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1171 dbus_message_unref (message
);
1173 dbus_move_error (&_error
, error
);
1174 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1175 return LIBHAL_PROPERTY_TYPE_INVALID
;
1177 if (reply
== NULL
) {
1178 return LIBHAL_PROPERTY_TYPE_INVALID
;
1181 dbus_message_iter_init (reply
, &reply_iter
);
1182 dbus_message_iter_get_basic (&reply_iter
, &type
);
1184 dbus_message_unref (reply
);
1189 * libhal_device_get_property_strlist:
1190 * @ctx: the context for the connection to hald
1191 * @udi: unique Device Id
1192 * @key: name of the property
1193 * @error: pointer to an initialized dbus error object for returning errors or NULL
1195 * Get the value of a property of type string list.
1197 * Returns: Array of pointers to UTF8 nul-terminated strings
1198 * terminated by NULL. The caller is responsible for freeing this
1199 * string array with the function libhal_free_string_array(). Returns
1200 * NULL if the property didn't exist or we are OOM
1203 libhal_device_get_property_strlist (LibHalContext
*ctx
, const char *udi
, const char *key
, DBusError
*error
)
1205 DBusMessage
*message
;
1207 DBusMessageIter iter
, iter_array
, reply_iter
;
1211 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
1212 LIBHAL_CHECK_UDI_VALID(udi
, NULL
);
1213 LIBHAL_CHECK_PARAM_VALID(key
, "*key", NULL
);
1215 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1216 "org.freedesktop.Hal.Device",
1217 "GetPropertyStringList");
1218 if (message
== NULL
) {
1220 "%s %d : Couldn't allocate D-BUS message\n",
1221 __FILE__
, __LINE__
);
1225 dbus_message_iter_init_append (message
, &iter
);
1226 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1228 dbus_error_init (&_error
);
1229 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1233 dbus_message_unref (message
);
1235 dbus_move_error (&_error
, error
);
1236 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1239 if (reply
== NULL
) {
1242 /* now analyse reply */
1243 dbus_message_iter_init (reply
, &reply_iter
);
1245 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_ARRAY
) {
1246 fprintf (stderr
, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__
, __LINE__
);
1247 dbus_message_unref (reply
);
1251 dbus_message_iter_recurse (&reply_iter
, &iter_array
);
1253 our_strings
= libhal_get_string_array_from_iter (&iter_array
, NULL
);
1255 dbus_message_unref (reply
);
1260 * libhal_device_get_property_string:
1261 * @ctx: the context for the connection to hald
1262 * @udi: the Unique Device Id
1263 * @key: the name of the property
1264 * @error: pointer to an initialized dbus error object for returning errors or NULL
1266 * Get the value of a property of type string.
1268 * Returns: UTF8 nul-terminated string. The caller is responsible for
1269 * freeing this string with the function libhal_free_string(). Returns
1270 * NULL if the property didn't exist or we are OOM.
1273 libhal_device_get_property_string (LibHalContext
*ctx
,
1274 const char *udi
, const char *key
, DBusError
*error
)
1276 DBusMessage
*message
;
1278 DBusMessageIter iter
, reply_iter
;
1283 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
1284 LIBHAL_CHECK_UDI_VALID(udi
, NULL
);
1285 LIBHAL_CHECK_PARAM_VALID(key
, "*key", NULL
);
1287 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1288 "org.freedesktop.Hal.Device",
1289 "GetPropertyString");
1291 if (message
== NULL
) {
1293 "%s %d : Couldn't allocate D-BUS message\n",
1294 __FILE__
, __LINE__
);
1298 dbus_message_iter_init_append (message
, &iter
);
1299 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1301 dbus_error_init (&_error
);
1302 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1306 dbus_message_unref (message
);
1308 dbus_move_error (&_error
, error
);
1309 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1312 if (reply
== NULL
) {
1316 dbus_message_iter_init (reply
, &reply_iter
);
1318 /* now analyze reply */
1319 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
1321 dbus_message_unref (reply
);
1325 dbus_message_iter_get_basic (&reply_iter
, &dbus_str
);
1326 value
= (char *) ((dbus_str
!= NULL
) ? strdup (dbus_str
) : NULL
);
1327 if (value
== NULL
) {
1328 fprintf (stderr
, "%s %d : error allocating memory\n",
1329 __FILE__
, __LINE__
);
1332 dbus_message_unref (reply
);
1337 * libhal_device_get_property_int:
1338 * @ctx: the context for the connection to hald
1339 * @udi: the Unique Device Id
1340 * @key: name of the property
1341 * @error: pointer to an initialized dbus error object for returning errors or NULL
1343 * Get the value of a property of type integer.
1345 * Returns: Property value (32-bit signed integer)
1348 libhal_device_get_property_int (LibHalContext
*ctx
,
1349 const char *udi
, const char *key
, DBusError
*error
)
1351 DBusMessage
*message
;
1353 DBusMessageIter iter
, reply_iter
;
1357 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, -1);
1358 LIBHAL_CHECK_UDI_VALID(udi
, -1);
1359 LIBHAL_CHECK_PARAM_VALID(key
, "*key", -1);
1361 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1362 "org.freedesktop.Hal.Device",
1363 "GetPropertyInteger");
1364 if (message
== NULL
) {
1366 "%s %d : Couldn't allocate D-BUS message\n",
1367 __FILE__
, __LINE__
);
1371 dbus_message_iter_init_append (message
, &iter
);
1372 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1374 dbus_error_init (&_error
);
1375 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1379 dbus_message_unref (message
);
1381 dbus_move_error (&_error
, error
);
1382 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1385 if (reply
== NULL
) {
1389 dbus_message_iter_init (reply
, &reply_iter
);
1391 /* now analyze reply */
1392 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
1395 "%s %d : property '%s' for device '%s' is not "
1396 "of type integer\n", __FILE__
, __LINE__
, key
,
1398 dbus_message_unref (reply
);
1401 dbus_message_iter_get_basic (&reply_iter
, &value
);
1403 dbus_message_unref (reply
);
1408 * libhal_device_get_property_uint64:
1409 * @ctx: the context for the connection to hald
1410 * @udi: the Unique Device Id
1411 * @key: name of the property
1412 * @error: pointer to an initialized dbus error object for returning errors or NULL
1414 * Get the value of a property of type signed integer.
1416 * Returns: Property value (64-bit unsigned integer)
1419 libhal_device_get_property_uint64 (LibHalContext
*ctx
,
1420 const char *udi
, const char *key
, DBusError
*error
)
1422 DBusMessage
*message
;
1424 DBusMessageIter iter
, reply_iter
;
1425 dbus_uint64_t value
;
1428 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, -1);
1429 LIBHAL_CHECK_UDI_VALID(udi
, -1);
1430 LIBHAL_CHECK_PARAM_VALID(key
, "*key", -1);
1432 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1433 "org.freedesktop.Hal.Device",
1434 "GetPropertyInteger");
1435 if (message
== NULL
) {
1437 "%s %d : Couldn't allocate D-BUS message\n",
1438 __FILE__
, __LINE__
);
1442 dbus_message_iter_init_append (message
, &iter
);
1443 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1445 dbus_error_init (&_error
);
1446 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1450 dbus_message_unref (message
);
1452 dbus_move_error (&_error
, error
);
1453 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1456 if (reply
== NULL
) {
1460 dbus_message_iter_init (reply
, &reply_iter
);
1461 /* now analyze reply */
1462 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
1465 "%s %d : property '%s' for device '%s' is not "
1466 "of type integer\n", __FILE__
, __LINE__
, key
,
1468 dbus_message_unref (reply
);
1471 dbus_message_iter_get_basic (&reply_iter
, &value
);
1473 dbus_message_unref (reply
);
1478 * libhal_device_get_property_double:
1479 * @ctx: the context for the connection to hald
1480 * @udi: the Unique Device Id
1481 * @key: name of the property
1482 * @error: pointer to an initialized dbus error object for returning errors or NULL
1484 * Get the value of a property of type double.
1486 * Returns: Property value (IEEE754 double precision float)
1489 libhal_device_get_property_double (LibHalContext
*ctx
,
1490 const char *udi
, const char *key
, DBusError
*error
)
1492 DBusMessage
*message
;
1494 DBusMessageIter iter
, reply_iter
;
1498 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, -1.0);
1499 LIBHAL_CHECK_UDI_VALID(udi
, -1.0);
1500 LIBHAL_CHECK_PARAM_VALID(key
, "*key", -1.0);
1502 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1503 "org.freedesktop.Hal.Device",
1504 "GetPropertyDouble");
1505 if (message
== NULL
) {
1507 "%s %d : Couldn't allocate D-BUS message\n",
1508 __FILE__
, __LINE__
);
1512 dbus_message_iter_init_append (message
, &iter
);
1513 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1515 dbus_error_init (&_error
);
1516 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1520 dbus_message_unref (message
);
1522 dbus_move_error (&_error
, error
);
1523 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1526 if (reply
== NULL
) {
1530 dbus_message_iter_init (reply
, &reply_iter
);
1532 /* now analyze reply */
1533 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
1536 "%s %d : property '%s' for device '%s' is not "
1537 "of type double\n", __FILE__
, __LINE__
, key
, udi
);
1538 dbus_message_unref (reply
);
1541 dbus_message_iter_get_basic (&reply_iter
, &value
);
1543 dbus_message_unref (reply
);
1544 return (double) value
;
1548 * libhal_device_get_property_bool:
1549 * @ctx: the context for the connection to hald
1550 * @udi: the Unique Device Id
1551 * @key: name of the property
1552 * @error: pointer to an initialized dbus error object for returning errors or NULL
1554 * Get the value of a property of type bool.
1556 * Returns: Property value (boolean)
1559 libhal_device_get_property_bool (LibHalContext
*ctx
,
1560 const char *udi
, const char *key
, DBusError
*error
)
1562 DBusMessage
*message
;
1564 DBusMessageIter iter
, reply_iter
;
1568 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1569 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1570 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1572 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1573 "org.freedesktop.Hal.Device",
1574 "GetPropertyBoolean");
1575 if (message
== NULL
) {
1577 "%s %d : Couldn't allocate D-BUS message\n",
1578 __FILE__
, __LINE__
);
1582 dbus_message_iter_init_append (message
, &iter
);
1583 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1585 dbus_error_init (&_error
);
1586 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1590 dbus_message_unref (message
);
1592 dbus_move_error (&_error
, error
);
1593 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1596 if (reply
== NULL
) {
1600 dbus_message_iter_init (reply
, &reply_iter
);
1602 /* now analyze reply */
1603 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
1604 DBUS_TYPE_BOOLEAN
) {
1606 "%s %d : property '%s' for device '%s' is not "
1607 "of type bool\n", __FILE__
, __LINE__
, key
, udi
);
1608 dbus_message_unref (reply
);
1611 dbus_message_iter_get_basic (&reply_iter
, &value
);
1613 dbus_message_unref (reply
);
1618 /* generic helper */
1620 libhal_device_set_property_helper (LibHalContext
*ctx
,
1624 const char *str_value
,
1625 dbus_int32_t int_value
,
1626 dbus_uint64_t uint64_value
,
1627 double double_value
,
1628 dbus_bool_t bool_value
,
1631 DBusMessage
*message
;
1633 DBusMessageIter iter
;
1634 char *method_name
= NULL
;
1636 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1637 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1638 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1640 /** @todo sanity check incoming params */
1642 case DBUS_TYPE_INVALID
:
1643 method_name
= "RemoveProperty";
1645 case DBUS_TYPE_STRING
:
1646 method_name
= "SetPropertyString";
1648 case DBUS_TYPE_INT32
:
1649 case DBUS_TYPE_UINT64
:
1650 method_name
= "SetPropertyInteger";
1652 case DBUS_TYPE_DOUBLE
:
1653 method_name
= "SetPropertyDouble";
1655 case DBUS_TYPE_BOOLEAN
:
1656 method_name
= "SetPropertyBoolean";
1660 /* cannot happen; is not callable from outside this file */
1664 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1665 "org.freedesktop.Hal.Device",
1667 if (message
== NULL
) {
1669 "%s %d : Couldn't allocate D-BUS message\n",
1670 __FILE__
, __LINE__
);
1674 dbus_message_iter_init_append (message
, &iter
);
1675 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1677 case DBUS_TYPE_STRING
:
1678 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &str_value
);
1680 case DBUS_TYPE_INT32
:
1681 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_INT32
, &int_value
);
1683 case DBUS_TYPE_UINT64
:
1684 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_UINT64
, &uint64_value
);
1686 case DBUS_TYPE_DOUBLE
:
1687 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_DOUBLE
, &double_value
);
1689 case DBUS_TYPE_BOOLEAN
:
1690 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_BOOLEAN
, &bool_value
);
1695 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1699 dbus_message_unref (message
);
1701 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1704 if (reply
== NULL
) {
1708 dbus_message_unref (reply
);
1714 * libhal_device_set_property_string:
1715 * @ctx: the context for the connection to hald
1716 * @udi: the Unique Device Id
1717 * @key: name of the property
1718 * @value: value of the property; a UTF8 string
1719 * @error: pointer to an initialized dbus error object for returning errors or NULL
1721 * Set a property of type string.
1723 * Returns: TRUE if the property was set, FALSE if the device didn't
1724 * exist or the property had a different type.
1727 libhal_device_set_property_string (LibHalContext
*ctx
,
1733 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1734 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1735 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1736 LIBHAL_CHECK_PARAM_VALID(value
, "*value", FALSE
);
1738 return libhal_device_set_property_helper (ctx
, udi
, key
,
1740 value
, 0, 0, 0.0f
, FALSE
, error
);
1744 * libhal_device_set_property_int:
1745 * @ctx: the context for the connection to hald
1746 * @udi: the Unique Device Id
1747 * @key: name of the property
1748 * @value: value of the property
1749 * @error: pointer to an initialized dbus error object for returning errors or NULL
1751 * Set a property of type signed integer.
1753 * Returns: TRUE if the property was set, FALSE if the device didn't
1754 * exist or the property had a different type.
1757 libhal_device_set_property_int (LibHalContext
*ctx
, const char *udi
,
1758 const char *key
, dbus_int32_t value
, DBusError
*error
)
1760 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1761 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1762 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1764 return libhal_device_set_property_helper (ctx
, udi
, key
,
1766 NULL
, value
, 0, 0.0f
, FALSE
, error
);
1770 * libhal_device_set_property_uint64:
1771 * @ctx: the context for the connection to hald
1772 * @udi: the Unique Device Id
1773 * @key: name of the property
1774 * @value: value of the property
1775 * @error: pointer to an initialized dbus error object for returning errors or NULL
1777 * Set a property of type unsigned integer.
1779 * Returns: TRUE if the property was set, FALSE if the device didn't
1780 * exist or the property had a different type.
1783 libhal_device_set_property_uint64 (LibHalContext
*ctx
, const char *udi
,
1784 const char *key
, dbus_uint64_t value
, DBusError
*error
)
1786 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1787 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1788 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1790 return libhal_device_set_property_helper (ctx
, udi
, key
,
1792 NULL
, 0, value
, 0.0f
, FALSE
, error
);
1796 * libhal_device_set_property_double:
1797 * @ctx: the context for the connection to hald
1798 * @udi: the Unique Device Id
1799 * @key: name of the property
1800 * @value: value of the property
1801 * @error: pointer to an initialized dbus error object for returning errors or NULL
1803 * Set a property of type double.
1805 * Returns: TRUE if the property was set, FALSE if the device didn't
1806 * exist or the property had a different type.
1809 libhal_device_set_property_double (LibHalContext
*ctx
, const char *udi
,
1810 const char *key
, double value
, DBusError
*error
)
1812 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1813 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1814 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1816 return libhal_device_set_property_helper (ctx
, udi
, key
,
1818 NULL
, 0, 0, value
, FALSE
, error
);
1822 * libhal_device_set_property_bool:
1823 * @ctx: the context for the connection to hald
1824 * @udi: the Unique Device Id
1825 * @key: name of the property
1826 * @value: value of the property
1827 * @error: pointer to an initialized dbus error object for returning errors or NULL
1829 * Set a property of type bool.
1831 * Returns: TRUE if the property was set, FALSE if the device didn't
1832 * exist or the property had a different type.
1835 libhal_device_set_property_bool (LibHalContext
*ctx
, const char *udi
,
1836 const char *key
, dbus_bool_t value
, DBusError
*error
)
1838 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1839 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1840 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1842 return libhal_device_set_property_helper (ctx
, udi
, key
,
1844 NULL
, 0, 0, 0.0f
, value
, error
);
1849 * libhal_device_remove_property:
1850 * @ctx: the context for the connection to hald
1851 * @udi: the Unique Device Id
1852 * @key: name of the property
1853 * @error: pointer to an initialized dbus error object for returning errors or NULL
1855 * Remove a property.
1857 * Returns: TRUE if the property was set, FALSE if the device didn't
1861 libhal_device_remove_property (LibHalContext
*ctx
,
1862 const char *udi
, const char *key
, DBusError
*error
)
1864 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1865 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1866 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1868 return libhal_device_set_property_helper (ctx
, udi
, key
, DBUS_TYPE_INVALID
,
1869 /* DBUS_TYPE_INVALID means remove */
1870 NULL
, 0, 0, 0.0f
, FALSE
, error
);
1874 * libhal_device_property_strlist_append:
1875 * @ctx: the context for the connection to hald
1876 * @udi: the Unique Device Id
1877 * @key: name of the property
1878 * @value: value to append to property
1879 * @error: pointer to an initialized dbus error object for returning errors or NULL
1881 * Append to a property of type strlist.
1883 * Returns: TRUE if the value was appended, FALSE if the device didn't
1884 * exist or the property had a different type.
1887 libhal_device_property_strlist_append (LibHalContext
*ctx
,
1893 DBusMessage
*message
;
1895 DBusMessageIter iter
;
1897 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1898 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1899 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1900 LIBHAL_CHECK_PARAM_VALID(value
, "*value", FALSE
);
1902 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1903 "org.freedesktop.Hal.Device",
1904 "StringListAppend");
1905 if (message
== NULL
) {
1907 "%s %d : Couldn't allocate D-BUS message\n",
1908 __FILE__
, __LINE__
);
1911 dbus_message_iter_init_append (message
, &iter
);
1912 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1913 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &value
);
1915 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1919 dbus_message_unref (message
);
1921 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1924 if (reply
== NULL
) {
1928 dbus_message_unref (reply
);
1933 * libhal_device_property_strlist_prepend:
1934 * @ctx: the context for the connection to hald
1935 * @udi: the Unique Device Id
1936 * @key: name of the property
1937 * @value: value to prepend to property
1938 * @error: pointer to an initialized dbus error object for returning errors or NULL
1940 * Prepend to a property of type strlist.
1942 * Returns: TRUE if the value was prepended, FALSE if the device
1943 * didn't exist or the property had a different type.
1946 libhal_device_property_strlist_prepend (LibHalContext
*ctx
,
1952 DBusMessage
*message
;
1954 DBusMessageIter iter
;
1956 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
1957 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
1958 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
1959 LIBHAL_CHECK_PARAM_VALID(value
, "*value", FALSE
);
1961 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
1962 "org.freedesktop.Hal.Device",
1963 "StringListPrepend");
1964 if (message
== NULL
) {
1966 "%s %d : Couldn't allocate D-BUS message\n",
1967 __FILE__
, __LINE__
);
1970 dbus_message_iter_init_append (message
, &iter
);
1971 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
1972 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &value
);
1974 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
1978 dbus_message_unref (message
);
1980 if (error
!= NULL
&& dbus_error_is_set (error
)) {
1983 if (reply
== NULL
) {
1987 dbus_message_unref (reply
);
1992 * libhal_device_property_strlist_remove_index:
1993 * @ctx: the context for the connection to hald
1994 * @udi: the Unique Device Id
1995 * @key: name of the property
1996 * @idx: index of string to remove in the strlist
1997 * @error: pointer to an initialized dbus error object for returning errors or NULL
1999 * Remove a specified string from a property of type strlist.
2001 * Returns: TRUE if the string was removed, FALSE if the device didn't
2002 * exist or the property had a different type.
2005 libhal_device_property_strlist_remove_index (LibHalContext
*ctx
,
2011 DBusMessage
*message
;
2013 DBusMessageIter iter
;
2015 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2016 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2017 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
2019 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
2020 "org.freedesktop.Hal.Device",
2021 "StringListRemoveIndex");
2022 if (message
== NULL
) {
2024 "%s %d : Couldn't allocate D-BUS message\n",
2025 __FILE__
, __LINE__
);
2028 dbus_message_iter_init_append (message
, &iter
);
2029 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
2030 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_UINT32
, &idx
);
2032 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2036 dbus_message_unref (message
);
2038 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2041 if (reply
== NULL
) {
2045 dbus_message_unref (reply
);
2050 * libhal_device_property_strlist_remove:
2051 * @ctx: the context for the connection to hald
2052 * @udi: the Unique Device Id
2053 * @key: name of the property
2054 * @value: the string to remove
2055 * @error: pointer to an initialized dbus error object for returning errors or NULL
2057 * Remove a specified string from a property of type strlist.
2059 * Returns: TRUE if the string was removed, FALSE if the device didn't
2060 * exist or the property had a different type.
2063 libhal_device_property_strlist_remove (LibHalContext
*ctx
,
2066 const char *value
, DBusError
*error
)
2068 DBusMessage
*message
;
2070 DBusMessageIter iter
;
2072 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2073 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2074 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
2075 LIBHAL_CHECK_PARAM_VALID(value
, "*value", FALSE
);
2077 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
2078 "org.freedesktop.Hal.Device",
2079 "StringListRemove");
2080 if (message
== NULL
) {
2082 "%s %d : Couldn't allocate D-BUS message\n",
2083 __FILE__
, __LINE__
);
2086 dbus_message_iter_init_append (message
, &iter
);
2087 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
2088 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &value
);
2090 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2094 dbus_message_unref (message
);
2096 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2099 if (reply
== NULL
) {
2103 dbus_message_unref (reply
);
2109 * libhal_device_lock:
2110 * @ctx: the context for the connection to hald
2111 * @udi: the Unique Device Id
2112 * @reason_to_lock: a user-presentable reason why the device is locked.
2113 * @reason_why_locked: a pointer to store the reason why the device cannot be locked on failure, or NULL
2114 * @error: pointer to an initialized dbus error object for returning errors or NULL
2116 * Take an advisory lock on the device.
2118 * Returns: TRUE if the lock was obtained, FALSE otherwise
2121 libhal_device_lock (LibHalContext
*ctx
,
2123 const char *reason_to_lock
,
2124 char **reason_why_locked
, DBusError
*error
)
2126 DBusMessage
*message
;
2127 DBusMessageIter iter
;
2130 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2131 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2133 if (reason_why_locked
!= NULL
)
2134 *reason_why_locked
= NULL
;
2136 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2138 "org.freedesktop.Hal.Device",
2141 if (message
== NULL
) {
2143 "%s %d : Couldn't allocate D-BUS message\n",
2144 __FILE__
, __LINE__
);
2148 dbus_message_iter_init_append (message
, &iter
);
2149 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &reason_to_lock
);
2152 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2156 dbus_message_unref (message
);
2158 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2159 if (strcmp (error
->name
,
2160 "org.freedesktop.Hal.DeviceAlreadyLocked") == 0) {
2161 if (reason_why_locked
!= NULL
) {
2162 *reason_why_locked
=
2163 dbus_malloc0 (strlen (error
->message
) + 1);
2164 if (*reason_why_locked
== NULL
)
2166 strcpy (*reason_why_locked
, error
->message
);
2175 dbus_message_unref (reply
);
2181 * libhal_device_unlock:
2182 * @ctx: the context for the connection to hald
2183 * @udi: the Unique Device Id
2184 * @error: pointer to an initialized dbus error object for returning errors or NULL
2186 * Release an advisory lock on the device.
2188 * Returns: TRUE if the device was successfully unlocked,
2192 libhal_device_unlock (LibHalContext
*ctx
,
2193 const char *udi
, DBusError
*error
)
2195 DBusMessage
*message
;
2198 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2199 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2201 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2203 "org.freedesktop.Hal.Device",
2206 if (message
== NULL
) {
2208 "%s %d : Couldn't allocate D-BUS message\n",
2209 __FILE__
, __LINE__
);
2214 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2218 dbus_message_unref (message
);
2220 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2226 dbus_message_unref (reply
);
2233 * libhal_new_device:
2234 * @ctx: the context for the connection to hald
2235 * @error: pointer to an initialized dbus error object for returning errors or NULL
2237 * Create a new device object which will be hidden from applications
2238 * until the CommitToGdl(), ie. libhal_device_commit_to_gdl(), method
2239 * is called. Note that the program invoking this method needs to run
2240 * with super user privileges.
2242 * Returns: Temporary device unique id or NULL if there was a
2243 * problem. This string must be freed by the caller.
2246 libhal_new_device (LibHalContext
*ctx
, DBusError
*error
)
2248 DBusMessage
*message
;
2250 DBusMessageIter reply_iter
;
2254 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
2256 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2257 "/org/freedesktop/Hal/Manager",
2258 "org.freedesktop.Hal.Manager",
2260 if (message
== NULL
) {
2262 "%s %d : Couldn't allocate D-BUS message\n",
2263 __FILE__
, __LINE__
);
2268 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2272 dbus_message_unref (message
);
2274 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2277 if (reply
== NULL
) {
2281 dbus_message_iter_init (reply
, &reply_iter
);
2283 /* now analyze reply */
2284 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_STRING
) {
2286 "%s %d : expected a string in reply to NewDevice\n",
2287 __FILE__
, __LINE__
);
2288 dbus_message_unref (reply
);
2292 dbus_message_iter_get_basic (&reply_iter
, &dbus_str
);
2293 value
= (char *) ((dbus_str
!= NULL
) ? strdup (dbus_str
) : NULL
);
2294 if (value
== NULL
) {
2295 fprintf (stderr
, "%s %d : error allocating memory\n",
2296 __FILE__
, __LINE__
);
2299 dbus_message_unref (reply
);
2305 * libhal_device_commit_to_gdl:
2306 * @ctx: the context for the connection to hald
2307 * @temp_udi: the temporary unique device id as returned by libhal_new_device()
2308 * @udi: the new unique device id.
2309 * @error: pointer to an initialized dbus error object for returning errors or NULL
2311 * When a hidden device has been built using the NewDevice method,
2312 * ie. libhal_new_device(), and the org.freedesktop.Hal.Device
2313 * interface this function will commit it to the global device list.
2315 * This means that the device object will be visible to applications
2316 * and the HAL daemon will possibly attempt to boot the device
2317 * (depending on the property RequireEnable).
2319 * Note that the program invoking this method needs to run with super
2322 * Returns: FALSE if the given unique device id is already in use.
2325 libhal_device_commit_to_gdl (LibHalContext
*ctx
,
2326 const char *temp_udi
, const char *udi
, DBusError
*error
)
2328 DBusMessage
*message
;
2330 DBusMessageIter iter
;
2332 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2333 LIBHAL_CHECK_UDI_VALID(temp_udi
, FALSE
);
2334 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2336 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2337 "/org/freedesktop/Hal/Manager",
2338 "org.freedesktop.Hal.Manager",
2340 if (message
== NULL
) {
2342 "%s %d : Couldn't allocate D-BUS message\n",
2343 __FILE__
, __LINE__
);
2347 dbus_message_iter_init_append (message
, &iter
);
2348 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &temp_udi
);
2349 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &udi
);
2352 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2356 dbus_message_unref (message
);
2358 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2361 if (reply
== NULL
) {
2365 dbus_message_unref (reply
);
2370 * libhal_remove_device:
2371 * @ctx: the context for the connection to hald
2372 * @udi: the Unique device id.
2373 * @error: pointer to an initialized dbus error object for returning errors or NULL
2375 * This method can be invoked when a device is removed. The HAL daemon
2376 * will shut down the device. Note that the device may still be in the
2377 * device list if the Persistent property is set to true.
2379 * Note that the program invoking this method needs to run with super
2382 * Returns: TRUE if the device was removed, FALSE otherwise
2385 libhal_remove_device (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
2387 DBusMessage
*message
;
2389 DBusMessageIter iter
;
2391 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2392 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2394 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2395 "/org/freedesktop/Hal/Manager",
2396 "org.freedesktop.Hal.Manager",
2398 if (message
== NULL
) {
2400 "%s %d : Couldn't allocate D-BUS message\n",
2401 __FILE__
, __LINE__
);
2405 dbus_message_iter_init_append (message
, &iter
);
2406 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &udi
);
2409 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2413 dbus_message_unref (message
);
2415 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2418 if (reply
== NULL
) {
2422 dbus_message_unref (reply
);
2427 * libhal_device_exists:
2428 * @ctx: the context for the connection to hald
2429 * @udi: the Unique device id.
2430 * @error: pointer to an initialized dbus error object for returning errors or NULL
2432 * Determine if a device exists.
2434 * Returns: TRUE if the device exists
2437 libhal_device_exists (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
2439 DBusMessage
*message
;
2441 DBusMessageIter iter
, reply_iter
;
2445 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2446 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2448 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2449 "/org/freedesktop/Hal/Manager",
2450 "org.freedesktop.Hal.Manager",
2452 if (message
== NULL
) {
2454 "%s %d : Couldn't allocate D-BUS message\n",
2455 __FILE__
, __LINE__
);
2459 dbus_message_iter_init_append (message
, &iter
);
2460 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &udi
);
2462 dbus_error_init (&_error
);
2463 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2467 dbus_message_unref (message
);
2469 dbus_move_error (&_error
, error
);
2470 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2473 if (reply
== NULL
) {
2477 dbus_message_iter_init (reply
, &reply_iter
);
2479 /* now analyze reply */
2480 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_BOOLEAN
) {
2482 "%s %d : expected a bool in reply to DeviceExists\n",
2483 __FILE__
, __LINE__
);
2484 dbus_message_unref (reply
);
2488 dbus_message_iter_get_basic (&reply_iter
, &value
);
2490 dbus_message_unref (reply
);
2495 * libhal_device_property_exists:
2496 * @ctx: the context for the connection to hald
2497 * @udi: the Unique device id.
2498 * @key: name of the property
2499 * @error: pointer to an initialized dbus error object for returning errors or NULL
2501 * Determine if a property on a device exists.
2503 * Returns: TRUE if the device exists, FALSE otherwise
2506 libhal_device_property_exists (LibHalContext
*ctx
,
2507 const char *udi
, const char *key
, DBusError
*error
)
2509 DBusMessage
*message
;
2511 DBusMessageIter iter
, reply_iter
;
2515 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2516 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2517 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
2519 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
2520 "org.freedesktop.Hal.Device",
2522 if (message
== NULL
) {
2524 "%s %d : Couldn't allocate D-BUS message\n",
2525 __FILE__
, __LINE__
);
2529 dbus_message_iter_init_append (message
, &iter
);
2530 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
2532 dbus_error_init (&_error
);
2533 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2537 dbus_message_unref (message
);
2539 dbus_move_error (&_error
, error
);
2540 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2543 if (reply
== NULL
) {
2547 dbus_message_iter_init (reply
, &reply_iter
);
2549 /* now analyse reply */
2550 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_BOOLEAN
) {
2551 fprintf (stderr
, "%s %d : expected a bool in reply to "
2552 "PropertyExists\n", __FILE__
, __LINE__
);
2553 dbus_message_unref (reply
);
2557 dbus_message_iter_get_basic (&reply_iter
, &value
);
2559 dbus_message_unref (reply
);
2564 * libhal_merge_properties:
2565 * @ctx: the context for the connection to hald
2566 * @target_udi: the Unique device id of target device to merge to
2567 * @source_udi: the Unique device id of device to merge from
2568 * @error: pointer to an initialized dbus error object for returning errors or NULL
2570 * Merge properties from one device to another.
2572 * Returns: TRUE if the properties were merged, FALSE otherwise
2575 libhal_merge_properties (LibHalContext
*ctx
,
2576 const char *target_udi
, const char *source_udi
, DBusError
*error
)
2578 DBusMessage
*message
;
2580 DBusMessageIter iter
;
2582 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2583 LIBHAL_CHECK_UDI_VALID(target_udi
, FALSE
);
2584 LIBHAL_CHECK_UDI_VALID(source_udi
, FALSE
);
2586 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2587 "/org/freedesktop/Hal/Manager",
2588 "org.freedesktop.Hal.Manager",
2590 if (message
== NULL
) {
2592 "%s %d : Couldn't allocate D-BUS message\n",
2593 __FILE__
, __LINE__
);
2597 dbus_message_iter_init_append (message
, &iter
);
2598 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &target_udi
);
2599 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &source_udi
);
2602 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2606 dbus_message_unref (message
);
2608 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2611 if (reply
== NULL
) {
2615 dbus_message_unref (reply
);
2620 * libhal_device_matches:
2621 * @ctx: the context for the connection to hald
2622 * @udi1: the Unique Device Id for device 1
2623 * @udi2: the Unique Device Id for device 2
2624 * @property_namespace: the namespace for set of devices, e.g. "usb"
2625 * @error: pointer to an initialized dbus error object for returning errors or NULL
2627 * Check a set of properties for two devices matches.
2629 * Checks that all properties where keys, starting with a given value
2630 * (namespace), of the first device is in the second device and that
2631 * they got the same value and type.
2633 * Note that the other inclusion isn't tested, so there could be
2634 * properties (from the given namespace) in the second device not
2635 * present in the first device.
2637 * Returns: TRUE if all properties starting with the given namespace
2638 * parameter from one device is in the other and have the same value.
2641 libhal_device_matches (LibHalContext
*ctx
,
2642 const char *udi1
, const char *udi2
,
2643 const char *property_namespace
, DBusError
*error
)
2645 DBusMessage
*message
;
2647 DBusMessageIter iter
, reply_iter
;
2651 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2652 LIBHAL_CHECK_UDI_VALID(udi1
, FALSE
);
2653 LIBHAL_CHECK_UDI_VALID(udi2
, FALSE
);
2654 LIBHAL_CHECK_PARAM_VALID(property_namespace
, "*property_namespace", FALSE
);
2656 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2657 "/org/freedesktop/Hal/Manager",
2658 "org.freedesktop.Hal.Manager",
2660 if (message
== NULL
) {
2662 "%s %d : Couldn't allocate D-BUS message\n",
2663 __FILE__
, __LINE__
);
2667 dbus_message_iter_init_append (message
, &iter
);
2668 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, udi1
);
2669 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, udi2
);
2670 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, property_namespace
);
2672 dbus_error_init (&_error
);
2673 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2677 dbus_message_unref (message
);
2679 dbus_move_error (&_error
, error
);
2680 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2683 if (reply
== NULL
) {
2686 /* now analyse reply */
2687 dbus_message_iter_init (reply
, &reply_iter
);
2689 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_BOOLEAN
) {
2691 "%s %d : expected a bool in reply to DeviceMatches\n",
2692 __FILE__
, __LINE__
);
2693 dbus_message_unref (reply
);
2697 dbus_message_iter_get_basic (&reply_iter
, &value
);
2699 dbus_message_unref (reply
);
2704 * libhal_device_print:
2705 * @ctx: the context for the connection to hald
2706 * @udi: the Unique Device Id
2707 * @error: pointer to an initialized dbus error object for returning errors or NULL
2709 * Print a device to stdout; useful for debugging.
2711 * Returns: TRUE if device's information could be obtained, FALSE otherwise
2714 libhal_device_print (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
2718 LibHalPropertySet
*pset
;
2719 LibHalPropertySetIterator i
;
2721 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2722 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2724 printf ("device_id = %s\n", udi
);
2726 if ((pset
= libhal_device_get_all_properties (ctx
, udi
, error
)) == NULL
)
2729 for (libhal_psi_init (&i
, pset
); libhal_psi_has_more (&i
);
2730 libhal_psi_next (&i
)) {
2731 type
= libhal_psi_get_type (&i
);
2732 key
= libhal_psi_get_key (&i
);
2735 case LIBHAL_PROPERTY_TYPE_STRING
:
2736 printf (" %s = '%s' (string)\n", key
,
2737 libhal_psi_get_string (&i
));
2739 case LIBHAL_PROPERTY_TYPE_INT32
:
2740 printf (" %s = %d = 0x%x (int)\n", key
,
2741 libhal_psi_get_int (&i
),
2742 libhal_psi_get_int (&i
));
2744 case LIBHAL_PROPERTY_TYPE_UINT64
:
2745 printf (" %s = %llu = 0x%llx (uint64)\n", key
,
2746 (long long unsigned int) libhal_psi_get_uint64 (&i
),
2747 (long long unsigned int) libhal_psi_get_uint64 (&i
));
2749 case LIBHAL_PROPERTY_TYPE_BOOLEAN
:
2750 printf (" %s = %s (bool)\n", key
,
2751 (libhal_psi_get_bool (&i
) ? "true" :
2754 case LIBHAL_PROPERTY_TYPE_DOUBLE
:
2755 printf (" %s = %g (double)\n", key
,
2756 libhal_psi_get_double (&i
));
2758 case LIBHAL_PROPERTY_TYPE_STRLIST
:
2763 str_list
= libhal_psi_get_strlist (&i
);
2764 printf (" %s = [", key
);
2765 for (j
= 0; str_list
[j
] != NULL
; j
++) {
2766 printf ("'%s'", str_list
[j
]);
2767 if (str_list
[j
+1] != NULL
)
2770 printf ("] (string list)\n");
2775 printf (" *** unknown type for key %s\n", key
);
2780 libhal_free_property_set (pset
);
2786 * libhal_manager_find_device_string_match:
2787 * @ctx: the context for the connection to hald
2788 * @key: name of the property
2789 * @value: the value to match
2790 * @num_devices: pointer to store number of devices
2791 * @error: pointer to an initialized dbus error object for returning errors or NULL
2793 * Find a device in the GDL where a single string property matches a
2796 * Returns: UDI of devices; free with libhal_free_string_array()
2799 libhal_manager_find_device_string_match (LibHalContext
*ctx
,
2801 const char *value
, int *num_devices
, DBusError
*error
)
2803 DBusMessage
*message
;
2805 DBusMessageIter iter
, iter_array
, reply_iter
;
2806 char **hal_device_names
;
2809 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
2810 LIBHAL_CHECK_PARAM_VALID(key
, "*key", NULL
);
2811 LIBHAL_CHECK_PARAM_VALID(value
, "*value", NULL
);
2813 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2814 "/org/freedesktop/Hal/Manager",
2815 "org.freedesktop.Hal.Manager",
2816 "FindDeviceStringMatch");
2817 if (message
== NULL
) {
2819 "%s %d : Couldn't allocate D-BUS message\n",
2820 __FILE__
, __LINE__
);
2824 dbus_message_iter_init_append (message
, &iter
);
2825 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &key
);
2826 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &value
);
2828 dbus_error_init (&_error
);
2829 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2833 dbus_message_unref (message
);
2835 dbus_move_error (&_error
, error
);
2836 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2839 if (reply
== NULL
) {
2842 /* now analyse reply */
2843 dbus_message_iter_init (reply
, &reply_iter
);
2845 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_ARRAY
) {
2846 fprintf (stderr
, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__
, __LINE__
);
2850 dbus_message_iter_recurse (&reply_iter
, &iter_array
);
2852 hal_device_names
= libhal_get_string_array_from_iter (&iter_array
, num_devices
);
2854 dbus_message_unref (reply
);
2855 return hal_device_names
;
2860 * libhal_device_add_capability:
2861 * @ctx: the context for the connection to hald
2862 * @udi: the Unique Device Id
2863 * @capability: the capability name to add
2864 * @error: pointer to an initialized dbus error object for returning errors or NULL
2866 * Assign a capability to a device.
2868 * Returns: TRUE if the capability was added, FALSE if the device didn't exist
2871 libhal_device_add_capability (LibHalContext
*ctx
,
2872 const char *udi
, const char *capability
, DBusError
*error
)
2874 DBusMessage
*message
;
2876 DBusMessageIter iter
;
2878 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2879 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2880 LIBHAL_CHECK_PARAM_VALID(capability
, "*capability", FALSE
);
2882 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
2883 "org.freedesktop.Hal.Device",
2885 if (message
== NULL
) {
2887 "%s %d : Couldn't allocate D-BUS message\n",
2888 __FILE__
, __LINE__
);
2892 dbus_message_iter_init_append (message
, &iter
);
2893 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &capability
);
2896 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2900 dbus_message_unref (message
);
2902 if (error
!= NULL
&& dbus_error_is_set (error
)) {
2905 if (reply
== NULL
) {
2909 dbus_message_unref (reply
);
2914 * libhal_device_query_capability:
2915 * @ctx: the context for the connection to hald
2916 * @udi: the Unique Device Id
2917 * @capability: the capability name
2918 * @error: pointer to an initialized dbus error object for returning errors or NULL
2920 * Check if a device has a capability. The result is undefined if the
2921 * device doesn't exist.
2923 * Returns: TRUE if the device has the capability, otherwise FALSE
2926 libhal_device_query_capability (LibHalContext
*ctx
, const char *udi
, const char *capability
, DBusError
*error
)
2932 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
2933 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
2934 LIBHAL_CHECK_PARAM_VALID(capability
, "*capability", FALSE
);
2938 caps
= libhal_device_get_property_strlist (ctx
, udi
, "info.capabilities", error
);
2940 for (i
= 0; caps
[i
] != NULL
; i
++) {
2941 if (strcmp (caps
[i
], capability
) == 0) {
2946 libhal_free_string_array (caps
);
2953 * libhal_find_device_by_capability:
2954 * @ctx: the context for the connection to hald
2955 * @capability: the capability name
2956 * @num_devices: pointer to store number of devices
2957 * @error: pointer to an initialized dbus error object for returning errors or NULL
2959 * Find devices with a given capability.
2961 * Returns: UDI of devices; free with libhal_free_string_array()
2964 libhal_find_device_by_capability (LibHalContext
*ctx
,
2965 const char *capability
, int *num_devices
, DBusError
*error
)
2967 DBusMessage
*message
;
2969 DBusMessageIter iter
, iter_array
, reply_iter
;
2970 char **hal_device_names
;
2973 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
2974 LIBHAL_CHECK_PARAM_VALID(capability
, "*capability", NULL
);
2976 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
2977 "/org/freedesktop/Hal/Manager",
2978 "org.freedesktop.Hal.Manager",
2979 "FindDeviceByCapability");
2980 if (message
== NULL
) {
2982 "%s %d : Couldn't allocate D-BUS message\n",
2983 __FILE__
, __LINE__
);
2987 dbus_message_iter_init_append (message
, &iter
);
2988 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &capability
);
2990 dbus_error_init (&_error
);
2991 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
2995 dbus_message_unref (message
);
2997 dbus_move_error (&_error
, error
);
2998 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3001 if (reply
== NULL
) {
3004 /* now analyse reply */
3005 dbus_message_iter_init (reply
, &reply_iter
);
3007 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_ARRAY
) {
3008 fprintf (stderr
, "%s %d : wrong reply from hald. Expecting an array.\n", __FILE__
, __LINE__
);
3012 dbus_message_iter_recurse (&reply_iter
, &iter_array
);
3014 hal_device_names
= libhal_get_string_array_from_iter (&iter_array
, num_devices
);
3016 dbus_message_unref (reply
);
3017 return hal_device_names
;
3021 * libhal_device_property_watch_all:
3022 * @ctx: the context for the connection to hald
3023 * @error: pointer to an initialized dbus error object for returning errors or NULL
3025 * Watch all devices, ie. the device_property_changed callback is
3026 * invoked when the properties on any device changes.
3028 * Returns: TRUE only if the operation succeeded
3031 libhal_device_property_watch_all (LibHalContext
*ctx
, DBusError
*error
)
3033 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3035 dbus_bus_add_match (ctx
->connection
,
3037 "interface='org.freedesktop.Hal.Device',"
3038 "sender='org.freedesktop.Hal'", error
);
3039 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3047 * libhal_device_add_property_watch:
3048 * @ctx: the context for the connection to hald
3049 * @udi: the Unique Device Id
3050 * @error: pointer to an initialized dbus error object for returning errors or NULL
3052 * Add a watch on a device, so the device_property_changed callback is
3053 * invoked when the properties on the given device changes.
3055 * The application itself is responsible for deleting the watch, using
3056 * libhal_device_remove_property_watch, if the device is removed.
3058 * Returns: TRUE only if the operation succeeded
3061 libhal_device_add_property_watch (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
3065 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3066 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3070 "interface='org.freedesktop.Hal.Device',"
3071 "sender='org.freedesktop.Hal'," "path=%s", udi
);
3073 dbus_bus_add_match (ctx
->connection
, buf
, error
);
3074 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3082 * libhal_device_remove_property_watch:
3083 * @ctx: the context for the connection to hald
3084 * @udi: the Unique Device Id
3085 * @error: pointer to an initialized dbus error object for returning errors or NULL
3087 * Remove a watch on a device.
3089 * Returns: TRUE only if the operation succeeded
3092 libhal_device_remove_property_watch (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
3096 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3097 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3101 "interface='org.freedesktop.Hal.Device',"
3102 "sender='org.freedesktop.Hal'," "path=%s", udi
);
3104 dbus_bus_remove_match (ctx
->connection
, buf
, error
);
3105 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3115 * Create a new LibHalContext
3117 * Returns: a new uninitialized LibHalContext object
3120 libhal_ctx_new (void)
3124 if (!libhal_already_initialized_once
) {
3125 bindtextdomain (GETTEXT_PACKAGE
, PACKAGE_LOCALE_DIR
);
3126 bind_textdomain_codeset (GETTEXT_PACKAGE
, "UTF-8");
3128 libhal_already_initialized_once
= TRUE
;
3131 ctx
= calloc (1, sizeof (LibHalContext
));
3134 "%s %d : Failed to allocate %lu bytes\n",
3135 __FILE__
, __LINE__
, (unsigned long) sizeof (LibHalContext
));
3139 ctx
->is_initialized
= FALSE
;
3140 ctx
->is_shutdown
= FALSE
;
3141 ctx
->connection
= NULL
;
3142 ctx
->is_direct
= FALSE
;
3148 * libhal_ctx_set_cache:
3149 * @ctx: context to enable/disable cache for
3150 * @use_cache: whether or not to use cache
3152 * Enable or disable caching. Note: Caching is not actually
3155 * Returns: TRUE if cache was successfully enabled/disabled, FALSE otherwise
3158 libhal_ctx_set_cache (LibHalContext
*ctx
, dbus_bool_t use_cache
)
3160 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3162 ctx
->cache_enabled
= use_cache
;
3167 * libhal_ctx_set_dbus_connection:
3168 * @ctx: context to set connection for
3169 * @conn: DBus connection to use
3171 * Set DBus connection to use to talk to hald.
3173 * Returns: TRUE if connection was successfully set, FALSE otherwise
3176 libhal_ctx_set_dbus_connection (LibHalContext
*ctx
, DBusConnection
*conn
)
3178 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3183 ctx
->connection
= conn
;
3188 * libhal_ctx_get_dbus_connection:
3189 * @ctx: context to get connection for
3191 * Get DBus connection used for talking to hald.
3193 * Returns: DBus connection to use or NULL
3196 libhal_ctx_get_dbus_connection (LibHalContext
*ctx
)
3198 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, NULL
);
3200 return ctx
->connection
;
3206 * @ctx: Context for connection to hald (D-BUS connection should be set with libhal_ctx_set_dbus_connection)
3207 * @error: pointer to an initialized dbus error object for returning errors or NULL
3209 * Initialize the connection to hald.
3211 * Returns: TRUE if initialization succeeds, FALSE otherwise
3214 libhal_ctx_init (LibHalContext
*ctx
, DBusError
*error
)
3217 dbus_bool_t hald_exists
;
3219 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3221 if (ctx
->connection
== NULL
)
3224 dbus_error_init (&_error
);
3225 hald_exists
= dbus_bus_name_has_owner (ctx
->connection
, "org.freedesktop.Hal", &_error
);
3226 dbus_move_error (&_error
, error
);
3227 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3236 if (!dbus_connection_add_filter (ctx
->connection
, filter_func
, ctx
, NULL
)) {
3240 dbus_bus_add_match (ctx
->connection
,
3242 "interface='org.freedesktop.Hal.Manager',"
3243 "sender='org.freedesktop.Hal',"
3244 "path='/org/freedesktop/Hal/Manager'", &_error
);
3245 dbus_move_error (&_error
, error
);
3246 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3249 ctx
->is_initialized
= TRUE
;
3250 ctx
->is_direct
= FALSE
;
3256 * libhal_ctx_init_direct:
3257 * @error: pointer to an initialized dbus error object for returning errors or NULL
3259 * Create an already initialized connection to hald. This function should only be used by HAL helpers.
3261 * Returns: A pointer to an already initialized LibHalContext
3264 libhal_ctx_init_direct (DBusError
*error
)
3270 ctx
= libhal_ctx_new ();
3274 if (((hald_addr
= getenv ("HALD_DIRECT_ADDR"))) == NULL
) {
3275 libhal_ctx_free (ctx
);
3280 dbus_error_init (&_error
);
3281 ctx
->connection
= dbus_connection_open (hald_addr
, &_error
);
3282 dbus_move_error (&_error
, error
);
3283 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3284 libhal_ctx_free (ctx
);
3289 ctx
->is_initialized
= TRUE
;
3290 ctx
->is_direct
= TRUE
;
3297 * libhal_ctx_shutdown:
3298 * @ctx: the context for the connection to hald
3299 * @error: pointer to an initialized dbus error object for returning errors or NULL
3301 * Shut down a connection to hald.
3303 * Returns: TRUE if connection successfully shut down, FALSE otherwise
3306 libhal_ctx_shutdown (LibHalContext
*ctx
, DBusError
*error
)
3310 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3312 if (ctx
->is_direct
) {
3313 /* for some reason dbus_connection_set_exit_on_disconnect doesn't work yet so don't unref */
3314 /*dbus_connection_unref (ctx->connection);*/
3316 dbus_error_init (&myerror
);
3317 dbus_bus_remove_match (ctx
->connection
,
3319 "interface='org.freedesktop.Hal.Manager',"
3320 "sender='org.freedesktop.Hal',"
3321 "path='/org/freedesktop/Hal/Manager'", &myerror
);
3322 dbus_move_error (&myerror
, error
);
3323 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3324 fprintf (stderr
, "%s %d : Error unsubscribing to signals, error=%s\n",
3325 __FILE__
, __LINE__
, error
->message
);
3326 /** @todo clean up */
3329 /* TODO: remove other matches */
3331 dbus_connection_remove_filter (ctx
->connection
, filter_func
, ctx
);
3334 ctx
->is_initialized
= FALSE
;
3341 * @ctx: pointer to a LibHalContext
3343 * Free a LibHalContext resource.
3348 libhal_ctx_free (LibHalContext
*ctx
)
3355 * libhal_ctx_set_device_added:
3356 * @ctx: the context for the connection to hald
3357 * @callback: the function to call when a device is added
3359 * Set the callback for when a device is added
3361 * Returns: TRUE if callback was successfully set, FALSE otherwise
3364 libhal_ctx_set_device_added (LibHalContext
*ctx
, LibHalDeviceAdded callback
)
3366 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3368 ctx
->device_added
= callback
;
3373 * libhal_ctx_set_device_removed:
3374 * @ctx: the context for the connection to hald
3375 * @callback: the function to call when a device is removed
3377 * Set the callback for when a device is removed.
3379 * Returns: TRUE if callback was successfully set, FALSE otherwise
3382 libhal_ctx_set_device_removed (LibHalContext
*ctx
, LibHalDeviceRemoved callback
)
3384 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3386 ctx
->device_removed
= callback
;
3391 * libhal_ctx_set_device_new_capability:
3392 * @ctx: the context for the connection to hald
3393 * @callback: the function to call when a device gains a new capability
3395 * Set the callback for when a device gains a new capability.
3397 * Returns: TRUE if callback was successfully set, FALSE otherwise
3400 libhal_ctx_set_device_new_capability (LibHalContext
*ctx
, LibHalDeviceNewCapability callback
)
3402 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3404 ctx
->device_new_capability
= callback
;
3409 * libhal_ctx_set_device_lost_capability:
3410 * @ctx: the context for the connection to hald
3411 * @callback: the function to call when a device loses a capability
3413 * Set the callback for when a device loses a capability
3415 * Returns: TRUE if callback was successfully set, FALSE otherwise
3418 libhal_ctx_set_device_lost_capability (LibHalContext
*ctx
, LibHalDeviceLostCapability callback
)
3420 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3422 ctx
->device_lost_capability
= callback
;
3427 * libhal_ctx_set_device_property_modified:
3428 * @ctx: the context for the connection to hald
3429 * @callback: the function to call when a property is modified on a device
3431 * Set the callback for when a property is modified on a device.
3433 * Returns: TRUE if callback was successfully set, FALSE otherwise
3436 libhal_ctx_set_device_property_modified (LibHalContext
*ctx
, LibHalDevicePropertyModified callback
)
3438 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3440 ctx
->device_property_modified
= callback
;
3445 * libhal_ctx_set_device_condition:
3446 * @ctx: the context for the connection to hald
3447 * @callback: the function to call when a device emits a condition
3449 * Set the callback for when a device emits a condition
3451 * Returns: TRUE if callback was successfully set, FALSE otherwise
3454 libhal_ctx_set_device_condition (LibHalContext
*ctx
, LibHalDeviceCondition callback
)
3456 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3458 ctx
->device_condition
= callback
;
3463 * libhal_string_array_length:
3464 * @str_array: array of strings to consider
3466 * Get the length of an array of strings.
3468 * Returns: Number of strings in array
3471 libhal_string_array_length (char **str_array
)
3475 if (str_array
== NULL
)
3478 for (i
= 0; str_array
[i
] != NULL
; i
++)
3486 * libhal_device_rescan:
3487 * @ctx: the context for the connection to hald
3488 * @udi: the Unique id of device
3489 * @error: pointer to an initialized dbus error object for returning errors or NULL
3493 * Returns: Whether the operation succeeded
3496 libhal_device_rescan (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
3498 DBusMessage
*message
;
3499 DBusMessageIter reply_iter
;
3503 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3504 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3506 message
= dbus_message_new_method_call ("org.freedesktop.Hal", udi
,
3507 "org.freedesktop.Hal.Device",
3510 if (message
== NULL
) {
3512 "%s %d : Couldn't allocate D-BUS message\n",
3513 __FILE__
, __LINE__
);
3517 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
3521 dbus_message_unref (message
);
3523 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3529 dbus_message_iter_init (reply
, &reply_iter
);
3530 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
3531 DBUS_TYPE_BOOLEAN
) {
3532 dbus_message_unref (reply
);
3535 dbus_message_iter_get_basic (&reply_iter
, &result
);
3537 dbus_message_unref (reply
);
3543 * libhal_device_reprobe:
3544 * @ctx: the context for the connection to hald
3545 * @udi: the Unique id of device
3546 * @error: pointer to an initialized dbus error object for returning errors or NULL
3550 * Returns: Whether the operation succeeded
3553 libhal_device_reprobe (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
3555 DBusMessage
*message
;
3556 DBusMessageIter reply_iter
;
3560 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3561 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3563 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
3565 "org.freedesktop.Hal.Device",
3568 if (message
== NULL
) {
3570 "%s %d : Couldn't allocate D-BUS message\n",
3571 __FILE__
, __LINE__
);
3575 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
3579 dbus_message_unref (message
);
3581 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3587 dbus_message_iter_init (reply
, &reply_iter
);
3588 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
3589 DBUS_TYPE_BOOLEAN
) {
3590 dbus_message_unref (reply
);
3593 dbus_message_iter_get_basic (&reply_iter
, &result
);
3595 dbus_message_unref (reply
);
3601 * libhal_device_emit_condition:
3602 * @ctx: the context for the connection to hald
3603 * @udi: the Unique Device Id
3604 * @condition_name: user-readable name of condition
3605 * @condition_details: user-readable details of condition
3606 * @error: pointer to an initialized dbus error object for returning errors or NULL
3608 * Emit a condition from a device. Can only be used from hald helpers.
3610 * Returns: TRUE if condition successfully emitted,
3613 dbus_bool_t
libhal_device_emit_condition (LibHalContext
*ctx
,
3615 const char *condition_name
,
3616 const char *condition_details
,
3619 DBusMessage
*message
;
3620 DBusMessageIter iter
;
3621 DBusMessageIter reply_iter
;
3625 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3626 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3627 LIBHAL_CHECK_PARAM_VALID(condition_name
, "*condition_name", FALSE
);
3628 LIBHAL_CHECK_PARAM_VALID(condition_details
, "*condition_details", FALSE
);
3630 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
3632 "org.freedesktop.Hal.Device",
3635 if (message
== NULL
) {
3637 "%s %d : Couldn't allocate D-BUS message\n",
3638 __FILE__
, __LINE__
);
3642 dbus_message_iter_init_append (message
, &iter
);
3643 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &condition_name
);
3644 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &condition_details
);
3646 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
3650 dbus_message_unref (message
);
3652 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3654 "%s %d : Failure sending D-BUS message: %s: %s\n",
3655 __FILE__
, __LINE__
, error
->name
, error
->message
);
3659 if (reply
== NULL
) {
3661 "%s %d : Got no reply\n",
3662 __FILE__
, __LINE__
);
3666 dbus_message_iter_init (reply
, &reply_iter
);
3667 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
3668 DBUS_TYPE_BOOLEAN
) {
3669 dbus_message_unref (reply
);
3671 "%s %d : Malformed reply\n",
3672 __FILE__
, __LINE__
);
3675 dbus_message_iter_get_basic (&reply_iter
, &result
);
3677 dbus_message_unref (reply
);
3683 * libhal_device_addon_is_ready:
3684 * @ctx: the context for the connection to hald
3685 * @udi: the Unique Device Id this addon is handling
3686 * @error: pointer to an initialized dbus error object for returning errors or NULL
3688 * HAL addon's must call this method when they are done initializing the device object. The HAL
3689 * daemon will wait for all addon's to call this.
3691 * Can only be used from hald helpers.
3693 * Returns: TRUE if the HAL daemon received the message, FALSE otherwise
3696 libhal_device_addon_is_ready (LibHalContext
*ctx
, const char *udi
, DBusError
*error
)
3698 DBusMessage
*message
;
3699 DBusMessageIter iter
;
3700 DBusMessageIter reply_iter
;
3704 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3705 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3707 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
3709 "org.freedesktop.Hal.Device",
3712 if (message
== NULL
) {
3714 "%s %d : Couldn't allocate D-BUS message\n",
3715 __FILE__
, __LINE__
);
3719 dbus_message_iter_init_append (message
, &iter
);
3721 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
3725 dbus_message_unref (message
);
3727 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3733 dbus_message_iter_init (reply
, &reply_iter
);
3734 if (dbus_message_iter_get_arg_type (&reply_iter
) != DBUS_TYPE_BOOLEAN
) {
3735 dbus_message_unref (reply
);
3738 dbus_message_iter_get_basic (&reply_iter
, &result
);
3740 dbus_message_unref (reply
);
3745 * libhal_device_claim_interface:
3746 * @ctx: the context for the connection to hald
3747 * @udi: the Unique Device Id
3748 * @interface_name: Name of interface to claim, e.g. org.freedesktop.Hal.Device.FoobarKindOfThing
3749 * @introspection_xml: Introspection XML containing what would be inside the interface XML tag
3750 * @error: pointer to an initialized dbus error object for returning errors or NULL
3752 * Claim an interface for a device. All messages to this interface
3753 * will be forwarded to the helper. Can only be used from hald
3756 * Returns: TRUE if interface was claimed, FALSE otherwise
3759 libhal_device_claim_interface (LibHalContext
*ctx
,
3761 const char *interface_name
,
3762 const char *introspection_xml
,
3765 DBusMessage
*message
;
3766 DBusMessageIter iter
;
3767 DBusMessageIter reply_iter
;
3771 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
3772 LIBHAL_CHECK_UDI_VALID(udi
, FALSE
);
3773 LIBHAL_CHECK_PARAM_VALID(interface_name
, "*interface_name", FALSE
);
3775 message
= dbus_message_new_method_call ("org.freedesktop.Hal",
3777 "org.freedesktop.Hal.Device",
3780 if (message
== NULL
) {
3782 "%s %d : Couldn't allocate D-BUS message\n",
3783 __FILE__
, __LINE__
);
3787 dbus_message_iter_init_append (message
, &iter
);
3788 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &interface_name
);
3789 dbus_message_iter_append_basic (&iter
, DBUS_TYPE_STRING
, &introspection_xml
);
3791 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
3795 dbus_message_unref (message
);
3797 if (error
!= NULL
&& dbus_error_is_set (error
)) {
3803 dbus_message_iter_init (reply
, &reply_iter
);
3804 if (dbus_message_iter_get_arg_type (&reply_iter
) !=
3805 DBUS_TYPE_BOOLEAN
) {
3806 dbus_message_unref (reply
);
3809 dbus_message_iter_get_basic (&reply_iter
, &result
);
3811 dbus_message_unref (reply
);
3818 struct LibHalChangeSetElement_s
;
3820 typedef struct LibHalChangeSetElement_s LibHalChangeSetElement
;
3822 struct LibHalChangeSetElement_s
{
3827 dbus_int32_t val_int
;
3828 dbus_uint64_t val_uint64
;
3830 dbus_bool_t val_bool
;
3833 LibHalChangeSetElement
*next
;
3834 LibHalChangeSetElement
*prev
;
3837 struct LibHalChangeSet_s
{
3839 LibHalChangeSetElement
*head
;
3840 LibHalChangeSetElement
*tail
;
3844 * libhal_device_new_changeset:
3845 * @udi: unique device identifier
3847 * Request a new changeset object. Used for changing multiple properties at once. Useful when
3848 * performance is critical and also for atomically updating several properties.
3850 * Returns: A new changeset object or NULL on error
3853 libhal_device_new_changeset (const char *udi
)
3855 LibHalChangeSet
*changeset
;
3857 LIBHAL_CHECK_UDI_VALID(udi
, NULL
);
3859 changeset
= calloc (1, sizeof (LibHalChangeSet
));
3860 if (changeset
== NULL
)
3863 changeset
->udi
= strdup (udi
);
3864 if (changeset
->udi
== NULL
) {
3870 changeset
->head
= NULL
;
3871 changeset
->tail
= NULL
;
3878 libhal_changeset_append (LibHalChangeSet
*changeset
, LibHalChangeSetElement
*elem
)
3880 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", );
3881 LIBHAL_CHECK_PARAM_VALID(elem
, "*elem", );
3883 if (changeset
->head
== NULL
) {
3884 changeset
->head
= elem
;
3885 changeset
->tail
= elem
;
3889 elem
->prev
= changeset
->tail
;
3891 elem
->prev
->next
= elem
;
3892 changeset
->tail
= elem
;
3898 * libhal_changeset_set_property_string:
3899 * @changeset: the changeset
3900 * @key: key of property
3901 * @value: the value to set
3905 * Returns: FALSE on OOM
3908 libhal_changeset_set_property_string (LibHalChangeSet
*changeset
, const char *key
, const char *value
)
3910 LibHalChangeSetElement
*elem
;
3912 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", FALSE
);
3913 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
3914 LIBHAL_CHECK_PARAM_VALID(value
, "*value", FALSE
);
3916 elem
= calloc (1, sizeof (LibHalChangeSetElement
));
3919 elem
->key
= strdup (key
);
3920 if (elem
->key
== NULL
) {
3926 elem
->change_type
= LIBHAL_PROPERTY_TYPE_STRING
;
3927 elem
->value
.val_str
= strdup (value
);
3928 if (elem
->value
.val_str
== NULL
) {
3935 libhal_changeset_append (changeset
, elem
);
3937 return elem
!= NULL
;
3941 * libhal_changeset_set_property_int:
3942 * @changeset: the changeset
3943 * @key: key of property
3944 * @value: the value to set
3948 * Returns: FALSE on OOM
3951 libhal_changeset_set_property_int (LibHalChangeSet
*changeset
, const char *key
, dbus_int32_t value
)
3953 LibHalChangeSetElement
*elem
;
3955 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", FALSE
);
3956 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
3958 elem
= calloc (1, sizeof (LibHalChangeSetElement
));
3961 elem
->key
= strdup (key
);
3962 if (elem
->key
== NULL
) {
3968 elem
->change_type
= LIBHAL_PROPERTY_TYPE_INT32
;
3969 elem
->value
.val_int
= value
;
3971 libhal_changeset_append (changeset
, elem
);
3973 return elem
!= NULL
;
3977 * libhal_changeset_set_property_uint64:
3978 * @changeset: the changeset
3979 * @key: key of property
3980 * @value: the value to set
3984 * Returns: FALSE on OOM
3987 libhal_changeset_set_property_uint64 (LibHalChangeSet
*changeset
, const char *key
, dbus_uint64_t value
)
3989 LibHalChangeSetElement
*elem
;
3991 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", FALSE
);
3992 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
3994 elem
= calloc (1, sizeof (LibHalChangeSetElement
));
3997 elem
->key
= strdup (key
);
3998 if (elem
->key
== NULL
) {
4004 elem
->change_type
= LIBHAL_PROPERTY_TYPE_UINT64
;
4005 elem
->value
.val_uint64
= value
;
4007 libhal_changeset_append (changeset
, elem
);
4009 return elem
!= NULL
;
4013 * libhal_changeset_set_property_double:
4014 * @changeset: the changeset
4015 * @key: key of property
4016 * @value: the value to set
4020 * Returns: FALSE on OOM
4023 libhal_changeset_set_property_double (LibHalChangeSet
*changeset
, const char *key
, double value
)
4025 LibHalChangeSetElement
*elem
;
4027 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", FALSE
);
4028 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
4030 elem
= calloc (1, sizeof (LibHalChangeSetElement
));
4033 elem
->key
= strdup (key
);
4034 if (elem
->key
== NULL
) {
4040 elem
->change_type
= LIBHAL_PROPERTY_TYPE_DOUBLE
;
4041 elem
->value
.val_double
= value
;
4043 libhal_changeset_append (changeset
, elem
);
4045 return elem
!= NULL
;
4049 * libhal_changeset_set_property_bool:
4050 * @changeset: the changeset
4051 * @key: key of property
4052 * @value: the value to set
4056 * Returns: FALSE on OOM
4059 libhal_changeset_set_property_bool (LibHalChangeSet
*changeset
, const char *key
, dbus_bool_t value
)
4061 LibHalChangeSetElement
*elem
;
4063 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", FALSE
);
4064 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
4066 elem
= calloc (1, sizeof (LibHalChangeSetElement
));
4069 elem
->key
= strdup (key
);
4070 if (elem
->key
== NULL
) {
4076 elem
->change_type
= LIBHAL_PROPERTY_TYPE_BOOLEAN
;
4077 elem
->value
.val_bool
= value
;
4079 libhal_changeset_append (changeset
, elem
);
4081 return elem
!= NULL
;
4085 * libhal_changeset_set_property_strlist:
4086 * @changeset: the changeset
4087 * @key: key of property
4088 * @value: the value to set - NULL terminated array of strings
4092 * Returns: FALSE on OOM
4095 libhal_changeset_set_property_strlist (LibHalChangeSet
*changeset
, const char *key
, const char **value
)
4097 LibHalChangeSetElement
*elem
;
4102 LIBHAL_CHECK_PARAM_VALID(changeset
, "*changeset", FALSE
);
4103 LIBHAL_CHECK_PARAM_VALID(key
, "*key", FALSE
);
4105 elem
= calloc (1, sizeof (LibHalChangeSetElement
));
4108 elem
->key
= strdup (key
);
4109 if (elem
->key
== NULL
) {
4115 for (i
= 0; value
[i
] != NULL
; i
++)
4119 value_copy
= calloc (len
+ 1, sizeof (char *));
4120 if (value_copy
== NULL
) {
4127 for (i
= 0; i
< len
; i
++) {
4128 value_copy
[i
] = strdup (value
[i
]);
4129 if (value_copy
[i
] == NULL
) {
4130 for (j
= 0; j
< i
; j
++) {
4131 free (value_copy
[j
]);
4140 value_copy
[i
] = NULL
;
4142 elem
->change_type
= LIBHAL_PROPERTY_TYPE_STRLIST
;
4143 elem
->value
.val_strlist
= value_copy
;
4145 libhal_changeset_append (changeset
, elem
);
4147 return elem
!= NULL
;
4151 * libhal_device_commit_changeset:
4152 * @ctx: the context for the connection to hald
4153 * @changeset: the changeset to commit
4154 * @error: pointer to an initialized dbus error object for returning errors or NULL
4156 * Commit a changeset to the daemon.
4158 * Returns: True if the changeset was committed on the daemon side
4161 libhal_device_commit_changeset (LibHalContext
*ctx
, LibHalChangeSet
*changeset
, DBusError
*error
)
4163 LibHalChangeSetElement
*elem
;
4164 DBusMessage
*message
;
4167 DBusMessageIter iter
;
4168 DBusMessageIter sub
;
4169 DBusMessageIter sub2
;
4170 DBusMessageIter sub3
;
4171 DBusMessageIter sub4
;
4174 LIBHAL_CHECK_LIBHALCONTEXT(ctx
, FALSE
);
4175 LIBHAL_CHECK_UDI_VALID(changeset
->udi
, FALSE
);
4177 if (changeset
->head
== NULL
) {
4181 message
= dbus_message_new_method_call ("org.freedesktop.Hal", changeset
->udi
,
4182 "org.freedesktop.Hal.Device",
4183 "SetMultipleProperties");
4185 if (message
== NULL
) {
4186 fprintf (stderr
, "%s %d : Couldn't allocate D-BUS message\n", __FILE__
, __LINE__
);
4190 dbus_message_iter_init_append (message
, &iter
);
4192 dbus_message_iter_open_container (&iter
,
4194 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
4195 DBUS_TYPE_STRING_AS_STRING
4196 DBUS_TYPE_VARIANT_AS_STRING
4197 DBUS_DICT_ENTRY_END_CHAR_AS_STRING
,
4200 for (elem
= changeset
->head
; elem
!= NULL
; elem
= elem
->next
) {
4201 dbus_message_iter_open_container (&sub
,
4202 DBUS_TYPE_DICT_ENTRY
,
4205 dbus_message_iter_append_basic (&sub2
, DBUS_TYPE_STRING
, &(elem
->key
));
4207 switch (elem
->change_type
) {
4208 case LIBHAL_PROPERTY_TYPE_STRING
:
4209 dbus_message_iter_open_container (&sub2
, DBUS_TYPE_VARIANT
, DBUS_TYPE_STRING_AS_STRING
, &sub3
);
4210 dbus_message_iter_append_basic (&sub3
, DBUS_TYPE_STRING
, &(elem
->value
.val_str
));
4211 dbus_message_iter_close_container (&sub2
, &sub3
);
4213 case LIBHAL_PROPERTY_TYPE_STRLIST
:
4214 dbus_message_iter_open_container (&sub2
, DBUS_TYPE_VARIANT
,
4215 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING
, &sub3
);
4216 dbus_message_iter_open_container (&sub3
, DBUS_TYPE_ARRAY
,
4217 DBUS_TYPE_STRING_AS_STRING
, &sub4
);
4218 for (i
= 0; elem
->value
.val_strlist
[i
] != NULL
; i
++) {
4219 dbus_message_iter_append_basic (&sub4
, DBUS_TYPE_STRING
,
4220 &(elem
->value
.val_strlist
[i
]));
4222 dbus_message_iter_close_container (&sub3
, &sub4
);
4223 dbus_message_iter_close_container (&sub2
, &sub3
);
4225 case LIBHAL_PROPERTY_TYPE_INT32
:
4226 dbus_message_iter_open_container (&sub2
, DBUS_TYPE_VARIANT
, DBUS_TYPE_INT32_AS_STRING
, &sub3
);
4227 dbus_message_iter_append_basic (&sub3
, DBUS_TYPE_INT32
, &(elem
->value
.val_int
));
4228 dbus_message_iter_close_container (&sub2
, &sub3
);
4230 case LIBHAL_PROPERTY_TYPE_UINT64
:
4231 dbus_message_iter_open_container (&sub2
, DBUS_TYPE_VARIANT
, DBUS_TYPE_UINT64_AS_STRING
, &sub3
);
4232 dbus_message_iter_append_basic (&sub3
, DBUS_TYPE_UINT64
, &(elem
->value
.val_uint64
));
4233 dbus_message_iter_close_container (&sub2
, &sub3
);
4235 case LIBHAL_PROPERTY_TYPE_DOUBLE
:
4236 dbus_message_iter_open_container (&sub2
, DBUS_TYPE_VARIANT
, DBUS_TYPE_DOUBLE_AS_STRING
, &sub3
);
4237 dbus_message_iter_append_basic (&sub3
, DBUS_TYPE_DOUBLE
, &(elem
->value
.val_double
));
4238 dbus_message_iter_close_container (&sub2
, &sub3
);
4240 case LIBHAL_PROPERTY_TYPE_BOOLEAN
:
4241 dbus_message_iter_open_container (&sub2
, DBUS_TYPE_VARIANT
, DBUS_TYPE_BOOLEAN_AS_STRING
,&sub3
);
4242 dbus_message_iter_append_basic (&sub3
, DBUS_TYPE_BOOLEAN
, &(elem
->value
.val_bool
));
4243 dbus_message_iter_close_container (&sub2
, &sub3
);
4246 fprintf (stderr
, "%s %d : unknown change_type %d\n", __FILE__
, __LINE__
, elem
->change_type
);
4249 dbus_message_iter_close_container (&sub
, &sub2
);
4252 dbus_message_iter_close_container (&iter
, &sub
);
4255 dbus_error_init (&_error
);
4256 reply
= dbus_connection_send_with_reply_and_block (ctx
->connection
,
4260 dbus_message_unref (message
);
4262 dbus_move_error (&_error
, error
);
4263 if (error
!= NULL
&& dbus_error_is_set (error
)) {
4266 __FILE__
, __LINE__
, error
->message
);
4270 if (reply
== NULL
) {
4274 dbus_message_unref (reply
);
4279 * libhal_device_free_changeset:
4280 * @changeset: the changeset to free
4285 libhal_device_free_changeset (LibHalChangeSet
*changeset
)
4287 LibHalChangeSetElement
*elem
;
4288 LibHalChangeSetElement
*elem2
;
4290 for (elem
= changeset
->head
; elem
!= NULL
; elem
= elem2
) {
4293 switch (elem
->change_type
) {
4294 case LIBHAL_PROPERTY_TYPE_STRING
:
4295 free (elem
->value
.val_str
);
4297 case LIBHAL_PROPERTY_TYPE_STRLIST
:
4298 libhal_free_string_array (elem
->value
.val_strlist
);
4300 /* explicit fallthrough */
4301 case LIBHAL_PROPERTY_TYPE_INT32
:
4302 case LIBHAL_PROPERTY_TYPE_UINT64
:
4303 case LIBHAL_PROPERTY_TYPE_DOUBLE
:
4304 case LIBHAL_PROPERTY_TYPE_BOOLEAN
:
4307 fprintf (stderr
, "%s %d : unknown change_type %d\n", __FILE__
, __LINE__
, elem
->change_type
);
4314 free (changeset
->udi
);