diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0d9fdba --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/qtbase-opensource-src-5.6.1.tar.xz diff --git a/.qt5-qtbase.metadata b/.qt5-qtbase.metadata new file mode 100644 index 0000000..76e0a22 --- /dev/null +++ b/.qt5-qtbase.metadata @@ -0,0 +1 @@ +234daccb120e34878abe10127b1a1ec18f1b12dc SOURCES/qtbase-opensource-src-5.6.1.tar.xz diff --git a/README.md b/README.md deleted file mode 100644 index 98f42b4..0000000 --- a/README.md +++ /dev/null @@ -1,4 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/10-qt5-check-opengl2.sh b/SOURCES/10-qt5-check-opengl2.sh new file mode 100755 index 0000000..57071d4 --- /dev/null +++ b/SOURCES/10-qt5-check-opengl2.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +if [ -z "$QT_XCB_FORCE_SOFTWARE_OPENGL" ]; then + +QT5_CHECK_OPENGL_VERSION=`LANG=C glxinfo 2> /dev/null | grep '^OpenGL version string: ' | head -n 1 | sed -e 's/^OpenGL version string: \([0-9]\).*$/\1/g'` ||: + +if [ "$QT5_CHECK_OPENGL_VERSION" == "1" ]; then + QT_XCB_FORCE_SOFTWARE_OPENGL=1 + export QT_XCB_FORCE_SOFTWARE_OPENGL +fi + +unset QT5_CHECK_OPENGL_VERSION + +fi diff --git a/SOURCES/macros.qt5 b/SOURCES/macros.qt5 new file mode 100644 index 0000000..9fb7807 --- /dev/null +++ b/SOURCES/macros.qt5 @@ -0,0 +1,35 @@ +%_qt5 @@NAME@@ +%_qt5_epoch @@EPOCH@@ +%_qt5_version @@VERSION@@ +%_qt5_evr @@EVR@@ +%_qt5_prefix %{_libdir}/qt5 +%_qt5_archdatadir %{_qt5_prefix} +%_qt5_bindir %{_qt5_prefix}/bin +%_qt5_datadir %{_datadir}/qt5 +%_qt5_docdir %{_docdir}/qt5 +%_qt5_examplesdir %{_qt5_prefix}/examples +%_qt5_headerdir %{_includedir}/qt5 +%_qt5_importdir %{_qt5_archdatadir}/imports +%_qt5_libdir %{_libdir} +%_qt5_libexecdir %{_qt5_archdatadir}/libexec +%_qt5_plugindir %{_qt5_archdatadir}/plugins +%_qt5_qmake %{_qt5_bindir}/qmake +%_qt5_settingsdir %{_sysconfdir}/xdg +%_qt5_sysconfdir %{_qt5_settingsdir} +%_qt5_translationdir %{_datadir}/qt5/translations + +%_qt5_cflags %{nil}@@QT5_CFLAGS@@ +%_qt5_cxxflags %{nil}@@QT5_CXXFLAGS@@ +%_qt5_ldflags %{nil}%{?__global_ldflags} @@QT5_RPM_LD_FLAGS@@ +%_qt5_optflags %{optflags} @@QT5_RPM_OPT_FLAGS@@ + +%_qt5_qmake_flags \\\ + QMAKE_CFLAGS_DEBUG="${CFLAGS:-%{_qt5_optflags} %{?_qt5_cflags}}" \\\ + QMAKE_CFLAGS_RELEASE="${CFLAGS:-%{_qt5_optflags} %{?_qt5_cflags}}" \\\ + QMAKE_CXXFLAGS_DEBUG="${CXXFLAGS:-%{_qt5_optflags} %{?_qt5_cxxflags}}" \\\ + QMAKE_CXXFLAGS_RELEASE="${CXXFLAGS:-%{_qt5_optflags} %{?_qt5_cxxflags}}" \\\ + QMAKE_LFLAGS_DEBUG="${LDFLAGS:-%{_qt5_ldflags}}" \\\ + QMAKE_LFLAGS_RELEASE="${LDFLAGS:-%{_qt5_ldflags}}" \\\ + QMAKE_STRIP= + +%qmake_qt5 %{_qt5_qmake} %{?_qt5_qmake_flags} diff --git a/SOURCES/moc-get-the-system-defines-from-the-compiler-itself.patch b/SOURCES/moc-get-the-system-defines-from-the-compiler-itself.patch new file mode 100644 index 0000000..3912cc7 --- /dev/null +++ b/SOURCES/moc-get-the-system-defines-from-the-compiler-itself.patch @@ -0,0 +1,368 @@ +From fa0d02eedcacc22db1026b902801b29176755362 Mon Sep 17 00:00:00 2001 +From: Thiago Macieira +Date: Fri, 21 Aug 2015 17:08:19 -0700 +Subject: [PATCH] moc: get the system #defines from the compiler itself + +In order for moc to properly parse #ifdefs and family, we've had +QMAKE_COMPILER_DEFINES as a list of pre-defined macros from the +compiler. That list is woefully incomplete. + +Instead, let's simply ask the compiler for the list. With GCC and +family, we use the -dM flag while preprocessing. With ICC on Windows, +the flag gains an extra "Q" but is otherwise the same. For MSVC, it +requires using some undocumented switches and parsing environment +variables (I've tested MSVC 2012, 2013 and 2015). + +The new moc option is called --include to be similar to GCC's -include +option. It does more than just parse a list of pre-defined macros and +can be used to insert any sort of code that moc needs to parse prior to +the main file. + +Change-Id: I7de033f80b0e4431b7f1ffff13fca02dbb60a0a6 +--- + mkspecs/features/moc.prf | 31 +++++++++++++-- + qmake/main.cpp | 38 +++++++++++++++++++ + src/tools/moc/main.cpp | 16 +++++++- + src/tools/moc/preprocessor.cpp | 60 +++++++++++++++++------------- + src/tools/moc/preprocessor.h | 1 + + tests/auto/tools/moc/subdir/extradefines.h | 1 + + tests/auto/tools/moc/tst_moc.cpp | 42 +++++++++++++++++++++ + 7 files changed, 158 insertions(+), 31 deletions(-) + create mode 100644 tests/auto/tools/moc/subdir/extradefines.h + +diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf +index c0b5682..af885c3 100644 +--- a/mkspecs/features/moc.prf ++++ b/mkspecs/features/moc.prf +@@ -24,8 +24,25 @@ win32:count(MOC_INCLUDEPATH, 40, >) { + write_file($$absolute_path($$WIN_INCLUDETEMP, $$OUT_PWD), WIN_INCLUDETEMP_CONT)|error("Aborting.") + } + ++# QNX's compiler sets "gcc" config, but does not support the -dM option; ++# iOS builds are multi-arch, so this feature cannot possibly work. ++if(gcc|intel_icl|msvc):!rim_qcc:!ios { ++ 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:msvc { ++ # make sure that our bin dir is first in path, so qmake is found ++ moc_predefs.commands = PATH $$shell_path($$[QT_INSTALL_BINS/src]);%PATH%& ++ moc_predefs.commands += $$QMAKE_CXX -Bxqmake $$QMAKE_CXXFLAGS -E ${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 ++ silent: moc_predefs.commands = @echo generating $$moc_predefs.output$$escape_expand(\n\t)@$$moc_predefs.commands ++ QMAKE_EXTRA_COMPILERS += moc_predefs ++ MOC_PREDEF_FILE = $$[QT_HOST_DATA/src]/mkspecs/features/data/dummy.cpp ++} ++ + defineReplace(mocCmdBase) { +- RET = + !isEmpty(WIN_INCLUDETEMP) { + incvar = @$$WIN_INCLUDETEMP + } else { +@@ -34,7 +51,13 @@ defineReplace(mocCmdBase) { + incvar += -I$$shell_quote($$inc) + incvar += $$QMAKE_FRAMEWORKPATH_FLAGS + } +- RET += $$QMAKE_MOC $(DEFINES) $$join(QMAKE_COMPILER_DEFINES, " -D", -D) $$incvar $$QMAKE_MOC_OPTIONS ++ ++ RET = $$QMAKE_MOC $(DEFINES) ++ ++ isEmpty(MOC_PREDEF_FILE): RET += $$join(QMAKE_COMPILER_DEFINES, " -D", -D) ++ else: RET += --include $$moc_predefs.output ++ ++ RET += $$incvar $$QMAKE_MOC_OPTIONS + return($$RET) + } + +@@ -46,7 +69,7 @@ moc_header.output = $$MOC_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAK + moc_header.input = HEADERS + moc_header.variable_out = SOURCES + moc_header.name = MOC ${QMAKE_FILE_IN} +-moc_header.depends += $$WIN_INCLUDETEMP ++moc_header.depends += $$WIN_INCLUDETEMP $$moc_predefs.output + silent:moc_header.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_header.commands + QMAKE_EXTRA_COMPILERS += moc_header + INCREDIBUILD_XGE += moc_header +@@ -58,7 +81,7 @@ moc_source.commands = ${QMAKE_FUNC_mocCmdBase} ${QMAKE_FILE_IN} -o ${QMAKE_FILE_ + moc_source.output = $$MOC_DIR/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC} + moc_source.input = SOURCES OBJECTIVE_SOURCES + moc_source.name = MOC ${QMAKE_FILE_IN} +-moc_source.depends += $$WIN_INCLUDETEMP ++moc_source.depends += $$WIN_INCLUDETEMP $$moc_predefs.output + silent:moc_source.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_source.commands + QMAKE_EXTRA_COMPILERS += moc_source + INCREDIBUILD_XGE += moc_source +diff --git a/qmake/main.cpp b/qmake/main.cpp +index bde537d..e9b8bde 100644 +--- a/qmake/main.cpp ++++ b/qmake/main.cpp +@@ -1,6 +1,7 @@ + /**************************************************************************** + ** + ** Copyright (C) 2015 The Qt Company Ltd. ++** Copyright (C) 2015 Intel Corporation. + ** Contact: http://www.qt.io/licensing/ + ** + ** This file is part of the qmake application of the Qt Toolkit. +@@ -47,6 +48,10 @@ + #include + #include + ++#ifdef Q_OS_WIN ++# include ++#endif ++ + QT_BEGIN_NAMESPACE + + #ifdef Q_OS_WIN +@@ -246,6 +251,30 @@ static int doInstall(int argc, char **argv) + return 3; + } + ++static int dumpMacros(const wchar_t *cmdline) ++{ ++ // from http://stackoverflow.com/questions/3665537/how-to-find-out-cl-exes-built-in-macros ++ int argc; ++ wchar_t **argv = CommandLineToArgvW(cmdline, &argc); ++ if (!argv) ++ return 2; ++ for (int i = 0; i < argc; ++i) { ++ if (argv[i][0] != L'-' || argv[i][1] != 'D') ++ continue; ++ ++ wchar_t *value = wcschr(argv[i], L'='); ++ if (value) { ++ *value = 0; ++ ++value; ++ } else { ++ // point to the NUL at the end, so we don't print anything ++ value = argv[i] + wcslen(argv[i]); ++ } ++ wprintf(L"#define %Ls %Ls\n", argv[i] + 2, value); ++ } ++ return 0; ++} ++ + #endif // Q_OS_WIN + + /* This is to work around lame implementation on Darwin. It has been noted that the getpwd(3) function +@@ -280,6 +309,15 @@ int runQMake(int argc, char **argv) + // Workaround for inferior/missing command line tools on Windows: make our own! + if (argc >= 2 && !strcmp(argv[1], "-install")) + return doInstall(argc - 2, argv + 2); ++ ++ { ++ // Support running as Visual C++'s compiler ++ const wchar_t *cmdline = _wgetenv(L"MSC_CMD_FLAGS"); ++ if (!cmdline || !*cmdline) ++ cmdline = _wgetenv(L"MSC_IDE_FLAGS"); ++ if (cmdline && *cmdline) ++ return dumpMacros(cmdline); ++ } + #endif + + QMakeVfs vfs; +diff --git a/src/tools/moc/main.cpp b/src/tools/moc/main.cpp +index a5cbad7..d06335d 100644 +--- a/src/tools/moc/main.cpp ++++ b/src/tools/moc/main.cpp +@@ -259,6 +259,11 @@ int runMoc(int argc, char **argv) + prependIncludeOption.setValueName(QStringLiteral("file")); + parser.addOption(prependIncludeOption); + ++ QCommandLineOption includeOption(QStringLiteral("include")); ++ includeOption.setDescription(QStringLiteral("Parse as an #include before the main source(s).")); ++ includeOption.setValueName(QStringLiteral("file")); ++ parser.addOption(includeOption); ++ + QCommandLineOption noNotesWarningsCompatOption(QStringLiteral("n")); + noNotesWarningsCompatOption.setDescription(QStringLiteral("Do not display notes (-nn) or warnings (-nw). Compatibility option.")); + noNotesWarningsCompatOption.setValueName(QStringLiteral("which")); +@@ -406,7 +411,16 @@ int runMoc(int argc, char **argv) + moc.includes = pp.includes; + + // 1. preprocess +- moc.symbols = pp.preprocessed(moc.filename, &in); ++ foreach (const QString &includeName, parser.values(includeOption)) { ++ QByteArray rawName = pp.resolveInclude(QFile::encodeName(includeName), moc.filename); ++ QFile f(QFile::decodeName(rawName)); ++ if (f.open(QIODevice::ReadOnly)) { ++ moc.symbols += Symbol(0, MOC_INCLUDE_BEGIN, rawName); ++ moc.symbols += pp.preprocessed(rawName, &f); ++ moc.symbols += Symbol(0, MOC_INCLUDE_END, rawName); ++ } ++ } ++ moc.symbols += pp.preprocessed(moc.filename, &in); + + if (!pp.preprocessOnly) { + // 2. parse +diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp +index d036c40..70cf14a 100644 +--- a/src/tools/moc/preprocessor.cpp ++++ b/src/tools/moc/preprocessor.cpp +@@ -1001,6 +1001,37 @@ static void mergeStringLiterals(Symbols *_symbols) + } + } + ++QByteArray Preprocessor::resolveInclude(const QByteArray &include, const QByteArray &relativeTo) ++{ ++ // #### stringery ++ QFileInfo fi; ++ if (!relativeTo.isEmpty()) ++ fi.setFile(QFileInfo(QString::fromLocal8Bit(relativeTo.constData())).dir(), QString::fromLocal8Bit(include.constData())); ++ for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) { ++ const IncludePath &p = Preprocessor::includes.at(j); ++ if (p.isFrameworkPath) { ++ const int slashPos = include.indexOf('/'); ++ if (slashPos == -1) ++ continue; ++ QByteArray frameworkCandidate = include.left(slashPos); ++ frameworkCandidate.append(".framework/Headers/"); ++ fi.setFile(QString::fromLocal8Bit(QByteArray(p.path + '/' + frameworkCandidate).constData()), QString::fromLocal8Bit(include.mid(slashPos + 1).constData())); ++ } else { ++ fi.setFile(QString::fromLocal8Bit(p.path.constData()), QString::fromLocal8Bit(include.constData())); ++ } ++ // try again, maybe there's a file later in the include paths with the same name ++ // (186067) ++ if (fi.isDir()) { ++ fi = QFileInfo(); ++ continue; ++ } ++ } ++ ++ if (!fi.exists() || fi.isDir()) ++ return QByteArray(); ++ return fi.canonicalFilePath().toLocal8Bit(); ++} ++ + void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) + { + currentFilenames.push(filename); +@@ -1021,33 +1052,9 @@ void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) + continue; + until(PP_NEWLINE); + +- // #### stringery +- QFileInfo fi; +- if (local) +- fi.setFile(QFileInfo(QString::fromLocal8Bit(filename.constData())).dir(), QString::fromLocal8Bit(include.constData())); +- for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) { +- const IncludePath &p = Preprocessor::includes.at(j); +- if (p.isFrameworkPath) { +- const int slashPos = include.indexOf('/'); +- if (slashPos == -1) +- continue; +- QByteArray frameworkCandidate = include.left(slashPos); +- frameworkCandidate.append(".framework/Headers/"); +- fi.setFile(QString::fromLocal8Bit(QByteArray(p.path + '/' + frameworkCandidate).constData()), QString::fromLocal8Bit(include.mid(slashPos + 1).constData())); +- } else { +- fi.setFile(QString::fromLocal8Bit(p.path.constData()), QString::fromLocal8Bit(include.constData())); +- } +- // try again, maybe there's a file later in the include paths with the same name +- // (186067) +- if (fi.isDir()) { +- fi = QFileInfo(); +- continue; +- } +- } +- +- if (!fi.exists() || fi.isDir()) ++ include = resolveInclude(include, local ? filename : QByteArray()); ++ if (include.isNull()) + continue; +- include = fi.canonicalFilePath().toLocal8Bit(); + + if (Preprocessor::preprocessedIncludes.contains(include)) + continue; +@@ -1202,6 +1209,7 @@ Symbols Preprocessor::preprocessed(const QByteArray &filename, QFile *file) + input = cleaned(input); + + // phase 2: tokenize for the preprocessor ++ index = 0; + symbols = tokenize(input); + + #if 0 +diff --git a/src/tools/moc/preprocessor.h b/src/tools/moc/preprocessor.h +index 9c81f86..d876caf 100644 +--- a/src/tools/moc/preprocessor.h ++++ b/src/tools/moc/preprocessor.h +@@ -67,6 +67,7 @@ public: + QList frameworks; + QSet preprocessedIncludes; + Macros macros; ++ QByteArray resolveInclude(const QByteArray &filename, const QByteArray &relativeTo); + Symbols preprocessed(const QByteArray &filename, QFile *device); + + void parseDefineArguments(Macro *m); +diff --git a/tests/auto/tools/moc/subdir/extradefines.h b/tests/auto/tools/moc/subdir/extradefines.h +new file mode 100644 +index 0000000..e7888ce +--- /dev/null ++++ b/tests/auto/tools/moc/subdir/extradefines.h +@@ -0,0 +1 @@ ++#define FOO 1 +diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp +index fa1b68b..1d6a911 100644 +--- a/tests/auto/tools/moc/tst_moc.cpp ++++ b/tests/auto/tools/moc/tst_moc.cpp +@@ -552,6 +552,8 @@ private slots: + void frameworkSearchPath(); + void cstyleEnums(); + void defineMacroViaCmdline(); ++ void defineMacroViaForcedInclude(); ++ void defineMacroViaForcedIncludeRelative(); + void specifyMetaTagsFromCmdline(); + void invokable(); + void singleFunctionKeywordSignalAndSlot(); +@@ -1219,6 +1221,46 @@ void tst_Moc::defineMacroViaCmdline() + #endif + } + ++void tst_Moc::defineMacroViaForcedInclude() ++{ ++#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) ++ QProcess proc; ++ ++ QStringList args; ++ args << "--include" << m_sourceDirectory + QLatin1String("/subdir/extradefines.h"); ++ args << m_sourceDirectory + QStringLiteral("/macro-on-cmdline.h"); ++ ++ proc.start(m_moc, args); ++ QVERIFY(proc.waitForFinished()); ++ QCOMPARE(proc.exitCode(), 0); ++ QCOMPARE(proc.readAllStandardError(), QByteArray()); ++ QByteArray mocOut = proc.readAllStandardOutput(); ++ QVERIFY(!mocOut.isEmpty()); ++#else ++ QSKIP("Only tested on linux/gcc"); ++#endif ++} ++ ++void tst_Moc::defineMacroViaForcedIncludeRelative() ++{ ++#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) ++ QProcess proc; ++ ++ QStringList args; ++ args << "--include" << QStringLiteral("extradefines.h") << "-I" + m_sourceDirectory + "/subdir"; ++ args << m_sourceDirectory + QStringLiteral("/macro-on-cmdline.h"); ++ ++ proc.start(m_moc, args); ++ QVERIFY(proc.waitForFinished()); ++ QCOMPARE(proc.exitCode(), 0); ++ QCOMPARE(proc.readAllStandardError(), QByteArray()); ++ QByteArray mocOut = proc.readAllStandardOutput(); ++ QVERIFY(!mocOut.isEmpty()); ++#else ++ QSKIP("Only tested on linux/gcc"); ++#endif ++} ++ + // tst_Moc::specifyMetaTagsFromCmdline() + // plugin_metadata.h contains a plugin which we register here. Since we're not building this + // application as a plugin, we need top copy some of the initializer code found in qplugin.h: +-- +1.9.3 + diff --git a/SOURCES/qconfig-multilib.h b/SOURCES/qconfig-multilib.h new file mode 100644 index 0000000..a104c37 --- /dev/null +++ b/SOURCES/qconfig-multilib.h @@ -0,0 +1,23 @@ +/* qconfig.h */ +/* This file is here to prevent a file conflict on multiarch systems. A + * conflict will occur because qconfig.h has arch-specific definitions. + * + * DO NOT INCLUDE THE NEW FILE DIRECTLY -- ALWAYS INCLUDE THIS ONE INSTEAD. */ + +#ifndef QCONFIG_MULTILIB_H +#define QCONFIG_MULTILIB_H + +#ifndef __WORDSIZE +#include +#endif + +#if __WORDSIZE == 32 +#include "QtCore/qconfig-32.h" +#elif __WORDSIZE == 64 +#include "QtCore/qconfig-64.h" +#else +#error "unexpected value for __WORDSIZE macro" +#endif + +#endif + diff --git a/SOURCES/qt5-poll.patch b/SOURCES/qt5-poll.patch new file mode 100644 index 0000000..1dd739b --- /dev/null +++ b/SOURCES/qt5-poll.patch @@ -0,0 +1,2254 @@ +diff --git a/config.tests/unix/poll/poll.cpp b/config.tests/unix/poll/poll.cpp +new file mode 100644 +index 0000000..06ae038 +--- /dev/null ++++ b/config.tests/unix/poll/poll.cpp +@@ -0,0 +1,45 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2015 The Qt Company Ltd. ++** Contact: http://www.qt.io/licensing/ ++** ++** This file is part of the config.tests of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL21$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see http://www.qt.io/terms-conditions. For further ++** information use the contact form at http://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 2.1 or version 3 as published by the Free ++** Software Foundation and appearing in the file LICENSE.LGPLv21 and ++** LICENSE.LGPLv3 included in the packaging of this file. Please review the ++** following information to ensure the GNU Lesser General Public License ++** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ++** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ++** ++** As a special exception, The Qt Company gives you certain additional ++** rights. These rights are described in The Qt Company LGPL Exception ++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++#include ++ ++int main() ++{ ++ struct pollfd pfd; ++ ++ pfd.fd = -1; ++ pfd.events = 0; ++ pfd.revents = 0; ++ ++ return ::poll(&pfd, 1, 0); ++} +diff --git a/config.tests/unix/poll/poll.pro b/config.tests/unix/poll/poll.pro +new file mode 100644 +index 0000000..70121b4 +--- /dev/null ++++ b/config.tests/unix/poll/poll.pro +@@ -0,0 +1,2 @@ ++SOURCES = poll.cpp ++CONFIG -= qt +diff --git a/config.tests/unix/pollts/poll/poll.cpp b/config.tests/unix/pollts/poll/poll.cpp +new file mode 100644 +index 0000000..06ae038 +--- /dev/null ++++ b/config.tests/unix/pollts/poll/poll.cpp +@@ -0,0 +1,45 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2015 The Qt Company Ltd. ++** Contact: http://www.qt.io/licensing/ ++** ++** This file is part of the config.tests of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL21$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see http://www.qt.io/terms-conditions. For further ++** information use the contact form at http://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 2.1 or version 3 as published by the Free ++** Software Foundation and appearing in the file LICENSE.LGPLv21 and ++** LICENSE.LGPLv3 included in the packaging of this file. Please review the ++** following information to ensure the GNU Lesser General Public License ++** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ++** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ++** ++** As a special exception, The Qt Company gives you certain additional ++** rights. These rights are described in The Qt Company LGPL Exception ++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++#include ++ ++int main() ++{ ++ struct pollfd pfd; ++ ++ pfd.fd = -1; ++ pfd.events = 0; ++ pfd.revents = 0; ++ ++ return ::poll(&pfd, 1, 0); ++} +diff --git a/config.tests/unix/pollts/poll/poll.pro b/config.tests/unix/pollts/poll/poll.pro +new file mode 100644 +index 0000000..70121b4 +--- /dev/null ++++ b/config.tests/unix/pollts/poll/poll.pro +@@ -0,0 +1,2 @@ ++SOURCES = poll.cpp ++CONFIG -= qt +diff --git a/config.tests/unix/pollts/pollts.cpp b/config.tests/unix/pollts/pollts.cpp +new file mode 100644 +index 0000000..c2d1940 +--- /dev/null ++++ b/config.tests/unix/pollts/pollts.cpp +@@ -0,0 +1,51 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2015 The Qt Company Ltd. ++** Contact: http://www.qt.io/licensing/ ++** ++** This file is part of the config.tests of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL21$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see http://www.qt.io/terms-conditions. For further ++** information use the contact form at http://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 2.1 or version 3 as published by the Free ++** Software Foundation and appearing in the file LICENSE.LGPLv21 and ++** LICENSE.LGPLv3 included in the packaging of this file. Please review the ++** following information to ensure the GNU Lesser General Public License ++** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ++** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ++** ++** As a special exception, The Qt Company gives you certain additional ++** rights. These rights are described in The Qt Company LGPL Exception ++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++#include ++#include ++#include ++ ++int main() ++{ ++ struct pollfd pfd; ++ struct timespec ts; ++ ++ pfd.fd = -1; ++ pfd.events = 0; ++ pfd.revents = 0; ++ ++ ts.tv_sec = 0; ++ ts.tv_nsec = 0; ++ ++ return ::pollts(&pfd, 1, &ts, nullptr); ++} +diff --git a/config.tests/unix/pollts/pollts/poll/poll.cpp b/config.tests/unix/pollts/pollts/poll/poll.cpp +new file mode 100644 +index 0000000..06ae038 +--- /dev/null ++++ b/config.tests/unix/pollts/pollts/poll/poll.cpp +@@ -0,0 +1,45 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2015 The Qt Company Ltd. ++** Contact: http://www.qt.io/licensing/ ++** ++** This file is part of the config.tests of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL21$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see http://www.qt.io/terms-conditions. For further ++** information use the contact form at http://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 2.1 or version 3 as published by the Free ++** Software Foundation and appearing in the file LICENSE.LGPLv21 and ++** LICENSE.LGPLv3 included in the packaging of this file. Please review the ++** following information to ensure the GNU Lesser General Public License ++** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ++** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ++** ++** As a special exception, The Qt Company gives you certain additional ++** rights. These rights are described in The Qt Company LGPL Exception ++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++#include ++ ++int main() ++{ ++ struct pollfd pfd; ++ ++ pfd.fd = -1; ++ pfd.events = 0; ++ pfd.revents = 0; ++ ++ return ::poll(&pfd, 1, 0); ++} +diff --git a/config.tests/unix/pollts/pollts/poll/poll.pro b/config.tests/unix/pollts/pollts/poll/poll.pro +new file mode 100644 +index 0000000..70121b4 +--- /dev/null ++++ b/config.tests/unix/pollts/pollts/poll/poll.pro +@@ -0,0 +1,2 @@ ++SOURCES = poll.cpp ++CONFIG -= qt +diff --git a/config.tests/unix/pollts/pollts/pollts.cpp b/config.tests/unix/pollts/pollts/pollts.cpp +new file mode 100644 +index 0000000..8b13789 +--- /dev/null ++++ b/config.tests/unix/pollts/pollts/pollts.cpp +@@ -0,0 +1 @@ ++ +diff --git a/config.tests/unix/pollts/pollts/pollts.pro b/config.tests/unix/pollts/pollts/pollts.pro +new file mode 100644 +index 0000000..5109dc3 +--- /dev/null ++++ b/config.tests/unix/pollts/pollts/pollts.pro +@@ -0,0 +1,2 @@ ++SOURCES = pollts.cpp ++CONFIG -= qt +diff --git a/config.tests/unix/ppoll/ppoll.cpp b/config.tests/unix/ppoll/ppoll.cpp +new file mode 100644 +index 0000000..5b0cc4d +--- /dev/null ++++ b/config.tests/unix/ppoll/ppoll.cpp +@@ -0,0 +1,51 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2015 The Qt Company Ltd. ++** Contact: http://www.qt.io/licensing/ ++** ++** This file is part of the config.tests of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL21$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see http://www.qt.io/terms-conditions. For further ++** information use the contact form at http://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 2.1 or version 3 as published by the Free ++** Software Foundation and appearing in the file LICENSE.LGPLv21 and ++** LICENSE.LGPLv3 included in the packaging of this file. Please review the ++** following information to ensure the GNU Lesser General Public License ++** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ++** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ++** ++** As a special exception, The Qt Company gives you certain additional ++** rights. These rights are described in The Qt Company LGPL Exception ++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++#include ++#include ++ ++int main() ++{ ++ struct pollfd pfd; ++ struct timespec ts; ++ ++ pfd.fd = -1; ++ pfd.events = 0; ++ pfd.revents = 0; ++ ++ ts.tv_sec = 0; ++ ts.tv_nsec = 0; ++ ++ return ::ppoll(&pfd, 1, &ts, nullptr); ++} ++ +diff --git a/config.tests/unix/ppoll/ppoll.pro b/config.tests/unix/ppoll/ppoll.pro +new file mode 100644 +index 0000000..d08a8a0 +--- /dev/null ++++ b/config.tests/unix/ppoll/ppoll.pro +@@ -0,0 +1,2 @@ ++SOURCES = ppoll.cpp ++CONFIG -= qt +diff --git a/configure b/configure +index 7651e29..9be4179 100755 +--- a/configure ++++ b/configure +@@ -729,6 +729,7 @@ CFG_GETIFADDRS=auto + CFG_INOTIFY=auto + CFG_EVENTFD=auto + CFG_CLOEXEC=no ++CFG_POLL=auto + CFG_RPATH=yes + CFG_FRAMEWORK=auto + CFG_USE_GOLD_LINKER=auto +@@ -6043,6 +6044,16 @@ if compileTest unix/cloexec "cloexec"; then + CFG_CLOEXEC=yes + fi + ++if compileTest unix/ppoll "ppoll"; then ++ CFG_POLL="ppoll" ++elif compileTest unix/pollts "pollts"; then ++ CFG_POLL="pollts" ++elif compileTest unix/poll "poll"; then ++ CFG_POLL="poll" ++else ++ CFG_POLL="select" ++fi ++ + if [ "$XPLATFORM_MAC" = "yes" ] && [ "$CFG_SECURETRANSPORT" != "no" ] && ([ "$CFG_OPENSSL" = "no" ] || [ "$CFG_OPENSSL" = "auto" ]); then + CFG_SECURETRANSPORT=yes + CFG_OPENSSL=no +@@ -6350,6 +6361,10 @@ fi + if [ "$CFG_CLOEXEC" = "yes" ]; then + QT_CONFIG="$QT_CONFIG threadsafe-cloexec" + fi ++if [ "$CFG_POLL" = "select" ]; then ++ QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_NATIVE_POLL" ++fi ++QT_CONFIG="$QT_CONFIG poll_$CFG_POLL" + if [ "$CFG_LIBJPEG" = "no" ]; then + CFG_JPEG="no" + elif [ "$CFG_LIBJPEG" = "system" ]; then +diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp +index 8eb5ac9..74a0c41 100644 +--- a/src/corelib/io/qprocess_unix.cpp ++++ b/src/corelib/io/qprocess_unix.cpp +@@ -115,11 +115,52 @@ QT_BEGIN_NAMESPACE + // so we will use 512 + static const int errorBufferMax = 512; + +-static inline void add_fd(int &nfds, int fd, fd_set *fdset) ++namespace { ++struct QProcessPoller + { +- FD_SET(fd, fdset); +- if ((fd) > nfds) +- nfds = fd; ++ QProcessPoller(const QProcessPrivate &proc); ++ ++ int poll(int timeout); ++ ++ pollfd &stdinPipe() { return pfds[0]; } ++ pollfd &stdoutPipe() { return pfds[1]; } ++ pollfd &stderrPipe() { return pfds[2]; } ++ pollfd &forkfd() { return pfds[3]; } ++ pollfd &childStartedPipe() { return pfds[4]; } ++ ++ enum { n_pfds = 5 }; ++ pollfd pfds[n_pfds]; ++}; ++ ++QProcessPoller::QProcessPoller(const QProcessPrivate &proc) ++{ ++ for (int i = 0; i < n_pfds; i++) ++ pfds[i] = qt_make_pollfd(-1, POLLIN); ++ ++ stdoutPipe().fd = proc.stdoutChannel.pipe[0]; ++ stderrPipe().fd = proc.stderrChannel.pipe[0]; ++ ++ if (!proc.stdinChannel.buffer.isEmpty()) { ++ stdinPipe().fd = proc.stdinChannel.pipe[1]; ++ stdinPipe().events = POLLOUT; ++ } ++ ++ forkfd().fd = proc.forkfd; ++ ++ if (proc.processState == QProcess::Starting) ++ childStartedPipe().fd = proc.childStartedPipe[0]; ++} ++ ++int QProcessPoller::poll(int timeout) ++{ ++ const nfds_t nfds = (childStartedPipe().fd == -1) ? 4 : 5; ++ return qt_poll_msecs(pfds, nfds, timeout); ++} ++} // anonymous namespace ++ ++static bool qt_pollfd_check(const pollfd &pfd, short revents) ++{ ++ return pfd.fd >= 0 && (pfd.revents & (revents | POLLHUP | POLLERR | POLLNVAL)) != 0; + } + + static int qt_create_pipe(int *pipe) +@@ -812,10 +853,9 @@ bool QProcessPrivate::waitForStarted(int msecs) + childStartedPipe[0]); + #endif + +- fd_set fds; +- FD_ZERO(&fds); +- FD_SET(childStartedPipe[0], &fds); +- if (qt_select_msecs(childStartedPipe[0] + 1, &fds, 0, msecs) == 0) { ++ pollfd pfd = qt_make_pollfd(childStartedPipe[0], POLLIN); ++ ++ if (qt_poll_msecs(&pfd, 1, msecs) == 0) { + setError(QProcess::Timedout); + #if defined (QPROCESS_DEBUG) + qDebug("QProcessPrivate::waitForStarted(%d) == false (timed out)", msecs); +@@ -855,31 +895,13 @@ bool QProcessPrivate::waitForReadyRead(int msecs) + #endif + + forever { +- fd_set fdread; +- fd_set fdwrite; +- +- FD_ZERO(&fdread); +- FD_ZERO(&fdwrite); +- +- int nfds = forkfd; +- FD_SET(forkfd, &fdread); +- +- if (processState == QProcess::Starting) +- add_fd(nfds, childStartedPipe[0], &fdread); +- +- if (stdoutChannel.pipe[0] != -1) +- add_fd(nfds, stdoutChannel.pipe[0], &fdread); +- if (stderrChannel.pipe[0] != -1) +- add_fd(nfds, stderrChannel.pipe[0], &fdread); +- +- if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1) +- add_fd(nfds, stdinChannel.pipe[1], &fdwrite); ++ QProcessPoller poller(*this); + + int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed()); + #ifdef Q_OS_BLACKBERRY + int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout); + #else +- int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout); ++ int ret = poller.poll(timeout); + #endif + if (ret < 0) { + break; +@@ -889,18 +911,18 @@ bool QProcessPrivate::waitForReadyRead(int msecs) + return false; + } + +- if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) { ++ if (qt_pollfd_check(poller.childStartedPipe(), POLLIN)) { + if (!_q_startupNotification()) + return false; + } + + bool readyReadEmitted = false; +- if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) { ++ if (qt_pollfd_check(poller.stdoutPipe(), POLLIN)) { + bool canRead = _q_canReadStandardOutput(); + if (processChannel == QProcess::StandardOutput && canRead) + readyReadEmitted = true; + } +- if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) { ++ if (qt_pollfd_check(poller.stderrPipe(), POLLIN)) { + bool canRead = _q_canReadStandardError(); + if (processChannel == QProcess::StandardError && canRead) + readyReadEmitted = true; +@@ -908,10 +930,10 @@ bool QProcessPrivate::waitForReadyRead(int msecs) + if (readyReadEmitted) + return true; + +- if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite)) ++ if (qt_pollfd_check(poller.stdinPipe(), POLLOUT)) + _q_canWrite(); + +- if (forkfd == -1 || FD_ISSET(forkfd, &fdread)) { ++ if (qt_pollfd_check(poller.forkfd(), POLLIN)) { + if (_q_processDied()) + return false; + } +@@ -933,32 +955,13 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) + #endif + + while (!stdinChannel.buffer.isEmpty()) { +- fd_set fdread; +- fd_set fdwrite; +- +- FD_ZERO(&fdread); +- FD_ZERO(&fdwrite); +- +- int nfds = forkfd; +- FD_SET(forkfd, &fdread); +- +- if (processState == QProcess::Starting) +- add_fd(nfds, childStartedPipe[0], &fdread); +- +- if (stdoutChannel.pipe[0] != -1) +- add_fd(nfds, stdoutChannel.pipe[0], &fdread); +- if (stderrChannel.pipe[0] != -1) +- add_fd(nfds, stderrChannel.pipe[0], &fdread); +- +- +- if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1) +- add_fd(nfds, stdinChannel.pipe[1], &fdwrite); ++ QProcessPoller poller(*this); + + int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed()); + #ifdef Q_OS_BLACKBERRY + int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout); + #else +- int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout); ++ int ret = poller.poll(timeout); + #endif + if (ret < 0) { + break; +@@ -969,21 +972,21 @@ bool QProcessPrivate::waitForBytesWritten(int msecs) + return false; + } + +- if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) { ++ if (qt_pollfd_check(poller.childStartedPipe(), POLLIN)) { + if (!_q_startupNotification()) + return false; + } + +- if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite)) ++ if (qt_pollfd_check(poller.stdinPipe(), POLLOUT)) + return _q_canWrite(); + +- if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) ++ if (qt_pollfd_check(poller.stdoutPipe(), POLLIN)) + _q_canReadStandardOutput(); + +- if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) ++ if (qt_pollfd_check(poller.stderrPipe(), POLLIN)) + _q_canReadStandardError(); + +- if (forkfd == -1 || FD_ISSET(forkfd, &fdread)) { ++ if (qt_pollfd_check(poller.forkfd(), POLLIN)) { + if (_q_processDied()) + return false; + } +@@ -1006,32 +1009,13 @@ bool QProcessPrivate::waitForFinished(int msecs) + #endif + + forever { +- fd_set fdread; +- fd_set fdwrite; +- int nfds = -1; +- +- FD_ZERO(&fdread); +- FD_ZERO(&fdwrite); +- +- if (processState == QProcess::Starting) +- add_fd(nfds, childStartedPipe[0], &fdread); +- +- if (stdoutChannel.pipe[0] != -1) +- add_fd(nfds, stdoutChannel.pipe[0], &fdread); +- if (stderrChannel.pipe[0] != -1) +- add_fd(nfds, stderrChannel.pipe[0], &fdread); +- +- if (processState == QProcess::Running && forkfd != -1) +- add_fd(nfds, forkfd, &fdread); +- +- if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1) +- add_fd(nfds, stdinChannel.pipe[1], &fdwrite); ++ QProcessPoller poller(*this); + + int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed()); + #ifdef Q_OS_BLACKBERRY + int ret = bb_select(notifiers, nfds + 1, &fdread, &fdwrite, timeout); + #else +- int ret = qt_select_msecs(nfds + 1, &fdread, &fdwrite, timeout); ++ int ret = poller.poll(timeout); + #endif + if (ret < 0) { + break; +@@ -1041,20 +1025,20 @@ bool QProcessPrivate::waitForFinished(int msecs) + return false; + } + +- if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) { ++ if (qt_pollfd_check(poller.childStartedPipe(), POLLIN)) { + if (!_q_startupNotification()) + return false; + } +- if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite)) ++ if (qt_pollfd_check(poller.stdinPipe(), POLLOUT)) + _q_canWrite(); + +- if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) ++ if (qt_pollfd_check(poller.stdoutPipe(), POLLIN)) + _q_canReadStandardOutput(); + +- if (stderrChannel.pipe[0] != -1 && FD_ISSET(stderrChannel.pipe[0], &fdread)) ++ if (qt_pollfd_check(poller.stderrPipe(), POLLIN)) + _q_canReadStandardError(); + +- if (forkfd == -1 || FD_ISSET(forkfd, &fdread)) { ++ if (qt_pollfd_check(poller.forkfd(), POLLIN)) { + if (_q_processDied()) + return true; + } +@@ -1064,10 +1048,8 @@ bool QProcessPrivate::waitForFinished(int msecs) + + bool QProcessPrivate::waitForWrite(int msecs) + { +- fd_set fdwrite; +- FD_ZERO(&fdwrite); +- FD_SET(stdinChannel.pipe[1], &fdwrite); +- return qt_select_msecs(stdinChannel.pipe[1] + 1, 0, &fdwrite, msecs < 0 ? 0 : msecs) == 1; ++ pollfd pfd = qt_make_pollfd(stdinChannel.pipe[1], POLLOUT); ++ return qt_poll_msecs(&pfd, 1, msecs < 0 ? 0 : msecs) == 1; + } + + void QProcessPrivate::findExitCode() +diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri +index bc93791..ff64b4e 100644 +--- a/src/corelib/kernel/kernel.pri ++++ b/src/corelib/kernel/kernel.pri +@@ -143,8 +143,14 @@ unix|integrity { + kernel/qcore_unix_p.h \ + kernel/qcrashhandler_p.h \ + kernel/qeventdispatcher_unix_p.h \ ++ kernel/qpoll_p.h \ + kernel/qtimerinfo_unix_p.h + ++ contains(QT_CONFIG, poll_select): SOURCES += kernel/qpoll.cpp ++ contains(QT_CONFIG, poll_poll): DEFINES += QT_HAVE_POLL ++ contains(QT_CONFIG, poll_ppoll): DEFINES += QT_HAVE_POLL QT_HAVE_PPOLL ++ contains(QT_CONFIG, poll_pollts): DEFINES += QT_HAVE_POLL QT_HAVE_POLLTS ++ + contains(QT_CONFIG, glib) { + SOURCES += \ + kernel/qeventdispatcher_glib.cpp +diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp +index 5695cb3..2ffc746 100644 +--- a/src/corelib/kernel/qcore_unix.cpp ++++ b/src/corelib/kernel/qcore_unix.cpp +@@ -56,6 +56,11 @@ + + QT_BEGIN_NAMESPACE + ++#if !defined(QT_HAVE_PPOLL) && defined(QT_HAVE_POLLTS) ++# define ppoll pollts ++# define QT_HAVE_PPOLL ++#endif ++ + static inline bool time_update(struct timespec *tv, const struct timespec &start, + const struct timespec &timeout) + { +@@ -85,9 +90,7 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, + #ifndef Q_OS_QNX + ret = ::pselect(nfds, fdread, fdwrite, fdexcept, &timeout, 0); + #else +- timeval timeoutVal; +- timeoutVal.tv_sec = timeout.tv_sec; +- timeoutVal.tv_usec = timeout.tv_nsec / 1000; ++ timeval timeoutVal = timespecToTimeval(timeout); + ret = ::select(nfds, fdread, fdwrite, fdexcept, &timeoutVal); + #endif + if (ret != -1 || errno != EINTR) +@@ -102,17 +105,82 @@ int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, + } + } + ++static inline struct timespec millisecsToTimespec(const unsigned int ms) ++{ ++ struct timespec tv; ++ ++ tv.tv_sec = ms / 1000; ++ tv.tv_nsec = (ms % 1000) * 1000 * 1000; ++ ++ return tv; ++} ++ + int qt_select_msecs(int nfds, fd_set *fdread, fd_set *fdwrite, int timeout) + { + if (timeout < 0) + return qt_safe_select(nfds, fdread, fdwrite, 0, 0); + +- struct timespec tv; +- tv.tv_sec = timeout / 1000; +- tv.tv_nsec = (timeout % 1000) * 1000 * 1000; ++ struct timespec tv = millisecsToTimespec(timeout); + return qt_safe_select(nfds, fdread, fdwrite, 0, &tv); + } + ++#if !defined(QT_HAVE_PPOLL) && defined(QT_HAVE_POLL) ++static inline int timespecToMillisecs(const struct timespec *ts) ++{ ++ return (ts == NULL) ? -1 : ++ (ts->tv_sec * 1000) + (ts->tv_nsec / 1000000); ++} ++#endif ++ ++// defined in qpoll.cpp ++int qt_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts); ++ ++static inline int qt_ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts) ++{ ++#if defined(QT_HAVE_PPOLL) ++ return ::ppoll(fds, nfds, timeout_ts, Q_NULLPTR); ++#elif defined(QT_HAVE_POLL) ++ return ::poll(fds, nfds, timespecToMillisecs(timeout_ts)); ++#else ++ return qt_poll(fds, nfds, timeout_ts); ++#endif ++} ++ ++ ++/*! ++ \internal ++ ++ Behaves as close to POSIX poll(2) as practical but may be implemented ++ using select(2) where necessary. In that case, returns -1 and sets errno ++ to EINVAL if passed any descriptor greater than or equal to FD_SETSIZE. ++*/ ++int qt_safe_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts) ++{ ++ if (!timeout_ts) { ++ // no timeout -> block forever ++ int ret; ++ EINTR_LOOP(ret, qt_ppoll(fds, nfds, Q_NULLPTR)); ++ return ret; ++ } ++ ++ timespec start = qt_gettime(); ++ timespec timeout = *timeout_ts; ++ ++ // loop and recalculate the timeout as needed ++ forever { ++ const int ret = qt_ppoll(fds, nfds, &timeout); ++ if (ret != -1 || errno != EINTR) ++ return ret; ++ ++ // recalculate the timeout ++ if (!time_update(&timeout, start, *timeout_ts)) { ++ // timeout during update ++ // or clock reset, fake timeout error ++ return 0; ++ } ++ } ++} ++ + #ifdef Q_OS_BLACKBERRY + // The BlackBerry event dispatcher uses bps_get_event. Unfortunately, already registered + // socket notifiers are disabled by a call to select. This is to rearm the standard streams. +diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h +index f80dcb5..fc3f63b 100644 +--- a/src/corelib/kernel/qcore_unix_p.h ++++ b/src/corelib/kernel/qcore_unix_p.h +@@ -66,6 +66,12 @@ + # include + #endif + ++#ifdef QT_NO_NATIVE_POLL ++# include "qpoll_p.h" ++#else ++# include ++#endif ++ + struct sockaddr; + + #define EINTR_LOOP(var, cmd) \ +@@ -122,6 +128,14 @@ inline timespec operator*(const timespec &t1, int mul) + return normalizedTimespec(tmp); + } + ++inline timeval timespecToTimeval(const timespec &ts) ++{ ++ timeval tv; ++ tv.tv_sec = ts.tv_sec; ++ tv.tv_usec = ts.tv_nsec / 1000; ++ return tv; ++} ++ + inline void qt_ignore_sigpipe() + { + // Set to ignore SIGPIPE once only. +@@ -303,6 +317,27 @@ static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options) + timespec qt_gettime() Q_DECL_NOTHROW; + void qt_nanosleep(timespec amount); + ++Q_CORE_EXPORT int qt_safe_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts); ++ ++static inline int qt_poll_msecs(struct pollfd *fds, nfds_t nfds, int timeout) ++{ ++ timespec ts, *pts = Q_NULLPTR; ++ ++ if (timeout >= 0) { ++ ts.tv_sec = timeout / 1000; ++ ts.tv_nsec = (timeout % 1000) * 1000 * 1000; ++ pts = &ts; ++ } ++ ++ return qt_safe_poll(fds, nfds, pts); ++} ++ ++static inline struct pollfd qt_make_pollfd(int fd, short events) ++{ ++ struct pollfd pfd = { fd, events, 0 }; ++ return pfd; ++} ++ + Q_CORE_EXPORT int qt_safe_select(int nfds, fd_set *fdread, fd_set *fdwrite, fd_set *fdexcept, + const struct timespec *tv); + +diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp +index 155f7b7..7d23283 100644 +--- a/src/corelib/kernel/qeventdispatcher_unix.cpp ++++ b/src/corelib/kernel/qeventdispatcher_unix.cpp +@@ -59,7 +59,7 @@ + # define _POSIX_MONOTONIC_CLOCK 1 + # endif + # include +-# include ++# include + #endif + + #if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED) +@@ -68,6 +68,20 @@ + + QT_BEGIN_NAMESPACE + ++static const char *socketType(QSocketNotifier::Type type) ++{ ++ switch (type) { ++ case QSocketNotifier::Read: ++ return "Read"; ++ case QSocketNotifier::Write: ++ return "Write"; ++ case QSocketNotifier::Exception: ++ return "Exception"; ++ } ++ ++ Q_UNREACHABLE(); ++} ++ + #if defined(Q_OS_INTEGRITY) || defined(Q_OS_VXWORKS) + static void initThreadPipeFD(int fd) + { +@@ -137,8 +151,6 @@ QEventDispatcherUNIXPrivate::QEventDispatcherUNIXPrivate() + + if (pipefail) + qFatal("QEventDispatcherUNIXPrivate(): Can not continue without a thread pipe"); +- +- sn_highest = -1; + } + + QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate() +@@ -163,116 +175,11 @@ QEventDispatcherUNIXPrivate::~QEventDispatcherUNIXPrivate() + qDeleteAll(timerList); + } + +-int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, timespec *timeout) +-{ +- Q_Q(QEventDispatcherUNIX); +- +- // needed in QEventDispatcherUNIX::select() +- timerList.updateCurrentTime(); +- +- int nsel; +- do { +- // Process timers and socket notifiers - the common UNIX stuff +- int highest = 0; +- if (! (flags & QEventLoop::ExcludeSocketNotifiers) && (sn_highest >= 0)) { +- // return the highest fd we can wait for input on +- sn_vec[0].select_fds = sn_vec[0].enabled_fds; +- sn_vec[1].select_fds = sn_vec[1].enabled_fds; +- sn_vec[2].select_fds = sn_vec[2].enabled_fds; +- highest = sn_highest; +- } else { +- FD_ZERO(&sn_vec[0].select_fds); +- FD_ZERO(&sn_vec[1].select_fds); +- FD_ZERO(&sn_vec[2].select_fds); +- } +- +- int wakeUpFd = initThreadWakeUp(); +- highest = qMax(highest, wakeUpFd); +- +- nsel = q->select(highest + 1, +- &sn_vec[0].select_fds, +- &sn_vec[1].select_fds, +- &sn_vec[2].select_fds, +- timeout); +- } while (nsel == -1 && (errno == EINTR || errno == EAGAIN)); +- +- if (nsel == -1) { +- if (errno == EBADF) { +- // it seems a socket notifier has a bad fd... find out +- // which one it is and disable it +- fd_set fdset; +- timeval tm; +- tm.tv_sec = tm.tv_usec = 0l; +- +- for (int type = 0; type < 3; ++type) { +- QSockNotType::List &list = sn_vec[type].list; +- if (list.size() == 0) +- continue; +- +- for (int i = 0; i < list.size(); ++i) { +- QSockNot *sn = list[i]; +- +- FD_ZERO(&fdset); +- FD_SET(sn->fd, &fdset); +- +- int ret = -1; +- do { +- switch (type) { +- case 0: // read +- ret = select(sn->fd + 1, &fdset, 0, 0, &tm); +- break; +- case 1: // write +- ret = select(sn->fd + 1, 0, &fdset, 0, &tm); +- break; +- case 2: // except +- ret = select(sn->fd + 1, 0, 0, &fdset, &tm); +- break; +- } +- } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); +- +- if (ret == -1 && errno == EBADF) { +- // disable the invalid socket notifier +- static const char *t[] = { "Read", "Write", "Exception" }; +- qWarning("QSocketNotifier: Invalid socket %d and type '%s', disabling...", +- sn->fd, t[type]); +- sn->obj->setEnabled(false); +- } +- } +- } +- } else { +- // EINVAL... shouldn't happen, so let's complain to stderr +- // and hope someone sends us a bug report +- perror("select"); +- } +- } +- +- int nevents = processThreadWakeUp(nsel); +- +- // activate socket notifiers +- if (! (flags & QEventLoop::ExcludeSocketNotifiers) && nsel > 0 && sn_highest >= 0) { +- // if select says data is ready on any socket, then set the socket notifier +- // to pending +- for (int i=0; i<3; i++) { +- QSockNotType::List &list = sn_vec[i].list; +- for (int j = 0; j < list.size(); ++j) { +- QSockNot *sn = list[j]; +- if (FD_ISSET(sn->fd, &sn_vec[i].select_fds)) +- q->setSocketNotifierPending(sn->obj); +- } +- } +- } +- return (nevents + q->activateSocketNotifiers()); +-} +- +-int QEventDispatcherUNIXPrivate::initThreadWakeUp() ++int QEventDispatcherUNIXPrivate::processThreadWakeUp(const pollfd &pfd) + { +- FD_SET(thread_pipe[0], &sn_vec[0].select_fds); +- return thread_pipe[0]; +-} ++ Q_ASSERT(pfd.fd == thread_pipe[0]); + +-int QEventDispatcherUNIXPrivate::processThreadWakeUp(int nsel) +-{ +- if (nsel > 0 && FD_ISSET(thread_pipe[0], &sn_vec[0].select_fds)) { ++ if (pfd.revents & POLLIN) { + // some other thread woke us up... consume the data on the thread pipe so that + // select doesn't immediately return next time + #if defined(Q_OS_VXWORKS) +@@ -302,6 +209,80 @@ int QEventDispatcherUNIXPrivate::processThreadWakeUp(int nsel) + return 0; + } + ++void QEventDispatcherUNIXPrivate::setSocketNotifierPending(QSocketNotifier *notifier) ++{ ++ Q_ASSERT(notifier); ++ ++ if (pendingNotifiers.contains(notifier)) ++ return; ++ ++ pendingNotifiers << notifier; ++} ++ ++int QEventDispatcherUNIXPrivate::activateTimers() ++{ ++ return timerList.activateTimers(); ++} ++ ++void QEventDispatcherUNIXPrivate::markPendingSocketNotifiers() ++{ ++ foreach (const pollfd &pfd, pollfds) { ++ if (pfd.fd < 0 || pfd.revents == 0) ++ continue; ++ ++ auto it = socketNotifiers.find(pfd.fd); ++ Q_ASSERT(it != socketNotifiers.end()); ++ ++ const QSocketNotifierSetUNIX &sn_set = it.value(); ++ ++ static const struct { ++ QSocketNotifier::Type type; ++ short flags; ++ } notifiers[] = { ++ { QSocketNotifier::Read, POLLIN | POLLHUP | POLLERR }, ++ { QSocketNotifier::Write, POLLOUT | POLLHUP | POLLERR }, ++ { QSocketNotifier::Exception, POLLPRI | POLLHUP | POLLERR } ++ }; ++ ++ for (const auto &n : notifiers) { ++ QSocketNotifier *notifier = sn_set.notifiers[n.type]; ++ ++ if (!notifier) ++ continue; ++ ++ if (pfd.revents & POLLNVAL) { ++ qWarning("QSocketNotifier: Invalid socket %d with type %s, disabling...", ++ it.key(), socketType(n.type)); ++ notifier->setEnabled(false); ++ } ++ ++ if (pfd.revents & n.flags) ++ setSocketNotifierPending(notifier); ++ } ++ } ++ ++ pollfds.resize(0); ++} ++ ++int QEventDispatcherUNIXPrivate::activateSocketNotifiers() ++{ ++ markPendingSocketNotifiers(); ++ ++ if (pendingNotifiers.isEmpty()) ++ return 0; ++ ++ int n_activated = 0; ++ QEvent event(QEvent::SockAct); ++ ++ while (!pendingNotifiers.isEmpty()) { ++ QSocketNotifier *notifier = pendingNotifiers.takeFirst(); ++ QCoreApplication::sendEvent(notifier, &event); ++ ++n_activated; ++ } ++ ++ return n_activated; ++} ++ + QEventDispatcherUNIX::QEventDispatcherUNIX(QObject *parent) + : QAbstractEventDispatcher(*new QEventDispatcherUNIXPrivate, parent) + { } +@@ -311,14 +292,7 @@ QEventDispatcherUNIX::QEventDispatcherUNIX(QEventDispatcherUNIXPrivate &dd, QObj + { } + + QEventDispatcherUNIX::~QEventDispatcherUNIX() +-{ +-} +- +-int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, +- timespec *timeout) +-{ +- return qt_safe_select(nfds, readfds, writefds, exceptfds, timeout); +-} ++{ } + + /*! + \internal +@@ -390,22 +364,6 @@ QEventDispatcherUNIX::registeredTimers(QObject *object) const + } + + /***************************************************************************** +- Socket notifier type +- *****************************************************************************/ +-QSockNotType::QSockNotType() +-{ +- FD_ZERO(&select_fds); +- FD_ZERO(&enabled_fds); +- FD_ZERO(&pending_fds); +-} +- +-QSockNotType::~QSockNotType() +-{ +- for (int i = 0; i < list.size(); ++i) +- delete list[i]; +-} +- +-/***************************************************************************** + QEventDispatcher implementations for UNIX + *****************************************************************************/ + +@@ -413,160 +371,57 @@ void QEventDispatcherUNIX::registerSocketNotifier(QSocketNotifier *notifier) + { + Q_ASSERT(notifier); + int sockfd = notifier->socket(); +- int type = notifier->type(); ++ QSocketNotifier::Type type = notifier->type(); + #ifndef QT_NO_DEBUG +- if (sockfd < 0 +- || unsigned(sockfd) >= FD_SETSIZE) { +- qWarning("QSocketNotifier: Internal error"); +- return; +- } else if (notifier->thread() != thread() +- || thread() != QThread::currentThread()) { ++ if (notifier->thread() != thread() || thread() != QThread::currentThread()) { + qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread"); + return; + } + #endif + + Q_D(QEventDispatcherUNIX); +- QSockNotType::List &list = d->sn_vec[type].list; +- fd_set *fds = &d->sn_vec[type].enabled_fds; +- QSockNot *sn; +- +- sn = new QSockNot; +- sn->obj = notifier; +- sn->fd = sockfd; +- sn->queue = &d->sn_vec[type].pending_fds; +- +- int i; +- for (i = 0; i < list.size(); ++i) { +- QSockNot *p = list[i]; +- if (p->fd < sockfd) +- break; +- if (p->fd == sockfd) { +- static const char *t[] = { "Read", "Write", "Exception" }; +- qWarning("QSocketNotifier: Multiple socket notifiers for " +- "same socket %d and type %s", sockfd, t[type]); +- } +- } +- list.insert(i, sn); ++ QSocketNotifierSetUNIX &sn_set = d->socketNotifiers[sockfd]; ++ ++ if (sn_set.notifiers[type] && sn_set.notifiers[type] != notifier) ++ qWarning("%s: Multiple socket notifiers for same socket %d and type %s", ++ Q_FUNC_INFO, sockfd, socketType(type)); + +- FD_SET(sockfd, fds); +- d->sn_highest = qMax(d->sn_highest, sockfd); ++ sn_set.notifiers[type] = notifier; + } + + void QEventDispatcherUNIX::unregisterSocketNotifier(QSocketNotifier *notifier) + { + Q_ASSERT(notifier); + int sockfd = notifier->socket(); +- int type = notifier->type(); ++ QSocketNotifier::Type type = notifier->type(); + #ifndef QT_NO_DEBUG +- if (sockfd < 0 +- || unsigned(sockfd) >= FD_SETSIZE) { +- qWarning("QSocketNotifier: Internal error"); +- return; +- } else if (notifier->thread() != thread() +- || thread() != QThread::currentThread()) { ++ if (notifier->thread() != thread() || thread() != QThread::currentThread()) { + qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread"); + return; + } + #endif + + Q_D(QEventDispatcherUNIX); +- QSockNotType::List &list = d->sn_vec[type].list; +- fd_set *fds = &d->sn_vec[type].enabled_fds; +- QSockNot *sn = 0; +- int i; +- for (i = 0; i < list.size(); ++i) { +- sn = list[i]; +- if(sn->obj == notifier && sn->fd == sockfd) +- break; +- } +- if (i == list.size()) // not found +- return; ++ d->pendingNotifiers.removeOne(notifier); + +- FD_CLR(sockfd, fds); // clear fd bit +- FD_CLR(sockfd, sn->queue); +- d->sn_pending_list.removeAll(sn); // remove from activation list +- list.removeAt(i); // remove notifier found above +- delete sn; +- +- if (d->sn_highest == sockfd) { // find highest fd +- d->sn_highest = -1; +- for (int i=0; i<3; i++) { +- if (!d->sn_vec[i].list.isEmpty()) +- d->sn_highest = qMax(d->sn_highest, // list is fd-sorted +- d->sn_vec[i].list[0]->fd); +- } +- } +-} +- +-void QEventDispatcherUNIX::setSocketNotifierPending(QSocketNotifier *notifier) +-{ +- Q_ASSERT(notifier); +- int sockfd = notifier->socket(); +- int type = notifier->type(); +-#ifndef QT_NO_DEBUG +- if (sockfd < 0 +- || unsigned(sockfd) >= FD_SETSIZE) { +- qWarning("QSocketNotifier: Internal error"); ++ auto i = d->socketNotifiers.find(sockfd); ++ if (i == d->socketNotifiers.end()) + return; +- } +- Q_ASSERT(notifier->thread() == thread() && thread() == QThread::currentThread()); +-#endif ++ QSocketNotifierSetUNIX &sn_set = i.value(); + +- Q_D(QEventDispatcherUNIX); +- QSockNotType::List &list = d->sn_vec[type].list; +- QSockNot *sn = 0; +- int i; +- for (i = 0; i < list.size(); ++i) { +- sn = list[i]; +- if(sn->obj == notifier && sn->fd == sockfd) +- break; +- } +- if (i == list.size()) // not found ++ if (sn_set.notifiers[type] == nullptr) + return; + +- // We choose a random activation order to be more fair under high load. +- // If a constant order is used and a peer early in the list can +- // saturate the IO, it might grab our attention completely. +- // Also, if we're using a straight list, the callback routines may +- // delete other entries from the list before those other entries are +- // processed. +- if (! FD_ISSET(sn->fd, sn->queue)) { +- if (d->sn_pending_list.isEmpty()) { +- d->sn_pending_list.append(sn); +- } else { +- d->sn_pending_list.insert((qrand() & 0xff) % +- (d->sn_pending_list.size()+1), sn); +- } +- FD_SET(sn->fd, sn->queue); ++ if (sn_set.notifiers[type] != notifier) { ++ qWarning("%s: Multiple socket notifiers for same socket %d and type %s", ++ Q_FUNC_INFO, sockfd, socketType(type)); ++ return; + } +-} +- +-int QEventDispatcherUNIX::activateTimers() +-{ +- Q_ASSERT(thread() == QThread::currentThread()); +- Q_D(QEventDispatcherUNIX); +- return d->timerList.activateTimers(); +-} + +-int QEventDispatcherUNIX::activateSocketNotifiers() +-{ +- Q_D(QEventDispatcherUNIX); +- if (d->sn_pending_list.isEmpty()) +- return 0; ++ sn_set.notifiers[type] = nullptr; + +- // activate entries +- int n_act = 0; +- QEvent event(QEvent::SockAct); +- while (!d->sn_pending_list.isEmpty()) { +- QSockNot *sn = d->sn_pending_list.takeFirst(); +- if (FD_ISSET(sn->fd, sn->queue)) { +- FD_CLR(sn->fd, sn->queue); +- QCoreApplication::sendEvent(sn->obj, &event); +- ++n_act; +- } +- } +- return n_act; ++ if (sn_set.isEmpty()) ++ d->socketNotifiers.erase(i); + } + + bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags) +@@ -578,39 +433,54 @@ bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags) + emit awake(); + QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData); + +- int nevents = 0; ++ const bool include_timers = (flags & QEventLoop::X11ExcludeTimers) == 0; ++ const bool include_notifiers = (flags & QEventLoop::ExcludeSocketNotifiers) == 0; ++ const bool wait_for_events = flags & QEventLoop::WaitForMoreEvents; ++ + const bool canWait = (d->threadData->canWaitLocked() + && !d->interrupt.load() +- && (flags & QEventLoop::WaitForMoreEvents)); ++ && wait_for_events); + + if (canWait) + emit aboutToBlock(); + +- if (!d->interrupt.load()) { +- // return the maximum time we can wait for an event. +- timespec *tm = 0; +- timespec wait_tm = { 0l, 0l }; +- if (!(flags & QEventLoop::X11ExcludeTimers)) { +- if (d->timerList.timerWait(wait_tm)) +- tm = &wait_tm; +- } ++ if (d->interrupt.load()) ++ return false; + +- if (!canWait) { +- if (!tm) +- tm = &wait_tm; ++ timespec *tm = nullptr; ++ timespec wait_tm = { 0, 0 }; + +- // no time to wait +- tm->tv_sec = 0l; +- tm->tv_nsec = 0l; +- } ++ if (!canWait || (include_timers && d->timerList.timerWait(wait_tm))) ++ tm = &wait_tm; + +- nevents = d->doSelect(flags, tm); ++ d->pollfds.reserve(1 + (include_notifiers ? d->socketNotifiers.size() : 0)); ++ d->pollfds.resize(0); + +- // activate timers +- if (! (flags & QEventLoop::X11ExcludeTimers)) { +- nevents += activateTimers(); +- } ++ if (include_notifiers) ++ for (auto it = d->socketNotifiers.cbegin(); it != d->socketNotifiers.cend(); ++it) ++ d->pollfds.append(qt_make_pollfd(it.key(), it.value().events())); ++ ++ // This must be last, as it's popped off the end below ++ d->pollfds.append(qt_make_pollfd(d->thread_pipe[0], POLLIN)); ++ ++ int nevents = 0; ++ ++ switch (qt_safe_poll(d->pollfds.data(), d->pollfds.size(), tm)) { ++ case -1: ++ perror("qt_safe_poll"); ++ break; ++ case 0: ++ break; ++ default: ++ nevents += d->processThreadWakeUp(d->pollfds.takeLast()); ++ if (include_notifiers) ++ nevents += d->activateSocketNotifiers(); ++ break; + } ++ ++ if (include_timers) ++ nevents += d->activateTimers(); ++ + // return true if we handled events, false otherwise + return (nevents > 0); + } +diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h +index df08080..b76bb8e 100644 +--- a/src/corelib/kernel/qeventdispatcher_unix_p.h ++++ b/src/corelib/kernel/qeventdispatcher_unix_p.h +@@ -53,38 +53,21 @@ + #include "QtCore/qvarlengtharray.h" + #include "private/qtimerinfo_unix_p.h" + +-#if !defined(Q_OS_VXWORKS) +-# include +-# if (!defined(Q_OS_HPUX) || defined(__ia64)) && !defined(Q_OS_NACL) +-# include +-# endif +-#endif +- + QT_BEGIN_NAMESPACE + +-struct QSockNot +-{ +- QSocketNotifier *obj; +- int fd; +- fd_set *queue; +-}; ++class QEventDispatcherUNIXPrivate; + +-class QSockNotType ++struct Q_CORE_EXPORT QSocketNotifierSetUNIX Q_DECL_FINAL + { +-public: +- QSockNotType(); +- ~QSockNotType(); ++ inline QSocketNotifierSetUNIX() Q_DECL_NOTHROW; + +- typedef QPodList List; +- +- List list; +- fd_set select_fds; +- fd_set enabled_fds; +- fd_set pending_fds; ++ inline bool isEmpty() const Q_DECL_NOTHROW; ++ inline short events() const Q_DECL_NOTHROW; + ++ QSocketNotifier *notifiers[3]; + }; + +-class QEventDispatcherUNIXPrivate; ++Q_DECLARE_TYPEINFO(QSocketNotifierSetUNIX, Q_PRIMITIVE_TYPE); + + #ifdef Q_OS_QNX + # define FINAL_EXCEPT_BLACKBERRY +@@ -120,15 +103,6 @@ public: + + protected: + QEventDispatcherUNIX(QEventDispatcherUNIXPrivate &dd, QObject *parent = 0); +- +- void setSocketNotifierPending(QSocketNotifier *notifier); +- +- int activateTimers(); +- int activateSocketNotifiers(); +- +- virtual int select(int nfds, +- fd_set *readfds, fd_set *writefds, fd_set *exceptfds, +- timespec *timeout); + }; + + class Q_CORE_EXPORT QEventDispatcherUNIXPrivate : public QAbstractEventDispatcherPrivate +@@ -139,9 +113,13 @@ public: + QEventDispatcherUNIXPrivate(); + ~QEventDispatcherUNIXPrivate(); + +- int doSelect(QEventLoop::ProcessEventsFlags flags, timespec *timeout); +- virtual int initThreadWakeUp() FINAL_EXCEPT_BLACKBERRY; +- virtual int processThreadWakeUp(int nsel) FINAL_EXCEPT_BLACKBERRY; ++ int processThreadWakeUp(const pollfd &pfd); ++ ++ int activateTimers(); ++ ++ void markPendingSocketNotifiers(); ++ int activateSocketNotifiers(); ++ void setSocketNotifierPending(QSocketNotifier *notifier); + + bool mainThread; + +@@ -149,15 +127,12 @@ public: + // if thread_pipe[1] is -1, then eventfd(7) is in use and is stored in thread_pipe[0] + int thread_pipe[2]; + +- // highest fd for all socket notifiers +- int sn_highest; +- // 3 socket notifier types - read, write and exception +- QSockNotType sn_vec[3]; ++ QVector pollfds; + +- QTimerInfoList timerList; ++ QHash socketNotifiers; ++ QVector pendingNotifiers; + +- // pending socket notifiers list +- QSockNotType::List sn_pending_list; ++ QTimerInfoList timerList; + + QAtomicInt wakeUps; + QAtomicInt interrupt; // bool +@@ -165,6 +140,34 @@ public: + + #undef FINAL_EXCEPT_BLACKBERRY + ++inline QSocketNotifierSetUNIX::QSocketNotifierSetUNIX() Q_DECL_NOTHROW ++{ ++ notifiers[0] = 0; ++ notifiers[1] = 0; ++ notifiers[2] = 0; ++} ++ ++inline bool QSocketNotifierSetUNIX::isEmpty() const Q_DECL_NOTHROW ++{ ++ return !notifiers[0] && !notifiers[1] && !notifiers[2]; ++} ++ ++inline short QSocketNotifierSetUNIX::events() const Q_DECL_NOTHROW ++{ ++ short result = 0; ++ ++ if (notifiers[0]) ++ result |= POLLIN; ++ ++ if (notifiers[1]) ++ result |= POLLOUT; ++ ++ if (notifiers[2]) ++ result |= POLLPRI; ++ ++ return result; ++} ++ + QT_END_NAMESPACE + + #endif // QEVENTDISPATCHER_UNIX_P_H +diff --git a/src/corelib/kernel/qpoll.cpp b/src/corelib/kernel/qpoll.cpp +new file mode 100644 +index 0000000..b152518 +--- /dev/null ++++ b/src/corelib/kernel/qpoll.cpp +@@ -0,0 +1,220 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2015 The Qt Company Ltd. ++** Contact: http://www.qt.io/licensing/ ++** ++** This file is part of the QtCore module of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL21$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see http://www.qt.io/terms-conditions. For further ++** information use the contact form at http://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 2.1 or version 3 as published by the Free ++** Software Foundation and appearing in the file LICENSE.LGPLv21 and ++** LICENSE.LGPLv3 included in the packaging of this file. Please review the ++** following information to ensure the GNU Lesser General Public License ++** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ++** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ++** ++** As a special exception, The Qt Company gives you certain additional ++** rights. These rights are described in The Qt Company LGPL Exception ++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++#include "qcore_unix_p.h" ++ ++QT_BEGIN_NAMESPACE ++ ++#define QT_POLL_READ_MASK (POLLIN | POLLRDNORM) ++#define QT_POLL_WRITE_MASK (POLLOUT | POLLWRNORM | POLLWRBAND) ++#define QT_POLL_EXCEPT_MASK (POLLPRI | POLLRDBAND) ++#define QT_POLL_ERROR_MASK (POLLERR | POLLNVAL) ++#define QT_POLL_EVENTS_MASK (QT_POLL_READ_MASK | QT_POLL_WRITE_MASK | QT_POLL_EXCEPT_MASK) ++ ++static inline int qt_poll_prepare(struct pollfd *fds, nfds_t nfds, ++ fd_set *read_fds, fd_set *write_fds, fd_set *except_fds) ++{ ++ int max_fd = -1; ++ ++ FD_ZERO(read_fds); ++ FD_ZERO(write_fds); ++ FD_ZERO(except_fds); ++ ++ for (nfds_t i = 0; i < nfds; i++) { ++ if (fds[i].fd >= FD_SETSIZE) { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ if ((fds[i].fd < 0) || (fds[i].revents & QT_POLL_ERROR_MASK)) ++ continue; ++ ++ if (fds[i].events & QT_POLL_READ_MASK) ++ FD_SET(fds[i].fd, read_fds); ++ ++ if (fds[i].events & QT_POLL_WRITE_MASK) ++ FD_SET(fds[i].fd, write_fds); ++ ++ if (fds[i].events & QT_POLL_EXCEPT_MASK) ++ FD_SET(fds[i].fd, except_fds); ++ ++ if (fds[i].events & QT_POLL_EVENTS_MASK) ++ max_fd = qMax(max_fd, fds[i].fd); ++ } ++ ++ return max_fd + 1; ++} ++ ++static inline void qt_poll_examine_ready_read(struct pollfd &pfd) ++{ ++ int res; ++ char data; ++ ++ EINTR_LOOP(res, ::recv(pfd.fd, &data, sizeof(data), MSG_PEEK)); ++ const int error = (res < 0) ? errno : 0; ++ ++ if (res == 0) { ++ pfd.revents |= POLLHUP; ++ } else if (res > 0 || error == ENOTSOCK || error == ENOTCONN) { ++ pfd.revents |= QT_POLL_READ_MASK & pfd.events; ++ } else { ++ switch (error) { ++ case ESHUTDOWN: ++ case ECONNRESET: ++ case ECONNABORTED: ++ case ENETRESET: ++ pfd.revents |= POLLHUP; ++ break; ++ default: ++ pfd.revents |= POLLERR; ++ break; ++ } ++ } ++} ++ ++static inline int qt_poll_sweep(struct pollfd *fds, nfds_t nfds, ++ fd_set *read_fds, fd_set *write_fds, fd_set *except_fds) ++{ ++ int result = 0; ++ ++ for (nfds_t i = 0; i < nfds; i++) { ++ if (fds[i].fd < 0) ++ continue; ++ ++ if (FD_ISSET(fds[i].fd, read_fds)) ++ qt_poll_examine_ready_read(fds[i]); ++ ++ if (FD_ISSET(fds[i].fd, write_fds)) ++ fds[i].revents |= QT_POLL_WRITE_MASK & fds[i].events; ++ ++ if (FD_ISSET(fds[i].fd, except_fds)) ++ fds[i].revents |= QT_POLL_EXCEPT_MASK & fds[i].events; ++ ++ if (fds[i].revents != 0) ++ result++; ++ } ++ ++ return result; ++} ++ ++static inline bool qt_poll_is_bad_fd(int fd) ++{ ++ int ret; ++ EINTR_LOOP(ret, fcntl(fd, F_GETFD)); ++ return (ret == -1 && errno == EBADF); ++} ++ ++static inline int qt_poll_mark_bad_fds(struct pollfd *fds, const nfds_t nfds) ++{ ++ int n_marked = 0; ++ ++ for (nfds_t i = 0; i < nfds; i++) { ++ if (fds[i].fd < 0) ++ continue; ++ ++ if (fds[i].revents & QT_POLL_ERROR_MASK) ++ continue; ++ ++ if (qt_poll_is_bad_fd(fds[i].fd)) { ++ fds[i].revents |= POLLNVAL; ++ n_marked++; ++ } ++ } ++ ++ return n_marked; ++} ++ ++int qt_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts) ++{ ++ if (!fds && nfds) { ++ errno = EFAULT; ++ return -1; ++ } ++ ++ fd_set read_fds, write_fds, except_fds; ++ struct timeval tv, *ptv = 0; ++ ++ if (timeout_ts) { ++ tv = timespecToTimeval(*timeout_ts); ++ ptv = &tv; ++ } ++ ++ int n_bad_fds = 0; ++ ++ for (nfds_t i = 0; i < nfds; i++) { ++ fds[i].revents = 0; ++ ++ if (fds[i].fd < 0) ++ continue; ++ ++ if (fds[i].events & QT_POLL_EVENTS_MASK) ++ continue; ++ ++ if (qt_poll_is_bad_fd(fds[i].fd)) { ++ // Mark bad file descriptors that have no event flags set ++ // here, as we won't be passing them to select below and therefore ++ // need to do the check ourselves ++ fds[i].revents = POLLNVAL; ++ n_bad_fds++; ++ } ++ } ++ ++ forever { ++ const int max_fd = qt_poll_prepare(fds, nfds, &read_fds, &write_fds, &except_fds); ++ ++ if (max_fd < 0) ++ return max_fd; ++ ++ if (n_bad_fds > 0) { ++ tv.tv_sec = 0; ++ tv.tv_usec = 0; ++ ptv = &tv; ++ } ++ ++ const int ret = ::select(max_fd, &read_fds, &write_fds, &except_fds, ptv); ++ ++ if (ret == 0) ++ return n_bad_fds; ++ ++ if (ret > 0) ++ return qt_poll_sweep(fds, nfds, &read_fds, &write_fds, &except_fds); ++ ++ if (errno != EBADF) ++ return -1; ++ ++ // We have at least one bad file descriptor that we waited on, find out which and try again ++ n_bad_fds += qt_poll_mark_bad_fds(fds, nfds); ++ } ++} ++ ++QT_END_NAMESPACE +diff --git a/src/corelib/kernel/qpoll_p.h b/src/corelib/kernel/qpoll_p.h +new file mode 100644 +index 0000000..497058a +--- /dev/null ++++ b/src/corelib/kernel/qpoll_p.h +@@ -0,0 +1,79 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2015 The Qt Company Ltd. ++** Contact: http://www.qt.io/licensing/ ++** ++** This file is part of the QtCore module of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL21$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see http://www.qt.io/terms-conditions. For further ++** information use the contact form at http://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 2.1 or version 3 as published by the Free ++** Software Foundation and appearing in the file LICENSE.LGPLv21 and ++** LICENSE.LGPLv3 included in the packaging of this file. Please review the ++** following information to ensure the GNU Lesser General Public License ++** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ++** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ++** ++** As a special exception, The Qt Company gives you certain additional ++** rights. These rights are described in The Qt Company LGPL Exception ++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++#ifndef QPOLL_P_H ++#define QPOLL_P_H ++ ++// ++// W A R N I N G ++// ------------- ++// ++// This file is not part of the Qt API. It exists for the convenience ++// of Qt code on Unix. This header file may change from version to ++// version without notice, or even be removed. ++// ++// We mean it. ++// ++ ++#include ++ ++QT_BEGIN_NAMESPACE ++ ++#ifdef QT_NO_NATIVE_POLL ++ ++#include ++#include ++ ++struct pollfd { ++ int fd; ++ short events, revents; ++}; ++ ++typedef unsigned long int nfds_t; ++ ++#define POLLIN 0x001 ++#define POLLPRI 0x002 ++#define POLLOUT 0x004 ++#define POLLERR 0x008 ++#define POLLHUP 0x010 ++#define POLLNVAL 0x020 ++#define POLLRDNORM 0x040 ++#define POLLRDBAND 0x080 ++#define POLLWRNORM 0x100 ++#define POLLWRBAND 0x200 ++ ++#endif // QT_NO_NATIVE_POLL ++ ++QT_END_NAMESPACE ++ ++#endif // QPOLL_P_H +diff --git a/src/network/socket/qlocalserver_unix.cpp b/src/network/socket/qlocalserver_unix.cpp +index a356e21..79b9b9c 100644 +--- a/src/network/socket/qlocalserver_unix.cpp ++++ b/src/network/socket/qlocalserver_unix.cpp +@@ -277,24 +277,27 @@ void QLocalServerPrivate::_q_onNewConnection() + + void QLocalServerPrivate::waitForNewConnection(int msec, bool *timedOut) + { +- fd_set readfds; +- FD_ZERO(&readfds); +- FD_SET(listenSocket, &readfds); ++ pollfd pfd = qt_make_pollfd(listenSocket, POLLIN); + +- struct timespec timeout; +- timeout.tv_sec = msec / 1000; +- timeout.tv_nsec = (msec % 1000) * 1000 * 1000; ++ switch (qt_poll_msecs(&pfd, 1, msec)) { ++ case 0: ++ if (timedOut) ++ *timedOut = true; ++ return; ++ break; ++ default: ++ if ((pfd.revents & POLLNVAL) == 0) { ++ _q_onNewConnection(); ++ return; ++ } + +- int result = -1; +- result = qt_safe_select(listenSocket + 1, &readfds, 0, 0, (msec == -1) ? 0 : &timeout); +- if (-1 == result) { ++ errno = EBADF; ++ // FALLTHROUGH ++ case -1: + setError(QLatin1String("QLocalServer::waitForNewConnection")); + closeServer(); ++ break; + } +- if (result > 0) +- _q_onNewConnection(); +- if (timedOut) +- *timedOut = (result == 0); + } + + void QLocalServerPrivate::setError(const QString &function) +diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp +index bb0f11f..3e85217 100644 +--- a/src/network/socket/qlocalsocket_unix.cpp ++++ b/src/network/socket/qlocalsocket_unix.cpp +@@ -507,36 +507,25 @@ void QLocalSocket::setReadBufferSize(qint64 size) + bool QLocalSocket::waitForConnected(int msec) + { + Q_D(QLocalSocket); ++ + if (state() != ConnectingState) + return (state() == ConnectedState); + +- fd_set fds; +- FD_ZERO(&fds); +- FD_SET(d->connectingSocket, &fds); ++ QElapsedTimer timer; ++ timer.start(); + +- timeval timeout; +- timeout.tv_sec = msec / 1000; +- timeout.tv_usec = (msec % 1000) * 1000; ++ pollfd pfd = qt_make_pollfd(d->connectingSocket, POLLIN); + +- // timeout can not be 0 or else select will return an error. +- if (0 == msec) +- timeout.tv_usec = 1000; ++ do { ++ const int timeout = (msec > 0) ? qMax(msec - timer.elapsed(), Q_INT64_C(0)) : msec; ++ const int result = qt_poll_msecs(&pfd, 1, timeout); + +- int result = -1; +- // on Linux timeout will be updated by select, but _not_ on other systems. +- QElapsedTimer timer; +- timer.start(); +- while (state() == ConnectingState +- && (-1 == msec || timer.elapsed() < msec)) { +- result = ::select(d->connectingSocket + 1, &fds, 0, 0, &timeout); +- if (-1 == result && errno != EINTR) { +- d->errorOccurred( QLocalSocket::UnknownSocketError, +- QLatin1String("QLocalSocket::waitForConnected")); +- break; +- } +- if (result > 0) ++ if (result == -1) ++ d->errorOccurred(QLocalSocket::UnknownSocketError, ++ QLatin1String("QLocalSocket::waitForConnected")); ++ else if (result > 0) + d->_q_connectToSocket(); +- } ++ } while (state() == ConnectingState && !timer.hasExpired(msec)); + + return (state() == ConnectedState); + } +diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp +index 6a740f4..de86f27 100644 +--- a/src/network/socket/qnativesocketengine_unix.cpp ++++ b/src/network/socket/qnativesocketengine_unix.cpp +@@ -1256,47 +1256,36 @@ int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool c + + int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool selectForRead) const + { +- fd_set fds; +- FD_ZERO(&fds); +- FD_SET(socketDescriptor, &fds); +- +- struct timespec tv; +- tv.tv_sec = timeout / 1000; +- tv.tv_nsec = (timeout % 1000) * 1000 * 1000; +- +- int retval; +- if (selectForRead) +- retval = qt_safe_select(socketDescriptor + 1, &fds, 0, 0, timeout < 0 ? 0 : &tv); +- else +- retval = qt_safe_select(socketDescriptor + 1, 0, &fds, 0, timeout < 0 ? 0 : &tv); +- +- return retval; ++ bool dummy; ++ return nativeSelect(timeout, selectForRead, !selectForRead, &dummy, &dummy); + } + + int QNativeSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool checkWrite, + bool *selectForRead, bool *selectForWrite) const + { +- fd_set fdread; +- FD_ZERO(&fdread); ++ pollfd pfd = qt_make_pollfd(socketDescriptor, 0); ++ + if (checkRead) +- FD_SET(socketDescriptor, &fdread); ++ pfd.events |= POLLIN; + +- fd_set fdwrite; +- FD_ZERO(&fdwrite); + if (checkWrite) +- FD_SET(socketDescriptor, &fdwrite); ++ pfd.events |= POLLOUT; + +- struct timespec tv; +- tv.tv_sec = timeout / 1000; +- tv.tv_nsec = (timeout % 1000) * 1000 * 1000; +- +- int ret; +- ret = qt_safe_select(socketDescriptor + 1, &fdread, &fdwrite, 0, timeout < 0 ? 0 : &tv); ++ const int ret = qt_poll_msecs(&pfd, 1, timeout); + + if (ret <= 0) + return ret; +- *selectForRead = FD_ISSET(socketDescriptor, &fdread); +- *selectForWrite = FD_ISSET(socketDescriptor, &fdwrite); ++ ++ if (pfd.revents & POLLNVAL) { ++ errno = EBADF; ++ return -1; ++ } ++ ++ static const short read_flags = POLLIN | POLLHUP | POLLERR; ++ static const short write_flags = POLLOUT | POLLERR; ++ ++ *selectForRead = ((pfd.revents & read_flags) != 0); ++ *selectForWrite = ((pfd.revents & write_flags) != 0); + + return ret; + } +diff --git a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp +index 8ffe4d8..c528891 100644 +--- a/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp ++++ b/tests/auto/concurrent/qtconcurrentrun/tst_qtconcurrentrun.cpp +@@ -48,6 +48,7 @@ private slots: + void memberFunctions(); + void implicitConvertibleTypes(); + void runWaitLoop(); ++ void pollForIsFinished(); + void recursive(); + #ifndef QT_NO_EXCEPTIONS + void exceptions(); +@@ -353,6 +354,33 @@ void tst_QtConcurrentRun::runWaitLoop() + run(fn).waitForFinished(); + } + ++static bool allFinished(const QList > &futures) ++{ ++ auto hasNotFinished = [](const QFuture &future) { return !future.isFinished(); }; ++ return std::find_if(futures.cbegin(), futures.cend(), hasNotFinished) ++ == futures.constEnd(); ++} ++ ++static void runFunction() ++{ ++ QEventLoop loop; ++ QTimer::singleShot(20, &loop, &QEventLoop::quit); ++ loop.exec(); ++} ++ ++void tst_QtConcurrentRun::pollForIsFinished() ++{ ++ const int numThreads = std::max(4, 2 * QThread::idealThreadCount()); ++ QThreadPool::globalInstance()->setMaxThreadCount(numThreads); ++ ++ QFutureSynchronizer synchronizer; ++ for (int i = 0; i < numThreads; ++i) ++ synchronizer.addFuture(QtConcurrent::run(&runFunction)); ++ ++ // same as synchronizer.waitForFinished() but with a timeout ++ QTRY_VERIFY(allFinished(synchronizer.futures())); ++} ++ + QAtomicInt count; + + void recursiveRun(int level) +diff --git a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp +index c8bb4cd..9b2bada 100644 +--- a/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp ++++ b/tests/auto/corelib/kernel/qeventloop/tst_qeventloop.cpp +@@ -430,11 +430,8 @@ public slots: + dataSent = serverSocket->waitForBytesWritten(-1); + + if (dataSent) { +- fd_set fdread; +- int fd = socket->socketDescriptor(); +- FD_ZERO(&fdread); +- FD_SET(fd, &fdread); +- dataReadable = (1 == qt_safe_select(fd + 1, &fdread, 0, 0, 0)); ++ pollfd pfd = qt_make_pollfd(socket->socketDescriptor(), POLLIN); ++ dataReadable = (1 == qt_safe_poll(&pfd, 1, nullptr)); + } + + if (!dataReadable) { +diff --git a/tests/manual/qt_poll/qt_poll.pro b/tests/manual/qt_poll/qt_poll.pro +new file mode 100644 +index 0000000..beea4d1 +--- /dev/null ++++ b/tests/manual/qt_poll/qt_poll.pro +@@ -0,0 +1,7 @@ ++CONFIG += testcase ++TARGET = tst_qt_poll ++QT = core-private network testlib ++INCLUDEPATH += ../../../src/corelib/kernel ++SOURCES += \ ++ tst_qt_poll.cpp \ ++ ../../../src/corelib/kernel/qpoll.cpp +diff --git a/tests/manual/qt_poll/tst_qt_poll.cpp b/tests/manual/qt_poll/tst_qt_poll.cpp +new file mode 100644 +index 0000000..56e41e4 +--- /dev/null ++++ b/tests/manual/qt_poll/tst_qt_poll.cpp +@@ -0,0 +1,155 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2015 The Qt Company Ltd. ++** Contact: http://www.qt.io/licensing/ ++** ++** This file is part of the test suite of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL21$ ++** Commercial License Usage ++** Licensees holding valid commercial Qt licenses may use this file in ++** accordance with the commercial license agreement provided with the ++** Software or, alternatively, in accordance with the terms contained in ++** a written agreement between you and The Qt Company. For licensing terms ++** and conditions see http://www.qt.io/terms-conditions. For further ++** information use the contact form at http://www.qt.io/contact-us. ++** ++** GNU Lesser General Public License Usage ++** Alternatively, this file may be used under the terms of the GNU Lesser ++** General Public License version 2.1 or version 3 as published by the Free ++** Software Foundation and appearing in the file LICENSE.LGPLv21 and ++** LICENSE.LGPLv3 included in the packaging of this file. Please review the ++** following information to ensure the GNU Lesser General Public License ++** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ++** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ++** ++** As a special exception, The Qt Company gives you certain additional ++** rights. These rights are described in The Qt Company LGPL Exception ++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++#ifndef QT_NO_NATIVE_POLL ++#define QT_NO_NATIVE_POLL ++#endif ++ ++#include ++#include ++ ++#include ++ ++QT_BEGIN_NAMESPACE ++// defined in qpoll.cpp ++int qt_poll(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout_ts); ++QT_END_NAMESPACE ++ ++class tst_qt_poll : public QObject ++{ ++ Q_OBJECT ++ ++private slots: ++ void pollout(); ++ void pollin(); ++ void pollnval(); ++ void pollprihup(); ++}; ++ ++void tst_qt_poll::pollout() ++{ ++ int fds[2]; ++ QCOMPARE(pipe(fds), 0); ++ ++ struct pollfd pfd = { fds[1], POLLOUT, 0 }; ++ const int nready = qt_poll(&pfd, 1, NULL); ++ ++ QCOMPARE(nready, 1); ++ QCOMPARE(pfd.revents, short(POLLOUT)); ++ ++ qt_safe_close(fds[0]); ++ qt_safe_close(fds[1]); ++} ++ ++void tst_qt_poll::pollin() ++{ ++ int fds[2]; ++ QCOMPARE(pipe(fds), 0); ++ ++ const char data = 'Q'; ++ QCOMPARE(qt_safe_write(fds[1], &data, 1), 1); ++ ++ struct pollfd pfd = { fds[0], POLLIN, 0 }; ++ const int nready = qt_poll(&pfd, 1, NULL); ++ ++ QCOMPARE(nready, 1); ++ QCOMPARE(pfd.revents, short(POLLIN)); ++ ++ qt_safe_close(fds[0]); ++ qt_safe_close(fds[1]); ++} ++ ++void tst_qt_poll::pollnval() ++{ ++ struct pollfd pfd = { 42, POLLOUT, 0 }; ++ ++ int nready = qt_poll(&pfd, 1, NULL); ++ QCOMPARE(nready, 1); ++ QCOMPARE(pfd.revents, short(POLLNVAL)); ++ ++ pfd.events = 0; ++ pfd.revents = 0; ++ ++ nready = qt_poll(&pfd, 1, NULL); ++ QCOMPARE(nready, 1); ++ QCOMPARE(pfd.revents, short(POLLNVAL)); ++} ++ ++void tst_qt_poll::pollprihup() ++{ ++ QTcpServer server; ++ QTcpSocket client_socket; ++ ++ QVERIFY(server.listen(QHostAddress::LocalHost)); ++ ++ const quint16 server_port = server.serverPort(); ++ client_socket.connectToHost(server.serverAddress(), server_port); ++ ++ QVERIFY(client_socket.waitForConnected()); ++ QVERIFY(server.waitForNewConnection()); ++ ++ QTcpSocket *server_socket = server.nextPendingConnection(); ++ server.close(); ++ ++ // TCP supports only a single byte of urgent data ++ static const char oob_out = 'Q'; ++ QCOMPARE(::send(server_socket->socketDescriptor(), &oob_out, 1, MSG_OOB), ++ ssize_t(1)); ++ ++ struct pollfd pfd = { ++ int(client_socket.socketDescriptor()), ++ POLLPRI | POLLIN, ++ 0 ++ }; ++ int res = qt_poll(&pfd, 1, NULL); ++ ++ QCOMPARE(res, 1); ++ QCOMPARE(pfd.revents, short(POLLPRI | POLLIN)); ++ ++ char oob_in = 0; ++ // We do not specify MSG_OOB here as SO_OOBINLINE is turned on by default ++ // in the native socket engine ++ QCOMPARE(::recv(client_socket.socketDescriptor(), &oob_in, 1, 0), ++ ssize_t(1)); ++ QCOMPARE(oob_in, oob_out); ++ ++ server_socket->close(); ++ pfd.events = POLLIN; ++ res = qt_poll(&pfd, 1, NULL); ++ ++ QCOMPARE(res, 1); ++ QCOMPARE(pfd.revents, short(POLLHUP)); ++} ++ ++QTEST_APPLESS_MAIN(tst_qt_poll) ++#include "tst_qt_poll.moc" +diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp +index 555ccbf..67a581a 100644 +--- a/tools/configure/configureapp.cpp ++++ b/tools/configure/configureapp.cpp +@@ -1733,6 +1733,7 @@ void Configure::applySpecSpecifics() + dictionary[ "QT_EVDEV" ] = "no"; + dictionary[ "QT_MTDEV" ] = "no"; + dictionary[ "FONT_CONFIG" ] = "auto"; ++ dictionary[ "POLL" ] = "poll"; + dictionary[ "ANGLE" ] = "no"; + + dictionary["DECORATIONS"] = "default windows styled"; +@@ -1758,6 +1759,7 @@ void Configure::applySpecSpecifics() + dictionary[ "QT_XKBCOMMON" ] = "no"; + dictionary["ANDROID_STYLE_ASSETS"] = "yes"; + dictionary[ "STYLE_ANDROID" ] = "yes"; ++ dictionary[ "POLL" ] = "poll"; + } + } + +@@ -3049,6 +3051,9 @@ void Configure::generateOutputVars() + if (dictionary["REDUCE_EXPORTS"] == "yes") + qtConfig += "reduce_exports"; + ++ if (!dictionary["POLL"].isEmpty()) ++ qtConfig += "poll_" + dictionary["POLL"]; ++ + // We currently have no switch for QtConcurrent, so add it unconditionally. + qtConfig += "concurrent"; + diff --git a/SOURCES/qt5-qtbase-cxxflag.patch b/SOURCES/qt5-qtbase-cxxflag.patch new file mode 100644 index 0000000..d428c6f --- /dev/null +++ b/SOURCES/qt5-qtbase-cxxflag.patch @@ -0,0 +1,12 @@ +diff -up qtbase-opensource-src-5.6.0/mkspecs/common/gcc-base.conf.than qtbase-opensource-src-5.6.0/mkspecs/common/gcc-base.conf +--- qtbase-opensource-src-5.6.0/mkspecs/common/gcc-base.conf.than 2016-06-02 17:30:07.249027901 +0200 ++++ qtbase-opensource-src-5.6.0/mkspecs/common/gcc-base.conf 2016-06-02 17:30:14.681748012 +0200 +@@ -32,7 +32,7 @@ + # + + QMAKE_CFLAGS_OPTIMIZE = -O2 +-QMAKE_CFLAGS_OPTIMIZE_FULL = -O3 ++QMAKE_CFLAGS_OPTIMIZE_FULL = -O2 + + QMAKE_CFLAGS += -pipe + QMAKE_CFLAGS_DEPS += -M diff --git a/SOURCES/qtbase-multilib_optflags.patch b/SOURCES/qtbase-multilib_optflags.patch new file mode 100644 index 0000000..5498e79 --- /dev/null +++ b/SOURCES/qtbase-multilib_optflags.patch @@ -0,0 +1,33 @@ +diff -r -u a/mkspecs/linux-g++/qmake.conf b/mkspecs/linux-g++/qmake.conf +--- a/mkspecs/linux-g++/qmake.conf 2015-10-30 06:20:01.000000000 -0200 ++++ b/mkspecs/linux-g++/qmake.conf 2015-11-05 11:23:23.230741601 -0200 +@@ -5,6 +5,7 @@ + MAKEFILE_GENERATOR = UNIX + CONFIG += incremental + QMAKE_INCREMENTAL_STYLE = sublib ++QMAKE_CFLAGS_RELEASE += -O2 + + include(../common/linux.conf) + include(../common/gcc-base-unix.conf) +diff -r -u a/mkspecs/linux-g++-32/qmake.conf b/mkspecs/linux-g++-32/qmake.conf +--- a/mkspecs/linux-g++-32/qmake.conf 2015-10-30 06:20:01.000000000 -0200 ++++ b/mkspecs/linux-g++-32/qmake.conf 2015-11-05 11:22:19.761494470 -0200 +@@ -10,6 +10,7 @@ + + QMAKE_CFLAGS = -m32 + QMAKE_LFLAGS = -m32 ++QMAKE_CFLAGS_RELEASE += -O2 + + include(../common/gcc-base-unix.conf) + include(../common/g++-unix.conf) +diff -r -u a/mkspecs/linux-g++-64/qmake.conf b/mkspecs/linux-g++-64/qmake.conf +--- a/mkspecs/linux-g++-64/qmake.conf 2015-10-30 06:20:01.000000000 -0200 ++++ b/mkspecs/linux-g++-64/qmake.conf 2015-11-05 11:22:49.497610248 -0200 +@@ -13,6 +13,7 @@ + + QMAKE_CFLAGS = -m64 + QMAKE_LFLAGS = -m64 ++QMAKE_CFLAGS_RELEASE += -O2 + + include(../common/gcc-base-unix.conf) + include(../common/g++-unix.conf) diff --git a/SOURCES/qtbase-opensource-src-5.2.0-enable_ft_lcdfilter.patch b/SOURCES/qtbase-opensource-src-5.2.0-enable_ft_lcdfilter.patch new file mode 100644 index 0000000..1c0326e --- /dev/null +++ b/SOURCES/qtbase-opensource-src-5.2.0-enable_ft_lcdfilter.patch @@ -0,0 +1,12 @@ +diff -up qtbase-opensource-src-5.2.0/src/gui/text/qfontengine_ft.cpp.lcdfilter qtbase-opensource-src-5.2.0/src/gui/text/qfontengine_ft.cpp +--- qtbase-opensource-src-5.2.0/src/gui/text/qfontengine_ft.cpp.lcdfilter 2013-12-08 11:09:51.000000000 -0600 ++++ qtbase-opensource-src-5.2.0/src/gui/text/qfontengine_ft.cpp 2014-01-27 13:09:28.426065603 -0600 +@@ -69,7 +69,7 @@ + #include FT_CONFIG_OPTIONS_H + #endif + +-#if defined(FT_LCD_FILTER_H) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING) ++#if defined(FT_LCD_FILTER_H) + #define QT_USE_FREETYPE_LCDFILTER + #endif + diff --git a/SOURCES/qtbase-opensource-src-5.3.2-QTBUG-35459.patch b/SOURCES/qtbase-opensource-src-5.3.2-QTBUG-35459.patch new file mode 100644 index 0000000..1ef698b --- /dev/null +++ b/SOURCES/qtbase-opensource-src-5.3.2-QTBUG-35459.patch @@ -0,0 +1,13 @@ +diff -up qtbase-opensource-src-5.3.2/src/xml/sax/qxml.cpp.QTBUG-35459 qtbase-opensource-src-5.3.2/src/xml/sax/qxml.cpp +diff -up qtbase-opensource-src-5.3.2/src/xml/sax/qxml_p.h.QTBUG-35459 qtbase-opensource-src-5.3.2/src/xml/sax/qxml_p.h +--- qtbase-opensource-src-5.3.2/src/xml/sax/qxml_p.h.QTBUG-35459 2014-09-11 05:48:05.000000000 -0500 ++++ qtbase-opensource-src-5.3.2/src/xml/sax/qxml_p.h 2014-09-16 09:35:01.189255615 -0500 +@@ -223,7 +223,7 @@ private: + // for the DTD currently being parsed. + static const int dtdRecursionLimit = 2; + // The maximum amount of characters an entity value may contain, after expansion. +- static const int entityCharacterLimit = 1024; ++ static const int entityCharacterLimit = 65536; + + const QString &string(); + void stringClear(); diff --git a/SOURCES/qtbase-opensource-src-5.6.0-arm.patch b/SOURCES/qtbase-opensource-src-5.6.0-arm.patch new file mode 100644 index 0000000..63df719 --- /dev/null +++ b/SOURCES/qtbase-opensource-src-5.6.0-arm.patch @@ -0,0 +1,13 @@ +diff -up qtbase-opensource-src-5.6.0-beta/configure.than qtbase-opensource-src-5.6.0-beta/configure +--- qtbase-opensource-src-5.6.0-beta/configure.than 2016-02-12 13:56:20.057741037 +0100 ++++ qtbase-opensource-src-5.6.0-beta/configure 2016-02-12 14:10:10.267768256 +0100 +@@ -4346,6 +4346,9 @@ if [ "$QMAKESPEC" != "$XQMAKESPEC" ]; th + else + # not cross compiling, host == target + CFG_HOST_ARCH="$CFG_ARCH" ++ if [ "$CFG_ARCH" = "arm" ] ; then ++ CFG_CPUFEATURES="neon" ++ fi + CFG_HOST_CPUFEATURES="$CFG_CPUFEATURES" + fi + unset OUTFILE diff --git a/SOURCES/qtbase-opensource-src-5.6.0-moc_WORDSIZE.patch b/SOURCES/qtbase-opensource-src-5.6.0-moc_WORDSIZE.patch new file mode 100644 index 0000000..62d1e9c --- /dev/null +++ b/SOURCES/qtbase-opensource-src-5.6.0-moc_WORDSIZE.patch @@ -0,0 +1,14 @@ +diff -up qtbase-opensource-src-5.6.0-beta/src/tools/moc/main.cpp.moc_WORDSIZE qtbase-opensource-src-5.6.0-beta/src/tools/moc/main.cpp +--- qtbase-opensource-src-5.6.0-beta/src/tools/moc/main.cpp.moc_WORDSIZE 2015-12-04 18:05:24.000000000 -0600 ++++ qtbase-opensource-src-5.6.0-beta/src/tools/moc/main.cpp 2015-12-15 20:57:55.554485416 -0600 +@@ -184,6 +184,10 @@ int runMoc(int argc, char **argv) + Moc moc; + pp.macros["Q_MOC_RUN"]; + pp.macros["__cplusplus"]; ++ Macro macro; ++ macro.symbols = Preprocessor::tokenize(QByteArray::number(Q_PROCESSOR_WORDSIZE*8), 1, Preprocessor::TokenizeDefine); ++ macro.symbols.removeLast(); // remove the EOF symbol ++ pp.macros.insert("__WORDSIZE", macro); + + // Don't stumble over GCC extensions + Macro dummyVariadicFunctionMacro; diff --git a/SOURCES/qtlogging.ini b/SOURCES/qtlogging.ini new file mode 100644 index 0000000..be2bf22 --- /dev/null +++ b/SOURCES/qtlogging.ini @@ -0,0 +1,2 @@ +[Rules] +*.debug=false diff --git a/SPECS/qt5-qtbase.spec b/SPECS/qt5-qtbase.spec new file mode 100644 index 0000000..728c42f --- /dev/null +++ b/SPECS/qt5-qtbase.spec @@ -0,0 +1,1632 @@ +# See http://bugzilla.redhat.com/223663 +%define multilib_archs x86_64 %{ix86} %{?mips} ppc64 ppc s390x s390 sparc64 sparcv9 +%define multilib_basearchs x86_64 %{?mips64} ppc64 s390x sparc64 + +# support qtchooser (adds qtchooser .conf file) +%define qtchooser 0 +%if 0%{?qtchooser} +%define priority 10 +%ifarch %{multilib_basearchs} +%define priority 15 +%endif +%endif + +%global qt_module qtbase + +%global rpm_macros_dir %(d=%{_rpmconfigdir}/macros.d; [ -d $d ] || d=%{_sysconfdir}/rpm; echo $d) + +## set to 1 to enable bootstrap +%global bootstrap 0 + +%if 0%{?fedora} > 21 +# use external qt_settings pkg +%global qt_settings 1 +%endif + +# See http://bugzilla.redhat.com/1279265 +%if 0%{?fedora} < 24 +%global inject_optflags 1 +%endif + +%if 0%{?fedora} > 23 || 0%{?rhel} > 6 +%global journald -journald +BuildRequires: pkgconfig(libsystemd) +%endif + +%if 0%{?fedora} > 23 +# gcc6: FTBFS +%global qt5_deprecated_flag -Wno-deprecated-declarations +# gcc6: Qt assumes this in places +%global qt5_null_flag -fno-delete-null-pointer-checks +%endif + +# define to build docs, need to undef this for bootstrapping +# where qt5-qttools builds are not yet available +# only primary archs (for now), allow secondary to bootstrap +%if ! 0%{?bootstrap} +%ifarch %{arm} %{ix86} x86_64 %{power64} s390 s390x aarch64 +%global docs 1 +%endif + +%global examples 1 +%global tests 1 +%endif + +#define prerelease rc + +Summary: Qt5 - QtBase components +Name: qt5-qtbase +Version: 5.6.1 +Release: 10%{?prerelease:.%{prerelease}}%{?dist} + +# See LGPL_EXCEPTIONS.txt, for exception details +License: LGPLv2 with exceptions or GPLv3 with exceptions +Url: http://qt-project.org/ +Source0: http://download.qt.io/official_releases/qt/5.6/%{version}%{?prerelease:-%{prerelease}}/submodules/%{qt_module}-opensource-src-%{version}%{?prerelease:-%{prerelease}}.tar.xz + +# https://bugzilla.redhat.com/show_bug.cgi?id=1227295 +Source1: qtlogging.ini + +# header file to workaround multilib issue +# https://bugzilla.redhat.com/show_bug.cgi?id=1036956 +Source5: qconfig-multilib.h + +# xinitrc script to check for OpenGL 1 only drivers and automatically set +# QT_XCB_FORCE_SOFTWARE_OPENGL for them +Source6: 10-qt5-check-opengl2.sh + +# support multilib optflags +Patch2: qtbase-multilib_optflags.patch + +# fix QTBUG-35459 (too low entityCharacterLimit=1024 for CVE-2013-4549) +Patch4: qtbase-opensource-src-5.3.2-QTBUG-35459.patch + +# unconditionally enable freetype lcdfilter support +Patch12: qtbase-opensource-src-5.2.0-enable_ft_lcdfilter.patch + +# upstreamable patches +# support poll +# https://bugreports.qt-project.org/browse/QTBUG-27195 +Patch50: qt5-poll.patch + +# Workaround moc/multilib issues +# https://bugzilla.redhat.com/show_bug.cgi?id=1290020 +# https://bugreports.qt.io/browse/QTBUG-49972 +Patch52: qtbase-opensource-src-5.6.0-moc_WORDSIZE.patch + +# arm patch +Patch54: qtbase-opensource-src-5.6.0-arm.patch + +# recently passed code review, not integrated yet +# https://codereview.qt-project.org/126102/ +Patch60: moc-get-the-system-defines-from-the-compiler-itself.patch + +# drop -O3 and make -O2 by default +Patch61: qt5-qtbase-cxxflag.patch + +## upstream patches + +# macros, be mindful to keep sync'd with macros.qt5 +Source10: macros.qt5 +%define _qt5 %{name} +%define _qt5_prefix %{_libdir}/qt5 +%define _qt5_archdatadir %{_libdir}/qt5 +# -devel bindir items (still) conflict with qt4 +# at least until this is all implemented, +# http://lists.qt-project.org/pipermail/development/2012-November/007990.html +%define _qt5_bindir %{_qt5_prefix}/bin +%define _qt5_datadir %{_datadir}/qt5 +%define _qt5_docdir %{_docdir}/qt5 +%define _qt5_examplesdir %{_qt5_prefix}/examples +%define _qt5_headerdir %{_includedir}/qt5 +%define _qt5_importdir %{_qt5_archdatadir}/imports +%define _qt5_libdir %{_libdir} +%define _qt5_libexecdir %{_qt5_archdatadir}/libexec +%define _qt5_plugindir %{_qt5_archdatadir}/plugins +%define _qt5_settingsdir %{_sysconfdir}/xdg +%define _qt5_sysconfdir %{_qt5_settingsdir} +%define _qt5_translationdir %{_datadir}/qt5/translations + +# Do not check any files in %%{_qt5_plugindir}/platformthemes/ for requires. +# Those themes are there for platform integration. If the required libraries are +# not there, the platform to integrate with isn't either. Then Qt will just +# silently ignore the plugin that fails to load. Thus, there is no need to let +# RPM drag in gtk2 as a dependency for the GTK+ 2 dialog support. +%global __requires_exclude_from ^%{_qt5_plugindir}/platformthemes/.*$ + +# for %%check +BuildRequires: cmake +BuildRequires: cups-devel +BuildRequires: desktop-file-utils +BuildRequires: findutils +BuildRequires: libjpeg-devel +BuildRequires: libmng-devel +BuildRequires: libtiff-devel +BuildRequires: pkgconfig(alsa) +# http://bugzilla.redhat.com/1196359 +%if 0%{?fedora} || 0%{?rhel} > 6 +%global dbus -dbus-linked +BuildRequires: pkgconfig(dbus-1) +%endif +BuildRequires: pkgconfig(libdrm) +BuildRequires: pkgconfig(fontconfig) +BuildRequires: pkgconfig(gl) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gtk+-2.0) +BuildRequires: pkgconfig(libproxy-1.0) +# xcb-sm +BuildRequires: pkgconfig(ice) pkgconfig(sm) +BuildRequires: pkgconfig(libpng) +BuildRequires: pkgconfig(libudev) +%global openssl -openssl-linked +BuildRequires: pkgconfig(openssl) +BuildRequires: pkgconfig(libpulse) pkgconfig(libpulse-mainloop-glib) +%if 0%{?fedora} +%global xkbcommon -system-xkbcommon +BuildRequires: pkgconfig(libinput) +BuildRequires: pkgconfig(xcb-xkb) >= 1.10 +BuildRequires: pkgconfig(xkbcommon) >= 0.4.1 +BuildRequires: pkgconfig(xkbcommon-x11) >= 0.4.1 +%else +# not Fedora +%if 0%{?rhel} == 6 +%global xcb -qt-xcb +%endif +%global xkbcommon -qt-xkbcommon +Provides: bundled(libxkbcommon) = 0.4.1 +%endif +BuildRequires: pkgconfig(xkeyboard-config) +%if 0%{?fedora} || 0%{?rhel} > 6 +%define egl 1 +BuildRequires: pkgconfig(egl) +BuildRequires: pkgconfig(gbm) +BuildRequires: pkgconfig(glesv2) +%global sqlite -system-sqlite +BuildRequires: pkgconfig(sqlite3) >= 3.7 +%if 0%{?fedora} > 22 +%global harfbuzz -system-harfbuzz +BuildRequires: pkgconfig(harfbuzz) >= 0.9.42 +%endif +BuildRequires: pkgconfig(icu-i18n) +BuildRequires: pkgconfig(libpcre) >= 8.30 +%define pcre -system-pcre +BuildRequires: pkgconfig(xcb-xkb) +%else +BuildRequires: libicu-devel +%define pcre -qt-pcre +%endif +BuildRequires: pkgconfig(xcb) pkgconfig(xcb-glx) pkgconfig(xcb-icccm) pkgconfig(xcb-image) pkgconfig(xcb-keysyms) pkgconfig(xcb-renderutil) +BuildRequires: pkgconfig(zlib) + +%if 0%{?tests} +BuildRequires: dbus-x11 +BuildRequires: mesa-dri-drivers +BuildRequires: time +BuildRequires: xorg-x11-server-Xvfb +%endif + +# For the very first bootstrap of 5.6 we need valgring for now, as qt5-qdoc brand new +# splitted package script still using it +%ifnarch s390 +BuildRequires: valgrind +%endif + +%if 0%{?qtchooser} +%if 0%{?fedora} +Conflicts: qt < 1:4.8.6-10 +%endif +Requires(post): %{_sbindir}/update-alternatives +Requires(postun): %{_sbindir}/update-alternatives +%endif +%if 0%{?qt_settings} +Requires: qt-settings +%endif +Requires: %{name}-common = %{version}-%{release} + +## Sql drivers +%if 0%{?rhel} +%define ibase -no-sql-ibase +%define tds -no-sql-tds +%endif + +%description +Qt is a software toolkit for developing applications. + +This package contains base tools, like string, xml, and network +handling. + +%package common +Summary: Common files for Qt5 +Requires: %{name} = %{version}-%{release} +BuildArch: noarch +%description common +%{summary}. + +%package devel +Summary: Development files for %{name} +Provides: %{name}-private-devel = %{version}-%{release} +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-gui%{?_isa} +%if 0%{?egl} +Requires: pkgconfig(egl) +%endif +Requires: pkgconfig(gl) +Requires: qt5-rpm-macros +%description devel +%{summary}. + +%if 0%{?docs} +%package doc +Summary: API documentation for %{name} +License: GFDL +Requires: %{name} = %{version}-%{release} +BuildRequires: qt5-qhelpgenerator +BuildRequires: qt5-qdoc +BuildArch: noarch +%description doc +%{summary}. +%endif + +%package examples +Summary: Programming examples for %{name} +Requires: %{name}%{?_isa} = %{version}-%{release} +%description examples +%{summary}. + +%package static +Summary: Static library files for %{name} +Requires: %{name}-devel%{?_isa} = %{version}-%{release} +Requires: pkgconfig(fontconfig) +Requires: pkgconfig(glib-2.0) +%if 0%{?fedora} +Requires: pkgconfig(libinput) +Requires: pkgconfig(xkbcommon) +%endif +Requires: pkgconfig(zlib) +%description static +%{summary}. + +%if "%{?ibase}" != "-no-sql-ibase" +%package ibase +Summary: IBase driver for Qt5's SQL classes +BuildRequires: firebird-devel +Requires: %{name}%{?_isa} = %{version}-%{release} +%description ibase +%{summary}. +%endif + +%package mysql +Summary: MySQL driver for Qt5's SQL classes +BuildRequires: mysql-devel +Requires: %{name}%{?_isa} = %{version}-%{release} +%description mysql +%{summary}. + +%package odbc +Summary: ODBC driver for Qt5's SQL classes +BuildRequires: unixODBC-devel +Requires: %{name}%{?_isa} = %{version}-%{release} +%description odbc +%{summary}. + +%package postgresql +Summary: PostgreSQL driver for Qt5's SQL classes +BuildRequires: postgresql-devel +Requires: %{name}%{?_isa} = %{version}-%{release} +%description postgresql +%{summary}. + +%if "%{?tds}" != "-no-sql-tds" +%package tds +Summary: TDS driver for Qt5's SQL classes +BuildRequires: freetds-devel +Requires: %{name}%{?_isa} = %{version}-%{release} +%description tds +%{summary}. +%endif + +# debating whether to do 1 subpkg per library or not -- rex +%package gui +Summary: Qt5 GUI-related libraries +Requires: %{name}%{?_isa} = %{version}-%{release} +%if 0%{?fedora} > 20 +Recommends: mesa-dri-drivers +%endif +Obsoletes: qt5-qtbase-x11 < 5.2.0 +Provides: qt5-qtbase-x11 = %{version}-%{release} +# for Source6: 10-qt5-check-opengl2.sh: +# glxinfo +Requires: glx-utils +%description gui +Qt5 libraries used for drawing widgets and OpenGL items. + +%package -n qt5-rpm-macros +Summary: RPM macros for Qt5 +%if 0%{?fedora} > 22 && 0%{?inject_optflags} +# https://bugzilla.redhat.com/show_bug.cgi?id=1248174 +Requires: redhat-rpm-config +%endif +# when qt5-rpm-macros was split out +Conflicts: qt5-qtbase-devel < 5.6.0-0.23 +BuildArch: noarch +%description -n qt5-rpm-macros +RPM macros for building Qt5 packages. + + +%prep +%setup -q -n %{qt_module}-opensource-src-%{version}%{?prerelease:-%{prerelease}} + +%patch4 -p1 -b .QTBUG-35459 +%patch12 -p1 -b .enable_ft_lcdfilter + +%patch50 -p1 -b .qt5-poll.patch +%patch52 -p1 -b .moc_WORDSIZE +%patch54 -p1 -b .arm +## FTBFS, omit for now +%patch60 -p1 -b .moc_system_defines +%patch61 -p1 -b .qt5-qtbase-cxxflag + +%define platform linux-g++ + +%if 0%{?inject_optflags} +## adjust $RPM_OPT_FLAGS +# remove -fexceptions +RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS | sed 's|-fexceptions||g'` +# these flags are for qtbase build only, no need to propogate elsewhere +#RPM_OPT_FLAGS="$RPM_OPT_FLAGS %{?qt5_deprecated_flag} %{?qt5_arm_flag}" + +%patch2 -p1 -b .multilib_optflags +# drop backup file(s), else they get installed too, http://bugzilla.redhat.com/639463 +rm -fv mkspecs/linux-g++*/qmake.conf.multilib-optflags + +sed -i -e "s|-O2|$RPM_OPT_FLAGS|g" \ + mkspecs/%{platform}/qmake.conf + +sed -i -e "s|^\(QMAKE_LFLAGS_RELEASE.*\)|\1 $RPM_LD_FLAGS|" \ + mkspecs/common/g++-unix.conf + +# undefine QMAKE_STRIP (and friends), so we get useful -debuginfo pkgs (#1065636) +sed -i -e 's|^\(QMAKE_STRIP.*=\).*$|\1|g' mkspecs/common/linux.conf +%endif + +%if 0%{?prerelease} +bin/syncqt.pl -version %{version} +%endif + +# move some bundled libs to ensure they're not accidentally used +pushd src/3rdparty +mkdir UNUSED +mv freetype libjpeg libpng zlib UNUSED/ +%if "%{?sqlite}" == "-system-sqlite" +mv sqlite UNUSED/ +%endif +%if "%{?xcb}" != "-qt-xcb" +mv xcb UNUSED/ +%endif +popd + +# builds failing mysteriously on f20 +# ./configure: Permission denied +# check to ensure that can't happen -- rex +test -x configure || chmod +x configure + + +%build +## adjust $RPM_OPT_FLAGS +# remove -fexceptions +RPM_OPT_FLAGS=`echo $RPM_OPT_FLAGS | sed 's|-fexceptions||g'` +RPM_OPT_FLAGS="$RPM_OPT_FLAGS %{?qt5_arm_flag} %{?qt5_deprecated_flag} %{?qt5_null_flag}" + +export CFLAGS="$CFLAGS $RPM_OPT_FLAGS" +export CXXFLAGS="$CXXFLAGS $RPM_OPT_FLAGS" +export LDFLAGS="$LDFLAGS $RPM_LD_FLAGS" +export MAKEFLAGS="%{?_smp_mflags}" + +./configure -v \ + -confirm-license \ + -opensource \ + -prefix %{_qt5_prefix} \ + -archdatadir %{_qt5_archdatadir} \ + -bindir %{_qt5_bindir} \ + -datadir %{_qt5_datadir} \ + -docdir %{_qt5_docdir} \ + -examplesdir %{_qt5_examplesdir} \ + -headerdir %{_qt5_headerdir} \ + -importdir %{_qt5_importdir} \ + -libdir %{_qt5_libdir} \ + -libexecdir %{_qt5_libexecdir} \ + -plugindir %{_qt5_plugindir} \ + -sysconfdir %{_qt5_sysconfdir} \ + -translationdir %{_qt5_translationdir} \ + -platform %{platform} \ + -release \ + -shared \ + -accessibility \ + %{?dbus}%{!?dbus:-dbus-runtime} \ + -fontconfig \ + -glib \ + -gtkstyle \ + %{?ibase} \ + -iconv \ + -icu \ + %{?journald} \ + %{?openssl} \ + -optimized-qmake \ + %{!?examples:-nomake examples} \ + %{!?tests:-nomake tests} \ + -no-pch \ + -no-rpath \ + -no-separate-debug-info \ + -no-strip \ + -system-libjpeg \ + -system-libpng \ + %{?harfbuzz} \ + %{?pcre} \ + %{?sqlite} \ + %{?tds} \ + %{?xcb} \ + %{?xkbcommon} \ + -system-zlib \ + -no-directfb + +%if ! 0%{?inject_optflags} +# ensure qmake build using optflags (which can happen if not munging qmake.conf defaults) +make clean -C qmake +make %{?_smp_mflags} -C qmake \ + QMAKE_CFLAGS_RELEASE="${CFLAGS:-$RPM_OPT_FLAGS}" \ + QMAKE_CXXFLAGS_RELEASE="${CXXFLAGS:-$RPM_OPT_FLAGS}" \ + QMAKE_LFLAGS_RELEASE="${LDFLAGS:-$RPM_LD_FLAGS}" \ + QMAKE_STRIP= +%endif + +make %{?_smp_mflags} + +%if 0%{?docs} +# HACK to avoid multilib conflicts in noarch content +# see also https://bugreports.qt-project.org/browse/QTBUG-42071 +QT_HASH_SEED=0; export QT_HASH_SEED + +make html_docs +make qch_docs +%endif + + +%install +make install INSTALL_ROOT=%{buildroot} + +%if 0%{?docs} +make install_docs INSTALL_ROOT=%{buildroot} +%endif + +install -m644 -p -D %{SOURCE1} %{buildroot}%{_qt5_datadir}/qtlogging.ini + +# Qt5.pc +cat >%{buildroot}%{_libdir}/pkgconfig/Qt5.pc< 5-%{__isa_bits}.conf + echo "%{_qt5_prefix}" >> 5-%{__isa_bits}.conf + # alternatives targets + touch default.conf 5.conf + popd +%endif + +## .prl/.la file love +# nuke .prl reference(s) to %%buildroot, excessive (.la-like) libs +pushd %{buildroot}%{_qt5_libdir} +for prl_file in libQt5*.prl ; do + sed -i -e "/^QMAKE_PRL_BUILD_DIR/d" ${prl_file} + if [ -f "$(basename ${prl_file} .prl).so" ]; then + rm -fv "$(basename ${prl_file} .prl).la" + sed -i -e "/^QMAKE_PRL_LIBS/d" ${prl_file} + fi +done +popd + +install -p -m755 -D %{SOURCE6} %{buildroot}%{_sysconfdir}/X11/xinit/xinitrc.d/10-qt5-check-opengl2.sh + +%check +%if 0%{?tests} +## see tests/README for expected environment (running a plasma session essentially) +## we are not quite there yet +export CTEST_OUTPUT_ON_FAILURE=1 +export PATH=%{buildroot}%{_qt5_bindir}:$PATH +export LD_LIBRARY_PATH=%{buildroot}%{_qt5_libdir} +# dbus tests error out when building if session bus is not available +dbus-launch --exit-with-session \ +make sub-tests %{?_smp_mflags} -k ||: +xvfb-run -a --server-args="-screen 0 1280x1024x32" \ +dbus-launch --exit-with-session \ +time \ +make check -k ||: +%endif + +%if 0%{?qtchooser} +%pre +if [ $1 -gt 1 ] ; then +# remove short-lived qt5.conf alternatives +%{_sbindir}/update-alternatives \ + --remove qtchooser-qt5 \ + %{_sysconfdir}/xdg/qtchooser/qt5-%{__isa_bits}.conf >& /dev/null ||: + +%{_sbindir}/update-alternatives \ + --remove qtchooser-default \ + %{_sysconfdir}/xdg/qtchooser/qt5.conf >& /dev/null ||: +fi +%endif + +%post +/sbin/ldconfig +%if 0%{?qtchooser} +%{_sbindir}/update-alternatives \ + --install %{_sysconfdir}/xdg/qtchooser/5.conf \ + qtchooser-5 \ + %{_sysconfdir}/xdg/qtchooser/5-%{__isa_bits}.conf \ + %{priority} + +%{_sbindir}/update-alternatives \ + --install %{_sysconfdir}/xdg/qtchooser/default.conf \ + qtchooser-default \ + %{_sysconfdir}/xdg/qtchooser/5.conf \ + %{priority} +%endif + +%postun +/sbin/ldconfig +%if 0%{?qtchooser} +if [ $1 -eq 0 ]; then +%{_sbindir}/update-alternatives \ + --remove qtchooser-5 \ + %{_sysconfdir}/xdg/qtchooser/5-%{__isa_bits}.conf + +%{_sbindir}/update-alternatives \ + --remove qtchooser-default \ + %{_sysconfdir}/xdg/qtchooser/5.conf +fi +%endif + +%files +%{!?_licensedir:%global license %%doc} +%license LICENSE.LGPL* LGPL_EXCEPTION.txt LICENSE.FDL +%if 0%{?qtchooser} +%dir %{_sysconfdir}/xdg/qtchooser +# not editable config files, so not using %%config here +%ghost %{_sysconfdir}/xdg/qtchooser/default.conf +%ghost %{_sysconfdir}/xdg/qtchooser/5.conf +%{_sysconfdir}/xdg/qtchooser/5-%{__isa_bits}.conf +%endif +%dir %{_sysconfdir}/xdg/QtProject/ +%{_qt5_libdir}/libQt5Concurrent.so.5* +%{_qt5_libdir}/libQt5Core.so.5* +%{_qt5_libdir}/libQt5DBus.so.5* +%{_qt5_libdir}/libQt5Network.so.5* +%{_qt5_libdir}/libQt5Sql.so.5* +%{_qt5_libdir}/libQt5Test.so.5* +%{_qt5_libdir}/libQt5Xml.so.5* +%dir %{_qt5_libdir}/cmake/ +%dir %{_qt5_libdir}/cmake/Qt5/ +%dir %{_qt5_libdir}/cmake/Qt5Concurrent/ +%dir %{_qt5_libdir}/cmake/Qt5Core/ +%dir %{_qt5_libdir}/cmake/Qt5DBus/ +%dir %{_qt5_libdir}/cmake/Qt5Gui/ +%dir %{_qt5_libdir}/cmake/Qt5Network/ +%dir %{_qt5_libdir}/cmake/Qt5OpenGL/ +%dir %{_qt5_libdir}/cmake/Qt5PrintSupport/ +%dir %{_qt5_libdir}/cmake/Qt5Sql/ +%dir %{_qt5_libdir}/cmake/Qt5Test/ +%dir %{_qt5_libdir}/cmake/Qt5Widgets/ +%dir %{_qt5_libdir}/cmake/Qt5Xml/ +%dir %{_qt5_docdir}/ +%{_qt5_docdir}/global/ +%{_qt5_importdir}/ +%{_qt5_translationdir}/ +%dir %{_qt5_prefix}/ +%dir %{_qt5_datadir}/ +%{_qt5_datadir}/qtlogging.ini +%dir %{_qt5_libexecdir}/ +%dir %{_qt5_plugindir}/ +%dir %{_qt5_plugindir}/bearer/ +%{_qt5_plugindir}/bearer/libqconnmanbearer.so +%{_qt5_plugindir}/bearer/libqgenericbearer.so +%{_qt5_plugindir}/bearer/libqnmbearer.so +%{_qt5_libdir}/cmake/Qt5Network/Qt5Network_QConnmanEnginePlugin.cmake +%{_qt5_libdir}/cmake/Qt5Network/Qt5Network_QGenericEnginePlugin.cmake +%{_qt5_libdir}/cmake/Qt5Network/Qt5Network_QNetworkManagerEnginePlugin.cmake +%dir %{_qt5_plugindir}/designer/ +%dir %{_qt5_plugindir}/generic/ +%dir %{_qt5_plugindir}/iconengines/ +%dir %{_qt5_plugindir}/imageformats/ +%dir %{_qt5_plugindir}/platforminputcontexts/ +%dir %{_qt5_plugindir}/platforms/ +%dir %{_qt5_plugindir}/platformthemes/ +%dir %{_qt5_plugindir}/printsupport/ +%dir %{_qt5_plugindir}/script/ +%dir %{_qt5_plugindir}/sqldrivers/ +%dir %{_qt5_plugindir}/styles/ +%{_qt5_plugindir}/sqldrivers/libqsqlite.so +%{_qt5_libdir}/cmake/Qt5Sql/Qt5Sql_QSQLiteDriverPlugin.cmake + +%files common +# empty for now, consider: filesystem/dir ownership, licenses + +%if 0%{?docs} +%files doc +%license LICENSE.FDL +%doc dist/README dist/changes-5.* +%{_qt5_docdir}/*.qch +%if 0%{?examples} +%if 0%{!?bootstrap} +# included in -examples instead, see bug #1212750 +%exclude %{_qt5_docdir}/*/examples-manifest.xml +%endif +%endif +%{_qt5_docdir}/qmake/ +%{_qt5_docdir}/qtconcurrent/ +%{_qt5_docdir}/qtcore/ +%{_qt5_docdir}/qtdbus/ +%{_qt5_docdir}/qtgui/ +%{_qt5_docdir}/qtnetwork/ +%{_qt5_docdir}/qtopengl/ +%{_qt5_docdir}/qtplatformheaders/ +%{_qt5_docdir}/qtprintsupport/ +%{_qt5_docdir}/qtsql/ +%{_qt5_docdir}/qttestlib/ +%{_qt5_docdir}/qtwidgets/ +%{_qt5_docdir}/qtxml/ +%endif + +%files devel +%if "%{_qt5_bindir}" != "%{_bindir}" +%dir %{_qt5_bindir} +%endif +%{_bindir}/moc* +%{_bindir}/qdbuscpp2xml* +%{_bindir}/qdbusxml2cpp* +%{_bindir}/qmake* +%{_bindir}/rcc* +%{_bindir}/syncqt* +%{_bindir}/uic* +%{_bindir}/qlalr +%{_bindir}/fixqt4headers.pl +%{_qt5_bindir}/moc* +%{_qt5_bindir}/qdbuscpp2xml* +%{_qt5_bindir}/qdbusxml2cpp* +%{_qt5_bindir}/qmake* +%{_qt5_bindir}/rcc* +%{_qt5_bindir}/syncqt* +%{_qt5_bindir}/uic* +%{_qt5_bindir}/qlalr +%{_qt5_bindir}/fixqt4headers.pl +%if "%{_qt5_headerdir}" != "%{_includedir}" +%dir %{_qt5_headerdir} +%endif +%{_qt5_headerdir}/QtConcurrent/ +%{_qt5_headerdir}/QtCore/ +%{_qt5_headerdir}/QtDBus/ +%{_qt5_headerdir}/QtGui/ +%{_qt5_headerdir}/QtNetwork/ +%{_qt5_headerdir}/QtOpenGL/ +%{_qt5_headerdir}/QtPlatformHeaders/ +%{_qt5_headerdir}/QtPrintSupport/ +%{_qt5_headerdir}/QtSql/ +%{_qt5_headerdir}/QtTest/ +%{_qt5_headerdir}/QtWidgets/ +%{_qt5_headerdir}/QtXml/ +%{_qt5_archdatadir}/mkspecs/ +%{_qt5_libdir}/libQt5Concurrent.prl +%{_qt5_libdir}/libQt5Concurrent.so +%{_qt5_libdir}/libQt5Core.prl +%{_qt5_libdir}/libQt5Core.so +%{_qt5_libdir}/libQt5DBus.prl +%{_qt5_libdir}/libQt5DBus.so +%{_qt5_libdir}/libQt5Gui.prl +%{_qt5_libdir}/libQt5Gui.so +%{_qt5_libdir}/libQt5Network.prl +%{_qt5_libdir}/libQt5Network.so +%{_qt5_libdir}/libQt5OpenGL.prl +%{_qt5_libdir}/libQt5OpenGL.so +%{_qt5_libdir}/libQt5PrintSupport.prl +%{_qt5_libdir}/libQt5PrintSupport.so +%{_qt5_libdir}/libQt5Sql.prl +%{_qt5_libdir}/libQt5Sql.so +%{_qt5_libdir}/libQt5Test.prl +%{_qt5_libdir}/libQt5Test.so +%{_qt5_libdir}/libQt5Widgets.prl +%{_qt5_libdir}/libQt5Widgets.so +%{_qt5_libdir}/libQt5XcbQpa.prl +%{_qt5_libdir}/libQt5XcbQpa.so +%{_qt5_libdir}/libQt5Xml.prl +%{_qt5_libdir}/libQt5Xml.so +%{_qt5_libdir}/cmake/Qt5/Qt5Config*.cmake +%{_qt5_libdir}/cmake/Qt5Concurrent/Qt5ConcurrentConfig*.cmake +%{_qt5_libdir}/cmake/Qt5Core/Qt5CoreConfig*.cmake +%{_qt5_libdir}/cmake/Qt5Core/Qt5CoreMacros.cmake +%{_qt5_libdir}/cmake/Qt5Core/Qt5CTestMacros.cmake +%{_qt5_libdir}/cmake/Qt5DBus/Qt5DBusConfig*.cmake +%{_qt5_libdir}/cmake/Qt5DBus/Qt5DBusMacros.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5GuiConfig*.cmake +%{_qt5_libdir}/cmake/Qt5Network/Qt5NetworkConfig*.cmake +%{_qt5_libdir}/cmake/Qt5OpenGL/Qt5OpenGLConfig*.cmake +%{_qt5_libdir}/cmake/Qt5PrintSupport/Qt5PrintSupportConfig*.cmake +%{_qt5_libdir}/cmake/Qt5Sql/Qt5SqlConfig*.cmake +%{_qt5_libdir}/cmake/Qt5Test/Qt5TestConfig*.cmake +%{_qt5_libdir}/cmake/Qt5Widgets/Qt5WidgetsConfig*.cmake +%{_qt5_libdir}/cmake/Qt5Widgets/Qt5WidgetsMacros.cmake +%{_qt5_libdir}/cmake/Qt5Xml/Qt5XmlConfig*.cmake +%{_qt5_libdir}/pkgconfig/Qt5.pc +%{_qt5_libdir}/pkgconfig/Qt5Concurrent.pc +%{_qt5_libdir}/pkgconfig/Qt5Core.pc +%{_qt5_libdir}/pkgconfig/Qt5DBus.pc +%{_qt5_libdir}/pkgconfig/Qt5Gui.pc +%{_qt5_libdir}/pkgconfig/Qt5Network.pc +%{_qt5_libdir}/pkgconfig/Qt5OpenGL.pc +%{_qt5_libdir}/pkgconfig/Qt5PrintSupport.pc +%{_qt5_libdir}/pkgconfig/Qt5Sql.pc +%{_qt5_libdir}/pkgconfig/Qt5Test.pc +%{_qt5_libdir}/pkgconfig/Qt5Widgets.pc +%{_qt5_libdir}/pkgconfig/Qt5Xml.pc +%if 0%{?egl} +%{_qt5_libdir}/libQt5EglDeviceIntegration.prl +%{_qt5_libdir}/libQt5EglDeviceIntegration.so +%endif + + +%files static +%{_qt5_libdir}/libQt5Bootstrap.*a +%{_qt5_libdir}/libQt5Bootstrap.prl +%{_qt5_headerdir}/QtOpenGLExtensions/ +%{_qt5_libdir}/libQt5OpenGLExtensions.*a +%{_qt5_libdir}/libQt5OpenGLExtensions.prl +%{_qt5_libdir}/cmake/Qt5OpenGLExtensions/ +%{_qt5_libdir}/pkgconfig/Qt5OpenGLExtensions.pc +%{_qt5_headerdir}/QtPlatformSupport/ +%{_qt5_libdir}/libQt5PlatformSupport.*a +%{_qt5_libdir}/libQt5PlatformSupport.prl + +%if 0%{?examples} +%files examples +%if 0%{!?bootstrap} +%{_qt5_docdir}/*/examples-manifest.xml +%endif +%{_qt5_examplesdir}/ +%endif + +%if "%{?ibase}" != "-no-sql-ibase" +%files ibase +%{_qt5_plugindir}/sqldrivers/libqsqlibase.so +%{_qt5_libdir}/cmake/Qt5Sql/Qt5Sql_QIBaseDriverPlugin.cmake +%endif + +%files mysql +%{_qt5_plugindir}/sqldrivers/libqsqlmysql.so +%{_qt5_libdir}/cmake/Qt5Sql/Qt5Sql_QMYSQLDriverPlugin.cmake + +%files odbc +%{_qt5_plugindir}/sqldrivers/libqsqlodbc.so +%{_qt5_libdir}/cmake/Qt5Sql/Qt5Sql_QODBCDriverPlugin.cmake + +%files postgresql +%{_qt5_plugindir}/sqldrivers/libqsqlpsql.so +%{_qt5_libdir}/cmake/Qt5Sql/Qt5Sql_QPSQLDriverPlugin.cmake + +%if "%{?tds}" != "-no-sql-tds" +%files tds +%{_qt5_plugindir}/sqldrivers/libqsqltds.so +%{_qt5_libdir}/cmake/Qt5Sql/Qt5Sql_QTDSDriverPlugin.cmake +%endif + +%post gui -p /sbin/ldconfig +%postun gui -p /sbin/ldconfig + +%files gui +%dir %{_sysconfdir}/X11/xinit +%dir %{_sysconfdir}/X11/xinit/xinitrc.d/ +%{_sysconfdir}/X11/xinit/xinitrc.d/10-qt5-check-opengl2.sh +%{_qt5_libdir}/libQt5Gui.so.5* +%{_qt5_libdir}/libQt5OpenGL.so.5* +%{_qt5_libdir}/libQt5PrintSupport.so.5* +%{_qt5_libdir}/libQt5Widgets.so.5* +%{_qt5_libdir}/libQt5XcbQpa.so.5* +%{_qt5_plugindir}/generic/libqevdevkeyboardplugin.so +%{_qt5_plugindir}/generic/libqevdevmouseplugin.so +%{_qt5_plugindir}/generic/libqevdevtabletplugin.so +%{_qt5_plugindir}/generic/libqevdevtouchplugin.so +%if 0%{?fedora} +%{_qt5_plugindir}/generic/libqlibinputplugin.so +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QLibInputPlugin.cmake +%endif +%{_qt5_plugindir}/generic/libqtuiotouchplugin.so +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QEvdevKeyboardPlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QEvdevMousePlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QEvdevTabletPlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QEvdevTouchScreenPlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QTuioTouchPlugin.cmake +%{_qt5_plugindir}/imageformats/libqgif.so +%{_qt5_plugindir}/imageformats/libqico.so +%{_qt5_plugindir}/imageformats/libqjpeg.so +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QGifPlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QICOPlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QJpegPlugin.cmake +%{_qt5_plugindir}/platforminputcontexts/libcomposeplatforminputcontextplugin.so +%{_qt5_plugindir}/platforminputcontexts/libibusplatforminputcontextplugin.so +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QComposePlatformInputContextPlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QIbusPlatformInputContextPlugin.cmake +%if 0%{?egl} +%{_qt5_libdir}/libQt5EglDeviceIntegration.so.5* +%{_qt5_plugindir}/platforms/libqeglfs.so +%{_qt5_plugindir}/platforms/libqminimalegl.so +%dir %{_qt5_plugindir}/egldeviceintegrations/ +%{_qt5_plugindir}/egldeviceintegrations/libqeglfs-kms-integration.so +%{_qt5_plugindir}/egldeviceintegrations/libqeglfs-x11-integration.so +%{_qt5_plugindir}/xcbglintegrations/libqxcb-egl-integration.so +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QMinimalEglIntegrationPlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QEglFSIntegrationPlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QEglFSKmsIntegrationPlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QEglFSX11IntegrationPlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QXcbEglIntegrationPlugin.cmake +%endif +%{_qt5_plugindir}/platforms/libqlinuxfb.so +%{_qt5_plugindir}/platforms/libqminimal.so +%{_qt5_plugindir}/platforms/libqoffscreen.so +%{_qt5_plugindir}/platforms/libqxcb.so +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QLinuxFbIntegrationPlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QMinimalIntegrationPlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QOffscreenIntegrationPlugin.cmake +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QXcbIntegrationPlugin.cmake +%{_qt5_plugindir}/xcbglintegrations/libqxcb-glx-integration.so +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QXcbGlxIntegrationPlugin.cmake +%{_qt5_plugindir}/platformthemes/libqgtk2.so +%{_qt5_libdir}/cmake/Qt5Gui/Qt5Gui_QGtk2ThemePlugin.cmake +%{_qt5_plugindir}/printsupport/libcupsprintersupport.so +%{_qt5_libdir}/cmake/Qt5PrintSupport/Qt5PrintSupport_QCupsPrinterSupportPlugin.cmake + +%files -n qt5-rpm-macros +%{rpm_macros_dir}/macros.qt5 + + +%changelog +* Tue Aug 30 2016 Jan Grulich - 5.6.1-10 +- Increase build version to have newer version than in EPEL + Resolves: bz#1317396 + +* Wed Jun 15 2016 Jan Grulich - 5.6.1-2 +- fix Qt5.pc version + +* Wed Jun 08 2016 Jan Grulich - 5.6.1-1 +- Update to 5.6.1 + sync with Fedora + Resolves: bz#1317396 + +* Thu May 26 2016 Jan Grulich - 5.6.0-13 +- Drop qtchooser support as qtchooser is not available in RHEL + Resolves: bz#1339918 + +* Wed Apr 27 2016 Jan Grulich - 5.6.0-12 +- Restore rebased poll patch + Resolves: bz#1317396 + CCBUG: bz#847857 + +* Wed Apr 13 2016 Jan Grulich - 5.6.0-11 +- Enable documentation + Resolves: bz#1317396 + +* Thu Apr 07 2016 Jan Grulich - 5.6.0-10 +- Initial version for RHEL + Resolves: bz#1317396 + +* Fri Mar 25 2016 Rex Dieter 5.6.0-9 +- pull upstream patches (upstreamed versions, gcc6-related bits mostly) + +* Thu Mar 24 2016 Rex Dieter - 5.6.0-8 +- make 10-qt5-check-opengl2.sh xinit script more robust +- enable journald support for el7+ (#1315239) + +* Sat Mar 19 2016 Rex Dieter - 5.6.0-7 +- macros.qt5: null-pointer-checks flag isn't c++-specific + +* Sat Mar 19 2016 Rex Dieter - 5.6.0-6 +- macros.qt5: we really only want the null-pointer-checks flag here + and definitely no arch-specific ones + +* Fri Mar 18 2016 Rex Dieter - 5.6.0-5 +- macros.qt5: cleanup, %%_qt5_cflags, %%_qt5_cxxflags (for f24+) + +* Fri Mar 18 2016 Rex Dieter - 5.6.0-3 +- rebuild + +* Tue Mar 15 2016 Rex Dieter 5.6.0-2 +- respin QTBUG-51767 patch + +* Mon Mar 14 2016 Helio Chissini de Castro - 5.6.0-1 +- 5.6.0 release + +* Sat Mar 12 2016 Rex Dieter 5.6.0-0.41.rc +- %%build: restore -dbus-linked + +* Fri Mar 11 2016 Rex Dieter 5.6.0-0.40.rc +- respin QTBUG-51649 patch +- %%build: use -dbus-runtime unconditionally +- drop (unused) build deps: atspi, dbus, networkmanager + +* Thu Mar 10 2016 Rex Dieter 5.6.0-0.39.rc +- candidate fixes for various QtDBus deadlocks (QTBUG-51648,QTBUG-51676) + +* Mon Mar 07 2016 Rex Dieter 5.6.0-0.38.rc +- backport "crash on start if system bus is not available" (QTBUG-51299) + +* Sat Mar 05 2016 Rex Dieter 5.6.0-0.37.rc +- %build: ./configure -journal (f24+) + +* Wed Mar 02 2016 Daniel Vrátil 5.6.0-0.36.rc +- Non-bootstrapped build + +* Tue Mar 01 2016 Daniel Vrátil 5.6.0-0.35.rc +- Rebuild against new openssl + +* Fri Feb 26 2016 Rex Dieter 5.6.0-0.34.rc +- qtlogging.ini: remove comments + +* Thu Feb 25 2016 Rex Dieter 5.6.0-0.33.rc +- ship $$[QT_INSTALL_DATA]/qtlogging.ini for packaged logging defaults (#1227295) + +* Thu Feb 25 2016 Rex Dieter 5.6.0-0.32.rc +- qt5-qtbase-static missing dependencies (#1311311) + +* Wed Feb 24 2016 Rex Dieter 5.6.0-0.31.rc +- Item views don't handle insert/remove of rows robustly (QTBUG-48870) + +* Tue Feb 23 2016 Helio Chissini de Castro - 5.6.0-0.30.rc +- Update to final RC + +* Mon Feb 22 2016 Helio Chissini de Castro - 5.6.0-0.29.rc +- Update tarball with https://bugreports.qt.io/browse/QTBUG-50703 fix + +* Wed Feb 17 2016 Than Ngo - 5.6.0-0.28.rc +- fix build issue with gcc6 + +* Mon Feb 15 2016 Helio Chissini de Castro - 5.6.0-0.27.rc +- Update proper tarball. Need avoid the fix branch + +* Mon Feb 15 2016 Helio Chissini de Castro - 5.6.0-0.26.rc +- Integrate rc releases now. + +* Sat Feb 13 2016 Rex Dieter 5.6.0-0.25.beta +- macros.qt5: fix %%qt5_ldflags macro + +* Thu Feb 11 2016 Than Ngo - 5.6.0-0.24.beta +- fix build issue with gcc6 +- fix check for alsa 1.1.x + +* Wed Feb 03 2016 Rex Dieter 5.6.0-0.23.beta +- qt5-rpm-macros pkg + +* Tue Feb 02 2016 Rex Dieter 5.6.0-0.22.beta +- don't inject $RPM_OPT_FLAGS/$RPM_LD_FLAGS into qmake defaults f24+ (#1279265) + +* Tue Feb 02 2016 Rex Dieter 5.6.0-0.21.beta +- build with and add to macros.qt5 flags: -fno-delete-null-pointer-checks + +* Fri Jan 15 2016 Than Ngo - 5.6.0-0.20.beta +- enable -qt-xcb to fix non-US keys under VNC (#1295713) + +* Mon Jan 04 2016 Rex Dieter 5.6.0-0.19.beta +- Crash in QXcbWindow::setParent() due to NULL xcbScreen (QTBUG-50081, #1291003) + +* Mon Dec 21 2015 Rex Dieter 5.6.0-0.17.beta +- fix/update Release: tag + +* Fri Dec 18 2015 Rex Dieter 5.6.0-0.16 +- 5.6.0-beta (final) + +* Wed Dec 16 2015 Rex Dieter - 5.6.0-0.15 +- pull in another upstream moc fix/improvement (#1290020,QTBUG-49972) +- fix bootstrap/docs + +* Wed Dec 16 2015 Rex Dieter 5.6.0-0.13 +- workaround moc/qconfig-multilib issues (#1290020,QTBUG-49972) + +* Wed Dec 16 2015 Peter Robinson 5.6.0-0.12 +- aarch64 is secondary arch too +- ppc64le is NOT multilib +- Fix Power 64 macro use + +* Mon Dec 14 2015 Than Ngo - 5.6.0-0.11 +- fix build failure on secondary arch + +* Sun Dec 13 2015 Helio Chissini de Castro - 5.6.0-0.10 +- We're back to gold linker +- Remove reduce relocations + +* Sat Dec 12 2015 Rex Dieter 5.6.0-0.9 +- drop disconnect_displays.patch so we can better test latest xcb/display work + +* Fri Dec 11 2015 Rex Dieter 5.6.0-0.8 +- sync latest xcb/screen/display related upstream commits + +* Thu Dec 10 2015 Helio Chissini de Castro - 5.6.0-0.7 +- Official beta release + +* Thu Dec 10 2015 Helio Chissini de Castro - 5.6.0-0.6 +- Official beta release + +* Wed Dec 09 2015 Daniel Vratil - 5.6.0-0.5 +- try reverting from -optimized-tools to -optimized-qmake + +* Sun Dec 06 2015 Rex Dieter - 5.6.0-0.4 +- re-introduce bootstrap/examples macros +- put examples-manifest.xml in -examples +- restore -doc multilib hack (to be on the safe side, can't hurt) +- %%build: s/-optimized-qmake/-optimized-tools/ + +* Sat Dec 05 2015 Helio Chissini de Castro - 5.6.0-0.3 +- Beta 3 +- Reintroduce xcb patch from https://codereview.qt-project.org/#/c/138201/ + +* Fri Nov 27 2015 Helio Chissini de Castro - 5.6.0-0.2 +- Valgrind still needed as buildreq due recent split qdoc package, but we can get rid of + specific arch set. +- Added missing libproxy buildreq +- Epel and RHEL doesn't have libinput, so a plugin need to be excluded for this distros + +* Wed Nov 25 2015 Rex Dieter 5.5.1-10 +- -devel: Requires: redhat-rpm-config (#1248174) + +* Wed Nov 18 2015 Helio Chissini de Castro - 5.5.1-9 +- Get rid of valgrind hack. It sort out that we don't need it anymore (#1211203) + +* Mon Nov 09 2015 Helio Chissini de Castro - 5.5.1-8 +- qt5-qdoc need requires >= current version, otherwise will prevent the usage further when moved to qttools + +* Mon Nov 09 2015 Rex Dieter 5.5.1-7 +- qt5-qdoc subpkg + +* Tue Nov 03 2015 Helio Chissini de Castro - 5.6.0-0.1 +- Start to implement 5.6.0 beta + +* Tue Nov 03 2015 Helio Chissini de Castro - 5.6.0-0.1 +- Start to implement 5.6.0 beta + +* Wed Oct 28 2015 David Tardon - 5.5.1-6 +- full build + +* Wed Oct 28 2015 David Tardon - 5.5.1-5 +- rebuild for ICU 56.1 + +* Thu Oct 15 2015 Helio Chissini de Castro - 5.5.1-2 +- Update to final release 5.5.1 + +* Mon Oct 05 2015 Helio Chissini de Castro - 5.5.1-1 +- Update to Qt 5.5.1 RC1 +- Patchs 13, 52, 53, 101, 155, 223, 297 removed due to inclusion upstream + +* Mon Oct 05 2015 Rex Dieter 5.5.0-18 +- When a screen comes back online, the windows need to be told about it (QTBUG-47041) +- xcb: Ignore disabling of outputs in the middle of the mode switch + +* Wed Aug 19 2015 Rex Dieter 5.5.0-17 +- unconditionally undo valgrind hack when done (#1255054) + +* Sat Aug 15 2015 Rex Dieter 5.5.0-16 +- backport 0055-Respect-manual-set-icon-themes.patch (kde#344469) +- conditionally use valgrind only if needed + +* Fri Aug 07 2015 Kevin Kofler - 5.5.0-15 +- use valgrind to debug qdoc HTML generation + +* Fri Aug 07 2015 Kevin Kofler - 5.5.0-14 +- remove GDB hackery again, -12 built fine on i686, hack breaks ARM build +- fix 10-qt5-check-opengl2.sh for multiple screens (#1245755) + +* Thu Aug 06 2015 Rex Dieter 5.5.0-13 +- use upstream commit/fix for QTBUG-46310 +- restore qdoc/gdb hackery, i686 still needs it :( + +* Wed Aug 05 2015 Kevin Kofler - 5.5.0-12 +- remove GDB hackery, it is not producing useful backtraces for the ARM crash + +* Mon Aug 03 2015 Helio Chissini de Castro - 5.5.0-11 +- Add mesa-dri-drivers as recommends on gui package as reported by Kevin Kofler +- Reference https://bugzilla.redhat.com/1249280 + +* Wed Jul 29 2015 Rex Dieter 5.5.0-10 +- -docs: BuildRequires: qt5-qhelpgenerator + +* Fri Jul 17 2015 Rex Dieter 5.5.0-9 +- use qdoc.gdb wrapper + +* Wed Jul 15 2015 Rex Dieter 5.5.0-8 +- %%build: hack around 'make docs' failures (on f22+) + +* Wed Jul 15 2015 Jan Grulich 5.5.0-7 +- restore previously dropped patches + +* Tue Jul 14 2015 Rex Dieter 5.5.0-6 +- disable bootstrap again + +* Tue Jul 14 2015 Rex Dieter 5.5.0-5 +- enable bootstrap (and disable failing docs) + +* Mon Jul 13 2015 Rex Dieter 5.5.0-4 +- Qt5 application crashes when connecting/disconnecting displays (#1083664) + +* Fri Jul 10 2015 Than Ngo - 5.5.0-3 +- add better fix for compile error on big endian + +* Thu Jul 09 2015 Than Ngo - 5.5.0-2 +- fix build failure on big endian platform (ppc64,s390x) + +* Mon Jun 29 2015 Helio Chissini de Castro - 5.5.0-0.5.rc +- Second round of builds now with bootstrap enabled due new qttools + +* Mon Jun 29 2015 Helio Chissini de Castro - 5.5.0-0.4.rc +- Enable bootstrap to first import on rawhide + +* Thu Jun 25 2015 Helio Chissini de Castro - 5.5.0-0.3.rc +- Disable bootstrap + +* Wed Jun 24 2015 Helio Chissini de Castro - 5.5.0-0.2.rc +- Update for official RC1 released packages + +* Mon Jun 15 2015 Daniel Vratil 5.5.0-0.1.rc +- Qt 5.5 RC 1 + +* Mon Jun 08 2015 Rex Dieter 5.4.2-2 +- rebase to latest SM patches (QTBUG-45484, QTBUG-46310) + +* Tue Jun 02 2015 Jan Grulich 5.4.2-1 +- Update to 5.4.2 + +* Tue May 26 2015 Rex Dieter 5.4.1-20 +- SM_CLIENT_ID property is not set (QTBUG-46310) + +* Mon May 25 2015 Rex Dieter 5.4.1-19 +- QWidget::setWindowRole does nothing (QTBUG-45484) + +* Wed May 20 2015 Rex Dieter 5.4.1-18 +- own /etc/xdg/QtProject +- Requires: qt-settings (f22+) + +* Sat May 16 2015 Rex Dieter 5.4.1-17 +- Try to ensure that -fPIC is used in CMake builds (QTBUG-45755) + +* Thu May 14 2015 Rex Dieter 5.4.1-16 +- Some Qt apps crash if they are compiled with gcc5 (QTBUG-45755) + +* Thu May 07 2015 Rex Dieter 5.4.1-15 +- try harder to avoid doc/multilib conflicts (#1212750) + +* Wed May 06 2015 Rex Dieter 5.4.1-14 +- Shortcuts with KeypadModifier not working (QTBUG-33093,#1219173) + +* Tue May 05 2015 Rex Dieter 5.4.1-13 +- backport: data corruption in QNetworkAccessManager + +* Fri May 01 2015 Rex Dieter - 5.4.1-12 +- backport a couple more upstream fixes +- introduce -common noarch subpkg, should help multilib issues + +* Sat Apr 25 2015 Rex Dieter 5.4.1-11 +- port qtdbusconnection_no_debug.patch from qt(4) + +* Fri Apr 17 2015 Rex Dieter 5.4.1-10 +- -examples: include %%{_qt5_docdir}/qdoc/examples-manifest.xml (#1212750) + +* Mon Apr 13 2015 Rex Dieter 5.4.1-9 +- Multiple Vulnerabilities in Qt Image Format Handling (CVE-2015-1860 CVE-2015-1859 CVE-2015-1858) + +* Fri Apr 10 2015 Rex Dieter - 5.4.1-8 +- -dbus=runtime on el6 (#1196359) +- %%build: -no-directfb + +* Wed Apr 01 2015 Daniel Vrátil - 5.4.1-7 +- drop 5.5 XCB patches, the rebase is incomplete and does not work properly with Qt 5.4 + +* Mon Mar 30 2015 Rex Dieter 5.4.1-6 +- Crash due to unsafe access to QTextLayout::lineCount (#1207279,QTBUG-43562) + +* Mon Mar 30 2015 Rex Dieter 5.4.1-5 +- unable to use input methods in ibus-1.5.10 (#1203575) + +* Wed Mar 25 2015 Daniel Vrátil - 5.4.1-4 +- pull in set of upstream Qt 5.5 fixes and improvements for XCB screen handling rebased to 5.4 + +* Fri Feb 27 2015 Rex Dieter - 5.4.1-3 +- pull in handful of upstream fixes, particularly... +- Fix a division by zero when processing malformed BMP files (QTBUG-44547, CVE-2015-0295) + +* Wed Feb 25 2015 Rex Dieter 5.4.1-2 +- try bootstrap=1 (f23) + +* Tue Feb 24 2015 Jan Grulich 5.4.1-1 +- update to 5.4.1 + +* Mon Feb 16 2015 Rex Dieter 5.4.0-13 +- -no-use-gold-linker (f22+, #1193044) + +* Thu Feb 12 2015 Rex Dieter 5.4.0-12 +- own %%{_qt5_plugindir}/{designer,iconengines,script,styles} + +* Thu Feb 05 2015 David Tardon - 5.4.0-11 +- full build after ICU soname bump + +* Wed Feb 04 2015 Petr Machata - 5.4.0-10 +- Bump for rebuild. + +* Sat Jan 31 2015 Rex Dieter 5.4.0-9 +- crashes when connecting/disconnecting displays (#1083664,QTBUG-42985) + +* Tue Jan 27 2015 David Tardon - 5.4.0-8 +- full build + +* Mon Jan 26 2015 David Tardon - 5.4.0-7 +- rebuild for ICU 54.1 + +* Sun Jan 18 2015 Rex Dieter 5.4.0-6 +- fix %%pre scriptlet + +* Sat Jan 17 2015 Rex Dieter 5.4.0-5 +- ship /etc/xdg/qtchooser/5.conf alternative instead (of qt5.conf) + +* Wed Dec 17 2014 Rex Dieter 5.4.0-4 +- workaround 'make docs' crasher on el6 (QTBUG-43057) + +* Thu Dec 11 2014 Rex Dieter 5.4.0-3 +- don't omit examples for bootstrap (needs work) + +* Wed Dec 10 2014 Rex Dieter 5.4.0-2 +- fix bootstrapping logic + +* Wed Dec 10 2014 Rex Dieter 5.4.0-1 +- 5.4.0 (final) + +* Fri Nov 28 2014 Rex Dieter 5.4.0-0.8.rc +- restore font rendering patch (#1052389,QTBUG-41590) + +* Thu Nov 27 2014 Rex Dieter 5.4.0-0.7.rc +- 5.4.0-rc + +* Wed Nov 12 2014 Rex Dieter 5.4.0-0.6.beta +- add versioned Requires: libxkbcommon dep + +* Tue Nov 11 2014 Rex Dieter 5.4.0-0.5.beta +- pull in slightly different upstreamed font rendering fix (#1052389,QTBUG-41590) + +* Mon Nov 10 2014 Rex Dieter 5.4.0-0.4.beta +- Bad font rendering (#1052389,QTBUG-41590) + +* Mon Nov 03 2014 Rex Dieter 5.4.0-0.3.beta +- macros.qt5: +%%qmake_qt5 , to help set standard build flags (CFLAGS, etc...) + +* Wed Oct 22 2014 Kevin Kofler - 5.4.0-0.2.beta +- -gui: don't require gtk2 (__requires_exclude_from platformthemes) (#1154884) + +* Sat Oct 18 2014 Rex Dieter - 5.4.0-0.1.beta +- 5.4.0-beta +- avoid extra -devel deps by moving *Plugin.cmake files to base pkgs +- support bootstrap macro, to disable -doc,-examples + +* Mon Oct 13 2014 Jan Grulich 5.3.2-3 +- QFileDialog: implement getOpenFileUrl and friends for real + +* Thu Oct 09 2014 Rex Dieter 5.3.2-2 +- use linux-g++ platform unconditionally + +* Thu Oct 09 2014 Kevin Kofler 5.3.2-1.1 +- F20: require libxkbcommon >= 0.4.1, only patch for the old libxcb + +* Tue Sep 16 2014 Rex Dieter 5.3.2-1 +- 5.3.2 + +* Wed Aug 27 2014 David Tardon - 5.3.1-8 +- do a normal build with docs + +* Tue Aug 26 2014 David Tardon - 5.3.1-7 +- rebuild for ICU 53.1 + +* Sun Aug 17 2014 Fedora Release Engineering - 5.3.1-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Thu Jul 24 2014 Rex Dieter - 5.3.1-5 +- drop dep on xorg-x11-xinit (own shared dirs instead) +- fix/improve qtchooser support using alternatives (#1122316) + +* Mon Jun 30 2014 Kevin Kofler 5.3.1-4 +- support the old versions of libxcb and libxkbcommon in F19 and F20 +- don't use the bundled libxkbcommon + +* Mon Jun 30 2014 Rex Dieter 5.3.1-3 +- -devel: Requires: pkgconfig(egl) + +* Fri Jun 27 2014 Jan Grulich - 5.3.1-2 +- Prefer QPA implementation in qsystemtrayicon_x11 if available + +* Tue Jun 17 2014 Jan Grulich - 5.3.1-1 +- 5.3.1 + +* Sun Jun 08 2014 Fedora Release Engineering - 5.3.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Fri May 30 2014 Rex Dieter 5.3.0-6 +- %%ix86: build -no-sse2 (#1103185) + +* Tue May 27 2014 Rex Dieter 5.3.0-5 +- BR: pkgconfig(xcb-xkb) > 1.10 (f21+) +- allow possibility for libxkbcommon-0.4.x only + +* Fri May 23 2014 Rex Dieter 5.3.0-4 +- -system-libxkbcommon (f21+) + +* Thu May 22 2014 Rex Dieter 5.3.0-3 +- qt5-qtbase-5.3.0-2.fc21 breaks keyboard input (#1100213) + +* Wed May 21 2014 Rex Dieter 5.3.0-2 +- limit -reduce-relocations to %%ix86 x86_64 archs (QTBUG-36129) + +* Wed May 21 2014 Jan Grulich 5.3.0-1 +- 5.3.0 + +* Thu Apr 24 2014 Rex Dieter 5.2.1-8 +- DoS vulnerability in the GIF image handler (QTBUG-38367) + +* Wed Mar 26 2014 Rex Dieter 5.2.1-7 +- support ppc64le multilib (#1080629) + +* Wed Mar 12 2014 Kevin Kofler 5.2.1-6 +- reenable documentation + +* Sat Mar 08 2014 Kevin Kofler 5.2.1-5 +- make the QMAKE_STRIP sed not sensitive to whitespace (see #1074041 in Qt 4) + +* Tue Feb 18 2014 Rex Dieter 5.2.1-4 +- undefine QMAKE_STRIP (and friends), so we get useful -debuginfo pkgs (#1065636) + +* Wed Feb 12 2014 Rex Dieter 5.2.1-3 +- bootstrap for libicu bump + +* Wed Feb 05 2014 Rex Dieter 5.2.1-2 +- qconfig.pri: +alsa +kms +pulseaudio +xcb-sm + +* Wed Feb 05 2014 Rex Dieter 5.2.1-1 +- 5.2.1 + +* Sat Feb 01 2014 Rex Dieter 5.2.0-11 +- better %%rpm_macros_dir handling + +* Wed Jan 29 2014 Kevin Kofler - 5.2.0-10 +- fix the allow-forcing-llvmpipe patch to patch actual caller of __glXInitialize + +* Wed Jan 29 2014 Kevin Kofler - 5.2.0-9 +- use software OpenGL (llvmpipe) if the hardware driver doesn't support OpenGL 2 + +* Tue Jan 28 2014 Rex Dieter 5.2.0-8 +- (re)enable -docs + +* Mon Jan 27 2014 Rex Dieter - 5.2.0-7 +- unconditionally enable freetype lcd_filter +- (temp) disable docs (libxcb bootstrap) + +* Sun Jan 26 2014 Rex Dieter 5.2.0-6 +- fix %%_qt5_examplesdir macro + +* Sat Jan 25 2014 Rex Dieter 5.2.0-5 +- -examples subpkg + +* Mon Jan 13 2014 Kevin Kofler - 5.2.0-4 +- fix QTBUG-35459 (too low entityCharacterLimit=1024 for CVE-2013-4549) +- fix QTBUG-35460 (error message for CVE-2013-4549 is misspelled) +- reenable docs on Fedora (accidentally disabled) + +* Mon Jan 13 2014 Rex Dieter - 5.2.0-3 +- move sql build deps into subpkg sections +- macro'ize ibase,tds support (disabled on rhel) + +* Thu Jan 02 2014 Rex Dieter 5.2.0-2 +- -devel: qtsql apparently wants all drivers available at buildtime + +* Thu Dec 12 2013 Rex Dieter 5.2.0-1 +- 5.2.0 + +* Fri Dec 06 2013 Rex Dieter 5.2.0-0.12.rc1 +- qt5-base-devel.x86_64 qt5-base-devel.i686 file conflict qconfig.h (#1036956) + +* Thu Dec 05 2013 Rex Dieter - 5.2.0-0.11.rc1 +- needs a minimum version on sqlite build dependency (#1038617) +- fix build when doc macro not defined + +* Mon Dec 02 2013 Rex Dieter 5.2.0-0.10.rc1 +- 5.2.0-rc1 +- revert/omit recent egl packaging changes +- -doc install changes-5.* files here (#989149) + +* Tue Nov 26 2013 Rex Dieter 5.2.0-0.8.beta1.20131108_141 +- Install changes-5.x.y file (#989149) + +* Mon Nov 25 2013 Rex Dieter 5.2.0-0.7.beta1.20131108_141 +- enable -doc only on primary archs (allow secondary bootstrap) + +* Fri Nov 22 2013 Lubomir Rintel 5.2.0-0.6.beta1.20131108_141 +- Enable EGL support + +* Sat Nov 09 2013 Rex Dieter 5.2.0-0.5.beta1.20131108_141 +- 2013-11-08_141 snapshot, arm switch qreal double + +* Thu Oct 24 2013 Rex Dieter 5.2.0-0.4.beta1 +- 5.2.0-beta1 + +* Wed Oct 16 2013 Rex Dieter 5.2.0-0.3.alpha +- disable -docs (for ppc bootstrap mostly) + +* Wed Oct 16 2013 Lukáš Tinkl - 5.2.0-0.2.alpha +- Fixes #1005482 - qtbase FTBFS on ppc/ppc64 + +* Tue Oct 01 2013 Rex Dieter - 5.2.0-0.1.alpha +- 5.2.0-alpha +- -system-harfbuzz +- rename subpkg -x11 => -gui +- move some gui-related plugins base => -gui +- don't use symlinks in %%_qt5_bindir (more qtchooser-friendly) + +* Fri Sep 27 2013 Rex Dieter - 5.1.1-6 +- -doc subpkg (not enabled) +- enable %%check + +* Mon Sep 23 2013 Dan Horák - 5.1.1-5 +- fix big endian builds + +* Wed Sep 11 2013 Rex Dieter 5.1.1-4 +- macros.qt5: use newer location, use unexpanded macros + +* Sat Sep 07 2013 Rex Dieter 5.1.1-3 +- ExcludeArch: ppc64 ppc (#1005482) + +* Fri Sep 06 2013 Rex Dieter 5.1.1-2 +- BR: pkgconfig(libudev) pkgconfig(xkbcommon) pkgconfig(xcb-xkb) + +* Tue Aug 27 2013 Rex Dieter 5.1.1-1 +- 5.1.1 + +* Sat Aug 03 2013 Petr Pisar - 5.0.2-8 +- Perl 5.18 rebuild + +* Tue Jul 30 2013 Rex Dieter 5.0.2-7 +- enable qtchooser support + +* Wed Jul 17 2013 Petr Pisar - 5.0.2-6 +- Perl 5.18 rebuild + +* Wed May 08 2013 Than Ngo - 5.0.2-5 +- add poll support, thanks to fweimer@redhat.com (QTBUG-27195) + +* Thu Apr 18 2013 Rex Dieter 5.0.2-4 +- respin lowmem patch to apply (unconditionally) to gcc-4.7.2 too + +* Fri Apr 12 2013 Dan Horák - 5.0.2-3 +- rebase the lowmem patch + +* Wed Apr 10 2013 Rex Dieter 5.0.2-2 +- more cmake_path love (#929227) + +* Wed Apr 10 2013 Rex Dieter - 5.0.2-1 +- 5.0.2 +- fix cmake config (#929227) + +* Tue Apr 02 2013 Rex Dieter 5.0.2-0.1.rc1 +- 5.0.2-rc1 + +* Sat Mar 16 2013 Rex Dieter 5.0.1-6 +- pull in upstream gcc-4.8.0 buildfix + +* Tue Feb 26 2013 Rex Dieter 5.0.1-5 +- -static subpkg, Requires: fontconfig-devel,glib2-devel,zlib-devel +- -devel: Requires: pkgconfig(gl) + +* Mon Feb 25 2013 Rex Dieter 5.0.1-4 +- create/own %%{_qt5_plugindir}/iconengines +- -devel: create/own %%{_qt5_archdatadir}/mkspecs/modules +- cleanup .prl + +* Sat Feb 23 2013 Rex Dieter 5.0.1-3 +- +%%_qt5_libexecdir + +* Sat Feb 23 2013 Rex Dieter 5.0.1-2 +- macros.qt5: fix %%_qt5_headerdir, %%_qt5_datadir, %%_qt5_plugindir + +* Thu Jan 31 2013 Rex Dieter 5.0.1-1 +- 5.0.1 +- lowmem patch for %%arm, s390 + +* Wed Jan 30 2013 Rex Dieter 5.0.0-4 +- %%build: -system-pcre, BR: pkgconfig(libpcre) +- use -O1 optimization on lowmem (s390) arch + +* Thu Jan 24 2013 Rex Dieter 5.0.0-3 +- enable (non-conflicting) qtchooser support + +* Wed Jan 09 2013 Rex Dieter 5.0.0-2 +- add qtchooser support (disabled by default) + +* Wed Dec 19 2012 Rex Dieter 5.0.0-1 +- 5.0 (final) + +* Thu Dec 13 2012 Rex Dieter 5.0.0-0.4.rc2 +- 5.0-rc2 +- initial try at putting non-conflicting binaries in %%_bindir + +* Thu Dec 06 2012 Rex Dieter 5.0.0-0.3.rc1 +- 5.0-rc1 + +* Wed Nov 28 2012 Rex Dieter 5.0.0-0.2.beta2 +- qtbase --> qt5-qtbase + +* Mon Nov 19 2012 Rex Dieter 5.0.0-0.1.beta2 +- %%build: -accessibility +- macros.qt5: +%%_qt5_archdatadir +%%_qt5_settingsdir +- pull in a couple more configure-related upstream patches + +* Wed Nov 14 2012 Rex Dieter 5.0.0-0.0.beta2 +- first try +