Usage: import pyfprint

Signed-off-by: Lukas Sandström <[EMAIL PROTECTED]>
---

Hi.

I've rebased the Python bindings I wrote some time ago.

New feature: *the build-system is working* (at least for me,
remember to pass --enable-python to ./configure)

You can test it using pyfprint_demo, available at
git://repo.or.cz/pyfprint_demo.git

The patch applies to the v0.0 libfprint branch. I'll look
into porting it to 1.0 sometime in this or the next week.

Patches and suggestions welcome.

/Lukas

 Makefile.am              |    6 +
 autogen.sh               |    4 +-
 configure.ac             |   16 ++-
 m4/ac_pkg_swig.m4        |  122 +++++++++++++
 m4/ac_python_devel.m4    |  265 ++++++++++++++++++++++++++++
 m4/swig_python.m4        |   65 +++++++
 pyfprint/Makefile.am     |   12 ++
 pyfprint/pyfprint.py     |  427 ++++++++++++++++++++++++++++++++++++++++++++++
 pyfprint/pyfprint_swig.i |  236 +++++++++++++++++++++++++
 9 files changed, 1150 insertions(+), 3 deletions(-)
 create mode 100644 m4/ac_pkg_swig.m4
 create mode 100644 m4/ac_python_devel.m4
 create mode 100644 m4/swig_python.m4
 create mode 100644 pyfprint/Makefile.am
 create mode 100644 pyfprint/pyfprint.py
 create mode 100644 pyfprint/pyfprint_swig.i

diff --git a/Makefile.am b/Makefile.am
index 4c63a15..ffe45ef 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,10 +4,16 @@ DISTCLEANFILES = ChangeLog libfprint.pc
 
 SUBDIRS = libfprint doc
 
+ACLOCAL_AMFLAGS = -I m4
+
 if BUILD_EXAMPLES
 SUBDIRS += examples
 endif
 
+if PYTHON
+SUBDIRS += pyfprint
+endif
+
 pkgconfigdir=$(libdir)/pkgconfig
 pkgconfig_DATA=libfprint.pc
 
diff --git a/autogen.sh b/autogen.sh
index 5499285..374db0f 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,8 +1,8 @@
 #!/bin/sh
 libtoolize --copy --force || exit 1
-aclocal || exit 1
+aclocal -I m4 || exit 1
 autoheader || exit 1
-autoconf || exit 1
+autoconf -I m4 || exit 1
 automake -a -c || exit 1
 ./configure --enable-maintainer-mode --enable-examples-build \
        --enable-x11-examples-build --enable-debug-log $*
diff --git a/configure.ac b/configure.ac
index 88f9641..6db68ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,6 +3,8 @@ AM_INIT_AUTOMAKE
 AC_CONFIG_SRCDIR([libfprint/core.c])
 AM_CONFIG_HEADER([config.h])
 
+dnl AC_DISABLE_STATIC
+
 AC_PREREQ([2.50])
 AC_PROG_CC
 AC_PROG_LIBTOOL
@@ -34,6 +36,18 @@ PKG_CHECK_MODULES(IMAGEMAGICK, "ImageMagick")
 AC_SUBST(IMAGEMAGICK_CFLAGS)
 AC_SUBST(IMAGEMAGICK_LIBS)
 
+AC_ARG_ENABLE([python], [AS_HELP_STRING([--enable-python],
+       [enable python wrapper (default n)])],
+       [pyfprint=$enableval],
+       [pyfprint='no'])
+AM_CONDITIONAL([PYTHON], [test "x$python" != "xno"])
+
+if test "x$python" != "xno" ; then
+       AM_PATH_PYTHON(2.3)
+       AC_PROG_SWIG(1.3.31)
+       SWIG_PYTHON
+fi
+
 # Examples build
 AC_ARG_ENABLE([examples-build], [AS_HELP_STRING([--enable-examples-build],
        [build example applications (default n)])],
@@ -99,6 +113,6 @@ AC_DEFINE([API_EXPORTED], 
[__attribute__((visibility("default")))], [Default vis
 AM_CFLAGS="-std=gnu99 $inline_cflags -Wall -Wundef -Wunused 
-Wstrict-prototypes -Werror-implicit-function-declaration -Wno-pointer-sign 
-Wshadow"
 AC_SUBST(AM_CFLAGS)
 
-AC_CONFIG_FILES([libfprint.pc] [Makefile] [libfprint/Makefile] 
[examples/Makefile] [doc/Makefile])
+AC_CONFIG_FILES([libfprint.pc] [Makefile] [libfprint/Makefile] 
[examples/Makefile] [doc/Makefile] [pyfprint/Makefile])
 AC_OUTPUT
 
diff --git a/m4/ac_pkg_swig.m4 b/m4/ac_pkg_swig.m4
new file mode 100644
index 0000000..738f69d
--- /dev/null
+++ b/m4/ac_pkg_swig.m4
@@ -0,0 +1,122 @@
+# ===========================================================================
+#              http://autoconf-archive.cryp.to/ac_pkg_swig.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AC_PROG_SWIG([major.minor.micro])
+#
+# DESCRIPTION
+#
+#   This macro searches for a SWIG installation on your system. If found you
+#   should call SWIG via $(SWIG). You can use the optional first argument to
+#   check if the version of the available SWIG is greater than or equal to
+#   the value of the argument. It should have the format: N[.N[.N]] (N is a
+#   number between 0 and 999. Only the first N is mandatory.)
+#
+#   If the version argument is given (e.g. 1.3.17), AC_PROG_SWIG checks that
+#   the swig package is this version number or higher.
+#
+#   In configure.in, use as:
+#
+#     AC_PROG_SWIG(1.3.17)
+#     SWIG_ENABLE_CXX
+#     SWIG_MULTI_MODULE_SUPPORT
+#     SWIG_PYTHON
+#
+# LAST MODIFICATION
+#
+#   2008-04-12
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Sebastian Huber <[EMAIL PROTECTED]>
+#   Copyright (c) 2008 Alan W. Irwin <[EMAIL PROTECTED]>
+#   Copyright (c) 2008 Rafael Laboissiere <[EMAIL PROTECTED]>
+#   Copyright (c) 2008 Andrew Collier <[EMAIL PROTECTED]>
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation; either version 2 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Macro Archive. When you make and
+#   distribute a modified version of the Autoconf Macro, you may extend this
+#   special exception to the GPL to apply to your modified version as well.
+
+AC_DEFUN([AC_PROG_SWIG],[
+        AC_PATH_PROG([SWIG],[swig])
+        if test -z "$SWIG" ; then
+                AC_MSG_WARN([cannot find 'swig' program. You should look at 
http://www.swig.org])
+                SWIG='echo "Error: SWIG is not installed. You should look at 
http://www.swig.org"; ; false'
+        elif test -n "$1" ; then
+                AC_MSG_CHECKING([for SWIG version])
+                [swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 
's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`]
+                AC_MSG_RESULT([$swig_version])
+                if test -n "$swig_version" ; then
+                        # Calculate the required version number components
+                        [required=$1]
+                        [required_major=`echo $required | sed 's/[^0-9].*//'`]
+                        if test -z "$required_major" ; then
+                                [required_major=0]
+                        fi
+                        [required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
+                        [required_minor=`echo $required | sed 's/[^0-9].*//'`]
+                        if test -z "$required_minor" ; then
+                                [required_minor=0]
+                        fi
+                        [required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
+                        [required_patch=`echo $required | sed 's/[^0-9].*//'`]
+                        if test -z "$required_patch" ; then
+                                [required_patch=0]
+                        fi
+                        # Calculate the available version number components
+                        [available=$swig_version]
+                        [available_major=`echo $available | sed 
's/[^0-9].*//'`]
+                        if test -z "$available_major" ; then
+                                [available_major=0]
+                        fi
+                        [available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
+                        [available_minor=`echo $available | sed 
's/[^0-9].*//'`]
+                        if test -z "$available_minor" ; then
+                                [available_minor=0]
+                        fi
+                        [available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
+                        [available_patch=`echo $available | sed 
's/[^0-9].*//'`]
+                        if test -z "$available_patch" ; then
+                                [available_patch=0]
+                        fi
+                        if test $available_major -ne $required_major \
+                                -o $available_minor -ne $required_minor \
+                                -o $available_patch -lt $required_patch ; then
+                                AC_MSG_WARN([SWIG version >= $1 is required.  
You have $swig_version.  You should look at http://www.swig.org])
+                                SWIG='echo "Error: SWIG version >= $1 is 
required.  You have '"$swig_version"'.  You should look at http://www.swig.org"; 
; false'
+                        else
+                                AC_MSG_NOTICE([SWIG executable is '$SWIG'])
+                                SWIG_LIB=`$SWIG -swiglib`
+                                AC_MSG_NOTICE([SWIG library directory is 
'$SWIG_LIB'])
+                        fi
+                else
+                        AC_MSG_WARN([cannot determine SWIG version])
+                        SWIG='echo "Error: Cannot determine SWIG version.  You 
should look at http://www.swig.org"; ; false'
+                fi
+        fi
+        AC_SUBST([SWIG_LIB])
+])
diff --git a/m4/ac_python_devel.m4 b/m4/ac_python_devel.m4
new file mode 100644
index 0000000..7cec10f
--- /dev/null
+++ b/m4/ac_python_devel.m4
@@ -0,0 +1,265 @@
+# ===========================================================================
+#            http://autoconf-archive.cryp.to/ac_python_devel.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AC_PYTHON_DEVEL([version])
+#
+# DESCRIPTION
+#
+#   Note: Defines as a precious variable "PYTHON_VERSION". Don't override it
+#   in your configure.ac.
+#
+#   This macro checks for Python and tries to get the include path to
+#   'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS)
+#   output variables. It also exports $(PYTHON_EXTRA_LIBS) and
+#   $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code.
+#
+#   You can search for some particular version of Python by passing a
+#   parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please
+#   note that you *have* to pass also an operator along with the version to
+#   match, and pay special attention to the single quotes surrounding the
+#   version number. Don't use "PYTHON_VERSION" for this: that environment
+#   variable is declared as precious and thus reserved for the end-user.
+#
+#   This macro should work for all versions of Python >= 2.1.0. As an end
+#   user, you can disable the check for the python version by setting the
+#   PYTHON_NOVERSIONCHECK environment variable to something else than the
+#   empty string.
+#
+#   If you need to use this macro for an older Python version, please
+#   contact the authors. We're always open for feedback.
+#
+# LAST MODIFICATION
+#
+#   2008-04-12
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Sebastian Huber <[EMAIL PROTECTED]>
+#   Copyright (c) 2008 Alan W. Irwin <[EMAIL PROTECTED]>
+#   Copyright (c) 2008 Rafael Laboissiere <[EMAIL PROTECTED]>
+#   Copyright (c) 2008 Andrew Collier <[EMAIL PROTECTED]>
+#   Copyright (c) 2008 Matteo Settenvini <[EMAIL PROTECTED]>
+#   Copyright (c) 2008 Horst Knorr <[EMAIL PROTECTED]>
+#
+#   This program is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation, either version 3 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Macro Archive. When you make and
+#   distribute a modified version of the Autoconf Macro, you may extend this
+#   special exception to the GPL to apply to your modified version as well.
+
+AC_DEFUN([AC_PYTHON_DEVEL],[
+       #
+       # Allow the use of a (user set) custom python version
+       #
+       AC_ARG_VAR([PYTHON_VERSION],[The installed Python
+               version to use, for example '2.3'. This string
+               will be appended to the Python interpreter
+               canonical name.])
+
+       AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
+       if test -z "$PYTHON"; then
+          AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
+          PYTHON_VERSION=""
+       fi
+
+       #
+       # Check for a version of Python >= 2.1.0
+       #
+       AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
+       ac_supports_python_ver=`$PYTHON -c "import sys, string; \
+               ver = string.split(sys.version)[[0]]; \
+               print ver >= '2.1.0'"`
+       if test "$ac_supports_python_ver" != "True"; then
+               if test -z "$PYTHON_NOVERSIONCHECK"; then
+                       AC_MSG_RESULT([no])
+                       AC_MSG_FAILURE([
+This version of the AC@&[EMAIL PROTECTED] macro
+doesn't work properly with versions of Python before
+2.1.0. You may need to re-run configure, setting the
+variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
+PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
+Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
+to something else than an empty string.
+])
+               else
+                       AC_MSG_RESULT([skip at user request])
+               fi
+       else
+               AC_MSG_RESULT([yes])
+       fi
+
+       #
+       # if the macro parameter ``version'' is set, honour it
+       #
+       if test -n "$1"; then
+               AC_MSG_CHECKING([for a version of Python $1])
+               ac_supports_python_ver=`$PYTHON -c "import sys, string; \
+                       ver = string.split(sys.version)[[0]]; \
+                       print ver $1"`
+               if test "$ac_supports_python_ver" = "True"; then
+                  AC_MSG_RESULT([yes])
+               else
+                       AC_MSG_RESULT([no])
+                       AC_MSG_ERROR([this package requires Python $1.
+If you have it installed, but it isn't the default Python
+interpreter in your system path, please pass the PYTHON_VERSION
+variable to configure. See ``configure --help'' for reference.
+])
+                       PYTHON_VERSION=""
+               fi
+       fi
+
+       #
+       # Check if you have distutils, else fail
+       #
+       AC_MSG_CHECKING([for the distutils Python package])
+       ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
+       if test -z "$ac_distutils_result"; then
+               AC_MSG_RESULT([yes])
+       else
+               AC_MSG_RESULT([no])
+               AC_MSG_ERROR([cannot import Python module "distutils".
+Please check your Python installation. The error was:
+$ac_distutils_result])
+               PYTHON_VERSION=""
+       fi
+
+       #
+       # Check for Python include path
+       #
+       AC_MSG_CHECKING([for Python include path])
+       if test -z "$PYTHON_CPPFLAGS"; then
+               python_path=`$PYTHON -c "import distutils.sysconfig; \
+                       print distutils.sysconfig.get_python_inc();"`
+               if test -n "${python_path}"; then
+                       python_path="-I$python_path"
+               fi
+               PYTHON_CPPFLAGS=$python_path
+       fi
+       AC_MSG_RESULT([$PYTHON_CPPFLAGS])
+       AC_SUBST([PYTHON_CPPFLAGS])
+
+       #
+       # Check for Python library path
+       #
+       AC_MSG_CHECKING([for Python library path])
+       if test -z "$PYTHON_LDFLAGS"; then
+               # (makes two attempts to ensure we've got a version number
+               # from the interpreter)
+               py_version=`$PYTHON -c "from distutils.sysconfig import *; \
+                       from string import join; \
+                       print join(get_config_vars('VERSION'))"`
+               if test "$py_version" == "[None]"; then
+                       if test -n "$PYTHON_VERSION"; then
+                               py_version=$PYTHON_VERSION
+                       else
+                               py_version=`$PYTHON -c "import sys; \
+                                       print sys.version[[:3]]"`
+                       fi
+               fi
+
+               PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
+                       from string import join; \
+                       print '-L' + get_python_lib(0,1), \
+                       '-lpython';"`$py_version
+       fi
+       AC_MSG_RESULT([$PYTHON_LDFLAGS])
+       AC_SUBST([PYTHON_LDFLAGS])
+
+       #
+       # Check for site packages
+       #
+       AC_MSG_CHECKING([for Python site-packages path])
+       if test -z "$PYTHON_SITE_PKG"; then
+               PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
+                       print distutils.sysconfig.get_python_lib(0,0);"`
+       fi
+       AC_MSG_RESULT([$PYTHON_SITE_PKG])
+       AC_SUBST([PYTHON_SITE_PKG])
+
+       #
+       # libraries which must be linked in when embedding
+       #
+       AC_MSG_CHECKING(python extra libraries)
+       if test -z "$PYTHON_EXTRA_LIBS"; then
+          PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
+                conf = distutils.sysconfig.get_config_var; \
+                print conf('LOCALMODLIBS'), conf('LIBS')"`
+       fi
+       AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
+       AC_SUBST(PYTHON_EXTRA_LIBS)
+
+       #
+       # linking flags needed when embedding
+       #
+       AC_MSG_CHECKING(python extra linking flags)
+       if test -z "$PYTHON_EXTRA_LDFLAGS"; then
+               PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
+                       conf = distutils.sysconfig.get_config_var; \
+                       print conf('LINKFORSHARED')"`
+       fi
+       AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
+       AC_SUBST(PYTHON_EXTRA_LDFLAGS)
+
+       #
+       # final check to see if everything compiles alright
+       #
+       AC_MSG_CHECKING([consistency of all components of python development 
environment])
+       AC_LANG_PUSH([C])
+       # save current global flags
+       LIBS="$ac_save_LIBS $PYTHON_LDFLAGS"
+       CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
+       AC_TRY_LINK([
+               #include <Python.h>
+       ],[
+               Py_Initialize();
+       ],[pythonexists=yes],[pythonexists=no])
+
+       AC_MSG_RESULT([$pythonexists])
+
+        if test ! "$pythonexists" = "yes"; then
+          AC_MSG_ERROR([
+  Could not link test program to Python. Maybe the main Python library has been
+  installed in some non-standard library path. If so, pass it to configure,
+  via the LDFLAGS environment variable.
+  Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
+  ============================================================================
+   ERROR!
+   You probably have to install the development version of the Python package
+   for your distribution.  The exact name of this package varies among them.
+  ============================================================================
+          ])
+         PYTHON_VERSION=""
+       fi
+       AC_LANG_POP
+       # turn back to default flags
+       CPPFLAGS="$ac_save_CPPFLAGS"
+       LIBS="$ac_save_LIBS"
+
+       #
+       # all done!
+       #
+])
diff --git a/m4/swig_python.m4 b/m4/swig_python.m4
new file mode 100644
index 0000000..2496976
--- /dev/null
+++ b/m4/swig_python.m4
@@ -0,0 +1,65 @@
+# ===========================================================================
+#              http://autoconf-archive.cryp.to/swig_python.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   SWIG_PYTHON([use-shadow-classes = {no, yes}])
+#
+# DESCRIPTION
+#
+#   Checks for Python and provides the $(SWIG_PYTHON_CPPFLAGS), and
+#   $(SWIG_PYTHON_OPT) output variables.
+#
+#   $(SWIG_PYTHON_OPT) contains all necessary SWIG options to generate code
+#   for Python. Shadow classes are enabled unless the value of the optional
+#   first argument is exactly 'no'. If you need multi module support
+#   (provided by the SWIG_MULTI_MODULE_SUPPORT macro) use
+#   $(SWIG_PYTHON_LIBS) to link against the appropriate library. It contains
+#   the SWIG Python runtime library that is needed by the type check system
+#   for example.
+#
+# LAST MODIFICATION
+#
+#   2008-04-12
+#
+# COPYLEFT
+#
+#   Copyright (c) 2008 Sebastian Huber <[EMAIL PROTECTED]>
+#   Copyright (c) 2008 Alan W. Irwin <[EMAIL PROTECTED]>
+#   Copyright (c) 2008 Rafael Laboissiere <[EMAIL PROTECTED]>
+#   Copyright (c) 2008 Andrew Collier <[EMAIL PROTECTED]>
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by the
+#   Free Software Foundation; either version 2 of the License, or (at your
+#   option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+#   Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License along
+#   with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#   As a special exception, the respective Autoconf Macro's copyright owner
+#   gives unlimited permission to copy, distribute and modify the configure
+#   scripts that are the output of Autoconf when processing the Macro. You
+#   need not follow the terms of the GNU General Public License when using
+#   or distributing such scripts, even though portions of the text of the
+#   Macro appear in them. The GNU General Public License (GPL) does govern
+#   all other use of the material that constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the Autoconf
+#   Macro released by the Autoconf Macro Archive. When you make and
+#   distribute a modified version of the Autoconf Macro, you may extend this
+#   special exception to the GPL to apply to your modified version as well.
+
+AC_DEFUN([SWIG_PYTHON],[
+        AC_REQUIRE([AC_PROG_SWIG])
+        AC_REQUIRE([AC_PYTHON_DEVEL])
+        test "x$1" != "xno" || swig_shadow=" -noproxy"
+        AC_SUBST([SWIG_PYTHON_OPT],[-python$swig_shadow])
+        AC_SUBST([SWIG_PYTHON_CPPFLAGS],[$PYTHON_CPPFLAGS])
+])
diff --git a/pyfprint/Makefile.am b/pyfprint/Makefile.am
new file mode 100644
index 0000000..51fdc48
--- /dev/null
+++ b/pyfprint/Makefile.am
@@ -0,0 +1,12 @@
+BUILT_SOURCES = pyfprint_swig.c
+SWIG_SOURCES = pyfprint_swig.i
+
+pkgpython_PYTHON = pyfprint_swig.py pyfprint.py
+pkgpyexec_LTLIBRARIES = _pyfprint_swig.la
+_pyfprint_swig_la_SOURCES = pyfprint_swig.c $(SWIG_SOURCES)
+_pyfprint_swig_la_CPPFLAGS = $(SWIG_PYTHON_CPPFLAGS) $(PYTHON_CPPFLAGS) 
-I$(top_srcdir)/libfprint
+_pyfprint_swig_la_LDFLAGS = -module
+_pyfprint_swig_la_LIBADD = ../libfprint/libfprint.la
+
+pyfprint_swig.c : $(SWIG_SOURCES)
+       $(SWIG) $(SWIG_PYTHON_OPT) -I$(top_srcdir)/libfprint -o $@ $<
diff --git a/pyfprint/pyfprint.py b/pyfprint/pyfprint.py
new file mode 100644
index 0000000..1b77dc7
--- /dev/null
+++ b/pyfprint/pyfprint.py
@@ -0,0 +1,427 @@
+
+import pyfprint_swig as pyf
+
+# TODO:
+#      exceptions, especially for RETRY_* errors
+#      constants for fingers
+#      tests
+#      documentation
+#      for x in y => map ?
+#      Image(img) for devices which don't support imaging? Is img NULL?
+
+_init_ok = False
+
+def _dbg(*arg):
+       #print arg
+       pass
+
+def fp_init():
+       _init_ok = (pyf.fp_init() == 0)
+       if not _init_ok:
+               raise "fprint initialization failed."
+
+def fp_exit():
+       pyf.fp_exit()
+       _init_ok = False
+
+Fingers = dict(
+       LEFT_THUMB = pyf.LEFT_THUMB,
+       LEFT_INDEX = pyf.LEFT_INDEX,
+       LEFT_MIDDLE = pyf.LEFT_MIDDLE,
+       LEFT_RING = pyf.LEFT_RING,
+       LEFT_LITTLE = pyf.LEFT_LITTLE,
+       RIGHT_THUMB = pyf.RIGHT_THUMB,
+       RIGHT_INDEX = pyf.RIGHT_INDEX,
+       RIGHT_MIDDLE = pyf.RIGHT_MIDDLE,
+       RIGHT_RING = pyf.RIGHT_RING,
+       RIGHT_LITTLE = pyf.RIGHT_LITTLE
+       )
+
+class Device:
+       def __init__(self, dev_ptr = None, dscv_ptr = None, DscvList = None):
+               self.dev = dev_ptr
+               self.dscv = dscv_ptr
+               self.DscvList = DscvList
+               if dscv_ptr and DscvList == None:
+                       raise "Programming error? Device contructed with dscv 
without DscvList."
+
+       def close(self):
+               if self.dev:
+                       pyf.fp_dev_close(self.dev)
+               self.dev = None
+
+       def open(self):
+               if self.dev:
+                       raise "Device already open"
+               self.dev = pyf.fp_dev_open(self.dscv)
+               if not self.dev:
+                       raise "device open failed"
+
+       def get_driver(self):
+               if self.dev:
+                       return Driver(pyf.fp_dev_get_driver(self.dev))
+               if self.dscv:
+                       return Driver(pyf.fp_dscv_dev_get_driver(self.dscv))
+
+       def get_devtype(self):
+               if self.dev:
+                       return pyf.fp_dev_get_devtype(self.dev)
+               if self.dscv:
+                       return pyf.fp_dscv_dev_get_devtype(self.dev)
+
+       def get_nr_enroll_stages(self):
+               if self.dev:
+                       return pyf.fp_dev_get_nr_enroll_stages(self.dev)
+               raise "Device not open"
+
+       def is_compatible(self, fprint):
+               if self.dev:
+                       if fprint.data_ptr:
+                               return pyf.fp_dev_supports_print_data(self.dev, 
fprint.data_ptr) == 1
+                       if fprint.dscv_ptr:
+                               return pyf.fp_dev_supports_dscv_print(self.dev, 
fprint.dscv_ptr) == 1
+                       raise "No print found"
+               if self.dscv:
+                       if fprint.data_ptr:
+                               return 
pyf.fp_dscv_dev_supports_print_data(self.dscv, fprint.data_ptr) == 1
+                       if fprint.dscv_ptr:
+                               return 
pyf.fp_dscv_dev_supports_dscv_print(self.dscv, fprint.dscv_ptr) == 1
+                       raise "No print found"
+               raise "No device found"
+
+       def get_supports_imaging(self):
+               if self.dev:
+                       return pyf.fp_dev_supports_imaging(self.dev) == 1
+               raise "Device not open"
+
+       def get_img_width(self):
+               if self.dev:
+                       return pyf.fp_dev_get_img_width(self.dev)
+               raise "Device not open"
+
+       def get_img_height(self):
+               if self.dev:
+                       return pyf.fp_dev_get_img_height(self.dev)
+               raise "Device not open"
+
+       def capture_image(self, wait_for_finger):
+               """FIXME: check that the dev supports imaging, or check 
-ENOTSUP"""
+               if not self.dev:
+                       raise "Device not open"
+
+               unconditional = 1
+               if wait_for_finger == True:
+                       unconditional = 0
+
+               (r, img) = pyf.pyfp_dev_img_capture(self.dev, unconditional)
+               if r != 0:
+                       raise "image_capture failed. error: " + r
+               return Image(img)
+
+       def enroll_finger(self):
+               if not self.dev:
+                       raise "Device not open"
+               (r, fprint, img) = pyf.pyfp_enroll_finger_img(self.dev)
+               if r < 0:
+                       raise "Internal I/O error while enrolling"
+               img = Image(img)
+               if r == pyf.FP_ENROLL_COMPLETE:
+                       _dbg("enroll complete")
+                       return (Fprint(data_ptr = fprint), img)
+               if r == pyf.FP_ENROLL_FAIL:
+                       print "Failed. Enrollmet process reset."
+               if r == pyf.FP_ENROLL_PASS:
+                       _dbg("enroll PASS")
+                       return (None, img)
+               if r == pyf.FP_ENROLL_RETRY:
+                       _dbg("enroll RETRY")
+                       pass
+               if r == pyf.FP_ENROLL_RETRY_TOO_SHORT:
+                       _dbg("enroll RETRY_SHORT")
+                       pass
+               if r == pyf.FP_ENROLL_RETRY_CENTER_FINGER:
+                       _dbg("enroll RETRY_CENTER")
+                       pass
+               if r == pyf.FP_ENROLL_RETRY_REMOVE_FINGER:
+                       _dbg("enroll RETRY_REMOVE")
+                       pass
+               return ("xxx", None)
+
+       def verify_finger(self, fprint):
+               if not self.dev:
+                       raise "Device not open"
+               (r, img) = pyf.pyfp_verify_finger_img(self.dev, 
fprint._get_print_data_ptr())
+               if r < 0:
+                       raise "verify error"
+               img = Image(img)
+               if r == pyf.FP_VERIFY_NO_MATCH:
+                       return (False, img)
+               if r == pyf.FP_VERIFY_MATCH:
+                       return (True, img)
+               if r == pyf.FP_VERIFY_RETRY:
+                       pass
+               if r == pyf.FP_VERIFY_RETRY_TOO_SHORT:
+                       pass
+               if r == pyf.FP_VERIFY_RETRY_CENTER_FINGER:
+                       pass
+               if r == pyf.FP_VERIFY_RETRY_REMOVE_FINGER:
+                       pass
+               return (None, None)
+
+       def supports_identification(self):
+               if not self.dev:
+                       raise "Device not open"
+               return pyf.fp_dev_supports_identification(self.dev) == 1
+
+       def identify_finger(self, fprints):
+               """Returns a tuple: (list_offset, Fprint, Image) if a match is 
found,
+               (None, None, Image) otherwise. Image is None if the device 
doesn't
+               support imaging."""
+
+               if not self.dev:
+                       raise "Device not open"
+               gallery = pyf.pyfp_print_data_array(len(fprints))
+               for x in fprints:
+                       if not self.is_compatible(x):
+                               raise "can't verify uncompatible print"
+                       gallery.append(x._get_print_data_ptr())
+               (r, offset, img) = pyf.pyfp_identify_finger_img(self.dev, 
gallery.list)
+               if r < 0:
+                       raise "identification error"
+               img = Image(img)
+               if r == pyf.FP_VERIFY_NO_MATCH:
+                       return (None, None, img)
+               if r == pyf.FP_VERIFY_MATCH:
+                       return (offset, fprints[offset], img)
+               if r == pyf.FP_VERIFY_RETRY:
+                       pass
+               if r == pyf.FP_VERIFY_RETRY_TOO_SHORT:
+                       pass
+               if r == pyf.FP_VERIFY_RETRY_CENTER_FINGER:
+                       pass
+               if r == pyf.FP_VERIFY_RETRY_REMOVE_FINGER:
+                       pass
+               return None
+
+       def load_print_from_disk(self, finger):
+               if not self.dev:
+                       raise "Device not open"
+               (r, print_ptr) = pyf.fp_print_data_load(self.dev, finger)
+               if r != 0:
+                       raise "could not load print from disk"
+               return Fprint(data_ptr = print_ptr)
+
+       def delete_stored_finger(self, finger):
+               if not self.dev:
+                       raise "Device not open"
+               r = pyf.fp_print_data_delete(self.dev, finger)
+               if r != 0:
+                       raise "delete failed"
+
+class Minutia(pyf.fp_minutia):
+       def __init__(self, minutia_ptr, img):
+               self.img = img
+               self.ptr = minutia_ptr
+               pyf.fp_minutia.__init__(self, minutia_ptr)
+
+class Image:
+       def __init__(self, img_ptr, bin = False):
+               self.img = img_ptr
+               self.bin = bin
+               self.std = False
+               self.minutiae = None
+
+       def __del__(self):
+               if self.img:
+                       pyf.fp_img_free(self.img)
+
+       def get_height(self):
+               return pyf.fp_img_get_height(self.img)
+       def get_width(self):
+               return pyf.fp_img_get_width(self.img)
+
+       def get_data(self):
+               return pyf.pyfp_img_get_data(self.img)
+
+       def get_rgb_data(self):
+               return pyf.pyfp_img_get_rgb_data(self.img)
+
+       def save_to_file(self, path):
+               r = pyf.fp_img_save_to_file(self.img, path)
+               if r != 0:
+                       raise "Save failed"
+
+       def standardize(self):
+               pyf.fp_img_standardize(self.img)
+               self.std = True
+
+       def binarize(self):
+               if self.bin:
+                       return
+               if not self.std:
+                       self.standardize()
+               i = pyf.fp_img_binarize(self.img)
+               if i == None:
+                       raise "Binarize failed"
+               return Image(img_ptr = i, bin = True)
+
+       def get_minutiae(self):
+               if self.minutiae:
+                       return self.minutiae
+               if self.bin:
+                       raise "Cannot find minutiae in binarized image"
+               if not self.std:
+                       self.standardize()
+               (min_list, nr) = pyf.fp_img_get_minutiae(self.img)
+               l = []
+               for n in range(nr):
+                       l.append(Minutia(img = self, minutia_ptr = 
pyf.pyfp_deref_minutiae(min_list, n)))
+               self.minutiae = l
+               return l
+
+class Driver:
+       def __init__(self, swig_drv_ptr):
+               self.drv = swig_drv_ptr
+
+       def __del__(self):
+               #FIXME: free drv?
+               pass
+
+       def get_name(self):
+               return pyf.fp_driver_get_name(self.drv)
+
+       def get_full_name(self):
+               return pyf.fp_driver_get_full_name(self.drv)
+
+       def get_driver_id(self):
+               return pyf.fp_driver_get_driver_id(self.drv)
+
+class Fprint:
+       def __init__(self, serial_data = None, data_ptr = None, dscv_ptr = 
None, DscvList = None):
+               # data_ptr is a SWIG pointer to a struct pf_print_data
+               # dscv_ptr is a SWIG pointer to a struct pf_dscv_print
+               # DscvList is a class instance used to free the allocated 
pf_dscv_print's
+               #          with pf_dscv_prints_free when they're all unused.
+               # serial_data is a string as returned by get_data()
+
+               self.data_ptr = data_ptr
+               self.dscv_ptr = dscv_ptr
+               self.DscvList = DscvList
+
+               if serial_data:
+                       self.data_ptr = pyf.fp_print_data_from_data(serial_data)
+                       return
+
+               if dscv_ptr != None and DscvList == None:
+                       raise "Programming error: Fprint constructed with 
dscv_prt with DscvList == None"
+
+       def __del__(self):
+               if self.data_ptr:
+                       pyf.fp_print_data_free(self.data_ptr)
+               # The dscv_ptr is freed when all the dscv prints have been 
garbage collected
+
+       def _get_print_data_ptr(self):
+               if not self.data_ptr:
+                       self._data_from_dscv()
+               return self.data_ptr
+
+       def get_driver_id(self):
+               if self.data_ptr:
+                       return pyf.fp_print_data_get_driver_id(self.data_ptr)
+               elif self.dscv_ptr:
+                       return pyf.fp_dscv_print_get_driver_id(self.dscv_ptr)
+               raise "no print"
+
+       def get_devtype(self):
+               if self.data_ptr:
+                       return pyf.fp_print_data_get_devtype(self.data_ptr)
+               elif self.dscv_ptr:
+                       return pyf.fp_dscv_print_get_devtype(self.dscv_ptr)
+               raise "no print"
+
+       def get_finger(self):
+               if not self.dscv_ptr:
+                       raise "get_finger needs a discovered print"
+               return pyf.fp_dscv_print_get_finger(self.dscv_ptr)
+
+       def delete_from_disk(self):
+               if not self.dscv_ptr:
+                       raise "delete needs a discovered print"
+               return pyf.fp_dscv_print_delete(self.dscv_ptr)
+
+       def save_to_disk(self, finger):
+               r = pyf.fp_print_data_save(self.data_ptr, finger)
+               if r != 0:
+                       raise "save failed"
+
+       def _data_from_dscv(self):
+               if self.data_ptr:
+                       return
+               if not self.dscv_ptr:
+                       raise "no print"
+               (r, ptr) = pyf.fp_print_data_from_dscv_print(self.dscv_ptr)
+               if r != 0:
+                       raise "print data from dscv failed"
+               self.data_ptr = ptr
+
+       def get_data(self):
+               if not self.data_ptr:
+                       raise "no print"
+               s = pyf.pyfp_print_get_data(self.data_ptr)
+               if not len(s):
+                       raise "serialization failed"
+               return s
+
+class DiscoveredPrints(list):
+       def __init__(self, dscv_devs_list):
+               self.ptr = dscv_devs_list
+               i = 0
+               while True:
+                       x = pyf.pyfp_deref_dscv_print_ptr(dscv_devs_list, i)
+                       if x == None:
+                               break
+                       self.append(Fprint(dscv_ptr = x, DscvList = self))
+                       i = i + 1
+       def __del__(self):
+               pyf.pf_dscv_prints_free(self.ptr)
+
+def discover_prints():
+       if not _init_ok:
+               fp_init()
+
+       prints = pyf.fp_discover_prints()
+
+       if not prints:
+               print "Print discovery failed"
+       return DiscoveredPrints(prints)
+
+
+class DiscoveredDevices(list):
+       def __init__(self, dscv_devs_list):
+               self.swig_list_ptr = dscv_devs_list
+               i = 0
+               while True:
+                       x = pyf.pyfp_deref_dscv_dev_ptr(dscv_devs_list, i)
+                       if x == None:
+                               break
+                       self.append(Device(dscv_ptr = x, DscvList = self))
+                       i = i + 1
+
+       def __del__(self):
+               pyf.fp_dscv_devs_free(self.swig_list_ptr)
+
+       def find_compatible(self, fprint):
+               for n in self:
+                       if n.is_compatible(fprint):
+                               return n
+               return None
+
+def discover_devices():
+       if not _init_ok:
+               fp_init()
+
+       devs = pyf.fp_discover_devs()
+
+       if not devs:
+               raise "Device discovery failed"
+       return DiscoveredDevices(devs)
\ No newline at end of file
diff --git a/pyfprint/pyfprint_swig.i b/pyfprint/pyfprint_swig.i
new file mode 100644
index 0000000..84fc3b1
--- /dev/null
+++ b/pyfprint/pyfprint_swig.i
@@ -0,0 +1,236 @@
+%module pyfprint_swig
+%{
+#include <fprint.h>
+#include <errno.h>
+%}
+
+%feature("autodoc", "1");
+
+%include <typemaps.i>
+%include <cdata.i>
+%include <carrays.i>
+%include <cstring.i>
+
+%nodefaultctor;
+
+/* fp_dev_img_capture,  fp_enroll_finger_img, fp_verify_finger_img, 
fp_identify_finger_img */
+%typemap(argout) struct fp_img ** {
+    PyObject *o;
+    o = SWIG_NewPointerObj(*$1, $*1_descriptor, 1);
+    $result = SWIG_AppendOutput($result, o);
+    /* FIXME: is a PY_DECREF(o) needed here ?*/
+}
+%typemap(in, numinputs=0) struct fp_img **(struct fp_img *img) {
+    $1 = &img;
+}
+
+/* fp_enroll_finger_img */
+%typemap(argout) struct fp_print_data **print_data = struct fp_img **;
+%typemap(in, numinputs=0) struct fp_print_data **print_data(struct 
fp_print_data *data) {
+    $1 = &data;
+}
+
+/* fp_print_data_load, fp_print_data_from_dscv_print */
+%apply struct fp_print_data **print_data { struct fp_print_data **data };
+
+/* fp_identify_finger */
+%apply unsigned long *OUTPUT { size_t *match_offset };
+
+/* fp_print_data_from_data */
+%apply (char *STRING, int LENGTH) { (unsigned char *buf, size_t buflen) };
+
+/* fp_img_get_minutiae */
+%apply int *OUTPUT { int *nr_minutiae };
+
+/* Tell SWIG that we're freeing the pointers */
+%delobject fp_dscv_devs_free;
+%delobject fp_img_free;
+%delobject fp_print_data_free;
+%delobject fp_dscv_prints_free;
+%delobject fp_dev_close;
+%delobject pyfp_free_print_data_array;
+
+/* Tell SWIG that we're allocating new objects */
+%newobject pyfp_alloc_print_data_array;
+%newobject fp_dev_open;
+
+/* Image.get_minutiae() */
+%inline %{
+struct fp_minutia * pyfp_deref_minutiae(struct fp_minutia **ptr, int i)
+{
+       return ptr[i];
+}
+
+%}
+/* The struct needs to be redefined as const, otherwise swig will generate 
_set_ methods for the members. */
+struct fp_minutia {
+       const int x;
+       const int y;
+       const int ex;
+       const int ey;
+       const int direction;
+       const double reliability;
+       const int type;
+       const int appearing;
+       const int feature_id;
+       int * const nbrs;
+       int * const ridge_counts;
+       const int num_nbrs;
+
+       %extend {
+               /* A constructor that accepts pre-allocated structs */
+               fp_minutia(struct fp_minutia *ptr)
+               {
+                       return ptr;
+               }
+               ~fp_minutia()
+               {
+                       /* Don't free() fp_minutia *. They are free'd together 
with the fp_img. */ ;
+               }
+       };
+};
+%ignore fp_minutia;
+
+/* Needed to get correct output from
+   fp_dscv_print_get_driver_id and fp_dev_get_devtype */
+typedef unsigned int uint32_t;
+/* fp_driver_get_driver_id, fp_dscv_print_get_driver_id, 
fp_print_data_get_driver_id*/
+typedef unsigned short int uint16_t;
+
+/* Fprint.get_data() */
+%cstring_output_allocate_size(char **print_data, int *len, free(*($1)));
+%inline %{
+void pyfp_print_get_data(char **print_data, int *len, struct fp_print_data 
*print)
+{
+       *len = fp_print_data_get_data(print, (unsigned char**)print_data);
+}
+%}
+%ignore fp_print_data_get_data;
+
+/* Img.get_data() */
+%cstring_output_allocate_size(char **img_data, int *len, "");
+%inline %{
+void pyfp_img_get_data(char **img_data, int *len, struct fp_img *img)
+{
+       *img_data = fp_img_get_data(img);
+       *len = fp_img_get_width(img) * fp_img_get_height(img);
+}
+%}
+%ignore fp_img_get_data;
+
+/* Image.get_rgb_data() */
+%cstring_output_allocate_size(char **img_rgb_data, int *len, free(*($1)));
+%inline %{
+void pyfp_img_get_rgb_data(char **img_rgb_data, int *len, struct fp_img *img)
+{
+       unsigned int i, j = 0;
+       unsigned char *img_data = fp_img_get_data(img);
+       *len = fp_img_get_width(img) * fp_img_get_height(img) * 3;
+       (*img_rgb_data) = malloc(*len);
+       for (i = 0; i < (*len)/3; i++) {
+               (*img_rgb_data)[j++] = img_data[i];
+               (*img_rgb_data)[j++] = img_data[i];
+               (*img_rgb_data)[j++] = img_data[i];
+       }
+}
+%}
+
+/* Wrappers to let Python yield the thread */
+%inline %{
+int pyfp_enroll_finger_img(struct fp_dev *dev, struct fp_print_data 
**print_data, struct fp_img **img)
+{
+       int ret;
+       Py_BEGIN_ALLOW_THREADS
+       ret = fp_enroll_finger_img(dev, print_data, img);
+       Py_END_ALLOW_THREADS
+       return ret;
+}
+int pyfp_verify_finger_img(struct fp_dev *dev, struct fp_print_data 
*enrolled_print, struct fp_img **img)
+{
+       int ret;
+       Py_BEGIN_ALLOW_THREADS
+       ret = fp_verify_finger_img(dev, enrolled_print, img);
+       Py_END_ALLOW_THREADS
+       return ret;
+}
+int pyfp_identify_finger_img(struct fp_dev *dev, struct fp_print_data 
**print_gallery, size_t *match_offset, struct fp_img **img)
+{
+       int ret;
+       Py_BEGIN_ALLOW_THREADS
+       ret = fp_identify_finger_img(dev, print_gallery, match_offset, img);
+       Py_END_ALLOW_THREADS
+       return ret;
+}
+int pyfp_dev_img_capture(struct fp_dev *dev, int unconditional, struct fp_img 
**image)
+{
+       int ret;
+       Py_BEGIN_ALLOW_THREADS
+       ret = fp_dev_img_capture(dev, unconditional, image);
+       Py_END_ALLOW_THREADS
+       return ret;
+}
+%}
+%ignore fp_enroll_finger_img;
+%ignore fp_enroll_finger;
+%ignore fp_verify_finger_img;
+%ignore fp_verify_finger;
+%ignore fp_identify_finger_img;
+%ignore fp_identify_finger;
+%ignore fp_dev_img_capture;
+
+
+%include "fprint.h"
+
+
+/* Device.identify_finger() */
+%inline %{
+struct pyfp_print_data_array {
+       size_t size;
+       size_t used;
+       struct fp_print_data * list[0];
+};
+%}
+%extend pyfp_print_data_array {
+       pyfp_print_data_array(size_t size)
+       {
+               struct pyfp_print_data_array *x;
+               x = calloc(1, sizeof(struct pyfp_print_data_array) +
+                               sizeof(struct fp_print_data *) * (size + 1)); 
/* +1 for NULL termination */
+               x->size = size;
+               return x;
+       }
+       ~pyfp_print_data_array()
+       {
+               free($self);
+       }
+       void append(struct fp_print_data *print)
+       {
+               if ($self->size <= $self->used) {
+                       PyErr_SetString(PyExc_OverflowError, "programming 
error: pyfp_print_data_array list overflow");
+                       return;
+               }
+               $self->list[$self->used] = print;
+               $self->used++;
+       }
+       struct fp_print_data ** pyfp_print_data_array_list_get()
+       {
+               return $self->list;
+       }
+};
+
+%inline %{
+
+/* DiscoveredDevices.__init__() */
+struct fp_dscv_dev * pyfp_deref_dscv_dev_ptr (struct fp_dscv_dev **ptr, int i)
+{
+       return ptr[i];
+}
+
+/* class DiscoveredPrints(list): */
+struct fp_dscv_print * pyfp_deref_dscv_print_ptr(struct fp_dscv_print **ptr, 
int i)
+{
+       return ptr[i];
+}
+
+
+%}
-- 
1.5.4.5
_______________________________________________
fprint mailing list
[email protected]
http://lists.reactivated.net/mailman/listinfo/fprint

Reply via email to