Merge remote-tracking branch 'origin/5.6' into dev
Change-Id: Ib43c6f126998eefcfed9a7c1f2bcbac8b4dd05ec
This commit is contained in:
commit
ea5f40a788
@ -237,7 +237,7 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:"
|
||||
#endif
|
||||
|
||||
// -- ARM --
|
||||
#ifdef __ARM_NEON__
|
||||
#if defined(__ARM_NEON) || defined(__ARM_NEON__)
|
||||
" neon"
|
||||
#endif
|
||||
#ifdef __IWMMXT__
|
||||
|
4
configure
vendored
4
configure
vendored
@ -455,7 +455,7 @@ DeviceVar()
|
||||
eq="="
|
||||
;;
|
||||
*)
|
||||
echo >&2 "BUG: wrong command to QMakeVar: $1"
|
||||
echo >&2 "BUG: wrong command to DeviceVar: $1"
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -7203,7 +7203,7 @@ if [ -n "$DISABLED_FEATURES" ]; then
|
||||
fi
|
||||
echo "QT_QCONFIG_PATH = ${CFG_QCONFIG_PATH#$relpath/src/corelib/global/}"
|
||||
|
||||
cat >>"$QTMODULE.tmp" <<EOF
|
||||
cat <<EOF
|
||||
host_build {
|
||||
QT_CPU_FEATURES.$CFG_HOST_ARCH = $CFG_HOST_CPUFEATURES
|
||||
} else {
|
||||
|
@ -105,6 +105,10 @@
|
||||
\externalpage http://doc.qt.io/qtcreator/qtcreator-transitions-example.html
|
||||
\title Qt Creator: Creating a Qt Quick Application
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/qtquick-iso-icon-browser.html
|
||||
\title Qt Creator: Browsing ISO 7000 Icons
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/quick-export-to-qml.html
|
||||
\title Qt Creator: Exporting Designs from Graphics Software
|
||||
@ -209,6 +213,10 @@
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-mime-types.html
|
||||
\title Qt Creator: Editing MIME Types
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-modeling.html
|
||||
\title Qt Creator: Modeling
|
||||
*/
|
||||
/*!
|
||||
\externalpage http://doc.qt.io/qtcreator/creator-qml-debugging-example.html
|
||||
\title Qt Creator: Debugging a Qt Quick Example Application
|
||||
|
@ -1261,6 +1261,9 @@ table td,table th {
|
||||
table.alignedsummary,table.propsummary {
|
||||
width:initial
|
||||
}
|
||||
table.valuelist td.tblval {
|
||||
font-size:0.75em
|
||||
}
|
||||
div.main_index .row {
|
||||
border-bottom:1px solid #eee
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ if(win32|mac):!macx-xcode {
|
||||
contains(QT_CONFIG, build_all):CONFIG += build_all
|
||||
}
|
||||
|
||||
CONFIG += relative_qt_rpath # Qt's QML plugins should be relocatable
|
||||
|
||||
!no_cxx_module:isEmpty(CXX_MODULE) {
|
||||
CXX_MODULE = $$TARGET
|
||||
TARGET = declarative_$${TARGET}
|
||||
|
@ -120,15 +120,9 @@ defineTest(qtAddTargetEnv) {
|
||||
deps = $$replace($$2, -private$, _private)
|
||||
deps = $$resolve_depends(deps, "QT.", ".depends" ".run_depends")
|
||||
!isEmpty(deps) {
|
||||
ptypes =
|
||||
for(dep, deps) {
|
||||
isEmpty(3): \
|
||||
deppath += $$shell_path($$eval(QT.$${dep}.libs))
|
||||
else: \
|
||||
deppath += $$system_path($$eval(QT.$${dep}.libs))
|
||||
ptypes += $$eval(QT.$${dep}.plugin_types)
|
||||
}
|
||||
libs = libs
|
||||
equals(QMAKE_HOST.os, Windows) {
|
||||
libs = bins
|
||||
deppath.name = PATH
|
||||
} else:contains(QMAKE_HOST.os, Linux|FreeBSD|OpenBSD|NetBSD|DragonFly|SunOS|HP-UX|QNX|GNU) {
|
||||
deppath.name = LD_LIBRARY_PATH
|
||||
@ -144,6 +138,14 @@ defineTest(qtAddTargetEnv) {
|
||||
} else {
|
||||
error("Operating system not supported.")
|
||||
}
|
||||
ptypes =
|
||||
for(dep, deps) {
|
||||
isEmpty(3): \
|
||||
deppath += $$shell_path($$eval(QT.$${dep}.$$libs))
|
||||
else: \
|
||||
deppath += $$system_path($$eval(QT.$${dep}.$$libs))
|
||||
ptypes += $$eval(QT.$${dep}.plugin_types)
|
||||
}
|
||||
deppath.value = $$unique(deppath)
|
||||
deppath.CONFIG = prepend
|
||||
|
||||
|
@ -40,6 +40,10 @@ $(EXPORT_SUBTARGETS): % : %-build
|
||||
%-install: ACTION = install
|
||||
%-install: xcodebuild-% ;
|
||||
|
||||
# iOS Simulator doesn't support archiving
|
||||
%-iphonesimulator-install: ACTION = build
|
||||
iphonesimulator-install: ACTION = build
|
||||
|
||||
# Limit check to a single configuration
|
||||
%-iphoneos-check: check-iphoneos ;
|
||||
%-iphonesimulator-check: check-iphonesimulator ;
|
||||
|
@ -596,14 +596,11 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
|
||||
continue;
|
||||
}
|
||||
x++;
|
||||
|
||||
int inc_len;
|
||||
for (inc_len = 0;
|
||||
buffer[x + inc_len] != term && !qmake_endOfLine(buffer[x + inc_len]);
|
||||
++inc_len) {} // skip until end of include name
|
||||
buffer[x + inc_len] = '\0';
|
||||
inc = buffer + x;
|
||||
x += inc_len;
|
||||
for (;
|
||||
buffer[x] != term && !qmake_endOfLine(buffer[x]);
|
||||
++x) {} // skip until end of include name
|
||||
buffer[x] = '\0';
|
||||
} else if (buffer[x] == '\'' || buffer[x] == '"') {
|
||||
const char term = buffer[x++];
|
||||
while(x < buffer_len) {
|
||||
|
1
src/3rdparty/libpng.pri
vendored
1
src/3rdparty/libpng.pri
vendored
@ -1,4 +1,3 @@
|
||||
DEFINES *= QT_USE_BUNDLED_LIBPNG
|
||||
DEFINES += PNG_ARM_NEON_OPT=0
|
||||
INCLUDEPATH += $$PWD/libpng
|
||||
SOURCES += $$PWD/libpng/png.c \
|
||||
|
@ -590,7 +590,7 @@ void QCoreApplicationPrivate::initLocale()
|
||||
|
||||
\section1 The Event Loop and Event Handling
|
||||
|
||||
The event loop is started with a call to exec(). Long running
|
||||
The event loop is started with a call to exec(). Long-running
|
||||
operations can call processEvents() to keep the application
|
||||
responsive.
|
||||
|
||||
@ -672,7 +672,7 @@ QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
|
||||
|
||||
#ifndef QT_NO_QOBJECT
|
||||
/*!
|
||||
Flushes the platform specific event queues.
|
||||
Flushes the platform-specific event queues.
|
||||
|
||||
If you are doing graphical changes inside a loop that does not
|
||||
return to the event loop on asynchronous window systems like X11
|
||||
@ -690,9 +690,9 @@ void QCoreApplication::flush()
|
||||
#endif
|
||||
|
||||
/*!
|
||||
Constructs a Qt kernel application. Kernel applications are
|
||||
applications without a graphical user interface. These type of
|
||||
applications are used at the console or as server processes.
|
||||
Constructs a Qt core application. Core applications are applications without
|
||||
a graphical user interface. Such applications are used at the console or as
|
||||
server processes.
|
||||
|
||||
The \a argc and \a argv arguments are processed by the application,
|
||||
and made available in a more convenient form by the arguments()
|
||||
@ -1174,7 +1174,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags)
|
||||
milliseconds or until there are no more events to process,
|
||||
whichever is shorter.
|
||||
|
||||
You can call this function occasionally when you program is busy
|
||||
You can call this function occasionally when your program is busy
|
||||
doing a long operation (e.g. copying a file).
|
||||
|
||||
Calling this function processes events only for the calling thread.
|
||||
@ -1201,9 +1201,9 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int m
|
||||
*****************************************************************************/
|
||||
|
||||
/*!
|
||||
Enters the main event loop and waits until exit() is called.
|
||||
Returns the value that was set to exit() (which is 0 if exit() is
|
||||
called via quit()).
|
||||
Enters the main event loop and waits until exit() is called. Returns
|
||||
the value that was passed to exit() (which is 0 if exit() is called via
|
||||
quit()).
|
||||
|
||||
It is necessary to call this function to start event handling. The
|
||||
main event loop receives events from the window system and
|
||||
@ -1459,7 +1459,8 @@ bool QCoreApplication::compressEvent(QEvent *event, QObject *receiver, QPostEven
|
||||
If \a receiver is null, the events of \a event_type are sent for all
|
||||
objects. If \a event_type is 0, all the events are sent for \a receiver.
|
||||
|
||||
\note This method must be called from the same thread as its QObject parameter, \a receiver.
|
||||
\note This method must be called from the thread in which its QObject
|
||||
parameter, \a receiver, lives.
|
||||
|
||||
\sa flush(), postEvent()
|
||||
*/
|
||||
@ -1805,7 +1806,7 @@ void QCoreApplication::quit()
|
||||
This signal is emitted when the application is about to quit the
|
||||
main event loop, e.g. when the event loop level drops to zero.
|
||||
This may happen either after a call to quit() from inside the
|
||||
application or when the users shuts down the entire desktop session.
|
||||
application or when the user shuts down the entire desktop session.
|
||||
|
||||
The signal is particularly useful if your application has to do some
|
||||
last-second cleanup. Note that no user interaction is possible in
|
||||
@ -2035,8 +2036,8 @@ void QCoreApplicationPrivate::setApplicationFilePath(const QString &path)
|
||||
directory, and you run the \c{regexp} example, this function will
|
||||
return "C:/Qt/examples/tools/regexp".
|
||||
|
||||
On OS X and iOS this will point to the directory actually containing the
|
||||
executable, which may be inside of an application bundle (if the
|
||||
On OS X and iOS this will point to the directory actually containing
|
||||
the executable, which may be inside an application bundle (if the
|
||||
application is bundled).
|
||||
|
||||
\warning On Linux, this function will try to get the path from the
|
||||
@ -2604,11 +2605,11 @@ void QCoreApplication::removeLibraryPath(const QString &path)
|
||||
The event filter \a filterObj receives events via its \l {QAbstractNativeEventFilter::}{nativeEventFilter()}
|
||||
function, which is called for all native events received in the main thread.
|
||||
|
||||
The QAbstractNativeEventFilter::nativeEventFilter() function should return true if the event should
|
||||
be filtered, (i.e. stopped). It should return false to allow
|
||||
normal Qt processing to continue: the native event can then be translated
|
||||
into a QEvent and handled by the standard Qt \l{QEvent} {event} filtering,
|
||||
e.g. QObject::installEventFilter().
|
||||
The QAbstractNativeEventFilter::nativeEventFilter() function should
|
||||
return true if the event should be filtered, i.e. stopped. It should
|
||||
return false to allow normal Qt processing to continue: the native
|
||||
event can then be translated into a QEvent and handled by the standard
|
||||
Qt \l{QEvent} {event} filtering, e.g. QObject::installEventFilter().
|
||||
|
||||
If multiple event filters are installed, the filter that was
|
||||
installed last is activated first.
|
||||
@ -2616,7 +2617,7 @@ void QCoreApplication::removeLibraryPath(const QString &path)
|
||||
\note The filter function set here receives native messages,
|
||||
i.e. MSG or XCB event structs.
|
||||
|
||||
\note Native event filters will be disabled when the application the
|
||||
\note Native event filters will be disabled in the application when the
|
||||
Qt::AA_PluginApplication attribute is set.
|
||||
|
||||
For maximum portability, you should always try to use QEvent
|
||||
@ -2805,7 +2806,7 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc
|
||||
\snippet code/src_corelib_kernel_qcoreapplication.cpp 7
|
||||
|
||||
The \a context parameter is normally the class name, but it can
|
||||
be any string.
|
||||
be any text.
|
||||
|
||||
\sa Q_OBJECT, QObject::tr(), QObject::trUtf8()
|
||||
*/
|
||||
|
@ -251,9 +251,13 @@
|
||||
|
||||
// NEON intrinsics
|
||||
// note: as of GCC 4.9, does not support function targets for ARM
|
||||
#if defined __ARM_NEON__
|
||||
#if defined(__ARM_NEON) || defined(__ARM_NEON__)
|
||||
#include <arm_neon.h>
|
||||
#define QT_FUNCTION_TARGET_STRING_ARM_NEON "neon"
|
||||
#ifndef __ARM_NEON__
|
||||
// __ARM_NEON__ is not defined on AArch64, but we need it in our NEON detection.
|
||||
#define __ARM_NEON__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef QT_COMPILER_SUPPORTS_SIMD_ALWAYS
|
||||
|
59
src/gui/doc/snippets/qfileopenevent/Info.plist
Normal file
59
src/gui/doc/snippets/qfileopenevent/Info.plist
Normal file
@ -0,0 +1,59 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Samuel Gaist <samuel.gaist@edeltech.ch>
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//! [Custom Info.plist]
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>png</string>
|
||||
</array>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
</dict>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
//! [Custom Info.plist]
|
73
src/gui/doc/snippets/qfileopenevent/main.cpp
Normal file
73
src/gui/doc/snippets/qfileopenevent/main.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 Samuel Gaist <samuel.gaist@edeltech.ch>
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the documentation of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** 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$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//! [QApplication subclass]
|
||||
#include <QApplication>
|
||||
#include <QFileOpenEvent>
|
||||
#include <QtDebug>
|
||||
|
||||
class MyApplication : public QApplication
|
||||
{
|
||||
public:
|
||||
MyApplication(int &argc, char **argv)
|
||||
: QApplication(argc, argv)
|
||||
{
|
||||
}
|
||||
|
||||
bool event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::FileOpen) {
|
||||
QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
|
||||
qDebug() << "Open file" << openEvent->file();
|
||||
}
|
||||
|
||||
return QApplication::event(event);
|
||||
}
|
||||
};
|
||||
//! [QApplication subclass]
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
MyApplication app(argc, argv);
|
||||
QPushButton closeButton("Quit");
|
||||
QObject::connect(&closeButton, &QPushButton::clicked, &app, &QApplication::quit);
|
||||
closeButton.show();
|
||||
return app.exec();
|
||||
}
|
@ -375,7 +375,32 @@ static void convert_RGB888_to_RGB(QImageData *dest, const QImageData *src, Qt::I
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __SSE2__
|
||||
extern bool convert_ARGB_to_ARGB_PM_inplace_sse2(QImageData *data, Qt::ImageConversionFlags);
|
||||
#else
|
||||
static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data,Qt::ImageConversionFlags)
|
||||
{
|
||||
Q_ASSERT(data->format == QImage::Format_ARGB32 || data->format == QImage::Format_RGBA8888);
|
||||
|
||||
const int pad = (data->bytes_per_line >> 2) - data->width;
|
||||
QRgb *rgb_data = (QRgb *) data->data;
|
||||
|
||||
for (int i = 0; i < data->height; ++i) {
|
||||
const QRgb *end = rgb_data + data->width;
|
||||
while (rgb_data < end) {
|
||||
*rgb_data = qPremultiply(*rgb_data);
|
||||
++rgb_data;
|
||||
}
|
||||
rgb_data += pad;
|
||||
}
|
||||
|
||||
if (data->format == QImage::Format_ARGB32)
|
||||
data->format = QImage::Format_ARGB32_Premultiplied;
|
||||
else
|
||||
data->format = QImage::Format_RGBA8888_Premultiplied;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void convert_ARGB_to_RGBx(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
|
||||
{
|
||||
@ -2592,7 +2617,7 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
|
||||
#ifdef __SSE2__
|
||||
convert_ARGB_to_ARGB_PM_inplace_sse2,
|
||||
#else
|
||||
0,
|
||||
convert_ARGB_to_ARGB_PM_inplace,
|
||||
#endif
|
||||
0,
|
||||
0,
|
||||
@ -2705,12 +2730,13 @@ InPlace_Image_Converter qimage_inplace_converter_map[QImage::NImageFormats][QIma
|
||||
0,
|
||||
0,
|
||||
mask_alpha_converter_rgbx_inplace,
|
||||
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN && __SSE2__
|
||||
0,
|
||||
#ifdef __SSE2__
|
||||
convert_ARGB_to_ARGB_PM_inplace_sse2,
|
||||
#elif Q_BYTE_ORDER == Q_LITTLE_ENDIAN
|
||||
convert_ARGB_to_ARGB_PM_inplace,
|
||||
#else
|
||||
0,
|
||||
0,
|
||||
#endif
|
||||
0, 0, 0, 0, 0, 0
|
||||
}, // Format_RGBA8888
|
||||
@ -2921,7 +2947,7 @@ void qInitImageConversions()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
|
||||
#if defined(__ARM_NEON__)
|
||||
extern void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
|
||||
qimage_converter_map[QImage::Format_RGB888][QImage::Format_RGB32] = convert_RGB888_to_RGB32_neon;
|
||||
qimage_converter_map[QImage::Format_RGB888][QImage::Format_ARGB32] = convert_RGB888_to_RGB32_neon;
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <private/qimage_p.h>
|
||||
#include <private/qsimd_p.h>
|
||||
|
||||
#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
|
||||
#if defined(__ARM_NEON__)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -55,6 +55,7 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons
|
||||
|
||||
if ((len - offsetToAlignOn8Bytes) >= 8) {
|
||||
const quint32 *const simdEnd = end - 7;
|
||||
#if !defined(Q_PROCESSOR_ARM_64)
|
||||
register uint8x8_t fullVector asm ("d3") = vdup_n_u8(0xff);
|
||||
do {
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
@ -76,6 +77,31 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons
|
||||
);
|
||||
#endif
|
||||
} while (dst < simdEnd);
|
||||
#else
|
||||
register uint8x8_t fullVector asm ("v3") = vdup_n_u8(0xff);
|
||||
do {
|
||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||
asm volatile (
|
||||
"ld3 { v4.8b, v5.8b, v6.8b }, [%[SRC]], #24 \n\t"
|
||||
"st4 { v3.8b, v4.8b, v5.8b, v6.8b }, [%[DST]], #32 \n\t"
|
||||
: [DST]"+r" (dst), [SRC]"+r" (src)
|
||||
: "w"(fullVector)
|
||||
: "memory", "v4", "v5", "v6"
|
||||
);
|
||||
#else
|
||||
asm volatile (
|
||||
"ld3 { v0.8b, v1.8b, v2.8b }, [%[SRC]], #24 \n\t"
|
||||
"mov v4.8b, v2.8b\n\t"
|
||||
"mov v2.8b, v0.8b\n\t"
|
||||
"mov v0.8b, v4.8b\n\t"
|
||||
"st4 { v0.8b, v1.8b, v2.8b, v3.8b }, [%[DST]], #32 \n\t"
|
||||
: [DST]"+r" (dst), [SRC]"+r" (src)
|
||||
: "w"(fullVector)
|
||||
: "memory", "v0", "v1", "v2", "v4"
|
||||
);
|
||||
#endif
|
||||
} while (dst < simdEnd);
|
||||
#endif
|
||||
}
|
||||
|
||||
while (dst != end) {
|
||||
@ -103,4 +129,4 @@ void convert_RGB888_to_RGB32_neon(QImageData *dest, const QImageData *src, Qt::I
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
|
||||
#endif // defined(__ARM_NEON__)
|
||||
|
@ -978,9 +978,8 @@ extern "C" void qt_convert_rgb888_to_rgb32_mips_dspr2_asm(quint32 *dst, const uc
|
||||
QJpegHandler::QJpegHandler()
|
||||
: d(new QJpegHandlerPrivate(this))
|
||||
{
|
||||
#if defined(__ARM_NEON__) && !defined(Q_PROCESSOR_ARM_64)
|
||||
#if defined(__ARM_NEON__)
|
||||
// from qimage_neon.cpp
|
||||
|
||||
if (qCpuHasFeature(NEON))
|
||||
d->rgb888ToRgb32ConverterPtr = qt_convert_rgb888_to_rgb32_neon;
|
||||
#endif
|
||||
|
@ -43,13 +43,8 @@
|
||||
#include <qvariant.h>
|
||||
#include <qvector.h>
|
||||
|
||||
#ifdef QT_USE_BUNDLED_LIBPNG
|
||||
#include <../../3rdparty/libpng/png.h>
|
||||
#include <../../3rdparty/libpng/pngconf.h>
|
||||
#else
|
||||
#include <png.h>
|
||||
#include <pngconf.h>
|
||||
#endif
|
||||
|
||||
#if PNG_LIBPNG_VER >= 10400 && PNG_LIBPNG_VER <= 10502 \
|
||||
&& defined(PNG_PEDANTIC_WARNINGS_SUPPORTED)
|
||||
|
@ -3418,6 +3418,21 @@ QShowEvent::~QShowEvent()
|
||||
It may be safely ignored.
|
||||
|
||||
\note This class is currently supported for OS X only.
|
||||
|
||||
\section1 OS X Example
|
||||
|
||||
In order to trigger the event on OS X, the application must be configured
|
||||
to let the OS know what kind of file(s) it should react on.
|
||||
|
||||
For example, the following \c Info.plist file declares that the application
|
||||
can act as a viewer for files with a PNG extension:
|
||||
|
||||
\snippet qfileopenevent/Info.plist Custom Info.plist
|
||||
|
||||
The following implementation of a QApplication subclass prints the path to
|
||||
the file that was, for example, dropped on the Dock icon of the application.
|
||||
|
||||
\snippet qfileopenevent/main.cpp QApplication subclass
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -101,7 +101,7 @@ SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \
|
||||
painting/qimagescale_sse4.cpp
|
||||
AVX2_SOURCES += painting/qdrawhelper_avx2.cpp
|
||||
|
||||
!ios {
|
||||
!ios:!contains(QT_ARCH, "arm64") {
|
||||
CONFIG += no_clang_integrated_as
|
||||
NEON_SOURCES += painting/qdrawhelper_neon.cpp
|
||||
NEON_HEADERS += painting/qdrawhelper_neon_p.h
|
||||
|
@ -6309,7 +6309,7 @@ void qt_memfill16(quint16 *dest, quint16 color, int count)
|
||||
qt_memfill_template<quint16>(dest, color, count);
|
||||
}
|
||||
#endif
|
||||
#if !defined(__SSE2__) && !defined(__ARM_NEON__)
|
||||
#if !defined(__SSE2__) && (!defined(__ARM_NEON__) || defined(Q_PROCESSOR_ARM_64))
|
||||
# ifdef QT_COMPILER_SUPPORTS_MIPS_DSP
|
||||
extern "C" void qt_memfill32_asm_mips_dsp(quint32 *, quint32, int);
|
||||
# endif
|
||||
@ -6425,7 +6425,7 @@ void qInitDrawhelperAsm()
|
||||
|
||||
#endif // SSE2
|
||||
|
||||
#if defined(__ARM_NEON__) && !defined(Q_OS_IOS)
|
||||
#if defined(__ARM_NEON__) && !defined(Q_OS_IOS) && !defined(Q_PROCESSOR_ARM_64)
|
||||
qBlendFunctions[QImage::Format_RGB32][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
|
||||
qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_neon;
|
||||
qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_neon;
|
||||
|
@ -31,15 +31,13 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <private/qdrawhelper_p.h>
|
||||
#include <private/qdrawhelper_neon_p.h>
|
||||
#include <private/qblendfunctions_p.h>
|
||||
#include <private/qmath_p.h>
|
||||
|
||||
#ifdef __ARM_NEON__
|
||||
|
||||
#include <private/qdrawhelper_neon_p.h>
|
||||
#include <private/qpaintengine_raster_p.h>
|
||||
#include <arm_neon.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -58,10 +58,10 @@ inline Q_DECL_CONSTEXPR int qAlpha(QRgb rgb) // get alpha part of
|
||||
{ return rgb >> 24; }
|
||||
|
||||
inline Q_DECL_CONSTEXPR QRgb qRgb(int r, int g, int b)// set RGB value
|
||||
{ return (0xffu << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); }
|
||||
{ return (0xffu << 24) | ((r & 0xffu) << 16) | ((g & 0xffu) << 8) | (b & 0xffu); }
|
||||
|
||||
inline Q_DECL_CONSTEXPR QRgb qRgba(int r, int g, int b, int a)// set RGBA value
|
||||
{ return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); }
|
||||
{ return ((a & 0xffu) << 24) | ((r & 0xffu) << 16) | ((g & 0xffu) << 8) | (b & 0xffu); }
|
||||
|
||||
inline Q_DECL_CONSTEXPR int qGray(int r, int g, int b)// convert R,G,B to gray 0..255
|
||||
{ return (r*11+g*16+b*5)/32; }
|
||||
|
@ -918,10 +918,11 @@ void QTextEngine::shapeLine(const QScriptLine &line)
|
||||
{
|
||||
QFixed x;
|
||||
bool first = true;
|
||||
const int end = findItem(line.from + line.length - 1);
|
||||
int item = findItem(line.from);
|
||||
if (item == -1)
|
||||
return;
|
||||
|
||||
const int end = findItem(line.from + line.length - 1, item);
|
||||
for ( ; item <= end; ++item) {
|
||||
QScriptItem &si = layoutData->items[item];
|
||||
if (si.analysis.flags == QScriptAnalysis::Tab) {
|
||||
@ -1747,13 +1748,13 @@ bool QTextEngine::isRightToLeft() const
|
||||
}
|
||||
|
||||
|
||||
int QTextEngine::findItem(int strPos) const
|
||||
int QTextEngine::findItem(int strPos, int firstItem) const
|
||||
{
|
||||
itemize();
|
||||
if (strPos < 0 || strPos >= layoutData->string.size())
|
||||
if (strPos < 0 || strPos >= layoutData->string.size() || firstItem < 0)
|
||||
return -1;
|
||||
|
||||
int left = 1;
|
||||
int left = firstItem + 1;
|
||||
int right = layoutData->items.size()-1;
|
||||
while(left <= right) {
|
||||
int middle = ((right-left)/2)+left;
|
||||
@ -2172,7 +2173,7 @@ void QTextEngine::justify(const QScriptLine &line)
|
||||
return;
|
||||
|
||||
int firstItem = findItem(line.from);
|
||||
int lastItem = findItem(line.from + line_length - 1);
|
||||
int lastItem = findItem(line.from + line_length - 1, firstItem);
|
||||
int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;
|
||||
|
||||
QVarLengthArray<QJustificationPoint> justificationPoints;
|
||||
@ -3529,7 +3530,7 @@ QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int _lineNum, co
|
||||
lineNum(_lineNum),
|
||||
lineEnd(line.from + line.length),
|
||||
firstItem(eng->findItem(line.from)),
|
||||
lastItem(eng->findItem(lineEnd - 1)),
|
||||
lastItem(eng->findItem(lineEnd - 1, firstItem)),
|
||||
nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0),
|
||||
logicalItem(-1),
|
||||
item(-1),
|
||||
|
@ -512,7 +512,7 @@ public:
|
||||
|
||||
void freeMemory();
|
||||
|
||||
int findItem(int strPos) const;
|
||||
int findItem(int strPos, int firstItem = 0) const;
|
||||
inline QTextFormatCollection *formatCollection() const {
|
||||
if (block.docHandle())
|
||||
return block.docHandle()->formatCollection();
|
||||
|
@ -2624,26 +2624,24 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
|
||||
*/
|
||||
qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
|
||||
{
|
||||
if (!eng->layoutData)
|
||||
eng->itemize();
|
||||
|
||||
const QScriptLine &line = eng->lines[index];
|
||||
bool lastLine = index >= eng->lines.size() - 1;
|
||||
|
||||
QFixed x = line.x;
|
||||
x += eng->alignLine(line) - eng->leadingSpaceWidth(line);
|
||||
QFixed x = line.x + eng->alignLine(line) - eng->leadingSpaceWidth(line);
|
||||
|
||||
if (!index && !eng->layoutData->items.size()) {
|
||||
*cursorPos = 0;
|
||||
if (!eng->layoutData)
|
||||
eng->itemize();
|
||||
if (!eng->layoutData->items.size()) {
|
||||
*cursorPos = line.from;
|
||||
return x.toReal();
|
||||
}
|
||||
|
||||
int lineEnd = line.from + line.length + line.trailingSpaces;
|
||||
int pos = qBound(0, *cursorPos, lineEnd);
|
||||
int pos = qBound(line.from, *cursorPos, lineEnd);
|
||||
int itm;
|
||||
const QCharAttributes *attributes = eng->attributes();
|
||||
if (!attributes) {
|
||||
*cursorPos = 0;
|
||||
*cursorPos = line.from;
|
||||
return x.toReal();
|
||||
}
|
||||
while (pos < lineEnd && !attributes[pos].graphemeBoundary)
|
||||
@ -2655,7 +2653,7 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
|
||||
else
|
||||
itm = eng->findItem(pos);
|
||||
if (itm < 0) {
|
||||
*cursorPos = 0;
|
||||
*cursorPos = line.from;
|
||||
return x.toReal();
|
||||
}
|
||||
eng->shapeLine(line);
|
||||
@ -2663,18 +2661,14 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
|
||||
const QScriptItem *si = &eng->layoutData->items[itm];
|
||||
if (!si->num_glyphs)
|
||||
eng->shape(itm);
|
||||
pos -= si->position;
|
||||
|
||||
const int l = eng->length(itm);
|
||||
pos = qBound(0, pos - si->position, l);
|
||||
|
||||
QGlyphLayout glyphs = eng->shapedGlyphs(si);
|
||||
unsigned short *logClusters = eng->logClusters(si);
|
||||
Q_ASSERT(logClusters);
|
||||
|
||||
int l = eng->length(itm);
|
||||
if (pos > l)
|
||||
pos = l;
|
||||
if (pos < 0)
|
||||
pos = 0;
|
||||
|
||||
int glyph_pos = pos == l ? si->num_glyphs : logClusters[pos];
|
||||
if (edge == Trailing && glyph_pos < si->num_glyphs) {
|
||||
// trailing edge is leading edge of next cluster
|
||||
@ -2683,13 +2677,13 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
|
||||
glyph_pos++;
|
||||
}
|
||||
|
||||
bool reverse = eng->layoutData->items[itm].analysis.bidiLevel % 2;
|
||||
bool reverse = si->analysis.bidiLevel % 2;
|
||||
|
||||
|
||||
// add the items left of the cursor
|
||||
|
||||
int firstItem = eng->findItem(line.from);
|
||||
int lastItem = eng->findItem(lineEnd - 1);
|
||||
int lastItem = eng->findItem(lineEnd - 1, itm);
|
||||
int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;
|
||||
|
||||
QVarLengthArray<int> visualOrder(nItems);
|
||||
@ -2710,13 +2704,15 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
|
||||
x += si.width;
|
||||
continue;
|
||||
}
|
||||
|
||||
const int itemLength = eng->length(item);
|
||||
int start = qMax(line.from, si.position);
|
||||
int end = qMin(lineEnd, si.position + eng->length(item));
|
||||
int end = qMin(lineEnd, si.position + itemLength);
|
||||
|
||||
logClusters = eng->logClusters(&si);
|
||||
|
||||
int gs = logClusters[start-si.position];
|
||||
int ge = (end == si.position + eng->length(item)) ? si.num_glyphs-1 : logClusters[end-si.position-1];
|
||||
int ge = (end == si.position + itemLength) ? si.num_glyphs-1 : logClusters[end-si.position-1];
|
||||
|
||||
QGlyphLayout glyphs = eng->shapedGlyphs(&si);
|
||||
|
||||
@ -2788,7 +2784,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
|
||||
return line.from;
|
||||
|
||||
int firstItem = eng->findItem(line.from);
|
||||
int lastItem = eng->findItem(line.from + line_length - 1);
|
||||
int lastItem = eng->findItem(line.from + line_length - 1, firstItem);
|
||||
int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;
|
||||
|
||||
if (!nItems)
|
||||
|
@ -717,15 +717,19 @@ QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont
|
||||
FcPatternDestroy(pattern);
|
||||
|
||||
if (fontSet) {
|
||||
QSet<QString> duplicates;
|
||||
duplicates.reserve(fontSet->nfont + 1);
|
||||
duplicates.insert(family.toCaseFolded());
|
||||
for (int i = 0; i < fontSet->nfont; i++) {
|
||||
FcChar8 *value = 0;
|
||||
if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
|
||||
continue;
|
||||
// capitalize(value);
|
||||
QString familyName = QString::fromUtf8((const char *)value);
|
||||
if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive) &&
|
||||
familyName.compare(family, Qt::CaseInsensitive)) {
|
||||
const QString familyName = QString::fromUtf8((const char *)value);
|
||||
const QString familyNameCF = familyName.toCaseFolded();
|
||||
if (!duplicates.contains(familyNameCF)) {
|
||||
fallbackFamilies << familyName;
|
||||
duplicates.insert(familyNameCF);
|
||||
}
|
||||
}
|
||||
FcFontSetDestroy(fontSet);
|
||||
|
@ -99,6 +99,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
|
||||
- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification;
|
||||
- (void)viewDidHide;
|
||||
- (void)viewDidUnhide;
|
||||
- (void)removeFromSuperview;
|
||||
|
||||
- (BOOL)isFlipped;
|
||||
- (BOOL)acceptsFirstResponder;
|
||||
|
@ -498,6 +498,12 @@ QT_WARNING_POP
|
||||
m_platformWindow->exposeWindow();
|
||||
}
|
||||
|
||||
- (void)removeFromSuperview
|
||||
{
|
||||
QMacAutoReleasePool pool;
|
||||
[super removeFromSuperview];
|
||||
}
|
||||
|
||||
- (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset
|
||||
{
|
||||
m_backingStore = backingStore;
|
||||
|
@ -12,6 +12,9 @@ CONFIG += egl
|
||||
LIBS += -lbcm_host
|
||||
QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
|
||||
|
||||
# Avoid X11 header collision
|
||||
DEFINES += MESA_EGL_NO_X11_HEADERS
|
||||
|
||||
SOURCES += $$PWD/qeglfsbrcmmain.cpp \
|
||||
$$PWD/qeglfsbrcmintegration.cpp
|
||||
|
||||
|
@ -89,10 +89,11 @@ QIOSIntegration::QIOSIntegration()
|
||||
// Set current directory to app bundle folder
|
||||
QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String]));
|
||||
|
||||
UIScreen *mainScreen = [UIScreen mainScreen];
|
||||
NSMutableArray *screens = [[[UIScreen screens] mutableCopy] autorelease];
|
||||
if (![screens containsObject:[UIScreen mainScreen]]) {
|
||||
if (![screens containsObject:mainScreen]) {
|
||||
// Fallback for iOS 7.1 (QTBUG-42345)
|
||||
[screens insertObject:[UIScreen mainScreen] atIndex:0];
|
||||
[screens insertObject:mainScreen atIndex:0];
|
||||
}
|
||||
|
||||
for (UIScreen *screen in screens)
|
||||
@ -103,7 +104,10 @@ QIOSIntegration::QIOSIntegration()
|
||||
|
||||
m_touchDevice = new QTouchDevice;
|
||||
m_touchDevice->setType(QTouchDevice::TouchScreen);
|
||||
m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition);
|
||||
QTouchDevice::Capabilities touchCapabilities = QTouchDevice::Position | QTouchDevice::NormalizedPosition;
|
||||
if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
|
||||
touchCapabilities |= QTouchDevice::Pressure;
|
||||
m_touchDevice->setCapabilities(touchCapabilities);
|
||||
QWindowSystemInterface::registerTouchDevice(m_touchDevice);
|
||||
QMacInternalPasteboardMime::initializeMimeTypes();
|
||||
}
|
||||
|
@ -280,6 +280,19 @@
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection
|
||||
{
|
||||
[super traitCollectionDidChange: previousTraitCollection];
|
||||
|
||||
QTouchDevice *touchDevice = QIOSIntegration::instance()->touchDevice();
|
||||
QTouchDevice::Capabilities touchCapabilities = touchDevice->capabilities();
|
||||
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
|
||||
touchCapabilities |= QTouchDevice::Pressure;
|
||||
else
|
||||
touchCapabilities &= ~QTouchDevice::Pressure;
|
||||
touchDevice->setCapabilities(touchCapabilities);
|
||||
}
|
||||
|
||||
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
|
||||
{
|
||||
if (m_qioswindow->window()->flags() & Qt::WindowTransparentForInput)
|
||||
@ -289,6 +302,8 @@
|
||||
|
||||
- (void)updateTouchList:(NSSet *)touches withState:(Qt::TouchPointState)state
|
||||
{
|
||||
bool supportsPressure = QIOSIntegration::instance()->touchDevice()->capabilities() & QTouchDevice::Pressure;
|
||||
|
||||
foreach (UITouch *uiTouch, m_activeTouches.keys()) {
|
||||
QWindowSystemInterface::TouchPoint &touchPoint = m_activeTouches[uiTouch];
|
||||
if (![touches containsObject:uiTouch]) {
|
||||
@ -309,12 +324,20 @@
|
||||
touchPoint.normalPosition = QPointF(globalScreenPosition.x() / screenSize.width(),
|
||||
globalScreenPosition.y() / screenSize.height());
|
||||
|
||||
if (supportsPressure) {
|
||||
// Note: iOS will deliver touchesBegan with a touch force of 0, which
|
||||
// we will reflect/propagate as a 0 pressure, but there is no clear
|
||||
// alternative, as we don't want to wait for a touchedMoved before
|
||||
// sending a touch press event to Qt, just to have a valid pressure.
|
||||
touchPoint.pressure = uiTouch.force / uiTouch.maximumPossibleForce;
|
||||
} else {
|
||||
// We don't claim that our touch device supports QTouchDevice::Pressure,
|
||||
// but fill in a meaningfull value in case clients use it anyways.
|
||||
touchPoint.pressure = (state == Qt::TouchPointReleased) ? 0.0 : 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)sendTouchEventWithTimestamp:(ulong)timeStamp
|
||||
{
|
||||
|
@ -49,11 +49,6 @@ QPlatformIntegration* QMirClientIntegrationPlugin::create(const QString &system,
|
||||
const QStringList &)
|
||||
{
|
||||
if (system.toLower() == "mirclient") {
|
||||
#ifdef PLATFORM_API_TOUCH
|
||||
setenv("UBUNTU_PLATFORM_API_BACKEND", "touch_mirclient", 1);
|
||||
#else
|
||||
setenv("UBUNTU_PLATFORM_API_BACKEND", "desktop_mirclient", 1);
|
||||
#endif
|
||||
return new QMirClientClientIntegration;
|
||||
} else {
|
||||
return 0;
|
||||
|
@ -43,15 +43,17 @@
|
||||
#include <QtGui/QGuiApplication>
|
||||
#include <QtGui/QScreen>
|
||||
#include <QtGui/private/qguiapplication_p.h> // getPixmapCursor()
|
||||
#include <QtGui/private/qhighdpiscaling_p.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QScopedArrayPointer>
|
||||
|
||||
static void initResources()
|
||||
static bool initResources()
|
||||
{
|
||||
#if !defined (Q_OS_WINCE) && !defined (QT_NO_IMAGEFORMAT_PNG)
|
||||
Q_INIT_RESOURCE(cursors);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -92,9 +94,14 @@ QWindowsPixmapCursorCacheKey::QWindowsPixmapCursorCacheKey(const QCursor &c)
|
||||
\sa QWindowsWindowCursor
|
||||
*/
|
||||
|
||||
HCURSOR QWindowsCursor::createPixmapCursor(const QPixmap &pixmap, const QPoint &hotSpot)
|
||||
HCURSOR QWindowsCursor::createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor)
|
||||
{
|
||||
HCURSOR cur = 0;
|
||||
scaleFactor /= pixmap.devicePixelRatioF();
|
||||
if (!qFuzzyCompare(scaleFactor, 1)) {
|
||||
pixmap = pixmap.scaled((scaleFactor * QSizeF(pixmap.size())).toSize(),
|
||||
Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
QBitmap mask = pixmap.mask();
|
||||
if (mask.isNull()) {
|
||||
mask = QBitmap(pixmap.size());
|
||||
@ -202,17 +209,43 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits,
|
||||
}
|
||||
|
||||
// Create a cursor from image and mask of the format QImage::Format_Mono.
|
||||
static HCURSOR createBitmapCursor(const QCursor &cursor)
|
||||
static HCURSOR createBitmapCursor(const QCursor &cursor, qreal scaleFactor = 1)
|
||||
{
|
||||
Q_ASSERT(cursor.shape() == Qt::BitmapCursor && cursor.bitmap());
|
||||
const QImage bbits = cursor.bitmap()->toImage().convertToFormat(QImage::Format_Mono);
|
||||
const QImage mbits = cursor.mask()->toImage().convertToFormat(QImage::Format_Mono);
|
||||
QImage bbits = cursor.bitmap()->toImage();
|
||||
QImage mbits = cursor.mask()->toImage();
|
||||
scaleFactor /= bbits.devicePixelRatioF();
|
||||
if (!qFuzzyCompare(scaleFactor, 1)) {
|
||||
const QSize scaledSize = (QSizeF(bbits.size()) * scaleFactor).toSize();
|
||||
bbits = bbits.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
mbits = mbits.scaled(scaledSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
}
|
||||
bbits = bbits.convertToFormat(QImage::Format_Mono);
|
||||
mbits = mbits.convertToFormat(QImage::Format_Mono);
|
||||
const bool invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
|
||||
const bool invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
|
||||
return createBitmapCursor(bbits, mbits, cursor.hotSpot(), invb, invm);
|
||||
}
|
||||
|
||||
static inline QSize systemCursorSize() { return QSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)); }
|
||||
static QSize systemCursorSize(const QPlatformScreen *screen = Q_NULLPTR)
|
||||
{
|
||||
const QSize primaryScreenCursorSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR));
|
||||
if (screen) {
|
||||
// Correct the size if the DPI value of the screen differs from
|
||||
// that of the primary screen.
|
||||
if (const QScreen *primaryQScreen = QGuiApplication::primaryScreen()) {
|
||||
const QPlatformScreen *primaryScreen = primaryQScreen->handle();
|
||||
if (screen != primaryScreen) {
|
||||
const qreal logicalDpi = screen->logicalDpi().first;
|
||||
const qreal primaryScreenLogicalDpi = primaryScreen->logicalDpi().first;
|
||||
if (!qFuzzyCompare(logicalDpi, primaryScreenLogicalDpi))
|
||||
return (QSizeF(primaryScreenCursorSize) * logicalDpi / primaryScreenLogicalDpi).toSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
return primaryScreenCursorSize;
|
||||
}
|
||||
|
||||
static inline QSize standardCursorSize() { return QSize(32, 32); }
|
||||
|
||||
#if defined (Q_OS_WINCE) || defined (QT_NO_IMAGEFORMAT_PNG)
|
||||
@ -242,7 +275,8 @@ static QWindowsCursor::PixmapCursor createPixmapCursorFromData(const QSize &syst
|
||||
return QWindowsCursor::PixmapCursor(rawImage, hotSpot);
|
||||
}
|
||||
|
||||
QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
|
||||
QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape,
|
||||
const QPlatformScreen *screen)
|
||||
{
|
||||
// Non-standard Windows cursors are created from bitmaps
|
||||
static const uchar vsplit_bits[] = {
|
||||
@ -410,13 +444,13 @@ QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursor
|
||||
|
||||
switch (cursorShape) {
|
||||
case Qt::SplitVCursor:
|
||||
return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 32, vsplit_bits, vsplitm_bits);
|
||||
return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 32, vsplit_bits, vsplitm_bits);
|
||||
case Qt::SplitHCursor:
|
||||
return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 32, hsplit_bits, hsplitm_bits);
|
||||
return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 32, hsplit_bits, hsplitm_bits);
|
||||
case Qt::OpenHandCursor:
|
||||
return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 16, openhand_bits, openhandm_bits);
|
||||
return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 16, openhand_bits, openhandm_bits);
|
||||
case Qt::ClosedHandCursor:
|
||||
return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 16, closedhand_bits, closedhandm_bits);
|
||||
return createPixmapCursorFromData(systemCursorSize(screen), standardCursorSize(), 16, closedhand_bits, closedhandm_bits);
|
||||
case Qt::DragCopyCursor:
|
||||
return QWindowsCursor::PixmapCursor(QPixmap(copyDragCursorXpmC), QPoint(0, 0));
|
||||
case Qt::DragMoveCursor:
|
||||
@ -436,7 +470,7 @@ struct QWindowsCustomPngCursor {
|
||||
int hotSpotY;
|
||||
};
|
||||
|
||||
QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
|
||||
QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen)
|
||||
{
|
||||
static const QWindowsCustomPngCursor pngCursors[] = {
|
||||
{ Qt::SplitVCursor, 32, "splitvcursor_32.png", 11, 11 },
|
||||
@ -462,14 +496,14 @@ QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursor
|
||||
{ Qt::DragLinkCursor, 64, "draglinkcursor_64.png", 0, 0 }
|
||||
};
|
||||
|
||||
const int cursorSize = GetSystemMetrics(SM_CXCURSOR);
|
||||
const QSize cursorSize = systemCursorSize(screen);
|
||||
const QWindowsCustomPngCursor *sEnd = pngCursors + sizeof(pngCursors) / sizeof(pngCursors[0]);
|
||||
const QWindowsCustomPngCursor *bestFit = 0;
|
||||
int sizeDelta = INT_MAX;
|
||||
for (const QWindowsCustomPngCursor *s = pngCursors; s < sEnd; ++s) {
|
||||
if (s->shape != cursorShape)
|
||||
continue;
|
||||
const int currentSizeDelta = qMax(s->size, cursorSize) - qMin(s->size, cursorSize);
|
||||
const int currentSizeDelta = qMax(s->size, cursorSize.width()) - qMin(s->size, cursorSize.width());
|
||||
if (currentSizeDelta < sizeDelta) {
|
||||
bestFit = s;
|
||||
if (currentSizeDelta == 0)
|
||||
@ -492,7 +526,7 @@ struct QWindowsStandardCursorMapping {
|
||||
LPCWSTR resource;
|
||||
};
|
||||
|
||||
HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape)
|
||||
HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen)
|
||||
{
|
||||
Q_ASSERT(cursorShape != Qt::BitmapCursor);
|
||||
|
||||
@ -515,7 +549,7 @@ HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape)
|
||||
|
||||
switch (cursorShape) {
|
||||
case Qt::BlankCursor: {
|
||||
QImage blank = QImage(systemCursorSize(), QImage::Format_Mono);
|
||||
QImage blank = QImage(systemCursorSize(screen), QImage::Format_Mono);
|
||||
blank.fill(0); // ignore color table
|
||||
return createBitmapCursor(blank, blank);
|
||||
}
|
||||
@ -526,7 +560,7 @@ HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape)
|
||||
case Qt::DragCopyCursor:
|
||||
case Qt::DragMoveCursor:
|
||||
case Qt::DragLinkCursor:
|
||||
return QWindowsCursor::createPixmapCursor(customCursor(cursorShape));
|
||||
return QWindowsCursor::createPixmapCursor(customCursor(cursorShape, screen));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -555,7 +589,7 @@ CursorHandlePtr QWindowsCursor::standardWindowCursor(Qt::CursorShape shape)
|
||||
{
|
||||
StandardCursorCache::Iterator it = m_standardCursorCache.find(shape);
|
||||
if (it == m_standardCursorCache.end()) {
|
||||
if (const HCURSOR hc = QWindowsCursor::createCursorFromShape(shape))
|
||||
if (const HCURSOR hc = QWindowsCursor::createCursorFromShape(shape, m_screen))
|
||||
it = m_standardCursorCache.insert(shape, CursorHandlePtr(new CursorHandle(hc)));
|
||||
}
|
||||
return it != m_standardCursorCache.end() ? it.value() : CursorHandlePtr(new CursorHandle);
|
||||
@ -582,17 +616,21 @@ CursorHandlePtr QWindowsCursor::pixmapWindowCursor(const QCursor &c)
|
||||
++it;
|
||||
}
|
||||
}
|
||||
const qreal scaleFactor = QHighDpiScaling::factor(m_screen);
|
||||
const QPixmap pixmap = c.pixmap();
|
||||
const HCURSOR hc = pixmap.isNull()
|
||||
? createBitmapCursor(c) : QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot());
|
||||
? createBitmapCursor(c, scaleFactor)
|
||||
: QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot(), scaleFactor);
|
||||
it = m_pixmapCursorCache.insert(cacheKey, CursorHandlePtr(new CursorHandle(hc)));
|
||||
}
|
||||
return it.value();
|
||||
}
|
||||
|
||||
QWindowsCursor::QWindowsCursor()
|
||||
QWindowsCursor::QWindowsCursor(const QPlatformScreen *screen)
|
||||
: m_screen(screen)
|
||||
{
|
||||
initResources();
|
||||
static const bool dummy = initResources();
|
||||
Q_UNUSED(dummy)
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -654,6 +692,94 @@ void QWindowsCursor::setPos(const QPoint &pos)
|
||||
SetCursorPos(pos.x() , pos.y());
|
||||
}
|
||||
|
||||
QPixmap QWindowsCursor::dragDefaultCursor(Qt::DropAction action) const
|
||||
{
|
||||
switch (action) {
|
||||
case Qt::CopyAction:
|
||||
if (m_copyDragCursor.isNull())
|
||||
m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor, m_screen).pixmap;
|
||||
return m_copyDragCursor;
|
||||
case Qt::TargetMoveAction:
|
||||
case Qt::MoveAction:
|
||||
if (m_moveDragCursor.isNull())
|
||||
m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor, m_screen).pixmap;
|
||||
return m_moveDragCursor;
|
||||
case Qt::LinkAction:
|
||||
if (m_linkDragCursor.isNull())
|
||||
m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor, m_screen).pixmap;
|
||||
return m_linkDragCursor;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
static const char * const ignoreDragCursorXpmC[] = {
|
||||
"24 30 3 1",
|
||||
". c None",
|
||||
"a c #000000",
|
||||
"X c #FFFFFF",
|
||||
"aa......................",
|
||||
"aXa.....................",
|
||||
"aXXa....................",
|
||||
"aXXXa...................",
|
||||
"aXXXXa..................",
|
||||
"aXXXXXa.................",
|
||||
"aXXXXXXa................",
|
||||
"aXXXXXXXa...............",
|
||||
"aXXXXXXXXa..............",
|
||||
"aXXXXXXXXXa.............",
|
||||
"aXXXXXXaaaa.............",
|
||||
"aXXXaXXa................",
|
||||
"aXXaaXXa................",
|
||||
"aXa..aXXa...............",
|
||||
"aa...aXXa...............",
|
||||
"a.....aXXa..............",
|
||||
"......aXXa.....XXXX.....",
|
||||
".......aXXa..XXaaaaXX...",
|
||||
".......aXXa.XaaaaaaaaX..",
|
||||
"........aa.XaaaXXXXaaaX.",
|
||||
"...........XaaaaX..XaaX.",
|
||||
"..........XaaXaaaX..XaaX",
|
||||
"..........XaaXXaaaX.XaaX",
|
||||
"..........XaaX.XaaaXXaaX",
|
||||
"..........XaaX..XaaaXaaX",
|
||||
"...........XaaX..XaaaaX.",
|
||||
"...........XaaaXXXXaaaX.",
|
||||
"............XaaaaaaaaX..",
|
||||
".............XXaaaaXX...",
|
||||
"...............XXXX....."};
|
||||
|
||||
if (m_ignoreDragCursor.isNull()) {
|
||||
#if !defined (Q_OS_WINCE)
|
||||
HCURSOR cursor = LoadCursor(NULL, IDC_NO);
|
||||
ICONINFO iconInfo = {0, 0, 0, 0, 0};
|
||||
GetIconInfo(cursor, &iconInfo);
|
||||
BITMAP bmColor = {0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
if (iconInfo.hbmColor
|
||||
&& GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor)
|
||||
&& bmColor.bmWidth == bmColor.bmWidthBytes / 4) {
|
||||
const int colorBitsLength = bmColor.bmHeight * bmColor.bmWidthBytes;
|
||||
uchar *colorBits = new uchar[colorBitsLength];
|
||||
GetBitmapBits(iconInfo.hbmColor, colorBitsLength, colorBits);
|
||||
const QImage colorImage(colorBits, bmColor.bmWidth, bmColor.bmHeight,
|
||||
bmColor.bmWidthBytes, QImage::Format_ARGB32);
|
||||
|
||||
m_ignoreDragCursor = QPixmap::fromImage(colorImage);
|
||||
delete [] colorBits;
|
||||
} else {
|
||||
m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
|
||||
}
|
||||
|
||||
DeleteObject(iconInfo.hbmMask);
|
||||
DeleteObject(iconInfo.hbmColor);
|
||||
DestroyCursor(cursor);
|
||||
#else // !Q_OS_WINCE
|
||||
m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
|
||||
#endif // !Q_OS_WINCE
|
||||
}
|
||||
return m_ignoreDragCursor;
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QWindowsWindowCursor
|
||||
\brief Per-Window cursor. Contains a QCursor and manages its associated system
|
||||
|
@ -96,29 +96,37 @@ public:
|
||||
QPoint hotSpot;
|
||||
};
|
||||
|
||||
QWindowsCursor();
|
||||
explicit QWindowsCursor(const QPlatformScreen *screen);
|
||||
|
||||
void changeCursor(QCursor * widgetCursor, QWindow * widget) Q_DECL_OVERRIDE;
|
||||
QPoint pos() const Q_DECL_OVERRIDE;
|
||||
void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
|
||||
|
||||
static HCURSOR createPixmapCursor(const QPixmap &pixmap, const QPoint &hotSpot);
|
||||
static HCURSOR createPixmapCursor(const PixmapCursor &pc) { return createPixmapCursor(pc.pixmap, pc.hotSpot); }
|
||||
static PixmapCursor customCursor(Qt::CursorShape cursorShape);
|
||||
static HCURSOR createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor = 1);
|
||||
static HCURSOR createPixmapCursor(const PixmapCursor &pc, qreal scaleFactor = 1) { return createPixmapCursor(pc.pixmap, pc.hotSpot, scaleFactor); }
|
||||
static PixmapCursor customCursor(Qt::CursorShape cursorShape, const QPlatformScreen *screen = Q_NULLPTR);
|
||||
|
||||
static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape);
|
||||
static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape, const QPlatformScreen *screen = Q_NULLPTR);
|
||||
static QPoint mousePosition();
|
||||
static CursorState cursorState();
|
||||
|
||||
CursorHandlePtr standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
|
||||
CursorHandlePtr pixmapWindowCursor(const QCursor &c);
|
||||
|
||||
QPixmap dragDefaultCursor(Qt::DropAction action) const;
|
||||
|
||||
private:
|
||||
typedef QHash<Qt::CursorShape, CursorHandlePtr> StandardCursorCache;
|
||||
typedef QHash<QWindowsPixmapCursorCacheKey, CursorHandlePtr> PixmapCursorCache;
|
||||
|
||||
const QPlatformScreen *const m_screen;
|
||||
StandardCursorCache m_standardCursorCache;
|
||||
PixmapCursorCache m_pixmapCursorCache;
|
||||
|
||||
mutable QPixmap m_copyDragCursor;
|
||||
mutable QPixmap m_moveDragCursor;
|
||||
mutable QPixmap m_linkDragCursor;
|
||||
mutable QPixmap m_ignoreDragCursor;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -269,13 +269,6 @@ QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e)
|
||||
}
|
||||
#endif // !QT_NO_DEBUG_STREAM
|
||||
|
||||
static qreal dragScaleFactor()
|
||||
{
|
||||
const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager();
|
||||
const QWindowsScreen *screen = screenManager.screenAtDp(QWindowsCursor::mousePosition());
|
||||
return screen ? QHighDpiScaling::factor(screen) : qreal(1);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Blend custom pixmap with cursors.
|
||||
*/
|
||||
@ -286,7 +279,17 @@ void QWindowsOleDropSource::createCursors()
|
||||
const QPixmap pixmap = drag->pixmap();
|
||||
const bool hasPixmap = !pixmap.isNull();
|
||||
|
||||
const qreal scaleFactor = dragScaleFactor();
|
||||
// Find screen for drag. Could be obtained from QDrag::source(), but that might be a QWidget.
|
||||
|
||||
qreal scaleFactor = 1;
|
||||
QPlatformCursor *platformCursor = Q_NULLPTR;
|
||||
if (const QPlatformScreen *platformScreen = QWindowsContext::instance()->screenManager().screenAtDp(QWindowsCursor::mousePosition())) {
|
||||
scaleFactor = QHighDpiScaling::factor(platformScreen);
|
||||
platformCursor = platformScreen->cursor();
|
||||
}
|
||||
if (!platformCursor && QGuiApplication::primaryScreen())
|
||||
platformCursor = QGuiApplication::primaryScreen()->handle()->cursor();
|
||||
|
||||
const bool scalePixmap = hasPixmap
|
||||
&& m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.
|
||||
&& (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio()));
|
||||
@ -304,8 +307,8 @@ void QWindowsOleDropSource::createCursors()
|
||||
for (int cnum = 0; cnum < actionCount; ++cnum) {
|
||||
const Qt::DropAction action = actions[cnum];
|
||||
QPixmap cursorPixmap = drag->dragCursor(action);
|
||||
if (cursorPixmap.isNull())
|
||||
cursorPixmap = m_drag->defaultCursor(action);
|
||||
if (cursorPixmap.isNull() && platformCursor)
|
||||
cursorPixmap = static_cast<QWindowsCursor *>(platformCursor)->dragDefaultCursor(action);
|
||||
const qint64 cacheKey = cursorPixmap.cacheKey();
|
||||
const auto it = m_cursors.find(action);
|
||||
if (it != m_cursors.end() && it.value().cacheKey == cacheKey)
|
||||
@ -704,94 +707,6 @@ IDropTargetHelper* QWindowsDrag::dropHelper() {
|
||||
return m_cachedDropTargetHelper;
|
||||
}
|
||||
|
||||
QPixmap QWindowsDrag::defaultCursor(Qt::DropAction action) const
|
||||
{
|
||||
switch (action) {
|
||||
case Qt::CopyAction:
|
||||
if (m_copyDragCursor.isNull())
|
||||
m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor).pixmap;
|
||||
return m_copyDragCursor;
|
||||
case Qt::TargetMoveAction:
|
||||
case Qt::MoveAction:
|
||||
if (m_moveDragCursor.isNull())
|
||||
m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor).pixmap;
|
||||
return m_moveDragCursor;
|
||||
case Qt::LinkAction:
|
||||
if (m_linkDragCursor.isNull())
|
||||
m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor).pixmap;
|
||||
return m_linkDragCursor;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
static const char * const ignoreDragCursorXpmC[] = {
|
||||
"24 30 3 1",
|
||||
". c None",
|
||||
"a c #000000",
|
||||
"X c #FFFFFF",
|
||||
"aa......................",
|
||||
"aXa.....................",
|
||||
"aXXa....................",
|
||||
"aXXXa...................",
|
||||
"aXXXXa..................",
|
||||
"aXXXXXa.................",
|
||||
"aXXXXXXa................",
|
||||
"aXXXXXXXa...............",
|
||||
"aXXXXXXXXa..............",
|
||||
"aXXXXXXXXXa.............",
|
||||
"aXXXXXXaaaa.............",
|
||||
"aXXXaXXa................",
|
||||
"aXXaaXXa................",
|
||||
"aXa..aXXa...............",
|
||||
"aa...aXXa...............",
|
||||
"a.....aXXa..............",
|
||||
"......aXXa.....XXXX.....",
|
||||
".......aXXa..XXaaaaXX...",
|
||||
".......aXXa.XaaaaaaaaX..",
|
||||
"........aa.XaaaXXXXaaaX.",
|
||||
"...........XaaaaX..XaaX.",
|
||||
"..........XaaXaaaX..XaaX",
|
||||
"..........XaaXXaaaX.XaaX",
|
||||
"..........XaaX.XaaaXXaaX",
|
||||
"..........XaaX..XaaaXaaX",
|
||||
"...........XaaX..XaaaaX.",
|
||||
"...........XaaaXXXXaaaX.",
|
||||
"............XaaaaaaaaX..",
|
||||
".............XXaaaaXX...",
|
||||
"...............XXXX....."};
|
||||
|
||||
if (m_ignoreDragCursor.isNull()) {
|
||||
#if !defined (Q_OS_WINCE)
|
||||
HCURSOR cursor = LoadCursor(NULL, IDC_NO);
|
||||
ICONINFO iconInfo = {0, 0, 0, 0, 0};
|
||||
GetIconInfo(cursor, &iconInfo);
|
||||
BITMAP bmColor = {0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
if (iconInfo.hbmColor
|
||||
&& GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor)
|
||||
&& bmColor.bmWidth == bmColor.bmWidthBytes / 4) {
|
||||
const int colorBitsLength = bmColor.bmHeight * bmColor.bmWidthBytes;
|
||||
uchar *colorBits = new uchar[colorBitsLength];
|
||||
GetBitmapBits(iconInfo.hbmColor, colorBitsLength, colorBits);
|
||||
const QImage colorImage(colorBits, bmColor.bmWidth, bmColor.bmHeight,
|
||||
bmColor.bmWidthBytes, QImage::Format_ARGB32);
|
||||
|
||||
m_ignoreDragCursor = QPixmap::fromImage(colorImage);
|
||||
delete [] colorBits;
|
||||
} else {
|
||||
m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
|
||||
}
|
||||
|
||||
DeleteObject(iconInfo.hbmMask);
|
||||
DeleteObject(iconInfo.hbmColor);
|
||||
DestroyCursor(cursor);
|
||||
#else // !Q_OS_WINCE
|
||||
m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
|
||||
#endif // !Q_OS_WINCE
|
||||
}
|
||||
return m_ignoreDragCursor;
|
||||
}
|
||||
|
||||
Qt::DropAction QWindowsDrag::drag(QDrag *drag)
|
||||
{
|
||||
// TODO: Accessibility handling?
|
||||
|
@ -42,6 +42,9 @@
|
||||
struct IDropTargetHelper;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QPlatformScreen;
|
||||
|
||||
class QWindowsDropMimeData : public QWindowsInternalMimeData {
|
||||
public:
|
||||
QWindowsDropMimeData() {}
|
||||
@ -97,8 +100,6 @@ public:
|
||||
|
||||
IDropTargetHelper* dropHelper();
|
||||
|
||||
QPixmap defaultCursor(Qt::DropAction action) const;
|
||||
|
||||
private:
|
||||
static bool m_canceled;
|
||||
|
||||
@ -106,11 +107,6 @@ private:
|
||||
IDataObject *m_dropDataObject;
|
||||
|
||||
IDropTargetHelper* m_cachedDropTargetHelper;
|
||||
|
||||
mutable QPixmap m_copyDragCursor;
|
||||
mutable QPixmap m_moveDragCursor;
|
||||
mutable QPixmap m_linkDragCursor;
|
||||
mutable QPixmap m_ignoreDragCursor;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -195,16 +195,6 @@ static QDebug operator<<(QDebug dbg, const QWindowsScreenData &d)
|
||||
}
|
||||
#endif // !QT_NO_DEBUG_STREAM
|
||||
|
||||
// Return the cursor to be shared by all screens (virtual desktop).
|
||||
static inline QSharedPointer<QPlatformCursor> sharedCursor()
|
||||
{
|
||||
#ifndef QT_NO_CURSOR
|
||||
if (const QScreen *primaryScreen = QGuiApplication::primaryScreen())
|
||||
return static_cast<const QWindowsScreen *>(primaryScreen->handle())->cursorPtr();
|
||||
#endif
|
||||
return QSharedPointer<QPlatformCursor>(new QWindowsCursor);
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QWindowsScreen
|
||||
\brief Windows screen.
|
||||
@ -216,7 +206,7 @@ static inline QSharedPointer<QPlatformCursor> sharedCursor()
|
||||
QWindowsScreen::QWindowsScreen(const QWindowsScreenData &data) :
|
||||
m_data(data)
|
||||
#ifndef QT_NO_CURSOR
|
||||
,m_cursor(sharedCursor())
|
||||
, m_cursor(new QWindowsCursor(this))
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QVector>
|
||||
#include <QtCore/QPair>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtCore/QScopedPointer>
|
||||
#include <qpa/qplatformscreen.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
@ -74,7 +74,7 @@ class QWindowsScreen : public QPlatformScreen
|
||||
{
|
||||
public:
|
||||
#ifndef QT_NO_CURSOR
|
||||
typedef QSharedPointer<QPlatformCursor> CursorPtr;
|
||||
typedef QScopedPointer<QPlatformCursor> CursorPtr;
|
||||
#endif
|
||||
|
||||
explicit QWindowsScreen(const QWindowsScreenData &data);
|
||||
|
@ -507,6 +507,8 @@ QWinRTScreen::QWinRTScreen()
|
||||
hr = d->displayInformation->get_NativeOrientation(&displayOrientation);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
d->nativeOrientation = static_cast<Qt::ScreenOrientation>(static_cast<int>(qtOrientationsFromNative(displayOrientation)));
|
||||
// Set initial pixel density
|
||||
onDpiChanged(Q_NULLPTR, Q_NULLPTR);
|
||||
d->orientation = d->nativeOrientation;
|
||||
|
||||
ComPtr<IApplicationViewStatics2> applicationViewStatics;
|
||||
@ -753,7 +755,6 @@ void QWinRTScreen::initialize()
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
hr = d->displayInformation->add_DpiChanged(Callback<DisplayInformationHandler>(this, &QWinRTScreen::onDpiChanged).Get(), &d->displayTokens[&IDisplayInformation::remove_DpiChanged]);
|
||||
Q_ASSERT_SUCCEEDED(hr);
|
||||
onDpiChanged(Q_NULLPTR, Q_NULLPTR);
|
||||
onOrientationChanged(Q_NULLPTR, Q_NULLPTR);
|
||||
onVisibilityChanged(nullptr, nullptr);
|
||||
}
|
||||
|
@ -1086,8 +1086,12 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
|
||||
case XCB_FOCUS_OUT:
|
||||
HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
|
||||
case XCB_KEY_PRESS:
|
||||
m_keyboard->updateXKBStateFromCore(((xcb_key_press_event_t *)event)->state);
|
||||
{
|
||||
xcb_key_press_event_t *kp = (xcb_key_press_event_t *)event;
|
||||
m_keyboard->updateXKBStateFromCore(kp->state);
|
||||
setTime(kp->time);
|
||||
HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
|
||||
}
|
||||
case XCB_KEY_RELEASE:
|
||||
m_keyboard->updateXKBStateFromCore(((xcb_key_release_event_t *)event)->state);
|
||||
HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
|
||||
|
@ -556,7 +556,8 @@ void QXcbScreen::updateRefreshRate(xcb_randr_mode_t mode)
|
||||
for (; modesIter.rem; xcb_randr_mode_info_next(&modesIter)) {
|
||||
xcb_randr_mode_info_t *modeInfo = modesIter.data;
|
||||
if (modeInfo->id == mode) {
|
||||
m_refreshRate = modeInfo->dot_clock / (modeInfo->htotal * modeInfo->vtotal);
|
||||
const uint32_t dotCount = modeInfo->htotal * modeInfo->vtotal;
|
||||
m_refreshRate = (dotCount != 0) ? modeInfo->dot_clock / dotCount : 0;
|
||||
m_mode = mode;
|
||||
break;
|
||||
}
|
||||
|
@ -314,8 +314,6 @@ void QXcbWindow::create()
|
||||
|
||||
destroy();
|
||||
|
||||
m_deferredExpose = false;
|
||||
m_configureNotifyPending = true;
|
||||
m_windowState = Qt::WindowNoState;
|
||||
|
||||
Qt::WindowType type = window()->type();
|
||||
@ -2032,12 +2030,8 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
|
||||
if (newScreen != currentScreen)
|
||||
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
|
||||
|
||||
m_configureNotifyPending = false;
|
||||
|
||||
if (m_deferredExpose) {
|
||||
m_deferredExpose = false;
|
||||
if (m_mapped)
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
|
||||
}
|
||||
|
||||
if (m_usingSyncProtocol && m_syncState == SyncReceived)
|
||||
m_syncState = SyncAndConfigureReceived;
|
||||
@ -2104,9 +2098,7 @@ void QXcbWindow::handleMapNotifyEvent(const xcb_map_notify_event_t *event)
|
||||
m_mapped = true;
|
||||
if (m_deferredActivation)
|
||||
requestActivateWindow();
|
||||
if (m_configureNotifyPending)
|
||||
m_deferredExpose = true;
|
||||
else
|
||||
|
||||
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
|
||||
}
|
||||
}
|
||||
|
@ -232,8 +232,6 @@ protected:
|
||||
bool m_transparent;
|
||||
bool m_usingSyncProtocol;
|
||||
bool m_deferredActivation;
|
||||
bool m_deferredExpose;
|
||||
bool m_configureNotifyPending;
|
||||
bool m_embedded;
|
||||
bool m_alertState;
|
||||
xcb_window_t m_netWmUserTimeWindow;
|
||||
|
@ -175,8 +175,11 @@ private:
|
||||
tp = QMetaType::UnknownType;
|
||||
}
|
||||
if (tp == QMetaType::UnknownType) {
|
||||
qWarning("Don't know how to handle '%s', use qRegisterMetaType to register it.",
|
||||
member.parameterNames().at(i).constData());
|
||||
qWarning("QSignalSpy: Unable to handle parameter '%s' of type '%s' of method '%s',"
|
||||
" use qRegisterMetaType to register it.",
|
||||
member.parameterNames().at(i).constData(),
|
||||
member.parameterTypes().at(i).constData(),
|
||||
member.name().constData());
|
||||
}
|
||||
args << tp;
|
||||
}
|
||||
|
@ -1172,8 +1172,7 @@ void QOpenGLWidget::resizeEvent(QResizeEvent *e)
|
||||
|
||||
d->recreateFbo();
|
||||
resizeGL(width(), height());
|
||||
d->invokeUserPaint();
|
||||
d->resolveSamples();
|
||||
d->sendPaintEvent(QRect(QPoint(0, 0), size()));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -271,6 +271,9 @@ QWidgetPrivate::QWidgetPrivate(int version)
|
||||
#ifndef QT_NO_IM
|
||||
, inheritsInputMethodHints(0)
|
||||
#endif
|
||||
#ifndef QT_NO_OPENGL
|
||||
, renderToTextureReallyDirty(1)
|
||||
#endif
|
||||
#if defined(Q_OS_WIN)
|
||||
, noPaintOnScreen(0)
|
||||
#endif
|
||||
@ -5560,7 +5563,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
|
||||
<< "geometry ==" << QRect(q->mapTo(q->window(), QPoint(0, 0)), q->size());
|
||||
#endif
|
||||
|
||||
bool grabbed = false;
|
||||
bool skipPaintEvent = false;
|
||||
#ifndef QT_NO_OPENGL
|
||||
if (renderToTexture) {
|
||||
// This widget renders into a texture which is composed later. We just need to
|
||||
@ -5574,14 +5577,18 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
|
||||
} else {
|
||||
// We are not drawing to a backingstore: fall back to QImage
|
||||
p.drawImage(q->rect(), grabFramebuffer());
|
||||
grabbed = true;
|
||||
skipPaintEvent = true;
|
||||
}
|
||||
endBackingStorePainting();
|
||||
}
|
||||
if (renderToTextureReallyDirty)
|
||||
renderToTextureReallyDirty = 0;
|
||||
else
|
||||
skipPaintEvent = true;
|
||||
}
|
||||
#endif // QT_NO_OPENGL
|
||||
|
||||
if (!grabbed) {
|
||||
if (!skipPaintEvent) {
|
||||
//actually send the paint event
|
||||
sendPaintEvent(toBePainted);
|
||||
}
|
||||
|
@ -743,6 +743,9 @@ public:
|
||||
#ifndef QT_NO_IM
|
||||
uint inheritsInputMethodHints : 1;
|
||||
#endif
|
||||
#ifndef QT_NO_OPENGL
|
||||
uint renderToTextureReallyDirty : 1;
|
||||
#endif
|
||||
|
||||
// *************************** Platform specific ************************************
|
||||
#if defined(Q_OS_WIN)
|
||||
|
@ -1000,6 +1000,16 @@ void QPlatformTextureListWatcher::onLockStatusChanged(bool locked)
|
||||
if (!isLocked())
|
||||
m_backingStore->sync();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget)
|
||||
{
|
||||
Q_UNUSED(tlw);
|
||||
Q_UNUSED(widget);
|
||||
return Q_NULLPTR;
|
||||
}
|
||||
|
||||
#endif // QT_NO_OPENGL
|
||||
|
||||
static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra)
|
||||
@ -1220,6 +1230,9 @@ void QWidgetBackingStore::doSync()
|
||||
QWidget *w = static_cast<QWidget *>(tl->source(i));
|
||||
if (dirtyRenderToTextureWidgets.contains(w)) {
|
||||
const QRect rect = tl->geometry(i); // mapped to the tlw already
|
||||
// Set a flag to indicate that the paint event for this
|
||||
// render-to-texture widget must not to be optimized away.
|
||||
w->d_func()->renderToTextureReallyDirty = 1;
|
||||
dirty += rect;
|
||||
toClean += rect;
|
||||
}
|
||||
|
@ -284,12 +284,6 @@ bool QSystemTrayIcon::isVisible() const
|
||||
*/
|
||||
bool QSystemTrayIcon::event(QEvent *e)
|
||||
{
|
||||
#if defined(Q_DEAD_CODE_FROM_QT4_X11)
|
||||
if (e->type() == QEvent::ToolTip) {
|
||||
Q_D(QSystemTrayIcon);
|
||||
return d->sys->deliverToolTipEvent(e);
|
||||
}
|
||||
#endif
|
||||
return QObject::event(e);
|
||||
}
|
||||
|
||||
|
@ -196,6 +196,9 @@ void QSystemTrayIconSys::mouseDoubleClickEvent(QMouseEvent *ev)
|
||||
bool QSystemTrayIconSys::event(QEvent *e)
|
||||
{
|
||||
switch (e->type()) {
|
||||
case QEvent::ToolTip:
|
||||
QApplication::sendEvent(q, e);
|
||||
break;
|
||||
#ifndef QT_NO_WHEELEVENT
|
||||
case QEvent::Wheel:
|
||||
return QApplication::sendEvent(q, e);
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QThread>
|
||||
#include <QtCore/QTemporaryDir>
|
||||
#include <QtCore/QRegExp>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QMetaType>
|
||||
@ -54,14 +55,6 @@ Q_DECLARE_METATYPE(QProcess::ExitStatus);
|
||||
Q_DECLARE_METATYPE(QProcess::ProcessState);
|
||||
#endif
|
||||
|
||||
#define QPROCESS_VERIFY(Process, Fn) \
|
||||
{ \
|
||||
const bool ret = Process.Fn; \
|
||||
if (ret == false) \
|
||||
qWarning("QProcess error: %d: %s", Process.error(), qPrintable(Process.errorString())); \
|
||||
QVERIFY(ret); \
|
||||
}
|
||||
|
||||
typedef void (QProcess::*QProcessFinishedSignal1)(int);
|
||||
typedef void (QProcess::*QProcessFinishedSignal2)(int, QProcess::ExitStatus);
|
||||
typedef void (QProcess::*QProcessErrorSignal)(QProcess::ProcessError);
|
||||
@ -180,6 +173,7 @@ protected slots:
|
||||
|
||||
private:
|
||||
qint64 bytesAvailable;
|
||||
QTemporaryDir m_temporaryDir;
|
||||
#endif //QT_NO_PROCESS
|
||||
};
|
||||
|
||||
@ -188,6 +182,7 @@ void tst_QProcess::initTestCase()
|
||||
#ifdef QT_NO_PROCESS
|
||||
QSKIP("This test requires QProcess support");
|
||||
#else
|
||||
QVERIFY2(m_temporaryDir.isValid(), qPrintable(m_temporaryDir.errorString()));
|
||||
// chdir to our testdata path and execute helper apps relative to that.
|
||||
QString testdata_dir = QFileInfo(QFINDTESTDATA("testProcessNormal")).absolutePath();
|
||||
QVERIFY2(QDir::setCurrent(testdata_dir), qPrintable("Could not chdir to " + testdata_dir));
|
||||
@ -1717,7 +1712,7 @@ void tst_QProcess::failToStartEmptyArgs()
|
||||
// Reading and writing to a process is not supported on Qt/CE
|
||||
void tst_QProcess::removeFileWhileProcessIsRunning()
|
||||
{
|
||||
QFile file("removeFile.txt");
|
||||
QFile file(m_temporaryDir.path() + QLatin1String("/removeFile.txt"));
|
||||
QVERIFY(file.open(QFile::WriteOnly));
|
||||
|
||||
QProcess process;
|
||||
@ -1948,16 +1943,16 @@ void tst_QProcess::setStandardInputFile()
|
||||
{
|
||||
static const char data[] = "A bunch\1of\2data\3\4\5\6\7...";
|
||||
QProcess process;
|
||||
QFile file("data");
|
||||
QFile file(m_temporaryDir.path() + QLatin1String("/data-sif"));
|
||||
|
||||
QVERIFY(file.open(QIODevice::WriteOnly));
|
||||
file.write(data, sizeof data);
|
||||
file.close();
|
||||
|
||||
process.setStandardInputFile("data");
|
||||
process.setStandardInputFile(file.fileName());
|
||||
process.start("testProcessEcho/testProcessEcho");
|
||||
|
||||
QPROCESS_VERIFY(process, waitForFinished());
|
||||
QVERIFY(process.waitForFinished());
|
||||
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
|
||||
QCOMPARE(process.exitCode(), 0);
|
||||
QByteArray all = process.readAll();
|
||||
@ -1967,7 +1962,7 @@ void tst_QProcess::setStandardInputFile()
|
||||
QProcess process2;
|
||||
process2.setStandardInputFile(QProcess::nullDevice());
|
||||
process2.start("testProcessEcho/testProcessEcho");
|
||||
QPROCESS_VERIFY(process2, waitForFinished());
|
||||
QVERIFY(process2.waitForFinished());
|
||||
all = process2.readAll();
|
||||
QCOMPARE(all.size(), 0);
|
||||
}
|
||||
@ -2016,7 +2011,7 @@ void tst_QProcess::setStandardOutputFile()
|
||||
QIODevice::OpenMode mode = append ? QIODevice::Append : QIODevice::Truncate;
|
||||
|
||||
// create the destination file with data
|
||||
QFile file("data");
|
||||
QFile file(m_temporaryDir.path() + QLatin1String("/data-stdof-") + QLatin1String(QTest::currentDataTag()));
|
||||
QVERIFY(file.open(QIODevice::WriteOnly));
|
||||
file.write(data, sizeof data - 1);
|
||||
file.close();
|
||||
@ -2025,13 +2020,13 @@ void tst_QProcess::setStandardOutputFile()
|
||||
QProcess process;
|
||||
process.setReadChannelMode(channelMode);
|
||||
if (channelToTest == QProcess::StandardOutput)
|
||||
process.setStandardOutputFile("data", mode);
|
||||
process.setStandardOutputFile(file.fileName(), mode);
|
||||
else
|
||||
process.setStandardErrorFile("data", mode);
|
||||
process.setStandardErrorFile(file.fileName(), mode);
|
||||
|
||||
process.start("testProcessEcho2/testProcessEcho2");
|
||||
process.write(testdata, sizeof testdata);
|
||||
QPROCESS_VERIFY(process,waitForFinished());
|
||||
QVERIFY(process.waitForFinished());
|
||||
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
|
||||
QCOMPARE(process.exitCode(), 0);
|
||||
|
||||
@ -2062,7 +2057,7 @@ void tst_QProcess::setStandardOutputFileNullDevice()
|
||||
process.setStandardOutputFile(QProcess::nullDevice());
|
||||
process.start("testProcessEcho2/testProcessEcho2");
|
||||
process.write(testdata, sizeof testdata);
|
||||
QPROCESS_VERIFY(process,waitForFinished());
|
||||
QVERIFY(process.waitForFinished());
|
||||
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
|
||||
QCOMPARE(process.exitCode(), 0);
|
||||
QCOMPARE(process.bytesAvailable(), Q_INT64_C(0));
|
||||
@ -2074,13 +2069,14 @@ void tst_QProcess::setStandardOutputFileAndWaitForBytesWritten()
|
||||
{
|
||||
static const char testdata[] = "Test data.";
|
||||
|
||||
QFile file("data");
|
||||
QFile file(m_temporaryDir.path() + QLatin1String("/data-stdofawfbw"));
|
||||
QProcess process;
|
||||
process.setStandardOutputFile(file.fileName());
|
||||
process.start("testProcessEcho2/testProcessEcho2");
|
||||
QVERIFY2(process.waitForStarted(), qPrintable(process.errorString()));
|
||||
process.write(testdata, sizeof testdata);
|
||||
process.waitForBytesWritten();
|
||||
QPROCESS_VERIFY(process, waitForFinished());
|
||||
QVERIFY(process.waitForFinished());
|
||||
QCOMPARE(process.exitStatus(), QProcess::NormalExit);
|
||||
QCOMPARE(process.exitCode(), 0);
|
||||
|
||||
@ -2122,10 +2118,10 @@ void tst_QProcess::setStandardOutputProcess()
|
||||
if (waitForBytesWritten)
|
||||
source.waitForBytesWritten();
|
||||
source.closeWriteChannel();
|
||||
QPROCESS_VERIFY(source, waitForFinished());
|
||||
QVERIFY(source.waitForFinished());
|
||||
QCOMPARE(source.exitStatus(), QProcess::NormalExit);
|
||||
QCOMPARE(source.exitCode(), 0);
|
||||
QPROCESS_VERIFY(sink, waitForFinished());
|
||||
QVERIFY(sink.waitForFinished());
|
||||
QCOMPARE(sink.exitStatus(), QProcess::NormalExit);
|
||||
QCOMPARE(sink.exitCode(), 0);
|
||||
QByteArray all = sink.readAll();
|
||||
@ -2151,14 +2147,15 @@ void tst_QProcess::fileWriterProcess()
|
||||
|
||||
QTime stopWatch;
|
||||
stopWatch.start();
|
||||
const QString fileName = QLatin1String("fileWriterProcess.txt");
|
||||
const QString fileName = m_temporaryDir.path() + QLatin1String("/fileWriterProcess.txt");
|
||||
const QString binary = QDir::currentPath() + QLatin1String("/fileWriterProcess/fileWriterProcess");
|
||||
|
||||
do {
|
||||
if (QFile::exists(fileName))
|
||||
QVERIFY(QFile::remove(fileName));
|
||||
QProcess process;
|
||||
process.start("fileWriterProcess/fileWriterProcess",
|
||||
QIODevice::ReadWrite | QIODevice::Text);
|
||||
process.setWorkingDirectory(m_temporaryDir.path());
|
||||
process.start(binary, QIODevice::ReadWrite | QIODevice::Text);
|
||||
process.write(stdinStr);
|
||||
process.closeWriteChannel();
|
||||
while (process.bytesToWrite()) {
|
||||
@ -2181,8 +2178,9 @@ void tst_QProcess::detachedWorkingDirectoryAndPid()
|
||||
QTest::qSleep(1000);
|
||||
#endif
|
||||
|
||||
QFile infoFile(QDir::currentPath() + QLatin1String("/detachedinfo.txt"));
|
||||
infoFile.remove();
|
||||
QFile infoFile(m_temporaryDir.path() + QLatin1String("/detachedinfo.txt"));
|
||||
if (infoFile.exists())
|
||||
QVERIFY(infoFile.remove());
|
||||
|
||||
QString workingDir = QDir::currentPath() + "/testDetached";
|
||||
|
||||
|
@ -49,6 +49,9 @@ class tst_QItemModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QItemModel();
|
||||
|
||||
public slots:
|
||||
void init();
|
||||
void cleanup();
|
||||
@ -124,6 +127,11 @@ private:
|
||||
bool insertRecursively;
|
||||
};
|
||||
|
||||
tst_QItemModel::tst_QItemModel()
|
||||
{
|
||||
qRegisterMetaType<QAbstractItemModel::LayoutChangeHint>();
|
||||
}
|
||||
|
||||
void tst_QItemModel::init()
|
||||
{
|
||||
testModels = new ModelsToTest();
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
#include <qatomic.h>
|
||||
#include <qcoreapplication.h>
|
||||
#include <qmutex.h>
|
||||
#include <qthread.h>
|
||||
@ -54,7 +55,25 @@ private slots:
|
||||
static const int iterations = 4;
|
||||
static const int ThreadCount = 4;
|
||||
|
||||
class wait_QMutex_Thread_1 : public QThread
|
||||
// Terminate thread in destructor for threads instantiated on the stack
|
||||
class TerminatingThread : public QThread
|
||||
{
|
||||
public:
|
||||
explicit TerminatingThread()
|
||||
{
|
||||
setTerminationEnabled(true);
|
||||
}
|
||||
|
||||
~TerminatingThread()
|
||||
{
|
||||
if (isRunning()) {
|
||||
qWarning() << "forcibly terminating " << objectName();
|
||||
terminate();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class wait_QMutex_Thread_1 : public TerminatingThread
|
||||
{
|
||||
public:
|
||||
QMutex mutex;
|
||||
@ -72,7 +91,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class wait_QMutex_Thread_2 : public QThread
|
||||
class wait_QMutex_Thread_2 : public TerminatingThread
|
||||
{
|
||||
public:
|
||||
QWaitCondition started;
|
||||
@ -93,7 +112,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class wait_QReadWriteLock_Thread_1 : public QThread
|
||||
class wait_QReadWriteLock_Thread_1 : public TerminatingThread
|
||||
{
|
||||
public:
|
||||
QReadWriteLock readWriteLock;
|
||||
@ -111,7 +130,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class wait_QReadWriteLock_Thread_2 : public QThread
|
||||
class wait_QReadWriteLock_Thread_2 : public TerminatingThread
|
||||
{
|
||||
public:
|
||||
QWaitCondition started;
|
||||
@ -155,7 +174,11 @@ void tst_QWaitCondition::wait_QMutex()
|
||||
// test multiple threads waiting on separate wait conditions
|
||||
wait_QMutex_Thread_1 thread[ThreadCount];
|
||||
|
||||
const QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_mutex_")
|
||||
+ QString::number(i) + QLatin1Char('_');
|
||||
|
||||
for (x = 0; x < ThreadCount; ++x) {
|
||||
thread[x].setObjectName(prefix + QString::number(x));
|
||||
thread[x].mutex.lock();
|
||||
thread[x].start();
|
||||
// wait for thread to start
|
||||
@ -185,8 +208,12 @@ void tst_QWaitCondition::wait_QMutex()
|
||||
QWaitCondition cond1, cond2;
|
||||
wait_QMutex_Thread_2 thread[ThreadCount];
|
||||
|
||||
const QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_mutex_")
|
||||
+ QString::number(i) + QLatin1Char('_');
|
||||
|
||||
mutex.lock();
|
||||
for (x = 0; x < ThreadCount; ++x) {
|
||||
thread[x].setObjectName(prefix + QString::number(x));
|
||||
thread[x].mutex = &mutex;
|
||||
thread[x].cond = (x < ThreadCount / 2) ? &cond1 : &cond2;
|
||||
thread[x].start();
|
||||
@ -289,7 +316,10 @@ void tst_QWaitCondition::wait_QReadWriteLock()
|
||||
// test multiple threads waiting on separate wait conditions
|
||||
wait_QReadWriteLock_Thread_1 thread[ThreadCount];
|
||||
|
||||
const QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_lockforread_");
|
||||
|
||||
for (x = 0; x < ThreadCount; ++x) {
|
||||
thread[x].setObjectName(prefix + QString::number(x));
|
||||
thread[x].readWriteLock.lockForRead();
|
||||
thread[x].start();
|
||||
// wait for thread to start
|
||||
@ -319,8 +349,11 @@ void tst_QWaitCondition::wait_QReadWriteLock()
|
||||
QWaitCondition cond1, cond2;
|
||||
wait_QReadWriteLock_Thread_2 thread[ThreadCount];
|
||||
|
||||
const QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_lockforwrite_");
|
||||
|
||||
readWriteLock.lockForWrite();
|
||||
for (x = 0; x < ThreadCount; ++x) {
|
||||
thread[x].setObjectName(prefix + QString::number(x));
|
||||
thread[x].readWriteLock = &readWriteLock;
|
||||
thread[x].cond = (x < ThreadCount / 2) ? &cond1 : &cond2;
|
||||
thread[x].start();
|
||||
@ -346,11 +379,17 @@ void tst_QWaitCondition::wait_QReadWriteLock()
|
||||
}
|
||||
}
|
||||
|
||||
class wake_Thread : public QThread
|
||||
class WakeThreadBase : public TerminatingThread
|
||||
{
|
||||
public:
|
||||
static int count;
|
||||
QAtomicInt *count;
|
||||
|
||||
WakeThreadBase() : count(Q_NULLPTR) {}
|
||||
};
|
||||
|
||||
class wake_Thread : public WakeThreadBase
|
||||
{
|
||||
public:
|
||||
QWaitCondition started;
|
||||
QWaitCondition dummy;
|
||||
|
||||
@ -366,24 +405,23 @@ public:
|
||||
|
||||
void run()
|
||||
{
|
||||
Q_ASSERT(count);
|
||||
Q_ASSERT(mutex);
|
||||
Q_ASSERT(cond);
|
||||
mutex->lock();
|
||||
++count;
|
||||
++*count;
|
||||
dummy.wakeOne(); // this wakeup should be lost
|
||||
started.wakeOne();
|
||||
dummy.wakeAll(); // this one too
|
||||
cond->wait(mutex);
|
||||
--count;
|
||||
--*count;
|
||||
mutex->unlock();
|
||||
}
|
||||
};
|
||||
|
||||
int wake_Thread::count = 0;
|
||||
|
||||
class wake_Thread_2 : public QThread
|
||||
class wake_Thread_2 : public WakeThreadBase
|
||||
{
|
||||
public:
|
||||
static int count;
|
||||
|
||||
QWaitCondition started;
|
||||
QWaitCondition dummy;
|
||||
|
||||
@ -399,22 +437,27 @@ public:
|
||||
|
||||
void run()
|
||||
{
|
||||
Q_ASSERT(count);
|
||||
Q_ASSERT(readWriteLock);
|
||||
Q_ASSERT(cond);
|
||||
readWriteLock->lockForWrite();
|
||||
++count;
|
||||
++*count;
|
||||
dummy.wakeOne(); // this wakeup should be lost
|
||||
started.wakeOne();
|
||||
dummy.wakeAll(); // this one too
|
||||
cond->wait(readWriteLock);
|
||||
--count;
|
||||
--*count;
|
||||
readWriteLock->unlock();
|
||||
}
|
||||
};
|
||||
|
||||
int wake_Thread_2::count = 0;
|
||||
|
||||
void tst_QWaitCondition::wakeOne()
|
||||
{
|
||||
static const int firstWaitInterval = 1000;
|
||||
static const int waitInterval = 30;
|
||||
|
||||
int x;
|
||||
QAtomicInt count;
|
||||
// wake up threads, one at a time
|
||||
for (int i = 0; i < iterations; ++i) {
|
||||
QMutex mutex;
|
||||
@ -424,8 +467,13 @@ void tst_QWaitCondition::wakeOne()
|
||||
wake_Thread thread[ThreadCount];
|
||||
bool thread_exited[ThreadCount];
|
||||
|
||||
QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_mutex_")
|
||||
+ QString::number(i) + QLatin1Char('_');
|
||||
|
||||
mutex.lock();
|
||||
for (x = 0; x < ThreadCount; ++x) {
|
||||
thread[x].setObjectName(prefix + QString::number(x));
|
||||
thread[x].count = &count;
|
||||
thread[x].mutex = &mutex;
|
||||
thread[x].cond = &cond;
|
||||
thread_exited[x] = false;
|
||||
@ -438,7 +486,7 @@ void tst_QWaitCondition::wakeOne()
|
||||
}
|
||||
mutex.unlock();
|
||||
|
||||
QCOMPARE(wake_Thread::count, ThreadCount);
|
||||
QCOMPARE(count.load(), ThreadCount);
|
||||
|
||||
// wake up threads one at a time
|
||||
for (x = 0; x < ThreadCount; ++x) {
|
||||
@ -452,24 +500,29 @@ void tst_QWaitCondition::wakeOne()
|
||||
for (int y = 0; y < ThreadCount; ++y) {
|
||||
if (thread_exited[y])
|
||||
continue;
|
||||
if (thread[y].wait(exited > 0 ? 10 : 1000)) {
|
||||
if (thread[y].wait(exited > 0 ? waitInterval : firstWaitInterval)) {
|
||||
thread_exited[y] = true;
|
||||
++exited;
|
||||
}
|
||||
}
|
||||
|
||||
QCOMPARE(exited, 1);
|
||||
QCOMPARE(wake_Thread::count, ThreadCount - (x + 1));
|
||||
QCOMPARE(count.load(), ThreadCount - (x + 1));
|
||||
}
|
||||
|
||||
QCOMPARE(wake_Thread::count, 0);
|
||||
QCOMPARE(count.load(), 0);
|
||||
|
||||
// QReadWriteLock
|
||||
QReadWriteLock readWriteLock;
|
||||
wake_Thread_2 rwthread[ThreadCount];
|
||||
|
||||
prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_readwritelock_")
|
||||
+ QString::number(i) + QLatin1Char('_');
|
||||
|
||||
readWriteLock.lockForWrite();
|
||||
for (x = 0; x < ThreadCount; ++x) {
|
||||
rwthread[x].setObjectName(prefix + QString::number(x));
|
||||
rwthread[x].count = &count;
|
||||
rwthread[x].readWriteLock = &readWriteLock;
|
||||
rwthread[x].cond = &cond;
|
||||
thread_exited[x] = false;
|
||||
@ -482,7 +535,7 @@ void tst_QWaitCondition::wakeOne()
|
||||
}
|
||||
readWriteLock.unlock();
|
||||
|
||||
QCOMPARE(wake_Thread_2::count, ThreadCount);
|
||||
QCOMPARE(count.load(), ThreadCount);
|
||||
|
||||
// wake up threads one at a time
|
||||
for (x = 0; x < ThreadCount; ++x) {
|
||||
@ -496,17 +549,17 @@ void tst_QWaitCondition::wakeOne()
|
||||
for (int y = 0; y < ThreadCount; ++y) {
|
||||
if (thread_exited[y])
|
||||
continue;
|
||||
if (rwthread[y].wait(exited > 0 ? 10 : 1000)) {
|
||||
if (rwthread[y].wait(exited > 0 ? waitInterval : firstWaitInterval)) {
|
||||
thread_exited[y] = true;
|
||||
++exited;
|
||||
}
|
||||
}
|
||||
|
||||
QCOMPARE(exited, 1);
|
||||
QCOMPARE(wake_Thread_2::count, ThreadCount - (x + 1));
|
||||
QCOMPARE(count.load(), ThreadCount - (x + 1));
|
||||
}
|
||||
|
||||
QCOMPARE(wake_Thread_2::count, 0);
|
||||
QCOMPARE(count.load(), 0);
|
||||
}
|
||||
|
||||
// wake up threads, two at a time
|
||||
@ -518,8 +571,13 @@ void tst_QWaitCondition::wakeOne()
|
||||
wake_Thread thread[ThreadCount];
|
||||
bool thread_exited[ThreadCount];
|
||||
|
||||
QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_mutex2_")
|
||||
+ QString::number(i) + QLatin1Char('_');
|
||||
|
||||
mutex.lock();
|
||||
for (x = 0; x < ThreadCount; ++x) {
|
||||
thread[x].setObjectName(prefix + QString::number(x));
|
||||
thread[x].count = &count;
|
||||
thread[x].mutex = &mutex;
|
||||
thread[x].cond = &cond;
|
||||
thread_exited[x] = false;
|
||||
@ -532,7 +590,7 @@ void tst_QWaitCondition::wakeOne()
|
||||
}
|
||||
mutex.unlock();
|
||||
|
||||
QCOMPARE(wake_Thread::count, ThreadCount);
|
||||
QCOMPARE(count.load(), ThreadCount);
|
||||
|
||||
// wake up threads one at a time
|
||||
for (x = 0; x < ThreadCount; x += 2) {
|
||||
@ -548,24 +606,29 @@ void tst_QWaitCondition::wakeOne()
|
||||
for (int y = 0; y < ThreadCount; ++y) {
|
||||
if (thread_exited[y])
|
||||
continue;
|
||||
if (thread[y].wait(exited > 0 ? 10 : 1000)) {
|
||||
if (thread[y].wait(exited > 0 ? waitInterval : firstWaitInterval)) {
|
||||
thread_exited[y] = true;
|
||||
++exited;
|
||||
}
|
||||
}
|
||||
|
||||
QCOMPARE(exited, 2);
|
||||
QCOMPARE(wake_Thread::count, ThreadCount - (x + 2));
|
||||
QCOMPARE(count.load(), ThreadCount - (x + 2));
|
||||
}
|
||||
|
||||
QCOMPARE(wake_Thread::count, 0);
|
||||
QCOMPARE(count.load(), 0);
|
||||
|
||||
// QReadWriteLock
|
||||
QReadWriteLock readWriteLock;
|
||||
wake_Thread_2 rwthread[ThreadCount];
|
||||
|
||||
prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_readwritelock_")
|
||||
+ QString::number(i) + QLatin1Char('_');
|
||||
|
||||
readWriteLock.lockForWrite();
|
||||
for (x = 0; x < ThreadCount; ++x) {
|
||||
rwthread[x].setObjectName(prefix + QString::number(x));
|
||||
rwthread[x].count = &count;
|
||||
rwthread[x].readWriteLock = &readWriteLock;
|
||||
rwthread[x].cond = &cond;
|
||||
thread_exited[x] = false;
|
||||
@ -578,7 +641,7 @@ void tst_QWaitCondition::wakeOne()
|
||||
}
|
||||
readWriteLock.unlock();
|
||||
|
||||
QCOMPARE(wake_Thread_2::count, ThreadCount);
|
||||
QCOMPARE(count.load(), ThreadCount);
|
||||
|
||||
// wake up threads one at a time
|
||||
for (x = 0; x < ThreadCount; x += 2) {
|
||||
@ -594,23 +657,24 @@ void tst_QWaitCondition::wakeOne()
|
||||
for (int y = 0; y < ThreadCount; ++y) {
|
||||
if (thread_exited[y])
|
||||
continue;
|
||||
if (rwthread[y].wait(exited > 0 ? 10 : 1000)) {
|
||||
if (rwthread[y].wait(exited > 0 ? waitInterval : firstWaitInterval)) {
|
||||
thread_exited[y] = true;
|
||||
++exited;
|
||||
}
|
||||
}
|
||||
|
||||
QCOMPARE(exited, 2);
|
||||
QCOMPARE(wake_Thread_2::count, ThreadCount - (x + 2));
|
||||
QCOMPARE(count.load(), ThreadCount - (x + 2));
|
||||
}
|
||||
|
||||
QCOMPARE(wake_Thread_2::count, 0);
|
||||
QCOMPARE(count.load(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QWaitCondition::wakeAll()
|
||||
{
|
||||
int x;
|
||||
QAtomicInt count;
|
||||
for (int i = 0; i < iterations; ++i) {
|
||||
QMutex mutex;
|
||||
QWaitCondition cond;
|
||||
@ -618,8 +682,13 @@ void tst_QWaitCondition::wakeAll()
|
||||
// QMutex
|
||||
wake_Thread thread[ThreadCount];
|
||||
|
||||
QString prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_mutex_")
|
||||
+ QString::number(i) + QLatin1Char('_');
|
||||
|
||||
mutex.lock();
|
||||
for (x = 0; x < ThreadCount; ++x) {
|
||||
thread[x].setObjectName(prefix + QString::number(x));
|
||||
thread[x].count = &count;
|
||||
thread[x].mutex = &mutex;
|
||||
thread[x].cond = &cond;
|
||||
thread[x].start();
|
||||
@ -628,7 +697,7 @@ void tst_QWaitCondition::wakeAll()
|
||||
}
|
||||
mutex.unlock();
|
||||
|
||||
QCOMPARE(wake_Thread::count, ThreadCount);
|
||||
QCOMPARE(count.load(), ThreadCount);
|
||||
|
||||
// wake up all threads at once
|
||||
mutex.lock();
|
||||
@ -643,14 +712,19 @@ void tst_QWaitCondition::wakeAll()
|
||||
}
|
||||
|
||||
QCOMPARE(exited, ThreadCount);
|
||||
QCOMPARE(wake_Thread::count, 0);
|
||||
QCOMPARE(count.load(), 0);
|
||||
|
||||
// QReadWriteLock
|
||||
QReadWriteLock readWriteLock;
|
||||
wake_Thread_2 rwthread[ThreadCount];
|
||||
|
||||
prefix = QLatin1String(QTest::currentTestFunction()) + QLatin1String("_readwritelock_")
|
||||
+ QString::number(i) + QLatin1Char('_');
|
||||
|
||||
readWriteLock.lockForWrite();
|
||||
for (x = 0; x < ThreadCount; ++x) {
|
||||
rwthread[x].setObjectName(prefix + QString::number(x));
|
||||
rwthread[x].count = &count;
|
||||
rwthread[x].readWriteLock = &readWriteLock;
|
||||
rwthread[x].cond = &cond;
|
||||
rwthread[x].start();
|
||||
@ -659,7 +733,7 @@ void tst_QWaitCondition::wakeAll()
|
||||
}
|
||||
readWriteLock.unlock();
|
||||
|
||||
QCOMPARE(wake_Thread_2::count, ThreadCount);
|
||||
QCOMPARE(count.load(), ThreadCount);
|
||||
|
||||
// wake up all threads at once
|
||||
readWriteLock.lockForWrite();
|
||||
@ -674,11 +748,11 @@ void tst_QWaitCondition::wakeAll()
|
||||
}
|
||||
|
||||
QCOMPARE(exited, ThreadCount);
|
||||
QCOMPARE(wake_Thread_2::count, 0);
|
||||
QCOMPARE(count.load(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
class wait_RaceConditionThread : public QThread
|
||||
class wait_RaceConditionThread : public TerminatingThread
|
||||
{
|
||||
public:
|
||||
wait_RaceConditionThread(QMutex *mutex, QWaitCondition *startup, QWaitCondition *waitCondition,
|
||||
@ -707,7 +781,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class wait_RaceConditionThread_2 : public QThread
|
||||
class wait_RaceConditionThread_2 : public TerminatingThread
|
||||
{
|
||||
public:
|
||||
wait_RaceConditionThread_2(QReadWriteLock *readWriteLock,
|
||||
|
@ -36,7 +36,6 @@
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QImage>
|
||||
#include <QImageReader>
|
||||
#include <QImageWriter>
|
||||
@ -46,6 +45,7 @@
|
||||
#include <QTcpServer>
|
||||
#include <QTimer>
|
||||
#include <QTemporaryDir>
|
||||
#include <QTemporaryFile>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
@ -53,6 +53,22 @@ typedef QMap<QString, QString> QStringMap;
|
||||
typedef QList<int> QIntList;
|
||||
Q_DECLARE_METATYPE(QImage::Format)
|
||||
|
||||
static QByteArray msgFileOpenWriteFailed(const QFile &file)
|
||||
{
|
||||
const QString result = QLatin1String("Cannot open \"")
|
||||
+ QDir::toNativeSeparators(file.fileName())
|
||||
+ QLatin1String("\" for writing: ") + file.errorString();
|
||||
return result.toLocal8Bit();
|
||||
}
|
||||
|
||||
static QByteArray msgFileOpenReadFailed(const QFile &file)
|
||||
{
|
||||
const QString result = QLatin1String("Cannot open \"")
|
||||
+ QDir::toNativeSeparators(file.fileName())
|
||||
+ QLatin1String("\" for reading: ") + file.errorString();
|
||||
return result.toLocal8Bit();
|
||||
}
|
||||
|
||||
class tst_QImageReader : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -1051,7 +1067,7 @@ void tst_QImageReader::readFromDevice()
|
||||
const QString imageFileName = prefix + fileName;
|
||||
QImage expectedImage(imageFileName, format);
|
||||
QFile file(imageFileName);
|
||||
QVERIFY(file.open(QFile::ReadOnly));
|
||||
QVERIFY2(file.open(QFile::ReadOnly), msgFileOpenReadFailed(file).constData());
|
||||
QByteArray imageData = file.readAll();
|
||||
QVERIFY(!imageData.isEmpty());
|
||||
{
|
||||
@ -1129,12 +1145,11 @@ void tst_QImageReader::readFromFileAfterJunk()
|
||||
|
||||
SKIP_IF_UNSUPPORTED(format);
|
||||
|
||||
QFile::remove("junk");
|
||||
QFile junkFile("junk");
|
||||
QVERIFY(junkFile.open(QFile::WriteOnly));
|
||||
QTemporaryFile junkFile(m_temporaryDir.path() + QLatin1String("/junkXXXXXX"));
|
||||
QVERIFY2(junkFile.open(), msgFileOpenWriteFailed(junkFile).constData());
|
||||
|
||||
QFile imageFile(prefix + fileName);
|
||||
QVERIFY(imageFile.open(QFile::ReadOnly));
|
||||
QVERIFY2(imageFile.open(QFile::ReadOnly), msgFileOpenReadFailed(imageFile).constData());
|
||||
QByteArray imageData = imageFile.readAll();
|
||||
QVERIFY(!imageData.isNull());
|
||||
|
||||
@ -1155,7 +1170,7 @@ void tst_QImageReader::readFromFileAfterJunk()
|
||||
}
|
||||
}
|
||||
junkFile.close();
|
||||
junkFile.open(QFile::ReadOnly);
|
||||
QVERIFY2(junkFile.open(), msgFileOpenReadFailed(junkFile).constData());
|
||||
|
||||
for (int i = 0; i < iterations; ++i) {
|
||||
QByteArray ole = junkFile.read(9);
|
||||
@ -1205,7 +1220,7 @@ void tst_QImageReader::devicePosition()
|
||||
QVERIFY(!expected.isNull());
|
||||
|
||||
QFile imageFile(prefix + fileName);
|
||||
QVERIFY(imageFile.open(QFile::ReadOnly));
|
||||
QVERIFY2(imageFile.open(QFile::ReadOnly), msgFileOpenReadFailed(imageFile).constData());
|
||||
QByteArray imageData = imageFile.readAll();
|
||||
QVERIFY(!imageData.isNull());
|
||||
int imageDataSize = imageData.size();
|
||||
|
@ -89,6 +89,7 @@ private slots:
|
||||
|
||||
void saveToTemporaryFile();
|
||||
private:
|
||||
QTemporaryDir m_temporaryDir;
|
||||
QString prefix;
|
||||
QString writePrefix;
|
||||
};
|
||||
@ -112,14 +113,11 @@ static void initializePadding(QImage *image)
|
||||
|
||||
void tst_QImageWriter::initTestCase()
|
||||
{
|
||||
QVERIFY(m_temporaryDir.isValid());
|
||||
prefix = QFINDTESTDATA("images/");
|
||||
if (prefix.isEmpty())
|
||||
QFAIL("Can't find images directory!");
|
||||
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_NO_SDK)
|
||||
writePrefix = QDir::homePath();
|
||||
#else
|
||||
writePrefix = prefix;
|
||||
#endif
|
||||
writePrefix = m_temporaryDir.path();
|
||||
}
|
||||
|
||||
// Testing get/set functions
|
||||
|
@ -202,8 +202,7 @@ protected Q_SLOTS:
|
||||
void notEnoughData();
|
||||
|
||||
private Q_SLOTS:
|
||||
void init();
|
||||
void cleanup();
|
||||
void cleanup() { cleanupTestData(); }
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
|
||||
@ -487,6 +486,8 @@ private Q_SLOTS:
|
||||
// NOTE: This test must be last!
|
||||
void parentingRepliesToTheApp();
|
||||
private:
|
||||
void cleanupTestData();
|
||||
|
||||
QString testDataDir;
|
||||
bool notEnoughDataForFastSender;
|
||||
};
|
||||
@ -1499,6 +1500,8 @@ void tst_QNetworkReply::initTestCase()
|
||||
echoProcessDir = QFINDTESTDATA("echo");
|
||||
QVERIFY2(!echoProcessDir.isEmpty(), qPrintable(
|
||||
QString::fromLatin1("Couldn't find echo dir starting from %1.").arg(QDir::currentPath())));
|
||||
|
||||
cleanupTestData();
|
||||
}
|
||||
|
||||
void tst_QNetworkReply::cleanupTestCase()
|
||||
@ -1514,12 +1517,7 @@ void tst_QNetworkReply::cleanupTestCase()
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QNetworkReply::init()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void tst_QNetworkReply::cleanup()
|
||||
void tst_QNetworkReply::cleanupTestData()
|
||||
{
|
||||
QFile file(testFileName);
|
||||
QVERIFY(!file.exists() || file.remove());
|
||||
|
5
tests/auto/tools/qmake/testdata/.gitignore
vendored
Normal file
5
tests/auto/tools/qmake/testdata/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# Created by various tests, even for shadow builds:
|
||||
/pro_file_cache/include.pri
|
||||
/quotedfilenames/cpp folder/
|
||||
/quotedfilenames/quotedfilenames
|
||||
/resources/resources
|
@ -1,3 +1,3 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS = allcursors grab_override
|
||||
SUBDIRS = allcursors grab_override qcursorhighdpi
|
||||
|
321
tests/manual/qcursor/qcursorhighdpi/main.cpp
Normal file
321
tests/manual/qcursor/qcursorhighdpi/main.cpp
Normal file
@ -0,0 +1,321 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the test suite of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL21$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see http://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** As a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QDesktopWidget>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QMainWindow>
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QSharedPointer>
|
||||
#include <QToolBar>
|
||||
|
||||
#include <QBitmap>
|
||||
#include <QCursor>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QStringList>
|
||||
#include <QTextStream>
|
||||
|
||||
#if QT_VERSION > 0x050000
|
||||
# include <QScreen>
|
||||
# include <QWindow>
|
||||
# include <private/qhighdpiscaling_p.h>
|
||||
# include <qpa/qplatformwindow.h>
|
||||
#else
|
||||
# define Q_NULLPTR 0
|
||||
# define Q_DECL_OVERRIDE
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
# include <qt_windows.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
// High DPI cursor test for testing cursor sizes in multi-screen setups.
|
||||
// It creates one widget per screen with a grid of standard cursors,
|
||||
// pixmap / bitmap cursors and pixmap / bitmap cursors with device pixel ratio 2.
|
||||
// On the left, there is a ruler with 10 DIP marks.
|
||||
// The code is meant to compile with Qt 4 also.
|
||||
|
||||
static QString screenInfo(const QWidget *w)
|
||||
{
|
||||
QString result;
|
||||
QTextStream str(&result);
|
||||
#if QT_VERSION > 0x050000
|
||||
QScreen *screen = Q_NULLPTR;
|
||||
if (const QWindow *window = w->windowHandle())
|
||||
screen = window->screen();
|
||||
if (screen) {
|
||||
str << '"' << screen->name() << "\" " << screen->size().width() << 'x'
|
||||
<< screen->size().height() << ", DPR=" << screen->devicePixelRatio()
|
||||
<< ", " << screen->logicalDotsPerInchX() << "DPI ";
|
||||
if (QHighDpiScaling::isActive())
|
||||
str << ", factor=" << QHighDpiScaling::factor(screen);
|
||||
else
|
||||
str << ", no scaling";
|
||||
} else {
|
||||
str << "<null>";
|
||||
}
|
||||
#else
|
||||
QDesktopWidget *desktop = QApplication::desktop();
|
||||
int screenNumber = desktop->screenNumber(w);
|
||||
str << "Screen #" <<screenNumber << ' ' << desktop->screenGeometry(screenNumber).width()
|
||||
<< 'x' << desktop->screenGeometry(screenNumber).height() << " PD: " << w->logicalDpiX() << "DPI";
|
||||
#endif
|
||||
#ifdef Q_OS_WIN
|
||||
str << ", SM_C_CURSOR: " << GetSystemMetrics(SM_CXCURSOR) << 'x' << GetSystemMetrics(SM_CYCURSOR);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
// Helpers for painting pixmaps and creating cursors
|
||||
static QPixmap paintPixmap(int size, QColor c)
|
||||
{
|
||||
QPixmap result(size, size);
|
||||
result.fill(c);
|
||||
QPainter p(&result);
|
||||
p.drawRect(QRect(QPoint(0, 0), result.size() - QSize(1, 1)));
|
||||
p.drawLine(0, 0, size, size);
|
||||
p.drawLine(0, size, size, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
static QCursor pixmapCursor(int size)
|
||||
{
|
||||
QCursor result(paintPixmap(size, Qt::red), size / 2, size / 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
static QPair<QBitmap, QBitmap> paintBitmaps(int size)
|
||||
{
|
||||
QBitmap bitmap(size, size);
|
||||
bitmap.fill(Qt::color1);
|
||||
QBitmap mask(size, size);
|
||||
mask.fill(Qt::color1);
|
||||
{
|
||||
QPainter mp(&mask);
|
||||
mp.fillRect(QRect(0, 0, size / 2, size / 2), Qt::color0);
|
||||
}
|
||||
return QPair<QBitmap, QBitmap>(bitmap, mask);
|
||||
}
|
||||
|
||||
static QCursor bitmapCursor(int size)
|
||||
{
|
||||
QPair<QBitmap, QBitmap> bitmaps = paintBitmaps(size);
|
||||
return QCursor(bitmaps.first, bitmaps.second, size / 2, size / 2);
|
||||
}
|
||||
|
||||
#if QT_VERSION > 0x050000
|
||||
static QCursor pixmapCursorDevicePixelRatio(int size, int dpr)
|
||||
{
|
||||
QPixmap pixmap = paintPixmap(dpr * size, Qt::yellow);
|
||||
pixmap.setDevicePixelRatio(dpr);
|
||||
return QCursor(pixmap, size / 2, size / 2);
|
||||
}
|
||||
|
||||
static QCursor bitmapCursorDevicePixelRatio(int size, int dpr)
|
||||
{
|
||||
QPair<QBitmap, QBitmap> bitmaps = paintBitmaps(dpr * size);
|
||||
bitmaps.first.setDevicePixelRatio(dpr);
|
||||
bitmaps.second.setDevicePixelRatio(dpr);
|
||||
return QCursor(bitmaps.first, bitmaps.second, size / 2, size / 2);
|
||||
}
|
||||
#endif // Qt 5
|
||||
|
||||
// Vertical ruler widget with 10 px marks
|
||||
class VerticalRuler : public QWidget {
|
||||
public:
|
||||
VerticalRuler(QWidget *parent = Q_NULLPTR);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
|
||||
};
|
||||
|
||||
VerticalRuler::VerticalRuler(QWidget *parent) : QWidget(parent)
|
||||
{
|
||||
const int screenWidth = QApplication::desktop()->screenGeometry(this).width();
|
||||
setFixedWidth(screenWidth / 48); // 1920 pixel monitor ->40
|
||||
}
|
||||
|
||||
void VerticalRuler::paintEvent(QPaintEvent *)
|
||||
{
|
||||
const QSize sizeS(size());
|
||||
const QPoint sizeP(sizeS.width(), sizeS.height());
|
||||
const QPoint center = sizeP / 2;
|
||||
QPainter painter(this);
|
||||
painter.fillRect(QRect(QPoint(0, 0), sizeS), Qt::white);
|
||||
painter.drawLine(center.x(), 0, center.x(), sizeP.y());
|
||||
for (int y = 0; y < sizeP.y(); y += 10)
|
||||
painter.drawLine(center.x() - 5, y, center.x() + 5, y);
|
||||
}
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainWindow(QWidget *parent = Q_NULLPTR);
|
||||
void updateScreenInfo() { m_screenInfoLabel->setText(screenInfo(this)); }
|
||||
|
||||
public slots:
|
||||
void screenChanged() { updateScreenInfo(); }
|
||||
|
||||
private:
|
||||
QLabel *m_screenInfoLabel;
|
||||
};
|
||||
|
||||
static QLabel *createCursorLabel(const QCursor &cursor, const QString &additionalText = QString())
|
||||
{
|
||||
QString labelText;
|
||||
QDebug(&labelText).nospace() << cursor.shape();
|
||||
#if QT_VERSION > 0x050000
|
||||
labelText.remove(0, labelText.indexOf('(') + 1);
|
||||
labelText.chop(1);
|
||||
#endif // Qt 5
|
||||
if (!additionalText.isEmpty())
|
||||
labelText += ' ' + additionalText;
|
||||
QLabel *result = new QLabel(labelText);
|
||||
result->setFrameShape(QFrame::Box);
|
||||
result->setCursor(cursor);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void addToGrid(QWidget *w, QGridLayout *gridLayout, int columnCount, int &row, int &col)
|
||||
{
|
||||
gridLayout->addWidget(w, row, col);
|
||||
if (col >= columnCount) {
|
||||
col = 0;
|
||||
row++;
|
||||
} else {
|
||||
col++;
|
||||
}
|
||||
}
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, m_screenInfoLabel(new QLabel)
|
||||
{
|
||||
QString title = "Cursors ";
|
||||
#if QT_VERSION > 0x050000
|
||||
title += '(' + QGuiApplication::platformName() + ") ";
|
||||
#endif
|
||||
title += QT_VERSION_STR;
|
||||
setWindowTitle(title);
|
||||
|
||||
QMenu *fileMenu = menuBar()->addMenu("File");
|
||||
QAction *quitAction = fileMenu->addAction("Quit");
|
||||
quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
|
||||
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
|
||||
|
||||
QToolBar *fileToolBar = addToolBar("File");
|
||||
fileToolBar->addAction(quitAction);
|
||||
|
||||
QWidget *cw = new QWidget;
|
||||
QHBoxLayout *hLayout = new QHBoxLayout(cw);
|
||||
hLayout->addWidget(new VerticalRuler(cw));
|
||||
QGridLayout *gridLayout = new QGridLayout;
|
||||
hLayout->addLayout(gridLayout);
|
||||
|
||||
const int columnCount = 5;
|
||||
const int size = 32;
|
||||
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
for (int i = 0; i < Qt::BitmapCursor; ++i)
|
||||
addToGrid(createCursorLabel(QCursor(static_cast<Qt::CursorShape>(i))), gridLayout, columnCount, row, col);
|
||||
|
||||
addToGrid(createCursorLabel(QCursor(pixmapCursor(size)),
|
||||
QLatin1String("Plain PX ") + QString::number(size)),
|
||||
gridLayout, columnCount, row, col);
|
||||
|
||||
addToGrid(createCursorLabel(bitmapCursor(size),
|
||||
QLatin1String("Plain BM ") + QString::number(size)),
|
||||
gridLayout, columnCount, row, col);
|
||||
|
||||
#if QT_VERSION > 0x050000
|
||||
addToGrid(createCursorLabel(QCursor(pixmapCursorDevicePixelRatio(size, 2)),
|
||||
"PX with DPR 2 " + QString::number(size)),
|
||||
gridLayout, columnCount, row, col);
|
||||
|
||||
addToGrid(createCursorLabel(QCursor(bitmapCursorDevicePixelRatio(size, 2)),
|
||||
"BM with DPR 2 " + QString::number(size)),
|
||||
gridLayout, columnCount, row, col);
|
||||
#endif // Qt 5
|
||||
|
||||
gridLayout->addWidget(m_screenInfoLabel, row + 1, 0, 1, columnCount);
|
||||
|
||||
setCentralWidget(cw);
|
||||
}
|
||||
|
||||
typedef QSharedPointer<MainWindow> MainWindowPtr;
|
||||
typedef QList<MainWindowPtr> MainWindowPtrList;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QStringList arguments;
|
||||
std::copy(argv + 1, argv + argc, std::back_inserter(arguments));
|
||||
|
||||
#if QT_VERSION > 0x050000
|
||||
if (arguments.contains("-s"))
|
||||
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
else if (arguments.contains("-n"))
|
||||
QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling);
|
||||
#endif // Qt 5
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
MainWindowPtrList windows;
|
||||
|
||||
QDesktopWidget *desktopWidget = app.desktop();
|
||||
|
||||
for (int s = desktopWidget->screenCount() - 1; s >= 0; --s) {
|
||||
MainWindowPtr window(new MainWindow(desktopWidget->screen(s)));
|
||||
const QPoint pos = desktopWidget->screenGeometry(s).center() - QPoint(200, 100);
|
||||
window->move(pos);
|
||||
windows.append(window);
|
||||
window->show();
|
||||
window->updateScreenInfo();
|
||||
#if QT_VERSION > 0x050000
|
||||
QObject::connect(window->windowHandle(), &QWindow::screenChanged,
|
||||
window.data(), &MainWindow::updateScreenInfo);
|
||||
#endif
|
||||
}
|
||||
return app.exec();
|
||||
}
|
||||
#include "main.moc"
|
6
tests/manual/qcursor/qcursorhighdpi/qcursorhighdpi.pro
Normal file
6
tests/manual/qcursor/qcursorhighdpi/qcursorhighdpi.pro
Normal file
@ -0,0 +1,6 @@
|
||||
TEMPLATE = app
|
||||
QT = core gui
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += gui-private core-private widgets
|
||||
CONFIG -= app_bundle
|
||||
SOURCES += main.cpp
|
||||
win32: LIBS += -lUser32
|
Loading…
Reference in New Issue
Block a user