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