static cairo_int_status_t _cairo_xcb_surface_create_shm_image (cairo_xcb_surface_t *target, cairo_image_surface_t **image_out, cairo_xcb_shm_info_t **shm_info_out) { cairo_image_surface_t *image; cairo_xcb_shm_info_t *shm_info; cairo_status_t status; size_t size, stride; if ((target->flags & CAIRO_XCB_HAS_SHM) == 0) return CAIRO_INT_STATUS_UNSUPPORTED; stride = CAIRO_STRIDE_FOR_WIDTH_BPP (target->width, PIXMAN_FORMAT_BPP (target->pixman_format)); size = stride * target->height; if (size < CAIRO_XCB_SHM_SMALL_IMAGE) { target->flags &= ~CAIRO_XCB_HAS_SHM; return CAIRO_INT_STATUS_UNSUPPORTED; } status = _cairo_xcb_connection_allocate_shm_info (target->screen->connection, size, &shm_info); if (unlikely (status)) return status; image = (cairo_image_surface_t *) _cairo_image_surface_create_with_pixman_format (shm_info->mem, target->pixman_format, target->width, target->height, stride); status = image->base.status; if (unlikely (status)) { _cairo_xcb_shm_info_destroy (shm_info); return status; } status = _cairo_user_data_array_set_data (&image->base.user_data, (const cairo_user_data_key_t *) target->connection, shm_info, (cairo_destroy_func_t) _cairo_xcb_shm_info_destroy); if (unlikely (status)) { cairo_surface_destroy (&image->base); _cairo_xcb_shm_info_destroy (shm_info); return status; } *image_out = image; *shm_info_out = shm_info; return CAIRO_STATUS_SUCCESS; }
static cairo_surface_t * _cairo_xcb_surface_create_shm_image (cairo_xcb_connection_t *connection, pixman_format_code_t pixman_format, int width, int height, cairo_bool_t might_reuse, cairo_xcb_shm_info_t **shm_info_out) { cairo_surface_t *image; cairo_xcb_shm_info_t *shm_info; cairo_int_status_t status; size_t stride; *shm_info_out = NULL; stride = CAIRO_STRIDE_FOR_WIDTH_BPP (width, PIXMAN_FORMAT_BPP (pixman_format)); status = _cairo_xcb_connection_allocate_shm_info (connection, stride * height, might_reuse, &shm_info); if (unlikely (status)) { if (status == CAIRO_INT_STATUS_UNSUPPORTED) return NULL; return _cairo_surface_create_in_error (status); } image = _cairo_image_surface_create_with_pixman_format (shm_info->mem, pixman_format, width, height, stride); if (unlikely (image->status)) { _cairo_xcb_shm_info_destroy (shm_info); return image; } status = _cairo_user_data_array_set_data (&image->user_data, (const cairo_user_data_key_t *) connection, shm_info, (cairo_destroy_func_t) _cairo_xcb_shm_info_destroy); if (unlikely (status)) { cairo_surface_destroy (image); _cairo_xcb_shm_info_destroy (shm_info); return _cairo_surface_create_in_error (status); } *shm_info_out = shm_info; return image; }
static cairo_status_t _cairo_xcb_surface_create_similar_shm (cairo_xcb_surface_t *other, pixman_format_code_t pixman_format, int width, int height, cairo_surface_t **out) { size_t size, stride; cairo_xcb_shm_info_t *shm_info; cairo_status_t status; cairo_surface_t *image; stride = CAIRO_STRIDE_FOR_WIDTH_BPP (width, PIXMAN_FORMAT_BPP (pixman_format)); size = stride * height; if (size < CAIRO_XCB_SHM_SMALL_IMAGE) return CAIRO_INT_STATUS_UNSUPPORTED; status = _cairo_xcb_connection_allocate_shm_info (other->connection, size, &shm_info); if (unlikely (status)) return status; image = _cairo_image_surface_create_with_pixman_format (shm_info->mem, pixman_format, width, height, stride); status = image->status; if (unlikely (status)) { _cairo_xcb_shm_info_destroy (shm_info); return status; } status = _cairo_user_data_array_set_data (&image->user_data, (const cairo_user_data_key_t *) other->connection, shm_info, (cairo_destroy_func_t) _cairo_xcb_shm_info_destroy); if (unlikely (status)) { cairo_surface_destroy (image); _cairo_xcb_shm_info_destroy (shm_info); return status; } *out = image; return CAIRO_STATUS_SUCCESS; }
static cairo_status_t _cairo_xcb_shm_image_create (cairo_xcb_connection_t *connection, pixman_format_code_t pixman_format, int width, int height, cairo_image_surface_t **image_out, cairo_xcb_shm_info_t **shm_info_out) { cairo_surface_t *image = NULL; cairo_xcb_shm_info_t *shm_info = NULL; cairo_status_t status; #if CAIRO_HAS_XCB_SHM_FUNCTIONS if ((connection->flags & CAIRO_XCB_HAS_SHM)) { size_t size, stride; stride = CAIRO_STRIDE_FOR_WIDTH_BPP (width, PIXMAN_FORMAT_BPP (pixman_format)); size = stride * height; if (size > CAIRO_XCB_SHM_SMALL_IMAGE) { status = _cairo_xcb_connection_allocate_shm_info (connection, size, &shm_info); if (unlikely (status)) return status; image = _cairo_image_surface_create_with_pixman_format (shm_info->mem, pixman_format, width, height, stride); status = image->status; if (unlikely (status)) { _cairo_xcb_shm_info_destroy (shm_info); return status; } status = _cairo_user_data_array_set_data (&image->user_data, (const cairo_user_data_key_t *) connection, shm_info, (cairo_destroy_func_t) _cairo_xcb_shm_info_destroy); if (unlikely (status)) { cairo_surface_destroy (image); _cairo_xcb_shm_info_destroy (shm_info); return status; } } } #endif if (image == NULL) { image = _cairo_image_surface_create_with_pixman_format (NULL, pixman_format, width, height, 0); status = image->status; if (unlikely (status)) return status; } *image_out = (cairo_image_surface_t *) image; *shm_info_out = shm_info; return CAIRO_STATUS_SUCCESS; }