Fix:binding_dbus:Further cleanups
[navit-package] / navit / binding / dbus / binding_dbus.c
1 /**
2  * Navit, a modular navigation system.
3  * Copyright (C) 2005-2008 Navit Team
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19
20 #include <string.h>
21 #define DBUS_API_SUBJECT_TO_CHANGE
22 #include <dbus/dbus.h>
23 #include <dbus/dbus-glib.h>
24 #include <dbus/dbus-glib-lowlevel.h>
25 #include "config.h"
26 #include "config_.h"
27 #include "navit.h"
28 #include "coord.h"
29 #include "point.h"
30 #include "plugin.h"
31 #include "debug.h"
32 #include "item.h"
33 #include "attr.h"
34 #include "layout.h"
35 #include "command.h"
36 #include "callback.h"
37 #include "graphics.h"
38 #include "vehicle.h"
39 #include "map.h"
40 #include "mapset.h"
41 #include "util.h"
42
43
44 static DBusConnection *connection;
45 static dbus_uint32_t dbus_serial;
46
47 static char *service_name = "org.navit_project.navit";
48 static char *object_path = "/org/navit_project/navit";
49 char *navitintrospectxml_head1 = "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
50                                  "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
51                                  "<node name=\"";
52
53 char *navitintrospectxml_head2 = "\">\n"
54                                  "  <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
55                                  "    <method name=\"Introspect\">\n"
56                                  "      <arg direction=\"out\" type=\"s\" />\n"
57                                  "    </method>\n"
58                                  "  </interface>\n";
59
60
61
62 GHashTable *object_hash;
63 GHashTable *object_hash_rev;
64 GHashTable *object_count;
65
66 static char *
67 object_new(char *type, void *object)
68 {
69         int id;
70         char *ret;
71         dbg(0,"enter %s\n", type);
72         if ((ret=g_hash_table_lookup(object_hash_rev, object)))
73                 return ret;
74         id=GPOINTER_TO_INT(g_hash_table_lookup(object_count, type));
75         g_hash_table_insert(object_count, type, GINT_TO_POINTER((id+1)));
76         ret=g_strdup_printf("%s/%s/%d", object_path, type, id);
77         g_hash_table_insert(object_hash, ret, object);
78         g_hash_table_insert(object_hash_rev, object, ret);
79         dbg(0,"return %s\n", ret);
80         return (ret);
81 }
82
83 static void *
84 object_get(const char *path)
85 {
86         return g_hash_table_lookup(object_hash, path);
87 }
88
89 static void *
90 resolve_object(const char *opath, char *type)
91 {
92         char *prefix;
93         const char *oprefix;
94         void *ret=NULL;
95         char *def_navit="/default_navit";
96         char *def_graphics="/default_graphics";
97         char *def_vehicle="/default_vehicle";
98         char *def_mapset="/default_mapset";
99         char *def_map="/default_map";
100         struct attr attr;
101
102         if (strncmp(opath, object_path, strlen(object_path))) {
103                 dbg(0,"wrong object path %s\n",opath);
104                 return NULL;
105         }
106         prefix=g_strdup_printf("%s/%s/", object_path, type);
107         if (!strncmp(prefix, opath, strlen(prefix))) {
108                 ret=object_get(opath);
109                 g_free(prefix);
110                 return ret;
111         }
112         g_free(prefix);
113         oprefix=opath+strlen(object_path);
114         if (!strncmp(oprefix,def_navit,strlen(def_navit))) {
115                 oprefix+=strlen(def_navit);
116                 struct attr navit;
117                 if (!config_get_attr(config, attr_navit, &navit, NULL))
118                         return NULL;
119                 if (!oprefix[0]) {
120                         dbg(0,"default_navit\n");
121                         return navit.u.navit;
122                 }
123                 if (!strncmp(oprefix,def_graphics,strlen(def_graphics))) {
124                         if (navit_get_attr(navit.u.navit, attr_graphics, &attr, NULL)) {
125                                 return attr.u.graphics;
126                         }
127                         return NULL;
128                 }
129                 if (!strncmp(oprefix,def_vehicle,strlen(def_vehicle))) {
130                         if (navit_get_attr(navit.u.navit, attr_vehicle, &attr, NULL)) {
131                                 return attr.u.vehicle;
132                         }
133                         return NULL;
134                 }
135                 if (!strncmp(oprefix,def_mapset,strlen(def_mapset))) {
136                         oprefix+=strlen(def_mapset);
137                         if (navit_get_attr(navit.u.navit, attr_mapset, &attr, NULL)) {
138                                 if (!oprefix[0]) {
139                                         return attr.u.mapset;
140                                 }       
141                                 if (!strncmp(oprefix,def_map,strlen(def_map))) {
142                                         if (mapset_get_attr(attr.u.mapset, attr_map, &attr, NULL)) {
143                                                 return attr.u.map;
144                                         }
145                                         return NULL;
146                                 }
147                         }
148                         return NULL;
149                 }
150         }
151         return NULL;
152 }
153
154 static void *
155 object_get_from_message_arg(DBusMessageIter *iter, char *type)
156 {
157         char *opath;
158
159         if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_OBJECT_PATH)
160                 return NULL;
161         dbus_message_iter_get_basic(iter, &opath);
162         dbus_message_iter_next(iter);
163         return resolve_object(opath, type);
164 }
165
166 static void *
167 object_get_from_message(DBusMessage *message, char *type)
168 {
169         return resolve_object(dbus_message_get_path(message), type);
170 }
171
172 static enum attr_type 
173 attr_type_get_from_message(DBusMessageIter *iter)
174 {
175         char *attr_type;
176
177         if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_STRING) 
178                 return attr_none;
179         dbus_message_iter_get_basic(iter, &attr_type);
180         dbus_message_iter_next(iter);
181         return attr_from_name(attr_type); 
182 }
183
184 static int
185 encode_attr(DBusMessage *message, struct attr *attr)
186 {
187         char *name=attr_to_name(attr->type);
188         DBusMessageIter iter1,iter2;
189         dbus_message_iter_init_append(message, &iter1);
190         dbus_message_iter_append_basic(&iter1, DBUS_TYPE_STRING, &name);
191         if (attr->type >= attr_type_int_begin && attr->type < attr_type_boolean_begin) {
192                 dbus_message_iter_open_container(&iter1, DBUS_TYPE_VARIANT, DBUS_TYPE_INT32_AS_STRING, &iter2);
193                 dbus_message_iter_append_basic(&iter2, DBUS_TYPE_INT32, &attr->u.num);
194                 dbus_message_iter_close_container(&iter1, &iter2);
195         }
196         if (attr->type >= attr_type_boolean_begin && attr->type <= attr_type_int_end) {
197                 dbus_message_iter_open_container(&iter1, DBUS_TYPE_VARIANT, DBUS_TYPE_BOOLEAN_AS_STRING, &iter2);
198                 dbus_message_iter_append_basic(&iter2, DBUS_TYPE_BOOLEAN, &attr->u.num);
199                 dbus_message_iter_close_container(&iter1, &iter2);
200         }
201         if (attr->type >= attr_type_string_begin && attr->type <= attr_type_string_end) {
202                 dbus_message_iter_open_container(&iter1, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &iter2);
203                 dbus_message_iter_append_basic(&iter2, DBUS_TYPE_STRING, &attr->u.str);
204                 dbus_message_iter_close_container(&iter1, &iter2);
205         }
206         if (attr->type >= attr_type_object_begin && attr->type <= attr_type_object_end) {
207                 char *object=object_new(attr_to_name(attr->type), attr->u.data);
208                 dbus_message_iter_open_container(&iter1, DBUS_TYPE_VARIANT, DBUS_TYPE_OBJECT_PATH_AS_STRING, &iter2);
209                 dbus_message_iter_append_basic(&iter2, DBUS_TYPE_OBJECT_PATH, &object);
210                 dbus_message_iter_close_container(&iter1, &iter2);
211         }
212         return 1;
213 }
214
215
216 static DBusHandlerResult
217 empty_reply(DBusConnection *connection, DBusMessage *message)
218 {
219         DBusMessage *reply;
220
221         reply = dbus_message_new_method_return(message);
222         dbus_connection_send (connection, reply, NULL);
223         dbus_message_unref (reply);
224
225         return DBUS_HANDLER_RESULT_HANDLED;
226 }
227
228
229 static DBusHandlerResult
230 dbus_error(DBusConnection *connection, DBusMessage *message, char *error, char *msg)
231 {
232         DBusMessage *reply;
233
234         reply = dbus_message_new_error(message, error, msg);
235         dbus_connection_send (connection, reply, NULL);
236         dbus_message_unref (reply);
237         return DBUS_HANDLER_RESULT_HANDLED;
238 }
239
240 static DBusHandlerResult
241 dbus_error_invalid_attr_type(DBusConnection *connection, DBusMessage *message)
242 {
243         return dbus_error(connection, message, DBUS_ERROR_INVALID_ARGS, "attribute type invalid");
244 }
245
246 static DBusHandlerResult
247 dbus_error_invalid_parameter(DBusConnection *connection, DBusMessage *message)
248 {
249         return dbus_error(connection, message, DBUS_ERROR_INVALID_ARGS, "parameter invalid");
250 }
251
252 static DBusHandlerResult
253 dbus_error_invalid_object_path(DBusConnection *connection, DBusMessage *message)
254 {
255         return dbus_error(connection, message, DBUS_ERROR_BAD_ADDRESS, "object path invalid");
256 }
257
258 static DBusHandlerResult
259 dbus_error_invalid_object_path_parameter(DBusConnection *connection, DBusMessage *message)
260 {
261         return dbus_error(connection, message, DBUS_ERROR_BAD_ADDRESS, "object path parameter invalid");
262 }
263
264 /**
265  * Extracts a struct pcoord from a DBus message
266  *
267  * @param message The DBus message
268  * @param iter Sort of pointer that points on that (iii)-object in the message
269  * @param pc Pointer where the data should get stored
270  * @returns Returns 1 when everything went right, otherwise 0
271  */
272 static int
273 pcoord_get_from_message(DBusMessage *message, DBusMessageIter *iter, struct pcoord *pc)
274 {
275
276     if(!strcmp(dbus_message_iter_get_signature(iter), "s")) {
277         char *coordstring;
278
279         dbus_message_iter_get_basic(iter, &coordstring);
280         if(!pcoord_parse(coordstring, projection_mg, pc))
281             return 0;
282         
283         return 1;
284     } else {
285         
286         DBusMessageIter iter2;
287         dbus_message_iter_recurse(iter, &iter2);
288         if(!strcmp(dbus_message_iter_get_signature(iter), "(is)")) {
289             char *coordstring;
290             int projection;
291             
292             dbus_message_iter_get_basic(&iter2, &projection);
293
294             dbus_message_iter_next(&iter2);
295             dbus_message_iter_get_basic(&iter2, &coordstring);
296
297             if(!pcoord_parse(coordstring, projection, pc))
298                 return 0;
299
300             return 1;
301         } else if(!strcmp(dbus_message_iter_get_signature(iter), "(iii)")) {
302             
303             dbus_message_iter_get_basic(&iter2, &pc->pro);
304             
305             dbus_message_iter_next(&iter2);
306             dbus_message_iter_get_basic(&iter2, &pc->x);
307             
308             dbus_message_iter_next(&iter2);
309             dbus_message_iter_get_basic(&iter2, &pc->y);
310
311             return 1;
312         }
313     }
314     return 0;
315     
316 }
317
318 static int
319 decode_attr(DBusMessage *message, struct attr *attr)
320 {
321         DBusMessageIter iter, iterattr, iterstruct;
322         char *attr_type;
323         int ret=1;
324         double d;
325
326         dbus_message_iter_init(message, &iter);
327         dbus_message_iter_get_basic(&iter, &attr_type);
328         attr->type = attr_from_name(attr_type); 
329         dbg(0, "attr value: 0x%x string: %s\n", attr->type, attr_type);
330     
331         if (attr->type == attr_none)
332                 return 0;
333     
334         dbus_message_iter_next(&iter);
335         dbus_message_iter_recurse(&iter, &iterattr);
336         dbg(0, "seems valid. signature: %s\n", dbus_message_iter_get_signature(&iterattr));
337     
338         if (attr->type >= attr_type_item_begin && attr->type <= attr_type_item_end)
339                 return 0;
340
341         if (attr->type >= attr_type_int_begin && attr->type <= attr_type_boolean_begin) {
342                 if (dbus_message_iter_get_arg_type(&iterattr) == DBUS_TYPE_INT32) {
343                         dbus_message_iter_get_basic(&iterattr, &attr->u.num);
344                         return 1;
345                 }
346                 return 0;
347         }
348         if(attr->type >= attr_type_boolean_begin && attr->type <= attr_type_int_end) {
349                 if (dbus_message_iter_get_arg_type(&iterattr) == DBUS_TYPE_BOOLEAN) {
350                         dbus_message_iter_get_basic(&iterattr, &attr->u.num);
351                         return 1;
352                 }
353                 return 0;
354         }
355         if(attr->type >= attr_type_string_begin && attr->type <= attr_type_string_end) {
356                 if (dbus_message_iter_get_arg_type(&iterattr) == DBUS_TYPE_STRING) {
357                         dbus_message_iter_get_basic(&iterattr, &attr->u.str);
358                         return 1;
359                 }
360                 return 0;
361         }
362         if(attr->type >= attr_type_double_begin && attr->type <= attr_type_double_end) {
363                 if (dbus_message_iter_get_arg_type(&iterattr) == DBUS_TYPE_DOUBLE) {
364                         attr->u.numd=g_new(typeof(*attr->u.numd),1);
365                         dbus_message_iter_get_basic(&iterattr, attr->u.numd);
366                         return 1;
367                 }
368         }
369         if(attr->type >= attr_type_coord_geo_begin && attr->type <= attr_type_coord_geo_end) {
370                 if (dbus_message_iter_get_arg_type(&iterattr) == DBUS_TYPE_STRUCT) {
371                         attr->u.coord_geo=g_new(typeof(*attr->u.coord_geo),1);
372                         dbus_message_iter_recurse(&iterattr, &iterstruct);
373                         if (dbus_message_iter_get_arg_type(&iterstruct) == DBUS_TYPE_DOUBLE) {
374                                 dbus_message_iter_get_basic(&iterstruct, &d);
375                                 dbus_message_iter_next(&iterstruct);
376                                 attr->u.coord_geo->lng=d;
377                         } else
378                                 ret=0;
379                         if (dbus_message_iter_get_arg_type(&iterstruct) == DBUS_TYPE_DOUBLE) {
380                                 dbus_message_iter_get_basic(&iterstruct, &d);
381                                 attr->u.coord_geo->lat=d;
382                         } else
383                                 ret=0;
384                         if (!ret) {
385                                 g_free(attr->u.coord_geo);
386                                 attr->u.coord_geo=NULL;
387                         }
388                         return ret;
389                 }
390         }
391         return 0;
392 }
393
394 static void
395 destroy_attr(struct attr *attr)
396 {
397         if(attr->type > attr_type_double_begin && attr->type < attr_type_double_end) {
398                 g_free(attr->u.numd);
399         }
400 }
401
402 static char *
403 get_iter_name(char *type)
404 {
405         return g_strdup_printf("%s_attr_iter",type);
406 }
407
408 static DBusHandlerResult
409 request_attr_iter(DBusConnection *connection, DBusMessage *message, char *type, struct attr_iter *(*func)(void))
410 {
411         DBusMessage *reply;
412         char *iter_name;
413         char *opath;
414         struct attr_iter *attr_iter;
415
416         attr_iter=(*func)();
417         iter_name=get_iter_name(type);
418         opath=object_new(iter_name,attr_iter);
419         g_free(iter_name);
420         reply = dbus_message_new_method_return(message);
421         dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID);
422         dbus_connection_send (connection, reply, NULL);
423         dbus_message_unref (reply);
424
425         return DBUS_HANDLER_RESULT_HANDLED;
426 }
427
428 static DBusHandlerResult
429 request_attr_iter_destroy(DBusConnection *connection, DBusMessage *message, char *type, void (*func)(struct attr_iter *))
430 {
431         struct attr_iter *attr_iter;
432         DBusMessageIter iter;
433         char *iter_name;
434
435         dbus_message_iter_init(message, &iter);
436         iter_name=get_iter_name(type);
437         attr_iter=object_get_from_message_arg(&iter, iter_name);
438         g_free(iter_name);
439         if (! attr_iter)
440                 return dbus_error_invalid_object_path_parameter(connection, message);
441         func(attr_iter);
442
443         return empty_reply(connection, message);
444 }
445
446
447 static DBusHandlerResult
448 request_get_attr(DBusConnection *connection, DBusMessage *message, char *type, void *data, int (*func)(void *data, enum attr_type type, struct attr *attr, struct attr_iter *iter))
449 {
450         DBusMessage *reply;
451         DBusMessageIter iter;
452         struct attr attr;
453         enum attr_type attr_type;
454         struct attr_iter *attr_iter;
455         char *iter_name;
456
457         if (! data)
458                 data = object_get_from_message(message, type);
459         if (! data)
460                 return dbus_error_invalid_object_path(connection, message);
461
462         dbus_message_iter_init(message, &iter);
463         attr_type=attr_type_get_from_message(&iter);
464         if (attr_type == attr_none)
465                 return dbus_error_invalid_attr_type(connection, message);
466         iter_name=get_iter_name(type);  
467         attr_iter=object_get_from_message_arg(&iter, iter_name);
468         g_free(iter_name);
469         if (func(data, attr_type, &attr, attr_iter)) {
470                 reply = dbus_message_new_method_return(message);
471                 encode_attr(reply, &attr);
472                 dbus_connection_send (connection, reply, NULL);
473                 dbus_message_unref (reply);
474                 return DBUS_HANDLER_RESULT_HANDLED;
475         }
476         return empty_reply(connection, message);
477         
478 }
479
480 static DBusHandlerResult
481 request_set_attr(DBusConnection *connection, DBusMessage *message, char *type, void *data, int (*func)(void *data, struct attr *attr))
482 {
483         struct attr attr;
484         int ret;
485
486         if (! data)     
487                 data = object_get_from_message(message, type);
488         if (! data)
489                 return dbus_error_invalid_object_path(connection, message);
490
491         if (decode_attr(message, &attr)) {
492                 ret=(*func)(data, &attr);
493                 destroy_attr(&attr);
494                 if (ret)        
495                         return empty_reply(connection, message);
496         }
497         return dbus_error_invalid_parameter(connection, message);
498 }
499
500
501 /* config */
502 static DBusHandlerResult
503 request_config_get_attr(DBusConnection *connection, DBusMessage *message)
504 {
505         return request_get_attr(connection, message, "config", config, (int (*)(void *, enum attr_type, struct attr *, struct attr_iter *))config_get_attr);
506 }
507
508 static DBusHandlerResult
509 request_config_attr_iter(DBusConnection *connection, DBusMessage *message)
510 {
511         return request_attr_iter(connection, message, "config", (struct attr_iter * (*)(void))config_attr_iter_new);
512 }
513
514 static DBusHandlerResult
515 request_config_attr_iter_destroy(DBusConnection *connection, DBusMessage *message)
516 {
517         return request_attr_iter_destroy(connection, message, "config", (void (*)(struct attr_iter *))config_attr_iter_destroy);
518 }
519
520 /* graphics */
521
522 static DBusHandlerResult
523 request_graphics_get_data(DBusConnection *connection, DBusMessage *message)
524 {
525         struct graphics *graphics;
526         char *data;
527         struct graphics_data_image *image;
528         DBusMessage *reply;
529
530         graphics = object_get_from_message(message, "graphics");
531         if (! graphics)
532                 return dbus_error_invalid_object_path(connection, message);
533
534         if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &data, DBUS_TYPE_INVALID))
535                 return dbus_error_invalid_parameter(connection, message);
536         image=graphics_get_data(graphics, data);
537         if (image) {
538                 DBusMessageIter iter1,iter2;
539                 reply = dbus_message_new_method_return(message);
540 #if 0
541                 dbus_message_append_args(reply, DBUS_TYPE_STRING, &result, DBUS_TYPE_INVALID);
542 #endif
543                 dbus_message_iter_init_append(reply, &iter1);
544                 dbus_message_iter_open_container(&iter1, DBUS_TYPE_ARRAY, "y", &iter2);
545                 if (image->data && image->size) 
546                         dbus_message_iter_append_fixed_array(&iter2, DBUS_TYPE_BYTE, &image->data, image->size);
547                 dbus_message_iter_close_container(&iter1, &iter2);
548                 dbus_connection_send (connection, reply, NULL);
549                 dbus_message_unref (reply);
550                 return DBUS_HANDLER_RESULT_HANDLED;
551         }
552         return empty_reply(connection, message);
553 }
554
555 static DBusHandlerResult
556 request_graphics_set_attr(DBusConnection *connection, DBusMessage *message)
557 {
558         return request_set_attr(connection, message, "graphics", NULL, (int (*)(void *, struct attr *))graphics_set_attr);
559 }
560
561 /* map */
562
563 static DBusHandlerResult
564 request_map_get_attr(DBusConnection *connection, DBusMessage *message)
565 {
566         return request_get_attr(connection, message, "map", NULL, (int (*)(void *, enum attr_type, struct attr *, struct attr_iter *))map_get_attr);
567 }
568
569
570 static DBusHandlerResult
571 request_map_set_attr(DBusConnection *connection, DBusMessage *message)
572 {
573         return request_set_attr(connection, message, "map", NULL, (int (*)(void *, struct attr *))map_set_attr);
574 }
575
576 /* mapset */
577
578 static DBusHandlerResult
579 request_mapset_attr_iter(DBusConnection *connection, DBusMessage *message)
580 {
581         return request_attr_iter(connection, message, "mapset", (struct attr_iter * (*)(void))mapset_attr_iter_new);
582 }
583
584 static DBusHandlerResult
585 request_mapset_attr_iter_destroy(DBusConnection *connection, DBusMessage *message)
586 {
587         return request_attr_iter_destroy(connection, message, "mapset", (void (*)(struct attr_iter *))mapset_attr_iter_destroy);
588 }
589
590 static DBusHandlerResult
591 request_mapset_get_attr(DBusConnection *connection, DBusMessage *message)
592 {
593         return request_get_attr(connection, message, "mapset", NULL, (int (*)(void *, enum attr_type, struct attr *, struct attr_iter *))mapset_get_attr);
594 }
595
596 /* navit */
597
598 static DBusHandlerResult
599 request_navit_draw(DBusConnection *connection, DBusMessage *message)
600 {
601         struct navit *navit;
602
603         navit=object_get_from_message(message, "navit");
604         if (! navit)
605                 return dbus_error_invalid_object_path(connection, message);
606
607         navit_draw(navit);
608         
609         return empty_reply(connection, message);
610 }
611
612
613 /**
614  * Extracts a struct point from a DBus message
615  *
616  * @param message The DBus message
617  * @param iter Sort of pointer that points on that (ii)-object in the message
618  * @param p Pointer where the data should get stored
619  * @returns Returns 1 when everything went right, otherwise 0
620  */
621 static int
622 point_get_from_message(DBusMessage *message, DBusMessageIter *iter, struct point *p)
623 {
624         DBusMessageIter iter2;
625
626         dbg(0,"%s\n", dbus_message_iter_get_signature(iter));
627         
628         dbus_message_iter_recurse(iter, &iter2);
629
630         if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INT32)
631                 return 0;
632         dbus_message_iter_get_basic(&iter2, &p->x);
633         
634         dbus_message_iter_next(&iter2);
635         
636         if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INT32)
637                 return 0;
638         dbus_message_iter_get_basic(&iter2, &p->y);
639
640         dbg(0, " x -> %x  y -> %x\n", p->x, p->y);
641         
642         dbus_message_iter_next(&iter2);
643
644         if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INVALID)
645                 return 0;
646         
647         return 1;
648 }
649
650 /**
651  * @brief Shows up a message
652  * @param connection The DBusConnection object through which \a message arrived
653  * @param message The DBusMessage containing the coordinates
654  * @returns An empty reply if everything went right, otherwise DBUS_HANDLER_RESULT_NOT_YET_HANDLED
655  */
656
657 static DBusHandlerResult
658 request_navit_add_message(DBusConnection *connection, DBusMessage *message)
659 {
660         struct navit *navit;
661         char *usermessage;
662     
663     DBusMessageIter iter;
664
665         navit=object_get_from_message(message, "navit");
666         if (! navit)
667                 return dbus_error_invalid_object_path(connection, message);
668
669         dbus_message_iter_init(message, &iter);
670         dbus_message_iter_get_basic(&iter, &usermessage);
671         
672     navit_add_message(navit, usermessage);
673         
674     return empty_reply(connection, message);
675 }
676
677
678 /**
679  * @brief Centers the screen on a specified position \a pc on the world
680  * @param connection The DBusConnection object through which \a message arrived
681  * @param message The DBusMessage containing the coordinates
682  * @returns An empty reply if everything went right, otherwise DBUS_HANDLER_RESULT_NOT_YET_HANDLED
683  */
684
685 static DBusHandlerResult
686 request_navit_set_center(DBusConnection *connection, DBusMessage *message)
687 {
688         struct pcoord pc;
689         struct navit *navit;
690         DBusMessageIter iter;
691
692         navit=object_get_from_message(message, "navit");
693         if (! navit)
694                 return dbus_error_invalid_object_path(connection, message);
695
696         dbus_message_iter_init(message, &iter);
697
698         if (!pcoord_get_from_message(message, &iter, &pc))
699                 return dbus_error_invalid_parameter(connection, message);
700     
701         navit_set_center(navit, &pc, 0);
702         return empty_reply(connection, message);
703 }
704
705 /**
706  * @brief Centers the screen on a specified position \a p shown on the screen
707  * @param connection The DBusConnection object through which \a message arrived
708  * @param message The DBusMessage containing the x and y value
709  * @returns An empty reply if everything went right, otherwise DBUS_HANDLER_RESULT_NOT_YET_HANDLED
710  */
711 static DBusHandlerResult
712 request_navit_set_center_screen(DBusConnection *connection, DBusMessage *message)
713 {
714         struct point p;
715         struct navit *navit;
716         DBusMessageIter iter;
717
718         navit=object_get_from_message(message, "navit");
719         if (! navit)
720                 return dbus_error_invalid_object_path(connection, message);
721
722         dbus_message_iter_init(message, &iter);
723
724         if (!point_get_from_message(message, &iter, &p))
725                 return dbus_error_invalid_parameter(connection, message);
726         navit_set_center_screen(navit, &p, 0);
727         return empty_reply(connection, message);
728 }
729
730 /**
731  * @brief Sets the layout to \a new_layout_name extracted from \a message
732  * @param connection The DBusConnection object through which \a message arrived
733  * @param message The DBusMessage containing the name of the layout
734  * @returns An empty reply if everything went right, otherwise DBUS_HANDLER_RESULT_NOT_YET_HANDLED
735  */
736 static DBusHandlerResult
737 request_navit_set_layout(DBusConnection *connection, DBusMessage *message)
738 {
739         char *new_layout_name;
740         struct navit *navit;
741         struct attr attr;
742         struct attr_iter *iter;
743
744         navit=object_get_from_message(message, "navit");
745         if (! navit)
746                 return dbus_error_invalid_object_path(connection, message);
747         
748         if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &new_layout_name, DBUS_TYPE_INVALID))
749                 return dbus_error_invalid_parameter(connection, message);
750         
751         iter=navit_attr_iter_new();
752         while(navit_get_attr(navit, attr_layout, &attr, iter)) {
753                 if (strcmp(attr.u.layout->name, new_layout_name) == 0) {
754                         navit_set_attr(navit, &attr);
755                 }
756         }
757         return empty_reply(connection, message);
758 }
759
760 static DBusHandlerResult
761 request_navit_zoom(DBusConnection *connection, DBusMessage *message)
762 {
763         int factor;
764         struct point p;
765         struct navit *navit;
766         DBusMessageIter iter;
767
768         navit = object_get_from_message(message, "navit");
769         if (! navit)
770                 return dbus_error_invalid_object_path(connection, message);
771
772         dbus_message_iter_init(message, &iter);
773         dbg(0,"%s\n", dbus_message_iter_get_signature(&iter));
774         
775         dbus_message_iter_get_basic(&iter, &factor);
776         
777         if (dbus_message_iter_has_next(&iter))
778         {
779                 dbus_message_iter_next(&iter);
780                 if (!point_get_from_message(message, &iter, &p))
781                         return dbus_error_invalid_parameter(connection, message);
782         }
783
784         if (factor > 1)
785                 navit_zoom_in(navit, factor, &p);
786         else if (factor < -1)
787                 navit_zoom_out(navit, 0-factor, &p);
788
789         return empty_reply(connection, message);
790
791 }
792
793 static DBusHandlerResult
794 request_navit_resize(DBusConnection *connection, DBusMessage *message)
795 {
796         struct navit *navit;
797         int w, h;
798         DBusMessageIter iter;
799
800         navit = object_get_from_message(message, "navit");
801         if (! navit)
802                 return dbus_error_invalid_object_path(connection, message);
803
804         dbus_message_iter_init(message, &iter);
805         dbg(0,"%s\n", dbus_message_iter_get_signature(&iter));
806         
807         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32)
808                 return dbus_error_invalid_parameter(connection, message);
809         dbus_message_iter_get_basic(&iter, &w);
810         
811         dbus_message_iter_next(&iter);
812         
813         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32)
814                 return dbus_error_invalid_parameter(connection, message);
815         dbus_message_iter_get_basic(&iter, &h);
816
817         dbg(0, " w -> %i  h -> %i\n", w, h);
818         
819         navit_handle_resize(navit, w, h);
820
821         return empty_reply(connection, message);
822
823 }
824
825 static DBusHandlerResult
826 request_navit_get_attr(DBusConnection *connection, DBusMessage *message)
827 {
828         DBusMessage *reply;
829         DBusMessageIter iter;
830         struct attr attr;
831         enum attr_type attr_type;
832         struct attr_iter *attr_iter;
833         struct navit *navit;
834
835         navit = object_get_from_message(message, "navit");
836         if (! navit)
837                 return dbus_error_invalid_object_path(connection, message);
838
839         dbus_message_iter_init(message, &iter);
840         attr_type=attr_type_get_from_message(&iter);
841         if (attr_type == attr_none)
842                 return dbus_error_invalid_attr_type(connection, message);
843         attr_iter=object_get_from_message_arg(&iter, "navit_attr_iter");
844         if (navit_get_attr(navit, attr_type, &attr, attr_iter)) {
845                 reply = dbus_message_new_method_return(message);
846                 encode_attr(reply, &attr);
847                 dbus_connection_send (connection, reply, NULL);
848                 dbus_message_unref (reply);
849                 return DBUS_HANDLER_RESULT_HANDLED;
850         }
851         return empty_reply(connection, message);
852 }
853
854 static DBusHandlerResult
855 request_navit_attr_iter(DBusConnection *connection, DBusMessage *message)
856 {
857         DBusMessage *reply;
858         struct attr_iter *attr_iter=navit_attr_iter_new();
859         char *opath=object_new("navit_attr_iter",attr_iter);
860         reply = dbus_message_new_method_return(message);
861         dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID);
862         dbus_connection_send (connection, reply, NULL);
863         dbus_message_unref (reply);
864
865         return DBUS_HANDLER_RESULT_HANDLED;
866 }
867
868 static DBusHandlerResult
869 request_navit_attr_iter_destroy(DBusConnection *connection, DBusMessage *message)
870 {
871         struct attr_iter *attr_iter;
872         DBusMessageIter iter;
873
874         dbus_message_iter_init(message, &iter);
875         attr_iter=object_get_from_message_arg(&iter, "navit_attr_iter");
876         if (! attr_iter)
877                 return dbus_error_invalid_object_path_parameter(connection, message);
878         navit_attr_iter_destroy(attr_iter);
879
880         return empty_reply(connection, message);
881 }
882
883
884 static DBusHandlerResult
885 request_navit_set_attr(DBusConnection *connection, DBusMessage *message)
886 {
887         struct navit *navit;
888         struct attr attr;
889         int ret;
890
891         navit = object_get_from_message(message, "navit");
892         if (! navit)
893                 return dbus_error_invalid_object_path(connection, message);
894         if (decode_attr(message, &attr)) {
895                 ret=navit_set_attr(navit, &attr);
896                 destroy_attr(&attr);
897                 if (ret)
898                         return empty_reply(connection, message);
899         }
900         return dbus_error_invalid_parameter(connection, message);
901 }
902
903 static DBusHandlerResult
904 request_navit_set_position(DBusConnection *connection, DBusMessage *message)
905 {
906         struct pcoord pc;
907         struct navit *navit;
908         DBusMessageIter iter;
909
910         navit = object_get_from_message(message, "navit");
911         if (! navit)
912                 return dbus_error_invalid_object_path(connection, message);
913
914         dbus_message_iter_init(message, &iter);
915         if (!pcoord_get_from_message(message, &iter, &pc))
916                 return dbus_error_invalid_parameter(connection, message);
917         
918         navit_set_position(navit, &pc);
919         return empty_reply(connection, message);
920 }
921
922 static DBusHandlerResult
923 request_navit_set_destination(DBusConnection *connection, DBusMessage *message)
924 {
925         struct pcoord pc;
926         struct navit *navit;
927         DBusMessageIter iter;
928         char *description;
929
930         navit = object_get_from_message(message, "navit");
931         if (! navit)
932                 return dbus_error_invalid_object_path(connection, message);
933
934         dbus_message_iter_init(message, &iter);
935         if (!pcoord_get_from_message(message, &iter, &pc))
936                 return dbus_error_invalid_parameter(connection, message);
937         
938         dbus_message_iter_next(&iter);
939         dbus_message_iter_get_basic(&iter, &description);
940         dbg(0, " destination -> %s\n", description);
941         
942         navit_set_destination(navit, &pc, description, 1);
943         return empty_reply(connection, message);
944 }
945
946 static DBusHandlerResult
947 request_navit_evaluate(DBusConnection *connection, DBusMessage *message)
948 {
949         struct navit *navit;
950         char *command;
951         char *result;
952         struct attr attr;
953         DBusMessage *reply;
954         int *error;
955
956         navit = object_get_from_message(message, "navit");
957         if (! navit)
958                 return dbus_error_invalid_object_path(connection, message);
959
960         attr.type=attr_navit;
961         attr.u.navit=navit;
962         if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &command, DBUS_TYPE_INVALID))
963                 return dbus_error_invalid_parameter(connection, message);
964         result=command_evaluate_to_string(&attr, command, &error);
965         reply = dbus_message_new_method_return(message);
966         if (error)
967                 dbus_message_append_args(reply, DBUS_TYPE_INT32, error, DBUS_TYPE_INVALID);
968         else
969                 dbus_message_append_args(reply, DBUS_TYPE_STRING, &result, DBUS_TYPE_INVALID);
970         dbus_connection_send (connection, reply, NULL);
971         dbus_message_unref (reply);
972         return DBUS_HANDLER_RESULT_HANDLED;
973 }
974
975
976
977 /* vehicle */
978
979 static DBusHandlerResult
980 request_vehicle_set_attr(DBusConnection *connection, DBusMessage *message)
981 {
982         struct vehicle *vehicle;
983         struct attr attr;
984         int ret;
985         
986         vehicle = object_get_from_message(message, "vehicle");
987         if (! vehicle)
988                 return dbus_error_invalid_object_path(connection, message);
989         if (decode_attr(message, &attr)) {
990                 ret=vehicle_set_attr(vehicle, &attr);
991                 destroy_attr(&attr);
992                 if (ret)        
993                         return empty_reply(connection, message);
994         }
995         return dbus_error_invalid_parameter(connection, message);
996 }
997
998
999 struct dbus_method {
1000         char *path;
1001         char *method;
1002         char *signature;
1003     char *signature_name;
1004     char *response;
1005     char *response_name;
1006         DBusHandlerResult(*func)(DBusConnection *connection, DBusMessage *message);
1007 } dbus_methods[] = {
1008         {"",        "attr_iter",           "",        "",                                        "o",  "attr_iter",  request_config_attr_iter},
1009         {"",        "attr_iter_destroy",   "o",       "attr_iter",                               "",   "",      request_config_attr_iter_destroy},
1010         {"",        "get_attr",            "s",       "attrname",                                "sv", "attrname,value",request_config_get_attr},
1011         {"",        "get_attr_wi",         "so",      "attrname,attr_iter",                      "sv", "attrname,value",request_config_get_attr},
1012         {".graphics","get_data",           "s",       "type",                                    "ay",  "data", request_graphics_get_data},
1013         {".graphics","set_attr",           "sv",      "attribute,value",                         "",   "",      request_graphics_set_attr},
1014         {".navit",  "draw",                "",        "",                                        "",   "",      request_navit_draw},
1015         {".navit",  "add_message",         "s",       "message",                                 "",   "",      request_navit_add_message},
1016         {".navit",  "set_center",          "s",       "(coordinates)",                           "",   "",      request_navit_set_center},
1017         {".navit",  "set_center",          "(is)",    "(projection,coordinates)",                "",   "",      request_navit_set_center},
1018         {".navit",  "set_center",          "(iii)",   "(projection,longitude,latitude)",         "",   "",      request_navit_set_center},
1019         {".navit",  "set_center_screen",   "(ii)",    "(pixel_x,pixel_y)",                       "",   "",      request_navit_set_center_screen},
1020         {".navit",  "set_layout",          "s",       "layoutname",                              "",   "",      request_navit_set_layout},
1021         {".navit",  "zoom",                "i(ii)",   "factor(pixel_x,pixel_y)",                 "",   "",      request_navit_zoom},
1022         {".navit",  "zoom",                "i",       "factor",                                  "",   "",      request_navit_zoom},
1023         {".navit",  "resize",              "ii",      "upperleft,lowerright",                    "",   "",      request_navit_resize},
1024         {".navit",  "attr_iter",           "",        "",                                        "o",  "attr_iter",  request_navit_attr_iter},
1025         {".navit",  "attr_iter_destroy",   "o",       "attr_iter",                               "",   "",      request_navit_attr_iter_destroy},
1026         {".navit",  "get_attr",            "s",       "attribute",                               "sv",  "attrname,value", request_navit_get_attr},
1027         {".navit",  "get_attr_wi",         "so",      "attribute,attr_iter",                     "sv",  "attrname,value", request_navit_get_attr},
1028         {".navit",  "set_attr",            "sv",      "attribute,value",                         "",   "",      request_navit_set_attr},
1029         {".navit",  "set_position",        "s",       "(coordinates)",                           "",   "",      request_navit_set_position},
1030         {".navit",  "set_position",        "(is)",    "(projection,coordinated)",                "",   "",      request_navit_set_position},
1031         {".navit",  "set_position",        "(iii)",   "(projection,longitude,latitude)",         "",   "",      request_navit_set_position},
1032         {".navit",  "set_destination",     "ss",      "coordinates,comment",                     "",   "",      request_navit_set_destination},
1033         {".navit",  "set_destination",     "(is)s",   "(projection,coordinates)comment",         "",   "",      request_navit_set_destination},
1034         {".navit",  "set_destination",     "(iii)s",  "(projection,longitude,latitude)comment",  "",   "",      request_navit_set_destination},
1035         {".navit",  "evaluate",            "s",       "command",                                 "s",  "",      request_navit_evaluate},
1036         {".map",    "get_attr",            "s",       "attribute",                               "sv",  "attrname,value", request_map_get_attr},
1037         {".map",    "set_attr",            "sv",      "attribute,value",                         "",   "",      request_map_set_attr},
1038         {".mapset", "attr_iter",           "",        "",                                        "o",  "attr_iter",  request_mapset_attr_iter},
1039         {".mapset", "attr_iter_destroy",   "o",       "attr_iter",                               "",   "",      request_mapset_attr_iter_destroy},
1040         {".mapset", "get_attr",            "s",       "attribute",                               "sv",  "attrname,value", request_mapset_get_attr},
1041         {".mapset", "get_attr_wi",         "so",      "attribute,attr_iter",                     "sv",  "attrname,value", request_mapset_get_attr},
1042         {".vehicle","set_attr",            "sv",      "attribute,value",                         "",   "",      request_vehicle_set_attr},
1043 };
1044
1045 static char *
1046 introspect_path(const char *object)
1047 {
1048         char *ret;
1049         int i;
1050         char *def=".default_";
1051         int def_len=strlen(def);
1052         if (strncmp(object, object_path, strlen(object_path)))
1053                 return NULL;
1054         ret=g_strdup(object+strlen(object_path));
1055         dbg(0,"path=%s\n",ret);
1056         for (i = strlen(ret)-1 ; i >= 0 ; i--) {
1057                 if (ret[i] == '/' || (ret[i] >= '0' && ret[i] <= '9'))
1058                         ret[i]='\0';
1059                 else
1060                         break;
1061         }
1062         for (i = 0 ; i < strlen(ret); i++)
1063                 if (ret[i] == '/')
1064                         ret[i]='.';
1065         
1066         for (i = strlen(ret)-1 ; i >= 0 ; i--) {
1067                 if (!strncmp(ret+i, def, def_len)) {
1068                         memmove(ret+1,ret+i+def_len,strlen(ret+i+def_len)+1);
1069                         break;
1070                 }
1071         }
1072         return ret;
1073 }
1074
1075 static char *
1076 generate_navitintrospectxml(const char *object)
1077 {
1078     int i,methods_size,n=0;
1079     char *navitintrospectxml;
1080     char *path=introspect_path(object);
1081     if (!path)
1082         return NULL;
1083     dbg(0,"path=%s\n",path);
1084     
1085     // write header and make navit introspectable
1086     navitintrospectxml = g_strdup_printf("%s%s%s\n", navitintrospectxml_head1, object, navitintrospectxml_head2);
1087     
1088     methods_size=sizeof(dbus_methods)/sizeof(struct dbus_method);
1089     for (i = 0 ; i < methods_size ; i++) {
1090         // start new interface if it's the first method or it changed
1091         if (strcmp(dbus_methods[i].path, path))
1092                 continue;
1093         if ((n == 0) || strcmp(dbus_methods[i-1].path, dbus_methods[i].path))
1094             navitintrospectxml = g_strconcat_printf(navitintrospectxml, "  <interface name=\"%s%s\">\n", service_name, dbus_methods[i].path);
1095         n++;
1096         
1097         // start the new method
1098         navitintrospectxml = g_strconcat_printf(navitintrospectxml, "    <method name=\"%s\">\n", dbus_methods[i].method);
1099
1100         // set input signature if existent
1101         if (strcmp(dbus_methods[i].signature, ""))
1102             navitintrospectxml = g_strconcat_printf(navitintrospectxml, "      <arg direction=\"in\" name=\"%s\" type=\"%s\" />\n", dbus_methods[i].signature_name, dbus_methods[i].signature);
1103         
1104         // set response signature if existent
1105         if (strcmp(dbus_methods[i].response, ""))
1106             navitintrospectxml = g_strconcat_printf(navitintrospectxml, "      <arg direction=\"out\" name=\"%s\" type=\"%s\" />\n", dbus_methods[i].response_name, dbus_methods[i].response);
1107         
1108         // close the method
1109         navitintrospectxml = g_strconcat_printf(navitintrospectxml, "    </method>\n");
1110         
1111         // close the interface if we reached the last method or the interface changes
1112         if ((methods_size == i+1) || ((methods_size > i+1) && strcmp(dbus_methods[i+1].path, dbus_methods[i].path)))
1113             navitintrospectxml = g_strconcat_printf(navitintrospectxml, "  </interface>\n\n");
1114     }
1115     // close the "mother tag"
1116     navitintrospectxml = g_strconcat_printf(navitintrospectxml, "</node>\n");
1117     
1118     return navitintrospectxml;
1119 }
1120
1121 static DBusHandlerResult
1122 navit_handler_func(DBusConnection *connection, DBusMessage *message, void *user_data)
1123 {
1124         int i;
1125         char *path;
1126         dbg(0,"type=%s interface=%s path=%s member=%s signature=%s\n", dbus_message_type_to_string(dbus_message_get_type(message)), dbus_message_get_interface(message), dbus_message_get_path(message), dbus_message_get_member(message), dbus_message_get_signature(message));
1127         if (dbus_message_is_method_call (message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
1128                 DBusMessage *reply;
1129                 char *navitintrospectxml = generate_navitintrospectxml(dbus_message_get_path(message));
1130                 dbg(0,"Introspect %s:Result:%s\n",dbus_message_get_path(message), navitintrospectxml);
1131                 if (navitintrospectxml) {
1132                         reply = dbus_message_new_method_return(message);
1133                         dbus_message_append_args(reply, DBUS_TYPE_STRING, &navitintrospectxml, DBUS_TYPE_INVALID);
1134                         dbus_connection_send (connection, reply, NULL);
1135                         dbus_message_unref (reply);
1136                         g_free(navitintrospectxml);
1137                         return DBUS_HANDLER_RESULT_HANDLED;
1138                 }
1139                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1140         }
1141         
1142     for (i = 0 ; i < sizeof(dbus_methods)/sizeof(struct dbus_method) ; i++) {
1143                 path=g_strdup_printf("%s%s", service_name, dbus_methods[i].path);
1144                 if (dbus_message_is_method_call(message, path, dbus_methods[i].method) &&
1145                     dbus_message_has_signature(message, dbus_methods[i].signature)) {
1146                         g_free(path);
1147                         return dbus_methods[i].func(connection, message);
1148                 }
1149                 g_free(path);
1150         }
1151         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1152 }
1153
1154 static DBusObjectPathVTable dbus_navit_vtable = {
1155         NULL,
1156         navit_handler_func,
1157         NULL
1158 };
1159
1160 #if 0
1161 DBusHandlerResult
1162 filter(DBusConnection *connection, DBusMessage *message, void *user_data)
1163 {
1164         dbg(0,"type=%s interface=%s path=%s member=%s signature=%s\n", dbus_message_type_to_string(dbus_message_get_type(message)), dbus_message_get_interface(message), dbus_message_get_path(message), dbus_message_get_member(message), dbus_message_get_signature(message));
1165         if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
1166         }
1167         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1168 }
1169 #endif
1170
1171 static int
1172 dbus_cmd_send_signal(struct navit *navit, char *command, struct attr **in, struct attr ***out)
1173 {
1174         DBusMessage* msg;
1175         char *opath=object_new("navit",navit);
1176         char *interface=g_strdup_printf("%s%s", service_name, ".navit");
1177         dbg(0,"enter %s %s %s\n",opath,command,interface);
1178         msg = dbus_message_new_signal(opath, interface, "signal");
1179         if (msg) {
1180                 if (in && in[0]) {
1181                         encode_attr(msg, in[0]);
1182                 }
1183                 dbus_connection_send(connection, msg, &dbus_serial);
1184                 dbus_connection_flush(connection);
1185                 dbus_message_unref(msg);
1186         }
1187         g_free(interface);
1188         return 0;
1189 }
1190      
1191
1192 static struct command_table commands[] = {
1193         {"dbus_send_signal",command_cast(dbus_cmd_send_signal)},
1194 };
1195
1196
1197 static void
1198 dbus_main_navit(struct navit *navit, int added)
1199 {
1200         struct attr attr;
1201         if (added) {
1202                 command_add_table_attr(commands, sizeof(commands)/sizeof(struct command_table), navit, &attr);
1203                 navit_add_attr(navit, &attr);
1204         }
1205 }
1206
1207 void plugin_init(void)
1208 {
1209         DBusError error;
1210
1211         struct attr callback;
1212         object_hash=g_hash_table_new(g_str_hash, g_str_equal);
1213         object_hash_rev=g_hash_table_new(NULL, NULL);
1214         object_count=g_hash_table_new(g_str_hash, g_str_equal);
1215         dbg(0,"enter 1\n");
1216         dbus_error_init(&error);
1217         connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
1218         if (!connection) {
1219                 dbg(0,"Failed to open connection to session message bus: %s\n", error.message);
1220                 dbus_error_free(&error);
1221                 return;
1222         }
1223         dbus_connection_setup_with_g_main(connection, NULL);
1224 #if 0
1225         dbus_connection_add_filter(connection, filter, NULL, NULL);
1226         dbus_bus_add_match(connection, "type='signal',""interface='" DBUS_INTERFACE_DBUS  "'", &error);
1227 #endif
1228         dbus_connection_register_fallback(connection, object_path, &dbus_navit_vtable, NULL);
1229         dbus_bus_request_name(connection, service_name, 0, &error);
1230         if (dbus_error_is_set(&error)) {
1231                 dbg(0,"Failed to request name: %s", error.message);
1232                 dbus_error_free (&error);
1233         }
1234         callback.type=attr_callback;
1235         callback.u.callback=callback_new_0(callback_cast(dbus_main_navit));
1236         config_add_attr(config, &callback);
1237 }