diff options
122 files changed, 2193 insertions, 1133 deletions
diff --git a/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro b/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro index b63c75c070..ce16a3a391 100644 --- a/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro +++ b/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro @@ -4,4 +4,8 @@ CONFIG -= qt INCLUDEPATH += $$QMAKE_INCDIR_EGL -LIBS += -L$$QMAKE_LIBDIR_EGL -lEGL -lGLESv2 -lbcm_host +for(p, QMAKE_LIBDIR_EGL) { + exists($$p):LIBS += -L$$p +} + +LIBS += -lEGL -lGLESv2 -lbcm_host @@ -2962,8 +2962,20 @@ if [ -f "$relpath"/LICENSE.PREVIEW.COMMERCIAL ] && [ $COMMERCIAL_USER = "yes" ]; Edition="Preview" EditionString="Technology Preview" elif [ $COMMERCIAL_USER = "yes" ]; then - if test -x "$relpath/bin/licheck"; then - LicheckOutput=`$relpath/bin/licheck $OPT_CONFIRM_LICENSE $relpath $outpath\ + if [ $UNAME_SYSTEM = "Linux" ]; then + if file -L /bin/sh | grep -q "64-bit" ; then + Licheck=licheck64 + else + Licheck=licheck32 + fi + elif [ $UNAME_SYSTEM = "Darwin" ]; then + Licheck=licheck_mac + else + echo >&2 "Host operating system not supported by this edition of Qt." + exit 1 + fi + if [ -x "$relpath/bin/$Licheck" ]; then + LicheckOutput=`$relpath/bin/$Licheck $OPT_CONFIRM_LICENSE $relpath $outpath\ $PLATFORM $XPLATFORM` if [ $? -ne 0 ]; then exit 1 @@ -2974,7 +2986,7 @@ elif [ $COMMERCIAL_USER = "yes" ]; then echo echo "Error: This is the Open Source version of Qt." echo "If you want to use Enterprise features of Qt," - echo "information use the contact form at http://www.qt.io/contact-us" + echo "use the contact form at http://www.qt.io/contact-us" echo "to purchase a license." echo exit 1 @@ -5346,6 +5358,14 @@ fi # auto-detect XInput2 support if [ "$CFG_XINPUT2" != "no" ]; then if compileTest x11/xinput2 "XInput2"; then + if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists xi 2>/dev/null; then + QMAKE_LIBXI_VERSION_MAJOR=`$PKG_CONFIG --modversion xi 2>/dev/null | cut -d . -f 1` + QMAKE_LIBXI_VERSION_MINOR=`$PKG_CONFIG --modversion xi 2>/dev/null | cut -d . -f 2` + QMAKE_LIBXI_VERSION_PATCH=`$PKG_CONFIG --modversion xi 2>/dev/null | cut -d . -f 3` + QMakeVar set QMAKE_LIBXI_VERSION_MAJOR "$QMAKE_LIBXI_VERSION_MAJOR" + QMakeVar set QMAKE_LIBXI_VERSION_MINOR "$QMAKE_LIBXI_VERSION_MINOR" + QMakeVar set QMAKE_LIBXI_VERSION_PATCH "$QMAKE_LIBXI_VERSION_PATCH" + fi CFG_XINPUT2=yes CFG_XINPUT=no else @@ -6763,8 +6783,15 @@ QT_PATCH_VERSION = $QT_PATCH_VERSION QT_LIBINFIX = $QT_LIBINFIX QT_NAMESPACE = $QT_NAMESPACE +QT_EDITION = $Edition EOF +if [ "$Edition" != "OpenSource" ] && [ "$Edition" != "Preview" ]; then + echo "QT_LICHECK = $Licheck" >> "$QTCONFIG.tmp" + echo "QT_RELEASE_DATE = $ReleaseDate" >> "$QTCONFIG.tmp" +fi +echo >> "$QTCONFIG.tmp" + if [ "$CFG_SHARED" = "no" ]; then echo "QT_DEFAULT_QPA_PLUGIN = q$QT_QPA_DEFAULT_PLATFORM" >> "$QTCONFIG.tmp" echo >> "$QTCONFIG.tmp" diff --git a/examples/opengl/legacy/hellogl/glwidget.cpp b/examples/opengl/legacy/hellogl/glwidget.cpp index 02501cd99e..122f7ddfe1 100644 --- a/examples/opengl/legacy/hellogl/glwidget.cpp +++ b/examples/opengl/legacy/hellogl/glwidget.cpp @@ -128,6 +128,8 @@ void GLWidget::setZRotation(int angle) //! [6] void GLWidget::initializeGL() { + initializeOpenGLFunctions(); + qglClearColor(qtPurple.dark()); logo = new QtLogo(this, 64); @@ -153,7 +155,7 @@ void GLWidget::paintGL() glRotatef(xRot / 16.0, 1.0, 0.0, 0.0); glRotatef(yRot / 16.0, 0.0, 1.0, 0.0); glRotatef(zRot / 16.0, 0.0, 0.0, 1.0); - logo->draw(); + logo->draw(static_cast<QOpenGLFunctions_1_1 *>(this)); } //! [7] diff --git a/examples/opengl/legacy/hellogl/glwidget.h b/examples/opengl/legacy/hellogl/glwidget.h index 994e38e13d..9aca4451df 100644 --- a/examples/opengl/legacy/hellogl/glwidget.h +++ b/examples/opengl/legacy/hellogl/glwidget.h @@ -42,11 +42,12 @@ #define GLWIDGET_H #include <QGLWidget> +#include <QOpenGLFunctions_1_1> class QtLogo; //! [0] -class GLWidget : public QGLWidget +class GLWidget : public QGLWidget, public QOpenGLFunctions_1_1 { Q_OBJECT diff --git a/examples/opengl/legacy/hellogl/hellogl.pro b/examples/opengl/legacy/hellogl/hellogl.pro index bb75b07200..c211242fd2 100644 --- a/examples/opengl/legacy/hellogl/hellogl.pro +++ b/examples/opengl/legacy/hellogl/hellogl.pro @@ -14,4 +14,4 @@ QT += opengl widgets target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/hellogl INSTALLS += target -contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") +contains(QT_CONFIG, opengles.|angle):error("This example requires Qt to be configured with -opengl desktop") diff --git a/examples/opengl/legacy/overpainting/glwidget.cpp b/examples/opengl/legacy/overpainting/glwidget.cpp index b41bc31126..52b6c35801 100644 --- a/examples/opengl/legacy/overpainting/glwidget.cpp +++ b/examples/opengl/legacy/overpainting/glwidget.cpp @@ -115,6 +115,8 @@ void GLWidget::setZRotation(int angle) //! [2] void GLWidget::initializeGL() { + initializeOpenGLFunctions(); + glEnable(GL_MULTISAMPLE); logo = new QtLogo(this); @@ -173,7 +175,7 @@ void GLWidget::paintEvent(QPaintEvent *event) glRotatef(yRot / 16.0, 0.0, 1.0, 0.0); glRotatef(zRot / 16.0, 0.0, 0.0, 1.0); - logo->draw(); + logo->draw(static_cast<QOpenGLFunctions_1_1 *>(this)); //! [7] //! [8] diff --git a/examples/opengl/legacy/overpainting/glwidget.h b/examples/opengl/legacy/overpainting/glwidget.h index dd5c0ba9ff..7e62a00170 100644 --- a/examples/opengl/legacy/overpainting/glwidget.h +++ b/examples/opengl/legacy/overpainting/glwidget.h @@ -42,13 +42,14 @@ #define GLWIDGET_H #include <QGLWidget> +#include <QOpenGLFunctions_1_1> #include <QTimer> class Bubble; class QtLogo; //! [0] -class GLWidget : public QGLWidget +class GLWidget : public QGLWidget, public QOpenGLFunctions_1_1 { Q_OBJECT diff --git a/examples/opengl/legacy/overpainting/overpainting.pro b/examples/opengl/legacy/overpainting/overpainting.pro index cbed7eed2b..cc46f18889 100644 --- a/examples/opengl/legacy/overpainting/overpainting.pro +++ b/examples/opengl/legacy/overpainting/overpainting.pro @@ -16,4 +16,4 @@ SOURCES = bubble.cpp \ target.path = $$[QT_INSTALL_EXAMPLES]/opengl/legacy/overpainting INSTALLS += target -contains(QT_CONFIG, opengles.|angle|dynamicgl):error("This example requires Qt to be configured with -opengl desktop") +contains(QT_CONFIG, opengles.|angle):error("This example requires Qt to be configured with -opengl desktop") diff --git a/examples/opengl/legacy/shared/qtlogo.cpp b/examples/opengl/legacy/shared/qtlogo.cpp index efe3fb0201..0d960dd4b6 100644 --- a/examples/opengl/legacy/shared/qtlogo.cpp +++ b/examples/opengl/legacy/shared/qtlogo.cpp @@ -43,6 +43,7 @@ #include <QGLWidget> #include <QMatrix4x4> #include <QVector3D> +#include <QOpenGLFunctions_1_1> #include <qmath.h> @@ -60,7 +61,7 @@ struct Geometry void appendSmooth(const QVector3D &a, const QVector3D &n, int from); void appendFaceted(const QVector3D &a, const QVector3D &n); void finalize(); - void loadArrays() const; + void loadArrays(QOpenGLFunctions_1_1 *functions) const; }; //! [0] @@ -73,7 +74,7 @@ public: void setSmoothing(Smoothing s) { sm = s; } void translate(const QVector3D &t); void rotate(qreal deg, QVector3D axis); - void draw() const; + void draw(QOpenGLFunctions_1_1 *functions) const; void addTri(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &n); void addQuad(const QVector3D &a, const QVector3D &b, const QVector3D &c, const QVector3D &d); @@ -96,10 +97,10 @@ static inline void qSetColor(float colorVec[], QColor c) colorVec[3] = c.alphaF(); } -void Geometry::loadArrays() const +void Geometry::loadArrays(QOpenGLFunctions_1_1 *functions) const { - glVertexPointer(3, GL_FLOAT, 0, vertices.constData()); - glNormalPointer(GL_FLOAT, 0, normals.constData()); + functions->glVertexPointer(3, GL_FLOAT, 0, vertices.constData()); + functions->glNormalPointer(GL_FLOAT, 0, normals.constData()); } void Geometry::finalize() @@ -170,15 +171,15 @@ void Patch::translate(const QVector3D &t) } //! [2] -void Patch::draw() const +void Patch::draw(QOpenGLFunctions_1_1 *functions) const { - glPushMatrix(); - glMultMatrixf(mat.constData()); - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor); + functions->glPushMatrix(); + functions->glMultMatrixf(mat.constData()); + functions->glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, faceColor); const GLushort *indices = geom->faces.constData(); - glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices + start); - glPopMatrix(); + functions->glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices + start); + functions->glPopMatrix(); } //! [2] @@ -371,17 +372,17 @@ void QtLogo::buildGeometry(int divisions, qreal scale) //! [3] //! [4] -void QtLogo::draw() const +void QtLogo::draw(QOpenGLFunctions_1_1 *functions) const { - geom->loadArrays(); + geom->loadArrays(functions); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); + functions->glEnableClientState(GL_VERTEX_ARRAY); + functions->glEnableClientState(GL_NORMAL_ARRAY); for (int i = 0; i < parts.count(); ++i) - parts[i]->draw(); + parts[i]->draw(functions); - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); + functions->glDisableClientState(GL_VERTEX_ARRAY); + functions->glDisableClientState(GL_NORMAL_ARRAY); } //! [4] diff --git a/examples/opengl/legacy/shared/qtlogo.h b/examples/opengl/legacy/shared/qtlogo.h index 562435daed..9bd15a1431 100644 --- a/examples/opengl/legacy/shared/qtlogo.h +++ b/examples/opengl/legacy/shared/qtlogo.h @@ -44,6 +44,7 @@ #include <QObject> #include <QColor> +class QOpenGLFunctions_1_1; class Patch; struct Geometry; @@ -54,7 +55,7 @@ public: explicit QtLogo(QObject *parent, int d = 64, qreal s = 1.0); ~QtLogo(); void setColor(QColor c); - void draw() const; + void draw(QOpenGLFunctions_1_1 *functions) const; private: void buildGeometry(int d, qreal s); diff --git a/examples/opengl/qopenglwidget/glwidget.cpp b/examples/opengl/qopenglwidget/glwidget.cpp index f93e667615..df52e3efbf 100644 --- a/examples/opengl/qopenglwidget/glwidget.cpp +++ b/examples/opengl/qopenglwidget/glwidget.cpp @@ -537,14 +537,14 @@ void GLWidget::setTransparent(bool transparent) window()->update(); } -void GLWidget::resizeGL(int w, int h) +void GLWidget::resizeGL(int, int) { if (m_hasButton) { if (!m_btn) { - m_btn = new QPushButton("A widget on top.\nPress me!", this); + m_btn = new QPushButton("A widget on top.\nPress for more widgets.", this); connect(m_btn, &QPushButton::clicked, this, &GLWidget::handleButtonPress); } - m_btn->move(w / 2, h / 2); + m_btn->move(20, 80); } } diff --git a/examples/opengl/qopenglwidget/mainwindow.cpp b/examples/opengl/qopenglwidget/mainwindow.cpp index 6cf1d5d6e2..22111afdcb 100644 --- a/examples/opengl/qopenglwidget/mainwindow.cpp +++ b/examples/opengl/qopenglwidget/mainwindow.cpp @@ -47,6 +47,7 @@ #include <QLabel> #include <QCheckBox> #include <QSpinBox> +#include <QScrollArea> #include "glwidget.h" @@ -69,7 +70,7 @@ MainWindow::MainWindow() "and therefore an interval < 16 ms will likely lead to a 60 FPS update rate."); QGroupBox *updateGroupBox = new QGroupBox(this); QCheckBox *timerBased = new QCheckBox("Use timer", this); - timerBased->setChecked(true); + timerBased->setChecked(false); timerBased->setToolTip("Toggles using a timer to trigger update().\n" "When not set, each paintGL() schedules the next update immediately,\n" "expecting the blocking swap to throttle the thread.\n" @@ -87,7 +88,7 @@ MainWindow::MainWindow() slider->setRange(0, 50); slider->setSliderPosition(30); m_timer->setInterval(10); - label->setText("A QOpenGLWidget"); + label->setText("A scrollable QOpenGLWidget"); label->setAlignment(Qt::AlignHCenter); QGroupBox * groupBox = new QGroupBox(this); @@ -96,7 +97,10 @@ MainWindow::MainWindow() m_layout = new QGridLayout(groupBox); - m_layout->addWidget(glwidget,1,0,8,1); + QScrollArea *scrollArea = new QScrollArea; + scrollArea->setWidget(glwidget); + + m_layout->addWidget(scrollArea,1,0,8,1); m_layout->addWidget(label,9,0,1,1); m_layout->addWidget(updateGroupBox, 10, 0, 1, 1); m_layout->addWidget(slider, 11,0,1,1); @@ -134,7 +138,10 @@ MainWindow::MainWindow() connect(timerBased, &QCheckBox::toggled, this, &MainWindow::timerUsageChanged); connect(timerBased, &QCheckBox::toggled, updateInterval, &QWidget::setEnabled); - m_timer->start(); + if (timerBased->isChecked()) + m_timer->start(); + else + updateInterval->setEnabled(false); } void MainWindow::updateIntervalChanged(int value) @@ -170,3 +177,8 @@ void MainWindow::timerUsageChanged(bool enabled) w->update(); } } + +void MainWindow::resizeEvent(QResizeEvent *) +{ + m_glWidgets[0]->setMinimumSize(size() + QSize(128, 128)); +} diff --git a/examples/opengl/qopenglwidget/mainwindow.h b/examples/opengl/qopenglwidget/mainwindow.h index f1b2c51e53..9ad8a01339 100644 --- a/examples/opengl/qopenglwidget/mainwindow.h +++ b/examples/opengl/qopenglwidget/mainwindow.h @@ -56,6 +56,8 @@ public: void addNew(); bool timerEnabled() const { return m_timer->isActive(); } + void resizeEvent(QResizeEvent *); + private slots: void updateIntervalChanged(int value); void timerUsageChanged(bool enabled); diff --git a/examples/touch/fingerpaint/scribblearea.cpp b/examples/touch/fingerpaint/scribblearea.cpp index 469c6b1a70..05598c134c 100644 --- a/examples/touch/fingerpaint/scribblearea.cpp +++ b/examples/touch/fingerpaint/scribblearea.cpp @@ -187,13 +187,14 @@ bool ScribbleArea::event(QEvent *event) foreach (const QTouchEvent::TouchPoint &touchPoint, touchPoints) { switch (touchPoint.state()) { case Qt::TouchPointStationary: - // don't do anything if this touch point hasn't moved + case Qt::TouchPointReleased: + // don't do anything if this touch point hasn't moved or has been released continue; default: { QRectF rect = touchPoint.rect(); if (rect.isEmpty()) { - qreal diameter = MinimumDiameter; + qreal diameter = MaximumDiameter; if (touch->device()->capabilities() & QTouchDevice::Pressure) diameter = MinimumDiameter + (MaximumDiameter - MinimumDiameter) * touchPoint.pressure(); rect.setSize(QSizeF(diameter, diameter)); diff --git a/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in new file mode 100644 index 0000000000..c6419660c1 --- /dev/null +++ b/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in @@ -0,0 +1,49 @@ +<?xml version=\"1.0\" encoding=\"utf-8\"?> + +<Package + xmlns=\"http://schemas.microsoft.com/appx/manifest/foundation/windows10\" + xmlns:mp=\"http://schemas.microsoft.com/appx/2014/phone/manifest\" + xmlns:uap=\"http://schemas.microsoft.com/appx/manifest/uap/windows10\" + IgnorableNamespaces=\"uap mp\"> + + <Identity + Name=\"$${WINRT_MANIFEST.identity}\" + Publisher=\"$${WINRT_MANIFEST.publisherid}\" + Version=\"$${WINRT_MANIFEST.version}\" /> + + <mp:PhoneIdentity PhoneProductId=\"$${WINRT_MANIFEST.identity}\" PhonePublisherId=\"$${WINRT_MANIFEST.phone_publisher_id}\"/> + + <Properties> + <DisplayName>$${WINRT_MANIFEST.name}</DisplayName> + <PublisherDisplayName>$${WINRT_MANIFEST.publisher}</PublisherDisplayName> + <Logo>$${WINRT_MANIFEST.logo_store}</Logo> + </Properties> + + <Dependencies> + <TargetDeviceFamily Name=\"Windows.Universal\" MinVersion=\"10.0.10069.0\" MaxVersionTested=\"10.0.10069.0\" /> + </Dependencies> + + <Resources> + <Resource Language=\"en\"/> + </Resources> + + <Applications> + <Application Id=\"App\" + Executable=\"$${WINRT_MANIFEST.target}.exe\" + EntryPoint=\"$${WINRT_MANIFEST.target}.App\"> + <uap:VisualElements + DisplayName=\"$${WINRT_MANIFEST.name}\" + Description=\"$${WINRT_MANIFEST.description}\" + BackgroundColor=\"$${WINRT_MANIFEST.background}\" + Square150x150Logo=\"$${WINRT_MANIFEST.logo_150x150}\" + Square44x44Logo=\"$${WINRT_MANIFEST.logo_44x44}\"> + + <uap:SplashScreen Image=\"$${WINRT_MANIFEST.logo_620x300}\" /> + </uap:VisualElements> + </Application> + </Applications> + + <Capabilities> + <Capability Name=\"internetClient\" /> + </Capabilities> +</Package> diff --git a/mkspecs/features/default_pre.prf b/mkspecs/features/default_pre.prf index b06b9d6cfc..eb3281ea1d 100644 --- a/mkspecs/features/default_pre.prf +++ b/mkspecs/features/default_pre.prf @@ -7,3 +7,18 @@ CONFIG = \ lex yacc debug exceptions depend_includepath \ testcase_targets import_plugins import_qpa_plugin \ $$CONFIG + +!build_pass:defined(QT_EDITION, var):!equals(QT_EDITION, "OpenSource"):!equals(QT_EDITION, "Preview") { + # + # call license checker (but cache result for one day) + # + today = $$section(_DATE_, " ", 0, 2) + !isEqual(QMAKE_LICHECK_TIMESTAMP, $$today) { + !system("$$system_quote($$system_path($$[QT_HOST_BINS/src]/$$QT_LICHECK)) check" \ + "$$QT_RELEASE_DATE $$[QMAKE_SPEC] $$[QMAKE_XSPEC]"): \ + error("License check failed! Giving up ...") + + cache(QMAKE_LICHECK_TIMESTAMP, set stash, today) + } + unset(today) +} diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index 78be2e8473..a1c499610b 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -185,7 +185,7 @@ defineTest(qtAddRpathLink) { # paths OTOH need to be put there. pubqt = $$replace(1, -private$, _private) pubdep = $$resolve_depends(pubqt, "QT.") - privdep = $$resolve_depends(pubqt, "QT.", ".depends" ".private_depends" ".run_depends") + privdep = $$resolve_depends(pubqt, "QT.", ".depends" ".run_depends") privdep -= $$pubdep rpaths = for(dep, privdep): \ @@ -259,7 +259,7 @@ defineTest(qtAddToolEnv) { # target variable, dependency var name, [non-empty: prepare for system(), not make] defineTest(qtAddTargetEnv) { deps = $$replace($$2, -private$, _private) - deps = $$resolve_depends(deps, "QT.", ".depends" ".private_depends" ".run_depends") + deps = $$resolve_depends(deps, "QT.", ".depends" ".run_depends") !isEmpty(deps) { ptypes = for(dep, deps) { diff --git a/mkspecs/features/testlib_defines.prf b/mkspecs/features/testlib_defines.prf index 9176beb9dd..901e03a91d 100644 --- a/mkspecs/features/testlib_defines.prf +++ b/mkspecs/features/testlib_defines.prf @@ -1 +1,2 @@ -DEFINES += QT_TESTCASE_BUILDDIR=$$shell_quote(\"$$OUT_PWD\") +contains(TEMPLATE, vc.*): DEFINES += QT_TESTCASE_BUILDDIR=\"$$OUT_PWD\" +else: DEFINES += QT_TESTCASE_BUILDDIR=$$shell_quote(\"$$OUT_PWD\") diff --git a/mkspecs/winrt-arm-msvc2015/qmake.conf b/mkspecs/winrt-arm-msvc2015/qmake.conf new file mode 100644 index 0000000000..fcb6d99aa9 --- /dev/null +++ b/mkspecs/winrt-arm-msvc2015/qmake.conf @@ -0,0 +1,32 @@ +# +# qmake configuration for winrt-arm-msvc2015 +# +# Written for Microsoft Visual C++ 2015 +# + +include(../common/winrt_winphone/qmake.conf) +QMAKE_COMPILER_DEFINES += _MSC_VER=1900 +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP ARM __ARM__ __arm__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /MACHINE:ARM /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib + +# Note that the order is important, ucrt(d) has to be first +# Otherwise the linker might use malloc from a different library +# but free_dbg() from the runtime, causing assert when deleting +# items from different heaps +CONFIG(debug, debug|release) { + QMAKE_LIBS = ucrtd.lib $$QMAKE_LIBS +} else { + QMAKE_LIBS = ucrt.lib $$QMAKE_LIBS +} + +VCPROJ_ARCH = ARM +MSVC_VER = 14.0 +WINSDK_VER = 10.0 +WINTARGET_VER = winv10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = arm diff --git a/mkspecs/winrt-arm-msvc2015/qplatformdefs.h b/mkspecs/winrt-arm-msvc2015/qplatformdefs.h new file mode 100644 index 0000000000..c8f88524d9 --- /dev/null +++ b/mkspecs/winrt-arm-msvc2015/qplatformdefs.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec 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 "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-x64-msvc2015/qmake.conf b/mkspecs/winrt-x64-msvc2015/qmake.conf new file mode 100644 index 0000000000..e8062f5364 --- /dev/null +++ b/mkspecs/winrt-x64-msvc2015/qmake.conf @@ -0,0 +1,32 @@ +# +# qmake configuration for winrt-x64-msvc2015 +# +# Written for Microsoft Visual C++ 2015 +# + +include(../common/winrt_winphone/qmake.conf) +QMAKE_COMPILER_DEFINES += _MSC_VER=1900 _WIN32 +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP X64 __X64__ __x64__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /MACHINE:X64 /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib + +# Note that the order is important, ucrt(d) has to be first +# Otherwise the linker might use malloc from a different library +# but free_dbg() from the runtime, causing assert when deleting +# items from different heaps +CONFIG(debug, debug|release) { + QMAKE_LIBS = ucrtd.lib $$QMAKE_LIBS +} else { + QMAKE_LIBS = ucrt.lib $$QMAKE_LIBS +} + +VCPROJ_ARCH = x64 +MSVC_VER = 14.0 +WINSDK_VER = 10.0 +WINTARGET_VER = winv10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = x64 diff --git a/mkspecs/winrt-x64-msvc2015/qplatformdefs.h b/mkspecs/winrt-x64-msvc2015/qplatformdefs.h new file mode 100644 index 0000000000..c8f88524d9 --- /dev/null +++ b/mkspecs/winrt-x64-msvc2015/qplatformdefs.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec 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 "../common/winrt_winphone/qplatformdefs.h" diff --git a/mkspecs/winrt-x86-msvc2015/qmake.conf b/mkspecs/winrt-x86-msvc2015/qmake.conf new file mode 100644 index 0000000000..5b44a97e8d --- /dev/null +++ b/mkspecs/winrt-x86-msvc2015/qmake.conf @@ -0,0 +1,32 @@ +# +# qmake configuration for winrt-x86-msvc2015 +# +# Written for Microsoft Visual C++ 2015 +# + +include(../common/winrt_winphone/qmake.conf) +QMAKE_COMPILER_DEFINES += _MSC_VER=1900 _WIN32 +DEFINES += WINAPI_FAMILY=WINAPI_FAMILY_APP X86 __X86__ __x86__ + +QMAKE_CFLAGS += -FS +QMAKE_CXXFLAGS += -FS +QMAKE_LFLAGS += /SAFESEH /MACHINE:X86 /NODEFAULTLIB:kernel32.lib + +QMAKE_LIBS += windowscodecs.lib WindowsApp.lib runtimeobject.lib + +# Note that the order is important, ucrt(d) has to be first +# Otherwise the linker might use malloc from a different library +# but free_dbg() from the runtime, causing assert when deleting +# items from different heaps +CONFIG(debug, debug|release) { + QMAKE_LIBS = ucrtd.lib $$QMAKE_LIBS +} else { + QMAKE_LIBS = ucrt.lib $$QMAKE_LIBS +} + +VCPROJ_ARCH = Win32 +MSVC_VER = 14.0 +WINSDK_VER = 10.0 +WINTARGET_VER = winv10.0 +WINRT_MANIFEST = $$PWD/../common/winrt_winphone/manifests/10.0/AppxManifest.xml.in +WINRT_MANIFEST.architecture = x86 diff --git a/mkspecs/winrt-x86-msvc2015/qplatformdefs.h b/mkspecs/winrt-x86-msvc2015/qplatformdefs.h new file mode 100644 index 0000000000..c8f88524d9 --- /dev/null +++ b/mkspecs/winrt-x86-msvc2015/qplatformdefs.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec 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 "../common/winrt_winphone/qplatformdefs.h" diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index d9eb149177..adf6ca5fb0 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -810,7 +810,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES ProStringList &libdirs = project->values("QMAKE_PBX_LIBPATHS"), &frameworkdirs = project->values("QMAKE_FRAMEWORKPATH"); - static const char * const libs[] = { "QMAKE_LFLAGS", "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; + static const char * const libs[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; for (int i = 0; libs[i]; i++) { tmp = project->values(libs[i]); for(int x = 0; x < tmp.count();) { @@ -821,9 +821,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString r = opt.mid(2).toQString(); fixForOutput(r); libdirs.append(r); - } else if(opt == "-prebind") { - project->values("QMAKE_DO_PREBINDING").append("TRUE"); - remove = true; } else if(opt.startsWith("-l")) { name = opt.mid(2).toQString(); QString lib("lib" + name); diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 728be67acc..4a03fafd77 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2240,7 +2240,7 @@ QString MakefileGenerator::buildArgs() QString ret; foreach (const QString &arg, Option::globals->qmake_args) - ret += " " + escapeFilePath(arg); + ret += " " + shellQuote(arg); return ret; } diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index 6c2d2c6206..cbf7cf26dc 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -608,10 +608,13 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) xml.setIndentString(" "); + const QString toolsVersion = (tool.SdkVersion == QStringLiteral("10.0")) ? QStringLiteral("14.0") + : QStringLiteral("4.0"); + xml << decl("1.0", "utf-8") << tag("Project") << attrTag("DefaultTargets","Build") - << attrTag("ToolsVersion", "4.0") + << attrTag("ToolsVersion", toolsVersion) << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003") << tag("ItemGroup") << attrTag("Label", "ProjectConfigurations"); @@ -640,7 +643,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) << tagValue("DefaultLanguage", "en") << tagValue("AppContainerApplication", "true") << tagValue("ApplicationType", isWinPhone ? "Windows Phone" : "Windows Store") - << tagValue("ApplicationTypeRevision", tool.SdkVersion); + << tagValue("ApplicationTypeRevision", tool.SdkVersion == "10.0" ? "8.2" : tool.SdkVersion); } xml << closetag(); diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index eb8ae23384..dfa8f8837b 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -176,11 +176,34 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) const QString vcInstallDir = "/fake/vc_install_dir"; const QString kitDir = "/fake/sdk_install_dir"; #endif // Q_OS_WIN - QStringList incDirs; QStringList libDirs; QStringList binDirs; - if (isPhone) { + if (msvcVer == QStringLiteral("14.0")) { + binDirs << vcInstallDir + QStringLiteral("bin/") + compiler; + binDirs << vcInstallDir + QStringLiteral("bin/"); // Maybe remove for x86 again? + binDirs << kitDir + QStringLiteral("bin/") + (arch == QStringLiteral("arm") ? QStringLiteral("x86") : arch); + binDirs << vcInstallDir + QStringLiteral("../Common7/Tools/bin"); + binDirs << vcInstallDir + QStringLiteral("../Common7/Tools"); + binDirs << vcInstallDir + QStringLiteral("../Common7/ide"); + binDirs << kitDir + QStringLiteral("Windows Performance Toolkit/"); + + incDirs << vcInstallDir + QStringLiteral("include"); + incDirs << vcInstallDir + QStringLiteral("atlmfc/include"); + // ### Investigate why VS uses 10056 first + incDirs << kitDir + QStringLiteral("Include/10.0.10056.0/ucrt"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/ucrt"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/um"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/shared"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/winrt"); + + libDirs << vcInstallDir + QStringLiteral("lib/store/") + compilerArch; + libDirs << vcInstallDir + QStringLiteral("atlmfc/lib") + compilerArch; + // ### Investigate why VS uses 10056 first + libDirs << kitDir + QStringLiteral("lib/10.0.10056.0/ucrt/") + arch; + libDirs << kitDir + QStringLiteral("lib/10.0.10069.0/ucrt/") + arch; + libDirs << kitDir + QStringLiteral("lib/10.0.10069.0/um/") + arch; + } else if (isPhone) { QString sdkDir = vcInstallDir; if (!QDir(sdkDir).exists()) { fprintf(stderr, "Failed to find the Windows Phone SDK in %s.\n" @@ -208,7 +231,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) << kitDir + QStringLiteral("/include/shared") << kitDir + QStringLiteral("/include/winrt"); } - // Inherit PATH binDirs << QString::fromLocal8Bit(qgetenv("PATH")).split(QLatin1Char(';')); diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 59136b16c8..7092da3e59 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -56,7 +56,8 @@ enum DotNET { NET2008 = 0x90, NET2010 = 0xa0, NET2012 = 0xb0, - NET2013 = 0xc0 + NET2013 = 0xc0, + NET2015 = 0xd0 }; /* diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 1fa117afda..fd2fc2eb94 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -71,6 +71,7 @@ struct DotNetCombo { const char *regKey; } dotNetCombo[] = { #ifdef Q_OS_WIN64 + {NET2015, "MSVC.NET 2015 (14.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\14.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 (12.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\12.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 Express Edition (12.0)", "Software\\Wow6432Node\\Microsoft\\VCExpress\\12.0\\Setup\\VC\\ProductDir"}, {NET2012, "MSVC.NET 2012 (11.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\11.0\\Setup\\VC\\ProductDir"}, @@ -84,6 +85,7 @@ struct DotNetCombo { {NET2003, "MSVC.NET 2003 (7.1)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\7.1\\Setup\\VC\\ProductDir"}, {NET2002, "MSVC.NET 2002 (7.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\7.0\\Setup\\VC\\ProductDir"}, #else + {NET2015, "MSVC.NET 2015 (14.0)", "Software\\Microsoft\\VisualStudio\\14.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 (12.0)", "Software\\Microsoft\\VisualStudio\\12.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 Express Edition (12.0)", "Software\\Microsoft\\VCExpress\\12.0\\Setup\\VC\\ProductDir"}, {NET2012, "MSVC.NET 2012 (11.0)", "Software\\Microsoft\\VisualStudio\\11.0\\Setup\\VC\\ProductDir"}, @@ -175,6 +177,8 @@ const char _slnHeader110[] = "Microsoft Visual Studio Solution File, Format "\n# Visual Studio 2012"; const char _slnHeader120[] = "Microsoft Visual Studio Solution File, Format Version 12.00" "\n# Visual Studio 2013"; +const char _slnHeader140[] = "Microsoft Visual Studio Solution File, Format Version 12.00" + "\n# Visual Studio 2015"; // The following UUID _may_ change for later servicepacks... // If so we need to search through the registry at // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects @@ -401,6 +405,8 @@ QString VcprojGenerator::retrievePlatformToolSet() const return QStringLiteral("v110") + suffix; case NET2013: return QStringLiteral("v120") + suffix; + case NET2015: + return QStringLiteral("v140") + suffix; default: return QString(); } @@ -647,6 +653,8 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) } switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) { + case NET2015: + t << _slnHeader140; case NET2013: t << _slnHeader120; break; @@ -972,6 +980,9 @@ void VcprojGenerator::initProject() // Own elements ----------------------------- vcProject.Name = project->first("QMAKE_ORIG_TARGET").toQString(); switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) { + case NET2015: + vcProject.Version = "14.00"; + break; case NET2013: vcProject.Version = "12.00"; break; diff --git a/qtbase.pro b/qtbase.pro index bae2641404..51e8fb8760 100644 --- a/qtbase.pro +++ b/qtbase.pro @@ -46,6 +46,11 @@ equals(QMAKE_HOST.os, Windows) { } INSTALLS += qmake +#licheck +licheck.path = $$[QT_HOST_BINS] +licheck.files = $$PWD/bin/$$QT_LICHECK +exists($$licheck.files): INSTALLS += licheck + #syncqt syncqt.path = $$[QT_HOST_BINS] syncqt.files = $$PWD/bin/syncqt.pl diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h index 81b9ea748d..0f70fe4615 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h @@ -38,7 +38,7 @@ class InspectableNativeWindow; using namespace Microsoft::WRL; using namespace Microsoft::WRL::Wrappers; -#else +#elif defined(ANGLE_ENABLE_D3D11) typedef IDXGISwapChain DXGISwapChain; typedef IDXGIFactory DXGIFactory; #endif @@ -60,9 +60,11 @@ class NativeWindow #endif static bool isValidNativeWindow(EGLNativeWindowType window); +#if defined(ANGLE_ENABLE_D3D11) HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory, DXGI_FORMAT format, UINT width, UINT height, DXGISwapChain** swapChain); +#endif inline EGLNativeWindowType getNativeWindow() const { return mWindow; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp index 9d8f0bb96c..0a4f45b5b7 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp @@ -37,6 +37,7 @@ bool NativeWindow::isValidNativeWindow(EGLNativeWindowType window) return IsWindow(window) == TRUE; } +#if defined(ANGLE_ENABLE_D3D11) HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory, DXGI_FORMAT format, unsigned int width, unsigned int height, DXGISwapChain** swapChain) @@ -65,4 +66,5 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory return factory->CreateSwapChain(device, &swapChainDesc, swapChain); } +#endif } diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c index 017ae0741e..8d08f403ec 100644 --- a/src/3rdparty/forkfd/forkfd.c +++ b/src/3rdparty/forkfd/forkfd.c @@ -63,7 +63,7 @@ # include <Availability.h> # include <AvailabilityMacros.h> # if MAC_OS_X_VERSION_MIN_REQUIRED <= 1070 -# define HAVE_BROKEN_WAITID_ALL 1 +# define HAVE_BROKEN_WAITID 1 # endif #endif @@ -109,10 +109,10 @@ static struct sigaction old_sigaction; static pthread_once_t forkfd_initialization = PTHREAD_ONCE_INIT; static ffd_atomic_int forkfd_status = FFD_ATOMIC_INIT(0); -#ifdef HAVE_BROKEN_WAITID_ALL -static int waitid_p_all_works = 0; +#ifdef HAVE_BROKEN_WAITID +static int waitid_works = 0; #else -static const int waitid_p_all_works = 1; +static const int waitid_works = 1; #endif static ProcessInfo *tryAllocateInSection(Header *header, ProcessInfo entries[], int maxCount) @@ -183,10 +183,13 @@ static int tryReaping(pid_t pid, siginfo_t *info) { /* reap the child */ #ifdef HAVE_WAITID - // we have waitid(2), which fills in siginfo_t for us - info->si_pid = 0; - return waitid(P_PID, pid, info, WEXITED | WNOHANG) == 0 && info->si_pid == pid; -#else + if (waitid_works) { + // we have waitid(2), which fills in siginfo_t for us + info->si_pid = 0; + return waitid(P_PID, pid, info, WEXITED | WNOHANG) == 0 && info->si_pid == pid; + } +#endif + int status; if (waitpid(pid, &status, WNOHANG) <= 0) return 0; // child did not change state @@ -206,7 +209,6 @@ static int tryReaping(pid_t pid, siginfo_t *info) } return 1; -#endif } static void freeInfo(Header *header, ProcessInfo *entry) @@ -246,7 +248,7 @@ static void sigchld_handler(int signum) memset(&info, 0, sizeof info); #ifdef HAVE_WAITID - if (!waitid_p_all_works) + if (!waitid_works) goto search_arrays; /* be optimistic: try to see if we can get the child that exited */ @@ -310,12 +312,14 @@ search_arrays: if (pid <= 0) continue; #ifdef HAVE_WAITID - /* The child might have been reaped by the block above in another thread, - * so first check if it's ready and, if it is, lock it */ - if (!isChildReady(pid, &info) || - !ffd_atomic_compare_exchange(&children.entries[i].pid, &pid, -1, - FFD_ATOMIC_RELAXED, FFD_ATOMIC_RELAXED)) - continue; + if (waitid_works) { + /* The child might have been reaped by the block above in another thread, + * so first check if it's ready and, if it is, lock it */ + if (!isChildReady(pid, &info) || + !ffd_atomic_compare_exchange(&children.entries[i].pid, &pid, -1, + FFD_ATOMIC_RELAXED, FFD_ATOMIC_RELAXED)) + continue; + } #endif if (tryReaping(pid, &info)) { /* this is our child, send notification and free up this entry */ @@ -331,12 +335,14 @@ search_arrays: if (pid <= 0) continue; #ifdef HAVE_WAITID - /* The child might have been reaped by the block above in another thread, - * so first check if it's ready and, if it is, lock it */ - if (!isChildReady(pid, &info) || - !ffd_atomic_compare_exchange(&array->entries[i].pid, &pid, -1, - FFD_ATOMIC_RELAXED, FFD_ATOMIC_RELAXED)) - continue; + if (waitid_works) { + /* The child might have been reaped by the block above in another thread, + * so first check if it's ready and, if it is, lock it */ + if (!isChildReady(pid, &info) || + !ffd_atomic_compare_exchange(&array->entries[i].pid, &pid, -1, + FFD_ATOMIC_RELAXED, FFD_ATOMIC_RELAXED)) + continue; + } #endif if (tryReaping(pid, &info)) { /* this is our child, send notification and free up this entry */ @@ -357,17 +363,19 @@ chain_handler: static void forkfd_initialize() { -#if defined(HAVE_BROKEN_WAITID_ALL) +#if defined(HAVE_BROKEN_WAITID) pid_t pid = fork(); if (pid == 0) { _exit(0); } else if (pid > 0) { siginfo_t info; waitid(P_ALL, 0, &info, WNOWAIT | WEXITED); - waitid_p_all_works = (info.si_pid != 0); + waitid_works = (info.si_pid != 0); + info.si_pid = 0; // now really reap the child waitid(P_PID, pid, &info, WEXITED); + waitid_works = waitid_works && (info.si_pid != 0); } #endif diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index 73140839cc..d6cd49f44c 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -65,7 +65,6 @@ import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; -import android.widget.LinearLayout; import java.io.BufferedReader; import java.io.DataOutputStream; @@ -789,29 +788,7 @@ public class QtActivityDelegate 0, 0, metrics.xdpi, metrics.ydpi, metrics.scaledDensity); } - - ViewGroup layout = null; m_layout = new QtLayout(m_activity); - if (Build.VERSION.SDK_INT >= 14) { - try { - ActivityInfo activityInfo = m_activity.getPackageManager().getActivityInfo(m_activity.getComponentName(), - PackageManager.GET_META_DATA); - if (activityInfo.metaData == null - || !activityInfo.metaData.containsKey("android.app.allow_overlapping_system_ui") - || !activityInfo.metaData.getBoolean("android.app.allow_overlapping_system_ui")) { - layout = new LinearLayout(m_activity); - layout.setFitsSystemWindows(true); - layout.addView(m_layout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - if (layout == null) - layout = m_layout; - m_editText = new QtEditText(m_activity, this); m_imm = (InputMethodManager)m_activity.getSystemService(Context.INPUT_METHOD_SERVICE); m_surfaces = new HashMap<Integer, QtSurface>(); @@ -834,7 +811,7 @@ public class QtActivityDelegate Log.w("Qt A11y", "Unknown exception: " + e.toString()); } - m_activity.setContentView(layout, + m_activity.setContentView(m_layout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml index 779612cdaf..60c612976f 100644 --- a/src/android/templates/AndroidManifest.xml +++ b/src/android/templates/AndroidManifest.xml @@ -44,10 +44,6 @@ signal is sent! --> <meta-data android:name="android.app.background_running" android:value="false"/> <!-- Background running --> - - <!-- Show translucent UI on top of Qt's surface when system theme mandates it --> - <meta-data android:name="android.app.allow_overlapping_system_ui" android:value="false"/> - <!-- Show translucent UI on top of Qt's surface when system theme mandates it --> </activity> </application> <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14"/> diff --git a/src/angle/patches/0007-ANGLE-Fix-compilation-without-d3d11.patch b/src/angle/patches/0007-ANGLE-Fix-compilation-without-d3d11.patch new file mode 100644 index 0000000000..eca7d0e162 --- /dev/null +++ b/src/angle/patches/0007-ANGLE-Fix-compilation-without-d3d11.patch @@ -0,0 +1,57 @@ +From 1f993a2492a618becd4bf89ef0d6cb5d2c9aa67a Mon Sep 17 00:00:00 2001 +From: Kai Koehne <kai.koehne@theqtcompany.com> +Date: Mon, 11 May 2015 15:17:12 +0200 +Subject: [PATCH] ANGLE: Fix compilation without d3d11 + +Change-Id: I0b772698cf521083e5ecf35a395af57100a50131 +--- + src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h | 4 +++- + .../angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp | 2 ++ + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h +index 81b9ea7..0f70fe4 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/NativeWindow.h +@@ -38,7 +38,7 @@ class InspectableNativeWindow; + using namespace Microsoft::WRL; + using namespace Microsoft::WRL::Wrappers; + +-#else ++#elif defined(ANGLE_ENABLE_D3D11) + typedef IDXGISwapChain DXGISwapChain; + typedef IDXGIFactory DXGIFactory; + #endif +@@ -60,9 +60,11 @@ class NativeWindow + #endif + static bool isValidNativeWindow(EGLNativeWindowType window); + ++#if defined(ANGLE_ENABLE_D3D11) + HRESULT createSwapChain(ID3D11Device* device, DXGIFactory* factory, + DXGI_FORMAT format, UINT width, UINT height, + DXGISwapChain** swapChain); ++#endif + + inline EGLNativeWindowType getNativeWindow() const { return mWindow; } + +diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp +index 9d8f0bb..0a4f45b 100644 +--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp ++++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/win32/NativeWindow.cpp +@@ -37,6 +37,7 @@ bool NativeWindow::isValidNativeWindow(EGLNativeWindowType window) + return IsWindow(window) == TRUE; + } + ++#if defined(ANGLE_ENABLE_D3D11) + HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory, + DXGI_FORMAT format, unsigned int width, unsigned int height, + DXGISwapChain** swapChain) +@@ -65,4 +66,5 @@ HRESULT NativeWindow::createSwapChain(ID3D11Device* device, DXGIFactory* factory + + return factory->CreateSwapChain(device, &swapChainDesc, swapChain); + } ++#endif + } +-- +1.9.5.msysgit.0 + diff --git a/src/angle/src/libGLESv2/libGLESv2.pro b/src/angle/src/libGLESv2/libGLESv2.pro index 1bf9af0436..5979b68098 100644 --- a/src/angle/src/libGLESv2/libGLESv2.pro +++ b/src/angle/src/libGLESv2/libGLESv2.pro @@ -329,6 +329,8 @@ angle_d3d11 { !static { DEF_FILE = $$ANGLE_DIR/src/libGLESv2/$${TARGET}.def mingw:equals(QT_ARCH, i386): DEF_FILE = $$ANGLE_DIR/src/libGLESv2/$${TARGET}_mingw32.def +} else { + DEFINES += DllMain=DllMain_ANGLE # prevent symbol from conflicting with the user's DllMain } float_converter.target = float_converter diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 447a875655..88882bbe8f 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1737,7 +1737,7 @@ void qErrnoWarning(int code, const char *msg, ...) Example: \code - QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz t} %{if-debug}D{%endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}" + QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz t} %{if-debug}D%{endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}" \endcode The default \a pattern is "%{if-category}%{category}: %{endif}%{message}". diff --git a/src/corelib/global/qtypetraits.h b/src/corelib/global/qtypetraits.h index 3a305713e6..488e257e0f 100644 --- a/src/corelib/global/qtypetraits.h +++ b/src/corelib/global/qtypetraits.h @@ -506,6 +506,27 @@ Q_STATIC_ASSERT((!is_unsigned<qint64>::value)); Q_STATIC_ASSERT((!is_signed<quint64>::value)); Q_STATIC_ASSERT(( is_signed<qint64>::value)); +template<class T = void> struct is_default_constructible; + +template<> struct is_default_constructible<void> +{ +protected: + template<bool> struct test { typedef char type; }; +public: + static bool const value = false; +}; +template<> struct is_default_constructible<>::test<true> { typedef double type; }; + +template<class T> struct is_default_constructible : is_default_constructible<> +{ +private: + template<class U> static typename test<!!sizeof(::new U())>::type sfinae(U*); + template<class U> static char sfinae(...); +public: + static bool const value = sizeof(sfinae<T>(0)) > 1; +}; + + } // namespace QtPrivate QT_END_NAMESPACE diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index e73a200fb4..b908ae3145 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -38,9 +38,9 @@ #include "qiodevice_p.h" #include "qfile.h" #include "qstringlist.h" +#include "qdir.h" #include <algorithm> -#include <limits.h> #ifdef QIODEVICE_DEBUG # include <ctype.h> @@ -80,10 +80,29 @@ void debugBinaryString(const char *data, qint64 maxlen) #define Q_VOID +static void checkWarnMessage(const QIODevice *device, const char *function, const char *what) +{ + QDebug d = qWarning(); + d.noquote(); + d.nospace(); + d << "QIODevice::" << function; +#ifndef QT_NO_QOBJECT + d << " (" << device->metaObject()->className(); + if (!device->objectName().isEmpty()) + d << ", \"" << device->objectName() << '"'; + if (const QFile *f = qobject_cast<const QFile *>(device)) + d << ", \"" << QDir::toNativeSeparators(f->fileName()) << '"'; + d << ')'; +#else + Q_UNUSED(device) +#endif // !QT_NO_QOBJECT + d << ": " << what; +} + #define CHECK_MAXLEN(function, returnType) \ do { \ if (maxSize < 0) { \ - qWarning("QIODevice::"#function": Called with maxSize < 0"); \ + checkWarnMessage(this, #function, "Called with maxSize < 0"); \ return returnType; \ } \ } while (0) @@ -92,10 +111,10 @@ void debugBinaryString(const char *data, qint64 maxlen) do { \ if ((d->openMode & WriteOnly) == 0) { \ if (d->openMode == NotOpen) { \ - qWarning("QIODevice::"#function": device not open"); \ + checkWarnMessage(this, #function, "device not open"); \ return returnType; \ } \ - qWarning("QIODevice::"#function": ReadOnly device"); \ + checkWarnMessage(this, #function, "ReadOnly device"); \ return returnType; \ } \ } while (0) @@ -104,10 +123,10 @@ void debugBinaryString(const char *data, qint64 maxlen) do { \ if ((d->openMode & ReadOnly) == 0) { \ if (d->openMode == NotOpen) { \ - qWarning("QIODevice::"#function": device not open"); \ + checkWarnMessage(this, #function, "device not open"); \ return returnType; \ } \ - qWarning("QIODevice::"#function": WriteOnly device"); \ + checkWarnMessage(this, #function, "WriteOnly device"); \ return returnType; \ } \ } while (0) @@ -462,7 +481,7 @@ void QIODevice::setTextModeEnabled(bool enabled) { Q_D(QIODevice); if (!isOpen()) { - qWarning("QIODevice::setTextModeEnabled: The device is not open"); + checkWarnMessage(this, "setTextModeEnabled", "The device is not open"); return; } if (enabled) @@ -621,11 +640,11 @@ bool QIODevice::seek(qint64 pos) { Q_D(QIODevice); if (d->isSequential()) { - qWarning("QIODevice::seek: Cannot call seek on a sequential device"); + checkWarnMessage(this, "seek", "Cannot call seek on a sequential device"); return false; } if (d->openMode == NotOpen) { - qWarning("QIODevice::seek: The device is not open"); + checkWarnMessage(this, "seek", "The device is not open"); return false; } if (pos < 0) { @@ -922,9 +941,9 @@ QByteArray QIODevice::read(qint64 maxSize) Q_UNUSED(d); #endif - if (maxSize != qint64(int(maxSize))) { - qWarning("QIODevice::read: maxSize argument exceeds QByteArray size limit"); - maxSize = INT_MAX; + if (quint64(maxSize) >= QByteArray::MaxSize) { + checkWarnMessage(this, "read", "maxSize argument exceeds QByteArray size limit"); + maxSize = QByteArray::MaxSize - 1; } qint64 readBytes = 0; @@ -976,7 +995,7 @@ QByteArray QIODevice::readAll() // flush internal read buffer if (!(d->openMode & Text) && !d->buffer.isEmpty()) { - if (d->buffer.size() >= INT_MAX) + if (quint64(d->buffer.size()) >= QByteArray::MaxSize) return QByteArray(); result = d->buffer.readAll(); readBytes = result.size(); @@ -1055,7 +1074,7 @@ qint64 QIODevice::readLine(char *data, qint64 maxSize) { Q_D(QIODevice); if (maxSize < 2) { - qWarning("QIODevice::readLine: Called with maxSize < 2"); + checkWarnMessage(this, "readLine", "Called with maxSize < 2"); return qint64(-1); } @@ -1159,9 +1178,9 @@ QByteArray QIODevice::readLine(qint64 maxSize) Q_UNUSED(d); #endif - if (maxSize > INT_MAX) { + if (quint64(maxSize) >= QByteArray::MaxSize) { qWarning("QIODevice::read: maxSize argument exceeds QByteArray size limit"); - maxSize = INT_MAX; + maxSize = QByteArray::MaxSize - 1; } result.resize(int(maxSize)); @@ -1169,7 +1188,7 @@ QByteArray QIODevice::readLine(qint64 maxSize) if (!result.size()) { // If resize fails or maxSize == 0, read incrementally if (maxSize == 0) - maxSize = INT_MAX; + maxSize = QByteArray::MaxSize - 1; // The first iteration needs to leave an extra byte for the terminating null result.resize(1); diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp index 4f5aeff395..2bd996d213 100644 --- a/src/corelib/io/qlockfile.cpp +++ b/src/corelib/io/qlockfile.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 David Faure <faure+bluesystems@kde.org> +** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -66,9 +67,12 @@ QT_BEGIN_NAMESPACE If the process holding the lock crashes, the lock file stays on disk and can prevent any other process from accessing the shared resource, ever. For this reason, QLockFile - tries to detect such a "stale" lock file, based on the process ID written into the file, - and (in case that process ID got reused meanwhile), on the last modification time of - the lock file (30s by default, for the use case of a short-lived operation). + tries to detect such a "stale" lock file, based on the process ID written into the file. + To cover the situation that the process ID got reused meanwhile, the current process name is + compared to the name of the process that corresponds to the process ID from the lock file. + If the process names differ, the lock file is considered stale. + Additionally, the last modification time of the lock file (30s by default, for the use case of a + short-lived operation) is taken into account. If the lock file is found to be stale, it will be deleted. For the use case of protecting a resource over a long time, you should therefore call @@ -122,7 +126,7 @@ QLockFile::~QLockFile() The value of \a staleLockTime is used by lock() and tryLock() in order to determine when an existing lock file is considered stale, i.e. left over by a crashed process. This is useful for the case where the PID got reused - meanwhile, so the only way to detect a stale lock file is by the fact that + meanwhile, so one way to detect a stale lock file is by the fact that it has been around for a long time. \sa staleLockTime() diff --git a/src/corelib/io/qlockfile_p.h b/src/corelib/io/qlockfile_p.h index 0cfaa42849..168062f467 100644 --- a/src/corelib/io/qlockfile_p.h +++ b/src/corelib/io/qlockfile_p.h @@ -75,6 +75,7 @@ public: // Returns \c true if the lock belongs to dead PID, or is old. // The attempt to delete it will tell us if it was really stale or not, though. bool isApparentlyStale() const; + static QString processNameByPid(qint64 pid); #ifdef Q_OS_UNIX static int checkFcntlWorksAfterFlock(); diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index d1804f2cb6..d6ea2f1f2d 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 David Faure <faure+bluesystems@kde.org> +** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -48,6 +49,15 @@ #include <signal.h> // kill #include <unistd.h> // gethostname +#if defined(Q_OS_OSX) +# include <libproc.h> +#elif defined(Q_OS_LINUX) +# include <unistd.h> +# include <cstdio> +#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) +# include <sys/user.h> +#endif + QT_BEGIN_NAMESPACE static QByteArray localHostName() // from QHostInfo::localHostName(), modified to return a QByteArray @@ -189,12 +199,50 @@ bool QLockFilePrivate::isApparentlyStale() const if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) { if (::kill(pid, 0) == -1 && errno == ESRCH) return true; // PID doesn't exist anymore + const QString processName = processNameByPid(pid); + if (!processName.isEmpty()) { + QFileInfo fi(appname); + if (fi.isSymLink()) + fi.setFile(fi.symLinkTarget()); + if (processName != fi.fileName()) + return true; // PID got reused by a different application. + } } } const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); return staleLockTime > 0 && age > staleLockTime; } +QString QLockFilePrivate::processNameByPid(qint64 pid) +{ +#if defined(Q_OS_OSX) + char name[1024]; + proc_name(pid, name, sizeof(name) / sizeof(char)); + return QString::fromUtf8(name); +#elif defined(Q_OS_LINUX) + if (!QFile::exists(QStringLiteral("/proc/version"))) + return QString(); + char exePath[64]; + char buf[PATH_MAX]; + memset(buf, 0, sizeof(buf)); + sprintf(exePath, "/proc/%lld/exe", pid); + if (readlink(exePath, buf, sizeof(buf)) < 0) { + // The pid is gone. Return some invalid process name to fail the test. + return QStringLiteral("/ERROR/"); + } + return QFileInfo(QString::fromUtf8(buf)).fileName(); +#elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) + kinfo_proc *proc = kinfo_getproc(pid); + if (!proc) + return QString(); + QString name = QString::fromUtf8(proc->ki_comm); + free(proc); + return name; +#else + return QString(); +#endif +} + void QLockFile::unlock() { Q_D(QLockFile); diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index 4e0d8134ec..8cbe0a9dfd 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 David Faure <faure+bluesystems@kde.org> +** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -140,6 +141,9 @@ bool QLockFilePrivate::isApparentlyStale() const ::CloseHandle(procHandle); if (dwR == WAIT_TIMEOUT) return true; + const QString processName = processNameByPid(pid); + if (!processName.isEmpty() && processName != appname) + return true; // PID got reused by a different application. } } #else // !Q_OS_WINRT @@ -151,6 +155,47 @@ bool QLockFilePrivate::isApparentlyStale() const return staleLockTime > 0 && age > staleLockTime; } +QString QLockFilePrivate::processNameByPid(qint64 pid) +{ +#if !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE) + typedef DWORD (WINAPI *GetModuleFileNameExFunc)(HANDLE, HMODULE, LPTSTR, DWORD); + + HMODULE hPsapi = LoadLibraryA("psapi"); + if (!hPsapi) + return QString(); + + GetModuleFileNameExFunc qGetModuleFileNameEx + = (GetModuleFileNameExFunc)GetProcAddress(hPsapi, "GetModuleFileNameExW"); + if (!qGetModuleFileNameEx) { + FreeLibrary(hPsapi); + return QString(); + } + + HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, DWORD(pid)); + if (!hProcess) { + FreeLibrary(hPsapi); + return QString(); + } + wchar_t buf[MAX_PATH]; + const DWORD length = qGetModuleFileNameEx(hProcess, NULL, buf, sizeof(buf) / sizeof(wchar_t)); + CloseHandle(hProcess); + FreeLibrary(hPsapi); + if (!length) + return QString(); + QString name = QString::fromWCharArray(buf, length); + int i = name.lastIndexOf(QLatin1Char('\\')); + if (i >= 0) + name.remove(0, i + 1); + i = name.lastIndexOf(QLatin1Char('.')); + if (i >= 0) + name.truncate(i); + return name; +#else + Q_UNUSED(pid); + return QString(); +#endif +} + void QLockFile::unlock() { Q_D(QLockFile); diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 7b8f608050..d170e7c0c0 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -67,8 +67,20 @@ #endif #if defined(Q_OS_BSD4) -# define QT_STATFSBUF struct statvfs -# define QT_STATFS ::statvfs +# if defined(Q_OS_NETBSD) + define QT_STATFSBUF struct statvfs + define QT_STATFS ::statvfs +# else +# define QT_STATFSBUF struct statfs +# define QT_STATFS ::statfs +# endif + +# if !defined(ST_RDONLY) +# define ST_RDONLY MNT_RDONLY +# endif +# if !defined(_STATFS_F_FLAGS) +# define _STATFS_F_FLAGS 1 +# endif #elif defined(Q_OS_ANDROID) # define QT_STATFS ::statfs # define QT_STATFSBUF struct statfs @@ -122,11 +134,7 @@ public: inline QByteArray device() const; private: #if defined(Q_OS_BSD4) -# if defined(Q_OS_NETBSD) - struct statvfs *stat_buf; -# else - struct statfs *stat_buf; -# endif + QT_STATFSBUF *stat_buf; int entryCount; int currentIndex; #elif defined(Q_OS_SOLARIS) @@ -501,7 +509,7 @@ void QStorageInfoPrivate::retrieveVolumeInfo() bytesTotal = statfs_buf.f_blocks * statfs_buf.f_bsize; bytesFree = statfs_buf.f_bfree * statfs_buf.f_bsize; bytesAvailable = statfs_buf.f_bavail * statfs_buf.f_bsize; -#if defined(Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) || defined (Q_OS_BSD4) #if defined(_STATFS_F_FLAGS) readOnly = (statfs_buf.f_flags & ST_RDONLY) != 0; #endif diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index b854dc16fd..1b214e9f74 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -1357,12 +1357,16 @@ namespace QtPrivate enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(yes_type) }; }; + template<typename T, typename Enable = void> + struct IsGadgetHelper { enum { Value = false }; }; + template<typename T> - struct IsGadgetHelper + struct IsGadgetHelper<T, typename T::QtGadgetHelper> { - template<typename X> static typename X::QtGadgetHelper *checkType(X*); - static char checkType(void*); - enum { Value = sizeof(checkType(static_cast<T*>(0))) == sizeof(void*) }; + template <typename X> + static char checkType(void (X::*)()); + static void *checkType(void (T::*)()); + enum { Value = sizeof(checkType(&T::qt_check_for_QGADGET_macro)) == sizeof(void *) }; }; @@ -1769,7 +1773,7 @@ template <typename T> struct QMetaTypeIdQObject<T, QMetaType::IsGadget> { enum { - Defined = 1 + Defined = QtPrivate::is_default_constructible<T>::value }; static int qt_metatype_id() diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 31e8a670e9..4d01264906 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -172,6 +172,7 @@ private: \ #define Q_GADGET \ public: \ static const QMetaObject staticMetaObject; \ + void qt_check_for_QGADGET_macro(); \ typedef void QtGadgetHelper; \ private: \ Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 255e9557e2..eaa695ef27 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -1362,11 +1362,11 @@ int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex \internal returns - 0 if str == QDateTimeEdit::tr("AM") - 1 if str == QDateTimeEdit::tr("PM") - 2 if str can become QDateTimeEdit::tr("AM") - 3 if str can become QDateTimeEdit::tr("PM") - 4 if str can become QDateTimeEdit::tr("PM") and can become QDateTimeEdit::tr("AM") + 0 if str == tr("AM") + 1 if str == tr("PM") + 2 if str can become tr("AM") + 3 if str can become tr("PM") + 4 if str can become tr("PM") and can become tr("AM") -1 can't become anything sensible */ @@ -1737,9 +1737,9 @@ QDateTime QDateTimeParser::getMaximum() const QString QDateTimeParser::getAmPmText(AmPm ap, Case cs) const { if (ap == AmText) { - return (cs == UpperCase ? QLatin1String("AM") : QLatin1String("am")); + return (cs == UpperCase ? tr("AM") : tr("am")); } else { - return (cs == UpperCase ? QLatin1String("PM") : QLatin1String("pm")); + return (cs == UpperCase ? tr("PM") : tr("pm")); } } diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h index 55dc3bf7a0..9457e35ad5 100644 --- a/src/corelib/tools/qdatetimeparser_p.h +++ b/src/corelib/tools/qdatetimeparser_p.h @@ -54,7 +54,7 @@ # include "QtCore/qvariant.h" #endif #include "QtCore/qvector.h" - +#include "QtCore/qcoreapplication.h" #define QDATETIMEEDIT_TIME_MIN QTime(0, 0, 0, 0) #define QDATETIMEEDIT_TIME_MAX QTime(23, 59, 59, 999) @@ -72,6 +72,7 @@ QT_BEGIN_NAMESPACE class Q_CORE_EXPORT QDateTimeParser { + Q_DECLARE_TR_FUNCTIONS(QDateTimeParser) public: enum Context { FromString, diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h index cec8ad62cb..32b76ee5bd 100644 --- a/src/dbus/qdbus_symbols_p.h +++ b/src/dbus/qdbus_symbols_p.h @@ -183,9 +183,6 @@ DEFINEFUNC(dbus_bool_t , dbus_connection_add_filter, (DBusConnection void *user_data, DBusFreeFunction free_data_function), (connection, function, user_data, free_data_function), return) -DEFINEFUNC(dbus_bool_t , dbus_connection_can_send_type, (DBusConnection *connection, - int type), - (connection, type), return) DEFINEFUNC(void , dbus_connection_close, (DBusConnection *connection), (connection), return) DEFINEFUNC(DBusDispatchStatus , dbus_connection_dispatch, (DBusConnection *connection), diff --git a/src/gui/kernel/qgenericpluginfactory.cpp b/src/gui/kernel/qgenericpluginfactory.cpp index 7e4727df8c..d7b9bfba06 100644 --- a/src/gui/kernel/qgenericpluginfactory.cpp +++ b/src/gui/kernel/qgenericpluginfactory.cpp @@ -69,13 +69,13 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, */ QObject *QGenericPluginFactory::create(const QString& key, const QString &specification) { +#if (!defined(Q_OS_WIN32) || defined(QT_SHARED)) && !defined(QT_NO_LIBRARY) const QString driver = key.toLower(); - -#if !defined(Q_OS_WIN32) || defined(QT_SHARED) -#ifndef QT_NO_LIBRARY if (QObject *object = qLoadPlugin1<QObject, QGenericPlugin>(loader(), driver, specification)) return object; -#endif +#else // (!Q_OS_WIN32 || QT_SHARED) && !QT_NO_LIBRARY + Q_UNUSED(key) + Q_UNUSED(specification) #endif return 0; } diff --git a/src/gui/kernel/qinputdevicemanager.cpp b/src/gui/kernel/qinputdevicemanager.cpp index d0dd8a4e7c..dbdb03adbb 100644 --- a/src/gui/kernel/qinputdevicemanager.cpp +++ b/src/gui/kernel/qinputdevicemanager.cpp @@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE QInputDeviceManager::QInputDeviceManager(QObject *parent) : QObject(*new QInputDeviceManagerPrivate, parent) { + qRegisterMetaType<DeviceType>(); } int QInputDeviceManager::deviceCount(DeviceType type) const diff --git a/src/gui/kernel/qinputdevicemanager_p.h b/src/gui/kernel/qinputdevicemanager_p.h index 15c84d1a82..d64793c23c 100644 --- a/src/gui/kernel/qinputdevicemanager_p.h +++ b/src/gui/kernel/qinputdevicemanager_p.h @@ -77,4 +77,6 @@ signals: QT_END_NAMESPACE +Q_DECLARE_METATYPE(QInputDeviceManager::DeviceType) + #endif // QINPUTDEVICEMANAGER_P_H diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp index 7113345a75..b2025faaf1 100644 --- a/src/gui/kernel/qopenglwindow.cpp +++ b/src/gui/kernel/qopenglwindow.cpp @@ -175,141 +175,156 @@ public: this->shareContext = qt_gl_global_share_context(); } - ~QOpenGLWindowPrivate() - { - Q_Q(QOpenGLWindow); - if (q->isValid()) { - q->makeCurrent(); // this works even when the platformwindow is destroyed - paintDevice.reset(0); - fbo.reset(0); - blitter.destroy(); - q->doneCurrent(); - } - } + ~QOpenGLWindowPrivate(); static QOpenGLWindowPrivate *get(QOpenGLWindow *w) { return w->d_func(); } - void bindFBO() - { - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->bind(); - else - QOpenGLFramebufferObject::bindDefault(); + void bindFBO(); + void initialize(); + + void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE; + void endPaint() Q_DECL_OVERRIDE; + void flush(const QRegion ®ion) Q_DECL_OVERRIDE; + + QOpenGLWindow::UpdateBehavior updateBehavior; + bool hasFboBlit; + QScopedPointer<QOpenGLContext> context; + QOpenGLContext *shareContext; + QScopedPointer<QOpenGLFramebufferObject> fbo; + QScopedPointer<QOpenGLWindowPaintDevice> paintDevice; + QOpenGLTextureBlitter blitter; + QColor backgroundColor; + QScopedPointer<QOffscreenSurface> offscreenSurface; +}; + +QOpenGLWindowPrivate::~QOpenGLWindowPrivate() +{ + Q_Q(QOpenGLWindow); + if (q->isValid()) { + q->makeCurrent(); // this works even when the platformwindow is destroyed + paintDevice.reset(0); + fbo.reset(0); + blitter.destroy(); + q->doneCurrent(); } +} - void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE - { - Q_UNUSED(region); - Q_Q(QOpenGLWindow); - - if (!context) { - context.reset(new QOpenGLContext); - context->setShareContext(shareContext); - context->setFormat(q->requestedFormat()); - context->setScreen(q->screen()); - if (!context->create()) - qWarning("QOpenGLWindow::beginPaint: Failed to create context"); - if (!context->makeCurrent(q)) - qWarning("QOpenGLWindow::beginPaint: Failed to make context current"); - - paintDevice.reset(new QOpenGLWindowPaintDevice(q)); - if (updateBehavior == QOpenGLWindow::PartialUpdateBlit) - hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit(); - - q->initializeGL(); - } else { - context->makeCurrent(q); - } +void QOpenGLWindowPrivate::initialize() +{ + Q_Q(QOpenGLWindow); - const int deviceWidth = q->width() * q->devicePixelRatio(); - const int deviceHeight = q->height() * q->devicePixelRatio(); - const QSize deviceSize(deviceWidth, deviceHeight); - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { - if (!fbo || fbo->size() != deviceSize) { - QOpenGLFramebufferObjectFormat fboFormat; - fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); - if (q->requestedFormat().samples() > 0) { - if (updateBehavior != QOpenGLWindow::PartialUpdateBlend) - fboFormat.setSamples(q->requestedFormat().samples()); - else - qWarning("QOpenGLWindow: PartialUpdateBlend does not support multisampling"); - } - fbo.reset(new QOpenGLFramebufferObject(deviceSize, fboFormat)); - markWindowAsDirty(); + if (context) + return; + + context.reset(new QOpenGLContext); + context->setShareContext(shareContext); + context->setFormat(q->requestedFormat()); + if (!context->create()) + qWarning("QOpenGLWindow::beginPaint: Failed to create context"); + if (!context->makeCurrent(q)) + qWarning("QOpenGLWindow::beginPaint: Failed to make context current"); + + paintDevice.reset(new QOpenGLWindowPaintDevice(q)); + if (updateBehavior == QOpenGLWindow::PartialUpdateBlit) + hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit(); + + q->initializeGL(); +} + +void QOpenGLWindowPrivate::beginPaint(const QRegion ®ion) +{ + Q_UNUSED(region); + Q_Q(QOpenGLWindow); + + initialize(); + context->makeCurrent(q); + + const int deviceWidth = q->width() * q->devicePixelRatio(); + const int deviceHeight = q->height() * q->devicePixelRatio(); + const QSize deviceSize(deviceWidth, deviceHeight); + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { + if (!fbo || fbo->size() != deviceSize) { + QOpenGLFramebufferObjectFormat fboFormat; + fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); + if (q->requestedFormat().samples() > 0) { + if (updateBehavior != QOpenGLWindow::PartialUpdateBlend) + fboFormat.setSamples(q->requestedFormat().samples()); + else + qWarning("QOpenGLWindow: PartialUpdateBlend does not support multisampling"); } - } else { + fbo.reset(new QOpenGLFramebufferObject(deviceSize, fboFormat)); markWindowAsDirty(); } + } else { + markWindowAsDirty(); + } - paintDevice->setSize(QSize(deviceWidth, deviceHeight)); - paintDevice->setDevicePixelRatio(q->devicePixelRatio()); - context->functions()->glViewport(0, 0, deviceWidth, deviceHeight); + paintDevice->setSize(QSize(deviceWidth, deviceHeight)); + paintDevice->setDevicePixelRatio(q->devicePixelRatio()); + context->functions()->glViewport(0, 0, deviceWidth, deviceHeight); - context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); + context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - q->paintUnderGL(); + q->paintUnderGL(); - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->bind(); - } + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) + fbo->bind(); +} - void endPaint() Q_DECL_OVERRIDE - { - Q_Q(QOpenGLWindow); - - if (updateBehavior > QOpenGLWindow::NoPartialUpdate) - fbo->release(); - - context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - - if (updateBehavior == QOpenGLWindow::PartialUpdateBlit && hasFboBlit) { - const int deviceWidth = q->width() * q->devicePixelRatio(); - const int deviceHeight = q->height() * q->devicePixelRatio(); - QOpenGLExtensions extensions(context.data()); - extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->handle()); - extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context->defaultFramebufferObject()); - extensions.glBlitFramebuffer(0, 0, deviceWidth, deviceHeight, - 0, 0, deviceWidth, deviceHeight, - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } else if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { - if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) { - context->functions()->glEnable(GL_BLEND); - context->functions()->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - if (!blitter.isCreated()) - blitter.create(); +void QOpenGLWindowPrivate::endPaint() +{ + Q_Q(QOpenGLWindow); + + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) + fbo->release(); - QRect windowRect(QPoint(0, 0), fbo->size()); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect); - blitter.bind(); - blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft); - blitter.release(); + context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject()); - if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) - context->functions()->glDisable(GL_BLEND); + if (updateBehavior == QOpenGLWindow::PartialUpdateBlit && hasFboBlit) { + const int deviceWidth = q->width() * q->devicePixelRatio(); + const int deviceHeight = q->height() * q->devicePixelRatio(); + QOpenGLExtensions extensions(context.data()); + extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo->handle()); + extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, context->defaultFramebufferObject()); + extensions.glBlitFramebuffer(0, 0, deviceWidth, deviceHeight, + 0, 0, deviceWidth, deviceHeight, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + } else if (updateBehavior > QOpenGLWindow::NoPartialUpdate) { + if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) { + context->functions()->glEnable(GL_BLEND); + context->functions()->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } + if (!blitter.isCreated()) + blitter.create(); - q->paintOverGL(); - } + QRect windowRect(QPoint(0, 0), fbo->size()); + QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect); + blitter.bind(); + blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft); + blitter.release(); - void flush(const QRegion ®ion) Q_DECL_OVERRIDE - { - Q_UNUSED(region); - Q_Q(QOpenGLWindow); - context->swapBuffers(q); - emit q->frameSwapped(); + if (updateBehavior == QOpenGLWindow::PartialUpdateBlend) + context->functions()->glDisable(GL_BLEND); } - QOpenGLWindow::UpdateBehavior updateBehavior; - bool hasFboBlit; - QScopedPointer<QOpenGLContext> context; - QOpenGLContext *shareContext; - QScopedPointer<QOpenGLFramebufferObject> fbo; - QScopedPointer<QOpenGLWindowPaintDevice> paintDevice; - QOpenGLTextureBlitter blitter; - QColor backgroundColor; - QScopedPointer<QOffscreenSurface> offscreenSurface; -}; + q->paintOverGL(); +} + +void QOpenGLWindowPrivate::bindFBO() +{ + if (updateBehavior > QOpenGLWindow::NoPartialUpdate) + fbo->bind(); + else + QOpenGLFramebufferObject::bindDefault(); +} + +void QOpenGLWindowPrivate::flush(const QRegion ®ion) +{ + Q_UNUSED(region); + Q_Q(QOpenGLWindow); + context->swapBuffers(q); + emit q->frameSwapped(); +} void QOpenGLWindowPaintDevice::ensureActiveTarget() { @@ -632,6 +647,8 @@ void QOpenGLWindow::paintEvent(QPaintEvent *event) void QOpenGLWindow::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); + Q_D(QOpenGLWindow); + d->initialize(); resizeGL(width(), height()); } diff --git a/src/gui/painting/qimagescale.cpp b/src/gui/painting/qimagescale.cpp index 5f1b25e189..9b4eabc552 100644 --- a/src/gui/painting/qimagescale.cpp +++ b/src/gui/painting/qimagescale.cpp @@ -38,22 +38,6 @@ QT_BEGIN_NAMESPACE -typedef void (*qt_qimageScaleFunc)(QImageScale::QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow); - -static void qt_qimageScaleAARGB(QImageScale::QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow); - -static void qt_qimageScaleAARGBA(QImageScale::QImageScaleInfo *isi, unsigned int *dest, - int dxx, int dyy, int dx, int dy, int dw, - int dh, int dow, int sow); - -qt_qimageScaleFunc qt_qimageScaleArgb = qt_qimageScaleAARGBA; -qt_qimageScaleFunc qt_qimageScaleRgb = qt_qimageScaleAARGB; - - /* * Copyright (C) 2004, 2005 Daniel M. Duley * @@ -115,13 +99,6 @@ using namespace QImageScale; // Code ported from Imlib... // -// FIXME: replace with qRed, etc... These work on pointers to pixels, not -// pixel values -#define A_VAL(p) (qAlpha(*p)) -#define R_VAL(p) (qRed(*p)) -#define G_VAL(p) (qGreen(*p)) -#define B_VAL(p) (qBlue(*p)) - const unsigned int** QImageScale::qimageCalcYPoints(const unsigned int *src, int sw, int sh, int dh) { @@ -381,46 +358,25 @@ static void qt_qimageScaleAARGBA(QImageScaleInfo *isi, unsigned int *dest, } } -inline static void qt_qimageScaleAARGBA_helper_x(const unsigned int *pix, int xap, int Cx, int &r, int &g, int &b, int &a) -{ - r = R_VAL(pix) * xap; - g = G_VAL(pix) * xap; - b = B_VAL(pix) * xap; - a = A_VAL(pix) * xap; - int j; - for (j = (1 << 14) - xap; j > Cx; j -= Cx ){ - pix++; - r += R_VAL(pix) * Cx; - g += G_VAL(pix) * Cx; - b += B_VAL(pix) * Cx; - a += A_VAL(pix) * Cx; - } - pix++; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; - a += A_VAL(pix) * j; -} - -inline static void qt_qimageScaleAARGBA_helper_y(const unsigned int *pix, int yap, int Cy, int sow, int &r, int &g, int &b, int &a) +inline static void qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, int &r, int &g, int &b, int &a) { - r = R_VAL(pix) * yap; - g = G_VAL(pix) * yap; - b = B_VAL(pix) * yap; - a = A_VAL(pix) * yap; + r = qRed(*pix) * xyap; + g = qGreen(*pix) * xyap; + b = qBlue(*pix) * xyap; + a = qAlpha(*pix) * xyap; int j; - for (j = (1 << 14) - yap; j > Cy; j -= Cy ){ - pix += sow; - r += R_VAL(pix) * Cy; - g += G_VAL(pix) * Cy; - b += B_VAL(pix) * Cy; - a += A_VAL(pix) * Cy; - } - pix += sow; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; - a += A_VAL(pix) * j; + for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy) { + pix += step; + r += qRed(*pix) * Cxy; + g += qGreen(*pix) * Cxy; + b += qBlue(*pix) * Cxy; + a += qAlpha(*pix) * Cxy; + } + pix += step; + r += qRed(*pix) * j; + g += qGreen(*pix) * j; + b += qBlue(*pix) * j; + a += qAlpha(*pix) * j; } static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, @@ -443,12 +399,12 @@ static void qt_qimageScaleAARGBA_up_x_down_y(QImageScaleInfo *isi, unsigned int for (int x = dxx; x < end; x++) { const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b, a; - qt_qimageScaleAARGBA_helper_y(sptr, yap, Cy, sow, r, g, b, a); + qt_qimageScaleAARGBA_helper(sptr, yap, Cy, sow, r, g, b, a); int xap = xapoints[x]; if (xap > 0) { int rr, gg, bb, aa; - qt_qimageScaleAARGBA_helper_y(sptr + 1, yap, Cy, sow, rr, gg, bb, aa); + qt_qimageScaleAARGBA_helper(sptr + 1, yap, Cy, sow, rr, gg, bb, aa); r = r * (256 - xap); g = g * (256 - xap); @@ -484,12 +440,12 @@ static void qt_qimageScaleAARGBA_down_x_up_y(QImageScaleInfo *isi, unsigned int const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b, a; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, r, g, b, a); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, r, g, b, a); int yap = yapoints[dyy + y]; if (yap > 0) { int rr, gg, bb, aa; - qt_qimageScaleAARGBA_helper_x(sptr + sow, xap, Cx, rr, gg, bb, aa); + qt_qimageScaleAARGBA_helper(sptr + sow, xap, Cx, 1, rr, gg, bb, aa); r = r * (256 - yap); g = g * (256 - yap); @@ -528,7 +484,7 @@ static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *des const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int rx, gx, bx, ax; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, rx, gx, bx, ax); int r = ((rx>>4) * yap); int g = ((gx>>4) * yap); @@ -538,14 +494,14 @@ static void qt_qimageScaleAARGBA_down_xy(QImageScaleInfo *isi, unsigned int *des int j; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { sptr += sow; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, rx, gx, bx, ax); r += ((rx>>4) * Cy); g += ((gx>>4) * Cy); b += ((bx>>4) * Cy); a += ((ax>>4) * Cy); } sptr += sow; - qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, rx, gx, bx, ax); + qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, rx, gx, bx, ax); r += ((rx>>4) * j); g += ((gx>>4) * j); @@ -609,40 +565,22 @@ static void qt_qimageScaleAARGB(QImageScaleInfo *isi, unsigned int *dest, } -inline static void qt_qimageScaleAARGB_helper_x(const unsigned int *pix, int xap, int Cx, int &r, int &g, int &b) +inline static void qt_qimageScaleAARGB_helper(const unsigned int *pix, int xyap, int Cxy, int step, int &r, int &g, int &b) { - r = R_VAL(pix) * xap; - g = G_VAL(pix) * xap; - b = B_VAL(pix) * xap; + r = qRed(*pix) * xyap; + g = qGreen(*pix) * xyap; + b = qBlue(*pix) * xyap; int j; - for (j = (1 << 14) - xap; j > Cx; j -= Cx ){ - pix++; - r += R_VAL(pix) * Cx; - g += G_VAL(pix) * Cx; - b += B_VAL(pix) * Cx; - } - pix++; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; -} - -inline static void qt_qimageScaleAARGB_helper_y(const unsigned int *pix, int yap, int Cy, int sow, int &r, int &g, int &b) -{ - r = R_VAL(pix) * yap; - g = G_VAL(pix) * yap; - b = B_VAL(pix) * yap; - int j; - for (j = (1 << 14) - yap; j > Cy; j -= Cy ){ - pix += sow; - r += R_VAL(pix) * Cy; - g += G_VAL(pix) * Cy; - b += B_VAL(pix) * Cy; - } - pix += sow; - r += R_VAL(pix) * j; - g += G_VAL(pix) * j; - b += B_VAL(pix) * j; + for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy) { + pix += step; + r += qRed(*pix) * Cxy; + g += qGreen(*pix) * Cxy; + b += qBlue(*pix) * Cxy; + } + pix += step; + r += qRed(*pix) * j; + g += qGreen(*pix) * j; + b += qBlue(*pix) * j; } static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int *dest, @@ -665,12 +603,12 @@ static void qt_qimageScaleAARGB_up_x_down_y(QImageScaleInfo *isi, unsigned int * for (int x = dxx; x < end; x++) { const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b; - qt_qimageScaleAARGB_helper_y(sptr, yap, Cy, sow, r, g, b); + qt_qimageScaleAARGB_helper(sptr, yap, Cy, sow, r, g, b); int xap = xapoints[x]; if (xap > 0) { int rr, bb, gg; - qt_qimageScaleAARGB_helper_y(sptr + 1, yap, Cy, sow, rr, gg, bb); + qt_qimageScaleAARGB_helper(sptr + 1, yap, Cy, sow, rr, gg, bb); r = r * (256 - xap); g = g * (256 - xap); @@ -704,12 +642,12 @@ static void qt_qimageScaleAARGB_down_x_up_y(QImageScaleInfo *isi, unsigned int * const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int r, g, b; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, r, g, b); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, r, g, b); int yap = yapoints[dyy + y]; if (yap > 0) { int rr, bb, gg; - qt_qimageScaleAARGB_helper_x(sptr + sow, xap, Cx, rr, gg, bb); + qt_qimageScaleAARGB_helper(sptr + sow, xap, Cx, 1, rr, gg, bb); r = r * (256 - yap); g = g * (256 - yap); @@ -745,7 +683,7 @@ static void qt_qimageScaleAARGB_down_xy(QImageScaleInfo *isi, unsigned int *dest const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; int rx, gx, bx; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, rx, gx, bx); int r = (rx >> 4) * yap; int g = (gx >> 4) * yap; @@ -754,14 +692,14 @@ static void qt_qimageScaleAARGB_down_xy(QImageScaleInfo *isi, unsigned int *dest int j; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { sptr += sow; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, rx, gx, bx); r += (rx >> 4) * Cy; g += (gx >> 4) * Cy; b += (bx >> 4) * Cy; } sptr += sow; - qt_qimageScaleAARGB_helper_x(sptr, xap, Cx, rx, gx, bx); + qt_qimageScaleAARGB_helper(sptr, xap, Cx, 1, rx, gx, bx); r += (rx >> 4) * j; g += (gx >> 4) * j; @@ -794,11 +732,11 @@ QImage qSmoothScaleImage(const QImage &src, int dw, int dh) } if (src.hasAlphaChannel()) - qt_qimageScaleArgb(scaleinfo, (unsigned int *)buffer.scanLine(0), - 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); + qt_qimageScaleAARGBA(scaleinfo, (unsigned int *)buffer.scanLine(0), + 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); else - qt_qimageScaleRgb(scaleinfo, (unsigned int *)buffer.scanLine(0), - 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); + qt_qimageScaleAARGB(scaleinfo, (unsigned int *)buffer.scanLine(0), + 0, 0, 0, 0, dw, dh, dw, src.bytesPerLine() / 4); qimageFreeScaleInfo(scaleinfo); return buffer; diff --git a/src/gui/painting/qimagescale_sse4.cpp b/src/gui/painting/qimagescale_sse4.cpp index 565ea4daa1..303e0fd980 100644 --- a/src/gui/painting/qimagescale_sse4.cpp +++ b/src/gui/painting/qimagescale_sse4.cpp @@ -41,33 +41,17 @@ QT_BEGIN_NAMESPACE using namespace QImageScale; -inline static __m128i qt_qimageScaleAARGBA_helper_x(const unsigned int *pix, int xap, int Cx, const __m128i vxap, const __m128i vCx) +inline static __m128i qt_qimageScaleAARGBA_helper(const unsigned int *pix, int xyap, int Cxy, int step, const __m128i vxyap, const __m128i vCxy) { __m128i vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - __m128i vx = _mm_mullo_epi32(vpix, vxap); + __m128i vx = _mm_mullo_epi32(vpix, vxyap); int i; - for (i = (1 << 14) - xap; i > Cx; i -= Cx) { - pix++; + for (i = (1 << 14) - xyap; i > Cxy; i -= Cxy) { + pix += step; vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCx)); + vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCxy)); } - pix++; - vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, _mm_set1_epi32(i))); - return vx; -} - -inline static __m128i qt_qimageScaleAARGBA_helper_y(const unsigned int *pix, int yap, int Cy, int sow, const __m128i vyap, const __m128i vCy) -{ - __m128i vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - __m128i vx = _mm_mullo_epi32(vpix, vyap); - int i; - for (i = (1 << 14) - yap; i > Cy; i -= Cy) { - pix += sow; - vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); - vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, vCy)); - } - pix += sow; + pix += step; vpix = _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*pix)); vx = _mm_add_epi32(vx, _mm_mullo_epi32(vpix, _mm_set1_epi32(i))); return vx; @@ -97,13 +81,13 @@ void qt_qimageScaleAARGBA_up_x_down_y_sse4(QImageScaleInfo *isi, unsigned int *d unsigned int *dptr = dest + dx + ((y + dy) * dow); for (int x = dxx; x < end; x++) { const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; - __m128i vx = qt_qimageScaleAARGBA_helper_y(sptr, yap, Cy, sow, vyap, vCy); + __m128i vx = qt_qimageScaleAARGBA_helper(sptr, yap, Cy, sow, vyap, vCy); int xap = xapoints[x]; if (xap > 0) { const __m128i vxap = _mm_set1_epi32(xap); const __m128i vinvxap = _mm_sub_epi32(v256, vxap); - __m128i vr = qt_qimageScaleAARGBA_helper_y(sptr + 1, yap, Cy, sow, vyap, vCy); + __m128i vr = qt_qimageScaleAARGBA_helper(sptr + 1, yap, Cy, sow, vyap, vCy); vx = _mm_mullo_epi32(vx, vinvxap); vr = _mm_mullo_epi32(vr, vxap); @@ -145,13 +129,13 @@ void qt_qimageScaleAARGBA_down_x_up_y_sse4(QImageScaleInfo *isi, unsigned int *d const __m128i vxap = _mm_set1_epi32(xap); const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; - __m128i vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + __m128i vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); int yap = yapoints[dyy + y]; if (yap > 0) { const __m128i vyap = _mm_set1_epi32(yap); const __m128i vinvyap = _mm_sub_epi32(v256, vyap); - __m128i vr = qt_qimageScaleAARGBA_helper_x(sptr + sow, xap, Cx, vxap, vCx); + __m128i vr = qt_qimageScaleAARGBA_helper(sptr + sow, xap, Cx, 1, vxap, vCx); vx = _mm_mullo_epi32(vx, vinvyap); vr = _mm_mullo_epi32(vr, vyap); @@ -194,17 +178,17 @@ void qt_qimageScaleAARGBA_down_xy_sse4(QImageScaleInfo *isi, unsigned int *dest, const __m128i vxap = _mm_set1_epi32(xap); const unsigned int *sptr = ypoints[dyy + y] + xpoints[x]; - __m128i vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + __m128i vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); __m128i vr = _mm_mullo_epi32(_mm_srli_epi32(vx, 4), vyap); int j; for (j = (1 << 14) - yap; j > Cy; j -= Cy) { sptr += sow; - vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); vr = _mm_add_epi32(vr, _mm_mullo_epi32(_mm_srli_epi32(vx, 4), vCy)); } sptr += sow; - vx = qt_qimageScaleAARGBA_helper_x(sptr, xap, Cx, vxap, vCx); + vx = qt_qimageScaleAARGBA_helper(sptr, xap, Cx, 1, vxap, vCx); vr = _mm_add_epi32(vr, _mm_mullo_epi32(_mm_srli_epi32(vx, 4), _mm_set1_epi32(j))); vr = _mm_srli_epi32(vr, 24); diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp index 14a9429c71..62492980de 100644 --- a/src/gui/painting/qplatformbackingstore.cpp +++ b/src/gui/painting/qplatformbackingstore.cpp @@ -83,9 +83,10 @@ public: struct QBackingstoreTextureInfo { - QWidget *widget; // may be null + void *source; // may be null GLuint textureId; QRect rect; + QRect clipRect; QPlatformTextureList::Flags flags; }; @@ -124,10 +125,10 @@ GLuint QPlatformTextureList::textureId(int index) const return d->textures.at(index).textureId; } -QWidget *QPlatformTextureList::widget(int index) +void *QPlatformTextureList::source(int index) { Q_D(const QPlatformTextureList); - return d->textures.at(index).widget; + return d->textures.at(index).source; } QPlatformTextureList::Flags QPlatformTextureList::flags(int index) const @@ -142,6 +143,12 @@ QRect QPlatformTextureList::geometry(int index) const return d->textures.at(index).rect; } +QRect QPlatformTextureList::clipRect(int index) const +{ + Q_D(const QPlatformTextureList); + return d->textures.at(index).clipRect; +} + void QPlatformTextureList::lock(bool on) { Q_D(QPlatformTextureList); @@ -157,13 +164,15 @@ bool QPlatformTextureList::isLocked() const return d->locked; } -void QPlatformTextureList::appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, Flags flags) +void QPlatformTextureList::appendTexture(void *source, GLuint textureId, const QRect &geometry, + const QRect &clipRect, Flags flags) { Q_D(QPlatformTextureList); QBackingstoreTextureInfo bi; - bi.widget = widget; + bi.source = source; bi.textureId = textureId; bi.rect = geometry; + bi.clipRect = clipRect; bi.flags = flags; d->textures.append(bi); } @@ -198,7 +207,7 @@ void QPlatformTextureList::clear() #ifndef QT_NO_OPENGL -static QRect deviceRect(const QRect &rect, QWindow *window) +static inline QRect deviceRect(const QRect &rect, QWindow *window) { QRect deviceRect(rect.topLeft() * window->devicePixelRatio(), rect.size() * window->devicePixelRatio()); @@ -219,6 +228,32 @@ static QRegion deviceRegion(const QRegion ®ion, QWindow *window) return deviceRegion; } +static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) +{ + return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1, + topLeftRect.width(), topLeftRect.height()); +} + +static void blit(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect, + QOpenGLTextureBlitter *blitter) +{ + const QRect rectInWindow = textures->geometry(idx); + QRect clipRect = textures->clipRect(idx); + if (clipRect.isEmpty()) + clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); + const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); + + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(deviceRect(clippedRectInWindow, window), + deviceWindowRect); + + const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(deviceRect(srcRect, window), + deviceRect(rectInWindow, window).size(), + QOpenGLTextureBlitter::OriginBottomLeft); + + blitter->blit(textures->textureId(idx), target, source); +} + /*! Flushes the given \a region from the specified \a window onto the screen, and composes it with the specified \a textures. @@ -254,15 +289,12 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i d_ptr->blitter->bind(); - QRect windowRect(QPoint(), window->size() * window->devicePixelRatio()); + const QRect deviceWindowRect = deviceRect(QRect(QPoint(), window->size()), window); // Textures for renderToTexture widgets. for (int i = 0; i < textures->count(); ++i) { - if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { - QRect targetRect = deviceRect(textures->geometry(i), window); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect); - d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); - } + if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) + blit(textures, i, window, deviceWindowRect, d_ptr->blitter); } funcs->glEnable(GL_BLEND); @@ -272,6 +304,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i // semi-transparency even when it is not wanted. funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + // Backingstore texture with the normal widgets. GLuint textureId = 0; QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft; if (QPlatformGraphicsBuffer *graphicsBuffer = this->graphicsBuffer()) { @@ -307,7 +340,6 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i origin = QOpenGLTextureBlitter::OriginBottomLeft; textureId = d_ptr->textureId; } else { - // Backingstore texture with the normal widgets. TextureFlags flags = 0; textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize, &flags); d_ptr->needsSwizzle = (flags & TextureSwizzle) != 0; @@ -316,7 +348,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i } if (textureId) { - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), windowRect); + QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), deviceWindowRect); if (d_ptr->needsSwizzle) d_ptr->blitter->setSwizzleRB(true); d_ptr->blitter->blit(textureId, target, origin); @@ -326,11 +358,8 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i // Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set. for (int i = 0; i < textures->count(); ++i) { - if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { - QRect targetRect = deviceRect(textures->geometry(i), window); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect); - d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); - } + if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) + blit(textures, i, window, deviceWindowRect, d_ptr->blitter); } funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); diff --git a/src/gui/painting/qplatformbackingstore.h b/src/gui/painting/qplatformbackingstore.h index ae7314b6d0..eac97e9cf6 100644 --- a/src/gui/painting/qplatformbackingstore.h +++ b/src/gui/painting/qplatformbackingstore.h @@ -82,12 +82,14 @@ public: bool isEmpty() const { return count() == 0; } GLuint textureId(int index) const; QRect geometry(int index) const; - QWidget *widget(int index); + QRect clipRect(int index) const; + void *source(int index); Flags flags(int index) const; void lock(bool on); bool isLocked() const; - void appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, Flags flags = 0); + void appendTexture(void *source, GLuint textureId, const QRect &geometry, + const QRect &clipRect = QRect(), Flags flags = 0); void clear(); Q_SIGNALS: diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index bb89eece4b..a83d56f31f 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -736,7 +736,10 @@ void QFtpDTP::socketConnectionClosed() clearData(); } - bytesFromSocket = socket->readAll(); + if (socket->isOpen()) + bytesFromSocket = socket->readAll(); + else + bytesFromSocket.clear(); #if defined(QFTPDTP_DEBUG) qDebug("QFtpDTP::connectState(CsClosed)"); #endif diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index 361fcf7ca2..42920c96f2 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -46,6 +46,7 @@ // #include <QtCore/QEventLoop> #include <QtCore/QBuffer> +#include <QtCore/QMutex> #include "QtNetwork/qhostaddress.h" #include "private/qabstractsocketengine_p.h" #include <wrl.h> diff --git a/src/network/ssl/qsslellipticcurve_dummy.cpp b/src/network/ssl/qsslellipticcurve_dummy.cpp index d05c920a49..16b7a3cd00 100644 --- a/src/network/ssl/qsslellipticcurve_dummy.cpp +++ b/src/network/ssl/qsslellipticcurve_dummy.cpp @@ -57,7 +57,7 @@ QSslEllipticCurve QSslEllipticCurve::fromLongName(const QString &name) return QSslEllipticCurve(); } -bool QSslEllipticCurve::isTlsNamedCurve() const +bool QSslEllipticCurve::isTlsNamedCurve() const Q_DECL_NOTHROW { return false; } diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 637c375311..9a1ae6e008 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -304,19 +304,23 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub for (int x = 0; x < maskWidth; ++x) src[x] = -src[x]; // convert 0 and 1 into 0 and 255 } - } else if (mask.format() == QImage::Format_RGB32) { + } else if (mask.depth() == 32) { // Make the alpha component equal to the average of the RGB values. // This is needed when drawing sub-pixel antialiased text on translucent targets. for (int y = 0; y < maskHeight; ++y) { quint32 *src = (quint32 *) mask.scanLine(y); for (int x = 0; x < maskWidth; ++x) { - uchar r = src[x] >> 16; - uchar g = src[x] >> 8; - uchar b = src[x]; - quint32 avg = (quint32(r) + quint32(g) + quint32(b) + 1) / 3; // "+1" for rounding. + int r = qRed(src[x]); + int g = qGreen(src[x]); + int b = qBlue(src[x]); + int avg; + if (mask.format() == QImage::Format_RGB32) + avg = (r + g + b + 1) / 3; // "+1" for rounding. + else // Format_ARGB_Premultiplied + avg = qAlpha(src[x]); if (ctx->contextHandle()->isOpenGLES()) { // swizzle the bits to accommodate for the GL_RGBA upload. - src[x] = (avg << 24) | (quint32(r) << 0) | (quint32(g) << 8) | (quint32(b) << 16); + src[x] = (avg << 24) | (r << 0) | (g << 8) | (b << 16); } else { src[x] = (src[x] & 0x00ffffff) | (avg << 24); } @@ -325,7 +329,7 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph, QFixed sub } funcs->glBindTexture(GL_TEXTURE_2D, m_textureResource->m_texture); - if (mask.format() == QImage::Format_RGB32) { + if (mask.depth() == 32) { GLenum format = GL_RGBA; #if !defined(QT_OPENGL_ES_2) if (!ctx->contextHandle()->isOpenGLES()) diff --git a/src/platformsupport/platformcompositor/qopenglcompositor.cpp b/src/platformsupport/platformcompositor/qopenglcompositor.cpp index 3fd6c999a2..2e386532e2 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositor.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositor.cpp @@ -169,6 +169,29 @@ struct BlendStateBinder bool m_blend; }; +static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) +{ + return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1, + topLeftRect.width(), topLeftRect.height()); +} + +static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect, QOpenGLTextureBlitter *blitter) +{ + const QRect rectInWindow = textures->geometry(idx); + QRect clipRect = textures->clipRect(idx); + if (clipRect.isEmpty()) + clipRect = QRect(QPoint(0, 0), rectInWindow.size()); + + const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft()); + const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height()); + + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(clippedRectInWindow, targetWindowRect); + const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(srcRect, rectInWindow.size(), + QOpenGLTextureBlitter::OriginBottomLeft); + + blitter->blit(textures->textureId(idx), target, source); +} + void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) { const QPlatformTextureList *textures = window->textures(); @@ -181,7 +204,6 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) for (int i = 0; i < textures->count(); ++i) { uint textureId = textures->textureId(i); - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); const float opacity = window->sourceWindow()->opacity(); if (opacity != currentOpacity) { currentOpacity = opacity; @@ -191,24 +213,25 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) if (textures->count() > 1 && i == textures->count() - 1) { // Backingstore for a widget with QOpenGLWidget subwidgets blend.set(true); + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); } else if (textures->count() == 1) { // A regular QWidget window const bool translucent = window->sourceWindow()->requestedFormat().alphaBufferSize() > 0; blend.set(translucent); + const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); } else if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { // Texture from an FBO belonging to a QOpenGLWidget blend.set(false); - m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginBottomLeft); + clippedBlit(textures, i, targetWindowRect, &m_blitter); } } for (int i = 0; i < textures->count(); ++i) { if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { - QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); blend.set(true); - m_blitter.blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft); + clippedBlit(textures, i, targetWindowRect, &m_blitter); } } diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp index 3caec468a6..8ce1ed2d2b 100644 --- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp +++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp @@ -175,7 +175,8 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi m_textures->clear(); for (int i = 0; i < textures->count(); ++i) - m_textures->appendTexture(textures->widget(i), textures->textureId(i), textures->geometry(i), textures->flags(i)); + m_textures->appendTexture(textures->source(i), textures->textureId(i), textures->geometry(i), + textures->clipRect(i), textures->flags(i)); updateTexture(); m_textures->appendTexture(Q_NULLPTR, m_bsTexture, window->geometry()); diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm index 9530dd83d0..a30d8f69c4 100644 --- a/src/plugins/bearer/corewlan/qcorewlanengine.mm +++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm @@ -85,8 +85,11 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time return self; } +static QT_MANGLE_NAMESPACE(QNSListener) *listener = 0; + -(void)dealloc { + listener = nil; [super dealloc]; } @@ -117,7 +120,6 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time } @end -static QT_MANGLE_NAMESPACE(QNSListener) *listener = 0; QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm index 09a4c95469..dd2c37d914 100644 --- a/src/plugins/platforms/cocoa/qcocoamenu.mm +++ b/src/plugins/platforms/cocoa/qcocoamenu.mm @@ -81,7 +81,7 @@ QT_END_NAMESPACE } - (id) initWithMenu:(QCocoaMenu*) m; -- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier; +- (NSMenuItem *)findItem:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier; @end @@ -152,11 +152,20 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); // Change the private unicode keys to the ones used in setting the "Key Equivalents" NSString *characters = qt_mac_removePrivateUnicode([event characters]); - if ([self hasShortcut:menu - forKey:characters - // Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ... - forModifiers:([event modifierFlags] & (NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask)) - ]) { + // Interested only in Shift, Cmd, Ctrl & Alt Keys, so ignoring masks like, Caps lock, Num Lock ... + const NSUInteger mask = NSShiftKeyMask | NSControlKeyMask | NSCommandKeyMask | NSAlternateKeyMask; + if (NSMenuItem *menuItem = [self findItem:menu forKey:characters forModifiers:([event modifierFlags] & mask)]) { + if (!menuItem.target) { + // This item was modified by QCocoaMenuBar::redirectKnownMenuItemsToFirstResponder + // and it looks like we're running a modal session for NSOpenPanel/NSSavePanel. + // QCocoaFileDialogHelper is actually the only place we use this and we run NSOpenPanel modal + // (modal sheet, window modal, application modal). + // Whatever the current first responder is, let's give it a chance + // and do not touch the Qt's focusObject (which is different from some native view + // having a focus inside NSSave/OpenPanel. + return YES; + } + QObject *object = qApp->focusObject(); if (object) { QChar ch; @@ -194,22 +203,23 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QCocoaMenuDelegate); return NO; } -- (BOOL)hasShortcut:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier +- (NSMenuItem *)findItem:(NSMenu *)menu forKey:(NSString *)key forModifiers:(NSUInteger)modifier { for (NSMenuItem *item in [menu itemArray]) { if (![item isEnabled] || [item isHidden] || [item isSeparatorItem]) continue; - if ([item hasSubmenu] - && [self hasShortcut:[item submenu] forKey:key forModifiers:modifier]) - return YES; + if ([item hasSubmenu]) { + if (NSMenuItem *nested = [self findItem:[item submenu] forKey:key forModifiers:modifier]) + return nested; + } NSString *menuKey = [item keyEquivalent]; if (menuKey && NSOrderedSame == [menuKey compare:key] && modifier == [item keyEquivalentModifierMask]) - return YES; + return item; } - return NO; + return nil; } @end diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index cbe4227b63..86959869cc 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -799,9 +799,22 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags) if (flags & Qt::FramelessWindowHint) return styleMask; if ((type & Qt::Popup) == Qt::Popup) { - if (!windowIsPopupType(type)) - styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask | NSTitledWindowMask); + if (!windowIsPopupType(type)) { + styleMask = NSUtilityWindowMask; + if (!(flags & Qt::CustomizeWindowHint)) { + styleMask |= NSResizableWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask | NSTitledWindowMask; + } else { + if (flags & Qt::WindowMaximizeButtonHint) + styleMask |= NSResizableWindowMask; + if (flags & Qt::WindowTitleHint) + styleMask |= NSTitledWindowMask; + if (flags & Qt::WindowCloseButtonHint) + styleMask |= NSClosableWindowMask; + if (flags & Qt::WindowMinimizeButtonHint) + styleMask |= NSMiniaturizableWindowMask; + } + } } else { if (type == Qt::Window && !(flags & Qt::CustomizeWindowHint)) { styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask); diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp index d439196dc1..16c05329de 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp @@ -358,10 +358,10 @@ public: } else if (path.isRect() && (q->state()->matrix.type() <= QTransform::TxScale)) { const qreal * const points = path.points(); D2D_RECT_F rect = { - points[0], // left - points[1], // top - points[2], // right, - points[5] // bottom + FLOAT(points[0]), // left + FLOAT(points[1]), // top + FLOAT(points[2]), // right, + FLOAT(points[5]) // bottom }; dc()->PushAxisAlignedClip(rect, antialiasMode()); @@ -918,13 +918,13 @@ public: DWRITE_GLYPH_RUN glyphRun = { fontFace, // IDWriteFontFace *fontFace; - fontDef.pixelSize, // FLOAT fontEmSize; - numGlyphs, // UINT32 glyphCount; + FLOAT(fontDef.pixelSize), // FLOAT fontEmSize; + UINT32(numGlyphs), // UINT32 glyphCount; glyphIndices, // const UINT16 *glyphIndices; glyphAdvances, // const FLOAT *glyphAdvances; glyphOffsets, // const DWRITE_GLYPH_OFFSET *glyphOffsets; FALSE, // BOOL isSideways; - rtl ? 1 : 0 // UINT32 bidiLevel; + rtl ? 1u : 0u // UINT32 bidiLevel; }; const bool antiAlias = bool((q->state()->renderHints & QPainter::TextAntialiasing) @@ -1393,8 +1393,8 @@ void QWindowsDirect2DPaintEngine::drawEllipse(const QRectF &r) D2D1_ELLIPSE ellipse = { to_d2d_point_2f(p), - r.width() / 2.0, - r.height() / 2.0 + FLOAT(r.width() / 2.0), + FLOAT(r.height() / 2.0) }; if (d->brush.brush) @@ -1421,8 +1421,8 @@ void QWindowsDirect2DPaintEngine::drawEllipse(const QRect &r) D2D1_ELLIPSE ellipse = { to_d2d_point_2f(p), - r.width() / 2.0, - r.height() / 2.0 + FLOAT(r.width() / 2.0), + FLOAT(r.height() / 2.0) }; if (d->brush.brush) diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp index e762eab711..ba23526447 100644 --- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp +++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp @@ -163,7 +163,7 @@ void QWindowsDirect2DWindow::present(const QRegion ®ion) const SIZE size = { bounds.width(), bounds.height() }; const POINT ptDst = { bounds.x(), bounds.y() }; const POINT ptSrc = { 0, 0 }; - const BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255.0 * opacity(), AC_SRC_ALPHA }; + const BLENDFUNCTION blend = { AC_SRC_OVER, 0, BYTE(255.0 * opacity()), AC_SRC_ALPHA }; const QRect r = region.boundingRect(); const RECT dirty = { r.left(), r.top(), r.left() + r.width(), r.top() + r.height() }; UPDATELAYEREDWINDOWINFO info = { sizeof(UPDATELAYEREDWINDOWINFO), NULL, diff --git a/src/plugins/platforms/eglfs/qeglfswindow.cpp b/src/plugins/platforms/eglfs/qeglfswindow.cpp index 30fdce9fd3..c0d51c94a5 100644 --- a/src/plugins/platforms/eglfs/qeglfswindow.cpp +++ b/src/plugins/platforms/eglfs/qeglfswindow.cpp @@ -35,6 +35,7 @@ #include <qpa/qwindowsysteminterface.h> #include <qpa/qplatformintegration.h> #include <private/qguiapplication_p.h> +#include <QtGui/private/qopenglcontext_p.h> #include <QtGui/QOpenGLContext> #include <QtPlatformSupport/private/qeglplatformcursor_p.h> #include <QtPlatformSupport/private/qeglconvenience_p.h> @@ -106,6 +107,7 @@ void QEglFSWindow::create() if (isRaster()) { QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance()); + context->setShareContext(qt_gl_global_share_context()); context->setFormat(m_format); context->setScreen(window()->screen()); if (!context->create()) diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp index 99c44c69ef..5ed8d30e67 100644 --- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp +++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp @@ -102,7 +102,7 @@ HRESULT STDMETHODCALLTYPE AccessibleApplication::get_toolkitName(/* [retval][out HRESULT STDMETHODCALLTYPE AccessibleApplication::get_toolkitVersion(/* [retval][out] */ BSTR *version) { - *version = ::SysAllocString(QT_UNICODE_LITERAL(QT_VERSION_STR)); + *version = ::SysAllocString(TEXT(QT_VERSION_STR)); return S_OK; } diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 0184877fdd..06c9985cac 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -39,7 +39,6 @@ #include <QtGui/QOpenGLContext> #if defined(QT_OPENGL_ES_2_ANGLE) || defined(QT_OPENGL_DYNAMIC) -# define EGL_EGLEXT_PROTOTYPES # include <QtANGLE/EGL/eglext.h> #endif @@ -137,7 +136,6 @@ bool QWindowsLibEGL::init() eglGetError = RESOLVE((EGLint (EGLAPIENTRY *)(void)), eglGetError); eglGetDisplay = RESOLVE((EGLDisplay (EGLAPIENTRY *)(EGLNativeDisplayType)), eglGetDisplay); - eglGetPlatformDisplayEXT = RESOLVE((EGLDisplay (EGLAPIENTRY *)(EGLenum platform, void *native_display, const EGLint *attrib_list)), eglGetPlatformDisplayEXT); eglInitialize = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay, EGLint *, EGLint *)), eglInitialize); eglTerminate = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay)), eglTerminate); eglChooseConfig = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay, const EGLint *, EGLConfig *, EGLint, EGLint *)), eglChooseConfig); @@ -156,7 +154,15 @@ bool QWindowsLibEGL::init() eglSwapBuffers = RESOLVE((EGLBoolean (EGLAPIENTRY *)(EGLDisplay , EGLSurface)), eglSwapBuffers); eglGetProcAddress = RESOLVE((__eglMustCastToProperFunctionPointerType (EGLAPIENTRY * )(const char *)), eglGetProcAddress); - return eglGetError && eglGetDisplay && eglInitialize; + if (!eglGetError || !eglGetDisplay || !eglInitialize || !eglGetProcAddress) + return false; + + eglGetPlatformDisplayEXT = 0; +#ifdef EGL_ANGLE_platform_angle + eglGetPlatformDisplayEXT = reinterpret_cast<EGLDisplay (EGLAPIENTRY *)(EGLenum, void *, const EGLint *)>(eglGetProcAddress("eglGetPlatformDisplayEXT")); +#endif + + return true; } #if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) @@ -360,7 +366,7 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: EGLDisplay display = EGL_NO_DISPLAY; EGLint major = 0; EGLint minor = 0; -#ifdef EGL_ANGLE_platform_angle_opengl +#ifdef EGL_ANGLE_platform_angle if (libEGL.eglGetPlatformDisplayEXT && (preferredType & QWindowsOpenGLTester::AngleBackendMask)) { const EGLint anglePlatformAttributes[][5] = { @@ -384,7 +390,7 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: } } } -#else // EGL_ANGLE_platform_angle_opengl +#else // EGL_ANGLE_platform_angle Q_UNUSED(preferredType) #endif if (display == EGL_NO_DISPLAY) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 2b249348c3..d8302c97a7 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -46,7 +46,6 @@ struct QWindowsLibEGL EGLint (EGLAPIENTRY * eglGetError)(void); EGLDisplay (EGLAPIENTRY * eglGetDisplay)(EGLNativeDisplayType display_id); - EGLDisplay (EGLAPIENTRY * eglGetPlatformDisplayEXT)(EGLenum platform, void *native_display, const EGLint *attrib_list); EGLBoolean (EGLAPIENTRY * eglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor); EGLBoolean (EGLAPIENTRY * eglTerminate)(EGLDisplay dpy); EGLBoolean (EGLAPIENTRY * eglChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, @@ -74,6 +73,8 @@ struct QWindowsLibEGL EGLBoolean (EGLAPIENTRY * eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface); __eglMustCastToProperFunctionPointerType (EGLAPIENTRY * eglGetProcAddress)(const char *procname); + EGLDisplay (EGLAPIENTRY * eglGetPlatformDisplayEXT)(EGLenum platform, void *native_display, const EGLint *attrib_list); + private: #if !defined(QT_STATIC) || defined(QT_OPENGL_DYNAMIC) void *resolve(const char *name); diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index 9691156403..6e58c55bbe 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -34,6 +34,7 @@ #include "qwindowsnativeinterface.h" #include "qwindowswindow.h" #include "qwindowscontext.h" +#include "qwindowsfontdatabase.h" #include "qwindowsopenglcontext.h" #include "qwindowsopengltester.h" #include "qwindowsintegration.h" @@ -222,6 +223,11 @@ int QWindowsNativeInterface::registerMimeType(const QString &mimeType) return QWindowsMime::registerMimeType(mimeType); } +QFont QWindowsNativeInterface::logFontToQFont(const void *logFont, int verticalDpi) +{ + return QWindowsFontDatabase::LOGFONT_to_QFont(*reinterpret_cast<const LOGFONT *>(logFont), verticalDpi); +} + QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &function) const { if (function == QWindowsWindowFunctions::setTouchWindowTouchTypeIdentifier()) diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h index be8418b769..97839ae1ae 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.h +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h @@ -34,6 +34,7 @@ #ifndef QWINDOWSNATIVEINTERFACE_H #define QWINDOWSNATIVEINTERFACE_H +#include <QtGui/qfont.h> #include <QtGui/qpa/qplatformnativeinterface.h> QT_BEGIN_NAMESPACE @@ -77,6 +78,7 @@ public: Q_INVOKABLE void registerWindowsMime(void *mimeIn); Q_INVOKABLE void unregisterWindowsMime(void *mime); Q_INVOKABLE int registerMimeType(const QString &mimeType); + Q_INVOKABLE QFont logFontToQFont(const void *logFont, int verticalDpi); bool asyncExpose() const; void setAsyncExpose(bool value); diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 923040fd71..543c08135f 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -438,6 +438,8 @@ QDebug operator<<(QDebug debug, const WindowCreationData &d) // Fix top level window flags in case only the type flags are passed. static inline void fixTopLevelWindowFlags(Qt::WindowFlags &flags) { + // Not supported on Windows, also do correction when it is set. + flags &= ~Qt::WindowFullscreenButtonHint; switch (flags) { case Qt::Window: flags |= Qt::WindowTitleHint | Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 92d064df9b..80c844e658 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -70,7 +70,6 @@ #endif #if defined(XCB_USE_XINPUT2) -#include <X11/extensions/XInput2.h> #include <X11/extensions/XI2proto.h> #endif @@ -457,6 +456,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra , m_focusWindow(0) , m_systemTrayTracker(0) , m_glIntegration(Q_NULLPTR) + , m_xiGrab(false) { #ifdef XCB_USE_XLIB Display *dpy = XOpenDisplay(m_displayName.constData()); @@ -909,7 +909,7 @@ static Qt::MouseButtons translateMouseButtons(int s) return ret; } -static Qt::MouseButton translateMouseButton(xcb_button_t s) +Qt::MouseButton QXcbConnection::translateMouseButton(xcb_button_t s) { switch (s) { case 1: return Qt::LeftButton; @@ -944,39 +944,6 @@ static Qt::MouseButton translateMouseButton(xcb_button_t s) } } -void QXcbConnection::handleButtonPress(xcb_generic_event_t *ev) -{ - xcb_button_press_event_t *event = (xcb_button_press_event_t *)ev; - - // the event explicitly contains the state of the three first buttons, - // the rest we need to manage ourselves - m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state); - m_buttons |= translateMouseButton(event->detail); - qCDebug(lcQpaXInput, "xcb: pressed mouse button %d, button state %X", event->detail, static_cast<unsigned int>(m_buttons)); -} - -void QXcbConnection::handleButtonRelease(xcb_generic_event_t *ev) -{ - xcb_button_release_event_t *event = (xcb_button_release_event_t *)ev; - - // the event explicitly contains the state of the three first buttons, - // the rest we need to manage ourselves - m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state); - m_buttons &= ~translateMouseButton(event->detail); - qCDebug(lcQpaXInput, "xcb: released mouse button %d, button state %X", event->detail, static_cast<unsigned int>(m_buttons)); -} - -void QXcbConnection::handleMotionNotify(xcb_generic_event_t *ev) -{ - xcb_motion_notify_event_t *event = (xcb_motion_notify_event_t *)ev; - - m_buttons = (m_buttons & ~0x7) | translateMouseButtons(event->state); -#ifdef Q_XCB_DEBUG - qCDebug(lcQpaXInput, "xcb: moved mouse to %4d, %4d; button state %X", - event->event_x, event->event_y, static_cast<unsigned int>(m_buttons)); -#endif -} - #ifndef QT_NO_XKB namespace { typedef union { @@ -1018,18 +985,35 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) switch (response_type) { case XCB_EXPOSE: HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent); - case XCB_BUTTON_PRESS: - m_keyboard->updateXKBStateFromCore(((xcb_button_press_event_t *)event)->state); - handleButtonPress(event); + + // press/release/motion is only delivered here when XI 2.2+ is _not_ in use + case XCB_BUTTON_PRESS: { + xcb_button_press_event_t *ev = (xcb_button_press_event_t *)event; + m_keyboard->updateXKBStateFromCore(ev->state); + // the event explicitly contains the state of the three first buttons, + // the rest we need to manage ourselves + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); + m_buttons |= translateMouseButton(ev->detail); + qCDebug(lcQpaXInput, "legacy mouse press, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttons)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent); - case XCB_BUTTON_RELEASE: - m_keyboard->updateXKBStateFromCore(((xcb_button_release_event_t *)event)->state); - handleButtonRelease(event); + } + case XCB_BUTTON_RELEASE: { + xcb_button_release_event_t *ev = (xcb_button_release_event_t *)event; + m_keyboard->updateXKBStateFromCore(ev->state); + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); + m_buttons &= ~translateMouseButton(ev->detail); + qCDebug(lcQpaXInput, "legacy mouse release, button %d state %X", ev->detail, static_cast<unsigned int>(m_buttons)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent); - case XCB_MOTION_NOTIFY: - m_keyboard->updateXKBStateFromCore(((xcb_motion_notify_event_t *)event)->state); - handleMotionNotify(event); + } + case XCB_MOTION_NOTIFY: { + xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)event; + m_keyboard->updateXKBStateFromCore(ev->state); + m_buttons = (m_buttons & ~0x7) | translateMouseButtons(ev->state); + qCDebug(lcQpaXInput, "legacy mouse move %d,%d button %d state %X", ev->event_x, ev->event_y, + ev->detail, static_cast<unsigned int>(m_buttons)); HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent); + } + case XCB_CONFIGURE_NOTIFY: HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent); case XCB_MAP_NOTIFY: @@ -1090,6 +1074,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) break; #if defined(XCB_USE_XINPUT2) case XCB_GE_GENERIC: + // Here the windowEventListener is invoked from xi2HandleEvent() if (m_xi2Enabled) xi2HandleEvent(reinterpret_cast<xcb_ge_event_t *>(event)); break; @@ -1931,6 +1916,12 @@ void QXcbConnection::initializeXKB() #endif } +bool QXcbConnection::xi2MouseEvents() const +{ + static bool mouseViaXI2 = !qEnvironmentVariableIsSet("QT_XCB_NO_XI2_MOUSE"); + return mouseViaXI2; +} + #if defined(XCB_USE_XINPUT2) static int xi2ValuatorOffset(unsigned char *maskPtr, int maskLen, int number) { diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index e4274eca4d..2005ae0701 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -69,7 +69,8 @@ #endif #endif struct XInput2TouchDeviceData; -#endif +#endif // XCB_USE_XINPUT2 + struct xcb_randr_get_output_info_reply_t; //#define Q_XCB_DEBUG @@ -347,6 +348,7 @@ public: virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {} virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {} virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {} + virtual void handleXIMouseEvent(xcb_ge_event_t *) {} virtual QXcbWindow *toWindow() { return 0; } }; @@ -413,14 +415,14 @@ public: void xi2Select(xcb_window_t window); #endif #ifdef XCB_USE_XINPUT21 - bool isUsingXInput21() const { return m_xi2Enabled && m_xi2Minor >= 1; } + bool isAtLeastXI21() const { return m_xi2Enabled && m_xi2Minor >= 1; } #else - bool isUsingXInput21() const { return false; } + bool isAtLeastXI21() const { return false; } #endif #ifdef XCB_USE_XINPUT22 - bool isUsingXInput22() const { return m_xi2Enabled && m_xi2Minor >= 2; } + bool isAtLeastXI22() const { return m_xi2Enabled && m_xi2Minor >= 2; } #else - bool isUsingXInput22() const { return false; } + bool isAtLeastXI22() const { return false; } #endif void sync(); @@ -457,7 +459,9 @@ public: xcb_timestamp_t getTimestamp(); + void setButton(Qt::MouseButton button, bool down) { if (down) m_buttons |= button; else m_buttons &= ~button; } Qt::MouseButtons buttons() const { return m_buttons; } + Qt::MouseButton translateMouseButton(xcb_button_t s); QXcbWindow *focusWindow() const { return m_focusWindow; } void setFocusWindow(QXcbWindow *); @@ -477,11 +481,19 @@ public: void handleEnterEvent(const xcb_enter_notify_event_t *); #endif +#ifdef XCB_USE_XINPUT22 + bool xi2SetMouseGrabEnabled(xcb_window_t w, bool grab); +#endif + Qt::MouseButton xiToQtMouseButton(uint32_t b); + QXcbEventReader *eventReader() const { return m_reader; } bool canGrab() const { return m_canGrabServer; } QXcbGlIntegration *glIntegration() const { return m_glIntegration; } + + bool xi2MouseEvents() const; + protected: bool event(QEvent *e) Q_DECL_OVERRIDE; @@ -509,9 +521,6 @@ private: bool checkOutputIsPrimary(xcb_window_t rootWindow, xcb_randr_output_t output); void initializeScreens(); void updateScreens(const xcb_randr_notify_event_t *event); - void handleButtonPress(xcb_generic_event_t *event); - void handleButtonRelease(xcb_generic_event_t *event); - void handleMotionNotify(xcb_generic_event_t *event); bool m_xi2Enabled; int m_xi2Minor; @@ -524,6 +533,9 @@ private: void xi2HandleHierachyEvent(void *event); void xi2HandleDeviceChangedEvent(void *event); int m_xiOpCode, m_xiEventBase, m_xiErrorBase; +#ifdef XCB_USE_XINPUT22 + void xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow); +#endif // XCB_USE_XINPUT22 #ifndef QT_NO_TABLETEVENT struct TabletData { TabletData() : deviceId(0), pointerType(QTabletEvent::UnknownPointer), @@ -543,10 +555,10 @@ private: }; QHash<int, ValuatorClassInfo> valuatorInfo; }; - bool xi2HandleTabletEvent(void *event, TabletData *tabletData); + bool xi2HandleTabletEvent(void *event, TabletData *tabletData, QXcbWindowEventListener *eventListener); void xi2ReportTabletEvent(TabletData &tabletData, void *event); QVector<TabletData> m_tabletData; -#endif +#endif // !QT_NO_TABLETEVENT struct ScrollingDevice { ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0), legacyOrientations(0) { } int deviceId; @@ -559,9 +571,7 @@ private: void updateScrollingDevice(ScrollingDevice& scrollingDevice, int num_classes, void *classes); void xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice); QHash<int, ScrollingDevice> m_scrollingDevices; -#endif // XCB_USE_XINPUT2 -#if defined(XCB_USE_XINPUT2) static bool xi2GetValuatorValueIfSet(void *event, int valuatorNum, double *value); static bool xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event, int opCode); #endif @@ -633,6 +643,7 @@ private: QByteArray m_startupId; QXcbSystemTrayTracker *m_systemTrayTracker; QXcbGlIntegration *m_glIntegration; + bool m_xiGrab; friend class QXcbEventReader; }; diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp index c43816fa05..0e8a162a7d 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp @@ -43,7 +43,6 @@ #include <X11/extensions/XInput2.h> #include <X11/extensions/XI2proto.h> -#define FINGER_MAX_WIDTH_MM 10 struct XInput2TouchDeviceData { XInput2TouchDeviceData() @@ -276,34 +275,37 @@ void QXcbConnection::xi2Select(xcb_window_t window) unsigned char *xiBitMask = reinterpret_cast<unsigned char *>(&bitMask); #ifdef XCB_USE_XINPUT22 - if (isUsingXInput22()) { + if (isAtLeastXI22()) { bitMask |= XI_TouchBeginMask; bitMask |= XI_TouchUpdateMask; bitMask |= XI_TouchEndMask; + bitMask |= XI_PropertyEventMask; // for tablets + if (xi2MouseEvents()) { + // We want both mouse and touch through XI2 if touch is supported (>= 2.2). + // The plain xcb press and motion events will not be delivered after this. + bitMask |= XI_ButtonPressMask; + bitMask |= XI_ButtonReleaseMask; + bitMask |= XI_MotionMask; + qCDebug(lcQpaXInput, "XInput 2.2: Selecting press/release/motion events in addition to touch"); + } XIEventMask mask; mask.mask_len = sizeof(bitMask); mask.mask = xiBitMask; - if (!m_touchDevices.isEmpty()) { - // If we select for touch events on the master pointer, XInput2 - // will not synthesize mouse events. This means Qt must do it, - // which is also preferable, since Qt can control better when - // to do so. - mask.deviceid = XIAllMasterDevices; - Status result = XISelectEvents(xDisplay, window, &mask, 1); - if (result != Success) - qCDebug(lcQpaXInput, "XInput 2.2: failed to select touch events, window %x, result %d", window, result); - } + // When xi2MouseEvents() is true (the default), pointer emulation for touch and tablet + // events will get disabled. This is preferable for touch, as Qt Quick handles touch events + // directly while for others QtGui synthesizes mouse events, not so much for tablets. For + // the latter we will synthesize the events ourselves. + mask.deviceid = XIAllMasterDevices; + Status result = XISelectEvents(xDisplay, window, &mask, 1); + if (result != Success) + qCDebug(lcQpaXInput, "XInput 2.2: failed to select pointer/touch events, window %x, result %d", window, result); } #endif // XCB_USE_XINPUT22 + const bool pointerSelected = isAtLeastXI22() && xi2MouseEvents(); QSet<int> tabletDevices; #ifndef QT_NO_TABLETEVENT - // For each tablet, select some additional event types. - // Press, motion, etc. events must never be selected for _all_ devices - // as that would render the standard XCB_MOTION_NOTIFY and - // similar handlers useless and we have no intention to infect - // all the pure xcb code with Xlib-based XI2. - if (!m_tabletData.isEmpty()) { + if (!m_tabletData.isEmpty() && !pointerSelected) { unsigned int tabletBitMask; unsigned char *xiTabletBitMask = reinterpret_cast<unsigned char *>(&tabletBitMask); QVector<XIEventMask> xiEventMask(m_tabletData.count()); @@ -324,7 +326,8 @@ void QXcbConnection::xi2Select(xcb_window_t window) #ifdef XCB_USE_XINPUT21 // Enable each scroll device - if (!m_scrollingDevices.isEmpty()) { + if (!m_scrollingDevices.isEmpty() && !pointerSelected) { + // Only when XI2 mouse events are not enabled, otherwise motion and release are selected already. QVector<XIEventMask> xiEventMask(m_scrollingDevices.size()); unsigned int scrollBitMask; unsigned char *xiScrollBitMask = reinterpret_cast<unsigned char *>(&scrollBitMask); @@ -426,7 +429,7 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) dev->size.width() > 10000 || dev->size.height() > 10000) dev->size = QSizeF(130, 110); } - if (!isUsingXInput22() || type == QTouchDevice::TouchPad) + if (!isAtLeastXI22() || type == QTouchDevice::TouchPad) caps |= QTouchDevice::MouseEmulation; if (type >= QTouchDevice::TouchScreen && type <= QTouchDevice::TouchPad) { @@ -448,7 +451,7 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id) } #if defined(XCB_USE_XINPUT21) || !defined(QT_NO_TABLETEVENT) -static qreal fixed1616ToReal(FP1616 val) +static inline qreal fixed1616ToReal(FP1616 val) { return qreal(val) / 0x10000; } @@ -469,163 +472,280 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) { if (xi2PrepareXIGenericDeviceEvent(event, m_xiOpCode)) { xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event); + int sourceDeviceId = xiEvent->deviceid; // may be the master id + xXIDeviceEvent *xiDeviceEvent = 0; + QXcbWindowEventListener *eventListener = 0; - if (xiEvent->evtype == XI_HierarchyChanged) { + switch (xiEvent->evtype) { + case XI_ButtonPress: + case XI_ButtonRelease: + case XI_Motion: + case XI_TouchBegin: + case XI_TouchUpdate: + case XI_TouchEnd: + { + xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event); + eventListener = windowEventListenerFromId(xiDeviceEvent->event); + if (eventListener) { + long result = 0; + if (eventListener->handleGenericEvent(reinterpret_cast<xcb_generic_event_t *>(event), &result)) + return; + } + sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master + break; + } + case XI_HierarchyChanged: xi2HandleHierachyEvent(xiEvent); return; - } - if (xiEvent->evtype == XI_DeviceChanged) { + case XI_DeviceChanged: xi2HandleDeviceChangedEvent(xiEvent); return; + default: + break; } #ifndef QT_NO_TABLETEVENT for (int i = 0; i < m_tabletData.count(); ++i) { - if (m_tabletData.at(i).deviceId == xiEvent->deviceid) { - if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i])) + if (m_tabletData.at(i).deviceId == sourceDeviceId) { + if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener)) return; } } #endif // QT_NO_TABLETEVENT #ifdef XCB_USE_XINPUT21 - QHash<int, ScrollingDevice>::iterator device = m_scrollingDevices.find(xiEvent->deviceid); + QHash<int, ScrollingDevice>::iterator device = m_scrollingDevices.find(sourceDeviceId); if (device != m_scrollingDevices.end()) xi2HandleScrollEvent(xiEvent, device.value()); #endif // XCB_USE_XINPUT21 #ifdef XCB_USE_XINPUT22 - if (xiEvent->evtype == XI_TouchBegin || xiEvent->evtype == XI_TouchUpdate || xiEvent->evtype == XI_TouchEnd) { - xXIDeviceEvent* xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event); - if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qCDebug(lcQpaXInput, "XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f", - event->event_type, xiEvent->sequenceNumber, xiDeviceEvent->detail, - fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y), - fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y) ); - - if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) { - XInput2TouchDeviceData *dev = touchDeviceForId(xiDeviceEvent->sourceid); - Q_ASSERT(dev); - const bool firstTouch = m_touchPoints.isEmpty(); - if (xiEvent->evtype == XI_TouchBegin) { - QWindowSystemInterface::TouchPoint tp; - tp.id = xiDeviceEvent->detail % INT_MAX; - tp.state = Qt::TouchPointPressed; - tp.pressure = -1.0; - m_touchPoints[tp.id] = tp; - } - QWindowSystemInterface::TouchPoint &touchPoint = m_touchPoints[xiDeviceEvent->detail]; - qreal x = fixed1616ToReal(xiDeviceEvent->root_x); - qreal y = fixed1616ToReal(xiDeviceEvent->root_y); - qreal nx = -1.0, ny = -1.0, w = 0.0, h = 0.0; - QXcbScreen* screen = m_screens.at(0); - for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) { - XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i]; - if (classinfo->type == XIValuatorClass) { - XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(classinfo); - int n = vci->number; - double value; - if (!xi2GetValuatorValueIfSet(xiDeviceEvent, n, &value)) - continue; - if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qCDebug(lcQpaXInput, " valuator %20s value %lf from range %lf -> %lf", - atomName(vci->label).constData(), value, vci->min, vci->max ); - if (vci->label == atom(QXcbAtom::RelX)) { - nx = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::RelY)) { - ny = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsX)) { - nx = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsY)) { - ny = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsMTPositionX)) { - nx = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsMTPositionY)) { - ny = valuatorNormalized(value, vci); - } else if (vci->label == atom(QXcbAtom::AbsMTTouchMajor)) { - // Convert the value within its range as a fraction of a finger's max (contact patch) - // width in mm, and from there to pixels depending on screen resolution - w = valuatorNormalized(value, vci) * FINGER_MAX_WIDTH_MM * - screen->geometry().width() / screen->physicalSize().width(); - } else if (vci->label == atom(QXcbAtom::AbsMTTouchMinor)) { - h = valuatorNormalized(value, vci) * FINGER_MAX_WIDTH_MM * - screen->geometry().height() / screen->physicalSize().height(); - } else if (vci->label == atom(QXcbAtom::AbsMTPressure) || - vci->label == atom(QXcbAtom::AbsPressure)) { - touchPoint.pressure = valuatorNormalized(value, vci); - } - } - } - // If any value was not updated, use the last-known value. - if (nx == -1.0) { - x = touchPoint.area.center().x(); - nx = x / screen->geometry().width(); - } - if (ny == -1.0) { - y = touchPoint.area.center().y(); - ny = y / screen->geometry().height(); - } - if (xiEvent->evtype != XI_TouchEnd) { - if (w == 0.0) - w = touchPoint.area.width(); - if (h == 0.0) - h = touchPoint.area.height(); - } - - switch (xiEvent->evtype) { - case XI_TouchBegin: - if (firstTouch) { - dev->firstPressedPosition = QPointF(x, y); - dev->firstPressedNormalPosition = QPointF(nx, ny); - } - dev->pointPressedPosition.insert(touchPoint.id, QPointF(x, y)); - break; - case XI_TouchUpdate: - if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) { - qreal dx = (nx - dev->firstPressedNormalPosition.x()) * - dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); - qreal dy = (ny - dev->firstPressedNormalPosition.y()) * - dev->size.height() * screen->geometry().height() / screen->physicalSize().height(); - x = dev->firstPressedPosition.x() + dx; - y = dev->firstPressedPosition.y() + dy; - touchPoint.state = Qt::TouchPointMoved; - } else if (touchPoint.area.center() != QPoint(x, y)) { - touchPoint.state = Qt::TouchPointMoved; - dev->pointPressedPosition[touchPoint.id] = QPointF(x, y); - } - break; - case XI_TouchEnd: - touchPoint.state = Qt::TouchPointReleased; - if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) { - qreal dx = (nx - dev->firstPressedNormalPosition.x()) * - dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); - qreal dy = (ny - dev->firstPressedNormalPosition.y()) * - dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); - x = dev->firstPressedPosition.x() + dx; - y = dev->firstPressedPosition.y() + dy; - } - dev->pointPressedPosition.remove(touchPoint.id); - } - touchPoint.area = QRectF(x - w/2, y - h/2, w, h); - touchPoint.normalPosition = QPointF(nx, ny); + if (xiDeviceEvent) { + switch (xiDeviceEvent->evtype) { + case XI_ButtonPress: + case XI_ButtonRelease: + case XI_Motion: + if (xi2MouseEvents() && eventListener) + eventListener->handleXIMouseEvent(event); + break; + case XI_TouchBegin: + case XI_TouchUpdate: + case XI_TouchEnd: if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) - qCDebug(lcQpaXInput) << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition << - " area " << touchPoint.area << " pressure " << touchPoint.pressure; - QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiEvent->time, dev->qtTouchDevice, m_touchPoints.values()); - if (touchPoint.state == Qt::TouchPointReleased) - // If a touchpoint was released, we can forget it, because the ID won't be reused. - m_touchPoints.remove(touchPoint.id); - else - // Make sure that we don't send TouchPointPressed/Moved in more than one QTouchEvent - // with this touch point if the next XI2 event is about a different touch point. - touchPoint.state = Qt::TouchPointStationary; + qCDebug(lcQpaXInput, "XI2 touch event type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f on window %x", + event->event_type, xiDeviceEvent->sequenceNumber, xiDeviceEvent->detail, + fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y), + fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y),xiDeviceEvent->event); + if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) + xi2ProcessTouch(xiDeviceEvent, platformWindow); + break; } } #endif // XCB_USE_XINPUT22 } } +#ifdef XCB_USE_XINPUT22 +void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindow) +{ + xXIDeviceEvent *xiDeviceEvent = static_cast<xXIDeviceEvent *>(xiDevEvent); + XInput2TouchDeviceData *dev = touchDeviceForId(xiDeviceEvent->sourceid); + Q_ASSERT(dev); + const bool firstTouch = m_touchPoints.isEmpty(); + if (xiDeviceEvent->evtype == XI_TouchBegin) { + QWindowSystemInterface::TouchPoint tp; + tp.id = xiDeviceEvent->detail % INT_MAX; + tp.state = Qt::TouchPointPressed; + tp.pressure = -1.0; + m_touchPoints[tp.id] = tp; + } + QWindowSystemInterface::TouchPoint &touchPoint = m_touchPoints[xiDeviceEvent->detail]; + qreal x = fixed1616ToReal(xiDeviceEvent->root_x); + qreal y = fixed1616ToReal(xiDeviceEvent->root_y); + qreal nx = -1.0, ny = -1.0, d = 0.0; + QXcbScreen* screen = m_screens.at(0); + for (int i = 0; i < dev->xiDeviceInfo->num_classes; ++i) { + XIAnyClassInfo *classinfo = dev->xiDeviceInfo->classes[i]; + if (classinfo->type == XIValuatorClass) { + XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(classinfo); + int n = vci->number; + double value; + if (!xi2GetValuatorValueIfSet(xiDeviceEvent, n, &value)) + continue; + if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) + qCDebug(lcQpaXInput, " valuator %20s value %lf from range %lf -> %lf", + atomName(vci->label).constData(), value, vci->min, vci->max ); + if (vci->label == atom(QXcbAtom::RelX)) { + nx = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::RelY)) { + ny = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsX)) { + nx = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsY)) { + ny = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsMTPositionX)) { + nx = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsMTPositionY)) { + ny = valuatorNormalized(value, vci); + } else if (vci->label == atom(QXcbAtom::AbsMTTouchMajor)) { + d = valuatorNormalized(value, vci) * screen->geometry().width(); + } else if (vci->label == atom(QXcbAtom::AbsMTPressure) || + vci->label == atom(QXcbAtom::AbsPressure)) { + touchPoint.pressure = valuatorNormalized(value, vci); + } + } + } + // If any value was not updated, use the last-known value. + if (nx == -1.0) { + x = touchPoint.area.center().x(); + nx = x / screen->geometry().width(); + } + if (ny == -1.0) { + y = touchPoint.area.center().y(); + ny = y / screen->geometry().height(); + } + if (xiDeviceEvent->evtype != XI_TouchEnd) { + if (d == 0.0) + d = touchPoint.area.width(); + } + + switch (xiDeviceEvent->evtype) { + case XI_TouchBegin: + if (firstTouch) { + dev->firstPressedPosition = QPointF(x, y); + dev->firstPressedNormalPosition = QPointF(nx, ny); + } + dev->pointPressedPosition.insert(touchPoint.id, QPointF(x, y)); + + // Touches must be accepted when we are grabbing touch events. Otherwise the entire sequence + // will get replayed when the grab ends. + if (m_xiGrab) { + // XIAllowTouchEvents deadlocks with libXi < 1.7.4 (this has nothing to do with the XI2 versions like 2.2) + // http://lists.x.org/archives/xorg-devel/2014-July/043059.html +#ifndef LIBXI_MAJOR + static bool allowTouchWarningShown = false; + if (!allowTouchWarningShown) { + allowTouchWarningShown = true; + qWarning("Skipping XIAllowTouchEvents() because it was not possible to detect libXi version at build time." + " Minimum libXi version required is 1.7.4." + " Expect issues with touch behavior."); + } +#elif LIBXI_MAJOR == 1 && (LIBXI_MINOR < 7 || (LIBXI_MINOR == 7 && LIBXI_PATCH < 4)) + static bool allowTouchWarningShown = false; + if (!allowTouchWarningShown) { + allowTouchWarningShown = true; + qWarning("Skipping XIAllowTouchEvents() due to not having libXi >= 1.7.4." + " libXi version at build time was %d.%d.%d." + " Expect issues with touch behavior.", LIBXI_MAJOR, LIBXI_MINOR, LIBXI_PATCH); + } +#else + XIAllowTouchEvents(static_cast<Display *>(m_xlib_display), xiDeviceEvent->deviceid, + xiDeviceEvent->detail, xiDeviceEvent->event, XIAcceptTouch); +#endif + } + break; + case XI_TouchUpdate: + if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) { + qreal dx = (nx - dev->firstPressedNormalPosition.x()) * + dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); + qreal dy = (ny - dev->firstPressedNormalPosition.y()) * + dev->size.height() * screen->geometry().height() / screen->physicalSize().height(); + x = dev->firstPressedPosition.x() + dx; + y = dev->firstPressedPosition.y() + dy; + touchPoint.state = Qt::TouchPointMoved; + } else if (touchPoint.area.center() != QPoint(x, y)) { + touchPoint.state = Qt::TouchPointMoved; + dev->pointPressedPosition[touchPoint.id] = QPointF(x, y); + } + break; + case XI_TouchEnd: + touchPoint.state = Qt::TouchPointReleased; + if (dev->qtTouchDevice->type() == QTouchDevice::TouchPad && dev->pointPressedPosition.value(touchPoint.id) == QPointF(x, y)) { + qreal dx = (nx - dev->firstPressedNormalPosition.x()) * + dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); + qreal dy = (ny - dev->firstPressedNormalPosition.y()) * + dev->size.width() * screen->geometry().width() / screen->physicalSize().width(); + x = dev->firstPressedPosition.x() + dx; + y = dev->firstPressedPosition.y() + dy; + } + dev->pointPressedPosition.remove(touchPoint.id); + } + touchPoint.area = QRectF(x - d/2, y - d/2, d, d); + touchPoint.normalPosition = QPointF(nx, ny); + + if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) + qCDebug(lcQpaXInput) << " touchpoint " << touchPoint.id << " state " << touchPoint.state << " pos norm " << touchPoint.normalPosition << + " area " << touchPoint.area << " pressure " << touchPoint.pressure; + QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xiDeviceEvent->time, dev->qtTouchDevice, m_touchPoints.values()); + if (touchPoint.state == Qt::TouchPointReleased) + // If a touchpoint was released, we can forget it, because the ID won't be reused. + m_touchPoints.remove(touchPoint.id); + else + // Make sure that we don't send TouchPointPressed/Moved in more than one QTouchEvent + // with this touch point if the next XI2 event is about a different touch point. + touchPoint.state = Qt::TouchPointStationary; +} + +bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab) +{ + if (grab && !canGrab()) + return false; + + int num_devices = 0; + Display *xDisplay = static_cast<Display *>(xlib_display()); + XIDeviceInfo *info = XIQueryDevice(xDisplay, XIAllMasterDevices, &num_devices); + if (!info) + return false; + + XIEventMask evmask; + unsigned char mask[XIMaskLen(XI_LASTEVENT)]; + evmask.mask = mask; + evmask.mask_len = sizeof(mask); + memset(mask, 0, sizeof(mask)); + evmask.deviceid = XIAllMasterDevices; + + XISetMask(mask, XI_ButtonPress); + XISetMask(mask, XI_ButtonRelease); + XISetMask(mask, XI_Motion); + XISetMask(mask, XI_TouchBegin); + XISetMask(mask, XI_TouchUpdate); + XISetMask(mask, XI_TouchEnd); + + bool grabbed = true; + for (int i = 0; i < num_devices; i++) { + int id = info[i].deviceid, n = 0; + XIDeviceInfo *deviceInfo = XIQueryDevice(xDisplay, id, &n); + if (deviceInfo) { + const bool grabbable = deviceInfo->use != XIMasterKeyboard; + XIFreeDeviceInfo(deviceInfo); + if (!grabbable) + continue; + } + if (!grab) { + Status result = XIUngrabDevice(xDisplay, id, CurrentTime); + if (result != Success) { + grabbed = false; + qCDebug(lcQpaXInput, "XInput 2.2: failed to ungrab events for device %d (result %d)", id, result); + } + } else { + Status result = XIGrabDevice(xDisplay, id, w, CurrentTime, None, XIGrabModeAsync, + XIGrabModeAsync, False, &evmask); + if (result != Success) { + grabbed = false; + qCDebug(lcQpaXInput, "XInput 2.2: failed to grab events for device %d on window %x (result %d)", id, w, result); + } + } + } + + XIFreeDeviceInfo(info); + + m_xiGrab = grabbed; + + return grabbed; +} +#endif // XCB_USE_XINPUT22 + void QXcbConnection::xi2HandleHierachyEvent(void *event) { xXIHierarchyEvent *xiEvent = reinterpret_cast<xXIHierarchyEvent *>(event); @@ -794,7 +914,8 @@ void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollin #endif // XCB_USE_XINPUT21 } -static Qt::MouseButton xiToQtMouseButton(uint32_t b) { +Qt::MouseButton QXcbConnection::xiToQtMouseButton(uint32_t b) +{ switch (b) { case 1: return Qt::LeftButton; case 2: return Qt::MiddleButton; @@ -841,20 +962,29 @@ static QTabletEvent::TabletDevice toolIdToTabletDevice(quint32 toolId) { } #ifndef QT_NO_TABLETEVENT -bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData) +bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, QXcbWindowEventListener *eventListener) { bool handled = true; Display *xDisplay = static_cast<Display *>(m_xlib_display); xXIGenericDeviceEvent *xiEvent = static_cast<xXIGenericDeviceEvent *>(event); + xXIDeviceEvent *xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(xiEvent); + +#ifdef XCB_USE_XINPUT22 + // Synthesize mouse events since otherwise there are no mouse events from + // the pen on the XI 2.2+ path. + if (xi2MouseEvents() && eventListener) + eventListener->handleXIMouseEvent(reinterpret_cast<xcb_ge_event_t *>(event)); +#endif + switch (xiEvent->evtype) { case XI_ButtonPress: { - Qt::MouseButton b = xiToQtMouseButton(reinterpret_cast<xXIDeviceEvent *>(event)->detail); + Qt::MouseButton b = xiToQtMouseButton(xiDeviceEvent->detail); tabletData->buttons |= b; xi2ReportTabletEvent(*tabletData, xiEvent); break; } case XI_ButtonRelease: { - Qt::MouseButton b = xiToQtMouseButton(reinterpret_cast<xXIDeviceEvent *>(event)->detail); + Qt::MouseButton b = xiToQtMouseButton(xiDeviceEvent->detail); tabletData->buttons ^= b; xi2ReportTabletEvent(*tabletData, xiEvent); break; @@ -917,7 +1047,7 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData) // TODO maybe have a hash of tabletData->deviceId to device data so we can // look up the tablet name here, and distinguish multiple tablets qCDebug(lcQpaXInput, "XI2 proximity change on tablet %d (USB %x): last tool: %x id %x current tool: %x id %x TabletDevice %d", - ev->deviceid, ptr[_WACSER_USB_ID], ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID], + tabletData->deviceId, ptr[_WACSER_USB_ID], ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID], ptr[_WACSER_TOOL_SERIAL], ptr[_WACSER_TOOL_ID], tabletData->tool); } XFree(data); @@ -981,7 +1111,7 @@ void QXcbConnection::xi2ReportTabletEvent(TabletData &tabletData, void *event) if (Q_UNLIKELY(lcQpaXInput().isDebugEnabled())) qCDebug(lcQpaXInput, "XI2 event on tablet %d with tool %d type %d seq %d detail %d pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf", - ev->deviceid, tabletData.tool, ev->evtype, ev->sequenceNumber, ev->detail, + tabletData.deviceId, tabletData.tool, ev->evtype, ev->sequenceNumber, ev->detail, fixed1616ToReal(ev->event_x), fixed1616ToReal(ev->event_y), fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y), (int)tabletData.buttons, pressure, xTilt, yTilt, rotation); diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 6a9ef5869e..2d96ed1c21 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -47,6 +47,12 @@ #include <stdio.h> #include <X11/keysym.h> +#ifdef XCB_USE_XINPUT22 +#include <X11/extensions/XI2proto.h> +#undef KeyPress +#undef KeyRelease +#endif + #ifndef XK_ISO_Left_Tab #define XK_ISO_Left_Tab 0xFE20 #endif @@ -791,6 +797,31 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state) } } +void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo) +{ +#ifdef XCB_USE_XINPUT22 + if (m_config && !connection()->hasXKB()) { + xXIModifierInfo *mods = static_cast<xXIModifierInfo *>(modInfo); + xXIGroupInfo *group = static_cast<xXIGroupInfo *>(groupInfo); + const xkb_state_component newState = xkb_state_update_mask(xkb_state, + mods->base_mods, + mods->latched_mods, + mods->locked_mods, + group->base_group, + group->latched_group, + group->locked_group); + + if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) { + //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); + } + } +#else + Q_UNUSED(modInfo); + Q_UNUSED(groupInfo); + Q_ASSERT(false); // this can't be +#endif +} + quint32 QXcbKeyboard::xkbModMask(quint16 state) { quint32 xkb_mask = 0; diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h index 2281674e2f..d2e37d624c 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.h +++ b/src/plugins/platforms/xcb/qxcbkeyboard.h @@ -68,6 +68,7 @@ public: void updateXKBMods(); quint32 xkbModMask(quint16 state); void updateXKBStateFromCore(quint16 state); + void updateXKBStateFromXI(void *modInfo, void *groupInfo); #ifndef QT_NO_XKB // when XKEYBOARD is present on the X server int coreDeviceId() const { return core_device_id; } diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 3188a7f19d..d1b688857d 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -96,6 +96,7 @@ #if defined(XCB_USE_XINPUT2) #include <X11/extensions/XInput2.h> +#include <X11/extensions/XI2proto.h> #endif #define XCOORD_MAX 16383 @@ -2106,16 +2107,17 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) } } -void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) +void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y, + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) { - const bool isWheel = event->detail >= 4 && event->detail <= 7; + const bool isWheel = detail >= 4 && detail <= 7; if (!isWheel && window() != QGuiApplication::focusWindow()) { QWindow *w = static_cast<QWindowPrivate *>(QObjectPrivate::get(window()))->eventReceiver(); if (!(w->flags() & Qt::WindowDoesNotAcceptFocus)) w->requestActivate(); } - updateNetWmUserTime(event->time); + updateNetWmUserTime(timestamp); if (m_embedded) { if (window() != QGuiApplication::focusWindow()) { @@ -2126,53 +2128,125 @@ void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) } } const int dpr = int(devicePixelRatio()); - QPoint local(event->event_x/dpr, event->event_y/dpr); - QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); - - Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + QPoint local(event_x / dpr, event_y / dpr); + QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y)); if (isWheel) { - if (!connection()->isUsingXInput21()) { + if (!connection()->isAtLeastXI21()) { // Logic borrowed from qapplication_x11.cpp - int delta = 120 * ((event->detail == 4 || event->detail == 6) ? 1 : -1); - bool hor = (((event->detail == 4 || event->detail == 5) + int delta = 120 * ((detail == 4 || detail == 6) ? 1 : -1); + bool hor = (((detail == 4 || detail == 5) && (modifiers & Qt::AltModifier)) - || (event->detail == 6 || event->detail == 7)); + || (detail == 6 || detail == 7)); - QWindowSystemInterface::handleWheelEvent(window(), event->time, + QWindowSystemInterface::handleWheelEvent(window(), timestamp, local, global, delta, hor ? Qt::Horizontal : Qt::Vertical, modifiers); } return; } - handleMouseEvent(event->time, local, global, modifiers); + handleMouseEvent(timestamp, local, global, modifiers); } -void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event) +void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y, + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) { const int dpr = int(devicePixelRatio()); - QPoint local(event->event_x/dpr, event->event_y/dpr); - QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); - Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + QPoint local(event_x / dpr, event_y / dpr); + QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y)); - if (event->detail >= 4 && event->detail <= 7) { + if (detail >= 4 && detail <= 7) { // mouse wheel, handled in handleButtonPressEvent() return; } - handleMouseEvent(event->time, local, global, modifiers); + handleMouseEvent(timestamp, local, global, modifiers); } -void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) +void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, + Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) { - const int dpr = int(devicePixelRatio()); - QPoint local(event->event_x/dpr, event->event_y/dpr); if (!xcbScreen()) return; - QPoint global = xcbScreen()->mapFromNative(QPoint(event->root_x, event->root_y)); + const int dpr = int(devicePixelRatio()); + QPoint local(event_x / dpr, event_y / dpr); + QPoint global = xcbScreen()->mapFromNative(QPoint(root_x, root_y)); + handleMouseEvent(timestamp, local, global, modifiers); +} + +// Handlers for plain xcb events. Used only when XI 2.2 or newer is not available. +void QXcbWindow::handleButtonPressEvent(const xcb_button_press_event_t *event) +{ Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + handleButtonPressEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->detail, + modifiers, event->time); +} - handleMouseEvent(event->time, local, global, modifiers); +void QXcbWindow::handleButtonReleaseEvent(const xcb_button_release_event_t *event) +{ + Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + handleButtonReleaseEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->detail, + modifiers, event->time); +} + +void QXcbWindow::handleMotionNotifyEvent(const xcb_motion_notify_event_t *event) +{ + Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state); + handleMotionNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, modifiers, event->time); +} + +#ifdef XCB_USE_XINPUT22 +static inline int fixed1616ToInt(FP1616 val) +{ + return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF); +} +#endif + +// With XI 2.2+ press/release/motion comes here instead of the above handlers. +void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event) +{ +#ifdef XCB_USE_XINPUT22 + QXcbConnection *conn = connection(); + xXIDeviceEvent *ev = reinterpret_cast<xXIDeviceEvent *>(event); + const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective_mods); + const int event_x = fixed1616ToInt(ev->event_x); + const int event_y = fixed1616ToInt(ev->event_y); + const int root_x = fixed1616ToInt(ev->root_x); + const int root_y = fixed1616ToInt(ev->root_y); + + conn->keyboard()->updateXKBStateFromXI(&ev->mods, &ev->group); + + const Qt::MouseButton button = conn->xiToQtMouseButton(ev->detail); + + if (ev->buttons_len > 0) { + unsigned char *buttonMask = (unsigned char *) &ev[1]; + for (int i = 1; i <= 15; ++i) + conn->setButton(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i)); + } + + switch (ev->evtype) { + case XI_ButtonPress: + qCDebug(lcQpaXInput, "XI2 mouse press, button %d", button); + conn->setButton(button, true); + handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time); + break; + case XI_ButtonRelease: + qCDebug(lcQpaXInput, "XI2 mouse release, button %d", button); + conn->setButton(button, false); + handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time); + break; + case XI_Motion: + qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d", event_x, event_y); + handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time); + break; + default: + qWarning() << "Unrecognized XI2 mouse event" << ev->evtype; + break; + } +#else + Q_UNUSED(event); + Q_ASSERT(false); // this can't be +#endif } QXcbWindow *QXcbWindow::toWindow() { return this; } @@ -2356,6 +2430,10 @@ bool QXcbWindow::setKeyboardGrabEnabled(bool grab) bool QXcbWindow::setMouseGrabEnabled(bool grab) { +#ifdef XCB_USE_XINPUT22 + if (connection()->xi2MouseEvents()) + return connection()->xi2SetMouseGrabEnabled(m_window, grab); +#endif if (grab && !connection()->canGrab()) return false; diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 512bc54255..e62bfcba64 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -131,6 +131,7 @@ public: void handleFocusInEvent(const xcb_focus_in_event_t *event) Q_DECL_OVERRIDE; void handleFocusOutEvent(const xcb_focus_out_event_t *event) Q_DECL_OVERRIDE; void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) Q_DECL_OVERRIDE; + void handleXIMouseEvent(xcb_ge_event_t *) Q_DECL_OVERRIDE; QXcbWindow *toWindow() Q_DECL_OVERRIDE; @@ -199,6 +200,15 @@ protected: void doFocusIn(); void doFocusOut(); + void handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y, + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + + void handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y, + int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + + void handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, + Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + xcb_window_t m_window; QXcbScreen *m_xcbScreen; diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro index fd704dd904..12987567ff 100644 --- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro +++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro @@ -59,6 +59,11 @@ contains(QT_CONFIG, xcb-xlib) { DEFINES += XCB_USE_XINPUT2 SOURCES += qxcbconnection_xi2.cpp LIBS += -lXi + !isEmpty(QMAKE_LIBXI_VERSION_MAJOR) { + DEFINES += LIBXI_MAJOR=$$QMAKE_LIBXI_VERSION_MAJOR \ + LIBXI_MINOR=$$QMAKE_LIBXI_VERSION_MINOR \ + LIBXI_PATCH=$$QMAKE_LIBXI_VERSION_PATCH + } } } diff --git a/src/tools/moc/preprocessor.cpp b/src/tools/moc/preprocessor.cpp index 51873033c7..f253c49995 100644 --- a/src/tools/moc/preprocessor.cpp +++ b/src/tools/moc/preprocessor.cpp @@ -661,8 +661,10 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym expansion += s; } } else if (mode == Hash) { - if (index < 0) + if (index < 0 || index >= arguments.size()) { that->error("'#' is not followed by a macro parameter"); + continue; + } const Symbols &arg = arguments.at(index); QByteArray stringified; @@ -681,7 +683,7 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym expansion.pop_back(); Symbol next = s; - if (index >= 0) { + if (index >= 0 && index < arguments.size()) { const Symbols &arg = arguments.at(index); if (arg.size() == 0) { mode = Normal; @@ -703,7 +705,7 @@ Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &sym expansion += next; } - if (index >= 0) { + if (index >= 0 && index < arguments.size()) { const Symbols &arg = arguments.at(index); for (int i = 1; i < arg.size(); ++i) expansion += arg.at(i); diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp index 701fea1c03..a4b37f360b 100644 --- a/src/widgets/dialogs/qwizard_win.cpp +++ b/src/widgets/dialogs/qwizard_win.cpp @@ -361,6 +361,36 @@ bool QVistaHelper::setDWMTitleBar(TitleBarChangeType type) Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &); +static LOGFONT getCaptionLogFont(HANDLE hTheme) +{ + LOGFONT result = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 } }; + + if (!hTheme || FAILED(pGetThemeSysFont(hTheme, WIZ_TMT_CAPTIONFONT, &result))) { + NONCLIENTMETRICS ncm; + ncm.cbSize = sizeof(NONCLIENTMETRICS); + SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, false); + result = ncm.lfMessageFont; + } + return result; +} + +static bool getCaptionQFont(int dpi, QFont *result) +{ + if (!pOpenThemeData) + return false; + const HANDLE hTheme = + pOpenThemeData(QApplicationPrivate::getHWNDForWidget(QApplication::desktop()), L"WINDOW"); + if (!hTheme) + return false; + // Call into QWindowsNativeInterface to convert the LOGFONT into a QFont. + const LOGFONT logFont = getCaptionLogFont(hTheme); + QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface(); + return ni && QMetaObject::invokeMethod(ni, "logFontToQFont", Qt::DirectConnection, + Q_RETURN_ARG(QFont, *result), + Q_ARG(const void *, &logFont), + Q_ARG(int, dpi)); +} + void QVistaHelper::drawTitleBar(QPainter *painter) { Q_ASSERT(backButton_); @@ -378,7 +408,9 @@ void QVistaHelper::drawTitleBar(QPainter *painter) const int verticalCenter = (btnTop + btnHeight / 2) - 1; const QString text = wizard->window()->windowTitle(); - const QFont font = QApplication::font("QMdiSubWindowTitleBar"); + QFont font; + if (!isWindow || !getCaptionQFont(wizard->logicalDpiY() * wizard->devicePixelRatio(), &font)) + font = QApplication::font("QMdiSubWindowTitleBar"); const QFontMetrics fontMetrics(font); const QRect brect = fontMetrics.boundingRect(text); int textHeight = brect.height(); @@ -649,19 +681,6 @@ bool QVistaHelper::eventFilter(QObject *obj, QEvent *event) return false; } -HFONT QVistaHelper::getCaptionFont(HANDLE hTheme) -{ - LOGFONT lf = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 } }; - - if (!hTheme || FAILED(pGetThemeSysFont(hTheme, WIZ_TMT_CAPTIONFONT, &lf))) { - NONCLIENTMETRICS ncm; - ncm.cbSize = sizeof(NONCLIENTMETRICS); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, false); - lf = ncm.lfMessageFont; - } - return CreateFontIndirect(&lf); -} - // Return a HDC for the wizard along with the transformation if the // wizard is a child window. HDC QVistaHelper::backingStoreDC(const QWidget *wizard, QPoint *offset) @@ -713,7 +732,8 @@ bool QVistaHelper::drawTitleText(QPainter *painter, const QString &text, const Q bmp = CreateDIBSection(hdc, &dib, DIB_RGB_COLORS, NULL, NULL, 0); // Set up the DC - HFONT hCaptionFont = getCaptionFont(hTheme); + const LOGFONT captionLogFont = getCaptionLogFont(hTheme); + const HFONT hCaptionFont = CreateFontIndirect(&captionLogFont); HBITMAP hOldBmp = (HBITMAP)SelectObject(dcMem, (HGDIOBJ) bmp); HFONT hOldFont = (HFONT)SelectObject(dcMem, (HGDIOBJ) hCaptionFont); diff --git a/src/widgets/dialogs/qwizard_win_p.h b/src/widgets/dialogs/qwizard_win_p.h index 8c36472bee..84b795d506 100644 --- a/src/widgets/dialogs/qwizard_win_p.h +++ b/src/widgets/dialogs/qwizard_win_p.h @@ -105,7 +105,6 @@ public: static HDC backingStoreDC(const QWidget *wizard, QPoint *offset); private: - static HFONT getCaptionFont(HANDLE hTheme); HWND wizardHWND() const; bool drawTitleText(QPainter *painter, const QString &text, const QRect &rect, HDC hdc); static bool drawBlackRect(const QRect &rect, HDC hdc); diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp index 66ff472724..bca315f80b 100644 --- a/src/widgets/itemviews/qheaderview.cpp +++ b/src/widgets/itemviews/qheaderview.cpp @@ -1879,13 +1879,13 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent, // insert sections into hiddenSectionSize QHash<int, int> newHiddenSectionSize; // from logical index to section size - for (int i = 0; i < logicalFirst; ++i) - if (isSectionHidden(i)) - newHiddenSectionSize[i] = d->hiddenSectionSize[i]; - for (int j = logicalLast + 1; j < d->sectionCount(); ++j) - if (isSectionHidden(j)) - newHiddenSectionSize[j] = d->hiddenSectionSize[j - insertCount]; - d->hiddenSectionSize = newHiddenSectionSize; + for (QHash<int, int>::const_iterator it = d->hiddenSectionSize.cbegin(), + end = d->hiddenSectionSize.cend(); it != end; ++it) { + const int oldIndex = it.key(); + const int newIndex = (oldIndex < logicalFirst) ? oldIndex : oldIndex + insertCount; + newHiddenSectionSize[newIndex] = it.value(); + } + d->hiddenSectionSize.swap(newHiddenSectionSize); d->doDelayedResizeSections(); emit sectionCountChanged(oldCount, count()); diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 43db43fcd4..9b3e270fdd 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -3658,6 +3658,7 @@ void QTreeViewPrivate::updateScrollBars() if (!viewportSize.isValid()) viewportSize = QSize(0, 0); + executePostedLayout(); if (viewItems.isEmpty()) { q->doItemsLayout(); } diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index b8df25b38f..9bfdc62e60 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -104,6 +104,12 @@ QT_BEGIN_NAMESPACE non-sharable. To overcome this issue, prefer using QSurfaceFormat::setDefaultFormat() instead of setFormat(). + \note Calling QSurfaceFormat::setDefaultFormat() before constructing + the QApplication instance is mandatory on some platforms (for example, + OS X) when an OpenGL core profile context is requested. This is to + ensure that resource sharing between contexts stays functional as all + internal contexts are created using the correct version and profile. + \section1 Painting Techniques As described above, subclass QOpenGLWidget to render pure 3D content in the diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 485cf82078..d1070839fa 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -962,7 +962,8 @@ static void findTextureWidgetsRecursively(QWidget *tlw, QWidget *widget, QPlatfo QPlatformTextureList::Flags flags = 0; if (widget->testAttribute(Qt::WA_AlwaysStackOnTop)) flags |= QPlatformTextureList::StacksOnTop; - widgetTextures->appendTexture(widget, wd->textureId(), QRect(widget->mapTo(tlw, QPoint()), widget->size()), flags); + const QRect rect(widget->mapTo(tlw, QPoint()), widget->size()); + widgetTextures->appendTexture(widget, wd->textureId(), rect, wd->clipRect(), flags); } for (int i = 0; i < wd->children.size(); ++i) { @@ -1156,7 +1157,7 @@ void QWidgetBackingStore::doSync() #ifndef QT_NO_OPENGL if (widgetTextures && widgetTextures->count()) { for (int i = 0; i < widgetTextures->count(); ++i) { - QWidget *w = widgetTextures->widget(i); + QWidget *w = static_cast<QWidget *>(widgetTextures->source(i)); if (dirtyRenderToTextureWidgets.contains(w)) { const QRect rect = widgetTextures->geometry(i); // mapped to the tlw already dirty += rect; diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp index f715d93298..daa8ab12a9 100644 --- a/src/widgets/styles/qwindowsvistastyle.cpp +++ b/src/widgets/styles/qwindowsvistastyle.cpp @@ -250,8 +250,6 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt int state = option->state; if (!QWindowsVistaStylePrivate::useVista()) { - foreach (const QObject *target, d->animationTargets()) - d->stopAnimation(target); QWindowsStyle::drawPrimitive(element, option, painter, widget); return; } @@ -810,8 +808,6 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func()); if (!QWindowsVistaStylePrivate::useVista()) { - foreach (const QObject *target, d->animationTargets()) - d->stopAnimation(target); QWindowsStyle::drawControl(element, option, painter, widget); return; } @@ -1494,8 +1490,6 @@ void QWindowsVistaStyle::drawComplexControl(ComplexControl control, const QStyle { QWindowsVistaStylePrivate *d = const_cast<QWindowsVistaStylePrivate*>(d_func()); if (!QWindowsVistaStylePrivate::useVista()) { - foreach (const QObject *target, d->animationTargets()) - d->stopAnimation(target); QWindowsStyle::drawComplexControl(control, option, painter, widget); return; } diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 76f923904d..ef80e359df 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -3034,7 +3034,7 @@ void QComboBoxPrivate::showPopupFromMouseEvent(QMouseEvent *e) QStyle::SubControl sc = q->style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, e->pos(), q); if (e->button() == Qt::LeftButton - && sc != QStyle::SC_None + && !(sc == QStyle::SC_None && e->type() == QEvent::MouseButtonRelease) && (sc == QStyle::SC_ComboBoxArrow || !q->isEditable()) && !viewContainer()->isVisible()) { if (sc == QStyle::SC_ComboBoxArrow) diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index b1749fa5d3..a8da78a025 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -2316,9 +2316,9 @@ void QDateTimeEdit::paintEvent(QPaintEvent *event) QString QDateTimeEditPrivate::getAmPmText(AmPm ap, Case cs) const { if (ap == AmText) { - return (cs == UpperCase ? QDateTimeEdit::tr("AM") : QDateTimeEdit::tr("am")); + return (cs == UpperCase ? QDateTimeParser::tr("AM") : QDateTimeParser::tr("am")); } else { - return (cs == UpperCase ? QDateTimeEdit::tr("PM") : QDateTimeEdit::tr("pm")); + return (cs == UpperCase ? QDateTimeParser::tr("PM") : QDateTimeParser::tr("pm")); } } diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index 5a44df622a..e68da520e7 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -222,11 +222,49 @@ private: // Main entry point for Appx containers int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { +#if _MSC_VER < 1900 int argc = 0; char **argv, **env; _startupinfo info = { _query_new_mode() }; if (int init = __getmainargs(&argc, &argv, &env, false, &info)) return init; +#else + QByteArray commandLine = QString::fromWCharArray(GetCommandLine()).toUtf8(); + QVarLengthArray<char *> args; + args.append(commandLine.data()); + bool quote = false; + bool escape = false; + for (int i = 0; i < commandLine.size(); ++i) { + switch (commandLine.at(i)) { + case '\\': + escape = true; + break; + case '"': + if (escape) { + escape = false; + break; + } + quote = !quote; + commandLine[i] = '\0'; + break; + case ' ': + if (quote) + break; + commandLine[i] = '\0'; + if (args.last()[0] != '\0') + args.append(commandLine.data() + i + 1); + // fall through + default: + if (args.last()[0] == '\0') + args.last() = commandLine.data() + i; + escape = false; // only quotes are escaped + break; + } + } + int argc = args.size(); + char **argv = args.data(); + char **env = Q_NULLPTR; +#endif // _MSC_VER >= 1900 for (int i = 0; env && env[i]; ++i) { QByteArray var(env[i]); diff --git a/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp b/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp index f792b34d48..3b730d97f9 100644 --- a/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp +++ b/tests/auto/corelib/io/qbuffer/tst_qbuffer.cpp @@ -151,7 +151,7 @@ void tst_QBuffer::readBlock() QCOMPARE(b.bytesAvailable(), (qint64) arraySize); b.open(QIODevice::WriteOnly); QCOMPARE(b.bytesAvailable(), (qint64) arraySize); - QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::read (QBuffer): WriteOnly device"); QCOMPARE(b.read(a, arraySize), (qint64) -1); // no read access b.close(); diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 98963108be..5025dd38db 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -2334,7 +2334,7 @@ void tst_QFile::readFromWriteOnlyFile() QFile file("writeonlyfile"); QVERIFY(file.open(QFile::WriteOnly)); char c; - QTest::ignoreMessage(QtWarningMsg, "QIODevice::read: WriteOnly device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::read (QFile, \"writeonlyfile\"): WriteOnly device"); QCOMPARE(file.read(&c, 1), qint64(-1)); } @@ -2343,7 +2343,7 @@ void tst_QFile::writeToReadOnlyFile() QFile file("readonlyfile"); QVERIFY(file.open(QFile::ReadOnly)); char c = 0; - QTest::ignoreMessage(QtWarningMsg, "QIODevice::write: ReadOnly device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::write (QFile, \"readonlyfile\"): ReadOnly device"); QCOMPARE(file.write(&c, 1), qint64(-1)); } diff --git a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp index f756588e80..565ca18899 100644 --- a/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp +++ b/tests/auto/corelib/io/qiodevice/tst_qiodevice.cpp @@ -224,7 +224,7 @@ void tst_QIODevice::unget() buf[0] = '@'; buf[1] = '@'; QTest::ignoreMessage(QtWarningMsg, - "QIODevice::readLine: Called with maxSize < 2"); + "QIODevice::readLine (QBuffer): Called with maxSize < 2"); QCOMPARE(buffer.readLine(buf, 1), qint64(-1)); QCOMPARE(buffer.readLine(buf, 2), qint64(i < 4 ? 1 : -1)); switch (i) { diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp index 8d890e81fa..27614e0eb8 100644 --- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp +++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp @@ -57,6 +57,7 @@ private slots: void waitForLock(); void staleLockFromCrashedProcess_data(); void staleLockFromCrashedProcess(); + void staleLockFromCrashedProcessReusedPid(); void staleShortLockFromBusyProcess(); void staleLongLockFromBusyProcess(); void staleLockRace(); @@ -64,6 +65,9 @@ private slots: void noPermissionsWindows(); void corruptedLockFile(); +private: + static bool overwritePidInLockFile(const QString &filePath, qint64 pid); + public: QString m_helperApp; QTemporaryDir dir; @@ -277,6 +281,30 @@ void tst_QLockFile::staleLockFromCrashedProcess() #endif // !QT_NO_PROCESS } +void tst_QLockFile::staleLockFromCrashedProcessReusedPid() +{ +#if defined(QT_NO_PROCESS) + QSKIP("This test requires QProcess support"); +#elif defined(Q_OS_WINRT) || defined(Q_OS_WINCE) || defined(Q_OS_IOS) + QSKIP("We cannot retrieve information about other processes on this platform."); +#else + const QString fileName = dir.path() + "/staleLockFromCrashedProcessReusedPid"; + + int ret = QProcess::execute(m_helperApp, QStringList() << fileName << "-crash"); + QCOMPARE(ret, int(QLockFile::NoError)); + QVERIFY(QFile::exists(fileName)); + QVERIFY(overwritePidInLockFile(fileName, QCoreApplication::applicationPid())); + + QLockFile secondLock(fileName); + qint64 pid = 0; + secondLock.getLockInfo(&pid, 0, 0); + QCOMPARE(pid, QCoreApplication::applicationPid()); + secondLock.setStaleLockTime(0); + QVERIFY(secondLock.tryLock()); + QCOMPARE(int(secondLock.error()), int(QLockFile::NoError)); +#endif // !QT_NO_PROCESS +} + void tst_QLockFile::staleShortLockFromBusyProcess() { #ifdef QT_NO_PROCESS @@ -497,5 +525,25 @@ void tst_QLockFile::corruptedLockFile() QCOMPARE(int(secondLock.error()), int(QLockFile::NoError)); } +bool tst_QLockFile::overwritePidInLockFile(const QString &filePath, qint64 pid) +{ + QFile f(filePath); + if (!f.open(QFile::ReadWrite)) { + qWarning("Cannot open %s.", qPrintable(filePath)); + return false; + } + QByteArray buf = f.readAll(); + int i = buf.indexOf('\n'); + if (i < 0) { + qWarning("Unexpected lockfile content."); + return false; + } + buf.remove(0, i); + buf.prepend(QByteArray::number(pid)); + f.seek(0); + f.resize(buf.size()); + return f.write(buf) == buf.size(); +} + QTEST_MAIN(tst_QLockFile) #include "tst_qlockfile.moc" diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp index b3333c6d68..9cdb1f47f8 100644 --- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp @@ -142,8 +142,14 @@ public: class CustomGadget { Q_GADGET }; +class CustomGadget_NonDefaultConstructible { + Q_GADGET +public: + CustomGadget_NonDefaultConstructible(int) {}; +}; class CustomNonQObject {}; +class GadgetDerived : public CustomGadget {}; void tst_QMetaType::defined() { @@ -153,11 +159,12 @@ void tst_QMetaType::defined() QCOMPARE(int(QMetaTypeId2<int*>::Defined), 0); QCOMPARE(int(QMetaTypeId2<CustomQObject::CustomQEnum>::Defined), 1); QCOMPARE(int(QMetaTypeId2<CustomGadget>::Defined), 1); + QVERIFY(!QMetaTypeId2<GadgetDerived>::Defined); QVERIFY(int(QMetaTypeId2<CustomQObject*>::Defined)); QVERIFY(!QMetaTypeId2<CustomQObject>::Defined); QVERIFY(!QMetaTypeId2<CustomNonQObject>::Defined); QVERIFY(!QMetaTypeId2<CustomNonQObject*>::Defined); - QVERIFY(!QMetaTypeId2<CustomGadget*>::Defined); + QVERIFY(!QMetaTypeId2<CustomGadget_NonDefaultConstructible>::Defined); } struct Bar diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 263cc5a07a..3ec84b5198 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -128,6 +128,7 @@ private slots: void connectWithReference(); void connectManyArguments(); void connectForwardDeclare(); + void connectNoDefaultConstructorArg(); void returnValue_data(); void returnValue(); void returnValue2_data(); @@ -5227,6 +5228,29 @@ void tst_QObject::connectForwardDeclare() QVERIFY(connect(&ob, &ForwardDeclareArguments::mySignal, &ob, &ForwardDeclareArguments::mySlot, Qt::QueuedConnection)); } +class NoDefaultConstructor +{ + Q_GADGET +public: + NoDefaultConstructor(int) {} +}; + +class NoDefaultContructorArguments : public QObject +{ + Q_OBJECT +signals: + void mySignal(const NoDefaultConstructor&); +public slots: + void mySlot(const NoDefaultConstructor&) {} +}; + +void tst_QObject::connectNoDefaultConstructorArg() +{ + NoDefaultContructorArguments ob; + // it should compile + QVERIFY(connect(&ob, &NoDefaultContructorArguments::mySignal, &ob, &NoDefaultContructorArguments::mySlot, Qt::QueuedConnection)); +} + class ReturnValue : public QObject { friend class tst_QObject; Q_OBJECT diff --git a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp index 76e740dc5f..16314a5dc5 100644 --- a/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp +++ b/tests/auto/dbus/qdbusmarshall/tst_qdbusmarshall.cpp @@ -39,10 +39,7 @@ #include <QtDBus/private/qdbusutil_p.h> #include <QtDBus/private/qdbusconnection_p.h> - -#define QT_LINKED_LIBDBUS -#include <QtDBus/private/qdbusutil_p.h> -#include <QtDBus/private/qdbusconnection_p.h> +#include <QtDBus/private/qdbus_symbols_p.h> static const char serviceName[] = "org.qtproject.autotests.qpong"; static const char objectPath[] = "/org/qtproject/qpong"; @@ -85,10 +82,8 @@ private slots: void sendCallErrors_data(); void sendCallErrors(); -#ifdef DBUS_TYPE_UNIX_FD void receiveUnknownType_data(); void receiveUnknownType(); -#endif void demarshallPrimitives_data(); void demarshallPrimitives(); @@ -1017,7 +1012,6 @@ void tst_QDBusMarshall::sendCallErrors() QCOMPARE(reply.errorMessage(), errorMsg); } -#ifdef DBUS_TYPE_UNIX_FD // If DBUS_TYPE_UNIX_FD is not defined, it means the current system's D-Bus library is too old for this test void tst_QDBusMarshall::receiveUnknownType_data() { @@ -1075,6 +1069,27 @@ public: } }; +// mostly the same as qdbusintegrator.cpp:connectionCapabilies +static bool canSendUnixFd(DBusConnection *connection) +{ + typedef dbus_bool_t (*can_send_type_t)(DBusConnection *, int); + static can_send_type_t can_send_type = 0; + +#if defined(QT_LINKED_LIBDBUS) +# if DBUS_VERSION-0 >= 0x010400 + can_send_type = dbus_connection_can_send_type; +# endif +#else + // run-time check if the next functions are available + can_send_type = (can_send_type_t)qdbus_resolve_conditionally("dbus_connection_can_send_type"); +#endif + +#ifndef DBUS_TYPE_UNIX_FD +# define DBUS_TYPE_UNIX_FD int('h') +#endif + return can_send_type && can_send_type(connection, DBUS_TYPE_UNIX_FD); +} + void tst_QDBusMarshall::receiveUnknownType() { QDBusConnection con = QDBusConnection::sessionBus(); @@ -1088,7 +1103,8 @@ void tst_QDBusMarshall::receiveUnknownType() QVERIFY2(rawcon.data(), error.name); // check if this bus supports passing file descriptors - if (!q_dbus_connection_can_send_type(rawcon.data(), DBUS_TYPE_UNIX_FD)) + + if (!canSendUnixFd(rawcon.data())) QSKIP("Your session bus does not allow sending Unix file descriptors"); // make sure this QDBusConnection won't handle Unix file descriptors @@ -1184,7 +1200,6 @@ void tst_QDBusMarshall::receiveUnknownType() QCOMPARE(spy.list.at(0).arguments().at(0).userType(), receivedTypeId); } } -#endif void tst_QDBusMarshall::demarshallPrimitives_data() { diff --git a/tests/auto/gui/kernel/qtouchevent/BLACKLIST b/tests/auto/gui/kernel/qtouchevent/BLACKLIST new file mode 100644 index 0000000000..8e78d7e41f --- /dev/null +++ b/tests/auto/gui/kernel/qtouchevent/BLACKLIST @@ -0,0 +1,6 @@ +[basicRawEventTranslation] +linux +[multiPointRawEventTranslationOnTouchScreen] +linux +[multiPointRawEventTranslationOnTouchPad] +linux diff --git a/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro b/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro index 7136611165..b1e3c10724 100644 --- a/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro +++ b/tests/auto/gui/kernel/qtouchevent/qtouchevent.pro @@ -1,3 +1,5 @@ +CONFIG += testcase +osx: CONFIG += insignificant_test # QTBUG-46266, crashes SOURCES=tst_qtouchevent.cpp TARGET=tst_qtouchevent QT += testlib widgets gui-private diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index fe11f39242..aa1f573aa9 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -31,11 +31,16 @@ ** ****************************************************************************/ -#include <QtGui> -#include <QtWidgets> +#include <QtWidgets/QDesktopWidget> +#include <QtWidgets/QGraphicsItem> +#include <QtWidgets/QGraphicsScene> +#include <QtWidgets/QGraphicsView> +#include <QtWidgets/QGraphicsWidget> +#include <QtWidgets/QWidget> #include <QtTest> #include <qpa/qwindowsysteminterface.h> +// FIXME: Use static functions of QWindowSystemInterface introduced with HighDPI scaling in 5.6 instead. static QWindowSystemInterface::TouchPoint touchPoint(const QTouchEvent::TouchPoint& pt) { QWindowSystemInterface::TouchPoint p; @@ -72,8 +77,7 @@ public: ulong timestamp; QTouchDevice *deviceFromEvent; - tst_QTouchEventWidget() - : QWidget() + explicit tst_QTouchEventWidget(QWidget *parent = Q_NULLPTR) : QWidget(parent) { reset(); } @@ -88,7 +92,7 @@ public: deleteInTouchBegin = deleteInTouchUpdate = deleteInTouchEnd = false; } - bool event(QEvent *event) + bool event(QEvent *event) Q_DECL_OVERRIDE { switch (event->type()) { case QEvent::TouchBegin: @@ -142,8 +146,8 @@ public: bool deleteInTouchBegin, deleteInTouchUpdate, deleteInTouchEnd; tst_QTouchEventGraphicsItem **weakpointer; - tst_QTouchEventGraphicsItem() - : QGraphicsItem(), weakpointer(0) + explicit tst_QTouchEventGraphicsItem(QGraphicsItem *parent = Q_NULLPTR) + : QGraphicsItem(parent), weakpointer(0) { reset(); } @@ -165,10 +169,10 @@ public: deleteInTouchBegin = deleteInTouchUpdate = deleteInTouchEnd = false; } - QRectF boundingRect() const { return QRectF(0, 0, 10, 10); } - void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) { } + QRectF boundingRect() const Q_DECL_OVERRIDE { return QRectF(0, 0, 10, 10); } + void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) Q_DECL_OVERRIDE { } - bool sceneEvent(QEvent *event) + bool sceneEvent(QEvent *event) Q_DECL_OVERRIDE { switch (event->type()) { case QEvent::TouchBegin: @@ -214,9 +218,9 @@ class tst_QTouchEvent : public QObject Q_OBJECT public: tst_QTouchEvent(); - ~tst_QTouchEvent() { } private slots: + void cleanup(); void touchDisabledByDefault(); void touchEventAcceptedByDefault(); void touchBeginPropagatesWhenIgnored(); @@ -236,15 +240,18 @@ private: QTouchDevice *touchPadDevice; }; -tst_QTouchEvent::tst_QTouchEvent() +tst_QTouchEvent::tst_QTouchEvent() : touchScreenDevice(new QTouchDevice), touchPadDevice(new QTouchDevice) { - touchScreenDevice = new QTouchDevice; - touchPadDevice = new QTouchDevice; touchPadDevice->setType(QTouchDevice::TouchPad); QWindowSystemInterface::registerTouchDevice(touchScreenDevice); QWindowSystemInterface::registerTouchDevice(touchPadDevice); } +void tst_QTouchEvent::cleanup() +{ + QVERIFY(QGuiApplication::topLevelWindows().isEmpty()); +} + void tst_QTouchEvent::touchDisabledByDefault() { // QWidget @@ -261,8 +268,7 @@ void tst_QTouchEvent::touchDisabledByDefault() Qt::NoModifier, Qt::TouchPointPressed, touchPoints); - bool res = QApplication::sendEvent(&widget, &touchEvent); - QVERIFY(!res); + QVERIFY(!QApplication::sendEvent(&widget, &touchEvent)); QVERIFY(!touchEvent.isAccepted()); } @@ -290,8 +296,7 @@ void tst_QTouchEvent::touchDisabledByDefault() Qt::NoModifier, Qt::TouchPointPressed, (QList<QTouchEvent::TouchPoint>() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchEvent); - QVERIFY(!res); + QVERIFY(!QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(!touchEvent.isAccepted()); QVERIFY(!item.seenTouchBegin); } @@ -299,7 +304,7 @@ void tst_QTouchEvent::touchDisabledByDefault() void tst_QTouchEvent::touchEventAcceptedByDefault() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); // QWidget @@ -317,16 +322,14 @@ void tst_QTouchEvent::touchEventAcceptedByDefault() Qt::NoModifier, Qt::TouchPointPressed, touchPoints); - bool res = QApplication::sendEvent(&widget, &touchEvent); - QVERIFY(res); - QVERIFY(touchEvent.isAccepted()); + QVERIFY(QApplication::sendEvent(&widget, &touchEvent)); + QVERIFY(!touchEvent.isAccepted()); // Qt 5.X ignores touch events. // tst_QTouchEventWidget does handle, sending succeeds tst_QTouchEventWidget touchWidget; touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchEvent.ignore(); - res = QApplication::sendEvent(&touchWidget, &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&touchWidget, &touchEvent)); QVERIFY(touchEvent.isAccepted()); } @@ -355,8 +358,7 @@ void tst_QTouchEvent::touchEventAcceptedByDefault() Qt::NoModifier, Qt::TouchPointPressed, (QList<QTouchEvent::TouchPoint>() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(item.seenTouchBegin); } @@ -383,8 +385,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() Qt::NoModifier, Qt::TouchPointPressed, touchPoints); - bool res = QApplication::sendEvent(&grandchild, &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&grandchild, &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(grandchild.seenTouchBegin); QVERIFY(child.seenTouchBegin); @@ -398,8 +399,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() grandchild.setAttribute(Qt::WA_AcceptTouchEvents, false); touchEvent.ignore(); - res = QApplication::sendEvent(&grandchild, &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&grandchild, &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(!grandchild.seenTouchBegin); QVERIFY(child.seenTouchBegin); @@ -435,8 +435,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() Qt::NoModifier, Qt::TouchPointPressed, (QList<QTouchEvent::TouchPoint>() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(grandchild.seenTouchBegin); QVERIFY(child.seenTouchBegin); @@ -471,8 +470,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() Qt::NoModifier, Qt::TouchPointPressed, (QList<QTouchEvent::TouchPoint>() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEvent)); QVERIFY(touchEvent.isAccepted()); QVERIFY(!grandchild.seenTouchBegin); QVERIFY(child.seenTouchBegin); @@ -499,8 +497,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointPressed, touchPoints); - bool res = QApplication::sendEvent(&child, &touchBeginEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&child, &touchBeginEvent)); QVERIFY(touchBeginEvent.isAccepted()); QVERIFY(child.seenTouchBegin); QVERIFY(!window.seenTouchBegin); @@ -511,8 +508,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointMoved, touchPoints); - res = QApplication::sendEvent(&child, &touchUpdateEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&child, &touchUpdateEvent)); QVERIFY(!touchUpdateEvent.isAccepted()); QVERIFY(child.seenTouchUpdate); QVERIFY(!window.seenTouchUpdate); @@ -523,8 +519,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointReleased, touchPoints); - res = QApplication::sendEvent(&child, &touchEndEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(&child, &touchEndEvent)); QVERIFY(!touchEndEvent.isAccepted()); QVERIFY(child.seenTouchEnd); QVERIFY(!window.seenTouchEnd); @@ -558,8 +553,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointPressed, (QList<QTouchEvent::TouchPoint>() << touchPoint)); - bool res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent)); QVERIFY(touchBeginEvent.isAccepted()); QVERIFY(child.seenTouchBegin); QVERIFY(!root.seenTouchBegin); @@ -571,8 +565,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointMoved, (QList<QTouchEvent::TouchPoint>() << touchPoint)); - res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent)); // the scene accepts the event, since it found an item to send the event to QVERIFY(!touchUpdateEvent.isAccepted()); QVERIFY(child.seenTouchUpdate); @@ -585,8 +578,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() Qt::NoModifier, Qt::TouchPointReleased, (QList<QTouchEvent::TouchPoint>() << touchPoint)); - res = QApplication::sendEvent(view.viewport(), &touchEndEvent); - QVERIFY(res); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent)); // the scene accepts the event, since it found an item to send the event to QVERIFY(!touchEndEvent.isAccepted()); QVERIFY(child.seenTouchEnd); @@ -601,17 +593,20 @@ QPointF normalized(const QPointF &pos, const QRectF &rect) void tst_QTouchEvent::basicRawEventTranslation() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 400, 300); + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowActive(&touchWidget)); QPointF pos = touchWidget.rect().center(); QPointF screenPos = touchWidget.mapToGlobal(pos.toPoint()); QPointF delta(10, 10); - QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget); + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); QTouchEvent::TouchPoint rawTouchPoint; rawTouchPoint.setId(0); @@ -726,24 +721,24 @@ void tst_QTouchEvent::basicRawEventTranslation() void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 400, 300); - tst_QTouchEventWidget leftWidget; - leftWidget.setParent(&touchWidget); + tst_QTouchEventWidget leftWidget(&touchWidget); leftWidget.setAttribute(Qt::WA_AcceptTouchEvents); leftWidget.setGeometry(0, 100, 100, 100); - leftWidget.show(); - tst_QTouchEventWidget rightWidget; - rightWidget.setParent(&touchWidget); + tst_QTouchEventWidget rightWidget(&touchWidget); rightWidget.setAttribute(Qt::WA_AcceptTouchEvents); rightWidget.setGeometry(300, 100, 100, 100); - rightWidget.show(); + + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowActive(&touchWidget)); QPointF leftPos = leftWidget.rect().center(); QPointF rightPos = rightWidget.rect().center(); @@ -751,8 +746,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() QPointF leftScreenPos = leftWidget.mapToGlobal(leftPos.toPoint()); QPointF rightScreenPos = rightWidget.mapToGlobal(rightPos.toPoint()); QPointF centerScreenPos = touchWidget.mapToGlobal(centerPos.toPoint()); - QPointF delta(10, 10); - QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget); + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); QList<QTouchEvent::TouchPoint> rawTouchPoints; rawTouchPoints.append(QTouchEvent::TouchPoint(0)); @@ -956,24 +950,25 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 400, 300); - tst_QTouchEventWidget leftWidget; - leftWidget.setParent(&touchWidget); + tst_QTouchEventWidget leftWidget(&touchWidget); leftWidget.setAttribute(Qt::WA_AcceptTouchEvents); leftWidget.setGeometry(0, 100, 100, 100); - leftWidget.show(); + leftWidget.acceptTouchBegin =true; - tst_QTouchEventWidget rightWidget; - rightWidget.setParent(&touchWidget); + tst_QTouchEventWidget rightWidget(&touchWidget); rightWidget.setAttribute(Qt::WA_AcceptTouchEvents); rightWidget.setGeometry(300, 100, 100, 100); - rightWidget.show(); + + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowActive(&touchWidget)); QPointF leftPos = leftWidget.rect().center(); QPointF rightPos = rightWidget.rect().center(); @@ -981,8 +976,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() QPointF leftScreenPos = leftWidget.mapToGlobal(leftPos.toPoint()); QPointF rightScreenPos = rightWidget.mapToGlobal(rightPos.toPoint()); QPointF centerScreenPos = touchWidget.mapToGlobal(centerPos.toPoint()); - QPointF delta(10, 10); - QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget); + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); QList<QTouchEvent::TouchPoint> rawTouchPoints; rawTouchPoints.append(QTouchEvent::TouchPoint(0)); @@ -1003,7 +997,8 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); QVERIFY(!touchWidget.seenTouchEnd); - QVERIFY(leftWidget.seenTouchBegin); + QEXPECT_FAIL("", "QTBUG-46266, fails in Qt 5", Abort); + QVERIFY(!leftWidget.seenTouchBegin); QVERIFY(!leftWidget.seenTouchUpdate); QVERIFY(!leftWidget.seenTouchEnd); QVERIFY(!rightWidget.seenTouchBegin); @@ -1186,19 +1181,15 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() void tst_QTouchEvent::deleteInEventHandler() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); // QWidget { QWidget window; - tst_QTouchEventWidget *child1, *child2, *child3; - child1 = new tst_QTouchEventWidget; - child2 = new tst_QTouchEventWidget; - child3 = new tst_QTouchEventWidget; - child1->setParent(&window); - child2->setParent(&window); - child3->setParent(&window); + QPointer<tst_QTouchEventWidget> child1 = new tst_QTouchEventWidget(&window); + QPointer<tst_QTouchEventWidget> child2 = new tst_QTouchEventWidget(&window); + QPointer<tst_QTouchEventWidget> child3 = new tst_QTouchEventWidget(&window); child1->setAttribute(Qt::WA_AcceptTouchEvents); child2->setAttribute(Qt::WA_AcceptTouchEvents); child3->setAttribute(Qt::WA_AcceptTouchEvents); @@ -1223,47 +1214,43 @@ void tst_QTouchEvent::deleteInEventHandler() Qt::NoModifier, Qt::TouchPointReleased, touchPoints); - QPointer<QWidget> p; - bool res; - touchBeginEvent.ignore(); - p = child1; - res = QApplication::sendEvent(child1, &touchBeginEvent); + QVERIFY(QApplication::sendEvent(child1, &touchBeginEvent)); // event is handled, but widget should be deleted - QVERIFY(res && touchBeginEvent.isAccepted() && p.isNull()); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(child1.isNull()); touchBeginEvent.ignore(); - p = child2; - res = QApplication::sendEvent(child2, &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && !p.isNull()); + QVERIFY(QApplication::sendEvent(child2, &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(!child2.isNull()); touchUpdateEvent.ignore(); - res = QApplication::sendEvent(child2, &touchUpdateEvent); - QVERIFY(res && touchUpdateEvent.isAccepted() && p.isNull()); + QVERIFY(QApplication::sendEvent(child2, &touchUpdateEvent)); + QVERIFY(touchUpdateEvent.isAccepted()); + QVERIFY(child2.isNull()); touchBeginEvent.ignore(); - p = child3; - res = QApplication::sendEvent(child3, &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && !p.isNull()); + QVERIFY(QApplication::sendEvent(child3, &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(!child3.isNull()); touchUpdateEvent.ignore(); - res = QApplication::sendEvent(child3, &touchUpdateEvent); - QVERIFY(res && touchUpdateEvent.isAccepted() && !p.isNull()); + QVERIFY(QApplication::sendEvent(child3, &touchUpdateEvent)); + QVERIFY(touchUpdateEvent.isAccepted()); + QVERIFY(!child3.isNull()); touchEndEvent.ignore(); - res = QApplication::sendEvent(child3, &touchEndEvent); - QVERIFY(res && touchEndEvent.isAccepted() && p.isNull()); + QVERIFY(QApplication::sendEvent(child3, &touchEndEvent)); + QVERIFY(touchEndEvent.isAccepted()); + QVERIFY(child3.isNull()); } // QGraphicsView { QGraphicsScene scene; QGraphicsView view(&scene); - tst_QTouchEventGraphicsItem *root, *child1, *child2, *child3; - root = new tst_QTouchEventGraphicsItem; - child1 = new tst_QTouchEventGraphicsItem; - child2 = new tst_QTouchEventGraphicsItem; - child3 = new tst_QTouchEventGraphicsItem; - child1->setParentItem(root); - child2->setParentItem(root); - child3->setParentItem(root); + QScopedPointer<tst_QTouchEventGraphicsItem> root(new tst_QTouchEventGraphicsItem); + tst_QTouchEventGraphicsItem *child1 = new tst_QTouchEventGraphicsItem(root.data()); + tst_QTouchEventGraphicsItem *child2 = new tst_QTouchEventGraphicsItem(root.data()); + tst_QTouchEventGraphicsItem *child3 = new tst_QTouchEventGraphicsItem(root.data()); child1->setZValue(1.); child2->setZValue(0.); child3->setZValue(-1.); @@ -1274,7 +1261,7 @@ void tst_QTouchEvent::deleteInEventHandler() child2->deleteInTouchUpdate = true; child3->deleteInTouchEnd = true; - scene.addItem(root); + scene.addItem(root.data()); view.resize(200, 200); view.fitInView(scene.sceneRect()); @@ -1302,71 +1289,75 @@ void tst_QTouchEvent::deleteInEventHandler() Qt::NoModifier, Qt::TouchPointReleased, touchPoints); - bool res; child1->weakpointer = &child1; touchBeginEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && !child1); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(!child1); touchUpdateEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); - QVERIFY(res && touchUpdateEvent.isAccepted() && !child1); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); // Qt 5.X ignores touch events. + QVERIFY(!child1); touchEndEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchEndEvent); - QVERIFY(res && touchUpdateEvent.isAccepted() && !child1); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); + QVERIFY(!child1); child2->weakpointer = &child2; touchBeginEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && child2); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(child2); touchUpdateEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); - QVERIFY(res && !touchUpdateEvent.isAccepted() && !child2); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); + QVERIFY(!child2); touchEndEvent.ignore(); - res = QApplication::sendEvent(view.viewport(), &touchEndEvent); - QVERIFY(res && !touchUpdateEvent.isAccepted() && !child2); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); + QVERIFY(!child2); child3->weakpointer = &child3; - res = QApplication::sendEvent(view.viewport(), &touchBeginEvent); - QVERIFY(res && touchBeginEvent.isAccepted() && child3); - res = QApplication::sendEvent(view.viewport(), &touchUpdateEvent); - QVERIFY(res && !touchUpdateEvent.isAccepted() && child3); - res = QApplication::sendEvent(view.viewport(), &touchEndEvent); - QVERIFY(res && !touchEndEvent.isAccepted() && !child3); - - delete root; + QVERIFY(QApplication::sendEvent(view.viewport(), &touchBeginEvent)); + QVERIFY(touchBeginEvent.isAccepted()); + QVERIFY(child3); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchUpdateEvent)); + QVERIFY(!touchUpdateEvent.isAccepted()); + QVERIFY(child3); + QVERIFY(QApplication::sendEvent(view.viewport(), &touchEndEvent)); + QVERIFY(!touchEndEvent.isAccepted()); + QVERIFY(!child3); } } void tst_QTouchEvent::deleteInRawEventTranslation() { - if (qApp->platformName().toLower() == QLatin1String("wayland")) + if (!QGuiApplication::platformName().compare(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); tst_QTouchEventWidget touchWidget; + touchWidget.setWindowTitle(QTest::currentTestFunction()); touchWidget.setAttribute(Qt::WA_AcceptTouchEvents); touchWidget.setGeometry(100, 100, 300, 300); - tst_QTouchEventWidget *leftWidget = new tst_QTouchEventWidget; - leftWidget->setParent(&touchWidget); + QPointer<tst_QTouchEventWidget> leftWidget = new tst_QTouchEventWidget(&touchWidget); leftWidget->setAttribute(Qt::WA_AcceptTouchEvents); leftWidget->setGeometry(0, 100, 100, 100); leftWidget->deleteInTouchBegin = true; - leftWidget->show(); - tst_QTouchEventWidget *centerWidget = new tst_QTouchEventWidget; - centerWidget->setParent(&touchWidget); + QPointer<tst_QTouchEventWidget> centerWidget = new tst_QTouchEventWidget(&touchWidget); centerWidget->setAttribute(Qt::WA_AcceptTouchEvents); centerWidget->setGeometry(100, 100, 100, 100); centerWidget->deleteInTouchUpdate = true; - centerWidget->show(); - tst_QTouchEventWidget *rightWidget = new tst_QTouchEventWidget; - rightWidget->setParent(&touchWidget); + QPointer<tst_QTouchEventWidget> rightWidget = new tst_QTouchEventWidget(&touchWidget); rightWidget->setAttribute(Qt::WA_AcceptTouchEvents); rightWidget->setGeometry(200, 100, 100, 100); rightWidget->deleteInTouchEnd = true; - rightWidget->show(); + + touchWidget.show(); + QVERIFY(QTest::qWaitForWindowExposed(&touchWidget)); QPointF leftPos = leftWidget->rect().center(); QPointF centerPos = centerWidget->rect().center(); @@ -1374,9 +1365,7 @@ void tst_QTouchEvent::deleteInRawEventTranslation() QPointF leftScreenPos = leftWidget->mapToGlobal(leftPos.toPoint()); QPointF centerScreenPos = centerWidget->mapToGlobal(centerPos.toPoint()); QPointF rightScreenPos = rightWidget->mapToGlobal(rightPos.toPoint()); - QRectF screenGeometry = qApp->desktop()->screenGeometry(&touchWidget); - - QPointer<QWidget> pl = leftWidget, pc = centerWidget, pr = rightWidget; + QRectF screenGeometry = QApplication::desktop()->screenGeometry(&touchWidget); QList<QTouchEvent::TouchPoint> rawTouchPoints; rawTouchPoints.append(QTouchEvent::TouchPoint(0)); @@ -1398,7 +1387,9 @@ void tst_QTouchEvent::deleteInRawEventTranslation() touchScreenDevice, touchPointList(rawTouchPoints)); QCoreApplication::processEvents(); - QVERIFY(pl.isNull() && !pc.isNull() && !pr.isNull()); + QVERIFY(leftWidget.isNull()); + QVERIFY(!centerWidget.isNull()); + QVERIFY(!rightWidget.isNull()); // generate update events on all widget, the center widget should die rawTouchPoints[0].setState(Qt::TouchPointMoved); @@ -1455,14 +1446,13 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget() { QGraphicsScene scene; QGraphicsView view(&scene); - tst_QTouchEventGraphicsItem *root; - root = new tst_QTouchEventGraphicsItem; + QScopedPointer<tst_QTouchEventGraphicsItem> root(new tst_QTouchEventGraphicsItem); root->setAcceptTouchEvents(true); - scene.addItem(root); + scene.addItem(root.data()); - QGraphicsWidget *glassWidget = new QGraphicsWidget; + QScopedPointer<QGraphicsWidget> glassWidget(new QGraphicsWidget); glassWidget->setMinimumSize(100, 100); - scene.addItem(glassWidget); + scene.addItem(glassWidget.data()); view.resize(200, 200); view.show(); @@ -1478,7 +1468,7 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget() .release(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport()) .release(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport()); - QCOMPARE(root->touchBeginCounter, 1); + QTRY_COMPARE(root->touchBeginCounter, 1); QCOMPARE(root->touchUpdateCounter, 1); QCOMPARE(root->touchEndCounter, 1); QCOMPARE(root->touchUpdatePoints.size(), 2); @@ -1498,17 +1488,13 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget() QCOMPARE(root->touchBeginCounter, 0); QCOMPARE(root->touchUpdateCounter, 0); QCOMPARE(root->touchEndCounter, 0); - - - delete root; - delete glassWidget; } class WindowTouchEventFilter : public QObject { Q_OBJECT public: - bool eventFilter(QObject *obj, QEvent *event); + bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE; struct TouchInfo { QList<QTouchEvent::TouchPoint> points; QEvent::Type lastSeenType; @@ -1537,18 +1523,18 @@ void tst_QTouchEvent::testQGuiAppDelivery() device->setType(QTouchDevice::TouchScreen); QWindowSystemInterface::registerTouchDevice(device); - QWindow *w = new QWindow; - w->setGeometry(100, 100, 100, 100); - w->show(); - QVERIFY(QTest::qWaitForWindowExposed(w)); + QWindow w; + w.setGeometry(100, 100, 100, 100); + w.show(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); WindowTouchEventFilter filter; - w->installEventFilter(&filter); + w.installEventFilter(&filter); QList<QWindowSystemInterface::TouchPoint> points; // Pass empty list, should be ignored. - QWindowSystemInterface::handleTouchEvent(w, 0, points); + QWindowSystemInterface::handleTouchEvent(&w, 0, points); QCoreApplication::processEvents(); QCOMPARE(filter.d.isEmpty(), true); @@ -1559,12 +1545,12 @@ void tst_QTouchEvent::testQGuiAppDelivery() points.append(tp); // Pass 0 as device, should be ignored. - QWindowSystemInterface::handleTouchEvent(w, 0, points); + QWindowSystemInterface::handleTouchEvent(&w, 0, points); QCoreApplication::processEvents(); QCOMPARE(filter.d.isEmpty(), true); // Now the real thing. - QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchBegin + QWindowSystemInterface::handleTouchEvent(&w, device, points); // TouchBegin QCoreApplication::processEvents(); QCOMPARE(filter.d.count(), 1); QCOMPARE(filter.d.contains(device), true); @@ -1572,7 +1558,7 @@ void tst_QTouchEvent::testQGuiAppDelivery() QCOMPARE(filter.d.value(device).lastSeenType, QEvent::TouchBegin); points[0].state = Qt::TouchPointMoved; - QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchUpdate + QWindowSystemInterface::handleTouchEvent(&w, device, points); // TouchUpdate QCoreApplication::processEvents(); QCOMPARE(filter.d.count(), 1); QCOMPARE(filter.d.contains(device), true); @@ -1580,7 +1566,7 @@ void tst_QTouchEvent::testQGuiAppDelivery() QCOMPARE(filter.d.value(device).lastSeenType, QEvent::TouchUpdate); points[0].state = Qt::TouchPointReleased; - QWindowSystemInterface::handleTouchEvent(w, device, points); // TouchEnd + QWindowSystemInterface::handleTouchEvent(&w, device, points); // TouchEnd QCoreApplication::processEvents(); QCOMPARE(filter.d.count(), 1); QCOMPARE(filter.d.contains(device), true); @@ -1597,13 +1583,13 @@ void tst_QTouchEvent::testMultiDevice() deviceTwo->setType(QTouchDevice::TouchScreen); QWindowSystemInterface::registerTouchDevice(deviceTwo); - QWindow *w = new QWindow; - w->setGeometry(100, 100, 100, 100); - w->show(); - QVERIFY(QTest::qWaitForWindowExposed(w)); + QWindow w; + w.setGeometry(100, 100, 100, 100); + w.show(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); WindowTouchEventFilter filter; - w->installEventFilter(&filter); + w.installEventFilter(&filter); QList<QWindowSystemInterface::TouchPoint> pointsOne, pointsTwo; @@ -1620,8 +1606,8 @@ void tst_QTouchEvent::testMultiDevice() tp.area = QRectF(140, 140, 20, 20); pointsTwo.append(tp); - QWindowSystemInterface::handleTouchEvent(w, deviceOne, pointsOne); - QWindowSystemInterface::handleTouchEvent(w, deviceTwo, pointsTwo); + QWindowSystemInterface::handleTouchEvent(&w, deviceOne, pointsOne); + QWindowSystemInterface::handleTouchEvent(&w, deviceTwo, pointsTwo); QCoreApplication::processEvents(); QCOMPARE(filter.d.contains(deviceOne), true); diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST new file mode 100644 index 0000000000..ee9709e68b --- /dev/null +++ b/tests/auto/gui/kernel/qwindow/BLACKLIST @@ -0,0 +1,6 @@ +[positioning:default] +ubuntu-14.04 +[modalWindowPosition] +ubuntu-14.04 +[modalWithChildWindow] +ubuntu-14.04 diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index f4d3555531..b0a19a6c2d 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -401,8 +401,8 @@ void tst_QSslSocket::proxyAuthenticationRequired(const QNetworkProxy &, QAuthent void tst_QSslSocket::constructing() { - const char readNotOpenMessage[] = "QIODevice::read: device not open"; - const char writeNotOpenMessage[] = "QIODevice::write: device not open"; + const char readNotOpenMessage[] = "QIODevice::read (QSslSocket): device not open"; + const char writeNotOpenMessage[] = "QIODevice::write (QSslSocket): device not open"; if (!QSslSocket::supportsSsl()) return; @@ -440,13 +440,13 @@ void tst_QSslSocket::constructing() QCOMPARE(socket.read(0, 0), qint64(-1)); QTest::ignoreMessage(QtWarningMsg, readNotOpenMessage); QVERIFY(socket.readAll().isEmpty()); - QTest::ignoreMessage(QtWarningMsg, "QIODevice::readLine: Called with maxSize < 2"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::readLine (QSslSocket): Called with maxSize < 2"); QCOMPARE(socket.readLine(0, 0), qint64(-1)); char buf[10]; QCOMPARE(socket.readLine(buf, sizeof(buf)), qint64(-1)); - QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek: Cannot call seek on a sequential device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek (QSslSocket): Cannot call seek on a sequential device"); QVERIFY(!socket.reset()); - QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek: Cannot call seek on a sequential device"); + QTest::ignoreMessage(QtWarningMsg, "QIODevice::seek (QSslSocket): Cannot call seek on a sequential device"); QVERIFY(!socket.seek(2)); QCOMPARE(socket.size(), qint64(0)); QVERIFY(!socket.waitForBytesWritten(10)); diff --git a/tests/auto/other/baselineexample/baselineexample.pro b/tests/auto/other/baselineexample/baselineexample.pro deleted file mode 100644 index c1c4b31bfe..0000000000 --- a/tests/auto/other/baselineexample/baselineexample.pro +++ /dev/null @@ -1,19 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2010-12-09T14:55:13 -# -#------------------------------------------------- - -QT += testlib widgets - -TARGET = tst_baselineexample -CONFIG += console -CONFIG -= app_bundle - -TEMPLATE = app - -SOURCES += tst_baselineexample.cpp -DEFINES += SRCDIR=\\\"$$PWD/\\\" - -include($$PWD/../../../baselineserver/shared/qbaselinetest.pri) -DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/other/baselineexample/tst_baselineexample.cpp b/tests/auto/other/baselineexample/tst_baselineexample.cpp deleted file mode 100644 index 9059989015..0000000000 --- a/tests/auto/other/baselineexample/tst_baselineexample.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** 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 <qbaselinetest.h> -#include <QPushButton> - -class tst_BaselineExample : public QObject -{ - Q_OBJECT - -public: - tst_BaselineExample(); - -private Q_SLOTS: - void testBasicUsage(); - void testMultipleImages(); - void testDataDriven_data(); - void testDataDriven(); - void testDataDrivenChecksum_data(); - void testDataDrivenChecksum(); -}; - - -tst_BaselineExample::tst_BaselineExample() -{ -} - - -void tst_BaselineExample::testBasicUsage() -{ - // Generate an image: - QPushButton b("Press me!"); - b.resize(100, 50); - b.show(); - QVERIFY(QTest::qWaitForWindowExposed(&b)); - QImage img1 = b.grab().toImage(); - QVERIFY(!img1.isNull()); - - // Compare it to baseline on server: - QBASELINE_CHECK(img1, "button"); -} - - -void tst_BaselineExample::testMultipleImages() -{ - QPushButton b("Press me!"); - b.resize(100, 50); - b.show(); - QVERIFY(QTest::qWaitForWindowExposed(&b)); - QBASELINE_CHECK(b.grab().toImage(), "text1"); - - b.setText("Kick me!"); - QTest::qWait(50); - QBASELINE_CHECK(b.grab().toImage(), "text2"); -} - - -void tst_BaselineExample::testDataDriven_data() -{ - QTest::addColumn<QString>("label"); - QBaselineTest::newRow("short") << "Ok!"; - QBaselineTest::newRow("long") << "A really long button text that just does not seem to end"; - QBaselineTest::newRow("empty") << ""; - QBaselineTest::newRow("signs") << "!@#$%^&*()_"; - QBaselineTest::newRow("html") << "<b>BOLD</b>"; -} - - -void tst_BaselineExample::testDataDriven() -{ - QFETCH(QString, label); - QPushButton b(label); - b.resize(100, 50); - b.show(); - QVERIFY(QTest::qWaitForWindowExposed(&b)); - QBASELINE_TEST(b.grab().toImage()); -} - - -void tst_BaselineExample::testDataDrivenChecksum_data() -{ - QTest::addColumn<QString>("label"); - - const int numItems = 5; - const char *tags[numItems] = {"short", "long", "empty", "signs", "html"}; - const char *labels[numItems] = {"Ok!", "A really long button text that just does not seem to end", "", "!@#$%^&*()_", "<b>BOLD</b>"}; - - for (int i = 0; i<numItems; i++) { - quint16 checksum = qChecksum(labels[i], qstrlen(labels[i])); - QBaselineTest::newRow(tags[i], checksum) << labels[i]; - } -} - - -void tst_BaselineExample::testDataDrivenChecksum() -{ - QFETCH(QString, label); - QPushButton b(label); - b.resize(100, 50); - b.show(); - QVERIFY(QTest::qWaitForWindowExposed(&b)); - QBASELINE_TEST(b.grab().toImage()); -} - - -QTEST_MAIN(tst_BaselineExample); - -#include "tst_baselineexample.moc" diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro index a5ed4c5f31..8c911da2e0 100644 --- a/tests/auto/other/other.pro +++ b/tests/auto/other/other.pro @@ -1,7 +1,6 @@ TEMPLATE=subdirs SUBDIRS=\ # atwrapper \ # QTBUG-19452 - baselineexample \ compiler \ gestures \ lancelot \ @@ -26,7 +25,6 @@ SUBDIRS=\ toolsupport \ !qtHaveModule(widgets): SUBDIRS -= \ - baselineexample \ gestures \ lancelot \ languagechange \ @@ -41,7 +39,6 @@ SUBDIRS=\ qaccessibilitymac \ !qtHaveModule(network): SUBDIRS -= \ - baselineexample \ lancelot \ networkselftest \ qnetworkaccessmanager_and_qprogressdialog \ diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 8bef678af9..350c6142d2 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -1882,6 +1882,13 @@ void tst_Moc::warnings_data() << 1 << QString() << QString("standard input:5: Error: Class declaration lacks Q_OBJECT macro."); + + QTest::newRow("QTBUG-46210: crash on invalid macro") + << QByteArray("#define Foo(a, b, c) a b c #a #b #c a##b##c #d\n Foo(45);") + << QStringList() + << 1 + << QString("IGNORE_ALL_STDOUT") + << QString(":2: Error: '#' is not followed by a macro parameter"); } void tst_Moc::warnings() diff --git a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp index 3ead172d82..1324027af6 100644 --- a/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/widgets/itemviews/qtreeview/tst_qtreeview.cpp @@ -255,6 +255,7 @@ private slots: void taskQTBUG_8176_emitOnExpandAll(); void taskQTBUG_34717_collapseAtBottom(); void taskQTBUG_37813_crash(); + void taskQTBUG_45697_crash(); void testInitialFocus(); }; @@ -4385,5 +4386,82 @@ void tst_QTreeView::taskQTBUG_37813_crash() #endif // QT_BUILD_INTERNAL } +// QTBUG-45697: Using a QTreeView with a multi-column model filtered by QSortFilterProxyModel, +// when sorting the source model while the widget is not yet visible and showing the widget +// later on, corruption occurs in QTreeView. +class Qtbug45697TestWidget : public QWidget +{ + Q_OBJECT +public: + static const int columnCount = 3; + + explicit Qtbug45697TestWidget(); + int timerTick() const { return m_timerTick; } + +public slots: + void slotTimer(); + +private: + QTreeView *m_treeView; + QStandardItemModel *m_model; + QSortFilterProxyModel *m_sortFilterProxyModel; + int m_timerTick; +}; + +Qtbug45697TestWidget::Qtbug45697TestWidget() + : m_treeView(new QTreeView(this)) + , m_model(new QStandardItemModel(0, Qtbug45697TestWidget::columnCount, this)) + , m_sortFilterProxyModel(new QSortFilterProxyModel(this)) + , m_timerTick(0) + { + QVBoxLayout *vBoxLayout = new QVBoxLayout(this); + vBoxLayout->addWidget(m_treeView); + + for (char sortChar = 'z'; sortChar >= 'a' ; --sortChar) { + QList<QStandardItem *> items; + for (int column = 0; column < Qtbug45697TestWidget::columnCount; ++column) { + const QString text = QLatin1Char(sortChar) + QLatin1String(" ") + QString::number(column); + items.append(new QStandardItem(text)); + } + m_model->appendRow(items); + } + + m_sortFilterProxyModel->setSourceModel(m_model); + m_treeView->setModel(m_sortFilterProxyModel); + + QHeaderView *headerView = m_treeView->header(); + for (int s = 1, lastSection = headerView->count() - 1; s < lastSection; ++s ) + headerView->setSectionResizeMode(s, QHeaderView::ResizeToContents); + + QTimer *timer = new QTimer(this); + timer->setInterval(50); + connect(timer, &QTimer::timeout, this, &Qtbug45697TestWidget::slotTimer); + timer->start(); +} + +void Qtbug45697TestWidget::slotTimer() +{ + switch (m_timerTick++) { + case 0: + m_model->sort(0); + break; + case 1: + show(); + break; + default: + close(); + break; + } +} + +void tst_QTreeView::taskQTBUG_45697_crash() +{ + Qtbug45697TestWidget testWidget; + testWidget.setWindowTitle(QTest::currentTestFunction()); + testWidget.resize(400, 400); + testWidget.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft() + QPoint(100, 100)); + QTRY_VERIFY(testWidget.timerTick() >= 2); +} + QTEST_MAIN(tst_QTreeView) #include "tst_qtreeview.moc" diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index c9a1a64135..c33fd5a951 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -178,6 +178,12 @@ private slots: void settableStyleHints_data(); void settableStyleHints(); // Needs to run last as it changes style hints. + +protected slots: + void quitApplication(); + +private: + bool quitApplicationTriggered; }; class EventSpy : public QObject @@ -235,6 +241,7 @@ public: static char *argv0; tst_QApplication::tst_QApplication() + : quitApplicationTriggered(false) { #ifdef Q_OS_WINCE // Clean up environment previously to launching test @@ -719,11 +726,8 @@ void tst_QApplication::quitOnLastWindowClosed() { int argc = 0; QApplication app(argc, 0); - QTimer timer; - timer.setInterval(100); QSignalSpy spy(&app, SIGNAL(aboutToQuit())); - QSignalSpy spy2(&timer, SIGNAL(timeout())); CloseEventTestWindow mainWindow; @@ -733,14 +737,14 @@ void tst_QApplication::quitOnLastWindowClosed() mainWindow.show(); QVERIFY(QTest::qWaitForWindowExposed(&mainWindow)); - timer.start(); - QTimer::singleShot(1000, &mainWindow, SLOT(close())); // This should quit the application - QTimer::singleShot(2000, &app, SLOT(quit())); // This makes sure we quit even if it didn't + QTimer::singleShot(1000, &mainWindow, SLOT(close())); // This should NOT quit the application (see CloseEventTestWindow) + quitApplicationTriggered = false; + QTimer::singleShot(2000, this, SLOT(quitApplication())); // This actually quits the application. app.exec(); QCOMPARE(spy.count(), 1); - QVERIFY(spy2.count() > 15); // Should be around 20 if closing did not caused the quit + QVERIFY(quitApplicationTriggered); } { int argc = 0; @@ -768,24 +772,20 @@ void tst_QApplication::quitOnLastWindowClosed() QApplication app(argc, 0); QVERIFY(app.quitOnLastWindowClosed()); - QTimer timer; - timer.setInterval(100); - QSignalSpy timerSpy(&timer, SIGNAL(timeout())); - QWindow w; w.show(); QWidget wid; wid.show(); - timer.start(); QTimer::singleShot(1000, &wid, SLOT(close())); // This should NOT quit the application because the // QWindow is still there. - QTimer::singleShot(2000, &app, SLOT(quit())); // This causes the quit. + quitApplicationTriggered = false; + QTimer::singleShot(2000, this, SLOT(quitApplication())); // This causes the quit. app.exec(); - QVERIFY(timerSpy.count() > 15); // Should be around 20 if closing did not caused the quit + QVERIFY(quitApplicationTriggered); // Should be around 20 if closing did not caused the quit } { // QTBUG-31569: If the last widget with Qt::WA_QuitOnClose set is closed, other // widgets that don't have the attribute set should be closed automatically. @@ -2406,6 +2406,12 @@ void tst_QApplication::globalStaticObjectDestruction() #endif } +void tst_QApplication::quitApplication() +{ + quitApplicationTriggered = true; + qApp->quit(); +} + //QTEST_APPLESS_MAIN(tst_QApplication) int main(int argc, char *argv[]) { diff --git a/tests/auto/widgets/kernel/qwidget/BLACKLIST b/tests/auto/widgets/kernel/qwidget/BLACKLIST index ed40f98051..591aa9e40f 100644 --- a/tests/auto/widgets/kernel/qwidget/BLACKLIST +++ b/tests/auto/widgets/kernel/qwidget/BLACKLIST @@ -1,11 +1,16 @@ +# OSX QTBUG-25300 QTBUG-45502 [normalGeometry] ubuntu-14.04 +osx [saveRestoreGeometry] ubuntu-14.04 +osx [restoreVersion1Geometry] ubuntu-14.04 +osx [updateWhileMinimized] ubuntu-14.04 +osx [focusProxyAndInputMethods] ubuntu-14.04 [touchEventSynthesizedMouseEvent] @@ -14,3 +19,119 @@ ubuntu-14.04 ubuntu-14.04 [largerThanScreen_QTBUG30142] ubuntu-14.04 +[windowState] +osx +[showMaximized] +osx +[setGeometry] +osx +[stackUnder] +osx +[raise] +osx-10.9 +[widgetAt] +osx +[sheetOpacity] +osx +[resizeEvent] +osx +[setWindowGeometry:100,123 200x200, flags 0] +osx-10.10 +[windowMoveResize:100,123 200x200, flags 0] +osx-10.10 +[setWindowGeometry:100,122 200x200, flags 0] +osx-10.9 +[windowMoveResize:100,122 200x200, flags 0] +osx-10.9 +[setWindowGeometry:100,100 824x564, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x564, flags 0] +osx-10.10 +[setWindowGeometry:100,100 824x516, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x516, flags 0] +osx-10.10 +[setWindowGeometry:100,73 200x0, flags 0] +osx-10.10 +[windowMoveResize:100,73 200x0, flags 0] +osx-10.10 +[setWindowGeometry:100,100 824x519, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x519, flags 0] +osx-10.10 +[setWindowGeometry:100,100 824x518, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x518, flags 0] +osx-10.10 +[setWindowGeometry:100,72 200x0, flags 0] +osx-10.9 +[windowMoveResize:100,72 200x0, flags 0] +osx-10.9 +[setWindowGeometry:100,122 952x574, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x574, flags 0] +osx-10.9 +[setWindowGeometry:100,122 952x578, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x578, flags 0] +osx-10.9 +[setWindowGeometry:100,122 952x576, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x576, flags 0] +osx-10.9 +[setWindowGeometry:100,100 824x521, flags 0] +osx-10.10 +[windowMoveResize:100,100 824x521, flags 0] +osx-10.10 +[setWindowGeometry:100,122 952x577, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x577, flags 0] +osx-10.9 +[setWindowGeometry:100,122 952x580, flags 0] +osx-10.9 +[windowMoveResize:100,122 952x580, flags 0] +osx-10.9 +[windowMoveResize:130,72 0x0, flags 0] +osx-10.9 +[windowMoveResize:130,122 0x200, flags 0] +osx-10.9 +[childEvents] +osx +[renderInvisible] +osx +[optimizedResizeMove] +osx +[optimizedResize_topLevel] +osx +[render_systemClip] +osx +[update] +osx +[doubleRepaint] +osx +[childAt_unifiedToolBar] +osx +[showMinimizedKeepsFocus] +osx-10.10 +[moveWindowInShowEvent:1] +osx-10.9 +[moveWindowInShowEvent:2] +osx-10.9 +[taskQTBUG_4055_sendSyntheticEnterLeave] +osx +[syntheticEnterLeave] +osx +[maskedUpdate] +osx +[hideWhenFocusWidgetIsChild] +osx-10.10 +[hideOpaqueChildWhileHidden] +osx +[resizeStaticContentsChildWidget_QTBUG35282] +osx-10.9 +[lower] +osx +[setClearAndResizeMask] +osx +[setToolTip] +osx-10.9 diff --git a/tests/auto/widgets/kernel/qwidget/qwidget.pro b/tests/auto/widgets/kernel/qwidget/qwidget.pro index 30e1048247..aae083d45e 100644 --- a/tests/auto/widgets/kernel/qwidget/qwidget.pro +++ b/tests/auto/widgets/kernel/qwidget/qwidget.pro @@ -21,5 +21,3 @@ x11 { } !wince*:win32:!winrt: LIBS += -luser32 -lgdi32 - -mac:CONFIG+=insignificant_test # QTBUG-25300, QTBUG-23695 diff --git a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp index ade9f72543..2bbc2e05b7 100644 --- a/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp +++ b/tests/auto/widgets/widgets/qdockwidget/tst_qdockwidget.cpp @@ -764,6 +764,8 @@ void tst_QDockWidget::restoreDockWidget() restoreWindow.show(); QVERIFY(QTest::qWaitForWindowExposed(&restoreWindow)); QTRY_VERIFY(dock->isFloating()); + if (!QGuiApplication::platformName().compare("xcb", Qt::CaseInsensitive)) + QSKIP("Skip due to Window manager positioning issues", Abort); QTRY_COMPARE(dock->pos(), dockPos); } } diff --git a/tools/configure/Makefile.mingw b/tools/configure/Makefile.mingw index 40c2112132..9ac99fd678 100644 --- a/tools/configure/Makefile.mingw +++ b/tools/configure/Makefile.mingw @@ -4,7 +4,7 @@ CONFSRC = $(TOOLSRC)/configure RAW_PCH = configure_pch.h PCH = $(RAW_PCH).gch/c++ -DEFINES = -DUNICODE -DQT_NO_DATASTREAM -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -DCOMMERCIAL_VERSION +DEFINES = -DUNICODE -DQT_NO_DATASTREAM -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE INCPATH = -I"../../include" -I"../../include/QtCore" -I"../../include/QtCore/$(QTVERSION)" -I"../../include/QtCore/$(QTVERSION)/QtCore" -I"$(TOOLSRC)/shared" -I"$(QTSRC)mkspecs/win32-g++" CXXFLAGS_BARE = -fno-rtti -fno-exceptions -mthreads -Wall -Wextra $(DEFINES) $(INCPATH) CXXFLAGS = -include $(RAW_PCH) $(CXXFLAGS_BARE) diff --git a/tools/configure/Makefile.win32 b/tools/configure/Makefile.win32 index b74b0bc82d..8c6d213e42 100644 --- a/tools/configure/Makefile.win32 +++ b/tools/configure/Makefile.win32 @@ -3,7 +3,7 @@ TOOLSRC = $(QTSRC)tools CONFSRC = $(TOOLSRC)\configure PCH = configure_pch.pch -DEFINES = -DUNICODE -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -DCOMMERCIAL_VERSION +DEFINES = -DUNICODE -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE INCPATH = -I"..\..\include" -I"..\..\include\QtCore" -I"..\..\include\QtCore\$(QTVERSION)" -I"..\..\include\QtCore\$(QTVERSION)\QtCore" -I"$(TOOLSRC)\shared" -I"$(QTSRC)mkspecs\win32-msvc2008" CXXFLAGS_BARE = -nologo -Zc:wchar_t -W3 -GR -EHsc -w34100 -w34189 $(CFLAGS_CRT) $(EXTRA_CXXFLAGS) $(DEFINES) $(INCPATH) CXXFLAGS = -FIconfigure_pch.h -Yuconfigure_pch.h -Fp$(PCH) -MP $(CXXFLAGS_BARE) diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index d3237d472b..e4901bacde 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -132,5 +132,3 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/plugin/quuid.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qcryptographichash.cpp \ $$QT_SOURCE_TREE/tools/shared/windows/registry.cpp - -DEFINES += COMMERCIAL_VERSION diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 08ec943563..3bf0546ac1 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -34,9 +34,7 @@ #include "configureapp.h" #include "environment.h" -#ifdef COMMERCIAL_VERSION -# include "tools.h" -#endif +#include "tools.h" #include <qdir.h> #include <qdiriterator.h> @@ -3460,6 +3458,14 @@ void Configure::generateQConfigPri() << "QT_MINOR_VERSION = " << dictionary["VERSION_MINOR"] << endl << "QT_PATCH_VERSION = " << dictionary["VERSION_PATCH"] << endl; + configStream << endl + << "QT_EDITION = " << dictionary["EDITION"] << endl; + + if (dictionary["EDITION"] != "OpenSource" && dictionary["EDITION"] != "Preview") { + configStream << "QT_LICHECK = " << dictionary["LICHECK"] << endl; + configStream << "QT_RELEASE_DATE = " << dictionary["RELEASEDATE"] << endl; + } + if (!dictionary["CFG_SYSROOT"].isEmpty() && dictionary["CFG_GCC_SYSROOT"] == "yes") { configStream << endl << "# sysroot" << endl @@ -4381,8 +4387,10 @@ bool Configure::showLicense(QString orgLicenseFile) bool showLgpl2 = true; QString licenseFile = orgLicenseFile; QString theLicense; - if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") { - if (platform() != ANDROID || dictionary["ANDROID_STYLE_ASSETS"] == "no") { + if (dictionary["EDITION"] == "OpenSource") { + if (platform() != WINDOWS_RT + && platform() != WINDOWS_CE + && (platform() != ANDROID || dictionary["ANDROID_STYLE_ASSETS"] == "no")) { theLicense = "GNU Lesser General Public License (LGPL) version 2.1" "\nor the GNU Lesser General Public License (LGPL) version 3"; } else { @@ -4404,7 +4412,7 @@ bool Configure::showLicense(QString orgLicenseFile) cout << "You are licensed to use this software under the terms of" << endl << "the " << theLicense << "." << endl << endl; - if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") { + if (dictionary["EDITION"] == "OpenSource") { cout << "Type '3' to view the Lesser GNU General Public License version 3 (LGPLv3)." << endl; if (showLgpl2) cout << "Type 'L' to view the Lesser GNU General Public License version 2.1 (LGPLv2.1)." << endl; @@ -4423,7 +4431,7 @@ bool Configure::showLicense(QString orgLicenseFile) } else if (accept == 'n') { return false; } else { - if (dictionary["EDITION"] == "OpenSource" || dictionary["EDITION"] == "Snapshot") { + if (dictionary["EDITION"] == "OpenSource") { if (accept == '3') licenseFile = orgLicenseFile + "/LICENSE.LGPLv3"; else @@ -4499,19 +4507,9 @@ void Configure::readLicense() cout << endl << "Cannot find the GPL license files! Please download the Open Source version of the library." << endl; dictionary["DONE"] = "error"; } -#ifdef COMMERCIAL_VERSION else { Tools::checkLicense(dictionary, sourcePath, buildPath); } -#else // !COMMERCIAL_VERSION - else { - cout << endl << "Error: This is the Open Source version of Qt." - << endl << "If you want to use Enterprise features of Qt," - << endl << "information use the contact form at http://www.qt.io/contact-us" - << endl << "to purchase a license." << endl << endl; - dictionary["DONE"] = "error"; - } -#endif } void Configure::reloadCmdLine() diff --git a/tools/configure/tools.cpp b/tools/configure/tools.cpp index 83d969ce16..095e798332 100644 --- a/tools/configure/tools.cpp +++ b/tools/configure/tools.cpp @@ -54,6 +54,8 @@ void Tools::checkLicense(QMap<QString,QString> &dictionary, return; } + dictionary["LICHECK"] = "licheck.exe"; + const QString licenseChecker = QDir::toNativeSeparators(sourcePath + "/bin/licheck.exe"); |