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
examples/tools/plugandpaint/plugins
include/*
include/*/*
lib/*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,3 +16,6 @@ qtHaveModule(widgets) {
textures \
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
\ingroup examples-widgets-tools
@ -47,8 +47,8 @@
through plugins, we recommend that you start by reading this
overview, which explains how to make an application use plugins.
Afterwards, you can read the
\l{tools/plugandpaintplugins/basictools}{Basic Tools} and
\l{tools/plugandpaintplugins/extrafilters}{Extra Filters}
\l{tools/plugandpaint/plugins/basictools}{Basic Tools} and
\l{tools/plugandpaint/plugins/extrafilters}{Extra Filters}
overviews, which show how to implement static and dynamic
plugins, respectively.
@ -74,7 +74,7 @@
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 first pure virtual function, \c brushes(), returns a list of
@ -96,7 +96,7 @@
virtual destructor. We provide the destructor to keep these
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
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
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
that returns a list of filter names, and a \c filterImage()
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
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
above.
The \l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin
and the \l{tools/plugandpaintplugins/extrafilters}{Extra Filters}
The \l{tools/plugandpaint/plugins/basictools}{Basic Tools} plugin
and the \l{tools/plugandpaint/plugins/extrafilters}{Extra Filters}
plugin shows how to derive from \c BrushInterface, \c
ShapeInterface, and \c FilterInterface.
@ -144,7 +144,7 @@
\l{mainwindows/application}{Application}). Here, we'll
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
constructor to detect plugins and update the \uicontrol{Brush},
@ -155,7 +155,7 @@
QObject. That QObject implements plugin interfaces using multiple
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
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
take this into account.
\snippet tools/plugandpaint/mainwindow.cpp 6
\snippet tools/plugandpaint/mainwindow.cpp 7
\snippet tools/plugandpaint/mainwindow.cpp 8
\snippet tools/plugandpaint/app/mainwindow.cpp 6
\snippet tools/plugandpaint/app/mainwindow.cpp 7
\snippet tools/plugandpaint/app/mainwindow.cpp 8
We use QDir::entryList() to get a list of all files in that
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.
\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},
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
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
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
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
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 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
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
shapes from the \uicontrol{Shapes} menu. We retrieve the QAction that
@ -230,7 +230,7 @@
QAction, and finally we call \c ShapeInterface::generateShape()
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
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
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
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},
we call the \c BrushInterface::mouseMove() function on the
@ -262,7 +262,7 @@
and a list of plugin file names. It calls \c findPlugins()
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
MainWindow::loadPlugins(). It uses QPluginLoader to access the
@ -270,11 +270,11 @@
populateTreeWidget() uses \l qobject_cast() to find out which
interfaces are implemented by the plugins:
\snippet tools/plugandpaint/plugindialog.cpp 1
\snippet tools/plugandpaint/app/plugindialog.cpp 1
\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
available to the application. This requires using the
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
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
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.
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
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
supports it on all platforms.)
@ -306,19 +306,19 @@
This completes our review of the Plug & Paint application. At
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.
*/
/*!
\example tools/plugandpaintplugins/basictools
\example tools/plugandpaint/plugins/basictools
\title Plug & Paint Basic Tools Example
\brief A plugin providing the basic tools for painting functionality.
\image plugandpaint.png Screenshot of the Plug & Paint example
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
example, we will review the four steps involved in writing a Qt
plugin:
@ -332,13 +332,13 @@
\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
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
INCLUDEPATH entry to the \c .pro file with the path to Qt's \c
examples/tools directory.
INCLUDEPATH entry to the \c .pro file with the path to the
header file.
The \c BasicToolsPlugin class is a QObject subclass that
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
meta-object compiler, that the base classes are plugin
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.
For an explanation for the \c Q_PLUGIN_METADATA() macro see
\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
functions from the three interfaces.
@ -361,23 +361,23 @@
Let's now review the implementation of the \c BasicToolsPlugin
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
this plugin. We provide three brushes: \uicontrol{Pencil}, \uicontrol{Air
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
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
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:
@ -399,14 +399,14 @@
At the end, we restore the painter state to what it was upon
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
empty QRect.
\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
\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
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
shape. If the shape is \uicontrol{Text}, we pop up a QInputDialog to
@ -426,12 +426,12 @@
\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
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
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
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,
so it just contains an empty json object.
@ -463,7 +463,7 @@
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
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
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
in its \c .pro file.
The \c INCLUDEPATH variable sets the search paths for global
headers (i.e., header files included using \c{#include <...>}).
We add Qt's \c examples/tools directory (strictly speaking,
\c{examples/tools/plugandpaintplugins/basictools/../..}) to the
list, so that we can include \c <plugandpaint/interfaces.h>.
We add \c ../../app to the list, so that we can include
\c <interfaces.h>.
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
@ -499,27 +498,27 @@
*/
/*!
\example tools/plugandpaintplugins/extrafilters
\example tools/plugandpaint/plugins/extrafilters
\title Plug & Paint Extra Filters Example
\brief A plugin providing the extra filters.
\image plugandpaint.png Screenshot of the Plug & Paint example
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
\l{tools/plugandpaintplugins/basictools}{Basic Tools} plugin.
\l{tools/plugandpaint/plugins/basictools}{Basic Tools} plugin.
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
\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).
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
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
headers (i.e., header files included using \c{#include <...>}).
We add Qt's \c examples/tools directory (strictly speaking,
\c{examples/tools/plugandpaintplugins/basictools/../..}) to the
list, so that we can include \c <plugandpaint/interfaces.h>.
We add \c ../../app to the list, so that we can include
\c <interfaces.h>.
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

View File

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

View File

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

View File

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

View File

@ -12,5 +12,7 @@ DESTDIR = ../plugins
EXAMPLE_FILES = echoplugin.json
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin/plugin
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tools/echoplugin/plugins
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]
QT += widgets
TEMPLATE = subdirs
SUBDIRS = plugins app
HEADERS = interfaces.h \
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
app.depends = plugins

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,13 +18,24 @@ defineReplace(qtStripProPwd) {
for (cp, COPIES) {
isEmpty($${cp}.files): next()
pfx = copy_$${cp}
for (f, $${cp}.files): \
$${pfx}.files += $$absolute_path($$f, $$_PRO_FILE_PWD_)
notdir = false
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)
isEmpty(path): error("COPY $cp defines no .path")
isEmpty(path): error("COPIES entry $$cp defines no .path")
base = $$eval($${cp}.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_) {
$${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripProPwd}
} else {
@ -34,7 +45,12 @@ for (cp, COPIES) {
$${pfx}.output = $$path/${QMAKE_FUNC_FILE_IN_qtStripSrcDir_$$cp}
}
$${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}.CONFIG = no_link no_clean target_predeps
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_)
# Only for Qt Creator's project view
OTHER_FILES += $$fq_qml_files
qml1_target: \
instbase = $$[QT_INSTALL_IMPORTS]
else: \

View File

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

View File

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

View File

@ -170,7 +170,7 @@ QImage scaledToWith(const QImage &image)
//! [13]
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]
//! [14]

View File

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

View File

@ -264,7 +264,7 @@ void QFileSystemMetaData::fillFromStatBuf(const QT_STATBUF &statBuffer)
entryFlags |= QFileSystemMetaData::FileType;
else if ((statBuffer.st_mode & S_IFMT) == S_IFDIR)
entryFlags |= QFileSystemMetaData::DirectoryType;
else
else if ((statBuffer.st_mode & S_IFMT) != S_IFBLK)
entryFlags |= QFileSystemMetaData::SequentialType;
// Attributes
@ -347,6 +347,18 @@ void QFileSystemMetaData::fillFromDirEnt(const QT_DIRENT &entry)
break;
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_FIFO:
case DT_SOCK:

View File

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

View File

@ -1103,7 +1103,6 @@ bool QProcessPrivate::_q_canReadStandardError()
*/
bool QProcessPrivate::_q_canWrite()
{
Q_Q(QProcess);
if (stdinChannel.notifier)
stdinChannel.notifier->setEnabled(false);
@ -1114,31 +1113,13 @@ bool QProcessPrivate::_q_canWrite()
return false;
}
qint64 written = writeToStdin(writeBuffer.readPointer(), writeBuffer.nextDataBlockSize());
if (written < 0) {
closeChannel(&stdinChannel);
setErrorAndEmit(QProcess::WriteError);
return false;
}
const bool writeSucceeded = writeToStdin();
#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())
stdinChannel.notifier->setEnabled(true);
if (writeBuffer.isEmpty() && stdinChannel.closed)
closeWriteChannel();
return true;
return writeSucceeded;
}
/*!

View File

@ -379,7 +379,7 @@ public:
qint64 bytesAvailableInChannel(const Channel *channel) const;
qint64 readFromChannel(const Channel *channel, char *data, qint64 maxlen);
qint64 writeToStdin(const char *data, qint64 maxlen);
bool writeToStdin();
void cleanup();
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;
}
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
qDebug("QProcessPrivate::writeToStdin(%p \"%s\", %lld) == %lld",
data, qt_prettyDebug(data, maxlen, 16).constData(), maxlen, written);
qDebug("QProcessPrivate::writeToStdin(), write(%p \"%s\", %lld) == %lld",
data, qt_prettyDebug(data, bytesToWrite, 16).constData(), bytesToWrite, written);
if (written == -1)
qDebug("QProcessPrivate::writeToStdin(), failed to write (%s)", qPrintable(qt_error_string(errno)));
#endif
// If the O_NONBLOCK flag is set and If some data can be written without blocking
// the process, write() will transfer what it can and return the number of bytes written.
// Otherwise, it will return -1 and set errno to EAGAIN
if (written == -1 && errno == EAGAIN)
written = 0;
return written;
if (written == -1) {
// If the O_NONBLOCK flag is set and If some data can be written without blocking
// the process, write() will transfer what it can and return the number of bytes written.
// Otherwise, it will return -1 and set errno to EAGAIN
if (errno == EAGAIN)
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()

View File

@ -805,17 +805,23 @@ qint64 QProcessPrivate::pipeWriterBytesToWrite() const
return stdinChannel.writer ? stdinChannel.writer->bytesToWrite() : qint64(0);
}
qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
bool QProcessPrivate::writeToStdin()
{
Q_Q(QProcess);
if (!stdinChannel.writer) {
stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q);
QObject::connect(stdinChannel.writer, &QWindowsPipeWriter::bytesWritten,
q, &QProcess::bytesWritten);
QObjectPrivate::connect(stdinChannel.writer, &QWindowsPipeWriter::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

View File

@ -271,11 +271,9 @@ qint64 QProcessPrivate::pipeWriterBytesToWrite() const
return 0;
}
qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
bool QProcessPrivate::writeToStdin()
{
Q_UNUSED(data);
Q_UNUSED(maxlen);
return -1;
return false;
}
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)
{
if (!writeSequenceStarted)
return false;
if (bytesWrittenPending) {
if (!inBytesWritten)
emitPendingBytesWrittenValue();
emitPendingBytesWrittenValue();
return true;
}
if (!writeSequenceStarted)
return false;
if (!waitForNotification(msecs))
return false;
if (bytesWrittenPending) {
if (!inBytesWritten)
emitPendingBytesWrittenValue();
emitPendingBytesWrittenValue();
return true;
}
@ -102,20 +100,24 @@ bool QWindowsPipeWriter::waitForWrite(int msecs)
qint64 QWindowsPipeWriter::bytesToWrite() const
{
return numberOfBytesToWrite;
return numberOfBytesToWrite + pendingBytesWrittenValue;
}
void QWindowsPipeWriter::emitPendingBytesWrittenValue()
{
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;
const qint64 bytes = pendingBytesWrittenValue;
pendingBytesWrittenValue = 0;
inBytesWritten = true;
emit bytesWritten(bytes);
inBytesWritten = false;
emit canWrite();
if (!inBytesWritten) {
inBytesWritten = true;
emit bytesWritten(bytes);
inBytesWritten = false;
}
}
}
@ -135,6 +137,8 @@ void QWindowsPipeWriter::notified(DWORD errorCode, DWORD numberOfBytesWritten)
notifiedCalled = true;
writeSequenceStarted = false;
numberOfBytesToWrite = 0;
Q_ASSERT(errorCode != ERROR_SUCCESS || numberOfBytesWritten == DWORD(buffer.size()));
buffer.clear();
switch (errorCode) {
case ERROR_SUCCESS:
@ -179,21 +183,26 @@ bool QWindowsPipeWriter::waitForNotification(int timeout)
return notifiedCalled;
}
qint64 QWindowsPipeWriter::write(const char *ptr, qint64 maxlen)
bool QWindowsPipeWriter::write(const QByteArray &ba)
{
if (writeSequenceStarted)
return 0;
return false;
overlapped.clear();
numberOfBytesToWrite = maxlen;
buffer = ba;
numberOfBytesToWrite = buffer.size();
stopped = false;
writeSequenceStarted = true;
if (!WriteFileEx(handle, ptr, maxlen, &overlapped, &writeFileCompleted)) {
if (!WriteFileEx(handle, buffer.constData(), numberOfBytesToWrite,
&overlapped, &writeFileCompleted)) {
writeSequenceStarted = false;
numberOfBytesToWrite = 0;
buffer.clear();
qErrnoWarning("QWindowsPipeWriter::write failed.");
return false;
}
return maxlen;
return true;
}
void QWindowsPipeWriter::stop()

View File

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

View File

@ -1130,7 +1130,7 @@ QObjectPrivate::Connection::~Connection()
RTTI support and it works across dynamic library boundaries.
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
function's return value is undefined.
@ -4160,11 +4160,11 @@ QDebug operator<<(QDebug dbg, const QObject *o)
Example:
\snippet ../widgets/tools/plugandpaintplugins/basictools/basictoolsplugin.h 1
\snippet ../widgets/tools/plugandpaint/plugins/basictools/basictoolsplugin.h 1
\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.
\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
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
\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
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
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.

View File

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

View File

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

View File

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

View File

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

View File

@ -69,6 +69,10 @@
QT_BEGIN_NAMESPACE
#ifdef Q_OS_WIN
static void preventDllUnload();
#endif
Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager)
// can be replaced with a lambda in Qt 5.7
@ -157,6 +161,10 @@ QDBusConnectionManager::QDBusConnectionManager()
this, &QDBusConnectionManager::createServer, Qt::BlockingQueuedConnection);
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;
start();
}
@ -1282,4 +1290,31 @@ QT_END_NAMESPACE
#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

View File

@ -2146,6 +2146,17 @@ bool QWindow::event(QEvent *ev)
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:
return QObject::event(ev);
}

View File

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

View File

@ -52,6 +52,7 @@
//
#include <QOpenGLShaderProgram>
#include <QtGlobal>
QT_BEGIN_NAMESPACE
@ -78,6 +79,8 @@ protected:
private:
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);
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) {
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->restore();
} 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();
if (uc.isValid())
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()
{

View File

@ -42,7 +42,6 @@
#include <qlibrary.h>
#include <qscopedpointer.h>
#include <qurl.h>
#include <private/qmutexpool_p.h>
#include <private/qnativesocketengine_p.h>
#include <sys/types.h>
@ -78,7 +77,7 @@ struct QDnsLookupStateDeleter
}
};
static void resolveLibrary()
static bool resolveLibraryInternal()
{
QLibrary lib;
#ifdef LIBRESOLV_SO
@ -88,7 +87,7 @@ static void resolveLibrary()
{
lib.setFileName(QLatin1String("resolv"));
if (!lib.load())
return;
return false;
}
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"));
if (!local_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)
{
// Load dn_expand, res_ninit and res_nquery on demand.
static QBasicAtomicInt triedResolve = Q_BASIC_ATOMIC_INITIALIZER(false);
if (!triedResolve.loadAcquire()) {
QMutexLocker locker(QMutexPool::globalInstanceGet(&local_res_ninit));
if (!triedResolve.load()) {
resolveLibrary();
triedResolve.storeRelease(true);
}
}
resolveLibrary();
// If dn_expand, res_ninit or res_nquery is missing, fail.
if (!local_dn_expand || !local_res_nclose || !local_res_ninit || !local_res_nquery) {

View File

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

View File

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

View File

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

View File

@ -218,11 +218,12 @@ qint64 QLocalSocket::writeData(const char *data, qint64 len)
memcpy(dest, data, len);
if (!d->pipeWriter) {
d->pipeWriter = new QWindowsPipeWriter(d->handle, this);
QObjectPrivate::connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten,
d, &QLocalSocketPrivate::_q_bytesWritten);
connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten,
this, &QLocalSocket::bytesWritten);
QObjectPrivate::connect(d->pipeWriter, &QWindowsPipeWriter::canWrite,
d, &QLocalSocketPrivate::_q_canWrite);
}
if (!d->pipeWriter->isWriteOperationActive())
d->startNextWrite();
d->_q_canWrite();
return len;
}
@ -275,7 +276,7 @@ qint64 QLocalSocket::bytesAvailable() const
qint64 QLocalSocket::bytesToWrite() const
{
Q_D(const QLocalSocket);
return d->writeBuffer.size();
return d->writeBuffer.size() + (d->pipeWriter ? d->pipeWriter->bytesToWrite() : 0);
}
bool QLocalSocket::canReadLine() const
@ -358,7 +359,7 @@ bool QLocalSocket::setSocketDescriptor(qintptr socketDescriptor,
return true;
}
void QLocalSocketPrivate::startNextWrite()
void QLocalSocketPrivate::_q_canWrite()
{
Q_Q(QLocalSocket);
if (writeBuffer.isEmpty()) {
@ -366,18 +367,11 @@ void QLocalSocketPrivate::startNextWrite()
q->close();
} else {
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
{
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));
if (::getpeername(socketDescriptor, &sa.a, &sockAddrSize) == 0) {
qt_socket_getPortAndAddress(socketDescriptor, &sa, &peerPort, &peerAddress);
@ -1186,7 +1199,7 @@ qint64 QNativeSocketEnginePrivate::nativePendingDatagramSize() const
#endif
#if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %li", ret);
qDebug("QNativeSocketEnginePrivate::nativePendingDatagramSize() == %lli", ret);
#endif
return ret;
@ -1292,10 +1305,11 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxL
}
#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,
address ? address->toString().toLatin1().constData() : "(nil)",
port ? *port : 0, ret);
printSender ? header->senderAddress.toString().toLatin1().constData() : "(unknown)",
printSender ? header->senderPort : 0, ret);
#endif
return ret;
@ -1407,9 +1421,10 @@ qint64 QNativeSocketEnginePrivate::nativeSendDatagram(const char *data, qint64 l
}
#if defined (QNATIVESOCKETENGINE_DEBUG)
qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %li, \"%s\", %i) == %li", data,
qt_prettyDebug(data, qMin<qint64>(len, 16), len).data(), 0, address.toString().toLatin1().constData(),
port, ret);
qDebug("QNativeSocketEnginePrivate::nativeSendDatagram(%p \"%s\", %lli, \"%s\", %i) == %lli", data,
qt_prettyDebug(data, qMin<qint64>(len, 16), len).data(), len,
header.destinationAddress.toString().toLatin1().constData(),
header.destinationPort, ret);
#endif
return ret;

View File

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

View File

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

View File

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

View File

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

View File

@ -186,18 +186,18 @@ QIOSScreen::QIOSScreen(UIScreen *screen)
if (deviceIdentifier.contains(QRegularExpression("^iPhone(7,1|8,2)$"))) {
// 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])$"))) {
// All iPads except the iPad Mini series
m_pixelDensity = 132 * devicePixelRatio();
m_physicalDpi = 132 * devicePixelRatio();
} else {
// All non-Plus iPhones, and iPad Minis
m_pixelDensity = 163 * devicePixelRatio();
m_physicalDpi = 163 * devicePixelRatio();
}
} else {
// External display, hard to say
m_depth = 24;
m_pixelDensity = 96;
m_physicalDpi = 96;
}
for (UIWindow *existingWindow in [[UIApplication sharedApplication] windows]) {
@ -259,8 +259,23 @@ void QIOSScreen::updateProperties()
}
if (m_geometry != previousGeometry) {
const qreal millimetersPerInch = 25.4;
m_physicalSize = QSizeF(m_geometry.size() * devicePixelRatio()) / m_pixelDensity * millimetersPerInch;
QRectF physicalGeometry;
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

View File

@ -263,15 +263,15 @@ static int openTtyDevice(const QString &device)
return fd;
}
static bool switchToGraphicsMode(int ttyfd, int *oldMode)
static void switchToGraphicsMode(int ttyfd, bool doSwitch, int *oldMode)
{
ioctl(ttyfd, KDGETMODE, oldMode);
if (*oldMode != KD_GRAPHICS) {
if (ioctl(ttyfd, KDSETMODE, KD_GRAPHICS) != 0)
return false;
// 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. The matching
// call in resetTty should at least fail then, too, so we do no harm.
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)
@ -287,14 +287,16 @@ static void blankScreen(int fd, bool on)
}
QLinuxFbScreen::QLinuxFbScreen(const QStringList &args)
: mArgs(args), mFbFd(-1), mBlitter(0)
: mArgs(args), mFbFd(-1), mTtyFd(-1), mBlitter(0)
{
mMmap.data = 0;
}
QLinuxFbScreen::~QLinuxFbScreen()
{
if (mFbFd != -1) {
munmap(mMmap.data - mMmap.offset, mMmap.size);
if (mMmap.data)
munmap(mMmap.data - mMmap.offset, mMmap.size);
close(mFbFd);
}
@ -394,11 +396,7 @@ bool QLinuxFbScreen::initialize()
if (mTtyFd == -1)
qErrnoWarning(errno, "Failed to open tty");
if (doSwitchToGraphicsMode)
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.
switchToGraphicsMode(mTtyFd, doSwitchToGraphicsMode, &mOldTtyMode);
blankScreen(mFbFd, false);
return true;

View File

@ -1638,8 +1638,13 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex,
if (!m_xi2Enabled)
return false;
// compress XI_Motion
// compress XI_Motion, but not from tablet devices
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) {
xcb_generic_event_t *next = eventqueue->at(j);
if (!isValid(next))

View File

@ -584,6 +584,7 @@ private:
bool xi2HandleTabletEvent(const void *event, TabletData *tabletData);
void xi2ReportTabletEvent(const void *event, TabletData *tabletData);
QVector<TabletData> m_tabletData;
TabletData *tabletDataForDevice(int id);
#endif // !QT_NO_TABLETEVENT
struct ScrollingDevice {
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.
if (devices[i].use != XISlavePointer)
continue;
qCDebug(lcQpaXInputDevices) << "input device "<< devices[i].name;
qCDebug(lcQpaXInputDevices) << "input device " << devices[i].name << "ID" << devices[i].deviceid;
#ifndef QT_NO_TABLETEVENT
TabletData tabletData;
#endif
@ -537,12 +537,9 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
#ifndef QT_NO_TABLETEVENT
if (!xiEnterEvent) {
for (int i = 0; i < m_tabletData.count(); ++i) {
if (m_tabletData.at(i).deviceId == sourceDeviceId) {
if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i]))
return;
}
}
QXcbConnection::TabletData *tablet = tabletDataForDevice(sourceDeviceId);
if (tablet && xi2HandleTabletEvent(xiEvent, tablet))
return;
}
#endif // QT_NO_TABLETEVENT
@ -1195,6 +1192,16 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
xTilt, yTilt, tangentialPressure,
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 // XCB_USE_XINPUT2

View File

@ -1140,10 +1140,10 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
at = findTransactionByWindow(event->requestor);
}
if (at == -1 && event->time == XCB_CURRENT_TIME) {
if (at == -1) {
xcb_window_t target = findXdndAwareParent(connection(), event->requestor);
if (target) {
if (current_target == target)
if (event->time == XCB_CURRENT_TIME && current_target == target)
at = -2;
else
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.
\note The splitter takes ownership of the widget.
\sa insertWidget(), widget(), indexOf()
*/
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 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()
*/

View File

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

View File

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

View File

@ -116,6 +116,23 @@ static bool orderByModifier(const QVector<int> &v1, const QVector<int> &v2)
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()
{
struct Modifier
@ -155,7 +172,8 @@ void tst_QKeyEvent::modifiers_data()
mods |= modifier.modifier;
}
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>
#ifdef QT_NETWORK_LIB
#include <QtNetwork/QHostInfo>
#include <QtNetwork/QHostAddress>
#include <QtNetwork/QAbstractSocket>
#endif
#ifdef Q_OS_UNIX
@ -134,5 +136,21 @@ public:
}
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 <qtextstream.h>
#include <qdatastream.h>
#include <QtNetwork/qlocalsocket.h>
#include <QtNetwork/qlocalserver.h>
@ -73,6 +74,9 @@ private slots:
void readBufferOverflow();
void simpleCommandProtocol1();
void simpleCommandProtocol2();
void fullPath();
void hitMaximumConnections_data();
@ -622,6 +626,110 @@ void tst_QLocalSocket::readBufferOverflow()
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
void tst_QLocalSocket::fullPath()
{

View File

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

View File

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

View File

@ -31,18 +31,21 @@ class Server : public QObject
{
Q_OBJECT
public:
Server(int port)
Server() { connect(&serverSocket, &QIODevice::readyRead, this, &Server::sendEcho); }
bool bind(quint16 port)
{
connect(&serverSocket, SIGNAL(readyRead()),
this, SLOT(sendEcho()));
if (serverSocket.bind(QHostAddress::Any, port,
QUdpSocket::ReuseAddressHint
| QUdpSocket::ShareAddress)) {
const bool result = serverSocket.bind(QHostAddress::Any, port,
QUdpSocket::ReuseAddressHint
| QUdpSocket::ShareAddress);
if (result) {
printf("OK\n");
} else {
printf("FAILED\n");
printf("FAILED: %s\n", qPrintable(serverSocket.errorString()));
}
fflush(stdout);
return result;
}
private slots:
@ -68,8 +71,19 @@ private:
int main(int argc, char **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();
}

View File

@ -69,7 +69,7 @@
#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.
#endif
@ -136,7 +136,7 @@ bool qt_wince_is_smartphone() {
}
#endif
#ifdef Q_OS_MAC
#ifdef Q_OS_OSX
#include <Security/AuthSession.h>
bool macHasAccessToWindowsServer()
{
@ -263,7 +263,7 @@ private slots:
void restoreVersion1Geometry();
void widgetAt();
#ifdef Q_OS_MAC
#ifdef Q_OS_OSX
void sheetOpacity();
void setMask();
#endif
@ -296,7 +296,7 @@ private slots:
void update();
void isOpaque();
#ifndef Q_OS_MAC
#ifndef Q_OS_OSX
void scroll();
void scrollNativeChildren();
#endif
@ -429,7 +429,7 @@ private slots:
void taskQTBUG_7532_tabOrderWithFocusProxy();
void movedAndResizedAttributes();
void childAt();
#ifdef Q_OS_MAC
#ifdef Q_OS_OSX
void childAt_unifiedToolBar();
void taskQTBUG_11373();
#endif
@ -2375,12 +2375,12 @@ void tst_QWidget::showMinimizedKeepsFocus()
window.showNormal();
qApp->setActiveWindow(&window);
QVERIFY(QTest::qWaitForWindowActive(&window));
#ifdef Q_OS_MAC
#ifdef Q_OS_OSX
if (!macHasAccessToWindowsServer())
QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue);
#endif
QTRY_COMPARE(window.focusWidget(), firstchild);
#ifdef Q_OS_MAC
#ifdef Q_OS_OSX
if (!macHasAccessToWindowsServer())
QEXPECT_FAIL("", "When not having WindowServer access, we lose focus.", Continue);
#endif
@ -2720,7 +2720,7 @@ public:
void tst_QWidget::lostUpdatesOnHide()
{
#ifndef Q_OS_MAC
#ifndef Q_OS_OSX
UpdateWidget widget;
widget.setAttribute(Qt::WA_DontShowOnScreen);
widget.show();
@ -2762,7 +2762,7 @@ void tst_QWidget::raise()
QVERIFY(QTest::qWaitForWindowExposed(parentPtr.data()));
QTest::qWait(10);
#ifdef Q_OS_MAC
#ifdef Q_OS_OSX
if (child1->internalWinId()) {
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) {
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)
QEXPECT_FAIL(0, "Mac and Windows issues double repaints for Z-Order change", Continue);
#endif
@ -2981,7 +2981,7 @@ void tst_QWidget::stackUnder()
#ifdef Q_OS_WINCE
qApp->processEvents();
#endif
#ifndef Q_OS_MAC
#ifndef Q_OS_OSX
QEXPECT_FAIL(0, "See QTBUG-493", Continue);
#endif
QCOMPARE(child->numPaintEvents, 0);
@ -3518,7 +3518,7 @@ void tst_QWidget::testDeletionInEventHandlers()
delete w;
}
#ifdef Q_OS_MAC
#ifdef Q_OS_OSX
void tst_QWidget::sheetOpacity()
{
QWidget tmpWindow;
@ -4309,7 +4309,7 @@ void tst_QWidget::update()
QCOMPARE(sibling.numPaintEvents, 1);
QCOMPARE(sibling.paintedRegion, sibling.visibleRegion());
#ifdef Q_OS_MAC
#ifdef Q_OS_OSX
if (child.internalWinId()) // child is native
QEXPECT_FAIL(0, "Cocoa compositor paints child and sibling", Continue);
#endif
@ -4335,7 +4335,7 @@ static inline bool isOpaque(QWidget *widget)
void tst_QWidget::isOpaque()
{
#ifndef Q_OS_MAC
#ifndef Q_OS_OSX
QWidget w;
QVERIFY(::isOpaque(&w));
@ -4407,7 +4407,7 @@ void tst_QWidget::isOpaque()
#endif
}
#ifndef Q_OS_MAC
#ifndef Q_OS_OSX
/*
Test that scrolling of a widget invalidates the correct regions
*/
@ -4854,7 +4854,7 @@ void tst_QWidget::windowMoveResize()
widget.move(r.topLeft());
widget.resize(r.size());
QApplication::processEvents();
#if defined(Q_OS_MAC)
#if defined(Q_OS_OSX)
if (r.width() == 0 && r.height() > 0) {
widget.move(r.topLeft());
widget.resize(r.size());
@ -4925,7 +4925,7 @@ void tst_QWidget::windowMoveResize()
widget.move(r.topLeft());
widget.resize(r.size());
QApplication::processEvents();
#if defined(Q_OS_MAC)
#if defined(Q_OS_OSX)
if (r.width() == 0 && r.height() > 0) {
widget.move(r.topLeft());
widget.resize(r.size());
@ -5115,7 +5115,7 @@ void tst_QWidget::moveChild()
QTRY_COMPARE(pos, child.pos());
QCOMPARE(parent.r, QRegion(oldGeometry) - child.geometry());
#if !defined(Q_OS_MAC)
#if !defined(Q_OS_OSX)
// should be scrolled in backingstore
QCOMPARE(child.r, QRegion());
#endif
@ -5857,7 +5857,7 @@ public:
startTimer(1000);
}
void timerEvent(QTimerEvent *)
void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE
{
switch (state++) {
case 0:
@ -5880,7 +5880,7 @@ public:
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))
gotExpectedMapNotify = true;
@ -5888,7 +5888,7 @@ public:
}
// 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))
gotExpectedGlobalEvent = true;
@ -6907,7 +6907,7 @@ void tst_QWidget::render_systemClip()
// rrrrrrrrrr
// ...
#ifndef Q_OS_MAC
#ifndef Q_OS_OSX
for (int i = 0; i < image.height(); ++i) {
for (int j = 0; j < image.width(); ++j) {
if (i < 50 && j < i)
@ -7911,7 +7911,7 @@ void tst_QWidget::sendUpdateRequestImmediately()
void tst_QWidget::doubleRepaint()
{
#if defined(Q_OS_MAC)
#if defined(Q_OS_OSX)
if (!macHasAccessToWindowsServer())
QSKIP("Not having window server access causes the wrong number of repaints to be issues");
#endif
@ -8621,7 +8621,7 @@ void tst_QWidget::setClearAndResizeMask()
QTRY_COMPARE(child.mask(), childMask);
QTest::qWait(50);
// 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.
if (child.internalWinId())
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.
QTRY_COMPARE(child.numPaintEvents, 1);
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.
if (!child.internalWinId())
#endif
@ -8659,7 +8659,7 @@ void tst_QWidget::setClearAndResizeMask()
// Mask child widget with a mask that is bigger than the rect
child.setMask(QRegion(0, 0, 1000, 1000));
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.
if (child.internalWinId())
QTRY_COMPARE(child.numPaintEvents, 1);
@ -8672,7 +8672,7 @@ void tst_QWidget::setClearAndResizeMask()
// ...and the same applies when clearing the mask.
child.clearMask();
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.
if (child.internalWinId())
QTRY_VERIFY(child.numPaintEvents > 0);
@ -8702,7 +8702,7 @@ void tst_QWidget::setClearAndResizeMask()
QTimer::singleShot(100, &resizeChild, SLOT(shrinkMask()));
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.
if (child.internalWinId())
QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask());
@ -8714,7 +8714,7 @@ void tst_QWidget::setClearAndResizeMask()
const QRegion oldMask = resizeChild.mask();
QTimer::singleShot(0, &resizeChild, SLOT(enlargeMask()));
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.
if (child.internalWinId())
QTRY_COMPARE(resizeChild.paintedRegion, resizeChild.mask());
@ -9427,7 +9427,7 @@ void tst_QWidget::taskQTBUG_7532_tabOrderWithFocusProxy()
void tst_QWidget::movedAndResizedAttributes()
{
#if defined (Q_OS_MAC)
#if defined (Q_OS_OSX)
QEXPECT_FAIL("", "FixMe, QTBUG-8941 and QTBUG-8977", Abort);
QVERIFY(false);
#else
@ -9534,7 +9534,7 @@ void tst_QWidget::childAt()
QCOMPARE(parent.childAt(120, 120), grandChild);
}
#ifdef Q_OS_MAC
#ifdef Q_OS_OSX
void tst_QWidget::childAt_unifiedToolBar()
{
QLabel *label = new QLabel(QLatin1String("foo"));

View File

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

View File

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

View File

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