From 53c8a687b46f6ce8c24fabfe924758fe174b6922 Mon Sep 17 00:00:00 2001 From: Jason Haslam Date: Fri, 4 Apr 2014 15:57:30 -0600 Subject: Fix xcb plugin backing store byte order issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The image format of the backing store should use the byte order of the machine where the application is running, not the native format of the X server. Then, if the byte order of the backing store image differs from the X server's native format, it needs to be converted before being sent across the network. Task-number: QTBUG-29898 Change-Id: Ic91c8ffb814c6beeb9f1d9195174a47d8bd94a90 Reviewed-by: Jørgen Lind --- src/plugins/platforms/xcb/qxcbbackingstore.cpp | 33 +++++++++++++++++++------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 1579797f85..57d6bc580b 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -94,14 +94,23 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI , m_gc_window(0) { Q_XCB_NOOP(connection()); - m_xcb_image = xcb_image_create_native(xcb_connection(), - size.width(), - size.height(), - XCB_IMAGE_FORMAT_Z_PIXMAP, - depth, - 0, - ~0, - 0); + + const xcb_setup_t *setup = xcb_get_setup(xcb_connection()); + xcb_format_t *fmt = xcb_setup_pixmap_formats(setup); + xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup); + for (; fmt != fmtend; ++fmt) + if (fmt->depth == depth) + break; + + Q_ASSERT(fmt != fmtend); + + m_xcb_image = xcb_image_create(size.width(), size.height(), + XCB_IMAGE_FORMAT_Z_PIXMAP, + fmt->scanline_pad, + fmt->depth, fmt->bits_per_pixel, 0, + QSysInfo::ByteOrder == QSysInfo::BigEndian ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST, + XCB_IMAGE_ORDER_MSB_FIRST, + 0, ~0, 0); const int segmentSize = m_xcb_image->stride * m_xcb_image->height; if (!segmentSize) @@ -209,10 +218,13 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s // at least 16384 bytes. That should be enough for quite large images. Q_ASSERT(rows_per_put > 0); + // Convert the image to the native byte order. + xcb_image_t *converted_image = xcb_image_native(xcb_connection(), m_xcb_image, 1); + while (height > 0) { int rows = std::min(height, rows_per_put); - xcb_image_t *subimage = xcb_image_subimage(m_xcb_image, src_x, src_y, width, rows, + xcb_image_t *subimage = xcb_image_subimage(converted_image, src_x, src_y, width, rows, 0, 0, 0); xcb_image_put(xcb_connection(), window, @@ -228,6 +240,9 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s target_y += rows; height -= rows; } + + if (converted_image != m_xcb_image) + xcb_image_destroy(converted_image); } Q_XCB_NOOP(connection()); -- cgit v1.2.3