From 8dcfb43d8f6bdd9d1331391bb4dfbee73de30658 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Wed, 17 Dec 2014 16:05:23 +0100 Subject: [PATCH 01/25] Resolve GLES3 functions from the shared lib MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unfortunately the few functions that are part of the OpenGL ES 3.0 standard and are used by QtGui have to have special handling after all. Just directly calling the functions causes issues when building on a GLES3 capable system and deploying somewhere where only GLES2 is available. Using eglGetProcAddress and such is not an option because the ES spec does not guarantee that standard functions are resolvable via that mechanism. Task-number: QTBUG-43318 Change-Id: I72f985d75ca669835839016573cbb8e4a3fb41db Reviewed-by: Jørgen Lind --- src/gui/opengl/qopenglextensions_p.h | 27 ++++++ src/gui/opengl/qopenglfunctions.cpp | 99 +++++++++++++++------ src/gui/opengl/qopengltexturehelper.cpp | 31 ++++--- src/gui/opengl/qopenglvertexarrayobject.cpp | 16 ++-- 4 files changed, 123 insertions(+), 50 deletions(-) diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h index 23cfe16467..f53addaf0e 100644 --- a/src/gui/opengl/qopenglextensions_p.h +++ b/src/gui/opengl/qopenglextensions_p.h @@ -46,11 +46,36 @@ // #include "qopenglfunctions.h" +#include QT_BEGIN_NAMESPACE class QOpenGLExtensionsPrivate; +class QOpenGLES3Helper +{ +public: + QOpenGLES3Helper(); + + GLvoid* (QOPENGLF_APIENTRYP MapBufferRange)(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access); + GLboolean (QOPENGLF_APIENTRYP UnmapBuffer)(GLenum target); + void (QOPENGLF_APIENTRYP BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + void (QOPENGLF_APIENTRYP RenderbufferStorageMultisample)(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height); + + void (QOPENGLF_APIENTRYP GenVertexArrays)(GLsizei n, GLuint *arrays); + void (QOPENGLF_APIENTRYP DeleteVertexArrays)(GLsizei n, const GLuint *arrays); + void (QOPENGLF_APIENTRYP BindVertexArray)(GLuint array); + GLboolean (QOPENGLF_APIENTRYP IsVertexArray)(GLuint array); + + void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); + void (QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); + void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); + void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); + +private: + QLibrary m_gl; +}; + class Q_GUI_EXPORT QOpenGLExtensions : public QOpenGLFunctions { Q_DECLARE_PRIVATE(QOpenGLExtensions) @@ -102,6 +127,8 @@ public: void glGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data); + QOpenGLES3Helper *gles3Helper(); + private: static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; } }; diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index 44b56699df..d561e65d8e 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -3187,65 +3187,105 @@ static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribPointer(GLuint indx, GL #endif // !QT_OPENGL_ES_2 +// Functions part of the OpenGL ES 3.0+ standard need special handling. These, +// just like the 2.0 functions, are not guaranteed to be resolvable via +// eglGetProcAddress or similar. Calling them directly is, unlike the 2.0 +// functions, not feasible because one may build the binaries on a GLES3-capable +// system and then deploy on a GLES2-only system that does not have these +// symbols. Until ES3 gets universally available, they have to be dlsym'ed. + +Q_GLOBAL_STATIC(QOpenGLES3Helper, qgles3Helper) + +QOpenGLES3Helper::QOpenGLES3Helper() +{ +#ifdef Q_OS_WIN +#ifdef QT_DEBUG + m_gl.setFileName(QStringLiteral("libGLESv2")); +#else + m_gl.setFileName(QStringLiteral("libGLESv2d")); +#endif +#else + m_gl.setFileName(QStringLiteral("GLESv2")); +#endif + if (m_gl.load()) { + MapBufferRange = (GLvoid* (QOPENGLF_APIENTRYP)(GLenum, qopengl_GLintptr, qopengl_GLsizeiptr, GLbitfield)) m_gl.resolve("glMapBufferRange"); + UnmapBuffer = (GLboolean (QOPENGLF_APIENTRYP)(GLenum)) m_gl.resolve("glUnmapBuffer"); + BlitFramebuffer = (void (QOPENGLF_APIENTRYP)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)) m_gl.resolve("glBlitFramebuffer"); + RenderbufferStorageMultisample = (void (QOPENGLF_APIENTRYP)(GLenum, GLsizei, GLenum, GLsizei, GLsizei)) m_gl.resolve("glRenderbufferStorageMultisample"); + + GenVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, GLuint *)) m_gl.resolve("glGenVertexArrays"); + DeleteVertexArrays = (void (QOPENGLF_APIENTRYP)(GLsizei, const GLuint *)) m_gl.resolve("glDeleteVertexArrays"); + BindVertexArray = (void (QOPENGLF_APIENTRYP)(GLuint)) m_gl.resolve("glBindVertexArray"); + IsVertexArray = (GLboolean (QOPENGLF_APIENTRYP)(GLuint)) m_gl.resolve("glIsVertexArray"); + + TexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *)) m_gl.resolve("glTexImage3D"); + TexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *)) m_gl.resolve("glTexSubImage3D"); + CompressedTexImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *)) m_gl.resolve("glCompressedTexImage3D"); + CompressedTexSubImage3D = (void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *)) m_gl.resolve("glCompressedTexSubImage3D"); + + if (!MapBufferRange || !GenVertexArrays || !TexImage3D) + qFatal("OpenGL ES 3.0 entry points not found"); + } else { + qFatal("Failed to load libGLESv2"); + } +} + +static inline bool isES3() +{ + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + return ctx->isOpenGLES() && ctx->format().majorVersion() >= 3; +} + static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBuffer(GLenum target, GLenum access) { -#ifdef QT_OPENGL_ES_3 // It is possible that GL_OES_map_buffer is present, but then having to // differentiate between glUnmapBufferOES and glUnmapBuffer causes extra // headache. QOpenGLBuffer::map() will handle this automatically, while direct // calls are better off with migrating to the standard glMapBufferRange. - if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) { + if (isES3()) { qWarning("QOpenGLFunctions: glMapBuffer is not available in OpenGL ES 3.0 and up. Use glMapBufferRange instead."); return 0; - } else -#endif - RESOLVE_FUNC(GLvoid *, ResolveOES, MapBuffer)(target, access); + } else { + RESOLVE_FUNC(GLvoid *, ResolveOES, MapBuffer)(target, access); + } } static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBufferRange(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access) { -#ifdef QT_OPENGL_ES_3 - if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) - return ::glMapBufferRange(target, offset, length, access); + if (isES3()) + return qgles3Helper()->MapBufferRange(target, offset, length, access); else -#endif - RESOLVE_FUNC(GLvoid *, 0, MapBufferRange)(target, offset, length, access); + RESOLVE_FUNC(GLvoid *, 0, MapBufferRange)(target, offset, length, access); } static GLboolean QOPENGLF_APIENTRY qopenglfResolveUnmapBuffer(GLenum target) { -#ifdef QT_OPENGL_ES_3 - if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) - return ::glUnmapBuffer(target); + if (isES3()) + return qgles3Helper()->UnmapBuffer(target); else -#endif - RESOLVE_FUNC(GLboolean, ResolveOES, UnmapBuffer)(target); + RESOLVE_FUNC(GLboolean, ResolveOES, UnmapBuffer)(target); } static void QOPENGLF_APIENTRY qopenglfResolveBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { -#ifdef QT_OPENGL_ES_3 - if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) - ::glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + if (isES3()) + qgles3Helper()->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); else -#endif - RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer) - (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer) + (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); } static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height) { -#ifdef QT_OPENGL_ES_3 - if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) - ::glRenderbufferStorageMultisample(target, samples, internalFormat, width, height); + if (isES3()) + qgles3Helper()->RenderbufferStorageMultisample(target, samples, internalFormat, width, height); else -#endif - RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample) - (target, samples, internalFormat, width, height); + RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample) + (target, samples, internalFormat, width, height); } static void QOPENGLF_APIENTRY qopenglfResolveGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data) @@ -3494,4 +3534,9 @@ QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx) GetBufferSubData = qopenglfResolveGetBufferSubData; } +QOpenGLES3Helper *QOpenGLExtensions::gles3Helper() +{ + return qgles3Helper(); +} + QT_END_NAMESPACE diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp index 29cecf0ea8..e1e3593f4f 100644 --- a/src/gui/opengl/qopengltexturehelper.cpp +++ b/src/gui/opengl/qopengltexturehelper.cpp @@ -34,6 +34,7 @@ #include "qopengltexturehelper_p.h" #include +#include QT_BEGIN_NAMESPACE @@ -242,21 +243,23 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) CompressedTexImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3DOES"))); CompressedTexSubImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3DOES"))); } else { -#ifdef QT_OPENGL_ES_3 - // OpenGL ES 3.0+ has glTexImage3D. - TexImage3D = ::glTexImage3D; - TexSubImage3D = ::glTexSubImage3D; - CompressedTexImage3D = ::glCompressedTexImage3D; - CompressedTexSubImage3D = ::glCompressedTexSubImage3D; -#else - // OpenGL 1.2 - TexImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTexImage3D"))); - TexSubImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTexSubImage3D"))); + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (ctx->isOpenGLES() && ctx->format().majorVersion() >= 3) { + // OpenGL ES 3.0+ has glTexImage3D. + QOpenGLES3Helper *es3 = static_cast(ctx->functions())->gles3Helper(); + TexImage3D = es3->TexImage3D; + TexSubImage3D = es3->TexSubImage3D; + CompressedTexImage3D = es3->CompressedTexImage3D; + CompressedTexSubImage3D = es3->CompressedTexSubImage3D; + } else { + // OpenGL 1.2 + TexImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTexImage3D"))); + TexSubImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glTexSubImage3D"))); - // OpenGL 1.3 - CompressedTexImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3D"))); - CompressedTexSubImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3D"))); -#endif + // OpenGL 1.3 + CompressedTexImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3D"))); + CompressedTexSubImage3D = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3D"))); + } } #ifndef QT_OPENGL_ES_2 diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp index 5520dfed08..d3eadf9ae1 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.cpp +++ b/src/gui/opengl/qopenglvertexarrayobject.cpp @@ -35,12 +35,12 @@ #include #include -#include #include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -56,16 +56,14 @@ void qtInitializeVertexArrayObjectHelper(QOpenGLVertexArrayObjectHelper *helper, bool tryARB = true; if (context->isOpenGLES()) { -#ifdef QT_OPENGL_ES_3 if (context->format().majorVersion() >= 3) { - helper->GenVertexArrays = ::glGenVertexArrays; - helper->DeleteVertexArrays = ::glDeleteVertexArrays; - helper->BindVertexArray = ::glBindVertexArray; - helper->IsVertexArray = ::glIsVertexArray; + QOpenGLES3Helper *es3 = static_cast(context->functions())->gles3Helper(); + helper->GenVertexArrays = es3->GenVertexArrays; + helper->DeleteVertexArrays = es3->DeleteVertexArrays; + helper->BindVertexArray = es3->BindVertexArray; + helper->IsVertexArray = es3->IsVertexArray; tryARB = false; - } else -#endif - if (context->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) { + } else if (context->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) { helper->GenVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysOES"))); helper->DeleteVertexArrays = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysOES"))); helper->BindVertexArray = reinterpret_cast(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayOES"))); From be5cfa960b617fb31a2a1f4ce850c35dcb23fde5 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 8 Jan 2015 14:24:34 +0100 Subject: [PATCH 02/25] QMacPasteboardMimeFileUri: Use file paths instead of file references Change-Id: I732d94bc6add2814c8ebd2c7fe80592024dd1b9a Task-number: QTBUG-40449 Reviewed-by: Eike Ziller --- src/platformsupport/clipboard/qmacmime.mm | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/platformsupport/clipboard/qmacmime.mm b/src/platformsupport/clipboard/qmacmime.mm index 6fcd19e07b..44580b017c 100644 --- a/src/platformsupport/clipboard/qmacmime.mm +++ b/src/platformsupport/clipboard/qmacmime.mm @@ -611,9 +611,21 @@ QVariant QMacPasteboardMimeFileUri::convertToMime(const QString &mime, QList ret; for (int i = 0; i < data.size(); ++i) { - QUrl url = QUrl::fromEncoded(data.at(i)); + const QByteArray &a = data.at(i); + NSString *urlString = [[[NSString alloc] initWithBytesNoCopy:(void *)a.data() length:a.size() + encoding:NSUTF8StringEncoding freeWhenDone:NO] autorelease]; + NSURL *nsurl = [NSURL URLWithString:urlString]; + QUrl url; + // OS X 10.10 sends file references instead of file paths + if ([nsurl isFileReferenceURL]) { + url = QUrl::fromNSURL([nsurl filePathURL]); + } else { + url = QUrl::fromNSURL(nsurl); + } + if (url.host().toLower() == QLatin1String("localhost")) url.setHost(QString()); + url.setPath(url.path().normalized(QString::NormalizationForm_C)); ret.append(url); } From ea9a366d3f01262f32134d1e9f7853d17832dbac Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 11 Dec 2014 09:47:43 +0100 Subject: [PATCH 03/25] Swallow wheel events while a popup widget is open. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wheel events should not cause a popup widget parented on a scrollable widget to be closed or moved to correctly reflect the system behavior on OS X and Windows. Task-number: QTBUG-42731 Task-number: QTBUG-40656 Change-Id: I4ef75aa8331390309c251316ac76db2cf9ec51f7 Reviewed-by: Morten Johan Sørvig --- src/widgets/kernel/qapplication.cpp | 8 +++----- .../auto/widgets/widgets/qcombobox/tst_qcombobox.cpp | 11 +++++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index b7d0869289..abd0231b00 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3320,12 +3320,10 @@ bool QApplication::notify(QObject *receiver, QEvent *e) QWidget* w = static_cast(receiver); QWheelEvent* wheel = static_cast(e); - // QTBUG-40656, combo and other popups should close when the main window gets a wheel event. - while (QWidget *popup = QApplication::activePopupWidget()) { + // QTBUG-40656, QTBUG-42731: ignore wheel events when a popup (QComboBox) is open. + if (const QWidget *popup = QApplication::activePopupWidget()) { if (w->window() != popup) - popup->close(); - else - break; + return true; } QPoint relpos = wheel->pos(); diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index ac32ee4968..23d0ffd2d2 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -124,7 +124,7 @@ private slots: void pixmapIcon(); void mouseWheel_data(); void mouseWheel(); - void wheelClosingPopup(); + void popupWheelHandling(); void layoutDirection(); void itemListPosition(); void separatorItem_data(); @@ -2037,9 +2037,9 @@ void tst_QComboBox::mouseWheel() } } -void tst_QComboBox::wheelClosingPopup() +void tst_QComboBox::popupWheelHandling() { - // QTBUG-40656, combo and other popups should close when the main window gets a wheel event. + // QTBUG-40656, QTBUG-42731 combo and other popups should not be affected by wheel events. QScrollArea scrollArea; scrollArea.move(300, 300); QWidget *widget = new QWidget; @@ -2058,9 +2058,12 @@ void tst_QComboBox::wheelClosingPopup() QVERIFY(QTest::qWaitForWindowExposed(&scrollArea)); comboBox->showPopup(); QTRY_VERIFY(comboBox->view() && comboBox->view()->isVisible()); + const QPoint popupPos = comboBox->view()->pos(); QWheelEvent event(QPointF(10, 10), WHEEL_DELTA, Qt::NoButton, Qt::NoModifier); QVERIFY(QCoreApplication::sendEvent(scrollArea.windowHandle(), &event)); - QTRY_VERIFY(!comboBox->view()->isVisible()); + QCoreApplication::processEvents(); + QVERIFY(comboBox->view()->isVisible()); + QCOMPARE(comboBox->view()->pos(), popupPos); } void tst_QComboBox::layoutDirection() From ecd74bcc945b60ac0d21a28c5fd18528f1a19090 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Tue, 13 Jan 2015 09:00:44 +0100 Subject: [PATCH 04/25] Bump copyright year to 2015 Bump copyright year in tool output and user visible strings to 2015. Change-Id: I9b29907fe3f555e78005cb296a49d92f601fb7ec Reviewed-by: Lars Knoll Reviewed-by: Martin Smith --- LICENSE.LGPLv21 | 2 +- LICENSE.LGPLv3 | 2 +- doc/global/config.qdocconf | 2 +- doc/global/html-footer-online.qdocconf | 2 +- doc/global/html-footer.qdocconf | 2 +- doc/global/qt-module-defaults-online.qdocconf | 2 +- src/corelib/global/qlibraryinfo.cpp | 4 ++-- src/corelib/kernel/qtcore_eval.cpp | 6 +++--- src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp | 4 ++-- src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp | 4 ++-- src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc | 4 ++-- src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc | 4 ++-- src/tools/qlalr/cppgenerator.cpp | 4 ++-- src/widgets/dialogs/qmessagebox.cpp | 4 ++-- 14 files changed, 23 insertions(+), 23 deletions(-) diff --git a/LICENSE.LGPLv21 b/LICENSE.LGPLv21 index 341aa9eea3..d26836dccc 100644 --- a/LICENSE.LGPLv21 +++ b/LICENSE.LGPLv21 @@ -1,6 +1,6 @@ GNU LESSER GENERAL PUBLIC LICENSE - The Qt Toolkit is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). + The Qt Toolkit is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). Contact: http://www.qt-project.org/legal You may use, distribute and copy the Qt GUI Toolkit under the terms of diff --git a/LICENSE.LGPLv3 b/LICENSE.LGPLv3 index aed671a0c9..747fb695c0 100644 --- a/LICENSE.LGPLv3 +++ b/LICENSE.LGPLv3 @@ -1,6 +1,6 @@ GNU LESSER GENERAL PUBLIC LICENSE - The Qt Toolkit is Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). + The Qt Toolkit is Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). Contact: http://www.qt-project.org/legal You may use, distribute and copy the Qt GUI Toolkit under the terms of diff --git a/doc/global/config.qdocconf b/doc/global/config.qdocconf index a6ab546b75..51bd7b4f96 100644 --- a/doc/global/config.qdocconf +++ b/doc/global/config.qdocconf @@ -3,7 +3,7 @@ dita.metadata.default.author = Qt Project dita.metadata.default.permissions = all dita.metadata.default.publisher = Qt Project -dita.metadata.default.copyryear = 2014 +dita.metadata.default.copyryear = 2015 dita.metadata.default.copyrholder = Digia Plc dita.metadata.default.audience = programmer diff --git a/doc/global/html-footer-online.qdocconf b/doc/global/html-footer-online.qdocconf index 326900160c..d40e908f81 100644 --- a/doc/global/html-footer-online.qdocconf +++ b/doc/global/html-footer-online.qdocconf @@ -76,7 +76,7 @@ HTML.footer += \ "
\n" \ " \n" \ "
\n" \ "\n" \ diff --git a/doc/global/html-footer.qdocconf b/doc/global/html-footer.qdocconf index a77950ff99..217494575f 100644 --- a/doc/global/html-footer.qdocconf +++ b/doc/global/html-footer.qdocconf @@ -8,7 +8,7 @@ HTML.footer = \ "\n" \ "
\n" \ "

\n" \ - " © 2014 Digia Plc and/or its\n" \ + " © 2015 Digia Plc and/or its\n" \ " subsidiaries. Documentation contributions included herein are the copyrights of\n" \ " their respective owners.
" \ " The documentation provided herein is licensed under the terms of the" \ diff --git a/doc/global/qt-module-defaults-online.qdocconf b/doc/global/qt-module-defaults-online.qdocconf index fcff1976d1..6e6854ff82 100644 --- a/doc/global/qt-module-defaults-online.qdocconf +++ b/doc/global/qt-module-defaults-online.qdocconf @@ -5,7 +5,7 @@ HTML.footer = \ "

\n" \ "

\n" \ - " © 2014 Digia Plc and/or its\n" \ + " © 2015 Digia Plc and/or its\n" \ " subsidiaries. Documentation contributions included herein are the copyrights of\n" \ " their respective owners. " \ " The documentation provided herein is licensed under the terms of the" \ diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 7ca0aa7f0b..2698098be0 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2014 Intel Corporation ** Contact: http://www.qt-project.org/legal ** @@ -605,7 +605,7 @@ extern "C" void qt_core_boilerplate(); void qt_core_boilerplate() { printf("This is the QtCore library version " QT_BUILD_STR "\n" - "Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).\n" + "Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).\n" "Contact: http://www.qt-project.org/legal\n" "\n" "Build date: %s\n" diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp index eb1019534c..2ee8c20bc3 100644 --- a/src/corelib/kernel/qtcore_eval.cpp +++ b/src/corelib/kernel/qtcore_eval.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE static const char boilerplate_supported_but_time_limited[] = "\nQt %1 Evaluation License\n" - "Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).\n" + "Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).\n" "This trial version may only be used for evaluation purposes\n" "and will shut down after 120 minutes.\n" "Registered to:\n" @@ -57,7 +57,7 @@ static const char boilerplate_supported_but_time_limited[] = static const char boilerplate_supported[] = "\nQt %1 Evaluation License\n" - "Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).\n" + "Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).\n" "This trial version may only be used for evaluation purposes\n" "Registered to:\n" " Licensee: %2\n\n" diff --git a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp index dc735df297..8b13334ca0 100644 --- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp +++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the tools applications of the Qt Toolkit. @@ -67,7 +67,7 @@ static const char docTypeHeader[] = #define PROGRAMNAME "qdbuscpp2xml" #define PROGRAMVERSION "0.2" -#define PROGRAMCOPYRIGHT "Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies)." +#define PROGRAMCOPYRIGHT "Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies)." static QString outputFile; static int flags; diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp index a85dd44f65..5b8de7c2ab 100644 --- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp +++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the tools applications of the Qt Toolkit. @@ -49,7 +49,7 @@ #define PROGRAMNAME "qdbusxml2cpp" #define PROGRAMVERSION "0.8" -#define PROGRAMCOPYRIGHT "Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies)." +#define PROGRAMCOPYRIGHT "Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies)." #define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply" diff --git a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc index c04cdeca2b..7825fc3a91 100644 --- a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -3789,7 +3789,7 @@ Qt Development Frameworks Qt Project - + Qt Project diff --git a/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc b/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc index 093f9cc2c6..cf1f7b2426 100644 --- a/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc +++ b/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the documentation of the Qt Toolkit. @@ -1576,7 +1576,7 @@ dita.metadata.default.author = Qt Development Frameworks dita.metadata.default.permissions = all dita.metadata.default.publisher = Qt Project - dita.metadata.default.copyryear = 2014 + dita.metadata.default.copyryear = 2015 dita.metadata.default.copyrholder = Qt Project dita.metadata.default.audience = programmer \endcode diff --git a/src/tools/qlalr/cppgenerator.cpp b/src/tools/qlalr/cppgenerator.cpp index 05c3c94cc9..6ffe322217 100644 --- a/src/tools/qlalr/cppgenerator.cpp +++ b/src/tools/qlalr/cppgenerator.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QLALR module of the Qt Toolkit. @@ -47,7 +47,7 @@ QString CppGenerator::copyrightHeader() const return QLatin1String( "/****************************************************************************\n" "**\n" - "** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).\n" + "** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).\n" "** Contact: http://www.qt-project.org/legal\n" "**\n" "** This file is part of the Qt Toolkit.\n" diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index effcef2bc9..391c1d4fb9 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtWidgets module of the Qt Toolkit. @@ -1906,7 +1906,7 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title) "

Qt and the Qt logo are trademarks of Digia Plc and/or its subsidiary(-ies).

" "

Qt is a Digia product developed as an open source project. See %3 " "for more information.

" - ).arg(QStringLiteral("2014"), + ).arg(QStringLiteral("2015"), QStringLiteral("qt.io/licensing"), QStringLiteral("qt.io")); QMessageBox *msgBox = new QMessageBox(parent); From 0fa092cbae1593ca73577ecf9ec71283ae3f2498 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 8 Jan 2015 15:43:29 +0100 Subject: [PATCH 05/25] Windows: Add GPU detection. Compile qwindowsopengltester on all platforms and add struct GpuDescription with detection method based on IDirect3D9 (dynamically loaded). Expose as a QVariantMap-property to QWindowsNativeInterface to be able to access it from qtdiag. Task-number: QTBUG-43263 Change-Id: I3c6cd0bbbe36465e0e05f7064ecfc943d6ea4101 Reviewed-by: Laszlo Agocs --- .../windows/qwindowsnativeinterface.cpp | 8 +- .../windows/qwindowsnativeinterface.h | 5 +- .../windows/qwindowsopengltester.cpp | 142 +++++++++++++++++- .../platforms/windows/qwindowsopengltester.h | 58 ++++++- src/plugins/platforms/windows/windows.pri | 11 +- 5 files changed, 213 insertions(+), 11 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index 002f4ae92c..12ecc53f92 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -35,6 +35,7 @@ #include "qwindowswindow.h" #include "qwindowscontext.h" #include "qwindowsopenglcontext.h" +#include "qwindowsopengltester.h" #include "qwindowsintegration.h" #include "qwindowsmime.h" @@ -216,4 +217,9 @@ int QWindowsNativeInterface::registerMimeType(const QString &mimeType) return QWindowsMime::registerMimeType(mimeType); } +QVariant QWindowsNativeInterface::gpu() const +{ + return GpuDescription::detect().toVariant(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h index 3d47dbe721..349ed28b1d 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.h +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -58,6 +58,7 @@ class QWindowsNativeInterface : public QPlatformNativeInterface { Q_OBJECT Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose) + Q_PROPERTY(QVariant gpu READ gpu STORED false) public: void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; @@ -81,6 +82,8 @@ public: bool asyncExpose() const; void setAsyncExpose(bool value); + QVariant gpu() const; + QVariantMap windowProperties(QPlatformWindow *window) const Q_DECL_OVERRIDE; QVariant windowProperty(QPlatformWindow *window, const QString &name) const Q_DECL_OVERRIDE; QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index ba3a95ce7a..5ef3dc0855 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -32,13 +32,148 @@ ****************************************************************************/ #include "qwindowsopengltester.h" -#include "qt_windows.h" #include "qwindowscontext.h" +#include +#include +#include + +#ifndef Q_OS_WINCE +# include +# include +# include +#endif + QT_BEGIN_NAMESPACE +QString GpuDriverVersion::toString() const +{ + return QString::number(product) + + QLatin1Char('.') + QString::number(version) + + QLatin1Char('.') + QString::number(subVersion) + + QLatin1Char('.') + QString::number(build); +} + +int GpuDriverVersion::compare(const GpuDriverVersion &rhs) const +{ + if (product < rhs.product) + return -1; + if (product > rhs.product) + return 1; + if (version < rhs.version) + return -1; + if (version > rhs.version) + return 1; + if (subVersion < rhs.subVersion) + return -1; + if (subVersion > rhs.subVersion) + return 1; + if (build < rhs.build) + return -1; + if (build > rhs.build) + return 1; + return 0; +} + +GpuDescription GpuDescription::detect() +{ +#ifndef Q_OS_WINCE + typedef IDirect3D9 * (WINAPI *PtrDirect3DCreate9)(UINT); + + GpuDescription result; + QSystemLibrary d3d9lib(QStringLiteral("d3d9")); + if (!d3d9lib.load()) + return result; + PtrDirect3DCreate9 direct3DCreate9 = (PtrDirect3DCreate9)d3d9lib.resolve("Direct3DCreate9"); + if (!direct3DCreate9) + return result; + IDirect3D9 *direct3D9 = direct3DCreate9(D3D_SDK_VERSION); + if (!direct3D9) + return result; + D3DADAPTER_IDENTIFIER9 adapterIdentifier; + const HRESULT hr = direct3D9->GetAdapterIdentifier(0, 0, &adapterIdentifier); + direct3D9->Release(); + if (SUCCEEDED(hr)) { + result.vendorId = int(adapterIdentifier.VendorId); + result.deviceId = int(adapterIdentifier.DeviceId); + result.revision = int(adapterIdentifier.Revision); + result.subSysId = int(adapterIdentifier.SubSysId); + result.driverVersion.product = HIWORD(adapterIdentifier.DriverVersion.HighPart); + result.driverVersion.version = LOWORD(adapterIdentifier.DriverVersion.HighPart); + result.driverVersion.subVersion = HIWORD(adapterIdentifier.DriverVersion.LowPart); + result.driverVersion.build = LOWORD(adapterIdentifier.DriverVersion.LowPart); + result.driverName = adapterIdentifier.Driver; + result.description = adapterIdentifier.Description; + } + return result; +#else // !Q_OS_WINCE + GpuDescription result; + result.vendorId = result.deviceId = result.revision + = result.driverVersion.product = result.driverVersion.version + = result.driverVersion.build = 1; + result.driverName = result.description = QByteArrayLiteral("Generic"); + return result; +#endif +} + +QDebug operator<<(QDebug d, const GpuDriverVersion &v) +{ + QDebugStateSaver s(d); + d.nospace(); + d << v.product << '.' << v.version << '.' << v.subVersion << '.' << v.build; + return d; +} + +QDebug operator<<(QDebug d, const GpuDescription &gd) +{ + QDebugStateSaver s(d); + d.nospace(); + d << hex << showbase << "GpuDescription(vendorId=" << gd.vendorId + << ", deviceId=" << gd.deviceId << ", subSysId=" << gd.subSysId + << dec << noshowbase << ", revision=" << gd.revision + << ", driver: " << gd.driverName + << ", version=" << gd.driverVersion << ", " << gd.description << ')'; + return d; +} + +// Return printable string formatted like the output of the dxdiag tool. +QString GpuDescription::toString() const +{ + QString result; + QTextStream str(&result); + str << " Card name: " << description + << "\n Driver Name: " << driverName + << "\n Driver Version: " << driverVersion.toString() + << "\n Vendor ID: 0x" << qSetPadChar(QLatin1Char('0')) + << uppercasedigits << hex << qSetFieldWidth(4) << vendorId + << "\n Device ID: 0x" << qSetFieldWidth(4) << deviceId + << "\n SubSys ID: 0x" << qSetFieldWidth(8) << subSysId + << "\n Revision ID: 0x" << qSetFieldWidth(4) << revision + << dec; + return result; +} + +QVariant GpuDescription::toVariant() const +{ + QVariantMap result; + result.insert(QStringLiteral("vendorId"), QVariant(vendorId)); + result.insert(QStringLiteral("deviceId"), QVariant(deviceId)); + result.insert(QStringLiteral("subSysId"),QVariant(subSysId)); + result.insert(QStringLiteral("revision"), QVariant(revision)); + result.insert(QStringLiteral("driver"), QVariant(QLatin1String(driverName))); + result.insert(QStringLiteral("driverProduct"), QVariant(driverVersion.product)); + result.insert(QStringLiteral("driverVersion"), QVariant(driverVersion.version)); + result.insert(QStringLiteral("driverSubVersion"), QVariant(driverVersion.subVersion)); + result.insert(QStringLiteral("driverBuild"), QVariant(driverVersion.build)); + result.insert(QStringLiteral("driverVersionString"), driverVersion.toString()); + result.insert(QStringLiteral("description"), QVariant(QLatin1String(description))); + result.insert(QStringLiteral("printable"), QVariant(toString())); + return result; +} + bool QWindowsOpenGLTester::testDesktopGL() { +#ifndef Q_OS_WINCE HMODULE lib = 0; HWND wnd = 0; HDC dc = 0; @@ -133,6 +268,9 @@ cleanup: // No FreeLibrary. Some implementations, Mesa in particular, deadlock when trying to unload. return result; +#else // !Q_OS_WINCE + return false; +#endif } QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h index 40a8e9d3ac..98b707dcd2 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.h +++ b/src/plugins/platforms/windows/qwindowsopengltester.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -31,10 +31,64 @@ ** ****************************************************************************/ +#ifndef QWINDOWSOPENGLTESTER_H +#define QWINDOWSOPENGLTESTER_H + #include +#include + QT_BEGIN_NAMESPACE +class QDebug; +class QVariant; + +struct GpuDriverVersion // ### fixme: Use QVersionNumber in Qt 5.5? +{ + GpuDriverVersion(int p = 0, int v = 0, int sv =0, int b = 0) : product(p), version(v), subVersion(sv), build(b) {} + QString toString() const; + int compare(const GpuDriverVersion &rhs) const; + + int product; + int version; + int subVersion; + int build; +}; + +inline bool operator==(const GpuDriverVersion &v1, const GpuDriverVersion &v2) + { return !v1.compare(v2); } +inline bool operator!=(const GpuDriverVersion &v1, const GpuDriverVersion &v2) + { return v1.compare(v2); } +inline bool operator< (const GpuDriverVersion &v1, const GpuDriverVersion &v2) + { return v1.compare(v2) < 0; } +inline bool operator<=(const GpuDriverVersion &v1, const GpuDriverVersion &v2) + { return v1.compare(v2) <= 0; } +inline bool operator> (const GpuDriverVersion &v1, const GpuDriverVersion &v2) + { return v1.compare(v2) > 0; } +inline bool operator>=(const GpuDriverVersion &v1, const GpuDriverVersion &v2) + { return v1.compare(v2) >= 0; } + +QDebug operator<<(QDebug d, const GpuDriverVersion &gd); + +struct GpuDescription +{ + GpuDescription() : vendorId(0), deviceId(0), revision(0), subSysId(0) {} + + static GpuDescription detect(); + QString toString() const; + QVariant toVariant() const; + + int vendorId; + int deviceId; + int revision; + int subSysId; + GpuDriverVersion driverVersion; + QByteArray driverName; + QByteArray description; +}; + +QDebug operator<<(QDebug d, const GpuDescription &gd); + class QWindowsOpenGLTester { public: @@ -42,3 +96,5 @@ public: }; QT_END_NAMESPACE + +#endif // QWINDOWSOPENGLTESTER_H diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index 8e5f35d293..246598677f 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -40,7 +40,8 @@ SOURCES += \ $$PWD/qwindowsservices.cpp \ $$PWD/qwindowsnativeimage.cpp \ $$PWD/qwindowsnativeinterface.cpp \ - $$PWD/qwindowsscaling.cpp + $$PWD/qwindowsscaling.cpp \ + $$PWD/qwindowsopengltester.cpp HEADERS += \ $$PWD/qwindowswindow.h \ @@ -66,9 +67,8 @@ HEADERS += \ $$PWD/qplatformfunctions_wince.h \ $$PWD/qwindowsnativeimage.h \ $$PWD/qwindowsnativeinterface.h \ - $$PWD/qwindowsscaling.h - -!wince: HEADERS += $$PWD/qwindowsopengltester.h + $$PWD/qwindowsscaling.h \ + $$PWD/qwindowsopengltester.h INCLUDEPATH += $$PWD @@ -84,8 +84,7 @@ contains(QT_CONFIG, opengles2) { # Dynamic GL needs both WGL and EGL contains(QT_CONFIG,dynamicgl) { - SOURCES += $$PWD/qwindowseglcontext.cpp \ - $$PWD/qwindowsopengltester.cpp + SOURCES += $$PWD/qwindowseglcontext.cpp HEADERS += $$PWD/qwindowseglcontext.h } From 97a82f62c46c272fe3ef1cd9d5c2214b6a7626af Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 12 Jan 2015 15:59:36 +0100 Subject: [PATCH 06/25] Windows: Add infrastructure to be able to a GL renderer based on GPU. Introduce flags for the renderer type and move code to qwindowsopengltester. Introduce QWindowsOpenGLTester::supportedGlesRenderers() where type-dependent checking can be added. Change-Id: I4bbffaf861cb0fdbea0919e081e3626fb5a872de Task-number: QTBUG-43263 Reviewed-by: Laszlo Agocs --- .../platforms/windows/qwindowseglcontext.cpp | 19 ++-- .../platforms/windows/qwindowseglcontext.h | 3 +- .../platforms/windows/qwindowsintegration.cpp | 88 +++++++++++-------- .../platforms/windows/qwindowsopenglcontext.h | 3 + .../windows/qwindowsopengltester.cpp | 82 +++++++++++++++++ .../platforms/windows/qwindowsopengltester.h | 21 +++++ 6 files changed, 168 insertions(+), 48 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index c0d0c1f77c..bde0503ee0 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -340,7 +340,7 @@ QWindowsEGLStaticContext::QWindowsEGLStaticContext(EGLDisplay display, int versi { } -QWindowsEGLStaticContext *QWindowsEGLStaticContext::create() +QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester::Renderers preferredType) { const HDC dc = QWindowsContext::instance()->displayContext(); if (!dc){ @@ -359,27 +359,26 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create() EGLDisplay display = EGL_NO_DISPLAY; #ifdef EGL_ANGLE_platform_angle_opengl - if (libEGL.eglGetPlatformDisplayEXT && qEnvironmentVariableIsSet("QT_ANGLE_PLATFORM")) { + if (libEGL.eglGetPlatformDisplayEXT + && (preferredType & QWindowsOpenGLTester::AngleBackendMask)) { const EGLint anglePlatformAttributes[][5] = { { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_NONE }, { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_NONE }, { EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_USE_WARP_ANGLE, EGL_TRUE, EGL_NONE } }; const EGLint *attributes = 0; - const QByteArray anglePlatform = qgetenv("QT_ANGLE_PLATFORM"); - if (anglePlatform == "d3d11") + if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11) attributes = anglePlatformAttributes[0]; - else if (anglePlatform == "d3d9") + else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d9) attributes = anglePlatformAttributes[1]; - else if (anglePlatform == "warp") + else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11Warp) attributes = anglePlatformAttributes[2]; - else - qCWarning(lcQpaGl) << "Invalid value set for QT_ANGLE_PLATFORM:" << anglePlatform; - if (attributes) display = libEGL.eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, attributes); } -#endif // EGL_ANGLE_platform_angle_opengl +#else // EGL_ANGLE_platform_angle_opengl + Q_UNUSED(preferredType) +#endif if (display == EGL_NO_DISPLAY) display = libEGL.eglGetDisplay((EGLNativeDisplayType)dc); if (!display) { diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 63a7c25a6f..45ccbfb734 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -35,6 +35,7 @@ #define QWINDOWSEGLCONTEXT_H #include "qwindowsopenglcontext.h" +#include "qwindowsopengltester.h" #include QT_BEGIN_NAMESPACE @@ -249,7 +250,7 @@ class QWindowsEGLStaticContext : public QWindowsStaticOpenGLContext Q_DISABLE_COPY(QWindowsEGLStaticContext) public: - static QWindowsEGLStaticContext *create(); + static QWindowsEGLStaticContext *create(QWindowsOpenGLTester::Renderers preferredType); ~QWindowsEGLStaticContext(); EGLDisplay display() const { return m_display; } diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 54fb138d85..82686f38ad 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -328,47 +328,61 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons } #ifndef QT_NO_OPENGL + +QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate() +{ +#if defined(QT_OPENGL_DYNAMIC) + QWindowsOpenGLTester::Renderer requestedRenderer = QWindowsOpenGLTester::requestedRenderer(); + switch (requestedRenderer) { + case QWindowsOpenGLTester::DesktopGl: + if (QWindowsStaticOpenGLContext *glCtx = QOpenGLStaticContext::create()) + return glCtx; + qCWarning(lcQpaGl, "System OpenGL failed. Falling back to Software OpenGL."); + return QOpenGLStaticContext::create(true); + // If ANGLE is requested, use it, don't try anything else. + case QWindowsOpenGLTester::AngleRendererD3d9: + case QWindowsOpenGLTester::AngleRendererD3d11: + case QWindowsOpenGLTester::AngleRendererD3d11Warp: + return QWindowsEGLStaticContext::create(requestedRenderer); + case QWindowsOpenGLTester::Gles: + return QWindowsEGLStaticContext::create(QWindowsOpenGLTester::supportedGlesRenderers()); + case QWindowsOpenGLTester::SoftwareRasterizer: + if (QWindowsStaticOpenGLContext *swCtx = QOpenGLStaticContext::create(true)) + return swCtx; + qCWarning(lcQpaGl, "Software OpenGL failed. Falling back to system OpenGL."); + if (QWindowsOpenGLTester::supportedRenderers() & QWindowsOpenGLTester::DesktopGl) + return QOpenGLStaticContext::create(); + return Q_NULLPTR; + default: + break; + } + + const QWindowsOpenGLTester::Renderers supportedRenderers = QWindowsOpenGLTester::supportedRenderers(); + if (supportedRenderers & QWindowsOpenGLTester::DesktopGl) { + if (QWindowsStaticOpenGLContext *glCtx = QOpenGLStaticContext::create()) + return glCtx; + } + if (QWindowsOpenGLTester::Renderers glesRenderers = supportedRenderers & QWindowsOpenGLTester::GlesMask) { + if (QWindowsEGLStaticContext *eglCtx = QWindowsEGLStaticContext::create(glesRenderers)) + return eglCtx; + } + return QOpenGLStaticContext::create(true); +#elif defined(QT_OPENGL_ES_2) + QWindowsOpenGLTester::Renderers glesRenderers = QWindowsOpenGLTester::requestedGlesRenderer(); + if (glesRenderers == QWindowsOpenGLTester::InvalidRenderer) + glesRenderers = QWindowsOpenGLTester::supportedGlesRenderers(); + return QWindowsEGLStaticContext::create(glesRenderers); +#elif !defined(QT_NO_OPENGL) + return QOpenGLStaticContext::create(); +#endif +} + static QWindowsStaticOpenGLContext *q_staticOpenGLContext = 0; QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::create() { - QWindowsStaticOpenGLContext *ctx = 0; - -#if defined(QT_OPENGL_DYNAMIC) - const QByteArray requested = qgetenv("QT_OPENGL"); // angle, desktop, software - const bool angleRequested = QCoreApplication::testAttribute(Qt::AA_UseOpenGLES) || requested == "angle"; - const bool desktopRequested = QCoreApplication::testAttribute(Qt::AA_UseDesktopOpenGL) || requested == "desktop"; - const bool softwareRequested = QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL) || requested == "software"; - - // If ANGLE is requested, use it, don't try anything else. - if (angleRequested) { - ctx = QWindowsEGLStaticContext::create(); - } else { - // If opengl32.dll seems to be OpenGL 2.x capable, or desktop OpenGL is requested, use it. - if (!softwareRequested && (desktopRequested || QWindowsOpenGLTester::testDesktopGL())) - ctx = QOpenGLStaticContext::create(); - // If failed and desktop OpenGL is not explicitly requested, try ANGLE. - if (!ctx && !desktopRequested && !softwareRequested) - ctx = QWindowsEGLStaticContext::create(); - // Try software. - if (!ctx) { - ctx = QOpenGLStaticContext::create(true); - // If software was explicitly requested but failed, try the regular one. - if (!ctx && softwareRequested && QWindowsOpenGLTester::testDesktopGL()) { - qCWarning(lcQpaGl, "Software OpenGL failed. Falling back to system OpenGL."); - ctx = QOpenGLStaticContext::create(); - } - } - } -#elif defined(QT_OPENGL_ES_2) - ctx = QWindowsEGLStaticContext::create(); -#elif !defined(QT_NO_OPENGL) - ctx = QOpenGLStaticContext::create(); -#endif - - q_staticOpenGLContext = ctx; - - return ctx; + q_staticOpenGLContext = QWindowsStaticOpenGLContext::doCreate(); + return q_staticOpenGLContext; } bool QWindowsIntegrationPrivate::ensureStaticOpenGLContext() diff --git a/src/plugins/platforms/windows/qwindowsopenglcontext.h b/src/plugins/platforms/windows/qwindowsopenglcontext.h index 2f724f3dd7..550bf00a40 100644 --- a/src/plugins/platforms/windows/qwindowsopenglcontext.h +++ b/src/plugins/platforms/windows/qwindowsopenglcontext.h @@ -58,6 +58,9 @@ public: // reimplement these. virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/) { return 0; } virtual void destroyWindowSurface(void * /*nativeSurface*/) { } + +private: + static QWindowsStaticOpenGLContext *doCreate(); }; class QWindowsOpenGLContext : public QPlatformOpenGLContext diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index 5ef3dc0855..ac886b6bee 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #ifndef Q_OS_WINCE # include @@ -171,6 +172,87 @@ QVariant GpuDescription::toVariant() const return result; } +QWindowsOpenGLTester::Renderer QWindowsOpenGLTester::requestedGlesRenderer() +{ +#ifndef Q_OS_WINCE + const char platformVar[] = "QT_ANGLE_PLATFORM"; + if (qEnvironmentVariableIsSet(platformVar)) { + const QByteArray anglePlatform = qgetenv(platformVar); + if (anglePlatform == "d3d11") + return QWindowsOpenGLTester::AngleRendererD3d11; + if (anglePlatform == "d3d9") + return QWindowsOpenGLTester::AngleRendererD3d9; + if (anglePlatform == "warp") + return QWindowsOpenGLTester::AngleRendererD3d11Warp; + qCWarning(lcQpaGl) << "Invalid value set for " << platformVar << ": " << anglePlatform; + } +#endif // !Q_OS_WINCE + return QWindowsOpenGLTester::InvalidRenderer; +} + +QWindowsOpenGLTester::Renderer QWindowsOpenGLTester::requestedRenderer() +{ +#ifndef Q_OS_WINCE + const char openGlVar[] = "QT_OPENGL"; + if (QCoreApplication::testAttribute(Qt::AA_UseOpenGLES)) { + const Renderer glesRenderer = QWindowsOpenGLTester::requestedGlesRenderer(); + return glesRenderer != InvalidRenderer ? glesRenderer : Gles; + } + if (QCoreApplication::testAttribute(Qt::AA_UseDesktopOpenGL)) + return QWindowsOpenGLTester::DesktopGl; + if (QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL)) + return QWindowsOpenGLTester::SoftwareRasterizer; + if (qEnvironmentVariableIsSet(openGlVar)) { + const QByteArray requested = qgetenv(openGlVar); + if (requested == "angle") { + const Renderer glesRenderer = QWindowsOpenGLTester::requestedGlesRenderer(); + return glesRenderer != InvalidRenderer ? glesRenderer : Gles; + } + if (requested == "desktop") + return QWindowsOpenGLTester::DesktopGl; + if (requested == "software") + return QWindowsOpenGLTester::SoftwareRasterizer; + qCWarning(lcQpaGl) << "Invalid value set for " << openGlVar << ": " << requested; + } +#endif // !Q_OS_WINCE + return QWindowsOpenGLTester::InvalidRenderer; +} + +static inline QWindowsOpenGLTester::Renderers + detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly) +{ + Q_UNUSED(gpu) +#ifndef Q_OS_WINCE + // Add checks for card types with known issues here. + QWindowsOpenGLTester::Renderers result(QWindowsOpenGLTester::AngleRendererD3d11 + | QWindowsOpenGLTester::AngleRendererD3d9 + | QWindowsOpenGLTester::AngleRendererD3d11Warp + | QWindowsOpenGLTester::SoftwareRasterizer); + + if (!glesOnly && QWindowsOpenGLTester::testDesktopGL()) + result |= QWindowsOpenGLTester::DesktopGl; + return result; +#else // !Q_OS_WINCE + return QWindowsOpenGLTester::Gles; +#endif +} + +QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::supportedGlesRenderers() +{ + const GpuDescription gpu = GpuDescription::detect(); + const QWindowsOpenGLTester::Renderers result = detectSupportedRenderers(gpu, true); + qDebug(lcQpaGl) << __FUNCTION__ << gpu << "renderer: " << result; + return result; +} + +QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::supportedRenderers() +{ + const GpuDescription gpu = GpuDescription::detect(); + const QWindowsOpenGLTester::Renderers result = detectSupportedRenderers(gpu, false); + qDebug(lcQpaGl) << __FUNCTION__ << gpu << "renderer: " << result; + return result; +} + bool QWindowsOpenGLTester::testDesktopGL() { #ifndef Q_OS_WINCE diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h index 98b707dcd2..6238eea4b0 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.h +++ b/src/plugins/platforms/windows/qwindowsopengltester.h @@ -37,6 +37,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -92,9 +93,29 @@ QDebug operator<<(QDebug d, const GpuDescription &gd); class QWindowsOpenGLTester { public: + enum Renderer { + InvalidRenderer = 0x0000, + DesktopGl = 0x0001, + AngleRendererD3d11 = 0x0002, + AngleRendererD3d9 = 0x0004, + AngleRendererD3d11Warp = 0x0008, // "Windows Advanced Rasterization Platform" + AngleBackendMask = AngleRendererD3d11 | AngleRendererD3d9 | AngleRendererD3d11Warp, + Gles = 0x0010, // ANGLE/unspecified or Generic GLES for Windows CE. + GlesMask = Gles | AngleBackendMask, + SoftwareRasterizer = 0x0020 + }; + Q_DECLARE_FLAGS(Renderers, Renderer) + + static Renderer requestedGlesRenderer(); + static Renderer requestedRenderer(); + static Renderers supportedGlesRenderers(); + static Renderers supportedRenderers(); + static bool testDesktopGL(); }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QWindowsOpenGLTester::Renderers) + QT_END_NAMESPACE #endif // QWINDOWSOPENGLTESTER_H From 9b35c2cc27741e335a231afd7bc7842602ddc8a2 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 14 Jan 2015 12:29:24 +0100 Subject: [PATCH 07/25] Windows: Fix crash when focus window does not have a native window. Check and warn in that case. Change-Id: Ic513334b5aa48e1c7e44685c30da3e9be52c3c52 Task-number: QTBUG-43833 Reviewed-by: Laszlo Agocs --- src/plugins/platforms/windows/qwindowsinputcontext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 94a27d146f..ad63a57d3e 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -209,7 +209,7 @@ void QWindowsInputContext::setFocusObject(QObject *object) imeNotifyCancelComposition(m_compositionContext.hwnd); const QWindow *window = QGuiApplication::focusWindow(); - if (object && window) { + if (object && window && window->handle()) { QWindowsWindow *platformWindow = QWindowsWindow::baseWindowOf(window); if (inputMethodAccepted()) { // Re-enable IME by associating default context saved on first disabling. From 5856f6e3057a881747d77e87f8934dd67860bed6 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 13 Jan 2015 12:49:40 +0100 Subject: [PATCH 08/25] Fix regression with frameless dialogs on Windows Task-number: QTBUG-41162 Change-Id: I6d4e6d0e8a262fead30d642d632f6b4021cc20ab Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowswindow.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 6279b6f4af..b8ad744d05 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -514,8 +514,12 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag if (flags & Qt::WindowSystemMenuHint) style |= WS_SYSMENU; else if (dialog) { - style |= WS_SYSMENU | WS_BORDER; // QTBUG-2027, dialogs without system menu. - exStyle |= WS_EX_DLGMODALFRAME; + // QTBUG-2027, dialogs without system menu. + style |= WS_SYSMENU; + if (!(flags & Qt::FramelessWindowHint)) { + style |= WS_BORDER; + exStyle |= WS_EX_DLGMODALFRAME; + } } if (flags & Qt::WindowMinimizeButtonHint) style |= WS_MINIMIZEBOX; From 6839aead0430a9b07b60fa3a1a7d685fe5d2d1ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Klitzing?= Date: Fri, 9 Jan 2015 11:53:17 +0100 Subject: [PATCH 09/25] Fix compile error if openssl is built with no-ssl3-method Since openssl 1.0.1k with enabled option no-ssl3-method we need to check for OPENSSL_NO_SSL3_METHOD to use following functions: - SSLv3_method - SSLv3_server_method - SSLv3_client_method Change-Id: Iee83a6f4bacbf5660baa6bdb89eb02ceb9f11614 Reviewed-by: Thiago Macieira --- src/network/ssl/qsslcontext_openssl.cpp | 6 ++++++ src/network/ssl/qsslsocket_openssl_symbols.cpp | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index 92e726bc01..18eef2fc60 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -138,7 +138,13 @@ init_context: #endif break; case QSsl::SslV3: +#ifndef OPENSSL_NO_SSL3_METHOD sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_method()); +#else + // SSL 3 not supported by the system, but chosen deliberately -> error + sslContext->ctx = 0; + unsupportedProtocol = true; +#endif break; case QSsl::SecureProtocols: // SSLv2 and SSLv3 will be disabled by SSL options diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index ea6e84adef..c1fea930d0 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -270,7 +270,9 @@ DEFINEFUNC(SSL_SESSION*, SSL_get_session, const SSL *ssl, ssl, return 0, return) #ifndef OPENSSL_NO_SSL2 DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return) #endif +#ifndef OPENSSL_NO_SSL3_METHOD DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return) +#endif DEFINEFUNC(const SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return) #if OPENSSL_VERSION_NUMBER >= 0x10001000L @@ -280,7 +282,9 @@ DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return #ifndef OPENSSL_NO_SSL2 DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return) #endif +#ifndef OPENSSL_NO_SSL3_METHOD DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return) +#endif DEFINEFUNC(const SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return) #if OPENSSL_VERSION_NUMBER >= 0x10001000L @@ -289,11 +293,15 @@ DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return #endif #else DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return) +#ifndef OPENSSL_NO_SSL3_METHOD DEFINEFUNC(SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return) +#endif DEFINEFUNC(SSL_METHOD *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return) +#ifndef OPENSSL_NO_SSL3_METHOD DEFINEFUNC(SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return) +#endif DEFINEFUNC(SSL_METHOD *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return) #endif @@ -799,7 +807,9 @@ bool q_resolveOpenSslSymbols() #ifndef OPENSSL_NO_SSL2 RESOLVEFUNC(SSLv2_client_method) #endif +#ifndef OPENSSL_NO_SSL3_METHOD RESOLVEFUNC(SSLv3_client_method) +#endif RESOLVEFUNC(SSLv23_client_method) RESOLVEFUNC(TLSv1_client_method) #if OPENSSL_VERSION_NUMBER >= 0x10001000L @@ -809,7 +819,9 @@ bool q_resolveOpenSslSymbols() #ifndef OPENSSL_NO_SSL2 RESOLVEFUNC(SSLv2_server_method) #endif +#ifndef OPENSSL_NO_SSL3_METHOD RESOLVEFUNC(SSLv3_server_method) +#endif RESOLVEFUNC(SSLv23_server_method) RESOLVEFUNC(TLSv1_server_method) #if OPENSSL_VERSION_NUMBER >= 0x10001000L From 5bb2e84a764f611cf4470f2ddc0bb427c4d110cc Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Fri, 16 Jan 2015 10:18:00 +0100 Subject: [PATCH 10/25] Fall back to ANGLE on OpenGL 1.x Apparently on some cards, that only provide OpenGL 1.4, the check for OpenGL 2 specific functions is not sufficient (presumably some old extensions provide the functions and so the test passes, even though it really shouldn't) To avoid crashing the apps later on, we should check the context version and activate the fall back to ANGLE if it's below 2.0. Task-number: QTBUG-43870 Change-Id: Id0e3d8ad1f632334ba03bbb1a4802413f28436dc Reviewed-by: Friedemann Kleint --- .../windows/qwindowsopengltester.cpp | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index ac886b6bee..f6caf8b06e 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -43,6 +43,7 @@ # include # include # include +# include #endif QT_BEGIN_NAMESPACE @@ -326,6 +327,37 @@ bool QWindowsOpenGLTester::testDesktopGL() goto cleanup; // Now that there is finally a context current, try doing something useful. + + // Check the version. If we got 1.x then it's all hopeless and we can stop right here. + typedef const GLubyte * (APIENTRY * GetString_t)(GLenum name); + GetString_t GetString = reinterpret_cast(::GetProcAddress(lib, "glGetString")); + if (GetString) { + const char *versionStr = (const char *) GetString(GL_VERSION); + if (versionStr) { + const QByteArray version(versionStr); + const int majorDot = version.indexOf('.'); + if (majorDot != -1) { + int minorDot = version.indexOf('.', majorDot + 1); + if (minorDot == -1) + minorDot = version.size(); + const int major = version.mid(0, majorDot).toInt(); + const int minor = version.mid(majorDot + 1, minorDot - majorDot - 1).toInt(); + qCDebug(lcQpaGl, "Basic wglCreateContext gives version %d.%d", major, minor); + // Try to be as lenient as possible. Missing version, bogus values and + // such are all accepted. The driver may still be functional. Only + // check for known-bad cases, like versions "1.4.0 ...". + if (major == 1) { + result = false; + qCDebug(lcQpaGl, "OpenGL version too low"); + } + } + } + } else { + result = false; + qCDebug(lcQpaGl, "OpenGL 1.x entry points not found"); + } + + // Check for a shader-specific function. if (WGL_GetProcAddress("glCreateShader")) { result = true; qCDebug(lcQpaGl, "OpenGL 2.0 entry points available"); From 3c21c4581dbd957d9f660dd52d0298ecef1001cb Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Wed, 7 Jan 2015 13:51:38 +0100 Subject: [PATCH 11/25] Fix drag and drop regression Fix regression introduced by e4becdc3d310a0dd1a6d34d0796a52b21dedeb2d Add QPlatformDrag::ownsDragObject() function, QDragManager can use the return value of this function to decide if it should take care of deleting QDrag object or platform plugin will take care of deleting QDrag. XCB platform plugins uses async dnd data delivery mechanism. It allows user to drop something and then continue working with the assurance that the target will get the data regardless of how slow the network connections are, which means that a source window should preserve QDrag data until dnd has finished. Change-Id: I1fbad7380cddec98b756698993dd397409833150 Task-number: QTBUG-43436 Reviewed-by: Friedemann Kleint --- src/gui/kernel/qdnd.cpp | 3 ++- src/gui/kernel/qplatformdrag.cpp | 12 ++++++++++++ src/gui/kernel/qplatformdrag.h | 2 ++ src/plugins/platforms/xcb/qxcbdrag.cpp | 7 +++++++ src/plugins/platforms/xcb/qxcbdrag.h | 12 ++++++------ 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/gui/kernel/qdnd.cpp b/src/gui/kernel/qdnd.cpp index f515fe18df..2a6cc4fc99 100644 --- a/src/gui/kernel/qdnd.cpp +++ b/src/gui/kernel/qdnd.cpp @@ -134,7 +134,8 @@ Qt::DropAction QDragManager::drag(QDrag *o) QGuiApplicationPrivate::instance()->notifyDragStarted(o); const Qt::DropAction result = m_platformDrag->drag(m_object); m_object = 0; - o->deleteLater(); + if (!m_platformDrag->ownsDragObject()) + o->deleteLater(); return result; } diff --git a/src/gui/kernel/qplatformdrag.cpp b/src/gui/kernel/qplatformdrag.cpp index 8a5c7264d1..326f092ead 100644 --- a/src/gui/kernel/qplatformdrag.cpp +++ b/src/gui/kernel/qplatformdrag.cpp @@ -241,6 +241,18 @@ QPixmap QPlatformDrag::defaultPixmap() return *qt_drag_default_pixmap(); } +/*! + \since 5.4 + \brief Returns bool indicating whether QPlatformDrag takes ownership + and therefore responsibility of deleting the QDrag object passed in + from QPlatformDrag::drag. This can be useful on platforms where QDrag + object has to be kept around. + */ +bool QPlatformDrag::ownsDragObject() const +{ + return false; +} + #endif // QT_NO_DRAGANDDROP QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformdrag.h b/src/gui/kernel/qplatformdrag.h index 34ad11e45f..ce7a9aa1f2 100644 --- a/src/gui/kernel/qplatformdrag.h +++ b/src/gui/kernel/qplatformdrag.h @@ -98,6 +98,8 @@ public: static QPixmap defaultPixmap(); + virtual bool ownsDragObject() const; + private: QPlatformDragPrivate *d_ptr; diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index 7037e102e2..ec0399ed5f 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -999,6 +999,8 @@ void QXcbDrag::handleFinished(const xcb_client_message_event_t *event) if (at != -1) { Transaction t = transactions.takeAt(at); + if (t.drag) + t.drag->deleteLater(); // QDragManager *manager = QDragManager::self(); // Window target = current_target; @@ -1186,6 +1188,11 @@ bool QXcbDrag::dndEnable(QXcbWindow *w, bool on) } } +bool QXcbDrag::ownsDragObject() const +{ + return true; +} + QXcbDropData::QXcbDropData(QXcbDrag *d) : QXcbMime(), drag(d) diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h index e273492837..63a344a098 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.h +++ b/src/plugins/platforms/xcb/qxcbdrag.h @@ -70,12 +70,11 @@ public: virtual QMimeData *platformDropData(); - - void startDrag(); - void cancel(); - void move(const QMouseEvent *me); - void drop(const QMouseEvent *me); - void endDrag(); + void startDrag() Q_DECL_OVERRIDE; + void cancel() Q_DECL_OVERRIDE; + void move(const QMouseEvent *me) Q_DECL_OVERRIDE; + void drop(const QMouseEvent *me) Q_DECL_OVERRIDE; + void endDrag() Q_DECL_OVERRIDE; void handleEnter(QWindow *window, const xcb_client_message_event_t *event); void handlePosition(QWindow *w, const xcb_client_message_event_t *event); @@ -87,6 +86,7 @@ public: void handleFinished(const xcb_client_message_event_t *event); bool dndEnable(QXcbWindow *win, bool on); + bool ownsDragObject() const Q_DECL_OVERRIDE; void updatePixmap(); xcb_timestamp_t targetTime() { return target_time; } From 128cab4635c3ea42af5d3b9952f7b7e1d89284e7 Mon Sep 17 00:00:00 2001 From: Michael Marley Date: Mon, 12 Jan 2015 21:59:43 -0500 Subject: [PATCH 12/25] Set pendingClose to false on init in QSslSocket Fixes an issue where under certain circumstances, QSslSocket could get stuck in a state where it would disconnect immediately after starting encryption. Since it doesn't make any sense for the socket to be initialized to a state where any connection attempt will fail, the pendingClose value should be set to false. Thanks to Martin Sandsmark for his help debugging this issue. Task-number: QTBUG-43793 Change-Id: I7deebacbac588c21439a8e594db4222095cf3f22 Reviewed-by: Richard J. Moore --- src/network/ssl/qsslsocket.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 31c7b3087e..0f7c376e04 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1982,6 +1982,7 @@ void QSslSocketPrivate::init() connectionEncrypted = false; ignoreAllSslErrors = false; shutdown = false; + pendingClose = false; // we don't want to clear the ignoreErrorsList, so // that it is possible setting it before connecting From 49fd3511f5bcdd61c92894636fcf0b2be23d1264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 13 Jan 2015 10:52:39 +0100 Subject: [PATCH 13/25] Fix memory leak in Qurl::toCFURL() Release the temp CFString. Change-Id: I8a5b8f18a42a4a9b2c6671f0f5b32a3f0b14238d Task-number: QTBUG-43710 Reviewed-by: Thiago Macieira --- src/corelib/io/qurl_mac.mm | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qurl_mac.mm b/src/corelib/io/qurl_mac.mm index c235365ad8..4468bf0f2b 100644 --- a/src/corelib/io/qurl_mac.mm +++ b/src/corelib/io/qurl_mac.mm @@ -54,7 +54,13 @@ QUrl QUrl::fromCFURL(CFURLRef url) CFURLRef QUrl::toCFURL() const { - return CFURLCreateWithString(0, toString(FullyEncoded).toCFString(), 0); + CFURLRef url = 0; + CFStringRef str = toString(FullyEncoded).toCFString(); + if (str) { + url = CFURLCreateWithString(0, str, 0); + CFRelease(str); + } + return url; } QUrl QUrl::fromNSURL(const NSURL *url) From cd389e4584754554282fbcb1cdc1b174d0f211dc Mon Sep 17 00:00:00 2001 From: Liang Qi Date: Wed, 7 Jan 2015 12:50:14 +0100 Subject: [PATCH 14/25] Fix possible divide by zero in QMacStyle [ChangeLog][Widgets][QMacStyle] Fixed a possible divide by zero crash. Task-number: QTBUG-43398 Change-Id: I8b5c6fd87d07eb42ad43e8c2405b7cad19372b86 Reviewed-by: Gabriel de Dietrich --- src/widgets/styles/qmacstyle_mac.mm | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index c166b1b26e..38c082baf5 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1675,13 +1675,14 @@ void QMacStylePrivate::getSliderInfo(QStyle::ComplexControl cc, const QStyleOpti else tdi->max = 10 * slider->rect.height(); - if (usePlainKnob || slider->orientation == Qt::Horizontal) { + int range = slider->maximum - slider->minimum; + if (range == 0) { + tdi->value = 0; + } else if (usePlainKnob || slider->orientation == Qt::Horizontal) { int endsCorrection = usePlainKnob ? 25 : 10; - tdi->value = (tdi->max + 2 * endsCorrection) * (slider->sliderPosition - slider->minimum) - / (slider->maximum - slider->minimum) - endsCorrection; + tdi->value = (tdi->max + 2 * endsCorrection) * (slider->sliderPosition - slider->minimum) / range - endsCorrection; } else { - tdi->value = (tdi->max + 30) * (slider->sliderPosition - slider->minimum) - / (slider->maximum - slider->minimum) - 20; + tdi->value = (tdi->max + 30) * (slider->sliderPosition - slider->minimum) / range - 20; } } tdi->attributes = kThemeTrackShowThumb; From 5ee8ed27e05f17dc7911a5917c012d0a4fa5afcb Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Fri, 16 Jan 2015 18:32:41 +0100 Subject: [PATCH 15/25] rcc: fix build failure on Windows XP / MinGW 4.9 The code makes usage of _fileno without including the appropriate header, which is stdio.h according to Microsoft: http://msdn.microsoft.com/en-us/library/zs6wbdhx%28v=vs.120%29.aspx Task-number: QTBUG-43900 Change-Id: Ic9d407c66243d64823353a1c7e79cf0825c735db Reviewed-by: Friedemann Kleint Reviewed-by: Kai Koehne --- src/tools/rcc/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp index 3c556d76a8..c2e9b26fb3 100644 --- a/src/tools/rcc/main.cpp +++ b/src/tools/rcc/main.cpp @@ -47,6 +47,7 @@ #ifdef Q_OS_WIN # include # include +# include #endif // Q_OS_WIN QT_BEGIN_NAMESPACE From a8f37e47751d7d29ab63bef55f5849056f826e8b Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 15 Jan 2015 17:04:29 +0100 Subject: [PATCH 16/25] Windows: Delay creation of the static OpenGL context. Delay initialization/GL detection until a surface is requested. Remove member variable from window and access static context from QWindowsIntegration only. Task-number: QTBUG-43832 Change-Id: I4b9a324b58af4399df5c314bfb2b952455b1e080 Reviewed-by: Laszlo Agocs --- .../platforms/windows/qwindowsintegration.cpp | 35 +++++++------------ .../platforms/windows/qwindowswindow.cpp | 10 ++++-- .../platforms/windows/qwindowswindow.h | 3 -- 3 files changed, 20 insertions(+), 28 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 82686f38ad..58d675876b 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -130,7 +130,6 @@ struct QWindowsIntegrationPrivate { explicit QWindowsIntegrationPrivate(const QStringList ¶mList); ~QWindowsIntegrationPrivate(); - bool ensureStaticOpenGLContext(); unsigned m_options; QWindowsContext m_context; @@ -266,7 +265,9 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co case OpenGL: return true; case ThreadedOpenGL: - return d->ensureStaticOpenGLContext() ? d->m_staticOpenGLContext->supportsThreadedOpenGL() : false; + if (const QWindowsStaticOpenGLContext *glContext = QWindowsIntegration::staticOpenGLContext()) + return glContext->supportsThreadedOpenGL(); + return false; #endif // !QT_NO_OPENGL case WindowMasks: return true; @@ -312,11 +313,6 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const QWindowSystemInterface::handleGeometryChange(window, QWindowsScaling::mapFromNative(obtained.geometry)); } -#ifndef QT_NO_OPENGL - d->ensureStaticOpenGLContext(); - obtained.staticOpenGLContext = d->m_staticOpenGLContext; -#endif // QT_NO_OPENGL - return obtained; } @@ -377,26 +373,16 @@ QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate() #endif } -static QWindowsStaticOpenGLContext *q_staticOpenGLContext = 0; - QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::create() { - q_staticOpenGLContext = QWindowsStaticOpenGLContext::doCreate(); - return q_staticOpenGLContext; -} - -bool QWindowsIntegrationPrivate::ensureStaticOpenGLContext() -{ - if (m_staticOpenGLContext.isNull()) - m_staticOpenGLContext = QSharedPointer(QWindowsStaticOpenGLContext::create()); - return !m_staticOpenGLContext.isNull(); + return QWindowsStaticOpenGLContext::doCreate(); } QPlatformOpenGLContext *QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { qCDebug(lcQpaGl) << __FUNCTION__ << context->format(); - if (d->ensureStaticOpenGLContext()) { - QScopedPointer result(d->m_staticOpenGLContext->createContext(context)); + if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext()) { + QScopedPointer result(staticOpenGLContext->createContext(context)); if (result->isValid()) return result.take(); } @@ -410,13 +396,18 @@ QOpenGLContext::OpenGLModuleType QWindowsIntegration::openGLModuleType() #elif !defined(QT_OPENGL_DYNAMIC) return QOpenGLContext::LibGL; #else - return d->ensureStaticOpenGLContext() ? d->m_staticOpenGLContext->moduleType() : QOpenGLContext::LibGL; + if (const QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext()) + return staticOpenGLContext->moduleType(); + return QOpenGLContext::LibGL; #endif } QWindowsStaticOpenGLContext *QWindowsIntegration::staticOpenGLContext() { - return q_staticOpenGLContext; + QWindowsIntegrationPrivate *d = QWindowsIntegration::instance()->d.data(); + if (d->m_staticOpenGLContext.isNull()) + d->m_staticOpenGLContext = QSharedPointer(QWindowsStaticOpenGLContext::create()); + return d->m_staticOpenGLContext.data(); } #endif // !QT_NO_OPENGL diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index b8ad744d05..926e7da67e 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -37,6 +37,7 @@ #include "qwindowsdrag.h" #include "qwindowsscreen.h" #include "qwindowsscaling.h" +#include "qwindowsintegration.h" #ifdef QT_NO_CURSOR # include "qwindowscursor.h" #endif @@ -958,7 +959,8 @@ void QWindowsWindow::destroyWindow() setDropSiteEnabled(false); #ifndef QT_NO_OPENGL if (m_surface) { - m_data.staticOpenGLContext->destroyWindowSurface(m_surface); + if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext()) + staticOpenGLContext->destroyWindowSurface(m_surface); m_surface = 0; } #endif @@ -2302,8 +2304,10 @@ void *QWindowsWindow::surface(void *nativeConfig) #ifdef QT_NO_OPENGL return 0; #else - if (!m_surface) - m_surface = m_data.staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig); + if (!m_surface) { + if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext()) + m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig); + } return m_surface; #endif diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index 9822ebce45..922d00f230 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -107,9 +107,6 @@ struct QWindowsWindowData QMargins customMargins; // User-defined, additional frame for NCCALCSIZE HWND hwnd; bool embedded; -#ifndef QT_NO_OPENGL - QSharedPointer staticOpenGLContext; -#endif // QT_NO_OPENGL static QWindowsWindowData create(const QWindow *w, const QWindowsWindowData ¶meters, From 2603873e75e4b3eedef2939ada3069da36231c09 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 19 Jan 2015 12:05:10 +0100 Subject: [PATCH 17/25] Make harfbuzz-old fallback available at run-time The old harfbuzz code path is included as a fail safe for any possible use case where the Harfbuzz-NG regresses, but because the variable was checked statically, it was not actually possible to build a releasable executable which employed the work-around. Instead we use the regular global static pattern where the variable is queried the first time it's needed. Task-number: QTBUG-43850 Change-Id: I9ade76bf0825bbfefebdbdc4e6ee5571f1a3deec Reviewed-by: Lars Knoll --- src/gui/text/qfontengine.cpp | 13 +++++++++---- src/gui/text/qtextengine.cpp | 8 ++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index b2a7a8e91f..b360ed5c85 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -77,7 +77,12 @@ static inline bool qtransform_equals_no_translate(const QTransform &a, const QTr // Harfbuzz helper functions #ifdef QT_ENABLE_HARFBUZZ_NG -bool useHarfbuzzNG = qgetenv("QT_HARFBUZZ") != "old"; +Q_GLOBAL_STATIC_WITH_ARGS(bool, useHarfbuzzNG,(qgetenv("QT_HARFBUZZ") != "old")) + +bool qt_useHarfbuzzNG() +{ + return *useHarfbuzzNG(); +} #endif Q_STATIC_ASSERT(sizeof(HB_Glyph) == sizeof(glyph_t)); @@ -282,7 +287,7 @@ void *QFontEngine::harfbuzzFont() const { Q_ASSERT(type() != QFontEngine::Multi); #ifdef QT_ENABLE_HARFBUZZ_NG - if (useHarfbuzzNG) + if (qt_useHarfbuzzNG()) return hb_qt_font_get_for_engine(const_cast(this)); #endif if (!font_) { @@ -318,7 +323,7 @@ void *QFontEngine::harfbuzzFace() const { Q_ASSERT(type() != QFontEngine::Multi); #ifdef QT_ENABLE_HARFBUZZ_NG - if (useHarfbuzzNG) + if (qt_useHarfbuzzNG()) return hb_qt_face_get_for_engine(const_cast(this)); #endif if (!face_) { @@ -360,7 +365,7 @@ bool QFontEngine::supportsScript(QChar::Script script) const #endif #ifdef QT_ENABLE_HARFBUZZ_NG - if (useHarfbuzzNG) { + if (qt_useHarfbuzzNG()) { bool ret = false; if (hb_face_t *face = hb_qt_face_get_for_engine(const_cast(this))) { hb_tag_t script_tag_1, script_tag_2; diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index d156124b98..13bfa2386d 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -938,7 +938,7 @@ void QTextEngine::shapeLine(const QScriptLine &line) } #ifdef QT_ENABLE_HARFBUZZ_NG -extern bool useHarfbuzzNG; // defined in qfontengine.cpp +extern bool qt_useHarfbuzzNG(); // defined in qfontengine.cpp #endif void QTextEngine::shapeText(int item) const @@ -1051,7 +1051,7 @@ void QTextEngine::shapeText(int item) const } #ifdef QT_ENABLE_HARFBUZZ_NG - if (useHarfbuzzNG) + if (qt_useHarfbuzzNG()) si.num_glyphs = shapeTextWithHarfbuzzNG(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled); else #endif @@ -1067,7 +1067,7 @@ void QTextEngine::shapeText(int item) const QGlyphLayout glyphs = shapedGlyphs(&si); #ifdef QT_ENABLE_HARFBUZZ_NG - if (useHarfbuzzNG) + if (qt_useHarfbuzzNG()) qt_getJustificationOpportunities(string, itemLength, si, glyphs, logClusters(&si)); #endif @@ -1607,7 +1607,7 @@ void QTextEngine::itemize() const } #ifdef QT_ENABLE_HARFBUZZ_NG analysis = scriptAnalysis.data(); - if (useHarfbuzzNG) { + if (qt_useHarfbuzzNG()) { // ### pretend HB-old behavior for now for (int i = 0; i < length; ++i) { switch (analysis[i].script) { From ee1afbb8aa99e10f1dae11d8418e40351f685b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 13 Jan 2015 10:49:07 +0100 Subject: [PATCH 18/25] tst_qstring_mac: Correct memory management. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The NSStrings return by QString::toNSString are autoreleased; manually releasing them is not correct. The test still works (no leaks or double deletes) since there is no autorelease pool in place when running it. We don't want to encourage incorrect usage: remove the release call an add an autorelease pool. Change-Id: Ic566fd3a8efd6cbc0eb6db850248a68bfc8fed0b Reviewed-by: Timur Pocheptsov Reviewed-by: Gabriel de Dietrich Reviewed-by: Tor Arne Vestbø Reviewed-by: Jake Petroules --- tests/auto/corelib/tools/qstring/tst_qstring_mac.mm | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/auto/corelib/tools/qstring/tst_qstring_mac.mm b/tests/auto/corelib/tools/qstring/tst_qstring_mac.mm index 9061b6c39d..4cec5b3798 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring_mac.mm +++ b/tests/auto/corelib/tools/qstring/tst_qstring_mac.mm @@ -63,17 +63,23 @@ void tst_QString_macTypes() } // QString <-> NSString { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + QString qtString("test string"); const NSString *nsString = qtString.toNSString(); QCOMPARE(QString::fromNSString(nsString), qtString); - [nsString release]; + + [pool release]; } { + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + QString qtString("test string"); const NSString *nsString = qtString.toNSString(); QString qtStringCopy(qtString); qtString = qtString.toUpper(); // modify QCOMPARE(QString::fromNSString(nsString), qtStringCopy); - [nsString release]; + + [pool release]; } } From 64c6bfd1f45f532ea32de49431b66e03e7593f01 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Mon, 19 Jan 2015 18:18:57 +0400 Subject: [PATCH 19/25] Fix crash with multi threaded QFont/QTextEngine usage Since we don't configure HB-NG via its configure script, we have to define all optional switchers we do care about by our own. Some of these switchers were missing in harfbuzz-ng.pro, causing HB-NG to be built with no threading support. Task-number: QTBUG-43850 Change-Id: I0944a68fe0bfae3306a3e6085e25704f0d0d0efc Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro index 79c2a3e2d6..6b51d9679a 100644 --- a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro +++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro @@ -7,7 +7,12 @@ CONFIG += \ load(qt_helper_lib) -DEFINES += HAVE_OT HAVE_ATEXIT HB_NO_UNICODE_FUNCS HB_DISABLE_DEPRECATED +DEFINES += HAVE_OT HB_NO_UNICODE_FUNCS HB_DISABLE_DEPRECATED + +# platform/compiler specific definitions +DEFINES += HAVE_ATEXIT +gcc: DEFINES += HAVE_INTEL_ATOMIC_PRIMITIVES +unix: DEFINES += HAVE_PTHREAD HAVE_SCHED_H HAVE_SCHED_YIELD INCLUDEPATH += $$PWD/include From 2ecde56f65c21e91c2d7e9fe72ecb9c9d1ff1d33 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Wed, 14 Jan 2015 00:25:26 +0100 Subject: [PATCH 20/25] QSortFilterProxyModel: fix a regression bec1854cc023fb705319c582a636d5f484adafcc introduced a regression: when sorting a tree model, children items would not follow the sorted parents any more (they wouldn't be remapped correctly), resulting in crashes. So, the fix needs more reasoning; let's revert the fix, but leave the original test around for any subsequent attempt, and introduce a new test which looks for the right behavior when sorting trees. This commit partially reverts bec1854cc023fb705319c582a636d5f484adafcc. Task-number: QTBUG-43827 Change-Id: Ic83ac53aef639f870f6c36a8b4b2992f5b485b13 Reviewed-by: David Faure Reviewed-by: Volker Krause (cherry-picked from qtbase/e9ad46ed412987e3e46c5a641e5f30408b97ac90) --- .../itemmodels/qsortfilterproxymodel.cpp | 6 ++- .../tst_qsortfilterproxymodel.cpp | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp index 0b2b0e4188..b01c9db418 100644 --- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp +++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp @@ -1196,7 +1196,11 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc parents << q->mapFromSource(source_parent); emit q->layoutAboutToBeChanged(parents, QAbstractItemModel::VerticalSortHint); QModelIndexPairList source_indexes = store_persistent_indexes(); - sort_source_rows(m->source_rows, source_parent); + remove_source_items(m->proxy_rows, m->source_rows, source_rows_resort, + source_parent, Qt::Vertical, false); + sort_source_rows(source_rows_resort, source_parent); + insert_source_items(m->proxy_rows, m->source_rows, source_rows_resort, + source_parent, Qt::Vertical, false); update_persistent_indexes(source_indexes); emit q->layoutChanged(parents, QAbstractItemModel::VerticalSortHint); // Make sure we also emit dataChanged for the rows diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index 53ed1bc9a0..5bb7ffc401 100644 --- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -96,6 +96,7 @@ private slots: void changeSourceData_data(); void changeSourceData(); void changeSourceDataKeepsStableSorting_qtbug1548(); + void resortingDoesNotBreakTreeModels(); void sortFilterRole(); void selectionFilteredOut(); void match_data(); @@ -2029,6 +2030,8 @@ static void checkSortedTableModel(const QAbstractItemModel *model, const QString void tst_QSortFilterProxyModel::changeSourceDataKeepsStableSorting_qtbug1548() { + QSKIP("This test will fail, see QTBUG-1548"); + // Check that emitting dataChanged from the source model // for a change of a role which is not the sorting role // doesn't alter the sorting. In this case, we sort on the DisplayRole, @@ -4028,5 +4031,39 @@ void tst_QSortFilterProxyModel::canDropMimeData() QCOMPARE(proxy.canDropMimeData(0, Qt::CopyAction, -1, -1, proxy.index(row, 0)), row < 5); } +void tst_QSortFilterProxyModel::resortingDoesNotBreakTreeModels() +{ + QStandardItemModel *treeModel = new QStandardItemModel(this); + QStandardItem *e1 = new QStandardItem("Loading..."); + e1->appendRow(new QStandardItem("entry10")); + treeModel->appendRow(e1); + QStandardItem *e0 = new QStandardItem("Loading..."); + e0->appendRow(new QStandardItem("entry00")); + e0->appendRow(new QStandardItem("entry01")); + treeModel->appendRow(e0); + + QSortFilterProxyModel proxy; + proxy.setDynamicSortFilter(true); + proxy.sort(0); + proxy.setSourceModel(treeModel); + + ModelTest modelTest(&proxy); + + QCOMPARE(proxy.rowCount(), 2); + e1->setText("entry1"); + e0->setText("entry0"); + + QModelIndex pi0 = proxy.index(0, 0); + QCOMPARE(pi0.data().toString(), QString("entry0")); + QCOMPARE(proxy.rowCount(pi0), 2); + + QModelIndex pi01 = proxy.index(1, 0, pi0); + QCOMPARE(pi01.data().toString(), QString("entry01")); + + QModelIndex pi1 = proxy.index(1, 0); + QCOMPARE(pi1.data().toString(), QString("entry1")); + QCOMPARE(proxy.rowCount(pi1), 1); +} + QTEST_MAIN(tst_QSortFilterProxyModel) #include "tst_qsortfilterproxymodel.moc" From 9e4ef3539a5770f1b422b73b41dc3218ff4efc81 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Tue, 20 Jan 2015 12:40:50 +0100 Subject: [PATCH 21/25] Fix finding widgets for Windows Embedded Compact ChildWindowFromPoint does not work properly under wince, so lets use the plain old WindowFromPoint. Task-number: QTBUG-44022 Change-Id: I49bae6409f2d11ddc01bea01f4c2f91a02b90892 Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowscontext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 13a3d044a0..ffa7f82d8e 100644 --- a/src/plugins/platforms/windows/qwindowscontext.cpp +++ b/src/plugins/platforms/windows/qwindowscontext.cpp @@ -676,7 +676,7 @@ static inline bool findPlatformWindowHelper(const POINT &screenPoint, unsigned c const HWND child = ChildWindowFromPointEx(*hwnd, point, cwexFlags); #else Q_UNUSED(cwexFlags) - const HWND child = ChildWindowFromPoint(*hwnd, point); + const HWND child = WindowFromPoint(point); #endif if (!child || child == *hwnd) return false; From 508b1fa173e135c839f07e0e4cd6009ac63a577c Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 20 Jan 2015 09:34:42 +0100 Subject: [PATCH 22/25] QTemporaryDir: Remove directories on failure When creating a temporary directory but failing to set its permissions, we need to remove the directory we created to avoid leaving 256 empty, unused directories in the destination folder. This happens on Android if you try creating a QTemporaryDir in the download path on the sdcard. Task-number: QTBUG-43352 Change-Id: Ic88fb7572f1abd65e5c7d8882b59c95f4b22ed72 Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/io/qtemporarydir.cpp | 5 ++++- .../corelib/io/qtemporarydir/tst_qtemporarydir.cpp | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qtemporarydir.cpp b/src/corelib/io/qtemporarydir.cpp index 5e0def74ee..5f0c500183 100644 --- a/src/corelib/io/qtemporarydir.cpp +++ b/src/corelib/io/qtemporarydir.cpp @@ -128,8 +128,11 @@ static char *q_mkdtemp(char *templateName) QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner, error); - if (error.error() != 0) + if (error.error() != 0) { + if (!QFileSystemEngine::removeDirectory(fileSystemEntry, false)) + qWarning() << "Unable to remove unused directory" << templateNameStr; continue; + } return templateName; } } diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp index a68a1185b8..e909b90a12 100644 --- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp +++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp @@ -70,6 +70,8 @@ private slots: void QTBUG_4796_data(); void QTBUG_4796(); + void QTBUG43352_failedSetPermissions(); + public: }; @@ -419,5 +421,17 @@ void tst_QTemporaryDir::QTBUG_4796() // unicode support cleaner.reset(); } +void tst_QTemporaryDir::QTBUG43352_failedSetPermissions() +{ + QString path = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + QStringLiteral("/"); + int count = QDir(path).entryList().size(); + + { + QTemporaryDir dir(path); + } + + QCOMPARE(QDir(path).entryList().size(), count); +} + QTEST_MAIN(tst_QTemporaryDir) #include "tst_qtemporarydir.moc" From 817800ad39df10ca78e2c965a61d4d2025df622b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 22 Dec 2014 21:19:27 -0200 Subject: [PATCH 23/25] Fix QXmlStreamReader parsing of files containing NULs Due to a flaw in the internal API, QXmlStreamReader's internal buffering would mistake a NUL byte in the input stream for EOF during parsing, but wouldn't set atEnd == true because it hadn't yet processed all bytes. This resulted in an infinite loop in QXmlStreamReaderPrivate::parse. So, instead of returning zero (false) to indicate EOF, return -1 (but in unsigned form, ~0, to avoid ICC warnings of change of sign). In turn, this required enlarging a few variables to avoid ~0U becoming 0xffff, which is a valid QChar (could happen if the input is a QString, not a QIODevice). Task-number: QTBUG-43513 Change-Id: If5badcfd3e4176b79517da1fd108e0abb93a3fd1 Reviewed-by: Lars Knoll Reviewed-by: Oswald Buddenhagen --- src/corelib/xml/qxmlstream.cpp | 41 ++++++++++-------- src/corelib/xml/qxmlstream_p.h | 12 ++--- .../qxmlstream/data/carriagereturn+nul.ref | 3 ++ .../qxmlstream/data/carriagereturn+nul.xml | Bin 0 -> 60 bytes .../auto/corelib/xml/qxmlstream/data/nul0.ref | 2 + .../auto/corelib/xml/qxmlstream/data/nul0.xml | Bin 0 -> 1 bytes .../auto/corelib/xml/qxmlstream/data/nul1.ref | 2 + .../auto/corelib/xml/qxmlstream/data/nul1.xml | Bin 0 -> 3 bytes .../auto/corelib/xml/qxmlstream/data/nul2.ref | 3 ++ .../auto/corelib/xml/qxmlstream/data/nul2.xml | Bin 0 -> 4 bytes .../auto/corelib/xml/qxmlstream/data/nul3.ref | 2 + .../auto/corelib/xml/qxmlstream/data/nul3.xml | Bin 0 -> 7 bytes .../corelib/xml/qxmlstream/data/nul3bis.ref | 2 + .../corelib/xml/qxmlstream/data/nul3bis.xml | Bin 0 -> 9 bytes .../auto/corelib/xml/qxmlstream/data/nul4.ref | 2 + .../auto/corelib/xml/qxmlstream/data/nul4.xml | Bin 0 -> 8 bytes .../corelib/xml/qxmlstream/data/nul4bis.ref | 2 + .../corelib/xml/qxmlstream/data/nul4bis.xml | Bin 0 -> 10 bytes .../auto/corelib/xml/qxmlstream/data/nul5.ref | 3 ++ .../auto/corelib/xml/qxmlstream/data/nul5.xml | Bin 0 -> 23 bytes 20 files changed, 49 insertions(+), 25 deletions(-) create mode 100644 tests/auto/corelib/xml/qxmlstream/data/carriagereturn+nul.ref create mode 100644 tests/auto/corelib/xml/qxmlstream/data/carriagereturn+nul.xml create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul0.ref create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul0.xml create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul1.ref create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul1.xml create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul2.ref create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul2.xml create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul3.ref create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul3.xml create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul3bis.ref create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul3bis.xml create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul4.ref create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul4.xml create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul4bis.ref create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul4bis.xml create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul5.ref create mode 100644 tests/auto/corelib/xml/qxmlstream/data/nul5.xml diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index 94f6a8bcde..d1698b812f 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -64,6 +64,8 @@ QT_BEGIN_NAMESPACE #include "qxmlstream_p.h" +enum { StreamEOF = ~0U }; + /*! \enum QXmlStreamReader::TokenType @@ -903,7 +905,7 @@ inline uint QXmlStreamReaderPrivate::filterCarriageReturn() ++readBufferPos; return peekc; } - if (peekc == 0) { + if (peekc == StreamEOF) { putChar('\r'); return 0; } @@ -912,13 +914,13 @@ inline uint QXmlStreamReaderPrivate::filterCarriageReturn() /*! \internal - If the end of the file is encountered, 0 is returned. + If the end of the file is encountered, ~0 is returned. */ inline uint QXmlStreamReaderPrivate::getChar() { uint c; if (putStack.size()) { - c = atEnd ? 0 : putStack.pop(); + c = atEnd ? StreamEOF : putStack.pop(); } else { if (readBufferPos < readBuffer.size()) c = readBuffer.at(readBufferPos++).unicode(); @@ -937,7 +939,7 @@ inline uint QXmlStreamReaderPrivate::peekChar() } else if (readBufferPos < readBuffer.size()) { c = readBuffer.at(readBufferPos).unicode(); } else { - if ((c = getChar_helper())) + if ((c = getChar_helper()) != StreamEOF) --readBufferPos; } @@ -961,7 +963,8 @@ bool QXmlStreamReaderPrivate::scanUntil(const char *str, short tokenToInject) int pos = textBuffer.size(); int oldLineNumber = lineNumber; - while (uint c = getChar()) { + uint c; + while ((c = getChar()) != StreamEOF) { /* First, we do the validation & normalization. */ switch (c) { case '\r': @@ -1007,9 +1010,9 @@ bool QXmlStreamReaderPrivate::scanString(const char *str, short tokenToInject, b { int n = 0; while (str[n]) { - ushort c = getChar(); + uint c = getChar(); if (c != ushort(str[n])) { - if (c) + if (c != StreamEOF) putChar(c); while (n--) { putChar(ushort(str[n])); @@ -1137,7 +1140,7 @@ inline int QXmlStreamReaderPrivate::fastScanLiteralContent() { int n = 0; uint c; - while ((c = getChar())) { + while ((c = getChar()) != StreamEOF) { switch (ushort(c)) { case 0xfffe: case 0xffff: @@ -1182,8 +1185,8 @@ inline int QXmlStreamReaderPrivate::fastScanLiteralContent() inline int QXmlStreamReaderPrivate::fastScanSpace() { int n = 0; - ushort c; - while ((c = getChar())) { + uint c; + while ((c = getChar()) != StreamEOF) { switch (c) { case '\r': if ((c = filterCarriageReturn()) == 0) @@ -1216,7 +1219,7 @@ inline int QXmlStreamReaderPrivate::fastScanContentCharList() { int n = 0; uint c; - while ((c = getChar())) { + while ((c = getChar()) != StreamEOF) { switch (ushort(c)) { case 0xfffe: case 0xffff: @@ -1279,8 +1282,8 @@ inline int QXmlStreamReaderPrivate::fastScanContentCharList() inline int QXmlStreamReaderPrivate::fastScanName(int *prefix) { int n = 0; - ushort c; - while ((c = getChar())) { + uint c; + while ((c = getChar()) != StreamEOF) { switch (c) { case '\n': case ' ': @@ -1396,7 +1399,7 @@ inline int QXmlStreamReaderPrivate::fastScanNMTOKEN() { int n = 0; uint c; - while ((c = getChar())) { + while ((c = getChar()) != StreamEOF) { if (fastDetermineNameChar(c) == NotName) { putChar(c); return n; @@ -1452,7 +1455,7 @@ void QXmlStreamReaderPrivate::putReplacementInAttributeValue(const QString &s) } } -ushort QXmlStreamReaderPrivate::getChar_helper() +uint QXmlStreamReaderPrivate::getChar_helper() { const int BUFFER_SIZE = 8192; characterOffset += readBufferPos; @@ -1476,7 +1479,7 @@ ushort QXmlStreamReaderPrivate::getChar_helper() } if (!nbytesread) { atEnd = true; - return 0; + return StreamEOF; } #ifndef QT_NO_TEXTCODEC @@ -1484,7 +1487,7 @@ ushort QXmlStreamReaderPrivate::getChar_helper() if (nbytesread < 4) { // the 4 is to cover 0xef 0xbb 0xbf plus // one extra for the utf8 codec atEnd = true; - return 0; + return StreamEOF; } int mib = 106; // UTF-8 @@ -1517,7 +1520,7 @@ ushort QXmlStreamReaderPrivate::getChar_helper() if(lockEncoding && decoder->hasFailure()) { raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content.")); readBuffer.clear(); - return 0; + return StreamEOF; } #else readBuffer = QString::fromLatin1(rawReadBuffer.data(), nbytesread); @@ -1531,7 +1534,7 @@ ushort QXmlStreamReaderPrivate::getChar_helper() } atEnd = true; - return 0; + return StreamEOF; } QStringRef QXmlStreamReaderPrivate::namespaceForPrefix(const QStringRef &prefix) diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h index 7ff65e1718..087d64fce8 100644 --- a/src/corelib/xml/qxmlstream_p.h +++ b/src/corelib/xml/qxmlstream_p.h @@ -944,7 +944,7 @@ public: short token; - ushort token_char; + uint token_char; uint filterCarriageReturn(); inline uint getChar(); @@ -955,7 +955,7 @@ public: void putStringLiteral(const QString &s); void putReplacement(const QString &s); void putReplacementInAttributeValue(const QString &s); - ushort getChar_helper(); + uint getChar_helper(); bool scanUntil(const char *str, short tokenToInject = -1); bool scanString(const char *str, short tokenToInject, bool requireSpace = true); @@ -1068,7 +1068,7 @@ bool QXmlStreamReaderPrivate::parse() documentVersion.clear(); documentEncoding.clear(); #ifndef QT_NO_TEXTCODEC - if (decoder->hasFailure()) { + if (decoder && decoder->hasFailure()) { raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content.")); readBuffer.clear(); return false; @@ -1099,8 +1099,8 @@ bool QXmlStreamReaderPrivate::parse() if (token == -1 && - TERMINAL_COUNT != action_index[act]) { uint cu = getChar(); token = NOTOKEN; - token_char = cu; - if (cu & 0xff0000) { + token_char = cu == ~0U ? cu : ushort(cu); + if ((cu != ~0U) && (cu & 0xff0000)) { token = cu >> 16; } else switch (token_char) { case 0xfffe: @@ -1119,7 +1119,7 @@ bool QXmlStreamReaderPrivate::parse() break; } // fall through - case '\0': { + case ~0U: { token = EOF_SYMBOL; if (!tagsDone && !inParseEntity) { int a = t_action(act, token); diff --git a/tests/auto/corelib/xml/qxmlstream/data/carriagereturn+nul.ref b/tests/auto/corelib/xml/qxmlstream/data/carriagereturn+nul.ref new file mode 100644 index 0000000000..b636d80294 --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/carriagereturn+nul.ref @@ -0,0 +1,3 @@ +StartDocument( ) +Invalid( processingInstructionTarget="xml_" ) +ERROR: Invalid XML character. diff --git a/tests/auto/corelib/xml/qxmlstream/data/carriagereturn+nul.xml b/tests/auto/corelib/xml/qxmlstream/data/carriagereturn+nul.xml new file mode 100644 index 0000000000000000000000000000000000000000..e87bf56453c2ad1ca7df3dd2804cf0d7730796ed GIT binary patch literal 60 zcmcDqugJ}b=jCNkC`&CW&dkrVRWj5wP*OID literal 0 HcmV?d00001 diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul3bis.ref b/tests/auto/corelib/xml/qxmlstream/data/nul3bis.ref new file mode 100644 index 0000000000..cf4dd3848b --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul3bis.ref @@ -0,0 +1,2 @@ +Invalid( ) +ERROR: Expected 'version', but got ''. diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul3bis.xml b/tests/auto/corelib/xml/qxmlstream/data/nul3bis.xml new file mode 100644 index 0000000000000000000000000000000000000000..61e011014eccbfea406e112ba99cb40f6ea798c6 GIT binary patch literal 9 QcmcDqugJ~eVzA=^01UkX9{>OV literal 0 HcmV?d00001 diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul4.ref b/tests/auto/corelib/xml/qxmlstream/data/nul4.ref new file mode 100644 index 0000000000..cf4dd3848b --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul4.ref @@ -0,0 +1,2 @@ +Invalid( ) +ERROR: Expected 'version', but got ''. diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul4.xml b/tests/auto/corelib/xml/qxmlstream/data/nul4.xml new file mode 100644 index 0000000000000000000000000000000000000000..90f20eebf0751d54fbeb57b51b81fe4f92c5a792 GIT binary patch literal 8 PcmcDqugJ|&;9>v(3bq0F literal 0 HcmV?d00001 diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul4bis.ref b/tests/auto/corelib/xml/qxmlstream/data/nul4bis.ref new file mode 100644 index 0000000000..cf4dd3848b --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul4bis.ref @@ -0,0 +1,2 @@ +Invalid( ) +ERROR: Expected 'version', but got ''. diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul4bis.xml b/tests/auto/corelib/xml/qxmlstream/data/nul4bis.xml new file mode 100644 index 0000000000000000000000000000000000000000..15d2d106857fc9c29b7f87778159c093421f7b10 GIT binary patch literal 10 RcmcDqugJ|&;9{`j0ss#x0zUu% literal 0 HcmV?d00001 diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul5.ref b/tests/auto/corelib/xml/qxmlstream/data/nul5.ref new file mode 100644 index 0000000000..9432b74a99 --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul5.ref @@ -0,0 +1,3 @@ +StartDocument( documentVersion="1.0" ) +Invalid( ) +ERROR: Start tag expected. diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul5.xml b/tests/auto/corelib/xml/qxmlstream/data/nul5.xml new file mode 100644 index 0000000000000000000000000000000000000000..6a79cbdc7521791dc3d127183c07a63580af27bc GIT binary patch literal 23 ecmcDqugJ|&C`&CW&dkrVRWj5wP_nn Date: Mon, 26 Jan 2015 19:40:35 +0100 Subject: [PATCH 24/25] Windows/ANGLE: Fix initialization of contexts. Immediately try to initialize a context obtained by eglGetPlatformDisplayEXT() and clear display in case it fails, falling back to eglGetDisplay(). Change-Id: Ia6c1c6da4daff6651153c854eda4fb8749bdc526 Reviewed-by: Laszlo Agocs --- .../platforms/windows/qwindowseglcontext.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index bde0503ee0..7f0421ad90 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -358,6 +358,8 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: } EGLDisplay display = EGL_NO_DISPLAY; + EGLint major = 0; + EGLint minor = 0; #ifdef EGL_ANGLE_platform_angle_opengl if (libEGL.eglGetPlatformDisplayEXT && (preferredType & QWindowsOpenGLTester::AngleBackendMask)) { @@ -373,8 +375,13 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: attributes = anglePlatformAttributes[1]; else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11Warp) attributes = anglePlatformAttributes[2]; - if (attributes) + if (attributes) { display = libEGL.eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, attributes); + if (!libEGL.eglInitialize(display, &major, &minor)) { + display = EGL_NO_DISPLAY; + major = minor = 0; + } + } } #else // EGL_ANGLE_platform_angle_opengl Q_UNUSED(preferredType) @@ -386,9 +393,7 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: return 0; } - EGLint major; - EGLint minor; - if (!libEGL.eglInitialize(display, &major, &minor)) { + if (!major && !libEGL.eglInitialize(display, &major, &minor)) { int err = libEGL.eglGetError(); qWarning("%s: Could not initialize EGL display: error 0x%x\n", Q_FUNC_INFO, err); if (err == 0x3001) From 6430d6e3ec31afabe0e674397088dd6d9e056195 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 27 Jan 2015 14:20:52 +0100 Subject: [PATCH 25/25] Use qt.io rather than qt-project.org for network tests Mainly because of a change in certificates which is causing failing tests. This patch is cherry-picked from https://codereview.qt-project.org/104619/ Change-Id: I8304e5ac4107428a250b71be5df7b5399a811017 Reviewed-by: Richard J. Moore --- tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp | 2 +- .../tst_qsslsocket_onDemandCertificates_member.cpp | 2 +- .../tst_qsslsocket_onDemandCertificates_static.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index aa954429de..a355cfeb17 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -772,7 +772,7 @@ void tst_QSslSocket::peerCertificateChain() QVERIFY(socket->waitForDisconnected()); // connect again to a different server - socket->connectToHostEncrypted("qt-project.org", 443); + socket->connectToHostEncrypted("www.qt.io", 443); socket->ignoreSslErrors(); QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode); QVERIFY(socket->peerCertificateChain().isEmpty()); diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp index 94d7c3905c..1a65d5f9f3 100644 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_member/tst_qsslsocket_onDemandCertificates_member.cpp @@ -185,7 +185,7 @@ void tst_QSslSocket_onDemandCertificates_member::proxyAuthenticationRequired(con void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMethods() { - QString host("qt-project.org"); + QString host("www.qt.io"); // not using any root certs -> should not work QSslSocketPtr socket2 = newSocket(); diff --git a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp index 418c702030..ad1f218471 100644 --- a/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp +++ b/tests/auto/network/ssl/qsslsocket_onDemandCertificates_static/tst_qsslsocket_onDemandCertificates_static.cpp @@ -181,7 +181,7 @@ void tst_QSslSocket_onDemandCertificates_static::proxyAuthenticationRequired(con void tst_QSslSocket_onDemandCertificates_static::onDemandRootCertLoadingStaticMethods() { - QString host("qt-project.org"); + QString host("www.qt.io"); // not using any root certs -> should not work QSslSocket::setDefaultCaCertificates(QList());