Merge remote-tracking branch 'origin/5.12' into dev

Change-Id: I2715ee7c694e5579bcedc7bab0ae68e79d5fd0b6
bb10
Qt Forward Merge Bot 2018-10-13 00:07:19 +02:00
commit fedcaf0256
32 changed files with 597 additions and 458 deletions

2
configure vendored
View File

@ -771,7 +771,7 @@ setBootstrapVariable()
echo "RM_RF = rm -rf" >> "$mkfile"
case `basename "$PLATFORM"` in
win32-g++*)
win32-*g++*)
cat "$in_mkfile.win32" >> "$mkfile"
;;
*)

View File

@ -730,6 +730,7 @@
"headersclean": {
"label": "Check for clean headers",
"autoDetect": "features.developer-build",
"condition": "!config.wasm",
"output": [ "privateConfig" ]
},
"framework": {

View File

@ -1221,13 +1221,43 @@ defineReplace(qtConfReportArch) {
return("$$arch, CPU features: $$subarch")
}
defineReplace(qtConfReportCompiler) {
clang_cl: {
return("clang-cl $${QMAKE_CLANG_MAJOR_VERSION}.$${QMAKE_CLANG_MINOR_VERSION}.$${QMAKE_CLANG_PATCH_VERSION}")
} else: clang {
!isEmpty(QMAKE_APPLE_CLANG_MAJOR_VERSION) {
return("clang (Apple) $${QMAKE_APPLE_CLANG_MAJOR_VERSION}.$${QMAKE_APPLE_CLANG_MINOR_VERSION}.$${QMAKE_APPLE_CLANG_PATCH_VERSION}")
} else {
return("clang $${QMAKE_CLANG_MAJOR_VERSION}.$${QMAKE_CLANG_MINOR_VERSION}.$${QMAKE_CLANG_PATCH_VERSION}")
}
} else: intel_icc {
return("intel_icc $$QMAKE_ICC_VER")
} else: intel_icl {
return("intel_icl $$QMAKE_ICC_VER")
} else: rim_qcc {
return("rim_qcc $${QMAKE_GCC_MAJOR_VERSION}.$${QMAKE_GCC_MINOR_VERSION}.$${QMAKE_GCC_PATCH_VERSION}")
} else: gcc {
return("gcc $${QMAKE_GCC_MAJOR_VERSION}.$${QMAKE_GCC_MINOR_VERSION}.$${QMAKE_GCC_PATCH_VERSION}")
} else: msvc {
return("msvc $$QMAKE_MSC_FULL_VER")
} else: ghs {
return("ghs $$QMAKE_GHS_VERSION")
} else {
return("unknown ($$QMAKE_COMPILER)")
}
}
defineTest(qtConfReport_buildTypeAndConfig) {
!$$qtConfEvaluate("features.cross_compile") {
qtConfAddReport("Build type: $$[QMAKE_SPEC] ($$qtConfReportArch(architecture))")
qtConfAddReport("Compiler: $$qtConfReportCompiler()")
} else {
qtConfAddReport("Building on: $$[QMAKE_SPEC] ($$qtConfReportArch(host_architecture))")
qtConfAddReport("Building for: $$[QMAKE_XSPEC] ($$qtConfReportArch(architecture))")
qtConfAddReport("Target compiler: $$qtConfReportCompiler()")
}
qtConfAddReport()
qtConfAddReport("Configuration: $$eval($${currentConfig}.output.privatePro.append.CONFIG) $$eval($${currentConfig}.output.publicPro.append.QT_CONFIG)")
qtConfAddReport()

View File

@ -29,12 +29,8 @@ qtHaveModule(widgets) {
}
qtConfig(openssl) {
SUBDIRS += \
securesocketclient \
secureudpserver \
secureudpclient
}
qtConfig(openssl): SUBDIRS += securesocketclient
qtConfig(dtls): SUBDIRS += secureudpserver secureudpclient
qtConfig(sctp): SUBDIRS += multistreamserver multistreamclient
}

View File

@ -40,7 +40,11 @@ QMAKE_CFLAGS += -DANDROID_HAS_WSTRING --sysroot=$$NDK_ROOT/sysroot \
ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$ANDROID_TARGET_ARCH
ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so
ANDROID_CXX_STL_LIBS = -lc++
exists($$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so): \
ANDROID_CXX_STL_LIBS = -lc++
else: \
ANDROID_CXX_STL_LIBS = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so.$$replace(ANDROID_PLATFORM, "android-", "")
QMAKE_CFLAGS_OPTIMIZE_SIZE = -Oz

View File

@ -907,9 +907,9 @@
Platform-specific variables follow the naming pattern of the
variables which they extend or modify, but include the name of the relevant
platform in their name. For example, \c QMAKE_LIBS can be used to specify a list
of libraries that a project needs to link against, and \c QMAKE_LIBS_X11 can be
used to extend or override this list.
platform in their name. For example, a makespec may use \c QMAKE_LIBS
to specify a list of libraries that each project needs to link against,
and \c QMAKE_LIBS_X11 would be used to extend this list.
\target CONFIG
\section1 CONFIG
@ -1320,6 +1320,19 @@
\snippet code/doc_src_qmake-manual.pro 39
\target LIBS_PRIVATE
\section1 LIBS_PRIVATE
Specifies a list of libraries to be linked privately into the project.
The behavior of this variable is identical to \l LIBS, except that
shared library projects built for Unix do not expose these dependencies
in their link interface.
The effect of this is that if project C depends on library B which
depends on library A privately, but C also wants to use symbols from A
directly, it needs to link to A explicitly. Put differently, libraries
linked privately are not exposed transitively at build time.
\target LITERAL_HASH
\section1 LITERAL_HASH
@ -2048,7 +2061,19 @@
\section1 QMAKE_LIBDIR
Specifies a list of system library paths.
Specifies a list of library search paths for all projects.
The value of this variable is typically handled by qmake
or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
To specify additional search paths in project files,
use \l LIBS like that, instead:
\badcode
LIBS += -L/path/to/libraries
\endcode
\section1 QMAKE_LIBDIR_POST
Specifies a list of system library search paths for all projects.
The value of this variable is typically handled by qmake
or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
@ -2098,10 +2123,22 @@
\section1 QMAKE_LIBS
Specifies all project libraries. The value of this variable
is typically handled by qmake or
Specifies additional libraries each project needs to link against.
The value of this variable is typically handled by qmake or
\l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
To specify libraries in a project file, use \l LIBS instead.
\section1 QMAKE_LIBS_PRIVATE
Specifies additional private libraries each project needs to
link against.
The value of this variable is typically handled by qmake or
\l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
To specify private libraries in a library project file,
use \l LIBS_PRIVATE instead.
\section1 QMAKE_LIBS_EGL
Specifies all EGL libraries when building Qt with OpenGL/ES

View File

@ -829,7 +829,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES
ProStringList &libdirs = project->values("QMAKE_PBX_LIBPATHS"),
&frameworkdirs = project->values("QMAKE_FRAMEWORKPATH");
static const char * const libs[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr };
static const char * const libs[] = { "LIBS", "LIBS_PRIVATE",
"QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr };
for (int i = 0; libs[i]; i++) {
tmp = project->values(libs[i]);
for(int x = 0; x < tmp.count();) {
@ -1695,6 +1696,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\t\t\t\t" << writeSettings("OTHER_LDFLAGS",
fixListForOutput("SUBLIBS")
+ fixListForOutput("QMAKE_LFLAGS")
+ fixListForOutput(fixLibFlags("LIBS"))
+ fixListForOutput(fixLibFlags("LIBS_PRIVATE"))
+ fixListForOutput(fixLibFlags("QMAKE_LIBS"))
+ fixListForOutput(fixLibFlags("QMAKE_LIBS_PRIVATE")),
SettingsAsList, 6) << ";\n";

View File

@ -1012,12 +1012,10 @@ MakefileGenerator::writePrlFile(QTextStream &t)
t << "QMAKE_PRL_VERSION = " << project->first("VERSION") << endl;
if(project->isActiveConfig("staticlib") || project->isActiveConfig("explicitlib")) {
ProStringList libs;
if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
libs = project->values("QMAKE_INTERNAL_PRL_LIBS");
if (!project->isActiveConfig("staticlib"))
libs << "LIBS" << "QMAKE_LIBS";
else
libs << "QMAKE_LIBS"; //obvious one
if(project->isActiveConfig("staticlib"))
libs << "QMAKE_LIBS_PRIVATE";
libs << "LIBS" << "LIBS_PRIVATE" << "QMAKE_LIBS" << "QMAKE_LIBS_PRIVATE";
t << "QMAKE_PRL_LIBS =";
for (ProStringList::Iterator it = libs.begin(); it != libs.end(); ++it)
t << qv(project->values((*it).toKey()));
@ -3348,10 +3346,9 @@ MakefileGenerator::writePkgConfigFile()
if (project->isActiveConfig("staticlib")) {
ProStringList libs;
if (!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
libs = project->values("QMAKE_INTERNAL_PRL_LIBS");
else
libs << "QMAKE_LIBS"; //obvious one
libs << "LIBS"; // FIXME: this should not be conditional on staticlib
libs << "LIBS_PRIVATE";
libs << "QMAKE_LIBS"; // FIXME: this should not be conditional on staticlib
libs << "QMAKE_LIBS_PRIVATE";
libs << "QMAKE_LFLAGS_THREAD"; //not sure about this one, but what about things like -pthread?
t << "Libs.private:";

View File

@ -37,6 +37,17 @@
QT_BEGIN_NAMESPACE
ProStringList UnixMakefileGenerator::libdirToFlags(const ProKey &key)
{
ProStringList results;
for (const auto &libdir : qAsConst(project->values(key))) {
if (!project->isEmpty("QMAKE_LFLAGS_RPATH") && project->isActiveConfig("rpath_libdirs"))
project->values("QMAKE_LFLAGS") += var("QMAKE_LFLAGS_RPATH") + libdir;
results.append("-L" + escapeFilePath(libdir));
}
return results;
}
void
UnixMakefileGenerator::init()
{
@ -80,8 +91,6 @@ UnixMakefileGenerator::init()
}
project->values("QMAKE_ORIG_DESTDIR") = project->values("DESTDIR");
project->values("QMAKE_LIBS") += project->values("LIBS");
project->values("QMAKE_LIBS_PRIVATE") += project->values("LIBS_PRIVATE");
if((!project->isEmpty("QMAKE_LIB_FLAG") && !project->isActiveConfig("staticlib")) ||
(project->isActiveConfig("qt") && project->isActiveConfig("plugin"))) {
if(configs.indexOf("dll") == -1) configs.append("dll");
@ -95,21 +104,13 @@ UnixMakefileGenerator::init()
project->isActiveConfig("dll"))
project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_PREBIND");
project->values("QMAKE_INCDIR") += project->values("QMAKE_INCDIR_POST");
project->values("QMAKE_LIBDIR") += project->values("QMAKE_LIBDIR_POST");
project->values("QMAKE_RPATHDIR") += project->values("QMAKE_RPATHDIR_POST");
project->values("QMAKE_RPATHLINKDIR") += project->values("QMAKE_RPATHLINKDIR_POST");
if(!project->isEmpty("QMAKE_INCDIR"))
project->values("INCLUDEPATH") += project->values("QMAKE_INCDIR");
ProStringList ldadd;
if(!project->isEmpty("QMAKE_LIBDIR")) {
const ProStringList &libdirs = project->values("QMAKE_LIBDIR");
for(int i = 0; i < libdirs.size(); ++i) {
if(!project->isEmpty("QMAKE_LFLAGS_RPATH") && project->isActiveConfig("rpath_libdirs"))
project->values("QMAKE_LFLAGS") += var("QMAKE_LFLAGS_RPATH") + libdirs[i];
project->values("QMAKE_LIBDIR_FLAGS") += "-L" + escapeFilePath(libdirs[i]);
}
}
ldadd += project->values("QMAKE_LIBDIR_FLAGS");
// The order of the next two lines is relevant due to side effect on QMAKE_LFLAGS.
ProStringList ldadd = project->values("QMAKE_LIBDIR_FLAGS") + libdirToFlags("QMAKE_LIBDIR");
ProStringList ldaddpost = libdirToFlags("QMAKE_LIBDIR_POST");
if (project->isActiveConfig("mac")) {
if (!project->isEmpty("QMAKE_FRAMEWORKPATH")) {
const ProStringList &fwdirs = project->values("QMAKE_FRAMEWORKPATH");
@ -118,8 +119,10 @@ UnixMakefileGenerator::init()
}
ldadd += project->values("QMAKE_FRAMEWORKPATH_FLAGS");
}
ProStringList &qmklibs = project->values("QMAKE_LIBS");
ProStringList &qmklibs = project->values("LIBS");
qmklibs = ldadd + qmklibs;
ProStringList &qmklibspost = project->values("QMAKE_LIBS");
qmklibspost = ldaddpost + qmklibspost;
if (!project->isEmpty("QMAKE_RPATHDIR") && !project->isEmpty("QMAKE_LFLAGS_RPATH")) {
const ProStringList &rpathdirs = project->values("QMAKE_RPATHDIR");
for (int i = 0; i < rpathdirs.size(); ++i) {
@ -300,35 +303,11 @@ UnixMakefileGenerator::init()
}
init2();
project->values("QMAKE_INTERNAL_PRL_LIBS") << "QMAKE_LIBS";
ProString target = project->first("TARGET");
int slsh = target.lastIndexOf(Option::dir_sep);
if (slsh != -1)
target.chopFront(slsh + 1);
project->values("LIB_TARGET").prepend(target);
if(!project->isEmpty("QMAKE_MAX_FILES_PER_AR")) {
bool ok;
int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(&ok);
ProStringList ar_sublibs, objs = project->values("OBJECTS");
if(ok && max_files > 5 && max_files < (int)objs.count()) {
QString lib;
for(int i = 0, obj_cnt = 0, lib_cnt = 0; i != objs.size(); ++i) {
if((++obj_cnt) >= max_files) {
if(lib_cnt) {
lib.sprintf("lib%s-tmp%d.a",
project->first("QMAKE_ORIG_TARGET").toLatin1().constData(), lib_cnt);
ar_sublibs << lib;
obj_cnt = 0;
}
lib_cnt++;
}
}
}
if(!ar_sublibs.isEmpty()) {
project->values("QMAKE_AR_SUBLIBS") = ar_sublibs;
project->values("QMAKE_INTERNAL_PRL_LIBS") << "QMAKE_AR_SUBLIBS";
}
}
}
QStringList
@ -420,7 +399,8 @@ UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
libdirs.append(QMakeLocalFileName(dlib.toQString()));
frameworkdirs.append(QMakeLocalFileName("/System/Library/Frameworks"));
frameworkdirs.append(QMakeLocalFileName("/Library/Frameworks"));
static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr };
static const char * const lflags[] = { "LIBS", "LIBS_PRIVATE",
"QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr };
for (int i = 0; lflags[i]; i++) {
ProStringList &l = project->values(lflags[i]);
for (ProStringList::Iterator it = l.begin(); it != l.end(); ) {

View File

@ -66,6 +66,7 @@ protected:
private:
void init2();
ProStringList libdirToFlags(const ProKey &key);
};
inline UnixMakefileGenerator::~UnixMakefileGenerator()

View File

@ -213,7 +213,9 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
if(!project->isActiveConfig("staticlib")) {
t << "LINK = " << var("QMAKE_LINK") << endl;
t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl;
t << "LIBS = $(SUBLIBS) " << fixLibFlags("QMAKE_LIBS").join(' ') << ' '
t << "LIBS = $(SUBLIBS) " << fixLibFlags("LIBS").join(' ') << ' '
<< fixLibFlags("LIBS_PRIVATE").join(' ') << ' '
<< fixLibFlags("QMAKE_LIBS").join(' ') << ' '
<< fixLibFlags("QMAKE_LIBS_PRIVATE").join(' ') << endl;
}
@ -690,56 +692,20 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
QString destdir_r = project->first("DESTDIR").toQString();
QString destdir_d = escapeDependencyPath(destdir_r);
QString destdir = escapeFilePath(destdir_r);
allDeps = ' ' + destdir_d + depVar("TARGET")
+ varGlue("QMAKE_AR_SUBLIBS", ' ' + destdir_d, ' ' + destdir_d, "");
t << "staticlib: " << destdir_d << "$(TARGET)\n\n";
if(project->isEmpty("QMAKE_AR_SUBLIBS")) {
t << destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS")
<< " $(OBJECTS) $(OBJCOMP) " << depVar("POST_TARGETDEPS") << "\n\t";
if(!destdir.isEmpty())
t << mkdir_p_asstring(destdir, false) << "\n\t";
if (!project->isEmpty("QMAKE_PRE_LINK"))
t << var("QMAKE_PRE_LINK") << "\n\t";
t << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t"
<< var("QMAKE_AR_CMD") << "\n";
if(!project->isEmpty("QMAKE_POST_LINK"))
t << "\t" << var("QMAKE_POST_LINK") << "\n";
if(!project->isEmpty("QMAKE_RANLIB"))
t << "\t$(RANLIB) " << destdir << "$(TARGET)\n";
} else {
int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt();
ProStringList objs = project->values("OBJECTS") + project->values("OBJCOMP"),
libs = project->values("QMAKE_AR_SUBLIBS");
libs.prepend("$(TARGET)");
for (ProStringList::Iterator libit = libs.begin(), objit = objs.begin();
libit != libs.end(); ++libit) {
ProStringList build;
for(int cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++)
build << (*objit);
QString ar;
ProString lib = destdir + escapeFilePath(*libit);
if((*libit) == "$(TARGET)") {
t << destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS")
<< ' ' << depVar("POST_TARGETDEPS") << valList(escapeDependencyPaths(build)) << "\n\t";
ar = project->first("QMAKE_AR_CMD").toQString();
ar.replace(QLatin1String("$(OBJECTS)"), escapeFilePaths(build).join(' '));
} else {
t << destdir_d << escapeDependencyPath(*libit) << ": "
<< valList(escapeDependencyPaths(build)) << "\n\t";
ar = "$(AR) " + lib + ' ' + escapeFilePaths(build).join(' ');
}
if(!destdir.isEmpty())
t << mkdir_p_asstring(destdir, false) << "\n\t";
if (!project->isEmpty("QMAKE_PRE_LINK"))
t << var("QMAKE_PRE_LINK") << "\n\t";
t << "-$(DEL_FILE) " << lib << "\n\t"
<< ar << "\n";
if(!project->isEmpty("QMAKE_POST_LINK"))
t << "\t" << var("QMAKE_POST_LINK") << "\n";
if(!project->isEmpty("QMAKE_RANLIB"))
t << "\t$(RANLIB) " << lib << "\n";
}
}
allDeps = ' ' + destdir_d + depVar("TARGET");
t << "staticlib: " << destdir_d << "$(TARGET)\n\n"
<< destdir_d << depVar("TARGET") << ": " << depVar("PRE_TARGETDEPS")
<< " $(OBJECTS) $(OBJCOMP) " << depVar("POST_TARGETDEPS") << "\n\t";
if (!destdir.isEmpty())
t << mkdir_p_asstring(destdir, false) << "\n\t";
if (!project->isEmpty("QMAKE_PRE_LINK"))
t << var("QMAKE_PRE_LINK") << "\n\t";
t << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t"
<< var("QMAKE_AR_CMD") << "\n";
if (!project->isEmpty("QMAKE_POST_LINK"))
t << "\t" << var("QMAKE_POST_LINK") << "\n";
if (!project->isEmpty("QMAKE_RANLIB"))
t << "\t$(RANLIB) " << destdir << "$(TARGET)\n";
t << endl << endl;
}
@ -1515,10 +1481,7 @@ UnixMakefileGenerator::writeLibtoolFile()
t << "# Libraries that this one depends upon.\n";
ProStringList libs;
if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
libs = project->values("QMAKE_INTERNAL_PRL_LIBS");
else
libs << "QMAKE_LIBS"; //obvious one
libs << "LIBS" << "QMAKE_LIBS";
t << "dependency_libs='";
for (ProStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it)
t << fixLibFlags((*it).toKey()).join(' ') << ' ';

View File

@ -131,22 +131,25 @@ QString MingwMakefileGenerator::installRoot() const
return QStringLiteral("$(INSTALL_ROOT:@msyshack@%=%)");
}
void createLdObjectScriptFile(const QString &fileName, const ProStringList &objList)
void createLdResponseFile(const QString &fileName, const ProStringList &objList)
{
QString filePath = Option::output_dir + QDir::separator() + fileName;
QFile file(filePath);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream t(&file);
t << "INPUT(\n";
for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) {
QString path = (*it).toQString();
// ### quoting?
if (QDir::isRelativePath(path))
t << "./" << path << endl;
else
t << path << endl;
// In response files, whitespace and special characters are
// escaped with a backslash; backslashes themselves can either
// be escaped into double backslashes, or, as this is a list of
// path names, converted to forward slashes.
path.replace(QLatin1Char('\\'), QLatin1String("/"))
.replace(QLatin1Char(' '), QLatin1String("\\ "))
.replace(QLatin1Char('\t'), QLatin1String("\\\t"))
.replace(QLatin1Char('"'), QLatin1String("\\\""))
.replace(QLatin1Char('\''), QLatin1String("\\'"));
t << path << endl;
}
t << ");\n";
t.flush();
file.close();
}
@ -206,7 +209,7 @@ void MingwMakefileGenerator::init()
processVars();
project->values("QMAKE_LIBS") += project->values("RES_FILE");
project->values("LIBS") += project->values("RES_FILE");
if (project->isActiveConfig("dll")) {
QString destDir = "";
@ -282,6 +285,8 @@ void MingwMakefileGenerator::writeLibsPart(QTextStream &t)
t << "LINKER = " << var("QMAKE_LINK") << endl;
t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl;
t << "LIBS = "
<< fixLibFlags("LIBS").join(' ') << ' '
<< fixLibFlags("LIBS_PRIVATE").join(' ') << ' '
<< fixLibFlags("QMAKE_LIBS").join(' ') << ' '
<< fixLibFlags("QMAKE_LIBS_PRIVATE").join(' ') << endl;
}
@ -307,14 +312,13 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t)
createArObjectScriptFile(ar_script_file, var("DEST_TARGET"), project->values("OBJECTS"));
objectsLinkLine = ar_cmd + " -M < " + escapeFilePath(ar_script_file);
} else {
QString ld_script_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
if (!var("BUILD_NAME").isEmpty()) {
ld_script_file += "." + var("BUILD_NAME");
}
QString ld_response_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET");
if (!var("BUILD_NAME").isEmpty())
ld_response_file += "." + var("BUILD_NAME");
if (!var("MAKEFILE").isEmpty())
ld_script_file += "." + var("MAKEFILE");
createLdObjectScriptFile(ld_script_file, project->values("OBJECTS"));
objectsLinkLine = escapeFilePath(ld_script_file);
ld_response_file += "." + var("MAKEFILE");
createLdResponseFile(ld_response_file, project->values("OBJECTS"));
objectsLinkLine = "@" + escapeFilePath(ld_response_file);
}
Win32MakefileGenerator::writeObjectsPart(t);
}

View File

@ -383,7 +383,7 @@ void NmakeMakefileGenerator::init()
processVars();
project->values("QMAKE_LIBS") += project->values("RES_FILE");
project->values("LIBS") += project->values("RES_FILE");
if (!project->values("DEF_FILE").isEmpty()) {
QString defFileName = fileFixify(project->first("DEF_FILE").toQString());

View File

@ -457,9 +457,8 @@ ProStringList VcprojGenerator::collectDependencies(QMakeProject *proj, QHash<QSt
newDep->dependencies << "idc.exe";
// Add all unknown libs to the deps
QStringList where = QStringList() << "QMAKE_LIBS" << "QMAKE_LIBS_PRIVATE";
if (!tmp_proj.isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
where = tmp_proj.values("QMAKE_INTERNAL_PRL_LIBS").toQStringList();
QStringList where = QStringList() << "LIBS" << "LIBS_PRIVATE"
<< "QMAKE_LIBS" << "QMAKE_LIBS_PRIVATE";
for (QStringList::ConstIterator wit = where.begin();
wit != where.end(); ++wit) {
const ProStringList &l = tmp_proj.values(ProKey(*wit));
@ -750,7 +749,7 @@ void VcprojGenerator::init()
projectTarget = Application;
} else if(project->first("TEMPLATE") == "vclib") {
if(project->isActiveConfig("staticlib")) {
project->values("QMAKE_LIBS") += project->values("RES_FILE");
project->values("LIBS") += project->values("RES_FILE");
projectTarget = StaticLib;
} else
projectTarget = SharedLib;
@ -1086,7 +1085,8 @@ void VcprojGenerator::initLinkerTool()
if (!project->values("DEF_FILE").isEmpty())
conf.linker.ModuleDefinitionFile = project->first("DEF_FILE").toQString();
static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr };
static const char * const lflags[] = { "LIBS", "LIBS_PRIVATE",
"QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr };
for (int i = 0; lflags[i]; i++) {
const auto libs = fixLibFlags(lflags[i]);
for (const ProString &lib : libs) {
@ -1181,7 +1181,8 @@ void VcprojGenerator::initDeploymentTool()
if (!dllPaths.isEmpty() &&
!(conf.WinRT && project->first("MSVC_VER").toQString() == "14.0")) {
// FIXME: This code should actually resolve the libraries from all Qt modules.
ProStringList arg = project->values("QMAKE_LIBS") + project->values("QMAKE_LIBS_PRIVATE");
ProStringList arg = project->values("LIBS") + project->values("LIBS_PRIVATE")
+ project->values("QMAKE_LIBS") + project->values("QMAKE_LIBS_PRIVATE");
bool qpaPluginDeployed = false;
for (ProStringList::ConstIterator it = arg.constBegin(); it != arg.constEnd(); ++it) {
QString dllName = (*it).toQString();

View File

@ -84,7 +84,8 @@ Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags)
if (impexts.isEmpty())
impexts = project->values("QMAKE_EXTENSION_STATICLIB");
QList<QMakeLocalFileName> dirs;
static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr };
static const char * const lflags[] = { "LIBS", "LIBS_PRIVATE",
"QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", nullptr };
for (int i = 0; lflags[i]; i++) {
ProStringList &l = project->values(lflags[i]);
for (ProStringList::Iterator it = l.begin(); it != l.end();) {
@ -225,8 +226,8 @@ void Win32MakefileGenerator::processVars()
libs << QLatin1String("-L") + lib;
}
}
project->values("QMAKE_LIBS") += libs + project->values("LIBS");
project->values("QMAKE_LIBS_PRIVATE") += project->values("LIBS_PRIVATE");
ProStringList &qmklibs = project->values("LIBS");
qmklibs = libs + qmklibs;
if (project->values("TEMPLATE").contains("app")) {
project->values("QMAKE_CFLAGS") += project->values("QMAKE_CFLAGS_APP");
@ -651,7 +652,9 @@ void Win32MakefileGenerator::writeLibsPart(QTextStream &t)
} else {
t << "LINKER = " << var("QMAKE_LINK") << endl;
t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl;
t << "LIBS = " << fixLibFlags("QMAKE_LIBS").join(' ') << ' '
t << "LIBS = " << fixLibFlags("LIBS").join(' ') << ' '
<< fixLibFlags("LIBS_PRIVATE").join(' ') << ' '
<< fixLibFlags("QMAKE_LIBS").join(' ') << ' '
<< fixLibFlags("QMAKE_LIBS_PRIVATE").join(' ') << endl;
}
}

View File

@ -7,6 +7,8 @@
"Description": "FreeType is a freely available software library to render fonts.",
"Homepage": "http://www.freetype.org",
"Version": "2.6.1",
"License": "Freetype Project License or GNU General Public License v2.0 only",
"LicenseId": "FTL OR GPL-2.0",
"LicenseFile": "LICENSE.txt",

View File

@ -18,4 +18,3 @@
"LicenseFile": "LICENSE",
"Copyright": "Copyright (C) 2003 Bitstream,Inc"
}

View File

@ -1454,7 +1454,8 @@ void QImage::setDevicePixelRatio(qreal scaleFactor)
return;
detach();
d->devicePixelRatio = scaleFactor;
if (d)
d->devicePixelRatio = scaleFactor;
}
/*!
@ -2240,8 +2241,15 @@ bool QImage::reinterpretAsFormat(Format format)
return true;
if (qt_depthForFormat(format) != qt_depthForFormat(d->format))
return false;
if (!isDetached()) // Detach only if shared, not for read-only data.
if (!isDetached()) { // Detach only if shared, not for read-only data.
QImageData *oldD = d;
detach();
// In case detach() ran out of memory
if (!d) {
d = oldD;
return false;
}
}
d->format = format;
return true;
@ -3288,6 +3296,8 @@ void QImage::mirrored_inplace(bool horizontal, bool vertical)
return;
detach();
if (!d)
return;
if (!d->own_data)
*this = copy();
@ -3440,6 +3450,8 @@ void QImage::rgbSwapped_inplace()
return;
detach();
if (!d)
return;
if (!d->own_data)
*this = copy();

View File

@ -119,6 +119,7 @@ void qGamma_correct_back_to_linear_cs(QImage *image)
*****************************************************************************/
// The drawhelper conversions from/to RGB32 are passthroughs which is not always correct for general image conversion
#if !defined(__ARM_NEON__)
static void QT_FASTCALL storeRGB32FromARGB32PM(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
@ -126,6 +127,7 @@ static void QT_FASTCALL storeRGB32FromARGB32PM(uchar *dest, const uint *src, int
for (int i = 0; i < count; ++i)
d[i] = 0xff000000 | qUnpremultiply(src[i]);
}
#endif
static void QT_FASTCALL storeRGB32FromARGB32(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
@ -147,6 +149,9 @@ static const uint *QT_FASTCALL fetchRGB32ToARGB32PM(uint *buffer, const uchar *s
#ifdef QT_COMPILER_SUPPORTS_SSE4_1
extern void QT_FASTCALL storeRGB32FromARGB32PM_sse4(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
#elif defined(__ARM_NEON__)
extern void QT_FASTCALL storeRGB32FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
#endif
void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags flags)
@ -175,8 +180,12 @@ void convert_generic(QImageData *dest, const QImageData *src, Qt::ImageConversio
if (qCpuHasFeature(SSE4_1))
store = storeRGB32FromARGB32PM_sse4;
else
#endif
store = storeRGB32FromARGB32PM;
#elif defined(__ARM_NEON__)
store = storeRGB32FromARGB32PM_neon;
#else
store = storeRGB32FromARGB32PM;
#endif
}
}
if (srcLayout->hasAlphaChannel && !srcLayout->premultiplied &&
@ -261,8 +270,12 @@ bool convert_generic_inplace(QImageData *data, QImage::Format dst_format, Qt::Im
if (qCpuHasFeature(SSE4_1))
store = storeRGB32FromARGB32PM_sse4;
else
#endif
store = storeRGB32FromARGB32PM;
#elif defined(__ARM_NEON__)
store = storeRGB32FromARGB32PM_neon;
#else
store = storeRGB32FromARGB32PM;
#endif
}
}
if (srcLayout->hasAlphaChannel && !srcLayout->premultiplied &&

View File

@ -449,8 +449,7 @@ Q_GUI_EXPORT QImage qt_imageFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0
Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0)
{
const QImage image = imageFromWinHBITMAP_GetDiBits(bitmap, /* forceQuads */ true, hbitmapFormat);
return QPixmap::fromImage(image);
return QPixmap::fromImage(imageFromWinHBITMAP_GetDiBits(bitmap, /* forceQuads */ true, hbitmapFormat));
}
Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &p)
@ -567,7 +566,7 @@ Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon)
SelectObject(hdc, oldhdc); //restore state
DeleteObject(winBitmap);
DeleteDC(hdc);
return QPixmap::fromImage(image);
return QPixmap::fromImage(std::move(image));
}
QT_END_NAMESPACE

View File

@ -6505,10 +6505,19 @@ static void qInitDrawhelperFunctions()
const QVector<QRgb> *, QDitherInfo *);
extern const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
extern void QT_FASTCALL storeARGB32FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
extern void QT_FASTCALL storeRGBA8888FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
extern void QT_FASTCALL storeRGBXFromARGB32PM_neon(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *);
qPixelLayouts[QImage::Format_ARGB32].fetchToARGB32PM = fetchARGB32ToARGB32PM_neon;
qPixelLayouts[QImage::Format_ARGB32].convertToARGB32PM = convertARGB32ToARGB32PM_neon;
qPixelLayouts[QImage::Format_ARGB32].storeFromARGB32PM = storeARGB32FromARGB32PM_neon;
qPixelLayouts[QImage::Format_RGBA8888].fetchToARGB32PM = fetchRGBA8888ToARGB32PM_neon;
qPixelLayouts[QImage::Format_RGBA8888].convertToARGB32PM = convertRGBA8888ToARGB32PM_neon;
qPixelLayouts[QImage::Format_RGBA8888].storeFromARGB32PM = storeRGBA8888FromARGB32PM_neon;
qPixelLayouts[QImage::Format_RGBX8888].storeFromARGB32PM = storeRGBXFromARGB32PM_neon;
#endif
#if defined(ENABLE_PIXMAN_DRAWHELPERS)

View File

@ -1081,15 +1081,28 @@ const uint * QT_FASTCALL qt_fetchUntransformed_888_neon(uint *buffer, const Oper
}
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
template<bool RGBA>
static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int count)
static inline uint32x4_t vrgba2argb(uint32x4_t srcVector)
{
int i = 0;
#if defined(Q_PROCESSOR_ARM_64)
const uint8x16_t rgbaMask = { 2, 1, 0, 3, 6, 5, 4, 7, 10, 9, 8, 11, 14, 13, 12, 15};
#else
const uint8x8_t rgbaMask = { 2, 1, 0, 3, 6, 5, 4, 7 };
#endif
#if defined(Q_PROCESSOR_ARM_64)
srcVector = vreinterpretq_u32_u8(vqtbl1q_u8(vreinterpretq_u8_u32(srcVector), rgbaMask));
#else
// no vqtbl1q_u8, so use two vtbl1_u8
const uint8x8_t low = vtbl1_u8(vreinterpret_u8_u32(vget_low_u32(srcVector)), rgbaMask);
const uint8x8_t high = vtbl1_u8(vreinterpret_u8_u32(vget_high_u32(srcVector)), rgbaMask);
srcVector = vcombine_u32(vreinterpret_u32_u8(low), vreinterpret_u32_u8(high));
#endif
return srcVector;
}
template<bool RGBA>
static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int count)
{
int i = 0;
const uint8x8_t shuffleMask = { 3, 3, 3, 3, 7, 7, 7, 7};
const uint32x4_t blendMask = vdupq_n_u32(0xff000000);
@ -1105,16 +1118,8 @@ static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int
#endif
if (alphaSum) {
if (alphaSum != 255 * 4) {
if (RGBA) {
#if defined(Q_PROCESSOR_ARM_64)
srcVector = vreinterpretq_u32_u8(vqtbl1q_u8(vreinterpretq_u8_u32(srcVector), rgbaMask));
#else
// no vqtbl1q_u8
const uint8x8_t low = vtbl1_u8(vreinterpret_u8_u32(vget_low_u32(srcVector)), rgbaMask);
const uint8x8_t high = vtbl1_u8(vreinterpret_u8_u32(vget_high_u32(srcVector)), rgbaMask);
srcVector = vcombine_u32(vreinterpret_u32_u8(low), vreinterpret_u32_u8(high));
#endif
}
if (RGBA)
srcVector = vrgba2argb(srcVector);
const uint8x8_t s1 = vreinterpret_u8_u32(vget_low_u32(srcVector));
const uint8x8_t s2 = vreinterpret_u8_u32(vget_high_u32(srcVector));
const uint8x8_t alpha1 = vtbl1_u8(s1, shuffleMask);
@ -1128,19 +1133,10 @@ static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int
const uint32x4_t d = vbslq_u32(blendMask, srcVector, vreinterpretq_u32_u8(vcombine_u8(d1, d2)));
vst1q_u32(buffer + i, d);
} else {
if (RGBA) {
#if defined(Q_PROCESSOR_ARM_64)
srcVector = vreinterpretq_u32_u8(vqtbl1q_u8(vreinterpretq_u8_u32(srcVector), rgbaMask));
#else
// no vqtbl1q_u8
const uint8x8_t low = vtbl1_u8(vreinterpret_u8_u32(vget_low_u32(srcVector)), rgbaMask);
const uint8x8_t high = vtbl1_u8(vreinterpret_u8_u32(vget_high_u32(srcVector)), rgbaMask);
srcVector = vcombine_u32(vreinterpret_u32_u8(low), vreinterpret_u32_u8(high));
#endif
if (RGBA)
vst1q_u32(buffer + i, vrgba2argb(srcVector));
else if (buffer != src)
vst1q_u32(buffer + i, srcVector);
} else if (buffer != src) {
vst1q_u32(buffer + i, srcVector);
}
}
} else {
vst1q_u32(buffer + i, vdupq_n_u32(0));
@ -1153,6 +1149,91 @@ static inline void convertARGBToARGB32PM_neon(uint *buffer, const uint *src, int
}
}
static inline float32x4_t reciprocal_mul_ps(float32x4_t a, float mul)
{
float32x4_t ia = vrecpeq_f32(a); // estimate 1/a
ia = vmulq_f32(vrecpsq_f32(a, ia), vmulq_n_f32(ia, mul)); // estimate improvement step * mul
return ia;
}
template<bool RGBA, bool RGBx>
static inline void convertARGBFromARGB32PM_neon(uint *buffer, const uint *src, int count)
{
int i = 0;
const uint32x4_t alphaMask = vdupq_n_u32(0xff000000);
for (; i < count - 3; i += 4) {
uint32x4_t srcVector = vld1q_u32(src + i);
uint32x4_t alphaVector = vshrq_n_u32(srcVector, 24);
#if defined(Q_PROCESSOR_ARM_64)
uint32_t alphaSum = vaddvq_u32(alphaVector);
#else
// no vaddvq_u32
uint32x2_t tmp = vpadd_u32(vget_low_u32(alphaVector), vget_high_u32(alphaVector));
uint32_t alphaSum = vget_lane_u32(vpadd_u32(tmp, tmp), 0);
#endif
if (alphaSum) {
if (alphaSum != 255 * 4) {
if (RGBA)
srcVector = vrgba2argb(srcVector);
const float32x4_t a = vcvtq_f32_u32(alphaVector);
const float32x4_t ia = reciprocal_mul_ps(a, 255.0f);
// Convert 4x(4xU8) to 4x(4xF32)
uint16x8_t tmp1 = vmovl_u8(vget_low_u8(vreinterpretq_u8_u32(srcVector)));
uint16x8_t tmp3 = vmovl_u8(vget_high_u8(vreinterpretq_u8_u32(srcVector)));
float32x4_t src1 = vcvtq_f32_u32(vmovl_u16(vget_low_u16(tmp1)));
float32x4_t src2 = vcvtq_f32_u32(vmovl_u16(vget_high_u16(tmp1)));
float32x4_t src3 = vcvtq_f32_u32(vmovl_u16(vget_low_u16(tmp3)));
float32x4_t src4 = vcvtq_f32_u32(vmovl_u16(vget_high_u16(tmp3)));
src1 = vmulq_lane_f32(src1, vget_low_f32(ia), 0);
src2 = vmulq_lane_f32(src2, vget_low_f32(ia), 1);
src3 = vmulq_lane_f32(src3, vget_high_f32(ia), 0);
src4 = vmulq_lane_f32(src4, vget_high_f32(ia), 1);
// Convert 4x(4xF32) back to 4x(4xU8) (over a 8.1 fixed point format to get rounding)
tmp1 = vcombine_u16(vrshrn_n_u32(vcvtq_n_u32_f32(src1, 1), 1),
vrshrn_n_u32(vcvtq_n_u32_f32(src2, 1), 1));
tmp3 = vcombine_u16(vrshrn_n_u32(vcvtq_n_u32_f32(src3, 1), 1),
vrshrn_n_u32(vcvtq_n_u32_f32(src4, 1), 1));
uint32x4_t dstVector = vreinterpretq_u32_u8(vcombine_u8(vmovn_u16(tmp1), vmovn_u16(tmp3)));
// Overwrite any undefined results from alpha==0 with zeros:
#if defined(Q_PROCESSOR_ARM_64)
uint32x4_t srcVectorAlphaMask = vceqzq_u32(alphaVector);
#else
uint32x4_t srcVectorAlphaMask = vceqq_u32(alphaVector, vdupq_n_u32(0));
#endif
dstVector = vbicq_u32(dstVector, srcVectorAlphaMask);
// Restore or mask alpha values:
if (RGBx)
dstVector = vorrq_u32(alphaMask, dstVector);
else
dstVector = vbslq_u32(alphaMask, srcVector, dstVector);
vst1q_u32(&buffer[i], dstVector);
} else {
// 4xAlpha==255, no change except if we are doing RGBA->ARGB:
if (RGBA)
vst1q_u32(&buffer[i], vrgba2argb(srcVector));
else if (buffer != src)
vst1q_u32(&buffer[i], srcVector);
}
} else {
// 4xAlpha==0, always zero, except if output is RGBx:
if (RGBx)
vst1q_u32(&buffer[i], alphaMask);
else
vst1q_u32(&buffer[i], vdupq_n_u32(0));
}
}
SIMD_EPILOGUE(i, count, 3) {
uint v = qUnpremultiply(src[i]);
if (RGBx)
v = 0xff000000 | v;
if (RGBA)
v = ARGB2RGBA(v);
buffer[i] = v;
}
}
void QT_FASTCALL convertARGB32ToARGB32PM_neon(uint *buffer, int count, const QVector<QRgb> *)
{
convertARGBToARGB32PM_neon<false>(buffer, buffer, count);
@ -1177,6 +1258,34 @@ const uint *QT_FASTCALL fetchRGBA8888ToARGB32PM_neon(uint *buffer, const uchar *
return buffer;
}
void QT_FASTCALL storeRGB32FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
uint *d = reinterpret_cast<uint *>(dest) + index;
convertARGBFromARGB32PM_neon<false,true>(d, src, count);
}
void QT_FASTCALL storeARGB32FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
uint *d = reinterpret_cast<uint *>(dest) + index;
convertARGBFromARGB32PM_neon<false,false>(d, src, count);
}
void QT_FASTCALL storeRGBA8888FromARGB32PM_neon(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
uint *d = reinterpret_cast<uint *>(dest) + index;
convertARGBFromARGB32PM_neon<true,false>(d, src, count);
}
void QT_FASTCALL storeRGBXFromARGB32PM_neon(uchar *dest, const uint *src, int index, int count,
const QVector<QRgb> *, QDitherInfo *)
{
uint *d = reinterpret_cast<uint *>(dest) + index;
convertARGBFromARGB32PM_neon<true,true>(d, src, count);
}
#endif // Q_BYTE_ORDER == Q_LITTLE_ENDIAN
QT_END_NAMESPACE

View File

@ -49,10 +49,135 @@
#include <private/qnetworkaccessmanager_p.h>
#include <private/qnetworkfile_p.h>
#include <iostream>
#include <emscripten.h>
#include <emscripten/bind.h>
#include <emscripten/val.h>
QT_BEGIN_NAMESPACE
using namespace emscripten;
static void q_requestErrorCallback(val event)
{
val xhr = event["target"];
quintptr func = xhr["data-handler"].as<quintptr>();
QNetworkReplyWasmImplPrivate *reply = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(func);
Q_ASSERT(reply);
int statusCode = xhr["status"].as<int>();
QString reasonStr = QString::fromStdString(xhr["statusText"].as<std::string>());
reply->setReplyAttributes(func, statusCode, reasonStr);
if (statusCode >= 400 && !reasonStr.isEmpty())
reply->emitReplyError(reply->statusCodeFromHttp(statusCode, reply->request.url()), reasonStr);
}
static void q_progressCallback(val event)
{
val xhr = event["target"];
QNetworkReplyWasmImplPrivate *reply =
reinterpret_cast<QNetworkReplyWasmImplPrivate*>(xhr["data-handler"].as<quintptr>());
Q_ASSERT(reply);
if (xhr["lengthComputable"].as<bool>() && xhr["status"].as<int>() < 400)
reply->emitDataReadProgress(xhr["loaded"].as<qint64>(), xhr["total"].as<qint64>());
}
static void q_loadCallback(val event)
{
val xhr = event["target"];
QNetworkReplyWasmImplPrivate *reply =
reinterpret_cast<QNetworkReplyWasmImplPrivate*>(xhr["data-handler"].as<quintptr>());
Q_ASSERT(reply);
int status = xhr["status"].as<int>();
if (status >= 300) {
q_requestErrorCallback(event);
return;
}
QString statusText = QString::fromStdString(xhr["statusText"].as<std::string>());
if (status == 200 || status == 203) {
QString responseString;
const std::string responseType = xhr["responseType"].as<std::string>();
if (responseType.length() == 0 || responseType == "document" || responseType == "text") {
responseString = QString::fromStdWString(xhr["responseText"].as<std::wstring>());
} else if (responseType == "json") {
responseString =
QString::fromStdWString(val::global("JSON").call<std::wstring>("stringify", xhr["response"]));
} else if (responseType == "arraybuffer" || responseType == "blob") {
// handle this data in the FileReader, triggered by the call to readAsArrayBuffer
val reader = val::global("FileReader").new_();
reader.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_readBinary"));
reader.set("data-handler", xhr["data-handler"]);
reader.call<void>("readAsArrayBuffer", xhr["response"]);
}
int readyState = xhr["readyState"].as<int>();
if (readyState == 4) { // done
reply->setReplyAttributes(xhr["data-handler"].as<quintptr>(), status, statusText);
if (!responseString.isEmpty())
reply->dataReceived(responseString.toUtf8(), responseString.size());
}
}
if (status >= 400 && !statusText.isEmpty())
reply->emitReplyError(reply->statusCodeFromHttp(status, reply->request.url()), statusText);
}
static void q_responseHeadersCallback(val event)
{
val xhr = event["target"];
if (xhr["readyState"].as<int>() == 2) { // HEADERS_RECEIVED
std::string responseHeaders = xhr.call<std::string>("getAllResponseHeaders");
if (!responseHeaders.empty()) {
QNetworkReplyWasmImplPrivate *reply =
reinterpret_cast<QNetworkReplyWasmImplPrivate*>(xhr["data-handler"].as<quintptr>());
Q_ASSERT(reply);
reply->headersReceived(QString::fromStdString(responseHeaders));
}
}
}
static void q_readBinary(val event)
{
val fileReader = event["target"];
QNetworkReplyWasmImplPrivate *reply =
reinterpret_cast<QNetworkReplyWasmImplPrivate*>(fileReader["data-handler"].as<quintptr>());
Q_ASSERT(reply);
// Set up source typed array
val result = fileReader["result"]; // ArrayBuffer
val Uint8Array = val::global("Uint8Array");
val sourceTypedArray = Uint8Array.new_(result);
// Allocate and set up destination typed array
const quintptr size = result["byteLength"].as<quintptr>();
QByteArray buffer(size, Qt::Uninitialized);
val destinationTypedArray = Uint8Array.new_(val::module_property("HEAPU8")["buffer"],
reinterpret_cast<quintptr>(buffer.data()), size);
destinationTypedArray.call<void>("set", sourceTypedArray);
reply->dataReceived(buffer, buffer.size());
}
EMSCRIPTEN_BINDINGS(network_module) {
function("QNetworkReplyWasmImplPrivate_requestErrorCallback", q_requestErrorCallback);
function("QNetworkReplyWasmImplPrivate_progressCallback", q_progressCallback);
function("QNetworkReplyWasmImplPrivate_loadCallback", q_loadCallback);
function("QNetworkReplyWasmImplPrivate_responseHeadersCallback", q_responseHeadersCallback);
function("QNetworkReplyWasmImplPrivate_readBinary", q_readBinary);
}
QNetworkReplyWasmImplPrivate::QNetworkReplyWasmImplPrivate()
: QNetworkReplyPrivate()
, managerPrivate(0)
@ -172,226 +297,80 @@ void QNetworkReplyWasmImplPrivate::setup(QNetworkAccessManager::Operation op, co
doSendRequest();
}
void QNetworkReplyWasmImplPrivate::onLoadCallback(void *data, int statusCode, int statusReason, int readyState, int buffer, int bufferSize)
void QNetworkReplyWasmImplPrivate::setReplyAttributes(quintptr data, int statusCode, const QString &statusReason)
{
QNetworkReplyWasmImplPrivate *handler = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(data);
const QString reasonStr = QString::fromUtf8(reinterpret_cast<char *>(statusReason));
switch (readyState) {
case 0://unsent
break;
case 1://opened
break;
case 2://headers received
break;
case 3://loading
break;
case 4: {//done
handler->q_func()->setAttribute(QNetworkRequest::HttpStatusCodeAttribute, statusCode);
if (!reasonStr.isEmpty())
handler->q_func()->setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, reasonStr);
if (statusCode >= 400) {
if (!reasonStr.isEmpty())
handler->emitReplyError(handler->statusCodeFromHttp(statusCode, handler->request.url()), reasonStr);
} else {
handler->dataReceived(reinterpret_cast<char *>(buffer), bufferSize);
}
}
break;
};
}
void QNetworkReplyWasmImplPrivate::onProgressCallback(void* data, int bytesWritten, int total, uint timestamp)
{
Q_UNUSED(timestamp);
QNetworkReplyWasmImplPrivate *handler = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(data);
handler->emitDataReadProgress(bytesWritten, total);
}
void QNetworkReplyWasmImplPrivate::onRequestErrorCallback(void* data, int statusCode, int statusReason)
{
QString reasonStr = QString::fromUtf8(reinterpret_cast<char *>(statusReason));
QNetworkReplyWasmImplPrivate *handler = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(data);
Q_ASSERT(handler);
handler->q_func()->setAttribute(QNetworkRequest::HttpStatusCodeAttribute, statusCode);
if (!reasonStr.isEmpty())
handler->q_func()->setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, reasonStr);
if (statusCode >= 400) {
if (!reasonStr.isEmpty())
handler->emitReplyError(handler->statusCodeFromHttp(statusCode, handler->request.url()), reasonStr);
}
}
void QNetworkReplyWasmImplPrivate::onResponseHeadersCallback(void* data, int headers)
{
QNetworkReplyWasmImplPrivate *handler = reinterpret_cast<QNetworkReplyWasmImplPrivate*>(data);
handler->headersReceived(reinterpret_cast<char *>(headers));
if (!statusReason.isEmpty())
handler->q_func()->setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, statusReason);
}
void QNetworkReplyWasmImplPrivate::doSendRequest()
{
Q_Q(QNetworkReplyWasmImpl);
totalDownloadSize = 0;
jsRequest(QString::fromUtf8(q->methodName()), // GET POST
request.url().toString(),
(void *)&onLoadCallback,
(void *)&onProgressCallback,
(void *)&onRequestErrorCallback,
(void *)&onResponseHeadersCallback);
}
/* const QString &body, const QList<QPair<QByteArray, QByteArray> > &headers ,*/
void QNetworkReplyWasmImplPrivate::jsRequest(const QString &verb, const QString &url,
void *loadCallback, void *progressCallback,
void *errorCallback, void *onResponseHeadersCallback)
{
val xhr = val::global("XMLHttpRequest").new_();
std::string verb = q->methodName().toStdString();
QUrl url;
QString extraDataString;
if (request.url().hasQuery()) { //strip query from url
extraDataString = request.url().query(QUrl::FullyEncoded);
QString urlStr = request.url().toString();
url.setUrl(urlStr.left(urlStr.indexOf("?")));
} else {
url = request.url();
}
xhr.call<void>("open", verb, url.toString().toStdString());
xhr.set("onerror", val::module_property("QNetworkReplyWasmImplPrivate_requestErrorCallback"));
xhr.set("onload", val::module_property("QNetworkReplyWasmImplPrivate_loadCallback"));
xhr.set("onprogress", val::module_property("QNetworkReplyWasmImplPrivate_progressCallback"));
xhr.set("onreadystatechange", val::module_property("QNetworkReplyWasmImplPrivate_responseHeadersCallback"));
xhr.set("data-handler", val(quintptr(reinterpret_cast<void *>(this))));
QByteArray contentType = request.rawHeader("Content-Type");
// handle extra data
val dataToSend = val::null();
QByteArray extraData;
if (outgoingData)
if (outgoingData) // data from post request
extraData = outgoingData->readAll();
if (extraData.size() > 0)
extraDataString.fromUtf8(extraData);
if (extraDataString.size() >= 0 && verb == QStringLiteral("POST") && extraDataString.startsWith(QStringLiteral("?")))
extraDataString.remove(QStringLiteral("?"));
// Probably a good idea to save any shared pointers as members in C++
// so the objects they point to survive as long as you need them
QStringList headersList;
for (auto header : request.rawHeaderList())
headersList << QString::fromUtf8(header + ":" + request.rawHeader(header));
EM_ASM_ARGS({
var verb = Pointer_stringify($0);
var url = Pointer_stringify($1);
var onLoadCallbackPointer = $2;
var onProgressCallbackPointer = $3;
var onErrorCallbackPointer = $4;
var onHeadersCallback = $5;
var handler = $8;
var dataToSend;
var extraRequestData = Pointer_stringify($6); // request parameters
var headersData = Pointer_stringify($7);
var xhr;
xhr = new XMLHttpRequest();
xhr.responseType = 'arraybuffer';
xhr.open(verb, url, true); //async
function handleError(xhrStatusCode, xhrStatusText) {
var errorPtr = allocate(intArrayFromString(xhrStatusText), 'i8', ALLOC_NORMAL);
Runtime.dynCall('viii', onErrorCallbackPointer, [handler, xhrStatusCode, errorPtr]);
_free(errorPtr);
if (contentType.contains("text") ||
contentType.contains("json") ||
contentType.contains("form")) {
if (extraData.size() > 0)
extraDataString.fromUtf8(extraData);
}
if (contentType.contains("json")) {
if (!extraDataString.isEmpty()) {
xhr.set("responseType", val("json"));
dataToSend = val(extraDataString.toStdString());
}
}
if (contentType.contains("form")) { //construct form data
if (!extraDataString.isEmpty()) {
val formData = val::global("FormData").new_();
QStringList formList = extraDataString.split('&');
if (headersData) {
var headers = headersData.split("&");
for (var i = 0; i < headers.length; i++) {
var header = headers[i].split(":")[0];
var value = headers[i].split(":")[1];
if (verb === 'POST' && value.toLowerCase().includes('json')) {
if (extraRequestData) {
xhr.responseType = 'json';
dataToSend = extraRequestData;
}
}
if (verb === 'POST' && value.toLowerCase().includes('form')) {
if (extraRequestData) {
var formData = new FormData();
var extra = extraRequestData.split("&");
for (var i = 0; i < extra.length; i++) {
formData.append(extra[i].split("=")[0],extra[i].split("=")[1]);
}
dataToSend = formData;
}
}
xhr.setRequestHeader(header, value);
for (auto formEntry : formList) {
formData.call<void>("append", formEntry.split('=')[0].toStdString(), formEntry.split('=')[1].toStdString());
}
dataToSend = formData;
}
xhr.onprogress = function(e) {
switch (xhr.status) {
case 200:
case 206:
case 300:
case 301:
case 302: {
var date = xhr.getResponseHeader('Last-Modified');
date = ((date != null) ? new Date(date).getTime() / 1000 : 0);
Runtime.dynCall('viiii', onProgressCallbackPointer, [handler, e.loaded, e.total, date]);
}
break;
}
};
xhr.onreadystatechange = function() {
if (this.readyState == this.HEADERS_RECEIVED) {
var responseStr = this.getAllResponseHeaders();
if (responseStr.length > 0) {
var ptr = allocate(intArrayFromString(responseStr), 'i8', ALLOC_NORMAL);
Runtime.dynCall('vii', onHeadersCallback, [handler, ptr]);
_free(ptr);
}
}
};
xhr.onload = function(e) {
if (xhr.status >= 300) { //error
handleError(xhr.status, xhr.statusText);
} else {
if (this.status == 200 || this.status == 203) {
var datalength;
var byteArray = 0;
var buffer;
if (this.responseType.length === 0 || this.responseType === 'document') {
byteArray = new Uint8Array(this.responseText);
} else if (this.responseType === 'json') {
var jsonResponse = JSON.stringify(this.response);
buffer = allocate(intArrayFromString(jsonResponse), 'i8', ALLOC_NORMAL);
datalength = jsonResponse.length;
} else if (this.responseType === 'arraybuffer') {
byteArray = new Uint8Array(xhr.response);
}
if (byteArray != 0 ) {
datalength = byteArray.length;
buffer = _malloc(datalength);
HEAPU8.set(byteArray, buffer);
}
var reasonPtr = allocate(intArrayFromString(this.statusText), 'i8', ALLOC_NORMAL);
Runtime.dynCall('viiiiii', onLoadCallbackPointer, [handler, this.status, reasonPtr, this.readyState, buffer, datalength]);
_free(buffer);
_free(reasonPtr);
}
}
};
xhr.onerror = function(e) {
handleError(xhr.status, xhr.statusText);
};
//TODO other operations, handle user/pass, handle binary data, data streaming
xhr.send(dataToSend);
}, verb.toLatin1().data(),
url.toLatin1().data(),
loadCallback,
progressCallback,
errorCallback,
onResponseHeadersCallback,
extraDataString.size() > 0 ? extraDataString.toLatin1().data() : extraData.data(),
headersList.join(QStringLiteral("&")).toLatin1().data(),
this
);
}
// set request headers
for (auto header : request.rawHeaderList()) {
xhr.call<void>("setRequestHeader", header.toStdString(), request.rawHeader(header).toStdString());
}
xhr.call<void>("send", dataToSend);
}
void QNetworkReplyWasmImplPrivate::emitReplyError(QNetworkReply::NetworkError errorCode, const QString &errorString)
@ -414,10 +393,10 @@ void QNetworkReplyWasmImplPrivate::emitDataReadProgress(qint64 bytesReceived, qi
percentFinished = (bytesReceived / bytesTotal) * 100;
emit q->downloadProgress(bytesReceived, totalDownloadSize);
emit q->downloadProgress(bytesReceived, bytesTotal);
}
void QNetworkReplyWasmImplPrivate::dataReceived(char *buffer, int bufferSize)
void QNetworkReplyWasmImplPrivate::dataReceived(const QByteArray &buffer, int bufferSize)
{
Q_Q(QNetworkReplyWasmImpl);
@ -481,11 +460,10 @@ static int parseHeaderName(const QByteArray &headerName)
}
void QNetworkReplyWasmImplPrivate::headersReceived(char *buffer)
void QNetworkReplyWasmImplPrivate::headersReceived(const QString &bufferString)
{
Q_Q(QNetworkReplyWasmImpl);
QString bufferString = QString::fromUtf8(buffer);
if (!bufferString.isEmpty()) {
QStringList headers = bufferString.split(QString::fromUtf8("\r\n"), QString::SkipEmptyParts);

View File

@ -95,7 +95,6 @@ public:
private:
QByteArray methodName() const;
};
class QNetworkReplyWasmImplPrivate: public QNetworkReplyPrivate
@ -106,19 +105,12 @@ public:
QNetworkAccessManagerPrivate *managerPrivate;
void doSendRequest();
void jsRequest(const QString &verb, const QString &url, void *, void *, void *, void *);
static void onLoadCallback(void *data, int statusCode, int statusReason, int readyState, int textBuffer, int size);
static void onProgressCallback(void *data, int done, int bytesTotal, uint timestamp);
static void onRequestErrorCallback(void *data, int statusCode, int statusReason);
static void onStateChangedCallback(int status);
static void onResponseHeadersCallback(void *data, int headers);
static void setReplyAttributes(quintptr data, int statusCode, const QString &statusReason);
void emitReplyError(QNetworkReply::NetworkError errorCode, const QString &);
void emitDataReadProgress(qint64 done, qint64 total);
void dataReceived(char *buffer, int bufferSize);
void headersReceived(char *buffer);
void dataReceived(const QByteArray &buffer, int bufferSize);
void headersReceived(const QString &bufferString);
void setup(QNetworkAccessManager::Operation op, const QNetworkRequest &request,
QIODevice *outgoingData);
@ -148,6 +140,4 @@ public:
QT_END_NAMESPACE
//Q_DECLARE_METATYPE(QNetworkRequest::KnownHeaders)
#endif // QNETWORKREPLYWASMIMPL_H

View File

@ -48,26 +48,78 @@
QT_BEGIN_NAMESPACE
struct GUserEventSource
{
GSource source;
QPAEventDispatcherGlib *q;
};
static gboolean userEventSourcePrepare(GSource *source, gint *timeout)
{
Q_UNUSED(timeout)
GUserEventSource *userEventSource = reinterpret_cast<GUserEventSource *>(source);
QPAEventDispatcherGlib *dispatcher = userEventSource->q;
if (dispatcher->m_flags & QEventLoop::ExcludeUserInputEvents)
return QWindowSystemInterface::nonUserInputEventsQueued();
else
return QWindowSystemInterface::windowSystemEventsQueued() > 0;
}
static gboolean userEventSourceCheck(GSource *source)
{
return userEventSourcePrepare(source, 0);
}
static gboolean userEventSourceDispatch(GSource *source, GSourceFunc, gpointer)
{
GUserEventSource *userEventSource = reinterpret_cast<GUserEventSource *>(source);
QPAEventDispatcherGlib *dispatcher = userEventSource->q;
QWindowSystemInterface::sendWindowSystemEvents(dispatcher->m_flags);
return true;
}
static GSourceFuncs userEventSourceFuncs = {
userEventSourcePrepare,
userEventSourceCheck,
userEventSourceDispatch,
NULL,
NULL,
NULL
};
QPAEventDispatcherGlibPrivate::QPAEventDispatcherGlibPrivate(GMainContext *context)
: QEventDispatcherGlibPrivate(context)
{
Q_Q(QPAEventDispatcherGlib);
userEventSource = reinterpret_cast<GUserEventSource *>(g_source_new(&userEventSourceFuncs,
sizeof(GUserEventSource)));
userEventSource->q = q;
g_source_set_can_recurse(&userEventSource->source, true);
g_source_attach(&userEventSource->source, mainContext);
}
QPAEventDispatcherGlib::QPAEventDispatcherGlib(QObject *parent)
: QEventDispatcherGlib(*new QPAEventDispatcherGlibPrivate, parent)
, m_flags(QEventLoop::AllEvents)
{
Q_D(QPAEventDispatcherGlib);
d->userEventSource->q = this;
}
QPAEventDispatcherGlib::~QPAEventDispatcherGlib()
{
Q_D(QPAEventDispatcherGlib);
g_source_destroy(&d->userEventSource->source);
g_source_unref(&d->userEventSource->source);
d->userEventSource = 0;
}
bool QPAEventDispatcherGlib::processEvents(QEventLoop::ProcessEventsFlags flags)
{
m_flags = flags;
const bool didSendEvents = QEventDispatcherGlib::processEvents(m_flags);
return QWindowSystemInterface::sendWindowSystemEvents(m_flags) || didSendEvents;
return QEventDispatcherGlib::processEvents(m_flags);
}
QT_END_NAMESPACE

View File

@ -71,11 +71,14 @@ public:
QEventLoop::ProcessEventsFlags m_flags;
};
struct GUserEventSource;
class QPAEventDispatcherGlibPrivate : public QEventDispatcherGlibPrivate
{
Q_DECLARE_PUBLIC(QPAEventDispatcherGlib)
public:
QPAEventDispatcherGlibPrivate(GMainContext *context = 0);
GUserEventSource *userEventSource;
};

View File

@ -144,9 +144,8 @@
},
{
"id": 12,
"description": "Intel HD Graphics 620 crash in conjunction with shader caches (QTBUG-64697)",
"description": "Intel HD Graphics crash in conjunction with shader caches (QTBUG-64697) - disable for all Intel GPUs",
"vendor_id": "0x8086",
"device_id": [ "0x5916" ],
"os": {
"type": "win"
},

View File

@ -118,11 +118,14 @@ void QWinRTBackingStore::flush(QWindow *window, const QRegion &region, const QPo
if (d->size.isEmpty())
return;
const QRect bounds = region.boundingRect() & d->paintDevice.rect();
if (bounds.isEmpty())
return;
const bool ok = d->context->makeCurrent(window);
if (!ok)
qWarning("unable to flush");
const QRect bounds = region.boundingRect();
glBindTexture(GL_TEXTURE_2D, d->fbo->texture());
// TODO: when ANGLE GLES3 support is finished, use the glPixelStorei functions to minimize upload
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, bounds.y(), d->size.width(), bounds.height(),

View File

@ -90,25 +90,6 @@
#include <xcb/render.h>
#endif
#if defined(Q_CC_GNU) && defined(Q_OF_ELF)
static xcb_generic_event_t *local_xcb_poll_for_queued_event(xcb_connection_t *c)
__attribute__((weakref("xcb_poll_for_queued_event")));
static inline void checkXcbPollForQueuedEvent()
{ }
#else
#include <dlfcn.h>
typedef xcb_generic_event_t * (*XcbPollForQueuedEventFunctionPointer)(xcb_connection_t *c);
static XcbPollForQueuedEventFunctionPointer local_xcb_poll_for_queued_event;
static inline void checkXcbPollForQueuedEvent()
{
#ifdef RTLD_DEFAULT
local_xcb_poll_for_queued_event = (XcbPollForQueuedEventFunctionPointer)dlsym(RTLD_DEFAULT, "xcb_poll_for_queued_event");
#endif
}
#endif
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaXInput, "qt.qpa.input")
@ -1365,39 +1346,19 @@ bool QXcbConnection::peekEventQueue(PeekerCallback peeker, void *peekerData,
QXcbEventReader::QXcbEventReader(QXcbConnection *connection)
: m_connection(connection)
{
checkXcbPollForQueuedEvent();
}
void QXcbEventReader::start()
{
if (local_xcb_poll_for_queued_event) {
connect(this, SIGNAL(eventPending()), m_connection, SLOT(processXcbEvents()), Qt::QueuedConnection);
connect(this, SIGNAL(finished()), m_connection, SLOT(processXcbEvents()));
QThread::start();
} else {
// Must be done after we have an event-dispatcher. By posting a method invocation
// we are sure that by the time the method is called we have an event-dispatcher.
QMetaObject::invokeMethod(this, "registerForEvents", Qt::QueuedConnection);
}
}
void QXcbEventReader::registerForEvents()
{
QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(m_connection->xcb_connection()), QSocketNotifier::Read, this);
connect(notifier, SIGNAL(activated(int)), m_connection, SLOT(processXcbEvents()));
QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
connect(dispatcher, SIGNAL(aboutToBlock()), m_connection, SLOT(processXcbEvents()));
connect(dispatcher, SIGNAL(awake()), m_connection, SLOT(processXcbEvents()));
connect(this, &QXcbEventReader::eventPending, m_connection, &QXcbConnection::processXcbEvents, Qt::QueuedConnection);
connect(this, &QXcbEventReader::finished, m_connection, &QXcbConnection::processXcbEvents);
QThread::start();
}
void QXcbEventReader::registerEventDispatcher(QAbstractEventDispatcher *dispatcher)
{
// flush the xcb connection before the EventDispatcher is going to block
// In the non-threaded case processXcbEvents is called before going to block,
// which flushes the connection.
if (local_xcb_poll_for_queued_event)
connect(dispatcher, SIGNAL(aboutToBlock()), m_connection, SLOT(flush()));
// Flush the xcb connection before the event dispatcher is going to block.
connect(dispatcher, &QAbstractEventDispatcher::aboutToBlock, m_connection, &QXcbConnection::flush);
}
void QXcbEventReader::run()
@ -1406,7 +1367,7 @@ void QXcbEventReader::run()
while (m_connection && (event = xcb_wait_for_event(m_connection->xcb_connection()))) {
m_mutex.lock();
addEvent(event);
while (m_connection && (event = local_xcb_poll_for_queued_event(m_connection->xcb_connection())))
while (m_connection && (event = xcb_poll_for_queued_event(m_connection->xcb_connection())))
addEvent(event);
m_mutex.unlock();
emit eventPending();
@ -1430,10 +1391,6 @@ void QXcbEventReader::addEvent(xcb_generic_event_t *event)
QXcbEventArray *QXcbEventReader::lock()
{
m_mutex.lock();
if (!local_xcb_poll_for_queued_event) {
while (xcb_generic_event_t *event = xcb_poll_for_event(m_connection->xcb_connection()))
m_events << event;
}
return &m_events;
}

View File

@ -326,9 +326,6 @@ public:
signals:
void eventPending();
private slots:
void registerForEvents();
private:
void addEvent(xcb_generic_event_t *event);
@ -493,8 +490,6 @@ public:
bool hasShmFd() const { return has_shm_fd; }
bool hasXSync() const { return has_sync_extension; }
bool threadedEventHandling() const { return m_reader->isRunning(); }
xcb_timestamp_t getTimestamp();
xcb_window_t getSelectionOwner(xcb_atom_t atom) const;
xcb_window_t getQtSelectionOwner();

View File

@ -308,8 +308,7 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
const auto *connection = qAsConst(m_connections).first();
if (const auto *integration = connection->glIntegration())
return cap != ThreadedOpenGL
|| (connection->threadedEventHandling() && integration->supportsThreadedOpenGL());
return cap != ThreadedOpenGL || integration->supportsThreadedOpenGL();
return false;
}

View File

@ -16,7 +16,7 @@ qtConfig(ssl) {
qsslsocket_onDemandCertificates_member \
qsslsocket_onDemandCertificates_static
qtConfig(openssl) {
qtConfig(dtls) {
SUBDIRS += \
qdtlscookie \
qdtls