From 0d42d801204cb1d696625da50f114fc6f7977e0c Mon Sep 17 00:00:00 2001 From: Pierre-Luc Beaudoin Date: Sun, 15 Feb 2009 12:35:07 +0200 Subject: [PATCH] libchamplain python bindings --- Makefile.am | 3 + bindings/python/Makefile.am | 1 + bindings/python/champlain/Makefile.am | 42 ++++ bindings/python/champlain/pychamplain.defs | 208 ++++++++++++++++++ .../python/champlain/pychamplain.override | 13 ++ bindings/python/champlain/pychamplainmodule.c | 26 +++ bindings/python/update-binding.sh | 38 ++++ configure.ac | 40 +++- m4/python.m4 | 66 ++++++ 9 files changed, 436 insertions(+), 1 deletion(-) create mode 100644 bindings/python/Makefile.am create mode 100644 bindings/python/champlain/Makefile.am create mode 100644 bindings/python/champlain/pychamplain.defs create mode 100644 bindings/python/champlain/pychamplain.override create mode 100644 bindings/python/champlain/pychamplainmodule.c create mode 100755 bindings/python/update-binding.sh create mode 100644 m4/python.m4 diff --git a/Makefile.am b/Makefile.am index 0abb509..25801cb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -13,6 +13,9 @@ champlain-gtk-@API_VERSION@.pc: champlain-gtk.pc @cp -f $< $@ endif +if ENABLE_PYTHON +SUBDIRS += bindings/python +endif pkgconfig_DATA = $(pcfiles) pkgconfigdir = $(libdir)/pkgconfig diff --git a/bindings/python/Makefile.am b/bindings/python/Makefile.am new file mode 100644 index 0000000..606c429 --- /dev/null +++ b/bindings/python/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = champlain diff --git a/bindings/python/champlain/Makefile.am b/bindings/python/champlain/Makefile.am new file mode 100644 index 0000000..e3af528 --- /dev/null +++ b/bindings/python/champlain/Makefile.am @@ -0,0 +1,42 @@ +PYCLUTTERDEFS=`pkg-config --variable=defsdir pyclutter-0.8` + +AM_CPPFLAGS = \ + -I. \ + -I$(top_srcdir)/champlain \ + -I$(top_srcdir) \ + -DDATADIR=\""$(datadir)"\" \ + $(PYTHON_INCLUDES) \ + $(PYTHON_BINDING_CFLAGS) \ + $(WARN_CFLAGS) + +BUILT_SOURCES = \ + pychamplain.c + +pychamplaindir = $(pyexecdir) +pychamplain_LTLIBRARIES = champlain.la + +champlain_la_SOURCES = \ + pychamplainmodule.c \ + pychamplain.c + +champlain_la_LIBADD = \ + $(PYTHON_BINDING_LIBS) \ + $(top_builddir)/champlain/libchamplain-0.3.la + +champlain_la_LDFLAGS = \ + -module -avoid-version + +pychamplain.c: pychamplain.override pychamplain.defs + $(PYGOBJECTCODEGEN) \ + --prefix champlain \ + --register $(PYCLUTTERDEFS)/clutter-types.defs \ + --register $(PYCLUTTERDEFS)/cogl-types.defs \ + --override pychamplain.override \ + pychamplain.defs > $@ + +EXTRA_DIST = \ + pychamplain.override \ + pychamplain.defs + +CLEANFILES = $(BUILT_SOURCES) + diff --git a/bindings/python/champlain/pychamplain.defs b/bindings/python/champlain/pychamplain.defs new file mode 100644 index 0000000..e3adc0b --- /dev/null +++ b/bindings/python/champlain/pychamplain.defs @@ -0,0 +1,208 @@ +;; -*- scheme -*- +; object definitions ... +(define-object Marker + (in-module "Champlain") + (parent "ClutterGroup") + (c-name "ChamplainMarker") + (gtype-id "CHAMPLAIN_TYPE_MARKER") +) + +(define-object View + (in-module "Champlain") + (parent "ClutterGroup") + (c-name "ChamplainView") + (gtype-id "CHAMPLAIN_TYPE_VIEW") +) + +;; Enumerations and flags ... + +(define-enum MapSource + (in-module "Champlain") + (c-name "ChamplainMapSource") + (gtype-id "CHAMPLAIN_TYPE_MAP_SOURCE") + (values + '("debug" "CHAMPLAIN_MAP_SOURCE_DEBUG") + '("openstreetmap" "CHAMPLAIN_MAP_SOURCE_OPENSTREETMAP") + '("openarialmap" "CHAMPLAIN_MAP_SOURCE_OPENARIALMAP") + '("mapsforfree-relief" "CHAMPLAIN_MAP_SOURCE_MAPSFORFREE_RELIEF") + '("count" "CHAMPLAIN_MAP_SOURCE_COUNT") + ) +) + +(define-enum ScrollMode + (in-module "Champlain") + (c-name "ChamplainScrollMode") + (gtype-id "CHAMPLAIN_TYPE_SCROLL_MODE") + (values + '("push" "CHAMPLAIN_SCROLL_MODE_PUSH") + '("kinetic" "CHAMPLAIN_SCROLL_MODE_KINETIC") + ) +) + + +;; From champlain.h + + + +;; From champlain-view.h + +(define-function view_get_type + (c-name "champlain_view_get_type") + (return-type "GType") +) + +(define-function view_new + (c-name "champlain_view_new") + (is-constructor-of "ChamplainView") + (return-type "ClutterActor*") + (parameters + ) +) + +(define-method center_on + (of-object "ChamplainView") + (c-name "champlain_view_center_on") + (return-type "none") + (parameters + '("gdouble" "latitude") + '("gdouble" "longitude") + ) +) + +(define-method zoom_in + (of-object "ChamplainView") + (c-name "champlain_view_zoom_in") + (return-type "none") +) + +(define-method zoom_out + (of-object "ChamplainView") + (c-name "champlain_view_zoom_out") + (return-type "none") +) + +(define-method add_layer + (of-object "ChamplainView") + (c-name "champlain_view_add_layer") + (return-type "none") + (parameters + '("ClutterActor*" "layer") + ) +) + +(define-method set_size + (of-object "ChamplainView") + (c-name "champlain_view_set_size") + (return-type "none") + (parameters + '("guint" "width") + '("guint" "height") + ) +) + +(define-method get_coords_from_event + (of-object "ChamplainView") + (c-name "champlain_view_get_coords_from_event") + (return-type "gboolean") + (parameters + '("ClutterEvent*" "event") + '("gdouble*" "lat") + '("gdouble*" "lon") + ) +) + + + +;; From champlain-defines.h + + + +;; From champlain-layer.h + +(define-function layer_new + (c-name "champlain_layer_new") + (is-constructor-of "ChamplainLayer") + (return-type "ChamplainLayer*") + (parameters + ) +) + + + +;; From champlain-marker.h + +(define-function marker_get_type + (c-name "champlain_marker_get_type") + (return-type "GType") +) + +(define-function marker_new + (c-name "champlain_marker_new") + (is-constructor-of "ChamplainMarker") + (return-type "ClutterActor*") + (parameters + ) +) + +(define-method set_position + (of-object "ChamplainMarker") + (c-name "champlain_marker_set_position") + (return-type "none") + (parameters + '("gdouble" "longitude") + '("gdouble" "latitude") + ) +) + +(define-function marker_new_with_label + (c-name "champlain_marker_new_with_label") + (return-type "ClutterActor*") + (parameters + '("const-gchar*" "label") + '("const-gchar*" "font") + '("ClutterColor*" "text_color") + '("ClutterColor*" "marker_color") + ) +) + +(define-function marker_new_with_image + (c-name "champlain_marker_new_with_image") + (return-type "ClutterActor*") + (parameters + '("const-gchar*" "filename") + '("GError**" "error") + ) +) + +(define-function marker_new_with_image_full + (c-name "champlain_marker_new_with_image_full") + (return-type "ClutterActor*") + (parameters + '("const-gchar*" "filename") + '("gint" "width") + '("gint" "height") + '("gint" "anchor_x") + '("gint" "anchor_y") + '("GError**" "error") + ) +) + + + +;; From champlain-marshal.h + + + +;; From champlain-enum-types.h + +(define-function map_source_get_type + (c-name "champlain_map_source_get_type") + (return-type "GType") +) + +(define-function scroll_mode_get_type + (c-name "champlain_scroll_mode_get_type") + (return-type "GType") +) + + diff --git a/bindings/python/champlain/pychamplain.override b/bindings/python/champlain/pychamplain.override new file mode 100644 index 0000000..fe20238 --- /dev/null +++ b/bindings/python/champlain/pychamplain.override @@ -0,0 +1,13 @@ +%% +headers +#include +#include +#include +#include + +%% +modulename champlain +%% +import clutter.Actor as PyClutterActor_Type +import clutter.Group as PyClutterGroup_Type +%% diff --git a/bindings/python/champlain/pychamplainmodule.c b/bindings/python/champlain/pychamplainmodule.c new file mode 100644 index 0000000..dca998c --- /dev/null +++ b/bindings/python/champlain/pychamplainmodule.c @@ -0,0 +1,26 @@ +#define NO_IMPORT_PYGOBJECT + +#include + +void champlain_register_classes (PyObject *d); +DL_EXPORT(void) initchamplain(void); +extern PyMethodDef champlain_functions[]; + +DL_EXPORT(void) +initchamplain(void) +{ + PyObject *m, *d; + + init_pygobject (); + + m = Py_InitModule ("champlain", champlain_functions); + d = PyModule_GetDict (m); + + champlain_register_classes (d); + + if (PyErr_Occurred ()) { + PyErr_Print(); + Py_FatalError ("can't initialise module champlain"); + } +} + diff --git a/bindings/python/update-binding.sh b/bindings/python/update-binding.sh new file mode 100755 index 0000000..a5d46af --- /dev/null +++ b/bindings/python/update-binding.sh @@ -0,0 +1,38 @@ +#! /bin/sh +#Manually update headers in pychamplain.override and pychamplaingtk.override. + +# Update the list of headers from Makefile.am +cd ../../champlain +python /usr/share/pygobject/2.0/codegen/h2def.py \ + -m champlain \ + champlain.h \ + champlain-view.h \ + champlain-defines.h \ + champlain-layer.h \ + champlain-marker.h \ + champlain-marshal.h \ + champlain-enum-types.h \ + > ../bindings/python/champlain/pychamplain.defs + +# Update the list of headers from Makefile.am +cd ../champlain-gtk +python /usr/share/pygobject/2.0/codegen/h2def.py \ + -m champlain \ + champlain-gtk.h \ + champlain-view-embed.h \ + champlain-gtk-marshal.h \ + > ../bindings/python/champlain-gtk/pychamplaingtk.defs + +# Keep original version +cd ../bindings/python +cp champlain/pychamplain.defs /tmp +cp champlain-gtk/pychamplaingtk.defs /tmp + +# Apply patches +#patch -p0 < pyempathy.patch +#patch -p0 < pyempathygtk.patch + +# Make modification then run that: +#diff -up /tmp/pyempathy.defs pyempathy/pyempathy.defs > pyempathy.patch +#diff -up /tmp/pyempathygtk.defs pyempathygtk/pyempathygtk.defs > pyempathygtk.patch + diff --git a/configure.ac b/configure.ac index 2fa4ec1..cd3f6d1 100644 --- a/configure.ac +++ b/configure.ac @@ -5,6 +5,7 @@ AC_PREREQ(2.61) AC_INIT(libchamplain, 0.3, pierre-luc@pierlux.com) AC_CONFIG_SRCDIR([champlain/champlain.h]) AC_CONFIG_HEADER([config.h]) +AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE AC_LIBTOOL_DLOPEN @@ -137,6 +138,43 @@ fi AM_CONDITIONAL(ENABLE_MANAGED, test "x$enable_managed" = "xyes") AM_CONDITIONAL(ENABLE_GTK_MANAGED, test "x$enable_managed" = "xyes" && test "x$enable_gtk" = "xyes") +# ----------------------------------------------------------- +# Enable Python bindings +# ----------------------------------------------------------- + +AC_ARG_ENABLE(python, + AC_HELP_STRING([--enable-python],[Build python bindings]), + enable_python=$enableval, enable_python=no ) + +if test x$enable_python = xyes; then + PKG_CHECK_MODULES(PYTHON_BINDING, + [ + pygtk-2.0, + glib-2.0, + gobject-2.0, + clutter-0.8, + gconf-2.0, + gtk+-2.0 + ], have_python="yes", have_python="no") + + AC_CONFIG_FILES([ + bindings/python/Makefile + bindings/python/champlain/Makefile + bindings/python/champlain-gtk/Makefile + ]) + + if test "x$have_python" = "xyes" ; then + AC_CHECK_PROGS([PYGOBJECTCODEGEN], [pygobject-codegen-2.0 pygtk-codegen-2.0]) + AM_CHECK_PYTHON_HEADERS(,have_python="no") + fi +fi + +if test "x$enable_python" = "xyes" -a "x$have_python" != "xyes"; then + AC_MSG_ERROR([Couldn't find python.]) +fi + +AM_CONDITIONAL(ENABLE_PYTHON, test "x$enable_python" = "xyes") + # ----------------------------------------------------------- AC_CONFIG_FILES([Makefile @@ -159,5 +197,5 @@ echo " Gtk+ View: ${enable_gtk}" echo "" echo "Bindings:" echo " champlain-sharp: ${enable_managed}" -echo "" +echo " Python bindings: ${enable_python}" diff --git a/m4/python.m4 b/m4/python.m4 new file mode 100644 index 0000000..fe90156 --- /dev/null +++ b/m4/python.m4 @@ -0,0 +1,66 @@ +## this one is commonly used with AM_PATH_PYTHONDIR ... +dnl AM_CHECK_PYMOD(MODNAME [,SYMBOL [,ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]]]) +dnl Check if a module containing a given symbol is visible to python. +AC_DEFUN([AM_CHECK_PYMOD], +[AC_REQUIRE([AM_PATH_PYTHON]) +py_mod_var=`echo $1['_']$2 | sed 'y%./+-%__p_%'` +AC_MSG_CHECKING(for ifelse([$2],[],,[$2 in ])python module $1) +AC_CACHE_VAL(py_cv_mod_$py_mod_var, [ +ifelse([$2],[], [prog=" +import sys +try: + import $1 +except ImportError: + sys.exit(1) +except: + sys.exit(0) +sys.exit(0)"], [prog=" +import $1 +$1.$2"]) +if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC + then + eval "py_cv_mod_$py_mod_var=yes" + else + eval "py_cv_mod_$py_mod_var=no" + fi +]) +py_val=`eval "echo \`echo '$py_cv_mod_'$py_mod_var\`"` +if test "x$py_val" != xno; then + AC_MSG_RESULT(yes) + ifelse([$3], [],, [$3 +])dnl +else + AC_MSG_RESULT(no) + ifelse([$4], [],, [$4 +])dnl +fi +]) + +dnl a macro to check for ability to create python extensions +dnl AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE]) +dnl function also defines PYTHON_INCLUDES +AC_DEFUN([AM_CHECK_PYTHON_HEADERS], +[AC_REQUIRE([AM_PATH_PYTHON]) +AC_MSG_CHECKING(for headers required to compile python extensions) +dnl deduce PYTHON_INCLUDES +py_prefix=`$PYTHON -c "import sys; print sys.prefix"` +py_exec_prefix=`$PYTHON -c "import sys; print sys.exec_prefix"` +if test -x "$PYTHON-config"; then +PYTHON_INCLUDES=`$PYTHON-config --includes 2>/dev/null` +else +PYTHON_INCLUDES="-I${py_prefix}/include/python${PYTHON_VERSION}" +if test "$py_prefix" != "$py_exec_prefix"; then + PYTHON_INCLUDES="$PYTHON_INCLUDES -I${py_exec_prefix}/include/python${PYTHON_VERSION}" +fi +fi +AC_SUBST(PYTHON_INCLUDES) +dnl check if the headers exist: +save_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $PYTHON_INCLUDES" +AC_TRY_CPP([#include ],dnl +[AC_MSG_RESULT(found) +$1],dnl +[AC_MSG_RESULT(not found) +$2]) +CPPFLAGS="$save_CPPFLAGS" +]) -- 2.39.5