1*18c2aff7Sartem /***************************************************************************
2*18c2aff7Sartem * CVSID: $Id$
3*18c2aff7Sartem *
4*18c2aff7Sartem * device_store.c : HalDeviceStore methods
5*18c2aff7Sartem *
6*18c2aff7Sartem * Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
7*18c2aff7Sartem * Copyright (C) 2004 Novell, Inc.
8*18c2aff7Sartem *
9*18c2aff7Sartem * Licensed under the Academic Free License version 2.1
10*18c2aff7Sartem *
11*18c2aff7Sartem * This program is free software; you can redistribute it and/or modify
12*18c2aff7Sartem * it under the terms of the GNU General Public License as published by
13*18c2aff7Sartem * the Free Software Foundation; either version 2 of the License, or
14*18c2aff7Sartem * (at your option) any later version.
15*18c2aff7Sartem *
16*18c2aff7Sartem * This program is distributed in the hope that it will be useful,
17*18c2aff7Sartem * but WITHOUT ANY WARRANTY; without even the implied warranty of
18*18c2aff7Sartem * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19*18c2aff7Sartem * GNU General Public License for more details.
20*18c2aff7Sartem *
21*18c2aff7Sartem * You should have received a copy of the GNU General Public License
22*18c2aff7Sartem * along with this program; if not, write to the Free Software
23*18c2aff7Sartem * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24*18c2aff7Sartem *
25*18c2aff7Sartem **************************************************************************/
26*18c2aff7Sartem
27*18c2aff7Sartem #ifdef HAVE_CONFIG_H
28*18c2aff7Sartem # include <config.h>
29*18c2aff7Sartem #endif
30*18c2aff7Sartem
31*18c2aff7Sartem #include <stdio.h>
32*18c2aff7Sartem #include <string.h>
33*18c2aff7Sartem
34*18c2aff7Sartem #include "device_store.h"
35*18c2aff7Sartem #include "hald_marshal.h"
36*18c2aff7Sartem #include "logger.h"
37*18c2aff7Sartem
38*18c2aff7Sartem static GObjectClass *parent_class;
39*18c2aff7Sartem
40*18c2aff7Sartem enum {
41*18c2aff7Sartem STORE_CHANGED,
42*18c2aff7Sartem DEVICE_PROPERTY_CHANGED,
43*18c2aff7Sartem DEVICE_CAPABILITY_ADDED,
44*18c2aff7Sartem LAST_SIGNAL
45*18c2aff7Sartem };
46*18c2aff7Sartem
47*18c2aff7Sartem static guint signals[LAST_SIGNAL] = { 0 };
48*18c2aff7Sartem
49*18c2aff7Sartem static void
hal_device_store_finalize(GObject * obj)50*18c2aff7Sartem hal_device_store_finalize (GObject *obj)
51*18c2aff7Sartem {
52*18c2aff7Sartem HalDeviceStore *store = HAL_DEVICE_STORE (obj);
53*18c2aff7Sartem
54*18c2aff7Sartem g_slist_foreach (store->devices, (GFunc) g_object_unref, NULL);
55*18c2aff7Sartem
56*18c2aff7Sartem if (parent_class->finalize)
57*18c2aff7Sartem parent_class->finalize (obj);
58*18c2aff7Sartem }
59*18c2aff7Sartem
60*18c2aff7Sartem static void
hal_device_store_class_init(HalDeviceStoreClass * klass)61*18c2aff7Sartem hal_device_store_class_init (HalDeviceStoreClass *klass)
62*18c2aff7Sartem {
63*18c2aff7Sartem GObjectClass *obj_class = (GObjectClass *) klass;
64*18c2aff7Sartem
65*18c2aff7Sartem parent_class = g_type_class_peek_parent (klass);
66*18c2aff7Sartem
67*18c2aff7Sartem obj_class->finalize = hal_device_store_finalize;
68*18c2aff7Sartem
69*18c2aff7Sartem signals[STORE_CHANGED] =
70*18c2aff7Sartem g_signal_new ("store_changed",
71*18c2aff7Sartem G_TYPE_FROM_CLASS (klass),
72*18c2aff7Sartem G_SIGNAL_RUN_LAST,
73*18c2aff7Sartem G_STRUCT_OFFSET (HalDeviceStoreClass,
74*18c2aff7Sartem store_changed),
75*18c2aff7Sartem NULL, NULL,
76*18c2aff7Sartem hald_marshal_VOID__OBJECT_BOOL,
77*18c2aff7Sartem G_TYPE_NONE, 2,
78*18c2aff7Sartem G_TYPE_OBJECT,
79*18c2aff7Sartem G_TYPE_BOOLEAN);
80*18c2aff7Sartem
81*18c2aff7Sartem signals[DEVICE_PROPERTY_CHANGED] =
82*18c2aff7Sartem g_signal_new ("device_property_changed",
83*18c2aff7Sartem G_TYPE_FROM_CLASS (klass),
84*18c2aff7Sartem G_SIGNAL_RUN_LAST,
85*18c2aff7Sartem G_STRUCT_OFFSET (HalDeviceStoreClass,
86*18c2aff7Sartem device_property_changed),
87*18c2aff7Sartem NULL, NULL,
88*18c2aff7Sartem hald_marshal_VOID__OBJECT_STRING_BOOL_BOOL,
89*18c2aff7Sartem G_TYPE_NONE, 4,
90*18c2aff7Sartem G_TYPE_OBJECT,
91*18c2aff7Sartem G_TYPE_STRING,
92*18c2aff7Sartem G_TYPE_BOOLEAN,
93*18c2aff7Sartem G_TYPE_BOOLEAN);
94*18c2aff7Sartem
95*18c2aff7Sartem signals[DEVICE_CAPABILITY_ADDED] =
96*18c2aff7Sartem g_signal_new ("device_capability_added",
97*18c2aff7Sartem G_TYPE_FROM_CLASS (klass),
98*18c2aff7Sartem G_SIGNAL_RUN_LAST,
99*18c2aff7Sartem G_STRUCT_OFFSET (HalDeviceStoreClass,
100*18c2aff7Sartem device_capability_added),
101*18c2aff7Sartem NULL, NULL,
102*18c2aff7Sartem hald_marshal_VOID__OBJECT_STRING,
103*18c2aff7Sartem G_TYPE_NONE, 2,
104*18c2aff7Sartem G_TYPE_OBJECT,
105*18c2aff7Sartem G_TYPE_STRING);
106*18c2aff7Sartem }
107*18c2aff7Sartem
108*18c2aff7Sartem static void
hal_device_store_init(HalDeviceStore * device)109*18c2aff7Sartem hal_device_store_init (HalDeviceStore *device)
110*18c2aff7Sartem {
111*18c2aff7Sartem }
112*18c2aff7Sartem
113*18c2aff7Sartem GType
hal_device_store_get_type(void)114*18c2aff7Sartem hal_device_store_get_type (void)
115*18c2aff7Sartem {
116*18c2aff7Sartem static GType type = 0;
117*18c2aff7Sartem
118*18c2aff7Sartem if (!type) {
119*18c2aff7Sartem static GTypeInfo type_info = {
120*18c2aff7Sartem sizeof (HalDeviceStoreClass),
121*18c2aff7Sartem NULL, NULL,
122*18c2aff7Sartem (GClassInitFunc) hal_device_store_class_init,
123*18c2aff7Sartem NULL, NULL,
124*18c2aff7Sartem sizeof (HalDeviceStore),
125*18c2aff7Sartem 0,
126*18c2aff7Sartem (GInstanceInitFunc) hal_device_store_init
127*18c2aff7Sartem };
128*18c2aff7Sartem
129*18c2aff7Sartem type = g_type_register_static (G_TYPE_OBJECT,
130*18c2aff7Sartem "HalDeviceStore",
131*18c2aff7Sartem &type_info,
132*18c2aff7Sartem 0);
133*18c2aff7Sartem }
134*18c2aff7Sartem
135*18c2aff7Sartem return type;
136*18c2aff7Sartem }
137*18c2aff7Sartem
138*18c2aff7Sartem HalDeviceStore *
hal_device_store_new(void)139*18c2aff7Sartem hal_device_store_new (void)
140*18c2aff7Sartem {
141*18c2aff7Sartem HalDeviceStore *store;
142*18c2aff7Sartem
143*18c2aff7Sartem store = g_object_new (HAL_TYPE_DEVICE_STORE, NULL, NULL);
144*18c2aff7Sartem
145*18c2aff7Sartem return store;
146*18c2aff7Sartem }
147*18c2aff7Sartem
148*18c2aff7Sartem static void
emit_device_property_changed(HalDevice * device,const char * key,gboolean added,gboolean removed,gpointer data)149*18c2aff7Sartem emit_device_property_changed (HalDevice *device,
150*18c2aff7Sartem const char *key,
151*18c2aff7Sartem gboolean added,
152*18c2aff7Sartem gboolean removed,
153*18c2aff7Sartem gpointer data)
154*18c2aff7Sartem {
155*18c2aff7Sartem HalDeviceStore *store = HAL_DEVICE_STORE (data);
156*18c2aff7Sartem
157*18c2aff7Sartem g_signal_emit (store, signals[DEVICE_PROPERTY_CHANGED], 0,
158*18c2aff7Sartem device, key, added, removed);
159*18c2aff7Sartem }
160*18c2aff7Sartem
161*18c2aff7Sartem static void
emit_device_capability_added(HalDevice * device,const char * capability,gpointer data)162*18c2aff7Sartem emit_device_capability_added (HalDevice *device,
163*18c2aff7Sartem const char *capability,
164*18c2aff7Sartem gpointer data)
165*18c2aff7Sartem {
166*18c2aff7Sartem HalDeviceStore *store = HAL_DEVICE_STORE (data);
167*18c2aff7Sartem
168*18c2aff7Sartem g_signal_emit (store, signals[DEVICE_CAPABILITY_ADDED], 0,
169*18c2aff7Sartem device, capability);
170*18c2aff7Sartem }
171*18c2aff7Sartem
172*18c2aff7Sartem void
hal_device_store_add(HalDeviceStore * store,HalDevice * device)173*18c2aff7Sartem hal_device_store_add (HalDeviceStore *store, HalDevice *device)
174*18c2aff7Sartem {
175*18c2aff7Sartem const char buf[] = "/org/freedesktop/Hal/devices/";
176*18c2aff7Sartem
177*18c2aff7Sartem if (strncmp(device->udi, buf, sizeof (buf) - 1) != 0) {
178*18c2aff7Sartem
179*18c2aff7Sartem HAL_ERROR(("Can't add HalDevice with incorrect UDI. Valid "
180*18c2aff7Sartem "UDI must start with '/org/freedesktop/Hal/devices/'"));
181*18c2aff7Sartem goto out;
182*18c2aff7Sartem }
183*18c2aff7Sartem store->devices = g_slist_prepend (store->devices,
184*18c2aff7Sartem g_object_ref (device));
185*18c2aff7Sartem
186*18c2aff7Sartem g_signal_connect (device, "property_changed",
187*18c2aff7Sartem G_CALLBACK (emit_device_property_changed), store);
188*18c2aff7Sartem g_signal_connect (device, "capability_added",
189*18c2aff7Sartem G_CALLBACK (emit_device_capability_added), store);
190*18c2aff7Sartem
191*18c2aff7Sartem g_signal_emit (store, signals[STORE_CHANGED], 0, device, TRUE);
192*18c2aff7Sartem
193*18c2aff7Sartem out:
194*18c2aff7Sartem ;
195*18c2aff7Sartem }
196*18c2aff7Sartem
197*18c2aff7Sartem gboolean
hal_device_store_remove(HalDeviceStore * store,HalDevice * device)198*18c2aff7Sartem hal_device_store_remove (HalDeviceStore *store, HalDevice *device)
199*18c2aff7Sartem {
200*18c2aff7Sartem if (!g_slist_find (store->devices, device))
201*18c2aff7Sartem return FALSE;
202*18c2aff7Sartem
203*18c2aff7Sartem store->devices = g_slist_remove (store->devices, device);
204*18c2aff7Sartem
205*18c2aff7Sartem g_signal_handlers_disconnect_by_func (device,
206*18c2aff7Sartem (gpointer)emit_device_property_changed,
207*18c2aff7Sartem store);
208*18c2aff7Sartem g_signal_handlers_disconnect_by_func (device,
209*18c2aff7Sartem (gpointer)emit_device_capability_added,
210*18c2aff7Sartem store);
211*18c2aff7Sartem
212*18c2aff7Sartem g_signal_emit (store, signals[STORE_CHANGED], 0, device, FALSE);
213*18c2aff7Sartem
214*18c2aff7Sartem g_object_unref (device);
215*18c2aff7Sartem
216*18c2aff7Sartem return TRUE;
217*18c2aff7Sartem }
218*18c2aff7Sartem
219*18c2aff7Sartem HalDevice *
hal_device_store_find(HalDeviceStore * store,const char * udi)220*18c2aff7Sartem hal_device_store_find (HalDeviceStore *store, const char *udi)
221*18c2aff7Sartem {
222*18c2aff7Sartem GSList *iter;
223*18c2aff7Sartem
224*18c2aff7Sartem for (iter = store->devices; iter != NULL; iter = iter->next) {
225*18c2aff7Sartem HalDevice *d = iter->data;
226*18c2aff7Sartem
227*18c2aff7Sartem if (strcmp (hal_device_get_udi (d), udi) == 0)
228*18c2aff7Sartem return d;
229*18c2aff7Sartem }
230*18c2aff7Sartem
231*18c2aff7Sartem return NULL;
232*18c2aff7Sartem }
233*18c2aff7Sartem
234*18c2aff7Sartem void
hal_device_store_foreach(HalDeviceStore * store,HalDeviceStoreForeachFn callback,gpointer user_data)235*18c2aff7Sartem hal_device_store_foreach (HalDeviceStore *store,
236*18c2aff7Sartem HalDeviceStoreForeachFn callback,
237*18c2aff7Sartem gpointer user_data)
238*18c2aff7Sartem {
239*18c2aff7Sartem GSList *iter;
240*18c2aff7Sartem
241*18c2aff7Sartem g_return_if_fail (store != NULL);
242*18c2aff7Sartem g_return_if_fail (callback != NULL);
243*18c2aff7Sartem
244*18c2aff7Sartem for (iter = store->devices; iter != NULL; iter = iter->next) {
245*18c2aff7Sartem HalDevice *d = HAL_DEVICE (iter->data);
246*18c2aff7Sartem gboolean cont;
247*18c2aff7Sartem
248*18c2aff7Sartem cont = callback (store, d, user_data);
249*18c2aff7Sartem
250*18c2aff7Sartem if (cont == FALSE)
251*18c2aff7Sartem return;
252*18c2aff7Sartem }
253*18c2aff7Sartem }
254*18c2aff7Sartem
255*18c2aff7Sartem static gboolean
hal_device_store_print_foreach_fn(HalDeviceStore * store,HalDevice * device,gpointer user_data)256*18c2aff7Sartem hal_device_store_print_foreach_fn (HalDeviceStore *store,
257*18c2aff7Sartem HalDevice *device,
258*18c2aff7Sartem gpointer user_data)
259*18c2aff7Sartem {
260*18c2aff7Sartem fprintf (stderr, "----\n");
261*18c2aff7Sartem hal_device_print (device);
262*18c2aff7Sartem fprintf (stderr, "----\n");
263*18c2aff7Sartem return TRUE;
264*18c2aff7Sartem }
265*18c2aff7Sartem
266*18c2aff7Sartem void
hal_device_store_print(HalDeviceStore * store)267*18c2aff7Sartem hal_device_store_print (HalDeviceStore *store)
268*18c2aff7Sartem {
269*18c2aff7Sartem fprintf (stderr, "===============================================\n");
270*18c2aff7Sartem fprintf (stderr, "Dumping %d devices\n",
271*18c2aff7Sartem g_slist_length (store->devices));
272*18c2aff7Sartem fprintf (stderr, "===============================================\n");
273*18c2aff7Sartem hal_device_store_foreach (store,
274*18c2aff7Sartem hal_device_store_print_foreach_fn,
275*18c2aff7Sartem NULL);
276*18c2aff7Sartem fprintf (stderr, "===============================================\n");
277*18c2aff7Sartem }
278*18c2aff7Sartem
279*18c2aff7Sartem HalDevice *
hal_device_store_match_key_value_string(HalDeviceStore * store,const char * key,const char * value)280*18c2aff7Sartem hal_device_store_match_key_value_string (HalDeviceStore *store,
281*18c2aff7Sartem const char *key,
282*18c2aff7Sartem const char *value)
283*18c2aff7Sartem {
284*18c2aff7Sartem GSList *iter;
285*18c2aff7Sartem
286*18c2aff7Sartem g_return_val_if_fail (store != NULL, NULL);
287*18c2aff7Sartem g_return_val_if_fail (key != NULL, NULL);
288*18c2aff7Sartem g_return_val_if_fail (value != NULL, NULL);
289*18c2aff7Sartem
290*18c2aff7Sartem for (iter = store->devices; iter != NULL; iter = iter->next) {
291*18c2aff7Sartem HalDevice *d = HAL_DEVICE (iter->data);
292*18c2aff7Sartem int type;
293*18c2aff7Sartem
294*18c2aff7Sartem if (!hal_device_has_property (d, key))
295*18c2aff7Sartem continue;
296*18c2aff7Sartem
297*18c2aff7Sartem type = hal_device_property_get_type (d, key);
298*18c2aff7Sartem if (type != HAL_PROPERTY_TYPE_STRING)
299*18c2aff7Sartem continue;
300*18c2aff7Sartem
301*18c2aff7Sartem if (strcmp (hal_device_property_get_string (d, key),
302*18c2aff7Sartem value) == 0)
303*18c2aff7Sartem return d;
304*18c2aff7Sartem }
305*18c2aff7Sartem
306*18c2aff7Sartem return NULL;
307*18c2aff7Sartem }
308*18c2aff7Sartem
309*18c2aff7Sartem HalDevice *
hal_device_store_match_key_value_int(HalDeviceStore * store,const char * key,int value)310*18c2aff7Sartem hal_device_store_match_key_value_int (HalDeviceStore *store,
311*18c2aff7Sartem const char *key,
312*18c2aff7Sartem int value)
313*18c2aff7Sartem {
314*18c2aff7Sartem GSList *iter;
315*18c2aff7Sartem
316*18c2aff7Sartem g_return_val_if_fail (store != NULL, NULL);
317*18c2aff7Sartem g_return_val_if_fail (key != NULL, NULL);
318*18c2aff7Sartem
319*18c2aff7Sartem for (iter = store->devices; iter != NULL; iter = iter->next) {
320*18c2aff7Sartem HalDevice *d = HAL_DEVICE (iter->data);
321*18c2aff7Sartem int type;
322*18c2aff7Sartem
323*18c2aff7Sartem if (!hal_device_has_property (d, key))
324*18c2aff7Sartem continue;
325*18c2aff7Sartem
326*18c2aff7Sartem type = hal_device_property_get_type (d, key);
327*18c2aff7Sartem if (type != HAL_PROPERTY_TYPE_INT32)
328*18c2aff7Sartem continue;
329*18c2aff7Sartem
330*18c2aff7Sartem if (hal_device_property_get_int (d, key) == value)
331*18c2aff7Sartem return d;
332*18c2aff7Sartem }
333*18c2aff7Sartem
334*18c2aff7Sartem return NULL;
335*18c2aff7Sartem }
336*18c2aff7Sartem
337*18c2aff7Sartem GSList *
hal_device_store_match_multiple_key_value_string(HalDeviceStore * store,const char * key,const char * value)338*18c2aff7Sartem hal_device_store_match_multiple_key_value_string (HalDeviceStore *store,
339*18c2aff7Sartem const char *key,
340*18c2aff7Sartem const char *value)
341*18c2aff7Sartem {
342*18c2aff7Sartem GSList *iter;
343*18c2aff7Sartem GSList *matches = NULL;
344*18c2aff7Sartem
345*18c2aff7Sartem g_return_val_if_fail (store != NULL, NULL);
346*18c2aff7Sartem g_return_val_if_fail (key != NULL, NULL);
347*18c2aff7Sartem g_return_val_if_fail (value != NULL, NULL);
348*18c2aff7Sartem
349*18c2aff7Sartem for (iter = store->devices; iter != NULL; iter = iter->next) {
350*18c2aff7Sartem HalDevice *d = HAL_DEVICE (iter->data);
351*18c2aff7Sartem int type;
352*18c2aff7Sartem
353*18c2aff7Sartem if (!hal_device_has_property (d, key))
354*18c2aff7Sartem continue;
355*18c2aff7Sartem
356*18c2aff7Sartem type = hal_device_property_get_type (d, key);
357*18c2aff7Sartem if (type != HAL_PROPERTY_TYPE_STRING)
358*18c2aff7Sartem continue;
359*18c2aff7Sartem
360*18c2aff7Sartem if (strcmp (hal_device_property_get_string (d, key),
361*18c2aff7Sartem value) == 0)
362*18c2aff7Sartem matches = g_slist_prepend (matches, d);
363*18c2aff7Sartem }
364*18c2aff7Sartem
365*18c2aff7Sartem return matches;
366*18c2aff7Sartem }
367*18c2aff7Sartem
368*18c2aff7Sartem typedef struct {
369*18c2aff7Sartem HalDeviceStore *store;
370*18c2aff7Sartem char *key;
371*18c2aff7Sartem char *value;
372*18c2aff7Sartem HalDeviceStoreAsyncCallback callback;
373*18c2aff7Sartem gpointer user_data;
374*18c2aff7Sartem
375*18c2aff7Sartem guint prop_signal_id;
376*18c2aff7Sartem guint store_signal_id;
377*18c2aff7Sartem guint timeout_id;
378*18c2aff7Sartem } AsyncMatchInfo;
379*18c2aff7Sartem
380*18c2aff7Sartem static void
destroy_async_match_info(AsyncMatchInfo * info)381*18c2aff7Sartem destroy_async_match_info (AsyncMatchInfo *info)
382*18c2aff7Sartem {
383*18c2aff7Sartem g_object_unref (info->store);
384*18c2aff7Sartem
385*18c2aff7Sartem g_free (info->key);
386*18c2aff7Sartem g_free (info->value);
387*18c2aff7Sartem
388*18c2aff7Sartem g_signal_handler_disconnect (info->store, info->prop_signal_id);
389*18c2aff7Sartem g_signal_handler_disconnect (info->store, info->store_signal_id);
390*18c2aff7Sartem g_source_remove (info->timeout_id);
391*18c2aff7Sartem
392*18c2aff7Sartem g_free (info);
393*18c2aff7Sartem }
394*18c2aff7Sartem
395*18c2aff7Sartem static void
match_device_async(HalDeviceStore * store,HalDevice * device,const char * key,gboolean removed,gboolean added,gpointer user_data)396*18c2aff7Sartem match_device_async (HalDeviceStore *store, HalDevice *device,
397*18c2aff7Sartem const char *key, gboolean removed, gboolean added,
398*18c2aff7Sartem gpointer user_data)
399*18c2aff7Sartem {
400*18c2aff7Sartem AsyncMatchInfo *info = (AsyncMatchInfo *) user_data;
401*18c2aff7Sartem
402*18c2aff7Sartem /* Only want to do it for added or changed properties */
403*18c2aff7Sartem if (removed)
404*18c2aff7Sartem return;
405*18c2aff7Sartem
406*18c2aff7Sartem /* Keys have to match */
407*18c2aff7Sartem if (strcmp (info->key, key) != 0)
408*18c2aff7Sartem return;
409*18c2aff7Sartem
410*18c2aff7Sartem /* Values have to match */
411*18c2aff7Sartem if (strcmp (hal_device_property_get_string (device, key),
412*18c2aff7Sartem info->value) != 0)
413*18c2aff7Sartem return;
414*18c2aff7Sartem
415*18c2aff7Sartem info->callback (store, device, info->user_data);
416*18c2aff7Sartem
417*18c2aff7Sartem destroy_async_match_info (info);
418*18c2aff7Sartem }
419*18c2aff7Sartem
420*18c2aff7Sartem static void
store_changed(HalDeviceStore * store,HalDevice * device,gboolean added,gpointer user_data)421*18c2aff7Sartem store_changed (HalDeviceStore *store, HalDevice *device,
422*18c2aff7Sartem gboolean added, gpointer user_data)
423*18c2aff7Sartem {
424*18c2aff7Sartem AsyncMatchInfo *info = (AsyncMatchInfo *) user_data;
425*18c2aff7Sartem
426*18c2aff7Sartem if (!added)
427*18c2aff7Sartem return;
428*18c2aff7Sartem
429*18c2aff7Sartem if (!hal_device_has_property (device, info->key))
430*18c2aff7Sartem return;
431*18c2aff7Sartem
432*18c2aff7Sartem if (strcmp (hal_device_property_get_string (device, info->key),
433*18c2aff7Sartem info->value) != 0)
434*18c2aff7Sartem return;
435*18c2aff7Sartem
436*18c2aff7Sartem info->callback (store, device, info->user_data);
437*18c2aff7Sartem
438*18c2aff7Sartem destroy_async_match_info (info);
439*18c2aff7Sartem }
440*18c2aff7Sartem
441*18c2aff7Sartem static gboolean
match_device_async_timeout(gpointer user_data)442*18c2aff7Sartem match_device_async_timeout (gpointer user_data)
443*18c2aff7Sartem {
444*18c2aff7Sartem AsyncMatchInfo *info = (AsyncMatchInfo *) user_data;
445*18c2aff7Sartem
446*18c2aff7Sartem info->callback (info->store, NULL, info->user_data);
447*18c2aff7Sartem
448*18c2aff7Sartem destroy_async_match_info (info);
449*18c2aff7Sartem
450*18c2aff7Sartem return FALSE;
451*18c2aff7Sartem }
452*18c2aff7Sartem
453*18c2aff7Sartem void
hal_device_store_match_key_value_string_async(HalDeviceStore * store,const char * key,const char * value,HalDeviceStoreAsyncCallback callback,gpointer user_data,int timeout)454*18c2aff7Sartem hal_device_store_match_key_value_string_async (HalDeviceStore *store,
455*18c2aff7Sartem const char *key,
456*18c2aff7Sartem const char *value,
457*18c2aff7Sartem HalDeviceStoreAsyncCallback callback,
458*18c2aff7Sartem gpointer user_data,
459*18c2aff7Sartem int timeout)
460*18c2aff7Sartem {
461*18c2aff7Sartem HalDevice *device;
462*18c2aff7Sartem AsyncMatchInfo *info;
463*18c2aff7Sartem
464*18c2aff7Sartem /* First check to see if it's already there */
465*18c2aff7Sartem device = hal_device_store_match_key_value_string (store, key, value);
466*18c2aff7Sartem
467*18c2aff7Sartem if (device != NULL || timeout == 0) {
468*18c2aff7Sartem callback (store, device, user_data);
469*18c2aff7Sartem
470*18c2aff7Sartem return;
471*18c2aff7Sartem }
472*18c2aff7Sartem
473*18c2aff7Sartem info = g_new0 (AsyncMatchInfo, 1);
474*18c2aff7Sartem
475*18c2aff7Sartem info->store = g_object_ref (store);
476*18c2aff7Sartem info->key = g_strdup (key);
477*18c2aff7Sartem info->value = g_strdup (value);
478*18c2aff7Sartem info->callback = callback;
479*18c2aff7Sartem info->user_data = user_data;
480*18c2aff7Sartem
481*18c2aff7Sartem info->prop_signal_id = g_signal_connect (store,
482*18c2aff7Sartem "device_property_changed",
483*18c2aff7Sartem G_CALLBACK (match_device_async),
484*18c2aff7Sartem info);
485*18c2aff7Sartem info->store_signal_id = g_signal_connect (store,
486*18c2aff7Sartem "store_changed",
487*18c2aff7Sartem G_CALLBACK (store_changed),
488*18c2aff7Sartem info);
489*18c2aff7Sartem
490*18c2aff7Sartem info->timeout_id = g_timeout_add (timeout,
491*18c2aff7Sartem match_device_async_timeout,
492*18c2aff7Sartem info);
493*18c2aff7Sartem }
494