diff options
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbwindowsurface.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindowsurface.cpp | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp b/src/plugins/platforms/xcb/qxcbwindowsurface.cpp index 4fcd207df3..63378515cc 100644 --- a/src/plugins/platforms/xcb/qxcbwindowsurface.cpp +++ b/src/plugins/platforms/xcb/qxcbwindowsurface.cpp @@ -52,6 +52,7 @@ #include <sys/shm.h> #include <stdio.h> +#include <errno.h> #include <qdebug.h> #include <qpainter.h> @@ -97,9 +98,16 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI ~0, 0); - m_shm_info.shmid = shmget (IPC_PRIVATE, - m_xcb_image->stride * m_xcb_image->height, IPC_CREAT|0777); + const int segmentSize = m_xcb_image->stride * m_xcb_image->height; + if (!segmentSize) + return; + int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0777); + if (id == -1) + qWarning("QXcbShmImage: shmget() failed (%d) for size %d (%dx%d)", + errno, segmentSize, size.width(), size.height()); + else + m_shm_info.shmid = id; m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat (m_shm_info.shmid, 0, 0); m_shm_info.shmseg = xcb_generate_id(xcb_connection()); @@ -117,10 +125,17 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI void QXcbShmImage::destroy() { - Q_XCB_CALL(xcb_shm_detach(xcb_connection(), m_shm_info.shmseg)); + const int segmentSize = m_xcb_image ? (m_xcb_image->stride * m_xcb_image->height) : 0; + if (segmentSize) + Q_XCB_CALL(xcb_shm_detach(xcb_connection(), m_shm_info.shmseg)); + xcb_image_destroy(m_xcb_image); - shmdt(m_shm_info.shmaddr); - shmctl(m_shm_info.shmid, IPC_RMID, 0); + + if (segmentSize) { + shmdt(m_shm_info.shmaddr); + shmctl(m_shm_info.shmid, IPC_RMID, 0); + } + if (m_gc) Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc)); } @@ -168,12 +183,12 @@ void QXcbShmImage::preparePaint(const QRegion ®ion) } } -QXcbWindowSurface::QXcbWindowSurface(QWidget *widget, bool setDefaultSurface) - : QWindowSurface(widget, setDefaultSurface) +QXcbWindowSurface::QXcbWindowSurface(QWindow *window, bool setDefaultSurface) + : QWindowSurface(window, setDefaultSurface) , m_image(0) , m_syncingResize(false) { - QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(widget)); + QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWindow(window)); setConnection(screen->connection()); } @@ -206,7 +221,7 @@ void QXcbWindowSurface::endPaint(const QRegion &) { } -void QXcbWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) +void QXcbWindowSurface::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { QRect bounds = region.boundingRect(); @@ -215,14 +230,11 @@ void QXcbWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoi Q_XCB_NOOP(connection()); - QXcbWindow *window = static_cast<QXcbWindow *>(widget->window()->platformWindow()); - - extern QWidgetData* qt_widget_data(QWidget *); - QPoint widgetOffset = qt_qwidget_data(widget)->wrect.topLeft(); + QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle()); QVector<QRect> rects = region.rects(); for (int i = 0; i < rects.size(); ++i) - m_image->put(window->window(), rects.at(i).topLeft() - widgetOffset, rects.at(i).translated(offset)); + m_image->put(platformWindow->xcb_window(), rects.at(i).topLeft(), rects.at(i).translated(offset)); Q_XCB_NOOP(connection()); @@ -230,7 +242,7 @@ void QXcbWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoi xcb_flush(xcb_connection()); connection()->sync(); m_syncingResize = false; - window->updateSyncRequestCounter(); + platformWindow->updateSyncRequestCounter(); } } @@ -242,8 +254,8 @@ void QXcbWindowSurface::resize(const QSize &size) Q_XCB_NOOP(connection()); QWindowSurface::resize(size); - QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWidget(window())); - QXcbWindow* win = static_cast<QXcbWindow *>(window()->platformWindow()); + QXcbScreen *screen = static_cast<QXcbScreen *>(QPlatformScreen::platformScreenForWindow(window())); + QXcbWindow* win = static_cast<QXcbWindow *>(window()->handle()); delete m_image; m_image = new QXcbShmImage(screen, size, win->depth(), win->format()); @@ -256,7 +268,7 @@ extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &o bool QXcbWindowSurface::scroll(const QRegion &area, int dx, int dy) { - if (m_image->image()->isNull()) + if (!m_image || m_image->image()->isNull()) return false; m_image->preparePaint(area); |