Merge remote-tracking branch 'origin/5.8.0' into 5.8
Conflicts: doc/global/qt-cpp-defines.qdocconf src/plugins/platforms/android/qandroidplatformopenglcontext.h src/plugins/platforms/android/qandroidplatformtheme.h Change-Id: I13d51cc66f708138ff4d667ceea7d515992e58a4
This commit is contained in:
commit
9bfe3ab71e
@ -81,6 +81,34 @@
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-version-control.html
|
||||
\title Qt Creator: Using Version Control Systems
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-vcs-bazaar.html
|
||||
\title Qt Creator: Using Bazaar
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-vcs-clearcase.html
|
||||
\title Qt Creator: Using ClearCase
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-vcs-cvs.html
|
||||
\title Qt Creator: Using CVS
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-vcs-git.html
|
||||
\title Qt Creator: Using Git
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-vcs-mercurial.html
|
||||
\title Qt Creator: Using Mercurial
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-vcs-perforce.html
|
||||
\title Qt Creator: Using Perforce
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-vcs-subversion.html
|
||||
\title Qt Creator: Using Subversion
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-keyboard-shortcuts.html
|
||||
\title Qt Creator: Keyboard Shortcuts
|
||||
|
@ -33,7 +33,6 @@ manifestmeta.filters = highlighted android thumbnail ios
|
||||
manifestmeta.highlighted.names = "QtQuick/Qt Quick Demo - Same Game" \
|
||||
"QtQuick/Qt Quick Demo - Photo Surface" \
|
||||
"QtQuick/Qt Quick Demo - Tweet Search" \
|
||||
"QtQuick/Qt Quick Demo - Maroon*" \
|
||||
"QtQuick/Qt Quick Demo - Calqlatr" \
|
||||
"QtQuick/Qt Quick Demo - StocQt" \
|
||||
"QtQuick/Qt Quick Demo - Clocks" \
|
||||
@ -45,14 +44,12 @@ manifestmeta.highlighted.names = "QtQuick/Qt Quick Demo - Same Game" \
|
||||
"QtQuickDialogs/Qt Quick System Dialog Examples" \
|
||||
"QtWinExtras/Quick Player" \
|
||||
"QtMultimedia/QML Video Shader Effects Example" \
|
||||
"QtCanvas3D/Planets Example" \
|
||||
"QtCanvas3D/Interactive Mobile Phone Example" \
|
||||
"QtLocation/Map Viewer (QML)"
|
||||
|
||||
manifestmeta.highlighted.attributes = isHighlighted:true
|
||||
|
||||
manifestmeta.android.names = "QtQuick/Qt Quick Demo - Maroon*" \
|
||||
"QtQuick/Qt Quick Demo - Calqlatr" \
|
||||
manifestmeta.android.names = "QtQuick/Qt Quick Demo - Calqlatr" \
|
||||
"QtWidgets/Application Chooser Example" \
|
||||
"QtWidgets/Stickman Example" \
|
||||
"QtWidgets/Move Blocks Example" \
|
||||
|
@ -14,12 +14,14 @@ defines += Q_QDOC \
|
||||
Q_NO_USING_KEYWORD \
|
||||
__cplusplus \
|
||||
Q_COMPILER_INITIALIZER_LISTS \
|
||||
Q_COMPILER_UNICODE_STRINGS \
|
||||
Q_COMPILER_UNIFORM_INIT \
|
||||
Q_COMPILER_RVALUE_REFS
|
||||
|
||||
Cpp.ignoretokens += \
|
||||
ENGINIOCLIENT_EXPORT \
|
||||
PHONON_EXPORT \
|
||||
Q_ALWAYS_INLINE \
|
||||
Q_AUTOTEST_EXPORT \
|
||||
Q_BLUETOOTH_EXPORT \
|
||||
Q_COMPAT_EXPORT \
|
||||
@ -121,6 +123,7 @@ Cpp.ignoretokens += \
|
||||
QT_END_NAMESPACE \
|
||||
QT_FASTCALL \
|
||||
QT_MUTEX_LOCK_NOEXCEPT \
|
||||
QT_WARNING_DISABLE_DEPRECATED \
|
||||
QT_WARNING_PUSH \
|
||||
QT_WARNING_POP \
|
||||
QT_WIDGET_PLUGIN_EXPORT \
|
||||
@ -152,6 +155,7 @@ Cpp.ignoredirectives += \
|
||||
Q_FLAG \
|
||||
Q_FLAGS \
|
||||
Q_FLAG_NS \
|
||||
QT_HAS_INCLUDE \
|
||||
Q_INTERFACES \
|
||||
Q_PRIVATE_PROPERTY \
|
||||
QT_FORWARD_DECLARE_CLASS \
|
||||
|
@ -49,7 +49,9 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtWidgets>
|
||||
#if defined(QT_PRINTSUPPORT_LIB)
|
||||
#include <QPrintPreviewDialog>
|
||||
#endif
|
||||
|
||||
#include "mainwindow.h"
|
||||
|
||||
@ -210,7 +212,7 @@ QMap<QString, StyleItems> MainWindow::currentPageMap()
|
||||
return pageMap;
|
||||
}
|
||||
|
||||
#if !defined(QT_NO_PRINTER) && !defined(QT_NO_PRINTDIALOG)
|
||||
#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog)
|
||||
void MainWindow::on_printAction_triggered()
|
||||
{
|
||||
pageMap = currentPageMap();
|
||||
@ -342,4 +344,4 @@ void MainWindow::printPage(int index, QPainter *painter, QPrinter *printer)
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
#endif // QT_NO_PRINTER
|
||||
#endif
|
||||
|
@ -55,6 +55,9 @@
|
||||
#include <QPrinter>
|
||||
#include <QPrintDialog>
|
||||
|
||||
#if defined(QT_PRINTSUPPORT_LIB)
|
||||
#include <QtPrintSupport/qtprintsupportglobal.h>
|
||||
#endif
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QPrinter;
|
||||
class QTextEdit;
|
||||
@ -74,12 +77,11 @@ public:
|
||||
public slots:
|
||||
void on_clearAction_triggered();
|
||||
void on_markAction_triggered();
|
||||
#if !defined(QT_NO_PRINTER) && !defined(QT_NO_PRINTDIALOG)
|
||||
void on_unmarkAction_triggered();
|
||||
|
||||
#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog)
|
||||
void on_printAction_triggered();
|
||||
void on_printPreviewAction_triggered();
|
||||
#endif
|
||||
void on_unmarkAction_triggered();
|
||||
#if !defined(QT_NO_PRINTER) && !defined(QT_NO_PRINTDIALOG)
|
||||
void printDocument(QPrinter *printer);
|
||||
void printPage(int index, QPainter *painter, QPrinter *printer);
|
||||
#endif
|
||||
|
@ -28,12 +28,13 @@ win32:count(MOC_INCLUDEPATH, 40, >) {
|
||||
# UIKit builds are always multi-arch due to simulator_and_device (unless
|
||||
# -sdk is used) so this feature cannot possibly work.
|
||||
if(gcc|intel_icl|msvc):!rim_qcc:!uikit {
|
||||
moc_predefs.name = "Generate moc_predefs.h"
|
||||
moc_predefs.CONFIG = no_link
|
||||
gcc: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -dM -E -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
|
||||
else:intel_icl: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -QdM -P -Fi${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
|
||||
else:intel_icl: moc_predefs.commands = $$QMAKE_CXX $$QMAKE_CXXFLAGS -QdM -P -Za -Fi${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
|
||||
else:msvc {
|
||||
moc_predefs.commands += $$QMAKE_CXX -Bx$$shell_quote($$shell_path($$QMAKE_QMAKE)) $$QMAKE_CXXFLAGS \
|
||||
-E ${QMAKE_FILE_IN} 2>NUL >${QMAKE_FILE_OUT}
|
||||
-E -Za ${QMAKE_FILE_IN} 2>NUL >${QMAKE_FILE_OUT}
|
||||
} else: error("Oops, I messed up")
|
||||
moc_predefs.output = $$MOC_DIR/moc_predefs.h
|
||||
moc_predefs.input = MOC_PREDEF_FILE
|
||||
|
@ -25,7 +25,7 @@ for (s, QLALRSOURCES) {
|
||||
$${base}.variable_out = GENERATED_SOURCES
|
||||
$${base}.depends += $$QMAKE_QLALR_EXE
|
||||
$${base}.commands = $$QMAKE_QLALR $$QMAKE_QLALRFLAGS ${QMAKE_FILE_IN}
|
||||
silent: $${base}.commands = @echo qlalr ${QMAKE_FILE_IN} && $${base}.commands
|
||||
silent: $${base}.commands = @echo qlalr ${QMAKE_FILE_IN} && $$eval($${base}.commands)
|
||||
$${base}.name = QLALR ${QMAKE_FILE_IN}
|
||||
|
||||
$${base}_h.input = $$invar
|
||||
|
@ -14,7 +14,7 @@ QMAKE_YACCFLAGS = -d
|
||||
QMAKE_CFLAGS =
|
||||
QMAKE_CFLAGS_APP = -fPIC
|
||||
QMAKE_CFLAGS_DEPS = -M
|
||||
QMAKE_CFLAGS_WARN_ON = -w1 -Wall -Wcheck -wd1572,873,2259,2261
|
||||
QMAKE_CFLAGS_WARN_ON = -w1 -Wall -Wcheck -wd1572,873,2259,2261,3373
|
||||
QMAKE_CFLAGS_WARN_OFF = -w
|
||||
QMAKE_CFLAGS_RELEASE = -O2 -falign-functions=16 -ansi-alias -fstrict-aliasing
|
||||
QMAKE_CFLAGS_DEBUG = -O0 -g
|
||||
|
@ -14,7 +14,7 @@ QMAKE_COMPILER = gcc clang intel_icc # icc pretends to be gcc and cla
|
||||
QMAKE_CC = icc
|
||||
QMAKE_CFLAGS =
|
||||
QMAKE_CFLAGS_DEPS = -M
|
||||
QMAKE_CFLAGS_WARN_ON = -w1 -Wcheck -wd654,1572,411,873,1125,2259,2261,3280
|
||||
QMAKE_CFLAGS_WARN_ON = -w1 -Wcheck -wd654,1572,411,873,1125,2259,2261,3280,3373
|
||||
QMAKE_CFLAGS_WARN_OFF = -w
|
||||
QMAKE_CFLAGS_RELEASE =
|
||||
QMAKE_CFLAGS_DEBUG = -g
|
||||
|
@ -19,7 +19,7 @@ QMAKE_LEX = flex
|
||||
QMAKE_LEXFLAGS =
|
||||
QMAKE_YACC = bison -y
|
||||
QMAKE_YACCFLAGS = -d
|
||||
QMAKE_CFLAGS = -nologo -Zm200 /Qprec /Qwd1744,1738,809
|
||||
QMAKE_CFLAGS = -nologo -Zm200 /Qprec /Qwd1744,1738,809,3373
|
||||
QMAKE_CFLAGS_WARN_ON = -W3 /Qwd673
|
||||
QMAKE_CFLAGS_WARN_OFF = -W0 /Qwd673
|
||||
QMAKE_CFLAGS_RELEASE = -O2 -MD
|
||||
|
@ -308,13 +308,13 @@ void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t)
|
||||
{
|
||||
t << "first: all\n";
|
||||
t << "all: " << escapeDependencyPath(fileFixify(Option::output.fileName()))
|
||||
<< ' ' << depVar("ALL_DEPS");
|
||||
<< ' ' << depVar("ALL_DEPS") << " $(DESTDIR_TARGET)\n\n";
|
||||
t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS");
|
||||
if (project->first("TEMPLATE") == "aux") {
|
||||
t << "\n\n";
|
||||
return;
|
||||
}
|
||||
t << " $(DESTDIR_TARGET)\n\n";
|
||||
t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS");
|
||||
|
||||
if(!project->isEmpty("QMAKE_PRE_LINK"))
|
||||
t << "\n\t" <<var("QMAKE_PRE_LINK");
|
||||
if(project->isActiveConfig("staticlib") && project->first("TEMPLATE") == "lib") {
|
||||
|
@ -517,13 +517,12 @@ void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t)
|
||||
|
||||
t << "first: all\n";
|
||||
t << "all: " << escapeDependencyPath(fileFixify(Option::output.fileName()))
|
||||
<< ' ' << depVar("ALL_DEPS");
|
||||
<< ' ' << depVar("ALL_DEPS") << " $(DESTDIR_TARGET)\n\n";
|
||||
t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS");
|
||||
if (templateName == "aux") {
|
||||
t << "\n\n";
|
||||
return;
|
||||
}
|
||||
t << " $(DESTDIR_TARGET)\n\n";
|
||||
t << "$(DESTDIR_TARGET): " << depVar("PRE_TARGETDEPS") << " $(OBJECTS) " << depVar("POST_TARGETDEPS");
|
||||
|
||||
if(!project->isEmpty("QMAKE_PRE_LINK"))
|
||||
t << "\n\t" <<var("QMAKE_PRE_LINK");
|
||||
|
@ -2264,10 +2264,14 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
|
||||
QString inFile = info.file;
|
||||
|
||||
// is the extracompiler rule on a file with a built in compiler?
|
||||
const QStringList &objectMappedFile = Project->extraCompilerOutputs[inFile];
|
||||
const QString objectMappedFile = Project->extraCompilerOutputs.value(inFile);
|
||||
bool hasBuiltIn = false;
|
||||
if (!objectMappedFile.isEmpty()) {
|
||||
hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile.at(0));
|
||||
hasBuiltIn = Project->hasBuiltinCompiler(objectMappedFile);
|
||||
|
||||
// Remove the fake file suffix we've added initially to generate correct command lines.
|
||||
inFile.chop(Project->customBuildToolFilterFileSuffix.length());
|
||||
|
||||
// qDebug("*** Extra compiler file has object mapped file '%s' => '%s'", qPrintable(inFile), qPrintable(objectMappedFile.join(' ')));
|
||||
}
|
||||
|
||||
@ -2309,7 +2313,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info)
|
||||
// compiler, too bad..
|
||||
if (hasBuiltIn) {
|
||||
out = inFile;
|
||||
inFile = objectMappedFile.at(0);
|
||||
inFile = objectMappedFile;
|
||||
}
|
||||
|
||||
// Dependency for the output
|
||||
|
@ -204,7 +204,8 @@ const char _slnExtSections[] = "\n\tGlobalSection(ExtensibilityGlobals) = pos
|
||||
VcprojGenerator::VcprojGenerator()
|
||||
: Win32MakefileGenerator(),
|
||||
is64Bit(false),
|
||||
projectWriter(0)
|
||||
projectWriter(0),
|
||||
customBuildToolFilterFileSuffix(QStringLiteral(".cbt"))
|
||||
{
|
||||
}
|
||||
|
||||
@ -892,10 +893,14 @@ void VcprojGenerator::init()
|
||||
if (!hasBuiltinCompiler(file)) {
|
||||
extraCompilerSources[file] += quc.toQString();
|
||||
} else {
|
||||
// Use a fake file name foo.moc.cbt for the project view.
|
||||
// This prevents VS from complaining about a circular
|
||||
// dependency from foo.moc -> foo.moc.
|
||||
QString out = Option::fixPathToTargetOS(replaceExtraCompilerVariables(
|
||||
compiler_out, file, QString(), NoShell), false);
|
||||
out += customBuildToolFilterFileSuffix;
|
||||
extraCompilerSources[out] += quc.toQString();
|
||||
extraCompilerOutputs[out] = QStringList(file); // Can only have one
|
||||
extraCompilerOutputs[out] = file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,8 @@ public:
|
||||
static bool hasBuiltinCompiler(const QString &file);
|
||||
|
||||
QHash<QString, QStringList> extraCompilerSources;
|
||||
QHash<QString, QStringList> extraCompilerOutputs;
|
||||
QHash<QString, QString> extraCompilerOutputs;
|
||||
const QString customBuildToolFilterFileSuffix;
|
||||
bool usePCH;
|
||||
VCProjectWriter *projectWriter;
|
||||
|
||||
|
@ -165,6 +165,9 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
|
||||
|
||||
void Win32MakefileGenerator::processVars()
|
||||
{
|
||||
if (project->first("TEMPLATE").endsWith("aux"))
|
||||
return;
|
||||
|
||||
project->values("QMAKE_ORIG_TARGET") = project->values("TARGET");
|
||||
if (project->isEmpty("QMAKE_PROJECT_NAME"))
|
||||
project->values("QMAKE_PROJECT_NAME") = project->values("QMAKE_ORIG_TARGET");
|
||||
|
@ -17,7 +17,9 @@ JAVASOURCES += \
|
||||
$$PATHPREFIX/QtNativeLibrariesDir.java \
|
||||
$$PATHPREFIX/QtSurface.java \
|
||||
$$PATHPREFIX/ExtractStyle.java \
|
||||
$$PATHPREFIX/QtServiceDelegate.java
|
||||
$$PATHPREFIX/EditMenu.java \
|
||||
$$PATHPREFIX/EditPopupMenu.java \
|
||||
$$PATHPREFIX/CursorHandle.java
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_PREFIX]/jar
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<resources>
|
||||
<array name="qt_sources">
|
||||
<item>https://download.qt.io/ministro/android/qt5/qt-5.7</item>
|
||||
<item>https://download.qt.io/ministro/android/qt5/qt-5.8</item>
|
||||
</array>
|
||||
|
||||
<!-- The following is handled automatically by the deployment tool. It should
|
||||
|
@ -1273,7 +1273,7 @@
|
||||
# define QT_WARNING_DISABLE_INTEL(number) __pragma(warning(disable: number))
|
||||
# define QT_WARNING_DISABLE_CLANG(text)
|
||||
# define QT_WARNING_DISABLE_GCC(text)
|
||||
# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1786)
|
||||
# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1478 1786)
|
||||
#elif defined(Q_CC_INTEL)
|
||||
/* icc: Intel compiler on Linux or OS X */
|
||||
# define QT_WARNING_PUSH QT_DO_PRAGMA(warning(push))
|
||||
@ -1282,7 +1282,7 @@
|
||||
# define QT_WARNING_DISABLE_MSVC(number)
|
||||
# define QT_WARNING_DISABLE_CLANG(text)
|
||||
# define QT_WARNING_DISABLE_GCC(text)
|
||||
# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1786)
|
||||
# define QT_WARNING_DISABLE_DEPRECATED QT_WARNING_DISABLE_INTEL(1478 1786)
|
||||
#elif defined(Q_CC_MSVC) && _MSC_VER >= 1500 && !defined(Q_CC_CLANG)
|
||||
# undef QT_DO_PRAGMA /* not needed */
|
||||
# define QT_WARNING_PUSH __pragma(warning(push))
|
||||
|
@ -921,10 +921,10 @@ template <typename T>
|
||||
class QForeachContainer {
|
||||
QForeachContainer &operator=(const QForeachContainer &) Q_DECL_EQ_DELETE;
|
||||
public:
|
||||
QForeachContainer(const T &t) : c(t) {}
|
||||
QForeachContainer(T &&t) : c(std::move(t)) {}
|
||||
QForeachContainer(const T &t) : c(t), i(c.begin()), e(c.end()) {}
|
||||
QForeachContainer(T &&t) : c(std::move(t)), i(c.begin()), e(c.end()) {}
|
||||
const T c;
|
||||
typename T::const_iterator i = c.begin(), e = c.end();
|
||||
typename T::const_iterator i, e;
|
||||
int control = 1;
|
||||
};
|
||||
|
||||
|
@ -1042,6 +1042,10 @@ void QMessagePattern::setPattern(const QString &pattern)
|
||||
delete [] literals;
|
||||
}
|
||||
delete [] tokens;
|
||||
timeArgs.clear();
|
||||
#ifdef QLOGGING_HAVE_BACKTRACE
|
||||
backtraceArgs.clear();
|
||||
#endif
|
||||
|
||||
// scanner
|
||||
QList<QString> lexemes;
|
||||
|
@ -68,6 +68,7 @@
|
||||
|
||||
#if !defined(Q_CC_MSVC) && (defined(Q_OS_QNX) || defined(Q_CC_INTEL) || !defined(__cplusplus))
|
||||
# include <math.h>
|
||||
# ifdef isnan
|
||||
# define QT_MATH_H_DEFINES_MACROS
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace qnumeric_std_wrapper {
|
||||
@ -85,6 +86,7 @@ QT_END_NAMESPACE
|
||||
# undef isnan
|
||||
# undef isinf
|
||||
# undef isfinite
|
||||
# endif // defined(isnan)
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
@ -578,6 +578,22 @@ QDebug &QDebug::resetFormat()
|
||||
output, but note that some QDebug backends might not be 8-bit clean.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QDebug &QDebug::operator<<(char16_t t)
|
||||
\since 5.5
|
||||
|
||||
Writes the UTF-16 character, \a t, to the stream and returns a reference
|
||||
to the stream.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QDebug &QDebug::operator<<(char32_t t)
|
||||
\since 5.5
|
||||
|
||||
Writes the UTF-32 character, \a t, to the stream and returns a reference
|
||||
to the stream.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QDebug &QDebug::operator<<(const QString &s)
|
||||
|
||||
|
@ -122,6 +122,7 @@ Q_DECL_CONST_FUNCTION static inline QPair<qint64, qint64> toSecsAndNSecs(qint64
|
||||
|
||||
\code
|
||||
using namespace std::chrono;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
QDeadlineTimer deadline(30s);
|
||||
device->waitForReadyRead(deadline);
|
||||
@ -141,6 +142,7 @@ Q_DECL_CONST_FUNCTION static inline QPair<qint64, qint64> toSecsAndNSecs(qint64
|
||||
|
||||
\code
|
||||
using namespace std::chrono;
|
||||
using namespace std::chrono_literals;
|
||||
auto now = steady_clock::now();
|
||||
QDeadlineTimer deadline(now + 1s);
|
||||
Q_ASSERT(deadline == now + 1s);
|
||||
@ -240,7 +242,7 @@ QDeadlineTimer::QDeadlineTimer(qint64 msecs, Qt::TimerType type) Q_DECL_NOTHROW
|
||||
This constructor can be used with C++14's user-defined literals for time, such as in:
|
||||
|
||||
\code
|
||||
using namespace std::chrono;
|
||||
using namespace std::chrono_literals;
|
||||
QDeadlineTimer deadline(250ms);
|
||||
\endcode
|
||||
|
||||
@ -333,7 +335,7 @@ void QDeadlineTimer::setPreciseRemainingTime(qint64 secs, qint64 nsecs, Qt::Time
|
||||
This function can be used with C++14's user-defined literals for time, such as in:
|
||||
|
||||
\code
|
||||
using namespace std::chrono;
|
||||
using namespace std::chrono_literals;
|
||||
deadline.setRemainingTime(250ms);
|
||||
\endcode
|
||||
|
||||
|
@ -1389,10 +1389,6 @@ namespace QtPrivate
|
||||
};
|
||||
|
||||
|
||||
QT_WARNING_PUSH
|
||||
// In C++03 mode, clang consider local or unnamed type and throw a warning instead of ignoring them
|
||||
QT_WARNING_DISABLE_CLANG("-Wunnamed-type-template-args")
|
||||
QT_WARNING_DISABLE_CLANG("-Wlocal-type-template-args")
|
||||
template<typename T> char qt_getEnumMetaObject(const T&);
|
||||
|
||||
template<typename T>
|
||||
@ -1405,7 +1401,6 @@ QT_WARNING_DISABLE_CLANG("-Wlocal-type-template-args")
|
||||
enum { Value = sizeof(qt_getEnumMetaObject(declval())) == sizeof(QMetaObject*) };
|
||||
};
|
||||
template<> struct IsQEnumHelper<void> { enum { Value = false }; };
|
||||
QT_WARNING_POP
|
||||
|
||||
template<typename T, typename Enable = void>
|
||||
struct MetaObjectForType
|
||||
|
@ -279,7 +279,7 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
|
||||
for the mutex to become available.
|
||||
|
||||
Note: Passing a negative duration as the \a duration is equivalent to
|
||||
calling try_lock(). This behavior is different from tryLock.
|
||||
calling try_lock(). This behavior differs from tryLock().
|
||||
|
||||
If the lock was obtained, the mutex must be unlocked with unlock()
|
||||
before another thread can successfully lock it.
|
||||
@ -303,7 +303,7 @@ bool QMutex::tryLock(int timeout) QT_MUTEX_LOCK_NOEXCEPT
|
||||
for the mutex to become available.
|
||||
|
||||
Note: Passing a \a timePoint which has already passed is equivalent
|
||||
to calling try_lock. This behavior is different from tryLock.
|
||||
to calling try_lock(). This behavior differs from tryLock().
|
||||
|
||||
If the lock was obtained, the mutex must be unlocked with unlock()
|
||||
before another thread can successfully lock it.
|
||||
|
@ -535,7 +535,7 @@ QT_DEPRECATED_X("Use std::binary_search") Q_OUTOFLINE_TEMPLATE RandomAccessItera
|
||||
# define QT_HAS_BUILTIN_CTZS
|
||||
Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) Q_DECL_NOTHROW
|
||||
{
|
||||
# if QT_HAS_BUILTIN(__builtin_ctzs) || defined(__BMI__)
|
||||
# if QT_HAS_BUILTIN(__builtin_ctzs)
|
||||
return __builtin_ctzs(v);
|
||||
# else
|
||||
return __builtin_ctz(v);
|
||||
@ -544,7 +544,7 @@ Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_ctzs(quint16 v) Q_DECL_NOTHROW
|
||||
#define QT_HAS_BUILTIN_CLZS
|
||||
Q_DECL_CONSTEXPR Q_ALWAYS_INLINE uint qt_builtin_clzs(quint16 v) Q_DECL_NOTHROW
|
||||
{
|
||||
# if QT_HAS_BUILTIN(__builtin_clzs) || defined(__BMI__)
|
||||
# if QT_HAS_BUILTIN(__builtin_clzs)
|
||||
return __builtin_clzs(v);
|
||||
# else
|
||||
return __builtin_clz(v) - 16U;
|
||||
|
@ -94,17 +94,17 @@ public:
|
||||
};
|
||||
|
||||
explicit QBmpHandler(InternalFormat fmt = BmpFormat);
|
||||
bool canRead() const;
|
||||
bool read(QImage *image);
|
||||
bool write(const QImage &image);
|
||||
bool canRead() const override;
|
||||
bool read(QImage *image) override;
|
||||
bool write(const QImage &image) override;
|
||||
|
||||
QByteArray name() const;
|
||||
QByteArray name() const override;
|
||||
|
||||
static bool canRead(QIODevice *device);
|
||||
|
||||
QVariant option(ImageOption option) const;
|
||||
void setOption(ImageOption option, const QVariant &value);
|
||||
bool supportsOption(ImageOption option) const;
|
||||
QVariant option(ImageOption option) const override;
|
||||
void setOption(ImageOption option, const QVariant &value) override;
|
||||
bool supportsOption(ImageOption option) const override;
|
||||
|
||||
private:
|
||||
bool readHeader();
|
||||
|
@ -91,6 +91,14 @@ QIconEngine::QIconEngine()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\since 5.8
|
||||
\internal
|
||||
*/
|
||||
QIconEngine::QIconEngine(const QIconEngine &)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys the icon engine.
|
||||
*/
|
||||
|
@ -51,6 +51,7 @@ class Q_GUI_EXPORT QIconEngine
|
||||
{
|
||||
public:
|
||||
QIconEngine();
|
||||
QIconEngine(const QIconEngine &other); // ### Qt6: make protected
|
||||
virtual ~QIconEngine();
|
||||
virtual void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) = 0;
|
||||
virtual QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state);
|
||||
@ -80,6 +81,9 @@ public:
|
||||
bool isNull() const; // ### Qt6 make virtual
|
||||
|
||||
virtual void virtual_hook(int id, void *data);
|
||||
|
||||
private:
|
||||
QIconEngine &operator=(const QIconEngine &other) Q_DECL_EQ_DELETE;
|
||||
};
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 0)
|
||||
|
@ -596,37 +596,6 @@ bool QImageData::checkForAlphaPixels() const
|
||||
|
||||
\endtable
|
||||
|
||||
\target qimage-legalese
|
||||
\section1 Legal Information
|
||||
|
||||
For smooth scaling, the transformed() functions use code based on
|
||||
smooth scaling algorithm by Daniel M. Duley.
|
||||
|
||||
\badcode
|
||||
Copyright (C) 2004, 2005 Daniel M. Duley
|
||||
|
||||
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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
\endcode
|
||||
|
||||
\sa QImageReader, QImageWriter, QPixmap, QSvgRenderer, {Image Composition Example},
|
||||
{Image Viewer Example}, {Scribble Example}, {Pixelator Example}
|
||||
*/
|
||||
|
@ -65,15 +65,15 @@ public:
|
||||
QPngHandler();
|
||||
~QPngHandler();
|
||||
|
||||
bool canRead() const;
|
||||
bool read(QImage *image);
|
||||
bool write(const QImage &image);
|
||||
bool canRead() const override;
|
||||
bool read(QImage *image) override;
|
||||
bool write(const QImage &image) override;
|
||||
|
||||
QByteArray name() const;
|
||||
QByteArray name() const override;
|
||||
|
||||
QVariant option(ImageOption option) const;
|
||||
void setOption(ImageOption option, const QVariant &value);
|
||||
bool supportsOption(ImageOption option) const;
|
||||
QVariant option(ImageOption option) const override;
|
||||
void setOption(ImageOption option, const QVariant &value) override;
|
||||
bool supportsOption(ImageOption option) const override;
|
||||
|
||||
static bool canRead(QIODevice *device);
|
||||
|
||||
|
@ -63,17 +63,17 @@ class QPpmHandler : public QImageIOHandler
|
||||
{
|
||||
public:
|
||||
QPpmHandler();
|
||||
bool canRead() const;
|
||||
bool read(QImage *image);
|
||||
bool write(const QImage &image);
|
||||
bool canRead() const override;
|
||||
bool read(QImage *image) override;
|
||||
bool write(const QImage &image) override;
|
||||
|
||||
QByteArray name() const;
|
||||
QByteArray name() const override;
|
||||
|
||||
static bool canRead(QIODevice *device, QByteArray *subType = 0);
|
||||
|
||||
QVariant option(ImageOption option) const;
|
||||
void setOption(ImageOption option, const QVariant &value);
|
||||
bool supportsOption(ImageOption option) const;
|
||||
QVariant option(ImageOption option) const override;
|
||||
void setOption(ImageOption option, const QVariant &value) override;
|
||||
bool supportsOption(ImageOption option) const override;
|
||||
|
||||
private:
|
||||
bool readHeader();
|
||||
|
@ -62,17 +62,17 @@ class QXbmHandler : public QImageIOHandler
|
||||
{
|
||||
public:
|
||||
QXbmHandler();
|
||||
bool canRead() const;
|
||||
bool read(QImage *image);
|
||||
bool write(const QImage &image);
|
||||
bool canRead() const override;
|
||||
bool read(QImage *image) override;
|
||||
bool write(const QImage &image) override;
|
||||
|
||||
QByteArray name() const;
|
||||
QByteArray name() const override;
|
||||
|
||||
static bool canRead(QIODevice *device);
|
||||
|
||||
QVariant option(ImageOption option) const;
|
||||
void setOption(ImageOption option, const QVariant &value);
|
||||
bool supportsOption(ImageOption option) const;
|
||||
QVariant option(ImageOption option) const override;
|
||||
void setOption(ImageOption option, const QVariant &value) override;
|
||||
bool supportsOption(ImageOption option) const override;
|
||||
|
||||
private:
|
||||
bool readHeader();
|
||||
|
@ -62,17 +62,17 @@ class QXpmHandler : public QImageIOHandler
|
||||
{
|
||||
public:
|
||||
QXpmHandler();
|
||||
bool canRead() const;
|
||||
bool read(QImage *image);
|
||||
bool write(const QImage &image);
|
||||
bool canRead() const override;
|
||||
bool read(QImage *image) override;
|
||||
bool write(const QImage &image) override;
|
||||
|
||||
static bool canRead(QIODevice *device);
|
||||
|
||||
QByteArray name() const;
|
||||
QByteArray name() const override;
|
||||
|
||||
QVariant option(ImageOption option) const;
|
||||
void setOption(ImageOption option, const QVariant &value);
|
||||
bool supportsOption(ImageOption option) const;
|
||||
QVariant option(ImageOption option) const override;
|
||||
void setOption(ImageOption option, const QVariant &value) override;
|
||||
bool supportsOption(ImageOption option) const override;
|
||||
|
||||
private:
|
||||
bool readHeader();
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "qpa/qplatformdrag.h"
|
||||
#include "private/qevent_p.h"
|
||||
#include "qfile.h"
|
||||
#include "qhashfunctions.h"
|
||||
#include "qmetaobject.h"
|
||||
#include "qmimedata.h"
|
||||
#include "private/qdnd_p.h"
|
||||
@ -4474,14 +4475,14 @@ int QTouchEvent::TouchPoint::id() const
|
||||
\since 5.8
|
||||
Returns the unique ID of this touch point or token, if any.
|
||||
|
||||
It is normally invalid (with a \l {QPointerUniqueId::numeric()} {numeric()} value of -1),
|
||||
It is normally invalid (see \l {QPointingDeviceUniqueId::isValid()} {isValid()}),
|
||||
because touchscreens cannot uniquely identify fingers. But when the
|
||||
\l {TouchPoint::InfoFlag} {Token} flag is set, it is expected to uniquely
|
||||
identify a specific token (fiducial object).
|
||||
|
||||
\sa flags
|
||||
*/
|
||||
QPointerUniqueId QTouchEvent::TouchPoint::uniqueId() const
|
||||
QPointingDeviceUniqueId QTouchEvent::TouchPoint::uniqueId() const
|
||||
{
|
||||
return d->uniqueId;
|
||||
}
|
||||
@ -4757,7 +4758,7 @@ void QTouchEvent::TouchPoint::setUniqueId(qint64 uid)
|
||||
{
|
||||
if (d->ref.load() != 1)
|
||||
d = d->detach();
|
||||
d->uniqueId = QPointerUniqueId(uid);
|
||||
d->uniqueId = QPointingDeviceUniqueId::fromNumericId(uid);
|
||||
}
|
||||
|
||||
/*! \internal */
|
||||
@ -5176,36 +5177,99 @@ Qt::ApplicationState QApplicationStateChangeEvent::applicationState() const
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QPointerUniqueId
|
||||
\class QPointingDeviceUniqueId
|
||||
\since 5.8
|
||||
\ingroup events
|
||||
\inmodule QtGui
|
||||
|
||||
\brief QPointerUniqueId identifies a unique object, such as a tagged token
|
||||
\brief QPointingDeviceUniqueId identifies a unique object, such as a tagged token
|
||||
or stylus, which is used with a pointing device.
|
||||
|
||||
QPointingDeviceUniqueIds can be compared for equality, and can be used as keys in a QHash.
|
||||
You get access to the numerical ID via numericId(), if the device supports such IDs.
|
||||
For future extensions, though, you should not use that function, but compare objects
|
||||
of this type using the equality operator.
|
||||
|
||||
This class is a thin wrapper around an integer ID. You pass it into and out of
|
||||
functions by value.
|
||||
|
||||
This type actively prevents you from holding it in a QList, because doing so would
|
||||
be very inefficient. Use a QVector instead, which has the same API as QList, but more
|
||||
efficient storage.
|
||||
|
||||
\sa QTouchEvent::TouchPoint
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs a unique pointer ID with a numeric \a id provided by the hardware.
|
||||
The default is -1, which means an invalid pointer ID.
|
||||
\fn QPointingDeviceUniqueId::QPointingDeviceUniqueId()
|
||||
Constructs an invalid unique pointer ID.
|
||||
*/
|
||||
QPointerUniqueId::QPointerUniqueId(qint64 id)
|
||||
: m_numericId(id)
|
||||
|
||||
/*!
|
||||
Constructs a unique pointer ID from numeric ID \a id.
|
||||
*/
|
||||
QPointingDeviceUniqueId QPointingDeviceUniqueId::fromNumericId(qint64 id)
|
||||
{
|
||||
QPointingDeviceUniqueId result;
|
||||
result.m_numericId = id;
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
\property QPointerUniqueId::numeric
|
||||
\fn bool QPointingDeviceUniqueId::isValid() const
|
||||
|
||||
Returns whether this unique pointer ID is valid, that is, it represents an actual
|
||||
pointer.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\property QPointingDeviceUniqueId::numericId
|
||||
\brief the numeric unique ID of the token represented by a touchpoint
|
||||
|
||||
This is the numeric unique ID if the device provides that type of ID;
|
||||
If the device provides a numeric ID, isValid() returns true, and this
|
||||
property provides the numeric ID;
|
||||
otherwise it is -1.
|
||||
|
||||
You should not use the value of this property in portable code, but
|
||||
instead rely on equality to identify pointers.
|
||||
|
||||
\sa isValid()
|
||||
*/
|
||||
qint64 QPointerUniqueId::numeric() const
|
||||
qint64 QPointingDeviceUniqueId::numericId() const Q_DECL_NOTHROW
|
||||
{
|
||||
return m_numericId;
|
||||
}
|
||||
|
||||
/*!
|
||||
\relates QPointingDeviceUniqueId
|
||||
\since 5.8
|
||||
|
||||
Returns whether the two unique pointer IDs \a lhs and \a rhs identify the same pointer
|
||||
(\c true) or not (\c false).
|
||||
*/
|
||||
bool operator==(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) Q_DECL_NOTHROW
|
||||
{
|
||||
return lhs.numericId() == rhs.numericId();
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs)
|
||||
\relates QPointingDeviceUniqueId
|
||||
\since 5.8
|
||||
|
||||
Returns whether the two unique pointer IDs \a lhs and \a rhs identify different pointers
|
||||
(\c true) or not (\c false).
|
||||
*/
|
||||
|
||||
/*!
|
||||
\relates QPointingDeviceUniqueId
|
||||
\since 5.8
|
||||
|
||||
Returns the hash value for \a key, using \a seed to seed the calculation.
|
||||
*/
|
||||
uint qHash(QPointingDeviceUniqueId key, uint seed) Q_DECL_NOTHROW
|
||||
{
|
||||
return qHash(key.numericId(), seed);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -793,21 +793,36 @@ inline bool operator==(QKeyEvent *e, QKeySequence::StandardKey key){return (e ?
|
||||
inline bool operator==(QKeySequence::StandardKey key, QKeyEvent *e){return (e ? e->matches(key) : false);}
|
||||
#endif // QT_NO_SHORTCUT
|
||||
|
||||
class QPointerUniqueIdPrivate;
|
||||
class Q_GUI_EXPORT QPointerUniqueId
|
||||
class Q_GUI_EXPORT QPointingDeviceUniqueId
|
||||
{
|
||||
Q_GADGET
|
||||
Q_PROPERTY(qint64 numeric READ numeric CONSTANT)
|
||||
Q_PROPERTY(qint64 numericId READ numericId CONSTANT)
|
||||
public:
|
||||
explicit QPointerUniqueId(qint64 id = -1);
|
||||
Q_ALWAYS_INLINE
|
||||
Q_DECL_CONSTEXPR QPointingDeviceUniqueId() Q_DECL_NOTHROW : m_numericId(-1) {}
|
||||
// compiler-generated copy/move ctor/assignment operators are ok!
|
||||
// compiler-generated dtor is ok!
|
||||
|
||||
qint64 numeric() const;
|
||||
static QPointingDeviceUniqueId fromNumericId(qint64 id);
|
||||
|
||||
Q_ALWAYS_INLINE Q_DECL_CONSTEXPR bool isValid() const Q_DECL_NOTHROW { return m_numericId != -1; }
|
||||
qint64 numericId() const Q_DECL_NOTHROW;
|
||||
|
||||
private:
|
||||
// TODO for TUIO 2, or any other type of complex token ID, a d-pointer can replace
|
||||
// m_numericId without changing the size of this class.
|
||||
// TODO: for TUIO 2, or any other type of complex token ID, an internal
|
||||
// array (or hash) can be added to hold additional properties.
|
||||
// In this case, m_numericId will then turn into an index into that array (or hash).
|
||||
qint64 m_numericId;
|
||||
};
|
||||
Q_DECLARE_TYPEINFO(QPointingDeviceUniqueId, Q_MOVABLE_TYPE);
|
||||
template <> class QList<QPointingDeviceUniqueId> {}; // to prevent instantiation: use QVector instead
|
||||
|
||||
Q_GUI_EXPORT bool operator==(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) Q_DECL_NOTHROW;
|
||||
inline bool operator!=(QPointingDeviceUniqueId lhs, QPointingDeviceUniqueId rhs) Q_DECL_NOTHROW
|
||||
{ return !operator==(lhs, rhs); }
|
||||
Q_GUI_EXPORT uint qHash(QPointingDeviceUniqueId key, uint seed = 0) Q_DECL_NOTHROW;
|
||||
|
||||
|
||||
|
||||
class QTouchEventTouchPointPrivate;
|
||||
class Q_GUI_EXPORT QTouchEvent : public QInputEvent
|
||||
@ -844,7 +859,7 @@ public:
|
||||
{ qSwap(d, other.d); }
|
||||
|
||||
int id() const;
|
||||
QPointerUniqueId uniqueId() const;
|
||||
QPointingDeviceUniqueId uniqueId() const;
|
||||
|
||||
Qt::TouchPointState state() const;
|
||||
|
||||
|
@ -80,7 +80,7 @@ public:
|
||||
|
||||
QAtomicInt ref;
|
||||
int id;
|
||||
QPointerUniqueId uniqueId;
|
||||
QPointingDeviceUniqueId uniqueId;
|
||||
Qt::TouchPointStates state;
|
||||
QRectF rect, sceneRect, screenRect;
|
||||
QPointF normalizedPos,
|
||||
|
@ -129,7 +129,7 @@ public:
|
||||
TouchPoint() : id(0), uniqueId(-1), pressure(0), rotation(0), state(Qt::TouchPointStationary) { }
|
||||
int id; // for application use
|
||||
qint64 uniqueId; // for TUIO: object/token ID; otherwise empty
|
||||
// TODO for TUIO 2.0: add registerPointerUniqueID(QPointerUniqueId)
|
||||
// TODO for TUIO 2.0: add registerPointerUniqueID(QPointingDeviceUniqueId)
|
||||
QPointF normalPosition; // touch device coordinates, (0 to 1, 0 to 1)
|
||||
QRectF area; // the touched area, centered at position in screen coordinates
|
||||
qreal pressure; // 0 to 1
|
||||
|
@ -61,8 +61,8 @@ public:
|
||||
QOpenGLPaintDevice(int width, int height);
|
||||
virtual ~QOpenGLPaintDevice();
|
||||
|
||||
int devType() const { return QInternal::OpenGL; }
|
||||
QPaintEngine *paintEngine() const;
|
||||
int devType() const override { return QInternal::OpenGL; }
|
||||
QPaintEngine *paintEngine() const override;
|
||||
|
||||
QOpenGLContext *context() const;
|
||||
QSize size() const;
|
||||
@ -82,7 +82,7 @@ public:
|
||||
|
||||
protected:
|
||||
QOpenGLPaintDevice(QOpenGLPaintDevicePrivate &dd);
|
||||
int metric(QPaintDevice::PaintDeviceMetric metric) const;
|
||||
int metric(QPaintDevice::PaintDeviceMetric metric) const override;
|
||||
|
||||
Q_DISABLE_COPY(QOpenGLPaintDevice)
|
||||
QScopedPointer<QOpenGLPaintDevicePrivate> d_ptr;
|
||||
|
60
src/gui/painting/QIMAGETRANSFORM_LICENSE.txt
Normal file
60
src/gui/painting/QIMAGETRANSFORM_LICENSE.txt
Normal file
@ -0,0 +1,60 @@
|
||||
qimagetransform.cpp was contributed by Daniel M. Duley based on code from Imlib2.
|
||||
|
||||
Copyright (C) 2004, 2005 Daniel M. Duley
|
||||
|
||||
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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
|
||||
|
||||
|
||||
Imlib2 License
|
||||
|
||||
Copyright (C) 2000 Carsten Haitzler and various contributors (see
|
||||
AUTHORS)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies of the Software and its Copyright notices. In addition
|
||||
publicly documented acknowledgment must be given that this software has
|
||||
been used if no source code of this software is made available publicly.
|
||||
This includes acknowledgments in either Copyright notices, Manuals,
|
||||
Publicity and Marketing documents or any documentation provided with any
|
||||
product containing this software. This License does not apply to any
|
||||
software that links to the libraries provided by this software
|
||||
(statically or dynamically), but only to the software provided.
|
||||
|
||||
Please see the COPYING.PLAIN for a plain-english explanation of this
|
||||
notice and it's intent.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
@ -1581,7 +1581,7 @@ static const uint *QT_FASTCALL fetchTransformed(uint *buffer, const Operator *,
|
||||
if (bpp != QPixelLayout::BPPNone) // Like this to not ICE on GCC 5.3.1
|
||||
Q_ASSERT(layout->bpp == bpp);
|
||||
// When templated 'fetch' should be inlined at compile time:
|
||||
const FetchPixelFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : fetchPixel<bpp>;
|
||||
const FetchPixelFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : FetchPixelFunc(fetchPixel<bpp>);
|
||||
|
||||
uint *const end = buffer + length;
|
||||
uint *b = buffer;
|
||||
@ -2532,8 +2532,8 @@ static const uint *QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Oper
|
||||
if (bpp != QPixelLayout::BPPNone) // Like this to not ICE on GCC 5.3.1
|
||||
Q_ASSERT(layout->bpp == bpp);
|
||||
// When templated 'fetch' should be inlined at compile time:
|
||||
const FetchPixelsFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixels[layout->bpp] : fetchPixels<bpp>;
|
||||
const FetchPixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : fetchPixel<bpp>;
|
||||
const FetchPixelsFunc fetch = (bpp == QPixelLayout::BPPNone) ? qFetchPixels[layout->bpp] : FetchPixelsFunc(fetchPixels<bpp>);
|
||||
const FetchPixelFunc fetch1 = (bpp == QPixelLayout::BPPNone) ? qFetchPixel[layout->bpp] : FetchPixelFunc(fetchPixel<bpp>);
|
||||
|
||||
int image_width = data->texture.width;
|
||||
int image_height = data->texture.height;
|
||||
|
@ -62,37 +62,37 @@ class QEmulationPaintEngine : public QPaintEngineEx
|
||||
public:
|
||||
QEmulationPaintEngine(QPaintEngineEx *engine);
|
||||
|
||||
virtual bool begin(QPaintDevice *pdev);
|
||||
virtual bool end();
|
||||
bool begin(QPaintDevice *pdev) override;
|
||||
bool end() override;
|
||||
|
||||
virtual Type type() const;
|
||||
virtual QPainterState *createState(QPainterState *orig) const;
|
||||
Type type() const override;
|
||||
QPainterState *createState(QPainterState *orig) const override;
|
||||
|
||||
virtual void fill(const QVectorPath &path, const QBrush &brush);
|
||||
virtual void stroke(const QVectorPath &path, const QPen &pen);
|
||||
virtual void clip(const QVectorPath &path, Qt::ClipOperation op);
|
||||
void fill(const QVectorPath &path, const QBrush &brush) override;
|
||||
void stroke(const QVectorPath &path, const QPen &pen) override;
|
||||
void clip(const QVectorPath &path, Qt::ClipOperation op) override;
|
||||
|
||||
virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
|
||||
virtual void drawTextItem(const QPointF &p, const QTextItem &textItem);
|
||||
virtual void drawStaticTextItem(QStaticTextItem *item);
|
||||
virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
|
||||
virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags);
|
||||
void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override;
|
||||
void drawTextItem(const QPointF &p, const QTextItem &textItem) override;
|
||||
void drawStaticTextItem(QStaticTextItem *item) override;
|
||||
void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) override;
|
||||
void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags) override;
|
||||
|
||||
virtual void clipEnabledChanged();
|
||||
virtual void penChanged();
|
||||
virtual void brushChanged();
|
||||
virtual void brushOriginChanged();
|
||||
virtual void opacityChanged();
|
||||
virtual void compositionModeChanged();
|
||||
virtual void renderHintsChanged();
|
||||
virtual void transformChanged();
|
||||
void clipEnabledChanged() override;
|
||||
void penChanged() override;
|
||||
void brushChanged() override;
|
||||
void brushOriginChanged() override;
|
||||
void opacityChanged() override;
|
||||
void compositionModeChanged() override;
|
||||
void renderHintsChanged() override;
|
||||
void transformChanged() override;
|
||||
|
||||
virtual void setState(QPainterState *s);
|
||||
void setState(QPainterState *s) override;
|
||||
|
||||
virtual void beginNativePainting();
|
||||
virtual void endNativePainting();
|
||||
void beginNativePainting() override;
|
||||
void endNativePainting() override;
|
||||
|
||||
virtual uint flags() const {return QPaintEngineEx::IsEmulationEngine | QPaintEngineEx::DoNotEmulate;}
|
||||
uint flags() const override { return QPaintEngineEx::IsEmulationEngine | QPaintEngineEx::DoNotEmulate; }
|
||||
|
||||
inline QPainterState *state() { return (QPainterState *)QPaintEngine::state; }
|
||||
inline const QPainterState *state() const { return (const QPainterState *)QPaintEngine::state; }
|
||||
|
@ -287,7 +287,7 @@ public:
|
||||
void rasterize(QT_FT_Outline *outline, ProcessSpans callback, void *userData, QRasterBuffer *rasterBuffer);
|
||||
void updateMatrixData(QSpanData *spanData, const QBrush &brush, const QTransform &brushMatrix);
|
||||
|
||||
void systemStateChanged();
|
||||
void systemStateChanged() override;
|
||||
|
||||
void drawImage(const QPointF &pt, const QImage &img, SrcOverBlendFunc func,
|
||||
const QRect &clip, int alpha, const QRect &sr = QRect());
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
QString creator() const;
|
||||
void setCreator(const QString &creator);
|
||||
|
||||
bool newPage();
|
||||
bool newPage() override;
|
||||
|
||||
void setResolution(int resolution);
|
||||
int resolution() const;
|
||||
@ -83,14 +83,14 @@ public:
|
||||
using QPagedPaintDevice::setPageSize;
|
||||
#endif
|
||||
|
||||
void setPageSize(PageSize size);
|
||||
void setPageSizeMM(const QSizeF &size);
|
||||
void setPageSize(PageSize size) override;
|
||||
void setPageSizeMM(const QSizeF &size) override;
|
||||
|
||||
void setMargins(const Margins &m);
|
||||
void setMargins(const Margins &m) override;
|
||||
|
||||
protected:
|
||||
QPaintEngine *paintEngine() const;
|
||||
int metric(PaintDeviceMetric id) const;
|
||||
QPaintEngine *paintEngine() const override;
|
||||
int metric(PaintDeviceMetric id) const override;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QPdfWriter)
|
||||
|
@ -234,7 +234,7 @@ protected:
|
||||
static Qt::PenJoinStyle joinForJoinMode(LineJoinMode mode);
|
||||
static LineJoinMode joinModeForJoin(Qt::PenJoinStyle joinStyle);
|
||||
|
||||
virtual void processCurrentSubpath();
|
||||
void processCurrentSubpath() override;
|
||||
|
||||
qfixed m_strokeWidth;
|
||||
qfixed m_miterLimit;
|
||||
@ -265,14 +265,14 @@ public:
|
||||
void setDashOffset(qreal offset) { m_dashOffset = offset; }
|
||||
qreal dashOffset() const { return m_dashOffset; }
|
||||
|
||||
virtual void begin(void *data);
|
||||
virtual void end();
|
||||
void begin(void *data) override;
|
||||
void end() override;
|
||||
|
||||
inline void setStrokeWidth(qreal width) { m_stroke_width = width; }
|
||||
inline void setMiterLimit(qreal limit) { m_miter_limit = limit; }
|
||||
|
||||
protected:
|
||||
virtual void processCurrentSubpath();
|
||||
void processCurrentSubpath() override;
|
||||
|
||||
QStroker *m_stroker;
|
||||
QVector<qfixed> m_dashPattern;
|
||||
|
@ -1,3 +1,4 @@
|
||||
[
|
||||
{
|
||||
"Id": "grayraster",
|
||||
"Name": "Anti-aliasing rasterizer from FreeType 2",
|
||||
@ -11,4 +12,20 @@
|
||||
"LicenseId": "FTL or GPL-2.0",
|
||||
"LicenseFile": "../../3rdparty/freetype/docs/LICENSE.TXT",
|
||||
"Copyright": "Copyright 2006-2015 by David Turner, Robert Wilhelm, and Werner Lemberg."
|
||||
},
|
||||
{
|
||||
"Id": "smooth-scaling-algorithm",
|
||||
"Name": "Smooth Scaling Algorithm",
|
||||
"QDocModule": "qtgui",
|
||||
"QtUsage": "Used in Qt Gui (QImage::transformed() functions).",
|
||||
"Files": "qimagescale.cpp",
|
||||
|
||||
"Description": "Normal smoothscale method, based on Imlib2's smoothscale.",
|
||||
"LicenseId": "BSD-2-Clause AND Imlib2",
|
||||
"License": "BSD 2-clause \"Simplified\" License and Imlib2 License",
|
||||
"LicenseFile": "QIMAGETRANSFORM_LICENSE.txt",
|
||||
"Copyright": "Copyright (C) 2004, 2005 Daniel M. Duley.
|
||||
(C) Carsten Haitzler and various contributors.
|
||||
(C) Willem Monsuwe <willem@stack.nl>"
|
||||
}
|
||||
]
|
||||
|
@ -118,6 +118,7 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate()
|
||||
{
|
||||
for (int i = 0; i < channelCount; ++i) {
|
||||
if (channels[i].socket) {
|
||||
QObject::disconnect(channels[i].socket, Q_NULLPTR, &channels[i], Q_NULLPTR);
|
||||
channels[i].socket->close();
|
||||
delete channels[i].socket;
|
||||
}
|
||||
|
@ -517,6 +517,19 @@ QHostAddress::QHostAddress(const QHostAddress &address)
|
||||
QHostAddress::QHostAddress(SpecialAddress address)
|
||||
: d(new QHostAddressPrivate)
|
||||
{
|
||||
setAddress(address);
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
\since 5.8
|
||||
|
||||
Sets the special address specified by \a address.
|
||||
*/
|
||||
void QHostAddress::setAddress(SpecialAddress address)
|
||||
{
|
||||
d->clear();
|
||||
|
||||
Q_IPV6ADDR ip6;
|
||||
memset(&ip6, 0, sizeof ip6);
|
||||
quint32 ip4 = INADDR_ANY;
|
||||
@ -567,6 +580,7 @@ QHostAddress &QHostAddress::operator=(const QHostAddress &address)
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if QT_DEPRECATED_SINCE(5, 8)
|
||||
/*!
|
||||
Assigns the host address \a address to this object, and returns a
|
||||
reference to this object.
|
||||
@ -578,6 +592,20 @@ QHostAddress &QHostAddress::operator=(const QString &address)
|
||||
setAddress(address);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\since 5.8
|
||||
Assigns the special address \a address to this object, and returns a
|
||||
reference to this object.
|
||||
|
||||
\sa setAddress()
|
||||
*/
|
||||
QHostAddress &QHostAddress::operator=(SpecialAddress address)
|
||||
{
|
||||
setAddress(address);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn bool QHostAddress::operator!=(const QHostAddress &other) const
|
||||
|
@ -108,7 +108,11 @@ public:
|
||||
#endif
|
||||
|
||||
QHostAddress &operator=(const QHostAddress &other);
|
||||
#if QT_DEPRECATED_SINCE(5, 8)
|
||||
QT_DEPRECATED_X("use = QHostAddress(string) instead")
|
||||
QHostAddress &operator=(const QString &address);
|
||||
#endif
|
||||
QHostAddress &operator=(SpecialAddress address);
|
||||
|
||||
void swap(QHostAddress &other) Q_DECL_NOTHROW { d.swap(other.d); }
|
||||
|
||||
@ -118,6 +122,7 @@ public:
|
||||
void setAddress(const Q_IPV6ADDR &ip6Addr);
|
||||
void setAddress(const sockaddr *address);
|
||||
bool setAddress(const QString &address);
|
||||
void setAddress(SpecialAddress address);
|
||||
|
||||
QAbstractSocket::NetworkLayerProtocol protocol() const;
|
||||
quint32 toIPv4Address() const; // ### Qt6: merge with next overload
|
||||
|
@ -126,6 +126,33 @@ static HRESULT qt_winrt_try_create_thread_network_context(QString host, ComPtr<I
|
||||
}
|
||||
#endif // _MSC_VER >= 1900
|
||||
|
||||
typedef QHash<qintptr, IStreamSocket *> TcpSocketHash;
|
||||
|
||||
struct SocketHandler
|
||||
{
|
||||
SocketHandler() : socketCount(0) {}
|
||||
qintptr socketCount;
|
||||
TcpSocketHash pendingTcpSockets;
|
||||
};
|
||||
|
||||
Q_GLOBAL_STATIC(SocketHandler, gSocketHandler)
|
||||
|
||||
struct SocketGlobal
|
||||
{
|
||||
SocketGlobal()
|
||||
{
|
||||
HRESULT hr;
|
||||
hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(),
|
||||
&bufferFactory);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
ComPtr<IBufferFactory> bufferFactory;
|
||||
};
|
||||
Q_GLOBAL_STATIC(SocketGlobal, g)
|
||||
|
||||
#define READ_BUFFER_SIZE 65536
|
||||
|
||||
static inline QString qt_QStringFromHString(const HString &string)
|
||||
{
|
||||
UINT32 length;
|
||||
@ -136,8 +163,43 @@ static inline QString qt_QStringFromHString(const HString &string)
|
||||
class SocketEngineWorker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SocketEngineWorker(QNativeSocketEnginePrivate *engine)
|
||||
: enginePrivate(engine)
|
||||
{
|
||||
}
|
||||
|
||||
~SocketEngineWorker()
|
||||
{
|
||||
if (Q_UNLIKELY(initialReadOp)) {
|
||||
ComPtr<IAsyncInfo> info;
|
||||
HRESULT hr = initialReadOp.As(&info);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
if (info) {
|
||||
hr = info->Cancel();
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = info->Close();
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
}
|
||||
|
||||
if (readOp) {
|
||||
ComPtr<IAsyncInfo> info;
|
||||
HRESULT hr = readOp.As(&info);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
if (info) {
|
||||
hr = info->Cancel();
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = info->Close();
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signals:
|
||||
void newDatagramsReceived(const QList<WinRtDatagram> &datagram);
|
||||
void newDataReceived(const QVector<QByteArray> &data);
|
||||
void socketErrorOccured(QAbstractSocket::SocketError error);
|
||||
|
||||
public slots:
|
||||
Q_INVOKABLE void notifyAboutNewDatagrams()
|
||||
@ -148,7 +210,30 @@ public slots:
|
||||
emit newDatagramsReceived(datagrams);
|
||||
}
|
||||
|
||||
Q_INVOKABLE void notifyAboutNewData()
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
const QVector<QByteArray> newData = std::move(pendingData);
|
||||
pendingData.clear();
|
||||
emit newDataReceived(newData);
|
||||
}
|
||||
|
||||
public:
|
||||
void startReading()
|
||||
{
|
||||
ComPtr<IBuffer> buffer;
|
||||
HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
ComPtr<IInputStream> stream;
|
||||
hr = tcpSocket->get_InputStream(&stream);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, initialReadOp.GetAddressOf());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
enginePrivate->socketState = QAbstractSocket::ConnectedState;
|
||||
hr = initialReadOp->put_Completed(Callback<SocketReadCompletedHandler>(this, &SocketEngineWorker::onReadyRead).Get());
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
HRESULT OnNewDatagramReceived(IDatagramSocket *, IDatagramSocketMessageReceivedEventArgs *args)
|
||||
{
|
||||
WinRtDatagram datagram;
|
||||
@ -184,9 +269,127 @@ public:
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT onReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status)
|
||||
{
|
||||
if (asyncInfo == initialReadOp.Get()) {
|
||||
initialReadOp.Reset();
|
||||
} else if (asyncInfo == readOp.Get()) {
|
||||
readOp.Reset();
|
||||
} else {
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
// A read in UnconnectedState will close the socket and return -1 and thus tell the caller,
|
||||
// that the connection was closed. The socket cannot be closed here, as the subsequent read
|
||||
// might fail then.
|
||||
if (status == Error || status == Canceled) {
|
||||
emit socketErrorOccured(QAbstractSocket::RemoteHostClosedError);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ComPtr<IBuffer> buffer;
|
||||
HRESULT hr = asyncInfo->GetResults(&buffer);
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning(hr, "Failed to get read results buffer");
|
||||
emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
UINT32 bufferLength;
|
||||
hr = buffer->get_Length(&bufferLength);
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning(hr, "Failed to get buffer length");
|
||||
emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
|
||||
return S_OK;
|
||||
}
|
||||
// A zero sized buffer length signals, that the remote host closed the connection. The socket
|
||||
// cannot be closed though, as the following read might have socket descriptor -1 and thus and
|
||||
// the closing of the socket won't be communicated to the caller. So only the error is set. The
|
||||
// actual socket close happens inside of read.
|
||||
if (!bufferLength) {
|
||||
emit socketErrorOccured(QAbstractSocket::RemoteHostClosedError);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
|
||||
hr = buffer.As(&byteArrayAccess);
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning(hr, "Failed to get cast buffer");
|
||||
emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
|
||||
return S_OK;
|
||||
}
|
||||
byte *data;
|
||||
hr = byteArrayAccess->Buffer(&data);
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning(hr, "Failed to access buffer data");
|
||||
emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
QByteArray newData(reinterpret_cast<const char*>(data), qint64(bufferLength));
|
||||
QMutexLocker readLocker(&mutex);
|
||||
if (pendingData.isEmpty())
|
||||
QMetaObject::invokeMethod(this, "notifyAboutNewData", Qt::QueuedConnection);
|
||||
pendingData << newData;
|
||||
readLocker.unlock();
|
||||
|
||||
hr = QEventDispatcherWinRT::runOnXamlThread([buffer, this]() {
|
||||
UINT32 readBufferLength;
|
||||
ComPtr<IInputStream> stream;
|
||||
HRESULT hr = tcpSocket->get_InputStream(&stream);
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning(hr, "Failed to obtain input stream");
|
||||
emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Reuse the stream buffer
|
||||
hr = buffer->get_Capacity(&readBufferLength);
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning(hr, "Failed to get buffer capacity");
|
||||
emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
|
||||
return S_OK;
|
||||
}
|
||||
hr = buffer->put_Length(0);
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning(hr, "Failed to set buffer length");
|
||||
emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hr = stream->ReadAsync(buffer.Get(), readBufferLength, InputStreamOptions_Partial, &readOp);
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning(hr, "onReadyRead(): Could not read into socket stream buffer.");
|
||||
emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
|
||||
return S_OK;
|
||||
}
|
||||
hr = readOp->put_Completed(Callback<SocketReadCompletedHandler>(this, &SocketEngineWorker::onReadyRead).Get());
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning(hr, "onReadyRead(): Failed to set socket read callback.");
|
||||
emit socketErrorOccured(QAbstractSocket::UnknownSocketError);
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
});
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void setTcpSocket(ComPtr<IStreamSocket> socket) { tcpSocket = socket; }
|
||||
|
||||
private:
|
||||
ComPtr<IStreamSocket> tcpSocket;
|
||||
|
||||
QList<WinRtDatagram> pendingDatagrams;
|
||||
QVector<QByteArray> pendingData;
|
||||
|
||||
// Protects pendingData/pendingDatagrams which are accessed from native callbacks
|
||||
QMutex mutex;
|
||||
|
||||
ComPtr<IAsyncOperationWithProgress<IBuffer *, UINT32>> initialReadOp;
|
||||
ComPtr<IAsyncOperationWithProgress<IBuffer *, UINT32>> readOp;
|
||||
|
||||
QNativeSocketEnginePrivate *enginePrivate;
|
||||
};
|
||||
|
||||
static QByteArray socketDescription(const QAbstractSocketEngine *s)
|
||||
@ -239,33 +442,6 @@ static QByteArray socketDescription(const QAbstractSocketEngine *s)
|
||||
} } while (0)
|
||||
#define Q_TR(a) QT_TRANSLATE_NOOP(QNativeSocketEngine, a)
|
||||
|
||||
typedef QHash<qintptr, IStreamSocket *> TcpSocketHash;
|
||||
|
||||
struct SocketHandler
|
||||
{
|
||||
SocketHandler() : socketCount(0) {}
|
||||
qintptr socketCount;
|
||||
TcpSocketHash pendingTcpSockets;
|
||||
};
|
||||
|
||||
Q_GLOBAL_STATIC(SocketHandler, gSocketHandler)
|
||||
|
||||
struct SocketGlobal
|
||||
{
|
||||
SocketGlobal()
|
||||
{
|
||||
HRESULT hr;
|
||||
hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(),
|
||||
&bufferFactory);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
ComPtr<IBufferFactory> bufferFactory;
|
||||
};
|
||||
Q_GLOBAL_STATIC(SocketGlobal, g)
|
||||
|
||||
#define READ_BUFFER_SIZE 65536
|
||||
|
||||
template <typename T>
|
||||
static AsyncStatus opStatus(const ComPtr<T> &op)
|
||||
{
|
||||
@ -315,6 +491,10 @@ QNativeSocketEngine::QNativeSocketEngine(QObject *parent)
|
||||
connect(this, SIGNAL(readReady()), SLOT(readNotification()), Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(writeReady()), SLOT(writeNotification()), Qt::QueuedConnection);
|
||||
connect(d->worker, &SocketEngineWorker::newDatagramsReceived, this, &QNativeSocketEngine::handleNewDatagrams, Qt::QueuedConnection);
|
||||
connect(d->worker, &SocketEngineWorker::newDataReceived,
|
||||
this, &QNativeSocketEngine::handleNewData, Qt::QueuedConnection);
|
||||
connect(d->worker, &SocketEngineWorker::socketErrorOccured,
|
||||
this, &QNativeSocketEngine::handleTcpError, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
QNativeSocketEngine::~QNativeSocketEngine()
|
||||
@ -358,23 +538,9 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket::
|
||||
|
||||
// Start processing incoming data
|
||||
if (d->socketType == QAbstractSocket::TcpSocket) {
|
||||
HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, socketState, this]() {
|
||||
ComPtr<IBuffer> buffer;
|
||||
HRESULT hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer);
|
||||
RETURN_HR_IF_FAILED("initialize(): Could not create buffer");
|
||||
ComPtr<IInputStream> stream;
|
||||
hr = socket->get_InputStream(&stream);
|
||||
RETURN_HR_IF_FAILED("initialize(): Could not obtain input stream");
|
||||
ComPtr<IAsyncBufferOperation> readOp;
|
||||
hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, readOp.GetAddressOf());
|
||||
RETURN_HR_IF_FAILED_WITH_ARGS("initialize(): Failed to read from the socket buffer (%s).",
|
||||
socketDescription(this).constData());
|
||||
QMutexLocker locker(&d->readOperationsMutex);
|
||||
d->pendingReadOps.append(readOp);
|
||||
d->socketState = socketState;
|
||||
hr = readOp->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get());
|
||||
RETURN_HR_IF_FAILED_WITH_ARGS("initialize(): Failed to set socket read callback (%s).",
|
||||
socketDescription(this).constData());
|
||||
HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, socket, this]() {
|
||||
d->worker->setTcpSocket(socket);
|
||||
d->worker->startReading();
|
||||
return S_OK;
|
||||
});
|
||||
if (FAILED(hr))
|
||||
@ -639,20 +805,6 @@ void QNativeSocketEngine::close()
|
||||
}
|
||||
#endif // _MSC_VER >= 1900
|
||||
|
||||
QMutexLocker locker(&d->readOperationsMutex);
|
||||
for (ComPtr<IAsyncBufferOperation> readOp : d->pendingReadOps) {
|
||||
ComPtr<IAsyncInfo> info;
|
||||
hr = readOp.As(&info);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
if (info) {
|
||||
hr = info->Cancel();
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = info->Close();
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
}
|
||||
}
|
||||
locker.unlock();
|
||||
|
||||
if (d->socketDescriptor != -1) {
|
||||
ComPtr<IClosable> socket;
|
||||
if (d->socketType == QAbstractSocket::TcpSocket) {
|
||||
@ -730,14 +882,32 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxlen)
|
||||
// happens and there isn't anything left in the buffer, we have to return -1 in order to signal
|
||||
// the closing of the socket.
|
||||
QMutexLocker mutexLocker(&d->readMutex);
|
||||
if (d->readBytes.pos() == d->readBytes.size() && d->socketState != QAbstractSocket::ConnectedState) {
|
||||
if (d->pendingData.isEmpty() && d->socketState != QAbstractSocket::ConnectedState) {
|
||||
close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
qint64 b = d->readBytes.read(data, maxlen);
|
||||
d->bytesAvailable = d->readBytes.size() - d->readBytes.pos();
|
||||
return b;
|
||||
QByteArray readData;
|
||||
qint64 leftToMaxLen = maxlen;
|
||||
while (leftToMaxLen > 0 && !d->pendingData.isEmpty()) {
|
||||
QByteArray pendingData = d->pendingData.takeFirst();
|
||||
// Do not read the whole data. Put the rest of it back into the "queue"
|
||||
if (leftToMaxLen < pendingData.length()) {
|
||||
readData += pendingData.left(leftToMaxLen);
|
||||
pendingData = pendingData.remove(0, maxlen);
|
||||
d->pendingData.prepend(pendingData);
|
||||
break;
|
||||
} else {
|
||||
readData += pendingData;
|
||||
leftToMaxLen -= pendingData.length();
|
||||
}
|
||||
}
|
||||
const int copyLength = qMin(maxlen, qint64(readData.length()));
|
||||
d->bytesAvailable -= copyLength;
|
||||
mutexLocker.unlock();
|
||||
|
||||
memcpy(data, readData, copyLength);
|
||||
return copyLength;
|
||||
}
|
||||
|
||||
qint64 QNativeSocketEngine::write(const char *data, qint64 len)
|
||||
@ -913,7 +1083,7 @@ bool QNativeSocketEngine::waitForRead(int msecs, bool *timedOut)
|
||||
|
||||
// If we are a client, we are ready to read if our buffer has data
|
||||
QMutexLocker locker(&d->readMutex);
|
||||
if (!d->readBytes.atEnd())
|
||||
if (!d->pendingData.isEmpty())
|
||||
return true;
|
||||
|
||||
// Nothing to do, wait for more events
|
||||
@ -1001,21 +1171,8 @@ void QNativeSocketEngine::establishRead()
|
||||
|
||||
HRESULT hr;
|
||||
hr = QEventDispatcherWinRT::runOnXamlThread([d]() {
|
||||
ComPtr<IInputStream> stream;
|
||||
HRESULT hr = d->tcpSocket()->get_InputStream(&stream);
|
||||
RETURN_HR_IF_FAILED("establishRead(): Failed to get socket input stream");
|
||||
|
||||
ComPtr<IBuffer> buffer;
|
||||
hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer);
|
||||
RETURN_HR_IF_FAILED("establishRead(): Failed to create buffer");
|
||||
|
||||
ComPtr<IAsyncBufferOperation> readOp;
|
||||
hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, readOp.GetAddressOf());
|
||||
RETURN_HR_IF_FAILED("establishRead(): Failed to initiate socket read");
|
||||
QMutexLocker locker(&d->readOperationsMutex);
|
||||
d->pendingReadOps.append(readOp);
|
||||
hr = readOp->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get());
|
||||
RETURN_HR_IF_FAILED("establishRead(): Failed to register read callback");
|
||||
d->worker->setTcpSocket(d->tcpSocket());
|
||||
d->worker->startReading();
|
||||
return S_OK;
|
||||
});
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
@ -1032,6 +1189,32 @@ void QNativeSocketEngine::handleNewDatagrams(const QList<WinRtDatagram> &datagra
|
||||
emit readReady();
|
||||
}
|
||||
|
||||
void QNativeSocketEngine::handleNewData(const QVector<QByteArray> &data)
|
||||
{
|
||||
// Defer putting the data into the list until the next event loop iteration
|
||||
// (where the readyRead signal is emitted as well)
|
||||
QMetaObject::invokeMethod(this, "putIntoPendingData", Qt::QueuedConnection,
|
||||
Q_ARG(QVector<QByteArray>, data));
|
||||
}
|
||||
|
||||
void QNativeSocketEngine::handleTcpError(QAbstractSocket::SocketError error)
|
||||
{
|
||||
Q_D(QNativeSocketEngine);
|
||||
QNativeSocketEnginePrivate::ErrorString errorString;
|
||||
switch (error) {
|
||||
case QAbstractSocket::RemoteHostClosedError:
|
||||
errorString = QNativeSocketEnginePrivate::RemoteHostClosedErrorString;
|
||||
break;
|
||||
default:
|
||||
errorString = QNativeSocketEnginePrivate::UnknownSocketErrorString;
|
||||
}
|
||||
|
||||
d->setError(error, errorString);
|
||||
d->socketState = QAbstractSocket::UnconnectedState;
|
||||
if (d->notifyOnRead)
|
||||
emit readReady();
|
||||
}
|
||||
|
||||
void QNativeSocketEngine::putIntoPendingDatagramsList(const QList<WinRtDatagram> &datagrams)
|
||||
{
|
||||
Q_D(QNativeSocketEngine);
|
||||
@ -1039,6 +1222,18 @@ void QNativeSocketEngine::putIntoPendingDatagramsList(const QList<WinRtDatagram>
|
||||
d->pendingDatagrams.append(datagrams);
|
||||
}
|
||||
|
||||
void QNativeSocketEngine::putIntoPendingData(const QVector<QByteArray> &data)
|
||||
{
|
||||
Q_D(QNativeSocketEngine);
|
||||
QMutexLocker locker(&d->readMutex);
|
||||
d->pendingData.append(data);
|
||||
for (const QByteArray &newData : data)
|
||||
d->bytesAvailable += newData.length();
|
||||
locker.unlock();
|
||||
if (d->notifyOnRead)
|
||||
readNotification();
|
||||
}
|
||||
|
||||
bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType socketType, QAbstractSocket::NetworkLayerProtocol &socketProtocol)
|
||||
{
|
||||
Q_UNUSED(socketProtocol);
|
||||
@ -1093,7 +1288,7 @@ QNativeSocketEnginePrivate::QNativeSocketEnginePrivate()
|
||||
, notifyOnException(false)
|
||||
, closingDown(false)
|
||||
, socketDescriptor(-1)
|
||||
, worker(new SocketEngineWorker)
|
||||
, worker(new SocketEngineWorker(this))
|
||||
, sslSocket(Q_NULLPTR)
|
||||
, connectionToken( { -1 } )
|
||||
{
|
||||
@ -1481,109 +1676,6 @@ HRESULT QNativeSocketEnginePrivate::handleConnectOpFinished(IAsyncAction *action
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status)
|
||||
{
|
||||
if (closingDown || wasDeleted || isDeletingChildren
|
||||
|| socketState == QAbstractSocket::UnconnectedState) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Q_Q(QNativeSocketEngine);
|
||||
QMutexLocker locker(&readOperationsMutex);
|
||||
for (int i = 0; i < pendingReadOps.count(); ++i) {
|
||||
if (pendingReadOps.at(i).Get() == asyncInfo) {
|
||||
pendingReadOps.takeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
locker.unlock();
|
||||
|
||||
// A read in UnconnectedState will close the socket and return -1 and thus tell the caller,
|
||||
// that the connection was closed. The socket cannot be closed here, as the subsequent read
|
||||
// might fail then.
|
||||
if (status == Error || status == Canceled) {
|
||||
setError(QAbstractSocket::RemoteHostClosedError, RemoteHostClosedErrorString);
|
||||
socketState = QAbstractSocket::UnconnectedState;
|
||||
if (notifyOnRead)
|
||||
emit q->readReady();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ComPtr<IBuffer> buffer;
|
||||
HRESULT hr = asyncInfo->GetResults(&buffer);
|
||||
RETURN_OK_IF_FAILED("Failed to get read results buffer");
|
||||
|
||||
UINT32 bufferLength;
|
||||
hr = buffer->get_Length(&bufferLength);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
// A zero sized buffer length signals, that the remote host closed the connection. The socket
|
||||
// cannot be closed though, as the following read might have socket descriptor -1 and thus and
|
||||
// the closing of the socket won't be communicated to the caller. So only the error is set. The
|
||||
// actual socket close happens inside of read.
|
||||
if (!bufferLength) {
|
||||
setError(QAbstractSocket::RemoteHostClosedError, RemoteHostClosedErrorString);
|
||||
socketState = QAbstractSocket::UnconnectedState;
|
||||
if (notifyOnRead)
|
||||
emit q->readReady();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
|
||||
hr = buffer.As(&byteArrayAccess);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
byte *data;
|
||||
hr = byteArrayAccess->Buffer(&data);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
|
||||
QMutexLocker readLocker(&readMutex);
|
||||
if (readBytes.atEnd()) // Everything has been read; the buffer is safe to reset
|
||||
readBytes.close();
|
||||
if (!readBytes.isOpen())
|
||||
readBytes.open(QBuffer::ReadWrite|QBuffer::Truncate);
|
||||
qint64 readPos = readBytes.pos();
|
||||
readBytes.seek(readBytes.size());
|
||||
Q_ASSERT(readBytes.atEnd());
|
||||
readBytes.write(reinterpret_cast<const char*>(data), qint64(bufferLength));
|
||||
readBytes.seek(readPos);
|
||||
bytesAvailable = readBytes.size() - readBytes.pos();
|
||||
readLocker.unlock();
|
||||
|
||||
if (notifyOnRead)
|
||||
emit q->readReady();
|
||||
|
||||
hr = QEventDispatcherWinRT::runOnXamlThread([buffer, q, this]() {
|
||||
UINT32 readBufferLength;
|
||||
ComPtr<IInputStream> stream;
|
||||
HRESULT hr = tcpSocket()->get_InputStream(&stream);
|
||||
RETURN_HR_IF_FAILED("handleReadyRead(): Could not obtain input stream");
|
||||
|
||||
// Reuse the stream buffer
|
||||
hr = buffer->get_Capacity(&readBufferLength);
|
||||
RETURN_HR_IF_FAILED("handleReadyRead(): Could not obtain buffer capacity");
|
||||
hr = buffer->put_Length(0);
|
||||
RETURN_HR_IF_FAILED("handleReadyRead(): Could not set buffer length");
|
||||
|
||||
ComPtr<IAsyncBufferOperation> readOp;
|
||||
hr = stream->ReadAsync(buffer.Get(), readBufferLength, InputStreamOptions_Partial, &readOp);
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning(hr, "handleReadyRead(): Could not read into socket stream buffer (%s).",
|
||||
socketDescription(q).constData());
|
||||
return S_OK;
|
||||
}
|
||||
QMutexLocker locker(&readOperationsMutex);
|
||||
pendingReadOps.append(readOp);
|
||||
hr = readOp->put_Completed(Callback<SocketReadCompletedHandler>(this, &QNativeSocketEnginePrivate::handleReadyRead).Get());
|
||||
if (FAILED(hr)) {
|
||||
qErrnoWarning(hr, "handleReadyRead(): Failed to set socket read callback (%s).",
|
||||
socketDescription(q).constData());
|
||||
return S_OK;
|
||||
}
|
||||
return S_OK;
|
||||
});
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT QNativeSocketEnginePrivate::handleNewDatagram(IDatagramSocket *socket, IDatagramSocketMessageReceivedEventArgs *args)
|
||||
{
|
||||
Q_Q(QNativeSocketEngine);
|
||||
|
@ -144,9 +144,12 @@ signals:
|
||||
private slots:
|
||||
void establishRead();
|
||||
void handleNewDatagrams(const QList<WinRtDatagram> &datagram);
|
||||
void handleNewData(const QVector<QByteArray> &data);
|
||||
void handleTcpError(QAbstractSocket::SocketError error);
|
||||
|
||||
private:
|
||||
Q_INVOKABLE void putIntoPendingDatagramsList(const QList<WinRtDatagram> &datagrams);
|
||||
Q_INVOKABLE void putIntoPendingData(const QVector<QByteArray> &data);
|
||||
|
||||
Q_DECLARE_PRIVATE(QNativeSocketEngine)
|
||||
Q_DISABLE_COPY(QNativeSocketEngine)
|
||||
@ -215,23 +218,17 @@ private:
|
||||
Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> tcpListener;
|
||||
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncAction> connectOp;
|
||||
|
||||
// Protected by readOperationsMutex. Written in handleReadyRead (native callback)
|
||||
QVector<Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IAsyncOperationWithProgress<ABI::Windows::Storage::Streams::IBuffer *, UINT32>>> pendingReadOps;
|
||||
|
||||
// Protected by readMutex. Written in handleReadyRead (native callback)
|
||||
QBuffer readBytes;
|
||||
|
||||
// In case of TCP readMutex protects readBytes and bytesAvailable. In case of UDP it is
|
||||
// pendingDatagrams. They are written inside native callbacks (handleReadyRead and
|
||||
// handleNewDatagrams/putIntoPendingDatagramsList)
|
||||
mutable QMutex readMutex;
|
||||
|
||||
// As pendingReadOps is changed inside handleReadyRead(native callback) it has to be protected
|
||||
QMutex readOperationsMutex;
|
||||
|
||||
// Protected by readMutex. Written in handleReadyRead (native callback)
|
||||
QAtomicInteger<int> bytesAvailable;
|
||||
|
||||
// Protected by readMutex. Written in handleNewData/putIntoPendingData (native callback)
|
||||
QVector<QByteArray> pendingData;
|
||||
|
||||
// Protected by readMutex. Written in handleNewDatagrams/putIntoPendingDatagramsList
|
||||
QList<WinRtDatagram> pendingDatagrams;
|
||||
|
||||
@ -246,7 +243,6 @@ private:
|
||||
HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener,
|
||||
ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args);
|
||||
HRESULT handleConnectOpFinished(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus);
|
||||
HRESULT handleReadyRead(ABI::Windows::Foundation::IAsyncOperationWithProgress<ABI::Windows::Storage::Streams::IBuffer *, UINT32> *asyncInfo, ABI::Windows::Foundation::AsyncStatus);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -41,7 +41,8 @@
|
||||
#define QEGLNATIVECONTEXT_H
|
||||
|
||||
#include <QtCore/QMetaType>
|
||||
#include <QtEglSupport/private/qt_egl_p.h>
|
||||
|
||||
// Leave including egl.h with the appropriate defines to the client.
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -36,6 +36,12 @@
|
||||
that an application using it is only guaranteed to work with the Qt version it was
|
||||
developed against.
|
||||
|
||||
\note Due to being public while relying on otherwise hidden EGL types, this header
|
||||
itself does not include \c{EGL/egl.h}. It is the application's responsibility to
|
||||
include egl.h with any appropriate defines (for example, \c{MESA_EGL_NO_X11_HEADERS}
|
||||
or other vendor-specific defines controlling the typedefs for EGL's native resources)
|
||||
before this header.
|
||||
|
||||
\sa QOpenGLContext::setNativeHandle(), QOpenGLContext::nativeHandle()
|
||||
*/
|
||||
|
||||
|
@ -663,7 +663,7 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
|
||||
glyphRun.glyphOffsets = &glyphOffset;
|
||||
|
||||
QTransform xform = originalTransform;
|
||||
if (fontDef.stretch != 100)
|
||||
if (fontDef.stretch != 100 && fontDef.stretch != QFont::AnyStretch)
|
||||
xform.scale(fontDef.stretch / 100.0, 1.0);
|
||||
|
||||
DWRITE_MATRIX transform;
|
||||
@ -933,7 +933,7 @@ glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph
|
||||
Q_UNUSED(format);
|
||||
|
||||
QTransform matrix = originalTransform;
|
||||
if (fontDef.stretch != 100)
|
||||
if (fontDef.stretch != 100 && fontDef.stretch != QFont::AnyStretch)
|
||||
matrix.scale(fontDef.stretch / 100.0, 1.0);
|
||||
|
||||
glyph_metrics_t bbox = QFontEngine::boundingBox(glyph, matrix); // To get transformed advance
|
||||
|
@ -767,6 +767,10 @@ static bool readExifHeader(QDataStream &stream)
|
||||
*/
|
||||
static int getExifOrientation(QByteArray &exifData)
|
||||
{
|
||||
// Current EXIF version (2.3) says there can be at most 5 IFDs,
|
||||
// byte we allow for 10 so we're able to deal with future extensions.
|
||||
const int maxIfdCount = 10;
|
||||
|
||||
QDataStream stream(&exifData, QIODevice::ReadOnly);
|
||||
|
||||
if (!readExifHeader(stream))
|
||||
@ -774,7 +778,8 @@ static int getExifOrientation(QByteArray &exifData)
|
||||
|
||||
quint16 val;
|
||||
quint32 offset;
|
||||
const qint64 headerStart = stream.device()->pos();
|
||||
const qint64 headerStart = 6; // the EXIF header has a constant size
|
||||
Q_ASSERT(headerStart == stream.device()->pos());
|
||||
|
||||
// read byte order marker
|
||||
stream >> val;
|
||||
@ -785,7 +790,7 @@ static int getExifOrientation(QByteArray &exifData)
|
||||
else
|
||||
return -1; // unknown byte order
|
||||
|
||||
// read size
|
||||
// confirm byte order
|
||||
stream >> val;
|
||||
if (val != 0x2a)
|
||||
return -1;
|
||||
@ -793,18 +798,22 @@ static int getExifOrientation(QByteArray &exifData)
|
||||
stream >> offset;
|
||||
|
||||
// read IFD
|
||||
while (!stream.atEnd()) {
|
||||
for (int n = 0; n < maxIfdCount; ++n) {
|
||||
quint16 numEntries;
|
||||
|
||||
// skip offset bytes to get the next IFD
|
||||
const qint64 bytesToSkip = offset - (stream.device()->pos() - headerStart);
|
||||
|
||||
if (stream.skipRawData(bytesToSkip) != bytesToSkip)
|
||||
if (bytesToSkip < 0 || (offset + headerStart >= exifData.size())) {
|
||||
// disallow going backwards, though it's permitted in the spec
|
||||
return -1;
|
||||
} else if (bytesToSkip != 0) {
|
||||
// seek to the IFD
|
||||
if (!stream.device()->seek(offset + headerStart))
|
||||
return -1;
|
||||
}
|
||||
|
||||
stream >> numEntries;
|
||||
|
||||
for (; numEntries > 0; --numEntries) {
|
||||
for (; numEntries > 0 && stream.status() == QDataStream::Ok; --numEntries) {
|
||||
quint16 tag;
|
||||
quint16 type;
|
||||
quint32 components;
|
||||
@ -828,12 +837,14 @@ static int getExifOrientation(QByteArray &exifData)
|
||||
|
||||
// read offset to next IFD
|
||||
stream >> offset;
|
||||
if (stream.status() != QDataStream::Ok)
|
||||
return -1;
|
||||
if (offset == 0) // this is the last IFD
|
||||
break;
|
||||
return 0; // No Exif orientation was found
|
||||
}
|
||||
|
||||
// No Exif orientation was found
|
||||
return 0;
|
||||
// too many IFDs
|
||||
return -1;
|
||||
}
|
||||
|
||||
static QImageIOHandler::Transformations exif2Qt(int exifOrientation)
|
||||
|
@ -54,7 +54,6 @@
|
||||
|
||||
static const char m_qtTag[] = "Qt A11Y";
|
||||
static const char m_classErrorMsg[] = "Can't find class \"%s\"";
|
||||
static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -810,7 +810,7 @@ namespace QtAndroidInput
|
||||
#endif
|
||||
QAndroidInputContext *inputContext = QAndroidInputContext::androidInputContext();
|
||||
if (inputContext && qGuiApp)
|
||||
QMetaObject::invokeMethod(inputContext, "handleLocationChanged",
|
||||
QMetaObject::invokeMethod(inputContext, "handleLocationChanged", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(int, id), Q_ARG(int, x), Q_ARG(int, y));
|
||||
|
||||
}
|
||||
|
@ -122,8 +122,6 @@ static int m_desktopHeightPixels = 0;
|
||||
static double m_scaledDensity = 0;
|
||||
static double m_density = 1.0;
|
||||
|
||||
static volatile bool m_pauseApplication;
|
||||
|
||||
static AndroidAssetsFileEngineHandler *m_androidAssetsFileEngineHandler = nullptr;
|
||||
|
||||
|
||||
|
@ -578,6 +578,11 @@ void QAndroidInputContext::updateSelectionHandles()
|
||||
*/
|
||||
void QAndroidInputContext::handleLocationChanged(int handleId, int x, int y)
|
||||
{
|
||||
if (m_batchEditNestingLevel.load() || m_blockUpdateSelection)
|
||||
return;
|
||||
|
||||
finishComposingText();
|
||||
|
||||
auto im = qGuiApp->inputMethod();
|
||||
auto leftRect = im->cursorRectangle();
|
||||
// The handle is down of the cursor, but we want the position in the middle.
|
||||
|
@ -152,7 +152,7 @@ private:
|
||||
CursorHandleShowPopup = 3
|
||||
};
|
||||
CursorHandleShowMode m_cursorHandleShown;
|
||||
int m_batchEditNestingLevel;
|
||||
QAtomicInt m_batchEditNestingLevel;
|
||||
QObject *m_focusObject;
|
||||
};
|
||||
|
||||
|
@ -331,11 +331,12 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *
|
||||
|
||||
void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
|
||||
{
|
||||
item->nsItem().target = m_nativeMenu.delegate;
|
||||
item->nsItem().action = @selector(itemFired:);
|
||||
NSMenuItem *nativeItem = item->nsItem();
|
||||
nativeItem.target = m_nativeMenu.delegate;
|
||||
nativeItem.action = @selector(itemFired:);
|
||||
// Someone's adding new items after aboutToShow() was emitted
|
||||
if (isOpen() && item->menu() && item->nsItem())
|
||||
item->menu()->setAttachedItem(item->nsItem());
|
||||
if (isOpen() && nativeItem && item->menu())
|
||||
item->menu()->setAttachedItem(nativeItem);
|
||||
|
||||
item->setParentEnabled(isEnabled());
|
||||
|
||||
@ -348,15 +349,20 @@ void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
|
||||
beforeItem = itemOrNull(m_menuItems.indexOf(beforeItem) + 1);
|
||||
}
|
||||
|
||||
if (nativeItem.menu) {
|
||||
qWarning() << "Menu item" << item->text() << "already in menu" << QString::fromNSString(nativeItem.menu.title);
|
||||
return;
|
||||
}
|
||||
|
||||
if (beforeItem) {
|
||||
if (beforeItem->isMerged()) {
|
||||
qWarning("No non-merged before menu item found");
|
||||
return;
|
||||
}
|
||||
NSUInteger nativeIndex = [m_nativeMenu indexOfItem:beforeItem->nsItem()];
|
||||
[m_nativeMenu insertItem: item->nsItem() atIndex: nativeIndex];
|
||||
const NSInteger nativeIndex = [m_nativeMenu indexOfItem:beforeItem->nsItem()];
|
||||
[m_nativeMenu insertItem:nativeItem atIndex:nativeIndex];
|
||||
} else {
|
||||
[m_nativeMenu addItem: item->nsItem()];
|
||||
[m_nativeMenu addItem:nativeItem];
|
||||
}
|
||||
item->setMenuParent(this);
|
||||
}
|
||||
@ -413,9 +419,8 @@ void QCocoaMenu::syncMenuItem(QPlatformMenuItem *menuItem)
|
||||
return;
|
||||
}
|
||||
|
||||
bool wasMerged = cocoaItem->isMerged();
|
||||
NSMenu *oldMenu = wasMerged ? [[QCocoaMenuLoader sharedMenuLoader] applicationMenu] : m_nativeMenu;
|
||||
NSMenuItem *oldItem = [oldMenu itemWithTag:(NSInteger) cocoaItem];
|
||||
const bool wasMerged = cocoaItem->isMerged();
|
||||
NSMenuItem *oldItem = cocoaItem->nsItem();
|
||||
|
||||
if (cocoaItem->sync() != oldItem) {
|
||||
// native item was changed for some reason
|
||||
|
@ -288,7 +288,7 @@ NSMenuItem *QCocoaMenuItem::sync()
|
||||
}
|
||||
|
||||
default:
|
||||
qWarning() << "menu item" << m_text << "has unsupported role" << (int)m_role;
|
||||
qWarning() << "Menu item" << m_text << "has unsupported role" << m_role;
|
||||
}
|
||||
|
||||
if (mergeItem) {
|
||||
|
@ -3,7 +3,7 @@ TARGET = qdirectfb
|
||||
QT += \
|
||||
core-private gui-private \
|
||||
eventdispatcher_support-private service_support-private \
|
||||
fontdatabase_support-private egl_support-private
|
||||
fontdatabase_support-private
|
||||
|
||||
QMAKE_USE += directfb
|
||||
|
||||
@ -28,6 +28,7 @@ HEADERS = qdirectfbintegration.h \
|
||||
|
||||
# ### port the GL context
|
||||
contains(QT_CONFIG, directfb_egl) {
|
||||
QT += egl_support-private
|
||||
HEADERS += qdirectfb_egl.h
|
||||
SOURCES += qdirectfb_egl.cpp
|
||||
DEFINES += DIRECTFB_GL_EGL
|
||||
|
@ -44,7 +44,8 @@
|
||||
|
||||
#if defined(Q_CC_MINGW)
|
||||
# define HAS_UI_VIEW_SETTINGS_INTEROP
|
||||
#elif !defined(Q_CC_MSVC) || _MSC_VER >= 1900 // MSVC2013 is lacking both
|
||||
// Present from MSVC2015 + SDK 10 onwards
|
||||
#elif (!defined(Q_CC_MSVC) || _MSC_VER >= 1900) && NTDDI_VERSION >= 0xa000000
|
||||
# define HAS_UI_VIEW_SETTINGS_INTEROP
|
||||
# define HAS_UI_VIEW_SETTINGS
|
||||
#endif
|
||||
|
@ -486,6 +486,9 @@ public:
|
||||
QHash<ApplicationView2CallbackRemover, EventRegistrationToken> view2Tokens;
|
||||
ComPtr<IApplicationView2> view2;
|
||||
#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
|
||||
QAtomicPointer<QWinRTWindow> mouseGrabWindow;
|
||||
QAtomicPointer<QWinRTWindow> keyboardGrabWindow;
|
||||
QWindow *currentPressWindow = 0;
|
||||
};
|
||||
|
||||
// To be called from the XAML thread
|
||||
@ -877,6 +880,44 @@ void QWinRTScreen::lower(QWindow *window)
|
||||
handleExpose();
|
||||
}
|
||||
|
||||
bool QWinRTScreen::setMouseGrabWindow(QWinRTWindow *window, bool grab)
|
||||
{
|
||||
Q_D(QWinRTScreen);
|
||||
qCDebug(lcQpaWindows) << __FUNCTION__ << window
|
||||
<< "(" << window->window()->objectName() << "):" << grab;
|
||||
|
||||
if (!grab || window == nullptr)
|
||||
d->mouseGrabWindow = nullptr;
|
||||
else if (d->mouseGrabWindow != window)
|
||||
d->mouseGrabWindow = window;
|
||||
return grab;
|
||||
}
|
||||
|
||||
QWinRTWindow *QWinRTScreen::mouseGrabWindow() const
|
||||
{
|
||||
Q_D(const QWinRTScreen);
|
||||
return d->mouseGrabWindow;
|
||||
}
|
||||
|
||||
bool QWinRTScreen::setKeyboardGrabWindow(QWinRTWindow *window, bool grab)
|
||||
{
|
||||
Q_D(QWinRTScreen);
|
||||
qCDebug(lcQpaWindows) << __FUNCTION__ << window
|
||||
<< "(" << window->window()->objectName() << "):" << grab;
|
||||
|
||||
if (!grab || window == nullptr)
|
||||
d->keyboardGrabWindow = nullptr;
|
||||
else if (d->keyboardGrabWindow != window)
|
||||
d->keyboardGrabWindow = window;
|
||||
return grab;
|
||||
}
|
||||
|
||||
QWinRTWindow *QWinRTScreen::keyboardGrabWindow() const
|
||||
{
|
||||
Q_D(const QWinRTScreen);
|
||||
return d->keyboardGrabWindow;
|
||||
}
|
||||
|
||||
void QWinRTScreen::updateWindowTitle(const QString &title)
|
||||
{
|
||||
Q_D(QWinRTScreen);
|
||||
@ -1022,7 +1063,11 @@ HRESULT QWinRTScreen::onPointerEntered(ICoreWindow *, IPointerEventArgs *args)
|
||||
pointerPoint->get_Position(&point);
|
||||
QPoint pos(point.X * d->scaleFactor, point.Y * d->scaleFactor);
|
||||
|
||||
QWindowSystemInterface::handleEnterEvent(topWindow(), pos, pos);
|
||||
QWindow *targetWindow = topWindow();
|
||||
if (d->mouseGrabWindow)
|
||||
targetWindow = d->mouseGrabWindow.load()->window();
|
||||
|
||||
QWindowSystemInterface::handleEnterEvent(targetWindow, pos, pos);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
@ -1041,7 +1086,11 @@ HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *args)
|
||||
|
||||
d->touchPoints.remove(id);
|
||||
|
||||
QWindowSystemInterface::handleLeaveEvent(0);
|
||||
QWindow *targetWindow = nullptr;
|
||||
if (d->mouseGrabWindow)
|
||||
targetWindow = d->mouseGrabWindow.load()->window();
|
||||
|
||||
QWindowSystemInterface::handleLeaveEvent(targetWindow);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@ -1063,7 +1112,12 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
|
||||
QPointF localPos = pos;
|
||||
|
||||
const QPoint posPoint = pos.toPoint();
|
||||
QWindow *targetWindow = windowAt(posPoint);
|
||||
QWindow *windowUnderPointer = windowAt(posPoint);
|
||||
QWindow *targetWindow = windowUnderPointer;
|
||||
|
||||
if (d->mouseGrabWindow)
|
||||
targetWindow = d->mouseGrabWindow.load()->window();
|
||||
|
||||
if (targetWindow) {
|
||||
const QPointF globalPosDelta = pos - posPoint;
|
||||
localPos = targetWindow->mapFromGlobal(posPoint) + globalPosDelta;
|
||||
@ -1127,6 +1181,22 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
|
||||
if (isPressed)
|
||||
buttons |= Qt::XButton2;
|
||||
|
||||
// In case of a mouse grab we have to store the target of a press event
|
||||
// to be able to send one additional release event to this target when the mouse
|
||||
// button is released. This is a similar approach to AutoMouseCapture in the
|
||||
// windows qpa backend. Otherwise the release might not be propagated and the original
|
||||
// press event receiver considers a button to still be pressed, as in Qt Quick Controls 1
|
||||
// menus.
|
||||
if (buttons != Qt::NoButton && d->currentPressWindow == nullptr && !d->mouseGrabWindow)
|
||||
d->currentPressWindow = windowUnderPointer;
|
||||
if (!isPressed && d->currentPressWindow && d->mouseGrabWindow) {
|
||||
const QPointF globalPosDelta = pos - posPoint;
|
||||
const QPointF localPressPos = d->currentPressWindow->mapFromGlobal(posPoint) + globalPosDelta;
|
||||
|
||||
QWindowSystemInterface::handleMouseEvent(d->currentPressWindow, localPressPos, pos, buttons, mods);
|
||||
d->currentPressWindow = nullptr;
|
||||
}
|
||||
|
||||
QWindowSystemInterface::handleMouseEvent(targetWindow, localPos, pos, buttons, mods);
|
||||
|
||||
break;
|
||||
|
@ -83,6 +83,7 @@ class QTouchDevice;
|
||||
class QWinRTCursor;
|
||||
class QWinRTInputContext;
|
||||
class QWinRTScreenPrivate;
|
||||
class QWinRTWindow;
|
||||
class QWinRTScreen : public QPlatformScreen
|
||||
{
|
||||
public:
|
||||
@ -110,6 +111,12 @@ public:
|
||||
void raise(QWindow *window);
|
||||
void lower(QWindow *window);
|
||||
|
||||
bool setMouseGrabWindow(QWinRTWindow *window, bool grab);
|
||||
QWinRTWindow* mouseGrabWindow() const;
|
||||
|
||||
bool setKeyboardGrabWindow(QWinRTWindow *window, bool grab);
|
||||
QWinRTWindow* keyboardGrabWindow() const;
|
||||
|
||||
void updateWindowTitle(const QString &title);
|
||||
|
||||
ABI::Windows::UI::Core::ICoreWindow *coreWindow() const;
|
||||
|
@ -191,6 +191,11 @@ QWinRTWindow::~QWinRTWindow()
|
||||
});
|
||||
RETURN_VOID_IF_FAILED("Failed to completely destroy window resources, likely because the application is shutting down");
|
||||
|
||||
if (d->screen->mouseGrabWindow() == this)
|
||||
d->screen->setMouseGrabWindow(this, false);
|
||||
if (d->screen->keyboardGrabWindow() == this)
|
||||
d->screen->setKeyboardGrabWindow(this, false);
|
||||
|
||||
d->screen->removeWindow(window());
|
||||
|
||||
if (!d->surface)
|
||||
@ -384,6 +389,24 @@ void QWinRTWindow::setWindowState(Qt::WindowState state)
|
||||
d->state = state;
|
||||
}
|
||||
|
||||
bool QWinRTWindow::setMouseGrabEnabled(bool grab)
|
||||
{
|
||||
Q_D(QWinRTWindow);
|
||||
if (!isActive() && grab) {
|
||||
qWarning("%s: Not setting mouse grab for invisible window %s/'%s'",
|
||||
__FUNCTION__, window()->metaObject()->className(),
|
||||
qPrintable(window()->objectName()));
|
||||
return false;
|
||||
}
|
||||
return d->screen->setMouseGrabWindow(this, grab);
|
||||
}
|
||||
|
||||
bool QWinRTWindow::setKeyboardGrabEnabled(bool grab)
|
||||
{
|
||||
Q_D(QWinRTWindow);
|
||||
return d->screen->setKeyboardGrabWindow(this, grab);
|
||||
}
|
||||
|
||||
EGLSurface QWinRTWindow::eglSurface() const
|
||||
{
|
||||
Q_D(const QWinRTWindow);
|
||||
|
@ -70,6 +70,9 @@ public:
|
||||
qreal devicePixelRatio() const override;
|
||||
void setWindowState(Qt::WindowState state) override;
|
||||
|
||||
bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE;
|
||||
bool setKeyboardGrabEnabled(bool grab) Q_DECL_OVERRIDE;
|
||||
|
||||
EGLSurface eglSurface() const;
|
||||
void createEglSurface(EGLDisplay display, EGLConfig config);
|
||||
|
||||
|
@ -135,11 +135,13 @@ bool QGtk3Dialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWind
|
||||
|
||||
GdkWindow *gdkWindow = gtk_widget_get_window(gtkWidget);
|
||||
if (parent) {
|
||||
if (GDK_IS_X11_WINDOW(gdkWindow)) {
|
||||
GdkDisplay *gdkDisplay = gdk_window_get_display(gdkWindow);
|
||||
XSetTransientForHint(gdk_x11_display_get_xdisplay(gdkDisplay),
|
||||
gdk_x11_window_get_xid(gdkWindow),
|
||||
parent->winId());
|
||||
}
|
||||
}
|
||||
|
||||
if (modality != Qt::NonModal) {
|
||||
gdk_window_set_modal_hint(gdkWindow, true);
|
||||
|
@ -164,7 +164,7 @@ qtConfig(gui) {
|
||||
SUBDIRS += src_angle
|
||||
src_gui.depends += src_angle
|
||||
}
|
||||
qtConfig(png) {
|
||||
qtConfig(png):!qtConfig(system-png) {
|
||||
SUBDIRS += src_3rdparty_libpng
|
||||
src_3rdparty_freetype.depends += src_3rdparty_libpng
|
||||
src_gui.depends += src_3rdparty_libpng
|
||||
|
@ -477,9 +477,6 @@ int runMoc(int argc, char **argv)
|
||||
}
|
||||
moc.symbols += pp.preprocessed(moc.filename, &in);
|
||||
|
||||
// We obviously do not support MS extensions
|
||||
pp.macros.remove("_MSC_EXTENSIONS");
|
||||
|
||||
if (!pp.preprocessOnly) {
|
||||
// 2. parse
|
||||
moc.parse();
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 910 B |
Binary file not shown.
After Width: | Height: | Size: 910 B |
Binary file not shown.
After Width: | Height: | Size: 964 B |
Binary file not shown.
After Width: | Height: | Size: 910 B |
@ -188,7 +188,8 @@ private slots:
|
||||
void exifOrientation();
|
||||
|
||||
void exif_QTBUG45865();
|
||||
void exif_invalid_data_QTBUG46870();
|
||||
void exifInvalidData_data();
|
||||
void exifInvalidData();
|
||||
|
||||
void cleanupFunctions();
|
||||
|
||||
@ -3049,10 +3050,20 @@ void tst_QImage::exif_QTBUG45865()
|
||||
QCOMPARE(image.size(), QSize(5, 8));
|
||||
}
|
||||
|
||||
void tst_QImage::exif_invalid_data_QTBUG46870()
|
||||
void tst_QImage::exifInvalidData_data()
|
||||
{
|
||||
QTest::addColumn<bool>("$never used");
|
||||
QTest::newRow("QTBUG-46870");
|
||||
QTest::newRow("back_pointers");
|
||||
QTest::newRow("past_end");
|
||||
QTest::newRow("too_many_ifds");
|
||||
QTest::newRow("too_many_tags");
|
||||
}
|
||||
|
||||
void tst_QImage::exifInvalidData()
|
||||
{
|
||||
QImage image;
|
||||
QVERIFY(image.load(m_prefix + "jpeg_exif_invalid_data_QTBUG-46870.jpg"));
|
||||
QVERIFY(image.load(m_prefix + "jpeg_exif_invalid_data_" + QTest::currentDataTag() + ".jpg"));
|
||||
QVERIFY(!image.isNull());
|
||||
}
|
||||
|
||||
|
@ -194,6 +194,7 @@ public:
|
||||
|
||||
private slots:
|
||||
void cleanup();
|
||||
void qPointerUniqueId();
|
||||
void touchDisabledByDefault();
|
||||
void touchEventAcceptedByDefault();
|
||||
void touchBeginPropagatesWhenIgnored();
|
||||
@ -224,6 +225,44 @@ void tst_QTouchEvent::cleanup()
|
||||
QVERIFY(QGuiApplication::topLevelWindows().isEmpty());
|
||||
}
|
||||
|
||||
void tst_QTouchEvent::qPointerUniqueId()
|
||||
{
|
||||
QPointingDeviceUniqueId id1, id2;
|
||||
|
||||
QCOMPARE(id1.numericId(), Q_INT64_C(-1));
|
||||
QVERIFY(!id1.isValid());
|
||||
|
||||
QVERIFY( id1 == id2);
|
||||
QVERIFY(!(id1 != id2));
|
||||
|
||||
QSet<QPointingDeviceUniqueId> set; // compile test
|
||||
set.insert(id1);
|
||||
set.insert(id2);
|
||||
QCOMPARE(set.size(), 1);
|
||||
|
||||
|
||||
const auto id3 = QPointingDeviceUniqueId::fromNumericId(-1);
|
||||
QCOMPARE(id3.numericId(), Q_INT64_C(-1));
|
||||
QVERIFY(!id3.isValid());
|
||||
|
||||
QVERIFY( id1 == id3);
|
||||
QVERIFY(!(id1 != id3));
|
||||
|
||||
set.insert(id3);
|
||||
QCOMPARE(set.size(), 1);
|
||||
|
||||
|
||||
const auto id4 = QPointingDeviceUniqueId::fromNumericId(4);
|
||||
QCOMPARE(id4.numericId(), Q_INT64_C(4));
|
||||
QVERIFY(id4.isValid());
|
||||
|
||||
QVERIFY( id1 != id4);
|
||||
QVERIFY(!(id1 == id4));
|
||||
|
||||
set.insert(id4);
|
||||
QCOMPARE(set.size(), 2);
|
||||
}
|
||||
|
||||
void tst_QTouchEvent::touchDisabledByDefault()
|
||||
{
|
||||
// QWidget
|
||||
|
@ -46,6 +46,8 @@
|
||||
# include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
Q_DECLARE_METATYPE(QHostAddress::SpecialAddress)
|
||||
|
||||
class tst_QHostAddress : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -232,51 +234,55 @@ void tst_QHostAddress::setAddress_QString()
|
||||
void tst_QHostAddress::specialAddresses_data()
|
||||
{
|
||||
QTest::addColumn<QString>("text");
|
||||
QTest::addColumn<int>("address");
|
||||
QTest::addColumn<QHostAddress::SpecialAddress>("address");
|
||||
QTest::addColumn<bool>("result");
|
||||
|
||||
QTest::newRow("localhost_1") << QString("127.0.0.1") << (int)QHostAddress::LocalHost << true;
|
||||
QTest::newRow("localhost_2") << QString("127.0.0.2") << (int)QHostAddress::LocalHost << false;
|
||||
QTest::newRow("localhost_3") << QString("127.0.0.2") << (int)QHostAddress::LocalHostIPv6 << false;
|
||||
QTest::newRow("localhost_1") << QString("127.0.0.1") << QHostAddress::LocalHost << true;
|
||||
QTest::newRow("localhost_2") << QString("127.0.0.2") << QHostAddress::LocalHost << false;
|
||||
QTest::newRow("localhost_3") << QString("127.0.0.2") << QHostAddress::LocalHostIPv6 << false;
|
||||
|
||||
QTest::newRow("localhost_ipv6_4") << QString("::1") << (int)QHostAddress::LocalHostIPv6 << true;
|
||||
QTest::newRow("localhost_ipv6_5") << QString("::2") << (int)QHostAddress::LocalHostIPv6 << false;
|
||||
QTest::newRow("localhost_ipv6_6") << QString("::1") << (int)QHostAddress::LocalHost << false;
|
||||
QTest::newRow("localhost_ipv6_4") << QString("::1") << QHostAddress::LocalHostIPv6 << true;
|
||||
QTest::newRow("localhost_ipv6_5") << QString("::2") << QHostAddress::LocalHostIPv6 << false;
|
||||
QTest::newRow("localhost_ipv6_6") << QString("::1") << QHostAddress::LocalHost << false;
|
||||
|
||||
QTest::newRow("null_1") << QString("") << (int)QHostAddress::Null << true;
|
||||
QTest::newRow("null_2") << QString("bjarne") << (int)QHostAddress::Null << true;
|
||||
QTest::newRow("null_1") << QString("") << QHostAddress::Null << true;
|
||||
QTest::newRow("null_2") << QString("bjarne") << QHostAddress::Null << true;
|
||||
|
||||
QTest::newRow("compare_from_null") << QString("") << (int)QHostAddress::Broadcast << false;
|
||||
QTest::newRow("compare_from_null") << QString("") << QHostAddress::Broadcast << false;
|
||||
|
||||
QTest::newRow("broadcast_1") << QString("255.255.255.255") << (int)QHostAddress::Any << false;
|
||||
QTest::newRow("broadcast_2") << QString("255.255.255.255") << (int)QHostAddress::Broadcast << true;
|
||||
QTest::newRow("broadcast_1") << QString("255.255.255.255") << QHostAddress::Any << false;
|
||||
QTest::newRow("broadcast_2") << QString("255.255.255.255") << QHostAddress::Broadcast << true;
|
||||
|
||||
QTest::newRow("any_ipv6") << QString("::") << (int)QHostAddress::AnyIPv6 << true;
|
||||
QTest::newRow("any_ipv4") << QString("0.0.0.0") << (int)QHostAddress::AnyIPv4 << true;
|
||||
QTest::newRow("any_ipv6") << QString("::") << QHostAddress::AnyIPv6 << true;
|
||||
QTest::newRow("any_ipv4") << QString("0.0.0.0") << QHostAddress::AnyIPv4 << true;
|
||||
|
||||
QTest::newRow("dual_not_ipv6") << QString("::") << (int)QHostAddress::Any << false;
|
||||
QTest::newRow("dual_not_ipv4") << QString("0.0.0.0") << (int)QHostAddress::Any << false;
|
||||
QTest::newRow("dual_not_ipv6") << QString("::") << QHostAddress::Any << false;
|
||||
QTest::newRow("dual_not_ipv4") << QString("0.0.0.0") << QHostAddress::Any << false;
|
||||
}
|
||||
|
||||
|
||||
void tst_QHostAddress::specialAddresses()
|
||||
{
|
||||
QFETCH(QString, text);
|
||||
QFETCH(int, address);
|
||||
QFETCH(QHostAddress::SpecialAddress, address);
|
||||
QFETCH(bool, result);
|
||||
QVERIFY((QHostAddress(text) == (QHostAddress::SpecialAddress)address) == result);
|
||||
QCOMPARE(QHostAddress(text) == address, result);
|
||||
|
||||
//check special address equal to itself (QTBUG-22898), note two overloads of operator==
|
||||
QVERIFY(QHostAddress((QHostAddress::SpecialAddress)address) == QHostAddress((QHostAddress::SpecialAddress)address));
|
||||
QVERIFY(QHostAddress((QHostAddress::SpecialAddress)address) == (QHostAddress::SpecialAddress)address);
|
||||
QVERIFY(QHostAddress(address) == QHostAddress(address));
|
||||
QVERIFY(QHostAddress(address) == address);
|
||||
QVERIFY(!(QHostAddress(address) != QHostAddress(address)));
|
||||
QVERIFY(!(QHostAddress(address) != address));
|
||||
|
||||
{
|
||||
QHostAddress ha;
|
||||
ha.setAddress(address);
|
||||
QVERIFY(ha == address);
|
||||
}
|
||||
|
||||
QHostAddress setter;
|
||||
setter.setAddress(text);
|
||||
if (result) {
|
||||
QVERIFY(setter == (QHostAddress::SpecialAddress) address);
|
||||
} else {
|
||||
QVERIFY(!((QHostAddress::SpecialAddress) address == setter));
|
||||
}
|
||||
QCOMPARE(setter == address, result);
|
||||
}
|
||||
|
||||
|
||||
@ -359,6 +365,11 @@ void tst_QHostAddress::isEqual()
|
||||
QCOMPARE(second.isEqual(first, QHostAddress::ConversionModeFlag(flags)), result);
|
||||
}
|
||||
|
||||
QT_WARNING_PUSH
|
||||
#ifdef QT_WARNING_DISABLE_DEPRECATED
|
||||
QT_WARNING_DISABLE_DEPRECATED
|
||||
#endif
|
||||
|
||||
void tst_QHostAddress::assignment()
|
||||
{
|
||||
QHostAddress address;
|
||||
@ -379,6 +390,8 @@ void tst_QHostAddress::assignment()
|
||||
#endif // !Q_OS_WINRT
|
||||
}
|
||||
|
||||
QT_WARNING_POP
|
||||
|
||||
void tst_QHostAddress::scopeId()
|
||||
{
|
||||
QHostAddress address("fe80::2e0:4cff:fefb:662a%eth0");
|
||||
|
@ -132,6 +132,7 @@ private slots:
|
||||
void taskQTBUG53205_crashReparentNested();
|
||||
#ifdef Q_OS_MACOS
|
||||
void taskQTBUG56275_reinsertMenuInParentlessQMenuBar();
|
||||
void QTBUG_57404_existingMenuItemException();
|
||||
#endif
|
||||
void taskQTBUG55966_subMenuRemoved();
|
||||
|
||||
@ -1540,6 +1541,31 @@ void tst_QMenuBar::taskQTBUG56275_reinsertMenuInParentlessQMenuBar()
|
||||
|
||||
QVERIFY(tst_qmenubar_taskQTBUG56275(&menubar));
|
||||
}
|
||||
|
||||
void tst_QMenuBar::QTBUG_57404_existingMenuItemException()
|
||||
{
|
||||
QMainWindow mw1;
|
||||
QMainWindow mw2;
|
||||
mw1.show();
|
||||
mw2.show();
|
||||
|
||||
QMenuBar *mb = new QMenuBar(&mw1);
|
||||
mw1.setMenuBar(mb);
|
||||
mb->show();
|
||||
QMenu *editMenu = new QMenu(QLatin1String("Edit"), &mw1);
|
||||
mb->addMenu(editMenu);
|
||||
QAction *copyAction = editMenu->addAction("&Copy");
|
||||
copyAction->setShortcut(QKeySequence("Ctrl+C"));
|
||||
QTest::ignoreMessage(QtWarningMsg, "Menu item \"&Copy\" has unsupported role QPlatformMenuItem::MenuRole(NoRole)");
|
||||
copyAction->setMenuRole(QAction::NoRole);
|
||||
|
||||
QVERIFY(QTest::qWaitForWindowExposed(&mw2));
|
||||
QTest::qWait(100);
|
||||
mw2.close();
|
||||
mw1.activateWindow();
|
||||
QTest::qWait(100);
|
||||
// No crash, all fine. Ideally, there should be only one warning.
|
||||
}
|
||||
#endif // Q_OS_MACOS
|
||||
|
||||
void tst_QMenuBar::taskQTBUG55966_subMenuRemoved()
|
||||
|
Loading…
Reference in New Issue
Block a user