changeset 7834:caab78e7e377

added checks for fltk & freetype in configure script * * * added fltk_backend * * * the fltk_backend now works but that's about it * * * fltk_backend now working * * * updated ChangeLogs with all changes * * * reverted backend::close_figure to using __plot_stream__ moved OpenGL includes into gl-render.h removed check for FL/glu.h * * * configure.in: fix unquoted variable warn_graphics. * * * fixed fltk test in configure.in and also some minor style problems
author Shai Ayal <shaiay@sourceforge.net>
date Sun, 17 Feb 2008 19:20:42 +0200
parents 8ff92634982d
children ca8b97bb952c
files ChangeLog aclocal.m4 configure.in src/graphics.h.in src/graphics/ChangeLog src/graphics/fltk_backend/Makefile.in src/graphics/fltk_backend/fltk_backend.cc src/graphics/opengl/gl-render.cc src/graphics/opengl/gl-render.h
diffstat 9 files changed, 957 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Feb 20 16:29:37 2008 +0100
+++ b/ChangeLog	Sun Feb 17 19:20:42 2008 +0200
@@ -1,5 +1,15 @@
+2008-06-04  Shai Ayal  <shaiay@users.sourceforge.net>
+
+	* configure.in: Remove check for Fl/glu.h header.
+
+	* aclocal.m4 (AC_CHECK_FT2): New macro to check for freetype2.
+
+	* configure.in: Check for FLTK and corresponding compiler flags.
+
 2008-06-04  Michael Goffioul <michael.goffioul@gmail.com>
 
+	* configure.in: Double-quote warn_graphics variable.
+
 	* aclocal.m4 (OCTAVE_OPENGL): New function to detect OpenGL
 	headers and libraries.
 	* configure.in (OCTAVE_OPENGL): Use it.
--- a/aclocal.m4	Wed Feb 20 16:29:37 2008 +0100
+++ b/aclocal.m4	Sun Feb 17 19:20:42 2008 +0200
@@ -1102,3 +1102,195 @@
 fi
 AC_SUBST(OPENGL_LIBS)
 ])
+dnl
+dnl Configure paths for FreeType2
+dnl Marcelo Magallon 2001-10-26, based on gtk.m4 by Owen Taylor
+dnl
+dnl Copyright 2001, 2003 by
+dnl David Turner, Robert Wilhelm, and Werner Lemberg.
+dnl
+dnl This file is part of the FreeType project, and may only be used, modified,
+dnl and distributed under the terms of the FreeType project license,
+dnl LICENSE.TXT.  By continuing to use, modify, or distribute this file you
+dnl indicate that you have read the license and understand and accept it
+dnl fully.
+dnl
+dnl As a special exception to the FreeType project license, this file may be
+dnl distributed as part of a program that contains a configuration script
+dnl generated by Autoconf, under the same distribution terms as the rest of
+dnl that program.
+dnl
+dnl serial 2
+dnl
+dnl AC_CHECK_FT2([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+dnl Test for FreeType 2, and define FT2_CFLAGS and FT2_LIBS.
+dnl MINIMUM-VERSION is what libtool reports; the default is `7.0.1' (this is
+dnl FreeType 2.0.4).
+dnl
+AC_DEFUN([AC_CHECK_FT2],
+  [dnl Get the cflags and libraries from the freetype-config script
+   dnl
+   AC_ARG_WITH([ft-prefix],
+     dnl don't quote AS_HELP_STRING!
+     AS_HELP_STRING([--with-ft-prefix=PREFIX],
+                    [Prefix where FreeType is installed (optional)]),
+     [ft_config_prefix="$withval"],
+     [ft_config_prefix=""])
+  
+   AC_ARG_WITH([ft-exec-prefix],
+     dnl don't quote AS_HELP_STRING!
+     AS_HELP_STRING([--with-ft-exec-prefix=PREFIX],
+                    [Exec prefix where FreeType is installed (optional)]),
+     [ft_config_exec_prefix="$withval"],
+     [ft_config_exec_prefix=""])
+
+   AC_ARG_ENABLE([freetypetest],
+     dnl don't quote AS_HELP_STRING!
+     AS_HELP_STRING([--disable-freetypetest],
+                    [Do not try to compile and run a test FreeType program]),
+     [],
+     [enable_fttest=yes])
+
+   if test x$ft_config_exec_prefix != x ; then
+     ft_config_args="$ft_config_args --exec-prefix=$ft_config_exec_prefix"
+     if test x${FT2_CONFIG+set} != xset ; then
+       FT2_CONFIG=$ft_config_exec_prefix/bin/freetype-config
+     fi
+   fi
+
+   if test x$ft_config_prefix != x ; then
+     ft_config_args="$ft_config_args --prefix=$ft_config_prefix"
+     if test x${FT2_CONFIG+set} != xset ; then
+       FT2_CONFIG=$ft_config_prefix/bin/freetype-config
+     fi
+   fi
+
+   AC_PATH_PROG([FT2_CONFIG], [freetype-config], [no])
+
+   min_ft_version=m4_if([$1], [], [7.0.1], [$1])
+   AC_MSG_CHECKING([for FreeType -- version >= $min_ft_version])
+   no_ft=""
+   if test "$FT2_CONFIG" = "no" ; then
+     no_ft=yes
+   else
+     FT2_CFLAGS=`$FT2_CONFIG $ft_config_args --cflags`
+     FT2_LIBS=`$FT2_CONFIG $ft_config_args --libs`
+     ft_config_major_version=`$FT2_CONFIG $ft_config_args --version | \
+       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+     ft_config_minor_version=`$FT2_CONFIG $ft_config_args --version | \
+       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+     ft_config_micro_version=`$FT2_CONFIG $ft_config_args --version | \
+       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+     ft_min_major_version=`echo $min_ft_version | \
+       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+     ft_min_minor_version=`echo $min_ft_version | \
+       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+     ft_min_micro_version=`echo $min_ft_version | \
+       sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+     if test x$enable_fttest = xyes ; then
+       ft_config_is_lt=""
+       if test $ft_config_major_version -lt $ft_min_major_version ; then
+         ft_config_is_lt=yes
+       else
+         if test $ft_config_major_version -eq $ft_min_major_version ; then
+           if test $ft_config_minor_version -lt $ft_min_minor_version ; then
+             ft_config_is_lt=yes
+           else
+            if test $ft_config_minor_version -eq $ft_min_minor_version ; then
+               if test $ft_config_micro_version -lt $ft_min_micro_version ; then
+                 ft_config_is_lt=yes
+               fi
+             fi
+           fi
+         fi
+       fi
+       if test x$ft_config_is_lt = xyes ; then
+         no_ft=yes
+       else
+         ac_save_CFLAGS="$CFLAGS"
+         ac_save_LIBS="$LIBS"
+         CFLAGS="$CFLAGS $FT2_CFLAGS"
+         LIBS="$FT2_LIBS $LIBS"
+
+         dnl
+         dnl Sanity checks for the results of freetype-config to some extent.
+         dnl
+         AC_RUN_IFELSE([
+             AC_LANG_SOURCE([[
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main()
+{
+  FT_Library library;
+  FT_Error  error;
+
+  error = FT_Init_FreeType(&library);
+
+  if (error)
+    return 1;
+  else
+  {
+    FT_Done_FreeType(library);
+    return 0;
+  }
+}
+
+             ]])
+           ],
+           [],
+           [no_ft=yes],
+           [echo $ECHO_N "cross compiling; assuming OK... $ECHO_C"])
+
+         CFLAGS="$ac_save_CFLAGS"
+         LIBS="$ac_save_LIBS"
+       fi             dnl test $ft_config_version -lt $ft_min_version
+     fi               dnl test x$enable_fttest = xyes
+   fi                 dnl test "$FT2_CONFIG" = "no"
+
+   if test x$no_ft = x ; then
+     AC_MSG_RESULT([yes])
+     m4_if([$2], [], [:], [$2])
+   else
+     AC_MSG_RESULT([no])
+     if test "$FT2_CONFIG" = "no" ; then
+       AC_MSG_WARN([
+
+  The freetype-config script installed by FreeType 2 could not be found.
+  If FreeType 2 was installed in PREFIX, make sure PREFIX/bin is in
+  your path, or set the FT2_CONFIG environment variable to the
+  full path to freetype-config.
+       ])
+     else
+       if test x$ft_config_is_lt = xyes ; then
+         AC_MSG_WARN([
+
+  Your installed version of the FreeType 2 library is too old.
+  If you have different versions of FreeType 2, make sure that
+  correct values for --with-ft-prefix or --with-ft-exec-prefix
+  are used, or set the FT2_CONFIG environment variable to the
+  full path to freetype-config.
+         ])
+       else
+         AC_MSG_WARN([
+
+  The FreeType test program failed to run.  If your system uses
+  shared libraries and they are installed outside the normal
+  system library path, make sure the variable LD_LIBRARY_PATH
+  (or whatever is appropiate for your system) is correctly set.
+         ])
+       fi
+     fi
+
+     FT2_CFLAGS=""
+     FT2_LIBS=""
+     m4_if([$3], [], [:], [$3])
+   fi
+
+   AC_SUBST([FT2_CFLAGS])
+   AC_SUBST([FT2_LIBS])])
+dnl end of freetype2.m4
--- a/configure.in	Wed Feb 20 16:29:37 2008 +0100
+++ b/configure.in	Sun Feb 17 19:20:42 2008 +0200
@@ -636,6 +636,79 @@
 fi
 
 
+# ---------------------------------------------------------------------
+
+## libraries needed for graphics
+
+GRAPHICS_OPENGL=
+OCTAVE_OPENGL
+if test "x$OPENGL_LIBS" != "x"; then
+  GRAPHICS_OPENGL="opengl"
+fi
+
+
+GRAPHICS_LIBS=
+GRAPHICS_CFLAGS=
+
+## fltk (www.fltk.org)
+AC_ARG_WITH(fltk-prefix,
+        [  --with-fltk-prefix=PFX   Prefix where FLTK is installed (optional)],
+        fltk_prefix="$withval",
+        fltk_prefix="")
+AC_ARG_WITH(fltk-exec-prefix,
+        [  --with-fltk-exec-prefix=PFX Exec prefix where FLTK is installed (optional)],
+        fltk_exec_prefix="$withval", 
+        fltk_exec_prefix="")
+
+if test "x$fltk_exec_prefix" != x ; then
+  fltk_args="$fltk_args --exec-prefix=$fltk_exec_prefix"
+  if test "x${FLTK_CONFIG+set}" != xset ; then
+    FLTK_CONFIG="$fltk_exec_prefix/bin/fltk-config"
+  fi
+fi
+
+if test "x$fltk_prefix" != x ; then
+  fltk_args="$fltk_args --prefix=$fltk_prefix"
+  if test x${FLTK_CONFIG+set} != xset ; then
+    FLTK_CONFIG="$fltk_prefix/bin/fltk-config"
+  fi
+fi
+
+AC_PATH_PROG(FLTK_CONFIG, fltk-config, no)
+
+warn_graphics=""
+if test "$FLTK_CONFIG" = "no" ; then
+  warn_graphics="fltk library (www.fltk.org) not found.  Native graphics will be disabled."
+else
+  FLTK_CFLAGS="`$FLTK_CONFIG $fltkconf_args --use-gl --cflags`"
+  FLTK_LDFLAGS="`$FLTK_CONFIG $fltkconf_args --use-gl --ldflags`"
+  
+  AC_MSG_CHECKING(for OpenGL support in fltk)
+  cat > conftest.cc <<EOF
+  #include <FL/gl.h>
+  int nothing=0;
+EOF
+  $CXX $CXXFLAGS $FLTK_CFLAGS -c conftest.cc || \
+    warn_graphics="fltk does not have OpenGL support.  Native graphics will be disabled."
+
+  if test "x$warn_graphics" = "x" ; then
+    AC_MSG_RESULT(yes)
+    ## FTGL flags
+    AC_CHECK_FT2([9.0.3],[],
+             [warn_graphics="FreeType library not found. Native graphics will be disabled."])
+
+    GRAPHICS_CFLAGS="$FLTK_CFLAGS $FT2_CFLAGS"
+    GRAPHICS_LIBS="$FLTK_LDFLAGS $FT2_LIBS"
+    GRAPHICS_OPENGL="$GRAPHICS_OPENGL fltk_backend" 
+  else
+    AC_MSG_RESULT(no)
+  fi
+fi
+
+AC_SUBST(GRAPHICS_CFLAGS)
+AC_SUBST(GRAPHICS_LIBS)
+AC_SUBST(GRAPHICS_OPENGL)
+
 OCTAVE_IEEE754_DATA_FORMAT
 
 # ----------------------------------------------------------------------
@@ -1613,15 +1686,6 @@
   ;;
 esac
 
-## Graphics related stuffs
-
-GRAPHICS_OPENGL=
-OCTAVE_OPENGL
-if test "x$OPENGL_LIBS" != "x"; then
-  GRAPHICS_OPENGL="opengl"
-fi
-AC_SUBST(GRAPHICS_OPENGL)
-
 ### Checks for other programs used for building, testing, installing,
 ### and running Octave.
 
@@ -1878,7 +1942,7 @@
   libcruft/slatec-err/Makefile libcruft/villad/Makefile
   libcruft/blas-xtra/Makefile libcruft/lapack-xtra/Makefile
   src/graphics/Makefile src/graphics/Makerules
-  src/graphics/opengl/Makefile])
+  src/graphics/opengl/Makefile src/graphics/fltk_backend/Makefile])
 AC_OUTPUT
 
 AC_CONFIG_COMMANDS([default-1],[[chmod +x install-octave]],[[]])
@@ -1915,6 +1979,7 @@
   CURL libraries:       $CURL_LIBS
   REGEX libraries:      $REGEX_LIBS
   QHULL libraries:	$QHULL_LIBS
+  GRAPHICS libraries    $GRAPHICS_LIBS
   LIBS:                 $LIBS
   Default pager:        $DEFAULT_PAGER
   gnuplot:              $GNUPLOT
@@ -2117,6 +2182,17 @@
   warn_msg_printed=true
 fi
 
+if test -n "$warn_graphics"; then
+  AC_MSG_WARN($warn_graphics)
+  AC_MSG_WARN([])
+  AC_MSG_WARN([I didn't find the necessary libraries to compile native])
+  AC_MSG_WARN([graphics. It isn't necessary to have native graphics])
+  AC_MSG_WARN([but you will have to use gnuplot or you won't be able])
+  AC_MSG_WARN([to use any of Octave's plotting commands])
+  AC_MSG_WARN([])
+  warn_msg_printed=true
+fi
+
 if $warn_msg_printed; then
   AC_MSG_NOTICE([
 
--- a/src/graphics.h.in	Wed Feb 20 16:29:37 2008 +0100
+++ b/src/graphics.h.in	Sun Feb 17 19:20:42 2008 +0200
@@ -1191,7 +1191,7 @@
 
   virtual bool is_valid (void) const { return false; }
 
-  virtual void close_figure (const octave_value&) const
+  virtual void close_figure (const octave_value& pstream) const
     { gripe_invalid ("close_figure"); }
 
   virtual void redraw_figure (const graphics_handle&) const
--- a/src/graphics/ChangeLog	Wed Feb 20 16:29:37 2008 +0100
+++ b/src/graphics/ChangeLog	Sun Feb 17 19:20:42 2008 +0200
@@ -1,3 +1,20 @@
+2008-02-21  Shai Ayal  <shaiay@users.sourceforge.net>
+
+	* opengl/gl-render.cc: remove OpenGL includes
+	* opengl/gl-render.h: add OpenGL includes
+	* fltk_backend/fltk_backend.cc: remove OpenGL includes
+	(__fltk_redraw__): put figure handle into the figure's
+	__plot_stream__ property for later
+	(fltk_backend::close_figure): use argument as figure handle to
+	close
+
+2008-02-20  Shai Ayal  <shaiay@users.sourceforge.net>
+
+	* fltk_backend/Makefile.in: initial import
+
+	* fltk_backend/fltk_backend.cc: initial import
+	
+
 2008-02-20  Michael Goffioul  <michael.goffioul@gmail.com>
 
 	* opengl/gl-render.h (opengl_renderer::draw(patch)): New method to
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/graphics/fltk_backend/Makefile.in	Sun Feb 17 19:20:42 2008 +0200
@@ -0,0 +1,70 @@
+# Makefile for octave's src/graphics/opengl directory
+#
+# Copyright (C) 1998, 2007 John W. Eaton
+#
+# This file is part of Octave.
+# 
+# Octave 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.
+# 
+# Octave 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 Octave; see the file COPYING.  If not, see
+# <http://www.gnu.org/licenses/>.
+
+TOPDIR = ../../..
+include $(TOPDIR)/Makeconf
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+GRAPHICS_LIBS = @GRAPHICS_LIBS@
+
+FLTK_EXTRA_LIBS = $(OPENGL_LIBS) $(GRAPHICS_LIBS)
+FLTK_EXTRA_CXXFLAGS = $(GRAPHICS_CFLAGS) -I../opengl
+
+FLTK_NAME = fltk_backend
+
+FLTK_SRC := fltk_backend.cc
+FLTK_OBJ := $(patsubst %.cc, %.o, $(FLTK_SRC))
+
+%.o : %.cc
+	$(CXX) -c $(CPPFLAGS) $(ALL_CXXFLAGS) $(FLTK_EXTRA_CXXFLAGS) $< -o $@
+
+# Some stupid egreps don't like empty elements in alternation patterns,
+# so we have to repeat ourselves because some stupid egreps don't like
+# empty elements in alternation patterns.
+
+DEFUN_PATTERN = "^[ \t]*DEF(CONSTFUN|CMD|UN|UN_DLD|UNX_DLD|UN_TEXT|UN_MAPPER)[ \t]*\\("
+
+DLD_DEF_FILES := $(patsubst %.cc, %.df, $(FLTK_SRC))
+
+OCTAVE_LFLAGS = -L$(TOPDIR)/liboctave -L$(TOPDIR)/libcruft \
+  -L$(TOPDIR)/src $(RLD_FLAG)
+
+ifeq ($(ENABLE_DYNAMIC_LINKING), true)
+  OCTAVE_LIBS = $(LIBOCTINTERP) $(LIBOCTAVE) \
+    $(SPECIAL_MATH_LIB) $(LIBCRUFT) \
+    $(LIBPLPLOT) $(LIBGLOB)
+else
+  OCTAVE_LIBS = $(LIBOCTINTERP) $(LIBOCTAVE) $(QHULL_LIBS) \
+    $(GLPK_LIBS) $(REGEX_LIBS) $(SPECIAL_MATH_LIB) $(LIBCRUFT) \
+    $(LIBPLPLOT) $(LIBGLOB)
+endif
+
+OCT_LINK_DEPS = \
+  -L../../../libcruft $(LIBCRUFT) -L../../../liboctave $(LIBOCTAVE) \
+  -L../../ $(LIBOCTINTERP) -L../opengl -loctgraphics_gl $(CHOLMOD_LIBS) $(UMFPACK_LIBS) $(AMD_LIBS) \
+   $(CAMD_LIBS) $(COLAMD_LIBS) $(CCOLAMD_LIBS) $(CXSPARSE_LIBS) $(BLAS_LIBS) \
+   $(FFTW_LIBS) $(LIBS) $(FLIBS) $(FLTK_EXTRA_LIBS) $(GRAPHICS_LIBS)
+
+
+fltk_backend.oct : fltk_backend.o
+	$(DL_LD) $(DL_LDFLAGS) -o $@ $< $(OCT_LINK_DEPS) 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/graphics/fltk_backend/fltk_backend.cc	Sun Feb 17 19:20:42 2008 +0200
@@ -0,0 +1,578 @@
+/*
+
+Copyright (C) 2007 Shai Ayal
+
+This file is part of Octave.
+
+Octave 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.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#include <map>
+#include <set>
+#include <sstream>
+#include <iostream>
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Output.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Gl_Window.H>
+#include <FL/fl_ask.H>
+#include <FL/fl_draw.H>
+
+#include "oct.h"
+#include "parse.h"
+#include "graphics.h"
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gl-render.h"
+
+
+const char* help_text = "\
+Keyboard Shortcuts\n\
+a - autoscale\n\
+g - toggle grid\n\
+\n\
+Mouse\n\
+left drag - zoom\n\
+right click - unzoom\n\
+double click - copy coordinates to clipboard\
+";
+
+class OpenGL_fltk : public Fl_Gl_Window {
+public:
+  OpenGL_fltk (int x, int y, int w, int h, double num) :
+    Fl_Gl_Window (x, y, w, h, 0),
+    number (num)
+  {
+    // ask for double buffering and a depth buffer
+    mode(FL_DEPTH | FL_DOUBLE );
+  };
+  ~OpenGL_fltk () {};
+
+private:
+  double number;
+  opengl_renderer renderer;
+
+  void setup_viewport (int _w, int _h) {
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glViewport (0, 0, _w, _h);
+    //    glOrtho (0.0, 1, 0.0, 1, -1.0, 1.0);
+  }    
+
+  void draw () {
+    if (!valid ()) {
+      valid (1);
+      setup_viewport (w (), h ());
+    }
+
+#ifndef MESA
+    glDrawBuffer (GL_FRONT_AND_BACK);
+#endif // !MESA
+
+    renderer.draw (gh_manager::lookup (number));
+
+#ifndef MESA
+      glDrawBuffer (GL_BACK);
+#endif // !MESA
+  };
+
+  void resize (int _x,int _y,int _w,int _h) {
+    Fl_Gl_Window::resize (_x, _y, _w, _h);
+    setup_viewport (_w, _h);
+    redraw ();
+  };
+
+  int handle (int event)
+  {
+    int retval = Fl_Gl_Window::handle (event);
+
+    switch (event)
+      {
+      case FL_ENTER:
+	window ()->cursor (FL_CURSOR_CROSS);
+	return 1;
+      
+      case FL_LEAVE:
+	window ()->cursor (FL_CURSOR_DEFAULT);
+	return 1;
+      }
+
+    return retval;
+  };
+
+};
+
+class plot_window : public Fl_Window {
+public:
+  plot_window (int _x, int _y, int _w, int _h, double num) :
+    Fl_Window (_x, _y, _w, _h, "octave"), 
+    _number (num),
+    err_props (graphics_handle (), graphics_handle ())
+  {
+    callback (window_close, static_cast<void*> (this));
+
+    begin();
+    {
+      canvas = new 
+	OpenGL_fltk (0, 0, _w , _h - status_h, num);
+
+      autoscale = new
+	Fl_Button (0, 
+		   _h - status_h, 
+		   status_h,
+		   status_h,
+		   "A");
+      autoscale->callback (button_callback, static_cast<void*> (this));
+
+      help = new
+	Fl_Button (status_h, 
+		   _h - status_h, 
+		   status_h,
+		   status_h,
+		   "H");
+      help->callback (button_callback, static_cast<void*> (this));
+
+      status = new 
+	Fl_Output (2*status_h, 
+		   _h - status_h, 
+		   _w > 2*status_h ? _w - status_h : 0, 
+		   status_h, "");
+      
+      status->textcolor (FL_BLACK);
+      status->color (FL_GRAY);
+      status->textfont (FL_COURIER);
+      status->textsize (10);
+      status->box (FL_ENGRAVED_BOX);
+
+      // This allows us to have a valid OpenGL context right away
+      canvas->mode (FL_DEPTH | FL_DOUBLE );
+      show ();
+      canvas->show ();
+      canvas->make_current ();
+    }
+    end ();
+
+    status->show ();
+    autoscale->show ();
+
+    resizable (canvas);
+    size_range (4*status_h, 2*status_h);
+
+    std::stringstream name;
+    name << "octave: figure " << number ();
+    label (name.str ().c_str ());
+  }
+
+  ~plot_window () {
+    canvas->hide();
+    status->hide();
+    this->hide();
+    delete canvas;
+    delete status;
+  };
+
+  double number () { return _number;};
+  
+  void mark_modified () { canvas->damage (FL_DAMAGE_ALL); }
+
+private:
+  // figure number
+  double _number;
+  figure::properties err_props;
+
+  // status area height
+  static const int status_h = 20;
+  
+  // window callback
+  static void window_close (Fl_Widget* w, void* data)
+  {
+    octave_value_list args;    
+    args(0) = static_cast<plot_window*> (data)-> number (); 
+    feval("close",args);
+  }
+
+  // button callbacks
+  static void button_callback (Fl_Widget* w, void* data) {
+    static_cast<plot_window*> (data)-> button_press (w);
+  };
+
+  void button_press (Fl_Widget* widg) {
+    if (widg == autoscale) std::cout << "AS " << number () << " pressed\n";
+    if (widg == help) fl_message (help_text);
+  }
+
+  OpenGL_fltk*   canvas;
+  Fl_Button*	 autoscale;
+  Fl_Button*	 help;
+  Fl_Output*     status;
+
+
+  figure::properties& get_figure_props () {
+    graphics_object obj = gh_manager::get_object (_number);
+  
+    if (obj && obj.isa ("figure"))
+      {
+	figure::properties& fprops = 
+	  dynamic_cast<figure::properties&> (obj.get_properties ());
+	return fprops;
+      }
+
+    error("OpenGL_fltk:: Internal error -- Not associated with figure!");
+    return err_props;
+  };
+
+  void pixel2pos (int px, int py, double& x, double& y) const {
+    x = static_cast<double> (px) / w ();
+    y = 1. - static_cast<double> (py) / (h () - status_h);
+  }    
+
+  graphics_handle pixel2axes (int px, int py) {
+    
+    double x,y;
+
+    pixel2pos (px, py, x, y);
+
+    figure::properties pp = get_figure_props ();
+    Matrix children = (get_figure_props ()).get_children ();
+    for (octave_idx_type n = 0; n < children.numel (); n++) 
+      {
+	graphics_object ax = gh_manager::get_object (children (n));
+	if (ax) 
+	  {
+	    if (ax.isa ("axes")) 
+	      {
+		axes::properties& props = 
+		  dynamic_cast<axes::properties&> (ax.get_properties ());
+		Matrix pos =  props.get_position (). matrix_value ();
+		  
+		if (x >= pos(0) && x <= pos(0) + pos(2) 
+		    &&
+		    y >= pos(1) && y <= pos(1) + pos(3) )
+		  return props.get___myhandle__ ();
+	      }
+	  }
+      }
+    return graphics_handle ();
+  }
+
+  void pixel2status (int px, int py) {
+    double x,y;
+    std::stringstream cbuf;
+
+    pixel2pos (px, py, x, y);
+    cbuf << "[" << x << ", " << y <<"]";
+    status->value (cbuf.str ().c_str ());
+    status->redraw ();
+  }    
+
+  void resize (int _x,int _y,int _w,int _h) 
+  {
+    Fl_Window::resize (_x, _y, _w, _h);
+
+    Matrix pos (1,4,0);
+    pos(0) = _x;
+    pos(1) = _y;
+    pos(2) = _w;
+    pos(3) = _h;
+
+    octave_value_list args;    
+    args(0) = number ();
+    args(1) = "position";
+    args(2) = pos;
+    feval("set",args);
+  }
+ 
+  int handle (int event) {
+    static double x0,y0;
+    static graphics_handle h0 = graphics_handle ();
+    static bool in_drag = false;
+
+    int retval = Fl_Window::handle (event);
+
+    // we only handle events which are in the canvas area
+    if (Fl::event_y () >= h() - status_h)
+      return retval;
+
+    switch (event)
+      {
+      
+      case FL_MOVE:
+	pixel2status (Fl::event_x (), Fl::event_y ());
+	break;
+      
+      case FL_PUSH:
+	if (Fl::event_button () == 1)
+	  {
+	    pixel2pos (Fl::event_x (), Fl::event_y (), x0, y0);
+	    h0 = pixel2axes (Fl::event_x (), Fl::event_y ());
+	    return 1;
+	  }
+	break;
+
+      case FL_DRAG:
+	pixel2status (Fl::event_x (), Fl::event_y ());
+	if (Fl::event_button () == 1)
+	  {
+	    in_drag = true;
+	    return 1;
+	  }
+	break;
+
+      case FL_RELEASE:
+	if (Fl::event_button () == 1)
+	  {
+	    // end of drag -- zoom
+	    if (in_drag)
+	      {
+		in_drag = false;
+	      }
+	    // one click -- select axes
+	    else if ( Fl::event_clicks () == 0)
+	      {
+		if (h0.ok ())
+		  get_figure_props ().set_currentaxes (h0. value());
+		return 1;
+	      }
+	  }
+	break;
+      }
+
+    return retval;
+  }
+
+};
+
+class figure_manager {
+public:
+
+  static figure_manager& Instance () {
+    static figure_manager fm;
+    return fm;
+  }
+
+  ~figure_manager () {
+    close_all ();
+  }
+
+  void close_all () {
+    wm_iterator win;
+    for (win = windows.begin (); win != windows.end (); win++)
+      delete (*win).second;
+    windows.clear ();
+  }
+
+  void new_window (double num) {
+    if (windows.find (num) != windows.end ())
+      return;
+
+    int x,y,w,h;
+
+    default_size(x,y,w,h);
+
+    windows[num] = new plot_window (x, y, w, h, num);
+  };
+
+  void delete_window (double num) {
+    wm_iterator win;
+    if ( (win=windows.find (num)) != windows.end ())
+      {
+	delete (*win).second;
+	windows.erase (win);
+      }
+  };
+
+  void mark_modified (double num) {
+    wm_iterator win;
+    if ( (win=windows.find (num)) != windows.end ())
+      {
+	(*win).second->mark_modified ();
+      }
+  };
+
+  Matrix get_size (double num)
+  {
+    Matrix sz (1, 2, 0.0);
+
+    wm_iterator win;
+    if ( (win=windows.find (num)) != windows.end ())
+      {
+	sz(0) = (*win).second->w ();
+	sz(1) = (*win).second->h ();
+      }
+    
+    return sz;
+  }
+
+private:
+  figure_manager () {};
+  figure_manager (const figure_manager& ) {};
+  figure_manager& operator = (const figure_manager&) {return *this;};
+  // singelton -- hide all of the above
+
+
+  typedef std::map<double, plot_window*> window_map;
+  typedef window_map::iterator wm_iterator;;
+
+  window_map windows;
+
+  void default_size (int& x, int& y, int& w, int& h) {
+    x = 10;
+    y = 10;
+    w = 400;
+    h = 300;
+  }
+
+};
+
+#define FLTK_BACKEND_NAME "fltk"
+
+class fltk_backend : public base_graphics_backend
+{
+public:
+  fltk_backend (void)
+      : base_graphics_backend (FLTK_BACKEND_NAME) { }
+
+  ~fltk_backend (void) { }
+
+  bool is_valid (void) const { return true; }
+ 
+  void close_figure (const octave_value& fh) const
+    {
+      if (fh.is_real_scalar ())
+	  figure_manager::Instance ().delete_window (fh.double_value ());
+    }
+
+  void redraw_figure (const graphics_handle& fh) const
+    {
+      figure_manager::Instance ().mark_modified (fh.value ());
+    }
+
+  void print_figure (const graphics_handle& fh, const std::string& term,
+		     const std::string& file, bool mono,
+		     const std::string& debug_file) const
+    {
+    }
+
+  Matrix get_canvas_size (const graphics_handle& fh) const
+    {
+      return figure_manager::Instance ().get_size (fh.value ());
+    }
+
+  double get_screen_resolution (void) const
+    { 
+      // FLTK doesn't give this info
+      return 72.0; 
+    }
+
+  Matrix get_screen_size (void) const
+  { 
+    Matrix sz (1, 2, 0.0); 
+    sz(0) = Fl::w ();
+    sz(1) = Fl::h ();
+    return sz;
+  }
+};
+
+bool backend_registered = false;
+// call this to init the fltk backend
+DEFUN_DLD (__init_fltk__, args, nargout,"")
+{
+  graphics_backend::register_backend (new fltk_backend);
+  backend_registered = true;
+
+  octave_value retval;
+  return retval;	
+}
+
+// call this to delete the fltk backend
+DEFUN_DLD (__remove_fltk__, args, nargout,"")
+{
+  figure_manager::Instance ().close_all ();
+  graphics_backend::unregister_backend (FLTK_BACKEND_NAME);
+  backend_registered = false;
+
+
+  // give FLTK no more than 0.01 sec to do it's stuff
+  Fl::wait(1e-2);	
+  octave_value retval;
+  return retval;	
+}
+
+// call this from the idle_callback to refresh windows
+DEFUN_DLD (__fltk_redraw__, args, nargout,"internal function for the fltk backend")
+{
+  octave_value retval;
+
+  if (!backend_registered)
+    return retval;
+
+  // we scan all figures and add those which use FLTK as a backend
+  graphics_object obj = gh_manager::get_object (0);
+  if (obj && obj.isa ("root_figure"))
+    {
+      base_properties& props = obj.get_properties ();
+      Matrix children = props.get_children ();
+
+      for (octave_idx_type n = 0; n < children.numel (); n++) 
+        {
+          graphics_object fobj = gh_manager::get_object (children (n));
+          if (fobj &&  fobj.isa ("figure")) 
+	    {
+	      figure::properties& fp = 
+		dynamic_cast<figure::properties&> (fobj.get_properties ());
+	      if (fp.get___backend__ () == FLTK_BACKEND_NAME)
+		{
+		  figure_manager::Instance ().new_window (children (n));
+
+		  // put figure handle in __plot_stream__ so we know
+		  // which window to close. Only do this if necesarry
+		  // since it modifies the figure and causes a redraw
+		  octave_value ps = fp.get___plot_stream__ ();
+		  if (ps.is_real_scalar ())
+		    if (ps.double_value () == fp.get___myhandle__ ().value ())
+		      continue;
+
+		  octave_value_list oargs;   
+		  oargs(0) = fp.get___myhandle__ ().value ();
+		  oargs(1) = "__plot_stream__";
+		  oargs(2) = fp.get___myhandle__ ().value ();
+		  feval ("set" , oargs);
+		}
+	    }
+        }
+    }
+
+  // give FLTK no more than 0.01 sec to do it's stuff
+  Fl::wait(1e-2);	
+
+  return retval;	
+}
+
+/* to init
+autoload("__init_fltk__",[pwd(),"/fltk_backend.oct"])
+autoload("__remove_fltk__",[pwd(),"/fltk_backend.oct"])
+autoload("__fltk_redraw__",[pwd(),"/fltk_backend.oct"])
+input_event_hook ("__fltk_redraw__");
+__init_fltk__ ();
+set(gcf(),"__backend__","fltk")
+
+
+*/
--- a/src/graphics/opengl/gl-render.cc	Wed Feb 20 16:29:37 2008 +0100
+++ b/src/graphics/opengl/gl-render.cc	Sun Feb 17 19:20:42 2008 +0200
@@ -27,9 +27,6 @@
 #include <lo-mappers.h>
 #include "gl-render.h"
 
-#include <GL/gl.h>
-#include <GL/glu.h>
-
 #define LIGHT_MODE GL_FRONT_AND_BACK
 
 // Win32 API requires the CALLBACK attributes for
--- a/src/graphics/opengl/gl-render.h	Wed Feb 20 16:29:37 2008 +0100
+++ b/src/graphics/opengl/gl-render.h	Sun Feb 17 19:20:42 2008 +0200
@@ -23,6 +23,9 @@
 #if !defined (gl_render_h)
 #define gl_render_h 1
 
+#include <GL/gl.h>
+#include <GL/glu.h>
+
 #include "graphics.h"
 
 class