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