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);
    AutoLockView locker(surface->view);
    if (!locker) {
	_cairo_error(CAIRO_STATUS_NO_MEMORY);
	return CAIRO_STATUS_NO_MEMORY; /// XXX not exactly right, but what can we do?
    }


    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;
}
/**
 * _cairo_beos_bitmap_to_surface:
 *
 * 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*>(
					_cairo_malloc_ab(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;
}
static cairo_status_t
_cairo_beos_surface_acquire_dest_image (void			 *abstract_surface,
                                        cairo_rectangle_int16_t	 *interest_rect,
                                        cairo_image_surface_t	**image_out,
                                        cairo_rectangle_int16_t	 *image_rect,
                                        void			**image_extra)
{
    cairo_beos_surface_t *surface = reinterpret_cast<cairo_beos_surface_t*>(
							abstract_surface);

    AutoLockView locker(surface->view);
    if (!locker) {
	*image_out = NULL;
	*image_extra = NULL;
	return CAIRO_STATUS_SUCCESS;
    }

    if (surface->bitmap) {
	surface->view->Sync();
	*image_out = _cairo_beos_bitmap_to_surface(surface->bitmap);
	if (!*image_out)
	    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)
	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)
	return CAIRO_STATUS_NO_MEMORY;

    *image_extra = NULL;

    return CAIRO_STATUS_SUCCESS;
}