[cairo] [patch] BeOS backend

Christian Biesinger cbiesinger at web.de
Mon Oct 10 15:46:50 PDT 2005


Christian Biesinger wrote:
> There are two parts here; the cplusplus.diff one allows including 
> cairoint.h in a C++ source file, while beos-backend.diff contains the 
> actual backend.

Sorry, please use this beos-backend-v2.diff instead; it removes the 
cairo-private.h include which fixes compilation (the C++ compiler I have 
doesn't seem to like the attribute((packed)) in cairo-path-fixed-private.h)

-biesi
-------------- next part --------------
Index: INSTALL
===================================================================
RCS file: /cvs/cairo/cairo/INSTALL,v
retrieving revision 1.4
diff -p -u -6 -r1.4 INSTALL
--- INSTALL	31 Aug 2005 20:52:19 -0000	1.4
+++ INSTALL	10 Oct 2005 22:39:59 -0000
@@ -63,12 +63,13 @@ More detailed build instructions
     --enable-ps
     --enable-pdf
     --enable-quartz
     --enable-atsui
     --enable-xcb
     --enable-glitz
+    --enable-beos
 
 	Some of cairo's backends are marked as experimental and will
 	not be built by default. If you would like to build and
 	experiment with these backends, you will need to pass one of
 	the above options to the configure script. You may need to
 	have certain libraries installed first as discussed in the
Index: README
===================================================================
RCS file: /cvs/cairo/cairo/README,v
retrieving revision 1.21
diff -p -u -6 -r1.21 README
--- README	24 Aug 2005 16:12:37 -0000	1.21
+++ README	10 Oct 2005 22:40:00 -0000
@@ -95,12 +95,17 @@ Surface backends:
 	XCB			http://xcb.freedesktop.org
 
 	xlib backend
 	------------
 	Xrender >= 0.6		http://freedesktop.org/Software/xlibs
 
+	beos backend
+	------------
+	No dependencies in itself other than an installed BeOS system, but cairo
+	requires a font backend. See the freetype dependency list.
+
 Font backends:
 
 	freetype font backend
 	---------------------
 	freetype >= 2.1.4	http://freetype.org
 	fontconfig		http://fontconfig.org
Index: configure.in
===================================================================
RCS file: /cvs/cairo/cairo/configure.in,v
retrieving revision 1.148
diff -p -u -6 -r1.148 configure.in
--- configure.in	8 Oct 2005 18:57:45 -0000	1.148
+++ configure.in	10 Oct 2005 22:40:00 -0000
@@ -187,12 +187,52 @@ AC_SUBST(WIN32_SURFACE_FEATURE)
 AM_CONDITIONAL(CAIRO_HAS_WIN32_FONT, test "x$use_win32" = "xyes")
 if test "x$use_win32" = "xyes"; then
   WIN32_FONT_FEATURE="#define CAIRO_HAS_WIN32_FONT 1"
 fi
 AC_SUBST(WIN32_FONT_FEATURE)
 
+
+dnl ===========================================================================
+
+
+AC_MSG_CHECKING([for BeOS/Zeta])
+case "$host" in
+  *-*-beos)
+    cairo_platform_beos=yes
+    ;;
+  *)
+    cairo_platform_beos=no
+    ;;
+esac
+AC_MSG_RESULT([$cairo_platform_beos])
+
+AC_ARG_ENABLE(beos,
+  [  --enable-beos            Disable cairo's BeOS/Zeta backend],
+  [use_beos=$enableval], [use_beos=no])
+
+if test "x$cairo_platform_beos" != "xyes" ; then
+  if test "x$use_beos" = "xyes"; then
+    AC_MSG_WARN([The BeOS backend requires a BeOS platform; disabling])
+    use_beos=no
+  fi
+fi
+
+if test "x$use_beos" = "xyes"; then
+  AC_PROG_CXX
+  dnl Add libbe and libzeta if available
+  AC_CHECK_LIB(be,main,CAIRO_LIBS="$CAIRO_LIBS -lbe")
+  AC_CHECK_LIB(zeta,main,CAIRO_LIBS="$CAIRO_LIBS -lzeta")
+fi
+
+AM_CONDITIONAL(CAIRO_HAS_BEOS_SURFACE, test "x$use_beos" = "xyes")
+if test "x$use_beos" = "xyes"; then
+  BEOS_SURFACE_FEATURE="#define CAIRO_HAS_BEOS_SURFACE 1"
+fi
+AC_SUBST(BEOS_SURFACE_FEATURE)
+
+
 dnl ===========================================================================
 
 AC_ARG_ENABLE(png,
   [  --disable-png           Disable cairo's PNG functions],
   [use_png=$enableval], [use_png=yes])
 
@@ -530,12 +570,13 @@ echo "  Xlib: $use_xlib"
 echo "  Quartz: $use_quartz"
 echo "  XCB: $use_xcb"
 echo "  Win32: $use_win32"
 echo "  PostScript: $use_ps"
 echo "  PDF: $use_pdf"
 echo "  glitz: $use_glitz"
+echo "  BeOS: $use_beos"
 echo ""
 echo "the following font backends:"
 echo "  FreeType: $use_freetype"
 echo "  Win32: $use_win32"
 echo "  ATSUI: $use_atsui"
 echo ""
Index: src/Makefile.am
===================================================================
RCS file: /cvs/cairo/cairo/src/Makefile.am,v
retrieving revision 1.66
diff -p -u -6 -r1.66 Makefile.am
--- src/Makefile.am	19 Sep 2005 21:14:03 -0000	1.66
+++ src/Makefile.am	10 Oct 2005 22:40:00 -0000
@@ -38,12 +38,18 @@ export_symbols = -export-symbols cairo.d
 cairo_def_dependency = cairo.def
 endif
 if CAIRO_HAS_WIN32_FONT
 libcairo_win32_sources += cairo-win32-font.c
 endif
 
+libcairo_beos_sources =
+if CAIRO_HAS_BEOS_SURFACE
+libcairo_beos_headers = cairo-beos.h
+libcairo_beos_sources += cairo-beos-surface.cpp
+endif
+
 if CAIRO_HAS_GLITZ_SURFACE
 libcairo_glitz_headers = cairo-glitz.h
 libcairo_glitz_sources = cairo-glitz-surface.c
 endif
 
 if CAIRO_HAS_ATSUI_FONT
@@ -80,12 +86,13 @@ cairoinclude_HEADERS =			\
 	$(libcairo_ft_headers)		\
 	$(libcairo_glitz_headers)	\
 	$(libcairo_pdf_headers)		\
 	$(libcairo_ps_headers)		\
 	$(libcairo_quartz_headers)	\
 	$(libcairo_win32_headers)	\
+	$(libcairo_beos_headers)	\
 	$(libcairo_xcb_headers)		\
 	$(libcairo_xlib_headers)
 
 lib_LTLIBRARIES = libcairo.la
 
 libcairo_la_SOURCES =				\
@@ -142,15 +149,19 @@ libcairo_la_SOURCES =				\
 	$(libcairo_png_sources)			\
 	$(libcairo_xlib_sources)		\
 	$(libcairo_quartz_sources)		\
 	$(libcairo_xcb_sources)			\
 	$(libcairo_glitz_sources)		\
 	$(libcairo_win32_sources)		\
+	$(libcairo_beos_sources)		\
 	cairoint.h
 
 libcairo_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined $(export_symbols)
+# this -Wno-multichar line is really just for the beos surface, because the
+# system headers trigger this warning.
+libcairo_la_CXXFLAGS = -Wno-multichar
 
 INCLUDES = -I$(srcdir) -I$(top_srcdir)/pixman/src $(CAIRO_CFLAGS)
 
 libcairo_la_LIBADD = $(top_builddir)/pixman/src/libpixman.la $(CAIRO_LIBS)
 
 libcairo_la_DEPENDENCIES = $(cairo_def_dependency) $(top_builddir)/pixman/src/libpixman.la
Index: src/cairo-beos-surface.cpp
===================================================================
RCS file: src/cairo-beos-surface.cpp
diff -N src/cairo-beos-surface.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/cairo-beos-surface.cpp	10 Oct 2005 22:40:00 -0000
@@ -0,0 +1,686 @@
+/* vim:set ts=8 sw=4 noet cin: */
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2005 Christian Biesinger <cbiesinger at web.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Christian Biesinger
+ * <cbiesinger at web.de>
+ *
+ * Contributor(s):
+ */
+
+// This is a C++ file in order to use the C++ BeOS API
+
+#include <new>
+
+#include <Bitmap.h>
+#include <Region.h>
+#if 0
+#include <DirectWindow.h>
+#endif
+#include <Screen.h>
+#include <Window.h>
+#include <Locker.h>
+
+#include "cairoint.h"
+#include "cairo-beos.h"
+
+#define CAIRO_INT_STATUS_SUCCESS (cairo_int_status_t)(CAIRO_STATUS_SUCCESS)
+
+typedef struct cairo_beos_surface {
+    cairo_surface_t base;
+
+    BView* view;
+
+    /**
+     * A view is either attached to a bitmap, a window, or unattached.
+     * If it is attached to a window, we can copy data out of it using BScreen.
+     * If it is attached to a bitmap, we can read the bitmap data.
+     * If it is not attached, it doesn't draw anything, we need not bother.
+     *
+     * Since there doesn't seem to be a way to get the bitmap from a view if it
+     * is attached to one, we have to use a special surface creation function.
+     */
+
+    BBitmap* bitmap;
+
+
+} cairo_beos_surface_t;
+
+static BRect
+_cairo_rect_to_brect(const cairo_rectangle_t* rect)
+{
+    // A BRect is one pixel wider than you'd think
+    return BRect(rect->x, rect->y, rect->x + rect->width - 1,
+	    	 rect->y + rect->height - 1);
+}
+
+static cairo_rectangle_t
+_brect_to_cairo_rect(const BRect& rect)
+{
+    cairo_rectangle_t retval;
+    retval.x = int(rect.left + 0.5);
+    retval.y = int(rect.top + 0.5);
+    retval.width = rect.IntegerWidth() + 1;
+    retval.height = rect.IntegerHeight() + 1;
+    return retval;
+}
+
+static rgb_color
+_cairo_color_to_be_color(const cairo_color_t* color)
+{
+    // This factor ensures a uniform distribution of numbers
+    const float factor = 256 - 1e-5;
+    // Using doubles to have non-premultiplied colors
+    rgb_color be_color = { uint8(color->red * factor),
+			   uint8(color->green * factor),
+			   uint8(color->blue * factor),
+			   uint8(color->alpha * factor) };
+
+    return be_color;
+}
+
+enum ViewCopyStatus {
+    OK,
+    NOT_VISIBLE, // The view or the interest rect is not visible on screen
+    ERROR        // The view was visible, but the rect could not be copied. Probably OOM
+};
+
+/**
+ * Gets the contents of the view as a BBitmap*. Caller must delete the bitmap.
+ * @param bitmap[out] The resulting bitmap.
+ * @param[out] rect The rectangle that was copied, in the view's coordinate system
+ * @param interestRect If non-null, only this part of the view will be copied (view's coord system).
+ **/
+static ViewCopyStatus
+_cairo_beos_view_to_bitmap(BView* view, BBitmap** bitmap, BRect* rect = NULL, const BRect* interestRect = NULL)
+{
+    *bitmap = NULL;
+
+    BWindow* wnd = view->Window();
+    // If we have no window, can't do anything
+    if (!wnd)
+	return NOT_VISIBLE;
+
+    view->Sync();
+    wnd->Sync();
+
+#if 0
+    // Is it a direct window?
+    BDirectWindow* directWnd = dynamic_cast<BDirectWindow*>(wnd);
+    if (directWnd) {
+	// WRITEME
+    }
+#endif
+
+    // Is it visible? If so, we can copy the content off the screen
+    if (wnd->IsHidden())
+	return NOT_VISIBLE;
+
+    BRect rectToCopy(view->Bounds());
+    if (interestRect)
+	rectToCopy = rectToCopy & *interestRect;
+
+    if (!rectToCopy.IsValid())
+	return NOT_VISIBLE;
+
+    BScreen screen(wnd);
+    BRect screenRect(view->ConvertToScreen(rectToCopy));
+    screenRect = screenRect & screen.Frame();
+
+    if (!screen.IsValid())
+	return NOT_VISIBLE;
+
+    if (rect)
+	*rect = view->ConvertFromScreen(screenRect);
+
+    if (screen.GetBitmap(bitmap, false, &screenRect) == B_OK)
+	return OK;
+
+    return ERROR;
+}
+
+inline unsigned char
+unpremultiply(unsigned char color, unsigned char alpha)
+{
+    if (alpha == 0)
+	return 0;
+    // plus alpha/2 to round instead of truncate
+    return (color * 255 + alpha / 2) / alpha;
+}
+
+inline unsigned char
+premultiply(unsigned char color, unsigned char alpha)
+{
+    // + 127 to round, instead of truncate
+    return (color * alpha + 127) / 255;
+}
+
+/**
+ * Takes an input in ABGR premultiplied image data and unmultiplies it.
+ * The result is stored in retdata.
+ */
+static void
+unpremultiply_rgba(unsigned char* data, int width, int height, int stride,
+		   unsigned char* retdata)
+{
+    unsigned char* end = data + stride * height;
+    for (unsigned char* in = data, *out = retdata;
+	 in < end;
+	 in += stride, out += stride)
+    {
+	for (int i = 0; i < width; ++i) {
+	    // XXX for a big-endian platform this'd have to change
+	    int idx = 4 * i;
+	    unsigned char alpha = in[idx + 3];
+	    out[idx + 0] = unpremultiply(in[idx + 0], alpha); // B
+	    out[idx + 1] = unpremultiply(in[idx + 1], alpha); // G
+	    out[idx + 2] = unpremultiply(in[idx + 2], alpha); // R
+	    out[idx + 3] = in[idx + 3]; // Alpha
+	}
+    }
+}
+
+/**
+ * Takes an input in ABGR non-premultiplied image data and premultiplies it.
+ * The returned data must be freed with free().
+ */
+static unsigned char*
+premultiply_rgba(unsigned char* data, int width, int height, int stride)
+{
+    unsigned char* retdata = reinterpret_cast<unsigned char*>(malloc(stride * height));
+    if (!retdata)
+	return NULL;
+
+    unsigned char* end = data + stride * height;
+    for (unsigned char* in = data, *out = retdata;
+	 in < end;
+	 in += stride, out += stride)
+    {
+	for (int i = 0; i < width; ++i) {
+	    // XXX for a big-endian platform this'd have to change
+	    int idx = 4 * i;
+	    unsigned char alpha = in[idx + 3];
+	    out[idx + 0] = premultiply(in[idx + 0], alpha); // B
+	    out[idx + 1] = premultiply(in[idx + 1], alpha); // G
+	    out[idx + 2] = premultiply(in[idx + 2], alpha); // R
+	    out[idx + 3] = in[idx + 3]; // Alpha
+	}
+    }
+    return retdata;
+}
+
+/**
+ * Returns an addrefed image surface for a BBitmap. The bitmap need not outlive
+ * the surface.
+ */
+static cairo_image_surface_t*
+_cairo_beos_bitmap_to_surface(BBitmap* bitmap)
+{
+    color_space format = bitmap->ColorSpace();
+    if (format != B_RGB32 && format != B_RGBA32) {
+	BBitmap bmp(bitmap->Bounds(), B_RGB32, true);
+	BView view(bitmap->Bounds(), "Cairo bitmap drawing view",
+		   B_FOLLOW_ALL_SIDES, 0);
+	bmp.AddChild(&view);
+
+	view.LockLooper();
+
+	view.DrawBitmap(bitmap, BPoint(0.0, 0.0));
+	view.Sync();
+
+	cairo_image_surface_t* imgsurf = _cairo_beos_bitmap_to_surface(&bmp);
+
+	view.UnlockLooper();
+	bmp.RemoveChild(&view);
+	return imgsurf;
+    }
+
+    cairo_format_t cformat = format == B_RGB32 ? CAIRO_FORMAT_RGB24
+						: CAIRO_FORMAT_ARGB32;
+
+    BRect bounds(bitmap->Bounds());
+    unsigned char* bits = reinterpret_cast<unsigned char*>(bitmap->Bits());
+    int width = bounds.IntegerWidth() + 1;
+    int height = bounds.IntegerHeight() + 1;
+    unsigned char* premultiplied;
+    if (cformat == CAIRO_FORMAT_ARGB32) {
+       premultiplied = premultiply_rgba(bits, width, height,
+					bitmap->BytesPerRow());
+    } else {
+	premultiplied = reinterpret_cast<unsigned char*>(
+					malloc(bitmap->BytesPerRow() * height));
+	if (premultiplied)
+	    memcpy(premultiplied, bits, bitmap->BytesPerRow() * height);
+    }
+    if (!premultiplied)
+	return NULL;
+
+    cairo_image_surface_t* surf = reinterpret_cast<cairo_image_surface_t*>
+	(cairo_image_surface_create_for_data(premultiplied,
+					     cformat,
+					     width,
+					     height,
+					     bitmap->BytesPerRow()));
+    if (surf->base.status)
+	free(premultiplied);
+    else
+	_cairo_image_surface_assume_ownership_of_data(surf);
+    return surf;
+}
+
+/**
+ * Converts an image surface to a BBitmap. The return value must be freed with
+ * delete.
+ */
+static BBitmap*
+_cairo_image_surface_to_bitmap(cairo_image_surface_t* surface)
+{
+    BRect size(0.0, 0.0, surface->width - 1, surface->height - 1);
+    switch (surface->format) {
+	case CAIRO_FORMAT_ARGB32: {
+	    BBitmap* data = new BBitmap(size, B_RGBA32);
+	    unpremultiply_rgba(surface->data,
+			       surface->width,
+			       surface->height,
+			       surface->stride,
+			       reinterpret_cast<unsigned char*>(data->Bits()));
+	    return data;
+        }
+	case CAIRO_FORMAT_RGB24: {
+	    BBitmap* data = new BBitmap(size, B_RGB32);
+	    memcpy(data->Bits(), surface->data, surface->height * surface->stride);
+	    return data;
+	}
+	default:
+	    return NULL;
+    }
+}
+
+/**
+ * Converts a cairo drawing operator to a beos drawing_mode. Returns true if
+ * the operator could be converted, false otherwise.
+ */
+static bool
+_cairo_op_to_be_op(cairo_operator_t cairo_op, drawing_mode* beos_op)
+{
+    switch (cairo_op) {
+
+	case CAIRO_OPERATOR_SOURCE:
+	    *beos_op = B_OP_COPY;
+	    return true;
+	case CAIRO_OPERATOR_OVER:
+	    *beos_op = B_OP_ALPHA;
+	    return true;
+
+	case CAIRO_OPERATOR_ADD:
+	    *beos_op = B_OP_ADD;
+	    return true;
+
+	case CAIRO_OPERATOR_CLEAR:
+	    // Does not map to B_OP_ERASE - it replaces the dest with the low
+	    // color, instead of transparency; could be done by setting low
+	    // color appropriately.
+	case CAIRO_OPERATOR_IN:
+	case CAIRO_OPERATOR_OUT:
+	case CAIRO_OPERATOR_ATOP:
+
+	case CAIRO_OPERATOR_DEST:
+	case CAIRO_OPERATOR_DEST_OVER:
+	case CAIRO_OPERATOR_DEST_IN:
+	case CAIRO_OPERATOR_DEST_OUT:
+	case CAIRO_OPERATOR_DEST_ATOP:
+
+	case CAIRO_OPERATOR_XOR:
+	case CAIRO_OPERATOR_SATURATE:
+
+	default:
+	    return false;
+    };
+}
+
+static cairo_status_t
+_cairo_beos_surface_finish(void *abstract_surface)
+{
+    // Nothing to do
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_status_t
+_cairo_beos_surface_acquire_source_image(void *abstract_surface,
+					 cairo_image_surface_t **image_out,
+					 void **image_extra)
+{
+    fprintf(stderr, "Getting source image\n");
+    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
+							abstract_surface);
+    surface->view->Sync();
+
+    if (surface->bitmap) {
+	*image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
+	if (!*image_out) {
+	    _cairo_error(CAIRO_STATUS_NO_MEMORY);
+	    return CAIRO_STATUS_NO_MEMORY;
+	}
+
+	*image_extra = NULL;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    BBitmap* bmp;
+    if (_cairo_beos_view_to_bitmap(surface->view, &bmp) != OK) {
+	_cairo_error(CAIRO_STATUS_NO_MEMORY);
+	return CAIRO_STATUS_NO_MEMORY; /// XXX incorrect if the error was NOT_VISIBLE
+    }
+
+    *image_out = _cairo_beos_bitmap_to_surface(bmp);
+    if (!*image_out) {
+	delete bmp;
+	_cairo_error(CAIRO_STATUS_NO_MEMORY);
+	return CAIRO_STATUS_NO_MEMORY;
+    }
+    *image_extra = bmp;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static void
+_cairo_beos_surface_release_source_image(void *abstract_surface,
+					 cairo_image_surface_t *image,
+					 void *image_extra)
+{
+    cairo_surface_destroy (&image->base);
+
+    BBitmap* bmp = static_cast<BBitmap*>(image_extra);
+    delete bmp;
+}
+
+
+
+static cairo_status_t
+_cairo_beos_surface_acquire_dest_image(void *abstract_surface,
+                                         cairo_rectangle_t * interest_rect,
+                                         cairo_image_surface_t ** image_out,
+                                         cairo_rectangle_t * image_rect,
+                                         void **image_extra)
+{
+    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
+							abstract_surface);
+
+    if (surface->bitmap) {
+	surface->view->Sync();
+	*image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
+	if (!*image_out) {
+	    _cairo_error(CAIRO_STATUS_NO_MEMORY);
+	    return CAIRO_STATUS_NO_MEMORY;
+	}
+
+	image_rect->x = 0;
+	image_rect->y = 0;
+	image_rect->width = (*image_out)->width;
+	image_rect->height = (*image_out)->height;
+
+	*image_extra = NULL;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
+    BRect b_interest_rect(_cairo_rect_to_brect(interest_rect));
+
+    BRect rect;
+    BBitmap* bitmap;
+    ViewCopyStatus status = _cairo_beos_view_to_bitmap(surface->view, &bitmap,
+	                                               &rect, &b_interest_rect);
+    if (status == NOT_VISIBLE) {
+	*image_out = NULL;
+	*image_extra = NULL;
+	return CAIRO_STATUS_SUCCESS;
+    }
+    if (status == ERROR) {
+	_cairo_error(CAIRO_STATUS_NO_MEMORY);
+	return CAIRO_STATUS_NO_MEMORY;
+    }
+
+    *image_rect = _brect_to_cairo_rect(rect);
+
+#if 0
+    fprintf(stderr, "Requested: (cairo rects) (%ix%i) dim (%u, %u) returning (%ix%i) dim (%u, %u)\n",
+	    interest_rect->x, interest_rect->y, interest_rect->width, interest_rect->height,
+	    image_rect->x, image_rect->y, image_rect->width, image_rect->height);
+#endif
+
+    *image_out = _cairo_beos_bitmap_to_surface(bitmap);
+    delete bitmap;
+    if (!*image_out) {
+	_cairo_error(CAIRO_STATUS_NO_MEMORY);
+	return CAIRO_STATUS_NO_MEMORY;
+    }
+    *image_extra = NULL;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+
+static void
+_cairo_beos_surface_release_dest_image(void *abstract_surface,
+                                         cairo_rectangle_t *
+                                         intersect_rect,
+                                         cairo_image_surface_t * image,
+                                         cairo_rectangle_t * image_rect,
+                                         void *image_extra)
+{
+    fprintf(stderr, "Fallback drawing\n");
+    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
+							abstract_surface);
+
+    BBitmap* bitmap_to_draw = _cairo_image_surface_to_bitmap(image);
+
+    surface->view->PushState();
+
+	surface->view->SetDrawingMode(B_OP_COPY);
+	BRect rect(_cairo_rect_to_brect(image_rect));
+
+	surface->view->DrawBitmap(bitmap_to_draw, rect);
+
+    surface->view->PopState();
+
+    delete bitmap_to_draw;
+    cairo_surface_destroy(&image->base);
+}
+
+static void
+_cairo_beos_fill_rectangle(cairo_beos_surface_t* surface,
+		      cairo_rectangle_t* rect)
+{
+    BRect brect(_cairo_rect_to_brect(rect));
+    surface->view->FillRect(brect);
+}
+
+static cairo_int_status_t
+_cairo_beos_fill_rectangles(void *abstract_surface,
+			    cairo_operator_t op,
+			    const cairo_color_t *color,
+			    cairo_rectangle_t *rects,
+			    int	 num_rects)
+{
+    fprintf(stderr, "Drawing %i rectangles\n", num_rects);
+    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
+							abstract_surface);
+
+    if (num_rects <= 0)
+	return CAIRO_INT_STATUS_SUCCESS;
+
+    drawing_mode mode;
+    if (!_cairo_op_to_be_op(op, &mode))
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    rgb_color be_color = _cairo_color_to_be_color(color);
+
+    if (mode == B_OP_ALPHA && be_color.alpha == 0xFF)
+	mode = B_OP_COPY;
+
+    surface->view->PushState();
+
+	surface->view->SetDrawingMode(mode);
+	surface->view->SetHighColor(be_color);
+	if (surface->bitmap && surface->bitmap->ColorSpace() == B_RGBA32)
+	    surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_COMPOSITE);
+	else
+	    surface->view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY);
+
+	for (int i = 0; i < num_rects; ++i) {
+	    _cairo_beos_fill_rectangle(surface, &rects[i]);
+	}
+
+    surface->view->PopState();
+
+    return CAIRO_INT_STATUS_SUCCESS;
+}
+
+
+
+static cairo_int_status_t
+_cairo_beos_surface_set_clip_region(void *abstract_surface,
+                                      pixman_region16_t * region)
+{
+    fprintf(stderr, "Setting clip region\n");
+    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
+							abstract_surface);
+    if (region == NULL) {
+	// No clipping
+	surface->view->ConstrainClippingRegion(NULL);
+	return CAIRO_INT_STATUS_SUCCESS;
+    }
+
+    int count = pixman_region_num_rects(region);
+    pixman_box16_t* rects = pixman_region_rects(region);
+    BRegion bregion;
+    for (int i = 0; i < count; ++i) {
+	// Have to substract one, because for pixman, the second coordinate
+	// lies outside the rectangle.
+	bregion.Include(BRect(rects[i].x1, rects[i].y1, rects[i].x2 - 1, rects[i].y2  - 1));
+    }
+    surface->view->ConstrainClippingRegion(&bregion);
+    return CAIRO_INT_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
+_cairo_beos_surface_get_extents (void *abstract_surface,
+				   cairo_rectangle_t * rectangle)
+{
+    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
+							abstract_surface);
+
+    BRect size = surface->view->Bounds();
+
+    *rectangle = _brect_to_cairo_rect(size);
+
+    // Make sure to have our upperleft edge as (0,0)
+    rectangle->x = 0;
+    rectangle->y = 0;
+
+    return CAIRO_INT_STATUS_SUCCESS;
+}
+
+static const struct _cairo_surface_backend cairo_beos_surface_backend = {
+    NULL, /* create_similar */ // should implement
+    _cairo_beos_surface_finish,
+    _cairo_beos_surface_acquire_source_image,
+    _cairo_beos_surface_release_source_image,
+    _cairo_beos_surface_acquire_dest_image,
+    _cairo_beos_surface_release_dest_image,
+    NULL, /* clone_similar */ // should implement
+    NULL, /* composite */ // should implement
+    _cairo_beos_fill_rectangles,
+    NULL, /* composite_trapezoids */ // should implement (antialiasing?)
+    NULL, /* copy_page */
+    NULL, /* show_page */
+    _cairo_beos_surface_set_clip_region,
+    NULL, /* intersect_clip_path */ // should implement
+    _cairo_beos_surface_get_extents,
+    NULL,  /* show_glyphs */
+    NULL, /* fill_path */ // should implement (antialiasing?)
+    NULL, /* get_font_options */
+    NULL, /* flush */
+    NULL /* mark_dirty_rectangle */
+};
+
+cairo_surface_t *
+cairo_beos_surface_create(BView* view)
+{
+    return cairo_beos_surface_create_for_bitmap(view, NULL);
+}
+
+cairo_surface_t *
+cairo_beos_surface_create_for_bitmap (BView* view, BBitmap* bmp)
+{
+    // Must use malloc, because cairo code will use free() on the surface
+    cairo_beos_surface_t *surface = static_cast<cairo_beos_surface_t*>(
+					malloc(sizeof(cairo_beos_surface_t)));
+    if (surface == NULL) {
+	_cairo_error (CAIRO_STATUS_NO_MEMORY);
+        return const_cast<cairo_surface_t*>(&_cairo_surface_nil);
+    }
+
+    _cairo_surface_init(&surface->base, &cairo_beos_surface_backend);
+
+    surface->view = view;
+    surface->bitmap = bmp;
+
+    return (cairo_surface_t *) surface;
+}
+
+// ---------------------------------------------------------------------------
+// Cairo uses locks without explicit initialization. To support that, we
+// provide a class here which manages the locks and is in global scope, so the
+// compiler will instantiate it on library load and destroy it on library
+// unload.
+
+class BeLocks {
+    public:
+	BLocker cairo_toy_font_face_hash_table_mutex;
+	BLocker cairo_scaled_font_map_mutex;
+	BLocker cairo_ft_unscaled_font_map_mutex;
+};
+
+static BeLocks locks;
+
+void* cairo_toy_font_face_hash_table_mutex = &locks.cairo_toy_font_face_hash_table_mutex;
+void* cairo_scaled_font_map_mutex = &locks.cairo_scaled_font_map_mutex;
+void* cairo_ft_unscaled_font_map_mutex = &locks.cairo_ft_unscaled_font_map_mutex;
+
+void _cairo_beos_lock(void* locker) {
+    BLocker* bLocker = reinterpret_cast<BLocker*>(locker);
+    bLocker->Lock();
+}
+
+void _cairo_beos_unlock(void* locker) {
+    BLocker* bLocker = reinterpret_cast<BLocker*>(locker);
+    bLocker->Unlock();
+}
+
Index: src/cairo-beos.h
===================================================================
RCS file: src/cairo-beos.h
diff -N src/cairo-beos.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/cairo-beos.h	10 Oct 2005 22:40:00 -0000
@@ -0,0 +1,77 @@
+/* cairo - a vector graphics library with display and print output
+ *
+ * Copyright © 2005 Christian Biesinger <cbiesinger at web.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it either under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * (the "LGPL") or, at your option, under the terms of the Mozilla
+ * Public License Version 1.1 (the "MPL"). If you do not alter this
+ * notice, a recipient may use your version of this file under either
+ * the MPL or the LGPL.
+ *
+ * You should have received a copy of the LGPL along with this library
+ * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * You should have received a copy of the MPL along with this library
+ * in the file COPYING-MPL-1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+ * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+ * the specific language governing rights and limitations.
+ *
+ * The Original Code is the cairo graphics library.
+ *
+ * The Initial Developer of the Original Code is Christian Biesinger
+ * <cbiesinger at web.de>
+ *
+ * Contributor(s):
+ */
+
+#ifndef CAIRO_BEOS_H
+#define CAIRO_BEOS_H
+
+#include <cairo.h>
+
+#if CAIRO_HAS_BEOS_SURFACE
+
+#include <View.h>
+
+CAIRO_BEGIN_DECLS
+
+/**
+ * Creates a Cairo surface that draws onto a BeOS BView.
+ * The caller must ensure that the view does not get deleted before the surface.
+ */
+cairo_public cairo_surface_t *
+cairo_beos_surface_create (BView*		view);
+
+/**
+ * Creates a Cairo surface that draws onto a BeOS BView which is attached to a
+ * BBitmap.
+ * The caller must ensure that the view and the bitmap do not get deleted
+ * before the surface.
+ *
+ * For views that draw to a bitmap (as opposed to a screen), use this function
+ * rather than cairo_beos_surface_create. Not using this function WILL lead to
+ * incorrect behaviour.
+ *
+ * For now, only views that draw to the entire area of bmp are supported.
+ * The view must already be attached to the bitmap.
+ */
+cairo_public cairo_surface_t *
+cairo_beos_surface_create_for_bitmap (BView* view, BBitmap* bmp);
+
+CAIRO_END_DECLS
+
+#else  /* CAIRO_HAS_BEOS_SURFACE */
+# error Cairo was not compiled with support for the beos backend
+#endif /* CAIRO_HAS_BEOS_SURFACE */
+
+#endif /* CAIRO_BEOS_H */
+
Index: src/cairo-features.h.in
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-features.h.in,v
retrieving revision 1.22
diff -p -u -6 -r1.22 cairo-features.h.in
--- src/cairo-features.h.in	7 Sep 2005 23:31:22 -0000	1.22
+++ src/cairo-features.h.in	10 Oct 2005 22:40:00 -0000
@@ -64,12 +64,14 @@
 @QUARTZ_SURFACE_FEATURE@
 
 @XCB_SURFACE_FEATURE@
 
 @WIN32_SURFACE_FEATURE@
 
+ at BEOS_SURFACE_FEATURE@
+
 @GLITZ_SURFACE_FEATURE@
 
 @FT_FONT_FEATURE@
 
 @WIN32_FONT_FEATURE@
 
Index: src/cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.214
diff -p -u -6 -r1.214 cairoint.h
--- src/cairoint.h	10 Oct 2005 19:45:15 -0000	1.214
+++ src/cairoint.h	10 Oct 2005 22:40:00 -0000
@@ -145,12 +147,23 @@
 # define CAIRO_MUTEX_DECLARE(name) extern CRITICAL_SECTION name; 
 # define CAIRO_MUTEX_DECLARE_GLOBAL(name) extern LPCRITICAL_SECTION name;
 # define CAIRO_MUTEX_LOCK(name) EnterCriticalSection (&name)
 # define CAIRO_MUTEX_UNLOCK(name) LeaveCriticalSection (&name)
 #endif
 
+#if !defined(CAIRO_MUTEX_DECLARE) && defined CAIRO_HAS_BEOS_SURFACE
+cairo_private void _cairo_beos_lock(void*);
+cairo_private void _cairo_beos_unlock(void*);
+  /* the real initialization takes place in a global constructor */
+# define CAIRO_MUTEX_DECLARE(name) extern void* name; 
+# define CAIRO_MUTEX_DECLARE_GLOBAL(name) extern void* name;
+# define CAIRO_MUTEX_LOCK(name) _cairo_beos_lock (&name)
+# define CAIRO_MUTEX_UNLOCK(name) _cairo_beos_unlock (&name)
+#endif
+
+
 #ifndef CAIRO_MUTEX_DECLARE
 # error "No mutex declarations. Cairo will not work with multiple threads." \
 	"(Remove this #error directive to acknowledge & accept this limitation)."
 # define CAIRO_MUTEX_DECLARE(name)
 # define CAIRO_MUTEX_DECLARE_GLOBAL(name)
 # define CAIRO_MUTEX_LOCK(name)
Index: test/.cvsignore
===================================================================
RCS file: /cvs/cairo/cairo/test/.cvsignore,v
retrieving revision 1.56
diff -p -u -6 -r1.56 .cvsignore
--- test/.cvsignore	9 Oct 2005 21:51:55 -0000	1.56
+++ test/.cvsignore	10 Oct 2005 22:40:00 -0000
@@ -79,10 +79,13 @@ xlib-surface
 *-xcb-out.png
 *-xcb-argb32-out.png
 *-xcb-rgb24-out.png
 *-xlib-out.png
 *-xlib-argb32-out.png
 *-xlib-rgb24-out.png
+*-beos-rgb24-out.png
+*-beos_bitmap-rgb24-out.png
+*-beos_bitmap-argb32-out.png
 *-diff.png
 *.la
 *.lo
 *.log
Index: test/Makefile.am
===================================================================
RCS file: /cvs/cairo/cairo/test/Makefile.am,v
retrieving revision 1.97
diff -p -u -6 -r1.97 Makefile.am
--- test/Makefile.am	9 Oct 2005 21:51:55 -0000	1.97
+++ test/Makefile.am	10 Oct 2005 22:40:00 -0000
@@ -239,12 +239,18 @@ read-png.c	\
 read-png.h	\
 write-png.c	\
 write-png.h	\
 xmalloc.c	\
 xmalloc.h
 
+if CAIRO_HAS_BEOS_SURFACE
+libcairotest_la_SOURCES += cairo-test-beos.cpp cairo-test-beos.h
+# BeOS system headers trigger this warning
+libcairotest_la_CXXFLAGS = -Wno-multichar
+endif
+
 LDADDS = libcairotest.la $(top_builddir)/src/libcairo.la
 
 if HAVE_PTHREAD
 LDADDS += -lpthread
 endif
 
Index: test/cairo-test-beos.cpp
===================================================================
RCS file: test/cairo-test-beos.cpp
diff -N test/cairo-test-beos.cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ test/cairo-test-beos.cpp	10 Oct 2005 22:40:00 -0000
@@ -0,0 +1,239 @@
+/* vim:set ts=8 sw=4 noet cin: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Takashi Toyoshima <toyoshim at be-in.org>
+ *   Fredrik Holmqvist <thesuckiestemail at yahoo.se>
+ *   Christian Biesinger <cbiesinger at web.de>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Part of this code was originally part of
+// xpfe/bootstrap/nsNativeAppSupportBeOS.cpp in the Mozilla source code.
+
+#include <Application.h>
+#include <Window.h>
+#include <View.h>
+#include <Bitmap.h>
+
+extern "C" {
+#include "cairo-test.h"
+}
+
+#include "cairo-test-beos.h"
+#include "cairo-beos.h"
+
+class CairoTestWindow : public BWindow
+{
+public:
+    CairoTestWindow(BRect frame, const char* title);
+    virtual ~CairoTestWindow();
+    BView* View() const { return mView; }
+private:
+    BView* mView;
+};
+
+CairoTestWindow::CairoTestWindow(BRect frame, const char* title)
+    : BWindow(frame, title, B_TITLED_WINDOW,
+	      B_NOT_RESIZABLE|B_NOT_ZOOMABLE)
+{
+    mView = new BView(frame, "CairoWindowTestView", B_FOLLOW_ALL_SIDES, 0);
+    AddChild(mView);
+    Show();
+}
+
+CairoTestWindow::~CairoTestWindow()
+{
+    RemoveChild(mView);
+    delete mView;
+}
+
+
+class nsBeOSApp : public BApplication
+{
+public:
+    nsBeOSApp(sem_id sem) : BApplication(GetAppSig()), init(sem)
+    {}
+
+    void ReadyToRun()
+    {
+        release_sem(init);
+    }
+
+    static int32 Main(void *args)
+    {
+        nsBeOSApp *app = new nsBeOSApp( (sem_id)args );
+        if(app == NULL)
+            return B_ERROR;
+        return app->Run();
+    }
+
+private:
+
+    const char *GetAppSig()
+    {
+        return "application/x-vnd.cairo-test-app";
+    }
+
+    sem_id init;
+}; //class nsBeOSApp
+
+class AppRunner
+{
+    public:
+	AppRunner();
+	~AppRunner();
+};
+
+AppRunner::AppRunner()
+{
+    if (be_app)
+	return;
+
+    sem_id initsem = create_sem(0, "Cairo BApplication init");
+    if (initsem < B_OK) {
+	cairo_test_log("Error creating BeOS initialization semaphore\n");
+        return;
+    }
+
+    thread_id tid = spawn_thread(nsBeOSApp::Main, "Cairo/BeOS test", B_NORMAL_PRIORITY, (void *)initsem);
+    if (tid < B_OK || B_OK != resume_thread(tid)) {
+	cairo_test_log("Error spawning thread\n");
+	return;
+    }
+
+    if (B_OK != acquire_sem(initsem)) {
+	cairo_test_log("Error acquiring semaphore\n");
+	return;
+    }
+
+    delete_sem(initsem);
+    return;
+}
+
+AppRunner::~AppRunner()
+{
+    if (be_app) {
+	if (be_app->Lock())
+	    be_app->Quit();
+	delete be_app;
+	be_app = NULL;
+    }
+}
+
+// Make sure that the BApplication is initialized
+static AppRunner sAppRunner;
+
+struct beos_test_closure
+{
+    BView* view;
+    BBitmap* bitmap;
+    BWindow* window;
+};
+
+// Test a real window
+cairo_surface_t *
+create_beos_surface (cairo_test_t* test, cairo_format_t format, void **closure)
+{
+    float right = test->width ? test->width - 1 : 0;
+    float bottom = test->height ? test->height - 1 : 0;
+    BRect rect(0.0, 0.0, right, bottom);
+    CairoTestWindow* wnd = new CairoTestWindow(rect, test->name);
+    if (!wnd->View()->LockLooper()) {
+	cairo_test_log("Error locking looper\n");
+	return NULL;
+    }
+
+    beos_test_closure* bclosure = new beos_test_closure;
+    bclosure->view = wnd->View();
+    bclosure->bitmap = NULL;
+    bclosure->window = wnd;
+
+    *closure = bclosure;
+
+    return cairo_beos_surface_create(wnd->View());
+}
+
+void
+cleanup_beos (void* closure)
+{
+    beos_test_closure* bclosure = reinterpret_cast<beos_test_closure*>(closure);
+
+    bclosure->window->Quit();
+
+    delete bclosure;
+}
+
+// Test a bitmap
+cairo_surface_t *
+create_beos_bitmap_surface (cairo_test_t* test, cairo_format_t format,
+	                    void **closure)
+{
+    BRect rect(0.0, 0.0, test->width - 1, test->height - 1);
+    color_space beosformat = (format == CAIRO_FORMAT_RGB24) ? B_RGB32
+							    : B_RGBA32;
+    BBitmap* bmp = new BBitmap(rect, beosformat, true);
+    BView* view = new BView(rect, "Cairo test view", B_FOLLOW_ALL_SIDES, 0);
+    bmp->AddChild(view);
+
+    if (!view->LockLooper()) {
+	cairo_test_log("Error locking looper\n");
+	return NULL;
+    }
+
+    beos_test_closure* bclosure = new beos_test_closure;
+    bclosure->view = view;
+    bclosure->bitmap = bmp;
+    bclosure->window = NULL;
+    *closure = bclosure;
+
+    return cairo_beos_surface_create_for_bitmap(view, bmp);
+}
+
+void
+cleanup_beos_bitmap (void* closure)
+{
+    beos_test_closure* bclosure = reinterpret_cast<beos_test_closure*>(closure);
+
+    bclosure->view->UnlockLooper();
+
+    bclosure->bitmap->RemoveChild(bclosure->view);
+
+
+    delete bclosure->view;
+    delete bclosure->bitmap;
+
+    delete bclosure;
+}
+
+
Index: test/cairo-test-beos.h
===================================================================
RCS file: test/cairo-test-beos.h
diff -N test/cairo-test-beos.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ test/cairo-test-beos.h	10 Oct 2005 22:40:00 -0000
@@ -0,0 +1,26 @@
+#ifndef CAIRO_TEST_BEOS_H_
+#define CAIRO_TEST_BEOS_H_
+
+/* Two functions: One for a real window, one for a bitmap */
+
+#include <cairo.h>
+
+CAIRO_BEGIN_DECLS
+
+extern cairo_surface_t *
+create_beos_surface (cairo_test_t* test, cairo_format_t format,
+                     void **closure);
+
+extern void
+cleanup_beos (void* closure);
+
+extern cairo_surface_t *
+create_beos_bitmap_surface (cairo_test_t* test, cairo_format_t format,
+                            void **closure);
+
+extern void
+cleanup_beos_bitmap (void* closure);
+
+CAIRO_END_DECLS
+
+#endif
Index: test/cairo-test.c
===================================================================
RCS file: /cvs/cairo/cairo/test/cairo-test.c,v
retrieving revision 1.61
diff -p -u -6 -r1.61 cairo-test.c
--- test/cairo-test.c	8 Oct 2005 18:58:20 -0000	1.61
+++ test/cairo-test.c	10 Oct 2005 22:40:00 -0000
@@ -470,12 +470,17 @@ cleanup_xlib (void *closure)
     XFreePixmap (xtc->dpy, xtc->pixmap);
     XCloseDisplay (xtc->dpy);
     free (xtc);
 }
 #endif
 
+#if CAIRO_HAS_BEOS_SURFACE
+/* BeOS test functions are external as they need to be C++ */
+#include "cairo-test-beos.h"
+#endif
+
 #if CAIRO_HAS_PS_SURFACE
 #include "cairo-ps.h"
 
 cairo_user_data_key_t	ps_closure_key;
 
 typedef struct _ps_target_closure
@@ -685,12 +690,20 @@ cairo_test_expecting (cairo_test_t *test
 		create_ps_surface, ps_surface_write_to_png, cleanup_ps },
 #endif
 #if 0 && CAIRO_HAS_PDF_SURFACE
 	    { "pdf", CAIRO_FORMAT_RGB24, 
 		create_pdf_surface, pdf_surface_write_to_png, cleanup_pdf },
 #endif
+#if CAIRO_HAS_BEOS_SURFACE
+	    { "beos", CAIRO_FORMAT_RGB24,
+		create_beos_surface, cairo_surface_write_to_png, cleanup_beos},
+	    { "beos_bitmap", CAIRO_FORMAT_RGB24,
+		create_beos_bitmap_surface, cairo_surface_write_to_png, cleanup_beos_bitmap},
+	    { "beos_bitmap", CAIRO_FORMAT_ARGB32,
+		create_beos_bitmap_surface, cairo_surface_write_to_png, cleanup_beos_bitmap},
+#endif
 	};
 
     cairo_test_init (test->name);
 
     /* The intended logic here is that we return overall SUCCESS
      * iff. there is at least one tested backend and that all tested


More information about the cairo mailing list