static cairo_surface_t *
_cairo_win32_display_surface_create_for_dc (HDC             original_dc,
					    cairo_format_t  format,
					    int	            width,
					    int	            height)
{
    cairo_status_t status;
    cairo_device_t *device;
    cairo_win32_display_surface_t *surface;
    unsigned char *bits;
    int rowstride;

    surface = malloc (sizeof (*surface));
    if (surface == NULL)
	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));

    surface->fallback = NULL;

    status = _create_dc_and_bitmap (surface, original_dc, format,
				    width, height,
				    &bits, &rowstride);
    if (status)
	goto FAIL;

    surface->image = cairo_image_surface_create_for_data (bits, format,
							  width, height, rowstride);
    status = surface->image->status;
    if (status)
	goto FAIL;

    _cairo_image_surface_set_parent (to_image_surface(surface->image),
				     &surface->win32.base);

    surface->win32.format = format;

    surface->win32.extents.x = 0;
    surface->win32.extents.y = 0;
    surface->win32.extents.width = width;
    surface->win32.extents.height = height;

    surface->initial_clip_rgn = NULL;
    surface->had_simple_clip = FALSE;

    device = _cairo_win32_device_get ();

    _cairo_surface_init (&surface->win32.base,
			 &cairo_win32_display_surface_backend,
			 device,
			 _cairo_content_from_format (format));

    cairo_device_destroy (device);

    return &surface->win32.base;

 FAIL:
    if (surface->bitmap) {
	SelectObject (surface->win32.dc, surface->saved_dc_bitmap);
	DeleteObject (surface->bitmap);
	DeleteDC (surface->win32.dc);
    }
    free (surface);

    return _cairo_surface_create_in_error (status);
}
static cairo_surface_t *
_cairo_win32_surface_create_for_dc (HDC             original_dc,
				    cairo_format_t  format,
				    int	            width,
				    int	            height)
{
    cairo_status_t status;
    cairo_win32_surface_t *surface;
    char *bits;
    int rowstride;

    surface = malloc (sizeof (cairo_win32_surface_t));
    if (surface == NULL) {
	_cairo_error (CAIRO_STATUS_NO_MEMORY);
	return &_cairo_surface_nil;
    }

    status = _create_dc_and_bitmap (surface, original_dc, format,
				    width, height,
				    &bits, &rowstride);
    if (status)
	goto FAIL;

    surface->image = cairo_image_surface_create_for_data (bits, format,
							  width, height, rowstride);
    if (surface->image->status) {
	status = CAIRO_STATUS_NO_MEMORY;
	goto FAIL;
    }
    
    surface->format = format;
    
    surface->clip_rect.x = 0;
    surface->clip_rect.y = 0;
    surface->clip_rect.width = width;
    surface->clip_rect.height = height;

    surface->saved_clip = CreateRectRgn (0, 0, 0, 0);
    if (GetClipRgn (surface->dc, surface->saved_clip) == 0) {
        DeleteObject(surface->saved_clip);
        surface->saved_clip = NULL;
    }

    surface->extents = surface->clip_rect;

    _cairo_surface_init (&surface->base, &cairo_win32_surface_backend);

    return (cairo_surface_t *)surface;

 FAIL:
    if (surface->bitmap) {
	SelectObject (surface->dc, surface->saved_dc_bitmap);
  	DeleteObject (surface->bitmap);
        DeleteDC (surface->dc);
    }
    if (surface)
	free (surface);

    if (status == CAIRO_STATUS_NO_MEMORY) {
	_cairo_error (CAIRO_STATUS_NO_MEMORY);
	return &_cairo_surface_nil;
    } else {
	_cairo_error (status);
	return &_cairo_surface_nil;
    }
}