diff options
Diffstat (limited to 'navit/binding')
-rw-r--r-- | navit/binding/Makefile.am | 10 | ||||
-rw-r--r-- | navit/binding/dbus/Makefile.am | 5 | ||||
-rw-r--r-- | navit/binding/dbus/binding_dbus.c | 267 | ||||
-rw-r--r-- | navit/binding/dbus/navit.introspect | 16 | ||||
-rwxr-xr-x | navit/binding/dbus/test.py | 11 | ||||
-rw-r--r-- | navit/binding/python/Makefile.am | 5 | ||||
-rw-r--r-- | navit/binding/python/binding_python.c | 283 |
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); +} |