diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2016-07-28 13:20:41 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2016-08-01 18:20:00 +0200 |
commit | f6fc34294f5691da8aa7ab8dc0452c6fa9036b67 (patch) | |
tree | 3b8fe9841f88aa81e2f8f2d57cbbca2c4736ca6f | |
parent | 6f75096afc000991111bb0fd7a7e530ce3518627 (diff) | |
parent | 0eb77c3011ee4d6bbc46dd2d40c9324e9bfcbecf (diff) |
Merge remote-tracking branch 'origin/5.7' into dev
Conflicts:
configure
5.7 now supports clang on android; but dev re-worked configure
src/gui/kernel/qevent.h
One side renamed a parameter of a constructor; the other added an
alternate constructor on the next line. Applied the rename to both
for consistency.
tests/auto/tools/moc/tst_moc.cpp
Each side added a new test at the end.
.qmake.conf
Ignored 5.7's change to MODULE_VERSION.
configure.json
No conflict noticed by git; but changes in 5.7 were needed for the
re-worked configure to accommodate 5.7's stricter handling of C++11.
Change-Id: I9cda53836a32d7bf83828212c7ea00b1de3e09d2
96 files changed, 2147 insertions, 789 deletions
diff --git a/.gitignore b/.gitignore index c3c9830385..52b064109f 100644 --- a/.gitignore +++ b/.gitignore @@ -152,6 +152,8 @@ tools/activeqt/testcon/testcon.tlb translations/*.qm translations/*_untranslated.ts qrc_*.cpp +*.version +*.version.in # Test generated files QObject.log diff --git a/config.tests/common/c++11/c++11.cpp b/config.tests/common/c++11/c++11.cpp deleted file mode 100644 index 88b67b5bff..0000000000 --- a/config.tests/common/c++11/c++11.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the configuration of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__INTEL_CXX11_MODE__) -// Compiler claims to support C++11, trust it -#else -# error "__cplusplus must be >= 201103L, or one of __GXX_EXPERIMENTAL_CXX0X__ or __INTEL_CXX11_MODE__ must be defined" -#endif - -#include <utility> -#include <initializer_list> - -int main(int, char **) { return std::move(0); } diff --git a/config.tests/common/c++11/c++11.pro b/config.tests/common/c++11/c++11.pro deleted file mode 100644 index 3620f99c71..0000000000 --- a/config.tests/common/c++11/c++11.pro +++ /dev/null @@ -1,3 +0,0 @@ -SOURCES = c++11.cpp -CONFIG += c++11 console -CONFIG -= qt diff --git a/config.tests/unix/precomp.test b/config.tests/unix/precomp.test index 9ffea20ff9..0b8377b21a 100755 --- a/config.tests/unix/precomp.test +++ b/config.tests/unix/precomp.test @@ -5,7 +5,7 @@ COMPILER=$1 VERBOSE=$2 case "$COMPILER" in -icpc) +*icpc) cat >header.h <<EOF #define HEADER_H @@ -417,7 +417,7 @@ if [ "$BUILD_ON_MAC" = "yes" ]; then exit 2 fi - if ! /usr/bin/xcrun -find xcrun >/dev/null 2>&1; then + if ! /usr/bin/xcrun -find xcodebuild >/dev/null 2>&1; then echo >&2 echo " Xcode not set up properly. You may need to confirm the license" >&2 echo " agreement by running /usr/bin/xcodebuild without arguments." >&2 @@ -1027,7 +1027,10 @@ case "$XPLATFORM" in *unsupported*) ;; *android-g++*) - XPLATFORM_ANDROID=yes + XPLATFORM_ANDROID=g++ + ;; + *android-clang*) + XPLATFORM_ANDROID=clang ;; esac @@ -1193,7 +1196,7 @@ fi # command line and environment validation #------------------------------------------------------------------------------- -if [ "$XPLATFORM_ANDROID" = "yes" ]; then +if [ "$XPLATFORM_ANDROID" != "no" ]; then if [ -z "$CFG_DEFAULT_ANDROID_NDK_HOST" ]; then case $PLATFORM in linux-*) @@ -1336,7 +1339,7 @@ if [ "$OPT_SHADOW" = "yes" ]; then mkdir -p "$outpath/mkspecs" fi -if [ "$XPLATFORM_ANDROID" != "yes" ]; then +if [ "$XPLATFORM_ANDROID" = "no" ]; then TEST_COMPILER=`getXQMakeConf QMAKE_CXX` GCC_MACHINE_DUMP= case "$TEST_COMPILER" in *g++) GCC_MACHINE_DUMP=$($TEST_COMPILER -dumpmachine);; esac diff --git a/configure.bat b/configure.bat index 1cbd733531..5c01890116 100644 --- a/configure.bat +++ b/configure.bat @@ -81,18 +81,18 @@ if not "%icl.exe%" == "" ( rem This must have a trailing space. echo QTSRC = %QTSRC% >> Makefile set tmpl=win32 -) else if not "%clang-cl.exe%" == "" ( - echo CXX = clang-cl>>Makefile - echo EXTRA_CXXFLAGS = -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value>>Makefile - rem This must have a trailing space. - echo QTSRC = %QTSRC% >> Makefile - set tmpl=win32 ) else if not "%cl.exe%" == "" ( echo CXX = cl>>Makefile echo EXTRA_CXXFLAGS =>>Makefile rem This must have a trailing space. echo QTSRC = %QTSRC% >> Makefile set tmpl=win32 +) else if not "%clang-cl.exe%" == "" ( + echo CXX = clang-cl>>Makefile + echo EXTRA_CXXFLAGS = -fms-compatibility-version=19.00.23506 -Wno-microsoft-enum-value>>Makefile + rem This must have a trailing space. + echo QTSRC = %QTSRC% >> Makefile + set tmpl=win32 ) else if not "%g++.exe%" == "" ( echo CXX = g++>>Makefile echo EXTRA_CXXFLAGS =>>Makefile diff --git a/configure.json b/configure.json index 2fc8ea776a..81aea1733f 100644 --- a/configure.json +++ b/configure.json @@ -225,11 +225,6 @@ "type": "compile", "test": "unix/stl" }, - "c++11": { - "description": "C++11 support", - "type": "compile", - "test": "common/c++11" - }, "c++14": { "description": "C++14 support", "type": "compile", @@ -1178,7 +1173,6 @@ }, "c++11": { "description": "C++11", - "condition": "tests.c++11", "output": [ "publicQtConfig" ] }, "c++14": { @@ -2330,11 +2324,6 @@ Please apply the patch corresponding to your Standard Library vendor, found in "type": "error", "condition": "!features.stl", "message": "Qt requires a compliant STL library." - }, - { - "type": "error", - "condition": "!features.c++11", - "message": "Qt requires a C++11 compiler." } ], diff --git a/doc/global/manifest-meta.qdocconf b/doc/global/manifest-meta.qdocconf index bb242eb98f..7ebe86a431 100644 --- a/doc/global/manifest-meta.qdocconf +++ b/doc/global/manifest-meta.qdocconf @@ -250,6 +250,7 @@ manifestmeta.thumbnail.names = "QtCore/Contiguous Cache Example" \ "QtHelp/*" \ "QtMultimedia/AudioEngine Example" \ "QtQml/Extending QML*" \ + "QtQuick/C++ Extensions: Image Response Provider Example" \ "QtQuick/Qt Quick Examples - Accessibility" \ "QtSensors/Qt Sensors - SensorGesture QML Type example" \ "QtWinExtras/Icon Extractor" diff --git a/examples/corelib/mimetypes/mimetypebrowser/mimetypemodel.cpp b/examples/corelib/mimetypes/mimetypebrowser/mimetypemodel.cpp index 99d73717e2..46e603621a 100644 --- a/examples/corelib/mimetypes/mimetypebrowser/mimetypemodel.cpp +++ b/examples/corelib/mimetypes/mimetypebrowser/mimetypemodel.cpp @@ -172,7 +172,8 @@ QString MimetypeModel::formatMimeTypeInfo(const QMimeType &t) str << "</td></tr>" << "<tr><td>Comment:</td><td>" << t.comment() << "</td></tr>" - << "<tr><td>Icon name:</td><td>" << t.iconName() << "</td></tr>"; + << "<tr><td>Icon name:</td><td>" << t.iconName() << "</td></tr>" + << "<tr><td>Generic icon name</td><td>" << t.genericIconName() << "</td></tr>"; const QString &filter = t.filterString(); if (!filter.isEmpty()) diff --git a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp index c472df966c..c47b80275f 100644 --- a/examples/widgets/mainwindows/mainwindow/colorswatch.cpp +++ b/examples/widgets/mainwindows/mainwindow/colorswatch.cpp @@ -61,6 +61,7 @@ #include <QDialog> #include <QDialogButtonBox> #include <QGridLayout> +#include <QSignalBlocker> #include <QSpinBox> #include <QLabel> #include <QPainterPath> @@ -426,20 +427,22 @@ void ColorSwatch::updateContextMenu() allowBottomAction->setEnabled(area != Qt::BottomDockWidgetArea); } - leftAction->blockSignals(true); - rightAction->blockSignals(true); - topAction->blockSignals(true); - bottomAction->blockSignals(true); - - leftAction->setChecked(area == Qt::LeftDockWidgetArea); - rightAction->setChecked(area == Qt::RightDockWidgetArea); - topAction->setChecked(area == Qt::TopDockWidgetArea); - bottomAction->setChecked(area == Qt::BottomDockWidgetArea); - - leftAction->blockSignals(false); - rightAction->blockSignals(false); - topAction->blockSignals(false); - bottomAction->blockSignals(false); + { + const QSignalBlocker blocker(leftAction); + leftAction->setChecked(area == Qt::LeftDockWidgetArea); + } + { + const QSignalBlocker blocker(rightAction); + rightAction->setChecked(area == Qt::RightDockWidgetArea); + } + { + const QSignalBlocker blocker(topAction); + topAction->setChecked(area == Qt::TopDockWidgetArea); + } + { + const QSignalBlocker blocker(bottomAction); + bottomAction->setChecked(area == Qt::BottomDockWidgetArea); + } if (areaActions->isEnabled()) { leftAction->setEnabled(areas & Qt::LeftDockWidgetArea); diff --git a/examples/widgets/widgets/charactermap/mainwindow.cpp b/examples/widgets/widgets/charactermap/mainwindow.cpp index 160b77a945..2141850f16 100644 --- a/examples/widgets/widgets/charactermap/mainwindow.cpp +++ b/examples/widgets/widgets/charactermap/mainwindow.cpp @@ -167,25 +167,27 @@ void MainWindow::findSizes(const QFont &font) { QFontDatabase fontDatabase; QString currentSize = sizeCombo->currentText(); - sizeCombo->blockSignals(true); - sizeCombo->clear(); - - int size; - if(fontDatabase.isSmoothlyScalable(font.family(), fontDatabase.styleString(font))) { - foreach(size, QFontDatabase::standardSizes()) { - sizeCombo->addItem(QVariant(size).toString()); - sizeCombo->setEditable(true); - } - } else { - foreach(size, fontDatabase.smoothSizes(font.family(), fontDatabase.styleString(font))) { - sizeCombo->addItem(QVariant(size).toString()); - sizeCombo->setEditable(false); + { + const QSignalBlocker blocker(sizeCombo); + // sizeCombo signals are now blocked until end of scope + sizeCombo->clear(); + + int size; + if (fontDatabase.isSmoothlyScalable(font.family(), fontDatabase.styleString(font))) { + foreach (size, QFontDatabase::standardSizes()) { + sizeCombo->addItem(QVariant(size).toString()); + sizeCombo->setEditable(true); + } + + } else { + foreach (size, fontDatabase.smoothSizes(font.family(), fontDatabase.styleString(font))) { + sizeCombo->addItem(QVariant(size).toString()); + sizeCombo->setEditable(false); + } } } - sizeCombo->blockSignals(false); - int sizeIndex = sizeCombo->findText(currentSize); if(sizeIndex == -1) diff --git a/mkspecs/android-clang/qmake.conf b/mkspecs/android-clang/qmake.conf new file mode 100644 index 0000000000..6d53bb921d --- /dev/null +++ b/mkspecs/android-clang/qmake.conf @@ -0,0 +1,32 @@ +# qmake configuration for building with android-g++ +MAKEFILE_GENERATOR = UNIX +QMAKE_PLATFORM = android +QMAKE_COMPILER = gcc clang llvm + +CONFIG += android_install unversioned_soname unversioned_libname android_deployment_settings + +include(../common/linux.conf) +include(../common/clang.conf) +include(../common/android-base-head.conf) + +NDK_LLVM_PATH = $$NDK_ROOT/toolchains/llvm/prebuilt/$$NDK_HOST +QMAKE_CC = $$NDK_LLVM_PATH/bin/clang +QMAKE_CXX = $$NDK_LLVM_PATH/bin/clang++ +QMAKE_GCC = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-g++ + +equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ + QMAKE_CFLAGS = -target armv7-none-linux-androideabi +else: equals(ANDROID_TARGET_ARCH, armeabi): \ + QMAKE_CFLAGS = -target armv5te-none-linux-androideabi +else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \ + QMAKE_CFLAGS = -target aarch64-none-linux-android +else: equals(ANDROID_TARGET_ARCH, x86): \ + QMAKE_CFLAGS = -target i686-none-linux-android +else: equals(ANDROID_TARGET_ARCH, x86_64): \ + QMAKE_CFLAGS = -target x86_64-none-linux-android +else: equals(ANDROID_TARGET_ARCH, mips): \ + QMAKE_CFLAGS += -target mipsel-none-linux-android +else: equals(ANDROID_TARGET_ARCH, mips64): \ + QMAKE_CFLAGS = -target mips64el-none-linux-android + +include(../common/android-base-tail.conf) diff --git a/mkspecs/android-clang/qplatformdefs.h b/mkspecs/android-clang/qplatformdefs.h new file mode 100644 index 0000000000..9d3820fa27 --- /dev/null +++ b/mkspecs/android-clang/qplatformdefs.h @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec 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 QPLATFORMDEFS_H +#define QPLATFORMDEFS_H + +#define QT_QPA_DEFAULT_PLATFORM_NAME "android" + +// Get Qt defines/settings + +#include "qglobal.h" + +// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs + +// 1) need to reset default environment if _BSD_SOURCE is defined +// 2) need to specify POSIX thread interfaces explicitly in glibc 2.0 +// 3) it seems older glibc need this to include the X/Open stuff + +#include <unistd.h> + +// We are hot - unistd.h should have turned on the specific APIs we requested + +#include <features.h> +#include <pthread.h> +#include <dirent.h> +#include <fcntl.h> +#include <grp.h> +#include <pwd.h> +#include <signal.h> +#include <dlfcn.h> + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/ipc.h> +#include <sys/time.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#ifndef QT_NO_IPV6IFNAME +#include <net/if.h> +#endif + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#ifdef QT_LARGEFILE_SUPPORT +#define QT_STATBUF struct stat64 +#define QT_STATBUF4TSTAT struct stat64 +#define QT_STAT ::stat64 +#define QT_FSTAT ::fstat64 +#define QT_LSTAT ::lstat64 +#define QT_OPEN ::open64 +#define QT_TRUNCATE ::truncate64 +#define QT_FTRUNCATE ::ftruncate64 +#define QT_LSEEK ::lseek64 +#else +#define QT_STATBUF struct stat +#define QT_STATBUF4TSTAT struct stat +#define QT_STAT ::stat +#define QT_FSTAT ::fstat +#define QT_LSTAT ::lstat +#define QT_OPEN ::open +#define QT_TRUNCATE ::truncate +#define QT_FTRUNCATE ::ftruncate +#define QT_LSEEK ::lseek +#endif + +#ifdef QT_LARGEFILE_SUPPORT +#define QT_FOPEN ::fopen64 +#define QT_FSEEK ::fseeko64 +#define QT_FTELL ::ftello64 +#define QT_FGETPOS ::fgetpos64 +#define QT_FSETPOS ::fsetpos64 +#define QT_MMAP ::mmap64 +#define QT_FPOS_T fpos64_t +#define QT_OFF_T off64_t +#else +#define QT_FOPEN ::fopen +#define QT_FSEEK ::fseek +#define QT_FTELL ::ftell +#define QT_FGETPOS ::fgetpos +#define QT_FSETPOS ::fsetpos +#define QT_MMAP ::mmap +#define QT_FPOS_T fpos_t +#define QT_OFF_T long +#endif + +#define QT_STAT_REG S_IFREG +#define QT_STAT_DIR S_IFDIR +#define QT_STAT_MASK S_IFMT +#define QT_STAT_LNK S_IFLNK +#define QT_SOCKET_CONNECT ::connect +#define QT_SOCKET_BIND ::bind +#define QT_FILENO fileno +#define QT_CLOSE ::close +#define QT_READ ::read +#define QT_WRITE ::write +#define QT_ACCESS ::access +#define QT_GETCWD ::getcwd +#define QT_CHDIR ::chdir +#define QT_MKDIR ::mkdir +#define QT_RMDIR ::rmdir +#define QT_OPEN_LARGEFILE O_LARGEFILE +#define QT_OPEN_RDONLY O_RDONLY +#define QT_OPEN_WRONLY O_WRONLY +#define QT_OPEN_RDWR O_RDWR +#define QT_OPEN_CREAT O_CREAT +#define QT_OPEN_TRUNC O_TRUNC +#define QT_OPEN_APPEND O_APPEND + +// Directory iteration +#define QT_DIR DIR + +#define QT_OPENDIR ::opendir +#define QT_CLOSEDIR ::closedir + +#if defined(QT_LARGEFILE_SUPPORT) \ + && defined(QT_USE_XOPEN_LFS_EXTENSIONS) \ + && !defined(QT_NO_READDIR64) +#define QT_DIRENT struct dirent64 +#define QT_READDIR ::readdir64 +#define QT_READDIR_R ::readdir64_r +#else +#define QT_DIRENT struct dirent +#define QT_READDIR ::readdir +#define QT_READDIR_R ::readdir_r +#endif + +#define QT_SOCKET_CONNECT ::connect +#define QT_SOCKET_BIND ::bind + + +#define QT_SIGNAL_RETTYPE void +#define QT_SIGNAL_ARGS int +#define QT_SIGNAL_IGNORE SIG_IGN + +#define QT_SOCKLEN_T socklen_t + +#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500) +#define QT_SNPRINTF ::snprintf +#define QT_VSNPRINTF ::vsnprintf +#endif + +#endif // QPLATFORMDEFS_H diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf index ef78c42de9..93bd5fa1c2 100644 --- a/mkspecs/android-g++/qmake.conf +++ b/mkspecs/android-g++/qmake.conf @@ -7,202 +7,12 @@ CONFIG += android_install unversioned_soname unversioned_libname include(../common/linux.conf) include(../common/gcc-base-unix.conf) +include(../common/android-base-head.conf) -load(device_config) - -NDK_ROOT = $$(ANDROID_NDK_ROOT) -!exists($$NDK_ROOT) { - NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT -} - -NDK_HOST = $$(ANDROID_NDK_HOST) -isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST - -ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM) -isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = $$DEFAULT_ANDROID_PLATFORM - -ANDROID_TARGET_ARCH = $$(ANDROID_TARGET_ARCH) -isEmpty(ANDROID_TARGET_ARCH): ANDROID_TARGET_ARCH = $$DEFAULT_ANDROID_TARGET_ARCH - -NDK_TOOLCHAIN_PREFIX = $$(ANDROID_NDK_TOOLCHAIN_PREFIX) -isEmpty(NDK_TOOLCHAIN_PREFIX) { - equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLCHAIN_PREFIX = x86 - else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLCHAIN_PREFIX = x86_64 - else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLCHAIN_PREFIX = mipsel-linux-android - else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLCHAIN_PREFIX = mips64el-linux-android - else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-android - else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi -} - -NDK_TOOLS_PREFIX = $$(ANDROID_NDK_TOOLS_PREFIX) -isEmpty(NDK_TOOLS_PREFIX) { - equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLS_PREFIX = i686-linux-android - else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLS_PREFIX = x86_64-linux-android - else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLS_PREFIX = mipsel-linux-android - else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLS_PREFIX = mips64el-linux-android - else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLS_PREFIX = aarch64-linux-android - else: NDK_TOOLS_PREFIX = arm-linux-androideabi -} - -NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION) -isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = $$DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION - -equals(ANDROID_TARGET_ARCH, x86): ANDROID_ARCHITECTURE = x86 -else: equals(ANDROID_TARGET_ARCH, x86_64): ANDROID_ARCHITECTURE = x86_64 -else: equals(ANDROID_TARGET_ARCH, mips): ANDROID_ARCHITECTURE = mips -else: equals(ANDROID_TARGET_ARCH, mips64): ANDROID_ARCHITECTURE = mips64 -else: equals(ANDROID_TARGET_ARCH, arm64-v8a): ANDROID_ARCHITECTURE = arm64 -else: ANDROID_ARCHITECTURE = arm - -!equals(NDK_TOOLCHAIN_VERSION, 4.4.3): ANDROID_CXXSTL_SUFFIX = -$$NDK_TOOLCHAIN_VERSION - -NDK_TOOLCHAIN = $$NDK_TOOLCHAIN_PREFIX-$$NDK_TOOLCHAIN_VERSION -NDK_TOOLCHAIN_PATH = $$NDK_ROOT/toolchains/$$NDK_TOOLCHAIN/prebuilt/$$NDK_HOST - - -ANDROID_SDK_ROOT = $$(ANDROID_SDK_ROOT) -isEmpty(ANDROID_SDK_ROOT): ANDROID_SDK_ROOT = $$DEFAULT_ANDROID_SDK_ROOT - -ANDROID_SDK_BUILD_TOOLS_REVISION = $$(ANDROID_BUILD_TOOLS_REVISION) -isEmpty(ANDROID_SDK_BUILD_TOOLS_REVISION) { - SDK_BUILD_TOOLS_REVISIONS = $$files($$ANDROID_SDK_ROOT/build-tools/*) - for (REVISION, SDK_BUILD_TOOLS_REVISIONS) { - BASENAME = $$basename(REVISION) - greaterThan(BASENAME, $$ANDROID_SDK_BUILD_TOOLS_REVISION): ANDROID_SDK_BUILD_TOOLS_REVISION = $$BASENAME - } -} - -CONFIG += $$ANDROID_PLATFORM -ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/ -ANDROID_PLATFORM_PATH = $$ANDROID_PLATFORM_ROOT_PATH/usr - -# used to compile platform plugins for android-4 and android-5 -QMAKE_ANDROID_PLATFORM_INCDIR = $$ANDROID_PLATFORM_PATH/include -QMAKE_ANDROID_PLATFORM_LIBDIR = $$ANDROID_PLATFORM_PATH/lib - -ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/libs/$$ANDROID_TARGET_ARCH -ANDROID_SOURCES_CXX_STL_INCDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/include $$ANDROID_SOURCES_CXX_STL_LIBDIR/include - -equals(ANDROID_TARGET_ARCH, x86_64)|equals(ANDROID_TARGET_ARCH, mips64): \ - QMAKE_ANDROID_PLATFORM_LIBDIR = $${QMAKE_ANDROID_PLATFORM_LIBDIR}64 - -# modifications to g++.conf QMAKE_CC = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-gcc - -equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ - QMAKE_CFLAGS = -Wno-psabi -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -DANDROID -Wa,--noexecstack -fno-builtin-memmove -else: equals(ANDROID_TARGET_ARCH, armeabi): \ - QMAKE_CFLAGS = -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -DANDROID -Wa,--noexecstack -fno-builtin-memmove -else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \ - QMAKE_CFLAGS = -ffunction-sections -funwind-tables -fstack-protector -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300 -DANDROID -Wa,--noexecstack -else: equals(ANDROID_TARGET_ARCH, x86): \ - QMAKE_CFLAGS = -ffunction-sections -funwind-tables -O2 -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300 -DANDROID -Wa,--noexecstack -else: equals(ANDROID_TARGET_ARCH, x86_64): \ - QMAKE_CFLAGS = -ffunction-sections -funwind-tables -fstack-protector -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300 -DANDROID -Wa,--noexecstack -else: equals(ANDROID_TARGET_ARCH, mips): \ - QMAKE_CFLAGS = -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers -O2 -fomit-frame-pointer -funswitch-loops -finline-limit=300 -DANDROID -Wa,--noexecstack -else: equals(ANDROID_TARGET_ARCH, mips64): \ - QMAKE_CFLAGS = -fno-strict-aliasing -finline-functions -ffunction-sections -funwind-tables -fmessage-length=0 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers -fomit-frame-pointer -funswitch-loops -finline-limit=300 -DANDROID -Werror -Wa,--noexecstack - -QMAKE_CFLAGS_WARN_ON = -Wall -Wno-psabi -W -QMAKE_CFLAGS_WARN_OFF = -Wno-psabi -equals(ANDROID_TARGET_ARCH, x86) { - QMAKE_CFLAGS_RELEASE = -O2 - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 - QMAKE_CFLAGS_DEBUG = -g -} else: equals(ANDROID_TARGET_ARCH, x86_64) { - QMAKE_CFLAGS_RELEASE = -O2 - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 - QMAKE_CFLAGS_DEBUG = -g -} else: equals(ANDROID_TARGET_ARCH, mips) { - QMAKE_CFLAGS_RELEASE = -O2 - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 - QMAKE_CFLAGS_DEBUG = -g -fno-omit-frame-pointer -} else: equals(ANDROID_TARGET_ARCH, mips64) { - QMAKE_CFLAGS_RELEASE = -O2 - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 - QMAKE_CFLAGS_DEBUG = -g -fno-omit-frame-pointer -} else: equals(ANDROID_TARGET_ARCH, arm64-v8a) { - QMAKE_CFLAGS_RELEASE = -O2 - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 - QMAKE_CFLAGS_DEBUG = -g -fno-omit-frame-pointer -} else { # arm - QMAKE_CFLAGS_RELEASE = -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Os -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64 - QMAKE_CFLAGS_DEBUG = -g -marm -O0 -fno-omit-frame-pointer - equals(ANDROID_TARGET_ARCH, armeabi):if(equals(NDK_TOOLCHAIN_VERSION, 4.8)|equals(NDK_TOOLCHAIN_VERSION, 4.9)) { - DEFINES += QT_OS_ANDROID_GCC_48_WORKAROUND - } else { - QMAKE_CFLAGS_RELEASE += -mthumb - QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb - } -} - -QMAKE_CFLAGS_SHLIB = -fPIC -QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses -QMAKE_CFLAGS_THREAD = -D_REENTRANT -QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden - QMAKE_CXX = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-g++ -QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -std=c++11 -QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF -QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE -QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO -QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG -QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB -QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC -QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD -QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden - -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_LINK - -# modifications to linux.conf -QMAKE_AR = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ar cqs -QMAKE_OBJCOPY = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-objcopy -QMAKE_NM = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-nm -P - -QMAKE_STRIP = -#$$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-strip - -QMAKE_RANLIB = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ranlib - -equals(ANDROID_TARGET_ARCH, armeabi)|equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ - LIBGCC_PATH_FULL = $$system("$$QMAKE_CC -mthumb-interwork -print-libgcc-file-name") -else: \ - LIBGCC_PATH_FULL = $$system("$$QMAKE_CC -print-libgcc-file-name") - -LIBGCC_PATH = $$dirname(LIBGCC_PATH_FULL) - -QMAKE_INCDIR = $$ANDROID_SOURCES_CXX_STL_INCDIR $$QMAKE_ANDROID_PLATFORM_INCDIR -QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$QMAKE_ANDROID_PLATFORM_LIBDIR $$LIBGCC_PATH -QMAKE_INCDIR_X11 = -QMAKE_LIBDIR_X11 = -QMAKE_INCDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_INCDIR -QMAKE_LIBDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_LIBDIR - -QMAKE_LINK = $$QMAKE_CXX -QMAKE_LINK_SHLIB = $$QMAKE_CXX -QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH -QMAKE_RPATHLINK = $$QMAKE_ANDROID_PLATFORM_LIBDIR -QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared -QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared -QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB -QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined -QMAKE_LFLAGS_RPATH = -Wl,-rpath= -QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link= - -QMAKE_LIBS_PRIVATE = -lgnustl_shared -llog -lz -lm -ldl -lc -lgcc -QMAKE_LIBS_X11 = -QMAKE_LIBS_THREAD = -QMAKE_LIBS_EGL = -lEGL -QMAKE_LIBS_OPENGL = -QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 - -!exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.") +QMAKE_GCC = $$QMAKE_CXX -load(qt_config) +QMAKE_CFLAGS = -QMAKE_DEFAULT_LIBDIRS = $$QMAKE_LIBDIR -QMAKE_DEFAULT_INCDIRS = $$QMAKE_INCDIR +include(../common/android-base-tail.conf) diff --git a/mkspecs/common/android-base-head.conf b/mkspecs/common/android-base-head.conf new file mode 100644 index 0000000000..7b2e988808 --- /dev/null +++ b/mkspecs/common/android-base-head.conf @@ -0,0 +1,78 @@ +load(device_config) + +NDK_ROOT = $$(ANDROID_NDK_ROOT) +!exists($$NDK_ROOT) { + NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT +} + +NDK_HOST = $$(ANDROID_NDK_HOST) +isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST + +ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM) +isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = $$DEFAULT_ANDROID_PLATFORM + +ANDROID_TARGET_ARCH = $$(ANDROID_TARGET_ARCH) +isEmpty(ANDROID_TARGET_ARCH): ANDROID_TARGET_ARCH = $$DEFAULT_ANDROID_TARGET_ARCH + +NDK_TOOLCHAIN_PREFIX = $$(ANDROID_NDK_TOOLCHAIN_PREFIX) +isEmpty(NDK_TOOLCHAIN_PREFIX) { + equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLCHAIN_PREFIX = x86 + else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLCHAIN_PREFIX = x86_64 + else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLCHAIN_PREFIX = mipsel-linux-android + else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLCHAIN_PREFIX = mips64el-linux-android + else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-android + else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi +} + +NDK_TOOLS_PREFIX = $$(ANDROID_NDK_TOOLS_PREFIX) +isEmpty(NDK_TOOLS_PREFIX) { + equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLS_PREFIX = i686-linux-android + else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLS_PREFIX = x86_64-linux-android + else: equals(ANDROID_TARGET_ARCH, mips): NDK_TOOLS_PREFIX = mipsel-linux-android + else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLS_PREFIX = mips64el-linux-android + else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLS_PREFIX = aarch64-linux-android + else: NDK_TOOLS_PREFIX = arm-linux-androideabi +} + +NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION) +isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = $$DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION + +equals(ANDROID_TARGET_ARCH, x86): ANDROID_ARCHITECTURE = x86 +else: equals(ANDROID_TARGET_ARCH, x86_64): ANDROID_ARCHITECTURE = x86_64 +else: equals(ANDROID_TARGET_ARCH, mips): ANDROID_ARCHITECTURE = mips +else: equals(ANDROID_TARGET_ARCH, mips64): ANDROID_ARCHITECTURE = mips64 +else: equals(ANDROID_TARGET_ARCH, arm64-v8a): ANDROID_ARCHITECTURE = arm64 +else: ANDROID_ARCHITECTURE = arm + +!equals(NDK_TOOLCHAIN_VERSION, 4.4.3): ANDROID_CXXSTL_SUFFIX = -$$NDK_TOOLCHAIN_VERSION + +NDK_TOOLCHAIN = $$NDK_TOOLCHAIN_PREFIX-$$NDK_TOOLCHAIN_VERSION +NDK_TOOLCHAIN_PATH = $$NDK_ROOT/toolchains/$$NDK_TOOLCHAIN/prebuilt/$$NDK_HOST + + +ANDROID_SDK_ROOT = $$(ANDROID_SDK_ROOT) +isEmpty(ANDROID_SDK_ROOT): ANDROID_SDK_ROOT = $$DEFAULT_ANDROID_SDK_ROOT + +ANDROID_SDK_BUILD_TOOLS_REVISION = $$(ANDROID_BUILD_TOOLS_REVISION) +isEmpty(ANDROID_SDK_BUILD_TOOLS_REVISION) { + SDK_BUILD_TOOLS_REVISIONS = $$files($$ANDROID_SDK_ROOT/build-tools/*) + for (REVISION, SDK_BUILD_TOOLS_REVISIONS) { + BASENAME = $$basename(REVISION) + greaterThan(BASENAME, $$ANDROID_SDK_BUILD_TOOLS_REVISION): ANDROID_SDK_BUILD_TOOLS_REVISION = $$BASENAME + } +} + +CONFIG += $$ANDROID_PLATFORM +ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/ +ANDROID_PLATFORM_PATH = $$ANDROID_PLATFORM_ROOT_PATH/usr + +# used to compile platform plugins for android-4 and android-5 +QMAKE_ANDROID_PLATFORM_INCDIR = $$ANDROID_PLATFORM_PATH/include +QMAKE_ANDROID_PLATFORM_LIBDIR = $$ANDROID_PLATFORM_PATH/lib + +ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/libs/$$ANDROID_TARGET_ARCH +ANDROID_SOURCES_CXX_STL_INCDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/include $$ANDROID_SOURCES_CXX_STL_LIBDIR/include + +equals(ANDROID_TARGET_ARCH, x86_64)|equals(ANDROID_TARGET_ARCH, mips64): \ + QMAKE_ANDROID_PLATFORM_LIBDIR = $${QMAKE_ANDROID_PLATFORM_LIBDIR}64 + diff --git a/mkspecs/common/android-base-tail.conf b/mkspecs/common/android-base-tail.conf new file mode 100644 index 0000000000..0dcaf64cff --- /dev/null +++ b/mkspecs/common/android-base-tail.conf @@ -0,0 +1,105 @@ +# -fstack-protector-strong offers good protection against stack smashing attacks. +# It is (currently) enabled only on Android because we know for sure that Andoroid compilers supports it +QMAKE_CFLAGS += -fstack-protector-strong -DANDROID + +equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ + QMAKE_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -fno-builtin-memmove +else: equals(ANDROID_TARGET_ARCH, armeabi): \ + QMAKE_CFLAGS += -march=armv5te -mtune=xscale -msoft-float -fno-builtin-memmove +# -fno-builtin-memmove is used to workaround https://code.google.com/p/android/issues/detail?id=81692 + +QMAKE_CFLAGS += --sysroot=$$ANDROID_PLATFORM_ROOT_PATH +QMAKE_CFLAGS_WARN_ON = -Wall -W +QMAKE_CFLAGS_WARN_OFF = +equals(ANDROID_TARGET_ARCH, armeabi-v7a) | equals(ANDROID_TARGET_ARCH, armeabi) { + QMAKE_CFLAGS_RELEASE = -Os + QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Os + QMAKE_CFLAGS_DEBUG = -g -marm -O0 + equals(ANDROID_TARGET_ARCH, armeabi):if(equals(NDK_TOOLCHAIN_VERSION, 4.8)|equals(NDK_TOOLCHAIN_VERSION, 4.9)) { + DEFINES += QT_OS_ANDROID_GCC_48_WORKAROUND + } else { + QMAKE_CFLAGS_RELEASE += -mthumb + QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb + } + + # Don't override our options with -O3 + QMAKE_CFLAGS_OPTIMIZE_FULL = +} else { + QMAKE_CFLAGS_RELEASE = -O2 + QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -O2 + QMAKE_CFLAGS_DEBUG = -g +} + +QMAKE_CFLAGS_SHLIB = -fPIC +QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses +QMAKE_CFLAGS_THREAD = -D_REENTRANT +QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden +QMAKE_CFLAGS_NEON = -mfpu=neon + +QMAKE_CXXFLAGS_CXX11 = -std=c++11 +QMAKE_CXXFLAGS_CXX14 = -std=c++14 +QMAKE_CXXFLAGS_CXX1Z = -std=c++1z +QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11 +QMAKE_CXXFLAGS_GNUCXX14 = -std=gnu++14 +QMAKE_CXXFLAGS_GNUCXX1Z = -std=gnu++1z + +QMAKE_CXXFLAGS = $$QMAKE_CFLAGS +QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON +QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF +QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE +QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO +QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG +QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB +QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC +QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD +QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden + +# modifications to linux.conf +QMAKE_AR = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ar cqs +QMAKE_OBJCOPY = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-objcopy +QMAKE_NM = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-nm -P + +QMAKE_STRIP = +#$$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-strip + +QMAKE_RANLIB = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ranlib + +equals(ANDROID_TARGET_ARCH, armeabi)|equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ + LIBGCC_PATH_FULL = $$system("$$QMAKE_GCC -mthumb-interwork -print-libgcc-file-name") +else: \ + LIBGCC_PATH_FULL = $$system("$$QMAKE_GCC -print-libgcc-file-name") + +LIBGCC_PATH = $$dirname(LIBGCC_PATH_FULL) + +QMAKE_INCDIR = $$ANDROID_SOURCES_CXX_STL_INCDIR $$QMAKE_ANDROID_PLATFORM_INCDIR +QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$QMAKE_ANDROID_PLATFORM_LIBDIR $$LIBGCC_PATH +QMAKE_INCDIR_X11 = +QMAKE_LIBDIR_X11 = +QMAKE_INCDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_INCDIR +QMAKE_LIBDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_LIBDIR + +QMAKE_LINK = $$QMAKE_GCC +QMAKE_LINK_SHLIB = $$QMAKE_GCC +QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH +QMAKE_RPATHLINK = $$QMAKE_ANDROID_PLATFORM_LIBDIR +QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared +QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared +QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB +QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined +QMAKE_LFLAGS_RPATH = -Wl,-rpath= +QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link= + +QMAKE_LIBS_PRIVATE = -lgnustl_shared -llog -lz -lm -ldl -lc -lgcc +QMAKE_LIBS_X11 = +QMAKE_LIBS_THREAD = +QMAKE_LIBS_EGL = -lEGL +QMAKE_LIBS_OPENGL = +QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 + + +!exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.") + +load(qt_config) + +QMAKE_DEFAULT_LIBDIRS = $$QMAKE_LIBDIR +QMAKE_DEFAULT_INCDIRS = $$QMAKE_INCDIR diff --git a/mkspecs/features/mac/default_pre.prf b/mkspecs/features/mac/default_pre.prf index 0cc8cd6dfd..5df99d1acd 100644 --- a/mkspecs/features/mac/default_pre.prf +++ b/mkspecs/features/mac/default_pre.prf @@ -12,7 +12,7 @@ isEmpty(QMAKE_XCODE_DEVELOPER_PATH) { error("Xcode is not installed in $${QMAKE_XCODE_DEVELOPER_PATH}. Please use xcode-select to choose Xcode installation path.") # Make sure Xcode is set up properly - isEmpty($$list($$system("/usr/bin/xcrun -find xcrun 2>/dev/null"))): \ + isEmpty($$list($$system("/usr/bin/xcrun -find xcodebuild 2>/dev/null"))): \ error("Xcode not set up properly. You may need to confirm the license agreement by running /usr/bin/xcodebuild.") } diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index 74d24aacf4..628210b55b 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -57,6 +57,8 @@ #include <utime.h> #include <errno.h> #include <unistd.h> +#include <signal.h> +#include <sys/wait.h> #include <sys/stat.h> #include <sys/utsname.h> #else @@ -1610,9 +1612,14 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( runProcess(&proc, args.at(0).toQString(m_tmp2)); return returnBool(proc.exitStatus() == QProcess::NormalExit && proc.exitCode() == 0); #else - return returnBool(system((QLatin1String("cd ") - + IoUtils::shellQuote(QDir::toNativeSeparators(currentDirectory())) - + QLatin1String(" && ") + args.at(0)).toLocal8Bit().constData()) == 0); + int ec = system((QLatin1String("cd ") + + IoUtils::shellQuote(QDir::toNativeSeparators(currentDirectory())) + + QLatin1String(" && ") + args.at(0)).toLocal8Bit().constData()); +# ifdef Q_OS_UNIX + if (ec != -1 && WIFSIGNALED(ec) && (WTERMSIG(ec) == SIGQUIT || WTERMSIG(ec) == SIGINT)) + raise(WTERMSIG(ec)); +# endif + return returnBool(ec == 0); #endif #else return ReturnTrue; diff --git a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro index 99c32ea672..4fd0823332 100644 --- a/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro +++ b/src/3rdparty/harfbuzz-ng/harfbuzz-ng.pro @@ -23,7 +23,10 @@ win32: DEFINES += HB_NO_WIN1256 android: DEFINES += _POSIX_C_SOURCE=200112L INCLUDEPATH += $$PWD/include + +# Harfbuzz-NG inside Qt uses the Qt atomics (inline code only) INCLUDEPATH += $$QT.core.includes +DEFINES += QT_NO_VERSION_TAGGING SOURCES += \ $$PWD/src/hb-blob.cc \ diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c b/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c index b43ac9c353..966537ffa0 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c +++ b/src/3rdparty/harfbuzz/src/harfbuzz-arabic.c @@ -921,7 +921,7 @@ static void shapedString(const HB_UChar16 *uc, hb_uint32 stringLength, hb_uint32 for (i = 0; i < len; i++) { hb_uint8 r = *ch >> 8; - int gpos = data - shapeBuffer; + const int gpos = int(data - shapeBuffer); if (r != 0x06) { if (r == 0x20) { @@ -981,7 +981,7 @@ static void shapedString(const HB_UChar16 *uc, hb_uint32 stringLength, hb_uint32 /* qDebug("glyph %d (char %d) is mark!", gpos, i); */ } else { attributes[gpos].mark = FALSE; - clusterStart = data - shapeBuffer; + clusterStart = int(data - shapeBuffer); } attributes[gpos].clusterStart = !attributes[gpos].mark; attributes[gpos].combiningClass = HB_GetUnicodeCharCombiningClass(*ch); @@ -992,7 +992,7 @@ static void shapedString(const HB_UChar16 *uc, hb_uint32 stringLength, hb_uint32 ch++; logClusters[i] = clusterStart; } - *shapedLength = data - shapeBuffer; + *shapedLength = int(data - shapeBuffer); HB_FREE_STACKARRAY(props); } diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp index f7a4195308..30dde281e8 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp +++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp @@ -94,7 +94,7 @@ static inline void positionCluster(HB_ShaperItem *item, int gfrom, int glast) offsetBase = ((size * 10) - markTotalHeight) / 2; // Use offset that just fits } - bool rightToLeft = item->item.bidiLevel % 2; + const bool rightToLeft = (item->item.bidiLevel % 2) != 0; int i; unsigned char lastCmb = 0; @@ -281,7 +281,7 @@ void HB_HeuristicSetGlyphAttributes(HB_ShaperItem *item) // first char in a run is never (treated as) a mark int cStart = 0; - const bool symbolFont = item->face->isSymbolFont; + const bool symbolFont = item->face->isSymbolFont != 0; attributes[0].mark = false; attributes[0].clusterStart = true; attributes[0].dontPrint = (!symbolFont && uc[0] == 0x00ad) || HB_IsControlChar(uc[0]); diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 0cfce2c6af..656dbdda45 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -489,11 +489,19 @@ public class QtActivityDelegate continue; try { - @SuppressWarnings("rawtypes") - Class<?> initClass = classLoader.loadClass(className); - Object staticInitDataObject = initClass.newInstance(); // create an instance - Method m = initClass.getMethod("setActivity", Activity.class, Object.class); - m.invoke(staticInitDataObject, m_activity, this); + Class<?> initClass = classLoader.loadClass(className); + Object staticInitDataObject = initClass.newInstance(); // create an instance + try { + Method m = initClass.getMethod("setActivity", Activity.class, Object.class); + m.invoke(staticInitDataObject, m_activity, this); + } catch (Exception e) { + } + + try { + Method m = initClass.getMethod("setContext", Context.class); + m.invoke(staticInitDataObject, (Context)m_activity); + } catch (Exception e) { + } } catch (Exception e) { e.printStackTrace(); } diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java index 634658eefb..5ac406c710 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtServiceDelegate.java @@ -120,12 +120,20 @@ public class QtServiceDelegate for (String className: loaderParams.getStringArray(STATIC_INIT_CLASSES_KEY)) { if (className.length() == 0) continue; - try { - Class<?> initClass = classLoader.loadClass(className); - Object staticInitDataObject = initClass.newInstance(); // create an instance - Method m = initClass.getMethod("setService", Service.class, Object.class); - m.invoke(staticInitDataObject, m_service, this); + Class<?> initClass = classLoader.loadClass(className); + Object staticInitDataObject = initClass.newInstance(); // create an instance + try { + Method m = initClass.getMethod("setService", Service.class, Object.class); + m.invoke(staticInitDataObject, m_service, this); + } catch (Exception e) { + } + + try { + Method m = initClass.getMethod("setContext", Context.class); + m.invoke(staticInitDataObject, (Context)m_service); + } catch (Exception e) { + } } catch (Exception e) { e.printStackTrace(); } diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index c5424be035..70c9e97c13 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -557,6 +557,12 @@ * Q_COMPILER_RESTRICTED_VLA variable-length arrays, prior to __cpp_runtime_arrays */ +#ifdef __cplusplus +# if __cplusplus < 201103L && !(defined(Q_CC_MSVC) && Q_CC_MSVC >= 1800) +# error Qt requires a C++11 compiler and yours does not seem to be that. +# endif +#endif + #ifdef Q_CC_INTEL # define Q_COMPILER_RESTRICTED_VLA # define Q_COMPILER_VARIADIC_MACROS // C++11 feature supported as an extension in other modes, too @@ -1023,6 +1029,33 @@ // critical definitions. (Reported as Intel Issue ID 6000117277) # define __USE_CONSTEXPR 1 # define __USE_NOEXCEPT 1 +# elif defined(Q_CC_MSVC) && (defined(Q_CC_CLANG) || defined(Q_CC_INTEL)) +// Clang and the Intel compiler support more C++ features than the Microsoft compiler +// so make sure we don't enable them if the MS headers aren't properly adapted. +# ifndef _HAS_CONSTEXPR +# undef Q_COMPILER_CONSTEXPR +# endif +# ifndef _HAS_DECLTYPE +# undef Q_COMPILER_DECLTYPE +# endif +# ifndef _HAS_INITIALIZER_LISTS +# undef Q_COMPILER_INITIALIZER_LISTS +# endif +# ifndef _HAS_NULLPTR_T +# undef Q_COMPILER_NULLPTR +# endif +# ifndef _HAS_RVALUE_REFERENCES +# undef Q_COMPILER_RVALUE_REFS +# endif +# ifndef _HAS_SCOPED_ENUM +# undef Q_COMPILER_CLASS_ENUM +# endif +# ifndef _HAS_TEMPLATE_ALIAS +# undef Q_COMPILER_TEMPLATE_ALIAS +# endif +# ifndef _HAS_VARIADIC_TEMPLATES +# undef Q_COMPILER_VARIADIC_TEMPLATES +# endif # elif defined(_LIBCPP_VERSION) // libc++ uses __has_feature(cxx_atomic), so disable the feature if the compiler // doesn't support it. That's required for the Intel compiler 14.x or earlier on OS X, for example. diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h index 5956f9ac40..ac58677b77 100644 --- a/src/corelib/io/qdatastream.h +++ b/src/corelib/io/qdatastream.h @@ -63,6 +63,9 @@ template <class Key, class T> class QMap; #if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED) class QDataStreamPrivate; +namespace QtPrivate { +class StreamStateSaver; +} class Q_CORE_EXPORT QDataStream { public: @@ -193,6 +196,7 @@ private: Status q_status; int readBlock(char *data, int len); + friend class QtPrivate::StreamStateSaver; }; namespace QtPrivate { @@ -202,7 +206,8 @@ class StreamStateSaver public: inline StreamStateSaver(QDataStream *s) : stream(s), oldStatus(s->status()) { - stream->resetStatus(); + if (!stream->dev || !stream->dev->isTransactionStarted()) + stream->resetStatus(); } inline ~StreamStateSaver() { diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 70c347978e..5c79a745fa 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -378,15 +378,13 @@ qint64 QFSFileEnginePrivate::nativeWrite(const char *data, qint64 len) if (fileHandle == INVALID_HANDLE_VALUE) return -1; - qint64 bytesToWrite = DWORD(len); // <- lossy + qint64 bytesToWrite = len; // Writing on Windows fails with ERROR_NO_SYSTEM_RESOURCES when // the chunks are too large, so we limit the block size to 32MB. - static const DWORD maxBlockSize = 32 * 1024 * 1024; - + const DWORD blockSize = DWORD(qMin(bytesToWrite, qint64(32 * 1024 * 1024))); qint64 totalWritten = 0; do { - DWORD blockSize = qMin<DWORD>(bytesToWrite, maxBlockSize); DWORD bytesWritten; if (!WriteFile(fileHandle, data + totalWritten, blockSize, &bytesWritten, NULL)) { if (totalWritten == 0) { diff --git a/src/corelib/io/qtemporarydir.cpp b/src/corelib/io/qtemporarydir.cpp index 563913bc12..6e50a8513e 100644 --- a/src/corelib/io/qtemporarydir.cpp +++ b/src/corelib/io/qtemporarydir.cpp @@ -51,8 +51,12 @@ #include "qcoreapplication.h" #endif +#if !defined(Q_OS_QNX) && !defined(Q_OS_WIN) && !defined(Q_OS_ANDROID) && !defined(Q_OS_INTEGRITY) +# define USE_SYSTEM_MKDTEMP +#endif + #include <stdlib.h> // mkdtemp -#if defined(Q_OS_QNX) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) || defined(Q_OS_INTEGRITY) +#ifndef USE_SYSTEM_MKDTEMP #include <private/qfilesystemengine_p.h> #endif @@ -98,8 +102,7 @@ static QString defaultTemplateName() return QDir::tempPath() + QLatin1Char('/') + baseName + QLatin1String("-XXXXXX"); } -#if defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) || defined(Q_OS_INTEGRITY) - +#ifndef USE_SYSTEM_MKDTEMP static int nextRand(int &v) { int r = v % 62; @@ -109,30 +112,28 @@ static int nextRand(int &v) return r; } -QPair<QString, bool> q_mkdtemp(char *templateName) +QPair<QString, bool> q_mkdtemp(QString templateName) { - static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + Q_ASSERT(templateName.endsWith(QLatin1String("XXXXXX"))); - const size_t length = strlen(templateName); + static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - char *XXXXXX = templateName + length - 6; + const int length = templateName.size(); - Q_ASSERT((length >= 6u) && strncmp(XXXXXX, "XXXXXX", 6) == 0); + QChar *XXXXXX = templateName.data() + length - 6; for (int i = 0; i < 256; ++i) { int v = qrand(); /* Fill in the random bits. */ - XXXXXX[0] = letters[nextRand(v)]; - XXXXXX[1] = letters[nextRand(v)]; - XXXXXX[2] = letters[nextRand(v)]; - XXXXXX[3] = letters[nextRand(v)]; - XXXXXX[4] = letters[nextRand(v)]; - XXXXXX[5] = letters[v % 62]; - - QString templateNameStr = QFile::decodeName(templateName); - - QFileSystemEntry fileSystemEntry(templateNameStr); + XXXXXX[0] = QLatin1Char(letters[nextRand(v)]); + XXXXXX[1] = QLatin1Char(letters[nextRand(v)]); + XXXXXX[2] = QLatin1Char(letters[nextRand(v)]); + XXXXXX[3] = QLatin1Char(letters[nextRand(v)]); + XXXXXX[4] = QLatin1Char(letters[nextRand(v)]); + XXXXXX[5] = QLatin1Char(letters[v % 62]); + + QFileSystemEntry fileSystemEntry(templateName); if (QFileSystemEngine::createDirectory(fileSystemEntry, false)) { QSystemError error; QFileSystemEngine::setPermissions(fileSystemEntry, @@ -141,10 +142,10 @@ QPair<QString, bool> q_mkdtemp(char *templateName) QFile::ExeOwner, error); if (error.error() != 0) { if (!QFileSystemEngine::removeDirectory(fileSystemEntry, false)) - qWarning() << "Unable to remove unused directory" << templateNameStr; + qWarning() << "Unable to remove unused directory" << templateName; continue; } - return qMakePair(QFile::decodeName(templateName), true); + return qMakePair(templateName, true); } # ifdef Q_OS_WIN const int exists = ERROR_ALREADY_EXISTS; @@ -159,7 +160,7 @@ QPair<QString, bool> q_mkdtemp(char *templateName) return qMakePair(qt_error_string(), false); } -#else // defined(Q_OS_QNX ) || defined(Q_OS_WIN) || defined(Q_OS_ANDROID) +#else // !USE_SYSTEM_MKDTEMP QPair<QString, bool> q_mkdtemp(char *templateName) { @@ -167,14 +168,21 @@ QPair<QString, bool> q_mkdtemp(char *templateName) return qMakePair(ok ? QFile::decodeName(templateName) : qt_error_string(), ok); } -#endif +#endif // USE_SYSTEM_MKDTEMP void QTemporaryDirPrivate::create(const QString &templateName) { +#ifndef USE_SYSTEM_MKDTEMP + QString buffer = templateName; + if (!buffer.endsWith(QLatin1String("XXXXXX"))) + buffer += QLatin1String("XXXXXX"); + const QPair<QString, bool> result = q_mkdtemp(buffer); +#else // !USE_SYSTEM_MKDTEMP QByteArray buffer = QFile::encodeName(templateName); if (!buffer.endsWith("XXXXXX")) buffer += "XXXXXX"; QPair<QString, bool> result = q_mkdtemp(buffer.data()); // modifies buffer +#endif // USE_SYSTEM_MKDTEMP pathOrError = result.first; success = result.second; } diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 9afbb84abf..802962d77d 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -421,7 +421,12 @@ void QEventDispatcherUNIX::unregisterSocketNotifier(QSocketNotifier *notifier) QSocketNotifier::Type type = notifier->type(); #ifndef QT_NO_DEBUG if (notifier->thread() != thread() || thread() != QThread::currentThread()) { - qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread"); + qWarning("QSocketNotifier: socket notifier (fd %d) cannot be disabled from another thread.\n" + "(Notifier's thread is %s(%p), event dispatcher's thread is %s(%p), current thread is %s(%p))", + sockfd, + notifier->thread() ? notifier->thread()->metaObject()->className() : "QThread", notifier->thread(), + thread() ? thread()->metaObject()->className() : "QThread", thread(), + QThread::currentThread() ? QThread::currentThread()->metaObject()->className() : "QThread", QThread::currentThread()); return; } #endif diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index 260b877291..41d55c8fde 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -476,7 +476,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(jobject obj) env->DeleteLocalRef(cls); } template <> -void QJNIObjectPrivate::callMethodV<void>(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT void QJNIObjectPrivate::callMethodV<void>(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); @@ -486,7 +486,7 @@ void QJNIObjectPrivate::callMethodV<void>(const char *methodName, const char *si } template <> -void QJNIObjectPrivate::callMethod<void>(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT void QJNIObjectPrivate::callMethod<void>(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -495,7 +495,7 @@ void QJNIObjectPrivate::callMethod<void>(const char *methodName, const char *sig } template <> -jboolean QJNIObjectPrivate::callMethodV<jboolean>(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callMethodV<jboolean>(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jboolean res = 0; @@ -507,7 +507,7 @@ jboolean QJNIObjectPrivate::callMethodV<jboolean>(const char *methodName, const } template <> -jboolean QJNIObjectPrivate::callMethod<jboolean>(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callMethod<jboolean>(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -517,7 +517,7 @@ jboolean QJNIObjectPrivate::callMethod<jboolean>(const char *methodName, const c } template <> -jbyte QJNIObjectPrivate::callMethodV<jbyte>(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callMethodV<jbyte>(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jbyte res = 0; @@ -529,7 +529,7 @@ jbyte QJNIObjectPrivate::callMethodV<jbyte>(const char *methodName, const char * } template <> -jbyte QJNIObjectPrivate::callMethod<jbyte>(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callMethod<jbyte>(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -539,7 +539,7 @@ jbyte QJNIObjectPrivate::callMethod<jbyte>(const char *methodName, const char *s } template <> -jchar QJNIObjectPrivate::callMethodV<jchar>(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jchar QJNIObjectPrivate::callMethodV<jchar>(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jchar res = 0; @@ -551,7 +551,7 @@ jchar QJNIObjectPrivate::callMethodV<jchar>(const char *methodName, const char * } template <> -jchar QJNIObjectPrivate::callMethod<jchar>(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jchar QJNIObjectPrivate::callMethod<jchar>(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -561,7 +561,7 @@ jchar QJNIObjectPrivate::callMethod<jchar>(const char *methodName, const char *s } template <> -jshort QJNIObjectPrivate::callMethodV<jshort>(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jshort QJNIObjectPrivate::callMethodV<jshort>(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jshort res = 0; @@ -573,7 +573,7 @@ jshort QJNIObjectPrivate::callMethodV<jshort>(const char *methodName, const char } template <> -jshort QJNIObjectPrivate::callMethod<jshort>(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jshort QJNIObjectPrivate::callMethod<jshort>(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -583,7 +583,7 @@ jshort QJNIObjectPrivate::callMethod<jshort>(const char *methodName, const char } template <> -jint QJNIObjectPrivate::callMethodV<jint>(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jint QJNIObjectPrivate::callMethodV<jint>(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jint res = 0; @@ -595,7 +595,7 @@ jint QJNIObjectPrivate::callMethodV<jint>(const char *methodName, const char *si } template <> -jint QJNIObjectPrivate::callMethod<jint>(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jint QJNIObjectPrivate::callMethod<jint>(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -605,7 +605,7 @@ jint QJNIObjectPrivate::callMethod<jint>(const char *methodName, const char *sig } template <> -jlong QJNIObjectPrivate::callMethodV<jlong>(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jlong QJNIObjectPrivate::callMethodV<jlong>(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jlong res = 0; @@ -617,7 +617,7 @@ jlong QJNIObjectPrivate::callMethodV<jlong>(const char *methodName, const char * } template <> -jlong QJNIObjectPrivate::callMethod<jlong>(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jlong QJNIObjectPrivate::callMethod<jlong>(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -627,7 +627,7 @@ jlong QJNIObjectPrivate::callMethod<jlong>(const char *methodName, const char *s } template <> -jfloat QJNIObjectPrivate::callMethodV<jfloat>(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callMethodV<jfloat>(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jfloat res = 0.f; @@ -639,7 +639,7 @@ jfloat QJNIObjectPrivate::callMethodV<jfloat>(const char *methodName, const char } template <> -jfloat QJNIObjectPrivate::callMethod<jfloat>(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callMethod<jfloat>(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -649,7 +649,7 @@ jfloat QJNIObjectPrivate::callMethod<jfloat>(const char *methodName, const char } template <> -jdouble QJNIObjectPrivate::callMethodV<jdouble>(const char *methodName, const char *sig, va_list args) const +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callMethodV<jdouble>(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; jdouble res = 0.; @@ -661,7 +661,7 @@ jdouble QJNIObjectPrivate::callMethodV<jdouble>(const char *methodName, const ch } template <> -jdouble QJNIObjectPrivate::callMethod<jdouble>(const char *methodName, const char *sig, ...) const +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callMethod<jdouble>(const char *methodName, const char *sig, ...) const { va_list args; va_start(args, sig); @@ -671,61 +671,61 @@ jdouble QJNIObjectPrivate::callMethod<jdouble>(const char *methodName, const cha } template <> -void QJNIObjectPrivate::callMethod<void>(const char *methodName) const +Q_CORE_EXPORT void QJNIObjectPrivate::callMethod<void>(const char *methodName) const { callMethod<void>(methodName, "()V"); } template <> -jboolean QJNIObjectPrivate::callMethod<jboolean>(const char *methodName) const +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callMethod<jboolean>(const char *methodName) const { return callMethod<jboolean>(methodName, "()Z"); } template <> -jbyte QJNIObjectPrivate::callMethod<jbyte>(const char *methodName) const +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callMethod<jbyte>(const char *methodName) const { return callMethod<jbyte>(methodName, "()B"); } template <> -jchar QJNIObjectPrivate::callMethod<jchar>(const char *methodName) const +Q_CORE_EXPORT jchar QJNIObjectPrivate::callMethod<jchar>(const char *methodName) const { return callMethod<jchar>(methodName, "()C"); } template <> -jshort QJNIObjectPrivate::callMethod<jshort>(const char *methodName) const +Q_CORE_EXPORT jshort QJNIObjectPrivate::callMethod<jshort>(const char *methodName) const { return callMethod<jshort>(methodName, "()S"); } template <> -jint QJNIObjectPrivate::callMethod<jint>(const char *methodName) const +Q_CORE_EXPORT jint QJNIObjectPrivate::callMethod<jint>(const char *methodName) const { return callMethod<jint>(methodName, "()I"); } template <> -jlong QJNIObjectPrivate::callMethod<jlong>(const char *methodName) const +Q_CORE_EXPORT jlong QJNIObjectPrivate::callMethod<jlong>(const char *methodName) const { return callMethod<jlong>(methodName, "()J"); } template <> -jfloat QJNIObjectPrivate::callMethod<jfloat>(const char *methodName) const +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callMethod<jfloat>(const char *methodName) const { return callMethod<jfloat>(methodName, "()F"); } template <> -jdouble QJNIObjectPrivate::callMethod<jdouble>(const char *methodName) const +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callMethod<jdouble>(const char *methodName) const { return callMethod<jdouble>(methodName, "()D"); } template <> -void QJNIObjectPrivate::callStaticMethodV<void>(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethodV<void>(const char *className, const char *methodName, const char *sig, va_list args) @@ -741,7 +741,7 @@ void QJNIObjectPrivate::callStaticMethodV<void>(const char *className, } template <> -void QJNIObjectPrivate::callStaticMethod<void>(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethod<void>(const char *className, const char *methodName, const char *sig, ...) @@ -753,7 +753,7 @@ void QJNIObjectPrivate::callStaticMethod<void>(const char *className, } template <> -void QJNIObjectPrivate::callStaticMethodV<void>(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethodV<void>(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -766,7 +766,7 @@ void QJNIObjectPrivate::callStaticMethodV<void>(jclass clazz, } template <> -void QJNIObjectPrivate::callStaticMethod<void>(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethod<void>(jclass clazz, const char *methodName, const char *sig, ...) @@ -778,7 +778,7 @@ void QJNIObjectPrivate::callStaticMethod<void>(jclass clazz, } template <> -jboolean QJNIObjectPrivate::callStaticMethodV<jboolean>(const char *className, +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethodV<jboolean>(const char *className, const char *methodName, const char *sig, va_list args) @@ -797,7 +797,7 @@ jboolean QJNIObjectPrivate::callStaticMethodV<jboolean>(const char *className, } template <> -jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(const char *className, +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(const char *className, const char *methodName, const char *sig, ...) @@ -810,7 +810,7 @@ jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(const char *className, } template <> -jboolean QJNIObjectPrivate::callStaticMethodV<jboolean>(jclass clazz, +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethodV<jboolean>(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -826,7 +826,7 @@ jboolean QJNIObjectPrivate::callStaticMethodV<jboolean>(jclass clazz, } template <> -jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(jclass clazz, +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(jclass clazz, const char *methodName, const char *sig, ...) @@ -839,7 +839,7 @@ jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(jclass clazz, } template <> -jbyte QJNIObjectPrivate::callStaticMethodV<jbyte>(const char *className, +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethodV<jbyte>(const char *className, const char *methodName, const char *sig, va_list args) @@ -858,7 +858,7 @@ jbyte QJNIObjectPrivate::callStaticMethodV<jbyte>(const char *className, } template <> -jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(const char *className, +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(const char *className, const char *methodName, const char *sig, ...) @@ -871,7 +871,7 @@ jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(const char *className, } template <> -jbyte QJNIObjectPrivate::callStaticMethodV<jbyte>(jclass clazz, +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethodV<jbyte>(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -887,7 +887,7 @@ jbyte QJNIObjectPrivate::callStaticMethodV<jbyte>(jclass clazz, } template <> -jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(jclass clazz, +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(jclass clazz, const char *methodName, const char *sig, ...) @@ -900,7 +900,7 @@ jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(jclass clazz, } template <> -jchar QJNIObjectPrivate::callStaticMethodV<jchar>(const char *className, +Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethodV<jchar>(const char *className, const char *methodName, const char *sig, va_list args) @@ -919,7 +919,7 @@ jchar QJNIObjectPrivate::callStaticMethodV<jchar>(const char *className, } template <> -jchar QJNIObjectPrivate::callStaticMethod<jchar>(const char *className, +Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethod<jchar>(const char *className, const char *methodName, const char *sig, ...) @@ -932,7 +932,7 @@ jchar QJNIObjectPrivate::callStaticMethod<jchar>(const char *className, } template <> -jchar QJNIObjectPrivate::callStaticMethodV<jchar>(jclass clazz, +Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethodV<jchar>(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -948,7 +948,7 @@ jchar QJNIObjectPrivate::callStaticMethodV<jchar>(jclass clazz, } template <> -jchar QJNIObjectPrivate::callStaticMethod<jchar>(jclass clazz, +Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethod<jchar>(jclass clazz, const char *methodName, const char *sig, ...) @@ -961,7 +961,7 @@ jchar QJNIObjectPrivate::callStaticMethod<jchar>(jclass clazz, } template <> -jshort QJNIObjectPrivate::callStaticMethodV<jshort>(const char *className, +Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethodV<jshort>(const char *className, const char *methodName, const char *sig, va_list args) @@ -980,7 +980,7 @@ jshort QJNIObjectPrivate::callStaticMethodV<jshort>(const char *className, } template <> -jshort QJNIObjectPrivate::callStaticMethod<jshort>(const char *className, +Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethod<jshort>(const char *className, const char *methodName, const char *sig, ...) @@ -993,7 +993,7 @@ jshort QJNIObjectPrivate::callStaticMethod<jshort>(const char *className, } template <> -jshort QJNIObjectPrivate::callStaticMethodV<jshort>(jclass clazz, +Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethodV<jshort>(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -1009,7 +1009,7 @@ jshort QJNIObjectPrivate::callStaticMethodV<jshort>(jclass clazz, } template <> -jshort QJNIObjectPrivate::callStaticMethod<jshort>(jclass clazz, +Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethod<jshort>(jclass clazz, const char *methodName, const char *sig, ...) @@ -1022,7 +1022,7 @@ jshort QJNIObjectPrivate::callStaticMethod<jshort>(jclass clazz, } template <> -jint QJNIObjectPrivate::callStaticMethodV<jint>(const char *className, +Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethodV<jint>(const char *className, const char *methodName, const char *sig, va_list args) @@ -1041,7 +1041,7 @@ jint QJNIObjectPrivate::callStaticMethodV<jint>(const char *className, } template <> -jint QJNIObjectPrivate::callStaticMethod<jint>(const char *className, +Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethod<jint>(const char *className, const char *methodName, const char *sig, ...) @@ -1054,7 +1054,7 @@ jint QJNIObjectPrivate::callStaticMethod<jint>(const char *className, } template <> -jint QJNIObjectPrivate::callStaticMethodV<jint>(jclass clazz, +Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethodV<jint>(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -1070,7 +1070,7 @@ jint QJNIObjectPrivate::callStaticMethodV<jint>(jclass clazz, } template <> -jint QJNIObjectPrivate::callStaticMethod<jint>(jclass clazz, +Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethod<jint>(jclass clazz, const char *methodName, const char *sig, ...) @@ -1083,7 +1083,7 @@ jint QJNIObjectPrivate::callStaticMethod<jint>(jclass clazz, } template <> -jlong QJNIObjectPrivate::callStaticMethodV<jlong>(const char *className, +Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethodV<jlong>(const char *className, const char *methodName, const char *sig, va_list args) @@ -1102,7 +1102,7 @@ jlong QJNIObjectPrivate::callStaticMethodV<jlong>(const char *className, } template <> -jlong QJNIObjectPrivate::callStaticMethod<jlong>(const char *className, +Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethod<jlong>(const char *className, const char *methodName, const char *sig, ...) @@ -1115,7 +1115,7 @@ jlong QJNIObjectPrivate::callStaticMethod<jlong>(const char *className, } template <> -jlong QJNIObjectPrivate::callStaticMethodV<jlong>(jclass clazz, +Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethodV<jlong>(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -1131,7 +1131,7 @@ jlong QJNIObjectPrivate::callStaticMethodV<jlong>(jclass clazz, } template <> -jlong QJNIObjectPrivate::callStaticMethod<jlong>(jclass clazz, +Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethod<jlong>(jclass clazz, const char *methodName, const char *sig, ...) @@ -1144,7 +1144,7 @@ jlong QJNIObjectPrivate::callStaticMethod<jlong>(jclass clazz, } template <> -jfloat QJNIObjectPrivate::callStaticMethodV<jfloat>(const char *className, +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethodV<jfloat>(const char *className, const char *methodName, const char *sig, va_list args) @@ -1163,7 +1163,7 @@ jfloat QJNIObjectPrivate::callStaticMethodV<jfloat>(const char *className, } template <> -jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(const char *className, +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(const char *className, const char *methodName, const char *sig, ...) @@ -1176,7 +1176,7 @@ jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(const char *className, } template <> -jfloat QJNIObjectPrivate::callStaticMethodV<jfloat>(jclass clazz, +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethodV<jfloat>(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -1192,7 +1192,7 @@ jfloat QJNIObjectPrivate::callStaticMethodV<jfloat>(jclass clazz, } template <> -jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(jclass clazz, +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(jclass clazz, const char *methodName, const char *sig, ...) @@ -1205,7 +1205,7 @@ jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(jclass clazz, } template <> -jdouble QJNIObjectPrivate::callStaticMethodV<jdouble>(const char *className, +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethodV<jdouble>(const char *className, const char *methodName, const char *sig, va_list args) @@ -1224,7 +1224,7 @@ jdouble QJNIObjectPrivate::callStaticMethodV<jdouble>(const char *className, } template <> -jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(const char *className, +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(const char *className, const char *methodName, const char *sig, ...) @@ -1237,7 +1237,7 @@ jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(const char *className, } template <> -jdouble QJNIObjectPrivate::callStaticMethodV<jdouble>(jclass clazz, +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethodV<jdouble>(jclass clazz, const char *methodName, const char *sig, va_list args) @@ -1253,7 +1253,7 @@ jdouble QJNIObjectPrivate::callStaticMethodV<jdouble>(jclass clazz, } template <> -jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(jclass clazz, +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(jclass clazz, const char *methodName, const char *sig, ...) @@ -1266,109 +1266,109 @@ jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(jclass clazz, } template <> -void QJNIObjectPrivate::callStaticMethod<void>(const char *className, const char *methodName) +Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethod<void>(const char *className, const char *methodName) { callStaticMethod<void>(className, methodName, "()V"); } template <> -void QJNIObjectPrivate::callStaticMethod<void>(jclass clazz, const char *methodName) +Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethod<void>(jclass clazz, const char *methodName) { callStaticMethod<void>(clazz, methodName, "()V"); } template <> -jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(const char *className, const char *methodName) +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(const char *className, const char *methodName) { return callStaticMethod<jboolean>(className, methodName, "()Z"); } template <> -jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(jclass clazz, const char *methodName) +Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(jclass clazz, const char *methodName) { return callStaticMethod<jboolean>(clazz, methodName, "()Z"); } template <> -jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(const char *className, const char *methodName) +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(const char *className, const char *methodName) { return callStaticMethod<jbyte>(className, methodName, "()B"); } template <> -jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(jclass clazz, const char *methodName) +Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(jclass clazz, const char *methodName) { return callStaticMethod<jbyte>(clazz, methodName, "()B"); } template <> -jchar QJNIObjectPrivate::callStaticMethod<jchar>(const char *className, const char *methodName) +Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethod<jchar>(const char *className, const char *methodName) { return callStaticMethod<jchar>(className, methodName, "()C"); } template <> -jchar QJNIObjectPrivate::callStaticMethod<jchar>(jclass clazz, const char *methodName) +Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethod<jchar>(jclass clazz, const char *methodName) { return callStaticMethod<jchar>(clazz, methodName, "()C"); } template <> -jshort QJNIObjectPrivate::callStaticMethod<jshort>(const char *className, const char *methodName) +Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethod<jshort>(const char *className, const char *methodName) { return callStaticMethod<jshort>(className, methodName, "()S"); } template <> -jshort QJNIObjectPrivate::callStaticMethod<jshort>(jclass clazz, const char *methodName) +Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethod<jshort>(jclass clazz, const char *methodName) { return callStaticMethod<jshort>(clazz, methodName, "()S"); } template <> -jint QJNIObjectPrivate::callStaticMethod<jint>(const char *className, const char *methodName) +Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethod<jint>(const char *className, const char *methodName) { return callStaticMethod<jint>(className, methodName, "()I"); } template <> -jint QJNIObjectPrivate::callStaticMethod<jint>(jclass clazz, const char *methodName) +Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethod<jint>(jclass clazz, const char *methodName) { return callStaticMethod<jint>(clazz, methodName, "()I"); } template <> -jlong QJNIObjectPrivate::callStaticMethod<jlong>(const char *className, const char *methodName) +Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethod<jlong>(const char *className, const char *methodName) { return callStaticMethod<jlong>(className, methodName, "()J"); } template <> -jlong QJNIObjectPrivate::callStaticMethod<jlong>(jclass clazz, const char *methodName) +Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethod<jlong>(jclass clazz, const char *methodName) { return callStaticMethod<jlong>(clazz, methodName, "()J"); } template <> -jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(const char *className, const char *methodName) +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(const char *className, const char *methodName) { return callStaticMethod<jfloat>(className, methodName, "()F"); } template <> -jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(jclass clazz, const char *methodName) +Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(jclass clazz, const char *methodName) { return callStaticMethod<jfloat>(clazz, methodName, "()F"); } template <> -jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(const char *className, const char *methodName) +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(const char *className, const char *methodName) { return callStaticMethod<jdouble>(className, methodName, "()D"); } template <> -jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(jclass clazz, const char *methodName) +Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(jclass clazz, const char *methodName) { return callStaticMethod<jdouble>(clazz, methodName, "()D"); } @@ -1403,49 +1403,49 @@ QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName, } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jstring>(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jstring>(const char *methodName) const { return callObjectMethod(methodName, "()Ljava/lang/String;"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jbooleanArray>(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jbooleanArray>(const char *methodName) const { return callObjectMethod(methodName, "()[Z"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jbyteArray>(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jbyteArray>(const char *methodName) const { return callObjectMethod(methodName, "()[B"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jshortArray>(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jshortArray>(const char *methodName) const { return callObjectMethod(methodName, "()[S"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jintArray>(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jintArray>(const char *methodName) const { return callObjectMethod(methodName, "()[I"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jlongArray>(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jlongArray>(const char *methodName) const { return callObjectMethod(methodName, "()[J"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jfloatArray>(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jfloatArray>(const char *methodName) const { return callObjectMethod(methodName, "()[F"); } template <> -QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jdoubleArray>(const char *methodName) const +Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jdoubleArray>(const char *methodName) const { return callObjectMethod(methodName, "()[D"); } @@ -1516,7 +1516,7 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(jclass clazz, } template <> -jboolean QJNIObjectPrivate::getField<jboolean>(const char *fieldName) const +Q_CORE_EXPORT jboolean QJNIObjectPrivate::getField<jboolean>(const char *fieldName) const { QJNIEnvironmentPrivate env; jboolean res = 0; @@ -1528,7 +1528,7 @@ jboolean QJNIObjectPrivate::getField<jboolean>(const char *fieldName) const } template <> -jbyte QJNIObjectPrivate::getField<jbyte>(const char *fieldName) const +Q_CORE_EXPORT jbyte QJNIObjectPrivate::getField<jbyte>(const char *fieldName) const { QJNIEnvironmentPrivate env; jbyte res = 0; @@ -1540,7 +1540,7 @@ jbyte QJNIObjectPrivate::getField<jbyte>(const char *fieldName) const } template <> -jchar QJNIObjectPrivate::getField<jchar>(const char *fieldName) const +Q_CORE_EXPORT jchar QJNIObjectPrivate::getField<jchar>(const char *fieldName) const { QJNIEnvironmentPrivate env; jchar res = 0; @@ -1552,7 +1552,7 @@ jchar QJNIObjectPrivate::getField<jchar>(const char *fieldName) const } template <> -jshort QJNIObjectPrivate::getField<jshort>(const char *fieldName) const +Q_CORE_EXPORT jshort QJNIObjectPrivate::getField<jshort>(const char *fieldName) const { QJNIEnvironmentPrivate env; jshort res = 0; @@ -1564,7 +1564,7 @@ jshort QJNIObjectPrivate::getField<jshort>(const char *fieldName) const } template <> -jint QJNIObjectPrivate::getField<jint>(const char *fieldName) const +Q_CORE_EXPORT jint QJNIObjectPrivate::getField<jint>(const char *fieldName) const { QJNIEnvironmentPrivate env; jint res = 0; @@ -1576,7 +1576,7 @@ jint QJNIObjectPrivate::getField<jint>(const char *fieldName) const } template <> -jlong QJNIObjectPrivate::getField<jlong>(const char *fieldName) const +Q_CORE_EXPORT jlong QJNIObjectPrivate::getField<jlong>(const char *fieldName) const { QJNIEnvironmentPrivate env; jlong res = 0; @@ -1588,7 +1588,7 @@ jlong QJNIObjectPrivate::getField<jlong>(const char *fieldName) const } template <> -jfloat QJNIObjectPrivate::getField<jfloat>(const char *fieldName) const +Q_CORE_EXPORT jfloat QJNIObjectPrivate::getField<jfloat>(const char *fieldName) const { QJNIEnvironmentPrivate env; jfloat res = 0.f; @@ -1600,7 +1600,7 @@ jfloat QJNIObjectPrivate::getField<jfloat>(const char *fieldName) const } template <> -jdouble QJNIObjectPrivate::getField<jdouble>(const char *fieldName) const +Q_CORE_EXPORT jdouble QJNIObjectPrivate::getField<jdouble>(const char *fieldName) const { QJNIEnvironmentPrivate env; jdouble res = 0.; @@ -1612,7 +1612,7 @@ jdouble QJNIObjectPrivate::getField<jdouble>(const char *fieldName) const } template <> -jboolean QJNIObjectPrivate::getStaticField<jboolean>(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jboolean QJNIObjectPrivate::getStaticField<jboolean>(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jboolean res = 0; @@ -1624,7 +1624,7 @@ jboolean QJNIObjectPrivate::getStaticField<jboolean>(jclass clazz, const char *f } template <> -jboolean QJNIObjectPrivate::getStaticField<jboolean>(const char *className, const char *fieldName) +Q_CORE_EXPORT jboolean QJNIObjectPrivate::getStaticField<jboolean>(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1639,7 +1639,7 @@ jboolean QJNIObjectPrivate::getStaticField<jboolean>(const char *className, cons } template <> -jbyte QJNIObjectPrivate::getStaticField<jbyte>(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jbyte QJNIObjectPrivate::getStaticField<jbyte>(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jbyte res = 0; @@ -1651,7 +1651,7 @@ jbyte QJNIObjectPrivate::getStaticField<jbyte>(jclass clazz, const char *fieldNa } template <> -jbyte QJNIObjectPrivate::getStaticField<jbyte>(const char *className, const char *fieldName) +Q_CORE_EXPORT jbyte QJNIObjectPrivate::getStaticField<jbyte>(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1666,7 +1666,7 @@ jbyte QJNIObjectPrivate::getStaticField<jbyte>(const char *className, const char } template <> -jchar QJNIObjectPrivate::getStaticField<jchar>(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jchar QJNIObjectPrivate::getStaticField<jchar>(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jchar res = 0; @@ -1678,7 +1678,7 @@ jchar QJNIObjectPrivate::getStaticField<jchar>(jclass clazz, const char *fieldNa } template <> -jchar QJNIObjectPrivate::getStaticField<jchar>(const char *className, const char *fieldName) +Q_CORE_EXPORT jchar QJNIObjectPrivate::getStaticField<jchar>(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1693,7 +1693,7 @@ jchar QJNIObjectPrivate::getStaticField<jchar>(const char *className, const char } template <> -jshort QJNIObjectPrivate::getStaticField<jshort>(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jshort QJNIObjectPrivate::getStaticField<jshort>(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jshort res = 0; @@ -1705,7 +1705,7 @@ jshort QJNIObjectPrivate::getStaticField<jshort>(jclass clazz, const char *field } template <> -jshort QJNIObjectPrivate::getStaticField<jshort>(const char *className, const char *fieldName) +Q_CORE_EXPORT jshort QJNIObjectPrivate::getStaticField<jshort>(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1720,7 +1720,7 @@ jshort QJNIObjectPrivate::getStaticField<jshort>(const char *className, const ch } template <> -jint QJNIObjectPrivate::getStaticField<jint>(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jint QJNIObjectPrivate::getStaticField<jint>(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jint res = 0; @@ -1732,7 +1732,7 @@ jint QJNIObjectPrivate::getStaticField<jint>(jclass clazz, const char *fieldName } template <> -jint QJNIObjectPrivate::getStaticField<jint>(const char *className, const char *fieldName) +Q_CORE_EXPORT jint QJNIObjectPrivate::getStaticField<jint>(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1747,7 +1747,7 @@ jint QJNIObjectPrivate::getStaticField<jint>(const char *className, const char * } template <> -jlong QJNIObjectPrivate::getStaticField<jlong>(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jlong QJNIObjectPrivate::getStaticField<jlong>(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jlong res = 0; @@ -1759,7 +1759,7 @@ jlong QJNIObjectPrivate::getStaticField<jlong>(jclass clazz, const char *fieldNa } template <> -jlong QJNIObjectPrivate::getStaticField<jlong>(const char *className, const char *fieldName) +Q_CORE_EXPORT jlong QJNIObjectPrivate::getStaticField<jlong>(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1774,7 +1774,7 @@ jlong QJNIObjectPrivate::getStaticField<jlong>(const char *className, const char } template <> -jfloat QJNIObjectPrivate::getStaticField<jfloat>(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jfloat QJNIObjectPrivate::getStaticField<jfloat>(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jfloat res = 0.f; @@ -1786,7 +1786,7 @@ jfloat QJNIObjectPrivate::getStaticField<jfloat>(jclass clazz, const char *field } template <> -jfloat QJNIObjectPrivate::getStaticField<jfloat>(const char *className, const char *fieldName) +Q_CORE_EXPORT jfloat QJNIObjectPrivate::getStaticField<jfloat>(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1801,7 +1801,7 @@ jfloat QJNIObjectPrivate::getStaticField<jfloat>(const char *className, const ch } template <> -jdouble QJNIObjectPrivate::getStaticField<jdouble>(jclass clazz, const char *fieldName) +Q_CORE_EXPORT jdouble QJNIObjectPrivate::getStaticField<jdouble>(jclass clazz, const char *fieldName) { QJNIEnvironmentPrivate env; jdouble res = 0.; @@ -1813,7 +1813,7 @@ jdouble QJNIObjectPrivate::getStaticField<jdouble>(jclass clazz, const char *fie } template <> -jdouble QJNIObjectPrivate::getStaticField<jdouble>(const char *className, const char *fieldName) +Q_CORE_EXPORT jdouble QJNIObjectPrivate::getStaticField<jdouble>(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); @@ -1885,7 +1885,7 @@ QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(jclass clazz, } template <> -void QJNIObjectPrivate::setField<jboolean>(const char *fieldName, jboolean value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jboolean>(const char *fieldName, jboolean value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Z"); @@ -1895,7 +1895,7 @@ void QJNIObjectPrivate::setField<jboolean>(const char *fieldName, jboolean value } template <> -void QJNIObjectPrivate::setField<jbyte>(const char *fieldName, jbyte value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jbyte>(const char *fieldName, jbyte value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "B"); @@ -1905,7 +1905,7 @@ void QJNIObjectPrivate::setField<jbyte>(const char *fieldName, jbyte value) } template <> -void QJNIObjectPrivate::setField<jchar>(const char *fieldName, jchar value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jchar>(const char *fieldName, jchar value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "C"); @@ -1915,7 +1915,7 @@ void QJNIObjectPrivate::setField<jchar>(const char *fieldName, jchar value) } template <> -void QJNIObjectPrivate::setField<jshort>(const char *fieldName, jshort value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jshort>(const char *fieldName, jshort value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "S"); @@ -1925,7 +1925,7 @@ void QJNIObjectPrivate::setField<jshort>(const char *fieldName, jshort value) } template <> -void QJNIObjectPrivate::setField<jint>(const char *fieldName, jint value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jint>(const char *fieldName, jint value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "I"); @@ -1935,7 +1935,7 @@ void QJNIObjectPrivate::setField<jint>(const char *fieldName, jint value) } template <> -void QJNIObjectPrivate::setField<jlong>(const char *fieldName, jlong value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jlong>(const char *fieldName, jlong value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "J"); @@ -1945,7 +1945,7 @@ void QJNIObjectPrivate::setField<jlong>(const char *fieldName, jlong value) } template <> -void QJNIObjectPrivate::setField<jfloat>(const char *fieldName, jfloat value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jfloat>(const char *fieldName, jfloat value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "F"); @@ -1955,7 +1955,7 @@ void QJNIObjectPrivate::setField<jfloat>(const char *fieldName, jfloat value) } template <> -void QJNIObjectPrivate::setField<jdouble>(const char *fieldName, jdouble value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jdouble>(const char *fieldName, jdouble value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "D"); @@ -1965,7 +1965,7 @@ void QJNIObjectPrivate::setField<jdouble>(const char *fieldName, jdouble value) } template <> -void QJNIObjectPrivate::setField<jbooleanArray>(const char *fieldName, jbooleanArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jbooleanArray>(const char *fieldName, jbooleanArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[Z"); @@ -1975,7 +1975,7 @@ void QJNIObjectPrivate::setField<jbooleanArray>(const char *fieldName, jbooleanA } template <> -void QJNIObjectPrivate::setField<jbyteArray>(const char *fieldName, jbyteArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jbyteArray>(const char *fieldName, jbyteArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[B"); @@ -1985,7 +1985,7 @@ void QJNIObjectPrivate::setField<jbyteArray>(const char *fieldName, jbyteArray v } template <> -void QJNIObjectPrivate::setField<jcharArray>(const char *fieldName, jcharArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jcharArray>(const char *fieldName, jcharArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[C"); @@ -1995,7 +1995,7 @@ void QJNIObjectPrivate::setField<jcharArray>(const char *fieldName, jcharArray v } template <> -void QJNIObjectPrivate::setField<jshortArray>(const char *fieldName, jshortArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jshortArray>(const char *fieldName, jshortArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[S"); @@ -2005,7 +2005,7 @@ void QJNIObjectPrivate::setField<jshortArray>(const char *fieldName, jshortArray } template <> -void QJNIObjectPrivate::setField<jintArray>(const char *fieldName, jintArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jintArray>(const char *fieldName, jintArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[I"); @@ -2015,7 +2015,7 @@ void QJNIObjectPrivate::setField<jintArray>(const char *fieldName, jintArray val } template <> -void QJNIObjectPrivate::setField<jlongArray>(const char *fieldName, jlongArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jlongArray>(const char *fieldName, jlongArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[J"); @@ -2025,7 +2025,7 @@ void QJNIObjectPrivate::setField<jlongArray>(const char *fieldName, jlongArray v } template <> -void QJNIObjectPrivate::setField<jfloatArray>(const char *fieldName, jfloatArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jfloatArray>(const char *fieldName, jfloatArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[F"); @@ -2035,7 +2035,7 @@ void QJNIObjectPrivate::setField<jfloatArray>(const char *fieldName, jfloatArray } template <> -void QJNIObjectPrivate::setField<jdoubleArray>(const char *fieldName, jdoubleArray value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jdoubleArray>(const char *fieldName, jdoubleArray value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[D"); @@ -2045,7 +2045,7 @@ void QJNIObjectPrivate::setField<jdoubleArray>(const char *fieldName, jdoubleArr } template <> -void QJNIObjectPrivate::setField<jstring>(const char *fieldName, jstring value) +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jstring>(const char *fieldName, jstring value) { QJNIEnvironmentPrivate env; jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Ljava/lang/String;"); @@ -2055,7 +2055,7 @@ void QJNIObjectPrivate::setField<jstring>(const char *fieldName, jstring value) } template <> -void QJNIObjectPrivate::setField<jobject>(const char *fieldName, +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jobject>(const char *fieldName, const char *sig, jobject value) { @@ -2067,7 +2067,7 @@ void QJNIObjectPrivate::setField<jobject>(const char *fieldName, } template <> -void QJNIObjectPrivate::setField<jobjectArray>(const char *fieldName, +Q_CORE_EXPORT void QJNIObjectPrivate::setField<jobjectArray>(const char *fieldName, const char *sig, jobjectArray value) { @@ -2079,7 +2079,7 @@ void QJNIObjectPrivate::setField<jobjectArray>(const char *fieldName, } template <> -void QJNIObjectPrivate::setStaticField<jboolean>(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jboolean>(jclass clazz, const char *fieldName, jboolean value) { @@ -2090,7 +2090,7 @@ void QJNIObjectPrivate::setStaticField<jboolean>(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField<jboolean>(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jboolean>(const char *className, const char *fieldName, jboolean value) { @@ -2107,7 +2107,7 @@ void QJNIObjectPrivate::setStaticField<jboolean>(const char *className, } template <> -void QJNIObjectPrivate::setStaticField<jbyte>(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jbyte>(jclass clazz, const char *fieldName, jbyte value) { @@ -2118,7 +2118,7 @@ void QJNIObjectPrivate::setStaticField<jbyte>(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField<jbyte>(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jbyte>(const char *className, const char *fieldName, jbyte value) { @@ -2135,7 +2135,7 @@ void QJNIObjectPrivate::setStaticField<jbyte>(const char *className, } template <> -void QJNIObjectPrivate::setStaticField<jchar>(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jchar>(jclass clazz, const char *fieldName, jchar value) { @@ -2146,7 +2146,7 @@ void QJNIObjectPrivate::setStaticField<jchar>(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField<jchar>(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jchar>(const char *className, const char *fieldName, jchar value) { @@ -2163,7 +2163,7 @@ void QJNIObjectPrivate::setStaticField<jchar>(const char *className, } template <> -void QJNIObjectPrivate::setStaticField<jshort>(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jshort>(jclass clazz, const char *fieldName, jshort value) { @@ -2174,7 +2174,7 @@ void QJNIObjectPrivate::setStaticField<jshort>(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField<jshort>(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jshort>(const char *className, const char *fieldName, jshort value) { @@ -2191,7 +2191,7 @@ void QJNIObjectPrivate::setStaticField<jshort>(const char *className, } template <> -void QJNIObjectPrivate::setStaticField<jint>(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jint>(jclass clazz, const char *fieldName, jint value) { @@ -2202,7 +2202,7 @@ void QJNIObjectPrivate::setStaticField<jint>(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField<jint>(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jint>(const char *className, const char *fieldName, jint value) { @@ -2219,7 +2219,7 @@ void QJNIObjectPrivate::setStaticField<jint>(const char *className, } template <> -void QJNIObjectPrivate::setStaticField<jlong>(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jlong>(jclass clazz, const char *fieldName, jlong value) { @@ -2230,7 +2230,7 @@ void QJNIObjectPrivate::setStaticField<jlong>(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField<jlong>(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jlong>(const char *className, const char *fieldName, jlong value) { @@ -2247,7 +2247,7 @@ void QJNIObjectPrivate::setStaticField<jlong>(const char *className, } template <> -void QJNIObjectPrivate::setStaticField<jfloat>(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jfloat>(jclass clazz, const char *fieldName, jfloat value) { @@ -2258,7 +2258,7 @@ void QJNIObjectPrivate::setStaticField<jfloat>(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField<jfloat>(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jfloat>(const char *className, const char *fieldName, jfloat value) { @@ -2275,7 +2275,7 @@ void QJNIObjectPrivate::setStaticField<jfloat>(const char *className, } template <> -void QJNIObjectPrivate::setStaticField<jdouble>(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jdouble>(jclass clazz, const char *fieldName, jdouble value) { @@ -2286,7 +2286,7 @@ void QJNIObjectPrivate::setStaticField<jdouble>(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField<jdouble>(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jdouble>(const char *className, const char *fieldName, jdouble value) { @@ -2303,7 +2303,7 @@ void QJNIObjectPrivate::setStaticField<jdouble>(const char *className, } template <> -void QJNIObjectPrivate::setStaticField<jobject>(jclass clazz, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jobject>(jclass clazz, const char *fieldName, const char *sig, jobject value) @@ -2315,7 +2315,7 @@ void QJNIObjectPrivate::setStaticField<jobject>(jclass clazz, } template <> -void QJNIObjectPrivate::setStaticField<jobject>(const char *className, +Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jobject>(const char *className, const char *fieldName, const char *sig, jobject value) diff --git a/src/corelib/kernel/qjnionload.cpp b/src/corelib/kernel/qjnionload.cpp index f80da36240..c936bf42fd 100644 --- a/src/corelib/kernel/qjnionload.cpp +++ b/src/corelib/kernel/qjnionload.cpp @@ -44,6 +44,11 @@ Q_CORE_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { Q_UNUSED(reserved) + static bool initialized = false; + if (initialized) + return JNI_VERSION_1_6; + initialized = true; + typedef union { JNIEnv *nenv; void *venv; diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index c0ebf273fa..c846aada05 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -3693,7 +3693,6 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i continue; #ifndef QT_NO_THREAD } else if (c->connectionType == Qt::BlockingQueuedConnection) { - locker.unlock(); if (receiverInSameThread) { qWarning("Qt: Dead lock detected while activating a BlockingQueuedConnection: " "Sender is %s(%p), receiver is %s(%p)", @@ -3705,6 +3704,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i new QMetaCallEvent(c->slotObj, sender, signal_index, 0, 0, argv ? argv : empty_argv, &semaphore) : new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal_index, 0, 0, argv ? argv : empty_argv, &semaphore); QCoreApplication::postEvent(receiver, ev); + locker.unlock(); semaphore.acquire(); locker.relock(); continue; @@ -4272,7 +4272,7 @@ QDebug operator<<(QDebug dbg, const QObject *o) \relates QObject \since 5.5 - This macro registers a single \l{QFlags}{flags types} with the + This macro registers a single \l{QFlags}{flags type} with the meta-object system. It is typically used in a class definition to declare that values of a given enum can be used as flags and combined using the bitwise OR operator. diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index f8bebdf617..3660d1c0e1 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -180,6 +180,8 @@ inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {} #if defined(Q_CC_CLANG) && Q_CC_CLANG >= 306 # define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override") +#elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 510 +# define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_GCC("-Wsuggest-override") #else # define Q_OBJECT_NO_OVERRIDE_WARNING #endif diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 886dd20d0e..93a901d614 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -536,8 +536,13 @@ bool QLibraryPrivate::load() return false; bool ret = load_sys(); - if (qt_debug_component()) - qDebug() << "loaded library" << fileName; + if (qt_debug_component()) { + if (ret) { + qDebug() << "loaded library" << fileName; + } else { + qDebug() << qUtf8Printable(errorString); + } + } if (ret) { //when loading a library we add a reference to it so that the QLibraryPrivate won't get deleted //this allows to unload the library at a later time diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index ec0eaa1edf..ebf9b45570 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -123,8 +123,8 @@ QT_DEPRECATED inline bool setYMD(int y, int m, int d) static bool isValid(int y, int m, int d); static bool isLeapYear(int year); - static Q_DECL_CONSTEXPR inline QDate fromJulianDay(qint64 jd) - { return jd >= minJd() && jd <= maxJd() ? QDate(jd) : QDate() ; } + static Q_DECL_CONSTEXPR inline QDate fromJulianDay(qint64 jd_) + { return jd_ >= minJd() && jd_ <= maxJd() ? QDate(jd_) : QDate() ; } Q_DECL_CONSTEXPR inline qint64 toJulianDay() const { return jd; } private: diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 0f769ffa86..7ce12bc244 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -499,14 +499,14 @@ private: void deref() Q_DECL_NOTHROW { deref(d); } - static void deref(Data *d) Q_DECL_NOTHROW + static void deref(Data *dd) Q_DECL_NOTHROW { - if (!d) return; - if (!d->strongref.deref()) { - d->destroy(); + if (!dd) return; + if (!dd->strongref.deref()) { + dd->destroy(); } - if (!d->weakref.deref()) - delete d; + if (!dd->weakref.deref()) + delete dd; } template <class X> diff --git a/src/corelib/tools/qtimezoneprivate.cpp b/src/corelib/tools/qtimezoneprivate.cpp index 763d12b702..56da197542 100644 --- a/src/corelib/tools/qtimezoneprivate.cpp +++ b/src/corelib/tools/qtimezoneprivate.cpp @@ -656,10 +656,11 @@ QTimeZonePrivate *QUtcTimeZonePrivate::clone() QTimeZonePrivate::Data QUtcTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const { - Data d = invalidData(); + Data d; d.abbreviation = m_abbreviation; d.atMSecsSinceEpoch = forMSecsSinceEpoch; - d.offsetFromUtc = m_offsetFromUtc; + d.standardTimeOffset = d.offsetFromUtc = m_offsetFromUtc; + d.daylightTimeOffset = 0; return d; } diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp index c2630c8593..6e717f2233 100644 --- a/src/corelib/tools/qtimezoneprivate_tz.cpp +++ b/src/corelib/tools/qtimezoneprivate_tz.cpp @@ -907,7 +907,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const { // If the required time is after the last transition and we have a POSIX rule then use it if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch - &&!m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) { + && !m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) { const int year = QDateTime::fromMSecsSinceEpoch(forMSecsSinceEpoch, Qt::UTC).date().year(); const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0; QVector<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, @@ -951,7 +951,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSince { // If the required time is after the last transition and we have a POSIX rule then use it if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch - &&!m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) { + && !m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) { const int year = QDateTime::fromMSecsSinceEpoch(afterMSecsSinceEpoch, Qt::UTC).date().year(); const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0; QVector<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, @@ -977,7 +977,7 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecs { // If the required time is after the last transition and we have a POSIX rule then use it if (m_tranTimes.size() > 0 && m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch - &&!m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) { + && !m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) { const int year = QDateTime::fromMSecsSinceEpoch(beforeMSecsSinceEpoch, Qt::UTC).date().year(); const int lastMSecs = (m_tranTimes.size() > 0) ? m_tranTimes.last().atMSecsSinceEpoch : 0; QVector<QTimeZonePrivate::Data> posixTrans = calculatePosixTransitions(m_posixRule, year - 1, diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index b68ca87063..4dbf95c315 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -397,7 +397,11 @@ void QVector<T>::reserve(int asize) { if (asize > int(d->alloc)) reallocData(d->size, asize); - if (isDetached()) + if (isDetached() +#if !defined(QT_NO_UNSHARABLE_CONTAINERS) + && d != Data::unsharableEmpty() +#endif + ) d->capacityReserved = 1; Q_ASSERT(capacity() >= asize); } diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index 3949d2c3ac..83b26d50ab 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -1181,6 +1181,10 @@ inline int QXmlStreamReaderPrivate::fastScanLiteralContent() } // fall through default: + if (c < 0x20) { + putChar(c); + return n; + } textBuffer += QChar(c); ++n; } diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 3abfac1575..bd32ca7bee 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -840,17 +840,6 @@ QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QIm d->cleanupFunction = cleanupFunction; d->cleanupInfo = cleanupInfo; - switch (format) { - case QImage::Format_Mono: - case QImage::Format_MonoLSB: - d->colortable.resize(2); - d->colortable[0] = QColor(Qt::black).rgba(); - d->colortable[1] = QColor(Qt::white).rgba(); - break; - default: - break; - } - return d; } @@ -2249,21 +2238,30 @@ QRgb QImage::pixel(int x, int y) const } const uchar *s = d->data + y * d->bytes_per_line; - switch(d->format) { + + int index = -1; + switch (d->format) { case Format_Mono: - return d->colortable.at((*(s + (x >> 3)) >> (~x & 7)) & 1); + index = (*(s + (x >> 3)) >> (~x & 7)) & 1; + break; case Format_MonoLSB: - return d->colortable.at((*(s + (x >> 3)) >> (x & 7)) & 1); + index = (*(s + (x >> 3)) >> (x & 7)) & 1; + break; case Format_Indexed8: - { - int index = (int)s[x]; - if (index < d->colortable.size()) { - return d->colortable.at(index); - } else { - qWarning("QImage::pixel: color table index %d out of range.", index); - return 0; - } + index = s[x]; + break; + default: + break; + } + if (index >= 0) { // Indexed format + if (index >= d->colortable.size()) { + qWarning("QImage::pixel: color table index %d out of range.", index); + return 0; } + return d->colortable.at(index); + } + + switch (d->format) { case Format_RGB32: return 0xff000000 | reinterpret_cast<const QRgb *>(s)[x]; case Format_ARGB32: // Keep old behaviour. @@ -4250,6 +4248,8 @@ void QImage::setAlphaChannel(const QImage &alphaChannel) } else { const QImage sourceImage = alphaChannel.convertToFormat(QImage::Format_RGB32); + if (sourceImage.isNull()) + return; const uchar *src_data = sourceImage.d->data; uchar *dest_data = d->data; for (int y=0; y<h; ++y) { diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 4ab8160f21..a360debf5b 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1410,10 +1410,8 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) QPixmap using the fromImage(). If this is too expensive an operation, you can use QBitmap::fromImage() instead. - The QPixmap class also supports conversion to and from HICON: - the toWinHICON() function creates a HICON equivalent to the - QPixmap, and returns the HICON handle. The fromWinHICON() - function returns a QPixmap that is equivalent to the given icon. + To convert a QPixmap to and from HICON you can use the QtWinExtras + functions QtWin::toHICON() and QtWin::fromHICON() respectively. \section1 Pixmap Transformations diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index fb72c561ab..93374b2299 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -537,8 +537,8 @@ public: }; class Attribute { public: - Attribute(AttributeType t, int s, int l, QVariant val) : type(t), start(s), length(l), value(qMove(val)) {} - Attribute(AttributeType t, int s, int l) : type(t), start(s), length(l), value() {} + Attribute(AttributeType typ, int s, int l, QVariant val) : type(typ), start(s), length(l), value(qMove(val)) {} + Attribute(AttributeType typ, int s, int l) : type(typ), start(s), length(l), value() {} AttributeType type; int start; diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index e45a1d61ba..bcd3e830dd 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -581,6 +581,20 @@ void QPlatformWindow::invalidateSurface() { } +static QSize fixInitialSize(QSize size, const QWindow *w, + int defaultWidth, int defaultHeight) +{ + if (size.width() == 0) { + const int minWidth = w->minimumWidth(); + size.setWidth(minWidth > 0 ? minWidth : defaultWidth); + } + if (size.height() == 0) { + const int minHeight = w->minimumHeight(); + size.setHeight(minHeight > 0 ? minHeight : defaultHeight); + } + return size; +} + /*! Helper function to get initial geometry on windowing systems which do not do smart positioning and also do not provide a means of centering a @@ -593,19 +607,18 @@ void QPlatformWindow::invalidateSurface() QRect QPlatformWindow::initialGeometry(const QWindow *w, const QRect &initialGeometry, int defaultWidth, int defaultHeight) { + if (!w->isTopLevel()) { + const qreal factor = QHighDpiScaling::factor(w); + const QSize size = fixInitialSize(QHighDpi::fromNative(initialGeometry.size(), factor), + w, defaultWidth, defaultHeight); + return QRect(initialGeometry.topLeft(), QHighDpi::toNative(size, factor)); + } const QScreen *screen = effectiveScreen(w); if (!screen) return initialGeometry; QRect rect(QHighDpi::fromNativePixels(initialGeometry, w)); - if (rect.width() == 0) { - const int minWidth = w->minimumWidth(); - rect.setWidth(minWidth > 0 ? minWidth : defaultWidth); - } - if (rect.height() == 0) { - const int minHeight = w->minimumHeight(); - rect.setHeight(minHeight > 0 ? minHeight : defaultHeight); - } - if (w->isTopLevel() && qt_window_private(const_cast<QWindow*>(w))->positionAutomatic + rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight)); + if (qt_window_private(const_cast<QWindow*>(w))->positionAutomatic && w->type() != Qt::Popup) { const QRect availableGeometry = screen->availableGeometry(); // Center unless the geometry ( + unknown window frame) is too large for the screen). diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index fa26fd77a3..f061a2bf50 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -402,7 +402,7 @@ void QWindowPrivate::create(bool recursive) q->parent()->create(); platformWindow = QGuiApplicationPrivate::platformIntegration()->createPlatformWindow(q); - Q_ASSERT(platformWindow); + Q_ASSERT(platformWindow || q->type() == Qt::ForeignWindow); if (!platformWindow) { qWarning() << "Failed to create platform window for" << q << "with flags" << q->flags(); @@ -2432,7 +2432,8 @@ QWindow *QWindowPrivate::topLevelWindow() const This can be used, on platforms which support it, to embed a QWindow inside a native window, or to embed a native window inside a QWindow. - If foreign windows are not supported, this function returns 0. + If foreign windows are not supported or embedding the native window + failed in the platform plugin, this function returns 0. \note The resulting QWindow should not be used to manipulate the underlying native window (besides re-parenting), or to observe state changes of the @@ -2453,6 +2454,10 @@ QWindow *QWindow::fromWinId(WId id) window->setFlags(Qt::ForeignWindow); window->setProperty("_q_foreignWinId", QVariant::fromValue(id)); window->create(); + if (!window->handle()) { + delete window; + return nullptr; + } return window; } diff --git a/src/gui/opengl/qopengldebug.cpp b/src/gui/opengl/qopengldebug.cpp index 24aa6094dd..f6c3af37dd 100644 --- a/src/gui/opengl/qopengldebug.cpp +++ b/src/gui/opengl/qopengldebug.cpp @@ -42,6 +42,7 @@ #include <QtCore/qvarlengtharray.h> #include <QtGui/qopengl.h> #include <QtGui/qopenglfunctions.h> +#include <QtGui/qoffscreensurface.h> #include "qopengldebug.h" @@ -1287,8 +1288,41 @@ void QOpenGLDebugLoggerPrivate::controlDebugMessages(QOpenGLDebugMessage::Source */ void QOpenGLDebugLoggerPrivate::_q_contextAboutToBeDestroyed() { + Q_ASSERT(context); + + // Re-make our context current somehow, otherwise stopLogging will fail. + + // Save the current context and its surface in case we need to set them back + QOpenGLContext *currentContext = QOpenGLContext::currentContext(); + QSurface *currentSurface = 0; + + QScopedPointer<QOffscreenSurface> offscreenSurface; + + if (context != currentContext) { + // Make our old context current on a temporary surface + if (currentContext) + currentSurface = currentContext->surface(); + + offscreenSurface.reset(new QOffscreenSurface); + offscreenSurface->setFormat(context->format()); + offscreenSurface->create(); + if (!context->makeCurrent(offscreenSurface.data())) + qWarning("QOpenGLDebugLoggerPrivate::_q_contextAboutToBeDestroyed(): could not make the owning GL context current for cleanup"); + } + Q_Q(QOpenGLDebugLogger); q->stopLogging(); + + if (offscreenSurface) { + // We did change the current context: set it back + if (currentContext) + currentContext->makeCurrent(currentSurface); + else + context->doneCurrent(); + } + + QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed())); + context = 0; initialized = false; } @@ -1494,6 +1528,12 @@ void QOpenGLDebugLogger::stopLogging() if (!d->isLogging) return; + QOpenGLContext *currentContext = QOpenGLContext::currentContext(); + if (!currentContext || currentContext != d->context) { + qWarning("QOpenGLDebugLogger::stopLogging(): attempting to stop logging with the wrong OpenGL context current"); + return; + } + d->isLogging = false; d->glDebugMessageCallback(d->oldDebugCallbackFunction, d->oldDebugCallbackParameter); diff --git a/src/gui/opengl/qopengltexturehelper_p.h b/src/gui/opengl/qopengltexturehelper_p.h index 77049dced3..00f6f9e5aa 100644 --- a/src/gui/opengl/qopengltexturehelper_p.h +++ b/src/gui/opengl/qopengltexturehelper_p.h @@ -76,6 +76,14 @@ QT_BEGIN_NAMESPACE #define GL_TEXTURE_COMPARE_FUNC 0x884D #endif +// use GL_APICALL only on Android + __clang__ +#if !defined(Q_OS_ANDROID) || !defined(__clang__) +# undef GL_APICALL +# define GL_APICALL +#elif !defined(GL_APICALL) +# define GL_APICALL +#endif + class QOpenGLContext; class QOpenGLTextureHelper @@ -754,15 +762,15 @@ private: // OpenGL 1.3 void (QOPENGLF_APIENTRYP GetCompressedTexImage)(GLenum target, GLint level, GLvoid *img); void (QOPENGLF_APIENTRYP CompressedTexSubImage1D)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); + GL_APICALL void (QOPENGLF_APIENTRYP CompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); void (QOPENGLF_APIENTRYP CompressedTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); void (QOPENGLF_APIENTRYP CompressedTexImage1D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP CompressedTexImage2D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); + GL_APICALL void (QOPENGLF_APIENTRYP CompressedTexImage2D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); void (QOPENGLF_APIENTRYP CompressedTexImage3D)(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); - void (QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture); + GL_APICALL void (QOPENGLF_APIENTRYP ActiveTexture)(GLenum texture); // OpenGL 3.0 - void (QOPENGLF_APIENTRYP GenerateMipmap)(GLenum target); + GL_APICALL void (QOPENGLF_APIENTRYP GenerateMipmap)(GLenum target); // OpenGL 3.2 void (QOPENGLF_APIENTRYP TexImage3DMultisample)(GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp index 6753064a60..babe52aa83 100644 --- a/src/gui/opengl/qopenglvertexarrayobject.cpp +++ b/src/gui/opengl/qopenglvertexarrayobject.cpp @@ -358,9 +358,11 @@ QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() Q_D(QOpenGLVertexArrayObject); QOpenGLContext *oldContext = 0; + QSurface *oldContextSurface = 0; QScopedPointer<QOffscreenSurface> offscreenSurface; if (d->context && ctx && d->context != ctx) { oldContext = ctx; + oldContextSurface = ctx->surface(); // Cannot just make the current surface current again with another context. // The format may be incompatible and some platforms (iOS) may impose // restrictions on using a window with different contexts. Create an @@ -380,7 +382,7 @@ QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() destroy(); if (oldContext) { - if (!oldContext->makeCurrent(oldContext->surface())) + if (!oldContext->makeCurrent(oldContextSurface)) qWarning("QOpenGLVertexArrayObject::~QOpenGLVertexArrayObject() failed to restore current context"); } } diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 801397751b..e3d18512dd 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -236,11 +236,16 @@ QSize QBackingStore::size() const */ bool QBackingStore::scroll(const QRegion &area, int dx, int dy) { - Q_UNUSED(area); - Q_UNUSED(dx); - Q_UNUSED(dy); - - return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window), QHighDpi::toNativePixels(dx, d_ptr->window), QHighDpi::toNativePixels(dy, d_ptr->window)); + // Disable scrolling for non-integer scroll deltas. For this case + // the the existing rendered pixels can't be re-used, and we return + // false to signal that a repaint is needed. + const qreal nativeDx = QHighDpi::toNativePixels(qreal(dx), d_ptr->window); + const qreal nativeDy = QHighDpi::toNativePixels(qreal(dy), d_ptr->window); + if (qFloor(nativeDx) != nativeDx || qFloor(nativeDy) != nativeDy) + return false; + + return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window), + nativeDx, nativeDy); } /*! diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 828dbc318c..12631b3a73 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -76,7 +76,9 @@ QT_BEGIN_NAMESPACE - +#ifndef QFONTCACHE_DECREASE_TRIGGER_LIMIT +# define QFONTCACHE_DECREASE_TRIGGER_LIMIT 256 +#endif bool QFontDef::exactMatch(const QFontDef &other) const { @@ -2800,7 +2802,7 @@ void QFontCache::insertEngineData(const QFontDef &def, QFontEngineData *engineDa engineData->ref.ref(); // Decrease now rather than waiting - if (total_cost > min_cost * 2) + if (total_cost > min_cost * 2 && engineDataCache.size() >= QFONTCACHE_DECREASE_TRIGGER_LIMIT) decreaseCache(); engineDataCache.insert(def, engineData); @@ -2849,7 +2851,7 @@ void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMu #endif engine->ref.ref(); // Decrease now rather than waiting - if (total_cost > min_cost * 2) + if (total_cost > min_cost * 2 && engineCache.size() >= QFONTCACHE_DECREASE_TRIGGER_LIMIT) decreaseCache(); Engine data(engine); diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 26ed81a091..51b1418bc3 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1849,7 +1849,10 @@ static inline QImage alphaMapFromGlyphData(QFontEngineFT::Glyph *glyph, QFontEng Q_UNREACHABLE(); }; - return QImage(static_cast<const uchar *>(glyph->data), glyph->width, glyph->height, bytesPerLine, format); + QImage img(static_cast<const uchar *>(glyph->data), glyph->width, glyph->height, bytesPerLine, format); + if (format == QImage::Format_Mono) + img.setColor(1, QColor(Qt::white).rgba()); // Expands color table to 2 items; item 0 set to transparent. + return img; } QImage *QFontEngineFT::lockedAlphaMapForGlyph(glyph_t glyphIndex, QFixed subPixelPosition, diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 0615cd1cb3..fbc7088a02 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -2657,9 +2657,8 @@ void QAbstractSocket::setPeerName(const QString &name) } /*! - Closes the I/O device for the socket, disconnects the socket's connection with the - host, closes the socket, and resets the name, address, port number and underlying - socket descriptor. + Closes the I/O device for the socket and calls disconnectFromHost() + to close the socket's connection. See QIODevice::close() for a description of the actions that occur when an I/O device is closed. @@ -2675,13 +2674,6 @@ void QAbstractSocket::close() QIODevice::close(); if (d->state != UnconnectedState) disconnectFromHost(); - - d->localPort = 0; - d->peerPort = 0; - d->localAddress.clear(); - d->peerAddress.clear(); - d->peerName.clear(); - d->cachedSocketDescriptor = -1; } /*! @@ -2784,6 +2776,7 @@ void QAbstractSocket::disconnectFromHost() d->peerPort = 0; d->localAddress.clear(); d->peerAddress.clear(); + d->peerName.clear(); d->setWriteChannelCount(0); #if defined(QABSTRACTSOCKET_DEBUG) diff --git a/src/platformsupport/fbconvenience/qfbvthandler.cpp b/src/platformsupport/fbconvenience/qfbvthandler.cpp index 2e5d00c8bd..4c4a01a82e 100644 --- a/src/platformsupport/fbconvenience/qfbvthandler.cpp +++ b/src/platformsupport/fbconvenience/qfbvthandler.cpp @@ -116,14 +116,16 @@ QFbVtHandler::QFbVtHandler(QObject *parent) m_signalNotifier = new QSocketNotifier(m_sigFd[1], QSocketNotifier::Read, this); connect(m_signalNotifier, &QSocketNotifier::activated, this, &QFbVtHandler::handleSignal); - struct sigaction sa; - sa.sa_flags = 0; - sa.sa_handler = signalHandler; - sigemptyset(&sa.sa_mask); - sigaction(SIGINT, &sa, 0); // Ctrl+C - sigaction(SIGTSTP, &sa, 0); // Ctrl+Z - sigaction(SIGCONT, &sa, 0); - sigaction(SIGTERM, &sa, 0); // default signal used by kill + if (!qEnvironmentVariableIntValue("QT_QPA_NO_SIGNAL_HANDLER")) { + struct sigaction sa; + sa.sa_flags = 0; + sa.sa_handler = signalHandler; + sigemptyset(&sa.sa_mask); + sigaction(SIGINT, &sa, 0); // Ctrl+C + sigaction(SIGTSTP, &sa, 0); // Ctrl+Z + sigaction(SIGCONT, &sa, 0); + sigaction(SIGTERM, &sa, 0); // default signal used by kill + } #endif } diff --git a/src/plugins/bearer/connman/qconnmanengine.cpp b/src/plugins/bearer/connman/qconnmanengine.cpp index 3f42f8828a..51ee51a64a 100644 --- a/src/plugins/bearer/connman/qconnmanengine.cpp +++ b/src/plugins/bearer/connman/qconnmanengine.cpp @@ -91,7 +91,7 @@ void QConnmanEngine::initialize() this, SLOT(updateServices(ConnmanMapList,QList<QDBusObjectPath>))); connect(connmanManager,SIGNAL(servicesReady(QStringList)),this,SLOT(servicesReady(QStringList))); - connect(connmanManager,SIGNAL(scanFinished()),this,SLOT(finishedScan())); + connect(connmanManager,SIGNAL(scanFinished(bool)),this,SLOT(finishedScan(bool))); foreach (const QString &servPath, connmanManager->getServices()) { addServiceConfiguration(servPath); @@ -203,11 +203,15 @@ void QConnmanEngine::requestUpdate() void QConnmanEngine::doRequestUpdate() { - connmanManager->requestScan("wifi"); + bool scanned = connmanManager->requestScan("wifi"); + if (!scanned) + Q_EMIT updateCompleted(); } -void QConnmanEngine::finishedScan() +void QConnmanEngine::finishedScan(bool error) { + if (error) + Q_EMIT updateCompleted(); } void QConnmanEngine::updateServices(const ConnmanMapList &changed, const QList<QDBusObjectPath> &removed) diff --git a/src/plugins/bearer/connman/qconnmanengine.h b/src/plugins/bearer/connman/qconnmanengine.h index 3827ea167f..23c158ac34 100644 --- a/src/plugins/bearer/connman/qconnmanengine.h +++ b/src/plugins/bearer/connman/qconnmanengine.h @@ -100,7 +100,7 @@ private Q_SLOTS: void updateServices(const ConnmanMapList &changed, const QList<QDBusObjectPath> &removed); void servicesReady(const QStringList &); - void finishedScan(); + void finishedScan(bool error); void changedModem(); void serviceStateChanged(const QString &state); void configurationChange(QConnmanServiceInterface * service); diff --git a/src/plugins/bearer/connman/qconnmanservice_linux.cpp b/src/plugins/bearer/connman/qconnmanservice_linux.cpp index 135aad4dec..7fbbe2cd07 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux.cpp +++ b/src/plugins/bearer/connman/qconnmanservice_linux.cpp @@ -249,13 +249,16 @@ QStringList QConnmanManagerInterface::getServices() return servicesList; } -void QConnmanManagerInterface::requestScan(const QString &type) +bool QConnmanManagerInterface::requestScan(const QString &type) { + bool scanned = false; Q_FOREACH (QConnmanTechnologyInterface *tech, technologiesMap) { if (tech->type() == type) { tech->scan(); + scanned = true; } } + return scanned; } void QConnmanManagerInterface::technologyAdded(const QDBusObjectPath &path, const QVariantMap &) @@ -265,7 +268,7 @@ void QConnmanManagerInterface::technologyAdded(const QDBusObjectPath &path, cons QConnmanTechnologyInterface *tech; tech = new QConnmanTechnologyInterface(path.path(),this); technologiesMap.insert(path.path(),tech); - connect(tech,SIGNAL(scanFinished()),this,SIGNAL(scanFinished())); + connect(tech,SIGNAL(scanFinished(bool)),this,SIGNAL(scanFinished(bool))); } } @@ -501,7 +504,11 @@ void QConnmanTechnologyInterface::scan() void QConnmanTechnologyInterface::scanReply(QDBusPendingCallWatcher *call) { - Q_EMIT scanFinished(); + QDBusPendingReply<QVariantMap> props_reply = *call; + if (props_reply.isError()) { + qDebug() << props_reply.error().message(); + } + Q_EMIT scanFinished(props_reply.isError()); call->deleteLater(); } diff --git a/src/plugins/bearer/connman/qconnmanservice_linux_p.h b/src/plugins/bearer/connman/qconnmanservice_linux_p.h index 0e774d50c3..d2804ebca6 100644 --- a/src/plugins/bearer/connman/qconnmanservice_linux_p.h +++ b/src/plugins/bearer/connman/qconnmanservice_linux_p.h @@ -115,7 +115,7 @@ public: bool getOfflineMode(); QStringList getTechnologies(); QStringList getServices(); - void requestScan(const QString &type); + bool requestScan(const QString &type); QHash<QString, QConnmanTechnologyInterface *> technologiesMap; @@ -126,7 +126,7 @@ Q_SIGNALS: void servicesChanged(const ConnmanMapList&, const QList<QDBusObjectPath> &); void servicesReady(const QStringList &); - void scanFinished(); + void scanFinished(bool error); protected: void connectNotify(const QMetaMethod &signal); @@ -211,7 +211,7 @@ public: Q_SIGNALS: void propertyChanged(const QString &, const QDBusVariant &value); void propertyChangedContext(const QString &,const QString &,const QDBusVariant &); - void scanFinished(); + void scanFinished(bool error); protected: void connectNotify(const QMetaMethod &signal); QVariant getProperty(const QString &); diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 52f34166eb..6419ba2c51 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -840,6 +840,11 @@ QT_END_NAMESPACE Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/) { + static bool initialized = false; + if (initialized) + return JNI_VERSION_1_6; + initialized = true; + QT_USE_NAMESPACE typedef union { JNIEnv *nativeEnvironment; diff --git a/src/plugins/platforms/cocoa/qmacclipboard.h b/src/plugins/platforms/cocoa/qmacclipboard.h index a4b5cf00d6..a3abacf849 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.h +++ b/src/plugins/platforms/cocoa/qmacclipboard.h @@ -75,6 +75,7 @@ private: uchar mime_type; mutable QPointer<QMimeData> mime; mutable bool mac_mime_source; + bool resolvingBeforeDestruction; static OSStatus promiseKeeper(PasteboardRef, PasteboardItemID, CFStringRef, void *); void clear_helper(); public: diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm index 70d1170edb..721b0fb4d1 100644 --- a/src/plugins/platforms/cocoa/qmacclipboard.mm +++ b/src/plugins/platforms/cocoa/qmacclipboard.mm @@ -87,6 +87,7 @@ QMacPasteboard::QMacPasteboard(PasteboardRef p, uchar mt) mime_type = mt ? mt : uchar(QMacInternalPasteboardMime::MIME_ALL); paste = p; CFRetain(paste); + resolvingBeforeDestruction = false; } QMacPasteboard::QMacPasteboard(uchar mt) @@ -100,6 +101,7 @@ QMacPasteboard::QMacPasteboard(uchar mt) } else { qDebug("PasteBoard: Error creating pasteboard: [%d]", (int)err); } + resolvingBeforeDestruction = false; } QMacPasteboard::QMacPasteboard(CFStringRef name, uchar mt) @@ -113,23 +115,14 @@ QMacPasteboard::QMacPasteboard(CFStringRef name, uchar mt) } else { qDebug("PasteBoard: Error creating pasteboard: %s [%d]", QCFString::toQString(name).toLatin1().constData(), (int)err); } + resolvingBeforeDestruction = false; } QMacPasteboard::~QMacPasteboard() { // commit all promises for paste after exit close - for (int i = 0; i < promises.count(); ++i) { - const Promise &promise = promises.at(i); - // At this point app teardown has started and control is somewhere in the Q[Core]Application - // destructor. Skip "lazy" promises where the application has not provided data; - // the application will generally not be in a state to provide it. - if (promise.dataRequestType == LazyRequest) - continue; - QCFString flavor = QCFString(promise.convertor->flavorFor(promise.mime)); - NSInteger pbItemId = promise.itemId; - promiseKeeper(paste, reinterpret_cast<PasteboardItemID>(pbItemId), flavor, this); - } - + resolvingBeforeDestruction = true; + PasteboardResolvePromises(paste); if (paste) CFRelease(paste); } @@ -181,7 +174,7 @@ OSStatus QMacPasteboard::promiseKeeper(PasteboardRef paste, PasteboardItemID id, // to request the data from the application. QVariant promiseData; if (promise.dataRequestType == LazyRequest) { - if (!promise.mimeData.isNull()) + if (!qpaste->resolvingBeforeDestruction && !promise.mimeData.isNull()) promiseData = promise.mimeData->variantData(promise.mime); } else { promiseData = promise.variantData; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index a72cbd010a..500049a504 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -1625,12 +1625,18 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent) const bool accepted = [self handleKeyEvent:nsevent eventType:int(QEvent::KeyPress)]; - // Track keyDown acceptance state for later acceptance of the keyUp. - if (accepted) + // When Qt is used to implement a plugin for a native application we + // want to propagate unhandled events to other native views. However, + // Qt does not always set the accepted state correctly (in particular + // for return key events), so do this for plugin applications only + // to prevent incorrect forwarding in the general case. + const bool shouldPropagate = QCoreApplication::testAttribute(Qt::AA_PluginApplication) && !accepted; + + // Track keyDown acceptance/forward state for later acceptance of the keyUp. + if (!shouldPropagate) m_acceptedKeyDowns.insert([nsevent keyCode]); - // Propagate the keyDown to the next responder if Qt did not accept it. - if (!accepted) + if (shouldPropagate) [super keyDown:nsevent]; } diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 5b8cc7893a..90aa3fef16 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -302,7 +302,12 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons } if (window->type() == Qt::ForeignWindow) { - QWindowsForeignWindow *result = new QWindowsForeignWindow(window, reinterpret_cast<HWND>(window->winId())); + const HWND hwnd = reinterpret_cast<HWND>(window->winId()); + if (!IsWindow(hwnd)) { + qWarning("Windows QPA: Invalid foreign window ID %p."); + return nullptr; + } + QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd); const QRect obtainedGeometry = result->geometry(); QScreen *screen = Q_NULLPTR; if (const QPlatformScreen *pScreen = result->screenForGeometry(obtainedGeometry)) diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index e84033f5e4..2c3ffd45d9 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -389,8 +389,13 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const return QVariant(booleanSystemParametersInfo(SPI_GETSNAPTODEFBUTTON, false)); case ContextMenuOnMouseRelease: return QVariant(true); - case WheelScrollLines: - return QVariant(int(dWordSystemParametersInfo(SPI_GETWHEELSCROLLLINES, 3))); + case WheelScrollLines: { + int result = 3; + const DWORD scrollLines = dWordSystemParametersInfo(SPI_GETWHEELSCROLLLINES, DWORD(result)); + if (scrollLines != DWORD(-1)) // Special value meaning "scroll one screen", unimplemented in Qt. + result = int(scrollLines); + return QVariant(result); + } default: break; } diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 29f0af4621..7289f8de6d 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1504,7 +1504,7 @@ void QWindowsWindow::handleGeometryChange() QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen()); } if (testFlag(SynchronousGeometryChangeEvent)) - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); qCDebug(lcQpaEvents) << __FUNCTION__ << this << window() << m_data.geometry; } @@ -1596,7 +1596,7 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, // Our tests depend on it. fireExpose(QRegion(qrectFromRECT(ps.rcPaint)), true); if (!QWindowsContext::instance()->asyncExpose()) - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); EndPaint(hwnd, &ps); return true; @@ -1656,7 +1656,7 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state) switch (state) { case Qt::WindowMinimized: handleHidden(); - QWindowSystemInterface::flushWindowSystemEvents(); // Tell QQuickWindow to stop rendering now. + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); // Tell QQuickWindow to stop rendering now. break; case Qt::WindowMaximized: case Qt::WindowFullScreen: @@ -1679,7 +1679,7 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state) } } if (exposeEventsSent && !QWindowsContext::instance()->asyncExpose()) - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); } break; default: @@ -1769,7 +1769,7 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState) if (!wasSync) clearFlag(SynchronousGeometryChangeEvent); QWindowSystemInterface::handleGeometryChange(window(), r); - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); } else if (newState != Qt::WindowMinimized) { // Restore saved state. unsigned newStyle = m_savedStyle ? m_savedStyle : style(); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index c5cc2cd790..10c8c8a2d8 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2195,8 +2195,11 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in const bool isWheel = detail >= 4 && detail <= 7; if (!isWheel && window() != QGuiApplication::focusWindow()) { QWindow *w = static_cast<QWindowPrivate *>(QObjectPrivate::get(window()))->eventReceiver(); - if (!(w->flags() & Qt::WindowDoesNotAcceptFocus)) + if (!(w->flags() & (Qt::WindowDoesNotAcceptFocus | Qt::BypassWindowManagerHint)) + && w->type() != Qt::ToolTip + && w->type() != Qt::Popup) { w->requestActivate(); + } } updateNetWmUserTime(timestamp); diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc index fc8f3b747e..624c314f6c 100644 --- a/src/testlib/doc/src/qttestlib-manual.qdoc +++ b/src/testlib/doc/src/qttestlib-manual.qdoc @@ -254,7 +254,7 @@ \li \c -nocrashhandler \br Disables the crash handler on Unix platforms. On Windows, it re-enables the Windows Error Reporting dialog, which is - turned off by default. + turned off by default. This is useful for debugging crashes. \li \c -platform \e name \br This command line argument applies to all Qt applications, but might be diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index cfa7d1b8ca..05d1592a60 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -485,7 +485,7 @@ Q_TESTLIB_EXPORT void qtest_qParseArgs(int argc, char *argv[], bool qml) " -mousedelay ms : Set default delay for mouse simulation to ms milliseconds\n" " -maxwarnings n : Sets the maximum amount of messages to output.\n" " 0 means unlimited, default: 2000\n" - " -nocrashhandler : Disables the crash handler\n" + " -nocrashhandler : Disables the crash handler. Useful for debugging crashes.\n" "\n" " Benchmarking options:\n" #ifdef QTESTLIB_USE_VALGRIND diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index f2efcadad7..87fb1318f9 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Olivier Goffart <ogoffart@woboq.com> ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the tools applications of the Qt Toolkit. @@ -179,6 +180,8 @@ Type Moc::parseType() case Q_SLOT_TOKEN: type.name += lexem(); return type; + case NOTOKEN: + return type; default: prev(); break; @@ -213,6 +216,8 @@ Type Moc::parseType() type.name += lexem(); isVoid |= (lookup(0) == VOID); break; + case NOTOKEN: + return type; default: prev(); ; diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index 464a1e139e..8dfcf2c6d6 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -849,8 +849,10 @@ void QDialog::adjustPosition(QWidget* w) // QTBUG-52735: Manually set the correct target screen since scaling in a // subsequent call to QWindow::resize() may otherwise use the wrong factor // if the screen changed notification is still in an event queue. - if (QWindow *window = windowHandle()) - window->setScreen(QGuiApplication::screens().at(scrn)); + if (scrn >= 0) { + if (QWindow *window = windowHandle()) + window->setScreen(QGuiApplication::screens().at(scrn)); + } move(p); } diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp index 6ed019f4a8..5e3b74f7b7 100644 --- a/src/widgets/itemviews/qabstractitemdelegate.cpp +++ b/src/widgets/itemviews/qabstractitemdelegate.cpp @@ -376,6 +376,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event, const QStyleOptionViewItem &option, const QModelIndex &index) { + Q_D(QAbstractItemDelegate); Q_UNUSED(option); if (!event || !view) @@ -384,9 +385,10 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event, #ifndef QT_NO_TOOLTIP case QEvent::ToolTip: { QHelpEvent *he = static_cast<QHelpEvent*>(event); - QVariant tooltip = index.data(Qt::ToolTipRole); - if (tooltip.canConvert<QString>()) { - QToolTip::showText(he->globalPos(), tooltip.toString(), view); + const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp + const QString tooltip = d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision); + if (!tooltip.isEmpty()) { + QToolTip::showText(he->globalPos(), tooltip, view); return true; } break;} @@ -398,9 +400,10 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event, break; } case QEvent::WhatsThis: { QHelpEvent *he = static_cast<QHelpEvent*>(event); - QVariant whatsthis = index.data(Qt::WhatsThisRole); - if (whatsthis.canConvert<QString>()) { - QWhatsThis::showText(he->globalPos(), whatsthis.toString(), view); + const int precision = inherits("QItemDelegate") ? 10 : 6; // keep in sync with DBL_DIG in qitemdelegate.cpp + const QString whatsthis = d->textForRole(Qt::WhatsThisRole, index.data(Qt::WhatsThisRole), option.locale, precision); + if (!whatsthis.isEmpty()) { + QWhatsThis::showText(he->globalPos(), whatsthis, view); return true; } break ; } @@ -543,6 +546,46 @@ bool QAbstractItemDelegatePrivate::tryFixup(QWidget *editor) return true; } +QString QAbstractItemDelegatePrivate::textForRole(Qt::ItemDataRole role, const QVariant &value, const QLocale &locale, int precision) const +{ + const QLocale::FormatType formatType = (role == Qt::DisplayRole) ? QLocale::ShortFormat : QLocale::LongFormat; + QString text; + switch (value.userType()) { + case QMetaType::Float: + text = locale.toString(value.toFloat()); + break; + case QVariant::Double: + text = locale.toString(value.toDouble(), 'g', precision); + break; + case QVariant::Int: + case QVariant::LongLong: + text = locale.toString(value.toLongLong()); + break; + case QVariant::UInt: + case QVariant::ULongLong: + text = locale.toString(value.toULongLong()); + break; + case QVariant::Date: + text = locale.toString(value.toDate(), formatType); + break; + case QVariant::Time: + text = locale.toString(value.toTime(), formatType); + break; + case QVariant::DateTime: { + const QDateTime dateTime = value.toDateTime(); + text = locale.toString(dateTime.date(), formatType) + + QLatin1Char(' ') + + locale.toString(dateTime.time(), formatType); + break; } + default: + text = value.toString(); + if (role == Qt::DisplayRole) + text.replace(QLatin1Char('\n'), QChar::LineSeparator); + break; + } + return text; +} + void QAbstractItemDelegatePrivate::_q_commitDataAndCloseEditor(QWidget *editor) { Q_Q(QAbstractItemDelegate); diff --git a/src/widgets/itemviews/qabstractitemdelegate_p.h b/src/widgets/itemviews/qabstractitemdelegate_p.h index 04d929a0ac..0b03be63f0 100644 --- a/src/widgets/itemviews/qabstractitemdelegate_p.h +++ b/src/widgets/itemviews/qabstractitemdelegate_p.h @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE -class QAbstractItemDelegatePrivate : public QObjectPrivate +class Q_AUTOTEST_EXPORT QAbstractItemDelegatePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QAbstractItemDelegate) public: @@ -67,6 +67,7 @@ public: bool editorEventFilter(QObject *object, QEvent *event); bool tryFixup(QWidget *editor); + QString textForRole(Qt::ItemDataRole role, const QVariant &value, const QLocale &locale, int precision = 6) const; void _q_commitDataAndCloseEditor(QWidget *editor); }; diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 4768c58d1d..221511f38d 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -4325,6 +4325,12 @@ const QEditorInfo & QAbstractItemViewPrivate::editorForIndex(const QModelIndex & return it.value(); } +bool QAbstractItemViewPrivate::hasEditor(const QModelIndex &index) const +{ + // Search's implicit cast (QModelIndex to QPersistentModelIndex) is slow; use cheap pre-test to avoid when we can. + return !indexEditorHash.isEmpty() && indexEditorHash.contains(index); +} + QModelIndex QAbstractItemViewPrivate::indexForEditor(QWidget *editor) const { // do not try to search to avoid slow implicit cast from QModelIndex to QPersistentModelIndex diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h index 3877969f87..f8ada6df08 100644 --- a/src/widgets/itemviews/qabstractitemview_p.h +++ b/src/widgets/itemviews/qabstractitemview_p.h @@ -277,10 +277,7 @@ public: } const QEditorInfo &editorForIndex(const QModelIndex &index) const; - inline bool hasEditor(const QModelIndex &index) const { - // Search's implicit cast (QModelIndex to QPersistentModelIndex) is slow; use cheap pre-test to avoid when we can. - return !indexEditorHash.isEmpty() && indexEditorHash.contains(index); - } + bool hasEditor(const QModelIndex &index) const; QModelIndex indexForEditor(QWidget *editor) const; void addEditor(const QModelIndex &index, QWidget *editor, bool isStatic); diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp index 194bd22493..747d5db782 100644 --- a/src/widgets/itemviews/qitemdelegate.cpp +++ b/src/widgets/itemviews/qitemdelegate.cpp @@ -67,6 +67,7 @@ #include <limits.h> +// keep in sync with QAbstractItemDelegate::helpEvent() #ifndef DBL_DIG # define DBL_DIG 10 #endif @@ -102,7 +103,7 @@ public: return text; } - static QString valueToText(const QVariant &value, const QStyleOptionViewItem &option); + QString valueToText(const QVariant &value, const QStyleOptionViewItem &option) const; QItemEditorFactory *f; bool clipPainting; @@ -332,40 +333,9 @@ void QItemDelegate::setClipping(bool clip) d->clipPainting = clip; } -QString QItemDelegatePrivate::valueToText(const QVariant &value, const QStyleOptionViewItem &option) +QString QItemDelegatePrivate::valueToText(const QVariant &value, const QStyleOptionViewItem &option) const { - QString text; - switch (value.userType()) { - case QMetaType::Float: - text = option.locale.toString(value.toFloat(), 'g'); - break; - case QVariant::Double: - text = option.locale.toString(value.toDouble(), 'g', DBL_DIG); - break; - case QVariant::Int: - case QVariant::LongLong: - text = option.locale.toString(value.toLongLong()); - break; - case QVariant::UInt: - case QVariant::ULongLong: - text = option.locale.toString(value.toULongLong()); - break; - case QVariant::Date: - text = option.locale.toString(value.toDate(), QLocale::ShortFormat); - break; - case QVariant::Time: - text = option.locale.toString(value.toTime(), QLocale::ShortFormat); - break; - case QVariant::DateTime: - text = option.locale.toString(value.toDateTime().date(), QLocale::ShortFormat); - text += QLatin1Char(' '); - text += option.locale.toString(value.toDateTime().time(), QLocale::ShortFormat); - break; - default: - text = replaceNewLine(value.toString()); - break; - } - return text; + return textForRole(Qt::DisplayRole, value, option.locale, DBL_DIG); } /*! @@ -434,7 +404,7 @@ void QItemDelegate::paint(QPainter *painter, QRect displayRect; value = index.data(Qt::DisplayRole); if (value.isValid() && !value.isNull()) { - text = QItemDelegatePrivate::valueToText(value, opt); + text = d->valueToText(value, opt); displayRect = textRectangle(painter, d->textLayoutBounds(opt), opt.font, text); } @@ -1061,7 +1031,7 @@ QRect QItemDelegate::rect(const QStyleOptionViewItem &option, return QRect(QPoint(0, 0), option.decorationSize); case QVariant::String: default: { - QString text = QItemDelegatePrivate::valueToText(value, option); + const QString text = d->valueToText(value, option); value = index.data(Qt::FontRole); QFont fnt = qvariant_cast<QFont>(value).resolve(option.font); return textRectangle(0, d->textLayoutBounds(option), fnt, text); } diff --git a/src/widgets/itemviews/qstyleditemdelegate.cpp b/src/widgets/itemviews/qstyleditemdelegate.cpp index 162ef826da..bab8436dce 100644 --- a/src/widgets/itemviews/qstyleditemdelegate.cpp +++ b/src/widgets/itemviews/qstyleditemdelegate.cpp @@ -261,41 +261,7 @@ QStyledItemDelegate::~QStyledItemDelegate() */ QString QStyledItemDelegate::displayText(const QVariant &value, const QLocale& locale) const { - QString text; - switch (value.userType()) { - case QMetaType::Float: - case QVariant::Double: - text = locale.toString(value.toReal()); - break; - case QVariant::Int: - case QVariant::LongLong: - text = locale.toString(value.toLongLong()); - break; - case QVariant::UInt: - case QVariant::ULongLong: - text = locale.toString(value.toULongLong()); - break; - case QVariant::Date: - text = locale.toString(value.toDate(), QLocale::ShortFormat); - break; - case QVariant::Time: - text = locale.toString(value.toTime(), QLocale::ShortFormat); - break; - case QVariant::DateTime: - text = locale.toString(value.toDateTime().date(), QLocale::ShortFormat); - text += QLatin1Char(' '); - text += locale.toString(value.toDateTime().time(), QLocale::ShortFormat); - break; - default: - // convert new lines into line separators - text = value.toString(); - for (int i = 0; i < text.count(); ++i) { - if (text.at(i) == QLatin1Char('\n')) - text[i] = QChar::LineSeparator; - } - break; - } - return text; + return d_func()->textForRole(Qt::DisplayRole, value, locale); } /*! diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index d28bd644c6..5b455a4e5c 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -1923,7 +1923,7 @@ NSView *QMacStylePrivate::cocoaControl(QCocoaWidget widget) const } case QCocoaPushButton: { NSButton *bc = (NSButton *)bv; - bc.buttonType = NSMomentaryPushButton; + bc.buttonType = NSMomentaryLightButton; bc.bezelStyle = NSRoundedBezelStyle; break; } diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp index b41ad4249e..c3a50968e2 100644 --- a/src/widgets/styles/qwindowsstyle.cpp +++ b/src/widgets/styles/qwindowsstyle.cpp @@ -64,8 +64,12 @@ #include "qlistview.h" #include <private/qmath_p.h> #include <qmath.h> +#include <QtGui/qscreen.h> +#include <QtGui/qwindow.h> #include <qpa/qplatformtheme.h> +#include <qpa/qplatformscreen.h> #include <private/qguiapplication_p.h> +#include <private/qhighdpiscaling_p.h> #include <private/qstylehelper_p.h> #include <private/qstyleanimation_p.h> @@ -360,6 +364,47 @@ int QWindowsStylePrivate::fixedPixelMetric(QStyle::PixelMetric pm) return QWindowsStylePrivate::InvalidMetric; } +static QWindow *windowOf(const QWidget *w) +{ + QWindow *result = Q_NULLPTR; + if (w) { + result = w->windowHandle(); + if (!result) { + if (const QWidget *np = w->nativeParentWidget()) + result = np->windowHandle(); + } + } + return result; +} + +static QScreen *screenOf(const QWidget *w) +{ + if (const QWindow *window = windowOf(w)) + return window->screen(); + return QGuiApplication::primaryScreen(); +} + +// Calculate the overall scale factor to obtain Qt Device Independent +// Pixels from a native Windows size. Divide by devicePixelRatio +// and account for secondary screens with differing logical DPI. +qreal QWindowsStylePrivate::nativeMetricScaleFactor(const QWidget *widget) +{ + if (!QHighDpiScaling::isActive()) + return 1; + qreal result = qreal(1) / QWindowsStylePrivate::devicePixelRatio(widget); + if (QGuiApplicationPrivate::screen_list.size() > 1) { + const QScreen *primaryScreen = QGuiApplication::primaryScreen(); + const QScreen *screen = screenOf(widget); + if (screen != primaryScreen) { + const qreal primaryLogicalDpi = primaryScreen->handle()->logicalDpi().first; + const qreal logicalDpi = screen->handle()->logicalDpi().first; + if (!qFuzzyCompare(primaryLogicalDpi, logicalDpi)) + result *= logicalDpi / primaryLogicalDpi; + } + } + return result; +} + /*! \reimp */ @@ -367,7 +412,7 @@ int QWindowsStyle::pixelMetric(PixelMetric pm, const QStyleOption *opt, const QW { int ret = QWindowsStylePrivate::pixelMetricFromSystemDp(pm, opt, widget); if (ret != QWindowsStylePrivate::InvalidMetric) - return qRound(qreal(ret) / QWindowsStylePrivate::devicePixelRatio(widget)); + return qRound(qreal(ret) * QWindowsStylePrivate::nativeMetricScaleFactor(widget)); ret = QWindowsStylePrivate::fixedPixelMetric(pm); if (ret != QWindowsStylePrivate::InvalidMetric) diff --git a/src/widgets/styles/qwindowsstyle_p_p.h b/src/widgets/styles/qwindowsstyle_p_p.h index b6a2df9cfc..0c23f4b4a8 100644 --- a/src/widgets/styles/qwindowsstyle_p_p.h +++ b/src/widgets/styles/qwindowsstyle_p_p.h @@ -73,6 +73,7 @@ public: static int fixedPixelMetric(QStyle::PixelMetric pm); static qreal devicePixelRatio(const QWidget *widget = 0) { return widget ? widget->devicePixelRatioF() : QWindowsStylePrivate::appDevicePixelRatio(); } + static qreal nativeMetricScaleFactor(const QWidget *widget = Q_NULLPTR); bool hasSeenAlt(const QWidget *widget) const; bool altDown() const { return alt_down; } @@ -105,3 +106,4 @@ QT_END_NAMESPACE #endif // QT_NO_STYLE_WINDOWS #endif //QWINDOWSSTYLE_P_P_H +; diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index 6009b5d1f8..c2cce5770f 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -430,7 +430,7 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt XPThemeData themeSize = theme; themeSize.partId = TVP_HOTGLYPH; themeSize.stateId = GLPS_OPENED; - const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget); + const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); decoration_size = qRound(qMax(size.width(), size.height())); } int mid_h = option->rect.x() + option->rect.width() / 2; @@ -988,7 +988,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption XPThemeData theme(widget, 0, QWindowsXPStylePrivate::ToolBarTheme, TP_DROPDOWNBUTTON); if (theme.isValid()) { - const QSizeF size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget); + const QSizeF size = theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); if (!size.isEmpty()) { mbiw = qRound(size.width()); mbih = qRound(size.height()); @@ -1184,8 +1184,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption XPThemeData themeSize = theme; themeSize.partId = MENU_POPUPCHECK; themeSize.stateId = 0; - const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget); - const QMarginsF margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget); + const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); checkcol = qMax(menuitem->maxIconWidth, qRound(gutterWidth + size.width() + margins.left() + margins.right())); } QRect rect = option->rect; @@ -1210,7 +1210,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (menuitem->menuItemType == QStyleOptionMenuItem::Separator) { int yoff = y-2 + h / 2; - const int separatorSize = 6 / QWindowsXPStylePrivate::devicePixelRatio(widget); + const int separatorSize = qRound(qreal(6) * QWindowsStylePrivate::nativeMetricScaleFactor(widget)); QPoint p1 = QPoint(x + checkcol, yoff); QPoint p2 = QPoint(x + w + separatorSize, yoff); stateId = MBI_HOT; @@ -1243,8 +1243,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption XPThemeData themeSize = theme; themeSize.partId = MENU_POPUPCHECK; themeSize.stateId = 0; - const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget); - const QMarginsF margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget); + const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); QRect checkRect(0, 0, qRound(size.width() + margins.left() + margins.right()), qRound(size.height() + margins.bottom() + margins.top())); checkRect.moveCenter(vCheckRect.center()); @@ -1856,8 +1856,8 @@ QSize QWindowsVistaStyle::sizeFromContents(ContentsType type, const QStyleOption XPThemeData themeSize = theme; themeSize.partId = MENU_POPUPCHECK; themeSize.stateId = 0; - const QSizeF size = themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget); - const QMarginsF margins = themeSize.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget); + const QSizeF size = themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); + const QMarginsF margins = themeSize.margins() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); minimumHeight = qMax(qRound(size.height() + margins.bottom() + margins.top()), sz.height()); sz.rwidth() += qRound(size.width() + margins.left() + margins.right()); } @@ -1959,7 +1959,7 @@ QRect QWindowsVistaStyle::subElementRect(SubElement element, const QStyleOption int arrowWidth = 13; int arrowHeight = 5; if (theme.isValid()) { - const QSizeF size = theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget); + const QSizeF size = theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget); if (!size.isEmpty()) { arrowWidth = qRound(size.width()); arrowHeight = qRound(size.height()); @@ -2440,7 +2440,7 @@ QIcon QWindowsVistaStyle::standardIcon(StandardPixmap standardIcon, QWindowsXPStylePrivate::ButtonTheme, BP_COMMANDLINKGLYPH, CMDLGS_NORMAL); if (theme.isValid()) { - const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize(); + const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); QIcon linkGlyph; QPixmap pm(size); pm.fill(Qt::transparent); diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp index c0ea725b7b..ffedc37edb 100644 --- a/src/widgets/styles/qwindowsxpstyle.cpp +++ b/src/widgets/styles/qwindowsxpstyle.cpp @@ -415,7 +415,7 @@ const QPixmap *QWindowsXPStylePrivate::tabBody(QWidget *widget) { if (!tabbody) { XPThemeData theme(0, 0, QWindowsXPStylePrivate::TabTheme, TABP_BODY); - const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize(); + const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); tabbody = new QPixmap(size.width(), QApplication::desktop()->screenGeometry().height()); QPainter painter(tabbody); @@ -3274,7 +3274,7 @@ int QWindowsXPStyle::pixelMetric(PixelMetric pm, const QStyleOption *option, con int res = QWindowsXPStylePrivate::pixelMetricFromSystemDp(pm, option, widget); if (res != QWindowsStylePrivate::InvalidMetric) - return qRound(qreal(res) / QWindowsStylePrivate::devicePixelRatio(widget)); + return qRound(qreal(res) * QWindowsStylePrivate::nativeMetricScaleFactor(widget)); res = 0; switch (pm) { @@ -3420,9 +3420,10 @@ QRect QWindowsXPStyle::subControlRect(ComplexControl cc, const QStyleOptionCompl const int height = tb->rect.height(); const int width = tb->rect.width(); const int buttonMargin = int(QStyleHelper::dpiScaled(4)); - int buttonHeight = qRound(qreal(GetSystemMetrics(SM_CYSIZE)) / QWindowsStylePrivate::devicePixelRatio(widget)) + const qreal factor = QWindowsStylePrivate::nativeMetricScaleFactor(widget); + int buttonHeight = qRound(qreal(GetSystemMetrics(SM_CYSIZE)) * factor) - buttonMargin; - int buttonWidth = qRound(qreal(GetSystemMetrics(SM_CXSIZE)) / QWindowsStylePrivate::devicePixelRatio(widget)) + int buttonWidth = qRound(qreal(GetSystemMetrics(SM_CXSIZE)) * factor) - buttonMargin; const int delta = buttonWidth + 2; int controlTop = option->rect.bottom() - buttonHeight - 2; @@ -3792,7 +3793,7 @@ QPixmap QWindowsXPStyle::standardPixmap(StandardPixmap standardPixmap, const QSt if (widget && widget->isWindow()) { XPThemeData theme(widget, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL); if (theme.isValid()) { - const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize(); + const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); return QIcon(QWindowsStyle::standardPixmap(standardPixmap, option, widget)).pixmap(size); } } @@ -3826,7 +3827,7 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon, XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, WP_MAXBUTTON, MAXBS_NORMAL); if (theme.isValid()) { - const QSize size = (themeSize.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize(); + const QSize size = (themeSize.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); QPixmap pm(size); pm.fill(Qt::transparent); QPainter p(&pm); @@ -3860,7 +3861,7 @@ QIcon QWindowsXPStyle::standardIcon(StandardPixmap standardIcon, XPThemeData theme(0, 0, QWindowsXPStylePrivate::WindowTheme, WP_SMALLCLOSEBUTTON, CBS_NORMAL); if (theme.isValid()) { - const QSize size = (theme.size() / QWindowsXPStylePrivate::devicePixelRatio(widget)).toSize(); + const QSize size = (theme.size() * QWindowsStylePrivate::nativeMetricScaleFactor(widget)).toSize(); QPixmap pm(size); pm.fill(Qt::transparent); QPainter p(&pm); diff --git a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp index de6884d454..5b03b35780 100644 --- a/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/io/qdatastream/tst_qdatastream.cpp @@ -2723,27 +2723,43 @@ void tst_QDataStream::status_QBitArray() } #define MAP_TEST(byteArray, initialStatus, expectedStatus, expectedHash) \ - { \ - QByteArray ba = byteArray; \ - QDataStream stream(&ba, QIODevice::ReadOnly); \ - stream.setStatus(initialStatus); \ - stream >> hash; \ - QCOMPARE((int)stream.status(), (int)expectedStatus); \ - QCOMPARE(hash.size(), expectedHash.size()); \ - QCOMPARE(hash, expectedHash); \ - } \ - { \ - QByteArray ba = byteArray; \ - StringMap expectedMap; \ - StringHash::const_iterator it = expectedHash.constBegin(); \ - for (; it != expectedHash.constEnd(); ++it) \ - expectedMap.insert(it.key(), it.value()); \ - QDataStream stream(&ba, QIODevice::ReadOnly); \ - stream.setStatus(initialStatus); \ - stream >> map; \ - QCOMPARE((int)stream.status(), (int)expectedStatus); \ - QCOMPARE(map.size(), expectedMap.size()); \ - QCOMPARE(map, expectedMap); \ + for (bool inTransaction = false;; inTransaction = true) { \ + { \ + QByteArray ba = byteArray; \ + QDataStream stream(&ba, QIODevice::ReadOnly); \ + if (inTransaction) \ + stream.startTransaction(); \ + stream.setStatus(initialStatus); \ + stream >> hash; \ + QCOMPARE((int)stream.status(), (int)expectedStatus); \ + if (!inTransaction || stream.commitTransaction()) { \ + QCOMPARE(hash.size(), expectedHash.size()); \ + QCOMPARE(hash, expectedHash); \ + } else { \ + QVERIFY(hash.isEmpty()); \ + } \ + } \ + { \ + QByteArray ba = byteArray; \ + StringMap expectedMap; \ + StringHash::const_iterator it = expectedHash.constBegin(); \ + for (; it != expectedHash.constEnd(); ++it) \ + expectedMap.insert(it.key(), it.value()); \ + QDataStream stream(&ba, QIODevice::ReadOnly); \ + if (inTransaction) \ + stream.startTransaction(); \ + stream.setStatus(initialStatus); \ + stream >> map; \ + QCOMPARE((int)stream.status(), (int)expectedStatus); \ + if (!inTransaction || stream.commitTransaction()) { \ + QCOMPARE(map.size(), expectedMap.size()); \ + QCOMPARE(map, expectedMap); \ + } else { \ + QVERIFY(map.isEmpty()); \ + } \ + } \ + if (inTransaction) \ + break; \ } void tst_QDataStream::status_QHash_QMap() @@ -2788,38 +2804,60 @@ void tst_QDataStream::status_QHash_QMap() } #define LIST_TEST(byteArray, initialStatus, expectedStatus, expectedList) \ - { \ - QByteArray ba = byteArray; \ - QDataStream stream(&ba, QIODevice::ReadOnly); \ - stream.setStatus(initialStatus); \ - stream >> list; \ - QCOMPARE((int)stream.status(), (int)expectedStatus); \ - QCOMPARE(list.size(), expectedList.size()); \ - QCOMPARE(list, expectedList); \ - } \ - { \ - LinkedList expectedLinkedList; \ - for (int i = 0; i < expectedList.count(); ++i) \ - expectedLinkedList << expectedList.at(i); \ - QByteArray ba = byteArray; \ - QDataStream stream(&ba, QIODevice::ReadOnly); \ - stream.setStatus(initialStatus); \ - stream >> linkedList; \ - QCOMPARE((int)stream.status(), (int)expectedStatus); \ - QCOMPARE(linkedList.size(), expectedLinkedList.size()); \ - QCOMPARE(linkedList, expectedLinkedList); \ - } \ - { \ - Vector expectedVector; \ - for (int i = 0; i < expectedList.count(); ++i) \ - expectedVector << expectedList.at(i); \ - QByteArray ba = byteArray; \ - QDataStream stream(&ba, QIODevice::ReadOnly); \ - stream.setStatus(initialStatus); \ - stream >> vector; \ - QCOMPARE((int)stream.status(), (int)expectedStatus); \ - QCOMPARE(vector.size(), expectedVector.size()); \ - QCOMPARE(vector, expectedVector); \ + for (bool inTransaction = false;; inTransaction = true) { \ + { \ + QByteArray ba = byteArray; \ + QDataStream stream(&ba, QIODevice::ReadOnly); \ + if (inTransaction) \ + stream.startTransaction(); \ + stream.setStatus(initialStatus); \ + stream >> list; \ + QCOMPARE((int)stream.status(), (int)expectedStatus); \ + if (!inTransaction || stream.commitTransaction()) { \ + QCOMPARE(list.size(), expectedList.size()); \ + QCOMPARE(list, expectedList); \ + } else { \ + QVERIFY(list.isEmpty()); \ + } \ + } \ + { \ + LinkedList expectedLinkedList; \ + for (int i = 0; i < expectedList.count(); ++i) \ + expectedLinkedList << expectedList.at(i); \ + QByteArray ba = byteArray; \ + QDataStream stream(&ba, QIODevice::ReadOnly); \ + if (inTransaction) \ + stream.startTransaction(); \ + stream.setStatus(initialStatus); \ + stream >> linkedList; \ + QCOMPARE((int)stream.status(), (int)expectedStatus); \ + if (!inTransaction || stream.commitTransaction()) { \ + QCOMPARE(linkedList.size(), expectedLinkedList.size()); \ + QCOMPARE(linkedList, expectedLinkedList); \ + } else { \ + QVERIFY(linkedList.isEmpty()); \ + } \ + } \ + { \ + Vector expectedVector; \ + for (int i = 0; i < expectedList.count(); ++i) \ + expectedVector << expectedList.at(i); \ + QByteArray ba = byteArray; \ + QDataStream stream(&ba, QIODevice::ReadOnly); \ + if (inTransaction) \ + stream.startTransaction(); \ + stream.setStatus(initialStatus); \ + stream >> vector; \ + QCOMPARE((int)stream.status(), (int)expectedStatus); \ + if (!inTransaction || stream.commitTransaction()) { \ + QCOMPARE(vector.size(), expectedVector.size()); \ + QCOMPARE(vector, expectedVector); \ + } else { \ + QVERIFY(vector.isEmpty()); \ + } \ + } \ + if (inTransaction) \ + break; \ } void tst_QDataStream::status_QLinkedList_QList_QVector() diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp index f0b9c05810..487c13be94 100644 --- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp +++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp @@ -34,6 +34,7 @@ #include <qfile.h> #include <qdir.h> #include <qset.h> +#include <qtextcodec.h> #ifdef Q_OS_WIN # include <windows.h> #endif @@ -108,6 +109,38 @@ void tst_QTemporaryDir::getSetCheck() QCOMPARE(true, obj1.autoRemove()); } +static inline bool canHandleUnicodeFileNames() +{ +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + return true; +#else + // Check for UTF-8 by converting the Euro symbol (see tst_utf8) + return QFile::encodeName(QString(QChar(0x20AC))) == QByteArrayLiteral("\342\202\254"); +#endif +} + +static QString hanTestText() +{ + QString text; + text += QChar(0x65B0); + text += QChar(0x5E10); + text += QChar(0x6237); + return text; +} + +static QString umlautTestText() +{ + QString text; + text += QChar(0xc4); + text += QChar(0xe4); + text += QChar(0xd6); + text += QChar(0xf6); + text += QChar(0xdc); + text += QChar(0xfc); + text += QChar(0xdf); + return text; +} + void tst_QTemporaryDir::fileTemplate_data() { QTest::addColumn<QString>("constructorTemplate"); @@ -124,6 +157,14 @@ void tst_QTemporaryDir::fileTemplate_data() QTest::newRow("constructor with XXXX suffix") << "qt_XXXXXX_XXXX" << "qt_"; QTest::newRow("constructor with XXXX prefix") << "qt_XXXX" << "qt_"; QTest::newRow("constructor with XXXXX prefix") << "qt_XXXXX" << "qt_"; + if (canHandleUnicodeFileNames()) { + // Test Umlauts (contained in Latin1) + QString prefix = "qt_" + umlautTestText(); + QTest::newRow("Umlauts") << (prefix + "XXXXXX") << prefix; + // Test Chinese + prefix = "qt_" + hanTestText(); + QTest::newRow("Chinese characters") << (prefix + "XXXXXX") << prefix; + } } void tst_QTemporaryDir::fileTemplate() diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp index 9b46121981..59cd3a8411 100644 --- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp @@ -34,6 +34,7 @@ #include <qfile.h> #include <qdir.h> #include <qset.h> +#include <qtextcodec.h> #if defined(Q_OS_WIN) # include <windows.h> @@ -140,6 +141,38 @@ void tst_QTemporaryFile::getSetCheck() QCOMPARE(true, obj1.autoRemove()); } +static inline bool canHandleUnicodeFileNames() +{ +#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) + return true; +#else + // Check for UTF-8 by converting the Euro symbol (see tst_utf8) + return QFile::encodeName(QString(QChar(0x20AC))) == QByteArrayLiteral("\342\202\254"); +#endif +} + +static QString hanTestText() +{ + QString text; + text += QChar(0x65B0); + text += QChar(0x5E10); + text += QChar(0x6237); + return text; +} + +static QString umlautTestText() +{ + QString text; + text += QChar(0xc4); + text += QChar(0xe4); + text += QChar(0xd6); + text += QChar(0xf6); + text += QChar(0xdc); + text += QChar(0xfc); + text += QChar(0xdf); + return text; +} + void tst_QTemporaryFile::fileTemplate_data() { QTest::addColumn<QString>("constructorTemplate"); @@ -166,6 +199,14 @@ void tst_QTemporaryFile::fileTemplate_data() QTest::newRow("set template, with xxx") << "" << "qt_" << ".xxx" << "qt_XXXXXX.xxx"; QTest::newRow("set template, with >6 X's") << "" << "qt_" << ".xxx" << "qt_XXXXXXXXXXXXXX.xxx"; QTest::newRow("set template, with >6 X's, no suffix") << "" << "qt_" << "" << "qt_XXXXXXXXXXXXXX"; + if (canHandleUnicodeFileNames()) { + // Test Umlauts (contained in Latin1) + QString prefix = "qt_" + umlautTestText(); + QTest::newRow("Umlauts") << (prefix + "XXXXXX") << prefix << QString() << QString(); + // Test Chinese + prefix = "qt_" + hanTestText(); + QTest::newRow("Chinese characters") << (prefix + "XXXXXX") << prefix << QString() << QString(); + } } void tst_QTemporaryFile::fileTemplate() diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp index 825cb05d74..374fec221e 100644 --- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp +++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp @@ -271,6 +271,7 @@ private slots: void testOperators() const; void reserve(); + void reserveZero(); void reallocAfterCopy_data(); void reallocAfterCopy(); void initializeListInt(); @@ -2365,13 +2366,34 @@ void tst_QVector::reserve() { QVector<Foo> a; a.resize(2); + QCOMPARE(fooCtor, 2); QVector<Foo> b(a); b.reserve(1); QCOMPARE(b.size(), a.size()); + QCOMPARE(fooDtor, 0); } QCOMPARE(fooCtor, fooDtor); } +// This is a regression test for QTBUG-51758 +void tst_QVector::reserveZero() +{ + QVector<int> vec; + vec.detach(); + vec.reserve(0); // should not crash + QCOMPARE(vec.size(), 0); + QCOMPARE(vec.capacity(), 0); + vec.squeeze(); + QCOMPARE(vec.size(), 0); + QCOMPARE(vec.capacity(), 0); + vec.reserve(-1); + QCOMPARE(vec.size(), 0); + QCOMPARE(vec.capacity(), 0); + vec.append(42); + QCOMPARE(vec.size(), 1); + QVERIFY(vec.capacity() >= 1); +} + // This is a regression test for QTBUG-11763, where memory would be reallocated // soon after copying a QVector. void tst_QVector::reallocAfterCopy_data() diff --git a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp index 26d443c2c6..9556a167c5 100644 --- a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp @@ -557,6 +557,8 @@ private slots: void checkCommentIndentation_data() const; void crashInXmlStreamReader() const; void write8bitCodec() const; + void invalidStringCharacters_data() const; + void invalidStringCharacters() const; void hasError() const; private: @@ -1614,6 +1616,63 @@ void tst_QXmlStream::write8bitCodec() const QVERIFY(decodedText.startsWith(expected)); } +void tst_QXmlStream::invalidStringCharacters() const +{ + // test scan in attributes + QFETCH(QString, testString); + QFETCH(bool, expectedResultNoError); + + QByteArray values = testString.toUtf8(); + QBuffer inBuffer; + inBuffer.setData(values); + QVERIFY(inBuffer.open(QIODevice::ReadOnly)); + QXmlStreamReader reader(&inBuffer); + do { + reader.readNext(); + } while (!reader.atEnd()); + QCOMPARE((reader.error() == QXmlStreamReader::NoError), expectedResultNoError); +} + +void tst_QXmlStream::invalidStringCharacters_data() const +{ + // test scan in attributes + QTest::addColumn<bool>("expectedResultNoError"); + QTest::addColumn<QString>("testString"); + QChar ctrl(0x1A); + QTest::newRow("utf8, attributes, legal") << true << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'/>"); + QTest::newRow("utf8, attributes, only char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='")+ctrl+QString("'/>"); + QTest::newRow("utf8, attributes, 1st char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='")+ctrl+QString("abc'/>"); + QTest::newRow("utf8, attributes, middle char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='abc")+ctrl+QString("efgx'/>"); + QTest::newRow("utf8, attributes, last char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='abcde")+ctrl+QString("'/>"); + // + QTest::newRow("utf8, text, legal") << true << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'>abcx1A</root>"); + QTest::newRow("utf8, text, only, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'>")+ctrl+QString("</root>"); + QTest::newRow("utf8, text, 1st char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'>abc")+ctrl+QString("def</root>"); + QTest::newRow("utf8, text, middle char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'>abc")+ctrl+QString("efg</root>"); + QTest::newRow("utf8, text, last char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'>abc")+ctrl+QString("</root>"); + // + QTest::newRow("utf8, cdata text, legal") << true << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'><![CDATA[abcdefghi]]></root>"); + QTest::newRow("utf8, cdata text, only, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'><![CDATA[")+ctrl+QString("]]></root>"); + QTest::newRow("utf8, cdata text, 1st char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'><![CDATA[")+ctrl+QString("abcdefghi]]></root>"); + QTest::newRow("utf8, cdata text, middle char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'><![CDATA[abcd")+ctrl+QString("efghi]]></root>"); + QTest::newRow("utf8, cdata text, last char, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'><![CDATA[abcdefghi")+ctrl+QString("]]></root>"); + // + QTest::newRow("utf8, mixed, control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='a")+ctrl+QString("a'><![CDATA[abcdefghi")+ctrl+QString("]]></root>"); + QTest::newRow("utf8, tag") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><roo")+ctrl+QString("t attr='aa'><![CDATA[abcdefghi]]></roo")+ctrl+QString("t>"); + // + QTest::newRow("utf8, attributes, 1st char, legal escaping hex") << true << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='a '/>"); + QTest::newRow("utf8, attributes, 1st char, control escaping hex") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aaa'/>"); + QTest::newRow("utf8, attributes, middle char, legal escaping hex") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aaaaaa'/>"); + QTest::newRow("utf8, attributes, last char, control escaping hex") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aaa'/>"); + QTest::newRow("utf8, attributes, 1st char, legal escaping dec") << true << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='a '/>"); + QTest::newRow("utf8, attributes, 1st char, control escaping dec") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aaaa'/>"); + QTest::newRow("utf8, attributes, middle char, legal escaping dec") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aaaaaaaa'/>"); + QTest::newRow("utf8, attributes, last char, control escaping dec") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aaaaaa'/>"); + QTest::newRow("utf8, tag escaping") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='aa'><![CDATA[abcdefghi]]></root>"); + // + QTest::newRow("utf8, mix of illegal control") << false << QString("<?xml version=\"1.0\" encoding=\"UTF-8\"?><root attr='a�a'><![CDATA[abcdefghi]]></root>"); + // +} #include "tst_qxmlstream.moc" // vim: et:ts=4:sw=4:sts=4 diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 7e1a02d716..18812fd090 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -94,6 +94,8 @@ private slots: void setPixel_data(); void setPixel(); + void defaultColorTable_data(); + void defaultColorTable(); void setColorCount(); void setColor(); @@ -1450,6 +1452,38 @@ void tst_QImage::convertToFormatPreserveText() QCOMPARE(imgResult2.textKeys(), listResult); } +void tst_QImage::defaultColorTable_data() +{ + QTest::addColumn<QImage::Format>("format"); + QTest::addColumn<int>("createdDataCount"); + QTest::addColumn<int>("externalDataCount"); + + // For historical reasons, internally created mono images get a default colormap. + // Externally created and Indexed8 images do not. + QTest::newRow("Mono") << QImage::Format_Mono << 2 << 0; + QTest::newRow("MonoLSB") << QImage::Format_MonoLSB << 2 << 0; + QTest::newRow("Indexed8") << QImage::Format_Indexed8 << 0 << 0; + QTest::newRow("ARGB32_PM") << QImage::Format_A2BGR30_Premultiplied << 0 << 0; +} + +void tst_QImage::defaultColorTable() +{ + QFETCH(QImage::Format, format); + QFETCH(int, createdDataCount); + QFETCH(int, externalDataCount); + + QImage img1(1, 1, format); + QCOMPARE(img1.colorCount(), createdDataCount); + QCOMPARE(img1.colorTable().size(), createdDataCount); + + quint32 buf; + QImage img2(reinterpret_cast<uchar *>(&buf), 1, 1, format); + QCOMPARE(img2.colorCount(), externalDataCount); + + QImage nullImg(0, 0, format); + QCOMPARE(nullImg.colorCount(), 0); +} + void tst_QImage::setColorCount() { QImage img(0, 0, QImage::Format_Indexed8); @@ -3194,8 +3228,8 @@ void tst_QImage::pixel() QImage monolsb(&a, 1, 1, QImage::Format_MonoLSB); QImage indexed(&a, 1, 1, QImage::Format_Indexed8); - QCOMPARE(QColor(mono.pixel(0, 0)), QColor(Qt::black)); - QCOMPARE(QColor(monolsb.pixel(0, 0)), QColor(Qt::black)); + mono.pixel(0, 0); // Don't crash + monolsb.pixel(0, 0); // Don't crash indexed.pixel(0, 0); // Don't crash } } diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 6bb502edcb..fb6b0c6e32 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -673,6 +673,12 @@ void tst_QTcpSocket::bindThenResolveHost() const quint16 port = 80; socket->connectToHost(hostName, port); + // Additionally, initiate a delayed close before the socket connects + // to ensure that we don't lose the socket engine in HostLookupState. + // After a connection has been established, socket should send all + // the pending data and close the socket engine automatically. + QVERIFY(socket->putChar(0)); + socket->close(); QVERIFY2(socket->waitForConnected(), (hostName.toLocal8Bit() + ": " + QByteArray::number(port) + ' ' + QtNetworkSettings::msgSocketError(*socket)).constData()); diff --git a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp index ae5953aa35..aa78d70716 100644 --- a/tests/auto/other/qobjectrace/tst_qobjectrace.cpp +++ b/tests/auto/other/qobjectrace/tst_qobjectrace.cpp @@ -46,6 +46,7 @@ class tst_QObjectRace: public QObject private slots: void moveToThreadRace(); void destroyRace(); + void disconnectRace(); }; class RaceObject : public QObject @@ -293,6 +294,180 @@ void tst_QObjectRace::destroyRace() delete threads[i]; } +static QAtomicInteger<unsigned> countedStructObjectsCount; +struct CountedFunctor +{ + CountedFunctor() : destroyed(false) { countedStructObjectsCount.fetchAndAddRelaxed(1); } + CountedFunctor(const CountedFunctor &) : destroyed(false) { countedStructObjectsCount.fetchAndAddRelaxed(1); } + CountedFunctor &operator=(const CountedFunctor &) { return *this; } + ~CountedFunctor() { destroyed = true; countedStructObjectsCount.fetchAndAddRelaxed(-1);} + void operator()() const {QCOMPARE(destroyed, false);} + +private: + bool destroyed; +}; + +class DisconnectRaceSenderObject : public QObject +{ + Q_OBJECT +signals: + void theSignal(); +}; + +class DisconnectRaceThread : public QThread +{ + Q_OBJECT + + DisconnectRaceSenderObject *sender; + bool emitSignal; +public: + DisconnectRaceThread(DisconnectRaceSenderObject *s, bool emitIt) + : QThread(), sender(s), emitSignal(emitIt) + { + } + + void run() + { + while (!isInterruptionRequested()) { + QMetaObject::Connection conn = connect(sender, &DisconnectRaceSenderObject::theSignal, + sender, CountedFunctor(), Qt::BlockingQueuedConnection); + if (emitSignal) + emit sender->theSignal(); + disconnect(conn); + yieldCurrentThread(); + } + } +}; + +class DeleteReceiverRaceSenderThread : public QThread +{ + Q_OBJECT + + DisconnectRaceSenderObject *sender; +public: + DeleteReceiverRaceSenderThread(DisconnectRaceSenderObject *s) + : QThread(), sender(s) + { + } + + void run() + { + while (!isInterruptionRequested()) { + emit sender->theSignal(); + yieldCurrentThread(); + } + } +}; + +class DeleteReceiverRaceReceiver : public QObject +{ + Q_OBJECT + + DisconnectRaceSenderObject *sender; + QObject *receiver; + QTimer *timer; +public: + DeleteReceiverRaceReceiver(DisconnectRaceSenderObject *s) + : QObject(), sender(s), receiver(0) + { + timer = new QTimer(this); + connect(timer, &QTimer::timeout, this, &DeleteReceiverRaceReceiver::onTimeout); + timer->start(1); + } + + void onTimeout() + { + if (receiver) + delete receiver; + receiver = new QObject; + connect(sender, &DisconnectRaceSenderObject::theSignal, receiver, CountedFunctor(), Qt::BlockingQueuedConnection); + } +}; + +class DeleteReceiverRaceReceiverThread : public QThread +{ + Q_OBJECT + + DisconnectRaceSenderObject *sender; +public: + DeleteReceiverRaceReceiverThread(DisconnectRaceSenderObject *s) + : QThread(), sender(s) + { + } + + void run() + { + QScopedPointer<DeleteReceiverRaceReceiver> receiver(new DeleteReceiverRaceReceiver(sender)); + exec(); + } +}; + +void tst_QObjectRace::disconnectRace() +{ + enum { ThreadCount = 20, TimeLimit = 3000 }; + + QCOMPARE(countedStructObjectsCount.load(), 0u); + + { + QScopedPointer<DisconnectRaceSenderObject> sender(new DisconnectRaceSenderObject()); + QScopedPointer<QThread> senderThread(new QThread()); + senderThread->start(); + sender->moveToThread(senderThread.data()); + + DisconnectRaceThread *threads[ThreadCount]; + for (int i = 0; i < ThreadCount; ++i) { + threads[i] = new DisconnectRaceThread(sender.data(), !(i % 10)); + threads[i]->start(); + } + + QTime timeLimiter; + timeLimiter.start(); + + while (timeLimiter.elapsed() < TimeLimit) + QTest::qWait(10); + + for (int i = 0; i < ThreadCount; ++i) { + threads[i]->requestInterruption(); + QVERIFY(threads[i]->wait(300)); + delete threads[i]; + } + + senderThread->quit(); + QVERIFY(senderThread->wait(300)); + } + + QCOMPARE(countedStructObjectsCount.load(), 0u); + + { + QScopedPointer<DisconnectRaceSenderObject> sender(new DisconnectRaceSenderObject()); + QScopedPointer<DeleteReceiverRaceSenderThread> senderThread(new DeleteReceiverRaceSenderThread(sender.data())); + senderThread->start(); + sender->moveToThread(senderThread.data()); + + DeleteReceiverRaceReceiverThread *threads[ThreadCount]; + for (int i = 0; i < ThreadCount; ++i) { + threads[i] = new DeleteReceiverRaceReceiverThread(sender.data()); + threads[i]->start(); + } + + QTime timeLimiter; + timeLimiter.start(); + + while (timeLimiter.elapsed() < TimeLimit) + QTest::qWait(10); + + senderThread->requestInterruption(); + QVERIFY(senderThread->wait(300)); + + for (int i = 0; i < ThreadCount; ++i) { + threads[i]->quit(); + QVERIFY(threads[i]->wait(300)); + delete threads[i]; + } + } + + QCOMPARE(countedStructObjectsCount.load(), 0u); +} QTEST_MAIN(tst_QObjectRace) #include "tst_qobjectrace.moc" diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 94df29f539..dc28422294 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -2034,6 +2034,13 @@ void tst_Moc::warnings_data() << 0 << QString("IGNORE_ALL_STDOUT") << QStringLiteral("Warning: Failed to resolve include \"doesnotexist.h\" for moc file <standard input>"); + + QTest::newRow("QTBUG-54815: Crash on invalid input") + << QByteArray("class M{(})F<{}d000000000000000#0") + << QStringList() + << 0 + << QString() + << QString("standard input:1: Note: No relevant classes found. No output generated."); } void tst_Moc::warnings() diff --git a/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro b/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro index 9405c33a48..10cd1dcc54 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro +++ b/tests/auto/widgets/itemviews/qitemdelegate/qitemdelegate.pro @@ -1,6 +1,6 @@ CONFIG += testcase TARGET = tst_qitemdelegate -QT += widgets testlib +QT += widgets widgets-private testlib SOURCES += tst_qitemdelegate.cpp win32:!winrt: LIBS += -luser32 diff --git a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp index e67edfcccb..0720a4f766 100644 --- a/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp +++ b/tests/auto/widgets/itemviews/qitemdelegate/tst_qitemdelegate.cpp @@ -51,6 +51,8 @@ #include <QPlainTextEdit> #include <QDialog> +#include <QtWidgets/private/qabstractitemdelegate_p.h> + Q_DECLARE_METATYPE(QAbstractItemDelegate::EndEditHint) #if defined (Q_OS_WIN) && !defined(Q_OS_WINRT) @@ -216,6 +218,8 @@ private slots: void task257859_finalizeEdit(); void QTBUG4435_keepSelectionOnCheck(); + + void QTBUG16469_textForRole(); }; @@ -1521,6 +1525,64 @@ void tst_QItemDelegate::testLineEditValidation() QCOMPARE(item->data(Qt::DisplayRole).toString(), QStringLiteral("abc,def")); } +void tst_QItemDelegate::QTBUG16469_textForRole() +{ +#ifndef QT_BUILD_INTERNAL + QSKIP("This test requires a developer build"); +#else + struct TestDelegate : public QItemDelegate + { + QString textForRole(Qt::ItemDataRole role, const QVariant &value, const QLocale &locale) + { + QAbstractItemDelegatePrivate *d = reinterpret_cast<QAbstractItemDelegatePrivate *>(qGetPtrHelper(d_ptr)); + return d->textForRole(role, value, locale); + } + } delegate; + QLocale locale; + + const float f = 123.456f; + QCOMPARE(delegate.textForRole(Qt::DisplayRole, f, locale), locale.toString(f)); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, f, locale), locale.toString(f)); + const double d = 123.456; + QCOMPARE(delegate.textForRole(Qt::DisplayRole, d, locale), locale.toString(d, 'g', 6)); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, d, locale), locale.toString(d, 'g', 6)); + const int i = 1234567; + QCOMPARE(delegate.textForRole(Qt::DisplayRole, i, locale), locale.toString(i)); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, i, locale), locale.toString(i)); + const qlonglong ll = 1234567; + QCOMPARE(delegate.textForRole(Qt::DisplayRole, ll, locale), locale.toString(ll)); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, ll, locale), locale.toString(ll)); + const uint ui = 1234567; + QCOMPARE(delegate.textForRole(Qt::DisplayRole, ui, locale), locale.toString(ui)); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, ui, locale), locale.toString(ui)); + const qulonglong ull = 1234567; + QCOMPARE(delegate.textForRole(Qt::DisplayRole, ull, locale), locale.toString(ull)); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, ull, locale), locale.toString(ull)); + + const QDateTime dateTime = QDateTime::currentDateTime(); + const QDate date = dateTime.date(); + const QTime time = dateTime.time(); + const QString shortDate = locale.toString(date, QLocale::ShortFormat); + const QString longDate = locale.toString(date, QLocale::LongFormat); + const QString shortTime = locale.toString(time, QLocale::ShortFormat); + const QString longTime = locale.toString(time, QLocale::LongFormat); + QCOMPARE(delegate.textForRole(Qt::DisplayRole, date, locale), shortDate); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, date, locale), longDate); + QCOMPARE(delegate.textForRole(Qt::DisplayRole, time, locale), shortTime); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, time, locale), longTime); + QCOMPARE(delegate.textForRole(Qt::DisplayRole, dateTime, locale), shortDate + QLatin1Char(' ') + shortTime); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, dateTime, locale), longDate + QLatin1Char(' ') + longTime); + + const QString text("text"); + QCOMPARE(delegate.textForRole(Qt::DisplayRole, text, locale), text); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, text, locale), text); + const QString multipleLines("multiple\nlines"); + QString multipleLines2 = multipleLines; + multipleLines2.replace(QLatin1Char('\n'), QChar::LineSeparator); + QCOMPARE(delegate.textForRole(Qt::DisplayRole, multipleLines, locale), multipleLines2); + QCOMPARE(delegate.textForRole(Qt::ToolTipRole, multipleLines, locale), multipleLines); +#endif +} // ### _not_ covered: diff --git a/tests/manual/embeddedintoforeignwindow/embeddedintoforeignwindow.pro b/tests/manual/embeddedintoforeignwindow/embeddedintoforeignwindow.pro new file mode 100644 index 0000000000..93da4b8c91 --- /dev/null +++ b/tests/manual/embeddedintoforeignwindow/embeddedintoforeignwindow.pro @@ -0,0 +1,7 @@ +TEMPLATE = app +QT += gui-private +CONFIG += console c++11 +CONFIG -= app_bundle +SOURCES += main.cpp itemwindow.cpp +HEADERS += itemwindow.h +include(../diaglib/diaglib.pri) diff --git a/tests/manual/embeddedintoforeignwindow/itemwindow.cpp b/tests/manual/embeddedintoforeignwindow/itemwindow.cpp new file mode 100644 index 0000000000..32a2e6557c --- /dev/null +++ b/tests/manual/embeddedintoforeignwindow/itemwindow.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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$ +** +****************************************************************************/ + +#include "itemwindow.h" + +#include <QtGui/QPainter> +#include <QtGui/QPaintEvent> + +void TextItem::paint(QPainter &painter) +{ + painter.fillRect(m_rect, m_col); + painter.drawRect(m_rect); + QTextOption textOption; + textOption.setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); + painter.drawText(m_rect, m_text, textOption); +} + +void ButtonItem::mouseEvent(QMouseEvent *mouseEvent) +{ + if (mouseEvent->type() == QEvent::MouseButtonPress && rect().contains(mouseEvent->pos())) { + mouseEvent->accept(); + emit clicked(); + } +} + +void ButtonItem::keyEvent(QKeyEvent *keyEvent) +{ + if (m_shortcut && keyEvent->type() == QEvent::KeyPress + && (keyEvent->key() + int(keyEvent->modifiers())) == m_shortcut) { + keyEvent->accept(); + emit clicked(); + } +} + +void ItemWindow::paintEvent(QPaintEvent *) +{ + QPainter painter(this); + QRect rect(QPoint(0, 0), size()); + painter.fillRect(rect, m_background); + foreach (Item *i, m_items) + i->paint(painter); +} diff --git a/tests/manual/embeddedintoforeignwindow/itemwindow.h b/tests/manual/embeddedintoforeignwindow/itemwindow.h new file mode 100644 index 0000000000..8ea9adaa16 --- /dev/null +++ b/tests/manual/embeddedintoforeignwindow/itemwindow.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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 ITEMWINDOW_H +#define ITEMWINDOW_H + +#include <QtGui/QKeySequence> +#include <QtGui/QRasterWindow> + +QT_USE_NAMESPACE + +// ItemWindow: Primitive UI item classes for use with a ItemWindow based +// on QRasterWindow without widgets allowing a simple UI without widgets. + +// Basic item to be used in a ItemWindow +class Item : public QObject { + Q_OBJECT +public: + explicit Item(QObject *parent = nullptr) : QObject(parent) {} + + virtual void paint(QPainter &painter) = 0; + virtual void mouseEvent(QMouseEvent *) {} + virtual void keyEvent(QKeyEvent *) {} +}; + +// Positionable text item +class TextItem : public Item { + Q_OBJECT +public: + explicit TextItem(const QString &text, const QRect &rect, const QColor &col, + QObject *parent = nullptr) + : Item(parent), m_text(text), m_rect(rect), m_col(col) {} + + void paint(QPainter &painter) override; + + QRect rect() const { return m_rect; } + +private: + const QString m_text; + const QRect m_rect; + const QColor m_col; +}; + +// "button" item +class ButtonItem : public TextItem { + Q_OBJECT +public: + explicit ButtonItem(const QString &text, const QRect &rect, const QColor &col, + QObject *parent = nullptr) + : TextItem(text, rect, col, parent), m_shortcut(0) {} + + void mouseEvent(QMouseEvent *mouseEvent) override; + void keyEvent(QKeyEvent *keyEvent) override; + + int shortcut() const { return m_shortcut; } + void setShortcut(int shortcut) { m_shortcut = shortcut; } + +signals: + void clicked(); + +private: + int m_shortcut; +}; + +#define PROPAGATE_EVENT(windowHandler, eventClass, itemHandler) \ +void windowHandler(eventClass *e) override \ +{ \ + foreach (Item *i, m_items) \ + i->itemHandler(e); \ +} + +class ItemWindow : public QRasterWindow { + Q_OBJECT +public: + explicit ItemWindow(QWindow *parent = nullptr) : QRasterWindow(parent), m_background(Qt::white) {} + + void addItem(Item *item) { m_items.append(item); } + + QColor background() const { return m_background; } + void setBackground(const QColor &background) { m_background = background; } + +protected: + void paintEvent(QPaintEvent *) override; + PROPAGATE_EVENT(mousePressEvent, QMouseEvent, mouseEvent) + PROPAGATE_EVENT(mouseReleaseEvent, QMouseEvent, mouseEvent) + PROPAGATE_EVENT(mouseDoubleClickEvent, QMouseEvent, mouseEvent) + PROPAGATE_EVENT(mouseMoveEvent, QMouseEvent, mouseEvent) + PROPAGATE_EVENT(keyPressEvent, QKeyEvent, keyEvent) + PROPAGATE_EVENT(keyReleaseEvent, QKeyEvent, keyEvent) + +private: + QList<Item *> m_items; + QColor m_background; +}; + +#endif // ITEMWINDOW_H diff --git a/tests/manual/embeddedintoforeignwindow/main.cpp b/tests/manual/embeddedintoforeignwindow/main.cpp new file mode 100644 index 0000000000..d7b33683a7 --- /dev/null +++ b/tests/manual/embeddedintoforeignwindow/main.cpp @@ -0,0 +1,287 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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$ +** +****************************************************************************/ + +#include "itemwindow.h" + +#include <QtGui/QGuiApplication> + +#include <QtCore/QCommandLineOption> +#include <QtCore/QCommandLineParser> +#include <QtCore/QDebug> +#include <QtCore/QStringList> + +#ifdef Q_OS_WIN +# include <qpa/qplatformnativeinterface.h> +# include <QtCore/QMetaObject> +# include <QtCore/qt_windows.h> +#endif + +#include <eventfilter.h> // diaglib +#include <qwindowdump.h> + +#include <iostream> + +QT_USE_NAMESPACE + +static const char usage[] = + "\nEmbeds a QWindow into a native foreign window passed on the command line.\n" + "When no window ID is passed, a test window is created (Windows only)."; + +static QString windowTitle() +{ + return QLatin1String(QT_VERSION_STR) + QLatin1Char(' ') + QGuiApplication::platformName(); +} + +#ifdef Q_OS_WIN +// Helper to create a native test window (Windows) +static QString registerWindowClass(const QString &name) +{ + QString result; + void *proc = DefWindowProc; + QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface(); + if (!QMetaObject::invokeMethod(ni, "registerWindowClass", Qt::DirectConnection, + Q_RETURN_ARG(QString, result), + Q_ARG(QString, name), + Q_ARG(void *, proc))) { + qWarning("registerWindowClass failed"); + } + return result; +} + +static HWND createNativeWindow(const QString &name) +{ + const HWND hwnd = + CreateWindowEx(0, reinterpret_cast<const wchar_t *>(name.utf16()), + L"NativeWindow", WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + 0, 0, GetModuleHandle(NULL), NULL); + + if (!hwnd) { + qErrnoWarning("Cannot create window \"%s\"", qPrintable(name)); + return 0; + } + + const QString text = windowTitle() + QLatin1String(" 0x") + QString::number(quint64(hwnd), 16); + SetWindowText(hwnd, reinterpret_cast<const wchar_t *>(text.utf16())); + return hwnd; +} +#endif // Q_OS_WIN + +// Helper functions for simple management of native windows. +static WId createNativeTestWindow() +{ + WId result = 0; +#ifdef Q_OS_WIN + const QString className = registerWindowClass(QLatin1String("TestClass") + windowTitle()); + const HWND nativeWin = createNativeWindow(className); + result = WId(nativeWin); +#else // Q_OS_WIN + Q_UNIMPLEMENTED(); +#endif + return result; +} + +static void showNativeWindow(WId wid) +{ +#ifdef Q_OS_WIN + ShowWindow(HWND(wid), SW_SHOW); +#else // Q_OS_WIN + Q_UNUSED(wid) + Q_UNIMPLEMENTED(); +#endif +} + +static void setFocusToNativeWindow(WId wid) +{ +#ifdef Q_OS_WIN + SetFocus(HWND(wid)); +#else // Q_OS_WIN + Q_UNUSED(wid) + Q_UNIMPLEMENTED(); +#endif +} + +static void destroyNativeWindow(WId wid) +{ +#ifdef Q_OS_WIN + DestroyWindow(HWND(wid)); +#else // Q_OS_WIN + Q_UNUSED(wid) + Q_UNIMPLEMENTED(); +#endif +} + +// Main test window to be embedded into foreign window with some buttons. +class EmbeddedTestWindow : public ItemWindow { + Q_OBJECT +public: + explicit EmbeddedTestWindow(QWindow *parent = nullptr) : ItemWindow(parent) + { + const int spacing = 10; + const QSize buttonSize(100, 30); + const int width = 3 * buttonSize.width() + 4 * spacing; + + QPoint pos(spacing, spacing); + addItem(new TextItem(::windowTitle(), QRect(pos, QSize(width - 2 * spacing, buttonSize.height())), + Qt::white)); + + pos.ry() += 2 * spacing + buttonSize.height(); + + ButtonItem *mgi = new ButtonItem("Map to global", QRect(pos, buttonSize), + QColor(Qt::yellow).lighter(), this); + connect(mgi, &ButtonItem::clicked, this, &EmbeddedTestWindow::testMapToGlobal); + addItem(mgi); + + pos.rx() += buttonSize.width() + spacing; + ButtonItem *di = new ButtonItem("Dump Wins", QRect(pos, buttonSize), + QColor(Qt::cyan).lighter(), this); + connect(di, &ButtonItem::clicked, this, [] () { QtDiag::dumpAllWindows(); }); + addItem(di); + + pos.rx() += buttonSize.width() + spacing; + ButtonItem *qi = new ButtonItem("Quit", QRect(pos, buttonSize), + QColor(Qt::red).lighter(), this); + qi->setShortcut(Qt::CTRL + Qt::Key_Q); + connect(qi, &ButtonItem::clicked, qApp, &QCoreApplication::quit); + addItem(qi); + + setBackground(Qt::lightGray); + resize(width, pos.y() + buttonSize.height() + spacing); + } + +public slots: + void testMapToGlobal(); +}; + +void EmbeddedTestWindow::testMapToGlobal() +{ + const QPoint globalPos = mapToGlobal(QPoint(0,0)); + qDebug() << "mapToGlobal(QPoint(0,0)" << globalPos + << "cursor at:" << QCursor::pos(); +} + +struct EventFilterOption +{ + const char *name; + const char *description; + QtDiag::EventFilter::EventCategories categories; +}; + +EventFilterOption eventFilterOptions[] = { +{"mouse-events", "Dump mouse events.", QtDiag::EventFilter::MouseEvents}, +{"keyboard-events", "Dump keyboard events.", QtDiag::EventFilter::KeyEvents}, +{"state-events", "Dump state/focus change events.", QtDiag::EventFilter::StateChangeEvents | QtDiag::EventFilter::FocusEvents} +}; + +static inline bool isOptionSet(int argc, char *argv[], const char *option) +{ + return (argv + argc) != + std::find_if(argv + 1, argv + argc, + [option] (const char *arg) { return !qstrcmp(arg, option); }); +} + +int main(int argc, char *argv[]) +{ + // Check for no scaling before QApplication is instantiated. + if (isOptionSet(argc, argv, "-s")) + QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); + QCoreApplication::setApplicationVersion(QLatin1String(QT_VERSION_STR)); + QGuiApplication::setApplicationDisplayName("Foreign Window Embedding Tester"); + + QGuiApplication app(argc, argv); + + // Process command line + QCommandLineParser parser; + parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); + parser.setApplicationDescription(QLatin1String(usage)); + parser.addHelpOption(); + parser.addVersionOption(); + QCommandLineOption noScalingDummy(QStringLiteral("s"), + QStringLiteral("Disable High DPI scaling.")); + parser.addOption(noScalingDummy); + const int eventFilterOptionCount = int(sizeof(eventFilterOptions) / sizeof(eventFilterOptions[0])); + for (int i = 0; i < eventFilterOptionCount; ++i) { + parser.addOption(QCommandLineOption(QLatin1String(eventFilterOptions[i].name), + QLatin1String(eventFilterOptions[i].description))); + } + parser.addPositionalArgument(QStringLiteral("[windows]"), QStringLiteral("Window ID.")); + + parser.process(QCoreApplication::arguments()); + + QtDiag::EventFilter::EventCategories eventCategories = 0; + for (int i = 0; i < eventFilterOptionCount; ++i) { + if (parser.isSet(QLatin1String(eventFilterOptions[i].name))) + eventCategories |= eventFilterOptions[i].categories; + } + if (eventCategories) + app.installEventFilter(new QtDiag::EventFilter(eventCategories, &app)); + + // Obtain foreign window to test with. + WId testForeignWinId = 0; + bool createdTestWindow = false; + if (parser.positionalArguments().isEmpty()) { + testForeignWinId = createNativeTestWindow(); + if (!testForeignWinId) + parser.showHelp(-1); + showNativeWindow(testForeignWinId); + createdTestWindow = true; + } else { + bool ok; + const QString &winIdArgument = parser.positionalArguments().constFirst(); + testForeignWinId = winIdArgument.toULongLong(&ok, 0); + if (!ok) { + std::cerr << "Invalid window id: \"" << qPrintable(winIdArgument) << "\"\n"; + return -1; + } + } + if (!testForeignWinId) + parser.showHelp(1); + + QWindow *foreignWindow = QWindow::fromWinId(testForeignWinId); + if (!foreignWindow) + return -2; + foreignWindow->setObjectName("ForeignWindow"); + EmbeddedTestWindow *embeddedTestWindow = new EmbeddedTestWindow(foreignWindow); + embeddedTestWindow->setObjectName("EmbeddedTestWindow"); + embeddedTestWindow->show(); + setFocusToNativeWindow(embeddedTestWindow->winId()); // Windows: Set keyboard focus. + + const int exitCode = app.exec(); + delete embeddedTestWindow; + delete foreignWindow; + if (createdTestWindow) + destroyNativeWindow(testForeignWinId); + return exitCode; +} + +#include "main.moc" diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro index 6f77c82dc5..b9789c354d 100644 --- a/tests/manual/manual.pro +++ b/tests/manual/manual.pro @@ -2,8 +2,10 @@ TEMPLATE=subdirs SUBDIRS = bearerex \ filetest \ +embeddedintoforeignwindow \ foreignwindows \ gestures \ +highdpi \ inputmethodhints \ keypadnavigation \ lance \ @@ -62,4 +64,4 @@ win32: SUBDIRS -= network_remote_stresstest network_stresstest lessThan(QT_MAJOR_VERSION, 5): SUBDIRS -= bearerex lance qnetworkaccessmanager/qget qmimedatabase qnetworkreply \ qpainfo qscreen socketengine xembed-raster xembed-widgets windowtransparency \ -foreignwindows +embeddedintoforeignwindow foreignwindows diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index fa282ea6e6..d8c27af884 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -2135,12 +2135,7 @@ void Configure::autoDetection() detectArch(); if (dictionary["C++STD"] == "auto" && !dictionary["QMAKESPEC"].contains("msvc")) { - if (!tryCompileProject("common/c++11")) { - dictionary["DONE"] = "error"; - cout << "ERROR: Qt requires a C++11 compiler and yours does not seem to be that." << endl - << "Please upgrade." << endl; - return; - } else if (!tryCompileProject("common/c++14")) { + if (!tryCompileProject("common/c++14")) { dictionary["C++STD"] = "c++11"; } else if (!tryCompileProject("common/c++1z")) { dictionary["C++STD"] = "c++14"; |