diff --git a/src/post_modules/GTK/Makefile.in b/src/post_modules/GTK/Makefile.in
index cc87e9443d88e63c9d0ac10706fa88bf819d2a24..36fc65db02cc7a8dc5e68ab5c08a57b8e08e5b0a 100644
--- a/src/post_modules/GTK/Makefile.in
+++ b/src/post_modules/GTK/Makefile.in
@@ -4,7 +4,7 @@ VPATH=@srcdir@:@srcdir@/../..:../..:.
 MODNAME=GTK
 DEST=@prefix@/lib/pike/modules/
 OBJS=dummy.o
-MODULE_LDFLAGS=@LDFLAGS@ @LIBS@ @GTKEXTRA_LIBS@ @PGTK_LIBS@ @GNOME_LIBS@ @LIBGLADE_LIBS@
+MODULE_LDFLAGS=@LDFLAGS@ @LIBS@ @DATABOX_LIBS@ @GTKEXTRA_LIBS@ @PGTK_LIBS@ @GNOME_LIBS@ @LIBGLADE_LIBS@
 MODULE_CFLAGS=@PGTK_CFLAGS@ @GTKEXTRA_CFLAGS@ @GNOME_CFLAGS@ @LIBGLADE_CFLAGS@
 CONFIG_HEADERS=config.h
 MODULE_CLEAN_EXTRA=pgtk*.c
diff --git a/src/post_modules/GTK/build_pgtk.pike b/src/post_modules/GTK/build_pgtk.pike
index 2f4e2130dc03211abda1702683278403479ee39e..da3da30b0ba05591f1701c4d12cfd0f96fd8e652 100755
--- a/src/post_modules/GTK/build_pgtk.pike
+++ b/src/post_modules/GTK/build_pgtk.pike
@@ -1185,6 +1185,8 @@ void do_default_sprintf( int args, int offset, int len )
            if( null )
              post += "  arg"+na+"[_i] = NULL;\n";
 	   break;
+	 case "!floatarray":
+           free_res=1; // Somewhat misleading reuse of variable...
 	 case "floatarray":
            if(!i_added++)
              args += "  int _i;\n";
@@ -1193,9 +1195,10 @@ void do_default_sprintf( int args, int offset, int len )
 	   format_string += "%a";
 	   args += "  struct array *_arg"+na+";\n";
 	   args += "  gfloat *arg"+na+";\n";
-	   fin += " free(arg"+na+");\n";
+           if(!free_res)
+             fin += " g_free(arg"+na+");\n";
 	   sargs += (",&_arg"+na);
-	   post += ("  arg"+na+"=malloc(sizeof(gfloat)* (_arg"+na+"->size));\n"
+	   post += ("  arg"+na+"=g_malloc(sizeof(gfloat)* (_arg"+na+"->size));\n"
 		    "  for(_i=0; _i<_arg"+na+"->size; _i++)\n"
 		    "  {\n"
 		    "    if(_arg"+na+"->item[_i].type != T_FLOAT)\n"
@@ -1206,6 +1209,8 @@ void do_default_sprintf( int args, int offset, int len )
 		    "    arg"+na+"[_i] = _arg"+na+"->item[_i].u.float_number;\n"
 		    "  }\n");
 	   break;
+	 case "!doublearray":
+           free_res=1; // Somewhat misleading reuse of variable...
 	 case "doublearray":
            if(!i_added++)
              args += "  int _i;\n";
@@ -1214,9 +1219,10 @@ void do_default_sprintf( int args, int offset, int len )
 	   format_string += "%a";
 	   args += "  struct array *_arg"+na+";\n";
 	   args += "  gdouble *arg"+na+";\n";
-	   fin += " free(arg"+na+");\n";
+           if(!free_res)
+             fin += " g_free(arg"+na+");\n";
 	   sargs += (",&_arg"+na);
-	   post += ("  arg"+na+"=malloc(sizeof(gfloat)* (_arg"+na+"->size));\n"
+	   post += ("  arg"+na+"=g_malloc(sizeof(gfloat)* (_arg"+na+"->size));\n"
 		    "  for(_i=0; _i<_arg"+na+"->size; _i++)\n"
 		    "  {\n"
 		    "    if(_arg"+na+"->item[_i].type != T_FLOAT)\n"
@@ -1227,6 +1233,8 @@ void do_default_sprintf( int args, int offset, int len )
 		    "    arg"+na+"[_i] = (gdouble)_arg"+na+"->item[_i].u.float_number;\n"
 		    "  }\n");
 	   break;
+	 case "!intarray":
+           free_res=1; // Somewhat misleading reuse of variable...
 	 case "intarray":
            if(!i_added++) args += "  int _i;\n";
 	   fundef += ",array(int)";
@@ -1234,9 +1242,10 @@ void do_default_sprintf( int args, int offset, int len )
 	   format_string += "%a";
 	   args += "  struct array *_arg"+na+";\n";
 	   args += "  gint *arg"+na+";\n";
-	   fin += " free(arg"+na+");\n";
+           if(!free_res)
+             fin += " g_free(arg"+na+");\n";
 	   sargs += (",&_arg"+na);
-	   post += ("  arg"+na+"=malloc(sizeof(gint)* (1+_arg"+na+"->size));\n"
+	   post += ("  arg"+na+"=g_malloc(sizeof(gint)* (1+_arg"+na+"->size));\n"
 		    "  for(_i=0; _i<_arg"+na+"->size; _i++)\n"
 		    "  {\n"
 		    "    if(_arg"+na+"->item[_i].type != T_INT)\n"
diff --git a/src/post_modules/GTK/configure.in b/src/post_modules/GTK/configure.in
index 4a446eb01b2ab2fa72379c933ee74a62d6ba62e9..3bafe44d90e1e9967b5b4e9cdd99d2dff3182ecb 100644
--- a/src/post_modules/GTK/configure.in
+++ b/src/post_modules/GTK/configure.in
@@ -324,7 +324,6 @@ fi
 AC_CHECK_HEADERS( X11/xpm.h )
 AC_CHECK_LIB(Xpm, XpmReadFileToXpmImage)
 
-
 AC_PATH_PROG(GTKEXTRA_CONFIG,gtkextra-config,no)
 
 AC_SUBST(pgtk_has_gtkextra)
@@ -347,6 +346,34 @@ fi
 
 
 
+AC_CHECK_LIB(gtkdatabox, main,,,`gtk-config --libs`)
+AC_CHECK_HEADERS(gtkdatabox.h)
+
+AC_SUBST(pgtk_have_gtkdatabox)
+AC_SUBST(DATABOX_LIBS)
+DATABOX_LIBS=""
+AC_MSG_CHECKING([gtkdatabox support]);
+if test x$ac_cv_lib_gtkdatabox_main = xyes ; then
+  if test x$ac_cv_header_gtkdatabox_h = xyes; then
+    AC_MSG_RESULT(yes)
+    DATABOX_LIBS=-lgtkdatabox
+    pgtk_has_gtkdatabox=gtkdatabox
+  else
+    AC_MSG_RESULT(no)
+    pgtk_has_gtkdatabox=nogtkdatabox
+    echo "*******************************************"
+    echo " Warning: Partial gtkdatabox installation  "
+    echo " Library found, but no header files.       "
+    echo " Databox support will be disabled.         "
+    echo " The widget is available from              "
+    echo " http://www.eudoxos.net/gtk/gtkdatabox/    "
+    echo "*******************************************"
+  fi
+else
+  pgtk_has_gtkdatabox=nogtkdatabox
+fi
+
+
 AC_MSG_CHECKING([OpenGL])
 
 LIBS="$saved_LIBS $GL_LDOPTS -lGL"
diff --git a/src/post_modules/GTK/make_example_image.pike b/src/post_modules/GTK/make_example_image.pike
index b008b8af212c292b7ccf6fa70f6941bef927526d..91b61950bb66997a148ebe719a39f51e49c0e2e1 100644
--- a/src/post_modules/GTK/make_example_image.pike
+++ b/src/post_modules/GTK/make_example_image.pike
@@ -4,8 +4,12 @@ object get_widget_from( string what )
 {
   array err;
   mixed res;
-  err = catch {
-    res= compile_string( "object foo(){ return "+what+"; }")()->foo();
+  err = catch
+  {
+    if( search(what, "return") == -1 )
+      res= compile_string( "object foo(){ return "+what+"; }")()->foo();
+    else
+      res= compile_string( "object foo(){ "+what+" }")()->foo();
   };
   if(!res)
     werror("Error while compiling or running "+what+"\n: %s\n", err?err[0]:"No return value");
@@ -118,8 +122,7 @@ void grab(object w)
 
 void got_event( mixed a, mixed b, object e )
 {
-  if(e->type == "expose" )
-    call_out(grab, 0.01, w );
+  call_out(grab, 0.3, w );
 }
 
 void show_recursively(object w)
@@ -157,7 +160,7 @@ int main(int argc, array (string) argv)
     ex = w = get_widget_from( argv[1] );
     w->set_border_width( 20 );
   }
-  w->signal_connect( "event", got_event, w );
+  w->signal_connect( "map_event", got_event, w );
   w->signal_connect( "destroy", _exit, 1 );
   show_recursively( w );
   return -1;
diff --git a/src/post_modules/GTK/options.in b/src/post_modules/GTK/options.in
index 0a438016e839636b6b323ca2b3ebffc1e6b999d3..b4a58dadb0ea0aa5f1ff0cc239b817590ed1c98a 100644
--- a/src/post_modules/GTK/options.in
+++ b/src/post_modules/GTK/options.in
@@ -5,3 +5,4 @@
 @pgtk_has_gnome@
 @pgtk_has_docklets@
 @pgtk_has_gtkextra@
+@pgtk_has_gtkdatabox@
diff --git a/src/post_modules/GTK/source/gtkdatabox.pre b/src/post_modules/GTK/source/gtkdatabox.pre
new file mode 100644
index 0000000000000000000000000000000000000000..125b5feec4eb701902b18476b1d8a1ec772838fd
--- /dev/null
+++ b/src/post_modules/GTK/source/gtkdatabox.pre
@@ -0,0 +1,128 @@
+require gtkdatabox;
+class databox;
+inherit vbox;
+#include <gtkdatabox.h>
+ADD_INCLUDE(#include <gtkdatabox.h>);
+// GtkDatabox is designed to display large amounts of numerical data
+// fast and easy. Thousands of data points (X and Y coordinate) may be
+// displayed without any problems, zooming and scrolling as well as
+// optional rulers are already included.
+// <p>
+// The widget may be used as display for oscilloscopes or other
+// applications that need to display fast changes in their data.
+// IMG:   GTK.Databox x=GTK.Databox(); x->data_add_x_y(3, ({ 1.0, 0.5, 0.0 }), ({1.0, -1.0, 0.0}),GDK.Color(Image.Color.red), GTK.DataboxLines,2); x->rescale(); x->set_usize(300,300); return x;
+
+constant int GTK_DATABOX_NOT_DISPLAYED;
+constant int GTK_DATABOX_POINTS;
+constant int GTK_DATABOX_LINES;
+constant int GTK_DATABOX_BARS;
+
+signal zoomed;
+signal marked;
+signal selection_started;
+signal selection_changed;
+signal selection_stopped;
+signal selection_canceled;
+
+void create();
+// Create a new databox widget
+void show_rulers();
+void hide_rulers();
+
+void show_cross();
+void hide_cross();
+
+void show_scrollbars();
+void hide_scrollbars();
+
+void enable_zoom();
+void disable_zoom();
+
+%{
+static GtkDataboxCoord get_coord(int offset,int args)
+{
+  GtkDataboxCoord c;
+  if( args < offset+2)
+    error("too few arguments\n");
+  if( sp[-args+offset].type != T_INT )
+    error("Bad argument %d\n", offset );
+  else
+    c.x = sp[-args+offset].u.integer;
+  if( sp[-args+offset+1].type != T_INT )
+    error("Bad argument %d\n", offset );
+  else
+    c.y = sp[-args+offset+1].u.integer;
+  return c;
+}
+
+static GtkDataboxValue get_value(int offset,int args)
+{
+  GtkDataboxValue c;
+  if( args < offset+2)
+    error("too few arguments\n");
+  if( sp[-args+offset].type != T_FLOAT )
+    error("Bad argument %d\n", offset );
+  else
+    c.x = sp[-args+offset].u.float_number;
+  if( sp[-args+offset+1].type != T_FLOAT )
+    error("Bad argument %d\n", offset );
+  else
+    c.y = sp[-args+offset+1].u.float_number;
+  return c;
+}
+
+static void push_value( GtkDataboxValue v )
+{
+  push_text( "x" ); push_float( v.x );
+  push_text( "y" ); push_float( v.y );
+  f_aggregate_mapping( 4 );
+}
+%}
+
+FUNCTION(data_get_value, "function(int,int:mapping)");
+NAME_ARGS(x,y);
+{
+  GtkDataboxValue v;
+  gtk_databox_data_get_value(GTK_DATABOX(THIS->obj), get_coord(0,args), &v );
+  push_value( v );
+}
+
+FUNCTION(data_get_visible_extrema, "function(void:array(mapping))");
+{
+  GtkDataboxValue v1,v2;
+  gtk_databox_data_get_visible_extrema(GTK_DATABOX(THIS->obj), &v1, &v2 );
+  push_value( v1 );
+  push_value( v2 );
+  f_aggregate(2);
+}
+
+FUNCTION(data_get_extrema, "function(void:array(mapping))");
+{
+  GtkDataboxValue v1,v2;
+  gtk_databox_data_get_extrema(GTK_DATABOX(THIS->obj), &v1, &v2 );
+  push_value( v1 );
+  push_value( v2 );
+  f_aggregate(2);
+}
+
+void rescale();
+FUNCTION(rescale_with_values, "function(float,float,float,float:object)");
+NAME_ARGS(minx,miny,maxx,maxy);
+{
+  gtk_databox_rescale_with_values(GTK_DATABOX(THIS->obj),
+                                  get_value( 0, args ),
+                                  get_value( 2, args ));
+  RETURN_THIS();
+}
+
+int set_color(int index, *GDK.Color color );
+int set_data_type( int index, int type, int dot_size );
+// Type is one of CONST(GTK_DATABOX_)
+int data_add_x_y( int nelems, !floatarray x, !floatarray y, *GDK.Color color, int type, int dot_size );
+// Type is one of CONST(GTK_DATABOX_)
+int data_add_x( int nelems, !floatarray x, int shared_Y_index, *GDK.Color color, int type, int dot_size );
+// Type is one of CONST(GTK_DATABOX_)
+int data_add_y( int nelems, !floatarray y, int shared_X_index, *GDK.Color color, int type, int dot_size );
+// Type is one of CONST(GTK_DATABOX_)
+int data_destroy( int index );
+int data_destroy_all( );