summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2018-02-16 08:54:58 +0100
committerLiang Qi <liang.qi@qt.io>2018-02-16 08:54:58 +0100
commit942ab490724fcc9544e786e5783718e1a07aa50b (patch)
treefeb7d3ff716edb37b2ca60e33c05adf8777bd964 /src
parent0fb8271a467202990c90321066e40faed640a7a8 (diff)
parent24adaa9a742e6f95ff897d0eb9a2bce0527dd042 (diff)
Merge remote-tracking branch 'origin/5.11' into dev
Conflicts: src/corelib/tools/tools.pri Change-Id: I705630f9cecbf0ce51a22fc6116b8c49611259e9
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/angle/src/libANGLE/Debug2.cpp303
-rw-r--r--src/3rdparty/angle/src/libANGLE/Debug2.h120
-rw-r--r--src/3rdparty/libjpeg/qt_attribution.json2
-rw-r--r--src/3rdparty/libjpeg/src/ChangeLog.md44
-rw-r--r--src/3rdparty/libjpeg/src/jcdctmgr.c2
-rw-r--r--src/3rdparty/libjpeg/src/jdapistd.c33
-rw-r--r--src/3rdparty/libjpeg/src/jdcolor.c2
-rw-r--r--src/3rdparty/libjpeg/src/jdmerge.c2
-rw-r--r--src/3rdparty/pcre2/pcre2.pro2
-rw-r--r--src/3rdparty/sqlite/qt_attribution.json2
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java27
-rw-r--r--src/angle/src/common/gles_common.pri12
-rw-r--r--src/concurrent/concurrent.pro2
-rw-r--r--src/concurrent/doc/src/qtconcurrent-index.qdoc11
-rw-r--r--src/corelib/corelib.pro2
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_concurrent_qthreadpool.cpp2
-rw-r--r--src/corelib/doc/src/qtcore-index.qdoc7
-rw-r--r--src/corelib/global/qfloat16_f16c.c6
-rw-r--r--src/corelib/global/qglobal.cpp6
-rw-r--r--src/corelib/global/qlogging.cpp4
-rw-r--r--src/corelib/global/qnumeric_p.h2
-rw-r--r--src/corelib/global/qoperatingsystemversion.cpp4
-rw-r--r--src/corelib/global/qrandom.cpp2
-rw-r--r--src/corelib/io/QTEMPORARYFILE_LICENSE.txt26
-rw-r--r--src/corelib/io/io.pri2
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp5
-rw-r--r--src/corelib/io/qloggingregistry.cpp10
-rw-r--r--src/corelib/io/qprocess_win.cpp3
-rw-r--r--src/corelib/io/qsavefile.cpp2
-rw-r--r--src/corelib/io/qsettings.cpp5
-rw-r--r--src/corelib/io/qstandardpaths_android.cpp15
-rw-r--r--src/corelib/io/qt_attribution.json15
-rw-r--r--src/corelib/io/qtemporaryfile.cpp11
-rw-r--r--src/corelib/io/qtemporaryfile_p.h7
-rw-r--r--src/corelib/io/qurlrecode.cpp4
-rw-r--r--src/corelib/json/qjsonarray.cpp1238
-rw-r--r--src/corelib/kernel/kernel.pri2
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp46
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp23
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h1
-rw-r--r--src/corelib/kernel/qeventloop.cpp14
-rw-r--r--src/corelib/kernel/qobject.cpp8
-rw-r--r--src/corelib/kernel/qsocketnotifier.cpp4
-rw-r--r--src/corelib/plugin/qlibrary.cpp29
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp35
-rw-r--r--src/corelib/thread/qthread_p.h4
-rw-r--r--src/corelib/thread/qthread_unix.cpp29
-rw-r--r--src/corelib/thread/qthread_win.cpp20
-rw-r--r--src/corelib/tools/UNICODE_LICENSE.txt (renamed from src/corelib/tools/CLDR_LICENSE.txt)2
-rw-r--r--src/corelib/tools/qarraydataops.h3
-rw-r--r--src/corelib/tools/qstring.cpp41
-rw-r--r--src/corelib/tools/qt_attribution.json40
-rw-r--r--src/corelib/tools/qtimezone.cpp8
-rw-r--r--src/corelib/tools/qtimezoneprivate_p.h6
-rw-r--r--src/corelib/tools/qvarlengtharray.h4
-rw-r--r--src/corelib/tools/qvector.h2
-rw-r--r--src/corelib/tools/tools.pri2
-rw-r--r--src/corelib/xml/qxmlstream_p.h1966
-rw-r--r--src/dbus/doc/src/qtdbus-index.qdoc11
-rw-r--r--src/gui/configure.json21
-rw-r--r--src/gui/doc/src/qtgui.qdoc5
-rw-r--r--src/gui/image/qmovie.cpp8
-rw-r--r--src/gui/kernel/qguiapplication.cpp4
-rw-r--r--src/gui/kernel/qopenglcontext.cpp1
-rw-r--r--src/gui/kernel/qplatforminputcontext.cpp2
-rw-r--r--src/gui/kernel/qsimpledrag.cpp30
-rw-r--r--src/gui/kernel/qsimpledrag_p.h6
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp3
-rw-r--r--src/gui/opengl/qopengltexture.cpp2
-rw-r--r--src/gui/painting/painting.pri2
-rw-r--r--src/gui/painting/qmatrix.h4
-rw-r--r--src/gui/painting/qtransform.h6
-rw-r--r--src/gui/text/qtextengine_p.h8
-rw-r--r--src/gui/text/qtextobject.h4
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp2
-rw-r--r--src/network/access/qhttpnetworkheader.cpp5
-rw-r--r--src/network/access/qhttpnetworkheader_p.h1
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp5
-rw-r--r--src/network/access/qhttpnetworkrequest_p.h1
-rw-r--r--src/network/configure.json11
-rw-r--r--src/network/network.pro2
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp2
-rw-r--r--src/network/ssl/qsslsocket_p.h2
-rw-r--r--src/network/ssl/ssl.pri2
-rw-r--r--src/opengl/doc/src/qtopengl-index.qdoc17
-rw-r--r--src/opengl/opengl.pro2
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp4
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp4
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h2
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm37
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm8
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h2
-rw-r--r--src/platformsupport/fontdatabases/windows/qwindowsnativeimage.cpp6
-rw-r--r--src/plugins/bearer/bearer.pro2
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp58
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm18
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm12
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm7
-rw-r--r--src/plugins/platforms/cocoa/qcocoansmenu.mm15
-rw-r--r--src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm24
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h3
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm48
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfswindow.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp18
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h1
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.cpp30
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.h1
-rw-r--r--src/plugins/platforms/ios/qioswindow.h4
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm13
-rw-r--r--src/plugins/platforms/ios/quiview.mm35
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp6
-rw-r--r--src/plugins/platforms/platforms.pro4
-rw-r--r--src/plugins/platforms/qnx/qnx.pro4
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.cpp130
-rw-r--r--src/plugins/platforms/qnx/qqnxeglwindow.h16
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.cpp206
-rw-r--r--src/plugins/platforms/qnx/qqnxglcontext.h30
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp53
-rw-r--r--src/plugins/platforms/qnx/qqnxnativeinterface.cpp2
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.h10
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.h3
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp27
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h1
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp166
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp37
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h6
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp6
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3menu.cpp9
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3theme.cpp17
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3theme.h2
-rw-r--r--src/plugins/styles/mac/qmacstyle_mac.mm8
-rw-r--r--src/printsupport/doc/src/qtprintsupport-index.qdoc15
-rw-r--r--src/sql/doc/src/qtsql.qdoc5
-rw-r--r--src/sql/sql.pro2
-rw-r--r--src/src.pro8
-rw-r--r--src/testlib/doc/src/qttest-index.qdoc5
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp5
-rw-r--r--src/widgets/doc/src/qtwidgets-index.qdoc11
-rw-r--r--src/widgets/graphicsview/qgraphicsview.cpp6
-rw-r--r--src/widgets/itemviews/qabstractitemdelegate.cpp8
-rw-r--r--src/widgets/itemviews/qheaderview.cpp88
-rw-r--r--src/widgets/itemviews/qheaderview_p.h11
-rw-r--r--src/widgets/itemviews/qtreeview.cpp2
-rw-r--r--src/widgets/kernel/qaction.cpp5
-rw-r--r--src/widgets/kernel/qapplication.cpp2
-rw-r--r--src/widgets/kernel/qwidget.cpp3
-rw-r--r--src/widgets/styles/qfusionstyle.cpp33
-rw-r--r--src/widgets/styles/qstylehelper.cpp8
-rw-r--r--src/widgets/styles/qstylehelper_p.h1
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp5
-rw-r--r--src/widgets/util/qsystemtrayicon.cpp7
-rw-r--r--src/widgets/widgets.pro2
-rw-r--r--src/widgets/widgets/qcombobox.cpp4
-rw-r--r--src/widgets/widgets/qlineedit.cpp5
-rw-r--r--src/widgets/widgets/qtoolbarextension.cpp20
-rw-r--r--src/widgets/widgets/qtoolbarextension_p.h6
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp5
-rw-r--r--src/xml/doc/src/qtxml-index.qdoc11
-rw-r--r--src/xml/sax/qxml.cpp14
-rw-r--r--src/xml/xml.pro2
164 files changed, 4538 insertions, 1278 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/Debug2.cpp b/src/3rdparty/angle/src/libANGLE/Debug2.cpp
deleted file mode 100644
index 30321f4160..0000000000
--- a/src/3rdparty/angle/src/libANGLE/Debug2.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-//
-// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// Debug.cpp: Defines debug state used for GL_KHR_debug
-
-#include "libANGLE/Debug.h"
-
-#include "common/debug.h"
-
-#include <algorithm>
-#include <tuple>
-
-namespace gl
-{
-
-Debug::Debug()
- : mOutputEnabled(false),
- mCallbackFunction(nullptr),
- mCallbackUserParam(nullptr),
- mMessages(),
- mMaxLoggedMessages(0),
- mOutputSynchronous(false),
- mGroups()
-{
- pushDefaultGroup();
-}
-
-void Debug::setMaxLoggedMessages(GLuint maxLoggedMessages)
-{
- mMaxLoggedMessages = maxLoggedMessages;
-}
-
-void Debug::setOutputEnabled(bool enabled)
-{
- mOutputEnabled = enabled;
-}
-
-bool Debug::isOutputEnabled() const
-{
- return mOutputEnabled;
-}
-
-void Debug::setOutputSynchronous(bool synchronous)
-{
- mOutputSynchronous = synchronous;
-}
-
-bool Debug::isOutputSynchronous() const
-{
- return mOutputSynchronous;
-}
-
-void Debug::setCallback(GLDEBUGPROCKHR callback, const void *userParam)
-{
- mCallbackFunction = callback;
- mCallbackUserParam = userParam;
-}
-
-GLDEBUGPROCKHR Debug::getCallback() const
-{
- return mCallbackFunction;
-}
-
-const void *Debug::getUserParam() const
-{
- return mCallbackUserParam;
-}
-
-void Debug::insertMessage(GLenum source,
- GLenum type,
- GLuint id,
- GLenum severity,
- const std::string &message)
-{
- std::string messageCopy(message);
- insertMessage(source, type, id, severity, std::move(messageCopy));
-}
-
-void Debug::insertMessage(GLenum source,
- GLenum type,
- GLuint id,
- GLenum severity,
- std::string &&message)
-{
- if (!isMessageEnabled(source, type, id, severity))
- {
- return;
- }
-
- if (mCallbackFunction != nullptr)
- {
- // TODO(geofflang) Check the synchronous flag and potentially flush messages from another
- // thread.
- mCallbackFunction(source, type, id, severity, static_cast<GLsizei>(message.length()),
- message.c_str(), mCallbackUserParam);
- }
- else
- {
- if (mMessages.size() >= mMaxLoggedMessages)
- {
- // Drop messages over the limit
- return;
- }
-
- Message m;
- m.source = source;
- m.type = type;
- m.id = id;
- m.severity = severity;
- m.message = std::move(message);
-
- mMessages.push_back(std::move(m));
- }
-}
-
-size_t Debug::getMessages(GLuint count,
- GLsizei bufSize,
- GLenum *sources,
- GLenum *types,
- GLuint *ids,
- GLenum *severities,
- GLsizei *lengths,
- GLchar *messageLog)
-{
- size_t messageCount = 0;
- size_t messageStringIndex = 0;
- while (messageCount <= count && !mMessages.empty())
- {
- const Message &m = mMessages.front();
-
- if (messageLog != nullptr)
- {
- // Check that this message can fit in the message buffer
- if (messageStringIndex + m.message.length() + 1 > static_cast<size_t>(bufSize))
- {
- break;
- }
-
- std::copy(m.message.begin(), m.message.end(), messageLog + messageStringIndex);
- messageStringIndex += m.message.length();
-
- messageLog[messageStringIndex] = '\0';
- messageStringIndex += 1;
- }
-
- if (sources != nullptr)
- {
- sources[messageCount] = m.source;
- }
-
- if (types != nullptr)
- {
- types[messageCount] = m.type;
- }
-
- if (ids != nullptr)
- {
- ids[messageCount] = m.id;
- }
-
- if (severities != nullptr)
- {
- severities[messageCount] = m.severity;
- }
-
- if (lengths != nullptr)
- {
- lengths[messageCount] = static_cast<GLsizei>(m.message.length());
- }
-
- mMessages.pop_front();
-
- messageCount++;
- }
-
- return messageCount;
-}
-
-size_t Debug::getNextMessageLength() const
-{
- return mMessages.empty() ? 0 : mMessages.front().message.length();
-}
-
-size_t Debug::getMessageCount() const
-{
- return mMessages.size();
-}
-
-void Debug::setMessageControl(GLenum source,
- GLenum type,
- GLenum severity,
- std::vector<GLuint> &&ids,
- bool enabled)
-{
- Control c;
- c.source = source;
- c.type = type;
- c.severity = severity;
- c.ids = std::move(ids);
- c.enabled = enabled;
-
- auto &controls = mGroups.back().controls;
- controls.push_back(std::move(c));
-}
-
-void Debug::pushGroup(GLenum source, GLuint id, std::string &&message)
-{
- insertMessage(source, GL_DEBUG_TYPE_PUSH_GROUP, id, GL_DEBUG_SEVERITY_NOTIFICATION,
- std::string(message));
-
- Group g;
- g.source = source;
- g.id = id;
- g.message = std::move(message);
- mGroups.push_back(std::move(g));
-}
-
-void Debug::popGroup()
-{
- // Make sure the default group is not about to be popped
- ASSERT(mGroups.size() > 1);
-
- Group g = mGroups.back();
- mGroups.pop_back();
-
- insertMessage(g.source, GL_DEBUG_TYPE_POP_GROUP, g.id, GL_DEBUG_SEVERITY_NOTIFICATION,
- g.message);
-}
-
-size_t Debug::getGroupStackDepth() const
-{
- return mGroups.size();
-}
-
-bool Debug::isMessageEnabled(GLenum source, GLenum type, GLuint id, GLenum severity) const
-{
- if (!mOutputEnabled)
- {
- return false;
- }
-
- for (auto groupIter = mGroups.rbegin(); groupIter != mGroups.rend(); groupIter++)
- {
- const auto &controls = groupIter->controls;
- for (auto controlIter = controls.rbegin(); controlIter != controls.rend(); controlIter++)
- {
- const auto &control = *controlIter;
-
- if (control.source != GL_DONT_CARE && control.source != source)
- {
- continue;
- }
-
- if (control.type != GL_DONT_CARE && control.type != type)
- {
- continue;
- }
-
- if (control.severity != GL_DONT_CARE && control.severity != severity)
- {
- continue;
- }
-
- if (!control.ids.empty() &&
- std::find(control.ids.begin(), control.ids.end(), id) == control.ids.end())
- {
- continue;
- }
-
- return control.enabled;
- }
- }
-
- return true;
-}
-
-void Debug::pushDefaultGroup()
-{
- Group g;
- g.source = GL_NONE;
- g.id = 0;
- g.message = "";
-
- Control c0;
- c0.source = GL_DONT_CARE;
- c0.type = GL_DONT_CARE;
- c0.severity = GL_DONT_CARE;
- c0.enabled = true;
- g.controls.push_back(std::move(c0));
-
- Control c1;
- c1.source = GL_DONT_CARE;
- c1.type = GL_DONT_CARE;
- c1.severity = GL_DEBUG_SEVERITY_LOW;
- c1.enabled = false;
- g.controls.push_back(std::move(c1));
-
- mGroups.push_back(std::move(g));
-}
-} // namespace gl
diff --git a/src/3rdparty/angle/src/libANGLE/Debug2.h b/src/3rdparty/angle/src/libANGLE/Debug2.h
deleted file mode 100644
index f545b815e4..0000000000
--- a/src/3rdparty/angle/src/libANGLE/Debug2.h
+++ /dev/null
@@ -1,120 +0,0 @@
-//
-// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// Debug.h: Defines debug state used for GL_KHR_debug
-
-#ifndef LIBANGLE_DEBUG_H_
-#define LIBANGLE_DEBUG_H_
-
-#include "angle_gl.h"
-#include "common/angleutils.h"
-
-#include <deque>
-#include <string>
-#include <vector>
-
-namespace gl
-{
-
-class LabeledObject
-{
- public:
- virtual ~LabeledObject() {}
- virtual void setLabel(const std::string &label) = 0;
- virtual const std::string &getLabel() const = 0;
-};
-
-class Debug : angle::NonCopyable
-{
- public:
- Debug();
-
- void setMaxLoggedMessages(GLuint maxLoggedMessages);
-
- void setOutputEnabled(bool enabled);
- bool isOutputEnabled() const;
-
- void setOutputSynchronous(bool synchronous);
- bool isOutputSynchronous() const;
-
- void setCallback(GLDEBUGPROCKHR callback, const void *userParam);
- GLDEBUGPROCKHR getCallback() const;
- const void *getUserParam() const;
-
- void insertMessage(GLenum source,
- GLenum type,
- GLuint id,
- GLenum severity,
- const std::string &message);
- void insertMessage(GLenum source,
- GLenum type,
- GLuint id,
- GLenum severity,
- std::string &&message);
-
- void setMessageControl(GLenum source,
- GLenum type,
- GLenum severity,
- std::vector<GLuint> &&ids,
- bool enabled);
- size_t getMessages(GLuint count,
- GLsizei bufSize,
- GLenum *sources,
- GLenum *types,
- GLuint *ids,
- GLenum *severities,
- GLsizei *lengths,
- GLchar *messageLog);
- size_t getNextMessageLength() const;
- size_t getMessageCount() const;
-
- void pushGroup(GLenum source, GLuint id, std::string &&message);
- void popGroup();
- size_t getGroupStackDepth() const;
-
- private:
- bool isMessageEnabled(GLenum source, GLenum type, GLuint id, GLenum severity) const;
-
- void pushDefaultGroup();
-
- struct Message
- {
- GLenum source;
- GLenum type;
- GLuint id;
- GLenum severity;
- std::string message;
- };
-
- struct Control
- {
- GLenum source;
- GLenum type;
- GLenum severity;
- std::vector<GLuint> ids;
- bool enabled;
- };
-
- struct Group
- {
- GLenum source;
- GLuint id;
- std::string message;
-
- std::vector<Control> controls;
- };
-
- bool mOutputEnabled;
- GLDEBUGPROCKHR mCallbackFunction;
- const void *mCallbackUserParam;
- std::deque<Message> mMessages;
- GLuint mMaxLoggedMessages;
- bool mOutputSynchronous;
- std::vector<Group> mGroups;
-};
-} // namespace gl
-
-#endif // LIBANGLE_DEBUG_H_
diff --git a/src/3rdparty/libjpeg/qt_attribution.json b/src/3rdparty/libjpeg/qt_attribution.json
index a1966d43d6..9bfc14f29d 100644
--- a/src/3rdparty/libjpeg/qt_attribution.json
+++ b/src/3rdparty/libjpeg/qt_attribution.json
@@ -6,7 +6,7 @@
"Description": "The Independent JPEG Group's JPEG software",
"Homepage": "http://libjpeg-turbo.virtualgl.org/",
- "Version": "1.5.2",
+ "Version": "1.5.3",
"License": "Independent JPEG Group License",
"LicenseId": "IJG",
"LicenseFile": "LICENSE",
diff --git a/src/3rdparty/libjpeg/src/ChangeLog.md b/src/3rdparty/libjpeg/src/ChangeLog.md
index 2aaa50c148..f5fe44bf85 100644
--- a/src/3rdparty/libjpeg/src/ChangeLog.md
+++ b/src/3rdparty/libjpeg/src/ChangeLog.md
@@ -1,3 +1,47 @@
+1.5.3
+=====
+
+### Significant changes relative to 1.5.2:
+
+1. Fixed a NullPointerException in the TurboJPEG Java wrapper that occurred
+when using the YUVImage constructor that creates an instance backed by separate
+image planes and allocates memory for the image planes.
+
+2. Fixed an issue whereby the Java version of TJUnitTest would fail when
+testing BufferedImage encoding/decoding on big endian systems.
+
+3. Fixed a segfault in djpeg that would occur if an output format other than
+PPM/PGM was selected along with the `-crop` option. The `-crop` option now
+works with the GIF and Targa formats as well (unfortunately, it cannot be made
+to work with the BMP and RLE formats due to the fact that those output engines
+write scanlines in bottom-up order.) djpeg will now exit gracefully if an
+output format other than PPM/PGM, GIF, or Targa is selected along with the
+`-crop` option.
+
+4. Fixed an issue whereby `jpeg_skip_scanlines()` would segfault if color
+quantization was enabled.
+
+5. TJBench (both C and Java versions) will now display usage information if any
+command-line argument is unrecognized. This prevents the program from silently
+ignoring typos.
+
+6. Fixed an access violation in tjbench.exe (Windows) that occurred when the
+program was used to decompress an existing JPEG image.
+
+7. Fixed an ArrayIndexOutOfBoundsException in the TJExample Java program that
+occurred when attempting to decompress a JPEG image that had been compressed
+with 4:1:1 chrominance subsampling.
+
+8. Fixed an issue whereby, when using `jpeg_skip_scanlines()` to skip to the
+end of a single-scan (non-progressive) image, subsequent calls to
+`jpeg_consume_input()` would return `JPEG_SUSPENDED` rather than
+`JPEG_REACHED_EOI`.
+
+9. `jpeg_crop_scanlines()` now works correctly when decompressing grayscale
+JPEG images that were compressed with a sampling factor other than 1 (for
+instance, with `cjpeg -grayscale -sample 2x2`).
+
+
1.5.2
=====
diff --git a/src/3rdparty/libjpeg/src/jcdctmgr.c b/src/3rdparty/libjpeg/src/jcdctmgr.c
index aef8517f9c..6e3b19bcb3 100644
--- a/src/3rdparty/libjpeg/src/jcdctmgr.c
+++ b/src/3rdparty/libjpeg/src/jcdctmgr.c
@@ -216,7 +216,7 @@ compute_reciprocal (UINT16 divisor, DCTELEM *dtbl)
#endif
dtbl[DCTSIZE2 * 3] = (DCTELEM) r - sizeof(DCTELEM)*8; /* shift */
- if(r <= 16) return 0;
+ if (r <= 16) return 0;
else return 1;
}
diff --git a/src/3rdparty/libjpeg/src/jdapistd.c b/src/3rdparty/libjpeg/src/jdapistd.c
index 37afc8448b..105121df2b 100644
--- a/src/3rdparty/libjpeg/src/jdapistd.c
+++ b/src/3rdparty/libjpeg/src/jdapistd.c
@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1994-1996, Thomas G. Lane.
* libjpeg-turbo Modifications:
- * Copyright (C) 2010, 2015-2016, D. R. Commander.
+ * Copyright (C) 2010, 2015-2017, D. R. Commander.
* Copyright (C) 2015, Google, Inc.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
@@ -190,7 +190,10 @@ jpeg_crop_scanline (j_decompress_ptr cinfo, JDIMENSION *xoffset,
* single-pass decompression case, allowing us to use the same MCU column
* width for all of the components.
*/
- align = cinfo->_min_DCT_scaled_size * cinfo->max_h_samp_factor;
+ if (cinfo->comps_in_scan == 1 && cinfo->num_components == 1)
+ align = cinfo->_min_DCT_scaled_size;
+ else
+ align = cinfo->_min_DCT_scaled_size * cinfo->max_h_samp_factor;
/* Adjust xoffset to the nearest iMCU boundary <= the requested value */
input_xoffset = *xoffset;
@@ -215,6 +218,9 @@ jpeg_crop_scanline (j_decompress_ptr cinfo, JDIMENSION *xoffset,
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
ci++, compptr++) {
+ int hsf = (cinfo->comps_in_scan == 1 && cinfo->num_components == 1) ?
+ 1 : compptr->h_samp_factor;
+
/* Set downsampled_width to the new output width. */
orig_downsampled_width = compptr->downsampled_width;
compptr->downsampled_width =
@@ -228,11 +234,10 @@ jpeg_crop_scanline (j_decompress_ptr cinfo, JDIMENSION *xoffset,
* values will be used in multi-scan decompressions.
*/
cinfo->master->first_MCU_col[ci] =
- (JDIMENSION) (long) (*xoffset * compptr->h_samp_factor) /
- (long) align;
+ (JDIMENSION) (long) (*xoffset * hsf) / (long) align;
cinfo->master->last_MCU_col[ci] =
(JDIMENSION) jdiv_round_up((long) ((*xoffset + cinfo->output_width) *
- compptr->h_samp_factor),
+ hsf),
(long) align) - 1;
}
@@ -293,6 +298,14 @@ noop_convert (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
}
+/* Dummy quantize function used by jpeg_skip_scanlines() */
+LOCAL(void)
+noop_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+{
+}
+
+
/*
* In some cases, it is best to call jpeg_read_scanlines() and discard the
* output, rather than skipping the scanlines, because this allows us to
@@ -308,14 +321,22 @@ read_and_discard_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines)
void (*color_convert) (j_decompress_ptr cinfo, JSAMPIMAGE input_buf,
JDIMENSION input_row, JSAMPARRAY output_buf,
int num_rows);
+ void (*color_quantize) (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows) = NULL;
color_convert = cinfo->cconvert->color_convert;
cinfo->cconvert->color_convert = noop_convert;
+ if (cinfo->cquantize && cinfo->cquantize->color_quantize) {
+ color_quantize = cinfo->cquantize->color_quantize;
+ cinfo->cquantize->color_quantize = noop_quantize;
+ }
for (n = 0; n < num_lines; n++)
jpeg_read_scanlines(cinfo, NULL, 1);
cinfo->cconvert->color_convert = color_convert;
+ if (color_quantize)
+ cinfo->cquantize->color_quantize = color_quantize;
}
@@ -370,6 +391,8 @@ jpeg_skip_scanlines (j_decompress_ptr cinfo, JDIMENSION num_lines)
/* Do not skip past the bottom of the image. */
if (cinfo->output_scanline + num_lines >= cinfo->output_height) {
cinfo->output_scanline = cinfo->output_height;
+ (*cinfo->inputctl->finish_input_pass) (cinfo);
+ cinfo->inputctl->eoi_reached = TRUE;
return cinfo->output_height - cinfo->output_scanline;
}
diff --git a/src/3rdparty/libjpeg/src/jdcolor.c b/src/3rdparty/libjpeg/src/jdcolor.c
index ab8fa24925..05cbf4df1f 100644
--- a/src/3rdparty/libjpeg/src/jdcolor.c
+++ b/src/3rdparty/libjpeg/src/jdcolor.c
@@ -616,7 +616,7 @@ static const JLONG dither_matrix[4] = {
static INLINE boolean is_big_endian(void)
{
int test_value = 1;
- if(*(char *)&test_value != 1)
+ if (*(char *)&test_value != 1)
return TRUE;
return FALSE;
}
diff --git a/src/3rdparty/libjpeg/src/jdmerge.c b/src/3rdparty/libjpeg/src/jdmerge.c
index 6276dd0950..ca6f16c252 100644
--- a/src/3rdparty/libjpeg/src/jdmerge.c
+++ b/src/3rdparty/libjpeg/src/jdmerge.c
@@ -503,7 +503,7 @@ static const JLONG dither_matrix[4] = {
static INLINE boolean is_big_endian(void)
{
int test_value = 1;
- if(*(char *)&test_value != 1)
+ if (*(char *)&test_value != 1)
return TRUE;
return FALSE;
}
diff --git a/src/3rdparty/pcre2/pcre2.pro b/src/3rdparty/pcre2/pcre2.pro
index 3dde2f62f8..296e65cd59 100644
--- a/src/3rdparty/pcre2/pcre2.pro
+++ b/src/3rdparty/pcre2/pcre2.pro
@@ -16,6 +16,8 @@ DEFINES += HAVE_CONFIG_H
# platform/compiler specific definitions
uikit|qnx|winrt: DEFINES += PCRE2_DISABLE_JIT
+win32:contains(QT_ARCH, "arm"): DEFINES += PCRE2_DISABLE_JIT
+win32:contains(QT_ARCH, "arm64"): DEFINES += PCRE2_DISABLE_JIT
SOURCES += \
$$PWD/src/pcre2_auto_possess.c \
diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json
index 50c179bf6e..3800477239 100644
--- a/src/3rdparty/sqlite/qt_attribution.json
+++ b/src/3rdparty/sqlite/qt_attribution.json
@@ -6,7 +6,7 @@
"Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.",
"Homepage": "http://www.sqlite.org/",
- "Version": "3.20.1",
+ "Version": "3.22.0",
"License": "Public Domain",
"Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed."
}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java b/src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java
index e6814c202d..4f2c06644d 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/CursorHandle.java
@@ -51,6 +51,7 @@ import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.widget.PopupWindow;
import android.app.Activity;
+import android.util.TypedValue;
import android.view.ViewTreeObserver;
/* This view represents one of the handle (selection or cursor handle) */
@@ -58,8 +59,9 @@ class CursorView extends ImageView
{
private CursorHandle mHandle;
// The coordinare which where clicked
- private int m_offsetX;
- private int m_offsetY;
+ private float m_offsetX;
+ private float m_offsetY;
+ private boolean m_pressed = false;
CursorView (Context context, CursorHandle handle) {
super(context);
@@ -76,21 +78,23 @@ class CursorView extends ImageView
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
- m_offsetX = Math.round(ev.getRawX());
- m_offsetY = Math.round(ev.getRawY());
+ m_offsetX = ev.getRawX();
+ m_offsetY = ev.getRawY() + getHeight() / 2;
+ m_pressed = true;
break;
}
case MotionEvent.ACTION_MOVE: {
- mHandle.updatePosition(Math.round(ev.getRawX()) - m_offsetX,
- Math.round(ev.getRawY()) - m_offsetY);
+ if (!m_pressed)
+ return false;
+ mHandle.updatePosition(Math.round(ev.getRawX() - m_offsetX),
+ Math.round(ev.getRawY() - m_offsetY));
break;
}
case MotionEvent.ACTION_UP:
- break;
-
case MotionEvent.ACTION_CANCEL:
+ m_pressed = false;
break;
}
return true;
@@ -113,6 +117,7 @@ public class CursorHandle implements ViewTreeObserver.OnPreDrawListener
private int m_lastY;
int tolerance;
private boolean m_rtl;
+ int m_yShift;
public CursorHandle(Activity activity, View layout, int id, int attr, boolean rtl) {
m_activity = activity;
@@ -121,7 +126,8 @@ public class CursorHandle implements ViewTreeObserver.OnPreDrawListener
m_layout = layout;
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
- tolerance = Math.round(2 * metrics.density);
+ m_yShift = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 1f, metrics);
+ tolerance = Math.min(1, (int)(m_yShift / 2f));
m_lastX = m_lastY = -1 - tolerance;
m_rtl = rtl;
}
@@ -158,7 +164,7 @@ public class CursorHandle implements ViewTreeObserver.OnPreDrawListener
m_layout.getLocationOnScreen(location);
int x2 = x + location[0];
- int y2 = y + location[1];
+ int y2 = y + location[1] + m_yShift;
if (m_id == QtNative.IdCursorHandle) {
x2 -= m_cursorView.getWidth() / 2 ;
@@ -187,6 +193,7 @@ public class CursorHandle implements ViewTreeObserver.OnPreDrawListener
// The handle was dragged by a given relative position
public void updatePosition(int x, int y) {
+ y -= m_yShift;
if (Math.abs(m_lastX - x) > tolerance || Math.abs(m_lastY - y) > tolerance) {
QtNative.handleLocationChanged(m_id, x + m_posX, y + m_posY);
m_lastX = x;
diff --git a/src/angle/src/common/gles_common.pri b/src/angle/src/common/gles_common.pri
index 5d5682a1df..82d38a62e6 100644
--- a/src/angle/src/common/gles_common.pri
+++ b/src/angle/src/common/gles_common.pri
@@ -1,4 +1,4 @@
-CONFIG += simd no_batch
+CONFIG += simd no_batch object_parallel_to_source
include(common.pri)
INCLUDEPATH += $$OUT_PWD/.. $$ANGLE_DIR/src/libANGLE
@@ -48,6 +48,7 @@ HEADERS += \
$$ANGLE_DIR/src/libANGLE/Constants.h \
$$ANGLE_DIR/src/libANGLE/Context.h \
$$ANGLE_DIR/src/libANGLE/Data.h \
+ $$ANGLE_DIR/src/libANGLE/Debug.h \
$$ANGLE_DIR/src/libANGLE/Device.h \
$$ANGLE_DIR/src/libANGLE/Display.h \
$$ANGLE_DIR/src/libANGLE/Error.h \
@@ -169,6 +170,7 @@ SOURCES += \
$$ANGLE_DIR/src/libANGLE/Config.cpp \
$$ANGLE_DIR/src/libANGLE/Context.cpp \
$$ANGLE_DIR/src/libANGLE/Data.cpp \
+ $$ANGLE_DIR/src/libANGLE/Debug.cpp \
$$ANGLE_DIR/src/libANGLE/Device.cpp \
$$ANGLE_DIR/src/libANGLE/Display.cpp \
$$ANGLE_DIR/src/libANGLE/Error.cpp \
@@ -241,14 +243,6 @@ SOURCES += \
SSE2_SOURCES += $$ANGLE_DIR/src/libANGLE/renderer/d3d/loadimageSSE2.cpp
-DEBUG_SOURCE = $$ANGLE_DIR/src/libANGLE/Debug.cpp
-debug_copy.input = DEBUG_SOURCE
-debug_copy.output = $$ANGLE_DIR/src/libANGLE/Debug2.cpp
-debug_copy.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
-debug_copy.variable_out = GENERATED_SOURCES
-debug_copy.CONFIG = target_predeps
-QMAKE_EXTRA_COMPILERS += debug_copy
-
angle_d3d11 {
HEADERS += \
$$ANGLE_DIR/src/libANGLE/renderer/d3d/d3d11/Blit11.h \
diff --git a/src/concurrent/concurrent.pro b/src/concurrent/concurrent.pro
index 017153c74d..18510e38a1 100644
--- a/src/concurrent/concurrent.pro
+++ b/src/concurrent/concurrent.pro
@@ -4,7 +4,7 @@ CONFIG += exceptions
DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x66000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x66000000
QMAKE_DOCS = $$PWD/doc/qtconcurrent.qdocconf
diff --git a/src/concurrent/doc/src/qtconcurrent-index.qdoc b/src/concurrent/doc/src/qtconcurrent-index.qdoc
index 836cde131c..3e4aa791f1 100644
--- a/src/concurrent/doc/src/qtconcurrent-index.qdoc
+++ b/src/concurrent/doc/src/qtconcurrent-index.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -133,4 +133,13 @@
copy of the container when called. If you are using STL containers this copy operation
might take some time, in this case we recommend specifying the begin and end iterators
for the container instead.
+
+ \section1 Licenses
+
+ The Qt Concurrent module is available under commercial licenses from \l{The Qt Company}.
+ In addition, it is available under free software licenses. Since Qt 5.4,
+ these free software licenses are
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt Licensing} for further details.
*/
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 2079d2117f..3db2e2ceb8 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -12,7 +12,7 @@ CONFIG += qt_tracepoints
CONFIG += $$MODULE_CONFIG
DEFINES += $$MODULE_DEFINES
DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x67000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x67000000
CONFIG += simd optimize_full
diff --git a/src/corelib/doc/snippets/code/src_corelib_concurrent_qthreadpool.cpp b/src/corelib/doc/snippets/code/src_corelib_concurrent_qthreadpool.cpp
index a1372976ae..ba31972aa1 100644
--- a/src/corelib/doc/snippets/code/src_corelib_concurrent_qthreadpool.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_concurrent_qthreadpool.cpp
@@ -55,7 +55,7 @@ class HelloWorldTask : public QRunnable
{
qDebug() << "Hello world from thread" << QThread::currentThread();
}
-}
+};
HelloWorldTask *hello = new HelloWorldTask();
// QThreadPool takes ownership and deletes 'hello' automatically
diff --git a/src/corelib/doc/src/qtcore-index.qdoc b/src/corelib/doc/src/qtcore-index.qdoc
index 9004c018ed..04af0e9416 100644
--- a/src/corelib/doc/src/qtcore-index.qdoc
+++ b/src/corelib/doc/src/qtcore-index.qdoc
@@ -104,17 +104,18 @@
\section1 Licenses and Attributions
Qt Core is available under commercial licenses from \l{The Qt Company}.
- In addition, it is available under the
+ In addition, it is available under free software licenses. Since Qt 5.4,
+ these free software licenses are
\l{GNU Lesser General Public License, version 3}, or
the \l{GNU General Public License, version 2}.
See \l{Qt Licensing} for further details.
Executables on Windows potentially link
against \l{The qtmain Library}. This library is available
- under commercial licenses, and in addition under the
+ under commercial licenses and also under the
\l{BSD 3-clause "New" or "Revised" License}.
- Furthermore Qt Core potentially contains third party
+ Furthermore, Qt Core in Qt \QtVersion may contain third party
modules under following permissive licenses:
\generatelist{groupsbymodule attributions-qtcore}
diff --git a/src/corelib/global/qfloat16_f16c.c b/src/corelib/global/qfloat16_f16c.c
index 31dff0b154..a7eadc71b7 100644
--- a/src/corelib/global/qfloat16_f16c.c
+++ b/src/corelib/global/qfloat16_f16c.c
@@ -57,6 +57,7 @@ QT_FUNCTION_TARGET(F16C)
void qFloatToFloat16_fast(quint16 *out, const float *in, qsizetype len) Q_DECL_NOTHROW
{
qsizetype i = 0;
+ int epilog_i;
for (; i < len - 7; i += 8)
_mm_storeu_si128((__m128i *)(out + i), _mm256_cvtps_ph(_mm256_loadu_ps(in + i), 0));
if (i < len - 3) {
@@ -64,7 +65,7 @@ void qFloatToFloat16_fast(quint16 *out, const float *in, qsizetype len) Q_DECL_N
i += 4;
}
// Inlining "qfloat16::qfloat16(float f)":
- SIMD_EPILOGUE(i, len, 3)
+ for (epilog_i = 0; i < len && epilog_i < 3; ++i, ++epilog_i)
out[i] = _mm_extract_epi16(_mm_cvtps_ph(_mm_set_ss(in[i]), 0), 0);
}
@@ -72,6 +73,7 @@ QT_FUNCTION_TARGET(F16C)
void qFloatFromFloat16_fast(float *out, const quint16 *in, qsizetype len) Q_DECL_NOTHROW
{
qsizetype i = 0;
+ int epilog_i;
for (; i < len - 7; i += 8)
_mm256_storeu_ps(out + i, _mm256_cvtph_ps(_mm_loadu_si128((const __m128i *)(in + i))));
if (i < len - 3) {
@@ -79,7 +81,7 @@ void qFloatFromFloat16_fast(float *out, const quint16 *in, qsizetype len) Q_DECL
i += 4;
}
// Inlining "qfloat16::operator float()":
- SIMD_EPILOGUE(i, len, 3)
+ for (epilog_i = 0; i < len && epilog_i < 3; ++i, ++epilog_i)
out[i] = _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(in[i])));
}
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 1fe1c8c0d1..2d8b860c5b 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -84,7 +84,7 @@
# include <envLib.h>
#endif
-#if defined(Q_OS_ANDROID)
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
#include <private/qjni_p.h>
#endif
@@ -2298,7 +2298,7 @@ static bool findUnixOsVersion(QUnixOSVersion &v)
# endif // USE_ETC_OS_RELEASE
#endif // Q_OS_UNIX
-#ifdef Q_OS_ANDROID
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
static const char *osVer_helper(QOperatingSystemVersion)
{
/* Data:
@@ -2779,7 +2779,7 @@ QString QSysInfo::productVersion()
*/
QString QSysInfo::prettyProductName()
{
-#if defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN) || defined(Q_OS_WIN)
+#if (defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)) || defined(Q_OS_DARWIN) || defined(Q_OS_WIN)
const auto version = QOperatingSystemVersion::current();
const char *name = osVer_helper(version);
if (name)
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 39a5bbf645..9f1fe7cabb 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1597,7 +1597,7 @@ static bool syslog_default_message_handler(QtMsgType type, const QMessageLogCont
}
#endif
-#ifdef Q_OS_ANDROID
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
static bool android_default_message_handler(QtMsgType type,
const QMessageLogContext &context,
const QString &message)
@@ -1678,7 +1678,7 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
handledStderr |= systemd_default_message_handler(type, context, message);
# elif QT_CONFIG(syslog)
handledStderr |= syslog_default_message_handler(type, context, message);
-# elif defined(Q_OS_ANDROID)
+# elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
handledStderr |= android_default_message_handler(type, context, message);
# elif defined(QT_USE_APPLE_UNIFIED_LOGGING)
if (__builtin_available(macOS 10.12, iOS 10, tvOS 10, watchOS 3, *))
diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h
index 9b86a16516..5f8a124bcc 100644
--- a/src/corelib/global/qnumeric_p.h
+++ b/src/corelib/global/qnumeric_p.h
@@ -168,7 +168,7 @@ namespace {
// size_t. Implementations for 8- and 16-bit types will work but may not be as
// efficient. Implementations for 64-bit may be missing on 32-bit platforms.
-#if (defined(Q_CC_GNU) && (Q_CC_GNU >= 500) || defined(Q_CC_INTEL)) || QT_HAS_BUILTIN(__builtin_add_overflowx)
+#if (defined(Q_CC_GNU) && (Q_CC_GNU >= 500) || (defined(Q_CC_INTEL) && !defined(Q_OS_WIN))) || QT_HAS_BUILTIN(__builtin_add_overflowx)
// GCC 5, ICC 18, and Clang 3.8 have builtins to detect overflows
template <typename T> inline
diff --git a/src/corelib/global/qoperatingsystemversion.cpp b/src/corelib/global/qoperatingsystemversion.cpp
index 682c9bab61..4d267e328d 100644
--- a/src/corelib/global/qoperatingsystemversion.cpp
+++ b/src/corelib/global/qoperatingsystemversion.cpp
@@ -45,7 +45,7 @@
#include <qversionnumber.h>
#include <qdebug.h>
-#if defined(Q_OS_ANDROID)
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
#include <private/qjni_p.h>
#endif
@@ -163,7 +163,7 @@ QOperatingSystemVersion QOperatingSystemVersion::current()
{
QOperatingSystemVersion version;
version.m_os = currentType();
-#if defined(Q_OS_ANDROID)
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
#ifndef QT_BOOTSTRAPPED
const QVersionNumber v = QVersionNumber::fromString(QJNIObjectPrivate::getStaticObjectField(
"android/os/Build$VERSION", "RELEASE", "Ljava/lang/String;").toString());
diff --git a/src/corelib/global/qrandom.cpp b/src/corelib/global/qrandom.cpp
index 6c26d4682d..9143e04d45 100644
--- a/src/corelib/global/qrandom.cpp
+++ b/src/corelib/global/qrandom.cpp
@@ -74,7 +74,7 @@ DECLSPEC_IMPORT BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG Rando
}
#endif
-#if defined(Q_OS_ANDROID)
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
# include <private/qjni_p.h>
#endif
diff --git a/src/corelib/io/QTEMPORARYFILE_LICENSE.txt b/src/corelib/io/QTEMPORARYFILE_LICENSE.txt
deleted file mode 100644
index f5f1a2e05e..0000000000
--- a/src/corelib/io/QTEMPORARYFILE_LICENSE.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright (c) 1987, 1993
- The Regents of the University of California. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-3. Neither the name of the University nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index c6a5973306..d138ab2f00 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -159,7 +159,7 @@ win32 {
} else {
LIBS += -framework MobileCoreServices
}
- } else:android {
+ } else:android:!android-embedded {
SOURCES += \
io/qstandardpaths_android.cpp \
io/qstorageinfo_unix.cpp
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index 7dd4f6556d..bc39ea73ee 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -185,10 +185,11 @@ bool QFSFileEnginePrivate::nativeFlush()
bool QFSFileEnginePrivate::nativeSyncToDisk()
{
Q_Q(QFSFileEngine);
+ int ret;
#if defined(_POSIX_SYNCHRONIZED_IO) && _POSIX_SYNCHRONIZED_IO > 0
- const int ret = fdatasync(nativeHandle());
+ EINTR_LOOP(ret, fdatasync(nativeHandle()));
#else
- const int ret = fsync(nativeHandle());
+ EINTR_LOOP(ret, fsync(nativeHandle()));
#endif
if (ret != 0)
q->setError(QFile::WriteError, qt_error_string(errno));
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index b5f8e30b80..cd97268d71 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -44,6 +44,7 @@
#include <QtCore/qstandardpaths.h>
#include <QtCore/qtextstream.h>
#include <QtCore/qdir.h>
+#include <QtCore/qcoreapplication.h>
// We can't use the default macros because this would lead to recursion.
// Instead let's define our own one that unconditionally logs...
@@ -255,6 +256,15 @@ void QLoggingSettingsParser::parseNextLine(QStringRef line)
QLoggingRegistry::QLoggingRegistry()
: categoryFilter(defaultCategoryFilter)
{
+#if defined(Q_OS_ANDROID)
+ // Unless QCoreApplication has been constructed we can't be sure that
+ // we are on Qt's main thread. If we did allow logging here, we would
+ // potentially set Qt's main thread to Android's thread 0, which would
+ // confuse Qt later when running main().
+ if (!qApp)
+ return;
+#endif
+
initializeRules(); // Init on first use
}
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index 6ab806d9fe..3a62a67e3b 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -101,7 +101,8 @@ static void qt_create_pipe(Q_PIPE *pipe, bool isInputPipe)
unsigned int attempts = 1000;
forever {
_snwprintf(pipeName, sizeof(pipeName) / sizeof(pipeName[0]),
- L"\\\\.\\pipe\\qt-%X", QRandomGenerator::global()->generate());
+ L"\\\\.\\pipe\\qt-%lX-%X", long(QCoreApplication::applicationPid()),
+ QRandomGenerator::global()->generate());
DWORD dwOpenMode = FILE_FLAG_OVERLAPPED;
DWORD dwOutputBufferSize = 0;
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index 56934a9a0f..0cbc8c2234 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -264,7 +264,7 @@ bool QSaveFile::open(OpenMode mode)
}
#endif
- d->fileEngine = new QTemporaryFileEngine(&d->finalFileName);
+ d->fileEngine = new QTemporaryFileEngine(&d->finalFileName, QTemporaryFileEngine::Win32NonShared);
// if the target file exists, we'll copy its permissions below,
// but until then, let's ensure the temporary file is not accessible
// to a third party
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index bbc66120b5..4b1b9888d8 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -2366,6 +2366,11 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
limitations is to store the settings using the IniFormat
instead of the NativeFormat.
+ \li On Windows, when the Windows system registry is used, QSettings
+ does not preserve the original type of the value. Therefore,
+ the type of the value might change when a new value is set. For
+ example, a value with type \c REG_EXPAND_SZ will change to \c REG_SZ.
+
\li On \macos and iOS, allKeys() will return some extra keys for global
settings that apply to all applications. These keys can be
read using value() but cannot be changed, only shadowed.
diff --git a/src/corelib/io/qstandardpaths_android.cpp b/src/corelib/io/qstandardpaths_android.cpp
index 2a44daf8b5..0667d170c7 100644
--- a/src/corelib/io/qstandardpaths_android.cpp
+++ b/src/corelib/io/qstandardpaths_android.cpp
@@ -217,7 +217,16 @@ static QString getFilesDir()
if (!path.isEmpty())
return path;
- return (path = QDir::homePath());
+ QJNIObjectPrivate appCtx = applicationContext();
+ if (!appCtx.isValid())
+ return QString();
+
+ QJNIObjectPrivate file = appCtx.callObjectMethod("getFilesDir",
+ "()Ljava/io/File;");
+ if (!file.isValid())
+ return QString();
+
+ return (path = getAbsolutePath(file));
}
QString QStandardPaths::writableLocation(StandardLocation type)
@@ -319,7 +328,9 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
if (!ba.isEmpty())
return QStringList((fontLocation = QDir::cleanPath(QString::fromLocal8Bit(ba))));
- return QStringList((fontLocation = QLatin1String("/system/fonts")));
+ // Don't cache the fallback, as we might just have been called before
+ // QT_ANDROID_FONT_LOCATION has been set.
+ return QStringList(QLatin1String("/system/fonts"));
}
return QStringList(writableLocation(type));
diff --git a/src/corelib/io/qt_attribution.json b/src/corelib/io/qt_attribution.json
index 0fa4502db4..e9eb9c85e4 100644
--- a/src/corelib/io/qt_attribution.json
+++ b/src/corelib/io/qt_attribution.json
@@ -1,17 +1,3 @@
-[
-{
- "Id": "qtemporaryfile",
- "Name": "Parts of QTemporaryFile",
- "QDocModule": "qtcore",
- "QtUsage": "Used in Qt Core. Disable the qtemporaryfile feature to avoid.",
- "Path": "qtemporaryfile.cpp",
-
- "Description": "Generates a unique file path and returns a native handle to the open file.",
- "License": "BSD 3-clause \"New\" or \"Revised\" License",
- "LicenseId": "BSD-3-Clause",
- "LicenseFile": "QTEMPORARYFILE_LICENSE.txt",
- "Copyright": "Copyright (c) 1987, 1993 The Regents of the University of California."
-},
{
"Id": "psl",
"Name": "The Public Suffix List",
@@ -39,4 +25,3 @@ supported by Qt (by the QNetworkCookieJar class).",
"Copyright": "The list was originally provided by Jo Hermans <jo.hermans@gmail.com>.
It is now maintained on github (https://github.com/publicsuffix/list)."
}
-]
diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp
index 73249d7df8..1983a22c65 100644
--- a/src/corelib/io/qtemporaryfile.cpp
+++ b/src/corelib/io/qtemporaryfile.cpp
@@ -207,7 +207,7 @@ QFileSystemEntry::NativePath QTemporaryFileName::generateNext()
changed and contain the generated path name.
*/
static bool createFileFromTemplate(NativeFileHandle &file, QTemporaryFileName &templ,
- quint32 mode, QSystemError &error)
+ quint32 mode, int flags, QSystemError &error)
{
const int maxAttempts = 16;
for (int attempt = 0; attempt < maxAttempts; ++attempt) {
@@ -216,16 +216,18 @@ static bool createFileFromTemplate(NativeFileHandle &file, QTemporaryFileName &t
#if defined(Q_OS_WIN)
Q_UNUSED(mode);
+ const DWORD shareMode = (flags & QTemporaryFileEngine::Win32NonShared)
+ ? 0u : (FILE_SHARE_READ | FILE_SHARE_WRITE);
# ifndef Q_OS_WINRT
file = CreateFile((const wchar_t *)path.constData(),
GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW,
+ shareMode, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
# else // !Q_OS_WINRT
file = CreateFile2((const wchar_t *)path.constData(),
GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, CREATE_NEW,
+ shareMode, CREATE_NEW,
NULL);
# endif // Q_OS_WINRT
@@ -247,6 +249,7 @@ static bool createFileFromTemplate(NativeFileHandle &file, QTemporaryFileName &t
return false;
}
#else // POSIX
+ Q_UNUSED(flags)
file = QT_OPEN(path.constData(),
QT_OPEN_CREAT | QT_OPEN_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE,
static_cast<mode_t>(mode));
@@ -366,7 +369,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
unnamedFile = true;
d->fileEntry.clear();
} else if (st == CreateUnnamedFileStatus::NotSupported &&
- createFileFromTemplate(file, tfn, fileMode, error)) {
+ createFileFromTemplate(file, tfn, fileMode, flags, error)) {
filePathIsTemplate = false;
unnamedFile = false;
d->fileEntry = QFileSystemEntry(tfn.path, QFileSystemEntry::FromNativePath());
diff --git a/src/corelib/io/qtemporaryfile_p.h b/src/corelib/io/qtemporaryfile_p.h
index fb8887af53..0fec88d3cd 100644
--- a/src/corelib/io/qtemporaryfile_p.h
+++ b/src/corelib/io/qtemporaryfile_p.h
@@ -108,8 +108,10 @@ class QTemporaryFileEngine : public QFSFileEngine
{
Q_DECLARE_PRIVATE(QFSFileEngine)
public:
- QTemporaryFileEngine(const QString *templateName)
- : templateName(*templateName)
+ enum Flags { Win32NonShared = 0x1 };
+
+ explicit QTemporaryFileEngine(const QString *_templateName, int _flags = 0)
+ : templateName(*_templateName), flags(_flags)
{}
void initialize(const QString &file, quint32 mode, bool nameIsTemplate = true)
@@ -144,6 +146,7 @@ public:
const QString &templateName;
quint32 fileMode;
+ int flags = 0;
bool filePathIsTemplate;
bool filePathWasTemplate;
bool unnamedFile = false;
diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp
index ce90ab49d3..a9b23babc0 100644
--- a/src/corelib/io/qurlrecode.cpp
+++ b/src/corelib/io/qurlrecode.cpp
@@ -511,7 +511,7 @@ static int decode(QString &appendTo, const ushort *begin, const ushort *end)
if (Q_UNLIKELY(end - input < 3 || !isHex(input[1]) || !isHex(input[2]))) {
// badly-encoded data
appendTo.resize(origSize + (end - begin));
- memcpy(appendTo.begin() + origSize, begin, (end - begin) * sizeof(ushort));
+ memcpy(static_cast<void *>(appendTo.begin() + origSize), static_cast<const void *>(begin), (end - begin) * sizeof(ushort));
return end - begin;
}
@@ -519,7 +519,7 @@ static int decode(QString &appendTo, const ushort *begin, const ushort *end)
// detach
appendTo.resize(origSize + (end - begin));
output = reinterpret_cast<ushort *>(appendTo.begin()) + origSize;
- memcpy(output, begin, (input - begin) * sizeof(ushort));
+ memcpy(static_cast<void *>(output), static_cast<const void *>(begin), (input - begin) * sizeof(ushort));
output += input - begin;
}
diff --git a/src/corelib/json/qjsonarray.cpp b/src/corelib/json/qjsonarray.cpp
new file mode 100644
index 0000000000..255dc2ee4e
--- /dev/null
+++ b/src/corelib/json/qjsonarray.cpp
@@ -0,0 +1,1238 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qjsonobject.h>
+#include <qjsonvalue.h>
+#include <qjsonarray.h>
+#include <qstringlist.h>
+#include <qvariant.h>
+#include <qdebug.h>
+
+#include "qjsonwriter_p.h"
+#include "qjson_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QJsonArray
+ \inmodule QtCore
+ \ingroup json
+ \ingroup shared
+ \reentrant
+ \since 5.0
+
+ \brief The QJsonArray class encapsulates a JSON array.
+
+ A JSON array is a list of values. The list can be manipulated by inserting and
+ removing QJsonValue's from the array.
+
+ A QJsonArray can be converted to and from a QVariantList. You can query the
+ number of entries with size(), insert(), and removeAt() entries from it
+ and iterate over its content using the standard C++ iterator pattern.
+
+ QJsonArray is an implicitly shared class and shares the data with the document
+ it has been created from as long as it is not being modified.
+
+ You can convert the array to and from text based JSON through QJsonDocument.
+
+ \sa {JSON Support in Qt}, {JSON Save Game Example}
+*/
+
+/*!
+ \typedef QJsonArray::Iterator
+
+ Qt-style synonym for QJsonArray::iterator.
+*/
+
+/*!
+ \typedef QJsonArray::ConstIterator
+
+ Qt-style synonym for QJsonArray::const_iterator.
+*/
+
+/*!
+ \typedef QJsonArray::size_type
+
+ Typedef for int. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QJsonArray::value_type
+
+ Typedef for QJsonValue. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QJsonArray::difference_type
+
+ Typedef for int. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QJsonArray::pointer
+
+ Typedef for QJsonValue *. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QJsonArray::const_pointer
+
+ Typedef for const QJsonValue *. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QJsonArray::reference
+
+ Typedef for QJsonValue &. Provided for STL compatibility.
+*/
+
+/*!
+ \typedef QJsonArray::const_reference
+
+ Typedef for const QJsonValue &. Provided for STL compatibility.
+*/
+
+/*!
+ Creates an empty array.
+ */
+QJsonArray::QJsonArray()
+ : d(0), a(0)
+{
+}
+
+/*!
+ \fn QJsonArray::QJsonArray(std::initializer_list<QJsonValue> args)
+ \since 5.4
+ Creates an array initialized from \a args initialization list.
+
+ QJsonArray can be constructed in a way similar to JSON notation,
+ for example:
+ \code
+ QJsonArray array = { 1, 2.2, QString() };
+ \endcode
+ */
+
+/*!
+ \internal
+ */
+QJsonArray::QJsonArray(QJsonPrivate::Data *data, QJsonPrivate::Array *array)
+ : d(data), a(array)
+{
+ Q_ASSERT(data);
+ Q_ASSERT(array);
+ d->ref.ref();
+}
+
+/*!
+ This method replaces part of QJsonArray(std::initializer_list<QJsonValue> args) .
+ The constructor needs to be inline, but we do not want to leak implementation details
+ of this class.
+ \note this method is called for an uninitialized object
+ \internal
+ */
+void QJsonArray::initialize()
+{
+ d = 0;
+ a = 0;
+}
+
+/*!
+ Deletes the array.
+ */
+QJsonArray::~QJsonArray()
+{
+ if (d && !d->ref.deref())
+ delete d;
+}
+
+/*!
+ Creates a copy of \a other.
+
+ Since QJsonArray is implicitly shared, the copy is shallow
+ as long as the object doesn't get modified.
+ */
+QJsonArray::QJsonArray(const QJsonArray &other)
+{
+ d = other.d;
+ a = other.a;
+ if (d)
+ d->ref.ref();
+}
+
+/*!
+ Assigns \a other to this array.
+ */
+QJsonArray &QJsonArray::operator =(const QJsonArray &other)
+{
+ if (d != other.d) {
+ if (d && !d->ref.deref())
+ delete d;
+ d = other.d;
+ if (d)
+ d->ref.ref();
+ }
+ a = other.a;
+
+ return *this;
+}
+
+/*! \fn QJsonArray &QJsonArray::operator+=(const QJsonValue &value)
+
+ Appends \a value to the array, and returns a reference to the array itself.
+
+ \since 5.3
+ \sa append(), operator<<()
+*/
+
+/*! \fn QJsonArray QJsonArray::operator+(const QJsonValue &value) const
+
+ Returns an array that contains all the items in this array followed
+ by the provided \a value.
+
+ \since 5.3
+ \sa operator+=()
+*/
+
+/*! \fn QJsonArray &QJsonArray::operator<<(const QJsonValue &value)
+
+ Appends \a value to the array, and returns a reference to the array itself.
+
+ \since 5.3
+ \sa operator+=(), append()
+*/
+
+/*!
+ Converts the string list \a list to a QJsonArray.
+
+ The values in \a list will be converted to JSON values.
+
+ \sa toVariantList(), QJsonValue::fromVariant()
+ */
+QJsonArray QJsonArray::fromStringList(const QStringList &list)
+{
+ QJsonArray array;
+ for (QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it)
+ array.append(QJsonValue(*it));
+ return array;
+}
+
+/*!
+ Converts the variant list \a list to a QJsonArray.
+
+ The QVariant values in \a list will be converted to JSON values.
+
+ \sa toVariantList(), QJsonValue::fromVariant()
+ */
+QJsonArray QJsonArray::fromVariantList(const QVariantList &list)
+{
+ QJsonArray array;
+ if (list.isEmpty())
+ return array;
+
+ array.detach2(1024);
+
+ QVector<QJsonPrivate::Value> values;
+ values.resize(list.size());
+ QJsonPrivate::Value *valueData = values.data();
+ uint currentOffset = sizeof(QJsonPrivate::Base);
+
+ for (int i = 0; i < list.size(); ++i) {
+ QJsonValue val = QJsonValue::fromVariant(list.at(i));
+
+ bool latinOrIntValue;
+ int valueSize = QJsonPrivate::Value::requiredStorage(val, &latinOrIntValue);
+
+ if (!array.detach2(valueSize))
+ return QJsonArray();
+
+ QJsonPrivate::Value *v = valueData + i;
+ v->type = (val.t == QJsonValue::Undefined ? QJsonValue::Null : val.t);
+ v->latinOrIntValue = latinOrIntValue;
+ v->latinKey = false;
+ v->value = QJsonPrivate::Value::valueToStore(val, currentOffset);
+ if (valueSize)
+ QJsonPrivate::Value::copyData(val, (char *)array.a + currentOffset, latinOrIntValue);
+
+ currentOffset += valueSize;
+ array.a->size = currentOffset;
+ }
+
+ // write table
+ array.a->tableOffset = currentOffset;
+ if (!array.detach2(sizeof(QJsonPrivate::offset)*values.size()))
+ return QJsonArray();
+ memcpy(static_cast<void *>(array.a->table()),
+ static_cast<const void *>(values.constData()), values.size()*sizeof(uint));
+ array.a->length = values.size();
+ array.a->size = currentOffset + sizeof(QJsonPrivate::offset)*values.size();
+
+ return array;
+}
+
+/*!
+ Converts this object to a QVariantList.
+
+ Returns the created map.
+ */
+QVariantList QJsonArray::toVariantList() const
+{
+ QVariantList list;
+
+ if (a) {
+ list.reserve(a->length);
+ for (int i = 0; i < (int)a->length; ++i)
+ list.append(QJsonValue(d, a, a->at(i)).toVariant());
+ }
+ return list;
+}
+
+
+/*!
+ Returns the number of values stored in the array.
+ */
+int QJsonArray::size() const
+{
+ if (!d)
+ return 0;
+
+ return (int)a->length;
+}
+
+/*!
+ \fn QJsonArray::count() const
+
+ Same as size().
+
+ \sa size()
+*/
+
+/*!
+ Returns \c true if the object is empty. This is the same as size() == 0.
+
+ \sa size()
+ */
+bool QJsonArray::isEmpty() const
+{
+ if (!d)
+ return true;
+
+ return !a->length;
+}
+
+/*!
+ Returns a QJsonValue representing the value for index \a i.
+
+ The returned QJsonValue is \c Undefined, if \a i is out of bounds.
+
+ */
+QJsonValue QJsonArray::at(int i) const
+{
+ if (!a || i < 0 || i >= (int)a->length)
+ return QJsonValue(QJsonValue::Undefined);
+
+ return QJsonValue(d, a, a->at(i));
+}
+
+/*!
+ Returns the first value stored in the array.
+
+ Same as \c at(0).
+
+ \sa at()
+ */
+QJsonValue QJsonArray::first() const
+{
+ return at(0);
+}
+
+/*!
+ Returns the last value stored in the array.
+
+ Same as \c{at(size() - 1)}.
+
+ \sa at()
+ */
+QJsonValue QJsonArray::last() const
+{
+ return at(a ? (a->length - 1) : 0);
+}
+
+/*!
+ Inserts \a value at the beginning of the array.
+
+ This is the same as \c{insert(0, value)} and will prepend \a value to the array.
+
+ \sa append(), insert()
+ */
+void QJsonArray::prepend(const QJsonValue &value)
+{
+ insert(0, value);
+}
+
+/*!
+ Inserts \a value at the end of the array.
+
+ \sa prepend(), insert()
+ */
+void QJsonArray::append(const QJsonValue &value)
+{
+ insert(a ? (int)a->length : 0, value);
+}
+
+/*!
+ Removes the value at index position \a i. \a i must be a valid
+ index position in the array (i.e., \c{0 <= i < size()}).
+
+ \sa insert(), replace()
+ */
+void QJsonArray::removeAt(int i)
+{
+ if (!a || i < 0 || i >= (int)a->length)
+ return;
+
+ detach2();
+ a->removeItems(i, 1);
+ ++d->compactionCounter;
+ if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(a->length) / 2u)
+ compact();
+}
+
+/*! \fn void QJsonArray::removeFirst()
+
+ Removes the first item in the array. Calling this function is
+ equivalent to calling \c{removeAt(0)}. The array must not be empty. If
+ the array can be empty, call isEmpty() before calling this
+ function.
+
+ \sa removeAt(), removeLast()
+*/
+
+/*! \fn void QJsonArray::removeLast()
+
+ Removes the last item in the array. Calling this function is
+ equivalent to calling \c{removeAt(size() - 1)}. The array must not be
+ empty. If the array can be empty, call isEmpty() before calling
+ this function.
+
+ \sa removeAt(), removeFirst()
+*/
+
+/*!
+ Removes the item at index position \a i and returns it. \a i must
+ be a valid index position in the array (i.e., \c{0 <= i < size()}).
+
+ If you don't use the return value, removeAt() is more efficient.
+
+ \sa removeAt()
+ */
+QJsonValue QJsonArray::takeAt(int i)
+{
+ if (!a || i < 0 || i >= (int)a->length)
+ return QJsonValue(QJsonValue::Undefined);
+
+ QJsonValue v(d, a, a->at(i));
+ removeAt(i); // detaches
+ return v;
+}
+
+/*!
+ Inserts \a value at index position \a i in the array. If \a i
+ is \c 0, the value is prepended to the array. If \a i is size(), the
+ value is appended to the array.
+
+ \sa append(), prepend(), replace(), removeAt()
+ */
+void QJsonArray::insert(int i, const QJsonValue &value)
+{
+ Q_ASSERT (i >= 0 && i <= (a ? (int)a->length : 0));
+ QJsonValue val = value;
+
+ bool compressed;
+ int valueSize = QJsonPrivate::Value::requiredStorage(val, &compressed);
+
+ if (!detach2(valueSize + sizeof(QJsonPrivate::Value)))
+ return;
+
+ if (!a->length)
+ a->tableOffset = sizeof(QJsonPrivate::Array);
+
+ int valueOffset = a->reserveSpace(valueSize, i, 1, false);
+ if (!valueOffset)
+ return;
+
+ QJsonPrivate::Value &v = (*a)[i];
+ v.type = (val.t == QJsonValue::Undefined ? QJsonValue::Null : val.t);
+ v.latinOrIntValue = compressed;
+ v.latinKey = false;
+ v.value = QJsonPrivate::Value::valueToStore(val, valueOffset);
+ if (valueSize)
+ QJsonPrivate::Value::copyData(val, (char *)a + valueOffset, compressed);
+}
+
+/*!
+ \fn QJsonArray::iterator QJsonArray::insert(iterator before, const QJsonValue &value)
+
+ Inserts \a value before the position pointed to by \a before, and returns an iterator
+ pointing to the newly inserted item.
+
+ \sa erase(), insert()
+*/
+
+/*!
+ \fn QJsonArray::iterator QJsonArray::erase(iterator it)
+
+ Removes the item pointed to by \a it, and returns an iterator pointing to the
+ next item.
+
+ \sa removeAt()
+*/
+
+/*!
+ Replaces the item at index position \a i with \a value. \a i must
+ be a valid index position in the array (i.e., \c{0 <= i < size()}).
+
+ \sa operator[](), removeAt()
+ */
+void QJsonArray::replace(int i, const QJsonValue &value)
+{
+ Q_ASSERT (a && i >= 0 && i < (int)(a->length));
+ QJsonValue val = value;
+
+ bool compressed;
+ int valueSize = QJsonPrivate::Value::requiredStorage(val, &compressed);
+
+ if (!detach2(valueSize))
+ return;
+
+ if (!a->length)
+ a->tableOffset = sizeof(QJsonPrivate::Array);
+
+ int valueOffset = a->reserveSpace(valueSize, i, 1, true);
+ if (!valueOffset)
+ return;
+
+ QJsonPrivate::Value &v = (*a)[i];
+ v.type = (val.t == QJsonValue::Undefined ? QJsonValue::Null : val.t);
+ v.latinOrIntValue = compressed;
+ v.latinKey = false;
+ v.value = QJsonPrivate::Value::valueToStore(val, valueOffset);
+ if (valueSize)
+ QJsonPrivate::Value::copyData(val, (char *)a + valueOffset, compressed);
+
+ ++d->compactionCounter;
+ if (d->compactionCounter > 32u && d->compactionCounter >= unsigned(a->length) / 2u)
+ compact();
+}
+
+/*!
+ Returns \c true if the array contains an occurrence of \a value, otherwise \c false.
+
+ \sa count()
+ */
+bool QJsonArray::contains(const QJsonValue &value) const
+{
+ for (int i = 0; i < size(); i++) {
+ if (at(i) == value)
+ return true;
+ }
+ return false;
+}
+
+/*!
+ Returns the value at index position \a i as a modifiable reference.
+ \a i must be a valid index position in the array (i.e., \c{0 <= i <
+ size()}).
+
+ The return value is of type QJsonValueRef, a helper class for QJsonArray
+ and QJsonObject. When you get an object of type QJsonValueRef, you can
+ use it as if it were a reference to a QJsonValue. If you assign to it,
+ the assignment will apply to the character in the QJsonArray of QJsonObject
+ from which you got the reference.
+
+ \sa at()
+ */
+QJsonValueRef QJsonArray::operator [](int i)
+{
+ Q_ASSERT(a && i >= 0 && i < (int)a->length);
+ return QJsonValueRef(this, i);
+}
+
+/*!
+ \overload
+
+ Same as at().
+ */
+QJsonValue QJsonArray::operator[](int i) const
+{
+ return at(i);
+}
+
+/*!
+ Returns \c true if this array is equal to \a other.
+ */
+bool QJsonArray::operator==(const QJsonArray &other) const
+{
+ if (a == other.a)
+ return true;
+
+ if (!a)
+ return !other.a->length;
+ if (!other.a)
+ return !a->length;
+ if (a->length != other.a->length)
+ return false;
+
+ for (int i = 0; i < (int)a->length; ++i) {
+ if (QJsonValue(d, a, a->at(i)) != QJsonValue(other.d, other.a, other.a->at(i)))
+ return false;
+ }
+ return true;
+}
+
+/*!
+ Returns \c true if this array is not equal to \a other.
+ */
+bool QJsonArray::operator!=(const QJsonArray &other) const
+{
+ return !(*this == other);
+}
+
+/*! \fn QJsonArray::iterator QJsonArray::begin()
+
+ Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first item in
+ the array.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QJsonArray::const_iterator QJsonArray::begin() const
+
+ \overload
+*/
+
+/*! \fn QJsonArray::const_iterator QJsonArray::constBegin() const
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item
+ in the array.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QJsonArray::iterator QJsonArray::end()
+
+ Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item
+ after the last item in the array.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn const_iterator QJsonArray::end() const
+
+ \overload
+*/
+
+/*! \fn QJsonArray::const_iterator QJsonArray::constEnd() const
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
+ item after the last item in the array.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn void QJsonArray::push_back(const QJsonValue &value)
+
+ This function is provided for STL compatibility. It is equivalent
+ to \l{QJsonArray::append()}{append(value)} and will append \a value to the array.
+*/
+
+/*! \fn void QJsonArray::push_front(const QJsonValue &value)
+
+ This function is provided for STL compatibility. It is equivalent
+ to \l{QJsonArray::prepend()}{prepend(value)} and will prepend \a value to the array.
+*/
+
+/*! \fn void QJsonArray::pop_front()
+
+ This function is provided for STL compatibility. It is equivalent
+ to removeFirst(). The array must not be empty. If the array can be
+ empty, call isEmpty() before calling this function.
+*/
+
+/*! \fn void QJsonArray::pop_back()
+
+ This function is provided for STL compatibility. It is equivalent
+ to removeLast(). The array must not be empty. If the array can be
+ empty, call isEmpty() before calling this function.
+*/
+
+/*! \fn bool QJsonArray::empty() const
+
+ This function is provided for STL compatibility. It is equivalent
+ to isEmpty() and returns \c true if the array is empty.
+*/
+
+/*! \class QJsonArray::iterator
+ \inmodule QtCore
+ \brief The QJsonArray::iterator class provides an STL-style non-const iterator for QJsonArray.
+
+ QJsonArray::iterator allows you to iterate over a QJsonArray
+ and to modify the array item associated with the
+ iterator. If you want to iterate over a const QJsonArray, use
+ QJsonArray::const_iterator instead. It is generally a good practice to
+ use QJsonArray::const_iterator on a non-const QJsonArray as well, unless
+ you need to change the QJsonArray through the iterator. Const
+ iterators are slightly faster and improves code readability.
+
+ The default QJsonArray::iterator constructor creates an uninitialized
+ iterator. You must initialize it using a QJsonArray function like
+ QJsonArray::begin(), QJsonArray::end(), or QJsonArray::insert() before you can
+ start iterating.
+
+ Most QJsonArray functions accept an integer index rather than an
+ iterator. For that reason, iterators are rarely useful in
+ connection with QJsonArray. One place where STL-style iterators do
+ make sense is as arguments to \l{generic algorithms}.
+
+ Multiple iterators can be used on the same array. However, be
+ aware that any non-const function call performed on the QJsonArray
+ will render all existing iterators undefined.
+
+ \sa QJsonArray::const_iterator
+*/
+
+/*! \typedef QJsonArray::iterator::iterator_category
+
+ A synonym for \e {std::random_access_iterator_tag} indicating
+ this iterator is a random access iterator.
+*/
+
+/*! \typedef QJsonArray::iterator::difference_type
+
+ \internal
+*/
+
+/*! \typedef QJsonArray::iterator::value_type
+
+ \internal
+*/
+
+/*! \typedef QJsonArray::iterator::reference
+
+ \internal
+*/
+
+/*! \typedef QJsonArray::iterator::pointer
+
+ \internal
+*/
+
+/*! \fn QJsonArray::iterator::iterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like operator*() and operator++() should not be called
+ on an uninitialized iterator. Use operator=() to assign a value
+ to it before using it.
+
+ \sa QJsonArray::begin(), QJsonArray::end()
+*/
+
+/*! \fn QJsonArray::iterator::iterator(QJsonArray *array, int index)
+ \internal
+*/
+
+/*! \fn QJsonValueRef QJsonArray::iterator::operator*() const
+
+
+ Returns a modifiable reference to the current item.
+
+ You can change the value of an item by using operator*() on the
+ left side of an assignment.
+
+ The return value is of type QJsonValueRef, a helper class for QJsonArray
+ and QJsonObject. When you get an object of type QJsonValueRef, you can
+ use it as if it were a reference to a QJsonValue. If you assign to it,
+ the assignment will apply to the character in the QJsonArray of QJsonObject
+ from which you got the reference.
+*/
+
+/*! \fn QJsonValueRef *QJsonArray::iterator::operator->() const
+
+ Returns a pointer to a modifiable reference to the current item.
+*/
+
+/*! \fn QJsonValueRef QJsonArray::iterator::operator[](int j) const
+
+ Returns a modifiable reference to the item at offset \a j from the
+ item pointed to by this iterator (the item at position \c{*this + j}).
+
+ This function is provided to make QJsonArray iterators behave like C++
+ pointers.
+
+ The return value is of type QJsonValueRef, a helper class for QJsonArray
+ and QJsonObject. When you get an object of type QJsonValueRef, you can
+ use it as if it were a reference to a QJsonValue. If you assign to it,
+ the assignment will apply to the character in the QJsonArray of QJsonObject
+ from which you got the reference.
+
+ \sa operator+()
+*/
+
+/*!
+ \fn bool QJsonArray::iterator::operator==(const iterator &other) const
+ \fn bool QJsonArray::iterator::operator==(const const_iterator &other) const
+
+ Returns \c true if \a other points to the same item as this
+ iterator; otherwise returns \c false.
+
+ \sa operator!=()
+*/
+
+/*!
+ \fn bool QJsonArray::iterator::operator!=(const iterator &other) const
+ \fn bool QJsonArray::iterator::operator!=(const const_iterator &other) const
+
+ Returns \c true if \a other points to a different item than this
+ iterator; otherwise returns \c false.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn bool QJsonArray::iterator::operator<(const iterator& other) const
+ \fn bool QJsonArray::iterator::operator<(const const_iterator& other) const
+
+ Returns \c true if the item pointed to by this iterator is less than
+ the item pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QJsonArray::iterator::operator<=(const iterator& other) const
+ \fn bool QJsonArray::iterator::operator<=(const const_iterator& other) const
+
+ Returns \c true if the item pointed to by this iterator is less than
+ or equal to the item pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QJsonArray::iterator::operator>(const iterator& other) const
+ \fn bool QJsonArray::iterator::operator>(const const_iterator& other) const
+
+ Returns \c true if the item pointed to by this iterator is greater
+ than the item pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QJsonArray::iterator::operator>=(const iterator& other) const
+ \fn bool QJsonArray::iterator::operator>=(const const_iterator& other) const
+
+ Returns \c true if the item pointed to by this iterator is greater
+ than or equal to the item pointed to by the \a other iterator.
+*/
+
+/*! \fn QJsonArray::iterator &QJsonArray::iterator::operator++()
+
+ The prefix ++ operator, \c{++it}, advances the iterator to the
+ next item in the array and returns an iterator to the new current
+ item.
+
+ Calling this function on QJsonArray::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QJsonArray::iterator QJsonArray::iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator, \c{it++}, advances the iterator to the
+ next item in the array and returns an iterator to the previously
+ current item.
+*/
+
+/*! \fn QJsonArray::iterator &QJsonArray::iterator::operator--()
+
+ The prefix -- operator, \c{--it}, makes the preceding item
+ current and returns an iterator to the new current item.
+
+ Calling this function on QJsonArray::begin() leads to undefined results.
+
+ \sa operator++()
+*/
+
+/*! \fn QJsonArray::iterator QJsonArray::iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator, \c{it--}, makes the preceding item
+ current and returns an iterator to the previously current item.
+*/
+
+/*! \fn QJsonArray::iterator &QJsonArray::iterator::operator+=(int j)
+
+ Advances the iterator by \a j items. If \a j is negative, the
+ iterator goes backward.
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QJsonArray::iterator &QJsonArray::iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items. If \a j is negative,
+ the iterator goes forward.
+
+ \sa operator+=(), operator-()
+*/
+
+/*! \fn QJsonArray::iterator QJsonArray::iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator. If \a j is negative, the iterator goes backward.
+
+ \sa operator-(), operator+=()
+*/
+
+/*! \fn QJsonArray::iterator QJsonArray::iterator::operator-(int j) const
+
+ Returns an iterator to the item at \a j positions backward from
+ this iterator. If \a j is negative, the iterator goes forward.
+
+ \sa operator+(), operator-=()
+*/
+
+/*! \fn int QJsonArray::iterator::operator-(iterator other) const
+
+ Returns the number of items between the item pointed to by \a
+ other and the item pointed to by this iterator.
+*/
+
+/*! \class QJsonArray::const_iterator
+ \inmodule QtCore
+ \brief The QJsonArray::const_iterator class provides an STL-style const iterator for QJsonArray.
+
+ QJsonArray::const_iterator allows you to iterate over a
+ QJsonArray. If you want to modify the QJsonArray as
+ you iterate over it, use QJsonArray::iterator instead. It is generally a
+ good practice to use QJsonArray::const_iterator on a non-const QJsonArray
+ as well, unless you need to change the QJsonArray through the
+ iterator. Const iterators are slightly faster and improves
+ code readability.
+
+ The default QJsonArray::const_iterator constructor creates an
+ uninitialized iterator. You must initialize it using a QJsonArray
+ function like QJsonArray::constBegin(), QJsonArray::constEnd(), or
+ QJsonArray::insert() before you can start iterating.
+
+ Most QJsonArray functions accept an integer index rather than an
+ iterator. For that reason, iterators are rarely useful in
+ connection with QJsonArray. One place where STL-style iterators do
+ make sense is as arguments to \l{generic algorithms}.
+
+ Multiple iterators can be used on the same array. However, be
+ aware that any non-const function call performed on the QJsonArray
+ will render all existing iterators undefined.
+
+ \sa QJsonArray::iterator
+*/
+
+/*! \fn QJsonArray::const_iterator::const_iterator()
+
+ Constructs an uninitialized iterator.
+
+ Functions like operator*() and operator++() should not be called
+ on an uninitialized iterator. Use operator=() to assign a value
+ to it before using it.
+
+ \sa QJsonArray::constBegin(), QJsonArray::constEnd()
+*/
+
+/*! \fn QJsonArray::const_iterator::const_iterator(const QJsonArray *array, int index)
+ \internal
+*/
+
+/*! \typedef QJsonArray::const_iterator::iterator_category
+
+ A synonym for \e {std::random_access_iterator_tag} indicating
+ this iterator is a random access iterator.
+*/
+
+/*! \typedef QJsonArray::const_iterator::difference_type
+
+ \internal
+*/
+
+/*! \typedef QJsonArray::const_iterator::value_type
+
+ \internal
+*/
+
+/*! \typedef QJsonArray::const_iterator::reference
+
+ \internal
+*/
+
+/*! \typedef QJsonArray::const_iterator::pointer
+
+ \internal
+*/
+
+/*! \fn QJsonArray::const_iterator::const_iterator(const const_iterator &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*! \fn QJsonArray::const_iterator::const_iterator(const iterator &other)
+
+ Constructs a copy of \a other.
+*/
+
+/*! \fn QJsonValue QJsonArray::const_iterator::operator*() const
+
+ Returns the current item.
+*/
+
+/*! \fn QJsonValue *QJsonArray::const_iterator::operator->() const
+
+ Returns a pointer to the current item.
+*/
+
+/*! \fn QJsonValue QJsonArray::const_iterator::operator[](int j) const
+
+ Returns the item at offset \a j from the item pointed to by this iterator (the item at
+ position \c{*this + j}).
+
+ This function is provided to make QJsonArray iterators behave like C++
+ pointers.
+
+ \sa operator+()
+*/
+
+/*! \fn bool QJsonArray::const_iterator::operator==(const const_iterator &other) const
+
+ Returns \c true if \a other points to the same item as this
+ iterator; otherwise returns \c false.
+
+ \sa operator!=()
+*/
+
+/*! \fn bool QJsonArray::const_iterator::operator!=(const const_iterator &other) const
+
+ Returns \c true if \a other points to a different item than this
+ iterator; otherwise returns \c false.
+
+ \sa operator==()
+*/
+
+/*!
+ \fn bool QJsonArray::const_iterator::operator<(const const_iterator& other) const
+
+ Returns \c true if the item pointed to by this iterator is less than
+ the item pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QJsonArray::const_iterator::operator<=(const const_iterator& other) const
+
+ Returns \c true if the item pointed to by this iterator is less than
+ or equal to the item pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QJsonArray::const_iterator::operator>(const const_iterator& other) const
+
+ Returns \c true if the item pointed to by this iterator is greater
+ than the item pointed to by the \a other iterator.
+*/
+
+/*!
+ \fn bool QJsonArray::const_iterator::operator>=(const const_iterator& other) const
+
+ Returns \c true if the item pointed to by this iterator is greater
+ than or equal to the item pointed to by the \a other iterator.
+*/
+
+/*! \fn QJsonArray::const_iterator &QJsonArray::const_iterator::operator++()
+
+ The prefix ++ operator, \c{++it}, advances the iterator to the
+ next item in the array and returns an iterator to the new current
+ item.
+
+ Calling this function on QJsonArray::end() leads to undefined results.
+
+ \sa operator--()
+*/
+
+/*! \fn QJsonArray::const_iterator QJsonArray::const_iterator::operator++(int)
+
+ \overload
+
+ The postfix ++ operator, \c{it++}, advances the iterator to the
+ next item in the array and returns an iterator to the previously
+ current item.
+*/
+
+/*! \fn QJsonArray::const_iterator &QJsonArray::const_iterator::operator--()
+
+ The prefix -- operator, \c{--it}, makes the preceding item
+ current and returns an iterator to the new current item.
+
+ Calling this function on QJsonArray::begin() leads to undefined results.
+
+ \sa operator++()
+*/
+
+/*! \fn QJsonArray::const_iterator QJsonArray::const_iterator::operator--(int)
+
+ \overload
+
+ The postfix -- operator, \c{it--}, makes the preceding item
+ current and returns an iterator to the previously current item.
+*/
+
+/*! \fn QJsonArray::const_iterator &QJsonArray::const_iterator::operator+=(int j)
+
+ Advances the iterator by \a j items. If \a j is negative, the
+ iterator goes backward.
+
+ \sa operator-=(), operator+()
+*/
+
+/*! \fn QJsonArray::const_iterator &QJsonArray::const_iterator::operator-=(int j)
+
+ Makes the iterator go back by \a j items. If \a j is negative,
+ the iterator goes forward.
+
+ \sa operator+=(), operator-()
+*/
+
+/*! \fn QJsonArray::const_iterator QJsonArray::const_iterator::operator+(int j) const
+
+ Returns an iterator to the item at \a j positions forward from
+ this iterator. If \a j is negative, the iterator goes backward.
+
+ \sa operator-(), operator+=()
+*/
+
+/*! \fn QJsonArray::const_iterator QJsonArray::const_iterator::operator-(int j) const
+
+ Returns an iterator to the item at \a j positions backward from
+ this iterator. If \a j is negative, the iterator goes forward.
+
+ \sa operator+(), operator-=()
+*/
+
+/*! \fn int QJsonArray::const_iterator::operator-(const_iterator other) const
+
+ Returns the number of items between the item pointed to by \a
+ other and the item pointed to by this iterator.
+*/
+
+
+/*!
+ \internal
+ */
+void QJsonArray::detach(uint reserve)
+{
+ Q_UNUSED(reserve)
+ Q_ASSERT(!reserve);
+ detach2(0);
+}
+
+/*!
+ \internal
+ */
+bool QJsonArray::detach2(uint reserve)
+{
+ if (!d) {
+ if (reserve >= QJsonPrivate::Value::MaxSize) {
+ qWarning("QJson: Document too large to store in data structure");
+ return false;
+ }
+ d = new QJsonPrivate::Data(reserve, QJsonValue::Array);
+ a = static_cast<QJsonPrivate::Array *>(d->header->root());
+ d->ref.ref();
+ return true;
+ }
+ if (reserve == 0 && d->ref.load() == 1)
+ return true;
+
+ QJsonPrivate::Data *x = d->clone(a, reserve);
+ if (!x)
+ return false;
+ x->ref.ref();
+ if (!d->ref.deref())
+ delete d;
+ d = x;
+ a = static_cast<QJsonPrivate::Array *>(d->header->root());
+ return true;
+}
+
+/*!
+ \internal
+ */
+void QJsonArray::compact()
+{
+ if (!d || !d->compactionCounter)
+ return;
+
+ detach2();
+ d->compact();
+ a = static_cast<QJsonPrivate::Array *>(d->header->root());
+}
+
+
+#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
+QDebug operator<<(QDebug dbg, const QJsonArray &a)
+{
+ QDebugStateSaver saver(dbg);
+ if (!a.a) {
+ dbg << "QJsonArray()";
+ return dbg;
+ }
+ QByteArray json;
+ QJsonPrivate::Writer::arrayToJson(a.a, json, 0, true);
+ dbg.nospace() << "QJsonArray("
+ << json.constData() // print as utf-8 string without extra quotation marks
+ << ")";
+ return dbg;
+}
+#endif
+
+QT_END_NAMESPACE
+
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 2336278b17..ca8bd30698 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -200,7 +200,7 @@ qnx:qtConfig(qqnx_pps) {
kernel/qppsobjectprivate_p.h
}
-android {
+android:!android-embedded {
SOURCES += \
kernel/qjnionload.cpp \
kernel/qjnihelpers.cpp \
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 4bab0b9f01..4e32f90964 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -95,7 +95,7 @@
#endif
#endif // QT_NO_QOBJECT
-#if defined(Q_OS_ANDROID)
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
# include <private/qjni_p.h>
# include <private/qjnihelpers_p.h>
#endif
@@ -186,7 +186,7 @@ QString QCoreApplicationPrivate::appVersion() const
#ifndef QT_BOOTSTRAPPED
# ifdef Q_OS_DARWIN
applicationVersion = infoDictionaryStringProperty(QStringLiteral("CFBundleVersion"));
-# elif defined(Q_OS_ANDROID)
+# elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
QJNIObjectPrivate context(QtAndroidPrivate::context());
if (context.isValid()) {
QJNIObjectPrivate pm = context.callObjectMethod(
@@ -538,29 +538,10 @@ void QCoreApplicationPrivate::cleanupThreadData()
void QCoreApplicationPrivate::createEventDispatcher()
{
Q_Q(QCoreApplication);
-#if defined(Q_OS_UNIX)
-# if defined(Q_OS_DARWIN)
- bool ok = false;
- int value = qEnvironmentVariableIntValue("QT_EVENT_DISPATCHER_CORE_FOUNDATION", &ok);
- if (ok && value > 0)
- eventDispatcher = new QEventDispatcherCoreFoundation(q);
- else
- eventDispatcher = new QEventDispatcherUNIX(q);
-# elif !defined(QT_NO_GLIB)
- if (qEnvironmentVariableIsEmpty("QT_NO_GLIB") && QEventDispatcherGlib::versionSupported())
- eventDispatcher = new QEventDispatcherGlib(q);
- else
- eventDispatcher = new QEventDispatcherUNIX(q);
-# else
- eventDispatcher = new QEventDispatcherUNIX(q);
-# endif
-#elif defined(Q_OS_WINRT)
- eventDispatcher = new QEventDispatcherWinRT(q);
-#elif defined(Q_OS_WIN)
- eventDispatcher = new QEventDispatcherWin32(q);
-#else
-# error "QEventDispatcher not yet ported to this platform"
-#endif
+ QThreadData *data = QThreadData::current();
+ Q_ASSERT(!data->hasEventDispatcher());
+ eventDispatcher = QThreadPrivate::createEventDispatcher(data);
+ eventDispatcher->setParent(q);
}
void QCoreApplicationPrivate::eventDispatcherReady()
@@ -816,6 +797,14 @@ void QCoreApplicationPrivate::init()
if (!coreappdata()->applicationVersionSet)
coreappdata()->applicationVersion = appVersion();
+#if defined(Q_OS_ANDROID)
+ // We've deferred initializing the logging registry due to not being
+ // able to guarantee that logging happened on the same thread as the
+ // Qt main thread, but now that the Qt main thread is set up, we can
+ // enable categorized logging.
+ QLoggingRegistry::instance()->initializeRules();
+#endif
+
#if QT_CONFIG(library)
// Reset the lib paths, so that they will be recomputed, taking the availability of argv[0]
// into account. If necessary, recompute right away and replay the manual changes on top of the
@@ -848,8 +837,9 @@ void QCoreApplicationPrivate::init()
#ifndef QT_NO_QOBJECT
// use the event dispatcher created by the app programmer (if any)
- if (!eventDispatcher)
- eventDispatcher = threadData->eventDispatcher.load();
+ Q_ASSERT(!eventDispatcher);
+ eventDispatcher = threadData->eventDispatcher.load();
+
// otherwise we create one
if (!eventDispatcher)
createEventDispatcher();
@@ -2266,7 +2256,7 @@ QString QCoreApplication::applicationFilePath()
}
#endif
#if defined( Q_OS_UNIX )
-# if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
+# if defined(Q_OS_LINUX) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_EMBEDDED))
// Try looking for a /proc/<pid>/exe symlink first which points to
// the absolute path of the executable
QFileInfo pfi(QString::fromLatin1("/proc/%1/exe").arg(getpid()));
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index bbd442d570..330870f219 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -905,6 +905,7 @@ bool QEventDispatcherWin32::registerEventNotifier(QWinEventNotifier *notifier)
return true;
d->winEventNotifierList.append(notifier);
+ d->winEventNotifierListModified = true;
if (!d->winEventNotifierActivatedEvent)
d->winEventNotifierActivatedEvent = CreateEvent(0, TRUE, FALSE, nullptr);
@@ -928,6 +929,7 @@ void QEventDispatcherWin32::unregisterEventNotifier(QWinEventNotifier *notifier)
if (i == -1)
return;
d->winEventNotifierList.takeAt(i);
+ d->winEventNotifierListModified = true;
QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier);
if (nd->waitHandle)
nd->unregisterWaitObject();
@@ -938,16 +940,19 @@ void QEventDispatcherWin32::activateEventNotifiers()
Q_D(QEventDispatcherWin32);
ResetEvent(d->winEventNotifierActivatedEvent);
- // Iterate backwards, because the notifier might remove itself on activate().
- for (int i = d->winEventNotifierList.count(); --i >= 0;) {
- QWinEventNotifier *notifier = d->winEventNotifierList.at(i);
- QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier);
- if (nd->signaledCount.load() != 0) {
- --nd->signaledCount;
- nd->unregisterWaitObject();
- d->activateEventNotifier(notifier);
+ // Activate signaled notifiers. Our winEventNotifierList can be modified in activation slots.
+ do {
+ d->winEventNotifierListModified = false;
+ for (int i = 0; i < d->winEventNotifierList.count(); ++i) {
+ QWinEventNotifier *notifier = d->winEventNotifierList.at(i);
+ QWinEventNotifierPrivate *nd = QWinEventNotifierPrivate::get(notifier);
+ if (nd->signaledCount.load() != 0) {
+ --nd->signaledCount;
+ nd->unregisterWaitObject();
+ d->activateEventNotifier(notifier);
+ }
}
- }
+ } while (d->winEventNotifierListModified);
// Re-register the remaining activated notifiers.
for (int i = 0; i < d->winEventNotifierList.count(); ++i) {
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index 683c7f8f36..a7ed8dda8a 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -195,6 +195,7 @@ public:
HANDLE winEventNotifierActivatedEvent;
QList<QWinEventNotifier *> winEventNotifierList;
+ bool winEventNotifierListModified = false;
void activateEventNotifier(QWinEventNotifier * wen);
QList<MSG> queuedUserInputEvents;
diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp
index 8974ff7709..6034698349 100644
--- a/src/corelib/kernel/qeventloop.cpp
+++ b/src/corelib/kernel/qeventloop.cpp
@@ -101,8 +101,10 @@ QEventLoop::QEventLoop(QObject *parent)
Q_D(QEventLoop);
if (!QCoreApplication::instance() && QCoreApplicationPrivate::threadRequiresCoreApplication()) {
qWarning("QEventLoop: Cannot be used without QApplication");
- } else if (!d->threadData->eventDispatcher.load()) {
- QThreadPrivate::createEventDispatcher(d->threadData);
+ } else if (!d->threadData->hasEventDispatcher()) {
+ QAbstractEventDispatcher *eventDispatcher = QThreadPrivate::createEventDispatcher(d->threadData);
+ d->threadData->eventDispatcher.storeRelease(eventDispatcher);
+ eventDispatcher->startingUp();
}
}
@@ -129,7 +131,7 @@ QEventLoop::~QEventLoop()
bool QEventLoop::processEvents(ProcessEventsFlags flags)
{
Q_D(QEventLoop);
- if (!d->threadData->eventDispatcher.load())
+ if (!d->threadData->hasEventDispatcher())
return false;
return d->threadData->eventDispatcher.load()->processEvents(flags);
}
@@ -234,7 +236,7 @@ int QEventLoop::exec(ProcessEventsFlags flags)
void QEventLoop::processEvents(ProcessEventsFlags flags, int maxTime)
{
Q_D(QEventLoop);
- if (!d->threadData->eventDispatcher.load())
+ if (!d->threadData->hasEventDispatcher())
return;
QElapsedTimer start;
@@ -263,7 +265,7 @@ void QEventLoop::processEvents(ProcessEventsFlags flags, int maxTime)
void QEventLoop::exit(int returnCode)
{
Q_D(QEventLoop);
- if (!d->threadData->eventDispatcher.load())
+ if (!d->threadData->hasEventDispatcher())
return;
d->returnCode.store(returnCode);
@@ -292,7 +294,7 @@ bool QEventLoop::isRunning() const
void QEventLoop::wakeUp()
{
Q_D(QEventLoop);
- if (!d->threadData->eventDispatcher.load())
+ if (!d->threadData->hasEventDispatcher())
return;
d->threadData->eventDispatcher.load()->wakeUp();
}
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 263c4019f7..9e1c3a50cb 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -238,7 +238,7 @@ QObjectPrivate::~QObjectPrivate()
if (extraData && !extraData->runningTimers.isEmpty()) {
if (Q_LIKELY(threadData->thread == QThread::currentThread())) {
// unregister pending timers
- if (threadData->eventDispatcher.load())
+ if (threadData->hasEventDispatcher())
threadData->eventDispatcher.load()->unregisterTimers(q_ptr);
// release the timer ids back to the pool
@@ -1538,7 +1538,7 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData
++eventsMoved;
}
}
- if (eventsMoved > 0 && targetData->eventDispatcher.load()) {
+ if (eventsMoved > 0 && targetData->hasEventDispatcher()) {
targetData->canWait = false;
targetData->eventDispatcher.load()->wakeUp();
}
@@ -1621,7 +1621,7 @@ int QObject::startTimer(int interval, Qt::TimerType timerType)
qWarning("QObject::startTimer: Timers cannot have negative intervals");
return 0;
}
- if (Q_UNLIKELY(!d->threadData->eventDispatcher.load())) {
+ if (Q_UNLIKELY(!d->threadData->hasEventDispatcher())) {
qWarning("QObject::startTimer: Timers can only be used with threads started with QThread");
return 0;
}
@@ -1703,7 +1703,7 @@ void QObject::killTimer(int id)
return;
}
- if (d->threadData->eventDispatcher.load())
+ if (d->threadData->hasEventDispatcher())
d->threadData->eventDispatcher.load()->unregisterTimer(id);
d->extraData->runningTimers.remove(at);
diff --git a/src/corelib/kernel/qsocketnotifier.cpp b/src/corelib/kernel/qsocketnotifier.cpp
index 2268cb83bb..6ff8268978 100644
--- a/src/corelib/kernel/qsocketnotifier.cpp
+++ b/src/corelib/kernel/qsocketnotifier.cpp
@@ -149,7 +149,7 @@ QSocketNotifier::QSocketNotifier(qintptr socket, Type type, QObject *parent)
if (socket < 0)
qWarning("QSocketNotifier: Invalid socket specified");
- else if (!d->threadData->eventDispatcher.load())
+ else if (!d->threadData->hasEventDispatcher())
qWarning("QSocketNotifier: Can only be used with threads started with QThread");
else
d->threadData->eventDispatcher.load()->registerSocketNotifier(this);
@@ -234,7 +234,7 @@ void QSocketNotifier::setEnabled(bool enable)
return;
d->snenabled = enable;
- if (!d->threadData->eventDispatcher.load()) // perhaps application/thread is shutting down
+ if (!d->threadData->hasEventDispatcher()) // perhaps application/thread is shutting down
return;
if (Q_UNLIKELY(thread() != QThread::currentThread())) {
qWarning("QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread");
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index bca6918b4a..a3b8be8911 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -239,21 +239,34 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
if (lib)
lib->errorString = file.errorString();
if (qt_debug_component()) {
- qWarning("%s: %s", (const char*) QFile::encodeName(library),
+ qWarning("%s: %s", QFile::encodeName(library).constData(),
qPrintable(QSystemError::stdString()));
}
return false;
}
QByteArray data;
- const char *filedata = 0;
ulong fdlen = file.size();
- filedata = (char *) file.map(0, fdlen);
+ const char *filedata = reinterpret_cast<char *>(file.map(0, fdlen));
+
if (filedata == 0) {
- // try reading the data into memory instead
- data = file.readAll();
- filedata = data.constData();
- fdlen = data.size();
+ if (uchar *mapdata = file.map(0, 1)) {
+ file.unmap(mapdata);
+ // Mapping is supported, but failed for the entire file, likely due to OOM.
+ // Return false, as readAll() would cause a bad_alloc and terminate the process.
+ if (lib)
+ lib->errorString = QLibrary::tr("Out of memory while loading plugin '%1'.").arg(library);
+ if (qt_debug_component()) {
+ qWarning("%s: %s", QFile::encodeName(library).constData(),
+ qPrintable(QSystemError::stdString(ENOMEM)));
+ }
+ return false;
+ } else {
+ // Try reading the data into memory instead.
+ data = file.readAll();
+ filedata = data.constData();
+ fdlen = data.size();
+ }
}
/*
@@ -751,7 +764,7 @@ void QLibraryPrivate::updatePluginState()
if (qt_debug_component()) {
qWarning("In %s:\n"
" Plugin uses incompatible Qt library (%d.%d.%d) [%s]",
- (const char*) QFile::encodeName(fileName),
+ QFile::encodeName(fileName).constData(),
(qt_version&0xff0000) >> 16, (qt_version&0xff00) >> 8, qt_version&0xff,
debug ? "debug" : "release");
}
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index 3c4fbaf348..23b9ad6434 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -44,25 +44,17 @@
#include <qcoreapplication.h>
#include <private/qfilesystementry_p.h>
+#include <dlfcn.h>
+
#ifdef Q_OS_MAC
# include <private/qcore_mac_p.h>
#endif
QT_BEGIN_NAMESPACE
-#if !defined(QT_HPUX_LD)
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <dlfcn.h>
-QT_END_INCLUDE_NAMESPACE
-#endif
-
static QString qdlerror()
{
-#if !defined(QT_HPUX_LD)
const char *err = dlerror();
-#else
- const char *err = strerror(errno);
-#endif
return err ? QLatin1Char('(') + QString::fromLocal8Bit(err) + QLatin1Char(')'): QString();
}
@@ -139,14 +131,6 @@ bool QLibraryPrivate::load_sys()
suffixes = suffixes_sys(fullVersion);
}
int dlFlags = 0;
-#if defined(QT_HPUX_LD)
- dlFlags = DYNAMIC_PATH | BIND_NONFATAL;
- if (loadHints & QLibrary::ResolveAllSymbolsHint) {
- dlFlags |= BIND_IMMEDIATE;
- } else {
- dlFlags |= BIND_DEFERRED;
- }
-#else
int loadHints = this->loadHints();
if (loadHints & QLibrary::ResolveAllSymbolsHint) {
dlFlags |= RTLD_NOW;
@@ -182,7 +166,6 @@ bool QLibraryPrivate::load_sys()
dlFlags |= RTLD_MEMBER;
}
#endif
-#endif // QT_HPUX_LD
// If the filename is an absolute path then we want to try that first as it is most likely
// what the callee wants. If we have been given a non-absolute path then lets try the
@@ -211,11 +194,7 @@ bool QLibraryPrivate::load_sys()
} else {
attempt = path + prefixes.at(prefix) + name + suffixes.at(suffix);
}
-#if defined(QT_HPUX_LD)
- pHnd = (void*)shl_load(QFile::encodeName(attempt), dlFlags, 0);
-#else
pHnd = dlopen(QFile::encodeName(attempt), dlFlags);
-#endif
if (!pHnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) {
// We only want to continue if dlopen failed due to that the shared library did not exist.
@@ -253,11 +232,7 @@ bool QLibraryPrivate::load_sys()
bool QLibraryPrivate::unload_sys()
{
-#if defined(QT_HPUX_LD)
- if (shl_unload((shl_t)pHnd)) {
-#else
if (dlclose(pHnd)) {
-#endif
#if defined (Q_OS_QNX) // Workaround until fixed in QNX; fixes crash in
char *error = dlerror(); // QtDeclarative auto test "qqmlenginecleanup" for instance
if (!qstrcmp(error, "Shared objects still referenced")) // On QNX that's only "informative"
@@ -289,13 +264,7 @@ Q_CORE_EXPORT QFunctionPointer qt_mac_resolve_sys(void *handle, const char *symb
QFunctionPointer QLibraryPrivate::resolve_sys(const char* symbol)
{
-#if defined(QT_HPUX_LD)
- QFunctionPointer address = 0;
- if (shl_findsym((shl_t*)&pHnd, symbol, TYPE_UNDEFINED, &address) < 0)
- address = 0;
-#else
QFunctionPointer address = QFunctionPointer(dlsym(pHnd, symbol));
-#endif
if (!address) {
errorString = QLibrary::tr("Cannot resolve symbol \"%1\" in %2: %3").arg(
QString::fromLatin1(symbol), fileName, qdlerror());
diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h
index baeefd87ff..46294a5fc8 100644
--- a/src/corelib/thread/qthread_p.h
+++ b/src/corelib/thread/qthread_p.h
@@ -195,7 +195,7 @@ public:
#endif // Q_OS_WIN
QThreadData *data;
- static void createEventDispatcher(QThreadData *data);
+ static QAbstractEventDispatcher *createEventDispatcher(QThreadData *data);
void ref()
{
@@ -222,7 +222,7 @@ public:
static void setCurrentThread(QThread*) {}
static QThread *threadForId(int) { return QThread::currentThread(); }
- static void createEventDispatcher(QThreadData *data);
+ static QAbstractEventDispatcher *createEventDispatcher(QThreadData *data);
void ref() {}
void deref() {}
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 1bb8e613e0..6248842d78 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -285,27 +285,27 @@ typedef void*(*QtThreadCallback)(void*);
#endif // QT_NO_THREAD
-void QThreadPrivate::createEventDispatcher(QThreadData *data)
+QAbstractEventDispatcher *QThreadPrivate::createEventDispatcher(QThreadData *data)
{
+ Q_UNUSED(data);
#if defined(Q_OS_DARWIN)
bool ok = false;
int value = qEnvironmentVariableIntValue("QT_EVENT_DISPATCHER_CORE_FOUNDATION", &ok);
if (ok && value > 0)
- data->eventDispatcher.storeRelease(new QEventDispatcherCoreFoundation);
+ return new QEventDispatcherCoreFoundation;
else
- data->eventDispatcher.storeRelease(new QEventDispatcherUNIX);
+ return new QEventDispatcherUNIX;
#elif !defined(QT_NO_GLIB)
+ const bool isQtMainThread = data->thread == QCoreApplicationPrivate::mainThread();
if (qEnvironmentVariableIsEmpty("QT_NO_GLIB")
- && qEnvironmentVariableIsEmpty("QT_NO_THREADED_GLIB")
+ && (isQtMainThread || qEnvironmentVariableIsEmpty("QT_NO_THREADED_GLIB"))
&& QEventDispatcherGlib::versionSupported())
- data->eventDispatcher.storeRelease(new QEventDispatcherGlib);
+ return new QEventDispatcherGlib;
else
- data->eventDispatcher.storeRelease(new QEventDispatcherUNIX);
+ return new QEventDispatcherUNIX;
#else
- data->eventDispatcher.storeRelease(new QEventDispatcherUNIX);
+ return new QEventDispatcherUNIX;
#endif
-
- data->eventDispatcher.load()->startingUp();
}
#ifndef QT_NO_THREAD
@@ -352,10 +352,13 @@ void *QThreadPrivate::start(void *arg)
data->quitNow = thr->d_func()->exited;
}
- if (data->eventDispatcher.load()) // custom event dispatcher set?
- data->eventDispatcher.load()->startingUp();
- else
- createEventDispatcher(data);
+ QAbstractEventDispatcher *eventDispatcher = data->eventDispatcher.load();
+ if (!eventDispatcher) {
+ eventDispatcher = createEventDispatcher(data);
+ data->eventDispatcher.storeRelease(eventDispatcher);
+ }
+
+ eventDispatcher->startingUp();
#if (defined(Q_OS_LINUX) || defined(Q_OS_MAC) || defined(Q_OS_QNX))
{
diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp
index 24d3ca2d7d..4459ae87af 100644
--- a/src/corelib/thread/qthread_win.cpp
+++ b/src/corelib/thread/qthread_win.cpp
@@ -331,15 +331,14 @@ void qt_set_thread_name(HANDLE threadId, LPCSTR threadName)
#endif // QT_NO_THREAD
-void QThreadPrivate::createEventDispatcher(QThreadData *data)
+QAbstractEventDispatcher *QThreadPrivate::createEventDispatcher(QThreadData *data)
{
+ Q_UNUSED(data);
#ifndef Q_OS_WINRT
- QEventDispatcherWin32 *theEventDispatcher = new QEventDispatcherWin32;
+ return new QEventDispatcherWin32;
#else
- QEventDispatcherWinRT *theEventDispatcher = new QEventDispatcherWinRT;
+ return new QEventDispatcherWinRT;
#endif
- data->eventDispatcher.storeRelease(theEventDispatcher);
- theEventDispatcher->startingUp();
}
#ifndef QT_NO_THREAD
@@ -360,10 +359,13 @@ unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(voi
data->quitNow = thr->d_func()->exited;
}
- if (data->eventDispatcher.load()) // custom event dispatcher set?
- data->eventDispatcher.load()->startingUp();
- else
- createEventDispatcher(data);
+ QAbstractEventDispatcher *eventDispatcher = data->eventDispatcher.load();
+ if (!eventDispatcher) {
+ eventDispatcher = createEventDispatcher(data);
+ data->eventDispatcher.storeRelease(eventDispatcher);
+ }
+
+ eventDispatcher->startingUp();
#if !defined(QT_NO_DEBUG) && defined(Q_CC_MSVC) && !defined(Q_OS_WINRT)
// sets the name of the current thread.
diff --git a/src/corelib/tools/CLDR_LICENSE.txt b/src/corelib/tools/UNICODE_LICENSE.txt
index ad28161436..1c73202b74 100644
--- a/src/corelib/tools/CLDR_LICENSE.txt
+++ b/src/corelib/tools/UNICODE_LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright © 1991-2016 Unicode, Inc. All rights reserved.
+Copyright © 1991-2018 Unicode, Inc. All rights reserved.
Distributed under the Terms of Use in http://www.unicode.org/copyright.html.
Permission is hereby granted, free of charge, to any person obtaining
diff --git a/src/corelib/tools/qarraydataops.h b/src/corelib/tools/qarraydataops.h
index b7c3bc1287..d0f83d2b6a 100644
--- a/src/corelib/tools/qarraydataops.h
+++ b/src/corelib/tools/qarraydataops.h
@@ -76,7 +76,8 @@ struct QPodArrayOps
Q_ASSERT(b < e);
Q_ASSERT(size_t(e - b) <= this->alloc - uint(this->size));
- ::memcpy(this->end(), b, (e - b) * sizeof(T));
+ ::memcpy(static_cast<void *>(this->end()), static_cast<const void *>(b),
+ (e - b) * sizeof(T));
this->size += e - b;
}
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 1e676365b0..b465bdc0f4 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -3855,14 +3855,14 @@ QString& QString::replace(const QRegExp &rx, const QString &after)
while (i < pos) {
int copyend = replacements[i].pos;
int size = copyend - copystart;
- memcpy(uc, d->data() + copystart, size * sizeof(QChar));
+ memcpy(static_cast<void*>(uc), static_cast<const void *>(d->data() + copystart), size * sizeof(QChar));
uc += size;
- memcpy(uc, after.d->data(), al * sizeof(QChar));
+ memcpy(static_cast<void *>(uc), static_cast<const void *>(after.d->data()), al * sizeof(QChar));
uc += al;
copystart = copyend + replacements[i].length;
i++;
}
- memcpy(uc, d->data() + copystart, (d->size - copystart) * sizeof(QChar));
+ memcpy(static_cast<void *>(uc), static_cast<const void *>(d->data() + copystart), (d->size - copystart) * sizeof(QChar));
newstring.resize(newlen);
*this = newstring;
caretMode = QRegExp::CaretWontMatch;
@@ -6353,7 +6353,7 @@ QString QString::rightJustified(int width, QChar fill, bool truncate) const
while (padlen--)
* uc++ = fill;
if (len)
- memcpy(uc, d->data(), sizeof(QChar)*len);
+ memcpy(static_cast<void *>(uc), static_cast<const void *>(d->data()), sizeof(QChar)*len);
} else {
if (truncate)
result = left(width);
@@ -6931,6 +6931,8 @@ QString QString::vasprintf(const char *cformat, va_list ap)
\snippet qstring/main.cpp 74
+ This function ignores leading and trailing whitespace.
+
\sa number(), toULongLong(), toInt(), QLocale::toLongLong()
*/
@@ -6971,6 +6973,8 @@ qlonglong QString::toIntegral_helper(const QChar *data, int len, bool *ok, int b
\snippet qstring/main.cpp 79
+ This function ignores leading and trailing whitespace.
+
\sa number(), toLongLong(), QLocale::toULongLong()
*/
@@ -7013,6 +7017,8 @@ qulonglong QString::toIntegral_helper(const QChar *data, uint len, bool *ok, int
\snippet qstring/main.cpp 73
+ This function ignores leading and trailing whitespace.
+
\sa number(), toULong(), toInt(), QLocale::toInt()
*/
@@ -7042,6 +7048,8 @@ long QString::toLong(bool *ok, int base) const
\snippet qstring/main.cpp 78
+ This function ignores leading and trailing whitespace.
+
\sa number(), QLocale::toUInt()
*/
@@ -7070,6 +7078,8 @@ ulong QString::toULong(bool *ok, int base) const
\snippet qstring/main.cpp 72
+ This function ignores leading and trailing whitespace.
+
\sa number(), toUInt(), toDouble(), QLocale::toInt()
*/
@@ -7097,6 +7107,8 @@ int QString::toInt(bool *ok, int base) const
\snippet qstring/main.cpp 77
+ This function ignores leading and trailing whitespace.
+
\sa number(), toInt(), QLocale::toUInt()
*/
@@ -7124,6 +7136,8 @@ uint QString::toUInt(bool *ok, int base) const
\snippet qstring/main.cpp 76
+ This function ignores leading and trailing whitespace.
+
\sa number(), toUShort(), toInt(), QLocale::toShort()
*/
@@ -7151,6 +7165,8 @@ short QString::toShort(bool *ok, int base) const
\snippet qstring/main.cpp 80
+ This function ignores leading and trailing whitespace.
+
\sa number(), toShort(), QLocale::toUShort()
*/
@@ -7170,7 +7186,10 @@ ushort QString::toUShort(bool *ok, int base) const
\snippet qstring/main.cpp 66
- \warning The QString content may only contain valid numerical characters which includes the plus/minus sign, the characters g and e used in scientific notation, and the decimal point. Including the unit or additional characters leads to a conversion error.
+ \warning The QString content may only contain valid numerical characters
+ which includes the plus/minus sign, the characters g and e used in scientific
+ notation, and the decimal point. Including the unit or additional characters
+ leads to a conversion error.
\snippet qstring/main.cpp 67
@@ -7185,6 +7204,8 @@ ushort QString::toUShort(bool *ok, int base) const
\snippet qstring/main.cpp 69
+ This function ignores leading and trailing whitespace.
+
\sa number(), QLocale::setDefault(), QLocale::toDouble(), trimmed()
*/
@@ -7199,6 +7220,8 @@ double QString::toDouble(bool *ok) const
If a conversion error occurs, *\a{ok} is set to \c false; otherwise
*\a{ok} is set to \c true. Returns 0.0 if the conversion fails.
+ This function ignores leading and trailing whitespace.
+
The string conversion will always happen in the 'C' locale. For locale
dependent conversion use QLocale::toFloat()
@@ -7206,6 +7229,8 @@ double QString::toDouble(bool *ok) const
\snippet qstring/main.cpp 71
+ This function ignores leading and trailing whitespace.
+
\sa number(), toDouble(), toInt(), QLocale::toFloat()
*/
@@ -11878,7 +11903,7 @@ QString QString::toHtmlEscaped() const
This cost can be avoided by using QStringLiteral instead:
\code
- if (node.hasAttribute(QStringLiteral("http-contents-length"))) //...
+ if (node.hasAttribute(QStringLiteral(u"http-contents-length"))) //...
\endcode
In this case, QString's internal data will be generated at compile time; no
@@ -11898,6 +11923,10 @@ QString QString::toHtmlEscaped() const
if (attribute.name() == QLatin1String("http-contents-length")) //...
\endcode
+ \note Some compilers have bugs encoding strings containing characters outside
+ the US-ASCII character set. Make sure you prefix your string with \c{u} in
+ those cases. It is optional otherwise.
+
\sa QByteArrayLiteral
*/
diff --git a/src/corelib/tools/qt_attribution.json b/src/corelib/tools/qt_attribution.json
index eec2cd6795..49a76cb8b4 100644
--- a/src/corelib/tools/qt_attribution.json
+++ b/src/corelib/tools/qt_attribution.json
@@ -1,13 +1,35 @@
+[
{
- "Id": "cldr-data",
- "Name": "Unicode CLDR (Unicode Common Locale Data Repository)",
+ "Id": "unicode-character-database",
+ "Name": "Unicode Character Database (UCD)",
"QDocModule": "qtcore",
- "QtUsage": "Used in Qt Core (QTimeZone). Disable the timezone feature to avoid.",
- "Files": "qlocale_data_p.h",
+ "QtUsage": "Qt Core uses data obtained from UCD files for working with characters and strings.",
+ "Files": "qunicodetables_p.h qunicodetables.cpp",
- "Description": "QTimeZone includes data obtained from the CLDR data files.",
- "License": "Unicode Data Files and Software License",
- "LicenseId": "Unicode-TOU",
- "LicenseFile": "CLDR_LICENSE.txt",
- "Copyright": "Copyright (C) 1991-2016 Unicode, Inc."
+ "Description": "The Unicode Character Database (UCD) is a set of files that
+ define the Unicode character properties and internal mappings.",
+ "Homepage": "https://www.unicode.org/ucd/",
+ "Version": "10.0.0",
+ "License": "Unicode License Agreement - Data Files and Software (2016)",
+ "LicenseId": "Unicode-DFS-2016",
+ "LicenseFile": "UNICODE_LICENSE.txt",
+ "Copyright": "Copyright (C) 1991-2018 Unicode, Inc."
+},
+{
+ "Id": "unicode-cldr",
+ "Name": "Unicode Common Locale Data Repository (CLDR)",
+ "QDocModule": "qtcore",
+ "QtUsage": "Used in Qt Core (QTimeZone, QLocale).",
+ "Files": "qlocale_data_p.h qtimezoneprivate_data_p.h",
+
+ "Description": "The Unicode CLDR provides key building blocks for software to support the
+ world's languages, with the largest and most extensive standard repository of locale data
+ available.",
+ "Homepage": "http://cldr.unicode.org/",
+ "Version": "v31.0.1",
+ "License": "Unicode License Agreement - Data Files and Software (2016)",
+ "LicenseId": "Unicode-DFS-2016",
+ "LicenseFile": "UNICODE_LICENSE.txt",
+ "Copyright": "Copyright (C) 1991-2017 Unicode, Inc."
}
+]
diff --git a/src/corelib/tools/qtimezone.cpp b/src/corelib/tools/qtimezone.cpp
index a9a9b4f25e..29299bfcd6 100644
--- a/src/corelib/tools/qtimezone.cpp
+++ b/src/corelib/tools/qtimezone.cpp
@@ -62,9 +62,9 @@ static QTimeZonePrivate *newBackendTimeZone()
#else
#if defined Q_OS_MAC
return new QMacTimeZonePrivate();
-#elif defined Q_OS_ANDROID
+#elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
return new QAndroidTimeZonePrivate();
-#elif defined Q_OS_UNIX
+#elif defined(Q_OS_UNIX) || defined(Q_OS_ANDROID_EMBEDDED)
return new QTzTimeZonePrivate();
#elif QT_CONFIG(icu)
return new QIcuTimeZonePrivate();
@@ -88,9 +88,9 @@ static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId)
#else
#if defined Q_OS_MAC
return new QMacTimeZonePrivate(ianaId);
-#elif defined Q_OS_ANDROID
+#elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
return new QAndroidTimeZonePrivate(ianaId);
-#elif defined Q_OS_UNIX
+#elif defined(Q_OS_UNIX) || defined(Q_OS_ANDROID_EMBEDDED)
return new QTzTimeZonePrivate(ianaId);
#elif QT_CONFIG(icu)
return new QIcuTimeZonePrivate(ianaId);
diff --git a/src/corelib/tools/qtimezoneprivate_p.h b/src/corelib/tools/qtimezoneprivate_p.h
index ca36f9d297..4d357111f2 100644
--- a/src/corelib/tools/qtimezoneprivate_p.h
+++ b/src/corelib/tools/qtimezoneprivate_p.h
@@ -68,7 +68,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(NSTimeZone);
#include <qt_windows.h>
#endif // Q_OS_WIN
-#ifdef Q_OS_ANDROID
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
#include <QtCore/private/qjni_p.h>
#endif
@@ -266,7 +266,7 @@ private:
};
#endif
-#if defined Q_OS_UNIX && !defined Q_OS_MAC && !defined Q_OS_ANDROID
+#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_EMBEDDED))
struct QTzTransitionTime
{
qint64 atMSecsSinceEpoch;
@@ -442,7 +442,7 @@ private:
};
#endif // Q_OS_WIN
-#ifdef Q_OS_ANDROID
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
class QAndroidTimeZonePrivate final : public QTimeZonePrivate
{
public:
diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h
index b2f05452ae..d0088471c7 100644
--- a/src/corelib/tools/qvarlengtharray.h
+++ b/src/corelib/tools/qvarlengtharray.h
@@ -344,7 +344,7 @@ Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::append(const T *abuf, in
while (s < asize)
new (ptr+(s++)) T(*abuf++);
} else {
- memcpy(&ptr[s], abuf, increment * sizeof(T));
+ memcpy(static_cast<void *>(&ptr[s]), static_cast<const void *>(abuf), increment * sizeof(T));
s = asize;
}
}
@@ -392,7 +392,7 @@ Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::realloc(int asize, int a
QT_RETHROW;
}
} else {
- memcpy(ptr, oldPtr, copySize * sizeof(T));
+ memcpy(static_cast<void *>(ptr), static_cast<const void *>(oldPtr), copySize * sizeof(T));
}
}
s = copySize;
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 24a19e68d4..9a6e67cc0b 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -747,7 +747,7 @@ typename QVector<T>::iterator QVector<T>::insert(iterator before, size_type n, c
} else {
T *b = d->begin() + offset;
T *i = b + n;
- memmove(i, b, (d->size - offset) * sizeof(T));
+ memmove(static_cast<void *>(i), static_cast<const void *>(b), (d->size - offset) * sizeof(T));
while (i != b)
new (--i) T(copy);
}
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 86afb46b8a..88708851d7 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -161,7 +161,7 @@ qtConfig(timezone) {
tools/qtimezoneprivate.cpp
!nacl:darwin: {
SOURCES += tools/qtimezoneprivate_mac.mm
- } else: android: {
+ } else: android:!android-embedded: {
SOURCES += tools/qtimezoneprivate_android.cpp
} else: unix: {
SOURCES += tools/qtimezoneprivate_tz.cpp
diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h
new file mode 100644
index 0000000000..e6c89e40cd
--- /dev/null
+++ b/src/corelib/xml/qxmlstream_p.h
@@ -0,0 +1,1966 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/private/qglobal_p.h>
+
+// This file was generated by qlalr - DO NOT EDIT!
+#ifndef QXMLSTREAM_P_H
+#define QXMLSTREAM_P_H
+
+#if defined(ERROR)
+# undef ERROR
+#endif
+
+class QXmlStreamReader_Table
+{
+public:
+ enum VariousConstants {
+ EOF_SYMBOL = 0,
+ AMPERSAND = 5,
+ ANY = 41,
+ ATTLIST = 31,
+ BANG = 25,
+ CDATA = 47,
+ CDATA_START = 28,
+ COLON = 17,
+ COMMA = 19,
+ DASH = 20,
+ DBLQUOTE = 8,
+ DIGIT = 27,
+ DOCTYPE = 29,
+ DOT = 23,
+ ELEMENT = 30,
+ EMPTY = 40,
+ ENTITIES = 51,
+ ENTITY = 32,
+ ENTITY_DONE = 45,
+ EQ = 14,
+ ERROR = 43,
+ FIXED = 39,
+ HASH = 6,
+ ID = 48,
+ IDREF = 49,
+ IDREFS = 50,
+ IMPLIED = 38,
+ LANGLE = 3,
+ LBRACK = 9,
+ LETTER = 26,
+ LPAREN = 11,
+ NDATA = 36,
+ NMTOKEN = 52,
+ NMTOKENS = 53,
+ NOTATION = 33,
+ NOTOKEN = 1,
+ PARSE_ENTITY = 44,
+ PCDATA = 42,
+ PERCENT = 15,
+ PIPE = 13,
+ PLUS = 21,
+ PUBLIC = 35,
+ QUESTIONMARK = 24,
+ QUOTE = 7,
+ RANGLE = 4,
+ RBRACK = 10,
+ REQUIRED = 37,
+ RPAREN = 12,
+ SEMICOLON = 18,
+ SHIFT_THERE = 56,
+ SLASH = 16,
+ SPACE = 2,
+ STAR = 22,
+ SYSTEM = 34,
+ UNRESOLVED_ENTITY = 46,
+ VERSION = 55,
+ XML = 54,
+
+ ACCEPT_STATE = 416,
+ RULE_COUNT = 270,
+ STATE_COUNT = 427,
+ TERMINAL_COUNT = 57,
+ NON_TERMINAL_COUNT = 84,
+
+ GOTO_INDEX_OFFSET = 427,
+ GOTO_INFO_OFFSET = 1017,
+ GOTO_CHECK_OFFSET = 1017
+ };
+
+ static const char *const spell [];
+ static const short lhs [];
+ static const short rhs [];
+ static const short goto_default [];
+ static const short action_default [];
+ static const short action_index [];
+ static const short action_info [];
+ static const short action_check [];
+
+ static inline int nt_action (int state, int nt)
+ {
+ const int yyn = action_index [GOTO_INDEX_OFFSET + state] + nt;
+ if (yyn < 0 || action_check [GOTO_CHECK_OFFSET + yyn] != nt)
+ return goto_default [nt];
+
+ return action_info [GOTO_INFO_OFFSET + yyn];
+ }
+
+ static inline int t_action (int state, int token)
+ {
+ const int yyn = action_index [state] + token;
+
+ if (yyn < 0 || action_check [yyn] != token)
+ return - action_default [state];
+
+ return action_info [yyn];
+ }
+};
+
+
+const char *const QXmlStreamReader_Table::spell [] = {
+ "end of file", 0, " ", "<", ">", "&", "#", "\'", "\"", "[",
+ "]", "(", ")", "|", "=", "%", "/", ":", ";", ",",
+ "-", "+", "*", ".", "?", "!", "[a-zA-Z]", "[0-9]", "[CDATA[", "DOCTYPE",
+ "ELEMENT", "ATTLIST", "ENTITY", "NOTATION", "SYSTEM", "PUBLIC", "NDATA", "REQUIRED", "IMPLIED", "FIXED",
+ "EMPTY", "ANY", "PCDATA", 0, 0, 0, 0, "CDATA", "ID", "IDREF",
+ "IDREFS", "ENTITIES", "NMTOKEN", "NMTOKENS", "<?xml", "version", 0};
+
+const short QXmlStreamReader_Table::lhs [] = {
+ 57, 57, 59, 59, 59, 59, 59, 59, 59, 59,
+ 67, 68, 64, 72, 72, 72, 75, 66, 66, 66,
+ 66, 79, 78, 80, 80, 80, 80, 80, 80, 80,
+ 81, 81, 81, 81, 81, 81, 81, 87, 83, 88,
+ 88, 88, 88, 91, 92, 93, 93, 93, 93, 94,
+ 94, 96, 96, 96, 97, 97, 98, 98, 99, 99,
+ 100, 100, 89, 89, 95, 90, 101, 101, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 104, 105,
+ 105, 105, 105, 107, 108, 109, 109, 84, 84, 110,
+ 110, 112, 112, 85, 85, 85, 65, 65, 76, 114,
+ 63, 115, 116, 86, 86, 86, 117, 117, 117, 117,
+ 117, 117, 117, 117, 117, 117, 117, 117, 117, 117,
+ 117, 117, 117, 117, 117, 117, 117, 117, 117, 118,
+ 118, 119, 119, 119, 119, 119, 119, 119, 119, 122,
+ 70, 70, 70, 70, 123, 124, 123, 124, 123, 124,
+ 123, 124, 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+ 126, 126, 126, 126, 125, 73, 113, 113, 113, 113,
+ 127, 128, 127, 128, 127, 128, 127, 128, 129, 129,
+ 129, 129, 129, 129, 129, 129, 129, 129, 129, 129,
+ 129, 129, 129, 129, 129, 129, 129, 129, 129, 129,
+ 129, 129, 129, 106, 106, 106, 106, 131, 132, 131,
+ 132, 131, 131, 132, 132, 133, 133, 133, 133, 135,
+ 71, 71, 71, 136, 136, 137, 62, 60, 61, 138,
+ 121, 82, 130, 134, 120, 139, 139, 139, 139, 58,
+ 58, 58, 58, 58, 58, 58, 58, 58, 58, 74,
+ 69, 69, 77, 111, 102, 102, 102, 102, 102, 140};
+
+const short QXmlStreamReader_Table::rhs [] = {
+ 2, 1, 4, 2, 2, 2, 2, 2, 2, 0,
+ 1, 1, 9, 2, 4, 0, 4, 4, 6, 6,
+ 4, 1, 3, 1, 1, 1, 2, 2, 2, 0,
+ 1, 1, 1, 1, 1, 1, 1, 4, 4, 1,
+ 1, 1, 1, 1, 2, 1, 1, 1, 0, 2,
+ 2, 2, 6, 6, 1, 5, 1, 5, 3, 5,
+ 0, 1, 6, 8, 4, 2, 1, 5, 1, 1,
+ 1, 1, 1, 1, 1, 1, 6, 7, 1, 2,
+ 2, 1, 4, 3, 3, 1, 2, 5, 6, 4,
+ 6, 3, 5, 5, 3, 4, 4, 5, 2, 3,
+ 2, 2, 4, 5, 5, 7, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 1, 1, 1, 1, 1,
+ 2, 2, 3, 3, 2, 2, 2, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 2, 2, 3, 3,
+ 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 2, 3, 3, 2, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 5,
+ 0, 1, 3, 1, 3, 2, 4, 3, 5, 1,
+ 3, 3, 3, 3, 4, 1, 1, 2, 2, 2,
+ 4, 2, 2, 2, 2, 2, 2, 2, 0, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 2};
+
+const short QXmlStreamReader_Table::action_default [] = {
+ 10, 259, 0, 2, 1, 0, 125, 117, 119, 120,
+ 127, 129, 123, 11, 114, 108, 0, 109, 128, 111,
+ 115, 113, 121, 124, 126, 107, 110, 112, 118, 116,
+ 131, 122, 240, 12, 254, 136, 250, 253, 0, 130,
+ 140, 257, 16, 252, 138, 137, 0, 256, 139, 259,
+ 231, 258, 255, 0, 0, 264, 0, 247, 246, 0,
+ 249, 248, 245, 241, 99, 263, 0, 236, 0, 0,
+ 260, 97, 98, 101, 0, 132, 134, 133, 135, 0,
+ 0, 261, 0, 0, 176, 0, 173, 165, 167, 168,
+ 142, 154, 171, 162, 156, 157, 153, 159, 163, 161,
+ 169, 172, 152, 155, 158, 160, 166, 164, 174, 170,
+ 150, 175, 0, 144, 148, 146, 151, 141, 149, 0,
+ 147, 143, 145, 0, 15, 14, 262, 0, 22, 21,
+ 261, 30, 0, 20, 0, 0, 32, 37, 31, 0,
+ 33, 261, 0, 34, 0, 24, 0, 35, 0, 26,
+ 36, 25, 0, 242, 41, 40, 261, 43, 49, 261,
+ 42, 0, 44, 261, 49, 261, 0, 261, 0, 49,
+ 0, 48, 46, 47, 51, 52, 261, 261, 0, 57,
+ 261, 54, 261, 0, 58, 0, 55, 261, 53, 261,
+ 0, 56, 65, 0, 261, 61, 261, 0, 59, 62,
+ 63, 0, 261, 0, 0, 60, 64, 45, 50, 66,
+ 0, 39, 0, 0, 261, 0, 94, 95, 0, 0,
+ 0, 0, 261, 0, 210, 201, 203, 205, 178, 190,
+ 208, 199, 193, 191, 194, 189, 196, 198, 206, 209,
+ 188, 192, 195, 197, 202, 200, 204, 207, 211, 213,
+ 212, 186, 0, 0, 243, 180, 184, 182, 0, 0,
+ 93, 187, 177, 185, 0, 183, 179, 181, 92, 0,
+ 96, 0, 0, 0, 0, 0, 261, 86, 261, 0,
+ 262, 0, 87, 0, 89, 69, 74, 73, 70, 71,
+ 72, 261, 75, 76, 0, 0, 0, 269, 268, 266,
+ 267, 265, 67, 261, 0, 261, 0, 0, 68, 77,
+ 261, 0, 261, 0, 0, 78, 0, 79, 0, 82,
+ 85, 0, 0, 215, 225, 224, 0, 227, 229, 228,
+ 226, 0, 244, 217, 221, 219, 223, 214, 222, 0,
+ 220, 216, 218, 0, 81, 80, 0, 83, 0, 84,
+ 88, 100, 0, 38, 0, 0, 0, 0, 91, 90,
+ 0, 103, 23, 27, 29, 28, 0, 0, 261, 262,
+ 0, 261, 0, 106, 105, 261, 0, 104, 102, 0,
+ 0, 18, 261, 17, 0, 19, 0, 0, 251, 0,
+ 261, 0, 239, 0, 232, 238, 0, 237, 234, 261,
+ 261, 262, 233, 235, 0, 261, 0, 230, 261, 0,
+ 261, 0, 231, 0, 0, 13, 270, 9, 5, 8,
+ 4, 0, 7, 259, 6, 0, 3};
+
+const short QXmlStreamReader_Table::goto_default [] = {
+ 2, 4, 3, 49, 388, 43, 37, 52, 47, 41,
+ 249, 53, 127, 84, 393, 81, 85, 126, 42, 46,
+ 169, 130, 131, 146, 145, 149, 138, 136, 140, 147,
+ 139, 159, 160, 157, 168, 167, 209, 165, 164, 166,
+ 187, 180, 196, 200, 303, 302, 295, 321, 320, 319,
+ 279, 277, 278, 142, 56, 141, 222, 38, 34, 148,
+ 39, 48, 40, 248, 45, 36, 119, 112, 330, 111,
+ 264, 252, 251, 250, 339, 326, 325, 329, 398, 399,
+ 50, 51, 59, 0};
+
+const short QXmlStreamReader_Table::action_index [] = {
+ -21, -57, 33, 119, 960, 70, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, 105, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, 40, -57,
+ 795, -57, 47, -57, -57, -57, 107, -57, -57, -57,
+ 84, -57, -57, -38, 80, -57, 12, -57, -57, 97,
+ -57, -57, -57, -57, -57, -57, 13, -57, 56, 34,
+ -57, -57, -57, -57, 51, -57, -57, -57, -57, 53,
+ 57, 84, 300, 255, -57, 84, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, 355, -57, -57, -57, -57, -57, -57, 326,
+ -57, -57, -57, 48, -57, -57, -57, 50, -57, -57,
+ 84, 155, 32, -57, 38, 22, -57, -57, -57, 115,
+ -57, 35, 156, -57, 173, -57, 245, -57, 44, -57,
+ -57, -57, 16, -57, -57, -57, 29, -57, 116, 29,
+ -57, 133, -57, 29, 129, 84, 15, 29, -22, 121,
+ 74, -57, -57, -57, -57, 82, 29, 29, 88, -57,
+ 29, 7, 29, 86, -57, 83, -57, 27, 19, 26,
+ 94, -57, -57, 106, 29, 3, 29, -8, -57, -57,
+ -57, 104, 29, -6, -7, -57, -57, -57, -57, -57,
+ 17, -57, -2, 11, 29, 18, -57, -57, 850, 65,
+ 465, 67, 84, 135, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, -57, -57, -57, -57, -57, -57, -57, -57,
+ -57, -57, 630, 24, -57, -57, -57, -57, 84, 76,
+ -57, -57, -57, -57, 740, -57, -57, -57, -57, 39,
+ -57, 23, 21, 14, 78, 22, 84, -57, 84, 184,
+ 20, 31, -57, 41, -57, -57, -57, -57, -57, -57,
+ -57, 84, -57, -57, 36, 126, 162, -57, -57, -57,
+ -57, -57, -57, 29, 79, 29, 29, 160, -57, -57,
+ 29, 145, 29, 75, 29, -57, 575, -57, 410, -57,
+ -57, 110, 64, -57, -57, -57, 685, -57, -57, -57,
+ -57, -17, -57, -57, -57, -57, -57, -57, -57, 520,
+ -57, -57, -57, 29, -57, -57, 61, -57, 29, -57,
+ -57, -57, 29, -57, 29, 29, -15, 29, -57, -57,
+ 29, -57, -57, -57, -57, -57, 95, 43, 29, 45,
+ 9, 29, 10, -57, -57, 29, 2, -57, -57, -24,
+ 190, -57, 29, -57, 1, -57, 905, 150, -57, -26,
+ 29, 0, -57, 109, -26, -57, 8, -57, -57, 29,
+ 29, -19, -57, -57, -11, 29, 59, -57, 29, -5,
+ 29, 103, 29, -16, 6, -57, -57, -57, -57, -57,
+ -57, 69, -57, -57, -57, 905, -57,
+
+ -84, -84, -84, 204, 75, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, 7, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ 101, -84, -84, -84, -84, -84, -84, -84, -84, 64,
+ 54, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, 68, -84, 30, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ 32, -84, -16, -7, -84, 42, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, 45, -84, -84, -84, -84, -84, -84, 44,
+ -84, -84, -84, 33, -84, -84, -84, -84, -84, -84,
+ 36, 108, -84, -84, -84, 69, -84, -84, -84, 62,
+ -84, 63, -84, -84, -84, -84, 118, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -2, -84, -84, -10,
+ -84, -84, -84, 25, -21, 11, -84, 20, -84, -25,
+ -84, -84, -84, -84, -84, -84, 1, 2, -36, -84,
+ -9, -84, 5, -13, -84, -8, -84, 6, -84, 8,
+ 12, -84, -84, -84, 23, -84, 4, -1, -84, -84,
+ -84, -84, 0, -84, -14, -84, -84, -84, -84, -84,
+ -84, -84, 55, -84, 58, -84, -84, -84, -84, 53,
+ 47, 123, 67, 66, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -15, -84, -84, -84, -84, -84, 41, 40,
+ -84, -84, -84, -84, -46, -84, -84, -84, -84, -84,
+ -84, 35, -84, 34, 37, 18, 70, -84, 89, -84,
+ 43, -84, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, 48, -84, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, 31, -84, 29, 27, 17, -84, -84,
+ 38, 24, 39, -84, 49, -84, 71, -84, 93, -84,
+ -84, -84, -12, -84, -84, -84, 94, -84, -84, -84,
+ -84, -84, -84, -84, -84, -84, -84, -84, -84, 78,
+ -84, -84, -84, 50, -84, -84, 46, -84, 56, -84,
+ -84, -84, 60, -84, 61, 59, 51, 57, -84, -84,
+ 14, -84, -84, -84, -84, -84, -11, -6, 72, -5,
+ -84, -3, -84, -84, -84, 52, -84, -84, -84, -20,
+ 77, -84, 21, -84, -84, -84, 76, 16, -84, 19,
+ 26, -84, -84, -84, 10, -84, -84, -84, -84, 80,
+ 13, 73, -84, -84, -84, 22, -27, -84, 9, -84,
+ 28, 15, 82, -84, -84, -84, -84, -84, -84, -84,
+ -84, -84, -84, 3, -84, 98, -84};
+
+const short QXmlStreamReader_Table::action_info [] = {
+ 65, 332, 65, 405, 392, 385, 377, 65, 414, 410,
+ 415, 55, 397, 374, 373, 217, 206, 408, 65, 65,
+ 207, 211, 216, 1, 55, 199, 182, 192, 70, 70,
+ 63, 70, 189, 416, 153, 350, 133, 70, 72, 55,
+ 65, 351, 254, 270, 73, 284, 65, 310, 55, 65,
+ 83, 82, 83, 82, 129, 83, 82, 54, 70, 128,
+ 83, 82, 66, 64, 83, 82, 318, 316, 318, 316,
+ 54, 212, 83, 82, 83, 82, 54, 55, 367, 366,
+ 69, 80, 79, 83, 82, 163, 70, 314, 305, 272,
+ 55, 306, 305, 354, 163, 177, 55, 163, 379, 163,
+ 65, 176, 83, 82, 55, 163, 58, 57, 0, 65,
+ 83, 82, 65, 395, 65, 62, 203, 202, 195, 194,
+ 65, 417, 16, 61, 60, 396, 156, 272, 0, 66,
+ 64, 65, 317, 318, 316, 378, 379, 171, 173, 162,
+ 172, 54, 171, 173, 163, 172, 0, 345, 344, 343,
+ 171, 173, 0, 172, 0, 155, 154, 70, 134, 65,
+ 0, 55, 297, 220, 218, 298, 389, 0, 300, 0,
+ 135, 301, 299, 33, 66, 64, 65, 297, 0, 297,
+ 298, 0, 298, 300, 0, 300, 301, 299, 301, 299,
+ 221, 219, 70, 272, 381, 291, 0, 0, 0, 128,
+ 13, 0, 0, 273, 271, 274, 275, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 287, 294, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 285, 288, 289, 290, 286, 292, 293, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 70, 134, 0,
+ 0, 0, 0, 0, 0, 362, 0, 108, 0, 103,
+ 135, 94, 117, 116, 95, 104, 97, 105, 99, 93,
+ 98, 107, 87, 106, 88, 89, 100, 109, 92, 101,
+ 86, 96, 91, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 108, 0, 103, 0, 94, 102, 90, 95,
+ 104, 97, 105, 99, 93, 98, 107, 87, 106, 88,
+ 89, 100, 109, 92, 101, 86, 96, 91, 108, 0,
+ 103, 0, 94, 121, 120, 95, 104, 97, 105, 99,
+ 93, 98, 107, 87, 106, 88, 89, 100, 109, 92,
+ 101, 86, 96, 91, 0, 0, 0, 108, 0, 103,
+ 0, 94, 114, 113, 95, 104, 97, 105, 99, 93,
+ 98, 107, 87, 106, 88, 89, 100, 109, 92, 101,
+ 86, 96, 91, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 108, 0, 103, 322, 94, 337, 336, 95,
+ 104, 97, 105, 99, 93, 98, 107, 87, 106, 88,
+ 89, 100, 109, 92, 101, 86, 96, 91, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 246, 233, 241,
+ 223, 232, 262, 261, 234, 242, 236, 243, 237, 231,
+ 0, 245, 225, 244, 226, 227, 238, 247, 230, 239,
+ 224, 235, 229, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 108, 0, 103, 322, 94, 341, 340, 95,
+ 104, 97, 105, 99, 93, 98, 107, 87, 106, 88,
+ 89, 100, 109, 92, 101, 86, 96, 91, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 108, 0, 103,
+ 322, 94, 324, 323, 95, 104, 97, 105, 99, 93,
+ 98, 107, 87, 106, 88, 89, 100, 109, 92, 101,
+ 86, 96, 91, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 246, 233, 241, 223, 232, 256, 255, 234,
+ 242, 236, 243, 237, 231, 0, 245, 225, 244, 226,
+ 227, 238, 247, 230, 239, 224, 235, 229, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 108, 0, 103,
+ 322, 94, 334, 333, 95, 104, 97, 105, 99, 93,
+ 98, 107, 87, 106, 88, 89, 100, 109, 92, 101,
+ 86, 96, 91, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 246, 233, 241, 223, 232, 266, 265, 234,
+ 242, 236, 243, 237, 231, 0, 245, 225, 244, 226,
+ 227, 238, 247, 230, 239, 224, 235, 229, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 30, 0, 25,
+ 74, 15, 24, 10, 17, 26, 19, 27, 21, 14,
+ 20, 29, 7, 28, 8, 9, 22, 31, 12, 23,
+ 6, 18, 11, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 246, 233, 241, 223, 232, 240, 228, 234,
+ 242, 236, 243, 237, 231, 0, 245, 225, 244, 226,
+ 227, 238, 247, 230, 239, 224, 235, 229, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 30, 387, 25,
+ 5, 15, 24, 10, 17, 26, 19, 27, 21, 14,
+ 20, 29, 7, 28, 8, 9, 22, 31, 12, 23,
+ 6, 18, 11, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 32, 0, 0, 0, 0, 0, 0, 0, 33,
+ 0, 0, 30, 16, 25, 5, 15, 24, 10, 17,
+ 26, 19, 27, 21, 14, 20, 29, 7, 28, 8,
+ 9, 22, 31, 12, 23, 6, 18, 11, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 13, 32, 0, 0, 0,
+ 0, 0, 0, 0, 33, 0, 0,
+
+ 380, 179, 210, 181, 425, 368, 205, 375, 371, 372,
+ 161, 208, 204, 178, 185, 174, 201, 183, 188, 198,
+ 190, 409, 407, 175, 184, 404, 267, 67, 412, 186,
+ 400, 361, 193, 384, 406, 197, 67, 170, 391, 390,
+ 411, 307, 331, 304, 309, 125, 124, 71, 132, 191,
+ 311, 313, 110, 260, 352, 276, 0, 257, 259, 123,
+ 296, 118, 308, 348, 376, 386, 315, 346, 312, 258,
+ 215, 394, 360, 349, 358, 213, 359, 353, 356, 269,
+ 0, 328, 281, 0, 370, 44, 44, 280, 328, 369,
+ 0, 355, 402, 400, 383, 347, 413, 401, 382, 394,
+ 158, 283, 426, 328, 328, 357, 280, 0, 44, 214,
+ 0, 76, 122, 115, 137, 0, 150, 0, 143, 263,
+ 253, 0, 68, 152, 137, 151, 150, 144, 143, 0,
+ 0, 0, 0, 0, 327, 365, 268, 144, 35, 35,
+ 282, 327, 363, 364, 0, 0, 0, 0, 0, 0,
+ 0, 403, 0, 0, 342, 0, 327, 327, 0, 0,
+ 0, 35, 78, 0, 75, 77, 0, 0, 0, 338,
+ 335, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 423, 0, 420,
+ 418, 424, 422, 419, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 421, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0};
+
+const short QXmlStreamReader_Table::action_check [] = {
+ 26, 18, 26, 14, 4, 4, 4, 26, 24, 14,
+ 4, 26, 4, 4, 4, 4, 22, 55, 26, 26,
+ 42, 4, 4, 44, 26, 22, 19, 12, 2, 2,
+ 18, 2, 13, 0, 18, 4, 4, 2, 4, 26,
+ 26, 20, 18, 4, 4, 4, 26, 11, 26, 26,
+ 7, 8, 7, 8, 4, 7, 8, 6, 2, 9,
+ 7, 8, 24, 25, 7, 8, 7, 8, 7, 8,
+ 6, 36, 7, 8, 7, 8, 6, 26, 34, 35,
+ 24, 34, 35, 7, 8, 11, 2, 12, 13, 20,
+ 26, 12, 13, 15, 11, 13, 26, 11, 29, 11,
+ 26, 19, 7, 8, 26, 11, 26, 27, -1, 26,
+ 7, 8, 26, 4, 26, 18, 12, 13, 12, 13,
+ 26, 2, 3, 26, 27, 16, 11, 20, -1, 24,
+ 25, 26, 6, 7, 8, 28, 29, 21, 22, 6,
+ 24, 6, 21, 22, 11, 24, -1, 37, 38, 39,
+ 21, 22, -1, 24, -1, 40, 41, 2, 3, 26,
+ -1, 26, 17, 7, 8, 20, 16, -1, 23, -1,
+ 15, 26, 27, 54, 24, 25, 26, 17, -1, 17,
+ 20, -1, 20, 23, -1, 23, 26, 27, 26, 27,
+ 34, 35, 2, 20, 4, 11, -1, -1, -1, 9,
+ 45, -1, -1, 30, 31, 32, 33, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 32, 33, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 47, 48, 49, 50, 51, 52, 53, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 2, 3, -1,
+ -1, -1, -1, -1, -1, 10, -1, 2, -1, 4,
+ 15, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ 45, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, -1, 4, -1, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 2, -1,
+ 4, -1, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, -1, -1, -1, 2, -1, 4,
+ -1, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, -1, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 45, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ -1, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 45, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, -1, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 45, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 2, -1, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 45, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 45, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 2, -1, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 45, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 45, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 2, -1, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 45, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, -1, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 45, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 45, 46, -1, -1, -1, -1, -1, -1, -1, 54,
+ -1, -1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 45, 46, -1, -1, -1,
+ -1, -1, -1, -1, 54, -1, -1,
+
+ 20, 37, 12, 12, 1, 16, 20, 13, 13, 12,
+ 12, 36, 12, 12, 12, 36, 12, 12, 12, 20,
+ 12, 12, 49, 12, 37, 12, 72, 20, 13, 37,
+ 20, 17, 12, 12, 12, 12, 20, 12, 12, 20,
+ 12, 12, 54, 12, 17, 13, 13, 17, 12, 37,
+ 12, 12, 68, 13, 20, 20, -1, 72, 17, 17,
+ 12, 68, 45, 20, 12, 1, 17, 17, 44, 16,
+ 12, 17, 54, 17, 17, 12, 17, 17, 17, 12,
+ -1, 10, 12, -1, 12, 10, 10, 17, 10, 17,
+ -1, 54, 12, 20, 17, 49, 14, 17, 21, 17,
+ 38, 12, 4, 10, 10, 54, 17, -1, 10, 54,
+ -1, 10, 68, 68, 6, -1, 8, -1, 10, 72,
+ 54, -1, 54, 54, 6, 17, 8, 19, 10, -1,
+ -1, -1, -1, -1, 63, 17, 13, 19, 63, 63,
+ 51, 63, 24, 25, -1, -1, -1, -1, -1, -1,
+ -1, 78, -1, -1, 76, -1, 63, 63, -1, -1,
+ -1, 63, 61, -1, 63, 64, -1, -1, -1, 76,
+ 76, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 3, -1, 5,
+ 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 19, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1};
+
+
+template <typename T> class QXmlStreamSimpleStack {
+ T *data;
+ int tos, cap;
+public:
+ inline QXmlStreamSimpleStack():data(0), tos(-1), cap(0){}
+ inline ~QXmlStreamSimpleStack(){ if (data) free(data); }
+
+ inline void reserve(int extraCapacity) {
+ if (tos + extraCapacity + 1 > cap) {
+ cap = qMax(tos + extraCapacity + 1, cap << 1 );
+ void *ptr = realloc(static_cast<void *>(data), cap * sizeof(T));
+ data = reinterpret_cast<T *>(ptr);
+ Q_CHECK_PTR(data);
+ }
+ }
+
+ inline T &push() { reserve(1); return data[++tos]; }
+ inline T &rawPush() { return data[++tos]; }
+ inline const T &top() const { return data[tos]; }
+ inline T &top() { return data[tos]; }
+ inline T &pop() { return data[tos--]; }
+ inline T &operator[](int index) { return data[index]; }
+ inline const T &at(int index) const { return data[index]; }
+ inline int size() const { return tos + 1; }
+ inline void resize(int s) { tos = s - 1; }
+ inline bool isEmpty() const { return tos < 0; }
+ inline void clear() { tos = -1; }
+};
+
+
+class QXmlStream
+{
+ Q_DECLARE_TR_FUNCTIONS(QXmlStream)
+};
+
+class QXmlStreamPrivateTagStack {
+public:
+ struct NamespaceDeclaration
+ {
+ QStringRef prefix;
+ QStringRef namespaceUri;
+ };
+
+ struct Tag
+ {
+ QStringRef name;
+ QStringRef qualifiedName;
+ NamespaceDeclaration namespaceDeclaration;
+ int tagStackStringStorageSize;
+ int namespaceDeclarationsSize;
+ };
+
+
+ QXmlStreamPrivateTagStack();
+ QXmlStreamSimpleStack<NamespaceDeclaration> namespaceDeclarations;
+ QString tagStackStringStorage;
+ int tagStackStringStorageSize;
+ int initialTagStackStringStorageSize;
+ bool tagsDone;
+
+ inline QStringRef addToStringStorage(const QStringRef &s) {
+ int pos = tagStackStringStorageSize;
+ int sz = s.size();
+ if (pos != tagStackStringStorage.size())
+ tagStackStringStorage.resize(pos);
+ tagStackStringStorage.insert(pos, s.unicode(), sz);
+ tagStackStringStorageSize += sz;
+ return QStringRef(&tagStackStringStorage, pos, sz);
+ }
+ inline QStringRef addToStringStorage(const QString &s) {
+ int pos = tagStackStringStorageSize;
+ int sz = s.size();
+ if (pos != tagStackStringStorage.size())
+ tagStackStringStorage.resize(pos);
+ tagStackStringStorage.insert(pos, s.unicode(), sz);
+ tagStackStringStorageSize += sz;
+ return QStringRef(&tagStackStringStorage, pos, sz);
+ }
+
+ QXmlStreamSimpleStack<Tag> tagStack;
+
+
+ inline Tag &tagStack_pop() {
+ Tag& tag = tagStack.pop();
+ tagStackStringStorageSize = tag.tagStackStringStorageSize;
+ namespaceDeclarations.resize(tag.namespaceDeclarationsSize);
+ tagsDone = tagStack.isEmpty();
+ return tag;
+ }
+ inline Tag &tagStack_push() {
+ Tag &tag = tagStack.push();
+ tag.tagStackStringStorageSize = tagStackStringStorageSize;
+ tag.namespaceDeclarationsSize = namespaceDeclarations.size();
+ return tag;
+ }
+};
+
+
+class QXmlStreamEntityResolver;
+#ifndef QT_NO_XMLSTREAMREADER
+class QXmlStreamReaderPrivate : public QXmlStreamReader_Table, public QXmlStreamPrivateTagStack{
+ QXmlStreamReader *q_ptr;
+ Q_DECLARE_PUBLIC(QXmlStreamReader)
+public:
+ QXmlStreamReaderPrivate(QXmlStreamReader *q);
+ ~QXmlStreamReaderPrivate();
+ void init();
+
+ QByteArray rawReadBuffer;
+ QByteArray dataBuffer;
+ uchar firstByte;
+ qint64 nbytesread;
+ QString readBuffer;
+ int readBufferPos;
+ QXmlStreamSimpleStack<uint> putStack;
+ struct Entity {
+ Entity(const QString& str = QString())
+ :value(str), external(false), unparsed(false), literal(false),
+ hasBeenParsed(false), isCurrentlyReferenced(false){}
+ static inline Entity createLiteral(const QString &entity)
+ { Entity result(entity); result.literal = result.hasBeenParsed = true; return result; }
+ QString value;
+ uint external : 1;
+ uint unparsed : 1;
+ uint literal : 1;
+ uint hasBeenParsed : 1;
+ uint isCurrentlyReferenced : 1;
+ };
+ QHash<QString, Entity> entityHash;
+ QHash<QString, Entity> parameterEntityHash;
+ QXmlStreamSimpleStack<Entity *>entityReferenceStack;
+ inline bool referenceEntity(Entity &entity) {
+ if (entity.isCurrentlyReferenced) {
+ raiseWellFormedError(QXmlStream::tr("Recursive entity detected."));
+ return false;
+ }
+ entity.isCurrentlyReferenced = true;
+ entityReferenceStack.push() = &entity;
+ injectToken(ENTITY_DONE);
+ return true;
+ }
+
+
+ QIODevice *device;
+ bool deleteDevice;
+#ifndef QT_NO_TEXTCODEC
+ QTextCodec *codec;
+ QTextDecoder *decoder;
+#endif
+ bool atEnd;
+
+ /*!
+ \sa setType()
+ */
+ QXmlStreamReader::TokenType type;
+ QXmlStreamReader::Error error;
+ QString errorString;
+ QString unresolvedEntity;
+
+ qint64 lineNumber, lastLineStart, characterOffset;
+
+
+ void write(const QString &);
+ void write(const char *);
+
+
+ QXmlStreamAttributes attributes;
+ QStringRef namespaceForPrefix(const QStringRef &prefix);
+ void resolveTag();
+ void resolvePublicNamespaces();
+ void resolveDtd();
+ uint resolveCharRef(int symbolIndex);
+ bool checkStartDocument();
+ void startDocument();
+ void parseError();
+ void checkPublicLiteral(const QStringRef &publicId);
+
+ bool scanDtd;
+ QStringRef lastAttributeValue;
+ bool lastAttributeIsCData;
+ struct DtdAttribute {
+ QStringRef tagName;
+ QStringRef attributeQualifiedName;
+ QStringRef attributePrefix;
+ QStringRef attributeName;
+ QStringRef defaultValue;
+ bool isCDATA;
+ bool isNamespaceAttribute;
+ };
+ QXmlStreamSimpleStack<DtdAttribute> dtdAttributes;
+ struct NotationDeclaration {
+ QStringRef name;
+ QStringRef publicId;
+ QStringRef systemId;
+ };
+ QXmlStreamSimpleStack<NotationDeclaration> notationDeclarations;
+ QXmlStreamNotationDeclarations publicNotationDeclarations;
+ QXmlStreamNamespaceDeclarations publicNamespaceDeclarations;
+
+ struct EntityDeclaration {
+ QStringRef name;
+ QStringRef notationName;
+ QStringRef publicId;
+ QStringRef systemId;
+ QStringRef value;
+ bool parameter;
+ bool external;
+ inline void clear() {
+ name.clear();
+ notationName.clear();
+ publicId.clear();
+ systemId.clear();
+ value.clear();
+ parameter = external = false;
+ }
+ };
+ QXmlStreamSimpleStack<EntityDeclaration> entityDeclarations;
+ QXmlStreamEntityDeclarations publicEntityDeclarations;
+
+ QStringRef text;
+
+ QStringRef prefix, namespaceUri, qualifiedName, name;
+ QStringRef processingInstructionTarget, processingInstructionData;
+ QStringRef dtdName, dtdPublicId, dtdSystemId;
+ QStringRef documentVersion, documentEncoding;
+ uint isEmptyElement : 1;
+ uint isWhitespace : 1;
+ uint isCDATA : 1;
+ uint standalone : 1;
+ uint hasCheckedStartDocument : 1;
+ uint normalizeLiterals : 1;
+ uint hasSeenTag : 1;
+ uint inParseEntity : 1;
+ uint referenceToUnparsedEntityDetected : 1;
+ uint referenceToParameterEntityDetected : 1;
+ uint hasExternalDtdSubset : 1;
+ uint lockEncoding : 1;
+ uint namespaceProcessing : 1;
+
+ int resumeReduction;
+ void resume(int rule);
+
+ inline bool entitiesMustBeDeclared() const {
+ return (!inParseEntity
+ && (standalone
+ || (!referenceToUnparsedEntityDetected
+ && !referenceToParameterEntityDetected // Errata 13 as of 2006-04-25
+ && !hasExternalDtdSubset)));
+ }
+
+ // qlalr parser
+ int tos;
+ int stack_size;
+ struct Value {
+ int pos;
+ int len;
+ int prefix;
+ ushort c;
+ };
+
+ Value *sym_stack;
+ int *state_stack;
+ inline void reallocateStack();
+ inline Value &sym(int index) const
+ { return sym_stack[tos + index - 1]; }
+ QString textBuffer;
+ inline void clearTextBuffer() {
+ if (!scanDtd) {
+ textBuffer.resize(0);
+ textBuffer.reserve(256);
+ }
+ }
+ struct Attribute {
+ Value key;
+ Value value;
+ };
+ QXmlStreamSimpleStack<Attribute> attributeStack;
+
+ inline QStringRef symString(int index) {
+ const Value &symbol = sym(index);
+ return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
+ }
+ inline QStringRef symName(int index) {
+ const Value &symbol = sym(index);
+ return QStringRef(&textBuffer, symbol.pos, symbol.len);
+ }
+ inline QStringRef symString(int index, int offset) {
+ const Value &symbol = sym(index);
+ return QStringRef(&textBuffer, symbol.pos + symbol.prefix + offset, symbol.len - symbol.prefix - offset);
+ }
+ inline QStringRef symPrefix(int index) {
+ const Value &symbol = sym(index);
+ if (symbol.prefix)
+ return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
+ return QStringRef();
+ }
+ inline QStringRef symString(const Value &symbol) {
+ return QStringRef(&textBuffer, symbol.pos + symbol.prefix, symbol.len - symbol.prefix);
+ }
+ inline QStringRef symName(const Value &symbol) {
+ return QStringRef(&textBuffer, symbol.pos, symbol.len);
+ }
+ inline QStringRef symPrefix(const Value &symbol) {
+ if (symbol.prefix)
+ return QStringRef(&textBuffer, symbol.pos, symbol.prefix - 1);
+ return QStringRef();
+ }
+
+ inline void clearSym() { Value &val = sym(1); val.pos = textBuffer.size(); val.len = 0; }
+
+
+ short token;
+ uint token_char;
+
+ uint filterCarriageReturn();
+ inline uint getChar();
+ inline uint peekChar();
+ inline void putChar(uint c) { putStack.push() = c; }
+ inline void putChar(QChar c) { putStack.push() = c.unicode(); }
+ void putString(const QString &s, int from = 0);
+ void putStringLiteral(const QString &s);
+ void putReplacement(const QString &s);
+ void putReplacementInAttributeValue(const QString &s);
+ uint getChar_helper();
+
+ bool scanUntil(const char *str, short tokenToInject = -1);
+ bool scanString(const char *str, short tokenToInject, bool requireSpace = true);
+ inline void injectToken(ushort tokenToInject) {
+ putChar(int(tokenToInject) << 16);
+ }
+
+ QString resolveUndeclaredEntity(const QString &name);
+ void parseEntity(const QString &value);
+ QXmlStreamReaderPrivate *entityParser;
+
+ bool scanAfterLangleBang();
+ bool scanPublicOrSystem();
+ bool scanNData();
+ bool scanAfterDefaultDecl();
+ bool scanAttType();
+
+
+ // scan optimization functions. Not strictly necessary but LALR is
+ // not very well suited for scanning fast
+ int fastScanLiteralContent();
+ int fastScanSpace();
+ int fastScanContentCharList();
+ int fastScanName(int *prefix = 0);
+ inline int fastScanNMTOKEN();
+
+
+ bool parse();
+ inline void consumeRule(int);
+
+ void raiseError(QXmlStreamReader::Error error, const QString& message = QString());
+ void raiseWellFormedError(const QString &message);
+
+ QXmlStreamEntityResolver *entityResolver;
+
+private:
+ /*! \internal
+ Never assign to variable type directly. Instead use this function.
+
+ This prevents errors from being ignored.
+ */
+ inline void setType(const QXmlStreamReader::TokenType t)
+ {
+ if(type != QXmlStreamReader::Invalid)
+ type = t;
+ }
+};
+
+bool QXmlStreamReaderPrivate::parse()
+{
+ // cleanup currently reported token
+
+ switch (type) {
+ case QXmlStreamReader::StartElement:
+ name.clear();
+ prefix.clear();
+ qualifiedName.clear();
+ namespaceUri.clear();
+ publicNamespaceDeclarations.clear();
+ attributes.clear();
+ if (isEmptyElement) {
+ setType(QXmlStreamReader::EndElement);
+ Tag &tag = tagStack_pop();
+ namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ name = tag.name;
+ qualifiedName = tag.qualifiedName;
+ isEmptyElement = false;
+ return true;
+ }
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::EndElement:
+ name.clear();
+ prefix.clear();
+ qualifiedName.clear();
+ namespaceUri.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::DTD:
+ publicNotationDeclarations.clear();
+ publicEntityDeclarations.clear();
+ dtdName.clear();
+ dtdPublicId.clear();
+ dtdSystemId.clear();
+ Q_FALLTHROUGH();
+ case QXmlStreamReader::Comment:
+ case QXmlStreamReader::Characters:
+ isCDATA = false;
+ isWhitespace = true;
+ text.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::EntityReference:
+ text.clear();
+ name.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::ProcessingInstruction:
+ processingInstructionTarget.clear();
+ processingInstructionData.clear();
+ clearTextBuffer();
+ break;
+ case QXmlStreamReader::NoToken:
+ case QXmlStreamReader::Invalid:
+ break;
+ case QXmlStreamReader::StartDocument:
+ lockEncoding = true;
+ documentVersion.clear();
+ documentEncoding.clear();
+#ifndef QT_NO_TEXTCODEC
+ if (decoder && decoder->hasFailure()) {
+ raiseWellFormedError(QXmlStream::tr("Encountered incorrectly encoded content."));
+ readBuffer.clear();
+ return false;
+ }
+#endif
+ Q_FALLTHROUGH();
+ default:
+ clearTextBuffer();
+ ;
+ }
+
+ setType(QXmlStreamReader::NoToken);
+
+
+ // the main parse loop
+ int act, r;
+
+ if (resumeReduction) {
+ act = state_stack[tos-1];
+ r = resumeReduction;
+ resumeReduction = 0;
+ goto ResumeReduction;
+ }
+
+ act = state_stack[tos];
+
+ forever {
+ if (token == -1 && - TERMINAL_COUNT != action_index[act]) {
+ uint cu = getChar();
+ token = NOTOKEN;
+ token_char = cu == ~0U ? cu : ushort(cu);
+ if ((cu != ~0U) && (cu & 0xff0000)) {
+ token = cu >> 16;
+ } else switch (token_char) {
+ case 0xfffe:
+ case 0xffff:
+ token = ERROR;
+ break;
+ case '\r':
+ token = SPACE;
+ if (cu == '\r') {
+ if ((token_char = filterCarriageReturn())) {
+ ++lineNumber;
+ lastLineStart = characterOffset + readBufferPos;
+ break;
+ }
+ } else {
+ break;
+ }
+ Q_FALLTHROUGH();
+ case ~0U: {
+ token = EOF_SYMBOL;
+ if (!tagsDone && !inParseEntity) {
+ int a = t_action(act, token);
+ if (a < 0) {
+ raiseError(QXmlStreamReader::PrematureEndOfDocumentError);
+ return false;
+ }
+ }
+
+ } break;
+ case '\n':
+ ++lineNumber;
+ lastLineStart = characterOffset + readBufferPos;
+ Q_FALLTHROUGH();
+ case ' ':
+ case '\t':
+ token = SPACE;
+ break;
+ case '&':
+ token = AMPERSAND;
+ break;
+ case '#':
+ token = HASH;
+ break;
+ case '\'':
+ token = QUOTE;
+ break;
+ case '\"':
+ token = DBLQUOTE;
+ break;
+ case '<':
+ token = LANGLE;
+ break;
+ case '>':
+ token = RANGLE;
+ break;
+ case '[':
+ token = LBRACK;
+ break;
+ case ']':
+ token = RBRACK;
+ break;
+ case '(':
+ token = LPAREN;
+ break;
+ case ')':
+ token = RPAREN;
+ break;
+ case '|':
+ token = PIPE;
+ break;
+ case '=':
+ token = EQ;
+ break;
+ case '%':
+ token = PERCENT;
+ break;
+ case '/':
+ token = SLASH;
+ break;
+ case ':':
+ token = COLON;
+ break;
+ case ';':
+ token = SEMICOLON;
+ break;
+ case ',':
+ token = COMMA;
+ break;
+ case '-':
+ token = DASH;
+ break;
+ case '+':
+ token = PLUS;
+ break;
+ case '*':
+ token = STAR;
+ break;
+ case '.':
+ token = DOT;
+ break;
+ case '?':
+ token = QUESTIONMARK;
+ break;
+ case '!':
+ token = BANG;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ token = DIGIT;
+ break;
+ default:
+ if (cu < 0x20)
+ token = NOTOKEN;
+ else
+ token = LETTER;
+ break;
+ }
+ }
+
+ act = t_action (act, token);
+ if (act == ACCEPT_STATE) {
+ // reset the parser in case someone resumes (process instructions can follow a valid document)
+ tos = 0;
+ state_stack[tos++] = 0;
+ state_stack[tos] = 0;
+ return true;
+ } else if (act > 0) {
+ if (++tos == stack_size-1)
+ reallocateStack();
+
+ Value &val = sym_stack[tos];
+ val.c = token_char;
+ val.pos = textBuffer.size();
+ val.prefix = 0;
+ val.len = 1;
+ if (token_char)
+ textBuffer += QChar(token_char);
+
+ state_stack[tos] = act;
+ token = -1;
+
+
+ } else if (act < 0) {
+ r = - act - 1;
+
+#if defined (QLALR_DEBUG)
+ int ridx = rule_index[r];
+ printf ("%3d) %s ::=", r + 1, spell[rule_info[ridx]]);
+ ++ridx;
+ for (int i = ridx; i < ridx + rhs[r]; ++i) {
+ int symbol = rule_info[i];
+ if (const char *name = spell[symbol])
+ printf (" %s", name);
+ else
+ printf (" #%d", symbol);
+ }
+ printf ("\n");
+#endif
+
+ tos -= rhs[r];
+ act = state_stack[tos++];
+ ResumeReduction:
+ switch (r) {
+
+ case 0:
+ setType(QXmlStreamReader::EndDocument);
+ break;
+
+ case 1:
+ if (type != QXmlStreamReader::Invalid) {
+ if (hasSeenTag || inParseEntity) {
+ setType(QXmlStreamReader::EndDocument);
+ } else {
+ raiseError(QXmlStreamReader::NotWellFormedError, QXmlStream::tr("Start tag expected."));
+ // reset the parser
+ tos = 0;
+ state_stack[tos++] = 0;
+ state_stack[tos] = 0;
+ return false;
+ }
+ }
+ break;
+
+ case 10:
+ entityReferenceStack.pop()->isCurrentlyReferenced = false;
+ clearSym();
+ break;
+
+ case 11:
+ if (!scanString(spell[VERSION], VERSION, false) && atEnd) {
+ resume(11);
+ return false;
+ }
+ break;
+
+ case 12:
+ setType(QXmlStreamReader::StartDocument);
+ documentVersion = symString(6);
+ startDocument();
+ break;
+
+ case 13:
+ hasExternalDtdSubset = true;
+ dtdSystemId = symString(2);
+ break;
+
+ case 14:
+ checkPublicLiteral(symString(2));
+ dtdPublicId = symString(2);
+ dtdSystemId = symString(4);
+ hasExternalDtdSubset = true;
+ break;
+
+ case 16:
+ if (!scanPublicOrSystem() && atEnd) {
+ resume(16);
+ return false;
+ }
+ dtdName = symString(3);
+ break;
+
+ case 17:
+ case 18:
+ dtdName = symString(3);
+ Q_FALLTHROUGH();
+
+ case 19:
+ case 20:
+ setType(QXmlStreamReader::DTD);
+ text = &textBuffer;
+ break;
+
+ case 21:
+ scanDtd = true;
+ break;
+
+ case 22:
+ scanDtd = false;
+ break;
+
+ case 37:
+ if (!scanString(spell[EMPTY], EMPTY, false)
+ && !scanString(spell[ANY], ANY, false)
+ && atEnd) {
+ resume(37);
+ return false;
+ }
+ break;
+
+ case 43:
+ if (!scanString(spell[PCDATA], PCDATA, false) && atEnd) {
+ resume(43);
+ return false;
+ }
+ break;
+
+ case 68: {
+ lastAttributeIsCData = true;
+ } break;
+
+ case 78:
+ if (!scanAfterDefaultDecl() && atEnd) {
+ resume(78);
+ return false;
+ }
+ break;
+
+ case 83:
+ sym(1) = sym(2);
+ lastAttributeValue.clear();
+ lastAttributeIsCData = false;
+ if (!scanAttType() && atEnd) {
+ resume(83);
+ return false;
+ }
+ break;
+
+ case 84: {
+ DtdAttribute &dtdAttribute = dtdAttributes.push();
+ dtdAttribute.tagName.clear();
+ dtdAttribute.isCDATA = lastAttributeIsCData;
+ dtdAttribute.attributePrefix = addToStringStorage(symPrefix(1));
+ dtdAttribute.attributeName = addToStringStorage(symString(1));
+ dtdAttribute.attributeQualifiedName = addToStringStorage(symName(1));
+ dtdAttribute.isNamespaceAttribute = (dtdAttribute.attributePrefix == QLatin1String("xmlns")
+ || (dtdAttribute.attributePrefix.isEmpty()
+ && dtdAttribute.attributeName == QLatin1String("xmlns")));
+ if (lastAttributeValue.isNull()) {
+ dtdAttribute.defaultValue.clear();
+ } else {
+ if (dtdAttribute.isCDATA)
+ dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue);
+ else
+ dtdAttribute.defaultValue = addToStringStorage(lastAttributeValue.toString().simplified());
+
+ }
+ } break;
+
+ case 88: {
+ if (referenceToUnparsedEntityDetected && !standalone)
+ break;
+ int n = dtdAttributes.size();
+ QStringRef tagName = addToStringStorage(symName(3));
+ while (n--) {
+ DtdAttribute &dtdAttribute = dtdAttributes[n];
+ if (!dtdAttribute.tagName.isNull())
+ break;
+ dtdAttribute.tagName = tagName;
+ for (int i = 0; i < n; ++i) {
+ if ((dtdAttributes[i].tagName.isNull() || dtdAttributes[i].tagName == tagName)
+ && dtdAttributes[i].attributeQualifiedName == dtdAttribute.attributeQualifiedName) {
+ dtdAttribute.attributeQualifiedName.clear(); // redefined, delete it
+ break;
+ }
+ }
+ }
+ } break;
+
+ case 89: {
+ if (!scanPublicOrSystem() && atEnd) {
+ resume(89);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.push();
+ entityDeclaration.clear();
+ entityDeclaration.name = symString(3);
+ } break;
+
+ case 90: {
+ if (!scanPublicOrSystem() && atEnd) {
+ resume(90);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.push();
+ entityDeclaration.clear();
+ entityDeclaration.name = symString(5);
+ entityDeclaration.parameter = true;
+ } break;
+
+ case 91: {
+ if (!scanNData() && atEnd) {
+ resume(91);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ entityDeclaration.systemId = symString(3);
+ entityDeclaration.external = true;
+ } break;
+
+ case 92: {
+ if (!scanNData() && atEnd) {
+ resume(92);
+ return false;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ checkPublicLiteral((entityDeclaration.publicId = symString(3)));
+ entityDeclaration.systemId = symString(5);
+ entityDeclaration.external = true;
+ } break;
+
+ case 93: {
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ entityDeclaration.notationName = symString(3);
+ if (entityDeclaration.parameter)
+ raiseWellFormedError(QXmlStream::tr("NDATA in parameter entity declaration."));
+ }
+ Q_FALLTHROUGH();
+
+ case 94:
+ case 95: {
+ if (referenceToUnparsedEntityDetected && !standalone) {
+ entityDeclarations.pop();
+ break;
+ }
+ EntityDeclaration &entityDeclaration = entityDeclarations.top();
+ if (!entityDeclaration.external)
+ entityDeclaration.value = symString(2);
+ QString entityName = entityDeclaration.name.toString();
+ QHash<QString, Entity> &hash = entityDeclaration.parameter ? parameterEntityHash : entityHash;
+ if (!hash.contains(entityName)) {
+ Entity entity(entityDeclaration.value.toString());
+ entity.unparsed = (!entityDeclaration.notationName.isNull());
+ entity.external = entityDeclaration.external;
+ hash.insert(entityName, entity);
+ }
+ } break;
+
+ case 96: {
+ setType(QXmlStreamReader::ProcessingInstruction);
+ int pos = sym(4).pos + sym(4).len;
+ processingInstructionTarget = symString(3);
+ if (scanUntil("?>")) {
+ processingInstructionData = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 2);
+ const QString piTarget(processingInstructionTarget.toString());
+ if (!piTarget.compare(QLatin1String("xml"), Qt::CaseInsensitive)) {
+ raiseWellFormedError(QXmlStream::tr("XML declaration not at start of document."));
+ }
+ else if(!QXmlUtils::isNCName(piTarget))
+ raiseWellFormedError(QXmlStream::tr("%1 is an invalid processing instruction name.").arg(piTarget));
+ } else if (type != QXmlStreamReader::Invalid){
+ resume(96);
+ return false;
+ }
+ } break;
+
+ case 97:
+ setType(QXmlStreamReader::ProcessingInstruction);
+ processingInstructionTarget = symString(3);
+ if (!processingInstructionTarget.toString().compare(QLatin1String("xml"), Qt::CaseInsensitive))
+ raiseWellFormedError(QXmlStream::tr("Invalid processing instruction name."));
+ break;
+
+ case 98:
+ if (!scanAfterLangleBang() && atEnd) {
+ resume(98);
+ return false;
+ }
+ break;
+
+ case 99:
+ if (!scanUntil("--")) {
+ resume(99);
+ return false;
+ }
+ break;
+
+ case 100: {
+ setType(QXmlStreamReader::Comment);
+ int pos = sym(1).pos + 4;
+ text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
+ } break;
+
+ case 101: {
+ setType(QXmlStreamReader::Characters);
+ isCDATA = true;
+ isWhitespace = false;
+ int pos = sym(2).pos;
+ if (scanUntil("]]>", -1)) {
+ text = QStringRef(&textBuffer, pos, textBuffer.size() - pos - 3);
+ } else {
+ resume(101);
+ return false;
+ }
+ } break;
+
+ case 102: {
+ if (!scanPublicOrSystem() && atEnd) {
+ resume(102);
+ return false;
+ }
+ NotationDeclaration &notationDeclaration = notationDeclarations.push();
+ notationDeclaration.name = symString(3);
+ } break;
+
+ case 103: {
+ NotationDeclaration &notationDeclaration = notationDeclarations.top();
+ notationDeclaration.systemId = symString(3);
+ notationDeclaration.publicId.clear();
+ } break;
+
+ case 104: {
+ NotationDeclaration &notationDeclaration = notationDeclarations.top();
+ notationDeclaration.systemId.clear();
+ checkPublicLiteral((notationDeclaration.publicId = symString(3)));
+ } break;
+
+ case 105: {
+ NotationDeclaration &notationDeclaration = notationDeclarations.top();
+ checkPublicLiteral((notationDeclaration.publicId = symString(3)));
+ notationDeclaration.systemId = symString(5);
+ } break;
+
+ case 129:
+ isWhitespace = false;
+ Q_FALLTHROUGH();
+
+ case 130:
+ sym(1).len += fastScanContentCharList();
+ if (atEnd && !inParseEntity) {
+ resume(130);
+ return false;
+ }
+ break;
+
+ case 139:
+ if (!textBuffer.isEmpty()) {
+ setType(QXmlStreamReader::Characters);
+ text = &textBuffer;
+ }
+ break;
+
+ case 140:
+ case 141:
+ clearSym();
+ break;
+
+ case 142:
+ case 143:
+ sym(1) = sym(2);
+ break;
+
+ case 144:
+ case 145:
+ case 146:
+ case 147:
+ sym(1).len += sym(2).len;
+ break;
+
+ case 173:
+ if (normalizeLiterals)
+ textBuffer.data()[textBuffer.size()-1] = QLatin1Char(' ');
+ break;
+
+ case 174:
+ sym(1).len += fastScanLiteralContent();
+ if (atEnd) {
+ resume(174);
+ return false;
+ }
+ break;
+
+ case 175: {
+ if (!QXmlUtils::isPublicID(symString(1).toString())) {
+ raiseWellFormedError(QXmlStream::tr("%1 is an invalid PUBLIC identifier.").arg(symString(1).toString()));
+ resume(175);
+ return false;
+ }
+ } break;
+
+ case 176:
+ case 177:
+ clearSym();
+ break;
+
+ case 178:
+ case 179:
+ sym(1) = sym(2);
+ break;
+
+ case 180:
+ case 181:
+ case 182:
+ case 183:
+ sym(1).len += sym(2).len;
+ break;
+
+ case 213:
+ case 214:
+ clearSym();
+ break;
+
+ case 215:
+ case 216:
+ sym(1) = sym(2);
+ lastAttributeValue = symString(1);
+ break;
+
+ case 217:
+ case 218:
+ case 219:
+ case 220:
+ sym(1).len += sym(2).len;
+ break;
+
+ case 229: {
+ QStringRef prefix = symPrefix(1);
+ if (prefix.isEmpty() && symString(1) == QLatin1String("xmlns") && namespaceProcessing) {
+ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+ namespaceDeclaration.prefix.clear();
+
+ const QStringRef ns(symString(5));
+ if(ns == QLatin1String("http://www.w3.org/2000/xmlns/") ||
+ ns == QLatin1String("http://www.w3.org/XML/1998/namespace"))
+ raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
+ else
+ namespaceDeclaration.namespaceUri = addToStringStorage(ns);
+ } else {
+ Attribute &attribute = attributeStack.push();
+ attribute.key = sym(1);
+ attribute.value = sym(5);
+
+ QStringRef attributeQualifiedName = symName(1);
+ bool normalize = false;
+ for (int a = 0; a < dtdAttributes.size(); ++a) {
+ DtdAttribute &dtdAttribute = dtdAttributes[a];
+ if (!dtdAttribute.isCDATA
+ && dtdAttribute.tagName == qualifiedName
+ && dtdAttribute.attributeQualifiedName == attributeQualifiedName
+ ) {
+ normalize = true;
+ break;
+ }
+ }
+ if (normalize) {
+ // normalize attribute value (simplify and trim)
+ int pos = textBuffer.size();
+ int n = 0;
+ bool wasSpace = true;
+ for (int i = 0; i < attribute.value.len; ++i) {
+ QChar c = textBuffer.at(attribute.value.pos + i);
+ if (c.unicode() == ' ') {
+ if (wasSpace)
+ continue;
+ wasSpace = true;
+ } else {
+ wasSpace = false;
+ }
+ textBuffer += textBuffer.at(attribute.value.pos + i);
+ ++n;
+ }
+ if (wasSpace)
+ while (n && textBuffer.at(pos + n - 1).unicode() == ' ')
+ --n;
+ attribute.value.pos = pos;
+ attribute.value.len = n;
+ }
+ if (prefix == QLatin1String("xmlns") && namespaceProcessing) {
+ NamespaceDeclaration &namespaceDeclaration = namespaceDeclarations.push();
+ QStringRef namespacePrefix = symString(attribute.key);
+ QStringRef namespaceUri = symString(attribute.value);
+ attributeStack.pop();
+ if (((namespacePrefix == QLatin1String("xml"))
+ ^ (namespaceUri == QLatin1String("http://www.w3.org/XML/1998/namespace")))
+ || namespaceUri == QLatin1String("http://www.w3.org/2000/xmlns/")
+ || namespaceUri.isEmpty()
+ || namespacePrefix == QLatin1String("xmlns"))
+ raiseWellFormedError(QXmlStream::tr("Illegal namespace declaration."));
+
+ namespaceDeclaration.prefix = addToStringStorage(namespacePrefix);
+ namespaceDeclaration.namespaceUri = addToStringStorage(namespaceUri);
+ }
+ }
+ } break;
+
+ case 235: {
+ normalizeLiterals = true;
+ Tag &tag = tagStack_push();
+ prefix = tag.namespaceDeclaration.prefix = addToStringStorage(symPrefix(2));
+ name = tag.name = addToStringStorage(symString(2));
+ qualifiedName = tag.qualifiedName = addToStringStorage(symName(2));
+ if ((!prefix.isEmpty() && !QXmlUtils::isNCName(prefix)) || !QXmlUtils::isNCName(name))
+ raiseWellFormedError(QXmlStream::tr("Invalid XML name."));
+ } break;
+
+ case 236:
+ isEmptyElement = true;
+ Q_FALLTHROUGH();
+
+ case 237:
+ setType(QXmlStreamReader::StartElement);
+ resolveTag();
+ if (tagStack.size() == 1 && hasSeenTag && !inParseEntity)
+ raiseWellFormedError(QXmlStream::tr("Extra content at end of document."));
+ hasSeenTag = true;
+ break;
+
+ case 238: {
+ setType(QXmlStreamReader::EndElement);
+ Tag &tag = tagStack_pop();
+
+ namespaceUri = tag.namespaceDeclaration.namespaceUri;
+ name = tag.name;
+ qualifiedName = tag.qualifiedName;
+ if (qualifiedName != symName(3))
+ raiseWellFormedError(QXmlStream::tr("Opening and ending tag mismatch."));
+ } break;
+
+ case 239:
+ if (entitiesMustBeDeclared()) {
+ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(unresolvedEntity));
+ break;
+ }
+ setType(QXmlStreamReader::EntityReference);
+ name = &unresolvedEntity;
+ break;
+
+ case 240: {
+ sym(1).len += sym(2).len + 1;
+ QString reference = symString(2).toString();
+ if (entityHash.contains(reference)) {
+ Entity &entity = entityHash[reference];
+ if (entity.unparsed) {
+ raiseWellFormedError(QXmlStream::tr("Reference to unparsed entity '%1'.").arg(reference));
+ } else {
+ if (!entity.hasBeenParsed) {
+ parseEntity(entity.value);
+ entity.hasBeenParsed = true;
+ }
+ if (entity.literal)
+ putStringLiteral(entity.value);
+ else if (referenceEntity(entity))
+ putReplacement(entity.value);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ }
+ break;
+ }
+
+ if (entityResolver) {
+ QString replacementText = resolveUndeclaredEntity(reference);
+ if (!replacementText.isNull()) {
+ putReplacement(replacementText);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ break;
+ }
+ }
+
+ injectToken(UNRESOLVED_ENTITY);
+ unresolvedEntity = symString(2).toString();
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+
+ } break;
+
+ case 241: {
+ sym(1).len += sym(2).len + 1;
+ QString reference = symString(2).toString();
+ if (parameterEntityHash.contains(reference)) {
+ referenceToParameterEntityDetected = true;
+ Entity &entity = parameterEntityHash[reference];
+ if (entity.unparsed || entity.external) {
+ referenceToUnparsedEntityDetected = true;
+ } else {
+ if (referenceEntity(entity))
+ putString(entity.value);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ }
+ } else if (entitiesMustBeDeclared()) {
+ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(symString(2).toString()));
+ }
+ } break;
+
+ case 242:
+ sym(1).len += sym(2).len + 1;
+ break;
+
+ case 243: {
+ sym(1).len += sym(2).len + 1;
+ QString reference = symString(2).toString();
+ if (entityHash.contains(reference)) {
+ Entity &entity = entityHash[reference];
+ if (entity.unparsed || entity.value.isNull()) {
+ raiseWellFormedError(QXmlStream::tr("Reference to external entity '%1' in attribute value.").arg(reference));
+ break;
+ }
+ if (!entity.hasBeenParsed) {
+ parseEntity(entity.value);
+ entity.hasBeenParsed = true;
+ }
+ if (entity.literal)
+ putStringLiteral(entity.value);
+ else if (referenceEntity(entity))
+ putReplacementInAttributeValue(entity.value);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ break;
+ }
+
+ if (entityResolver) {
+ QString replacementText = resolveUndeclaredEntity(reference);
+ if (!replacementText.isNull()) {
+ putReplacement(replacementText);
+ textBuffer.chop(2 + sym(2).len);
+ clearSym();
+ break;
+ }
+ }
+ if (entitiesMustBeDeclared()) {
+ raiseWellFormedError(QXmlStream::tr("Entity '%1' not declared.").arg(reference));
+ }
+ } break;
+
+ case 244: {
+ if (uint s = resolveCharRef(3)) {
+ if (s >= 0xffff)
+ putStringLiteral(QString::fromUcs4(&s, 1));
+ else
+ putChar((LETTER << 16) | s);
+
+ textBuffer.chop(3 + sym(3).len);
+ clearSym();
+ } else {
+ raiseWellFormedError(QXmlStream::tr("Invalid character reference."));
+ }
+ } break;
+
+ case 247:
+ case 248:
+ sym(1).len += sym(2).len;
+ break;
+
+ case 259:
+ sym(1).len += fastScanSpace();
+ if (atEnd) {
+ resume(259);
+ return false;
+ }
+ break;
+
+ case 262: {
+ sym(1).len += fastScanName(&sym(1).prefix);
+ if (atEnd) {
+ resume(262);
+ return false;
+ }
+ } break;
+
+ case 263:
+ sym(1).len += fastScanName();
+ if (atEnd) {
+ resume(263);
+ return false;
+ }
+ break;
+
+ case 264:
+ case 265:
+ case 266:
+ case 267:
+ case 268:
+ sym(1).len += fastScanNMTOKEN();
+ if (atEnd) {
+ resume(268);
+ return false;
+ }
+
+ break;
+
+ default:
+ ;
+ } // switch
+ act = state_stack[tos] = nt_action (act, lhs[r] - TERMINAL_COUNT);
+ if (type != QXmlStreamReader::NoToken)
+ return true;
+ } else {
+ parseError();
+ break;
+ }
+ }
+ return false;
+}
+#endif //QT_NO_XMLSTREAMREADER.xml
+
+
+#endif // QXMLSTREAM_P_H
+
diff --git a/src/dbus/doc/src/qtdbus-index.qdoc b/src/dbus/doc/src/qtdbus-index.qdoc
index 080066cfa8..eed5e42731 100644
--- a/src/dbus/doc/src/qtdbus-index.qdoc
+++ b/src/dbus/doc/src/qtdbus-index.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -200,6 +200,15 @@
Information about the messages will be written to the console the application
was launched from.
+ \section1 Licenses
+
+ The Qt D-Bus module is available under commercial licenses from \l{The Qt Company}.
+ In addition, it is available under free software licenses. Since Qt 5.4,
+ these free software licenses are
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt Licensing} for further details.
+
\section1 Further Reading
The following documents contain information about Qt's D-Bus integration
diff --git a/src/gui/configure.json b/src/gui/configure.json
index ccaf38e4b7..27e913877f 100644
--- a/src/gui/configure.json
+++ b/src/gui/configure.json
@@ -167,25 +167,20 @@
"label": "Fontconfig",
"test": {
"head": [
- "#include <ft2build.h>",
- "#include FT_FREETYPE_H",
"#include <fontconfig/fontconfig.h>",
"#ifndef FC_RGBA_UNKNOWN",
"# error This version of fontconfig is tool old, it is missing the FC_RGBA_UNKNOWN define",
- "#endif",
- "#if ((FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100 + FREETYPE_PATCH) < 20110)",
- "# error This version of freetype is too old.",
"#endif"
],
"main": [
- "FT_Face face = 0;",
"FcPattern *pattern = 0;"
]
},
"sources": [
- { "type": "pkgConfig", "args": "fontconfig freetype2" },
- { "type": "freetype", "libs": "-lfontconfig -lfreetype" }
- ]
+ { "type": "pkgConfig", "args": "fontconfig" },
+ { "type": "freetype", "libs": "-lfontconfig" }
+ ],
+ "use": "freetype"
},
"gbm": {
"label": "GBM",
@@ -637,7 +632,13 @@
"angle_d3d11_qdtd": {
"label": "D3D11_QUERY_DATA_TIMESTAMP_DISJOINT",
"type": "compile",
- "test": "win/angle_d3d11_qdtd"
+ "test": {
+ "include": "d3d11.h",
+ "main": [
+ "D3D11_QUERY_DATA_TIMESTAMP_DISJOINT qdtd;",
+ "(void) qdtd;"
+ ]
+ }
},
"directwrite2": {
"label": "DirectWrite 2",
diff --git a/src/gui/doc/src/qtgui.qdoc b/src/gui/doc/src/qtgui.qdoc
index da3d419735..010659df8c 100644
--- a/src/gui/doc/src/qtgui.qdoc
+++ b/src/gui/doc/src/qtgui.qdoc
@@ -215,12 +215,13 @@
\section1 Licenses and Attributions
Qt GUI is available under commercial licenses from \l{The Qt Company}.
- In addition, it is available under the
+ In addition, it is available under free software licenses. Since Qt 5.4,
+ these free software licenses are
\l{GNU Lesser General Public License, version 3}, or
the \l{GNU General Public License, version 2}.
See \l{Qt Licensing} for further details.
- Furthermore Qt GUI potentially contains third party
+ Furthermore, Qt GUI in Qt \QtVersion may contain third-party
modules under following permissive licenses:
\generatelist{groupsbymodule attributions-qtgui}
diff --git a/src/gui/image/qmovie.cpp b/src/gui/image/qmovie.cpp
index d5e8b1b974..010760de4c 100644
--- a/src/gui/image/qmovie.cpp
+++ b/src/gui/image/qmovie.cpp
@@ -470,6 +470,10 @@ bool QMoviePrivate::next()
currentPixmap = QPixmap::fromImage( info.pixmap.toImage().scaled(scaledSize) );
else
currentPixmap = info.pixmap;
+
+ if (!speed)
+ return true;
+
nextDelay = speedAdjustedDelay(info.delay);
// Adjust delay according to the time it took to read the frame
int processingTime = time.elapsed();
@@ -504,7 +508,7 @@ void QMoviePrivate::_q_loadNextFrame(bool starting)
emit q->updated(frameRect);
emit q->frameChanged(currentFrameNumber);
- if (movieState == QMovie::Running)
+ if (speed && movieState == QMovie::Running)
nextImageTimer.start(nextDelay);
} else {
// Could not read another frame
@@ -926,6 +930,8 @@ void QMovie::setPaused(bool paused)
void QMovie::setSpeed(int percentSpeed)
{
Q_D(QMovie);
+ if (!d->speed && d->movieState == Running)
+ d->nextImageTimer.start(nextFrameDelay());
d->speed = percentSpeed;
}
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 36c9b1a964..f7da94d111 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -2122,7 +2122,7 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
QWindow *window = e->window.data();
modifier_buttons = e->modifiers;
if (e->nullWindow()
-#if defined(Q_OS_ANDROID)
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
|| e->key == Qt::Key_Back || e->key == Qt::Key_Menu
#endif
) {
@@ -2158,7 +2158,7 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE
if (window && !window->d_func()->blockedByModalWindow)
QGuiApplication::sendSpontaneousEvent(window, &ev);
-#if defined(Q_OS_ANDROID)
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
else
ev.setAccepted(false);
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 27ea3864b9..6f332c8ad6 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -1002,6 +1002,7 @@ bool QOpenGLContext::makeCurrent(QSurface *surface)
if (rendererString)
needsWorkaround =
qstrncmp(rendererString, "Mali-4xx", 6) == 0 // Mali-400, Mali-450
+ || qstrcmp(rendererString, "Mali-T880") == 0
|| qstrncmp(rendererString, "Adreno (TM) 2xx", 13) == 0 // Adreno 200, 203, 205
|| qstrncmp(rendererString, "Adreno 2xx", 8) == 0 // Same as above but without the '(TM)'
|| qstrncmp(rendererString, "Adreno (TM) 30x", 14) == 0 // Adreno 302, 305
diff --git a/src/gui/kernel/qplatforminputcontext.cpp b/src/gui/kernel/qplatforminputcontext.cpp
index 3f59116e9a..9771e6ba11 100644
--- a/src/gui/kernel/qplatforminputcontext.cpp
+++ b/src/gui/kernel/qplatforminputcontext.cpp
@@ -287,6 +287,8 @@ void QPlatformInputContext::setSelectionOnFocusObject(const QPointF &anchorPos,
if (success) {
int cursor = QInputMethod::queryFocusObject(Qt::ImCursorPosition, cursorPos * mapToLocal).toInt(&success);
if (success) {
+ if (anchor == cursor && anchorPos != cursorPos)
+ return;
QList<QInputMethodEvent::Attribute> imAttributes;
imAttributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection, anchor, cursor - anchor, QVariant()));
QInputMethodEvent event(QString(), imAttributes);
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
index 1b56c7d9f2..c98b879a15 100644
--- a/src/gui/kernel/qsimpledrag.cpp
+++ b/src/gui/kernel/qsimpledrag.cpp
@@ -58,6 +58,7 @@
#include <QtCore/QEventLoop>
#include <QtCore/QDebug>
+#include <QtCore/QLoggingCategory>
#include <private/qguiapplication_p.h>
#include <private/qdnd_p.h>
@@ -69,6 +70,8 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_DRAGANDDROP
+Q_LOGGING_CATEGORY(lcDnd, "qt.gui.dnd")
+
static QWindow* topLevelAt(const QPoint &pos)
{
QWindowList list = QGuiApplication::topLevelWindows();
@@ -94,9 +97,9 @@ static QWindow* topLevelAt(const QPoint &pos)
*/
QBasicDrag::QBasicDrag() :
- m_restoreCursor(false), m_eventLoop(0),
+ m_current_window(nullptr), m_restoreCursor(false), m_eventLoop(nullptr),
m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false),
- m_drag(0), m_drag_icon_window(0), m_useCompositing(true),
+ m_drag(nullptr), m_drag_icon_window(nullptr), m_useCompositing(true),
m_screen(nullptr)
{
}
@@ -161,6 +164,7 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
return true; // Eat all mouse move events
}
case QEvent::MouseButtonRelease:
+ {
disableEventFilter();
if (canDrop()) {
QPoint nativePosition = getNativeMousePos(e, m_drag_icon_window);
@@ -169,8 +173,25 @@ bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
cancel();
}
exitDndEventLoop();
- QCoreApplication::postEvent(o, new QMouseEvent(*static_cast<QMouseEvent *>(e)));
+
+ // If a QShapedPixmapWindow (drag feedback) is being dragged along, the
+ // mouse event's localPos() will be relative to that, which is useless.
+ // We want a position relative to the window where the drag ends, if possible (?).
+ // If there is no such window (belonging to this Qt application),
+ // make the event relative to the window where the drag started. (QTBUG-66103)
+ const QMouseEvent *release = static_cast<QMouseEvent *>(e);
+ const QWindow *releaseWindow = topLevelAt(release->globalPos());
+ qCDebug(lcDnd) << "mouse released over" << releaseWindow << "after drag from" << m_current_window << "globalPos" << release->globalPos();
+ if (!releaseWindow)
+ releaseWindow = m_current_window;
+ QPoint releaseWindowPos = (releaseWindow ? releaseWindow->mapFromGlobal(release->globalPos()) : release->globalPos());
+ QMouseEvent *newRelease = new QMouseEvent(release->type(),
+ releaseWindowPos, releaseWindowPos, release->screenPos(),
+ release->button(), release->buttons(),
+ release->modifiers(), release->source());
+ QCoreApplication::postEvent(o, newRelease);
return true; // defer mouse release events until drag event loop has returned
+ }
case QEvent::MouseButtonDblClick:
case QEvent::Wheel:
return true;
@@ -349,7 +370,7 @@ static inline QPoint fromNativeGlobalPixels(const QPoint &point)
into account.
*/
-QSimpleDrag::QSimpleDrag() : m_current_window(0)
+QSimpleDrag::QSimpleDrag()
{
}
@@ -366,6 +387,7 @@ void QSimpleDrag::startDrag()
updateCursor(Qt::IgnoreAction);
}
setExecutedDropAction(Qt::IgnoreAction);
+ qCDebug(lcDnd) << "drag began from" << m_current_window<< "cursor pos" << QCursor::pos() << "can drop?" << canDrop();
}
void QSimpleDrag::cancel()
diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
index 4db8eb4505..e56c7bf306 100644
--- a/src/gui/kernel/qsimpledrag_p.h
+++ b/src/gui/kernel/qsimpledrag_p.h
@@ -105,6 +105,9 @@ protected:
QDrag *drag() const { return m_drag; }
+protected:
+ QWindow *m_current_window;
+
private:
void enableEventFilter();
void disableEventFilter();
@@ -131,9 +134,6 @@ protected:
virtual void cancel() override;
virtual void move(const QPoint &globalPos) override;
virtual void drop(const QPoint &globalPos) override;
-
-private:
- QWindow *m_current_window;
};
#endif // QT_NO_DRAGANDDROP
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 35a9ede227..318a280a40 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -283,9 +283,10 @@ QT_DEFINE_QPA_EVENT_HANDLER(void, handleApplicationStateChanged, Qt::Application
QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow *window, const QRect &newGeometry)
: WindowSystemEvent(GeometryChange)
, window(window)
- , requestedGeometry(window->handle() ? window->handle()->QPlatformWindow::geometry() : QRect())
, newGeometry(newGeometry)
{
+ if (const QPlatformWindow *pw = window->handle())
+ requestedGeometry = QHighDpi::fromNativePixels(pw->QPlatformWindow::geometry(), window);
}
QT_DEFINE_QPA_EVENT_HANDLER(void, handleGeometryChange, QWindow *window, const QRect &newRect)
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index 3563f1b5d3..b825b56d45 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -778,6 +778,8 @@ static QOpenGLTexture::PixelFormat pixelFormatCompatibleWithInternalFormat(QOpen
return QOpenGLTexture::Alpha;
case QOpenGLTexture::RGBFormat:
+ return QOpenGLTexture::RGB;
+
case QOpenGLTexture::RGBAFormat:
return QOpenGLTexture::RGBA;
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index 1e14498f79..29bef14f0c 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -127,7 +127,7 @@ AVX2_SOURCES += painting/qdrawhelper_avx2.cpp
NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
NEON_HEADERS += painting/qdrawhelper_neon_p.h
NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
-!uikit:contains(QT_ARCH, "arm"): CONFIG += no_clang_integrated_as
+!uikit:!win32:contains(QT_ARCH, "arm"): CONFIG += no_clang_integrated_as
!uikit:!win32:!contains(QT_ARCH, "arm64"): DEFINES += ENABLE_PIXMAN_DRAWHELPERS
MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
diff --git a/src/gui/painting/qmatrix.h b/src/gui/painting/qmatrix.h
index 74ecef767e..d8a4fcfb1c 100644
--- a/src/gui/painting/qmatrix.h
+++ b/src/gui/painting/qmatrix.h
@@ -65,10 +65,10 @@ public:
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
// ### Qt 6: remove; the compiler-generated ones are fine!
QMatrix &operator=(QMatrix &&other) Q_DECL_NOTHROW // = default
- { memcpy(this, &other, sizeof(QMatrix)); return *this; }
+ { memcpy(static_cast<void *>(this), static_cast<void *>(&other), sizeof(QMatrix)); return *this; }
QMatrix &operator=(const QMatrix &) Q_DECL_NOTHROW; // = default
QMatrix(QMatrix &&other) Q_DECL_NOTHROW // = default
- { memcpy(this, &other, sizeof(QMatrix)); }
+ { memcpy(static_cast<void *>(this), static_cast<void *>(&other), sizeof(QMatrix)); }
QMatrix(const QMatrix &other) Q_DECL_NOTHROW; // = default
#endif
diff --git a/src/gui/painting/qtransform.h b/src/gui/painting/qtransform.h
index 79835b36e2..63c4a241c1 100644
--- a/src/gui/painting/qtransform.h
+++ b/src/gui/painting/qtransform.h
@@ -78,14 +78,14 @@ public:
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
// ### Qt 6: remove; the compiler-generated ones are fine!
QTransform &operator=(QTransform &&other) Q_DECL_NOTHROW // = default
- { memcpy(this, &other, sizeof(QTransform)); return *this; }
+ { memcpy(static_cast<void *>(this), static_cast<void *>(&other), sizeof(QTransform)); return *this; }
QTransform &operator=(const QTransform &) Q_DECL_NOTHROW; // = default
QTransform(QTransform &&other) Q_DECL_NOTHROW // = default
: affine(Qt::Uninitialized)
- { memcpy(this, &other, sizeof(QTransform)); }
+ { memcpy(static_cast<void *>(this), static_cast<void *>(&other), sizeof(QTransform)); }
QTransform(const QTransform &other) Q_DECL_NOTHROW // = default
: affine(Qt::Uninitialized)
- { memcpy(this, &other, sizeof(QTransform)); }
+ { memcpy(static_cast<void *>(this), static_cast<const void *>(&other), sizeof(QTransform)); }
#endif
bool isAffine() const;
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index 8cdbeafd7d..4b1564e69c 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -237,13 +237,13 @@ struct QGlyphLayout
last = numGlyphs;
if (first == 0 && last == numGlyphs
&& reinterpret_cast<char *>(offsets + numGlyphs) == reinterpret_cast<char *>(glyphs)) {
- memset(offsets, 0, (numGlyphs * SpaceNeeded));
+ memset(static_cast<void *>(offsets), 0, (numGlyphs * SpaceNeeded));
} else {
const int num = last - first;
- memset(offsets + first, 0, num * sizeof(QFixedPoint));
+ memset(static_cast<void *>(offsets + first), 0, num * sizeof(QFixedPoint));
memset(glyphs + first, 0, num * sizeof(glyph_t));
- memset(advances + first, 0, num * sizeof(QFixed));
- memset(justifications + first, 0, num * sizeof(QGlyphJustification));
+ memset(static_cast<void *>(advances + first), 0, num * sizeof(QFixed));
+ memset(static_cast<void *>(justifications + first), 0, num * sizeof(QGlyphJustification));
memset(attributes + first, 0, num * sizeof(QGlyphAttributes));
}
}
diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h
index 7e4efa28f8..067f8473ea 100644
--- a/src/gui/text/qtextobject.h
+++ b/src/gui/text/qtextobject.h
@@ -154,9 +154,9 @@ public:
iterator(const iterator &o) Q_DECL_NOTHROW; // = default
iterator &operator=(const iterator &o) Q_DECL_NOTHROW; // = default
iterator(iterator &&other) Q_DECL_NOTHROW // = default
- { memcpy(this, &other, sizeof(iterator)); }
+ { memcpy(static_cast<void *>(this), static_cast<void *>(&other), sizeof(iterator)); }
iterator &operator=(iterator &&other) Q_DECL_NOTHROW // = default
- { memcpy(this, &other, sizeof(iterator)); return *this; }
+ { memcpy(static_cast<void *>(this), static_cast<void *>(&other), sizeof(iterator)); return *this; }
#endif
QTextFrame *parentFrame() const { return f; }
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 517af326a8..0e2c257952 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -354,7 +354,7 @@ void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair)
host += QByteArray::number(port);
}
- request.setHeaderField("Host", host);
+ request.prependHeaderField("Host", host);
}
reply->d_func()->requestIsPrepared = true;
diff --git a/src/network/access/qhttpnetworkheader.cpp b/src/network/access/qhttpnetworkheader.cpp
index 19a3dfcfe8..3326f89d2f 100644
--- a/src/network/access/qhttpnetworkheader.cpp
+++ b/src/network/access/qhttpnetworkheader.cpp
@@ -112,6 +112,11 @@ void QHttpNetworkHeaderPrivate::setHeaderField(const QByteArray &name, const QBy
fields.append(qMakePair(name, data));
}
+void QHttpNetworkHeaderPrivate::prependHeaderField(const QByteArray &name, const QByteArray &data)
+{
+ fields.prepend(qMakePair(name, data));
+}
+
bool QHttpNetworkHeaderPrivate::operator==(const QHttpNetworkHeaderPrivate &other) const
{
return (url == other.url);
diff --git a/src/network/access/qhttpnetworkheader_p.h b/src/network/access/qhttpnetworkheader_p.h
index f46c259919..3adb0ed7f1 100644
--- a/src/network/access/qhttpnetworkheader_p.h
+++ b/src/network/access/qhttpnetworkheader_p.h
@@ -92,6 +92,7 @@ public:
QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const;
QList<QByteArray> headerFieldValues(const QByteArray &name) const;
void setHeaderField(const QByteArray &name, const QByteArray &data);
+ void prependHeaderField(const QByteArray &name, const QByteArray &data);
bool operator==(const QHttpNetworkHeaderPrivate &other) const;
};
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index 3fcf946945..cf4be3df95 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -279,6 +279,11 @@ void QHttpNetworkRequest::setHeaderField(const QByteArray &name, const QByteArra
d->setHeaderField(name, data);
}
+void QHttpNetworkRequest::prependHeaderField(const QByteArray &name, const QByteArray &data)
+{
+ d->prependHeaderField(name, data);
+}
+
QHttpNetworkRequest &QHttpNetworkRequest::operator=(const QHttpNetworkRequest &other)
{
d = other.d;
diff --git a/src/network/access/qhttpnetworkrequest_p.h b/src/network/access/qhttpnetworkrequest_p.h
index 2cbb8e255e..bc797537ae 100644
--- a/src/network/access/qhttpnetworkrequest_p.h
+++ b/src/network/access/qhttpnetworkrequest_p.h
@@ -102,6 +102,7 @@ public:
QList<QPair<QByteArray, QByteArray> > header() const override;
QByteArray headerField(const QByteArray &name, const QByteArray &defaultValue = QByteArray()) const override;
void setHeaderField(const QByteArray &name, const QByteArray &data) override;
+ void prependHeaderField(const QByteArray &name, const QByteArray &data);
Operation operation() const;
void setOperation(Operation operation);
diff --git a/src/network/configure.json b/src/network/configure.json
index 94a23bbc78..89bb1efffa 100644
--- a/src/network/configure.json
+++ b/src/network/configure.json
@@ -141,10 +141,10 @@
"use": "network"
},
"openssl11": {
- "label": "OpenSSL v. 1.1 support",
+ "label": "OpenSSL 1.1 support",
"type": "compile",
"test": "unix/openssl11",
- "use": "network"
+ "use": "openssl"
}
},
@@ -213,9 +213,9 @@
"output": [ "publicFeature", "feature" ]
},
"opensslv11": {
- "label": "OpenSSL v. 1.1",
- "condition": "tests.openssl11",
- "output": ["publicFeature", "feature"]
+ "label": "OpenSSL 1.1",
+ "condition": "features.openssl && tests.openssl11",
+ "output": [ "publicFeature" ]
},
"sctp": {
"label": "SCTP",
@@ -341,6 +341,7 @@ For example:
},
"openssl",
"openssl-linked",
+ "opensslv11",
"sctp",
"system-proxies"
]
diff --git a/src/network/network.pro b/src/network/network.pro
index b8272d91d6..9082439f1c 100644
--- a/src/network/network.pro
+++ b/src/network/network.pro
@@ -10,7 +10,7 @@ DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
#DEFINES += QTCPSOCKETENGINE_DEBUG QTCPSOCKET_DEBUG QTCPSERVER_DEBUG QSSLSOCKET_DEBUG
#DEFINES += QUDPSOCKET_DEBUG QUDPSERVER_DEBUG
#DEFINES += QSCTPSOCKET_DEBUG QSCTPSERVER_DEBUG
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x64000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x64000000
QMAKE_DOCS = $$PWD/doc/qtnetwork.qdocconf
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 2d771b5637..1fc7817fe8 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -541,12 +541,14 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
directories << ministroPath;
nameFilters << QLatin1String("*.der");
platformEncodingFormat = QSsl::Der;
+# ifndef Q_OS_ANDROID_EMBEDDED
if (ministroPath.isEmpty()) {
QList<QByteArray> certificateData = fetchSslCertificateData();
for (int i = 0; i < certificateData.size(); ++i) {
systemCerts.append(QSslCertificate::fromData(certificateData.at(i), QSsl::Der));
}
} else
+# endif //Q_OS_ANDROID_EMBEDDED
# endif //Q_OS_ANDROID
{
currentDir.setNameFilters(nameFilters);
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index ced861805b..6f34c6c888 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -210,7 +210,7 @@ public:
private:
static bool ensureLibraryLoaded();
static void ensureCiphersAndCertsLoaded();
-#if defined(Q_OS_ANDROID)
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
static QList<QByteArray> fetchSslCertificateData();
#endif
diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri
index 949ebc3d2a..2783effaf1 100644
--- a/src/network/ssl/ssl.pri
+++ b/src/network/ssl/ssl.pri
@@ -82,7 +82,7 @@ qtConfig(ssl) {
darwin:SOURCES += ssl/qsslsocket_mac_shared.cpp
- android: SOURCES += ssl/qsslsocket_openssl_android.cpp
+ android:!android-embedded: SOURCES += ssl/qsslsocket_openssl_android.cpp
# Add optional SSL libs
# Static linking of OpenSSL with msvc:
diff --git a/src/opengl/doc/src/qtopengl-index.qdoc b/src/opengl/doc/src/qtopengl-index.qdoc
index 6ab888a14d..30b657f6db 100644
--- a/src/opengl/doc/src/qtopengl-index.qdoc
+++ b/src/opengl/doc/src/qtopengl-index.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -41,9 +41,6 @@
platform, Microsoft Foundation Classes (MFC) under Windows, or Qt
on both platforms.
- \note OpenGL is a trademark of Silicon Graphics, Inc. in
- the United States and other countries.
-
The Qt OpenGL module makes it easy to use OpenGL in Qt applications.
It provides an OpenGL widget class that can be used just like any
other Qt widget, except that it opens an OpenGL display buffer where
@@ -68,4 +65,16 @@
The \l{Qt OpenGL C++ Classes} page gives an overview over the available classes
in this module.
+
+ \section1 Licenses and Trademarks
+
+ The Qt OpenGL module is available under commercial licenses from \l{The Qt Company}.
+ In addition, it is available under free software licenses. Since Qt 5.4,
+ these free software licenses are
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt Licensing} for further details.
+
+ OpenGL\reg is a trademark of Silicon Graphics, Inc. in
+ the United States and other countries.
*/
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index 077b190d3e..8b2349ff2f 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -3,7 +3,7 @@ QT = core-private gui-private widgets-private
DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x63000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x63000000
solaris-cc*:QMAKE_CXXFLAGS_RELEASE -= -O2
QMAKE_DOCS = $$PWD/doc/qtopengl.qdocconf
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
index 674ab29012..7a9a98573e 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
@@ -45,7 +45,7 @@
#include <QtPlatformHeaders/QEGLNativeContext>
#include <QDebug>
-#ifdef Q_OS_ANDROID
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
#include <QtCore/private/qjnihelpers_p.h>
#endif
#ifndef Q_OS_WIN
@@ -332,7 +332,7 @@ void QEGLPlatformContext::updateFormatFromGL()
QByteArray version = QByteArray(reinterpret_cast<const char *>(s));
int major, minor;
if (QPlatformOpenGLContext::parseOpenGLVersion(version, major, minor)) {
-#ifdef Q_OS_ANDROID
+#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
// Some Android 4.2.2 devices report OpenGL ES 3.0 without the functions being available.
static int apiLevel = QtAndroidPrivate::androidSdkVersion();
if (apiLevel <= 17 && major >= 3) {
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
index beec8e763c..cc0246b64a 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
@@ -993,9 +993,7 @@ int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags,
static inline bool areMetricsTooLarge(const QFontEngineFT::GlyphInfo &info)
{
// false if exceeds QFontEngineFT::Glyph metrics
- return (short)(info.linearAdvance) != info.linearAdvance
- || (uchar)(info.width) != info.width
- || (uchar)(info.height) != info.height;
+ return info.width > 0xFF || info.height > 0xFF;
}
static inline void transformBoundingBox(int *left, int *top, int *right, int *bottom, FT_Matrix *matrix)
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h b/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
index f5585da7de..d498b0ac8b 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft_p.h
@@ -133,7 +133,7 @@ public:
/* we don't cache glyphs that are too large anyway, so we can make this struct rather small */
struct Glyph {
~Glyph();
- short linearAdvance;
+ int linearAdvance : 22;
unsigned char width;
unsigned char height;
short x;
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index 2edee51989..5eb5cd8a30 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -507,6 +507,23 @@ static QString familyNameFromPostScriptName(NSString *psName)
}
#endif
+static void addExtraFallbacks(QStringList *fallbackList)
+{
+#if defined(Q_OS_MACOS)
+ // Since we are only returning a list of default fonts for the current language, we do not
+ // cover all unicode completely. This was especially an issue for some of the common script
+ // symbols such as mathematical symbols, currency or geometric shapes. To minimize the risk
+ // of missing glyphs, we add Arial Unicode MS as a final fail safe, since this covers most
+ // of Unicode 2.1.
+ if (!fallbackList->contains(QStringLiteral("Arial Unicode MS")))
+ fallbackList->append(QStringLiteral("Arial Unicode MS"));
+ // Since some symbols (specifically Braille) are not in Arial Unicode MS, we
+ // add Apple Symbols to cover those too.
+ if (!fallbackList->contains(QStringLiteral("Apple Symbols")))
+ fallbackList->append(QStringLiteral("Apple Symbols"));
+#endif
+}
+
QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const
{
Q_UNUSED(style);
@@ -534,16 +551,7 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
fallbackList.append(QString::fromCFString(fallbackFamilyName));
}
-#if defined(Q_OS_OSX)
- // Since we are only returning a list of default fonts for the current language, we do not
- // cover all unicode completely. This was especially an issue for some of the common script
- // symbols such as mathematical symbols, currency or geometric shapes. To minimize the risk
- // of missing glyphs, we add Arial Unicode MS as a final fail safe, since this covers most
- // of Unicode 2.1.
- if (!fallbackList.contains(QStringLiteral("Arial Unicode MS")))
- fallbackList.append(QStringLiteral("Arial Unicode MS"));
-#endif
-
+ addExtraFallbacks(&fallbackList);
extern QStringList qt_sort_families_by_writing_system(QChar::Script, const QStringList &);
fallbackList = qt_sort_families_by_writing_system(script, fallbackList);
@@ -584,14 +592,7 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
fallbackList.append(QLatin1String("Apple Color Emoji"));
- // Since we are only returning a list of default fonts for the current language, we do not
- // cover all unicode completely. This was especially an issue for some of the common script
- // symbols such as mathematical symbols, currency or geometric shapes. To minimize the risk
- // of missing glyphs, we add Arial Unicode MS as a final fail safe, since this covers most
- // of Unicode 2.1.
- if (!fallbackList.contains(QStringLiteral("Arial Unicode MS")))
- fallbackList.append(QStringLiteral("Arial Unicode MS"));
-
+ addExtraFallbacks(&fallbackList);
fallbackLists[styleLookupKey.arg(fallbackStyleHint)] = fallbackList;
}
#else
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 675f689ace..25ff69d877 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -182,6 +182,14 @@ public:
: QCoreTextFontEngine(font, def)
, m_fontData(fontData)
{}
+ QFontEngine *cloneWithSize(qreal pixelSize) const
+ {
+ QFontDef newFontDef = fontDef;
+ newFontDef.pixelSize = pixelSize;
+ newFontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
+
+ return new QCoreTextRawFontEngine(cgFont, newFontDef, m_fontData);
+ }
QByteArray m_fontData;
};
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
index 1f7b346909..b77aaa27c1 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
@@ -125,7 +125,7 @@ public:
static QFontEngine::GlyphFormat defaultGlyphFormat;
static QCoreTextFontEngine *create(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference);
-private:
+protected:
void init();
QImage imageForGlyph(glyph_t glyph, QFixed subPixelPosition, bool colorful, const QTransform &m);
CTFontRef ctfont;
diff --git a/src/platformsupport/fontdatabases/windows/qwindowsnativeimage.cpp b/src/platformsupport/fontdatabases/windows/qwindowsnativeimage.cpp
index 67a6619b91..b1133dca22 100644
--- a/src/platformsupport/fontdatabases/windows/qwindowsnativeimage.cpp
+++ b/src/platformsupport/fontdatabases/windows/qwindowsnativeimage.cpp
@@ -101,8 +101,10 @@ static inline HBITMAP createDIB(HDC hdc, int width, int height,
uchar *bits = nullptr;
HBITMAP bitmap = CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO *>(&bmi),
DIB_RGB_COLORS, reinterpret_cast<void **>(&bits), 0, 0);
- if (Q_UNLIKELY(!bitmap || !bits))
- qFatal("%s: CreateDIBSection failed.", __FUNCTION__);
+ if (Q_UNLIKELY(!bitmap || !bits)) {
+ qFatal("%s: CreateDIBSection failed (%dx%d, format: %d)", __FUNCTION__,
+ width, height, int(format));
+ }
*bitsIn = bits;
return bitmap;
diff --git a/src/plugins/bearer/bearer.pro b/src/plugins/bearer/bearer.pro
index 824fd0388f..afdc613167 100644
--- a/src/plugins/bearer/bearer.pro
+++ b/src/plugins/bearer/bearer.pro
@@ -6,6 +6,6 @@ QT_FOR_CONFIG += network-private
SUBDIRS += connman networkmanager
}
-android:SUBDIRS += android
+android:!android-embedded: SUBDIRS += android
isEmpty(SUBDIRS):SUBDIRS = generic
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index fe4c5be4cb..f548a1fa96 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -438,6 +438,16 @@ QAndroidInputContext::QAndroidInputContext()
QObject::connect(QGuiApplication::inputMethod(), &QInputMethod::cursorRectangleChanged,
this, &QAndroidInputContext::updateSelectionHandles);
+ QObject::connect(QGuiApplication::inputMethod(), &QInputMethod::anchorRectangleChanged,
+ this, &QAndroidInputContext::updateSelectionHandles);
+ QObject::connect(QGuiApplication::inputMethod(), &QInputMethod::inputItemClipRectangleChanged, this, [this]{
+ auto im = qGuiApp->inputMethod();
+ if (!im->inputItemClipRectangle().contains(im->anchorRectangle()) ||
+ !im->inputItemClipRectangle().contains(im->cursorRectangle())) {
+ m_cursorHandleShown = CursorHandleNotShown;
+ updateSelectionHandles();
+ }
+ });
}
QAndroidInputContext::~QAndroidInputContext()
@@ -595,27 +605,63 @@ void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y)
double pixelDensity = window
? QHighDpiScaling::factor(window)
: QHighDpiScaling::factor(QtAndroid::androidPlatformIntegration()->screen());
- QPoint point(x / pixelDensity, y / pixelDensity);
- y -= leftRect.width() / 2;
+ QPointF point(x / pixelDensity, y / pixelDensity);
+ point.setY(point.y() - leftRect.width() / 2);
if (handleId == 1) {
setSelectionOnFocusObject(point, point);
return;
}
- QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition);
+ QInputMethodQueryEvent query(Qt::ImCursorPosition | Qt::ImAnchorPosition | Qt::ImCurrentSelection);
QCoreApplication::sendEvent(m_focusObject, &query);
int cpos = query.value(Qt::ImCursorPosition).toInt();
int anchor = query.value(Qt::ImAnchorPosition).toInt();
-
+ bool rtl = query.value(Qt::ImCurrentSelection).toString().isRightToLeft();
auto rightRect = im->anchorRectangle();
if (cpos > anchor)
std::swap(leftRect, rightRect);
+ auto checkLeftHandle = [&rightRect](QPointF &handlePos) {
+ if (handlePos.y() > rightRect.center().y())
+ handlePos.setY(rightRect.center().y()); // adjust Y handle pos
+ if (handlePos.y() >= rightRect.y() && handlePos.y() <= rightRect.bottom() && handlePos.x() >= rightRect.x())
+ return false; // same line and wrong X pos ?
+ return true;
+ };
+
+ auto checkRtlRightHandle = [&rightRect](QPointF &handlePos) {
+ if (handlePos.y() > rightRect.center().y())
+ handlePos.setY(rightRect.center().y()); // adjust Y handle pos
+ if (handlePos.y() >= rightRect.y() && handlePos.y() <= rightRect.bottom() && rightRect.x() >= handlePos.x())
+ return false; // same line and wrong X pos ?
+ return true;
+ };
+
+ auto checkRightHandle = [&leftRect](QPointF &handlePos) {
+ if (handlePos.y() < leftRect.center().y())
+ handlePos.setY(leftRect.center().y()); // adjust Y handle pos
+ if (handlePos.y() >= leftRect.y() && handlePos.y() <= leftRect.bottom() && leftRect.x() >= handlePos.x())
+ return false; // same line and wrong X pos ?
+ return true;
+ };
+
+ auto checkRtlLeftHandle = [&leftRect](QPointF &handlePos) {
+ if (handlePos.y() < leftRect.center().y())
+ handlePos.setY(leftRect.center().y()); // adjust Y handle pos
+ if (handlePos.y() >= leftRect.y() && handlePos.y() <= leftRect.bottom() && handlePos.x() >= leftRect.x())
+ return false; // same line and wrong X pos ?
+ return true;
+ };
+
if (handleId == 2) {
- QPoint rightPoint(rightRect.center().toPoint());
+ QPointF rightPoint(rightRect.center());
+ if ((!rtl && !checkLeftHandle(point)) || (rtl && !checkRtlRightHandle(point)))
+ return;
setSelectionOnFocusObject(point, rightPoint);
} else if (handleId == 3) {
- QPoint leftPoint(leftRect.center().toPoint());
+ QPointF leftPoint(leftRect.center());
+ if ((!rtl && !checkRightHandle(point)) || (rtl && !checkRtlLeftHandle(point)))
+ return;
setSelectionOnFocusObject(leftPoint, point);
}
}
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index 32be9ad4ee..a94e0dc517 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -311,6 +311,24 @@ QT_USE_NAMESPACE
return NO; // Someday qApp->quitOnLastWindowClosed(); when QApp and NSApp work closer together.
}
+- (void)applicationWillHide:(NSNotification *)notification
+{
+ if (reflectionDelegate
+ && [reflectionDelegate respondsToSelector:@selector(applicationWillHide:)]) {
+ [reflectionDelegate applicationWillHide:notification];
+ }
+
+ // When the application is hidden Qt will hide the popup windows associated with
+ // it when it has lost the activation for the application. However, when it gets
+ // to this point it believes the popup windows to be hidden already due to the
+ // fact that the application itself is hidden, which will cause a problem when
+ // the application is made visible again.
+ const QWindowList topLevelWindows = QGuiApplication::topLevelWindows();
+ for (QWindow *topLevelWindow : qAsConst(topLevelWindows)) {
+ if ((topLevelWindow->type() & Qt::Popup) == Qt::Popup && topLevelWindow->isVisible())
+ topLevelWindow->hide();
+ }
+}
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 00bfc8bef5..94f2125bad 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -415,6 +415,13 @@ static QString strippedText(QString s)
} else {
QList<QUrl> result;
QString filename = QString::fromNSString([[mSavePanel URL] path]).normalized(QString::NormalizationForm_C);
+ const QString defaultSuffix = mOptions->defaultSuffix();
+ const QFileInfo fileInfo(filename);
+ // If neither the user or the NSSavePanel have provided a suffix, use
+ // the default suffix (if it exists).
+ if (fileInfo.suffix().isEmpty() && !defaultSuffix.isEmpty()) {
+ filename.append('.').append(defaultSuffix);
+ }
result << QUrl::fromLocalFile(filename.remove(QLatin1String("___qt_very_unlikely_prefix_")));
return result;
}
@@ -442,10 +449,7 @@ static QString strippedText(QString s)
[mPopUpButton setHidden:chooseDirsOnly]; // TODO hide the whole sunken pane instead?
if (mOptions->acceptMode() == QFileDialogOptions::AcceptSave) {
- QStringList ext = [self acceptableExtensionsForSave];
- const QString defaultSuffix = mOptions->defaultSuffix();
- if (!ext.isEmpty() && !defaultSuffix.isEmpty())
- ext.prepend(defaultSuffix);
+ const QStringList ext = [self acceptableExtensionsForSave];
[mSavePanel setAllowedFileTypes:ext.isEmpty() ? nil : qt_mac_QStringListToNSMutableArray(ext)];
} else {
[mOpenPanel setAllowedFileTypes:nil]; // delegate panel:shouldEnableURL: does the file filtering for NSOpenPanel
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index 7a550b163b..b3c2d5ae90 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -44,9 +44,11 @@
#include <QtCore/QtDebug>
#include "qcocoaapplication.h"
+#include "qcocoaintegration.h"
#include "qcocoamenuloader.h"
#include "qcocoamenubar.h"
#include "qcocoawindow.h"
+#include "qcocoascreen.h"
QT_BEGIN_NAMESPACE
@@ -364,8 +366,9 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect,
[popupCell setMenu:m_nativeMenu];
[popupCell selectItem:nsItem];
- int availableHeight = screen->availableSize().height();
- const QPoint &globalPos = parentWindow->mapToGlobal(pos);
+ QCocoaScreen *cocoaScreen = static_cast<QCocoaScreen *>(screen->handle());
+ int availableHeight = cocoaScreen->availableGeometry().height();
+ const QPoint &globalPos = cocoaWindow->mapToGlobal(pos);
int menuHeight = m_nativeMenu.size.height;
if (globalPos.y() + menuHeight > availableHeight) {
// Maybe we need to fix the vertical popup position but we don't know the
diff --git a/src/plugins/platforms/cocoa/qcocoansmenu.mm b/src/plugins/platforms/cocoa/qcocoansmenu.mm
index 996a4ff194..6be2569dbc 100644
--- a/src/plugins/platforms/cocoa/qcocoansmenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoansmenu.mm
@@ -40,6 +40,8 @@
#import "qcocoansmenu.h"
#include "qcocoamenu.h"
#include "qcocoamenuitem.h"
+#include "qcocoamenubar.h"
+#include "qcocoawindow.h"
#import "qnsview.h"
#include <QtCore/qmetaobject.h>
@@ -291,6 +293,19 @@ static NSString *qt_mac_removePrivateUnicode(NSString* string)
return nil;
}
+// Cocoa will query the menu item's target for the worksWhenModal selector.
+// So we need to implement this to allow the items to be handled correctly
+// when a modal dialog is visible.
+- (BOOL)worksWhenModal
+{
+ if (!QGuiApplication::modalWindow())
+ return YES;
+ const auto &qpaMenu = static_cast<QCocoaNSMenu *>(self).qpaMenu;
+ if (auto *mb = qobject_cast<QCocoaMenuBar *>(qpaMenu->menuParent()))
+ return QGuiApplication::modalWindow()->handle() == mb->cocoaWindow() ? YES : NO;
+ return YES;
+}
+
@end
#undef CHECK_MENU_CLASS
diff --git a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
index e756f0aeb0..f4c968ab57 100644
--- a/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
+++ b/src/plugins/platforms/cocoa/qcocoasystemtrayicon.mm
@@ -72,8 +72,6 @@
**
****************************************************************************/
-#define QT_MAC_SYSTEMTRAY_USE_GROWL
-
#include "qcocoasystemtrayicon.h"
#ifndef QT_NO_SYSTEMTRAYICON
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index e4dd71f01b..471a19adb0 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -498,9 +498,10 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
{
const Qt::WindowType type = static_cast<Qt::WindowType>(int(flags & Qt::WindowType_Mask));
const bool frameless = (flags & Qt::FramelessWindowHint) || windowIsPopupType(type);
+ const bool resizeable = type != Qt::Dialog; // Dialogs: remove zoom button by disabling resize
- // Select base window type.
- NSUInteger styleMask = frameless ? NSBorderlessWindowMask : NSResizableWindowMask;
+ // Select base window type. Note that the value of NSBorderlessWindowMask is 0.
+ NSUInteger styleMask = (frameless || !resizeable) ? NSBorderlessWindowMask : NSResizableWindowMask;
if (frameless) {
// No further customizations for frameless since there are no window decorations.
@@ -1151,23 +1152,6 @@ void QCocoaWindow::handleExposeEvent(const QRegion &region)
m_exposedRect = QRect();
}
- QWindowPrivate *windowPrivate = qt_window_private(window());
- if (windowPrivate->updateRequestPending) {
- // We can only deliver update request events when the window is exposed,
- // and we also have to make sure we deliver any change to the exposed
- // rect as a real expose event (including going from non-exposed to
- // exposed). FIXME: Should this logic live in QGuiApplication?
- if (isExposed() && m_exposedRect == previouslyExposedRect) {
- qCDebug(lcQpaCocoaDrawing) << "QCocoaWindow::handleExposeEvent" << window() << region << "as update request";
- windowPrivate->deliverUpdateRequest();
- return;
- } else {
- // Since updateRequestPending is still set, we will issue a deferred setNeedsDisplay
- // from drawRect and get back into this code on the next display cycle, delivering
- // the pending update request.
- }
- }
-
qCDebug(lcQpaCocoaDrawing) << "QCocoaWindow::handleExposeEvent" << window() << region << "isExposed" << isExposed();
QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::SynchronousDelivery>(window(), region);
}
@@ -1342,7 +1326,7 @@ void QCocoaWindow::recreateWindowIfNeeded()
void QCocoaWindow::requestUpdate()
{
qCDebug(lcQpaCocoaDrawing) << "QCocoaWindow::requestUpdate" << window();
- [m_view setNeedsDisplay:YES];
+ [m_view requestUpdate];
}
void QCocoaWindow::requestActivateWindow()
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index f8903725a6..e2ea862cd5 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -81,6 +81,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
NSEvent *m_currentlyInterpretedKeyEvent;
bool m_isMenuView;
QSet<quint32> m_acceptedKeyDowns;
+ bool m_updateRequested;
}
@property (nonatomic, retain) NSCursor *cursor;
@@ -105,6 +106,8 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
- (void)resetMouseButtons;
+- (void)requestUpdate;
+
- (void)handleMouseEvent:(NSEvent *)theEvent;
- (bool)handleMouseDownEvent:(NSEvent *)theEvent withButton:(int)buttonNumber;
- (bool)handleMouseDraggedEvent:(NSEvent *)theEvent withButton:(int)buttonNumber;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index f9c28542a9..fd7f216e10 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -148,6 +148,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
m_isMenuView = false;
self.focusRingType = NSFocusRingTypeNone;
self.cursor = nil;
+ m_updateRequested = false;
}
return self;
}
@@ -300,6 +301,25 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
return m_platformWindow->isOpaque();
}
+- (void)requestUpdate
+{
+ if (self.needsDisplay) {
+ // If the view already has needsDisplay set it means that there may be code waiting for
+ // a real expose event, so we can't issue setNeedsDisplay now as a way to trigger an
+ // update request. We will re-trigger requestUpdate from drawRect.
+ return;
+ }
+
+ [self setNeedsDisplay:YES];
+ m_updateRequested = true;
+}
+
+- (void)setNeedsDisplayInRect:(NSRect)rect
+{
+ [super setNeedsDisplayInRect:rect];
+ m_updateRequested = false;
+}
+
- (void)drawRect:(NSRect)dirtyRect
{
Q_UNUSED(dirtyRect);
@@ -315,7 +335,11 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
exposedRegion += QRectF::fromCGRect(dirtyRects[i]).toRect();
qCDebug(lcQpaCocoaDrawing) << "[QNSView drawRect:]" << m_platformWindow->window() << exposedRegion;
+ [self updateRegion:exposedRegion];
+}
+- (void)updateRegion:(QRegion)dirtyRegion
+{
#ifndef QT_NO_OPENGL
if (m_glContext && m_shouldSetGLContextinDrawRect) {
[m_glContext->nsOpenGLContext() setView:self];
@@ -323,18 +347,24 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
}
#endif
- m_platformWindow->handleExposeEvent(exposedRegion);
+ QWindowPrivate *windowPrivate = qt_window_private(m_platformWindow->window());
+
+ if (m_updateRequested) {
+ Q_ASSERT(windowPrivate->updateRequestPending);
+ qCDebug(lcQpaCocoaWindow) << "Delivering update request to" << m_platformWindow->window();
+ windowPrivate->deliverUpdateRequest();
+ m_updateRequested = false;
+ } else {
+ m_platformWindow->handleExposeEvent(dirtyRegion);
+ }
- if (qt_window_private(m_platformWindow->window())->updateRequestPending) {
- // A call to QWindow::requestUpdate was issued during the expose event, or we
- // had to deliver a real expose event and still need to deliver the update.
- // But AppKit will reset the needsDisplay state of the view after completing
+ if (windowPrivate->updateRequestPending) {
+ // A call to QWindow::requestUpdate was issued during event delivery above,
+ // but AppKit will reset the needsDisplay state of the view after completing
// the current display cycle, so we need to defer the request to redisplay.
// FIXME: Perhaps this should be a trigger to enable CADisplayLink?
qCDebug(lcQpaCocoaDrawing) << "[QNSView drawRect:] issuing deferred setNeedsDisplay due to pending update request";
- dispatch_async(dispatch_get_main_queue (), ^{
- [self setNeedsDisplay:YES];
- });
+ dispatch_async(dispatch_get_main_queue (), ^{ [self requestUpdate]; });
}
}
@@ -351,7 +381,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
qCDebug(lcQpaCocoaDrawing) << "[QNSView updateLayer]" << m_platformWindow->window();
// FIXME: Find out if there's a way to resolve the dirty rect like in drawRect:
- m_platformWindow->handleExposeEvent(QRectF::fromCGRect(self.bounds).toRect());
+ [self updateRegion:QRectF::fromCGRect(self.bounds).toRect()];
}
- (void)viewDidChangeBackingProperties
diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
index f3efbea60b..29cfd4ea79 100644
--- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
@@ -117,7 +117,7 @@ void QEglFSWindow::create()
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
if (screen->primarySurface() != EGL_NO_SURFACE) {
if (Q_UNLIKELY(!isRaster() || !compositor->targetWindow())) {
-#if !defined(Q_OS_ANDROID)
+#if !defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_EMBEDDED)
// We can have either a single OpenGL window or multiple raster windows.
// Other combinations cannot work.
qFatal("EGLFS: OpenGL windows cannot be mixed with others.");
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp
index 88b401c920..475d9d55dd 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.cpp
@@ -141,10 +141,15 @@ void QEglFSKmsVsp2Screen::initDumbFrameBuffers()
void QEglFSKmsVsp2Screen::initVsp2()
{
qCDebug(qLcEglfsKmsDebug, "Initializing Vsp2 hardware");
- const QSize screenSize = rawGeometry().size();
- m_blendDevice.reset(new QVsp2BlendingDevice(screenSize));
+ m_blendDevice.reset(new QVsp2BlendingDevice(rawGeometry().size()));
// Enable input for main buffer drawn by the compositor (always on)
+ initQtLayer();
+}
+
+void QEglFSKmsVsp2Screen::initQtLayer()
+{
+ const QSize screenSize = rawGeometry().size();
const uint bytesPerLine = uint(screenSize.width()) * 4; //TODO: is this ok?
bool formatSet = m_blendDevice->enableInput(m_qtLayer, QRect(QPoint(), screenSize), m_output.drm_format, bytesPerLine);
if (!formatSet) {
@@ -298,8 +303,13 @@ void QEglFSKmsVsp2Screen::blendAndFlipDrm()
vBlank.request.signal = 0;
drmWaitVBlank(driFd, &vBlank);
- if (!m_blendDevice->blend(backBuffer.dmabufFd))
- qWarning() << "Vsp2: blending failed";
+ if (!m_blendDevice->blend(backBuffer.dmabufFd)) {
+ qWarning() << "Vsp2: Blending failed";
+
+ // For some reason, a failed blend may often mess up the qt layer, so reinitialize it here
+ m_blendDevice->disableInput(m_qtLayer);
+ initQtLayer();
+ }
for (auto cb : m_blendFinishedCallbacks)
cb();
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h
index fa03e36785..7618510333 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qeglfskmsvsp2screen.h
@@ -60,6 +60,7 @@ public:
void initDumbFrameBuffers();
void initVsp2();
+ void initQtLayer();
//TODO: use a fixed index API instead of auto increment?
int addLayer(int dmabufFd, const QSize &size, const QPoint &position, uint drmPixelFormat, uint bytesPerLine);
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.cpp
index 879d312341..132806a2e3 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.cpp
@@ -219,11 +219,12 @@ bool QVsp2BlendingDevice::blend(int outputDmabufFd)
if (!m_dirty)
qWarning("Blending without being dirty, should not be necessary");
- if (!m_inputs[0].enabled) {
- qWarning("Vsp2: Can't blend with layer 0 disabled");
+ if (!hasContinuousLayers()) {
+ qWarning("Vsp2: Can't blend when layers are not enabled in order from 0 without gaps.");
return false;
}
+ bool queueingFailed = false;
// Queue dma input buffers
for (int i=0; i < m_inputs.size(); ++i) {
auto &input = m_inputs[i];
@@ -233,12 +234,22 @@ bool QVsp2BlendingDevice::blend(int outputDmabufFd)
<< "with dmabuf" << input.dmabuf.fd
<< "and size" << input.geometry.size();
- if (!disableInput(i))
- qWarning() << "Vsp2: Failed to disable input" << i;
+ queueingFailed = true;
}
}
}
+ if (queueingFailed) {
+ qWarning() << "Vsp2: Trying to clean up queued buffers";
+ for (auto &input : qAsConst(m_inputs)) {
+ if (input.enabled) {
+ if (!input.rpfInput->clearBuffers())
+ qWarning() << "Vsp2: Failed to remove buffers after an aborted blend";
+ }
+ }
+ return false;
+ }
+
if (!m_wpfOutput->queueBuffer(outputDmabufFd, m_screenSize)) {
qWarning() << "Vsp2: Failed to queue blending output buffer" << outputDmabufFd << m_screenSize;
return false;
@@ -270,6 +281,17 @@ int QVsp2BlendingDevice::numInputs() const
return m_inputs.size();
}
+bool QVsp2BlendingDevice::hasContinuousLayers() const
+{
+ bool seenDisabled = false;
+ for (auto &input : qAsConst(m_inputs)) {
+ if (seenDisabled && input.enabled)
+ return false;
+ seenDisabled |= !input.enabled;
+ }
+ return m_inputs[0].enabled;
+}
+
bool QVsp2BlendingDevice::streamOn()
{
for (auto &input : m_inputs) {
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.h
index be48954f47..ee34ae654a 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_vsp2/qvsp2blendingdevice.h
@@ -63,6 +63,7 @@ public:
bool blend(int outputDmabufFd);
int numInputs() const;
bool isDirty() const { return m_dirty; }
+ bool hasContinuousLayers() const;
private:
bool streamOn();
bool streamOff();
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h
index d5af31044d..2028fc2a42 100644
--- a/src/plugins/platforms/ios/qioswindow.h
+++ b/src/plugins/platforms/ios/qioswindow.h
@@ -110,6 +110,10 @@ private:
friend class QIOSScreen;
};
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, const QIOSWindow *window);
+#endif
+
QT_END_NAMESPACE
#endif // QIOSWINDOW_H
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 38136c05db..6ee258e363 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -381,6 +381,19 @@ CAEAGLLayer *QIOSWindow::eaglLayer() const
return static_cast<CAEAGLLayer *>(m_view.layer);
}
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, const QIOSWindow *window)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug << "QIOSWindow(" << (const void *)window;
+ if (window)
+ debug << ", window=" << window->window();
+ debug << ')';
+ return debug;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
#include "moc_qioswindow.cpp"
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index 6960698bf1..584dfe9b41 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -149,6 +149,21 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
[super dealloc];
}
+- (NSString *)description
+{
+ NSMutableString *description = [NSMutableString stringWithString:[super description]];
+
+#ifndef QT_NO_DEBUG_STREAM
+ QString platformWindowDescription;
+ QDebug debug(&platformWindowDescription);
+ debug.nospace() << "; " << m_qioswindow << ">";
+ NSRange lastCharacter = [description rangeOfComposedCharacterSequenceAtIndex:description.length - 1];
+ [description replaceCharactersInRange:lastCharacter withString:platformWindowDescription.toNSString()];
+#endif
+
+ return description;
+}
+
- (void)willMoveToWindow:(UIWindow *)newWindow
{
// UIKIt will normally set the scale factor of a view to match the corresponding
@@ -193,13 +208,12 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
// when the size is also changed.
if (!CGAffineTransformIsIdentity(self.transform))
- qWarning() << m_qioswindow->window()
- << "is backed by a UIView that has a transform set. This is not supported.";
+ qWarning() << self << "has a transform set. This is not supported.";
QWindow *window = m_qioswindow->window();
QRect lastReportedGeometry = qt_window_private(window)->geometry;
QRect currentGeometry = QRectF::fromCGRect(self.frame).toRect();
- qCDebug(lcQpaWindow) << m_qioswindow->window() << "new geometry is" << currentGeometry;
+ qCDebug(lcQpaWindow) << m_qioswindow << "new geometry is" << currentGeometry;
QWindowSystemInterface::handleGeometryChange(window, currentGeometry);
if (currentGeometry.size() != lastReportedGeometry.size()) {
@@ -232,7 +246,7 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
region = QRect(QPoint(), bounds);
}
- qCDebug(lcQpaWindow) << m_qioswindow->window() << region << "isExposed" << m_qioswindow->isExposed();
+ qCDebug(lcQpaWindow) << m_qioswindow << region << "isExposed" << m_qioswindow->isExposed();
QWindowSystemInterface::handleExposeEvent(m_qioswindow->window(), region);
}
@@ -256,16 +270,14 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
// blocked by this guard.
FirstResponderCandidate firstResponderCandidate(self);
- qImDebug() << "win:" << m_qioswindow->window() << "self:" << self
- << "first:" << [UIResponder currentFirstResponder];
+ qImDebug() << "self:" << self << "first:" << [UIResponder currentFirstResponder];
if (![super becomeFirstResponder]) {
- qImDebug() << m_qioswindow->window()
- << "was not allowed to become first responder";
+ qImDebug() << self << "was not allowed to become first responder";
return NO;
}
- qImDebug() << m_qioswindow->window() << "became first responder";
+ qImDebug() << self << "became first responder";
}
if (qGuiApp->focusWindow() != m_qioswindow->window())
@@ -297,13 +309,12 @@ Q_LOGGING_CATEGORY(lcQpaTablet, "qt.qpa.input.tablet")
- (BOOL)resignFirstResponder
{
- qImDebug() << "win:" << m_qioswindow->window() << "self:" << self
- << "first:" << [UIResponder currentFirstResponder];
+ qImDebug() << "self:" << self << "first:" << [UIResponder currentFirstResponder];
if (![super resignFirstResponder])
return NO;
- qImDebug() << m_qioswindow->window() << "resigned first responder";
+ qImDebug() << self << "resigned first responder";
UIResponder *newResponder = FirstResponderCandidate::currentCandidate();
if ([self responderShouldTriggerWindowDeactivation:newResponder])
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
index 6f79cd96d3..f835dbf6d4 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
@@ -59,13 +59,13 @@
#include <QtInputSupport/private/qlibinputhandler_p.h>
#endif
-#if QT_CONFIG(evdev) && !defined(Q_OS_ANDROID)
+#if QT_CONFIG(evdev)
#include <QtInputSupport/private/qevdevmousemanager_p.h>
#include <QtInputSupport/private/qevdevkeyboardmanager_p.h>
#include <QtInputSupport/private/qevdevtouchmanager_p.h>
#endif
-#if QT_CONFIG(tslib) && !defined(Q_OS_ANDROID)
+#if QT_CONFIG(tslib)
#include <QtInputSupport/private/qtslib_p.h>
#endif
@@ -162,7 +162,7 @@ void QLinuxFbIntegration::createInputHandlers()
new QTsLibMouseHandler(QLatin1String("TsLib"), QString());
#endif
-#if QT_CONFIG(evdev) && !defined(Q_OS_ANDROID)
+#if QT_CONFIG(evdev)
new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString(), this);
new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString(), this);
#if QT_CONFIG(tslib)
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index 9ccc2b54b9..e61887618f 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -1,7 +1,7 @@
TEMPLATE = subdirs
QT_FOR_CONFIG += gui-private
-android: SUBDIRS += android
+android:!android-embedded: SUBDIRS += android
!android: SUBDIRS += minimal
@@ -36,7 +36,7 @@ qtConfig(directfb) {
qtConfig(linuxfb): SUBDIRS += linuxfb
-qtConfig(vnc): SUBDIRS += vnc
+qtHaveModule(network):qtConfig(vnc): SUBDIRS += vnc
freebsd {
SUBDIRS += bsdfb
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro
index 15d33200e5..96bfa1dd19 100644
--- a/src/plugins/platforms/qnx/qnx.pro
+++ b/src/plugins/platforms/qnx/qnx.pro
@@ -71,14 +71,14 @@ HEADERS = main.h \
LIBS += -lscreen
-qtConfig(opengles2) {
+qtConfig(egl) {
SOURCES += qqnxglcontext.cpp \
qqnxeglwindow.cpp
HEADERS += qqnxglcontext.h \
qqnxeglwindow.h
- QMAKE_USE += opengl_es2 egl
+ QMAKE_USE += egl
}
qtConfig(qqnx_pps) {
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.cpp b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
index 33ce0f924c..48766fc435 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.cpp
@@ -56,18 +56,12 @@ QT_BEGIN_NAMESPACE
QQnxEglWindow::QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow) :
QQnxWindow(window, context, needRootWindow),
- m_platformOpenGLContext(0),
m_newSurfaceRequested(true),
+ m_eglDisplay(EGL_NO_DISPLAY),
m_eglSurface(EGL_NO_SURFACE)
{
initWindow();
- // Set window usage
- const int val = SCREEN_USAGE_OPENGL_ES2;
- const int result = screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_USAGE, &val);
- if (Q_UNLIKELY(result != 0))
- qFatal("QQnxEglWindow: failed to set window alpha usage, errno=%d", errno);
-
m_requestedBufferSize = shouldMakeFullScreen() ? screen()->geometry().size() : window->geometry().size();
}
@@ -77,14 +71,58 @@ QQnxEglWindow::~QQnxEglWindow()
destroyEGLSurface();
}
-void QQnxEglWindow::createEGLSurface()
+bool QQnxEglWindow::isInitialized() const
{
+ return m_eglSurface != EGL_NO_SURFACE;
+}
+
+void QQnxEglWindow::ensureInitialized(QQnxGLContext* context)
+{
+ if (m_newSurfaceRequested.testAndSetOrdered(true, false)) {
+ const QMutexLocker locker(&m_mutex); // Set geomety must not reset the requestedBufferSize till
+ // the surface is created
+
+ if (m_requestedBufferSize != bufferSize() || m_eglSurface == EGL_NO_SURFACE) {
+ if (m_eglSurface != EGL_NO_SURFACE) {
+ context->doneCurrent();
+ destroyEGLSurface();
+ }
+ createEGLSurface(context);
+ } else {
+ // Must've been a sequence of unprocessed changes returning us to the original size.
+ resetBuffers();
+ }
+ }
+}
+
+void QQnxEglWindow::createEGLSurface(QQnxGLContext *context)
+{
+ if (context->format().renderableType() != QSurfaceFormat::OpenGLES) {
+ qFatal("QQnxEglWindow: renderable type is not OpenGLES");
+ return;
+ }
+
+ // Set window usage
+ int usage = SCREEN_USAGE_OPENGL_ES2;
+#if _SCREEN_VERSION >= _SCREEN_MAKE_VERSION(1, 0, 0)
+ if (context->format().majorVersion() == 3)
+ usage |= SCREEN_USAGE_OPENGL_ES3;
+#endif
+
+ const int result = screen_set_window_property_iv(nativeHandle(), SCREEN_PROPERTY_USAGE, &usage);
+ if (Q_UNLIKELY(result != 0))
+ qFatal("QQnxEglWindow: failed to set window usage, errno=%d", errno);
+
if (!m_requestedBufferSize.isValid()) {
qWarning("QQNX: Trying to create 0 size EGL surface. "
"Please set a valid window size before calling QOpenGLContext::makeCurrent()");
return;
}
+ m_eglDisplay = context->eglDisplay();
+ m_eglConfig = context->eglConfig();
+ m_format = context->format();
+
// update the window's buffers before we create the EGL surface
setBufferSize(m_requestedBufferSize);
@@ -94,24 +132,27 @@ void QQnxEglWindow::createEGLSurface()
EGL_NONE
};
- qEglWindowDebug() << "Creating EGL surface" << platformOpenGLContext()->getEglDisplay()
- << platformOpenGLContext()->getEglConfig();
+ qEglWindowDebug() << "Creating EGL surface from" << this << context
+ << window()->surfaceType() << window()->type();
// Create EGL surface
- m_eglSurface = eglCreateWindowSurface(platformOpenGLContext()->getEglDisplay(),
- platformOpenGLContext()->getEglConfig(),
- (EGLNativeWindowType) nativeHandle(), eglSurfaceAttrs);
- if (m_eglSurface == EGL_NO_SURFACE) {
- const EGLenum error = QQnxGLContext::checkEGLError("eglCreateWindowSurface");
- qWarning("QQNX: failed to create EGL surface, err=%d", error);
- }
+ EGLSurface eglSurface = eglCreateWindowSurface(
+ m_eglDisplay,
+ m_eglConfig,
+ (EGLNativeWindowType) nativeHandle(),
+ eglSurfaceAttrs);
+
+ if (eglSurface == EGL_NO_SURFACE)
+ qWarning("QQNX: failed to create EGL surface, err=%d", eglGetError());
+
+ m_eglSurface = eglSurface;
}
void QQnxEglWindow::destroyEGLSurface()
{
// Destroy EGL surface if it exists
if (m_eglSurface != EGL_NO_SURFACE) {
- EGLBoolean eglResult = eglDestroySurface(platformOpenGLContext()->getEglDisplay(), m_eglSurface);
+ EGLBoolean eglResult = eglDestroySurface(m_eglDisplay, m_eglSurface);
if (Q_UNLIKELY(eglResult != EGL_TRUE))
qFatal("QQNX: failed to destroy EGL surface, err=%d", eglGetError());
}
@@ -119,40 +160,8 @@ void QQnxEglWindow::destroyEGLSurface()
m_eglSurface = EGL_NO_SURFACE;
}
-void QQnxEglWindow::swapEGLBuffers()
+EGLSurface QQnxEglWindow::surface() const
{
- qEglWindowDebug();
- // Set current rendering API
- EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
- if (Q_UNLIKELY(eglResult != EGL_TRUE))
- qFatal("QQNX: failed to set EGL API, err=%d", eglGetError());
-
- // Post EGL surface to window
- eglResult = eglSwapBuffers(m_platformOpenGLContext->getEglDisplay(), m_eglSurface);
- if (Q_UNLIKELY(eglResult != EGL_TRUE))
- qFatal("QQNX: failed to swap EGL buffers, err=%d", eglGetError());
-
- windowPosted();
-}
-
-EGLSurface QQnxEglWindow::getSurface()
-{
- if (m_newSurfaceRequested.testAndSetOrdered(true, false)) {
- const QMutexLocker locker(&m_mutex); //Set geomety must not reset the requestedBufferSize till
- //the surface is created
-
- if ((m_requestedBufferSize != bufferSize()) || (m_eglSurface == EGL_NO_SURFACE)) {
- if (m_eglSurface != EGL_NO_SURFACE) {
- platformOpenGLContext()->doneCurrent();
- destroyEGLSurface();
- }
- createEGLSurface();
- } else {
- // Must've been a sequence of unprocessed changes returning us to the original size.
- resetBuffers();
- }
- }
-
return m_eglSurface;
}
@@ -169,35 +178,24 @@ void QQnxEglWindow::setGeometry(const QRect &rect)
// that test.
const QMutexLocker locker(&m_mutex);
m_requestedBufferSize = newGeometry.size();
- if (m_platformOpenGLContext != 0 && bufferSize() != newGeometry.size())
+ if (isInitialized() && bufferSize() != newGeometry.size())
m_newSurfaceRequested.testAndSetRelease(false, true);
}
QQnxWindow::setGeometry(newGeometry);
}
-void QQnxEglWindow::setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext)
-{
- // This function does not take ownership of the platform gl context.
- // It is owned by the frontend QOpenGLContext
- m_platformOpenGLContext = platformOpenGLContext;
-}
-
int QQnxEglWindow::pixelFormat() const
{
- if (!m_platformOpenGLContext) //The platform GL context was not set yet
- return -1;
-
- const QSurfaceFormat format = m_platformOpenGLContext->format();
// Extract size of color channels from window format
- const int redSize = format.redBufferSize();
+ const int redSize = m_format.redBufferSize();
if (Q_UNLIKELY(redSize == -1))
qFatal("QQnxWindow: red size not defined");
- const int greenSize = format.greenBufferSize();
+ const int greenSize = m_format.greenBufferSize();
if (Q_UNLIKELY(greenSize == -1))
qFatal("QQnxWindow: green size not defined");
- const int blueSize = format.blueBufferSize();
+ const int blueSize = m_format.blueBufferSize();
if (Q_UNLIKELY(blueSize == -1))
qFatal("QQnxWindow: blue size not defined");
diff --git a/src/plugins/platforms/qnx/qqnxeglwindow.h b/src/plugins/platforms/qnx/qqnxeglwindow.h
index 183be11ddc..3a3840f13c 100644
--- a/src/plugins/platforms/qnx/qqnxeglwindow.h
+++ b/src/plugins/platforms/qnx/qqnxeglwindow.h
@@ -53,13 +53,10 @@ public:
QQnxEglWindow(QWindow *window, screen_context_t context, bool needRootWindow);
~QQnxEglWindow();
- void createEGLSurface();
- void destroyEGLSurface();
- void swapEGLBuffers();
- EGLSurface getSurface();
+ EGLSurface surface() const;
- void setPlatformOpenGLContext(QQnxGLContext *platformOpenGLContext);
- QQnxGLContext *platformOpenGLContext() const { return m_platformOpenGLContext; }
+ bool isInitialized() const;
+ void ensureInitialized(QQnxGLContext *context);
void setGeometry(const QRect &rect) override;
@@ -68,6 +65,9 @@ protected:
void resetBuffers() override;
private:
+ void createEGLSurface(QQnxGLContext *context);
+ void destroyEGLSurface();
+
QSize m_requestedBufferSize;
// This mutex is used to protect access to the m_requestedBufferSize
@@ -78,9 +78,11 @@ private:
// QQnxGLContext::makeCurrent()
mutable QMutex m_mutex;
- QQnxGLContext *m_platformOpenGLContext;
QAtomicInt m_newSurfaceRequested;
+ EGLDisplay m_eglDisplay;
+ EGLConfig m_eglConfig;
EGLSurface m_eglSurface;
+ QSurfaceFormat m_format;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.cpp b/src/plugins/platforms/qnx/qqnxglcontext.cpp
index d35a4f0bba..d4493943e2 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.cpp
+++ b/src/plugins/platforms/qnx/qqnxglcontext.cpp
@@ -59,117 +59,13 @@ QT_BEGIN_NAMESPACE
EGLDisplay QQnxGLContext::ms_eglDisplay = EGL_NO_DISPLAY;
-QQnxGLContext::QQnxGLContext(QOpenGLContext *glContext)
- : QPlatformOpenGLContext(),
- m_glContext(glContext),
- m_currentEglSurface(EGL_NO_SURFACE)
+QQnxGLContext::QQnxGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share)
+ : QEGLPlatformContext(format, share, ms_eglDisplay)
{
- qGLContextDebug();
- QSurfaceFormat format = m_glContext->format();
-
- // Set current rendering API
- EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
- if (Q_UNLIKELY(eglResult != EGL_TRUE))
- qFatal("QQNX: failed to set EGL API, err=%d", eglGetError());
-
- // Get colour channel sizes from window format
- int alphaSize = format.alphaBufferSize();
- int redSize = format.redBufferSize();
- int greenSize = format.greenBufferSize();
- int blueSize = format.blueBufferSize();
-
- // Check if all channels are don't care
- if (alphaSize == -1 && redSize == -1 && greenSize == -1 && blueSize == -1) {
- // Set colour channels based on depth of window's screen
- QQnxScreen *screen = static_cast<QQnxScreen*>(glContext->screen()->handle());
- int depth = screen->depth();
- if (depth == 32) {
- // SCREEN_FORMAT_RGBA8888
- alphaSize = 8;
- redSize = 8;
- greenSize = 8;
- blueSize = 8;
- } else {
- // SCREEN_FORMAT_RGB565
- alphaSize = 0;
- redSize = 5;
- greenSize = 6;
- blueSize = 5;
- }
- } else {
- // Choose best match based on supported pixel formats
- if (alphaSize <= 0 && redSize <= 5 && greenSize <= 6 && blueSize <= 5) {
- // SCREEN_FORMAT_RGB565
- alphaSize = 0;
- redSize = 5;
- greenSize = 6;
- blueSize = 5;
- } else {
- // SCREEN_FORMAT_RGBA8888
- alphaSize = 8;
- redSize = 8;
- greenSize = 8;
- blueSize = 8;
- }
- }
-
- // Update colour channel sizes in window format
- format.setAlphaBufferSize(alphaSize);
- format.setRedBufferSize(redSize);
- format.setGreenBufferSize(greenSize);
- format.setBlueBufferSize(blueSize);
-
- // Select EGL config based on requested window format
- m_eglConfig = q_configFromGLFormat(ms_eglDisplay, format);
- if (Q_UNLIKELY(m_eglConfig == 0))
- qFatal("QQnxGLContext: failed to find EGL config");
-
- QQnxGLContext *glShareContext = static_cast<QQnxGLContext*>(m_glContext->shareHandle());
- m_eglShareContext = glShareContext ? glShareContext->m_eglContext : EGL_NO_CONTEXT;
-
- m_eglContext = eglCreateContext(ms_eglDisplay, m_eglConfig, m_eglShareContext,
- contextAttrs(format));
- if (Q_UNLIKELY(m_eglContext == EGL_NO_CONTEXT)) {
- checkEGLError("eglCreateContext");
- qFatal("QQnxGLContext: failed to create EGL context, err=%d", eglGetError());
- }
-
- // Query/cache window format of selected EGL config
- m_windowFormat = q_glFormatFromConfig(ms_eglDisplay, m_eglConfig);
}
QQnxGLContext::~QQnxGLContext()
{
- qGLContextDebug();
-
- // Cleanup EGL context if it exists
- if (m_eglContext != EGL_NO_CONTEXT)
- eglDestroyContext(ms_eglDisplay, m_eglContext);
-}
-
-EGLenum QQnxGLContext::checkEGLError(const char *msg)
-{
- static const char *errmsg[] =
- {
- "EGL function succeeded",
- "EGL is not initialized, or could not be initialized, for the specified display",
- "EGL cannot access a requested resource",
- "EGL failed to allocate resources for the requested operation",
- "EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list",
- "EGLConfig argument does not name a valid EGLConfig",
- "EGLContext argument does not name a valid EGLContext",
- "EGL current surface of the calling thread is no longer valid",
- "EGLDisplay argument does not name a valid EGLDisplay",
- "EGL arguments are inconsistent",
- "EGLNativePixmapType argument does not refer to a valid native pixmap",
- "EGLNativeWindowType argument does not refer to a valid native window",
- "EGL one or more argument values are invalid",
- "EGLSurface argument does not name a valid surface configured for rendering",
- "EGL power management event has occurred",
- };
- EGLenum error = eglGetError();
- fprintf(stderr, "%s: %s\n", msg, errmsg[error - EGL_SUCCESS]);
- return error;
}
void QQnxGLContext::initializeContext()
@@ -178,16 +74,12 @@ void QQnxGLContext::initializeContext()
// Initialize connection to EGL
ms_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (Q_UNLIKELY(ms_eglDisplay == EGL_NO_DISPLAY)) {
- checkEGLError("eglGetDisplay");
- qFatal("QQnxGLContext: failed to obtain EGL display");
- }
+ if (Q_UNLIKELY(ms_eglDisplay == EGL_NO_DISPLAY))
+ qFatal("QQnxGLContext: failed to obtain EGL display: %x", eglGetError());
EGLBoolean eglResult = eglInitialize(ms_eglDisplay, 0, 0);
- if (Q_UNLIKELY(eglResult != EGL_TRUE)) {
- checkEGLError("eglInitialize");
+ if (Q_UNLIKELY(eglResult != EGL_TRUE))
qFatal("QQnxGLContext: failed to initialize EGL display, err=%d", eglGetError());
- }
}
void QQnxGLContext::shutdownContext()
@@ -198,98 +90,32 @@ void QQnxGLContext::shutdownContext()
eglTerminate(ms_eglDisplay);
}
-bool QQnxGLContext::makeCurrent(QPlatformSurface *surface)
+EGLSurface QQnxGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
{
- qGLContextDebug();
-
- Q_ASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
-
- // Set current rendering API
- EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
- if (Q_UNLIKELY(eglResult != EGL_TRUE))
- qFatal("QQnxGLContext: failed to set EGL API, err=%d", eglGetError());
-
- QQnxEglWindow *platformWindow = dynamic_cast<QQnxEglWindow*>(surface);
- if (!platformWindow)
- return false;
-
- platformWindow->setPlatformOpenGLContext(this);
-
- if (m_currentEglSurface == EGL_NO_SURFACE || m_currentEglSurface != platformWindow->getSurface()) {
- m_currentEglSurface = platformWindow->getSurface();
- doneCurrent();
- }
-
- eglResult = eglMakeCurrent(ms_eglDisplay, m_currentEglSurface, m_currentEglSurface, m_eglContext);
- if (eglResult != EGL_TRUE) {
- checkEGLError("eglMakeCurrent");
- qWarning("QQNX: failed to set current EGL context, err=%d", eglGetError());
- return false;
- }
- return (eglResult == EGL_TRUE);
+ QQnxEglWindow *window = static_cast<QQnxEglWindow *>(surface);
+ window->ensureInitialized(this);
+ return window->surface();
}
-void QQnxGLContext::doneCurrent()
+bool QQnxGLContext::makeCurrent(QPlatformSurface *surface)
{
qGLContextDebug();
-
- // set current rendering API
- EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
- if (Q_UNLIKELY(eglResult != EGL_TRUE))
- qFatal("QQNX: failed to set EGL API, err=%d", eglGetError());
-
- // clear curent EGL context and unbind EGL surface
- eglResult = eglMakeCurrent(ms_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if (Q_UNLIKELY(eglResult != EGL_TRUE))
- qFatal("QQNX: failed to clear current EGL context, err=%d", eglGetError());
+ return QEGLPlatformContext::makeCurrent(surface);
}
void QQnxGLContext::swapBuffers(QPlatformSurface *surface)
{
qGLContextDebug();
- QQnxEglWindow *platformWindow = dynamic_cast<QQnxEglWindow*>(surface);
- if (!platformWindow)
- return;
-
- platformWindow->swapEGLBuffers();
-}
-QFunctionPointer QQnxGLContext::getProcAddress(const char *procName)
-{
- qGLContextDebug();
+ QEGLPlatformContext::swapBuffers(surface);
- // Set current rendering API
- EGLBoolean eglResult = eglBindAPI(EGL_OPENGL_ES_API);
- if (Q_UNLIKELY(eglResult != EGL_TRUE))
- qFatal("QQNX: failed to set EGL API, err=%d", eglGetError());
-
- // Lookup EGL extension function pointer
- QFunctionPointer result = static_cast<QFunctionPointer>(eglGetProcAddress(procName));
- if (!result)
- result = reinterpret_cast<QFunctionPointer>(dlsym(RTLD_DEFAULT, procName));
- return result;
-}
-
-bool QQnxGLContext::isSharing() const
-{
- return m_eglShareContext != EGL_NO_CONTEXT;
-}
-
-EGLDisplay QQnxGLContext::getEglDisplay() {
- return ms_eglDisplay;
+ QQnxEglWindow *platformWindow = static_cast<QQnxEglWindow*>(surface);
+ platformWindow->windowPosted();
}
-EGLint *QQnxGLContext::contextAttrs(const QSurfaceFormat &format)
+void QQnxGLContext::doneCurrent()
{
- qGLContextDebug();
-
- // Choose EGL settings based on OpenGL version
-#if defined(QT_OPENGL_ES_2)
- static EGLint attrs[] = { EGL_CONTEXT_CLIENT_VERSION, format.version().first, EGL_NONE };
- return attrs;
-#else
- return 0;
-#endif
+ QEGLPlatformContext::doneCurrent();
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxglcontext.h b/src/plugins/platforms/qnx/qqnxglcontext.h
index 6e5408e8bf..19179a80e2 100644
--- a/src/plugins/platforms/qnx/qqnxglcontext.h
+++ b/src/plugins/platforms/qnx/qqnxglcontext.h
@@ -46,49 +46,31 @@
#include <QtCore/QSize>
#include <EGL/egl.h>
+#include <QtEglSupport/private/qeglplatformcontext_p.h>
QT_BEGIN_NAMESPACE
class QQnxWindow;
-class QQnxGLContext : public QPlatformOpenGLContext
+class QQnxGLContext : public QEGLPlatformContext
{
public:
- QQnxGLContext(QOpenGLContext *glContext);
+ QQnxGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share);
virtual ~QQnxGLContext();
- static EGLenum checkEGLError(const char *msg);
-
static void initializeContext();
static void shutdownContext();
- void requestSurfaceChange();
-
bool makeCurrent(QPlatformSurface *surface) override;
- void doneCurrent() override;
void swapBuffers(QPlatformSurface *surface) override;
- QFunctionPointer getProcAddress(const char *procName) override;
-
- virtual QSurfaceFormat format() const override { return m_windowFormat; }
- bool isSharing() const override;
+ void doneCurrent() override;
- static EGLDisplay getEglDisplay();
- EGLConfig getEglConfig() const { return m_eglConfig;}
- EGLContext getEglContext() const { return m_eglContext; }
+protected:
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) override;
private:
//Can be static because different displays returne the same handle
static EGLDisplay ms_eglDisplay;
-
- QSurfaceFormat m_windowFormat;
- QOpenGLContext *m_glContext;
-
- EGLConfig m_eglConfig;
- EGLContext m_eglContext;
- EGLContext m_eglShareContext;
- EGLSurface m_currentEglSurface;
-
- static EGLint *contextAttrs(const QSurfaceFormat &format);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 072510e052..bffe7ee34b 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -313,7 +313,58 @@ QPlatformBackingStore *QQnxIntegration::createPlatformBackingStore(QWindow *wind
QPlatformOpenGLContext *QQnxIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
qIntegrationDebug();
- return new QQnxGLContext(context);
+
+ // Get color channel sizes from window format
+ QSurfaceFormat format = context->format();
+ int alphaSize = format.alphaBufferSize();
+ int redSize = format.redBufferSize();
+ int greenSize = format.greenBufferSize();
+ int blueSize = format.blueBufferSize();
+
+ // Check if all channels are don't care
+ if (alphaSize == -1 && redSize == -1 && greenSize == -1 && blueSize == -1) {
+ // Set color channels based on depth of window's screen
+ QQnxScreen *screen = static_cast<QQnxScreen*>(context->screen()->handle());
+ int depth = screen->depth();
+ if (depth == 32) {
+ // SCREEN_FORMAT_RGBA8888
+ alphaSize = 8;
+ redSize = 8;
+ greenSize = 8;
+ blueSize = 8;
+ } else {
+ // SCREEN_FORMAT_RGB565
+ alphaSize = 0;
+ redSize = 5;
+ greenSize = 6;
+ blueSize = 5;
+ }
+ } else {
+ // Choose best match based on supported pixel formats
+ if (alphaSize <= 0 && redSize <= 5 && greenSize <= 6 && blueSize <= 5) {
+ // SCREEN_FORMAT_RGB565
+ alphaSize = 0;
+ redSize = 5;
+ greenSize = 6;
+ blueSize = 5;
+ } else {
+ // SCREEN_FORMAT_RGBA8888
+ alphaSize = 8;
+ redSize = 8;
+ greenSize = 8;
+ blueSize = 8;
+ }
+ }
+
+ // Update color channel sizes in window format
+ format.setAlphaBufferSize(alphaSize);
+ format.setRedBufferSize(redSize);
+ format.setGreenBufferSize(greenSize);
+ format.setBlueBufferSize(blueSize);
+ context->setFormat(format);
+
+ QQnxGLContext *ctx = new QQnxGLContext(context->format(), context->shareHandle());
+ return ctx;
}
#endif
diff --git a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
index 468fe9cd91..3eebb9c742 100644
--- a/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
+++ b/src/plugins/platforms/qnx/qqnxnativeinterface.cpp
@@ -98,7 +98,7 @@ void *QQnxNativeInterface::nativeResourceForIntegration(const QByteArray &resour
void *QQnxNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
{
if (resource == "eglcontext" && context)
- return static_cast<QQnxGLContext*>(context->handle())->getEglContext();
+ return static_cast<QQnxGLContext*>(context->handle())->eglContext();
return 0;
}
diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h
index 8a498434aa..a6d5623d04 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.h
+++ b/src/plugins/platforms/qnx/qqnxscreen.h
@@ -49,10 +49,14 @@
#include <screen/screen.h>
-// For pre-7.0 SDPs, map some screen property names to the old
+#if !defined(_SCREEN_VERSION)
+#define _SCREEN_MAKE_VERSION(major, minor, patch) (((major) * 10000) + ((minor) * 100) + (patch))
+#define _SCREEN_VERSION _SCREEN_MAKE_VERSION(0, 0, 0)
+#endif
+
+// For pre-1.0.0 screen, map some screen property names to the old
// names.
-#include <sys/neutrino.h>
-#if _NTO_VERSION < 700
+#if _SCREEN_VERSION < _SCREEN_MAKE_VERSION(1, 0, 0)
const int SCREEN_PROPERTY_FLAGS = SCREEN_PROPERTY_KEY_FLAGS;
const int SCREEN_PROPERTY_FOCUS = SCREEN_PROPERTY_KEYBOARD_FOCUS;
const int SCREEN_PROPERTY_MODIFIERS = SCREEN_PROPERTY_KEY_MODIFIERS;
diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h
index dfcca78f80..2895a547b1 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.h
+++ b/src/plugins/platforms/qnx/qqnxwindow.h
@@ -112,12 +112,13 @@ public:
bool shouldMakeFullScreen() const;
+ void windowPosted();
+
protected:
virtual int pixelFormat() const = 0;
virtual void resetBuffers() = 0;
void initWindow();
- void windowPosted();
screen_context_t m_screenContext;
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index c146f8ec25..3d0dbd7b1a 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -980,8 +980,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::QuerySizeHints:
d->m_creationContext->applyToMinMaxInfo(reinterpret_cast<MINMAXINFO *>(lParam));
return true;
- case QtWindows::ResizeEvent:
- d->m_creationContext->obtainedGeometry.setSize(QSize(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+ case QtWindows::ResizeEvent: {
+ const QSize size(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) - d->m_creationContext->menuHeight);
+ d->m_creationContext->obtainedGeometry.setSize(size);
+ }
return true;
case QtWindows::MoveEvent:
d->m_creationContext->obtainedGeometry.moveTo(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 70ee708b61..80ee7b2287 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -68,7 +68,6 @@
#include <QtCore/QMutex>
#include <QtCore/QMutexLocker>
#include <QtCore/QUuid>
-#include <QtCore/QRegularExpression>
#include <QtCore/QTemporaryFile>
#include <QtCore/private/qsystemlibrary_p.h>
@@ -1135,12 +1134,32 @@ void QWindowsNativeFileDialogBase::setLabelText(QFileDialogOptions::DialogLabel
}
}
+static bool isHexRange(const QString& s, int start, int end)
+{
+ for (;start < end; ++start) {
+ QChar ch = s.at(start);
+ if (!(ch.isDigit()
+ || (ch >= QLatin1Char('a') && ch <= QLatin1Char('f'))
+ || (ch >= QLatin1Char('A') && ch <= QLatin1Char('F'))))
+ return false;
+ }
+ return true;
+}
+
static inline bool isClsid(const QString &s)
{
// detect "374DE290-123F-4565-9164-39C4925E467B".
- static const QRegularExpression pattern(QLatin1String("\\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}\\z"));
- Q_ASSERT(pattern.isValid());
- return pattern.match(s).hasMatch();
+ const QChar dash(QLatin1Char('-'));
+ return s.size() == 36
+ && isHexRange(s, 0, 8)
+ && s.at(8) == dash
+ && isHexRange(s, 9, 13)
+ && s.at(13) == dash
+ && isHexRange(s, 14, 18)
+ && s.at(18) == dash
+ && isHexRange(s, 19, 23)
+ && s.at(23) == dash
+ && isHexRange(s, 24, 36);
}
void QWindowsNativeFileDialogBase::selectFile(const QString &fileName) const
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index ada124b5af..159e1250d0 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1034,8 +1034,10 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
const QMargins effectiveMargins = margins + customMargins;
frameWidth = effectiveMargins.left() + geometry.width() + effectiveMargins.right();
frameHeight = effectiveMargins.top() + geometry.height() + effectiveMargins.bottom();
- if (QWindowsMenuBar::menuBarOf(w) != nullptr)
- frameHeight += GetSystemMetrics(SM_CYMENU);
+ if (QWindowsMenuBar::menuBarOf(w) != nullptr) {
+ menuHeight = GetSystemMetrics(SM_CYMENU);
+ frameHeight += menuHeight;
+ }
const bool isDefaultPosition = !frameX && !frameY && w->isTopLevel();
if (!QWindowsGeometryHint::positionIncludesFrame(w) && !isDefaultPosition) {
frameX -= effectiveMargins.left();
@@ -2558,7 +2560,7 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins)
newFrame.moveTo(topLeft);
qCDebug(lcQpaWindows) << __FUNCTION__ << oldCustomMargins << "->" << newCustomMargins
<< currentFrameGeometry << "->" << newFrame;
- SetWindowPos(m_data.hwnd, 0, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED);
+ SetWindowPos(m_data.hwnd, 0, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE);
}
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 3732255738..8d29b871bf 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -101,6 +101,7 @@ struct QWindowCreationContext
int frameY = CW_USEDEFAULT;
int frameWidth = CW_USEDEFAULT;
int frameHeight = CW_USEDEFAULT;
+ int menuHeight = 0;
};
struct QWindowsWindowData
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
index 56a737e882..21024385b0 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp
@@ -134,7 +134,11 @@ static void updateFormatFromContext(QSurfaceFormat &format)
}
format.setProfile(QSurfaceFormat::NoProfile);
+ const bool isStereo = format.testOption(QSurfaceFormat::StereoBuffers);
format.setOptions(QSurfaceFormat::FormatOptions());
+ // Restore flags that come from the VisualInfo/FBConfig.
+ if (isStereo)
+ format.setOption(QSurfaceFormat::StereoBuffers);
if (format.renderableType() == QSurfaceFormat::OpenGL) {
if (format.version() < qMakePair(3, 0)) {
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index 1cf45c96d1..eae0ee7613 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -48,9 +48,11 @@
#include <sys/ipc.h>
#include <sys/shm.h>
+#include <sys/mman.h>
#include <stdio.h>
#include <errno.h>
+#include <unistd.h>
#include <qdebug.h>
#include <qpainter.h>
@@ -61,6 +63,11 @@
#include <qendian.h>
#include <algorithm>
+
+#if (XCB_SHM_MAJOR_VERSION == 1 && XCB_SHM_MINOR_VERSION >= 2) || XCB_SHM_MAJOR_VERSION > 1
+#define XCB_USE_SHM_FD
+#endif
+
QT_BEGIN_NAMESPACE
class QXcbShmImage : public QXcbObject
@@ -85,6 +92,9 @@ public:
void preparePaint(const QRegion &region);
private:
+ void createShmSegment(size_t segmentSize);
+ void destroyShmSegment(size_t segmentSize);
+
void destroy();
void ensureGC(xcb_drawable_t dst);
@@ -154,6 +164,11 @@ private:
QImage *m_image;
};
+static inline size_t imageDataSize(const xcb_image_t *image)
+{
+ return static_cast<size_t>(image->stride) * image->height;
+}
+
QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QImage::Format format)
: QXcbObject(screen->connection())
, m_graphics_buffer(nullptr)
@@ -173,39 +188,13 @@ QXcbShmImage::QXcbShmImage(QXcbScreen *screen, const QSize &size, uint depth, QI
XCB_IMAGE_ORDER_MSB_FIRST,
0, ~0, 0);
- const int segmentSize = m_xcb_image->stride * m_xcb_image->height;
+ const size_t segmentSize = imageDataSize(m_xcb_image);
if (!segmentSize)
return;
- int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0600);
- if (id == -1) {
- qWarning("QXcbShmImage: shmget() failed (%d: %s) for size %d (%dx%d)",
- errno, strerror(errno), segmentSize, size.width(), size.height());
- } else {
- m_shm_info.shmaddr = m_xcb_image->data = (quint8 *)shmat(id, 0, 0);
- }
- m_shm_info.shmid = id;
- m_shm_info.shmseg = xcb_generate_id(xcb_connection());
-
- const xcb_query_extension_reply_t *shm_reply = xcb_get_extension_data(xcb_connection(), &xcb_shm_id);
- bool shm_present = shm_reply != NULL && shm_reply->present;
- xcb_generic_error_t *error = NULL;
- if (shm_present)
- error = xcb_request_check(xcb_connection(), xcb_shm_attach_checked(xcb_connection(), m_shm_info.shmseg, m_shm_info.shmid, false));
- if (!shm_present || error || id == -1) {
- free(error);
-
- if (id != -1) {
- shmdt(m_shm_info.shmaddr);
- shmctl(m_shm_info.shmid, IPC_RMID, 0);
- }
- m_shm_info.shmaddr = 0;
+ createShmSegment(segmentSize);
- m_xcb_image->data = (uint8_t *)malloc(segmentSize);
- } else {
- if (shmctl(m_shm_info.shmid, IPC_RMID, 0) == -1)
- qWarning("QXcbBackingStore: Error while marking the shared memory segment to be destroyed");
- }
+ m_xcb_image->data = m_shm_info.shmaddr ? m_shm_info.shmaddr : (uint8_t *)malloc(segmentSize);
m_hasAlpha = QImage::toPixelFormat(format).alphaUsage() == QPixelFormat::UsesAlpha;
if (!m_hasAlpha)
@@ -270,6 +259,111 @@ void QXcbShmImage::flushScrolledRegion(bool clientSideScroll)
}
}
+void QXcbShmImage::createShmSegment(size_t segmentSize)
+{
+ m_shm_info.shmaddr = nullptr;
+
+ if (!connection()->hasShm())
+ return;
+
+#ifdef XCB_USE_SHM_FD
+ if (connection()->hasShmFd()) {
+ if (Q_UNLIKELY(segmentSize > std::numeric_limits<uint32_t>::max())) {
+ qWarning("QXcbShmImage: xcb_shm_create_segment() can't be called for size %zu, maximum allowed size is %u",
+ segmentSize, std::numeric_limits<uint32_t>::max());
+ return;
+ }
+ const auto seg = xcb_generate_id(xcb_connection());
+ auto reply = Q_XCB_REPLY(xcb_shm_create_segment,
+ xcb_connection(), seg, segmentSize, false);
+ if (!reply) {
+ qWarning("QXcbShmImage: xcb_shm_create_segment() failed for size %zu", segmentSize);
+ return;
+ }
+
+ int *fds = xcb_shm_create_segment_reply_fds(xcb_connection(), reply.get());
+ if (reply->nfd != 1) {
+ for (int i = 0; i < reply->nfd; i++)
+ close(fds[i]);
+
+ qWarning("QXcbShmImage: failed to get file descriptor for shm segment of size %zu", segmentSize);
+ return;
+ }
+
+ void *addr = mmap(nullptr, segmentSize, PROT_READ|PROT_WRITE, MAP_SHARED, fds[0], 0);
+ if (addr == MAP_FAILED) {
+ qWarning("QXcbShmImage: failed to mmap segment from X server (%d: %s) for size %zu",
+ errno, strerror(errno), segmentSize);
+ close(fds[0]);
+ xcb_shm_detach(xcb_connection(), seg);
+ return;
+ }
+
+ close(fds[0]);
+ m_shm_info.shmseg = seg;
+ m_shm_info.shmaddr = static_cast<quint8 *>(addr);
+ } else
+#endif
+ {
+ const int id = shmget(IPC_PRIVATE, segmentSize, IPC_CREAT | 0600);
+ if (id == -1) {
+ qWarning("QXcbShmImage: shmget() failed (%d: %s) for size %zu",
+ errno, strerror(errno), segmentSize);
+ return;
+ }
+
+ void *addr = shmat(id, 0, 0);
+ if (addr == (void *)-1) {
+ qWarning("QXcbShmImage: shmat() failed (%d: %s) for id %d",
+ errno, strerror(errno), id);
+ return;
+ }
+
+ if (shmctl(id, IPC_RMID, 0) == -1)
+ qWarning("QXcbBackingStore: Error while marking the shared memory segment to be destroyed");
+
+ const auto seg = xcb_generate_id(xcb_connection());
+ auto cookie = xcb_shm_attach_checked(xcb_connection(), seg, id, false);
+ auto *error = xcb_request_check(xcb_connection(), cookie);
+ if (error) {
+ connection()->printXcbError("QXcbShmImage: xcb_shm_attach() failed with error", error);
+ free(error);
+ if (shmdt(addr) == -1) {
+ qWarning("QXcbShmImage: shmdt() failed (%d: %s) for %p",
+ errno, strerror(errno), addr);
+ }
+ return;
+ }
+
+ m_shm_info.shmseg = seg;
+ m_shm_info.shmid = id; // unused
+ m_shm_info.shmaddr = static_cast<quint8 *>(addr);
+ }
+}
+
+void QXcbShmImage::destroyShmSegment(size_t segmentSize)
+{
+ auto cookie = xcb_shm_detach_checked(xcb_connection(), m_shm_info.shmseg);
+ xcb_generic_error_t *error = xcb_request_check(xcb_connection(), cookie);
+ if (error)
+ connection()->printXcbError("QXcbShmImage: xcb_shm_detach() failed with error", error);
+
+#ifdef XCB_USE_SHM_FD
+ if (connection()->hasShmFd()) {
+ if (munmap(m_shm_info.shmaddr, segmentSize) == -1) {
+ qWarning("QXcbShmImage: munmap() failed (%d: %s) for %p with size %zu",
+ errno, strerror(errno), m_shm_info.shmaddr, segmentSize);
+ }
+ } else
+#endif
+ {
+ if (shmdt(m_shm_info.shmaddr) == -1) {
+ qWarning("QXcbShmImage: shmdt() failed (%d: %s) for %p",
+ errno, strerror(errno), m_shm_info.shmaddr);
+ }
+ }
+}
+
extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
bool QXcbShmImage::scroll(const QRegion &area, int dx, int dy)
@@ -318,17 +412,11 @@ bool QXcbShmImage::scroll(const QRegion &area, int dx, int dy)
void QXcbShmImage::destroy()
{
- const int segmentSize = m_xcb_image ? (m_xcb_image->stride * m_xcb_image->height) : 0;
- if (segmentSize && m_shm_info.shmaddr)
- xcb_shm_detach(xcb_connection(), m_shm_info.shmseg);
-
- if (segmentSize) {
- if (m_shm_info.shmaddr) {
- shmdt(m_shm_info.shmaddr);
- shmctl(m_shm_info.shmid, IPC_RMID, 0);
- } else {
+ if (m_xcb_image->data) {
+ if (m_shm_info.shmaddr)
+ destroyShmSegment(imageDataSize(m_xcb_image));
+ else
free(m_xcb_image->data);
- }
}
xcb_image_destroy(m_xcb_image);
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index d6013541fc..ee25d6a12f 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -582,6 +582,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
initializeAllAtoms();
+ initializeShm();
if (!qEnvironmentVariableIsSet("QT_XCB_NO_XRANDR"))
initializeXRandr();
if (!has_randr_extension)
@@ -961,14 +962,20 @@ void QXcbConnection::handleXcbError(xcb_generic_error_t *error)
if (dispatcher && dispatcher->filterNativeEvent(m_nativeInterface->genericEventFilterType(), error, &result))
return;
+ printXcbError("QXcbConnection: XCB error", error);
+}
+
+void QXcbConnection::printXcbError(const char *message, xcb_generic_error_t *error)
+{
uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
- qWarning("QXcbConnection: XCB error: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
- int(error->error_code), xcb_errors[clamped_error_code],
- int(error->sequence), int(error->resource_id),
- int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
- int(error->minor_code));
+ qWarning("%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
+ message,
+ int(error->error_code), xcb_errors[clamped_error_code],
+ int(error->sequence), int(error->resource_id),
+ int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
+ int(error->minor_code));
}
static Qt::MouseButtons translateMouseButtons(int s)
@@ -2084,6 +2091,26 @@ void QXcbConnection::sync()
free(xcb_get_input_focus_reply(xcb_connection(), cookie, 0));
}
+void QXcbConnection::initializeShm()
+{
+ const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_shm_id);
+ if (!reply || !reply->present) {
+ qWarning("QXcbConnection: MIT-SHM extension is not present on the X server.");
+ return;
+ }
+
+ has_shm = true;
+
+ auto shm_query = Q_XCB_REPLY(xcb_shm_query_version, m_connection);
+ if (!shm_query) {
+ qWarning("QXcbConnection: Failed to request MIT-SHM version");
+ return;
+ }
+
+ has_shm_fd = (shm_query->major_version == 1 && shm_query->minor_version >= 2) ||
+ shm_query->major_version > 1;
+}
+
void QXcbConnection::initializeXFixes()
{
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xfixes_id);
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 2e06292f78..0a7f878ed8 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -438,6 +438,7 @@ public:
void sync();
void handleXcbError(xcb_generic_error_t *error);
+ void printXcbError(const char *message, xcb_generic_error_t *error);
void handleXcbEvent(xcb_generic_event_t *event);
void printXcbEvent(const QLoggingCategory &log, const char *message,
xcb_generic_event_t *event) const;
@@ -475,6 +476,8 @@ public:
bool hasXKB() const { return has_xkb; }
bool hasXRender() const { return has_render_extension; }
bool hasXInput2() const { return m_xi2Enabled; }
+ bool hasShm() const { return has_shm; }
+ bool hasShmFd() const { return has_shm_fd; }
bool threadedEventHandling() const { return m_reader->isRunning(); }
@@ -542,6 +545,7 @@ private slots:
private:
void initializeAllAtoms();
void sendConnectionEvent(QXcbAtom::Atom atom, uint id = 0);
+ void initializeShm();
void initializeXFixes();
void initializeXRender();
void initializeXRandr();
@@ -696,6 +700,8 @@ private:
bool has_input_shape;
bool has_xkb = false;
bool has_render_extension = false;
+ bool has_shm = false;
+ bool has_shm_fd = false;
Qt::MouseButtons m_buttonState = 0;
Qt::MouseButton m_button = Qt::NoButton;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 5b05a230e4..e9a6e536a7 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -2071,7 +2071,7 @@ bool QXcbWindow::isEmbedded() const
QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const
{
if (!m_embedded)
- return pos;
+ return QPlatformWindow::mapToGlobal(pos);
QPoint ret;
auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(),
@@ -2088,7 +2088,7 @@ QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const
QPoint QXcbWindow::mapFromGlobal(const QPoint &pos) const
{
if (!m_embedded)
- return pos;
+ return QPlatformWindow::mapFromGlobal(pos);
QPoint ret;
auto reply = Q_XCB_REPLY(xcb_translate_coordinates, xcb_connection(),
@@ -2857,7 +2857,7 @@ QString QXcbWindow::windowTitle(const QXcbConnection *conn, xcb_window_t window)
utf8Atom, 0, 1024);
if (reply && reply->format == 8 && reply->type == utf8Atom) {
const char *name = reinterpret_cast<const char *>(xcb_get_property_value(reply.get()));
- return QString::fromUtf8(name);
+ return QString::fromUtf8(name, xcb_get_property_value_length(reply.get()));
}
return QString();
}
diff --git a/src/plugins/platformthemes/gtk3/qgtk3menu.cpp b/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
index 0b67739095..ec4ff68e8d 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
@@ -41,6 +41,7 @@
#include <QtGui/qwindow.h>
#include <QtGui/qpa/qplatformtheme.h>
+#include <QtGui/qpa/qplatformwindow.h>
#undef signals
#include <gtk/gtk.h>
@@ -426,9 +427,11 @@ void QGtk3Menu::showPopup(const QWindow *parentWindow, const QRect &targetRect,
if (index != -1)
gtk_menu_set_active(GTK_MENU(m_menu), index);
- m_targetPos = targetRect.bottomLeft();
- if (parentWindow)
- m_targetPos = parentWindow->mapToGlobal(m_targetPos);
+ m_targetPos = QPoint(targetRect.x(), targetRect.y() + targetRect.height());
+
+ QPlatformWindow *pw = parentWindow ? parentWindow->handle() : nullptr;
+ if (pw)
+ m_targetPos = pw->mapToGlobal(m_targetPos);
gtk_menu_popup(GTK_MENU(m_menu), NULL, NULL, qt_gtk_menu_position_func, this, 0, gtk_get_current_event_time());
}
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
index 6447776f25..077955eb4e 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
@@ -153,7 +153,7 @@ bool QGtk3Theme::usePlatformNativeDialog(DialogType type) const
case ColorDialog:
return true;
case FileDialog:
- return true;
+ return useNativeFileDialog();
case FontDialog:
return true;
default:
@@ -167,6 +167,8 @@ QPlatformDialogHelper *QGtk3Theme::createPlatformDialogHelper(DialogType type) c
case ColorDialog:
return new QGtk3ColorDialogHelper;
case FileDialog:
+ if (!useNativeFileDialog())
+ return nullptr;
return new QGtk3FileDialogHelper;
case FontDialog:
return new QGtk3FontDialogHelper;
@@ -185,4 +187,17 @@ QPlatformMenuItem* QGtk3Theme::createPlatformMenuItem() const
return new QGtk3MenuItem;
}
+bool QGtk3Theme::useNativeFileDialog()
+{
+ /* Require GTK3 >= 3.15.5 to avoid running into this bug:
+ * https://bugzilla.gnome.org/show_bug.cgi?id=725164
+ *
+ * While this bug only occurs when using widget-based file dialogs
+ * (native GTK3 dialogs are fine) we have to disable platform file
+ * dialogs entirely since we can't avoid creation of a platform
+ * dialog helper.
+ */
+ return gtk_check_version(3, 15, 5) == 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.h b/src/plugins/platformthemes/gtk3/qgtk3theme.h
index 8f03b84bb6..54296d2ff1 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.h
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.h
@@ -59,6 +59,8 @@ public:
QPlatformMenuItem* createPlatformMenuItem() const override;
static const char *name;
+private:
+ static bool useNativeFileDialog();
};
QT_END_NAMESPACE
diff --git a/src/plugins/styles/mac/qmacstyle_mac.mm b/src/plugins/styles/mac/qmacstyle_mac.mm
index df2b637630..9e8af78a8e 100644
--- a/src/plugins/styles/mac/qmacstyle_mac.mm
+++ b/src/plugins/styles/mac/qmacstyle_mac.mm
@@ -3348,13 +3348,12 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
}
break;
case PE_IndicatorMenuCheckMark: {
- if (!(opt->state & State_On))
- break;
QColor pc;
- if (opt->state & State_Selected)
+ if (opt->state & State_On)
pc = opt->palette.highlightedText().color();
else
pc = opt->palette.text().color();
+
QCFType<CGColorRef> checkmarkColor = CGColorCreateGenericRGB(static_cast<CGFloat>(pc.redF()),
static_cast<CGFloat>(pc.greenF()),
static_cast<CGFloat>(pc.blueF()),
@@ -4273,8 +4272,7 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
const int xp = mi->rect.x() + macItemFrame;
checkmarkOpt.rect = QRect(xp, mi->rect.y() - checkmarkOpt.fontMetrics.descent(), mw, mh);
- checkmarkOpt.state |= State_On; // Always on. Never rendered when off.
- checkmarkOpt.state.setFlag(State_Selected, active);
+ checkmarkOpt.state.setFlag(State_On, active);
checkmarkOpt.state.setFlag(State_Enabled, enabled);
if (widgetSize == QStyleHelper::SizeMini)
checkmarkOpt.state |= State_Mini;
diff --git a/src/printsupport/doc/src/qtprintsupport-index.qdoc b/src/printsupport/doc/src/qtprintsupport-index.qdoc
index 7ac448f66f..a8a0f0cb20 100644
--- a/src/printsupport/doc/src/qtprintsupport-index.qdoc
+++ b/src/printsupport/doc/src/qtprintsupport-index.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -165,6 +165,19 @@
QTextEdit requires a QPrinter rather than a QPainter because it uses information
about the configured page dimensions in order to insert page breaks at the most
appropriate places in printed documents.
+
+ \section1 Licenses and Trademarks
+
+ The Qt Print Support module is available under commercial licenses from \l{The Qt Company}.
+ In addition, it is available under free software licenses. Since Qt 5.4,
+ these free software licenses are
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt Licensing} for further details.
+
+ Please note that Adobe\reg places restrictions on the use of its trademarks
+ (including logos) in conjunction with PDF; e.g. "Adobe PDF". Please refer
+ to \l{http://www.adobe.com}{www.adobe.com} for guidelines.
*/
/*!
diff --git a/src/sql/doc/src/qtsql.qdoc b/src/sql/doc/src/qtsql.qdoc
index 56d714becf..f0d74739b0 100644
--- a/src/sql/doc/src/qtsql.qdoc
+++ b/src/sql/doc/src/qtsql.qdoc
@@ -54,12 +54,13 @@
\section1 Licenses and Attributions
Qt SQL is available under commercial licenses from \l{The Qt Company}.
- In addition, it is available under the
+ In addition, it is available under free software licenses. Since Qt 5.4,
+ these free software licenses are
\l{GNU Lesser General Public License, version 3}, or
the \l{GNU General Public License, version 2}.
See \l{Qt Licensing} for further details.
- Furthermore Qt SQL potentially contains third party
+ Furthermore, Qt SQL in Qt \QtVersion may contain third party
modules under following permissive licenses:
\generatelist{groupsbymodule attributions-qtsql}
diff --git a/src/sql/sql.pro b/src/sql/sql.pro
index 133bf831c8..821ae1c9b9 100644
--- a/src/sql/sql.pro
+++ b/src/sql/sql.pro
@@ -2,7 +2,7 @@ TARGET = QtSql
QT = core-private
DEFINES += QT_NO_USING_NAMESPACE
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x62000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x62000000
QMAKE_DOCS = $$PWD/doc/qtsql.qdocconf
diff --git a/src/src.pro b/src/src.pro
index 3b93b1a9d8..1f7c5d99c1 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -210,9 +210,11 @@ qtConfig(gui) {
src_plugins.depends += src_gui src_platformsupport src_platformheaders
src_testlib.depends += src_gui # if QtGui is enabled, QtTest requires QtGui's headers
qtConfig(widgets) {
- SUBDIRS += src_tools_uic src_widgets src_printsupport
+ SUBDIRS += src_tools_uic src_widgets
+ !android-embedded: SUBDIRS += src_printsupport
TOOLS += src_tools_uic
- src_plugins.depends += src_widgets src_printsupport
+ src_plugins.depends += src_widgets
+ !android-embedded: src_plugins.depends += src_printsupport
src_testlib.depends += src_widgets # if QtWidgets is enabled, QtTest requires QtWidgets's headers
qtConfig(opengl) {
SUBDIRS += src_opengl
@@ -224,7 +226,7 @@ SUBDIRS += src_plugins
nacl: SUBDIRS -= src_network src_testlib
-android: SUBDIRS += src_android src_3rdparty_gradle
+android:!android-embedded: SUBDIRS += src_android src_3rdparty_gradle
TR_EXCLUDE = \
src_tools_bootstrap src_tools_moc src_tools_rcc src_tools_uic src_tools_qlalr \
diff --git a/src/testlib/doc/src/qttest-index.qdoc b/src/testlib/doc/src/qttest-index.qdoc
index 7b3e96f72e..b3c2be7375 100644
--- a/src/testlib/doc/src/qttest-index.qdoc
+++ b/src/testlib/doc/src/qttest-index.qdoc
@@ -55,12 +55,13 @@
\section1 Licenses and Attributions
Qt Test is available under commercial licenses from \l{The Qt Company}.
- In addition, it is available under the
+ In addition, it is available under free software licenses. Since Qt 5.4,
+ these free software licenses are
\l{GNU Lesser General Public License, version 3}, or
the \l{GNU General Public License, version 2}.
See \l{Qt Licensing} for further details.
- Furthermore Qt Test potentially contains third party
+ Furthermore, Qt Test in Qt \QtVersion may contain third party
modules under following permissive licenses:
\generatelist{groupsbymodule attributions-qttestlib}
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 4cda5f34ad..3d91bdef34 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -2830,7 +2830,10 @@ void QFileDialogPrivate::init(const QUrl &directory, const QString &nameFilter,
if (!nameFilter.isEmpty())
q->setNameFilter(nameFilter);
q->setDirectoryUrl(workingDirectory(directory));
- q->selectFile(initialSelection(directory));
+ if (directory.isLocalFile())
+ q->selectFile(initialSelection(directory));
+ else
+ q->selectUrl(directory);
#ifndef QT_NO_SETTINGS
// Try to restore from the FileDialog settings group; if it fails, fall back
diff --git a/src/widgets/doc/src/qtwidgets-index.qdoc b/src/widgets/doc/src/qtwidgets-index.qdoc
index 7cd1c8d735..1a23d172dd 100644
--- a/src/widgets/doc/src/qtwidgets-index.qdoc
+++ b/src/widgets/doc/src/qtwidgets-index.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -128,6 +128,15 @@ interfaces
\image graphicsview-items.png
+ \section1 Licenses
+
+ The Qt Widgets module is available under commercial licenses from \l{The Qt Company}.
+ In addition, it is available under free software licenses. Since Qt 5.4,
+ these free software licenses are
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt Licensing} for further details.
+
\section1 Related Information
\section2 Tutorials
diff --git a/src/widgets/graphicsview/qgraphicsview.cpp b/src/widgets/graphicsview/qgraphicsview.cpp
index 1cc8543fdd..0c847b899e 100644
--- a/src/widgets/graphicsview/qgraphicsview.cpp
+++ b/src/widgets/graphicsview/qgraphicsview.cpp
@@ -313,13 +313,15 @@ void QGraphicsViewPrivate::translateTouchEvent(QGraphicsViewPrivate *d, QTouchEv
QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
for (int i = 0; i < touchPoints.count(); ++i) {
QTouchEvent::TouchPoint &touchPoint = touchPoints[i];
+ const QSizeF ellipseDiameters = touchPoint.ellipseDiameters();
// the scene will set the item local pos, startPos, lastPos, and rect before delivering to
// an item, but for now those functions are returning the view's local coordinates
- touchPoint.setSceneRect(d->mapToScene(touchPoint.rect()));
+ touchPoint.setScenePos(d->mapToScene(touchPoint.pos()));
touchPoint.setStartScenePos(d->mapToScene(touchPoint.startPos()));
touchPoint.setLastScenePos(d->mapToScene(touchPoint.lastPos()));
+ touchPoint.setEllipseDiameters(ellipseDiameters);
- // screenPos, startScreenPos, lastScreenPos, and screenRect are already set
+ // screenPos, startScreenPos, and lastScreenPos are already set
}
touchEvent->setTouchPoints(touchPoints);
diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp
index 3268fda2fc..117de8edf9 100644
--- a/src/widgets/itemviews/qabstractitemdelegate.cpp
+++ b/src/widgets/itemviews/qabstractitemdelegate.cpp
@@ -526,7 +526,15 @@ bool QAbstractItemDelegatePrivate::editorEventFilter(QObject *object, QEvent *ev
if (tryFixup(editor))
emit q->commitData(editor);
+ // If the application loses focus while editing, then the focus needs to go back
+ // to the itemview when the editor closes. This ensures that when the application
+ // is active again it will have the focus on the itemview as expected.
+ const bool manuallyFixFocus = (event->type() == QEvent::FocusOut) && !editor->hasFocus() &&
+ editor->parentWidget() &&
+ (static_cast<QFocusEvent *>(event)->reason() == Qt::ActiveWindowFocusReason);
emit q->closeEditor(editor, QAbstractItemDelegate::NoHint);
+ if (manuallyFixFocus)
+ editor->parentWidget()->setFocus();
}
#ifndef QT_NO_SHORTCUT
} else if (event->type() == QEvent::ShortcutOverride) {
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 585cfddff5..c90a61d4ff 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -351,7 +351,7 @@ void QHeaderView::setModel(QAbstractItemModel *model)
if (model == this->model())
return;
Q_D(QHeaderView);
- d->persistentHiddenSections.clear();
+ d->layoutChangePersistentSections.clear();
if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
if (d->orientation == Qt::Horizontal) {
QObject::disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
@@ -2160,14 +2160,28 @@ void QHeaderViewPrivate::_q_sectionsAboutToBeChanged()
|| model->columnCount(root) == 0)
return;
- if (hiddenSectionSize.count() == 0)
- return;
+ layoutChangePersistentSections.clear();
+ layoutChangePersistentSections.reserve(std::min(10, sectionItems.count()));
+ // after layoutChanged another section can be last stretched section
+ if (stretchLastSection) {
+ const int visual = visualIndex(lastSectionLogicalIdx);
+ sectionItems[visual].size = lastSectionSize;
+ }
+ for (int i = 0; i < sectionItems.size(); ++i) {
+ const auto &s = sectionItems.at(i);
+ // only add if the section is not default and not visually moved
+ if (s.size == defaultSectionSize && !s.isHidden && s.resizeMode == globalResizeMode)
+ continue;
- for (int i = 0; i < sectionItems.count(); ++i)
- if (isVisualIndexHidden(i)) // ### note that we are using column or row 0
- persistentHiddenSections.append(orientation == Qt::Horizontal
- ? model->index(0, logicalIndex(i), root)
- : model->index(logicalIndex(i), 0, root));
+ // ### note that we are using column or row 0
+ layoutChangePersistentSections.append({orientation == Qt::Horizontal
+ ? model->index(0, logicalIndex(i), root)
+ : model->index(logicalIndex(i), 0, root),
+ s});
+
+ if (layoutChangePersistentSections.size() > 1000)
+ break;
+ }
}
void QHeaderViewPrivate::_q_sectionsChanged()
@@ -2175,25 +2189,57 @@ void QHeaderViewPrivate::_q_sectionsChanged()
Q_Q(QHeaderView);
viewport->update();
- const auto hiddenSections = persistentHiddenSections;
- persistentHiddenSections.clear();
-
- clear();
- q->initializeSections();
- invalidateCachedSizeHint();
+ const auto oldPersistentSections = layoutChangePersistentSections;
+ layoutChangePersistentSections.clear();
- if (modelIsEmpty()) {
+ const int newCount = modelSectionCount();
+ const int oldCount = sectionItems.size();
+ if (newCount == 0) {
+ clear();
+ if (oldCount != 0)
+ emit q->sectionCountChanged(oldCount, 0);
return;
}
- for (const auto &index : hiddenSections) {
- if (index.isValid()) {
- const int logical = (orientation == Qt::Horizontal
- ? index.column()
- : index.row());
- q->setSectionHidden(logical, true);
+ // adjust section size
+ if (newCount != oldCount) {
+ const int min = qBound(0, oldCount, newCount - 1);
+ q->initializeSections(min, newCount - 1);
+ }
+ // reset sections
+ sectionItems.fill(SectionItem(defaultSectionSize, globalResizeMode), newCount);
+
+ // all hidden sections are in oldPersistentSections
+ hiddenSectionSize.clear();
+
+ for (const auto &item : oldPersistentSections) {
+ const auto &index = item.index;
+ if (!index.isValid())
+ continue;
+
+ const int newLogicalIndex = (orientation == Qt::Horizontal
+ ? index.column()
+ : index.row());
+ // the new visualIndices are already adjusted / reset by initializeSections()
+ const int newVisualIndex = visualIndex(newLogicalIndex);
+ auto &newSection = sectionItems[newVisualIndex];
+ newSection = item.section;
+
+ if (newSection.isHidden) {
+ // otherwise setSectionHidden will return without doing anything
+ newSection.isHidden = false;
+ q->setSectionHidden(newLogicalIndex, true);
}
}
+
+ recalcSectionStartPos();
+ length = headerLength();
+
+ if (stretchLastSection) {
+ // force rebuild of stretched section later on
+ lastSectionLogicalIdx = -1;
+ maybeRestorePrevLastSectionAndStretchLast();
+ }
}
/*!
diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h
index d844274618..24dc3bf075 100644
--- a/src/widgets/itemviews/qheaderview_p.h
+++ b/src/widgets/itemviews/qheaderview_p.h
@@ -231,10 +231,6 @@ public:
: model->rowCount(root));
}
- inline bool modelIsEmpty() const {
- return (model->rowCount(root) == 0 || model->columnCount(root) == 0);
- }
-
inline void doDelayedResizeSections() {
if (!delayedResize.isActive())
delayedResize.start(0, q_func());
@@ -300,7 +296,6 @@ public:
QLabel *sectionIndicator;
#endif
QHeaderView::ResizeMode globalResizeMode;
- QList<QPersistentModelIndex> persistentHiddenSections;
mutable bool sectionStartposRecalc;
int resizeContentsPrecision;
// header sections
@@ -331,6 +326,11 @@ public:
};
QVector<SectionItem> sectionItems;
+ struct LayoutChangeItem {
+ QPersistentModelIndex index;
+ SectionItem section;
+ };
+ QVector<LayoutChangeItem> layoutChangePersistentSections;
void createSectionItems(int start, int end, int size, QHeaderView::ResizeMode mode);
void removeSectionsFromSectionItems(int start, int end);
@@ -384,6 +384,7 @@ public:
};
Q_DECLARE_TYPEINFO(QHeaderViewPrivate::SectionItem, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(QHeaderViewPrivate::LayoutChangeItem, Q_MOVABLE_TYPE);
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 9b7797993c..ebeefad682 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -987,7 +987,7 @@ void QTreeView::setTreePosition(int index)
{
Q_D(QTreeView);
d->treePosition = index;
- update();
+ d->viewport->update();
}
/*!
diff --git a/src/widgets/kernel/qaction.cpp b/src/widgets/kernel/qaction.cpp
index 967b0b8dde..8c8217bb75 100644
--- a/src/widgets/kernel/qaction.cpp
+++ b/src/widgets/kernel/qaction.cpp
@@ -1332,9 +1332,8 @@ bool QAction::isShortcutVisibleInContextMenu() const
{
Q_D(const QAction);
if (d->shortcutVisibleInContextMenu == -1) {
- if (QApplication::instance()->testAttribute(Qt::AA_DontShowIconsInMenus))
- return false;
- return qApp->styleHints()->showShortcutsInContextMenus();
+ return !QCoreApplication::testAttribute(Qt::AA_DontShowShortcutsInContextMenus)
+ && QGuiApplication::styleHints()->showShortcutsInContextMenus();
}
return d->shortcutVisibleInContextMenu;
}
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 9e4910ebd0..b855e32f2d 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -2847,7 +2847,7 @@ void QApplication::setStartDragDistance(int l)
and the current position (e.g. in the mouse move event) is \c currentPos,
you can find out if a drag should be started with code like this:
- \snippet code/src_gui_kernel_qapplication.cpp 6
+ \snippet code/src_gui_kernel_qapplication.cpp 7
Qt uses this value internally, e.g. in QFileDialog.
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index bc5062e942..74f2dc0c41 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1482,7 +1482,8 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO
if (q->windowType() != Qt::Desktop || q->testAttribute(Qt::WA_NativeWindow)) {
win->create();
// Enable nonclient-area events for QDockWidget and other NonClientArea-mouse event processing.
- win->handle()->setFrameStrutEventsEnabled(true);
+ if (QPlatformWindow *platformWindow = win->handle())
+ platformWindow->setFrameStrutEventsEnabled(true);
}
data.window_flags = win->flags();
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index 26f651906a..6873ca876e 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -763,7 +763,7 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
painter->drawRect(rect);
QColor checkMarkColor = option->palette.text().color().darker(120);
- const int checkMarkPadding = 1 + rect.width() * 0.2; // at least one pixel padding
+ const qreal checkMarkPadding = 1 + rect.width() * 0.13; // at least one pixel padding
if (checkbox->state & State_NoChange) {
gradient = QLinearGradient(rect.topLeft(), rect.bottomLeft());
@@ -776,21 +776,22 @@ void QFusionStyle::drawPrimitive(PrimitiveElement elem,
painter->setBrush(gradient);
painter->drawRect(rect.adjusted(checkMarkPadding, checkMarkPadding, -checkMarkPadding, -checkMarkPadding));
- } else if (checkbox->state & (State_On)) {
- qreal penWidth = QStyleHelper::dpiScaled(1.8);
- penWidth = qMax(penWidth , 0.18 * rect.height());
- penWidth = qMin(penWidth , 0.30 * rect.height());
+ } else if (checkbox->state & State_On) {
+ qreal penWidth = QStyleHelper::dpiScaled(1.5);
+ penWidth = qMax(penWidth , 0.13 * rect.height());
+ penWidth = qMin(penWidth , 0.20 * rect.height());
QPen checkPen = QPen(checkMarkColor, penWidth);
checkMarkColor.setAlpha(210);
- painter->translate(-0.8, 0.5);
+ painter->translate(dpiScaled(-0.8), dpiScaled(0.5));
painter->setPen(checkPen);
painter->setBrush(Qt::NoBrush);
// Draw checkmark
QPainterPath path;
- path.moveTo(1.33 * checkMarkPadding, rect.height() / 2.0);
- path.lineTo(rect.width() / 2.0, rect.height() - checkMarkPadding);
- path.lineTo(rect.width() - checkMarkPadding * 0.92, checkMarkPadding);
+ const qreal rectHeight = rect.height(); // assuming height equals width
+ path.moveTo(checkMarkPadding + rectHeight * 0.11, rectHeight * 0.47);
+ path.lineTo(rectHeight * 0.5, rectHeight - checkMarkPadding);
+ path.lineTo(rectHeight - checkMarkPadding, checkMarkPadding);
painter->drawPath(path.translated(rect.topLeft()));
}
}
@@ -1561,8 +1562,8 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
bool ignoreCheckMark = false;
const int checkColHOffset = windowsItemHMargin + windowsItemFrame - 1;
- int checkcol = qMax(menuItem->rect.height() * 0.7,
- qMax(menuItem->maxIconWidth * 1.0, dpiScaled(17))); // icon checkbox's highlihgt column width
+ int checkcol = qMax(menuItem->rect.height() * 0.79,
+ qMax(menuItem->maxIconWidth * 1.0, dpiScaled(21))); // icon checkbox's highlihgt column width
if (
#if QT_CONFIG(combobox)
qobject_cast<const QComboBox*>(widget) ||
@@ -1571,10 +1572,12 @@ void QFusionStyle::drawControl(ControlElement element, const QStyleOption *optio
ignoreCheckMark = true; //ignore the checkmarks provided by the QComboMenuDelegate
if (!ignoreCheckMark) {
- // Check
- const int boxMargin = dpiScaled(4);
- const int boxWidth = checkcol - 2 * boxMargin;
- QRect checkRect(option->rect.left() + boxMargin + checkColHOffset, option->rect.center().y() - boxWidth/2 + 1, boxWidth, boxWidth);
+ // Check, using qreal and QRectF to avoid error accumulation
+ const qreal boxMargin = dpiScaled(3.5);
+ const qreal boxWidth = checkcol - 2 * boxMargin;
+ QRectF checkRectF(option->rect.left() + boxMargin + checkColHOffset, option->rect.center().y() - boxWidth/2 + 1, boxWidth, boxWidth);
+ QRect checkRect = checkRectF.toRect();
+ checkRect.setWidth(checkRect.height()); // avoid .toRect() round error results in non-perfect square
checkRect = visualRect(menuItem->direction, menuItem->rect, checkRect);
if (checkable) {
if (menuItem->checkType & QStyleOptionMenuItem::Exclusive) {
diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp
index 373699a7aa..8679d96eda 100644
--- a/src/widgets/styles/qstylehelper.cpp
+++ b/src/widgets/styles/qstylehelper.cpp
@@ -411,14 +411,6 @@ QWindow *styleObjectWindow(QObject *so)
return 0;
}
-void setWidgetSizePolicy(const QWidget *widget, WidgetSizePolicy policy)
-{
- QWidget *wadget = const_cast<QWidget *>(widget);
- wadget->setAttribute(Qt::WA_MacNormalSize, policy == SizeLarge);
- wadget->setAttribute(Qt::WA_MacSmallSize, policy == SizeSmall);
- wadget->setAttribute(Qt::WA_MacMiniSize, policy == SizeMini);
-}
-
WidgetSizePolicy widgetSizePolicy(const QWidget *widget, const QStyleOption *opt)
{
while (widget) {
diff --git a/src/widgets/styles/qstylehelper_p.h b/src/widgets/styles/qstylehelper_p.h
index bd263cea7b..260860bf4d 100644
--- a/src/widgets/styles/qstylehelper_p.h
+++ b/src/widgets/styles/qstylehelper_p.h
@@ -94,7 +94,6 @@ namespace QStyleHelper
enum WidgetSizePolicy { SizeLarge = 0, SizeSmall = 1, SizeMini = 2, SizeDefault = -1 };
- void setWidgetSizePolicy(const QWidget *w, WidgetSizePolicy policy);
Q_WIDGETS_EXPORT WidgetSizePolicy widgetSizePolicy(const QWidget *w, const QStyleOption *opt = 0);
}
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index 9ce1a04d86..e12aeb900b 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -3968,10 +3968,11 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
x += reverse ? -chunkWidth : chunkWidth;
--chunkCount;
};
- } else {
+ } else if (chunkWidth > 0) {
+ const int chunkCount = ceil(qreal(fillWidth)/chunkWidth);
int x = reverse ? r.left() + r.width() - chunkWidth : r.x();
- for (int i = 0; i < ceil(qreal(fillWidth)/chunkWidth); ++i) {
+ for (int i = 0; i < chunkCount; ++i) {
r.setRect(x, rect.y(), chunkWidth, rect.height());
r = m.mapRect(QRectF(r)).toRect();
subRule.drawRule(p, r);
diff --git a/src/widgets/util/qsystemtrayicon.cpp b/src/widgets/util/qsystemtrayicon.cpp
index 447c7b2aeb..86c824afdb 100644
--- a/src/widgets/util/qsystemtrayicon.cpp
+++ b/src/widgets/util/qsystemtrayicon.cpp
@@ -111,9 +111,7 @@ static QIcon messageIcon2qIcon(QSystemTrayIcon::MessageIcon icon)
\li All X11 desktop environments that implement the D-Bus
\l{http://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem}
specification, including recent versions of KDE and Unity.
- \li All supported versions of \macos. Note that the Growl
- notification system must be installed for
- QSystemTrayIcon::showMessage() to display messages on \macos prior to 10.8 (Mountain Lion).
+ \li All supported versions of \macos.
\endlist
To check whether a system tray is present on the user's desktop,
@@ -420,9 +418,6 @@ bool QSystemTrayIcon::supportsMessages()
On Windows, the \a millisecondsTimeoutHint is usually ignored by the system
when the application has focus.
- On \macos, the Growl notification system must be installed for this function to
- display messages.
-
Has been turned into a slot in Qt 5.2.
\sa show(), supportsMessages()
diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro
index 27d7fe9874..e028a691c8 100644
--- a/src/widgets/widgets.pro
+++ b/src/widgets/widgets.pro
@@ -4,7 +4,7 @@ MODULE_CONFIG = uic
CONFIG += $$MODULE_CONFIG
DEFINES += QT_NO_USING_NAMESPACE
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x65000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x65000000
QMAKE_DOCS = $$PWD/doc/qtwidgets.qdocconf
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 7d4498af5b..e70d096e04 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -67,6 +67,7 @@
#include <qabstractproxymodel.h>
#include <qstylehints.h>
#include <private/qguiapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
#include <private/qapplication_p.h>
#include <private/qcombobox_p.h>
#include <private/qabstractitemmodel_p.h>
@@ -2582,7 +2583,8 @@ bool QComboBoxPrivate::showNativePopup()
else if (q->testAttribute(Qt::WA_MacMiniSize))
offset = QPoint(-2, 6);
- m_platformMenu->showPopup(tlw, QRect(tlw->mapFromGlobal(q->mapToGlobal(offset)), QSize()), currentItem);
+ const QRect targetRect = QRect(tlw->mapFromGlobal(q->mapToGlobal(offset)), QSize());
+ m_platformMenu->showPopup(tlw, QHighDpi::toNativePixels(targetRect, tlw), currentItem);
#ifdef Q_OS_OSX
// The Cocoa popup will swallow any mouse release event.
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index e3b348f0ef..bdeef7cdf7 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -80,9 +80,8 @@
#include "private/qapplication_p.h"
#include "private/qshortcutmap_p.h"
#include "qkeysequence.h"
-#define ACCEL_KEY(k) ((qApp->testAttribute(Qt::AA_DontShowIconsInMenus) \
- ? false \
- : qApp->styleHints()->showShortcutsInContextMenus()) \
+#define ACCEL_KEY(k) ((!QCoreApplication::testAttribute(Qt::AA_DontShowIconsInMenus) \
+ && QGuiApplication::styleHints()->showShortcutsInContextMenus()) \
&& !qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? \
QLatin1Char('\t') + QKeySequence(k).toString(QKeySequence::NativeText) : QString())
#else
diff --git a/src/widgets/widgets/qtoolbarextension.cpp b/src/widgets/widgets/qtoolbarextension.cpp
index 47cf16e0cc..bbe7eddaa4 100644
--- a/src/widgets/widgets/qtoolbarextension.cpp
+++ b/src/widgets/widgets/qtoolbarextension.cpp
@@ -38,7 +38,7 @@
****************************************************************************/
#include "qtoolbarextension_p.h"
-#include <qpixmap.h>
+#include <qevent.h>
#include <qstyle.h>
#include <qstylepainter.h>
#include <qstyleoption.h>
@@ -47,10 +47,11 @@ QT_BEGIN_NAMESPACE
QToolBarExtension::QToolBarExtension(QWidget *parent)
: QToolButton(parent)
+ , m_orientation(Qt::Horizontal)
{
setObjectName(QLatin1String("qt_toolbar_ext_button"));
setAutoRaise(true);
- setOrientation(Qt::Horizontal);
+ setOrientation(m_orientation);
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
setCheckable(true);
}
@@ -63,7 +64,8 @@ void QToolBarExtension::setOrientation(Qt::Orientation o)
setIcon(style()->standardIcon(QStyle::SP_ToolBarHorizontalExtensionButton, &opt));
} else {
setIcon(style()->standardIcon(QStyle::SP_ToolBarVerticalExtensionButton, &opt));
- }
+ }
+ m_orientation = o;
}
void QToolBarExtension::paintEvent(QPaintEvent *)
@@ -83,6 +85,18 @@ QSize QToolBarExtension::sizeHint() const
return QSize(ext, ext);
}
+bool QToolBarExtension::event(QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::LayoutDirectionChange:
+ setOrientation(m_orientation);
+ break;
+ default:
+ break;
+ }
+ return QToolButton::event(event);
+}
+
QT_END_NAMESPACE
#include "moc_qtoolbarextension_p.cpp"
diff --git a/src/widgets/widgets/qtoolbarextension_p.h b/src/widgets/widgets/qtoolbarextension_p.h
index a388f1e40f..146e0e58c1 100644
--- a/src/widgets/widgets/qtoolbarextension_p.h
+++ b/src/widgets/widgets/qtoolbarextension_p.h
@@ -69,6 +69,12 @@ public:
public Q_SLOTS:
void setOrientation(Qt::Orientation o);
+
+protected:
+ bool event(QEvent *e) override;
+
+private:
+ Qt::Orientation m_orientation;
};
QT_END_NAMESPACE
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index 93158dcdba..d3203e180b 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -93,9 +93,8 @@
#include "private/qapplication_p.h"
#include "private/qshortcutmap_p.h"
#include <qkeysequence.h>
-#define ACCEL_KEY(k) ((qApp->testAttribute(Qt::AA_DontShowIconsInMenus) \
- ? false \
- : qApp->styleHints()->showShortcutsInContextMenus()) \
+#define ACCEL_KEY(k) ((!QCoreApplication::testAttribute(Qt::AA_DontShowShortcutsInContextMenus) \
+ && QGuiApplication::styleHints()->showShortcutsInContextMenus()) \
&& !qApp->d_func()->shortcutMap.hasShortcutForKeySequence(k) ? \
QLatin1Char('\t') + QKeySequence(k).toString(QKeySequence::NativeText) : QString())
diff --git a/src/xml/doc/src/qtxml-index.qdoc b/src/xml/doc/src/qtxml-index.qdoc
index eb35903756..91f2515d60 100644
--- a/src/xml/doc/src/qtxml-index.qdoc
+++ b/src/xml/doc/src/qtxml-index.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -45,4 +45,13 @@
The \l{Qt XML C++ Classes} page gives an overview over the available classes
in this module.
+
+ \section1 Licenses
+
+ The Qt XML module is available under commercial licenses from \l{The Qt Company}.
+ In addition, it is available under free software licenses. Since Qt 5.4,
+ these free software licenses are
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt Licensing} for further details.
*/
diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp
index b781176e13..168e8c3cb4 100644
--- a/src/xml/sax/qxml.cpp
+++ b/src/xml/sax/qxml.cpp
@@ -1270,18 +1270,8 @@ void QXmlInputSource::fetchData()
} else if (device->isOpen() || device->open(QIODevice::ReadOnly)) {
rawData.resize(BufferSize);
qint64 size = device->read(rawData.data(), BufferSize);
-
- if (size != -1) {
- // We don't want to give fromRawData() less than four bytes if we can avoid it.
- while (size < 4) {
- if (!device->waitForReadyRead(-1))
- break;
- int ret = device->read(rawData.data() + size, BufferSize - size);
- if (ret <= 0)
- break;
- size += ret;
- }
- }
+ if (size == 0 && device->waitForReadyRead(-1))
+ size = device->read(rawData.data(), BufferSize);
rawData.resize(qMax(qint64(0), size));
}
diff --git a/src/xml/xml.pro b/src/xml/xml.pro
index cf9feda9bc..31d742d6ea 100644
--- a/src/xml/xml.pro
+++ b/src/xml/xml.pro
@@ -3,7 +3,7 @@ QT = core-private
DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
-win32-msvc*|win32-icc:QMAKE_LFLAGS += /BASE:0x61000000
+msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x61000000
QMAKE_DOCS = $$PWD/doc/qtxml.qdocconf