summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp54
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h4
-rw-r--r--src/plugins/platforms/xcb/xcb.pro1
4 files changed, 60 insertions, 0 deletions
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index c40ebe47bc..f7576fe19b 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -203,6 +203,7 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
case ThreadedPixmaps: return true;
case OpenGL: return true;
case ThreadedOpenGL: return false;
+ case WindowMasks: return true;
default: return QPlatformIntegration::hasCapability(cap);
}
}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 59e805fd0e..a4ee2a461c 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -44,6 +44,7 @@
#include <QtDebug>
#include <QScreen>
#include <QtGui/QIcon>
+#include <QtGui/QRegion>
#include "qxcbconnection.h"
#include "qxcbscreen.h"
@@ -97,6 +98,9 @@
#ifdef XCB_USE_XLIB
#include <X11/Xlib.h>
#include <X11/Xutil.h>
+#ifndef QT_NO_SHAPE
+# include <X11/extensions/shape.h>
+#endif // QT_NO_SHAPE
#endif
#ifdef XCB_USE_XINPUT2_MAEMO
@@ -1698,4 +1702,54 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
return true;
}
+#if defined(XCB_USE_XLIB) && !defined(QT_NO_SHAPE)
+
+static inline XRectangle qRectToX11Rectangle(const QRect &r)
+{
+ XRectangle result;
+ result.x = qMax(SHRT_MIN, r.x());
+ result.y = qMax(SHRT_MIN, r.y());
+ result.width = qMin((int)USHRT_MAX, r.width());
+ result.height = qMin((int)USHRT_MAX, r.height());
+ return result;
+}
+
+static inline Region qRegionToX11Region(const QRegion &region)
+{
+ if (region.isEmpty())
+ return None;
+ Region result = XCreateRegion();
+ if (!result)
+ return None;
+ const QVector<QRect> rects = region.rects();
+ if (rects.size() == 1) {
+ XRectangle xrect = qRectToX11Rectangle(region.boundingRect());
+ XUnionRectWithRegion(&xrect, result, result);
+ } else {
+ foreach (const QRect &r, rects) {
+ XRectangle xrect = qRectToX11Rectangle(r);
+ XUnionRectWithRegion(&xrect, result, result);
+ }
+ }
+ return result;
+}
+
+
+void QXcbWindow::setMask(const QRegion &region)
+{
+
+ Display *display = (Display *)connection()->xlib_display();
+ if (region.isEmpty()) {
+ XShapeCombineMask(display, xcb_window(),
+ ShapeBounding, 0, 0,
+ None, ShapeSet);
+ } else {
+ XShapeCombineRegion(display, xcb_window(),
+ ShapeBounding, 0, 0,
+ qRegionToX11Region(region), ShapeSet);
+ }
+}
+
+#endif // XCB_USE_XLIB && !QT_NO_SHAPE
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index d383248428..0c4ec34269 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -109,6 +109,10 @@ public:
bool startSystemResize(const QPoint &pos, Qt::Corner corner);
+#if defined(XCB_USE_XLIB) && !defined(QT_NO_SHAPE)
+ void setMask(const QRegion &region);
+#endif // XCB_USE_XLIB && !QT_NO_SHAPE
+
xcb_window_t xcb_window() const { return m_window; }
uint depth() const { return m_depth; }
QImage::Format imageFormat() const { return m_imageFormat; }
diff --git a/src/plugins/platforms/xcb/xcb.pro b/src/plugins/platforms/xcb/xcb.pro
index 210b770a51..8e6fbc6c63 100644
--- a/src/plugins/platforms/xcb/xcb.pro
+++ b/src/plugins/platforms/xcb/xcb.pro
@@ -45,6 +45,7 @@ contains(QT_CONFIG, xcb-poll-for-queued-event) {
# needed by GLX, Xcursor, XLookupString, ...
contains(QT_CONFIG, xcb-xlib) {
DEFINES += XCB_USE_XLIB
+ !contains(DEFINES, QT_NO_SHAPE):LIBS += -lXext
LIBS += -lX11 -lX11-xcb
linux-g++-maemo {