[cairo-commit] cairo-5c ChangeLog, 1.13, 1.14 Makefile.am, 1.5, 1.6 cairo-5c.h, 1.8, 1.9 cairo.5c, 1.6, 1.7 cairo.c, NONE, 1.1 draw.c, 1.4, 1.5 event.c, 1.1, 1.2 gstate.c, 1.5, 1.6 gtk.c, 1.3, 1.4 init.c, 1.9, 1.10 pattern.c, 1.2, 1.3 surface.c, 1.7, 1.8 text.c, 1.4, 1.5

Keith Packard commit at pdx.freedesktop.org
Thu Dec 23 14:39:42 PST 2004


Committed by: keithp

Update of /cvs/cairo/cairo-5c
In directory gabe:/tmp/cvs-serv25485

Modified Files:
	ChangeLog Makefile.am cairo-5c.h cairo.5c draw.c event.c 
	gstate.c gtk.c init.c pattern.c surface.c text.c 
Added Files:
	cairo.c 
Log Message:
2004-12-23  Keith Packard  <keithp at keithp.com>

	* Makefile.am:
	* cairo-5c.h:
	* cairo.5c:
	* cairo.c: (cairo_5c_get), (cairo_5c_mark), (cairo_5c_free),
	(cairo_foreign_mark), (cairo_foreign_free), (do_Cairo_create),
	(cairo_5c_dirty), (cairo_5c_enable), (cairo_5c_disable),
	(do_Cairo_set_target_surface), (do_Cairo_current_target_surface),
	(do_Cairo_destroy), (do_Cairo_copy), (do_Cairo_status),
	(do_Cairo_status_string), (do_Cairo_enable), (do_Cairo_disable):
	* draw.c: (do_Cairo_new_path), (do_Cairo_move_to),
	(do_Cairo_line_to), (do_Cairo_curve_to), (do_Cairo_arc),
	(do_Cairo_arc_negative), (do_Cairo_rel_move_to),
	(do_Cairo_rel_line_to), (do_Cairo_rel_curve_to),
	(do_Cairo_rectangle), (do_Cairo_close_path), (do_Cairo_fill),
	(do_Cairo_stroke), (do_Cairo_in_stroke), (do_Cairo_in_fill),
	(do_Cairo_stroke_extents), (do_Cairo_fill_extents),
	(do_Cairo_current_path_list), (do_Cairo_current_path_flat_list):
	* event.c: (do_Cairo_Surface_open_event):
	* examples/draw.5c:
	* examples/graph.5c:
	* examples/grid.5c:
	* examples/rottext.5c:
	* gstate.c: (do_Cairo_save), (do_Cairo_restore),
	(do_Cairo_set_operator), (do_Cairo_set_rgb_color),
	(do_Cairo_set_alpha), (do_Cairo_set_tolerance),
	(do_Cairo_set_fill_rule), (do_Cairo_set_line_width),
	(do_Cairo_set_line_cap), (do_Cairo_set_line_join),
	(do_Cairo_set_dash), (do_Cairo_set_miter_limit),
	(do_Cairo_identity_matrix), (do_Cairo_default_matrix),
	(do_Cairo_translate), (do_Cairo_scale), (do_Cairo_rotate),
	(do_Cairo_current_matrix), (do_Cairo_concat_matrix),
	(do_Cairo_set_matrix), (do_Cairo_transform_point),
	(do_Cairo_transform_distance), (do_Cairo_inverse_transform_point),
	(do_Cairo_inverse_transform_distance), (do_Cairo_init_clip),
	(do_Cairo_clip), (do_Cairo_current_operator),
	(do_Cairo_current_rgb_color), (do_Cairo_current_alpha),
	(do_Cairo_current_tolerance), (do_Cairo_current_point),
	(do_Cairo_current_fill_rule), (do_Cairo_current_line_width),
	(do_Cairo_current_line_cap), (do_Cairo_current_line_join),
	(do_Cairo_current_miter_limit):
	* gtk.c: (configure_event), (expose_event), (delete_drawing_area),
	(delete_event), (motion_notify_event), (button_press_event),
	(button_release_event), (gtk_repaint), (gtk_repaint_timeout),
	(gtk_global_mark), (gtk_global_free), (create_gtk_global),
	(gtk_tool_mark), (gtk_tool_free), (cairo_5c_tool_create),
	(cairo_5c_tool_destroy), (cairo_5c_tool_mark),
	(cairo_5c_tool_dirty), (cairo_5c_tool_disable),
	(cairo_5c_tool_enable), (cairo_5c_tool_display):
	* init.c: (init_types), (nickle_init):
	* pattern.c: (mark_cairo_pattern), (make_pattern_value),
	(do_Cairo_set_pattern), (do_Cairo_current_pattern),
	(do_Cairo_Pattern_create_for_surface):
	* surface.c: (create_cairo_window), (cairo_5c_surface_get),
	(cairo_5c_surface_mark), (cairo_5c_surface_free),
	(cairo_surface_foreign_mark), (cairo_surface_foreign_free),
	(do_Cairo_Surface_create_window), (do_Cairo_Surface_create_png),
	(do_Cairo_Surface_create_ps), (do_Cairo_Surface_create_similar),
	(do_Cairo_Surface_destroy), (do_Cairo_Surface_width),
	(do_Cairo_Surface_height):
	* text.c: (do_Cairo_select_font), (do_Cairo_set_font),
	(do_Cairo_scale_font), (do_Cairo_transform_font),
	(do_Cairo_current_font_extents), (do_Cairo_show_text),
	(do_Cairo_text_path), (do_Cairo_text_extents):
	Split cairo_t and cairo_surface_t functions apart, permitting
	more complex programs to be written that use more than a single
	window.  Switch allocations around to mostly use the nickle memory
	allocator now.  Requires updated nickle bits that expose this
	change in the foreign object API.


Index: ChangeLog
===================================================================
RCS file: /cvs/cairo/cairo-5c/ChangeLog,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- ChangeLog	19 Dec 2004 03:04:24 -0000	1.13
+++ ChangeLog	23 Dec 2004 22:39:40 -0000	1.14
@@ -1,3 +1,74 @@
+2004-12-23  Keith Packard  <keithp at keithp.com>
+
+	* Makefile.am:
+	* cairo-5c.h:
+	* cairo.5c:
+	* cairo.c: (cairo_5c_get), (cairo_5c_mark), (cairo_5c_free),
+	(cairo_foreign_mark), (cairo_foreign_free), (do_Cairo_create),
+	(cairo_5c_dirty), (cairo_5c_enable), (cairo_5c_disable),
+	(do_Cairo_set_target_surface), (do_Cairo_current_target_surface),
+	(do_Cairo_destroy), (do_Cairo_copy), (do_Cairo_status),
+	(do_Cairo_status_string), (do_Cairo_enable), (do_Cairo_disable):
+	* draw.c: (do_Cairo_new_path), (do_Cairo_move_to),
+	(do_Cairo_line_to), (do_Cairo_curve_to), (do_Cairo_arc),
+	(do_Cairo_arc_negative), (do_Cairo_rel_move_to),
+	(do_Cairo_rel_line_to), (do_Cairo_rel_curve_to),
+	(do_Cairo_rectangle), (do_Cairo_close_path), (do_Cairo_fill),
+	(do_Cairo_stroke), (do_Cairo_in_stroke), (do_Cairo_in_fill),
+	(do_Cairo_stroke_extents), (do_Cairo_fill_extents),
+	(do_Cairo_current_path_list), (do_Cairo_current_path_flat_list):
+	* event.c: (do_Cairo_Surface_open_event):
+	* examples/draw.5c:
+	* examples/graph.5c:
+	* examples/grid.5c:
+	* examples/rottext.5c:
+	* gstate.c: (do_Cairo_save), (do_Cairo_restore),
+	(do_Cairo_set_operator), (do_Cairo_set_rgb_color),
+	(do_Cairo_set_alpha), (do_Cairo_set_tolerance),
+	(do_Cairo_set_fill_rule), (do_Cairo_set_line_width),
+	(do_Cairo_set_line_cap), (do_Cairo_set_line_join),
+	(do_Cairo_set_dash), (do_Cairo_set_miter_limit),
+	(do_Cairo_identity_matrix), (do_Cairo_default_matrix),
+	(do_Cairo_translate), (do_Cairo_scale), (do_Cairo_rotate),
+	(do_Cairo_current_matrix), (do_Cairo_concat_matrix),
+	(do_Cairo_set_matrix), (do_Cairo_transform_point),
+	(do_Cairo_transform_distance), (do_Cairo_inverse_transform_point),
+	(do_Cairo_inverse_transform_distance), (do_Cairo_init_clip),
+	(do_Cairo_clip), (do_Cairo_current_operator),
+	(do_Cairo_current_rgb_color), (do_Cairo_current_alpha),
+	(do_Cairo_current_tolerance), (do_Cairo_current_point),
+	(do_Cairo_current_fill_rule), (do_Cairo_current_line_width),
+	(do_Cairo_current_line_cap), (do_Cairo_current_line_join),
+	(do_Cairo_current_miter_limit):
+	* gtk.c: (configure_event), (expose_event), (delete_drawing_area),
+	(delete_event), (motion_notify_event), (button_press_event),
+	(button_release_event), (gtk_repaint), (gtk_repaint_timeout),
+	(gtk_global_mark), (gtk_global_free), (create_gtk_global),
+	(gtk_tool_mark), (gtk_tool_free), (cairo_5c_tool_create),
+	(cairo_5c_tool_destroy), (cairo_5c_tool_mark),
+	(cairo_5c_tool_dirty), (cairo_5c_tool_disable),
+	(cairo_5c_tool_enable), (cairo_5c_tool_display):
+	* init.c: (init_types), (nickle_init):
+	* pattern.c: (mark_cairo_pattern), (make_pattern_value),
+	(do_Cairo_set_pattern), (do_Cairo_current_pattern),
+	(do_Cairo_Pattern_create_for_surface):
+	* surface.c: (create_cairo_window), (cairo_5c_surface_get),
+	(cairo_5c_surface_mark), (cairo_5c_surface_free),
+	(cairo_surface_foreign_mark), (cairo_surface_foreign_free),
+	(do_Cairo_Surface_create_window), (do_Cairo_Surface_create_png),
+	(do_Cairo_Surface_create_ps), (do_Cairo_Surface_create_similar),
+	(do_Cairo_Surface_destroy), (do_Cairo_Surface_width),
+	(do_Cairo_Surface_height):
+	* text.c: (do_Cairo_select_font), (do_Cairo_set_font),
+	(do_Cairo_scale_font), (do_Cairo_transform_font),
+	(do_Cairo_current_font_extents), (do_Cairo_show_text),
+	(do_Cairo_text_path), (do_Cairo_text_extents):
+	Split cairo_t and cairo_surface_t functions apart, permitting
+	more complex programs to be written that use more than a single
+	window.  Switch allocations around to mostly use the nickle memory
+	allocator now.  Requires updated nickle bits that expose this
+	change in the foreign object API.
+
 2004-12-18  Keith Packard  <keithp at keithp.com>
 
 	* configure.in:

Index: Makefile.am
===================================================================
RCS file: /cvs/cairo/cairo-5c/Makefile.am,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- Makefile.am	18 Dec 2004 08:16:28 -0000	1.5
+++ Makefile.am	23 Dec 2004 22:39:40 -0000	1.6
@@ -38,6 +38,7 @@
 libcairo_5c_la_SOURCES = \
 	cairo-5c.h \
 	init.c \
+	cairo.c \
 	draw.c \
 	event.c \
 	gstate.c \

Index: cairo-5c.h
===================================================================
RCS file: /cvs/cairo/cairo-5c/cairo-5c.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- cairo-5c.h	19 Dec 2004 00:06:26 -0000	1.8
+++ cairo-5c.h	23 Dec 2004 22:39:40 -0000	1.9
@@ -43,38 +43,48 @@
 #include <unistd.h>
 #undef Atom
 
-typedef enum { CAIRO_5C_WINDOW, CAIRO_5C_PNG, CAIRO_5C_SCRATCH } cairo_5c_kind_t;
+typedef enum { CAIRO_5C_WINDOW, CAIRO_5C_PNG, CAIRO_5C_PS, CAIRO_5C_SCRATCH } cairo_5c_kind_t;
 
-typedef struct _cairo_5c_x_t {
-    Display	*dpy;
-    Pixmap	pixmap;
-    int		width;
-    int		height;
-    FILE	*send_events;
-} cairo_5c_x_t;
+typedef struct _cairo_5c_tool	cairo_5c_tool_t;
 
-typedef struct {
+typedef struct _cairo_5c_window_t {
+    Pixmap	    pixmap;
+    Pixmap	    curpix;
+    cairo_5c_tool_t *tool;
+    FILE	    *send_events;
+} cairo_5c_window_t;
+
+typedef struct _cairo_png_t {
+    FILE	*file;
+} cairo_5c_png_t;
+
+typedef struct _cairo_ps_t {
+    FILE	*file;
+} cairo_5c_ps_t;
+
+typedef struct _cairo_5c_t {
+    DataType	    *data;
+    cairo_t	    *cr;
+    Value	    surface;
+} cairo_5c_t;
+
+typedef struct _cairo_5c_surface_t {
+    DataType	    *data;
     cairo_5c_kind_t kind;
-    cairo_t *cr;
-    int	    width;
-    int	    height;
-    Bool    dirty;
-    Value   recv_events;
+    cairo_surface_t *surface;
+    int		    width;
+    int		    height;
+    Bool	    dirty;
+    Value	    recv_events;
     union {
-	struct {
-	    Pixmap	    pix;
-	    cairo_5c_x_t    *x;
-	} window;
-	struct {
-	    FILE	    *file;
-	} png;
-	struct {
-	    cairo_surface_t *surface;
-	} scratch;
+	cairo_5c_window_t   window;
+	cairo_5c_png_t	    png;
+	cairo_5c_ps_t	    ps;
     } u;
-} cairo_5c_t;
+} cairo_5c_surface_t;
 
 extern Type		*typeCairo;
+extern Type		*typeCairoSurface;
 extern Type		*typeCairoStatus;
 extern Type		*typeCairoOperator;
 extern Type		*typeCairoFillRule;
@@ -83,6 +93,7 @@
 extern Type		*typeCairoFontSlant;
 extern Type		*typeCairoFontWeight;
 extern Type		*typeCairoTextExtents;
+extern Type		*typeCairoFontExtents;
 extern Type		*typeCairoMatrix;
 extern Type		*typeCairoPoint;
 extern Type		*typeCairoRect;
@@ -98,52 +109,70 @@
 extern Type		*typeCairoPatternExtend;
 extern Type		*typeCairoPatternFilter;
 
-/* surface.c */
+/* cairo.c */
+    
 cairo_5c_t *
-get_cairo_5c (Value av);
+cairo_5c_get (Value av);
 
 void
-free_cairo_5c (void *v);
+cairo_5c_dirty (cairo_5c_t *c5c);
 
-void
-dirty_cairo_5c (cairo_5c_t *c5c);
+Value
+do_Cairo_create (void);
 
 Value
-do_Cairo_new (int n, Value *v);
+do_Cairo_destroy (Value cv);
 
 Value
-do_Cairo_new_png (Value fv, Value wv, Value hv);
+do_Cairo_set_target_surface (Value cv, Value sv);
+    
+Value
+do_Cairo_current_target_surface (Value cv);
+    
+Value
+do_Cairo_copy (Value dstv, Value srcv);
 
 Value
-do_Cairo_new_scratch (Value cov, Value wv, Value hv);
+do_Cairo_status (Value cv);
 
 Value
-do_Cairo_dup (Value cov);
-    
+do_Cairo_status_string (Value cv);
+
 Value
-do_Cairo_width (Value av);
+do_Cairo_enable (Value cv);
 
 Value
-do_Cairo_height (Value av);
+do_Cairo_disable (Value cv);
+
+/* surface.c */
+
+cairo_5c_surface_t *
+cairo_5c_surface_get (Value av);
 
 Value
-do_Cairo_status (Value cv);
+do_Cairo_Surface_create_window (Value wv, Value hv);
 
 Value
-do_Cairo_status_string (Value cv);
+do_Cairo_Surface_create_png (Value fv, Value wv, Value hv);
 
 Value
-do_Cairo_dispose (Value av);
+do_Cairo_Surface_create_ps (Value fv, Value wv, Value hv, Value xppiv, Value yppiv);
 
 Value
-do_Cairo_enable (Value cv);
+do_Cairo_Surface_create_similar (Value sv, Value wv, Value hv);
 
 Value
-do_Cairo_disable (Value cv);
+do_Cairo_Surface_destroy (Value sv);
+
+Value
+do_Cairo_Surface_width (Value sv);
+
+Value
+do_Cairo_Surface_height (Value sv);
 
 /* event.c */
 Value
-do_Cairo_open_event (Value cv);
+do_Cairo_Surface_open_event (Value sv);
 
 /* init.c */
 Value
@@ -212,6 +241,9 @@
 do_Cairo_current_matrix (Value cv);
 
 Value
+do_Cairo_concat_matrix (Value cv, Value mv);
+
+Value
 do_Cairo_set_matrix (Value cv, Value mv);
 
 Value
@@ -399,6 +431,9 @@
 do_Cairo_transform_font (Value cv, Value mv);
 
 Value
+do_Cairo_current_font_extents (Value cv);
+
+Value
 do_Cairo_show_text (Value cv, Value uv);
 
 Value
@@ -406,25 +441,29 @@
 
 Value
 do_Cairo_text_extents (Value cv, Value uv);
-    
-Value
-do_Cairo_select_ft_font (Value pv);
 
-/* gtk+.c */
-cairo_5c_x_t *
-start_x (int width, int height);
 
-void
-repaint_x (cairo_5c_x_t *c5cx, int x, int y, int w, int h);
+/* gtk.c */
+
+Bool
+cairo_5c_tool_create (cairo_5c_surface_t *c5s, int width, int height);
+
+Bool
+cairo_5c_tool_destroy (cairo_5c_surface_t *c5s);
 
 void
-dirty_x (cairo_5c_x_t *c5cx, int x, int y, int w, int h);
+cairo_5c_tool_dirty (cairo_5c_surface_t *c5s);
 
 Bool
-enable_x  (cairo_5c_x_t *c5cx);
+cairo_5c_tool_disable (cairo_5c_surface_t *c5s);
 
 Bool
-disable_x (cairo_5c_x_t *c5cx);
+cairo_5c_tool_enable (cairo_5c_surface_t *c5s);
+
+Display *
+cairo_5c_tool_display (cairo_5c_surface_t *c5s);
+
+void
+cairo_5c_tool_mark (cairo_5c_surface_t *c5s);
 
-    
 #endif /* _CAIRO_5C_H_ */

Index: cairo.5c
===================================================================
RCS file: /cvs/cairo/cairo-5c/cairo.5c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- cairo.5c	19 Dec 2004 00:06:26 -0000	1.6
+++ cairo.5c	23 Dec 2004 22:39:40 -0000	1.7
@@ -46,6 +46,79 @@
 	real hue, saturation, value;
     } hsv_color_t;
     
+    public int width (cairo_t cr) = 
+	Surface::width (current_target_surface (cr));
+    
+    public int height (cairo_t cr) = 
+	Surface::height (current_target_surface (cr));
+    
+    public file open_event (cairo_t cr) =
+	Surface::open_event (current_target_surface (cr));
+
+    public cairo_t new (int args...) {
+	int w = dim(args) > 0 ? args[0] : 0;
+	int h = dim(args) > 1 ? args[1] : 0;
+
+	static surface_t    surface;
+	static bool	    been_here = false;
+	static mutex	    m = Mutex::new();
+
+	Mutex::acquire (m);
+	if (!been_here) {
+	    been_here = true;
+	    surface = Surface::create_window (w, h);
+	}
+	Mutex::release (m);
+
+	cairo_t	cr = create ();
+	set_target_surface (cr, surface);
+	set_rgb_color (cr, 1, 1, 1);
+	rectangle (cr, 0, 0, Cairo::width (cr), Cairo::height (cr));
+	fill (cr);
+	set_rgb_color (cr, 0, 0, 0);
+	return cr;
+    }
+
+    public cairo_t new_png (string filename, int width, int height)
+    {
+	surface_t   surface = Surface::create_png (filename, width, height);
+	cairo_t	    cr = create ();
+	set_target_surface (cr, surface);
+	set_target_surface (cr, surface);
+	set_rgb_color (cr, 0, 0, 0);
+	set_alpha (cr, 0);
+	rectangle (cr, 0, 0, Cairo::width (cr), Cairo::height (cr));
+	fill (cr);
+	set_rgb_color (cr, 0, 0, 0);
+	set_alpha (cr, 1);
+	return cr;
+    }
+    
+    public cairo_t new_ps (string filename, 
+			   real width, real height,
+			   real xppi, real yppi)
+    {
+	surface_t   surface = Surface::create_ps (filename, width, height,
+						  xppi, yppi);
+	cairo_t	    cr = create ();
+	set_target_surface (cr, surface);
+	set_target_surface (cr, surface);
+	set_rgb_color (cr, 1, 1, 1);
+	rectangle (cr, 0, 0, Cairo::width (cr), Cairo::height (cr));
+	fill (cr);
+	set_rgb_color (cr, 0, 0, 0);
+	return cr;
+    }
+    
+    public cairo_t dup (cairo_t cr)
+    {
+	cairo_t	n = create ();
+
+	set_target_surface (n, current_target_surface (cr));
+	copy (n, cr);
+	return n;
+    }
+    
     void walk_path (path_t  path,
 		    move_to_func_t move_to,
 		    line_to_func_t line_to,

--- NEW FILE: cairo.c ---
(This appears to be a binary file; contents omitted.)

Index: draw.c
===================================================================
RCS file: /cvs/cairo/cairo-5c/draw.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- draw.c	17 Dec 2004 09:40:43 -0000	1.4
+++ draw.c	23 Dec 2004 22:39:40 -0000	1.5
@@ -37,7 +37,7 @@
 Value
 do_Cairo_new_path (Value cv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
 
     if (!aborting)
 	cairo_new_path (c5c->cr);
@@ -47,7 +47,7 @@
 Value
 do_Cairo_move_to (Value cv, Value xv, Value yv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x = DoublePart (xv, "invalid X value");
     double	y = DoublePart (yv, "invalid Y value");
 
@@ -59,7 +59,7 @@
 Value
 do_Cairo_line_to (Value cv, Value xv, Value yv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x = DoublePart (xv, "invalid X value");
     double	y = DoublePart (yv, "invalid Y value");
 
@@ -74,7 +74,7 @@
 		   Value x2v, Value y2v,
 		   Value x3v, Value y3v)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x1 = DoublePart (x1v, "invalid X1 value");
     double	y1 = DoublePart (y1v, "invalid Y1 value");
     double	x2 = DoublePart (x2v, "invalid X2 value");
@@ -93,7 +93,7 @@
 	      Value x2v, Value y2v,
 	      Value rv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x1 = DoublePart (x1v, "invalid X1 value");
     double	y1 = DoublePart (y1v, "invalid Y1 value");
     double	x2 = DoublePart (x2v, "invalid X2 value");
@@ -111,7 +111,7 @@
 		       Value x2v, Value y2v,
 		       Value rv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x1 = DoublePart (x1v, "invalid X1 value");
     double	y1 = DoublePart (y1v, "invalid Y1 value");
     double	x2 = DoublePart (x2v, "invalid X2 value");
@@ -126,7 +126,7 @@
 Value
 do_Cairo_rel_move_to (Value cv, Value xv, Value yv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x = DoublePart (xv, "invalid X value");
     double	y = DoublePart (yv, "invalid Y value");
 
@@ -138,7 +138,7 @@
 Value
 do_Cairo_rel_line_to (Value cv, Value xv, Value yv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x = DoublePart (xv, "invalid X value");
     double	y = DoublePart (yv, "invalid Y value");
 
@@ -153,7 +153,7 @@
 		   Value x2v, Value y2v,
 		   Value x3v, Value y3v)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x1 = DoublePart (x1v, "invalid X1 value");
     double	y1 = DoublePart (y1v, "invalid Y1 value");
     double	x2 = DoublePart (x2v, "invalid X2 value");
@@ -169,7 +169,7 @@
 Value
 do_Cairo_rectangle (Value cv, Value xv, Value yv, Value wv, Value hv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x = DoublePart (xv, "invalid x value");
     double	y = DoublePart (yv, "invalid y value");
     double	w = DoublePart (wv, "invalid width value");
@@ -183,7 +183,7 @@
 Value
 do_Cairo_close_path (Value cv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
 
     if (!aborting)
 	cairo_close_path (c5c->cr);
@@ -193,12 +193,12 @@
 Value
 do_Cairo_fill (Value cv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
 
     if (!aborting)
     {
 	cairo_fill (c5c->cr);
-	dirty_cairo_5c (c5c);
+	cairo_5c_dirty (c5c);
     }
     return Void;
 }
@@ -206,11 +206,11 @@
 Value
 do_Cairo_stroke (Value cv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
 
     if (!aborting) {
 	cairo_stroke (c5c->cr);
-	dirty_cairo_5c (c5c);
+	cairo_5c_dirty (c5c);
     }
     return Void;
 }
@@ -218,7 +218,7 @@
 Value
 do_Cairo_in_stroke (Value cv, Value xv, Value yv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x = DoublePart (xv, "invalid X value");
     double	y = DoublePart (yv, "invalid Y value");
 
@@ -231,7 +231,7 @@
 Value
 do_Cairo_in_fill (Value cv, Value xv, Value yv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x = DoublePart (xv, "invalid X value");
     double	y = DoublePart (yv, "invalid Y value");
 
@@ -245,7 +245,7 @@
 do_Cairo_stroke_extents (Value cv)
 {
     ENTER ();
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x, y, w, h;
     Value	ret;
     static int	dims[2] = { 2, 2 };
@@ -265,7 +265,7 @@
 do_Cairo_fill_extents (Value cv)
 {
     ENTER ();
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x, y, w, h;
     Value	ret;
     static int	dims[2] = { 2, 2 };
@@ -369,7 +369,7 @@
 {
     ENTER ();
     path_closure_t  close;
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     
     if (aborting)
 	RETURN (Void);
@@ -389,7 +389,7 @@
 {
     ENTER ();
     path_closure_t  close;
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     
     if (aborting)
 	RETURN (Void);

Index: event.c
===================================================================
RCS file: /cvs/cairo/cairo-5c/event.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- event.c	17 Dec 2004 02:10:21 -0000	1.1
+++ event.c	23 Dec 2004 22:39:40 -0000	1.2
@@ -37,32 +37,50 @@
 #include <errno.h>
 
 Value
-do_Cairo_open_event (Value cv)
+do_Cairo_Surface_open_event (Value sv)
 {
     ENTER ();
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
-    Value	read;
-    int		fd[2];
-    FILE	*write;
+    cairo_5c_surface_t	*c5s = cairo_5c_surface_get (sv);
+    Value		read;
+    int			fd[2];
+    FILE		*write;
+    int			err;
 
     if (aborting)
 	RETURN(Void);
-    if (!c5c->recv_events)
+    
+    if (c5s->recv_events == Void)
     {
-	if (pipe (fd) < 0)
-	{
-	    int err = errno;
-	    RaiseStandardException (exception_open_error,
-				    FileGetErrorMessage (err),
-				    2, FileGetError (err), Void);
-	    RETURN (Void);
+	switch (c5s->kind) {
+	case CAIRO_5C_WINDOW:
+	    if (pipe (fd) < 0)
+	    {
+		err = errno;
+		RaiseStandardException (exception_open_error,
+					FileGetErrorMessage (err),
+					2, FileGetError (err), Void);
+		RETURN (Void);
+	    }
+	    read = FileCreate (fd[0], FileReadable);
+	    if (aborting)
+		RETURN(Void);
+	    write = fdopen (fd[1], "w");
+	    c5s->u.window.send_events = write;
+	    break;
+	case CAIRO_5C_PNG:
+	case CAIRO_5C_PS:
+	case CAIRO_5C_SCRATCH:
+	    read = FileFopen ("/dev/null", "r", &err);
+	    if (!c5s->recv_events)
+	    {
+		RaiseStandardException (exception_open_error,
+					FileGetErrorMessage (err),
+					2, FileGetError (err), Void);
+		RETURN (Void);
+	    }
+	    break;
 	}
-	read = FileCreate (fd[0], FileReadable);
-	if (aborting)
-	    RETURN(Void);
-	write = fdopen (fd[1], "w");
-	c5c->recv_events = read;
-	c5c->u.window.x->send_events = write;
+	c5s->recv_events = read;
     }
-    RETURN (c5c->recv_events);
+    RETURN (c5s->recv_events);
 }

Index: gstate.c
===================================================================
RCS file: /cvs/cairo/cairo-5c/gstate.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- gstate.c	18 Dec 2004 08:16:28 -0000	1.5
+++ gstate.c	23 Dec 2004 22:39:40 -0000	1.6
@@ -38,7 +38,7 @@
 Value
 do_Cairo_save (Value cv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     if (!aborting)
 	cairo_save (c5c->cr);
     return Void;
@@ -47,7 +47,7 @@
 Value
 do_Cairo_restore (Value cv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     if (!aborting)
 	cairo_restore (c5c->cr);
     return Void;
@@ -56,7 +56,7 @@
 Value
 do_Cairo_set_operator (Value cv, Value ov)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     int		o = EnumIntPart (ov, "invalid operator");
 
     if (!aborting)
@@ -67,7 +67,7 @@
 Value
 do_Cairo_set_rgb_color (Value cv, Value rv, Value gv, Value bv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	r = DoublePart (rv, "invalid red value");
     double	g = DoublePart (gv, "invalid green value");
     double	b = DoublePart (bv, "invalid blue value");
@@ -80,7 +80,7 @@
 Value
 do_Cairo_set_alpha (Value cv, Value av)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	a = DoublePart (av, "invalid alpha value");
 
     if (!aborting)
@@ -91,7 +91,7 @@
 Value
 do_Cairo_set_tolerance (Value cv, Value tv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	t = DoublePart (tv, "invalid tolerance");
 
     if (!aborting)
@@ -102,7 +102,7 @@
 Value
 do_Cairo_set_fill_rule (Value cv, Value fv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     int		f = EnumIntPart (fv, "invalid fill rule");
 
     if (!aborting)
@@ -113,7 +113,7 @@
 Value
 do_Cairo_set_line_width (Value cv, Value lv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	l = DoublePart (lv, "invalid line_width");
 
     if (!aborting)
@@ -124,7 +124,7 @@
 Value
 do_Cairo_set_line_cap (Value cv, Value lv)
 {
-    cairo_5c_t		*c5c = get_cairo_5c (cv);
+    cairo_5c_t		*c5c = cairo_5c_get (cv);
     cairo_line_cap_t	l = EnumIntPart (lv, "invalid line_cap");
 
     if (!aborting)
@@ -135,7 +135,7 @@
 Value
 do_Cairo_set_line_join (Value cv, Value lv)
 {
-    cairo_5c_t		*c5c = get_cairo_5c (cv);
+    cairo_5c_t		*c5c = cairo_5c_get (cv);
     cairo_line_join_t	l = EnumIntPart (lv, "invalid line_join");
 
     if (!aborting)
@@ -147,7 +147,7 @@
 do_Cairo_set_dash (Value cv, Value dv, Value ov)
 {
     ENTER ();
-    cairo_5c_t		*c5c = get_cairo_5c (cv);
+    cairo_5c_t		*c5c = cairo_5c_get (cv);
     double		o = DoublePart (ov, "invalid dash offset");
     int			ndash = ArrayLimits (&dv->array)[0];
     double		*d = AllocateTemp (ndash * sizeof (double));
@@ -168,7 +168,7 @@
 Value
 do_Cairo_set_miter_limit (Value cv, Value mv)
 {
-    cairo_5c_t		*c5c = get_cairo_5c (cv);
+    cairo_5c_t		*c5c = cairo_5c_get (cv);
     double		m = DoublePart (mv, "invalid miter limit");
     
     if (!aborting)
@@ -179,7 +179,7 @@
 Value
 do_Cairo_identity_matrix (Value cv)
 {
-    cairo_5c_t		*c5c = get_cairo_5c (cv);
+    cairo_5c_t		*c5c = cairo_5c_get (cv);
     if (!aborting)
 	cairo_identity_matrix (c5c->cr);
     return Void;
@@ -188,7 +188,7 @@
 Value
 do_Cairo_default_matrix (Value cv)
 {
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
 
     if (aborting)
 	return Void;
@@ -199,7 +199,7 @@
 Value
 do_Cairo_translate (Value cv, Value xv, Value yv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x = DoublePart (xv, "invalid X value");
     double	y = DoublePart (yv, "invalid Y value");
 
@@ -211,7 +211,7 @@
 Value
 do_Cairo_scale (Value cv, Value xv, Value yv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	x = DoublePart (xv, "invalid X value");
     double	y = DoublePart (yv, "invalid Y value");
 
@@ -223,7 +223,7 @@
 Value
 do_Cairo_rotate (Value cv, Value av)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
     double	a = DoublePart (av, "invalid angle");
 
     if (!aborting)
@@ -235,7 +235,7 @@
 do_Cairo_current_matrix (Value cv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     cairo_matrix_t  *matrix;
     Value	    ret;
 
@@ -258,10 +258,27 @@
 }
 
 Value
+do_Cairo_concat_matrix (Value cv, Value mv)
+{
+    ENTER ();
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
+    cairo_matrix_t  *matrix;
+
+    if (aborting)
+	RETURN(Void);
+    matrix = cairo_matrix_part (mv, "invalid matrix");
+    if (aborting)
+	RETURN(Void);
+    cairo_concat_matrix (c5c->cr, matrix);
+    cairo_matrix_destroy (matrix);
+    RETURN (Void);
+}
+
+Value
 do_Cairo_set_matrix (Value cv, Value mv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     cairo_matrix_t  *matrix;
 
     if (aborting)
@@ -278,7 +295,7 @@
 do_Cairo_transform_point (Value cv, Value pv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     double	    x, y;
     Value	    ret;
     BoxPtr	    box;
@@ -300,7 +317,7 @@
 do_Cairo_transform_distance (Value cv, Value pv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     double	    x, y;
     Value	    ret;
     BoxPtr	    box;
@@ -322,7 +339,7 @@
 do_Cairo_inverse_transform_point (Value cv, Value pv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     double	    x, y;
     Value	    ret;
     BoxPtr	    box;
@@ -344,7 +361,7 @@
 do_Cairo_inverse_transform_distance (Value cv, Value pv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     double	    x, y;
     Value	    ret;
     BoxPtr	    box;
@@ -365,7 +382,7 @@
 Value
 do_Cairo_init_clip (Value cv)
 {
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     if (!aborting)
 	cairo_init_clip (c5c->cr);
     return Void;
@@ -374,7 +391,7 @@
 Value
 do_Cairo_clip (Value cv)
 {
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     if (!aborting)
 	cairo_clip (c5c->cr);
     return Void;
@@ -383,7 +400,7 @@
 Value
 do_Cairo_current_operator (Value cv)
 {
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     
     if (aborting)
 	return Void;
@@ -394,7 +411,7 @@
 do_Cairo_current_rgb_color (Value cv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     double	    r, g, b;
     Value	    ret;
     BoxPtr	    box;
@@ -414,7 +431,7 @@
 do_Cairo_current_alpha (Value cv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     
     if (aborting)
 	RETURN(Void);
@@ -425,7 +442,7 @@
 do_Cairo_current_tolerance (Value cv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     
     if (aborting)
 	RETURN(Void);
@@ -436,7 +453,7 @@
 do_Cairo_current_point (Value cv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     double	    x, y;
     Value	    ret;
     BoxPtr	    box;
@@ -455,7 +472,7 @@
 do_Cairo_current_fill_rule (Value cv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     
     if (aborting)
 	RETURN(Void);
@@ -466,7 +483,7 @@
 do_Cairo_current_line_width (Value cv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     
     if (aborting)
 	RETURN(Void);
@@ -477,7 +494,7 @@
 do_Cairo_current_line_cap (Value cv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     
     if (aborting)
 	RETURN(Void);
@@ -488,7 +505,7 @@
 do_Cairo_current_line_join (Value cv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     
     if (aborting)
 	RETURN(Void);
@@ -499,7 +516,7 @@
 do_Cairo_current_miter_limit (Value cv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     
     if (aborting)
 	RETURN(Void);

Index: gtk.c
===================================================================
RCS file: /cvs/cairo/cairo-5c/gtk.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- gtk.c	17 Dec 2004 02:09:45 -0000	1.3
+++ gtk.c	23 Dec 2004 22:39:40 -0000	1.4
@@ -39,24 +39,37 @@
 #include <gdk/gdkx.h>
 #include <pthread.h>
 
+typedef struct _gtk_global {
+    DataType	*data;
+    Display	*dpy;
+    pthread_t	gtk_thread;
+} gtk_global_t;
 
-typedef struct _cairo_5c_gtk {
-    cairo_5c_x_t    x;
-    int		    dirty;
-    int		    disable;
-    GtkWidget	    *window;
-    GtkWidget	    *drawing_area;
-    GdkPixmap	    *pixmap;
-} cairo_5c_gtk_t;
+struct _cairo_5c_tool {
+    DataType		*data;
+    gtk_global_t	*global;
+    int			dirty;
+    int			disable;
+    GtkWidget		*window;
+    GtkWidget		*drawing_area;
+    GdkPixmap		*pixmap;
+};
+
+static gtk_global_t *gtk_global;
 
+/*
+ * This part runs in the gtk thread, so it must not refer to or use
+ * any memory managed by nickle
+ */
 static gboolean
 configure_event (GtkWidget *widget, GdkEventConfigure *event)
 {
     GdkPixmap		*pixmap;
-    cairo_5c_gtk_t	*c5cg = GTK_DRAWING_AREA (widget)->draw_data;
+    cairo_5c_surface_t	*c5s = GTK_DRAWING_AREA (widget)->draw_data;
+    cairo_5c_tool_t	*tool = c5s->u.window.tool;
 
-    c5cg->x.width = widget->allocation.width;
-    c5cg->x.height = widget->allocation.height;
+    c5s->width = widget->allocation.width;
+    c5s->height = widget->allocation.height;
     pixmap = gdk_pixmap_new (widget->window,
 			     widget->allocation.width,
 			     widget->allocation.height,
@@ -67,44 +80,63 @@
 			0, 0,
 			widget->allocation.width,
 			widget->allocation.height);
-    if (c5cg->pixmap)
+    if (tool->pixmap)
     {
 	gdk_draw_drawable (pixmap, widget->style->white_gc,
-			   c5cg->pixmap, 0, 0, 0, 0, 
+			   tool->pixmap, 0, 0, 0, 0, 
 			   widget->allocation.width,
 			   widget->allocation.height);
-	gdk_pixmap_unref (c5cg->pixmap);
+	gdk_drawable_unref (tool->pixmap);
     }
-    c5cg->pixmap = pixmap;
-    c5cg->x.pixmap = GDK_PIXMAP_XID (GDK_DRAWABLE(c5cg->pixmap));
+    tool->pixmap = pixmap;
+    c5s->u.window.pixmap = GDK_PIXMAP_XID (GDK_DRAWABLE(tool->pixmap));
     return TRUE;
 }
 
 static gboolean
 expose_event( GtkWidget *widget, GdkEventExpose *event )
 {
-    cairo_5c_gtk_t	*c5cg = GTK_DRAWING_AREA (widget)->draw_data;
+    cairo_5c_surface_t	*c5s = GTK_DRAWING_AREA (widget)->draw_data;
+    cairo_5c_tool_t	*tool = c5s->u.window.tool;
     
     gdk_draw_pixmap(widget->window,
 		    widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-		    c5cg->pixmap,
+		    tool->pixmap,
 		    event->area.x, event->area.y,
 		    event->area.x, event->area.y,
 		    event->area.width, event->area.height);
+    return FALSE;
+}
 
+static void
+delete_drawing_area (GtkWidget *widget, gpointer data)
+{			   
+    cairo_5c_surface_t	*c5s = GTK_DRAWING_AREA (widget)->draw_data;
+    
+    if (c5s->u.window.send_events)
+    {
+	fprintf (c5s->u.window.send_events, "%d delete\n", 0);
+	fflush (c5s->u.window.send_events);
+    }
+}
+
+static gboolean
+delete_event( GtkWidget *widget, GdkEventAny *event )
+{
+    gtk_container_foreach (GTK_CONTAINER(widget), delete_drawing_area, NULL);
     return FALSE;
 }
 
 static gboolean
 motion_notify_event( GtkWidget *widget, GdkEventMotion *event )
 {
-    cairo_5c_gtk_t	*c5cg = GTK_DRAWING_AREA (widget)->draw_data;
+    cairo_5c_surface_t	*c5s = GTK_DRAWING_AREA (widget)->draw_data;
     
-    if (c5cg->x.send_events)
+    if (c5s->u.window.send_events)
     {
-	fprintf (c5cg->x.send_events, "%d motion %g %g\n",
+	fprintf (c5s->u.window.send_events, "%d motion %g %g\n",
 		 event->time, event->x, event->y);
-	fflush (c5cg->x.send_events);
+	fflush (c5s->u.window.send_events);
     }
     return FALSE;
 }
@@ -113,13 +145,13 @@
 static gboolean
 button_press_event( GtkWidget *widget, GdkEventButton *event )
 {
-    cairo_5c_gtk_t	*c5cg = GTK_DRAWING_AREA (widget)->draw_data;
+    cairo_5c_surface_t	*c5s = GTK_DRAWING_AREA (widget)->draw_data;
     
-    if (c5cg->x.send_events)
+    if (c5s->u.window.send_events)
     {
-	fprintf (c5cg->x.send_events, "%d press %d %g %g\n",
+	fprintf (c5s->u.window.send_events, "%d press %d %g %g\n",
 		 event->time, event->button, event->x, event->y);
-	fflush (c5cg->x.send_events);
+	fflush (c5s->u.window.send_events);
     }
     return FALSE;
 }
@@ -127,100 +159,53 @@
 static gboolean
 button_release_event( GtkWidget *widget, GdkEventButton *event )
 {
-    cairo_5c_gtk_t	*c5cg = GTK_DRAWING_AREA (widget)->draw_data;
+    cairo_5c_surface_t	*c5s = GTK_DRAWING_AREA (widget)->draw_data;
     
-    if (c5cg->x.send_events)
+    if (c5s->u.window.send_events)
     {
-	fprintf (c5cg->x.send_events, "%d release %d %g %g\n",
+	fprintf (c5s->u.window.send_events, "%d release %d %g %g\n",
 		 event->time, event->button, event->x, event->y);
-	fflush (c5cg->x.send_events);
+	fflush (c5s->u.window.send_events);
     }
     return FALSE;
 }
 
-
-static cairo_5c_gtk_t *
-cairo_5c_window_new (int width, int height)
+static void
+gtk_repaint (cairo_5c_surface_t *c5s, int x, int y, int w, int h)
 {
-    cairo_5c_gtk_t	*c5cg = malloc (sizeof (cairo_5c_gtk_t));
-    Display		*dpy;
-
-    c5cg->pixmap = 0;
-    c5cg->x.send_events = 0;
-    c5cg->x.dpy = gdk_x11_get_default_xdisplay ();
-    dpy = c5cg->x.dpy;
-    if (!width)
-	width = XDisplayWidth (dpy, DefaultScreen (dpy)) / 3;
-    if (!height)
-	height = XDisplayWidth (dpy, DefaultScreen (dpy)) / 3;
-    c5cg->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-    gtk_window_set_default_size (GTK_WINDOW(c5cg->window),
-				 width, height);
-    
-    c5cg->drawing_area = gtk_drawing_area_new ();
-    
-    GTK_DRAWING_AREA (c5cg->drawing_area)->draw_data = c5cg;
-    
-    gtk_container_add (GTK_CONTAINER(c5cg->window), c5cg->drawing_area);
-    
-    g_signal_connect (GTK_OBJECT (c5cg->drawing_area), "expose_event",
-		      (GtkSignalFunc) expose_event, NULL);
-    g_signal_connect (GTK_OBJECT(c5cg->drawing_area),"configure_event",
-		      (GtkSignalFunc) configure_event, NULL);
-    g_signal_connect (GTK_OBJECT (c5cg->drawing_area), "motion_notify_event",
-		      (GtkSignalFunc) motion_notify_event, NULL);
-    g_signal_connect (GTK_OBJECT (c5cg->drawing_area), "button_press_event",
-		      (GtkSignalFunc) button_press_event, NULL);
-    g_signal_connect (GTK_OBJECT (c5cg->drawing_area), "button_release_event",
-		      (GtkSignalFunc) button_release_event, NULL);
-
-    gtk_widget_set_events (c5cg->drawing_area, GDK_EXPOSURE_MASK
-			   | GDK_LEAVE_NOTIFY_MASK
-			   | GDK_BUTTON_PRESS_MASK
-			   | GDK_BUTTON_RELEASE_MASK
-			   | GDK_POINTER_MOTION_MASK);
-
-    gtk_widget_realize (c5cg->window);
-    gtk_widget_realize (c5cg->drawing_area);
-    gdk_window_set_back_pixmap (GTK_WIDGET(c5cg->drawing_area)->window, NULL, FALSE);
-    gtk_widget_show (c5cg->drawing_area);
-    gtk_widget_show (c5cg->window);
-    configure_event (c5cg->drawing_area, 0);
+    cairo_5c_tool_t *tool = c5s->u.window.tool;
+    GtkWidget	    *widget = tool->drawing_area;
+    GdkPixmap	    *pixmap = tool->pixmap;
     
-    return c5cg;
-}
-
-void
-repaint_x (cairo_5c_x_t *c5cx, int x, int y, int w, int h)
-{
-    cairo_5c_gtk_t  *c5cg = (cairo_5c_gtk_t *) c5cx;
-    GtkWidget	    *widget = c5cg->drawing_area;
-    Window	    xwin = GDK_WINDOW_XID (widget->window);
-    GdkPixmap	    *pixmap = c5cg->pixmap;
-    Pixmap	    xpix = GDK_PIXMAP_XID (pixmap);
-    Display	    *dpy = gdk_x11_get_default_xdisplay ();
-    GC		    xgc = GDK_GC_XGC(widget->style->white_gc);
-
-    if (xwin && xpix && xgc)
+    if (widget && pixmap)
     {
-	if (w == 0)
-	    w = c5cg->x.width - x;
-	if (h == 0)
-	    h = c5cg->x.height - y;
-	XCopyArea (dpy, xpix, xwin, xgc, x, y, w, h, x, y);
-	XFlush (dpy);
+	Window	    xwin = GDK_WINDOW_XID (widget->window);
+	Pixmap	    xpix = GDK_PIXMAP_XID (pixmap);
+	Display	    *dpy = tool->global->dpy;
+	GC	    xgc = GDK_GC_XGC(widget->style->white_gc);
+    
+	if (xwin && xpix && xgc)
+	{
+	    if (w == 0)
+		w = c5s->width - x;
+	    if (h == 0)
+		h = c5s->height - y;
+	    XCopyArea (dpy, xpix, xwin, xgc, x, y, w, h, x, y);
+	    XFlush (dpy);
+	}
     }
 }
 
 static gboolean
 gtk_repaint_timeout (gpointer data)
 {
-    cairo_5c_gtk_t  *c5cg = data;
+    cairo_5c_surface_t	*c5s = data;
+    cairo_5c_tool_t	*tool = c5s->u.window.tool;
 
-    if (c5cg->disable == 0)
+    if (tool->disable == 0)
     {
-	c5cg->dirty = 0;
-	repaint_x (&c5cg->x, 0, 0, 0, 0);
+	tool->dirty = 0;
+	gtk_repaint (c5s, 0, 0, 0, 0);
     }
     return FALSE;
 }
@@ -232,68 +217,251 @@
     return 0;
 }
 
-static cairo_5c_gtk_t *c5cg;
+/*
+ * Manage the gtk_global object, starting the thread and such
+ */
+static void
+gtk_global_mark (void *object)
+{
+}
 
-cairo_5c_x_t *
-start_x (int width, int height)
+static int
+gtk_global_free (void *object)
 {
-    pthread_t	gtk_thread;
+    gtk_global_t    *gg = object;
+
+    gdk_threads_enter ();
+    gtk_main_quit ();
+    gdk_threads_leave ();
+    if (gg == gtk_global)
+	gtk_global = NULL;
+    return 1;
+}
+
+static DataType	gtk_global_type = { gtk_global_mark, gtk_global_free, "GtkGlobal" };
+
+static gtk_global_t *
+create_gtk_global (void)
+{
+    ENTER ();
+    static int	been_here = 0;
     static int	argc = 1;
     static char	*args[] = { "nickle", 0 };
     static char **argv = args;
+    gtk_global_t    *gg;
 
-    if (!c5cg)
+    if (!been_here)
     {
 	XInitThreads ();
 	g_thread_init (NULL);
 	gdk_threads_init ();
-	gtk_init (&argc, &argv);
-	c5cg = cairo_5c_window_new (width, height);
+	been_here = 1;
+    }
     
-	pthread_create (&gtk_thread, 0, gtk_thread_main, c5cg);
+    if (!gtk_init_check (&argc, &argv))
+    {
+	const char *display_name_arg = gdk_get_display_arg_name ();
+	RaiseStandardException (exception_open_error,
+				"cannot open X display",
+				0, NewStrString (display_name_arg));
+	RETURN (Void);
     }
-    return &c5cg->x;
+	
+    gg = ALLOCATE (&gtk_global_type, sizeof (gtk_global_t));
+    
+    gg->dpy = gdk_x11_get_default_xdisplay ();
+    
+    pthread_create (&gg->gtk_thread, 0, gtk_thread_main, gg);
+    if (!gtk_global)
+	gtk_global = gg;
+    RETURN (gg);
+}
+
+/*
+ * manage a the gtk piece of an xlib surface
+ */
+
+static void
+gtk_tool_mark (void *object)
+{
+    cairo_5c_tool_t *tool = object;
+
+    MemReference (tool->global);
+}
+
+static int
+gtk_tool_free (void *object)
+{
+    cairo_5c_tool_t *tool = object;
+
+    gdk_threads_enter ();
+    if (tool->window)
+    {
+	gtk_widget_destroy (tool->window);
+	tool->window = NULL;
+    }
+    if (tool->pixmap)
+    {
+	gdk_drawable_unref (tool->pixmap);
+	tool->pixmap = NULL;
+    }
+    gdk_threads_leave ();
+    return 1;
+}
+
+static DataType gtk_tool_type = { gtk_tool_mark, gtk_tool_free, "GtkTool" };
+
+Bool
+cairo_5c_tool_create (cairo_5c_surface_t *c5s, int width, int height)
+{
+    ENTER ();
+    gtk_global_t    *gg = gtk_global ? gtk_global : create_gtk_global ();
+    cairo_5c_tool_t *tool;
+    Display	    *dpy;
+    
+    if (aborting)
+    {
+	EXIT ();
+	return False;
+    }
+    tool = ALLOCATE (&gtk_tool_type, sizeof (cairo_5c_tool_t));
+    
+    gdk_threads_enter ();
+    dpy = gg->dpy;
+    
+    tool->global = gg;
+    tool->dirty = 0;
+    tool->disable = 0;
+    tool->pixmap = 0;
+    
+    c5s->dirty = False;
+    c5s->recv_events = Void;
+    c5s->u.window.send_events = 0;
+    c5s->u.window.tool = tool;
+    
+    if (!width)
+	width = XDisplayWidth (dpy, DefaultScreen (dpy)) / 3;
+    if (!height)
+	height = XDisplayWidth (dpy, DefaultScreen (dpy)) / 3;
+    
+    tool->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_default_size (GTK_WINDOW(tool->window),
+				 width, height);
+    
+    tool->drawing_area = gtk_drawing_area_new ();
+    
+    GTK_DRAWING_AREA (tool->drawing_area)->draw_data = c5s;
+    
+    gtk_container_add (GTK_CONTAINER(tool->window), tool->drawing_area);
+    
+    g_signal_connect (GTK_OBJECT (tool->drawing_area), "expose_event",
+		      (GtkSignalFunc) expose_event, NULL);
+    g_signal_connect (GTK_OBJECT(tool->drawing_area),"configure_event",
+		      (GtkSignalFunc) configure_event, NULL);
+    g_signal_connect (GTK_OBJECT (tool->window), "delete_event",
+		      (GtkSignalFunc) delete_event, NULL);
+    g_signal_connect (GTK_OBJECT (tool->drawing_area), "motion_notify_event",
+		      (GtkSignalFunc) motion_notify_event, NULL);
+    g_signal_connect (GTK_OBJECT (tool->drawing_area), "button_press_event",
+		      (GtkSignalFunc) button_press_event, NULL);
+    g_signal_connect (GTK_OBJECT (tool->drawing_area), "button_release_event",
+		      (GtkSignalFunc) button_release_event, NULL);
+
+    gtk_widget_set_events (tool->drawing_area, GDK_EXPOSURE_MASK
+			   | GDK_LEAVE_NOTIFY_MASK
+			   | GDK_BUTTON_PRESS_MASK
+			   | GDK_BUTTON_RELEASE_MASK
+			   | GDK_POINTER_MOTION_MASK);
+
+    gtk_widget_realize (tool->window);
+    gtk_widget_realize (tool->drawing_area);
+    gdk_window_set_back_pixmap (GTK_WIDGET(tool->drawing_area)->window, NULL, FALSE);
+    gtk_widget_show (tool->drawing_area);
+    gtk_widget_show (tool->window);
+    /* create the pixmap */
+    configure_event (tool->drawing_area, 0);
+    
+    /* fill in the c5s window structure */
+     
+    c5s->u.window.pixmap = GDK_PIXMAP_XID (GDK_DRAWABLE(tool->pixmap));
+    gdk_threads_leave ();
+    EXIT ();
+    return True;
+}
+
+Bool
+cairo_5c_tool_destroy (cairo_5c_surface_t *c5s)
+{
+    cairo_5c_tool_t *tool = c5s->u.window.tool;
+
+    gdk_threads_enter ();
+    if (tool->window)
+    {
+	gtk_widget_destroy (tool->window);
+	tool->window = NULL;
+    }
+    if (tool->pixmap)
+    {
+	gdk_drawable_unref (tool->pixmap);
+	tool->pixmap = NULL;
+    }
+    gdk_threads_leave ();
+    return True;
 }
 
 void
-dirty_x (cairo_5c_x_t *c5cx, int x, int y, int w, int h)
+cairo_5c_tool_mark (cairo_5c_surface_t *c5s)
 {
-    cairo_5c_gtk_t  *c5cg = (cairo_5c_gtk_t *) c5cx;
+    MemReference (c5s->u.window.tool);
+}
 
-    if (!c5cg->dirty)
+void
+cairo_5c_tool_dirty (cairo_5c_surface_t *c5s)
+{
+    cairo_5c_tool_t *tool = c5s->u.window.tool;
+    
+    if (!tool->dirty)
     {
-	c5cg->dirty = 1;
-	if (c5cg->disable == 0)
+	tool->dirty = 1;
+	if (tool->disable == 0)
 	{
 	    gdk_threads_enter ();
-	    g_timeout_add (16, gtk_repaint_timeout, c5cg);
+	    g_timeout_add (16, gtk_repaint_timeout, c5s);
 	    gdk_threads_leave ();
 	}
     }
 }
 
 Bool
-disable_x (cairo_5c_x_t *c5cx)
+cairo_5c_tool_disable (cairo_5c_surface_t *c5s)
 {
-    cairo_5c_gtk_t  *c5cg = (cairo_5c_gtk_t *) c5cx;
+    cairo_5c_tool_t *tool = c5s->u.window.tool;
 
-    ++c5cg->disable;
+    ++tool->disable;
     return True;
 }
 
 Bool
-enable_x  (cairo_5c_x_t *c5cx)
+cairo_5c_tool_enable (cairo_5c_surface_t *c5s)
 {
-    cairo_5c_gtk_t  *c5cg = (cairo_5c_gtk_t *) c5cx;
+    cairo_5c_tool_t *tool = c5s->u.window.tool;
 
-    if (!c5cg->disable)
+    if (!tool->disable)
 	return False;
-    --c5cg->disable;
-    if (!c5cg->disable && c5cg->dirty)
+    --tool->disable;
+    if (!tool->disable && tool->dirty)
     {
 	gdk_threads_enter ();
-	g_timeout_add (0, gtk_repaint_timeout, c5cg);
+	g_timeout_add (0, gtk_repaint_timeout, c5s);
 	gdk_threads_leave ();
     }
     return True;
 }
+
+Display *
+cairo_5c_tool_display (cairo_5c_surface_t *c5s)
+{
+    cairo_5c_tool_t *tool = c5s->u.window.tool;
+    
+    return tool->global->dpy;
+}

Index: init.c
===================================================================
RCS file: /cvs/cairo/cairo-5c/init.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- init.c	19 Dec 2004 00:06:26 -0000	1.9
+++ init.c	23 Dec 2004 22:39:40 -0000	1.10
@@ -36,8 +36,10 @@
 #include "cairo-5c.h"
 
 NamespacePtr	CairoNamespace;
+NamespacePtr	CairoSurfaceNamespace;
 NamespacePtr	CairoPatternNamespace;
 Type		*typeCairo;
+Type		*typeCairoSurface;
 Type		*typeCairoStatus;
 Type		*typeCairoOperator;
 Type		*typeCairoFillRule;
@@ -46,6 +48,7 @@
 Type		*typeCairoFontSlant;
 Type		*typeCairoFontWeight;
 Type		*typeCairoTextExtents;
+Type		*typeCairoFontExtents;
 Type		*typeCairoMatrix;
 Type		*typeCairoPoint;
 Type		*typeCairoRect;
@@ -62,42 +65,46 @@
 
 #define CAIRO_I		0
 #define CAIRO_S		"00"
-#define STATUS_I	1
-#define STATUS_S	"01"
-#define OPERATOR_I	2
-#define OPERATOR_S	"02"
-#define FILL_RULE_I	3
-#define FILL_RULE_S	"03"
-#define LINE_CAP_I	4
-#define LINE_CAP_S	"04"
-#define LINE_JOIN_I	5
-#define LINE_JOIN_S	"05"
-#define FONT_SLANT_I	6
-#define FONT_SLANT_S	"06"
-#define FONT_WEIGHT_I	7
-#define FONT_WEIGHT_S	"07"
-#define	TEXT_EXTENTS_I	8
-#define TEXT_EXTENTS_S	"08"
-#define MATRIX_I	9
-#define MATRIX_S	"09"
-#define POINT_I		10
-#define POINT_S		"10"
-#define RECT_I		11
-#define RECT_S		"11"
-#define RGB_COLOR_I	12
-#define RGB_COLOR_S	"12"
-#define PATTERN_I	13
-#define PATTERN_S	"13"
-#define PATH_I		14
-#define PATH_S		"14"
-#define MOVE_TO_I	15
-#define MOVE_TO_S	"15"
-#define LINE_TO_I	16
-#define LINE_TO_S	"16"
-#define CURVE_TO_I	17
-#define CURVE_TO_S	"17"
-#define CLOSE_PATH_I	18
-#define CLOSE_PATH_S	"18"
+#define SURFACE_I	1
+#define SURFACE_S	"01"
+#define STATUS_I	2
+#define STATUS_S	"02"
+#define OPERATOR_I	3
+#define OPERATOR_S	"03"
+#define FILL_RULE_I	4
+#define FILL_RULE_S	"04"
+#define LINE_CAP_I	5
+#define LINE_CAP_S	"05"
+#define LINE_JOIN_I	6
+#define LINE_JOIN_S	"06"
+#define FONT_SLANT_I	7
+#define FONT_SLANT_S	"07"
+#define FONT_WEIGHT_I	8
+#define FONT_WEIGHT_S	"08"
+#define	TEXT_EXTENTS_I	9
+#define TEXT_EXTENTS_S	"09"
+#define	FONT_EXTENTS_I	10
+#define FONT_EXTENTS_S	"10"
+#define MATRIX_I	11
+#define MATRIX_S	"11"
+#define POINT_I		12
+#define POINT_S		"12"
+#define RECT_I		13
+#define RECT_S		"13"
+#define RGB_COLOR_I	14
+#define RGB_COLOR_S	"14"
+#define PATTERN_I	15
+#define PATTERN_S	"15"
+#define PATH_I		16
+#define PATH_S		"16"
+#define MOVE_TO_I	17
+#define MOVE_TO_S	"17"
+#define LINE_TO_I	18
+#define LINE_TO_S	"18"
+#define CURVE_TO_I	19
+#define CURVE_TO_S	"19"
+#define CLOSE_PATH_I	20
+#define CLOSE_PATH_S	"20"
 
 #define EXTEND_I	30
 #define EXTEND_S	"30"
@@ -142,6 +149,13 @@
 			      NULL,
 			      typePrim[rep_foreign]);
 
+    typeCairoSurface = make_typedef ("surface_t",
+				     CairoNamespace,
+				     publish_public,
+				     SURFACE_I,
+				     NULL,
+				     typePrim[rep_foreign]);
+
     typeCairoStatus = make_typedef ("status_t",
 				    CairoNamespace,
 				    publish_public,
@@ -236,6 +250,17 @@
 							  typePrim[rep_float], "height",
 							  typePrim[rep_float], "x_advance",
 							  typePrim[rep_float], "y_advance"));
+    typeCairoFontExtents = make_typedef ("font_extents_t",
+					 CairoNamespace,
+					 publish_public,
+					 FONT_EXTENTS_I,
+					 NULL,
+					 BuildStructType (5, 
+							  typePrim[rep_float], "ascent",
+							  typePrim[rep_float], "descent",
+							  typePrim[rep_float], "height",
+							  typePrim[rep_float], "max_x_advance",
+							  typePrim[rep_float], "max_y_advance"));
     typeCairoMatrix = make_typedef ("matrix_t",
 				    CairoNamespace,
 				    publish_public,
@@ -347,6 +372,11 @@
     cp->symbol.type = BuildStructType (1,
 				       typeCairoPath, "next");
 
+    
+
+    CairoSurfaceNamespace = BuiltinNamespace (&CairoNamespace, "Surface")->namespace.namespace;
+
+
     CairoPatternNamespace = BuiltinNamespace (&CairoNamespace, "Pattern")->namespace.namespace;
 
     typeCairoPatternExtend = make_typedef ("extend_t",
@@ -416,40 +446,33 @@
 nickle_init (void)
 {
     ENTER ();
-    
-    static const struct fbuiltin_v funcs_v[] = {
-	{ do_Cairo_new, "new", CAIRO_S, ".i", "\n"
-	    " cairo_t new (int...)\n"
+	
+    static const struct fbuiltin_0 funcs_0[] = {
+	{ do_Cairo_create, "create", CAIRO_S, "", "\n"
+	    " cairo_t create ()\n"
 	    "\n"
-	    " Create a cairo window. Optional arguments are width, height\n" },
-	{ 0 }
+	    " Create a cairo context.\n"
+	},
+	{ 0 },
     };
-	
+    
     static const struct fbuiltin_1 funcs_1[] = {
-	{ do_Cairo_dup, "dup", CAIRO_S, CAIRO_S, "\n"
-	    " cairo_t dup (cairo_t cairo)\n"
-	    "\n"
-	    " Creates another rendering context pointing at the same surface\n"},
-	{ do_Cairo_width, "width", "i", CAIRO_S, "\n"
-	    " void width (cairo_t cairo)\n"
+	{ do_Cairo_destroy, "destroy", "v", CAIRO_S, "\n"
+	    " void destroy (cairo_t cairo)\n"
 	    "\n"
-	    " Return the width of a cairo surface\n" },
-	{ do_Cairo_height, "height", "i", CAIRO_S, "\n"
-	    " void height (cairo_t cairo)\n"
+	    " destroy a rendering context.\n"},
+	{ do_Cairo_current_target_surface, "current_target_surface", SURFACE_S, CAIRO_S, "\n"
+	    " surface_t current_target_surface (cairo_t cairo)\n"
 	    "\n"
-	    " Return the height of a cairo surface\n" },
+	    " Return current target surface\n" },
 	{ do_Cairo_status, "status", STATUS_S, CAIRO_S, "\n"
-	    " void status (cairo_t cairo)\n"
+	    " status_t status (cairo_t cairo)\n"
 	    "\n"
 	    " Return the status of a cairo surface\n" },
 	{ do_Cairo_status_string, "status_string", "s", CAIRO_S, "\n"
-	    " void status_string (cairo_t cairo)\n"
+	    " string status_string (cairo_t cairo)\n"
 	    "\n"
 	    " Return the status string of a cairo surface\n" },
-	{ do_Cairo_dispose, "dispose", "v", CAIRO_S, "\n"
-	    " void dispose (cairo_t cairo)\n"
-	    "\n"
-	    " Dispose a cairo surface\n" },
 	{ do_Cairo_enable, "enable", "v", CAIRO_S, "\n"
 	    " void enable (cairo_t cairo)\n"
 	    "\n"
@@ -581,14 +604,22 @@
 	    "\n"
 	    " Returns the current transformation matrix\n" },
 	
-	{ do_Cairo_open_event, "open_event", "f", CAIRO_S, "\n"
-	    " file open_event (cairo_t cairo)\n"
+	{ do_Cairo_current_font_extents, "current_font_extents", FONT_EXTENTS_S, CAIRO_S, "\n"
+	    " font_extents_t current_font_extents (cairo_t cairo)\n"
 	    "\n"
-	    " Returns a file which will receive events\n" },
+	    " Returns metrics for current font\n" },
 	{ 0 }
     };
     
     static const struct fbuiltin_2 funcs_2[] = {
+	{ do_Cairo_set_target_surface, "set_target_surface", "v", CAIRO_S SURFACE_S, "\n"
+	    " void set_target_surface (cairo_t cr, surface_t surface)\n"
+	    "\n"
+	    " Set target surface for drawing operations\n" },
+	{ do_Cairo_copy, "copy", "v", CAIRO_S CAIRO_S, "\n"
+	    " void copy (cairo_t dst, cairo_t src)\n"
+	    "\n"
+	    " Copy state from one rendering context to another\n" },
 	{ do_Cairo_set_operator, "set_operator", "v", CAIRO_S OPERATOR_S, "\n"
 	    " void set_operator (cairo_t cr, operator_t operator)\n"
 	    "\n"
@@ -653,7 +684,11 @@
 	    " text_extents_t text_extents (cairo_t cr, string text)\n"
 	    "\n"
 	    " Appends text to current path\n" },
-	{ do_Cairo_set_matrix, "set_matrix", "v", CAIRO_S "A**n", "\n"
+	{ do_Cairo_concat_matrix, "concat_matrix", "v", CAIRO_S MATRIX_S, "\n"
+	    " void concat_matrix (cairo_t cr, matrix_t matrix)\n"
+	    "\n"
+	    " Mixes in another matrix to the current transformation\n" },
+	{ do_Cairo_set_matrix, "set_matrix", "v", CAIRO_S MATRIX_S, "\n"
 	    " void set_matrix (cairo_t cr, matrix_t matrix)\n"
 	    "\n"
 	    " Sets the transformation matrix\n" },
@@ -677,6 +712,7 @@
     };
 
     static const struct fbuiltin_3 funcs_3[] = {
+#if 0
 	{ do_Cairo_new_png, "new_png", CAIRO_S, "sii", "\n"
 	    " cairo_t new_png (string filename, int width, int height)\n"
 	    "\n"
@@ -685,6 +721,7 @@
 	    " cairo_t new_scratch (cairo_t cr, int width, int height)\n"
 	    "\n"
 	    " Create a scratch surface related to the given surface.\n" },
+#endif
 	{ do_Cairo_move_to, "move_to", "v", CAIRO_S "nn", "\n"
 	    " void move_to (cairo_t cr, real x, real y)\n"
 	    "\n"
@@ -768,6 +805,54 @@
 	{ 0 }
     };
 
+    static const struct fbuiltin_1 surfuncs_1[] = {
+	{ do_Cairo_Surface_destroy, "destroy", "v", SURFACE_S, "\n"
+	    " void destroy (surface_t surface)\n"
+	    "\n"
+	    " Destroy a surface.  Further usage will raise an exception.\n" },
+	{ do_Cairo_Surface_width, "width", "i", SURFACE_S, "\n"
+	    " int width (surface_t surface)\n"
+	    "\n"
+	    " Returns the width of the given surface\n" },
+	{ do_Cairo_Surface_height, "height", "i", SURFACE_S, "\n"
+	    " int height (surface_t surface)\n"
+	    "\n"
+	    " Returns the height of the given surface\n" },
+	{ do_Cairo_Surface_open_event, "open_event", "f", SURFACE_S, "\n"
+	    " file open_event (surface_t surface)\n"
+	    "\n"
+	    " Returns a file which will receive events\n" },
+	{ 0 }
+    };
+
+    static const struct fbuiltin_2 surfuncs_2[] = {
+	{ do_Cairo_Surface_create_window, "create_window", SURFACE_S, "nn", "\n"
+	    " surface_t create_window (real width, real height)\n"
+	    "\n"
+	    " Create a window and return a surface pointer for it\n" },
+	{ 0 }
+    };
+
+    static const struct fbuiltin_3 surfuncs_3[] = {
+	{ do_Cairo_Surface_create_png, "create_png", SURFACE_S, "snn", "\n"
+	    " surface_t create_png (string filename, real width, real height)\n"
+	    "\n"
+	    " Create a png file and return a surface pointer for it\n" },
+	{ do_Cairo_Surface_create_similar, "create_similar", SURFACE_S, SURFACE_S "nn", "\n"
+	    " surface_t create_similar (surface_t related, real width, real height)\n"
+	    "\n"
+	    " Create a similar surface related to another surface\n" },
+	{ 0 }
+    };
+
+    static const struct fbuiltin_5 surfuncs_5[] = {
+	{ do_Cairo_Surface_create_ps, "create_ps", SURFACE_S, "snnnn", "\n"
+	    " surface_t create_ps (string filename, real width_inches, real height_inches, real xppi, real yppi)\n"
+	    "\n"
+	    " Create a PostScript file and return a surface pointer for it\n" },
+	{ 0 }
+    };
+
     static const struct fbuiltin_1 patfuncs_1[] = {
 	{ do_Cairo_Pattern_create_png, "create_png", PATTERN_S, "s", "\n"
 	    " pattern_t create_png (string filename)\n"
@@ -830,7 +915,7 @@
 
     init_types ();
     
-    BuiltinFuncsV (&CairoNamespace, funcs_v);
+    BuiltinFuncs0 (&CairoNamespace, funcs_0);
     BuiltinFuncs1 (&CairoNamespace, funcs_1);
     BuiltinFuncs2 (&CairoNamespace, funcs_2);
     BuiltinFuncs3 (&CairoNamespace, funcs_3);
@@ -839,6 +924,11 @@
     BuiltinFuncs6 (&CairoNamespace, funcs_6);
     BuiltinFuncs7 (&CairoNamespace, funcs_7);
 
+    BuiltinFuncs1 (&CairoSurfaceNamespace, surfuncs_1);
+    BuiltinFuncs2 (&CairoSurfaceNamespace, surfuncs_2);
+    BuiltinFuncs3 (&CairoSurfaceNamespace, surfuncs_3);
+    BuiltinFuncs5 (&CairoSurfaceNamespace, surfuncs_5);
+    
     BuiltinFuncs1 (&CairoPatternNamespace, patfuncs_1);
     BuiltinFuncs2 (&CairoPatternNamespace, patfuncs_2);
     BuiltinFuncs4 (&CairoPatternNamespace, patfuncs_4);

Index: pattern.c
===================================================================
RCS file: /cvs/cairo/cairo-5c/pattern.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- pattern.c	18 Dec 2004 08:16:28 -0000	1.2
+++ pattern.c	23 Dec 2004 22:39:40 -0000	1.3
@@ -53,6 +53,12 @@
 }
 
 static void
+mark_cairo_pattern (void *v)
+{
+    ;
+}
+
+static void
 free_cairo_pattern (void *v)
 {
     cairo_pattern_t *pat = v;
@@ -65,13 +71,13 @@
 make_pattern_value (cairo_pattern_t *pat)
 {
     cairo_pattern_reference (pat);
-    return NewForeign (CairoPatternId, pat, free_cairo_pattern);
+    return NewForeign (CairoPatternId, pat, mark_cairo_pattern, free_cairo_pattern);
 }
 
 Value
 do_Cairo_set_pattern (Value cv, Value patv)
 {
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     cairo_pattern_t *pat = get_cairo_pattern (patv);
 
     if (aborting)
@@ -83,7 +89,7 @@
 Value
 do_Cairo_current_pattern (Value cv)
 {
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_t	*c5c = cairo_5c_get (cv);
 
     if (aborting)
 	return Void;
@@ -126,7 +132,7 @@
 do_Cairo_Pattern_create_for_surface (Value cv)
 {
     ENTER ();
-    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_5c_t	    *c5c = cairo_5c_get (cv);
     cairo_surface_t *surface;
 
     if (aborting)

Index: surface.c
===================================================================
RCS file: /cvs/cairo/cairo-5c/surface.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- surface.c	19 Dec 2004 00:06:26 -0000	1.7
+++ surface.c	23 Dec 2004 22:39:40 -0000	1.8
@@ -35,358 +35,307 @@
 
 #include "cairo-5c.h"
 
-static char	CairoId[] = "Cairo";
+static char	CairoSurfaceId[] = "CairoSurface";
 
-cairo_5c_t *
-get_cairo_5c (Value av)
+static Bool
+create_cairo_window (cairo_5c_surface_t *c5s)
 {
-    cairo_5c_t	*c5c;
+    Display	*dpy = cairo_5c_tool_display (c5s);
     
-    if (av->foreign.id != CairoId)
+    if (c5s->surface)
+	cairo_surface_destroy (c5s->surface);
+    c5s->surface = cairo_xlib_surface_create (dpy,
+					      c5s->u.window.pixmap,
+					      DefaultVisual (dpy, DefaultScreen (dpy)),
+					      0,
+					      DefaultColormap (dpy, DefaultScreen (dpy)));
+    c5s->u.window.curpix = c5s->u.window.pixmap;
+    return True;
+}
+
+cairo_5c_surface_t *
+cairo_5c_surface_get (Value av)
+{
+    cairo_5c_surface_t	*c5s;
+
+    if (av == Void)
     {
 	RaiseStandardException (exception_invalid_argument,
-				"not a cairo_t",
+				"context not bound to surface",
+				2, NewInt(0), av);
+    }
+    if (av->foreign.id != CairoSurfaceId)
+    {
+	RaiseStandardException (exception_invalid_argument,
+				"not a surface_t",
 				2, NewInt(0), av);
 	return 0;
     }
-    c5c = av->foreign.data;
-    if (!c5c)
+    c5s = av->foreign.data;
+    if (!c5s)
     {
 	RaiseStandardException (exception_invalid_argument,
-				"cairo destroyed",
+				"surface destroyed",
 				2, NewInt(0), av);
 	return 0;
     }
-    switch (c5c->kind) {
+    switch (c5s->kind) {
     case CAIRO_5C_WINDOW:
-	if (c5c->u.window.pix != c5c->u.window.x->pixmap)
-	{
-	    c5c->u.window.pix = c5c->u.window.x->pixmap;
-	    c5c->width = c5c->u.window.x->width;
-	    c5c->height = c5c->u.window.x->height;
-	    cairo_set_target_drawable (c5c->cr, c5c->u.window.x->dpy, c5c->u.window.pix);
-	}
+	if (c5s->u.window.curpix != c5s->u.window.pixmap)
+	    create_cairo_window (c5s);
 	break;
     case CAIRO_5C_PNG:
+    case CAIRO_5C_PS:
     case CAIRO_5C_SCRATCH:
 	break;
     }
-    return c5c;
+    return c5s;
 }
 
-void
-free_cairo_5c (void *v)
-{
-    cairo_5c_t	*c5c = v;
-
-    if (c5c)
-    {
-	cairo_destroy (c5c->cr);
-	switch (c5c->kind) {
-	case CAIRO_5C_WINDOW:
-	    break;
-	case CAIRO_5C_PNG:
-	    fflush (c5c->u.png.file);
-	    break;
-	case CAIRO_5C_SCRATCH:
-	    cairo_surface_destroy (c5c->u.scratch.surface);
-	    break;
-	}
-        free (c5c);
-    }
-}
+/*
+ * These are the functions for the nickle memory allocator interface
+ * for the CairoSurfaceType datatype
+ */
 
-void
-dirty_cairo_5c (cairo_5c_t *c5c)
+static void
+cairo_5c_surface_mark (void *object)
 {
-    switch (c5c->kind) {
+    cairo_5c_surface_t	*c5s = object;
+    MemReference (c5s->recv_events);
+    switch (c5s->kind) {
     case CAIRO_5C_WINDOW:
-	dirty_x (c5c->u.window.x, 0, 0, 0, 0);
+	cairo_5c_tool_mark (c5s);
 	break;
     case CAIRO_5C_PNG:
+    case CAIRO_5C_PS:
     case CAIRO_5C_SCRATCH:
 	break;
     }
 }
 
-static Bool
-enable_cairo_5c (cairo_5c_t *c5c)
+static int
+cairo_5c_surface_free (void *object)
 {
-    switch (c5c->kind) {
+    cairo_5c_surface_t	*c5s = object;
+
+    cairo_surface_destroy (c5s->surface);
+    switch (c5s->kind) {
     case CAIRO_5C_WINDOW:
-	return enable_x (c5c->u.window.x);
+	cairo_5c_tool_destroy (c5s);
+	break;
     case CAIRO_5C_PNG:
+    case CAIRO_5C_PS:
     case CAIRO_5C_SCRATCH:
 	break;
     }
-    return True;
+    return 1;
 }
 
-static Bool
-disable_cairo_5c (cairo_5c_t *c5c)
+static DataType Cairo5cSurfaceType = { 
+    cairo_5c_surface_mark,
+    cairo_5c_surface_free,
+    "Cairo5cSurface"
+};
+    
+/*
+ * These are the functions for the nickle foreign function interface
+ * for the "CairoSurface" foreign datatype
+ */
+
+static void
+cairo_surface_foreign_mark (void *object)
 {
-    switch (c5c->kind) {
-    case CAIRO_5C_WINDOW:
-	return disable_x (c5c->u.window.x);
-    case CAIRO_5C_PNG:
-    case CAIRO_5C_SCRATCH:
-	break;
-    }
-    return True;
+    MemReference (object);
+}
+
+static void
+cairo_surface_foreign_free (void *object)
+{
+    /* let nickle finalizer deal with this */
+    ;
 }
 
 Value
-do_Cairo_new (int n, Value *v)
+do_Cairo_Surface_create_window (Value wv, Value hv)
 {
     ENTER ();
-    cairo_5c_t	*c5c;
-    Value	ret;
-    int		width, height;
+    cairo_5c_surface_t	*c5s;
+    Value		ret;
+    int			width = IntPart (wv, "invalid width");
+    int			height = IntPart (hv, "invalid height");
     
-    c5c = malloc (sizeof (cairo_5c_t));
-    c5c->kind = CAIRO_5C_WINDOW;
-
-    if (!c5c)
+    if (aborting )
 	RETURN (Void);
-    if (n > 0)
-	width = IntPart (v[0], "invalid width");
-    else
-	width = 0;
-    if (n > 1)
-	height = IntPart (v[1], "invalid height");
-    else
-	height = 0;
 
-    if (aborting)
+    c5s = ALLOCATE (&Cairo5cSurfaceType, sizeof (cairo_5c_surface_t));
+    c5s->kind = CAIRO_5C_WINDOW;
+    c5s->surface = 0;
+    c5s->width = width;
+    c5s->height = height;
+    c5s->dirty = False;
+    c5s->recv_events = Void;
+    
+    if (!cairo_5c_tool_create (c5s, width, height))
     {
-	free (c5c);
+	RaiseStandardException (exception_open_error,
+				"Can't create window",
+				0, wv);
 	RETURN (Void);
     }
     
-    c5c->recv_events = 0;
-    c5c->u.window.x = start_x (width, height);
-    c5c->width = c5c->u.window.x->width;
-    c5c->height = c5c->u.window.x->height;
-    c5c->u.window.pix = c5c->u.window.x->pixmap;
-
-    c5c->cr = cairo_create ();
-    cairo_set_target_drawable (c5c->cr, c5c->u.window.x->dpy, c5c->u.window.pix);
-    
-    cairo_save (c5c->cr); {
-	cairo_identity_matrix (c5c->cr);
-	cairo_set_rgb_color (c5c->cr, 1, 1, 1);
-	cairo_rectangle (c5c->cr, 0, 0, c5c->width, c5c->height);
-	cairo_fill (c5c->cr);
-    } cairo_restore (c5c->cr);
-    
-    cairo_set_rgb_color (c5c->cr, 0, 0, 0);
+    create_cairo_window (c5s);
 
-    ret = NewForeign (CairoId, c5c, free_cairo_5c);
+    ret = NewForeign (CairoSurfaceId, c5s, 
+		      cairo_surface_foreign_mark, cairo_surface_foreign_free);
 
     RETURN (ret);
 }
 
 Value
-do_Cairo_new_png (Value fv, Value wv, Value hv)
+do_Cairo_Surface_create_png (Value fv, Value wv, Value hv)
 {
     ENTER ();
-    cairo_5c_t	*c5c;
-    char	*filename = StrzPart (fv, "invalid filename");
-    int		width = IntPart (wv, "invalid width");
-    int		height = IntPart (hv, "invalid height");
-    Value	ret;
+    cairo_5c_surface_t	*c5s;
+    char		*filename = StrzPart (fv, "invalid filename");
+    int			width = IntPart (wv, "invalid width");
+    int			height = IntPart (hv, "invalid height");
+    Value		ret;
 
     if (aborting)
 	RETURN (Void);
     
-    c5c = malloc (sizeof (cairo_5c_t));
-    if (!c5c)
-	RETURN (Void);
-
-    c5c->kind = CAIRO_5C_PNG;
-
-    c5c->u.png.file = fopen (filename, "w");
-    if (!c5c->u.png.file)
+    c5s = ALLOCATE (&Cairo5cSurfaceType, sizeof (cairo_5c_surface_t));
+    c5s->kind = CAIRO_5C_PNG;
+    c5s->surface = 0;
+    c5s->width = width;
+    c5s->height = height;
+    c5s->dirty = False;
+    c5s->recv_events = Void;
+    
+    c5s->u.png.file = fopen (filename, "w");
+    
+    if (!c5s->u.png.file)
     {
 	RaiseStandardException (exception_open_error,
 				"can't open file",
 				0, fv);
-	free (c5c);
 	RETURN (Void);
     }
-    c5c->width = width;
-    c5c->height = height;
-    c5c->cr = cairo_create ();
-    cairo_set_target_png (c5c->cr, c5c->u.png.file,
-			  CAIRO_FORMAT_ARGB32, c5c->width,
-			  c5c->height);
 
-    cairo_save (c5c->cr); {
-	cairo_set_rgb_color (c5c->cr, 0, 0, 0);
-	cairo_set_alpha (c5c->cr, 0);
-	cairo_set_operator (c5c->cr, CAIRO_OPERATOR_SRC);
-	cairo_rectangle (c5c->cr, 0, 0, c5c->width, c5c->height);
-	cairo_fill (c5c->cr);
-    } cairo_restore (c5c->cr);
-
-    cairo_set_rgb_color (c5c->cr, 0, 0, 0);
-
-    ret = NewForeign (CairoId, c5c, free_cairo_5c);
+    c5s->surface = cairo_png_surface_create (c5s->u.png.file,
+					     CAIRO_FORMAT_ARGB32,
+					     width,
+					     height);
+    
+    ret = NewForeign (CairoSurfaceId, c5s, 
+		      cairo_surface_foreign_mark, cairo_surface_foreign_free);
 
     RETURN (ret);
 }
 
 Value
-do_Cairo_new_scratch (Value cov, Value wv, Value hv)
+do_Cairo_Surface_create_ps (Value fv, Value wv, Value hv, Value xppiv, Value yppiv)
 {
     ENTER ();
-    cairo_5c_t	*c5co = get_cairo_5c (cov);
-    cairo_5c_t	*c5c;
-    int		width = IntPart (wv, "invalid width");
-    int		height = IntPart (hv, "invalid height");
-    Value	ret;
-    
+    cairo_5c_surface_t	*c5s;
+    char		*filename = StrzPart (fv, "invalid filename");
+    double		width = DoublePart (wv, "invalid width");
+    double    		height = DoublePart (hv, "invalid height");
+    double		xppi = DoublePart (xppiv, "invalid x pixels per inch");
+    double		yppi = DoublePart (yppiv, "invalid y pixels per inch");
+    Value		ret;
+
     if (aborting)
 	RETURN (Void);
     
-    c5c = malloc (sizeof (cairo_5c_t));
-    if (!c5c)
+    c5s = ALLOCATE (&Cairo5cSurfaceType, sizeof (cairo_5c_surface_t));
+    c5s->kind = CAIRO_5C_PS;
+    c5s->surface = 0;
+    c5s->width = width * xppi;
+    c5s->height = height * yppi;
+    c5s->dirty = False;
+    c5s->recv_events = Void;
+    
+    c5s->u.ps.file = fopen (filename, "w");
+    
+    if (!c5s->u.ps.file)
+    {
+	RaiseStandardException (exception_open_error,
+				"can't open file",
+				0, fv);
 	RETURN (Void);
+    }
 
-    c5c->kind = CAIRO_5C_SCRATCH;
-
-    c5c->u.scratch.surface = cairo_surface_create_similar (cairo_current_target_surface (c5co->cr),
-							   CAIRO_FORMAT_ARGB32,
-							   width, height);
-    c5c->width = width;
-    c5c->height = height;
-    c5c->cr = cairo_create ();
-    cairo_set_target_surface (c5c->cr, c5c->u.scratch.surface);
-
-    cairo_save (c5c->cr); {
-	cairo_set_rgb_color (c5c->cr, 0, 0, 0);
-	cairo_set_alpha (c5c->cr, 0);
-	cairo_set_operator (c5c->cr, CAIRO_OPERATOR_SRC);
-	cairo_rectangle (c5c->cr, 0, 0, c5c->width, c5c->height);
-	cairo_fill (c5c->cr);
-    } cairo_restore (c5c->cr);
-
-    cairo_set_rgb_color (c5c->cr, 0, 0, 0);
-
-    ret = NewForeign (CairoId, c5c, free_cairo_5c);
+    c5s->surface = cairo_ps_surface_create (c5s->u.ps.file, width, height, xppi, yppi);
+    
+    ret = NewForeign (CairoSurfaceId, c5s, 
+		      cairo_surface_foreign_mark, cairo_surface_foreign_free);
 
     RETURN (ret);
 }
 
 Value
-do_Cairo_dup (Value cov)
+do_Cairo_Surface_create_similar (Value sv, Value wv, Value hv)
 {
     ENTER ();
-    cairo_5c_t	*c5co = get_cairo_5c (cov);
-    cairo_5c_t	*c5c;
-    Value	ret;
-    
+    cairo_5c_surface_t	*c5s;
+    cairo_5c_surface_t	*c5os = cairo_5c_surface_get (sv);
+    int			width = IntPart (wv, "invalid width");
+    int			height = IntPart (hv, "invalid height");
+    Value		ret;
+
     if (aborting)
 	RETURN (Void);
     
-    c5c = malloc (sizeof (cairo_5c_t));
-    if (!c5c)
-	RETURN (Void);
-
-    *c5c = *c5co;
-    c5c->cr = cairo_create ();
-    cairo_set_target_surface (c5c->cr, cairo_current_target_surface (c5co->cr));
-    cairo_copy (c5c->cr, c5co->cr);
-    ret = NewForeign (CairoId, c5c, free_cairo_5c);
+    c5s = ALLOCATE (&Cairo5cSurfaceType, sizeof (cairo_5c_surface_t));
+    c5s->kind = CAIRO_5C_SCRATCH;
+    c5s->surface = 0;
+    c5s->width = width;
+    c5s->height = height;
+    c5s->dirty = False;
+    c5s->recv_events = Void;
+    
+    c5s->surface = cairo_surface_create_similar (c5os->surface,
+						 CAIRO_FORMAT_ARGB32,
+						 width, height);
+						 
+    ret = NewForeign (CairoSurfaceId, c5s, 
+		      cairo_surface_foreign_mark, cairo_surface_foreign_free);
 
     RETURN (ret);
 }
 
 Value
-do_Cairo_width (Value av)
-{
-    ENTER ();
-    cairo_5c_t	*c5c = get_cairo_5c (av);
-    if (aborting)
-	return Void;
-    RETURN(NewInt (c5c->width));
-}
-
-Value
-do_Cairo_height (Value av)
-{
-    ENTER ();
-    cairo_5c_t	*c5c = get_cairo_5c (av);
-
-    if (aborting)
-	return Void;
-    RETURN(NewInt (c5c->height));
-}
-
-Value
-do_Cairo_status (Value cv)
+do_Cairo_Surface_destroy (Value sv)
 {
     ENTER ();
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_surface_t	*c5s = cairo_5c_surface_get (sv);
 
     if (aborting)
-	return Void;
-    RETURN(IntToEnum (typeCairoStatus, cairo_status (c5c->cr)));
+	RETURN (Void);
+    cairo_surface_destroy (c5s->surface);
+    c5s->surface = 0;
+    RETURN(Void);
 }
 
 Value
-do_Cairo_status_string (Value cv)
+do_Cairo_Surface_width (Value sv)
 {
     ENTER ();
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
+    cairo_5c_surface_t	*c5s = cairo_5c_surface_get (sv);
 
     if (aborting)
-	return Void;
-    RETURN(NewStrString (cairo_status_string (c5c->cr)));
+	RETURN (Void);
+    RETURN(NewInt (c5s->width));
 }
 
 Value
-do_Cairo_dispose (Value av)
+do_Cairo_Surface_height (Value sv)
 {
     ENTER ();
-    cairo_5c_t	*c5c = get_cairo_5c (av);
-
-    if (c5c)
-    {
-	free_cairo_5c (c5c);
-	av->foreign.data = 0;
-    }
-    RETURN (Void);
-}
-
-Value
-do_Cairo_enable (Value cv)
-{
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
-    
-    if (aborting)
-	return Void;
-    if (!enable_cairo_5c (c5c))
-    {
-	RaiseStandardException (exception_invalid_argument,
-				"already enabled",
-				2, NewInt(0), cv);
-    }
-    return Void;
-}
+    cairo_5c_surface_t	*c5s = cairo_5c_surface_get (sv);
 
-Value
-do_Cairo_disable (Value cv)
-{
-    cairo_5c_t	*c5c = get_cairo_5c (cv);
-    
     if (aborting)
-	return Void;
-    if (!disable_cairo_5c (c5c))
-    {
-	RaiseStandardException (exception_invalid_argument,
-				"can't disable",
-				2, NewInt(0), cv);
-    }
-    return Void;
+	RETURN (Void);
+    RETURN(NewInt (c5s->height));
 }

Index: text.c
===================================================================
RCS file: /cvs/cairo/cairo-5c/text.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- text.c	19 Dec 2004 00:06:26 -0000	1.4
+++ text.c	23 Dec 2004 22:39:40 -0000	1.5
@@ -38,7 +38,7 @@
 Value
 do_Cairo_select_font (Value cv, Value fv, Value sv, Value wv)
 {
-    cairo_5c_t		*c5c = get_cairo_5c (cv);
+    cairo_5c_t		*c5c = cairo_5c_get (cv);
     char		*family = StrzPart (fv, "invalid family");
     cairo_font_slant_t	slant = EnumIntPart (sv, "invalid slant");
     cairo_font_weight_t	weight = EnumIntPart (wv, "invalid weight");
@@ -52,7 +52,7 @@
 do_Cairo_set_font (Value cv, Value fv)
 {
     ENTER ();
-    cairo_5c_t		*c5c = get_cairo_5c (cv);
+    cairo_5c_t		*c5c = cairo_5c_get (cv);
     char		*name = StrzPart (fv, "invalid name");
     FcPattern		*pat;
     static FT_Library	ft_library;
@@ -90,7 +90,7 @@
 Value
 do_Cairo_scale_font (Value cv, Value sv)
 {
-    cairo_5c_t		*c5c = get_cairo_5c (cv);
+    cairo_5c_t		*c5c = cairo_5c_get (cv);
     double		scale = DoublePart (sv, "invalid scale");
     
     if (!aborting)
@@ -102,7 +102,7 @@
 do_Cairo_transform_font (Value cv, Value mv)
 {
     ENTER ();
-    cairo_5c_t		*c5c = get_cairo_5c (cv);
+    cairo_5c_t		*c5c = cairo_5c_get (cv);
     cairo_matrix_t	*matrix;
     
     if (aborting)
@@ -116,15 +116,37 @@
 }
 
 Value
+do_Cairo_current_font_extents (Value cv)
+{
+    ENTER ();
+    cairo_5c_t		    *c5c = cairo_5c_get (cv);
+    cairo_font_extents_t    extents;
+    Value		    ret;
+    BoxPtr		    box;
+
+    if (aborting)
+	return Void;
+    cairo_current_font_extents (c5c->cr, &extents);
+    ret = NewStruct (TypeCanon (typeCairoFontExtents)->structs.structs, False);
+    box = ret->structs.values;
+    BoxValueSet (box, 0, NewDoubleFloat (extents.ascent));
+    BoxValueSet (box, 1, NewDoubleFloat (extents.descent));
+    BoxValueSet (box, 2, NewDoubleFloat (extents.height));
+    BoxValueSet (box, 3, NewDoubleFloat (extents.max_x_advance));
+    BoxValueSet (box, 4, NewDoubleFloat (extents.max_y_advance));
+    RETURN (ret);
+}
+
+Value
 do_Cairo_show_text (Value cv, Value uv)
 {
-    cairo_5c_t		*c5c = get_cairo_5c (cv);
+    cairo_5c_t		*c5c = cairo_5c_get (cv);
     char		*utf8 = StrzPart (uv, "invalid text");
 
     if (!aborting)
     {
 	cairo_show_text (c5c->cr, utf8);
-	dirty_cairo_5c (c5c);
+	cairo_5c_dirty (c5c);
     }
     return Void;
 }
@@ -132,7 +154,7 @@
 Value
 do_Cairo_text_path (Value cv, Value uv)
 {
-    cairo_5c_t		*c5c = get_cairo_5c (cv);
+    cairo_5c_t		*c5c = cairo_5c_get (cv);
     char		*utf8 = StrzPart (uv, "invalid text");
 
     if (!aborting)
@@ -144,7 +166,7 @@
 do_Cairo_text_extents (Value cv, Value uv)
 {
     ENTER ();
-    cairo_5c_t		    *c5c = get_cairo_5c (cv);
+    cairo_5c_t		    *c5c = cairo_5c_get (cv);
     char		    *utf8 = StrzPart (uv, "invalid text");
     cairo_text_extents_t    extents;
     Value		    ret;
@@ -163,10 +185,3 @@
     BoxValueSet (box, 5, NewDoubleFloat (extents.y_advance));
     RETURN (ret);
 }
-
-Value
-do_Cairo_select_ft_font (Value pv)
-{
-    /* XXX */
-    return Void;
-}




More information about the cairo-commit mailing list