Merge remote-tracking branch 'origin/5.4.1' into 5.4

Change-Id: Idadb5639da6e55e7ac8cc30eedf76d147d8d5d23
This commit is contained in:
Frederik Gladhorn 2015-01-29 10:02:38 +01:00
commit 55162dae7e
76 changed files with 817 additions and 229 deletions

View File

@ -1,6 +1,6 @@
GNU LESSER GENERAL PUBLIC LICENSE 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 Contact: http://www.qt-project.org/legal
You may use, distribute and copy the Qt GUI Toolkit under the terms of You may use, distribute and copy the Qt GUI Toolkit under the terms of

View File

@ -1,6 +1,6 @@
GNU LESSER GENERAL PUBLIC LICENSE 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 Contact: http://www.qt-project.org/legal
You may use, distribute and copy the Qt GUI Toolkit under the terms of You may use, distribute and copy the Qt GUI Toolkit under the terms of

View File

@ -3,7 +3,7 @@
dita.metadata.default.author = Qt Project dita.metadata.default.author = Qt Project
dita.metadata.default.permissions = all dita.metadata.default.permissions = all
dita.metadata.default.publisher = Qt Project 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.copyrholder = Digia Plc
dita.metadata.default.audience = programmer dita.metadata.default.audience = programmer

View File

@ -76,7 +76,7 @@ HTML.footer += \
"<div class=\"container clearfix no_discs\">\n" \ "<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" \ " <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-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" \ " </ul>\n" \
"</div>\n" \ "</div>\n" \
"</div>\n" \ "</div>\n" \

View File

@ -8,7 +8,7 @@ HTML.footer = \
"</div>\n" \ "</div>\n" \
"<div class=\"footer\">\n" \ "<div class=\"footer\">\n" \
" <p>\n" \ " <p>\n" \
" <acronym title=\"Copyright\">&copy;</acronym> 2014 Digia Plc and/or its\n" \ " <acronym title=\"Copyright\">&copy;</acronym> 2015 Digia Plc and/or its\n" \
" subsidiaries. Documentation contributions included herein are the copyrights of\n" \ " subsidiaries. Documentation contributions included herein are the copyrights of\n" \
" their respective owners.<br>" \ " their respective owners.<br>" \
" The documentation provided herein is licensed under the terms of the" \ " The documentation provided herein is licensed under the terms of the" \

View File

@ -5,7 +5,7 @@
HTML.footer = \ HTML.footer = \
" </div>\n" \ " </div>\n" \
" <p class=\"copy-notice\">\n" \ " <p class=\"copy-notice\">\n" \
" <acronym title=\"Copyright\">&copy;</acronym> 2014 Digia Plc and/or its\n" \ " <acronym title=\"Copyright\">&copy;</acronym> 2015 Digia Plc and/or its\n" \
" subsidiaries. Documentation contributions included herein are the copyrights of\n" \ " subsidiaries. Documentation contributions included herein are the copyrights of\n" \
" their respective owners. " \ " their respective owners. " \
" The documentation provided herein is licensed under the terms of the" \ " The documentation provided herein is licensed under the terms of the" \

View File

@ -7,7 +7,12 @@ CONFIG += \
load(qt_helper_lib) 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 INCLUDEPATH += $$PWD/include

View File

@ -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 ** Copyright (C) 2014 Intel Corporation
** Contact: http://www.qt-project.org/legal ** Contact: http://www.qt-project.org/legal
** **
@ -604,7 +604,7 @@ extern "C" void qt_core_boilerplate();
void qt_core_boilerplate() void qt_core_boilerplate()
{ {
printf("This is the QtCore library version " QT_BUILD_STR "\n" 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" "Contact: http://www.qt-project.org/legal\n"
"\n" "\n"
"Build date: %s\n" "Build date: %s\n"

View File

@ -128,8 +128,11 @@ static char *q_mkdtemp(char *templateName)
QFile::ReadOwner | QFile::ReadOwner |
QFile::WriteOwner | QFile::WriteOwner |
QFile::ExeOwner, error); QFile::ExeOwner, error);
if (error.error() != 0) if (error.error() != 0) {
if (!QFileSystemEngine::removeDirectory(fileSystemEntry, false))
qWarning() << "Unable to remove unused directory" << templateNameStr;
continue; continue;
}
return templateName; return templateName;
} }
} }

View File

@ -54,7 +54,13 @@ QUrl QUrl::fromCFURL(CFURLRef url)
CFURLRef QUrl::toCFURL() const 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) QUrl QUrl::fromNSURL(const NSURL *url)

View File

@ -1196,7 +1196,11 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc
parents << q->mapFromSource(source_parent); parents << q->mapFromSource(source_parent);
emit q->layoutAboutToBeChanged(parents, QAbstractItemModel::VerticalSortHint); emit q->layoutAboutToBeChanged(parents, QAbstractItemModel::VerticalSortHint);
QModelIndexPairList source_indexes = store_persistent_indexes(); 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); update_persistent_indexes(source_indexes);
emit q->layoutChanged(parents, QAbstractItemModel::VerticalSortHint); emit q->layoutChanged(parents, QAbstractItemModel::VerticalSortHint);
// Make sure we also emit dataChanged for the rows // Make sure we also emit dataChanged for the rows

View File

@ -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 ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the QtCore module of the Qt Toolkit. ** 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[] = static const char boilerplate_supported_but_time_limited[] =
"\nQt %1 Evaluation License\n" "\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" "This trial version may only be used for evaluation purposes\n"
"and will shut down after 120 minutes.\n" "and will shut down after 120 minutes.\n"
"Registered to:\n" "Registered to:\n"
@ -57,7 +57,7 @@ static const char boilerplate_supported_but_time_limited[] =
static const char boilerplate_supported[] = static const char boilerplate_supported[] =
"\nQt %1 Evaluation License\n" "\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" "This trial version may only be used for evaluation purposes\n"
"Registered to:\n" "Registered to:\n"
" Licensee: %2\n\n" " Licensee: %2\n\n"

View File

@ -64,6 +64,8 @@ QT_BEGIN_NAMESPACE
#include "qxmlstream_p.h" #include "qxmlstream_p.h"
enum { StreamEOF = ~0U };
/*! /*!
\enum QXmlStreamReader::TokenType \enum QXmlStreamReader::TokenType
@ -903,7 +905,7 @@ inline uint QXmlStreamReaderPrivate::filterCarriageReturn()
++readBufferPos; ++readBufferPos;
return peekc; return peekc;
} }
if (peekc == 0) { if (peekc == StreamEOF) {
putChar('\r'); putChar('\r');
return 0; return 0;
} }
@ -912,13 +914,13 @@ inline uint QXmlStreamReaderPrivate::filterCarriageReturn()
/*! /*!
\internal \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() inline uint QXmlStreamReaderPrivate::getChar()
{ {
uint c; uint c;
if (putStack.size()) { if (putStack.size()) {
c = atEnd ? 0 : putStack.pop(); c = atEnd ? StreamEOF : putStack.pop();
} else { } else {
if (readBufferPos < readBuffer.size()) if (readBufferPos < readBuffer.size())
c = readBuffer.at(readBufferPos++).unicode(); c = readBuffer.at(readBufferPos++).unicode();
@ -937,7 +939,7 @@ inline uint QXmlStreamReaderPrivate::peekChar()
} else if (readBufferPos < readBuffer.size()) { } else if (readBufferPos < readBuffer.size()) {
c = readBuffer.at(readBufferPos).unicode(); c = readBuffer.at(readBufferPos).unicode();
} else { } else {
if ((c = getChar_helper())) if ((c = getChar_helper()) != StreamEOF)
--readBufferPos; --readBufferPos;
} }
@ -961,7 +963,8 @@ bool QXmlStreamReaderPrivate::scanUntil(const char *str, short tokenToInject)
int pos = textBuffer.size(); int pos = textBuffer.size();
int oldLineNumber = lineNumber; int oldLineNumber = lineNumber;
while (uint c = getChar()) { uint c;
while ((c = getChar()) != StreamEOF) {
/* First, we do the validation & normalization. */ /* First, we do the validation & normalization. */
switch (c) { switch (c) {
case '\r': case '\r':
@ -1007,9 +1010,9 @@ bool QXmlStreamReaderPrivate::scanString(const char *str, short tokenToInject, b
{ {
int n = 0; int n = 0;
while (str[n]) { while (str[n]) {
ushort c = getChar(); uint c = getChar();
if (c != ushort(str[n])) { if (c != ushort(str[n])) {
if (c) if (c != StreamEOF)
putChar(c); putChar(c);
while (n--) { while (n--) {
putChar(ushort(str[n])); putChar(ushort(str[n]));
@ -1137,7 +1140,7 @@ inline int QXmlStreamReaderPrivate::fastScanLiteralContent()
{ {
int n = 0; int n = 0;
uint c; uint c;
while ((c = getChar())) { while ((c = getChar()) != StreamEOF) {
switch (ushort(c)) { switch (ushort(c)) {
case 0xfffe: case 0xfffe:
case 0xffff: case 0xffff:
@ -1182,8 +1185,8 @@ inline int QXmlStreamReaderPrivate::fastScanLiteralContent()
inline int QXmlStreamReaderPrivate::fastScanSpace() inline int QXmlStreamReaderPrivate::fastScanSpace()
{ {
int n = 0; int n = 0;
ushort c; uint c;
while ((c = getChar())) { while ((c = getChar()) != StreamEOF) {
switch (c) { switch (c) {
case '\r': case '\r':
if ((c = filterCarriageReturn()) == 0) if ((c = filterCarriageReturn()) == 0)
@ -1216,7 +1219,7 @@ inline int QXmlStreamReaderPrivate::fastScanContentCharList()
{ {
int n = 0; int n = 0;
uint c; uint c;
while ((c = getChar())) { while ((c = getChar()) != StreamEOF) {
switch (ushort(c)) { switch (ushort(c)) {
case 0xfffe: case 0xfffe:
case 0xffff: case 0xffff:
@ -1279,8 +1282,8 @@ inline int QXmlStreamReaderPrivate::fastScanContentCharList()
inline int QXmlStreamReaderPrivate::fastScanName(int *prefix) inline int QXmlStreamReaderPrivate::fastScanName(int *prefix)
{ {
int n = 0; int n = 0;
ushort c; uint c;
while ((c = getChar())) { while ((c = getChar()) != StreamEOF) {
switch (c) { switch (c) {
case '\n': case '\n':
case ' ': case ' ':
@ -1396,7 +1399,7 @@ inline int QXmlStreamReaderPrivate::fastScanNMTOKEN()
{ {
int n = 0; int n = 0;
uint c; uint c;
while ((c = getChar())) { while ((c = getChar()) != StreamEOF) {
if (fastDetermineNameChar(c) == NotName) { if (fastDetermineNameChar(c) == NotName) {
putChar(c); putChar(c);
return n; 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; const int BUFFER_SIZE = 8192;
characterOffset += readBufferPos; characterOffset += readBufferPos;
@ -1476,7 +1479,7 @@ ushort QXmlStreamReaderPrivate::getChar_helper()
} }
if (!nbytesread) { if (!nbytesread) {
atEnd = true; atEnd = true;
return 0; return StreamEOF;
} }
#ifndef QT_NO_TEXTCODEC #ifndef QT_NO_TEXTCODEC
@ -1484,7 +1487,7 @@ ushort QXmlStreamReaderPrivate::getChar_helper()
if (nbytesread < 4) { // the 4 is to cover 0xef 0xbb 0xbf plus if (nbytesread < 4) { // the 4 is to cover 0xef 0xbb 0xbf plus
// one extra for the utf8 codec // one extra for the utf8 codec
atEnd = true; atEnd = true;
return 0; return StreamEOF;
} }
int mib = 106; // UTF-8 int mib = 106; // UTF-8
@ -1517,7 +1520,7 @@ ushort QXmlStreamReaderPrivate::getChar_helper()
if(lockEncoding && decoder->hasFailure()) { if(lockEncoding && decoder->hasFailure()) {
raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content.")); raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
readBuffer.clear(); readBuffer.clear();
return 0; return StreamEOF;
} }
#else #else
readBuffer = QString::fromLatin1(rawReadBuffer.data(), nbytesread); readBuffer = QString::fromLatin1(rawReadBuffer.data(), nbytesread);
@ -1531,7 +1534,7 @@ ushort QXmlStreamReaderPrivate::getChar_helper()
} }
atEnd = true; atEnd = true;
return 0; return StreamEOF;
} }
QStringRef QXmlStreamReaderPrivate::namespaceForPrefix(const QStringRef &prefix) QStringRef QXmlStreamReaderPrivate::namespaceForPrefix(const QStringRef &prefix)

View File

@ -944,7 +944,7 @@ public:
short token; short token;
ushort token_char; uint token_char;
uint filterCarriageReturn(); uint filterCarriageReturn();
inline uint getChar(); inline uint getChar();
@ -955,7 +955,7 @@ public:
void putStringLiteral(const QString &s); void putStringLiteral(const QString &s);
void putReplacement(const QString &s); void putReplacement(const QString &s);
void putReplacementInAttributeValue(const QString &s); void putReplacementInAttributeValue(const QString &s);
ushort getChar_helper(); uint getChar_helper();
bool scanUntil(const char *str, short tokenToInject = -1); bool scanUntil(const char *str, short tokenToInject = -1);
bool scanString(const char *str, short tokenToInject, bool requireSpace = true); bool scanString(const char *str, short tokenToInject, bool requireSpace = true);
@ -1068,7 +1068,7 @@ bool QXmlStreamReaderPrivate::parse()
documentVersion.clear(); documentVersion.clear();
documentEncoding.clear(); documentEncoding.clear();
#ifndef QT_NO_TEXTCODEC #ifndef QT_NO_TEXTCODEC
if (decoder->hasFailure()) { if (decoder && decoder->hasFailure()) {
raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content.")); raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
readBuffer.clear(); readBuffer.clear();
return false; return false;
@ -1099,8 +1099,8 @@ bool QXmlStreamReaderPrivate::parse()
if (token == -1 && - TERMINAL_COUNT != action_index[act]) { if (token == -1 && - TERMINAL_COUNT != action_index[act]) {
uint cu = getChar(); uint cu = getChar();
token = NOTOKEN; token = NOTOKEN;
token_char = cu; token_char = cu == ~0U ? cu : ushort(cu);
if (cu & 0xff0000) { if ((cu != ~0U) && (cu & 0xff0000)) {
token = cu >> 16; token = cu >> 16;
} else switch (token_char) { } else switch (token_char) {
case 0xfffe: case 0xfffe:
@ -1119,7 +1119,7 @@ bool QXmlStreamReaderPrivate::parse()
break; break;
} }
// fall through // fall through
case '\0': { case ~0U: {
token = EOF_SYMBOL; token = EOF_SYMBOL;
if (!tagsDone && !inParseEntity) { if (!tagsDone && !inParseEntity) {
int a = t_action(act, token); int a = t_action(act, token);

View File

@ -134,7 +134,8 @@ Qt::DropAction QDragManager::drag(QDrag *o)
QGuiApplicationPrivate::instance()->notifyDragStarted(o); QGuiApplicationPrivate::instance()->notifyDragStarted(o);
const Qt::DropAction result = m_platformDrag->drag(m_object); const Qt::DropAction result = m_platformDrag->drag(m_object);
m_object = 0; m_object = 0;
o->deleteLater(); if (!m_platformDrag->ownsDragObject())
o->deleteLater();
return result; return result;
} }

View File

@ -241,6 +241,18 @@ QPixmap QPlatformDrag::defaultPixmap()
return *qt_drag_default_pixmap(); 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 #endif // QT_NO_DRAGANDDROP
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -98,6 +98,8 @@ public:
static QPixmap defaultPixmap(); static QPixmap defaultPixmap();
virtual bool ownsDragObject() const;
private: private:
QPlatformDragPrivate *d_ptr; QPlatformDragPrivate *d_ptr;

View File

@ -46,11 +46,36 @@
// //
#include "qopenglfunctions.h" #include "qopenglfunctions.h"
#include <QtCore/qlibrary.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QOpenGLExtensionsPrivate; 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 class Q_GUI_EXPORT QOpenGLExtensions : public QOpenGLFunctions
{ {
Q_DECLARE_PRIVATE(QOpenGLExtensions) Q_DECLARE_PRIVATE(QOpenGLExtensions)
@ -102,6 +127,8 @@ public:
void glGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data); void glGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data);
QOpenGLES3Helper *gles3Helper();
private: private:
static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; } static bool isInitialized(const QOpenGLFunctionsPrivate *d) { return d != 0; }
}; };

View File

@ -3187,65 +3187,105 @@ static void QOPENGLF_APIENTRY qopenglfResolveVertexAttribPointer(GLuint indx, GL
#endif // !QT_OPENGL_ES_2 #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) 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 // It is possible that GL_OES_map_buffer is present, but then having to
// differentiate between glUnmapBufferOES and glUnmapBuffer causes extra // differentiate between glUnmapBufferOES and glUnmapBuffer causes extra
// headache. QOpenGLBuffer::map() will handle this automatically, while direct // headache. QOpenGLBuffer::map() will handle this automatically, while direct
// calls are better off with migrating to the standard glMapBufferRange. // 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."); qWarning("QOpenGLFunctions: glMapBuffer is not available in OpenGL ES 3.0 and up. Use glMapBufferRange instead.");
return 0; return 0;
} else } else {
#endif RESOLVE_FUNC(GLvoid *, ResolveOES, MapBuffer)(target, access);
RESOLVE_FUNC(GLvoid *, ResolveOES, MapBuffer)(target, access); }
} }
static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBufferRange(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access) static GLvoid *QOPENGLF_APIENTRY qopenglfResolveMapBufferRange(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr length, GLbitfield access)
{ {
#ifdef QT_OPENGL_ES_3 if (isES3())
if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) return qgles3Helper()->MapBufferRange(target, offset, length, access);
return ::glMapBufferRange(target, offset, length, access);
else 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) static GLboolean QOPENGLF_APIENTRY qopenglfResolveUnmapBuffer(GLenum target)
{ {
#ifdef QT_OPENGL_ES_3 if (isES3())
if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) return qgles3Helper()->UnmapBuffer(target);
return ::glUnmapBuffer(target);
else 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, static void QOPENGLF_APIENTRY qopenglfResolveBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter) GLbitfield mask, GLenum filter)
{ {
#ifdef QT_OPENGL_ES_3 if (isES3())
if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) qgles3Helper()->BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
::glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
else else
#endif RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer)
RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, BlitFramebuffer) (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
} }
static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLenum target, GLsizei samples, static void QOPENGLF_APIENTRY qopenglfResolveRenderbufferStorageMultisample(GLenum target, GLsizei samples,
GLenum internalFormat, GLenum internalFormat,
GLsizei width, GLsizei height) GLsizei width, GLsizei height)
{ {
#ifdef QT_OPENGL_ES_3 if (isES3())
if (QOpenGLContext::currentContext()->format().majorVersion() >= 3) qgles3Helper()->RenderbufferStorageMultisample(target, samples, internalFormat, width, height);
::glRenderbufferStorageMultisample(target, samples, internalFormat, width, height);
else else
#endif RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample)
RESOLVE_FUNC_VOID(ResolveEXT | ResolveANGLE | ResolveNV, RenderbufferStorageMultisample) (target, samples, internalFormat, width, height);
(target, samples, internalFormat, width, height);
} }
static void QOPENGLF_APIENTRY qopenglfResolveGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data) 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; GetBufferSubData = qopenglfResolveGetBufferSubData;
} }
QOpenGLES3Helper *QOpenGLExtensions::gles3Helper()
{
return qgles3Helper();
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -34,6 +34,7 @@
#include "qopengltexturehelper_p.h" #include "qopengltexturehelper_p.h"
#include <QOpenGLContext> #include <QOpenGLContext>
#include <private/qopenglextensions_p.h>
QT_BEGIN_NAMESPACE 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"))); 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"))); CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3DOES")));
} else { } else {
#ifdef QT_OPENGL_ES_3 QOpenGLContext *ctx = QOpenGLContext::currentContext();
// OpenGL ES 3.0+ has glTexImage3D. if (ctx->isOpenGLES() && ctx->format().majorVersion() >= 3) {
TexImage3D = ::glTexImage3D; // OpenGL ES 3.0+ has glTexImage3D.
TexSubImage3D = ::glTexSubImage3D; QOpenGLES3Helper *es3 = static_cast<QOpenGLExtensions *>(ctx->functions())->gles3Helper();
CompressedTexImage3D = ::glCompressedTexImage3D; TexImage3D = es3->TexImage3D;
CompressedTexSubImage3D = ::glCompressedTexSubImage3D; TexSubImage3D = es3->TexSubImage3D;
#else CompressedTexImage3D = es3->CompressedTexImage3D;
// OpenGL 1.2 CompressedTexSubImage3D = es3->CompressedTexSubImage3D;
TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexImage3D"))); } else {
TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glTexSubImage3D"))); // 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 // OpenGL 1.3
CompressedTexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLenum , GLsizei , GLsizei , GLsizei , GLint , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexImage3D"))); 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"))); CompressedTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLsizei , const GLvoid *)>(context->getProcAddress(QByteArrayLiteral("glCompressedTexSubImage3D")));
#endif }
} }
#ifndef QT_OPENGL_ES_2 #ifndef QT_OPENGL_ES_2

View File

@ -35,12 +35,12 @@
#include <QtCore/private/qobject_p.h> #include <QtCore/private/qobject_p.h>
#include <QtGui/qopenglcontext.h> #include <QtGui/qopenglcontext.h>
#include <QtGui/qopenglfunctions.h>
#include <QtGui/qoffscreensurface.h> #include <QtGui/qoffscreensurface.h>
#include <QtGui/qopenglfunctions_3_0.h> #include <QtGui/qopenglfunctions_3_0.h>
#include <QtGui/qopenglfunctions_3_2_core.h> #include <QtGui/qopenglfunctions_3_2_core.h>
#include <private/qopenglextensions_p.h>
#include <private/qopenglvertexarrayobject_p.h> #include <private/qopenglvertexarrayobject_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -56,16 +56,14 @@ void qtInitializeVertexArrayObjectHelper(QOpenGLVertexArrayObjectHelper *helper,
bool tryARB = true; bool tryARB = true;
if (context->isOpenGLES()) { if (context->isOpenGLES()) {
#ifdef QT_OPENGL_ES_3
if (context->format().majorVersion() >= 3) { if (context->format().majorVersion() >= 3) {
helper->GenVertexArrays = ::glGenVertexArrays; QOpenGLES3Helper *es3 = static_cast<QOpenGLExtensions *>(context->functions())->gles3Helper();
helper->DeleteVertexArrays = ::glDeleteVertexArrays; helper->GenVertexArrays = es3->GenVertexArrays;
helper->BindVertexArray = ::glBindVertexArray; helper->DeleteVertexArrays = es3->DeleteVertexArrays;
helper->IsVertexArray = ::glIsVertexArray; helper->BindVertexArray = es3->BindVertexArray;
helper->IsVertexArray = es3->IsVertexArray;
tryARB = false; tryARB = false;
} else } else if (context->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) {
#endif
if (context->hasExtension(QByteArrayLiteral("GL_OES_vertex_array_object"))) {
helper->GenVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_GenVertexArrays_t>(context->getProcAddress(QByteArrayLiteral("glGenVertexArraysOES"))); 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->DeleteVertexArrays = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_DeleteVertexArrays_t>(context->getProcAddress(QByteArrayLiteral("glDeleteVertexArraysOES")));
helper->BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayOES"))); helper->BindVertexArray = reinterpret_cast<QOpenGLVertexArrayObjectHelper::qt_BindVertexArray_t>(context->getProcAddress(QByteArrayLiteral("glBindVertexArrayOES")));

View File

@ -77,7 +77,12 @@ static inline bool qtransform_equals_no_translate(const QTransform &a, const QTr
// Harfbuzz helper functions // Harfbuzz helper functions
#ifdef QT_ENABLE_HARFBUZZ_NG #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 #endif
Q_STATIC_ASSERT(sizeof(HB_Glyph) == sizeof(glyph_t)); Q_STATIC_ASSERT(sizeof(HB_Glyph) == sizeof(glyph_t));
@ -282,7 +287,7 @@ void *QFontEngine::harfbuzzFont() const
{ {
Q_ASSERT(type() != QFontEngine::Multi); Q_ASSERT(type() != QFontEngine::Multi);
#ifdef QT_ENABLE_HARFBUZZ_NG #ifdef QT_ENABLE_HARFBUZZ_NG
if (useHarfbuzzNG) if (qt_useHarfbuzzNG())
return hb_qt_font_get_for_engine(const_cast<QFontEngine *>(this)); return hb_qt_font_get_for_engine(const_cast<QFontEngine *>(this));
#endif #endif
if (!font_) { if (!font_) {
@ -318,7 +323,7 @@ void *QFontEngine::harfbuzzFace() const
{ {
Q_ASSERT(type() != QFontEngine::Multi); Q_ASSERT(type() != QFontEngine::Multi);
#ifdef QT_ENABLE_HARFBUZZ_NG #ifdef QT_ENABLE_HARFBUZZ_NG
if (useHarfbuzzNG) if (qt_useHarfbuzzNG())
return hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this)); return hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this));
#endif #endif
if (!face_) { if (!face_) {
@ -360,7 +365,7 @@ bool QFontEngine::supportsScript(QChar::Script script) const
#endif #endif
#ifdef QT_ENABLE_HARFBUZZ_NG #ifdef QT_ENABLE_HARFBUZZ_NG
if (useHarfbuzzNG) { if (qt_useHarfbuzzNG()) {
bool ret = false; bool ret = false;
if (hb_face_t *face = hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this))) { if (hb_face_t *face = hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this))) {
hb_tag_t script_tag_1, script_tag_2; hb_tag_t script_tag_1, script_tag_2;

View File

@ -938,7 +938,7 @@ void QTextEngine::shapeLine(const QScriptLine &line)
} }
#ifdef QT_ENABLE_HARFBUZZ_NG #ifdef QT_ENABLE_HARFBUZZ_NG
extern bool useHarfbuzzNG; // defined in qfontengine.cpp extern bool qt_useHarfbuzzNG(); // defined in qfontengine.cpp
#endif #endif
void QTextEngine::shapeText(int item) const void QTextEngine::shapeText(int item) const
@ -1051,7 +1051,7 @@ void QTextEngine::shapeText(int item) const
} }
#ifdef QT_ENABLE_HARFBUZZ_NG #ifdef QT_ENABLE_HARFBUZZ_NG
if (useHarfbuzzNG) if (qt_useHarfbuzzNG())
si.num_glyphs = shapeTextWithHarfbuzzNG(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled); si.num_glyphs = shapeTextWithHarfbuzzNG(si, string, itemLength, fontEngine, itemBoundaries, kerningEnabled);
else else
#endif #endif
@ -1067,7 +1067,7 @@ void QTextEngine::shapeText(int item) const
QGlyphLayout glyphs = shapedGlyphs(&si); QGlyphLayout glyphs = shapedGlyphs(&si);
#ifdef QT_ENABLE_HARFBUZZ_NG #ifdef QT_ENABLE_HARFBUZZ_NG
if (useHarfbuzzNG) if (qt_useHarfbuzzNG())
qt_getJustificationOpportunities(string, itemLength, si, glyphs, logClusters(&si)); qt_getJustificationOpportunities(string, itemLength, si, glyphs, logClusters(&si));
#endif #endif
@ -1616,7 +1616,7 @@ void QTextEngine::itemize() const
} }
#ifdef QT_ENABLE_HARFBUZZ_NG #ifdef QT_ENABLE_HARFBUZZ_NG
analysis = scriptAnalysis.data(); analysis = scriptAnalysis.data();
if (useHarfbuzzNG) { if (qt_useHarfbuzzNG()) {
// ### pretend HB-old behavior for now // ### pretend HB-old behavior for now
for (int i = 0; i < length; ++i) { for (int i = 0; i < length; ++i) {
switch (analysis[i].script) { switch (analysis[i].script) {

View File

@ -138,7 +138,13 @@ init_context:
#endif #endif
break; break;
case QSsl::SslV3: case QSsl::SslV3:
#ifndef OPENSSL_NO_SSL3_METHOD
sslContext->ctx = q_SSL_CTX_new(client ? q_SSLv3_client_method() : q_SSLv3_server_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; break;
case QSsl::SecureProtocols: case QSsl::SecureProtocols:
// SSLv2 and SSLv3 will be disabled by SSL options // SSLv2 and SSLv3 will be disabled by SSL options

View File

@ -1983,6 +1983,7 @@ void QSslSocketPrivate::init()
connectionEncrypted = false; connectionEncrypted = false;
ignoreAllSslErrors = false; ignoreAllSslErrors = false;
shutdown = false; shutdown = false;
pendingClose = false;
// we don't want to clear the ignoreErrorsList, so // we don't want to clear the ignoreErrorsList, so
// that it is possible setting it before connecting // that it is possible setting it before connecting

View File

@ -270,7 +270,9 @@ DEFINEFUNC(SSL_SESSION*, SSL_get_session, const SSL *ssl, ssl, return 0, return)
#ifndef OPENSSL_NO_SSL2 #ifndef OPENSSL_NO_SSL2
DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(const SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return)
#endif #endif
#ifndef OPENSSL_NO_SSL3_METHOD
DEFINEFUNC(const SSL_METHOD *, SSLv3_client_method, DUMMYARG, DUMMYARG, return 0, return) 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 *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(const SSL_METHOD *, TLSv1_client_method, DUMMYARG, DUMMYARG, return 0, return)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L #if OPENSSL_VERSION_NUMBER >= 0x10001000L
@ -280,7 +282,9 @@ DEFINEFUNC(const SSL_METHOD *, TLSv1_2_client_method, DUMMYARG, DUMMYARG, return
#ifndef OPENSSL_NO_SSL2 #ifndef OPENSSL_NO_SSL2
DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(const SSL_METHOD *, SSLv2_server_method, DUMMYARG, DUMMYARG, return 0, return)
#endif #endif
#ifndef OPENSSL_NO_SSL3_METHOD
DEFINEFUNC(const SSL_METHOD *, SSLv3_server_method, DUMMYARG, DUMMYARG, return 0, return) 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 *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(const SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L #if OPENSSL_VERSION_NUMBER >= 0x10001000L
@ -289,11 +293,15 @@ DEFINEFUNC(const SSL_METHOD *, TLSv1_2_server_method, DUMMYARG, DUMMYARG, return
#endif #endif
#else #else
DEFINEFUNC(SSL_METHOD *, SSLv2_client_method, DUMMYARG, DUMMYARG, return 0, return) 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) 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 *, SSLv23_client_method, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(SSL_METHOD *, TLSv1_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) 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) 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 *, SSLv23_server_method, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(SSL_METHOD *, TLSv1_server_method, DUMMYARG, DUMMYARG, return 0, return)
#endif #endif
@ -799,7 +807,9 @@ bool q_resolveOpenSslSymbols()
#ifndef OPENSSL_NO_SSL2 #ifndef OPENSSL_NO_SSL2
RESOLVEFUNC(SSLv2_client_method) RESOLVEFUNC(SSLv2_client_method)
#endif #endif
#ifndef OPENSSL_NO_SSL3_METHOD
RESOLVEFUNC(SSLv3_client_method) RESOLVEFUNC(SSLv3_client_method)
#endif
RESOLVEFUNC(SSLv23_client_method) RESOLVEFUNC(SSLv23_client_method)
RESOLVEFUNC(TLSv1_client_method) RESOLVEFUNC(TLSv1_client_method)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L #if OPENSSL_VERSION_NUMBER >= 0x10001000L
@ -809,7 +819,9 @@ bool q_resolveOpenSslSymbols()
#ifndef OPENSSL_NO_SSL2 #ifndef OPENSSL_NO_SSL2
RESOLVEFUNC(SSLv2_server_method) RESOLVEFUNC(SSLv2_server_method)
#endif #endif
#ifndef OPENSSL_NO_SSL3_METHOD
RESOLVEFUNC(SSLv3_server_method) RESOLVEFUNC(SSLv3_server_method)
#endif
RESOLVEFUNC(SSLv23_server_method) RESOLVEFUNC(SSLv23_server_method)
RESOLVEFUNC(TLSv1_server_method) RESOLVEFUNC(TLSv1_server_method)
#if OPENSSL_VERSION_NUMBER >= 0x10001000L #if OPENSSL_VERSION_NUMBER >= 0x10001000L

View File

@ -611,9 +611,21 @@ QVariant QMacPasteboardMimeFileUri::convertToMime(const QString &mime, QList<QBy
return QVariant(); return QVariant();
QList<QVariant> ret; QList<QVariant> ret;
for (int i = 0; i < data.size(); ++i) { 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")) if (url.host().toLower() == QLatin1String("localhost"))
url.setHost(QString()); url.setHost(QString());
url.setPath(url.path().normalized(QString::NormalizationForm_C)); url.setPath(url.path().normalized(QString::NormalizationForm_C));
ret.append(url); ret.append(url);
} }

View File

@ -676,7 +676,7 @@ static inline bool findPlatformWindowHelper(const POINT &screenPoint, unsigned c
const HWND child = ChildWindowFromPointEx(*hwnd, point, cwexFlags); const HWND child = ChildWindowFromPointEx(*hwnd, point, cwexFlags);
#else #else
Q_UNUSED(cwexFlags) Q_UNUSED(cwexFlags)
const HWND child = ChildWindowFromPoint(*hwnd, point); const HWND child = WindowFromPoint(point);
#endif #endif
if (!child || child == *hwnd) if (!child || child == *hwnd)
return false; return false;

View File

@ -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(); const HDC dc = QWindowsContext::instance()->displayContext();
if (!dc){ if (!dc){
@ -358,28 +358,34 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create()
} }
EGLDisplay display = EGL_NO_DISPLAY; EGLDisplay display = EGL_NO_DISPLAY;
EGLint major = 0;
EGLint minor = 0;
#ifdef EGL_ANGLE_platform_angle_opengl #ifdef EGL_ANGLE_platform_angle_opengl
if (libEGL.eglGetPlatformDisplayEXT && qEnvironmentVariableIsSet("QT_ANGLE_PLATFORM")) { if (libEGL.eglGetPlatformDisplayEXT
&& (preferredType & QWindowsOpenGLTester::AngleBackendMask)) {
const EGLint anglePlatformAttributes[][5] = { 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_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_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 } { 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 EGLint *attributes = 0;
const QByteArray anglePlatform = qgetenv("QT_ANGLE_PLATFORM"); if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11)
if (anglePlatform == "d3d11")
attributes = anglePlatformAttributes[0]; attributes = anglePlatformAttributes[0];
else if (anglePlatform == "d3d9") else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d9)
attributes = anglePlatformAttributes[1]; attributes = anglePlatformAttributes[1];
else if (anglePlatform == "warp") else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11Warp)
attributes = anglePlatformAttributes[2]; attributes = anglePlatformAttributes[2];
else if (attributes) {
qCWarning(lcQpaGl) << "Invalid value set for QT_ANGLE_PLATFORM:" << anglePlatform;
if (attributes)
display = libEGL.eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, 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) if (display == EGL_NO_DISPLAY)
display = libEGL.eglGetDisplay((EGLNativeDisplayType)dc); display = libEGL.eglGetDisplay((EGLNativeDisplayType)dc);
if (!display) { if (!display) {
@ -387,9 +393,7 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create()
return 0; return 0;
} }
EGLint major; if (!major && !libEGL.eglInitialize(display, &major, &minor)) {
EGLint minor;
if (!libEGL.eglInitialize(display, &major, &minor)) {
int err = libEGL.eglGetError(); int err = libEGL.eglGetError();
qWarning("%s: Could not initialize EGL display: error 0x%x\n", Q_FUNC_INFO, err); qWarning("%s: Could not initialize EGL display: error 0x%x\n", Q_FUNC_INFO, err);
if (err == 0x3001) if (err == 0x3001)

View File

@ -35,6 +35,7 @@
#define QWINDOWSEGLCONTEXT_H #define QWINDOWSEGLCONTEXT_H
#include "qwindowsopenglcontext.h" #include "qwindowsopenglcontext.h"
#include "qwindowsopengltester.h"
#include <EGL/egl.h> #include <EGL/egl.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -250,7 +251,7 @@ class QWindowsEGLStaticContext : public QWindowsStaticOpenGLContext
Q_DISABLE_COPY(QWindowsEGLStaticContext) Q_DISABLE_COPY(QWindowsEGLStaticContext)
public: public:
static QWindowsEGLStaticContext *create(); static QWindowsEGLStaticContext *create(QWindowsOpenGLTester::Renderers preferredType);
~QWindowsEGLStaticContext(); ~QWindowsEGLStaticContext();
EGLDisplay display() const { return m_display; } EGLDisplay display() const { return m_display; }

View File

@ -209,7 +209,7 @@ void QWindowsInputContext::setFocusObject(QObject *object)
imeNotifyCancelComposition(m_compositionContext.hwnd); imeNotifyCancelComposition(m_compositionContext.hwnd);
const QWindow *window = QGuiApplication::focusWindow(); const QWindow *window = QGuiApplication::focusWindow();
if (object && window) { if (object && window && window->handle()) {
QWindowsWindow *platformWindow = QWindowsWindow::baseWindowOf(window); QWindowsWindow *platformWindow = QWindowsWindow::baseWindowOf(window);
if (inputMethodAccepted()) { if (inputMethodAccepted()) {
// Re-enable IME by associating default context saved on first disabling. // Re-enable IME by associating default context saved on first disabling.

View File

@ -130,7 +130,6 @@ struct QWindowsIntegrationPrivate
{ {
explicit QWindowsIntegrationPrivate(const QStringList &paramList); explicit QWindowsIntegrationPrivate(const QStringList &paramList);
~QWindowsIntegrationPrivate(); ~QWindowsIntegrationPrivate();
bool ensureStaticOpenGLContext();
unsigned m_options; unsigned m_options;
QWindowsContext m_context; QWindowsContext m_context;
@ -266,7 +265,9 @@ bool QWindowsIntegration::hasCapability(QPlatformIntegration::Capability cap) co
case OpenGL: case OpenGL:
return true; return true;
case ThreadedOpenGL: 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 #endif // !QT_NO_OPENGL
case WindowMasks: case WindowMasks:
return true; return true;
@ -312,11 +313,6 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const
QWindowSystemInterface::handleGeometryChange(window, QWindowsScaling::mapFromNative(obtained.geometry)); QWindowSystemInterface::handleGeometryChange(window, QWindowsScaling::mapFromNative(obtained.geometry));
} }
#ifndef QT_NO_OPENGL
d->ensureStaticOpenGLContext();
obtained.staticOpenGLContext = d->m_staticOpenGLContext;
#endif // QT_NO_OPENGL
return obtained; return obtained;
} }
@ -328,61 +324,65 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
} }
#ifndef QT_NO_OPENGL #ifndef QT_NO_OPENGL
static QWindowsStaticOpenGLContext *q_staticOpenGLContext = 0;
QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::doCreate()
{
#if defined(QT_OPENGL_DYNAMIC)
QWindowsOpenGLTester::Renderer requestedRenderer = QWindowsOpenGLTester::requestedRenderer();
switch (requestedRenderer) {
case QWindowsOpenGLTester::DesktopGl:
if (QWindowsStaticOpenGLContext *glCtx = QOpenGLStaticContext::create())
return glCtx;
qCWarning(lcQpaGl, "System OpenGL failed. Falling back to Software OpenGL.");
return QOpenGLStaticContext::create(true);
// If ANGLE is requested, use it, don't try anything else.
case QWindowsOpenGLTester::AngleRendererD3d9:
case QWindowsOpenGLTester::AngleRendererD3d11:
case QWindowsOpenGLTester::AngleRendererD3d11Warp:
return QWindowsEGLStaticContext::create(requestedRenderer);
case QWindowsOpenGLTester::Gles:
return QWindowsEGLStaticContext::create(QWindowsOpenGLTester::supportedGlesRenderers());
case QWindowsOpenGLTester::SoftwareRasterizer:
if (QWindowsStaticOpenGLContext *swCtx = QOpenGLStaticContext::create(true))
return swCtx;
qCWarning(lcQpaGl, "Software OpenGL failed. Falling back to system OpenGL.");
if (QWindowsOpenGLTester::supportedRenderers() & QWindowsOpenGLTester::DesktopGl)
return QOpenGLStaticContext::create();
return Q_NULLPTR;
default:
break;
}
const QWindowsOpenGLTester::Renderers supportedRenderers = QWindowsOpenGLTester::supportedRenderers();
if (supportedRenderers & QWindowsOpenGLTester::DesktopGl) {
if (QWindowsStaticOpenGLContext *glCtx = QOpenGLStaticContext::create())
return glCtx;
}
if (QWindowsOpenGLTester::Renderers glesRenderers = supportedRenderers & QWindowsOpenGLTester::GlesMask) {
if (QWindowsEGLStaticContext *eglCtx = QWindowsEGLStaticContext::create(glesRenderers))
return eglCtx;
}
return QOpenGLStaticContext::create(true);
#elif defined(QT_OPENGL_ES_2)
QWindowsOpenGLTester::Renderers glesRenderers = QWindowsOpenGLTester::requestedGlesRenderer();
if (glesRenderers == QWindowsOpenGLTester::InvalidRenderer)
glesRenderers = QWindowsOpenGLTester::supportedGlesRenderers();
return QWindowsEGLStaticContext::create(glesRenderers);
#elif !defined(QT_NO_OPENGL)
return QOpenGLStaticContext::create();
#endif
}
QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::create() QWindowsStaticOpenGLContext *QWindowsStaticOpenGLContext::create()
{ {
QWindowsStaticOpenGLContext *ctx = 0; return QWindowsStaticOpenGLContext::doCreate();
#if defined(QT_OPENGL_DYNAMIC)
const QByteArray requested = qgetenv("QT_OPENGL"); // angle, desktop, software
const bool angleRequested = QCoreApplication::testAttribute(Qt::AA_UseOpenGLES) || requested == "angle";
const bool desktopRequested = QCoreApplication::testAttribute(Qt::AA_UseDesktopOpenGL) || requested == "desktop";
const bool softwareRequested = QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL) || requested == "software";
// If ANGLE is requested, use it, don't try anything else.
if (angleRequested) {
ctx = QWindowsEGLStaticContext::create();
} else {
// If opengl32.dll seems to be OpenGL 2.x capable, or desktop OpenGL is requested, use it.
if (!softwareRequested && (desktopRequested || QWindowsOpenGLTester::testDesktopGL()))
ctx = QOpenGLStaticContext::create();
// If failed and desktop OpenGL is not explicitly requested, try ANGLE.
if (!ctx && !desktopRequested && !softwareRequested)
ctx = QWindowsEGLStaticContext::create();
// Try software.
if (!ctx) {
ctx = QOpenGLStaticContext::create(true);
// If software was explicitly requested but failed, try the regular one.
if (!ctx && softwareRequested && QWindowsOpenGLTester::testDesktopGL()) {
qCWarning(lcQpaGl, "Software OpenGL failed. Falling back to system OpenGL.");
ctx = QOpenGLStaticContext::create();
}
}
}
#elif defined(QT_OPENGL_ES_2)
ctx = QWindowsEGLStaticContext::create();
#elif !defined(QT_NO_OPENGL)
ctx = QOpenGLStaticContext::create();
#endif
q_staticOpenGLContext = ctx;
return ctx;
}
bool QWindowsIntegrationPrivate::ensureStaticOpenGLContext()
{
if (m_staticOpenGLContext.isNull())
m_staticOpenGLContext = QSharedPointer<QWindowsStaticOpenGLContext>(QWindowsStaticOpenGLContext::create());
return !m_staticOpenGLContext.isNull();
} }
QPlatformOpenGLContext *QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const QPlatformOpenGLContext *QWindowsIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{ {
qCDebug(lcQpaGl) << __FUNCTION__ << context->format(); qCDebug(lcQpaGl) << __FUNCTION__ << context->format();
if (d->ensureStaticOpenGLContext()) { if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext()) {
QScopedPointer<QWindowsOpenGLContext> result(d->m_staticOpenGLContext->createContext(context)); QScopedPointer<QWindowsOpenGLContext> result(staticOpenGLContext->createContext(context));
if (result->isValid()) if (result->isValid())
return result.take(); return result.take();
} }
@ -396,13 +396,18 @@ QOpenGLContext::OpenGLModuleType QWindowsIntegration::openGLModuleType()
#elif !defined(QT_OPENGL_DYNAMIC) #elif !defined(QT_OPENGL_DYNAMIC)
return QOpenGLContext::LibGL; return QOpenGLContext::LibGL;
#else #else
return d->ensureStaticOpenGLContext() ? d->m_staticOpenGLContext->moduleType() : QOpenGLContext::LibGL; if (const QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
return staticOpenGLContext->moduleType();
return QOpenGLContext::LibGL;
#endif #endif
} }
QWindowsStaticOpenGLContext *QWindowsIntegration::staticOpenGLContext() 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 #endif // !QT_NO_OPENGL

View File

@ -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 ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the plugins of the Qt Toolkit. ** This file is part of the plugins of the Qt Toolkit.
@ -35,6 +35,7 @@
#include "qwindowswindow.h" #include "qwindowswindow.h"
#include "qwindowscontext.h" #include "qwindowscontext.h"
#include "qwindowsopenglcontext.h" #include "qwindowsopenglcontext.h"
#include "qwindowsopengltester.h"
#include "qwindowsintegration.h" #include "qwindowsintegration.h"
#include "qwindowsmime.h" #include "qwindowsmime.h"
@ -216,4 +217,9 @@ int QWindowsNativeInterface::registerMimeType(const QString &mimeType)
return QWindowsMime::registerMimeType(mimeType); return QWindowsMime::registerMimeType(mimeType);
} }
QVariant QWindowsNativeInterface::gpu() const
{
return GpuDescription::detect().toVariant();
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -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 ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the plugins of the Qt Toolkit. ** This file is part of the plugins of the Qt Toolkit.
@ -58,6 +58,7 @@ class QWindowsNativeInterface : public QPlatformNativeInterface
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose) Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose)
Q_PROPERTY(QVariant gpu READ gpu STORED false)
public: public:
void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
@ -81,6 +82,8 @@ public:
bool asyncExpose() const; bool asyncExpose() const;
void setAsyncExpose(bool value); void setAsyncExpose(bool value);
QVariant gpu() const;
QVariantMap windowProperties(QPlatformWindow *window) const Q_DECL_OVERRIDE; 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 Q_DECL_OVERRIDE;
QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const Q_DECL_OVERRIDE; QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const Q_DECL_OVERRIDE;

View File

@ -58,6 +58,9 @@ public:
// reimplement these. // reimplement these.
virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/) { return 0; } virtual void *createWindowSurface(void * /*nativeWindow*/, void * /*nativeConfig*/) { return 0; }
virtual void destroyWindowSurface(void * /*nativeSurface*/) { } virtual void destroyWindowSurface(void * /*nativeSurface*/) { }
private:
static QWindowsStaticOpenGLContext *doCreate();
}; };
class QWindowsOpenGLContext : public QPlatformOpenGLContext class QWindowsOpenGLContext : public QPlatformOpenGLContext

View File

@ -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 ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the plugins of the Qt Toolkit. ** This file is part of the plugins of the Qt Toolkit.
@ -32,13 +32,231 @@
****************************************************************************/ ****************************************************************************/
#include "qwindowsopengltester.h" #include "qwindowsopengltester.h"
#include "qt_windows.h"
#include "qwindowscontext.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 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() bool QWindowsOpenGLTester::testDesktopGL()
{ {
#ifndef Q_OS_WINCE
HMODULE lib = 0; HMODULE lib = 0;
HWND wnd = 0; HWND wnd = 0;
HDC dc = 0; HDC dc = 0;
@ -109,6 +327,37 @@ bool QWindowsOpenGLTester::testDesktopGL()
goto cleanup; goto cleanup;
// Now that there is finally a context current, try doing something useful. // 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")) { if (WGL_GetProcAddress("glCreateShader")) {
result = true; result = true;
qCDebug(lcQpaGl, "OpenGL 2.0 entry points available"); 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. // No FreeLibrary. Some implementations, Mesa in particular, deadlock when trying to unload.
return result; return result;
#else // !Q_OS_WINCE
return false;
#endif
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -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 ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the plugins of the Qt Toolkit. ** 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 <qtwindowsglobal.h>
#include <QtCore/QByteArray>
#include <QtCore/QFlags>
QT_BEGIN_NAMESPACE 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 class QWindowsOpenGLTester
{ {
public: 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(); static bool testDesktopGL();
}; };
Q_DECLARE_OPERATORS_FOR_FLAGS(QWindowsOpenGLTester::Renderers)
QT_END_NAMESPACE QT_END_NAMESPACE
#endif // QWINDOWSOPENGLTESTER_H

View File

@ -37,6 +37,7 @@
#include "qwindowsdrag.h" #include "qwindowsdrag.h"
#include "qwindowsscreen.h" #include "qwindowsscreen.h"
#include "qwindowsscaling.h" #include "qwindowsscaling.h"
#include "qwindowsintegration.h"
#ifdef QT_NO_CURSOR #ifdef QT_NO_CURSOR
# include "qwindowscursor.h" # include "qwindowscursor.h"
#endif #endif
@ -555,8 +556,12 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
if (flags & Qt::WindowSystemMenuHint) if (flags & Qt::WindowSystemMenuHint)
style |= WS_SYSMENU; style |= WS_SYSMENU;
else if (dialog) { else if (dialog) {
style |= WS_SYSMENU | WS_BORDER; // QTBUG-2027, dialogs without system menu. // QTBUG-2027, dialogs without system menu.
exStyle |= WS_EX_DLGMODALFRAME; style |= WS_SYSMENU;
if (!(flags & Qt::FramelessWindowHint)) {
style |= WS_BORDER;
exStyle |= WS_EX_DLGMODALFRAME;
}
} }
if (flags & Qt::WindowMinimizeButtonHint) if (flags & Qt::WindowMinimizeButtonHint)
style |= WS_MINIMIZEBOX; style |= WS_MINIMIZEBOX;
@ -995,7 +1000,8 @@ void QWindowsWindow::destroyWindow()
setDropSiteEnabled(false); setDropSiteEnabled(false);
#ifndef QT_NO_OPENGL #ifndef QT_NO_OPENGL
if (m_surface) { if (m_surface) {
m_data.staticOpenGLContext->destroyWindowSurface(m_surface); if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
staticOpenGLContext->destroyWindowSurface(m_surface);
m_surface = 0; m_surface = 0;
} }
#endif #endif
@ -2340,8 +2346,10 @@ void *QWindowsWindow::surface(void *nativeConfig)
#ifdef QT_NO_OPENGL #ifdef QT_NO_OPENGL
return 0; return 0;
#else #else
if (!m_surface) if (!m_surface) {
m_surface = m_data.staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig); if (QWindowsStaticOpenGLContext *staticOpenGLContext = QWindowsIntegration::staticOpenGLContext())
m_surface = staticOpenGLContext->createWindowSurface(m_data.hwnd, nativeConfig);
}
return m_surface; return m_surface;
#endif #endif

View File

@ -107,9 +107,6 @@ struct QWindowsWindowData
QMargins customMargins; // User-defined, additional frame for NCCALCSIZE QMargins customMargins; // User-defined, additional frame for NCCALCSIZE
HWND hwnd; HWND hwnd;
bool embedded; bool embedded;
#ifndef QT_NO_OPENGL
QSharedPointer<QWindowsStaticOpenGLContext> staticOpenGLContext;
#endif // QT_NO_OPENGL
static QWindowsWindowData create(const QWindow *w, static QWindowsWindowData create(const QWindow *w,
const QWindowsWindowData &parameters, const QWindowsWindowData &parameters,

View File

@ -40,7 +40,8 @@ SOURCES += \
$$PWD/qwindowsservices.cpp \ $$PWD/qwindowsservices.cpp \
$$PWD/qwindowsnativeimage.cpp \ $$PWD/qwindowsnativeimage.cpp \
$$PWD/qwindowsnativeinterface.cpp \ $$PWD/qwindowsnativeinterface.cpp \
$$PWD/qwindowsscaling.cpp $$PWD/qwindowsscaling.cpp \
$$PWD/qwindowsopengltester.cpp
HEADERS += \ HEADERS += \
$$PWD/qwindowswindow.h \ $$PWD/qwindowswindow.h \
@ -66,9 +67,8 @@ HEADERS += \
$$PWD/qplatformfunctions_wince.h \ $$PWD/qplatformfunctions_wince.h \
$$PWD/qwindowsnativeimage.h \ $$PWD/qwindowsnativeimage.h \
$$PWD/qwindowsnativeinterface.h \ $$PWD/qwindowsnativeinterface.h \
$$PWD/qwindowsscaling.h $$PWD/qwindowsscaling.h \
$$PWD/qwindowsopengltester.h
!wince: HEADERS += $$PWD/qwindowsopengltester.h
INCLUDEPATH += $$PWD INCLUDEPATH += $$PWD
@ -84,8 +84,7 @@ contains(QT_CONFIG, opengles2) {
# Dynamic GL needs both WGL and EGL # Dynamic GL needs both WGL and EGL
contains(QT_CONFIG,dynamicgl) { contains(QT_CONFIG,dynamicgl) {
SOURCES += $$PWD/qwindowseglcontext.cpp \ SOURCES += $$PWD/qwindowseglcontext.cpp
$$PWD/qwindowsopengltester.cpp
HEADERS += $$PWD/qwindowseglcontext.h HEADERS += $$PWD/qwindowseglcontext.h
} }

View File

@ -999,6 +999,8 @@ void QXcbDrag::handleFinished(const xcb_client_message_event_t *event)
if (at != -1) { if (at != -1) {
Transaction t = transactions.takeAt(at); Transaction t = transactions.takeAt(at);
if (t.drag)
t.drag->deleteLater();
// QDragManager *manager = QDragManager::self(); // QDragManager *manager = QDragManager::self();
// Window target = current_target; // 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) QXcbDropData::QXcbDropData(QXcbDrag *d)
: QXcbMime(), : QXcbMime(),
drag(d) drag(d)

View File

@ -70,12 +70,11 @@ public:
virtual QMimeData *platformDropData(); virtual QMimeData *platformDropData();
void startDrag() Q_DECL_OVERRIDE;
void startDrag(); void cancel() Q_DECL_OVERRIDE;
void cancel(); void move(const QMouseEvent *me) Q_DECL_OVERRIDE;
void move(const QMouseEvent *me); void drop(const QMouseEvent *me) Q_DECL_OVERRIDE;
void drop(const QMouseEvent *me); void endDrag() Q_DECL_OVERRIDE;
void endDrag();
void handleEnter(QWindow *window, const xcb_client_message_event_t *event); void handleEnter(QWindow *window, const xcb_client_message_event_t *event);
void handlePosition(QWindow *w, 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); void handleFinished(const xcb_client_message_event_t *event);
bool dndEnable(QXcbWindow *win, bool on); bool dndEnable(QXcbWindow *win, bool on);
bool ownsDragObject() const Q_DECL_OVERRIDE;
void updatePixmap(); void updatePixmap();
xcb_timestamp_t targetTime() { return target_time; } xcb_timestamp_t targetTime() { return target_time; }

View File

@ -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 ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the tools applications of the Qt Toolkit. ** This file is part of the tools applications of the Qt Toolkit.
@ -67,7 +67,7 @@ static const char docTypeHeader[] =
#define PROGRAMNAME "qdbuscpp2xml" #define PROGRAMNAME "qdbuscpp2xml"
#define PROGRAMVERSION "0.2" #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 QString outputFile;
static int flags; static int flags;

View File

@ -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 ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the tools applications of the Qt Toolkit. ** This file is part of the tools applications of the Qt Toolkit.
@ -49,7 +49,7 @@
#define PROGRAMNAME "qdbusxml2cpp" #define PROGRAMNAME "qdbusxml2cpp"
#define PROGRAMVERSION "0.8" #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" #define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"

View File

@ -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 ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the documentation of the Qt Toolkit. ** This file is part of the documentation of the Qt Toolkit.
@ -3789,7 +3789,7 @@
<author>Qt Development Frameworks</author> <author>Qt Development Frameworks</author>
<publisher>Qt Project</publisher> <publisher>Qt Project</publisher>
<copyright> <copyright>
<copyryear year="2014"/> <copyryear year="2015"/>
<copyrholder>Qt Project</copyrholder> <copyrholder>Qt Project</copyrholder>
</copyright> </copyright>
<permissions view="all"/> <permissions view="all"/>

View File

@ -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 ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the documentation of the Qt Toolkit. ** 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.author = Qt Development Frameworks
dita.metadata.default.permissions = all dita.metadata.default.permissions = all
dita.metadata.default.publisher = Qt Project 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.copyrholder = Qt Project
dita.metadata.default.audience = programmer dita.metadata.default.audience = programmer
\endcode \endcode

View File

@ -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 ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the QLALR module of the Qt Toolkit. ** This file is part of the QLALR module of the Qt Toolkit.
@ -47,7 +47,7 @@ QString CppGenerator::copyrightHeader() const
return QLatin1String( return QLatin1String(
"/****************************************************************************\n" "/****************************************************************************\n"
"**\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" "** Contact: http://www.qt-project.org/legal\n"
"**\n" "**\n"
"** This file is part of the Qt Toolkit.\n" "** This file is part of the Qt Toolkit.\n"

View File

@ -47,6 +47,7 @@
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
# include <fcntl.h> # include <fcntl.h>
# include <io.h> # include <io.h>
# include <stdio.h>
#endif // Q_OS_WIN #endif // Q_OS_WIN
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -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 ** Contact: http://www.qt-project.org/legal
** **
** This file is part of the QtWidgets module of the Qt Toolkit. ** 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 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> " "<p>Qt is a Digia product developed as an open source project. See <a href=\"http://%3/\">%3</a> "
"for more information.</p>" "for more information.</p>"
).arg(QStringLiteral("2014"), ).arg(QStringLiteral("2015"),
QStringLiteral("qt.io/licensing"), QStringLiteral("qt.io/licensing"),
QStringLiteral("qt.io")); QStringLiteral("qt.io"));
QMessageBox *msgBox = new QMessageBox(parent); QMessageBox *msgBox = new QMessageBox(parent);

View File

@ -3320,12 +3320,10 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
QWidget* w = static_cast<QWidget *>(receiver); QWidget* w = static_cast<QWidget *>(receiver);
QWheelEvent* wheel = static_cast<QWheelEvent*>(e); QWheelEvent* wheel = static_cast<QWheelEvent*>(e);
// QTBUG-40656, combo and other popups should close when the main window gets a wheel event. // QTBUG-40656, QTBUG-42731: ignore wheel events when a popup (QComboBox) is open.
while (QWidget *popup = QApplication::activePopupWidget()) { if (const QWidget *popup = QApplication::activePopupWidget()) {
if (w->window() != popup) if (w->window() != popup)
popup->close(); return true;
else
break;
} }
QPoint relpos = wheel->pos(); QPoint relpos = wheel->pos();

View File

@ -1675,13 +1675,14 @@ void QMacStylePrivate::getSliderInfo(QStyle::ComplexControl cc, const QStyleOpti
else else
tdi->max = 10 * slider->rect.height(); 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; int endsCorrection = usePlainKnob ? 25 : 10;
tdi->value = (tdi->max + 2 * endsCorrection) * (slider->sliderPosition - slider->minimum) tdi->value = (tdi->max + 2 * endsCorrection) * (slider->sliderPosition - slider->minimum) / range - endsCorrection;
/ (slider->maximum - slider->minimum) - endsCorrection;
} else { } else {
tdi->value = (tdi->max + 30) * (slider->sliderPosition - slider->minimum) tdi->value = (tdi->max + 30) * (slider->sliderPosition - slider->minimum) / range - 20;
/ (slider->maximum - slider->minimum) - 20;
} }
} }
tdi->attributes = kThemeTrackShowThumb; tdi->attributes = kThemeTrackShowThumb;

View File

@ -70,6 +70,8 @@ private slots:
void QTBUG_4796_data(); void QTBUG_4796_data();
void QTBUG_4796(); void QTBUG_4796();
void QTBUG43352_failedSetPermissions();
public: public:
}; };
@ -419,5 +421,17 @@ void tst_QTemporaryDir::QTBUG_4796() // unicode support
cleaner.reset(); 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) QTEST_MAIN(tst_QTemporaryDir)
#include "tst_qtemporarydir.moc" #include "tst_qtemporarydir.moc"

View File

@ -96,6 +96,7 @@ private slots:
void changeSourceData_data(); void changeSourceData_data();
void changeSourceData(); void changeSourceData();
void changeSourceDataKeepsStableSorting_qtbug1548(); void changeSourceDataKeepsStableSorting_qtbug1548();
void resortingDoesNotBreakTreeModels();
void sortFilterRole(); void sortFilterRole();
void selectionFilteredOut(); void selectionFilteredOut();
void match_data(); void match_data();
@ -2029,6 +2030,8 @@ static void checkSortedTableModel(const QAbstractItemModel *model, const QString
void tst_QSortFilterProxyModel::changeSourceDataKeepsStableSorting_qtbug1548() void tst_QSortFilterProxyModel::changeSourceDataKeepsStableSorting_qtbug1548()
{ {
QSKIP("This test will fail, see QTBUG-1548");
// Check that emitting dataChanged from the source model // Check that emitting dataChanged from the source model
// for a change of a role which is not the sorting role // 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, // 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); 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) QTEST_MAIN(tst_QSortFilterProxyModel)
#include "tst_qsortfilterproxymodel.moc" #include "tst_qsortfilterproxymodel.moc"

View File

@ -63,17 +63,23 @@ void tst_QString_macTypes()
} }
// QString <-> NSString // QString <-> NSString
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
QString qtString("test string"); QString qtString("test string");
const NSString *nsString = qtString.toNSString(); const NSString *nsString = qtString.toNSString();
QCOMPARE(QString::fromNSString(nsString), qtString); QCOMPARE(QString::fromNSString(nsString), qtString);
[nsString release];
[pool release];
} }
{ {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
QString qtString("test string"); QString qtString("test string");
const NSString *nsString = qtString.toNSString(); const NSString *nsString = qtString.toNSString();
QString qtStringCopy(qtString); QString qtStringCopy(qtString);
qtString = qtString.toUpper(); // modify qtString = qtString.toUpper(); // modify
QCOMPARE(QString::fromNSString(nsString), qtStringCopy); QCOMPARE(QString::fromNSString(nsString), qtStringCopy);
[nsString release];
[pool release];
} }
} }

View File

@ -0,0 +1,3 @@
StartDocument( )
Invalid( processingInstructionTarget="xml_" )
ERROR: Invalid XML character.

View File

@ -0,0 +1,2 @@
Invalid( )
ERROR: Premature end of document.

Binary file not shown.

View File

@ -0,0 +1,2 @@
Invalid( )
ERROR: Premature end of document.

Binary file not shown.

View File

@ -0,0 +1,3 @@
StartDocument( )
Invalid( )
ERROR: Expected '[a-zA-Z]', but got ' '.

Binary file not shown.

View File

@ -0,0 +1,2 @@
Invalid( )
ERROR: Expected 'version', but got ''.

Binary file not shown.

View File

@ -0,0 +1,2 @@
Invalid( )
ERROR: Expected 'version', but got ''.

Binary file not shown.

View File

@ -0,0 +1,2 @@
Invalid( )
ERROR: Expected 'version', but got ''.

Binary file not shown.

View File

@ -0,0 +1,2 @@
Invalid( )
ERROR: Expected 'version', but got ''.

Binary file not shown.

View File

@ -0,0 +1,3 @@
StartDocument( documentVersion="1.0" )
Invalid( )
ERROR: Start tag expected.

Binary file not shown.

View File

@ -772,7 +772,7 @@ void tst_QSslSocket::peerCertificateChain()
QVERIFY(socket->waitForDisconnected()); QVERIFY(socket->waitForDisconnected());
// connect again to a different server // connect again to a different server
socket->connectToHostEncrypted("qt-project.org", 443); socket->connectToHostEncrypted("www.qt.io", 443);
socket->ignoreSslErrors(); socket->ignoreSslErrors();
QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode); QCOMPARE(socket->mode(), QSslSocket::UnencryptedMode);
QVERIFY(socket->peerCertificateChain().isEmpty()); QVERIFY(socket->peerCertificateChain().isEmpty());

View File

@ -185,7 +185,7 @@ void tst_QSslSocket_onDemandCertificates_member::proxyAuthenticationRequired(con
void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMethods() void tst_QSslSocket_onDemandCertificates_member::onDemandRootCertLoadingMemberMethods()
{ {
QString host("qt-project.org"); QString host("www.qt.io");
// not using any root certs -> should not work // not using any root certs -> should not work
QSslSocketPtr socket2 = newSocket(); QSslSocketPtr socket2 = newSocket();

View File

@ -181,7 +181,7 @@ void tst_QSslSocket_onDemandCertificates_static::proxyAuthenticationRequired(con
void tst_QSslSocket_onDemandCertificates_static::onDemandRootCertLoadingStaticMethods() void tst_QSslSocket_onDemandCertificates_static::onDemandRootCertLoadingStaticMethods()
{ {
QString host("qt-project.org"); QString host("www.qt.io");
// not using any root certs -> should not work // not using any root certs -> should not work
QSslSocket::setDefaultCaCertificates(QList<QSslCertificate>()); QSslSocket::setDefaultCaCertificates(QList<QSslCertificate>());

View File

@ -124,7 +124,7 @@ private slots:
void pixmapIcon(); void pixmapIcon();
void mouseWheel_data(); void mouseWheel_data();
void mouseWheel(); void mouseWheel();
void wheelClosingPopup(); void popupWheelHandling();
void layoutDirection(); void layoutDirection();
void itemListPosition(); void itemListPosition();
void separatorItem_data(); 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; QScrollArea scrollArea;
scrollArea.move(300, 300); scrollArea.move(300, 300);
QWidget *widget = new QWidget; QWidget *widget = new QWidget;
@ -2058,9 +2058,12 @@ void tst_QComboBox::wheelClosingPopup()
QVERIFY(QTest::qWaitForWindowExposed(&scrollArea)); QVERIFY(QTest::qWaitForWindowExposed(&scrollArea));
comboBox->showPopup(); comboBox->showPopup();
QTRY_VERIFY(comboBox->view() && comboBox->view()->isVisible()); QTRY_VERIFY(comboBox->view() && comboBox->view()->isVisible());
const QPoint popupPos = comboBox->view()->pos();
QWheelEvent event(QPointF(10, 10), WHEEL_DELTA, Qt::NoButton, Qt::NoModifier); QWheelEvent event(QPointF(10, 10), WHEEL_DELTA, Qt::NoButton, Qt::NoModifier);
QVERIFY(QCoreApplication::sendEvent(scrollArea.windowHandle(), &event)); 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() void tst_QComboBox::layoutDirection()