summaryrefslogtreecommitdiff
path: root/navit/binding
diff options
context:
space:
mode:
Diffstat (limited to 'navit/binding')
-rw-r--r--navit/binding/Makefile.am10
-rw-r--r--navit/binding/dbus/Makefile.am5
-rw-r--r--navit/binding/dbus/binding_dbus.c267
-rw-r--r--navit/binding/dbus/navit.introspect16
-rwxr-xr-xnavit/binding/dbus/test.py11
-rw-r--r--navit/binding/python/Makefile.am5
-rw-r--r--navit/binding/python/binding_python.c283
7 files changed, 597 insertions, 0 deletions
diff --git a/navit/binding/Makefile.am b/navit/binding/Makefile.am
new file mode 100644
index 000000000..540a233cd
--- /dev/null
+++ b/navit/binding/Makefile.am
@@ -0,0 +1,10 @@
+SUBDIRS=
+if USE_BINDING_PYTHON
+ SUBDIRS+=python
+endif
+if USE_BINDING_DBUS
+ SUBDIRS+=dbus
+endif
+
+DIST_SUBDIRS=python dbus
+
diff --git a/navit/binding/dbus/Makefile.am b/navit/binding/dbus/Makefile.am
new file mode 100644
index 000000000..55b7b2908
--- /dev/null
+++ b/navit/binding/dbus/Makefile.am
@@ -0,0 +1,5 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ @DBUS_CFLAGS@ -I$(top_srcdir)/src -DMODULE=binding_dbus
+modulebinding_LTLIBRARIES = libbinding_dbus.la
+libbinding_dbus_la_SOURCES = binding_dbus.c
+libbinding_dbus_la_LIBADD = @DBUS_LIBS@
diff --git a/navit/binding/dbus/binding_dbus.c b/navit/binding/dbus/binding_dbus.c
new file mode 100644
index 000000000..5f682180c
--- /dev/null
+++ b/navit/binding/dbus/binding_dbus.c
@@ -0,0 +1,267 @@
+#include <string.h>
+#define DBUS_API_SUBJECT_TO_CHANGE
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include "config.h"
+#include "main.h"
+#include "navit.h"
+#include "coord.h"
+#include "plugin.h"
+#include "debug.h"
+
+
+static DBusConnection *connection;
+
+static char *service_name="org.navit-project.navit";
+static char *object_path="/org/navit_project/navit";
+
+GHashTable *object_hash;
+GHashTable *object_count;
+
+static char *
+object_new(char *type, void *object)
+{
+ int id;
+ char *ret;
+ dbg(0,"enter %s\n", type);
+ id=(int)g_hash_table_lookup(object_count, type);
+ g_hash_table_insert(object_count, type, (void *)(id+1));
+ ret=g_strdup_printf("%s/%s/%d", object_path, type, id);
+ g_hash_table_insert(object_hash, ret, object);
+ dbg(0,"return %s\n", ret);
+ return (ret);
+}
+
+static void *
+object_get(const char *path)
+{
+ return g_hash_table_lookup(object_hash, path);
+}
+
+static void *
+object_get_from_message_arg(DBusMessage *message, char *type)
+{
+ char *opath;
+ char *prefix;
+ DBusError error;
+ void *ret=NULL;
+
+ dbus_error_init(&error);
+ if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID)) {
+ dbus_error_free(&error);
+ dbg(0,"wrong arg type\n");
+ return NULL;
+ }
+ prefix=g_strdup_printf("%s/%s/", object_path, type);
+ if (!strncmp(prefix, opath, strlen(prefix)))
+ ret=object_get(opath);
+ else
+ dbg(0,"wrong object type\n");
+ g_free(prefix);
+ return ret;
+}
+
+static void *
+object_get_from_message(DBusMessage *message, char *type)
+{
+ const char *opath=dbus_message_get_path(message);
+ char *prefix;
+ void *ret=NULL;
+
+ prefix=g_strdup_printf("%s/%s/", object_path, type);
+ if (!strncmp(prefix, opath, strlen(prefix)))
+ ret=object_get(opath);
+ else
+ dbg(0,"wrong object type\n");
+ g_free(prefix);
+ return ret;
+}
+
+static DBusHandlerResult
+empty_reply(DBusConnection *connection, DBusMessage *message)
+{
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(message);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+request_main_get_navit(DBusConnection *connection, DBusMessage *message)
+{
+ DBusMessage *reply;
+ DBusError error;
+ struct iter *iter;
+ struct navit *navit;
+ char *opath;
+
+ dbus_error_init(&error);
+
+ if (!dbus_message_get_args(message, &error, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID)) {
+ dbg(0,"Error parsing\n");
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ dbg(0,"opath=%s\n", opath);
+ iter=object_get(opath);
+ navit=main_get_navit(iter);
+ if (navit) {
+ reply = dbus_message_new_method_return(message);
+ opath=object_new("navit",navit);
+ dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusHandlerResult
+request_main_iter(DBusConnection *connection, DBusMessage *message)
+{
+ DBusMessage *reply;
+ struct iter *iter=main_iter_new();
+ dbg(0,"iter=%p\n", iter);
+ char *opath=object_new("main_iter",iter);
+ reply = dbus_message_new_method_return(message);
+ dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &opath, DBUS_TYPE_INVALID);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+static DBusHandlerResult
+request_main_iter_destroy(DBusConnection *connection, DBusMessage *message)
+{
+ struct iter *iter;
+
+ iter=object_get_from_message_arg(message, "main_iter");
+ if (! iter)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ main_iter_destroy(iter);
+
+ return empty_reply(connection, message);
+}
+static int
+pcoord_get_from_message(DBusMessage *message, struct pcoord *pc)
+{
+ DBusMessageIter iter,iter2;
+
+ dbus_message_iter_init(message, &iter);
+ dbg(0,"%s\n", dbus_message_iter_get_signature(&iter));
+ dbus_message_iter_recurse(&iter, &iter2);
+
+ if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INT32)
+ return 0;
+ dbus_message_iter_get_basic(&iter2, &pc->pro);
+ dbus_message_iter_next(&iter2);
+ if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INT32)
+ return 0;
+ dbus_message_iter_get_basic(&iter2, &pc->x);
+ dbus_message_iter_next(&iter2);
+ if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INT32)
+ return 0;
+ dbus_message_iter_get_basic(&iter2, &pc->y);
+ dbus_message_iter_next(&iter2);
+ if (dbus_message_iter_get_arg_type(&iter2) != DBUS_TYPE_INVALID)
+ return 0;
+ return 1;
+}
+
+static DBusHandlerResult
+request_navit_set_center(DBusConnection *connection, DBusMessage *message)
+{
+ struct pcoord pc;
+ struct navit *navit;
+ navit=object_get_from_message(message, "navit");
+ if (! navit)
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ if (!pcoord_get_from_message(message, &pc))
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ navit_set_center(navit, &pc);
+ return empty_reply(connection, message);
+}
+
+static DBusHandlerResult
+navit_handler_func(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ 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));
+#if 0
+ if (dbus_message_is_method_call (message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
+ DBusMessage *reply;
+ gchar *idata;
+ dbg(0,"Introspect\n");
+ if (! strcmp(dbus_message_get_path(message), "/org/navit_project/navit")) {
+ g_file_get_contents("binding/dbus/navit.introspect", &idata, NULL, NULL);
+ reply = dbus_message_new_method_return(message);
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &idata, DBUS_TYPE_INVALID);
+ dbus_connection_send (connection, reply, NULL);
+ dbus_message_unref (reply);
+ g_free(idata);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ }
+#endif
+ if (dbus_message_is_method_call (message, "org.navit_project.navit", "iter") &&
+ dbus_message_has_signature(message, ""))
+ return request_main_iter(connection, message);
+ if (dbus_message_is_method_call (message, "org.navit_project.navit", "iter_destroy") &&
+ dbus_message_has_signature(message, "o"))
+ return request_main_iter_destroy(connection, message);
+ if (dbus_message_is_method_call (message, "org.navit_project.navit", "get_navit") &&
+ dbus_message_has_signature(message,"o"))
+ return request_main_get_navit(connection, message);
+ if (dbus_message_is_method_call (message, "org.navit_project.navit.navit", "set_center") &&
+ dbus_message_has_signature(message,"(iii)"))
+ return request_navit_set_center(connection, message);
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static DBusObjectPathVTable dbus_navit_vtable = {
+ NULL,
+ navit_handler_func,
+ NULL
+};
+
+#if 0
+DBusHandlerResult
+filter(DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ 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));
+ if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
+ }
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+#endif
+
+void plugin_init(void)
+{
+ DBusError error;
+
+ object_hash=g_hash_table_new(g_str_hash, g_str_equal);
+ object_count=g_hash_table_new(g_str_hash, g_str_equal);
+ dbg(0,"enter 1\n");
+ dbus_error_init(&error);
+ connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
+ if (!connection) {
+ dbg(0,"Failed to open connection to session message bus: %s", error.message);
+ dbus_error_free(&error);
+ return;
+ }
+ dbus_connection_setup_with_g_main(connection, NULL);
+#if 0
+ dbus_connection_add_filter(connection, filter, NULL, NULL);
+ dbus_bus_add_match(connection, "type='signal',""interface='" DBUS_INTERFACE_DBUS "'", &error);
+#endif
+ dbus_connection_register_fallback(connection, object_path, &dbus_navit_vtable, NULL);
+ dbus_bus_request_name(connection, service_name, 0, &error);
+ if (dbus_error_is_set(&error)) {
+ dbg(0,"Failed to request name: %s", error.message);
+ dbus_error_free (&error);
+ }
+}
diff --git a/navit/binding/dbus/navit.introspect b/navit/binding/dbus/navit.introspect
new file mode 100644
index 000000000..8afea2d6f
--- /dev/null
+++ b/navit/binding/dbus/navit.introspect
@@ -0,0 +1,16 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node>
+ <interface name="org.navit_project.navit">
+ <method name="iter_new">
+ <arg name="iter" type="o" direction="out"/>
+ </method>
+ <method name="get_navit">
+ <arg name="iter" type="o" direction="in"/>
+ <arg name="navit" type="o" direction="out"/>
+ </method>
+ <method name="iter_destroy">
+ <arg name="iter" type="o" direction="in"/>
+ </method>
+ </interface>
+</node>
diff --git a/navit/binding/dbus/test.py b/navit/binding/dbus/test.py
new file mode 100755
index 000000000..5f69fddbf
--- /dev/null
+++ b/navit/binding/dbus/test.py
@@ -0,0 +1,11 @@
+#! /usr/bin/python
+import dbus
+bus = dbus.SessionBus()
+conn = bus.get_object('org.navit-project.navit',
+ '/org/navit_project/navit')
+iface = dbus.Interface(conn, dbus_interface='org.navit_project.navit');
+iter=iface.iter();
+navit=bus.get_object('org.navit-project.navit', conn.get_navit(iter));
+iface.iter_destroy(iter);
+navit_iface = dbus.Interface(navit, dbus_interface='org.navit_project.navit.navit');
+navit_iface.set_center((1,0x138a4a,0x5d773f));
diff --git a/navit/binding/python/Makefile.am b/navit/binding/python/Makefile.am
new file mode 100644
index 000000000..637492080
--- /dev/null
+++ b/navit/binding/python/Makefile.am
@@ -0,0 +1,5 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ @PYTHON_CFLAGS@ -I$(top_srcdir)/src -DMODULE=binding_python
+modulebinding_LTLIBRARIES = libbinding_python.la
+libbinding_python_la_SOURCES = binding_python.c
+libbinding_python_la_LIBADD = @PYTHON_LIBS@
diff --git a/navit/binding/python/binding_python.c b/navit/binding/python/binding_python.c
new file mode 100644
index 000000000..cb33f83b3
--- /dev/null
+++ b/navit/binding/python/binding_python.c
@@ -0,0 +1,283 @@
+#include "config.h"
+#include <glib.h>
+#include <Python.h>
+#include <fcntl.h>
+#include "coord.h"
+#include "projection.h"
+#include "map.h"
+#include "mapset.h"
+#include "plugin.h"
+
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+#define Obj_HEAD PyObject_HEAD_INIT(NULL);
+#else
+#define Obj_HEAD PyObject_HEAD_INIT(&PyType_Type)
+#endif
+
+/* *** coord *** */
+
+typedef struct {
+ PyObject_HEAD
+ struct coord *c;
+} coordObject;
+
+static void coord_destroy_py(coordObject *self);
+
+PyTypeObject coord_Type = {
+ Obj_HEAD
+ .tp_name="coord",
+ .tp_basicsize=sizeof(coordObject),
+ .tp_dealloc=(destructor)coord_destroy_py,
+};
+
+
+/* *** map *** */
+
+typedef struct {
+ PyObject_HEAD
+ struct map *m;
+} mapObject;
+
+static void map_destroy_py(mapObject *self);
+static PyObject *map_getattr_py(PyObject *self, char *name);
+
+PyTypeObject map_Type = {
+ Obj_HEAD
+ .tp_name="map",
+ .tp_basicsize=sizeof(mapObject),
+ .tp_dealloc=(destructor)map_destroy_py,
+ .tp_getattr=map_getattr_py,
+};
+
+/* *** IMPLEMENTATIONS *** */
+
+/* *** coord *** */
+
+static PyObject *
+coord_new_py(PyObject *self, PyObject *args)
+{
+ coordObject *ret;
+ int x,y;
+ if (!PyArg_ParseTuple(args, "ii:navit.coord",&x,&y))
+ return NULL;
+ ret=PyObject_NEW(coordObject, &coord_Type);
+ ret->c=coord_new(x,y);
+ return (PyObject *)ret;
+}
+
+static void
+coord_destroy_py(coordObject *self)
+{
+ coord_destroy(self->c);
+}
+
+/* *** coord_rect *** */
+
+typedef struct {
+ PyObject_HEAD
+ struct coord_rect *r;
+} coord_rectObject;
+
+
+static void coord_rect_destroy_py(coord_rectObject *self);
+
+PyTypeObject coord_rect_Type = {
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+ PyObject_HEAD_INIT(NULL);
+#else
+ PyObject_HEAD_INIT(&PyType_Type)
+#endif
+ .tp_name="coord_rect",
+ .tp_basicsize=sizeof(coord_rectObject),
+ .tp_dealloc=(destructor)coord_rect_destroy_py,
+};
+
+static PyObject *
+coord_rect_new_py(PyObject *self, PyObject *args)
+{
+ coord_rectObject *ret;
+ coordObject *lu,*rd;
+ if (!PyArg_ParseTuple(args, "O!O!:navit.coord_rect_rect",&coord_Type,&lu,&coord_Type,&rd))
+ return NULL;
+ ret=PyObject_NEW(coord_rectObject, &coord_rect_Type);
+ ret->r=coord_rect_new(lu->c,rd->c);
+ return (PyObject *)ret;
+}
+
+static void
+coord_rect_destroy_py(coord_rectObject *self)
+{
+ coord_rect_destroy(self->r);
+}
+
+/* *** map_rect *** */
+
+typedef struct {
+ PyObject_HEAD
+ struct map_rect *mr;
+} map_rectObject;
+
+
+static void map_rect_destroy_py(map_rectObject *self);
+
+PyTypeObject map_rect_Type = {
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+ PyObject_HEAD_INIT(NULL);
+#else
+ PyObject_HEAD_INIT(&PyType_Type)
+#endif
+ .tp_name="map_rect",
+ .tp_basicsize=sizeof(map_rectObject),
+ .tp_dealloc=(destructor)map_rect_destroy_py,
+};
+
+static PyObject *
+map_rect_new_py(mapObject *self, PyObject *args)
+{
+ map_rectObject *ret;
+ coord_rectObject *r;
+ if (!PyArg_ParseTuple(args, "O!:navit.map_rect_rect",&coord_rect_Type,&r))
+ return NULL;
+ ret=PyObject_NEW(map_rectObject, &map_rect_Type);
+ ret->mr=map_rect_new(self->m, NULL);
+ return (PyObject *)ret;
+}
+
+static void
+map_rect_destroy_py(map_rectObject *self)
+{
+ map_rect_destroy(self->mr);
+}
+
+
+/* *** map *** */
+
+
+
+static PyMethodDef map_methods[] = {
+ {"map_rect_new", (PyCFunction) map_rect_new_py, METH_VARARGS },
+ {NULL, NULL },
+};
+
+static PyObject *
+map_getattr_py(PyObject *self, char *name)
+{
+ return Py_FindMethod(map_methods, self, name);
+}
+
+
+static PyObject *
+map_new_py(PyObject *self, PyObject *args)
+{
+ mapObject *ret;
+ char *type, *filename;
+
+ if (!PyArg_ParseTuple(args, "ss:navit.map", &type, &filename))
+ return NULL;
+ ret=PyObject_NEW(mapObject, &map_Type);
+ ret->m=map_new(type,NULL);
+ return (PyObject *)ret;
+}
+
+static void
+map_destroy_py(mapObject *self)
+{
+ map_destroy(self->m);
+}
+
+/* *** mapset *** */
+
+
+typedef struct {
+ PyObject_HEAD
+ struct mapset *ms;
+} mapsetObject;
+
+
+static void mapset_destroy_py(mapsetObject *self);
+static PyObject *mapset_getattr_py(PyObject *self, char *name);
+
+PyTypeObject mapset_Type = {
+#if defined(MS_WINDOWS) || defined(__CYGWIN__)
+ PyObject_HEAD_INIT(NULL);
+#else
+ PyObject_HEAD_INIT(&PyType_Type)
+#endif
+ .tp_name="mapset",
+ .tp_basicsize=sizeof(mapsetObject),
+ .tp_dealloc=(destructor)mapset_destroy_py,
+ .tp_getattr=mapset_getattr_py,
+};
+
+static PyObject *
+mapset_add_py(mapsetObject *self, PyObject *args)
+{
+ mapObject *map;
+ if (!PyArg_ParseTuple(args, "O:navit.mapset", &map))
+ return NULL;
+ Py_INCREF(map);
+ mapset_add(self->ms, map->m);
+ return Py_BuildValue("");
+}
+
+static PyMethodDef mapset_methods[] = {
+ {"add", (PyCFunction) mapset_add_py, METH_VARARGS },
+ {NULL, NULL },
+};
+
+static PyObject *
+mapset_getattr_py(PyObject *self, char *name)
+{
+ return Py_FindMethod(mapset_methods, self, name);
+}
+
+static PyObject *
+mapset_new_py(PyObject *self, PyObject *args)
+{
+ mapsetObject *ret;
+ if (!PyArg_ParseTuple(args, ":navit.mapset"))
+ return NULL;
+ ret=PyObject_NEW(mapsetObject, &mapset_Type);
+ ret->ms=mapset_new();
+ return (PyObject *)ret;
+}
+
+static void
+mapset_destroy_py(mapsetObject *self)
+{
+ mapset_destroy(self->ms);
+}
+
+
+
+static PyMethodDef navitMethods[]={
+ {"coord", coord_new_py, METH_VARARGS, "Create a new coordinate point."},
+ {"coord_rect", coord_rect_new_py, METH_VARARGS, "Create a new coordinate rectangle."},
+ {"map", map_new_py, METH_VARARGS, "Create a new map."},
+ {"mapset", mapset_new_py, METH_VARARGS, "Create a new mapset."},
+ {NULL, NULL, 0, NULL}
+};
+
+
+void
+plugin_init(void)
+{
+ int fd,size;
+ char buffer[65536];
+
+ return;
+
+ Py_Initialize();
+ Py_InitModule("navit", navitMethods);
+ fd=open("startup.py",O_RDONLY);
+ if (fd >= 0) {
+ size=read(fd, buffer, 65535);
+ if (size > 0) {
+ buffer[size]='\0';
+ PyRun_SimpleString(buffer);
+ }
+ }
+
+ Py_Finalize();
+ exit(0);
+}