00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifdef HAVE_CONFIG_H
00028 # include <config.h>
00029 #endif
00030
00031 #include <assert.h>
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <dbus/dbus.h>
00036 #include <dbus/dbus-glib.h>
00037
00038 #include "logger.h"
00039 #include "hald.h"
00040 #include "device_store.h"
00041
00054
00055 static void async_find_property_changed (HalDevice * device,
00056 const char *key,
00057 dbus_bool_t in_gdl,
00058 dbus_bool_t removed,
00059 dbus_bool_t added);
00060
00062 #define MAX_CB_FUNCS 32
00063
00065 static HalDevicePropertyChangedCallback property_changed_cb[MAX_CB_FUNCS];
00066
00068 static HalDeviceGDLChangedCallback gdl_changed_cb[MAX_CB_FUNCS];
00069
00071 static HalDeviceNewCapabilityCallback new_capability_cb[MAX_CB_FUNCS];
00072
00074 static int num_property_changed_cb = 0;
00075
00077 static int num_gdl_changed_cb = 0;
00078
00080 static int num_new_capability_cb = 0;
00081
00082
00084 static unsigned int device_list_num = 0;
00085
00087 unsigned int temp_device_counter = 0;
00088
00090 static HalDevice *device_list_head = NULL;
00091
00095 void
00096 ds_init ()
00097 {
00098 device_list_num = 0;
00099 device_list_head = NULL;
00100 temp_device_counter = 0;
00101
00102 num_gdl_changed_cb = 0;
00103 num_new_capability_cb = 0;
00104 num_property_changed_cb = 1;
00105 property_changed_cb[0] = async_find_property_changed;
00106 }
00107
00112 void
00113 ds_add_cb_newcap (HalDeviceNewCapabilityCallback cb)
00114 {
00115 if (num_property_changed_cb < MAX_CB_FUNCS)
00116 new_capability_cb[num_new_capability_cb++] = cb;
00117 }
00118
00123 void
00124 ds_add_cb_property_changed (HalDevicePropertyChangedCallback cb)
00125 {
00126 if (num_property_changed_cb < MAX_CB_FUNCS)
00127 property_changed_cb[num_property_changed_cb++] = cb;
00128 }
00129
00134 void
00135 ds_add_cb_gdl_changed (HalDeviceGDLChangedCallback cb)
00136 {
00137 if (num_gdl_changed_cb < MAX_CB_FUNCS)
00138 gdl_changed_cb[num_gdl_changed_cb++] = cb;
00139 }
00140
00141
00142
00145 void
00146 ds_shutdown ()
00147 {
00148 }
00149
00154 void
00155 ds_print (HalDevice * device)
00156 {
00157 HalPropertyIterator iter;
00158
00159 printf ("device udi = %s (%s)\n", ds_device_get_udi (device),
00160 device->in_gdl ? "in GDL" : "NOT in GDL");
00161
00162 for (ds_property_iter_begin (device, &iter);
00163 ds_property_iter_has_more (&iter);
00164 ds_property_iter_next (&iter)) {
00165 int type;
00166 HalProperty *p;
00167 const char *key;
00168
00169 p = ds_property_iter_get (&iter);
00170
00171 key = ds_property_iter_get_key (p);
00172 type = ds_property_iter_get_type (p);
00173
00174 switch (type) {
00175 case DBUS_TYPE_STRING:
00176 printf (" %s = '%s' (string)\n", key,
00177 ds_property_iter_get_string (p));
00178 break;
00179
00180 case DBUS_TYPE_INT32:
00181 printf (" %s = %d 0x%x (int)\n", key,
00182 ds_property_iter_get_int (p),
00183 ds_property_iter_get_int (p));
00184 break;
00185
00186 case DBUS_TYPE_DOUBLE:
00187 printf (" %s = %g (double)\n", key,
00188 ds_property_iter_get_double (p));
00189 break;
00190
00191 case DBUS_TYPE_BOOLEAN:
00192 printf (" %s = %s (bool)\n", key,
00193 (ds_property_iter_get_bool (p) ? "true" :
00194 "false"));
00195 break;
00196
00197 default:
00198 HAL_WARNING (("Unknown property type %d", type));
00199 break;
00200 }
00201 }
00202 printf ("\n");
00203 }
00204
00205
00206
00213 HalDevice *
00214 ds_device_find (const char *udi)
00215 {
00216 HalDevice *it;
00217
00218 for (it = device_list_head; it != NULL; it = it->next) {
00219 if (strcmp (it->udi, udi) == 0)
00220 return it;
00221 }
00222 return NULL;
00223 }
00224
00226 typedef struct DSDeviceAsyncFindStruct_s {
00227 char *key;
00228 char *value;
00230 dbus_bool_t only_gdl;
00231 DSAsyncFindDeviceCB callback;
00233 void *data1;
00234 void *data2;
00235 guint timeout_id;
00237 struct DSDeviceAsyncFindStruct_s *next;
00239 } DSDeviceAsyncFindStruct;
00240
00242 static DSDeviceAsyncFindStruct *async_find_outstanding_head = NULL;
00243
00249 static gboolean
00250 async_find_timeout_fn (gpointer data)
00251 {
00252 void *data1;
00253 void *data2;
00254 DSAsyncFindDeviceCB callback;
00255 DSDeviceAsyncFindStruct *i;
00256 DSDeviceAsyncFindStruct *prev;
00257 DSDeviceAsyncFindStruct *afs = (DSDeviceAsyncFindStruct *) data;
00258
00259
00260 for (i = async_find_outstanding_head, prev = NULL; i != NULL;
00261 i = i->next) {
00262 if (i == afs) {
00263 data1 = i->data1;
00264 data2 = i->data2;
00265 callback = i->callback;
00266
00267
00268 if (prev != NULL) {
00269 prev->next = i->next;
00270 } else {
00271 async_find_outstanding_head = i->next;
00272 }
00273
00274
00275 free (i->key);
00276 free (i->value);
00277 free (i);
00278
00279
00280
00281
00282
00283
00284
00285 (*callback) (NULL, data1, data2);
00286
00287 return FALSE;
00288 }
00289
00290 prev = i;
00291 }
00292 return FALSE;
00293 }
00294
00295
00304 static void
00305 async_find_check_new_addition (HalDevice * device)
00306 {
00307 int type;
00308 void *data1;
00309 void *data2;
00310 DSAsyncFindDeviceCB callback;
00311 DSDeviceAsyncFindStruct *i;
00312 DSDeviceAsyncFindStruct *prev;
00313
00314 check_list_again:
00315
00316
00317 for (i = async_find_outstanding_head, prev = NULL; i != NULL;
00318 i = i->next) {
00319
00320
00321 type = ds_property_get_type (device, i->key);
00322 if (type == DBUS_TYPE_STRING) {
00323 if (strcmp
00324 (ds_property_get_string (device, i->key),
00325 i->value) == 0 && ((!(i->only_gdl))
00326 || (i->only_gdl
00327 && device->in_gdl))) {
00328
00329
00330
00331
00332 data1 = i->data1;
00333 data2 = i->data2;
00334 callback = i->callback;
00335
00336
00337 if (prev != NULL) {
00338 prev->next = i->next;
00339 } else {
00340 async_find_outstanding_head =
00341 i->next;
00342 }
00343
00344
00345 free (i->key);
00346 free (i->value);
00347 free (i);
00348
00349
00350
00351
00352
00353
00354
00355 (*callback) (device, data1, data2);
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 goto check_list_again;
00374
00375 }
00376 }
00377 prev = i;
00378 }
00379 }
00380
00390 static void
00391 async_find_property_changed (HalDevice * device,
00392 const char *key,
00393 dbus_bool_t in_gdl,
00394 dbus_bool_t removed, dbus_bool_t added)
00395 {
00396 if (!removed)
00397 async_find_check_new_addition (device);
00398 }
00399
00400
00426 void
00427 ds_device_async_find_by_key_value_string (const char *key,
00428 const char *value,
00429 dbus_bool_t only_gdl,
00430 DSAsyncFindDeviceCB callback,
00431 void *data1,
00432 void *data2, int timeout)
00433 {
00434 HalDevice *device;
00435 DSDeviceAsyncFindStruct *afs;
00436
00437 assert (callback != NULL);
00438
00439
00440 device = ds_device_find_by_key_value_string (key, value, only_gdl);
00441 if (device != NULL) {
00442
00443 (*callback) (device, data1, data2);
00444 return;
00445 }
00446
00447 if (timeout == 0) {
00448 (*callback) (NULL, data1, data2);
00449 return;
00450 }
00451
00452
00453 afs = xmalloc (sizeof (DSDeviceAsyncFindStruct));
00454 afs->key = xstrdup (key);
00455 afs->value = xstrdup (value);
00456 afs->only_gdl = only_gdl;
00457 afs->callback = callback;
00458 afs->data1 = data1;
00459 afs->data2 = data2;
00460
00461
00462 afs->timeout_id = g_timeout_add (timeout,
00463 async_find_timeout_fn,
00464 (gpointer) afs);
00465
00466 afs->next = async_find_outstanding_head;
00467 async_find_outstanding_head = afs;
00468
00469 }
00470
00483 HalDevice **
00484 ds_device_find_multiple_by_key_value_string (const char *key,
00485 const char *value,
00486 dbus_bool_t only_gdl,
00487 int *num_results)
00488 {
00489 int type;
00490 int num_devices;
00491 HalDevice *device;
00492 HalDevice **devices;
00493 HalDeviceIterator iter_device;
00494
00498 devices = xmalloc (sizeof (HalDevice *) * 1024);
00499 num_devices = 0;
00500
00501 for (ds_device_iter_begin (&iter_device);
00502 ds_device_iter_has_more (&iter_device);
00503 ds_device_iter_next (&iter_device)) {
00504 device = ds_device_iter_get (&iter_device);
00505
00506 if (only_gdl && !device->in_gdl)
00507 continue;
00508
00509 type = ds_property_get_type (device, key);
00510 if (type == DBUS_TYPE_STRING) {
00511 if (strcmp (ds_property_get_string (device, key),
00512 value) == 0)
00513 devices[num_devices++] = device;
00514 }
00515 }
00516
00517 if (num_devices == 0) {
00518 free (devices);
00519 return NULL;
00520 } else {
00521 if (num_results != NULL)
00522 *num_results = num_devices;
00523 return devices;
00524 }
00525 }
00526
00537 HalDevice *
00538 ds_device_find_by_key_value_string (const char *key,
00539 const char *value,
00540 dbus_bool_t only_gdl)
00541 {
00542 int type;
00543 HalDevice *device;
00544 HalDeviceIterator iter_device;
00545
00546 for (ds_device_iter_begin (&iter_device);
00547 ds_device_iter_has_more (&iter_device);
00548 ds_device_iter_next (&iter_device)) {
00549 device = ds_device_iter_get (&iter_device);
00550
00551 if (only_gdl && !device->in_gdl)
00552 continue;
00553
00554 type = ds_property_get_type (device, key);
00555 if (type == DBUS_TYPE_STRING) {
00556 if (strcmp (ds_property_get_string (device, key),
00557 value) == 0)
00558 return device;
00559 }
00560 }
00561
00562 return NULL;
00563 }
00564
00571 HalDevice *
00572 ds_device_new ()
00573 {
00574 char buf[128];
00575 HalDevice *obj;
00576
00577 snprintf (buf, 128, "/org/freedesktop/Hal/devices/temp/%d",
00578 temp_device_counter++);
00579
00580 obj = (HalDevice *) xmalloc (sizeof (HalDevice));
00581
00582 obj->udi = xstrdup (buf);
00583 obj->in_gdl = FALSE;
00584 obj->num_properties = 0;
00585 obj->prop_head = NULL;
00586
00587 obj->prev = NULL;
00588 obj->next = device_list_head;
00589 if (obj->next != NULL)
00590 obj->next->prev = obj;
00591
00592 device_list_head = obj;
00593 device_list_num++;
00594
00595 return obj;
00596 }
00597
00603 void
00604 ds_device_destroy (HalDevice * device)
00605 {
00606 int i;
00607 HalProperty *prop;
00608 HalProperty *prop_next;
00609
00610 if (device->in_gdl) {
00611 for (i = 0; i < num_gdl_changed_cb; i++)
00612 (*(gdl_changed_cb[i])) (device, FALSE);
00613 }
00614
00615 if (device->next != NULL)
00616 device->next->prev = device->prev;
00617 if (device->prev != NULL)
00618 device->prev->next = device->next;
00619 if (device_list_head == device)
00620 device_list_head = device->next;
00621 --device_list_num;
00622
00623
00624 for (prop = device->prop_head; prop != NULL; prop = prop_next) {
00625 prop_next = prop->next;
00626 free (prop->key);
00627 if (prop->type == DBUS_TYPE_STRING)
00628 free (prop->str_value);
00629 free (prop);
00630 }
00631 free (device->udi);
00632 free (device);
00633 }
00634
00635
00636
00641 void
00642 ds_gdl_add (HalDevice * device)
00643 {
00644 int i;
00645 device->in_gdl = TRUE;
00646
00647 for (i = 0; i < num_gdl_changed_cb; i++)
00648 (*(gdl_changed_cb[i])) (device, TRUE);
00649
00650
00651
00652
00653 async_find_check_new_addition (device);
00654 }
00655
00660 unsigned int
00661 ds_device_size ()
00662 {
00663 return device_list_num;
00664 }
00665
00670 void
00671 ds_device_iter_begin (HalDeviceIterator * iterator)
00672 {
00673 iterator->position = 0;
00674 iterator->cursor = device_list_head;
00675 }
00676
00682 dbus_bool_t
00683 ds_device_iter_has_more (HalDeviceIterator * iterator)
00684 {
00685 return iterator->position < device_list_num;
00686 }
00687
00694 void
00695 ds_device_iter_next (HalDeviceIterator * iterator)
00696 {
00697 iterator->position++;
00698 iterator->cursor = iterator->cursor->next;
00699 }
00700
00706 HalDevice *
00707 ds_device_iter_get (HalDeviceIterator * iterator)
00708 {
00709 return iterator->cursor;
00710 }
00711
00712
00713
00719 const char *
00720 ds_device_get_udi (HalDevice * device)
00721 {
00722 return device->udi;
00723 }
00724
00732 dbus_bool_t
00733 ds_device_set_udi (HalDevice * device, const char *udi)
00734 {
00735 if (ds_device_find (udi) != NULL)
00736 return FALSE;
00737 free (device->udi);
00738 device->udi = xstrdup (udi);
00739 return TRUE;
00740 }
00741
00742
00743
00744
00750 unsigned int
00751 ds_properties_size (HalDevice * device)
00752 {
00753 return device->num_properties;
00754 }
00755
00762 dbus_bool_t
00763 ds_property_exists (HalDevice * device, const char *key)
00764 {
00765 return ds_property_find (device, key) != NULL;
00766 }
00767
00775 HalProperty *
00776 ds_property_find (HalDevice * device, const char *key)
00777 {
00778 HalProperty *prop;
00779
00780
00781 for (prop = device->prop_head; prop != NULL; prop = prop->next) {
00782 if (strcmp (prop->key, key) == 0) {
00783 return prop;
00784 }
00785 }
00786
00787 return NULL;
00788 }
00789
00795 void
00796 ds_property_iter_begin (HalDevice * device, HalPropertyIterator * iterator)
00797 {
00798 iterator->device = device;
00799 iterator->cursor = device->prop_head;
00800 }
00801
00807 dbus_bool_t
00808 ds_property_iter_has_more (HalPropertyIterator * iterator)
00809 {
00810 return iterator->cursor != NULL;
00811 }
00812
00817 void
00818 ds_property_iter_next (HalPropertyIterator * iterator)
00819 {
00820 iterator->cursor = iterator->cursor->next;
00821 }
00822
00828 HalProperty *
00829 ds_property_iter_get (HalPropertyIterator * iterator)
00830 {
00831 return iterator->cursor;
00832 }
00833
00842 dbus_bool_t
00843 ds_property_set_string (HalDevice * device, const char *key,
00844 const char *value)
00845 {
00846 int i;
00847 HalProperty *prop;
00848
00849
00850 for (prop = device->prop_head; prop != NULL; prop = prop->next) {
00851 if (strcmp (prop->key, key) == 0) {
00852 if (prop->type != DBUS_TYPE_STRING)
00853 return FALSE;
00854
00855
00856 if (value != NULL
00857 && strcmp (prop->str_value, value) == 0) {
00858 return TRUE;
00859 }
00860
00861 free (prop->str_value);
00862 prop->str_value = (char *) xstrdup (value);
00863
00864
00865 for (i = 0; i < num_property_changed_cb; i++)
00866 (*(property_changed_cb[i])) (device, key,
00867 device->
00868 in_gdl, FALSE,
00869 FALSE);
00870 return TRUE;
00871 }
00872 }
00873
00874
00875 prop = (HalProperty *) malloc (sizeof (HalProperty));
00876 if (prop == NULL)
00877 return FALSE;
00878 prop->key = (char *) xstrdup (key);
00879 prop->str_value = (char *) xstrdup (value);
00880
00881 prop->type = DBUS_TYPE_STRING;
00882
00883 prop->next = device->prop_head;
00884 prop->prev = NULL;
00885 device->prop_head = prop;
00886 device->num_properties++;
00887 if (prop->next != NULL)
00888 prop->next->prev = prop;
00889
00890
00891 for (i = 0; i < num_property_changed_cb; i++)
00892 (*(property_changed_cb[i])) (device, key, device->in_gdl,
00893 FALSE, TRUE);
00894
00895 return TRUE;
00896 }
00897
00906 dbus_bool_t
00907 ds_property_set_int (HalDevice * device, const char *key,
00908 dbus_int32_t value)
00909 {
00910 int i;
00911 HalProperty *prop;
00912
00913
00914 for (prop = device->prop_head; prop != NULL; prop = prop->next) {
00915 if (strcmp (prop->key, key) == 0) {
00916 if (prop->type != DBUS_TYPE_INT32)
00917 return FALSE;
00918
00919
00920 if (prop->int_value == value)
00921 return TRUE;
00922
00923 prop->int_value = value;
00924
00925
00926 for (i = 0; i < num_property_changed_cb; i++)
00927 (*(property_changed_cb[i])) (device, key,
00928 device->
00929 in_gdl, FALSE,
00930 FALSE);
00931 return TRUE;
00932 }
00933 }
00934
00935
00936 prop = (HalProperty *) malloc (sizeof (HalProperty));
00937 if (prop == NULL)
00938 return FALSE;
00939 prop->key = (char *) xstrdup (key);
00940 prop->int_value = value;
00941
00942 prop->type = DBUS_TYPE_INT32;
00943
00944 prop->next = device->prop_head;
00945 prop->prev = NULL;
00946 device->prop_head = prop;
00947 device->num_properties++;
00948 if (prop->next != NULL)
00949 prop->next->prev = prop;
00950
00951
00952 for (i = 0; i < num_property_changed_cb; i++)
00953 (*(property_changed_cb[i])) (device, key, device->in_gdl,
00954 FALSE, TRUE);
00955
00956 return TRUE;
00957 }
00958
00967 dbus_bool_t
00968 ds_property_set_bool (HalDevice * device, const char *key,
00969 dbus_bool_t value)
00970 {
00971 int i;
00972 HalProperty *prop;
00973
00974
00975 for (prop = device->prop_head; prop != NULL; prop = prop->next) {
00976 if (strcmp (prop->key, key) == 0) {
00977 if (prop->type != DBUS_TYPE_BOOLEAN)
00978 return FALSE;
00979
00980
00981 if (prop->bool_value == value)
00982 return TRUE;
00983
00984 prop->bool_value = value;
00985
00986
00987 for (i = 0; i < num_property_changed_cb; i++)
00988 (*(property_changed_cb[i])) (device, key,
00989 device->
00990 in_gdl, FALSE,
00991 FALSE);
00992 return TRUE;
00993 }
00994 }
00995
00996
00997 prop = (HalProperty *) malloc (sizeof (HalProperty));
00998 if (prop == NULL)
00999 return FALSE;
01000 prop->key = (char *) xstrdup (key);
01001 prop->bool_value = value;
01002
01003 prop->type = DBUS_TYPE_BOOLEAN;
01004
01005 prop->next = device->prop_head;
01006 prop->prev = NULL;
01007 device->prop_head = prop;
01008 device->num_properties++;
01009 if (prop->next != NULL)
01010 prop->next->prev = prop;
01011
01012
01013 for (i = 0; i < num_property_changed_cb; i++)
01014 (*(property_changed_cb[i])) (device, key, device->in_gdl,
01015 FALSE, TRUE);
01016
01017 return TRUE;
01018 }
01019
01028 dbus_bool_t
01029 ds_property_set_double (HalDevice * device, const char *key, double value)
01030 {
01031 int i;
01032 HalProperty *prop;
01033
01034
01035 for (prop = device->prop_head; prop != NULL; prop = prop->next) {
01036 if (strcmp (prop->key, key) == 0) {
01037 if (prop->type != DBUS_TYPE_DOUBLE)
01038 return FALSE;
01039
01040
01041 if (prop->double_value == value)
01042 return TRUE;
01043
01044 prop->double_value = value;
01045
01046
01047 for (i = 0; i < num_property_changed_cb; i++)
01048 (*(property_changed_cb[i])) (device, key,
01049 device->
01050 in_gdl, FALSE,
01051 FALSE);
01052 return TRUE;
01053 }
01054 }
01055
01056
01057 prop = (HalProperty *) malloc (sizeof (HalProperty));
01058 if (prop == NULL)
01059 return FALSE;
01060 prop->key = (char *) xstrdup (key);
01061 prop->double_value = value;
01062
01063 prop->type = DBUS_TYPE_DOUBLE;
01064
01065 prop->next = device->prop_head;
01066 prop->prev = NULL;
01067 device->prop_head = prop;
01068 device->num_properties++;
01069 if (prop->next != NULL)
01070 prop->next->prev = prop;
01071
01072
01073 for (i = 0; i < num_property_changed_cb; i++)
01074 (*(property_changed_cb[i])) (device, key, device->in_gdl,
01075 FALSE, TRUE);
01076
01077 return TRUE;
01078 }
01079
01086 dbus_bool_t
01087 ds_property_remove (HalDevice * device, const char *key)
01088 {
01089 int i;
01090 int j;
01091 HalProperty *prop;
01092
01093 i = 0;
01094
01095 for (prop = device->prop_head; prop != NULL;
01096 prop = prop->next, i++) {
01097 if (strcmp (prop->key, key) == 0) {
01098 switch (prop->type) {
01099 case DBUS_TYPE_STRING:
01100 free (prop->str_value);
01101 break;
01102 case DBUS_TYPE_INT32:
01103 break;
01104 case DBUS_TYPE_DOUBLE:
01105 break;
01106 case DBUS_TYPE_BOOLEAN:
01107 break;
01108 }
01109
01110 free (prop->key);
01111
01112 if (prop->prev == NULL) {
01113 device->prop_head = prop->next;
01114 if (prop->next != NULL)
01115 prop->next->prev = NULL;
01116 } else {
01117 prop->prev->next = prop->next;
01118 if (prop->next != NULL)
01119 prop->next->prev = prop->prev;
01120 }
01121 free (prop);
01122 device->num_properties--;
01123
01124 for (j = 0; j < num_property_changed_cb; j++)
01125 (*(property_changed_cb[j])) (device, key,
01126 device->
01127 in_gdl, TRUE,
01128 FALSE);
01129
01130 return TRUE;
01131 }
01132 }
01133
01134 return FALSE;
01135 }
01136
01137
01138
01144 const char *
01145 ds_property_iter_get_key (HalProperty * property)
01146 {
01147 return property->key;
01148 }
01149
01156 int
01157 ds_property_iter_get_type (HalProperty * property)
01158 {
01159 return property->type;
01160 }
01161
01162
01169 const char *
01170 ds_property_iter_get_string (HalProperty * property)
01171 {
01172 if (property->type != DBUS_TYPE_STRING)
01173 return NULL;
01174 return property->str_value;
01175 }
01176
01182 dbus_int32_t
01183 ds_property_iter_get_int (HalProperty * property)
01184 {
01185 return property->int_value;
01186 }
01187
01193 dbus_bool_t
01194 ds_property_iter_get_bool (HalProperty * property)
01195 {
01196 return property->bool_value;
01197 }
01198
01204 double
01205 ds_property_iter_get_double (HalProperty * property)
01206 {
01207 return property->double_value;
01208 }
01209
01220 void
01221 ds_device_merge (HalDevice * target, HalDevice * source)
01222 {
01223 const char *caps;
01224 HalPropertyIterator iter;
01225
01226 property_atomic_update_begin ();
01227
01228 for (ds_property_iter_begin (source, &iter);
01229 ds_property_iter_has_more (&iter);
01230 ds_property_iter_next (&iter)) {
01231 int type;
01232 int target_type;
01233 const char *key;
01234 HalProperty *p;
01235
01236 p = ds_property_iter_get (&iter);
01237 key = ds_property_iter_get_key (p);
01238 type = ds_property_iter_get_type (p);
01239
01240
01241 if (strcmp (key, "info.capabilities") == 0)
01242 continue;
01243
01244
01245 target_type = ds_property_get_type (target, key);
01246 if (target_type != DBUS_TYPE_NIL && target_type != type)
01247 ds_property_remove (target, key);
01248
01249 switch (type) {
01250 case DBUS_TYPE_STRING:
01251 ds_property_set_string (target, key,
01252 ds_property_iter_get_string
01253 (p));
01254 break;
01255 case DBUS_TYPE_INT32:
01256 ds_property_set_int (target, key,
01257 ds_property_iter_get_int (p));
01258 break;
01259 case DBUS_TYPE_DOUBLE:
01260 ds_property_set_double (target, key,
01261 ds_property_iter_get_double
01262 (p));
01263 break;
01264 case DBUS_TYPE_BOOLEAN:
01265 ds_property_set_bool (target, key,
01266 ds_property_iter_get_bool
01267 (p));
01268 break;
01269 default:
01270 HAL_WARNING (("Unknown property type %d", type));
01271 break;
01272 }
01273 }
01274
01275 property_atomic_update_end ();
01276
01277 caps = ds_property_get_string (source, "info.capabilities");
01278 if (caps != NULL) {
01279 int i;
01280 char *tok;
01281 char buf[256];
01282 char *bufp = buf;
01283
01284 tok = strtok_r ((char *) caps, " ", &bufp);
01285 while (tok != NULL) {
01286 if (!ds_query_capability (target, tok)) {
01287 ds_add_capability (target, tok);
01288 }
01289 tok = strtok_r (NULL, " ", &bufp);
01290 }
01291 }
01292
01293 }
01294
01303 int
01304 ds_property_get_type (HalDevice * device, const char *key)
01305 {
01306 HalProperty *prop;
01307
01308
01309 for (prop = device->prop_head; prop != NULL; prop = prop->next) {
01310 if (strcmp (prop->key, key) == 0) {
01311 return prop->type;
01312 }
01313 }
01314 return DBUS_TYPE_NIL;
01315 }
01316
01324 const char *
01325 ds_property_get_string (HalDevice * device, const char *key)
01326 {
01327 HalProperty *prop;
01328
01329
01330 for (prop = device->prop_head; prop != NULL; prop = prop->next) {
01331 if (strcmp (prop->key, key) == 0) {
01332 if (prop->type != DBUS_TYPE_STRING)
01333 return NULL;
01334 return prop->str_value;
01335 }
01336 }
01337 return NULL;
01338 }
01339
01346 dbus_int32_t
01347 ds_property_get_int (HalDevice * device, const char *key)
01348 {
01349 HalProperty *prop;
01350
01351
01352 for (prop = device->prop_head; prop != NULL; prop = prop->next) {
01353 if (strcmp (prop->key, key) == 0) {
01354 if (prop->type != DBUS_TYPE_INT32)
01355 return -1;
01356 return prop->int_value;
01357 }
01358 }
01359 return -1;
01360 }
01361
01368 dbus_bool_t
01369 ds_property_get_bool (HalDevice * device, const char *key)
01370 {
01371 HalProperty *prop;
01372
01373
01374 for (prop = device->prop_head; prop != NULL; prop = prop->next) {
01375 if (strcmp (prop->key, key) == 0) {
01376 if (prop->type != DBUS_TYPE_BOOLEAN)
01377 return -1;
01378 return prop->bool_value;
01379 }
01380 }
01381 return -1;
01382 }
01383
01390 double
01391 ds_property_get_double (HalDevice * device, const char *key)
01392 {
01393 HalProperty *prop;
01394
01395
01396 for (prop = device->prop_head; prop != NULL; prop = prop->next) {
01397 if (strcmp (prop->key, key) == 0) {
01398 if (prop->type != DBUS_TYPE_DOUBLE)
01399 return -1.0;
01400 return prop->double_value;
01401 }
01402 }
01403 return -1.0;
01404 }
01405
01406
01425 dbus_bool_t
01426 ds_device_matches (HalDevice * device1, HalDevice * device2,
01427 const char *namespace)
01428 {
01429 int len;
01430 HalPropertyIterator iter;
01431
01432 len = strlen (namespace);
01433
01434 for (ds_property_iter_begin (device1, &iter);
01435 ds_property_iter_has_more (&iter);
01436 ds_property_iter_next (&iter)) {
01437 int type;
01438 const char *key;
01439 HalProperty *p;
01440
01441 p = ds_property_iter_get (&iter);
01442 key = ds_property_iter_get_key (p);
01443 type = ds_property_iter_get_type (p);
01444
01445 if (strncmp (key, namespace, len) != 0)
01446 continue;
01447
01448 if (!ds_property_exists (device2, key))
01449 return FALSE;
01450
01451 switch (type) {
01452 case DBUS_TYPE_STRING:
01453 if (strcmp (ds_property_iter_get_string (p),
01454 ds_property_get_string (device2,
01455 key)) != 0)
01456 return FALSE;
01457 break;
01458 case DBUS_TYPE_INT32:
01459 if (ds_property_iter_get_int (p) !=
01460 ds_property_get_int (device2, key))
01461 return FALSE;
01462 break;
01463 case DBUS_TYPE_DOUBLE:
01464 if (ds_property_iter_get_double (p) !=
01465 ds_property_get_double (device2, key))
01466 return FALSE;
01467 break;
01468 case DBUS_TYPE_BOOLEAN:
01469 if (ds_property_iter_get_bool (p) !=
01470 ds_property_get_bool (device2, key))
01471 return FALSE;
01472 break;
01473 default:
01474 HAL_WARNING (("Unknown property type %d", type));
01475 break;
01476 }
01477 }
01478
01479 return TRUE;
01480 }
01481
01482
01484 #define MAX_CAP_SIZE 2048
01485
01491 void
01492 ds_add_capability (HalDevice * device, const char *capability)
01493 {
01494 int i;
01495 const char *caps;
01496 char buf[MAX_CAP_SIZE];
01497
01498 caps = ds_property_get_string (device, "info.capabilities");
01499 if (caps == NULL) {
01500 ds_property_set_string (device, "info.capabilities",
01501 capability);
01502 } else {
01503 if (ds_query_capability (device, capability)) {
01504 return;
01505 } else {
01506 snprintf (buf, MAX_CAP_SIZE, "%s %s", caps,
01507 capability);
01508 ds_property_set_string (device,
01509 "info.capabilities", buf);
01510 }
01511 }
01512
01513 for (i = 0; i < num_new_capability_cb; i++)
01514 (*(new_capability_cb[i])) (device, capability,
01515 device->in_gdl);
01516 }
01517
01525 dbus_bool_t
01526 ds_query_capability (HalDevice * device, const char *capability)
01527 {
01528 const char *caps_orig;
01529 char *caps;
01530 char buf[256];
01531 char *bufp = buf;
01532 char *c;
01533
01534 caps = NULL;
01535 caps_orig = ds_property_get_string (device, "info.capabilities");
01536 if (caps_orig != NULL) {
01537
01538 caps = xstrdup (caps_orig);
01539
01540 for (c = strtok_r (caps, " ", &bufp);
01541 c != NULL; c = strtok_r (NULL, " ", &bufp)) {
01542 if (strcmp (c, capability) == 0) {
01543 free (caps);
01544 return TRUE;
01545 }
01546 }
01547
01548 free (caps);
01549 }
01550 return FALSE;
01551 }
01552
01553