static cairo_xcb_pixmap_t *
_pixmap_from_image (cairo_xcb_surface_t *target,
		    xcb_render_pictformat_t format,
		    cairo_image_surface_t *image,
		    cairo_xcb_shm_info_t *shm_info)
{
    xcb_gcontext_t gc;
    cairo_xcb_pixmap_t *pixmap;

    pixmap = _cairo_xcb_pixmap_create (target,
				       image->width,
				       image->height);
    if (unlikely (pixmap->base.status))
	return pixmap;

    gc = _cairo_xcb_screen_get_gc (target->screen, pixmap->pixmap, image->depth);

    if (shm_info != NULL) {
	shm_info->seqno =
	    _cairo_xcb_connection_shm_put_image (target->connection,
						 pixmap->pixmap, gc,
						 image->width, image->height,
						 0, 0,
						 image->width, image->height,
						 0, 0,
						 image->depth,
						 shm_info->shm,
						 shm_info->offset);
    } else {
	int len;

	/* Do we need to trim the image? */
	len = CAIRO_STRIDE_FOR_WIDTH_BPP (image->width,
					  PIXMAN_FORMAT_BPP (image->pixman_format));
	if (len == image->stride) {
	    _cairo_xcb_connection_put_image (target->connection,
					     pixmap->pixmap, gc,
					     image->width, image->height,
					     0, 0,
					     image->depth,
					     image->stride,
					     image->data);
	} else {
	    _cairo_xcb_connection_put_subimage (target->connection,
						pixmap->pixmap, gc,
						0, 0,
						image->width, image->height,
						PIXMAN_FORMAT_BPP (image->pixman_format) / 8,
						image->stride,
						0, 0,
						image->depth,
						image->data);

	}
    }

    _cairo_xcb_screen_put_gc (target->screen, image->depth, gc);

    return pixmap;
}
Exemple #2
0
static cairo_status_t
_put_image_boxes (cairo_xcb_surface_t    *surface,
		  cairo_image_surface_t  *image,
		  cairo_boxes_t *boxes)
{
    cairo_int_status_t status = CAIRO_INT_STATUS_SUCCESS;
    xcb_gcontext_t gc;

    if (boxes->num_boxes == 0)
	    return CAIRO_STATUS_SUCCESS;

    /* XXX track damaged region? */

    status = _cairo_xcb_connection_acquire (surface->connection);
    if (unlikely (status))
	return status;

    assert (image->pixman_format == surface->pixman_format);
    assert (image->depth == surface->depth);
    assert (image->stride == (int) CAIRO_STRIDE_FOR_WIDTH_BPP (image->width, PIXMAN_FORMAT_BPP (image->pixman_format)));

    gc = _cairo_xcb_screen_get_gc (surface->screen,
				   surface->drawable,
				   surface->depth);

    status = _put_shm_image_boxes (surface, image, gc, boxes);
    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
	    struct _cairo_boxes_chunk *chunk;

	    for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
		    int i;

		    for (i = 0; i < chunk->count; i++) {
			    cairo_box_t *b = &chunk->base[i];
			    int x = _cairo_fixed_integer_part (b->p1.x);
			    int y = _cairo_fixed_integer_part (b->p1.y);
			    int width = _cairo_fixed_integer_part (b->p2.x - b->p1.x);
			    int height = _cairo_fixed_integer_part (b->p2.y - b->p1.y);
			    _cairo_xcb_connection_put_subimage (surface->connection,
								surface->drawable, gc,
								x, y,
								width, height,
								PIXMAN_FORMAT_BPP (image->pixman_format) / 8,
								image->stride,
								x, y,
								image->depth,
								image->data);

		    }
	    }
	    status = CAIRO_STATUS_SUCCESS;
    }

    _cairo_xcb_screen_put_gc (surface->screen, surface->depth, gc);
    _cairo_xcb_connection_release (surface->connection);
    return status;
}