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

Conflicts:
	src/widgets/styles/qgtkstyle_p.cpp
	tests/auto/corelib/io/qtextstream/test/test.pro
	tests/auto/corelib/plugin/plugin.pro

Change-Id: I512bc1b36acf3933ed2b96c00f476ee3819c1f4b
This commit is contained in:
Liang Qi 2016-03-21 09:02:57 +01:00
commit 6cb8121a44
189 changed files with 2052 additions and 984 deletions

11
configure vendored
View File

@ -6553,9 +6553,9 @@ fi
[ "$CFG_SYSTEM_PROXIES" = "yes" ] && QT_CONFIG="$QT_CONFIG system-proxies" [ "$CFG_SYSTEM_PROXIES" = "yes" ] && QT_CONFIG="$QT_CONFIG system-proxies"
[ "$CFG_DIRECTWRITE" = "yes" ] && QT_CONFIG="$QT_CONFIG directwrite" [ "$CFG_DIRECTWRITE" = "yes" ] && QT_CONFIG="$QT_CONFIG directwrite"
[ '!' -z "$DEFINES" ] && QMakeVar add DEFINES "$DEFINES" [ '!' -z "$DEFINES" ] && QMakeVar add EXTRA_DEFINES "$DEFINES"
[ '!' -z "$INCLUDES" ] && QMakeVar add INCLUDEPATH "$INCLUDES" [ '!' -z "$INCLUDES" ] && QMakeVar add EXTRA_INCLUDEPATH "$INCLUDES"
[ '!' -z "$L_FLAGS" ] && QMakeVar add LIBS "$L_FLAGS" [ '!' -z "$L_FLAGS" ] && QMakeVar add EXTRA_LIBS "$L_FLAGS"
if [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then if [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then
if [ -n "$RPATH_FLAGS" ]; then if [ -n "$RPATH_FLAGS" ]; then
@ -6571,7 +6571,7 @@ if [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then
else else
if [ -n "$RPATH_FLAGS" ]; then if [ -n "$RPATH_FLAGS" ]; then
# add the user defined rpaths # add the user defined rpaths
QMakeVar add QMAKE_RPATHDIR "$RPATH_FLAGS" QMakeVar add EXTRA_RPATHS "$RPATH_FLAGS"
fi fi
fi fi
if [ "$CFG_RPATH" = "yes" ]; then if [ "$CFG_RPATH" = "yes" ]; then
@ -7159,9 +7159,6 @@ if [ -n "$CFG_SYSROOT" ] && [ "$CFG_GCC_SYSROOT" = "yes" ]; then
echo "}" echo "}"
echo echo
fi fi
if [ -n "$RPATH_FLAGS" ]; then
echo "QMAKE_RPATHDIR += $RPATH_FLAGS"
fi
echo "QT_COMPILER_STDCXX = $CFG_STDCXX_DEFAULT" echo "QT_COMPILER_STDCXX = $CFG_STDCXX_DEFAULT"
if [ -n "$QT_GCC_MAJOR_VERSION" ]; then if [ -n "$QT_GCC_MAJOR_VERSION" ]; then
echo "QT_GCC_MAJOR_VERSION = $QT_GCC_MAJOR_VERSION" echo "QT_GCC_MAJOR_VERSION = $QT_GCC_MAJOR_VERSION"

View File

@ -702,7 +702,7 @@ void TorrentView::dragMoveEvent(QDragMoveEvent *event)
{ {
// Accept file actions with a '.torrent' extension. // Accept file actions with a '.torrent' extension.
QUrl url(event->mimeData()->text()); QUrl url(event->mimeData()->text());
if (url.isValid() && url.scheme().toLower() == "file" if (url.isValid() && url.scheme() == "file"
&& url.path().toLower().endsWith(".torrent")) && url.path().toLower().endsWith(".torrent"))
event->acceptProposedAction(); event->acceptProposedAction();
} }

View File

@ -160,21 +160,8 @@ qt_module_deps = $$resolve_depends(qt_module_deps, "QT.")
contains(qt_module_deps, core) { contains(qt_module_deps, core) {
relative_qt_rpath:!isEmpty(QMAKE_REL_RPATH_BASE):contains(INSTALLS, target):\ relative_qt_rpath:!isEmpty(QMAKE_REL_RPATH_BASE):contains(INSTALLS, target):\
isEmpty(target.files):isEmpty(target.commands):isEmpty(target.extra) { isEmpty(target.files):isEmpty(target.commands):isEmpty(target.extra) {
mac {
if(equals(TEMPLATE, app):app_bundle)|\
if(equals(TEMPLATE, lib):plugin:plugin_bundle) {
ios: binpath = $$target.path/$${TARGET}.app
else: binpath = $$target.path/$${TARGET}.app/Contents/MacOS
} else: equals(TEMPLATE, lib):!plugin:lib_bundle {
binpath = $$target.path/$${TARGET}.framework/Versions/Current
} else {
binpath = $$target.path
}
} else {
binpath = $$target.path
}
# NOT the /dev property, as INSTALLS use host paths # NOT the /dev property, as INSTALLS use host paths
QMAKE_RPATHDIR += $$relative_path($$[QT_INSTALL_LIBS], $$binpath) QMAKE_RPATHDIR += $$relative_path($$[QT_INSTALL_LIBS], $$qtRelativeRPathBase())
} else { } else {
QMAKE_RPATHDIR += $$[QT_INSTALL_LIBS/dev] QMAKE_RPATHDIR += $$[QT_INSTALL_LIBS/dev]
} }

View File

@ -52,6 +52,9 @@ QMAKE_DIR_REPLACE_SANE = PRECOMPILED_DIR OBJECTS_DIR MOC_DIR RCC_DIR UI_DIR
unset(modpath) unset(modpath)
} }
# Apply extra compiler flags passed via configure last.
CONFIG = qt_build_extra $$CONFIG
# Don't actually try to install anything in non-prefix builds. # Don't actually try to install anything in non-prefix builds.
# This is much easier and safer than making every single INSTALLS # This is much easier and safer than making every single INSTALLS
# assignment conditional. # assignment conditional.
@ -72,6 +75,10 @@ CONFIG += \
# However, testcases should be still built with exceptions. # However, testcases should be still built with exceptions.
exceptions_off testcase_exceptions exceptions_off testcase_exceptions
# Under Windows, this is neither necessary (transitive deps are automatically
# resolved), nor functional (.res files end up in .prl files and break things).
unix: CONFIG += explicitlib
defineTest(qtBuildPart) { defineTest(qtBuildPart) {
bp = $$eval($$upper($$section(_QMAKE_CONF_, /, -2, -2))_BUILD_PARTS) bp = $$eval($$upper($$section(_QMAKE_CONF_, /, -2, -2))_BUILD_PARTS)

View File

@ -0,0 +1,40 @@
#
# W A R N I N G
# -------------
#
# This file is not part of the Qt API. It exists purely as an
# implementation detail. It may change from version to version
# without notice, or even be removed.
#
# We mean it.
#
equals(TEMPLATE, subdirs): return()
# It's likely that these extra flags will be wrong for host builds,
# and the bootstrapped tools usually don't need them anyway.
host_build:force_bootstrap: return()
# The headersclean check needs defines and includes even for
# header-only modules.
DEFINES += $$EXTRA_DEFINES
INCLUDEPATH += $$EXTRA_INCLUDEPATH
# The other flags are relevant only for actual libraries.
equals(TEMPLATE, aux): return()
LIBS += $$EXTRA_LIBS
# Static libs need no rpaths
static: return()
for (rp, EXTRA_RPATHS) {
absrp = $$absolute_path($$rp, $$[QT_INSTALL_LIBS])
!isEqual(absrp, $$rp) {
isEmpty(QMAKE_REL_RPATH_BASE)|!contains(INSTALLS, target): \
rp = $$absrp
else: \
rp = $$relative_path($$absrp, $$qtRelativeRPathBase())
}
QMAKE_RPATHDIR += $$rp
}

View File

@ -33,6 +33,19 @@ defineReplace(qt5LibraryTarget) {
return($$LIBRARY_NAME) return($$LIBRARY_NAME)
} }
defineReplace(qtRelativeRPathBase) {
darwin {
if(equals(TEMPLATE, app):app_bundle)|\
if(equals(TEMPLATE, lib):plugin:plugin_bundle) {
ios: return($$target.path/$${TARGET}.app)
return($$target.path/$${TARGET}.app/Contents/MacOS)
}
equals(TEMPLATE, lib):!plugin:lib_bundle: \
return($$target.path/$${TARGET}.framework/Versions/Current)
}
return($$target.path)
}
defineTest(qtAddLibrary) { defineTest(qtAddLibrary) {
warning("qtAddLibrary() is deprecated. Use QT+= instead.") warning("qtAddLibrary() is deprecated. Use QT+= instead.")

View File

@ -258,12 +258,9 @@ void NmakeMakefileGenerator::writeSubMakeCall(QTextStream &t, const QString &cal
QString NmakeMakefileGenerator::defaultInstall(const QString &t) QString NmakeMakefileGenerator::defaultInstall(const QString &t)
{ {
if((t != "target" && t != "dlltarget") ||
(t == "dlltarget" && (project->first("TEMPLATE") != "lib" || !project->isActiveConfig("shared"))) ||
project->first("TEMPLATE") == "subdirs")
return QString();
QString ret = Win32MakefileGenerator::defaultInstall(t); QString ret = Win32MakefileGenerator::defaultInstall(t);
if (ret.isEmpty())
return ret;
const QString root = installRoot(); const QString root = installRoot();
ProStringList &uninst = project->values(ProKey(t + ".uninstall")); ProStringList &uninst = project->values(ProKey(t + ".uninstall"));

View File

@ -1,4 +1,4 @@
Libpng 1.6.19 - November 12, 2015 Libpng 1.6.20 - December 3, 2015
This is a public release of libpng, intended for use in production codes. This is a public release of libpng, intended for use in production codes.
@ -7,104 +7,41 @@ Files available for download:
Source files with LF line endings (for Unix/Linux) and with a Source files with LF line endings (for Unix/Linux) and with a
"configure" script "configure" script
libpng-1.6.19.tar.xz (LZMA-compressed, recommended) libpng-1.6.20.tar.xz (LZMA-compressed, recommended)
libpng-1.6.19.tar.gz libpng-1.6.20.tar.gz
Source files with CRLF line endings (for Windows), without the Source files with CRLF line endings (for Windows), without the
"configure" script "configure" script
lpng1619.7z (LZMA-compressed, recommended) /scratch/glennrp/Libpng16/lpng1620.7z (LZMA-compressed, recommended)
lpng1619.zip /scratch/glennrp/Libpng16/lpng1620.zip
Other information: Other information:
libpng-1.6.19-README.txt libpng-1.6.20-README.txt
libpng-1.6.19-LICENSE.txt libpng-1.6.20-LICENSE.txt
libpng-1.6.19-*.asc (armored detached GPG signatures) libpng-1.6.20-*.asc (armored detached GPG signatures)
Changes since the last public release (1.6.18): Changes since the last public release (1.6.19):
Avoid potential pointer overflow/underflow in png_handle_sPLT() and
Updated obsolete information about the simplified API macros in the png_handle_pCAL() (Bug report by John Regehr).
manual pages (Bug report by Arc Riley). Fixed incorrect implementation of png_set_PLTE() that uses png_ptr
Avoid potentially dereferencing NULL info_ptr in png_info_init_3(). not info_ptr, that left png_set_PLTE() open to the CVE-2015-8126
Rearranged png.h to put the major sections in the same order as vulnerability.
in libpng17. Backported tests from libpng-1.7.0beta69.
Eliminated unused PNG_COST_SHIFT, PNG_WEIGHT_SHIFT, PNG_COST_FACTOR, and Fixed an error in handling of bad zlib CMINFO field in pngfix, found by
PNG_WEIGHT_FACTOR macros. American Fuzzy Lop, reported by Brian Carpenter. inflate() doesn't
Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler immediately fault a bad CMINFO field; instead a 'too far back' error
(Bug report by Viktor Szakats). Several warnings remain and are happens later (at least some times). pngfix failed to limit CMINFO to
unavoidable, where we test for overflow. the allowed values but then assumed that window_bits was in range,
Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c triggering an assert. The bug is mostly harmless; the PNG file cannot
Fixed uninitialized variable in contrib/gregbook/rpng2-x.c be fixed.
Moved config.h.in~ from the "libpng_autotools_files" list to the In libpng 1.6 zlib initialization was changed to use the window size
"libpng_autotools_extra" list in autogen.sh because it was causing a in the zlib stream, not a fixed value. This causes some invalid images,
false positive for missing files (bug report by Robert C. Seacord). where CINFO is too large, to display 'correctly' if the rest of the
Removed unreachable "break" statements in png.c, pngread.c, and pngrtran.c data is valid. This provides a workaround for zlib versions where the
to suppress clang warnings (Bug report by Viktor Szakats). error arises (ones that support the API change to use the window size
Fixed some bad links in the man page. in the stream).
Changed "n bit" to "n-bit" in comments.
Added signed/unsigned 16-bit safety net. This removes the dubious
0x8000 flag definitions on 16-bit systems. They aren't supported
yet the defs *probably* work, however it seems much safer to do this
and be advised if anyone, contrary to advice, is building libpng 1.6
on a 16-bit system. It also adds back various switch default clauses
for GCC; GCC errors out if they are not present (with an appropriately
high level of warnings).
Safely convert num_bytes to a png_byte in png_set_sig_bytes() (Robert
Seacord).
Fixed the recently reported 1's complement security issue by replacing
the value that is illegal in the PNG spec, in both signed and unsigned
values, with 0. Illegal unsigned values (anything greater than or equal
to 0x80000000) can still pass through, but since these are not illegal
in ANSI-C (unlike 0x80000000 in the signed case) the checking that
occurs later can catch them (John Bowler).
Fixed png_save_int_32 when int is not 2's complement (John Bowler).
Updated libpng16 with all the recent test changes from libpng17,
including changes to pngvalid.c to ensure that the original,
distributed, version of contrib/visupng/cexcept.h can be used
(John Bowler).
pngvalid contains the correction to the use of SAVE/STORE_
UNKNOWN_CHUNKS; a bug revealed by changes in libpng 1.7. More
tests contain the --strict option to detect warnings and the
pngvalid-standard test has been corrected so that it does not
turn on progressive-read. There is a separate test which does
that. (John Bowler)
Also made some signed/unsigned fixes.
Make pngstest error limits version specific. Splitting the machine
generated error structs out to a file allows the values to be updated
without changing pngstest.c itself. Since libpng 1.6 and 1.7 have
slightly different error limits this simplifies maintenance. The
makepngs.sh script has also been updated to more accurately reflect
current problems in libpng 1.7 (John Bowler).
Incorporated new test PNG files into make check. tests/pngstest-*
are changed so that the new test files are divided into 8 groups by
gamma and alpha channel. These tests have considerably better code
and pixel-value coverage than contrib/pngsuite; however,coverage is
still incomplete (John Bowler).
Removed the '--strict' in 1.6 because of the double-gamma-correction
warning, updated pngstest-errors.h for the errors detected with the
new contrib/testspngs PNG test files (John Bowler).
Worked around rgb-to-gray issues in libpng 1.6. The previous
attempts to ignore the errors in the code aren't quite enough to
deal with the 'channel selection' encoding added to libpng 1.7; abort.
Fixed 'pow' macros in pngvalid.c. It is legal for 'pow' to be a
macro, therefore the argument list cannot contain preprocessing
directives. Make sure pow is a function where this happens. This is
a minimal safe fix, the issue only arises in non-performance-critical
code (bug report by Curtis Leach, fix by John Bowler).
Added sPLT support to pngtest.c
Prevent setting or writing over-length PLTE chunk (Cosmin Truta).
Silently truncate over-length PLTE chunk while reading.
Libpng incorrectly calculated the output rowbytes when the application
decreased either the number of channels or the bit depth (or both) in
a user transform. This was safe; libpng overallocated buffer space
(potentially by quite a lot; up to 4 times the amount required) but,
from 1.5.4 on, resulted in a png_error (John Bowler).
Fixed some inconsequential cut-and-paste typos in png_set_cHRM_XYZ_fixed().
Clarified COPYRIGHT information to state explicitly that versions
are derived from previous versions.
Removed much of the long list of previous versions from png.h and
libpng.3.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit (subscription required; visit

View File

@ -5409,11 +5409,43 @@ Version 1.6.19rc03 [November 3, 2015]
Version 1.6.19rc04 [November 5, 2015] Version 1.6.19rc04 [November 5, 2015]
Fixed new bug with CRC error after reading an over-length palette Fixed new bug with CRC error after reading an over-length palette
(bug report by Cosmin Truta). (bug report by Cosmin Truta) (CVE-2015-8126).
Version 1.6.19 [November 12, 2015] Version 1.6.19 [November 12, 2015]
Cleaned up coding style in png_handle_PLTE(). Cleaned up coding style in png_handle_PLTE().
Version 1.6.20beta01 [November 20, 2015]
Avoid potential pointer overflow/underflow in png_handle_sPLT() and
png_handle_pCAL() (Bug report by John Regehr).
Version 1.6.20beta02 [November 23, 2015]
Fixed incorrect implementation of png_set_PLTE() that uses png_ptr
not info_ptr, that left png_set_PLTE() open to the CVE-2015-8126
vulnerability.
Version 1.6.20beta03 [November 24, 2015]
Backported tests from libpng-1.7.0beta69.
Version 1.6.20rc01 [November 26, 2015]
Fixed an error in handling of bad zlib CMINFO field in pngfix, found by
American Fuzzy Lop, reported by Brian Carpenter. inflate() doesn't
immediately fault a bad CMINFO field; instead a 'too far back' error
happens later (at least some times). pngfix failed to limit CMINFO to
the allowed values but then assumed that window_bits was in range,
triggering an assert. The bug is mostly harmless; the PNG file cannot
be fixed.
Version 1.6.20rc02 [November 29, 2015]
In libpng 1.6 zlib initialization was changed to use the window size
in the zlib stream, not a fixed value. This causes some invalid images,
where CINFO is too large, to display 'correctly' if the rest of the
data is valid. This provides a workaround for zlib versions where the
error arises (ones that support the API change to use the window size
in the stream).
Version 1.6.20 [December 3, 2015]
No changes.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit (subscription required; visit
https://lists.sourceforge.net/lists/listinfo/png-mng-implement https://lists.sourceforge.net/lists/listinfo/png-mng-implement

View File

@ -10,7 +10,7 @@ this sentence.
This code is released under the libpng license. This code is released under the libpng license.
libpng versions 1.0.7, July 1, 2000, through 1.6.19, November 12, 2015, are libpng versions 1.0.7, July 1, 2000, through 1.6.20, December 3, 2015, are
Copyright (c) 2000-2002, 2004, 2006-2015 Glenn Randers-Pehrson, are Copyright (c) 2000-2002, 2004, 2006-2015 Glenn Randers-Pehrson, are
derived from libpng-1.0.6, and are distributed according to the same derived from libpng-1.0.6, and are distributed according to the same
disclaimer and license as libpng-1.0.6 with the following individuals disclaimer and license as libpng-1.0.6 with the following individuals
@ -109,4 +109,4 @@ the additional disclaimers inserted at version 1.0.7.
Glenn Randers-Pehrson Glenn Randers-Pehrson
glennrp at users.sourceforge.net glennrp at users.sourceforge.net
November 12, 2015 December 3, 2015

View File

@ -1,4 +1,4 @@
README for libpng version 1.6.19 - November 12, 2015 (shared library 16.0) README for libpng version 1.6.20 - December 3, 2015 (shared library 16.0)
See the note about version numbers near the top of png.h See the note about version numbers near the top of png.h
See INSTALL for instructions on how to install libpng. See INSTALL for instructions on how to install libpng.

View File

@ -1,6 +1,6 @@
libpng-manual.txt - A description on how to use and modify libpng libpng-manual.txt - A description on how to use and modify libpng
libpng version 1.6.19 - November 12, 2015 libpng version 1.6.20 - December 3, 2015
Updated and distributed by Glenn Randers-Pehrson Updated and distributed by Glenn Randers-Pehrson
<glennrp at users.sourceforge.net> <glennrp at users.sourceforge.net>
Copyright (c) 1998-2015 Glenn Randers-Pehrson Copyright (c) 1998-2015 Glenn Randers-Pehrson
@ -11,7 +11,7 @@ libpng-manual.txt - A description on how to use and modify libpng
Based on: Based on:
libpng versions 0.97, January 1998, through 1.6.19 - November 12, 2015 libpng versions 0.97, January 1998, through 1.6.20 - December 3, 2015
Updated and distributed by Glenn Randers-Pehrson Updated and distributed by Glenn Randers-Pehrson
Copyright (c) 1998-2015 Glenn Randers-Pehrson Copyright (c) 1998-2015 Glenn Randers-Pehrson
@ -2960,6 +2960,7 @@ width, height, bit_depth, and color_type must be the same in each call.
(array of png_color) (array of png_color)
num_palette - number of entries in the palette num_palette - number of entries in the palette
png_set_gAMA(png_ptr, info_ptr, file_gamma); png_set_gAMA(png_ptr, info_ptr, file_gamma);
png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma); png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
@ -4897,7 +4898,7 @@ a set of "safe" limits is applied in pngpriv.h. These can be overridden by
application calls to png_set_user_limits(), png_set_user_chunk_cache_max(), application calls to png_set_user_limits(), png_set_user_chunk_cache_max(),
and/or png_set_user_malloc_max() that increase or decrease the limits. Also, and/or png_set_user_malloc_max() that increase or decrease the limits. Also,
in libpng-1.5.10 the default width and height limits were increased in libpng-1.5.10 the default width and height limits were increased
from 1,000,000 to 0x7ffffff (i.e., made unlimited). Therefore, the from 1,000,000 to 0x7fffffff (i.e., made unlimited). Therefore, the
limits are now limits are now
default safe default safe
png_user_width_max 0x7fffffff 1,000,000 png_user_width_max 0x7fffffff 1,000,000
@ -5323,7 +5324,7 @@ Since the PNG Development group is an ad-hoc body, we can't make
an official declaration. an official declaration.
This is your unofficial assurance that libpng from version 0.71 and This is your unofficial assurance that libpng from version 0.71 and
upward through 1.6.19 are Y2K compliant. It is my belief that earlier upward through 1.6.20 are Y2K compliant. It is my belief that earlier
versions were also Y2K compliant. versions were also Y2K compliant.
Libpng only has two year fields. One is a 2-byte unsigned integer Libpng only has two year fields. One is a 2-byte unsigned integer

View File

@ -14,7 +14,7 @@
#include "pngpriv.h" #include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */ /* Generate a compiler error if there is an old png.h in the search path. */
typedef png_libpng_version_1_6_19 Your_png_h_is_not_version_1_6_19; typedef png_libpng_version_1_6_20 Your_png_h_is_not_version_1_6_20;
/* Tells libpng that we have already handled the first "num_bytes" bytes /* Tells libpng that we have already handled the first "num_bytes" bytes
* of the PNG file signature. If the PNG data is embedded into another * of the PNG file signature. If the PNG data is embedded into another
@ -775,13 +775,13 @@ png_get_copyright(png_const_structrp png_ptr)
#else #else
# ifdef __STDC__ # ifdef __STDC__
return PNG_STRING_NEWLINE \ return PNG_STRING_NEWLINE \
"libpng version 1.6.19 - November 12, 2015" PNG_STRING_NEWLINE \ "libpng version 1.6.20 - December 3, 2015" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2015 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2015 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
PNG_STRING_NEWLINE; PNG_STRING_NEWLINE;
# else # else
return "libpng version 1.6.19 - November 12, 2015\ return "libpng version 1.6.20 - December 3, 2015\
Copyright (c) 1998-2015 Glenn Randers-Pehrson\ Copyright (c) 1998-2015 Glenn Randers-Pehrson\
Copyright (c) 1996-1997 Andreas Dilger\ Copyright (c) 1996-1997 Andreas Dilger\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
@ -2343,7 +2343,7 @@ png_compare_ICC_profile_with_sRGB(png_const_structrp png_ptr,
* Fall through to "no match". * Fall through to "no match".
*/ */
png_chunk_report(png_ptr, png_chunk_report(png_ptr,
"Not recognizing known sRGB profile that has been edited", "Not recognizing known sRGB profile that has been edited",
PNG_CHUNK_WARNING); PNG_CHUNK_WARNING);
break; break;
# endif # endif

View File

@ -1,7 +1,7 @@
/* png.h - header file for PNG reference library /* png.h - header file for PNG reference library
* *
* libpng version 1.6.19, November 12, 2015 * libpng version 1.6.20, December 3, 2015
* *
* Copyright (c) 1998-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2015 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
@ -12,7 +12,8 @@
* Authors and maintainers: * Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
* libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.6.19, November 12, 2015: Glenn * libpng versions 0.97, January 1998, through 1.6.20, December 3, 2015:
* Glenn Randers-Pehrson.
* See also "Contributing Authors", below. * See also "Contributing Authors", below.
*/ */
@ -24,7 +25,7 @@
* *
* This code is released under the libpng license. * This code is released under the libpng license.
* *
* libpng versions 1.0.7, July 1, 2000, through 1.6.19, November 12, 2015, are * libpng versions 1.0.7, July 1, 2000, through 1.6.20, December 3, 2015, are
* Copyright (c) 2000-2002, 2004, 2006-2015 Glenn Randers-Pehrson, are * Copyright (c) 2000-2002, 2004, 2006-2015 Glenn Randers-Pehrson, are
* derived from libpng-1.0.6, and are distributed according to the same * derived from libpng-1.0.6, and are distributed according to the same
* disclaimer and license as libpng-1.0.6 with the following individuals * disclaimer and license as libpng-1.0.6 with the following individuals
@ -185,7 +186,7 @@
* ... * ...
* 1.5.23 15 10523 15.so.15.23[.0] * 1.5.23 15 10523 15.so.15.23[.0]
* ... * ...
* 1.6.19 16 10619 16.so.16.19[.0] * 1.6.20 16 10620 16.so.16.20[.0]
* *
* Henceforth the source version will match the shared-library major * Henceforth the source version will match the shared-library major
* and minor numbers; the shared-library major version number will be * and minor numbers; the shared-library major version number will be
@ -213,13 +214,13 @@
* Y2K compliance in libpng: * Y2K compliance in libpng:
* ========================= * =========================
* *
* November 12, 2015 * December 3, 2015
* *
* Since the PNG Development group is an ad-hoc body, we can't make * Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration. * an official declaration.
* *
* This is your unofficial assurance that libpng from version 0.71 and * This is your unofficial assurance that libpng from version 0.71 and
* upward through 1.6.19 are Y2K compliant. It is my belief that * upward through 1.6.20 are Y2K compliant. It is my belief that
* earlier versions were also Y2K compliant. * earlier versions were also Y2K compliant.
* *
* Libpng only has two year fields. One is a 2-byte unsigned integer * Libpng only has two year fields. One is a 2-byte unsigned integer
@ -281,9 +282,9 @@
*/ */
/* Version information for png.h - this should match the version in png.c */ /* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.6.19" #define PNG_LIBPNG_VER_STRING "1.6.20"
#define PNG_HEADER_VERSION_STRING \ #define PNG_HEADER_VERSION_STRING \
" libpng version 1.6.19 - November 12, 2015\n" " libpng version 1.6.20 - December 3, 2015\n"
#define PNG_LIBPNG_VER_SONUM 16 #define PNG_LIBPNG_VER_SONUM 16
#define PNG_LIBPNG_VER_DLLNUM 16 #define PNG_LIBPNG_VER_DLLNUM 16
@ -291,7 +292,7 @@
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 6 #define PNG_LIBPNG_VER_MINOR 6
#define PNG_LIBPNG_VER_RELEASE 19 #define PNG_LIBPNG_VER_RELEASE 20
/* This should match the numeric part of the final component of /* This should match the numeric part of the final component of
* PNG_LIBPNG_VER_STRING, omitting any leading zero: * PNG_LIBPNG_VER_STRING, omitting any leading zero:
@ -322,7 +323,7 @@
* version 1.0.0 was mis-numbered 100 instead of 10000). From * version 1.0.0 was mis-numbered 100 instead of 10000). From
* version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release
*/ */
#define PNG_LIBPNG_VER 10619 /* 1.6.19 */ #define PNG_LIBPNG_VER 10620 /* 1.6.20 */
/* Library configuration: these options cannot be changed after /* Library configuration: these options cannot be changed after
* the library has been built. * the library has been built.
@ -432,7 +433,7 @@ extern "C" {
/* This triggers a compiler error in png.c, if png.c and png.h /* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number. * do not agree upon the version number.
*/ */
typedef char* png_libpng_version_1_6_19; typedef char* png_libpng_version_1_6_20;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
* *

View File

@ -1,7 +1,7 @@
/* pngconf.h - machine configurable file for libpng /* pngconf.h - machine configurable file for libpng
* *
* libpng version 1.6.19, July 23, 2015 * libpng version 1.6.20, December 3, 2015
* *
* Copyright (c) 1998-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2015 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)

View File

@ -768,7 +768,7 @@ png_longjmp,(png_const_structrp png_ptr, int val),PNG_NORETURN)
/* If control reaches this point, png_longjmp() must not return. The only /* If control reaches this point, png_longjmp() must not return. The only
* choice is to terminate the whole process (or maybe the thread); to do * choice is to terminate the whole process (or maybe the thread); to do
* this the ANSI-C abort() function is used unless a different method is * this the ANSI-C abort() function is used unless a different method is
* implemented by overriding the default configuration setting for * implemented by overriding the default configuration setting for
* PNG_ABORT(). * PNG_ABORT().
*/ */

View File

@ -223,7 +223,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
/* Storage for unknown chunks that the library doesn't recognize. */ /* Storage for unknown chunks that the library doesn't recognize. */
png_unknown_chunkp unknown_chunks; png_unknown_chunkp unknown_chunks;
/* The type of this field is limited by the type of /* The type of this field is limited by the type of
* png_struct::user_chunk_cache_max, else overflow can occur. * png_struct::user_chunk_cache_max, else overflow can occur.
*/ */
int unknown_chunks_num; int unknown_chunks_num;

View File

@ -1,6 +1,6 @@
/* pnglibconf.h - library build configuration */ /* pnglibconf.h - library build configuration */
/* libpng version 1.6.19, July 23, 2015 */ /* libpng version 1.6.20 - December 3, 2015 */
/* Copyright (c) 1998-2014 Glenn Randers-Pehrson */ /* Copyright (c) 1998-2014 Glenn Randers-Pehrson */

View File

@ -133,7 +133,7 @@ png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
void /* PRIVATE */ void /* PRIVATE */
png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr)
{ {
png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */
num_to_check = 8 - num_checked; num_to_check = 8 - num_checked;
if (png_ptr->buffer_size < num_to_check) if (png_ptr->buffer_size < num_to_check)
@ -662,7 +662,7 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
* change the current behavior (see comments in inflate.c * change the current behavior (see comments in inflate.c
* for why this doesn't happen at present with zlib 1.2.5). * for why this doesn't happen at present with zlib 1.2.5).
*/ */
ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH); ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH);
/* Check for any failure before proceeding. */ /* Check for any failure before proceeding. */
if (ret != Z_OK && ret != Z_STREAM_END) if (ret != Z_OK && ret != Z_STREAM_END)

View File

@ -1229,6 +1229,14 @@ PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),
/* Initialize the row buffers, etc. */ /* Initialize the row buffers, etc. */
PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);
#if PNG_ZLIB_VERNUM >= 0x1240
PNG_INTERNAL_FUNCTION(int,png_zlib_inflate,(png_structrp png_ptr, int flush),
PNG_EMPTY);
# define PNG_INFLATE(pp, flush) png_zlib_inflate(pp, flush)
#else /* Zlib < 1.2.4 */
# define PNG_INFLATE(pp, flush) inflate(&(pp)->zstream, flush)
#endif /* Zlib < 1.2.4 */
#ifdef PNG_READ_TRANSFORMS_SUPPORTED #ifdef PNG_READ_TRANSFORMS_SUPPORTED
/* Optional call to update the users info structure */ /* Optional call to update the users info structure */
PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr, PNG_INTERNAL_FUNCTION(void,png_read_transform_info,(png_structrp png_ptr,

View File

@ -2838,7 +2838,6 @@ png_image_read_colormap(png_voidp argument)
default: default:
png_error(png_ptr, "invalid PNG color type"); png_error(png_ptr, "invalid PNG color type");
/*NOT REACHED*/ /*NOT REACHED*/
break;
} }
/* Now deal with the output processing */ /* Now deal with the output processing */

View File

@ -1,7 +1,7 @@
/* pngrutil.c - utilities to read a PNG file /* pngrutil.c - utilities to read a PNG file
* *
* Last changed in libpng 1.6.19 [November 12, 2015] * Last changed in libpng 1.6.20 [December 3, 2015]
* Copyright (c) 1998-2015 Glenn Randers-Pehrson * Copyright (c) 1998-2015 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -377,10 +377,16 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) == if (((png_ptr->options >> PNG_MAXIMUM_INFLATE_WINDOW) & 3) ==
PNG_OPTION_ON) PNG_OPTION_ON)
{
window_bits = 15; window_bits = 15;
png_ptr->zstream_start = 0; /* fixed window size */
}
else else
{
window_bits = 0; window_bits = 0;
png_ptr->zstream_start = 1;
}
# else # else
# define window_bits 0 # define window_bits 0
# endif # endif
@ -429,6 +435,31 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
#endif #endif
} }
#if PNG_ZLIB_VERNUM >= 0x1240
/* Handle the start of the inflate stream if we called inflateInit2(strm,0);
* in this case some zlib versions skip validation of the CINFO field and, in
* certain circumstances, libpng may end up displaying an invalid image, in
* contrast to implementations that call zlib in the normal way (e.g. libpng
* 1.5).
*/
int /* PRIVATE */
png_zlib_inflate(png_structrp png_ptr, int flush)
{
if (png_ptr->zstream_start && png_ptr->zstream.avail_in > 0)
{
if ((*png_ptr->zstream.next_in >> 4) > 7)
{
png_ptr->zstream.msg = "invalid window size (libpng)";
return Z_DATA_ERROR;
}
png_ptr->zstream_start = 0;
}
return inflate(&png_ptr->zstream, flush);
}
#endif /* Zlib >= 1.2.4 */
#ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED #ifdef PNG_READ_COMPRESSED_TEXT_SUPPORTED
/* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to /* png_inflate now returns zlib error codes including Z_OK and Z_STREAM_END to
* allow the caller to do multiple calls if required. If the 'finish' flag is * allow the caller to do multiple calls if required. If the 'finish' flag is
@ -522,7 +553,7 @@ png_inflate(png_structrp png_ptr, png_uint_32 owner, int finish,
* the previous chunk of input data. Tell zlib if we have reached the * the previous chunk of input data. Tell zlib if we have reached the
* end of the output buffer. * end of the output buffer.
*/ */
ret = inflate(&png_ptr->zstream, avail_out > 0 ? Z_NO_FLUSH : ret = PNG_INFLATE(png_ptr, avail_out > 0 ? Z_NO_FLUSH :
(finish ? Z_FINISH : Z_SYNC_FLUSH)); (finish ? Z_FINISH : Z_SYNC_FLUSH));
} while (ret == Z_OK); } while (ret == Z_OK);
@ -771,7 +802,7 @@ png_inflate_read(png_structrp png_ptr, png_bytep read_buffer, uInt read_size,
* the available output is produced; this allows reading of truncated * the available output is produced; this allows reading of truncated
* streams. * streams.
*/ */
ret = inflate(&png_ptr->zstream, ret = PNG_INFLATE(png_ptr,
*chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH)); *chunk_bytes > 0 ? Z_NO_FLUSH : (finish ? Z_FINISH : Z_SYNC_FLUSH));
} }
while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0)); while (ret == Z_OK && (*out_size > 0 || png_ptr->zstream.avail_out > 0));
@ -1670,7 +1701,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
++entry_start; ++entry_start;
/* A sample depth should follow the separator, and we should be on it */ /* A sample depth should follow the separator, and we should be on it */
if (entry_start > buffer + length - 2) if (length < 2U || entry_start > buffer + (length - 2U))
{ {
png_warning(png_ptr, "malformed sPLT chunk"); png_warning(png_ptr, "malformed sPLT chunk");
return; return;
@ -2174,7 +2205,7 @@ png_handle_pCAL(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
/* We need to have at least 12 bytes after the purpose string /* We need to have at least 12 bytes after the purpose string
* in order to get the parameter information. * in order to get the parameter information.
*/ */
if (endptr <= buf + 12) if (endptr - buf <= 12)
{ {
png_chunk_benign_error(png_ptr, "invalid"); png_chunk_benign_error(png_ptr, "invalid");
return; return;
@ -4039,7 +4070,7 @@ png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
* *
* TODO: deal more elegantly with truncated IDAT lists. * TODO: deal more elegantly with truncated IDAT lists.
*/ */
ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); ret = PNG_INFLATE(png_ptr, Z_NO_FLUSH);
/* Take the unconsumed output back. */ /* Take the unconsumed output back. */
if (output != NULL) if (output != NULL)

View File

@ -520,8 +520,8 @@ png_set_PLTE(png_structrp png_ptr, png_inforp info_ptr,
if (png_ptr == NULL || info_ptr == NULL) if (png_ptr == NULL || info_ptr == NULL)
return; return;
max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ? max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
(1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH; (1 << info_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
if (num_palette < 0 || num_palette > (int) max_palette_length) if (num_palette < 0 || num_palette > (int) max_palette_length)
{ {
@ -1573,7 +1573,7 @@ png_set_user_limits (png_structrp png_ptr, png_uint_32 user_width_max,
{ {
/* Images with dimensions larger than these limits will be /* Images with dimensions larger than these limits will be
* rejected by png_set_IHDR(). To accept any PNG datastream * rejected by png_set_IHDR(). To accept any PNG datastream
* regardless of dimensions, set both limits to 0x7ffffff. * regardless of dimensions, set both limits to 0x7fffffff.
*/ */
if (png_ptr == NULL) if (png_ptr == NULL)
return; return;

View File

@ -263,6 +263,9 @@ struct png_struct_def
/* pixel depth used for the row buffers */ /* pixel depth used for the row buffers */
png_byte transformed_pixel_depth; png_byte transformed_pixel_depth;
/* pixel depth after read/write transforms */ /* pixel depth after read/write transforms */
#if PNG_ZLIB_VERNUM >= 0x1240
png_byte zstream_start; /* at start of an input zlib stream */
#endif /* Zlib >= 1.2.4 */
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED) #if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
png_uint_16 filler; /* filler bytes for pixel expansion */ png_uint_16 filler; /* filler bytes for pixel expansion */
#endif #endif

View File

@ -2563,7 +2563,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
if (filter_to_do == PNG_FILTER_SUB) if (filter_to_do == PNG_FILTER_SUB)
/* It's the only filter so no testing is needed */ /* It's the only filter so no testing is needed */
{ {
(void) png_setup_sub_row(png_ptr, bpp, row_bytes, mins); (void) png_setup_sub_row(png_ptr, bpp, row_bytes, mins);
best_row = png_ptr->try_row; best_row = png_ptr->try_row;
} }
@ -2572,7 +2572,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
png_size_t sum; png_size_t sum;
png_size_t lmins = mins; png_size_t lmins = mins;
sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins); sum = png_setup_sub_row(png_ptr, bpp, row_bytes, lmins);
if (sum < mins) if (sum < mins)
{ {
@ -2598,7 +2598,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
png_size_t sum; png_size_t sum;
png_size_t lmins = mins; png_size_t lmins = mins;
sum = png_setup_up_row(png_ptr, row_bytes, lmins); sum = png_setup_up_row(png_ptr, row_bytes, lmins);
if (sum < mins) if (sum < mins)
{ {

View File

@ -98,6 +98,11 @@ extern char *__progname;
#if defined(Q_OS_LINUX) && (defined(__GLIBC__) || QT_HAS_INCLUDE(<sys/syscall.h>)) #if defined(Q_OS_LINUX) && (defined(__GLIBC__) || QT_HAS_INCLUDE(<sys/syscall.h>))
# include <sys/syscall.h> # include <sys/syscall.h>
# if defined(Q_OS_ANDROID) && !defined(SYS_gettid)
# define SYS_gettid __NR_gettid
# endif
static long qt_gettid() static long qt_gettid()
{ {
// no error handling // no error handling

View File

@ -118,14 +118,14 @@ public:
*/ */
// apply defaults for a generic QTypeInfo<T> that didn't provide the new values // apply defaults for a generic QTypeInfo<T> that didn't provide the new values
template <typename T, typename = void> template <typename T, typename = void>
struct QTypeInfoQuery : QTypeInfo<T> struct QTypeInfoQuery : public QTypeInfo<T>
{ {
enum { isRelocatable = !QTypeInfo<T>::isStatic }; enum { isRelocatable = !QTypeInfo<T>::isStatic };
}; };
// if QTypeInfo<T>::isRelocatable exists, use it // if QTypeInfo<T>::isRelocatable exists, use it
template <typename T> template <typename T>
struct QTypeInfoQuery<T, typename QtPrivate::QEnableIf<QTypeInfo<T>::isRelocatable || true>::Type> : QTypeInfo<T> struct QTypeInfoQuery<T, typename QtPrivate::QEnableIf<QTypeInfo<T>::isRelocatable || true>::Type> : public QTypeInfo<T>
{}; {};
/*! /*!

View File

@ -684,10 +684,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
QIncrementalSleepTimer timer(msecs); QIncrementalSleepTimer timer(msecs);
forever { forever {
// Check if we have any data pending: the pipe writer has bool pendingDataInPipe = stdinChannel.writer && stdinChannel.writer->bytesToWrite();
// bytes waiting to written, or it has written data since the
// last time we called stdinChannel.writer->waitForWrite().
bool pendingDataInPipe = stdinChannel.writer && (stdinChannel.writer->bytesToWrite() || stdinChannel.writer->hadWritten());
// If we don't have pending data, and our write buffer is // If we don't have pending data, and our write buffer is
// empty, we fail. // empty, we fail.
@ -815,7 +812,6 @@ qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q); stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q);
QObjectPrivate::connect(stdinChannel.writer, &QWindowsPipeWriter::canWrite, QObjectPrivate::connect(stdinChannel.writer, &QWindowsPipeWriter::canWrite,
this, &QProcessPrivate::_q_canWrite); this, &QProcessPrivate::_q_canWrite);
stdinChannel.writer->start();
} }
return stdinChannel.writer->write(data, maxlen); return stdinChannel.writer->write(data, maxlen);

View File

@ -117,6 +117,7 @@ static inline void appendTestMode(QString &path)
// Map QStandardPaths::StandardLocation to CLSID of SHGetSpecialFolderPath() // Map QStandardPaths::StandardLocation to CLSID of SHGetSpecialFolderPath()
static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type) static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type)
{ {
#ifndef Q_OS_WINCE
static const int clsids[] = { static const int clsids[] = {
CSIDL_DESKTOPDIRECTORY, // DesktopLocation CSIDL_DESKTOPDIRECTORY, // DesktopLocation
CSIDL_PERSONAL, // DocumentsLocation CSIDL_PERSONAL, // DocumentsLocation
@ -136,6 +137,27 @@ static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type)
CSIDL_APPDATA, // AppDataLocation ("Roaming" path) CSIDL_APPDATA, // AppDataLocation ("Roaming" path)
CSIDL_LOCAL_APPDATA, // AppConfigLocation ("Local" path) CSIDL_LOCAL_APPDATA, // AppConfigLocation ("Local" path)
}; };
#else // !Q_OS_WINCE
static const int clsids[] = {
CSIDL_DESKTOPDIRECTORY, // DesktopLocation
CSIDL_PERSONAL, // DocumentsLocation
CSIDL_FONTS, // FontsLocation
CSIDL_PROGRAMS, // ApplicationsLocation
CSIDL_MYMUSIC, // MusicLocation
CSIDL_MYVIDEO, // MoviesLocation
CSIDL_MYPICTURES, // PicturesLocation
-1, -1, // TempLocation/HomeLocation
CSIDL_APPDATA, // AppLocalDataLocation, AppLocalDataLocation = DataLocation
-1, // CacheLocation
CSIDL_APPDATA, // GenericDataLocation
-1, // RuntimeLocation
CSIDL_APPDATA, // ConfigLocation
-1, -1, // DownloadLocation/GenericCacheLocation
CSIDL_APPDATA, // GenericConfigLocation
CSIDL_APPDATA, // AppDataLocation
CSIDL_APPDATA, // AppConfigLocation
};
#endif // Q_OS_WINCE
Q_STATIC_ASSERT(sizeof(clsids) / sizeof(clsids[0]) == size_t(QStandardPaths::AppConfigLocation + 1)); Q_STATIC_ASSERT(sizeof(clsids) / sizeof(clsids[0]) == size_t(QStandardPaths::AppConfigLocation + 1));
return size_t(type) < sizeof(clsids) / sizeof(clsids[0]) ? clsids[type] : -1; return size_t(type) < sizeof(clsids) / sizeof(clsids[0]) ? clsids[type] : -1;

View File

@ -38,28 +38,40 @@
****************************************************************************/ ****************************************************************************/
#include "qwindowspipereader_p.h" #include "qwindowspipereader_p.h"
#include "qwinoverlappedionotifier_p.h" #include "qiodevice_p.h"
#include <qdebug.h>
#include <qelapsedtimer.h> #include <qelapsedtimer.h>
#include <qeventloop.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QWindowsPipeReader::Overlapped::Overlapped(QWindowsPipeReader *reader)
: pipeReader(reader)
{
}
void QWindowsPipeReader::Overlapped::clear()
{
ZeroMemory(this, sizeof(OVERLAPPED));
}
QWindowsPipeReader::QWindowsPipeReader(QObject *parent) QWindowsPipeReader::QWindowsPipeReader(QObject *parent)
: QObject(parent), : QObject(parent),
handle(INVALID_HANDLE_VALUE), handle(INVALID_HANDLE_VALUE),
overlapped(this),
readBufferMaxSize(0), readBufferMaxSize(0),
actualReadBufferSize(0), actualReadBufferSize(0),
stopped(true), stopped(true),
readSequenceStarted(false), readSequenceStarted(false),
notifiedCalled(false),
pipeBroken(false), pipeBroken(false),
readyReadEmitted(false) readyReadPending(false),
inReadyRead(false)
{ {
dataReadNotifier = new QWinOverlappedIoNotifier(this); connect(this, &QWindowsPipeReader::_q_queueReadyRead,
connect(dataReadNotifier, &QWinOverlappedIoNotifier::notified, this, &QWindowsPipeReader::notified); this, &QWindowsPipeReader::emitPendingReadyRead, Qt::QueuedConnection);
} }
static bool qt_cancelIo(HANDLE handle, OVERLAPPED *overlapped) bool qt_cancelIo(HANDLE handle, OVERLAPPED *overlapped)
{ {
typedef BOOL (WINAPI *PtrCancelIoEx)(HANDLE, LPOVERLAPPED); typedef BOOL (WINAPI *PtrCancelIoEx)(HANDLE, LPOVERLAPPED);
static PtrCancelIoEx ptrCancelIoEx = 0; static PtrCancelIoEx ptrCancelIoEx = 0;
@ -88,12 +100,6 @@ void QWindowsPipeReader::setHandle(HANDLE hPipeReadEnd)
actualReadBufferSize = 0; actualReadBufferSize = 0;
handle = hPipeReadEnd; handle = hPipeReadEnd;
pipeBroken = false; pipeBroken = false;
readyReadEmitted = false;
stopped = false;
if (hPipeReadEnd != INVALID_HANDLE_VALUE) {
dataReadNotifier->setHandle(hPipeReadEnd);
dataReadNotifier->setEnabled(true);
}
} }
/*! /*!
@ -104,19 +110,15 @@ void QWindowsPipeReader::stop()
{ {
stopped = true; stopped = true;
if (readSequenceStarted) { if (readSequenceStarted) {
if (qt_cancelIo(handle, &overlapped)) { if (!qt_cancelIo(handle, &overlapped)) {
dataReadNotifier->waitForNotified(-1, &overlapped);
} else {
const DWORD dwError = GetLastError(); const DWORD dwError = GetLastError();
if (dwError != ERROR_NOT_FOUND) { if (dwError != ERROR_NOT_FOUND) {
qErrnoWarning(dwError, "QWindowsPipeReader: qt_cancelIo on handle %x failed.", qErrnoWarning(dwError, "QWindowsPipeReader: qt_cancelIo on handle %x failed.",
handle); handle);
} }
} }
waitForNotification(-1);
} }
readSequenceStarted = false;
dataReadNotifier->setEnabled(false);
handle = INVALID_HANDLE_VALUE;
} }
/*! /*!
@ -174,11 +176,10 @@ bool QWindowsPipeReader::canReadLine() const
\internal \internal
Will be called whenever the read operation completes. Will be called whenever the read operation completes.
*/ */
void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode, void QWindowsPipeReader::notified(DWORD errorCode, DWORD numberOfBytesRead)
OVERLAPPED *notifiedOverlapped)
{ {
if (&overlapped != notifiedOverlapped) notifiedCalled = true;
return; readSequenceStarted = false;
switch (errorCode) { switch (errorCode) {
case ERROR_SUCCESS: case ERROR_SUCCESS:
@ -202,8 +203,6 @@ void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode,
break; break;
} }
readSequenceStarted = false;
// After the reader was stopped, the only reason why this function can be called is the // After the reader was stopped, the only reason why this function can be called is the
// completion of a cancellation. No signals should be emitted, and no new read sequence should // completion of a cancellation. No signals should be emitted, and no new read sequence should
// be started in this case. // be started in this case.
@ -218,13 +217,15 @@ void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode,
actualReadBufferSize += numberOfBytesRead; actualReadBufferSize += numberOfBytesRead;
readBuffer.truncate(actualReadBufferSize); readBuffer.truncate(actualReadBufferSize);
startAsyncRead(); startAsyncRead();
readyReadEmitted = true; if (!readyReadPending) {
emit readyRead(); readyReadPending = true;
emit _q_queueReadyRead(QWindowsPipeReader::QPrivateSignal());
}
} }
/*! /*!
\internal \internal
Reads data from the socket into the readbuffer Reads data from the pipe into the readbuffer.
*/ */
void QWindowsPipeReader::startAsyncRead() void QWindowsPipeReader::startAsyncRead()
{ {
@ -244,41 +245,39 @@ void QWindowsPipeReader::startAsyncRead()
char *ptr = readBuffer.reserve(bytesToRead); char *ptr = readBuffer.reserve(bytesToRead);
stopped = false;
readSequenceStarted = true; readSequenceStarted = true;
ZeroMemory(&overlapped, sizeof(overlapped)); overlapped.clear();
if (ReadFile(handle, ptr, bytesToRead, NULL, &overlapped)) { if (!ReadFileEx(handle, ptr, bytesToRead, &overlapped, &readFileCompleted)) {
// We get notified by the QWinOverlappedIoNotifier - even in the synchronous case. readSequenceStarted = false;
return;
} else {
const DWORD dwError = GetLastError(); const DWORD dwError = GetLastError();
switch (dwError) { switch (dwError) {
case ERROR_IO_PENDING:
// This is not an error. We're getting notified, when data arrives.
return;
case ERROR_MORE_DATA:
// This is not an error. The synchronous read succeeded.
// We're connected to a message mode pipe and the message
// didn't fit into the pipe's system buffer.
// We're getting notified by the QWinOverlappedIoNotifier.
break;
case ERROR_BROKEN_PIPE: case ERROR_BROKEN_PIPE:
case ERROR_PIPE_NOT_CONNECTED: case ERROR_PIPE_NOT_CONNECTED:
{ // It may happen, that the other side closes the connection directly
// It may happen, that the other side closes the connection directly // after writing data. Then we must set the appropriate socket state.
// after writing data. Then we must set the appropriate socket state. pipeBroken = true;
readSequenceStarted = false; emit pipeClosed();
pipeBroken = true; break;
emit pipeClosed();
return;
}
default: default:
readSequenceStarted = false;
emit winError(dwError, QLatin1String("QWindowsPipeReader::startAsyncRead")); emit winError(dwError, QLatin1String("QWindowsPipeReader::startAsyncRead"));
return; break;
} }
} }
} }
/*!
\internal
Called when ReadFileEx finished the read operation.
*/
void QWindowsPipeReader::readFileCompleted(DWORD errorCode, DWORD numberOfBytesTransfered,
OVERLAPPED *overlappedBase)
{
Overlapped *overlapped = static_cast<Overlapped *>(overlappedBase);
overlapped->pipeReader->notified(errorCode, numberOfBytesTransfered);
}
/*! /*!
\internal \internal
Returns the number of available bytes in the pipe. Returns the number of available bytes in the pipe.
@ -298,17 +297,60 @@ DWORD QWindowsPipeReader::checkPipeState()
return 0; return 0;
} }
bool QWindowsPipeReader::waitForNotification(int timeout)
{
QElapsedTimer t;
t.start();
notifiedCalled = false;
int msecs = timeout;
while (SleepEx(msecs == -1 ? INFINITE : msecs, TRUE) == WAIT_IO_COMPLETION) {
if (notifiedCalled)
return true;
// Some other I/O completion routine was called. Wait some more.
msecs = qt_subtract_from_timeout(timeout, t.elapsed());
if (!msecs)
break;
}
return notifiedCalled;
}
void QWindowsPipeReader::emitPendingReadyRead()
{
if (readyReadPending) {
readyReadPending = false;
inReadyRead = true;
emit readyRead();
inReadyRead = false;
}
}
/*! /*!
Waits for the completion of the asynchronous read operation. Waits for the completion of the asynchronous read operation.
Returns \c true, if we've emitted the readyRead signal. Returns \c true, if we've emitted the readyRead signal (non-recursive case)
or readyRead will be emitted by the event loop (recursive case).
*/ */
bool QWindowsPipeReader::waitForReadyRead(int msecs) bool QWindowsPipeReader::waitForReadyRead(int msecs)
{ {
if (!readSequenceStarted) if (!readSequenceStarted)
return false; return false;
readyReadEmitted = false;
dataReadNotifier->waitForNotified(msecs, &overlapped); if (readyReadPending) {
return readyReadEmitted; if (!inReadyRead)
emitPendingReadyRead();
return true;
}
if (!waitForNotification(msecs))
return false;
if (readyReadPending) {
if (!inReadyRead)
emitPendingReadyRead();
return true;
}
return false;
} }
/*! /*!

View File

@ -51,7 +51,6 @@
// We mean it. // We mean it.
// //
#include <qbytearray.h>
#include <qobject.h> #include <qobject.h>
#include <private/qringbuffer_p.h> #include <private/qringbuffer_p.h>
@ -59,9 +58,6 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QWinOverlappedIoNotifier;
class Q_CORE_EXPORT QWindowsPipeReader : public QObject class Q_CORE_EXPORT QWindowsPipeReader : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -70,6 +66,7 @@ public:
~QWindowsPipeReader(); ~QWindowsPipeReader();
void setHandle(HANDLE hPipeReadEnd); void setHandle(HANDLE hPipeReadEnd);
void startAsyncRead();
void stop(); void stop();
void setMaxReadBufferSize(qint64 size) { readBufferMaxSize = size; } void setMaxReadBufferSize(qint64 size) { readBufferMaxSize = size; }
@ -82,31 +79,42 @@ public:
bool waitForReadyRead(int msecs); bool waitForReadyRead(int msecs);
bool waitForPipeClosed(int msecs); bool waitForPipeClosed(int msecs);
void startAsyncRead();
bool isReadOperationActive() const { return readSequenceStarted; } bool isReadOperationActive() const { return readSequenceStarted; }
Q_SIGNALS: Q_SIGNALS:
void winError(ulong, const QString &); void winError(ulong, const QString &);
void readyRead(); void readyRead();
void pipeClosed(); void pipeClosed();
void _q_queueReadyRead(QPrivateSignal);
private Q_SLOTS:
void notified(quint32 numberOfBytesRead, quint32 errorCode, OVERLAPPED *notifiedOverlapped);
private: private:
static void CALLBACK readFileCompleted(DWORD errorCode, DWORD numberOfBytesTransfered,
OVERLAPPED *overlappedBase);
void notified(DWORD errorCode, DWORD numberOfBytesRead);
DWORD checkPipeState(); DWORD checkPipeState();
bool waitForNotification(int timeout);
void emitPendingReadyRead();
class Overlapped : public OVERLAPPED
{
Q_DISABLE_COPY(Overlapped)
public:
explicit Overlapped(QWindowsPipeReader *reader);
void clear();
QWindowsPipeReader *pipeReader;
};
private:
HANDLE handle; HANDLE handle;
OVERLAPPED overlapped; Overlapped overlapped;
QWinOverlappedIoNotifier *dataReadNotifier;
qint64 readBufferMaxSize; qint64 readBufferMaxSize;
QRingBuffer readBuffer; QRingBuffer readBuffer;
qint64 actualReadBufferSize; qint64 actualReadBufferSize;
bool stopped; bool stopped;
bool readSequenceStarted; bool readSequenceStarted;
bool notifiedCalled;
bool pipeBroken; bool pipeBroken;
bool readyReadEmitted; bool readyReadPending;
bool inReadyRead;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -38,144 +38,177 @@
****************************************************************************/ ****************************************************************************/
#include "qwindowspipewriter_p.h" #include "qwindowspipewriter_p.h"
#include "qiodevice_p.h"
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#ifndef QT_NO_THREAD extern bool qt_cancelIo(HANDLE handle, OVERLAPPED *overlapped); // from qwindowspipereader.cpp
QWindowsPipeWriter::QWindowsPipeWriter(HANDLE pipe, QObject * parent)
: QThread(parent), QWindowsPipeWriter::Overlapped::Overlapped(QWindowsPipeWriter *pipeWriter)
writePipe(INVALID_HANDLE_VALUE), : pipeWriter(pipeWriter)
quitNow(false),
hasWritten(false)
{ {
DuplicateHandle(GetCurrentProcess(), pipe, GetCurrentProcess(), }
&writePipe, 0, FALSE, DUPLICATE_SAME_ACCESS);
void QWindowsPipeWriter::Overlapped::clear()
{
ZeroMemory(this, sizeof(OVERLAPPED));
}
QWindowsPipeWriter::QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent)
: QObject(parent),
handle(pipeWriteEnd),
overlapped(this),
numberOfBytesToWrite(0),
pendingBytesWrittenValue(0),
stopped(true),
writeSequenceStarted(false),
notifiedCalled(false),
bytesWrittenPending(false),
inBytesWritten(false)
{
connect(this, &QWindowsPipeWriter::_q_queueBytesWritten,
this, &QWindowsPipeWriter::emitPendingBytesWrittenValue, Qt::QueuedConnection);
} }
QWindowsPipeWriter::~QWindowsPipeWriter() QWindowsPipeWriter::~QWindowsPipeWriter()
{ {
lock.lock(); stop();
quitNow = true;
waitCondition.wakeOne();
lock.unlock();
if (!wait(30000))
terminate();
CloseHandle(writePipe);
} }
bool QWindowsPipeWriter::waitForWrite(int msecs) bool QWindowsPipeWriter::waitForWrite(int msecs)
{ {
QMutexLocker locker(&lock); if (!writeSequenceStarted)
bool hadWritten = hasWritten;
hasWritten = false;
if (hadWritten)
return true;
if (!waitCondition.wait(&lock, msecs))
return false; return false;
hadWritten = hasWritten;
hasWritten = false; if (bytesWrittenPending) {
return hadWritten; if (!inBytesWritten)
emitPendingBytesWrittenValue();
return true;
}
if (!waitForNotification(msecs))
return false;
if (bytesWrittenPending) {
if (!inBytesWritten)
emitPendingBytesWrittenValue();
return true;
}
return false;
} }
qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen) qint64 QWindowsPipeWriter::bytesToWrite() const
{ {
if (!isRunning()) return numberOfBytesToWrite;
return -1;
QMutexLocker locker(&lock);
data.append(ptr, maxlen);
waitCondition.wakeOne();
return maxlen;
} }
class QPipeWriterOverlapped void QWindowsPipeWriter::emitPendingBytesWrittenValue()
{ {
public: if (bytesWrittenPending) {
QPipeWriterOverlapped() bytesWrittenPending = false;
{ const qint64 bytes = pendingBytesWrittenValue;
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); pendingBytesWrittenValue = 0;
}
~QPipeWriterOverlapped() inBytesWritten = true;
{ emit bytesWritten(bytes);
CloseHandle(overlapped.hEvent); inBytesWritten = false;
}
void prepare()
{
const HANDLE hEvent = overlapped.hEvent;
ZeroMemory(&overlapped, sizeof overlapped);
overlapped.hEvent = hEvent;
}
OVERLAPPED *operator&()
{
return &overlapped;
}
private:
OVERLAPPED overlapped;
};
void QWindowsPipeWriter::run()
{
QPipeWriterOverlapped overl;
forever {
lock.lock();
while(data.isEmpty() && (!quitNow)) {
waitCondition.wakeOne();
waitCondition.wait(&lock);
}
if (quitNow) {
lock.unlock();
quitNow = false;
break;
}
QByteArray copy = data;
lock.unlock();
const char *ptrData = copy.data();
qint64 maxlen = copy.size();
qint64 totalWritten = 0;
overl.prepare();
while ((!quitNow) && totalWritten < maxlen) {
DWORD written = 0;
if (!WriteFile(writePipe, ptrData + totalWritten,
maxlen - totalWritten, &written, &overl)) {
const DWORD writeError = GetLastError();
if (writeError == 0xE8/*NT_STATUS_INVALID_USER_BUFFER*/) {
// give the os a rest
msleep(100);
continue;
}
if (writeError != ERROR_IO_PENDING) {
qErrnoWarning(writeError, "QWindowsPipeWriter: async WriteFile failed.");
return;
}
if (!GetOverlappedResult(writePipe, &overl, &written, TRUE)) {
qErrnoWarning(GetLastError(), "QWindowsPipeWriter: GetOverlappedResult failed.");
return;
}
}
totalWritten += written;
#if defined QPIPEWRITER_DEBUG
qDebug("QWindowsPipeWriter::run() wrote %d %d/%d bytes",
written, int(totalWritten), int(maxlen));
#endif
lock.lock();
data.remove(0, written);
hasWritten = true;
lock.unlock();
}
emit bytesWritten(totalWritten);
emit canWrite(); emit canWrite();
} }
} }
#endif //QT_NO_THREAD void QWindowsPipeWriter::writeFileCompleted(DWORD errorCode, DWORD numberOfBytesTransfered,
OVERLAPPED *overlappedBase)
{
Overlapped *overlapped = static_cast<Overlapped *>(overlappedBase);
overlapped->pipeWriter->notified(errorCode, numberOfBytesTransfered);
}
/*!
\internal
Will be called whenever the write operation completes.
*/
void QWindowsPipeWriter::notified(DWORD errorCode, DWORD numberOfBytesWritten)
{
notifiedCalled = true;
writeSequenceStarted = false;
numberOfBytesToWrite = 0;
switch (errorCode) {
case ERROR_SUCCESS:
break;
case ERROR_OPERATION_ABORTED:
if (stopped)
break;
// fall through
default:
qErrnoWarning(errorCode, "QWindowsPipeWriter: asynchronous write failed.");
break;
}
// After the writer was stopped, the only reason why this function can be called is the
// completion of a cancellation. No signals should be emitted, and no new write sequence should
// be started in this case.
if (stopped)
return;
pendingBytesWrittenValue += qint64(numberOfBytesWritten);
if (!bytesWrittenPending) {
bytesWrittenPending = true;
emit _q_queueBytesWritten(QWindowsPipeWriter::QPrivateSignal());
}
}
bool QWindowsPipeWriter::waitForNotification(int timeout)
{
QElapsedTimer t;
t.start();
notifiedCalled = false;
int msecs = timeout;
while (SleepEx(msecs == -1 ? INFINITE : msecs, TRUE) == WAIT_IO_COMPLETION) {
if (notifiedCalled)
return true;
// Some other I/O completion routine was called. Wait some more.
msecs = qt_subtract_from_timeout(timeout, t.elapsed());
if (!msecs)
break;
}
return notifiedCalled;
}
qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen)
{
if (writeSequenceStarted)
return 0;
overlapped.clear();
numberOfBytesToWrite = maxlen;
stopped = false;
writeSequenceStarted = true;
if (!WriteFileEx(handle, ptr, maxlen, &overlapped, &writeFileCompleted)) {
writeSequenceStarted = false;
qErrnoWarning("QWindowsPipeWriter::write failed.");
}
return maxlen;
}
void QWindowsPipeWriter::stop()
{
stopped = true;
if (writeSequenceStarted) {
if (!qt_cancelIo(handle, &overlapped)) {
const DWORD dwError = GetLastError();
if (dwError != ERROR_NOT_FOUND) {
qErrnoWarning(dwError, "QWindowsPipeWriter: qt_cancelIo on handle %x failed.",
handle);
}
}
waitForNotification(-1);
}
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -52,16 +52,11 @@
// //
#include <qelapsedtimer.h> #include <qelapsedtimer.h>
#include <qthread.h> #include <qobject.h>
#include <qmutex.h>
#include <qwaitcondition.h>
#include <qt_windows.h> #include <qt_windows.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#ifndef QT_NO_THREAD
#define SLEEPMIN 10 #define SLEEPMIN 10
#define SLEEPMAX 500 #define SLEEPMAX 500
@ -110,45 +105,50 @@ private:
int nextSleep; int nextSleep;
}; };
class Q_CORE_EXPORT QWindowsPipeWriter : public QThread class Q_CORE_EXPORT QWindowsPipeWriter : public QObject
{ {
Q_OBJECT Q_OBJECT
public:
explicit QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent = 0);
~QWindowsPipeWriter();
qint64 write(const char *data, qint64 maxlen);
void stop();
bool waitForWrite(int msecs);
qint64 bytesToWrite() const;
Q_SIGNALS: Q_SIGNALS:
void canWrite(); void canWrite();
void bytesWritten(qint64 bytes); void bytesWritten(qint64 bytes);
void _q_queueBytesWritten(QPrivateSignal);
public:
explicit QWindowsPipeWriter(HANDLE writePipe, QObject * parent = 0);
~QWindowsPipeWriter();
bool waitForWrite(int msecs);
qint64 write(const char *data, qint64 maxlen);
qint64 bytesToWrite() const
{
QMutexLocker locker(&lock);
return data.size();
}
bool hadWritten() const
{
return hasWritten;
}
protected:
void run();
private: private:
QByteArray data; static void CALLBACK writeFileCompleted(DWORD errorCode, DWORD numberOfBytesTransfered,
QWaitCondition waitCondition; OVERLAPPED *overlappedBase);
mutable QMutex lock; void notified(DWORD errorCode, DWORD numberOfBytesWritten);
HANDLE writePipe; bool waitForNotification(int timeout);
volatile bool quitNow; void emitPendingBytesWrittenValue();
bool hasWritten;
};
#endif //QT_NO_THREAD class Overlapped : public OVERLAPPED
{
Q_DISABLE_COPY(Overlapped)
public:
explicit Overlapped(QWindowsPipeWriter *pipeWriter);
void clear();
QWindowsPipeWriter *pipeWriter;
};
HANDLE handle;
Overlapped overlapped;
qint64 numberOfBytesToWrite;
qint64 pendingBytesWrittenValue;
bool stopped;
bool writeSequenceStarted;
bool notifiedCalled;
bool bytesWrittenPending;
bool inBytesWritten;
};
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -216,8 +216,10 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
const QVector<HANDLE> timerHandles = d->timerIdToHandle.values().toVector(); const QVector<HANDLE> timerHandles = d->timerIdToHandle.values().toVector();
if (waitTime) if (waitTime)
emit aboutToBlock(); emit aboutToBlock();
bool timerEventsSent = false;
DWORD waitResult = WaitForMultipleObjectsEx(timerHandles.count(), timerHandles.constData(), FALSE, waitTime, TRUE); DWORD waitResult = WaitForMultipleObjectsEx(timerHandles.count(), timerHandles.constData(), FALSE, waitTime, TRUE);
if (waitResult >= WAIT_OBJECT_0 && waitResult < WAIT_OBJECT_0 + timerHandles.count()) { while (waitResult >= WAIT_OBJECT_0 && waitResult < WAIT_OBJECT_0 + timerHandles.count()) {
timerEventsSent = true;
const HANDLE handle = timerHandles.value(waitResult - WAIT_OBJECT_0); const HANDLE handle = timerHandles.value(waitResult - WAIT_OBJECT_0);
ResetEvent(handle); ResetEvent(handle);
const int timerId = d->timerHandleToId.value(handle); const int timerId = d->timerHandleToId.value(handle);
@ -232,12 +234,10 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
// Update timer's targetTime // Update timer's targetTime
const quint64 targetTime = qt_msectime() + info.interval; const quint64 targetTime = qt_msectime() + info.interval;
info.targetTime = targetTime; info.targetTime = targetTime;
emit awake(); waitResult = WaitForMultipleObjectsEx(timerHandles.count(), timerHandles.constData(), FALSE, 0, TRUE);
return true;
} }
emit awake(); emit awake();
if (timerEventsSent || userEventsSent)
if (userEventsSent)
return true; return true;
// We cannot wait infinitely like on other platforms, as // We cannot wait infinitely like on other platforms, as

View File

@ -119,8 +119,8 @@ public:
Q_INVOKABLE explicit QObject(QObject *parent=Q_NULLPTR); Q_INVOKABLE explicit QObject(QObject *parent=Q_NULLPTR);
virtual ~QObject(); virtual ~QObject();
virtual bool event(QEvent *); virtual bool event(QEvent *event);
virtual bool eventFilter(QObject *, QEvent *); virtual bool eventFilter(QObject *watched, QEvent *event);
#ifdef Q_QDOC #ifdef Q_QDOC
static QString tr(const char *sourceText, const char *comment = Q_NULLPTR, int n = -1); static QString tr(const char *sourceText, const char *comment = Q_NULLPTR, int n = -1);
@ -195,9 +195,9 @@ public:
inline const QObjectList &children() const { return d_ptr->children; } inline const QObjectList &children() const { return d_ptr->children; }
void setParent(QObject *); void setParent(QObject *parent);
void installEventFilter(QObject *); void installEventFilter(QObject *filterObj);
void removeEventFilter(QObject *); void removeEventFilter(QObject *obj);
static QMetaObject::Connection connect(const QObject *sender, const char *signal, static QMetaObject::Connection connect(const QObject *sender, const char *signal,
const QObject *receiver, const char *member, Qt::ConnectionType = Qt::AutoConnection); const QObject *receiver, const char *member, Qt::ConnectionType = Qt::AutoConnection);
@ -428,9 +428,9 @@ protected:
int receivers(const char* signal) const; int receivers(const char* signal) const;
bool isSignalConnected(const QMetaMethod &signal) const; bool isSignalConnected(const QMetaMethod &signal) const;
virtual void timerEvent(QTimerEvent *); virtual void timerEvent(QTimerEvent *event);
virtual void childEvent(QChildEvent *); virtual void childEvent(QChildEvent *event);
virtual void customEvent(QEvent *); virtual void customEvent(QEvent *event);
virtual void connectNotify(const QMetaMethod &signal); virtual void connectNotify(const QMetaMethod &signal);
virtual void disconnectNotify(const QMetaMethod &signal); virtual void disconnectNotify(const QMetaMethod &signal);

View File

@ -310,8 +310,9 @@ QThreadPrivate::~QThreadPrivate()
The effect of the \a priority parameter is dependent on the The effect of the \a priority parameter is dependent on the
operating system's scheduling policy. In particular, the \a priority operating system's scheduling policy. In particular, the \a priority
will be ignored on systems that do not support thread priorities will be ignored on systems that do not support thread priorities
(such as on Linux, see http://linux.die.net/man/2/sched_setscheduler (such as on Linux, see the
for more details). \l {http://linux.die.net/man/2/sched_setscheduler}{sched_setscheduler}
documentation for more details).
\sa run(), terminate() \sa run(), terminate()
*/ */

View File

@ -252,7 +252,7 @@ Q_DECL_CONSTEXPR inline QPoint QRect::bottomLeft() const Q_DECL_NOTHROW
{ return QPoint(x1, y2); } { return QPoint(x1, y2); }
Q_DECL_CONSTEXPR inline QPoint QRect::center() const Q_DECL_NOTHROW Q_DECL_CONSTEXPR inline QPoint QRect::center() const Q_DECL_NOTHROW
{ return QPoint((x1+x2)/2, (y1+y2)/2); } { return QPoint(int((qint64(x1)+x2)/2), int((qint64(y1)+y2)/2)); } // cast avoids overflow on addition
Q_DECL_CONSTEXPR inline int QRect::width() const Q_DECL_NOTHROW Q_DECL_CONSTEXPR inline int QRect::width() const Q_DECL_NOTHROW
{ return x2 - x1 + 1; } { return x2 - x1 + 1; }

View File

@ -67,7 +67,7 @@ static QTimeZonePrivate *newBackendTimeZone()
#elif defined Q_OS_UNIX #elif defined Q_OS_UNIX
return new QTzTimeZonePrivate(); return new QTzTimeZonePrivate();
// Registry based timezone backend not available on WinRT // Registry based timezone backend not available on WinRT
#elif defined Q_OS_WIN && !defined Q_OS_WINRT #elif defined Q_OS_WIN
return new QWinTimeZonePrivate(); return new QWinTimeZonePrivate();
#elif defined QT_USE_ICU #elif defined QT_USE_ICU
return new QIcuTimeZonePrivate(); return new QIcuTimeZonePrivate();
@ -94,7 +94,7 @@ static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId)
#elif defined Q_OS_UNIX #elif defined Q_OS_UNIX
return new QTzTimeZonePrivate(ianaId); return new QTzTimeZonePrivate(ianaId);
// Registry based timezone backend not available on WinRT // Registry based timezone backend not available on WinRT
#elif defined Q_OS_WIN && !defined Q_OS_WINRT #elif defined Q_OS_WIN
return new QWinTimeZonePrivate(ianaId); return new QWinTimeZonePrivate(ianaId);
#elif defined QT_USE_ICU #elif defined QT_USE_ICU
return new QIcuTimeZonePrivate(ianaId); return new QIcuTimeZonePrivate(ianaId);

View File

@ -48,6 +48,10 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#ifndef Q_OS_WINRT
#define QT_USE_REGISTRY_TIMEZONE 1
#endif
/* /*
Private Private
@ -65,9 +69,10 @@ QT_BEGIN_NAMESPACE
// Vista introduced support for historic data, see MSDN docs on DYNAMIC_TIME_ZONE_INFORMATION // Vista introduced support for historic data, see MSDN docs on DYNAMIC_TIME_ZONE_INFORMATION
// http://msdn.microsoft.com/en-gb/library/windows/desktop/ms724253%28v=vs.85%29.aspx // http://msdn.microsoft.com/en-gb/library/windows/desktop/ms724253%28v=vs.85%29.aspx
#ifdef QT_USE_REGISTRY_TIMEZONE
static const char tzRegPath[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones"; static const char tzRegPath[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones";
static const char currTzRegPath[] = "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation"; static const char currTzRegPath[] = "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation";
#endif
enum { enum {
MIN_YEAR = -292275056, MIN_YEAR = -292275056,
@ -129,6 +134,7 @@ static bool equalTzi(const TIME_ZONE_INFORMATION &tzi1, const TIME_ZONE_INFORMAT
&& wcscmp(tzi1.DaylightName, tzi2.DaylightName) == 0); && wcscmp(tzi1.DaylightName, tzi2.DaylightName) == 0);
} }
#ifdef QT_USE_REGISTRY_TIMEZONE
static bool openRegistryKey(const QString &keyPath, HKEY *key) static bool openRegistryKey(const QString &keyPath, HKEY *key)
{ {
return (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (const wchar_t*)keyPath.utf16(), 0, KEY_READ, key) return (RegOpenKeyEx(HKEY_LOCAL_MACHINE, (const wchar_t*)keyPath.utf16(), 0, KEY_READ, key)
@ -203,9 +209,61 @@ static TIME_ZONE_INFORMATION getRegistryTzi(const QByteArray &windowsId, bool *o
return tzi; return tzi;
} }
#else // QT_USE_REGISTRY_TIMEZONE
struct QWinDynamicTimeZone
{
QString standardName;
QString daylightName;
QString timezoneName;
qint32 bias;
bool daylightTime;
};
typedef QHash<QByteArray, QWinDynamicTimeZone> QWinRTTimeZoneHash;
Q_GLOBAL_STATIC(QWinRTTimeZoneHash, gTimeZones)
static void enumerateTimeZones()
{
DYNAMIC_TIME_ZONE_INFORMATION dtzInfo;
quint32 index = 0;
QString prevTimeZoneKeyName;
while (SUCCEEDED(EnumDynamicTimeZoneInformation(index++, &dtzInfo))) {
QWinDynamicTimeZone item;
item.timezoneName = QString::fromWCharArray(dtzInfo.TimeZoneKeyName);
// As soon as key name repeats, break. Some systems continue to always
// return the last item independent of index being out of range
if (item.timezoneName == prevTimeZoneKeyName)
break;
item.standardName = QString::fromWCharArray(dtzInfo.StandardName);
item.daylightName = QString::fromWCharArray(dtzInfo.DaylightName);
item.daylightTime = !dtzInfo.DynamicDaylightTimeDisabled;
item.bias = dtzInfo.Bias;
gTimeZones->insert(item.timezoneName.toUtf8(), item);
prevTimeZoneKeyName = item.timezoneName;
}
}
static DYNAMIC_TIME_ZONE_INFORMATION dynamicInfoForId(const QByteArray &windowsId)
{
DYNAMIC_TIME_ZONE_INFORMATION dtzInfo;
quint32 index = 0;
QString prevTimeZoneKeyName;
while (SUCCEEDED(EnumDynamicTimeZoneInformation(index++, &dtzInfo))) {
const QString timeZoneName = QString::fromWCharArray(dtzInfo.TimeZoneKeyName);
if (timeZoneName == QLatin1String(windowsId))
break;
if (timeZoneName == prevTimeZoneKeyName)
break;
prevTimeZoneKeyName = timeZoneName;
}
return dtzInfo;
}
#endif // QT_USE_REGISTRY_TIMEZONE
static QList<QByteArray> availableWindowsIds() static QList<QByteArray> availableWindowsIds()
{ {
#ifdef QT_USE_REGISTRY_TIMEZONE
// TODO Consider caching results in a global static, very unlikely to change. // TODO Consider caching results in a global static, very unlikely to change.
QList<QByteArray> list; QList<QByteArray> list;
HKEY key = NULL; HKEY key = NULL;
@ -223,10 +281,16 @@ static QList<QByteArray> availableWindowsIds()
RegCloseKey(key); RegCloseKey(key);
} }
return list; return list;
#else // QT_USE_REGISTRY_TIMEZONE
if (gTimeZones->isEmpty())
enumerateTimeZones();
return gTimeZones->keys();
#endif // QT_USE_REGISTRY_TIMEZONE
} }
static QByteArray windowsSystemZoneId() static QByteArray windowsSystemZoneId()
{ {
#ifdef QT_USE_REGISTRY_TIMEZONE
// On Vista and later is held in the value TimeZoneKeyName in key currTzRegPath // On Vista and later is held in the value TimeZoneKeyName in key currTzRegPath
QString id; QString id;
HKEY key = NULL; HKEY key = NULL;
@ -248,6 +312,11 @@ static QByteArray windowsSystemZoneId()
if (equalTzi(getRegistryTzi(winId, &ok), sysTzi)) if (equalTzi(getRegistryTzi(winId, &ok), sysTzi))
return winId; return winId;
} }
#else // QT_USE_REGISTRY_TIMEZONE
DYNAMIC_TIME_ZONE_INFORMATION dtzi;
if (SUCCEEDED(GetDynamicTimeZoneInformation(&dtzi)))
return QString::fromWCharArray(dtzi.TimeZoneKeyName).toLocal8Bit();
#endif // QT_USE_REGISTRY_TIMEZONE
// If we can't determine the current ID use UTC // If we can't determine the current ID use UTC
return QTimeZonePrivate::utcQByteArray(); return QTimeZonePrivate::utcQByteArray();
@ -368,6 +437,7 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId)
} }
if (!m_windowsId.isEmpty()) { if (!m_windowsId.isEmpty()) {
#ifdef QT_USE_REGISTRY_TIMEZONE
// Open the base TZI for the time zone // Open the base TZI for the time zone
HKEY baseKey = NULL; HKEY baseKey = NULL;
const QString baseKeyPath = QString::fromUtf8(tzRegPath) + QLatin1Char('\\') const QString baseKeyPath = QString::fromUtf8(tzRegPath) + QLatin1Char('\\')
@ -404,6 +474,34 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId)
} }
RegCloseKey(baseKey); RegCloseKey(baseKey);
} }
#else // QT_USE_REGISTRY_TIMEZONE
if (gTimeZones->isEmpty())
enumerateTimeZones();
QWinRTTimeZoneHash::const_iterator it = gTimeZones->find(m_windowsId);
if (it != gTimeZones->constEnd()) {
m_displayName = it->timezoneName;
m_standardName = it->standardName;
m_daylightName = it->daylightName;
DWORD firstYear = 0;
DWORD lastYear = 0;
DYNAMIC_TIME_ZONE_INFORMATION dtzi = dynamicInfoForId(m_windowsId);
GetDynamicTimeZoneInformationEffectiveYears(&dtzi, &firstYear, &lastYear);
// If there is no dynamic information, you can still query for
// year 0, which helps simplifying following part
for (DWORD year = firstYear; year <= lastYear; ++year) {
TIME_ZONE_INFORMATION tzi;
if (!GetTimeZoneInformationForYear(year, &dtzi, &tzi))
continue;
QWinTransitionRule rule;
rule.standardTimeBias = tzi.Bias + tzi.StandardBias;
rule.daylightTimeBias = tzi.Bias + tzi.DaylightBias - rule.standardTimeBias;
rule.standardTimeRule = tzi.StandardDate;
rule.daylightTimeRule = tzi.DaylightDate;
rule.startYear = year;
m_tranRules.append(rule);
}
}
#endif // QT_USE_REGISTRY_TIMEZONE
} }
// If there are no rules then we failed to find a windowsId or any tzi info // If there are no rules then we failed to find a windowsId or any tzi info

View File

@ -144,9 +144,11 @@ else:unix {
SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp tools/qtimezoneprivate_tz.cpp SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp tools/qtimezoneprivate_tz.cpp
} }
else:win32 { else:win32 {
SOURCES += tools/qelapsedtimer_win.cpp tools/qlocale_win.cpp SOURCES += tools/qelapsedtimer_win.cpp \
!winrt: SOURCES += tools/qtimezoneprivate_win.cpp tools/qlocale_win.cpp \
tools/qtimezoneprivate_win.cpp
winphone: LIBS_PRIVATE += -lWindowsPhoneGlobalizationUtil winphone: LIBS_PRIVATE += -lWindowsPhoneGlobalizationUtil
winrt-*-msvc2013: LIBS += advapi32.lib
} else:integrity:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp } else:integrity:SOURCES += tools/qelapsedtimer_unix.cpp tools/qlocale_unix.cpp
else:SOURCES += tools/qelapsedtimer_generic.cpp else:SOURCES += tools/qelapsedtimer_generic.cpp

View File

@ -486,6 +486,11 @@ QDBusSpyCallEvent::~QDBusSpyCallEvent()
} }
void QDBusSpyCallEvent::placeMetaCall(QObject *) void QDBusSpyCallEvent::placeMetaCall(QObject *)
{
invokeSpyHooks(msg, hooks, hookCount);
}
inline void QDBusSpyCallEvent::invokeSpyHooks(const QDBusMessage &msg, const Hook *hooks, int hookCount)
{ {
// call the spy hook list // call the spy hook list
for (int i = 0; i < hookCount; ++i) for (int i = 0; i < hookCount; ++i)
@ -515,7 +520,12 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
{ {
if (!ref.load()) if (!ref.load())
return false; return false;
if (!dispatchEnabled && !QDBusMessagePrivate::isLocal(amsg)) {
// local message are always delivered, regardless of filtering
// or whether the dispatcher is enabled
bool isLocal = QDBusMessagePrivate::isLocal(amsg);
if (!dispatchEnabled && !isLocal) {
// queue messages only, we'll handle them later // queue messages only, we'll handle them later
qDBusDebug() << this << "delivery is suspended"; qDBusDebug() << this << "delivery is suspended";
pendingMessages << amsg; pendingMessages << amsg;
@ -529,13 +539,23 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
// let them see the signal too // let them see the signal too
return false; return false;
case QDBusMessage::MethodCallMessage: case QDBusMessage::MethodCallMessage:
// run it through the spy filters (if any) before the regular processing // run it through the spy filters (if any) before the regular processing:
// a) if it's a local message, we're in the caller's thread, so invoke the filter directly
// b) if it's an external message, post to the main thread
if (Q_UNLIKELY(qDBusSpyHookList.exists()) && qApp) { if (Q_UNLIKELY(qDBusSpyHookList.exists()) && qApp) {
const QDBusSpyHookList &list = *qDBusSpyHookList; const QDBusSpyHookList &list = *qDBusSpyHookList;
qDBusDebug() << this << "invoking message spies"; if (isLocal) {
QCoreApplication::postEvent(qApp, new QDBusSpyCallEvent(this, QDBusConnection(this), Q_ASSERT(QThread::currentThread() != thread());
amsg, list.constData(), list.size())); qDBusDebug() << this << "invoking message spies directly";
return true; QDBusSpyCallEvent::invokeSpyHooks(amsg, list.constData(), list.size());
} else {
qDBusDebug() << this << "invoking message spies via event";
QCoreApplication::postEvent(qApp, new QDBusSpyCallEvent(this, QDBusConnection(this),
amsg, list.constData(), list.size()));
// we'll be called back, so return
return true;
}
} }
handleObjectCall(amsg); handleObjectCall(amsg);
@ -1456,9 +1476,9 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
// that means the dispatchLock mutex is locked // that means the dispatchLock mutex is locked
// must not call out to user code in that case // must not call out to user code in that case
// //
// however, if the message is internal, handleMessage was called // however, if the message is internal, handleMessage was called directly
// directly and no lock is in place. We can therefore call out to // (user's thread) and no lock is in place. We can therefore call out to
// user code, if necessary // user code, if necessary.
ObjectTreeNode result; ObjectTreeNode result;
int usedLength; int usedLength;
QThread *objThread = 0; QThread *objThread = 0;
@ -1497,12 +1517,14 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
usedLength, msg)); usedLength, msg));
return; return;
} else if (objThread != QThread::currentThread()) { } else if (objThread != QThread::currentThread()) {
// synchronize with other thread // looped-back message, targeting another thread:
// synchronize with it
postEventToThread(HandleObjectCallPostEventAction, result.obj, postEventToThread(HandleObjectCallPostEventAction, result.obj,
new QDBusActivateObjectEvent(QDBusConnection(this), this, result, new QDBusActivateObjectEvent(QDBusConnection(this), this, result,
usedLength, msg, &sem)); usedLength, msg, &sem));
semWait = true; semWait = true;
} else { } else {
// looped-back message, targeting current thread
semWait = false; semWait = false;
} }
} // release the lock } // release the lock

View File

@ -151,6 +151,7 @@ public:
{} {}
~QDBusSpyCallEvent(); ~QDBusSpyCallEvent();
void placeMetaCall(QObject *) Q_DECL_OVERRIDE; void placeMetaCall(QObject *) Q_DECL_OVERRIDE;
static inline void invokeSpyHooks(const QDBusMessage &msg, const Hook *hooks, int hookCount);
QDBusConnection conn; // keeps the refcount in QDBusConnectionPrivate up QDBusConnection conn; // keeps the refcount in QDBusConnectionPrivate up
QDBusMessage msg; QDBusMessage msg;

View File

@ -48,52 +48,31 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QShapedPixmapWindow::QShapedPixmapWindow(QScreen *screen) QShapedPixmapWindow::QShapedPixmapWindow(QScreen *screen)
: QWindow(screen), : m_useCompositing(true)
m_backingStore(0),
m_useCompositing(true)
{ {
setScreen(screen);
QSurfaceFormat format; QSurfaceFormat format;
format.setAlphaBufferSize(8); format.setAlphaBufferSize(8);
setFormat(format); setFormat(format);
setSurfaceType(RasterSurface); setFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint
setFlags(Qt::ToolTip | Qt::FramelessWindowHint | | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
Qt::X11BypassWindowManagerHint | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
create();
m_backingStore = new QBackingStore(this);
} }
QShapedPixmapWindow::~QShapedPixmapWindow() QShapedPixmapWindow::~QShapedPixmapWindow()
{ {
delete m_backingStore;
m_backingStore = 0;
}
void QShapedPixmapWindow::render()
{
QRect rect(QPoint(), geometry().size());
m_backingStore->beginPaint(rect);
QPaintDevice *device = m_backingStore->paintDevice();
{
QPainter p(device);
if (m_useCompositing)
p.setCompositionMode(QPainter::CompositionMode_Source);
else
p.fillRect(rect, QGuiApplication::palette().base());
p.drawPixmap(0, 0, m_pixmap);
}
m_backingStore->endPaint();
m_backingStore->flush(rect);
} }
void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap) void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap)
{ {
m_pixmap = pixmap; m_pixmap = pixmap;
if (!m_useCompositing) if (!m_useCompositing) {
setMask(m_pixmap.mask()); const QBitmap mask = m_pixmap.mask();
if (!mask.isNull()) {
if (!handle())
create();
setMask(mask);
}
}
} }
void QShapedPixmapWindow::setHotspot(const QPoint &hotspot) void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
@ -101,19 +80,28 @@ void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
m_hotSpot = hotspot; m_hotSpot = hotspot;
} }
void QShapedPixmapWindow::updateGeometry(const QPoint &pos) void QShapedPixmapWindow::paintEvent(QPaintEvent *)
{ {
if (m_pixmap.isNull()) if (!m_pixmap.isNull()) {
m_backingStore->resize(QSize(1,1)); const QRect rect(QPoint(0, 0), size());
else if (m_backingStore->size() != m_pixmap.size()) QPainter painter(this);
m_backingStore->resize(m_pixmap.size()); if (m_useCompositing)
painter.setCompositionMode(QPainter::CompositionMode_Source);
setGeometry(QRect(pos - m_hotSpot, m_backingStore->size())); else
painter.fillRect(rect, QGuiApplication::palette().base());
painter.drawPixmap(rect, m_pixmap);
}
} }
void QShapedPixmapWindow::exposeEvent(QExposeEvent *) void QShapedPixmapWindow::updateGeometry(const QPoint &pos)
{ {
render(); QSize size(1, 1);
if (!m_pixmap.isNull()) {
size = qFuzzyCompare(m_pixmap.devicePixelRatio(), 1.0)
? m_pixmap.size()
: (QSizeF(m_pixmap.size()) / m_pixmap.devicePixelRatio()).toSize();
}
setGeometry(QRect(pos - m_hotSpot, size));
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -51,21 +51,18 @@
// We mean it. // We mean it.
// //
#include <QtGui/QWindow> #include <QtGui/QRasterWindow>
#include <QtGui/QPixmap> #include <QtGui/QPixmap>
#include <QtGui/QBackingStore>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QShapedPixmapWindow : public QWindow class QShapedPixmapWindow : public QRasterWindow
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit QShapedPixmapWindow(QScreen *screen = 0); explicit QShapedPixmapWindow(QScreen *screen = 0);
~QShapedPixmapWindow(); ~QShapedPixmapWindow();
void render();
void setUseCompositing(bool on) { m_useCompositing = on; } void setUseCompositing(bool on) { m_useCompositing = on; }
void setPixmap(const QPixmap &pixmap); void setPixmap(const QPixmap &pixmap);
void setHotspot(const QPoint &hotspot); void setHotspot(const QPoint &hotspot);
@ -73,10 +70,9 @@ public:
void updateGeometry(const QPoint &pos); void updateGeometry(const QPoint &pos);
protected: protected:
void exposeEvent(QExposeEvent *) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
private: private:
QBackingStore *m_backingStore;
QPixmap m_pixmap; QPixmap m_pixmap;
QPoint m_hotSpot; QPoint m_hotSpot;
bool m_useCompositing; bool m_useCompositing;

View File

@ -68,8 +68,8 @@ static inline uint sourceOver(uint d, uint color)
inline static int F16Dot16FixedDiv(int x, int y) inline static int F16Dot16FixedDiv(int x, int y)
{ {
if (qAbs(x) > 0x7fff) if (qAbs(x) > 0x7fff)
return (((qlonglong)x) << 16) / y; return qlonglong(x) * (1<<16) / y;
return (x << 16) / y; return x * (1<<16) / y;
} }
typedef void (*DrawPixel)(QCosmeticStroker *stroker, int x, int y, int coverage); typedef void (*DrawPixel)(QCosmeticStroker *stroker, int x, int y, int coverage);
@ -441,14 +441,14 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
qSwap(x1, x2); qSwap(x1, x2);
} }
int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1); int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);
int x = x1 << 10; int x = x1 * (1<<10);
int y = (y1 + 32) >> 6; int y = (y1 + 32) >> 6;
int ys = (y2 + 32) >> 6; int ys = (y2 + 32) >> 6;
int round = (xinc > 0) ? 32 : 0; int round = (xinc > 0) ? 32 : 0;
if (y != ys) { if (y != ys) {
x += ( ((((y << 6) + round - y1))) * xinc ) >> 6; x += ((y * (1<<6)) + round - y1) * xinc >> 6;
if (swapped) { if (swapped) {
lastPixel.x = x >> 16; lastPixel.x = x >> 16;
@ -480,7 +480,7 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
int round = (yinc > 0) ? 32 : 0; int round = (yinc > 0) ? 32 : 0;
if (x != xs) { if (x != xs) {
y += ( ((((x << 6) + round - x1))) * yinc ) >> 6; y += ((x * (1<<6)) + round - x1) * yinc >> 6;
if (swapped) { if (swapped) {
lastPixel.x = x; lastPixel.x = x;
@ -759,7 +759,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
dir = QCosmeticStroker::BottomToTop; dir = QCosmeticStroker::BottomToTop;
} }
int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1); int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);
int x = x1 << 10; int x = x1 * (1<<10);
if ((stroker->lastDir ^ QCosmeticStroker::VerticalMask) == dir) if ((stroker->lastDir ^ QCosmeticStroker::VerticalMask) == dir)
caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin; caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin;
@ -771,7 +771,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
int round = (xinc > 0) ? 32 : 0; int round = (xinc > 0) ? 32 : 0;
if (y != ys) { if (y != ys) {
x += ( ((((y << 6) + round - y1))) * xinc ) >> 6; x += ((y * (1<<6)) + round - y1) * xinc >> 6;
// calculate first and last pixel and perform dropout control // calculate first and last pixel and perform dropout control
QCosmeticStroker::Point first; QCosmeticStroker::Point first;
@ -810,7 +810,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
stroker->lastDir = dir; stroker->lastDir = dir;
stroker->lastAxisAligned = axisAligned; stroker->lastAxisAligned = axisAligned;
Dasher dasher(stroker, swapped, y << 6, ys << 6); Dasher dasher(stroker, swapped, y * (1<<6), ys * (1<<6));
do { do {
if (dasher.on()) if (dasher.on())
@ -836,7 +836,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
dir = QCosmeticStroker::RightToLeft; dir = QCosmeticStroker::RightToLeft;
} }
int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1); int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1);
int y = y1 << 10; int y = y1 * (1<<10);
if ((stroker->lastDir ^ QCosmeticStroker::HorizontalMask) == dir) if ((stroker->lastDir ^ QCosmeticStroker::HorizontalMask) == dir)
caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin; caps |= swapped ? QCosmeticStroker::CapEnd : QCosmeticStroker::CapBegin;
@ -848,7 +848,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
int round = (yinc > 0) ? 32 : 0; int round = (yinc > 0) ? 32 : 0;
if (x != xs) { if (x != xs) {
y += ( ((((x << 6) + round - x1))) * yinc ) >> 6; y += ((x * (1<<6)) + round - x1) * yinc >> 6;
// calculate first and last pixel to perform dropout control // calculate first and last pixel to perform dropout control
QCosmeticStroker::Point first; QCosmeticStroker::Point first;
@ -886,7 +886,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
stroker->lastDir = dir; stroker->lastDir = dir;
stroker->lastAxisAligned = axisAligned; stroker->lastAxisAligned = axisAligned;
Dasher dasher(stroker, swapped, x << 6, xs << 6); Dasher dasher(stroker, swapped, x * (1<<6), xs * (1<<6));
do { do {
if (dasher.on()) if (dasher.on())
@ -929,7 +929,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
caps = swapCaps(caps); caps = swapCaps(caps);
} }
int x = (x1 - 32) << 10; int x = (x1 - 32) * (1<<10);
x -= ( ((y1 & 63) - 32) * xinc ) >> 6; x -= ( ((y1 & 63) - 32) * xinc ) >> 6;
capAdjust(caps, y1, y2, x, xinc); capAdjust(caps, y1, y2, x, xinc);
@ -992,7 +992,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
caps = swapCaps(caps); caps = swapCaps(caps);
} }
int y = (y1 - 32) << 10; int y = (y1 - 32) * (1<<10);
y -= ( ((x1 & 63) - 32) * yinc ) >> 6; y -= ( ((x1 & 63) - 32) * yinc ) >> 6;
capAdjust(caps, x1, x2, y, yinc); capAdjust(caps, x1, x2, y, yinc);

View File

@ -137,7 +137,7 @@ extern bool qt_is_gui_used;
Q_GUI_EXPORT int qt_defaultDpiX() Q_GUI_EXPORT int qt_defaultDpiX()
{ {
if (qApp->testAttribute(Qt::AA_Use96Dpi)) if (QCoreApplication::instance()->testAttribute(Qt::AA_Use96Dpi))
return 96; return 96;
if (!qt_is_gui_used) if (!qt_is_gui_used)
@ -152,7 +152,7 @@ Q_GUI_EXPORT int qt_defaultDpiX()
Q_GUI_EXPORT int qt_defaultDpiY() Q_GUI_EXPORT int qt_defaultDpiY()
{ {
if (qApp->testAttribute(Qt::AA_Use96Dpi)) if (QCoreApplication::instance()->testAttribute(Qt::AA_Use96Dpi))
return 96; return 96;
if (!qt_is_gui_used) if (!qt_is_gui_used)

View File

@ -614,8 +614,7 @@ QByteArray QRawFont::fontTable(const char *tagName) const
if (!d->isValid()) if (!d->isValid())
return QByteArray(); return QByteArray();
const quint32 *tagId = reinterpret_cast<const quint32 *>(tagName); return d->fontEngine->getSfntTable(MAKE_TAG(tagName[0], tagName[1], tagName[2], tagName[3]));
return d->fontEngine->getSfntTable(qToBigEndian(*tagId));
} }
/*! /*!

View File

@ -128,7 +128,7 @@ static QByteArray makeCacheKey(QUrl &url, QNetworkProxy *proxy)
{ {
QString result; QString result;
QUrl copy = url; QUrl copy = url;
QString scheme = copy.scheme().toLower(); QString scheme = copy.scheme();
bool isEncrypted = scheme == QLatin1String("https"); bool isEncrypted = scheme == QLatin1String("https");
copy.setPort(copy.port(isEncrypted ? 443 : 80)); copy.setPort(copy.port(isEncrypted ? 443 : 80));
if (scheme == QLatin1String("preconnect-http")) { if (scheme == QLatin1String("preconnect-http")) {

View File

@ -1125,42 +1125,40 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera
Q_D(QNetworkAccessManager); Q_D(QNetworkAccessManager);
bool isLocalFile = req.url().isLocalFile(); bool isLocalFile = req.url().isLocalFile();
QString scheme = req.url().scheme().toLower(); QString scheme = req.url().scheme();
// fast path for GET on file:// URLs // fast path for GET on file:// URLs
// The QNetworkAccessFileBackend will right now only be used for PUT // The QNetworkAccessFileBackend will right now only be used for PUT
if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) if (op == QNetworkAccessManager::GetOperation
&& (isLocalFile || scheme == QLatin1String("qrc") || op == QNetworkAccessManager::HeadOperation) {
#if defined(Q_OS_ANDROID) if (isLocalFile
#ifdef Q_OS_ANDROID
|| scheme == QLatin1String("assets") || scheme == QLatin1String("assets")
#endif #endif
)) { || scheme == QLatin1String("qrc")) {
return new QNetworkReplyFileImpl(this, req, op); return new QNetworkReplyFileImpl(this, req, op);
} }
if ((op == QNetworkAccessManager::GetOperation || op == QNetworkAccessManager::HeadOperation) if (scheme == QLatin1String("data"))
&& scheme == QLatin1String("data")) { return new QNetworkReplyDataImpl(this, req, op);
return new QNetworkReplyDataImpl(this, req, op);
}
// A request with QNetworkRequest::AlwaysCache does not need any bearer management // A request with QNetworkRequest::AlwaysCache does not need any bearer management
QNetworkRequest::CacheLoadControl mode = QNetworkRequest::CacheLoadControl mode =
static_cast<QNetworkRequest::CacheLoadControl>( static_cast<QNetworkRequest::CacheLoadControl>(
req.attribute(QNetworkRequest::CacheLoadControlAttribute, req.attribute(QNetworkRequest::CacheLoadControlAttribute,
QNetworkRequest::PreferNetwork).toInt()); QNetworkRequest::PreferNetwork).toInt());
if (mode == QNetworkRequest::AlwaysCache if (mode == QNetworkRequest::AlwaysCache) {
&& (op == QNetworkAccessManager::GetOperation // FIXME Implement a QNetworkReplyCacheImpl instead, see QTBUG-15106
|| op == QNetworkAccessManager::HeadOperation)) { QNetworkReplyImpl *reply = new QNetworkReplyImpl(this);
// FIXME Implement a QNetworkReplyCacheImpl instead, see QTBUG-15106 QNetworkReplyImplPrivate *priv = reply->d_func();
QNetworkReplyImpl *reply = new QNetworkReplyImpl(this); priv->manager = this;
QNetworkReplyImplPrivate *priv = reply->d_func(); priv->backend = new QNetworkAccessCacheBackend();
priv->manager = this; priv->backend->manager = this->d_func();
priv->backend = new QNetworkAccessCacheBackend(); priv->backend->setParent(reply);
priv->backend->manager = this->d_func(); priv->backend->reply = priv;
priv->backend->setParent(reply); priv->setup(op, req, outgoingData);
priv->backend->reply = priv; return reply;
priv->setup(op, req, outgoingData); }
return reply;
} }
#ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_BEARERMANAGEMENT

View File

@ -224,7 +224,7 @@ QList<QNetworkCookie> QNetworkCookieJar::cookiesForUrl(const QUrl &url) const
Q_D(const QNetworkCookieJar); Q_D(const QNetworkCookieJar);
const QDateTime now = QDateTime::currentDateTimeUtc(); const QDateTime now = QDateTime::currentDateTimeUtc();
QList<QNetworkCookie> result; QList<QNetworkCookie> result;
bool isEncrypted = url.scheme().toLower() == QLatin1String("https"); bool isEncrypted = url.scheme() == QLatin1String("https");
// scan our cookies for something that matches // scan our cookies for something that matches
QList<QNetworkCookie>::ConstIterator it = d->allCookies.constBegin(), QList<QNetworkCookie>::ConstIterator it = d->allCookies.constBegin(),

View File

@ -634,7 +634,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
httpRequest.setUrl(url); httpRequest.setUrl(url);
httpRequest.setRedirectCount(newHttpRequest.maximumRedirectsAllowed()); httpRequest.setRedirectCount(newHttpRequest.maximumRedirectsAllowed());
QString scheme = url.scheme().toLower(); QString scheme = url.scheme();
bool ssl = (scheme == QLatin1String("https") bool ssl = (scheme == QLatin1String("https")
|| scheme == QLatin1String("preconnect-https")); || scheme == QLatin1String("preconnect-https"));
q->setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, ssl); q->setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, ssl);

View File

@ -806,10 +806,10 @@ static QByteArray headerValue(QNetworkRequest::KnownHeaders header, const QVaria
return QByteArray(); return QByteArray();
} }
static QNetworkRequest::KnownHeaders parseHeaderName(const QByteArray &headerName) static int parseHeaderName(const QByteArray &headerName)
{ {
if (headerName.isEmpty()) if (headerName.isEmpty())
return QNetworkRequest::KnownHeaders(-1); return -1;
switch (tolower(headerName.at(0))) { switch (tolower(headerName.at(0))) {
case 'c': case 'c':
@ -841,7 +841,7 @@ static QNetworkRequest::KnownHeaders parseHeaderName(const QByteArray &headerNam
break; break;
} }
return QNetworkRequest::KnownHeaders(-1); // nothing found return -1; // nothing found
} }
static QVariant parseHttpDate(const QByteArray &raw) static QVariant parseHttpDate(const QByteArray &raw)
@ -1012,8 +1012,10 @@ void QNetworkHeadersPrivate::setRawHeaderInternal(const QByteArray &key, const Q
void QNetworkHeadersPrivate::parseAndSetHeader(const QByteArray &key, const QByteArray &value) void QNetworkHeadersPrivate::parseAndSetHeader(const QByteArray &key, const QByteArray &value)
{ {
// is it a known header? // is it a known header?
QNetworkRequest::KnownHeaders parsedKey = parseHeaderName(key); const int parsedKeyAsInt = parseHeaderName(key);
if (parsedKey != QNetworkRequest::KnownHeaders(-1)) { if (parsedKeyAsInt != -1) {
const QNetworkRequest::KnownHeaders parsedKey
= static_cast<QNetworkRequest::KnownHeaders>(parsedKeyAsInt);
if (value.isNull()) { if (value.isNull()) {
cookedHeaders.remove(parsedKey); cookedHeaders.remove(parsedKey);
} else if (parsedKey == QNetworkRequest::ContentLengthHeader } else if (parsedKey == QNetworkRequest::ContentLengthHeader

View File

@ -198,6 +198,9 @@ bool QLocalServerPrivate::addListener()
memset(&listener.overlapped, 0, sizeof(listener.overlapped)); memset(&listener.overlapped, 0, sizeof(listener.overlapped));
listener.overlapped.hEvent = eventHandle; listener.overlapped.hEvent = eventHandle;
// Beware! ConnectNamedPipe will reset the eventHandle to non-signaled.
// Callers of addListener must check all listeners for connections.
if (!ConnectNamedPipe(listener.handle, &listener.overlapped)) { if (!ConnectNamedPipe(listener.handle, &listener.overlapped)) {
switch (GetLastError()) { switch (GetLastError()) {
case ERROR_IO_PENDING: case ERROR_IO_PENDING:
@ -205,7 +208,6 @@ bool QLocalServerPrivate::addListener()
break; break;
case ERROR_PIPE_CONNECTED: case ERROR_PIPE_CONNECTED:
listener.connected = true; listener.connected = true;
SetEvent(eventHandle);
break; break;
default: default:
CloseHandle(listener.handle); CloseHandle(listener.handle);
@ -257,6 +259,8 @@ bool QLocalServerPrivate::listen(const QString &name)
for (int i = 0; i < SYSTEM_MAX_PENDING_SOCKETS; ++i) for (int i = 0; i < SYSTEM_MAX_PENDING_SOCKETS; ++i)
if (!addListener()) if (!addListener())
return false; return false;
_q_onNewConnection();
return true; return true;
} }
@ -270,37 +274,43 @@ void QLocalServerPrivate::_q_onNewConnection()
{ {
Q_Q(QLocalServer); Q_Q(QLocalServer);
DWORD dummy; DWORD dummy;
bool tryAgain;
do {
tryAgain = false;
// Reset first, otherwise we could reset an event which was asserted // Reset first, otherwise we could reset an event which was asserted
// immediately after we checked the conn status. // immediately after we checked the conn status.
ResetEvent(eventHandle); ResetEvent(eventHandle);
// Testing shows that there is indeed absolutely no guarantee which listener gets // Testing shows that there is indeed absolutely no guarantee which listener gets
// a client connection first, so there is no way around polling all of them. // a client connection first, so there is no way around polling all of them.
for (int i = 0; i < listeners.size(); ) { for (int i = 0; i < listeners.size(); ) {
HANDLE handle = listeners[i].handle; HANDLE handle = listeners[i].handle;
if (listeners[i].connected if (listeners[i].connected
|| GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE)) || GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE))
{ {
listeners.removeAt(i); listeners.removeAt(i);
addListener(); addListener();
if (pendingConnections.size() > maxPendingConnections) if (pendingConnections.size() > maxPendingConnections)
connectionEventNotifier->setEnabled(false); connectionEventNotifier->setEnabled(false);
else
tryAgain = true;
// Make this the last thing so connected slots can wreak the least havoc // Make this the last thing so connected slots can wreak the least havoc
q->incomingConnection((quintptr)handle); q->incomingConnection((quintptr)handle);
} else { } else {
if (GetLastError() != ERROR_IO_INCOMPLETE) { if (GetLastError() != ERROR_IO_INCOMPLETE) {
q->close(); q->close();
setError(QLatin1String("QLocalServerPrivate::_q_onNewConnection")); setError(QLatin1String("QLocalServerPrivate::_q_onNewConnection"));
return; return;
}
++i;
} }
++i;
} }
} } while (tryAgain);
} }
void QLocalServerPrivate::closeServer() void QLocalServerPrivate::closeServer()

View File

@ -220,7 +220,6 @@ qint64 QLocalSocket::writeData(const char *data, qint64 maxSize)
d->pipeWriter = new QWindowsPipeWriter(d->handle, this); d->pipeWriter = new QWindowsPipeWriter(d->handle, this);
connect(d->pipeWriter, SIGNAL(canWrite()), this, SLOT(_q_canWrite())); connect(d->pipeWriter, SIGNAL(canWrite()), this, SLOT(_q_canWrite()));
connect(d->pipeWriter, SIGNAL(bytesWritten(qint64)), this, SIGNAL(bytesWritten(qint64))); connect(d->pipeWriter, SIGNAL(bytesWritten(qint64)), this, SIGNAL(bytesWritten(qint64)));
d->pipeWriter->start();
} }
return d->pipeWriter->write(data, maxSize); return d->pipeWriter->write(data, maxSize);
} }

View File

@ -399,6 +399,10 @@ bool QSslSocketBackendPrivate::initSslContext()
if (!ace.isEmpty() if (!ace.isEmpty()
&& !QHostAddress().setAddress(tlsHostName) && !QHostAddress().setAddress(tlsHostName)
&& !(configuration.sslOptions & QSsl::SslOptionDisableServerNameIndication)) { && !(configuration.sslOptions & QSsl::SslOptionDisableServerNameIndication)) {
// We don't send the trailing dot from the host header if present see
// https://tools.ietf.org/html/rfc6066#section-3
if (ace.endsWith('.'))
ace.chop(1);
if (!q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, ace.data())) if (!q_SSL_ctrl(ssl, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, ace.data()))
qCWarning(lcSsl, "could not set SSL_CTRL_SET_TLSEXT_HOSTNAME, Server Name Indication disabled"); qCWarning(lcSsl, "could not set SSL_CTRL_SET_TLSEXT_HOSTNAME, Server Name Indication disabled");
} }
@ -632,10 +636,12 @@ void QSslSocketPrivate::resetDefaultCiphers()
// Unconditionally exclude ADH and AECDH ciphers since they offer no MITM protection // Unconditionally exclude ADH and AECDH ciphers since they offer no MITM protection
if (!ciph.name().toLower().startsWith(QLatin1String("adh")) && if (!ciph.name().toLower().startsWith(QLatin1String("adh")) &&
!ciph.name().toLower().startsWith(QLatin1String("exp-adh")) && !ciph.name().toLower().startsWith(QLatin1String("exp-adh")) &&
!ciph.name().toLower().startsWith(QLatin1String("aecdh"))) !ciph.name().toLower().startsWith(QLatin1String("aecdh"))) {
ciphers << ciph; ciphers << ciph;
if (ciph.usedBits() >= 128)
defaultCiphers << ciph; if (ciph.usedBits() >= 128)
defaultCiphers << ciph;
}
} }
} }
} }

View File

@ -643,7 +643,7 @@ QList<QByteArray> QMacPasteboardMimeFileUri::convertFromMime(const QString &mime
QUrl url = urls.at(i).toUrl(); QUrl url = urls.at(i).toUrl();
if (url.scheme().isEmpty()) if (url.scheme().isEmpty())
url.setScheme(QLatin1String("file")); url.setScheme(QLatin1String("file"));
if (url.scheme().toLower() == QLatin1String("file")) { if (url.scheme() == QLatin1String("file")) {
if (url.host().isEmpty()) if (url.host().isEmpty())
url.setHost(QLatin1String("localhost")); url.setHost(QLatin1String("localhost"));
url.setPath(url.path().normalized(QString::NormalizationForm_D)); url.setPath(url.path().normalized(QString::NormalizationForm_D));
@ -722,7 +722,7 @@ QList<QByteArray> QMacPasteboardMimeUrl::convertFromMime(const QString &mime, QV
QUrl url = urls.at(i).toUrl(); QUrl url = urls.at(i).toUrl();
if (url.scheme().isEmpty()) if (url.scheme().isEmpty())
url.setScheme(QLatin1String("file")); url.setScheme(QLatin1String("file"));
if (url.scheme().toLower() == QLatin1String("file")) { if (url.scheme() == QLatin1String("file")) {
if (url.host().isEmpty()) if (url.host().isEmpty())
url.setHost(QLatin1String("localhost")); url.setHost(QLatin1String("localhost"));
url.setPath(url.path().normalized(QString::NormalizationForm_D)); url.setPath(url.path().normalized(QString::NormalizationForm_D));

View File

@ -57,7 +57,11 @@ public:
QPaintDevice *paintDevice() Q_DECL_OVERRIDE; QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
void flush(QWindow *widget, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE; void flush(QWindow *widget, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
#ifndef QT_NO_OPENGL
QImage toImage() const Q_DECL_OVERRIDE; QImage toImage() const Q_DECL_OVERRIDE;
#else
QImage toImage() const; // No QPlatformBackingStore::toImage() for NO_OPENGL builds.
#endif
void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE; void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE;
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE; bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
void beginPaint(const QRegion &region) Q_DECL_OVERRIDE; void beginPaint(const QRegion &region) Q_DECL_OVERRIDE;

View File

@ -428,14 +428,18 @@ void QCocoaIntegration::updateScreens()
} }
siblings << screen; siblings << screen;
} }
// Set virtual siblings list. All screens in mScreens are siblings, because we ignored the
// mirrors. Note that some of the screens we update the siblings list for here may be deleted
// below, but update anyway to keep the to-be-deleted screens out of the siblings list.
foreach (QCocoaScreen* screen, mScreens)
screen->setVirtualSiblings(siblings);
// Now the leftovers in remainingScreens are no longer current, so we can delete them. // Now the leftovers in remainingScreens are no longer current, so we can delete them.
foreach (QCocoaScreen* screen, remainingScreens) { foreach (QCocoaScreen* screen, remainingScreens) {
mScreens.removeOne(screen); mScreens.removeOne(screen);
destroyScreen(screen); destroyScreen(screen);
} }
// All screens in mScreens are siblings, because we ignored the mirrors.
foreach (QCocoaScreen* screen, mScreens)
screen->setVirtualSiblings(siblings);
} }
QCocoaScreen *QCocoaIntegration::screenAtIndex(int index) QCocoaScreen *QCocoaIntegration::screenAtIndex(int index)

View File

@ -81,8 +81,6 @@ public:
inline NSMenu *nsMenu() const inline NSMenu *nsMenu() const
{ return m_nativeMenu; } { return m_nativeMenu; }
inline NSMenuItem *nsMenuItem() const
{ return m_nativeItem; }
inline bool isVisible() const { return m_visible; } inline bool isVisible() const { return m_visible; }
@ -91,11 +89,9 @@ public:
QList<QCocoaMenuItem *> items() const; QList<QCocoaMenuItem *> items() const;
QList<QCocoaMenuItem *> merged() const; QList<QCocoaMenuItem *> merged() const;
void setMenuBar(QCocoaMenuBar *menuBar);
QCocoaMenuBar *menuBar() const;
void setContainingMenuItem(QCocoaMenuItem *menuItem); void setAttachedItem(NSMenuItem *item);
QCocoaMenuItem *containingMenuItem() const; NSMenuItem *attachedItem() const;
private: private:
QCocoaMenuItem *itemOrNull(int index) const; QCocoaMenuItem *itemOrNull(int index) const;
@ -103,13 +99,10 @@ private:
QList<QCocoaMenuItem *> m_menuItems; QList<QCocoaMenuItem *> m_menuItems;
NSMenu *m_nativeMenu; NSMenu *m_nativeMenu;
NSMenuItem *m_nativeItem; NSMenuItem *m_attachedItem;
NSObject *m_delegate;
bool m_enabled; bool m_enabled;
bool m_visible; bool m_visible;
quintptr m_tag; quintptr m_tag;
QCocoaMenuBar *m_menuBar;
QCocoaMenuItem *m_containingMenuItem;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -102,6 +102,28 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
return self; return self;
} }
- (NSInteger)numberOfItemsInMenu:(NSMenu *)menu
{
Q_ASSERT(m_menu->nsMenu() == menu);
return m_menu->items().count();
}
- (BOOL)menu:(NSMenu *)menu updateItem:(NSMenuItem *)item atIndex:(NSInteger)index shouldCancel:(BOOL)shouldCancel
{
Q_UNUSED(index);
Q_ASSERT(m_menu->nsMenu() == menu);
if (shouldCancel) {
// TODO detach all submenus
return NO;
}
QCocoaMenuItem *menuItem = reinterpret_cast<QCocoaMenuItem *>(item.tag);
if (m_menu->items().contains(menuItem)) {
if (QCocoaMenu *itemSubmenu = menuItem->menu())
itemSubmenu->setAttachedItem(item);
}
return YES;
}
- (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item - (void)menu:(NSMenu*)menu willHighlightItem:(NSMenuItem*)item
{ {
@ -234,20 +256,16 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
QCocoaMenu::QCocoaMenu() : QCocoaMenu::QCocoaMenu() :
m_attachedItem(0),
m_enabled(true), m_enabled(true),
m_visible(true), m_visible(true),
m_tag(0), m_tag(0)
m_menuBar(0),
m_containingMenuItem(0)
{ {
QMacAutoReleasePool pool; QMacAutoReleasePool pool;
m_delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this];
m_nativeItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
m_nativeMenu = [[NSMenu alloc] initWithTitle:@"Untitled"]; m_nativeMenu = [[NSMenu alloc] initWithTitle:@"Untitled"];
[m_nativeMenu setAutoenablesItems:YES]; [m_nativeMenu setAutoenablesItems:YES];
m_nativeMenu.delegate = (QCocoaMenuDelegate *) m_delegate; m_nativeMenu.delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this];
[m_nativeItem setSubmenu:m_nativeMenu];
} }
QCocoaMenu::~QCocoaMenu() QCocoaMenu::~QCocoaMenu()
@ -257,14 +275,11 @@ QCocoaMenu::~QCocoaMenu()
SET_COCOA_MENU_ANCESTOR(item, 0); SET_COCOA_MENU_ANCESTOR(item, 0);
} }
if (m_containingMenuItem)
m_containingMenuItem->clearMenu(this);
QMacAutoReleasePool pool; QMacAutoReleasePool pool;
[m_nativeItem setSubmenu:nil]; NSObject *delegate = m_nativeMenu.delegate;
m_nativeMenu.delegate = nil;
[delegate release];
[m_nativeMenu release]; [m_nativeMenu release];
[m_delegate release];
[m_nativeItem release];
} }
void QCocoaMenu::setText(const QString &text) void QCocoaMenu::setText(const QString &text)
@ -272,7 +287,6 @@ void QCocoaMenu::setText(const QString &text)
QMacAutoReleasePool pool; QMacAutoReleasePool pool;
QString stripped = qt_mac_removeAmpersandEscapes(text); QString stripped = qt_mac_removeAmpersandEscapes(text);
[m_nativeMenu setTitle:QCFString::toNSString(stripped)]; [m_nativeMenu setTitle:QCFString::toNSString(stripped)];
[m_nativeItem setTitle:QCFString::toNSString(stripped)];
} }
void QCocoaMenu::setMinimumWidth(int width) void QCocoaMenu::setMinimumWidth(int width)
@ -313,17 +327,13 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *
void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem) void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
{ {
[item->nsItem() setTarget:m_delegate]; item->nsItem().target = m_nativeMenu.delegate;
if (!item->menu()) if (!item->menu())
[item->nsItem() setAction:@selector(itemFired:)]; [item->nsItem() setAction:@selector(itemFired:)];
if (item->isMerged()) if (item->isMerged())
return; return;
if ([item->nsItem() menu]) {
qWarning("Menu item is already in a menu, remove it from the other menu first before inserting");
return;
}
// if the item we're inserting before is merged, skip along until // if the item we're inserting before is merged, skip along until
// we find a non-merged real item to insert ahead of. // we find a non-merged real item to insert ahead of.
while (beforeItem && beforeItem->isMerged()) { while (beforeItem && beforeItem->isMerged()) {
@ -451,12 +461,11 @@ void QCocoaMenu::setEnabled(bool enabled)
bool QCocoaMenu::isEnabled() const bool QCocoaMenu::isEnabled() const
{ {
return [m_nativeItem isEnabled]; return m_attachedItem ? [m_attachedItem isEnabled] : m_enabled;
} }
void QCocoaMenu::setVisible(bool visible) void QCocoaMenu::setVisible(bool visible)
{ {
[m_nativeItem setSubmenu:(visible ? m_nativeMenu : nil)];
m_visible = visible; m_visible = visible;
} }
@ -593,8 +602,6 @@ void QCocoaMenu::syncModalState(bool modal)
if (!m_enabled) if (!m_enabled)
modal = true; modal = true;
[m_nativeItem setEnabled:!modal];
foreach (QCocoaMenuItem *item, m_menuItems) { foreach (QCocoaMenuItem *item, m_menuItems) {
if (item->menu()) { // recurse into submenus if (item->menu()) { // recurse into submenus
item->menu()->syncModalState(modal); item->menu()->syncModalState(modal);
@ -605,25 +612,24 @@ void QCocoaMenu::syncModalState(bool modal)
} }
} }
void QCocoaMenu::setMenuBar(QCocoaMenuBar *menuBar) void QCocoaMenu::setAttachedItem(NSMenuItem *item)
{ {
m_menuBar = menuBar; if (item == m_attachedItem)
SET_COCOA_MENU_ANCESTOR(this, menuBar); return;
if (m_attachedItem)
m_attachedItem.submenu = nil;
m_attachedItem = item;
if (m_attachedItem)
m_attachedItem.submenu = m_nativeMenu;
} }
QCocoaMenuBar *QCocoaMenu::menuBar() const NSMenuItem *QCocoaMenu::attachedItem() const
{ {
return m_menuBar; return m_attachedItem;
}
void QCocoaMenu::setContainingMenuItem(QCocoaMenuItem *menuItem)
{
m_containingMenuItem = menuItem;
}
QCocoaMenuItem *QCocoaMenu::containingMenuItem() const
{
return m_containingMenuItem;
} }
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -77,10 +77,10 @@ private:
static QCocoaMenuBar *findGlobalMenubar(); static QCocoaMenuBar *findGlobalMenubar();
bool shouldDisable(QCocoaWindow *active) const; bool shouldDisable(QCocoaWindow *active) const;
void insertNativeMenu(QCocoaMenu *menu, QCocoaMenu *beforeMenu);
void removeNativeMenu(QCocoaMenu *menu);
QList<QCocoaMenu*> m_menus; NSMenuItem *nativeItemForMenu(QCocoaMenu *menu) const;
QList<QPointer<QCocoaMenu> > m_menus;
NSMenu *m_nativeMenu; NSMenu *m_nativeMenu;
QCocoaWindow *m_window; QCocoaWindow *m_window;
}; };

View File

@ -57,7 +57,6 @@ static inline QCocoaMenuLoader *getMenuLoader()
return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)]; return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
} }
QCocoaMenuBar::QCocoaMenuBar() : QCocoaMenuBar::QCocoaMenuBar() :
m_window(0) m_window(0)
{ {
@ -74,11 +73,20 @@ QCocoaMenuBar::~QCocoaMenuBar()
#ifdef QT_COCOA_ENABLE_MENU_DEBUG #ifdef QT_COCOA_ENABLE_MENU_DEBUG
qDebug() << "~QCocoaMenuBar" << this; qDebug() << "~QCocoaMenuBar" << this;
#endif #endif
foreach (QCocoaMenu *menu, m_menus) {
if (!menu)
continue;
NSMenuItem *item = nativeItemForMenu(menu);
if (menu->attachedItem() == item)
menu->setAttachedItem(nil);
}
[m_nativeMenu release]; [m_nativeMenu release];
static_menubars.removeOne(this); static_menubars.removeOne(this);
if (m_window && m_window->menubar() == this) { if (m_window && m_window->menubar() == this) {
m_window->setMenubar(0); m_window->setMenubar(0);
// Delete the children first so they do not cause // Delete the children first so they do not cause
// the native menu items to be hidden after // the native menu items to be hidden after
// the menu bar was updated // the menu bar was updated
@ -87,24 +95,6 @@ QCocoaMenuBar::~QCocoaMenuBar()
} }
} }
void QCocoaMenuBar::insertNativeMenu(QCocoaMenu *menu, QCocoaMenu *beforeMenu)
{
QMacAutoReleasePool pool;
if (beforeMenu) {
NSUInteger nativeIndex = [m_nativeMenu indexOfItem:beforeMenu->nsMenuItem()];
[m_nativeMenu insertItem: menu->nsMenuItem() atIndex: nativeIndex];
} else {
[m_nativeMenu addItem: menu->nsMenuItem()];
}
menu->setMenuBar(this);
syncMenu(static_cast<QPlatformMenu *>(menu));
if (menu->isVisible()) {
[m_nativeMenu setSubmenu: menu->nsMenu() forItem: menu->nsMenuItem()];
}
}
void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *before) void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *before)
{ {
QCocoaMenu *menu = static_cast<QCocoaMenu *>(platformMenu); QCocoaMenu *menu = static_cast<QCocoaMenu *>(platformMenu);
@ -113,33 +103,42 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor
qDebug() << "QCocoaMenuBar" << this << "insertMenu" << menu << "before" << before; qDebug() << "QCocoaMenuBar" << this << "insertMenu" << menu << "before" << before;
#endif #endif
if (m_menus.contains(menu)) { if (m_menus.contains(QPointer<QCocoaMenu>(menu))) {
qWarning("This menu already belongs to the menubar, remove it first"); qWarning("This menu already belongs to the menubar, remove it first");
return; return;
} }
if (beforeMenu && !m_menus.contains(beforeMenu)) { if (beforeMenu && !m_menus.contains(QPointer<QCocoaMenu>(beforeMenu))) {
qWarning("The before menu does not belong to the menubar"); qWarning("The before menu does not belong to the menubar");
return; return;
} }
m_menus.insert(beforeMenu ? m_menus.indexOf(beforeMenu) : m_menus.size(), menu); int insertionIndex = beforeMenu ? m_menus.indexOf(beforeMenu) : m_menus.size();
if (!menu->menuBar()) m_menus.insert(insertionIndex, menu);
insertNativeMenu(menu, beforeMenu);
{
QMacAutoReleasePool pool;
NSMenuItem *item = [[[NSMenuItem alloc] init] autorelease];
item.tag = reinterpret_cast<NSInteger>(menu);
if (beforeMenu) {
// QMenuBar::toNSMenu() exposes the native menubar and
// the user could have inserted its own items in there.
// Same remark applies to removeMenu().
NSMenuItem *beforeItem = nativeItemForMenu(beforeMenu);
NSInteger nativeIndex = [m_nativeMenu indexOfItem:beforeItem];
[m_nativeMenu insertItem:item atIndex:nativeIndex];
} else {
[m_nativeMenu addItem:item];
}
}
syncMenu(menu);
if (m_window && m_window->window()->isActive()) if (m_window && m_window->window()->isActive())
updateMenuBarImmediately(); updateMenuBarImmediately();
} }
void QCocoaMenuBar::removeNativeMenu(QCocoaMenu *menu)
{
QMacAutoReleasePool pool;
if (menu->menuBar() == this)
menu->setMenuBar(0);
NSUInteger realIndex = [m_nativeMenu indexOfItem:menu->nsMenuItem()];
[m_nativeMenu removeItemAtIndex: realIndex];
}
void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu) void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu)
{ {
QCocoaMenu *menu = static_cast<QCocoaMenu *>(platformMenu); QCocoaMenu *menu = static_cast<QCocoaMenu *>(platformMenu);
@ -147,8 +146,17 @@ void QCocoaMenuBar::removeMenu(QPlatformMenu *platformMenu)
qWarning("Trying to remove a menu that does not belong to the menubar"); qWarning("Trying to remove a menu that does not belong to the menubar");
return; return;
} }
NSMenuItem *item = nativeItemForMenu(menu);
if (menu->attachedItem() == item)
menu->setAttachedItem(nil);
m_menus.removeOne(menu); m_menus.removeOne(menu);
removeNativeMenu(menu);
QMacAutoReleasePool pool;
// See remark in insertMenu().
NSInteger nativeIndex = [m_nativeMenu indexOfItem:item];
[m_nativeMenu removeItemAtIndex:nativeIndex];
} }
void QCocoaMenuBar::syncMenu(QPlatformMenu *menu) void QCocoaMenuBar::syncMenu(QPlatformMenu *menu)
@ -170,7 +178,16 @@ void QCocoaMenuBar::syncMenu(QPlatformMenu *menu)
break; break;
} }
} }
[cocoaMenu->nsMenuItem() setHidden:shouldHide];
nativeItemForMenu(cocoaMenu).hidden = shouldHide;
}
NSMenuItem *QCocoaMenuBar::nativeItemForMenu(QCocoaMenu *menu) const
{
if (!menu)
return nil;
return [m_nativeMenu itemWithTag:reinterpret_cast<NSInteger>(menu)];
} }
void QCocoaMenuBar::handleReparent(QWindow *newParentWindow) void QCocoaMenuBar::handleReparent(QWindow *newParentWindow)
@ -297,24 +314,16 @@ void QCocoaMenuBar::updateMenuBarImmediately()
qDebug() << "QCocoaMenuBar" << "updateMenuBarImmediately" << cw; qDebug() << "QCocoaMenuBar" << "updateMenuBarImmediately" << cw;
#endif #endif
bool disableForModal = mb->shouldDisable(cw); bool disableForModal = mb->shouldDisable(cw);
// force a sync?
foreach (QCocoaMenu *m, mb->m_menus) {
mb->syncMenu(m);
m->syncModalState(disableForModal);
}
// reparent shared menu items if necessary. foreach (QCocoaMenu *menu, mb->m_menus) {
// We browse the list in reverse order to be sure that the next items are redrawn before the current ones, if (!menu)
// in this way we are sure that "beforeMenu" (see below) is part of the native menu before "m" is redraw continue;
for (int i = mb->m_menus.size() - 1; i >= 0; i--) { NSMenuItem *item = mb->nativeItemForMenu(menu);
QCocoaMenu *m = mb->m_menus.at(i); menu->setAttachedItem(item);
QCocoaMenuBar *menuBar = m->menuBar(); SET_COCOA_MENU_ANCESTOR(menu, mb);
if (menuBar != mb) { // force a sync?
QCocoaMenu *beforeMenu = i < (mb->m_menus.size() - 1) ? mb->m_menus.at(i + 1) : 0; mb->syncMenu(menu);
if (menuBar) menu->syncModalState(disableForModal);
menuBar->removeNativeMenu(m);
mb->insertNativeMenu(m, beforeMenu);
}
} }
QCocoaMenuLoader *loader = getMenuLoader(); QCocoaMenuLoader *loader = getMenuLoader();

View File

@ -93,7 +93,6 @@ public:
inline bool isSeparator() const { return m_isSeparator; } inline bool isSeparator() const { return m_isSeparator; }
QCocoaMenu *menu() const { return m_menu; } QCocoaMenu *menu() const { return m_menu; }
void clearMenu(QCocoaMenu *menu);
MenuRole effectiveRole() const; MenuRole effectiveRole() const;
private: private:
@ -105,7 +104,7 @@ private:
QString m_text; QString m_text;
bool m_textSynced; bool m_textSynced;
QIcon m_icon; QIcon m_icon;
QCocoaMenu *m_menu; QPointer<QCocoaMenu> m_menu;
bool m_isVisible; bool m_isVisible;
bool m_enabled; bool m_enabled;
bool m_isSeparator; bool m_isSeparator;

View File

@ -142,15 +142,12 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
if (m_menu) { if (m_menu) {
if (COCOA_MENU_ANCESTOR(m_menu) == this) if (COCOA_MENU_ANCESTOR(m_menu) == this)
SET_COCOA_MENU_ANCESTOR(m_menu, 0); SET_COCOA_MENU_ANCESTOR(m_menu, 0);
if (m_menu->containingMenuItem() == this)
m_menu->setContainingMenuItem(0);
} }
QMacAutoReleasePool pool; QMacAutoReleasePool pool;
m_menu = static_cast<QCocoaMenu *>(menu); m_menu = static_cast<QCocoaMenu *>(menu);
if (m_menu) { if (m_menu) {
SET_COCOA_MENU_ANCESTOR(m_menu, this); SET_COCOA_MENU_ANCESTOR(m_menu, this);
m_menu->setContainingMenuItem(this);
} else { } else {
// we previously had a menu, but no longer // we previously had a menu, but no longer
// clear out our item so the nexy sync() call builds a new one // clear out our item so the nexy sync() call builds a new one
@ -159,12 +156,6 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
} }
} }
void QCocoaMenuItem::clearMenu(QCocoaMenu *menu)
{
if (menu == m_menu)
m_menu = 0;
}
void QCocoaMenuItem::setVisible(bool isVisible) void QCocoaMenuItem::setVisible(bool isVisible)
{ {
m_isVisible = isVisible; m_isVisible = isVisible;
@ -226,14 +217,6 @@ NSMenuItem *QCocoaMenuItem::sync()
m_native = nil; m_native = nil;
} }
if (m_menu) {
if (m_native != m_menu->nsMenuItem()) {
[m_native release];
m_native = [m_menu->nsMenuItem() retain];
[m_native setTag:reinterpret_cast<NSInteger>(this)];
}
}
if ((m_role != NoRole && !m_textSynced) || m_merged) { if ((m_role != NoRole && !m_textSynced) || m_merged) {
NSMenuItem *mergeItem = nil; NSMenuItem *mergeItem = nil;
QCocoaMenuLoader *loader = getMenuLoader(); QCocoaMenuLoader *loader = getMenuLoader();

View File

@ -414,6 +414,7 @@ QCocoaWindow::~QCocoaWindow()
#endif #endif
QMacAutoReleasePool pool; QMacAutoReleasePool pool;
[m_nsWindow makeFirstResponder:nil];
[m_nsWindow setContentView:nil]; [m_nsWindow setContentView:nil];
[m_nsWindow.helper detachFromPlatformWindow]; [m_nsWindow.helper detachFromPlatformWindow];
if (m_isNSWindowChild) { if (m_isNSWindowChild) {
@ -1004,7 +1005,15 @@ void QCocoaWindow::raise()
[parentNSWindow removeChildWindow:m_nsWindow]; [parentNSWindow removeChildWindow:m_nsWindow];
[parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove]; [parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
} else { } else {
[m_nsWindow orderFront: m_nsWindow]; {
// Clean up autoreleased temp objects from orderFront immediately.
// Failure to do so has been observed to cause leaks also beyond any outer
// autorelease pool (for example around a complete QWindow
// construct-show-raise-hide-delete cyle), counter to expected autoreleasepool
// behavior.
QMacAutoReleasePool pool;
[m_nsWindow orderFront: m_nsWindow];
}
static bool raiseProcess = qt_mac_resolveOption(true, "QT_MAC_SET_RAISE_PROCESS"); static bool raiseProcess = qt_mac_resolveOption(true, "QT_MAC_SET_RAISE_PROCESS");
if (raiseProcess) { if (raiseProcess) {
ProcessSerialNumber psn; ProcessSerialNumber psn;

View File

@ -1253,7 +1253,12 @@ QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const
{ {
QList<int> result; QList<int> result;
const KeyboardLayoutItem &kbItem = keyLayout[e->nativeVirtualKey()];
const quint32 nativeVirtualKey = e->nativeVirtualKey();
if (nativeVirtualKey > 255)
return result;
const KeyboardLayoutItem &kbItem = keyLayout[nativeVirtualKey];
if (!kbItem.exists) if (!kbItem.exists)
return result; return result;

View File

@ -39,8 +39,10 @@
#include "qwinrtbackingstore.h" #include "qwinrtbackingstore.h"
#include "qwinrtinputcontext.h" #include "qwinrtinputcontext.h"
#include "qwinrtcursor.h" #include "qwinrtcursor.h"
#include "qwinrtwindow.h"
#include <private/qeventdispatcher_winrt_p.h> #include <private/qeventdispatcher_winrt_p.h>
#include <QtCore/QLoggingCategory>
#include <QtGui/QSurfaceFormat> #include <QtGui/QSurfaceFormat>
#include <QtGui/QGuiApplication> #include <QtGui/QGuiApplication>
#include <qpa/qwindowsysteminterface.h> #include <qpa/qwindowsysteminterface.h>
@ -469,6 +471,7 @@ QWinRTScreen::QWinRTScreen()
: d_ptr(new QWinRTScreenPrivate) : d_ptr(new QWinRTScreenPrivate)
{ {
Q_D(QWinRTScreen); Q_D(QWinRTScreen);
qCDebug(lcQpaWindows) << __FUNCTION__;
d->orientation = Qt::PrimaryOrientation; d->orientation = Qt::PrimaryOrientation;
d->touchDevice = Q_NULLPTR; d->touchDevice = Q_NULLPTR;
@ -553,6 +556,7 @@ QWinRTScreen::QWinRTScreen()
QWinRTScreen::~QWinRTScreen() QWinRTScreen::~QWinRTScreen()
{ {
Q_D(QWinRTScreen); Q_D(QWinRTScreen);
qCDebug(lcQpaWindows) << __FUNCTION__ << this;
// Unregister callbacks // Unregister callbacks
HRESULT hr; HRESULT hr;
@ -631,6 +635,12 @@ QDpi QWinRTScreen::logicalDpi() const
return QDpi(d->logicalDpi, d->logicalDpi); return QDpi(d->logicalDpi, d->logicalDpi);
} }
qreal QWinRTScreen::pixelDensity() const
{
Q_D(const QWinRTScreen);
return qRound(d->logicalDpi / 96);
}
qreal QWinRTScreen::scaleFactor() const qreal QWinRTScreen::scaleFactor() const
{ {
Q_D(const QWinRTScreen); Q_D(const QWinRTScreen);
@ -697,6 +707,8 @@ Xaml::IDependencyObject *QWinRTScreen::canvas() const
void QWinRTScreen::setStatusBarVisibility(bool visible, QWindow *window) void QWinRTScreen::setStatusBarVisibility(bool visible, QWindow *window)
{ {
Q_D(QWinRTScreen); Q_D(QWinRTScreen);
qCDebug(lcQpaWindows) << __FUNCTION__ << window << visible;
const Qt::WindowFlags windowType = window->flags() & Qt::WindowType_Mask; const Qt::WindowFlags windowType = window->flags() & Qt::WindowType_Mask;
if (!window || (windowType != Qt::Window && windowType != Qt::Dialog)) if (!window || (windowType != Qt::Window && windowType != Qt::Dialog))
return; return;
@ -768,6 +780,7 @@ QWindow *QWinRTScreen::topWindow() const
void QWinRTScreen::addWindow(QWindow *window) void QWinRTScreen::addWindow(QWindow *window)
{ {
Q_D(QWinRTScreen); Q_D(QWinRTScreen);
qCDebug(lcQpaWindows) << __FUNCTION__ << window;
if (window == topWindow()) if (window == topWindow())
return; return;
@ -785,6 +798,7 @@ void QWinRTScreen::addWindow(QWindow *window)
void QWinRTScreen::removeWindow(QWindow *window) void QWinRTScreen::removeWindow(QWindow *window)
{ {
Q_D(QWinRTScreen); Q_D(QWinRTScreen);
qCDebug(lcQpaWindows) << __FUNCTION__ << window;
#ifdef Q_OS_WINPHONE #ifdef Q_OS_WINPHONE
if (window->visibility() == QWindow::Minimized) if (window->visibility() == QWindow::Minimized)
@ -1131,6 +1145,7 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *
hr = d->coreWindow->get_Bounds(&size); hr = d->coreWindow->get_Bounds(&size);
RETURN_OK_IF_FAILED("Failed to get window bounds"); RETURN_OK_IF_FAILED("Failed to get window bounds");
d->logicalSize = QSizeF(size.Width, size.Height); d->logicalSize = QSizeF(size.Width, size.Height);
qCDebug(lcQpaWindows) << __FUNCTION__ << d->logicalSize;
QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry()); QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), availableGeometry());
QPlatformScreen::resizeMaximizedWindows(); QPlatformScreen::resizeMaximizedWindows();
handleExpose(); handleExpose();
@ -1140,6 +1155,7 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *
HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args) HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args)
{ {
Q_D(QWinRTScreen); Q_D(QWinRTScreen);
qCDebug(lcQpaWindows) << __FUNCTION__;
CoreWindowActivationState activationState; CoreWindowActivationState activationState;
args->get_WindowActivationState(&activationState); args->get_WindowActivationState(&activationState);
@ -1159,6 +1175,8 @@ HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args
HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *) HRESULT QWinRTScreen::onClosed(ICoreWindow *, ICoreWindowEventArgs *)
{ {
qCDebug(lcQpaWindows) << __FUNCTION__;
foreach (QWindow *w, QGuiApplication::topLevelWindows()) foreach (QWindow *w, QGuiApplication::topLevelWindows())
QWindowSystemInterface::handleCloseEvent(w); QWindowSystemInterface::handleCloseEvent(w);
return S_OK; return S_OK;
@ -1170,6 +1188,7 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEvent
boolean visible; boolean visible;
HRESULT hr = args ? args->get_Visible(&visible) : d->coreWindow->get_Visible(&visible); HRESULT hr = args ? args->get_Visible(&visible) : d->coreWindow->get_Visible(&visible);
RETURN_OK_IF_FAILED("Failed to get visibility."); RETURN_OK_IF_FAILED("Failed to get visibility.");
qCDebug(lcQpaWindows) << __FUNCTION__ << visible;
QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden); QWindowSystemInterface::handleApplicationStateChanged(visible ? Qt::ApplicationActive : Qt::ApplicationHidden);
if (visible) if (visible)
handleExpose(); handleExpose();
@ -1179,7 +1198,7 @@ HRESULT QWinRTScreen::onVisibilityChanged(ICoreWindow *, IVisibilityChangedEvent
HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *) HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *)
{ {
Q_D(QWinRTScreen); Q_D(QWinRTScreen);
qCDebug(lcQpaWindows) << __FUNCTION__;
DisplayOrientations displayOrientation; DisplayOrientations displayOrientation;
HRESULT hr = d->displayInformation->get_CurrentOrientation(&displayOrientation); HRESULT hr = d->displayInformation->get_CurrentOrientation(&displayOrientation);
RETURN_OK_IF_FAILED("Failed to get current orientations."); RETURN_OK_IF_FAILED("Failed to get current orientations.");
@ -1187,7 +1206,8 @@ HRESULT QWinRTScreen::onOrientationChanged(IDisplayInformation *, IInspectable *
Qt::ScreenOrientation newOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation))); Qt::ScreenOrientation newOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
if (d->orientation != newOrientation) { if (d->orientation != newOrientation) {
d->orientation = newOrientation; d->orientation = newOrientation;
#ifdef Q_OS_WINPHONE qCDebug(lcQpaWindows) << " New orientation:" << newOrientation;
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
onSizeChanged(nullptr, nullptr); onSizeChanged(nullptr, nullptr);
#endif #endif
QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation); QWindowSystemInterface::handleScreenOrientationChange(screen(), d->orientation);
@ -1211,6 +1231,8 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
hr = d->displayInformation->get_ResolutionScale(&resolutionScale); hr = d->displayInformation->get_ResolutionScale(&resolutionScale);
d->scaleFactor = qreal(resolutionScale) / 100; d->scaleFactor = qreal(resolutionScale) / 100;
#endif #endif
qCDebug(lcQpaWindows) << __FUNCTION__ << "Scale Factor:" << d->scaleFactor;
RETURN_OK_IF_FAILED("Failed to get scale factor"); RETURN_OK_IF_FAILED("Failed to get scale factor");
FLOAT dpi; FLOAT dpi;
@ -1225,6 +1247,8 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
hr = d->displayInformation->get_RawDpiY(&dpi); hr = d->displayInformation->get_RawDpiY(&dpi);
RETURN_OK_IF_FAILED("Failed to get y raw DPI."); RETURN_OK_IF_FAILED("Failed to get y raw DPI.");
d->physicalDpi.second = dpi ? dpi : 96.0; d->physicalDpi.second = dpi ? dpi : 96.0;
qCDebug(lcQpaWindows) << __FUNCTION__ << "Logical DPI:" << d->logicalDpi
<< "Physical DPI:" << d->physicalDpi;
return S_OK; return S_OK;
} }
@ -1232,12 +1256,14 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
#ifdef Q_OS_WINPHONE #ifdef Q_OS_WINPHONE
HRESULT QWinRTScreen::onStatusBarShowing(IStatusBar *, IInspectable *) HRESULT QWinRTScreen::onStatusBarShowing(IStatusBar *, IInspectable *)
{ {
qCDebug(lcQpaWindows) << __FUNCTION__;
onSizeChanged(nullptr, nullptr); onSizeChanged(nullptr, nullptr);
return S_OK; return S_OK;
} }
HRESULT QWinRTScreen::onStatusBarHiding(IStatusBar *, IInspectable *) HRESULT QWinRTScreen::onStatusBarHiding(IStatusBar *, IInspectable *)
{ {
qCDebug(lcQpaWindows) << __FUNCTION__;
onSizeChanged(nullptr, nullptr); onSizeChanged(nullptr, nullptr);
return S_OK; return S_OK;
} }

View File

@ -93,6 +93,7 @@ public:
QImage::Format format() const Q_DECL_OVERRIDE; QImage::Format format() const Q_DECL_OVERRIDE;
QSizeF physicalSize() const Q_DECL_OVERRIDE; QSizeF physicalSize() const Q_DECL_OVERRIDE;
QDpi logicalDpi() const Q_DECL_OVERRIDE; QDpi logicalDpi() const Q_DECL_OVERRIDE;
qreal pixelDensity() const Q_DECL_OVERRIDE;
qreal scaleFactor() const; qreal scaleFactor() const;
QPlatformCursor *cursor() const Q_DECL_OVERRIDE; QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
Qt::KeyboardModifiers keyboardModifiers() const; Qt::KeyboardModifiers keyboardModifiers() const;

View File

@ -429,6 +429,7 @@ void QXcbDrag::move(const QPoint &globalPos)
xcb_client_message_event_t enter; xcb_client_message_event_t enter;
enter.response_type = XCB_CLIENT_MESSAGE; enter.response_type = XCB_CLIENT_MESSAGE;
enter.sequence = 0;
enter.window = target; enter.window = target;
enter.format = 32; enter.format = 32;
enter.type = atom(QXcbAtom::XdndEnter); enter.type = atom(QXcbAtom::XdndEnter);
@ -457,6 +458,7 @@ void QXcbDrag::move(const QPoint &globalPos)
xcb_client_message_event_t move; xcb_client_message_event_t move;
move.response_type = XCB_CLIENT_MESSAGE; move.response_type = XCB_CLIENT_MESSAGE;
move.sequence = 0;
move.window = target; move.window = target;
move.format = 32; move.format = 32;
move.type = atom(QXcbAtom::XdndPosition); move.type = atom(QXcbAtom::XdndPosition);
@ -485,6 +487,7 @@ void QXcbDrag::drop(const QPoint &globalPos)
xcb_client_message_event_t drop; xcb_client_message_event_t drop;
drop.response_type = XCB_CLIENT_MESSAGE; drop.response_type = XCB_CLIENT_MESSAGE;
drop.sequence = 0;
drop.window = current_target; drop.window = current_target;
drop.format = 32; drop.format = 32;
drop.type = atom(QXcbAtom::XdndDrop); drop.type = atom(QXcbAtom::XdndDrop);
@ -746,6 +749,7 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message
xcb_client_message_event_t response; xcb_client_message_event_t response;
response.response_type = XCB_CLIENT_MESSAGE; response.response_type = XCB_CLIENT_MESSAGE;
response.sequence = 0;
response.window = xdnd_dragsource; response.window = xdnd_dragsource;
response.format = 32; response.format = 32;
response.type = atom(QXcbAtom::XdndStatus); response.type = atom(QXcbAtom::XdndStatus);
@ -892,6 +896,7 @@ void QXcbDrag::send_leave()
xcb_client_message_event_t leave; xcb_client_message_event_t leave;
leave.response_type = XCB_CLIENT_MESSAGE; leave.response_type = XCB_CLIENT_MESSAGE;
leave.sequence = 0;
leave.window = current_target; leave.window = current_target;
leave.format = 32; leave.format = 32;
leave.type = atom(QXcbAtom::XdndLeave); leave.type = atom(QXcbAtom::XdndLeave);
@ -962,6 +967,7 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
xcb_client_message_event_t finished; xcb_client_message_event_t finished;
finished.response_type = XCB_CLIENT_MESSAGE; finished.response_type = XCB_CLIENT_MESSAGE;
finished.sequence = 0;
finished.window = xdnd_dragsource; finished.window = xdnd_dragsource;
finished.format = 32; finished.format = 32;
finished.type = atom(QXcbAtom::XdndFinished); finished.type = atom(QXcbAtom::XdndFinished);

View File

@ -367,6 +367,7 @@ void QXcbScreen::sendStartupMessage(const QByteArray &message) const
ev.response_type = XCB_CLIENT_MESSAGE; ev.response_type = XCB_CLIENT_MESSAGE;
ev.format = 8; ev.format = 8;
ev.type = connection()->atom(QXcbAtom::_NET_STARTUP_INFO_BEGIN); ev.type = connection()->atom(QXcbAtom::_NET_STARTUP_INFO_BEGIN);
ev.sequence = 0;
ev.window = rootWindow; ev.window = rootWindow;
int sent = 0; int sent = 0;
int length = message.length() + 1; // include NUL byte int length = message.length() + 1; // include NUL byte

View File

@ -100,9 +100,9 @@ xcb_window_t QXcbSystemTrayTracker::locateTrayWindow(const QXcbConnection *conne
void QXcbSystemTrayTracker::requestSystemTrayWindowDock(xcb_window_t window) const void QXcbSystemTrayTracker::requestSystemTrayWindowDock(xcb_window_t window) const
{ {
xcb_client_message_event_t trayRequest; xcb_client_message_event_t trayRequest;
memset(&trayRequest, 0, sizeof(trayRequest));
trayRequest.response_type = XCB_CLIENT_MESSAGE; trayRequest.response_type = XCB_CLIENT_MESSAGE;
trayRequest.format = 32; trayRequest.format = 32;
trayRequest.sequence = 0;
trayRequest.window = m_trayWindow; trayRequest.window = m_trayWindow;
trayRequest.type = m_trayAtom; trayRequest.type = m_trayAtom;
trayRequest.data.data32[0] = XCB_CURRENT_TIME; trayRequest.data.data32[0] = XCB_CURRENT_TIME;

View File

@ -1111,21 +1111,37 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
void QXcbWindow::setNetWmStates(NetWmStates states) void QXcbWindow::setNetWmStates(NetWmStates states)
{ {
QVector<xcb_atom_t> atoms; QVector<xcb_atom_t> atoms;
if (states & NetWmStateAbove)
xcb_get_property_cookie_t get_cookie =
xcb_get_property_unchecked(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE),
XCB_ATOM_ATOM, 0, 1024);
xcb_get_property_reply_t *reply =
xcb_get_property_reply(xcb_connection(), get_cookie, NULL);
if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM && reply->value_len > 0) {
const xcb_atom_t *data = static_cast<const xcb_atom_t *>(xcb_get_property_value(reply));
atoms.resize(reply->value_len);
memcpy((void *)&atoms.first(), (void *)data, reply->value_len * sizeof(xcb_atom_t));
}
free(reply);
if (states & NetWmStateAbove && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_ABOVE)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE)); atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE));
if (states & NetWmStateBelow) if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_BELOW)); atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_BELOW));
if (states & NetWmStateFullScreen) if (states & NetWmStateFullScreen && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)); atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
if (states & NetWmStateMaximizedHorz) if (states & NetWmStateMaximizedHorz && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)); atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ));
if (states & NetWmStateMaximizedVert) if (states & NetWmStateMaximizedVert && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)); atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT));
if (states & NetWmStateModal) if (states & NetWmStateModal && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MODAL)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MODAL)); atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MODAL));
if (states & NetWmStateStaysOnTop) if (states & NetWmStateStaysOnTop && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)); atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP));
if (states & NetWmStateDemandsAttention) if (states & NetWmStateDemandsAttention && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)); atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION));
if (atoms.isEmpty()) { if (atoms.isEmpty()) {
@ -1245,6 +1261,7 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two)
event.response_type = XCB_CLIENT_MESSAGE; event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32; event.format = 32;
event.sequence = 0;
event.window = m_window; event.window = m_window;
event.type = atom(QXcbAtom::_NET_WM_STATE); event.type = atom(QXcbAtom::_NET_WM_STATE);
event.data.data32[0] = set ? 1 : 0; event.data.data32[0] = set ? 1 : 0;
@ -1286,6 +1303,7 @@ void QXcbWindow::setWindowState(Qt::WindowState state)
event.response_type = XCB_CLIENT_MESSAGE; event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32; event.format = 32;
event.sequence = 0;
event.window = m_window; event.window = m_window;
event.type = atom(QXcbAtom::WM_CHANGE_STATE); event.type = atom(QXcbAtom::WM_CHANGE_STATE);
event.data.data32[0] = XCB_WM_STATE_ICONIC; event.data.data32[0] = XCB_WM_STATE_ICONIC;
@ -1690,6 +1708,7 @@ void QXcbWindow::requestActivateWindow()
event.response_type = XCB_CLIENT_MESSAGE; event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32; event.format = 32;
event.sequence = 0;
event.window = m_window; event.window = m_window;
event.type = atom(QXcbAtom::_NET_ACTIVE_WINDOW); event.type = atom(QXcbAtom::_NET_ACTIVE_WINDOW);
event.data.data32[0] = 1; event.data.data32[0] = 1;
@ -2636,6 +2655,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
xcb_client_message_event_t xev; xcb_client_message_event_t xev;
xev.response_type = XCB_CLIENT_MESSAGE; xev.response_type = XCB_CLIENT_MESSAGE;
xev.type = moveResize; xev.type = moveResize;
xev.sequence = 0;
xev.window = xcb_window(); xev.window = xcb_window();
xev.format = 32; xev.format = 32;
const QPoint globalPos = window()->mapToGlobal(pos); const QPoint globalPos = window()->mapToGlobal(pos);
@ -2664,6 +2684,7 @@ void QXcbWindow::sendXEmbedMessage(xcb_window_t window, quint32 message,
event.response_type = XCB_CLIENT_MESSAGE; event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32; event.format = 32;
event.sequence = 0;
event.window = window; event.window = window;
event.type = atom(QXcbAtom::_XEMBED); event.type = atom(QXcbAtom::_XEMBED);
event.data.data32[0] = connection()->time(); event.data.data32[0] = connection()->time();

View File

@ -44,6 +44,9 @@
#include <QtCore/qvector.h> #include <QtCore/qvector.h>
#include <QtSql/qsql.h> #include <QtSql/qsql.h>
// for testing:
class tst_QSqlQuery;
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -60,6 +63,8 @@ class Q_SQL_EXPORT QSqlResult
Q_DECLARE_PRIVATE(QSqlResult) Q_DECLARE_PRIVATE(QSqlResult)
friend class QSqlQuery; friend class QSqlQuery;
friend class QSqlTableModelPrivate; friend class QSqlTableModelPrivate;
// for testing:
friend class ::tst_QSqlQuery;
public: public:
virtual ~QSqlResult(); virtual ~QSqlResult();

View File

@ -0,0 +1,5 @@
set_property(TARGET Qt5::Test
APPEND PROPERTY
INTERFACE_COMPILE_DEFINITIONS QT_TESTCASE_BUILDDIR=\\\"\${CMAKE_BINARY_DIR}\\\"
)

View File

@ -402,4 +402,6 @@ void QErrorMessagePrivate::retranslateStrings()
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qerrormessage.cpp"
#endif // QT_NO_ERRORMESSAGE #endif // QT_NO_ERRORMESSAGE

View File

@ -345,3 +345,5 @@ void QFileInfoGatherer::fetch(const QFileInfo &fileInfo, QElapsedTimer &base, bo
#endif // QT_NO_FILESYSTEMMODEL #endif // QT_NO_FILESYSTEMMODEL
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qfileinfogatherer_p.cpp"

View File

@ -515,4 +515,6 @@ bool QSidebar::event(QEvent * event)
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qsidebar_p.cpp"
#endif #endif

View File

@ -1235,4 +1235,7 @@ void QGraphicsOpacityEffect::draw(QPainter *painter)
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qgraphicseffect.cpp"
#include "moc_qgraphicseffect_p.cpp"
#endif //QT_NO_GRAPHICSEFFECT #endif //QT_NO_GRAPHICSEFFECT

View File

@ -1345,4 +1345,6 @@ void QPixmapDropShadowFilter::draw(QPainter *p,
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qpixmapfilter_p.cpp"
#endif //QT_NO_GRAPHICSEFFECT #endif //QT_NO_GRAPHICSEFFECT

View File

@ -529,4 +529,7 @@ QSizeF QGraphicsAnchorLayout::sizeHint(Qt::SizeHint which, const QSizeF &constra
} }
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qgraphicsanchorlayout.cpp"
#endif //QT_NO_GRAPHICSVIEW #endif //QT_NO_GRAPHICSVIEW

View File

@ -594,4 +594,6 @@ void QGraphicsItemAnimation::afterAnimationStep(qreal step)
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qgraphicsitemanimation.cpp"
#endif // QT_NO_GRAPHICSVIEW #endif // QT_NO_GRAPHICSVIEW

View File

@ -91,3 +91,4 @@
Add the \a item from the index. Add the \a item from the index.
*/ */
#include "moc_qgraphicsscenelinearindex_p.cpp"

View File

@ -2417,4 +2417,6 @@ void QGraphicsWidget::dumpFocusChain()
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qgraphicswidget.cpp"
#endif //QT_NO_GRAPHICSVIEW #endif //QT_NO_GRAPHICSVIEW

View File

@ -4401,7 +4401,20 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes,
QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r); QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r);
if (paintPairs.isEmpty()) if (paintPairs.isEmpty())
return QPixmap(); return QPixmap();
QPixmap pixmap(r->size());
qreal scale = 1.0f;
Q_Q(const QAbstractItemView);
QWidget *window = q->window();
if (window) {
QWindow *windowHandle = window->windowHandle();
if (windowHandle)
scale = windowHandle->devicePixelRatio();
}
QPixmap pixmap(r->size() * scale);
pixmap.setDevicePixelRatio(scale);
pixmap.fill(Qt::transparent); pixmap.fill(Qt::transparent);
QPainter painter(&pixmap); QPainter painter(&pixmap);
QStyleOptionViewItem option = viewOptionsV1(); QStyleOptionViewItem option = viewOptionsV1();

View File

@ -189,4 +189,6 @@ originalXLocation(-1)
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qcolumnviewgrip_p.cpp"
#endif // QT_NO_QCOLUMNVIEW #endif // QT_NO_QCOLUMNVIEW

View File

@ -613,4 +613,6 @@ QT_END_NAMESPACE
#include "qitemeditorfactory.moc" #include "qitemeditorfactory.moc"
#endif #endif
#include "moc_qitemeditorfactory_p.cpp"
#endif // QT_NO_ITEMVIEWS #endif // QT_NO_ITEMVIEWS

View File

@ -3301,4 +3301,6 @@ QSize QListView::viewportSizeHint() const
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qlistview.cpp"
#endif // QT_NO_LISTVIEW #endif // QT_NO_LISTVIEW

View File

@ -1975,5 +1975,6 @@ bool QListWidget::event(QEvent *e)
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qlistwidget.cpp" #include "moc_qlistwidget.cpp"
#include "moc_qlistwidget_p.cpp"
#endif // QT_NO_LISTWIDGET #endif // QT_NO_LISTWIDGET

View File

@ -2721,5 +2721,6 @@ void QTableWidget::dropEvent(QDropEvent *event) {
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qtablewidget.cpp" #include "moc_qtablewidget.cpp"
#include "moc_qtablewidget_p.cpp"
#endif // QT_NO_TABLEWIDGET #endif // QT_NO_TABLEWIDGET

View File

@ -3466,5 +3466,6 @@ bool QTreeWidget::event(QEvent *e)
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qtreewidget.cpp" #include "moc_qtreewidget.cpp"
#include "moc_qtreewidget_p.cpp"
#endif // QT_NO_TREEWIDGET #endif // QT_NO_TREEWIDGET

View File

@ -1354,3 +1354,5 @@ QVBoxLayout::~QVBoxLayout()
} }
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qboxlayout.cpp"

View File

@ -274,3 +274,4 @@ void QDesktopWidget::resizeEvent(QResizeEvent *)
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qdesktopwidget.cpp" #include "moc_qdesktopwidget.cpp"
#include "moc_qdesktopwidget_p.cpp"

View File

@ -2114,3 +2114,5 @@ void QFormLayout::dump() const
#endif #endif
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qformlayout.cpp"

View File

@ -1692,3 +1692,5 @@ void QGridLayout::invalidate()
} }
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qgridlayout.cpp"

View File

@ -1477,3 +1477,5 @@ QSize QLayout::closestAcceptableSize(const QWidget *widget, const QSize &size)
} }
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qlayout.cpp"

View File

@ -1349,3 +1349,5 @@ bool QOpenGLWidget::event(QEvent *e)
} }
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qopenglwidget.cpp"

View File

@ -658,3 +658,5 @@ bool QShortcut::event(QEvent *e)
#endif // QT_NO_SHORTCUT #endif // QT_NO_SHORTCUT
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qshortcut.cpp"

View File

@ -512,3 +512,5 @@ QDebug operator<<(QDebug dbg, const QSizePolicy &p)
#endif #endif
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qsizepolicy.cpp"

View File

@ -596,3 +596,5 @@ void QStackedLayout::setStackingMode(StackingMode stackingMode)
} }
QT_END_NAMESPACE QT_END_NAMESPACE
#include "moc_qstackedlayout.cpp"

View File

@ -1892,7 +1892,6 @@ void QWidgetPrivate::deleteTLSysExtra()
if (extra->topextra->window) { if (extra->topextra->window) {
extra->topextra->window->destroy(); extra->topextra->window->destroy();
} }
setWinId(0);
delete extra->topextra->window; delete extra->topextra->window;
extra->topextra->window = 0; extra->topextra->window = 0;
@ -7245,7 +7244,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
if (q->isVisible()) if (q->isVisible())
hide_sys(); hide_sys();
data.crect = QRect(x, y, w, h); data.crect = QRect(x, y, w, h);
} else if (q->isVisible() && q->testAttribute(Qt::WA_OutsideWSRange)) { } else if (q->testAttribute(Qt::WA_OutsideWSRange)) {
q->setAttribute(Qt::WA_OutsideWSRange, false); q->setAttribute(Qt::WA_OutsideWSRange, false);
needsShow = true; needsShow = true;
} }

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