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/qglxintegration.cpp157
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.h9
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbmime.cpp7
-rw-r--r--src/plugins/platforms/xcb/qxcbmime.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp17
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h10
-rw-r--r--src/plugins/platforms/xcb/qxcbxsettings.cpp45
12 files changed, 223 insertions, 46 deletions
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index f78d3bcc4e..30d5c911e7 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -54,6 +54,7 @@
#include "qglxintegration.h"
#include <QtPlatformSupport/private/qglxconvenience_p.h>
+#include <QtPlatformHeaders/QGLXNativeContext>
#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4)
#include <dlfcn.h>
@@ -83,31 +84,31 @@ typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXC
#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
#endif
-static Window createDummyWindow(QXcbScreen *screen, XVisualInfo *visualInfo)
+static Window createDummyWindow(Display *dpy, XVisualInfo *visualInfo, int screenNumber, Window rootWin)
{
- Colormap cmap = XCreateColormap(DISPLAY_FROM_XCB(screen), screen->root(), visualInfo->visual, AllocNone);
+ Colormap cmap = XCreateColormap(dpy, rootWin, visualInfo->visual, AllocNone);
XSetWindowAttributes a;
- a.background_pixel = WhitePixel(DISPLAY_FROM_XCB(screen), screen->screenNumber());
- a.border_pixel = BlackPixel(DISPLAY_FROM_XCB(screen), screen->screenNumber());
+ a.background_pixel = WhitePixel(dpy, screenNumber);
+ a.border_pixel = BlackPixel(dpy, screenNumber);
a.colormap = cmap;
- Window window = XCreateWindow(DISPLAY_FROM_XCB(screen), screen->root(),
+ Window window = XCreateWindow(dpy, rootWin,
0, 0, 100, 100,
0, visualInfo->depth, InputOutput, visualInfo->visual,
CWBackPixel|CWBorderPixel|CWColormap, &a);
#ifndef QT_NO_DEBUG
- XStoreName(DISPLAY_FROM_XCB(screen), window, "Qt GLX dummy window");
+ XStoreName(dpy, window, "Qt GLX dummy window");
#endif
- XFreeColormap(DISPLAY_FROM_XCB(screen), cmap);
+ XFreeColormap(dpy, cmap);
return window;
}
-static Window createDummyWindow(QXcbScreen *screen, GLXFBConfig config)
+static Window createDummyWindow(Display *dpy, GLXFBConfig config, int screenNumber, Window rootWin)
{
- XVisualInfo *visualInfo = glXGetVisualFromFBConfig(DISPLAY_FROM_XCB(screen), config);
+ XVisualInfo *visualInfo = glXGetVisualFromFBConfig(dpy, config);
if (!visualInfo)
qFatal("Could not initialize GLX");
- Window window = createDummyWindow(screen, visualInfo);
+ Window window = createDummyWindow(dpy, visualInfo, screenNumber, rootWin);
XFree(visualInfo);
return window;
}
@@ -160,7 +161,8 @@ static void updateFormatFromContext(QSurfaceFormat &format)
}
}
-QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share)
+QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share,
+ const QVariant &nativeHandle)
: QPlatformOpenGLContext()
, m_screen(screen)
, m_context(0)
@@ -168,6 +170,15 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
, m_format(format)
, m_isPBufferCurrent(false)
, m_swapInterval(-1)
+ , m_ownsContext(nativeHandle.isNull())
+{
+ if (nativeHandle.isNull())
+ init(screen, share);
+ else
+ init(screen, share, nativeHandle);
+}
+
+void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share)
{
if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType)
m_format.setRenderableType(QSurfaceFormat::OpenGL);
@@ -195,7 +206,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
&& (m_format.renderableType() != QSurfaceFormat::OpenGLES || (supportsProfiles && glxExt.contains("GLX_EXT_create_context_es2_profile")))) {
// Try to create an OpenGL context for each known OpenGL version in descending
// order from the requested version.
- const int requestedVersion = format.majorVersion() * 10 + qMin(format.minorVersion(), 9);
+ const int requestedVersion = m_format.majorVersion() * 10 + qMin(m_format.minorVersion(), 9);
QVector<int> glVersions;
if (m_format.renderableType() == QSurfaceFormat::OpenGL) {
@@ -282,10 +293,10 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
// Get the basic surface format details
if (m_context)
- qglx_surfaceFormatFromGLXFBConfig(&m_format, DISPLAY_FROM_XCB(screen), config, m_context);
+ qglx_surfaceFormatFromGLXFBConfig(&m_format, DISPLAY_FROM_XCB(screen), config);
// Create a temporary window so that we can make the new context current
- window = createDummyWindow(screen, config);
+ window = createDummyWindow(DISPLAY_FROM_XCB(screen), config, screen->screenNumber(), screen->root());
} else {
// requesting an OpenGL ES context requires glXCreateContextAttribsARB, so bail out
if (m_format.renderableType() == QSurfaceFormat::OpenGLES)
@@ -303,7 +314,7 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
}
// Create a temporary window so that we can make the new context current
- window = createDummyWindow(screen, visualInfo);
+ window = createDummyWindow(DISPLAY_FROM_XCB(screen), visualInfo, screen->screenNumber(), screen->root());
XFree(visualInfo);
}
@@ -320,9 +331,123 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat
XDestroyWindow(DISPLAY_FROM_XCB(screen), window);
}
+void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share, const QVariant &nativeHandle)
+{
+ if (!nativeHandle.canConvert<QGLXNativeContext>()) {
+ qWarning("QGLXContext: Requires a QGLXNativeContext");
+ return;
+ }
+ QGLXNativeContext handle = nativeHandle.value<QGLXNativeContext>();
+ GLXContext context = handle.context();
+ if (!context) {
+ qWarning("QGLXContext: No GLXContext given");
+ return;
+ }
+
+ // Use the provided Display, if available. If not, use our own. It may still work.
+ Display *dpy = handle.display();
+ if (!dpy)
+ dpy = DISPLAY_FROM_XCB(screen);
+
+ // Legacy contexts created using glXCreateContext are created using a visual
+ // and the FBConfig cannot be queried. The only way to adapt these contexts
+ // is to figure out the visual id.
+ XVisualInfo *vinfo = 0;
+ // If the VisualID is provided use it.
+ VisualID vid = handle.visualId();
+ if (!vid) {
+ // In the absence of the VisualID figure it out from the window.
+ Window wnd = handle.window();
+ if (wnd) {
+ XWindowAttributes attrs;
+ XGetWindowAttributes(dpy, wnd, &attrs);
+ vid = XVisualIDFromVisual(attrs.visual);
+ }
+ }
+ if (vid) {
+ XVisualInfo v;
+ v.screen = screen->screenNumber();
+ v.visualid = vid;
+ int n = 0;
+ vinfo = XGetVisualInfo(dpy, VisualScreenMask | VisualIDMask, &v, &n);
+ if (n < 1) {
+ XFree(vinfo);
+ vinfo = 0;
+ }
+ }
+
+ // For contexts created with an FBConfig using the modern functions providing the
+ // visual or window is not mandatory. Just query the config from the context.
+ GLXFBConfig config = 0;
+ if (!vinfo) {
+ int configId = 0;
+ if (glXQueryContext(dpy, context, GLX_FBCONFIG_ID, &configId) != Success) {
+ qWarning("QGLXContext: Failed to query config from the provided context");
+ return;
+ }
+
+ GLXFBConfig *configs;
+ int numConfigs = 0;
+ static const int attribs[] = { GLX_FBCONFIG_ID, configId, None };
+ configs = glXChooseFBConfig(dpy, screen->screenNumber(), attribs, &numConfigs);
+ if (!configs || numConfigs < 1) {
+ qWarning("QGLXContext: Failed to find config");
+ return;
+ }
+ if (configs && numConfigs > 1) // this is suspicious so warn but let it continue
+ qWarning("QGLXContext: Multiple configs for FBConfig ID %d", configId);
+
+ config = configs[0];
+ }
+
+ Q_ASSERT(vinfo || config);
+
+ int screenNumber = DefaultScreen(dpy);
+ Window window;
+ if (vinfo)
+ window = createDummyWindow(dpy, vinfo, screenNumber, RootWindow(dpy, screenNumber));
+ else
+ window = createDummyWindow(dpy, config, screenNumber, RootWindow(dpy, screenNumber));
+ if (!window) {
+ qWarning("QGLXContext: Failed to create dummy window");
+ return;
+ }
+
+ // Update OpenGL version and buffer sizes in our format.
+ if (!glXMakeCurrent(dpy, window, context)) {
+ qWarning("QGLXContext: Failed to make provided context current");
+ return;
+ }
+ m_format = QSurfaceFormat();
+ m_format.setRenderableType(QOpenGLContext::openGLModuleType() == QOpenGLContext::DesktopGL
+ ? QSurfaceFormat::OpenGL : QSurfaceFormat::OpenGLES);
+ updateFormatFromContext(m_format);
+ if (vinfo)
+ qglx_surfaceFormatFromVisualInfo(&m_format, dpy, vinfo);
+ else
+ qglx_surfaceFormatFromGLXFBConfig(&m_format, dpy, config);
+ glXMakeCurrent(dpy, 0, 0);
+ XDestroyWindow(dpy, window);
+
+ if (vinfo)
+ XFree(vinfo);
+
+ // Success. Store the context. From this point on isValid() is true.
+ m_context = context;
+
+ if (share)
+ m_shareContext = static_cast<const QGLXContext*>(share)->glxContext();
+}
+
QGLXContext::~QGLXContext()
{
- glXDestroyContext(DISPLAY_FROM_XCB(m_screen), m_context);
+ if (m_ownsContext)
+ glXDestroyContext(DISPLAY_FROM_XCB(m_screen), m_context);
+}
+
+QVariant QGLXContext::nativeHandle() const
+{
+ return QVariant::fromValue<QGLXNativeContext>(QGLXNativeContext(m_context));
}
bool QGLXContext::makeCurrent(QPlatformSurface *surface)
diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h
index 00bba94ab3..a7787f5f86 100644
--- a/src/plugins/platforms/xcb/qglxintegration.h
+++ b/src/plugins/platforms/xcb/qglxintegration.h
@@ -58,7 +58,8 @@ QT_BEGIN_NAMESPACE
class QGLXContext : public QPlatformOpenGLContext
{
public:
- QGLXContext(QXcbScreen *xd, const QSurfaceFormat &format, QPlatformOpenGLContext *share);
+ QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlatformOpenGLContext *share,
+ const QVariant &nativeHandle);
~QGLXContext();
bool makeCurrent(QPlatformSurface *surface);
@@ -72,16 +73,22 @@ public:
GLXContext glxContext() const { return m_context; }
+ QVariant nativeHandle() const;
+
static bool supportsThreading();
static void queryDummyContext();
private:
+ void init(QXcbScreen *screen, QPlatformOpenGLContext *share);
+ void init(QXcbScreen *screen, QPlatformOpenGLContext *share, const QVariant &nativeHandle);
+
QXcbScreen *m_screen;
GLXContext m_context;
GLXContext m_shareContext;
QSurfaceFormat m_format;
bool m_isPBufferCurrent;
int m_swapInterval;
+ bool m_ownsContext;
static bool m_queriedDummyContext;
static bool m_supportsThreading;
};
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index e7f8510706..3b30274f25 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -135,9 +135,10 @@ protected:
(void)formats(); // trigger update of format list
- QList<xcb_atom_t> atoms;
+ QVector<xcb_atom_t> atoms;
xcb_atom_t *targets = (xcb_atom_t *) format_atoms.data();
int size = format_atoms.size() / sizeof(xcb_atom_t);
+ atoms.reserve(size);
for (int i = 0; i < size; ++i)
atoms.append(targets[i]);
@@ -524,7 +525,7 @@ xcb_atom_t QXcbClipboard::sendTargetsSelection(QMimeData *d, xcb_window_t window
QVector<xcb_atom_t> types;
QStringList formats = QInternalMimeData::formatsHelper(d);
for (int i = 0; i < formats.size(); ++i) {
- QList<xcb_atom_t> atoms = QXcbMime::mimeAtomsForFormat(connection(), formats.at(i));
+ QVector<xcb_atom_t> atoms = QXcbMime::mimeAtomsForFormat(connection(), formats.at(i));
for (int j = 0; j < atoms.size(); ++j) {
if (!types.contains(atoms.at(j)))
types.append(atoms.at(j));
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 1933b89a19..1719d8ec6b 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -451,6 +451,7 @@ public:
void setFocusWindow(QXcbWindow *);
QByteArray startupId() const { return m_startupId; }
+ void setStartupId(const QByteArray &nextId) { m_startupId = nextId; }
void clearStartupId() { m_startupId.clear(); }
void grabServer();
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 4f0f57c375..bcadcd1f02 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -183,7 +183,7 @@ void QXcbDrag::startDrag()
QStringList fmts = QXcbMime::formatsHelper(drag()->mimeData());
for (int i = 0; i < fmts.size(); ++i) {
- QList<xcb_atom_t> atoms = QXcbMime::mimeAtomsForFormat(connection(), fmts.at(i));
+ QVector<xcb_atom_t> atoms = QXcbMime::mimeAtomsForFormat(connection(), fmts.at(i));
for (int j = 0; j < atoms.size(); ++j) {
if (!drag_types.contains(atoms.at(j)))
drag_types.append(atoms.at(j));
@@ -1211,7 +1211,7 @@ QVariant QXcbDropData::xdndObtainData(const QByteArray &format, QVariant::Type r
return result;
}
- QList<xcb_atom_t> atoms = drag->xdnd_types;
+ QVector<xcb_atom_t> atoms = drag->xdnd_types;
QByteArray encoding;
xcb_atom_t a = mimeAtomForFormat(c, QLatin1String(format), requestedType, atoms, &encoding);
if (a == XCB_NONE)
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
index d94c42696f..7b0d337e7c 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.h
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -46,7 +46,6 @@
#include <private/qsimpledrag_p.h>
#include <qxcbobject.h>
#include <xcb/xcb.h>
-#include <qlist.h>
#include <qpoint.h>
#include <qrect.h>
#include <qsharedpointer.h>
@@ -127,7 +126,7 @@ private:
// the types in this drop. 100 is no good, but at least it's big.
enum { xdnd_max_type = 100 };
- QList<xcb_atom_t> xdnd_types;
+ QVector<xcb_atom_t> xdnd_types;
// timestamp from XdndPosition and XdndDroptime for retrieving the data
xcb_timestamp_t target_time;
@@ -160,7 +159,7 @@ private:
QPointer<QDrag> drag;
QTime time;
};
- QList<Transaction> transactions;
+ QVector<Transaction> transactions;
int transaction_expiry_timer;
void restartDropExpiryTimer();
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 0bab341914..2d4c523a4b 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -233,7 +233,10 @@ QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLCont
{
QXcbScreen *screen = static_cast<QXcbScreen *>(context->screen()->handle());
#if defined(XCB_USE_GLX)
- return new QGLXContext(screen, context->format(), context->shareHandle());
+ QGLXContext *platformContext = new QGLXContext(screen, context->format(),
+ context->shareHandle(), context->nativeHandle());
+ context->setNativeHandle(platformContext->nativeHandle());
+ return platformContext;
#elif defined(XCB_USE_EGL)
return new QEGLXcbPlatformContext(context->format(), context->shareHandle(),
screen->connection()->egl_display(), screen->connection());
diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp
index b205a63267..c0f6745e7f 100644
--- a/src/plugins/platforms/xcb/qxcbmime.cpp
+++ b/src/plugins/platforms/xcb/qxcbmime.cpp
@@ -136,9 +136,10 @@ bool QXcbMime::mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeDa
return ret;
}
-QList<xcb_atom_t> QXcbMime::mimeAtomsForFormat(QXcbConnection *connection, const QString &format)
+QVector<xcb_atom_t> QXcbMime::mimeAtomsForFormat(QXcbConnection *connection, const QString &format)
{
- QList<xcb_atom_t> atoms;
+ QVector<xcb_atom_t> atoms;
+ atoms.reserve(7);
atoms.append(connection->internAtom(format.toLatin1()));
// special cases for strings
@@ -240,7 +241,7 @@ QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a,
}
xcb_atom_t QXcbMime::mimeAtomForFormat(QXcbConnection *connection, const QString &format, QVariant::Type requestedType,
- const QList<xcb_atom_t> &atoms, QByteArray *requestedEncoding)
+ const QVector<xcb_atom_t> &atoms, QByteArray *requestedEncoding)
{
requestedEncoding->clear();
diff --git a/src/plugins/platforms/xcb/qxcbmime.h b/src/plugins/platforms/xcb/qxcbmime.h
index 4a69a35ced..563716a75b 100644
--- a/src/plugins/platforms/xcb/qxcbmime.h
+++ b/src/plugins/platforms/xcb/qxcbmime.h
@@ -59,14 +59,14 @@ public:
QXcbMime();
~QXcbMime();
- static QList<xcb_atom_t> mimeAtomsForFormat(QXcbConnection *connection, const QString &format);
+ static QVector<xcb_atom_t> mimeAtomsForFormat(QXcbConnection *connection, const QString &format);
static QString mimeAtomToString(QXcbConnection *connection, xcb_atom_t a);
static bool mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeData *mimeData, QByteArray *data,
xcb_atom_t *atomFormat, int *dataFormat);
static QVariant mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a, const QByteArray &data, const QString &format,
QVariant::Type requestedType, const QByteArray &encoding);
static xcb_atom_t mimeAtomForFormat(QXcbConnection *connection, const QString &format, QVariant::Type requestedType,
- const QList<xcb_atom_t> &atoms, QByteArray *requestedEncoding);
+ const QVector<xcb_atom_t> &atoms, QByteArray *requestedEncoding);
};
#endif // !(defined(QT_NO_DRAGANDDROP) && defined(QT_NO_CLIPBOARD))
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index b45bd6a82e..37936a9c72 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -225,6 +225,14 @@ void *QXcbNativeInterface::nativeResourceForWindow(const QByteArray &resourceStr
return result;
}
+QPlatformNativeInterface::NativeResourceForIntegrationFunction QXcbNativeInterface::nativeResourceFunctionForIntegration(const QByteArray &resource)
+{
+ QByteArray lowerCaseResource = resource.toLower();
+ if (lowerCaseResource == "setstartupid")
+ return NativeResourceForIntegrationFunction(setStartupId);
+ return 0;
+}
+
QPlatformNativeInterface::NativeResourceForScreenFunction QXcbNativeInterface::nativeResourceFunctionForScreen(const QByteArray &resource)
{
const QByteArray lowerCaseResource = resource.toLower();
@@ -287,6 +295,15 @@ void QXcbNativeInterface::setAppUserTime(QScreen* screen, xcb_timestamp_t time)
static_cast<QXcbScreen *>(screen->handle())->connection()->setNetWmUserTime(time);
}
+void QXcbNativeInterface::setStartupId(const char *data)
+{
+ QByteArray startupId(data);
+ QXcbIntegration *integration = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration());
+ QXcbConnection *defaultConnection = integration->defaultConnection();
+ if (defaultConnection)
+ defaultConnection->setStartupId(startupId);
+}
+
QPlatformNativeInterface::NativeResourceForContextFunction QXcbNativeInterface::nativeResourceFunctionForContext(const QByteArray &resource)
{
QByteArray lowerCaseResource = resource.toLower();
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index fb1a46014c..cf26aff011 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -77,11 +77,12 @@ public:
QXcbNativeInterface();
void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
- void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context);
- void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen);
- void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
+ void *nativeResourceForContext(const QByteArray &resourceString, QOpenGLContext *context) Q_DECL_OVERRIDE;
+ void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) Q_DECL_OVERRIDE;
+ void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window) Q_DECL_OVERRIDE;
- NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource);
+ NativeResourceForIntegrationFunction nativeResourceFunctionForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
+ NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
NativeResourceForScreenFunction nativeResourceFunctionForScreen(const QByteArray &resource) Q_DECL_OVERRIDE;
inline const QByteArray &genericEventFilterType() const { return m_genericEventFilterType; }
@@ -96,6 +97,7 @@ public:
void *startupId();
void *x11Screen();
void *rootWindow();
+ static void setStartupId(const char *);
static void setAppTime(QScreen *screen, xcb_timestamp_t time);
static void setAppUserTime(QScreen *screen, xcb_timestamp_t time);
static void *eglContextForContext(QOpenGLContext *context);
diff --git a/src/plugins/platforms/xcb/qxcbxsettings.cpp b/src/plugins/platforms/xcb/qxcbxsettings.cpp
index 141a6cc0cb..17b40a45e1 100644
--- a/src/plugins/platforms/xcb/qxcbxsettings.cpp
+++ b/src/plugins/platforms/xcb/qxcbxsettings.cpp
@@ -42,6 +42,7 @@
#include "qxcbxsettings.h"
#include <QtCore/QByteArray>
+#include <QtCore/QtEndian>
#include <X11/extensions/XIproto.h>
@@ -149,47 +150,67 @@ public:
{
if (xSettings.length() < 12)
return;
- // we ignore byteorder for now
- char byteOrder = xSettings.at(1);
- Q_UNUSED(byteOrder);
- uint number_of_settings = *reinterpret_cast<const uint *>(xSettings.mid(8,4).constData());
+ char byteOrder = xSettings.at(0);
+ if (byteOrder != LSBFirst && byteOrder != MSBFirst) {
+ qWarning("%s ByteOrder byte %d not 0 or 1", Q_FUNC_INFO , byteOrder);
+ return;
+ }
+
+#define ADJUST_BO(b, t, x) \
+ ((b == LSBFirst) ? \
+ qFromLittleEndian<t>((const uchar *)(x)) : \
+ qFromBigEndian<t>((const uchar *)(x)))
+#define VALIDATE_LENGTH(x) \
+ if ((size_t)xSettings.length() < (offset + local_offset + 12 + x)) { \
+ qWarning("%s Length %d runs past end of data", Q_FUNC_INFO , x); \
+ return; \
+ }
+ uint number_of_settings = ADJUST_BO(byteOrder, quint32, xSettings.mid(8,4).constData());
const char *data = xSettings.constData() + 12;
size_t offset = 0;
for (uint i = 0; i < number_of_settings; i++) {
int local_offset = 0;
+ VALIDATE_LENGTH(2);
XSettingsType type = static_cast<XSettingsType>(*reinterpret_cast<const quint8 *>(data + offset));
local_offset += 2;
- quint16 name_len = *reinterpret_cast<const quint16 *>(data + offset + local_offset);
+ VALIDATE_LENGTH(2);
+ quint16 name_len = ADJUST_BO(byteOrder, quint16, data + offset + local_offset);
local_offset += 2;
+ VALIDATE_LENGTH(name_len);
QByteArray name(data + offset + local_offset, name_len);
local_offset += round_to_nearest_multiple_of_4(name_len);
- int last_change_serial = *reinterpret_cast<const int *>(data + offset + local_offset);
+ VALIDATE_LENGTH(4);
+ int last_change_serial = ADJUST_BO(byteOrder, qint32, data + offset + local_offset);
Q_UNUSED(last_change_serial);
local_offset += 4;
QVariant value;
if (type == XSettingsTypeString) {
- int value_length = *reinterpret_cast<const int *>(data + offset + local_offset);
+ VALIDATE_LENGTH(4);
+ int value_length = ADJUST_BO(byteOrder, qint32, data + offset + local_offset);
local_offset+=4;
+ VALIDATE_LENGTH(value_length);
QByteArray value_string(data + offset + local_offset, value_length);
value.setValue(value_string);
local_offset += round_to_nearest_multiple_of_4(value_length);
} else if (type == XSettingsTypeInteger) {
- int value_length = *reinterpret_cast<const int *>(data + offset + local_offset);
+ VALIDATE_LENGTH(4);
+ int value_length = ADJUST_BO(byteOrder, qint32, data + offset + local_offset);
local_offset += 4;
value.setValue(value_length);
} else if (type == XSettingsTypeColor) {
- quint16 red = *reinterpret_cast<const quint16 *>(data + offset + local_offset);
+ VALIDATE_LENGTH(2*4);
+ quint16 red = ADJUST_BO(byteOrder, quint16, data + offset + local_offset);
local_offset += 2;
- quint16 green = *reinterpret_cast<const quint16 *>(data + offset + local_offset);
+ quint16 green = ADJUST_BO(byteOrder, quint16, data + offset + local_offset);
local_offset += 2;
- quint16 blue = *reinterpret_cast<const quint16 *>(data + offset + local_offset);
+ quint16 blue = ADJUST_BO(byteOrder, quint16, data + offset + local_offset);
local_offset += 2;
- quint16 alpha= *reinterpret_cast<const quint16 *>(data + offset + local_offset);
+ quint16 alpha= ADJUST_BO(byteOrder, quint16, data + offset + local_offset);
local_offset += 2;
QColor color_value(red,green,blue,alpha);
value.setValue(color_value);