commit
6e008cd579
|
|
@ -4,4 +4,8 @@ CONFIG -= qt
|
|||
|
||||
INCLUDEPATH += $$QMAKE_INCDIR_EGL
|
||||
|
||||
LIBS += -L$$QMAKE_LIBDIR_EGL -lEGL -lGLESv2 -lbcm_host
|
||||
for(p, QMAKE_LIBDIR_EGL) {
|
||||
exists($$p):LIBS += -L$$p
|
||||
}
|
||||
|
||||
LIBS += -lEGL -lGLESv2 -lbcm_host
|
||||
|
|
|
|||
|
|
@ -2962,8 +2962,20 @@ if [ -f "$relpath"/LICENSE.PREVIEW.COMMERCIAL ] && [ $COMMERCIAL_USER = "yes" ];
|
|||
Edition="Preview"
|
||||
EditionString="Technology Preview"
|
||||
elif [ $COMMERCIAL_USER = "yes" ]; then
|
||||
if test -x "$relpath/bin/licheck"; then
|
||||
LicheckOutput=`$relpath/bin/licheck $OPT_CONFIRM_LICENSE $relpath $outpath\
|
||||
if [ $UNAME_SYSTEM = "Linux" ]; then
|
||||
if file -L /bin/sh | grep -q "64-bit" ; then
|
||||
Licheck=licheck64
|
||||
else
|
||||
Licheck=licheck32
|
||||
fi
|
||||
elif [ $UNAME_SYSTEM = "Darwin" ]; then
|
||||
Licheck=licheck_mac
|
||||
else
|
||||
echo >&2 "Host operating system not supported by this edition of Qt."
|
||||
exit 1
|
||||
fi
|
||||
if [ -x "$relpath/bin/$Licheck" ]; then
|
||||
LicheckOutput=`$relpath/bin/$Licheck $OPT_CONFIRM_LICENSE $relpath $outpath\
|
||||
$PLATFORM $XPLATFORM`
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
|
|
@ -2974,7 +2986,7 @@ elif [ $COMMERCIAL_USER = "yes" ]; then
|
|||
echo
|
||||
echo "Error: This is the Open Source version of Qt."
|
||||
echo "If you want to use Enterprise features of Qt,"
|
||||
echo "information use the contact form at http://www.qt.io/contact-us"
|
||||
echo "use the contact form at http://www.qt.io/contact-us"
|
||||
echo "to purchase a license."
|
||||
echo
|
||||
exit 1
|
||||
|
|
@ -5346,6 +5358,14 @@ fi
|
|||
# auto-detect XInput2 support
|
||||
if [ "$CFG_XINPUT2" != "no" ]; then
|
||||
if compileTest x11/xinput2 "XInput2"; then
|
||||
if [ -n "$PKG_CONFIG" ] && $PKG_CONFIG --exists xi 2>/dev/null; then
|
||||
QMAKE_LIBXI_VERSION_MAJOR=`$PKG_CONFIG --modversion xi 2>/dev/null | cut -d . -f 1`
|
||||
QMAKE_LIBXI_VERSION_MINOR=`$PKG_CONFIG --modversion xi 2>/dev/null | cut -d . -f 2`
|
||||
QMAKE_LIBXI_VERSION_PATCH=`$PKG_CONFIG --modversion xi 2>/dev/null | cut -d . -f 3`
|
||||
QMakeVar set QMAKE_LIBXI_VERSION_MAJOR "$QMAKE_LIBXI_VERSION_MAJOR"
|
||||
QMakeVar set QMAKE_LIBXI_VERSION_MINOR "$QMAKE_LIBXI_VERSION_MINOR"
|
||||
QMakeVar set QMAKE_LIBXI_VERSION_PATCH "$QMAKE_LIBXI_VERSION_PATCH"
|
||||
fi
|
||||
CFG_XINPUT2=yes
|
||||
CFG_XINPUT=no
|
||||
else
|
||||
|
|
@ -6763,8 +6783,15 @@ QT_PATCH_VERSION = $QT_PATCH_VERSION
|
|||
QT_LIBINFIX = $QT_LIBINFIX
|
||||
QT_NAMESPACE = $QT_NAMESPACE
|
||||
|
||||
QT_EDITION = $Edition
|
||||
EOF
|
||||
|
||||
if [ "$Edition" != "OpenSource" ] && [ "$Edition" != "Preview" ]; then
|
||||
echo "QT_LICHECK = $Licheck" >> "$QTCONFIG.tmp"
|
||||
echo "QT_RELEASE_DATE = $ReleaseDate" >> "$QTCONFIG.tmp"
|
||||
fi
|
||||
echo >> "$QTCONFIG.tmp"
|
||||
|
||||
if [ "$CFG_SHARED" = "no" ]; then
|
||||
echo "QT_DEFAULT_QPA_PLUGIN = q$QT_QPA_DEFAULT_PLATFORM" >> "$QTCONFIG.tmp"
|
||||
echo >> "$QTCONFIG.tmp"
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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\")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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(';'));
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ enum DotNET {
|
|||
NET2008 = 0x90,
|
||||
NET2010 = 0xa0,
|
||||
NET2012 = 0xb0,
|
||||
NET2013 = 0xc0
|
||||
NET2013 = 0xc0,
|
||||
NET2015 = 0xd0
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
||||
|
|
|
|||
|
|
@ -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"/>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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}".
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 **);
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE
|
|||
QInputDeviceManager::QInputDeviceManager(QObject *parent)
|
||||
: QObject(*new QInputDeviceManagerPrivate, parent)
|
||||
{
|
||||
qRegisterMetaType<DeviceType>();
|
||||
}
|
||||
|
||||
int QInputDeviceManager::deviceCount(DeviceType type) const
|
||||
|
|
|
|||
|
|
@ -77,4 +77,6 @@ signals:
|
|||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
Q_DECLARE_METATYPE(QInputDeviceManager::DeviceType)
|
||||
|
||||
#endif // QINPUTDEVICEMANAGER_P_H
|
||||
|
|
|
|||
|
|
@ -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 ®ion) Q_DECL_OVERRIDE
|
||||
{
|
||||
Q_UNUSED(region);
|
||||
Q_Q(QOpenGLWindow);
|
||||
|
||||
if (!context) {
|
||||
context.reset(new QOpenGLContext);
|
||||
context->setShareContext(shareContext);
|
||||
context->setFormat(q->requestedFormat());
|
||||
context->setScreen(q->screen());
|
||||
if (!context->create())
|
||||
qWarning("QOpenGLWindow::beginPaint: Failed to create context");
|
||||
if (!context->makeCurrent(q))
|
||||
qWarning("QOpenGLWindow::beginPaint: Failed to make context current");
|
||||
|
||||
paintDevice.reset(new QOpenGLWindowPaintDevice(q));
|
||||
if (updateBehavior == QOpenGLWindow::PartialUpdateBlit)
|
||||
hasFboBlit = QOpenGLFramebufferObject::hasOpenGLFramebufferBlit();
|
||||
|
||||
q->initializeGL();
|
||||
} else {
|
||||
context->makeCurrent(q);
|
||||
}
|
||||
|
||||
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 ®ion) Q_DECL_OVERRIDE
|
||||
{
|
||||
Q_UNUSED(region);
|
||||
Q_Q(QOpenGLWindow);
|
||||
context->swapBuffers(q);
|
||||
emit q->frameSwapped();
|
||||
}
|
||||
void beginPaint(const QRegion ®ion) Q_DECL_OVERRIDE;
|
||||
void endPaint() Q_DECL_OVERRIDE;
|
||||
void flush(const QRegion ®ion) Q_DECL_OVERRIDE;
|
||||
|
||||
QOpenGLWindow::UpdateBehavior updateBehavior;
|
||||
bool hasFboBlit;
|
||||
|
|
@ -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 ®ion)
|
||||
{
|
||||
Q_UNUSED(region);
|
||||
Q_Q(QOpenGLWindow);
|
||||
|
||||
initialize();
|
||||
context->makeCurrent(q);
|
||||
|
||||
const int deviceWidth = q->width() * q->devicePixelRatio();
|
||||
const int deviceHeight = q->height() * q->devicePixelRatio();
|
||||
const QSize deviceSize(deviceWidth, deviceHeight);
|
||||
if (updateBehavior > QOpenGLWindow::NoPartialUpdate) {
|
||||
if (!fbo || fbo->size() != deviceSize) {
|
||||
QOpenGLFramebufferObjectFormat fboFormat;
|
||||
fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
|
||||
if (q->requestedFormat().samples() > 0) {
|
||||
if (updateBehavior != QOpenGLWindow::PartialUpdateBlend)
|
||||
fboFormat.setSamples(q->requestedFormat().samples());
|
||||
else
|
||||
qWarning("QOpenGLWindow: PartialUpdateBlend does not support multisampling");
|
||||
}
|
||||
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 ®ion)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -83,9 +83,10 @@ public:
|
|||
|
||||
struct QBackingstoreTextureInfo
|
||||
{
|
||||
QWidget *widget; // may be null
|
||||
void *source; // may be null
|
||||
GLuint textureId;
|
||||
QRect rect;
|
||||
QRect clipRect;
|
||||
QPlatformTextureList::Flags flags;
|
||||
};
|
||||
|
||||
|
|
@ -124,10 +125,10 @@ GLuint QPlatformTextureList::textureId(int index) const
|
|||
return d->textures.at(index).textureId;
|
||||
}
|
||||
|
||||
QWidget *QPlatformTextureList::widget(int index)
|
||||
void *QPlatformTextureList::source(int index)
|
||||
{
|
||||
Q_D(const QPlatformTextureList);
|
||||
return d->textures.at(index).widget;
|
||||
return d->textures.at(index).source;
|
||||
}
|
||||
|
||||
QPlatformTextureList::Flags QPlatformTextureList::flags(int index) const
|
||||
|
|
@ -142,6 +143,12 @@ QRect QPlatformTextureList::geometry(int index) const
|
|||
return d->textures.at(index).rect;
|
||||
}
|
||||
|
||||
QRect QPlatformTextureList::clipRect(int index) const
|
||||
{
|
||||
Q_D(const QPlatformTextureList);
|
||||
return d->textures.at(index).clipRect;
|
||||
}
|
||||
|
||||
void QPlatformTextureList::lock(bool on)
|
||||
{
|
||||
Q_D(QPlatformTextureList);
|
||||
|
|
@ -157,13 +164,15 @@ bool QPlatformTextureList::isLocked() const
|
|||
return d->locked;
|
||||
}
|
||||
|
||||
void QPlatformTextureList::appendTexture(QWidget *widget, GLuint textureId, const QRect &geometry, Flags flags)
|
||||
void QPlatformTextureList::appendTexture(void *source, GLuint textureId, const QRect &geometry,
|
||||
const QRect &clipRect, Flags flags)
|
||||
{
|
||||
Q_D(QPlatformTextureList);
|
||||
QBackingstoreTextureInfo bi;
|
||||
bi.widget = widget;
|
||||
bi.source = source;
|
||||
bi.textureId = textureId;
|
||||
bi.rect = geometry;
|
||||
bi.clipRect = clipRect;
|
||||
bi.flags = flags;
|
||||
d->textures.append(bi);
|
||||
}
|
||||
|
|
@ -198,7 +207,7 @@ void QPlatformTextureList::clear()
|
|||
|
||||
#ifndef QT_NO_OPENGL
|
||||
|
||||
static QRect deviceRect(const QRect &rect, QWindow *window)
|
||||
static inline QRect deviceRect(const QRect &rect, QWindow *window)
|
||||
{
|
||||
QRect deviceRect(rect.topLeft() * window->devicePixelRatio(),
|
||||
rect.size() * window->devicePixelRatio());
|
||||
|
|
@ -219,6 +228,32 @@ static QRegion deviceRegion(const QRegion ®ion, QWindow *window)
|
|||
return deviceRegion;
|
||||
}
|
||||
|
||||
static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
|
||||
{
|
||||
return QRect(topLeftRect.x(), windowHeight - topLeftRect.bottomRight().y() - 1,
|
||||
topLeftRect.width(), topLeftRect.height());
|
||||
}
|
||||
|
||||
static void blit(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect,
|
||||
QOpenGLTextureBlitter *blitter)
|
||||
{
|
||||
const QRect rectInWindow = textures->geometry(idx);
|
||||
QRect clipRect = textures->clipRect(idx);
|
||||
if (clipRect.isEmpty())
|
||||
clipRect = QRect(QPoint(0, 0), rectInWindow.size());
|
||||
const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
|
||||
const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
|
||||
|
||||
const QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(deviceRect(clippedRectInWindow, window),
|
||||
deviceWindowRect);
|
||||
|
||||
const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(deviceRect(srcRect, window),
|
||||
deviceRect(rectInWindow, window).size(),
|
||||
QOpenGLTextureBlitter::OriginBottomLeft);
|
||||
|
||||
blitter->blit(textures->textureId(idx), target, source);
|
||||
}
|
||||
|
||||
/*!
|
||||
Flushes the given \a region from the specified \a window onto the
|
||||
screen, and composes it with the specified \a textures.
|
||||
|
|
@ -254,15 +289,12 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i
|
|||
|
||||
d_ptr->blitter->bind();
|
||||
|
||||
QRect windowRect(QPoint(), window->size() * window->devicePixelRatio());
|
||||
const QRect deviceWindowRect = deviceRect(QRect(QPoint(), window->size()), window);
|
||||
|
||||
// Textures for renderToTexture widgets.
|
||||
for (int i = 0; i < textures->count(); ++i) {
|
||||
if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
|
||||
QRect targetRect = deviceRect(textures->geometry(i), window);
|
||||
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect);
|
||||
d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft);
|
||||
}
|
||||
if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
|
||||
blit(textures, i, window, deviceWindowRect, d_ptr->blitter);
|
||||
}
|
||||
|
||||
funcs->glEnable(GL_BLEND);
|
||||
|
|
@ -272,6 +304,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i
|
|||
// semi-transparency even when it is not wanted.
|
||||
funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||
|
||||
// Backingstore texture with the normal widgets.
|
||||
GLuint textureId = 0;
|
||||
QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft;
|
||||
if (QPlatformGraphicsBuffer *graphicsBuffer = this->graphicsBuffer()) {
|
||||
|
|
@ -307,7 +340,6 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i
|
|||
origin = QOpenGLTextureBlitter::OriginBottomLeft;
|
||||
textureId = d_ptr->textureId;
|
||||
} else {
|
||||
// Backingstore texture with the normal widgets.
|
||||
TextureFlags flags = 0;
|
||||
textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize, &flags);
|
||||
d_ptr->needsSwizzle = (flags & TextureSwizzle) != 0;
|
||||
|
|
@ -316,7 +348,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i
|
|||
}
|
||||
|
||||
if (textureId) {
|
||||
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), windowRect);
|
||||
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), deviceWindowRect);
|
||||
if (d_ptr->needsSwizzle)
|
||||
d_ptr->blitter->setSwizzleRB(true);
|
||||
d_ptr->blitter->blit(textureId, target, origin);
|
||||
|
|
@ -326,11 +358,8 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i
|
|||
|
||||
// Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
|
||||
for (int i = 0; i < textures->count(); ++i) {
|
||||
if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) {
|
||||
QRect targetRect = deviceRect(textures->geometry(i), window);
|
||||
QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(targetRect, windowRect);
|
||||
d_ptr->blitter->blit(textures->textureId(i), target, QOpenGLTextureBlitter::OriginBottomLeft);
|
||||
}
|
||||
if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
|
||||
blit(textures, i, window, deviceWindowRect, d_ptr->blitter);
|
||||
}
|
||||
|
||||
funcs->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ void QWindowsDirect2DWindow::present(const QRegion ®ion)
|
|||
const SIZE size = { bounds.width(), bounds.height() };
|
||||
const POINT ptDst = { bounds.x(), bounds.y() };
|
||||
const POINT ptSrc = { 0, 0 };
|
||||
const BLENDFUNCTION blend = { AC_SRC_OVER, 0, 255.0 * opacity(), AC_SRC_ALPHA };
|
||||
const BLENDFUNCTION blend = { AC_SRC_OVER, 0, BYTE(255.0 * opacity()), AC_SRC_ALPHA };
|
||||
const QRect r = region.boundingRect();
|
||||
const RECT dirty = { r.left(), r.top(), r.left() + r.width(), r.top() + r.height() };
|
||||
UPDATELAYEREDWINDOWINFO info = { sizeof(UPDATELAYEREDWINDOWINFO), NULL,
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -3658,6 +3658,7 @@ void QTreeViewPrivate::updateScrollBars()
|
|||
if (!viewportSize.isValid())
|
||||
viewportSize = QSize(0, 0);
|
||||
|
||||
executePostedLayout();
|
||||
if (viewItems.isEmpty()) {
|
||||
q->doItemsLayout();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue