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