From 64857434e29c367191b653e24e0fe672c13eb2b1 Mon Sep 17 00:00:00 2001 From: Frank Meerkoetter Date: Fri, 18 Dec 2015 21:39:49 +0100 Subject: [PATCH 001/100] Fix broken permission to mode mapping Fixes coverity CID154258. Change-Id: Ia958d24c533c4f0077abd363ee4c041cc2cdb6f0 Reviewed-by: Konstantin Ritt --- src/gui/text/qzip.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp index be002167cbe..31ef8f87bea 100644 --- a/src/gui/text/qzip.cpp +++ b/src/gui/text/qzip.cpp @@ -243,11 +243,11 @@ static QFile::Permissions modeToPermissions(quint32 mode) static quint32 permissionsToMode(QFile::Permissions perms) { quint32 mode = 0; - if (mode & (QFile::ReadOwner | QFile::ReadUser)) + if (perms & (QFile::ReadOwner | QFile::ReadUser)) mode |= UnixFileAttributes::ReadUser; - if (mode & (QFile::WriteOwner | QFile::WriteUser)) + if (perms & (QFile::WriteOwner | QFile::WriteUser)) mode |= UnixFileAttributes::WriteUser; - if (mode & (QFile::ExeOwner | QFile::ExeUser)) + if (perms & (QFile::ExeOwner | QFile::ExeUser)) mode |= UnixFileAttributes::WriteUser; if (perms & QFile::ReadGroup) mode |= UnixFileAttributes::ReadGroup; From bcc23e7942debca71f5aa13af3e512aeb5bb4fe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 14 Dec 2015 10:53:39 +0100 Subject: [PATCH 002/100] Make tst_qtimeline::duration less fragile to timings The test still can fail because 1s is quite a short time. Change-Id: I6f42c182f2932d5a053f6a69667210529c9a7697 Reviewed-by: Friedemann Kleint --- tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp index 507f7e3992a..79118791d02 100644 --- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp @@ -174,11 +174,9 @@ void tst_QTimeLine::duration() QCOMPARE(timeLine.duration(), 1000); timeLine.start(); - QTest::qWait(999); - QCOMPARE(timeLine.state(), QTimeLine::Running); - QVERIFY(timeLine.currentTime() > 900); - QTest::qWait(100); - QCOMPARE(timeLine.state(), QTimeLine::NotRunning); + QTRY_COMPARE(timeLine.state(), QTimeLine::Running); + QTRY_VERIFY(timeLine.currentTime() > 0); + QTRY_COMPARE(timeLine.state(), QTimeLine::NotRunning); QCOMPARE(timeLine.currentTime(), 1000); // The duration shouldn't change QCOMPARE(timeLine.duration(), 1000); @@ -187,7 +185,7 @@ void tst_QTimeLine::duration() void tst_QTimeLine::frameRate() { QTimeLine timeLine; - timeLine.setFrameRange(10, 20); + timeLine.setFrameRange(100, 2000); QCOMPARE(timeLine.updateInterval(), 1000 / 25); timeLine.setUpdateInterval(1000 / 60); QCOMPARE(timeLine.updateInterval(), 1000 / 60); From 229c03cd88ab9ed6453eb39df907825193a87af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 14 Dec 2015 11:13:10 +0100 Subject: [PATCH 003/100] Make tst_qtimeline::range less prune to timing errors Change-Id: I5fd84c58250a9dfa237fcb7fca4da50c35a9f57e Reviewed-by: Friedemann Kleint --- .../corelib/tools/qtimeline/tst_qtimeline.cpp | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp index 79118791d02..8d42fc9d44a 100644 --- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp @@ -93,29 +93,20 @@ void tst_QTimeLine::range() QCOMPARE(timeLine.endFrame(), 16); // Verify that you can change the range in the timeLine - timeLine.setFrameRange(10, 20); + timeLine.setFrameRange(1000, 2000); QSignalSpy spy(&timeLine, &QTimeLine::frameChanged); QVERIFY(spy.isValid()); - timeLine.start(); -#ifdef Q_OS_WINCE - QTest::qWait(1000); -#else - QTest::qWait(100); -#endif - QCOMPARE(timeLine.state(), QTimeLine::Running); + timeLine.start(); // make sure that the logic works for a running timeline + QTRY_COMPARE(timeLine.state(), QTimeLine::Running); + timeLine.setCurrentTime(timeLine.duration()/2); int oldValue = timeLine.currentFrame(); - timeLine.setFrameRange(0, 5); + timeLine.setFrameRange(0, 500); QVERIFY(timeLine.currentFrame() < oldValue); - timeLine.setEndFrame(100); - timeLine.setStartFrame(50); + timeLine.setEndFrame(10000); + timeLine.setStartFrame(5000); QVERIFY(timeLine.currentFrame() > oldValue); - timeLine.setFrameRange(0, 5); -#ifdef Q_OS_WINCE - QTest::qWait(500); -#else - QTest::qWait(50); -#endif - QVERIFY(spy.count() > 1); + timeLine.setFrameRange(0, 500); + QTRY_VERIFY(spy.count() > 1); QVERIFY(timeLine.currentFrame() < oldValue); } From 70e290411a3dd9549492a9770429952bd25134a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 14 Dec 2015 12:28:51 +0100 Subject: [PATCH 004/100] Improve tst_qtimeline::currentTime Now the test is less fragile to time and it executes 4s faster Change-Id: Id3eb8ed2c03317e7d2f2c3cd17f889a8d8e7e5b4 Reviewed-by: Friedemann Kleint --- .../corelib/tools/qtimeline/tst_qtimeline.cpp | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp index 8d42fc9d44a..07531f6a7f4 100644 --- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp @@ -114,19 +114,17 @@ void tst_QTimeLine::currentTime() { QTimeLine timeLine(2000); timeLine.setUpdateInterval((timeLine.duration()/2) / 33); - QSignalSpy spy(&timeLine, &QTimeLine::valueChanged); - QVERIFY(spy.isValid()); timeLine.setFrameRange(10, 20); QCOMPARE(timeLine.currentTime(), 0); timeLine.start(); - QTest::qWait(timeLine.duration()/2); - QCOMPARE(timeLine.state(), QTimeLine::Running); - QVERIFY(timeLine.currentTime() > timeLine.duration()/2 - timeLine.duration()/10); - QVERIFY(timeLine.currentTime() < timeLine.duration()/2 + timeLine.duration()/10); - QTest::qWait(timeLine.duration()/4 + timeLine.duration()); - QCOMPARE(timeLine.state(), QTimeLine::NotRunning); + QTRY_COMPARE(timeLine.state(), QTimeLine::Running); + QTRY_VERIFY(timeLine.currentTime() > timeLine.duration()/2 - timeLine.duration()/4); + QVERIFY(timeLine.currentTime() < timeLine.duration()/2 + timeLine.duration()/4); + QTRY_COMPARE(timeLine.state(), QTimeLine::NotRunning); QCOMPARE(timeLine.currentTime(), timeLine.duration()); + QSignalSpy spy(&timeLine, &QTimeLine::valueChanged); + QVERIFY(spy.isValid()); spy.clear(); timeLine.setCurrentTime(timeLine.duration()/2); timeLine.setCurrentTime(timeLine.duration()/2); @@ -135,24 +133,22 @@ void tst_QTimeLine::currentTime() QCOMPARE(timeLine.currentTime(), timeLine.duration()/2); timeLine.resume(); // Let it update on its own - QTest::qWait(timeLine.duration()/4); QCOMPARE(timeLine.state(), QTimeLine::Running); - QVERIFY(timeLine.currentTime() > timeLine.duration()/2); + QTRY_VERIFY(timeLine.currentTime() > timeLine.duration()/2); QVERIFY(timeLine.currentTime() < timeLine.duration()); - QTest::qWait(timeLine.duration()/4 + timeLine.duration()); - QCOMPARE(timeLine.state(), QTimeLine::NotRunning); - QVERIFY(timeLine.currentTime() == timeLine.duration()); + QTRY_COMPARE(timeLine.state(), QTimeLine::NotRunning); + QCOMPARE(timeLine.currentTime(), timeLine.duration()); // Reverse should decrease the currentTime timeLine.setCurrentTime(timeLine.duration()/2); timeLine.start(); // Let it update on its own - QTest::qWait(timeLine.duration()/4); - QCOMPARE(timeLine.state(), QTimeLine::Running); int currentTime = timeLine.currentTime(); + QTRY_VERIFY(timeLine.currentTime() > currentTime); + QCOMPARE(timeLine.state(), QTimeLine::Running); + currentTime = timeLine.currentTime(); timeLine.setDirection(QTimeLine::Backward); - QTest::qWait(timeLine.duration()/4); - QVERIFY(timeLine.currentTime() < currentTime); + QTRY_VERIFY(timeLine.currentTime() < currentTime); timeLine.stop(); } From 266511401f8d513aaeca1380248e5534e33bf55e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 14 Dec 2015 12:35:47 +0100 Subject: [PATCH 005/100] Improve tst_qtimeline::currentFrame The test run faster and it less vulnerable to an inaccurate time. Change-Id: I19475095395dcf1e6d47fdbba5eeffabab1fc7b9 Reviewed-by: Friedemann Kleint --- tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp index 07531f6a7f4..91e095f541a 100644 --- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp @@ -236,22 +236,19 @@ void tst_QTimeLine::currentFrame() QSignalSpy spy(&timeLine, &QTimeLine::frameChanged); QVERIFY(spy.isValid()); timeLine.start(); - QTest::qWait(timeLine.duration()/3); - QVERIFY(timeLine.currentFrame() > 10); - QTest::qWait(timeLine.duration()); - QCOMPARE(timeLine.state(), QTimeLine::NotRunning); + QTRY_VERIFY(timeLine.currentFrame() > 10); + QTRY_COMPARE(timeLine.state(), QTimeLine::NotRunning); QCOMPARE(timeLine.currentFrame(), 20); // Reverse should decrease the value timeLine.setCurrentTime(timeLine.duration()/2); timeLine.start(); // Let it update on its own - QTest::qWait(timeLine.duration()/4); QCOMPARE(timeLine.state(), QTimeLine::Running); + QTRY_VERIFY(timeLine.currentTime() > timeLine.duration()/2); // wait for continuation int value = timeLine.currentFrame(); timeLine.setDirection(QTimeLine::Backward); - QTest::qWait(timeLine.duration()/2); - QVERIFY(timeLine.currentFrame() < value); + QTRY_VERIFY(timeLine.currentFrame() < value); timeLine.stop(); } From 4e012cb08390beb21620b5d3fbf86ad2216b2a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 14 Dec 2015 13:23:47 +0100 Subject: [PATCH 006/100] Improve tst_qtimeline::value The test was improved by: - Use QCOMPARE instead of QVERIFY - Use QTRY_ macro instead arbitrary qWait - Use longer time line The test executes faster and it should be less vulnerable to an unreliable timer. Change-Id: I92675015a6251b47eaf20b0fc916f3a36b52d783 Reviewed-by: Friedemann Kleint --- .../corelib/tools/qtimeline/tst_qtimeline.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp index 91e095f541a..98e8ffded55 100644 --- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp @@ -198,31 +198,27 @@ void tst_QTimeLine::frameRate() void tst_QTimeLine::value() { - QTimeLine timeLine(2000); - QVERIFY(timeLine.currentValue() == 0.0); + QTimeLine timeLine(5000); + QCOMPARE(timeLine.currentValue(), 0.0); // Default speed QSignalSpy spy(&timeLine, &QTimeLine::valueChanged); QVERIFY(spy.isValid()); timeLine.start(); - QTest::qWait(timeLine.duration()/3); - QVERIFY(timeLine.currentValue() > 0); - QTest::qWait(timeLine.duration()); - QCOMPARE(timeLine.state(), QTimeLine::NotRunning); - qreal currentValue = timeLine.currentValue(); - QVERIFY(currentValue == 1); + QTRY_VERIFY(timeLine.currentValue() > 0); + QTRY_COMPARE(timeLine.state(), QTimeLine::NotRunning); + QCOMPARE(timeLine.currentValue(), 1.0); QVERIFY(spy.count() > 0); // Reverse should decrease the value timeLine.setCurrentTime(100); timeLine.start(); // Let it update on its own - QTest::qWait(500); QCOMPARE(timeLine.state(), QTimeLine::Running); + QTRY_VERIFY(timeLine.currentValue()); qreal value = timeLine.currentValue(); timeLine.setDirection(QTimeLine::Backward); - QTest::qWait(1000); - QVERIFY(timeLine.currentValue() < value); + QTRY_VERIFY(timeLine.currentValue() < value); timeLine.stop(); } From 6606b151c4c4849ab0b0e6b8d62837ac87858814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Mon, 14 Dec 2015 14:40:15 +0100 Subject: [PATCH 007/100] Get rid of qWait in tst_qtimeline::restart to make it less flaky Change-Id: Iba3a9e5dce6bd7ff6e241fae738cfc51386f0c75 Reviewed-by: Friedemann Kleint --- tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp index 98e8ffded55..9f8cfc6b6a8 100644 --- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp @@ -621,8 +621,7 @@ void tst_QTimeLine::restart() timeLine.setFrameRange(0,9); timeLine.start(); - QTest::qWait(timeLine.duration()*2); - QCOMPARE(timeLine.currentFrame(), timeLine.endFrame()); + QTRY_COMPARE(timeLine.currentFrame(), timeLine.endFrame()); QCOMPARE(timeLine.state(), QTimeLine::NotRunning); // A restart with the same duration @@ -630,8 +629,7 @@ void tst_QTimeLine::restart() QCOMPARE(timeLine.state(), QTimeLine::Running); QCOMPARE(timeLine.currentFrame(), timeLine.startFrame()); QCOMPARE(timeLine.currentTime(), 0); - QTest::qWait(250); - QCOMPARE(timeLine.currentFrame(), timeLine.endFrame()); + QTRY_COMPARE(timeLine.currentFrame(), timeLine.endFrame()); QCOMPARE(timeLine.state(), QTimeLine::NotRunning); // Set a smaller duration and restart @@ -640,8 +638,7 @@ void tst_QTimeLine::restart() QCOMPARE(timeLine.state(), QTimeLine::Running); QCOMPARE(timeLine.currentFrame(), timeLine.startFrame()); QCOMPARE(timeLine.currentTime(), 0); - QTest::qWait(250); - QCOMPARE(timeLine.currentFrame(), timeLine.endFrame()); + QTRY_COMPARE(timeLine.currentFrame(), timeLine.endFrame()); QCOMPARE(timeLine.state(), QTimeLine::NotRunning); // Set a longer duration and restart From 8dd84c6420a7184f2ed4347395bcd6a3dae8907c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Tue, 15 Dec 2015 08:52:51 +0100 Subject: [PATCH 008/100] Speedup tst_qtimeline::finished Change-Id: Id9ae42663d8830365d4dcfab92b48621eb1b409f Reviewed-by: Friedemann Kleint --- tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp index 9f8cfc6b6a8..0ca6fea4825 100644 --- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp @@ -483,9 +483,8 @@ void tst_QTimeLine::finished() QSignalSpy spy(&timeLine, &QTimeLine::finished); QVERIFY(spy.isValid()); timeLine.start(); - QTest::qWait(timeLine.duration()*2); + QTRY_COMPARE(spy.count(), 1); QCOMPARE(timeLine.state(), QTimeLine::NotRunning); - QCOMPARE(spy.count(), 1); spy.clear(); timeLine.start(); From 55eaf11bb7c0a89f3dd86e56c82809f81c121e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Tue, 15 Dec 2015 09:51:12 +0100 Subject: [PATCH 009/100] Stabilize tst_qtimeline::resume Change-Id: Ife0ce27c680196ed1fe3d037ea0367e511560c96 Reviewed-by: Friedemann Kleint --- tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp index 0ca6fea4825..b588e1fe821 100644 --- a/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp +++ b/tests/auto/corelib/tools/qtimeline/tst_qtimeline.cpp @@ -583,16 +583,15 @@ void tst_QTimeLine::resume() { QCOMPARE(timeLine.currentTime(), 0); timeLine.start(); - QTest::qWait(250); + QTRY_VERIFY(timeLine.currentTime() > 0); timeLine.stop(); int oldCurrentTime = timeLine.currentTime(); QVERIFY(oldCurrentTime > 0); QVERIFY(oldCurrentTime < 1000); timeLine.resume(); - QTest::qWait(250); + QTRY_VERIFY(timeLine.currentTime() > oldCurrentTime); timeLine.stop(); int currentTime = timeLine.currentTime(); - QVERIFY(currentTime > oldCurrentTime); QVERIFY(currentTime < 1000); } timeLine.setDirection(QTimeLine::Backward); @@ -600,13 +599,13 @@ void tst_QTimeLine::resume() timeLine.setCurrentTime(1000); QCOMPARE(timeLine.currentTime(), 1000); timeLine.start(); - QTest::qWait(250); + QTRY_VERIFY(timeLine.currentTime() < 1000); timeLine.stop(); int oldCurrentTime = timeLine.currentTime(); QVERIFY(oldCurrentTime < 1000); QVERIFY(oldCurrentTime > 0); timeLine.resume(); - QTest::qWait(250); + QTRY_VERIFY(timeLine.currentTime() < oldCurrentTime); timeLine.stop(); int currentTime = timeLine.currentTime(); QVERIFY(currentTime < oldCurrentTime); From 7cde1c029e5a7da7738484758aa8fc7c930d06cc Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Fri, 18 Dec 2015 16:10:13 +0100 Subject: [PATCH 010/100] Remove superfluous ReleaseSemaphore/WFSO calls Factor out the dispatching of IO results into a separate function. Do not increment the semaphore count in waitForAnyNotified just to decrement it again in _q_notified. Change-Id: I7d4a04b679bb152ab3a5025513f885aee276d086 Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qwinoverlappedionotifier.cpp | 27 ++++++++++++--------- src/corelib/io/qwinoverlappedionotifier_p.h | 2 +- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/corelib/io/qwinoverlappedionotifier.cpp b/src/corelib/io/qwinoverlappedionotifier.cpp index c6ce15c2c9a..c9de6671f7f 100644 --- a/src/corelib/io/qwinoverlappedionotifier.cpp +++ b/src/corelib/io/qwinoverlappedionotifier.cpp @@ -102,7 +102,8 @@ public: OVERLAPPED *waitForAnyNotified(int msecs); void notify(DWORD numberOfBytes, DWORD errorCode, OVERLAPPED *overlapped); - OVERLAPPED *_q_notified(); + void _q_notified(); + OVERLAPPED *dispatchNextIoResult(); static QWinIoCompletionPort *iocp; static HANDLE iocpInstanceLock; @@ -302,8 +303,7 @@ OVERLAPPED *QWinOverlappedIoNotifierPrivate::waitForAnyNotified(int msecs) const DWORD wfso = WaitForSingleObject(hSemaphore, msecs == -1 ? INFINITE : DWORD(msecs)); switch (wfso) { case WAIT_OBJECT_0: - ReleaseSemaphore(hSemaphore, 1, NULL); - return _q_notified(); + return dispatchNextIoResult(); case WAIT_TIMEOUT: return 0; default: @@ -385,17 +385,20 @@ void QWinOverlappedIoNotifierPrivate::notify(DWORD numberOfBytes, DWORD errorCod emit q->_q_notify(); } -OVERLAPPED *QWinOverlappedIoNotifierPrivate::_q_notified() +void QWinOverlappedIoNotifierPrivate::_q_notified() +{ + if (WaitForSingleObject(hSemaphore, 0) == WAIT_OBJECT_0) + dispatchNextIoResult(); +} + +OVERLAPPED *QWinOverlappedIoNotifierPrivate::dispatchNextIoResult() { Q_Q(QWinOverlappedIoNotifier); - if (WaitForSingleObject(hSemaphore, 0) == WAIT_OBJECT_0) { - WaitForSingleObject(hResultsMutex, INFINITE); - IOResult ioresult = results.dequeue(); - ReleaseMutex(hResultsMutex); - emit q->notified(ioresult.numberOfBytes, ioresult.errorCode, ioresult.overlapped); - return ioresult.overlapped; - } - return 0; + WaitForSingleObject(hResultsMutex, INFINITE); + IOResult ioresult = results.dequeue(); + ReleaseMutex(hResultsMutex); + emit q->notified(ioresult.numberOfBytes, ioresult.errorCode, ioresult.overlapped); + return ioresult.overlapped; } QT_END_NAMESPACE diff --git a/src/corelib/io/qwinoverlappedionotifier_p.h b/src/corelib/io/qwinoverlappedionotifier_p.h index 863f87353e3..41945d65560 100644 --- a/src/corelib/io/qwinoverlappedionotifier_p.h +++ b/src/corelib/io/qwinoverlappedionotifier_p.h @@ -58,7 +58,7 @@ class Q_CORE_EXPORT QWinOverlappedIoNotifier : public QObject Q_OBJECT Q_DISABLE_COPY(QWinOverlappedIoNotifier) Q_DECLARE_PRIVATE(QWinOverlappedIoNotifier) - Q_PRIVATE_SLOT(d_func(), OVERLAPPED *_q_notified()) + Q_PRIVATE_SLOT(d_func(), void _q_notified()) friend class QWinIoCompletionPort; public: QWinOverlappedIoNotifier(QObject *parent = 0); From b826672658fcfce1688b329c32c91423b1c3cbd5 Mon Sep 17 00:00:00 2001 From: John Brooks Date: Wed, 2 Sep 2015 13:48:08 -0600 Subject: [PATCH 011/100] Fix visibility of bundled zlib symbols with mingw When QT_VISIBILITY_AVAILABLE is defined, the zlib header would use visibility("default") instead of Q_DECL_EXPORT, but Windows needs dllexport for these symbols to be available to QtGui/QtNetwork. In practice, Q_CORE_EXPORT always has the correct behavior for the zlib symbols. Change-Id: I7ab8080528e437260f822ac33e9e4334e2a0fdc8 Reviewed-by: Oswald Buddenhagen --- src/3rdparty/zlib/zlib.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/3rdparty/zlib/zlib.h b/src/3rdparty/zlib/zlib.h index 5229707f526..d0908ab6e9d 100644 --- a/src/3rdparty/zlib/zlib.h +++ b/src/3rdparty/zlib/zlib.h @@ -34,13 +34,8 @@ #include "zconf.h" #include -#if defined(QT_VISIBILITY_AVAILABLE) -# undef ZEXTERN -# define ZEXTERN __attribute__((visibility("default"))) -#else -# undef ZEXTERN -# define ZEXTERN Q_DECL_EXPORT -#endif +#undef ZEXTERN +#define ZEXTERN Q_CORE_EXPORT #ifdef __cplusplus extern "C" { From f25298bd11cf03a9e7af63ae5512c8ab8b47b306 Mon Sep 17 00:00:00 2001 From: Topi Reinio Date: Mon, 14 Dec 2015 12:06:15 +0100 Subject: [PATCH 012/100] Doc: Update Qt Account url Change-Id: I123ce085032eeb323f7c60548a9651c5188bb337 Reviewed-by: Venugopal Shivashankar --- doc/global/externalsites/external-resources.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/global/externalsites/external-resources.qdoc b/doc/global/externalsites/external-resources.qdoc index d2cf88c1744..3e82dfe814c 100644 --- a/doc/global/externalsites/external-resources.qdoc +++ b/doc/global/externalsites/external-resources.qdoc @@ -489,6 +489,6 @@ */ /*! - \externalpage http://qt.digia.com/Try-Buy/Qt-Account-Sign-up/ + \externalpage https://login.qt.io/ \title Qt Account Sign-up */ From 32e4546cc3b38dd8a15eaac07dc79c48acea5ce7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 3 Dec 2015 16:51:05 -0800 Subject: [PATCH 013/100] qprocessordetection.h: Fix detection of 32-bit ARMv8 This is more future-proof. It fixes the detection of 32-bit on ARMv8-A processors since it uses the __ARM_ARCH macro that GCC and Clang define. For MSVC, we use _M_ARM, which also contains the architecture version. MSVC does not currently support ARMv8 code, but when it does, this commit should make the support automatic. I don't know which compiler defines __TARGET_ARM_ARCH, but support it too. Change-Id: I8de47ed6c7be4847b99bffff141c8ede54a849eb Reviewed-by: Erik Verbruggen --- src/corelib/global/qprocessordetection.h | 47 ++++++++++++++---------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/corelib/global/qprocessordetection.h b/src/corelib/global/qprocessordetection.h index 4b75872bb62..f80e9c15356 100644 --- a/src/corelib/global/qprocessordetection.h +++ b/src/corelib/global/qprocessordetection.h @@ -88,44 +88,51 @@ auto-detection implemented below. */ #if defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(__aarch64__) -# define Q_PROCESSOR_ARM # if defined(__aarch64__) # define Q_PROCESSOR_ARM_64 # define Q_PROCESSOR_WORDSIZE 8 # else # define Q_PROCESSOR_ARM_32 # endif -# if defined(__ARM64_ARCH_8__) -# define Q_PROCESSOR_ARM_V8 -# define Q_PROCESSOR_ARM_V7 -# define Q_PROCESSOR_ARM_V6 -# define Q_PROCESSOR_ARM_V5 +# if defined(__ARM_ARCH) && __ARM_ARCH > 1 +# define Q_PROCESSOR_ARM __ARM_ARCH +# elif defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM > 1 +# define Q_PROCESSOR_ARM __TARGET_ARCH_ARM +# elif defined(_M_ARM) && _M_ARM > 1 +# define Q_PROCESSOR_ARM _M_ARM +# elif defined(__ARM64_ARCH_8__) +# define Q_PROCESSOR_ARM 8 # elif defined(__ARM_ARCH_7__) \ || defined(__ARM_ARCH_7A__) \ || defined(__ARM_ARCH_7R__) \ || defined(__ARM_ARCH_7M__) \ || defined(__ARM_ARCH_7S__) \ - || defined(_ARM_ARCH_7) \ - || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7) \ - || (defined(_M_ARM) && _M_ARM-0 >= 7) -# define Q_PROCESSOR_ARM_V7 -# define Q_PROCESSOR_ARM_V6 -# define Q_PROCESSOR_ARM_V5 + || defined(_ARM_ARCH_7) +# define Q_PROCESSOR_ARM 7 # elif defined(__ARM_ARCH_6__) \ || defined(__ARM_ARCH_6J__) \ || defined(__ARM_ARCH_6T2__) \ || defined(__ARM_ARCH_6Z__) \ || defined(__ARM_ARCH_6K__) \ || defined(__ARM_ARCH_6ZK__) \ - || defined(__ARM_ARCH_6M__) \ - || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6) \ - || (defined(_M_ARM) && _M_ARM-0 >= 6) -# define Q_PROCESSOR_ARM_V6 -# define Q_PROCESSOR_ARM_V5 + || defined(__ARM_ARCH_6M__) +# define Q_PROCESSOR_ARM 6 # elif defined(__ARM_ARCH_5TEJ__) \ - || defined(__ARM_ARCH_5TE__) \ - || (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5) \ - || (defined(_M_ARM) && _M_ARM-0 >= 5) + || defined(__ARM_ARCH_5TE__) +# define Q_PROCESSOR_ARM 5 +# else +# define Q_PROCESSOR_ARM 0 +# endif +# if Q_PROCESSOR_ARM >= 8 +# define Q_PROCESSOR_ARM_V8 +# endif +# if Q_PROCESSOR_ARM >= 7 +# define Q_PROCESSOR_ARM_V7 +# endif +# if Q_PROCESSOR_ARM >= 6 +# define Q_PROCESSOR_ARM_V6 +# endif +# if Q_PROCESSOR_ARM >= 5 # define Q_PROCESSOR_ARM_V5 # endif # if defined(__ARMEL__) From a206583da1bee8fdc90b58bbc8d067ba724de203 Mon Sep 17 00:00:00 2001 From: Daniel Levin Date: Mon, 19 Jan 2015 01:18:39 -0500 Subject: [PATCH 014/100] Add DEPENDS option to qt5_wrap_cpp() Currently the moc rule does not support dependency scanning, so after successful moc file generation it will ignore implicit dependencies in the header file. Although this works in most typical scenarios, at least in one case incremental builds become broken: when using Q_PLUGIN_METADATA() with the FILE argument. If FILE refers to a JSON file and latter was updated, then the expected behavior is to regenerate the moc file. Since CMake add_custom_command() does not support late dependency setup, all dependencies should be explicitly listed in a DEPENDS section. This patch adds the DEPENDS multiarg option to qt5_wrap_cpp(), allowing to specify additional dependencies to the moc rule. Task-number: QTBUG-44009 Change-Id: I2052ce23d3cb0c87c6bd99fcb7e8a71a7be9a330 Reviewed-by: Kevin Funk Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Daniel Levin --- src/corelib/Qt5CoreMacros.cmake | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake index 18563764ad4..c441d3ad734 100644 --- a/src/corelib/Qt5CoreMacros.cmake +++ b/src/corelib/Qt5CoreMacros.cmake @@ -94,7 +94,7 @@ endmacro() # helper macro to set up a moc rule -macro(QT5_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target) +macro(QT5_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target moc_depends) # Pass the parameters in a file. Set the working directory to # be that containing the parameters file and reference it by # just the file name. This is necessary because the moc tool on @@ -131,7 +131,7 @@ macro(QT5_CREATE_MOC_COMMAND infile outfile moc_flags moc_options moc_target) set(_moc_extra_parameters_file @${_moc_parameters_file}) add_custom_command(OUTPUT ${outfile} COMMAND ${Qt5Core_MOC_EXECUTABLE} ${_moc_extra_parameters_file} - DEPENDS ${infile} + DEPENDS ${infile} ${moc_depends} ${_moc_working_dir} VERBATIM) endmacro() @@ -151,7 +151,7 @@ function(QT5_GENERATE_MOC infile outfile ) endif() set(moc_target ${ARGV3}) endif() - qt5_create_moc_command(${abs_infile} ${_outfile} "${moc_flags}" "" "${moc_target}") + qt5_create_moc_command(${abs_infile} ${_outfile} "${moc_flags}" "" "${moc_target}" "") set_source_files_properties(${outfile} PROPERTIES SKIP_AUTOMOC TRUE) # dont run automoc on this file endfunction() @@ -164,13 +164,14 @@ function(QT5_WRAP_CPP outfiles ) set(options) set(oneValueArgs TARGET) - set(multiValueArgs OPTIONS) + set(multiValueArgs OPTIONS DEPENDS) cmake_parse_arguments(_WRAP_CPP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) set(moc_files ${_WRAP_CPP_UNPARSED_ARGUMENTS}) set(moc_options ${_WRAP_CPP_OPTIONS}) set(moc_target ${_WRAP_CPP_TARGET}) + set(moc_depends ${_WRAP_CPP_DEPENDS}) if (moc_target AND CMAKE_VERSION VERSION_LESS 2.8.12) message(FATAL_ERROR "The TARGET parameter to qt5_wrap_cpp is only available when using CMake 2.8.12 or later.") @@ -178,7 +179,7 @@ function(QT5_WRAP_CPP outfiles ) foreach(it ${moc_files}) get_filename_component(it ${it} ABSOLUTE) qt5_make_output_file(${it} moc_ cpp outfile) - qt5_create_moc_command(${it} ${outfile} "${moc_flags}" "${moc_options}" "${moc_target}") + qt5_create_moc_command(${it} ${outfile} "${moc_flags}" "${moc_options}" "${moc_target}" "${moc_depends}") list(APPEND ${outfiles} ${outfile}) endforeach() set(${outfiles} ${${outfiles}} PARENT_SCOPE) From 6f1b78c980b5250b2bb8408a5fe422997b52eb0e Mon Sep 17 00:00:00 2001 From: Matt Hoosier Date: Wed, 2 Dec 2015 14:02:02 -0600 Subject: [PATCH 015/100] Fix version script generation when cross-compiling from Windows to QNX Recent versions of Qt have apparently added sufficient numbers of headers that the command lines used to spawn a custom header- parsing tool, started overflowing Windows' maximum command-line length. This change restructures the mechanism to use a GCC-style command- line arguments file rather than passing filenames all directly in the argv[] vector. Although QNX is the usual ELF target whose cross-build is supported on Windows, the mechanics introduced in this patch happen to affect all other ELF Unix systems' builds too. Change-Id: I5a7383cf9f2ebf9dffde8dbfdcdeca888265e085 Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- mkspecs/features/data/unix/findclasslist.pl | 17 +++++++++++++++-- mkspecs/features/qt_module.prf | 5 +++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/data/unix/findclasslist.pl b/mkspecs/features/data/unix/findclasslist.pl index 9113b4921c6..ac010ae0a7e 100644 --- a/mkspecs/features/data/unix/findclasslist.pl +++ b/mkspecs/features/data/unix/findclasslist.pl @@ -33,8 +33,21 @@ ############################################################################# use strict; -my $syntax = "findclasslist.pl [private header list]\n" . +my $syntax = "findclasslist.pl \n" . "Replaces \@CLASSLIST\@ with the classes found in the header files\n"; + +die("Expected exactly one argument") if (@ARGV != 1); + +my @headers = (); + +# Expand contents of the command-line arguments file +open ARGFILE, "<$ARGV[0]" or die("Could not open arguments file $ARGV[0]: $!"); +while (my $line = ) { + chomp($line); + push @headers, $line; +} +close ARGFILE; + $\ = $/; while () { chomp; @@ -44,7 +57,7 @@ while () { } # Replace @CLASSLIST@ with the class list - for my $header (@ARGV) { + for my $header (@headers) { open HDR, "<$header" or die("Could not open header $header: $!"); my $comment = " /* $header */"; while (my $line = ) { diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf index 9a4ed20af8f..1dae3706302 100644 --- a/mkspecs/features/qt_module.prf +++ b/mkspecs/features/qt_module.prf @@ -215,11 +215,12 @@ android: CONFIG += qt_android_deps no_linker_version_script } # Add a post-processing step to replace the @CLASSLIST@ - verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < $^ > $@ + verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < $${verscript}.in $${verscript}.in.args > $@ verscriptprocess.target = $$verscript - verscriptprocess.depends = $${verscript}.in for(header, SYNCQT.PRIVATE_HEADER_FILES): \ verscriptprocess.depends += $${_PRO_FILE_PWD_}/$$header + write_file($${verscript}.in.args, verscriptprocess.depends)|error("Aborting.") + verscriptprocess.depends += $${verscript}.in $${verscript}.in.args QMAKE_EXTRA_TARGETS += verscriptprocess PRE_TARGETDEPS += $$verscript verscript = $${verscript}.in From 57ca8d2698f1eaf30f1110ba47445c04d2bcd0f7 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 11 Dec 2015 12:08:47 +0100 Subject: [PATCH 016/100] make write_file() capable of making files (not) executable Change-Id: I9ca96bc3408160261781697a3471c1f446c86c3a Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 27 ++++++++++++++++++-------- qmake/library/qmakeevaluator.h | 2 +- qmake/library/qmakevfs.cpp | 17 +++++++++++++--- qmake/library/qmakevfs.h | 2 +- tests/auto/tools/qmakelib/evaltest.cpp | 11 +++++++++-- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index f57d9c89a7d..e8be2f42fdf 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -358,10 +358,10 @@ static QMakeEvaluator::VisitReturn parseJsonInto(const QByteArray &json, const Q QMakeEvaluator::VisitReturn QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode, - const QString &contents) + bool exe, const QString &contents) { QString errStr; - if (!m_vfs->writeFile(fn, mode, contents, &errStr)) { + if (!m_vfs->writeFile(fn, mode, exe, contents, &errStr)) { evalError(fL1S("Cannot write %1file %2: %3") .arg(ctx, QDir::toNativeSeparators(fn), errStr)); return ReturnFalse; @@ -1543,22 +1543,33 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( } case T_WRITE_FILE: { if (args.count() > 3) { - evalError(fL1S("write_file(name, [content var, [append]]) requires one to three arguments.")); + evalError(fL1S("write_file(name, [content var, [append] [exe]]) requires one to three arguments.")); return ReturnFalse; } QIODevice::OpenMode mode = QIODevice::Truncate; + bool exe = false; QString contents; if (args.count() >= 2) { const ProStringList &vals = values(args.at(1).toKey()); if (!vals.isEmpty()) contents = vals.join(QLatin1Char('\n')) + QLatin1Char('\n'); - if (args.count() >= 3) - if (!args.at(2).toQString(m_tmp1).compare(fL1S("append"), Qt::CaseInsensitive)) - mode = QIODevice::Append; + if (args.count() >= 3) { + foreach (const ProString &opt, split_value_list(args.at(2).toQString(m_tmp2))) { + opt.toQString(m_tmp3); + if (m_tmp3 == QLatin1String("append")) { + mode = QIODevice::Append; + } else if (m_tmp3 == QLatin1String("exe")) { + exe = true; + } else { + evalError(fL1S("write_file(): invalid flag %1.").arg(m_tmp3)); + return ReturnFalse; + } + } + } } QString path = resolvePath(args.at(0).toQString(m_tmp1)); path.detach(); // make sure to not leak m_tmp1 into the map of written files. - return writeFile(QString(), path, mode, contents); + return writeFile(QString(), path, mode, exe, contents); } case T_TOUCH: { if (args.count() != 2) { @@ -1769,7 +1780,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( valuesRef(ProKey("_QMAKE_STASH_")) << ProString(fn); } } - return writeFile(fL1S("cache "), fn, QIODevice::Append, varstr); + return writeFile(fL1S("cache "), fn, QIODevice::Append, false, varstr); } default: evalError(fL1S("Function '%1' is not implemented.").arg(function.toQString(m_tmp1))); diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index 8995d495829..b61c0661930 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -235,7 +235,7 @@ public: QMultiMap &rootSet) const; VisitReturn writeFile(const QString &ctx, const QString &fn, QIODevice::OpenMode mode, - const QString &contents); + bool exe, const QString &contents); #ifndef QT_BOOTSTRAPPED void runProcess(QProcess *proc, const QString &command) const; #endif diff --git a/qmake/library/qmakevfs.cpp b/qmake/library/qmakevfs.cpp index 613e4e90d79..d23d1f06ff3 100644 --- a/qmake/library/qmakevfs.cpp +++ b/qmake/library/qmakevfs.cpp @@ -52,8 +52,8 @@ QMakeVfs::QMakeVfs() { } -bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, const QString &contents, - QString *errStr) +bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, bool exe, + const QString &contents, QString *errStr) { #ifndef PROEVALUATOR_FULL # ifdef PROEVALUATOR_THREAD_SAFE @@ -75,8 +75,16 @@ bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, const QStr QByteArray bytes = contents.toLocal8Bit(); QFile cfile(fn); if (!(mode & QIODevice::Append) && cfile.open(QIODevice::ReadOnly | QIODevice::Text)) { - if (cfile.readAll() == bytes) + if (cfile.readAll() == bytes) { + if (exe) { + cfile.setPermissions(cfile.permissions() + | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther); + } else { + cfile.setPermissions(cfile.permissions() + & ~(QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther)); + } return true; + } cfile.close(); } if (!cfile.open(mode | QIODevice::WriteOnly | QIODevice::Text)) { @@ -89,6 +97,9 @@ bool QMakeVfs::writeFile(const QString &fn, QIODevice::OpenMode mode, const QStr *errStr = cfile.errorString(); return false; } + if (exe) + cfile.setPermissions(cfile.permissions() + | QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther); return true; #endif } diff --git a/qmake/library/qmakevfs.h b/qmake/library/qmakevfs.h index 8eeae15dccb..1bc11d35932 100644 --- a/qmake/library/qmakevfs.h +++ b/qmake/library/qmakevfs.h @@ -52,7 +52,7 @@ class QMAKE_EXPORT QMakeVfs public: QMakeVfs(); - bool writeFile(const QString &fn, QIODevice::OpenMode mode, const QString &contents, QString *errStr); + bool writeFile(const QString &fn, QIODevice::OpenMode mode, bool exe, const QString &contents, QString *errStr); bool readFile(const QString &fn, QString *contents, QString *errStr); bool exists(const QString &fn); diff --git a/tests/auto/tools/qmakelib/evaltest.cpp b/tests/auto/tools/qmakelib/evaltest.cpp index bed4c792a1e..beafef5ad23 100644 --- a/tests/auto/tools/qmakelib/evaltest.cpp +++ b/tests/auto/tools/qmakelib/evaltest.cpp @@ -2205,9 +2205,10 @@ void tst_qmakelib::addTestFunctions(const QString &qindir) << "" << true; + // FIXME: This also tests that 'exe' is accepted, but does not test whether it actually works. QTest::newRow("write_file(): append") << "VAR = 'one more line'\n" - "write_file(" + wpath + ", VAR, append): OK = 1\n" + "write_file(" + wpath + ", VAR, append exe): OK = 1\n" "OUT = $$cat(" + wpath + ", lines)" << "OK = 1\nOUT = 'other content' 'one more line'" << "" @@ -2227,7 +2228,13 @@ void tst_qmakelib::addTestFunctions(const QString &qindir) QTest::newRow("write_file(): bad number of arguments") << "write_file(1, 2, 3, 4): OK = 1" << "OK = UNDEF" - << "##:1: write_file(name, [content var, [append]]) requires one to three arguments." + << "##:1: write_file(name, [content var, [append] [exe]]) requires one to three arguments." + << true; + + QTest::newRow("write_file(): invalid flag") + << "write_file(file, VAR, fail): OK = 1" + << "OK = UNDEF" + << "##:1: write_file(): invalid flag fail." << true; // FIXME: This doesn't test whether it actually works. From 75e45cc2df06e9d85f4646146b34f8baf945ad03 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 7 Jan 2015 09:30:52 +0100 Subject: [PATCH 017/100] Add missing includes. After 90e7cc172a7521396bb2d49720ee4ceb9a9390b3, QStringList no longer includes QDataStream. This also reverts commit c1be0fbe7d17b67c330c0c90eb9ba8a0536c2121, which did the same in a worse way. Change-Id: Ib10622b0da3b3450d29fc65dc5356fde75444a8f Reviewed-by: Olivier Goffart (cherry picked from qttools/376501ae5a86859821c0e89b2e8fbc9906d11e07) Reviewed-by: Friedemann Kleint --- qmake/library/qmakeevaluator.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index b61c0661930..0a653ad6649 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -41,7 +41,6 @@ #include "qmakeparser.h" #include "ioutils.h" -#include #include #include #include @@ -52,6 +51,8 @@ #include #ifndef QT_BOOTSTRAPPED # include +#else +# include #endif #ifdef PROEVALUATOR_THREAD_SAFE # include From 86b2b5319d6654f6bc51e8b561c160eba39202a0 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 2 Sep 2013 16:52:47 +0200 Subject: [PATCH 018/100] make CONFIG feature evaluation failure non-fatal in cumulative mode while we evaluate the features themselves in precise mode (which is the reason why they can error out), we do not want them to terminate cumulative project evaluation. Change-Id: I70f3e1bcb2ca04a70c74ff484749ca92c1cf6372 Reviewed-by: hjk Reviewed-by: Oswald Buddenhagen (cherry picked from qttools/90ee4094161b427c32581bca2f5286edb4fffdb1) Reviewed-by: Joerg Bornemann --- qmake/library/qmakeevaluator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index e220d595174..4c5ce2e0978 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -1306,7 +1306,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateConfigFeatures() config.detach(); processed.insert(config); VisitReturn vr = evaluateFeatureFile(config, true); - if (vr == ReturnError) + if (vr == ReturnError && !m_cumulative) return vr; if (vr == ReturnTrue) { finished = false; From e5f3b653f0f5c7214041654e2132ac0781258499 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 2 Sep 2013 16:43:49 +0200 Subject: [PATCH 019/100] add enablers for printing project errors in cumulative mode this doesn't actually do anything in qmake. Change-Id: Ia14953a5a9dc31af56ad6c338017dd5b85bb4494 Reviewed-by: hjk Reviewed-by: Oswald Buddenhagen (cherry picked from qttools/08d0cb6f8e90a818bf6d3bec7a6d00f16419b8c0) Reviewed-by: Joerg Bornemann --- qmake/library/qmakebuiltins.cpp | 8 ++++++-- qmake/library/qmakeevaluator.h | 4 +++- qmake/library/qmakeparser.h | 5 +++-- qmake/option.cpp | 3 ++- qmake/option.h | 2 +- tests/auto/tools/qmakelib/tst_qmakelib.h | 4 ++-- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index e8be2f42fdf..02cd8a27606 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -1470,8 +1470,12 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( fputs(msg.toLatin1().constData(), stderr); #endif } else { - m_handler->fileMessage(fL1S("Project %1: %2") - .arg(function.toQString(m_tmp1).toUpper(), msg)); + m_handler->fileMessage( + (func_t == T_ERROR ? QMakeHandler::ErrorMessage : + func_t == T_WARNING ? QMakeHandler::WarningMessage : + QMakeHandler::InfoMessage) + | (m_cumulative ? QMakeHandler::CumulativeEvalMessage : 0), + fL1S("Project %1: %2").arg(function.toQString(m_tmp1).toUpper(), msg)); } } return (func_t == T_ERROR && !m_cumulative) ? ReturnError : ReturnTrue; diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index 0a653ad6649..9560f715875 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -68,6 +68,8 @@ public: enum { SourceEvaluator = 0x10, + CumulativeEvalMessage = 0x1000, + EvalWarnLanguage = SourceEvaluator | WarningMessage | WarnLanguage, EvalWarnDeprecated = SourceEvaluator | WarningMessage | WarnDeprecated, @@ -75,7 +77,7 @@ public: }; // error(), warning() and message() from .pro file - virtual void fileMessage(const QString &msg) = 0; + virtual void fileMessage(int type, const QString &msg) = 0; enum EvalFileType { EvalProjectFile, EvalIncludeFile, EvalConfigFile, EvalFeatureFile, EvalAuxFile }; virtual void aboutToEval(ProFile *parent, ProFile *proFile, EvalFileType type) = 0; diff --git a/qmake/library/qmakeparser.h b/qmake/library/qmakeparser.h index dfea1ddfdf8..7fa4f62a963 100644 --- a/qmake/library/qmakeparser.h +++ b/qmake/library/qmakeparser.h @@ -50,8 +50,9 @@ class QMAKE_EXPORT QMakeParserHandler public: enum { CategoryMask = 0xf00, - WarningMessage = 0x000, - ErrorMessage = 0x100, + InfoMessage = 0x100, + WarningMessage = 0x200, + ErrorMessage = 0x300, SourceMask = 0xf0, SourceParser = 0, diff --git a/qmake/option.cpp b/qmake/option.cpp index da59616e5ce..46bfa33dd39 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -601,8 +601,9 @@ void EvalHandler::message(int type, const QString &msg, const QString &fileName, fprintf(stderr, "%s%s\n", qPrintable(pfx), qPrintable(msg)); } -void EvalHandler::fileMessage(const QString &msg) +void EvalHandler::fileMessage(int type, const QString &msg) { + Q_UNUSED(type) fprintf(stderr, "%s\n", qPrintable(msg)); } diff --git a/qmake/option.h b/qmake/option.h index 663f096072d..cb3eb1341a6 100644 --- a/qmake/option.h +++ b/qmake/option.h @@ -67,7 +67,7 @@ class EvalHandler : public QMakeHandler { public: void message(int type, const QString &msg, const QString &fileName, int lineNo); - void fileMessage(const QString &msg); + void fileMessage(int type, const QString &msg); void aboutToEval(ProFile *, ProFile *, EvalFileType); void doneWithEval(ProFile *); diff --git a/tests/auto/tools/qmakelib/tst_qmakelib.h b/tests/auto/tools/qmakelib/tst_qmakelib.h index c4716ca65ef..b043d31e21f 100644 --- a/tests/auto/tools/qmakelib/tst_qmakelib.h +++ b/tests/auto/tools/qmakelib/tst_qmakelib.h @@ -90,8 +90,8 @@ public: virtual void message(int type, const QString &msg, const QString &fileName, int lineNo) { print(fileName, lineNo, type, msg); } - virtual void fileMessage(const QString &msg) - { doPrint(msg); } + virtual void fileMessage(int type, const QString &msg) + { Q_UNUSED(type) doPrint(msg); } virtual void aboutToEval(ProFile *, ProFile *, EvalFileType) {} virtual void doneWithEval(ProFile *) {} From 15163d1939d86cfdcebd64ed2fb2cbc0cd56808a Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 17 Dec 2015 16:11:25 -0800 Subject: [PATCH 020/100] QHeaderView and others: Fix font lookup name It should the the actual class name, without any suffix. This also allows us to use the painter font when rendering CE_HeaderLabel and, as a consequence, change QHeaderView's font through the usual methods. Change-Id: I0b13ee349f5fa505be66a9c884c26885f5fc468f Task-number: QTBUG-33855 Task-number: QTBUG-37153 Reviewed-by: Timur Pocheptsov Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/kernel/qapplication.cpp | 8 ++++---- src/widgets/styles/qmacstyle_mac.mm | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 4f13c06c15a..e20e820f12a 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -740,15 +740,15 @@ void QApplicationPrivate::initializeWidgetFontHash() if (const QFont *font = theme->font(QPlatformTheme::ItemViewFont)) fontHash->insert(QByteArrayLiteral("QAbstractItemView"), *font); if (const QFont *font = theme->font(QPlatformTheme::ListViewFont)) - fontHash->insert(QByteArrayLiteral("QListViewFont"), *font); + fontHash->insert(QByteArrayLiteral("QListView"), *font); if (const QFont *font = theme->font(QPlatformTheme::HeaderViewFont)) - fontHash->insert(QByteArrayLiteral("QHeaderViewFont"), *font); + fontHash->insert(QByteArrayLiteral("QHeaderView"), *font); if (const QFont *font = theme->font(QPlatformTheme::ListBoxFont)) fontHash->insert(QByteArrayLiteral("QListBox"), *font); if (const QFont *font = theme->font(QPlatformTheme::ComboMenuItemFont)) - fontHash->insert(QByteArrayLiteral("QComboMenuItemFont"), *font); + fontHash->insert(QByteArrayLiteral("QComboMenuItem"), *font); if (const QFont *font = theme->font(QPlatformTheme::ComboLineEditFont)) - fontHash->insert(QByteArrayLiteral("QComboLineEditFont"), *font); + fontHash->insert(QByteArrayLiteral("QComboLineEdit"), *font); if (const QFont *font = theme->font(QPlatformTheme::SmallFont)) fontHash->insert(QByteArrayLiteral("QSmallFont"), *font); if (const QFont *font = theme->font(QPlatformTheme::MiniFont)) diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm index 7fc4093e81f..ac23512f1d4 100644 --- a/src/widgets/styles/qmacstyle_mac.mm +++ b/src/widgets/styles/qmacstyle_mac.mm @@ -3698,7 +3698,6 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter textr.translate(pixmap.width() / pixmap.devicePixelRatio() + 2, 0); } - p->setFont(qt_app_fonts_hash()->value("QSmallFont", QFont())); proxy()->drawItemText(p, textr, header->textAlignment | Qt::AlignVCenter, header->palette, header->state & State_Enabled, header->text, QPalette::ButtonText); p->restore(); From ac2e991675565b42b673ce27054b7dad90685eca Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 18 Dec 2015 13:11:30 -0800 Subject: [PATCH 021/100] QHeaderView: Reset cached section sizes on font and style change Change-Id: I7ce88b7e43249499343a9aae6acb806dd9c41f31 Task-number: QTBUG-33855 Task-number: QTBUG-37153 Task-number: QTBUG-50010 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/itemviews/qheaderview.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 4cb28d08043..338627c79ff 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -2608,10 +2608,12 @@ bool QHeaderView::viewportEvent(QEvent *e) } return true; } #endif // QT_NO_STATUSTIP - case QEvent::Hide: - case QEvent::Show: case QEvent::FontChange: - case QEvent::StyleChange:{ + case QEvent::StyleChange: + d->invalidateCachedSizeHint(); + // Fall through + case QEvent::Hide: + case QEvent::Show: { QAbstractScrollArea *parent = qobject_cast(parentWidget()); if (parent && parent->isVisible()) // Only resize if we have a visible parent resizeSections(); From 4d9e06fa5346858bed41880917a850964acae225 Mon Sep 17 00:00:00 2001 From: David Faure Date: Thu, 5 Nov 2015 14:27:49 +0100 Subject: [PATCH 022/100] Docu: fix documentation of QHostAddress() default constructor. In Qt3 this would indeed be equivalent to QHostAddress("0.0.0.0"). But since Qt4, it creates an address of type Null, and QHostAddress()==QHostAddress("0.0.0.0") is no longer true. Change-Id: I28025421e77c861783c612c2225be345dad5615a Reviewed-by: Martin Smith --- src/network/kernel/qhostaddress.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index 935af04e31c..d775007f46c 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -379,7 +379,7 @@ void QNetmaskAddress::setPrefixLength(QAbstractSocket::NetworkLayerProtocol prot \value Any The dual stack any-address. A socket bound with this address will listen on both IPv4 and IPv6 interfaces. */ -/*! Constructs a host address object with the IP address 0.0.0.0. +/*! Constructs a null host address object, i.e. an address which is not valid for any host or interface. \sa clear() */ From 5f03b48cb38936e2e86143bec71d030876b84c8b Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 30 Nov 2015 13:49:33 +0100 Subject: [PATCH 023/100] QStandardPaths: warn if $XDG_RUNTIME_DIR doesn't exist If the environment variable is set, but points to a non-existing directory, the user would get a warning about chmod failing. Better be clear and warn about the fact that the directory itself doesn't exist. Also warn if $XDG_RUNTIME_DIR points to a file rather than a directory. Task-number: QTBUG-48771 Change-Id: If84e72d768528ea4b80260afbbc18709b7b738a8 Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qstandardpaths_unix.cpp | 30 ++++++++++++++----- .../io/qstandardpaths/tst_qstandardpaths.cpp | 23 ++++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp index ed2faa742aa..78f75482ea0 100644 --- a/src/corelib/io/qstandardpaths_unix.cpp +++ b/src/corelib/io/qstandardpaths_unix.cpp @@ -113,21 +113,33 @@ QString QStandardPaths::writableLocation(StandardLocation type) { const uid_t myUid = geteuid(); // http://standards.freedesktop.org/basedir-spec/latest/ + QFileInfo fileInfo; QString xdgRuntimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR")); if (xdgRuntimeDir.isEmpty()) { const QString userName = QFileSystemEngine::resolveUserName(myUid); xdgRuntimeDir = QDir::tempPath() + QLatin1String("/runtime-") + userName; - QDir dir(xdgRuntimeDir); - if (!dir.exists()) { + fileInfo.setFile(xdgRuntimeDir); + if (!fileInfo.isDir()) { if (!QDir().mkdir(xdgRuntimeDir)) { qWarning("QStandardPaths: error creating runtime directory %s: %s", qPrintable(xdgRuntimeDir), qPrintable(qt_error_string(errno))); return QString(); } } qWarning("QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '%s'", qPrintable(xdgRuntimeDir)); + } else { + fileInfo.setFile(xdgRuntimeDir); + if (!fileInfo.exists()) { + qWarning("QStandardPaths: XDG_RUNTIME_DIR points to non-existing path '%s', " + "please create it with 0700 permissions.", qPrintable(xdgRuntimeDir)); + return QString(); + } + if (!fileInfo.isDir()) { + qWarning("QStandardPaths: XDG_RUNTIME_DIR points to '%s' which is not a directory", + qPrintable(xdgRuntimeDir)); + return QString(); + } } // "The directory MUST be owned by the user" - QFileInfo fileInfo(xdgRuntimeDir); if (fileInfo.ownerId() != myUid) { qWarning("QStandardPaths: wrong ownership on runtime directory %s, %d instead of %d", qPrintable(xdgRuntimeDir), fileInfo.ownerId(), myUid); @@ -135,13 +147,15 @@ QString QStandardPaths::writableLocation(StandardLocation type) } // "and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700." // since the current user is the owner, set both xxxUser and xxxOwner - QFile file(xdgRuntimeDir); const QFile::Permissions wantedPerms = QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner; - if (file.permissions() != wantedPerms && !file.setPermissions(wantedPerms)) { - qWarning("QStandardPaths: could not set correct permissions on runtime directory %s: %s", - qPrintable(xdgRuntimeDir), qPrintable(file.errorString())); - return QString(); + if (fileInfo.permissions() != wantedPerms) { + QFile file(xdgRuntimeDir); + if (!file.setPermissions(wantedPerms)) { + qWarning("QStandardPaths: could not set correct permissions on runtime directory %s: %s", + qPrintable(xdgRuntimeDir), qPrintable(file.errorString())); + return QString(); + } } return xdgRuntimeDir; } diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index 24ff2f237fe..50c5b938e9d 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -464,6 +464,15 @@ void tst_qstandardpaths::testCustomRuntimeDirectory() #endif #ifdef Q_XDG_PLATFORM + struct EnvVarRestorer + { + EnvVarRestorer() : origRuntimeDir(qgetenv("XDG_RUNTIME_DIR")) {} + ~EnvVarRestorer() { qputenv("XDG_RUNTIME_DIR", origRuntimeDir.constData()); } + const QByteArray origRuntimeDir; + }; + EnvVarRestorer restorer; + + // When $XDG_RUNTIME_DIR points to a directory with wrong ownership, QStandardPaths should warn qputenv("XDG_RUNTIME_DIR", QFile::encodeName("/tmp")); // It's very unlikely that /tmp is 0600 or that we can chmod it // The call below outputs @@ -474,6 +483,20 @@ void tst_qstandardpaths::testCustomRuntimeDirectory() qPrintable(QString::fromLatin1("QStandardPaths: wrong ownership on runtime directory /tmp, 0 instead of %1").arg(uid))); const QString runtimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); QVERIFY2(runtimeDir.isEmpty(), qPrintable(runtimeDir)); + + // When $XDG_RUNTIME_DIR points to a non-existing directory, QStandardPaths should warn (QTBUG-48771) + qputenv("XDG_RUNTIME_DIR", "does_not_exist"); + QTest::ignoreMessage(QtWarningMsg, "QStandardPaths: XDG_RUNTIME_DIR points to non-existing path 'does_not_exist', please create it with 0700 permissions."); + const QString nonExistingRuntimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); + QVERIFY2(nonExistingRuntimeDir.isEmpty(), qPrintable(nonExistingRuntimeDir)); + + // When $XDG_RUNTIME_DIR points to a file, QStandardPaths should warn + const QString file = QFINDTESTDATA("tst_qstandardpaths.cpp"); + QVERIFY(!file.isEmpty()); + qputenv("XDG_RUNTIME_DIR", QFile::encodeName(file)); + QTest::ignoreMessage(QtWarningMsg, qPrintable(QString::fromLatin1("QStandardPaths: XDG_RUNTIME_DIR points to '%1' which is not a directory").arg(file))); + const QString noRuntimeDir = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); + QVERIFY2(noRuntimeDir.isEmpty(), qPrintable(file)); #endif } From 2e1de7f3c4cab55ce6b65f945cf0f444e6bee53a Mon Sep 17 00:00:00 2001 From: David Faure Date: Sun, 6 Dec 2015 14:37:58 +0100 Subject: [PATCH 024/100] QUrl: revert path-normalization in setPath(). Path normalization should happen only when NormalizePathSegments is set. Use a less intrusive fix for the setPath("//path") issue that commit aba336c2b4ad8 was about. This allows fromLocalFile("/tmp/.") to keep the "/." at the end, which is useful for appending to the path later on (e.g. to get "/tmp/.hidden") Change-Id: Ibc3d4d3276c1d3aaee1774e21e24d01af38fa880 Reviewed-by: Thiago Macieira --- src/corelib/io/qurl.cpp | 6 ++- tests/auto/corelib/io/qurl/tst_qurl.cpp | 54 ++++++++++++++++++++----- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 9bf359222a4..775a870a271 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -2470,8 +2470,10 @@ void QUrl::setPath(const QString &path, ParsingMode mode) mode = TolerantMode; } - data = qt_normalizePathSegments(data, false); - d->setPath(data, 0, data.length()); + int from = 0; + while (from < data.length() - 2 && data.midRef(from, 2) == QLatin1String("//")) + ++from; + d->setPath(data, from, data.length()); // optimized out, since there is no path delimiter // if (path.isNull()) diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 7579c6713d5..031a35b3806 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -79,6 +79,8 @@ private slots: void toLocalFile(); void fromLocalFile_data(); void fromLocalFile(); + void fromLocalFileNormalize_data(); + void fromLocalFileNormalize(); void macTypes(); void relative(); void compat_legacy(); @@ -1242,16 +1244,6 @@ void tst_QUrl::fromLocalFile_data() << QString::fromLatin1("/"); QTest::newRow("data7") << QString::fromLatin1("/Mambo <#5>.mp3") << QString::fromLatin1("file:///Mambo <%235>.mp3") << QString::fromLatin1("/Mambo <#5>.mp3"); - QTest::newRow("data8") << QString::fromLatin1("/a%.txt") << QString::fromLatin1("file:///a%25.txt") - << QString::fromLatin1("/a%.txt"); - QTest::newRow("data9") << QString::fromLatin1("/a%25.txt") << QString::fromLatin1("file:///a%2525.txt") - << QString::fromLatin1("/a%25.txt"); - QTest::newRow("data10") << QString::fromLatin1("/%80.txt") << QString::fromLatin1("file:///%2580.txt") - << QString::fromLatin1("/%80.txt"); - QTest::newRow("data11") << QString::fromLatin1("./a.txt") << QString::fromLatin1("file:a.txt") << QString::fromLatin1("a.txt"); - QTest::newRow("data12") << QString::fromLatin1("././a.txt") << QString::fromLatin1("file:a.txt") << QString::fromLatin1("a.txt"); - QTest::newRow("data13") << QString::fromLatin1("b/../a.txt") << QString::fromLatin1("file:a.txt") << QString::fromLatin1("a.txt"); - QTest::newRow("data14") << QString::fromLatin1("/b/../a.txt") << QString::fromLatin1("file:///a.txt") << QString::fromLatin1("/a.txt"); } void tst_QUrl::fromLocalFile() @@ -1266,6 +1258,41 @@ void tst_QUrl::fromLocalFile() QCOMPARE(url.path(), thePath); } +void tst_QUrl::fromLocalFileNormalize_data() +{ + QTest::addColumn("theFile"); // should support the fromLocalFile/toLocalFile roundtrip (so no //host or windows path) + QTest::addColumn("theUrl"); + QTest::addColumn("urlWithNormalizedPath"); + + QTest::newRow("data0") << QString::fromLatin1("/a.txt") << QString::fromLatin1("file:///a.txt") << QString::fromLatin1("file:///a.txt"); + QTest::newRow("data1") << QString::fromLatin1("a.txt") << QString::fromLatin1("file:a.txt") << QString::fromLatin1("file:a.txt"); + QTest::newRow("data8") << QString::fromLatin1("/a%.txt") << QString::fromLatin1("file:///a%25.txt") + << QString::fromLatin1("file:///a%25.txt"); + QTest::newRow("data9") << QString::fromLatin1("/a%25.txt") << QString::fromLatin1("file:///a%2525.txt") + << QString::fromLatin1("file:///a%2525.txt"); + QTest::newRow("data10") << QString::fromLatin1("/%80.txt") << QString::fromLatin1("file:///%2580.txt") + << QString::fromLatin1("file:///%2580.txt"); + QTest::newRow("data11") << QString::fromLatin1("./a.txt") << QString::fromLatin1("file:./a.txt") << QString::fromLatin1("file:a.txt"); + QTest::newRow("data12") << QString::fromLatin1("././a.txt") << QString::fromLatin1("file:././a.txt") << QString::fromLatin1("file:a.txt"); + QTest::newRow("data13") << QString::fromLatin1("b/../a.txt") << QString::fromLatin1("file:b/../a.txt") << QString::fromLatin1("file:a.txt"); + QTest::newRow("data14") << QString::fromLatin1("/b/../a.txt") << QString::fromLatin1("file:///b/../a.txt") << QString::fromLatin1("file:///a.txt"); + QTest::newRow("data15") << QString::fromLatin1("/b/.") << QString::fromLatin1("file:///b/.") << QString::fromLatin1("file:///b"); +} + +void tst_QUrl::fromLocalFileNormalize() +{ + QFETCH(QString, theFile); + QFETCH(QString, theUrl); + QFETCH(QString, urlWithNormalizedPath); + + QUrl url = QUrl::fromLocalFile(theFile); + + QCOMPARE(url.toString(QUrl::DecodeReserved), theUrl); + QCOMPARE(url.toLocalFile(), theFile); // roundtrip + QCOMPARE(url.path(), theFile); // works as well as long as we don't test windows paths + QCOMPARE(url.toString(QUrl::NormalizePathSegments), urlWithNormalizedPath); +} + void tst_QUrl::macTypes() { #ifndef Q_OS_MAC @@ -2960,6 +2987,9 @@ void tst_QUrl::fromUserInputWithCwd_data() while (it.hasNext()) { it.next(); QUrl url = QUrl::fromLocalFile(it.filePath()); + if (it.fileName() == QLatin1String(".")) { + url = QUrl::fromLocalFile(QDir::currentPath()); // fromUserInput cleans the path + } QTest::newRow(QString("file-%1").arg(c++).toLatin1()) << it.fileName() << QDir::currentPath() << url << url; } QDir parent = QDir::current(); @@ -3021,6 +3051,8 @@ void tst_QUrl::fileName_data() << QString() << "tmp.txt" << "tmp.txt"; QTest::newRow("encoded") << "print:/specials/Print%20To%20File%20(PDF%252FAcrobat)" << "/specials/" << "Print To File (PDF%252FAcrobat)" << "Print To File (PDF%2FAcrobat)"; + QTest::newRow("endsWithDot") << "file:///temp/." + << "/temp/" << "." << "."; } void tst_QUrl::fileName() @@ -3513,7 +3545,7 @@ void tst_QUrl::setComponents_data() << PrettyDecoded << "/path" << "trash:/path"; QTest::newRow("path-withdotdot") << QUrl("file:///tmp") << int(Path) << "//tmp/..///root/." << Tolerant << true - << PrettyDecoded << "/root" << "file:///root"; + << PrettyDecoded << "/tmp/..///root/." << "file:///tmp/..///root/."; // the other fields can be present and be empty // that is, their delimiters would be present, but there would be nothing to one side From 26237f0a2d8db80024b601f676bbce54d483e672 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 20 Mar 2015 13:05:43 +0100 Subject: [PATCH 025/100] Fix QJsonValue::fromVariant() if the variant contains a json object If the variant contains a known json type (value, array, object or document), simply unwrap those. In the case of the json document wrap the contained object/array into a QJsonValue. This should be the expected behavior, and makes more sense than returning a null QJsonValue. Task-number: QTBUG-41234 Change-Id: Id084fc11220d51aaf78b7694fd0ebef1411f5c51 Reviewed-by: Thiago Macieira --- src/corelib/json/qjsonvalue.cpp | 12 ++++++++++++ tests/auto/corelib/json/tst_qtjson.cpp | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp index 328e07d18e7..76e5ae562fb 100644 --- a/src/corelib/json/qjsonvalue.cpp +++ b/src/corelib/json/qjsonvalue.cpp @@ -420,6 +420,18 @@ QJsonValue QJsonValue::fromVariant(const QVariant &variant) return QJsonValue(QJsonObject::fromVariantMap(variant.toMap())); case QVariant::Hash: return QJsonValue(QJsonObject::fromVariantHash(variant.toHash())); +#ifndef QT_BOOTSTRAPPED + case QMetaType::QJsonValue: + return variant.toJsonValue(); + case QMetaType::QJsonObject: + return variant.toJsonObject(); + case QMetaType::QJsonArray: + return variant.toJsonArray(); + case QMetaType::QJsonDocument: { + QJsonDocument doc = variant.toJsonDocument(); + return doc.isArray() ? QJsonValue(doc.array()) : QJsonValue(doc.object()); + } +#endif default: break; } diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index 884c4b38505..1665ff696d8 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -1137,6 +1137,12 @@ void tst_QtJson::fromVariant() QCOMPARE(QJsonValue::fromVariant(QVariant(stringList)), QJsonValue(jsonArray_string)); QCOMPARE(QJsonValue::fromVariant(QVariant(variantList)), QJsonValue(jsonArray_variant)); QCOMPARE(QJsonValue::fromVariant(QVariant(variantMap)), QJsonValue(jsonObject)); + + QVERIFY(QJsonValue::fromVariant(QVariant(QJsonValue(true))).isBool()); + QVERIFY(QJsonValue::fromVariant(QVariant(jsonArray_string)).isArray()); + QVERIFY(QJsonValue::fromVariant(QVariant(QJsonDocument(jsonArray_string))).isArray()); + QVERIFY(QJsonValue::fromVariant(QVariant(jsonObject)).isObject()); + QVERIFY(QJsonValue::fromVariant(QVariant(QJsonDocument(jsonObject))).isObject()); } void tst_QtJson::fromVariantMap() From f7a167223bd654bccb3c5bee7750eb86e6692d7a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 21 Dec 2015 15:59:13 +0100 Subject: [PATCH 026/100] tst_QTemporaryDir::nonWritableCurrentDir: Add a check for write protection. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit /home has been observed to be writable on some CI machines. Add checks verifying existence and correct permissions. Change-Id: Ie0f952e20d0d8eb0b57234eea2e2ecb78f5a7b58 Reviewed-by: Jędrzej Nowacki --- .../io/qtemporarydir/tst_qtemporarydir.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp index 58a3db9615c..621e215d60a 100644 --- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp +++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp @@ -229,6 +229,13 @@ void tst_QTemporaryDir::autoRemove() void tst_QTemporaryDir::nonWritableCurrentDir() { #ifdef Q_OS_UNIX + +# if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK) + const char nonWritableDir[] = "/data"; +# else + const char nonWritableDir[] = "/home"; +# endif + if (::geteuid() == 0) QSKIP("not valid running this test as root"); @@ -240,13 +247,13 @@ void tst_QTemporaryDir::nonWritableCurrentDir() } QString dir; }; - ChdirOnReturn cor(QDir::currentPath()); -#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK) - QDir::setCurrent("/data"); -#else - QDir::setCurrent("/home"); -#endif + const QFileInfo nonWritableDirFi = QFileInfo(QLatin1String(nonWritableDir)); + QVERIFY(nonWritableDirFi.isDir()); + QVERIFY(!nonWritableDirFi.isWritable()); + + ChdirOnReturn cor(QDir::currentPath()); + QVERIFY(QDir::setCurrent(nonWritableDirFi.absoluteFilePath())); // QTemporaryDir("tempXXXXXX") is probably a bad idea in any app // where the current dir could anything... QTemporaryDir dir("tempXXXXXX"); From f48170b479df359f47af12b03a501d9d0c386e66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Mon, 2 Nov 2015 00:26:39 +0100 Subject: [PATCH 027/100] xcb: Add Xinerama support This patch makes possible to use Xinerama screens in XCB platform plugin. Task-number: QTBUG-48615 Change-Id: Ib4dbfcdfadc46d2875a2fc09e8b852181edfbed2 Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/README | 6 +-- src/plugins/platforms/xcb/qxcbconnection.cpp | 54 +++++++++++++++++--- src/plugins/platforms/xcb/qxcbconnection.h | 2 + src/plugins/platforms/xcb/qxcbscreen.cpp | 26 +++++++--- src/plugins/platforms/xcb/qxcbscreen.h | 4 +- src/plugins/platforms/xcb/xcb_qpa_lib.pro | 2 +- 6 files changed, 75 insertions(+), 19 deletions(-) diff --git a/src/plugins/platforms/xcb/README b/src/plugins/platforms/xcb/README index 2f666bebfd4..15cf4cf2415 100644 --- a/src/plugins/platforms/xcb/README +++ b/src/plugins/platforms/xcb/README @@ -3,14 +3,14 @@ Requires libxcb >= 1.5. PACKAGE DEPENDENCIES Required packages: -libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev +libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm1 libxcb-icccm1-dev libxcb-sync0 libxcb-sync0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev libxcb-xinerama0-dev On Ubuntu 11.10 icccm1 is replaced by icccm4 and xcb-render-util is not available: -libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync0 libxcb-sync0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev +libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync0 libxcb-sync0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev libxcb-xinerama0-dev The packages for xcb-render-util can be installed manually from http://packages.ubuntu.com/natty/libxcb-render-util0 and http://packages.ubuntu.com/natty/libxcb-render-util0-dev On Ubuntu 12.04 icccm1 is replaced by icccm4 and xcb-render-util can be installed automatically: -libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync0 libxcb-sync0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-glx0-dev +libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync0 libxcb-sync0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-glx0-dev libxcb-xinerama0-dev On Fedora, the following packages are required: diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 231fe9af3f3..f93cfde4a59 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -60,6 +60,7 @@ #include #include #include +#include #ifdef XCB_USE_XLIB #include @@ -386,6 +387,7 @@ void QXcbConnection::initializeScreens() xcb_screen_t *xcbScreen = it.data; QXcbVirtualDesktop *virtualDesktop = new QXcbVirtualDesktop(this, xcbScreen, xcbScreenNumber); m_virtualDesktops.append(virtualDesktop); + QList siblings; if (has_randr_extension) { xcb_generic_error_t *error = NULL; // RRGetScreenResourcesCurrent is fast but it may return nothing if the @@ -429,7 +431,6 @@ void QXcbConnection::initializeScreens() qWarning("failed to get the primary output of the screen"); free(error); } else { - QList siblings; for (int i = 0; i < outputCount; i++) { QScopedPointer output( xcb_randr_get_output_info_reply(xcb_connection(), @@ -471,12 +472,30 @@ void QXcbConnection::initializeScreens() } } } - virtualDesktop->setScreens(siblings); } } } + } else if (has_xinerama_extension) { + // Xinerama is available + xcb_xinerama_query_screens_cookie_t cookie = xcb_xinerama_query_screens(m_connection); + xcb_xinerama_query_screens_reply_t *screens = xcb_xinerama_query_screens_reply(m_connection, + cookie, + Q_NULLPTR); + if (screens) { + xcb_xinerama_screen_info_iterator_t it = xcb_xinerama_query_screens_screen_info_iterator(screens); + while (it.rem) { + xcb_xinerama_screen_info_t *screen_info = it.data; + QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, + XCB_NONE, Q_NULLPTR, + screen_info, it.index); + siblings << screen; + m_screens << screen; + xcb_xinerama_screen_info_next(&it); + } + free(screens); + } } - if (virtualDesktop->screens().isEmpty()) { + if (siblings.isEmpty()) { // If there are no XRandR outputs or XRandR extension is missing, // then create a fake/legacy screen. QXcbScreen *screen = new QXcbScreen(this, virtualDesktop, XCB_NONE, Q_NULLPTR); @@ -486,8 +505,9 @@ void QXcbConnection::initializeScreens() primaryScreen = screen; primaryScreen->setPrimary(true); } - virtualDesktop->addScreen(screen); + siblings << screen; } + virtualDesktop->setScreens(siblings); xcb_screen_next(&it); ++xcbScreenNumber; } // for each xcb screen @@ -529,6 +549,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra , xfixes_first_event(0) , xrandr_first_event(0) , xkb_first_event(0) + , has_xinerama_extension(false) , has_shape_extension(false) , has_randr_extension(false) , has_input_shape(false) @@ -583,7 +604,10 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra m_time = XCB_CURRENT_TIME; m_netWmUserTime = XCB_CURRENT_TIME; - initializeXRandr(); + if (!qEnvironmentVariableIsSet("QT_XCB_NO_XRANDR")) + initializeXRandr(); + if (!has_randr_extension) + initializeXinerama(); initializeXFixes(); initializeScreens(); @@ -2087,6 +2111,22 @@ void QXcbConnection::initializeXRandr() } } +void QXcbConnection::initializeXinerama() +{ + const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xinerama_id); + if (!reply || !reply->present) + return; + + xcb_generic_error_t *error = Q_NULLPTR; + xcb_xinerama_is_active_cookie_t xinerama_query_cookie = xcb_xinerama_is_active(m_connection); + xcb_xinerama_is_active_reply_t *xinerama_is_active = xcb_xinerama_is_active_reply(m_connection, + xinerama_query_cookie, + &error); + has_xinerama_extension = xinerama_is_active && !error && xinerama_is_active->state; + free(error); + free(xinerama_is_active); +} + void QXcbConnection::initializeXShape() { const xcb_query_extension_reply_t *xshape_reply = xcb_get_extension_data(m_connection, &xcb_shape_id); @@ -2174,7 +2214,9 @@ void QXcbConnection::initializeXKB() bool QXcbConnection::xi2MouseEvents() const { static bool mouseViaXI2 = !qEnvironmentVariableIsSet("QT_XCB_NO_XI2_MOUSE"); - return mouseViaXI2; + // Don't use XInput2 when Xinerama extension is enabled, + // because it causes problems with multi-monitor setup. + return mouseViaXI2 && !has_xinerama_extension; } #if defined(XCB_USE_XINPUT2) diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index fb7cc137b97..6d26e88fa27 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -515,6 +515,7 @@ private: void initializeXFixes(); void initializeXRender(); void initializeXRandr(); + void initializeXinerama(); void initializeXShape(); void initializeXKB(); void handleClientMessageEvent(const xcb_client_message_event_t *event); @@ -639,6 +640,7 @@ private: uint32_t xrandr_first_event; uint32_t xkb_first_event; + bool has_xinerama_extension; bool has_shape_extension; bool has_randr_extension; bool has_input_shape; diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp index f05432ef685..caddd2b2a5d 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.cpp +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp @@ -155,8 +155,15 @@ void QXcbVirtualDesktop::updateWorkArea() } } +static inline QSizeF sizeInMillimeters(const QSize &size, const QDpi &dpi) +{ + return QSizeF(Q_MM_PER_INCH * size.width() / dpi.first, + Q_MM_PER_INCH * size.height() / dpi.second); +} + QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop, - xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output) + xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *output, + const xcb_xinerama_screen_info_t *xineramaScreenInfo, int xineramaScreenIdx) : QXcbObject(connection) , m_virtualDesktop(virtualDesktop) , m_output(outputId) @@ -188,8 +195,14 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe updateRefreshRate(crtc->mode); free(crtc); } - } else { - updateGeometry(output ? output->timestamp : 0); + } else if (xineramaScreenInfo) { + m_geometry = QRect(xineramaScreenInfo->x_org, xineramaScreenInfo->y_org, + xineramaScreenInfo->width, xineramaScreenInfo->height); + m_nativeGeometry = m_geometry; + m_availableGeometry = m_geometry & m_virtualDesktop->workArea(); + m_sizeMillimeters = sizeInMillimeters(m_geometry.size(), virtualDpi()); + if (xineramaScreenIdx > -1) + m_outputName += QLatin1Char('-') + QString::number(xineramaScreenIdx); } if (m_geometry.isEmpty()) { @@ -538,11 +551,8 @@ void QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation) // It can be that physical size is unknown while virtual size // is known (probably back-calculated from DPI and resolution), // e.g. on VNC or with some hardware. - if (m_sizeMillimeters.isEmpty()) { - QDpi dpi = virtualDpi(); - m_sizeMillimeters = QSizeF(Q_MM_PER_INCH * xGeometry.width() / dpi.first, - Q_MM_PER_INCH * xGeometry.width() / dpi.second); - } + if (m_sizeMillimeters.isEmpty()) + m_sizeMillimeters = sizeInMillimeters(xGeometry.size(), virtualDpi()); qreal dpi = xGeometry.width() / physicalSize().width() * qreal(25.4); m_pixelDensity = qRound(dpi/96); diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h index 79620f40ec1..dd7396aca27 100644 --- a/src/plugins/platforms/xcb/qxcbscreen.h +++ b/src/plugins/platforms/xcb/qxcbscreen.h @@ -40,6 +40,7 @@ #include #include #include +#include #include "qxcbobject.h" #include "qxcbscreen.h" @@ -102,7 +103,8 @@ class Q_XCB_EXPORT QXcbScreen : public QXcbObject, public QPlatformScreen { public: QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDesktop, - xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *outputInfo); + xcb_randr_output_t outputId, xcb_randr_get_output_info_reply_t *outputInfo, + const xcb_xinerama_screen_info_t *xineramaScreenInfo = Q_NULLPTR, int xineramaScreenIdx = -1); ~QXcbScreen(); QString getOutputName(xcb_randr_get_output_info_reply_t *outputInfo); diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index 60eb8a02e31..302d87e0079 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -92,7 +92,7 @@ contains(QT_CONFIG, xcb-qt) { INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static } else { - LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms + LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms -lxcb-xinerama !contains(DEFINES, QT_NO_XKB):LIBS += -lxcb-xkb } From ebe08096c94c6af43ee492c8939693a1bcbd893f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Mon, 16 Nov 2015 14:21:58 +0100 Subject: [PATCH 028/100] xcb: Add Xinerama 3rd party source code for static build Change-Id: I421d0bcf3fd6362ad6e95db5cfcdefd1a9ec096f Reviewed-by: Shawn Rutledge --- src/3rdparty/xcb/README | 2 +- src/3rdparty/xcb/include/xcb/xinerama.h | 808 ++++++++++++++++++ src/3rdparty/xcb/libxcb/xinerama.c | 655 ++++++++++++++ .../platforms/xcb/xcb-static/xcb-static.pro | 6 +- 4 files changed, 1468 insertions(+), 3 deletions(-) create mode 100644 src/3rdparty/xcb/include/xcb/xinerama.h create mode 100644 src/3rdparty/xcb/libxcb/xinerama.c diff --git a/src/3rdparty/xcb/README b/src/3rdparty/xcb/README index 4de7a17409d..d7c8eba294d 100644 --- a/src/3rdparty/xcb/README +++ b/src/3rdparty/xcb/README @@ -1,6 +1,6 @@ Contains the header and sources files from selected xcb libraries: - libxcb-1.5 together with xcb-proto-1.6 (sync, xfixes, randr sources) + libxcb-1.5 together with xcb-proto-1.6 (sync, xfixes, randr, xinerama sources) # libxkbcommon-x11 requires libxcb-xkb >= 1.10 libxcb-1.10 together with xcb-proto-1.10 (xkb sources) libxcb-util-image-0.3.9 diff --git a/src/3rdparty/xcb/include/xcb/xinerama.h b/src/3rdparty/xcb/include/xcb/xinerama.h new file mode 100644 index 00000000000..74da5458d2a --- /dev/null +++ b/src/3rdparty/xcb/include/xcb/xinerama.h @@ -0,0 +1,808 @@ +/* + * This file generated automatically from xinerama.xml by c_client.py. + * Edit at your peril. + */ + +/** + * @defgroup XCB_Xinerama_API XCB Xinerama API + * @brief Xinerama XCB Protocol Implementation. + * @{ + **/ + +#ifndef __XINERAMA_H +#define __XINERAMA_H + +#include "xcb.h" +#include "xproto.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define XCB_XINERAMA_MAJOR_VERSION 1 +#define XCB_XINERAMA_MINOR_VERSION 1 + +extern xcb_extension_t xcb_xinerama_id; + +/** + * @brief xcb_xinerama_screen_info_t + **/ +typedef struct xcb_xinerama_screen_info_t { + int16_t x_org; /**< */ + int16_t y_org; /**< */ + uint16_t width; /**< */ + uint16_t height; /**< */ +} xcb_xinerama_screen_info_t; + +/** + * @brief xcb_xinerama_screen_info_iterator_t + **/ +typedef struct xcb_xinerama_screen_info_iterator_t { + xcb_xinerama_screen_info_t *data; /**< */ + int rem; /**< */ + int index; /**< */ +} xcb_xinerama_screen_info_iterator_t; + +/** + * @brief xcb_xinerama_query_version_cookie_t + **/ +typedef struct xcb_xinerama_query_version_cookie_t { + unsigned int sequence; /**< */ +} xcb_xinerama_query_version_cookie_t; + +/** Opcode for xcb_xinerama_query_version. */ +#define XCB_XINERAMA_QUERY_VERSION 0 + +/** + * @brief xcb_xinerama_query_version_request_t + **/ +typedef struct xcb_xinerama_query_version_request_t { + uint8_t major_opcode; /**< */ + uint8_t minor_opcode; /**< */ + uint16_t length; /**< */ + uint8_t major; /**< */ + uint8_t minor; /**< */ +} xcb_xinerama_query_version_request_t; + +/** + * @brief xcb_xinerama_query_version_reply_t + **/ +typedef struct xcb_xinerama_query_version_reply_t { + uint8_t response_type; /**< */ + uint8_t pad0; /**< */ + uint16_t sequence; /**< */ + uint32_t length; /**< */ + uint16_t major; /**< */ + uint16_t minor; /**< */ +} xcb_xinerama_query_version_reply_t; + +/** + * @brief xcb_xinerama_get_state_cookie_t + **/ +typedef struct xcb_xinerama_get_state_cookie_t { + unsigned int sequence; /**< */ +} xcb_xinerama_get_state_cookie_t; + +/** Opcode for xcb_xinerama_get_state. */ +#define XCB_XINERAMA_GET_STATE 1 + +/** + * @brief xcb_xinerama_get_state_request_t + **/ +typedef struct xcb_xinerama_get_state_request_t { + uint8_t major_opcode; /**< */ + uint8_t minor_opcode; /**< */ + uint16_t length; /**< */ + xcb_window_t window; /**< */ +} xcb_xinerama_get_state_request_t; + +/** + * @brief xcb_xinerama_get_state_reply_t + **/ +typedef struct xcb_xinerama_get_state_reply_t { + uint8_t response_type; /**< */ + uint8_t state; /**< */ + uint16_t sequence; /**< */ + uint32_t length; /**< */ + xcb_window_t window; /**< */ +} xcb_xinerama_get_state_reply_t; + +/** + * @brief xcb_xinerama_get_screen_count_cookie_t + **/ +typedef struct xcb_xinerama_get_screen_count_cookie_t { + unsigned int sequence; /**< */ +} xcb_xinerama_get_screen_count_cookie_t; + +/** Opcode for xcb_xinerama_get_screen_count. */ +#define XCB_XINERAMA_GET_SCREEN_COUNT 2 + +/** + * @brief xcb_xinerama_get_screen_count_request_t + **/ +typedef struct xcb_xinerama_get_screen_count_request_t { + uint8_t major_opcode; /**< */ + uint8_t minor_opcode; /**< */ + uint16_t length; /**< */ + xcb_window_t window; /**< */ +} xcb_xinerama_get_screen_count_request_t; + +/** + * @brief xcb_xinerama_get_screen_count_reply_t + **/ +typedef struct xcb_xinerama_get_screen_count_reply_t { + uint8_t response_type; /**< */ + uint8_t screen_count; /**< */ + uint16_t sequence; /**< */ + uint32_t length; /**< */ + xcb_window_t window; /**< */ +} xcb_xinerama_get_screen_count_reply_t; + +/** + * @brief xcb_xinerama_get_screen_size_cookie_t + **/ +typedef struct xcb_xinerama_get_screen_size_cookie_t { + unsigned int sequence; /**< */ +} xcb_xinerama_get_screen_size_cookie_t; + +/** Opcode for xcb_xinerama_get_screen_size. */ +#define XCB_XINERAMA_GET_SCREEN_SIZE 3 + +/** + * @brief xcb_xinerama_get_screen_size_request_t + **/ +typedef struct xcb_xinerama_get_screen_size_request_t { + uint8_t major_opcode; /**< */ + uint8_t minor_opcode; /**< */ + uint16_t length; /**< */ + xcb_window_t window; /**< */ + uint32_t screen; /**< */ +} xcb_xinerama_get_screen_size_request_t; + +/** + * @brief xcb_xinerama_get_screen_size_reply_t + **/ +typedef struct xcb_xinerama_get_screen_size_reply_t { + uint8_t response_type; /**< */ + uint8_t pad0; /**< */ + uint16_t sequence; /**< */ + uint32_t length; /**< */ + uint32_t width; /**< */ + uint32_t height; /**< */ + xcb_window_t window; /**< */ + uint32_t screen; /**< */ +} xcb_xinerama_get_screen_size_reply_t; + +/** + * @brief xcb_xinerama_is_active_cookie_t + **/ +typedef struct xcb_xinerama_is_active_cookie_t { + unsigned int sequence; /**< */ +} xcb_xinerama_is_active_cookie_t; + +/** Opcode for xcb_xinerama_is_active. */ +#define XCB_XINERAMA_IS_ACTIVE 4 + +/** + * @brief xcb_xinerama_is_active_request_t + **/ +typedef struct xcb_xinerama_is_active_request_t { + uint8_t major_opcode; /**< */ + uint8_t minor_opcode; /**< */ + uint16_t length; /**< */ +} xcb_xinerama_is_active_request_t; + +/** + * @brief xcb_xinerama_is_active_reply_t + **/ +typedef struct xcb_xinerama_is_active_reply_t { + uint8_t response_type; /**< */ + uint8_t pad0; /**< */ + uint16_t sequence; /**< */ + uint32_t length; /**< */ + uint32_t state; /**< */ +} xcb_xinerama_is_active_reply_t; + +/** + * @brief xcb_xinerama_query_screens_cookie_t + **/ +typedef struct xcb_xinerama_query_screens_cookie_t { + unsigned int sequence; /**< */ +} xcb_xinerama_query_screens_cookie_t; + +/** Opcode for xcb_xinerama_query_screens. */ +#define XCB_XINERAMA_QUERY_SCREENS 5 + +/** + * @brief xcb_xinerama_query_screens_request_t + **/ +typedef struct xcb_xinerama_query_screens_request_t { + uint8_t major_opcode; /**< */ + uint8_t minor_opcode; /**< */ + uint16_t length; /**< */ +} xcb_xinerama_query_screens_request_t; + +/** + * @brief xcb_xinerama_query_screens_reply_t + **/ +typedef struct xcb_xinerama_query_screens_reply_t { + uint8_t response_type; /**< */ + uint8_t pad0; /**< */ + uint16_t sequence; /**< */ + uint32_t length; /**< */ + uint32_t number; /**< */ + uint8_t pad1[20]; /**< */ +} xcb_xinerama_query_screens_reply_t; + +/** + * Get the next element of the iterator + * @param i Pointer to a xcb_xinerama_screen_info_iterator_t + * + * Get the next element in the iterator. The member rem is + * decreased by one. The member data points to the next + * element. The member index is increased by sizeof(xcb_xinerama_screen_info_t) + */ + +/***************************************************************************** + ** + ** void xcb_xinerama_screen_info_next + ** + ** @param xcb_xinerama_screen_info_iterator_t *i + ** @returns void + ** + *****************************************************************************/ + +void +xcb_xinerama_screen_info_next (xcb_xinerama_screen_info_iterator_t *i /**< */); + +/** + * Return the iterator pointing to the last element + * @param i An xcb_xinerama_screen_info_iterator_t + * @return The iterator pointing to the last element + * + * Set the current element in the iterator to the last element. + * The member rem is set to 0. The member data points to the + * last element. + */ + +/***************************************************************************** + ** + ** xcb_generic_iterator_t xcb_xinerama_screen_info_end + ** + ** @param xcb_xinerama_screen_info_iterator_t i + ** @returns xcb_generic_iterator_t + ** + *****************************************************************************/ + +xcb_generic_iterator_t +xcb_xinerama_screen_info_end (xcb_xinerama_screen_info_iterator_t i /**< */); + +/** + * Delivers a request to the X server + * @param c The connection + * @return A cookie + * + * Delivers a request to the X server. + * + */ + +/***************************************************************************** + ** + ** xcb_xinerama_query_version_cookie_t xcb_xinerama_query_version + ** + ** @param xcb_connection_t *c + ** @param uint8_t major + ** @param uint8_t minor + ** @returns xcb_xinerama_query_version_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_query_version_cookie_t +xcb_xinerama_query_version (xcb_connection_t *c /**< */, + uint8_t major /**< */, + uint8_t minor /**< */); + +/** + * Delivers a request to the X server + * @param c The connection + * @return A cookie + * + * Delivers a request to the X server. + * + * This form can be used only if the request will cause + * a reply to be generated. Any returned error will be + * placed in the event queue. + */ + +/***************************************************************************** + ** + ** xcb_xinerama_query_version_cookie_t xcb_xinerama_query_version_unchecked + ** + ** @param xcb_connection_t *c + ** @param uint8_t major + ** @param uint8_t minor + ** @returns xcb_xinerama_query_version_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_query_version_cookie_t +xcb_xinerama_query_version_unchecked (xcb_connection_t *c /**< */, + uint8_t major /**< */, + uint8_t minor /**< */); + +/** + * Return the reply + * @param c The connection + * @param cookie The cookie + * @param e The xcb_generic_error_t supplied + * + * Returns the reply of the request asked by + * + * The parameter @p e supplied to this function must be NULL if + * xcb_xinerama_query_version_unchecked(). is used. + * Otherwise, it stores the error if any. + * + * The returned value must be freed by the caller using free(). + */ + +/***************************************************************************** + ** + ** xcb_xinerama_query_version_reply_t * xcb_xinerama_query_version_reply + ** + ** @param xcb_connection_t *c + ** @param xcb_xinerama_query_version_cookie_t cookie + ** @param xcb_generic_error_t **e + ** @returns xcb_xinerama_query_version_reply_t * + ** + *****************************************************************************/ + +xcb_xinerama_query_version_reply_t * +xcb_xinerama_query_version_reply (xcb_connection_t *c /**< */, + xcb_xinerama_query_version_cookie_t cookie /**< */, + xcb_generic_error_t **e /**< */); + +/** + * Delivers a request to the X server + * @param c The connection + * @return A cookie + * + * Delivers a request to the X server. + * + */ + +/***************************************************************************** + ** + ** xcb_xinerama_get_state_cookie_t xcb_xinerama_get_state + ** + ** @param xcb_connection_t *c + ** @param xcb_window_t window + ** @returns xcb_xinerama_get_state_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_get_state_cookie_t +xcb_xinerama_get_state (xcb_connection_t *c /**< */, + xcb_window_t window /**< */); + +/** + * Delivers a request to the X server + * @param c The connection + * @return A cookie + * + * Delivers a request to the X server. + * + * This form can be used only if the request will cause + * a reply to be generated. Any returned error will be + * placed in the event queue. + */ + +/***************************************************************************** + ** + ** xcb_xinerama_get_state_cookie_t xcb_xinerama_get_state_unchecked + ** + ** @param xcb_connection_t *c + ** @param xcb_window_t window + ** @returns xcb_xinerama_get_state_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_get_state_cookie_t +xcb_xinerama_get_state_unchecked (xcb_connection_t *c /**< */, + xcb_window_t window /**< */); + +/** + * Return the reply + * @param c The connection + * @param cookie The cookie + * @param e The xcb_generic_error_t supplied + * + * Returns the reply of the request asked by + * + * The parameter @p e supplied to this function must be NULL if + * xcb_xinerama_get_state_unchecked(). is used. + * Otherwise, it stores the error if any. + * + * The returned value must be freed by the caller using free(). + */ + +/***************************************************************************** + ** + ** xcb_xinerama_get_state_reply_t * xcb_xinerama_get_state_reply + ** + ** @param xcb_connection_t *c + ** @param xcb_xinerama_get_state_cookie_t cookie + ** @param xcb_generic_error_t **e + ** @returns xcb_xinerama_get_state_reply_t * + ** + *****************************************************************************/ + +xcb_xinerama_get_state_reply_t * +xcb_xinerama_get_state_reply (xcb_connection_t *c /**< */, + xcb_xinerama_get_state_cookie_t cookie /**< */, + xcb_generic_error_t **e /**< */); + +/** + * Delivers a request to the X server + * @param c The connection + * @return A cookie + * + * Delivers a request to the X server. + * + */ + +/***************************************************************************** + ** + ** xcb_xinerama_get_screen_count_cookie_t xcb_xinerama_get_screen_count + ** + ** @param xcb_connection_t *c + ** @param xcb_window_t window + ** @returns xcb_xinerama_get_screen_count_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_get_screen_count_cookie_t +xcb_xinerama_get_screen_count (xcb_connection_t *c /**< */, + xcb_window_t window /**< */); + +/** + * Delivers a request to the X server + * @param c The connection + * @return A cookie + * + * Delivers a request to the X server. + * + * This form can be used only if the request will cause + * a reply to be generated. Any returned error will be + * placed in the event queue. + */ + +/***************************************************************************** + ** + ** xcb_xinerama_get_screen_count_cookie_t xcb_xinerama_get_screen_count_unchecked + ** + ** @param xcb_connection_t *c + ** @param xcb_window_t window + ** @returns xcb_xinerama_get_screen_count_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_get_screen_count_cookie_t +xcb_xinerama_get_screen_count_unchecked (xcb_connection_t *c /**< */, + xcb_window_t window /**< */); + +/** + * Return the reply + * @param c The connection + * @param cookie The cookie + * @param e The xcb_generic_error_t supplied + * + * Returns the reply of the request asked by + * + * The parameter @p e supplied to this function must be NULL if + * xcb_xinerama_get_screen_count_unchecked(). is used. + * Otherwise, it stores the error if any. + * + * The returned value must be freed by the caller using free(). + */ + +/***************************************************************************** + ** + ** xcb_xinerama_get_screen_count_reply_t * xcb_xinerama_get_screen_count_reply + ** + ** @param xcb_connection_t *c + ** @param xcb_xinerama_get_screen_count_cookie_t cookie + ** @param xcb_generic_error_t **e + ** @returns xcb_xinerama_get_screen_count_reply_t * + ** + *****************************************************************************/ + +xcb_xinerama_get_screen_count_reply_t * +xcb_xinerama_get_screen_count_reply (xcb_connection_t *c /**< */, + xcb_xinerama_get_screen_count_cookie_t cookie /**< */, + xcb_generic_error_t **e /**< */); + +/** + * Delivers a request to the X server + * @param c The connection + * @return A cookie + * + * Delivers a request to the X server. + * + */ + +/***************************************************************************** + ** + ** xcb_xinerama_get_screen_size_cookie_t xcb_xinerama_get_screen_size + ** + ** @param xcb_connection_t *c + ** @param xcb_window_t window + ** @param uint32_t screen + ** @returns xcb_xinerama_get_screen_size_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_get_screen_size_cookie_t +xcb_xinerama_get_screen_size (xcb_connection_t *c /**< */, + xcb_window_t window /**< */, + uint32_t screen /**< */); + +/** + * Delivers a request to the X server + * @param c The connection + * @return A cookie + * + * Delivers a request to the X server. + * + * This form can be used only if the request will cause + * a reply to be generated. Any returned error will be + * placed in the event queue. + */ + +/***************************************************************************** + ** + ** xcb_xinerama_get_screen_size_cookie_t xcb_xinerama_get_screen_size_unchecked + ** + ** @param xcb_connection_t *c + ** @param xcb_window_t window + ** @param uint32_t screen + ** @returns xcb_xinerama_get_screen_size_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_get_screen_size_cookie_t +xcb_xinerama_get_screen_size_unchecked (xcb_connection_t *c /**< */, + xcb_window_t window /**< */, + uint32_t screen /**< */); + +/** + * Return the reply + * @param c The connection + * @param cookie The cookie + * @param e The xcb_generic_error_t supplied + * + * Returns the reply of the request asked by + * + * The parameter @p e supplied to this function must be NULL if + * xcb_xinerama_get_screen_size_unchecked(). is used. + * Otherwise, it stores the error if any. + * + * The returned value must be freed by the caller using free(). + */ + +/***************************************************************************** + ** + ** xcb_xinerama_get_screen_size_reply_t * xcb_xinerama_get_screen_size_reply + ** + ** @param xcb_connection_t *c + ** @param xcb_xinerama_get_screen_size_cookie_t cookie + ** @param xcb_generic_error_t **e + ** @returns xcb_xinerama_get_screen_size_reply_t * + ** + *****************************************************************************/ + +xcb_xinerama_get_screen_size_reply_t * +xcb_xinerama_get_screen_size_reply (xcb_connection_t *c /**< */, + xcb_xinerama_get_screen_size_cookie_t cookie /**< */, + xcb_generic_error_t **e /**< */); + +/** + * Delivers a request to the X server + * @param c The connection + * @return A cookie + * + * Delivers a request to the X server. + * + */ + +/***************************************************************************** + ** + ** xcb_xinerama_is_active_cookie_t xcb_xinerama_is_active + ** + ** @param xcb_connection_t *c + ** @returns xcb_xinerama_is_active_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_is_active_cookie_t +xcb_xinerama_is_active (xcb_connection_t *c /**< */); + +/** + * Delivers a request to the X server + * @param c The connection + * @return A cookie + * + * Delivers a request to the X server. + * + * This form can be used only if the request will cause + * a reply to be generated. Any returned error will be + * placed in the event queue. + */ + +/***************************************************************************** + ** + ** xcb_xinerama_is_active_cookie_t xcb_xinerama_is_active_unchecked + ** + ** @param xcb_connection_t *c + ** @returns xcb_xinerama_is_active_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_is_active_cookie_t +xcb_xinerama_is_active_unchecked (xcb_connection_t *c /**< */); + +/** + * Return the reply + * @param c The connection + * @param cookie The cookie + * @param e The xcb_generic_error_t supplied + * + * Returns the reply of the request asked by + * + * The parameter @p e supplied to this function must be NULL if + * xcb_xinerama_is_active_unchecked(). is used. + * Otherwise, it stores the error if any. + * + * The returned value must be freed by the caller using free(). + */ + +/***************************************************************************** + ** + ** xcb_xinerama_is_active_reply_t * xcb_xinerama_is_active_reply + ** + ** @param xcb_connection_t *c + ** @param xcb_xinerama_is_active_cookie_t cookie + ** @param xcb_generic_error_t **e + ** @returns xcb_xinerama_is_active_reply_t * + ** + *****************************************************************************/ + +xcb_xinerama_is_active_reply_t * +xcb_xinerama_is_active_reply (xcb_connection_t *c /**< */, + xcb_xinerama_is_active_cookie_t cookie /**< */, + xcb_generic_error_t **e /**< */); + +/** + * Delivers a request to the X server + * @param c The connection + * @return A cookie + * + * Delivers a request to the X server. + * + */ + +/***************************************************************************** + ** + ** xcb_xinerama_query_screens_cookie_t xcb_xinerama_query_screens + ** + ** @param xcb_connection_t *c + ** @returns xcb_xinerama_query_screens_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_query_screens_cookie_t +xcb_xinerama_query_screens (xcb_connection_t *c /**< */); + +/** + * Delivers a request to the X server + * @param c The connection + * @return A cookie + * + * Delivers a request to the X server. + * + * This form can be used only if the request will cause + * a reply to be generated. Any returned error will be + * placed in the event queue. + */ + +/***************************************************************************** + ** + ** xcb_xinerama_query_screens_cookie_t xcb_xinerama_query_screens_unchecked + ** + ** @param xcb_connection_t *c + ** @returns xcb_xinerama_query_screens_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_query_screens_cookie_t +xcb_xinerama_query_screens_unchecked (xcb_connection_t *c /**< */); + + +/***************************************************************************** + ** + ** xcb_xinerama_screen_info_t * xcb_xinerama_query_screens_screen_info + ** + ** @param const xcb_xinerama_query_screens_reply_t *R + ** @returns xcb_xinerama_screen_info_t * + ** + *****************************************************************************/ + +xcb_xinerama_screen_info_t * +xcb_xinerama_query_screens_screen_info (const xcb_xinerama_query_screens_reply_t *R /**< */); + + +/***************************************************************************** + ** + ** int xcb_xinerama_query_screens_screen_info_length + ** + ** @param const xcb_xinerama_query_screens_reply_t *R + ** @returns int + ** + *****************************************************************************/ + +int +xcb_xinerama_query_screens_screen_info_length (const xcb_xinerama_query_screens_reply_t *R /**< */); + + +/***************************************************************************** + ** + ** xcb_xinerama_screen_info_iterator_t xcb_xinerama_query_screens_screen_info_iterator + ** + ** @param const xcb_xinerama_query_screens_reply_t *R + ** @returns xcb_xinerama_screen_info_iterator_t + ** + *****************************************************************************/ + +xcb_xinerama_screen_info_iterator_t +xcb_xinerama_query_screens_screen_info_iterator (const xcb_xinerama_query_screens_reply_t *R /**< */); + +/** + * Return the reply + * @param c The connection + * @param cookie The cookie + * @param e The xcb_generic_error_t supplied + * + * Returns the reply of the request asked by + * + * The parameter @p e supplied to this function must be NULL if + * xcb_xinerama_query_screens_unchecked(). is used. + * Otherwise, it stores the error if any. + * + * The returned value must be freed by the caller using free(). + */ + +/***************************************************************************** + ** + ** xcb_xinerama_query_screens_reply_t * xcb_xinerama_query_screens_reply + ** + ** @param xcb_connection_t *c + ** @param xcb_xinerama_query_screens_cookie_t cookie + ** @param xcb_generic_error_t **e + ** @returns xcb_xinerama_query_screens_reply_t * + ** + *****************************************************************************/ + +xcb_xinerama_query_screens_reply_t * +xcb_xinerama_query_screens_reply (xcb_connection_t *c /**< */, + xcb_xinerama_query_screens_cookie_t cookie /**< */, + xcb_generic_error_t **e /**< */); + + +#ifdef __cplusplus +} +#endif + +#endif + +/** + * @} + */ diff --git a/src/3rdparty/xcb/libxcb/xinerama.c b/src/3rdparty/xcb/libxcb/xinerama.c new file mode 100644 index 00000000000..05b6b737078 --- /dev/null +++ b/src/3rdparty/xcb/libxcb/xinerama.c @@ -0,0 +1,655 @@ +/* + * This file generated automatically from xinerama.xml by c_client.py. + * Edit at your peril. + */ + +#include +#include +#include "xcbext.h" +#include "xinerama.h" +#include "xproto.h" + +xcb_extension_t xcb_xinerama_id = { "XINERAMA", 0 }; + + +/***************************************************************************** + ** + ** void xcb_xinerama_screen_info_next + ** + ** @param xcb_xinerama_screen_info_iterator_t *i + ** @returns void + ** + *****************************************************************************/ + +void +xcb_xinerama_screen_info_next (xcb_xinerama_screen_info_iterator_t *i /**< */) +{ + --i->rem; + ++i->data; + i->index += sizeof(xcb_xinerama_screen_info_t); +} + + +/***************************************************************************** + ** + ** xcb_generic_iterator_t xcb_xinerama_screen_info_end + ** + ** @param xcb_xinerama_screen_info_iterator_t i + ** @returns xcb_generic_iterator_t + ** + *****************************************************************************/ + +xcb_generic_iterator_t +xcb_xinerama_screen_info_end (xcb_xinerama_screen_info_iterator_t i /**< */) +{ + xcb_generic_iterator_t ret; + ret.data = i.data + i.rem; + ret.index = i.index + ((char *) ret.data - (char *) i.data); + ret.rem = 0; + return ret; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_query_version_cookie_t xcb_xinerama_query_version + ** + ** @param xcb_connection_t *c + ** @param uint8_t major + ** @param uint8_t minor + ** @returns xcb_xinerama_query_version_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_query_version_cookie_t +xcb_xinerama_query_version (xcb_connection_t *c /**< */, + uint8_t major /**< */, + uint8_t minor /**< */) +{ + static const xcb_protocol_request_t xcb_req = { + /* count */ 2, + /* ext */ &xcb_xinerama_id, + /* opcode */ XCB_XINERAMA_QUERY_VERSION, + /* isvoid */ 0 + }; + + struct iovec xcb_parts[4]; + xcb_xinerama_query_version_cookie_t xcb_ret; + xcb_xinerama_query_version_request_t xcb_out; + + xcb_out.major = major; + xcb_out.minor = minor; + + xcb_parts[2].iov_base = (char *) &xcb_out; + xcb_parts[2].iov_len = sizeof(xcb_out); + xcb_parts[3].iov_base = 0; + xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; + xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req); + return xcb_ret; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_query_version_cookie_t xcb_xinerama_query_version_unchecked + ** + ** @param xcb_connection_t *c + ** @param uint8_t major + ** @param uint8_t minor + ** @returns xcb_xinerama_query_version_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_query_version_cookie_t +xcb_xinerama_query_version_unchecked (xcb_connection_t *c /**< */, + uint8_t major /**< */, + uint8_t minor /**< */) +{ + static const xcb_protocol_request_t xcb_req = { + /* count */ 2, + /* ext */ &xcb_xinerama_id, + /* opcode */ XCB_XINERAMA_QUERY_VERSION, + /* isvoid */ 0 + }; + + struct iovec xcb_parts[4]; + xcb_xinerama_query_version_cookie_t xcb_ret; + xcb_xinerama_query_version_request_t xcb_out; + + xcb_out.major = major; + xcb_out.minor = minor; + + xcb_parts[2].iov_base = (char *) &xcb_out; + xcb_parts[2].iov_len = sizeof(xcb_out); + xcb_parts[3].iov_base = 0; + xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; + xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req); + return xcb_ret; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_query_version_reply_t * xcb_xinerama_query_version_reply + ** + ** @param xcb_connection_t *c + ** @param xcb_xinerama_query_version_cookie_t cookie + ** @param xcb_generic_error_t **e + ** @returns xcb_xinerama_query_version_reply_t * + ** + *****************************************************************************/ + +xcb_xinerama_query_version_reply_t * +xcb_xinerama_query_version_reply (xcb_connection_t *c /**< */, + xcb_xinerama_query_version_cookie_t cookie /**< */, + xcb_generic_error_t **e /**< */) +{ + return (xcb_xinerama_query_version_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e); +} + + +/***************************************************************************** + ** + ** xcb_xinerama_get_state_cookie_t xcb_xinerama_get_state + ** + ** @param xcb_connection_t *c + ** @param xcb_window_t window + ** @returns xcb_xinerama_get_state_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_get_state_cookie_t +xcb_xinerama_get_state (xcb_connection_t *c /**< */, + xcb_window_t window /**< */) +{ + static const xcb_protocol_request_t xcb_req = { + /* count */ 2, + /* ext */ &xcb_xinerama_id, + /* opcode */ XCB_XINERAMA_GET_STATE, + /* isvoid */ 0 + }; + + struct iovec xcb_parts[4]; + xcb_xinerama_get_state_cookie_t xcb_ret; + xcb_xinerama_get_state_request_t xcb_out; + + xcb_out.window = window; + + xcb_parts[2].iov_base = (char *) &xcb_out; + xcb_parts[2].iov_len = sizeof(xcb_out); + xcb_parts[3].iov_base = 0; + xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; + xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req); + return xcb_ret; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_get_state_cookie_t xcb_xinerama_get_state_unchecked + ** + ** @param xcb_connection_t *c + ** @param xcb_window_t window + ** @returns xcb_xinerama_get_state_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_get_state_cookie_t +xcb_xinerama_get_state_unchecked (xcb_connection_t *c /**< */, + xcb_window_t window /**< */) +{ + static const xcb_protocol_request_t xcb_req = { + /* count */ 2, + /* ext */ &xcb_xinerama_id, + /* opcode */ XCB_XINERAMA_GET_STATE, + /* isvoid */ 0 + }; + + struct iovec xcb_parts[4]; + xcb_xinerama_get_state_cookie_t xcb_ret; + xcb_xinerama_get_state_request_t xcb_out; + + xcb_out.window = window; + + xcb_parts[2].iov_base = (char *) &xcb_out; + xcb_parts[2].iov_len = sizeof(xcb_out); + xcb_parts[3].iov_base = 0; + xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; + xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req); + return xcb_ret; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_get_state_reply_t * xcb_xinerama_get_state_reply + ** + ** @param xcb_connection_t *c + ** @param xcb_xinerama_get_state_cookie_t cookie + ** @param xcb_generic_error_t **e + ** @returns xcb_xinerama_get_state_reply_t * + ** + *****************************************************************************/ + +xcb_xinerama_get_state_reply_t * +xcb_xinerama_get_state_reply (xcb_connection_t *c /**< */, + xcb_xinerama_get_state_cookie_t cookie /**< */, + xcb_generic_error_t **e /**< */) +{ + return (xcb_xinerama_get_state_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e); +} + + +/***************************************************************************** + ** + ** xcb_xinerama_get_screen_count_cookie_t xcb_xinerama_get_screen_count + ** + ** @param xcb_connection_t *c + ** @param xcb_window_t window + ** @returns xcb_xinerama_get_screen_count_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_get_screen_count_cookie_t +xcb_xinerama_get_screen_count (xcb_connection_t *c /**< */, + xcb_window_t window /**< */) +{ + static const xcb_protocol_request_t xcb_req = { + /* count */ 2, + /* ext */ &xcb_xinerama_id, + /* opcode */ XCB_XINERAMA_GET_SCREEN_COUNT, + /* isvoid */ 0 + }; + + struct iovec xcb_parts[4]; + xcb_xinerama_get_screen_count_cookie_t xcb_ret; + xcb_xinerama_get_screen_count_request_t xcb_out; + + xcb_out.window = window; + + xcb_parts[2].iov_base = (char *) &xcb_out; + xcb_parts[2].iov_len = sizeof(xcb_out); + xcb_parts[3].iov_base = 0; + xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; + xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req); + return xcb_ret; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_get_screen_count_cookie_t xcb_xinerama_get_screen_count_unchecked + ** + ** @param xcb_connection_t *c + ** @param xcb_window_t window + ** @returns xcb_xinerama_get_screen_count_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_get_screen_count_cookie_t +xcb_xinerama_get_screen_count_unchecked (xcb_connection_t *c /**< */, + xcb_window_t window /**< */) +{ + static const xcb_protocol_request_t xcb_req = { + /* count */ 2, + /* ext */ &xcb_xinerama_id, + /* opcode */ XCB_XINERAMA_GET_SCREEN_COUNT, + /* isvoid */ 0 + }; + + struct iovec xcb_parts[4]; + xcb_xinerama_get_screen_count_cookie_t xcb_ret; + xcb_xinerama_get_screen_count_request_t xcb_out; + + xcb_out.window = window; + + xcb_parts[2].iov_base = (char *) &xcb_out; + xcb_parts[2].iov_len = sizeof(xcb_out); + xcb_parts[3].iov_base = 0; + xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; + xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req); + return xcb_ret; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_get_screen_count_reply_t * xcb_xinerama_get_screen_count_reply + ** + ** @param xcb_connection_t *c + ** @param xcb_xinerama_get_screen_count_cookie_t cookie + ** @param xcb_generic_error_t **e + ** @returns xcb_xinerama_get_screen_count_reply_t * + ** + *****************************************************************************/ + +xcb_xinerama_get_screen_count_reply_t * +xcb_xinerama_get_screen_count_reply (xcb_connection_t *c /**< */, + xcb_xinerama_get_screen_count_cookie_t cookie /**< */, + xcb_generic_error_t **e /**< */) +{ + return (xcb_xinerama_get_screen_count_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e); +} + + +/***************************************************************************** + ** + ** xcb_xinerama_get_screen_size_cookie_t xcb_xinerama_get_screen_size + ** + ** @param xcb_connection_t *c + ** @param xcb_window_t window + ** @param uint32_t screen + ** @returns xcb_xinerama_get_screen_size_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_get_screen_size_cookie_t +xcb_xinerama_get_screen_size (xcb_connection_t *c /**< */, + xcb_window_t window /**< */, + uint32_t screen /**< */) +{ + static const xcb_protocol_request_t xcb_req = { + /* count */ 2, + /* ext */ &xcb_xinerama_id, + /* opcode */ XCB_XINERAMA_GET_SCREEN_SIZE, + /* isvoid */ 0 + }; + + struct iovec xcb_parts[4]; + xcb_xinerama_get_screen_size_cookie_t xcb_ret; + xcb_xinerama_get_screen_size_request_t xcb_out; + + xcb_out.window = window; + xcb_out.screen = screen; + + xcb_parts[2].iov_base = (char *) &xcb_out; + xcb_parts[2].iov_len = sizeof(xcb_out); + xcb_parts[3].iov_base = 0; + xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; + xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req); + return xcb_ret; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_get_screen_size_cookie_t xcb_xinerama_get_screen_size_unchecked + ** + ** @param xcb_connection_t *c + ** @param xcb_window_t window + ** @param uint32_t screen + ** @returns xcb_xinerama_get_screen_size_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_get_screen_size_cookie_t +xcb_xinerama_get_screen_size_unchecked (xcb_connection_t *c /**< */, + xcb_window_t window /**< */, + uint32_t screen /**< */) +{ + static const xcb_protocol_request_t xcb_req = { + /* count */ 2, + /* ext */ &xcb_xinerama_id, + /* opcode */ XCB_XINERAMA_GET_SCREEN_SIZE, + /* isvoid */ 0 + }; + + struct iovec xcb_parts[4]; + xcb_xinerama_get_screen_size_cookie_t xcb_ret; + xcb_xinerama_get_screen_size_request_t xcb_out; + + xcb_out.window = window; + xcb_out.screen = screen; + + xcb_parts[2].iov_base = (char *) &xcb_out; + xcb_parts[2].iov_len = sizeof(xcb_out); + xcb_parts[3].iov_base = 0; + xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; + xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req); + return xcb_ret; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_get_screen_size_reply_t * xcb_xinerama_get_screen_size_reply + ** + ** @param xcb_connection_t *c + ** @param xcb_xinerama_get_screen_size_cookie_t cookie + ** @param xcb_generic_error_t **e + ** @returns xcb_xinerama_get_screen_size_reply_t * + ** + *****************************************************************************/ + +xcb_xinerama_get_screen_size_reply_t * +xcb_xinerama_get_screen_size_reply (xcb_connection_t *c /**< */, + xcb_xinerama_get_screen_size_cookie_t cookie /**< */, + xcb_generic_error_t **e /**< */) +{ + return (xcb_xinerama_get_screen_size_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e); +} + + +/***************************************************************************** + ** + ** xcb_xinerama_is_active_cookie_t xcb_xinerama_is_active + ** + ** @param xcb_connection_t *c + ** @returns xcb_xinerama_is_active_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_is_active_cookie_t +xcb_xinerama_is_active (xcb_connection_t *c /**< */) +{ + static const xcb_protocol_request_t xcb_req = { + /* count */ 2, + /* ext */ &xcb_xinerama_id, + /* opcode */ XCB_XINERAMA_IS_ACTIVE, + /* isvoid */ 0 + }; + + struct iovec xcb_parts[4]; + xcb_xinerama_is_active_cookie_t xcb_ret; + xcb_xinerama_is_active_request_t xcb_out; + + + xcb_parts[2].iov_base = (char *) &xcb_out; + xcb_parts[2].iov_len = sizeof(xcb_out); + xcb_parts[3].iov_base = 0; + xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; + xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req); + return xcb_ret; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_is_active_cookie_t xcb_xinerama_is_active_unchecked + ** + ** @param xcb_connection_t *c + ** @returns xcb_xinerama_is_active_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_is_active_cookie_t +xcb_xinerama_is_active_unchecked (xcb_connection_t *c /**< */) +{ + static const xcb_protocol_request_t xcb_req = { + /* count */ 2, + /* ext */ &xcb_xinerama_id, + /* opcode */ XCB_XINERAMA_IS_ACTIVE, + /* isvoid */ 0 + }; + + struct iovec xcb_parts[4]; + xcb_xinerama_is_active_cookie_t xcb_ret; + xcb_xinerama_is_active_request_t xcb_out; + + + xcb_parts[2].iov_base = (char *) &xcb_out; + xcb_parts[2].iov_len = sizeof(xcb_out); + xcb_parts[3].iov_base = 0; + xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; + xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req); + return xcb_ret; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_is_active_reply_t * xcb_xinerama_is_active_reply + ** + ** @param xcb_connection_t *c + ** @param xcb_xinerama_is_active_cookie_t cookie + ** @param xcb_generic_error_t **e + ** @returns xcb_xinerama_is_active_reply_t * + ** + *****************************************************************************/ + +xcb_xinerama_is_active_reply_t * +xcb_xinerama_is_active_reply (xcb_connection_t *c /**< */, + xcb_xinerama_is_active_cookie_t cookie /**< */, + xcb_generic_error_t **e /**< */) +{ + return (xcb_xinerama_is_active_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e); +} + + +/***************************************************************************** + ** + ** xcb_xinerama_query_screens_cookie_t xcb_xinerama_query_screens + ** + ** @param xcb_connection_t *c + ** @returns xcb_xinerama_query_screens_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_query_screens_cookie_t +xcb_xinerama_query_screens (xcb_connection_t *c /**< */) +{ + static const xcb_protocol_request_t xcb_req = { + /* count */ 2, + /* ext */ &xcb_xinerama_id, + /* opcode */ XCB_XINERAMA_QUERY_SCREENS, + /* isvoid */ 0 + }; + + struct iovec xcb_parts[4]; + xcb_xinerama_query_screens_cookie_t xcb_ret; + xcb_xinerama_query_screens_request_t xcb_out; + + + xcb_parts[2].iov_base = (char *) &xcb_out; + xcb_parts[2].iov_len = sizeof(xcb_out); + xcb_parts[3].iov_base = 0; + xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; + xcb_ret.sequence = xcb_send_request(c, XCB_REQUEST_CHECKED, xcb_parts + 2, &xcb_req); + return xcb_ret; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_query_screens_cookie_t xcb_xinerama_query_screens_unchecked + ** + ** @param xcb_connection_t *c + ** @returns xcb_xinerama_query_screens_cookie_t + ** + *****************************************************************************/ + +xcb_xinerama_query_screens_cookie_t +xcb_xinerama_query_screens_unchecked (xcb_connection_t *c /**< */) +{ + static const xcb_protocol_request_t xcb_req = { + /* count */ 2, + /* ext */ &xcb_xinerama_id, + /* opcode */ XCB_XINERAMA_QUERY_SCREENS, + /* isvoid */ 0 + }; + + struct iovec xcb_parts[4]; + xcb_xinerama_query_screens_cookie_t xcb_ret; + xcb_xinerama_query_screens_request_t xcb_out; + + + xcb_parts[2].iov_base = (char *) &xcb_out; + xcb_parts[2].iov_len = sizeof(xcb_out); + xcb_parts[3].iov_base = 0; + xcb_parts[3].iov_len = -xcb_parts[2].iov_len & 3; + xcb_ret.sequence = xcb_send_request(c, 0, xcb_parts + 2, &xcb_req); + return xcb_ret; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_screen_info_t * xcb_xinerama_query_screens_screen_info + ** + ** @param const xcb_xinerama_query_screens_reply_t *R + ** @returns xcb_xinerama_screen_info_t * + ** + *****************************************************************************/ + +xcb_xinerama_screen_info_t * +xcb_xinerama_query_screens_screen_info (const xcb_xinerama_query_screens_reply_t *R /**< */) +{ + return (xcb_xinerama_screen_info_t *) (R + 1); +} + + +/***************************************************************************** + ** + ** int xcb_xinerama_query_screens_screen_info_length + ** + ** @param const xcb_xinerama_query_screens_reply_t *R + ** @returns int + ** + *****************************************************************************/ + +int +xcb_xinerama_query_screens_screen_info_length (const xcb_xinerama_query_screens_reply_t *R /**< */) +{ + return R->number; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_screen_info_iterator_t xcb_xinerama_query_screens_screen_info_iterator + ** + ** @param const xcb_xinerama_query_screens_reply_t *R + ** @returns xcb_xinerama_screen_info_iterator_t + ** + *****************************************************************************/ + +xcb_xinerama_screen_info_iterator_t +xcb_xinerama_query_screens_screen_info_iterator (const xcb_xinerama_query_screens_reply_t *R /**< */) +{ + xcb_xinerama_screen_info_iterator_t i; + i.data = (xcb_xinerama_screen_info_t *) (R + 1); + i.rem = R->number; + i.index = (char *) i.data - (char *) R; + return i; +} + + +/***************************************************************************** + ** + ** xcb_xinerama_query_screens_reply_t * xcb_xinerama_query_screens_reply + ** + ** @param xcb_connection_t *c + ** @param xcb_xinerama_query_screens_cookie_t cookie + ** @param xcb_generic_error_t **e + ** @returns xcb_xinerama_query_screens_reply_t * + ** + *****************************************************************************/ + +xcb_xinerama_query_screens_reply_t * +xcb_xinerama_query_screens_reply (xcb_connection_t *c /**< */, + xcb_xinerama_query_screens_cookie_t cookie /**< */, + xcb_generic_error_t **e /**< */) +{ + return (xcb_xinerama_query_screens_reply_t *) xcb_wait_for_reply(c, cookie.sequence, e); +} + diff --git a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro index d0fe282b147..20481e48344 100644 --- a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro +++ b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro @@ -1,7 +1,8 @@ # # Statically compile in code for # libxcb-fixes, libxcb-randr, libxcb-shm, libxcb-sync, libxcb-image, -# libxcb-keysyms, libxcb-icccm, libxcb-renderutil, libxcb-xkb +# libxcb-keysyms, libxcb-icccm, libxcb-renderutil, libxcb-xkb, +# libxcb-xinerama # CONFIG += static load(qt_helper_lib) @@ -28,7 +29,8 @@ SOURCES += \ $$LIBXCB_DIR/sync.c \ $$LIBXCB_DIR/render.c \ $$LIBXCB_DIR/shape.c \ - $$LIBXCB_DIR/xkb.c + $$LIBXCB_DIR/xkb.c \ + $$LIBXCB_DIR/xinerama.c # # xcb-util From a2d218cc41c97f184465611c13d6dbbc2a72d858 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 23 Dec 2015 02:12:35 +0100 Subject: [PATCH 029/100] tst_collections: "explicit instantiation of 'NS::QList' must occur in namespace 'NS'" Probably correct. The question is just why this code has survived for so many years. Change-Id: Iaf01850476f9b066243abebb9ee6c5928d7ada19 Reviewed-by: Simon Hausmann --- tests/auto/corelib/tools/collections/tst_collections.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/corelib/tools/collections/tst_collections.cpp b/tests/auto/corelib/tools/collections/tst_collections.cpp index ae8ffe48be7..b9487cee33a 100644 --- a/tests/auto/corelib/tools/collections/tst_collections.cpp +++ b/tests/auto/corelib/tools/collections/tst_collections.cpp @@ -90,7 +90,9 @@ void foo() #include "qvector.h" #include "qqueue.h" +QT_BEGIN_NAMESPACE template class QList; +QT_END_NAMESPACE class tst_Collections : public QObject { From 27479c13237692d91ba385e8eef82221d7de2d19 Mon Sep 17 00:00:00 2001 From: Alex Trotsenko Date: Tue, 22 Dec 2015 10:56:26 +0200 Subject: [PATCH 030/100] Enable a test for QFilePrivate::fileName offset on 32 bit Linux Change-Id: I3577ff7126263ddbe4b7714095480e6f1da7b661 Reviewed-by: hjk --- tests/auto/other/toolsupport/tst_toolsupport.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/other/toolsupport/tst_toolsupport.cpp b/tests/auto/other/toolsupport/tst_toolsupport.cpp index f3c99af8ba6..92127fcd5c2 100644 --- a/tests/auto/other/toolsupport/tst_toolsupport.cpp +++ b/tests/auto/other/toolsupport/tst_toolsupport.cpp @@ -111,7 +111,7 @@ void tst_toolsupport::offsets_data() } #ifdef Q_OS_LINUX - if (sizeof(void *) == 8) { + { QTestData &data = QTest::newRow("QFilePrivate::fileName") << pmm_to_offsetof(&QFilePrivate::fileName); data << 168 << 248; From b1c156d692b21a04e31d5658ee6a73867e86e48f Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Sun, 20 Dec 2015 00:09:01 +0100 Subject: [PATCH 031/100] Default to OpenGLES when building with -opengl es2 Fixes the xcb_glx plugin to follow the -opengl configure option for default surface types. This makes it match closer to xcb_egl behavior and makes the default match QOpenGLContext::openGLModuleType. Change-Id: Iea3f8069fffefa46a32945eeeea1312566df129f Task-number: QTBUG-50015 Reviewed-by: Laszlo Agocs --- .../platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp index 37f01d4eed2..4cb220a02fb 100644 --- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qglxintegration.cpp @@ -175,7 +175,11 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat void QGLXContext::init(QXcbScreen *screen, QPlatformOpenGLContext *share) { if (m_format.renderableType() == QSurfaceFormat::DefaultRenderableType) +#if defined(QT_OPENGL_ES_2) + m_format.setRenderableType(QSurfaceFormat::OpenGLES); +#else m_format.setRenderableType(QSurfaceFormat::OpenGL); +#endif if (m_format.renderableType() != QSurfaceFormat::OpenGL && m_format.renderableType() != QSurfaceFormat::OpenGLES) return; From 959f09bbc5757bc42db603b2c085ad46fc12af96 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Thu, 17 Dec 2015 16:30:57 +0100 Subject: [PATCH 032/100] Remove CMake warning CMP0054 changes CMake behavior wrt. interpreting quoted arguments in if() statements. This change ensures that CMP0054 dev warnings are never emitted no matter how polluted the environment, e.g. even if the variable ${5.5.1} is defined and no matter whether CMP0054 is set to OLD, NEW or undefined. Change-Id: Iee008497b333e2db23fb1adbf8b02252314ffa8a Reviewed-by: Kevin Funk Reviewed-by: Stephen Kelly --- mkspecs/features/data/cmake/Qt5ConfigVersion.cmake.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/data/cmake/Qt5ConfigVersion.cmake.in b/mkspecs/features/data/cmake/Qt5ConfigVersion.cmake.in index e804754912e..7c42430e97b 100644 --- a/mkspecs/features/data/cmake/Qt5ConfigVersion.cmake.in +++ b/mkspecs/features/data/cmake/Qt5ConfigVersion.cmake.in @@ -1,11 +1,11 @@ set(PACKAGE_VERSION $$CMAKE_PACKAGE_VERSION) -if(\"\${PACKAGE_VERSION}\" VERSION_LESS \"\${PACKAGE_FIND_VERSION}\") +if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION) set(PACKAGE_VERSION_COMPATIBLE FALSE) else() set(PACKAGE_VERSION_COMPATIBLE TRUE) - if(\"\${PACKAGE_FIND_VERSION}\" STREQUAL \"\${PACKAGE_VERSION}\") + if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION) set(PACKAGE_VERSION_EXACT TRUE) endif() endif() From 9871c3d8bd71ab265d7394495a3a9f0c2963f6ab Mon Sep 17 00:00:00 2001 From: Kevin Funk Date: Mon, 2 Nov 2015 09:41:01 +0100 Subject: [PATCH 033/100] CMake: Add -fPIC to CXX flags only where necessary Before this patch, Qt5Core_EXECUTABLE_COMPILE_FLAGS was populated with -fPIC unconditionally. This causes warnings on MSVC, since the compiler does not understand this flag. In fact, -fPIC is only required in case an older release of CMake is being used and the compiler is GCC 5.x (according to documentation), so let's really add it just in this case. Task-number: QTBUG-47942 Change-Id: I9d09b8b257a0647235d6d781ee5c023af34f8f88 Reviewed-by: Stephen Kelly --- src/corelib/Qt5CoreConfigExtras.cmake.in | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index 65fd1f93838..91a4eb619a1 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -70,7 +70,14 @@ set(_qt5_corelib_extra_includes) # Qt5_POSITION_INDEPENDENT_CODE variable is used in the # qt5_use_module # macro to add it. set(Qt5_POSITION_INDEPENDENT_CODE True) -set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") + +# On x86 and x86-64 systems with ELF binaries (especially Linux), due to +# a new optimization in GCC 5.x in combination with a recent version of +# GNU binutils, compiling Qt applications with -fPIE is no longer +# enough. +# Applications now need to be compiled with the -fPIC option if the Qt option +# \"reduce relocations\" is active. For backward compatibility only, Qt accepts +# the use of -fPIE for GCC 4.x versions. if (CMAKE_VERSION VERSION_LESS 2.8.12 AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\" OR CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)) @@ -79,6 +86,20 @@ else() set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $$QMAKE_CXXFLAGS_APP) endif() +# Applications using qmake or cmake >= 2.8.12 as their build system will +# adapt automatically. Applications using an older release of cmake in +# combination with GCC 5.x need to change their CMakeLists.txt to add +# Qt5Core_EXECUTABLE_COMPILE_FLAGS to CMAKE_CXX_FLAGS. In particular, +# applications using cmake >= 2.8.9 and < 2.8.11 will continue to build +# with the -fPIE option and invoke the special compatibility mode if using +# GCC 4.x. +set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"\") +if (CMAKE_VERSION VERSION_LESS 2.8.12 + AND (CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\" + AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)) + set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") +endif() + !!IF !isEmpty(QT_NAMESPACE) list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) list(APPEND Qt5Core_COMPILE_DEFINITIONS QT_NAMESPACE=$$QT_NAMESPACE) From 72b4f0d4743826ee14ec06bf0ada26418f4a69be Mon Sep 17 00:00:00 2001 From: David Faure Date: Mon, 30 Nov 2015 12:03:18 +0100 Subject: [PATCH 034/100] QMimeDatabase: follow symlinks when checking for FIFO etc. This was documented, but not what the code did. Task-number: QTBUG-48529 Change-Id: I4849778c61dcae13be27c62b24717693c0c07d78 Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/mimetypes/qmimedatabase.cpp | 3 ++- .../qmimedatabase/tst_qmimedatabase.cpp | 27 +++++++++++++++++++ .../qmimedatabase/tst_qmimedatabase.h | 1 + 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index c1e17b9fc4d..fd11dbc787b 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -354,9 +354,10 @@ QMimeType QMimeDatabase::mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mo #ifdef Q_OS_UNIX // Cannot access statBuf.st_mode from the filesystem engine, so we have to stat again. + // In addition we want to follow symlinks. const QByteArray nativeFilePath = QFile::encodeName(file.fileName()); QT_STATBUF statBuffer; - if (QT_LSTAT(nativeFilePath.constData(), &statBuffer) == 0) { + if (QT_STAT(nativeFilePath.constData(), &statBuffer) == 0) { if (S_ISCHR(statBuffer.st_mode)) return d->mimeTypeForName(QLatin1String("inode/chardevice")); if (S_ISBLK(statBuffer.st_mode)) diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index 0171c4ac5ae..1b4dc020f2c 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -35,6 +35,11 @@ #include "qstandardpaths.h" +#ifdef Q_OS_UNIX +#include +#include +#endif + #include #include #include @@ -646,6 +651,28 @@ void tst_QMimeDatabase::knownSuffix() QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.tar.bz2")), QString::fromLatin1("tar.bz2")); } +void tst_QMimeDatabase::symlinkToFifo() // QTBUG-48529 +{ +#ifdef Q_OS_UNIX + QTemporaryDir tempDir; + QVERIFY(tempDir.isValid()); + const QString dir = tempDir.path(); + const QString fifo = dir + "/fifo"; + QCOMPARE(mkfifo(QFile::encodeName(fifo), 0006), 0); + + QMimeDatabase db; + QCOMPARE(db.mimeTypeForFile(fifo).name(), QString::fromLatin1("inode/fifo")); + + // Now make a symlink to the fifo + const QString link = dir + "/link"; + QVERIFY(QFile::link(fifo, link)); + QCOMPARE(db.mimeTypeForFile(link).name(), QString::fromLatin1("inode/fifo")); + +#else + QSKIP("This test requires pipes and symlinks"); +#endif +} + void tst_QMimeDatabase::findByFileName_data() { QTest::addColumn("filePath"); diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h index 2827bd2dc40..4b703f15d79 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h @@ -70,6 +70,7 @@ private slots: void suffixes_data(); void suffixes(); void knownSuffix(); + void symlinkToFifo(); void fromThreads(); // shared-mime-info test suite From 83da3e5edaf568b4a8c6aec8e0750fa45c726a27 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 28 Dec 2015 13:23:28 -0200 Subject: [PATCH 035/100] Change a QList of pointers to QVector QList of pointers is optimum, but QVector should provide the same performance (we aren't using the beginning-of-list feature that QList has and QVector doesn't). But since we're using QVector elsewhere, this should be better. Change-Id: I39cc61d0d59846ab8c23ffff14241c6715e2eb00 Reviewed-by: Marc Mutz --- src/dbus/qdbusconnection_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 91824c5c79c..0371f5ece01 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -174,7 +174,7 @@ public: typedef QMultiHash SignalHookHash; typedef QHash MetaObjectHash; typedef QHash MatchRefCountHash; - typedef QList PendingCallList; + typedef QVector PendingCallList; struct WatchedServiceData { WatchedServiceData() : refcount(0) {} From 982fefe69d5fd679e473bd7826aaf78a56779610 Mon Sep 17 00:00:00 2001 From: Frank Meerkoetter Date: Mon, 28 Dec 2015 20:04:46 +0100 Subject: [PATCH 036/100] Cleanup memory owned by QTestTablePrivate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since 7a42c8c15c59ef5fe84e6f293f2c97d38b85599c QTestTablePrivate no longer cleans up the memory it holds in dataList. This will make tools such as valgrind/address-sanitizer generate a lot of noise about directly or indirectly leaked memory. Change-Id: Ic0900ecdd7b76cda9f5366f3950bccde2f1b244c Reviewed-by: Jędrzej Nowacki --- src/testlib/qtesttable.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/testlib/qtesttable.cpp b/src/testlib/qtesttable.cpp index d20bdd84679..05cce37a47d 100644 --- a/src/testlib/qtesttable.cpp +++ b/src/testlib/qtesttable.cpp @@ -46,6 +46,11 @@ QT_BEGIN_NAMESPACE class QTestTablePrivate { public: + ~QTestTablePrivate() + { + qDeleteAll(dataList.begin(), dataList.end()); + } + struct Element { Element() : name(Q_NULLPTR), type(0) {} Element(const char *n, int t) : name(n), type(t) {} From a6b2a4642f07cd6e52b447e1e441b257990a8d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Sun, 25 Oct 2015 01:11:28 +0200 Subject: [PATCH 037/100] Fix incorrect screen number reported by QDesktopWidget Screens connected to separate graphics cards are detected as separate screens which don't have offset. This patch fixes obtaining the screen number by QWidget: it uses the screen assigned to the root widget. The patch also assigns a proper QScreen to each QDesktopWidget screen(). It also fixes closing a popup menu by clicking on another screen. Task-number: QTBUG-48545 Change-Id: I3d76261c0c067293d39949c4428b2d8dfd085dc7 Reviewed-by: Shawn Rutledge --- src/widgets/kernel/qdesktopwidget.cpp | 31 ++++++++++++++++++++++----- src/widgets/widgets/qmenu.cpp | 6 +++++- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp index b88b3cc61d9..d21e60198ed 100644 --- a/src/widgets/kernel/qdesktopwidget.cpp +++ b/src/widgets/kernel/qdesktopwidget.cpp @@ -36,6 +36,7 @@ #include "qdesktopwidget_p.h" #include "qscreen.h" #include "qwidget_p.h" +#include "qwindow.h" QT_BEGIN_NAMESPACE @@ -99,13 +100,18 @@ void QDesktopWidgetPrivate::_q_updateScreens() QRegion virtualGeometry; - // update the geometry of each screen widget, determine virtual geometry - // and emit change signals afterwards. + // update the geometry of each screen widget, determine virtual geometry, + // set the new screen for window handle and emit change signals afterwards. QList changedScreens; for (int i = 0; i < screens.length(); i++) { - const QRect screenGeometry = screenList.at(i)->geometry(); - if (screenGeometry != screens.at(i)->geometry()) { - screens.at(i)->setGeometry(screenGeometry); + QDesktopScreenWidget *screenWidget = screens.at(i); + QScreen *qScreen = screenList.at(i); + QWindow *winHandle = screenWidget->windowHandle(); + if (winHandle && winHandle->screen() != qScreen) + winHandle->setScreen(qScreen); + const QRect screenGeometry = qScreen->geometry(); + if (screenGeometry != screenWidget->geometry()) { + screenWidget->setGeometry(screenGeometry); changedScreens.push_back(i); } virtualGeometry += screenGeometry; @@ -191,6 +197,21 @@ int QDesktopWidget::screenNumber(const QWidget *w) const if (!w) return 0; + // Find the root widget, get a QScreen pointer from it and find + // the screen number. + const QWidget *root = w; + const QWidget *tmp = w; + while ((tmp = tmp->parentWidget())) + root = tmp; + QWindow *winHandle = root->windowHandle(); + if (winHandle) { + int screenIdx = QGuiApplication::screens().indexOf(winHandle->screen()); + if (screenIdx > -1) + return screenIdx; + } + + // If the screen number cannot be obtained using QScreen pointer, + // get it from window position using screen geometry. QRect frame = w->frameGeometry(); if (!w->isWindow()) frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0))); diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index 4239e7f3d42..ea3e4c44885 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -2586,7 +2586,11 @@ void QMenu::mousePressEvent(QMouseEvent *e) Q_D(QMenu); if (d->aboutToHide || d->mouseEventTaken(e)) return; - if (!rect().contains(e->pos())) { + // Workaround for XCB on multiple screens which doesn't have offset. If the menu is open on one screen + // and mouse clicks on second screen, e->pos() is QPoint(0,0) and the menu doesn't hide. This trick makes + // possible to hide the menu when mouse clicks on another screen (e->screenPos() returns correct value). + // Only when mouse clicks in QPoint(0,0) on second screen, the menu doesn't hide. + if ((e->pos().isNull() && !e->screenPos().isNull()) || !rect().contains(e->pos())) { if (d->noReplayFor && QRect(d->noReplayFor->mapToGlobal(QPoint()), d->noReplayFor->size()).contains(e->globalPos())) setAttribute(Qt::WA_NoMouseReplay); From cbc4750f52964e6e7e13e296e526de98ef538cd4 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Thu, 24 Dec 2015 00:15:44 +0100 Subject: [PATCH 038/100] QSocks5SocketEngine: Always try to connect in connectToHost unless already connecting. Otherwise, connectInternal becomes a no-op after an initial connection attempt has been made (making the socket effectively useless if that connection attempt fails). A workaround is to close() the socket, which worked by virtue of QAbstractSocket's close() disconnecting (which ultimately calls resetSocketLayer, and destroys the socket engine instance) - meaning that the next connection attempt would have a fresh socks instance to try out the connection with. Reported-by: Gabe Edwards Change-Id: Iab1e84af6d4248fd75a6dfe5e79a3c73129aae0b Reviewed-by: Richard J. Moore --- src/network/socket/qsocks5socketengine.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index 26543883cc1..6868e8c73a3 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -1111,14 +1111,16 @@ bool QSocks5SocketEngine::connectInternal() } } - if (d->socks5State == QSocks5SocketEnginePrivate::Uninitialized - && d->socketState != QAbstractSocket::ConnectingState) { - setState(QAbstractSocket::ConnectingState); - //limit buffer in internal socket, data is buffered in the external socket under application control - d->data->controlSocket->setReadBufferSize(65536); + if (d->socketState != QAbstractSocket::ConnectingState) { + if (d->socks5State == QSocks5SocketEnginePrivate::Uninitialized) { + setState(QAbstractSocket::ConnectingState); + //limit buffer in internal socket, data is buffered in the external socket under application control + d->data->controlSocket->setReadBufferSize(65536); + } + d->data->controlSocket->connectToHost(d->proxyInfo.hostName(), d->proxyInfo.port()); - return false; } + return false; } From 1568b09f1c1be5a8891e7cc75288c6a2b6bf60de Mon Sep 17 00:00:00 2001 From: Frank Meerkoetter Date: Wed, 30 Dec 2015 20:44:33 +0100 Subject: [PATCH 039/100] Correctly flag WinPhone Fixes coverity CID21703. Change-Id: If9587c7cc49768066273a97fc56c3a662104f439 Reviewed-by: Andrew Knight Reviewed-by: Maurice Kalinowski --- qmake/generators/win32/msbuild_objectmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index aad6e6e8787..8e2be589cdd 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -628,7 +628,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) << tagValue("Platform", tool.SingleProjects.at(i).PlatformName) << closetag(); isWinRT = isWinRT || tool.SingleProjects.at(i).Configuration.WinRT; - isWinPhone = isWinPhone = tool.SingleProjects.at(i).Configuration.WinPhone; + isWinPhone = isWinPhone || tool.SingleProjects.at(i).Configuration.WinPhone; } xml << closetag() From fd3ea7004dd9c1c5bd6e18a39fb02b230ef603a4 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 28 Dec 2015 13:14:16 -0200 Subject: [PATCH 040/100] Remove unused member variable QDBusConnectionPrivate::timeoutsPendingAdd They're never pending, since we add them immediately since commit 186d8814407ccb3e221537d9797172c37127bc51. Change-Id: I39cc61d0d59846ab8c23ffff14241be6785ad5a0 Reviewed-by: Lorn Potter --- src/dbus/qdbusconnection_p.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 0371f5ece01..2df7a49966e 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -169,7 +169,6 @@ public: // typedefs typedef QMultiHash WatcherHash; typedef QHash TimeoutHash; - typedef QVector > PendingTimeoutList; typedef QMultiHash SignalHookHash; typedef QHash MetaObjectHash; @@ -309,7 +308,6 @@ public: }; WatcherHash watchers; TimeoutHash timeouts; - PendingTimeoutList timeoutsPendingAdd; // the master lock protects our own internal state QReadWriteLock lock; From 8d195c0d57ea241183d23c45f855be1b126d8ee7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 28 Dec 2015 13:38:08 -0200 Subject: [PATCH 041/100] Add a default argument to QDBusPendingCallWatcher::finished signal So we can do connect(&watcher, SIGNAL(finished()), receiver, SLOT(foo())); Change-Id: I39cc61d0d59846ab8c23ffff14241d33fecf2d53 Reviewed-by: Lorn Potter --- src/dbus/qdbuspendingcall.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dbus/qdbuspendingcall.h b/src/dbus/qdbuspendingcall.h index 3bcacffd224..d7d68825be6 100644 --- a/src/dbus/qdbuspendingcall.h +++ b/src/dbus/qdbuspendingcall.h @@ -106,7 +106,7 @@ public: void waitForFinished(); // non-virtual override Q_SIGNALS: - void finished(QDBusPendingCallWatcher *self); + void finished(QDBusPendingCallWatcher *self = Q_NULLPTR); private: Q_DECLARE_PRIVATE(QDBusPendingCallWatcher) From 1f6fa1f37a14742ddf53c753ce52d9dc048cd1dc Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 27 Dec 2015 11:15:24 -0200 Subject: [PATCH 042/100] Suspend processing of some messages in the default busses by default To retain a bit compatibility with applications developed in the last 9 years that expect that QDBusConnections won't process their events until the event loop runs, we now suspend the handling of incoming messages in the two default buses (and only in them) and resume when the event loop starts. This is required because the new threaded QtDBus would otherwise process incoming messages that the application didn't expect it to. For example, if the application first acquires names on the bus and only after that registers objects with QtDBus, there's a small window in which the name is acquired and visible to other applications, but no objects are registered yet. Calls to those objects may be received, would then be processed in the QDBusConnectionManager thread and fail. The work around is to disable the actual handling of method calls and signals in QDBusConnectionPrivate::handleMessage. Instead, those messages are queued until later. Due to the way that libdbus-1 works, outgoing method calls that are waiting for replies are not affected, since their processing does not happen in handleMessage(). [ChangeLog][Important Behavior Changes] QtDBus now uses threads to implement processing of incoming and outgoing messages. This solves a number of thread safety issues and fixes an architectural problem that would cause all processing to stop if a particular thread (usually the main thread) were blocked in any operation. On the flip side, application developers need to know that modifications to a QDBusConnection may be visible immediately on the connection, so they should be done in an order that won't allow for incomplete states to be observed (for example, first register all objects, then acquire service names). Change-Id: I39cc61d0d59846ab8c23ffff1423c6d555f6ee0a Reviewed-by: David Faure --- src/dbus/qdbusconnection.cpp | 45 ++++++- src/dbus/qdbusconnection_p.h | 4 + src/dbus/qdbusconnectionmanager_p.h | 2 +- src/dbus/qdbusintegrator.cpp | 33 +++++- src/dbus/qdbusthreaddebug_p.h | 2 +- tests/auto/dbus/dbus.pro | 5 + .../qdbusconnection_delayed.pro | 5 + .../tst_qdbusconnection_delayed.cpp | 111 ++++++++++++++++++ 8 files changed, 200 insertions(+), 7 deletions(-) create mode 100644 tests/auto/dbus/qdbusconnection_delayed/qdbusconnection_delayed.pro create mode 100644 tests/auto/dbus/qdbusconnection_delayed/tst_qdbusconnection_delayed.cpp diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index e9196173ad5..0f2d799b922 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include "qdbusconnectioninterface.h" @@ -59,6 +60,24 @@ QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager) +// can be replaced with a lambda in Qt 5.7 +class QDBusConnectionDispatchEnabler : public QObject +{ + Q_OBJECT + QDBusConnectionPrivate *con; +public: + QDBusConnectionDispatchEnabler(QDBusConnectionPrivate *con) : con(con) {} + +public slots: + void execute() + { + con->setDispatchEnabled(true); + if (!con->ref.deref()) + con->deleteLater(); + deleteLater(); + } +}; + struct QDBusConnectionManager::ConnectionRequestData { enum RequestType { @@ -74,6 +93,8 @@ struct QDBusConnectionManager::ConnectionRequestData const QString *name; QDBusConnectionPrivate *result; + + bool suspendedDelivery; }; QDBusConnectionPrivate *QDBusConnectionManager::busConnection(QDBusConnection::BusType type) @@ -84,6 +105,10 @@ QDBusConnectionPrivate *QDBusConnectionManager::busConnection(QDBusConnection::B if (!qdbus_loadLibDBus()) return 0; + // we'll start in suspended delivery mode if we're in the main thread + // (the event loop will resume delivery) + bool suspendedDelivery = qApp && qApp->thread() == QThread::currentThread(); + QMutexLocker lock(&defaultBusMutex); if (defaultBuses[type]) return defaultBuses[type]; @@ -91,7 +116,7 @@ QDBusConnectionPrivate *QDBusConnectionManager::busConnection(QDBusConnection::B QString name = QStringLiteral("qt_default_session_bus"); if (type == QDBusConnection::SystemBus) name = QStringLiteral("qt_default_system_bus"); - return defaultBuses[type] = connectToBus(type, name); + return defaultBuses[type] = connectToBus(type, name, suspendedDelivery); } QDBusConnectionPrivate *QDBusConnectionManager::connection(const QString &name) const @@ -169,14 +194,22 @@ void QDBusConnectionManager::run() moveToThread(Q_NULLPTR); } -QDBusConnectionPrivate *QDBusConnectionManager::connectToBus(QDBusConnection::BusType type, const QString &name) +QDBusConnectionPrivate *QDBusConnectionManager::connectToBus(QDBusConnection::BusType type, const QString &name, + bool suspendedDelivery) { ConnectionRequestData data; data.type = ConnectionRequestData::ConnectToStandardBus; data.busType = type; data.name = &name; + data.suspendedDelivery = suspendedDelivery; emit connectionRequested(&data); + if (suspendedDelivery) { + data.result->ref.ref(); + QDBusConnectionDispatchEnabler *o = new QDBusConnectionDispatchEnabler(data.result); + QTimer::singleShot(0, o, SLOT(execute())); + o->moveToThread(qApp->thread()); // qApp was checked in the caller + } return data.result; } @@ -186,6 +219,7 @@ QDBusConnectionPrivate *QDBusConnectionManager::connectToBus(const QString &addr data.type = ConnectionRequestData::ConnectToBusByAddress; data.busAddress = &address; data.name = &name; + data.suspendedDelivery = false; emit connectionRequested(&data); return data.result; @@ -197,6 +231,7 @@ QDBusConnectionPrivate *QDBusConnectionManager::connectToPeer(const QString &add data.type = ConnectionRequestData::ConnectToPeerByAddress; data.busAddress = &address; data.name = &name; + data.suspendedDelivery = false; emit connectionRequested(&data); return data.result; @@ -252,6 +287,8 @@ void QDBusConnectionManager::executeConnectionRequest(QDBusConnectionManager::Co // will lock in QDBusConnectionPrivate::connectRelay() d->setConnection(c, error); d->createBusService(); + if (data->suspendedDelivery) + d->setDispatchEnabled(false); } } @@ -456,7 +493,7 @@ QDBusConnection QDBusConnection::connectToBus(BusType type, const QString &name) QDBusConnectionPrivate *d = 0; return QDBusConnection(d); } - return QDBusConnection(_q_manager()->connectToBus(type, name)); + return QDBusConnection(_q_manager()->connectToBus(type, name, false)); } /*! @@ -1232,4 +1269,6 @@ QByteArray QDBusConnection::localMachineId() QT_END_NAMESPACE +#include "qdbusconnection.moc" + #endif // QT_NO_DBUS diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 2df7a49966e..f030a3ff8c0 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -169,6 +169,7 @@ public: // typedefs typedef QMultiHash WatcherHash; typedef QHash TimeoutHash; + typedef QVector PendingMessageList; typedef QMultiHash SignalHookHash; typedef QHash MetaObjectHash; @@ -191,6 +192,7 @@ public: ~QDBusConnectionPrivate(); void createBusService(); + void setDispatchEnabled(bool enable); void setPeer(DBusConnection *connection, const QDBusErrorInternal &error); void setConnection(DBusConnection *connection, const QDBusErrorInternal &error); void setServer(QDBusServer *object, DBusServer *server, const QDBusErrorInternal &error); @@ -308,6 +310,7 @@ public: }; WatcherHash watchers; TimeoutHash timeouts; + PendingMessageList pendingMessages; // the master lock protects our own internal state QReadWriteLock lock; @@ -322,6 +325,7 @@ public: PendingCallList pendingCalls; bool anonymousAuthenticationAllowed; + bool dispatchEnabled; // protected by the dispatch lock, not the main lock public: // static methods diff --git a/src/dbus/qdbusconnectionmanager_p.h b/src/dbus/qdbusconnectionmanager_p.h index 3f815fdcd76..c0ab48e4ee6 100644 --- a/src/dbus/qdbusconnectionmanager_p.h +++ b/src/dbus/qdbusconnectionmanager_p.h @@ -67,7 +67,7 @@ public: QDBusConnectionPrivate *connection(const QString &name) const; void removeConnection(const QString &name); void setConnection(const QString &name, QDBusConnectionPrivate *c); - QDBusConnectionPrivate *connectToBus(QDBusConnection::BusType type, const QString &name); + QDBusConnectionPrivate *connectToBus(QDBusConnection::BusType type, const QString &name, bool suspendedDelivery); QDBusConnectionPrivate *connectToBus(const QString &address, const QString &name); QDBusConnectionPrivate *connectToPeer(const QString &address, const QString &name); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index c465706913f..f6221d51b6f 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -496,6 +496,11 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg) if (!ref.load()) return false; + if (!dispatchEnabled && !QDBusMessagePrivate::isLocal(amsg)) { + // queue messages only, we'll handle them later + pendingMessages << amsg; + return amsg.type() == QDBusMessage::MethodCallMessage; + } switch (amsg.type()) { case QDBusMessage::SignalMessage: @@ -690,6 +695,20 @@ static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags, return -1; } +/*! + \internal + Enables or disables the delivery of incoming method calls and signals. If + \a enable is true, this will also cause any queued, pending messages to be + delivered. + */ +void QDBusConnectionPrivate::setDispatchEnabled(bool enable) +{ + QDBusDispatchLocker locker(SetDispatchEnabledAction, this); + dispatchEnabled = enable; + if (enable) + emit dispatchStatusChanged(); +} + static QDBusCallDeliveryEvent * const DIRECT_DELIVERY = (QDBusCallDeliveryEvent *)1; QDBusCallDeliveryEvent* QDBusConnectionPrivate::prepareReply(QDBusConnectionPrivate *target, @@ -946,7 +965,8 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p) : QObject(p), ref(1), capabilities(0), mode(InvalidMode), busService(0), dispatchLock(QMutex::Recursive), connection(0), rootNode(QString(QLatin1Char('/'))), - anonymousAuthenticationAllowed(false) + anonymousAuthenticationAllowed(false), + dispatchEnabled(true) { static const bool threads = q_dbus_threads_init_default(); if (::isDebugging == -1) @@ -1066,8 +1086,17 @@ void QDBusConnectionPrivate::timerEvent(QTimerEvent *e) void QDBusConnectionPrivate::doDispatch() { QDBusDispatchLocker locker(DoDispatchAction, this); - if (mode == ClientMode || mode == PeerMode) + if (mode == ClientMode || mode == PeerMode) { while (q_dbus_connection_dispatch(connection) == DBUS_DISPATCH_DATA_REMAINS) ; + if (dispatchEnabled && !pendingMessages.isEmpty()) { + // dispatch previously queued messages + PendingMessageList::Iterator it = pendingMessages.begin(); + PendingMessageList::Iterator end = pendingMessages.end(); + for ( ; it != end; ++it) + handleMessage(qMove(*it)); + pendingMessages.clear(); + } + } } void QDBusConnectionPrivate::socketRead(int fd) diff --git a/src/dbus/qdbusthreaddebug_p.h b/src/dbus/qdbusthreaddebug_p.h index eace25478d6..420f0626151 100644 --- a/src/dbus/qdbusthreaddebug_p.h +++ b/src/dbus/qdbusthreaddebug_p.h @@ -83,7 +83,7 @@ enum ThreadAction { HandleObjectCallPostEventAction = 22, HandleObjectCallSemaphoreAction = 23, DoDispatchAction = 24, - // unused: 25, + SetDispatchEnabledAction = 25, MessageResultReceivedAction = 26, ActivateSignalAction = 27, PendingCallBlockAction = 28, diff --git a/tests/auto/dbus/dbus.pro b/tests/auto/dbus/dbus.pro index bd1fef51937..ea8939bb9d4 100644 --- a/tests/auto/dbus/dbus.pro +++ b/tests/auto/dbus/dbus.pro @@ -1,5 +1,10 @@ TEMPLATE=subdirs + +# Run this test first SUBDIRS=\ + qdbusconnection_delayed + +SUBDIRS+=\ qdbusabstractadaptor \ qdbusabstractinterface \ qdbusconnection \ diff --git a/tests/auto/dbus/qdbusconnection_delayed/qdbusconnection_delayed.pro b/tests/auto/dbus/qdbusconnection_delayed/qdbusconnection_delayed.pro new file mode 100644 index 00000000000..71a75c644d0 --- /dev/null +++ b/tests/auto/dbus/qdbusconnection_delayed/qdbusconnection_delayed.pro @@ -0,0 +1,5 @@ +CONFIG += testcase parallel_test +TARGET = tst_qdbusconnection_delayed +QT = core dbus testlib +SOURCES += tst_qdbusconnection_delayed.cpp +DEFINES += SRCDIR=\\\"$$PWD/\\\" diff --git a/tests/auto/dbus/qdbusconnection_delayed/tst_qdbusconnection_delayed.cpp b/tests/auto/dbus/qdbusconnection_delayed/tst_qdbusconnection_delayed.cpp new file mode 100644 index 00000000000..a7492a48551 --- /dev/null +++ b/tests/auto/dbus/qdbusconnection_delayed/tst_qdbusconnection_delayed.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2015 Intel Corporation. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#ifdef Q_OS_WIN +# include +# define getpid _getpid +#else +# include +# include +#endif + +class tst_QDBusConnection_Delayed : public QObject +{ + Q_OBJECT +private slots: + void delayedMessages(); +}; + +class Foo : public QObject +{ + Q_OBJECT + Q_CLASSINFO("D-Bus Interface", "org.qtproject.tst_qdbusconnection_delayed.Foo") +public slots: + int bar() { return 42; } +}; + +static bool executedOnce = false; + +void tst_QDBusConnection_Delayed::delayedMessages() +{ + if (executedOnce) + QSKIP("This test can only be executed once"); + executedOnce = true; + + int argc = 1; + char *argv[] = { const_cast("tst_qdbusconnection_delayed"), 0 }; + QCoreApplication app(argc, argv); + + QDBusConnection session = QDBusConnection::sessionBus(); + QVERIFY(session.isConnected()); + QVERIFY(!session.baseService().isEmpty()); + + QDBusConnection other = QDBusConnection::connectToBus(QDBusConnection::SessionBus, "other"); + QVERIFY(other.isConnected()); + QVERIFY(!other.baseService().isEmpty()); + + QString name = "org.qtproject.tst_qdbusconnection_delayed-" + + QString::number(getpid()); + + // acquire a name in the main session bus connection + QVERIFY(session.registerService(name)); + QVERIFY(other.interface()->isServiceRegistered(name)); + + // make an asynchronous call to a yet-unregistered object + QDBusPendingCallWatcher pending(other.asyncCall(QDBusMessage::createMethodCall(name, "/foo", QString(), "bar"))); + + // sleep the main thread without running the event loop; + // the call must not be delivered + QTest::qSleep(1000); + QVERIFY(!pending.isFinished()); + + // now register the object + Foo foo; + session.registerObject("/foo", &foo, QDBusConnection::ExportAllSlots); + + connect(&pending, &QDBusPendingCallWatcher::finished, + &QTestEventLoop::instance(), &QTestEventLoop::exitLoop); + QTestEventLoop::instance().enterLoop(2); + QVERIFY(!QTestEventLoop::instance().timeout()); + QVERIFY(pending.isFinished()); + QVERIFY2(!pending.isError(), pending.error().name().toLatin1()); + QVERIFY(!pending.reply().arguments().isEmpty()); + QCOMPARE(pending.reply().arguments().at(0), QVariant(42)); +} + +QTEST_APPLESS_MAIN(tst_QDBusConnection_Delayed) + +#include "tst_qdbusconnection_delayed.moc" From 9510d99f088d328efab265745351a0fb21c9ae00 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 28 Dec 2015 14:40:56 -0200 Subject: [PATCH 043/100] Autotest: Mark D-Bus tests that don't connect to the bus as parallel There's no problem running them in parallel. Change-Id: I39cc61d0d59846ab8c23ffff142420a127ab6968 Reviewed-by: Lorn Potter --- .../auto/dbus/qdbusconnection_no_bus/qdbusconnection_no_bus.pro | 2 +- tests/auto/dbus/qdbusmetaobject/qdbusmetaobject.pro | 2 +- tests/auto/dbus/qdbusmetatype/qdbusmetatype.pro | 2 +- tests/auto/dbus/qdbustype/qdbustype.pro | 2 +- tests/auto/dbus/qdbusxmlparser/qdbusxmlparser.pro | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/auto/dbus/qdbusconnection_no_bus/qdbusconnection_no_bus.pro b/tests/auto/dbus/qdbusconnection_no_bus/qdbusconnection_no_bus.pro index 7b15a4fb81f..57712f0689b 100644 --- a/tests/auto/dbus/qdbusconnection_no_bus/qdbusconnection_no_bus.pro +++ b/tests/auto/dbus/qdbusconnection_no_bus/qdbusconnection_no_bus.pro @@ -1,4 +1,4 @@ -CONFIG += testcase +CONFIG += testcase parallel_test TARGET = tst_qdbusconnection_no_bus QT = core dbus testlib SOURCES += tst_qdbusconnection_no_bus.cpp diff --git a/tests/auto/dbus/qdbusmetaobject/qdbusmetaobject.pro b/tests/auto/dbus/qdbusmetaobject/qdbusmetaobject.pro index c0b38cf4789..26dd58a0102 100644 --- a/tests/auto/dbus/qdbusmetaobject/qdbusmetaobject.pro +++ b/tests/auto/dbus/qdbusmetaobject/qdbusmetaobject.pro @@ -1,4 +1,4 @@ -CONFIG += testcase +CONFIG += testcase parallel_test TARGET = tst_qdbusmetaobject QT = core dbus-private testlib SOURCES += tst_qdbusmetaobject.cpp diff --git a/tests/auto/dbus/qdbusmetatype/qdbusmetatype.pro b/tests/auto/dbus/qdbusmetatype/qdbusmetatype.pro index aef9bc73cbe..ac020b435ac 100644 --- a/tests/auto/dbus/qdbusmetatype/qdbusmetatype.pro +++ b/tests/auto/dbus/qdbusmetatype/qdbusmetatype.pro @@ -1,4 +1,4 @@ -CONFIG += testcase +CONFIG += testcase parallel_test TARGET = tst_qdbusmetatype QT = core dbus testlib SOURCES += tst_qdbusmetatype.cpp diff --git a/tests/auto/dbus/qdbustype/qdbustype.pro b/tests/auto/dbus/qdbustype/qdbustype.pro index 21df33d2c72..7db87d279ee 100644 --- a/tests/auto/dbus/qdbustype/qdbustype.pro +++ b/tests/auto/dbus/qdbustype/qdbustype.pro @@ -1,4 +1,4 @@ -CONFIG += testcase +CONFIG += testcase parallel_test TARGET = tst_qdbustype QT = core-private dbus-private testlib SOURCES += tst_qdbustype.cpp diff --git a/tests/auto/dbus/qdbusxmlparser/qdbusxmlparser.pro b/tests/auto/dbus/qdbusxmlparser/qdbusxmlparser.pro index a7186c341b4..6cdd09007c6 100644 --- a/tests/auto/dbus/qdbusxmlparser/qdbusxmlparser.pro +++ b/tests/auto/dbus/qdbusxmlparser/qdbusxmlparser.pro @@ -1,4 +1,4 @@ -CONFIG += testcase +CONFIG += testcase parallel_test TARGET = tst_qdbusxmlparser QT = core-private dbus-private xml testlib SOURCES += tst_qdbusxmlparser.cpp From 0828d4e8ea6d70ada3992445a02944ea03295613 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 28 Dec 2015 15:16:40 -0200 Subject: [PATCH 044/100] Autotest: test both libdbus-1 load failure and connection failure Change-Id: I39cc61d0d59846ab8c23ffff14242294649c1a45 Reviewed-by: Lorn Potter --- tests/auto/dbus/dbus.pro | 1 + .../qdbusconnection_no_bus/tst_qdbusconnection_no_bus.cpp | 4 +++- .../qdbusconnection_no_libdbus.pro | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tests/auto/dbus/qdbusconnection_no_libdbus/qdbusconnection_no_libdbus.pro diff --git a/tests/auto/dbus/dbus.pro b/tests/auto/dbus/dbus.pro index ea8939bb9d4..67cbc4bfef3 100644 --- a/tests/auto/dbus/dbus.pro +++ b/tests/auto/dbus/dbus.pro @@ -10,6 +10,7 @@ SUBDIRS+=\ qdbusconnection \ qdbusconnection_no_app \ qdbusconnection_no_bus \ + qdbusconnection_no_libdbus \ qdbuscontext \ qdbusinterface \ qdbuslocalcalls \ diff --git a/tests/auto/dbus/qdbusconnection_no_bus/tst_qdbusconnection_no_bus.cpp b/tests/auto/dbus/qdbusconnection_no_bus/tst_qdbusconnection_no_bus.cpp index 21f8f11f80c..5a740960596 100644 --- a/tests/auto/dbus/qdbusconnection_no_bus/tst_qdbusconnection_no_bus.cpp +++ b/tests/auto/dbus/qdbusconnection_no_bus/tst_qdbusconnection_no_bus.cpp @@ -52,7 +52,9 @@ public: tst_QDBusConnectionNoBus() { qputenv("DBUS_SESSION_BUS_ADDRESS", "unix:abstract=/tmp/does_not_exist"); +#ifdef SIMULATE_LOAD_FAIL qputenv("QT_SIMULATE_DBUS_LIBFAIL", "1"); +#endif } private slots: @@ -67,7 +69,7 @@ void tst_QDBusConnectionNoBus::connectToBus() QDBusConnection con = QDBusConnection::sessionBus(); - QVERIFY(true); // if we didn't crash here, the test passed :) + QVERIFY(!con.isConnected()); // if we didn't crash here, the test passed :) } QTEST_APPLESS_MAIN(tst_QDBusConnectionNoBus) diff --git a/tests/auto/dbus/qdbusconnection_no_libdbus/qdbusconnection_no_libdbus.pro b/tests/auto/dbus/qdbusconnection_no_libdbus/qdbusconnection_no_libdbus.pro new file mode 100644 index 00000000000..cb0eab1a187 --- /dev/null +++ b/tests/auto/dbus/qdbusconnection_no_libdbus/qdbusconnection_no_libdbus.pro @@ -0,0 +1,5 @@ +CONFIG += testcase parallel_test +TARGET = tst_qdbusconnection_no_libdbus +QT = core dbus testlib +DEFINES += SIMULATE_LOAD_FAIL +SOURCES += ../qdbusconnection_no_bus/tst_qdbusconnection_no_bus.cpp From 7e132066c1f7a811dd7c11918b4b0245cfd3162f Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Wed, 30 Dec 2015 09:25:16 +0300 Subject: [PATCH 045/100] QNativeSocketEngine: fix undefined variable on FreeBSD Change-Id: I192e20eef4db27fc19ec9a6e517ae5c8cb88897c Reviewed-by: Marc Mutz --- src/network/socket/qnativesocketengine_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 8626a6be0f3..6a740f4c30e 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -994,7 +994,7 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l # elif defined(IP_SENDSRCADDR) struct in_addr *data = reinterpret_cast(CMSG_DATA(cmsgptr)); cmsgptr->cmsg_type = IP_SENDSRCADDR; - addr->s_addr = htonl(header.senderAddress.toIPv4Address()); + data->s_addr = htonl(header.senderAddress.toIPv4Address()); # endif cmsgptr->cmsg_level = IPPROTO_IP; msg.msg_controllen += CMSG_SPACE(sizeof(*data)); From b08d84d39e11b6abab4e941050c22f37ca79a83a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 27 Dec 2015 11:15:24 -0200 Subject: [PATCH 046/100] Autotest: Make sure that we can place calls with disabled delivery This often happens in applications. Besides, we are expecting at least a call to RequestName to happen. Change-Id: Ifd2454ffba454fd591d0ffff1425a84563267d19 Reviewed-by: David Faure --- .../qdbusconnection_delayed/tst_qdbusconnection_delayed.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/auto/dbus/qdbusconnection_delayed/tst_qdbusconnection_delayed.cpp b/tests/auto/dbus/qdbusconnection_delayed/tst_qdbusconnection_delayed.cpp index a7492a48551..c4f30631692 100644 --- a/tests/auto/dbus/qdbusconnection_delayed/tst_qdbusconnection_delayed.cpp +++ b/tests/auto/dbus/qdbusconnection_delayed/tst_qdbusconnection_delayed.cpp @@ -77,10 +77,12 @@ void tst_QDBusConnection_Delayed::delayedMessages() QVERIFY(other.isConnected()); QVERIFY(!other.baseService().isEmpty()); + // make a method call: those should work even if delivery is disabled + QVERIFY(session.interface()->isServiceRegistered(other.baseService())); + + // acquire a name in the main session bus connection: the effect is immediate QString name = "org.qtproject.tst_qdbusconnection_delayed-" + QString::number(getpid()); - - // acquire a name in the main session bus connection QVERIFY(session.registerService(name)); QVERIFY(other.interface()->isServiceRegistered(name)); From 3880f41e683f02b905c8cbc3c578c3f3a0a1eb2e Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Fri, 18 Dec 2015 13:19:10 +0100 Subject: [PATCH 047/100] Update PCRE to SVN r1622 (8.38 + patches) In preparation for the 5.6 release. Upstream changelog: http://vcs.pcre.org/pcre/code/trunk/ChangeLog?revision=1622&view=markup&pathrev=1622 Upstream changes: http://vcs.pcre.org/pcre/code/trunk/?pathrev=1622 Change-Id: I97fb23f6b42f4871f05daa726c2edfc691a16d8e Reviewed-by: Lars Knoll --- src/3rdparty/pcre/pcre.h | 4 +- src/3rdparty/pcre/pcre_compile.c | 235 ++++++++++-------- src/3rdparty/pcre/pcre_get.c | 23 +- src/3rdparty/pcre/pcre_internal.h | 2 +- src/3rdparty/pcre/pcre_jit_compile.c | 19 +- src/3rdparty/pcre/pcre_study.c | 2 +- src/3rdparty/pcre/pcre_xclass.c | 2 +- src/3rdparty/pcre/sljit/sljitLir.h | 88 ++++--- .../pcre/sljit/sljitNativeX86_common.c | 66 +++++ 9 files changed, 284 insertions(+), 157 deletions(-) diff --git a/src/3rdparty/pcre/pcre.h b/src/3rdparty/pcre/pcre.h index c2557cf4b1b..609deb5be64 100644 --- a/src/3rdparty/pcre/pcre.h +++ b/src/3rdparty/pcre/pcre.h @@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE_MAJOR 8 -#define PCRE_MINOR 38 +#define PCRE_MINOR 39 #define PCRE_PRERELEASE -RC1 -#define PCRE_DATE 2015-05-03 +#define PCRE_DATE 2015-11-23 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE, the appropriate diff --git a/src/3rdparty/pcre/pcre_compile.c b/src/3rdparty/pcre/pcre_compile.c index 866aa8c693d..b9a239e5544 100644 --- a/src/3rdparty/pcre/pcre_compile.c +++ b/src/3rdparty/pcre/pcre_compile.c @@ -4639,16 +4639,16 @@ for (;; ptr++) /* In the real compile phase, just check the workspace used by the forward reference list. */ - else if (cd->hwm > cd->start_workspace + cd->workspace_size - - WORK_SIZE_SAFETY_MARGIN) + else if (cd->hwm > cd->start_workspace + cd->workspace_size) { *errorcodeptr = ERR52; goto FAILED; } - /* If in \Q...\E, check for the end; if not, we have a literal */ + /* If in \Q...\E, check for the end; if not, we have a literal. Otherwise an + isolated \E is ignored. */ - if (inescq && c != CHAR_NULL) + if (c != CHAR_NULL) { if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) { @@ -4656,7 +4656,7 @@ for (;; ptr++) ptr++; continue; } - else + else if (inescq) { if (previous_callout != NULL) { @@ -4671,18 +4671,27 @@ for (;; ptr++) } goto NORMAL_CHAR; } - /* Control does not reach here. */ + + /* Check for the start of a \Q...\E sequence. We must do this here rather + than later in case it is immediately followed by \E, which turns it into a + "do nothing" sequence. */ + + if (c == CHAR_BACKSLASH && ptr[1] == CHAR_Q) + { + inescq = TRUE; + ptr++; + continue; + } } - /* In extended mode, skip white space and comments. We need a loop in order - to check for more white space and more comments after a comment. */ + /* In extended mode, skip white space and comments. */ if ((options & PCRE_EXTENDED) != 0) { - for (;;) + const pcre_uchar *wscptr = ptr; + while (MAX_255(c) && (cd->ctypes[c] & ctype_space) != 0) c = *(++ptr); + if (c == CHAR_NUMBER_SIGN) { - while (MAX_255(c) && (cd->ctypes[c] & ctype_space) != 0) c = *(++ptr); - if (c != CHAR_NUMBER_SIGN) break; ptr++; while (*ptr != CHAR_NULL) { @@ -4696,8 +4705,33 @@ for (;; ptr++) if (utf) FORWARDCHAR(ptr); #endif } - c = *ptr; /* Either NULL or the char after a newline */ } + + /* If we skipped any characters, restart the loop. Otherwise, we didn't see + a comment. */ + + if (ptr > wscptr) + { + ptr--; + continue; + } + } + + /* Skip over (?# comments. We need to do this here because we want to know if + the next thing is a quantifier, and these comments may come between an item + and its quantifier. */ + + if (c == CHAR_LEFT_PARENTHESIS && ptr[1] == CHAR_QUESTION_MARK && + ptr[2] == CHAR_NUMBER_SIGN) + { + ptr += 3; + while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; + if (*ptr == CHAR_NULL) + { + *errorcodeptr = ERR18; + goto FAILED; + } + continue; } /* See if the next thing is a quantifier. */ @@ -4941,9 +4975,10 @@ for (;; ptr++) (which is on the stack). We have to remember that there was XCLASS data, however. */ + if (class_uchardata > class_uchardata_base) xclass = TRUE; + if (lengthptr != NULL && class_uchardata > class_uchardata_base) { - xclass = TRUE; *lengthptr += (int)(class_uchardata - class_uchardata_base); class_uchardata = class_uchardata_base; } @@ -5046,10 +5081,28 @@ for (;; ptr++) ptr = tempptr + 1; continue; - /* For all other POSIX classes, no special action is taken in UCP - mode. Fall through to the non_UCP case. */ + /* For the other POSIX classes (ascii, cntrl, xdigit) we are going + to fall through to the non-UCP case and build a bit map for + characters with code points less than 256. If we are in a negated + POSIX class, characters with code points greater than 255 must + either all match or all not match. In the special case where we + have not yet generated any xclass data, and this is the final item + in the overall class, we need do nothing: later on, the opcode + OP_NCLASS will be used to indicate that characters greater than 255 + are acceptable. If we have already seen an xclass item or one may + follow (we have to assume that it might if this is not the end of + the class), explicitly list all wide codepoints, which will then + either not match or match, depending on whether the class is or is + not negated. */ default: + if (local_negate && + (xclass || tempptr[2] != CHAR_RIGHT_SQUARE_BRACKET)) + { + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x100, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); + } break; } } @@ -5388,16 +5441,20 @@ for (;; ptr++) CLASS_SINGLE_CHARACTER: if (class_one_char < 2) class_one_char++; - /* If class_one_char is 1, we have the first single character in the - class, and there have been no prior ranges, or XCLASS items generated by - escapes. If this is the final character in the class, we can optimize by - turning the item into a 1-character OP_CHAR[I] if it's positive, or - OP_NOT[I] if it's negative. In the positive case, it can cause firstchar - to be set. Otherwise, there can be no first char if this item is first, - whatever repeat count may follow. In the case of reqchar, save the - previous value for reinstating. */ + /* If xclass_has_prop is false and class_one_char is 1, we have the first + single character in the class, and there have been no prior ranges, or + XCLASS items generated by escapes. If this is the final character in the + class, we can optimize by turning the item into a 1-character OP_CHAR[I] + if it's positive, or OP_NOT[I] if it's negative. In the positive case, it + can cause firstchar to be set. Otherwise, there can be no first char if + this item is first, whatever repeat count may follow. In the case of + reqchar, save the previous value for reinstating. */ - if (!inescq && class_one_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) + if (!inescq && +#ifdef SUPPORT_UCP + !xclass_has_prop && +#endif + class_one_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) { ptr++; zeroreqchar = reqchar; @@ -5513,9 +5570,10 @@ for (;; ptr++) actual compiled code. */ #ifdef SUPPORT_UTF - if (xclass && (!should_flip_negation || (options & PCRE_UCP) != 0)) + if (xclass && (xclass_has_prop || !should_flip_negation || + (options & PCRE_UCP) != 0)) #elif !defined COMPILE_PCRE8 - if (xclass && !should_flip_negation) + if (xclass && (xclass_has_prop || !should_flip_negation)) #endif #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 { @@ -6508,21 +6566,6 @@ for (;; ptr++) case CHAR_LEFT_PARENTHESIS: ptr++; - /* First deal with comments. Putting this code right at the start ensures - that comments have no bad side effects. */ - - if (ptr[0] == CHAR_QUESTION_MARK && ptr[1] == CHAR_NUMBER_SIGN) - { - ptr += 2; - while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; - if (*ptr == CHAR_NULL) - { - *errorcodeptr = ERR18; - goto FAILED; - } - continue; - } - /* Now deal with various "verbs" that can be introduced by '*'. */ if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':' @@ -6613,9 +6656,17 @@ for (;; ptr++) goto FAILED; } setverb = *code++ = verbs[i].op_arg; - *code++ = arglen; - memcpy(code, arg, IN_UCHARS(arglen)); - code += arglen; + if (lengthptr != NULL) /* In pass 1 just add in the length */ + { /* to avoid potential workspace */ + *lengthptr += arglen; /* overflow. */ + *code++ = 0; + } + else + { + *code++ = arglen; + memcpy(code, arg, IN_UCHARS(arglen)); + code += arglen; + } *code++ = 0; } @@ -6668,7 +6719,7 @@ for (;; ptr++) /* ------------------------------------------------------------ */ case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */ reset_bracount = TRUE; - cd->dupgroups = TRUE; /* Record (?| encountered */ + cd->dupgroups = TRUE; /* Record (?| encountered */ /* Fall through */ /* ------------------------------------------------------------ */ @@ -6769,11 +6820,11 @@ for (;; ptr++) { while (IS_DIGIT(*ptr)) { - if (recno > INT_MAX / 10 - 1) /* Integer overflow */ - { - while (IS_DIGIT(*ptr)) ptr++; - *errorcodeptr = ERR61; - goto FAILED; + if (recno > INT_MAX / 10 - 1) /* Integer overflow */ + { + while (IS_DIGIT(*ptr)) ptr++; + *errorcodeptr = ERR61; + goto FAILED; } recno = recno * 10 + (int)(*ptr - CHAR_0); ptr++; @@ -6909,11 +6960,11 @@ for (;; ptr++) *errorcodeptr = ERR15; goto FAILED; } - if (recno > INT_MAX / 10 - 1) /* Integer overflow */ - { - *errorcodeptr = ERR61; - goto FAILED; - } + if (recno > INT_MAX / 10 - 1) /* Integer overflow */ + { + *errorcodeptr = ERR61; + goto FAILED; + } recno = recno * 10 + name[i] - CHAR_0; } if (recno == 0) recno = RREF_ANY; @@ -7191,7 +7242,7 @@ for (;; ptr++) { named_group *ng; recno = 0; - + if (namelen == 0) { *errorcodeptr = ERR62; @@ -7229,24 +7280,24 @@ for (;; ptr++) issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance only mode, we finesse the bug by allowing more memory always. */ - *lengthptr += 2 + 2*LINK_SIZE; - + *lengthptr += 4 + 4*LINK_SIZE; + /* It is even worse than that. The current reference may be to an existing named group with a different number (so apparently not recursive) but which later on is also attached to a group with the - current number. This can only happen if $(| has been previous - encountered. In that case, we allow yet more memory, just in case. + current number. This can only happen if $(| has been previous + encountered. In that case, we allow yet more memory, just in case. (Again, this is fixed "properly" in PCRE2. */ - + if (cd->dupgroups) *lengthptr += 4 + 4*LINK_SIZE; /* Otherwise, check for recursion here. The name table does not exist in the first pass; instead we must scan the list of names encountered so far in order to get the number. If the name is not found, leave the value of recno as 0 for a forward reference. */ - + else - { + { ng = cd->named_groups; for (i = 0; i < cd->names_found; i++, ng++) { @@ -7266,7 +7317,7 @@ for (;; ptr++) } } } - } + } } /* In the real compile, search the name table. We check the name @@ -7556,39 +7607,15 @@ for (;; ptr++) newoptions = (options | set) & (~unset); /* If the options ended with ')' this is not the start of a nested - group with option changes, so the options change at this level. If this - item is right at the start of the pattern, the options can be - abstracted and made external in the pre-compile phase, and ignored in - the compile phase. This can be helpful when matching -- for instance in - caseless checking of required bytes. - - If the code pointer is not (cd->start_code + 1 + LINK_SIZE), we are - definitely *not* at the start of the pattern because something has been - compiled. In the pre-compile phase, however, the code pointer can have - that value after the start, because it gets reset as code is discarded - during the pre-compile. However, this can happen only at top level - if - we are within parentheses, the starting BRA will still be present. At - any parenthesis level, the length value can be used to test if anything - has been compiled at that level. Thus, a test for both these conditions - is necessary to ensure we correctly detect the start of the pattern in - both phases. - + group with option changes, so the options change at this level. If we are not at the pattern start, reset the greedy defaults and the case value for firstchar and reqchar. */ if (*ptr == CHAR_RIGHT_PARENTHESIS) { - if (code == cd->start_code + 1 + LINK_SIZE && - (lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE)) - { - cd->external_options = newoptions; - } - else - { - greedy_default = ((newoptions & PCRE_UNGREEDY) != 0); - greedy_non_default = greedy_default ^ 1; - req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS:0; - } + greedy_default = ((newoptions & PCRE_UNGREEDY) != 0); + greedy_non_default = greedy_default ^ 1; + req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS:0; /* Change options at this level, and pass them back for use in subsequent branches. */ @@ -7867,16 +7894,6 @@ for (;; ptr++) c = ec; else { - if (escape == ESC_Q) /* Handle start of quoted string */ - { - if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) - ptr += 2; /* avoid empty string */ - else inescq = TRUE; - continue; - } - - if (escape == ESC_E) continue; /* Perl ignores an orphan \E */ - /* For metasequences that actually match a character, we disable the setting of a first character if it hasn't already been set. */ @@ -9296,7 +9313,7 @@ if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN; DPRINTF(("end pre-compile: length=%d workspace=%d\n", length, (int)(cd->hwm - cworkspace))); - + if (length > MAX_PATTERN_SIZE) { errorcode = ERR20; @@ -9434,16 +9451,16 @@ if (cd->hwm > cd->start_workspace) int offset, recno; cd->hwm -= LINK_SIZE; offset = GET(cd->hwm, 0); - + /* Check that the hwm handling hasn't gone wrong. This whole area is - rewritten in PCRE2 because there are some obscure cases. */ - + rewritten in PCRE2 because there are some obscure cases. */ + if (offset == 0 || codestart[offset-1] != OP_RECURSE) { - errorcode = ERR10; + errorcode = ERR10; break; - } - + } + recno = GET(codestart, offset); if (recno != prev_recno) { diff --git a/src/3rdparty/pcre/pcre_get.c b/src/3rdparty/pcre/pcre_get.c index 8094b34bbfb..cdd2abc80f2 100644 --- a/src/3rdparty/pcre/pcre_get.c +++ b/src/3rdparty/pcre/pcre_get.c @@ -250,6 +250,7 @@ Arguments: code the compiled regex stringname the name of the capturing substring ovector the vector of matched substrings + stringcount number of captured substrings Returns: the number of the first that is set, or the number of the last one if none are set, @@ -258,13 +259,16 @@ Returns: the number of the first that is set, #if defined COMPILE_PCRE8 static int -get_first_set(const pcre *code, const char *stringname, int *ovector) +get_first_set(const pcre *code, const char *stringname, int *ovector, + int stringcount) #elif defined COMPILE_PCRE16 static int -get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector) +get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector, + int stringcount) #elif defined COMPILE_PCRE32 static int -get_first_set(const pcre32 *code, PCRE_SPTR32 stringname, int *ovector) +get_first_set(const pcre32 *code, PCRE_SPTR32 stringname, int *ovector, + int stringcount) #endif { const REAL_PCRE *re = (const REAL_PCRE *)code; @@ -295,7 +299,7 @@ if (entrysize <= 0) return entrysize; for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize) { int n = GET2(entry, 0); - if (ovector[n*2] >= 0) return n; + if (n < stringcount && ovector[n*2] >= 0) return n; } return GET2(entry, 0); } @@ -402,7 +406,7 @@ pcre32_copy_named_substring(const pcre32 *code, PCRE_SPTR32 subject, PCRE_UCHAR32 *buffer, int size) #endif { -int n = get_first_set(code, stringname, ovector); +int n = get_first_set(code, stringname, ovector, stringcount); if (n <= 0) return n; #if defined COMPILE_PCRE8 return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size); @@ -457,7 +461,10 @@ pcre_uchar **stringlist; pcre_uchar *p; for (i = 0; i < double_count; i += 2) - size += sizeof(pcre_uchar *) + IN_UCHARS(ovector[i+1] - ovector[i] + 1); + { + size += sizeof(pcre_uchar *) + IN_UCHARS(1); + if (ovector[i+1] > ovector[i]) size += IN_UCHARS(ovector[i+1] - ovector[i]); + } stringlist = (pcre_uchar **)(PUBL(malloc))(size); if (stringlist == NULL) return PCRE_ERROR_NOMEMORY; @@ -473,7 +480,7 @@ p = (pcre_uchar *)(stringlist + stringcount + 1); for (i = 0; i < double_count; i += 2) { - int len = ovector[i+1] - ovector[i]; + int len = (ovector[i+1] > ovector[i])? (ovector[i+1] - ovector[i]) : 0; memcpy(p, subject + ovector[i], IN_UCHARS(len)); *stringlist++ = p; p += len; @@ -619,7 +626,7 @@ pcre32_get_named_substring(const pcre32 *code, PCRE_SPTR32 subject, PCRE_SPTR32 *stringptr) #endif { -int n = get_first_set(code, stringname, ovector); +int n = get_first_set(code, stringname, ovector, stringcount); if (n <= 0) return n; #if defined COMPILE_PCRE8 return pcre_get_substring(subject, ovector, stringcount, n, stringptr); diff --git a/src/3rdparty/pcre/pcre_internal.h b/src/3rdparty/pcre/pcre_internal.h index 544d9c07097..f7a5ee7aa6f 100644 --- a/src/3rdparty/pcre/pcre_internal.h +++ b/src/3rdparty/pcre/pcre_internal.h @@ -2454,7 +2454,7 @@ typedef struct compile_data { BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */ BOOL check_lookbehind; /* Lookbehinds need later checking */ BOOL dupnames; /* Duplicate names exist */ - BOOL dupgroups; /* Duplicate groups exist: (?| found */ + BOOL dupgroups; /* Duplicate groups exist: (?| found */ BOOL iscondassert; /* Next assert is a condition */ int nltype; /* Newline type */ int nllen; /* Newline string length */ diff --git a/src/3rdparty/pcre/pcre_jit_compile.c b/src/3rdparty/pcre/pcre_jit_compile.c index 868d1d91bfe..445de0cbefe 100644 --- a/src/3rdparty/pcre/pcre_jit_compile.c +++ b/src/3rdparty/pcre/pcre_jit_compile.c @@ -4342,8 +4342,10 @@ switch(length) case 4: if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2]) && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2] + && (ranges[1] & (ranges[2] - ranges[0])) == 0 && is_powerof2(ranges[2] - ranges[0])) { + SLJIT_ASSERT((ranges[0] & (ranges[2] - ranges[0])) == 0 && (ranges[2] & ranges[3] & (ranges[2] - ranges[0])) != 0); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]); if (ranges[2] + 1 != ranges[3]) { @@ -4931,9 +4933,10 @@ else if ((cc[-1] & XCL_MAP) != 0) if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list)) { #ifdef COMPILE_PCRE8 - SLJIT_ASSERT(common->utf); + jump = NULL; + if (common->utf) #endif - jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); + jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); @@ -4942,7 +4945,10 @@ else if ((cc[-1] & XCL_MAP) != 0) OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); add_jump(compiler, list, JUMP(SLJIT_NOT_ZERO)); - JUMPHERE(jump); +#ifdef COMPILE_PCRE8 + if (common->utf) +#endif + JUMPHERE(jump); } OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); @@ -5250,7 +5256,7 @@ while (*cc != XCL_END) OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_LESS_EQUAL); SET_CHAR_OFFSET(0); - OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xff); + OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x7f); OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_LESS_EQUAL); SET_TYPE_OFFSET(ucp_Pc); @@ -8477,8 +8483,7 @@ while (cc < ccend) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); } BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL(); - if (cc[1] > OP_ASSERTBACK_NOT) - count_match(common); + count_match(common); break; case OP_ONCE: @@ -9660,7 +9665,7 @@ static SLJIT_INLINE void compile_recurse(compiler_common *common) DEFINE_COMPILER; pcre_uchar *cc = common->start + common->currententry->start; pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE); -pcre_uchar *ccend = bracketend(cc); +pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE); BOOL needs_control_head; int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head); int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head); diff --git a/src/3rdparty/pcre/pcre_study.c b/src/3rdparty/pcre/pcre_study.c index 932e9a7c4c6..7fd0ba0b3d8 100644 --- a/src/3rdparty/pcre/pcre_study.c +++ b/src/3rdparty/pcre/pcre_study.c @@ -71,7 +71,7 @@ Arguments: startcode pointer to start of the whole pattern's code options the compiling options recurses chain of recurse_check to catch mutual recursion - countptr pointer to call count (to catch over complexity) + countptr pointer to call count (to catch over complexity) Returns: the minimum length -1 if \C in UTF-8 mode or (*ACCEPT) was encountered diff --git a/src/3rdparty/pcre/pcre_xclass.c b/src/3rdparty/pcre/pcre_xclass.c index c2b61f0f920..ef759a589a6 100644 --- a/src/3rdparty/pcre/pcre_xclass.c +++ b/src/3rdparty/pcre/pcre_xclass.c @@ -246,7 +246,7 @@ while ((t = *data++) != XCL_END) case PT_PXPUNCT: if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P || - (c < 256 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop) + (c < 128 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop) return !negated; break; diff --git a/src/3rdparty/pcre/sljit/sljitLir.h b/src/3rdparty/pcre/sljit/sljitLir.h index f0969dac2e4..2e2e9ac09cd 100644 --- a/src/3rdparty/pcre/sljit/sljitLir.h +++ b/src/3rdparty/pcre/sljit/sljitLir.h @@ -869,34 +869,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler sljit_si src1, sljit_sw src1w, sljit_si src2, sljit_sw src2w); -/* The following function is a helper function for sljit_emit_op_custom. - It returns with the real machine register index ( >=0 ) of any SLJIT_R, - SLJIT_S and SLJIT_SP registers. - - Note: it returns with -1 for virtual registers (only on x86-32). */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg); - -/* The following function is a helper function for sljit_emit_op_custom. - It returns with the real machine register index of any SLJIT_FLOAT register. - - Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg); - -/* Any instruction can be inserted into the instruction stream by - sljit_emit_op_custom. It has a similar purpose as inline assembly. - The size parameter must match to the instruction size of the target - architecture: - - x86: 0 < size <= 15. The instruction argument can be byte aligned. - Thumb2: if size == 2, the instruction argument must be 2 byte aligned. - if size == 4, the instruction argument must be 4 byte aligned. - Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size); - /* Returns with non-zero if fpu is available. */ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void); @@ -1214,4 +1186,64 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct #endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */ +/* --------------------------------------------------------------------- */ +/* CPU specific functions */ +/* --------------------------------------------------------------------- */ + +/* The following function is a helper function for sljit_emit_op_custom. + It returns with the real machine register index ( >=0 ) of any SLJIT_R, + SLJIT_S and SLJIT_SP registers. + + Note: it returns with -1 for virtual registers (only on x86-32). */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg); + +/* The following function is a helper function for sljit_emit_op_custom. + It returns with the real machine register index of any SLJIT_FLOAT register. + + Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg); + +/* Any instruction can be inserted into the instruction stream by + sljit_emit_op_custom. It has a similar purpose as inline assembly. + The size parameter must match to the instruction size of the target + architecture: + + x86: 0 < size <= 15. The instruction argument can be byte aligned. + Thumb2: if size == 2, the instruction argument must be 2 byte aligned. + if size == 4, the instruction argument must be 4 byte aligned. + Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, sljit_si size); + +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) + +/* Returns with non-zero if sse2 is available. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void); + +/* Returns with non-zero if cmov instruction is available. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void); + +/* Emit a conditional mov instruction on x86 CPUs. This instruction + moves src to destination, if the condition is satisfied. Unlike + other arithmetic instructions, destination must be a register. + Before such instructions are emitted, cmov support should be + checked by sljit_x86_is_cmov_available function. + type must be between SLJIT_EQUAL and SLJIT_S_ORDERED + dst_reg must be a valid register and it can be combined + with SLJIT_INT_OP to perform 32 bit arithmetic + Flags: I - (never set any flags) + */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler, + sljit_si type, + sljit_si dst_reg, + sljit_si src, sljit_sw srcw); + +#endif + #endif /* _SLJIT_LIR_H_ */ diff --git a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c index e148c34cd10..416c15afafa 100644 --- a/src/3rdparty/pcre/sljit/sljitNativeX86_common.c +++ b/src/3rdparty/pcre/sljit/sljitNativeX86_common.c @@ -2936,3 +2936,69 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta { *(sljit_sw*)addr = new_constant; } + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void) +{ +#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) + if (cpu_has_sse2 == -1) + get_cpu_features(); + return cpu_has_sse2; +#else + return 1; +#endif +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void) +{ + if (cpu_has_cmov == -1) + get_cpu_features(); + return cpu_has_cmov; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler, + sljit_si type, + sljit_si dst_reg, + sljit_si src, sljit_sw srcw) +{ + sljit_ub* inst; + + CHECK_ERROR(); +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_x86_is_cmov_available()); + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_INT_OP))); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_INT_OP)); + FUNCTION_CHECK_SRC(src, srcw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " x86_cmov%s %s%s, ", + !(dst_reg & SLJIT_INT_OP) ? "" : ".i", + JUMP_PREFIX(type), jump_names[type & 0xff]); + sljit_verbose_reg(compiler, dst_reg & ~SLJIT_INT_OP); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif + + ADJUST_LOCAL_OFFSET(src, srcw); + CHECK_EXTRA_REGS(src, srcw, (void)0); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = dst_reg & SLJIT_INT_OP; +#endif + dst_reg &= ~SLJIT_INT_OP; + + if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw); + src = TMP_REG1; + srcw = 0; + } + + inst = emit_x86_instruction(compiler, 2, dst_reg, 0, src, srcw); + FAIL_IF(!inst); + *inst++ = GROUP_0F; + *inst = get_jump_code(type & 0xff) - 0x40; + return SLJIT_SUCCESS; +} From 5d849880f4225717b76fb95d9c6a5dd9614ac7be Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 23 Oct 2015 16:32:59 +0200 Subject: [PATCH 048/100] QNetworkReplyHttpImpl: convert another QDateTime::currentDateTime() to currentDateTimeUtc() The latter is much faster as it doesn't have to deal with time zones. This change is safe because QNetworkHeadersPrivate::fromHttpDate(), used as the QDateTime source in other, nearby, code paths, also returns only UTC date-times. So not only is this change faster at the call site, it also avoids inconsistent-timespec comparisons down the line. Credits to Milian Wolff, from whose QtWS15 talk this advice is taken. Change-Id: I26d308a2763cc45d28bc96871e651f30b17a6b85 Reviewed-by: Lars Knoll Reviewed-by: Friedemann Kleint --- src/network/access/qnetworkreplyhttpimpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp index ad8a5321b46..04d391a14c9 100644 --- a/src/network/access/qnetworkreplyhttpimpl.cpp +++ b/src/network/access/qnetworkreplyhttpimpl.cpp @@ -1585,7 +1585,7 @@ QNetworkCacheMetaData QNetworkReplyHttpImplPrivate::fetchCacheMetaData(const QNe QByteArray maxAge = cacheControl.value("max-age"); if (!maxAge.isEmpty()) { checkExpired = false; - QDateTime dt = QDateTime::currentDateTime(); + QDateTime dt = QDateTime::currentDateTimeUtc(); dt = dt.addSecs(maxAge.toInt()); metaData.setExpirationDate(dt); } From b12e876efce4309ed61c04b9232ee80ec64baddc Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 9 Dec 2015 13:18:17 +0100 Subject: [PATCH 049/100] tst_qwindow::isExposed - fix failing test on OS X MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ice25c8ffaaa4662b679ee829dc0a38834e3258b7 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qnsview.mm | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 3faa292ae0e..0d80333e65a 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -440,16 +440,17 @@ QT_WARNING_PUSH QT_WARNING_DISABLE_CLANG("-Wobjc-method-access") enum { NSWindowOcclusionStateVisible = 1UL << 1 }; #endif - if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible) { - m_platformWindow->exposeWindow(); - } else { - // Send Obscure events on window occlusion to stop animations. Several - // unit tests expect paint and/or expose events for windows that are - // sometimes (unpredictably) occlouded: Don't send Obscure events when - // running under QTestLib. - static bool onTestLib = qt_mac_resolveOption(false, "QT_QTESTLIB_RUNNING"); - if (!onTestLib) + // Several unit tests expect paint and/or expose events for windows that are + // sometimes (unpredictably) occluded and some unit tests depend on QWindow::isExposed - + // don't send Expose/Obscure events when running under QTestLib. + static const bool onTestLib = qt_mac_resolveOption(false, "QT_QTESTLIB_RUNNING"); + if (!onTestLib) { + if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible) { + m_platformWindow->exposeWindow(); + } else { + // Send Obscure events on window occlusion to stop animations. m_platformWindow->obscureWindow(); + } } #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9 QT_WARNING_POP From 7fdfaad43f75bab9d701b0b55c13570d2140fde4 Mon Sep 17 00:00:00 2001 From: Samuel Nevala Date: Mon, 7 Dec 2015 10:51:18 +0200 Subject: [PATCH 050/100] Fix deadlock when setting environment variables. Qt uses QHash as the container for faking environment variables on Windows Runtime and CE. Environment variable manipulation functions are protected by mutex. Accessing the QT_HASH_SEED environment variable inside QHash can lead to situation where qputenv() call leads to qgetenv() call and that leads to a deadlock. Change the container from QHash to QVector to avoid deadlock. Task-number: QTBUG-49529 Change-Id: I550ead4ab12e7abebc044f52339063a44fcf0170 Reviewed-by: Marc Mutz Reviewed-by: Maurice Kalinowski --- src/corelib/kernel/qfunctions_fake_env_p.h | 51 +++++++++++++++------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/src/corelib/kernel/qfunctions_fake_env_p.h b/src/corelib/kernel/qfunctions_fake_env_p.h index 8b1ab446963..b4c5ffb079e 100644 --- a/src/corelib/kernel/qfunctions_fake_env_p.h +++ b/src/corelib/kernel/qfunctions_fake_env_p.h @@ -46,51 +46,72 @@ // #include "qbytearray.h" -#include "qhash.h" +#include "qvector.h" QT_BEGIN_NAMESPACE // Environment ------------------------------------------------------ -Q_CORE_EXPORT QHash &qt_app_environment() -{ - static QHash internalEnvironment; - return internalEnvironment; -} +struct Variable { + Variable() { } + + Variable(const QByteArray &name, const QByteArray &value) + : name(name), value(value) { } + + QByteArray name; + QByteArray value; +}; + +Q_DECLARE_TYPEINFO(Variable, Q_MOVABLE_TYPE); + +struct NameEquals { + typedef bool result_type; + const char *name; + explicit NameEquals(const char *name) Q_DECL_NOTHROW : name(name) {} + result_type operator()(const Variable &other) const Q_DECL_NOTHROW + { return qstrcmp(other.name, name) == 0; } +}; + +Q_GLOBAL_STATIC(QVector, qt_app_environment) errno_t qt_fake_getenv_s(size_t *sizeNeeded, char *buffer, size_t bufferSize, const char *varName) { if (!sizeNeeded) return EINVAL; - QHash::const_iterator iterator = qt_app_environment().constFind(varName); - if (iterator == qt_app_environment().constEnd()) { + QVector::const_iterator end = qt_app_environment->constEnd(); + QVector::const_iterator iterator = std::find_if(qt_app_environment->constBegin(), + end, + NameEquals(varName)); + if (iterator == end) { if (buffer) buffer[0] = '\0'; return ENOENT; } - const int size = iterator->size() + 1; + const int size = iterator->value.size() + 1; if (bufferSize < size_t(size)) { *sizeNeeded = size; return ERANGE; } - qstrcpy(buffer, iterator->constData()); + qstrcpy(buffer, iterator->value.constData()); return 0; } errno_t qt_fake__putenv_s(const char *varName, const char *value) { - QHash::iterator iterator = qt_app_environment().find(varName); - QHash::iterator end = qt_app_environment().end(); + QVector::iterator end = qt_app_environment->end(); + QVector::iterator iterator = std::find_if(qt_app_environment->begin(), + end, + NameEquals(varName)); if (!value || !*value) { if (iterator != end) - qt_app_environment().erase(iterator); + qt_app_environment->erase(iterator); } else { if (iterator == end) - qt_app_environment()[varName] = QByteArray(value); + qt_app_environment->append(Variable(varName, value)); else - (*iterator) = value; + iterator->value = value; } return 0; From eaa3a9d0108cdf692f1686cafefb7b834f0e5af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Fri, 1 Jan 2016 20:02:42 +0100 Subject: [PATCH 051/100] Fix crash because of NULL screen in QXcbWindow Change-Id: If7bbe3ad1656dadcb098bcd3ece2e7b064eeb44d Task-number: QTBUG-50081 Reviewed-by: Shawn Rutledge --- src/gui/kernel/qwindow.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index e728d32e4b2..83e87776278 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -609,18 +609,16 @@ void QWindow::setParent(QWindow *parent) } QObject::setParent(parent); - if (parent) + + QPlatformWindow *parentPlatformWindow = parent ? parent->d_func()->platformWindow : Q_NULLPTR; + + if (parentPlatformWindow) d->disconnectFromScreen(); else d->connectToScreen(newScreen); - if (d->platformWindow) { - if (parent && parent->d_func()->platformWindow) { - d->platformWindow->setParent(parent->d_func()->platformWindow); - } else { - d->platformWindow->setParent(0); - } - } + if (d->platformWindow) + d->platformWindow->setParent(parentPlatformWindow); d->parentWindow = parent; From 374d35d5ba7ceb4a95bcbe83d538a27a0283662b Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 28 Oct 2015 12:48:00 +0100 Subject: [PATCH 052/100] Make use of preprocessor easier to understand. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The #if had a condition that was needlessly hard to understand; and was widely separated from its #else clause. Change-Id: I43f4282993f4f2e8c4b5ad07dc2c2e06a6b95aa9 Reviewed-by: Jędrzej Nowacki --- .../util/qundogroup/tst_qundogroup.cpp | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp b/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp index 781adeedada..9f03e9b3a04 100644 --- a/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp +++ b/tests/auto/widgets/util/qundogroup/tst_qundogroup.cpp @@ -36,7 +36,22 @@ #include // Temporarily disabling IRIX due to build issuues with GCC -#if !defined(__sgi) || defined(__sgi) && !defined(__GNUC__) +#if defined(__sgi) && defined(__GNUC__) + +class tst_QUndoGroup : public QObject +{ + Q_OBJECT +public: + tst_QUndoGroup() {} + +private slots: + void setActive() { QSKIP( "Not tested on irix-g++"); } + void addRemoveStack() { QSKIP( "Not tested on irix-g++"); } + void deleteStack() { QSKIP( "Not tested on irix-g++"); } + void checkSignals() { QSKIP( "Not tested on irix-g++"); } + void addStackAndDie() { QSKIP( "Not tested on irix-g++"); } +}; +#else /****************************************************************************** ** Commands @@ -645,22 +660,7 @@ void tst_QUndoGroup::commandTextFormat() qApp->removeTranslator(&translator); #endif } - -#else -class tst_QUndoGroup : public QObject -{ - Q_OBJECT -public: - tst_QUndoGroup() {} - -private slots: - void setActive() { QSKIP( "Not tested on irix-g++"); } - void addRemoveStack() { QSKIP( "Not tested on irix-g++"); } - void deleteStack() { QSKIP( "Not tested on irix-g++"); } - void checkSignals() { QSKIP( "Not tested on irix-g++"); } - void addStackAndDie() { QSKIP( "Not tested on irix-g++"); } -}; -#endif +#endif // !(SGI && GCC) QTEST_MAIN(tst_QUndoGroup) From c19216cbeab53b5de249dc2a31e6555f013e6be0 Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Tue, 15 Dec 2015 13:17:35 +0100 Subject: [PATCH 053/100] Fix QPainter::rotate() documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I5d11f84181cad9be644e850c83459b47ec2f2f15 Reviewed-by: Topi Reiniö --- src/gui/painting/qpainter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index e80c0130c3f..5dcab11f0a3 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -3154,7 +3154,7 @@ void QPainter::shear(qreal sh, qreal sv) /*! \fn void QPainter::rotate(qreal angle) - Rotates the coordinate system clockwise. The given \a angle parameter uses degree unit. + Rotates the coordinate system clockwise. The given \a angle parameter is in degrees. \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate Transformations} */ From 0c60dda8728af906acd0772615c517a51d3bec61 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 4 Jan 2016 12:45:46 +0100 Subject: [PATCH 054/100] QWindowsTheme: Fix return type of helper dWordSystemParametersInfo(). QApplication::wheelScrollLines() was always 1 due it being a bool. Task-number: QTBUG-49561 Change-Id: I83e97da3507c31dfd024db7bf543c4e6a3b4a98b Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowstheme.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 877bdfec17d..cc367ff8013 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -131,7 +131,7 @@ static inline bool booleanSystemParametersInfo(UINT what, bool defaultValue) return defaultValue; } -static inline bool dWordSystemParametersInfo(UINT what, DWORD defaultValue) +static inline DWORD dWordSystemParametersInfo(UINT what, DWORD defaultValue) { DWORD result; if (SystemParametersInfo(what, 0, &result, 0)) @@ -394,7 +394,7 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const case ContextMenuOnMouseRelease: return QVariant(true); case WheelScrollLines: - return dWordSystemParametersInfo(SPI_GETWHEELSCROLLLINES, 3); + return QVariant(int(dWordSystemParametersInfo(SPI_GETWHEELSCROLLLINES, 3))); default: break; } From 0cee94017f441be09518a190ac1c4cbd8a76adc6 Mon Sep 17 00:00:00 2001 From: Mauro Persano Date: Thu, 24 Dec 2015 14:15:19 -0200 Subject: [PATCH 055/100] QOpenGLTexture: fix target for compressed textures Trying to set data for a compressed cubemap texture face fails, because the code incorrectly tries to bind to a cubemap face target. This was already fixed for uncompressed textures. Instead of duplicating the code, moved the texture binding/unbinding code to a RAII class. Change-Id: I8f1cb7fc661b919200f85c3465d6e6e3c22d0871 Reviewed-by: Sean Harmer --- src/gui/opengl/qopengltexturehelper.cpp | 208 ++++++++---------------- 1 file changed, 70 insertions(+), 138 deletions(-) diff --git a/src/gui/opengl/qopengltexturehelper.cpp b/src/gui/opengl/qopengltexturehelper.cpp index bf8b514449f..df2945a4796 100644 --- a/src/gui/opengl/qopengltexturehelper.cpp +++ b/src/gui/opengl/qopengltexturehelper.cpp @@ -453,260 +453,192 @@ void QOpenGLTextureHelper::dsa_CompressedTextureImage3D(GLuint texture, GLenum t CompressedTextureImage3DEXT(texture, target, level, internalFormat, width, height, depth, border, imageSize, bits); } +namespace { + +class TextureBinder +{ +public: + TextureBinder(QOpenGLTextureHelper *textureFunctions, GLuint texture, GLenum target, GLenum bindingTarget) + : m_textureFunctions(textureFunctions) + { + // For cubemaps we can't use the standard DSA emulation as it is illegal to + // try to bind a texture to one of the cubemap face targets. So we force the + // target and binding target to the cubemap values in this case. + switch (target) { + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + bindingTarget = GL_TEXTURE_BINDING_CUBE_MAP; + m_target = GL_TEXTURE_CUBE_MAP; + break; + + default: + m_target = target; + break; + } + + m_textureFunctions->glGetIntegerv(bindingTarget, &m_oldTexture); + m_textureFunctions->glBindTexture(m_target, texture); + } + + ~TextureBinder() + { + m_textureFunctions->glBindTexture(m_target, m_oldTexture); + } + +private: + QOpenGLTextureHelper *m_textureFunctions; + GLenum m_target; + GLint m_oldTexture; +}; + +} // namespace + void QOpenGLTextureHelper::qt_TextureParameteri(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLint param) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexParameteri(target, pname, param); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureParameteriv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLint *params) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexParameteriv(target, pname, params); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureParameterf(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, GLfloat param) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexParameterf(target, pname, param); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureParameterfv(GLuint texture, GLenum target, GLenum bindingTarget, GLenum pname, const GLfloat *params) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexParameterfv(target, pname, params); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_GenerateTextureMipmap(GLuint texture, GLenum target, GLenum bindingTarget) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glGenerateMipmap(target); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureStorage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexStorage3D(target, levels, internalFormat, width, height, depth); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureStorage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexStorage2D(target, levels, internalFormat, width, height); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureStorage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei levels, GLenum internalFormat, GLsizei width) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexStorage1D(target, levels, internalFormat, width); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureStorage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexStorage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureStorage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexStorage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, pixels); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { - // For cubemaps we can't use the standard DSA emulation as it is illegal to - // try to bind a texture to one of the cubemap face targets. So we force the - // target and binding target to the cubemap values in this case. - GLint oldTexture; - - switch (target) { - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture); - glBindTexture(GL_TEXTURE_CUBE_MAP, texture); - glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels); - glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture); - break; - - default: - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); - glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels); - glBindTexture(target, oldTexture); - break; - } + TextureBinder binder(this, texture, target, bindingTarget); + glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels); } void QOpenGLTextureHelper::qt_TextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexImage1D(target, level, internalFormat, width, border, format, type, pixels); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) { - // For cubemaps we can't use the standard DSA emulation as it is illegal to - // try to bind a texture to one of the cubemap face targets. So we force the - // target and binding target to the cubemap values in this case. - GLint oldTexture; - - switch (target) { - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture); - glBindTexture(GL_TEXTURE_CUBE_MAP, texture); - glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); - glBindTexture(GL_TEXTURE_CUBE_MAP, oldTexture); - break; - - default: - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); - glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); - glBindTexture(target, oldTexture); - break; - } + TextureBinder binder(this, texture, target, bindingTarget); + glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); } void QOpenGLTextureHelper::qt_TextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexSubImage1D(target, level, xoffset, width, format, type, pixels); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureImage3DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexImage3DMultisample(target, samples, internalFormat, width, height, depth, fixedSampleLocations); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_TextureImage2DMultisample(GLuint texture, GLenum target, GLenum bindingTarget, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glTexImage2DMultisample(target, samples, internalFormat, width, height, fixedSampleLocations); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_CompressedTextureSubImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glCompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, bits); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, bits); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_CompressedTextureSubImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_CompressedTextureImage1D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glCompressedTexImage1D(target, level, internalFormat, width, border, imageSize, bits); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_CompressedTextureImage2D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glCompressedTexImage2D(target, level, internalFormat, width, height, border, imageSize, bits); - glBindTexture(target, oldTexture); } void QOpenGLTextureHelper::qt_CompressedTextureImage3D(GLuint texture, GLenum target, GLenum bindingTarget, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits) { - GLint oldTexture; - glGetIntegerv(bindingTarget, &oldTexture); - glBindTexture(target, texture); + TextureBinder binder(this, texture, target, bindingTarget); glCompressedTexImage3D(target, level, internalFormat, width, height, depth, border, imageSize, bits); - glBindTexture(target, oldTexture); } QT_END_NAMESPACE From 60c333cabaf7514790c35f382a9f7f074fb7c20c Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 4 Jan 2016 16:10:03 +0100 Subject: [PATCH 056/100] QMacPanGestureRecognizer - stop timer on 'reset' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _panTimer has a target - for example, widget. 'reset' should stop this timer. The problem (quite subtle and difficult to reproduce) found in tst_QTouchEvent: widgets created/destoryed by different tests but we still can have a timer waiting for event dispatcher to 'processEvents', firing with now-invalid dangling pointer - 'target'. Change-Id: Iccaf3368a8ee6a0a2f60e9dcdf5d40fb7392ca21 Task-number: QTBUG-49844 Reviewed-by: Morten Johan Sørvig --- src/widgets/kernel/qmacgesturerecognizer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/widgets/kernel/qmacgesturerecognizer.cpp b/src/widgets/kernel/qmacgesturerecognizer.cpp index 47003f58662..9f55e23cee0 100644 --- a/src/widgets/kernel/qmacgesturerecognizer.cpp +++ b/src/widgets/kernel/qmacgesturerecognizer.cpp @@ -256,6 +256,7 @@ void QMacPanGestureRecognizer::reset(QGesture *gesture) QPanGesture *g = static_cast(gesture); _startPos = QPointF(); _panCanceled = true; + _panTimer.stop(); g->setOffset(QPointF(0, 0)); g->setLastOffset(QPointF(0, 0)); g->setAcceleration(qreal(1)); From 4ed8733d909f8a6b719bf56266114eae885cd74f Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 4 Jan 2016 16:37:55 +0100 Subject: [PATCH 057/100] tst_Gesture - fix failing tests on OS X 10.11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test seems to be quite broken on OS X: qWaitForWindowExposed returns too early (while no window is on screen) so gestures can not be dispatched QApplication::topLevelAt(pt) - returns null. Use qWait + isExposed combo instead (similar to qWaitForWindowExposed, but there is no isExposed test before the loop). Change-Id: I85fbd773ccce0ca92b2dceb1749d67ef767aa0cf Task-number: QTBUG-49849 Reviewed-by: Morten Johan Sørvig --- tests/auto/other/gestures/tst_gestures.cpp | 56 ++++++++++++++-------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/tests/auto/other/gestures/tst_gestures.cpp b/tests/auto/other/gestures/tst_gestures.cpp index 2a4f88c6274..6db918cffd0 100644 --- a/tests/auto/other/gestures/tst_gestures.cpp +++ b/tests/auto/other/gestures/tst_gestures.cpp @@ -48,6 +48,24 @@ #include +static bool waitForWindowExposed(QWindow *window) +{ + if (!window) + return false; +#ifdef Q_OS_OSX + QTest::qWait(100); + return window->isExposed(); +#endif + return QTest::qWaitForWindowExposed(window); +} + +static bool waitForWindowExposed(QWidget *widget) +{ + if (!widget) + return false; + return waitForWindowExposed(widget->windowHandle()); +} + static QPointF mapToGlobal(const QPointF &pt, QGraphicsItem *item, QGraphicsView *view) { return view->viewport()->mapToGlobal(view->mapFromScene(item->mapToScene(pt))); @@ -387,7 +405,7 @@ void tst_Gestures::customGesture() GestureWidget widget; widget.grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren); widget.show(); - QVERIFY(QTest::qWaitForWindowExposed(&widget)); + QVERIFY(waitForWindowExposed(&widget)); CustomEvent event; event.hotSpot = widget.mapToGlobal(QPoint(5,5)); @@ -856,7 +874,7 @@ void tst_Gestures::graphicsItemGesture() item->setPos(100, 100); view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); item->grabGesture(CustomGesture::GestureType); @@ -918,7 +936,7 @@ void tst_Gestures::graphicsView() item->setPos(100, 100); view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); item->grabGesture(CustomGesture::GestureType); @@ -994,7 +1012,7 @@ void tst_Gestures::graphicsItemTreeGesture() item1_child2->setParentItem(item1); view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); item1->grabGesture(CustomGesture::GestureType); @@ -1051,7 +1069,7 @@ void tst_Gestures::explicitGraphicsObjectTarget() item2_child1->setPos(10, 10); view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); item1->grabGesture(CustomGesture::GestureType, Qt::DontStartGestureOnChildren); @@ -1110,7 +1128,7 @@ void tst_Gestures::gestureOverChildGraphicsItem() item2_child1->setPos(0, 0); view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); item1->grabGesture(CustomGesture::GestureType); @@ -1408,7 +1426,7 @@ void tst_Gestures::testMapToScene() item0->setPos(14, 16); view.show(); // need to show to give it a global coordinate - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); QPoint origin = view.mapToGlobal(QPoint()); @@ -1534,7 +1552,7 @@ void tst_Gestures::autoCancelGestures() parent.grabGesture(CustomGesture::GestureType); child->grabGesture(secondGesture); parent.show(); - QVERIFY(QTest::qWaitForWindowExposed(&parent)); + QVERIFY(waitForWindowExposed(&parent)); /* An event is sent to both the child and the parent, when the child gets it a gesture is triggered @@ -1593,7 +1611,7 @@ void tst_Gestures::autoCancelGestures2() child->grabGesture(secondGesture); view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); CustomEvent event; @@ -1639,7 +1657,7 @@ void tst_Gestures::graphicsViewParentPropagation() item1_c1_c1->setPos(0, 0); view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); item0->grabGesture(CustomGesture::GestureType, Qt::ReceivePartialGestures | Qt::IgnoredGesturesPropagateToParent); @@ -1709,7 +1727,7 @@ void tst_Gestures::panelPropagation() item1_child1_child1->setZValue(10); view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1; @@ -1820,7 +1838,7 @@ void tst_Gestures::panelStacksBehindParent() panel->setZValue(5); view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1; @@ -1904,7 +1922,7 @@ void tst_Gestures::deleteGestureTargetItem() items.insert(item2->objectName(), item2); view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); if (propagateUpdateGesture) @@ -1949,7 +1967,7 @@ void tst_Gestures::viewportCoordinates() scene.addItem(item1); view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); CustomEvent event; @@ -1986,7 +2004,7 @@ void tst_Gestures::partialGesturePropagation() scene.addItem(item4); view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); item1->ignoredUpdatedGestures << CustomGesture::GestureType; @@ -2074,7 +2092,7 @@ void tst_Gestures::testQGestureRecognizerCleanup() //QGestureRecognizer::registerRecognizer(new PanRecognizer(PanRecognizer::Custom)); w->show(); - QVERIFY(QTest::qWaitForWindowExposed(w)); + QVERIFY(waitForWindowExposed(w)); delete w; } @@ -2195,7 +2213,7 @@ void tst_Gestures::testReuseCanceledGestures() gv->viewport()->grabGesture(tapGestureTypeId); mw.show(); - QVERIFY(QTest::qWaitForWindowExposed(&mw)); + QVERIFY(waitForWindowExposed(&mw)); QPoint targetPos(gv->mapFromScene(target->mapToScene(target->rect().center()))); targetPos = gv->viewport()->mapFromParent(targetPos); @@ -2261,7 +2279,7 @@ void tst_Gestures::conflictingGesturesInGraphicsView() scene.addItem(item2); view.show(); - QVERIFY(QTest::qWaitForWindowExposed(&view)); + QVERIFY(waitForWindowExposed(&view)); view.ensureVisible(scene.sceneRect()); static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1; @@ -2326,7 +2344,7 @@ void tst_Gestures::bug_13501_gesture_not_accepted() NoConsumeWidgetBug13501 w; w.grabGesture(Qt::TapGesture); w.show(); - QVERIFY(QTest::qWaitForWindowExposed(&w)); + QVERIFY(waitForWindowExposed(&w)); //QTest::mousePress(&ignoreEvent, Qt::LeftButton); QTouchDevice *device = new QTouchDevice; device->setType(QTouchDevice::TouchScreen); From 2ca20724dd17df96143be160505f982ab6cf4378 Mon Sep 17 00:00:00 2001 From: Samuel Nevala Date: Tue, 17 Nov 2015 07:52:28 +0200 Subject: [PATCH 058/100] WinRT: Add camera button events on Windows Phone MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Windows Phone 8.1 provides access to the camera button and press/release events get passed as Key_CameraFocus and Key_Camera. Unfortunately a release does not provide what has been pressed before, hence this information needs to be cached when the press happens. Done-with: Maurice Kalinowski Task-number: QTBUG-39115 Change-Id: I6ce58a1f07a6bf7183b8d99a26e5cd7b0d32d6db Reviewed-by: Topi Reiniö Reviewed-by: Samuel Nevala Reviewed-by: Oliver Wolff --- src/corelib/global/qnamespace.qdoc | 4 +- .../platforms/winrt/qwinrtintegration.cpp | 64 +++++++++++++++++++ .../platforms/winrt/qwinrtintegration.h | 4 ++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 502d6acd9fd..be7240b4ef3 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -1704,8 +1704,8 @@ \value Key_unknown \value Key_Call A key to answer or initiate a call (see Qt::Key_ToggleCallHangup for a key to toggle current call state) - \value Key_Camera A key to activate the camera shutter - \value Key_CameraFocus A key to focus the camera + \value Key_Camera A key to activate the camera shutter. On Windows Runtime, the environment variable QT_QPA_ENABLE_CAMERA_KEYS must be set to receive the event. + \value Key_CameraFocus A key to focus the camera. On Windows Runtime, the environment variable QT_QPA_ENABLE_CAMERA_KEYS must be set to receive the event. \value Key_Context1 \value Key_Context2 \value Key_Context3 diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 9db5df995ad..e94a0aa846f 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -79,6 +79,7 @@ typedef IEventHandler ResumeHandler; typedef IEventHandler SuspendHandler; #ifdef Q_OS_WINPHONE typedef IEventHandler BackPressedHandler; +typedef IEventHandler CameraButtonHandler; #endif QT_BEGIN_NAMESPACE @@ -88,6 +89,8 @@ uint qHash(CoreApplicationCallbackRemover key) { void *ptr = *(void **)(&key); r #ifdef Q_OS_WINPHONE typedef HRESULT (__stdcall IHardwareButtonsStatics::*HardwareButtonsCallbackRemover)(EventRegistrationToken); uint qHash(HardwareButtonsCallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } +typedef HRESULT (__stdcall IHardwareButtonsStatics2::*HardwareButtons2CallbackRemover)(EventRegistrationToken); +uint qHash(HardwareButtons2CallbackRemover key) { void *ptr = *(void **)(&key); return qHash(ptr); } #endif class QWinRTIntegrationPrivate @@ -103,6 +106,10 @@ public: #ifdef Q_OS_WINPHONE ComPtr hardwareButtons; QHash buttonsTokens; + ComPtr cameraButtons; + QHash cameraTokens; + bool cameraHalfPressed : 1; + bool cameraPressed : 1; #endif }; @@ -130,6 +137,23 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate) hr = d->hardwareButtons->add_BackPressed(Callback(this, &QWinRTIntegration::onBackButtonPressed).Get(), &d->buttonsTokens[&IHardwareButtonsStatics::remove_BackPressed]); Q_ASSERT_SUCCEEDED(hr); + + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(), + IID_PPV_ARGS(&d->cameraButtons)); + Q_ASSERT_SUCCEEDED(hr); + if (qEnvironmentVariableIntValue("QT_QPA_ENABLE_CAMERA_KEYS")) { + hr = d->cameraButtons->add_CameraPressed(Callback(this, &QWinRTIntegration::onCameraPressed).Get(), + &d->cameraTokens[&IHardwareButtonsStatics2::remove_CameraPressed]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->cameraButtons->add_CameraHalfPressed(Callback(this, &QWinRTIntegration::onCameraHalfPressed).Get(), + &d->cameraTokens[&IHardwareButtonsStatics2::remove_CameraHalfPressed]); + Q_ASSERT_SUCCEEDED(hr); + hr = d->cameraButtons->add_CameraReleased(Callback(this, &QWinRTIntegration::onCameraReleased).Get(), + &d->cameraTokens[&IHardwareButtonsStatics2::remove_CameraReleased]); + Q_ASSERT_SUCCEEDED(hr); + } + d->cameraPressed = false; + d->cameraHalfPressed = false; #endif // Q_OS_WINPHONE QEventDispatcherWinRT::runOnXamlThread([d]() { @@ -151,6 +175,10 @@ QWinRTIntegration::~QWinRTIntegration() hr = (d->hardwareButtons.Get()->*i.key())(i.value()); Q_ASSERT_SUCCEEDED(hr); } + for (QHash::const_iterator i = d->cameraTokens.begin(); i != d->cameraTokens.end(); ++i) { + hr = (d->cameraButtons.Get()->*i.key())(i.value()); + Q_ASSERT_SUCCEEDED(hr); + } #endif for (QHash::const_iterator i = d->applicationTokens.begin(); i != d->applicationTokens.end(); ++i) { hr = (d->application.Get()->*i.key())(i.value()); @@ -268,6 +296,42 @@ HRESULT QWinRTIntegration::onBackButtonPressed(IInspectable *, IBackPressedEvent args->put_Handled(pressed || released); return S_OK; } + +HRESULT QWinRTIntegration::onCameraPressed(IInspectable *, ICameraEventArgs *) +{ + Q_D(QWinRTIntegration); + QWindow *window = d->mainScreen->topWindow(); + QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyPress, Qt::Key_Camera, Qt::NoModifier, + 0, 0, 0, QString(), false, 1, false); + d->cameraPressed = true; + return S_OK; +} + +HRESULT QWinRTIntegration::onCameraHalfPressed(IInspectable *, ICameraEventArgs *) +{ + Q_D(QWinRTIntegration); + QWindow *window = d->mainScreen->topWindow(); + QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyPress, Qt::Key_CameraFocus, Qt::NoModifier, + 0, 0, 0, QString(), false, 1, false); + d->cameraHalfPressed = true; + return S_OK; +} + +HRESULT QWinRTIntegration::onCameraReleased(IInspectable *, ICameraEventArgs *) +{ + Q_D(QWinRTIntegration); + QWindow *window = d->mainScreen->topWindow(); + if (d->cameraHalfPressed) + QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyRelease, Qt::Key_CameraFocus, Qt::NoModifier, + 0, 0, 0, QString(), false, 1, false); + + if (d->cameraPressed) + QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyRelease, Qt::Key_Camera, Qt::NoModifier, + 0, 0, 0, QString(), false, 1, false); + d->cameraHalfPressed = false; + d->cameraPressed = false; + return S_OK; +} #endif // Q_OS_WINPHONE HRESULT QWinRTIntegration::onSuspended(IInspectable *, ISuspendingEventArgs *) diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h index 3a151e1ed88..5456f6922f4 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.h +++ b/src/plugins/platforms/winrt/qwinrtintegration.h @@ -52,6 +52,7 @@ namespace ABI { namespace UI { namespace Input { struct IBackPressedEventArgs; + struct ICameraEventArgs; } } } @@ -100,6 +101,9 @@ public: private: #ifdef Q_OS_WINPHONE HRESULT onBackButtonPressed(IInspectable *, ABI::Windows::Phone::UI::Input::IBackPressedEventArgs *args); + HRESULT onCameraPressed(IInspectable *, ABI::Windows::Phone::UI::Input::ICameraEventArgs *); + HRESULT onCameraHalfPressed(IInspectable *, ABI::Windows::Phone::UI::Input::ICameraEventArgs *); + HRESULT onCameraReleased(IInspectable *, ABI::Windows::Phone::UI::Input::ICameraEventArgs *); #endif HRESULT onSuspended(IInspectable *, ABI::Windows::ApplicationModel::ISuspendingEventArgs *); HRESULT onResume(IInspectable *, IInspectable *); From 190c76f685f1dcafbcc762082edcdccdb9bb8b0b Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 16 Dec 2015 15:33:42 +0100 Subject: [PATCH 059/100] winrt: Use winsock2 API for hostname resolution on WinRT/WinPhone That API has been available for WinRT and Windows Phone for some time now. By using it to get the machine name and for hostname resolution we can get rid of some winrt-only code and use qhostinfo_win.cpp on WinRT and Windows phone as well. Additionally the required capability was added to tst_qhostinfo so that this auto test can be run without any manual editing. Change-Id: I63fa5521bf8cdb0c919bd5a0100ea977c865622a Reviewed-by: Maurice Kalinowski --- mkspecs/common/winrt_winphone/qmake.conf | 4 +- mkspecs/common/winrt_winphone/qplatformdefs.h | 10 -- src/corelib/global/qglobal.cpp | 54 +------ src/corelib/global/qglobal.h | 1 - src/network/kernel/kernel.pri | 4 +- src/network/kernel/qhostinfo_win.cpp | 15 +- src/network/kernel/qhostinfo_winrt.cpp | 150 ------------------ .../network/kernel/qhostinfo/qhostinfo.pro | 2 + 8 files changed, 17 insertions(+), 223 deletions(-) delete mode 100644 src/network/kernel/qhostinfo_winrt.cpp diff --git a/mkspecs/common/winrt_winphone/qmake.conf b/mkspecs/common/winrt_winphone/qmake.conf index bf237882ff4..a9450b0c32d 100644 --- a/mkspecs/common/winrt_winphone/qmake.conf +++ b/mkspecs/common/winrt_winphone/qmake.conf @@ -78,9 +78,9 @@ QMAKE_PREFIX_STATICLIB = QMAKE_EXTENSION_STATICLIB = lib QMAKE_LIBS += runtimeobject.lib -QMAKE_LIBS_CORE = +QMAKE_LIBS_CORE += ws2_32.lib QMAKE_LIBS_GUI = -QMAKE_LIBS_NETWORK = +QMAKE_LIBS_NETWORK += ws2_32.lib QMAKE_LIBS_OPENGL_ES2 = $${LIBEGL_NAME}.lib $${LIBGLESV2_NAME}.lib QMAKE_LIBS_OPENGL_ES2_DEBUG = $${LIBEGL_NAME}d.lib $${LIBGLESV2_NAME}d.lib diff --git a/mkspecs/common/winrt_winphone/qplatformdefs.h b/mkspecs/common/winrt_winphone/qplatformdefs.h index 6abac1e94df..14f6c582536 100644 --- a/mkspecs/common/winrt_winphone/qplatformdefs.h +++ b/mkspecs/common/winrt_winphone/qplatformdefs.h @@ -130,14 +130,4 @@ typedef int mode_t; -#ifndef INADDR_ANY -# define INADDR_ANY (u_long)0x00000000 -#endif -#ifndef INADDR_LOOPBACK -# define INADDR_LOOPBACK 0x7f000001 -#endif -#ifndef INADDR_BROADCAST -# define INADDR_BROADCAST (u_long)0xffffffff -#endif - #endif // QPLATFORMDEFS_H diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 81925642f8c..e8c50dff2b2 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -66,18 +66,8 @@ #endif #ifdef Q_OS_WINRT -#include -#include -#include -#include -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::Foundation::Collections; -using namespace ABI::Windows::Networking; -using namespace ABI::Windows::Networking::Connectivity; -using namespace ABI::Windows::Networking::Sockets; -#endif +#include +#endif // Q_OS_WINRT #if defined(Q_OS_VXWORKS) && defined(_WRS_KERNEL) # include @@ -1880,8 +1870,6 @@ QT_BEGIN_INCLUDE_NAMESPACE #include "qt_windows.h" QT_END_INCLUDE_NAMESPACE -#ifndef Q_OS_WINRT - # ifndef QT_BOOTSTRAPPED class QWindowsSockInit { @@ -1912,8 +1900,6 @@ QWindowsSockInit::~QWindowsSockInit() Q_GLOBAL_STATIC(QWindowsSockInit, winsockInit) # endif // QT_BOOTSTRAPPED -#endif // !Q_OS_WINRT - #ifdef Q_OS_WINRT static inline HMODULE moduleHandleForFunction(LPCVOID address) { @@ -2797,42 +2783,6 @@ QString QSysInfo::machineHostName() struct utsname u; if (uname(&u) == 0) return QString::fromLocal8Bit(u.nodename); -#elif defined(Q_OS_WINRT) - ComPtr statics; - GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Connectivity_NetworkInformation).Get(), &statics); - - ComPtr> hostNames; - statics->GetHostNames(&hostNames); - if (!hostNames) - return QString(); - - unsigned int size; - hostNames->get_Size(&size); - if (size == 0) - return QString(); - - for (unsigned int i = 0; i < size; ++i) { - ComPtr hostName; - hostNames->GetAt(i, &hostName); - HostNameType type; - hostName->get_Type(&type); - if (type != HostNameType_DomainName) - continue; - - HString name; - hostName->get_CanonicalName(name.GetAddressOf()); - UINT32 length; - PCWSTR rawString = name.GetRawBuffer(&length); - return QString::fromWCharArray(rawString, length); - } - ComPtr firstHost; - hostNames->GetAt(0, &firstHost); - - HString name; - firstHost->get_CanonicalName(name.GetAddressOf()); - UINT32 length; - PCWSTR rawString = name.GetRawBuffer(&length); - return QString::fromWCharArray(rawString, length); #else # ifdef Q_OS_WIN // Important: QtNetwork depends on machineHostName() initializing ws2_32.dll diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 07a0b5e27ac..2551dcb5d3f 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -611,7 +611,6 @@ class QDataStream; #if defined(Q_OS_WINRT) # define QT_NO_FILESYSTEMWATCHER -# define QT_NO_GETADDRINFO # define QT_NO_NETWORKPROXY # define QT_NO_PROCESS # define QT_NO_SOCKETNOTIFIER diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 435bfd6c27d..ddb30b7b6fe 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -33,16 +33,16 @@ android { } win32: { + SOURCES += kernel/qhostinfo_win.cpp + !winrt { SOURCES += kernel/qdnslookup_win.cpp \ - kernel/qhostinfo_win.cpp \ kernel/qnetworkinterface_win.cpp LIBS_PRIVATE += -ldnsapi -liphlpapi DEFINES += WINVER=0x0600 _WIN32_WINNT=0x0600 } else { SOURCES += kernel/qdnslookup_winrt.cpp \ - kernel/qhostinfo_winrt.cpp \ kernel/qnetworkinterface_winrt.cpp } } diff --git a/src/network/kernel/qhostinfo_win.cpp b/src/network/kernel/qhostinfo_win.cpp index da28cd48c1d..7e45e9f9498 100644 --- a/src/network/kernel/qhostinfo_win.cpp +++ b/src/network/kernel/qhostinfo_win.cpp @@ -34,7 +34,6 @@ #include #include "qhostinfo_p.h" -#include "private/qnativesocketengine_p.h" #include #include #include @@ -77,14 +76,18 @@ static void resolveLibrary() { // Attempt to resolve getaddrinfo(); without it we'll have to fall // back to gethostbyname(), which has no IPv6 support. -#if !defined(Q_OS_WINCE) - local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getaddrinfo"); - local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo"); - local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo"); -#else +#if defined(Q_OS_WINCE) local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "getaddrinfo"); local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "freeaddrinfo"); local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2"), "getnameinfo"); +#elif defined (Q_OS_WINRT) + local_getaddrinfo = (getaddrinfoProto) &getaddrinfo; + local_freeaddrinfo = (freeaddrinfoProto) &freeaddrinfo; + local_getnameinfo = (getnameinfoProto) getnameinfo; +#else + local_getaddrinfo = (getaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getaddrinfo"); + local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo"); + local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo"); #endif } diff --git a/src/network/kernel/qhostinfo_winrt.cpp b/src/network/kernel/qhostinfo_winrt.cpp deleted file mode 100644 index 1840bebd398..00000000000 --- a/src/network/kernel/qhostinfo_winrt.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtNetwork module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qhostinfo_p.h" - -#include -#include - -#include -#include -#include -#include -using namespace Microsoft::WRL; -using namespace Microsoft::WRL::Wrappers; -using namespace ABI::Windows::Foundation; -using namespace ABI::Windows::Foundation::Collections; -using namespace ABI::Windows::Networking; -using namespace ABI::Windows::Networking::Connectivity; -using namespace ABI::Windows::Networking::Sockets; - -QT_BEGIN_NAMESPACE - -#define E_NO_SUCH_HOST 0x80072af9 - -//#define QHOSTINFO_DEBUG - -QHostInfo QHostInfoAgent::fromName(const QString &hostName) -{ - QHostInfo results; - - QHostAddress address; - if (address.setAddress(hostName)) { - // Reverse lookup - // TODO: is there a replacement for getnameinfo for winrt? - Q_UNIMPLEMENTED(); - return results; - } - - QByteArray aceHostname = QUrl::toAce(hostName); - results.setHostName(hostName); - if (aceHostname.isEmpty()) { - results.setError(QHostInfo::HostNotFound); - results.setErrorString(hostName.isEmpty() ? tr("No host name given") : tr("Invalid hostname")); - return results; - } - - ComPtr hostnameFactory; - HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), - IID_PPV_ARGS(&hostnameFactory)); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr host; - HStringReference hostNameRef((const wchar_t*)hostName.utf16()); - hr = hostnameFactory->CreateHostName(hostNameRef.Get(), &host); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr datagramSocketStatics; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr *>> op; - hr = datagramSocketStatics->GetEndpointPairsAsync(host.Get(), - HString::MakeReference(L"0").Get(), - &op); - Q_ASSERT_SUCCEEDED(hr); - - ComPtr> endpointPairs; - hr = op->GetResults(&endpointPairs); - int waitCount = 0; - while (hr == E_ILLEGAL_METHOD_CALL) { - WaitForSingleObjectEx(GetCurrentThread(), 50, FALSE); - hr = op->GetResults(&endpointPairs); - if (++waitCount > 1200) // Wait for 1 minute max - return results; - } - - if (hr == E_NO_SUCH_HOST || !endpointPairs) { - results.setError(QHostInfo::HostNotFound); - results.setErrorString(tr("Host %1 could not be found.").arg(hostName)); - return results; - } - Q_ASSERT_SUCCEEDED(hr); - - unsigned int size; - hr = endpointPairs->get_Size(&size); - Q_ASSERT_SUCCEEDED(hr); - QList addresses; - for (unsigned int i = 0; i < size; ++i) { - ComPtr endpointpair; - hr = endpointPairs->GetAt(i, &endpointpair); - Q_ASSERT_SUCCEEDED(hr); - ComPtr remoteHost; - hr = endpointpair->get_RemoteHostName(&remoteHost); - Q_ASSERT_SUCCEEDED(hr); - if (!remoteHost) - continue; - HostNameType type; - hr = remoteHost->get_Type(&type); - Q_ASSERT_SUCCEEDED(hr); - if (type == HostNameType_DomainName) - continue; - - HString name; - hr = remoteHost->get_CanonicalName(name.GetAddressOf()); - Q_ASSERT_SUCCEEDED(hr); - UINT32 length; - PCWSTR rawString = name.GetRawBuffer(&length); - QHostAddress addr; - addr.setAddress(QString::fromWCharArray(rawString, length)); - if (!addresses.contains(addr)) - addresses.append(addr); - } - results.setAddresses(addresses); - - return results; -} - -// QString QHostInfo::localDomainName() defined in qnetworkinterface_win.cpp - -QT_END_NAMESPACE diff --git a/tests/auto/network/kernel/qhostinfo/qhostinfo.pro b/tests/auto/network/kernel/qhostinfo/qhostinfo.pro index c9b795d0988..12858c97eee 100644 --- a/tests/auto/network/kernel/qhostinfo/qhostinfo.pro +++ b/tests/auto/network/kernel/qhostinfo/qhostinfo.pro @@ -14,3 +14,5 @@ wince { # needed for getaddrinfo with official MinGW mingw:DEFINES += _WIN32_WINNT=0x0501 + +winrt: WINRT_MANIFEST.capabilities += internetClientServer From 47b5b5d1065085974737aaca44f229704b59b49b Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 16 Dec 2015 15:05:40 +0100 Subject: [PATCH 060/100] winrt: Use "await" with its timeout for dns queries By using await instead of using a custom wait function we get rid of a lot of "function was called at an unexpected time" warnings and use the default way of waiting for an asynchronous function to complete. Change-Id: I6c5bf73ccf68a219b8f3facd3531873d7e8d4c67 Reviewed-by: Maurice Kalinowski --- src/network/kernel/qdnslookup_winrt.cpp | 47 +++++++++++++++---------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/src/network/kernel/qdnslookup_winrt.cpp b/src/network/kernel/qdnslookup_winrt.cpp index 8c6f9bfda5c..8be63f18466 100644 --- a/src/network/kernel/qdnslookup_winrt.cpp +++ b/src/network/kernel/qdnslookup_winrt.cpp @@ -33,6 +33,7 @@ #include "qdnslookup_p.h" +#include #include #include @@ -50,6 +51,8 @@ using namespace ABI::Windows::Networking; using namespace ABI::Windows::Networking::Connectivity; using namespace ABI::Windows::Networking::Sockets; +#define E_NO_SUCH_HOST 0x80072af9 + QT_BEGIN_NAMESPACE void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply) @@ -83,40 +86,47 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN } ComPtr host; HStringReference hostNameRef((const wchar_t*)aceHostname.utf16()); - hostnameFactory->CreateHostName(hostNameRef.Get(), &host); + hr = hostnameFactory->CreateHostName(hostNameRef.Get(), &host); + Q_ASSERT_SUCCEEDED(hr); ComPtr datagramSocketStatics; - GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics); + hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics); + Q_ASSERT_SUCCEEDED(hr); ComPtr *>> op; - datagramSocketStatics->GetEndpointPairsAsync(host.Get(), + hr = datagramSocketStatics->GetEndpointPairsAsync(host.Get(), HString::MakeReference(L"0").Get(), &op); + Q_ASSERT_SUCCEEDED(hr); ComPtr> endpointPairs; - hr = op->GetResults(&endpointPairs); - int waitCount = 0; - while (hr == E_ILLEGAL_METHOD_CALL) { - WaitForSingleObjectEx(GetCurrentThread(), 50, FALSE); - hr = op->GetResults(&endpointPairs); - if (++waitCount > 1200) // Wait for 1 minute max - return; + hr = QWinRTFunctions::await(op, endpointPairs.GetAddressOf(), QWinRTFunctions::YieldThread, 60 * 1000); + if (hr == E_NO_SUCH_HOST || !endpointPairs) { + reply->error = QDnsLookup::NotFoundError; + reply->errorString = tr("Host %1 could not be found.").arg(aceHostname); + return; + } + if (FAILED(hr)) { + reply->error = QDnsLookup::ServerFailureError; + reply->errorString = tr("Unknown error"); + return; } - if (!endpointPairs) - return; - unsigned int size; - endpointPairs->get_Size(&size); + hr = endpointPairs->get_Size(&size); + Q_ASSERT_SUCCEEDED(hr); // endpoint pairs might contain duplicates so we temporarily store addresses in a QSet QSet addresses; for (unsigned int i = 0; i < size; ++i) { ComPtr endpointpair; - endpointPairs->GetAt(i, &endpointpair); + hr = endpointPairs->GetAt(i, &endpointpair); + Q_ASSERT_SUCCEEDED(hr); ComPtr remoteHost; - endpointpair->get_RemoteHostName(&remoteHost); + hr = endpointpair->get_RemoteHostName(&remoteHost); + Q_ASSERT_SUCCEEDED(hr); HostNameType type; - remoteHost->get_Type(&type); + hr = remoteHost->get_Type(&type); + Q_ASSERT_SUCCEEDED(hr); if (type == HostNameType_Bluetooth || type == HostNameType_DomainName || (requestType != QDnsLookup::ANY && ((type == HostNameType_Ipv4 && requestType == QDnsLookup::AAAA) @@ -124,7 +134,8 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN continue; HString name; - remoteHost->get_CanonicalName(name.GetAddressOf()); + hr = remoteHost->get_CanonicalName(name.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); UINT32 length; PCWSTR rawString = name.GetRawBuffer(&length); addresses.insert(QHostAddress(QString::fromWCharArray(rawString, length))); From 452a27e1f0abba550cba24390c03a05d9091bedc Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 2 Sep 2015 11:07:33 +0200 Subject: [PATCH 061/100] Winrt: Show message when command line processing fails/usage should be shown Change-Id: If8f69906beb22f632ccbde92aab5caf914dcb31b Reviewed-by: Friedemann Kleint --- src/corelib/tools/qcommandlineparser.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/corelib/tools/qcommandlineparser.cpp b/src/corelib/tools/qcommandlineparser.cpp index 15c7a0646fb..2bc60c5b9ee 100644 --- a/src/corelib/tools/qcommandlineparser.cpp +++ b/src/corelib/tools/qcommandlineparser.cpp @@ -540,7 +540,13 @@ static inline bool displayMessageBox() static void showParserMessage(const QString &message, MessageType type) { -#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) +#if defined(Q_OS_WINRT) + if (type == UsageMessage) + qInfo(qPrintable(message)); + else + qCritical(qPrintable(message)); + return; +#elif defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WINCE) if (displayMessageBox()) { const UINT flags = MB_OK | MB_TOPMOST | MB_SETFOREGROUND | (type == UsageMessage ? MB_ICONINFORMATION : MB_ICONERROR); @@ -553,7 +559,7 @@ static void showParserMessage(const QString &message, MessageType type) reinterpret_cast(title.utf16()), flags); return; } -#endif // Q_OS_WIN && !QT_BOOTSTRAPPED && !Q_OS_WIN && !Q_OS_WINRT +#endif // Q_OS_WIN && !QT_BOOTSTRAPPED && !Q_OS_WINCE fputs(qPrintable(message), type == UsageMessage ? stdout : stderr); } From 275f182872fa2671da9445ba6295f50f2c283ae6 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Mon, 14 Dec 2015 09:15:16 +0100 Subject: [PATCH 062/100] winrt: Added timeout to await function Instead of using a "custom wait function" in cases, where a timeout is needed (like in qhostinfo_winrt.cpp) we should have the timeout as part of our await function. By having one common place to handle this, we can avoid unnecessary warnings, that might be caused by custom functions. The current implementation in qhostinfo for example causes at least 1 "originate error" exception per call. Change-Id: I7b6cfdfd861af2b0d271465eecaefe4a93e3109b Reviewed-by: Maurice Kalinowski --- src/corelib/kernel/qfunctions_winrt.h | 29 +++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/corelib/kernel/qfunctions_winrt.h b/src/corelib/kernel/qfunctions_winrt.h index ee4e0507937..dc1cbe0adef 100644 --- a/src/corelib/kernel/qfunctions_winrt.h +++ b/src/corelib/kernel/qfunctions_winrt.h @@ -40,6 +40,7 @@ #include #include +#include #include // Convenience macros for handling HRESULT values @@ -160,7 +161,7 @@ enum AwaitStyle }; template -static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr &asyncOp, AwaitStyle awaitStyle) +static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr &asyncOp, AwaitStyle awaitStyle, uint timeout) { Microsoft::WRL::ComPtr asyncInfo; HRESULT hr = asyncOp.As(&asyncInfo); @@ -168,22 +169,34 @@ static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr &asyncOp, Awai return hr; AsyncStatus status; + QElapsedTimer t; + if (timeout) + t.start(); switch (awaitStyle) { case ProcessMainThreadEvents: - while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == Started) + while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == Started) { QCoreApplication::processEvents(); + if (timeout && t.hasExpired(timeout)) + return ERROR_TIMEOUT; + } break; case ProcessThreadEvents: if (QAbstractEventDispatcher *dispatcher = QThread::currentThread()->eventDispatcher()) { - while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == Started) + while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == Started) { dispatcher->processEvents(QEventLoop::AllEvents); + if (timeout && t.hasExpired(timeout)) + return ERROR_TIMEOUT; + } break; } // fall through default: case YieldThread: - while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == Started) + while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == Started) { QThread::yieldCurrentThread(); + if (timeout && t.hasExpired(timeout)) + return ERROR_TIMEOUT; + } break; } @@ -199,9 +212,9 @@ static inline HRESULT _await_impl(const Microsoft::WRL::ComPtr &asyncOp, Awai } template -static inline HRESULT await(const Microsoft::WRL::ComPtr &asyncOp, AwaitStyle awaitStyle = YieldThread) +static inline HRESULT await(const Microsoft::WRL::ComPtr &asyncOp, AwaitStyle awaitStyle = YieldThread, uint timeout = 0) { - HRESULT hr = _await_impl(asyncOp, awaitStyle); + HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout); if (FAILED(hr)) return hr; @@ -209,9 +222,9 @@ static inline HRESULT await(const Microsoft::WRL::ComPtr &asyncOp, AwaitStyle } template -static inline HRESULT await(const Microsoft::WRL::ComPtr &asyncOp, U *results, AwaitStyle awaitStyle = YieldThread) +static inline HRESULT await(const Microsoft::WRL::ComPtr &asyncOp, U *results, AwaitStyle awaitStyle = YieldThread, uint timeout = 0) { - HRESULT hr = _await_impl(asyncOp, awaitStyle); + HRESULT hr = _await_impl(asyncOp, awaitStyle, timeout); if (FAILED(hr)) return hr; From 3c086e50d36f4cba566ed366bc546744372aec40 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 5 Jan 2016 13:47:21 +0100 Subject: [PATCH 063/100] winrt: handle PrelaunchActivated property to pass certification Windows 10 requires apps to handle the PrelaunchActivated property. This enables a faster startup by launching an app and immediately suspending it. This happens by the system and at the time the user launches the app no library loading or initialization is required. By default we opt-out of this and return early. The reason is that we cannot know the type of application written in Qt and whether it breaks the guidelines by using prelaunch. For further details check here: https://msdn.microsoft.com/en-us/library/windows/apps/mt593297.aspx Task-number: QTBUG-50292 Change-Id: I4d0b0b95a03f93b99211d042895404a88ea7cb9d Reviewed-by: Oliver Wolff --- src/winmain/qtmain_winrt.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index 098ae45dc8e..9e5f206ea5b 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -198,6 +198,15 @@ private: HRESULT __stdcall OnLaunched(ILaunchActivatedEventArgs *launchArgs) Q_DECL_OVERRIDE { #if _MSC_VER >= 1900 + ComPtr preArgs; + HRESULT hr = launchArgs->QueryInterface(preArgs.GetAddressOf()); + if (SUCCEEDED(hr)) { + boolean prelaunched; + preArgs->get_PrelaunchActivated(&prelaunched); + if (prelaunched) + return S_OK; + } + commandLine = QString::fromWCharArray(GetCommandLine()).toUtf8(); #endif HString launchCommandLine; From e0cc6e5b8e1be3ce292060d3b0f7f92e1bde82c1 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 4 Jan 2016 15:27:16 +0100 Subject: [PATCH 064/100] winphone: Invoke windeployqt twice unconditionally for vcproj In 50bf54c invoking windeployqt was only required in release mode as MDILXapCompile was not invoked for debug builds with Visual Studio 2013. However, Visual Studio 2015 invokes MDILXapCompile for debug and release. Hence we have to use this workaround unconditionally. Also we cannot limit this to msvc2015 host specs only, as older projects still might be loaded with Visual Studio 2015 causing the build to break. Task-number: QTBUG-49815 Change-Id: Ia120a392967319b945a9746ad489f2db0eed7156 Reviewed-by: Joerg Bornemann Reviewed-by: Oliver Wolff --- qmake/generators/win32/msvc_vcproj.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 1e187075c88..465c8fc3129 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1428,11 +1428,11 @@ void VcprojGenerator::initWinDeployQtTool() // itself contains the original subdirectories as parameters and hence the // call fails. // Neither there is a way to disable this behavior for Windows Phone, nor - // to influence the parameters. Hence the only way to get a release build + // to influence the parameters. Hence the only way to get a build // done is to recreate the directory structure manually by invoking // windeployqt a second time, so that the MDILXapCompile call succeeds and // deployment continues. - if (conf.WinPhone && conf.Name == QStringLiteral("Release|ARM")) { + if (conf.WinPhone) { conf.windeployqt.CommandLine = commandLine + QStringLiteral(" -list relative -dir \"$(MSBuildProjectDirectory)\\") + var("OBJECTS_DIR") From a1702da020906e1fb5b293257d87209f1795809b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Tue, 5 Jan 2016 14:09:30 +0000 Subject: [PATCH 065/100] Don't detach QGradientStops Change-Id: I1ae84d0ae825e9fb474d4fab45b0c475a3878b25 Reviewed-by: David Faure --- src/gui/painting/qpaintengine_raster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 207e31d91ac..d71297bd600 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -4150,7 +4150,7 @@ public: inline const QRgba64 *getBuffer(const QGradient &gradient, int opacity) { quint64 hash_val = 0; - QGradientStops stops = gradient.stops(); + const QGradientStops stops = gradient.stops(); for (int i = 0; i < stops.size() && i <= 2; i++) hash_val += stops[i].second.rgba64(); From 6d6707c8c390216ac2f69b5771d14ee9141b19d2 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 4 Jan 2016 17:28:51 +0100 Subject: [PATCH 066/100] Fix access after delete in GTK2 dialog helpers Each QGtk2*DialogHelper class owns a QGtk2Dialog. It is possible that QGtk2Dialog's parent window is destroyed before QGtk2*DialogHelper. Then the QGtk2Dialog is destroyed, because of the QWindow parent/child relationship. Before destroying QGtk2*DialogHelper, QQuickPlatformFileDialog calls QGtk2*DialogHelper::hide, which will then operate on the already destroyed QGtk2Dialog. Break the parent/child relationship when QGtk2Dialog's parent is destroyed. Change-Id: Ie2bda234f759e7bf4d0642accd82fdc38e0379c2 Task-number: QTBUG-49203 Reviewed-by: J-P Nurmi --- .../platformthemes/gtk2/qgtk2dialoghelpers.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp index 2f0bceafe68..857f373759a 100644 --- a/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp +++ b/src/plugins/platformthemes/gtk2/qgtk2dialoghelpers.cpp @@ -71,6 +71,9 @@ Q_SIGNALS: protected: static void onResponse(QGtk2Dialog *dialog, int response); +private slots: + void onParentWindowDestroyed(); + private: GtkWidget *gtkWidget; }; @@ -108,6 +111,8 @@ void QGtk2Dialog::exec() bool QGtk2Dialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) { + connect(parent, &QWindow::destroyed, this, &QGtk2Dialog::onParentWindowDestroyed, + Qt::UniqueConnection); setParent(parent); setFlags(flags); setModality(modality); @@ -144,6 +149,12 @@ void QGtk2Dialog::onResponse(QGtk2Dialog *dialog, int response) emit dialog->reject(); } +void QGtk2Dialog::onParentWindowDestroyed() +{ + // The QGtk2*DialogHelper classes own this object. Make sure the parent doesn't delete it. + setParent(0); +} + QGtk2ColorDialogHelper::QGtk2ColorDialogHelper() { d.reset(new QGtk2Dialog(gtk_color_selection_dialog_new(""))); From bddccfb839f4164039d929bf4f6a64e882855222 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Mon, 28 Dec 2015 13:47:09 +0200 Subject: [PATCH 067/100] Do not use gold linker on Windows Gold only supports ELF binaries, not Windows PE. Change-Id: I72b0f944566bbc8713c71b5cd01f217ab55c8103 Reviewed-by: Friedemann Kleint Reviewed-by: Oswald Buddenhagen --- mkspecs/win32-g++/qmake.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/mkspecs/win32-g++/qmake.conf b/mkspecs/win32-g++/qmake.conf index 9cb811b5bf8..61963c7b0df 100644 --- a/mkspecs/win32-g++/qmake.conf +++ b/mkspecs/win32-g++/qmake.conf @@ -85,7 +85,6 @@ QMAKE_LFLAGS_CXX11 = QMAKE_LFLAGS_CXX14 = QMAKE_LFLAGS_CXX1Z = QMAKE_LFLAGS_GCSECTIONS = -Wl,--gc-sections -QMAKE_LFLAGS_USE_GOLD = -fuse-ld=gold QMAKE_LINK_OBJECT_MAX = 10 QMAKE_LINK_OBJECT_SCRIPT = object_script QMAKE_PREFIX_SHLIB = From 2d8b0d1cd566cc0c3ab600650b66cdc771d8314f Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Mon, 4 Jan 2016 15:09:10 +0100 Subject: [PATCH 068/100] xcb: don't select XInput events on the root window If we select XInput events, then when the mouse is clicked, there will not be a fallback to a core pointer event. But a typical Qt application doesn't own the root window. If the window manager (such as OpenBox, Awesome or fvwm) relies on receiving core pointer click events, e.g. to show a desktop menu, then each time a device is hotplugged while a Qt application is running, we would select XI2 events and thereby prevent the window manager from receiving them. QDesktopWidget's native window is added to m_mapper, even when it isn't mapped. Then after hotplugging there's a hierarchy event, and that calls xi2Select for every window in m_mapper. The assumption with this patch is that the root window does need to be in m_mapper in case the QDesktopWidget is shown (that was done already in Qt 5.1: fca94fa5ed8321e84e7b0ff515620fbb901db545), but xi2Select must avoid selecting XI2 events on it to fix this bug. Task-number: QTBUG-49952 Change-Id: I5c160e879d93fadfce14120ef2e89a4f71d4f599 Reviewed-by: Uli Schlachter Reviewed-by: Paul Olav Tvete --- src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index 1a123703a55..1b84de48344 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -274,7 +274,7 @@ void QXcbConnection::finalizeXInput2() void QXcbConnection::xi2Select(xcb_window_t window) { - if (!m_xi2Enabled) + if (!m_xi2Enabled || window == rootWindow()) return; Display *xDisplay = static_cast(m_xlib_display); From 0b3da1907d46a03e8838c4086b23d48ba69c8776 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Sun, 18 Oct 2015 00:16:15 +0200 Subject: [PATCH 069/100] xcb: fix drag and drop when window is hidden This patch fixes drag and drop operation on XCB platform when window will be hidden. The window can be hidden during dnd operation by switching virtual desktops or by minimizing all windows (show desktop) using key shortcut. The ShapedPixmapWindow must grab mouse before dnd operation if mouse is not grabbed by other window (like in Qt4). Task-number: QTBUG-46243 Change-Id: I807bc842719a2d0ea0f4dcb733c06c1fd08813e1 Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection.cpp | 5 +++++ src/plugins/platforms/xcb/qxcbconnection.h | 3 +++ src/plugins/platforms/xcb/qxcbdrag.cpp | 2 ++ src/plugins/platforms/xcb/qxcbwindow.cpp | 21 ++++++++++++++++++-- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index f93cfde4a59..abb48034cd6 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -556,6 +556,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra , has_xkb(false) , m_buttons(0) , m_focusWindow(0) + , m_mouseGrabber(0) , m_clientLeader(0) , m_systemTrayTracker(0) , m_glIntegration(Q_NULLPTR) @@ -1352,6 +1353,10 @@ void QXcbConnection::setFocusWindow(QXcbWindow *w) { m_focusWindow = w; } +void QXcbConnection::setMouseGrabber(QXcbWindow *w) +{ + m_mouseGrabber = w; +} void QXcbConnection::grabServer() { diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 6d26e88fa27..a6a7b9e7ca1 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -469,6 +469,8 @@ public: QXcbWindow *focusWindow() const { return m_focusWindow; } void setFocusWindow(QXcbWindow *); + QXcbWindow *mouseGrabber() const { return m_mouseGrabber; } + void setMouseGrabber(QXcbWindow *); QByteArray startupId() const { return m_startupId; } void setStartupId(const QByteArray &nextId) { m_startupId = nextId; } @@ -649,6 +651,7 @@ private: Qt::MouseButtons m_buttons; QXcbWindow *m_focusWindow; + QXcbWindow *m_mouseGrabber; xcb_window_t m_clientLeader; QByteArray m_startupId; diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index d19ea241f1e..9296a6d1410 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -194,6 +194,8 @@ void QXcbDrag::startDrag() setUseCompositing(current_virtual_desktop->compositingActive()); QBasicDrag::startDrag(); + if (connection()->mouseGrabber() == Q_NULLPTR) + shapedPixmapWindow()->setMouseGrabEnabled(true); } void QXcbDrag::endDrag() diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index bec167fec2a..4e4a0cdaefd 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -594,12 +594,16 @@ QXcbWindow::~QXcbWindow() { if (window()->type() != Qt::ForeignWindow) destroy(); + else if (connection()->mouseGrabber() == this) + connection()->setMouseGrabber(Q_NULLPTR); } void QXcbWindow::destroy() { if (connection()->focusWindow() == this) doFocusOut(); + if (connection()->mouseGrabber() == this) + connection()->setMouseGrabber(Q_NULLPTR); if (m_syncCounter && m_usingSyncProtocol) Q_XCB_CALL(xcb_sync_destroy_counter(xcb_connection(), m_syncCounter)); @@ -847,6 +851,9 @@ void QXcbWindow::hide() xcb_flush(xcb_connection()); + if (connection()->mouseGrabber() == this) + connection()->setMouseGrabber(Q_NULLPTR); + m_mapped = false; } @@ -2357,6 +2364,8 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev QWindowSystemInterface::handleWindowStateChanged(window(), newState); m_lastWindowStateEvent = newState; m_windowState = newState; + if (m_windowState == Qt::WindowMinimized && connection()->mouseGrabber() == this) + connection()->setMouseGrabber(Q_NULLPTR); } return; } else if (event->atom == atom(QXcbAtom::_NET_FRAME_EXTENTS)) { @@ -2411,9 +2420,15 @@ bool QXcbWindow::setKeyboardGrabEnabled(bool grab) bool QXcbWindow::setMouseGrabEnabled(bool grab) { + if (!grab && connection()->mouseGrabber() == this) + connection()->setMouseGrabber(Q_NULLPTR); #ifdef XCB_USE_XINPUT22 - if (connection()->xi2MouseEvents()) - return connection()->xi2SetMouseGrabEnabled(m_window, grab); + if (connection()->xi2MouseEvents()) { + bool result = connection()->xi2SetMouseGrabEnabled(m_window, grab); + if (grab && result) + connection()->setMouseGrabber(this); + return result; + } #endif if (grab && !connection()->canGrab()) return false; @@ -2432,6 +2447,8 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab) xcb_grab_pointer_reply_t *reply = xcb_grab_pointer_reply(xcb_connection(), cookie, NULL); bool result = !(!reply || reply->status != XCB_GRAB_STATUS_SUCCESS); free(reply); + if (result) + connection()->setMouseGrabber(this); return result; } From 83dedc5b74c4d66c378b1335b134cc558c8a4ea4 Mon Sep 17 00:00:00 2001 From: Takumi ASAKI Date: Tue, 5 Jan 2016 14:28:50 +0900 Subject: [PATCH 070/100] Fix potential crash in FreeType font database for WinCE Change-Id: Iea922c2561d59a67cc26c300325a3f198baaafa7 Reviewed-by: Andy Shaw --- src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index 1b6ee0f383a..684c44acf23 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -310,7 +310,7 @@ static QStringList fontNamesFromTTCFile(const QString &filename) if (ttcTableHeader.majorVersion < 1 || ttcTableHeader.majorVersion > 2) return retVal; QVarLengthArray offsetTable(ttcTableHeader.numFonts); - bytesToRead = sizeof(offsetTable) * ttcTableHeader.numFonts; + bytesToRead = sizeof(quint32) * ttcTableHeader.numFonts; bytesRead = f.read((char*)offsetTable.data(), bytesToRead); if (bytesToRead != bytesRead) return retVal; From e5724533e48c5e136b2f045e04e25bab7e1752eb Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 20 Oct 2015 13:19:35 +0200 Subject: [PATCH 071/100] Remove declaration of method nowhere defined MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia95aac626803a85fea0bc0bc99972eb34215d351 Reviewed-by: Jędrzej Nowacki --- src/corelib/plugin/qfactoryloader.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp index fb5b895851d..dcf1b1a81d7 100644 --- a/src/corelib/plugin/qfactoryloader.cpp +++ b/src/corelib/plugin/qfactoryloader.cpp @@ -79,8 +79,6 @@ public: QString suffix; Qt::CaseSensitivity cs; QStringList loadedPaths; - - void unloadPath(const QString &path); }; QFactoryLoaderPrivate::~QFactoryLoaderPrivate() From daeed4631ab61b68609c009a0628f54a2e6e5e11 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Mon, 4 Jan 2016 14:23:32 +0100 Subject: [PATCH 072/100] Blacklist failing tst_QFile tests (OS X) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit openStandardStreamsFileDescriptors and openStandardStreamsBufferedStreams fail on OS X: lseek somehow works on sequential streams (standard streams) but QFile has pos() == 0 (since it's sequential). Change-Id: I6a6161c012a91de189f59c533880fb8fe7a66d37 Task-number: QTBUG-49841 Reviewed-by: Morten Johan Sørvig Reviewed-by: Tony Sarajärvi --- tests/auto/corelib/io/qfile/BLACKLIST | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/auto/corelib/io/qfile/BLACKLIST b/tests/auto/corelib/io/qfile/BLACKLIST index 7aac313b12f..e3bc093c833 100644 --- a/tests/auto/corelib/io/qfile/BLACKLIST +++ b/tests/auto/corelib/io/qfile/BLACKLIST @@ -3,3 +3,7 @@ msvc-2015 [readLineStdin_lineByLine] msvc-2015 +[openStandardStreamsFileDescriptors] +osx +[openStandardStreamsBufferedStreams] +osx From b1dcdc406446a5e1eb5a7e04d984fed91ceb52ec Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Tue, 5 Jan 2016 15:17:11 +0100 Subject: [PATCH 073/100] Avoid unnecessary detaching of the pending deletions list. This code seems to be hit three times per frame in a hybrid QQ2/Qt3D app, quickly generating thousands of allocations here via the detach in begin(). Heaptrack confirms they are all gone now. Change-Id: I7d09f3f5c2b24a2590b701216715055751306e82 Reviewed-by: Sean Harmer Reviewed-by: Marc Mutz --- src/gui/kernel/qopenglcontext.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 85d05959def..3c033ea39e1 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -1459,11 +1459,11 @@ void QOpenGLContextGroupPrivate::deletePendingResources(QOpenGLContext *ctx) { QMutexLocker locker(&m_mutex); - QList pending = m_pendingDeletion; + const QList pending = m_pendingDeletion; m_pendingDeletion.clear(); - QList::iterator it = pending.begin(); - QList::iterator end = pending.end(); + QList::const_iterator it = pending.begin(); + QList::const_iterator end = pending.end(); while (it != end) { (*it)->freeResource(ctx); delete *it; From e8747d9e9fdc039eadb5bd937f7832164ef6796a Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 4 Jan 2016 12:06:02 +0100 Subject: [PATCH 074/100] Windows/DirectWrite: Dynamically load GetUserDefaultLocaleName(). The function is not available on Windows XP. Task-number: QTBUG-50188 Change-Id: I4ded1a4eb37af84979c3ce1a9af0d95da60b56ac Reviewed-by: Kai Koehne --- .../windows/qwindowsfontenginedirectwrite.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index 5e2e9f64545..a50ee609750 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -645,6 +646,16 @@ QFontEngine *QWindowsFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const return fontEngine; } +// Dynamically resolve GetUserDefaultLocaleName, which is available from Windows +// Vista onwards. ### fixme 5.7: Consider reverting to direct linking. +typedef int (WINAPI *GetUserDefaultLocaleNamePtr)(LPWSTR, int); + +static inline GetUserDefaultLocaleNamePtr resolveGetUserDefaultLocaleName() +{ + QSystemLibrary library(QStringLiteral("kernel32")); + return (GetUserDefaultLocaleNamePtr)library.resolve("GetUserDefaultLocaleName"); +} + void QWindowsFontEngineDirectWrite::initFontInfo(const QFontDef &request, int dpi, IDWriteFont *font) { @@ -663,7 +674,9 @@ void QWindowsFontEngineDirectWrite::initFontInfo(const QFontDef &request, BOOL exists = false; wchar_t localeName[LOCALE_NAME_MAX_LENGTH]; - int defaultLocaleSuccess = GetUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH); + static const GetUserDefaultLocaleNamePtr getUserDefaultLocaleName = resolveGetUserDefaultLocaleName(); + const int defaultLocaleSuccess = getUserDefaultLocaleName + ? getUserDefaultLocaleName(localeName, LOCALE_NAME_MAX_LENGTH) : 0; if (defaultLocaleSuccess) hr = familyNames->FindLocaleName(localeName, &index, &exists); From 4f7a72c1ef4c32e28a916b035de7e802a2870a06 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 6 Jan 2016 10:46:12 +0100 Subject: [PATCH 075/100] Remove doc for non-existent QTest::qCompare() variant. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's no variant with bool first argument. Change-Id: Ib18b50ed6271d21253d075dc72b6e2b8744cf131 Reviewed-by: Topi Reiniö --- src/testlib/qtestcase.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 0847d639fda..286da52be26 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -3682,10 +3682,6 @@ bool QTest::compare_string_helper(const char *t1, const char *t2, const char *ac \internal */ -/*! \fn bool QTest::qCompare(bool const &t1, int const &t2, const char *actual, const char *expected, const char *file, int line) - \internal - */ - /*! \fn bool QTest::qTest(const T& actual, const char *elementName, const char *actualStr, const char *expected, const char *file, int line) \internal */ From a62132b22c77c869d8f8e1e48d197bcce53e50a6 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 6 Jan 2016 09:11:23 +0100 Subject: [PATCH 076/100] Diaglib: Output more information about QWindow. Output surface class/type, screen name and scaling factors. Task-number: QTBUG-50206 Change-Id: I88d3494962b29985cd9e492c1761361b73e0172e Reviewed-by: Joerg Bornemann Reviewed-by: Oliver Wolff --- tests/manual/diaglib/qwindowdump.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/manual/diaglib/qwindowdump.cpp b/tests/manual/diaglib/qwindowdump.cpp index a77bae22e98..c0faefb9188 100644 --- a/tests/manual/diaglib/qwindowdump.cpp +++ b/tests/manual/diaglib/qwindowdump.cpp @@ -38,6 +38,9 @@ # include # include # include +# if QT_VERSION >= 0x050600 +# include +# endif #endif #include #include @@ -131,9 +134,19 @@ void formatWindow(QTextStream &str, const QWindow *w, FormatWindowOptions option str << "[top] "; if (w->isExposed()) str << "[exposed] "; + if (w->surfaceClass() == QWindow::Offscreen) + str << "[offscreen] "; + str << "surface=" << w->surfaceType() << ' '; if (const Qt::WindowState state = w->windowState()) str << "windowState=" << state << ' '; formatRect(str, w->geometry()); + if (w->isTopLevel()) { + str << " \"" << w->screen()->name() << "\" "; +#if QT_VERSION >= 0x050600 + if (QHighDpiScaling::isActive()) + str << "factor=" << QHighDpiScaling::factor(w) << ' '; +#endif + } if (!(options & DontPrintWindowFlags)) { str << ' '; formatWindowFlags(str, w->flags()); From 81ee6e763efc4cb7cac12a9f91578776e9b05a3c Mon Sep 17 00:00:00 2001 From: Harald Meyer Date: Thu, 24 Dec 2015 12:23:14 +0100 Subject: [PATCH 077/100] Fixed crash on iOS devices due to unsupported selector. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added check for traiCollection selector. Task-number: QTBUG-50159 Change-Id: Ie3efafe9e22e59aef862a681ad733f2bb0a5ba49 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosintegration.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm index 0e3da8dce8e..3e6b5e51eab 100644 --- a/src/plugins/platforms/ios/qiosintegration.mm +++ b/src/plugins/platforms/ios/qiosintegration.mm @@ -105,8 +105,10 @@ QIOSIntegration::QIOSIntegration() m_touchDevice = new QTouchDevice; m_touchDevice->setType(QTouchDevice::TouchScreen); QTouchDevice::Capabilities touchCapabilities = QTouchDevice::Position | QTouchDevice::NormalizedPosition; - if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) - touchCapabilities |= QTouchDevice::Pressure; + if ([mainScreen respondsToSelector:@selector(traitCollection)]) { + if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) + touchCapabilities |= QTouchDevice::Pressure; + } m_touchDevice->setCapabilities(touchCapabilities); QWindowSystemInterface::registerTouchDevice(m_touchDevice); QMacInternalPasteboardMime::initializeMimeTypes(); From 50ab7c16d470dbb0984bc2b48c5f49d94106edd0 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 12 Oct 2015 22:47:13 +0200 Subject: [PATCH 078/100] QString: prevent resize() from shedding capacity ...even if reserve() hasn't been called before. [ChangeLog][QtCore][QString] resize() will no longer shrink the capacity. That means resize(0) now reliably preserves capacity(). Change-Id: If499a20990bbf3a20553da14e50a42918d310c9f Reviewed-by: Lars Knoll --- src/corelib/tools/qstring.cpp | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 8c06ec40458..89d9889b2f0 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1676,20 +1676,11 @@ void QString::resize(int size) return; } - if (size == 0 && !d->capacityReserved) { - Data *x = Data::allocate(0); - if (!d->ref.deref()) - Data::deallocate(d); - d = x; - } else { - if (d->ref.isShared() || uint(size) + 1u > d->alloc - || (!d->capacityReserved && size < d->size - && uint(size) + 1u < uint(d->alloc >> 1))) - reallocData(uint(size) + 1u, true); - if (d->alloc) { - d->size = size; - d->data()[size] = '\0'; - } + if (d->ref.isShared() || uint(size) + 1u > d->alloc) + reallocData(uint(size) + 1u, true); + if (d->alloc) { + d->size = size; + d->data()[size] = '\0'; } } From 6e823d283286aab15592f9fde11720c10447c4c5 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 5 Jan 2016 16:04:32 +0100 Subject: [PATCH 079/100] WinCE: Remove QIncrementalSleepTimer from QProcess::waitForFinished Remove a superfluous loop and thus the usage of QIncrementalSleepTimer from QProcess::waitForFinished. We just wait for the process handle. There's no need for a loop that checks multiple wait conditions. This enables us to remove QWindowsPipeWriter from the Windows CE port in a subsequent commit. Change-Id: If6a82405227cf145263dba3726bae959e6871d0e Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qprocess_wince.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp index 9b63ece15c8..acacdb85403 100644 --- a/src/corelib/io/qprocess_wince.cpp +++ b/src/corelib/io/qprocess_wince.cpp @@ -235,20 +235,14 @@ bool QProcessPrivate::waitForFinished(int msecs) qDebug("QProcessPrivate::waitForFinished(%d)", msecs); #endif - QIncrementalSleepTimer timer(msecs); + if (!pid) + return true; - forever { - if (!pid) - return true; - - if (WaitForSingleObject(pid->hProcess, timer.nextSleepTime()) == WAIT_OBJECT_0) { - _q_processDied(); - return true; - } - - if (timer.hasTimedOut()) - break; + if (WaitForSingleObject(pid->hProcess, msecs == -1 ? INFINITE : msecs) == WAIT_OBJECT_0) { + _q_processDied(); + return true; } + setError(QProcess::Timedout); return false; } From 6060ffff88fd4345aa5e89b6e3d761704379ad4e Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Wed, 6 Jan 2016 13:01:22 +0100 Subject: [PATCH 080/100] Fixed recently added "excess colon in front of brace" qmake warning Change-Id: I3a650bb4e27cad00f639e6445c36fa8b69edb5b9 Reviewed-by: Oswald Buddenhagen --- mkspecs/features/android/android.prf | 2 +- mkspecs/features/qt.prf | 4 ++-- mkspecs/features/win32/idcidl.prf | 2 +- mkspecs/features/win32/windows.prf | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mkspecs/features/android/android.prf b/mkspecs/features/android/android.prf index f428f7db876..7d77598e76c 100644 --- a/mkspecs/features/android/android.prf +++ b/mkspecs/features/android/android.prf @@ -3,7 +3,7 @@ contains(TEMPLATE, ".*app") { !contains(TARGET, ".so"): TARGET = lib$${TARGET}.so QMAKE_LFLAGS += -Wl,-soname,$$shell_quote($$TARGET) - android_install: { + android_install { target.path=/libs/$$ANDROID_TARGET_ARCH/ INSTALLS *= target } diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index c3448718b93..72632a14ee2 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -208,7 +208,7 @@ contains(qt_module_deps, qml): \ !isEmpty(IMPORTS._KEYS_) { # add import plugins to LIBS line - for (key, IMPORTS._KEYS_): { + for (key, IMPORTS._KEYS_) { PATH = $$eval(IMPORTS.$${key}.path) PLUGIN = $$eval(IMPORTS.$${key}.plugin) !isEmpty(PATH):!isEmpty(PLUGIN): LIBS *= -L$$PATH -l$${PLUGIN}$$qtPlatformTargetSuffix() @@ -347,7 +347,7 @@ for(QT_CURRENT_VERIFY, $$list($$QT_PLUGIN_VERIFY)) { QT_LINKAGE = -l$${QTPLUG}$$qtPlatformTargetSuffix() # Only link against plugin in static builds - isEqual(QT_CURRENT_VERIFY, QTPLUGIN): { + isEqual(QT_CURRENT_VERIFY, QTPLUGIN) { !isEmpty(QT_PLUGINPATH) { plugpath = $$eval(QT_PLUGIN.$${QTPLUG}.PATH) isEmpty(plugpath): \ diff --git a/mkspecs/features/win32/idcidl.prf b/mkspecs/features/win32/idcidl.prf index a688b3ff413..fba7173e79b 100644 --- a/mkspecs/features/win32/idcidl.prf +++ b/mkspecs/features/win32/idcidl.prf @@ -1,4 +1,4 @@ -build_pass:console: { +build_pass:console { warning("QAxServer applications cannot be console applications.") warning("Remove 'console' from your CONFIG.") } diff --git a/mkspecs/features/win32/windows.prf b/mkspecs/features/win32/windows.prf index 6ea9756f9af..986067fc8c9 100644 --- a/mkspecs/features/win32/windows.prf +++ b/mkspecs/features/win32/windows.prf @@ -5,7 +5,7 @@ contains(TEMPLATE, ".*app") { mingw:DEFINES += QT_NEEDS_QMAIN qt:for(entryLib, $$list($$unique(QMAKE_LIBS_QT_ENTRY))) { - isEqual(entryLib, -lqtmain): { + isEqual(entryLib, -lqtmain) { !contains(QMAKE_DEFAULT_LIBDIRS, $$QT.core.libs): \ QMAKE_LIBS += -L$$QT.core.libs CONFIG(debug, debug|release): QMAKE_LIBS += $${entryLib}$${QT_LIBINFIX}d From caee8f6107ea0a1615c6fdb54c5e9ffd69cd76fe Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 6 Jan 2016 10:01:07 +0100 Subject: [PATCH 081/100] Unbreak ubsan developer-build GCC 5.3's undefined-behavior sanitizer checks that the declared type of the object is a base class of the dynamic type of the object on each access to a member of a class type. It therefore requires the typeinfo for these types, which for polymorphic types is emitted in the TU where the vtable is emitted, too. QFileDialogPrivate is a polymorphic non-exported class, so this failed at link-time. Ditto for the other cases. Fix by autotest-exporting the classs. Also, where applicable, de-inline the dtors, so the vtable (and typeinfo) are pinned to one TU, and the ctor, just because it's the correct thing to do. Change-Id: I2b7dba776282a2809c80eb2bc36440d7d698f926 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/dialogs/qfontdialog.cpp | 9 +++++++++ src/widgets/dialogs/qfontdialog_p.h | 7 +++---- src/widgets/graphicsview/qgraphicsproxywidget_p.h | 2 +- src/widgets/itemviews/qlistview_p.h | 2 +- src/widgets/widgets/qdatetimeedit.cpp | 4 ++++ src/widgets/widgets/qdatetimeedit_p.h | 3 ++- src/widgets/widgets/qlabel_p.h | 2 +- 7 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp index 688e8f5c133..008bccaf3fd 100644 --- a/src/widgets/dialogs/qfontdialog.cpp +++ b/src/widgets/dialogs/qfontdialog.cpp @@ -102,6 +102,15 @@ QFontListView::QFontListView(QWidget *parent) static const Qt::WindowFlags DefaultWindowFlags = Qt::Dialog | Qt::WindowSystemMenuHint; +QFontDialogPrivate::QFontDialogPrivate() + : writingSystem(QFontDatabase::Any), options(new QFontDialogOptions) +{ +} + +QFontDialogPrivate::~QFontDialogPrivate() +{ +} + /*! \class QFontDialog \ingroup standard-dialogs diff --git a/src/widgets/dialogs/qfontdialog_p.h b/src/widgets/dialogs/qfontdialog_p.h index e456faaa618..7b92b67f5c2 100644 --- a/src/widgets/dialogs/qfontdialog_p.h +++ b/src/widgets/dialogs/qfontdialog_p.h @@ -65,14 +65,13 @@ class QGroupBox; class QLabel; class QLineEdit; -class QFontDialogPrivate : public QDialogPrivate +class Q_AUTOTEST_EXPORT QFontDialogPrivate : public QDialogPrivate { Q_DECLARE_PUBLIC(QFontDialog) public: - inline QFontDialogPrivate() - : writingSystem(QFontDatabase::Any), options(new QFontDialogOptions) - { } + QFontDialogPrivate(); + ~QFontDialogPrivate(); QPlatformFontDialogHelper *platformFontDialogHelper() const { return static_cast(platformHelper()); } diff --git a/src/widgets/graphicsview/qgraphicsproxywidget_p.h b/src/widgets/graphicsview/qgraphicsproxywidget_p.h index 7b164a0067b..c0e0d73aa90 100644 --- a/src/widgets/graphicsview/qgraphicsproxywidget_p.h +++ b/src/widgets/graphicsview/qgraphicsproxywidget_p.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE -class QGraphicsProxyWidgetPrivate : public QGraphicsWidgetPrivate +class Q_AUTOTEST_EXPORT QGraphicsProxyWidgetPrivate : public QGraphicsWidgetPrivate { Q_DECLARE_PUBLIC(QGraphicsProxyWidget) public: diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h index c1b5b8772c8..62fa45e6403 100644 --- a/src/widgets/itemviews/qlistview_p.h +++ b/src/widgets/itemviews/qlistview_p.h @@ -293,7 +293,7 @@ private: }; -class QListViewPrivate: public QAbstractItemViewPrivate +class Q_AUTOTEST_EXPORT QListViewPrivate: public QAbstractItemViewPrivate { Q_DECLARE_PUBLIC(QListView) public: diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index 42987df3ecd..abee788a46e 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -1687,6 +1687,10 @@ QDateTimeEditPrivate::QDateTimeEditPrivate() #endif } +QDateTimeEditPrivate::~QDateTimeEditPrivate() +{ +} + void QDateTimeEditPrivate::updateTimeSpec() { minimum = minimum.toDateTime().toTimeSpec(spec); diff --git a/src/widgets/widgets/qdatetimeedit_p.h b/src/widgets/widgets/qdatetimeedit_p.h index 50e2cde8cc8..4a6014000b0 100644 --- a/src/widgets/widgets/qdatetimeedit_p.h +++ b/src/widgets/widgets/qdatetimeedit_p.h @@ -62,11 +62,12 @@ QT_BEGIN_NAMESPACE class QCalendarPopup; -class QDateTimeEditPrivate : public QAbstractSpinBoxPrivate, public QDateTimeParser +class Q_AUTOTEST_EXPORT QDateTimeEditPrivate : public QAbstractSpinBoxPrivate, public QDateTimeParser { Q_DECLARE_PUBLIC(QDateTimeEdit) public: QDateTimeEditPrivate(); + ~QDateTimeEditPrivate(); void init(const QVariant &var); void readLocaleSettings(); diff --git a/src/widgets/widgets/qlabel_p.h b/src/widgets/widgets/qlabel_p.h index bd7a9d1e8fa..b4da56c290a 100644 --- a/src/widgets/widgets/qlabel_p.h +++ b/src/widgets/widgets/qlabel_p.h @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE -class QLabelPrivate : public QFramePrivate +class Q_AUTOTEST_EXPORT QLabelPrivate : public QFramePrivate { Q_DECLARE_PUBLIC(QLabel) public: From 14a5a175ae30e72d7cb19fe5297c3948f484bd4f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 6 Jan 2016 10:02:04 +0100 Subject: [PATCH 082/100] QFontDialog: optimize allocation of QFontDialogOptions Use QSharedPointer::create(), to fuse control block and payload into a single memory allocation. Change-Id: I8d87c73566c3be960e957ec0b5419a77da2fc8c9 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/widgets/dialogs/qfontdialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp index 008bccaf3fd..d0177941f7e 100644 --- a/src/widgets/dialogs/qfontdialog.cpp +++ b/src/widgets/dialogs/qfontdialog.cpp @@ -103,7 +103,8 @@ static const Qt::WindowFlags DefaultWindowFlags = Qt::Dialog | Qt::WindowSystemMenuHint; QFontDialogPrivate::QFontDialogPrivate() - : writingSystem(QFontDatabase::Any), options(new QFontDialogOptions) + : writingSystem(QFontDatabase::Any), + options(QSharedPointer::create()) { } From f3114120f2d6f81f424ee542635c2711f66b516b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Tue, 5 Jan 2016 00:58:50 +0100 Subject: [PATCH 083/100] QtGui: Don't set a screen to a child window This is a partial revert of eaa3a9d0108cdf692f1686cafefb7b834f0e5af6 Task-number: QTBUG-50081 Change-Id: Ic3dc4daa90d7a968a4ebf45d3029c99a12985686 Reviewed-by: Shawn Rutledge --- src/gui/kernel/qwindow.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 83e87776278..21734f16198 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -609,18 +609,20 @@ void QWindow::setParent(QWindow *parent) } QObject::setParent(parent); + d->parentWindow = parent; - QPlatformWindow *parentPlatformWindow = parent ? parent->d_func()->platformWindow : Q_NULLPTR; - - if (parentPlatformWindow) + if (parent) d->disconnectFromScreen(); else d->connectToScreen(newScreen); - if (d->platformWindow) - d->platformWindow->setParent(parentPlatformWindow); - - d->parentWindow = parent; + if (d->platformWindow) { + if (parent && parent->d_func()->platformWindow) { + d->platformWindow->setParent(parent->d_func()->platformWindow); + } else { + d->platformWindow->setParent(0); + } + } QGuiApplicationPrivate::updateBlockedStatus(this); } From 1606a0e508b8ecdcbdff953ef55136c8ff59ba79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Thu, 31 Dec 2015 21:47:41 +0100 Subject: [PATCH 084/100] QDesktopWidget::screenNumber(QWidget*): check virtual sibling screens Find the root widget only when more than one virtual desktop exists and find the screen index using virtual siblings from this root widget. Use intersecting rects instead of middle point to obtain the screen. This can help to get the screen index when the middle point is outside the screen geometry, but part of the window is still on the screen. If the widget is completely outside the screen geometry, -1 is returned. This commit amends: a6b2a4642f07cd6e52b447e1e441b257990a8d03 Change-Id: I80247fc1956a82c487ee6f728d1576bf48b28748 Reviewed-by: Shawn Rutledge --- src/widgets/kernel/qdesktopwidget.cpp | 50 ++++++++++++++++++--------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp index d21e60198ed..e586be206e3 100644 --- a/src/widgets/kernel/qdesktopwidget.cpp +++ b/src/widgets/kernel/qdesktopwidget.cpp @@ -195,28 +195,46 @@ const QRect QDesktopWidget::screenGeometry(int screenNo) const int QDesktopWidget::screenNumber(const QWidget *w) const { if (!w) - return 0; + return primaryScreen(); - // Find the root widget, get a QScreen pointer from it and find - // the screen number. - const QWidget *root = w; - const QWidget *tmp = w; - while ((tmp = tmp->parentWidget())) - root = tmp; - QWindow *winHandle = root->windowHandle(); - if (winHandle) { - int screenIdx = QGuiApplication::screens().indexOf(winHandle->screen()); - if (screenIdx > -1) - return screenIdx; + const QList allScreens = QGuiApplication::screens(); + QList screens = allScreens; + if (screens.isEmpty()) // This should never happen + return primaryScreen(); + + // If there is more than one virtual desktop + if (screens.count() != screens.first()->virtualSiblings().count()) { + // Find the root widget, get a QScreen from it and use the + // virtual siblings for checking the window position. + const QWidget *root = w; + const QWidget *tmp = w; + while ((tmp = tmp->parentWidget())) + root = tmp; + const QWindow *winHandle = root->windowHandle(); + if (winHandle) { + const QScreen *winScreen = winHandle->screen(); + if (winScreen) + screens = winScreen->virtualSiblings(); + } } - // If the screen number cannot be obtained using QScreen pointer, - // get it from window position using screen geometry. + // Get the screen number from window position using screen geometry + // and proper screens. QRect frame = w->frameGeometry(); if (!w->isWindow()) frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0))); - const QPoint midpoint = (frame.topLeft() + frame.bottomRight()) / 2; - return screenNumber(midpoint); + + QScreen *widgetScreen = Q_NULLPTR; + int largestArea = 0; + foreach (QScreen *screen, screens) { + QRect intersected = screen->geometry().intersected(frame); + int area = intersected.width() * intersected.height(); + if (largestArea < area) { + widgetScreen = screen; + largestArea = area; + } + } + return allScreens.indexOf(widgetScreen); } int QDesktopWidget::screenNumber(const QPoint &p) const From b50f0244c8f1b8e229a71018f39ac373d0ba6a1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Fri, 1 Jan 2016 13:56:04 +0100 Subject: [PATCH 085/100] QDesktopWidget::screenNumber(QPoint): fix handling of virtual desktops On X11, QXcbVirtualDesktop represents an X11 screen while QScreen represents an X11 output. In the case that there are multiple screens (possibly with multiple outputs), calculate the screen number correctly: Find the screen index on the primary virtual desktop first to avoid obtaining a screen index which doesn't belong to the primary virtual desktop when screen geometry is similar. Change-Id: I4cbb29b7aa7cd2125759ffbbbe3db4e934feaeae Reviewed-by: Shawn Rutledge --- src/widgets/kernel/qdesktopwidget.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp index e586be206e3..a1c2aebbe69 100644 --- a/src/widgets/kernel/qdesktopwidget.cpp +++ b/src/widgets/kernel/qdesktopwidget.cpp @@ -239,12 +239,25 @@ int QDesktopWidget::screenNumber(const QWidget *w) const int QDesktopWidget::screenNumber(const QPoint &p) const { - QList screens = QGuiApplication::screens(); - - for (int i = 0; i < screens.size(); ++i) - if (screens.at(i)->geometry().contains(p)) - return i; - + const QList screens = QGuiApplication::screens(); + if (!screens.isEmpty()) { + const QList primaryScreens = screens.first()->virtualSiblings(); + // Find the screen index on the primary virtual desktop first + foreach (QScreen *screen, primaryScreens) { + if (screen->geometry().contains(p)) + return screens.indexOf(screen); + } + // If the screen index is not found on primary virtual desktop, find + // the screen index on all screens except the first which was for + // sure in the previous loop. Some other screens may repeat. Find + // only when there is more than one virtual desktop. + if (screens.count() != primaryScreens.count()) { + for (int i = 1; i < screens.size(); ++i) { + if (screens[i]->geometry().contains(p)) + return i; + } + } + } return primaryScreen(); //even better would be closest screen } From e9eb32f332561847e11ada14fd04c919b91d3511 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 6 Jan 2016 14:16:57 +0200 Subject: [PATCH 086/100] Android: Activate Qt::Popup windows On Android, back button will send a CloseEvent to the focused window. This change will activate (focus) the Popup windows when they'll become visible. Task-number: QTBUG-46419 Change-Id: I6787435b24502bbf9a78662a0c6fd159d4ee2e8d Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/plugins/platforms/android/qandroidplatformscreen.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp index 209ce2f7db8..8152f1d53f2 100644 --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp @@ -111,9 +111,13 @@ QAndroidPlatformScreen::~QAndroidPlatformScreen() QWindow *QAndroidPlatformScreen::topWindow() const { - foreach (QAndroidPlatformWindow *w, m_windowStack) - if (w->window()->type() == Qt::Window || w->window()->type() == Qt::Dialog) + foreach (QAndroidPlatformWindow *w, m_windowStack) { + if (w->window()->type() == Qt::Window || + w->window()->type() == Qt::Popup || + w->window()->type() == Qt::Dialog) { return w->window(); + } + } return 0; } From c09412fcea92864c4240bced258a72ab5f73870d Mon Sep 17 00:00:00 2001 From: YAMAMOTO Atsushi Date: Tue, 15 Dec 2015 01:07:40 +0900 Subject: [PATCH 087/100] Windows: Fix QWindowsInputContext for Japanese IME. Change the QWindowsInputContext::composition if it is called with lParam has flags GCS_RESULTSTR and GCS_DELTASTART, it doesn't call endContextComposition. Task-number: QTBUG-49955 Change-Id: I49de3f239bf8a77414e433b255db08f227141158 Reviewed-by: Tasuku Suzuki Reviewed-by: Takumi ASAKI Reviewed-by: Friedemann Kleint Reviewed-by: Andy Shaw Reviewed-by: Liang Qi (cherry picked from qtbase/786984e7e47a63094ad64ec86a4892cc5c0ad6d4) Reviewed-by: Oswald Buddenhagen --- src/plugins/platforms/windows/qwindowsinputcontext.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp index 7e1cc563cb2..56b5561756f 100644 --- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp +++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp @@ -484,7 +484,8 @@ bool QWindowsInputContext::composition(HWND hwnd, LPARAM lParamIn) if (lParam & GCS_RESULTSTR) { // A fixed result, return the converted string event->setCommitString(getCompositionString(himc, GCS_RESULTSTR)); - endContextComposition(); + if (!(lParam & GCS_DELTASTART)) + endContextComposition(); } const bool result = QCoreApplication::sendEvent(m_compositionContext.focusObject, event.data()); qCDebug(lcQpaInputMethods) << '<' << __FUNCTION__ << "sending markup=" From 618e2cc081e09d9222418bd933876224675a7530 Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Wed, 18 Feb 2015 02:13:49 +0100 Subject: [PATCH 088/100] dbus: Add method serial() and replySerial() to class DBusMessage. This patch includes setup of class member 'msg' in QDBusMessagePrivate::toDBusMessage() to be able to get the serial after message sending. Testcases for comparing the 'reply serial to' with the 'serial' are included. Task-number: QTBUG-44490 Change-Id: Iae7c48f5b0c70a6c5ae500904072b38b46dfd876 Reviewed-by: Thiago Macieira --- src/dbus/qdbus_symbols_p.h | 2 + src/dbus/qdbusmessage.cpp | 41 +++++++++++++++++++ src/dbus/qdbusmessage.h | 2 + src/dbus/qdbusmessage_p.h | 2 + .../qdbusconnection/tst_qdbusconnection.cpp | 7 ++++ 5 files changed, 54 insertions(+) diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h index 1991a462e90..67680f6b827 100644 --- a/src/dbus/qdbus_symbols_p.h +++ b/src/dbus/qdbus_symbols_p.h @@ -286,6 +286,8 @@ DEFINEFUNC(const char* , dbus_message_get_sender, (DBusMessage *message), (message), return) DEFINEFUNC(dbus_uint32_t , dbus_message_get_serial, (DBusMessage *message), (message), return) +DEFINEFUNC(dbus_uint32_t , dbus_message_get_reply_serial, (DBusMessage *message), + (message), return) DEFINEFUNC(const char* , dbus_message_get_signature, (DBusMessage *message), (message), return) DEFINEFUNC(int , dbus_message_get_type, (DBusMessage *message), diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp index 32b77875146..e20c851d6c3 100644 --- a/src/dbus/qdbusmessage.cpp +++ b/src/dbus/qdbusmessage.cpp @@ -188,7 +188,12 @@ DBusMessage *QDBusMessagePrivate::toDBusMessage(const QDBusMessage &message, QDB // check if everything is ok if (marshaller.ok) + { + QDBusMessage *m = (QDBusMessage*)&message; + q_dbus_message_ref(msg); + m->d_ptr->msg = msg; return msg; + } // not ok; q_dbus_message_unref(msg); @@ -317,6 +322,16 @@ QDBusMessage QDBusMessagePrivate::makeLocalReply(const QDBusConnectionPrivate &c return QDBusMessage(); // failed } +uint QDBusMessagePrivate::serial() +{ + return msg ? q_dbus_message_get_serial(msg) : reply ? q_dbus_message_get_serial(reply) : 0; +} + +uint QDBusMessagePrivate::replySerial() +{ + return msg ? q_dbus_message_get_reply_serial(msg) : reply ? q_dbus_message_get_reply_serial(reply) : 0; +} + /*! \class QDBusMessage \inmodule QtDBus @@ -632,6 +647,32 @@ QString QDBusMessage::signature() const return d_ptr->signature; } +/*! + Returns the serial of the message or 0 if undefined. + + The serial number is a unique identifier of a message coming from a + given connection. + + The serial is set to a non zero value after the message has been sent + over a D-Bus connection. +*/ +uint QDBusMessage::serial() const +{ + return d_ptr->serial(); +} + +/*! + Returns the serial of the message this is a reply to or 0 if undefined. + + The serial number is a unique identifier of a message coming from a + given connection and D-Bus messages of 'method return' or 'error' type + use them to match the reply to the method call message. +*/ +uint QDBusMessage::replySerial() const +{ + return d_ptr->replySerial(); +} + /*! Returns the flag that indicates if this message should see a reply or not. This is only meaningful for \l {MethodCallMessage}{method diff --git a/src/dbus/qdbusmessage.h b/src/dbus/qdbusmessage.h index e85d6000807..f6538bd2cf1 100644 --- a/src/dbus/qdbusmessage.h +++ b/src/dbus/qdbusmessage.h @@ -104,6 +104,8 @@ public: QString errorMessage() const; MessageType type() const; QString signature() const; + uint serial() const; + uint replySerial() const; bool isReplyRequired() const; diff --git a/src/dbus/qdbusmessage_p.h b/src/dbus/qdbusmessage_p.h index 5abd4905025..0ad9924cac9 100644 --- a/src/dbus/qdbusmessage_p.h +++ b/src/dbus/qdbusmessage_p.h @@ -93,6 +93,8 @@ public: const QDBusMessage &asSent); static QDBusMessage makeLocalReply(const QDBusConnectionPrivate &conn, const QDBusMessage &asSent); + uint serial(); + uint replySerial(); }; QT_END_NAMESPACE diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp index e91f87d6c8d..a1530a8b864 100644 --- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp @@ -71,6 +71,7 @@ void tst_QDBusConnection::noConnection() QVERIFY(con.callWithCallback(msg, &spy, SLOT(asyncReply)) == 0); QDBusMessage reply = con.call(msg); + QCOMPARE(msg.serial(), reply.replySerial()); QVERIFY(reply.type() == QDBusMessage::ErrorMessage); QDBusReply voidreply(reply); @@ -152,6 +153,7 @@ void tst_QDBusConnection::send() QDBusMessage reply = con.call(msg); + QCOMPARE(msg.serial(), reply.replySerial()); QCOMPARE(reply.arguments().count(), 1); QCOMPARE(reply.arguments().at(0).typeName(), "QStringList"); QVERIFY(reply.arguments().at(0).toStringList().contains(con.baseService())); @@ -171,6 +173,7 @@ void tst_QDBusConnection::sendWithGui() QDBusMessage reply = con.call(msg, QDBus::BlockWithGui); + QCOMPARE(msg.serial(), reply.replySerial()); QCOMPARE(reply.arguments().count(), 1); QCOMPARE(reply.arguments().at(0).typeName(), "QStringList"); QVERIFY(reply.arguments().at(0).toStringList().contains(con.baseService())); @@ -840,6 +843,7 @@ void tst_QDBusConnection::callSelf() QString(), "test3"); msg << 44; reply = connection.call(msg); + QCOMPARE(msg.serial(), reply.replySerial()); QCOMPARE(reply.arguments().value(0).toInt(), 45); } @@ -907,6 +911,7 @@ void tst_QDBusConnection::callSelfByAnotherName() QString(), "test0"); QDBusMessage reply = con.call(msg, QDBus::Block, 1000); + QCOMPARE(msg.serial(), reply.replySerial()); QVERIFY(reply.type() == QDBusMessage::ReplyMessage); } @@ -922,6 +927,7 @@ void tst_QDBusConnection::multipleInterfacesInQObject() QDBusMessage msg = QDBusMessage::createMethodCall(con.baseService(), "/p1", "local.BaseObject", "anotherMethod"); QDBusMessage reply = con.call(msg, QDBus::Block); + QCOMPARE(msg.serial(), reply.replySerial()); QCOMPARE(reply.type(), QDBusMessage::ReplyMessage); QVERIFY(reply.arguments().count() == 0); } @@ -1202,6 +1208,7 @@ void tst_QDBusConnection::callVirtualObjectLocal() QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), path, QString(), "hello"); QDBusMessage reply = con.call(message, QDBus::Block, 5000); + QCOMPARE(message.serial(), reply.replySerial()); QCOMPARE(obj.callCount, 1); QCOMPARE(obj.lastMessage.service(), con.baseService()); QCOMPARE(obj.lastMessage.interface(), QString()); From d3fe4f066f70bc8e4aef06b963444ecdbc3dd00f Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Wed, 18 Feb 2015 02:14:39 +0100 Subject: [PATCH 089/100] dbus: Print out 'serial' and 'serial reply to' with DBusMessage operator<<. The reply serial is displayed for method call returns and errors, while the serial is displayed for all message types. To see a message serial it is required to dump messages after sending, not before. Task-number: QTBUG-44490 Change-Id: I859f50d739ed059d5b2dfe1a2efdf04b906891a7 Reviewed-by: Thiago Macieira --- src/dbus/qdbusintegrator.cpp | 4 ++-- src/dbus/qdbusmessage.cpp | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index f6221d51b6f..0c0109b6b63 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1819,8 +1819,8 @@ bool QDBusConnectionPrivate::send(const QDBusMessage& message) } q_dbus_message_set_no_reply(msg, true); // the reply would not be delivered to anything - qDBusDebug() << this << "sending message (no reply):" << message; emit messageNeedsSending(Q_NULLPTR, msg); + qDBusDebug() << this << "sending message (no reply):" << message; return true; } @@ -2019,8 +2019,8 @@ QDBusPendingCallPrivate *QDBusConnectionPrivate::sendWithReplyAsync(const QDBusM lastError = error; processFinishedCall(pcall); } else { - qDBusDebug() << this << "sending message:" << message; emit messageNeedsSending(pcall, msg, timeout); + qDBusDebug() << this << "sending message:" << message; } return pcall; } diff --git a/src/dbus/qdbusmessage.cpp b/src/dbus/qdbusmessage.cpp index e20c851d6c3..078442f3f1e 100644 --- a/src/dbus/qdbusmessage.cpp +++ b/src/dbus/qdbusmessage.cpp @@ -861,10 +861,16 @@ QDebug operator<<(QDebug dbg, const QDBusMessage &msg) msg.type() == QDBusMessage::SignalMessage) dbg.nospace() << ", path=" << msg.path() << ", interface=" << msg.interface() - << ", member=" << msg.member(); + << ", member=" << msg.member() + << ", serial=" << msg.serial(); if (msg.type() == QDBusMessage::ErrorMessage) dbg.nospace() << ", error name=" << msg.errorName() - << ", error message=" << msg.errorMessage(); + << ", error message=" << msg.errorMessage() + << ", serial=" << msg.serial() + << ", reply serial=" << msg.replySerial(); + else if (msg.type() == QDBusMessage::ReplyMessage) + dbg.nospace() << ", serial=" << msg.serial() + << ", reply serial=" << msg.replySerial(); dbg.nospace() << ", signature=" << msg.signature() << ", contents=("; debugVariantList(dbg, msg.arguments()); From eb0b03c579cfd90ebfeeaa115955a0a924c9ce0f Mon Sep 17 00:00:00 2001 From: Volker Krause Date: Wed, 6 Jan 2016 15:39:01 +0100 Subject: [PATCH 090/100] QPair is too large for QList to be efficient-ish. Qt3D is making heavy use of this, causing the QList node allocations to be among the top 10 per frame allocation sources. Switching to QVector fixes that. Change-Id: I3b4df329710f82bf8d6797ea1f0c79b288a08063 Reviewed-by: Sean Harmer Reviewed-by: Marc Mutz --- src/corelib/thread/qthreadpool.cpp | 10 +++++----- src/corelib/thread/qthreadpool_p.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index b6b3be8d923..e4a53682810 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -204,8 +204,8 @@ void QThreadPoolPrivate::enqueueTask(QRunnable *runnable, int priority) ++runnable->ref; // put it on the queue - QList >::const_iterator begin = queue.constBegin(); - QList >::const_iterator it = queue.constEnd(); + QVector >::const_iterator begin = queue.constBegin(); + QVector >::const_iterator it = queue.constEnd(); if (it != begin && priority > (*(it - 1)).second) it = std::upper_bound(begin, --it, priority); queue.insert(it - begin, qMakePair(runnable, priority)); @@ -299,7 +299,7 @@ bool QThreadPoolPrivate::waitForDone(int msecs) void QThreadPoolPrivate::clear() { QMutexLocker locker(&mutex); - for (QList >::const_iterator it = queue.constBegin(); + for (QVector >::const_iterator it = queue.constBegin(); it != queue.constEnd(); ++it) { QRunnable* r = it->first; if (r->autoDelete() && !--r->ref) @@ -319,8 +319,8 @@ bool QThreadPoolPrivate::stealRunnable(QRunnable *runnable) return false; { QMutexLocker locker(&mutex); - QList >::iterator it = queue.begin(); - QList >::iterator end = queue.end(); + QVector >::iterator it = queue.begin(); + QVector >::iterator end = queue.end(); while (it != end) { if (it->first == runnable) { diff --git a/src/corelib/thread/qthreadpool_p.h b/src/corelib/thread/qthreadpool_p.h index 34728ed3e2c..b03eefcc942 100644 --- a/src/corelib/thread/qthreadpool_p.h +++ b/src/corelib/thread/qthreadpool_p.h @@ -83,7 +83,7 @@ public: QSet allThreads; QQueue waitingThreads; QQueue expiredThreads; - QList > queue; + QVector > queue; QWaitCondition noActiveThreads; bool isExiting; From 7e28079484ec12ce0609419262b869354e7678a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Tue, 5 Jan 2016 15:25:12 +0100 Subject: [PATCH 091/100] QtGui: Fix obtaining the top level window at a point Find the top level window on the primary virtual desktop first to avoid obtaining a window which doesn't belong to the primary virtual desktop when screen geometry is similar. Change-Id: I78fdfa0b5146d0ba9b912338adeb612c102c4ac3 Reviewed-by: Adam Majer Reviewed-by: Shawn Rutledge --- src/gui/kernel/qguiapplication.cpp | 38 +++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 00245b25b09..00e3e2fcf4a 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -964,18 +964,38 @@ qreal QGuiApplication::devicePixelRatio() const */ QWindow *QGuiApplication::topLevelAt(const QPoint &pos) { - QList screens = QGuiApplication::screens(); - QList::const_iterator screen = screens.constBegin(); - QList::const_iterator end = screens.constEnd(); + const QList screens = QGuiApplication::screens(); + if (!screens.isEmpty()) { + const QList primaryScreens = screens.first()->virtualSiblings(); + QScreen *windowScreen = Q_NULLPTR; - while (screen != end) { - if ((*screen)->geometry().contains(pos)) { - const QPoint devicePosition = QHighDpi::toNativePixels(pos, *screen); - return (*screen)->handle()->topLevelAt(devicePosition); + // Find the window on the primary virtual desktop first + foreach (QScreen *screen, primaryScreens) { + if (screen->geometry().contains(pos)) { + windowScreen = screen; + break; + } + } + + // If the window is not found on primary virtual desktop, find it on all screens + // except the first which was for sure in the previous loop. Some other screens + // may repeat. Find only when there is more than one virtual desktop. + if (!windowScreen && screens.count() != primaryScreens.count()) { + for (int i = 1; i < screens.size(); ++i) { + QScreen *screen = screens[i]; + if (screen->geometry().contains(pos)) { + windowScreen = screen; + break; + } + } + } + + if (windowScreen) { + const QPoint devicePosition = QHighDpi::toNativePixels(pos, windowScreen); + return windowScreen->handle()->topLevelAt(devicePosition); } - ++screen; } - return 0; + return Q_NULLPTR; } /*! From 7409e3a42bcfdf4d170832efa076a5795423c1d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Tue, 5 Jan 2016 00:05:21 +0100 Subject: [PATCH 092/100] QtGui: Don't set screen to a child window when processing screen events Setting a screen to a child window causes a warning message. This patch prevents the debug message by catching incorrect behavior made by QPA earlier. Change-Id: Idf3ac02290a18afc134f19c2b91348dc009ca4ca Reviewed-by: Shawn Rutledge --- src/gui/kernel/qguiapplication.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 00e3e2fcf4a..770f8471908 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2090,10 +2090,12 @@ void QGuiApplicationPrivate::processWindowStateChangedEvent(QWindowSystemInterfa void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterfacePrivate::WindowScreenChangedEvent *wse) { if (QWindow *window = wse->window.data()) { - if (QScreen *screen = wse->screen.data()) - window->d_func()->setTopLevelScreen(screen, false /* recreate */); - else // Fall back to default behavior, and try to find some appropriate screen - window->setScreen(0); + if (window->isTopLevel()) { + if (QScreen *screen = wse->screen.data()) + window->d_func()->setTopLevelScreen(screen, false /* recreate */); + else // Fall back to default behavior, and try to find some appropriate screen + window->setScreen(0); + } // we may have changed scaling, so trigger resize event if needed if (window->handle()) { QWindowSystemInterfacePrivate::GeometryChangeEvent gce(window, QHighDpi::fromNativePixels(window->handle()->geometry(), window), QRect()); From b2203b2490031aa13ed90c73c8414081896b649c Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Thu, 7 Jan 2016 10:41:38 +0100 Subject: [PATCH 093/100] doc: correct documentation of QT_AUTO_SCREEN_SCALE_FACTOR env var MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I4fa57279b23911893a615fe8a3ce9854d0fec971 Reviewed-by: Topi Reiniö --- src/gui/kernel/qhighdpiscaling.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp index a3201aa23f7..b0ef2a284fe 100644 --- a/src/gui/kernel/qhighdpiscaling.cpp +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -173,7 +173,7 @@ static inline qreal initialGlobalScaleFactor() include X11, Windows, and Android. There are two APIs for enabling or disabling this behavior: - - The QT_AUTO_SCALE_FACTOR environment variable. + - The QT_AUTO_SCREEN_SCALE_FACTOR environment variable. - The AA_EnableHighDpiScaling and AA_DisableHighDpiScaling application attributes From 6f69a313bd03c4a96f3efcd1ea00068fd5d572e9 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 5 Jan 2016 14:57:35 +0100 Subject: [PATCH 094/100] Fix offset and size for native child rtt widgets Render-to-texture widgets that are native children may have a non-zero offset telling the position within the top-level widget. The size is usually different (smaller) than the tlw's size as well. An unfortunate optimization attempt led to ignoring the size for native children with offset (0, 0). This resulted in interesting rendering artifacts whenever such widgets were placed in the top-left corner of the toplevel. This is now corrected. Task-number: QTBUG-48130 Change-Id: If449610c3f3333cb73ae149efaefd7ef42953951 Reviewed-by: Paul Olav Tvete --- src/gui/painting/qplatformbackingstore.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index cda2446a5ed..4b725fc79fa 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -371,17 +371,13 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i if (textureId) { if (d_ptr->needsSwizzle) d_ptr->blitter->setSwizzleRB(true); - // offset is usually (0, 0) unless we have native child widgets. - if (offset.isNull()) { - d_ptr->blitter->blit(textureId, QMatrix4x4(), origin); - } else { - // The backingstore is for the entire tlw. offset tells the position of the native child in the tlw. - const QRect srcRect = toBottomLeftRect(deviceWindowRect.translated(offset), d_ptr->textureSize.height()); - const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(deviceRect(srcRect, window), - d_ptr->textureSize, - origin); - d_ptr->blitter->blit(textureId, QMatrix4x4(), source); - } + // The backingstore is for the entire tlw. + // In case of native children offset tells the position relative to the tlw. + const QRect srcRect = toBottomLeftRect(deviceWindowRect.translated(offset), d_ptr->textureSize.height()); + const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(deviceRect(srcRect, window), + d_ptr->textureSize, + origin); + d_ptr->blitter->blit(textureId, QMatrix4x4(), source); if (d_ptr->needsSwizzle) d_ptr->blitter->setSwizzleRB(false); } From 5001f6ceba5a1006876e9daf90eaab03ef9fef0c Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 7 Jan 2016 12:40:20 +0100 Subject: [PATCH 095/100] Fix mac build with -no-widgets Unused parameters are errors. Change-Id: I79782a8094491a953d6e838e6b8c5b9d6327f30a Reviewed-by: Simon Hausmann --- src/plugins/platforms/cocoa/qcocoahelpers.mm | 1 + src/plugins/platforms/cocoa/qcocoanativeinterface.mm | 1 + 2 files changed, 2 insertions(+) diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index f51c21ee9ba..7bc8d6585b5 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -604,6 +604,7 @@ void qt_mac_cleanUpMacColorSpaces() CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice) { #ifdef QT_NO_WIDGETS + Q_UNUSED(paintDevice) return qt_mac_displayColorSpace(0); #else bool isWidget = (paintDevice->devType() == QInternal::Widget); diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm index 41ea1fa49cd..baee4519031 100644 --- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm +++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm @@ -162,6 +162,7 @@ void *QCocoaNativeInterface::NSPrintInfoForPrintEngine(QPrintEngine *printEngine macPrintEnginePriv->initialize(); return macPrintEnginePriv->printInfo; #else + Q_UNUSED(printEngine); qFatal("Printing is not supported when Qt is configured with -no-widgets"); return 0; #endif From c7797184f0813606c93fe7316b7b42e28b81b68b Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 7 Jan 2016 17:07:39 +0100 Subject: [PATCH 096/100] Prospective fix for running cmake tests with -no-widgets Don't try to run test_interface when Qt is configured without QtWidgets. Change-Id: If6c376c250215c1d639b06881d16c0141091f288 Reviewed-by: Stephen Kelly --- tests/auto/cmake/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/cmake/CMakeLists.txt b/tests/auto/cmake/CMakeLists.txt index 25bc8a5e457..3a607983f98 100644 --- a/tests/auto/cmake/CMakeLists.txt +++ b/tests/auto/cmake/CMakeLists.txt @@ -127,7 +127,7 @@ if (QT_WITH_ANGLE OR (NOT WIN32 AND NOT APPLE AND NOT NO_EGL)) endif() expect_pass(test_opengl_lib) -if (NOT CMAKE_VERSION VERSION_LESS 2.8.11) +if (NOT CMAKE_VERSION VERSION_LESS 2.8.11 AND NOT NO_WIDGETS) expect_pass(test_interface) endif() From 282f15feaae4c525602d537ab65cb61987eb5f7f Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 23 Nov 2015 14:14:46 +0100 Subject: [PATCH 097/100] rewrite qtAddToolEnv() the primary purpose is making env var prepend mode work for unset variables on windows. this is achieved by using a conditional and delayed variable expansion. however, the latter is disabled by default and can be locally enabled only in batch files. therefore, write wrapper scripts and substitute them for the actual commands. we do this also on unix, both for consistency and simply because the commands look much less confusing. this change is slightly backwards-incompatible, as invoking qtAddToolEnv() multiple times on the same command will now make a total mess. also, invoking it on a command that contains 'make' macro expansions isn't a good idea, so testcase.prf needed an adjustment. the function is an undocumented internal, so Nobody Should Care (TM). this also reverts 80ebedecf9, as it's obsolete now. Change-Id: I8394b77868b495abcf27b688996ca74c40b80994 Reviewed-by: Simon Hausmann --- .gitignore | 4 ++ mkspecs/features/qt_functions.prf | 61 +++++++++++++++++---- mkspecs/features/testcase.prf | 9 +-- qmake/generators/win32/msvc_objectmodel.cpp | 4 -- 4 files changed, 60 insertions(+), 18 deletions(-) diff --git a/.gitignore b/.gitignore index 5a23b64d69d..1ecd8c1009f 100644 --- a/.gitignore +++ b/.gitignore @@ -47,6 +47,10 @@ pcviewer.cfg *_resource.rc .#* *.*# +*_wrapper.sh +*_wrapper.bat +wrapper.sh +wrapper.bat core .qmake.cache .qmake.vars diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index 00f4bdf93e8..abb7439f181 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -70,6 +70,7 @@ defineTest(qtPrepareTool) { } } QT_TOOL_ENV += $$eval(QT_TOOL.$${2}.envvars) + QT_TOOL_NAME = $$2 !isEmpty(3)|!isEmpty(4) { $$1$$3 = for (arg, cmd): \ @@ -90,6 +91,7 @@ defineTest(qtAddToolEnv) { ds = $$QMAKE_DIR_SEP else: \ ds = $$DIR_SEPARATOR + batch_sets = for(env, 2) { value = $$eval($${env}.value) !isEmpty(value) { @@ -97,22 +99,61 @@ defineTest(qtAddToolEnv) { equals(ds, /) { contains($${env}.CONFIG, prepend): infix = \${$$name:+:\$$$name} else: infix = - val = "$$name=$$shell_quote($$join(value, :))$$infix" + # Under msys, this path is taken only in the non-system() + # case, so using shell_quote() always works. + batch_sets += \ + "$$name=$$shell_quote($$join(value, :))$$infix" \ + "export $$name" } else { - # Escape closing parens when expanding the variable, otherwise cmd confuses itself. - contains($${env}.CONFIG, prepend): infix = ;%$$name:)=^)% - else: infix = + value ~= s,\\^,^^^^,g + value ~= s,!,^^!,g value ~= s,\\),^),g - val = "(set $$name=$$join(value, ;)$$infix) &" + contains($${env}.CONFIG, prepend) { + batch_sets += \ + "if defined $$name (" \ + " set $$name=$$join(value, ;);!$$name!" \ + ") else (" \ + " set $$name=$$join(value, ;)" \ + ")" + } else { + batch_sets += "(set $$name=$$join(value, ;))" + } } - isEmpty(3): !contains(TEMPLATE, vc.*) { - contains(MAKEFILE_GENERATOR, MS.*): val ~= s,%,%%,g - val ~= s,\\\$,\$\$,g - } - $$1 = "$$val $$eval($$1)" } } + !isEmpty(batch_sets) { + batch_name = wrapper + !isEmpty(QT_TOOL_NAME): batch_name = $${QT_TOOL_NAME}_wrapper + cmd = $$eval($$1) + !isEmpty(cmd): cmd = "$$cmd " + equals(ds, /) { + batch_name = $${batch_name}.sh + batch_cont = \ + "$$LITERAL_HASH!/bin/sh" \ + $$batch_sets \ + "exec $$cmd\"$@\"" + # It would be nicer to use the '.' command (without 'exec' above), + # but that doesn't set the positional arguments under (d)ash. + $$1 = + } else { + batch_name = $${batch_name}.bat + batch_cont = \ + "@echo off" \ + "SetLocal EnableDelayedExpansion" \ + $$batch_sets \ + "$$cmd%*" \ + "EndLocal" + $$1 = call + } + !build_pass:!write_file($$OUT_PWD/$$batch_name, batch_cont, exe): error("Aborting.") + isEmpty(3): \ + $$1 += $$shell_quote($$shell_path($$OUT_PWD/$$batch_name)) + else: \ + $$1 += $$system_quote($$system_path($$OUT_PWD/$$batch_name)) + QMAKE_DISTCLEAN += $$OUT_PWD/$$batch_name + } export($$1) + export(QMAKE_DISTCLEAN) } # target variable, dependency var name, [non-empty: prepare for system(), not make] diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf index 6bac0546c32..5ad372f976c 100644 --- a/mkspecs/features/testcase.prf +++ b/mkspecs/features/testcase.prf @@ -9,6 +9,11 @@ testcase_exceptions: CONFIG += exceptions check.files = check.path = . +# Add environment for non-installed builds. Do this first, so the +# 'make' variable expansions don't end up in a batch file/script. +QT_TOOL_NAME = target +qtAddTargetEnv(check.commands, QT) + # If the test ends up in a different directory, we should cd to that directory. TESTRUN_CWD = $$DESTDIR @@ -40,10 +45,6 @@ unix { # Allow for custom arguments to tests check.commands += $(TESTARGS) -# Add environment for non-installed builds -qtAddTargetEnv(check.commands, QT) - -# This must happen after adding the environment. !isEmpty(TESTRUN_CWD):!contains(TESTRUN_CWD, ^\\./?): \ check.commands = cd $$shell_path($$TESTRUN_CWD) && $$check.commands diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 339dae953ae..18457ac5ad3 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -2399,11 +2399,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) if (!CustomBuildTool.Description.isEmpty()) CustomBuildTool.Description += ", "; CustomBuildTool.Description += cmd_name; - // Execute custom build steps in an environment variable scope to prevent unwanted - // side effects for downstream build steps - CustomBuildTool.CommandLine += QLatin1String("setlocal"); CustomBuildTool.CommandLine += VCToolBase::fixCommandLine(cmd.trimmed()); - CustomBuildTool.CommandLine += QLatin1String("endlocal"); int space = cmd.indexOf(' '); QFileInfo finf(cmd.left(space)); if (CustomBuildTool.ToolPath.isEmpty()) From c0efee2f265279a4ced90279ad2e7536c596f08c Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 11 Dec 2015 14:14:13 +0100 Subject: [PATCH 098/100] add always_prepend mode to qtAddToolEnv() this is just an optimization/clarification: variables which are known to be never empty (like PATH) can be extended with less convoluted code. Change-Id: Ib365bbec8301673ed1c874979b4de19bc983dab1 Reviewed-by: Romain Pokrzywka Reviewed-by: Simon Hausmann --- mkspecs/features/qt_functions.prf | 11 ++++++++--- src/angle/src/config.pri | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index abb7439f181..6b72db61019 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -96,8 +96,10 @@ defineTest(qtAddToolEnv) { value = $$eval($${env}.value) !isEmpty(value) { name = $$eval($${env}.name) + config = $$eval($${env}.CONFIG) equals(ds, /) { - contains($${env}.CONFIG, prepend): infix = \${$$name:+:\$$$name} + contains(config, prepend): infix = \${$$name:+:\$$$name} + else: contains(config, always_prepend): infix = :\$$$name else: infix = # Under msys, this path is taken only in the non-system() # case, so using shell_quote() always works. @@ -108,13 +110,15 @@ defineTest(qtAddToolEnv) { value ~= s,\\^,^^^^,g value ~= s,!,^^!,g value ~= s,\\),^),g - contains($${env}.CONFIG, prepend) { + contains(config, prepend) { batch_sets += \ "if defined $$name (" \ " set $$name=$$join(value, ;);!$$name!" \ ") else (" \ " set $$name=$$join(value, ;)" \ ")" + } else: contains(config, always_prepend) { + batch_sets += "(set $$name=$$join(value, ;);!$$name!)" } else { batch_sets += "(set $$name=$$join(value, ;))" } @@ -162,8 +166,10 @@ defineTest(qtAddTargetEnv) { deps = $$resolve_depends(deps, "QT.", ".depends" ".run_depends") !isEmpty(deps) { libs = libs + deppath.CONFIG = prepend equals(QMAKE_HOST.os, Windows) { libs = bins + deppath.CONFIG = always_prepend deppath.name = PATH } else:contains(QMAKE_HOST.os, Linux|FreeBSD|OpenBSD|NetBSD|DragonFly|SunOS|HP-UX|QNX|GNU) { deppath.name = LD_LIBRARY_PATH @@ -188,7 +194,6 @@ defineTest(qtAddTargetEnv) { ptypes += $$eval(QT.$${dep}.plugin_types) } deppath.value = $$unique(deppath) - deppath.CONFIG = prepend pluginpath.value = ppaths = $$[QT_INSTALL_PLUGINS/get] diff --git a/src/angle/src/config.pri b/src/angle/src/config.pri index 085913ac83b..be612820693 100644 --- a/src/angle/src/config.pri +++ b/src/angle/src/config.pri @@ -16,7 +16,7 @@ equals(QMAKE_HOST.os, Windows) { gnutools.value = $$absolute_path(../../../../gnuwin32/bin) exists($$gnutools.value/gperf.exe) { gnutools.name = PATH - gnutools.CONFIG = prepend + gnutools.CONFIG = always_prepend } } From d3518b752583d6d725f4adb14f804ae6d7cfa650 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 11 Dec 2015 14:53:18 +0100 Subject: [PATCH 099/100] Revert "use bindir instead of libdir when launching tools on windows" proper prefix builds don't have the redundant .dlls in bin (the copy step is simply omitted), so this is broken. the change would have to be done atomically with making DLLDESTDIR sane. This reverts commit 9b2e98245a95bec9179edf648d7b562d2d1cb692. Task-number: QTBUG-50065 Change-Id: I9ce0a2d1147a1a2d4bd2f22e619d5c737864a637 Reviewed-by: Romain Pokrzywka Reviewed-by: Tim Blechmann Reviewed-by: Frederik Gladhorn Reviewed-by: Simon Hausmann --- mkspecs/features/qt_functions.prf | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index 6b72db61019..c23d006d828 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -165,10 +165,8 @@ defineTest(qtAddTargetEnv) { deps = $$replace($$2, -private$, _private) deps = $$resolve_depends(deps, "QT.", ".depends" ".run_depends") !isEmpty(deps) { - libs = libs deppath.CONFIG = prepend equals(QMAKE_HOST.os, Windows) { - libs = bins deppath.CONFIG = always_prepend deppath.name = PATH } else:contains(QMAKE_HOST.os, Linux|FreeBSD|OpenBSD|NetBSD|DragonFly|SunOS|HP-UX|QNX|GNU) { @@ -188,9 +186,9 @@ defineTest(qtAddTargetEnv) { ptypes = for(dep, deps) { isEmpty(3): \ - deppath += $$shell_path($$eval(QT.$${dep}.$$libs)) + deppath += $$shell_path($$eval(QT.$${dep}.libs)) else: \ - deppath += $$system_path($$eval(QT.$${dep}.$$libs)) + deppath += $$system_path($$eval(QT.$${dep}.libs)) ptypes += $$eval(QT.$${dep}.plugin_types) } deppath.value = $$unique(deppath) From 09c92863001790a0304a5ef389901ee2b5b6cdc2 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Fri, 11 Dec 2015 15:01:24 +0100 Subject: [PATCH 100/100] fix doc builds in paths with spaces Change-Id: Ie76411e3a4a8df69ff9b12a18480d1a987fac639 Reviewed-by: Joerg Bornemann Reviewed-by: Frederik Gladhorn --- mkspecs/features/qt_docs.prf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mkspecs/features/qt_docs.prf b/mkspecs/features/qt_docs.prf index 15bd12072a4..37b2f061937 100644 --- a/mkspecs/features/qt_docs.prf +++ b/mkspecs/features/qt_docs.prf @@ -31,9 +31,9 @@ qtdocs.value = $$[QT_INSTALL_DOCS/src] QT_TOOL_ENV = qtver qtmver qtvertag qtdocs qtPrepareTool(QDOC, qdoc) QT_TOOL_ENV = -QDOC += -outputdir $$QMAKE_DOCS_OUTPUTDIR +QDOC += -outputdir $$shell_quote($$QMAKE_DOCS_OUTPUTDIR) !build_online_docs: \ - QDOC += -installdir $$[QT_INSTALL_DOCS] + QDOC += -installdir $$shell_quote($$[QT_INSTALL_DOCS]) PREP_DOC_INDEXES = DOC_INDEXES = !isEmpty(QTREPOS) { @@ -46,14 +46,14 @@ DOC_INDEXES = mps += $$dirname(QT.$${d}.libs) mps = $$unique(mps) for (mp, mps): \ - PREP_DOC_INDEXES += -indexdir $$mp/doc + PREP_DOC_INDEXES += -indexdir $$shell_quote($$mp/doc) } for(qrep, QTREPOS): \ - DOC_INDEXES += -indexdir $$qrep/doc + DOC_INDEXES += -indexdir $$shell_quote($$qrep/doc) } else { prepare_docs: \ - PREP_DOC_INDEXES += -indexdir $$[QT_INSTALL_DOCS/get] - DOC_INDEXES += -indexdir $$[QT_INSTALL_DOCS/get] + PREP_DOC_INDEXES += -indexdir $$shell_quote($$[QT_INSTALL_DOCS/get]) + DOC_INDEXES += -indexdir $$shell_quote($$[QT_INSTALL_DOCS/get]) } doc_command = $$QDOC $$QMAKE_DOCS prepare_docs { @@ -65,7 +65,7 @@ prepare_docs { !build_online_docs { qtPrepareTool(QHELPGENERATOR, qhelpgenerator) - qch_docs.commands = $$QHELPGENERATOR $$QMAKE_DOCS_OUTPUTDIR/$${QMAKE_DOCS_TARGET}.qhp -o $$QMAKE_DOCS_BASE_OUTDIR/$${QMAKE_DOCS_TARGET}.qch + qch_docs.commands = $$QHELPGENERATOR $$shell_quote($$QMAKE_DOCS_OUTPUTDIR/$${QMAKE_DOCS_TARGET}.qhp) -o $$shell_quote($$QMAKE_DOCS_BASE_OUTDIR/$${QMAKE_DOCS_TARGET}.qch) inst_html_docs.files = $$QMAKE_DOCS_OUTPUTDIR inst_html_docs.path = $$[QT_INSTALL_DOCS]