summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbwindowsurface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbwindowsurface.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbwindowsurface.cpp48
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 &region)
}
}
-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 &region, const QPoint &offset)
+void QXcbWindowSurface::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
QRect bounds = region.boundingRect();
@@ -215,14 +230,11 @@ void QXcbWindowSurface::flush(QWidget *widget, const QRegion &region, 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 &region, 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);