2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team
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.
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.
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.
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>
38 static DBusConnection *connection;
40 static char *service_name = "org.navit_project.navit";
41 static char *object_path = "/org/navit_project/navit";
42 char *navitintrospectxml_head1 = "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
43 "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
46 char *navitintrospectxml_head2 = "\">\n"
47 " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
48 " <method name=\"Introspect\">\n"
49 " <arg direction=\"out\" type=\"s\" />\n"
55 GHashTable *object_hash;
56 GHashTable *object_count;
59 object_new(char *type, void *object)
63 dbg(0,"enter %s\n", type);
64 id=(int)g_hash_table_lookup(object_count, type);
65 g_hash_table_insert(object_count, type, (void *)(id+1));
66 ret=g_strdup_printf("%s/%s/%d", object_path, type, id);
67 g_hash_table_insert(object_hash, ret, object);
68 dbg(0,"return %s\n", ret);
73 object_get(const char *path)
75 return g_hash_table_lookup(object_hash, path);
79 object_get_from_message_arg(DBusMessage *message, char *type)
86 dbus_error_init(&error);
87 if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID)) {
88 dbus_error_free(&error);
89 dbg(0,"wrong arg type\n");
92 prefix=g_strdup_printf("%s/%s/", object_path, type);
93 if (!strncmp(prefix, opath, strlen(prefix)))
94 ret=object_get(opath);
96 dbg(0,"wrong object type\n");
102 object_get_from_message(DBusMessage *message, char *type)
104 const char *opath=dbus_message_get_path(message);
108 prefix=g_strdup_printf("%s/%s/", object_path, type);
109 if (!strncmp(prefix, opath, strlen(prefix)))
110 ret=object_get(opath);
112 dbg(0,"wrong object type\n");
117 static DBusHandlerResult
118 reply_simple_as_variant(DBusConnection *connection, DBusMessage *message, int value, int dbus_type)
122 reply = dbus_message_new_method_return(message);
123 dbus_message_append_args(reply,
126 dbus_connection_send (connection, reply, NULL);
127 dbus_message_unref (reply);
129 return DBUS_HANDLER_RESULT_HANDLED;
132 static DBusHandlerResult
133 empty_reply(DBusConnection *connection, DBusMessage *message)
137 reply = dbus_message_new_method_return(message);
138 dbus_connection_send (connection, reply, NULL);
139 dbus_message_unref (reply);
141 return DBUS_HANDLER_RESULT_HANDLED;
144 static DBusHandlerResult
145 request_main_get_navit(DBusConnection *connection, DBusMessage *message)
153 dbus_error_init(&error);
155 if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID)) {
156 dbg(0,"Error parsing\n");
157 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
159 dbg(0,"opath=%s\n", opath);
160 iter=object_get(opath);
161 navit=main_get_navit(iter);
163 reply = dbus_message_new_method_return(message);
164 opath=object_new("navit",navit);
165 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID);
166 dbus_connection_send (connection, reply, NULL);
167 dbus_message_unref (reply);
168 return DBUS_HANDLER_RESULT_HANDLED;
170 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
173 static DBusHandlerResult
174 request_main_iter(DBusConnection *connection, DBusMessage *message)
177 struct iter *iter=main_iter_new();
178 dbg(0,"iter=%p\n", iter);
179 char *opath=object_new("main_iter",iter);
180 reply = dbus_message_new_method_return(message);
181 dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID);
182 dbus_connection_send (connection, reply, NULL);
183 dbus_message_unref (reply);
185 return DBUS_HANDLER_RESULT_HANDLED;
188 static DBusHandlerResult
189 request_main_iter_destroy(DBusConnection *connection, DBusMessage *message)
193 iter=object_get_from_message_arg(message, "main_iter");
195 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
196 main_iter_destroy(iter);
198 return empty_reply(connection, message);
202 * Extracts a struct pcoord from a DBus message
204 * @param message The DBus message
205 * @param iter Sort of pointer that points on that (iii)-object in the message
206 * @param pc Pointer where the data should get stored
207 * @returns Returns 1 when everything went right, otherwise 0
210 pcoord_get_from_message(DBusMessage *message, DBusMessageIter *iter, struct pcoord *pc)
213 if(!strcmp(dbus_message_iter_get_signature(iter), "s")) {
216 dbus_message_iter_get_basic(iter, &coordstring);
217 if(!pcoord_parse(coordstring, projection_mg, pc))
223 DBusMessageIter iter2;
224 dbus_message_iter_recurse(iter, &iter2);
225 if(!strcmp(dbus_message_iter_get_signature(iter), "(is)")) {
229 dbus_message_iter_get_basic(&iter2, &projection);
231 dbus_message_iter_next(&iter2);
232 dbus_message_iter_get_basic(&iter2, &coordstring);
234 if(!pcoord_parse(coordstring, projection, pc))
238 } else if(!strcmp(dbus_message_iter_get_signature(iter), "(iii)")) {
240 dbus_message_iter_get_basic(&iter2, &pc->pro);
242 dbus_message_iter_next(&iter2);
243 dbus_message_iter_get_basic(&iter2, &pc->x);
245 dbus_message_iter_next(&iter2);
246 dbus_message_iter_get_basic(&iter2, &pc->y);
255 static DBusHandlerResult
256 request_navit_draw(DBusConnection *connection, DBusMessage *message)
260 navit=object_get_from_message(message, "navit");
262 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
266 return empty_reply(connection, message);
271 * Extracts a struct point from a DBus message
273 * @param message The DBus message
274 * @param iter Sort of pointer that points on that (ii)-object in the message
275 * @param p Pointer where the data should get stored
276 * @returns Returns 1 when everything went right, otherwise 0
279 point_get_from_message(DBusMessage *message, DBusMessageIter *iter, struct point *p)
281 DBusMessageIter iter2;
283 dbg(0,"%s\n", dbus_message_iter_get_signature(iter));
285 dbus_message_iter_recurse(iter, &iter2);
287 if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INT32)
289 dbus_message_iter_get_basic(&iter2, &p->x);
291 dbus_message_iter_next(&iter2);
293 if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INT32)
295 dbus_message_iter_get_basic(&iter2, &p->y);
297 dbg(0, " x -> %x y -> %x\n", p->x, p->y);
299 dbus_message_iter_next(&iter2);
301 if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INVALID)
308 * @brief Shows up a message
309 * @param connection The DBusConnection object through which \a message arrived
310 * @param message The DBusMessage containing the coordinates
311 * @returns An empty reply if everything went right, otherwise DBUS_HANDLER_RESULT_NOT_YET_HANDLED
314 static DBusHandlerResult
315 request_navit_add_message(DBusConnection *connection, DBusMessage *message)
320 DBusMessageIter iter;
322 navit=object_get_from_message(message, "navit");
324 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
326 dbus_message_iter_init(message, &iter);
327 dbus_message_iter_get_basic(&iter, &usermessage);
329 navit_add_message(navit, usermessage);
331 return empty_reply(connection, message);
336 * @brief Centers the screen on a specified position \a pc on the world
337 * @param connection The DBusConnection object through which \a message arrived
338 * @param message The DBusMessage containing the coordinates
339 * @returns An empty reply if everything went right, otherwise DBUS_HANDLER_RESULT_NOT_YET_HANDLED
342 static DBusHandlerResult
343 request_navit_set_center(DBusConnection *connection, DBusMessage *message)
347 DBusMessageIter iter;
349 navit=object_get_from_message(message, "navit");
351 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
353 dbus_message_iter_init(message, &iter);
355 if (!pcoord_get_from_message(message, &iter, &pc))
356 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
358 navit_set_center(navit, &pc);
359 return empty_reply(connection, message);
363 * @brief Centers the screen on a specified position \a p shown on the screen
364 * @param connection The DBusConnection object through which \a message arrived
365 * @param message The DBusMessage containing the x and y value
366 * @returns An empty reply if everything went right, otherwise DBUS_HANDLER_RESULT_NOT_YET_HANDLED
368 static DBusHandlerResult
369 request_navit_set_center_screen(DBusConnection *connection, DBusMessage *message)
373 DBusMessageIter iter;
375 navit=object_get_from_message(message, "navit");
377 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
379 dbus_message_iter_init(message, &iter);
381 if (!point_get_from_message(message, &iter, &p))
382 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
383 navit_set_center_screen(navit, &p);
384 return empty_reply(connection, message);
388 * @brief Sets the layout to \a new_layout_name extracted from \a message
389 * @param connection The DBusConnection object through which \a message arrived
390 * @param message The DBusMessage containing the name of the layout
391 * @returns An empty reply if everything went right, otherwise DBUS_HANDLER_RESULT_NOT_YET_HANDLED
393 static DBusHandlerResult
394 request_navit_set_layout(DBusConnection *connection, DBusMessage *message)
396 char *new_layout_name;
399 struct attr_iter *iter;
401 navit=object_get_from_message(message, "navit");
403 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
405 if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &new_layout_name, DBUS_TYPE_INVALID))
406 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
408 iter=navit_attr_iter_new();
409 while(navit_get_attr(navit, attr_layout, &attr, iter)) {
410 if (strcmp(attr.u.layout->name, new_layout_name) == 0) {
411 navit_set_attr(navit, &attr);
414 return empty_reply(connection, message);
417 static DBusHandlerResult
418 request_navit_zoom(DBusConnection *connection, DBusMessage *message)
421 struct point *p = NULL;
423 DBusMessageIter iter;
425 navit = object_get_from_message(message, "navit");
427 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
429 dbus_message_iter_init(message, &iter);
430 dbg(0,"%s\n", dbus_message_iter_get_signature(&iter));
432 dbus_message_iter_get_basic(&iter, &factor);
434 if (dbus_message_iter_has_next(&iter))
436 dbus_message_iter_next(&iter);
437 if (!point_get_from_message(message, &iter, p))
438 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
442 navit_zoom_in(navit, factor, p);
443 else if (factor < -1)
444 navit_zoom_out(navit, 0-factor, p);
446 return empty_reply(connection, message);
450 static DBusHandlerResult
451 request_navit_resize(DBusConnection *connection, DBusMessage *message)
455 DBusMessageIter iter;
457 navit = object_get_from_message(message, "navit");
459 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
461 dbus_message_iter_init(message, &iter);
462 dbg(0,"%s\n", dbus_message_iter_get_signature(&iter));
464 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32)
465 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
466 dbus_message_iter_get_basic(&iter, &w);
468 dbus_message_iter_next(&iter);
470 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT32)
471 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
472 dbus_message_iter_get_basic(&iter, &h);
474 dbg(0, " w -> %i h -> %i\n", w, h);
476 navit_handle_resize(navit, w, h);
478 return empty_reply(connection, message);
482 static DBusHandlerResult
483 request_navit_get_attr(DBusConnection *connection, DBusMessage *message)
486 DBusMessageIter iter, response;
487 char * attr_type = NULL;
489 navit = object_get_from_message(message, "navit");
491 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
493 dbus_message_iter_init(message, &iter);
494 dbus_message_iter_get_basic(&iter, &attr_type);
495 attr.type = attr_from_name(attr_type);
496 dbg(0, "attr value: 0x%x string: %s\n", attr.type, attr_type);
498 if (attr.type == attr_none)
499 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
501 if (attr.type > attr_type_item_begin && attr.type < attr_type_item_end)
502 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
504 else if (attr.type > attr_type_int_begin && attr.type < attr_type_boolean_begin)
506 dbg(0, "int detected\n");
507 if(navit_get_attr(navit, attr.type, &attr, NULL)) {
508 dbg(0, "%s = %i\n", attr_type, attr.u.num);
509 return reply_simple_as_variant(connection, message, attr.u.num, DBUS_TYPE_INT32);
513 else if(attr.type > attr_type_boolean_begin && attr.type < attr_type_int_end)
515 dbg(0, "bool detected\n");
516 if(navit_get_attr(navit, attr.type, &attr, NULL)) {
517 dbg(0, "%s = %i\n", attr_type, attr.u.num);
518 return reply_simple_as_variant(connection, message, attr.u.num, DBUS_TYPE_BOOLEAN);
522 else if(attr.type > attr_type_string_begin && attr.type < attr_type_string_end)
524 dbg(0, "string detected\n");
525 if(navit_get_attr(navit, attr.type, &attr, NULL)) {
526 dbg(0, "%s = %s\n", attr_type, &attr.u.layout);
527 return reply_simple_as_variant(connection, message, &attr.u.layout, DBUS_TYPE_STRING);
532 else if(attr.type > attr_type_special_begin && attr.type < attr_type_special_end)
533 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
535 else if(attr.type > attr_type_double_begin && attr.type < attr_type_double_end)
536 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
538 else if(attr.type > attr_type_coord_geo_begin && attr.type < attr_type_coord_geo_end)
539 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
541 else if(attr.type > attr_type_color_begin && attr.type < attr_type_color_end)
542 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
544 else if(attr.type > attr_type_object_begin && attr.type < attr_type_object_end)
545 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
547 else if(attr.type > attr_type_coord_begin && attr.type < attr_type_coord_end)
548 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
550 else if(attr.type > attr_type_pcoord_begin && attr.type < attr_type_pcoord_end)
551 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
553 else if(attr.type > attr_type_callback_begin && attr.type < attr_type_callback_end)
554 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
557 dbg(0, "zomg really unhandled111\n");
558 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
561 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
565 static DBusHandlerResult
566 request_navit_set_attr(DBusConnection *connection, DBusMessage *message)
569 DBusMessageIter iter, iterattr;
573 navit = object_get_from_message(message, "navit");
575 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
577 dbus_message_iter_init(message, &iter);
578 dbus_message_iter_get_basic(&iter, &attr_type);
579 attr.type = attr_from_name(attr_type);
580 dbg(0, "attr value: 0x%x string: %s\n", attr.type, attr_type);
582 if (attr.type == attr_none)
583 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
585 dbus_message_iter_next(&iter);
586 dbus_message_iter_recurse(&iter, &iterattr);
587 dbg(0, "seems valid. signature: %s\n", dbus_message_iter_get_signature(&iterattr));
589 if (attr.type > attr_type_item_begin && attr.type < attr_type_item_end)
590 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
592 else if (attr.type > attr_type_int_begin && attr.type < attr_type_boolean_begin)
593 if (dbus_message_iter_get_arg_type(&iterattr) == DBUS_TYPE_INT32)
595 dbus_message_iter_get_basic(&iterattr, &attr.u.num);
596 if (navit_set_attr(navit, &attr))
597 return empty_reply(connection, message);
600 else if(attr.type > attr_type_boolean_begin && attr.type < attr_type_int_end)
601 if (dbus_message_iter_get_arg_type(&iterattr) == DBUS_TYPE_BOOLEAN)
603 dbus_message_iter_get_basic(&iterattr, &attr.u.num);
604 if (navit_set_attr(navit, &attr))
605 return empty_reply(connection, message);
609 else if(attr.type > attr_type_string_begin && attr.type < attr_type_string_end)
610 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
612 else if(attr.type > attr_type_special_begin && attr.type < attr_type_special_end)
613 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
615 else if(attr.type > attr_type_double_begin && attr.type < attr_type_double_end)
616 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
618 else if(attr.type > attr_type_coord_geo_begin && attr.type < attr_type_coord_geo_end)
619 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
621 else if(attr.type > attr_type_color_begin && attr.type < attr_type_color_end)
622 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
624 else if(attr.type > attr_type_object_begin && attr.type < attr_type_object_end)
625 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
627 else if(attr.type > attr_type_coord_begin && attr.type < attr_type_coord_end)
628 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
630 else if(attr.type > attr_type_pcoord_begin && attr.type < attr_type_pcoord_end)
631 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
633 else if(attr.type > attr_type_callback_begin && attr.type < attr_type_callback_end)
634 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
637 dbg(0, "zomg really unhandled111\n");
638 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
641 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
644 static DBusHandlerResult
645 request_navit_set_position(DBusConnection *connection, DBusMessage *message)
649 DBusMessageIter iter;
651 navit = object_get_from_message(message, "navit");
653 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
655 dbus_message_iter_init(message, &iter);
656 if (!pcoord_get_from_message(message, &iter, &pc))
657 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
659 navit_set_position(navit, &pc);
660 return empty_reply(connection, message);
663 static DBusHandlerResult
664 request_navit_set_destination(DBusConnection *connection, DBusMessage *message)
668 DBusMessageIter iter;
671 navit = object_get_from_message(message, "navit");
673 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
675 dbus_message_iter_init(message, &iter);
676 if (!pcoord_get_from_message(message, &iter, &pc))
677 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
679 dbus_message_iter_next(&iter);
680 dbus_message_iter_get_basic(&iter, &description);
681 dbg(0, " destination -> %s\n", description);
683 navit_set_destination(navit, &pc, description);
684 return empty_reply(connection, message);
687 static DBusHandlerResult
688 request_navit_evaluate(DBusConnection *connection, DBusMessage *message)
698 navit = object_get_from_message(message, "navit");
700 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
702 attr.type=attr_navit;
704 if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &command, DBUS_TYPE_INVALID))
705 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
706 result=command_evaluate_to_string(&attr, command, &error);
707 reply = dbus_message_new_method_return(message);
709 dbus_message_append_args(reply, DBUS_TYPE_INT32, &error, DBUS_TYPE_INVALID);
711 dbus_message_append_args(reply, DBUS_TYPE_STRING, &result, DBUS_TYPE_INVALID);
712 dbus_connection_send (connection, reply, NULL);
713 dbus_message_unref (reply);
714 return DBUS_HANDLER_RESULT_HANDLED;
721 char *signature_name;
724 DBusHandlerResult(*func)(DBusConnection *connection, DBusMessage *message);
726 {"", "iter", "", "", "o", "navit", request_main_iter},
727 {"", "iter_destroy", "o", "navit", "", "", request_main_iter_destroy},
728 {"", "get_navit", "o", "navit", "o", "", request_main_get_navit},
729 {".navit", "draw", "", "", "", "", request_navit_draw},
730 {".navit", "add_message", "s", "message", "", "", request_navit_add_message},
731 {".navit", "set_center", "s", "(coordinates)", "", "", request_navit_set_center},
732 {".navit", "set_center", "(is)", "(projection,coordinates)", "", "", request_navit_set_center},
733 {".navit", "set_center", "(iii)", "(projection,longitude,latitude)", "", "", request_navit_set_center},
734 {".navit", "set_center_screen", "(ii)", "(pixel_x,pixel_y)", "", "", request_navit_set_center_screen},
735 {".navit", "set_layout", "s", "layoutname", "", "", request_navit_set_layout},
736 {".navit", "zoom", "i(ii)", "factor(pixel_x,pixel_y)", "", "", request_navit_zoom},
737 {".navit", "zoom", "i", "factor", "", "", request_navit_zoom},
738 {".navit", "resize", "ii", "upperleft,lowerright", "", "", request_navit_resize},
739 {".navit", "get_attr", "s", "attribute", "v", "value", request_navit_get_attr},
740 {".navit", "set_attr", "sv", "attribute,value", "", "", request_navit_set_attr},
741 {".navit", "set_position", "s", "(coordinates)", "", "", request_navit_set_position},
742 {".navit", "set_position", "(is)", "(projection,coordinated)", "", "", request_navit_set_position},
743 {".navit", "set_position", "(iii)", "(projection,longitude,latitude)", "", "", request_navit_set_position},
744 {".navit", "set_destination", "ss", "coordinates,comment", "", "", request_navit_set_destination},
745 {".navit", "set_destination", "(is)s", "(projection,coordinates)comment", "", "", request_navit_set_destination},
746 {".navit", "set_destination", "(iii)s", "(projection,longitude,latitude)comment", "", "", request_navit_set_destination},
747 {".navit", "evaluate", "s", "command", "s", "", request_navit_evaluate},
749 {".navit", "toggle_announcer", "", "", "", "", request_navit_toggle_announcer},
750 {".navit", "toggle_announcer", "i", "", "", "", request_navit_toggle_announcer},
755 generate_navitintrospectxml(void)
758 char *navitintrospectxml;
760 // write header and make navit introspectable
761 navitintrospectxml = g_strdup_printf("%s%s%s\n", navitintrospectxml_head1, object_path, navitintrospectxml_head2);
763 for (i = 0 ; i < sizeof(dbus_methods)/sizeof(struct dbus_method) ; i++) {
764 // start new interface if it's the first method or it changed
765 if ((i == 0) || strcmp(dbus_methods[i-1].path, dbus_methods[i].path))
766 navitintrospectxml = g_strconcat_printf(navitintrospectxml, " <interface name=\"%s%s\">\n", service_name, dbus_methods[i].path);
768 // start the new method
769 navitintrospectxml = g_strconcat_printf(navitintrospectxml, " <method name=\"%s\">\n", dbus_methods[i].method);
771 // set input signature if existent
772 if (strcmp(dbus_methods[i].signature, ""))
773 navitintrospectxml = g_strconcat_printf(navitintrospectxml, " <arg direction=\"in\" name=\"%s\" type=\"%s\" />\n", dbus_methods[i].signature_name, dbus_methods[i].signature);
775 // set response signature if existent
776 if (strcmp(dbus_methods[i].response, ""))
777 navitintrospectxml = g_strconcat_printf(navitintrospectxml, " <arg direction=\"out\" name=\"%s\" type=\"%s\" />\n", dbus_methods[i].response_name, dbus_methods[i].response);
780 navitintrospectxml = g_strconcat_printf(navitintrospectxml, " </method>\n");
782 // close the interface if we reached the last method or the interface changes
783 if ((sizeof(dbus_methods)/sizeof(struct dbus_method) == (i+1)) || strcmp(dbus_methods[i+1].path, dbus_methods[i].path))
784 navitintrospectxml = g_strconcat_printf(navitintrospectxml, " </interface>\n\n");
786 // close the "mother tag"
787 navitintrospectxml = g_strconcat_printf(navitintrospectxml, "</node>\n");
789 return navitintrospectxml;
792 static DBusHandlerResult
793 navit_handler_func(DBusConnection *connection, DBusMessage *message, void *user_data)
797 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));
798 if (dbus_message_is_method_call (message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
800 dbg(0,"Introspect\n");
801 if (! strcmp(dbus_message_get_path(message), object_path)) {
802 char *navitintrospectxml = generate_navitintrospectxml();
803 reply = dbus_message_new_method_return(message);
804 dbus_message_append_args(reply, DBUS_TYPE_STRING, &navitintrospectxml, DBUS_TYPE_INVALID);
805 dbus_connection_send (connection, reply, NULL);
806 dbus_message_unref (reply);
807 g_free(navitintrospectxml);
808 return DBUS_HANDLER_RESULT_HANDLED;
812 for (i = 0 ; i < sizeof(dbus_methods)/sizeof(struct dbus_method) ; i++) {
813 path=g_strdup_printf("%s%s", service_name, dbus_methods[i].path);
814 if (dbus_message_is_method_call(message, path, dbus_methods[i].method) &&
815 dbus_message_has_signature(message, dbus_methods[i].signature)) {
817 return dbus_methods[i].func(connection, message);
821 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
824 static DBusObjectPathVTable dbus_navit_vtable = {
832 filter(DBusConnection *connection, DBusMessage *message, void *user_data)
834 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));
835 if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
837 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
841 void plugin_init(void)
845 object_hash=g_hash_table_new(g_str_hash, g_str_equal);
846 object_count=g_hash_table_new(g_str_hash, g_str_equal);
848 dbus_error_init(&error);
849 connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
851 dbg(0,"Failed to open connection to session message bus: %s\n", error.message);
852 dbus_error_free(&error);
855 dbus_connection_setup_with_g_main(connection, NULL);
857 dbus_connection_add_filter(connection, filter, NULL, NULL);
858 dbus_bus_add_match(connection, "type='signal',""interface='" DBUS_INTERFACE_DBUS "'", &error);
860 dbus_connection_register_fallback(connection, object_path, &dbus_navit_vtable, NULL);
861 dbus_bus_request_name(connection, service_name, 0, &error);
862 if (dbus_error_is_set(&error)) {
863 dbg(0,"Failed to request name: %s", error.message);
864 dbus_error_free (&error);