1 /* cairo - a vector graphics library with display and print output
3 * Copyright © 2009 Intel Corporation
5 * This library is free software; you can redistribute it and/or
6 * modify it either under the terms of the GNU Lesser General Public
7 * License version 2.1 as published by the Free Software Foundation
8 * (the "LGPL") or, at your option, under the terms of the Mozilla
9 * Public License Version 1.1 (the "MPL"). If you do not alter this
10 * notice, a recipient may use your version of this file under either
11 * the MPL or the LGPL.
13 * You should have received a copy of the LGPL along with this library
14 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16 * You should have received a copy of the MPL along with this library
17 * in the file COPYING-MPL-1.1
19 * The contents of this file are subject to the Mozilla Public License
20 * Version 1.1 (the "License"); you may not use this file except in
21 * compliance with the License. You may obtain a copy of the License at
22 * http://www.mozilla.org/MPL/
24 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26 * the specific language governing rights and limitations.
29 * Chris Wilson <chris@chris-wilson.co.uk>
34 #include "cairo-xcb-private.h"
36 #include <xcb/xcbext.h>
39 _cairo_xcb_connection_create_pixmap (cairo_xcb_connection_t *connection,
41 xcb_drawable_t drawable,
45 xcb_pixmap_t pixmap = _cairo_xcb_connection_get_xid (connection);
49 xcb_create_pixmap (connection->xcb_connection,
50 depth, pixmap, drawable,
56 _cairo_xcb_connection_free_pixmap (cairo_xcb_connection_t *connection,
59 xcb_free_pixmap (connection->xcb_connection, pixmap);
60 _cairo_xcb_connection_put_xid (connection, pixmap);
64 _cairo_xcb_connection_create_gc (cairo_xcb_connection_t *connection,
65 xcb_drawable_t drawable,
69 xcb_gcontext_t gc = _cairo_xcb_connection_get_xid (connection);
70 xcb_create_gc (connection->xcb_connection, gc, drawable,
76 _cairo_xcb_connection_free_gc (cairo_xcb_connection_t *connection,
79 xcb_free_gc (connection->xcb_connection, gc);
80 _cairo_xcb_connection_put_xid (connection, gc);
84 _cairo_xcb_connection_change_gc (cairo_xcb_connection_t *connection,
89 xcb_change_gc (connection->xcb_connection, gc,
94 _cairo_xcb_connection_copy_area (cairo_xcb_connection_t *connection,
105 xcb_copy_area (connection->xcb_connection, src, dst, gc,
106 src_x, src_y, dst_x, dst_y, width, height);
110 _cairo_xcb_connection_poly_fill_rectangle (cairo_xcb_connection_t *connection,
113 uint32_t num_rectangles,
114 xcb_rectangle_t *rectangles)
116 xcb_poly_fill_rectangle (connection->xcb_connection, dst, gc,
117 num_rectangles, rectangles);
121 _cairo_xcb_connection_put_image (cairo_xcb_connection_t *connection,
132 const uint32_t req_size = 18;
133 uint32_t length = height * stride;
134 uint32_t len = (req_size + length) >> 2;
136 if (len < connection->maximum_request_length) {
137 xcb_put_image (connection->xcb_connection, XCB_IMAGE_FORMAT_Z_PIXMAP,
138 dst, gc, width, height, dst_x, dst_y, 0, depth,
141 int rows = (connection->maximum_request_length - req_size - 4) / stride;
147 length = rows * stride;
149 xcb_put_image (connection->xcb_connection, XCB_IMAGE_FORMAT_Z_PIXMAP,
150 dst, gc, width, rows, dst_x, dst_y, 0, depth, length, data);
154 data = (char *) data + length;
163 _cairo_xcb_connection_put_subimage (cairo_xcb_connection_t *connection,
177 xcb_protocol_request_t xcb_req = {
180 XCB_PUT_IMAGE /* opcode */,
181 1 /* isvoid (doesn't cause a reply) */
183 xcb_put_image_request_t req;
184 struct iovec vec_stack[CAIRO_STACK_ARRAY_LENGTH (struct iovec)];
185 struct iovec *vec = vec_stack;
187 uint8_t *data = _data;
189 /* Two extra entries are needed for xcb, two for us */
190 int entries_needed = height + 2 + 2;
192 req.format = XCB_IMAGE_FORMAT_Z_PIXMAP;
204 if (entries_needed > ARRAY_LENGTH (vec_stack)) {
205 vec = _cairo_malloc_ab (entries_needed, sizeof (struct iovec));
206 if (unlikely (vec == NULL)) {
207 /* XXX loop over ARRAY_LENGTH (vec_stack) */
212 data += src_y * stride + src_x * cpp;
213 /* vec[1] will be used in XCB if it has to use BigRequests or insert a sync,
214 * vec[0] is used if the internal queue needs to be flushed. */
215 vec[2].iov_base = (char *) &req;
216 vec[2].iov_len = sizeof (req);
218 /* Now comes the actual data */
220 vec[n].iov_base = data;
221 vec[n].iov_len = cpp * width;
227 /* And again some padding */
229 vec[n].iov_len = -len & 3;
232 /* For efficiency reasons, this functions writes the request "directly" to
233 * the xcb connection to avoid having to copy the data around. */
234 assert (n == entries_needed);
235 xcb_req.count = n - 2;
236 xcb_send_request (connection->xcb_connection, 0, &vec[2], &xcb_req);
238 if (vec != vec_stack)
243 _cairo_xcb_connection_get_image (cairo_xcb_connection_t *connection,
249 xcb_get_image_reply_t **reply)
251 xcb_generic_error_t *error;
253 *reply = xcb_get_image_reply (connection->xcb_connection,
254 xcb_get_image (connection->xcb_connection,
255 XCB_IMAGE_FORMAT_Z_PIXMAP,
269 return CAIRO_STATUS_SUCCESS;