From e026f767c9c600618104619d45ab6537f6988929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Thu, 21 Jul 2011 10:54:41 +0200 Subject: Handle failed SHM attach in XCB backing store. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I5f97c0c6030d13b68cfc17d19ba969cd78f79c3f Reviewed-on: http://codereview.qt.nokia.com/1943 Reviewed-by: Qt Sanity Bot Reviewed-by: Jørgen Lind --- src/plugins/platforms/xcb/qxcbbackingstore.cpp | 54 +++++++++++++++++++------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp index 3def577462..50407f7c9b 100644 --- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp +++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp @@ -114,12 +114,18 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI xcb_generic_error_t *error = xcb_request_check(xcb_connection(), xcb_shm_attach_checked(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false)); if (error) { - qWarning() << "QXcbBackingStore: Unable to attach to shared memory segment"; free(error); - } - if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1) - qWarning() << "QXcbBackingStore: Error while marking the shared memory segment to be destroyed"; + shmdt(m_shm_info.shmaddr); + shmctl(m_shm_info.shmid, IPC_RMID, 0); + + m_shm_info.shmaddr = 0; + + m_xcb_image->data = (uint8_t *)qMalloc(segmentSize); + } else { + if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1) + qWarning() << "QXcbBackingStore: Error while marking the shared memory segment to be destroyed"; + } m_qimage = QImage( (uchar*) m_xcb_image->data, m_xcb_image->width, m_xcb_image->height, m_xcb_image->stride, format); } @@ -127,14 +133,18 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI void QXcbShmImage::destroy() { const int segmentSize = m_xcb_image ? (m_xcb_image->stride * m_xcb_image->height) : 0; - if (segmentSize) + if (segmentSize && m_shm_info.shmaddr) Q_XCB_CALL(xcb_shm_detach(xcb_connection(), m_shm_info.shmseg)); xcb_image_destroy(m_xcb_image); if (segmentSize) { - shmdt(m_shm_info.shmaddr); - shmctl(m_shm_info.shmid, IPC_RMID, 0); + if (m_shm_info.shmaddr) { + shmdt(m_shm_info.shmaddr); + shmctl(m_shm_info.shmid, IPC_RMID, 0); + } else { + qFree(m_xcb_image->data); + } } if (m_gc) @@ -155,18 +165,32 @@ void QXcbShmImage::put(xcb_window_t window, const QPoint &target, const QRect &s } Q_XCB_NOOP(connection()); - xcb_image_shm_put(xcb_connection(), + if (m_shm_info.shmaddr) { + xcb_image_shm_put(xcb_connection(), + window, + m_gc, + m_xcb_image, + m_shm_info, + source.x(), + source.y(), + target.x(), + target.y(), + source.width(), + source.height(), + false); + } else { + xcb_image_t *subimage = xcb_image_subimage(m_xcb_image, source.x(), source.y(), source.width(), source.height(), + 0, 0, 0); + xcb_image_put(xcb_connection(), window, m_gc, - m_xcb_image, - m_shm_info, - source.x(), - source.y(), + subimage, target.x(), target.y(), - source.width(), - source.height(), - false); + 0); + + xcb_image_destroy(subimage); + } Q_XCB_NOOP(connection()); m_dirty = m_dirty | source; -- cgit v1.2.3