diff options
234 files changed, 2843 insertions, 1120 deletions
diff --git a/config.tests/qpa/eglfs-brcm/eglfs-brcm.cpp b/config.tests/qpa/eglfs-brcm/eglfs-brcm.cpp new file mode 100644 index 0000000000..a97fb510c7 --- /dev/null +++ b/config.tests/qpa/eglfs-brcm/eglfs-brcm.cpp @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the config.tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <EGL/egl.h> +#include <GLES2/gl2.h> +#include <bcm_host.h> + +int main(int, char **) +{ + EGLDisplay dpy = 0; + EGLContext ctx = 0; + eglDestroyContext(dpy, ctx); + vc_dispmanx_display_open(0); + return 0; +} diff --git a/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro b/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro new file mode 100644 index 0000000000..623726c9f3 --- /dev/null +++ b/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro @@ -0,0 +1,9 @@ +SOURCES = eglfs-brcm.cpp + +CONFIG -= qt + +INCLUDEPATH += $$[QT_SYSROOT]/opt/vc/include \ + $$[QT_SYSROOT]/opt/vc/include/interface/vcos/pthreads \ + $$[QT_SYSROOT]/opt/vc/include/interface/vmcs_host/linux + +LIBS += -L$$[QT_SYSROOT]/opt/vc/lib -lEGL -lGLESv2 -lbcm_host diff --git a/config.tests/qpa/eglfs-mali/eglfs-mali.cpp b/config.tests/qpa/eglfs-mali/eglfs-mali.cpp new file mode 100644 index 0000000000..8c1d33308d --- /dev/null +++ b/config.tests/qpa/eglfs-mali/eglfs-mali.cpp @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the config.tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <EGL/fbdev_window.h> +#include <EGL/egl.h> +#include <GLES2/gl2.h> + +int main(int, char **) +{ + EGLDisplay dpy = 0; + EGLContext ctx = 0; + fbdev_window *w = 0; + eglDestroyContext(dpy, ctx); + return 0; +} diff --git a/config.tests/qpa/eglfs-mali/eglfs-mali.pro b/config.tests/qpa/eglfs-mali/eglfs-mali.pro new file mode 100644 index 0000000000..132918c4bc --- /dev/null +++ b/config.tests/qpa/eglfs-mali/eglfs-mali.pro @@ -0,0 +1,5 @@ +SOURCES = eglfs-mali.cpp + +CONFIG -= qt + +LIBS += -lEGL -lGLESv2 diff --git a/config.tests/qpa/eglfs-viv/eglfs-viv.cpp b/config.tests/qpa/eglfs-viv/eglfs-viv.cpp new file mode 100644 index 0000000000..7b5b02541b --- /dev/null +++ b/config.tests/qpa/eglfs-viv/eglfs-viv.cpp @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the config.tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <EGL/egl.h> +#include <EGL/eglvivante.h> +#include <GLES2/gl2.h> + +int main(int, char **) +{ + fbGetDisplayByIndex(0); + return 0; +} diff --git a/config.tests/qpa/eglfs-viv/eglfs-viv.pro b/config.tests/qpa/eglfs-viv/eglfs-viv.pro new file mode 100644 index 0000000000..99776940ec --- /dev/null +++ b/config.tests/qpa/eglfs-viv/eglfs-viv.pro @@ -0,0 +1,6 @@ +SOURCES = eglfs-viv.cpp +DEFINES += LINUX=1 EGL_API_FB=1 + +CONFIG -= qt + +LIBS += -lEGL -lGLESv2 -lGAL @@ -5283,6 +5283,8 @@ if [ "$CFG_LIBINPUT" != "no" ] && [ "$CFG_LIBUDEV" != "no" ]; then else CFG_LIBINPUT=no fi +else + CFG_LIBINPUT=no fi if [ "$CFG_LIBINPUT" = "no" ]; then QMakeVar add DEFINES QT_NO_LIBINPUT @@ -5551,6 +5553,22 @@ fi if [ "$CFG_EGLFS" != "no" ]; then if [ "$XPLATFORM_QNX" = "no" ] && [ "$CFG_OPENGL" != "no" ]; then CFG_EGLFS="$CFG_EGL" + # Detect eglfs backends. + if compileTest qpa/eglfs-brcm "eglfs-brcm"; then + CFG_EGLFS_BRCM=yes + else + CFG_EGLFS_BRCM=no + fi + if compileTest qpa/eglfs-mali "eglfs-mali"; then + CFG_EGLFS_MALI=yes + else + CFG_EGLFS_MALI=no + fi + if compileTest qpa/eglfs-viv "eglfs-viv"; then + CFG_EGLFS_VIV=yes + else + CFG_EGLFS_VIV=no + fi else CFG_EGLFS="no" fi @@ -5962,6 +5980,16 @@ if [ "$CFG_EGLFS" = "yes" ]; then else QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_EGLFS" fi +# eglfs backends +if [ "$CFG_EGLFS_BRCM" = "yes" ]; then + QT_CONFIG="$QT_CONFIG eglfs_brcm" +fi +if [ "$CFG_EGLFS_MALI" = "yes" ]; then + QT_CONFIG="$QT_CONFIG eglfs_mali" +fi +if [ "$CFG_EGLFS_VIV" = "yes" ]; then + QT_CONFIG="$QT_CONFIG eglfs_viv" +fi # enable openvg if [ "$CFG_OPENVG" = "no" ]; then @@ -6996,7 +7024,11 @@ report_support " PulseAudio ............." "$CFG_PULSEAUDIO" report_support " QPA backends:" report_support " DirectFB ............." "$CFG_DIRECTFB" report_support " EGLFS ................" "$CFG_EGLFS" -report_support " KMS .................." "$CFG_KMS" +report_support " EGLFS i.MX6....... ." "$CFG_EGLFS_VIV" +report_support " EGLFS KMS .........." "$CFG_KMS" +report_support " EGLFS Mali ........." "$CFG_EGLFS_MALI" +report_support " EGLFS Raspberry Pi ." "$CFG_EGLFS_BRCM" +report_support " EGLFS X11 .........." "$CFG_EGL_X" report_support " LinuxFB .............." "$CFG_LINUXFB" report_support " XCB .................." "$CFG_XCB" system "system library" qt "bundled copy" if [ "$CFG_XCB" != "no" ]; then diff --git a/examples/widgets/itemviews/dirview/main.cpp b/examples/widgets/itemviews/dirview/main.cpp index bc1b8a5d7b..abca413325 100644 --- a/examples/widgets/itemviews/dirview/main.cpp +++ b/examples/widgets/itemviews/dirview/main.cpp @@ -39,25 +39,45 @@ ****************************************************************************/ #include <QApplication> +#include <QDesktopWidget> #include <QFileSystemModel> #include <QTreeView> +#include <QCommandLineParser> +#include <QCommandLineOption> int main(int argc, char *argv[]) { QApplication app(argc, argv); + QCoreApplication::setApplicationVersion(QT_VERSION_STR); + QCommandLineParser parser; + parser.setApplicationDescription("Qt Dir View Example"); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("directory", "The directory to start in."); + parser.process(app); + const QString rootPath = parser.positionalArguments().isEmpty() + ? QString() : parser.positionalArguments().first(); + QFileSystemModel model; model.setRootPath(""); QTreeView tree; tree.setModel(&model); + if (!rootPath.isEmpty()) { + const QModelIndex rootIndex = model.index(QDir::cleanPath(rootPath)); + if (rootIndex.isValid()) + tree.setRootIndex(rootIndex); + } // Demonstrating look and feel features tree.setAnimated(false); tree.setIndentation(20); tree.setSortingEnabled(true); + const QSize availableSize = QApplication::desktop()->availableGeometry(&tree).size(); + tree.resize(availableSize / 2); + tree.setColumnWidth(0, tree.width() / 3); tree.setWindowTitle(QObject::tr("Dir View")); - tree.resize(640, 480); tree.show(); return app.exec(); diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf index e334686b49..2fb2f4cc20 100644 --- a/mkspecs/android-g++/qmake.conf +++ b/mkspecs/android-g++/qmake.conf @@ -10,30 +10,6 @@ include(../common/gcc-base-unix.conf) load(device_config) -# Passing in -win32 to qmake (from NQTC) causes this condition to pass, however -# qmake complains that -win32 is deprecated; should find another way, Q_OS_WIN -# should really be all QMAKE_HOST.os needs to depend on? -contains(QMAKE_HOST.os,Windows) { - # Not having sh.exe in your path causes this condition to pass - # To build Android Qt on Windows, this block must not be evaluated. - isEmpty(QMAKE_SH) { - # Override values from previously loaded shell-unix.conf - # (via unix.conf, via linux.conf). - include(../common/shell-win32.conf) - QMAKE_DEL_TREE = rmdir /s /q - QMAKE_INSTALL_FILE = copy /y - QMAKE_INSTALL_PROGRAM = copy /y - } else { - MINGW_IN_SHELL = 1 - QMAKE_DIR_SEP = / - QMAKE_DIRLIST_SEP = : - # Because install's ability to set permissions is not relevant on Windows, - # and git's msys does not provide it to start with. - QMAKE_INSTALL_FILE = cp -f - QMAKE_INSTALL_PROGRAM = cp -f - } -} - NDK_ROOT = $$(ANDROID_NDK_ROOT) !exists($$NDK_ROOT) { NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT diff --git a/mkspecs/common/clang.conf b/mkspecs/common/clang.conf index e188f10200..a0a2b3f3d1 100644 --- a/mkspecs/common/clang.conf +++ b/mkspecs/common/clang.conf @@ -20,10 +20,12 @@ QMAKE_CFLAGS_ISYSTEM = -isystem QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} QMAKE_CFLAGS_USE_PRECOMPILE = -Xclang -include-pch -Xclang ${QMAKE_PCH_OUTPUT} QMAKE_CFLAGS_LTCG = -flto +QMAKE_CFLAGS_DISABLE_LTCG = -fno-lto QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG +QMAKE_CXXFLAGS_DISABLE_LTCG = $$QMAKE_CFLAGS_DISABLE_LTCG QMAKE_CXXFLAGS_CXX11 = -std=c++11 QMAKE_LFLAGS_CXX11 = diff --git a/mkspecs/common/gcc-base-mac.conf b/mkspecs/common/gcc-base-mac.conf index 43fa49c209..747f09ae81 100644 --- a/mkspecs/common/gcc-base-mac.conf +++ b/mkspecs/common/gcc-base-mac.conf @@ -10,7 +10,7 @@ include(gcc-base.conf) -QMAKE_COMPILER_DEFINES += __APPLE__ __GNUC__=4 +QMAKE_COMPILER_DEFINES += __APPLE__ __GNUC__=4 __APPLE_CC__ QMAKE_OBJECTIVE_CFLAGS = $$QMAKE_CFLAGS QMAKE_OBJECTIVE_CFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON diff --git a/mkspecs/common/gcc-base.conf b/mkspecs/common/gcc-base.conf index d21ee38fb7..ff89accace 100644 --- a/mkspecs/common/gcc-base.conf +++ b/mkspecs/common/gcc-base.conf @@ -50,6 +50,7 @@ QMAKE_CFLAGS_EXCEPTIONS_OFF += -fno-exceptions QMAKE_CFLAGS_SPLIT_SECTIONS += -ffunction-sections QMAKE_CFLAGS_LTCG = -flto -fno-fat-lto-objects QMAKE_CFLAGS_LTCG_FATOBJECTS = -ffat-lto-objects +QMAKE_CFLAGS_DISABLE_LTCG = -fno-lto QMAKE_CXXFLAGS += $$QMAKE_CFLAGS QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS @@ -66,6 +67,7 @@ QMAKE_CXXFLAGS_EXCEPTIONS_OFF += $$QMAKE_CFLAGS_EXCEPTIONS_OFF QMAKE_CXXFLAGS_SPLIT_SECTIONS += $$QMAKE_CFLAGS_SPLIT_SECTIONS QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG QMAKE_CXXFLAGS_LTCG_FATOBJECTS = $$QMAKE_CFLAGS_LTCG_FATOBJECTS +QMAKE_CXXFLAGS_DISABLE_LTCG = $$QMAKE_CFLAGS_DISABLE_LTCG QMAKE_LFLAGS += QMAKE_LFLAGS_DEBUG += diff --git a/mkspecs/common/linux.conf b/mkspecs/common/linux.conf index e10ab71cd6..8d6fb6fe17 100644 --- a/mkspecs/common/linux.conf +++ b/mkspecs/common/linux.conf @@ -51,7 +51,5 @@ QMAKE_RANLIB = QMAKE_STRIP = strip QMAKE_STRIPFLAGS_LIB += --strip-unneeded -QMAKE_INSTALL_FILE = install -m 644 -p -QMAKE_INSTALL_PROGRAM = install -m 755 -p include(unix.conf) diff --git a/mkspecs/common/shell-unix.conf b/mkspecs/common/shell-unix.conf index a533e77cb5..2ab932f7b8 100644 --- a/mkspecs/common/shell-unix.conf +++ b/mkspecs/common/shell-unix.conf @@ -1,14 +1 @@ -QMAKE_TAR = tar -cf -QMAKE_GZIP = gzip -9f - -QMAKE_COPY = cp -f -QMAKE_COPY_FILE = $$QMAKE_COPY -QMAKE_COPY_DIR = $$QMAKE_COPY -R -QMAKE_MOVE = mv -f -QMAKE_DEL_FILE = rm -f -QMAKE_DEL_DIR = rmdir -QMAKE_CHK_EXISTS = test -e %1 || -QMAKE_CHK_DIR_EXISTS = test -d # legacy -QMAKE_MKDIR = mkdir -p # legacy -QMAKE_MKDIR_CMD = test -d %1 || mkdir -p %1 -QMAKE_STREAM_EDITOR = sed +warning("shell-unix.conf is deprecated and has no effect.") diff --git a/mkspecs/common/shell-win32.conf b/mkspecs/common/shell-win32.conf index 1da8057c43..c6f3514697 100644 --- a/mkspecs/common/shell-win32.conf +++ b/mkspecs/common/shell-win32.conf @@ -1,17 +1 @@ -QMAKE_ZIP = zip -r -9 - -QMAKE_COPY = copy /y -QMAKE_COPY_DIR = xcopy /s /q /y /i -QMAKE_MOVE = move -QMAKE_DEL_FILE = del -QMAKE_DEL_DIR = rmdir -QMAKE_CHK_EXISTS = if not exist %1 -QMAKE_CHK_DIR_EXISTS = if not exist # legacy -QMAKE_MKDIR = mkdir # legacy -QMAKE_MKDIR_CMD = if not exist %1 mkdir %1 & if not exist %1 exit 1 -# Ugly hack to support cross-building for unix (android). -QMAKE_SYMBOLIC_LINK = $$QMAKE_COPY -QMAKE_LN_SHLIB = $$QMAKE_SYMBOLIC_LINK -# xcopy copies the contained files if source is a directory. Deal with it. -CONFIG += copy_dir_files -QMAKE_STREAM_EDITOR = $(QMAKE) -install sed +warning("shell-win32.conf is deprecated and has no effect.") diff --git a/mkspecs/common/unix.conf b/mkspecs/common/unix.conf index c0deafd141..2146b62f17 100644 --- a/mkspecs/common/unix.conf +++ b/mkspecs/common/unix.conf @@ -14,5 +14,3 @@ QMAKE_YACC_SOURCE = $base.tab.c QMAKE_PREFIX_SHLIB = lib QMAKE_PREFIX_STATICLIB = lib QMAKE_EXTENSION_STATICLIB = a - -include(shell-unix.conf) diff --git a/mkspecs/common/wince/qmake.conf b/mkspecs/common/wince/qmake.conf index 6e2e24dbd0..434e063de8 100644 --- a/mkspecs/common/wince/qmake.conf +++ b/mkspecs/common/wince/qmake.conf @@ -73,8 +73,6 @@ QMAKE_IDL = midl QMAKE_LIB = lib QMAKE_RC = rc -include(../shell-win32.conf) - VCPROJ_EXTENSION = .vcproj VCSOLUTION_EXTENSION = .sln VCPROJ_KEYWORD = Qt4VSv1.0 diff --git a/mkspecs/common/winrt_winphone/qmake.conf b/mkspecs/common/winrt_winphone/qmake.conf index 70bd0a3945..d71915408d 100644 --- a/mkspecs/common/winrt_winphone/qmake.conf +++ b/mkspecs/common/winrt_winphone/qmake.conf @@ -85,8 +85,6 @@ QMAKE_IDL = midl QMAKE_LIB = lib /NOLOGO QMAKE_RC = rc -include(../shell-win32.conf) - VCPROJ_EXTENSION = .vcxproj VCSOLUTION_EXTENSION = .sln VCPROJ_KEYWORD = Qt4VSv1.0 diff --git a/mkspecs/cygwin-g++/qmake.conf b/mkspecs/cygwin-g++/qmake.conf index 06135beb30..caed4133b1 100644 --- a/mkspecs/cygwin-g++/qmake.conf +++ b/mkspecs/cygwin-g++/qmake.conf @@ -73,5 +73,4 @@ QMAKE_OBJCOPY = objcopy QMAKE_NM = nm -P QMAKE_RANLIB = -include(../common/shell-unix.conf) load(qt_config) diff --git a/mkspecs/devices/linux-arm-hisilicon-hix5hd2-g++/qmake.conf b/mkspecs/devices/linux-arm-hisilicon-hix5hd2-g++/qmake.conf index 851d08600f..71ff90c9f8 100644 --- a/mkspecs/devices/linux-arm-hisilicon-hix5hd2-g++/qmake.conf +++ b/mkspecs/devices/linux-arm-hisilicon-hix5hd2-g++/qmake.conf @@ -18,7 +18,6 @@ # -prefix /home/abc/project/sysbase/qt_install include(../common/linux_device_pre.conf) -EGLFS_PLATFORM_HOOKS_SOURCES = $$PWD/qeglfshooks_hix5hd2.cpp QMAKE_INCDIR += /usr/arm-linux-gnueabihf/include QMAKE_LIBDIR += /usr/arm-linux-gnueabihf/lib @@ -39,6 +38,9 @@ DISTRO_OPTS += hard-float QMAKE_CFLAGS +=-march=armv7-a -mcpu=cortex-a9 -mfpu=vfpv3-d16 QMAKE_CXXFLAGS += $$QMAKE_CFLAGS +# Preferred eglfs backend +EGLFS_DEVICE_INTEGRATION = eglfs_mali + include(../common/linux_arm_device_post.conf) load(qt_config) diff --git a/mkspecs/devices/linux-imx6-g++/qmake.conf b/mkspecs/devices/linux-imx6-g++/qmake.conf index c8b6741e9a..1646c5fe77 100644 --- a/mkspecs/devices/linux-imx6-g++/qmake.conf +++ b/mkspecs/devices/linux-imx6-g++/qmake.conf @@ -4,8 +4,6 @@ include(../common/linux_device_pre.conf) -EGLFS_PLATFORM_HOOKS_SOURCES = $$PWD/qeglfshooks_imx6.cpp - QMAKE_INCDIR += $$[QT_SYSROOT]/usr/include QMAKE_LIBDIR += $$[QT_SYSROOT]/usr/lib @@ -21,6 +19,9 @@ QMAKE_CXXFLAGS += $$IMX6_CFLAGS DISTRO_OPTS += hard-float +# Preferred eglfs backend +EGLFS_DEVICE_INTEGRATION = eglfs_viv + include(../common/linux_arm_device_post.conf) load(qt_config) diff --git a/mkspecs/devices/linux-rasp-pi-g++/qmake.conf b/mkspecs/devices/linux-rasp-pi-g++/qmake.conf index 38e4b36cdd..20f8212f8f 100644 --- a/mkspecs/devices/linux-rasp-pi-g++/qmake.conf +++ b/mkspecs/devices/linux-rasp-pi-g++/qmake.conf @@ -36,8 +36,8 @@ QMAKE_CFLAGS += \ QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -EGLFS_PLATFORM_HOOKS_SOURCES = $$PWD/qeglfshooks_pi.cpp -EGLFS_PLATFORM_HOOKS_LIBS = -lbcm_host +# Preferred eglfs backend +EGLFS_DEVICE_INTEGRATION = eglfs_brcm include(../common/linux_arm_device_post.conf) diff --git a/mkspecs/devices/linux-rasp-pi2-g++/qmake.conf b/mkspecs/devices/linux-rasp-pi2-g++/qmake.conf new file mode 100644 index 0000000000..9be3f401ce --- /dev/null +++ b/mkspecs/devices/linux-rasp-pi2-g++/qmake.conf @@ -0,0 +1,26 @@ +# qmake configuration for the Raspberry Pi 2 + +include(../common/linux_device_pre.conf) + +QMAKE_LFLAGS += -Wl,-rpath-link,$$[QT_SYSROOT]/opt/vc/lib + +QMAKE_LIBDIR_OPENGL_ES2 = $$[QT_SYSROOT]/opt/vc/lib +QMAKE_LIBDIR_EGL = $$QMAKE_LIBDIR_OPENGL_ES2 + +QMAKE_INCDIR_EGL = $$[QT_SYSROOT]/opt/vc/include \ + $$[QT_SYSROOT]/opt/vc/include/interface/vcos/pthreads \ + $$[QT_SYSROOT]/opt/vc/include/interface/vmcs_host/linux +QMAKE_INCDIR_OPENGL_ES2 = $${QMAKE_INCDIR_EGL} + +QMAKE_LIBS_EGL = -lEGL -lGLESv2 +QMAKE_CFLAGS += -march=armv7-a -marm -mthumb-interwork -mfpu=neon-vfpv4 -mtune=cortex-a7 -mabi=aapcs-linux +QMAKE_CXXFLAGS = $$QMAKE_CFLAGS + +DISTRO_OPTS += hard-float + +# Preferred eglfs backend +EGLFS_DEVICE_INTEGRATION = eglfs_brcm + +include(../common/linux_arm_device_post.conf) + +load(qt_config) diff --git a/mkspecs/devices/linux-rasp-pi2-g++/qplatformdefs.h b/mkspecs/devices/linux-rasp-pi2-g++/qplatformdefs.h new file mode 100644 index 0000000000..5ae49b35dd --- /dev/null +++ b/mkspecs/devices/linux-rasp-pi2-g++/qplatformdefs.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** 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$ +** +****************************************************************************/ + +#include "../../linux-g++/qplatformdefs.h" diff --git a/mkspecs/features/mac/sdk.prf b/mkspecs/features/mac/sdk.prf index d2e698894f..e238f8e005 100644 --- a/mkspecs/features/mac/sdk.prf +++ b/mkspecs/features/mac/sdk.prf @@ -13,6 +13,14 @@ isEmpty(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.path) { QMAKE_MAC_SDK_PATH = $$eval(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.path) } +isEmpty(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.platform_path) { + QMAKE_MAC_SDK_PLATFORM_PATH = $$system("/usr/bin/xcodebuild -sdk $$QMAKE_MAC_SDK -version PlatformPath 2>/dev/null") + isEmpty(QMAKE_MAC_SDK_PLATFORM_PATH): error("Could not resolve SDK platform path for \'$$QMAKE_MAC_SDK\'") + cache(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.platform_path, set stash, QMAKE_MAC_SDK_PLATFORM_PATH) +} else { + QMAKE_MAC_SDK_PLATFORM_PATH = $$eval(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.platform_path) +} + isEmpty(QMAKE_MAC_SDK.$${QMAKE_MAC_SDK}.version) { QMAKE_MAC_SDK_VERSION = $$system("/usr/bin/xcodebuild -sdk $$QMAKE_MAC_SDK -version SDKVersion 2>/dev/null") isEmpty(QMAKE_MAC_SDK_VERSION): error("Could not resolve SDK version for \'$$QMAKE_MAC_SDK\'") diff --git a/mkspecs/features/simd.prf b/mkspecs/features/simd.prf index 7d9eaffafa..700d79a1b5 100644 --- a/mkspecs/features/simd.prf +++ b/mkspecs/features/simd.prf @@ -27,6 +27,7 @@ defineTest(addSimdCompiler) { CONFIG($$1) { cflags = $$eval(QMAKE_CFLAGS_$${upname}) + ltcg: cflags += $$QMAKE_CFLAGS_DISABLE_LTCG contains(QT_CPU_FEATURES, $$name) { # Default compiler settings include this feature, so just add to SOURCES SOURCES += $$eval($$sources_var) diff --git a/mkspecs/features/spec_post.prf b/mkspecs/features/spec_post.prf index b4f9ca47ae..c9578773fe 100644 --- a/mkspecs/features/spec_post.prf +++ b/mkspecs/features/spec_post.prf @@ -54,3 +54,65 @@ isEmpty(QMAKE_COMPILER) { warning("qmake spec does not announce the compiler family. Guessed $${QMAKE_COMPILER}.") } CONFIG += $$QMAKE_COMPILER + +equals(MAKEFILE_GENERATOR, MSBUILD) \ +|equals(MAKEFILE_GENERATOR, MSVC.NET) \ +|isEmpty(QMAKE_SH) { + QMAKE_ZIP = zip -r -9 + + QMAKE_COPY = copy /y + QMAKE_COPY_FILE = $$QMAKE_COPY + QMAKE_COPY_DIR = xcopy /s /q /y /i + # xcopy copies the contained files if source is a directory. Deal with it. + CONFIG += copy_dir_files + QMAKE_MOVE = move + QMAKE_DEL_FILE = del + QMAKE_DEL_DIR = rmdir + QMAKE_DEL_TREE = rmdir /s /q + QMAKE_CHK_EXISTS = if not exist %1 + QMAKE_CHK_DIR_EXISTS = if not exist # legacy + QMAKE_MKDIR = mkdir # legacy + QMAKE_MKDIR_CMD = if not exist %1 mkdir %1 & if not exist %1 exit 1 + QMAKE_STREAM_EDITOR = $(QMAKE) -install sed + QMAKE_INSTALL_FILE = copy /y + QMAKE_INSTALL_PROGRAM = copy /y +} else { + QMAKE_TAR = tar -cf + QMAKE_GZIP = gzip -9f + + QMAKE_COPY = cp -f + QMAKE_COPY_FILE = $$QMAKE_COPY + QMAKE_COPY_DIR = $$QMAKE_COPY -R + QMAKE_MOVE = mv -f + QMAKE_DEL_FILE = rm -f + QMAKE_DEL_DIR = rmdir + QMAKE_DEL_TREE = rm -rf + QMAKE_CHK_EXISTS = test -e %1 || + QMAKE_CHK_DIR_EXISTS = test -d # legacy + QMAKE_MKDIR = mkdir -p # legacy + QMAKE_MKDIR_CMD = test -d %1 || mkdir -p %1 + QMAKE_STREAM_EDITOR = sed + + equals(QMAKE_HOST.os, Windows) { + MINGW_IN_SHELL = 1 # legacy + # Override built-ins. + QMAKE_DIR_SEP = / + QMAKE_DIRLIST_SEP = : + # Because install's ability to set permissions is not relevant on Windows, + # and git's msys does not provide it to start with. + QMAKE_INSTALL_FILE = cp -f + QMAKE_INSTALL_PROGRAM = cp -f + } else { + QMAKE_INSTALL_FILE = install -m 644 -p + QMAKE_INSTALL_PROGRAM = install -m 755 -p + } +} +QMAKE_INSTALL_DIR = $$QMAKE_COPY_DIR +equals(QMAKE_HOST.os, Windows) { + # Ugly (and broken for relative paths) hack to support cross-building for Unix. + QMAKE_SYMBOLIC_LINK = $$QMAKE_COPY + QMAKE_LN_SHLIB = $$QMAKE_SYMBOLIC_LINK +} else { + QMAKE_SYMBOLIC_LINK = ln -f -s + QMAKE_LN_SHLIB = ln -s +} diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf index 770afa3386..c77f3b70ab 100644 --- a/mkspecs/features/testcase.prf +++ b/mkspecs/features/testcase.prf @@ -187,5 +187,11 @@ contains(INSTALLS, target) { } } +macx-xcode:bundle:isEmpty(QMAKE_BUNDLE_EXTENSION) { + QMAKE_PBX_PRODUCT_TYPE = com.apple.product-type.bundle.unit-test + QMAKE_PBX_BUNDLE_TYPE = wrapper.cfbundle + QMAKE_BUNDLE_EXTENSION = .xctest +} + } # have_target diff --git a/mkspecs/hurd-g++/qmake.conf b/mkspecs/hurd-g++/qmake.conf index d53b49ced2..e7e4e3a82d 100644 --- a/mkspecs/hurd-g++/qmake.conf +++ b/mkspecs/hurd-g++/qmake.conf @@ -45,8 +45,6 @@ QMAKE_RANLIB = QMAKE_STRIP = strip QMAKE_STRIPFLAGS_LIB += --strip-unneeded -QMAKE_INSTALL_FILE = install -m 644 -p -QMAKE_INSTALL_PROGRAM = install -m 755 -p include(../common/unix.conf) include(../common/gcc-base-unix.conf) diff --git a/mkspecs/macx-ios-clang/features/default_post.prf b/mkspecs/macx-ios-clang/features/default_post.prf index f1f23dd716..f9a8921a09 100644 --- a/mkspecs/macx-ios-clang/features/default_post.prf +++ b/mkspecs/macx-ios-clang/features/default_post.prf @@ -1,14 +1,5 @@ -# In case the user sets the SDK manually -contains(QMAKE_MAC_SDK, ^iphonesimulator.*) { - iphonesimulator_and_iphoneos: \ - error("iOS simulator is handled automatically for iphonesimulator_and_iphoneos") - - CONFIG += iphonesimulator -} - -iphonesimulator_and_iphoneos:iphonesimulator: \ - QMAKE_MAC_SDK ~= s,^iphoneos,iphonesimulator, +load(sdk) # Resolve config so we don't need to use CONFIG() later on CONFIG(iphonesimulator, iphonesimulator|iphoneos) { @@ -76,8 +67,8 @@ equals(TEMPLATE, app) { args += $$system_quote($$arg) system("cd $$system_quote($$OUT_PWD) && $$QMAKE_QMAKE $$args $$system_quote($$_PRO_FILE_) -spec macx-xcode") - check.commands = "$(MAKE) -f $(MAKEFILE).ReleaseSimulator xcode_build_check" - QMAKE_EXTRA_TARGETS += check + # We have a target, even though our template is aux + CONFIG += have_target } else { load(resolve_config) @@ -92,10 +83,13 @@ equals(TEMPLATE, app) { else: \ cfg = release - for(action, $$list(build install clean)) { + for(action, $$list(build install clean test)) { equals(action, build) { action_target_suffix = action_target = all + } else: equals(action, test) { + action_target_suffix = -check + action_target = check } else { action_target_suffix = -$$action action_target = $$action @@ -103,7 +97,7 @@ equals(TEMPLATE, app) { target = $${sdk}-$${cfg}$${action_target_suffix} - $${target}.commands = "@bash -o pipefail -c 'xcodebuild $$action -sdk $$sdk -configuration $$title($$cfg) | grep -v setenv'" + $${target}.commands = "@bash -o pipefail -c 'xcodebuild $$action -scheme $(TARGET) -sdk $$sdk -configuration $$title($$cfg) | grep -v setenv'" QMAKE_EXTRA_TARGETS += $$target $${action_target}.depends += $$target @@ -115,12 +109,7 @@ equals(TEMPLATE, app) { QMAKE_EXTRA_TARGETS += xcode_build_dir_distclean distclean.depends = xcode_build_dir_distclean QMAKE_EXTRA_TARGETS += distclean - - xcode_build_check.commands = "$(TESTRUNNER) $$title($$cfg)-$${sdk}/$(TARGET).app $(TESTARGS)" - QMAKE_EXTRA_TARGETS += xcode_build_check } - - CONFIG = } } } else: equals(TEMPLATE, lib) { diff --git a/mkspecs/macx-ios-clang/features/qt.prf b/mkspecs/macx-ios-clang/features/qt.prf index 7ca3198dbe..697eb0ed60 100644 --- a/mkspecs/macx-ios-clang/features/qt.prf +++ b/mkspecs/macx-ios-clang/features/qt.prf @@ -1,5 +1,6 @@ -equals(TEMPLATE, app):contains(QT, gui(-private)?) { +qt_depends = $$resolve_depends(QT, "QT.") +equals(TEMPLATE, app):contains(qt_depends, gui(-private)?) { LIBS *= -L$$[QT_INSTALL_PLUGINS/get]/platforms lib_name = qios diff --git a/mkspecs/macx-ios-clang/features/sdk.prf b/mkspecs/macx-ios-clang/features/sdk.prf index 607a71bb26..32fcbb7289 100644 --- a/mkspecs/macx-ios-clang/features/sdk.prf +++ b/mkspecs/macx-ios-clang/features/sdk.prf @@ -1,4 +1,33 @@ +# In case the user sets the SDK manually +contains(QMAKE_MAC_SDK, ^iphonesimulator.*) { + iphonesimulator_and_iphoneos: \ + error("iOS simulator is handled automatically for iphonesimulator_and_iphoneos") + + CONFIG += iphonesimulator +} + +iphonesimulator_and_iphoneos:iphonesimulator: \ + QMAKE_MAC_SDK ~= s,^iphoneos,iphonesimulator, + load(sdk) lessThan(QMAKE_MAC_SDK_VERSION, "8.0"): \ error("Current $$QMAKE_MAC_SDK SDK version ($$QMAKE_MAC_SDK_VERSION) is too old. Please upgrade Xcode.") + +macx-xcode { + sdk_path_iphoneos.name = "QMAKE_MAC_SDK_PATH[sdk=iphoneos*]" + sdk_path_iphoneos.value = $$QMAKE_MAC_SDK_PATH + QMAKE_MAC_SDK_PATH ~= s,iPhoneOS,iPhoneSimulator, + sdk_path_iphonesimulator.name = "QMAKE_MAC_SDK_PATH[sdk=iphonesimulator*]" + sdk_path_iphonesimulator.value = $$QMAKE_MAC_SDK_PATH + QMAKE_MAC_XCODE_SETTINGS += sdk_path_iphoneos sdk_path_iphonesimulator + QMAKE_MAC_SDK_PATH = "$(QMAKE_MAC_SDK_PATH)" + + sdk_platform_path_iphoneos.name = "QMAKE_MAC_SDK_PLATFORM_PATH[sdk=iphoneos*]" + sdk_platform_path_iphoneos.value = $$QMAKE_MAC_SDK_PLATFORM_PATH + QMAKE_MAC_SDK_PLATFORM_PATH ~= s,iPhoneOS,iPhoneSimulator, + sdk_platform_path_iphonesimulator.name = "QMAKE_MAC_SDK_PLATFORM_PATH[sdk=iphonesimulator*]" + sdk_platform_path_iphonesimulator.value = $$QMAKE_MAC_SDK_PLATFORM_PATH + QMAKE_MAC_XCODE_SETTINGS += sdk_platform_path_iphoneos sdk_platform_path_iphonesimulator + QMAKE_MAC_SDK_PLATFORM_PATH = "$(QMAKE_MAC_SDK_PLATFORM_PATH)" +} diff --git a/mkspecs/macx-xcode/WorkspaceSettings.xcsettings b/mkspecs/macx-xcode/WorkspaceSettings.xcsettings new file mode 100644 index 0000000000..08de0be8d3 --- /dev/null +++ b/mkspecs/macx-xcode/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key> + <false/> +</dict> +</plist> diff --git a/mkspecs/macx-xcode/default.xcscheme b/mkspecs/macx-xcode/default.xcscheme new file mode 100644 index 0000000000..53c736cc15 --- /dev/null +++ b/mkspecs/macx-xcode/default.xcscheme @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Scheme + LastUpgradeVersion = "0610" + version = "1.3"> + <BuildAction + parallelizeBuildables = "YES" + buildImplicitDependencies = "YES"> + <BuildActionEntries> + <BuildActionEntry + buildForTesting = "YES" + buildForRunning = "YES" + buildForProfiling = "YES" + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "@TARGET_PBX_KEY@" + BuildableName = "@QMAKE_ORIG_TARGET@" + BlueprintName = "@QMAKE_ORIG_TARGET@" + ReferencedContainer = "container:@QMAKE_ORIG_TARGET@.xcodeproj"> + </BuildableReference> + </BuildActionEntry> + </BuildActionEntries> + </BuildAction> + <TestAction + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES" + buildConfiguration = "Debug"> + <Testables> + <TestableReference + skipped = "NO"> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "@TARGET_PBX_KEY@" + BuildableName = "@QMAKE_ORIG_TARGET@" + BlueprintName = "@QMAKE_ORIG_TARGET@" + ReferencedContainer = "container:@QMAKE_ORIG_TARGET@.xcodeproj"> + </BuildableReference> + </TestableReference> + </Testables> + <MacroExpansion> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "@TARGET_PBX_KEY@" + BuildableName = "@QMAKE_ORIG_TARGET@" + BlueprintName = "@QMAKE_ORIG_TARGET@" + ReferencedContainer = "container:@QMAKE_ORIG_TARGET@.xcodeproj"> + </BuildableReference> + </MacroExpansion> + </TestAction> + <LaunchAction + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + launchStyle = "0" + useCustomWorkingDirectory = "NO" + buildConfiguration = "Debug" + ignoresPersistentStateOnLaunch = "NO" + debugDocumentVersioning = "YES" + allowLocationSimulation = "YES"> + <BuildableProductRunnable> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "@TARGET_PBX_KEY@" + BuildableName = "@QMAKE_ORIG_TARGET@" + BlueprintName = "@QMAKE_ORIG_TARGET@" + ReferencedContainer = "container:@QMAKE_ORIG_TARGET@.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + <AdditionalOptions> + </AdditionalOptions> + </LaunchAction> + <ProfileAction + shouldUseLaunchSchemeArgsEnv = "YES" + savedToolIdentifier = "" + useCustomWorkingDirectory = "NO" + buildConfiguration = "Release" + debugDocumentVersioning = "YES"> + <BuildableProductRunnable> + <BuildableReference + BuildableIdentifier = "primary" + BlueprintIdentifier = "@TARGET_PBX_KEY@" + BuildableName = "@QMAKE_ORIG_TARGET@" + BlueprintName = "@QMAKE_ORIG_TARGET@" + ReferencedContainer = "container:@QMAKE_ORIG_TARGET@.xcodeproj"> + </BuildableReference> + </BuildableProductRunnable> + </ProfileAction> + <AnalyzeAction + buildConfiguration = "Debug"> + </AnalyzeAction> + <ArchiveAction + buildConfiguration = "Release" + revealArchiveInOrganizer = "YES"> + </ArchiveAction> +</Scheme> diff --git a/mkspecs/macx-xcode/qmake.conf b/mkspecs/macx-xcode/qmake.conf index fde682b64b..6fc6160ec7 100644 --- a/mkspecs/macx-xcode/qmake.conf +++ b/mkspecs/macx-xcode/qmake.conf @@ -6,6 +6,8 @@ QMAKESPEC = $$dirname(PWD)/$$[QMAKE_XSPEC] +QMAKE_XCODE_SPECDIR = $$PWD + include($$QMAKESPEC/qmake.conf) MAKEFILE_GENERATOR = XCODE diff --git a/mkspecs/unsupported/linux-host-g++/qmake.conf b/mkspecs/unsupported/linux-host-g++/qmake.conf index 3dc490d6dd..1523126eaa 100644 --- a/mkspecs/unsupported/linux-host-g++/qmake.conf +++ b/mkspecs/unsupported/linux-host-g++/qmake.conf @@ -109,8 +109,6 @@ QMAKE_RANLIB = QMAKE_STRIP = host-strip QMAKE_STRIPFLAGS_LIB += --strip-unneeded -QMAKE_INSTALL_FILE = install -m 644 -p -QMAKE_INSTALL_PROGRAM = install -m 755 -p include(../../common/unix.conf) load(qt_config) diff --git a/mkspecs/unsupported/vxworks-ppc-dcc/qmake.conf b/mkspecs/unsupported/vxworks-ppc-dcc/qmake.conf index 814b844131..a4cf23df9c 100644 --- a/mkspecs/unsupported/vxworks-ppc-dcc/qmake.conf +++ b/mkspecs/unsupported/vxworks-ppc-dcc/qmake.conf @@ -87,8 +87,6 @@ QMAKE_RANLIB = QMAKE_STRIP = strip QMAKE_STRIPFLAGS_LIB += --strip-unneeded -QMAKE_INSTALL_FILE = install -m 644 -p -QMAKE_INSTALL_PROGRAM = install -m 755 -p include(../../common/unix.conf) load(qt_config) diff --git a/mkspecs/unsupported/vxworks-simpentium-dcc/qmake.conf b/mkspecs/unsupported/vxworks-simpentium-dcc/qmake.conf index c362d098db..49f0c21d4a 100644 --- a/mkspecs/unsupported/vxworks-simpentium-dcc/qmake.conf +++ b/mkspecs/unsupported/vxworks-simpentium-dcc/qmake.conf @@ -86,8 +86,6 @@ QMAKE_RANLIB = QMAKE_STRIP = strip QMAKE_STRIPFLAGS_LIB += --strip-unneeded -QMAKE_INSTALL_FILE = install -m 644 -p -QMAKE_INSTALL_PROGRAM = install -m 755 -p include(../../common/unix.conf) load(qt_config) diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index 9f0188be80..c6ff808a99 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -93,19 +93,6 @@ QMAKE_LIBS_OPENGL_ES2_DEBUG = -llibEGLd -llibGLESv2d -lgdi32 -luser32 QMAKE_LIBS_COMPAT = -ladvapi32 -lshell32 -lcomdlg32 -luser32 -lgdi32 -lws2_32 QMAKE_LIBS_QT_ENTRY = -lmingw32 -lqtmain -!isEmpty(QMAKE_SH) { - MINGW_IN_SHELL = 1 - QMAKE_DIR_SEP = / - QMAKE_DIRLIST_SEP = : - include(../common/shell-unix.conf) - # Because install's ability to set permissions is not relevant on Windows, - # and git's msys does not provide it to start with. - QMAKE_INSTALL_FILE = cp -f - QMAKE_INSTALL_PROGRAM = cp -f -} else { - include(../common/shell-win32.conf) -} - QMAKE_IDL = midl QMAKE_LIB = $${CROSS_COMPILE}ar -ru QMAKE_RC = $${CROSS_COMPILE}windres diff --git a/mkspecs/win32-icc/qmake.conf b/mkspecs/win32-icc/qmake.conf index d326cdeee3..2ec0d84918 100644 --- a/mkspecs/win32-icc/qmake.conf +++ b/mkspecs/win32-icc/qmake.conf @@ -79,7 +79,5 @@ QMAKE_IDL = midl QMAKE_LIB = xilib /NOLOGO QMAKE_RC = rc -include(../common/shell-win32.conf) - DSP_EXTENSION = .dsp load(qt_config) diff --git a/mkspecs/win32-msvc2005/qmake.conf b/mkspecs/win32-msvc2005/qmake.conf index ca901effd3..458f37cc04 100644 --- a/mkspecs/win32-msvc2005/qmake.conf +++ b/mkspecs/win32-msvc2005/qmake.conf @@ -7,5 +7,4 @@ MSC_VER = 1400 MSVC_VER = 8.0 include(../common/msvc-desktop.conf) -include(../common/shell-win32.conf) load(qt_config) diff --git a/mkspecs/win32-msvc2008/qmake.conf b/mkspecs/win32-msvc2008/qmake.conf index 1a04c9952b..d1382ff2d4 100644 --- a/mkspecs/win32-msvc2008/qmake.conf +++ b/mkspecs/win32-msvc2008/qmake.conf @@ -7,5 +7,4 @@ MSC_VER = 1500 MSVC_VER = 9.0 include(../common/msvc-desktop.conf) -include(../common/shell-win32.conf) load(qt_config) diff --git a/mkspecs/win32-msvc2010/qmake.conf b/mkspecs/win32-msvc2010/qmake.conf index 8160001a4b..3ad9d478ee 100644 --- a/mkspecs/win32-msvc2010/qmake.conf +++ b/mkspecs/win32-msvc2010/qmake.conf @@ -7,5 +7,4 @@ MSC_VER = 1600 MSVC_VER = 10.0 include(../common/msvc-desktop.conf) -include(../common/shell-win32.conf) load(qt_config) diff --git a/mkspecs/win32-msvc2012/qmake.conf b/mkspecs/win32-msvc2012/qmake.conf index 57161071c8..3d9c5864af 100644 --- a/mkspecs/win32-msvc2012/qmake.conf +++ b/mkspecs/win32-msvc2012/qmake.conf @@ -7,5 +7,4 @@ MSC_VER = 1700 MSVC_VER = 11.0 include(../common/msvc-desktop.conf) -include(../common/shell-win32.conf) load(qt_config) diff --git a/mkspecs/win32-msvc2013/qmake.conf b/mkspecs/win32-msvc2013/qmake.conf index ece04203ea..34108b2c32 100644 --- a/mkspecs/win32-msvc2013/qmake.conf +++ b/mkspecs/win32-msvc2013/qmake.conf @@ -7,5 +7,4 @@ MSC_VER = 1800 MSVC_VER = 12.0 include(../common/msvc-desktop.conf) -include(../common/shell-win32.conf) load(qt_config) diff --git a/mkspecs/win32-msvc2015/qmake.conf b/mkspecs/win32-msvc2015/qmake.conf index 617adb681c..ea654d4296 100644 --- a/mkspecs/win32-msvc2015/qmake.conf +++ b/mkspecs/win32-msvc2015/qmake.conf @@ -7,5 +7,4 @@ MSC_VER = 1900 MSVC_VER = 14.0 include(../common/msvc-desktop.conf) -include(../common/shell-win32.conf) load(qt_config) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 610bf0cca5..27399c1a1e 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -2556,18 +2556,64 @@ \li The unique ID of the app. Defaults to reusing the existing generated manifest's UUID, or generates a new UUID if none is present. \row + \li logo_30x30 + \li Logo image file of size 30x30 pixels. This is not supported on Windows Phone. + \row + \li logo_41x41 + \li Logo image file of size 41x41 pixels. This is only supported on Windows Phone. + \row + \li logo_70x70 + \li Logo image file of size 70x70 pixels. This is not supported on Windows Phone. + \row + \li logo_71x71 + \li Logo image file of size 71x71 pixels. This is only supported on Windows Phone. + \row + \li logo_150x150 + \li Logo image file of size 150x150 pixels. This is supported on all Windows + Store App platforms. + \row + \li logo_310x150 + \li Logo image file of size 310x150 pixels. This is supported on all Windows + Store App platforms. + \row + \li logo_310x310 + \li Logo image file of size 310x310 pixels. This is supported on all Windows + Store App platforms. + \row + \li logo_620x300 + \li Splash screen image file of size 620x300 pixels. This is not supported on + Windows Phone. + \row + \li logo_480x800 + \li Splash sceen image file of size 480x800 pixels. This is only supported on + Windows Phone. + \row \li logo_large - \li Large logo image file. Default provided by the mkspec. + \li Large logo image file. This has to be 150x150 pixels. Supported on all + Windows Store App platforms. Default provided by the mkspec. \row \li logo_medium - \li Medium logo image file. Default provided by the mkspec. + \li Medium logo image file. For Windows Phone the image must have a pixel size + of 71x71, for other Windows Store App platforms 70x70. Default provided by + the mkspec. \row \li logo_small - \li Small logo image file. Default provided by the mkspec. + \li Small logo image file. For Windows Phone the image must have a pixel size + of 44x44, for other Windows Store App platforms 30x30. Default provided by + the mkspec. + \row + \li logo_splash + \li Splash screen image file. For Windows Phone the image must have a pixel size + of 480x800, for other Windows Store App platforms 620x300. Default provided + by the mkspec. \row \li logo_store \li Logo image file for Windows Store. Default provided by the mkspec. \row + \li logo_wide + \li Wide logo image file. This has to be 310x150 pixels. Supported on all + Windows Store App platforms. Default provided by the mkspec. + \row \li name \li The name of the package as displayed to the user. Defaults to TARGET. \row @@ -2583,9 +2629,6 @@ \li publisher_id \li The publisher's distinguished name (default: \c{CN=MyCN}). \row - \li splash_screen - \li Splash screen image file. Default provided by the mkspec. - \row \li target \li The name of the target (.exe). Defaults to TARGET. \row @@ -2612,6 +2655,10 @@ WINRT_MANIFEST = someManifest.xml.in \endcode + \note The required image sizes of \e logo_small, \e logo_medium, and \e logo_large + depend on the target platform. The general descriptions are overwritten if a + description that specifies the size is provided. + \target YACCSOURCES \section1 YACCSOURCES diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 36ec6ef742..e2b5f5f90b 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -1573,6 +1573,52 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) } } + // Scheme + { + QString xcodeSpecDir = project->first("QMAKE_XCODE_SPECDIR").toQString(); + + bool wroteCustomScheme = false; + + QString projectSharedSchemesPath = pbx_dir + "/xcshareddata/xcschemes"; + if (mkdir(projectSharedSchemesPath)) { + QString target = project->first("QMAKE_ORIG_TARGET").toQString(); + + QFile defaultSchemeFile(xcodeSpecDir + "/default.xcscheme"); + QFile outputSchemeFile(projectSharedSchemesPath + Option::dir_sep + target + ".xcscheme"); + + if (defaultSchemeFile.open(QIODevice::ReadOnly) + && outputSchemeFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + + QTextStream defaultSchemeStream(&defaultSchemeFile); + QString schemeData = defaultSchemeStream.readAll(); + + schemeData.replace("@QMAKE_ORIG_TARGET@", target); + schemeData.replace("@TARGET_PBX_KEY@", keyFor(pbx_dir + "QMAKE_PBX_TARGET")); + + QTextStream outputSchemeStream(&outputSchemeFile); + outputSchemeStream << schemeData; + + wroteCustomScheme = true; + } + } + + if (wroteCustomScheme) { + // Prevent Xcode from auto-generating schemes + QString workspaceSettingsFilename("WorkspaceSettings.xcsettings"); + QString workspaceSharedDataPath = pbx_dir + "/project.xcworkspace/xcshareddata"; + if (mkdir(workspaceSharedDataPath)) { + QFile::copy(xcodeSpecDir + Option::dir_sep + workspaceSettingsFilename, + workspaceSharedDataPath + Option::dir_sep + workspaceSettingsFilename); + } else { + wroteCustomScheme = false; + } + } + + if (!wroteCustomScheme) + warn_msg(WarnLogic, "Failed to generate schemes in '%s', " \ + "falling back to Xcode auto-generated schemes", qPrintable(projectSharedSchemesPath)); + } + qmake_setpwd(input_dir); return true; diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index 3a76d898ed..efea807209 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -58,22 +58,8 @@ UnixMakefileGenerator::init() project->values("ICON") = project->values("RC_FILE"); if(project->isEmpty("QMAKE_EXTENSION_PLUGIN")) project->values("QMAKE_EXTENSION_PLUGIN").append(project->first("QMAKE_EXTENSION_SHLIB")); - if(project->isEmpty("QMAKE_COPY_FILE")) - project->values("QMAKE_COPY_FILE").append("$(COPY)"); - if(project->isEmpty("QMAKE_STREAM_EDITOR")) - project->values("QMAKE_STREAM_EDITOR").append("sed"); - if(project->isEmpty("QMAKE_COPY_DIR")) - project->values("QMAKE_COPY_DIR").append("$(COPY) -R"); - if(project->isEmpty("QMAKE_INSTALL_FILE")) - project->values("QMAKE_INSTALL_FILE").append("$(COPY_FILE)"); - if(project->isEmpty("QMAKE_INSTALL_DIR")) - project->values("QMAKE_INSTALL_DIR").append("$(COPY_DIR)"); - if(project->isEmpty("QMAKE_INSTALL_PROGRAM")) - project->values("QMAKE_INSTALL_PROGRAM").append("$(COPY_FILE)"); if(project->isEmpty("QMAKE_LIBTOOL")) project->values("QMAKE_LIBTOOL").append("libtool --silent"); - if(project->isEmpty("QMAKE_SYMBOLIC_LINK")) - project->values("QMAKE_SYMBOLIC_LINK").append("ln -f -s"); project->values("QMAKE_ORIG_TARGET") = project->values("TARGET"); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index c14395ae27..9d666509fd 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -1298,8 +1298,6 @@ void UnixMakefileGenerator::init2() else project->values("TARGET") = project->values("TARGET_x.y.z"); } - if(project->isEmpty("QMAKE_LN_SHLIB")) - project->values("QMAKE_LN_SHLIB").append("ln -s"); if (!project->values("QMAKE_LFLAGS_SONAME").isEmpty()) { ProString soname; if(project->isActiveConfig("plugin")) { diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index af5e62330e..c19e17bc0e 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -232,16 +232,6 @@ void MingwMakefileGenerator::init() project->values("QMAKE_LIB_FLAG").append("1"); else if(project->first("TEMPLATE") == "subdirs") { MakefileGenerator::init(); - if(project->isEmpty("QMAKE_COPY_FILE")) - project->values("QMAKE_COPY_FILE").append("$(COPY)"); - if(project->isEmpty("QMAKE_COPY_DIR")) - project->values("QMAKE_COPY_DIR").append("xcopy /s /q /y /i"); - if(project->isEmpty("QMAKE_INSTALL_FILE")) - project->values("QMAKE_INSTALL_FILE").append("$(COPY_FILE)"); - if(project->isEmpty("QMAKE_INSTALL_PROGRAM")) - project->values("QMAKE_INSTALL_PROGRAM").append("$(COPY_FILE)"); - if(project->isEmpty("QMAKE_INSTALL_DIR")) - project->values("QMAKE_INSTALL_DIR").append("$(COPY_DIR)"); if(project->values("MAKEFILE").isEmpty()) project->values("MAKEFILE").append("Makefile"); return; diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index ae888cb96d..c719aa4cbf 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -340,16 +340,6 @@ void NmakeMakefileGenerator::init() MakefileGenerator::init(); if(project->values("MAKEFILE").isEmpty()) project->values("MAKEFILE").append("Makefile"); - if(project->isEmpty("QMAKE_COPY_FILE")) - project->values("QMAKE_COPY_FILE").append("$(COPY)"); - if(project->isEmpty("QMAKE_COPY_DIR")) - project->values("QMAKE_COPY_DIR").append("xcopy /s /q /y /i"); - if(project->isEmpty("QMAKE_INSTALL_FILE")) - project->values("QMAKE_INSTALL_FILE").append("$(COPY_FILE)"); - if(project->isEmpty("QMAKE_INSTALL_PROGRAM")) - project->values("QMAKE_INSTALL_PROGRAM").append("$(COPY_FILE)"); - if(project->isEmpty("QMAKE_INSTALL_DIR")) - project->values("QMAKE_INSTALL_DIR").append("$(COPY_DIR)"); return; } diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index ad6a19e5df..6ea129f82c 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -280,19 +280,6 @@ void Win32MakefileGenerator::processVars() && !project->values("VER_MAJ").isEmpty()) project->values("TARGET_VERSION_EXT").append(project->first("VER_MAJ")); - if(project->isEmpty("QMAKE_COPY_FILE")) - project->values("QMAKE_COPY_FILE").append("$(COPY)"); - if(project->isEmpty("QMAKE_COPY_DIR")) - project->values("QMAKE_COPY_DIR").append("xcopy /s /q /y /i"); - if (project->isEmpty("QMAKE_STREAM_EDITOR")) - project->values("QMAKE_STREAM_EDITOR").append("$(QMAKE) -install sed"); - if(project->isEmpty("QMAKE_INSTALL_FILE")) - project->values("QMAKE_INSTALL_FILE").append("$(COPY_FILE)"); - if(project->isEmpty("QMAKE_INSTALL_PROGRAM")) - project->values("QMAKE_INSTALL_PROGRAM").append("$(COPY_FILE)"); - if(project->isEmpty("QMAKE_INSTALL_DIR")) - project->values("QMAKE_INSTALL_DIR").append("$(COPY_DIR)"); - fixTargetExt(); processRcFileVar(); 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 dc80689f63..93d7baabdb 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -866,8 +866,8 @@ public class QtActivityDelegate while (itr.hasNext()) m_activity.runOnUiThread(itr.next()); + QtNative.updateApplicationState(ApplicationActive); if (m_started) { - QtNative.updateApplicationState(ApplicationActive); QtNative.clearLostActions(); QtNative.updateWindow(); updateFullScreen(); // Suspending the app clears the immersive mode, so we need to set it again. diff --git a/src/concurrent/doc/src/qtconcurrent-index.qdoc b/src/concurrent/doc/src/qtconcurrent-index.qdoc index 2a4720a9a3..2157280021 100644 --- a/src/concurrent/doc/src/qtconcurrent-index.qdoc +++ b/src/concurrent/doc/src/qtconcurrent-index.qdoc @@ -50,25 +50,25 @@ \list - \li QtConcurrent::map() applies a function to every item in a container, + \li \l {QtConcurrent::map}{QtConcurrent::map()} applies a function to every item in a container, modifying the items in-place. - \li QtConcurrent::mapped() is like map(), except that it returns a new + \li \l {QtConcurrent::mapped}{QtConcurrent::mapped()} is like map(), except that it returns a new container with the modifications. - \li QtConcurrent::mappedReduced() is like mapped(), except that the + \li \l {QtConcurrent::mappedReduced}{QtConcurrent::mappedReduced()} is like mapped(), except that the modified results are reduced or folded into a single result. - \li QtConcurrent::filter() removes all items from a container based on the + \li \l {QtConcurrent::filter}{QtConcurrent::filter()} removes all items from a container based on the result of a filter function. - \li QtConcurrent::filtered() is like filter(), except that it returns a new + \li \l {QtConcurrent::filtered}{QtConcurrent::filtered()} is like filter(), except that it returns a new container with the filtered results. - \li QtConcurrent::filteredReduced() is like filtered(), except that the + \li \l {QtConcurrent::filteredReduced}{QtConcurrent::filteredReduced()} is like filtered(), except that the filtered results are reduced or folded into a single result. - \li QtConcurrent::run() runs a function in another thread. + \li \l {QtConcurrent::run}{QtConcurrent::run()} runs a function in another thread. \li QFuture represents the result of an asynchronous computation. diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/arch/qatomic_cxx11.h index a58c8ab72e..09e900f4ea 100644 --- a/src/corelib/arch/qatomic_cxx11.h +++ b/src/corelib/arch/qatomic_cxx11.h @@ -230,6 +230,102 @@ template <typename X> struct QAtomicOps { return _q_value.fetch_add(valueToAdd, std::memory_order_acq_rel); } + + template <typename T> static inline + T fetchAndSubRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_sub(valueToAdd, std::memory_order_relaxed); + } + + template <typename T> static inline + T fetchAndSubAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_sub(valueToAdd, std::memory_order_acquire); + } + + template <typename T> static inline + T fetchAndSubRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_sub(valueToAdd, std::memory_order_release); + } + + template <typename T> static inline + T fetchAndSubOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_sub(valueToAdd, std::memory_order_acq_rel); + } + + template <typename T> static inline + T fetchAndAndRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_and(valueToAdd, std::memory_order_relaxed); + } + + template <typename T> static inline + T fetchAndAndAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_and(valueToAdd, std::memory_order_acquire); + } + + template <typename T> static inline + T fetchAndAndRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_and(valueToAdd, std::memory_order_release); + } + + template <typename T> static inline + T fetchAndAndOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_and(valueToAdd, std::memory_order_acq_rel); + } + + template <typename T> static inline + T fetchAndOrRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_or(valueToAdd, std::memory_order_relaxed); + } + + template <typename T> static inline + T fetchAndOrAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_or(valueToAdd, std::memory_order_acquire); + } + + template <typename T> static inline + T fetchAndOrRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_or(valueToAdd, std::memory_order_release); + } + + template <typename T> static inline + T fetchAndOrOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_or(valueToAdd, std::memory_order_acq_rel); + } + + template <typename T> static inline + T fetchAndXorRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_xor(valueToAdd, std::memory_order_relaxed); + } + + template <typename T> static inline + T fetchAndXorAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_xor(valueToAdd, std::memory_order_acquire); + } + + template <typename T> static inline + T fetchAndXorRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_xor(valueToAdd, std::memory_order_release); + } + + template <typename T> static inline + T fetchAndXorOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW + { + return _q_value.fetch_xor(valueToAdd, std::memory_order_acq_rel); + } }; #ifdef ATOMIC_VAR_INIT diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 2d3a78db01..6aa3eb305b 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -585,6 +585,10 @@ class QDataStream; # define QT_NO_SOCKS5 #endif +#if defined(Q_OS_IOS) +# define QT_NO_PROCESS +#endif + inline void qt_noop(void) {} /* These wrap try/catch so we can switch off exceptions later. @@ -660,7 +664,7 @@ Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line) #if !defined(Q_ASSERT) # if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) -# define Q_ASSERT(cond) do { } while (false && (cond)) +# define Q_ASSERT(cond) do { } while ((false) && (cond)) # else # define Q_ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop()) # endif diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index e115cedc51..420b8b0430 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1663,6 +1663,7 @@ public: QT_Q_ENUM(ItemSelectionOperation) QT_Q_FLAG(ItemFlags) QT_Q_ENUM(CheckState) + QT_Q_ENUM(ItemDataRole) QT_Q_ENUM(SortOrder) QT_Q_ENUM(CaseSensitivity) QT_Q_FLAG(MatchFlags) diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index 5719d899a0..1c8da607a7 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -157,13 +157,17 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys() if (!setNativeLocks(fd)) qWarning() << "setNativeLocks failed:" << strerror(errno); + if (qt_write_loop(fd, fileData.constData(), fileData.size()) < fileData.size()) { + close(fd); + if (!QFile::remove(fileName)) + qWarning("QLockFile: Could not remove our own lock file %s.", qPrintable(fileName)); + return QLockFile::UnknownError; // partition full + } + // We hold the lock, continue. fileHandle = fd; - QLockFile::LockError error = QLockFile::NoError; - if (qt_write_loop(fd, fileData.constData(), fileData.size()) < fileData.size()) - error = QLockFile::UnknownError; // partition full - return error; + return QLockFile::NoError; } bool QLockFilePrivate::removeStaleLock() diff --git a/src/corelib/itemmodels/qabstractitemmodel.h b/src/corelib/itemmodels/qabstractitemmodel.h index 7789c0d483..1c2ff9f190 100644 --- a/src/corelib/itemmodels/qabstractitemmodel.h +++ b/src/corelib/itemmodels/qabstractitemmodel.h @@ -164,20 +164,20 @@ public: explicit QAbstractItemModel(QObject *parent = 0); virtual ~QAbstractItemModel(); - bool hasIndex(int row, int column, const QModelIndex &parent = QModelIndex()) const; - virtual QModelIndex index(int row, int column, + Q_INVOKABLE bool hasIndex(int row, int column, const QModelIndex &parent = QModelIndex()) const; + Q_INVOKABLE virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const = 0; - virtual QModelIndex parent(const QModelIndex &child) const = 0; + Q_INVOKABLE virtual QModelIndex parent(const QModelIndex &child) const = 0; - virtual QModelIndex sibling(int row, int column, const QModelIndex &idx) const; - virtual int rowCount(const QModelIndex &parent = QModelIndex()) const = 0; - virtual int columnCount(const QModelIndex &parent = QModelIndex()) const = 0; - virtual bool hasChildren(const QModelIndex &parent = QModelIndex()) const; + Q_INVOKABLE virtual QModelIndex sibling(int row, int column, const QModelIndex &idx) const; + Q_INVOKABLE virtual int rowCount(const QModelIndex &parent = QModelIndex()) const = 0; + Q_INVOKABLE virtual int columnCount(const QModelIndex &parent = QModelIndex()) const = 0; + Q_INVOKABLE virtual bool hasChildren(const QModelIndex &parent = QModelIndex()) const; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const = 0; - virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + Q_INVOKABLE virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const = 0; + Q_INVOKABLE virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - virtual QVariant headerData(int section, Qt::Orientation orientation, + Q_INVOKABLE virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; virtual bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole); @@ -217,9 +217,9 @@ public: inline bool moveColumn(const QModelIndex &sourceParent, int sourceColumn, const QModelIndex &destinationParent, int destinationChild); - virtual void fetchMore(const QModelIndex &parent); - virtual bool canFetchMore(const QModelIndex &parent) const; - virtual Qt::ItemFlags flags(const QModelIndex &index) const; + Q_INVOKABLE virtual void fetchMore(const QModelIndex &parent); + Q_INVOKABLE virtual bool canFetchMore(const QModelIndex &parent) const; + Q_INVOKABLE virtual Qt::ItemFlags flags(const QModelIndex &index) const; virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); virtual QModelIndex buddy(const QModelIndex &index) const; virtual QModelIndexList match(const QModelIndex &start, int role, @@ -484,6 +484,5 @@ inline uint qHash(const QModelIndex &index) Q_DECL_NOTHROW QT_END_NAMESPACE Q_DECLARE_METATYPE(QModelIndexList) -Q_DECLARE_METATYPE(QPersistentModelIndex) #endif // QABSTRACTITEMMODEL_H diff --git a/src/corelib/itemmodels/qitemselectionmodel.h b/src/corelib/itemmodels/qitemselectionmodel.h index fe0bd459cd..09fab78214 100644 --- a/src/corelib/itemmodels/qitemselectionmodel.h +++ b/src/corelib/itemmodels/qitemselectionmodel.h @@ -146,6 +146,7 @@ class Q_CORE_EXPORT QItemSelectionModel : public QObject Q_PROPERTY(QAbstractItemModel *model READ model WRITE setModel NOTIFY modelChanged) Q_PROPERTY(bool hasSelection READ hasSelection NOTIFY selectionChanged STORED false DESIGNABLE false) Q_PROPERTY(QModelIndex currentIndex READ currentIndex NOTIFY currentChanged STORED false DESIGNABLE false) + Q_PROPERTY(QItemSelection selection READ selection NOTIFY selectionChanged STORED false DESIGNABLE false) Q_DECLARE_PRIVATE(QItemSelectionModel) @@ -186,7 +187,7 @@ public: Q_INVOKABLE QModelIndexList selectedIndexes() const; Q_INVOKABLE QModelIndexList selectedRows(int column = 0) const; Q_INVOKABLE QModelIndexList selectedColumns(int row = 0) const; - Q_INVOKABLE const QItemSelection selection() const; + const QItemSelection selection() const; // ### Qt 6: Merge these two as "QAbstractItemModel *model() const" const QAbstractItemModel *model() const; diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 18a379f8b9..0bde57c8b3 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -368,7 +368,9 @@ struct QCoreApplicationData { } #endif - QString orgName, orgDomain, application; + QString orgName, orgDomain; + QString application; // application name, initially from argv[0], can then be modified. + QString applicationNameCompat; // for QDesktopServices. Only set explicitly. QString applicationVersion; #ifndef QT_NO_LIBRARY @@ -750,6 +752,9 @@ void QCoreApplication::init() Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object"); QCoreApplication::self = this; + // Store app name (so it's still available after QCoreApplication is destroyed) + coreappdata()->application = d_func()->appName(); + QLoggingRegistry::instance()->init(); #ifndef QT_NO_QOBJECT @@ -2345,9 +2350,13 @@ QString QCoreApplication::organizationDomain() */ void QCoreApplication::setApplicationName(const QString &application) { - if (coreappdata()->application == application) + QString newAppName = application; + if (newAppName.isEmpty() && QCoreApplication::self) + newAppName = QCoreApplication::self->d_func()->appName(); + if (coreappdata()->application == newAppName) return; - coreappdata()->application = application; + coreappdata()->application = newAppName; + coreappdata()->applicationNameCompat = newAppName; #ifndef QT_NO_QOBJECT if (QCoreApplication::self) emit QCoreApplication::self->applicationNameChanged(); @@ -2359,16 +2368,13 @@ QString QCoreApplication::applicationName() #ifdef Q_OS_BLACKBERRY coreappdata()->loadManifest(); #endif - QString appname = coreappdata() ? coreappdata()->application : QString(); - if (appname.isEmpty() && QCoreApplication::self) - appname = QCoreApplication::self->d_func()->appName(); - return appname; + return coreappdata() ? coreappdata()->application : QString(); } // Exported for QDesktopServices (Qt4 behavior compatibility) Q_CORE_EXPORT QString qt_applicationName_noFallback() { - return coreappdata()->application; + return coreappdata()->applicationNameCompat; } /*! diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 305e998818..d4a69ee4b9 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -277,6 +277,7 @@ struct DefinedTypesFilter { \value QJsonArray QJsonArray \value QJsonDocument QJsonDocument \value QModelIndex QModelIndex + \value QPersistentModelIndex QPersistentModelIndex (since 5.5) \value QUuid QUuid \value QByteArrayList QByteArrayList @@ -1209,6 +1210,7 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data) case QMetaType::VoidStar: case QMetaType::QObjectStar: case QMetaType::QModelIndex: + case QMetaType::QPersistentModelIndex: case QMetaType::QJsonValue: case QMetaType::QJsonObject: case QMetaType::QJsonArray: @@ -1429,6 +1431,7 @@ bool QMetaType::load(QDataStream &stream, int type, void *data) case QMetaType::VoidStar: case QMetaType::QObjectStar: case QMetaType::QModelIndex: + case QMetaType::QPersistentModelIndex: case QMetaType::QJsonValue: case QMetaType::QJsonObject: case QMetaType::QJsonArray: diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 9659c015ff..2c2dbeef9d 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -113,6 +113,7 @@ inline Q_DECL_CONSTEXPR int qMetaTypeId(); F(QJsonObject, 46, QJsonObject) \ F(QJsonArray, 47, QJsonArray) \ F(QJsonDocument, 48, QJsonDocument) \ + F(QPersistentModelIndex, 50, QPersistentModelIndex) \ #define QT_FOR_EACH_STATIC_CORE_POINTER(F)\ F(QObjectStar, 39, QObject*) @@ -407,7 +408,7 @@ public: QT_FOR_EACH_STATIC_TYPE(QT_DEFINE_METATYPE_ID) FirstCoreType = Bool, - LastCoreType = QByteArrayList, + LastCoreType = QPersistentModelIndex, FirstGuiType = QFont, LastGuiType = QPolygonF, FirstWidgetsType = QSizePolicy, @@ -431,7 +432,7 @@ public: QLocale = 18, QRect = 19, QRectF = 20, QSize = 21, QSizeF = 22, QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26, QRegExp = 27, QEasingCurve = 29, QUuid = 30, QVariant = 41, QModelIndex = 42, - QRegularExpression = 44, + QPersistentModelIndex = 50, QRegularExpression = 44, QJsonValue = 45, QJsonObject = 46, QJsonArray = 47, QJsonDocument = 48, QByteArrayList = 49, QObjectStar = 39, SChar = 40, Void = 43, diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index 7880baf0f1..7c0c984c9c 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -192,6 +192,7 @@ template<> struct TypeDefinition<QJsonDocument> { static const bool IsAvailable template<> struct TypeDefinition<QJsonObject> { static const bool IsAvailable = false; }; template<> struct TypeDefinition<QJsonValue> { static const bool IsAvailable = false; }; template<> struct TypeDefinition<QModelIndex> { static const bool IsAvailable = false; }; +template<> struct TypeDefinition<QPersistentModelIndex> { static const bool IsAvailable = false; }; template<> struct TypeDefinition<QUrl> { static const bool IsAvailable = false; }; template<> struct TypeDefinition<QByteArrayList> { static const bool IsAvailable = false; }; #endif diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index b14c9ed167..9ae6c779c0 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -390,7 +390,25 @@ static bool convert(const QVariant::Private *d, int t, void *result, bool *ok) return false; } break; -#endif + case QVariant::ModelIndex: + switch (d->type) { + case QVariant::PersistentModelIndex: + *static_cast<QModelIndex *>(result) = QModelIndex(*v_cast<QPersistentModelIndex>(d)); + break; + default: + return false; + } + break; + case QVariant::PersistentModelIndex: + switch (d->type) { + case QVariant::ModelIndex: + *static_cast<QPersistentModelIndex *>(result) = QPersistentModelIndex(*v_cast<QModelIndex>(d)); + break; + default: + return false; + } + break; +#endif // QT_BOOTSTRAPPED case QVariant::String: { QString *str = static_cast<QString *>(result); switch (d->type) { @@ -1208,6 +1226,7 @@ Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names \value EasingCurve a QEasingCurve \value Uuid a QUuid \value ModelIndex a QModelIndex + \value PersistentModelIndex a QPersistentModelIndex (since 5.5) \value Font a QFont \value Hash a QVariantHash \value Icon a QIcon @@ -1455,7 +1474,14 @@ QVariant::QVariant(const char *val) \since 5.0 \fn QVariant::QVariant(const QModelIndex &val) - Constructs a new variant with an modelIndex value, \a val. + Constructs a new variant with a QModelIndex value, \a val. +*/ + +/*! + \since 5.5 + \fn QVariant::QVariant(const QPersistentModelIndex &val) + + Constructs a new variant with a QPersistentModelIndex value, \a val. */ /*! @@ -1763,6 +1789,9 @@ QVariant::QVariant(const QUuid &uuid) QVariant::QVariant(const QModelIndex &modelIndex) : d(ModelIndex) { v_construct<QModelIndex>(&d, modelIndex); } +QVariant::QVariant(const QPersistentModelIndex &modelIndex) + : d(PersistentModelIndex) +{ v_construct<QPersistentModelIndex>(&d, modelIndex); } QVariant::QVariant(const QJsonValue &jsonValue) : d(QMetaType::QJsonValue) { v_construct<QJsonValue>(&d, jsonValue); } @@ -2492,7 +2521,7 @@ QUuid QVariant::toUuid() const Returns the variant as a QModelIndex if the variant has userType() \l QModelIndex; otherwise returns a default constructed QModelIndex. - \sa canConvert(), convert() + \sa canConvert(), convert(), toPersistentModelIndex() */ QModelIndex QVariant::toModelIndex() const { @@ -2500,6 +2529,19 @@ QModelIndex QVariant::toModelIndex() const } /*! + \since 5.5 + + Returns the variant as a QPersistentModelIndex if the variant has userType() \l + QPersistentModelIndex; otherwise returns a default constructed QPersistentModelIndex. + + \sa canConvert(), convert(), toModelIndex() +*/ +QModelIndex QVariant::toPersistentModelIndex() const +{ + return qVariantToHelper<QPersistentModelIndex>(d, handlerManager); +} + +/*! \since 5.0 Returns the variant as a QJsonValue if the variant has userType() \l @@ -2966,6 +3008,10 @@ static bool canConvertMetaObject(int fromId, int toId, QObject *fromObject) */ bool QVariant::canConvert(int targetTypeId) const { + if ((targetTypeId == QMetaType::QModelIndex && d.type == QMetaType::QPersistentModelIndex) + || (targetTypeId == QMetaType::QPersistentModelIndex && d.type == QMetaType::QModelIndex)) + return true; + if (targetTypeId == QMetaType::QVariantList && (d.type == QMetaType::QVariantList || d.type == QMetaType::QStringList diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index b6a4133582..d9eca94391 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -156,6 +156,7 @@ class Q_CORE_EXPORT QVariant EasingCurve = QMetaType::QEasingCurve, Uuid = QMetaType::QUuid, ModelIndex = QMetaType::QModelIndex, + PersistentModelIndex = QMetaType::QPersistentModelIndex, LastCoreType = QMetaType::LastCoreType, Font = QMetaType::QFont, @@ -245,6 +246,7 @@ class Q_CORE_EXPORT QVariant QVariant(const QEasingCurve &easing); QVariant(const QUuid &uuid); QVariant(const QModelIndex &modelIndex); + QVariant(const QPersistentModelIndex &modelIndex); QVariant(const QJsonValue &jsonValue); QVariant(const QJsonObject &jsonObject); QVariant(const QJsonArray &jsonArray); @@ -318,6 +320,7 @@ class Q_CORE_EXPORT QVariant QEasingCurve toEasingCurve() const; QUuid toUuid() const; QModelIndex toModelIndex() const; + QModelIndex toPersistentModelIndex() const; QJsonValue toJsonValue() const; QJsonObject toJsonObject() const; QJsonArray toJsonArray() const; diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index 16a27862c2..ecf39d699f 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -39,6 +39,14 @@ #if defined(QT_BOOTSTRAPPED) # include <QtCore/qatomic_bootstrap.h> +// The following two are used for testing only. +// Note that we don't check the compiler support -- you had better +// know what you're doing if you set them +#elif defined(QT_ATOMIC_FORCE_CXX11) +# include <QtCore/qatomic_cxx11.h> +#elif defined(QT_ATOMIC_FORCE_GCC) +# include <QtCore/qatomic_gcc.h> + // Compiler dependent implementation #elif defined(Q_CC_MSVC) # include <QtCore/qatomic_msvc.h> diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index eeefea8137..e5fbf5af5e 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2607,7 +2607,6 @@ QDateTimePrivate::QDateTimePrivate(const QDate &toDate, const QTime &toTime, void QDateTimePrivate::setTimeSpec(Qt::TimeSpec spec, int offsetSeconds) { clearValidDateTime(); - clearTimeZoneCached(); clearSetToDaylightStatus(); #ifndef QT_BOOTSTRAPPED @@ -2707,27 +2706,44 @@ QDateTimePrivate::DaylightStatus QDateTimePrivate::daylightStatus() const return UnknownDaylightTime; } +qint64 QDateTimePrivate::toMSecsSinceEpoch() const +{ + switch (m_spec) { + case Qt::OffsetFromUTC: + case Qt::UTC: + return (m_msecs - (m_offsetFromUtc * 1000)); + + case Qt::LocalTime: + // recalculate the local timezone + return localMSecsToEpochMSecs(m_msecs); + + case Qt::TimeZone: +#ifndef QT_BOOTSTRAPPED + return zoneMSecsToEpochMSecs(m_msecs, m_timeZone); +#endif + break; + } + Q_UNREACHABLE(); + return 0; +} + // Check the UTC / offsetFromUTC validity void QDateTimePrivate::checkValidDateTime() { switch (m_spec) { case Qt::OffsetFromUTC: case Qt::UTC: + // for these, a valid date and a valid time imply a valid QDateTime if (isValidDate() && isValidTime()) setValidDateTime(); else clearValidDateTime(); break; case Qt::TimeZone: - // Defer checking until required as can be expensive - clearValidDateTime(); - clearTimeZoneCached(); - m_offsetFromUtc = 0; - break; case Qt::LocalTime: - // Defer checking until required as can be expensive - clearValidDateTime(); - m_offsetFromUtc = 0; + // for these, we need to check whether the timezone is valid and whether + // the time is valid in that timezone. Expensive, but no other option. + refreshDateTime(); break; } } @@ -2741,12 +2757,6 @@ void QDateTimePrivate::refreshDateTime() // Always set by setDateTime so just return return; case Qt::TimeZone: - // If already cached then don't need to refresh as tz won't change - if (isTimeZoneCached()) - return; - // Flag that will have a cached result after calculations - setTimeZoneCached(); - break; case Qt::LocalTime: break; } @@ -3082,7 +3092,6 @@ bool QDateTime::isNull() const bool QDateTime::isValid() const { - d->refreshDateTime(); return (d->isValidDateTime()); } @@ -3143,13 +3152,11 @@ Qt::TimeSpec QDateTime::timeSpec() const QTimeZone QDateTime::timeZone() const { switch (d->m_spec) { - case Qt::OffsetFromUTC: - if (!d->m_timeZone.isValid()) - d->m_timeZone = QTimeZone(d->m_offsetFromUtc); - return d->m_timeZone; case Qt::UTC: return QTimeZone::utc(); + case Qt::OffsetFromUTC: case Qt::TimeZone: + Q_ASSERT(d->m_timeZone.isValid()); return d->m_timeZone; case Qt::LocalTime: return QTimeZone::systemTimeZone(); @@ -3178,7 +3185,6 @@ QTimeZone QDateTime::timeZone() const int QDateTime::offsetFromUtc() const { - d->refreshDateTime(); return d->m_offsetFromUtc; } @@ -3350,7 +3356,7 @@ void QDateTime::setTimeZone(const QTimeZone &toZone) d->m_spec = Qt::TimeZone; d->m_offsetFromUtc = 0; d->m_timeZone = toZone; - d->m_status = d->m_status & ~QDateTimePrivate::ValidDateTime & ~QDateTimePrivate::TimeZoneCached; + d->refreshDateTime(); } #endif // QT_BOOTSTRAPPED @@ -3371,7 +3377,6 @@ void QDateTime::setTimeZone(const QTimeZone &toZone) */ qint64 QDateTime::toMSecsSinceEpoch() const { - d->refreshDateTime(); return d->toMSecsSinceEpoch(); } @@ -3453,8 +3458,8 @@ void QDateTime::setMSecsSinceEpoch(qint64 msecs) d->m_status = d->m_status | QDateTimePrivate::ValidDate | QDateTimePrivate::ValidTime - | QDateTimePrivate::ValidDateTime - | QDateTimePrivate::TimeZoneCached; + | QDateTimePrivate::ValidDateTime; + d->refreshDateTime(); #endif // QT_BOOTSTRAPPED break; case Qt::LocalTime: { diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index 784aced71a..88288872df 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -326,7 +326,7 @@ private: // ### Qt6: Using a private here has high impact on runtime // on users such as QFileInfo. In Qt 6, the data members // should be inlined. - QExplicitlySharedDataPointer<QDateTimePrivate> d; + QSharedDataPointer<QDateTimePrivate> d; #ifndef QT_NO_DATASTREAM friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &); diff --git a/src/corelib/tools/qdatetime_p.h b/src/corelib/tools/qdatetime_p.h index a139390a9d..b8934f7f70 100644 --- a/src/corelib/tools/qdatetime_p.h +++ b/src/corelib/tools/qdatetime_p.h @@ -79,10 +79,9 @@ public: enum StatusFlag { NullDate = 0x01, NullTime = 0x02, - ValidDate = 0x04, - ValidTime = 0x08, - ValidDateTime = 0x10, - TimeZoneCached = 0x20, + ValidDate = 0x04, // just the date field + ValidTime = 0x08, // just the time field + ValidDateTime = 0x10, // the whole object (including timezone) SetToStandardTime = 0x40, SetToDaylightTime = 0x80 }; @@ -120,7 +119,7 @@ public: DaylightStatus daylightStatus() const; // Returns msecs since epoch, assumes offset value is current - inline qint64 toMSecsSinceEpoch() const { return (m_msecs - (m_offsetFromUtc * 1000)); } + inline qint64 toMSecsSinceEpoch() const; void checkValidDateTime(); void refreshDateTime(); @@ -133,14 +132,11 @@ public: inline bool isValidDateTime() const { return m_status & ValidDateTime; } inline void setValidDateTime() { m_status |= ValidDateTime; } inline void clearValidDateTime() { m_status &= ~ValidDateTime; } - inline bool isTimeZoneCached() const { return m_status & TimeZoneCached; } - inline void setTimeZoneCached() { m_status |= TimeZoneCached; } - inline void clearTimeZoneCached() { m_status &= ~TimeZoneCached; } inline void clearSetToDaylightStatus() { m_status &= ~(SetToStandardTime | SetToDaylightTime); } #ifndef QT_BOOTSTRAPPED static qint64 zoneMSecsToEpochMSecs(qint64 msecs, const QTimeZone &zone, - QDate *localDate, QTime *localTime); + QDate *localDate = 0, QTime *localTime = 0); #endif // QT_BOOTSTRAPPED static inline qint64 minJd() { return QDate::minJd(); } diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index 8cccc83e9d..9e6b48a97d 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -247,6 +247,7 @@ namespace QtSharedPointer { ExternalRefCountWithContiguousData *that = static_cast<ExternalRefCountWithContiguousData *>(self); that->data.~T(); + Q_UNUSED(that); // MSVC warns if T has a trivial destructor } static void safetyCheckDeleter(ExternalRefCountData *self) { diff --git a/src/corelib/tools/qstringalgorithms_p.h b/src/corelib/tools/qstringalgorithms_p.h index 1481b194eb..b4be5c7ec7 100644 --- a/src/corelib/tools/qstringalgorithms_p.h +++ b/src/corelib/tools/qstringalgorithms_p.h @@ -114,7 +114,7 @@ template <typename StringType> struct QStringAlgorithms return str; const Char *src = str.cbegin(); const Char *end = str.cend(); - NakedStringType result = isConst ? + NakedStringType result = isConst || !str.isDetached() ? StringType(str.size(), Qt::Uninitialized) : qMove(str); diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index b60ef4b8c1..8c49b3a2b5 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -873,9 +873,14 @@ QWindowList QGuiApplication::topLevelWindows() } /*! - Returns the primary (or default) screen of the application. + Returns the primary (or default) screen of the application, or null if there is none This will be the screen where QWindows are initially shown, unless otherwise specified. + + On some platforms, it may be null when there are actually no screens connected. + It is not possible to start a new QGuiApplication while there are no screens. + Applications which were running at the time the primary screen was removed + will stop rendering graphics until one or more screens are restored. */ QScreen *QGuiApplication::primaryScreen() { @@ -1859,6 +1864,13 @@ void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyE window = QGuiApplication::focusWindow(); } +#if !defined(Q_OS_OSX) + // On OS X the shortcut override is checked earlier, see: QWindowSystemInterface::handleKeyEvent() + const bool checkShortcut = e->keyType == QEvent::KeyPress && window != 0; + if (checkShortcut && QWindowSystemInterface::tryHandleShortcutEvent(window, e->timestamp, e->key, e->modifiers, e->unicode)) + return; +#endif // Q_OS_OSX + QKeyEvent ev(e->keyType, e->key, e->modifiers, e->nativeScanCode, e->nativeVirtualKey, e->nativeModifiers, e->unicode, e->repeat, e->repeatCount); diff --git a/src/gui/kernel/qplatformdrag.cpp b/src/gui/kernel/qplatformdrag.cpp index f509408f8f..d789c75d1d 100644 --- a/src/gui/kernel/qplatformdrag.cpp +++ b/src/gui/kernel/qplatformdrag.cpp @@ -42,57 +42,7 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_DRAGANDDROP #ifdef QDND_DEBUG -QString dragActionsToString(Qt::DropActions actions) -{ - QString str; - if (actions == Qt::IgnoreAction) { - if (!str.isEmpty()) - str += QLatin1String(" | "); - str += QLatin1String("IgnoreAction"); - } - if (actions & Qt::LinkAction) { - if (!str.isEmpty()) - str += QLatin1String(" | "); - str += QLatin1String("LinkAction"); - } - if (actions & Qt::CopyAction) { - if (!str.isEmpty()) - str += QLatin1String(" | "); - str += QLatin1String("CopyAction"); - } - if (actions & Qt::MoveAction) { - if (!str.isEmpty()) - str += QLatin1String(" | "); - str += QLatin1String("MoveAction"); - } - if ((actions & Qt::TargetMoveAction) == Qt::TargetMoveAction ) { - if (!str.isEmpty()) - str += QLatin1String(" | "); - str += QLatin1String("TargetMoveAction"); - } - return str; -} - -QString KeyboardModifiersToString(Qt::KeyboardModifiers modifiers) -{ - QString str; - if (modifiers & Qt::ControlModifier) { - if (!str.isEmpty()) - str += QLatin1String(" | "); - str += QLatin1String("ControlModifier"); - } - if (modifiers & Qt::AltModifier) { - if (!str.isEmpty()) - str += QLatin1String(" | "); - str += QLatin1String("AltModifier"); - } - if (modifiers & Qt::ShiftModifier) { - if (!str.isEmpty()) - str += QLatin1String(" | "); - str += QLatin1String("ShiftModifier"); - } - return str; -} +# include <QtCore/QDebug> #endif QPlatformDropQtResponse::QPlatformDropQtResponse(bool accepted, Qt::DropAction acceptedAction) @@ -156,8 +106,7 @@ Qt::DropAction QPlatformDrag::defaultAction(Qt::DropActions possibleActions, Qt::KeyboardModifiers modifiers) const { #ifdef QDND_DEBUG - qDebug("QDragManager::defaultAction(Qt::DropActions possibleActions)"); - qDebug("keyboard modifiers : %s", qPrintable(KeyboardModifiersToString(modifiers))); + qDebug() << "QDragManager::defaultAction(Qt::DropActions possibleActions)\nkeyboard modifiers : " << modifiers; #endif Qt::DropAction default_action = Qt::IgnoreAction; @@ -183,7 +132,7 @@ Qt::DropAction QPlatformDrag::defaultAction(Qt::DropActions possibleActions, default_action = Qt::LinkAction; #ifdef QDND_DEBUG - qDebug("possible actions : %s", qPrintable(dragActionsToString(possibleActions))); + qDebug() << "possible actions : " << possibleActions; #endif // Check if the action determined is allowed @@ -199,7 +148,7 @@ Qt::DropAction QPlatformDrag::defaultAction(Qt::DropActions possibleActions, } #ifdef QDND_DEBUG - qDebug("default action : %s", qPrintable(dragActionsToString(default_action))); + qDebug() << "default action : " << default_action; #endif return default_action; diff --git a/src/gui/kernel/qplatformtheme.cpp b/src/gui/kernel/qplatformtheme.cpp index c53b71eafc..aa49d64309 100644 --- a/src/gui/kernel/qplatformtheme.cpp +++ b/src/gui/kernel/qplatformtheme.cpp @@ -315,7 +315,7 @@ const QKeyBinding QPlatformThemePrivate::keyBindings[] = { {QKeySequence::InsertLineSeparator, 0, Qt::META | Qt::Key_O, KB_Mac}, {QKeySequence::SaveAs, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_S, KB_Gnome | KB_Mac}, {QKeySequence::Preferences, 0, Qt::CTRL | Qt::Key_Comma, KB_Mac}, - {QKeySequence::Quit, 0, Qt::CTRL | Qt::Key_Q, KB_Gnome | KB_KDE | KB_Mac}, + {QKeySequence::Quit, 0, Qt::CTRL | Qt::Key_Q, KB_X11 | KB_Gnome | KB_KDE | KB_Mac}, {QKeySequence::FullScreen, 1, Qt::META | Qt::CTRL | Qt::Key_F, KB_Mac}, {QKeySequence::FullScreen, 0, Qt::ALT | Qt::Key_Enter, KB_Win}, {QKeySequence::FullScreen, 0, Qt::CTRL | Qt::SHIFT | Qt::Key_F, KB_KDE}, diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index d8e4e7736e..114fcf8062 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -79,7 +79,8 @@ QPlatformWindow *QPlatformWindow::parent() const } /*! - Returns the platform screen handle corresponding to this platform window. + Returns the platform screen handle corresponding to this platform window, + or null if the window is not associated with a screen. */ QPlatformScreen *QPlatformWindow::screen() const { diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 33f0409216..06db4e81fa 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -1678,7 +1678,7 @@ bool QWindow::setMouseGrabEnabled(bool grab) } /*! - Returns the screen on which the window is shown. + Returns the screen on which the window is shown, or null if there is none. For child windows, this returns the screen of the corresponding top level window. diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp index 9a2fb33bbc..73b1a84005 100644 --- a/src/gui/kernel/qwindowsysteminterface.cpp +++ b/src/gui/kernel/qwindowsysteminterface.cpp @@ -292,8 +292,13 @@ void QWindowSystemInterface::handleKeyEvent(QWindow *w, QEvent::Type t, int k, Q void QWindowSystemInterface::handleKeyEvent(QWindow *tlw, ulong timestamp, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text, bool autorep, ushort count) { + // This is special handling needed for OS X which eventually will call sendEvent(), on other platforms + // this might not be safe, e.g., on Android. See: QGuiApplicationPrivate::processKeyEvent() for + // shortcut overriding on other platforms. +#if defined(Q_OS_OSX) if (t == QEvent::KeyPress && QWindowSystemInterface::tryHandleShortcutEvent(tlw, timestamp, k, mods, text)) return; +#endif // Q_OS_OSX QWindowSystemInterfacePrivate::KeyEvent * e = new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, t, k, mods, text, autorep, count); @@ -318,10 +323,7 @@ void QWindowSystemInterface::handleExtendedKeyEvent(QWindow *tlw, ulong timestam const QString& text, bool autorep, ushort count, bool tryShortcutOverride) { - // on OS X we try the shortcut override even earlier and thus shouldn't handle it here - if (tryShortcutOverride && type == QEvent::KeyPress && QWindowSystemInterface::tryHandleShortcutEvent(tlw, timestamp, key, modifiers, text)) - return; - + Q_UNUSED(tryShortcutOverride) QWindowSystemInterfacePrivate::KeyEvent * e = new QWindowSystemInterfacePrivate::KeyEvent(tlw, timestamp, type, key, modifiers, nativeScanCode, nativeVirtualKey, nativeModifiers, text, autorep, count); diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index 19d1fe6a8c..09b41ac570 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -1523,10 +1523,13 @@ void QMatrix4x4::perspective(float verticalAngle, float aspectRatio, float nearP #ifndef QT_NO_VECTOR3D /*! - Multiplies this matrix by another that applies an \a eye position - transformation. The \a center value indicates the center of the - view that the \a eye is looking at. The \a up value indicates - which direction should be considered up with respect to the \a eye. + Multiplies this matrix by a viewing matrix derived from an eye + point. The \a center value indicates the center of the view that + the \a eye is looking at. The \a up value indicates which direction + should be considered up with respect to the \a eye. + + \note The \a up vector must not be parallel to the line of sight + from \a eye to \a center. */ void QMatrix4x4::lookAt(const QVector3D& eye, const QVector3D& center, const QVector3D& up) { diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 4f07d82a25..90d90448e0 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -213,9 +213,18 @@ QT_BEGIN_NAMESPACE */ /*! + \fn float QQuaternion::dotProduct(const QQuaternion &q1, const QQuaternion &q2) + \since 5.5 + + Returns the dot product of \a q1 and \a q2. + + \sa length() +*/ + +/*! Returns the length of the quaternion. This is also called the "norm". - \sa lengthSquared(), normalized() + \sa lengthSquared(), normalized(), dotProduct() */ float QQuaternion::length() const { @@ -225,7 +234,7 @@ float QQuaternion::length() const /*! Returns the squared length of the quaternion. - \sa length() + \sa length(), dotProduct() */ float QQuaternion::lengthSquared() const { @@ -240,7 +249,7 @@ float QQuaternion::lengthSquared() const will be returned as-is. Otherwise the normalized form of the quaternion of length 1 will be returned. - \sa length(), normalize() + \sa normalize(), length(), dotProduct() */ QQuaternion QQuaternion::normalized() const { @@ -583,7 +592,7 @@ QQuaternion QQuaternion::fromEulerAngles(float pitch, float yaw, float roll) \note If this quaternion is not normalized, the resulting rotation matrix will contain scaling information. - \sa fromRotationMatrix() + \sa fromRotationMatrix(), getAxes() */ QMatrix3x3 QQuaternion::toRotationMatrix() const { @@ -626,7 +635,7 @@ QMatrix3x3 QQuaternion::toRotationMatrix() const \note If a given rotation matrix is not normalized, the resulting quaternion will contain scaling information. - \sa toRotationMatrix() + \sa toRotationMatrix(), fromAxes() */ QQuaternion QQuaternion::fromRotationMatrix(const QMatrix3x3 &rot3x3) { @@ -663,6 +672,85 @@ QQuaternion QQuaternion::fromRotationMatrix(const QMatrix3x3 &rot3x3) return QQuaternion(scalar, axis[0], axis[1], axis[2]); } +#ifndef QT_NO_VECTOR3D + +/*! + \since 5.5 + + Returns the 3 orthonormal axes (\a xAxis, \a yAxis, \a zAxis) defining the quaternion. + + \sa fromAxes(), toRotationMatrix() +*/ +void QQuaternion::getAxes(QVector3D *xAxis, QVector3D *yAxis, QVector3D *zAxis) const +{ + Q_ASSERT(xAxis && yAxis && zAxis); + + const QMatrix3x3 rot3x3(toRotationMatrix()); + + *xAxis = QVector3D(rot3x3(0, 0), rot3x3(1, 0), rot3x3(2, 0)); + *yAxis = QVector3D(rot3x3(0, 1), rot3x3(1, 1), rot3x3(2, 1)); + *zAxis = QVector3D(rot3x3(0, 2), rot3x3(1, 2), rot3x3(2, 2)); +} + +/*! + \since 5.5 + + Constructs the quaternion using 3 axes (\a xAxis, \a yAxis, \a zAxis). + + \note The axes are assumed to be orthonormal. + + \sa getAxes(), fromRotationMatrix() +*/ +QQuaternion QQuaternion::fromAxes(const QVector3D &xAxis, const QVector3D &yAxis, const QVector3D &zAxis) +{ + QMatrix3x3 rot3x3(Qt::Uninitialized); + rot3x3(0, 0) = xAxis.x(); + rot3x3(1, 0) = xAxis.y(); + rot3x3(2, 0) = xAxis.z(); + rot3x3(0, 1) = yAxis.x(); + rot3x3(1, 1) = yAxis.y(); + rot3x3(2, 1) = yAxis.z(); + rot3x3(0, 2) = zAxis.x(); + rot3x3(1, 2) = zAxis.y(); + rot3x3(2, 2) = zAxis.z(); + + return QQuaternion::fromRotationMatrix(rot3x3); +} + +/*! + \since 5.5 + + Returns the shortest arc quaternion to rotate from the direction described by the vector \a from + to the direction described by the vector \a to. +*/ +QQuaternion QQuaternion::rotationTo(const QVector3D &from, const QVector3D &to) +{ + // Based on Stan Melax's article in Game Programming Gems + + const QVector3D v0(from.normalized()); + const QVector3D v1(to.normalized()); + + float d = QVector3D::dotProduct(v0, v1) + 1.0f; + + // if dest vector is close to the inverse of source vector, ANY axis of rotation is valid + if (qFuzzyIsNull(d)) { + QVector3D axis = QVector3D::crossProduct(QVector3D(1.0f, 0.0f, 0.0f), v0); + if (qFuzzyIsNull(axis.lengthSquared())) + axis = QVector3D::crossProduct(QVector3D(0.0f, 1.0f, 0.0f), v0); + axis.normalize(); + + // same as QQuaternion::fromAxisAndAngle(axis, 180.0f) + return QQuaternion(0.0f, axis.x(), axis.y(), axis.z()); + } + + d = std::sqrt(2.0f * d); + const QVector3D axis(QVector3D::crossProduct(v0, v1) / d); + + return QQuaternion(d * 0.5f, axis).normalized(); +} + +#endif // QT_NO_VECTOR3D + /*! \fn bool operator==(const QQuaternion &q1, const QQuaternion &q2) \relates QQuaternion @@ -792,13 +880,10 @@ QQuaternion QQuaternion::slerp return q2; // Determine the angle between the two quaternions. - QQuaternion q2b; - float dot; - dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp; - if (dot >= 0.0f) { - q2b = q2; - } else { - q2b = -q2; + QQuaternion q2b(q2); + float dot = QQuaternion::dotProduct(q1, q2); + if (dot < 0.0f) { + q2b = -q2b; dot = -dot; } @@ -844,13 +929,10 @@ QQuaternion QQuaternion::nlerp return q2; // Determine the angle between the two quaternions. - QQuaternion q2b; - float dot; - dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp; - if (dot >= 0.0f) - q2b = q2; - else - q2b = -q2; + QQuaternion q2b(q2); + float dot = QQuaternion::dotProduct(q1, q2); + if (dot < 0.0f) + q2b = -q2b; // Perform the linear interpolation. return (q1 * (1.0f - t) + q2b * t).normalized(); diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index a02c37ce1d..c3918645d4 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -78,6 +78,8 @@ public: void setZ(float z); void setScalar(float scalar); + Q_DECL_CONSTEXPR static inline float dotProduct(const QQuaternion &q1, const QQuaternion &q2); + float length() const; float lengthSquared() const; @@ -132,6 +134,13 @@ public: QMatrix3x3 toRotationMatrix() const; static QQuaternion fromRotationMatrix(const QMatrix3x3 &rot3x3); +#ifndef QT_NO_VECTOR3D + void getAxes(QVector3D *xAxis, QVector3D *yAxis, QVector3D *zAxis) const; + static QQuaternion fromAxes(const QVector3D &xAxis, const QVector3D &yAxis, const QVector3D &zAxis); + + static QQuaternion rotationTo(const QVector3D &from, const QVector3D &to); +#endif + static QQuaternion slerp (const QQuaternion& q1, const QQuaternion& q2, float t); static QQuaternion nlerp @@ -168,6 +177,11 @@ inline void QQuaternion::setY(float aY) { yp = aY; } inline void QQuaternion::setZ(float aZ) { zp = aZ; } inline void QQuaternion::setScalar(float aScalar) { wp = aScalar; } +Q_DECL_CONSTEXPR inline float QQuaternion::dotProduct(const QQuaternion &q1, const QQuaternion &q2) +{ + return q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp; +} + inline QQuaternion QQuaternion::inverted() const { // Need some extra precision if the length is very small. diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 20fd41e0ae..04857fb0d6 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -69,8 +69,6 @@ enum { // must be multiple of 4 for easier SIMD implementations static const int buffer_size = 2048; -#ifdef Q_COMPILER_CONSTEXPR - template<QImage::Format> Q_DECL_CONSTEXPR uint redWidth(); template<QImage::Format> Q_DECL_CONSTEXPR uint redShift(); template<QImage::Format> Q_DECL_CONSTEXPR uint greenWidth(); @@ -310,6 +308,8 @@ static const uint *QT_FASTCALL convertARGBPMFromARGB32PM(uint *buffer, const uin return buffer; } +#ifdef Q_COMPILER_CONSTEXPR + template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixelLayoutRGB() { return QPixelLayout{ @@ -338,177 +338,6 @@ template<QImage::Format Format> Q_DECL_CONSTEXPR static inline QPixelLayout pixe }; } -#else // CONSTEXPR - -static const uint *QT_FASTCALL convertToARGB32PM(uint *buffer, const uint *src, int count, - const QPixelLayout *layout, const QRgb *) -{ - Q_ASSERT(layout->redWidth >= 4); - Q_ASSERT(layout->greenWidth >= 4); - Q_ASSERT(layout->blueWidth >= 4); - Q_ASSERT(layout->alphaWidth >= 4); - - const uint redMask = ((1 << layout->redWidth) - 1); - const uint greenMask = ((1 << layout->greenWidth) - 1); - const uint blueMask = ((1 << layout->blueWidth) - 1); - - const uchar redLeftShift = 8 - layout->redWidth; - const uchar greenLeftShift = 8 - layout->greenWidth; - const uchar blueLeftShift = 8 - layout->blueWidth; - - const uchar redRightShift = 2 * layout->redWidth - 8; - const uchar greenRightShift = 2 * layout->greenWidth - 8; - const uchar blueRightShift = 2 * layout->blueWidth - 8; - - const uint alphaMask = ((1 << layout->alphaWidth) - 1); - const uchar alphaLeftShift = 8 - layout->alphaWidth; - const uchar alphaRightShift = 2 * layout->alphaWidth - 8; - - if (layout->premultiplied) { - for (int i = 0; i < count; ++i) { - uint alpha = (src[i] >> layout->alphaShift) & alphaMask; - uint red = (src[i] >> layout->redShift) & redMask; - uint green = (src[i] >> layout->greenShift) & greenMask; - uint blue = (src[i] >> layout->blueShift) & blueMask; - - alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift); - red = qMin(alpha, (red << redLeftShift) | (red >> redRightShift)); - green = qMin(alpha, (green << greenLeftShift) | (green >> greenRightShift)); - blue = qMin(alpha, (blue << blueLeftShift) | (blue >> blueRightShift)); - buffer[i] = (alpha << 24) | (red << 16) | (green << 8) | blue; - } - } else { - for (int i = 0; i < count; ++i) { - uint alpha = (src[i] >> layout->alphaShift) & alphaMask; - uint red = (src[i] >> layout->redShift) & redMask; - uint green = (src[i] >> layout->greenShift) & greenMask; - uint blue = (src[i] >> layout->blueShift) & blueMask; - - alpha = (alpha << alphaLeftShift) | (alpha >> alphaRightShift); - red = (red << redLeftShift) | (red >> redRightShift); - green = (green << greenLeftShift) | (green >> greenRightShift); - blue = (blue << blueLeftShift) | (blue >> blueRightShift); - buffer[i] = qPremultiply((alpha << 24) | (red << 16) | (green << 8) | blue); - } - } - return buffer; -} - -static const uint *QT_FASTCALL convertToRGB32(uint *buffer, const uint *src, int count, - const QPixelLayout *layout, const QRgb *) -{ - Q_ASSERT(layout->redWidth >= 4); - Q_ASSERT(layout->greenWidth >= 4); - Q_ASSERT(layout->blueWidth >= 4); - Q_ASSERT(layout->alphaWidth == 0); - - const uint redMask = ((1 << layout->redWidth) - 1); - const uint greenMask = ((1 << layout->greenWidth) - 1); - const uint blueMask = ((1 << layout->blueWidth) - 1); - - const uchar redLeftShift = 8 - layout->redWidth; - const uchar greenLeftShift = 8 - layout->greenWidth; - const uchar blueLeftShift = 8 - layout->blueWidth; - - const uchar redRightShift = 2 * layout->redWidth - 8; - const uchar greenRightShift = 2 * layout->greenWidth - 8; - const uchar blueRightShift = 2 * layout->blueWidth - 8; - - for (int i = 0; i < count; ++i) { - uint red = (src[i] >> layout->redShift) & redMask; - uint green = (src[i] >> layout->greenShift) & greenMask; - uint blue = (src[i] >> layout->blueShift) & blueMask; - - red = (red << redLeftShift) | (red >> redRightShift); - green = (green << greenLeftShift) | (green >> greenRightShift); - blue = (blue << blueLeftShift) | (blue >> blueRightShift); - buffer[i] = 0xff000000 | (red << 16) | (green << 8) | blue; - } - return buffer; -} - -static const uint *QT_FASTCALL convertFromARGB32PM(uint *buffer, const uint *src, int count, - const QPixelLayout *layout, const QRgb *) -{ - Q_ASSERT(layout->redWidth <= 8); - Q_ASSERT(layout->greenWidth <= 8); - Q_ASSERT(layout->blueWidth <= 8); - Q_ASSERT(layout->alphaWidth <= 8); - - const uint redMask = (1 << layout->redWidth) - 1; - const uint greenMask = (1 << layout->greenWidth) - 1; - const uint blueMask = (1 << layout->blueWidth) - 1; - const uint alphaMask = (1 << layout->alphaWidth) - 1; - - const uchar redRightShift = 24 - layout->redWidth; - const uchar greenRightShift = 16 - layout->greenWidth; - const uchar blueRightShift = 8 - layout->blueWidth; - const uchar alphaRightShift = 32 - layout->alphaWidth; - - if (!layout->premultiplied) { - for (int i = 0; i < count; ++i) - buffer[i] = qUnpremultiply(src[i]); - src = buffer; - } - for (int i = 0; i < count; ++i) { - uint red = ((src[i] >> redRightShift) & redMask) << layout->redShift; - uint green = ((src[i] >> greenRightShift) & greenMask) << layout->greenShift; - uint blue = ((src[i] >> blueRightShift) & blueMask) << layout->blueShift; - uint alpha = ((src[i] >> alphaRightShift) & alphaMask) << layout->alphaShift; - buffer[i] = red | green | blue | alpha; - } - return buffer; -} - -static const uint *QT_FASTCALL convertFromRGB32(uint *buffer, const uint *src, int count, - const QPixelLayout *layout, const QRgb *) -{ - Q_ASSERT(layout->redWidth <= 8); - Q_ASSERT(layout->greenWidth <= 8); - Q_ASSERT(layout->blueWidth <= 8); - - const uint redMask = (1 << layout->redWidth) - 1; - const uint greenMask = (1 << layout->greenWidth) - 1; - const uint blueMask = (1 << layout->blueWidth) - 1; - const uint alphaMask = (1 << layout->alphaWidth) - 1; - - const uchar redRightShift = 24 - layout->redWidth; - const uchar greenRightShift = 16 - layout->greenWidth; - const uchar blueRightShift = 8 - layout->blueWidth; - - for (int i = 0; i < count; ++i) { - uint red = ((src[i] >> redRightShift) & redMask) << layout->redShift; - uint green = ((src[i] >> greenRightShift) & greenMask) << layout->greenShift; - uint blue = ((src[i] >> blueRightShift) & blueMask) << layout->blueShift; - uint alpha = (0xff & alphaMask) << layout->alphaShift; - buffer[i] = red | green | blue | alpha; - } - return buffer; -} - -static const uint *QT_FASTCALL convertRGB16ToRGB32(uint *buffer, const uint *src, int count, - const QPixelLayout *, const QRgb *) -{ - for (int i = 0; i < count; ++i) - buffer[i] = qConvertRgb16To32(src[i]); - return buffer; -} - -static const uint *QT_FASTCALL convertRGB16FromRGB32(uint *buffer, const uint *src, int count, - const QPixelLayout *, const QRgb *) -{ - for (int i = 0; i < count; ++i) - buffer[i] = qConvertRgb32To16(src[i]); - return buffer; -} - -static const uint *QT_FASTCALL convertRGB16FromARGB32PM(uint *buffer, const uint *src, int count, - const QPixelLayout *, const QRgb *) -{ - for (int i = 0; i < count; ++i) - buffer[i] = qConvertRgb32To16(qUnpremultiply(src[i])); - return buffer; -} #endif // To convert in place, let 'dest' and 'src' be the same. @@ -851,15 +680,42 @@ QPixelLayout qPixelLayouts[QImage::NImageFormats] = { pixelLayoutRGB<QImage::Format_RGB444>(), pixelLayoutARGBPM<QImage::Format_ARGB4444_Premultiplied>(), #else - { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertRGB16ToRGB32, convertRGB16FromARGB32PM, convertRGB16FromRGB32 }, // Format_RGB16 - { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, convertFromRGB32 }, // Format_ARGB8565_Premultiplied - { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB666 - { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, convertFromRGB32 }, // Format_ARGB6666_Premultiplied - { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB555 - { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, convertToARGB32PM, convertFromARGB32PM, convertFromRGB32 }, // Format_ARGB8555_Premultiplied - { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB888 - { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, convertToRGB32, convertFromARGB32PM, convertFromRGB32 }, // Format_RGB444 - { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, convertToARGB32PM, convertFromARGB32PM, convertFromRGB32 }, // Format_ARGB4444_Premultiplied + { 5, 11, 6, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, + convertToRGB32<QImage::Format_RGB16>, + convertRGBFromARGB32PM<QImage::Format_RGB16>, + convertRGBFromRGB32<QImage::Format_RGB16>}, + { 5, 19, 6, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, + convertARGBPMToARGB32PM<QImage::Format_ARGB8565_Premultiplied>, + convertARGBPMFromARGB32PM<QImage::Format_ARGB8565_Premultiplied>, + convertARGBPMFromRGB32<QImage::Format_ARGB8565_Premultiplied>}, + { 6, 12, 6, 6, 6, 0, 0, 0, false, QPixelLayout::BPP24, + convertToRGB32<QImage::Format_RGB666>, + convertRGBFromARGB32PM<QImage::Format_RGB666>, + convertRGBFromRGB32<QImage::Format_RGB666>}, + { 6, 12, 6, 6, 6, 0, 6, 18, true, QPixelLayout::BPP24, + convertARGBPMToARGB32PM<QImage::Format_ARGB6666_Premultiplied>, + convertARGBPMFromARGB32PM<QImage::Format_ARGB6666_Premultiplied>, + convertARGBPMFromRGB32<QImage::Format_ARGB6666_Premultiplied>}, + { 5, 10, 5, 5, 5, 0, 0, 0, false, QPixelLayout::BPP16, + convertToRGB32<QImage::Format_RGB555>, + convertRGBFromARGB32PM<QImage::Format_RGB555>, + convertRGBFromRGB32<QImage::Format_RGB555> }, + { 5, 18, 5, 13, 5, 8, 8, 0, true, QPixelLayout::BPP24, + convertARGBPMToARGB32PM<QImage::Format_ARGB8555_Premultiplied>, + convertARGBPMFromARGB32PM<QImage::Format_ARGB8555_Premultiplied>, + convertARGBPMFromRGB32<QImage::Format_ARGB8555_Premultiplied>}, + { 8, 16, 8, 8, 8, 0, 0, 0, false, QPixelLayout::BPP24, + convertToRGB32<QImage::Format_RGB888>, + convertRGBFromARGB32PM<QImage::Format_RGB888>, + convertRGBFromRGB32<QImage::Format_RGB888>}, + { 4, 8, 4, 4, 4, 0, 0, 0, false, QPixelLayout::BPP16, + convertToRGB32<QImage::Format_RGB444>, + convertRGBFromARGB32PM<QImage::Format_RGB444>, + convertRGBFromRGB32<QImage::Format_RGB444>}, + { 4, 8, 4, 4, 4, 0, 4, 12, true, QPixelLayout::BPP16, + convertARGBPMToARGB32PM<QImage::Format_ARGB4444_Premultiplied>, + convertARGBPMFromARGB32PM<QImage::Format_ARGB4444_Premultiplied>, + convertARGBPMFromRGB32<QImage::Format_ARGB4444_Premultiplied>}, #endif #if Q_BYTE_ORDER == Q_BIG_ENDIAN { 8, 24, 8, 16, 8, 8, 0, 0, false, QPixelLayout::BPP32, convertRGBA8888PMToARGB32PM, convertRGBXFromARGB32PM, convertRGBXFromRGB32 }, // Format_RGBX8888 diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h index 333bbb202f..ca80a88033 100644 --- a/src/gui/text/qtextdocument.h +++ b/src/gui/text/qtextdocument.h @@ -63,7 +63,6 @@ class QTextCursor; template<typename T> class QVector; -#ifndef Q_QDOC // Workaround for QTBUG-35230 namespace Qt { Q_GUI_EXPORT bool mightBeRichText(const QString&); @@ -73,7 +72,6 @@ namespace Qt Q_GUI_EXPORT QTextCodec *codecForHtml(const QByteArray &ba); #endif } -#endif // Q_QDOC class Q_GUI_EXPORT QAbstractUndoItem { diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index d31c04eb87..abb47e9e29 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -1078,7 +1078,7 @@ static QByteArray qStringAsUcs2Le(const QString& src) } -static QString qStringFromUcs2Le(const QByteArray& src) +static QString qStringFromUcs2Le(QByteArray src) { Q_ASSERT(src.size() % 2 == 0); unsigned short *d = (unsigned short*)src.data(); diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index 2054fb2c0a..9a993392e9 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -123,28 +123,41 @@ QHostAddressPrivate::QHostAddressPrivate() void QHostAddressPrivate::setAddress(quint32 a_) { a = a_; - //create mapped address + //create mapped address, except for a_ == 0 (any) memset(&a6, 0, sizeof(a6)); + if (a) { + a6[11] = 0xFF; + a6[10] = 0xFF; + } else { + a6[11] = 0; + a6[10] = 0; + } + int i; for (i=15; a_ != 0; i--) { a6[i] = a_ & 0xFF; a_ >>=8; } Q_ASSERT(i >= 11); - a6[11] = 0xFF; - a6[10] = 0xFF; protocol = QAbstractSocket::IPv4Protocol; isParsed = true; } -static bool parseMappedAddress(quint32& a, const Q_IPV6ADDR &a6) +/// parses v4-mapped addresses or the AnyIPv6 address and stores in \a a; +/// returns true if the address was one of those +static bool convertToIpv4(quint32& a, const Q_IPV6ADDR &a6) { - int i; - for (i=0;i<10;i++) - if (a6[i]) return false; - for (;i<12;i++) - if (a6[i] != 0xFF) return false; - a=(a6[12] << 24) | (a6[13] << 16) | (a6[14] << 8) | a6[15]; + const uchar *ptr = a6.c; + if (qFromUnaligned<quint64>(ptr) != 0) + return false; + if (qFromBigEndian<quint32>(ptr + 8) == 0) { + // is it AnyIPv6? + a = 0; + return qFromBigEndian<quint32>(ptr + 12) == 0; + } + if (qFromBigEndian<quint32>(ptr + 8) != 0xFFFF) + return false; + a = qFromBigEndian<quint32>(ptr + 12); return true; } @@ -153,10 +166,8 @@ void QHostAddressPrivate::setAddress(const quint8 *a_) for (int i = 0; i < 16; i++) a6[i] = a_[i]; a = 0; - if (parseMappedAddress(a, a6)) - protocol = QAbstractSocket::IPv4Protocol; - else - protocol = QAbstractSocket::IPv6Protocol; + convertToIpv4(a, a6); + protocol = QAbstractSocket::IPv6Protocol; isParsed = true; } @@ -164,10 +175,8 @@ void QHostAddressPrivate::setAddress(const Q_IPV6ADDR &a_) { a6 = a_; a = 0; - if (parseMappedAddress(a, a6)) - protocol = QAbstractSocket::IPv4Protocol; - else - protocol = QAbstractSocket::IPv6Protocol; + convertToIpv4(a, a6); + protocol = QAbstractSocket::IPv6Protocol; isParsed = true; } @@ -197,7 +206,6 @@ bool QHostAddressPrivate::parse() quint8 maybeIp6[16]; if (parseIp6(a, maybeIp6, &scopeId)) { setAddress(maybeIp6); - protocol = QAbstractSocket::IPv6Protocol; return true; } } @@ -205,7 +213,6 @@ bool QHostAddressPrivate::parse() quint32 maybeIp4 = 0; if (QIPAddressUtils::parseIp4(maybeIp4, a.constBegin(), a.constEnd())) { setAddress(maybeIp4); - protocol = QAbstractSocket::IPv4Protocol; return true; } @@ -627,7 +634,31 @@ void QHostAddress::setAddress(const struct sockaddr *sockaddr) */ quint32 QHostAddress::toIPv4Address() const { + return toIPv4Address(Q_NULLPTR); +} + +/*! + Returns the IPv4 address as a number. + + For example, if the address is 127.0.0.1, the returned value is + 2130706433 (i.e. 0x7f000001). + + This value is valid if the protocol() is + \l{QAbstractSocket::}{IPv4Protocol}, + or if the protocol is + \l{QAbstractSocket::}{IPv6Protocol}, + and the IPv6 address is an IPv4 mapped address. (RFC4291). In those + cases, \a ok will be set to true. Otherwise, it will be set to false. + + \sa toString() +*/ +quint32 QHostAddress::toIPv4Address(bool *ok) const +{ QT_ENSURE_PARSED(this); + quint32 dummy; + if (ok) + *ok = d->protocol == QAbstractSocket::IPv4Protocol || d->protocol == QAbstractSocket::AnyIPProtocol + || (d->protocol == QAbstractSocket::IPv6Protocol && convertToIpv4(dummy, d->a6)); return d->a; } diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h index 93d64ff54a..de3a79278e 100644 --- a/src/network/kernel/qhostaddress.h +++ b/src/network/kernel/qhostaddress.h @@ -93,7 +93,8 @@ public: bool setAddress(const QString &address); QAbstractSocket::NetworkLayerProtocol protocol() const; - quint32 toIPv4Address() const; + quint32 toIPv4Address() const; // ### Qt6: merge with next overload + quint32 toIPv4Address(bool *ok) const; Q_IPV6ADDR toIPv6Address() const; QString toString() const; diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index d2dc7c4850..a2ac9065fd 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -689,6 +689,7 @@ void qt_qhostinfo_clear_cache() } } +#ifdef QT_BUILD_INTERNAL void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e) { QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager(); @@ -697,6 +698,16 @@ void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e) } } +void qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolution) +{ + QAbstractHostInfoLookupManager* manager = theHostInfoLookupManager(); + if (!manager || !manager->cache.isEnabled()) + return; + + manager->cache.put(hostname, resolution); +} +#endif + // cache for 60 seconds // cache 128 items QHostInfoCache::QHostInfoCache() : max_age(60), enabled(true), cache(128) diff --git a/src/network/kernel/qhostinfo_p.h b/src/network/kernel/qhostinfo_p.h index 74cfe2a9aa..a99c3dc8ca 100644 --- a/src/network/kernel/qhostinfo_p.h +++ b/src/network/kernel/qhostinfo_p.h @@ -117,6 +117,7 @@ public: QHostInfo Q_NETWORK_EXPORT qt_qhostinfo_lookup(const QString &name, QObject *receiver, const char *member, bool *valid, int *id); void Q_AUTOTEST_EXPORT qt_qhostinfo_clear_cache(); void Q_AUTOTEST_EXPORT qt_qhostinfo_enable_cache(bool e); +void Q_AUTOTEST_EXPORT qt_qhostinfo_cache_inject(const QString &hostname, const QHostInfo &resolution); class QHostInfoCache { diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index f9fe40955a..3b10387b37 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -976,7 +976,7 @@ void QAbstractSocketPrivate::startConnectingByName(const QString &host) connectTimeElapsed = 0; - if (initSocketLayer(QAbstractSocket::UnknownNetworkLayerProtocol)) { + if (cachedSocketDescriptor != -1 || initSocketLayer(QAbstractSocket::UnknownNetworkLayerProtocol)) { if (socketEngine->connectToHostByName(host, port) || socketEngine->state() == QAbstractSocket::ConnectingState) { cachedSocketDescriptor = socketEngine->socketDescriptor(); @@ -1117,7 +1117,7 @@ void QAbstractSocketPrivate::_q_connectToNextAddress() host.toString().toLatin1().constData(), port, addresses.count()); #endif - if (!initSocketLayer(host.protocol())) { + if (cachedSocketDescriptor == -1 && !initSocketLayer(host.protocol())) { // hope that the next address is better #if defined(QABSTRACTSOCKET_DEBUG) qDebug("QAbstractSocketPrivate::_q_connectToNextAddress(), failed to initialize sock layer"); @@ -1134,9 +1134,6 @@ void QAbstractSocketPrivate::_q_connectToNextAddress() return; } - // cache the socket descriptor even if we're not fully connected yet - cachedSocketDescriptor = socketEngine->socketDescriptor(); - // Check that we're in delayed connection state. If not, try // the next address if (socketEngine->state() != QAbstractSocket::ConnectingState) { @@ -1481,54 +1478,60 @@ void QAbstractSocket::setPauseMode(PauseModes pauseMode) bool QAbstractSocket::bind(const QHostAddress &address, quint16 port, BindMode mode) { Q_D(QAbstractSocket); + return d->bind(address, port, mode); +} + +bool QAbstractSocketPrivate::bind(const QHostAddress &address, quint16 port, QAbstractSocket::BindMode mode) +{ + Q_Q(QAbstractSocket); // now check if the socket engine is initialized and to the right type - if (!d->socketEngine || !d->socketEngine->isValid()) { + if (!socketEngine || !socketEngine->isValid()) { QHostAddress nullAddress; - d->resolveProxy(nullAddress.toString(), port); + resolveProxy(nullAddress.toString(), port); QAbstractSocket::NetworkLayerProtocol protocol = address.protocol(); if (protocol == QAbstractSocket::UnknownNetworkLayerProtocol) protocol = nullAddress.protocol(); - if (!d->initSocketLayer(protocol)) + if (!initSocketLayer(protocol)) return false; } - if (mode != DefaultForPlatform) { + if (mode != QAbstractSocket::DefaultForPlatform) { #ifdef Q_OS_UNIX - if ((mode & ShareAddress) || (mode & ReuseAddressHint)) - d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1); + if ((mode & QAbstractSocket::ShareAddress) || (mode & QAbstractSocket::ReuseAddressHint)) + socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1); else - d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 0); + socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 0); #endif #ifdef Q_OS_WIN - if (mode & ReuseAddressHint) - d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1); + if (mode & QAbstractSocket::ReuseAddressHint) + socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 1); else - d->socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 0); - if (mode & DontShareAddress) - d->socketEngine->setOption(QAbstractSocketEngine::BindExclusively, 1); + socketEngine->setOption(QAbstractSocketEngine::AddressReusable, 0); + if (mode & QAbstractSocket::DontShareAddress) + socketEngine->setOption(QAbstractSocketEngine::BindExclusively, 1); else - d->socketEngine->setOption(QAbstractSocketEngine::BindExclusively, 0); + socketEngine->setOption(QAbstractSocketEngine::BindExclusively, 0); #endif } - bool result = d->socketEngine->bind(address, port); - d->cachedSocketDescriptor = d->socketEngine->socketDescriptor(); + bool result = socketEngine->bind(address, port); + cachedSocketDescriptor = socketEngine->socketDescriptor(); if (!result) { - d->socketError = d->socketEngine->error(); - setErrorString(d->socketEngine->errorString()); - emit error(d->socketError); + socketError = socketEngine->error(); + q->setErrorString(socketEngine->errorString()); + emit q->error(socketError); return false; } - d->state = BoundState; - d->localAddress = d->socketEngine->localAddress(); - d->localPort = d->socketEngine->localPort(); + state = QAbstractSocket::BoundState; + localAddress = socketEngine->localAddress(); + localPort = socketEngine->localPort(); - emit stateChanged(d->state); - d->socketEngine->setReadNotificationEnabled(true); + emit q->stateChanged(state); + socketEngine->setReadNotificationEnabled(true); return true; } @@ -1605,14 +1608,16 @@ void QAbstractSocket::connectToHost(const QString &hostName, quint16 port, d->preferredNetworkLayerProtocol = protocol; d->hostName = hostName; d->port = port; - d->state = UnconnectedState; d->buffer.clear(); d->writeBuffer.clear(); d->abortCalled = false; d->pendingClose = false; - d->localPort = 0; + if (d->state != BoundState) { + d->state = UnconnectedState; + d->localPort = 0; + d->localAddress.clear(); + } d->peerPort = 0; - d->localAddress.clear(); d->peerAddress.clear(); d->peerName = hostName; if (d->hostLookupId != -1) { diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h index 76b1e5f538..f3d7f13f48 100644 --- a/src/network/socket/qabstractsocket.h +++ b/src/network/socket/qabstractsocket.h @@ -135,9 +135,11 @@ public: PauseModes pauseMode() const; void setPauseMode(PauseModes pauseMode); + // ### Qt6: make the first one virtual bool bind(const QHostAddress &address, quint16 port = 0, BindMode mode = DefaultForPlatform); bool bind(quint16 port = 0, BindMode mode = DefaultForPlatform); + // ### Qt6: de-virtualize connectToHost(QHostAddress) overload virtual void connectToHost(const QString &hostName, quint16 port, OpenMode mode = ReadWrite, NetworkLayerProtocol protocol = AnyIPProtocol); virtual void connectToHost(const QHostAddress &address, quint16 port, OpenMode mode = ReadWrite); virtual void disconnectFromHost(); diff --git a/src/network/socket/qabstractsocket_p.h b/src/network/socket/qabstractsocket_p.h index 379657f4fa..63440b6416 100644 --- a/src/network/socket/qabstractsocket_p.h +++ b/src/network/socket/qabstractsocket_p.h @@ -78,6 +78,8 @@ public: } #endif + virtual bool bind(const QHostAddress &address, quint16 port, QAbstractSocket::BindMode mode); + bool canReadNotification(); bool canWriteNotification(); void canCloseNotification(); diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp index db6c7c487a..52e6922b5f 100644 --- a/src/network/socket/qnativesocketengine.cpp +++ b/src/network/socket/qnativesocketengine.cpp @@ -136,6 +136,12 @@ QT_BEGIN_NAMESPACE " not in "#state1" or "#state2); \ return (returnValue); \ } } while (0) +#define Q_CHECK_STATES3(function, state1, state2, state3, returnValue) do { \ + if (d->socketState != (state1) && d->socketState != (state2) && d->socketState != (state3)) { \ + qWarning(""#function" was called" \ + " not in "#state1" or "#state2); \ + return (returnValue); \ + } } while (0) #define Q_CHECK_TYPE(function, type, returnValue) do { \ if (d->socketType != (type)) { \ qWarning(#function" was called by a" \ @@ -275,6 +281,38 @@ void QNativeSocketEnginePrivate::setError(QAbstractSocket::SocketError error, Er } } +/*! + \internal + + Adjusts the incoming \a address family to match the currently bound address + (if any). This function will convert v4-mapped IPv6 addresses to IPv4 and + vice-versa. All other address types and values will be left unchanged. + */ +QHostAddress QNativeSocketEnginePrivate::adjustAddressProtocol(const QHostAddress &address) const +{ + QAbstractSocket::NetworkLayerProtocol targetProtocol = socketProtocol; + if (Q_LIKELY(targetProtocol == QAbstractSocket::UnknownNetworkLayerProtocol)) + return address; + + QAbstractSocket::NetworkLayerProtocol sourceProtocol = address.protocol(); + + if (targetProtocol == QAbstractSocket::AnyIPProtocol) + targetProtocol = QAbstractSocket::IPv6Protocol; + if (targetProtocol == QAbstractSocket::IPv6Protocol && sourceProtocol == QAbstractSocket::IPv4Protocol) { + // convert to IPv6 v4-mapped address. This always works + return QHostAddress(address.toIPv6Address()); + } + + if (targetProtocol == QAbstractSocket::IPv4Protocol && sourceProtocol == QAbstractSocket::IPv6Protocol) { + // convert to IPv4 if the source is a v4-mapped address + quint32 ip4 = address.toIPv4Address(); + if (ip4) + return QHostAddress(ip4); + } + + return address; +} + bool QNativeSocketEnginePrivate::checkProxy(const QHostAddress &address) { if (address.isLoopback()) @@ -495,12 +533,12 @@ bool QNativeSocketEngine::connectToHost(const QHostAddress &address, quint16 por if (!d->checkProxy(address)) return false; - Q_CHECK_STATES(QNativeSocketEngine::connectToHost(), + Q_CHECK_STATES3(QNativeSocketEngine::connectToHost(), QAbstractSocket::BoundState, QAbstractSocket::UnconnectedState, QAbstractSocket::ConnectingState, false); d->peerAddress = address; d->peerPort = port; - bool connected = d->nativeConnect(address, port); + bool connected = d->nativeConnect(d->adjustAddressProtocol(address), port); if (connected) d->fetchConnectionParameters(); @@ -560,7 +598,7 @@ bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port) Q_CHECK_STATE(QNativeSocketEngine::bind(), QAbstractSocket::UnconnectedState, false); - if (!d->nativeBind(address, port)) + if (!d->nativeBind(d->adjustAddressProtocol(address), port)) return false; d->fetchConnectionParameters(); @@ -770,7 +808,7 @@ qint64 QNativeSocketEngine::writeDatagram(const char *data, qint64 size, Q_D(QNativeSocketEngine); Q_CHECK_VALID_SOCKETLAYER(QNativeSocketEngine::writeDatagram(), -1); Q_CHECK_TYPE(QNativeSocketEngine::writeDatagram(), QAbstractSocket::UdpSocket, -1); - return d->nativeSendDatagram(data, size, host, port); + return d->nativeSendDatagram(data, size, d->adjustAddressProtocol(host), port); } /*! @@ -961,7 +999,7 @@ bool QNativeSocketEngine::waitForWrite(int msecs, bool *timedOut) QNativeSocketEnginePrivate::TimeOutErrorString); d->hasSetSocketError = false; // A timeout error is temporary in waitFor functions return false; - } else if (state() == QAbstractSocket::ConnectingState) { + } else if (state() == QAbstractSocket::ConnectingState || (state() == QAbstractSocket::BoundState && d->socketDescriptor != -1)) { connectToHost(d->peerAddress, d->peerPort); } diff --git a/src/network/socket/qnativesocketengine_p.h b/src/network/socket/qnativesocketengine_p.h index 4ec6023d4b..24909bf310 100644 --- a/src/network/socket/qnativesocketengine_p.h +++ b/src/network/socket/qnativesocketengine_p.h @@ -232,6 +232,7 @@ public: }; void setError(QAbstractSocket::SocketError error, ErrorString errorString) const; + QHostAddress adjustAddressProtocol(const QHostAddress &address) const; // native functions int option(QNativeSocketEngine::SocketOption option) const; diff --git a/src/network/ssl/qsslcontext_openssl.cpp b/src/network/ssl/qsslcontext_openssl.cpp index a7295933b5..b88ab54038 100644 --- a/src/network/ssl/qsslcontext_openssl.cpp +++ b/src/network/ssl/qsslcontext_openssl.cpp @@ -60,7 +60,7 @@ static DH *get_dh1024() "/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC")); const char *ptr = params.constData(); - DH *dh = q_d2i_DHparams(NULL, (unsigned char **)(&ptr), params.length()); + DH *dh = q_d2i_DHparams(NULL, reinterpret_cast<const unsigned char **>(&ptr), params.length()); return dh; } diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 508d300d42..b1076ebd68 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -2404,6 +2404,29 @@ bool QSslSocketPrivate::isPaused() const return paused; } +bool QSslSocketPrivate::bind(const QHostAddress &address, quint16 port, QAbstractSocket::BindMode mode) +{ + // this function is called from QAbstractSocket::bind + if (!initialized) + init(); + initialized = false; + +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << "QSslSocket::bind(" << address << ',' << port << ',' << mode << ')'; +#endif + if (!plainSocket) { +#ifdef QSSLSOCKET_DEBUG + qCDebug(lcSsl) << "\tcreating internal plain socket"; +#endif + createPlainSocket(QIODevice::ReadWrite); + } + bool ret = plainSocket->bind(address, port, mode); + localPort = plainSocket->localPort(); + localAddress = plainSocket->localAddress(); + cachedSocketDescriptor = plainSocket->socketDescriptor(); + return ret; +} + /*! \internal */ diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index 7d29e25e33..e2700df3cc 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -399,7 +399,7 @@ DEFINEFUNC3(void, SSL_get0_next_proto_negotiated, const SSL *s, s, #endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ... DEFINEFUNC(DH *, DH_new, DUMMYARG, DUMMYARG, return 0, return) DEFINEFUNC(void, DH_free, DH *dh, dh, return, DUMMYARG) -DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, unsigned char **pp, pp, long length, length, return 0, return); +DEFINEFUNC3(DH *, d2i_DHparams, DH**a, a, const unsigned char **pp, pp, long length, length, return 0, return) DEFINEFUNC3(BIGNUM *, BN_bin2bn, const unsigned char *s, s, int len, len, BIGNUM *ret, ret, return 0, return) #ifndef OPENSSL_NO_EC DEFINEFUNC(EC_KEY *, EC_KEY_dup, const EC_KEY *ec, ec, return 0, return) diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index aedd477b39..626c049629 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -440,7 +440,7 @@ STACK_OF(X509) *q_X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); // Diffie-Hellman support DH *q_DH_new(); void q_DH_free(DH *dh); -DH *q_d2i_DHparams(DH **a, unsigned char **pp, long length); +DH *q_d2i_DHparams(DH **a, const unsigned char **pp, long length); BIGNUM *q_BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); #define q_SSL_CTX_set_tmp_dh(ctx, dh) q_SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TMP_DH, 0, (char *)dh) diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index b110d65f9a..5f726f2371 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -172,6 +172,7 @@ public: static void checkSettingSslContext(QSslSocket*, QSharedPointer<QSslContext>); static QSharedPointer<QSslContext> sslContext(QSslSocket *socket); bool isPaused() const; + bool bind(const QHostAddress &address, quint16, QAbstractSocket::BindMode) Q_DECL_OVERRIDE; void _q_connectedSlot(); void _q_hostFoundSlot(); void _q_disconnectedSlot(); diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp index fc6e4bad8d..bf23d52465 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp @@ -62,7 +62,7 @@ QEGLPlatformCursor::QEGLPlatformCursor(QPlatformScreen *screen) m_textureCoordEntry(0), m_textureEntry(0), m_deviceListener(0), - m_updater(screen) + m_updateRequested(false) { QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR"); if (!hideCursorVal.isEmpty()) @@ -246,30 +246,43 @@ bool QEGLPlatformCursor::setCurrentCursor(QCursor *cursor) } #endif -void QEGLPlatformCursorUpdater::update(const QPoint &pos, const QRegion &rgn) +class CursorUpdateEvent : public QEvent { - m_active = false; - QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(pos), rgn); - QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); -} - -void QEGLPlatformCursorUpdater::scheduleUpdate(const QPoint &pos, const QRegion &rgn) +public: + CursorUpdateEvent(const QPoint &pos, const QRegion &rgn) + : QEvent(QEvent::Type(QEvent::User + 1)), + m_pos(pos), + m_region(rgn) + { } + QPoint pos() const { return m_pos; } + QRegion region() const { return m_region; } + +private: + QPoint m_pos; + QRegion m_region; +}; + +bool QEGLPlatformCursor::event(QEvent *e) { - if (m_active) - return; - - m_active = true; - - // Must not flush the window system events directly from here since we are likely to - // be a called directly from QGuiApplication's processMouseEvents. Flushing events - // could cause reentering by dispatching more queued mouse events. - QMetaObject::invokeMethod(this, "update", Qt::QueuedConnection, - Q_ARG(QPoint, pos), Q_ARG(QRegion, rgn)); + if (e->type() == QEvent::User + 1) { + CursorUpdateEvent *ev = static_cast<CursorUpdateEvent *>(e); + m_updateRequested = false; + QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(ev->pos()), ev->region()); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); + return true; + } + return QPlatformCursor::event(e); } void QEGLPlatformCursor::update(const QRegion &rgn) { - m_updater.scheduleUpdate(m_cursor.pos, rgn); + if (!m_updateRequested) { + // Must not flush the window system events directly from here since we are likely to + // be a called directly from QGuiApplication's processMouseEvents. Flushing events + // could cause reentering by dispatching more queued mouse events. + m_updateRequested = true; + QCoreApplication::postEvent(this, new CursorUpdateEvent(m_cursor.pos, rgn)); + } } QRect QEGLPlatformCursor::cursorRect() const diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h index 1c05a06b63..481bb3c74c 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h @@ -70,24 +70,6 @@ private: QEGLPlatformCursor *m_cursor; }; -class QEGLPlatformCursorUpdater : public QObject -{ - Q_OBJECT - -public: - QEGLPlatformCursorUpdater(QPlatformScreen *screen) - : m_screen(screen), m_active(false) { } - - void scheduleUpdate(const QPoint &pos, const QRegion &rgn); - -private slots: - void update(const QPoint &pos, const QRegion &rgn); - -private: - QPlatformScreen *m_screen; - bool m_active; -}; - class QEGLPlatformCursor : public QPlatformCursor, protected QOpenGLFunctions { Q_OBJECT @@ -109,6 +91,7 @@ public: void updateMouseStatus(); private: + bool event(QEvent *e) Q_DECL_OVERRIDE; #ifndef QT_NO_CURSOR bool setCurrentCursor(QCursor *cursor); #endif @@ -150,7 +133,7 @@ private: int m_textureCoordEntry; int m_textureEntry; QEGLPlatformCursorDeviceListener *m_deviceListener; - QEGLPlatformCursorUpdater m_updater; + bool m_updateRequested; }; QT_END_NAMESPACE diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h index 3b6c862333..42fbf8c8a1 100644 --- a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h @@ -90,6 +90,8 @@ public: QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE; + QFbVtHandler *vtHandler() { return m_vtHandler.data(); } + protected: virtual QEGLPlatformWindow *createWindow(QWindow *window) const = 0; virtual QEGLPlatformContext *createContext(const QSurfaceFormat &format, diff --git a/src/platformsupport/fbconvenience/qfbvthandler.cpp b/src/platformsupport/fbconvenience/qfbvthandler.cpp index d534985129..84844d8eda 100644 --- a/src/platformsupport/fbconvenience/qfbvthandler.cpp +++ b/src/platformsupport/fbconvenience/qfbvthandler.cpp @@ -32,72 +32,148 @@ ****************************************************************************/ #include "qfbvthandler_p.h" -#include <QtCore/private/qcrashhandler_p.h> -#include <QtGui/private/qguiapplication_p.h> +#include <QtCore/QSocketNotifier> -#if defined(Q_OS_LINUX) && !defined(QT_NO_EVDEV) -#define HAS_VT -#endif +#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID) && (!defined(QT_NO_EVDEV) || !defined(QT_NO_LIBINPUT)) -#ifdef HAS_VT +#define VTH_ENABLED +#include <unistd.h> +#include <signal.h> +#include <errno.h> +#include <sys/signalfd.h> #include <sys/ioctl.h> #include <linux/kd.h> +#ifndef KDSKBMUTE +#define KDSKBMUTE 0x4B51 +#endif + #ifdef K_OFF #define KBD_OFF_MODE K_OFF #else #define KBD_OFF_MODE K_RAW #endif -#endif // HAS_VT +#endif QT_BEGIN_NAMESPACE -QFbVtHandler *QFbVtHandler::self = 0; - QFbVtHandler::QFbVtHandler(QObject *parent) - : QObject(parent), m_tty(-1) + : QObject(parent), + m_tty(-1), + m_signalFd(-1), + m_signalNotifier(0) { - Q_ASSERT(!self); - self = this; +#ifdef VTH_ENABLED + if (isatty(0)) { + m_tty = 0; + ioctl(m_tty, KDGKBMODE, &m_oldKbdMode); + + if (!qEnvironmentVariableIntValue("QT_QPA_ENABLE_TERMINAL_KEYBOARD")) { + // Disable the tty keyboard. + ioctl(m_tty, KDSKBMUTE, 1); + ioctl(m_tty, KDSKBMODE, KBD_OFF_MODE); + } + } -#ifdef HAS_VT - if (!isatty(0)) - return; + // SIGSEGV and such cannot safely be blocked. We cannot handle them in an + // async-safe manner either. Restoring the keyboard, video mode, etc. may + // all contain calls that cannot safely be made from a signal handler. - m_tty = 0; - ::ioctl(m_tty, KDGKBMODE, &m_oldKbdMode); - if (!qEnvironmentVariableIntValue("QT_QPA_ENABLE_TERMINAL_KEYBOARD")) { - ::ioctl(m_tty, KDSKBMODE, KBD_OFF_MODE); - QGuiApplicationPrivate *appd = QGuiApplicationPrivate::instance(); - Q_ASSERT(appd); - QSegfaultHandler::initialize(appd->argv, appd->argc); - QSegfaultHandler::installCrashHandler(crashHandler); + // Other signals: block them and use signalfd. + sigset_t mask; + sigemptyset(&mask); + + // Catch Ctrl+C. + sigaddset(&mask, SIGINT); + + // Ctrl+Z. Up to the platform plugins to handle it in a meaningful way. + sigaddset(&mask, SIGTSTP); + sigaddset(&mask, SIGCONT); + + // Default signal used by kill. To overcome the common issue of no cleaning + // up when killing a locally started app via a remote session. + sigaddset(&mask, SIGTERM); + + m_signalFd = signalfd(-1, &mask, SFD_CLOEXEC); + if (m_signalFd < 0) { + qErrnoWarning(errno, "signalfd() failed"); + } else { + m_signalNotifier = new QSocketNotifier(m_signalFd, QSocketNotifier::Read, this); + connect(m_signalNotifier, &QSocketNotifier::activated, this, &QFbVtHandler::handleSignal); + + // Block the signals that are handled via signalfd. Applies only to the current + // thread, but new threads will inherit the creator's signal mask. + pthread_sigmask(SIG_BLOCK, &mask, 0); } #endif } QFbVtHandler::~QFbVtHandler() { - self->cleanup(); - self = 0; +#ifdef VTH_ENABLED + restoreKeyboard(); + + if (m_signalFd != -1) + close(m_signalFd); +#endif } -void QFbVtHandler::cleanup() +void QFbVtHandler::restoreKeyboard() { +#ifdef VTH_ENABLED if (m_tty == -1) return; -#ifdef HAS_VT - ::ioctl(m_tty, KDSKBMODE, m_oldKbdMode); + ioctl(m_tty, KDSKBMUTE, 0); + ioctl(m_tty, KDSKBMODE, m_oldKbdMode); +#endif +} + +// To be called from the slot connected to suspendRequested() in case the +// platform plugin does in fact allow suspending on Ctrl+Z. +void QFbVtHandler::suspend() +{ +#ifdef VTH_ENABLED + kill(getpid(), SIGSTOP); +#endif +} + +void QFbVtHandler::handleSignal() +{ +#ifdef VTH_ENABLED + m_signalNotifier->setEnabled(false); + + signalfd_siginfo sig; + if (read(m_signalFd, &sig, sizeof(sig)) == sizeof(sig)) { + switch (sig.ssi_signo) { + case SIGINT: // fallthrough + case SIGTERM: + handleInt(); + break; + case SIGTSTP: + emit suspendRequested(); + break; + case SIGCONT: + emit resumed(); + break; + default: + break; + } + } + + m_signalNotifier->setEnabled(true); #endif } -void QFbVtHandler::crashHandler() +void QFbVtHandler::handleInt() { - Q_ASSERT(self); - self->cleanup(); +#ifdef VTH_ENABLED + emit interrupted(); + restoreKeyboard(); + _exit(1); +#endif } QT_END_NAMESPACE diff --git a/src/platformsupport/fbconvenience/qfbvthandler_p.h b/src/platformsupport/fbconvenience/qfbvthandler_p.h index 53a39fd58b..3681def9f0 100644 --- a/src/platformsupport/fbconvenience/qfbvthandler_p.h +++ b/src/platformsupport/fbconvenience/qfbvthandler_p.h @@ -49,6 +49,8 @@ QT_BEGIN_NAMESPACE +class QSocketNotifier; + class QFbVtHandler : public QObject { Q_OBJECT @@ -57,13 +59,24 @@ public: QFbVtHandler(QObject *parent = 0); ~QFbVtHandler(); + void suspend(); + +signals: + void interrupted(); + void suspendRequested(); + void resumed(); + +private slots: + void handleSignal(); + private: - void cleanup(); - static void crashHandler(); + void restoreKeyboard(); + void handleInt(); - static QFbVtHandler *self; int m_tty; int m_oldKbdMode; + int m_signalFd; + QSocketNotifier *m_signalNotifier; }; QT_END_NAMESPACE diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm index a022587e11..99f54237bc 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm @@ -270,23 +270,29 @@ static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd) fd->fixedPitch = false; if (QCFType<CTFontRef> tempFont = CTFontCreateWithFontDescriptor(font, 0.0, 0)) { - uint length = 0; uint tag = MAKE_TAG('O', 'S', '/', '2'); CTFontRef tempFontRef = tempFont; void *userData = reinterpret_cast<void *>(&tempFontRef); - if (QCoreTextFontEngine::ct_getSfntTable(userData, tag, 0, &length)) { - QVarLengthArray<uchar> os2Table(length); - if (length >= 86 && QCoreTextFontEngine::ct_getSfntTable(userData, tag, os2Table.data(), &length)) { - quint32 unicodeRange[4] = { - qFromBigEndian<quint32>(os2Table.data() + 42), - qFromBigEndian<quint32>(os2Table.data() + 46), - qFromBigEndian<quint32>(os2Table.data() + 50), - qFromBigEndian<quint32>(os2Table.data() + 54) - }; - quint32 codePageRange[2] = { qFromBigEndian<quint32>(os2Table.data() + 78), - qFromBigEndian<quint32>(os2Table.data() + 82) }; - fd->writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange); + uint length = 128; + QVarLengthArray<uchar, 128> os2Table(length); + if (QCoreTextFontEngine::ct_getSfntTable(userData, tag, os2Table.data(), &length) && length >= 86) { + if (length > os2Table.length()) { + os2Table.resize(length); + if (!QCoreTextFontEngine::ct_getSfntTable(userData, tag, os2Table.data(), &length)) + Q_UNREACHABLE(); + Q_ASSERT(length >= 86); } + quint32 unicodeRange[4] = { + qFromBigEndian<quint32>(os2Table.data() + 42), + qFromBigEndian<quint32>(os2Table.data() + 46), + qFromBigEndian<quint32>(os2Table.data() + 50), + qFromBigEndian<quint32>(os2Table.data() + 54) + }; + quint32 codePageRange[2] = { + qFromBigEndian<quint32>(os2Table.data() + 78), + qFromBigEndian<quint32>(os2Table.data() + 82) + }; + fd->writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange); } } @@ -342,11 +348,7 @@ void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font) { FontDescription fd; getFontDescription(font, &fd); - populateFromFontDescription(font, fd); -} -void QCoreTextFontDatabase::populateFromFontDescription(CTFontDescriptorRef font, const FontDescription &fd) -{ CFRetain(font); QPlatformFontDatabase::registerFont(fd.familyName, fd.styleName, fd.foundryName, fd.weight, fd.style, fd.stretch, true /* antialiased */, true /* scalable */, diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h index 42c8701a71..822d6f9b9c 100644 --- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h +++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h @@ -70,8 +70,6 @@ Q_DECLARE_METATYPE(ATSFontContainerRef); QT_BEGIN_NAMESPACE -struct FontDescription; - class QCoreTextFontDatabase : public QPlatformFontDatabase { public: @@ -96,7 +94,6 @@ public: private: void populateFromDescriptor(CTFontDescriptorRef font); - void populateFromFontDescription(CTFontDescriptorRef font, const FontDescription &fd); mutable QString defaultFontName; diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm index 64de364bfb..7e1dfd9275 100644 --- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm +++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm @@ -250,11 +250,9 @@ bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout * int glyph_pos = 0; for (int i = 0; i < len; ++i) { - if (cgGlyphs[i]) { - glyphs->glyphs[glyph_pos] = cgGlyphs[i]; - if (glyph_pos < i) - cgGlyphs[glyph_pos] = cgGlyphs[i]; - } + glyphs->glyphs[glyph_pos] = cgGlyphs[i]; + if (glyph_pos < i) + cgGlyphs[glyph_pos] = cgGlyphs[i]; glyph_pos++; // If it's a non-BMP char, skip the lower part of surrogate pair and go diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index f711450fab..a18e9dac5f 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -589,8 +589,10 @@ static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state { m_activityActive = (state == Qt::ApplicationActive); - if (!m_main || !m_androidPlatformIntegration || !QGuiApplicationPrivate::platformIntegration()) + if (!m_main || !m_androidPlatformIntegration || !QGuiApplicationPrivate::platformIntegration()) { + QAndroidPlatformIntegration::setDefaultApplicationState(Qt::ApplicationState(state)); return; + } if (state <= Qt::ApplicationInactive) { // Don't send timers and sockets events anymore if we are going to hide all windows diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp index 93532a62e9..5384b6faca 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.cpp +++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp @@ -34,6 +34,7 @@ #include "qandroidplatformintegration.h" #include <QtCore/private/qjni_p.h> +#include <QtGui/private/qguiapplication_p.h> #include <QGuiApplication> #include <QOpenGLContext> #include <QThread> @@ -72,6 +73,8 @@ int QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight = 71; Qt::ScreenOrientation QAndroidPlatformIntegration::m_orientation = Qt::PrimaryOrientation; Qt::ScreenOrientation QAndroidPlatformIntegration::m_nativeOrientation = Qt::PrimaryOrientation; +Qt::ApplicationState QAndroidPlatformIntegration::m_defaultApplicationState = Qt::ApplicationActive; + void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource) { if (resource=="JavaVM") @@ -176,6 +179,8 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶ QWindowSystemInterface::registerTouchDevice(m_touchDevice); } } + + QGuiApplicationPrivate::instance()->setApplicationState(m_defaultApplicationState); } bool QAndroidPlatformIntegration::needsBasicRenderloopWorkaround() diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h index b08d3d872c..c0a9229056 100644 --- a/src/plugins/platforms/android/qandroidplatformintegration.h +++ b/src/plugins/platforms/android/qandroidplatformintegration.h @@ -115,6 +115,7 @@ public: QTouchDevice *touchDevice() const { return m_touchDevice; } void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; } + static void setDefaultApplicationState(Qt::ApplicationState applicationState) { m_defaultApplicationState = applicationState; } EGLDisplay m_eglDisplay; private: @@ -136,6 +137,8 @@ private: static Qt::ScreenOrientation m_orientation; static Qt::ScreenOrientation m_nativeOrientation; + static Qt::ApplicationState m_defaultApplicationState; + QPlatformFontDatabase *m_androidFDB; QImage *m_FbScreenImage; QPainter *m_compositePainter; diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp index 272480e25f..9dc94df451 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include "qwindowsdirect2dbackingstore.h" +#include "qwindowsdirect2dplatformpixmap.h" #include "qwindowsdirect2dintegration.h" #include "qwindowsdirect2dcontext.h" #include "qwindowsdirect2dpaintdevice.h" diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h index 3687f47f4d..1c7f65a12d 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbackingstore.h @@ -34,11 +34,7 @@ #ifndef QWINDOWSDIRECT2DBACKINGSTORE_H #define QWINDOWSDIRECT2DBACKINGSTORE_H -#include "qwindowsdirect2dplatformpixmap.h" - -#include <QtCore/QScopedPointer> #include <QtGui/qpa/qplatformbackingstore.h> -#include <QtGui/QPixmap> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h index 22c81cf658..a6ae6d76d8 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.h @@ -34,8 +34,9 @@ #ifndef QWINDOWSDIRECT2DBITMAP_H #define QWINDOWSDIRECT2DBITMAP_H +#include <QtCore/qnamespace.h> +#include <QtCore/QRect> #include <QtCore/QScopedPointer> -#include <QtGui/QImage> struct ID2D1DeviceContext; struct ID2D1Bitmap1; @@ -44,6 +45,11 @@ QT_BEGIN_NAMESPACE class QWindowsDirect2DDeviceContext; class QWindowsDirect2DBitmapPrivate; + +class QImage; +class QSize; +class QColor; + class QWindowsDirect2DBitmap { Q_DECLARE_PRIVATE(QWindowsDirect2DBitmap) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h index e7c920cf53..312955b54a 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.h @@ -34,8 +34,6 @@ #ifndef QWINDOWSDIRECT2DDEVICECONTEXT_H #define QWINDOWSDIRECT2DDEVICECONTEXT_H -#include "qwindowsdirect2dhelpers.h" - #include <QtCore/QScopedPointer> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index 36cfff43f5..d439196dc1 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -51,6 +51,10 @@ #include <QtGui/private/qfontengine_p.h> #include <QtGui/private/qstatictext_p.h> +#include <d2d1_1.h> +#include <dwrite_1.h> +#include <wrl.h> + using Microsoft::WRL::ComPtr; QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h index a75c0b6cc7..5e0f0b4b97 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.h @@ -37,9 +37,7 @@ #include <QtCore/QScopedPointer> #include <QtGui/private/qpaintengineex_p.h> -#include <d2d1_1.h> -#include <dwrite_1.h> -#include <wrl.h> +struct ID2D1Geometry; QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp index 414d2fb36e..e762eab711 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include "qwindowsdirect2dcontext.h" +#include "qwindowsdirect2dbitmap.h" #include "qwindowsdirect2dwindow.h" #include "qwindowsdirect2ddevicecontext.h" #include "qwindowsdirect2dhelpers.h" @@ -39,6 +40,8 @@ #include <d3d11.h> #include <d2d1_1.h> +#include <dxgi1_2.h> + using Microsoft::WRL::ComPtr; QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h index 0c0240b1dc..707305a515 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h @@ -35,13 +35,15 @@ #define QWINDOWSDIRECT2DWINDOW_H #include "qwindowswindow.h" -#include "qwindowsdirect2dbitmap.h" - -#include <dxgi1_2.h> #include <wrl.h> +struct IDXGISwapChain1; +struct ID2D1DeviceContext; + QT_BEGIN_NAMESPACE +class QWindowsDirect2DBitmap; + class QWindowsDirect2DWindow : public QWindowsWindow { public: diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro index d8ce385636..0adbb0d49f 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro @@ -2,3 +2,6 @@ TEMPLATE = subdirs contains(QT_CONFIG, egl_x11): SUBDIRS += eglfs_x11 contains(QT_CONFIG, kms): SUBDIRS += eglfs_kms +contains(QT_CONFIG, eglfs_brcm): SUBDIRS += eglfs_brcm +contains(QT_CONFIG, eglfs_mali): SUBDIRS += eglfs_mali +contains(QT_CONFIG, eglfs_viv): SUBDIRS += eglfs_viv diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.json new file mode 100644 index 0000000000..5f29d7dd0e --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "eglfs_brcm" ] +} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro new file mode 100644 index 0000000000..98797e2106 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/eglfs_brcm.pro @@ -0,0 +1,20 @@ +TARGET = qeglfs-brcm-integration + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSBrcmIntegrationPlugin +load(qt_plugin) + +QT += core-private gui-private platformsupport-private eglfs_device_lib-private + +INCLUDEPATH += $$PWD/../.. +CONFIG += egl + +LIBS += -lbcm_host +QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF + +SOURCES += $$PWD/qeglfsbrcmmain.cpp \ + $$PWD/qeglfsbrcmintegration.cpp + +HEADERS += $$PWD/qeglfsbrcmintegration.h + +OTHER_FILES += $$PWD/eglfs_brcm.json diff --git a/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp index 64a9617c48..4813d9be04 100644 --- a/mkspecs/devices/linux-rasp-pi-g++/qeglfshooks_pi.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.cpp @@ -3,7 +3,7 @@ ** 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. +** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage @@ -31,13 +31,7 @@ ** ****************************************************************************/ -#include "qeglfshooks.h" - -#include <QtDebug> - -#include <QtPlatformSupport/private/qeglconvenience_p.h> -#include <QtPlatformSupport/private/qeglplatformcontext_p.h> - +#include "qeglfsbrcmintegration.h" #include <bcm_host.h> QT_BEGIN_NAMESPACE @@ -88,54 +82,41 @@ static void destroyDispmanxLayer(EGLNativeWindowType window) delete eglWindow; } -class QEglFSPiHooks : public QEglFSHooks -{ -public: - virtual void platformInit(); - virtual void platformDestroy(); - virtual EGLNativeDisplayType platformDisplay() const; - virtual QSize screenSize() const; - virtual EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format); - virtual void destroyNativeWindow(EGLNativeWindowType window); - virtual bool hasCapability(QPlatformIntegration::Capability cap) const; - -}; - -void QEglFSPiHooks::platformInit() +void QEglFSBrcmIntegration::platformInit() { bcm_host_init(); } -EGLNativeDisplayType QEglFSPiHooks::platformDisplay() const +EGLNativeDisplayType QEglFSBrcmIntegration::platformDisplay() const { dispman_display = vc_dispmanx_display_open(0/* LCD */); return EGL_DEFAULT_DISPLAY; } -void QEglFSPiHooks::platformDestroy() +void QEglFSBrcmIntegration::platformDestroy() { vc_dispmanx_display_close(dispman_display); } -QSize QEglFSPiHooks::screenSize() const +QSize QEglFSBrcmIntegration::screenSize() const { uint32_t width, height; graphics_get_display_size(0 /* LCD */, &width, &height); return QSize(width, height); } -EGLNativeWindowType QEglFSPiHooks::createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) +EGLNativeWindowType QEglFSBrcmIntegration::createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) { Q_UNUSED(window) return createDispmanxLayer(QPoint(0, 0), size, 1, format.hasAlpha() ? DISPMANX_FLAGS_ALPHA_FROM_SOURCE : DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS); } -void QEglFSPiHooks::destroyNativeWindow(EGLNativeWindowType window) +void QEglFSBrcmIntegration::destroyNativeWindow(EGLNativeWindowType window) { destroyDispmanxLayer(window); } -bool QEglFSPiHooks::hasCapability(QPlatformIntegration::Capability cap) const +bool QEglFSBrcmIntegration::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { case QPlatformIntegration::ThreadedPixmaps: @@ -148,7 +129,4 @@ bool QEglFSPiHooks::hasCapability(QPlatformIntegration::Capability cap) const } } -QEglFSPiHooks eglFSPiHooks; -QEglFSHooks *platformHooks = &eglFSPiHooks; - QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.h new file mode 100644 index 0000000000..2a592b8445 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins 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 QEGLFSBRCMINTEGRATION_H +#define QEGLFSBRCMINTEGRATION_H + +#include "qeglfsdeviceintegration.h" + +QT_BEGIN_NAMESPACE + +class QEglFSBrcmIntegration : public QEGLDeviceIntegration +{ +public: + void platformInit() Q_DECL_OVERRIDE; + void platformDestroy() Q_DECL_OVERRIDE; + EGLNativeDisplayType platformDisplay() const Q_DECL_OVERRIDE; + QSize screenSize() const Q_DECL_OVERRIDE; + EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) Q_DECL_OVERRIDE; + void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE; + bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmmain.cpp new file mode 100644 index 0000000000..eb10f3a1e6 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmmain.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins 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 "qeglfsdeviceintegration.h" +#include "qeglfsbrcmintegration.h" + +QT_BEGIN_NAMESPACE + +class QEglFSBrcmIntegrationPlugin : public QEGLDeviceIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_brcm.json") + +public: + QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSBrcmIntegration; } +}; + +QT_END_NAMESPACE + +#include "qeglfsbrcmmain.moc" diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro index f79653127e..e53793ce54 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro @@ -1,8 +1,7 @@ TARGET = qeglfs-kms-integration -PLUGIN_CLASS_NAME=QEglFSKmsIntegrationPlugin -PLUGIN_TYPE=egldeviceintegrations - +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSKmsIntegrationPlugin load(qt_plugin) QT += core-private gui-private platformsupport-private eglfs_device_lib-private diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp index 45287ae36e..a36ce50b76 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.cpp @@ -37,10 +37,35 @@ #include <QtCore/QLoggingCategory> +#include <QtGui/private/qguiapplication_p.h> +#include <QtPlatformSupport/private/qeglplatformintegration_p.h> +#include <QtPlatformSupport/private/qfbvthandler_p.h> + QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug) +class QEglFSKmsInterruptHandler : public QObject +{ +public: + QEglFSKmsInterruptHandler(QEglFSKmsScreen *screen) : m_screen(screen) { + m_vtHandler = static_cast<QEGLPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration())->vtHandler(); + connect(m_vtHandler, &QFbVtHandler::interrupted, this, &QEglFSKmsInterruptHandler::restoreVideoMode); + connect(m_vtHandler, &QFbVtHandler::suspendRequested, this, &QEglFSKmsInterruptHandler::handleSuspendRequest); + } + +public slots: + void restoreVideoMode() { m_screen->restoreMode(); } + void handleSuspendRequest() { + m_screen->restoreMode(); + m_vtHandler->suspend(); + } + +private: + QFbVtHandler *m_vtHandler; + QEglFSKmsScreen *m_screen; +}; + void QEglFSKmsScreen::bufferDestroyedHandler(gbm_bo *bo, void *data) { FrameBuffer *fb = static_cast<FrameBuffer *>(data); @@ -93,12 +118,18 @@ QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration, , m_output(output) , m_pos(position) , m_cursor(Q_NULLPTR) + , m_interruptHandler(new QEglFSKmsInterruptHandler(this)) { } QEglFSKmsScreen::~QEglFSKmsScreen() { restoreMode(); + if (m_output.saved_crtc) { + drmModeFreeCrtc(m_output.saved_crtc); + m_output.saved_crtc = Q_NULLPTR; + } + delete m_interruptHandler; } QRect QEglFSKmsScreen::geometry() const @@ -268,9 +299,6 @@ void QEglFSKmsScreen::restoreMode() &m_output.connector_id, 1, &m_output.saved_crtc->mode); - drmModeFreeCrtc(m_output.saved_crtc); - m_output.saved_crtc = Q_NULLPTR; - m_output.mode_set = false; } } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h index cc2d6942d6..ed79d00896 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsscreen.h @@ -47,6 +47,7 @@ QT_BEGIN_NAMESPACE class QEglFSKmsDevice; class QEglFSKmsCursor; +class QEglFSKmsInterruptHandler; struct QEglFSKmsOutput { @@ -115,6 +116,8 @@ private: FrameBuffer *framebufferForBufferObject(gbm_bo *bo); static QMutex m_waitForFlipMutex; + + QEglFSKmsInterruptHandler *m_interruptHandler; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.json new file mode 100644 index 0000000000..8cabc1abbd --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "eglfs_mali" ] +} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro new file mode 100644 index 0000000000..dcfb4cd26d --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/eglfs_mali.pro @@ -0,0 +1,18 @@ +TARGET = qeglfs-mali-integration + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSMaliIntegrationPlugin +load(qt_plugin) + +QT += core-private gui-private platformsupport-private eglfs_device_lib-private + +INCLUDEPATH += $$PWD/../.. +CONFIG += egl +QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF + +SOURCES += $$PWD/qeglfsmalimain.cpp \ + $$PWD/qeglfsmaliintegration.cpp + +HEADERS += $$PWD/qeglfsmaliintegration.h + +OTHER_FILES += $$PWD/eglfs_mali.json diff --git a/mkspecs/devices/linux-arm-hisilicon-hix5hd2-g++/qeglfshooks_hix5hd2.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp index 9100a97646..6e5421d5b9 100644 --- a/mkspecs/devices/linux-arm-hisilicon-hix5hd2-g++/qeglfshooks_hix5hd2.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.cpp @@ -3,7 +3,7 @@ ** 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. +** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage @@ -31,7 +31,7 @@ ** ****************************************************************************/ -#include "qeglfshooks.h" +#include "qeglfsmaliintegration.h" #include <EGL/fbdev_window.h> #include <unistd.h> @@ -43,18 +43,11 @@ QT_BEGIN_NAMESPACE -class QEglFSHiX5Hd2Hooks : public QEglFSHooks +void QEglFSMaliIntegration::platformInit() { -private: - void fbInit(); -public: - void platformInit() Q_DECL_OVERRIDE; - EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) Q_DECL_OVERRIDE; - void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE; -}; + // Keep the non-overridden base class functions based on fb0 working. + QEGLDeviceIntegration::platformInit(); -void QEglFSHiX5Hd2Hooks::fbInit() -{ int fd = qt_safe_open("/dev/fb0", O_RDWR, 0); if (fd == -1) qWarning("Failed to open fb to detect screen resolution!"); @@ -79,17 +72,13 @@ void QEglFSHiX5Hd2Hooks::fbInit() qErrnoWarning(errno, "Unable to set double buffer mode!"); qt_safe_close(fd); - return; } -void QEglFSHiX5Hd2Hooks::platformInit() +EGLNativeWindowType QEglFSMaliIntegration::createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) { - QEglFSHooks::platformInit(); - fbInit(); -} + Q_UNUSED(window); + Q_UNUSED(format); -EGLNativeWindowType QEglFSHiX5Hd2Hooks::createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) -{ fbdev_window *fbwin = reinterpret_cast<fbdev_window *>(malloc(sizeof(fbdev_window))); if (NULL == fbwin) return 0; @@ -99,12 +88,9 @@ EGLNativeWindowType QEglFSHiX5Hd2Hooks::createNativeWindow(QPlatformWindow *wind return (EGLNativeWindowType)fbwin; } -void QEglFSHiX5Hd2Hooks::destroyNativeWindow(EGLNativeWindowType window) +void QEglFSMaliIntegration::destroyNativeWindow(EGLNativeWindowType window) { free(window); } -QEglFSHiX5Hd2Hooks eglFSHiX5Hd2Hooks; -QEglFSHooks *platformHooks = &eglFSHiX5Hd2Hooks; - QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.h new file mode 100644 index 0000000000..ebe468d70b --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.h @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins 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 QEGLFSMALIINTEGRATION_H +#define QEGLFSMALIINTEGRATION_H + +#include "qeglfsdeviceintegration.h" + +QT_BEGIN_NAMESPACE + +class QEglFSMaliIntegration : public QEGLDeviceIntegration +{ +public: + void platformInit() Q_DECL_OVERRIDE; + EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) Q_DECL_OVERRIDE; + void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmalimain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmalimain.cpp new file mode 100644 index 0000000000..0b90858efe --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmalimain.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins 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 "qeglfsdeviceintegration.h" +#include "qeglfsmaliintegration.h" + +QT_BEGIN_NAMESPACE + +class QEglFSMaliIntegrationPlugin : public QEGLDeviceIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_mali.json") + +public: + QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSMaliIntegration; } +}; + +QT_END_NAMESPACE + +#include "qeglfsmalimain.moc" diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.json new file mode 100644 index 0000000000..ae0cada044 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "eglfs_viv" ] +} diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro new file mode 100644 index 0000000000..fc0533127c --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/eglfs_viv.pro @@ -0,0 +1,20 @@ +TARGET = qeglfs-viv-integration + +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSVivIntegrationPlugin +load(qt_plugin) + +QT += core-private gui-private platformsupport-private eglfs_device_lib-private + +INCLUDEPATH += $$PWD/../.. +CONFIG += egl +DEFINES += LINUX=1 EGL_API_FB=1 +LIBS += -lGAL +QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF + +SOURCES += $$PWD/qeglfsvivmain.cpp \ + $$PWD/qeglfsvivintegration.cpp + +HEADERS += $$PWD/qeglfsvivintegration.h + +OTHER_FILES += $$PWD/eglfs_viv.json diff --git a/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp index b5ddafefdc..b7eb3fb2d3 100644 --- a/mkspecs/devices/linux-imx6-g++/qeglfshooks_imx6.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp @@ -3,7 +3,7 @@ ** 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. +** This file is part of the plugins of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage @@ -31,35 +31,22 @@ ** ****************************************************************************/ -#include "qeglfshooks.h" +#include "qeglfsvivintegration.h" #include <EGL/eglvivante.h> #include <QDebug> QT_BEGIN_NAMESPACE -class QEglFSImx6Hooks : public QEglFSHooks +void QEglFSVivIntegration::platformInit() { -public: - QEglFSImx6Hooks(); - virtual QSize screenSize() const; - virtual EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format); - virtual void destroyNativeWindow(EGLNativeWindowType window); - virtual EGLNativeDisplayType platformDisplay() const; + QEGLDeviceIntegration::platformInit(); -private: - QSize mScreenSize; - EGLNativeDisplayType mNativeDisplay; -}; - - -QEglFSImx6Hooks::QEglFSImx6Hooks() -{ int width, height; bool multiBufferNotEnabledYet = qEnvironmentVariableIsEmpty("FB_MULTI_BUFFER"); bool multiBuffer = qEnvironmentVariableIsEmpty("QT_EGLFS_IMX6_NO_FB_MULTI_BUFFER"); if (multiBufferNotEnabledYet && multiBuffer) { - qWarning() << "QEglFSImx6Hooks will set environment variable FB_MULTI_BUFFER=2 to enable double buffering and vsync.\n" + qWarning() << "QEglFSVivIntegration will set environment variable FB_MULTI_BUFFER=2 to enable double buffering and vsync.\n" << "If this is not desired, you can override this via: export QT_EGLFS_IMX6_NO_FB_MULTI_BUFFER=1"; qputenv("FB_MULTI_BUFFER", "2"); } @@ -70,17 +57,17 @@ QEglFSImx6Hooks::QEglFSImx6Hooks() mScreenSize.setWidth(width); } -QSize QEglFSImx6Hooks::screenSize() const +QSize QEglFSVivIntegration::screenSize() const { return mScreenSize; } -EGLNativeDisplayType QEglFSImx6Hooks::platformDisplay() const +EGLNativeDisplayType QEglFSVivIntegration::platformDisplay() const { return mNativeDisplay; } -EGLNativeWindowType QEglFSImx6Hooks::createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) +EGLNativeWindowType QEglFSVivIntegration::createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) { Q_UNUSED(window) Q_UNUSED(format) @@ -89,13 +76,9 @@ EGLNativeWindowType QEglFSImx6Hooks::createNativeWindow(QPlatformWindow *window, return eglWindow; } - -void QEglFSImx6Hooks::destroyNativeWindow(EGLNativeWindowType window) +void QEglFSVivIntegration::destroyNativeWindow(EGLNativeWindowType window) { fbDestroyWindow(window); } -QEglFSImx6Hooks eglFSImx6Hooks; -QEglFSHooks *platformHooks = &eglFSImx6Hooks; - QT_END_NAMESPACE diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h new file mode 100644 index 0000000000..181cd3ab94 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins 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 QEGLFSVIVINTEGRATION_H +#define QEGLFSVIVINTEGRATION_H + +#include "qeglfsdeviceintegration.h" + +QT_BEGIN_NAMESPACE + +class QEglFSVivIntegration : public QEGLDeviceIntegration +{ +public: + void platformInit() Q_DECL_OVERRIDE; + QSize screenSize() const Q_DECL_OVERRIDE; + EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) Q_DECL_OVERRIDE; + void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE; + EGLNativeDisplayType platformDisplay() const Q_DECL_OVERRIDE; + +private: + QSize mScreenSize; + EGLNativeDisplayType mNativeDisplay; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivmain.cpp new file mode 100644 index 0000000000..11727f63f9 --- /dev/null +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivmain.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins 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 "qeglfsdeviceintegration.h" +#include "qeglfsvivintegration.h" + +QT_BEGIN_NAMESPACE + +class QEglFSVivIntegrationPlugin : public QEGLDeviceIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QEGLDeviceIntegrationFactoryInterface_iid FILE "eglfs_viv.json") + +public: + QEGLDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSVivIntegration; } +}; + +QT_END_NAMESPACE + +#include "qeglfsvivmain.moc" diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro index a1d08248ff..86fefac8aa 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/eglfs_x11.pro @@ -1,8 +1,7 @@ TARGET = qeglfs-x11-integration -PLUGIN_CLASS_NAME=QEglFSX11IntegrationPlugin -PLUGIN_TYPE=egldeviceintegrations - +PLUGIN_TYPE = egldeviceintegrations +PLUGIN_CLASS_NAME = QEglFSX11IntegrationPlugin load(qt_plugin) QT += core-private gui-private platformsupport-private eglfs_device_lib-private diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 33328e0490..9d29b4edf7 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -69,12 +69,10 @@ QIOSIntegration::QIOSIntegration() , m_accessibility(0) { if (![UIApplication sharedApplication]) { - qWarning() - << "Error: You are creating QApplication before calling UIApplicationMain.\n" - << "If you are writing a native iOS application, and only want to use Qt for\n" - << "parts of the application, a good place to create QApplication is from within\n" - << "'applicationDidFinishLaunching' inside your UIApplication delegate.\n"; - exit(-1); + qFatal("Error: You are creating QApplication before calling UIApplicationMain.\n" \ + "If you are writing a native iOS application, and only want to use Qt for\n" \ + "parts of the application, a good place to create QApplication is from within\n" \ + "'applicationDidFinishLaunching' inside your UIApplication delegate.\n"); } // Set current directory to app bundle folder diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 287ee4c46e..9e037723fe 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1104,11 +1104,18 @@ QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal GUID guid; CoCreateGuid(&guid); +#ifdef Q_CC_GNU +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif QString uniqueFamilyName = QLatin1Char('f') + QString::number(guid.Data1, 36) + QLatin1Char('-') + QString::number(guid.Data2, 36) + QLatin1Char('-') + QString::number(guid.Data3, 36) + QLatin1Char('-') + QString::number(*reinterpret_cast<quint64 *>(guid.Data4), 36); +#ifdef Q_CC_GNU +# pragma GCC diagnostic pop +#endif QString actualFontName = font.changeFamilyName(uniqueFamilyName); if (actualFontName.isEmpty()) { diff --git a/src/plugins/platforms/windows/qwindowsguieventdispatcher.h b/src/plugins/platforms/windows/qwindowsguieventdispatcher.h index 3db6eac662..3389139461 100644 --- a/src/plugins/platforms/windows/qwindowsguieventdispatcher.h +++ b/src/plugins/platforms/windows/qwindowsguieventdispatcher.h @@ -34,11 +34,8 @@ #ifndef QWINDOWSGUIEVENTDISPATCHER_H #define QWINDOWSGUIEVENTDISPATCHER_H -#include "qtwindowsglobal.h" #include "qtwindows_additional.h" -#include <QtCore/QPair> -#include <QtCore/QEventLoop> #include <QtCore/private/qeventdispatcher_win_p.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index af7ecd5834..9fd18a1ef4 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -316,9 +316,9 @@ QWindowsWindowData QWindowsIntegration::createWindowData(QWindow *window) const << __FUNCTION__ << '<' << window << "\n Requested: " << requested.geometry << "frame incl.: " << QWindowsGeometryHint::positionIncludesFrame(window) - << " Flags=" << QWindowsWindow::debugWindowFlags(requested.flags) + << " Flags=" << requested.flags << "\n Obtained : " << obtained.geometry << " Margins "<< obtained.frame - << " Flags=" << QWindowsWindow::debugWindowFlags(obtained.flags) + << " Flags=" << obtained.flags << " Handle=" << obtained.hwnd << '\n'; if (obtained.hwnd) { @@ -420,7 +420,10 @@ QOpenGLContext::OpenGLModuleType QWindowsIntegration::openGLModuleType() QWindowsStaticOpenGLContext *QWindowsIntegration::staticOpenGLContext() { - QWindowsIntegrationPrivate *d = QWindowsIntegration::instance()->d.data(); + QWindowsIntegration *integration = QWindowsIntegration::instance(); + if (!integration) + return 0; + QWindowsIntegrationPrivate *d = integration->d.data(); if (d->m_staticOpenGLContext.isNull()) d->m_staticOpenGLContext = QSharedPointer<QWindowsStaticOpenGLContext>(QWindowsStaticOpenGLContext::create()); return d->m_staticOpenGLContext.data(); diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h index 8a2d14f172..fa5192ba03 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.h +++ b/src/plugins/platforms/windows/qwindowsintegration.h @@ -35,7 +35,6 @@ #ifndef QWINDOWSINTEGRATION_H #define QWINDOWSINTEGRATION_H -#include <QtCore/qconfig.h> #include <qpa/qplatformintegration.h> #include <QtCore/QScopedPointer> diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h index e7a01ae79a..952410e14b 100644 --- a/src/plugins/platforms/windows/qwindowsmime.h +++ b/src/plugins/platforms/windows/qwindowsmime.h @@ -39,7 +39,6 @@ #include <QtCore/QVector> #include <QtCore/QList> #include <QtCore/QVariant> -#include <QtCore/QSharedPointer> QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsnativeimage.h b/src/plugins/platforms/windows/qwindowsnativeimage.h index cbf93b9602..6f9ce93ef0 100644 --- a/src/plugins/platforms/windows/qwindowsnativeimage.h +++ b/src/plugins/platforms/windows/qwindowsnativeimage.h @@ -38,8 +38,6 @@ #include <QtGui/QImage> -#include <QtCore/QtGlobal> - QT_BEGIN_NAMESPACE class QWindowsNativeImage diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index 84608edddc..9691156403 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -192,6 +192,11 @@ QString QWindowsNativeInterface::registerWindowClass(const QString &classNameIn, return QWindowsContext::instance()->registerWindowClass(classNameIn, (WNDPROC)eventProc); } +void QWindowsNativeInterface::beep() +{ + MessageBeep(MB_OK); // For QApplication +} + bool QWindowsNativeInterface::asyncExpose() const { return QWindowsContext::instance()->asyncExpose(); diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h index 4069d60f3b..be8418b769 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.h +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h @@ -34,7 +34,6 @@ #ifndef QWINDOWSNATIVEINTERFACE_H #define QWINDOWSNATIVEINTERFACE_H -#include "qtwindows_additional.h" #include <QtGui/qpa/qplatformnativeinterface.h> QT_BEGIN_NAMESPACE @@ -73,7 +72,7 @@ public: Q_INVOKABLE QString registerWindowClass(const QString &classNameIn, void *eventProc) const; - Q_INVOKABLE void beep() { MessageBeep(MB_OK); } // For QApplication + Q_INVOKABLE void beep(); Q_INVOKABLE void registerWindowsMime(void *mimeIn); Q_INVOKABLE void unregisterWindowsMime(void *mime); diff --git a/src/plugins/platforms/windows/qwindowsole.h b/src/plugins/platforms/windows/qwindowsole.h index b63d7611da..09f6114e2d 100644 --- a/src/plugins/platforms/windows/qwindowsole.h +++ b/src/plugins/platforms/windows/qwindowsole.h @@ -36,12 +36,9 @@ #include "qtwindows_additional.h" -#include <QtCore/QObject> #include <QtCore/QMap> -#include <QtCore/QPoint> #include <QtCore/QPointer> #include <QtCore/QVector> -#include <QtCore/QRect> #include <objidl.h> diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h index f58bf305fc..7b6164946e 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.h +++ b/src/plugins/platforms/windows/qwindowsopengltester.h @@ -34,8 +34,6 @@ #ifndef QWINDOWSOPENGLTESTER_H #define QWINDOWSOPENGLTESTER_H -#include <qtwindowsglobal.h> - #include <QtCore/QByteArray> #include <QtCore/QFlags> #include <private/qversionnumber_p.h> diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp index 4ab4ac352e..28e2aadf14 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.cpp +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp @@ -191,13 +191,13 @@ static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d) } // Return the cursor to be shared by all screens (virtual desktop). -static inline QSharedPointer<QWindowsCursor> sharedCursor() +static inline QSharedPointer<QPlatformCursor> sharedCursor() { #ifndef QT_NO_CURSOR if (const QScreen *primaryScreen = QGuiApplication::primaryScreen()) - return static_cast<const QWindowsScreen *>(primaryScreen->handle())->windowsCursor(); + return static_cast<const QWindowsScreen *>(primaryScreen->handle())->cursorPtr(); #endif - return QSharedPointer<QWindowsCursor>(new QWindowsCursor); + return QSharedPointer<QPlatformCursor>(new QWindowsCursor); } /*! diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h index b561f73804..7352c45777 100644 --- a/src/plugins/platforms/windows/qwindowsscreen.h +++ b/src/plugins/platforms/windows/qwindowsscreen.h @@ -34,8 +34,8 @@ #ifndef QWINDOWSSCREEN_H #define QWINDOWSSCREEN_H -#include "qwindowscursor.h" #include "qwindowsscaling.h" +#include "qtwindowsglobal.h" #ifdef Q_OS_WINCE # include "qplatformfunctions_wince.h" #endif @@ -75,7 +75,7 @@ class QWindowsScreen : public QPlatformScreen { public: #ifndef QT_NO_CURSOR - typedef QSharedPointer<QWindowsCursor> WindowsCursorPtr; + typedef QSharedPointer<QPlatformCursor> CursorPtr; #endif explicit QWindowsScreen(const QWindowsScreenData &data); @@ -105,8 +105,8 @@ public: inline void handleChanges(const QWindowsScreenData &newData); #ifndef QT_NO_CURSOR - QPlatformCursor *cursor() const { return m_cursor.data(); } - const WindowsCursorPtr &windowsCursor() const { return m_cursor; } + QPlatformCursor *cursor() const Q_DECL_OVERRIDE { return m_cursor.data(); } + const CursorPtr &cursorPtr() const { return m_cursor; } #else QPlatformCursor *cursor() const { return 0; } #endif // !QT_NO_CURSOR @@ -117,7 +117,7 @@ public: private: QWindowsScreenData m_data; #ifndef QT_NO_CURSOR - const WindowsCursorPtr m_cursor; + const CursorPtr m_cursor; #endif }; diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 9b6ae7c445..d3f67e9eaa 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -62,6 +62,7 @@ #include <QtCore/QTextStream> #include <QtCore/QSysInfo> #include <QtCore/QCache> +#include <QtGui/QColor> #include <QtGui/QPalette> #include <QtGui/QGuiApplication> #include <QtGui/QPainter> @@ -77,6 +78,16 @@ QT_BEGIN_NAMESPACE +static inline COLORREF qColorToCOLORREF(const QColor &color) +{ + return RGB(color.red(), color.green(), color.blue()); +} + +static inline QColor COLORREFToQColor(COLORREF cr) +{ + return QColor(GetRValue(cr), GetGValue(cr), GetBValue(cr)); +} + static inline QTextStream& operator<<(QTextStream &str, const QColor &c) { str.setIntegerBase(16); diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h index 3840e978cd..b2f8e13b64 100644 --- a/src/plugins/platforms/windows/qwindowstheme.h +++ b/src/plugins/platforms/windows/qwindowstheme.h @@ -35,9 +35,6 @@ #define QWINDOWSTHEME_H #include <qpa/qplatformtheme.h> -#include <QtGui/QColor> - -#include "qtwindows_additional.h" QT_BEGIN_NAMESPACE @@ -79,12 +76,6 @@ private: QFont *m_fonts[NFonts]; }; -static inline COLORREF qColorToCOLORREF(const QColor &color) -{ return RGB(color.red(), color.green(), color.blue()); } - -static inline QColor COLORREFToQColor(COLORREF cr) -{ return QColor(GetRValue(cr), GetGValue(cr), GetBValue(cr)); } - QT_END_NAMESPACE #endif // QWINDOWSTHEME_H diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index b229ec4080..4cf8fcf4da 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -38,6 +38,7 @@ #include "qwindowsscreen.h" #include "qwindowsscaling.h" #include "qwindowsintegration.h" +#include "qwindowsopenglcontext.h" #ifdef QT_NO_CURSOR # include "qwindowscursor.h" #endif @@ -416,7 +417,7 @@ struct WindowCreationData QDebug operator<<(QDebug debug, const WindowCreationData &d) { - debug.nospace() << QWindowsWindow::debugWindowFlags(d.flags) + debug.nospace() << d.flags << " topLevel=" << d.topLevel << " popup=" << d.popup << " dialog=" << d.dialog << " desktop=" << d.desktop << " embedded=" << d.embedded @@ -1529,8 +1530,7 @@ void QWindowsWindow::setWindowTitle(const QString &title) void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags) { qCDebug(lcQpaWindows) << '>' << __FUNCTION__ << this << window() << "\n from: " - << QWindowsWindow::debugWindowFlags(m_data.flags) - << "\n to: " << QWindowsWindow::debugWindowFlags(flags); + << m_data.flags << "\n to: " << flags; const QRect oldGeometry = geometryDp(); if (m_data.flags != flags) { m_data.flags = flags; @@ -1548,8 +1548,7 @@ void QWindowsWindow::setWindowFlags(Qt::WindowFlags flags) handleGeometryChange(); qCDebug(lcQpaWindows) << '<' << __FUNCTION__ << "\n returns: " - << QWindowsWindow::debugWindowFlags(m_data.flags) - << " geometry " << oldGeometry << "->" << newGeometry; + << m_data.flags << " geometry " << oldGeometry << "->" << newGeometry; } QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt, @@ -2201,62 +2200,6 @@ void QWindowsWindow::setEnabled(bool enabled) setStyle(newStyle); } -QByteArray QWindowsWindow::debugWindowFlags(Qt::WindowFlags wf) -{ - const int iwf = int(wf); - QByteArray rc = "0x"; - rc += QByteArray::number(iwf, 16); - rc += " ["; - - switch ((iwf & Qt::WindowType_Mask)) { - case Qt::Widget: - rc += " Widget"; - break; - case Qt::Window: - rc += " Window"; - break; - case Qt::Dialog: - rc += " Dialog"; - break; - case Qt::Sheet: - rc += " Sheet"; - break; - case Qt::Popup: - rc += " Popup"; - break; - case Qt::Tool: - rc += " Tool"; - break; - case Qt::ToolTip: - rc += " ToolTip"; - break; - case Qt::SplashScreen: - rc += " SplashScreen"; - break; - case Qt::Desktop: - rc += " Desktop"; - break; - case Qt::SubWindow: - rc += " SubWindow"; - break; - } - if (iwf & Qt::MSWindowsFixedSizeDialogHint) rc += " MSWindowsFixedSizeDialogHint"; - if (iwf & Qt::MSWindowsOwnDC) rc += " MSWindowsOwnDC"; - if (iwf & Qt::FramelessWindowHint) rc += " FramelessWindowHint"; - if (iwf & Qt::WindowTitleHint) rc += " WindowTitleHint"; - if (iwf & Qt::WindowSystemMenuHint) rc += " WindowSystemMenuHint"; - if (iwf & Qt::WindowMinimizeButtonHint) rc += " WindowMinimizeButtonHint"; - if (iwf & Qt::WindowMaximizeButtonHint) rc += " WindowMaximizeButtonHint"; - if (iwf & Qt::WindowContextHelpButtonHint) rc += " WindowContextHelpButtonHint"; - if (iwf & Qt::WindowShadeButtonHint) rc += " WindowShadeButtonHint"; - if (iwf & Qt::WindowStaysOnTopHint) rc += " WindowStaysOnTopHint"; - if (iwf & Qt::CustomizeWindowHint) rc += " CustomizeWindowHint"; - if (iwf & Qt::WindowStaysOnBottomHint) rc += " WindowStaysOnBottomHint"; - if (iwf & Qt::WindowCloseButtonHint) rc += " WindowCloseButtonHint"; - rc += ']'; - return rc; -} - static HICON createHIcon(const QIcon &icon, int xSize, int ySize) { if (!icon.isNull()) { diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h index ec419d8272..f0b04fbc47 100644 --- a/src/plugins/platforms/windows/qwindowswindow.h +++ b/src/plugins/platforms/windows/qwindowswindow.h @@ -40,7 +40,6 @@ #endif #include "qwindowsscaling.h" #include "qwindowscursor.h" -#include "qwindowsopenglcontext.h" #include <qpa/qplatformwindow.h> #include <QtPlatformHeaders/qwindowswindowfunctions.h> @@ -241,8 +240,6 @@ public: void setCursor(const QWindowsWindowCursor &c); void applyCursor(); - static QByteArray debugWindowFlags(Qt::WindowFlags wf); - inline bool testFlag(unsigned f) const { return (m_flags & f) != 0; } inline void setFlag(unsigned f) const { m_flags |= f; } inline void clearFlag(unsigned f) const { m_flags &= ~f; } diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 57dcdc8f9c..7ec5851737 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -215,16 +215,6 @@ void QXcbConnection::updateScreens() } free(primary); } - // If there's no randr extension, or there was some error above, or the screen - // doesn't have outputs for some other reason (e.g. on VNC or ssh -X), just assume there is one screen. - if (connectedOutputCount == 0) { - qCDebug(lcQpaScreen, "found a screen with zero outputs"); - QXcbScreen *screen = findOrCreateScreen(newScreens, xcbScreenNumber, xcbScreen); - siblings << screen; - activeScreens << screen; - if (!primaryScreen) - primaryScreen = screen; - } foreach (QPlatformScreen* s, siblings) ((QXcbScreen*)s)->setVirtualSiblings(siblings); xcb_screen_next(&it); @@ -282,6 +272,11 @@ void QXcbConnection::updateScreens() if (!m_screens.isEmpty()) qCDebug(lcQpaScreen) << "primary output is" << m_screens.first()->name(); + else + // QTBUG-40174, QTBUG-42985: If there are no outputs, then there must be + // no QScreen instances; a Qt application can survive this situation, and + // start rendering again later when there is a screen again. + qCDebug(lcQpaScreen) << "xcb connection has no outputs"; } QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, const char *displayName) diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index 58a364848a..78ced43af8 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -399,7 +399,8 @@ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *chan // They need to be told the screen is back, it's OK to render. foreach (QWindow *window, QGuiApplication::topLevelWindows()) { QXcbWindow *xcbWin = static_cast<QXcbWindow*>(window->handle()); - xcbWin->maybeSetScreen(this); + if (xcbWin) + xcbWin->maybeSetScreen(this); } } diff --git a/src/tools/qdoc/codemarker.cpp b/src/tools/qdoc/codemarker.cpp index 6a1675aeb5..2253aca183 100644 --- a/src/tools/qdoc/codemarker.cpp +++ b/src/tools/qdoc/codemarker.cpp @@ -391,12 +391,11 @@ void CodeMarker::insert(FastSection &fastSection, bool inheritedMember = false; if (!node->relates()) { InnerNode* p = node->parent(); - if (p->type() == Node::QmlPropertyGroup) + if (p->isQmlPropertyGroup()) p = p->parent(); if (p != fastSection.parent_) { - if ((!p->isQmlType() && !p->isJsType()) || !p->isAbstract()) { + if ((!p->isQmlType() && !p->isJsType()) || !p->isAbstract()) inheritedMember = true; - } } } @@ -438,7 +437,7 @@ void CodeMarker::insert(FastSection &fastSection, fastSection.memberMap.insertMulti(key, node); } else { - if (node->parent()->type() == Node::Class) { + if (node->parent()->isClass() || node->parent()->isNamespace()) { if (fastSection.inherited.isEmpty() || fastSection.inherited.last().first != node->parent()) { QPair<InnerNode *, int> p(node->parent(), 0); diff --git a/src/tools/qdoc/cppcodemarker.cpp b/src/tools/qdoc/cppcodemarker.cpp index 400c4808ed..1546b5226e 100644 --- a/src/tools/qdoc/cppcodemarker.cpp +++ b/src/tools/qdoc/cppcodemarker.cpp @@ -442,75 +442,73 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner, { QList<Section> sections; - if (inner->type() == Node::Class) { - const ClassNode *classNode = static_cast<const ClassNode *>(inner); - + if (inner->isClass()) { if (style == Summary) { - FastSection privateFunctions(classNode, + FastSection privateFunctions(inner, "Private Functions", QString(), "private function", "private functions"); - FastSection privateSlots(classNode, "Private Slots", QString(), "private slot", "private slots"); - FastSection privateTypes(classNode, "Private Types", QString(), "private type", "private types"); - FastSection protectedFunctions(classNode, + FastSection privateSlots(inner, "Private Slots", QString(), "private slot", "private slots"); + FastSection privateTypes(inner, "Private Types", QString(), "private type", "private types"); + FastSection protectedFunctions(inner, "Protected Functions", QString(), "protected function", "protected functions"); - FastSection protectedSlots(classNode, + FastSection protectedSlots(inner, "Protected Slots", QString(), "protected slot", "protected slots"); - FastSection protectedTypes(classNode, + FastSection protectedTypes(inner, "Protected Types", QString(), "protected type", "protected types"); - FastSection protectedVariables(classNode, + FastSection protectedVariables(inner, "Protected Variables", QString(), "protected type", "protected variables"); - FastSection publicFunctions(classNode, + FastSection publicFunctions(inner, "Public Functions", QString(), "public function", "public functions"); - FastSection publicSignals(classNode, "Signals", QString(), "signal", "signals"); - FastSection publicSlots(classNode, "Public Slots", QString(), "public slot", "public slots"); - FastSection publicTypes(classNode, "Public Types", QString(), "public type", "public types"); - FastSection publicVariables(classNode, + FastSection publicSignals(inner, "Signals", QString(), "signal", "signals"); + FastSection publicSlots(inner, "Public Slots", QString(), "public slot", "public slots"); + FastSection publicTypes(inner, "Public Types", QString(), "public type", "public types"); + FastSection publicVariables(inner, "Public Variables", QString(), "public variable", "public variables"); - FastSection properties(classNode, "Properties", QString(), "property", "properties"); - FastSection relatedNonMembers(classNode, + FastSection properties(inner, "Properties", QString(), "property", "properties"); + FastSection relatedNonMembers(inner, "Related Non-Members", QString(), "related non-member", "related non-members"); - FastSection staticPrivateMembers(classNode, + FastSection staticPrivateMembers(inner, "Static Private Members", QString(), "static private member", "static private members"); - FastSection staticProtectedMembers(classNode, + FastSection staticProtectedMembers(inner, "Static Protected Members", QString(), "static protected member", "static protected members"); - FastSection staticPublicMembers(classNode, + FastSection staticPublicMembers(inner, "Static Public Members", QString(), "static public member", "static public members"); FastSection macros(inner, "Macros", QString(), "macro", "macros"); - NodeList::ConstIterator r = classNode->relatedNodes().constBegin(); - while (r != classNode->relatedNodes().constEnd()) { + NodeList::ConstIterator r = inner->relatedNodes().constBegin(); + while (r != inner->relatedNodes().constEnd()) { if ((*r)->type() == Node::Function) { FunctionNode *func = static_cast<FunctionNode *>(*r); if (func->isMacro()) @@ -524,13 +522,13 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner, ++r; } - QStack<const ClassNode *> stack; - stack.push(classNode); + QStack<const InnerNode *> stack; + stack.push(inner); while (!stack.isEmpty()) { - const ClassNode *ancestorClass = stack.pop(); + const InnerNode* ancestor = stack.pop(); - NodeList::ConstIterator c = ancestorClass->childNodes().constBegin(); - while (c != ancestorClass->childNodes().constEnd()) { + NodeList::ConstIterator c = ancestor->childNodes().constBegin(); + while (c != ancestor->childNodes().constEnd()) { bool isSlot = false; bool isSignal = false; bool isStatic = false; @@ -620,15 +618,16 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner, ++c; } - QList<RelatedClass>::ConstIterator r = - ancestorClass->baseClasses().constBegin(); - while (r != ancestorClass->baseClasses().constEnd()) { - if ((*r).node_) - stack.prepend((*r).node_); - ++r; + if (ancestor->isClass()) { + const ClassNode* cn = static_cast<const ClassNode*>(ancestor); + QList<RelatedClass>::ConstIterator r = cn->baseClasses().constBegin(); + while (r != cn->baseClasses().constEnd()) { + if ((*r).node_) + stack.prepend((*r).node_); + ++r; + } } } - append(sections, publicTypes); append(sections, properties); append(sections, publicFunctions); @@ -649,15 +648,15 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner, append(sections, macros); } else if (style == Detailed) { - FastSection memberFunctions(classNode,"Member Function Documentation","func","member","members"); - FastSection memberTypes(classNode,"Member Type Documentation","types","member","members"); - FastSection memberVariables(classNode,"Member Variable Documentation","vars","member","members"); - FastSection properties(classNode,"Property Documentation","prop","member","members"); - FastSection relatedNonMembers(classNode,"Related Non-Members","relnonmem","member","members"); - FastSection macros(classNode,"Macro Documentation","macros","member","members"); - - NodeList::ConstIterator r = classNode->relatedNodes().constBegin(); - while (r != classNode->relatedNodes().constEnd()) { + FastSection memberFunctions(inner,"Member Function Documentation","func","member","members"); + FastSection memberTypes(inner,"Member Type Documentation","types","member","members"); + FastSection memberVariables(inner,"Member Variable Documentation","vars","member","members"); + FastSection properties(inner,"Property Documentation","prop","member","members"); + FastSection relatedNonMembers(inner,"Related Non-Members","relnonmem","member","members"); + FastSection macros(inner,"Macro Documentation","macros","member","members"); + + NodeList::ConstIterator r = inner->relatedNodes().constBegin(); + while (r != inner->relatedNodes().constEnd()) { if ((*r)->type() == Node::Function) { FunctionNode *func = static_cast<FunctionNode *>(*r); if (func->isMacro()) @@ -671,8 +670,8 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner, ++r; } - NodeList::ConstIterator c = classNode->childNodes().constBegin(); - while (c != classNode->childNodes().constEnd()) { + NodeList::ConstIterator c = inner->childNodes().constBegin(); + while (c != inner->childNodes().constEnd()) { if ((*c)->type() == Node::Enum || (*c)->type() == Node::Typedef) { insert(memberTypes, *c, style, status); @@ -700,28 +699,28 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner, append(sections, macros); } else { - FastSection all(classNode,QString(),QString(),"member","members"); + FastSection all(inner,QString(),QString(),"member","members"); - QStack<const ClassNode *> stack; - stack.push(classNode); + QStack<const InnerNode*> stack; + stack.push(inner); while (!stack.isEmpty()) { - const ClassNode *ancestorClass = stack.pop(); - - NodeList::ConstIterator c = ancestorClass->childNodes().constBegin(); - while (c != ancestorClass->childNodes().constEnd()) { - if ((*c)->access() != Node::Private && - (*c)->type() != Node::Property) + const InnerNode* ancestor = stack.pop(); + NodeList::ConstIterator c = ancestor->childNodes().constBegin(); + while (c != ancestor->childNodes().constEnd()) { + if ((*c)->access() != Node::Private && (*c)->type() != Node::Property) insert(all, *c, style, status); ++c; } - QList<RelatedClass>::ConstIterator r = - ancestorClass->baseClasses().constBegin(); - while (r != ancestorClass->baseClasses().constEnd()) { - if ((*r).node_) - stack.prepend((*r).node_); - ++r; + if (ancestor->isClass()) { + const ClassNode* cn = static_cast<const ClassNode*>(ancestor); + QList<RelatedClass>::ConstIterator r = cn->baseClasses().constBegin(); + while (r != cn->baseClasses().constEnd()) { + if ((*r).node_) + stack.prepend((*r).node_); + ++r; + } } } append(sections, all); diff --git a/src/tools/qdoc/cppcodeparser.cpp b/src/tools/qdoc/cppcodeparser.cpp index 6cb86a7515..bc24ff5daa 100644 --- a/src/tools/qdoc/cppcodeparser.cpp +++ b/src/tools/qdoc/cppcodeparser.cpp @@ -423,6 +423,10 @@ Node* CppCodeParser::processTopicCommand(const Doc& doc, } else if (node->isInnerNode()) { + if (type == Node::Namespace) { + NamespaceNode* ns = static_cast<NamespaceNode*>(node); + ns->markSeen(); + } /* This treats a class as a namespace. */ diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index 8eb96bff17..7518b20fa3 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -291,7 +291,12 @@ void HtmlGenerator::generateKeywordAnchors(const Node* node) } /*! - Traverses the current tree generating all the HTML documentation. + If qdoc is in the \c {-prepare} phase, traverse the primary + tree to generate the index file for the current module. + + If qdoc is in the \c {-generate} phase, traverse the primary + tree to generate all the HTML documentation for the current + module. Then generate the help file and the tag file. */ void HtmlGenerator::generateDocs() { diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp index e14ca4af3e..25792a7c35 100644 --- a/src/tools/qdoc/node.cpp +++ b/src/tools/qdoc/node.cpp @@ -1112,7 +1112,9 @@ bool InnerNode::isSameSignature(const FunctionNode *f1, const FunctionNode *f2) } /*! - Adds the \a child to this node's child list. + Adds the \a child to this node's child list. It might also + be necessary to update this node's internal collections and + the child's parent pointer and output subdirectory. */ void InnerNode::addChild(Node *child) { @@ -1132,6 +1134,10 @@ void InnerNode::addChild(Node *child) enumChildren_.append(child); childMap.insertMulti(child->name(), child); } + if (child->parent() == 0) { + child->setParent(this); + child->setOutputSubdirectory(this->outputSubdirectory()); + } } /*! @@ -1146,6 +1152,10 @@ void InnerNode::addChild(Node* child, const QString& title) } /*! + The \a child is removed from this node's child list and + from this node's internal collections. The child's parent + pointer is set to 0, but its output subdirectory is not + changed. */ void InnerNode::removeChild(Node *child) { @@ -1185,6 +1195,7 @@ void InnerNode::removeChild(Node *child) } ++ent; } + child->setParent(0); } /*! @@ -1357,7 +1368,7 @@ LeafNode::LeafNode(InnerNode* parent, Type type, const QString& name) Constructs a namespace node. */ NamespaceNode::NamespaceNode(InnerNode *parent, const QString& name) - : InnerNode(Namespace, parent, name), tree_(0) + : InnerNode(Namespace, parent, name), seen_(false), tree_(0) { setGenus(Node::CPP); setPageType(ApiPage); diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h index b6717b3b1b..73b705dd0f 100644 --- a/src/tools/qdoc/node.h +++ b/src/tools/qdoc/node.h @@ -373,9 +373,7 @@ public: virtual ~InnerNode(); Node* findChildNode(const QString& name, Node::Genus genus) const; - //Node* findChildNode(const QString& name, bool qml) const; Node* findChildNode(const QString& name, Type type); - //void findNodes(const QString& name, NodeList& n); virtual void findChildren(const QString& name, NodeList& nodes) const Q_DECL_OVERRIDE; FunctionNode* findFunctionNode(const QString& name) const; FunctionNode* findFunctionNode(const FunctionNode* clone); @@ -410,6 +408,8 @@ public: const QStringList& groupNames() const { return groupNames_; } virtual void appendGroupName(const QString& t) Q_DECL_OVERRIDE { groupNames_.append(t); } void printChildren(const QString& title); + void addChild(Node* child); + void removeChild(Node* child); protected: InnerNode(Type type, InnerNode* parent, const QString& name); @@ -418,9 +418,7 @@ private: friend class Node; static bool isSameSignature(const FunctionNode* f1, const FunctionNode* f2); - void addChild(Node* child); void removeRelated(Node* pseudoChild); - void removeChild(Node* child); QString outputFileName_; QStringList pageKeywds; @@ -455,9 +453,14 @@ public: virtual ~NamespaceNode() { } virtual bool isNamespace() const Q_DECL_OVERRIDE { return true; } virtual Tree* tree() const Q_DECL_OVERRIDE { return (parent() ? parent()->tree() : tree_); } + virtual bool wasSeen() const Q_DECL_OVERRIDE { return seen_; } + + void markSeen() { seen_ = true; } + void markNotSeen() { seen_ = false; } void setTree(Tree* t) { tree_ = t; } private: + bool seen_; Tree* tree_; }; @@ -881,12 +884,24 @@ public: bool isOverload() const { return ove; } bool isReimp() const Q_DECL_OVERRIDE { return reimp; } bool isFunction() const Q_DECL_OVERRIDE { return true; } - virtual bool isQmlSignal() const Q_DECL_OVERRIDE { return genus() == Node::QML; } - virtual bool isJsSignal() const Q_DECL_OVERRIDE { return genus() == Node::JS; } - virtual bool isQmlSignalHandler() const Q_DECL_OVERRIDE { return genus() == Node::QML; } - virtual bool isJsSignalHandler() const Q_DECL_OVERRIDE { return genus() == Node::JS; } - virtual bool isQmlMethod() const Q_DECL_OVERRIDE { return genus() == Node::QML; } - virtual bool isJsMethod() const Q_DECL_OVERRIDE { return genus() == Node::JS; } + virtual bool isQmlSignal() const Q_DECL_OVERRIDE { + return (type() == Node::QmlSignal) && (genus() == Node::QML); + } + virtual bool isJsSignal() const Q_DECL_OVERRIDE { + return (type() == Node::QmlSignal) && (genus() == Node::JS); + } + virtual bool isQmlSignalHandler() const Q_DECL_OVERRIDE { + return (type() == Node::QmlSignalHandler) && (genus() == Node::QML); + } + virtual bool isJsSignalHandler() const Q_DECL_OVERRIDE { + return (type() == Node::QmlSignalHandler) && (genus() == Node::JS); + } + virtual bool isQmlMethod() const Q_DECL_OVERRIDE { + return (type() == Node::QmlMethod) && (genus() == Node::QML); + } + virtual bool isJsMethod() const Q_DECL_OVERRIDE { + return (type() == Node::QmlMethod) && (genus() == Node::JS); + } int overloadNumber() const; const QList<Parameter>& parameters() const { return params; } QStringList parameterNames() const; diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp index 75295613f7..30d4d28a17 100644 --- a/src/tools/qdoc/qdocdatabase.cpp +++ b/src/tools/qdoc/qdocdatabase.cpp @@ -796,7 +796,6 @@ void QDocDatabase::processForest() { Tree* t = forest_.firstTree(); while (t) { - findAllNamespaces(t->root()); findAllClasses(t->root()); findAllFunctions(t->root()); findAllObsoleteThings(t->root()); @@ -805,6 +804,7 @@ void QDocDatabase::processForest() t->setTreeHasBeenAnalyzed(); t = forest_.nextTree(); } + resolveNamespaces(); } /*! @@ -872,16 +872,10 @@ NodeMap& QDocDatabase::getQmlTypesWithObsoleteMembers() return qmlTypesWithObsoleteMembers_; } -/*! - Constructs the C++ namespace data structure, if it has not - already been constructed. Returns a reference to it. +/*! \fn NodeMap& QDocDatabase::getNamespaces() + Returns a reference to the map of all namespace nodes. + This function must not be called in the -prepare phase. */ -NodeMap& QDocDatabase::getNamespaces() -{ - if (namespaceIndex_.isEmpty()) - processForest(&QDocDatabase::findAllNamespaces); - return namespaceIndex_; -} /*! Construct the C++ class data structures, if they have not @@ -1082,14 +1076,15 @@ void QDocDatabase::findAllNamespaces(InnerNode* node) { NodeList::ConstIterator c = node->childNodes().constBegin(); while (c != node->childNodes().constEnd()) { - if ((*c)->access() != Node::Private) { + if ((*c)->access() != Node::Private || (*c)->isNamespace()) { if ((*c)->isInnerNode()) { findAllNamespaces(static_cast<InnerNode *>(*c)); - if ((*c)->type() == Node::Namespace) { + if ((*c)->isNamespace()) { // Ensure that the namespace's name is not empty (the root // namespace has no name). - if (!(*c)->name().isEmpty()) - namespaceIndex_.insert((*c)->name(), *c); + if (!(*c)->name().isEmpty()) { + nmm_.insert((*c)->name(), *c); + } } } } @@ -1332,8 +1327,56 @@ void QDocDatabase::resolveStuff() //primaryTree()->resolveTargets(primaryTreeRoot()); primaryTree()->resolveCppToQmlLinks(); primaryTree()->resolveUsingClauses(); + resolveNamespaces(); +} + +/*! + */ +void QDocDatabase::resolveNamespaces() +{ + if (!namespaceIndex_.isEmpty()) + return; + Tree* t = forest_.firstTree(); + while (t) { + findAllNamespaces(t->root()); + t = forest_.nextTree(); + } + QList<QString> keys = nmm_.uniqueKeys(); + foreach (QString s, keys) { + NamespaceNode* ns = 0; + QList<Node*> nodes = nmm_.values(s); + int count = nmm_.remove(s); + if (count > 1) { + foreach (Node* n, nodes) { + if (n->isNamespace() && n->wasSeen()) { + ns = static_cast<NamespaceNode*>(n); + break; + } + } + } + else if (count == 1) + ns = static_cast<NamespaceNode*>(nodes.at(0)); + if (ns && ns->wasSeen()) { + if (count >1) { + foreach (Node* n, nodes) { + if (n->isNamespace()) { + NamespaceNode* NS = static_cast<NamespaceNode*>(n); + if (NS != ns) { + while (!NS->childNodes().isEmpty()) { + Node* child = NS->childNodes().first(); + NS->removeChild(child); + ns->addChild(child); + } + } + } + } + } + namespaceIndex_.insert(ns->name(), ns); + } + } } + /*! This function is called for autolinking to a \a type, which could be a function return type or a parameter diff --git a/src/tools/qdoc/qdocdatabase.h b/src/tools/qdoc/qdocdatabase.h index 70307aa3ae..d0c59d731c 100644 --- a/src/tools/qdoc/qdocdatabase.h +++ b/src/tools/qdoc/qdocdatabase.h @@ -278,7 +278,7 @@ class QDocDatabase NodeMap& getClassesWithObsoleteMembers(); NodeMap& getObsoleteQmlTypes(); NodeMap& getQmlTypesWithObsoleteMembers(); - NodeMap& getNamespaces(); + NodeMap& getNamespaces() { resolveNamespaces(); return namespaceIndex_; } NodeMap& getServiceClasses(); NodeMap& getQmlBasicTypes(); NodeMap& getQmlTypes(); @@ -404,9 +404,8 @@ class QDocDatabase } TargetList* getTargetList(const QString& t) { return primaryTree()->getTargetList(t); } QStringList getTargetListKeys() { return primaryTree()->getTargetListKeys(); } - QStringList keys() { - return forest_.keys(); - } + QStringList keys() { return forest_.keys(); } + void resolveNamespaces(); private: friend class QDocIndexFiles; @@ -447,6 +446,7 @@ class QDocDatabase NodeMap obsoleteQmlTypes_; NodeMap qmlTypesWithObsoleteMembers_; NodeMap namespaceIndex_; + NodeMultiMap nmm_; NodeMap serviceClasses_; // MWS: not needed, should be deleted NodeMap qmlBasicTypes_; NodeMap qmlTypes_; diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp index 66152387e4..571b01802d 100644 --- a/src/widgets/dialogs/qmessagebox.cpp +++ b/src/widgets/dialogs/qmessagebox.cpp @@ -1894,18 +1894,17 @@ void QMessageBox::aboutQt(QWidget *parent, const QString &title) "want to share any source code with third parties or otherwise cannot " "comply with the terms of the GNU LGPL version 3 or GNU LGPL version 2.1.</p>" "<p>Qt licensed under the GNU LGPL version 3 is appropriate for the " - "development of Qt applications provided you can comply with the terms " + "development of Qt applications provided you can comply with the terms " "and conditions of the GNU LGPL version 3.</p>" "<p>Qt licensed under the GNU LGPL version 2.1 is appropriate for the " - "development of Qt applications provided you can comply with the terms " + "development of Qt applications provided you can comply with the terms " "and conditions of the GNU LGPL version 2.1.</p>" "<p>Please see <a href=\"http://%2/\">%2</a> " "for an overview of Qt licensing.</p>" "<p>Copyright (C) %1 The Qt Company Ltd and other " "contributors.</p>" - "<p>Qt and the Qt logo are trademarks of The Qt Company Ltd and/or its" - "subsidiary(-ies).</p>" - "<p>Qt is The Qt Company Ltd product developed as an open source" + "<p>Qt and the Qt logo are trademarks of The Qt Company Ltd.</p>" + "<p>Qt is The Qt Company Ltd product developed as an open source " "project. See <a href=\"http://%3/\">%3</a> for more information.</p>" ).arg(QStringLiteral("2015"), QStringLiteral("qt.io/licensing"), diff --git a/src/widgets/kernel/qdesktopwidget.qdoc b/src/widgets/kernel/qdesktopwidget.qdoc index 822bb47a15..6ce312dc2f 100644 --- a/src/widgets/kernel/qdesktopwidget.qdoc +++ b/src/widgets/kernel/qdesktopwidget.qdoc @@ -238,6 +238,11 @@ \property QDesktopWidget::screenCount \brief the number of screens currently available on the system. + Note that on some platforms, screenCount will be zero if there are actually + no screens connected. Applications which were running at the time the + screenCount went to zero will stop rendering graphics until one or more + screens are restored. + \since 4.6 */ diff --git a/src/widgets/kernel/qlayoutitem.cpp b/src/widgets/kernel/qlayoutitem.cpp index f195ac81c9..a79d9bb2c6 100644 --- a/src/widgets/kernel/qlayoutitem.cpp +++ b/src/widgets/kernel/qlayoutitem.cpp @@ -341,6 +341,14 @@ QSpacerItem * QSpacerItem::spacerItem() } /*! + Returns the size policy of this item. +*/ +QSizePolicy QSpacerItem::sizePolicy() const +{ + return sizeP; +} + +/*! If this item is a QWidget, it is returned as a QWidget; otherwise 0 is returned. This function provides type-safe casting. */ diff --git a/src/widgets/kernel/qlayoutitem.h b/src/widgets/kernel/qlayoutitem.h index 7de94852e6..eaa129a85b 100644 --- a/src/widgets/kernel/qlayoutitem.h +++ b/src/widgets/kernel/qlayoutitem.h @@ -102,6 +102,7 @@ public: void setGeometry(const QRect&); QRect geometry() const; QSpacerItem *spacerItem(); + QSizePolicy sizePolicy() const; private: int width; diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp index 5fc2164c97..862a4302f3 100644 --- a/src/widgets/styles/qstyle.cpp +++ b/src/widgets/styles/qstyle.cpp @@ -2355,51 +2355,24 @@ int QStyle::combinedLayoutSpacing(QSizePolicy::ControlTypes controls1, return result; } +// ### Qt 6: Remove in favor of template<class T> QDebug operator<<(QDebug, const QFlags<T> &). +#if QT_VERSION < QT_VERSION_CHECK(6,0,0) QT_BEGIN_INCLUDE_NAMESPACE -#include <QDebug> +# include <QDebug> QT_END_INCLUDE_NAMESPACE -#if !defined(QT_NO_DEBUG_STREAM) +# if !defined(QT_NO_DEBUG_STREAM) QDebug operator<<(QDebug debug, QStyle::State state) { -#if !defined(QT_NO_DEBUG) - debug << "QStyle::State("; - - QStringList states; - if (state & QStyle::State_Active) states << QLatin1String("Active"); - if (state & QStyle::State_AutoRaise) states << QLatin1String("AutoRaise"); - if (state & QStyle::State_Bottom) states << QLatin1String("Bottom"); - if (state & QStyle::State_Children) states << QLatin1String("Children"); - if (state & QStyle::State_DownArrow) states << QLatin1String("DownArrow"); - if (state & QStyle::State_Editing) states << QLatin1String("Editing"); - if (state & QStyle::State_Enabled) states << QLatin1String("Enabled"); - if (state & QStyle::State_FocusAtBorder) states << QLatin1String("FocusAtBorder"); - if (state & QStyle::State_HasFocus) states << QLatin1String("HasFocus"); - if (state & QStyle::State_Horizontal) states << QLatin1String("Horizontal"); - if (state & QStyle::State_Item) states << QLatin1String("Item"); - if (state & QStyle::State_KeyboardFocusChange) states << QLatin1String("KeyboardFocusChange"); - if (state & QStyle::State_MouseOver) states << QLatin1String("MouseOver"); - if (state & QStyle::State_NoChange) states << QLatin1String("NoChange"); - if (state & QStyle::State_Off) states << QLatin1String("Off"); - if (state & QStyle::State_On) states << QLatin1String("On"); - if (state & QStyle::State_Open) states << QLatin1String("Open"); - if (state & QStyle::State_Raised) states << QLatin1String("Raised"); - if (state & QStyle::State_ReadOnly) states << QLatin1String("ReadOnly"); - if (state & QStyle::State_Selected) states << QLatin1String("Selected"); - if (state & QStyle::State_Sibling) states << QLatin1String("Sibling"); - if (state & QStyle::State_Sunken) states << QLatin1String("Sunken"); - if (state & QStyle::State_Top) states << QLatin1String("Top"); - if (state & QStyle::State_UpArrow) states << QLatin1String("UpArrow"); - - std::sort(states.begin(), states.end()); - debug << states.join(QLatin1String(" | ")); - debug << ')'; -#else +# if !defined(QT_NO_DEBUG) + return operator<< <QStyle::StateFlag>(debug, state); +# else Q_UNUSED(state); -#endif +# endif return debug; } -#endif +# endif // !QT_NO_DEBUG_STREAM +#endif // QT_VERSION < QT_VERSION_CHECK(6,0,0) /*! \since 4.6 diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h index f1f063dfcc..b41762795d 100644 --- a/src/widgets/styles/qstyle.h +++ b/src/widgets/styles/qstyle.h @@ -848,7 +848,10 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::State) Q_DECLARE_OPERATORS_FOR_FLAGS(QStyle::SubControls) #if !defined(QT_NO_DEBUG_STREAM) +// ### Qt 6: Remove in favor of template<class T> QDebug operator<<(QDebug, const QFlags<T> &). +# if QT_VERSION < QT_VERSION_CHECK(6,0,0) Q_WIDGETS_EXPORT QDebug operator<<(QDebug debug, QStyle::State state); +# endif #endif QT_END_NAMESPACE diff --git a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp index 93a6daa6b9..ff4963a960 100644 --- a/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp +++ b/tests/auto/corelib/kernel/qcoreapplication/tst_qcoreapplication.cpp @@ -102,10 +102,15 @@ void tst_QCoreApplication::qAppName() const char* appName = "tst_qcoreapplication"; #endif - int argc = 1; - char *argv[] = { const_cast<char*>(appName) }; - TestApplication app(argc, argv); - QCOMPARE(::qAppName(), QString::fromLatin1(appName)); + { + int argc = 1; + char *argv[] = { const_cast<char*>(appName) }; + TestApplication app(argc, argv); + QCOMPARE(::qAppName(), QString::fromLatin1(appName)); + QCOMPARE(QCoreApplication::applicationName(), QString::fromLatin1(appName)); + } + // The application name should still be available after destruction; + // global statics often rely on this. QCOMPARE(QCoreApplication::applicationName(), QString::fromLatin1(appName)); } diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index 717a7633f5..88b1bebb29 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -661,6 +661,9 @@ template<> struct TestValueFactory<QMetaType::QUuid> { template<> struct TestValueFactory<QMetaType::QModelIndex> { static QModelIndex *create() { return new QModelIndex(); } }; +template<> struct TestValueFactory<QMetaType::QPersistentModelIndex> { + static QPersistentModelIndex *create() { return new QPersistentModelIndex(); } +}; template<> struct TestValueFactory<QMetaType::QRegExp> { static QRegExp *create() { @@ -1735,6 +1738,7 @@ struct StreamingTraits DECLARE_NONSTREAMABLE(void) DECLARE_NONSTREAMABLE(void*) DECLARE_NONSTREAMABLE(QModelIndex) +DECLARE_NONSTREAMABLE(QPersistentModelIndex) DECLARE_NONSTREAMABLE(QJsonValue) DECLARE_NONSTREAMABLE(QJsonObject) DECLARE_NONSTREAMABLE(QJsonArray) diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp index 32674c587c..1f5132d369 100644 --- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp +++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp @@ -248,6 +248,7 @@ private slots: void movabilityTest(); void variantInVariant(); void userConversion(); + void modelIndexConversion(); void forwardDeclare(); void debugStream_data(); @@ -3846,6 +3847,17 @@ void tst_QVariant::userConversion() } } +void tst_QVariant::modelIndexConversion() +{ + QVariant modelIndexVariant = QModelIndex(); + QVERIFY(modelIndexVariant.canConvert(QMetaType::QPersistentModelIndex)); + QVERIFY(modelIndexVariant.convert(QMetaType::QPersistentModelIndex)); + QCOMPARE(modelIndexVariant.type(), QVariant::PersistentModelIndex); + QVERIFY(modelIndexVariant.canConvert(QMetaType::QModelIndex)); + QVERIFY(modelIndexVariant.convert(QMetaType::QModelIndex)); + QCOMPARE(modelIndexVariant.type(), QVariant::ModelIndex); +} + class Forward; Q_DECLARE_OPAQUE_POINTER(Forward*) Q_DECLARE_METATYPE(Forward*) @@ -4073,6 +4085,7 @@ void tst_QVariant::implicitConstruction() F(EasingCurve) \ F(Uuid) \ F(ModelIndex) \ + F(PersistentModelIndex) \ F(RegularExpression) \ F(JsonValue) \ F(JsonObject) \ diff --git a/tests/auto/corelib/thread/qatomicinteger/char/char.pro b/tests/auto/corelib/thread/qatomicinteger/char/char.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/char/char.pro +++ b/tests/auto/corelib/thread/qatomicinteger/char/char.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro b/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro +++ b/tests/auto/corelib/thread/qatomicinteger/char16_t/char16_t.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro b/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro +++ b/tests/auto/corelib/thread/qatomicinteger/char32_t/char32_t.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/char/char.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/char/char.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/char/char.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/char16_t/char16_t.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/char16_t/char16_t.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/char16_t/char16_t.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/char32_t/char32_t.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/char32_t/char32_t.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/char32_t/char32_t.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/int/int.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/int/int.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/int/int.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/long/long.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/long/long.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/long/long.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/qlonglong/qlonglong.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/qlonglong/qlonglong.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/qlonglong/qlonglong.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/qptrdiff/qptrdiff.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/qptrdiff/qptrdiff.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/qptrdiff/qptrdiff.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/quintptr/quintptr.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/quintptr/quintptr.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/quintptr/quintptr.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/qulonglong/qulonglong.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/qulonglong/qulonglong.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/qulonglong/qulonglong.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/schar/schar.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/schar/schar.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/schar/schar.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/short/short.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/short/short.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/short/short.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/uchar/uchar.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/uchar/uchar.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/uchar/uchar.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/uint/uint.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/uint/uint.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/uint/uint.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/ulong/ulong.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/ulong/ulong.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/ulong/ulong.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/ushort/ushort.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/ushort/ushort.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/ushort/ushort.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/cxx11/wchar_t/wchar_t.pro b/tests/auto/corelib/thread/qatomicinteger/cxx11/wchar_t/wchar_t.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/cxx11/wchar_t/wchar_t.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/char/char.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/char/char.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/char/char.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/char16_t/char16_t.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/char16_t/char16_t.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/char16_t/char16_t.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/char32_t/char32_t.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/char32_t/char32_t.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/char32_t/char32_t.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/int/int.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/int/int.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/int/int.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/long/long.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/long/long.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/long/long.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/qlonglong/qlonglong.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/qlonglong/qlonglong.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/qlonglong/qlonglong.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/qptrdiff/qptrdiff.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/qptrdiff/qptrdiff.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/qptrdiff/qptrdiff.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/quintptr/quintptr.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/quintptr/quintptr.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/quintptr/quintptr.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/qulonglong/qulonglong.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/qulonglong/qulonglong.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/qulonglong/qulonglong.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/schar/schar.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/schar/schar.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/schar/schar.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/short/short.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/short/short.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/short/short.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/uchar/uchar.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/uchar/uchar.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/uchar/uchar.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/uint/uint.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/uint/uint.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/uint/uint.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/ulong/ulong.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/ulong/ulong.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/ulong/ulong.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/ushort/ushort.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/ushort/ushort.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/ushort/ushort.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/gcc/wchar_t/wchar_t.pro b/tests/auto/corelib/thread/qatomicinteger/gcc/wchar_t/wchar_t.pro new file mode 100644 index 0000000000..64401f0229 --- /dev/null +++ b/tests/auto/corelib/thread/qatomicinteger/gcc/wchar_t/wchar_t.pro @@ -0,0 +1 @@ +include(../../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/int/int.pro b/tests/auto/corelib/thread/qatomicinteger/int/int.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/int/int.pro +++ b/tests/auto/corelib/thread/qatomicinteger/int/int.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/long/long.pro b/tests/auto/corelib/thread/qatomicinteger/long/long.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/long/long.pro +++ b/tests/auto/corelib/thread/qatomicinteger/long/long.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri index dc7cc8bcec..d9ebe64d5b 100644 --- a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri +++ b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pri @@ -1,7 +1,20 @@ -isEmpty(TYPE): error("Project must define TYPE variable") +# Get our build type from the directory name +TYPE = $$basename(_PRO_FILE_PWD_) +dn = $$dirname(_PRO_FILE_PWD_) +FORCE = $$basename(dn) + +equals(FORCE, cxx11) { + suffix = Cxx11_$$TYPE + DEFINES += QT_ATOMIC_FORCE_CXX11 +} else: equals(FORCE, gcc) { + suffix = Gcc_$$TYPE + DEFINES += QT_ATOMIC_FORCE_GCC +} else { + suffix = $$TYPE +} CONFIG += testcase parallel_test QT = core testlib -TARGET = tst_qatomicinteger_$$TYPE +TARGET = tst_qatomicinteger_$$lower($$suffix) SOURCES = $$PWD/tst_qatomicinteger.cpp -DEFINES += QATOMIC_TEST_TYPE=$$TYPE tst_QAtomicIntegerXX=tst_QAtomicInteger_$$TYPE +DEFINES += QATOMIC_TEST_TYPE=$$TYPE tst_QAtomicIntegerXX=tst_QAtomicInteger_$$suffix diff --git a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro index 373e8801a4..58e5b157bd 100644 --- a/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro +++ b/tests/auto/corelib/thread/qatomicinteger/qatomicinteger.pro @@ -17,3 +17,42 @@ SUBDIRS=\ ushort \ wchar_t \ + +contains(QT_CONFIG, c++11)|msvc: SUBDIRS +=\ + cxx11/char \ + cxx11/char16_t \ + cxx11/char32_t \ + cxx11/int \ + cxx11/long \ + cxx11/qlonglong \ + cxx11/qptrdiff \ + cxx11/quintptr \ + cxx11/qulonglong \ + cxx11/schar \ + cxx11/short \ + cxx11/uchar \ + cxx11/uint \ + cxx11/ulong \ + cxx11/ushort \ + cxx11/wchar_t \ + + +# The GCC-style atomics only support 32-bit and pointer-sized but add +# them all anyway so we ensure the macros are properly defined +gcc: SUBDIRS +=\ + gcc/char \ + gcc/char16_t \ + gcc/char32_t \ + gcc/int \ + gcc/long \ + gcc/qlonglong \ + gcc/qptrdiff \ + gcc/quintptr \ + gcc/qulonglong \ + gcc/schar \ + gcc/short \ + gcc/uchar \ + gcc/uint \ + gcc/ulong \ + gcc/ushort \ + gcc/wchar_t \ diff --git a/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro b/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro +++ b/tests/auto/corelib/thread/qatomicinteger/qlonglong/qlonglong.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro b/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro +++ b/tests/auto/corelib/thread/qatomicinteger/qptrdiff/qptrdiff.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro b/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro +++ b/tests/auto/corelib/thread/qatomicinteger/quintptr/quintptr.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro b/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro +++ b/tests/auto/corelib/thread/qatomicinteger/qulonglong/qulonglong.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro b/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro +++ b/tests/auto/corelib/thread/qatomicinteger/schar/schar.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/short/short.pro b/tests/auto/corelib/thread/qatomicinteger/short/short.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/short/short.pro +++ b/tests/auto/corelib/thread/qatomicinteger/short/short.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp index cb01237b85..d3c85c54a7 100644 --- a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp +++ b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp @@ -31,6 +31,30 @@ ** ****************************************************************************/ +#ifdef QT_ATOMIC_FORCE_CXX11 +// We need to check if this compiler has C++11 atomics and constexpr support. +// We can't rely on qcompilerdetection.h because it forces all of qglobal.h to +// be included, which causes qbasicatomic.h to be included too. +// Incomplete, but ok +# if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1500 && (__cplusplus >= 201103L || defined(__INTEL_CXX11_MODE__)) +# elif defined(__clang__) && (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)) +# if !__has_feature(cxx_constexpr) || !__has_feature(cxx_atomic) || !__has_include(<atomic>) +# undef QT_ATOMIC_FORCE_CXX11 +# endif +# elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 407 && (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)) +# elif defined(_MSC_VER) && _MSC_VER >= 1900 + // We need MSVC 2015 because of: atomics (2012), constexpr (2015), and unrestricted unions (2015). + // Support for constexpr is not working completely on MSVC 2015 but it's enough for the test. +# else +# undef QT_ATOMIC_FORCE_CXX11 +# endif + +# ifndef QT_ATOMIC_FORCE_CXX11 +# undef QATOMIC_TEST_TYPE +# define QATOMIC_TEST_TYPE unsupported +# endif +#endif + #include <QtTest> #include <QAtomicInt> diff --git a/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro b/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro +++ b/tests/auto/corelib/thread/qatomicinteger/uchar/uchar.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro b/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro +++ b/tests/auto/corelib/thread/qatomicinteger/uint/uint.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro b/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro +++ b/tests/auto/corelib/thread/qatomicinteger/ulong/ulong.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro b/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro +++ b/tests/auto/corelib/thread/qatomicinteger/ushort/ushort.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro b/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro index 51ef1add8f..1e97d5cbae 100644 --- a/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro +++ b/tests/auto/corelib/thread/qatomicinteger/wchar_t/wchar_t.pro @@ -1,2 +1 @@ -TYPE = $$basename(PWD) include(../qatomicinteger.pri) diff --git a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp index c6806086d3..446e56e936 100644 --- a/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/corelib/tools/qdatetime/tst_qdatetime.cpp @@ -142,6 +142,9 @@ private slots: void isDaylightTime() const; void daylightTransitions() const; void timeZones() const; +#if defined(Q_OS_UNIX) + void systemTimeZoneChange() const; +#endif void invalid() const; @@ -2984,6 +2987,56 @@ void tst_QDateTime::timeZones() const QCOMPARE(future.offsetFromUtc(), 28800); } +#if defined(Q_OS_UNIX) +// Currently disabled on Windows as adjusting the timezone +// requires additional privileges that aren't normally +// enabled for a process. This can be achieved by calling +// AdjustTokenPrivileges() and then SetTimeZoneInformation(), +// which will require linking to a different library to access that API. +static void setTimeZone(const QByteArray &tz) +{ + qputenv("TZ", tz); + ::tzset(); + +// following left for future reference, see comment above +// #if defined(Q_OS_WIN32) +// ::_tzset(); +// #endif +} + +void tst_QDateTime::systemTimeZoneChange() const +{ + struct ResetTZ { + QByteArray original; + ResetTZ() : original(qgetenv("TZ")) {} + ~ResetTZ() { setTimeZone(original); } + } scopedReset; + + // Set the timezone to Brisbane time + setTimeZone(QByteArray("AEST-10:00")); + + QDateTime localDate = QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::LocalTime); + QDateTime utcDate = QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::UTC); + QDateTime tzDate = QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), QTimeZone("Australia/Brisbane")); + qint64 localMsecs = localDate.toMSecsSinceEpoch(); + qint64 utcMsecs = utcDate.toMSecsSinceEpoch(); + qint64 tzMsecs = tzDate.toMSecsSinceEpoch(); + + // check that Australia/Brisbane is known + QVERIFY(tzDate.timeZone().isValid()); + + // Change to Indian time + setTimeZone(QByteArray("IST-05:30")); + + QCOMPARE(localDate, QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::LocalTime)); + QVERIFY(localMsecs != localDate.toMSecsSinceEpoch()); + QCOMPARE(utcDate, QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), Qt::UTC)); + QCOMPARE(utcDate.toMSecsSinceEpoch(), utcMsecs); + QCOMPARE(tzDate, QDateTime(QDate(2012, 6, 1), QTime(2, 15, 30), QTimeZone("Australia/Brisbane"))); + QCOMPARE(tzDate.toMSecsSinceEpoch(), tzMsecs); +} +#endif + void tst_QDateTime::invalid() const { QDateTime invalidDate = QDateTime(QDate(0, 0, 0), QTime(-1, -1, -1)); diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index 52c3e65a24..8cd9610542 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -2040,6 +2040,9 @@ void tst_QString::simplified() QFETCH(QString, full); QFETCH(QString, simple); + QString orig_full = full; + orig_full.data(); // forces a detach + QString result = full.simplified(); if (simple.isNull()) { QVERIFY2(result.isNull(), qPrintable("'" + full + "' did not yield null: " + result)); @@ -2048,6 +2051,12 @@ void tst_QString::simplified() } else { QCOMPARE(result, simple); } + QCOMPARE(full, orig_full); + + // without detaching: + QString copy1 = full; + QCOMPARE(qMove(full).simplified(), simple); + QCOMPARE(full, orig_full); // force a detach if (!full.isEmpty()) diff --git a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp index ed93ff24b0..2c38e4c111 100644 --- a/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp +++ b/tests/auto/gui/math3d/qquaternion/tst_qquaternion.cpp @@ -35,6 +35,52 @@ #include <QtCore/qmath.h> #include <QtGui/qquaternion.h> +// This is a more tolerant version of qFuzzyCompare that also handles the case +// where one or more of the values being compare are close to zero +static inline bool myFuzzyCompare(float p1, float p2) +{ + if (qFuzzyIsNull(p1) && qFuzzyIsNull(p2)) + return true; + return qAbs(qAbs(p1) - qAbs(p2)) <= 0.00003f; +} + +static inline bool myFuzzyCompare(const QVector3D &v1, const QVector3D &v2) +{ + return myFuzzyCompare(v1.x(), v2.x()) + && myFuzzyCompare(v1.y(), v2.y()) + && myFuzzyCompare(v1.z(), v2.z()); +} + +static inline bool myFuzzyCompare(const QQuaternion &q1, const QQuaternion &q2) +{ + const float d = QQuaternion::dotProduct(q1, q2); + return myFuzzyCompare(d * d, 1.0f); +} + +static inline bool myFuzzyCompareRadians(float p1, float p2) +{ + static const float fPI = float(M_PI); + if (p1 < -fPI) + p1 += 2.0f * fPI; + else if (p1 > fPI) + p1 -= 2.0f * fPI; + + if (p2 < -fPI) + p2 += 2.0f * fPI; + else if (p2 > fPI) + p2 -= 2.0f * fPI; + + return qAbs(qAbs(p1) - qAbs(p2)) <= qDegreesToRadians(0.05f); +} + +static inline bool myFuzzyCompareDegrees(float p1, float p2) +{ + p1 = qDegreesToRadians(p1); + p2 = qDegreesToRadians(p2); + return myFuzzyCompareRadians(p1, p2); +} + + class tst_QQuaternion : public QObject { Q_OBJECT @@ -45,6 +91,9 @@ public: private slots: void create(); + void dotProduct_data(); + void dotProduct(); + void length_data(); void length(); @@ -86,6 +135,12 @@ private slots: void fromRotationMatrix_data(); void fromRotationMatrix(); + void fromAxes_data(); + void fromAxes(); + + void rotationTo_data(); + void rotationTo(); + void fromEulerAngles_data(); void fromEulerAngles(); @@ -219,6 +274,58 @@ void tst_QQuaternion::create() QCOMPARE(v10.w(), 34.0f); } +// Test the computation of dot product. +void tst_QQuaternion::dotProduct_data() +{ + QTest::addColumn<float>("x1"); + QTest::addColumn<float>("y1"); + QTest::addColumn<float>("z1"); + QTest::addColumn<float>("scalar1"); + QTest::addColumn<float>("x2"); + QTest::addColumn<float>("y2"); + QTest::addColumn<float>("z2"); + QTest::addColumn<float>("scalar2"); + QTest::addColumn<float>("dot"); + + QTest::newRow("null") + << 0.0f << 0.0f << 0.0f << 0.0f + << 0.0f << 0.0f << 0.0f << 0.0f + << 0.0f; + + QTest::newRow("identity") + << 0.0f << 0.0f << 0.0f << 1.0f + << 0.0f << 0.0f << 0.0f << 1.0f + << 1.0f; + + QTest::newRow("unitvec") + << 1.0f << 0.0f << 0.0f << 0.0f + << 0.0f << 1.0f << 0.0f << 0.0f + << 0.0f; + + QTest::newRow("complex") + << 1.0f << 2.0f << 3.0f << 4.0f + << 4.0f << 5.0f << 6.0f << 7.0f + << 60.0f; +} +void tst_QQuaternion::dotProduct() +{ + QFETCH(float, x1); + QFETCH(float, y1); + QFETCH(float, z1); + QFETCH(float, scalar1); + QFETCH(float, x2); + QFETCH(float, y2); + QFETCH(float, z2); + QFETCH(float, scalar2); + QFETCH(float, dot); + + QQuaternion q1(scalar1, x1, y1, z1); + QQuaternion q2(scalar2, x2, y2, z2); + + QCOMPARE(QQuaternion::dotProduct(q1, q2), dot); + QCOMPARE(QQuaternion::dotProduct(q2, q1), dot); +} + // Test length computation for quaternions. void tst_QQuaternion::length_data() { @@ -771,40 +878,115 @@ void tst_QQuaternion::fromRotationMatrix() QVERIFY(qFuzzyCompare(answer, result) || qFuzzyCompare(-answer, result)); } -// This is a more tolerant version of qFuzzyCompare that also handles the case -// where one or more of the values being compare are close to zero -static inline bool myFuzzyCompare(float p1, float p2) +// Test quaternion convertion to and from orthonormal axes. +void tst_QQuaternion::fromAxes_data() { - if (qFuzzyIsNull(p1)) - return qFuzzyIsNull(p2); - if (qFuzzyIsNull(p2)) - return false; - // a very slightly looser version of qFuzzyCompare - // for use with values that are not very close to zero - return qAbs(p1 - p2) <= 0.00003f * qMin(qAbs(p1), qAbs(p2)); -} + QTest::addColumn<float>("x1"); + QTest::addColumn<float>("y1"); + QTest::addColumn<float>("z1"); + QTest::addColumn<float>("angle"); + QTest::addColumn<QVector3D>("xAxis"); + QTest::addColumn<QVector3D>("yAxis"); + QTest::addColumn<QVector3D>("zAxis"); -static inline bool myFuzzyCompareRadians(float p1, float p2) + QTest::newRow("null") + << 0.0f << 0.0f << 0.0f << 0.0f + << QVector3D(1, 0, 0) << QVector3D(0, 1, 0) << QVector3D(0, 0, 1); + + QTest::newRow("xonly") + << 1.0f << 0.0f << 0.0f << 90.0f + << QVector3D(1, 0, 0) << QVector3D(0, 0, 1) << QVector3D(0, -1, 0); + + QTest::newRow("yonly") + << 0.0f << 1.0f << 0.0f << 180.0f + << QVector3D(-1, 0, 0) << QVector3D(0, 1, 0) << QVector3D(0, 0, -1); + + QTest::newRow("zonly") + << 0.0f << 0.0f << 1.0f << 270.0f + << QVector3D(0, -1, 0) << QVector3D(1, 0, 0) << QVector3D(0, 0, 1); + + QTest::newRow("complex") + << 1.0f << 2.0f << -3.0f << 45.0f + << QVector3D(0.728028, -0.525105, -0.440727) << QVector3D(0.608789, 0.790791, 0.0634566) << QVector3D(0.315202, -0.314508, 0.895395); +} +void tst_QQuaternion::fromAxes() { - static const float fPI = float(M_PI); - if (p1 < -fPI) - p1 += 2.0f * fPI; - else if (p1 > fPI) - p1 -= 2.0f * fPI; + QFETCH(float, x1); + QFETCH(float, y1); + QFETCH(float, z1); + QFETCH(float, angle); + QFETCH(QVector3D, xAxis); + QFETCH(QVector3D, yAxis); + QFETCH(QVector3D, zAxis); - if (p2 < -fPI) - p2 += 2.0f * fPI; - else if (p2 > fPI) - p2 -= 2.0f * fPI; + QQuaternion result = QQuaternion::fromAxisAndAngle(QVector3D(x1, y1, z1), angle); - return qAbs(qAbs(p1) - qAbs(p2)) <= qDegreesToRadians(0.05f); + QVector3D axes[3]; + result.getAxes(&axes[0], &axes[1], &axes[2]); + QVERIFY(myFuzzyCompare(axes[0], xAxis)); + QVERIFY(myFuzzyCompare(axes[1], yAxis)); + QVERIFY(myFuzzyCompare(axes[2], zAxis)); + + QQuaternion answer = QQuaternion::fromAxes(axes[0], axes[1], axes[2]); + + QVERIFY(qFuzzyCompare(answer, result) || qFuzzyCompare(-answer, result)); } -static inline bool myFuzzyCompareDegrees(float p1, float p2) +// Test shortest arc quaternion. +void tst_QQuaternion::rotationTo_data() { - p1 = qDegreesToRadians(p1); - p2 = qDegreesToRadians(p2); - return myFuzzyCompareRadians(p1, p2); + QTest::addColumn<QVector3D>("from"); + QTest::addColumn<QVector3D>("to"); + + // same + QTest::newRow("+X -> +X") << QVector3D(10.0f, 0.0f, 0.0f) << QVector3D(10.0f, 0.0f, 0.0f); + QTest::newRow("-X -> -X") << QVector3D(-10.0f, 0.0f, 0.0f) << QVector3D(-10.0f, 0.0f, 0.0f); + QTest::newRow("+Y -> +Y") << QVector3D(0.0f, 10.0f, 0.0f) << QVector3D(0.0f, 10.0f, 0.0f); + QTest::newRow("-Y -> -Y") << QVector3D(0.0f, -10.0f, 0.0f) << QVector3D(0.0f, -10.0f, 0.0f); + QTest::newRow("+Z -> +Z") << QVector3D(0.0f, 0.0f, 10.0f) << QVector3D(0.0f, 0.0f, 10.0f); + QTest::newRow("-Z -> -Z") << QVector3D(0.0f, 0.0f, -10.0f) << QVector3D(0.0f, 0.0f, -10.0f); + QTest::newRow("+X+Y+Z -> +X+Y+Z") << QVector3D(10.0f, 10.0f, 10.0f) << QVector3D(10.0f, 10.0f, 10.0f); + QTest::newRow("-X-Y-Z -> -X-Y-Z") << QVector3D(-10.0f, -10.0f, -10.0f) << QVector3D(-10.0f, -10.0f, -10.0f); + + // arbitrary + QTest::newRow("+Z -> +X") << QVector3D(0.0f, 0.0f, 10.0f) << QVector3D(10.0f, 0.0f, 0.0f); + QTest::newRow("+Z -> -X") << QVector3D(0.0f, 0.0f, 10.0f) << QVector3D(-10.0f, 0.0f, 0.0f); + QTest::newRow("+Z -> +Y") << QVector3D(0.0f, 0.0f, 10.0f) << QVector3D(0.0f, 10.0f, 0.0f); + QTest::newRow("+Z -> -Y") << QVector3D(0.0f, 0.0f, 10.0f) << QVector3D(0.0f, -10.0f, 0.0f); + QTest::newRow("-Z -> +X") << QVector3D(0.0f, 0.0f, -10.0f) << QVector3D(10.0f, 0.0f, 0.0f); + QTest::newRow("-Z -> -X") << QVector3D(0.0f, 0.0f, -10.0f) << QVector3D(-10.0f, 0.0f, 0.0f); + QTest::newRow("-Z -> +Y") << QVector3D(0.0f, 0.0f, -10.0f) << QVector3D(0.0f, 10.0f, 0.0f); + QTest::newRow("-Z -> -Y") << QVector3D(0.0f, 0.0f, -10.0f) << QVector3D(0.0f, -10.0f, 0.0f); + QTest::newRow("+X -> +Y") << QVector3D(10.0f, 0.0f, 0.0f) << QVector3D(0.0f, 10.0f, 0.0f); + QTest::newRow("+X -> -Y") << QVector3D(10.0f, 0.0f, 0.0f) << QVector3D(0.0f, -10.0f, 0.0f); + QTest::newRow("-X -> +Y") << QVector3D(-10.0f, 0.0f, 0.0f) << QVector3D(0.0f, 10.0f, 0.0f); + QTest::newRow("-X -> -Y") << QVector3D(-10.0f, 0.0f, 0.0f) << QVector3D(0.0f, -10.0f, 0.0f); + QTest::newRow("+X+Y+Z -> +X-Y-Z") << QVector3D(10.0f, 10.0f, 10.0f) << QVector3D(10.0f, -10.0f, -10.0f); + QTest::newRow("-X-Y+Z -> -X+Y-Z") << QVector3D(-10.0f, -10.0f, 10.0f) << QVector3D(-10.0f, 10.0f, -10.0f); + QTest::newRow("+X+Y+Z -> +Z") << QVector3D(10.0f, 10.0f, 10.0f) << QVector3D(0.0f, 0.0f, 10.0f); + + // collinear + QTest::newRow("+X -> -X") << QVector3D(10.0f, 0.0f, 0.0f) << QVector3D(-10.0f, 0.0f, 0.0f); + QTest::newRow("+Y -> -Y") << QVector3D(0.0f, 10.0f, 0.0f) << QVector3D(0.0f, -10.0f, 0.0f); + QTest::newRow("+Z -> -Z") << QVector3D(0.0f, 0.0f, 10.0f) << QVector3D(0.0f, 0.0f, -10.0f); + QTest::newRow("+X+Y+Z -> -X-Y-Z") << QVector3D(10.0f, 10.0f, 10.0f) << QVector3D(-10.0f, -10.0f, -10.0f); +} +void tst_QQuaternion::rotationTo() +{ + QFETCH(QVector3D, from); + QFETCH(QVector3D, to); + + QQuaternion q1 = QQuaternion::rotationTo(from, to); + QVERIFY(myFuzzyCompare(q1, q1.normalized())); + QVector3D vec1(q1 * from); + vec1 *= (to.length() / from.length()); // discard rotated length + QVERIFY(myFuzzyCompare(vec1, to)); + + QQuaternion q2 = QQuaternion::rotationTo(to, from); + QVERIFY(myFuzzyCompare(q2, q2.normalized())); + QVector3D vec2(q2 * to); + vec2 *= (from.length() / to.length()); // discard rotated length + QVERIFY(myFuzzyCompare(vec2, from)); } // Test quaternion creation from an axis and an angle. diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp index 49a030aaaa..ef24cbf3c8 100644 --- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp @@ -83,6 +83,8 @@ private slots: void isInSubnet(); void isLoopback_data(); void isLoopback(); + void convertv4v6_data(); + void convertv4v6(); }; QT_BEGIN_NAMESPACE @@ -313,6 +315,10 @@ void tst_QHostAddress::compare_data() QTest::newRow("5") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::Broadcast) << false; QTest::newRow("6") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << false; QTest::newRow("7") << QHostAddress() << QHostAddress(QHostAddress::LocalHostIPv6) << false; + + Q_IPV6ADDR localhostv4mapped = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1 }; + QTest::newRow("v4-v4mapped") << QHostAddress(QHostAddress::LocalHost) << QHostAddress("::ffff:127.0.0.1") << false; + QTest::newRow("v4-v4mapped-2") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(localhostv4mapped) << false; } void tst_QHostAddress::compare() @@ -322,6 +328,7 @@ void tst_QHostAddress::compare() QFETCH(bool, result); QCOMPARE(first == second, result); + QCOMPARE(second == first, result); if (result == true) QVERIFY(qHash(first) == qHash(second)); } @@ -657,5 +664,51 @@ void tst_QHostAddress::isLoopback() QCOMPARE(address.isLoopback(), result); } +void tst_QHostAddress::convertv4v6_data() +{ + QTest::addColumn<QHostAddress>("source"); + QTest::addColumn<int>("protocol"); + QTest::addColumn<QHostAddress>("result"); + + QTest::newRow("any-to-v4") << QHostAddress(QHostAddress::Any) << 4 << QHostAddress(QHostAddress::AnyIPv4); + QTest::newRow("any-to-v6") << QHostAddress(QHostAddress::Any) << 6 << QHostAddress(QHostAddress::AnyIPv6); + QTest::newRow("anyv4-to-v6") << QHostAddress(QHostAddress::AnyIPv4) << 6 << QHostAddress(QHostAddress::AnyIPv6); + QTest::newRow("anyv6-to-v4") << QHostAddress(QHostAddress::AnyIPv6) << 4 << QHostAddress(QHostAddress::AnyIPv4); + + QTest::newRow("v4mapped-to-v4") << QHostAddress("::ffff:192.0.2.1") << 4 << QHostAddress("192.0.2.1"); + QTest::newRow("v4-to-v4mapped") << QHostAddress("192.0.2.1") << 6 << QHostAddress("::ffff:192.0.2.1"); + + // we won't convert 127.0.0.1 to ::1 or vice-versa: + // you can connect to a v4 server socket with ::ffff:127.0.0.1, but not with ::1 + QTest::newRow("localhost-to-v4mapped") << QHostAddress(QHostAddress::LocalHost) << 6 << QHostAddress("::ffff:127.0.0.1"); + QTest::newRow("v4mapped-to-localhost") << QHostAddress("::ffff:127.0.0.1") << 4 << QHostAddress(QHostAddress::LocalHost); + + // in turn, that means localhost6 doesn't convert to v4 + QTest::newRow("localhost6-to-v4") << QHostAddress(QHostAddress::LocalHostIPv6) << 4 << QHostAddress(); + + // some other v6 addresses that won't convert to v4 + QTest::newRow("v4compat-to-v4") << QHostAddress("::192.0.2.1") << 4 << QHostAddress(); + QTest::newRow("localhostv4compat-to-v4") << QHostAddress("::127.0.0.1") << 4 << QHostAddress(); + QTest::newRow("v6global-to-v4") << QHostAddress("2001:db8::1") << 4 << QHostAddress(); + QTest::newRow("v6multicast-to-v4") << QHostAddress("ff02::1") << 4 << QHostAddress(); +} + +void tst_QHostAddress::convertv4v6() +{ + QFETCH(QHostAddress, source); + QFETCH(int, protocol); + QFETCH(QHostAddress, result); + + if (protocol == 4) { + bool ok; + quint32 v4 = source.toIPv4Address(&ok); + QCOMPARE(ok, result.protocol() == QAbstractSocket::IPv4Protocol); + if (ok) + QCOMPARE(QHostAddress(v4), result); + } else if (protocol == 6) { + QCOMPARE(QHostAddress(source.toIPv6Address()), result); + } +} + QTEST_MAIN(tst_QHostAddress) #include "tst_qhostaddress.moc" diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 13d8a21794..109e48ed74 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -73,6 +73,7 @@ // RVCT compiles also unused inline methods # include <QNetworkProxy> +#include <time.h> #ifdef Q_OS_LINUX #include <stdio.h> #include <stdlib.h> @@ -123,6 +124,8 @@ private slots: void constructing(); void bind_data(); void bind(); + void bindThenResolveHost_data(); + void bindThenResolveHost(); void setInvalidSocketDescriptor(); #ifndef Q_OS_WINRT void setSocketDescriptor(); @@ -246,6 +249,9 @@ private: int earlyBytesWrittenCount; int earlyReadyReadCount; QString stressTestDir; + + QString firstFailName; + QHostInfo firstFailInfo; }; enum ProxyTests { @@ -298,7 +304,10 @@ public: }; tst_QTcpSocket::tst_QTcpSocket() + : firstFailName("qt-test-server-first-fail") { + qsrand(time(NULL)); + tmpSocket = 0; //This code relates to the socketsConstructedBeforeEventLoop test case @@ -309,6 +318,8 @@ tst_QTcpSocket::tst_QTcpSocket() connect(earlyConstructedSockets->endPoints[0], SIGNAL(readyRead()), this, SLOT(earlySocketReadyRead())); connect(earlyConstructedSockets->endPoints[1], SIGNAL(bytesWritten(qint64)), this, SLOT(earlySocketBytesSent(qint64))); earlyConstructedSockets->endPoints[1]->write("hello work"); + + firstFailInfo.setAddresses(QList<QHostAddress>() << QHostAddress("224.0.0.0") << QtNetworkSettings::serverIP()); } tst_QTcpSocket::~tst_QTcpSocket() @@ -390,6 +401,7 @@ void tst_QTcpSocket::init() } qt_qhostinfo_clear_cache(); + qt_qhostinfo_cache_inject(firstFailName, firstFailInfo); } QTcpSocket *tst_QTcpSocket::newSocket() const @@ -487,9 +499,12 @@ void tst_QTcpSocket::constructing() void tst_QTcpSocket::bind_data() { QTest::addColumn<QString>("stringAddr"); + QTest::addColumn<int>("port"); QTest::addColumn<bool>("successExpected"); QTest::addColumn<QString>("stringExpectedLocalAddress"); + bool testIpv6 = false; + // iterate all interfaces, add all addresses on them as test data QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces(); foreach (const QNetworkInterface &netinterface, interfaces) { @@ -502,10 +517,26 @@ void tst_QTcpSocket::bind_data() continue; // link-local bind will fail, at least on Linux, so skip it. QString ip(entry.ip().toString()); - QTest::newRow(ip.toLatin1().constData()) << ip << true << ip; + QTest::newRow(ip.toLatin1().constData()) << ip << 0 << true << ip; + + if (!testIpv6 && entry.ip().protocol() == QAbstractSocket::IPv6Protocol) + testIpv6 = true; } } + // test binding to localhost + QTest::newRow("0.0.0.0") << "0.0.0.0" << 0 << true << "0.0.0.0"; + if (testIpv6) + QTest::newRow("[::]") << "::" << 0 << true << "::"; + + // and binding with a port number... + // Since we want to test that we got the port number we asked for, we need a random port number. + // We use random in case a previous run of the test left the port lingering open. + // -1 indicates "random port" + QTest::newRow("0.0.0.0:randomport") << "0.0.0.0" << -1 << true << "0.0.0.0"; + if (testIpv6) + QTest::newRow("[::]:randomport") << "::" << -1 << true << "::"; + // additionally, try bind to known-bad addresses, and make sure this doesn't work // these ranges are guaranteed to be reserved for 'documentation purposes', // and thus, should be unused in the real world. Not that I'm assuming the @@ -514,8 +545,16 @@ void tst_QTcpSocket::bind_data() knownBad << "198.51.100.1"; knownBad << "2001:0DB8::1"; foreach (const QString &badAddress, knownBad) { - QTest::newRow(badAddress.toLatin1().constData()) << badAddress << false << QString(); + QTest::newRow(badAddress.toLatin1().constData()) << badAddress << 0 << false << QString(); } + +#ifdef Q_OS_UNIX + // try to bind to a privileged ports + // we should fail if we're not root (unless the ports are in use!) + QTest::newRow("127.0.0.1:1") << "127.0.0.1" << 1 << !geteuid() << (geteuid() ? QString() : "127.0.0.1"); + if (testIpv6) + QTest::newRow("[::]:1") << "::" << 1 << !geteuid() << (geteuid() ? QString() : "::"); +#endif } void tst_QTcpSocket::bind() @@ -524,23 +563,124 @@ void tst_QTcpSocket::bind() if (setProxy) return; // QTBUG-22964 for proxies, QTBUG-29972 for QSKIP QFETCH(QString, stringAddr); + QFETCH(int, port); QFETCH(bool, successExpected); QFETCH(QString, stringExpectedLocalAddress); QHostAddress addr(stringAddr); QHostAddress expectedLocalAddress(stringExpectedLocalAddress); + QTcpSocket dummySocket; // used only to "use up" a file descriptor + dummySocket.bind(); + QTcpSocket *socket = newSocket(); - qDebug() << "Binding " << addr; + quint16 boundPort; + qintptr fd; if (successExpected) { - QVERIFY2(socket->bind(addr), qPrintable(socket->errorString())); + bool randomPort = port == -1; + int attemptsLeft = 5; // only used with randomPort + do { + if (randomPort) { + // try to get a random port number + // we do this to ensure we're not trying to bind to the same port as we've just used in + // a previous run - race condition with the OS actually freeing the port + Q_STATIC_ASSERT(RAND_MAX > 1024); + port = qrand() & USHRT_MAX; + if (port < 1024) + continue; + } + + bool bindSuccess = socket->bind(addr, port); + if (!bindSuccess && randomPort && socket->error() == QTcpSocket::AddressInUseError) { + // we may have been unlucky and hit an already open port, so try another + --attemptsLeft; + continue; + } + + QVERIFY2(bindSuccess, qPrintable(socket->errorString() + ", tried port " + QString::number(port))); + break; + } while (randomPort && attemptsLeft); + + QCOMPARE(socket->state(), QAbstractSocket::BoundState); + boundPort = socket->localPort(); + if (port) + QCOMPARE(int(boundPort), port); + fd = socket->socketDescriptor(); + QVERIFY(fd != INVALID_SOCKET); } else { - QVERIFY(!socket->bind(addr)); + QVERIFY(!socket->bind(addr, port)); + QCOMPARE(socket->localPort(), quint16(0)); } QCOMPARE(socket->localAddress(), expectedLocalAddress); + if (successExpected) { + // try to use the socket and expect it to remain working + QTcpServer server; + QVERIFY(server.listen(addr)); + + // free up the file descriptor + dummySocket.close(); + + QHostAddress remoteAddr = addr; + if (addr == QHostAddress::AnyIPv4) + remoteAddr = QHostAddress::LocalHost; + else if (addr == QHostAddress::AnyIPv6) + remoteAddr = QHostAddress::LocalHostIPv6; + + socket->connectToHost(remoteAddr, server.serverPort()); + QVERIFY2(socket->waitForConnected(2000), socket->errorString().toLocal8Bit()); + QVERIFY(server.waitForNewConnection(2000)); + + QTcpSocket *acceptedSocket = server.nextPendingConnection(); + QCOMPARE(socket->localPort(), boundPort); + QCOMPARE(acceptedSocket->peerPort(), boundPort); + QCOMPARE(socket->localAddress(), remoteAddr); + QCOMPARE(socket->socketDescriptor(), fd); + } + + delete socket; +} + +//---------------------------------------------------------------------------------- + +void tst_QTcpSocket::bindThenResolveHost_data() +{ + QTest::addColumn<QString>("hostName"); + QTest::newRow("ip-literal") << QtNetworkSettings::serverIP().toString(); + QTest::newRow("name") << QtNetworkSettings::serverName(); + QTest::newRow("first-fail") << firstFailName; +} + +// similar to the previous test, but we'll connect to a host name that needs resolving +void tst_QTcpSocket::bindThenResolveHost() +{ + QFETCH_GLOBAL(bool, setProxy); + if (setProxy) + return; // doesn't make sense to test binding locally with proxies + + QFETCH(QString, hostName); + + QTcpSocket dummySocket; // used only to "use up" a file descriptor + dummySocket.bind(); + + QTcpSocket *socket = newSocket(); + + QVERIFY2(socket->bind(QHostAddress(QHostAddress::AnyIPv4), 0), socket->errorString().toLocal8Bit()); + QCOMPARE(socket->state(), QAbstractSocket::BoundState); + quint16 boundPort = socket->localPort(); + qintptr fd = socket->socketDescriptor(); + QVERIFY(fd != INVALID_SOCKET); + + dummySocket.close(); + + socket->connectToHost(hostName, 80); + QVERIFY2(socket->waitForConnected(), "Network timeout"); + + QCOMPARE(socket->localPort(), boundPort); + QCOMPARE(socket->socketDescriptor(), fd); + delete socket; } @@ -593,13 +733,10 @@ void tst_QTcpSocket::setSocketDescriptor() QCOMPARE(socket->socketDescriptor(), (qintptr)sock); qt_qhostinfo_clear_cache(); //avoid the HostLookupState being skipped due to address being in cache from previous test. - socket->connectToHost(QtNetworkSettings::serverName(), 143); + socket->connectToHost(QtNetworkSettings::serverName(), 80); QCOMPARE(socket->state(), QTcpSocket::HostLookupState); QCOMPARE(socket->socketDescriptor(), (qintptr)sock); QVERIFY(socket->waitForConnected(10000)); - // skip this, it has been broken for years, see task 260735 - // if somebody complains, consider fixing it, but it might break existing applications. - QEXPECT_FAIL("", "bug has been around for years, will not fix without need", Continue); QCOMPARE(socket->socketDescriptor(), (qintptr)sock); delete socket; #ifdef Q_OS_WIN @@ -616,8 +753,8 @@ void tst_QTcpSocket::socketDescriptor() QCOMPARE(socket->socketDescriptor(), (qintptr)-1); socket->connectToHost(QtNetworkSettings::serverName(), 143); - QVERIFY((socket->state() == QAbstractSocket::HostLookupState && socket->socketDescriptor() == -1) || - (socket->state() == QAbstractSocket::ConnectingState && socket->socketDescriptor() != -1)); + QVERIFY(socket->state() == QAbstractSocket::HostLookupState || + socket->state() == QAbstractSocket::ConnectingState); QVERIFY(socket->waitForConnected(10000)); QVERIFY(socket->state() == QAbstractSocket::ConnectedState); QVERIFY(socket->socketDescriptor() != -1); diff --git a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp index 76d4543da9..4bd330b04f 100644 --- a/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp +++ b/tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp @@ -85,7 +85,8 @@ private slots: void dualStack(); void dualStackAutoBinding(); void dualStackNoIPv4onV6only(); - void readLine(); + void connectToHost(); + void bindAndConnectToHost(); void pendingDatagramSize(); void writeDatagram(); void performance(); @@ -621,7 +622,7 @@ void tst_QUdpSocket::empty_connectedSlot() //---------------------------------------------------------------------------------- -void tst_QUdpSocket::readLine() +void tst_QUdpSocket::connectToHost() { QUdpSocket socket1; QUdpSocket socket2; @@ -629,10 +630,41 @@ void tst_QUdpSocket::readLine() socket1.setProperty("_q_networksession", QVariant::fromValue(networkSession)); socket2.setProperty("_q_networksession", QVariant::fromValue(networkSession)); #endif + + QVERIFY2(socket1.bind(), socket1.errorString().toLatin1().constData()); + + socket2.connectToHost(makeNonAny(socket1.localAddress()), socket1.localPort()); + QVERIFY(socket2.waitForConnected(5000)); +} + +//---------------------------------------------------------------------------------- + +void tst_QUdpSocket::bindAndConnectToHost() +{ + QUdpSocket socket1; + QUdpSocket socket2; + QUdpSocket dummysocket; +#ifdef FORCE_SESSION + socket1.setProperty("_q_networksession", QVariant::fromValue(networkSession)); + socket2.setProperty("_q_networksession", QVariant::fromValue(networkSession)); + dummysocket.setProperty("_q_networksession", QVariant::fromValue(networkSession)); +#endif + + // we use the dummy socket to use up a file descriptor + dummysocket.bind(); + + QVERIFY2(socket2.bind(), socket2.errorString().toLatin1()); + quint16 boundPort = socket2.localPort(); + qintptr fd = socket2.socketDescriptor(); + QVERIFY2(socket1.bind(), socket1.errorString().toLatin1().constData()); + dummysocket.close(); socket2.connectToHost(makeNonAny(socket1.localAddress()), socket1.localPort()); QVERIFY(socket2.waitForConnected(5000)); + + QCOMPARE(socket2.localPort(), boundPort); + QCOMPARE(socket2.socketDescriptor(), fd); } //---------------------------------------------------------------------------------- diff --git a/tests/manual/dialogs/printdialogpanel.cpp b/tests/manual/dialogs/printdialogpanel.cpp index d7291b016d..202a291e5f 100644 --- a/tests/manual/dialogs/printdialogpanel.cpp +++ b/tests/manual/dialogs/printdialogpanel.cpp @@ -50,6 +50,7 @@ #include <QGridLayout> #include <QFormLayout> #include <QVBoxLayout> +#include <QMessageBox> #include <QDoubleSpinBox> #include <QPainter> #include <QFont> @@ -258,9 +259,27 @@ static void drawVertCmRuler(QPainter &painter, int x, int y1, int y2) } } -static void print(QPrinter *printer) +static bool print(QPrinter *printer, QString *errorMessage) { - QPainter painter(printer); + QPainter painter; + + if (!printer->isValid()) { + *errorMessage = QLatin1String("Invalid printer."); + return false; + } + + if (printer->printerState() != QPrinter::Idle) { + *errorMessage = QLatin1String("Printer not idle (state ") + + QString::number(printer->printerState()) + + QLatin1String(")."); + return false; + } + + if (!painter.begin(printer)) { + *errorMessage = QLatin1String("QPainter::begin() failed."); + return false; + } + const QRectF pageF = printer->pageRect(); QFont font = painter.font(); @@ -280,8 +299,8 @@ static void print(QPrinter *printer) << *printer; if (!painter.device()->logicalDpiY() || !painter.device()->logicalDpiX()) { - qWarning() << Q_FUNC_INFO << "Bailing out due to invalid DPI: " << msg; - return; + *errorMessage = QLatin1String("Bailing out due to invalid DPI."); + return false; } painter.drawRect(pageF); @@ -296,7 +315,21 @@ static void print(QPrinter *printer) textPoint.ry() += (15 * charHeight) / 10; } - painter.end(); + if (!painter.end()) { + *errorMessage = QLatin1String("QPainter::end() failed."); + return false; + } + + return true; +} + +static bool print(QPrinter *printer, QWidget *dialogParent) +{ + QString errorMessage; + const bool result = print(printer, &errorMessage); + if (!result) + QMessageBox::warning(dialogParent, QLatin1String("Printing Failed"), errorMessage); + return result; } class PrintPreviewDialog : public QPrintPreviewDialog { @@ -308,7 +341,7 @@ public: } public slots: - void slotPaintRequested(QPrinter *p) { print(p); } + void slotPaintRequested(QPrinter *p) { print(p, this); } }; PrintDialogPanel::PrintDialogPanel(QWidget *parent) @@ -669,7 +702,7 @@ void PrintDialogPanel::showPrintDialog() dialog.setOptions(m_panel.m_dialogOptionsGroupBox->value<QPrintDialog::PrintDialogOptions>()); if (dialog.exec() == QDialog::Accepted) { retrieveSettings(m_printer.data()); - print(m_printer.data()); + print(m_printer.data(), this); } } @@ -693,7 +726,7 @@ void PrintDialogPanel::showPageSetupDialog() void PrintDialogPanel::directPrint() { applySettings(m_printer.data()); - print(m_printer.data()); + print(m_printer.data(), this); retrieveSettings(m_printer.data()); } diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 4c8adfaf30..ed4eb7e09a 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3626,6 +3626,16 @@ void Configure::generateConfigfiles() } +QString Configure::formatConfigPath(const char *var) +{ + QString val = dictionary[var]; + if (QFileInfo(val).isRelative()) { + QString pfx = dictionary["QT_INSTALL_PREFIX"]; + val = (val == ".") ? pfx : QDir(pfx).absoluteFilePath(val); + } + return QDir::toNativeSeparators(val); +} + void Configure::displayConfig() { fstream sout; @@ -3767,19 +3777,19 @@ void Configure::displayConfig() sout << "Sources are in.............." << QDir::toNativeSeparators(sourcePath) << endl; sout << "Build is done in............" << QDir::toNativeSeparators(buildPath) << endl; sout << "Install prefix.............." << QDir::toNativeSeparators(dictionary["QT_INSTALL_PREFIX"]) << endl; - sout << "Headers installed to........" << QDir::toNativeSeparators(dictionary["QT_INSTALL_HEADERS"]) << endl; - sout << "Libraries installed to......" << QDir::toNativeSeparators(dictionary["QT_INSTALL_LIBS"]) << endl; - sout << "Arch-dep. data to..........." << QDir::toNativeSeparators(dictionary["QT_INSTALL_ARCHDATA"]) << endl; - sout << "Plugins installed to........" << QDir::toNativeSeparators(dictionary["QT_INSTALL_PLUGINS"]) << endl; - sout << "Library execs installed to.." << QDir::toNativeSeparators(dictionary["QT_INSTALL_LIBEXECS"]) << endl; - sout << "QML1 imports installed to..." << QDir::toNativeSeparators(dictionary["QT_INSTALL_IMPORTS"]) << endl; - sout << "QML2 imports installed to..." << QDir::toNativeSeparators(dictionary["QT_INSTALL_QML"]) << endl; - sout << "Binaries installed to......." << QDir::toNativeSeparators(dictionary["QT_INSTALL_BINS"]) << endl; - sout << "Arch-indep. data to........." << QDir::toNativeSeparators(dictionary["QT_INSTALL_DATA"]) << endl; - sout << "Docs installed to..........." << QDir::toNativeSeparators(dictionary["QT_INSTALL_DOCS"]) << endl; - sout << "Translations installed to..." << QDir::toNativeSeparators(dictionary["QT_INSTALL_TRANSLATIONS"]) << endl; - sout << "Examples installed to......." << QDir::toNativeSeparators(dictionary["QT_INSTALL_EXAMPLES"]) << endl; - sout << "Tests installed to.........." << QDir::toNativeSeparators(dictionary["QT_INSTALL_TESTS"]) << endl; + sout << "Headers installed to........" << formatConfigPath("QT_REL_INSTALL_HEADERS") << endl; + sout << "Libraries installed to......" << formatConfigPath("QT_REL_INSTALL_LIBS") << endl; + sout << "Arch-dep. data to..........." << formatConfigPath("QT_REL_INSTALL_ARCHDATA") << endl; + sout << "Plugins installed to........" << formatConfigPath("QT_REL_INSTALL_PLUGINS") << endl; + sout << "Library execs installed to.." << formatConfigPath("QT_REL_INSTALL_LIBEXECS") << endl; + sout << "QML1 imports installed to..." << formatConfigPath("QT_REL_INSTALL_IMPORTS") << endl; + sout << "QML2 imports installed to..." << formatConfigPath("QT_REL_INSTALL_QML") << endl; + sout << "Binaries installed to......." << formatConfigPath("QT_REL_INSTALL_BINS") << endl; + sout << "Arch-indep. data to........." << formatConfigPath("QT_REL_INSTALL_DATA") << endl; + sout << "Docs installed to..........." << formatConfigPath("QT_REL_INSTALL_DOCS") << endl; + sout << "Translations installed to..." << formatConfigPath("QT_REL_INSTALL_TRANSLATIONS") << endl; + sout << "Examples installed to......." << formatConfigPath("QT_REL_INSTALL_EXAMPLES") << endl; + sout << "Tests installed to.........." << formatConfigPath("QT_REL_INSTALL_TESTS") << endl; if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith(QLatin1String("wince"))) { sout << "Using c runtime detection..." << dictionary[ "CE_CRT" ] << endl; @@ -4088,7 +4098,7 @@ void Configure::generateQConfigCpp() << ";\n" << endl; if ((platform() != WINDOWS) && (platform() != WINDOWS_CE) && (platform() != WINDOWS_RT)) - tmpStream << "#define QT_CONFIGURE_SETTINGS_PATH \"" << QDir::cleanPath(dictionary["QT_INSTALL_SETTINGS"]) << "\"" << endl; + tmpStream << "#define QT_CONFIGURE_SETTINGS_PATH \"" << dictionary["QT_REL_INSTALL_SETTINGS"] << "\"" << endl; tmpStream << endl << "#ifdef QT_BUILD_QMAKE\n" diff --git a/tools/configure/configureapp.h b/tools/configure/configureapp.h index 78fd956eda..e58a0feb2b 100644 --- a/tools/configure/configureapp.h +++ b/tools/configure/configureapp.h @@ -165,6 +165,8 @@ private: void desc(const char *option, const char *description, bool skipIndent = false, char fillChar = '.'); void desc(const char *mark_option, const char *mark, const char *option, const char *description, char fillChar = '.'); void applySpecSpecifics(); + + QString formatConfigPath(const char *var); }; class FileWriter : public QTextStream |