Merge "Merge remote-tracking branch 'origin/5.6' into 5.7" into refs/staging/5.7

This commit is contained in:
Liang Qi 2016-03-21 16:14:42 +00:00 committed by The Qt Project
commit f9e746959b
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_DIRECTWRITE" = "yes" ] && QT_CONFIG="$QT_CONFIG directwrite"
[ '!' -z "$DEFINES" ] && QMakeVar add DEFINES "$DEFINES"
[ '!' -z "$INCLUDES" ] && QMakeVar add INCLUDEPATH "$INCLUDES"
[ '!' -z "$L_FLAGS" ] && QMakeVar add LIBS "$L_FLAGS"
[ '!' -z "$DEFINES" ] && QMakeVar add EXTRA_DEFINES "$DEFINES"
[ '!' -z "$INCLUDES" ] && QMakeVar add EXTRA_INCLUDEPATH "$INCLUDES"
[ '!' -z "$L_FLAGS" ] && QMakeVar add EXTRA_LIBS "$L_FLAGS"
if [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then
if [ -n "$RPATH_FLAGS" ]; then
@ -6571,7 +6571,7 @@ if [ -z "`getXQMakeConf 'QMAKE_(LFLAGS_)?RPATH'`" ]; then
else
if [ -n "$RPATH_FLAGS" ]; then
# add the user defined rpaths
QMakeVar add QMAKE_RPATHDIR "$RPATH_FLAGS"
QMakeVar add EXTRA_RPATHS "$RPATH_FLAGS"
fi
fi
if [ "$CFG_RPATH" = "yes" ]; then
@ -7159,9 +7159,6 @@ if [ -n "$CFG_SYSROOT" ] && [ "$CFG_GCC_SYSROOT" = "yes" ]; then
echo "}"
echo
fi
if [ -n "$RPATH_FLAGS" ]; then
echo "QMAKE_RPATHDIR += $RPATH_FLAGS"
fi
echo "QT_COMPILER_STDCXX = $CFG_STDCXX_DEFAULT"
if [ -n "$QT_GCC_MAJOR_VERSION" ]; then
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.
QUrl url(event->mimeData()->text());
if (url.isValid() && url.scheme().toLower() == "file"
if (url.isValid() && url.scheme() == "file"
&& url.path().toLower().endsWith(".torrent"))
event->acceptProposedAction();
}

View File

@ -160,21 +160,8 @@ qt_module_deps = $$resolve_depends(qt_module_deps, "QT.")
contains(qt_module_deps, core) {
relative_qt_rpath:!isEmpty(QMAKE_REL_RPATH_BASE):contains(INSTALLS, target):\
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
QMAKE_RPATHDIR += $$relative_path($$[QT_INSTALL_LIBS], $$binpath)
QMAKE_RPATHDIR += $$relative_path($$[QT_INSTALL_LIBS], $$qtRelativeRPathBase())
} else {
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)
}
# Apply extra compiler flags passed via configure last.
CONFIG = qt_build_extra $$CONFIG
# Don't actually try to install anything in non-prefix builds.
# This is much easier and safer than making every single INSTALLS
# assignment conditional.
@ -72,6 +75,10 @@ CONFIG += \
# However, testcases should be still built with 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) {
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)
}
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) {
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)
{
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);
if (ret.isEmpty())
return ret;
const QString root = installRoot();
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.
@ -7,104 +7,41 @@ Files available for download:
Source files with LF line endings (for Unix/Linux) and with a
"configure" script
libpng-1.6.19.tar.xz (LZMA-compressed, recommended)
libpng-1.6.19.tar.gz
libpng-1.6.20.tar.xz (LZMA-compressed, recommended)
libpng-1.6.20.tar.gz
Source files with CRLF line endings (for Windows), without the
"configure" script
lpng1619.7z (LZMA-compressed, recommended)
lpng1619.zip
/scratch/glennrp/Libpng16/lpng1620.7z (LZMA-compressed, recommended)
/scratch/glennrp/Libpng16/lpng1620.zip
Other information:
libpng-1.6.19-README.txt
libpng-1.6.19-LICENSE.txt
libpng-1.6.19-*.asc (armored detached GPG signatures)
libpng-1.6.20-README.txt
libpng-1.6.20-LICENSE.txt
libpng-1.6.20-*.asc (armored detached GPG signatures)
Changes since the last public release (1.6.18):
Updated obsolete information about the simplified API macros in the
manual pages (Bug report by Arc Riley).
Avoid potentially dereferencing NULL info_ptr in png_info_init_3().
Rearranged png.h to put the major sections in the same order as
in libpng17.
Eliminated unused PNG_COST_SHIFT, PNG_WEIGHT_SHIFT, PNG_COST_FACTOR, and
PNG_WEIGHT_FACTOR macros.
Suppressed some warnings from the Borland C++ 5.5.1/5.82 compiler
(Bug report by Viktor Szakats). Several warnings remain and are
unavoidable, where we test for overflow.
Fixed potential leak of png_pixels in contrib/pngminus/pnm2png.c
Fixed uninitialized variable in contrib/gregbook/rpng2-x.c
Moved config.h.in~ from the "libpng_autotools_files" list to the
"libpng_autotools_extra" list in autogen.sh because it was causing a
false positive for missing files (bug report by Robert C. Seacord).
Removed unreachable "break" statements in png.c, pngread.c, and pngrtran.c
to suppress clang warnings (Bug report by Viktor Szakats).
Fixed some bad links in the man page.
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.
Changes since the last public release (1.6.19):
Avoid potential pointer overflow/underflow in png_handle_sPLT() and
png_handle_pCAL() (Bug report by John Regehr).
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.
Backported tests from libpng-1.7.0beta69.
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.
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).
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit

View File

@ -5409,11 +5409,43 @@ Version 1.6.19rc03 [November 3, 2015]
Version 1.6.19rc04 [November 5, 2015]
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]
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
(subscription required; visit
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.
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
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
@ -109,4 +109,4 @@ the additional disclaimers inserted at version 1.0.7.
Glenn Randers-Pehrson
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 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 version 1.6.19 - November 12, 2015
libpng version 1.6.20 - December 3, 2015
Updated and distributed by Glenn Randers-Pehrson
<glennrp at users.sourceforge.net>
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:
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
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)
num_palette - number of entries in the palette
png_set_gAMA(png_ptr, info_ptr, 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(),
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
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
default safe
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.
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.
Libpng only has two year fields. One is a 2-byte unsigned integer

View File

@ -14,7 +14,7 @@
#include "pngpriv.h"
/* 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
* 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
# ifdef __STDC__
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) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
PNG_STRING_NEWLINE;
# 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) 1996-1997 Andreas Dilger\
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".
*/
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);
break;
# endif

View File

@ -1,7 +1,7 @@
/* 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
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
@ -12,7 +12,8 @@
* Authors and maintainers:
* 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.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.
*/
@ -24,7 +25,7 @@
*
* 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
* 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
@ -185,7 +186,7 @@
* ...
* 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
* and minor numbers; the shared-library major version number will be
@ -213,13 +214,13 @@
* Y2K compliance in libpng:
* =========================
*
* November 12, 2015
* December 3, 2015
*
* Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration.
*
* 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.
*
* 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 */
#define PNG_LIBPNG_VER_STRING "1.6.19"
#define PNG_LIBPNG_VER_STRING "1.6.20"
#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_DLLNUM 16
@ -291,7 +292,7 @@
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1
#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
* 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.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
* 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
* 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.
*

View File

@ -1,7 +1,7 @@
/* 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
* (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
* 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
* PNG_ABORT().
*/

View File

@ -223,7 +223,7 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
/* Storage for unknown chunks that the library doesn't recognize. */
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.
*/
int unknown_chunks_num;

View File

@ -1,6 +1,6 @@
/* 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 */

View File

@ -133,7 +133,7 @@ png_process_some_data(png_structrp png_ptr, png_inforp info_ptr)
void /* PRIVATE */
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;
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
* 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. */
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. */
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
/* Optional call to update the users info structure */
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:
png_error(png_ptr, "invalid PNG color type");
/*NOT REACHED*/
break;
}
/* Now deal with the output processing */

View File

@ -1,7 +1,7 @@
/* 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
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (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) ==
PNG_OPTION_ON)
{
window_bits = 15;
png_ptr->zstream_start = 0; /* fixed window size */
}
else
{
window_bits = 0;
png_ptr->zstream_start = 1;
}
# else
# define window_bits 0
# endif
@ -429,6 +435,31 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner)
#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
/* 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
@ -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
* 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));
} 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
* streams.
*/
ret = inflate(&png_ptr->zstream,
ret = PNG_INFLATE(png_ptr,
*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));
@ -1670,7 +1701,7 @@ png_handle_sPLT(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
++entry_start;
/* 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");
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
* in order to get the parameter information.
*/
if (endptr <= buf + 12)
if (endptr - buf <= 12)
{
png_chunk_benign_error(png_ptr, "invalid");
return;
@ -4039,7 +4070,7 @@ png_read_IDAT_data(png_structrp png_ptr, png_bytep output,
*
* 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. */
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)
return;
max_palette_length = (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
(1 << png_ptr->bit_depth) : PNG_MAX_PALETTE_LENGTH;
max_palette_length = (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ?
(1 << info_ptr->bit_depth) : PNG_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
* 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)
return;

View File

@ -263,6 +263,9 @@ struct png_struct_def
/* pixel depth used for the row buffers */
png_byte transformed_pixel_depth;
/* 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)
png_uint_16 filler; /* filler bytes for pixel expansion */
#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)
/* 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;
}
@ -2572,7 +2572,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
png_size_t sum;
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)
{
@ -2598,7 +2598,7 @@ png_write_find_filter(png_structrp png_ptr, png_row_infop row_info)
png_size_t sum;
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)
{

View File

@ -98,6 +98,11 @@ extern char *__progname;
#if defined(Q_OS_LINUX) && (defined(__GLIBC__) || QT_HAS_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()
{
// no error handling

View File

@ -118,14 +118,14 @@ public:
*/
// apply defaults for a generic QTypeInfo<T> that didn't provide the new values
template <typename T, typename = void>
struct QTypeInfoQuery : QTypeInfo<T>
struct QTypeInfoQuery : public QTypeInfo<T>
{
enum { isRelocatable = !QTypeInfo<T>::isStatic };
};
// if QTypeInfo<T>::isRelocatable exists, use it
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);
forever {
// Check if we have any data pending: the pipe writer has
// 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());
bool pendingDataInPipe = stdinChannel.writer && stdinChannel.writer->bytesToWrite();
// If we don't have pending data, and our write buffer is
// empty, we fail.
@ -815,7 +812,6 @@ qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q);
QObjectPrivate::connect(stdinChannel.writer, &QWindowsPipeWriter::canWrite,
this, &QProcessPrivate::_q_canWrite);
stdinChannel.writer->start();
}
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()
static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type)
{
#ifndef Q_OS_WINCE
static const int clsids[] = {
CSIDL_DESKTOPDIRECTORY, // DesktopLocation
CSIDL_PERSONAL, // DocumentsLocation
@ -136,6 +137,27 @@ static int writableSpecialFolderClsid(QStandardPaths::StandardLocation type)
CSIDL_APPDATA, // AppDataLocation ("Roaming" 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));
return size_t(type) < sizeof(clsids) / sizeof(clsids[0]) ? clsids[type] : -1;

View File

@ -38,28 +38,40 @@
****************************************************************************/
#include "qwindowspipereader_p.h"
#include "qwinoverlappedionotifier_p.h"
#include <qdebug.h>
#include "qiodevice_p.h"
#include <qelapsedtimer.h>
#include <qeventloop.h>
QT_BEGIN_NAMESPACE
QWindowsPipeReader::Overlapped::Overlapped(QWindowsPipeReader *reader)
: pipeReader(reader)
{
}
void QWindowsPipeReader::Overlapped::clear()
{
ZeroMemory(this, sizeof(OVERLAPPED));
}
QWindowsPipeReader::QWindowsPipeReader(QObject *parent)
: QObject(parent),
handle(INVALID_HANDLE_VALUE),
overlapped(this),
readBufferMaxSize(0),
actualReadBufferSize(0),
stopped(true),
readSequenceStarted(false),
notifiedCalled(false),
pipeBroken(false),
readyReadEmitted(false)
readyReadPending(false),
inReadyRead(false)
{
dataReadNotifier = new QWinOverlappedIoNotifier(this);
connect(dataReadNotifier, &QWinOverlappedIoNotifier::notified, this, &QWindowsPipeReader::notified);
connect(this, &QWindowsPipeReader::_q_queueReadyRead,
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);
static PtrCancelIoEx ptrCancelIoEx = 0;
@ -88,12 +100,6 @@ void QWindowsPipeReader::setHandle(HANDLE hPipeReadEnd)
actualReadBufferSize = 0;
handle = hPipeReadEnd;
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;
if (readSequenceStarted) {
if (qt_cancelIo(handle, &overlapped)) {
dataReadNotifier->waitForNotified(-1, &overlapped);
} else {
if (!qt_cancelIo(handle, &overlapped)) {
const DWORD dwError = GetLastError();
if (dwError != ERROR_NOT_FOUND) {
qErrnoWarning(dwError, "QWindowsPipeReader: qt_cancelIo on handle %x failed.",
handle);
}
}
waitForNotification(-1);
}
readSequenceStarted = false;
dataReadNotifier->setEnabled(false);
handle = INVALID_HANDLE_VALUE;
}
/*!
@ -174,11 +176,10 @@ bool QWindowsPipeReader::canReadLine() const
\internal
Will be called whenever the read operation completes.
*/
void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode,
OVERLAPPED *notifiedOverlapped)
void QWindowsPipeReader::notified(DWORD errorCode, DWORD numberOfBytesRead)
{
if (&overlapped != notifiedOverlapped)
return;
notifiedCalled = true;
readSequenceStarted = false;
switch (errorCode) {
case ERROR_SUCCESS:
@ -202,8 +203,6 @@ void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode,
break;
}
readSequenceStarted = false;
// 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
// be started in this case.
@ -218,13 +217,15 @@ void QWindowsPipeReader::notified(quint32 numberOfBytesRead, quint32 errorCode,
actualReadBufferSize += numberOfBytesRead;
readBuffer.truncate(actualReadBufferSize);
startAsyncRead();
readyReadEmitted = true;
emit readyRead();
if (!readyReadPending) {
readyReadPending = true;
emit _q_queueReadyRead(QWindowsPipeReader::QPrivateSignal());
}
}
/*!
\internal
Reads data from the socket into the readbuffer
Reads data from the pipe into the readbuffer.
*/
void QWindowsPipeReader::startAsyncRead()
{
@ -244,41 +245,39 @@ void QWindowsPipeReader::startAsyncRead()
char *ptr = readBuffer.reserve(bytesToRead);
stopped = false;
readSequenceStarted = true;
ZeroMemory(&overlapped, sizeof(overlapped));
if (ReadFile(handle, ptr, bytesToRead, NULL, &overlapped)) {
// We get notified by the QWinOverlappedIoNotifier - even in the synchronous case.
return;
} else {
overlapped.clear();
if (!ReadFileEx(handle, ptr, bytesToRead, &overlapped, &readFileCompleted)) {
readSequenceStarted = false;
const DWORD dwError = GetLastError();
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_PIPE_NOT_CONNECTED:
{
// It may happen, that the other side closes the connection directly
// after writing data. Then we must set the appropriate socket state.
readSequenceStarted = false;
pipeBroken = true;
emit pipeClosed();
return;
}
// It may happen, that the other side closes the connection directly
// after writing data. Then we must set the appropriate socket state.
pipeBroken = true;
emit pipeClosed();
break;
default:
readSequenceStarted = false;
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
Returns the number of available bytes in the pipe.
@ -298,17 +297,60 @@ DWORD QWindowsPipeReader::checkPipeState()
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.
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)
{
if (!readSequenceStarted)
return false;
readyReadEmitted = false;
dataReadNotifier->waitForNotified(msecs, &overlapped);
return readyReadEmitted;
if (readyReadPending) {
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.
//
#include <qbytearray.h>
#include <qobject.h>
#include <private/qringbuffer_p.h>
@ -59,9 +58,6 @@
QT_BEGIN_NAMESPACE
class QWinOverlappedIoNotifier;
class Q_CORE_EXPORT QWindowsPipeReader : public QObject
{
Q_OBJECT
@ -70,6 +66,7 @@ public:
~QWindowsPipeReader();
void setHandle(HANDLE hPipeReadEnd);
void startAsyncRead();
void stop();
void setMaxReadBufferSize(qint64 size) { readBufferMaxSize = size; }
@ -82,31 +79,42 @@ public:
bool waitForReadyRead(int msecs);
bool waitForPipeClosed(int msecs);
void startAsyncRead();
bool isReadOperationActive() const { return readSequenceStarted; }
Q_SIGNALS:
void winError(ulong, const QString &);
void readyRead();
void pipeClosed();
private Q_SLOTS:
void notified(quint32 numberOfBytesRead, quint32 errorCode, OVERLAPPED *notifiedOverlapped);
void _q_queueReadyRead(QPrivateSignal);
private:
static void CALLBACK readFileCompleted(DWORD errorCode, DWORD numberOfBytesTransfered,
OVERLAPPED *overlappedBase);
void notified(DWORD errorCode, DWORD numberOfBytesRead);
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;
OVERLAPPED overlapped;
QWinOverlappedIoNotifier *dataReadNotifier;
Overlapped overlapped;
qint64 readBufferMaxSize;
QRingBuffer readBuffer;
qint64 actualReadBufferSize;
bool stopped;
bool readSequenceStarted;
bool notifiedCalled;
bool pipeBroken;
bool readyReadEmitted;
bool readyReadPending;
bool inReadyRead;
};
QT_END_NAMESPACE

View File

@ -38,144 +38,177 @@
****************************************************************************/
#include "qwindowspipewriter_p.h"
#include "qiodevice_p.h"
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),
writePipe(INVALID_HANDLE_VALUE),
quitNow(false),
hasWritten(false)
QWindowsPipeWriter::Overlapped::Overlapped(QWindowsPipeWriter *pipeWriter)
: pipeWriter(pipeWriter)
{
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()
{
lock.lock();
quitNow = true;
waitCondition.wakeOne();
lock.unlock();
if (!wait(30000))
terminate();
CloseHandle(writePipe);
stop();
}
bool QWindowsPipeWriter::waitForWrite(int msecs)
{
QMutexLocker locker(&lock);
bool hadWritten = hasWritten;
hasWritten = false;
if (hadWritten)
return true;
if (!waitCondition.wait(&lock, msecs))
if (!writeSequenceStarted)
return false;
hadWritten = hasWritten;
hasWritten = false;
return hadWritten;
if (bytesWrittenPending) {
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 -1;
QMutexLocker locker(&lock);
data.append(ptr, maxlen);
waitCondition.wakeOne();
return maxlen;
return numberOfBytesToWrite;
}
class QPipeWriterOverlapped
void QWindowsPipeWriter::emitPendingBytesWrittenValue()
{
public:
QPipeWriterOverlapped()
{
overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}
if (bytesWrittenPending) {
bytesWrittenPending = false;
const qint64 bytes = pendingBytesWrittenValue;
pendingBytesWrittenValue = 0;
~QPipeWriterOverlapped()
{
CloseHandle(overlapped.hEvent);
}
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);
inBytesWritten = true;
emit bytesWritten(bytes);
inBytesWritten = false;
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

View File

@ -52,16 +52,11 @@
//
#include <qelapsedtimer.h>
#include <qthread.h>
#include <qmutex.h>
#include <qwaitcondition.h>
#include <qobject.h>
#include <qt_windows.h>
QT_BEGIN_NAMESPACE
#ifndef QT_NO_THREAD
#define SLEEPMIN 10
#define SLEEPMAX 500
@ -110,45 +105,50 @@ private:
int nextSleep;
};
class Q_CORE_EXPORT QWindowsPipeWriter : public QThread
class Q_CORE_EXPORT QWindowsPipeWriter : public QObject
{
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:
void canWrite();
void bytesWritten(qint64 bytes);
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();
void _q_queueBytesWritten(QPrivateSignal);
private:
QByteArray data;
QWaitCondition waitCondition;
mutable QMutex lock;
HANDLE writePipe;
volatile bool quitNow;
bool hasWritten;
};
static void CALLBACK writeFileCompleted(DWORD errorCode, DWORD numberOfBytesTransfered,
OVERLAPPED *overlappedBase);
void notified(DWORD errorCode, DWORD numberOfBytesWritten);
bool waitForNotification(int timeout);
void emitPendingBytesWrittenValue();
#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

View File

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

View File

@ -119,8 +119,8 @@ public:
Q_INVOKABLE explicit QObject(QObject *parent=Q_NULLPTR);
virtual ~QObject();
virtual bool event(QEvent *);
virtual bool eventFilter(QObject *, QEvent *);
virtual bool event(QEvent *event);
virtual bool eventFilter(QObject *watched, QEvent *event);
#ifdef Q_QDOC
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; }
void setParent(QObject *);
void installEventFilter(QObject *);
void removeEventFilter(QObject *);
void setParent(QObject *parent);
void installEventFilter(QObject *filterObj);
void removeEventFilter(QObject *obj);
static QMetaObject::Connection connect(const QObject *sender, const char *signal,
const QObject *receiver, const char *member, Qt::ConnectionType = Qt::AutoConnection);
@ -428,9 +428,9 @@ protected:
int receivers(const char* signal) const;
bool isSignalConnected(const QMetaMethod &signal) const;
virtual void timerEvent(QTimerEvent *);
virtual void childEvent(QChildEvent *);
virtual void customEvent(QEvent *);
virtual void timerEvent(QTimerEvent *event);
virtual void childEvent(QChildEvent *event);
virtual void customEvent(QEvent *event);
virtual void connectNotify(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
operating system's scheduling policy. In particular, the \a priority
will be ignored on systems that do not support thread priorities
(such as on Linux, see http://linux.die.net/man/2/sched_setscheduler
for more details).
(such as on Linux, see the
\l {http://linux.die.net/man/2/sched_setscheduler}{sched_setscheduler}
documentation for more details).
\sa run(), terminate()
*/

View File

@ -252,7 +252,7 @@ Q_DECL_CONSTEXPR inline QPoint QRect::bottomLeft() const Q_DECL_NOTHROW
{ return QPoint(x1, y2); }
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
{ return x2 - x1 + 1; }

View File

@ -67,7 +67,7 @@ static QTimeZonePrivate *newBackendTimeZone()
#elif defined Q_OS_UNIX
return new QTzTimeZonePrivate();
// 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();
#elif defined QT_USE_ICU
return new QIcuTimeZonePrivate();
@ -94,7 +94,7 @@ static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId)
#elif defined Q_OS_UNIX
return new QTzTimeZonePrivate(ianaId);
// 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);
#elif defined QT_USE_ICU
return new QIcuTimeZonePrivate(ianaId);

View File

@ -48,6 +48,10 @@
QT_BEGIN_NAMESPACE
#ifndef Q_OS_WINRT
#define QT_USE_REGISTRY_TIMEZONE 1
#endif
/*
Private
@ -65,9 +69,10 @@ QT_BEGIN_NAMESPACE
// 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
#ifdef QT_USE_REGISTRY_TIMEZONE
static const char tzRegPath[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones";
static const char currTzRegPath[] = "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation";
#endif
enum {
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);
}
#ifdef QT_USE_REGISTRY_TIMEZONE
static bool openRegistryKey(const QString &keyPath, HKEY *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;
}
#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()
{
#ifdef QT_USE_REGISTRY_TIMEZONE
// TODO Consider caching results in a global static, very unlikely to change.
QList<QByteArray> list;
HKEY key = NULL;
@ -223,10 +281,16 @@ static QList<QByteArray> availableWindowsIds()
RegCloseKey(key);
}
return list;
#else // QT_USE_REGISTRY_TIMEZONE
if (gTimeZones->isEmpty())
enumerateTimeZones();
return gTimeZones->keys();
#endif // QT_USE_REGISTRY_TIMEZONE
}
static QByteArray windowsSystemZoneId()
{
#ifdef QT_USE_REGISTRY_TIMEZONE
// On Vista and later is held in the value TimeZoneKeyName in key currTzRegPath
QString id;
HKEY key = NULL;
@ -248,6 +312,11 @@ static QByteArray windowsSystemZoneId()
if (equalTzi(getRegistryTzi(winId, &ok), sysTzi))
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
return QTimeZonePrivate::utcQByteArray();
@ -368,6 +437,7 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId)
}
if (!m_windowsId.isEmpty()) {
#ifdef QT_USE_REGISTRY_TIMEZONE
// Open the base TZI for the time zone
HKEY baseKey = NULL;
const QString baseKeyPath = QString::fromUtf8(tzRegPath) + QLatin1Char('\\')
@ -404,6 +474,34 @@ void QWinTimeZonePrivate::init(const QByteArray &ianaId)
}
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

View File

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

View File

@ -486,6 +486,11 @@ QDBusSpyCallEvent::~QDBusSpyCallEvent()
}
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
for (int i = 0; i < hookCount; ++i)
@ -515,7 +520,12 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
{
if (!ref.load())
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
qDBusDebug() << this << "delivery is suspended";
pendingMessages << amsg;
@ -529,13 +539,23 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg)
// let them see the signal too
return false;
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) {
const QDBusSpyHookList &list = *qDBusSpyHookList;
qDBusDebug() << this << "invoking message spies";
QCoreApplication::postEvent(qApp, new QDBusSpyCallEvent(this, QDBusConnection(this),
amsg, list.constData(), list.size()));
return true;
if (isLocal) {
Q_ASSERT(QThread::currentThread() != thread());
qDBusDebug() << this << "invoking message spies directly";
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);
@ -1456,9 +1476,9 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
// that means the dispatchLock mutex is locked
// must not call out to user code in that case
//
// however, if the message is internal, handleMessage was called
// directly and no lock is in place. We can therefore call out to
// user code, if necessary
// however, if the message is internal, handleMessage was called directly
// (user's thread) and no lock is in place. We can therefore call out to
// user code, if necessary.
ObjectTreeNode result;
int usedLength;
QThread *objThread = 0;
@ -1497,12 +1517,14 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg)
usedLength, msg));
return;
} else if (objThread != QThread::currentThread()) {
// synchronize with other thread
// looped-back message, targeting another thread:
// synchronize with it
postEventToThread(HandleObjectCallPostEventAction, result.obj,
new QDBusActivateObjectEvent(QDBusConnection(this), this, result,
usedLength, msg, &sem));
semWait = true;
} else {
// looped-back message, targeting current thread
semWait = false;
}
} // release the lock

View File

@ -151,6 +151,7 @@ public:
{}
~QDBusSpyCallEvent();
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
QDBusMessage msg;

View File

@ -48,52 +48,31 @@
QT_BEGIN_NAMESPACE
QShapedPixmapWindow::QShapedPixmapWindow(QScreen *screen)
: QWindow(screen),
m_backingStore(0),
m_useCompositing(true)
: m_useCompositing(true)
{
setScreen(screen);
QSurfaceFormat format;
format.setAlphaBufferSize(8);
setFormat(format);
setSurfaceType(RasterSurface);
setFlags(Qt::ToolTip | Qt::FramelessWindowHint |
Qt::X11BypassWindowManagerHint | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
create();
m_backingStore = new QBackingStore(this);
setFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint
| Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
}
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)
{
m_pixmap = pixmap;
if (!m_useCompositing)
setMask(m_pixmap.mask());
if (!m_useCompositing) {
const QBitmap mask = m_pixmap.mask();
if (!mask.isNull()) {
if (!handle())
create();
setMask(mask);
}
}
}
void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
@ -101,19 +80,28 @@ void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
m_hotSpot = hotspot;
}
void QShapedPixmapWindow::updateGeometry(const QPoint &pos)
void QShapedPixmapWindow::paintEvent(QPaintEvent *)
{
if (m_pixmap.isNull())
m_backingStore->resize(QSize(1,1));
else if (m_backingStore->size() != m_pixmap.size())
m_backingStore->resize(m_pixmap.size());
setGeometry(QRect(pos - m_hotSpot, m_backingStore->size()));
if (!m_pixmap.isNull()) {
const QRect rect(QPoint(0, 0), size());
QPainter painter(this);
if (m_useCompositing)
painter.setCompositionMode(QPainter::CompositionMode_Source);
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

View File

@ -51,21 +51,18 @@
// We mean it.
//
#include <QtGui/QWindow>
#include <QtGui/QRasterWindow>
#include <QtGui/QPixmap>
#include <QtGui/QBackingStore>
QT_BEGIN_NAMESPACE
class QShapedPixmapWindow : public QWindow
class QShapedPixmapWindow : public QRasterWindow
{
Q_OBJECT
public:
explicit QShapedPixmapWindow(QScreen *screen = 0);
~QShapedPixmapWindow();
void render();
void setUseCompositing(bool on) { m_useCompositing = on; }
void setPixmap(const QPixmap &pixmap);
void setHotspot(const QPoint &hotspot);
@ -73,10 +70,9 @@ public:
void updateGeometry(const QPoint &pos);
protected:
void exposeEvent(QExposeEvent *) Q_DECL_OVERRIDE;
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
private:
QBackingStore *m_backingStore;
QPixmap m_pixmap;
QPoint m_hotSpot;
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)
{
if (qAbs(x) > 0x7fff)
return (((qlonglong)x) << 16) / y;
return (x << 16) / y;
return qlonglong(x) * (1<<16) / y;
return x * (1<<16) / y;
}
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);
}
int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);
int x = x1 << 10;
int x = x1 * (1<<10);
int y = (y1 + 32) >> 6;
int ys = (y2 + 32) >> 6;
int round = (xinc > 0) ? 32 : 0;
if (y != ys) {
x += ( ((((y << 6) + round - y1))) * xinc ) >> 6;
x += ((y * (1<<6)) + round - y1) * xinc >> 6;
if (swapped) {
lastPixel.x = x >> 16;
@ -480,7 +480,7 @@ void QCosmeticStroker::calculateLastPoint(qreal rx1, qreal ry1, qreal rx2, qreal
int round = (yinc > 0) ? 32 : 0;
if (x != xs) {
y += ( ((((x << 6) + round - x1))) * yinc ) >> 6;
y += ((x * (1<<6)) + round - x1) * yinc >> 6;
if (swapped) {
lastPixel.x = x;
@ -759,7 +759,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
dir = QCosmeticStroker::BottomToTop;
}
int xinc = F16Dot16FixedDiv(x2 - x1, y2 - y1);
int x = x1 << 10;
int x = x1 * (1<<10);
if ((stroker->lastDir ^ QCosmeticStroker::VerticalMask) == dir)
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;
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
QCosmeticStroker::Point first;
@ -810,7 +810,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
stroker->lastDir = dir;
stroker->lastAxisAligned = axisAligned;
Dasher dasher(stroker, swapped, y << 6, ys << 6);
Dasher dasher(stroker, swapped, y * (1<<6), ys * (1<<6));
do {
if (dasher.on())
@ -836,7 +836,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
dir = QCosmeticStroker::RightToLeft;
}
int yinc = F16Dot16FixedDiv(y2 - y1, x2 - x1);
int y = y1 << 10;
int y = y1 * (1<<10);
if ((stroker->lastDir ^ QCosmeticStroker::HorizontalMask) == dir)
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;
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
QCosmeticStroker::Point first;
@ -886,7 +886,7 @@ static bool drawLine(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx2,
stroker->lastDir = dir;
stroker->lastAxisAligned = axisAligned;
Dasher dasher(stroker, swapped, x << 6, xs << 6);
Dasher dasher(stroker, swapped, x * (1<<6), xs * (1<<6));
do {
if (dasher.on())
@ -929,7 +929,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
caps = swapCaps(caps);
}
int x = (x1 - 32) << 10;
int x = (x1 - 32) * (1<<10);
x -= ( ((y1 & 63) - 32) * xinc ) >> 6;
capAdjust(caps, y1, y2, x, xinc);
@ -992,7 +992,7 @@ static bool drawLineAA(QCosmeticStroker *stroker, qreal rx1, qreal ry1, qreal rx
caps = swapCaps(caps);
}
int y = (y1 - 32) << 10;
int y = (y1 - 32) * (1<<10);
y -= ( ((x1 & 63) - 32) * yinc ) >> 6;
capAdjust(caps, x1, x2, y, yinc);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -198,6 +198,9 @@ bool QLocalServerPrivate::addListener()
memset(&listener.overlapped, 0, sizeof(listener.overlapped));
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)) {
switch (GetLastError()) {
case ERROR_IO_PENDING:
@ -205,7 +208,6 @@ bool QLocalServerPrivate::addListener()
break;
case ERROR_PIPE_CONNECTED:
listener.connected = true;
SetEvent(eventHandle);
break;
default:
CloseHandle(listener.handle);
@ -257,6 +259,8 @@ bool QLocalServerPrivate::listen(const QString &name)
for (int i = 0; i < SYSTEM_MAX_PENDING_SOCKETS; ++i)
if (!addListener())
return false;
_q_onNewConnection();
return true;
}
@ -270,37 +274,43 @@ void QLocalServerPrivate::_q_onNewConnection()
{
Q_Q(QLocalServer);
DWORD dummy;
bool tryAgain;
do {
tryAgain = false;
// Reset first, otherwise we could reset an event which was asserted
// immediately after we checked the conn status.
ResetEvent(eventHandle);
// Reset first, otherwise we could reset an event which was asserted
// immediately after we checked the conn status.
ResetEvent(eventHandle);
// 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.
for (int i = 0; i < listeners.size(); ) {
HANDLE handle = listeners[i].handle;
if (listeners[i].connected
|| GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE))
{
listeners.removeAt(i);
// 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.
for (int i = 0; i < listeners.size(); ) {
HANDLE handle = listeners[i].handle;
if (listeners[i].connected
|| GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE))
{
listeners.removeAt(i);
addListener();
addListener();
if (pendingConnections.size() > maxPendingConnections)
connectionEventNotifier->setEnabled(false);
if (pendingConnections.size() > maxPendingConnections)
connectionEventNotifier->setEnabled(false);
else
tryAgain = true;
// Make this the last thing so connected slots can wreak the least havoc
q->incomingConnection((quintptr)handle);
} else {
if (GetLastError() != ERROR_IO_INCOMPLETE) {
q->close();
setError(QLatin1String("QLocalServerPrivate::_q_onNewConnection"));
return;
// Make this the last thing so connected slots can wreak the least havoc
q->incomingConnection((quintptr)handle);
} else {
if (GetLastError() != ERROR_IO_INCOMPLETE) {
q->close();
setError(QLatin1String("QLocalServerPrivate::_q_onNewConnection"));
return;
}
++i;
}
++i;
}
}
} while (tryAgain);
}
void QLocalServerPrivate::closeServer()

View File

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

View File

@ -399,6 +399,10 @@ bool QSslSocketBackendPrivate::initSslContext()
if (!ace.isEmpty()
&& !QHostAddress().setAddress(tlsHostName)
&& !(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()))
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
if (!ciph.name().toLower().startsWith(QLatin1String("adh")) &&
!ciph.name().toLower().startsWith(QLatin1String("exp-adh")) &&
!ciph.name().toLower().startsWith(QLatin1String("aecdh")))
!ciph.name().toLower().startsWith(QLatin1String("aecdh"))) {
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();
if (url.scheme().isEmpty())
url.setScheme(QLatin1String("file"));
if (url.scheme().toLower() == QLatin1String("file")) {
if (url.scheme() == QLatin1String("file")) {
if (url.host().isEmpty())
url.setHost(QLatin1String("localhost"));
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();
if (url.scheme().isEmpty())
url.setScheme(QLatin1String("file"));
if (url.scheme().toLower() == QLatin1String("file")) {
if (url.scheme() == QLatin1String("file")) {
if (url.host().isEmpty())
url.setHost(QLatin1String("localhost"));
url.setPath(url.path().normalized(QString::NormalizationForm_D));

View File

@ -57,7 +57,11 @@ public:
QPaintDevice *paintDevice() 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;
#else
QImage toImage() const; // No QPlatformBackingStore::toImage() for NO_OPENGL builds.
#endif
void resize (const QSize &size, const QRegion &) Q_DECL_OVERRIDE;
bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
void beginPaint(const QRegion &region) Q_DECL_OVERRIDE;

View File

@ -428,14 +428,18 @@ void QCocoaIntegration::updateScreens()
}
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.
foreach (QCocoaScreen* screen, remainingScreens) {
mScreens.removeOne(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)

View File

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

View File

@ -102,6 +102,28 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
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
{
@ -234,20 +256,16 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate);
QT_BEGIN_NAMESPACE
QCocoaMenu::QCocoaMenu() :
m_attachedItem(0),
m_enabled(true),
m_visible(true),
m_tag(0),
m_menuBar(0),
m_containingMenuItem(0)
m_tag(0)
{
QMacAutoReleasePool pool;
m_delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this];
m_nativeItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
m_nativeMenu = [[NSMenu alloc] initWithTitle:@"Untitled"];
[m_nativeMenu setAutoenablesItems:YES];
m_nativeMenu.delegate = (QCocoaMenuDelegate *) m_delegate;
[m_nativeItem setSubmenu:m_nativeMenu];
m_nativeMenu.delegate = [[QCocoaMenuDelegate alloc] initWithMenu:this];
}
QCocoaMenu::~QCocoaMenu()
@ -257,14 +275,11 @@ QCocoaMenu::~QCocoaMenu()
SET_COCOA_MENU_ANCESTOR(item, 0);
}
if (m_containingMenuItem)
m_containingMenuItem->clearMenu(this);
QMacAutoReleasePool pool;
[m_nativeItem setSubmenu:nil];
NSObject *delegate = m_nativeMenu.delegate;
m_nativeMenu.delegate = nil;
[delegate release];
[m_nativeMenu release];
[m_delegate release];
[m_nativeItem release];
}
void QCocoaMenu::setText(const QString &text)
@ -272,7 +287,6 @@ void QCocoaMenu::setText(const QString &text)
QMacAutoReleasePool pool;
QString stripped = qt_mac_removeAmpersandEscapes(text);
[m_nativeMenu setTitle:QCFString::toNSString(stripped)];
[m_nativeItem setTitle:QCFString::toNSString(stripped)];
}
void QCocoaMenu::setMinimumWidth(int width)
@ -313,17 +327,13 @@ void QCocoaMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *
void QCocoaMenu::insertNative(QCocoaMenuItem *item, QCocoaMenuItem *beforeItem)
{
[item->nsItem() setTarget:m_delegate];
item->nsItem().target = m_nativeMenu.delegate;
if (!item->menu())
[item->nsItem() setAction:@selector(itemFired:)];
if (item->isMerged())
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
// we find a non-merged real item to insert ahead of.
while (beforeItem && beforeItem->isMerged()) {
@ -451,12 +461,11 @@ void QCocoaMenu::setEnabled(bool enabled)
bool QCocoaMenu::isEnabled() const
{
return [m_nativeItem isEnabled];
return m_attachedItem ? [m_attachedItem isEnabled] : m_enabled;
}
void QCocoaMenu::setVisible(bool visible)
{
[m_nativeItem setSubmenu:(visible ? m_nativeMenu : nil)];
m_visible = visible;
}
@ -593,8 +602,6 @@ void QCocoaMenu::syncModalState(bool modal)
if (!m_enabled)
modal = true;
[m_nativeItem setEnabled:!modal];
foreach (QCocoaMenuItem *item, m_menuItems) {
if (item->menu()) { // recurse into submenus
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;
SET_COCOA_MENU_ANCESTOR(this, menuBar);
if (item == m_attachedItem)
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;
}
void QCocoaMenu::setContainingMenuItem(QCocoaMenuItem *menuItem)
{
m_containingMenuItem = menuItem;
}
QCocoaMenuItem *QCocoaMenu::containingMenuItem() const
{
return m_containingMenuItem;
return m_attachedItem;
}
QT_END_NAMESPACE

View File

@ -77,10 +77,10 @@ private:
static QCocoaMenuBar *findGlobalMenubar();
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;
QCocoaWindow *m_window;
};

View File

@ -57,7 +57,6 @@ static inline QCocoaMenuLoader *getMenuLoader()
return [NSApp QT_MANGLE_NAMESPACE(qt_qcocoamenuLoader)];
}
QCocoaMenuBar::QCocoaMenuBar() :
m_window(0)
{
@ -74,11 +73,20 @@ QCocoaMenuBar::~QCocoaMenuBar()
#ifdef QT_COCOA_ENABLE_MENU_DEBUG
qDebug() << "~QCocoaMenuBar" << this;
#endif
foreach (QCocoaMenu *menu, m_menus) {
if (!menu)
continue;
NSMenuItem *item = nativeItemForMenu(menu);
if (menu->attachedItem() == item)
menu->setAttachedItem(nil);
}
[m_nativeMenu release];
static_menubars.removeOne(this);
if (m_window && m_window->menubar() == this) {
m_window->setMenubar(0);
// Delete the children first so they do not cause
// the native menu items to be hidden after
// 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)
{
QCocoaMenu *menu = static_cast<QCocoaMenu *>(platformMenu);
@ -113,33 +103,42 @@ void QCocoaMenuBar::insertMenu(QPlatformMenu *platformMenu, QPlatformMenu *befor
qDebug() << "QCocoaMenuBar" << this << "insertMenu" << menu << "before" << before;
#endif
if (m_menus.contains(menu)) {
if (m_menus.contains(QPointer<QCocoaMenu>(menu))) {
qWarning("This menu already belongs to the menubar, remove it first");
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");
return;
}
m_menus.insert(beforeMenu ? m_menus.indexOf(beforeMenu) : m_menus.size(), menu);
if (!menu->menuBar())
insertNativeMenu(menu, beforeMenu);
int insertionIndex = beforeMenu ? m_menus.indexOf(beforeMenu) : m_menus.size();
m_menus.insert(insertionIndex, menu);
{
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())
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)
{
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");
return;
}
NSMenuItem *item = nativeItemForMenu(menu);
if (menu->attachedItem() == item)
menu->setAttachedItem(nil);
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)
@ -170,7 +178,16 @@ void QCocoaMenuBar::syncMenu(QPlatformMenu *menu)
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)
@ -297,24 +314,16 @@ void QCocoaMenuBar::updateMenuBarImmediately()
qDebug() << "QCocoaMenuBar" << "updateMenuBarImmediately" << cw;
#endif
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.
// We browse the list in reverse order to be sure that the next items are redrawn before the current ones,
// in this way we are sure that "beforeMenu" (see below) is part of the native menu before "m" is redraw
for (int i = mb->m_menus.size() - 1; i >= 0; i--) {
QCocoaMenu *m = mb->m_menus.at(i);
QCocoaMenuBar *menuBar = m->menuBar();
if (menuBar != mb) {
QCocoaMenu *beforeMenu = i < (mb->m_menus.size() - 1) ? mb->m_menus.at(i + 1) : 0;
if (menuBar)
menuBar->removeNativeMenu(m);
mb->insertNativeMenu(m, beforeMenu);
}
foreach (QCocoaMenu *menu, mb->m_menus) {
if (!menu)
continue;
NSMenuItem *item = mb->nativeItemForMenu(menu);
menu->setAttachedItem(item);
SET_COCOA_MENU_ANCESTOR(menu, mb);
// force a sync?
mb->syncMenu(menu);
menu->syncModalState(disableForModal);
}
QCocoaMenuLoader *loader = getMenuLoader();

View File

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

View File

@ -142,15 +142,12 @@ void QCocoaMenuItem::setMenu(QPlatformMenu *menu)
if (m_menu) {
if (COCOA_MENU_ANCESTOR(m_menu) == this)
SET_COCOA_MENU_ANCESTOR(m_menu, 0);
if (m_menu->containingMenuItem() == this)
m_menu->setContainingMenuItem(0);
}
QMacAutoReleasePool pool;
m_menu = static_cast<QCocoaMenu *>(menu);
if (m_menu) {
SET_COCOA_MENU_ANCESTOR(m_menu, this);
m_menu->setContainingMenuItem(this);
} else {
// we previously had a menu, but no longer
// 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)
{
m_isVisible = isVisible;
@ -226,14 +217,6 @@ NSMenuItem *QCocoaMenuItem::sync()
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) {
NSMenuItem *mergeItem = nil;
QCocoaMenuLoader *loader = getMenuLoader();

View File

@ -414,6 +414,7 @@ QCocoaWindow::~QCocoaWindow()
#endif
QMacAutoReleasePool pool;
[m_nsWindow makeFirstResponder:nil];
[m_nsWindow setContentView:nil];
[m_nsWindow.helper detachFromPlatformWindow];
if (m_isNSWindowChild) {
@ -1004,7 +1005,15 @@ void QCocoaWindow::raise()
[parentNSWindow removeChildWindow:m_nsWindow];
[parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
} 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");
if (raiseProcess) {
ProcessSerialNumber psn;

View File

@ -1253,7 +1253,12 @@ QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const
{
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)
return result;

View File

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

View File

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

View File

@ -429,6 +429,7 @@ void QXcbDrag::move(const QPoint &globalPos)
xcb_client_message_event_t enter;
enter.response_type = XCB_CLIENT_MESSAGE;
enter.sequence = 0;
enter.window = target;
enter.format = 32;
enter.type = atom(QXcbAtom::XdndEnter);
@ -457,6 +458,7 @@ void QXcbDrag::move(const QPoint &globalPos)
xcb_client_message_event_t move;
move.response_type = XCB_CLIENT_MESSAGE;
move.sequence = 0;
move.window = target;
move.format = 32;
move.type = atom(QXcbAtom::XdndPosition);
@ -485,6 +487,7 @@ void QXcbDrag::drop(const QPoint &globalPos)
xcb_client_message_event_t drop;
drop.response_type = XCB_CLIENT_MESSAGE;
drop.sequence = 0;
drop.window = current_target;
drop.format = 32;
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;
response.response_type = XCB_CLIENT_MESSAGE;
response.sequence = 0;
response.window = xdnd_dragsource;
response.format = 32;
response.type = atom(QXcbAtom::XdndStatus);
@ -892,6 +896,7 @@ void QXcbDrag::send_leave()
xcb_client_message_event_t leave;
leave.response_type = XCB_CLIENT_MESSAGE;
leave.sequence = 0;
leave.window = current_target;
leave.format = 32;
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;
finished.response_type = XCB_CLIENT_MESSAGE;
finished.sequence = 0;
finished.window = xdnd_dragsource;
finished.format = 32;
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.format = 8;
ev.type = connection()->atom(QXcbAtom::_NET_STARTUP_INFO_BEGIN);
ev.sequence = 0;
ev.window = rootWindow;
int sent = 0;
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
{
xcb_client_message_event_t trayRequest;
memset(&trayRequest, 0, sizeof(trayRequest));
trayRequest.response_type = XCB_CLIENT_MESSAGE;
trayRequest.format = 32;
trayRequest.sequence = 0;
trayRequest.window = m_trayWindow;
trayRequest.type = m_trayAtom;
trayRequest.data.data32[0] = XCB_CURRENT_TIME;

View File

@ -1111,21 +1111,37 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
void QXcbWindow::setNetWmStates(NetWmStates states)
{
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));
if (states & NetWmStateBelow)
if (states & NetWmStateBelow && !atoms.contains(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));
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));
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));
if (states & NetWmStateModal)
if (states & NetWmStateModal && !atoms.contains(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));
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));
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.format = 32;
event.sequence = 0;
event.window = m_window;
event.type = atom(QXcbAtom::_NET_WM_STATE);
event.data.data32[0] = set ? 1 : 0;
@ -1286,6 +1303,7 @@ void QXcbWindow::setWindowState(Qt::WindowState state)
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
event.sequence = 0;
event.window = m_window;
event.type = atom(QXcbAtom::WM_CHANGE_STATE);
event.data.data32[0] = XCB_WM_STATE_ICONIC;
@ -1690,6 +1708,7 @@ void QXcbWindow::requestActivateWindow()
event.response_type = XCB_CLIENT_MESSAGE;
event.format = 32;
event.sequence = 0;
event.window = m_window;
event.type = atom(QXcbAtom::_NET_ACTIVE_WINDOW);
event.data.data32[0] = 1;
@ -2636,6 +2655,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner)
xcb_client_message_event_t xev;
xev.response_type = XCB_CLIENT_MESSAGE;
xev.type = moveResize;
xev.sequence = 0;
xev.window = xcb_window();
xev.format = 32;
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.format = 32;
event.sequence = 0;
event.window = window;
event.type = atom(QXcbAtom::_XEMBED);
event.data.data32[0] = connection()->time();

View File

@ -44,6 +44,9 @@
#include <QtCore/qvector.h>
#include <QtSql/qsql.h>
// for testing:
class tst_QSqlQuery;
QT_BEGIN_NAMESPACE
@ -60,6 +63,8 @@ class Q_SQL_EXPORT QSqlResult
Q_DECLARE_PRIVATE(QSqlResult)
friend class QSqlQuery;
friend class QSqlTableModelPrivate;
// for testing:
friend class ::tst_QSqlQuery;
public:
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
#include "moc_qerrormessage.cpp"
#endif // QT_NO_ERRORMESSAGE

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4401,7 +4401,20 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes,
QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r);
if (paintPairs.isEmpty())
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);
QPainter painter(&pixmap);
QStyleOptionViewItem option = viewOptionsV1();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1692,3 +1692,5 @@ void QGridLayout::invalidate()
}
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
#include "moc_qlayout.cpp"

View File

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

View File

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

View File

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

View File

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

View File

@ -1892,7 +1892,6 @@ void QWidgetPrivate::deleteTLSysExtra()
if (extra->topextra->window) {
extra->topextra->window->destroy();
}
setWinId(0);
delete extra->topextra->window;
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())
hide_sys();
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);
needsShow = true;
}

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