Merge 5.5 into 5.5.0

Change-Id: I27921a25a0fc56afb5429e40fc1e9b4b9a645a9a
bb10
Oswald Buddenhagen 2015-06-01 19:44:29 +02:00
commit 6e008cd579
122 changed files with 2198 additions and 1138 deletions

View File

@ -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

33
configure vendored
View File

@ -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"

View File

@ -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]

View File

@ -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

View File

@ -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")

View File

@ -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]

View File

@ -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

View File

@ -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")

View File

@ -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]

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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));
}

View File

@ -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);

View File

@ -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));

View File

@ -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>

View File

@ -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)
}

View File

@ -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) {

View File

@ -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\")

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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);

View File

@ -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;
}

View File

@ -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();

View File

@ -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(';'));

View File

@ -56,7 +56,8 @@ enum DotNET {
NET2008 = 0x90,
NET2010 = 0xa0,
NET2012 = 0xb0,
NET2013 = 0xc0
NET2013 = 0xc0,
NET2015 = 0xd0
};
/*

View File

@ -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;

View File

@ -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

View File

@ -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; }

View File

@ -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
}

View File

@ -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

View File

@ -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));

View File

@ -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"/>

View File

@ -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

View File

@ -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

View File

@ -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}".

View File

@ -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

View File

@ -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);

View File

@ -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()

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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()

View File

@ -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 **);

View File

@ -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"));
}
}

View File

@ -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,

View File

@ -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),

View File

@ -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;
}

View File

@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE
QInputDeviceManager::QInputDeviceManager(QObject *parent)
: QObject(*new QInputDeviceManagerPrivate, parent)
{
qRegisterMetaType<DeviceType>();
}
int QInputDeviceManager::deviceCount(DeviceType type) const

View File

@ -77,4 +77,6 @@ signals:
QT_END_NAMESPACE
Q_DECLARE_METATYPE(QInputDeviceManager::DeviceType)
#endif // QINPUTDEVICEMANAGER_P_H

View File

@ -175,130 +175,16 @@ 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 &region) 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);
}
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();
}
} else {
markWindowAsDirty();
}
paintDevice->setSize(QSize(deviceWidth, deviceHeight));
paintDevice->setDevicePixelRatio(q->devicePixelRatio());
context->functions()->glViewport(0, 0, deviceWidth, deviceHeight);
context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject());
q->paintUnderGL();
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();
QRect windowRect(QPoint(0, 0), fbo->size());
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect);
blitter.bind();
blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft);
blitter.release();
if (updateBehavior == QOpenGLWindow::PartialUpdateBlend)
context->functions()->glDisable(GL_BLEND);
}
q->paintOverGL();
}
void flush(const QRegion &region) Q_DECL_OVERRIDE
{
Q_UNUSED(region);
Q_Q(QOpenGLWindow);
context->swapBuffers(q);
emit q->frameSwapped();
}
void beginPaint(const QRegion &region) Q_DECL_OVERRIDE;
void endPaint() Q_DECL_OVERRIDE;
void flush(const QRegion &region) Q_DECL_OVERRIDE;
QOpenGLWindow::UpdateBehavior updateBehavior;
bool hasFboBlit;
@ -311,6 +197,135 @@ public:
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 QOpenGLWindowPrivate::initialize()
{
Q_Q(QOpenGLWindow);
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 &region)
{
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");
}
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);
context->functions()->glBindFramebuffer(GL_FRAMEBUFFER, context->defaultFramebufferObject());
q->paintUnderGL();
if (updateBehavior > QOpenGLWindow::NoPartialUpdate)
fbo->bind();
}
void QOpenGLWindowPrivate::endPaint()
{
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();
QRect windowRect(QPoint(0, 0), fbo->size());
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(windowRect, windowRect);
blitter.bind();
blitter.blit(fbo->texture(), target, QOpenGLTextureBlitter::OriginBottomLeft);
blitter.release();
if (updateBehavior == QOpenGLWindow::PartialUpdateBlend)
context->functions()->glDisable(GL_BLEND);
}
q->paintOverGL();
}
void QOpenGLWindowPrivate::bindFBO()
{
if (updateBehavior > QOpenGLWindow::NoPartialUpdate)
fbo->bind();
else
QOpenGLFramebufferObject::bindDefault();
}
void QOpenGLWindowPrivate::flush(const QRegion &region)
{
Q_UNUSED(region);
Q_Q(QOpenGLWindow);
context->swapBuffers(q);
emit q->frameSwapped();
}
void QOpenGLWindowPaintDevice::ensureActiveTarget()
{
QOpenGLWindowPrivate::get(m_window)->bindFBO();
@ -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());
}

View File

@ -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)
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) * xap;
g = G_VAL(pix) * xap;
b = B_VAL(pix) * xap;
a = A_VAL(pix) * xap;
r = qRed(*pix) * xyap;
g = qGreen(*pix) * xyap;
b = qBlue(*pix) * xyap;
a = qAlpha(*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;
a += A_VAL(pix) * Cx;
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++;
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)
{
r = R_VAL(pix) * yap;
g = G_VAL(pix) * yap;
b = B_VAL(pix) * yap;
a = A_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;
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;
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;
for (j = (1 << 14) - xyap; j > Cxy; j -= Cxy) {
pix += step;
r += qRed(*pix) * Cxy;
g += qGreen(*pix) * Cxy;
b += qBlue(*pix) * Cxy;
}
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;
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;

View File

@ -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);

View File

@ -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 &region, 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 &regi
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 &regi
// 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 &regi
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 &regi
}
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 &regi
// 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);

View File

@ -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:

View File

@ -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

View File

@ -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>

View File

@ -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;
}

View File

@ -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())

View File

@ -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);
}
}

View File

@ -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());

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -163,7 +163,7 @@ void QWindowsDirect2DWindow::present(const QRegion &region)
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,

View File

@ -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())

View File

@ -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;
}

View File

@ -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)

View File

@ -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);

View File

@ -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())

View File

@ -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);

View File

@ -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

View File

@ -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)
{

View File

@ -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;
};

View File

@ -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);

View File

@ -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;

View File

@ -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; }

View File

@ -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(int event_x, int event_y, int root_x, int root_y,
Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp)
{
if (!xcbScreen())
return;
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);
}
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)
{
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));
Qt::KeyboardModifiers modifiers = connection()->keyboard()->translateModifiers(event->state);
handleMotionNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, modifiers, event->time);
}
handleMouseEvent(event->time, local, global, modifiers);
#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;

View File

@ -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;

View File

@ -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
}
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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());

View File

@ -3658,6 +3658,7 @@ void QTreeViewPrivate::updateScrollBars()
if (!viewportSize.isValid())
viewportSize = QSize(0, 0);
executePostedLayout();
if (viewItems.isEmpty()) {
q->doItemsLayout();
}

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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)

View File

@ -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"));
}
}

View File

@ -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]);

View File

@ -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();

View File

@ -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));
}

View File

@ -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) {

View File

@ -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"

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