1*18c2aff7Sartem /*************************************************************************** 2*18c2aff7Sartem * CVSID: $Id$ 3*18c2aff7Sartem * 4*18c2aff7Sartem * device.c : HalDevice methods 5*18c2aff7Sartem * 6*18c2aff7Sartem * Copyright (C) 2003 David Zeuthen, <david@fubar.dk> 7*18c2aff7Sartem * Copyright (C) 2004 Novell, Inc. 8*18c2aff7Sartem * 9*18c2aff7Sartem * Licensed under the Academic Free License version 2.1 10*18c2aff7Sartem * 11*18c2aff7Sartem * This program is free software; you can redistribute it and/or modify 12*18c2aff7Sartem * it under the terms of the GNU General Public License as published by 13*18c2aff7Sartem * the Free Software Foundation; either version 2 of the License, or 14*18c2aff7Sartem * (at your option) any later version. 15*18c2aff7Sartem * 16*18c2aff7Sartem * This program is distributed in the hope that it will be useful, 17*18c2aff7Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of 18*18c2aff7Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19*18c2aff7Sartem * GNU General Public License for more details. 20*18c2aff7Sartem * 21*18c2aff7Sartem * You should have received a copy of the GNU General Public License 22*18c2aff7Sartem * along with this program; if not, write to the Free Software 23*18c2aff7Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24*18c2aff7Sartem * 25*18c2aff7Sartem **************************************************************************/ 26*18c2aff7Sartem 27*18c2aff7Sartem #ifdef HAVE_CONFIG_H 28*18c2aff7Sartem # include <config.h> 29*18c2aff7Sartem #endif 30*18c2aff7Sartem 31*18c2aff7Sartem #include <stdio.h> 32*18c2aff7Sartem #include <string.h> 33*18c2aff7Sartem 34*18c2aff7Sartem #include "hald.h" 35*18c2aff7Sartem #include "device.h" 36*18c2aff7Sartem #include "hald_marshal.h" 37*18c2aff7Sartem #include "logger.h" 38*18c2aff7Sartem #include "hald_runner.h" 39*18c2aff7Sartem 40*18c2aff7Sartem static GObjectClass *parent_class; 41*18c2aff7Sartem 42*18c2aff7Sartem enum { 43*18c2aff7Sartem PROPERTY_CHANGED, 44*18c2aff7Sartem CAPABILITY_ADDED, 45*18c2aff7Sartem CALLOUTS_FINISHED, 46*18c2aff7Sartem CANCELLED, 47*18c2aff7Sartem LAST_SIGNAL 48*18c2aff7Sartem }; 49*18c2aff7Sartem 50*18c2aff7Sartem static guint signals[LAST_SIGNAL] = { 0 }; 51*18c2aff7Sartem 52*18c2aff7Sartem #ifdef HALD_MEMLEAK_DBG 53*18c2aff7Sartem int dbg_hal_device_object_delta = 0; 54*18c2aff7Sartem #endif 55*18c2aff7Sartem 56*18c2aff7Sartem static void 57*18c2aff7Sartem hal_device_finalize (GObject *obj) 58*18c2aff7Sartem { 59*18c2aff7Sartem HalDevice *device = HAL_DEVICE (obj); 60*18c2aff7Sartem 61*18c2aff7Sartem runner_device_finalized (device); 62*18c2aff7Sartem 63*18c2aff7Sartem #ifdef HALD_MEMLEAK_DBG 64*18c2aff7Sartem dbg_hal_device_object_delta--; 65*18c2aff7Sartem printf ("************* in finalize for udi=%s\n", device->udi); 66*18c2aff7Sartem #endif 67*18c2aff7Sartem 68*18c2aff7Sartem 69*18c2aff7Sartem g_slist_foreach (device->properties, (GFunc) hal_property_free, NULL); 70*18c2aff7Sartem 71*18c2aff7Sartem g_free (device->udi); 72*18c2aff7Sartem 73*18c2aff7Sartem if (parent_class->finalize) 74*18c2aff7Sartem parent_class->finalize (obj); 75*18c2aff7Sartem 76*18c2aff7Sartem } 77*18c2aff7Sartem 78*18c2aff7Sartem static void 79*18c2aff7Sartem hal_device_class_init (HalDeviceClass *klass) 80*18c2aff7Sartem { 81*18c2aff7Sartem GObjectClass *obj_class = (GObjectClass *) klass; 82*18c2aff7Sartem 83*18c2aff7Sartem parent_class = g_type_class_peek_parent (klass); 84*18c2aff7Sartem 85*18c2aff7Sartem obj_class->finalize = hal_device_finalize; 86*18c2aff7Sartem 87*18c2aff7Sartem signals[PROPERTY_CHANGED] = 88*18c2aff7Sartem g_signal_new ("property_changed", 89*18c2aff7Sartem G_TYPE_FROM_CLASS (klass), 90*18c2aff7Sartem G_SIGNAL_RUN_LAST, 91*18c2aff7Sartem G_STRUCT_OFFSET (HalDeviceClass, 92*18c2aff7Sartem property_changed), 93*18c2aff7Sartem NULL, NULL, 94*18c2aff7Sartem hald_marshal_VOID__STRING_BOOL_BOOL, 95*18c2aff7Sartem G_TYPE_NONE, 3, 96*18c2aff7Sartem G_TYPE_STRING, 97*18c2aff7Sartem G_TYPE_BOOLEAN, 98*18c2aff7Sartem G_TYPE_BOOLEAN); 99*18c2aff7Sartem 100*18c2aff7Sartem signals[CAPABILITY_ADDED] = 101*18c2aff7Sartem g_signal_new ("capability_added", 102*18c2aff7Sartem G_TYPE_FROM_CLASS (klass), 103*18c2aff7Sartem G_SIGNAL_RUN_LAST, 104*18c2aff7Sartem G_STRUCT_OFFSET (HalDeviceClass, 105*18c2aff7Sartem capability_added), 106*18c2aff7Sartem NULL, NULL, 107*18c2aff7Sartem hald_marshal_VOID__STRING, 108*18c2aff7Sartem G_TYPE_NONE, 1, 109*18c2aff7Sartem G_TYPE_STRING); 110*18c2aff7Sartem 111*18c2aff7Sartem signals[CALLOUTS_FINISHED] = 112*18c2aff7Sartem g_signal_new ("callouts_finished", 113*18c2aff7Sartem G_TYPE_FROM_CLASS (klass), 114*18c2aff7Sartem G_SIGNAL_RUN_LAST, 115*18c2aff7Sartem G_STRUCT_OFFSET (HalDeviceClass, 116*18c2aff7Sartem callouts_finished), 117*18c2aff7Sartem NULL, NULL, 118*18c2aff7Sartem hald_marshal_VOID__VOID, 119*18c2aff7Sartem G_TYPE_NONE, 0); 120*18c2aff7Sartem 121*18c2aff7Sartem signals[CANCELLED] = 122*18c2aff7Sartem g_signal_new ("cancelled", 123*18c2aff7Sartem G_TYPE_FROM_CLASS (klass), 124*18c2aff7Sartem G_SIGNAL_RUN_LAST, 125*18c2aff7Sartem G_STRUCT_OFFSET (HalDeviceClass, 126*18c2aff7Sartem cancelled), 127*18c2aff7Sartem NULL, NULL, 128*18c2aff7Sartem hald_marshal_VOID__VOID, 129*18c2aff7Sartem G_TYPE_NONE, 0); 130*18c2aff7Sartem } 131*18c2aff7Sartem 132*18c2aff7Sartem static void 133*18c2aff7Sartem hal_device_init (HalDevice *device) 134*18c2aff7Sartem { 135*18c2aff7Sartem static int temp_device_counter = 0; 136*18c2aff7Sartem 137*18c2aff7Sartem device->udi = g_strdup_printf ("/org/freedesktop/Hal/devices/temp/%d", 138*18c2aff7Sartem temp_device_counter++); 139*18c2aff7Sartem device->num_addons = 0; 140*18c2aff7Sartem device->num_addons_ready = 0; 141*18c2aff7Sartem } 142*18c2aff7Sartem 143*18c2aff7Sartem GType 144*18c2aff7Sartem hal_device_get_type (void) 145*18c2aff7Sartem { 146*18c2aff7Sartem static GType type = 0; 147*18c2aff7Sartem 148*18c2aff7Sartem if (!type) { 149*18c2aff7Sartem static GTypeInfo type_info = { 150*18c2aff7Sartem sizeof (HalDeviceClass), 151*18c2aff7Sartem NULL, NULL, 152*18c2aff7Sartem (GClassInitFunc) hal_device_class_init, 153*18c2aff7Sartem NULL, NULL, 154*18c2aff7Sartem sizeof (HalDevice), 155*18c2aff7Sartem 0, 156*18c2aff7Sartem (GInstanceInitFunc) hal_device_init, 157*18c2aff7Sartem NULL 158*18c2aff7Sartem }; 159*18c2aff7Sartem 160*18c2aff7Sartem type = g_type_register_static (G_TYPE_OBJECT, 161*18c2aff7Sartem "HalDevice", 162*18c2aff7Sartem &type_info, 163*18c2aff7Sartem 0); 164*18c2aff7Sartem } 165*18c2aff7Sartem 166*18c2aff7Sartem return type; 167*18c2aff7Sartem } 168*18c2aff7Sartem 169*18c2aff7Sartem 170*18c2aff7Sartem HalDevice * 171*18c2aff7Sartem hal_device_new (void) 172*18c2aff7Sartem { 173*18c2aff7Sartem HalDevice *device; 174*18c2aff7Sartem 175*18c2aff7Sartem device = g_object_new (HAL_TYPE_DEVICE, NULL, NULL); 176*18c2aff7Sartem 177*18c2aff7Sartem #ifdef HALD_MEMLEAK_DBG 178*18c2aff7Sartem dbg_hal_device_object_delta++; 179*18c2aff7Sartem #endif 180*18c2aff7Sartem return device; 181*18c2aff7Sartem } 182*18c2aff7Sartem 183*18c2aff7Sartem /** Merge all properties from source where the key starts with 184*18c2aff7Sartem * source_namespace and put them onto target replacing source_namespace 185*18c2aff7Sartem * with target_namespace 186*18c2aff7Sartem * 187*18c2aff7Sartem * @param target Device to put properties onto 188*18c2aff7Sartem * @param source Device to retrieve properties from 189*18c2aff7Sartem * @param target_namespace Replace source namespace with this namespace 190*18c2aff7Sartem * @param source_namespace Source namespace that property keys must match 191*18c2aff7Sartem */ 192*18c2aff7Sartem void 193*18c2aff7Sartem hal_device_merge_with_rewrite (HalDevice *target, 194*18c2aff7Sartem HalDevice *source, 195*18c2aff7Sartem const char *target_namespace, 196*18c2aff7Sartem const char *source_namespace) 197*18c2aff7Sartem { 198*18c2aff7Sartem GSList *iter; 199*18c2aff7Sartem size_t source_ns_len; 200*18c2aff7Sartem 201*18c2aff7Sartem source_ns_len = strlen (source_namespace); 202*18c2aff7Sartem 203*18c2aff7Sartem /* doesn't handle info.capabilities */ 204*18c2aff7Sartem 205*18c2aff7Sartem /* device_property_atomic_update_begin (); */ 206*18c2aff7Sartem 207*18c2aff7Sartem for (iter = source->properties; iter != NULL; iter = iter->next) { 208*18c2aff7Sartem HalProperty *p = iter->data; 209*18c2aff7Sartem int type; 210*18c2aff7Sartem const char *key; 211*18c2aff7Sartem int target_type; 212*18c2aff7Sartem gchar *target_key; 213*18c2aff7Sartem 214*18c2aff7Sartem key = hal_property_get_key (p); 215*18c2aff7Sartem 216*18c2aff7Sartem /* only care about properties that match source namespace */ 217*18c2aff7Sartem if (strncmp(key, source_namespace, source_ns_len) != 0) 218*18c2aff7Sartem continue; 219*18c2aff7Sartem 220*18c2aff7Sartem target_key = g_strdup_printf("%s%s", target_namespace, 221*18c2aff7Sartem key+source_ns_len); 222*18c2aff7Sartem 223*18c2aff7Sartem type = hal_property_get_type (p); 224*18c2aff7Sartem 225*18c2aff7Sartem /* only remove target if it exists with a different type */ 226*18c2aff7Sartem target_type = hal_device_property_get_type (target, key); 227*18c2aff7Sartem if (target_type != HAL_PROPERTY_TYPE_INVALID && target_type != type) 228*18c2aff7Sartem hal_device_property_remove (target, key); 229*18c2aff7Sartem 230*18c2aff7Sartem switch (type) { 231*18c2aff7Sartem 232*18c2aff7Sartem case HAL_PROPERTY_TYPE_STRING: 233*18c2aff7Sartem hal_device_property_set_string ( 234*18c2aff7Sartem target, target_key, 235*18c2aff7Sartem hal_property_get_string (p)); 236*18c2aff7Sartem break; 237*18c2aff7Sartem 238*18c2aff7Sartem case HAL_PROPERTY_TYPE_INT32: 239*18c2aff7Sartem hal_device_property_set_int ( 240*18c2aff7Sartem target, target_key, 241*18c2aff7Sartem hal_property_get_int (p)); 242*18c2aff7Sartem break; 243*18c2aff7Sartem 244*18c2aff7Sartem case HAL_PROPERTY_TYPE_UINT64: 245*18c2aff7Sartem hal_device_property_set_uint64 ( 246*18c2aff7Sartem target, target_key, 247*18c2aff7Sartem hal_property_get_uint64 (p)); 248*18c2aff7Sartem break; 249*18c2aff7Sartem 250*18c2aff7Sartem case HAL_PROPERTY_TYPE_BOOLEAN: 251*18c2aff7Sartem hal_device_property_set_bool ( 252*18c2aff7Sartem target, target_key, 253*18c2aff7Sartem hal_property_get_bool (p)); 254*18c2aff7Sartem break; 255*18c2aff7Sartem 256*18c2aff7Sartem case HAL_PROPERTY_TYPE_DOUBLE: 257*18c2aff7Sartem hal_device_property_set_double ( 258*18c2aff7Sartem target, target_key, 259*18c2aff7Sartem hal_property_get_double (p)); 260*18c2aff7Sartem break; 261*18c2aff7Sartem 262*18c2aff7Sartem default: 263*18c2aff7Sartem HAL_WARNING (("Unknown property type %d", type)); 264*18c2aff7Sartem break; 265*18c2aff7Sartem } 266*18c2aff7Sartem 267*18c2aff7Sartem g_free (target_key); 268*18c2aff7Sartem } 269*18c2aff7Sartem 270*18c2aff7Sartem /* device_property_atomic_update_end (); */ 271*18c2aff7Sartem 272*18c2aff7Sartem } 273*18c2aff7Sartem 274*18c2aff7Sartem void 275*18c2aff7Sartem hal_device_merge (HalDevice *target, HalDevice *source) 276*18c2aff7Sartem { 277*18c2aff7Sartem GSList *iter; 278*18c2aff7Sartem GSList *caps; 279*18c2aff7Sartem 280*18c2aff7Sartem /* device_property_atomic_update_begin (); */ 281*18c2aff7Sartem 282*18c2aff7Sartem for (iter = source->properties; iter != NULL; iter = iter->next) { 283*18c2aff7Sartem HalProperty *p = iter->data; 284*18c2aff7Sartem int type; 285*18c2aff7Sartem const char *key; 286*18c2aff7Sartem int target_type; 287*18c2aff7Sartem 288*18c2aff7Sartem key = hal_property_get_key (p); 289*18c2aff7Sartem type = hal_property_get_type (p); 290*18c2aff7Sartem 291*18c2aff7Sartem /* handle info.capabilities in a special way */ 292*18c2aff7Sartem if (strcmp (key, "info.capabilities") == 0) 293*18c2aff7Sartem continue; 294*18c2aff7Sartem 295*18c2aff7Sartem /* only remove target if it exists with a different type */ 296*18c2aff7Sartem target_type = hal_device_property_get_type (target, key); 297*18c2aff7Sartem if (target_type != HAL_PROPERTY_TYPE_INVALID && target_type != type) 298*18c2aff7Sartem hal_device_property_remove (target, key); 299*18c2aff7Sartem 300*18c2aff7Sartem switch (type) { 301*18c2aff7Sartem 302*18c2aff7Sartem case HAL_PROPERTY_TYPE_STRING: 303*18c2aff7Sartem hal_device_property_set_string ( 304*18c2aff7Sartem target, key, 305*18c2aff7Sartem hal_property_get_string (p)); 306*18c2aff7Sartem break; 307*18c2aff7Sartem 308*18c2aff7Sartem case HAL_PROPERTY_TYPE_INT32: 309*18c2aff7Sartem hal_device_property_set_int ( 310*18c2aff7Sartem target, key, 311*18c2aff7Sartem hal_property_get_int (p)); 312*18c2aff7Sartem break; 313*18c2aff7Sartem 314*18c2aff7Sartem case HAL_PROPERTY_TYPE_UINT64: 315*18c2aff7Sartem hal_device_property_set_uint64 ( 316*18c2aff7Sartem target, key, 317*18c2aff7Sartem hal_property_get_uint64 (p)); 318*18c2aff7Sartem break; 319*18c2aff7Sartem 320*18c2aff7Sartem case HAL_PROPERTY_TYPE_BOOLEAN: 321*18c2aff7Sartem hal_device_property_set_bool ( 322*18c2aff7Sartem target, key, 323*18c2aff7Sartem hal_property_get_bool (p)); 324*18c2aff7Sartem break; 325*18c2aff7Sartem 326*18c2aff7Sartem case HAL_PROPERTY_TYPE_DOUBLE: 327*18c2aff7Sartem hal_device_property_set_double ( 328*18c2aff7Sartem target, key, 329*18c2aff7Sartem hal_property_get_double (p)); 330*18c2aff7Sartem break; 331*18c2aff7Sartem 332*18c2aff7Sartem default: 333*18c2aff7Sartem HAL_WARNING (("Unknown property type %d", type)); 334*18c2aff7Sartem break; 335*18c2aff7Sartem } 336*18c2aff7Sartem } 337*18c2aff7Sartem 338*18c2aff7Sartem /* device_property_atomic_update_end (); */ 339*18c2aff7Sartem 340*18c2aff7Sartem caps = hal_device_property_get_strlist (source, "info.capabilities"); 341*18c2aff7Sartem for (iter = caps; iter != NULL; iter = iter->next) { 342*18c2aff7Sartem if (!hal_device_has_capability (target, iter->data)) 343*18c2aff7Sartem hal_device_add_capability (target, iter->data); 344*18c2aff7Sartem } 345*18c2aff7Sartem } 346*18c2aff7Sartem 347*18c2aff7Sartem gboolean 348*18c2aff7Sartem hal_device_matches (HalDevice *device1, HalDevice *device2, 349*18c2aff7Sartem const char *namespace) 350*18c2aff7Sartem { 351*18c2aff7Sartem int len; 352*18c2aff7Sartem GSList *iter; 353*18c2aff7Sartem 354*18c2aff7Sartem len = strlen (namespace); 355*18c2aff7Sartem 356*18c2aff7Sartem for (iter = device1->properties; iter != NULL; iter = iter->next) { 357*18c2aff7Sartem HalProperty *p; 358*18c2aff7Sartem const char *key; 359*18c2aff7Sartem int type; 360*18c2aff7Sartem 361*18c2aff7Sartem p = (HalProperty *) iter->data; 362*18c2aff7Sartem key = hal_property_get_key (p); 363*18c2aff7Sartem type = hal_property_get_type (p); 364*18c2aff7Sartem 365*18c2aff7Sartem if (strncmp (key, namespace, len) != 0) 366*18c2aff7Sartem continue; 367*18c2aff7Sartem 368*18c2aff7Sartem if (!hal_device_has_property (device2, key)) 369*18c2aff7Sartem return FALSE; 370*18c2aff7Sartem 371*18c2aff7Sartem switch (type) { 372*18c2aff7Sartem 373*18c2aff7Sartem case HAL_PROPERTY_TYPE_STRING: 374*18c2aff7Sartem if (strcmp (hal_property_get_string (p), 375*18c2aff7Sartem hal_device_property_get_string (device2, 376*18c2aff7Sartem key)) != 0) 377*18c2aff7Sartem return FALSE; 378*18c2aff7Sartem break; 379*18c2aff7Sartem 380*18c2aff7Sartem case HAL_PROPERTY_TYPE_INT32: 381*18c2aff7Sartem if (hal_property_get_int (p) != 382*18c2aff7Sartem hal_device_property_get_int (device2, key)) 383*18c2aff7Sartem return FALSE; 384*18c2aff7Sartem break; 385*18c2aff7Sartem 386*18c2aff7Sartem case HAL_PROPERTY_TYPE_UINT64: 387*18c2aff7Sartem if (hal_property_get_uint64 (p) != 388*18c2aff7Sartem hal_device_property_get_uint64 (device2, key)) 389*18c2aff7Sartem return FALSE; 390*18c2aff7Sartem break; 391*18c2aff7Sartem 392*18c2aff7Sartem case HAL_PROPERTY_TYPE_BOOLEAN: 393*18c2aff7Sartem if (hal_property_get_bool (p) != 394*18c2aff7Sartem hal_device_property_get_bool (device2, key)) 395*18c2aff7Sartem return FALSE; 396*18c2aff7Sartem break; 397*18c2aff7Sartem 398*18c2aff7Sartem case HAL_PROPERTY_TYPE_DOUBLE: 399*18c2aff7Sartem if (hal_property_get_double (p) != 400*18c2aff7Sartem hal_device_property_get_double (device2, key)) 401*18c2aff7Sartem return FALSE; 402*18c2aff7Sartem break; 403*18c2aff7Sartem 404*18c2aff7Sartem default: 405*18c2aff7Sartem HAL_WARNING (("Unknown property type %d", type)); 406*18c2aff7Sartem break; 407*18c2aff7Sartem } 408*18c2aff7Sartem } 409*18c2aff7Sartem 410*18c2aff7Sartem return TRUE; 411*18c2aff7Sartem } 412*18c2aff7Sartem 413*18c2aff7Sartem const char * 414*18c2aff7Sartem hal_device_get_udi (HalDevice *device) 415*18c2aff7Sartem { 416*18c2aff7Sartem return device->udi; 417*18c2aff7Sartem } 418*18c2aff7Sartem 419*18c2aff7Sartem void 420*18c2aff7Sartem hal_device_set_udi (HalDevice *device, const char *udi) 421*18c2aff7Sartem { 422*18c2aff7Sartem if (device->udi != NULL) 423*18c2aff7Sartem g_free (device->udi); 424*18c2aff7Sartem device->udi = g_strdup (udi); 425*18c2aff7Sartem } 426*18c2aff7Sartem 427*18c2aff7Sartem void 428*18c2aff7Sartem hal_device_add_capability (HalDevice *device, const char *capability) 429*18c2aff7Sartem { 430*18c2aff7Sartem if (hal_device_property_strlist_add (device, "info.capabilities", capability)) 431*18c2aff7Sartem g_signal_emit (device, signals[CAPABILITY_ADDED], 0, capability); 432*18c2aff7Sartem } 433*18c2aff7Sartem 434*18c2aff7Sartem gboolean 435*18c2aff7Sartem hal_device_has_capability (HalDevice *device, const char *capability) 436*18c2aff7Sartem { 437*18c2aff7Sartem GSList *caps; 438*18c2aff7Sartem GSList *iter; 439*18c2aff7Sartem gboolean matched = FALSE; 440*18c2aff7Sartem 441*18c2aff7Sartem caps = hal_device_property_get_strlist (device, "info.capabilities"); 442*18c2aff7Sartem 443*18c2aff7Sartem if (caps == NULL) 444*18c2aff7Sartem return FALSE; 445*18c2aff7Sartem 446*18c2aff7Sartem for (iter = caps; iter != NULL; iter = iter->next) { 447*18c2aff7Sartem if (strcmp (iter->data, capability) == 0) { 448*18c2aff7Sartem matched = TRUE; 449*18c2aff7Sartem break; 450*18c2aff7Sartem } 451*18c2aff7Sartem } 452*18c2aff7Sartem 453*18c2aff7Sartem return matched; 454*18c2aff7Sartem } 455*18c2aff7Sartem 456*18c2aff7Sartem gboolean 457*18c2aff7Sartem hal_device_has_property (HalDevice *device, const char *key) 458*18c2aff7Sartem { 459*18c2aff7Sartem g_return_val_if_fail (device != NULL, FALSE); 460*18c2aff7Sartem g_return_val_if_fail (key != NULL, FALSE); 461*18c2aff7Sartem 462*18c2aff7Sartem return hal_device_property_find (device, key) != NULL; 463*18c2aff7Sartem } 464*18c2aff7Sartem 465*18c2aff7Sartem int 466*18c2aff7Sartem hal_device_num_properties (HalDevice *device) 467*18c2aff7Sartem { 468*18c2aff7Sartem g_return_val_if_fail (device != NULL, -1); 469*18c2aff7Sartem 470*18c2aff7Sartem return g_slist_length (device->properties); 471*18c2aff7Sartem } 472*18c2aff7Sartem 473*18c2aff7Sartem HalProperty * 474*18c2aff7Sartem hal_device_property_find (HalDevice *device, const char *key) 475*18c2aff7Sartem { 476*18c2aff7Sartem GSList *iter; 477*18c2aff7Sartem 478*18c2aff7Sartem g_return_val_if_fail (device != NULL, NULL); 479*18c2aff7Sartem g_return_val_if_fail (key != NULL, NULL); 480*18c2aff7Sartem 481*18c2aff7Sartem for (iter = device->properties; iter != NULL; iter = iter->next) { 482*18c2aff7Sartem HalProperty *p = iter->data; 483*18c2aff7Sartem 484*18c2aff7Sartem if (strcmp (hal_property_get_key (p), key) == 0) 485*18c2aff7Sartem return p; 486*18c2aff7Sartem } 487*18c2aff7Sartem 488*18c2aff7Sartem return NULL; 489*18c2aff7Sartem } 490*18c2aff7Sartem 491*18c2aff7Sartem char * 492*18c2aff7Sartem hal_device_property_to_string (HalDevice *device, const char *key) 493*18c2aff7Sartem { 494*18c2aff7Sartem HalProperty *prop; 495*18c2aff7Sartem 496*18c2aff7Sartem prop = hal_device_property_find (device, key); 497*18c2aff7Sartem if (!prop) 498*18c2aff7Sartem return NULL; 499*18c2aff7Sartem 500*18c2aff7Sartem return hal_property_to_string (prop); 501*18c2aff7Sartem } 502*18c2aff7Sartem 503*18c2aff7Sartem void 504*18c2aff7Sartem hal_device_property_foreach (HalDevice *device, 505*18c2aff7Sartem HalDevicePropertyForeachFn callback, 506*18c2aff7Sartem gpointer user_data) 507*18c2aff7Sartem { 508*18c2aff7Sartem GSList *iter; 509*18c2aff7Sartem 510*18c2aff7Sartem g_return_if_fail (device != NULL); 511*18c2aff7Sartem g_return_if_fail (callback != NULL); 512*18c2aff7Sartem 513*18c2aff7Sartem for (iter = device->properties; iter != NULL; iter = iter->next) { 514*18c2aff7Sartem HalProperty *p = iter->data; 515*18c2aff7Sartem gboolean cont; 516*18c2aff7Sartem 517*18c2aff7Sartem cont = callback (device, p, user_data); 518*18c2aff7Sartem 519*18c2aff7Sartem if (cont == FALSE) 520*18c2aff7Sartem return; 521*18c2aff7Sartem } 522*18c2aff7Sartem } 523*18c2aff7Sartem 524*18c2aff7Sartem int 525*18c2aff7Sartem hal_device_property_get_type (HalDevice *device, const char *key) 526*18c2aff7Sartem { 527*18c2aff7Sartem HalProperty *prop; 528*18c2aff7Sartem 529*18c2aff7Sartem g_return_val_if_fail (device != NULL, HAL_PROPERTY_TYPE_INVALID); 530*18c2aff7Sartem g_return_val_if_fail (key != NULL, HAL_PROPERTY_TYPE_INVALID); 531*18c2aff7Sartem 532*18c2aff7Sartem prop = hal_device_property_find (device, key); 533*18c2aff7Sartem 534*18c2aff7Sartem if (prop != NULL) 535*18c2aff7Sartem return hal_property_get_type (prop); 536*18c2aff7Sartem else 537*18c2aff7Sartem return HAL_PROPERTY_TYPE_INVALID; 538*18c2aff7Sartem } 539*18c2aff7Sartem 540*18c2aff7Sartem const char * 541*18c2aff7Sartem hal_device_property_get_string (HalDevice *device, const char *key) 542*18c2aff7Sartem { 543*18c2aff7Sartem HalProperty *prop; 544*18c2aff7Sartem 545*18c2aff7Sartem g_return_val_if_fail (device != NULL, NULL); 546*18c2aff7Sartem g_return_val_if_fail (key != NULL, NULL); 547*18c2aff7Sartem 548*18c2aff7Sartem prop = hal_device_property_find (device, key); 549*18c2aff7Sartem 550*18c2aff7Sartem if (prop != NULL) 551*18c2aff7Sartem return hal_property_get_string (prop); 552*18c2aff7Sartem else 553*18c2aff7Sartem return NULL; 554*18c2aff7Sartem } 555*18c2aff7Sartem 556*18c2aff7Sartem const char * 557*18c2aff7Sartem hal_device_property_get_as_string (HalDevice *device, const char *key, char *buf, size_t bufsize) 558*18c2aff7Sartem { 559*18c2aff7Sartem HalProperty *prop; 560*18c2aff7Sartem 561*18c2aff7Sartem g_return_val_if_fail (device != NULL, NULL); 562*18c2aff7Sartem g_return_val_if_fail (key != NULL, NULL); 563*18c2aff7Sartem g_return_val_if_fail (buf != NULL, NULL); 564*18c2aff7Sartem 565*18c2aff7Sartem prop = hal_device_property_find (device, key); 566*18c2aff7Sartem 567*18c2aff7Sartem if (prop != NULL) { 568*18c2aff7Sartem switch (hal_property_get_type (prop)) { 569*18c2aff7Sartem case HAL_PROPERTY_TYPE_STRING: 570*18c2aff7Sartem strncpy (buf, hal_property_get_string (prop), bufsize); 571*18c2aff7Sartem break; 572*18c2aff7Sartem case HAL_PROPERTY_TYPE_INT32: 573*18c2aff7Sartem snprintf (buf, bufsize, "%d", hal_property_get_int (prop)); 574*18c2aff7Sartem break; 575*18c2aff7Sartem case HAL_PROPERTY_TYPE_UINT64: 576*18c2aff7Sartem snprintf (buf, bufsize, "%llu", (long long unsigned int) hal_property_get_uint64 (prop)); 577*18c2aff7Sartem break; 578*18c2aff7Sartem case HAL_PROPERTY_TYPE_DOUBLE: 579*18c2aff7Sartem snprintf (buf, bufsize, "%f", hal_property_get_double (prop)); 580*18c2aff7Sartem break; 581*18c2aff7Sartem case HAL_PROPERTY_TYPE_BOOLEAN: 582*18c2aff7Sartem strncpy (buf, hal_property_get_bool (prop) ? "true" : "false", bufsize); 583*18c2aff7Sartem break; 584*18c2aff7Sartem 585*18c2aff7Sartem case HAL_PROPERTY_TYPE_STRLIST: 586*18c2aff7Sartem /* print out as "\tval1\tval2\val3\t" */ 587*18c2aff7Sartem { 588*18c2aff7Sartem GSList *iter; 589*18c2aff7Sartem guint i; 590*18c2aff7Sartem 591*18c2aff7Sartem if (bufsize > 0) 592*18c2aff7Sartem buf[0] = '\t'; 593*18c2aff7Sartem i = 1; 594*18c2aff7Sartem for (iter = hal_property_get_strlist (prop); 595*18c2aff7Sartem iter != NULL && i < bufsize; 596*18c2aff7Sartem iter = g_slist_next (iter)) { 597*18c2aff7Sartem guint len; 598*18c2aff7Sartem const char *str; 599*18c2aff7Sartem 600*18c2aff7Sartem str = (const char *) iter->data; 601*18c2aff7Sartem len = strlen (str); 602*18c2aff7Sartem strncpy (buf + i, str, bufsize - i); 603*18c2aff7Sartem i += len; 604*18c2aff7Sartem 605*18c2aff7Sartem if (i < bufsize) { 606*18c2aff7Sartem buf[i] = '\t'; 607*18c2aff7Sartem i++; 608*18c2aff7Sartem } 609*18c2aff7Sartem } 610*18c2aff7Sartem } 611*18c2aff7Sartem break; 612*18c2aff7Sartem } 613*18c2aff7Sartem return buf; 614*18c2aff7Sartem } else { 615*18c2aff7Sartem buf[0] = '\0'; 616*18c2aff7Sartem return NULL; 617*18c2aff7Sartem } 618*18c2aff7Sartem } 619*18c2aff7Sartem 620*18c2aff7Sartem dbus_int32_t 621*18c2aff7Sartem hal_device_property_get_int (HalDevice *device, const char *key) 622*18c2aff7Sartem { 623*18c2aff7Sartem HalProperty *prop; 624*18c2aff7Sartem 625*18c2aff7Sartem g_return_val_if_fail (device != NULL, -1); 626*18c2aff7Sartem g_return_val_if_fail (key != NULL, -1); 627*18c2aff7Sartem 628*18c2aff7Sartem prop = hal_device_property_find (device, key); 629*18c2aff7Sartem 630*18c2aff7Sartem if (prop != NULL) 631*18c2aff7Sartem return hal_property_get_int (prop); 632*18c2aff7Sartem else 633*18c2aff7Sartem return -1; 634*18c2aff7Sartem } 635*18c2aff7Sartem 636*18c2aff7Sartem dbus_uint64_t 637*18c2aff7Sartem hal_device_property_get_uint64 (HalDevice *device, const char *key) 638*18c2aff7Sartem { 639*18c2aff7Sartem HalProperty *prop; 640*18c2aff7Sartem 641*18c2aff7Sartem g_return_val_if_fail (device != NULL, -1); 642*18c2aff7Sartem g_return_val_if_fail (key != NULL, -1); 643*18c2aff7Sartem 644*18c2aff7Sartem prop = hal_device_property_find (device, key); 645*18c2aff7Sartem 646*18c2aff7Sartem if (prop != NULL) 647*18c2aff7Sartem return hal_property_get_uint64 (prop); 648*18c2aff7Sartem else 649*18c2aff7Sartem return -1; 650*18c2aff7Sartem } 651*18c2aff7Sartem 652*18c2aff7Sartem dbus_bool_t 653*18c2aff7Sartem hal_device_property_get_bool (HalDevice *device, const char *key) 654*18c2aff7Sartem { 655*18c2aff7Sartem HalProperty *prop; 656*18c2aff7Sartem 657*18c2aff7Sartem g_return_val_if_fail (device != NULL, FALSE); 658*18c2aff7Sartem g_return_val_if_fail (key != NULL, FALSE); 659*18c2aff7Sartem 660*18c2aff7Sartem prop = hal_device_property_find (device, key); 661*18c2aff7Sartem 662*18c2aff7Sartem if (prop != NULL) 663*18c2aff7Sartem return hal_property_get_bool (prop); 664*18c2aff7Sartem else 665*18c2aff7Sartem return FALSE; 666*18c2aff7Sartem } 667*18c2aff7Sartem 668*18c2aff7Sartem double 669*18c2aff7Sartem hal_device_property_get_double (HalDevice *device, const char *key) 670*18c2aff7Sartem { 671*18c2aff7Sartem HalProperty *prop; 672*18c2aff7Sartem 673*18c2aff7Sartem g_return_val_if_fail (device != NULL, -1.0); 674*18c2aff7Sartem g_return_val_if_fail (key != NULL, -1.0); 675*18c2aff7Sartem 676*18c2aff7Sartem prop = hal_device_property_find (device, key); 677*18c2aff7Sartem 678*18c2aff7Sartem if (prop != NULL) 679*18c2aff7Sartem return hal_property_get_double (prop); 680*18c2aff7Sartem else 681*18c2aff7Sartem return -1.0; 682*18c2aff7Sartem } 683*18c2aff7Sartem 684*18c2aff7Sartem gboolean 685*18c2aff7Sartem hal_device_property_set_string (HalDevice *device, const char *key, 686*18c2aff7Sartem const char *value) 687*18c2aff7Sartem { 688*18c2aff7Sartem HalProperty *prop; 689*18c2aff7Sartem 690*18c2aff7Sartem /* check if property already exists */ 691*18c2aff7Sartem prop = hal_device_property_find (device, key); 692*18c2aff7Sartem 693*18c2aff7Sartem if (prop != NULL) { 694*18c2aff7Sartem if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRING) 695*18c2aff7Sartem return FALSE; 696*18c2aff7Sartem 697*18c2aff7Sartem /* don't bother setting the same value */ 698*18c2aff7Sartem if (value != NULL && 699*18c2aff7Sartem strcmp (hal_property_get_string (prop), value) == 0) 700*18c2aff7Sartem return TRUE; 701*18c2aff7Sartem 702*18c2aff7Sartem hal_property_set_string (prop, value); 703*18c2aff7Sartem 704*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 705*18c2aff7Sartem key, FALSE, FALSE); 706*18c2aff7Sartem 707*18c2aff7Sartem } else { 708*18c2aff7Sartem 709*18c2aff7Sartem prop = hal_property_new_string (key, value); 710*18c2aff7Sartem 711*18c2aff7Sartem device->properties = g_slist_prepend (device->properties, prop); 712*18c2aff7Sartem 713*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 714*18c2aff7Sartem key, FALSE, TRUE); 715*18c2aff7Sartem } 716*18c2aff7Sartem 717*18c2aff7Sartem return TRUE; 718*18c2aff7Sartem } 719*18c2aff7Sartem 720*18c2aff7Sartem gboolean 721*18c2aff7Sartem hal_device_property_set_int (HalDevice *device, const char *key, 722*18c2aff7Sartem dbus_int32_t value) 723*18c2aff7Sartem { 724*18c2aff7Sartem HalProperty *prop; 725*18c2aff7Sartem 726*18c2aff7Sartem /* check if property already exists */ 727*18c2aff7Sartem prop = hal_device_property_find (device, key); 728*18c2aff7Sartem 729*18c2aff7Sartem if (prop != NULL) { 730*18c2aff7Sartem if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_INT32) 731*18c2aff7Sartem return FALSE; 732*18c2aff7Sartem 733*18c2aff7Sartem /* don't bother setting the same value */ 734*18c2aff7Sartem if (hal_property_get_int (prop) == value) 735*18c2aff7Sartem return TRUE; 736*18c2aff7Sartem 737*18c2aff7Sartem hal_property_set_int (prop, value); 738*18c2aff7Sartem 739*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 740*18c2aff7Sartem key, FALSE, FALSE); 741*18c2aff7Sartem 742*18c2aff7Sartem } else { 743*18c2aff7Sartem prop = hal_property_new_int (key, value); 744*18c2aff7Sartem 745*18c2aff7Sartem device->properties = g_slist_prepend (device->properties, prop); 746*18c2aff7Sartem 747*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 748*18c2aff7Sartem key, FALSE, TRUE); 749*18c2aff7Sartem } 750*18c2aff7Sartem 751*18c2aff7Sartem return TRUE; 752*18c2aff7Sartem } 753*18c2aff7Sartem 754*18c2aff7Sartem gboolean 755*18c2aff7Sartem hal_device_property_set_uint64 (HalDevice *device, const char *key, 756*18c2aff7Sartem dbus_uint64_t value) 757*18c2aff7Sartem { 758*18c2aff7Sartem HalProperty *prop; 759*18c2aff7Sartem 760*18c2aff7Sartem /* check if property already exists */ 761*18c2aff7Sartem prop = hal_device_property_find (device, key); 762*18c2aff7Sartem 763*18c2aff7Sartem if (prop != NULL) { 764*18c2aff7Sartem if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_UINT64) 765*18c2aff7Sartem return FALSE; 766*18c2aff7Sartem 767*18c2aff7Sartem /* don't bother setting the same value */ 768*18c2aff7Sartem if (hal_property_get_uint64 (prop) == value) 769*18c2aff7Sartem return TRUE; 770*18c2aff7Sartem 771*18c2aff7Sartem hal_property_set_uint64 (prop, value); 772*18c2aff7Sartem 773*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 774*18c2aff7Sartem key, FALSE, FALSE); 775*18c2aff7Sartem 776*18c2aff7Sartem } else { 777*18c2aff7Sartem prop = hal_property_new_uint64 (key, value); 778*18c2aff7Sartem 779*18c2aff7Sartem device->properties = g_slist_prepend (device->properties, prop); 780*18c2aff7Sartem 781*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 782*18c2aff7Sartem key, FALSE, TRUE); 783*18c2aff7Sartem } 784*18c2aff7Sartem 785*18c2aff7Sartem return TRUE; 786*18c2aff7Sartem } 787*18c2aff7Sartem 788*18c2aff7Sartem gboolean 789*18c2aff7Sartem hal_device_property_set_bool (HalDevice *device, const char *key, 790*18c2aff7Sartem dbus_bool_t value) 791*18c2aff7Sartem { 792*18c2aff7Sartem HalProperty *prop; 793*18c2aff7Sartem 794*18c2aff7Sartem /* check if property already exists */ 795*18c2aff7Sartem prop = hal_device_property_find (device, key); 796*18c2aff7Sartem 797*18c2aff7Sartem if (prop != NULL) { 798*18c2aff7Sartem if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_BOOLEAN) 799*18c2aff7Sartem return FALSE; 800*18c2aff7Sartem 801*18c2aff7Sartem /* don't bother setting the same value */ 802*18c2aff7Sartem if (hal_property_get_bool (prop) == value) 803*18c2aff7Sartem return TRUE; 804*18c2aff7Sartem 805*18c2aff7Sartem hal_property_set_bool (prop, value); 806*18c2aff7Sartem 807*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 808*18c2aff7Sartem key, FALSE, FALSE); 809*18c2aff7Sartem 810*18c2aff7Sartem } else { 811*18c2aff7Sartem prop = hal_property_new_bool (key, value); 812*18c2aff7Sartem 813*18c2aff7Sartem device->properties = g_slist_prepend (device->properties, prop); 814*18c2aff7Sartem 815*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 816*18c2aff7Sartem key, FALSE, TRUE); 817*18c2aff7Sartem } 818*18c2aff7Sartem 819*18c2aff7Sartem return TRUE; 820*18c2aff7Sartem } 821*18c2aff7Sartem 822*18c2aff7Sartem gboolean 823*18c2aff7Sartem hal_device_property_set_double (HalDevice *device, const char *key, 824*18c2aff7Sartem double value) 825*18c2aff7Sartem { 826*18c2aff7Sartem HalProperty *prop; 827*18c2aff7Sartem 828*18c2aff7Sartem /* check if property already exists */ 829*18c2aff7Sartem prop = hal_device_property_find (device, key); 830*18c2aff7Sartem 831*18c2aff7Sartem if (prop != NULL) { 832*18c2aff7Sartem if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_DOUBLE) 833*18c2aff7Sartem return FALSE; 834*18c2aff7Sartem 835*18c2aff7Sartem /* don't bother setting the same value */ 836*18c2aff7Sartem if (hal_property_get_double (prop) == value) 837*18c2aff7Sartem return TRUE; 838*18c2aff7Sartem 839*18c2aff7Sartem hal_property_set_double (prop, value); 840*18c2aff7Sartem 841*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 842*18c2aff7Sartem key, FALSE, FALSE); 843*18c2aff7Sartem 844*18c2aff7Sartem } else { 845*18c2aff7Sartem prop = hal_property_new_double (key, value); 846*18c2aff7Sartem 847*18c2aff7Sartem device->properties = g_slist_prepend (device->properties, prop); 848*18c2aff7Sartem 849*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 850*18c2aff7Sartem key, FALSE, TRUE); 851*18c2aff7Sartem } 852*18c2aff7Sartem 853*18c2aff7Sartem return TRUE; 854*18c2aff7Sartem } 855*18c2aff7Sartem 856*18c2aff7Sartem gboolean 857*18c2aff7Sartem hal_device_copy_property (HalDevice *from_device, const char *from, HalDevice *to_device, const char *to) 858*18c2aff7Sartem { 859*18c2aff7Sartem gboolean rc; 860*18c2aff7Sartem 861*18c2aff7Sartem rc = FALSE; 862*18c2aff7Sartem 863*18c2aff7Sartem if (hal_device_has_property (from_device, from)) { 864*18c2aff7Sartem switch (hal_device_property_get_type (from_device, from)) { 865*18c2aff7Sartem case HAL_PROPERTY_TYPE_STRING: 866*18c2aff7Sartem rc = hal_device_property_set_string ( 867*18c2aff7Sartem to_device, to, hal_device_property_get_string (from_device, from)); 868*18c2aff7Sartem break; 869*18c2aff7Sartem case HAL_PROPERTY_TYPE_INT32: 870*18c2aff7Sartem rc = hal_device_property_set_int ( 871*18c2aff7Sartem to_device, to, hal_device_property_get_int (from_device, from)); 872*18c2aff7Sartem break; 873*18c2aff7Sartem case HAL_PROPERTY_TYPE_UINT64: 874*18c2aff7Sartem rc = hal_device_property_set_uint64 ( 875*18c2aff7Sartem to_device, to, hal_device_property_get_uint64 (from_device, from)); 876*18c2aff7Sartem break; 877*18c2aff7Sartem case HAL_PROPERTY_TYPE_BOOLEAN: 878*18c2aff7Sartem rc = hal_device_property_set_bool ( 879*18c2aff7Sartem to_device, to, hal_device_property_get_bool (from_device, from)); 880*18c2aff7Sartem break; 881*18c2aff7Sartem case HAL_PROPERTY_TYPE_DOUBLE: 882*18c2aff7Sartem rc = hal_device_property_set_double ( 883*18c2aff7Sartem to_device, to, hal_device_property_get_double (from_device, from)); 884*18c2aff7Sartem break; 885*18c2aff7Sartem } 886*18c2aff7Sartem } 887*18c2aff7Sartem 888*18c2aff7Sartem return rc; 889*18c2aff7Sartem } 890*18c2aff7Sartem 891*18c2aff7Sartem gboolean 892*18c2aff7Sartem hal_device_property_remove (HalDevice *device, const char *key) 893*18c2aff7Sartem { 894*18c2aff7Sartem HalProperty *prop; 895*18c2aff7Sartem 896*18c2aff7Sartem prop = hal_device_property_find (device, key); 897*18c2aff7Sartem 898*18c2aff7Sartem if (prop == NULL) 899*18c2aff7Sartem return FALSE; 900*18c2aff7Sartem 901*18c2aff7Sartem device->properties = g_slist_remove (device->properties, prop); 902*18c2aff7Sartem 903*18c2aff7Sartem hal_property_free (prop); 904*18c2aff7Sartem 905*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 906*18c2aff7Sartem key, TRUE, FALSE); 907*18c2aff7Sartem 908*18c2aff7Sartem return TRUE; 909*18c2aff7Sartem } 910*18c2aff7Sartem 911*18c2aff7Sartem gboolean 912*18c2aff7Sartem hal_device_property_set_attribute (HalDevice *device, 913*18c2aff7Sartem const char *key, 914*18c2aff7Sartem enum PropertyAttribute attr, 915*18c2aff7Sartem gboolean val) 916*18c2aff7Sartem { 917*18c2aff7Sartem HalProperty *prop; 918*18c2aff7Sartem 919*18c2aff7Sartem prop = hal_device_property_find (device, key); 920*18c2aff7Sartem 921*18c2aff7Sartem if (prop == NULL) 922*18c2aff7Sartem return FALSE; 923*18c2aff7Sartem 924*18c2aff7Sartem return TRUE; 925*18c2aff7Sartem } 926*18c2aff7Sartem 927*18c2aff7Sartem void 928*18c2aff7Sartem hal_device_print (HalDevice *device) 929*18c2aff7Sartem { 930*18c2aff7Sartem GSList *iter; 931*18c2aff7Sartem 932*18c2aff7Sartem fprintf (stderr, "device udi = %s\n", hal_device_get_udi (device)); 933*18c2aff7Sartem 934*18c2aff7Sartem for (iter = device->properties; iter != NULL; iter = iter->next) { 935*18c2aff7Sartem HalProperty *p = iter->data; 936*18c2aff7Sartem int type; 937*18c2aff7Sartem const char *key; 938*18c2aff7Sartem 939*18c2aff7Sartem key = hal_property_get_key (p); 940*18c2aff7Sartem type = hal_property_get_type (p); 941*18c2aff7Sartem 942*18c2aff7Sartem switch (type) { 943*18c2aff7Sartem case HAL_PROPERTY_TYPE_STRING: 944*18c2aff7Sartem fprintf (stderr, " %s = '%s' (string)\n", key, 945*18c2aff7Sartem hal_property_get_string (p)); 946*18c2aff7Sartem break; 947*18c2aff7Sartem 948*18c2aff7Sartem case HAL_PROPERTY_TYPE_INT32: 949*18c2aff7Sartem fprintf (stderr, " %s = %d 0x%x (int)\n", key, 950*18c2aff7Sartem hal_property_get_int (p), 951*18c2aff7Sartem hal_property_get_int (p)); 952*18c2aff7Sartem break; 953*18c2aff7Sartem 954*18c2aff7Sartem case HAL_PROPERTY_TYPE_UINT64: 955*18c2aff7Sartem fprintf (stderr, " %s = %llu 0x%llx (uint64)\n", key, 956*18c2aff7Sartem (long long unsigned int) hal_property_get_uint64 (p), 957*18c2aff7Sartem (long long unsigned int) hal_property_get_uint64 (p)); 958*18c2aff7Sartem break; 959*18c2aff7Sartem 960*18c2aff7Sartem case HAL_PROPERTY_TYPE_DOUBLE: 961*18c2aff7Sartem fprintf (stderr, " %s = %g (double)\n", key, 962*18c2aff7Sartem hal_property_get_double (p)); 963*18c2aff7Sartem break; 964*18c2aff7Sartem 965*18c2aff7Sartem case HAL_PROPERTY_TYPE_BOOLEAN: 966*18c2aff7Sartem fprintf (stderr, " %s = %s (bool)\n", key, 967*18c2aff7Sartem (hal_property_get_bool (p) ? "true" : 968*18c2aff7Sartem "false")); 969*18c2aff7Sartem break; 970*18c2aff7Sartem 971*18c2aff7Sartem default: 972*18c2aff7Sartem HAL_WARNING (("Unknown property type %d", type)); 973*18c2aff7Sartem break; 974*18c2aff7Sartem } 975*18c2aff7Sartem } 976*18c2aff7Sartem fprintf (stderr, "\n"); 977*18c2aff7Sartem } 978*18c2aff7Sartem 979*18c2aff7Sartem 980*18c2aff7Sartem typedef struct { 981*18c2aff7Sartem char *key; 982*18c2aff7Sartem HalDevice *device; 983*18c2aff7Sartem HalDeviceAsyncCallback callback; 984*18c2aff7Sartem gpointer user_data; 985*18c2aff7Sartem 986*18c2aff7Sartem guint prop_signal_id; 987*18c2aff7Sartem guint timeout_id; 988*18c2aff7Sartem } AsyncMatchInfo; 989*18c2aff7Sartem 990*18c2aff7Sartem static void 991*18c2aff7Sartem destroy_async_match_info (AsyncMatchInfo *ai) 992*18c2aff7Sartem { 993*18c2aff7Sartem g_free (ai->key); 994*18c2aff7Sartem g_signal_handler_disconnect (ai->device, ai->prop_signal_id); 995*18c2aff7Sartem g_source_remove (ai->timeout_id); 996*18c2aff7Sartem g_object_unref (ai->device); 997*18c2aff7Sartem g_free (ai); 998*18c2aff7Sartem } 999*18c2aff7Sartem 1000*18c2aff7Sartem static void 1001*18c2aff7Sartem prop_changed_cb (HalDevice *device, const char *key, 1002*18c2aff7Sartem gboolean removed, gboolean added, gpointer user_data) 1003*18c2aff7Sartem { 1004*18c2aff7Sartem AsyncMatchInfo *ai = user_data; 1005*18c2aff7Sartem 1006*18c2aff7Sartem if (strcmp (key, ai->key) != 0) 1007*18c2aff7Sartem return; 1008*18c2aff7Sartem 1009*18c2aff7Sartem /* the property is no longer there */ 1010*18c2aff7Sartem if (removed) 1011*18c2aff7Sartem goto cleanup; 1012*18c2aff7Sartem 1013*18c2aff7Sartem 1014*18c2aff7Sartem ai->callback (ai->device, ai->user_data, TRUE); 1015*18c2aff7Sartem 1016*18c2aff7Sartem cleanup: 1017*18c2aff7Sartem destroy_async_match_info (ai); 1018*18c2aff7Sartem } 1019*18c2aff7Sartem 1020*18c2aff7Sartem 1021*18c2aff7Sartem static gboolean 1022*18c2aff7Sartem async_wait_timeout (gpointer user_data) 1023*18c2aff7Sartem { 1024*18c2aff7Sartem AsyncMatchInfo *ai = (AsyncMatchInfo *) user_data; 1025*18c2aff7Sartem 1026*18c2aff7Sartem ai->callback (ai->device, ai->user_data, FALSE); 1027*18c2aff7Sartem 1028*18c2aff7Sartem destroy_async_match_info (ai); 1029*18c2aff7Sartem 1030*18c2aff7Sartem return FALSE; 1031*18c2aff7Sartem } 1032*18c2aff7Sartem 1033*18c2aff7Sartem void 1034*18c2aff7Sartem hal_device_async_wait_property (HalDevice *device, 1035*18c2aff7Sartem const char *key, 1036*18c2aff7Sartem HalDeviceAsyncCallback callback, 1037*18c2aff7Sartem gpointer user_data, 1038*18c2aff7Sartem int timeout) 1039*18c2aff7Sartem { 1040*18c2aff7Sartem HalProperty *prop; 1041*18c2aff7Sartem AsyncMatchInfo *ai; 1042*18c2aff7Sartem 1043*18c2aff7Sartem /* check if property already exists */ 1044*18c2aff7Sartem prop = hal_device_property_find (device, key); 1045*18c2aff7Sartem 1046*18c2aff7Sartem if (prop != NULL || timeout==0) { 1047*18c2aff7Sartem callback (device, user_data, prop != NULL); 1048*18c2aff7Sartem return; 1049*18c2aff7Sartem } 1050*18c2aff7Sartem 1051*18c2aff7Sartem ai = g_new0 (AsyncMatchInfo, 1); 1052*18c2aff7Sartem 1053*18c2aff7Sartem ai->device = g_object_ref (device); 1054*18c2aff7Sartem ai->key = g_strdup (key); 1055*18c2aff7Sartem ai->callback = callback; 1056*18c2aff7Sartem ai->user_data = user_data; 1057*18c2aff7Sartem 1058*18c2aff7Sartem ai->prop_signal_id = g_signal_connect (device, "property_changed", 1059*18c2aff7Sartem G_CALLBACK (prop_changed_cb), 1060*18c2aff7Sartem ai); 1061*18c2aff7Sartem 1062*18c2aff7Sartem ai->timeout_id = g_timeout_add (timeout, async_wait_timeout, ai); 1063*18c2aff7Sartem } 1064*18c2aff7Sartem 1065*18c2aff7Sartem void 1066*18c2aff7Sartem hal_device_callouts_finished (HalDevice *device) 1067*18c2aff7Sartem { 1068*18c2aff7Sartem g_signal_emit (device, signals[CALLOUTS_FINISHED], 0); 1069*18c2aff7Sartem } 1070*18c2aff7Sartem 1071*18c2aff7Sartem /** Used when giving up on a device, e.g. if no device file appeared 1072*18c2aff7Sartem */ 1073*18c2aff7Sartem void 1074*18c2aff7Sartem hal_device_cancel (HalDevice *device) 1075*18c2aff7Sartem { 1076*18c2aff7Sartem HAL_INFO (("udi=%s", device->udi)); 1077*18c2aff7Sartem g_signal_emit (device, signals[CANCELLED], 0); 1078*18c2aff7Sartem } 1079*18c2aff7Sartem 1080*18c2aff7Sartem 1081*18c2aff7Sartem 1082*18c2aff7Sartem 1083*18c2aff7Sartem GSList * 1084*18c2aff7Sartem hal_device_property_get_strlist (HalDevice *device, 1085*18c2aff7Sartem const char *key) 1086*18c2aff7Sartem { 1087*18c2aff7Sartem HalProperty *prop; 1088*18c2aff7Sartem 1089*18c2aff7Sartem g_return_val_if_fail (device != NULL, NULL); 1090*18c2aff7Sartem g_return_val_if_fail (key != NULL, NULL); 1091*18c2aff7Sartem 1092*18c2aff7Sartem prop = hal_device_property_find (device, key); 1093*18c2aff7Sartem 1094*18c2aff7Sartem if (prop != NULL) 1095*18c2aff7Sartem return hal_property_get_strlist (prop); 1096*18c2aff7Sartem else 1097*18c2aff7Sartem return NULL; 1098*18c2aff7Sartem } 1099*18c2aff7Sartem 1100*18c2aff7Sartem const char * 1101*18c2aff7Sartem hal_device_property_get_strlist_elem (HalDevice *device, 1102*18c2aff7Sartem const char *key, 1103*18c2aff7Sartem guint index) 1104*18c2aff7Sartem { 1105*18c2aff7Sartem GSList *strlist; 1106*18c2aff7Sartem GSList *i; 1107*18c2aff7Sartem 1108*18c2aff7Sartem strlist = hal_device_property_get_strlist (device, key); 1109*18c2aff7Sartem if (strlist == NULL) 1110*18c2aff7Sartem return NULL; 1111*18c2aff7Sartem 1112*18c2aff7Sartem i = g_slist_nth (strlist, index); 1113*18c2aff7Sartem if (i == NULL) 1114*18c2aff7Sartem return NULL; 1115*18c2aff7Sartem 1116*18c2aff7Sartem return (const char *) i->data; 1117*18c2aff7Sartem } 1118*18c2aff7Sartem 1119*18c2aff7Sartem gboolean 1120*18c2aff7Sartem hal_device_property_strlist_append (HalDevice *device, 1121*18c2aff7Sartem const char *key, 1122*18c2aff7Sartem const char *value) 1123*18c2aff7Sartem { 1124*18c2aff7Sartem HalProperty *prop; 1125*18c2aff7Sartem 1126*18c2aff7Sartem /* check if property already exists */ 1127*18c2aff7Sartem prop = hal_device_property_find (device, key); 1128*18c2aff7Sartem 1129*18c2aff7Sartem if (prop != NULL) { 1130*18c2aff7Sartem if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST) 1131*18c2aff7Sartem return FALSE; 1132*18c2aff7Sartem 1133*18c2aff7Sartem hal_property_strlist_append (prop, value); 1134*18c2aff7Sartem 1135*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 1136*18c2aff7Sartem key, FALSE, FALSE); 1137*18c2aff7Sartem 1138*18c2aff7Sartem } else { 1139*18c2aff7Sartem prop = hal_property_new_strlist (key); 1140*18c2aff7Sartem hal_property_strlist_append (prop, value); 1141*18c2aff7Sartem 1142*18c2aff7Sartem device->properties = g_slist_prepend (device->properties, prop); 1143*18c2aff7Sartem 1144*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 1145*18c2aff7Sartem key, FALSE, TRUE); 1146*18c2aff7Sartem } 1147*18c2aff7Sartem 1148*18c2aff7Sartem return TRUE; 1149*18c2aff7Sartem } 1150*18c2aff7Sartem 1151*18c2aff7Sartem gboolean 1152*18c2aff7Sartem hal_device_property_strlist_prepend (HalDevice *device, 1153*18c2aff7Sartem const char *key, 1154*18c2aff7Sartem const char *value) 1155*18c2aff7Sartem { 1156*18c2aff7Sartem HalProperty *prop; 1157*18c2aff7Sartem 1158*18c2aff7Sartem /* check if property already exists */ 1159*18c2aff7Sartem prop = hal_device_property_find (device, key); 1160*18c2aff7Sartem 1161*18c2aff7Sartem if (prop != NULL) { 1162*18c2aff7Sartem if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST) 1163*18c2aff7Sartem return FALSE; 1164*18c2aff7Sartem 1165*18c2aff7Sartem hal_property_strlist_prepend (prop, value); 1166*18c2aff7Sartem 1167*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 1168*18c2aff7Sartem key, FALSE, FALSE); 1169*18c2aff7Sartem 1170*18c2aff7Sartem } else { 1171*18c2aff7Sartem prop = hal_property_new_strlist (key); 1172*18c2aff7Sartem hal_property_strlist_prepend (prop, value); 1173*18c2aff7Sartem 1174*18c2aff7Sartem device->properties = g_slist_prepend (device->properties, prop); 1175*18c2aff7Sartem 1176*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 1177*18c2aff7Sartem key, FALSE, TRUE); 1178*18c2aff7Sartem } 1179*18c2aff7Sartem 1180*18c2aff7Sartem return TRUE; 1181*18c2aff7Sartem } 1182*18c2aff7Sartem 1183*18c2aff7Sartem gboolean 1184*18c2aff7Sartem hal_device_property_strlist_remove_elem (HalDevice *device, 1185*18c2aff7Sartem const char *key, 1186*18c2aff7Sartem guint index) 1187*18c2aff7Sartem { 1188*18c2aff7Sartem HalProperty *prop; 1189*18c2aff7Sartem 1190*18c2aff7Sartem /* check if property already exists */ 1191*18c2aff7Sartem prop = hal_device_property_find (device, key); 1192*18c2aff7Sartem 1193*18c2aff7Sartem if (prop == NULL) 1194*18c2aff7Sartem return FALSE; 1195*18c2aff7Sartem 1196*18c2aff7Sartem if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST) 1197*18c2aff7Sartem return FALSE; 1198*18c2aff7Sartem 1199*18c2aff7Sartem if (hal_property_strlist_remove_elem (prop, index)) { 1200*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 1201*18c2aff7Sartem key, FALSE, FALSE); 1202*18c2aff7Sartem return TRUE; 1203*18c2aff7Sartem } 1204*18c2aff7Sartem 1205*18c2aff7Sartem return FALSE; 1206*18c2aff7Sartem } 1207*18c2aff7Sartem 1208*18c2aff7Sartem gboolean 1209*18c2aff7Sartem hal_device_property_strlist_clear (HalDevice *device, 1210*18c2aff7Sartem const char *key) 1211*18c2aff7Sartem { 1212*18c2aff7Sartem HalProperty *prop; 1213*18c2aff7Sartem 1214*18c2aff7Sartem /* check if property already exists */ 1215*18c2aff7Sartem prop = hal_device_property_find (device, key); 1216*18c2aff7Sartem 1217*18c2aff7Sartem if (prop == NULL) { 1218*18c2aff7Sartem prop = hal_property_new_strlist (key); 1219*18c2aff7Sartem 1220*18c2aff7Sartem device->properties = g_slist_prepend (device->properties, prop); 1221*18c2aff7Sartem 1222*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 1223*18c2aff7Sartem key, FALSE, TRUE); 1224*18c2aff7Sartem 1225*18c2aff7Sartem return TRUE; 1226*18c2aff7Sartem } 1227*18c2aff7Sartem 1228*18c2aff7Sartem if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST) 1229*18c2aff7Sartem return FALSE; 1230*18c2aff7Sartem 1231*18c2aff7Sartem if (hal_property_strlist_clear (prop)) { 1232*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 1233*18c2aff7Sartem key, FALSE, FALSE); 1234*18c2aff7Sartem return TRUE; 1235*18c2aff7Sartem } 1236*18c2aff7Sartem 1237*18c2aff7Sartem return FALSE; 1238*18c2aff7Sartem } 1239*18c2aff7Sartem 1240*18c2aff7Sartem 1241*18c2aff7Sartem gboolean 1242*18c2aff7Sartem hal_device_property_strlist_add (HalDevice *device, 1243*18c2aff7Sartem const char *key, 1244*18c2aff7Sartem const char *value) 1245*18c2aff7Sartem { 1246*18c2aff7Sartem HalProperty *prop; 1247*18c2aff7Sartem gboolean res; 1248*18c2aff7Sartem 1249*18c2aff7Sartem res = FALSE; 1250*18c2aff7Sartem 1251*18c2aff7Sartem /* check if property already exists */ 1252*18c2aff7Sartem prop = hal_device_property_find (device, key); 1253*18c2aff7Sartem 1254*18c2aff7Sartem if (prop != NULL) { 1255*18c2aff7Sartem if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST) 1256*18c2aff7Sartem goto out; 1257*18c2aff7Sartem 1258*18c2aff7Sartem res = hal_property_strlist_add (prop, value); 1259*18c2aff7Sartem if (res) { 1260*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 1261*18c2aff7Sartem key, FALSE, FALSE); 1262*18c2aff7Sartem } 1263*18c2aff7Sartem 1264*18c2aff7Sartem } else { 1265*18c2aff7Sartem prop = hal_property_new_strlist (key); 1266*18c2aff7Sartem hal_property_strlist_prepend (prop, value); 1267*18c2aff7Sartem 1268*18c2aff7Sartem device->properties = g_slist_prepend (device->properties, prop); 1269*18c2aff7Sartem 1270*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 1271*18c2aff7Sartem key, FALSE, TRUE); 1272*18c2aff7Sartem 1273*18c2aff7Sartem res = TRUE; 1274*18c2aff7Sartem } 1275*18c2aff7Sartem 1276*18c2aff7Sartem out: 1277*18c2aff7Sartem return res; 1278*18c2aff7Sartem } 1279*18c2aff7Sartem 1280*18c2aff7Sartem gboolean 1281*18c2aff7Sartem hal_device_property_strlist_remove (HalDevice *device, 1282*18c2aff7Sartem const char *key, 1283*18c2aff7Sartem const char *value) 1284*18c2aff7Sartem { 1285*18c2aff7Sartem HalProperty *prop; 1286*18c2aff7Sartem 1287*18c2aff7Sartem /* check if property already exists */ 1288*18c2aff7Sartem prop = hal_device_property_find (device, key); 1289*18c2aff7Sartem 1290*18c2aff7Sartem if (prop == NULL) 1291*18c2aff7Sartem return FALSE; 1292*18c2aff7Sartem 1293*18c2aff7Sartem if (hal_property_get_type (prop) != HAL_PROPERTY_TYPE_STRLIST) 1294*18c2aff7Sartem return FALSE; 1295*18c2aff7Sartem 1296*18c2aff7Sartem if (hal_property_strlist_remove (prop, value)) { 1297*18c2aff7Sartem g_signal_emit (device, signals[PROPERTY_CHANGED], 0, 1298*18c2aff7Sartem key, FALSE, FALSE); 1299*18c2aff7Sartem } 1300*18c2aff7Sartem 1301*18c2aff7Sartem return TRUE; 1302*18c2aff7Sartem } 1303*18c2aff7Sartem 1304*18c2aff7Sartem gboolean 1305*18c2aff7Sartem hal_device_property_strlist_is_empty (HalDevice *device, 1306*18c2aff7Sartem const char *key) 1307*18c2aff7Sartem { 1308*18c2aff7Sartem GSList *strlist; 1309*18c2aff7Sartem 1310*18c2aff7Sartem if ( hal_device_has_property (device, key)) { 1311*18c2aff7Sartem strlist = hal_device_property_get_strlist (device, key); 1312*18c2aff7Sartem if (strlist == NULL ) 1313*18c2aff7Sartem return TRUE; 1314*18c2aff7Sartem 1315*18c2aff7Sartem if (g_slist_length (strlist) > 0) 1316*18c2aff7Sartem return FALSE; 1317*18c2aff7Sartem else 1318*18c2aff7Sartem return TRUE; 1319*18c2aff7Sartem } 1320*18c2aff7Sartem return FALSE; 1321*18c2aff7Sartem } 1322*18c2aff7Sartem 1323*18c2aff7Sartem void 1324*18c2aff7Sartem hal_device_inc_num_addons (HalDevice *device) 1325*18c2aff7Sartem { 1326*18c2aff7Sartem device->num_addons++; 1327*18c2aff7Sartem } 1328*18c2aff7Sartem 1329*18c2aff7Sartem gboolean 1330*18c2aff7Sartem hal_device_inc_num_ready_addons (HalDevice *device) 1331*18c2aff7Sartem { 1332*18c2aff7Sartem if (hal_device_are_all_addons_ready (device)) { 1333*18c2aff7Sartem HAL_ERROR (("In hal_device_inc_num_ready_addons for udi=%s but all addons are already ready!", 1334*18c2aff7Sartem device->udi)); 1335*18c2aff7Sartem return FALSE; 1336*18c2aff7Sartem } 1337*18c2aff7Sartem 1338*18c2aff7Sartem device->num_addons_ready++; 1339*18c2aff7Sartem return TRUE; 1340*18c2aff7Sartem } 1341*18c2aff7Sartem 1342*18c2aff7Sartem gboolean 1343*18c2aff7Sartem hal_device_are_all_addons_ready (HalDevice *device) 1344*18c2aff7Sartem { 1345*18c2aff7Sartem if (device->num_addons_ready == device->num_addons) { 1346*18c2aff7Sartem return TRUE; 1347*18c2aff7Sartem } else { 1348*18c2aff7Sartem return FALSE; 1349*18c2aff7Sartem } 1350*18c2aff7Sartem } 1351