Merge remote-tracking branch 'origin/5.6' into 5.7

Conflicts:
	examples/qtestlib/tutorial5/containers.cpp
	examples/widgets/tools/tools.pro
	src/corelib/io/qprocess.cpp
	src/corelib/io/qprocess_unix.cpp
	src/corelib/io/qprocess_win.cpp
	src/network/kernel/qdnslookup_unix.cpp
	src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
	src/testlib/qtestcase.cpp
	tools/configure/configureapp.cpp

Change-Id: I838ae7f082535a67a4a53aa13a21ba5580758be8
This commit is contained in:
Liang Qi 2016-05-06 09:07:18 +02:00
commit dbef41f43e
94 changed files with 699 additions and 658 deletions

1
.gitignore vendored
View File

@ -226,7 +226,6 @@ config.tests/unix/sse2/sse2
# --------------------- # ---------------------
debug debug
examples/tools/plugandpaint/plugins
include/* include/*
include/*/* include/*/*
lib/* lib/*

View File

@ -8,7 +8,7 @@ SOURCES = main.cpp \
QT += widgets QT += widgets
# install # install
target.path = $$[QT_INSTALL_EXAMPLES]/corelib/threads/mandelbrot target.path = $$[QT_INSTALL_EXAMPLES]/corelib/threads/queuedcustomtype
INSTALLS += target INSTALLS += target

View File

@ -54,8 +54,10 @@
#include <QWidget> #include <QWidget>
#include "renderthread.h" #include "renderthread.h"
QT_BEGIN_NAMESPACE
class QLabel; class QLabel;
class QPushButton; class QPushButton;
QT_END_NAMESPACE
//! [Window class definition] //! [Window class definition]
class Window : public QWidget class Window : public QWidget

View File

@ -4,4 +4,6 @@ CONFIG += no_docs_target
SUBDIRS = semaphores \ SUBDIRS = semaphores \
waitconditions waitconditions
qtHaveModule(widgets): SUBDIRS += mandelbrot qtHaveModule(widgets): SUBDIRS += \
mandelbrot \
queuedcustomtype

View File

@ -4,5 +4,5 @@ SOURCES = main.cpp \
QT += widgets QT += widgets
# install # install
target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customcompleter target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customtype
INSTALLS += target INSTALLS += target

View File

@ -6,5 +6,5 @@ SOURCES = main.cpp \
QT += widgets QT += widgets
# install # install
target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customcompleter target.path = $$[QT_INSTALL_EXAMPLES]/corelib/tools/customtypesending
INSTALLS += target INSTALLS += target

View File

@ -7,3 +7,7 @@ SOURCES += main.cpp \
HEADERS += widget.h \ HEADERS += widget.h \
renderwindow.h renderwindow.h
# install
target.path = $$[QT_INSTALL_EXAMPLES]/opengl/contextinfo
INSTALLS += target

View File

@ -16,3 +16,6 @@ qtHaveModule(widgets) {
textures \ textures \
hellogles3 hellogles3
} }
EXAMPLE_FILES += \
legacy

View File

@ -1,274 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
// This file contains benchmarks for comparing QVector against std::vector
#include <QtCore>
#include <QVector>
#include <vector>
#include <qtest.h>
template <typename T> // T is the item type
class UseCases {
public:
virtual ~UseCases() {}
// Use case: Insert \a size items into the vector.
virtual void insert(int size) = 0;
// Use case: Lookup \a size items from the vector.
virtual void lookup(int size) = 0;
};
template <typename T>
T * f(T *ts) // dummy function to prevent code from being optimized away by the compiler
{
return ts;
}
// This subclass implements the use cases using QVector as efficiently as possible.
template <typename T>
class UseCases_QVector : public UseCases<T>
{
void insert(int size)
{
QVector<T> v;
T t;
QBENCHMARK {
for (int i = 0; i < size; ++i)
v.append(t);
}
}
void lookup(int size)
{
QVector<T> v;
T t;
for (int i = 0; i < size; ++i)
v.append(t);
T *ts = new T[size];
QBENCHMARK {
for (int i = 0; i < size; ++i)
ts[i] = v.value(i);
}
f<T>(ts);
delete[] ts;
}
};
// This subclass implements the use cases using std::vector as efficiently as possible.
template <typename T>
class UseCases_stdvector : public UseCases<T>
{
void insert(int size)
{
std::vector<T> v;
T t;
QBENCHMARK {
for (int i = 0; i < size; ++i)
v.push_back(t);
}
}
void lookup(int size)
{
std::vector<T> v;
T t;
for (int i = 0; i < size; ++i)
v.push_back(t);
T *ts = new T[size];
QBENCHMARK {
for (int i = 0; i < size; ++i)
ts[i] = v[i];
}
f<T>(ts);
delete[] ts;
}
};
struct Large { // A "large" item type
int x[1000];
};
// Symbian devices typically have limited memory
# define LARGE_MAX_SIZE 20000
class tst_vector_vs_std : public QObject
{
Q_OBJECT
public:
tst_vector_vs_std()
{
useCases_QVector_int = new UseCases_QVector<int>;
useCases_stdvector_int = new UseCases_stdvector<int>;
useCases_QVector_Large = new UseCases_QVector<Large>;
useCases_stdvector_Large = new UseCases_stdvector<Large>;
}
private:
UseCases<int> *useCases_QVector_int;
UseCases<int> *useCases_stdvector_int;
UseCases<Large> *useCases_QVector_Large;
UseCases<Large> *useCases_stdvector_Large;
private slots:
void insert_int_data();
void insert_int();
void insert_Large_data();
void insert_Large();
void lookup_int_data();
void lookup_int();
void lookup_Large_data();
void lookup_Large();
};
void tst_vector_vs_std::insert_int_data()
{
QTest::addColumn<bool>("useStd");
QTest::addColumn<int>("size");
for (int size = 10; size < 20000; size += 100) {
const QByteArray sizeString = QByteArray::number(size);
QTest::newRow(("std::vector-int--" + sizeString).constData()) << true << size;
QTest::newRow(("QVector-int--" + sizeString).constData()) << false << size;
}
}
void tst_vector_vs_std::insert_int()
{
QFETCH(bool, useStd);
QFETCH(int, size);
if (useStd)
useCases_stdvector_int->insert(size);
else
useCases_QVector_int->insert(size);
}
void tst_vector_vs_std::insert_Large_data()
{
QTest::addColumn<bool>("useStd");
QTest::addColumn<int>("size");
for (int size = 10; size < LARGE_MAX_SIZE; size += 100) {
const QByteArray sizeString = QByteArray::number(size);
QTest::newRow(("std::vector-Large--" + sizeString).constData()) << true << size;
QTest::newRow(("QVector-Large--" + sizeString).constData()) << false << size;
}
}
void tst_vector_vs_std::insert_Large()
{
QFETCH(bool, useStd);
QFETCH(int, size);
if (useStd)
useCases_stdvector_Large->insert(size);
else
useCases_QVector_Large->insert(size);
}
//! [1]
void tst_vector_vs_std::lookup_int_data()
{
QTest::addColumn<bool>("useStd");
QTest::addColumn<int>("size");
for (int size = 10; size < 20000; size += 100) {
const QByteArray sizeString = QByteArray::number(size);
QTest::newRow(("std::vector-int--" + sizeString).constData()) << true << size;
QTest::newRow(("QVector-int--" + sizeString).constData()) << false << size;
}
}
//! [1]
//! [2]
void tst_vector_vs_std::lookup_int()
{
QFETCH(bool, useStd);
QFETCH(int, size);
if (useStd)
useCases_stdvector_int->lookup(size); // Create a std::vector and run the benchmark.
else
useCases_QVector_int->lookup(size); // Create a QVector and run the benchmark.
}
//! [2]
void tst_vector_vs_std::lookup_Large_data()
{
QTest::addColumn<bool>("useStd");
QTest::addColumn<int>("size");
for (int size = 10; size < LARGE_MAX_SIZE; size += 100) {
const QByteArray sizeString = QByteArray::number(size);
QTest::newRow(("std::vector-Large--" + sizeString).constData()) << true << size;
QTest::newRow(("QVector-Large--" + sizeString).constData()) << false << size;
}
}
void tst_vector_vs_std::lookup_Large()
{
QFETCH(bool, useStd);
QFETCH(int, size);
if (useStd)
useCases_stdvector_Large->lookup(size);
else
useCases_QVector_Large->lookup(size);
}
QTEST_MAIN(tst_vector_vs_std)
#include "main.moc"

View File

@ -26,7 +26,7 @@
****************************************************************************/ ****************************************************************************/
/*! /*!
\example tools/plugandpaint \example tools/plugandpaint/app
\title Plug & Paint Example \title Plug & Paint Example
\ingroup examples-widgets-tools \ingroup examples-widgets-tools
@ -47,8 +47,8 @@
through plugins, we recommend that you start by reading this through plugins, we recommend that you start by reading this
overview, which explains how to make an application use plugins. overview, which explains how to make an application use plugins.
Afterwards, you can read the Afterwards, you can read the
\l{tools/plugandpaintplugins/basictools}{Basic Tools} and \l{tools/plugandpaint/plugins/basictools}{Basic Tools} and
\l{tools/plugandpaintplugins/extrafilters}{Extra Filters} \l{tools/plugandpaint/plugins/extrafilters}{Extra Filters}
overviews, which show how to implement static and dynamic overviews, which show how to implement static and dynamic
plugins, respectively. plugins, respectively.
@ -74,7 +74,7 @@
in the plugins. in the plugins.
\snippet tools/plugandpaint/interfaces.h 0 \snippet tools/plugandpaint/app/interfaces.h 0
The \c BrushInterface class declares four pure virtual functions. The \c BrushInterface class declares four pure virtual functions.
The first pure virtual function, \c brushes(), returns a list of The first pure virtual function, \c brushes(), returns a list of
@ -96,7 +96,7 @@
virtual destructor. We provide the destructor to keep these virtual destructor. We provide the destructor to keep these
compilers happy. compilers happy.
\snippet tools/plugandpaint/interfaces.h 1 \snippet tools/plugandpaint/app/interfaces.h 1
The \c ShapeInterface class declares a \c shapes() function that The \c ShapeInterface class declares a \c shapes() function that
works the same as \c{BrushInterface}'s \c brushes() function, and works the same as \c{BrushInterface}'s \c brushes() function, and
@ -106,13 +106,13 @@
parent parameter can be used by the plugin to pop up a dialog parent parameter can be used by the plugin to pop up a dialog
asking the user to specify more information. asking the user to specify more information.
\snippet tools/plugandpaint/interfaces.h 2 \snippet tools/plugandpaint/app/interfaces.h 2
The \c FilterInterface class declares a \c filters() function The \c FilterInterface class declares a \c filters() function
that returns a list of filter names, and a \c filterImage() that returns a list of filter names, and a \c filterImage()
function that applies a filter to an image. function that applies a filter to an image.
\snippet tools/plugandpaint/interfaces.h 4 \snippet tools/plugandpaint/app/interfaces.h 4
To make it possible to query at run-time whether a plugin To make it possible to query at run-time whether a plugin
implements a given interface, we must use the \c implements a given interface, we must use the \c
@ -125,8 +125,8 @@
a good idea to include a version number in the string, as we did a good idea to include a version number in the string, as we did
above. above.
The \l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin The \l{tools/plugandpaint/plugins/basictools}{Basic Tools} plugin
and the \l{tools/plugandpaintplugins/extrafilters}{Extra Filters} and the \l{tools/plugandpaint/plugins/extrafilters}{Extra Filters}
plugin shows how to derive from \c BrushInterface, \c plugin shows how to derive from \c BrushInterface, \c
ShapeInterface, and \c FilterInterface. ShapeInterface, and \c FilterInterface.
@ -144,7 +144,7 @@
\l{mainwindows/application}{Application}). Here, we'll \l{mainwindows/application}{Application}). Here, we'll
concentrate on the parts of the code that are related to plugins. concentrate on the parts of the code that are related to plugins.
\snippet tools/plugandpaint/mainwindow.cpp 4 \snippet tools/plugandpaint/app/mainwindow.cpp 4
The \c loadPlugins() function is called from the \c MainWindow The \c loadPlugins() function is called from the \c MainWindow
constructor to detect plugins and update the \uicontrol{Brush}, constructor to detect plugins and update the \uicontrol{Brush},
@ -155,7 +155,7 @@
QObject. That QObject implements plugin interfaces using multiple QObject. That QObject implements plugin interfaces using multiple
inheritance. inheritance.
\snippet tools/plugandpaint/mainwindow.cpp 5 \snippet tools/plugandpaint/app/mainwindow.cpp 5
The next step is to load dynamic plugins. We initialize the \c The next step is to load dynamic plugins. We initialize the \c
pluginsDir member variable to refer to the \c plugins pluginsDir member variable to refer to the \c plugins
@ -166,9 +166,9 @@
this file is usually located in a subdirectory, so we need to this file is usually located in a subdirectory, so we need to
take this into account. take this into account.
\snippet tools/plugandpaint/mainwindow.cpp 6 \snippet tools/plugandpaint/app/mainwindow.cpp 6
\snippet tools/plugandpaint/mainwindow.cpp 7 \snippet tools/plugandpaint/app/mainwindow.cpp 7
\snippet tools/plugandpaint/mainwindow.cpp 8 \snippet tools/plugandpaint/app/mainwindow.cpp 8
We use QDir::entryList() to get a list of all files in that We use QDir::entryList() to get a list of all files in that
directory. Then we iterate over the result using \l foreach and directory. Then we iterate over the result using \l foreach and
@ -181,12 +181,12 @@
If QPluginLoader::instance() is non-null, we add it to the menus. If QPluginLoader::instance() is non-null, we add it to the menus.
\snippet tools/plugandpaint/mainwindow.cpp 9 \snippet tools/plugandpaint/app/mainwindow.cpp 9
At the end, we enable or disable the \uicontrol{Brush}, \uicontrol{Shapes}, At the end, we enable or disable the \uicontrol{Brush}, \uicontrol{Shapes},
and \uicontrol{Filters} menus based on whether they contain any items. and \uicontrol{Filters} menus based on whether they contain any items.
\snippet tools/plugandpaint/mainwindow.cpp 10 \snippet tools/plugandpaint/app/mainwindow.cpp 10
For each plugin (static or dynamic), we check which interfaces it For each plugin (static or dynamic), we check which interfaces it
implements using \l qobject_cast(). First, we try to cast the implements using \l qobject_cast(). First, we try to cast the
@ -195,7 +195,7 @@
by \c brushes(). Then we do the same with the \c ShapeInterface by \c brushes(). Then we do the same with the \c ShapeInterface
and the \c FilterInterface. and the \c FilterInterface.
\snippet tools/plugandpaint/mainwindow.cpp 3 \snippet tools/plugandpaint/app/mainwindow.cpp 3
The \c aboutPlugins() slot is called on startup and can be The \c aboutPlugins() slot is called on startup and can be
invoked at any time through the \uicontrol{About Plugins} action. It invoked at any time through the \uicontrol{About Plugins} action. It
@ -211,7 +211,7 @@
plugin from which it comes from as the parent; this makes it plugin from which it comes from as the parent; this makes it
convenient to get access to the plugin later. convenient to get access to the plugin later.
\snippet tools/plugandpaint/mainwindow.cpp 0 \snippet tools/plugandpaint/app/mainwindow.cpp 0
The \c changeBrush() slot is invoked when the user chooses one of The \c changeBrush() slot is invoked when the user chooses one of
the brushes from the \uicontrol{Brush} menu. We start by finding out the brushes from the \uicontrol{Brush} menu. We start by finding out
@ -222,7 +222,7 @@
identifying the brush. Next time the user draws on the paint identifying the brush. Next time the user draws on the paint
area, \c PaintArea will use this brush. area, \c PaintArea will use this brush.
\snippet tools/plugandpaint/mainwindow.cpp 1 \snippet tools/plugandpaint/app/mainwindow.cpp 1
The \c insertShape() is invoked when the use chooses one of the The \c insertShape() is invoked when the use chooses one of the
shapes from the \uicontrol{Shapes} menu. We retrieve the QAction that shapes from the \uicontrol{Shapes} menu. We retrieve the QAction that
@ -230,7 +230,7 @@
QAction, and finally we call \c ShapeInterface::generateShape() QAction, and finally we call \c ShapeInterface::generateShape()
to obtain a QPainterPath. to obtain a QPainterPath.
\snippet tools/plugandpaint/mainwindow.cpp 2 \snippet tools/plugandpaint/app/mainwindow.cpp 2
The \c applyFilter() slot is similar: We retrieve the QAction The \c applyFilter() slot is similar: We retrieve the QAction
that invoked the slot, then the \c FilterInterface associated to that invoked the slot, then the \c FilterInterface associated to
@ -243,12 +243,12 @@
The \c PaintArea class contains some code that deals with \c The \c PaintArea class contains some code that deals with \c
BrushInterface, so we'll review it briefly. BrushInterface, so we'll review it briefly.
\snippet tools/plugandpaint/paintarea.cpp 0 \snippet tools/plugandpaint/app/paintarea.cpp 0
In \c setBrush(), we simply store the \c BrushInterface and the In \c setBrush(), we simply store the \c BrushInterface and the
brush that are given to us by \c MainWindow. brush that are given to us by \c MainWindow.
\snippet tools/plugandpaint/paintarea.cpp 1 \snippet tools/plugandpaint/app/paintarea.cpp 1
In the \l{QWidget::mouseMoveEvent()}{mouse move event handler}, In the \l{QWidget::mouseMoveEvent()}{mouse move event handler},
we call the \c BrushInterface::mouseMove() function on the we call the \c BrushInterface::mouseMove() function on the
@ -262,7 +262,7 @@
and a list of plugin file names. It calls \c findPlugins() and a list of plugin file names. It calls \c findPlugins()
to fill the QTreeWdiget with information about the plugins: to fill the QTreeWdiget with information about the plugins:
\snippet tools/plugandpaint/plugindialog.cpp 0 \snippet tools/plugandpaint/app/plugindialog.cpp 0
The \c findPlugins() is very similar to \c The \c findPlugins() is very similar to \c
MainWindow::loadPlugins(). It uses QPluginLoader to access the MainWindow::loadPlugins(). It uses QPluginLoader to access the
@ -270,11 +270,11 @@
populateTreeWidget() uses \l qobject_cast() to find out which populateTreeWidget() uses \l qobject_cast() to find out which
interfaces are implemented by the plugins: interfaces are implemented by the plugins:
\snippet tools/plugandpaint/plugindialog.cpp 1 \snippet tools/plugandpaint/app/plugindialog.cpp 1
\section1 Importing Static Plugins \section1 Importing Static Plugins
The \l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin The \l{tools/plugandpaint/plugins/basictools}{Basic Tools} plugin
is built as a static plugin, to ensure that it is always is built as a static plugin, to ensure that it is always
available to the application. This requires using the available to the application. This requires using the
Q_IMPORT_PLUGIN() macro somewhere in the application (in a \c Q_IMPORT_PLUGIN() macro somewhere in the application (in a \c
@ -283,7 +283,7 @@
For Plug & Paint, we have chosen to put Q_IMPORT_PLUGIN() in \c For Plug & Paint, we have chosen to put Q_IMPORT_PLUGIN() in \c
main.cpp: main.cpp:
\snippet tools/plugandpaint/main.cpp 0 \snippet tools/plugandpaint/app/main.cpp 0
The argument to Q_IMPORT_PLUGIN() is the plugin name, which corresponds The argument to Q_IMPORT_PLUGIN() is the plugin name, which corresponds
with the name of the class that declares metadata for the plugin with with the name of the class that declares metadata for the plugin with
@ -292,10 +292,10 @@
In the \c .pro file, we need to specify the static library. In the \c .pro file, we need to specify the static library.
Here's the project file for building Plug & Paint: Here's the project file for building Plug & Paint:
\snippet tools/plugandpaint/plugandpaint.pro 0 \snippet tools/plugandpaint/app/app.pro 0
The \c LIBS line variable specifies the library \c pnp_basictools The \c LIBS line variable specifies the library \c pnp_basictools
located in the \c ../plugandpaintplugins/basictools directory. located in the \c ../plugandpaint/plugins/basictools directory.
(Although the \c LIBS syntax has a distinct Unix flavor, \c qmake (Although the \c LIBS syntax has a distinct Unix flavor, \c qmake
supports it on all platforms.) supports it on all platforms.)
@ -306,19 +306,19 @@
This completes our review of the Plug & Paint application. At This completes our review of the Plug & Paint application. At
this point, you might want to take a look at the this point, you might want to take a look at the
\l{tools/plugandpaintplugins/basictools}{Basic Tools} example \l{tools/plugandpaint/plugins/basictools}{Basic Tools} example
plugin. plugin.
*/ */
/*! /*!
\example tools/plugandpaintplugins/basictools \example tools/plugandpaint/plugins/basictools
\title Plug & Paint Basic Tools Example \title Plug & Paint Basic Tools Example
\brief A plugin providing the basic tools for painting functionality. \brief A plugin providing the basic tools for painting functionality.
\image plugandpaint.png Screenshot of the Plug & Paint example \image plugandpaint.png Screenshot of the Plug & Paint example
The Basic Tools example is a static plugin for the The Basic Tools example is a static plugin for the
\l{tools/plugandpaint}{Plug & Paint} example. It provides a set \l{tools/plugandpaint/app}{Plug & Paint} example. It provides a set
of basic brushes, shapes, and filters. Through the Basic Tools of basic brushes, shapes, and filters. Through the Basic Tools
example, we will review the four steps involved in writing a Qt example, we will review the four steps involved in writing a Qt
plugin: plugin:
@ -332,13 +332,13 @@
\section1 Declaration of the Plugin Class \section1 Declaration of the Plugin Class
\snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 0 \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.h 0
We start by including \c interfaces.h, which defines the plugin We start by including \c interfaces.h, which defines the plugin
interfaces for the \l{tools/plugandpaint}{Plug & Paint} interfaces for the \l{tools/plugandpaint/app}{Plug & Paint}
application. For the \c #include to work, we need to add an \c application. For the \c #include to work, we need to add an \c
INCLUDEPATH entry to the \c .pro file with the path to Qt's \c INCLUDEPATH entry to the \c .pro file with the path to the
examples/tools directory. header file.
The \c BasicToolsPlugin class is a QObject subclass that The \c BasicToolsPlugin class is a QObject subclass that
implements the \c BrushInterface, the \c ShapeInterface, and the implements the \c BrushInterface, the \c ShapeInterface, and the
@ -346,12 +346,12 @@
The \c Q_INTERFACES() macro is necessary to tell \l{moc}, Qt's The \c Q_INTERFACES() macro is necessary to tell \l{moc}, Qt's
meta-object compiler, that the base classes are plugin meta-object compiler, that the base classes are plugin
interfaces. Without the \c Q_INTERFACES() macro, we couldn't use interfaces. Without the \c Q_INTERFACES() macro, we couldn't use
\l qobject_cast() in the \l{tools/plugandpaint}{Plug & Paint} \l qobject_cast() in the \l{tools/plugandpaint/app}{Plug & Paint}
application to detect interfaces. application to detect interfaces.
For an explanation for the \c Q_PLUGIN_METADATA() macro see For an explanation for the \c Q_PLUGIN_METADATA() macro see
\l {Exporting the Plugin}. \l {Exporting the Plugin}.
\snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 2 \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.h 2
In the \c public section of the class, we declare all the In the \c public section of the class, we declare all the
functions from the three interfaces. functions from the three interfaces.
@ -361,23 +361,23 @@
Let's now review the implementation of the \c BasicToolsPlugin Let's now review the implementation of the \c BasicToolsPlugin
member functions inherited from \c BrushInterface. member functions inherited from \c BrushInterface.
\snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 0 \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 0
The \c brushes() function returns a list of brushes provided by The \c brushes() function returns a list of brushes provided by
this plugin. We provide three brushes: \uicontrol{Pencil}, \uicontrol{Air this plugin. We provide three brushes: \uicontrol{Pencil}, \uicontrol{Air
Brush}, and \uicontrol{Random Letters}. Brush}, and \uicontrol{Random Letters}.
\snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 1 \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 1
On a mouse press event, we just call \c mouseMove() to draw the On a mouse press event, we just call \c mouseMove() to draw the
spot where the event occurred. spot where the event occurred.
\snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 2 \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 2
In \c mouseMove(), we start by saving the state of the QPainter In \c mouseMove(), we start by saving the state of the QPainter
and we compute a few variables that we'll need later. and we compute a few variables that we'll need later.
\snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 3 \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 3
Then comes the brush-dependent part of the code: Then comes the brush-dependent part of the code:
@ -399,14 +399,14 @@
At the end, we restore the painter state to what it was upon At the end, we restore the painter state to what it was upon
entering the function and we return the bounding rectangle. entering the function and we return the bounding rectangle.
\snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 4 \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 4
When the user releases the mouse, we do nothing and return an When the user releases the mouse, we do nothing and return an
empty QRect. empty QRect.
\section1 Implementation of the Shape Interface \section1 Implementation of the Shape Interface
\snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 5 \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 5
The plugin provides three shapes: \uicontrol{Circle}, \uicontrol{Star}, and The plugin provides three shapes: \uicontrol{Circle}, \uicontrol{Star}, and
\uicontrol{Text...}. The three dots after \uicontrol{Text} are there because \uicontrol{Text...}. The three dots after \uicontrol{Text} are there because
@ -418,7 +418,7 @@
distinguish between the internal shape name and the name used in distinguish between the internal shape name and the name used in
the user interface. the user interface.
\snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 6 \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 6
The \c generateShape() creates a QPainterPath for the specified The \c generateShape() creates a QPainterPath for the specified
shape. If the shape is \uicontrol{Text}, we pop up a QInputDialog to shape. If the shape is \uicontrol{Text}, we pop up a QInputDialog to
@ -426,12 +426,12 @@
\section1 Implementation of the Filter Interface \section1 Implementation of the Filter Interface
\snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 7 \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 7
The plugin provides three filters: \uicontrol{Invert Pixels}, \uicontrol{Swap The plugin provides three filters: \uicontrol{Invert Pixels}, \uicontrol{Swap
RGB}, and \uicontrol{Grayscale}. RGB}, and \uicontrol{Grayscale}.
\snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 8 \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.cpp 8
The \c filterImage() function takes a filter name and a QImage as The \c filterImage() function takes a filter name and a QImage as
parameters and returns an altered QImage. The first thing we do parameters and returns an altered QImage. The first thing we do
@ -450,7 +450,7 @@
It must contain the plugins IID and optionally a filename pointing It must contain the plugins IID and optionally a filename pointing
to a json file containing the metadata for the plugin. to a json file containing the metadata for the plugin.
\snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 4 \snippet tools/plugandpaint/plugins/basictools/basictoolsplugin.h 4
Within this example the json file does not need to export any metadata, Within this example the json file does not need to export any metadata,
so it just contains an empty json object. so it just contains an empty json object.
@ -463,7 +463,7 @@
Here's the project file for building the Basic Tools plugin: Here's the project file for building the Basic Tools plugin:
\snippet tools/plugandpaintplugins/basictools/basictools.pro 0 \snippet tools/plugandpaint/plugins/basictools/basictools.pro 0
The \c .pro file differs from typical \c .pro files in many The \c .pro file differs from typical \c .pro files in many
respects. First, it starts with a \c TEMPLATE entry specifying \c respects. First, it starts with a \c TEMPLATE entry specifying \c
@ -475,15 +475,14 @@
To make the plugin a static plugin, all that is required is to To make the plugin a static plugin, all that is required is to
specify \c static in addition to \c plugin. The specify \c static in addition to \c plugin. The
\l{tools/plugandpaintplugins/extrafilters}{Extra Filters} plugin, \l{tools/plugandpaint/plugins/extrafilters}{Extra Filters} plugin,
which is compiled as a dynamic plugin, doesn't specify \c static which is compiled as a dynamic plugin, doesn't specify \c static
in its \c .pro file. in its \c .pro file.
The \c INCLUDEPATH variable sets the search paths for global The \c INCLUDEPATH variable sets the search paths for global
headers (i.e., header files included using \c{#include <...>}). headers (i.e., header files included using \c{#include <...>}).
We add Qt's \c examples/tools directory (strictly speaking, We add \c ../../app to the list, so that we can include
\c{examples/tools/plugandpaintplugins/basictools/../..}) to the \c <interfaces.h>.
list, so that we can include \c <plugandpaint/interfaces.h>.
The \c TARGET variable specifies which name we want to give the The \c TARGET variable specifies which name we want to give the
target library. We use \c pnp_ as the prefix to show that the target library. We use \c pnp_ as the prefix to show that the
@ -499,27 +498,27 @@
*/ */
/*! /*!
\example tools/plugandpaintplugins/extrafilters \example tools/plugandpaint/plugins/extrafilters
\title Plug & Paint Extra Filters Example \title Plug & Paint Extra Filters Example
\brief A plugin providing the extra filters. \brief A plugin providing the extra filters.
\image plugandpaint.png Screenshot of the Plug & Paint example \image plugandpaint.png Screenshot of the Plug & Paint example
The Extra Filters example is a plugin for the The Extra Filters example is a plugin for the
\l{tools/plugandpaint}{Plug & Paint} example. It provides a set \l{tools/plugandpaint/app}{Plug & Paint} example. It provides a set
of filters in addition to those provided by the of filters in addition to those provided by the
\l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin. \l{tools/plugandpaint/plugins/basictools}{Basic Tools} plugin.
Since the approach is identical to Since the approach is identical to
\l{tools/plugandpaintplugins/basictools}{Basic Tools}, we won't \l{tools/plugandpaint/plugins/basictools}{Basic Tools}, we won't
review the code here. The only part of interest is the review the code here. The only part of interest is the
\c .pro file, since Extra Filters is a dynamic plugin \c .pro file, since Extra Filters is a dynamic plugin
(\l{tools/plugandpaintplugins/basictools}{Basic Tools} is (\l{tools/plugandpaint/plugins/basictools}{Basic Tools} is
linked statically into the Plug & Paint executable). linked statically into the Plug & Paint executable).
Here's the project file for building the Extra Filters plugin: Here's the project file for building the Extra Filters plugin:
\snippet tools/plugandpaintplugins/extrafilters/extrafilters.pro 0 \snippet tools/plugandpaint/plugins/extrafilters/extrafilters.pro 0
The \c .pro file differs from typical \c .pro files in many The \c .pro file differs from typical \c .pro files in many
respects. First, it starts with a \c TEMPLATE entry specifying \c respects. First, it starts with a \c TEMPLATE entry specifying \c
@ -531,9 +530,8 @@
The \c INCLUDEPATH variable sets the search paths for global The \c INCLUDEPATH variable sets the search paths for global
headers (i.e., header files included using \c{#include <...>}). headers (i.e., header files included using \c{#include <...>}).
We add Qt's \c examples/tools directory (strictly speaking, We add \c ../../app to the list, so that we can include
\c{examples/tools/plugandpaintplugins/basictools/../..}) to the \c <interfaces.h>.
list, so that we can include \c <plugandpaint/interfaces.h>.
The \c TARGET variable specifies which name we want to give the The \c TARGET variable specifies which name we want to give the
target library. We use \c pnp_ as the prefix to show that the target library. We use \c pnp_ as the prefix to show that the

View File

@ -5,3 +5,7 @@ SOURCES += storagemodel.cpp \
main.cpp main.cpp
HEADERS += \ HEADERS += \
storagemodel.h storagemodel.h
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/itemviews/storageview
INSTALLS += target

View File

@ -3,7 +3,3 @@ TEMPLATE = subdirs
SUBDIRS = echowindow \ SUBDIRS = echowindow \
plugin plugin
#! [0] #! [0]
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin
INSTALLS += target

View File

@ -17,3 +17,5 @@ win32 {
# install # install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin
INSTALLS += target INSTALLS += target
CONFIG += install_ok # Do not cargo-cult this!

View File

@ -12,5 +12,7 @@ DESTDIR = ../plugins
EXAMPLE_FILES = echoplugin.json EXAMPLE_FILES = echoplugin.json
# install # install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin/plugin target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin/plugins
INSTALLS += target INSTALLS += target
CONFIG += install_ok # Do not cargo-cult this!

View File

@ -0,0 +1,28 @@
#! [0]
TARGET = plugandpaint
DESTDIR = ..
QT += widgets
HEADERS = interfaces.h \
mainwindow.h \
paintarea.h \
plugindialog.h
SOURCES = main.cpp \
mainwindow.cpp \
paintarea.cpp \
plugindialog.cpp
LIBS = -L../plugins -lpnp_basictools
if(!debug_and_release|build_pass):CONFIG(debug, debug|release) {
mac:LIBS = $$member(LIBS, 0) $$member(LIBS, 1)_debug
win32:LIBS = $$member(LIBS, 0) $$member(LIBS, 1)d
}
#! [0]
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint
INSTALLS += target
CONFIG += install_ok # Do not cargo-cult this!

View File

@ -1,23 +1,4 @@
#! [0] TEMPLATE = subdirs
QT += widgets SUBDIRS = plugins app
HEADERS = interfaces.h \ app.depends = plugins
mainwindow.h \
paintarea.h \
plugindialog.h
SOURCES = main.cpp \
mainwindow.cpp \
paintarea.cpp \
plugindialog.cpp
LIBS = -Lplugins -lpnp_basictools
if(!debug_and_release|build_pass):CONFIG(debug, debug|release) {
mac:LIBS = $$member(LIBS, 0) $$member(LIBS, 1)_debug
win32:LIBS = $$member(LIBS, 0) $$member(LIBS, 1)d
}
#! [0]
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint
INSTALLS += target

View File

@ -2,13 +2,15 @@
TEMPLATE = lib TEMPLATE = lib
CONFIG += plugin static CONFIG += plugin static
QT += widgets QT += widgets
INCLUDEPATH += ../.. INCLUDEPATH += ../../app
HEADERS = basictoolsplugin.h HEADERS = basictoolsplugin.h
SOURCES = basictoolsplugin.cpp SOURCES = basictoolsplugin.cpp
TARGET = $$qtLibraryTarget(pnp_basictools) TARGET = $$qtLibraryTarget(pnp_basictools)
DESTDIR = ../../plugandpaint/plugins DESTDIR = ../../plugins
#! [0] #! [0]
# install # install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint/plugins target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint/plugins
INSTALLS += target INSTALLS += target
CONFIG += install_ok # Do not cargo-cult this!

View File

@ -51,6 +51,9 @@
#ifndef BASICTOOLSPLUGIN_H #ifndef BASICTOOLSPLUGIN_H
#define BASICTOOLSPLUGIN_H #define BASICTOOLSPLUGIN_H
//! [0]
#include <interfaces.h>
#include <QRect> #include <QRect>
#include <QObject> #include <QObject>
#include <QtPlugin> #include <QtPlugin>
@ -58,9 +61,6 @@
#include <QPainterPath> #include <QPainterPath>
#include <QImage> #include <QImage>
//! [0]
#include <plugandpaint/interfaces.h>
//! [1] //! [1]
class BasicToolsPlugin : public QObject, class BasicToolsPlugin : public QObject,
public BrushInterface, public BrushInterface,

View File

@ -2,13 +2,15 @@
TEMPLATE = lib TEMPLATE = lib
CONFIG += plugin CONFIG += plugin
QT += widgets QT += widgets
INCLUDEPATH += ../.. INCLUDEPATH += ../../app
HEADERS = extrafiltersplugin.h HEADERS = extrafiltersplugin.h
SOURCES = extrafiltersplugin.cpp SOURCES = extrafiltersplugin.cpp
TARGET = $$qtLibraryTarget(pnp_extrafilters) TARGET = $$qtLibraryTarget(pnp_extrafilters)
DESTDIR = ../../plugandpaint/plugins DESTDIR = ../../plugins
#! [0] #! [0]
# install # install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint/plugins target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/plugandpaint/plugins
INSTALLS += target INSTALLS += target
CONFIG += install_ok # Do not cargo-cult this!

View File

@ -52,13 +52,13 @@
#define EXTRAFILTERSPLUGIN_H #define EXTRAFILTERSPLUGIN_H
//! [0] //! [0]
#include <interfaces.h>
#include <QObject> #include <QObject>
#include <QtPlugin> #include <QtPlugin>
#include <QStringList> #include <QStringList>
#include <QImage> #include <QImage>
#include <plugandpaint/interfaces.h>
class ExtraFiltersPlugin : public QObject, public FilterInterface class ExtraFiltersPlugin : public QObject, public FilterInterface
{ {
Q_OBJECT Q_OBJECT

View File

@ -20,3 +20,5 @@ EXAMPLE_FILES += simplestyle.json
# install # install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/styleplugin/styles target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/styleplugin/styles
INSTALLS += target INSTALLS += target
CONFIG += install_ok # Do not cargo-cult this!

View File

@ -1,7 +1,3 @@
TEMPLATE = subdirs TEMPLATE = subdirs
SUBDIRS = stylewindow \ SUBDIRS = stylewindow \
plugin plugin
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/styleplugin
INSTALLS += target

View File

@ -15,3 +15,5 @@ win32 {
# install # install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/styleplugin target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/styleplugin
INSTALLS += target INSTALLS += target
CONFIG += install_ok # Do not cargo-cult this!

View File

@ -5,7 +5,6 @@ SUBDIRS = \
customcompleter \ customcompleter \
echoplugin \ echoplugin \
i18n \ i18n \
plugandpaintplugins \
plugandpaint \ plugandpaint \
regexp \ regexp \
regularexpression \ regularexpression \
@ -17,12 +16,9 @@ SUBDIRS = \
contains(DEFINES, QT_NO_TRANSLATION): SUBDIRS -= i18n contains(DEFINES, QT_NO_TRANSLATION): SUBDIRS -= i18n
plugandpaint.depends = plugandpaintplugins
load(qfeatures) load(qfeatures)
contains(QT_DISABLED_FEATURES, library) { contains(QT_DISABLED_FEATURES, library) {
SUBDIRS -= \ SUBDIRS -= \
echoplugin \ echoplugin \
plugandpaintplugins \
plugandpaint plugandpaint
} }

View File

@ -18,13 +18,24 @@ defineReplace(qtStripProPwd) {
for (cp, COPIES) { for (cp, COPIES) {
isEmpty($${cp}.files): next() isEmpty($${cp}.files): next()
pfx = copy_$${cp} pfx = copy_$${cp}
for (f, $${cp}.files): \ notdir = false
$${pfx}.files += $$absolute_path($$f, $$_PRO_FILE_PWD_) dir = false
for (f, $${cp}.files) {
fil = $$absolute_path($$f, $$_PRO_FILE_PWD_)
tfiles = $$files($$fil/*)
isEmpty(tfiles): \
notdir = true
else: \
dir = true
$${pfx}.files += $$fil
}
$$dir:$$notdir: \
error("COPIES entry $$cp lists both files and directories.")
path = $$eval($${cp}.path) path = $$eval($${cp}.path)
isEmpty(path): error("COPY $cp defines no .path") isEmpty(path): error("COPIES entry $$cp defines no .path")
base = $$eval($${cp}.base) base = $$eval($${cp}.base)
isEmpty(base) { isEmpty(base) {
$${pfx}.output = $$path/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT} $${pfx}.output = $$path/${QMAKE_FILE_IN_NAME}
} else: isEqual(base, $$_PRO_FILE_PWD_) { } else: isEqual(base, $$_PRO_FILE_PWD_) {
$${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripProPwd} $${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripProPwd}
} else { } else {
@ -34,7 +45,12 @@ for (cp, COPIES) {
$${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripSrcDir_$$cp} $${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripSrcDir_$$cp}
} }
$${pfx}.input = $${pfx}.files $${pfx}.input = $${pfx}.files
$${pfx}.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} !$$dir: \
$${pfx}.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT_PATH}
else: !copy_dir_files: \
$${pfx}.commands = $$QMAKE_COPY_DIR ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT_PATH}
else: \
$${pfx}.commands = $$QMAKE_COPY_DIR ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
$${pfx}.name = COPY ${QMAKE_FILE_IN} $${pfx}.name = COPY ${QMAKE_FILE_IN}
$${pfx}.CONFIG = no_link no_clean target_predeps $${pfx}.CONFIG = no_link no_clean target_predeps
QMAKE_EXTRA_COMPILERS += $${pfx} QMAKE_EXTRA_COMPILERS += $${pfx}

View File

@ -18,9 +18,6 @@ fq_qml_files = $$qmldir_file
for(qmlf, QML_FILES): fq_qml_files += $$absolute_path($$qmlf, $$_PRO_FILE_PWD_) for(qmlf, QML_FILES): fq_qml_files += $$absolute_path($$qmlf, $$_PRO_FILE_PWD_)
# Only for Qt Creator's project view
OTHER_FILES += $$fq_qml_files
qml1_target: \ qml1_target: \
instbase = $$[QT_INSTALL_IMPORTS] instbase = $$[QT_INSTALL_IMPORTS]
else: \ else: \

View File

@ -47,8 +47,13 @@ probase = $$relative_path($$_PRO_FILE_PWD_, $$dirname(_QMAKE_CONF_)/examples)
sourcefiles += $$resrc sourcefiles += $$resrc
} }
} }
sourcefiles += \
$$ANDROID_PACKAGE_SOURCE_DIR \
$$QMAKE_INFO_PLIST \
$$DISTFILES
extras = \ extras = \
$$_PRO_FILE_PWD_/README \ $$_PRO_FILE_PWD_/README \
$$_PRO_FILE_PWD_/README.TXT \
$$files($$_PRO_FILE_PWD_/*.pri) \ $$files($$_PRO_FILE_PWD_/*.pri) \
$$replace(_PRO_FILE_, \\.pro$, .qmlproject) \ $$replace(_PRO_FILE_, \\.pro$, .qmlproject) \
$$replace(_PRO_FILE_, \\.pro$, .json) \ $$replace(_PRO_FILE_, \\.pro$, .json) \

View File

@ -1612,7 +1612,7 @@ MakefileGenerator::replaceExtraCompilerVariables(
const ProKey funcname = var.mid(19).toKey(); const ProKey funcname = var.mid(19).toKey();
val += project->expand(funcname, QList<ProStringList>() << ProStringList(in)); val += project->expand(funcname, QList<ProStringList>() << ProStringList(in));
} else if(var == QLatin1String("QMAKE_FILE_BASE") || var == QLatin1String("QMAKE_FILE_IN_BASE")) { } else if(var == QLatin1String("QMAKE_FILE_BASE") || var == QLatin1String("QMAKE_FILE_IN_BASE")) {
//filePath = true; filePath = true;
for(int i = 0; i < in.size(); ++i) { for(int i = 0; i < in.size(); ++i) {
QFileInfo fi(fileInfo(Option::normalizePath(in.at(i)))); QFileInfo fi(fileInfo(Option::normalizePath(in.at(i))));
QString base = fi.completeBaseName(); QString base = fi.completeBaseName();
@ -1620,7 +1620,7 @@ MakefileGenerator::replaceExtraCompilerVariables(
base = fi.fileName(); base = fi.fileName();
val += base; val += base;
} }
} else if(var == QLatin1String("QMAKE_FILE_EXT")) { } else if (var == QLatin1String("QMAKE_FILE_EXT") || var == QLatin1String("QMAKE_FILE_IN_EXT")) {
filePath = true; filePath = true;
for(int i = 0; i < in.size(); ++i) { for(int i = 0; i < in.size(); ++i) {
QFileInfo fi(fileInfo(Option::normalizePath(in.at(i)))); QFileInfo fi(fileInfo(Option::normalizePath(in.at(i))));
@ -1633,6 +1633,10 @@ MakefileGenerator::replaceExtraCompilerVariables(
ext = fi.fileName().remove(0, baseLen); ext = fi.fileName().remove(0, baseLen);
val += ext; val += ext;
} }
} else if (var == QLatin1String("QMAKE_FILE_IN_NAME")) {
filePath = true;
for (int i = 0; i < in.size(); ++i)
val += fileInfo(Option::normalizePath(in.at(i))).fileName();
} else if(var == QLatin1String("QMAKE_FILE_PATH") || var == QLatin1String("QMAKE_FILE_IN_PATH")) { } else if(var == QLatin1String("QMAKE_FILE_PATH") || var == QLatin1String("QMAKE_FILE_IN_PATH")) {
filePath = true; filePath = true;
for(int i = 0; i < in.size(); ++i) for(int i = 0; i < in.size(); ++i)
@ -1649,12 +1653,16 @@ MakefileGenerator::replaceExtraCompilerVariables(
filePath = true; filePath = true;
const ProKey funcname = var.mid(20).toKey(); const ProKey funcname = var.mid(20).toKey();
val += project->expand(funcname, QList<ProStringList>() << ProStringList(out)); val += project->expand(funcname, QList<ProStringList>() << ProStringList(out));
} else if (var == QLatin1String("QMAKE_FILE_OUT_PATH")) {
filePath = true;
for (int i = 0; i < out.size(); ++i)
val += fileInfo(Option::normalizePath(out.at(i))).path();
} else if(var == QLatin1String("QMAKE_FILE_OUT")) { } else if(var == QLatin1String("QMAKE_FILE_OUT")) {
filePath = true; filePath = true;
for(int i = 0; i < out.size(); ++i) for(int i = 0; i < out.size(); ++i)
val += fileInfo(Option::normalizePath(out.at(i))).filePath(); val += fileInfo(Option::normalizePath(out.at(i))).filePath();
} else if(var == QLatin1String("QMAKE_FILE_OUT_BASE")) { } else if(var == QLatin1String("QMAKE_FILE_OUT_BASE")) {
//filePath = true; filePath = true;
for(int i = 0; i < out.size(); ++i) { for(int i = 0; i < out.size(); ++i) {
QFileInfo fi(fileInfo(Option::normalizePath(out.at(i)))); QFileInfo fi(fileInfo(Option::normalizePath(out.at(i))));
QString base = fi.completeBaseName(); QString base = fi.completeBaseName();

View File

@ -170,7 +170,7 @@ QImage scaledToWith(const QImage &image)
//! [13] //! [13]
QList<QImage> images = ...; QList<QImage> images = ...;
QFuture<QImage> thumbnails = QtConcurrent::mapped(images, std::bind(&QImage::scaledToWidth, 100 Qt::SmoothTransformation)); QFuture<QImage> thumbnails = QtConcurrent::mapped(images, std::bind(&QImage::scaledToWidth, 100, Qt::SmoothTransformation));
//! [13] //! [13]
//! [14] //! [14]

View File

@ -116,7 +116,7 @@ QT_BEGIN_NAMESPACE
guard.store(QtGlobalStatic::Destroyed); \ guard.store(QtGlobalStatic::Destroyed); \
} \ } \
} cleanup; \ } cleanup; \
guard.store(QtGlobalStatic::Initialized); \ guard.storeRelease(QtGlobalStatic::Initialized); \
} \ } \
} \ } \
return d; \ return d; \

View File

@ -264,7 +264,7 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer)
entryFlags |= QFileSystemMetaData::FileType; entryFlags |= QFileSystemMetaData::FileType;
else if ((statBuffer.st_mode & S_IFMT) == S_IFDIR) else if ((statBuffer.st_mode & S_IFMT) == S_IFDIR)
entryFlags |= QFileSystemMetaData::DirectoryType; entryFlags |= QFileSystemMetaData::DirectoryType;
else else if ((statBuffer.st_mode & S_IFMT) != S_IFBLK)
entryFlags |= QFileSystemMetaData::SequentialType; entryFlags |= QFileSystemMetaData::SequentialType;
// Attributes // Attributes
@ -347,6 +347,18 @@ void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry)
break; break;
case DT_BLK: case DT_BLK:
knownFlagsMask = QFileSystemMetaData::LinkType
| QFileSystemMetaData::FileType
| QFileSystemMetaData::DirectoryType
| QFileSystemMetaData::BundleType
| QFileSystemMetaData::AliasType
| QFileSystemMetaData::SequentialType
| QFileSystemMetaData::ExistsAttribute;
entryFlags = QFileSystemMetaData::ExistsAttribute;
break;
case DT_CHR: case DT_CHR:
case DT_FIFO: case DT_FIFO:
case DT_SOCK: case DT_SOCK:

View File

@ -1422,8 +1422,9 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst
COPYFILE2_EXTENDED_PARAMETERS copyParams = { COPYFILE2_EXTENDED_PARAMETERS copyParams = {
sizeof(copyParams), COPY_FILE_FAIL_IF_EXISTS, NULL, NULL, NULL sizeof(copyParams), COPY_FILE_FAIL_IF_EXISTS, NULL, NULL, NULL
}; };
bool ret = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(), HRESULT hres = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(),
(const wchar_t*)target.nativeFilePath().utf16(), &copyParams) != 0; (const wchar_t*)target.nativeFilePath().utf16(), &copyParams);
bool ret = SUCCEEDED(hres);
#endif // Q_OS_WINRT #endif // Q_OS_WINRT
if(!ret) if(!ret)
error = QSystemError(::GetLastError(), QSystemError::NativeError); error = QSystemError(::GetLastError(), QSystemError::NativeError);

View File

@ -1103,7 +1103,6 @@ bool QProcessPrivate::_q_canReadStandardError()
*/ */
bool QProcessPrivate::_q_canWrite() bool QProcessPrivate::_q_canWrite()
{ {
Q_Q(QProcess);
if (stdinChannel.notifier) if (stdinChannel.notifier)
stdinChannel.notifier->setEnabled(false); stdinChannel.notifier->setEnabled(false);
@ -1114,31 +1113,13 @@ bool QProcessPrivate::_q_canWrite()
return false; return false;
} }
qint64 written = writeToStdin(writeBuffer.readPointer(), writeBuffer.nextDataBlockSize()); const bool writeSucceeded = writeToStdin();
if (written < 0) {
closeChannel(&stdinChannel);
setErrorAndEmit(QProcess::WriteError);
return false;
}
#if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::canWrite(), wrote %d bytes to the process input", int(written));
#endif
if (written != 0) {
writeBuffer.free(written);
if (!emittedBytesWritten) {
emittedBytesWritten = true;
emit q->bytesWritten(written);
emittedBytesWritten = false;
}
emit q->channelBytesWritten(0, written);
}
if (stdinChannel.notifier && !writeBuffer.isEmpty()) if (stdinChannel.notifier && !writeBuffer.isEmpty())
stdinChannel.notifier->setEnabled(true); stdinChannel.notifier->setEnabled(true);
if (writeBuffer.isEmpty() && stdinChannel.closed) if (writeBuffer.isEmpty() && stdinChannel.closed)
closeWriteChannel(); closeWriteChannel();
return true; return writeSucceeded;
} }
/*! /*!

View File

@ -379,7 +379,7 @@ public:
qint64 bytesAvailableInChannel(const Channel *channel) const; qint64 bytesAvailableInChannel(const Channel *channel) const;
qint64 readFromChannel(const Channel *channel, char *data, qint64 maxlen); qint64 readFromChannel(const Channel *channel, char *data, qint64 maxlen);
qint64 writeToStdin(const char *data, qint64 maxlen); bool writeToStdin();
void cleanup(); void cleanup();
void setError(QProcess::ProcessError error, const QString &description = QString()); void setError(QProcess::ProcessError error, const QString &description = QString());

View File

@ -681,21 +681,36 @@ qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint
return bytesRead; return bytesRead;
} }
qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) bool QProcessPrivate::writeToStdin()
{ {
qint64 written = qt_safe_write_nosignal(stdinChannel.pipe[1], data, maxlen); const char *data = writeBuffer.readPointer();
const qint64 bytesToWrite = writeBuffer.nextDataBlockSize();
qint64 written = qt_safe_write_nosignal(stdinChannel.pipe[1], data, bytesToWrite);
#if defined QPROCESS_DEBUG #if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::writeToStdin(%p \"%s\", %lld) == %lld", qDebug("QProcessPrivate::writeToStdin(), write(%p \"%s\", %lld) == %lld",
data, qt_prettyDebug(data, maxlen, 16).constData(), maxlen, written); data, qt_prettyDebug(data, bytesToWrite, 16).constData(), bytesToWrite, written);
if (written == -1) if (written == -1)
qDebug("QProcessPrivate::writeToStdin(), failed to write (%s)", qPrintable(qt_error_string(errno))); qDebug("QProcessPrivate::writeToStdin(), failed to write (%s)", qPrintable(qt_error_string(errno)));
#endif #endif
// If the O_NONBLOCK flag is set and If some data can be written without blocking if (written == -1) {
// the process, write() will transfer what it can and return the number of bytes written. // If the O_NONBLOCK flag is set and If some data can be written without blocking
// Otherwise, it will return -1 and set errno to EAGAIN // the process, write() will transfer what it can and return the number of bytes written.
if (written == -1 && errno == EAGAIN) // Otherwise, it will return -1 and set errno to EAGAIN
written = 0; if (errno == EAGAIN)
return written; return true;
closeChannel(&stdinChannel);
setErrorAndEmit(QProcess::WriteError);
return false;
}
writeBuffer.free(written);
if (!emittedBytesWritten && written != 0) {
emittedBytesWritten = true;
emit q_func()->bytesWritten(written);
emittedBytesWritten = false;
}
return true;
} }
void QProcessPrivate::terminateProcess() void QProcessPrivate::terminateProcess()

View File

@ -805,17 +805,23 @@ qint64 QProcessPrivate::pipeWriterBytesToWrite() const
return stdinChannel.writer ? stdinChannel.writer->bytesToWrite() : qint64(0); return stdinChannel.writer ? stdinChannel.writer->bytesToWrite() : qint64(0);
} }
qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) bool QProcessPrivate::writeToStdin()
{ {
Q_Q(QProcess); Q_Q(QProcess);
if (!stdinChannel.writer) { if (!stdinChannel.writer) {
stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q); stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q);
QObject::connect(stdinChannel.writer, &QWindowsPipeWriter::bytesWritten,
q, &QProcess::bytesWritten);
QObjectPrivate::connect(stdinChannel.writer, &QWindowsPipeWriter::canWrite, QObjectPrivate::connect(stdinChannel.writer, &QWindowsPipeWriter::canWrite,
this, &QProcessPrivate::_q_canWrite); this, &QProcessPrivate::_q_canWrite);
} else {
if (stdinChannel.writer->isWriteOperationActive())
return true;
} }
return stdinChannel.writer->write(data, maxlen); stdinChannel.writer->write(writeBuffer.read());
return true;
} }
// Use ShellExecuteEx() to trigger an UAC prompt when CreateProcess()fails // Use ShellExecuteEx() to trigger an UAC prompt when CreateProcess()fails

View File

@ -271,11 +271,9 @@ qint64 QProcessPrivate::pipeWriterBytesToWrite() const
return 0; return 0;
} }
qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen) bool QProcessPrivate::writeToStdin()
{ {
Q_UNUSED(data); return false;
Q_UNUSED(maxlen);
return -1;
} }
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDir, qint64 *pid) bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDir, qint64 *pid)

View File

@ -79,21 +79,19 @@ QWindowsPipeWriter::~QWindowsPipeWriter()
bool QWindowsPipeWriter::waitForWrite(int msecs) bool QWindowsPipeWriter::waitForWrite(int msecs)
{ {
if (!writeSequenceStarted)
return false;
if (bytesWrittenPending) { if (bytesWrittenPending) {
if (!inBytesWritten) emitPendingBytesWrittenValue();
emitPendingBytesWrittenValue();
return true; return true;
} }
if (!writeSequenceStarted)
return false;
if (!waitForNotification(msecs)) if (!waitForNotification(msecs))
return false; return false;
if (bytesWrittenPending) { if (bytesWrittenPending) {
if (!inBytesWritten) emitPendingBytesWrittenValue();
emitPendingBytesWrittenValue();
return true; return true;
} }
@ -102,20 +100,24 @@ bool QWindowsPipeWriter::waitForWrite(int msecs)
qint64 QWindowsPipeWriter::bytesToWrite() const qint64 QWindowsPipeWriter::bytesToWrite() const
{ {
return numberOfBytesToWrite; return numberOfBytesToWrite + pendingBytesWrittenValue;
} }
void QWindowsPipeWriter::emitPendingBytesWrittenValue() void QWindowsPipeWriter::emitPendingBytesWrittenValue()
{ {
if (bytesWrittenPending) { if (bytesWrittenPending) {
// Reset the state even if we don't emit bytesWritten().
// It's a defined behavior to not re-emit this signal recursively.
bytesWrittenPending = false; bytesWrittenPending = false;
const qint64 bytes = pendingBytesWrittenValue; const qint64 bytes = pendingBytesWrittenValue;
pendingBytesWrittenValue = 0; pendingBytesWrittenValue = 0;
inBytesWritten = true;
emit bytesWritten(bytes);
inBytesWritten = false;
emit canWrite(); emit canWrite();
if (!inBytesWritten) {
inBytesWritten = true;
emit bytesWritten(bytes);
inBytesWritten = false;
}
} }
} }
@ -135,6 +137,8 @@ void QWindowsPipeWriter::notified(DWORD errorCode, DWORD numberOfBytesWritten)
notifiedCalled = true; notifiedCalled = true;
writeSequenceStarted = false; writeSequenceStarted = false;
numberOfBytesToWrite = 0; numberOfBytesToWrite = 0;
Q_ASSERT(errorCode != ERROR_SUCCESS || numberOfBytesWritten == DWORD(buffer.size()));
buffer.clear();
switch (errorCode) { switch (errorCode) {
case ERROR_SUCCESS: case ERROR_SUCCESS:
@ -179,21 +183,26 @@ bool QWindowsPipeWriter::waitForNotification(int timeout)
return notifiedCalled; return notifiedCalled;
} }
qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen) bool QWindowsPipeWriter::write(const QByteArray &ba)
{ {
if (writeSequenceStarted) if (writeSequenceStarted)
return 0; return false;
overlapped.clear(); overlapped.clear();
numberOfBytesToWrite = maxlen; buffer = ba;
numberOfBytesToWrite = buffer.size();
stopped = false; stopped = false;
writeSequenceStarted = true; writeSequenceStarted = true;
if (!WriteFileEx(handle, ptr, maxlen, &overlapped, &writeFileCompleted)) { if (!WriteFileEx(handle, buffer.constData(), numberOfBytesToWrite,
&overlapped, &writeFileCompleted)) {
writeSequenceStarted = false; writeSequenceStarted = false;
numberOfBytesToWrite = 0;
buffer.clear();
qErrnoWarning("QWindowsPipeWriter::write failed."); qErrnoWarning("QWindowsPipeWriter::write failed.");
return false;
} }
return maxlen; return true;
} }
void QWindowsPipeWriter::stop() void QWindowsPipeWriter::stop()

View File

@ -53,6 +53,7 @@
#include <qelapsedtimer.h> #include <qelapsedtimer.h>
#include <qobject.h> #include <qobject.h>
#include <qbytearray.h>
#include <qt_windows.h> #include <qt_windows.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -112,7 +113,7 @@ public:
explicit QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent = 0); explicit QWindowsPipeWriter(HANDLE pipeWriteEnd, QObject *parent = 0);
~QWindowsPipeWriter(); ~QWindowsPipeWriter();
qint64 write(const char *data, qint64 maxlen); bool write(const QByteArray &ba);
void stop(); void stop();
bool waitForWrite(int msecs); bool waitForWrite(int msecs);
bool isWriteOperationActive() const { return writeSequenceStarted; } bool isWriteOperationActive() const { return writeSequenceStarted; }
@ -142,6 +143,7 @@ private:
HANDLE handle; HANDLE handle;
Overlapped overlapped; Overlapped overlapped;
QByteArray buffer;
qint64 numberOfBytesToWrite; qint64 numberOfBytesToWrite;
qint64 pendingBytesWrittenValue; qint64 pendingBytesWrittenValue;
bool stopped; bool stopped;

View File

@ -1130,7 +1130,7 @@ QObjectPrivate::Connection::~Connection()
RTTI support and it works across dynamic library boundaries. RTTI support and it works across dynamic library boundaries.
qobject_cast() can also be used in conjunction with interfaces; qobject_cast() can also be used in conjunction with interfaces;
see the \l{tools/plugandpaint}{Plug & Paint} example for details. see the \l{tools/plugandpaint/app}{Plug & Paint} example for details.
\warning If T isn't declared with the Q_OBJECT macro, this \warning If T isn't declared with the Q_OBJECT macro, this
function's return value is undefined. function's return value is undefined.
@ -4160,11 +4160,11 @@ QDebug operator<<(QDebug dbg, const QObject *o)
Example: Example:
\snippet ../widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h 1 \snippet ../widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h 1
\dots \dots
\snippet ../widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h 3 \snippet ../widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h 3
See the \l{tools/plugandpaintplugins/basictools}{Plug & Paint See the \l{tools/plugandpaint/plugins/basictools}{Plug & Paint
Basic Tools} example for details. Basic Tools} example for details.
\sa Q_DECLARE_INTERFACE(), Q_PLUGIN_METADATA(), {How to Create Qt Plugins} \sa Q_DECLARE_INTERFACE(), Q_PLUGIN_METADATA(), {How to Create Qt Plugins}

View File

@ -44,11 +44,11 @@
to the interface class called \a ClassName. The \a Identifier must to the interface class called \a ClassName. The \a Identifier must
be unique. For example: be unique. For example:
\snippet plugandpaint/interfaces.h 3 \snippet plugandpaint/app/interfaces.h 3
This macro is normally used right after the class definition for This macro is normally used right after the class definition for
\a ClassName, in a header file. See the \a ClassName, in a header file. See the
\l{tools/plugandpaint}{Plug & Paint} example for details. \l{tools/plugandpaint/app}{Plug & Paint} example for details.
If you want to use Q_DECLARE_INTERFACE with interface classes If you want to use Q_DECLARE_INTERFACE with interface classes
declared in a namespace then you have to make sure the Q_DECLARE_INTERFACE declared in a namespace then you have to make sure the Q_DECLARE_INTERFACE
@ -76,7 +76,7 @@
\snippet code/doc_src_qplugin.cpp 1 \snippet code/doc_src_qplugin.cpp 1
See the \l{tools/plugandpaint}{Plug & Paint} example for details. See the \l{tools/plugandpaint/app}{Plug & Paint} example for details.
Note that the class this macro appears on must be default-constructible. Note that the class this macro appears on must be default-constructible.

View File

@ -149,16 +149,12 @@ QThreadPrivate::QThreadPrivate(QThreadData *d)
exited(false), returnCode(-1), exited(false), returnCode(-1),
stackSize(0), priority(QThread::InheritPriority), data(d) stackSize(0), priority(QThread::InheritPriority), data(d)
{ {
#if defined (Q_OS_UNIX) #if defined (Q_OS_WIN)
thread_id = 0;
#elif defined (Q_OS_WIN)
handle = 0; handle = 0;
# ifndef Q_OS_WINRT # ifndef Q_OS_WINRT
id = 0; id = 0;
# endif # endif
waiters = 0; waiters = 0;
#endif
#if defined (Q_OS_WIN)
terminationEnabled = true; terminationEnabled = true;
terminatePending = false; terminatePending = false;
#endif #endif

View File

@ -176,7 +176,6 @@ public:
static QThread *threadForId(int id); static QThread *threadForId(int id);
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
pthread_t thread_id;
QWaitCondition thread_done; QWaitCondition thread_done;
static void *start(void *arg); static void *start(void *arg);

View File

@ -110,6 +110,8 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_THREAD #ifndef QT_NO_THREAD
Q_STATIC_ASSERT(sizeof(pthread_t) == sizeof(Qt::HANDLE));
enum { ThreadPriorityResetFlag = 0x80000000 }; enum { ThreadPriorityResetFlag = 0x80000000 };
#if defined(Q_OS_LINUX) && defined(__GLIBC__) && (defined(Q_CC_GNU) || defined(Q_CC_INTEL)) && !defined(QT_LINUXBASE) #if defined(Q_OS_LINUX) && defined(__GLIBC__) && (defined(Q_CC_GNU) || defined(Q_CC_INTEL)) && !defined(QT_LINUXBASE)
@ -239,8 +241,6 @@ QThreadData *QThreadData::current(bool createIfNecessary)
void QAdoptedThread::init() void QAdoptedThread::init()
{ {
Q_D(QThread);
d->thread_id = pthread_self();
} }
/* /*
@ -328,10 +328,11 @@ void *QThreadPrivate::start(void *arg)
// sets the name of the current thread. // sets the name of the current thread.
QString objectName = thr->objectName(); QString objectName = thr->objectName();
pthread_t thread_id = reinterpret_cast<pthread_t>(data->threadId);
if (Q_LIKELY(objectName.isEmpty())) if (Q_LIKELY(objectName.isEmpty()))
setCurrentThreadName(thr->d_func()->thread_id, thr->metaObject()->className()); setCurrentThreadName(thread_id, thr->metaObject()->className());
else else
setCurrentThreadName(thr->d_func()->thread_id, objectName.toLocal8Bit()); setCurrentThreadName(thread_id, objectName.toLocal8Bit());
} }
#endif #endif
@ -372,7 +373,6 @@ void QThreadPrivate::finish(void *arg)
locker.relock(); locker.relock();
} }
d->thread_id = 0;
d->running = false; d->running = false;
d->finished = true; d->finished = true;
d->interruptionRequested = false; d->interruptionRequested = false;
@ -618,15 +618,16 @@ void QThread::start(Priority priority)
} }
int code = int code =
pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this); pthread_create(reinterpret_cast<pthread_t *>(&d->data->threadId), &attr,
QThreadPrivate::start, this);
if (code == EPERM) { if (code == EPERM) {
// caller does not have permission to set the scheduling // caller does not have permission to set the scheduling
// parameters/policy // parameters/policy
#if defined(QT_HAS_THREAD_PRIORITY_SCHEDULING) #if defined(QT_HAS_THREAD_PRIORITY_SCHEDULING)
pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED); pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
#endif #endif
code = code = pthread_create(reinterpret_cast<pthread_t *>(&d->data->threadId), &attr,
pthread_create(&d->thread_id, &attr, QThreadPrivate::start, this); QThreadPrivate::start, this);
} }
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
@ -636,7 +637,7 @@ void QThread::start(Priority priority)
d->running = false; d->running = false;
d->finished = false; d->finished = false;
d->thread_id = 0; d->data->threadId = 0;
} }
} }
@ -646,10 +647,10 @@ void QThread::terminate()
Q_D(QThread); Q_D(QThread);
QMutexLocker locker(&d->mutex); QMutexLocker locker(&d->mutex);
if (!d->thread_id) if (!d->data->threadId)
return; return;
int code = pthread_cancel(d->thread_id); int code = pthread_cancel(reinterpret_cast<pthread_t>(d->data->threadId));
if (code) { if (code) {
qWarning("QThread::start: Thread termination error: %s", qWarning("QThread::start: Thread termination error: %s",
qPrintable(qt_error_string((code)))); qPrintable(qt_error_string((code))));
@ -662,7 +663,7 @@ bool QThread::wait(unsigned long time)
Q_D(QThread); Q_D(QThread);
QMutexLocker locker(&d->mutex); QMutexLocker locker(&d->mutex);
if (d->thread_id == pthread_self()) { if (reinterpret_cast<pthread_t>(d->data->threadId) == pthread_self()) {
qWarning("QThread::wait: Thread tried to wait on itself"); qWarning("QThread::wait: Thread tried to wait on itself");
return false; return false;
} }
@ -704,7 +705,7 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
int sched_policy; int sched_policy;
sched_param param; sched_param param;
if (pthread_getschedparam(thread_id, &sched_policy, &param) != 0) { if (pthread_getschedparam(reinterpret_cast<pthread_t>(data->threadId), &sched_policy, &param) != 0) {
// failed to get the scheduling policy, don't bother setting // failed to get the scheduling policy, don't bother setting
// the priority // the priority
qWarning("QThread::setPriority: Cannot get scheduler parameters"); qWarning("QThread::setPriority: Cannot get scheduler parameters");
@ -720,15 +721,15 @@ void QThreadPrivate::setPriority(QThread::Priority threadPriority)
} }
param.sched_priority = prio; param.sched_priority = prio;
int status = pthread_setschedparam(thread_id, sched_policy, &param); int status = pthread_setschedparam(reinterpret_cast<pthread_t>(data->threadId), sched_policy, &param);
# ifdef SCHED_IDLE # ifdef SCHED_IDLE
// were we trying to set to idle priority and failed? // were we trying to set to idle priority and failed?
if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) { if (status == -1 && sched_policy == SCHED_IDLE && errno == EINVAL) {
// reset to lowest priority possible // reset to lowest priority possible
pthread_getschedparam(thread_id, &sched_policy, &param); pthread_getschedparam(reinterpret_cast<pthread_t>(data->threadId), &sched_policy, &param);
param.sched_priority = sched_get_priority_min(sched_policy); param.sched_priority = sched_get_priority_min(sched_policy);
pthread_setschedparam(thread_id, sched_policy, &param); pthread_setschedparam(reinterpret_cast<pthread_t>(data->threadId), sched_policy, &param);
} }
# else # else
Q_UNUSED(status); Q_UNUSED(status);

View File

@ -43,7 +43,6 @@
#include <QtCore/qlibrary.h> #include <QtCore/qlibrary.h>
#endif #endif
#include <QtCore/qmutex.h> #include <QtCore/qmutex.h>
#include <private/qmutexpool_p.h>
#ifndef QT_NO_DBUS #ifndef QT_NO_DBUS
@ -81,8 +80,10 @@ bool qdbus_loadLibDBus()
static bool triedToLoadLibrary = false; static bool triedToLoadLibrary = false;
#ifndef QT_NO_THREAD #ifndef QT_NO_THREAD
QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&qdbus_resolve_me)); static QBasicMutex mutex;
QMutexLocker locker(&mutex);
#endif #endif
QLibrary *&lib = qdbus_libdbus; QLibrary *&lib = qdbus_libdbus;
if (triedToLoadLibrary) if (triedToLoadLibrary)
return lib && lib->isLoaded(); return lib && lib->isLoaded();

View File

@ -69,6 +69,10 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#ifdef Q_OS_WIN
static void preventDllUnload();
#endif
Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager) Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager)
// can be replaced with a lambda in Qt 5.7 // can be replaced with a lambda in Qt 5.7
@ -157,6 +161,10 @@ QDBusConnectionManager::QDBusConnectionManager()
this, &QDBusConnectionManager::createServer, Qt::BlockingQueuedConnection); this, &QDBusConnectionManager::createServer, Qt::BlockingQueuedConnection);
moveToThread(this); // ugly, don't do this in other projects moveToThread(this); // ugly, don't do this in other projects
#ifdef Q_OS_WIN
// prevent the library from being unloaded on Windows. See comments in the function.
preventDllUnload();
#endif
defaultBuses[0] = defaultBuses[1] = Q_NULLPTR; defaultBuses[0] = defaultBuses[1] = Q_NULLPTR;
start(); start();
} }
@ -1282,4 +1290,31 @@ QT_END_NAMESPACE
#include "qdbusconnection.moc" #include "qdbusconnection.moc"
#ifdef Q_OS_WIN
# include <qt_windows.h>
QT_BEGIN_NAMESPACE
static void preventDllUnload()
{
// Thread termination is really wacky on Windows. For some reason we don't
// understand, exiting from the thread may try to unload the DLL. Since the
// QDBusConnectionManager thread runs until the DLL is unloaded, we've got
// a deadlock: the main thread is waiting for the manager thread to exit,
// but the manager thread is attempting to acquire a lock to unload the DLL.
//
// We work around the issue by preventing the unload from happening in the
// first place.
//
// For this trick, see
// https://blogs.msdn.microsoft.com/oldnewthing/20131105-00/?p=2733
static HMODULE self;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_PIN,
reinterpret_cast<const wchar_t *>(&self), // any address in this DLL
&self);
}
QT_END_NAMESPACE
#endif
#endif // QT_NO_DBUS #endif // QT_NO_DBUS

View File

@ -2146,6 +2146,17 @@ bool QWindow::event(QEvent *ev)
break; break;
} }
case QEvent::PlatformSurface: {
if ((static_cast<QPlatformSurfaceEvent *>(ev))->surfaceEventType() == QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed) {
#ifndef QT_NO_OPENGL
QOpenGLContext *context = QOpenGLContext::currentContext();
if (context && context->surface() == static_cast<QSurface *>(this))
context->doneCurrent();
#endif
}
break;
}
default: default:
return QObject::event(ev); return QObject::event(ev);
} }

View File

@ -69,6 +69,7 @@ QOpenGLCustomShaderStage::~QOpenGLCustomShaderStage()
d->m_manager->removeCustomStage(); d->m_manager->removeCustomStage();
d->m_manager->sharedShaders->cleanupCustomStage(this); d->m_manager->sharedShaders->cleanupCustomStage(this);
} }
delete d_ptr;
} }
void QOpenGLCustomShaderStage::setUniformsDirty() void QOpenGLCustomShaderStage::setUniformsDirty()

View File

@ -52,6 +52,7 @@
// //
#include <QOpenGLShaderProgram> #include <QOpenGLShaderProgram>
#include <QtGlobal>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -78,6 +79,8 @@ protected:
private: private:
QOpenGLCustomShaderStagePrivate* d_ptr; QOpenGLCustomShaderStagePrivate* d_ptr;
Q_DISABLE_COPY(QOpenGLCustomShaderStage)
}; };

View File

@ -6255,9 +6255,6 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
painter->setRenderHint(QPainter::Qt4CompatiblePainting, false); painter->setRenderHint(QPainter::Qt4CompatiblePainting, false);
const qreal underlineOffset = fe->underlinePosition().toReal(); const qreal underlineOffset = fe->underlinePosition().toReal();
// deliberately ceil the offset to avoid the underline coming too close to
// the text above it.
const qreal underlinePos = pos.y() + qCeil(underlineOffset) + 0.5;
if (underlineStyle == QTextCharFormat::SpellCheckUnderline) { if (underlineStyle == QTextCharFormat::SpellCheckUnderline) {
QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme(); QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
@ -6282,6 +6279,12 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave); painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave);
painter->restore(); painter->restore();
} else if (underlineStyle != QTextCharFormat::NoUnderline) { } else if (underlineStyle != QTextCharFormat::NoUnderline) {
// Deliberately ceil the offset to avoid the underline coming too close to
// the text above it, but limit it to stay within descent.
qreal adjustedUnderlineOffset = std::ceil(underlineOffset) + 0.5;
if (underlineOffset <= fe->descent().toReal())
adjustedUnderlineOffset = qMin(adjustedUnderlineOffset, fe->descent().toReal() - 0.5);
const qreal underlinePos = pos.y() + adjustedUnderlineOffset;
QColor uc = charFormat.underlineColor(); QColor uc = charFormat.underlineColor();
if (uc.isValid()) if (uc.isValid())
pen.setColor(uc); pen.setColor(uc);

View File

@ -418,9 +418,12 @@ QTextFrame::QTextFrame(QTextDocument *doc)
{ {
} }
// ### DOC: What does this do to child frames?
/*! /*!
Destroys the frame, and removes it from the document's layout. Destroys the text frame.
\warning Text frames are owned by the document, so you should
never destroy them yourself. In order to remove a frame from
its document, remove its contents using a \c QTextCursor.
*/ */
QTextFrame::~QTextFrame() QTextFrame::~QTextFrame()
{ {

View File

@ -42,7 +42,6 @@
#include <qlibrary.h> #include <qlibrary.h>
#include <qscopedpointer.h> #include <qscopedpointer.h>
#include <qurl.h> #include <qurl.h>
#include <private/qmutexpool_p.h>
#include <private/qnativesocketengine_p.h> #include <private/qnativesocketengine_p.h>
#include <sys/types.h> #include <sys/types.h>
@ -78,7 +77,7 @@ struct QDnsLookupStateDeleter
} }
}; };
static void resolveLibrary() static bool resolveLibraryInternal()
{ {
QLibrary lib; QLibrary lib;
#ifdef LIBRESOLV_SO #ifdef LIBRESOLV_SO
@ -88,7 +87,7 @@ static void resolveLibrary()
{ {
lib.setFileName(QLatin1String("resolv")); lib.setFileName(QLatin1String("resolv"));
if (!lib.load()) if (!lib.load())
return; return false;
} }
local_dn_expand = dn_expand_proto(lib.resolve("__dn_expand")); local_dn_expand = dn_expand_proto(lib.resolve("__dn_expand"));
@ -112,19 +111,15 @@ static void resolveLibrary()
local_res_nquery = res_nquery_proto(lib.resolve("res_9_nquery")); local_res_nquery = res_nquery_proto(lib.resolve("res_9_nquery"));
if (!local_res_nquery) if (!local_res_nquery)
local_res_nquery = res_nquery_proto(lib.resolve("res_nquery")); local_res_nquery = res_nquery_proto(lib.resolve("res_nquery"));
return true;
} }
Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal()))
void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply) void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply)
{ {
// Load dn_expand, res_ninit and res_nquery on demand. // Load dn_expand, res_ninit and res_nquery on demand.
static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false); resolveLibrary();
if (!triedResolve.loadAcquire()) {
QMutexLocker locker(QMutexPool::globalInstanceGet(&local_res_ninit));
if (!triedResolve.load()) {
resolveLibrary();
triedResolve.storeRelease(true);
}
}
// If dn_expand, res_ninit or res_nquery is missing, fail. // If dn_expand, res_ninit or res_nquery is missing, fail.
if (!local_dn_expand || !local_res_nclose || !local_res_ninit || !local_res_nquery) { if (!local_dn_expand || !local_res_nclose || !local_res_ninit || !local_res_nquery) {

View File

@ -49,7 +49,6 @@
#include <qbasicatomic.h> #include <qbasicatomic.h>
#include <qurl.h> #include <qurl.h>
#include <qfile.h> #include <qfile.h>
#include <private/qmutexpool_p.h>
#include <private/qnet_unix_p.h> #include <private/qnet_unix_p.h>
#include <sys/types.h> #include <sys/types.h>
@ -92,7 +91,7 @@ typedef void (*res_nclose_proto)(res_state_ptr);
static res_nclose_proto local_res_nclose = 0; static res_nclose_proto local_res_nclose = 0;
static res_state_ptr local_res = 0; static res_state_ptr local_res = 0;
static void resolveLibrary() static bool resolveLibraryInternal()
{ {
#if !defined(QT_NO_LIBRARY) && !defined(Q_OS_QNX) #if !defined(QT_NO_LIBRARY) && !defined(Q_OS_QNX)
QLibrary lib; QLibrary lib;
@ -103,7 +102,7 @@ static void resolveLibrary()
{ {
lib.setFileName(QLatin1String("resolv")); lib.setFileName(QLatin1String("resolv"));
if (!lib.load()) if (!lib.load())
return; return false;
} }
local_res_init = res_init_proto(lib.resolve("__res_init")); local_res_init = res_init_proto(lib.resolve("__res_init"));
@ -125,7 +124,10 @@ static void resolveLibrary()
local_res_ninit = 0; local_res_ninit = 0;
} }
#endif #endif
return true;
} }
Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal()))
QHostInfo QHostInfoAgent::fromName(const QString &hostName) QHostInfo QHostInfoAgent::fromName(const QString &hostName)
{ {
@ -137,14 +139,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
#endif #endif
// Load res_init on demand. // Load res_init on demand.
static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false); resolveLibrary();
if (!triedResolve.loadAcquire()) {
QMutexLocker locker(QMutexPool::globalInstanceGet(&local_res_init));
if (!triedResolve.load()) {
resolveLibrary();
triedResolve.storeRelease(true);
}
}
// If res_init is available, poll it. // If res_init is available, poll it.
if (local_res_init) if (local_res_init)

View File

@ -45,7 +45,6 @@
#include <qmutex.h> #include <qmutex.h>
#include <qbasicatomic.h> #include <qbasicatomic.h>
#include <qurl.h> #include <qurl.h>
#include <private/qmutexpool_p.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
@ -78,7 +77,7 @@ static getnameinfoProto local_getnameinfo = 0;
static getaddrinfoProto local_getaddrinfo = 0; static getaddrinfoProto local_getaddrinfo = 0;
static freeaddrinfoProto local_freeaddrinfo = 0; static freeaddrinfoProto local_freeaddrinfo = 0;
static void resolveLibrary() static bool resolveLibraryInternal()
{ {
// Attempt to resolve getaddrinfo(); without it we'll have to fall // Attempt to resolve getaddrinfo(); without it we'll have to fall
// back to gethostbyname(), which has no IPv6 support. // back to gethostbyname(), which has no IPv6 support.
@ -95,7 +94,9 @@ static void resolveLibrary()
local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo"); local_freeaddrinfo = (freeaddrinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "freeaddrinfo");
local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo"); local_getnameinfo = (getnameinfoProto) QSystemLibrary::resolve(QLatin1String("ws2_32"), "getnameinfo");
#endif #endif
return true;
} }
Q_GLOBAL_STATIC_WITH_ARGS(bool, resolveLibrary, (resolveLibraryInternal()))
static void translateWSAError(int error, QHostInfo *results) static void translateWSAError(int error, QHostInfo *results)
{ {
@ -123,14 +124,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
QSysInfo::machineHostName(); // this initializes ws2_32.dll QSysInfo::machineHostName(); // this initializes ws2_32.dll
// Load res_init on demand. // Load res_init on demand.
static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false); resolveLibrary();
if (!triedResolve.loadAcquire()) {
QMutexLocker locker(QMutexPool::globalInstanceGet(&local_getaddrinfo));
if (!triedResolve.load()) {
resolveLibrary();
triedResolve.storeRelease(true);
}
}
QHostInfo results; QHostInfo results;

View File

@ -130,7 +130,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QAbstractSocket::SocketState)) Q_PRIVATE_SLOT(d_func(), void _q_stateChanged(QAbstractSocket::SocketState))
Q_PRIVATE_SLOT(d_func(), void _q_error(QAbstractSocket::SocketError)) Q_PRIVATE_SLOT(d_func(), void _q_error(QAbstractSocket::SocketError))
#elif defined(Q_OS_WIN) #elif defined(Q_OS_WIN)
Q_PRIVATE_SLOT(d_func(), void _q_bytesWritten(qint64)) Q_PRIVATE_SLOT(d_func(), void _q_canWrite())
Q_PRIVATE_SLOT(d_func(), void _q_pipeClosed()) Q_PRIVATE_SLOT(d_func(), void _q_pipeClosed())
Q_PRIVATE_SLOT(d_func(), void _q_winError(ulong, const QString &)) Q_PRIVATE_SLOT(d_func(), void _q_winError(ulong, const QString &))
#else #else

View File

@ -130,8 +130,7 @@ public:
~QLocalSocketPrivate(); ~QLocalSocketPrivate();
void destroyPipeHandles(); void destroyPipeHandles();
void setErrorString(const QString &function); void setErrorString(const QString &function);
void startNextWrite(); void _q_canWrite();
void _q_bytesWritten(qint64 bytes);
void _q_pipeClosed(); void _q_pipeClosed();
void _q_winError(ulong windowsError, const QString &function); void _q_winError(ulong windowsError, const QString &function);
HANDLE handle; HANDLE handle;

View File

@ -218,11 +218,12 @@ qint64 QLocalSocket::writeData(const char *data, qint64 len)
memcpy(dest, data, len); memcpy(dest, data, len);
if (!d->pipeWriter) { if (!d->pipeWriter) {
d->pipeWriter = new QWindowsPipeWriter(d->handle, this); d->pipeWriter = new QWindowsPipeWriter(d->handle, this);
QObjectPrivate::connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten, connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten,
d, &QLocalSocketPrivate::_q_bytesWritten); this, &QLocalSocket::bytesWritten);
QObjectPrivate::connect(d->pipeWriter, &QWindowsPipeWriter::canWrite,
d, &QLocalSocketPrivate::_q_canWrite);
} }
if (!d->pipeWriter->isWriteOperationActive()) d->_q_canWrite();
d->startNextWrite();
return len; return len;
} }
@ -275,7 +276,7 @@ qint64 QLocalSocket::bytesAvailable() const
qint64 QLocalSocket::bytesToWrite() const qint64 QLocalSocket::bytesToWrite() const
{ {
Q_D(const QLocalSocket); Q_D(const QLocalSocket);
return d->writeBuffer.size(); return d->writeBuffer.size() + (d->pipeWriter ? d->pipeWriter->bytesToWrite() : 0);
} }
bool QLocalSocket::canReadLine() const bool QLocalSocket::canReadLine() const
@ -358,7 +359,7 @@ bool QLocalSocket::setSocketDescriptor(qintptr socketDescriptor,
return true; return true;
} }
void QLocalSocketPrivate::startNextWrite() void QLocalSocketPrivate::_q_canWrite()
{ {
Q_Q(QLocalSocket); Q_Q(QLocalSocket);
if (writeBuffer.isEmpty()) { if (writeBuffer.isEmpty()) {
@ -366,18 +367,11 @@ void QLocalSocketPrivate::startNextWrite()
q->close(); q->close();
} else { } else {
Q_ASSERT(pipeWriter); Q_ASSERT(pipeWriter);
pipeWriter->write(writeBuffer.readPointer(), writeBuffer.nextDataBlockSize()); if (!pipeWriter->isWriteOperationActive())
pipeWriter->write(writeBuffer.read());
} }
} }
void QLocalSocketPrivate::_q_bytesWritten(qint64 bytes)
{
Q_Q(QLocalSocket);
writeBuffer.free(bytes);
startNextWrite();
emit q->bytesWritten(bytes);
}
qintptr QLocalSocket::socketDescriptor() const qintptr QLocalSocket::socketDescriptor() const
{ {
Q_D(const QLocalSocket); Q_D(const QLocalSocket);

View File

@ -574,6 +574,19 @@ bool QNativeSocketEnginePrivate::fetchConnectionParameters()
} }
} }
// Some Windows kernels return a v4-mapped QHostAddress::AnyIPv4 as a
// local address of the socket which bound on both IPv4 and IPv6 interfaces.
// This address does not match to any special address and should not be used
// to send the data. So, replace it with QHostAddress::Any.
if (socketProtocol == QAbstractSocket::IPv6Protocol) {
bool ok = false;
const quint32 localIPv4 = localAddress.toIPv4Address(&ok);
if (ok && localIPv4 == INADDR_ANY) {
socketProtocol = QAbstractSocket::AnyIPProtocol;
localAddress = QHostAddress::Any;
}
}
memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
if (::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0) { if (::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0) {
qt_socket_getPortAndAddress(socketDescriptor, &sa, &peerPort, &peerAddress); qt_socket_getPortAndAddress(socketDescriptor, &sa, &peerPort, &peerAddress);
@ -1186,7 +1199,7 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
#endif #endif
#if defined (QNATIVESOCKETENGINE_DEBUG) #if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %li", ret); qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %lli", ret);
#endif #endif
return ret; return ret;
@ -1292,10 +1305,11 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL
} }
#if defined (QNATIVESOCKETENGINE_DEBUG) #if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %li, %s, %i) == %li", bool printSender = (ret != -1 && (options & QNativeSocketEngine::WantDatagramSender) != 0);
qDebug("QNativeSocketEnginePrivate::nativeReceiveDatagram(%p \"%s\", %lli, %s, %i) == %lli",
data, qt_prettyDebug(data, qMin<qint64>(ret, 16), ret).data(), maxLength, data, qt_prettyDebug(data, qMin<qint64>(ret, 16), ret).data(), maxLength,
address ? address->toString().toLatin1().constData() : "(nil)", printSender ? header->senderAddress.toString().toLatin1().constData() : "(unknown)",
port ? *port : 0, ret); printSender ? header->senderPort : 0, ret);
#endif #endif
return ret; return ret;
@ -1407,9 +1421,10 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
} }
#if defined (QNATIVESOCKETENGINE_DEBUG) #if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %li, \"%s\", %i) == %li", data, qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %lli, \"%s\", %i) == %lli", data,
qt_prettyDebug(data, qMin<qint64>(len, 16), len).data(), 0, address.toString().toLatin1().constData(), qt_prettyDebug(data, qMin<qint64>(len, 16), len).data(), len,
port, ret); header.destinationAddress.toString().toLatin1().constData(),
header.destinationPort, ret);
#endif #endif
return ret; return ret;

View File

@ -9,5 +9,3 @@ JAVASOURCES += $$PWD/src/org/qtproject/qt5/android/bearer/QtNetworkReceiver.java
# install # install
target.path = $$[QT_INSTALL_PREFIX]/jar target.path = $$[QT_INSTALL_PREFIX]/jar
INSTALLS += target INSTALLS += target
OTHER_FILES += $$JAVASOURCES

View File

@ -75,6 +75,8 @@ static QTouchDevice *touchDevice = 0;
// ### HACK Remove once 10.8 is unsupported // ### HACK Remove once 10.8 is unsupported
static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
static bool _q_dontOverrideCtrlLMB = false;
@interface NSEvent (Qt_Compile_Leopard_DeviceDelta) @interface NSEvent (Qt_Compile_Leopard_DeviceDelta)
- (CGFloat)deviceDeltaX; - (CGFloat)deviceDeltaX;
- (CGFloat)deviceDeltaY; - (CGFloat)deviceDeltaY;
@ -135,6 +137,8 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
NSString **notificationNameVar = (NSString **)dlsym(RTLD_NEXT, "NSWindowDidChangeOcclusionStateNotification"); NSString **notificationNameVar = (NSString **)dlsym(RTLD_NEXT, "NSWindowDidChangeOcclusionStateNotification");
if (notificationNameVar) if (notificationNameVar)
_q_NSWindowDidChangeOcclusionStateNotification = *notificationNameVar; _q_NSWindowDidChangeOcclusionStateNotification = *notificationNameVar;
_q_dontOverrideCtrlLMB = qt_mac_resolveOption(false, "QT_MAC_DONT_OVERRIDE_CTRL_LMB");
} }
- (id) init - (id) init
@ -969,7 +973,7 @@ QT_WARNING_POP
if ([self hasMarkedText]) { if ([self hasMarkedText]) {
[[NSTextInputContext currentInputContext] handleEvent:theEvent]; [[NSTextInputContext currentInputContext] handleEvent:theEvent];
} else { } else {
if ([QNSView convertKeyModifiers:[theEvent modifierFlags]] & Qt::MetaModifier) { if (!_q_dontOverrideCtrlLMB && [QNSView convertKeyModifiers:[theEvent modifierFlags]] & Qt::MetaModifier) {
m_buttons |= Qt::RightButton; m_buttons |= Qt::RightButton;
m_sendUpAsRightButton = true; m_sendUpAsRightButton = true;
} else { } else {

View File

@ -107,8 +107,10 @@ QEglFSKmsGbmCursor::~QEglFSKmsGbmCursor()
drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0); drmModeMoveCursor(kmsScreen->device()->fd(), kmsScreen->output().crtc_id, 0, 0);
} }
gbm_bo_destroy(m_bo); if (m_bo) {
m_bo = Q_NULLPTR; gbm_bo_destroy(m_bo);
m_bo = Q_NULLPTR;
}
} }
void QEglFSKmsGbmCursor::pointerEvent(const QMouseEvent &event) void QEglFSKmsGbmCursor::pointerEvent(const QMouseEvent &event)
@ -121,6 +123,9 @@ void QEglFSKmsGbmCursor::changeCursor(QCursor *windowCursor, QWindow *window)
{ {
Q_UNUSED(window); Q_UNUSED(window);
if (!m_bo)
return;
if (!m_visible) if (!m_visible)
return; return;

View File

@ -79,7 +79,7 @@ private:
QRect m_geometry; QRect m_geometry;
QRect m_availableGeometry; QRect m_availableGeometry;
int m_depth; int m_depth;
uint m_pixelDensity; uint m_physicalDpi;
QSizeF m_physicalSize; QSizeF m_physicalSize;
QIOSOrientationListener *m_orientationListener; QIOSOrientationListener *m_orientationListener;
}; };

View File

@ -186,18 +186,18 @@ QIOSScreen::QIOSScreen(UIScreen *screen)
if (deviceIdentifier.contains(QRegularExpression("^iPhone(7,1|8,2)$"))) { if (deviceIdentifier.contains(QRegularExpression("^iPhone(7,1|8,2)$"))) {
// iPhone 6 Plus or iPhone 6S Plus // iPhone 6 Plus or iPhone 6S Plus
m_pixelDensity = 401; m_physicalDpi = 401;
} else if (deviceIdentifier.contains(QRegularExpression("^iPad(1,1|2,[1-4]|3,[1-6]|4,[1-3]|5,[3-4]|6,[7-8])$"))) { } else if (deviceIdentifier.contains(QRegularExpression("^iPad(1,1|2,[1-4]|3,[1-6]|4,[1-3]|5,[3-4]|6,[7-8])$"))) {
// All iPads except the iPad Mini series // All iPads except the iPad Mini series
m_pixelDensity = 132 * devicePixelRatio(); m_physicalDpi = 132 * devicePixelRatio();
} else { } else {
// All non-Plus iPhones, and iPad Minis // All non-Plus iPhones, and iPad Minis
m_pixelDensity = 163 * devicePixelRatio(); m_physicalDpi = 163 * devicePixelRatio();
} }
} else { } else {
// External display, hard to say // External display, hard to say
m_depth = 24; m_depth = 24;
m_pixelDensity = 96; m_physicalDpi = 96;
} }
for (UIWindow *existingWindow in [[UIApplication sharedApplication] windows]) { for (UIWindow *existingWindow in [[UIApplication sharedApplication] windows]) {
@ -259,8 +259,23 @@ void QIOSScreen::updateProperties()
} }
if (m_geometry != previousGeometry) { if (m_geometry != previousGeometry) {
const qreal millimetersPerInch = 25.4; QRectF physicalGeometry;
m_physicalSize = QSizeF(m_geometry.size() * devicePixelRatio()) / m_pixelDensity * millimetersPerInch; if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_8_0) {
// We can't use the primaryOrientation of screen(), as we haven't reported the new geometry yet
Qt::ScreenOrientation primaryOrientation = m_geometry.width() >= m_geometry.height() ?
Qt::LandscapeOrientation : Qt::PortraitOrientation;
// On iPhone 6+ devices, or when display zoom is enabled, the render buffer is scaled
// before being output on the physical display. We have to take this into account when
// computing the physical size. Note that unlike the native bounds, the physical size
// follows the primary orientation of the screen.
physicalGeometry = mapBetween(nativeOrientation(), primaryOrientation, fromCGRect(m_uiScreen.nativeBounds).toRect());
} else {
physicalGeometry = QRectF(0, 0, m_geometry.width() * devicePixelRatio(), m_geometry.height() * devicePixelRatio());
}
static const qreal millimetersPerInch = 25.4;
m_physicalSize = physicalGeometry.size() / m_physicalDpi * millimetersPerInch;
} }
// At construction time, we don't yet have an associated QScreen, but we still want // At construction time, we don't yet have an associated QScreen, but we still want

View File

@ -263,15 +263,15 @@ static int openTtyDevice(const QString &device)
return fd; return fd;
} }
static bool switchToGraphicsMode(int ttyfd, int *oldMode) static void switchToGraphicsMode(int ttyfd, bool doSwitch, int *oldMode)
{ {
ioctl(ttyfd, KDGETMODE, oldMode); // Do not warn if the switch fails: the ioctl fails when launching from a
if (*oldMode != KD_GRAPHICS) { // remote console and there is nothing we can do about it. The matching
if (ioctl(ttyfd, KDSETMODE, KD_GRAPHICS) != 0) // call in resetTty should at least fail then, too, so we do no harm.
return false; if (ioctl(ttyfd, KDGETMODE, oldMode) == 0) {
if (doSwitch && *oldMode != KD_GRAPHICS)
ioctl(ttyfd, KDSETMODE, KD_GRAPHICS);
} }
return true;
} }
static void resetTty(int ttyfd, int oldMode) static void resetTty(int ttyfd, int oldMode)
@ -287,14 +287,16 @@ static void blankScreen(int fd, bool on)
} }
QLinuxFbScreen::QLinuxFbScreen(const QStringList &args) QLinuxFbScreen::QLinuxFbScreen(const QStringList &args)
: mArgs(args), mFbFd(-1), mBlitter(0) : mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0)
{ {
mMmap.data = 0;
} }
QLinuxFbScreen::~QLinuxFbScreen() QLinuxFbScreen::~QLinuxFbScreen()
{ {
if (mFbFd != -1) { if (mFbFd != -1) {
munmap(mMmap.data - mMmap.offset, mMmap.size); if (mMmap.data)
munmap(mMmap.data - mMmap.offset, mMmap.size);
close(mFbFd); close(mFbFd);
} }
@ -394,11 +396,7 @@ bool QLinuxFbScreen::initialize()
if (mTtyFd == -1) if (mTtyFd == -1)
qErrnoWarning(errno, "Failed to open tty"); qErrnoWarning(errno, "Failed to open tty");
if (doSwitchToGraphicsMode) switchToGraphicsMode(mTtyFd, doSwitchToGraphicsMode, &mOldTtyMode);
switchToGraphicsMode(mTtyFd, &mOldTtyMode);
// Do not warn if the switch fails: the ioctl fails when launching from
// a remote console and there is nothing we can do about it.
blankScreen(mFbFd, false); blankScreen(mFbFd, false);
return true; return true;

View File

@ -1638,8 +1638,13 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex,
if (!m_xi2Enabled) if (!m_xi2Enabled)
return false; return false;
// compress XI_Motion // compress XI_Motion, but not from tablet devices
if (isXIType(event, m_xiOpCode, XI_Motion)) { if (isXIType(event, m_xiOpCode, XI_Motion)) {
#ifndef QT_NO_TABLETEVENT
xXIDeviceEvent *xdev = reinterpret_cast<xXIDeviceEvent *>(event);
if (const_cast<QXcbConnection *>(this)->tabletDataForDevice(xdev->sourceid))
return false;
#endif // QT_NO_TABLETEVENT
for (int j = nextIndex; j < eventqueue->size(); ++j) { for (int j = nextIndex; j < eventqueue->size(); ++j) {
xcb_generic_event_t *next = eventqueue->at(j); xcb_generic_event_t *next = eventqueue->at(j);
if (!isValid(next)) if (!isValid(next))

View File

@ -584,6 +584,7 @@ private:
bool xi2HandleTabletEvent(const void *event, TabletData *tabletData); bool xi2HandleTabletEvent(const void *event, TabletData *tabletData);
void xi2ReportTabletEvent(const void *event, TabletData *tabletData); void xi2ReportTabletEvent(const void *event, TabletData *tabletData);
QVector<TabletData> m_tabletData; QVector<TabletData> m_tabletData;
TabletData *tabletDataForDevice(int id);
#endif // !QT_NO_TABLETEVENT #endif // !QT_NO_TABLETEVENT
struct ScrollingDevice { struct ScrollingDevice {
ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0), legacyOrientations(0) { } ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0), legacyOrientations(0) { }

View File

@ -119,7 +119,7 @@ void QXcbConnection::xi2SetupDevices()
// Only non-master pointing devices are relevant here. // Only non-master pointing devices are relevant here.
if (devices[i].use != XISlavePointer) if (devices[i].use != XISlavePointer)
continue; continue;
qCDebug(lcQpaXInputDevices) << "input device "<< devices[i].name; qCDebug(lcQpaXInputDevices) << "input device " << devices[i].name << "ID" << devices[i].deviceid;
#ifndef QT_NO_TABLETEVENT #ifndef QT_NO_TABLETEVENT
TabletData tabletData; TabletData tabletData;
#endif #endif
@ -537,12 +537,9 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
#ifndef QT_NO_TABLETEVENT #ifndef QT_NO_TABLETEVENT
if (!xiEnterEvent) { if (!xiEnterEvent) {
for (int i = 0; i < m_tabletData.count(); ++i) { QXcbConnection::TabletData *tablet = tabletDataForDevice(sourceDeviceId);
if (m_tabletData.at(i).deviceId == sourceDeviceId) { if (tablet && xi2HandleTabletEvent(xiEvent, tablet))
if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i])) return;
return;
}
}
} }
#endif // QT_NO_TABLETEVENT #endif // QT_NO_TABLETEVENT
@ -1195,6 +1192,16 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
xTilt, yTilt, tangentialPressure, xTilt, yTilt, tangentialPressure,
rotation, 0, tabletData->serialId); rotation, 0, tabletData->serialId);
} }
QXcbConnection::TabletData *QXcbConnection::tabletDataForDevice(int id)
{
for (int i = 0; i < m_tabletData.count(); ++i) {
if (m_tabletData.at(i).deviceId == id)
return &m_tabletData[i];
}
return Q_NULLPTR;
}
#endif // QT_NO_TABLETEVENT #endif // QT_NO_TABLETEVENT
#endif // XCB_USE_XINPUT2 #endif // XCB_USE_XINPUT2

View File

@ -1140,10 +1140,10 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
at = findTransactionByWindow(event->requestor); at = findTransactionByWindow(event->requestor);
} }
if (at == -1 && event->time == XCB_CURRENT_TIME) { if (at == -1) {
xcb_window_t target = findXdndAwareParent(connection(), event->requestor); xcb_window_t target = findXdndAwareParent(connection(), event->requestor);
if (target) { if (target) {
if (current_target == target) if (event->time == XCB_CURRENT_TIME && current_target == target)
at = -2; at = -2;
else else
at = findTransactionByWindow(target); at = findTransactionByWindow(target);

View File

@ -1099,6 +1099,8 @@ void QSplitter::resizeEvent(QResizeEvent *)
If \a widget is already in the splitter, it will be moved to the new position. If \a widget is already in the splitter, it will be moved to the new position.
\note The splitter takes ownership of the widget.
\sa insertWidget(), widget(), indexOf() \sa insertWidget(), widget(), indexOf()
*/ */
void QSplitter::addWidget(QWidget *widget) void QSplitter::addWidget(QWidget *widget)
@ -1113,7 +1115,9 @@ void QSplitter::addWidget(QWidget *widget)
If \a widget is already in the splitter, it will be moved to the new position. If \a widget is already in the splitter, it will be moved to the new position.
if \a index is an invalid index, then the widget will be inserted at the end. If \a index is an invalid index, then the widget will be inserted at the end.
\note The splitter takes ownership of the widget.
\sa addWidget(), indexOf(), widget() \sa addWidget(), indexOf(), widget()
*/ */

View File

@ -5,7 +5,6 @@ CONFIG += testcase
QT = core core-private testlib QT = core core-private testlib
SOURCES += tst_qloggingregistry.cpp SOURCES += tst_qloggingregistry.cpp
OTHER_FILES += qtlogging.ini
TESTDATA += qtlogging.ini TESTDATA += qtlogging.ini
android { android {

View File

@ -644,22 +644,21 @@ void tst_QTimeLine::restart()
void tst_QTimeLine::setPaused() void tst_QTimeLine::setPaused()
{ {
QTimeLine timeLine(1000); const int EndTime = 10000;
QTimeLine timeLine(EndTime);
{ {
QCOMPARE(timeLine.currentTime(), 0); QCOMPARE(timeLine.currentTime(), 0);
timeLine.start(); timeLine.start();
QTest::qWait(250); QTRY_VERIFY(timeLine.currentTime() != 0); // wait for start
timeLine.setPaused(true); timeLine.setPaused(true);
int oldCurrentTime = timeLine.currentTime(); int oldCurrentTime = timeLine.currentTime();
QVERIFY(oldCurrentTime > 0); QVERIFY(oldCurrentTime > 0);
QVERIFY(oldCurrentTime < 1000); QVERIFY(oldCurrentTime < EndTime);
QTest::qWait(1000); QTest::qWait(1000);
timeLine.setPaused(false); timeLine.setPaused(false);
QTest::qWait(250); QTRY_VERIFY(timeLine.currentTime() > oldCurrentTime);
int currentTime = timeLine.currentTime(); QVERIFY(timeLine.currentTime() > 0);
QVERIFY(currentTime > 0); QVERIFY(timeLine.currentTime() < EndTime);
QVERIFY(currentTime > oldCurrentTime);
QVERIFY(currentTime < 1000);
timeLine.stop(); timeLine.stop();
} }
} }

View File

@ -116,6 +116,23 @@ static bool orderByModifier(const QVector<int> &v1, const QVector<int> &v2)
return true; return true;
} }
static QByteArray modifiersTestRowName(const QString &keySequence)
{
QByteArray result;
QTextStream str(&result);
for (int i = 0, size = keySequence.size(); i < size; ++i) {
const QChar &c = keySequence.at(i);
const ushort uc = c.unicode();
if (uc > 32 && uc < 128)
str << '"' << c << '"';
else
str << "U+" << hex << uc << dec;
if (i < size - 1)
str << ',';
}
return result;
}
void tst_QKeyEvent::modifiers_data() void tst_QKeyEvent::modifiers_data()
{ {
struct Modifier struct Modifier
@ -155,7 +172,8 @@ void tst_QKeyEvent::modifiers_data()
mods |= modifier.modifier; mods |= modifier.modifier;
} }
QKeySequence keySequence(keys[0], keys[1], keys[2], keys[3]); QKeySequence keySequence(keys[0], keys[1], keys[2], keys[3]);
QTest::newRow(keySequence.toString(QKeySequence::NativeText).toUtf8().constData()) << mods; QTest::newRow(modifiersTestRowName(keySequence.toString(QKeySequence::NativeText)).constData())
<< mods;
} }
} }

View File

@ -29,6 +29,8 @@
#include <QString> #include <QString>
#ifdef QT_NETWORK_LIB #ifdef QT_NETWORK_LIB
#include <QtNetwork/QHostInfo> #include <QtNetwork/QHostInfo>
#include <QtNetwork/QHostAddress>
#include <QtNetwork/QAbstractSocket>
#endif #endif
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
@ -134,5 +136,21 @@ public:
} }
return true; return true;
} }
#endif
// Helper function for usage with QVERIFY2 on sockets.
static QByteArray msgSocketError(const QAbstractSocket &s)
{
QString result;
QDebug debug(&result);
debug.nospace();
debug.noquote();
if (!s.localAddress().isNull())
debug << "local=" << s.localAddress().toString() << ':' << s.localPort();
if (!s.peerAddress().isNull())
debug << ", peer=" << s.peerAddress().toString() << ':' << s.peerPort();
debug << ", type=" << s.socketType() << ", state=" << s.state()
<< ", error=" << s.error() << ": " << s.errorString();
return result.toLocal8Bit();
}
#endif // QT_NETWORK_LIB
}; };

View File

@ -31,6 +31,7 @@
#include <QtTest/QtTest> #include <QtTest/QtTest>
#include <qtextstream.h> #include <qtextstream.h>
#include <qdatastream.h>
#include <QtNetwork/qlocalsocket.h> #include <QtNetwork/qlocalsocket.h>
#include <QtNetwork/qlocalserver.h> #include <QtNetwork/qlocalserver.h>
@ -73,6 +74,9 @@ private slots:
void readBufferOverflow(); void readBufferOverflow();
void simpleCommandProtocol1();
void simpleCommandProtocol2();
void fullPath(); void fullPath();
void hitMaximumConnections_data(); void hitMaximumConnections_data();
@ -622,6 +626,110 @@ void tst_QLocalSocket::readBufferOverflow()
QCOMPARE(client.bytesAvailable(), 0); QCOMPARE(client.bytesAvailable(), 0);
} }
static qint64 writeCommand(const QVariant &command, QIODevice *device, int commandCounter)
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << qint64(0);
out << commandCounter;
out << command;
out.device()->seek(0);
out << qint64(block.size() - sizeof(qint64));
return device->write(block);
}
static QVariant readCommand(QIODevice *ioDevice, int *readCommandCounter, bool readSize = true)
{
QDataStream in(ioDevice);
qint64 blockSize;
int commandCounter;
if (readSize)
in >> blockSize;
in >> commandCounter;
*readCommandCounter = commandCounter;
QVariant command;
in >> command;
return command;
}
void tst_QLocalSocket::simpleCommandProtocol1()
{
QLocalServer server;
server.listen(QStringLiteral("simpleProtocol"));
QLocalSocket localSocketWrite;
localSocketWrite.connectToServer(server.serverName());
QVERIFY(server.waitForNewConnection());
QLocalSocket *localSocketRead = server.nextPendingConnection();
QVERIFY(localSocketRead);
int readCounter = 0;
for (int i = 0; i < 2000; ++i) {
const QVariant command(QRect(readCounter, i, 10, 10));
const qint64 blockSize = writeCommand(command, &localSocketWrite, i);
while (localSocketWrite.bytesToWrite())
QVERIFY(localSocketWrite.waitForBytesWritten());
while (localSocketRead->bytesAvailable() < blockSize) {
QVERIFY(localSocketRead->waitForReadyRead(1000));
}
const QVariant variant = readCommand(localSocketRead, &readCounter);
QCOMPARE(readCounter, i);
QCOMPARE(variant, command);
}
}
void tst_QLocalSocket::simpleCommandProtocol2()
{
QLocalServer server;
server.listen(QStringLiteral("simpleProtocol"));
QLocalSocket localSocketWrite;
localSocketWrite.connectToServer(server.serverName());
QVERIFY(server.waitForNewConnection());
QLocalSocket* localSocketRead = server.nextPendingConnection();
QVERIFY(localSocketRead);
int readCounter = 0;
qint64 writtenBlockSize = 0;
qint64 blockSize = 0;
QObject::connect(localSocketRead, &QLocalSocket::readyRead, [&] {
forever {
if (localSocketRead->bytesAvailable() < sizeof(qint64))
return;
if (blockSize == 0) {
QDataStream in(localSocketRead);
in >> blockSize;
}
if (localSocketRead->bytesAvailable() < blockSize)
return;
int commandNumber = 0;
const QVariant variant = readCommand(localSocketRead, &commandNumber, false);
QCOMPARE(writtenBlockSize, blockSize);
QCOMPARE(readCounter, commandNumber);
QCOMPARE(variant.userType(), (int)QMetaType::QRect);
readCounter++;
blockSize = 0;
}
});
for (int i = 0; i < 500; ++i) {
const QVariant command(QRect(readCounter, i, 10, 10));
writtenBlockSize = writeCommand(command, &localSocketWrite, i) - sizeof(qint64);
if (i % 10 == 0)
QTest::qWait(1);
}
localSocketWrite.abort();
QVERIFY(localSocketRead->waitForDisconnected(1000));
}
// QLocalSocket/Server can take a name or path, check that it works as expected // QLocalSocket/Server can take a name or path, check that it works as expected
void tst_QLocalSocket::fullPath() void tst_QLocalSocket::fullPath()
{ {

View File

@ -671,8 +671,10 @@ void tst_QTcpSocket::bindThenResolveHost()
dummySocket.close(); dummySocket.close();
socket->connectToHost(hostName, 80); const quint16 port = 80;
QVERIFY2(socket->waitForConnected(), "Network timeout"); socket->connectToHost(hostName, port);
QVERIFY2(socket->waitForConnected(), (hostName.toLocal8Bit() + ": " + QByteArray::number(port) + ' '
+ QtNetworkSettings::msgSocketError(*socket)).constData());
QCOMPARE(socket->localPort(), boundPort); QCOMPARE(socket->localPort(), boundPort);
QCOMPARE(socket->socketDescriptor(), fd); QCOMPARE(socket->socketDescriptor(), fd);

View File

@ -33,6 +33,7 @@
#include <qcoreapplication.h> #include <qcoreapplication.h>
#include <qfileinfo.h> #include <qfileinfo.h>
#include <qdatastream.h> #include <qdatastream.h>
#include <qdebug.h>
#include <qudpsocket.h> #include <qudpsocket.h>
#include <qhostaddress.h> #include <qhostaddress.h>
#include <qhostinfo.h> #include <qhostinfo.h>
@ -246,7 +247,7 @@ void tst_QUdpSocket::unconnectedServerAndClientTest()
char buf[1024]; char buf[1024];
QHostAddress host; QHostAddress host;
quint16 port; quint16 port;
QVERIFY(serverSocket.waitForReadyRead(5000)); QVERIFY2(serverSocket.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(serverSocket).constData());
QCOMPARE(int(serverSocket.readDatagram(buf, sizeof(buf), &host, &port)), QCOMPARE(int(serverSocket.readDatagram(buf, sizeof(buf), &host, &port)),
int(strlen(message[i]))); int(strlen(message[i])));
buf[strlen(message[i])] = '\0'; buf[strlen(message[i])] = '\0';
@ -378,8 +379,8 @@ void tst_QUdpSocket::loop()
QCOMPARE(paul.writeDatagram(paulMessage.data(), paulMessage.length(), QCOMPARE(paul.writeDatagram(paulMessage.data(), paulMessage.length(),
peterAddress, peter.localPort()), qint64(paulMessage.length())); peterAddress, peter.localPort()), qint64(paulMessage.length()));
QVERIFY(peter.waitForReadyRead(9000)); QVERIFY2(peter.waitForReadyRead(9000), QtNetworkSettings::msgSocketError(peter).constData());
QVERIFY(paul.waitForReadyRead(9000)); QVERIFY2(paul.waitForReadyRead(9000), QtNetworkSettings::msgSocketError(paul).constData());
char peterBuffer[16*1024]; char peterBuffer[16*1024];
char paulBuffer[16*1024]; char paulBuffer[16*1024];
if (success) { if (success) {
@ -435,8 +436,8 @@ void tst_QUdpSocket::ipv6Loop()
char peterBuffer[16*1024]; char peterBuffer[16*1024];
char paulBuffer[16*1024]; char paulBuffer[16*1024];
#if !defined(Q_OS_WINCE) #if !defined(Q_OS_WINCE)
QVERIFY(peter.waitForReadyRead(5000)); QVERIFY2(peter.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(peter).constData());
QVERIFY(paul.waitForReadyRead(5000)); QVERIFY2(paul.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(paul).constData());
#else #else
QVERIFY(peter.waitForReadyRead(15000)); QVERIFY(peter.waitForReadyRead(15000));
QVERIFY(paul.waitForReadyRead(15000)); QVERIFY(paul.waitForReadyRead(15000));
@ -471,7 +472,7 @@ void tst_QUdpSocket::dualStack()
QByteArray buffer; QByteArray buffer;
//test v4 -> dual //test v4 -> dual
QCOMPARE((int)v4Sock.writeDatagram(v4Data.constData(), v4Data.length(), QHostAddress(QHostAddress::LocalHost), dualSock.localPort()), v4Data.length()); QCOMPARE((int)v4Sock.writeDatagram(v4Data.constData(), v4Data.length(), QHostAddress(QHostAddress::LocalHost), dualSock.localPort()), v4Data.length());
QVERIFY(dualSock.waitForReadyRead(5000)); QVERIFY2(dualSock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(dualSock).constData());
buffer.reserve(100); buffer.reserve(100);
qint64 size = dualSock.readDatagram(buffer.data(), 100, &from, &port); qint64 size = dualSock.readDatagram(buffer.data(), 100, &from, &port);
QCOMPARE((int)size, v4Data.length()); QCOMPARE((int)size, v4Data.length());
@ -485,7 +486,7 @@ void tst_QUdpSocket::dualStack()
//test v6 -> dual //test v6 -> dual
QCOMPARE((int)v6Sock.writeDatagram(v6Data.constData(), v6Data.length(), QHostAddress(QHostAddress::LocalHostIPv6), dualSock.localPort()), v6Data.length()); QCOMPARE((int)v6Sock.writeDatagram(v6Data.constData(), v6Data.length(), QHostAddress(QHostAddress::LocalHostIPv6), dualSock.localPort()), v6Data.length());
QVERIFY(dualSock.waitForReadyRead(5000)); QVERIFY2(dualSock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(dualSock).constData());
buffer.reserve(100); buffer.reserve(100);
size = dualSock.readDatagram(buffer.data(), 100, &from, &port); size = dualSock.readDatagram(buffer.data(), 100, &from, &port);
QCOMPARE((int)size, v6Data.length()); QCOMPARE((int)size, v6Data.length());
@ -494,7 +495,7 @@ void tst_QUdpSocket::dualStack()
//test dual -> v6 //test dual -> v6
QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length()); QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length());
QVERIFY(v6Sock.waitForReadyRead(5000)); QVERIFY2(v6Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v6Sock).constData());
buffer.reserve(100); buffer.reserve(100);
size = v6Sock.readDatagram(buffer.data(), 100, &from, &port); size = v6Sock.readDatagram(buffer.data(), 100, &from, &port);
QCOMPARE((int)size, dualData.length()); QCOMPARE((int)size, dualData.length());
@ -504,7 +505,7 @@ void tst_QUdpSocket::dualStack()
//test dual -> v4 //test dual -> v4
QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length()); QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length());
QVERIFY(v4Sock.waitForReadyRead(5000)); QVERIFY2(v4Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v4Sock).constData());
buffer.reserve(100); buffer.reserve(100);
size = v4Sock.readDatagram(buffer.data(), 100, &from, &port); size = v4Sock.readDatagram(buffer.data(), 100, &from, &port);
QCOMPARE((int)size, dualData.length()); QCOMPARE((int)size, dualData.length());
@ -536,7 +537,7 @@ void tst_QUdpSocket::dualStackAutoBinding()
QUdpSocket dualSock; QUdpSocket dualSock;
QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length()); QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length());
QVERIFY(v4Sock.waitForReadyRead(5000)); QVERIFY2(v4Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v4Sock).constData());
buffer.reserve(100); buffer.reserve(100);
size = v4Sock.readDatagram(buffer.data(), 100, &from, &port); size = v4Sock.readDatagram(buffer.data(), 100, &from, &port);
QCOMPARE((int)size, dualData.length()); QCOMPARE((int)size, dualData.length());
@ -544,7 +545,7 @@ void tst_QUdpSocket::dualStackAutoBinding()
QCOMPARE(buffer, dualData); QCOMPARE(buffer, dualData);
QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length()); QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length());
QVERIFY(v6Sock.waitForReadyRead(5000)); QVERIFY2(v6Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v6Sock).constData());
buffer.reserve(100); buffer.reserve(100);
size = v6Sock.readDatagram(buffer.data(), 100, &from, &port); size = v6Sock.readDatagram(buffer.data(), 100, &from, &port);
QCOMPARE((int)size, dualData.length()); QCOMPARE((int)size, dualData.length());
@ -557,7 +558,7 @@ void tst_QUdpSocket::dualStackAutoBinding()
QUdpSocket dualSock; QUdpSocket dualSock;
QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length()); QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHostIPv6), v6Sock.localPort()), dualData.length());
QVERIFY(v6Sock.waitForReadyRead(5000)); QVERIFY2(v6Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v6Sock).constData());
buffer.reserve(100); buffer.reserve(100);
size = v6Sock.readDatagram(buffer.data(), 100, &from, &port); size = v6Sock.readDatagram(buffer.data(), 100, &from, &port);
QCOMPARE((int)size, dualData.length()); QCOMPARE((int)size, dualData.length());
@ -565,7 +566,7 @@ void tst_QUdpSocket::dualStackAutoBinding()
QCOMPARE(buffer, dualData); QCOMPARE(buffer, dualData);
QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length()); QCOMPARE((int)dualSock.writeDatagram(dualData.constData(), dualData.length(), QHostAddress(QHostAddress::LocalHost), v4Sock.localPort()), dualData.length());
QVERIFY(v4Sock.waitForReadyRead(5000)); QVERIFY2(v4Sock.waitForReadyRead(5000), QtNetworkSettings::msgSocketError(v4Sock).constData());
buffer.reserve(100); buffer.reserve(100);
size = v4Sock.readDatagram(buffer.data(), 100, &from, &port); size = v4Sock.readDatagram(buffer.data(), 100, &from, &port);
QCOMPARE((int)size, dualData.length()); QCOMPARE((int)size, dualData.length());
@ -670,7 +671,7 @@ void tst_QUdpSocket::pendingDatagramSize()
QVERIFY(client.writeDatagram("3 messages", 10, serverAddress, server.localPort()) == 10); QVERIFY(client.writeDatagram("3 messages", 10, serverAddress, server.localPort()) == 10);
char c = 0; char c = 0;
QVERIFY(server.waitForReadyRead()); QVERIFY2(server.waitForReadyRead(), QtNetworkSettings::msgSocketError(server).constData());
if (server.hasPendingDatagrams()) { if (server.hasPendingDatagrams()) {
#if defined Q_OS_HPUX && defined __ia64 #if defined Q_OS_HPUX && defined __ia64
QEXPECT_FAIL("", "HP-UX 11i v2 can't determine the datagram size correctly.", Abort); QEXPECT_FAIL("", "HP-UX 11i v2 can't determine the datagram size correctly.", Abort);
@ -1082,7 +1083,7 @@ void tst_QUdpSocket::zeroLengthDatagram()
#endif #endif
QCOMPARE(sender.writeDatagram(QByteArray(), QHostAddress::LocalHost, receiver.localPort()), qint64(0)); QCOMPARE(sender.writeDatagram(QByteArray(), QHostAddress::LocalHost, receiver.localPort()), qint64(0));
QVERIFY(receiver.waitForReadyRead(1000)); QVERIFY2(receiver.waitForReadyRead(1000), QtNetworkSettings::msgSocketError(receiver).constData());
QVERIFY(receiver.hasPendingDatagrams()); QVERIFY(receiver.hasPendingDatagrams());
char buf; char buf;
@ -1361,8 +1362,7 @@ void tst_QUdpSocket::multicast()
int(datagram.size())); int(datagram.size()));
} }
QVERIFY2(receiver.waitForReadyRead(), QVERIFY2(receiver.waitForReadyRead(), QtNetworkSettings::msgSocketError(receiver).constData());
qPrintable(receiver.errorString()));
QVERIFY(receiver.hasPendingDatagrams()); QVERIFY(receiver.hasPendingDatagrams());
QList<QByteArray> receivedDatagrams; QList<QByteArray> receivedDatagrams;
while (receiver.hasPendingDatagrams()) { while (receiver.hasPendingDatagrams()) {
@ -1428,7 +1428,7 @@ void tst_QUdpSocket::echo()
qDebug() << "packets in" << successes << "out" << i; qDebug() << "packets in" << successes << "out" << i;
QTest::qWait(50); //choke to avoid triggering flood/DDoS protections on echo service QTest::qWait(50); //choke to avoid triggering flood/DDoS protections on echo service
} }
QVERIFY(successes >= 9); QVERIFY2(successes >= 9, QByteArray::number(successes).constData());
} }
void tst_QUdpSocket::linkLocalIPv6() void tst_QUdpSocket::linkLocalIPv6()
@ -1549,7 +1549,7 @@ void tst_QUdpSocket::linkLocalIPv4()
QByteArray receiveBuffer("xxxxx"); QByteArray receiveBuffer("xxxxx");
foreach (QUdpSocket *s, sockets) { foreach (QUdpSocket *s, sockets) {
QVERIFY(s->writeDatagram(testData, s->localAddress(), neutral.localPort())); QVERIFY(s->writeDatagram(testData, s->localAddress(), neutral.localPort()));
QVERIFY(neutral.waitForReadyRead(10000)); QVERIFY2(neutral.waitForReadyRead(10000), QtNetworkSettings::msgSocketError(neutral).constData());
QHostAddress from; QHostAddress from;
quint16 fromPort; quint16 fromPort;
QCOMPARE((int)neutral.readDatagram(receiveBuffer.data(), receiveBuffer.length(), &from, &fromPort), testData.length()); QCOMPARE((int)neutral.readDatagram(receiveBuffer.data(), receiveBuffer.length(), &from, &fromPort), testData.length());
@ -1558,7 +1558,7 @@ void tst_QUdpSocket::linkLocalIPv4()
QCOMPARE(receiveBuffer, testData); QCOMPARE(receiveBuffer, testData);
QVERIFY(neutral.writeDatagram(testData, s->localAddress(), s->localPort())); QVERIFY(neutral.writeDatagram(testData, s->localAddress(), s->localPort()));
QVERIFY(s->waitForReadyRead(10000)); QVERIFY2(s->waitForReadyRead(10000), QtNetworkSettings::msgSocketError(*s).constData());
QCOMPARE((int)s->readDatagram(receiveBuffer.data(), receiveBuffer.length(), &from, &fromPort), testData.length()); QCOMPARE((int)s->readDatagram(receiveBuffer.data(), receiveBuffer.length(), &from, &fromPort), testData.length());
QCOMPARE(receiveBuffer, testData); QCOMPARE(receiveBuffer, testData);

View File

@ -31,18 +31,21 @@ class Server : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
Server(int port)
Server() { connect(&serverSocket, &QIODevice::readyRead, this, &Server::sendEcho); }
bool bind(quint16 port)
{ {
connect(&serverSocket, SIGNAL(readyRead()), const bool result = serverSocket.bind(QHostAddress::Any, port,
this, SLOT(sendEcho())); QUdpSocket::ReuseAddressHint
if (serverSocket.bind(QHostAddress::Any, port, | QUdpSocket::ShareAddress);
QUdpSocket::ReuseAddressHint if (result) {
| QUdpSocket::ShareAddress)) {
printf("OK\n"); printf("OK\n");
} else { } else {
printf("FAILED\n"); printf("FAILED: %s\n", qPrintable(serverSocket.errorString()));
} }
fflush(stdout); fflush(stdout);
return result;
} }
private slots: private slots:
@ -68,8 +71,19 @@ private:
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
QStringList arguments = QCoreApplication::arguments();
arguments.pop_front();
quint16 port = 0;
if (!arguments.isEmpty())
port = arguments.constFirst().toUShort();
if (!port) {
printf("Specify port number\n");
return -1;
}
Server server(app.arguments().at(1).toInt()); Server server;
if (!server.bind(port))
return -2;
return app.exec(); return app.exec();
} }

View File

@ -69,7 +69,7 @@
#include "../../../qtest-config.h" #include "../../../qtest-config.h"
#if defined(Q_OS_MAC) #if defined(Q_OS_OSX)
#include "tst_qwidget_mac_helpers.h" // Abstract the ObjC stuff out so not everyone must run an ObjC++ compile. #include "tst_qwidget_mac_helpers.h" // Abstract the ObjC stuff out so not everyone must run an ObjC++ compile.
#endif #endif
@ -136,7 +136,7 @@ bool qt_wince_is_smartphone() {
} }
#endif #endif
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
#include <Security/AuthSession.h> #include <Security/AuthSession.h>
bool macHasAccessToWindowsServer() bool macHasAccessToWindowsServer()
{ {
@ -263,7 +263,7 @@ private slots:
void restoreVersion1Geometry(); void restoreVersion1Geometry();
void widgetAt(); void widgetAt();
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
void sheetOpacity(); void sheetOpacity();
void setMask(); void setMask();
#endif #endif
@ -296,7 +296,7 @@ private slots:
void update(); void update();
void isOpaque(); void isOpaque();
#ifndef Q_OS_MAC #ifndef Q_OS_OSX
void scroll(); void scroll();
void scrollNativeChildren(); void scrollNativeChildren();
#endif #endif
@ -429,7 +429,7 @@ private slots:
void taskQTBUG_7532_tabOrderWithFocusProxy(); void taskQTBUG_7532_tabOrderWithFocusProxy();
void movedAndResizedAttributes(); void movedAndResizedAttributes();
void childAt(); void childAt();
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
void childAt_unifiedToolBar(); void childAt_unifiedToolBar();
void taskQTBUG_11373(); void taskQTBUG_11373();
#endif #endif
@ -2375,12 +2375,12 @@ void tst_QWidget::showMinimizedKeepsFocus()
window.showNormal(); window.showNormal();
qApp->setActiveWindow(&window); qApp->setActiveWindow(&window);
QVERIFY(QTest::qWaitForWindowActive(&window)); QVERIFY(QTest::qWaitForWindowActive(&window));
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
if (!macHasAccessToWindowsServer()) if (!macHasAccessToWindowsServer())
QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue); QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue);
#endif #endif
QTRY_COMPARE(window.focusWidget(), firstchild); QTRY_COMPARE(window.focusWidget(), firstchild);
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
if (!macHasAccessToWindowsServer()) if (!macHasAccessToWindowsServer())
QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue); QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue);
#endif #endif
@ -2720,7 +2720,7 @@ public:
void tst_QWidget::lostUpdatesOnHide() void tst_QWidget::lostUpdatesOnHide()
{ {
#ifndef Q_OS_MAC #ifndef Q_OS_OSX
UpdateWidget widget; UpdateWidget widget;
widget.setAttribute(Qt::WA_DontShowOnScreen); widget.setAttribute(Qt::WA_DontShowOnScreen);
widget.show(); widget.show();
@ -2762,7 +2762,7 @@ void tst_QWidget::raise()
QVERIFY(QTest::qWaitForWindowExposed(parentPtr.data())); QVERIFY(QTest::qWaitForWindowExposed(parentPtr.data()));
QTest::qWait(10); QTest::qWait(10);
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
if (child1->internalWinId()) { if (child1->internalWinId()) {
QSKIP("Cocoa has no Z-Order for views, we hack it, but it results in paint events."); QSKIP("Cocoa has no Z-Order for views, we hack it, but it results in paint events.");
} }
@ -2942,7 +2942,7 @@ void tst_QWidget::stackUnder()
foreach (UpdateWidget *child, allChildren) { foreach (UpdateWidget *child, allChildren) {
int expectedPaintEvents = child == child4 ? 1 : 0; int expectedPaintEvents = child == child4 ? 1 : 0;
#if defined(Q_OS_WIN) || defined(Q_OS_MAC) #if defined(Q_OS_WIN) || defined(Q_OS_OSX)
if (expectedPaintEvents == 1 && child->numPaintEvents == 2) if (expectedPaintEvents == 1 && child->numPaintEvents == 2)
QEXPECT_FAIL(0, "Mac and Windows issues double repaints for Z-Order change", Continue); QEXPECT_FAIL(0, "Mac and Windows issues double repaints for Z-Order change", Continue);
#endif #endif
@ -2981,7 +2981,7 @@ void tst_QWidget::stackUnder()
#ifdef Q_OS_WINCE #ifdef Q_OS_WINCE
qApp->processEvents(); qApp->processEvents();
#endif #endif
#ifndef Q_OS_MAC #ifndef Q_OS_OSX
QEXPECT_FAIL(0, "See QTBUG-493", Continue); QEXPECT_FAIL(0, "See QTBUG-493", Continue);
#endif #endif
QCOMPARE(child->numPaintEvents, 0); QCOMPARE(child->numPaintEvents, 0);
@ -3518,7 +3518,7 @@ void tst_QWidget::testDeletionInEventHandlers()
delete w; delete w;
} }
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
void tst_QWidget::sheetOpacity() void tst_QWidget::sheetOpacity()
{ {
QWidget tmpWindow; QWidget tmpWindow;
@ -4309,7 +4309,7 @@ void tst_QWidget::update()
QCOMPARE(sibling.numPaintEvents, 1); QCOMPARE(sibling.numPaintEvents, 1);
QCOMPARE(sibling.paintedRegion, sibling.visibleRegion()); QCOMPARE(sibling.paintedRegion, sibling.visibleRegion());
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
if (child.internalWinId()) // child is native if (child.internalWinId()) // child is native
QEXPECT_FAIL(0, "Cocoa compositor paints child and sibling", Continue); QEXPECT_FAIL(0, "Cocoa compositor paints child and sibling", Continue);
#endif #endif
@ -4335,7 +4335,7 @@ static inline bool isOpaque(QWidget *widget)
void tst_QWidget::isOpaque() void tst_QWidget::isOpaque()
{ {
#ifndef Q_OS_MAC #ifndef Q_OS_OSX
QWidget w; QWidget w;
QVERIFY(::isOpaque(&w)); QVERIFY(::isOpaque(&w));
@ -4407,7 +4407,7 @@ void tst_QWidget::isOpaque()
#endif #endif
} }
#ifndef Q_OS_MAC #ifndef Q_OS_OSX
/* /*
Test that scrolling of a widget invalidates the correct regions Test that scrolling of a widget invalidates the correct regions
*/ */
@ -4854,7 +4854,7 @@ void tst_QWidget::windowMoveResize()
widget.move(r.topLeft()); widget.move(r.topLeft());
widget.resize(r.size()); widget.resize(r.size());
QApplication::processEvents(); QApplication::processEvents();
#if defined(Q_OS_MAC) #if defined(Q_OS_OSX)
if (r.width() == 0 && r.height() > 0) { if (r.width() == 0 && r.height() > 0) {
widget.move(r.topLeft()); widget.move(r.topLeft());
widget.resize(r.size()); widget.resize(r.size());
@ -4925,7 +4925,7 @@ void tst_QWidget::windowMoveResize()
widget.move(r.topLeft()); widget.move(r.topLeft());
widget.resize(r.size()); widget.resize(r.size());
QApplication::processEvents(); QApplication::processEvents();
#if defined(Q_OS_MAC) #if defined(Q_OS_OSX)
if (r.width() == 0 && r.height() > 0) { if (r.width() == 0 && r.height() > 0) {
widget.move(r.topLeft()); widget.move(r.topLeft());
widget.resize(r.size()); widget.resize(r.size());
@ -5115,7 +5115,7 @@ void tst_QWidget::moveChild()
QTRY_COMPARE(pos, child.pos()); QTRY_COMPARE(pos, child.pos());
QCOMPARE(parent.r, QRegion(oldGeometry) - child.geometry()); QCOMPARE(parent.r, QRegion(oldGeometry) - child.geometry());
#if !defined(Q_OS_MAC) #if !defined(Q_OS_OSX)
// should be scrolled in backingstore // should be scrolled in backingstore
QCOMPARE(child.r, QRegion()); QCOMPARE(child.r, QRegion());
#endif #endif
@ -5857,7 +5857,7 @@ public:
startTimer(1000); startTimer(1000);
} }
void timerEvent(QTimerEvent *) void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE
{ {
switch (state++) { switch (state++) {
case 0: case 0:
@ -5880,7 +5880,7 @@ public:
return false; return false;
} }
bool nativeEvent(const QByteArray &eventType, void *message, long *) bool nativeEvent(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE
{ {
if (isMapNotify(eventType, message)) if (isMapNotify(eventType, message))
gotExpectedMapNotify = true; gotExpectedMapNotify = true;
@ -5888,7 +5888,7 @@ public:
} }
// QAbstractNativeEventFilter interface // QAbstractNativeEventFilter interface
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE bool nativeEventFilter(const QByteArray &eventType, void *message, long *) Q_DECL_OVERRIDE
{ {
if (isMapNotify(eventType, message)) if (isMapNotify(eventType, message))
gotExpectedGlobalEvent = true; gotExpectedGlobalEvent = true;
@ -6907,7 +6907,7 @@ void tst_QWidget::render_systemClip()
// rrrrrrrrrr // rrrrrrrrrr
// ... // ...
#ifndef Q_OS_MAC #ifndef Q_OS_OSX
for (int i = 0; i < image.height(); ++i) { for (int i = 0; i < image.height(); ++i) {
for (int j = 0; j < image.width(); ++j) { for (int j = 0; j < image.width(); ++j) {
if (i < 50 && j < i) if (i < 50 && j < i)
@ -7911,7 +7911,7 @@ void tst_QWidget::sendUpdateRequestImmediately()
void tst_QWidget::doubleRepaint() void tst_QWidget::doubleRepaint()
{ {
#if defined(Q_OS_MAC) #if defined(Q_OS_OSX)
if (!macHasAccessToWindowsServer()) if (!macHasAccessToWindowsServer())
QSKIP("Not having window server access causes the wrong number of repaints to be issues"); QSKIP("Not having window server access causes the wrong number of repaints to be issues");
#endif #endif
@ -8621,7 +8621,7 @@ void tst_QWidget::setClearAndResizeMask()
QTRY_COMPARE(child.mask(), childMask); QTRY_COMPARE(child.mask(), childMask);
QTest::qWait(50); QTest::qWait(50);
// and ensure that the child widget doesn't get any update. // and ensure that the child widget doesn't get any update.
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
// Mac always issues a full update when calling setMask, and we cannot force it to not do so. // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
if (child.internalWinId()) if (child.internalWinId())
QCOMPARE(child.numPaintEvents, 1); QCOMPARE(child.numPaintEvents, 1);
@ -8644,7 +8644,7 @@ void tst_QWidget::setClearAndResizeMask()
// and ensure that that the child widget gets an update for the area outside the old mask. // and ensure that that the child widget gets an update for the area outside the old mask.
QTRY_COMPARE(child.numPaintEvents, 1); QTRY_COMPARE(child.numPaintEvents, 1);
outsideOldMask = child.rect(); outsideOldMask = child.rect();
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
// Mac always issues a full update when calling setMask, and we cannot force it to not do so. // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
if (!child.internalWinId()) if (!child.internalWinId())
#endif #endif
@ -8659,7 +8659,7 @@ void tst_QWidget::setClearAndResizeMask()
// Mask child widget with a mask that is bigger than the rect // Mask child widget with a mask that is bigger than the rect
child.setMask(QRegion(0, 0, 1000, 1000)); child.setMask(QRegion(0, 0, 1000, 1000));
QTest::qWait(100); QTest::qWait(100);
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
// Mac always issues a full update when calling setMask, and we cannot force it to not do so. // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
if (child.internalWinId()) if (child.internalWinId())
QTRY_COMPARE(child.numPaintEvents, 1); QTRY_COMPARE(child.numPaintEvents, 1);
@ -8672,7 +8672,7 @@ void tst_QWidget::setClearAndResizeMask()
// ...and the same applies when clearing the mask. // ...and the same applies when clearing the mask.
child.clearMask(); child.clearMask();
QTest::qWait(100); QTest::qWait(100);
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
// Mac always issues a full update when calling setMask, and we cannot force it to not do so. // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
if (child.internalWinId()) if (child.internalWinId())
QTRY_VERIFY(child.numPaintEvents > 0); QTRY_VERIFY(child.numPaintEvents > 0);
@ -8702,7 +8702,7 @@ void tst_QWidget::setClearAndResizeMask()
QTimer::singleShot(100, &resizeChild, SLOT(shrinkMask())); QTimer::singleShot(100, &resizeChild, SLOT(shrinkMask()));
QTest::qWait(200); QTest::qWait(200);
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
// Mac always issues a full update when calling setMask, and we cannot force it to not do so. // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
if (child.internalWinId()) if (child.internalWinId())
QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask());
@ -8714,7 +8714,7 @@ void tst_QWidget::setClearAndResizeMask()
const QRegion oldMask = resizeChild.mask(); const QRegion oldMask = resizeChild.mask();
QTimer::singleShot(0, &resizeChild, SLOT(enlargeMask())); QTimer::singleShot(0, &resizeChild, SLOT(enlargeMask()));
QTest::qWait(100); QTest::qWait(100);
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
// Mac always issues a full update when calling setMask, and we cannot force it to not do so. // Mac always issues a full update when calling setMask, and we cannot force it to not do so.
if (child.internalWinId()) if (child.internalWinId())
QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask()); QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask());
@ -9427,7 +9427,7 @@ void tst_QWidget::taskQTBUG_7532_tabOrderWithFocusProxy()
void tst_QWidget::movedAndResizedAttributes() void tst_QWidget::movedAndResizedAttributes()
{ {
#if defined (Q_OS_MAC) #if defined (Q_OS_OSX)
QEXPECT_FAIL("", "FixMe, QTBUG-8941 and QTBUG-8977", Abort); QEXPECT_FAIL("", "FixMe, QTBUG-8941 and QTBUG-8977", Abort);
QVERIFY(false); QVERIFY(false);
#else #else
@ -9534,7 +9534,7 @@ void tst_QWidget::childAt()
QCOMPARE(parent.childAt(120, 120), grandChild); QCOMPARE(parent.childAt(120, 120), grandChild);
} }
#ifdef Q_OS_MAC #ifdef Q_OS_OSX
void tst_QWidget::childAt_unifiedToolBar() void tst_QWidget::childAt_unifiedToolBar()
{ {
QLabel *label = new QLabel(QLatin1String("foo")); QLabel *label = new QLabel(QLatin1String("foo"));

View File

@ -1,6 +1,5 @@
QT += widgets QT += widgets
SOURCES = main.cpp SOURCES = main.cpp
OTHER_FILES = glyphshaping_data.xml
glyphshaping_data.path = . glyphshaping_data.path = .
glyphshaping_data.files = $$PWD/glyphshaping_data.xml glyphshaping_data.files = $$PWD/glyphshaping_data.xml
DEPLOYMENT += glyphshaping_data DEPLOYMENT += glyphshaping_data

View File

@ -256,6 +256,9 @@ QColor Point::color() const
case Qt::MouseEventSynthesizedByQt: case Qt::MouseEventSynthesizedByQt:
globalColor = Qt::blue; globalColor = Qt::blue;
break; break;
case Qt::MouseEventSynthesizedByApplication:
globalColor = Qt::green;
break;
case Qt::MouseEventNotSynthesized: case Qt::MouseEventNotSynthesized:
break; break;
} }

View File

@ -1651,6 +1651,7 @@ void Configure::applySpecSpecifics()
dictionary["DECORATIONS"] = "default windows styled"; dictionary["DECORATIONS"] = "default windows styled";
} else if (platform() == QNX) { } else if (platform() == QNX) {
dictionary[ "REDUCE_EXPORTS" ] = "yes";
dictionary["STACK_PROTECTOR_STRONG"] = "auto"; dictionary["STACK_PROTECTOR_STRONG"] = "auto";
dictionary["SLOG2"] = "auto"; dictionary["SLOG2"] = "auto";
dictionary["QNX_IMF"] = "auto"; dictionary["QNX_IMF"] = "auto";
@ -1660,6 +1661,7 @@ void Configure::applySpecSpecifics()
dictionary[ "ANGLE" ] = "no"; dictionary[ "ANGLE" ] = "no";
dictionary[ "DYNAMICGL" ] = "no"; dictionary[ "DYNAMICGL" ] = "no";
dictionary[ "FONT_CONFIG" ] = "auto"; dictionary[ "FONT_CONFIG" ] = "auto";
dictionary[ "ICU" ] = "auto";
dictionary[ "POLL" ] = "poll"; dictionary[ "POLL" ] = "poll";
} else if (platform() == ANDROID) { } else if (platform() == ANDROID) {
dictionary[ "REDUCE_EXPORTS" ] = "yes"; dictionary[ "REDUCE_EXPORTS" ] = "yes";