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