Merge remote-tracking branch 'origin/5.11' into dev

Conflicts:
	src/plugins/platforms/cocoa/qcocoawindow.mm
	src/plugins/platforms/xcb/qxcbintegration.cpp

 Conflicts git missed:
	src/plugins/platforms/qnx/qqnxglcontext.cpp

Change-Id: I0582cdc9e66e43efe79038b9c43d4f9572ac88fc
This commit is contained in:
Qt Forward Merge Bot 2018-07-17 01:00:21 +02:00 committed by Edward Welbourne
commit 1783fca897
66 changed files with 6078 additions and 3718 deletions

View File

@ -206,7 +206,7 @@
"testTypeDependencies": { "testTypeDependencies": {
"linkerSupportsFlag": [ "use_gold_linker" ], "linkerSupportsFlag": [ "use_gold_linker" ],
"verifySpec": [ "shared", "use_gold_linker", "compiler-flags", "gcc-sysroot", "qmakeargs", "commit" ], "verifySpec": [ "shared", "use_gold_linker", "compiler-flags", "qmakeargs", "commit" ],
"compile": [ "verifyspec" ], "compile": [ "verifyspec" ],
"detectPkgConfig": [ "cross_compile", "machineTuple" ], "detectPkgConfig": [ "cross_compile", "machineTuple" ],
"library": [ "pkg-config" ], "library": [ "pkg-config" ],
@ -554,6 +554,7 @@
"features": { "features": {
"prepare": { "prepare": {
"condition": "features.gcc-sysroot || true",
"output": [ "prepareSpec", "prepareOptions", "preparePaths", "reloadSpec" ] "output": [ "prepareSpec", "prepareOptions", "preparePaths", "reloadSpec" ]
}, },
"machineTuple": { "machineTuple": {

View File

@ -1074,6 +1074,10 @@ defineTest(qtConfOutput_gccSysroot) {
"\"QMAKE_LFLAGS += --sysroot=$$config.input.sysroot\"" "\"QMAKE_LFLAGS += --sysroot=$$config.input.sysroot\""
export(EXTRA_QMAKE_ARGS) export(EXTRA_QMAKE_ARGS)
# This one is for qtConfToolchainSupportsFlag().
QMAKE_CXXFLAGS += --sysroot=$$config.input.sysroot
export(QMAKE_CXXFLAGS)
output = \ output = \
"!host_build {" \ "!host_build {" \
" QMAKE_CFLAGS += --sysroot=\$\$[QT_SYSROOT]" \ " QMAKE_CFLAGS += --sysroot=\$\$[QT_SYSROOT]" \

View File

@ -221,7 +221,7 @@ Cpp.ignoredirectives += \
# Qt 6: Remove # Qt 6: Remove
falsehoods += \ falsehoods += \
"QT_VERSION >= QT_VERSION_CHECK\\(6,0,0\\)" "QT_VERSION >= QT_VERSION_CHECK\\(\\s*6\\s*,\\s*0\\s*,\\s*0\\s*\\)"
excludefiles += \ excludefiles += \

View File

@ -344,7 +344,7 @@ defineReplace(qtConfToolchainSupportsFlag) {
conftest = "int main() { return 0; }" conftest = "int main() { return 0; }"
write_file("$$test_out_dir/conftest.cpp", conftest)|error() write_file("$$test_out_dir/conftest.cpp", conftest)|error()
qtRunLoggedCommand("$$test_cmd_base $$QMAKE_CXX $${1} -o conftest-out conftest.cpp"): \ qtRunLoggedCommand("$$test_cmd_base $$QMAKE_CXX $$QMAKE_CXXFLAGS $${1} -o conftest-out conftest.cpp"): \
return(true) return(true)
return(false) return(false)
} }

View File

@ -149,13 +149,13 @@ ProjectBuilderMakefileGenerator::writeSubDirs(QTextStream &t)
if(!qmake_setpwd(dir)) if(!qmake_setpwd(dir))
fprintf(stderr, "Cannot find directory: %s\n", dir.toLatin1().constData()); fprintf(stderr, "Cannot find directory: %s\n", dir.toLatin1().constData());
} }
Option::output_dir = Option::globals->shadowedPath(QDir::cleanPath(fi.absoluteFilePath())); Option::output_dir = Option::globals->shadowedPath(qmake_getpwd());
if(tmp_proj.read(fn)) { if(tmp_proj.read(fn)) {
if(tmp_proj.first("TEMPLATE") == "subdirs") { if(tmp_proj.first("TEMPLATE") == "subdirs") {
QMakeProject *pp = new QMakeProject(&tmp_proj); QMakeProject *pp = new QMakeProject(&tmp_proj);
pb_subdirs += new ProjectBuilderSubDirs(pp, dir); pb_subdirs += new ProjectBuilderSubDirs(pp, dir);
} else if(tmp_proj.first("TEMPLATE") == "app" || tmp_proj.first("TEMPLATE") == "lib") { } else if(tmp_proj.first("TEMPLATE") == "app" || tmp_proj.first("TEMPLATE") == "lib") {
QString pbxproj = qmake_getpwd() + Option::dir_sep + tmp_proj.first("TARGET") + projectSuffix(); QString pbxproj = Option::output_dir + Option::dir_sep + tmp_proj.first("TARGET") + projectSuffix();
if(!exists(pbxproj)) { if(!exists(pbxproj)) {
warn_msg(WarnLogic, "Ignored (not found) '%s'", pbxproj.toLatin1().constData()); warn_msg(WarnLogic, "Ignored (not found) '%s'", pbxproj.toLatin1().constData());
goto nextfile; // # Dirty! goto nextfile; // # Dirty!
@ -875,7 +875,9 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t)
name.chop(librarySuffix.length()); name.chop(librarySuffix.length());
} }
} else { } else {
library.replace(name, name + suffixSetting); int pos = library.lastIndexOf(name);
if (pos != -1)
library.insert(pos + name.length(), suffixSetting);
} }
} }
} }

View File

@ -599,7 +599,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
<< var("QMAKE_LINK_SHLIB_CMD"); << var("QMAKE_LINK_SHLIB_CMD");
if(!destdir.isEmpty()) if(!destdir.isEmpty())
t << "\n\t" t << "\n\t"
<< "-$(MOVE) $(TARGET) " << destdir << " "; << "-$(MOVE) $(TARGET) " << destdir << "$(TARGET)";
if(!project->isEmpty("QMAKE_POST_LINK")) if(!project->isEmpty("QMAKE_POST_LINK"))
t << "\n\t" << var("QMAKE_POST_LINK"); t << "\n\t" << var("QMAKE_POST_LINK");
t << endl << endl; t << endl << endl;
@ -636,16 +636,16 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
if (!destdir.isEmpty()) { if (!destdir.isEmpty()) {
t << "\n\t" t << "\n\t"
<< "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t" << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t"
<< "-$(MOVE) $(TARGET) " << destdir << " "; << "-$(MOVE) $(TARGET) " << destdir << "$(TARGET)";
if (!project->isActiveConfig("unversioned_libname")) { if (!project->isActiveConfig("unversioned_libname")) {
t << "\n\t" t << "\n\t"
<< "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t" << "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t"
<< "-$(DEL_FILE) " << destdir << "$(TARGET1)\n\t" << "-$(DEL_FILE) " << destdir << "$(TARGET1)\n\t"
<< "-$(DEL_FILE) " << destdir << "$(TARGET2)\n\t" << "-$(DEL_FILE) " << destdir << "$(TARGET2)\n\t"
<< "-$(MOVE) $(TARGET0) " << destdir << " \n\t" << "-$(MOVE) $(TARGET0) " << destdir << "$(TARGET0)\n\t"
<< "-$(MOVE) $(TARGET1) " << destdir << " \n\t" << "-$(MOVE) $(TARGET1) " << destdir << "$(TARGET1)\n\t"
<< "-$(MOVE) $(TARGET2) " << destdir << " "; << "-$(MOVE) $(TARGET2) " << destdir << "$(TARGET2)";
} }
} }
if(!project->isEmpty("QMAKE_POST_LINK")) if(!project->isEmpty("QMAKE_POST_LINK"))
@ -660,8 +660,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\n\t" t << "\n\t"
<< "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t" << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t"
<< "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t" << "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t"
<< "-$(MOVE) $(TARGET) " << destdir << " \n\t" << "-$(MOVE) $(TARGET) " << destdir << "$(TARGET)\n\t"
<< "-$(MOVE) $(TARGET0) " << destdir << " \n\t"; << "-$(MOVE) $(TARGET0) " << destdir << "$(TARGET0)\n\t";
if(!project->isEmpty("QMAKE_POST_LINK")) if(!project->isEmpty("QMAKE_POST_LINK"))
t << "\n\t" << var("QMAKE_POST_LINK"); t << "\n\t" << var("QMAKE_POST_LINK");
t << endl << endl; t << endl << endl;

View File

@ -7,11 +7,9 @@
"License": "MIT License", "License": "MIT License",
"LicenseId": "MIT", "LicenseId": "MIT",
"LicenseFile": "COPYING", "LicenseFile": "COPYING",
"Copyright": "Copyright (c) 1992, 1993 "Copyright": "Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies)
The Regents of the University of California. All rights reserved. Copyright © 2006 Behdad Esfahbod
Copyright © 2005 David Turner
Copyright (c) 2011 The FreeBSD Foundation Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc.
All rights reserved. Copyright © 1998-2004 David Turner and Werner Lemberg"
Portions of this software were developed by David Chisnall
under sponsorship from the FreeBSD Foundation."
} }

View File

@ -5,8 +5,9 @@
"QtUsage": "Used in Qt SQL Lite plugin. Configure Qt with -system-sqlite or -no-sqlite to avoid.", "QtUsage": "Used in Qt SQL Lite plugin. Configure Qt with -system-sqlite or -no-sqlite to avoid.",
"Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.", "Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.",
"Homepage": "http://www.sqlite.org/", "Homepage": "https://www.sqlite.org/",
"Version": "3.23.1", "Version": "3.24.0",
"DownloadLocation": "https://www.sqlite.org/2018/sqlite-amalgamation-3240000.zip",
"License": "Public Domain", "License": "Public Domain",
"Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed." "Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed."
} }

File diff suppressed because it is too large Load Diff

View File

@ -123,9 +123,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()]. ** [sqlite_version()] and [sqlite_source_id()].
*/ */
#define SQLITE_VERSION "3.23.1" #define SQLITE_VERSION "3.24.0"
#define SQLITE_VERSION_NUMBER 3023001 #define SQLITE_VERSION_NUMBER 3024000
#define SQLITE_SOURCE_ID "2018-04-10 17:39:29 4bb2294022060e61de7da5c227a69ccd846ba330e31626ebcd59a94efd148b3b" #define SQLITE_SOURCE_ID "2018-06-04 19:24:41 c7ee0833225bfd8c5ec2f9bf62b97c4e04d03bd9566366d5221ac8fb199a87ca"
/* /*
** CAPI3REF: Run-Time Library Version Numbers ** CAPI3REF: Run-Time Library Version Numbers
@ -504,6 +504,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8))
#define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8))
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8))
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
@ -511,6 +512,7 @@ SQLITE_API int sqlite3_exec(
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
@ -1930,6 +1932,22 @@ struct sqlite3_mem_methods {
** I/O required to support statement rollback. ** I/O required to support statement rollback.
** The default value for this setting is controlled by the ** The default value for this setting is controlled by the
** [SQLITE_STMTJRNL_SPILL] compile-time option. ** [SQLITE_STMTJRNL_SPILL] compile-time option.
**
** [[SQLITE_CONFIG_SORTERREF_SIZE]]
** <dt>SQLITE_CONFIG_SORTERREF_SIZE
** <dd>The SQLITE_CONFIG_SORTERREF_SIZE option accepts a single parameter
** of type (int) - the new value of the sorter-reference size threshold.
** Usually, when SQLite uses an external sort to order records according
** to an ORDER BY clause, all fields required by the caller are present in the
** sorted records. However, if SQLite determines based on the declared type
** of a table column that its values are likely to be very large - larger
** than the configured sorter-reference size threshold - then a reference
** is stored in each sorted record and the required column values loaded
** from the database as records are returned in sorted order. The default
** value for this option is to never use this optimization. Specifying a
** negative value for this option restores the default behaviour.
** This option is only available if SQLite is compiled with the
** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option.
** </dl> ** </dl>
*/ */
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
@ -1959,6 +1977,7 @@ struct sqlite3_mem_methods {
#define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */
#define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */ #define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */
#define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ #define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */
#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */
/* /*
** CAPI3REF: Database Connection Configuration Options ** CAPI3REF: Database Connection Configuration Options
@ -2095,6 +2114,21 @@ struct sqlite3_mem_methods {
** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if ** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if
** it is not disabled, 1 if it is. ** it is not disabled, 1 if it is.
** </dd> ** </dd>
**
** <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>
** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run
** [VACUUM] in order to reset a database back to an empty database
** with no schema and no content. The following process works even for
** a badly corrupted database file:
** <ol>
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
** </ol>
** Because resetting a database is destructive and irreversible, the
** process requires the use of this obscure API and multiple steps to help
** ensure that it does not happen by accident.
** </dd>
** </dl> ** </dl>
*/ */
#define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */
@ -2106,7 +2140,8 @@ struct sqlite3_mem_methods {
#define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */ #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */
#define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */ #define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */
#define SQLITE_DBCONFIG_MAX 1008 /* Largest DBCONFIG */ #define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */
#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */
/* /*
** CAPI3REF: Enable Or Disable Extended Result Codes ** CAPI3REF: Enable Or Disable Extended Result Codes
@ -5492,6 +5527,41 @@ SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory;
*/ */
SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory; SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
/*
** CAPI3REF: Win32 Specific Interface
**
** These interfaces are available only on Windows. The
** [sqlite3_win32_set_directory] interface is used to set the value associated
** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to
** zValue, depending on the value of the type parameter. The zValue parameter
** should be NULL to cause the previous value to be freed via [sqlite3_free];
** a non-NULL value will be copied into memory obtained from [sqlite3_malloc]
** prior to being used. The [sqlite3_win32_set_directory] interface returns
** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported,
** or [SQLITE_NOMEM] if memory could not be allocated. The value of the
** [sqlite3_data_directory] variable is intended to act as a replacement for
** the current directory on the sub-platforms of Win32 where that concept is
** not present, e.g. WinRT and UWP. The [sqlite3_win32_set_directory8] and
** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the
** sqlite3_win32_set_directory interface except the string parameter must be
** UTF-8 or UTF-16, respectively.
*/
SQLITE_API int sqlite3_win32_set_directory(
unsigned long type, /* Identifier for directory being set or reset */
void *zValue /* New value for directory being set or reset */
);
SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue);
SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue);
/*
** CAPI3REF: Win32 Directory Types
**
** These macros are only available on Windows. They define the allowed values
** for the type argument to the [sqlite3_win32_set_directory] interface.
*/
#define SQLITE_WIN32_DATA_DIRECTORY_TYPE 1
#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE 2
/* /*
** CAPI3REF: Test For Auto-Commit Mode ** CAPI3REF: Test For Auto-Commit Mode
** KEYWORDS: {autocommit mode} ** KEYWORDS: {autocommit mode}
@ -6224,6 +6294,10 @@ struct sqlite3_index_info {
/* /*
** CAPI3REF: Virtual Table Scan Flags ** CAPI3REF: Virtual Table Scan Flags
**
** Virtual table implementations are allowed to set the
** [sqlite3_index_info].idxFlags field to some combination of
** these bits.
*/ */
#define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ #define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */
@ -6999,7 +7073,7 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_ALWAYS 13
#define SQLITE_TESTCTRL_RESERVE 14 #define SQLITE_TESTCTRL_RESERVE 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
@ -7013,6 +7087,189 @@ SQLITE_API int sqlite3_test_control(int op, ...);
#define SQLITE_TESTCTRL_PARSER_COVERAGE 26 #define SQLITE_TESTCTRL_PARSER_COVERAGE 26
#define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */ #define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */
/*
** CAPI3REF: SQL Keyword Checking
**
** These routines provide access to the set of SQL language keywords
** recognized by SQLite. Applications can uses these routines to determine
** whether or not a specific identifier needs to be escaped (for example,
** by enclosing in double-quotes) so as not to confuse the parser.
**
** The sqlite3_keyword_count() interface returns the number of distinct
** keywords understood by SQLite.
**
** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and
** makes *Z point to that keyword expressed as UTF8 and writes the number
** of bytes in the keyword into *L. The string that *Z points to is not
** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns
** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z
** or L are NULL or invalid pointers then calls to
** sqlite3_keyword_name(N,Z,L) result in undefined behavior.
**
** The sqlite3_keyword_check(Z,L) interface checks to see whether or not
** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero
** if it is and zero if not.
**
** The parser used by SQLite is forgiving. It is often possible to use
** a keyword as an identifier as long as such use does not result in a
** parsing ambiguity. For example, the statement
** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and
** creates a new table named "BEGIN" with three columns named
** "REPLACE", "PRAGMA", and "END". Nevertheless, best practice is to avoid
** using keywords as identifiers. Common techniques used to avoid keyword
** name collisions include:
** <ul>
** <li> Put all identifier names inside double-quotes. This is the official
** SQL way to escape identifier names.
** <li> Put identifier names inside &#91;...&#93;. This is not standard SQL,
** but it is what SQL Server does and so lots of programmers use this
** technique.
** <li> Begin every identifier with the letter "Z" as no SQL keywords start
** with "Z".
** <li> Include a digit somewhere in every identifier name.
** </ul>
**
** Note that the number of keywords understood by SQLite can depend on
** compile-time options. For example, "VACUUM" is not a keyword if
** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option. Also,
** new keywords may be added to future releases of SQLite.
*/
SQLITE_API int sqlite3_keyword_count(void);
SQLITE_API int sqlite3_keyword_name(int,const char**,int*);
SQLITE_API int sqlite3_keyword_check(const char*,int);
/*
** CAPI3REF: Dynamic String Object
** KEYWORDS: {dynamic string}
**
** An instance of the sqlite3_str object contains a dynamically-sized
** string under construction.
**
** The lifecycle of an sqlite3_str object is as follows:
** <ol>
** <li> ^The sqlite3_str object is created using [sqlite3_str_new()].
** <li> ^Text is appended to the sqlite3_str object using various
** methods, such as [sqlite3_str_appendf()].
** <li> ^The sqlite3_str object is destroyed and the string it created
** is returned using the [sqlite3_str_finish()] interface.
** </ol>
*/
typedef struct sqlite3_str sqlite3_str;
/*
** CAPI3REF: Create A New Dynamic String Object
** CONSTRUCTOR: sqlite3_str
**
** ^The [sqlite3_str_new(D)] interface allocates and initializes
** a new [sqlite3_str] object. To avoid memory leaks, the object returned by
** [sqlite3_str_new()] must be freed by a subsequent call to
** [sqlite3_str_finish(X)].
**
** ^The [sqlite3_str_new(D)] interface always returns a pointer to a
** valid [sqlite3_str] object, though in the event of an out-of-memory
** error the returned object might be a special singleton that will
** silently reject new text, always return SQLITE_NOMEM from
** [sqlite3_str_errcode()], always return 0 for
** [sqlite3_str_length()], and always return NULL from
** [sqlite3_str_finish(X)]. It is always safe to use the value
** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter
** to any of the other [sqlite3_str] methods.
**
** The D parameter to [sqlite3_str_new(D)] may be NULL. If the
** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum
** length of the string contained in the [sqlite3_str] object will be
** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead
** of [SQLITE_MAX_LENGTH].
*/
SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*);
/*
** CAPI3REF: Finalize A Dynamic String
** DESTRUCTOR: sqlite3_str
**
** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X
** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()]
** that contains the constructed string. The calling application should
** pass the returned value to [sqlite3_free()] to avoid a memory leak.
** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any
** errors were encountered during construction of the string. ^The
** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the
** string in [sqlite3_str] object X is zero bytes long.
*/
SQLITE_API char *sqlite3_str_finish(sqlite3_str*);
/*
** CAPI3REF: Add Content To A Dynamic String
** METHOD: sqlite3_str
**
** These interfaces add content to an sqlite3_str object previously obtained
** from [sqlite3_str_new()].
**
** ^The [sqlite3_str_appendf(X,F,...)] and
** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]
** functionality of SQLite to append formatted text onto the end of
** [sqlite3_str] object X.
**
** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S
** onto the end of the [sqlite3_str] object X. N must be non-negative.
** S must contain at least N non-zero bytes of content. To append a
** zero-terminated string in its entirety, use the [sqlite3_str_appendall()]
** method instead.
**
** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of
** zero-terminated string S onto the end of [sqlite3_str] object X.
**
** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the
** single-byte character C onto the end of [sqlite3_str] object X.
** ^This method can be used, for example, to add whitespace indentation.
**
** ^The [sqlite3_str_reset(X)] method resets the string under construction
** inside [sqlite3_str] object X back to zero bytes in length.
**
** These methods do not return a result code. ^If an error occurs, that fact
** is recorded in the [sqlite3_str] object and can be recovered by a
** subsequent call to [sqlite3_str_errcode(X)].
*/
SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);
SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);
SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);
SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);
SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);
SQLITE_API void sqlite3_str_reset(sqlite3_str*);
/*
** CAPI3REF: Status Of A Dynamic String
** METHOD: sqlite3_str
**
** These interfaces return the current status of an [sqlite3_str] object.
**
** ^If any prior errors have occurred while constructing the dynamic string
** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return
** an appropriate error code. ^The [sqlite3_str_errcode(X)] method returns
** [SQLITE_NOMEM] following any out-of-memory error, or
** [SQLITE_TOOBIG] if the size of the dynamic string exceeds
** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors.
**
** ^The [sqlite3_str_length(X)] method returns the current length, in bytes,
** of the dynamic string under construction in [sqlite3_str] object X.
** ^The length returned by [sqlite3_str_length(X)] does not include the
** zero-termination byte.
**
** ^The [sqlite3_str_value(X)] method returns a pointer to the current
** content of the dynamic string under construction in X. The value
** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X
** and might be freed or altered by any subsequent method on the same
** [sqlite3_str] object. Applications must not used the pointer returned
** [sqlite3_str_value(X)] after any subsequent method call on the same
** object. ^Applications may change the content of the string returned
** by [sqlite3_str_value(X)] as long as they do not write into any bytes
** outside the range of 0 to [sqlite3_str_length(X)] and do not read or
** write any byte after any subsequent sqlite3_str method call.
*/
SQLITE_API int sqlite3_str_errcode(sqlite3_str*);
SQLITE_API int sqlite3_str_length(sqlite3_str*);
SQLITE_API char *sqlite3_str_value(sqlite3_str*);
/* /*
** CAPI3REF: SQLite Runtime Status ** CAPI3REF: SQLite Runtime Status
** **
@ -8282,11 +8539,11 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
** method of a [virtual table], then it returns true if and only if the ** method of a [virtual table], then it returns true if and only if the
** column is being fetched as part of an UPDATE operation during which the ** column is being fetched as part of an UPDATE operation during which the
** column value will not change. Applications might use this to substitute ** column value will not change. Applications might use this to substitute
** a lighter-weight value to return that the corresponding [xUpdate] method ** a return value that is less expensive to compute and that the corresponding
** understands as a "no-change" value. ** [xUpdate] method understands as a "no-change" value.
** **
** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that ** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
** the column is not changed by the UPDATE statement, they the xColumn ** the column is not changed by the UPDATE statement, then the xColumn
** method can optionally return without setting a result, without calling ** method can optionally return without setting a result, without calling
** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. ** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
** In that case, [sqlite3_value_nochange(X)] will return true for the ** In that case, [sqlite3_value_nochange(X)] will return true for the
@ -8781,7 +9038,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const c
** been a prior call to [sqlite3_deserialize(D,S,...)] with the same ** been a prior call to [sqlite3_deserialize(D,S,...)] with the same
** values of D and S. ** values of D and S.
** The size of the database is written into *P even if the ** The size of the database is written into *P even if the
** SQLITE_SERIALIZE_NOCOPY bit is set but no contigious copy ** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy
** of the database exists. ** of the database exists.
** **
** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the ** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the

View File

@ -104,7 +104,7 @@ QList<QImage> images = ...;
QFuture<QImage> thumbnails = QtConcurrent::mapped(images.constBegin(), images.constEnd(), scaled); QFuture<QImage> thumbnails = QtConcurrent::mapped(images.constBegin(), images.constEnd(), scaled);
// map in-place only works on non-const iterators // Map in-place only works on non-const iterators.
QFuture<void> future = QtConcurrent::map(images.begin(), images.end(), scale); QFuture<void> future = QtConcurrent::map(images.begin(), images.end(), scale);
QFuture<QImage> collage = QtConcurrent::mappedReduced(images.constBegin(), images.constEnd(), scaled, addToCollage); QFuture<QImage> collage = QtConcurrent::mappedReduced(images.constBegin(), images.constEnd(), scaled, addToCollage);
@ -114,7 +114,7 @@ QFuture<QImage> collage = QtConcurrent::mappedReduced(images.constBegin(), image
//! [7] //! [7]
QList<QImage> images = ...; QList<QImage> images = ...;
// each call blocks until the entire operation is finished // Each call blocks until the entire operation is finished.
QList<QImage> future = QtConcurrent::blockingMapped(images, scaled); QList<QImage> future = QtConcurrent::blockingMapped(images, scaled);
QtConcurrent::blockingMap(images, scale); QtConcurrent::blockingMap(images, scale);
@ -124,29 +124,29 @@ QImage collage = QtConcurrent::blockingMappedReduced(images, scaled, addToCollag
//! [8] //! [8]
// squeeze all strings in a QStringList // Squeeze all strings in a QStringList.
QStringList strings = ...; QStringList strings = ...;
QFuture<void> squeezedStrings = QtConcurrent::map(strings, &QString::squeeze); QFuture<void> squeezedStrings = QtConcurrent::map(strings, &QString::squeeze);
// swap the rgb values of all pixels on a list of images // Swap the rgb values of all pixels on a list of images.
QList<QImage> images = ...; QList<QImage> images = ...;
QFuture<QImage> bgrImages = QtConcurrent::mapped(images, &QImage::rgbSwapped); QFuture<QImage> bgrImages = QtConcurrent::mapped(images, &QImage::rgbSwapped);
// create a set of the lengths of all strings in a list // Create a set of the lengths of all strings in a list.
QStringList strings = ...; QStringList strings = ...;
QFuture<QSet<int> > wordLengths = QtConcurrent::mappedReduced(string, &QString::length, &QSet<int>::insert); QFuture<QSet<int> > wordLengths = QtConcurrent::mappedReduced(strings, &QString::length, &QSet<int>::insert);
//! [8] //! [8]
//! [9] //! [9]
// can mix normal functions and member functions with QtConcurrent::mappedReduced() // Can mix normal functions and member functions with QtConcurrent::mappedReduced().
// compute the average length of a list of strings // Compute the average length of a list of strings.
extern void computeAverage(int &average, int length); extern void computeAverage(int &average, int length);
QStringList strings = ...; QStringList strings = ...;
QFuture<int> averageWordLength = QtConcurrent::mappedReduced(strings, &QString::length, computeAverage); QFuture<int> averageWordLength = QtConcurrent::mappedReduced(strings, &QString::length, computeAverage);
// create a set of the color distribution of all images in a list // Create a set of the color distribution of all images in a list.
extern int colorDistribution(const QImage &string); extern int colorDistribution(const QImage &string);
QList<QImage> images = ...; QList<QImage> images = ...;
QFuture<QSet<int> > totalColorDistribution = QtConcurrent::mappedReduced(images, colorDistribution, QSet<int>::insert); QFuture<QSet<int> > totalColorDistribution = QtConcurrent::mappedReduced(images, colorDistribution, QSet<int>::insert);

View File

@ -1366,7 +1366,10 @@
\value Key_Pause The Pause/Break key (\b Note: Not related to pausing media) \value Key_Pause The Pause/Break key (\b Note: Not related to pausing media)
\value Key_Print \value Key_Print
\value Key_SysReq \value Key_SysReq
\value Key_Clear \value Key_Clear Corresponds to the \b Clear key on selected Apple
keyboard models. On other systems it is commonly mapped
to the numeric keypad key \b 5, when \b {Num Lock} is
\c off.
\value Key_Home \value Key_Home
\value Key_End \value Key_End
\value Key_Left \value Key_Left

View File

@ -1113,7 +1113,6 @@ bool QFileSystemEngine::cloneFile(int srcfd, int dstfd, const QFileSystemMetaDat
QT_STATBUF statBuffer; QT_STATBUF statBuffer;
if (knownData.hasFlags(QFileSystemMetaData::PosixStatFlags) && if (knownData.hasFlags(QFileSystemMetaData::PosixStatFlags) &&
knownData.isFile()) { knownData.isFile()) {
statBuffer.st_size = knownData.size();
statBuffer.st_mode = S_IFREG; statBuffer.st_mode = S_IFREG;
} else if (knownData.hasFlags(QFileSystemMetaData::PosixStatFlags) && } else if (knownData.hasFlags(QFileSystemMetaData::PosixStatFlags) &&
knownData.isDirectory()) { knownData.isDirectory()) {
@ -1126,29 +1125,23 @@ bool QFileSystemEngine::cloneFile(int srcfd, int dstfd, const QFileSystemMetaDat
} }
#if defined(Q_OS_LINUX) #if defined(Q_OS_LINUX)
if (statBuffer.st_size == 0) {
// empty file? we're done.
return true;
}
// first, try FICLONE (only works on regular files and only on certain fs) // first, try FICLONE (only works on regular files and only on certain fs)
if (::ioctl(dstfd, FICLONE, srcfd) == 0) if (::ioctl(dstfd, FICLONE, srcfd) == 0)
return true; return true;
// Second, try sendfile (it can send to some special types too). // Second, try sendfile (it can send to some special types too).
// sendfile(2) is limited in the kernel to 2G - 4k // sendfile(2) is limited in the kernel to 2G - 4k
auto sendfileSize = [](QT_OFF_T size) { return size_t(qMin<qint64>(0x7ffff000, size)); }; const size_t SendfileSize = 0x7ffff000;
ssize_t n = ::sendfile(dstfd, srcfd, NULL, sendfileSize(statBuffer.st_size)); ssize_t n = ::sendfile(dstfd, srcfd, NULL, SendfileSize);
if (n == -1) { if (n == -1) {
// if we got an error here, give up and try at an upper layer // if we got an error here, give up and try at an upper layer
return false; return false;
} }
statBuffer.st_size -= n; while (n) {
while (statBuffer.st_size) { n = ::sendfile(dstfd, srcfd, NULL, SendfileSize);
n = ::sendfile(dstfd, srcfd, NULL, sendfileSize(statBuffer.st_size)); if (n == -1) {
if (n == 0) {
// uh oh, this is probably a real error (like ENOSPC), but we have // uh oh, this is probably a real error (like ENOSPC), but we have
// no way to notify QFile of partial success, so just erase any work // no way to notify QFile of partial success, so just erase any work
// done (hopefully we won't get any errors, because there's nothing // done (hopefully we won't get any errors, because there's nothing
@ -1158,9 +1151,6 @@ bool QFileSystemEngine::cloneFile(int srcfd, int dstfd, const QFileSystemMetaDat
n = lseek(dstfd, 0, SEEK_SET); n = lseek(dstfd, 0, SEEK_SET);
return false; return false;
} }
if (n == 0)
return true;
statBuffer.st_size -= n;
} }
return true; return true;

View File

@ -221,6 +221,8 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
All message types for this category are enabled by default. All message types for this category are enabled by default.
If \a category is \c{0}, the category name is changed to \c "default". If \a category is \c{0}, the category name is changed to \c "default".
Note that \a category must be kept valid during the lifetime of this object.
*/ */
QLoggingCategory::QLoggingCategory(const char *category) QLoggingCategory::QLoggingCategory(const char *category)
: d(0), : d(0),
@ -235,6 +237,8 @@ QLoggingCategory::QLoggingCategory(const char *category)
If \a category is \c{0}, the category name is changed to \c "default". If \a category is \c{0}, the category name is changed to \c "default".
Note that \a category must be kept valid during the lifetime of this object.
\since 5.4 \since 5.4
*/ */
QLoggingCategory::QLoggingCategory(const char *category, QtMsgType enableForLevel) QLoggingCategory::QLoggingCategory(const char *category, QtMsgType enableForLevel)

View File

@ -342,13 +342,14 @@ inline bool QStorageIterator::isValid() const
inline bool QStorageIterator::next() inline bool QStorageIterator::next()
{ {
QList<QByteArray> data; QList<QByteArray> data;
// If file is virtual, file.readLine() may succeed even when file.atEnd().
do { do {
const QByteArray line = file.readLine(); const QByteArray line = file.readLine();
if (line.isEmpty() && file.atEnd())
return false;
data = line.split(' '); data = line.split(' ');
} while (data.count() < 3 && !file.atEnd()); } while (data.count() < 4);
if (file.atEnd())
return false;
m_device = data.at(0); m_device = data.at(0);
m_rootPath = data.at(1); m_rootPath = data.at(1);
m_fileSystemType = data.at(2); m_fileSystemType = data.at(2);

View File

@ -63,7 +63,7 @@ const char *QElfParser::parseSectionHeader(const char *data, ElfSectionHeader *s
return data; return data;
} }
int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library, QLibraryPrivate *lib, long *pos, ulong *sectionlen) int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library, QLibraryPrivate *lib, qsizetype *pos, qsizetype *sectionlen)
{ {
#if defined(QELFPARSER_DEBUG) #if defined(QELFPARSER_DEBUG)
qDebug() << "QElfParser::parse " << library; qDebug() << "QElfParser::parse " << library;
@ -224,7 +224,7 @@ int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library
return Corrupt; return Corrupt;
} }
*pos = sh.offset; *pos = sh.offset;
*sectionlen = sh.size - 1; *sectionlen = sh.size;
if (shnam[1] == 'q') if (shnam[1] == 'q')
return QtMetaDataSection; return QtMetaDataSection;
} }

View File

@ -96,7 +96,7 @@ public:
} }
const char *parseSectionHeader(const char* s, ElfSectionHeader *sh); const char *parseSectionHeader(const char* s, ElfSectionHeader *sh);
int parse(const char *m_s, ulong fdlen, const QString &library, QLibraryPrivate *lib, long *pos, ulong *sectionlen); int parse(const char *m_s, ulong fdlen, const QString &library, QLibraryPrivate *lib, qsizetype *pos, qsizetype *sectionlen);
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation. ** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the QtCore module of the Qt Toolkit. ** This file is part of the QtCore module of the Qt Toolkit.
@ -186,7 +186,7 @@ QT_BEGIN_NAMESPACE
*/ */
static long qt_find_pattern(const char *s, ulong s_len, static qsizetype qt_find_pattern(const char *s, qsizetype s_len,
const char *pattern, ulong p_len) const char *pattern, ulong p_len)
{ {
/* /*
@ -201,8 +201,10 @@ static long qt_find_pattern(const char *s, ulong s_len,
because we have to skip over all the debugging symbols first because we have to skip over all the debugging symbols first
*/ */
if (! s || ! pattern || p_len > s_len) return -1; if (!s || !pattern || qsizetype(p_len) > s_len)
ulong i, hs = 0, hp = 0, delta = s_len - p_len; return -1;
size_t i, hs = 0, hp = 0, delta = s_len - p_len;
for (i = 0; i < p_len; ++i) { for (i = 0; i < p_len; ++i) {
hs += s[delta + i]; hs += s[delta + i];
@ -211,7 +213,7 @@ static long qt_find_pattern(const char *s, ulong s_len,
i = delta; i = delta;
for (;;) { for (;;) {
if (hs == hp && qstrncmp(s + i, pattern, p_len) == 0) if (hs == hp && qstrncmp(s + i, pattern, p_len) == 0)
return i; return i; // can't overflow, by construction
if (i == 0) if (i == 0)
break; break;
--i; --i;
@ -245,35 +247,27 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
return false; return false;
} }
// Files can be bigger than the virtual memory size on 32-bit systems, so
// we limit to 512 MB there. For 64-bit, we allow up to 2^40 bytes.
constexpr qint64 MaxMemoryMapSize =
Q_INT64_C(1) << (sizeof(qsizetype) > 4 ? 40 : 29);
QByteArray data; QByteArray data;
ulong fdlen = file.size(); qsizetype fdlen = qMin(file.size(), MaxMemoryMapSize);
const char *filedata = reinterpret_cast<char *>(file.map(0, fdlen)); const char *filedata = reinterpret_cast<char *>(file.map(0, fdlen));
if (filedata == 0) { if (filedata == 0) {
if (uchar *mapdata = file.map(0, 1)) { // Try reading the data into memory instead (up to 64 MB).
file.unmap(mapdata); data = file.read(64 * 1024 * 1024);
// Mapping is supported, but failed for the entire file, likely due to OOM. filedata = data.constData();
// Return false, as readAll() would cause a bad_alloc and terminate the process. fdlen = data.size();
if (lib)
lib->errorString = QLibrary::tr("Out of memory while loading plugin '%1'.").arg(library);
if (qt_debug_component()) {
qWarning("%s: %s", QFile::encodeName(library).constData(),
qPrintable(QSystemError::stdString(ENOMEM)));
}
return false;
} else {
// Try reading the data into memory instead.
data = file.readAll();
filedata = data.constData();
fdlen = data.size();
}
} }
/* /*
ELF and Mach-O binaries with GCC have .qplugin sections. ELF and Mach-O binaries with GCC have .qplugin sections.
*/ */
bool hasMetaData = false; bool hasMetaData = false;
long pos = 0; qsizetype pos = 0;
char pattern[] = "qTMETADATA "; char pattern[] = "qTMETADATA ";
pattern[0] = 'Q'; // Ensure the pattern "QTMETADATA" is not found in this library should QPluginLoader ever encounter it. pattern[0] = 'Q'; // Ensure the pattern "QTMETADATA" is not found in this library should QPluginLoader ever encounter it.
const ulong plen = qstrlen(pattern); const ulong plen = qstrlen(pattern);
@ -285,7 +279,7 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
} }
return false; return false;
} else if (r == QElfParser::QtMetaDataSection) { } else if (r == QElfParser::QtMetaDataSection) {
long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen); qsizetype rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen);
if (rel < 0) if (rel < 0)
pos = -1; pos = -1;
else else
@ -305,7 +299,7 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
} }
// even if the metadata section was not found, the Mach-O parser will // even if the metadata section was not found, the Mach-O parser will
// at least return the boundaries of the right architecture // at least return the boundaries of the right architecture
long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen); qsizetype rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen);
if (rel < 0) if (rel < 0)
pos = -1; pos = -1;
else else

View File

@ -89,7 +89,7 @@ static int ns(const QString &reason, const QString &library, QString *errorStrin
return QMachOParser::NotSuitable; return QMachOParser::NotSuitable;
} }
int QMachOParser::parse(const char *m_s, ulong fdlen, const QString &library, QString *errorString, long *pos, ulong *sectionlen) int QMachOParser::parse(const char *m_s, ulong fdlen, const QString &library, QString *errorString, qsizetype *pos, qsizetype *sectionlen)
{ {
// The minimum size of a Mach-O binary we're interested in. // The minimum size of a Mach-O binary we're interested in.
// It must have a full Mach header, at least one segment and at least one // It must have a full Mach header, at least one segment and at least one

View File

@ -67,7 +67,7 @@ class Q_AUTOTEST_EXPORT QMachOParser
{ {
public: public:
enum { QtMetaDataSection, NoQtSection, NotSuitable }; enum { QtMetaDataSection, NoQtSection, NotSuitable };
static int parse(const char *m_s, ulong fdlen, const QString &library, QString *errorString, long *pos, ulong *sectionlen); static int parse(const char *m_s, ulong fdlen, const QString &library, QString *errorString, qsizetype *pos, qsizetype *sectionlen);
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -116,6 +116,9 @@ int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) con
int QCollator::compare(const QString &s1, const QString &s2) const int QCollator::compare(const QString &s1, const QString &s2) const
{ {
if (d->dirty)
d->init();
if (d->collator) if (d->collator)
return compare(s1.constData(), s1.size(), s2.constData(), s2.size()); return compare(s1.constData(), s1.size(), s2.constData(), s2.size());
@ -124,6 +127,9 @@ int QCollator::compare(const QString &s1, const QString &s2) const
int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
{ {
if (d->dirty)
d->init();
if (d->collator) if (d->collator)
return compare(s1.constData(), s1.size(), s2.constData(), s2.size()); return compare(s1.constData(), s1.size(), s2.constData(), s2.size());

View File

@ -351,9 +351,8 @@ QT_WARNING_DISABLE_GCC("-Wfloat-equal")
Q_DECL_CONSTEXPR inline bool operator==(const QPointF &p1, const QPointF &p2) Q_DECL_CONSTEXPR inline bool operator==(const QPointF &p1, const QPointF &p2)
{ {
return ((!p1.xp && !p1.yp) || (!p2.xp && !p2.yp)) return ((!p1.xp || !p2.xp) ? qFuzzyIsNull(p1.xp - p2.xp) : qFuzzyCompare(p1.xp, p2.xp))
? (qFuzzyIsNull(p1.xp - p2.xp) && qFuzzyIsNull(p1.yp - p2.yp)) && ((!p1.yp || !p2.yp) ? qFuzzyIsNull(p1.yp - p2.yp) : qFuzzyCompare(p1.yp, p2.yp));
: (qFuzzyCompare(p1.xp, p2.xp) && qFuzzyCompare(p1.yp, p2.yp));
} }
Q_DECL_CONSTEXPR inline bool operator!=(const QPointF &p1, const QPointF &p2) Q_DECL_CONSTEXPR inline bool operator!=(const QPointF &p1, const QPointF &p2)

View File

@ -1359,7 +1359,7 @@ const QString::Null QString::null = { };
\ingroup string-processing \ingroup string-processing
QString stores a string of 16-bit \l{QChar}s, where each QChar QString stores a string of 16-bit \l{QChar}s, where each QChar
corresponds one Unicode 4.0 character. (Unicode characters corresponds to one UTF-16 code unit. (Unicode characters
with code values above 65535 are stored using surrogate pairs, with code values above 65535 are stored using surrogate pairs,
i.e., two consecutive \l{QChar}s.) i.e., two consecutive \l{QChar}s.)

View File

@ -85,10 +85,9 @@ void QAndroidTimeZonePrivate::init(const QByteArray &ianaId)
// Painfully, JNI gives us back a default zone object if it doesn't // Painfully, JNI gives us back a default zone object if it doesn't
// recognize the name; so check for whether ianaId is a recognized name of // recognize the name; so check for whether ianaId is a recognized name of
// the zone object we got and ignore the zone if not. // the zone object we got and ignore the zone if not.
bool found = false;
// Try checking ianaId against getID(), getDisplayName(): // Try checking ianaId against getID(), getDisplayName():
QJNIObjectPrivate jname = androidTimeZone.callObjectMethod("getID", "()Ljava/lang/String;"); QJNIObjectPrivate jname = androidTimeZone.callObjectMethod("getID", "()Ljava/lang/String;");
found = (jname.toString().toUtf8() == ianaId); bool found = (jname.toString().toUtf8() == ianaId);
for (int style = 1; !found && style-- > 0;) { for (int style = 1; !found && style-- > 0;) {
for (int dst = 1; !found && dst-- > 0;) { for (int dst = 1; !found && dst-- > 0;) {
jname = androidTimeZone.callObjectMethod("getDisplayName", "(ZI;)Ljava/lang/String;", jname = androidTimeZone.callObjectMethod("getDisplayName", "(ZI;)Ljava/lang/String;",

View File

@ -328,7 +328,7 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal
return; return;
} }
png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
image.setColorCount(num_palette); image.setColorCount((format == QImage::Format_Mono) ? 2 : num_palette);
int i = 0; int i = 0;
if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_alpha) { if (png_get_tRNS(png_ptr, info_ptr, &trans_alpha, &num_trans, &trans_color_p) && trans_alpha) {
while (i < num_trans) { while (i < num_trans) {

View File

@ -11,7 +11,7 @@
"License": "Freetype Project License or GNU General Public License v2.0 only", "License": "Freetype Project License or GNU General Public License v2.0 only",
"LicenseId": "FTL or GPL-2.0", "LicenseId": "FTL or GPL-2.0",
"LicenseFile": "../../3rdparty/freetype/docs/LICENSE.TXT", "LicenseFile": "../../3rdparty/freetype/docs/LICENSE.TXT",
"Copyright": "Copyright 2006-2015 by David Turner, Robert Wilhelm, and Werner Lemberg." "Copyright": "Copyright 2000-2016 by David Turner, Robert Wilhelm, and Werner Lemberg."
}, },
{ {
"Id": "smooth-scaling-algorithm", "Id": "smooth-scaling-algorithm",

View File

@ -548,7 +548,7 @@ void QNetworkAccessManager::setProxy(const QNetworkProxy &proxy)
Q_D(QNetworkAccessManager); Q_D(QNetworkAccessManager);
delete d->proxyFactory; delete d->proxyFactory;
d->proxy = proxy; d->proxy = proxy;
d->proxyFactory = 0; d->proxyFactory = nullptr;
} }
/*! /*!
@ -1804,7 +1804,7 @@ void QNetworkAccessManagerPrivate::destroyThread()
delete thread; delete thread;
else else
QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread = 0; thread = nullptr;
} }
} }

View File

@ -77,10 +77,11 @@ class QNetworkAccessManagerPrivate: public QObjectPrivate
{ {
public: public:
QNetworkAccessManagerPrivate() QNetworkAccessManagerPrivate()
: networkCache(0), cookieJar(0), : networkCache(nullptr),
thread(0), cookieJar(nullptr),
thread(nullptr),
#ifndef QT_NO_NETWORKPROXY #ifndef QT_NO_NETWORKPROXY
proxyFactory(0), proxyFactory(nullptr),
#endif #endif
#ifndef QT_NO_BEARERMANAGEMENT #ifndef QT_NO_BEARERMANAGEMENT
lastSessionState(QNetworkSession::Invalid), lastSessionState(QNetworkSession::Invalid),
@ -130,7 +131,7 @@ public:
bool allowAuthenticationReuse = true); bool allowAuthenticationReuse = true);
void cacheCredentials(const QUrl &url, const QAuthenticator *auth); void cacheCredentials(const QUrl &url, const QAuthenticator *auth);
QNetworkAuthenticationCredential *fetchCachedCredentials(const QUrl &url, QNetworkAuthenticationCredential *fetchCachedCredentials(const QUrl &url,
const QAuthenticator *auth = 0); const QAuthenticator *auth = nullptr);
#ifndef QT_NO_NETWORKPROXY #ifndef QT_NO_NETWORKPROXY
void proxyAuthenticationRequired(const QUrl &url, void proxyAuthenticationRequired(const QUrl &url,
@ -140,7 +141,7 @@ public:
QNetworkProxy *lastProxyAuthentication); QNetworkProxy *lastProxyAuthentication);
void cacheProxyCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth); void cacheProxyCredentials(const QNetworkProxy &proxy, const QAuthenticator *auth);
QNetworkAuthenticationCredential *fetchCachedProxyCredentials(const QNetworkProxy &proxy, QNetworkAuthenticationCredential *fetchCachedProxyCredentials(const QNetworkProxy &proxy,
const QAuthenticator *auth = 0); const QAuthenticator *auth = nullptr);
QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query); QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query);
#endif #endif

View File

@ -69,7 +69,7 @@ class QNetworkProxy;
static inline bool isSeparator(char c) static inline bool isSeparator(char c)
{ {
static const char separators[] = "()<>@,;:\\\"/[]?={}"; static const char separators[] = "()<>@,;:\\\"/[]?={}";
return isLWS(c) || strchr(separators, c) != 0; return isLWS(c) || strchr(separators, c) != nullptr;
} }
// ### merge with nextField in cookiejar.cpp // ### merge with nextField in cookiejar.cpp
@ -438,18 +438,18 @@ void QNetworkReplyHttpImpl::sslConfigurationImplementation(QSslConfiguration &co
QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate() QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate()
: QNetworkReplyPrivate() : QNetworkReplyPrivate()
, manager(0) , manager(nullptr)
, managerPrivate(0) , managerPrivate(nullptr)
, synchronous(false) , synchronous(false)
, state(Idle) , state(Idle)
, statusCode(0) , statusCode(0)
, uploadByteDevicePosition(false) , uploadByteDevicePosition(false)
, uploadDeviceChoking(false) , uploadDeviceChoking(false)
, outgoingData(0) , outgoingData(nullptr)
, bytesUploaded(-1) , bytesUploaded(-1)
, cacheLoadDevice(0) , cacheLoadDevice(nullptr)
, loadingFromCache(false) , loadingFromCache(false)
, cacheSaveDevice(0) , cacheSaveDevice(nullptr)
, cacheEnabled(false) , cacheEnabled(false)
, resumeOffset(0) , resumeOffset(0)
, preMigrationDownloaded(-1) , preMigrationDownloaded(-1)
@ -457,7 +457,7 @@ QNetworkReplyHttpImplPrivate::QNetworkReplyHttpImplPrivate()
, bytesBuffered(0) , bytesBuffered(0)
, downloadBufferReadPosition(0) , downloadBufferReadPosition(0)
, downloadBufferCurrentSize(0) , downloadBufferCurrentSize(0)
, downloadZerocopyBuffer(0) , downloadZerocopyBuffer(nullptr)
, pendingDownloadDataEmissions(QSharedPointer<QAtomicInt>::create()) , pendingDownloadDataEmissions(QSharedPointer<QAtomicInt>::create())
, pendingDownloadProgressEmissions(QSharedPointer<QAtomicInt>::create()) , pendingDownloadProgressEmissions(QSharedPointer<QAtomicInt>::create())
#ifndef QT_NO_SSL #ifndef QT_NO_SSL
@ -618,7 +618,7 @@ void QNetworkReplyHttpImplPrivate::postRequest(const QNetworkRequest &newHttpReq
{ {
Q_Q(QNetworkReplyHttpImpl); Q_Q(QNetworkReplyHttpImpl);
QThread *thread = 0; QThread *thread = nullptr;
if (synchronous) { if (synchronous) {
// A synchronous HTTP request uses its own thread // A synchronous HTTP request uses its own thread
thread = new QThread(); thread = new QThread();
@ -1031,7 +1031,7 @@ void QNetworkReplyHttpImplPrivate::initCacheSaveDevice()
managerPrivate->networkCache->metaObject()->className()); managerPrivate->networkCache->metaObject()->className());
managerPrivate->networkCache->remove(url); managerPrivate->networkCache->remove(url);
cacheSaveDevice = 0; cacheSaveDevice = nullptr;
cacheEnabled = false; cacheEnabled = false;
} }
} }
@ -1973,7 +1973,7 @@ void QNetworkReplyHttpImplPrivate::_q_cacheLoadReadyRead()
qint64 actualCount = cacheLoadDevice->read(&c, 1); qint64 actualCount = cacheLoadDevice->read(&c, 1);
if (actualCount < 0) { if (actualCount < 0) {
cacheLoadDevice->deleteLater(); cacheLoadDevice->deleteLater();
cacheLoadDevice = 0; cacheLoadDevice = nullptr;
QMetaObject::invokeMethod(q, "_q_finished", Qt::QueuedConnection); QMetaObject::invokeMethod(q, "_q_finished", Qt::QueuedConnection);
} else if (actualCount == 1) { } else if (actualCount == 1) {
// This is most probably not happening since most QIODevice returned something proper for bytesAvailable() // This is most probably not happening since most QIODevice returned something proper for bytesAvailable()
@ -1983,7 +1983,7 @@ void QNetworkReplyHttpImplPrivate::_q_cacheLoadReadyRead()
} else if ((!cacheLoadDevice->isSequential() && cacheLoadDevice->atEnd())) { } else if ((!cacheLoadDevice->isSequential() && cacheLoadDevice->atEnd())) {
// This codepath is in case the cache device is a QBuffer, e.g. from QNetworkDiskCache. // This codepath is in case the cache device is a QBuffer, e.g. from QNetworkDiskCache.
cacheLoadDevice->deleteLater(); cacheLoadDevice->deleteLater();
cacheLoadDevice = 0; cacheLoadDevice = nullptr;
QMetaObject::invokeMethod(q, "_q_finished", Qt::QueuedConnection); QMetaObject::invokeMethod(q, "_q_finished", Qt::QueuedConnection);
} }
} }
@ -2010,7 +2010,7 @@ void QNetworkReplyHttpImplPrivate::_q_cacheSaveDeviceAboutToClose()
{ {
// do not keep a dangling pointer to the device around (device // do not keep a dangling pointer to the device around (device
// is closing because e.g. QAbstractNetworkCache::remove() was called). // is closing because e.g. QAbstractNetworkCache::remove() was called).
cacheSaveDevice = 0; cacheSaveDevice = nullptr;
} }
void QNetworkReplyHttpImplPrivate::_q_bufferOutgoingData() void QNetworkReplyHttpImplPrivate::_q_bufferOutgoingData()
@ -2162,7 +2162,7 @@ QNonContiguousByteDevice* QNetworkReplyHttpImplPrivate::createUploadByteDevice()
else if (outgoingData) { else if (outgoingData) {
uploadByteDevice = QNonContiguousByteDeviceFactory::createShared(outgoingData); uploadByteDevice = QNonContiguousByteDeviceFactory::createShared(outgoingData);
} else { } else {
return 0; return nullptr;
} }
// We want signal emissions only for normal asynchronous uploads // We want signal emissions only for normal asynchronous uploads
@ -2335,7 +2335,7 @@ void QNetworkReplyHttpImplPrivate::createCache()
bool QNetworkReplyHttpImplPrivate::isCachingEnabled() const bool QNetworkReplyHttpImplPrivate::isCachingEnabled() const
{ {
return (cacheEnabled && managerPrivate->networkCache != 0); return (cacheEnabled && managerPrivate->networkCache != nullptr);
} }
void QNetworkReplyHttpImplPrivate::setCachingEnabled(bool enable) void QNetworkReplyHttpImplPrivate::setCachingEnabled(bool enable)
@ -2359,7 +2359,7 @@ void QNetworkReplyHttpImplPrivate::setCachingEnabled(bool enable)
// ok... but you should make up your mind // ok... but you should make up your mind
qDebug("QNetworkReplyImpl: setCachingEnabled(true) called after setCachingEnabled(false)"); qDebug("QNetworkReplyImpl: setCachingEnabled(true) called after setCachingEnabled(false)");
managerPrivate->networkCache->remove(url); managerPrivate->networkCache->remove(url);
cacheSaveDevice = 0; cacheSaveDevice = nullptr;
cacheEnabled = false; cacheEnabled = false;
} }
} }
@ -2376,7 +2376,7 @@ void QNetworkReplyHttpImplPrivate::completeCacheSave()
} else if (cacheEnabled && cacheSaveDevice) { } else if (cacheEnabled && cacheSaveDevice) {
managerPrivate->networkCache->insert(cacheSaveDevice); managerPrivate->networkCache->insert(cacheSaveDevice);
} }
cacheSaveDevice = 0; cacheSaveDevice = nullptr;
cacheEnabled = false; cacheEnabled = false;
} }

View File

@ -734,7 +734,7 @@ void QKmsDevice::enumerateProperties(drmModeObjectPropertiesPtr objProps, PropCa
} else if (propTypeIs(prop, DRM_MODE_PROP_ENUM)) { } else if (propTypeIs(prop, DRM_MODE_PROP_ENUM)) {
qCDebug(qLcKmsDebug, " type is ENUM, value is %llu, possible values are:", value); qCDebug(qLcKmsDebug, " type is ENUM, value is %llu, possible values are:", value);
for (int i = 0; i < prop->count_enums; ++i) for (int i = 0; i < prop->count_enums; ++i)
qCDebug(qLcKmsDebug, " enum %d: %s - %llu", i, prop->enums[i].name, prop->enums[i].value); qCDebug(qLcKmsDebug, " enum %d: %s - %llu", i, prop->enums[i].name, quint64(prop->enums[i].value));
} else if (propTypeIs(prop, DRM_MODE_PROP_BITMASK)) { } else if (propTypeIs(prop, DRM_MODE_PROP_BITMASK)) {
qCDebug(qLcKmsDebug, " type is BITMASK, value is %llu, possible bits are:", value); qCDebug(qLcKmsDebug, " type is BITMASK, value is %llu, possible bits are:", value);
for (int i = 0; i < prop->count_enums; ++i) for (int i = 0; i < prop->count_enums; ++i)

View File

@ -54,7 +54,7 @@ public:
explicit QBsdFbScreen(const QStringList &args); explicit QBsdFbScreen(const QStringList &args);
~QBsdFbScreen() override; ~QBsdFbScreen() override;
bool initialize(); bool initialize() override;
QPixmap grabWindow(WId wid, int x, int y, int width, int height) const override; QPixmap grabWindow(WId wid, int x, int y, int width, int height) const override;

View File

@ -1503,6 +1503,15 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
{ {
QMacAutoReleasePool pool; QMacAutoReleasePool pool;
Qt::WindowType type = window()->type();
Qt::WindowFlags flags = window()->flags();
// Note: The macOS window manager has a bug, where if a screen is rotated, it will not allow
// a window to be created within the area of the screen that has a Y coordinate (I quadrant)
// higher than the height of the screen in its non-rotated state, unless the window is
// created with the NSWindowStyleMaskBorderless style mask.
NSWindowStyleMask styleMask = windowStyleMask(flags);
QRect rect = geometry(); QRect rect = geometry();
QScreen *targetScreen = nullptr; QScreen *targetScreen = nullptr;
@ -1514,26 +1523,22 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
} }
if (!targetScreen) { if (!targetScreen) {
qCWarning(lcQpaWindow) << "Window position outside any known screen, using primary screen"; qCWarning(lcQpaWindow) << "Window position" << rect << "outside any known screen, using primary screen";
targetScreen = QGuiApplication::primaryScreen(); targetScreen = QGuiApplication::primaryScreen();
// AppKit will only reposition a window that's outside the target screen area if
// the window has a title bar. If left out, the window ends up with no screen.
// The style mask will be corrected to the original style mask in setWindowFlags.
styleMask |= NSWindowStyleMaskTitled;
} }
rect.translate(-targetScreen->geometry().topLeft()); rect.translate(-targetScreen->geometry().topLeft());
QCocoaScreen *cocoaScreen = static_cast<QCocoaScreen *>(targetScreen->handle()); QCocoaScreen *cocoaScreen = static_cast<QCocoaScreen *>(targetScreen->handle());
NSRect frame = QCocoaScreen::mapToNative(rect, cocoaScreen); NSRect frame = QCocoaScreen::mapToNative(rect, cocoaScreen);
// Note: The macOS window manager has a bug, where if a screen is rotated, it will not allow
// a window to be created within the area of the screen that has a Y coordinate (I quadrant)
// higher than the height of the screen in its non-rotated state, unless the window is
// created with the NSWindowStyleMaskBorderless style mask.
Qt::WindowType type = window()->type();
Qt::WindowFlags flags = window()->flags();
// Create NSWindow // Create NSWindow
Class windowClass = shouldBePanel ? [QNSPanel class] : [QNSWindow class]; Class windowClass = shouldBePanel ? [QNSPanel class] : [QNSWindow class];
QCocoaNSWindow *nsWindow = [[windowClass alloc] initWithContentRect:frame QCocoaNSWindow *nsWindow = [[windowClass alloc] initWithContentRect:frame
styleMask:windowStyleMask(flags) styleMask:styleMask
// Deferring window creation breaks OpenGL (the GL context is // Deferring window creation breaks OpenGL (the GL context is
// set up before the window is shown and needs a proper window) // set up before the window is shown and needs a proper window)
backing:NSBackingStoreBuffered defer:NO backing:NSBackingStoreBuffered defer:NO
@ -1542,6 +1547,11 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
Q_ASSERT_X(nsWindow.screen == cocoaScreen->nativeScreen(), "QCocoaWindow", Q_ASSERT_X(nsWindow.screen == cocoaScreen->nativeScreen(), "QCocoaWindow",
"Resulting NSScreen should match the requested NSScreen"); "Resulting NSScreen should match the requested NSScreen");
if (targetScreen != window()->screen()) {
QWindowSystemInterface::handleWindowScreenChanged<
QWindowSystemInterface::SynchronousDelivery>(window(), targetScreen);
}
nsWindow.delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this]; nsWindow.delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this];
// Prevent Cocoa from releasing the window on close. Qt // Prevent Cocoa from releasing the window on close. Qt
@ -1561,9 +1571,6 @@ QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBePanel)
}); });
} }
if (targetScreen != window()->screen())
QWindowSystemInterface::handleWindowScreenChanged<QWindowSystemInterface::SynchronousDelivery>(window(), targetScreen);
nsWindow.restorable = NO; nsWindow.restorable = NO;
nsWindow.level = windowLevel(flags); nsWindow.level = windowLevel(flags);

View File

@ -38,6 +38,7 @@
****************************************************************************/ ****************************************************************************/
#include "qqnxglcontext.h" #include "qqnxglcontext.h"
#include "qqnxintegration.h"
#include "qqnxscreen.h" #include "qqnxscreen.h"
#include "qqnxeglwindow.h" #include "qqnxeglwindow.h"
@ -59,8 +60,18 @@ QT_BEGIN_NAMESPACE
EGLDisplay QQnxGLContext::ms_eglDisplay = EGL_NO_DISPLAY; EGLDisplay QQnxGLContext::ms_eglDisplay = EGL_NO_DISPLAY;
static QEGLPlatformContext::Flags makeFlags()
{
QEGLPlatformContext::Flags result = 0;
if (!QQnxIntegration::instance()->options().testFlag(QQnxIntegration::SurfacelessEGLContext))
result |= QEGLPlatformContext::NoSurfaceless;
return result;
}
QQnxGLContext::QQnxGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share) QQnxGLContext::QQnxGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share)
: QEGLPlatformContext(format, share, ms_eglDisplay) : QEGLPlatformContext(format, share, ms_eglDisplay, 0, QVariant(), makeFlags())
{ {
} }

View File

@ -116,6 +116,10 @@ static inline QQnxIntegration::Options parseOptions(const QStringList &paramList
options |= QQnxIntegration::RootWindow; options |= QQnxIntegration::RootWindow;
} }
if (!paramList.contains(QLatin1String("disable-EGL_KHR_surfaceless_context"))) {
options |= QQnxIntegration::SurfacelessEGLContext;
}
return options; return options;
} }

View File

@ -81,7 +81,8 @@ public:
NoOptions = 0x0, NoOptions = 0x0,
FullScreenApplication = 0x1, FullScreenApplication = 0x1,
RootWindow = 0x2, RootWindow = 0x2,
AlwaysFlushScreenContext = 0x4 AlwaysFlushScreenContext = 0x4,
SurfacelessEGLContext = 0x8
}; };
Q_DECLARE_FLAGS(Options, Option) Q_DECLARE_FLAGS(Options, Option)
explicit QQnxIntegration(const QStringList &paramList); explicit QQnxIntegration(const QStringList &paramList);

View File

@ -1268,7 +1268,8 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
it.value().id = id; it.value().id = id;
} }
if (isPressed && it.value().pressure == 0.) const bool wasPressEvent = isPressed && it.value().pressure == 0.;
if (wasPressEvent)
it.value().state = Qt::TouchPointPressed; it.value().state = Qt::TouchPointPressed;
else if (!isPressed && it.value().pressure > 0.) else if (!isPressed && it.value().pressure > 0.)
it.value().state = Qt::TouchPointReleased; it.value().state = Qt::TouchPointReleased;
@ -1282,6 +1283,8 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
it.value().pressure = pressure; it.value().pressure = pressure;
QWindowSystemInterface::handleTouchEvent(d->currentTargetWindow, d->touchDevice, d->touchPoints.values(), mods); QWindowSystemInterface::handleTouchEvent(d->currentTargetWindow, d->touchDevice, d->touchPoints.values(), mods);
if (wasPressEvent)
it.value().state = Qt::TouchPointStationary;
// Fall-through for pen to generate tablet event // Fall-through for pen to generate tablet event
if (pointerDeviceType != PointerDeviceType_Pen) if (pointerDeviceType != PointerDeviceType_Pen)

View File

@ -45,8 +45,10 @@
#include "qxcbwindow.h" #include "qxcbwindow.h"
#include "qxcbscreen.h" #include "qxcbscreen.h"
#define register /* C++17 deprecated register */
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#undef register
#include <GL/glx.h> #include <GL/glx.h>
#include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLContext>

View File

@ -52,7 +52,9 @@
#include "qxcbglxnativeinterfacehandler.h" #include "qxcbglxnativeinterfacehandler.h"
#define register /* C++17 deprecated register */
#include <X11/Xlibint.h> #include <X11/Xlibint.h>
#undef register
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@ -48,7 +48,9 @@
# include <X11/extensions/Xrender.h> # include <X11/extensions/Xrender.h>
#endif #endif
#define register /* C++17 deprecated register */
#include <X11/Xlib.h> #include <X11/Xlib.h>
#undef register
#ifndef None #ifndef None
#define None 0L #define None 0L

View File

@ -40,8 +40,10 @@
#ifndef QT_X11_P_H #ifndef QT_X11_P_H
#define QT_X11_P_H #define QT_X11_P_H
#define register /* C++17 deprecated register */
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
#undef register
#if QT_CONFIG(xrender) #if QT_CONFIG(xrender)
# include "qtessellator_p.h" # include "qtessellator_p.h"

View File

@ -74,10 +74,12 @@
#include <xcb/xinerama.h> #include <xcb/xinerama.h>
#if QT_CONFIG(xcb_xlib) #if QT_CONFIG(xcb_xlib)
#define register /* C++17 deprecated register */
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xlib-xcb.h> #include <X11/Xlib-xcb.h>
#include <X11/Xlibint.h> #include <X11/Xlibint.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#undef register
#endif #endif
#if QT_CONFIG(xcb_xinput) #if QT_CONFIG(xcb_xinput)
@ -1213,10 +1215,9 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
handled = true; handled = true;
} else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY) { } else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
xcb_randr_screen_change_notify_event_t *change_event = reinterpret_cast<xcb_randr_screen_change_notify_event_t *>(event); xcb_randr_screen_change_notify_event_t *change_event = reinterpret_cast<xcb_randr_screen_change_notify_event_t *>(event);
for (QXcbScreen *s : qAsConst(m_screens)) { if (auto *virtualDesktop = virtualDesktopForRootWindow(change_event->root))
if (s->root() == change_event->root ) virtualDesktop->handleScreenChange(change_event);
s->handleScreenChange(change_event);
}
handled = true; handled = true;
#if QT_CONFIG(xkb) #if QT_CONFIG(xkb)
} else if (response_type == xkb_first_event) { // https://bugs.freedesktop.org/show_bug.cgi?id=51295 } else if (response_type == xkb_first_event) { // https://bugs.freedesktop.org/show_bug.cgi?id=51295

View File

@ -66,7 +66,9 @@
#include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qguiapplication_p.h>
#if QT_CONFIG(xcb_xlib) #if QT_CONFIG(xcb_xlib)
#define register /* C++17 deprecated register */
#include <X11/Xlib.h> #include <X11/Xlib.h>
#undef register
#endif #endif
#if QT_CONFIG(xcb_native_painting) #if QT_CONFIG(xcb_native_painting)
#include "qxcbnativepainting.h" #include "qxcbnativepainting.h"

View File

@ -112,6 +112,13 @@ QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t
xcb_depth_next(&depth_iterator); xcb_depth_next(&depth_iterator);
} }
if (connection->hasXRandr()) {
xcb_connection_t *conn = connection->xcb_connection();
auto screen_info = Q_XCB_REPLY(xcb_randr_get_screen_info, conn, screen->root);
if (screen_info)
m_rotation = screen_info->rotation;
}
} }
QXcbVirtualDesktop::~QXcbVirtualDesktop() QXcbVirtualDesktop::~QXcbVirtualDesktop()
@ -119,6 +126,15 @@ QXcbVirtualDesktop::~QXcbVirtualDesktop()
delete m_xSettings; delete m_xSettings;
} }
QDpi QXcbVirtualDesktop::dpi() const
{
const QSize virtualSize = size();
const QSize virtualSizeMillimeters = physicalSize();
return QDpi(Q_MM_PER_INCH * virtualSize.width() / virtualSizeMillimeters.width(),
Q_MM_PER_INCH * virtualSize.height() / virtualSizeMillimeters.height());
}
QXcbScreen *QXcbVirtualDesktop::screenAt(const QPoint &pos) const QXcbScreen *QXcbVirtualDesktop::screenAt(const QPoint &pos) const
{ {
const auto screens = connection()->screens(); const auto screens = connection()->screens();
@ -174,6 +190,74 @@ void QXcbVirtualDesktop::subscribeToXFixesSelectionNotify()
} }
} }
/*!
\brief handle the XCB screen change event and update properties
On a mobile device, the ideal use case is that the accelerometer would
drive the orientation. This could be achieved by using QSensors to read the
accelerometer and adjusting the rotation in QML, or by reading the
orientation from the QScreen object and doing the same, or in many other
ways. However, on X we have the XRandR extension, which makes it possible
to have the whole screen rotated, so that individual apps DO NOT have to
rotate themselves. Apps could optionally use the
QScreen::primaryOrientation property to optimize layout though.
Furthermore, there is no support in X for accelerometer events anyway. So
it makes more sense on a Linux system running X to just run a daemon which
monitors the accelerometer and runs xrandr automatically to do the rotation,
then apps do not have to be aware of it (but probably the window manager
would resize them accordingly). updateGeometry() is written with this
design in mind. Therefore the physical geometry, available geometry,
virtual geometry, orientation and primaryOrientation should all change at
the same time. On a system which cannot rotate the whole screen, it would
be correct for only the orientation (not the primary orientation) to
change.
*/
void QXcbVirtualDesktop::handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event)
{
// No need to do anything when screen rotation did not change - if any
// xcb output geometry has changed, we will get RRCrtcChangeNotify and
// RROutputChangeNotify events next
if (change_event->rotation == m_rotation)
return;
m_rotation = change_event->rotation;
switch (m_rotation) {
case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal
m_screen->width_in_pixels = change_event->width;
m_screen->height_in_pixels = change_event->height;
m_screen->width_in_millimeters = change_event->mwidth;
m_screen->height_in_millimeters = change_event->mheight;
break;
case XCB_RANDR_ROTATION_ROTATE_90: // xrandr --rotate left
m_screen->width_in_pixels = change_event->height;
m_screen->height_in_pixels = change_event->width;
m_screen->width_in_millimeters = change_event->mheight;
m_screen->height_in_millimeters = change_event->mwidth;
break;
case XCB_RANDR_ROTATION_ROTATE_180: // xrandr --rotate inverted
m_screen->width_in_pixels = change_event->width;
m_screen->height_in_pixels = change_event->height;
m_screen->width_in_millimeters = change_event->mwidth;
m_screen->height_in_millimeters = change_event->mheight;
break;
case XCB_RANDR_ROTATION_ROTATE_270: // xrandr --rotate right
m_screen->width_in_pixels = change_event->height;
m_screen->height_in_pixels = change_event->width;
m_screen->width_in_millimeters = change_event->mheight;
m_screen->height_in_millimeters = change_event->mwidth;
break;
// We don't need to do anything with these, since QScreen doesn't store reflection state,
// and Qt-based applications probably don't need to care about it anyway.
case XCB_RANDR_ROTATION_REFLECT_X: break;
case XCB_RANDR_ROTATION_REFLECT_Y: break;
}
for (QPlatformScreen *platformScreen: qAsConst(m_screens)) {
QDpi ldpi = platformScreen->logicalDpi();
QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(platformScreen->screen(), ldpi.first, ldpi.second);
}
}
/*! \internal /*! \internal
Using _NET_WORKAREA to calculate the available desktop geometry on multi-head systems (systems Using _NET_WORKAREA to calculate the available desktop geometry on multi-head systems (systems
@ -401,8 +485,6 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
, m_crtc(output ? output->crtc : XCB_NONE) , m_crtc(output ? output->crtc : XCB_NONE)
, m_outputName(getOutputName(output)) , m_outputName(getOutputName(output))
, m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize()) , m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize())
, m_virtualSize(virtualDesktop->size())
, m_virtualSizeMillimeters(virtualDesktop->physicalSize())
{ {
if (connection->hasXRandr()) { if (connection->hasXRandr()) {
xcb_randr_select_input(xcb_connection(), screen()->root, true); xcb_randr_select_input(xcb_connection(), screen()->root, true);
@ -416,19 +498,19 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
m_geometry = QRect(xineramaScreenInfo->x_org, xineramaScreenInfo->y_org, m_geometry = QRect(xineramaScreenInfo->x_org, xineramaScreenInfo->y_org,
xineramaScreenInfo->width, xineramaScreenInfo->height); xineramaScreenInfo->width, xineramaScreenInfo->height);
m_availableGeometry = m_geometry & m_virtualDesktop->workArea(); m_availableGeometry = m_geometry & m_virtualDesktop->workArea();
m_sizeMillimeters = sizeInMillimeters(m_geometry.size(), virtualDpi()); m_sizeMillimeters = sizeInMillimeters(m_geometry.size(), m_virtualDesktop->dpi());
if (xineramaScreenIdx > -1) if (xineramaScreenIdx > -1)
m_outputName += QLatin1Char('-') + QString::number(xineramaScreenIdx); m_outputName += QLatin1Char('-') + QString::number(xineramaScreenIdx);
} }
if (m_geometry.isEmpty()) if (m_geometry.isEmpty())
m_geometry = QRect(QPoint(), m_virtualSize); m_geometry = QRect(QPoint(), virtualDesktop->size());
if (m_availableGeometry.isEmpty()) if (m_availableGeometry.isEmpty())
m_availableGeometry = m_geometry & m_virtualDesktop->workArea(); m_availableGeometry = m_geometry & m_virtualDesktop->workArea();
if (m_sizeMillimeters.isEmpty()) if (m_sizeMillimeters.isEmpty())
m_sizeMillimeters = m_virtualSizeMillimeters; m_sizeMillimeters = virtualDesktop->physicalSize();
m_cursor = new QXcbCursor(connection, this); m_cursor = new QXcbCursor(connection, this);
@ -583,13 +665,6 @@ QImage::Format QXcbScreen::format() const
return format; return format;
} }
QDpi QXcbScreen::virtualDpi() const
{
return QDpi(Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(),
Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height());
}
QDpi QXcbScreen::logicalDpi() const QDpi QXcbScreen::logicalDpi() const
{ {
static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI"); static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI");
@ -600,7 +675,7 @@ QDpi QXcbScreen::logicalDpi() const
if (forcedDpi > 0) { if (forcedDpi > 0) {
return QDpi(forcedDpi, forcedDpi); return QDpi(forcedDpi, forcedDpi);
} }
return virtualDpi(); return m_virtualDesktop->dpi();
} }
qreal QXcbScreen::pixelDensity() const qreal QXcbScreen::pixelDensity() const
@ -631,80 +706,6 @@ int QXcbScreen::virtualDesktopNumberStatic(const QScreen *screen)
return 0; return 0;
} }
/*!
\brief handle the XCB screen change event and update properties
On a mobile device, the ideal use case is that the accelerometer would
drive the orientation. This could be achieved by using QSensors to read the
accelerometer and adjusting the rotation in QML, or by reading the
orientation from the QScreen object and doing the same, or in many other
ways. However, on X we have the XRandR extension, which makes it possible
to have the whole screen rotated, so that individual apps DO NOT have to
rotate themselves. Apps could optionally use the
QScreen::primaryOrientation property to optimize layout though.
Furthermore, there is no support in X for accelerometer events anyway. So
it makes more sense on a Linux system running X to just run a daemon which
monitors the accelerometer and runs xrandr automatically to do the rotation,
then apps do not have to be aware of it (but probably the window manager
would resize them accordingly). updateGeometry() is written with this
design in mind. Therefore the physical geometry, available geometry,
virtual geometry, orientation and primaryOrientation should all change at
the same time. On a system which cannot rotate the whole screen, it would
be correct for only the orientation (not the primary orientation) to
change.
*/
void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event)
{
// No need to do anything when screen rotation did not change - if any
// xcb output geometry has changed, we will get RRCrtcChangeNotify and
// RROutputChangeNotify events next
if (change_event->rotation == m_rotation)
return;
m_rotation = change_event->rotation;
switch (m_rotation) {
case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal
m_orientation = Qt::LandscapeOrientation;
m_virtualSize.setWidth(change_event->width);
m_virtualSize.setHeight(change_event->height);
m_virtualSizeMillimeters.setWidth(change_event->mwidth);
m_virtualSizeMillimeters.setHeight(change_event->mheight);
break;
case XCB_RANDR_ROTATION_ROTATE_90: // xrandr --rotate left
m_orientation = Qt::PortraitOrientation;
m_virtualSize.setWidth(change_event->height);
m_virtualSize.setHeight(change_event->width);
m_virtualSizeMillimeters.setWidth(change_event->mheight);
m_virtualSizeMillimeters.setHeight(change_event->mwidth);
break;
case XCB_RANDR_ROTATION_ROTATE_180: // xrandr --rotate inverted
m_orientation = Qt::InvertedLandscapeOrientation;
m_virtualSize.setWidth(change_event->width);
m_virtualSize.setHeight(change_event->height);
m_virtualSizeMillimeters.setWidth(change_event->mwidth);
m_virtualSizeMillimeters.setHeight(change_event->mheight);
break;
case XCB_RANDR_ROTATION_ROTATE_270: // xrandr --rotate right
m_orientation = Qt::InvertedPortraitOrientation;
m_virtualSize.setWidth(change_event->height);
m_virtualSize.setHeight(change_event->width);
m_virtualSizeMillimeters.setWidth(change_event->mheight);
m_virtualSizeMillimeters.setHeight(change_event->mwidth);
break;
// We don't need to do anything with these, since QScreen doesn't store reflection state,
// and Qt-based applications probably don't need to care about it anyway.
case XCB_RANDR_ROTATION_REFLECT_X: break;
case XCB_RANDR_ROTATION_REFLECT_Y: break;
}
updateGeometry(change_event->timestamp);
QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation);
QDpi ldpi = logicalDpi();
QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QPlatformScreen::screen(), ldpi.first, ldpi.second);
}
void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp) void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
{ {
if (!connection()->hasXRandr()) if (!connection()->hasXRandr())
@ -718,6 +719,8 @@ void QXcbScreen::updateGeometry(xcb_timestamp_t timestamp)
void QXcbScreen::updateGeometry(const QRect &geometry, uint8_t rotation) void QXcbScreen::updateGeometry(const QRect &geometry, uint8_t rotation)
{ {
const Qt::ScreenOrientation oldOrientation = m_orientation;
switch (rotation) { switch (rotation) {
case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal
m_orientation = Qt::LandscapeOrientation; m_orientation = Qt::LandscapeOrientation;
@ -741,13 +744,15 @@ void QXcbScreen::updateGeometry(const QRect &geometry, uint8_t rotation)
// is known (probably back-calculated from DPI and resolution), // is known (probably back-calculated from DPI and resolution),
// e.g. on VNC or with some hardware. // e.g. on VNC or with some hardware.
if (m_sizeMillimeters.isEmpty()) if (m_sizeMillimeters.isEmpty())
m_sizeMillimeters = sizeInMillimeters(geometry.size(), virtualDpi()); m_sizeMillimeters = sizeInMillimeters(geometry.size(), m_virtualDesktop->dpi());
qreal dpi = geometry.width() / physicalSize().width() * qreal(25.4); qreal dpi = geometry.width() / physicalSize().width() * qreal(25.4);
m_pixelDensity = qMax(1, qRound(dpi/96)); m_pixelDensity = qMax(1, qRound(dpi/96));
m_geometry = geometry; m_geometry = geometry;
m_availableGeometry = geometry & m_virtualDesktop->workArea(); m_availableGeometry = geometry & m_virtualDesktop->workArea();
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry); QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry);
if (m_orientation != oldOrientation)
QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation);
} }
void QXcbScreen::updateAvailableGeometry() void QXcbScreen::updateAvailableGeometry()
@ -943,8 +948,9 @@ QDebug operator<<(QDebug debug, const QXcbScreen *screen)
formatSizeF(debug, screen->physicalSize()); formatSizeF(debug, screen->physicalSize());
// TODO 5.6 if (debug.verbosity() > 2) { // TODO 5.6 if (debug.verbosity() > 2) {
debug << ", screenNumber=" << screen->screenNumber(); debug << ", screenNumber=" << screen->screenNumber();
debug << ", virtualSize=" << screen->virtualSize().width() << 'x' << screen->virtualSize().height() << " ("; const QSize virtualSize = screen->virtualDesktop()->size();
formatSizeF(debug, screen->virtualSize()); debug << ", virtualSize=" << virtualSize.width() << 'x' << virtualSize.height() << " (";
formatSizeF(debug, virtualSize);
debug << "), orientation=" << screen->orientation(); debug << "), orientation=" << screen->orientation();
debug << ", depth=" << screen->depth(); debug << ", depth=" << screen->depth();
debug << ", refreshRate=" << screen->refreshRate(); debug << ", refreshRate=" << screen->refreshRate();

View File

@ -74,6 +74,7 @@ public:
int number() const { return m_number; } int number() const { return m_number; }
QSize size() const { return QSize(m_screen->width_in_pixels, m_screen->height_in_pixels); } QSize size() const { return QSize(m_screen->width_in_pixels, m_screen->height_in_pixels); }
QSize physicalSize() const { return QSize(m_screen->width_in_millimeters, m_screen->height_in_millimeters); } QSize physicalSize() const { return QSize(m_screen->width_in_millimeters, m_screen->height_in_millimeters); }
QDpi dpi() const;
xcb_window_t root() const { return m_screen->root; } xcb_window_t root() const { return m_screen->root; }
QXcbScreen *screenAt(const QPoint &pos) const; QXcbScreen *screenAt(const QPoint &pos) const;
@ -93,6 +94,8 @@ public:
void handleXFixesSelectionNotify(xcb_xfixes_selection_notify_event_t *notify_event); void handleXFixesSelectionNotify(xcb_xfixes_selection_notify_event_t *notify_event);
void subscribeToXFixesSelectionNotify(); void subscribeToXFixesSelectionNotify();
void handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event);
int forcedDpi() const { return m_forcedDpi; } int forcedDpi() const { return m_forcedDpi; }
QFontEngine::HintStyle hintStyle() const { return m_hintStyle; } QFontEngine::HintStyle hintStyle() const { return m_hintStyle; }
QFontEngine::SubpixelAntialiasingType subpixelType() const { return m_subpixelType; } QFontEngine::SubpixelAntialiasingType subpixelType() const { return m_subpixelType; }
@ -131,6 +134,7 @@ private:
QString m_windowManagerName; QString m_windowManagerName;
QMap<xcb_visualid_t, xcb_visualtype_t> m_visuals; QMap<xcb_visualid_t, xcb_visualtype_t> m_visuals;
QMap<xcb_visualid_t, quint8> m_visualDepths; QMap<xcb_visualid_t, quint8> m_visualDepths;
uint16_t m_rotation = XCB_RANDR_ROTATION_ROTATE_0;
}; };
class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen
@ -156,9 +160,6 @@ public:
int depth() const override { return screen()->root_depth; } int depth() const override { return screen()->root_depth; }
QImage::Format format() const override; QImage::Format format() const override;
QSizeF physicalSize() const override { return m_sizeMillimeters; } QSizeF physicalSize() const override { return m_sizeMillimeters; }
QSize virtualSize() const { return m_virtualSize; }
QSizeF physicalVirtualSize() const { return m_virtualSizeMillimeters; }
QDpi virtualDpi() const;
QDpi logicalDpi() const override; QDpi logicalDpi() const override;
qreal pixelDensity() const override; qreal pixelDensity() const override;
QPlatformCursor *cursor() const override; QPlatformCursor *cursor() const override;
@ -194,7 +195,6 @@ public:
QString name() const override { return m_outputName; } QString name() const override { return m_outputName; }
void handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event);
void updateGeometry(const QRect &geometry, uint8_t rotation); void updateGeometry(const QRect &geometry, uint8_t rotation);
void updateGeometry(xcb_timestamp_t timestamp = XCB_TIME_CURRENT_TIME); void updateGeometry(xcb_timestamp_t timestamp = XCB_TIME_CURRENT_TIME);
void updateAvailableGeometry(); void updateAvailableGeometry();
@ -224,8 +224,6 @@ private:
QSizeF m_sizeMillimeters; QSizeF m_sizeMillimeters;
QRect m_geometry; QRect m_geometry;
QRect m_availableGeometry; QRect m_availableGeometry;
QSize m_virtualSize;
QSizeF m_virtualSizeMillimeters;
Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation; Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation;
QXcbCursor *m_cursor; QXcbCursor *m_cursor;
int m_refreshRate = 60; int m_refreshRate = 60;

View File

@ -106,8 +106,10 @@
#include <stdio.h> #include <stdio.h>
#if QT_CONFIG(xcb_xlib) #if QT_CONFIG(xcb_xlib)
#define register /* C++17 deprecated register */
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h> #include <X11/Xutil.h>
#undef register
#endif #endif
#define XCOORD_MAX 16383 #define XCOORD_MAX 16383

View File

@ -244,6 +244,7 @@ QXcbXSettings::QXcbXSettings(QXcbVirtualDesktop *screen)
if (!d_ptr->x_settings_window) if (!d_ptr->x_settings_window)
return; return;
screen->connection()->addWindowEventListener(d_ptr->x_settings_window, this);
const uint32_t event = XCB_CW_EVENT_MASK; const uint32_t event = XCB_CW_EVENT_MASK;
const uint32_t event_mask[] = { XCB_EVENT_MASK_STRUCTURE_NOTIFY|XCB_EVENT_MASK_PROPERTY_CHANGE }; const uint32_t event_mask[] = { XCB_EVENT_MASK_STRUCTURE_NOTIFY|XCB_EVENT_MASK_PROPERTY_CHANGE };
xcb_change_window_attributes(screen->xcb_connection(),d_ptr->x_settings_window,event,event_mask); xcb_change_window_attributes(screen->xcb_connection(),d_ptr->x_settings_window,event,event_mask);

View File

@ -232,10 +232,6 @@ void QActionPrivate::setShortcutEnabled(bool enable, QShortcutMap &map)
the action. For example: the action. For example:
\snippet mainwindows/application/mainwindow.cpp 19 \snippet mainwindows/application/mainwindow.cpp 19
\codeline
\code
fileMenu->addAction(openAct);
\endcode
We recommend that actions are created as children of the window We recommend that actions are created as children of the window
they are used in. In most cases actions will be children of they are used in. In most cases actions will be children of
@ -968,7 +964,10 @@ void QAction::toggle()
Only checkable actions can be checked. By default, this is false Only checkable actions can be checked. By default, this is false
(the action is unchecked). (the action is unchecked).
\sa checkable \note The notifier signal for this property is toggled(). As toggling
a QAction changes its state, it will also emit a changed() signal.
\sa checkable, toggled()
*/ */
void QAction::setChecked(bool b) void QAction::setChecked(bool b)
{ {
@ -1190,7 +1189,8 @@ void QAction::activate(ActionEvent event)
This signal is emitted whenever a checkable action changes its This signal is emitted whenever a checkable action changes its
isChecked() status. This can be the result of a user interaction, isChecked() status. This can be the result of a user interaction,
or because setChecked() was called. or because setChecked() was called. As setChecked() changes the
QAction, it emits changed() in addition to toggled().
\a checked is true if the action is checked, or false if the \a checked is true if the action is checked, or false if the
action is unchecked. action is unchecked.

View File

@ -1946,8 +1946,8 @@ void QCalendarWidgetPrivate::updateNavigationBar()
QString monthName = q->locale().standaloneMonthName(m_model->m_shownMonth, QLocale::LongFormat); QString monthName = q->locale().standaloneMonthName(m_model->m_shownMonth, QLocale::LongFormat);
monthButton->setText(monthName); monthButton->setText(monthName);
yearButton->setText(QString::number(m_model->m_shownYear));
yearEdit->setValue(m_model->m_shownYear); yearEdit->setValue(m_model->m_shownYear);
yearButton->setText(yearEdit->text());
} }
void QCalendarWidgetPrivate::update() void QCalendarWidgetPrivate::update()

View File

@ -349,6 +349,7 @@ bool QSplashScreen::event(QEvent *e)
if (e->type() == QEvent::Paint) { if (e->type() == QEvent::Paint) {
Q_D(QSplashScreen); Q_D(QSplashScreen);
QPainter painter(this); QPainter painter(this);
painter.setLayoutDirection(layoutDirection());
if (!d->pixmap.isNull()) if (!d->pixmap.isNull())
painter.drawPixmap(QPoint(), d->pixmap); painter.drawPixmap(QPoint(), d->pixmap);
drawContents(&painter); drawContents(&painter);

View File

@ -756,14 +756,14 @@ void QToolButtonPrivate::popupTimerDone()
QSize sh = ((QToolButton*)(QMenu*)actualMenu)->receivers(SIGNAL(aboutToShow()))? QSize() : actualMenu->sizeHint(); QSize sh = ((QToolButton*)(QMenu*)actualMenu)->receivers(SIGNAL(aboutToShow()))? QSize() : actualMenu->sizeHint();
if (horizontal) { if (horizontal) {
if (q->isRightToLeft()) { if (q->isRightToLeft()) {
if (q->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.height()) { if (q->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.bottom()) {
p = q->mapToGlobal(rect.bottomRight()); p = q->mapToGlobal(rect.bottomRight());
} else { } else {
p = q->mapToGlobal(rect.topRight() - QPoint(0, sh.height())); p = q->mapToGlobal(rect.topRight() - QPoint(0, sh.height()));
} }
p.rx() -= sh.width(); p.rx() -= sh.width();
} else { } else {
if (q->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.height()) { if (q->mapToGlobal(QPoint(0, rect.bottom())).y() + sh.height() <= screen.bottom()) {
p = q->mapToGlobal(rect.bottomLeft()); p = q->mapToGlobal(rect.bottomLeft());
} else { } else {
p = q->mapToGlobal(rect.topLeft() - QPoint(0, sh.height())); p = q->mapToGlobal(rect.topLeft() - QPoint(0, sh.height()));

View File

@ -1848,7 +1848,8 @@ void QWidgetLineControl::processKeyEvent(QKeyEvent* event)
else if (event == QKeySequence::DeleteStartOfWord) { else if (event == QKeySequence::DeleteStartOfWord) {
if (!isReadOnly()) { if (!isReadOnly()) {
cursorWordBackward(true); cursorWordBackward(true);
del(); if (hasSelectedText())
del();
} }
} else if (event == QKeySequence::DeleteCompleteLine) { } else if (event == QKeySequence::DeleteCompleteLine) {
if (!isReadOnly()) { if (!isReadOnly()) {

View File

@ -20,3 +20,11 @@ win32 {
!qtConfig(library) { !qtConfig(library) {
LIBS += -L ../bin/ -lplugin1 -lplugin2 LIBS += -L ../bin/ -lplugin1 -lplugin2
} }
android {
libs.prefix = android_test_data
libs.base = $$OUT_PWD/..
libs.files += $$OUT_PWD/../bin
RESOURCES += libs
}

View File

@ -42,6 +42,11 @@ Q_IMPORT_PLUGIN(Plugin2)
class tst_QFactoryLoader : public QObject class tst_QFactoryLoader : public QObject
{ {
Q_OBJECT Q_OBJECT
#ifdef Q_OS_ANDROID
QSharedPointer<QTemporaryDir> directory;
#endif
public slots: public slots:
void initTestCase(); void initTestCase();
@ -53,6 +58,12 @@ static const char binFolderC[] = "bin";
void tst_QFactoryLoader::initTestCase() void tst_QFactoryLoader::initTestCase()
{ {
#ifdef Q_OS_ANDROID
directory = QEXTRACTTESTDATA("android_test_data");
QVERIFY(directory);
QVERIFY(directory->isValid());
QVERIFY2(QDir::setCurrent(directory->path()), qPrintable("Could not chdir to " + directory->path()));
#endif
const QString binFolder = QFINDTESTDATA(binFolderC); const QString binFolder = QFINDTESTDATA(binFolderC);
QVERIFY2(!binFolder.isEmpty(), "Unable to locate 'bin' folder"); QVERIFY2(!binFolder.isEmpty(), "Unable to locate 'bin' folder");
#if QT_CONFIG(library) #if QT_CONFIG(library)

View File

@ -345,8 +345,8 @@ void tst_QPluginLoader::loadMachO()
QVERIFY(f.open(QIODevice::ReadOnly)); QVERIFY(f.open(QIODevice::ReadOnly));
QByteArray data = f.readAll(); QByteArray data = f.readAll();
long pos; qsizetype pos;
ulong len; qsizetype len;
QString errorString; QString errorString;
int r = QMachOParser::parse(data.constData(), data.size(), f.fileName(), &errorString, &pos, &len); int r = QMachOParser::parse(data.constData(), data.size(), f.fileName(), &errorString, &pos, &len);

View File

@ -2723,12 +2723,15 @@ void tst_QDateTime::timeZoneAbbreviation()
#endif #endif
QCOMPARE(dt5.timeZoneAbbreviation(), QStringLiteral("CEST")); QCOMPARE(dt5.timeZoneAbbreviation(), QStringLiteral("CEST"));
} else { } else {
QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo"); qDebug("(Skipped some CET-only tests)");
} }
#ifdef Q_OS_ANDROID // Only reports (general) zones as offsets (QTBUG-68837) #ifdef Q_OS_ANDROID // Only reports (general) zones as offsets (QTBUG-68837)
const QString cet(QStringLiteral("GMT+01:00")); const QString cet(QStringLiteral("GMT+01:00"));
const QString cest(QStringLiteral("GMT+02:00")); const QString cest(QStringLiteral("GMT+02:00"));
#elif defined Q_OS_DARWIN
const QString cet(QStringLiteral("GMT+1"));
const QString cest(QStringLiteral("GMT+2"));
#else #else
const QString cet(QStringLiteral("CET")); const QString cet(QStringLiteral("CET"));
const QString cest(QStringLiteral("CEST")); const QString cest(QStringLiteral("CEST"));

View File

@ -1567,12 +1567,15 @@ void tst_QLocale::formatTimeZone()
#endif // Q_OS_WIN #endif // Q_OS_WIN
QCOMPARE(enUS.toString(dt5, "t"), QLatin1String("CEST")); QCOMPARE(enUS.toString(dt5, "t"), QLatin1String("CEST"));
} else { } else {
QSKIP("You must test using Central European (CET/CEST) time zone, e.g. TZ=Europe/Oslo"); qDebug("(Skipped some CET-only tests)");
} }
#ifdef Q_OS_ANDROID // Only reports (general) zones as offsets (QTBUG-68837) #ifdef Q_OS_ANDROID // Only reports (general) zones as offsets (QTBUG-68837)
const QString cet(QStringLiteral("GMT+01:00")); const QString cet(QStringLiteral("GMT+01:00"));
const QString cest(QStringLiteral("GMT+02:00")); const QString cest(QStringLiteral("GMT+02:00"));
#elif defined Q_OS_DARWIN
const QString cet(QStringLiteral("GMT+1"));
const QString cest(QStringLiteral("GMT+2"));
#else #else
const QString cet(QStringLiteral("CET")); const QString cet(QStringLiteral("CET"));
const QString cest(QStringLiteral("CEST")); const QString cest(QStringLiteral("CEST"));

View File

@ -450,6 +450,9 @@ void tst_QPointF::compare()
p3 -= QPointF(0.1, 0.1); p3 -= QPointF(0.1, 0.1);
QVERIFY(p3 == QPointF()); QVERIFY(p3 == QPointF());
// Test we can compare one dimension with hard zero
QVERIFY(QPointF(1.9543e-14, -32.0) == QPointF(0.0, -32.0));
} }
QTEST_MAIN(tst_QPointF) QTEST_MAIN(tst_QPointF)

View File

@ -460,6 +460,9 @@ void tst_QBrush::textureBrushStream()
QCOMPARE(loadedBrush1.style(), Qt::TexturePattern); QCOMPARE(loadedBrush1.style(), Qt::TexturePattern);
QCOMPARE(loadedBrush2.style(), Qt::TexturePattern); QCOMPARE(loadedBrush2.style(), Qt::TexturePattern);
#ifdef Q_OS_ANDROID
QEXPECT_FAIL("", "QTBUG-69193", Continue);
#endif
QCOMPARE(loadedBrush1.texture(), pixmap_source); QCOMPARE(loadedBrush1.texture(), pixmap_source);
QCOMPARE(loadedBrush2.textureImage(), image_source); QCOMPARE(loadedBrush2.textureImage(), image_source);
} }

View File

@ -300,6 +300,9 @@ void tst_QFont::resetFont()
child->setFont(QFont()); // reset font child->setFont(QFont()); // reset font
QCOMPARE(child->font().resolve(), uint(0)); QCOMPARE(child->font().resolve(), uint(0));
#ifdef Q_OS_ANDROID
QEXPECT_FAIL("", "QTBUG-69214", Continue);
#endif
QCOMPARE(child->font().pointSize(), parent.font().pointSize()); QCOMPARE(child->font().pointSize(), parent.font().pointSize());
QVERIFY(parent.font().resolve() != 0); QVERIFY(parent.font().resolve() != 0);
} }
@ -539,6 +542,9 @@ void tst_QFont::defaultFamily()
} }
} }
#ifdef Q_OS_ANDROID
QEXPECT_FAIL("serif", "QTBUG-69215", Continue);
#endif
QVERIFY2(isAcceptable, msgNotAcceptableFont(familyForHint, acceptableFamilies)); QVERIFY2(isAcceptable, msgNotAcceptableFont(familyForHint, acceptableFamilies));
} }

View File

@ -359,6 +359,9 @@ void tst_QFontDatabase::condensedFontMatching()
QEXPECT_FAIL("","No matching of sub-family by stretch on Windows", Continue); QEXPECT_FAIL("","No matching of sub-family by stretch on Windows", Continue);
#endif #endif
#ifdef Q_OS_ANDROID
QEXPECT_FAIL("", "QTBUG-69216", Continue);
#endif
QCOMPARE(QFontMetrics(tfcByStretch).horizontalAdvance(testString()), QCOMPARE(QFontMetrics(tfcByStretch).horizontalAdvance(testString()),
QFontMetrics(tfcByStyleName).horizontalAdvance(testString())); QFontMetrics(tfcByStyleName).horizontalAdvance(testString()));

View File

@ -1039,6 +1039,9 @@ void tst_QRawFont::fallbackFontsOrder()
QList<QGlyphRun> glyphRuns = layout.glyphRuns(); QList<QGlyphRun> glyphRuns = layout.glyphRuns();
#ifdef Q_OS_ANDROID
QEXPECT_FAIL("", "QTBUG-69217", Continue);
#endif
// Since QtBidiTestFont does not support Arabic nor the space, both should map to // Since QtBidiTestFont does not support Arabic nor the space, both should map to
// the same font. If this fails, it is an indication that the list of fallbacks fonts // the same font. If this fails, it is an indication that the list of fallbacks fonts
// is not sorted by writing system support. // is not sorted by writing system support.

View File

@ -465,6 +465,9 @@ void tst_QStaticText::rotatedPainter()
QVERIFY(imageDrawText.toImage() != m_whiteSquare); QVERIFY(imageDrawText.toImage() != m_whiteSquare);
#ifdef Q_OS_ANDROID
QEXPECT_FAIL("", "QTBUG-69218", Continue);
#endif
if (!supportsTransformations()) if (!supportsTransformations())
QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort); QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort);
QCOMPARE(imageDrawStaticText, imageDrawText); QCOMPARE(imageDrawStaticText, imageDrawText);
@ -622,6 +625,9 @@ void tst_QStaticText::transformationChanged()
QVERIFY(imageDrawText.toImage() != m_whiteSquare); QVERIFY(imageDrawText.toImage() != m_whiteSquare);
#ifdef Q_OS_ANDROID
QEXPECT_FAIL("", "QTBUG-69220", Continue);
#endif
if (!supportsTransformations()) if (!supportsTransformations())
QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort); QEXPECT_FAIL("", "Graphics system does not support transformed text on this platform", Abort);
QCOMPARE(imageDrawStaticText, imageDrawText); QCOMPARE(imageDrawStaticText, imageDrawText);

View File

@ -619,7 +619,11 @@ void tst_QTextDocument::task240325()
QCOMPARE(doc->blockCount(), 1); QCOMPARE(doc->blockCount(), 1);
for (QTextBlock block = doc->begin() ; block!=doc->end() ; block = block.next()) { for (QTextBlock block = doc->begin() ; block!=doc->end() ; block = block.next()) {
QTextLayout *layout = block.layout(); QTextLayout *layout = block.layout();
#ifdef Q_OS_ANDROID
QEXPECT_FAIL("", "QTBUG-69242", Abort);
#endif
QCOMPARE(layout->lineCount(), 4); QCOMPARE(layout->lineCount(), 4);
for (int lineIdx=0;lineIdx<layout->lineCount();++lineIdx) { for (int lineIdx=0;lineIdx<layout->lineCount();++lineIdx) {
QTextLine line = layout->lineAt(lineIdx); QTextLine line = layout->lineAt(lineIdx);

View File

@ -283,6 +283,8 @@ void tst_QNetworkInterface::interfaceFromXXX_data()
QTest::addColumn<QNetworkInterface>("iface"); QTest::addColumn<QNetworkInterface>("iface");
QList<QNetworkInterface> allInterfaces = QNetworkInterface::allInterfaces(); QList<QNetworkInterface> allInterfaces = QNetworkInterface::allInterfaces();
if (allInterfaces.count() == 0)
QSKIP("No interfaces to test!");
foreach (QNetworkInterface iface, allInterfaces) foreach (QNetworkInterface iface, allInterfaces)
QTest::newRow(iface.name().toLocal8Bit()) << iface; QTest::newRow(iface.name().toLocal8Bit()) << iface;
} }

View File

@ -0,0 +1,73 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
// This tests that when in a multiple screen setup, that screens that have a top-left of 0x0 or
// a top left of being above/below the other screen then showing the toolbutton menu will be
// placed correctly.
#include <QApplication>
#include <QMainWindow>
#include <QToolBar>
#include <QToolButton>
#include <QMenu>
#include <QScreen>
class MyMainWindow : public QMainWindow
{
public:
MyMainWindow(QWidget *parent = 0) : QMainWindow(parent)
{
auto *toolBar = new QToolBar;
QPixmap pix(16, 16);
pix.fill(Qt::red);
auto *button = new QToolButton;
button->setIcon(pix);
toolBar->addWidget(button);
auto *menu = new QMenu(button);
for (int i = 0; i < 10; ++i)
menu->addAction(QString("Test Action %1").arg(i));
button->setMenu(menu);
addToolBar(toolBar);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QList<MyMainWindow *> windows;
for (QScreen *s : a.screens()) {
MyMainWindow *w = new MyMainWindow;
w->setGeometry(s->availableGeometry());
w->show();
windows << w;
}
int ret = a.exec();
qDeleteAll(windows);
return ret;
}

View File

@ -0,0 +1,3 @@
TEMPLATE = app
QT += widgets
SOURCES += main.cpp