Merge remote-tracking branch 'origin/5.6' into 5.7

Conflicts:
	.qmake.conf
	config.tests/unix/nis/nis.cpp
	mkspecs/unsupported/freebsd-g++/qplatformdefs.h
	src/corelib/tools/qdatetime.cpp
	src/corelib/tools/qsimd.cpp
	src/corelib/tools/qsimd_p.h
	src/network/access/access.pri
	src/network/access/qnetworkreplynsurlconnectionimpl.mm
	src/network/access/qnetworkreplynsurlconnectionimpl_p.h
	src/plugins/platforms/cocoa/qnsview.mm
	src/plugins/printsupport/windows/qwindowsprintdevice.cpp
	tests/auto/corelib/kernel/qobject/tst_qobject.cpp
	tests/auto/network/access/qnetworkreply/BLACKLIST
	tests/auto/widgets/widgets/qopenglwidget/BLACKLIST

Change-Id: I4b32055bbf922392ef0264fd403405416fffee57
This commit is contained in:
Liang Qi 2016-06-06 08:34:03 +02:00
commit 57057f76ad
137 changed files with 2582 additions and 1355 deletions

View File

@ -6,7 +6,10 @@ for(p, QMAKE_LIBDIR_EGL) {
INCLUDEPATH += $$QMAKE_INCDIR_EGL
LIBS += $$QMAKE_LIBS_EGL
LIBS += -ldrm
CONFIG += link_pkgconfig
!contains(QT_CONFIG, no-pkg-config) {
PKGCONFIG += libdrm
} else {
LIBS += -ldrm
}
CONFIG -= qt

View File

@ -0,0 +1,2 @@
SOURCES = $$PWD/dlopen.cpp
CONFIG -= qt dylib

View File

@ -1,3 +1,3 @@
SOURCES = iconv.cpp
CONFIG -= qt dylib
mac|mingw|qnx|haiku:LIBS += -liconv
mac|mingw|openbsd|qnx|haiku:LIBS += -liconv

View File

@ -1,3 +1,2 @@
SOURCES = libdl.cpp
CONFIG -= qt dylib
!qnx: LIBS += -ldl
include(../dlopen/dlopen.pro)
LIBS += -ldl

View File

@ -41,5 +41,6 @@
int main(int, char **)
{
mysql_get_client_version();
return 0;
}

View File

@ -1,50 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the config.tests of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <sys/types.h>
#include <rpc/rpc.h>
#include <rpcsvc/ypclnt.h>
#include <rpcsvc/yp_prot.h>
int main(int, char **)
{
char *d;
yp_get_default_domain(&d);
return 0;
}

View File

@ -1,4 +0,0 @@
SOURCES = nis.cpp
CONFIG -= qt dylib
solaris-*:LIBS += -lnsl
else:LIBS += $$QMAKE_LIBS_NIS

View File

@ -1,4 +1,7 @@
SOURCES = objcopy.cpp
CONFIG -= qt
TARGET = objcopytest
QMAKE_POST_LINK += $$QMAKE_OBJCOPY --only-keep-debug objcopy objcopy.debug && $$QMAKE_OBJCOPY --strip-debug objcopy && $$QMAKE_OBJCOPY --add-gnu-debuglink=objcopy.debug objcopy
load(resolve_target)
QMAKE_POST_LINK += $$QMAKE_OBJCOPY --only-keep-debug $$QMAKE_RESOLVED_TARGET objcopytest.debug && $$QMAKE_OBJCOPY --strip-debug $$QMAKE_RESOLVED_TARGET && $$QMAKE_OBJCOPY --add-gnu-debuglink=objcopytest.debug $$QMAKE_RESOLVED_TARGET

View File

@ -43,6 +43,12 @@
# error "OpenSSL >= 0.9.7 is required"
#endif
#include <openssl/ssl.h>
#if OPENSSL_VERSION_NUMBER-0 >= 0x10002000L && !defined(OPENSSL_NO_EC) && !defined(SSL_CTRL_SET_CURVES)
# error "OpenSSL was reported as >= 1.0.2 but is missing required features, possibly it's libressl which is unsupported"
#endif
int main()
{
}

57
configure vendored
View File

@ -719,7 +719,6 @@ CFG_LIBINPUT=auto
CFG_OBSOLETE_WAYLAND=no
CFG_EVDEV=auto
CFG_TSLIB=auto
CFG_NIS=auto
CFG_CUPS=auto
CFG_ICONV=auto
CFG_DBUS=auto
@ -2052,13 +2051,6 @@ while [ "$#" -gt 0 ]; do
UNKNOWN_OPT=yes
fi
;;
nis)
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
CFG_NIS="$VAL"
else
UNKNOWN_OPT=yes
fi
;;
largefile)
if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
CFG_LARGEFILE="$VAL"
@ -2655,9 +2647,6 @@ Additional options:
-silent ............ Reduce the build output so that warnings and errors
can be seen more easily.
-no-nis ............ Do not compile NIS support.
* -nis ............... Compile NIS support.
-no-cups ........... Do not compile CUPS support.
* -cups .............. Compile CUPS support.
Requires cups/cups.h and libcups.so.2.
@ -2891,10 +2880,17 @@ if [ -z "$PLATFORM" ]; then
PLATFORM=ultrix-g++
;;
FreeBSD:*)
PLATFORM=freebsd-clang
PLATFORM_NOTES="
- Also available for FreeBSD: freebsd-icc
"
if [ "$(uname -r | cut -d. -f1)" -ge 10 ]; then
PLATFORM=freebsd-clang
PLATFORM_NOTES="
- Also available for FreeBSD: freebsd-g++
"
else
PLATFORM=freebsd-g++
PLATFORM_NOTES="
- Also available for FreeBSD: freebsd-clang
"
fi
;;
OpenBSD:*)
PLATFORM=openbsd-g++
@ -3244,6 +3240,9 @@ if [ "$XPLATFORM_ANDROID" = "yes" ]; then
if [ "$CFG_DBUS" = "auto" ]; then
CFG_DBUS="no"
fi
if [ "$CFG_EGLFS" = "auto" ]; then
CFG_EGLFS="no"
fi
if [ -z "$CFG_DEFAULT_ANDROID_NDK_HOST" ]; then
case $PLATFORM in
linux-*)
@ -4829,9 +4828,13 @@ if [ "$CFG_LIBPNG" = "auto" ]; then
fi
# detect dl
if ! compileTest unix/libdl "libdl"; then
QMakeVar add DEFINES QT_NO_DYNAMIC_LIBRARY
if compileTest unix/dlopen "dlopen"; then
QMAKE_CONFIG="$QMAKE_CONFIG no-libdl"
else
if ! compileTest unix/libdl "libdl"; then
QMAKE_CONFIG="$QMAKE_CONFIG no-libdl"
QMakeVar add DEFINES QT_NO_DYNAMIC_LIBRARY
fi
fi
if [ "$CFG_EGLFS" = "yes" ]; then
@ -5097,23 +5100,6 @@ for _SQLDR in $CFG_SQL_AVAILABLE; do
esac
done
# auto-detect NIS support
if [ "$CFG_NIS" != "no" ]; then
if compileTest unix/nis "NIS"; then
CFG_NIS=yes
else
if [ "$CFG_NIS" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then
echo "NIS support cannot be enabled due to functionality tests!"
echo " Turn on verbose messaging (-v) to $0 to see the final report."
echo " If you believe this message is in error you may use the continue"
echo " switch (-continue) to $0 to continue."
exit 101
else
CFG_NIS=no
fi
fi
fi
# auto-detect CUPS support
if [ "$CFG_CUPS" != "no" ]; then
if compileTest unix/cups "Cups"; then
@ -6585,7 +6571,6 @@ elif [ "$CFG_ZLIB" = "system" ]; then
fi
[ "$CFG_MTDEV" = "yes" ] && QT_CONFIG="$QT_CONFIG mtdev"
[ "$CFG_NIS" = "yes" ] && QT_CONFIG="$QT_CONFIG nis"
[ "$CFG_CUPS" = "yes" ] && QT_CONFIG="$QT_CONFIG cups"
[ "$CFG_ICONV" = "yes" ] && QT_CONFIG="$QT_CONFIG iconv"
[ "$CFG_ICONV" = "sun" ] && QT_CONFIG="$QT_CONFIG sun-libiconv"
@ -7013,7 +6998,6 @@ QMakeVar set sql-plugins "$SQL_PLUGINS"
[ "$CFG_INOTIFY" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_INOTIFY"
[ "$CFG_EVENTFD" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_EVENTFD"
[ "$CFG_CLOEXEC" = "yes" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_THREADSAFE_CLOEXEC=1"
[ "$CFG_NIS" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_NIS"
[ "$CFG_OPENSSL" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_OPENSSL"
[ "$CFG_OPENSSL" = "linked" ]&& QCONFIG_FLAGS="$QCONFIG_FLAGS QT_LINKED_OPENSSL"
[ "$CFG_OPENSSL" = "no" ] && [ "$CFG_SECURETRANSPORT" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_SSL"
@ -7480,7 +7464,6 @@ report_support " libproxy.............." "$CFG_LIBPROXY"
report_support " OpenSSL .............." "$CFG_OPENSSL" yes "loading libraries at run-time" linked "linked to the libraries"
[ "$XPLATFORM_MAC" = "yes" ] && \
report_support " SecureTransport ......" "$CFG_SECURETRANSPORT"
report_support " NIS ...................." "$CFG_NIS"
report_support " OpenGL / OpenVG:"
report_support " EGL .................." "$CFG_EGL"
report_support " OpenGL ..............." "$CFG_OPENGL" yes "Desktop OpenGL" es2 "OpenGL ES 2.0+"

165
dist/changes-5.6.1 vendored Normal file
View File

@ -0,0 +1,165 @@
Qt 5.6.1 is a bug-fix release. It maintains both forward and backward
compatibility (source and binary) with Qt 5.6.0.
For more details, refer to the online documentation included in this
distribution. The documentation is also available online:
https://doc.qt.io/qt-5/
The Qt version 5.6 series is binary compatible with the 5.5.x series.
Applications compiled for 5.5 will continue to run with 5.6.
Some of the changes listed in this file include issue tracking numbers
corresponding to tasks in the Qt Bug Tracker:
https://bugreports.qt.io/
Each of these identifiers can be entered in the bug tracker to obtain more
information about a particular change.
****************************************************************************
* Important Behavior Changes *
****************************************************************************
- Support for DirectFB is disabled by default, due to lack of
development in upstream. To enable the platform plugin, pass the
-directfb option to configure.
- [QTBUG-44964] The new X event compression feature that was added in 5.6.0
no longer applies to motion events from drawing tablets.
configure & build system
------------------------
- The configure -D/-I/-L/-l/-R options do not affect the build of Qt's
host tools any more when cross-building. While this usually improves
the chances of a build succeeding, it may also require adjustments.
qmake
-----
- [Unix] Paths passed to configure -R are not automatically used by 3rd
party projects any more. Use QMAKE_RPATHDIR if your project explicitly
depends on external libraries. Note that this is not needed for Qt or
its transitive dependencies.
- Expansions of ${QMAKE_FILE_IN_BASE} and ${QMAKE_FILE_OUT_BASE} in extra
compilers are now automatically quoted.
****************************************************************************
* Library *
****************************************************************************
QtCore
------
- QObject:
* [QTBUG-52542] If the compiler supports variadic templates, functors
connected to signals will no longer be copied each time the signal is
emitted.
- QRect:
* Fixed integer overflow in center(). This fixes the result for some
corner-cases such as a 1x1 rectangle at (INT_MIN, INT_MIN), for which the
previous implementation could return anything (due to invoking undefined
behavior), but commonly returned (0, 0).
- QStringRef:
* Fixed relational operators against (const char*) to return the correct
result.
QtGui
-----
- [QTBUG-50199] QWheelEvent::phase() now returns zero rather than
Qt::ScrollUpdate when the wheel event comes from an actual non-emulated
mouse wheel, and the QT_ENABLE_MOUSE_WHEEL_TRACKING environment variable
is set.
- Image:
* [QTBUG-50745] Fixed possible crash in QImage::pixel() for mono or indexed
images.
QtWidgets
---------
- Dialogs:
* [QTBUG-51148] Fixed font dialog support for fonts with a non-existent
family name and/or pixel size.
- QHeaderView:
* [QTBUG-50171] Fixed a repainting issue when items had been reordered.
- QListWidget:
* [QTBUG-15741] Fixed a bug that caused the default drop action to be
ignored when using icon mode.
****************************************************************************
* Platform-specific Changes *
****************************************************************************
Android
-------
- The navigation bar is now hidden only on Android API level 19 and above.
OS X
----
- [QTBUG-50262] QStandardPaths now returns the correct display name for the
download folder.
- [QTBUG-7000] QMacPrintEngine now really sets the printer resolution.
- [QTBUG-48138] QPinchGesture on OS X now behaves like on other platforms:
totalScaleFactor is the magnitude of the pinch and scaleFactor is the delta
for the current event.
Windows
-------
- Text:
* [QTBUG-18711] Fixed disabling hints for application fonts.
For example, when automatic scaling by device pixel ratio is in effect.
* [QTBUG-47141] Made it possible to disable antialiasing for text when
drawing into images.
X11/XCB
-------
- [QTBUG-49071] Fixed failure to deliver focusIn events on hide/show.
****************************************************************************
* Tools *
****************************************************************************
configure & build system
------------------------
- [QTBUG-11545][Windows] Added missing -pch/-no-pch options to configure.exe.
- [QTBUG-37952][Apple] configure -separate-debug-info is now supported.
- [QTBUG-47313][QTBUG-47639] Fixed builds with "debug" and/or "release" in
the build path's name.
- [QTBUG-51621][Unix] Fixed transitive dependencies on non-Qt libraries.
- [QTBUG-51644][QTBUG-53017] Fixed cross-builds which use a host compiler
which is significantly different from the target compiler.
- [QTBUG-52578][QNX] Unified some defaults between the Unix and Windows
configures.
- [Unix] configure -R now supports paths relative to -libdir.
- [Android@Windows] Added missing -android-ndk-host option to configure.exe.
- [MinGW] Fixed -release -force-debug-info builds actually being neither.
- [WinCE] Fixed (Open)SSL detection.
- Fixed builds with static libc.
qmake
-----
- [QTBUG-34182] Fixed UTF-8 BOM breaking dependency calculation.
- [QTBUG-38802][WinRT] Capabilities needed by Qt are now automatically
added to the manifest.
- [QTBUG-50924][WEC7][VS] Fixed deployment of Qt.
- [QTBUG-51775][Unix@Windows] Fixed installation of target.targets when
cross-building.
- [QTBUG-51782] Fixed simultaneous use of the separate_debug_info and
no_plugin_name_prefix CONFIG flags.
- [QTBUG-52008] qmake-generated Visual Studio projects now automatically
invoke windeployqt by default.
- [QTBUG-52998] Restored use of -P option when invoking lex.
- The expansions ${QMAKE_FILE_IN_EXT}, ${QMAKE_FILE_IN_NAME}, and
${QMAKE_FILE_OUT_PATH} are now understood in extra compilers.

View File

@ -56,9 +56,9 @@
#include "ui_authenticationdialog.h"
#ifndef QT_NO_SSL
static const char defaultUrl[] = "https://qt-project.org/";
static const char defaultUrl[] = "https://www.qt.io/";
#else
static const char defaultUrl[] = "http://qt-project.org/";
static const char defaultUrl[] = "http://www.qt.io/";
#endif
static const char defaultFileName[] = "index.html";
@ -106,7 +106,7 @@ HttpWindow::HttpWindow(QWidget *parent)
connect(urlLineEdit, &QLineEdit::textChanged,
this, &HttpWindow::enableDownloadButton);
formLayout->addRow(tr("&URL:"), urlLineEdit);
QString downloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
QString downloadDirectory = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
if (downloadDirectory.isEmpty() || !QFileInfo(downloadDirectory).isDir())
downloadDirectory = QDir::currentPath();
downloadDirectoryLineEdit->setText(QDir::toNativeSeparators(downloadDirectory));

View File

@ -54,7 +54,8 @@
#include <QObject>
#include <QColor>
class QOpenGLFunctions_1_1;
QT_FORWARD_DECLARE_CLASS(QOpenGLFunctions_1_1)
class Patch;
struct Geometry;

View File

@ -5,3 +5,6 @@ LIBS += -framework AppKit
QT += widgets
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/mac/qmaccocoaviewcontainer
INSTALLS += target

View File

@ -5,3 +5,7 @@ LIBS += -framework AppKit
QT += widgets
#QT += widgets-private gui-private core-private
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/mac/qmacnativewidget
INSTALLS += target

View File

@ -168,13 +168,6 @@ QMAKE_STRIP =
QMAKE_RANLIB = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ranlib
QMAKE_INCDIR = $$ANDROID_SOURCES_CXX_STL_INCDIR $$QMAKE_ANDROID_PLATFORM_INCDIR
QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$QMAKE_ANDROID_PLATFORM_LIBDIR $$LIBGCC_PATH
QMAKE_INCDIR_X11 =
QMAKE_LIBDIR_X11 =
QMAKE_INCDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_INCDIR
QMAKE_LIBDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_LIBDIR
equals(ANDROID_TARGET_ARCH, armeabi)|equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
LIBGCC_PATH_FULL = $$system("$$QMAKE_CC -mthumb-interwork -print-libgcc-file-name")
else: \
@ -182,20 +175,19 @@ else: \
LIBGCC_PATH = $$dirname(LIBGCC_PATH_FULL)
QMAKE_INCDIR = $$ANDROID_SOURCES_CXX_STL_INCDIR $$QMAKE_ANDROID_PLATFORM_INCDIR
QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$QMAKE_ANDROID_PLATFORM_LIBDIR $$LIBGCC_PATH
QMAKE_INCDIR_X11 =
QMAKE_LIBDIR_X11 =
QMAKE_INCDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_INCDIR
QMAKE_LIBDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_LIBDIR
QMAKE_LINK = $$QMAKE_CXX
QMAKE_LINK_SHLIB = $$QMAKE_CXX
QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
QMAKE_RPATHLINK = $$QMAKE_ANDROID_PLATFORM_LIBDIR
QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared
QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared
contains(NDK_ROOT, ".*r6")|contains(NDK_ROOT, ".*r5.*") {
!equals(ANDROID_PLATFORM, android-4):!equals(ANDROID_PLATFORM, android-5):!equals(ANDROID_PLATFORM, android-8) {
warning("Your NDK version is outdated. A workaround is enabled. Consider updating your NDK (workarounds are required until r6(a))")
QMAKE_LFLAGS_SHLIB += $$QMAKE_ANDROID_PLATFORM_LIBDIR/crtbegin_so.o $$QMAKE_ANDROID_PLATFORM_LIBDIR/crtend_so.o
}
}
QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined
QMAKE_LFLAGS_RPATH = -Wl,-rpath=

View File

@ -1,3 +1,3 @@
contains(QT_CONFIG, system-freetype) {
LIBS += -lfreetype
LIBS_PRIVATE += -lfreetype
}

View File

@ -1,7 +1,7 @@
CONFIG += qpa/basicunixfontdatabase
contains(QT_CONFIG, fontconfig) {
DEFINES += Q_FONTCONFIGDATABASE
LIBS += -lfontconfig
LIBS_PRIVATE += -lfontconfig
} else:!android {
fonts.path = $$[QT_INSTALL_LIBS]/fonts
fonts.files = $$QT_SOURCE_TREE/lib/fonts/*

View File

@ -0,0 +1,18 @@
have_target:!static:!isEmpty(QMAKE_OBJCOPY) {
load(resolve_target)
QMAKE_TARGET_DEBUG_INFO = $${QMAKE_RESOLVED_TARGET}.debug
shell_target = $$shell_quote($$relative_path($$QMAKE_RESOLVED_TARGET, $$OUT_PWD))
shell_target_debug_info = $$shell_quote($$relative_path($$QMAKE_TARGET_DEBUG_INFO, $$OUT_PWD))
copy_debug_info = $$QMAKE_OBJCOPY --only-keep-debug $$shell_target $$shell_target_debug_info
link_debug_info = $$QMAKE_OBJCOPY --add-gnu-debuglink=$$shell_target_debug_info $$shell_target
strip_debug_info = $$QMAKE_OBJCOPY --strip-debug $$shell_target
!isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$escape_expand(\\n\\t)$$QMAKE_POST_LINK
QMAKE_POST_LINK = $$copy_debug_info && $$strip_debug_info && $$link_debug_info $$QMAKE_POST_LINK
silent:QMAKE_POST_LINK = @echo creating $@.debug && $$QMAKE_POST_LINK
target.targets += $$QMAKE_TARGET_DEBUG_INFO
QMAKE_DISTCLEAN += $$QMAKE_TARGET_DEBUG_INFO
}

View File

@ -5,7 +5,7 @@
MAKEFILE_GENERATOR = UNIX
QMAKE_PLATFORM = freebsd bsd
include(../../common/unix.conf)
include(../common/unix.conf)
QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE
@ -29,6 +29,6 @@ QMAKE_OBJCOPY = objcopy
QMAKE_NM = nm -P
QMAKE_RANLIB =
include(../../common/gcc-base-unix.conf)
include(../../common/g++-unix.conf)
include(../common/gcc-base-unix.conf)
include(../common/g++-unix.conf)
load(qt_config)

View File

@ -37,4 +37,4 @@
**
****************************************************************************/
#include "../freebsd-g++/qplatformdefs.h"
#include "../freebsd-clang/qplatformdefs.h"

View File

@ -1,95 +0,0 @@
#
# qmake configuration for freebsd-icc
#
# Written for Intel C++ 7.1 and 8.0 on FreeBSD
#
# Note: Some of the remarks from the Intel compiler are disabled (even
# with 'warn_on' specified):
#
# remark #171: invalid type conversion: "int" to "void *"
# remark #193: zero used for undefined preprocessing identifier
# remark #279: controlling expression is constant
# remark #304: access control not specified ("public" by default)
# remark #310: old-style parameter list (anachronism)
# remark #383: value copied to temporary, reference to temporary used
# remark #424: extra ";" ignored
# remark #444: destructor for base class "Class" is not virtual
# remark #488: template parameter "T" is not used in declaring the parameter
# types of function template "function"
# remark #810: conversion from "type1" to "type2" may loose significant bits
# remark #858: type qualifier on return type is meaningless
# remark #967: conversion from "type1" to "type2"; sizes do not match
# remark #981: operands are evaluated in unspecified order
# remark #1418: external definition with no prior declaration
# remark #1419: external declaration in primary source file
# warning #1476: field uses tail padding of a base class
# warning #1477: GNU C++ compilers may use bit field padding
# warning #1572: floating-point equality and inequality comparisons are unreliable
#
MAKEFILE_GENERATOR = UNIX
QMAKE_PLATFORM = freebsd bsd
include(../common/unix.conf)
QMAKE_COMPILER = gcc intel_icc # icc pretends to be gcc
QMAKE_CC = icc
QMAKE_LEX = flex
QMAKE_LEXFLAGS =
QMAKE_YACC = yacc
QMAKE_YACCFLAGS = -d
QMAKE_CFLAGS = -wd858,1572
QMAKE_CFLAGS_DEPS = -M
QMAKE_CFLAGS_WARN_ON = -w2 -wd171,193,279,304,310,383,424,444,488,810,967,981,1418,1419,1476,1477
QMAKE_CFLAGS_WARN_OFF = -w
QMAKE_CFLAGS_RELEASE =
QMAKE_CFLAGS_DEBUG = -g
QMAKE_CFLAGS_SHLIB = -fpic
QMAKE_CFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CFLAGS_YACC =
QMAKE_CFLAGS_THREAD = -D_THREAD_SAFE
QMAKE_CXX = icpc
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
# Addon software goes into /usr/local on the BSDs, by default we will look there
QMAKE_INCDIR = /usr/local/include
QMAKE_LIBDIR = /usr/local/lib
QMAKE_INCDIR_X11 = /usr/X11R6/include
QMAKE_LIBDIR_X11 = /usr/X11R6/lib
QMAKE_INCDIR_OPENGL = /usr/X11R6/include
QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib
QMAKE_LINK = icpc
QMAKE_LINK_SHLIB = icpc
QMAKE_LFLAGS =
QMAKE_LFLAGS_RELEASE =
QMAKE_LFLAGS_DEBUG =
QMAKE_LFLAGS_SHLIB = -shared
QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
QMAKE_LFLAGS_SONAME = -Qoption,ld,-soname,
QMAKE_LFLAGS_THREAD = -mt
QMAKE_LFLAGS_RPATH = -Qoption,ld,-rpath,
QMAKE_LIBS =
QMAKE_LIBS_DYNLOAD =
QMAKE_LIBS_X11 = -lXext -lX11 -lm
QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_THREAD =
QMAKE_AR = ar cqs
QMAKE_OBJCOPY = objcopy
QMAKE_NM = nm -P
QMAKE_RANLIB =
load(qt_config)

View File

@ -61,6 +61,7 @@ QMAKE_LFLAGS_RPATH = -Wl,-rpath,
QMAKE_LIBS =
QMAKE_LIBS_DYNLOAD =
QMAKE_LIBS_EXECINFO = -lexecinfo
QMAKE_LIBS_X11 = -lXext -lX11 -lm
QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_THREAD =

View File

@ -62,6 +62,7 @@ QMAKE_LFLAGS_NOUNDEF = -Wl,-no_unresolved
QMAKE_LIBS =
QMAKE_LIBS_DYNLOAD =
QMAKE_LIBS_EXECINFO = -lexecinfo
QMAKE_LIBS_X11 = -lXext -lX11 -lm
QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_THREAD =

View File

@ -1,40 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the qmake spec of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "../../freebsd-clang/qplatformdefs.h"

View File

@ -1616,6 +1616,13 @@
\note Platform-specific variables that change the extension override
the contents of this variable.
\target QMAKE_EXTENSION_STATICLIB
\section1 QMAKE_EXTENSION_STATICLIB
Contains the extension for shared static libraries. The value of
this variable is typically handled by qmake or
\l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified.
\section1 QMAKE_EXT_MOC
Contains the extension used on included moc files.

View File

@ -30,6 +30,9 @@
#include "forkfd.h"
#include <sys/types.h>
#if defined(__OpenBSD__) || defined(__NetBSD__)
# include <sys/param.h>
#endif
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
@ -65,7 +68,9 @@
# undef HAVE_WAITID
#endif
#if defined(__FreeBSD__) && defined(__FreeBSD_version) && __FreeBSD_version >= 1000032
#if (defined(__FreeBSD__) && defined(__FreeBSD_version) && __FreeBSD_version >= 1000032) || \
(defined(__OpenBSD__) && OpenBSD >= 201505) || \
(defined(__NetBSD__) && __NetBSD_Version__ >= 600000000)
# define HAVE_PIPE2 1
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) || \
@ -410,6 +415,26 @@ chain_handler:
old_sigaction.sa_handler(signum);
}
static void ignore_sigpipe()
{
#ifdef O_NOSIGPIPE
static ffd_atomic_int done = FFD_ATOMIC_INIT(0);
if (ffd_atomic_load(&done, FFD_ATOMIC_RELAXED))
return;
#endif
struct sigaction action;
memset(&action, 0, sizeof action);
sigemptyset(&action.sa_mask);
action.sa_handler = SIG_IGN;
action.sa_flags = 0;
sigaction(SIGPIPE, &action, NULL);
#ifdef O_NOSIGPIPE
ffd_atomic_store(&done, 1, FFD_ATOMIC_RELAXED);
#endif
}
static void forkfd_initialize()
{
#if defined(HAVE_BROKEN_WAITID)
@ -446,6 +471,11 @@ static void forkfd_initialize()
*/
sigaction(SIGCHLD, &action, &old_sigaction);
#ifndef O_NOSIGPIPE
/* disable SIGPIPE too */
ignore_sigpipe();
#endif
#ifndef __GNUC__
atexit(cleanup);
#endif
@ -486,13 +516,23 @@ static void cleanup()
static int create_pipe(int filedes[], int flags)
{
int ret;
int ret = -1;
#ifdef HAVE_PIPE2
/* use pipe2(2) whenever possible, since it can thread-safely create a
* cloexec pair of pipes. Without it, we have a race condition setting
* FD_CLOEXEC
*/
ret = pipe2(filedes, O_CLOEXEC);
# ifdef O_NOSIGPIPE
/* try first with O_NOSIGPIPE */
ret = pipe2(filedes, O_CLOEXEC | O_NOSIGPIPE);
if (ret == -1) {
/* O_NOSIGPIPE not supported, ignore SIGPIPE */
ignore_sigpipe();
}
# endif
if (ret == -1)
ret = pipe2(filedes, O_CLOEXEC);
if (ret == -1)
return ret;

View File

@ -28,8 +28,9 @@ SOURCES += \
global/qmalloc.cpp \
global/qnumeric.cpp \
global/qlogging.cpp \
global/qhooks.cpp \
global/qversiontagging.cpp
global/qhooks.cpp
VERSIONTAGGING_SOURCES = global/qversiontagging.cpp
# qlibraryinfo.cpp includes qconfig.cpp
INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global
@ -63,3 +64,21 @@ journald {
syslog {
DEFINES += QT_USE_SYSLOG
}
gcc:ltcg {
versiontagging_compiler.commands = $$QMAKE_CXX -c $(CXXFLAGS) $(INCPATH)
# Disable LTO, as the symbols disappear somehow under GCC
versiontagging_compiler.commands += -fno-lto
versiontagging_compiler.commands += -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
versiontagging_compiler.dependency_type = TYPE_C
versiontagging_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)}
versiontagging_compiler.input = VERSIONTAGGING_SOURCES
versiontagging_compiler.variable_out = OBJECTS
versiontagging_compiler.name = compiling[versiontagging] ${QMAKE_FILE_IN}
silent: versiontagging_compiler.commands = @echo compiling[versiontagging] ${QMAKE_FILE_IN} && $$versiontagging_compiler.commands
QMAKE_EXTRA_COMPILERS += versiontagging_compiler
} else {
SOURCES += $$VERSIONTAGGING_SOURCES
}

View File

@ -756,7 +756,9 @@
# define Q_COMPILER_TEMPLATE_ALIAS
# endif
# if __has_feature(cxx_thread_local)
# define Q_COMPILER_THREAD_LOCAL
# if !defined(__FreeBSD__) /* FreeBSD clang fails on __cxa_thread_atexit */
# define Q_COMPILER_THREAD_LOCAL
# endif
# endif
# if __has_feature(cxx_user_literals)
# define Q_COMPILER_UDL
@ -1114,7 +1116,8 @@
# define Q_DECL_NOTHROW Q_DECL_NOEXCEPT
#endif
#if defined(Q_COMPILER_ALIGNOF) && !defined(Q_ALIGNOF)
#if defined(Q_COMPILER_ALIGNOF)
# undef Q_ALIGNOF
# define Q_ALIGNOF(x) alignof(x)
#endif

View File

@ -49,6 +49,11 @@
QT_BEGIN_NAMESPACE
#ifdef __has_builtin
# define QT_HAS_BUILTIN(x) __has_builtin(x)
#else
# define QT_HAS_BUILTIN(x) 0
#endif
/*
* ENDIAN FUNCTIONS
@ -71,18 +76,29 @@ template <typename T> inline void qbswap(const T src, uchar *dest)
// Used to implement a type-safe and alignment-safe copy operation
// If you want to avoid the memcpy, you must write specializations for these functions
template <typename T> inline void qToUnaligned(const T src, uchar *dest)
template <typename T> Q_ALWAYS_INLINE void qToUnaligned(const T src, uchar *dest)
{
// Using sizeof(T) inside memcpy function produces internal compiler error with
// MSVC2008/ARM in tst_endian -> use extra indirection to resolve size of T.
const size_t size = sizeof(T);
memcpy(dest, &src, size);
#if QT_HAS_BUILTIN(__builtin_memcpy)
__builtin_memcpy
#else
memcpy
#endif
(dest, &src, size);
}
template <typename T> inline T qFromUnaligned(const uchar *src)
template <typename T> Q_ALWAYS_INLINE T qFromUnaligned(const uchar *src)
{
T dest;
const size_t size = sizeof(T);
memcpy(&dest, src, size);
#if QT_HAS_BUILTIN(__builtin_memcpy)
__builtin_memcpy
#else
memcpy
#endif
(&dest, src, size);
return dest;
}

View File

@ -33,6 +33,29 @@
little and big endian representations of numbers.
*/
/*!
\internal
\fn T qFromUnaligned(const uchar *ptr)
\since 5.5
Loads a \c{T} from address \a ptr, which may be misaligned.
Use of this function avoids the undefined behavior that the C++ standard
otherwise attributes to unaligned loads.
*/
/*!
\internal
\fn void qToUnaligned(T t, uchar *ptr)
\since 4.5
Stores \a t to address \a ptr, which may be misaligned.
Use of this function avoids the undefined behavior that the C++ standard
otherwise attributes to unaligned stores.
*/
/*!
\fn T qFromBigEndian(const uchar *src)
\since 4.3

View File

@ -67,6 +67,7 @@
NETBSD - NetBSD
OPENBSD - OpenBSD
BSDI - BSD/OS
INTERIX - Interix
IRIX - SGI Irix
OSF - HP Tru64 UNIX
SCO - SCO OpenServer 5
@ -172,6 +173,9 @@
#elif defined(__bsdi__)
# define Q_OS_BSDI
# define Q_OS_BSD4
#elif defined(__INTERIX)
# define Q_OS_INTERIX
# define Q_OS_BSD4
#elif defined(__sgi)
# define Q_OS_IRIX
#elif defined(__osf__)

View File

@ -149,7 +149,6 @@ win32 {
SOURCES += io/qsettings_mac.cpp
OBJECTIVE_SOURCES += io/qurl_mac.mm
}
freebsd: LIBS_PRIVATE += -lutil # qlockfile_unix.cpp requires this
mac {
SOURCES += io/qstorageinfo_mac.cpp
OBJECTIVE_SOURCES += io/qstandardpaths_mac.mm

View File

@ -58,7 +58,7 @@
# include "qfilesystemwatcher_win_p.h"
#elif defined(USE_INOTIFY)
# include "qfilesystemwatcher_inotify_p.h"
#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_IOS)
#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_OPENBSD) || defined(Q_OS_IOS)
# include "qfilesystemwatcher_kqueue_p.h"
#elif defined(Q_OS_OSX)
# include "qfilesystemwatcher_fsevents_p.h"
@ -74,7 +74,7 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject
// there is a chance that inotify may fail on Linux pre-2.6.13 (August
// 2005), so we can't just new inotify directly.
return QInotifyFileSystemWatcherEngine::create(parent);
#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_IOS)
#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_OPENBSD) || defined(Q_OS_IOS)
return QKqueueFileSystemWatcherEngine::create(parent);
#elif defined(Q_OS_OSX)
return QFseventsFileSystemWatcherEngine::create(parent);

View File

@ -172,7 +172,6 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths
QStringList *files,
QStringList *directories)
{
bool isEmpty;
QStringList p = paths;
if (pathToID.isEmpty())
return p;
@ -193,7 +192,6 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths
else
files->removeAll(path);
}
isEmpty = pathToID.isEmpty();
return p;
}

View File

@ -71,14 +71,12 @@
#elif defined(Q_OS_HAIKU)
# include <kernel/OS.h>
#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS)
# if !defined(Q_OS_NETBSD)
# include <sys/user.h>
# if defined(__GLIBC__) && defined(__FreeBSD_kernel__)
# endif
# include <sys/cdefs.h>
# include <sys/param.h>
# include <sys/sysctl.h>
# else
# include <libutil.h>
# endif
#endif
QT_BEGIN_NAMESPACE
@ -286,30 +284,33 @@ QString QLockFilePrivate::processNameByPid(qint64 pid)
return QString();
return QFile::decodeName(info.name);
#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS)
# if defined(__GLIBC__) && defined(__FreeBSD_kernel__)
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
size_t len = 0;
if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0)
return QString();
kinfo_proc *proc = static_cast<kinfo_proc *>(malloc(len));
# if defined(Q_OS_NETBSD)
struct kinfo_proc2 kp;
int mib[6] = { CTL_KERN, KERN_PROC2, KERN_PROC_PID, (int)pid, sizeof(struct kinfo_proc2), 1 };
# elif defined(Q_OS_OPENBSD)
struct kinfo_proc kp;
int mib[6] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid, sizeof(struct kinfo_proc), 1 };
# else
kinfo_proc *proc = kinfo_getproc(pid);
struct kinfo_proc kp;
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid };
# endif
if (!proc)
size_t len = sizeof(kp);
u_int mib_len = sizeof(mib)/sizeof(u_int);
if (sysctl(mib, mib_len, &kp, &len, NULL, 0) < 0)
return QString();
# if defined(__GLIBC__) && defined(__FreeBSD_kernel__)
if (sysctl(mib, 4, proc, &len, NULL, 0) < 0) {
free(proc);
# if defined(Q_OS_OPENBSD) || defined(Q_OS_NETBSD)
if (kp.p_pid != pid)
return QString();
}
if (proc->ki_pid != pid) {
free(proc);
QString name = QFile::decodeName(kp.p_comm);
# else
if (kp.ki_pid != pid)
return QString();
}
QString name = QFile::decodeName(kp.ki_comm);
# endif
QString name = QFile::decodeName(proc->ki_comm);
free(proc);
return name;
#else
Q_UNUSED(pid);
return QString();

View File

@ -143,9 +143,11 @@ bool QLockFilePrivate::isApparentlyStale() const
if (!procHandle)
return true;
// We got a handle but check if process is still alive
DWORD dwR = ::WaitForSingleObject(procHandle, 0);
DWORD exitCode = 0;
if (!::GetExitCodeProcess(procHandle, &exitCode))
exitCode = 0;
::CloseHandle(procHandle);
if (dwR == WAIT_TIMEOUT)
if (exitCode != STILL_ACTIVE)
return true;
const QString processName = processNameByPid(pid);
if (!processName.isEmpty() && processName != appname)

View File

@ -2097,10 +2097,7 @@ void QProcess::start(const QString &program, const QStringList &arguments, OpenM
return;
}
if (program.isEmpty()) {
Q_D(QProcess);
d->processError = QProcess::FailedToStart;
setErrorString(tr("No program defined"));
emit error(d->processError);
d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
return;
}
@ -2127,10 +2124,7 @@ void QProcess::start(OpenMode mode)
return;
}
if (d->program.isEmpty()) {
Q_D(QProcess);
d->processError = QProcess::FailedToStart;
setErrorString(tr("No program defined"));
emit error(d->processError);
d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
return;
}

View File

@ -84,7 +84,7 @@
# if !defined(ST_RDONLY)
# define ST_RDONLY MNT_RDONLY
# endif
# if !defined(_STATFS_F_FLAGS)
# if !defined(_STATFS_F_FLAGS) && !defined(Q_OS_NETBSD)
# define _STATFS_F_FLAGS 1
# endif
#elif defined(Q_OS_ANDROID)

View File

@ -208,6 +208,8 @@ bool QWindowsPipeWriter::write(const QByteArray &ba)
void QWindowsPipeWriter::stop()
{
stopped = true;
bytesWrittenPending = false;
pendingBytesWrittenValue = 0;
if (writeSequenceStarted) {
if (!qt_cancelIo(handle, &overlapped)) {
const DWORD dwError = GetLastError();

View File

@ -410,7 +410,7 @@ public:
// pack with itself, we'll discard the high part anyway
chunk = _mm_packus_epi16(chunk, chunk);
// unaligned 64-bit store
qUnalignedStore(l + i, _mm_cvtsi128_si64(chunk));
qToUnaligned(_mm_cvtsi128_si64(chunk), l + i);
i += 8;
}
# endif

View File

@ -275,25 +275,11 @@ QJsonValue::QJsonValue(const QJsonValue &other)
*/
QJsonValue &QJsonValue::operator =(const QJsonValue &other)
{
if (t == String && stringData && !stringData->ref.deref())
free(stringData);
t = other.t;
dbl = other.dbl;
if (d != other.d) {
if (d && !d->ref.deref())
delete d;
d = other.d;
if (d)
d->ref.ref();
}
if (t == String && stringData)
stringData->ref.ref();
QJsonValue copy(other);
// swap(copy);
qSwap(dbl, copy.dbl);
qSwap(d, copy.d);
qSwap(t, copy.t);
return *this;
}

View File

@ -41,16 +41,6 @@
#include "qcore_unix_p.h"
#include "qelapsedtimer.h"
#ifdef Q_OS_NACL
#elif !defined (Q_OS_VXWORKS)
# if !defined(Q_OS_HPUX) || defined(__ia64)
# include <sys/select.h>
# endif
# include <sys/time.h>
#else
# include <selectLib.h>
#endif
#include <stdlib.h>
#ifdef Q_OS_MAC

View File

@ -65,6 +65,16 @@
#include <sys/stat.h>
#include <unistd.h>
#ifdef Q_OS_NACL
#elif !defined (Q_OS_VXWORKS)
# if !defined(Q_OS_HPUX) || defined(__ia64)
# include <sys/select.h>
# endif
# include <sys/time.h>
#else
# include <selectLib.h>
#endif
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>

View File

@ -4699,7 +4699,7 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
QOrderedMutexLocker locker(signalSlotLock(sender),
signalSlotLock(receiver));
if (type & Qt::UniqueConnection) {
if (type & Qt::UniqueConnection && slot) {
QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
if (connectionLists && connectionLists->count() > signal_index) {
const QObjectPrivate::Connection *c2 =

View File

@ -419,8 +419,7 @@ protected:
QScopedPointer<QObjectData> d_ptr;
static const QMetaObject staticQtMetaObject;
friend inline const QMetaObject *qt_getQtMetaObject() Q_DECL_NOEXCEPT
{ return &staticQtMetaObject; }
friend inline const QMetaObject *qt_getQtMetaObject() Q_DECL_NOEXCEPT;
friend struct QMetaObject;
friend struct QMetaObjectPrivate;
@ -451,6 +450,9 @@ inline QMetaObject::Connection QObject::connect(const QObject *asender, const ch
const char *amember, Qt::ConnectionType atype) const
{ return connect(asender, asignal, this, amember, atype); }
inline const QMetaObject *qt_getQtMetaObject() Q_DECL_NOEXCEPT
{ return &QObject::staticQtMetaObject; }
#ifndef QT_NO_USERDATA
class Q_CORE_EXPORT QObjectUserData {
public:

View File

@ -48,7 +48,6 @@
#include <QtCore/QList>
#include <QtCore/QDebug>
#include <qendian.h>
#include <private/qsimd_p.h> // for qUnalignedLoad
QT_BEGIN_NAMESPACE
@ -164,7 +163,7 @@ bool QMimeMagicRule::matchNumber(const QByteArray &data) const
const char *p = data.constData() + m_startPos;
const char *e = data.constData() + qMin(data.size() - int(sizeof(T)), m_endPos + 1);
for ( ; p <= e; ++p) {
if ((qUnalignedLoad<T>(p) & mask) == (value & mask))
if ((qFromUnaligned<T>(reinterpret_cast<const uchar *>(p)) & mask) == (value & mask))
return true;
}

View File

@ -42,6 +42,7 @@
#include <qalgorithms.h>
#include <qdatastream.h>
#include <qdebug.h>
#include <qendian.h>
#include <string.h>
QT_BEGIN_NAMESPACE
@ -169,25 +170,6 @@ QBitArray::QBitArray(int size, bool value)
Same as size().
*/
template <typename T> T qUnalignedLoad(const uchar *ptr)
{
/*
* Testing with different compilers shows that they all optimize the memcpy
* call away and replace with direct loads whenever possible. On x86 and PPC,
* GCC does direct unaligned loads; on MIPS, it generates a pair of load-left
* and load-right instructions. ICC and Clang do the same on x86. This is both
* 32- and 64-bit.
*
* On ARM cores without unaligned loads, the compiler leaves a call to
* memcpy.
*/
T u;
memcpy(&u, ptr, sizeof(u));
return u;
}
/*!
If \a on is true, this function returns the number of
1-bits stored in the bit array; otherwise the number
@ -203,17 +185,17 @@ int QBitArray::count(bool on) const
const quint8 *const end = reinterpret_cast<const quint8 *>(d.end());
while (bits + 7 <= end) {
quint64 v = qUnalignedLoad<quint64>(bits);
quint64 v = qFromUnaligned<quint64>(bits);
bits += 8;
numBits += int(qPopulationCount(v));
}
if (bits + 3 <= end) {
quint32 v = qUnalignedLoad<quint32>(bits);
quint32 v = qFromUnaligned<quint32>(bits);
bits += 4;
numBits += int(qPopulationCount(v));
}
if (bits + 1 < end) {
quint16 v = qUnalignedLoad<quint16>(bits);
quint16 v = qFromUnaligned<quint16>(bits);
bits += 2;
numBits += int(qPopulationCount(v));
}

View File

@ -95,9 +95,29 @@ static SHA3Final * const sha3Final = Final;
available on all platforms (MSVC 2008, for example), we #define them to the
Qt equivalents.
*/
#ifdef uint64_t
#undef uint64_t
#endif
#define uint64_t QT_PREPEND_NAMESPACE(quint64)
#ifdef uint32_t
#undef uint32_t
#endif
#define uint32_t QT_PREPEND_NAMESPACE(quint32)
#ifdef uint8_t
#undef uint8_t
#endif
#define uint8_t QT_PREPEND_NAMESPACE(quint8)
#ifdef int_least16_t
#undef int_least16_t
#endif
#define int_least16_t QT_PREPEND_NAMESPACE(qint16)
// Header from rfc6234 with 1 modification:

View File

@ -2180,7 +2180,7 @@ static int qt_timezone()
// number of seconds west of UTC.
// - It also takes DST into account, so we need to adjust it to always
// get the Standard Time offset.
return -t.tm_gmtoff + (t.tm_isdst ? SECS_PER_HOUR : 0L);
return -t.tm_gmtoff + (t.tm_isdst ? (long)SECS_PER_HOUR : 0L);
#elif defined(Q_OS_INTEGRITY)
return 0;
#else

View File

@ -58,6 +58,7 @@
#include <qbytearray.h>
#include <qdatetime.h>
#include <qbasicatomic.h>
#include <qendian.h>
#include <private/qsimd_p.h>
#ifndef QT_BOOTSTRAPPED
@ -112,24 +113,24 @@ static uint crc32(const Char *ptr, size_t len, uint h)
p += 8;
for ( ; p <= e; p += 8)
h2 = _mm_crc32_u64(h2, qUnalignedLoad<qlonglong>(p - 8));
h2 = _mm_crc32_u64(h2, qFromUnaligned<qlonglong>(p - 8));
h = h2;
p -= 8;
len = e - p;
if (len & 4) {
h = _mm_crc32_u32(h, qUnalignedLoad<uint>(p));
h = _mm_crc32_u32(h, qFromUnaligned<uint>(p));
p += 4;
}
# else
p += 4;
for ( ; p <= e; p += 4)
h = _mm_crc32_u32(h, qUnalignedLoad<uint>(p - 4));
h = _mm_crc32_u32(h, qFromUnaligned<uint>(p - 4));
p -= 4;
len = e - p;
# endif
if (len & 2) {
h = _mm_crc32_u16(h, qUnalignedLoad<ushort>(p));
h = _mm_crc32_u16(h, qFromUnaligned<ushort>(p));
p += 2;
}
if (sizeof(Char) == 1 && len & 1)

View File

@ -46,9 +46,29 @@
available on all platforms (MSVC 2008, for example), we #define them to the
Qt equivalents.
*/
#ifdef uint64_t
#undef uint64_t
#endif
#define uint64_t QT_PREPEND_NAMESPACE(quint64)
#ifdef uint32_t
#undef uint32_t
#endif
#define uint32_t QT_PREPEND_NAMESPACE(quint32)
#ifdef uint8_t
#undef uint8_t
#endif
#define uint8_t QT_PREPEND_NAMESPACE(quint8)
#ifdef int_least16_t
#undef int_least16_t
#endif
#define int_least16_t QT_PREPEND_NAMESPACE(qint16)
// Header from rfc6234 with 1 modification:

View File

@ -751,26 +751,4 @@ void qDumpCPUFeatures()
puts("");
}
/*!
\internal
\fn T qUnalignedLoad(const void *ptr)
\since 5.6.1
Loads a \c{T} from address \a ptr, which may be misaligned.
Use of this function avoid the undefined behavior that the C++ standard
otherwise attributes to unaligned loads.
*/
/*!
\internal
\fn void qUnalignedStore(void *ptr, T t)
\since 5.6.1
Stores \a t to address \a ptr, which may be misaligned.
Use of this function avoid the undefined behavior that the C++ standard
otherwise attributes to unaligned stores.
*/
QT_END_NAMESPACE

View File

@ -584,7 +584,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l)
// we'll read uc[offset..offset+7] (16 bytes) and c[offset..offset+7] (8 bytes)
if (uc + offset + 7 < e) {
// same, but we're using an 8-byte load
__m128i chunk = _mm_cvtsi64_si128(qUnalignedLoad<long long>(c + offset));
__m128i chunk = _mm_cvtsi64_si128(qFromUnaligned<long long>(c + offset));
__m128i secondHalf = _mm_unpacklo_epi8(chunk, nullmask);
__m128i ucdata = _mm_loadu_si128((const __m128i*)(uc + offset));

View File

@ -47,6 +47,8 @@
#include <qdebug.h>
#include "qlocale_tools_p.h"
#include <algorithm>
QT_BEGIN_NAMESPACE
@ -376,39 +378,126 @@ static QDate calculatePosixDate(const QByteArray &dateRule, int year)
}
}
static QTime parsePosixTime(const QByteArray &timeRule)
// returns the time in seconds, INT_MIN if we failed to parse
static int parsePosixTime(const char *begin, const char *end)
{
// Format "HH:mm:ss", put check parts count just in case
QList<QByteArray> parts = timeRule.split(':');
int count = parts.count();
if (count == 3)
return QTime(parts.at(0).toInt(), parts.at(1).toInt(), parts.at(2).toInt());
else if (count == 2)
return QTime(parts.at(0).toInt(), parts.at(1).toInt(), 0);
else if (count == 1)
return QTime(parts.at(0).toInt(), 0, 0);
return QTime(2, 0, 0);
// Format "hh[:mm[:ss]]"
int hour, min = 0, sec = 0;
// Note that the calls to qstrtoll do *not* check the end pointer, which
// means they proceed until they find a non-digit. We check that we're
// still in range at the end, but we may have read from past end. It's the
// caller's responsibility to ensure that begin is part of a
// null-terminated string.
bool ok = false;
hour = qstrtoll(begin, &begin, 10, &ok);
if (!ok || hour < 0)
return INT_MIN;
if (begin < end && *begin == ':') {
// minutes
++begin;
min = qstrtoll(begin, &begin, 10, &ok);
if (!ok || min < 0)
return INT_MIN;
if (begin < end && *begin == ':') {
// seconds
++begin;
sec = qstrtoll(begin, &begin, 10, &ok);
if (!ok || sec < 0)
return INT_MIN;
}
}
// we must have consumed everything
if (begin != end)
return INT_MIN;
return (hour * 60 + min) * 60 + sec;
}
static int parsePosixOffset(const QByteArray &timeRule)
static QTime parsePosixTransitionTime(const QByteArray &timeRule)
{
// Format "hh[:mm[:ss]]"
int value = parsePosixTime(timeRule.constBegin(), timeRule.constEnd());
if (value == INT_MIN) {
// if we failed to parse, return 02:00
return QTime(2, 0, 0);
}
return QTime::fromMSecsSinceStartOfDay(value * 1000);
}
static int parsePosixOffset(const char *begin, const char *end)
{
// Format "[+|-]hh[:mm[:ss]]"
QList<QByteArray> parts = timeRule.split(':');
int count = parts.count();
if (count == 3) {
int hour = parts.at(0).toInt();
int sign = hour >= 0 ? -1 : 1;
return sign * ((qAbs(hour) * 60 * 60) + (parts.at(1).toInt() * 60) + parts.at(2).toInt());
} else if (count == 2) {
int hour = parts.at(0).toInt();
int sign = hour >= 0 ? -1 : 1;
return sign * ((qAbs(hour) * 60 * 60) + (parts.at(1).toInt() * 60));
} else if (count == 1) {
int hour = parts.at(0).toInt();
int sign = hour >= 0 ? -1 : 1;
return sign * (qAbs(hour) * 60 * 60);
// note that the sign is inverted because POSIX counts in hours West of GMT
bool negate = true;
if (*begin == '+') {
++begin;
} else if (*begin == '-') {
negate = false;
++begin;
}
return 0;
int value = parsePosixTime(begin, end);
if (value == INT_MIN)
return value;
return negate ? -value : value;
}
static inline bool asciiIsLetter(char ch)
{
ch |= 0x20; // lowercases if it is a letter, otherwise just corrupts ch
return ch >= 'a' && ch <= 'z';
}
// Returns the zone name, the offset (in seconds) and advances \a begin to
// where the parsing ended. Returns a zone of INT_MIN in case an offset
// couldn't be read.
static QPair<QString, int> parsePosixZoneNameAndOffset(const char *&pos, const char *end)
{
static const char offsetChars[] = "0123456789:";
QPair<QString, int> result = qMakePair(QString(), INT_MIN);
const char *nameBegin = pos;
const char *nameEnd;
Q_ASSERT(pos < end);
if (*pos == '<') {
nameBegin = pos + 1; // skip the '<'
nameEnd = nameBegin;
while (nameEnd < end && *nameEnd != '>') {
// POSIX says only alphanumeric, but we allow anything
++nameEnd;
}
pos = nameEnd + 1; // skip the '>'
} else {
nameBegin = pos;
nameEnd = nameBegin;
while (nameEnd < end && asciiIsLetter(*nameEnd))
++nameEnd;
pos = nameEnd;
}
if (nameEnd - nameBegin < 3)
return result; // name must be at least 3 characters long
// zone offset, form [+-]hh:mm:ss
const char *zoneBegin = pos;
const char *zoneEnd = pos;
if (zoneEnd < end && (zoneEnd[0] == '+' || zoneEnd[0] == '-'))
++zoneEnd;
while (zoneEnd < end) {
if (strchr(offsetChars, char(*zoneEnd)) == NULL)
break;
++zoneEnd;
}
result.first = QString::fromUtf8(nameBegin, nameEnd - nameBegin);
if (zoneEnd > zoneBegin)
result.second = parsePosixOffset(zoneBegin, zoneEnd);
pos = zoneEnd;
return result;
}
static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray &posixRule,
@ -425,58 +514,45 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
// POSIX Format is like "TZ=CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00"
// i.e. "std offset dst [offset],start[/time],end[/time]"
// See http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
// See the section about TZ at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
QList<QByteArray> parts = posixRule.split(',');
QString name = QString::fromUtf8(parts.at(0));
QString stdName;
QString stdOffsetString;
QString dstName;
QString dstOffsetString;
bool parsedStdName = false;
bool parsedStdOffset = false;
for (int i = 0; i < name.size(); ++i) {
if (name.at(i).isLetter()) {
if (parsedStdName) {
parsedStdOffset = true;
dstName.append(name.at(i));
} else {
stdName.append(name.at(i));
QPair<QString, int> stdZone, dstZone;
{
const QByteArray &zoneinfo = parts.at(0);
const char *begin = zoneinfo.constBegin();
stdZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd());
if (stdZone.second == INT_MIN) {
stdZone.second = 0; // reset to UTC if we failed to parse
} else if (begin < zoneinfo.constEnd()) {
dstZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd());
if (dstZone.second == INT_MIN) {
// if the dst offset isn't provided, it is 1 hour ahead of the standard offset
dstZone.second = stdZone.second + (60 * 60);
}
} else {
parsedStdName = true;
if (parsedStdOffset)
dstOffsetString.append(name.at(i));
else
stdOffsetString.append(name.at(i));
}
}
int utcOffset = parsePosixOffset(stdOffsetString.toUtf8());
// If only the name part then no transitions
if (parts.count() == 1) {
QTimeZonePrivate::Data data;
data.atMSecsSinceEpoch = lastTranMSecs;
data.offsetFromUtc = utcOffset;
data.standardTimeOffset = utcOffset;
data.offsetFromUtc = stdZone.second;
data.standardTimeOffset = stdZone.second;
data.daylightTimeOffset = 0;
data.abbreviation = stdName;
data.abbreviation = stdZone.first;
result << data;
return result;
}
// If not populated the total dst offset is 1 hour
int dstOffset = utcOffset + (60 * 60);
if (!dstOffsetString.isEmpty())
dstOffset = parsePosixOffset(dstOffsetString.toUtf8());
// Get the std to dst transtion details
QList<QByteArray> dstParts = parts.at(1).split('/');
QByteArray dstDateRule = dstParts.at(0);
QTime dstTime;
if (dstParts.count() > 1)
dstTime = parsePosixTime(dstParts.at(1));
dstTime = parsePosixTransitionTime(dstParts.at(1));
else
dstTime = QTime(2, 0, 0);
@ -485,25 +561,25 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
QByteArray stdDateRule = stdParts.at(0);
QTime stdTime;
if (stdParts.count() > 1)
stdTime = parsePosixTime(stdParts.at(1));
stdTime = parsePosixTransitionTime(stdParts.at(1));
else
stdTime = QTime(2, 0, 0);
for (int year = startYear; year <= endYear; ++year) {
QTimeZonePrivate::Data dstData;
QDateTime dst(calculatePosixDate(dstDateRule, year), dstTime, Qt::UTC);
dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (utcOffset * 1000);
dstData.offsetFromUtc = dstOffset;
dstData.standardTimeOffset = utcOffset;
dstData.daylightTimeOffset = dstOffset - utcOffset;
dstData.abbreviation = dstName;
dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (stdZone.second * 1000);
dstData.offsetFromUtc = dstZone.second;
dstData.standardTimeOffset = stdZone.second;
dstData.daylightTimeOffset = dstZone.second - stdZone.second;
dstData.abbreviation = dstZone.first;
QTimeZonePrivate::Data stdData;
QDateTime std(calculatePosixDate(stdDateRule, year), stdTime, Qt::UTC);
stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstOffset * 1000);
stdData.offsetFromUtc = utcOffset;
stdData.standardTimeOffset = utcOffset;
stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstZone.second * 1000);
stdData.offsetFromUtc = stdZone.second;
stdData.standardTimeOffset = stdZone.second;
stdData.daylightTimeOffset = 0;
stdData.abbreviation = stdName;
stdData.abbreviation = stdZone.first;
// Part of the high year will overflow
if (year == 292278994 && (dstData.atMSecsSinceEpoch < 0 || stdData.atMSecsSinceEpoch < 0)) {
if (dstData.atMSecsSinceEpoch > 0) {

View File

@ -49,7 +49,7 @@
****************************************************************************/
//! [0]
QClipboard *clipboard = QApplication::clipboard();
QClipboard *clipboard = QGuiApplication::clipboard();
QString originalText = clipboard->text();
...
clipboard->setText(newText);

View File

@ -289,6 +289,12 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
format = QImage::Format_Mono;
}
if (depth != 32) {
ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
if (ncols < 1 || ncols > 256) // sanity check - don't run out of mem if color table is broken
return false;
}
if (bi.biHeight < 0)
h = -h; // support images with negative height
@ -296,19 +302,15 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int
image = QImage(w, h, format);
if (image.isNull()) // could not create image
return false;
}
if (depth != 32) {
ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
if (ncols < 1 || ncols > 256) // sanity check - don't run out of mem if color table is broken
return false;
image.setColorCount(ncols);
if (ncols)
image.setColorCount(ncols); // Ensure valid QImage
}
image.setDotsPerMeterX(bi.biXPelsPerMeter);
image.setDotsPerMeterY(bi.biYPelsPerMeter);
if (ncols > 0) { // read color table
image.setColorCount(ncols);
uchar rgb[4];
int rgb_len = t == BMP_OLD ? 3 : 4;
for (int i=0; i<ncols; i++) {

View File

@ -176,6 +176,9 @@ QImageData::~QImageData()
data = 0;
}
#if defined(_M_ARM)
#pragma optimize("", off)
#endif
bool QImageData::checkForAlphaPixels() const
{
@ -290,6 +293,9 @@ bool QImageData::checkForAlphaPixels() const
return has_alpha_pixels;
}
#if defined(_M_ARM)
#pragma optimize("", on)
#endif
/*!
\class QImage

View File

@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE
Drop}.
There is a single QClipboard object in an application, accessible
as QApplication::clipboard().
as QGuiApplication::clipboard().
Example:
\snippet code/src_gui_kernel_qclipboard.cpp 0
@ -137,7 +137,7 @@ QT_BEGIN_NAMESPACE
\endlist
\sa QApplication
\sa QGuiApplication
*/
/*!
@ -147,7 +147,7 @@ QT_BEGIN_NAMESPACE
Do not call this function.
Call QApplication::clipboard() instead to get a pointer to the
Call QGuiApplication::clipboard() instead to get a pointer to the
application's global clipboard object.
There is only one clipboard in the window system, and creating
@ -165,7 +165,7 @@ QClipboard::QClipboard(QObject *parent)
Destroys the clipboard.
You should never delete the clipboard. QApplication will do this
You should never delete the clipboard. QGuiApplication will do this
when the application terminates.
*/
QClipboard::~QClipboard()

View File

@ -2186,11 +2186,10 @@ void QPainter::setBrushOrigin(const QPointF &p)
destination pixel in such a way that the alpha component of the
source defines the translucency of the pixel.
When the paint device is a QImage, the image format must be set to
\l {QImage::Format}{Format_ARGB32_Premultiplied} or
\l {QImage::Format}{Format_ARGB32} for the composition modes to have
any effect. For performance the premultiplied version is the preferred
format.
Several composition modes require an alpha channel in the source or
target images to have an effect. For optimal performance the
image format \l {QImage::Format}{Format_ARGB32_Premultiplied} is
preferred.
When a composition mode is set it applies to all painting
operator, pens, brushes, gradients and pixmap/image drawing.

View File

@ -2732,8 +2732,7 @@ void QFontDatabase::load(const QFontPrivate *d, int script)
}
if (req.pointSize < 0)
req.pointSize = req.pixelSize*72.0/d->dpi;
if (req.weight == 0)
req.weight = QFont::Normal;
req.weight = QFont::Normal;
if (req.stretch == 0)
req.stretch = 100;

View File

@ -1833,8 +1833,7 @@ QFontEngine *QFontEngineMulti::loadEngine(int at)
request.family = fallbackFamilyAt(at - 1);
if (QFontEngine *engine = QFontDatabase::findFont(request, m_script)) {
if (request.weight > QFont::Normal)
engine->fontDef.weight = request.weight;
engine->fontDef.weight = request.weight;
if (request.style > QFont::StyleNormal)
engine->fontDef.style = request.style;
return engine;

View File

@ -1645,8 +1645,14 @@ void QTextEngine::itemize() const
if (analysis->bidiLevel % 2)
--analysis->bidiLevel;
analysis->flags = QScriptAnalysis::LineOrParagraphSeparator;
if (option.flags() & QTextOption::ShowLineAndParagraphSeparators)
if (option.flags() & QTextOption::ShowLineAndParagraphSeparators) {
const int offset = uc - string;
layoutData->string.detach();
string = reinterpret_cast<const ushort *>(layoutData->string.unicode());
uc = string + offset;
e = uc + length;
*const_cast<ushort*>(uc) = 0x21B5; // visual line separator
}
break;
case QChar::Tabulation:
analysis->flags = QScriptAnalysis::Tab;

View File

@ -364,9 +364,10 @@ void QTextFormatPrivate::recalcFont() const
f.setPixelSize(props.at(i).value.toInt());
break;
case QTextFormat::FontWeight: {
int weight = props.at(i).value.toInt();
if (weight == 0) weight = QFont::Normal;
f.setWeight(weight);
const QVariant weightValue = props.at(i).value;
int weight = weightValue.toInt();
if (weight >= 0 && weightValue.isValid())
f.setWeight(weight);
break; }
case QTextFormat::FontItalic:
f.setItalic(props.at(i).value.toBool());

View File

@ -431,9 +431,9 @@ public:
{ return doubleProperty(FontPointSize); }
inline void setFontWeight(int weight)
{ if (weight == QFont::Normal) weight = 0; setProperty(FontWeight, weight); }
{ setProperty(FontWeight, weight); }
inline int fontWeight() const
{ int weight = intProperty(FontWeight); if (weight == 0) weight = QFont::Normal; return weight; }
{ return hasProperty(FontWeight) ? intProperty(FontWeight) : QFont::Normal; }
inline void setFontItalic(bool italic)
{ setProperty(FontItalic, italic); }
inline bool fontItalic() const

View File

@ -72,14 +72,4 @@ SOURCES += \
mac: LIBS_PRIVATE += -framework Security
ios {
HEADERS += \
access/qnetworkreplynsurlconnectionimpl_p.h
OBJECTIVE_SOURCES += \
access/qnetworkreplynsurlconnectionimpl.mm
LIBS_PRIVATE += -framework Foundation
}
include($$PWD/../../3rdparty/zlib_dependency.pri)

View File

@ -331,7 +331,7 @@ bool QHttpNetworkConnectionChannel::ensureConnection()
priv->phase = QAuthenticatorPrivate::Start;
QString connectHost = connection->d_func()->hostName;
qint16 connectPort = connection->d_func()->port;
quint16 connectPort = connection->d_func()->port;
#ifndef QT_NO_NETWORKPROXY
// HTTPS always use transparent proxy.

View File

@ -56,10 +56,6 @@
#include "qnetworkreplydataimpl_p.h"
#include "qnetworkreplyfileimpl_p.h"
#if defined(Q_OS_IOS) && defined(QT_NO_SSL)
#include "qnetworkreplynsurlconnectionimpl_p.h"
#endif
#include "QtCore/qbuffer.h"
#include "QtCore/qurl.h"
#include "QtCore/qvector.h"
@ -1207,12 +1203,6 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
}
}
// Use NSURLConnection for https on iOS when OpenSSL is disabled.
#if defined(Q_OS_IOS) && defined(QT_NO_SSL)
if (scheme == QLatin1String("https"))
return new QNetworkReplyNSURLConnectionImpl(this, request, op, outgoingData);
#endif
#ifndef QT_NO_HTTP
// Since Qt 5 we use the new QNetworkReplyHttpImpl
if (scheme == QLatin1String("http") || scheme == QLatin1String("preconnect-http")

View File

@ -1,458 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qnetworkreplynsurlconnectionimpl_p.h"
#include "QtCore/qdatetime.h"
#include <QtCore/qcoreapplication.h>
#include <QtCore/qdebug.h>
#include <Foundation/Foundation.h>
QT_BEGIN_NAMESPACE
// Network reply implementation using NSUrlConnection.
//
// Class/object structure:
//
// QNetworkReplyNSURLConnectionImpl
// |- QNetworkReplyNSURLConnectionImplPrivate
// |- (bytes read)
// |- (QIODevice and CFStream for async POST data transfer)
// |- NSURLConnection
// |- QtNSURLConnectionDelegate <NSURLConnectionDataDelegate>
// |- NSURLResponse/NSHTTPURLResponse
// |- (response data)
//
// The main entry point is the QNetworkReplyNSURLConnectionImpl constructor, which
// receives a network request from QNetworkAccessManager. The constructor
// creates a NSURLRequest and initiates a NSURLConnection with a QtNSURLConnectionDelegate.
// The delegate callbacks are then called asynchronously as the request completes.
//
@class QtNSURLConnectionDelegate;
class QNetworkReplyNSURLConnectionImplPrivate: public QNetworkReplyPrivate
{
public:
QNetworkReplyNSURLConnectionImplPrivate();
virtual ~QNetworkReplyNSURLConnectionImplPrivate();
Q_DECLARE_PUBLIC(QNetworkReplyNSURLConnectionImpl)
NSURLConnection * urlConnection;
QtNSURLConnectionDelegate *urlConnectionDelegate;
qint64 bytesRead;
// Sequental outgiong data streaming
QIODevice *outgoingData;
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFIndex transferBufferSize;
// Forwarding functions to the public class.
void setFinished();
void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value);
void setRawHeader(const QByteArray &headerName, const QByteArray &value);
void setError(QNetworkReply::NetworkError errorCode, const QString &errorString);
void setAttribute(QNetworkRequest::Attribute code, const QVariant &value);
};
@interface QtNSURLConnectionDelegate : NSObject
{
NSURLResponse *response;
NSMutableData *responseData;
QNetworkReplyNSURLConnectionImplPrivate * replyprivate;
}
- (id)initWithQNetworkReplyNSURLConnectionImplPrivate:(QNetworkReplyNSURLConnectionImplPrivate *)a_replyPrivate ;
#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_7, __IPHONE_3_0)
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
#endif
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError*)error;
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response;
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data;
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite;
- (NSCachedURLResponse*)connection:(NSURLConnection*)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse;
- (NSURLRequest*)connection:(NSURLConnection*)connection willSendRequest:(NSURLRequest*)request redirectResponse:(NSURLResponse*)redirectResponse;
- (void)connectionDidFinishLoading:(NSURLConnection*)connection;
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection*)connection;
@end
QNetworkReplyNSURLConnectionImplPrivate::QNetworkReplyNSURLConnectionImplPrivate()
: QNetworkReplyPrivate()
, urlConnection(0)
, urlConnectionDelegate(0)
, bytesRead(0)
, readStream(0)
, writeStream(0)
, transferBufferSize(4096)
{
}
QNetworkReplyNSURLConnectionImplPrivate::~QNetworkReplyNSURLConnectionImplPrivate()
{
[urlConnection cancel];
[urlConnection release];
[urlConnectionDelegate release];
if (readStream)
CFRelease(readStream);
if (writeStream)
CFRelease(writeStream);
}
void QNetworkReplyNSURLConnectionImplPrivate::setFinished()
{
q_func()->setFinished(true);
QMetaObject::invokeMethod(q_func(), "finished", Qt::QueuedConnection);
}
void QNetworkReplyNSURLConnectionImplPrivate::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
{
q_func()->setHeader(header, value);
}
void QNetworkReplyNSURLConnectionImplPrivate::setRawHeader(const QByteArray &headerName, const QByteArray &value)
{
q_func()->setRawHeader(headerName, value);
}
void QNetworkReplyNSURLConnectionImplPrivate::setError(QNetworkReply::NetworkError errorCode, const QString &errorString)
{
q_func()->setError(errorCode, errorString);
}
void QNetworkReplyNSURLConnectionImplPrivate::setAttribute(QNetworkRequest::Attribute code, const QVariant &value)
{
q_func()->setAttribute(code, value);
}
void QNetworkReplyNSURLConnectionImpl::readyReadOutgoingData()
{
Q_D(QNetworkReplyNSURLConnectionImpl);
int bytesRead = 0;
do {
char data[d->transferBufferSize];
bytesRead = d->outgoingData->read(data, d->transferBufferSize);
if (bytesRead <= 0)
break;
CFIndex bytesWritten = CFWriteStreamWrite(d->writeStream, reinterpret_cast<unsigned char *>(data), bytesRead);
if (bytesWritten != bytesRead) {
CFErrorRef err = CFWriteStreamCopyError(d->writeStream);
qWarning() << "QNetworkReplyNSURLConnectionImpl: CFWriteStreamWrite error"
<< (err ? QString::number(CFErrorGetCode(err)) : QStringLiteral(""));
}
} while (bytesRead > 0);
if (d->outgoingData->atEnd())
CFWriteStreamClose(d->writeStream);
}
@interface QtNSURLConnectionDelegate ()
@property (nonatomic, retain) NSURLResponse* response;
@property (nonatomic, retain) NSMutableData* responseData;
@end
@implementation QtNSURLConnectionDelegate
@synthesize response;
@synthesize responseData;
- (id)initWithQNetworkReplyNSURLConnectionImplPrivate:(QNetworkReplyNSURLConnectionImplPrivate *)a_replyPrivate
{
if (self = [super init])
replyprivate = a_replyPrivate;
return self;
}
- (void)dealloc
{
[response release];
[responseData release];
[super dealloc];
}
#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_7, __IPHONE_3_0)
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
Q_UNUSED(connection)
Q_UNUSED(challenge)
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecTrustResultType resultType;
SecTrustEvaluate(serverTrust, &resultType);
if (resultType == kSecTrustResultUnspecified) {
// All good
[challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
} else if (resultType == kSecTrustResultRecoverableTrustFailure) {
// Certificate verification error, ask user
// ### TODO actually ask user
// (test site: https://testssl-expire.disig.sk/index.en.html)
qWarning() << "QNetworkReplyNSURLConnection: Certificate verification error handlig is"
<< "not implemented. Connection will time out.";
} else {
// other error, which the default handler will handle
[challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
}
}
[challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
}
#endif
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
Q_UNUSED(connection)
QNetworkReply::NetworkError qtError = QNetworkReply::UnknownNetworkError;
if ([[error domain] isEqualToString:NSURLErrorDomain]) {
switch ([error code]) {
case NSURLErrorTimedOut: qtError = QNetworkReply::TimeoutError; break;
case NSURLErrorUnsupportedURL: qtError = QNetworkReply::ProtocolUnknownError; break;
case NSURLErrorCannotFindHost: qtError = QNetworkReply::HostNotFoundError; break;
case NSURLErrorCannotConnectToHost: qtError = QNetworkReply::ConnectionRefusedError; break;
case NSURLErrorNetworkConnectionLost: qtError = QNetworkReply::NetworkSessionFailedError; break;
case NSURLErrorDNSLookupFailed: qtError = QNetworkReply::HostNotFoundError; break;
case NSURLErrorNotConnectedToInternet: qtError = QNetworkReply::NetworkSessionFailedError; break;
case NSURLErrorUserAuthenticationRequired: qtError = QNetworkReply::AuthenticationRequiredError; break;
default: break;
}
}
replyprivate->setError(qtError, QString::fromNSString([error localizedDescription]));
replyprivate->setFinished();
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)aResponse
{
Q_UNUSED(connection)
self.response = aResponse;
self.responseData = [NSMutableData data];
// copy headers
if ([aResponse isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)aResponse;
NSDictionary *headers = [httpResponse allHeaderFields];
for (NSString *key in headers) {
NSString *value = [headers objectForKey:key];
replyprivate->setRawHeader(QString::fromNSString(key).toUtf8(), QString::fromNSString(value).toUtf8());
}
int code = [httpResponse statusCode];
replyprivate->setAttribute(QNetworkRequest::HttpStatusCodeAttribute, code);
} else {
if ([aResponse expectedContentLength] != NSURLResponseUnknownLength)
replyprivate->setHeader(QNetworkRequest::ContentLengthHeader, [aResponse expectedContentLength]);
}
QMetaObject::invokeMethod(replyprivate->q_func(), "metaDataChanged", Qt::QueuedConnection);
}
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
Q_UNUSED(connection)
[responseData appendData:data];
if ([response expectedContentLength] != NSURLResponseUnknownLength) {
QMetaObject::invokeMethod(replyprivate->q_func(), "downloadProgress", Qt::QueuedConnection,
Q_ARG(qint64, qint64([responseData length] + replyprivate->bytesRead)),
Q_ARG(qint64, qint64([response expectedContentLength])));
}
QMetaObject::invokeMethod(replyprivate->q_func(), "readyRead", Qt::QueuedConnection);
}
- (void)connection:(NSURLConnection*)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
Q_UNUSED(connection)
Q_UNUSED(bytesWritten)
QMetaObject::invokeMethod(replyprivate->q_func(), "uploadProgress", Qt::QueuedConnection,
Q_ARG(qint64, qint64(totalBytesWritten)),
Q_ARG(qint64, qint64(totalBytesExpectedToWrite)));
}
- (NSCachedURLResponse*)connection:(NSURLConnection*)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse
{
Q_UNUSED(connection)
return cachedResponse;
}
- (NSURLRequest*)connection:(NSURLConnection*)connection willSendRequest:(NSURLRequest*)request redirectResponse:(NSURLResponse*)redirectResponse
{
Q_UNUSED(connection)
Q_UNUSED(redirectResponse)
return request;
}
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
Q_UNUSED(connection)
replyprivate->setFinished();
}
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection*)connection
{
Q_UNUSED(connection)
return YES;
}
@end
QNetworkReplyNSURLConnectionImpl::~QNetworkReplyNSURLConnectionImpl()
{
}
QNetworkReplyNSURLConnectionImpl::QNetworkReplyNSURLConnectionImpl(QObject *parent,
const QNetworkRequest &request, const QNetworkAccessManager::Operation operation, QIODevice* outgoingData)
: QNetworkReply(*new QNetworkReplyNSURLConnectionImplPrivate(), parent)
{
setRequest(request);
setUrl(request.url());
setOperation(operation);
QNetworkReply::open(QIODevice::ReadOnly);
QNetworkReplyNSURLConnectionImplPrivate *d = (QNetworkReplyNSURLConnectionImplPrivate*) d_func();
QUrl url = request.url();
if (url.host() == QLatin1String("localhost"))
url.setHost(QString());
if (url.path().isEmpty())
url.setPath(QLatin1String("/"));
setUrl(url);
// Create a NSMutableURLRequest from QNetworkRequest
NSMutableURLRequest *nsRequest = [NSMutableURLRequest requestWithURL:request.url().toNSURL()
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// copy headers
const auto headers = request.rawHeaderList();
for (const QByteArray &header : headers) {
QByteArray headerValue = request.rawHeader(header);
[nsRequest addValue:QString::fromUtf8(headerValue).toNSString()
forHTTPHeaderField:QString::fromUtf8(header).toNSString()];
}
if (operation == QNetworkAccessManager::GetOperation)
[nsRequest setHTTPMethod:@"GET"];
else if (operation == QNetworkAccessManager::PostOperation)
[nsRequest setHTTPMethod:@"POST"];
else if (operation == QNetworkAccessManager::PutOperation)
[nsRequest setHTTPMethod:@"PUT"];
else if (operation == QNetworkAccessManager::DeleteOperation)
[nsRequest setHTTPMethod:@"DELETE"];
else
qWarning() << "QNetworkReplyNSURLConnection: Unsupported netork operation" << operation;
if (outgoingData) {
d->outgoingData = outgoingData;
if (outgoingData->isSequential()) {
// set up streaming from outgoingData iodevice to request
CFStreamCreateBoundPair(kCFAllocatorDefault, &d->readStream, &d->writeStream, d->transferBufferSize);
CFWriteStreamOpen(d->writeStream);
[nsRequest setHTTPBodyStream:reinterpret_cast<NSInputStream *>(d->readStream)];
connect(outgoingData, SIGNAL(readyRead()), this, SLOT(readyReadOutgoingData()));
readyReadOutgoingData();
} else {
// move all data at once
QByteArray data = outgoingData->readAll();
[nsRequest setHTTPBody:[NSData dataWithBytes:data.constData() length:data.length()]];
}
}
// Create connection
d->urlConnectionDelegate = [[QtNSURLConnectionDelegate alloc] initWithQNetworkReplyNSURLConnectionImplPrivate:d];
d->urlConnection = [[NSURLConnection alloc] initWithRequest:nsRequest delegate:d->urlConnectionDelegate];
if (!d->urlConnection) {
// ### what type of error is an initWithRequest fail?
setError(QNetworkReply::ProtocolUnknownError, QStringLiteral("QNetworkReplyNSURLConnection internal error"));
}
}
void QNetworkReplyNSURLConnectionImpl::close()
{
// No-op? Network ops should continue (especially POSTs)
QNetworkReply::close();
}
void QNetworkReplyNSURLConnectionImpl::abort()
{
Q_D(QNetworkReplyNSURLConnectionImpl);
[d->urlConnection cancel];
QNetworkReply::close();
}
qint64 QNetworkReplyNSURLConnectionImpl::bytesAvailable() const
{
Q_D(const QNetworkReplyNSURLConnectionImpl);
qint64 available = QNetworkReply::bytesAvailable() +
[[d->urlConnectionDelegate responseData] length];
return available;
}
bool QNetworkReplyNSURLConnectionImpl::isSequential() const
{
return true;
}
qint64 QNetworkReplyNSURLConnectionImpl::size() const
{
Q_D(const QNetworkReplyNSURLConnectionImpl);
return [[d->urlConnectionDelegate responseData] length] + d->bytesRead;
}
/*!
\internal
*/
qint64 QNetworkReplyNSURLConnectionImpl::readData(char *data, qint64 maxlen)
{
Q_D(QNetworkReplyNSURLConnectionImpl);
qint64 dataSize = [[d->urlConnectionDelegate responseData] length];
qint64 canRead = qMin(maxlen, dataSize);
const char *sourceBase = static_cast<const char *>([[d->urlConnectionDelegate responseData] bytes]);
memcpy(data, sourceBase, canRead);
[[d->urlConnectionDelegate responseData] replaceBytesInRange:NSMakeRange(0, canRead) withBytes:NULL length:0];
d->bytesRead += canRead;
return canRead;
}
QT_END_NAMESPACE

View File

@ -1,87 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QNETWORKREPLYNSURLCONNECTIONIMPL_H
#define QNETWORKREPLYNSURLCONNECTIONIMPL_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of the Network Access API. This header file may change from
// version to version without notice, or even be removed.
//
// We mean it.
//
#include "qnetworkreply.h"
#include "qnetworkreply_p.h"
#include "qnetworkaccessmanager.h"
#include <QFile>
#include <private/qabstractfileengine_p.h>
QT_BEGIN_NAMESPACE
class QNetworkReplyNSURLConnectionImplPrivate;
class QNetworkReplyNSURLConnectionImpl: public QNetworkReply
{
Q_OBJECT
public:
QNetworkReplyNSURLConnectionImpl(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op, QIODevice* outgoingData);
virtual ~QNetworkReplyNSURLConnectionImpl();
virtual void abort();
// reimplemented from QNetworkReply
virtual void close();
virtual qint64 bytesAvailable() const;
virtual bool isSequential () const;
qint64 size() const;
virtual qint64 readData(char *data, qint64 maxlen);
public Q_SLOTS:
void readyReadOutgoingData();
Q_DECLARE_PRIVATE(QNetworkReplyNSURLConnectionImpl)
};
QT_END_NAMESPACE
#endif // QNetworkReplyNSURLConnectionImpl_H

View File

@ -47,7 +47,9 @@
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <arpa/nameser_compat.h>
#if !defined(Q_OS_OPENBSD)
# include <arpa/nameser_compat.h>
#endif
#include <resolv.h>
#if defined(__GNU_LIBRARY__) && !defined(__UCLIBC__)
@ -58,6 +60,9 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_LIBRARY
#if defined(Q_OS_OPENBSD)
typedef struct __res_state* res_state;
#endif
typedef int (*dn_expand_proto)(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
static dn_expand_proto local_dn_expand = 0;
typedef void (*res_nclose_proto)(res_state);

View File

@ -560,7 +560,9 @@ int QNativeSocketEnginePrivate::nativeAccept()
setError(QAbstractSocket::SocketResourceError, NotSocketErrorString);
break;
case EPROTONOSUPPORT:
#if !defined(Q_OS_OPENBSD)
case EPROTO:
#endif
case EAFNOSUPPORT:
case EINVAL:
setError(QAbstractSocket::UnsupportedSocketOperationError, ProtocolUnsupportedErrorString);
@ -900,7 +902,9 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS
if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_RECVIF
&& cmsgptr->cmsg_len >= CMSG_LEN(sizeof(sockaddr_dl))) {
sockaddr_dl *sdl = reinterpret_cast<sockaddr_dl *>(CMSG_DATA(cmsgptr));
# if defined(Q_OS_OPENBSD)
# define LLINDEX(s) ((s)->sdl_index)
# endif
header->ifindex = LLINDEX(sdl);
}
# endif

View File

@ -337,7 +337,7 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port)
d->socketState = QAbstractSocket::ConnectingState;
hr = QEventDispatcherWinRT::runOnXamlThread([d]() {
return d->connectOp->put_Completed(Callback<IAsyncActionCompletedHandler>(
d, &QNativeSocketEnginePrivate::handleConnectToHost).Get());
d, &QNativeSocketEnginePrivate::handleConnectOpFinished).Get());
});
Q_ASSERT_SUCCEEDED(hr);
@ -477,7 +477,10 @@ void QNativeSocketEngine::close()
hr = socket3->CancelIOAsync(&action);
Q_ASSERT_SUCCEEDED(hr);
hr = QWinRTFunctions::await(action);
Q_ASSERT_SUCCEEDED(hr);
// If there is no pending IO (no read established before) the function will fail with
// "function was called at an unexpected time" which is fine.
if (hr != E_ILLEGAL_METHOD_CALL)
Q_ASSERT_SUCCEEDED(hr);
return S_OK;
});
Q_ASSERT_SUCCEEDED(hr);
@ -759,7 +762,7 @@ bool QNativeSocketEngine::waitForWrite(int msecs, bool *timedOut)
if (d->socketState == QAbstractSocket::ConnectingState) {
HRESULT hr = QWinRTFunctions::await(d->connectOp, QWinRTFunctions::ProcessMainThreadEvents);
if (SUCCEEDED(hr)) {
d->handleConnectionEstablished(d->connectOp.Get());
d->handleConnectOpFinished(d->connectOp.Get(), Completed);
return true;
}
}
@ -1214,38 +1217,32 @@ HRESULT QNativeSocketEnginePrivate::handleClientConnection(IStreamSocketListener
return S_OK;
}
HRESULT QNativeSocketEnginePrivate::handleConnectToHost(IAsyncAction *action, AsyncStatus)
{
handleConnectionEstablished(action);
return S_OK;
}
void QNativeSocketEnginePrivate::handleConnectionEstablished(IAsyncAction *action)
HRESULT QNativeSocketEnginePrivate::handleConnectOpFinished(IAsyncAction *action, AsyncStatus)
{
Q_Q(QNativeSocketEngine);
if (wasDeleted || !connectOp) // Protect against a late callback
return;
return S_OK;
HRESULT hr = action->GetResults();
switch (hr) {
case 0x8007274c: // A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString);
socketState = QAbstractSocket::UnconnectedState;
break;
return S_OK;
case 0x80072751: // A socket operation was attempted to an unreachable host.
setError(QAbstractSocket::HostNotFoundError, HostUnreachableErrorString);
socketState = QAbstractSocket::UnconnectedState;
break;
return S_OK;
case 0x8007274d: // No connection could be made because the target machine actively refused it.
setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString);
socketState = QAbstractSocket::UnconnectedState;
break;
return S_OK;
default:
if (FAILED(hr)) {
setError(QAbstractSocket::UnknownSocketError, UnknownSocketErrorString);
socketState = QAbstractSocket::UnconnectedState;
return S_OK;
}
break;
}
// The callback might be triggered several times if we do not cancel/reset it here
@ -1267,13 +1264,14 @@ void QNativeSocketEnginePrivate::handleConnectionEstablished(IAsyncAction *actio
emit q->connectionReady();
if (socketType != QAbstractSocket::TcpSocket)
return;
return S_OK;
// Delay the reader so that the SSL socket can upgrade
if (sslSocket)
QObject::connect(qobject_cast<QSslSocket *>(sslSocket), &QSslSocket::encrypted, q, &QNativeSocketEngine::establishRead);
else
q->establishRead();
return S_OK;
}
HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status)

View File

@ -220,8 +220,7 @@ private:
ABI::Windows::Networking::Sockets::IDatagramSocketMessageReceivedEventArgs *args);
HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener,
ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args);
HRESULT handleConnectToHost(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus);
void handleConnectionEstablished(ABI::Windows::Foundation::IAsyncAction *action);
HRESULT handleConnectOpFinished(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus);
HRESULT handleReadyRead(ABI::Windows::Foundation::IAsyncOperationWithProgress<ABI::Windows::Storage::Streams::IBuffer *, UINT32> *asyncInfo, ABI::Windows::Foundation::AsyncStatus);
};

View File

@ -1122,7 +1122,9 @@ bool QSocks5SocketEngine::connectInternal()
}
if (d->socketState != QAbstractSocket::ConnectingState) {
if (d->socks5State == QSocks5SocketEnginePrivate::Uninitialized) {
if (d->socks5State == QSocks5SocketEnginePrivate::Uninitialized
// We may have new auth credentials since an earlier failure:
|| d->socks5State == QSocks5SocketEnginePrivate::AuthenticatingError) {
setState(QAbstractSocket::ConnectingState);
//limit buffer in internal socket, data is buffered in the external socket under application control
d->data->controlSocket->setReadBufferSize(65536);

View File

@ -2632,7 +2632,8 @@ QList<QByteArray> QSslSocketPrivate::unixRootCertDirectories()
<< "/var/ssl/certs/" // AIX
<< "/usr/local/ssl/certs/" // Solaris
<< "/etc/openssl/certs/" // BlackBerry
<< "/opt/openssl/certs/"; // HP-UX
<< "/opt/openssl/certs/" // HP-UX
<< "/etc/ssl/"; // OpenBSD
}
/*!

View File

@ -80,6 +80,19 @@
\sa QXcbWindowFunctions QWindowsWindowFunctions
\section1 Getting Started
To include the definitions of the module's functions and classes, use the following directives:
\code
#include <QtPlatformHeaders/QWindowsWindowFunctions>
#include <QtPlatformHeaders/QXcbWindowFunctions>
\endcode
As the module is header-only, no further modifications to the .pro files are required to use it.
\note The module name (\c QtPlatformHeaders) must appear in the \c #include directive.
\note It is not necessary to enclose the code in \c #ifdef directives depending on platform.
\section1 API Reference
\list
\li \l{Qt Platform Headers C++ Classes}{C++ Classes}

View File

@ -1,18 +1,14 @@
HEADERS += $$PWD/qdevicediscovery_p.h
linux {
contains(QT_CONFIG, libudev) {
SOURCES += $$PWD/qdevicediscovery_udev.cpp
HEADERS += $$PWD/qdevicediscovery_udev_p.h
INCLUDEPATH += $$QMAKE_INCDIR_LIBUDEV
LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV
} else: contains(QT_CONFIG, evdev) {
SOURCES += $$PWD/qdevicediscovery_static.cpp
HEADERS += $$PWD/qdevicediscovery_static_p.h
} else {
SOURCES += $$PWD/qdevicediscovery_dummy.cpp
HEADERS += $$PWD/qdevicediscovery_dummy_p.h
}
contains(QT_CONFIG, libudev) {
SOURCES += $$PWD/qdevicediscovery_udev.cpp
HEADERS += $$PWD/qdevicediscovery_udev_p.h
INCLUDEPATH += $$QMAKE_INCDIR_LIBUDEV
LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV
} else: contains(QT_CONFIG, evdev) {
SOURCES += $$PWD/qdevicediscovery_static.cpp
HEADERS += $$PWD/qdevicediscovery_static_p.h
} else {
SOURCES += $$PWD/qdevicediscovery_dummy.cpp
HEADERS += $$PWD/qdevicediscovery_dummy_p.h
}

View File

@ -587,6 +587,10 @@ int q_screenDepthFromFb(int framebufferDevice)
qreal q_refreshRateFromFb(int framebufferDevice)
{
#ifndef Q_OS_LINUX
Q_UNUSED(framebufferDevice)
#endif
static qreal rate = 0;
#ifdef Q_OS_LINUX

View File

@ -60,7 +60,7 @@ Q_LOGGING_CATEGORY(qLcEvdevKeyMap, "qt.qpa.input.keymap")
#include "qevdevkeyboard_defaultmap_p.h"
QEvdevKeyboardHandler::QEvdevKeyboardHandler(const QString &device, int fd, bool disableZap, bool enableCompose, const QString &keymapFile)
: m_device(device), m_fd(fd),
: m_device(device), m_fd(fd), m_notify(Q_NULLPTR),
m_modifiers(0), m_composing(0), m_dead_unicode(0xffff),
m_no_zap(disableZap), m_do_compose(enableCompose),
m_keymap(0), m_keymap_size(0), m_keycompose(0), m_keycompose_size(0)
@ -75,9 +75,8 @@ QEvdevKeyboardHandler::QEvdevKeyboardHandler(const QString &device, int fd, bool
unloadKeymap();
// socket notifier for events on the keyboard device
QSocketNotifier *notifier;
notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
connect(notifier, SIGNAL(activated(int)), this, SLOT(readKeycode()));
m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
connect(m_notify, SIGNAL(activated(int)), this, SLOT(readKeycode()));
}
QEvdevKeyboardHandler::~QEvdevKeyboardHandler()
@ -162,6 +161,14 @@ void QEvdevKeyboardHandler::readKeycode()
} else if (result < 0) {
if (errno != EINTR && errno != EAGAIN) {
qErrnoWarning(errno, "evdevkeyboard: Could not read from input device");
// If the device got disconnected, stop reading, otherwise we get flooded
// by the above error over and over again.
if (errno == ENODEV) {
delete m_notify;
m_notify = Q_NULLPTR;
qt_safe_close(m_fd);
m_fd = -1;
}
return;
}
} else {

View File

@ -57,6 +57,8 @@
QT_BEGIN_NAMESPACE
class QSocketNotifier;
namespace QEvdevKeyboardMap {
const quint32 FileMagic = 0x514d4150; // 'QMAP'
@ -186,6 +188,7 @@ private:
QString m_device;
int m_fd;
QSocketNotifier *m_notify;
// keymap handling
quint8 m_modifiers;

View File

@ -111,9 +111,8 @@ QEvdevMouseHandler::QEvdevMouseHandler(const QString &device, int fd, bool abs,
m_abs = getHardwareMaximum();
// socket notifier for events on the mouse device
QSocketNotifier *notifier;
notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
connect(notifier, SIGNAL(activated(int)), this, SLOT(readMouseData()));
m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData()));
}
QEvdevMouseHandler::~QEvdevMouseHandler()
@ -202,6 +201,14 @@ void QEvdevMouseHandler::readMouseData()
} else if (result < 0) {
if (errno != EINTR && errno != EAGAIN) {
qErrnoWarning(errno, "evdevmouse: Could not read from input device");
// If the device got disconnected, stop reading, otherwise we get flooded
// by the above error over and over again.
if (errno == ENODEV) {
delete m_notify;
m_notify = Q_NULLPTR;
qt_safe_close(m_fd);
m_fd = -1;
}
return;
}
} else {

View File

@ -21,7 +21,11 @@ include(accessibility/accessibility.pri)
include(linuxaccessibility/linuxaccessibility.pri)
include(clipboard/clipboard.pri)
include(platformcompositor/platformcompositor.pri)
contains(QT_CONFIG, dbus) {
# dbus convenience, but not for darwin: the platform
# plugins for these platforms do not use dbus and we
# don't want to create a false dependency.
!darwin: contains(QT_CONFIG, dbus) {
include(dbusmenu/dbusmenu.pri)
include(dbustray/dbustray.pri)
}

View File

@ -153,7 +153,7 @@ static bool isMouseEvent(NSEvent *ev)
if (NSMouseInRect(loc, windowFrame, NO) &&
!NSMouseInRect(loc, contentFrame, NO))
{
QNSView *contentView = (QNSView *)pw->contentView();
QNSView *contentView = pw->m_qtView;
[contentView handleFrameStrutMouseEvent: theEvent];
}
}
@ -1188,7 +1188,11 @@ NSView *QCocoaWindow::contentView() const
void QCocoaWindow::setContentView(NSView *contentView)
{
// Remove and release the previous content view
[m_contentView removeFromSuperview];
if (m_nsWindow)
[m_nsWindow setContentView:nil];
else
[m_contentView removeFromSuperview];
[m_contentView release];
// Insert and retain the new content view

View File

@ -663,7 +663,9 @@ QT_WARNING_POP
- (BOOL)becomeFirstResponder
{
if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) )
if (!m_window || !m_platformWindow)
return NO;
if (m_window->flags() & Qt::WindowTransparentForInput)
return NO;
if (!m_platformWindow->windowIsPopupType() && !m_isMenuView)
QWindowSystemInterface::handleWindowActivated([self topLevelWindow]);
@ -672,11 +674,13 @@ QT_WARNING_POP
- (BOOL)acceptsFirstResponder
{
if (!m_window || !m_platformWindow)
return NO;
if (m_isMenuView)
return NO;
if (m_platformWindow->shouldRefuseKeyWindowAndFirstResponder())
return NO;
if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) )
if (m_window->flags() & Qt::WindowTransparentForInput)
return NO;
if ((m_window->flags() & Qt::ToolTip) == Qt::ToolTip)
return NO;
@ -686,7 +690,9 @@ QT_WARNING_POP
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
Q_UNUSED(theEvent)
if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) )
if (!m_window || !m_platformWindow)
return NO;
if (m_window->flags() & Qt::WindowTransparentForInput)
return NO;
return YES;
}
@ -2199,7 +2205,11 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
// keep our state, and QGuiApplication state (buttons member) in-sync,
// or future mouse events will be processed incorrectly
m_buttons &= ~(m_sendUpAsRightButton ? Qt::RightButton : Qt::LeftButton);
NSUInteger pmb = [NSEvent pressedMouseButtons];
for (int buttonNumber = 0; buttonNumber < 32; buttonNumber++) { // see cocoaButton2QtButton() for the 32 value
if (!(pmb & (1 << buttonNumber)))
m_buttons &= ~cocoaButton2QtButton(buttonNumber);
}
NSPoint windowPoint = [self convertPoint: point fromView: nil];
QPoint qtWindowPoint(windowPoint.x, windowPoint.y);

View File

@ -132,7 +132,7 @@ void QEglFSKmsGbmCursor::updateMouseStatus()
m_state = visible ? CursorPendingVisible : CursorPendingHidden;
#ifndef QT_NO_CURSOR
changeCursor(nullptr, m_screen->topLevelAt(pos()));
changeCursor(Q_NULLPTR, m_screen->topLevelAt(pos()));
#endif
}

View File

@ -42,6 +42,7 @@
#include <UIKit/UIKit.h>
#include <QtCore/qlocale.h>
#include <QtGui/qevent.h>
#include <QtGui/qtransform.h>
#include <qpa/qplatforminputcontext.h>
@ -52,6 +53,7 @@ const char kImePlatformDataReturnKeyType[] = "returnKeyType";
QT_BEGIN_NAMESPACE
@class QIOSLocaleListener;
@class QIOSKeyboardListener;
@class QIOSTextInputResponder;
@protocol KeyboardState;
@ -98,6 +100,8 @@ public:
void reset() Q_DECL_OVERRIDE;
void commit() Q_DECL_OVERRIDE;
QLocale locale() const Q_DECL_OVERRIDE;
void clearCurrentFocusObject();
void setFocusObject(QObject *object) Q_DECL_OVERRIDE;
@ -118,6 +122,7 @@ public:
private:
UIView* scrollableRootView();
QIOSLocaleListener *m_localeListener;
QIOSKeyboardListener *m_keyboardHideGesture;
QIOSTextInputResponder *m_textResponder;
KeyboardState m_keyboardState;

View File

@ -62,6 +62,39 @@ static QUIView *focusView()
// -------------------------------------------------------------------------
@interface QIOSLocaleListener : NSObject
@end
@implementation QIOSLocaleListener
- (id)init
{
if (self = [super init]) {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self
selector:@selector(localeDidChange:)
name:NSCurrentLocaleDidChangeNotification object:nil];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (void)localeDidChange:(NSNotification *)notification
{
Q_UNUSED(notification);
QIOSInputContext::instance()->emitLocaleChanged();
}
@end
// -------------------------------------------------------------------------
@interface QIOSKeyboardListener : UIGestureRecognizer <UIGestureRecognizerDelegate> {
@private
QIOSInputContext *m_context;
@ -291,6 +324,7 @@ QIOSInputContext *QIOSInputContext::instance()
QIOSInputContext::QIOSInputContext()
: QPlatformInputContext()
, m_localeListener([QIOSLocaleListener new])
, m_keyboardHideGesture([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this])
, m_textResponder(0)
{
@ -304,6 +338,7 @@ QIOSInputContext::QIOSInputContext()
QIOSInputContext::~QIOSInputContext()
{
[m_localeListener release];
[m_keyboardHideGesture.view removeGestureRecognizer:m_keyboardHideGesture];
[m_keyboardHideGesture release];
@ -663,3 +698,8 @@ void QIOSInputContext::commit()
[m_textResponder unmarkText];
[m_textResponder notifyInputDelegate:Qt::ImSurroundingText];
}
QLocale QIOSInputContext::locale() const
{
return QLocale(QString::fromNSString([[NSLocale currentLocale] objectForKey:NSLocaleIdentifier]));
}

View File

@ -359,6 +359,7 @@
- (void)sendKeyPressRelease:(Qt::Key)key modifiers:(Qt::KeyboardModifiers)modifiers
{
QScopedValueRollback<BOOL> rollback(m_inSendEventToFocusObject, true);
QWindowSystemInterface::handleKeyEvent(qApp->focusWindow(), QEvent::KeyPress, key, modifiers);
QWindowSystemInterface::handleKeyEvent(qApp->focusWindow(), QEvent::KeyRelease, key, modifiers);
QWindowSystemInterface::flushWindowSystemEvents();

View File

@ -11,6 +11,7 @@ HEADERS = qminimalintegration.h \
OTHER_FILES += minimal.json
CONFIG += qpa/genericunixfontdatabase
darwin: DEFINES += QT_NO_FONTCONFIG
PLUGIN_TYPE = platforms
PLUGIN_CLASS_NAME = QMinimalIntegrationPlugin

View File

@ -2,9 +2,9 @@ TEMPLATE = subdirs
android: SUBDIRS += android
SUBDIRS += minimal
!android: SUBDIRS += minimal
!win32|contains(QT_CONFIG, freetype):SUBDIRS += offscreen
!android:if(!win32|contains(QT_CONFIG, freetype)): SUBDIRS += offscreen
contains(QT_CONFIG, xcb) {
SUBDIRS += xcb

View File

@ -205,6 +205,45 @@ QWindowsEGLStaticContext::QWindowsEGLStaticContext(EGLDisplay display)
{
}
bool QWindowsEGLStaticContext::initializeAngle(QWindowsOpenGLTester::Renderers preferredType, HDC dc,
EGLDisplay *display, EGLint *major, EGLint *minor)
{
#ifdef EGL_ANGLE_platform_angle
if (libEGL.eglGetPlatformDisplayEXT
&& (preferredType & QWindowsOpenGLTester::AngleBackendMask)) {
const EGLint anglePlatformAttributes[][5] = {
{ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_NONE },
{ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_NONE },
{ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, EGL_NONE }
};
const EGLint *attributes = 0;
if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11)
attributes = anglePlatformAttributes[0];
else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d9)
attributes = anglePlatformAttributes[1];
else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11Warp)
attributes = anglePlatformAttributes[2];
if (attributes) {
*display = libEGL.eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, attributes);
if (!libEGL.eglInitialize(*display, major, minor)) {
libEGL.eglTerminate(*display);
*display = EGL_NO_DISPLAY;
*major = *minor = 0;
return false;
}
}
}
#else // EGL_ANGLE_platform_angle
Q_UNUSED(preferredType);
Q_UNUSED(dc);
Q_UNUSED(display);
Q_UNUSED(major);
Q_UNUSED(minor);
#endif
return true;
}
QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester::Renderers preferredType)
{
const HDC dc = QWindowsContext::instance()->displayContext();
@ -225,33 +264,13 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester:
EGLDisplay display = EGL_NO_DISPLAY;
EGLint major = 0;
EGLint minor = 0;
#ifdef EGL_ANGLE_platform_angle
if (libEGL.eglGetPlatformDisplayEXT
&& (preferredType & QWindowsOpenGLTester::AngleBackendMask)) {
const EGLint anglePlatformAttributes[][5] = {
{ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_NONE },
{ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_NONE },
{ EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE, EGL_NONE }
};
const EGLint *attributes = 0;
if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11)
attributes = anglePlatformAttributes[0];
else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d9)
attributes = anglePlatformAttributes[1];
else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11Warp)
attributes = anglePlatformAttributes[2];
if (attributes) {
display = libEGL.eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, attributes);
if (!libEGL.eglInitialize(display, &major, &minor)) {
display = EGL_NO_DISPLAY;
major = minor = 0;
}
}
if (!initializeAngle(preferredType, dc, &display, &major, &minor)
&& (preferredType & QWindowsOpenGLTester::AngleRendererD3d11)) {
preferredType &= ~QWindowsOpenGLTester::AngleRendererD3d11;
initializeAngle(preferredType, dc, &display, &major, &minor);
}
#else // EGL_ANGLE_platform_angle
Q_UNUSED(preferredType)
#endif
if (display == EGL_NO_DISPLAY)
display = libEGL.eglGetDisplay(dc);
if (!display) {

View File

@ -131,6 +131,8 @@ public:
private:
explicit QWindowsEGLStaticContext(EGLDisplay display);
static bool initializeAngle(QWindowsOpenGLTester::Renderers preferredType, HDC dc,
EGLDisplay *display, EGLint *major, EGLint *minor);
const EGLDisplay m_display;
};

View File

@ -1346,8 +1346,7 @@ QFontEngine *QWindowsMultiFontEngine::loadEngine(int at)
QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace,
fontEngine->fontDef.pixelSize,
data);
if (fontEngine->fontDef.weight > QFont::Normal)
fedw->fontDef.weight = fontEngine->fontDef.weight;
fedw->fontDef.weight = fontEngine->fontDef.weight;
if (fontEngine->fontDef.style > QFont::StyleNormal)
fedw->fontDef.style = fontEngine->fontDef.style;
fedw->fontDef.family = fam;
@ -1364,8 +1363,7 @@ QFontEngine *QWindowsMultiFontEngine::loadEngine(int at)
// reason
QFontEngine *fe = new QWindowsFontEngine(fam, lf, data);
if (fontEngine->fontDef.weight > QFont::Normal)
fe->fontDef.weight = fontEngine->fontDef.weight;
fe->fontDef.weight = fontEngine->fontDef.weight;
if (fontEngine->fontDef.style > QFont::StyleNormal)
fe->fontDef.style = fontEngine->fontDef.style;
fe->fontDef.family = fam;

View File

@ -138,7 +138,16 @@ public:
explicit ShGetFileInfoFunction(const wchar_t *fn, DWORD a, SHFILEINFO *i, UINT f, bool *r) :
m_fileName(fn), m_attributes(a), m_flags(f), m_info(i), m_result(r) {}
void operator()() const { *m_result = SHGetFileInfo(m_fileName, m_attributes, m_info, sizeof(SHFILEINFO), m_flags); }
void operator()() const
{
#ifndef Q_OS_WINCE
const UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
#endif
*m_result = SHGetFileInfo(m_fileName, m_attributes, m_info, sizeof(SHFILEINFO), m_flags);
#ifndef Q_OS_WINCE
SetErrorMode(oldErrorMode);
#endif
}
private:
const wchar_t *m_fileName;

View File

@ -1677,12 +1677,13 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
return false;
PAINTSTRUCT ps;
// Observed painting problems with Aero style disabled (QTBUG-7865).
if (testFlag(OpenGLSurface) && testFlag(OpenGLDoubleBuffered))
InvalidateRect(hwnd, 0, false);
BeginPaint(hwnd, &ps);
// Observed painting problems with Aero style disabled (QTBUG-7865).
// 5.8: Consider making it dependent on !DwmIsCompositionEnabled().
if (testFlag(OpenGLSurface) && testFlag(OpenGLDoubleBuffered))
SelectClipRgn(ps.hdc, NULL);
// If the a window is obscured by another window (such as a child window)
// we still need to send isExposed=true, for compatibility.
// Our tests depend on it.

View File

@ -0,0 +1,893 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwinrtdrag.h"
#include <QtCore/qglobal.h>
#include <QtCore/QMimeData>
#include <QtCore/QStringList>
#include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface.h>
#include <qfunctions_winrt.h>
#include <private/qeventdispatcher_winrt_p.h>
#include <Windows.ApplicationModel.datatransfer.h>
#include <windows.ui.xaml.h>
#include <windows.foundation.collections.h>
#include <windows.graphics.imaging.h>
#include <windows.storage.streams.h>
#include <functional>
#include <robuffer.h>
using namespace ABI::Windows::ApplicationModel::DataTransfer;
using namespace ABI::Windows::ApplicationModel::DataTransfer::DragDrop;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::Graphics::Imaging;
using namespace ABI::Windows::Storage;
using namespace ABI::Windows::Storage::Streams;
using namespace ABI::Windows::UI::Xaml;
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaMime, "qt.qpa.mime")
ComPtr<IBuffer> createIBufferFromData(const char *data, qint32 size)
{
static ComPtr<IBufferFactory> bufferFactory;
HRESULT hr;
if (!bufferFactory) {
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(),
IID_PPV_ARGS(&bufferFactory));
Q_ASSERT_SUCCEEDED(hr);
}
ComPtr<IBuffer> buffer;
const UINT32 length = size;
hr = bufferFactory->Create(length, &buffer);
Q_ASSERT_SUCCEEDED(hr);
hr = buffer->put_Length(length);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
hr = buffer.As(&byteArrayAccess);
Q_ASSERT_SUCCEEDED(hr);
byte *bytes;
hr = byteArrayAccess->Buffer(&bytes);
Q_ASSERT_SUCCEEDED(hr);
memcpy(bytes, data, length);
return buffer;
}
class DragThreadTransferData : public QObject
{
Q_OBJECT
public slots:
void handleDrag();
public:
explicit DragThreadTransferData(QObject *parent = Q_NULLPTR);
QWindow *window;
QWinRTInternalMimeData *mime;
QPoint point;
Qt::DropActions actions;
bool dropAction;
ComPtr<IDragEventArgs> nativeArgs;
ComPtr<IDragOperationDeferral> deferral;
};
inline QString hStringToQString(const HString &hString)
{
quint32 l;
const wchar_t *raw = hString.GetRawBuffer(&l);
return (QString::fromWCharArray(raw, l));
}
inline HString qStringToHString(const QString &qString)
{
HString h;
h.Set(reinterpret_cast<const wchar_t*>(qString.utf16()), qString.size());
return h;
}
namespace NativeFormatStrings {
static ComPtr<IStandardDataFormatsStatics> dataStatics;
static HSTRING text; // text/plain
static HSTRING html; // text/html
static HSTRING storage; // text/uri-list
}
static inline DataPackageOperation translateFromQDragDropActions(const Qt::DropAction action)
{
switch (action) {
case Qt::CopyAction:
return DataPackageOperation_Copy;
case Qt::MoveAction:
return DataPackageOperation_Move;
case Qt::LinkAction:
return DataPackageOperation_Link;
case Qt::IgnoreAction:
default:
return DataPackageOperation_None;
}
}
static inline Qt::DropActions translateToQDragDropActions(const DataPackageOperation op)
{
Qt::DropActions actions = Qt::IgnoreAction;
// None needs to be interpreted as the sender being able to handle
// anything and let the receiver decide
if (op == DataPackageOperation_None)
actions = Qt::LinkAction | Qt::CopyAction | Qt::MoveAction;
if (op & DataPackageOperation_Link)
actions |= Qt::LinkAction;
if (op & DataPackageOperation_Copy)
actions |= Qt::CopyAction;
if (op & DataPackageOperation_Move)
actions |= Qt::MoveAction;
return actions;
}
QWinRTInternalMimeData::QWinRTInternalMimeData()
: QInternalMimeData()
{
qCDebug(lcQpaMime) << __FUNCTION__;
if (!NativeFormatStrings::dataStatics) {
HRESULT hr;
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_StandardDataFormats).Get(),
IID_PPV_ARGS(&NativeFormatStrings::dataStatics));
Q_ASSERT_SUCCEEDED(hr);
hr = NativeFormatStrings::dataStatics->get_Text(&NativeFormatStrings::text);
Q_ASSERT_SUCCEEDED(hr);
hr = NativeFormatStrings::dataStatics->get_Html(&NativeFormatStrings::html);
Q_ASSERT_SUCCEEDED(hr);
hr = NativeFormatStrings::dataStatics->get_StorageItems(&NativeFormatStrings::storage);
Q_ASSERT_SUCCEEDED(hr);
}
}
QWinRTInternalMimeData::~QWinRTInternalMimeData()
{
}
bool QWinRTInternalMimeData::hasFormat_sys(const QString &mimetype) const
{
qCDebug(lcQpaMime) << __FUNCTION__ << mimetype;
if (!dataView)
return false;
return formats_sys().contains(mimetype);
}
QStringList QWinRTInternalMimeData::formats_sys() const
{
qCDebug(lcQpaMime) << __FUNCTION__;
if (!dataView)
return QStringList();
if (!formats.isEmpty())
return formats;
HRESULT hr;
hr = QEventDispatcherWinRT::runOnXamlThread([this]() {
boolean contains;
HRESULT hr;
hr = dataView->Contains(NativeFormatStrings::text, &contains);
if (SUCCEEDED(hr) && contains)
formats.append(QLatin1String("text/plain"));
hr = dataView->Contains(NativeFormatStrings::html, &contains);
if (SUCCEEDED(hr) && contains)
formats.append(QLatin1String("text/html"));
hr = dataView->Contains(NativeFormatStrings::storage, &contains);
if (SUCCEEDED(hr) && contains)
formats.append(QLatin1String("text/uri-list"));
// We need to add any additional format as well, for legacy windows
// reasons, but also in case someone adds custom formats.
ComPtr<IVectorView<HSTRING>> availableFormats;
hr = dataView->get_AvailableFormats(&availableFormats);
RETURN_OK_IF_FAILED("Could not query available formats.");
quint32 size;
hr = availableFormats->get_Size(&size);
RETURN_OK_IF_FAILED("Could not query format vector size.");
for (quint32 i = 0; i < size; ++i) {
HString str;
hr = availableFormats->GetAt(i, str.GetAddressOf());
if (FAILED(hr))
continue;
formats.append(hStringToQString(str));
}
return S_OK;
});
Q_ASSERT_SUCCEEDED(hr);
return formats;
}
QVariant QWinRTInternalMimeData::retrieveData_sys(const QString &mimetype, QVariant::Type preferredType) const
{
qCDebug(lcQpaMime) << __FUNCTION__ << mimetype << preferredType;
if (!dataView || !formats.contains(mimetype))
return QVariant();
QVariant result;
HRESULT hr;
if (mimetype == QLatin1String("text/plain")) {
hr = QEventDispatcherWinRT::runOnXamlThread([this, &result]() {
HRESULT hr;
ComPtr<IAsyncOperation<HSTRING>> op;
HString res;
hr = dataView->GetTextAsync(&op);
Q_ASSERT_SUCCEEDED(hr);
hr = QWinRTFunctions::await(op, res.GetAddressOf());
Q_ASSERT_SUCCEEDED(hr);
result.setValue(hStringToQString(res));
return S_OK;
});
} else if (mimetype == QLatin1String("text/uri-list")) {
hr = QEventDispatcherWinRT::runOnXamlThread([this, &result]() {
HRESULT hr;
ComPtr<IAsyncOperation<IVectorView<IStorageItem*>*>> op;
hr = dataView->GetStorageItemsAsync(&op);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IVectorView<IStorageItem*>> nativeItems;
hr = QWinRTFunctions::await(op, nativeItems.GetAddressOf());
Q_ASSERT_SUCCEEDED(hr);
QList<QVariant> items;
quint32 count;
hr = nativeItems->get_Size(&count);
for (quint32 i = 0; i < count; ++i) {
ComPtr<IStorageItem> item;
hr = nativeItems->GetAt(i, &item);
Q_ASSERT_SUCCEEDED(hr);
HString path;
hr = item->get_Path(path.GetAddressOf());
Q_ASSERT_SUCCEEDED(hr);
items.append(QUrl::fromLocalFile(hStringToQString(path)));
}
result.setValue(items);
return S_OK;
});
} else if (mimetype == QLatin1String("text/html")) {
hr = QEventDispatcherWinRT::runOnXamlThread([this, &result]() {
HRESULT hr;
ComPtr<IAsyncOperation<HSTRING>> op;
HString res;
hr = dataView->GetHtmlFormatAsync(&op);
Q_ASSERT_SUCCEEDED(hr);
hr = QWinRTFunctions::await(op, res.GetAddressOf());
Q_ASSERT_SUCCEEDED(hr);
result.setValue(hStringToQString(res));
return S_OK;
});
} else {
// Asking for custom data
hr = QEventDispatcherWinRT::runOnXamlThread([this, &result, mimetype]() {
HRESULT hr;
ComPtr<IAsyncOperation<IInspectable*>> op;
ComPtr<IInspectable> res;
HString type;
type.Set(reinterpret_cast<const wchar_t*>(mimetype.utf16()), mimetype.size());
hr = dataView->GetDataAsync(type.Get(), &op);
RETURN_OK_IF_FAILED("Could not query custom drag data.");
hr = QWinRTFunctions::await(op, res.GetAddressOf());
if (FAILED(hr) || !res) {
qCDebug(lcQpaMime) << "Custom drop data operation returned no results or failed.";
return S_OK;
}
// Test for properties
ComPtr<IPropertyValue> propertyValue;
hr = res.As(&propertyValue);
if (SUCCEEDED(hr)) {
// We need to check which type of custom data we are receiving
PropertyType type;
propertyValue->get_Type(&type);
switch (type) {
case PropertyType_UInt8: {
quint8 v;
hr = propertyValue->GetUInt8(&v);
Q_ASSERT_SUCCEEDED(hr);
result.setValue(v);
return S_OK;
}
case PropertyType_Int16: {
qint16 v;
hr = propertyValue->GetInt16(&v);
Q_ASSERT_SUCCEEDED(hr);
result.setValue(v);
return S_OK;
}
case PropertyType_UInt16: {
quint16 v;
hr = propertyValue->GetUInt16(&v);
Q_ASSERT_SUCCEEDED(hr);
result.setValue(v);
return S_OK;
}
case PropertyType_Int32: {
qint32 v;
hr = propertyValue->GetInt32(&v);
Q_ASSERT_SUCCEEDED(hr);
result.setValue(v);
return S_OK;
}
case PropertyType_UInt32: {
quint32 v;
hr = propertyValue->GetUInt32(&v);
Q_ASSERT_SUCCEEDED(hr);
result.setValue(v);
return S_OK;
}
case PropertyType_Int64: {
qint64 v;
hr = propertyValue->GetInt64(&v);
Q_ASSERT_SUCCEEDED(hr);
result.setValue(v);
return S_OK;
}
case PropertyType_UInt64: {
quint64 v;
hr = propertyValue->GetUInt64(&v);
Q_ASSERT_SUCCEEDED(hr);
result.setValue(v);
return S_OK;
}
case PropertyType_Single: {
float v;
hr = propertyValue->GetSingle(&v);
Q_ASSERT_SUCCEEDED(hr);
result.setValue(v);
return S_OK;
}
case PropertyType_Double: {
double v;
hr = propertyValue->GetDouble(&v);
Q_ASSERT_SUCCEEDED(hr);
result.setValue(v);
return S_OK;
}
case PropertyType_Char16: {
wchar_t v;
hr = propertyValue->GetChar16(&v);
Q_ASSERT_SUCCEEDED(hr);
result.setValue(QString::fromWCharArray(&v, 1));
return S_OK;
}
case PropertyType_Boolean: {
boolean v;
hr = propertyValue->GetBoolean(&v);
Q_ASSERT_SUCCEEDED(hr);
result.setValue(v);
return S_OK;
}
case PropertyType_String: {
HString stringProperty;
hr = propertyValue->GetString(stringProperty.GetAddressOf());
Q_ASSERT_SUCCEEDED(hr);
result.setValue(hStringToQString(stringProperty));
return S_OK;
}
default:
qCDebug(lcQpaMime) << "Unknown property type dropped:" << type;
}
return S_OK;
}
// Custom data can be read via input streams
ComPtr<IRandomAccessStream> randomAccessStream;
hr = res.As(&randomAccessStream);
if (SUCCEEDED(hr)) {
UINT64 size;
hr = randomAccessStream->get_Size(&size);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IInputStream> stream;
hr = randomAccessStream.As(&stream);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IBufferFactory> bufferFactory;
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(),
IID_PPV_ARGS(&bufferFactory));
Q_ASSERT_SUCCEEDED(hr);
UINT32 length = qBound(quint64(0), quint64(size), quint64(UINT_MAX));
ComPtr<IBuffer> buffer;
hr = bufferFactory->Create(length, &buffer);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IAsyncOperationWithProgress<IBuffer *, UINT32>> readOp;
hr = stream->ReadAsync(buffer.Get(), length, InputStreamOptions_None, &readOp);
ComPtr<IBuffer> effectiveBuffer;
hr = QWinRTFunctions::await(readOp, effectiveBuffer.GetAddressOf());
hr = effectiveBuffer->get_Length(&length);
ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
hr = effectiveBuffer.As(&byteArrayAccess);
byte *bytes;
hr = byteArrayAccess->Buffer(&bytes);
QByteArray array((char *)bytes, length);
result.setValue(array);
return S_OK;
}
HSTRING runtimeClass;
hr = res->GetRuntimeClassName(&runtimeClass);
Q_ASSERT_SUCCEEDED(hr);
HString converted;
converted.Set(runtimeClass);
qCDebug(lcQpaMime) << "Unknown drop data type received (" << hStringToQString(converted)
<< "). Ignoring...";
return S_OK;
});
}
return result;
}
void QWinRTInternalMimeData::setDataView(const Microsoft::WRL::ComPtr<IDataPackageView> &d)
{
dataView = d;
formats.clear();
}
static HRESULT qt_drag_enter(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventArgs *e)
{
QWinRTDrag::instance()->handleNativeDragEvent(sender, e);
return S_OK;
}
static HRESULT qt_drag_over(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventArgs *e)
{
QWinRTDrag::instance()->handleNativeDragEvent(sender, e);
return S_OK;
}
static HRESULT qt_drag_leave(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventArgs *e)
{
// Qt internally checks for new drags and auto sends leave events
// Also there is no QPA function for handling leave
Q_UNUSED(sender);
Q_UNUSED(e);
return S_OK;
}
static HRESULT qt_drop(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventArgs *e)
{
QWinRTDrag::instance()->handleNativeDragEvent(sender, e, true);
return S_OK;
}
#define Q_DECLARE_DRAGHANDLER(name,func) \
class QtDragEventHandler##name : public IDragEventHandler \
{ \
public: \
virtual HRESULT STDMETHODCALLTYPE Invoke(IInspectable *sender, \
ABI::Windows::UI::Xaml::IDragEventArgs *e) \
{ \
return qt_##func(sender, e);\
} \
\
STDMETHODIMP \
QueryInterface(REFIID riid, void FAR* FAR* ppvObj) \
{ \
if (riid == IID_IUnknown || riid == IID_IDragEventHandler) { \
*ppvObj = this; \
AddRef(); \
return NOERROR; \
} \
*ppvObj = NULL; \
return ResultFromScode(E_NOINTERFACE); \
} \
\
STDMETHODIMP_(ULONG) \
AddRef(void) \
{ \
return ++m_refs; \
} \
\
STDMETHODIMP_(ULONG) \
Release(void) \
{ \
if (--m_refs == 0) { \
delete this; \
return 0; \
} \
return m_refs; \
} \
private: \
ULONG m_refs{0}; \
};
Q_DECLARE_DRAGHANDLER(Enter, drag_enter)
Q_DECLARE_DRAGHANDLER(Over, drag_over)
Q_DECLARE_DRAGHANDLER(Leave, drag_leave)
Q_DECLARE_DRAGHANDLER(Drop, drop)
#define Q_INST_DRAGHANDLER(name) QtDragEventHandler##name()
Q_GLOBAL_STATIC(QWinRTDrag, gDrag);
extern ComPtr<ABI::Windows::UI::Input::IPointerPoint> qt_winrt_lastPointerPoint; // qwinrtscreen.cpp
QWinRTDrag::QWinRTDrag()
: QPlatformDrag()
, m_dragTarget(0)
{
qCDebug(lcQpaMime) << __FUNCTION__;
m_enter = new Q_INST_DRAGHANDLER(Enter);
m_over = new Q_INST_DRAGHANDLER(Over);
m_leave = new Q_INST_DRAGHANDLER(Leave);
m_drop = new Q_INST_DRAGHANDLER(Drop);
m_mimeData = new QWinRTInternalMimeData;
}
QWinRTDrag::~QWinRTDrag()
{
qCDebug(lcQpaMime) << __FUNCTION__;
delete m_enter;
delete m_over;
delete m_leave;
delete m_drop;
delete m_mimeData;
}
QWinRTDrag *QWinRTDrag::instance()
{
return gDrag;
}
inline HRESULT resetUiElementDrag(ComPtr<IUIElement3> &elem3, EventRegistrationToken startingToken)
{
return QEventDispatcherWinRT::runOnXamlThread([elem3, startingToken]() {
HRESULT hr;
hr = elem3->put_CanDrag(false);
Q_ASSERT_SUCCEEDED(hr);
hr = elem3->remove_DragStarting(startingToken);
Q_ASSERT_SUCCEEDED(hr);
return S_OK;
});
}
Qt::DropAction QWinRTDrag::drag(QDrag *drag)
{
qCDebug(lcQpaMime) << __FUNCTION__ << drag;
if (!qt_winrt_lastPointerPoint) {
Q_ASSERT_X(qt_winrt_lastPointerPoint, Q_FUNC_INFO, "No pointerpoint known");
return Qt::IgnoreAction;
}
ComPtr<IUIElement3> elem3;
HRESULT hr = m_ui.As(&elem3);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IAsyncOperation<ABI::Windows::ApplicationModel::DataTransfer::DataPackageOperation>> op;
EventRegistrationToken startingToken;
hr = QEventDispatcherWinRT::runOnXamlThread([drag, &op, &hr, elem3, &startingToken, this]() {
hr = elem3->put_CanDrag(true);
Q_ASSERT_SUCCEEDED(hr);
auto startingCallback = Callback<ITypedEventHandler<UIElement*, DragStartingEventArgs*>> ([drag](IInspectable *, IDragStartingEventArgs *args) {
qCDebug(lcQpaMime) << "Drag starting" << args;
ComPtr<IDataPackage> dataPackage;
HRESULT hr;
hr = args->get_Data(dataPackage.GetAddressOf());
Q_ASSERT_SUCCEEDED(hr);
Qt::DropAction action = drag->defaultAction();
hr = dataPackage->put_RequestedOperation(translateFromQDragDropActions(action));
Q_ASSERT_SUCCEEDED(hr);
#ifndef QT_WINRT_LIMITED_DRAGANDDROP
ComPtr<IDragStartingEventArgs2> args2;
hr = args->QueryInterface(IID_PPV_ARGS(&args2));
Q_ASSERT_SUCCEEDED(hr);
Qt::DropActions actions = drag->supportedActions();
DataPackageOperation allowedOperations = DataPackageOperation_None;
if (actions & Qt::CopyAction)
allowedOperations |= DataPackageOperation_Copy;
if (actions & Qt::MoveAction)
allowedOperations |= DataPackageOperation_Move;
if (actions & Qt::LinkAction)
allowedOperations |= DataPackageOperation_Link;
hr = args2->put_AllowedOperations(allowedOperations);
Q_ASSERT_SUCCEEDED(hr);
#endif // QT_WINRT_LIMITED_DRAGANDDROP
QMimeData *mimeData = drag->mimeData();
if (mimeData->hasText()) {
hr = dataPackage->SetText(qStringToHString(mimeData->text()).Get());
Q_ASSERT_SUCCEEDED(hr);
}
if (mimeData->hasHtml()) {
hr = dataPackage->SetHtmlFormat(qStringToHString(mimeData->html()).Get());
Q_ASSERT_SUCCEEDED(hr);
}
// ### TODO: Missing: weblink, image
if (!drag->pixmap().isNull()) {
const QImage image2 = drag->pixmap().toImage();
const QImage image = image2.convertToFormat(QImage::Format_ARGB32);
if (!image.isNull()) {
// Create IBuffer containing image
ComPtr<IBuffer> imageBuffer = createIBufferFromData(reinterpret_cast<const char*>(image.bits()), image.byteCount());
ComPtr<ISoftwareBitmapFactory> bitmapFactory;
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Imaging_SoftwareBitmap).Get(),
IID_PPV_ARGS(&bitmapFactory));
Q_ASSERT_SUCCEEDED(hr);
ComPtr<ISoftwareBitmap> bitmap;
hr = bitmapFactory->Create(BitmapPixelFormat_Rgba8, image.width(), image.height(), &bitmap);
Q_ASSERT_SUCCEEDED(hr);
hr = bitmap->CopyFromBuffer(imageBuffer.Get());
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IDragUI> dragUi;
hr = args->get_DragUI(dragUi.GetAddressOf());
Q_ASSERT_SUCCEEDED(hr);
hr = dragUi->SetContentFromSoftwareBitmap(bitmap.Get());
Q_ASSERT_SUCCEEDED(hr);
}
}
const QStringList formats = mimeData->formats();
for (auto item : formats) {
QByteArray data = mimeData->data(item);
ComPtr<IBuffer> buffer = createIBufferFromData(data.constData(), data.size());
// We cannot push the buffer to the data package as the result on
// recipient side is different from native events. It still sends a
// buffer, but that potentially cannot be parsed. Hence we need to create
// a IRandomAccessStream which gets forwarded as is to the drop side.
ComPtr<IRandomAccessStream> ras;
hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_InMemoryRandomAccessStream).Get(), &ras);
Q_ASSERT_SUCCEEDED(hr);
hr = ras->put_Size(data.size());
ComPtr<IOutputStream> outputStream;
hr = ras->GetOutputStreamAt(0, &outputStream);
Q_ASSERT_SUCCEEDED(hr);
ComPtr<IAsyncOperationWithProgress<UINT32,UINT32>> writeOp;
hr = outputStream->WriteAsync(buffer.Get(), &writeOp);
Q_ASSERT_SUCCEEDED(hr);
UINT32 result;
hr = QWinRTFunctions::await(writeOp, &result);
Q_ASSERT_SUCCEEDED(hr);
unsigned char flushResult;
ComPtr<IAsyncOperation<bool>> flushOp;
hr = outputStream->FlushAsync(&flushOp);
Q_ASSERT_SUCCEEDED(hr);
hr = QWinRTFunctions::await(flushOp, &flushResult);
Q_ASSERT_SUCCEEDED(hr);
hr = dataPackage->SetData(qStringToHString(item).Get(), ras.Get());
Q_ASSERT_SUCCEEDED(hr);
}
return S_OK;
});
hr = elem3->add_DragStarting(startingCallback.Get(), &startingToken);
Q_ASSERT_SUCCEEDED(hr);
hr = elem3->StartDragAsync(qt_winrt_lastPointerPoint.Get(), &op);
Q_ASSERT_SUCCEEDED(hr);
return hr;
});
if (!op || FAILED(hr)) {
qCDebug(lcQpaMime) << "Drag failed:" << hr;
hr = resetUiElementDrag(elem3, startingToken);
Q_ASSERT_SUCCEEDED(hr);
return Qt::IgnoreAction;
}
DataPackageOperation nativeOperationType;
// Do not yield, as that can cause deadlocks when dropping inside the same app
hr = QWinRTFunctions::await(op, &nativeOperationType, QWinRTFunctions::ProcessThreadEvents);
Q_ASSERT_SUCCEEDED(hr);
hr = resetUiElementDrag(elem3, startingToken);
Q_ASSERT_SUCCEEDED(hr);
Qt::DropAction resultAction;
switch (nativeOperationType) {
case DataPackageOperation_Link:
resultAction = Qt::LinkAction;
break;
case DataPackageOperation_Copy:
resultAction = Qt::CopyAction;
break;
case DataPackageOperation_Move:
resultAction = Qt::MoveAction;
break;
case DataPackageOperation_None:
default:
resultAction = Qt::IgnoreAction;
break;
}
return resultAction;
}
void QWinRTDrag::setDropTarget(QWindow *target)
{
qCDebug(lcQpaMime) << __FUNCTION__ << target;
m_dragTarget = target;
}
QMimeData *QWinRTDrag::platformDropData()
{
qCDebug(lcQpaMime) << __FUNCTION__;
return m_mimeData;
}
void QWinRTDrag::setUiElement(ComPtr<ABI::Windows::UI::Xaml::IUIElement> &element)
{
qCDebug(lcQpaMime) << __FUNCTION__;
m_ui = element;
// We set the element to always accept drops and then evaluate during
// runtime
HRESULT hr = element->put_AllowDrop(TRUE);
EventRegistrationToken tok;
hr = element->add_DragEnter(m_enter, &tok);
RETURN_VOID_IF_FAILED("Failed to add DragEnter handler.");
hr = element->add_DragOver(m_over, &tok);
RETURN_VOID_IF_FAILED("Failed to add DragOver handler.");
hr = element->add_DragLeave(m_leave, &tok);
RETURN_VOID_IF_FAILED("Failed to add DragLeave handler.");
hr = element->add_Drop(m_drop, &tok);
RETURN_VOID_IF_FAILED("Failed to add Drop handler.");
}
void QWinRTDrag::handleNativeDragEvent(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventArgs *e, bool drop)
{
Q_UNUSED(sender);
if (!m_dragTarget)
return;
HRESULT hr;
Point relativePoint;
hr = e->GetPosition(m_ui.Get(), &relativePoint);
RETURN_VOID_IF_FAILED("Could not query drag position.");
const QPoint p(relativePoint.X, relativePoint.Y);
ComPtr<IDragEventArgs2> e2;
hr = e->QueryInterface(IID_PPV_ARGS(&e2));
RETURN_VOID_IF_FAILED("Could not convert drag event args");
DragDropModifiers modifiers;
hr = e2->get_Modifiers(&modifiers);
#ifndef QT_WINRT_LIMITED_DRAGANDDROP
ComPtr<IDragEventArgs3> e3;
hr = e->QueryInterface(IID_PPV_ARGS(&e3));
Q_ASSERT_SUCCEEDED(hr);
DataPackageOperation dataOp;
hr = e3->get_AllowedOperations(&dataOp);
if (FAILED(hr))
qCDebug(lcQpaMime) << __FUNCTION__ << "Could not query drag operations";
const Qt::DropActions actions = translateToQDragDropActions(dataOp);
#else // !QT_WINRT_LIMITED_DRAGANDDROP
const Qt::DropActions actions = Qt::LinkAction | Qt::CopyAction | Qt::MoveAction;;
#endif // !QT_WINRT_LIMITED_DRAGANDDROP
ComPtr<IDataPackageView> dataView;
hr = e2->get_DataView(&dataView);
Q_ASSERT_SUCCEEDED(hr);
m_mimeData->setDataView(dataView);
// We use deferral as we need to jump to the Qt thread to handle
// the drag event
ComPtr<IDragOperationDeferral> deferral;
hr = e2->GetDeferral(&deferral);
Q_ASSERT_SUCCEEDED(hr);
DragThreadTransferData *transferData = new DragThreadTransferData;
transferData->moveToThread(qGuiApp->thread());
transferData->window = m_dragTarget;
transferData->point = p;
transferData->mime = m_mimeData;
transferData->actions = actions;
transferData->dropAction = drop;
transferData->nativeArgs = e;
transferData->deferral = deferral;
QMetaObject::invokeMethod(transferData, "handleDrag", Qt::QueuedConnection);
}
DragThreadTransferData::DragThreadTransferData(QObject *parent)
: QObject(parent)
, dropAction(false)
{
}
void DragThreadTransferData::handleDrag()
{
bool accepted = false;
Qt::DropAction acceptedAction;
if (dropAction) {
QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(window, mime, point, actions);
accepted = response.isAccepted();
acceptedAction = response.acceptedAction();
} else {
QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(window, mime, point, actions);
accepted = response.isAccepted();
acceptedAction = response.acceptedAction();
}
HRESULT hr;
hr = QEventDispatcherWinRT::runOnXamlThread([accepted, acceptedAction, this]() {
HRESULT hr;
hr = nativeArgs->put_Handled(accepted);
if (acceptedAction != Qt::IgnoreAction) {
ComPtr<IDragEventArgs2> e2;
hr = nativeArgs.As(&e2);
if (SUCCEEDED(hr))
hr = e2->put_AcceptedOperation(translateFromQDragDropActions(acceptedAction));
}
deferral->Complete();
return S_OK;
});
Q_ASSERT_SUCCEEDED(hr);
deleteLater();
}
QT_END_NAMESPACE
#include "qwinrtdrag.moc"

View File

@ -0,0 +1,113 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qpa/qplatformdrag.h>
#include <QtCore/QLoggingCategory>
#include <QtCore/QMimeData>
#include <QtGui/private/qdnd_p.h> // QInternalMime
#include <wrl.h>
namespace ABI {
namespace Windows {
namespace ApplicationModel {
namespace DataTransfer {
struct IDataPackageView;
}
}
namespace UI {
namespace Xaml {
struct IUIElement;
struct IDragEventArgs;
struct IDragOperationDeferral;
//struct IDataPackageView;
}
}
}
}
QT_BEGIN_NAMESPACE
Q_DECLARE_LOGGING_CATEGORY(lcQpaMime)
class QtDragEventHandlerEnter;
class QtDragEventHandlerOver;
class QtDragEventHandlerLeave;
class QtDragEventHandlerDrop;
class QWinRTInternalMimeData;
class QWinRTInternalMimeData : public QInternalMimeData {
public:
QWinRTInternalMimeData();
virtual ~QWinRTInternalMimeData();
bool hasFormat_sys(const QString &mimetype) const Q_DECL_OVERRIDE;
QStringList formats_sys() const Q_DECL_OVERRIDE;
QVariant retrieveData_sys(const QString &mimetype, QVariant::Type preferredType) const Q_DECL_OVERRIDE;
void setDataView(const Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::DataTransfer::IDataPackageView> &d);
private:
Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::DataTransfer::IDataPackageView> dataView;
mutable QStringList formats;
};
class QWinRTDrag : public QPlatformDrag {
public:
QWinRTDrag();
virtual ~QWinRTDrag();
static QWinRTDrag *instance();
QMimeData *platformDropData(void) Q_DECL_OVERRIDE;
Qt::DropAction drag(QDrag *) Q_DECL_OVERRIDE;
void setDropTarget(QWindow *target);
// Native integration and registration
void setUiElement(Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::IUIElement> &element);
void handleNativeDragEvent(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventArgs *e, bool drop = false);
private:
Microsoft::WRL::ComPtr<ABI::Windows::UI::Xaml::IUIElement> m_ui;
QWindow *m_dragTarget;
QtDragEventHandlerEnter *m_enter;
QtDragEventHandlerOver *m_over;
QtDragEventHandlerLeave *m_leave;
QtDragEventHandlerDrop *m_drop;
QWinRTInternalMimeData *m_mimeData;
};
QT_END_NAMESPACE

View File

@ -48,6 +48,9 @@
#include "qwinrtfontdatabase.h"
#include "qwinrttheme.h"
#include "qwinrtclipboard.h"
#ifndef QT_NO_DRAGANDDROP
#include "qwinrtdrag.h"
#endif
#include <QtGui/QOffscreenSurface>
#include <QtGui/QOpenGLContext>
@ -312,6 +315,17 @@ QPlatformClipboard *QWinRTIntegration::clipboard() const
return d->clipboard;
}
#ifndef QT_NO_DRAGANDDROP
QPlatformDrag *QWinRTIntegration::drag() const
{
#if _MSC_VER >= 1900
return QWinRTDrag::instance();
#else
return QPlatformIntegration::drag();
#endif
}
#endif // QT_NO_DRAGANDDROP
Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const
{
Q_D(const QWinRTIntegration);

Some files were not shown because too many files have changed in this diff Show More