summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Haslam <jason.haslam@gmail.com>2014-04-04 15:57:30 -0600
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-04-08 09:54:16 +0200
commit53c8a687b46f6ce8c24fabfe924758fe174b6922 (patch)
tree78897293288cd5b86cf8e61f01055d9d89ae261f /src
parentf6dce4c858e525b7f2adc4f5f5e6e92152d2a002 (diff)
Fix xcb plugin backing store byte order issue
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 <jorgen.lind@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp33
1 files changed, 24 insertions, 9 deletions
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());