diff options
author | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2015-01-29 10:02:38 +0100 |
---|---|---|
committer | Frederik Gladhorn <frederik.gladhorn@theqtcompany.com> | 2015-01-29 10:05:01 +0100 |
commit | 55162dae7e5e40bd86b1a6d2c5d5009660159d39 (patch) | |
tree | 30b54dfc19cb83ac0edb795bf206b51edd805c97 | |
parent | 3527fd62c2705a0292458dd751d9d7f8d4be357f (diff) | |
parent | 6430d6e3ec31afabe0e674397088dd6d9e056195 (diff) | |
download | qtbase-55162dae7e5e40bd86b1a6d2c5d5009660159d39.tar.gz |
Merge remote-tracking branch 'origin/5.4.1' into 5.4
Change-Id: Idadb5639da6e55e7ac8cc30eedf76d147d8d5d23
76 files changed, 810 insertions, 222 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 += \ "<div class=\"container clearfix no_discs\">\n" \ " <ul id=\"menu-footer-submenu\" class=\"right clearfix\"><li id=\"menu-item-1795\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-1795\"><a title=\"Sign into your account.\" href=\"https://account.qt.io/login\">Sign In</a></li>\n" \ " <li id=\"menu-item-1494\" class=\"menu-item menu-item-type-post_type menu-item-object-page menu-item-1494\"><a href=\"http://qt.io/contact-us/\">Contact us</a></li>\n" \ - " <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://www.digia.com\">© 2014 Digia Oyj</a></li>\n" \ + " <li id=\"menu-item-4472\" class=\"menu-item menu-item-type-custom menu-item-object-custom menu-item-4472\"><a href=\"http://www.digia.com\">© 2015 Digia Oyj</a></li>\n" \ " </ul>\n" \ "</div>\n" \ "</div>\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 = \ "</div>\n" \ "<div class=\"footer\">\n" \ " <p>\n" \ - " <acronym title=\"Copyright\">©</acronym> 2014 Digia Plc and/or its\n" \ + " <acronym title=\"Copyright\">©</acronym> 2015 Digia Plc and/or its\n" \ " subsidiaries. Documentation contributions included herein are the copyrights of\n" \ " their respective owners.<br>" \ " 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 = \ " </div>\n" \ " <p class=\"copy-notice\">\n" \ - " <acronym title=\"Copyright\">©</acronym> 2014 Digia Plc and/or its\n" \ + " <acronym title=\"Copyright\">©</acronym> 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/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 diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 4f9f54cde8..d592032c1f 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 ** @@ -604,7 +604,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/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/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) 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/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/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index e4ee71f0b1..ad10c63686 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/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/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 <QtCore/qlibrary.h> 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 <QOpenGLContext> +#include <private/qopenglextensions_p.h> QT_BEGIN_NAMESPACE @@ -242,21 +243,23 @@ QOpenGLTextureHelper::QOpenGLTextureHelper(QOpenGLContext *context) CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3DOES"))); CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)>(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<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexImage3D"))); - TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3D"))); - - // OpenGL 1.3 - CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3D"))); - CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3D"))); -#endif + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + if (ctx->isOpenGLES() && ctx->format().majorVersion() >= 3) { + // OpenGL ES 3.0+ has glTexImage3D. + QOpenGLES3Helper *es3 = static_cast<QOpenGLExtensions *>(ctx->functions())->gles3Helper(); + TexImage3D = es3->TexImage3D; + TexSubImage3D = es3->TexSubImage3D; + CompressedTexImage3D = es3->CompressedTexImage3D; + CompressedTexSubImage3D = es3->CompressedTexSubImage3D; + } else { + // OpenGL 1.2 + TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexImage3D"))); + TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3D"))); + + // OpenGL 1.3 + CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3D"))); + CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(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 <QtCore/private/qobject_p.h> #include <QtGui/qopenglcontext.h> -#include <QtGui/qopenglfunctions.h> #include <QtGui/qoffscreensurface.h> #include <QtGui/qopenglfunctions_3_0.h> #include <QtGui/qopenglfunctions_3_2_core.h> +#include <private/qopenglextensions_p.h> #include <private/qopenglvertexarrayobject_p.h> 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<QOpenGLExtensions *>(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<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysOES"))); helper->DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysOES"))); helper->BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayOES"))); 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<QFontEngine *>(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<QFontEngine *>(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<QFontEngine *>(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 8f60847250..8f874e0245 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 @@ -1616,7 +1616,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) { 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.cpp b/src/network/ssl/qsslsocket.cpp index f735b6bd4f..c0c15fb5b1 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1983,6 +1983,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 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 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<QBy return QVariant(); QList<QVariant> 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); } diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp index 1cc596ca8d..c253a9605b 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; diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 7fcb1f4ffe..f52c5b733c 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){ @@ -358,28 +358,34 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create() } EGLDisplay display = EGL_NO_DISPLAY; + EGLint major = 0; + EGLint minor = 0; #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) + if (attributes) { display = libEGL.eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, attributes); + if (!libEGL.eglInitialize(display, &major, &minor)) { + display = EGL_NO_DISPLAY; + major = minor = 0; + } + } } -#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) { @@ -387,9 +393,7 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create() 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) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 29df3ba882..c2b153e4c1 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 <EGL/egl.h> QT_BEGIN_NAMESPACE @@ -250,7 +251,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/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. diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 54fb138d85..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; } @@ -328,61 +324,65 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons } #ifndef QT_NO_OPENGL -static QWindowsStaticOpenGLContext *q_staticOpenGLContext = 0; -QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::create() +QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate() { - 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"; - + 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. - 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(); - } - } + 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) - ctx = QWindowsEGLStaticContext::create(); + QWindowsOpenGLTester::Renderers glesRenderers = QWindowsOpenGLTester::requestedGlesRenderer(); + if (glesRenderers == QWindowsOpenGLTester::InvalidRenderer) + glesRenderers = QWindowsOpenGLTester::supportedGlesRenderers(); + return QWindowsEGLStaticContext::create(glesRenderers); #elif !defined(QT_NO_OPENGL) - ctx = QOpenGLStaticContext::create(); + return QOpenGLStaticContext::create(); #endif - - q_staticOpenGLContext = ctx; - - return ctx; } -bool QWindowsIntegrationPrivate::ensureStaticOpenGLContext() +QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::create() { - if (m_staticOpenGLContext.isNull()) - m_staticOpenGLContext = QSharedPointer<QWindowsStaticOpenGLContext>(QWindowsStaticOpenGLContext::create()); - return !m_staticOpenGLContext.isNull(); + return QWindowsStaticOpenGLContext::doCreate(); } QPlatformOpenGLContext *QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const { qCDebug(lcQpaGl) << __FUNCTION__ << context->format(); - if (d->ensureStaticOpenGLContext()) { - QScopedPointer<QWindowsOpenGLContext> result(d->m_staticOpenGLContext->createContext(context)); + if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext()) { + QScopedPointer<QWindowsOpenGLContext> result(staticOpenGLContext->createContext(context)); if (result->isValid()) return result.take(); } @@ -396,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>(QWindowsStaticOpenGLContext::create()); + return d->m_staticOpenGLContext.data(); } #endif // !QT_NO_OPENGL 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/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 ba3a95ce7a..f6caf8b06e 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,231 @@ ****************************************************************************/ #include "qwindowsopengltester.h" -#include "qt_windows.h" #include "qwindowscontext.h" +#include <QtCore/QVariantMap> +#include <QtCore/QDebug> +#include <QtCore/QTextStream> +#include <QtCore/QCoreApplication> + +#ifndef Q_OS_WINCE +# include <QtCore/qt_windows.h> +# include <private/qsystemlibrary_p.h> +# include <d3d9.h> +# include <GL/gl.h> +#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; +} + +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 HMODULE lib = 0; HWND wnd = 0; HDC dc = 0; @@ -109,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<GetString_t>(::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"); @@ -133,6 +382,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..6238eea4b0 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,14 +31,91 @@ ** ****************************************************************************/ +#ifndef QWINDOWSOPENGLTESTER_H +#define QWINDOWSOPENGLTESTER_H + #include <qtwindowsglobal.h> +#include <QtCore/QByteArray> +#include <QtCore/QFlags> + 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: + 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 diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 2e5308f157..65bc9742e4 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 @@ -555,8 +556,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; @@ -995,7 +1000,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 @@ -2340,8 +2346,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 33be287f81..6d6d473ccd 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<QWindowsStaticOpenGLContext> staticOpenGLContext; -#endif // QT_NO_OPENGL static QWindowsWindowData create(const QWindow *w, const QWindowsWindowData ¶meters, 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 } 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; } 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 @@ <author>Qt Development Frameworks</author> <publisher>Qt Project</publisher> <copyright> - <copyryear year="2014"/> + <copyryear year="2015"/> <copyrholder>Qt Project</copyrholder> </copyright> <permissions view="all"/> 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/tools/rcc/main.cpp b/src/tools/rcc/main.cpp index 3c88be92bb..2cfc30ed3f 100644 --- a/src/tools/rcc/main.cpp +++ b/src/tools/rcc/main.cpp @@ -47,6 +47,7 @@ #ifdef Q_OS_WIN # include <fcntl.h> # include <io.h> +# include <stdio.h> #endif // Q_OS_WIN QT_BEGIN_NAMESPACE 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) "<p>Qt and the Qt logo are trademarks of Digia Plc and/or its subsidiary(-ies).</p>" "<p>Qt is a Digia product developed as an open source project. See <a href=\"http://%3/\">%3</a> " "for more information.</p>" - ).arg(QStringLiteral("2014"), + ).arg(QStringLiteral("2015"), QStringLiteral("qt.io/licensing"), QStringLiteral("qt.io")); QMessageBox *msgBox = new QMessageBox(parent); 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<QWidget *>(receiver); QWheelEvent* wheel = static_cast<QWheelEvent*>(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/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; 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" 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" 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]; } } 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 Binary files differnew file mode 100644 index 0000000000..e87bf56453 --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/carriagereturn+nul.xml diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul0.ref b/tests/auto/corelib/xml/qxmlstream/data/nul0.ref new file mode 100644 index 0000000000..a76455ee07 --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul0.ref @@ -0,0 +1,2 @@ +Invalid( ) +ERROR: Premature end of document. diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul0.xml b/tests/auto/corelib/xml/qxmlstream/data/nul0.xml Binary files differnew file mode 100644 index 0000000000..f76dd238ad --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul0.xml diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul1.ref b/tests/auto/corelib/xml/qxmlstream/data/nul1.ref new file mode 100644 index 0000000000..a76455ee07 --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul1.ref @@ -0,0 +1,2 @@ +Invalid( ) +ERROR: Premature end of document. diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul1.xml b/tests/auto/corelib/xml/qxmlstream/data/nul1.xml Binary files differnew file mode 100644 index 0000000000..aab3ad6ca9 --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul1.xml diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul2.ref b/tests/auto/corelib/xml/qxmlstream/data/nul2.ref new file mode 100644 index 0000000000..08bbcc6aa4 --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul2.ref @@ -0,0 +1,3 @@ +StartDocument( ) +Invalid( ) +ERROR: Expected '[a-zA-Z]', but got ' '. diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul2.xml b/tests/auto/corelib/xml/qxmlstream/data/nul2.xml Binary files differnew file mode 100644 index 0000000000..e14d1b8ae5 --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul2.xml diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul3.ref b/tests/auto/corelib/xml/qxmlstream/data/nul3.ref new file mode 100644 index 0000000000..cf4dd3848b --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul3.ref @@ -0,0 +1,2 @@ +Invalid( ) +ERROR: Expected 'version', but got ''. diff --git a/tests/auto/corelib/xml/qxmlstream/data/nul3.xml b/tests/auto/corelib/xml/qxmlstream/data/nul3.xml Binary files differnew file mode 100644 index 0000000000..d8260b908e --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul3.xml 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 Binary files differnew file mode 100644 index 0000000000..61e011014e --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul3bis.xml 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 Binary files differnew file mode 100644 index 0000000000..90f20eebf0 --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul4.xml 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 Binary files differnew file mode 100644 index 0000000000..15d2d10685 --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul4bis.xml 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 Binary files differnew file mode 100644 index 0000000000..6a79cbdc75 --- /dev/null +++ b/tests/auto/corelib/xml/qxmlstream/data/nul5.xml 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<QSslCertificate>()); 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() |