summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/sqlite.pri4
-rw-r--r--src/corelib/configure.json19
-rw-r--r--src/corelib/corelib.pro2
-rw-r--r--src/corelib/eval.pri4
-rw-r--r--src/corelib/global/qhooks.cpp2
-rw-r--r--src/corelib/global/qlibraryinfo.cpp5
-rw-r--r--src/corelib/global/qtrace_p.h2
-rw-r--r--src/corelib/kernel/kernel.pri2
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp14
-rw-r--r--src/corelib/kernel/qmetaobject_p.h4
-rw-r--r--src/corelib/kernel/qobject.cpp630
-rw-r--r--src/corelib/kernel/qobject_p.h123
-rw-r--r--src/corelib/kernel/qtcore_eval.cpp560
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp1
-rw-r--r--src/corelib/mimetypes/qmimetypeparser.cpp3
-rw-r--r--src/corelib/serialization/qdatastream.cpp1
-rw-r--r--src/corelib/serialization/qdatastream.h5
-rw-r--r--src/corelib/thread/qorderedmutexlocker_p.h62
-rw-r--r--src/corelib/tools/qbytearray.cpp3
-rw-r--r--src/corelib/tools/qcollator.cpp116
-rw-r--r--src/corelib/tools/qcollator.h6
-rw-r--r--src/corelib/tools/qcollator_icu.cpp41
-rw-r--r--src/corelib/tools/qcollator_macx.cpp46
-rw-r--r--src/corelib/tools/qcollator_posix.cpp14
-rw-r--r--src/corelib/tools/qcollator_win.cpp34
-rw-r--r--src/corelib/tools/qline.cpp2
-rw-r--r--src/corelib/tools/qline.h3
-rw-r--r--src/corelib/tools/qstring.cpp6
-rw-r--r--src/corelib/tools/qstring.h23
-rw-r--r--src/corelib/tools/qstringview.cpp31
-rw-r--r--src/corelib/tools/qstringview.h2
-rw-r--r--src/gui/configure.json26
-rw-r--r--src/gui/image/qimage.cpp134
-rw-r--r--src/gui/image/qimage.h10
-rw-r--r--src/gui/image/qimage_conversions.cpp4
-rw-r--r--src/gui/image/qimage_p.h4
-rw-r--r--src/gui/image/qpnghandler.cpp72
-rw-r--r--src/gui/kernel/kernel.pri2
-rw-r--r--src/gui/kernel/qguiapplication.cpp30
-rw-r--r--src/gui/kernel/qguiapplication_p.h11
-rw-r--r--src/gui/opengl/qopengles2ext.h442
-rw-r--r--src/gui/opengl/qopenglext.h555
-rw-r--r--src/gui/opengl/qopengltexture.cpp234
-rw-r--r--src/gui/opengl/qopengltexture.h26
-rw-r--r--src/gui/opengl/qopengltexture_p.h4
-rw-r--r--src/gui/painting/painting.pri16
-rw-r--r--src/gui/painting/qcolormatrix_p.h214
-rw-r--r--src/gui/painting/qcolorspace.cpp633
-rw-r--r--src/gui/painting/qcolorspace.h136
-rw-r--r--src/gui/painting/qcolorspace_p.h (renamed from src/plugins/platforms/mirclient/qmirclientclipboard.h)86
-rw-r--r--src/gui/painting/qcolortransferfunction_p.h207
-rw-r--r--src/gui/painting/qcolortransfertable_p.h245
-rw-r--r--src/gui/painting/qcolortransform.cpp679
-rw-r--r--src/gui/painting/qcolortransform.h (renamed from src/plugins/platforms/mirclient/qmirclientscreenobserver.h)71
-rw-r--r--src/gui/painting/qcolortransform_p.h (renamed from src/plugins/platforms/mirclient/qmirclientbackingstore.h)67
-rw-r--r--src/gui/painting/qcolortrc_p.h129
-rw-r--r--src/gui/painting/qcolortrclut.cpp (renamed from src/gui/painting/qcolorprofile.cpp)41
-rw-r--r--src/gui/painting/qcolortrclut_p.h (renamed from src/gui/painting/qcolorprofile_p.h)72
-rw-r--r--src/gui/painting/qdrawhelper.cpp22
-rw-r--r--src/gui/painting/qicc.cpp669
-rw-r--r--src/gui/painting/qicc_p.h (renamed from src/plugins/platforms/mirclient/qmirclientdebugextension.h)43
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp76
-rw-r--r--src/gui/painting/qpaintengine_raster_p.h20
-rw-r--r--src/gui/painting/qpainter_p.h2
-rw-r--r--src/gui/painting/qpdf.cpp12
-rw-r--r--src/gui/painting/qpdfwriter.cpp10
-rw-r--r--src/gui/painting/qpdfwriter.h6
-rw-r--r--src/gui/painting/qstroker.cpp9
-rw-r--r--src/gui/text/qfont.cpp99
-rw-r--r--src/gui/text/qfont.h6
-rw-r--r--src/gui/util/qvalidator.h1
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp13
-rw-r--r--src/network/access/qhttpnetworkreply.cpp3
-rw-r--r--src/network/configure.json30
-rw-r--r--src/network/kernel/kernel.pri2
-rw-r--r--src/network/kernel/qauthenticator.cpp406
-rw-r--r--src/network/kernel/qauthenticator_p.h17
-rw-r--r--src/network/socket/qhttpsocketengine.cpp2
-rw-r--r--src/network/ssl/qsslcontext_openssl11.cpp2
-rw-r--r--src/network/ssl/qsslkey_mac.cpp22
-rw-r--r--src/network/ssl/qsslkey_openssl.cpp8
-rw-r--r--src/network/ssl/qsslkey_p.h5
-rw-r--r--src/network/ssl/qsslkey_qt.cpp48
-rw-r--r--src/network/ssl/qsslkey_schannel.cpp1
-rw-r--r--src/network/ssl/qsslsocket.cpp17
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp3
-rw-r--r--src/network/ssl/qsslsocket_openssl11_symbols_p.h1
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp4
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h7
-rw-r--r--src/platformsupport/eglconvenience/qeglstreamconvenience_p.h11
-rw-r--r--src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp324
-rw-r--r--src/platformsupport/kmsconvenience/qkmsdevice.cpp4
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes.cpp12
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp14
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp50
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h2
-rw-r--r--src/plugins/platforms/mirclient/mirclient.json3
-rw-r--r--src/plugins/platforms/mirclient/mirclient.pro61
-rw-r--r--src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp102
-rw-r--r--src/plugins/platforms/mirclient/qmirclientappstatecontroller.h62
-rw-r--r--src/plugins/platforms/mirclient/qmirclientbackingstore.cpp157
-rw-r--r--src/plugins/platforms/mirclient/qmirclientclipboard.cpp181
-rw-r--r--src/plugins/platforms/mirclient/qmirclientcursor.cpp209
-rw-r--r--src/plugins/platforms/mirclient/qmirclientcursor.h64
-rw-r--r--src/plugins/platforms/mirclient/qmirclientdebugextension.cpp79
-rw-r--r--src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp50
-rw-r--r--src/plugins/platforms/mirclient/qmirclientdesktopwindow.h53
-rw-r--r--src/plugins/platforms/mirclient/qmirclientglcontext.cpp132
-rw-r--r--src/plugins/platforms/mirclient/qmirclientglcontext.h63
-rw-r--r--src/plugins/platforms/mirclient/qmirclientinput.cpp708
-rw-r--r--src/plugins/platforms/mirclient/qmirclientinput.h86
-rw-r--r--src/plugins/platforms/mirclient/qmirclientintegration.cpp411
-rw-r--r--src/plugins/platforms/mirclient/qmirclientintegration.h131
-rw-r--r--src/plugins/platforms/mirclient/qmirclientlogging.h55
-rw-r--r--src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp217
-rw-r--r--src/plugins/platforms/mirclient/qmirclientnativeinterface.h83
-rw-r--r--src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h61
-rw-r--r--src/plugins/platforms/mirclient/qmirclientplatformservices.cpp75
-rw-r--r--src/plugins/platforms/mirclient/qmirclientplatformservices.h57
-rw-r--r--src/plugins/platforms/mirclient/qmirclientplugin.cpp56
-rw-r--r--src/plugins/platforms/mirclient/qmirclientplugin.h56
-rw-r--r--src/plugins/platforms/mirclient/qmirclientscreen.cpp262
-rw-r--r--src/plugins/platforms/mirclient/qmirclientscreen.h106
-rw-r--r--src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp161
-rw-r--r--src/plugins/platforms/mirclient/qmirclienttheme.cpp67
-rw-r--r--src/plugins/platforms/mirclient/qmirclienttheme.h57
-rw-r--r--src/plugins/platforms/mirclient/qmirclientwindow.cpp968
-rw-r--r--src/plugins/platforms/mirclient/qmirclientwindow.h118
-rw-r--r--src/plugins/platforms/platforms.pro2
-rw-r--r--src/printsupport/dialogs/qpagesetupdialog_unix.cpp26
-rw-r--r--src/printsupport/dialogs/qprintpreviewdialog.cpp14
-rw-r--r--src/testlib/qsignaldumper.cpp5
-rw-r--r--src/testlib/qtestcase.cpp42
-rw-r--r--src/tools/bootstrap/bootstrap.pro2
-rw-r--r--src/tools/moc/moc.cpp54
-rw-r--r--src/tools/moc/moc.h3
-rw-r--r--src/tools/qvkgen/qvkgen.cpp45
-rw-r--r--src/tools/rcc/main.cpp19
-rw-r--r--src/tools/rcc/rcc.cpp201
-rw-r--r--src/tools/rcc/rcc.h3
-rw-r--r--src/widgets/dialogs/qdialog.cpp11
-rw-r--r--src/widgets/doc/snippets/timeline/main.cpp4
-rw-r--r--src/widgets/graphicsview/qgraphicsitemanimation.cpp33
-rw-r--r--src/widgets/graphicsview/qgraphicsitemanimation.h5
-rw-r--r--src/widgets/kernel/qapplication.cpp4
-rw-r--r--src/widgets/kernel/qformlayout.cpp2
-rw-r--r--src/widgets/kernel/qwidget.cpp11
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp6
-rw-r--r--src/widgets/kernel/qwidgetbackingstore_p.h1
-rw-r--r--src/widgets/styles/qstyle.h7
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp5
-rw-r--r--src/widgets/widgets.pro2
-rw-r--r--src/widgets/widgets/qabstractspinbox.cpp14
-rw-r--r--src/widgets/widgets/qcombobox.cpp12
-rw-r--r--src/widgets/widgets/qcombobox.h12
-rw-r--r--src/widgets/widgets/qdialogbuttonbox.cpp13
-rw-r--r--src/widgets/widgets/qlineedit.cpp12
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp7
-rw-r--r--src/widgets/widgets/qlineedit_p.h4
-rw-r--r--src/widgets/widgets/qmdiarea.cpp4
-rw-r--r--src/widgets/widgets/qspinbox.cpp47
-rw-r--r--src/widgets/widgets/qspinbox.h8
162 files changed, 6416 insertions, 7078 deletions
diff --git a/src/3rdparty/sqlite.pri b/src/3rdparty/sqlite.pri
index 068764c726..6405beb3d0 100644
--- a/src/3rdparty/sqlite.pri
+++ b/src/3rdparty/sqlite.pri
@@ -1,5 +1,6 @@
CONFIG(release, debug|release):DEFINES *= NDEBUG
-DEFINES += SQLITE_ENABLE_COLUMN_METADATA SQLITE_OMIT_LOAD_EXTENSION SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_FTS5 SQLITE_ENABLE_RTREE SQLITE_ENABLE_JSON1
+QT_FOR_CONFIG += core-private
+DEFINES += SQLITE_ENABLE_COLUMN_METADATA SQLITE_OMIT_COMPLETE SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_ENABLE_FTS5 SQLITE_ENABLE_RTREE SQLITE_ENABLE_JSON1
!contains(CONFIG, largefile):DEFINES += SQLITE_DISABLE_LFS
qtConfig(posix_fallocate): DEFINES += HAVE_POSIX_FALLOCATE=1
winrt {
@@ -8,6 +9,7 @@ winrt {
}
qnx: DEFINES += _QNX_SOURCE
!win32:!winrt:!winphone: DEFINES += HAVE_USLEEP=1
+qtConfig(dlopen): QMAKE_USE += libdl
integrity: QMAKE_CFLAGS += -include qplatformdefs.h
INCLUDEPATH += $$PWD/sqlite
SOURCES += $$PWD/sqlite/sqlite3.c
diff --git a/src/corelib/configure.json b/src/corelib/configure.json
index 948aa0829b..81768507f6 100644
--- a/src/corelib/configure.json
+++ b/src/corelib/configure.json
@@ -11,7 +11,7 @@
"icu": "boolean",
"inotify": "boolean",
"journald": "boolean",
- "pcre": { "type": "enum", "values": [ "qt", "system" ] },
+ "pcre": { "type": "enum", "values": [ "no", "qt", "system" ] },
"posix-ipc": { "type": "boolean", "name": "ipc_posix" },
"pps": { "type": "boolean", "name": "qqnx_pps" },
"slog2": "boolean",
@@ -662,15 +662,18 @@
"condition": "features.textcodec",
"output": [ "publicFeature", "feature" ]
},
+ "pcre2": {
+ "label": "PCRE2",
+ "disable": "input.pcre == 'no' || input.pcre == 'system'",
+ "enable": "input.pcre == 'qt'",
+ "output": [ "privateConfig" ]
+ },
"system-pcre2": {
- "label": "Using system PCRE2",
- "disable": "input.pcre == 'qt'",
+ "label": " Using system PCRE2",
+ "disable": "input.pcre == 'no' || input.pcre == 'qt'",
"enable": "input.pcre == 'system'",
"condition": "libs.pcre2",
- "output": [
- "privateFeature",
- { "type": "privateConfig", "negative": true, "name": "pcre2" }
- ]
+ "output": [ "privateFeature" ]
},
"poll_ppoll": {
"label": "Native ppoll()",
@@ -749,6 +752,7 @@
"label": "QRegularExpression",
"purpose": "Provides an API to Perl-compatible regular expressions.",
"section": "Kernel",
+ "condition": "features.system-pcre2 || features.pcre2",
"output": [ "publicFeature", "feature" ]
},
"sharedmemory": {
@@ -1048,6 +1052,7 @@ Please apply the patch corresponding to your Standard Library vendor, found in
"args": "qqnx_pps",
"condition": "config.qnx"
},
+ "pcre2",
"system-pcre2"
]
}
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 4b758532e6..dc43e56836 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -68,8 +68,6 @@ integrity {
QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtCore.dynlist
-contains(DEFINES,QT_EVAL):include(eval.pri)
-
HOST_BINS = $$[QT_HOST_BINS]
host_bins.name = host_bins
host_bins.variable = HOST_BINS
diff --git a/src/corelib/eval.pri b/src/corelib/eval.pri
deleted file mode 100644
index efda56b16a..0000000000
--- a/src/corelib/eval.pri
+++ /dev/null
@@ -1,4 +0,0 @@
-SOURCES += \
- $$QT_SOURCE_TREE/src/corelib/kernel/qtcore_eval.cpp
-INCLUDEPATH += \
- $$QT_BUILD_TREE/src/corelib/global
diff --git a/src/corelib/global/qhooks.cpp b/src/corelib/global/qhooks.cpp
index bbddb1cbf1..020dee3710 100644
--- a/src/corelib/global/qhooks.cpp
+++ b/src/corelib/global/qhooks.cpp
@@ -67,7 +67,7 @@ quintptr Q_CORE_EXPORT qtHookData[] = {
// The required sizes and offsets are tested in tests/auto/other/toolsupport.
// When this fails and the change was intentional, adjust the test and
// adjust this value here.
- 16
+ 17
};
Q_STATIC_ASSERT(QHooks::LastHookIndex == sizeof(qtHookData) / sizeof(qtHookData[0]));
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 4119012d85..88cc5b0b01 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -717,11 +717,6 @@ void qt_core_boilerplate()
QT_PREPEND_NAMESPACE(qDumpCPUFeatures)();
-#ifdef QT_EVAL
- extern void qt_core_eval_init(QCoreApplicationPrivate::Type);
- qt_core_eval_init(QCoreApplicationPrivate::Tty);
-#endif
-
exit(0);
}
diff --git a/src/corelib/global/qtrace_p.h b/src/corelib/global/qtrace_p.h
index 3d04a7311d..56d1f9a318 100644
--- a/src/corelib/global/qtrace_p.h
+++ b/src/corelib/global/qtrace_p.h
@@ -114,10 +114,12 @@
QT_BEGIN_NAMESPACE
#if defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED)
+# define Q_HAS_TRACEPOINTS 1
# define Q_TRACE(x, ...) QtPrivate::trace_ ## x(__VA_ARGS__)
# define Q_UNCONDITIONAL_TRACE(x, ...) QtPrivate::do_trace_ ## x(__VA_ARGS__)
# define Q_TRACE_ENABLED(x) QtPrivate::trace_ ## x ## _enabled()
#else
+# define Q_HAS_TRACEPOINTS 0
# define Q_TRACE(x, ...)
# define Q_UNCONDITIONAL_TRACE(x, ...)
# define Q_TRACE_ENABLED(x) false
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri
index 3f7bf3cd47..789bcb7927 100644
--- a/src/corelib/kernel/kernel.pri
+++ b/src/corelib/kernel/kernel.pri
@@ -7,7 +7,7 @@ HEADERS += \
kernel/qdeadlinetimer.h \
kernel/qdeadlinetimer_p.h \
kernel/qelapsedtimer.h \
- kernel/qeventloop.h\
+ kernel/qeventloop.h \
kernel/qpointer.h \
kernel/qcorecmdlineargs_p.h \
kernel/qcoreapplication.h \
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index c06af79cc7..5da33a5aae 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -256,15 +256,6 @@ void QCoreApplicationPrivate::processCommandLineArguments()
// Support for introspection
-#ifndef QT_NO_QOBJECT
-QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set = { 0, 0, 0, 0 };
-
-void qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set)
-{
- qt_signal_spy_callback_set = callback_set;
-}
-#endif
-
extern "C" void Q_CORE_EXPORT qt_startup_hook()
{
}
@@ -866,11 +857,6 @@ void QCoreApplicationPrivate::init()
eventDispatcherReady();
#endif
-#ifdef QT_EVAL
- extern void qt_core_eval_init(QCoreApplicationPrivate::Type);
- qt_core_eval_init(application_type);
-#endif
-
processCommandLineArguments();
qt_call_pre_routines();
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index 522bd78e42..5b412b5140 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -54,6 +54,7 @@
#include <QtCore/qglobal.h>
#include <QtCore/qobjectdefs.h>
+#include <QtCore/qmutex.h>
#ifndef QT_NO_QOBJECT
#include <private/qobject_p.h> // For QObjectPrivate::Connection
#endif
@@ -168,7 +169,6 @@ Q_DECLARE_TYPEINFO(QArgumentType, Q_MOVABLE_TYPE);
typedef QVarLengthArray<QArgumentType, 10> QArgumentTypeArray;
class QMetaMethodPrivate;
-class QMutex;
struct QMetaObjectPrivate
{
@@ -234,7 +234,7 @@ struct QMetaObjectPrivate
DisconnectType = DisconnectAll);
static inline bool disconnectHelper(QObjectPrivate::Connection *c,
const QObject *receiver, int method_index, void **slot,
- QMutex *senderMutex, DisconnectType = DisconnectAll);
+ QBasicMutex *senderMutex, DisconnectType = DisconnectAll);
#endif
};
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 15955e1665..759ccaacd8 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -77,6 +77,12 @@ QT_BEGIN_NAMESPACE
static int DIRECT_CONNECTION_ONLY = 0;
+Q_CORE_EXPORT QBasicAtomicPointer<QSignalSpyCallbackSet> qt_signal_spy_callback_set = Q_BASIC_ATOMIC_INITIALIZER(nullptr);
+
+void qt_register_signal_spy_callbacks(QSignalSpyCallbackSet *callback_set)
+{
+ qt_signal_spy_callback_set.store(callback_set);
+}
QDynamicMetaObjectData::~QDynamicMetaObjectData()
{
@@ -146,10 +152,9 @@ static QBasicMutex _q_ObjectMutexPool[131];
* \internal
* mutex to be locked when accessing the connectionlists or the senders list
*/
-static inline QMutex *signalSlotLock(const QObject *o)
+static inline QBasicMutex *signalSlotLock(const QObject *o)
{
- return static_cast<QMutex *>(&_q_ObjectMutexPool[
- uint(quintptr(o)) % sizeof(_q_ObjectMutexPool)/sizeof(QBasicMutex)]);
+ return &_q_ObjectMutexPool[uint(quintptr(o)) % sizeof(_q_ObjectMutexPool)/sizeof(QBasicMutex)];
}
#if QT_VERSION < 0x60000
@@ -160,39 +165,6 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
{}
#endif
-struct QConnectionSenderSwitcher {
- QObject *receiver;
- QObjectPrivate::Sender *previousSender;
- QObjectPrivate::Sender currentSender;
- bool switched;
-
- inline QConnectionSenderSwitcher() : switched(false) {}
-
- inline QConnectionSenderSwitcher(QObject *receiver, QObject *sender, int signal_absolute_id)
- {
- switchSender(receiver, sender, signal_absolute_id);
- }
-
- inline void switchSender(QObject *receiver, QObject *sender, int signal_absolute_id)
- {
- this->receiver = receiver;
- currentSender.sender = sender;
- currentSender.signal = signal_absolute_id;
- currentSender.ref = 1;
- previousSender = QObjectPrivate::setCurrentSender(receiver, &currentSender);
- switched = true;
- }
-
- inline ~QConnectionSenderSwitcher()
- {
- if (switched)
- QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);
- }
-private:
- Q_DISABLE_COPY(QConnectionSenderSwitcher)
-};
-
-
void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0;
void (*QAbstractDeclarativeData::destroyed_qml1)(QAbstractDeclarativeData *, QObject *) = 0;
void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0;
@@ -209,7 +181,7 @@ QMetaObject *QObjectData::dynamicMetaObject() const
}
QObjectPrivate::QObjectPrivate(int version)
- : threadData(0), connectionLists(0), senders(0), currentSender(0), currentChildBeingDeleted(0)
+ : threadData(0), currentChildBeingDeleted(0)
{
#ifdef QT_BUILD_INTERNAL
// Don't check the version parameter in internal builds.
@@ -232,7 +204,6 @@ QObjectPrivate::QObjectPrivate(int version)
receiveChildEvents = true;
postedEvents = 0;
extraData = 0;
- connectedSignals[0] = connectedSignals[1] = 0;
metaObject = 0;
isWindow = false;
deleteLaterCalled = false;
@@ -285,59 +256,22 @@ static void computeOffsets(const QMetaObject *metaobject, int *signalOffset, int
}
}
-/*
- This vector contains the all connections from an object.
-
- Each object may have one vector containing the lists of
- connections for a given signal. The index in the vector correspond
- to the signal index. The signal index is the one returned by
- QObjectPrivate::signalIndex (not QMetaObject::indexOfSignal).
- Negative index means connections to all signals.
-
- This vector is protected by the object mutex (signalSlotMutexes())
-
- Each Connection is also part of a 'senders' linked list. The mutex
- of the receiver must be locked when touching the pointers of this
- linked list.
-*/
-class QObjectConnectionListVector : public QVector<QObjectPrivate::ConnectionList>
-{
-public:
- bool orphaned; //the QObject owner of this vector has been destroyed while the vector was inUse
- bool dirty; //some Connection have been disconnected (their receiver is 0) but not removed from the list yet
- int inUse; //number of functions that are currently accessing this object or its connections
- QObjectPrivate::ConnectionList allsignals;
-
- QObjectConnectionListVector()
- : QVector<QObjectPrivate::ConnectionList>(), orphaned(false), dirty(false), inUse(0)
- { }
-
- QObjectPrivate::ConnectionList &operator[](int at)
- {
- if (at < 0)
- return allsignals;
- return QVector<QObjectPrivate::ConnectionList>::operator[](at);
- }
-};
-
// Used by QAccessibleWidget
bool QObjectPrivate::isSender(const QObject *receiver, const char *signal) const
{
Q_Q(const QObject);
int signal_index = signalIndex(signal);
- if (signal_index < 0)
+ ConnectionData *cd = connections.load();
+ if (signal_index < 0 || !cd)
return false;
- QMutexLocker locker(signalSlotLock(q));
- if (connectionLists) {
- if (signal_index < connectionLists->count()) {
- const QObjectPrivate::Connection *c =
- connectionLists->at(signal_index).first;
-
- while (c) {
- if (c->receiver == receiver)
- return true;
- c = c->nextConnectionList;
- }
+ QBasicMutexLocker locker(signalSlotLock(q));
+ if (signal_index < cd->signalVector.count()) {
+ const QObjectPrivate::Connection *c = cd->signalVector.at(signal_index).first;
+
+ while (c) {
+ if (c->receiver == receiver)
+ return true;
+ c = c->nextConnectionList;
}
}
return false;
@@ -349,18 +283,17 @@ QObjectList QObjectPrivate::receiverList(const char *signal) const
Q_Q(const QObject);
QObjectList returnValue;
int signal_index = signalIndex(signal);
- if (signal_index < 0)
+ ConnectionData *cd = connections.load();
+ if (signal_index < 0 || !cd)
return returnValue;
- QMutexLocker locker(signalSlotLock(q));
- if (connectionLists) {
- if (signal_index < connectionLists->count()) {
- const QObjectPrivate::Connection *c = connectionLists->at(signal_index).first;
-
- while (c) {
- if (c->receiver)
- returnValue << c->receiver;
- c = c->nextConnectionList;
- }
+ QBasicMutexLocker locker(signalSlotLock(q));
+ if (signal_index < cd->signalVector.count()) {
+ const QObjectPrivate::Connection *c = cd->signalVector.at(signal_index).first;
+
+ while (c) {
+ if (c->receiver)
+ returnValue << c->receiver;
+ c = c->nextConnectionList;
}
}
return returnValue;
@@ -370,9 +303,12 @@ QObjectList QObjectPrivate::receiverList(const char *signal) const
QObjectList QObjectPrivate::senderList() const
{
QObjectList returnValue;
- QMutexLocker locker(signalSlotLock(q_func()));
- for (Connection *c = senders; c; c = c->next)
- returnValue << c->sender;
+ ConnectionData *cd = connections.load();
+ if (cd) {
+ QBasicMutexLocker locker(signalSlotLock(q_func()));
+ for (Connection *c = cd->senders; c; c = c->next)
+ returnValue << c->sender;
+ }
return returnValue;
}
@@ -389,12 +325,12 @@ QObjectList QObjectPrivate::senderList() const
void QObjectPrivate::addConnection(int signal, Connection *c)
{
Q_ASSERT(c->sender == q_ptr);
- if (!connectionLists)
- connectionLists = new QObjectConnectionListVector();
- if (signal >= connectionLists->count())
- connectionLists->resize(signal + 1);
+ ensureConnectionData();
+ ConnectionData *cd = connections.load();
+ if (signal >= cd->signalVector.count())
+ cd->signalVector.resize(signal + 1);
- ConnectionList &connectionList = (*connectionLists)[signal];
+ ConnectionList &connectionList = cd->connectionsForSignal(signal);
if (connectionList.last) {
connectionList.last->nextConnectionList = c;
} else {
@@ -404,27 +340,23 @@ void QObjectPrivate::addConnection(int signal, Connection *c)
cleanConnectionLists();
- c->prev = &(QObjectPrivate::get(c->receiver)->senders);
+ QObjectPrivate *rd = QObjectPrivate::get(c->receiver);
+ rd->ensureConnectionData();
+
+ c->prev = &(rd->connections.load()->senders);
c->next = *c->prev;
*c->prev = c;
if (c->next)
c->next->prev = &c->next;
-
- if (signal < 0) {
- connectedSignals[0] = connectedSignals[1] = ~0;
- } else if (signal < (int)sizeof(connectedSignals) * 8) {
- connectedSignals[signal >> 5] |= (1 << (signal & 0x1f));
- }
}
void QObjectPrivate::cleanConnectionLists()
{
- if (connectionLists->dirty && !connectionLists->inUse) {
+ ConnectionData *cd = connections.load();
+ if (cd->dirty && cd->ref == 1) {
// remove broken connections
- bool allConnected = false;
- for (int signal = -1; signal < connectionLists->count(); ++signal) {
- QObjectPrivate::ConnectionList &connectionList =
- (*connectionLists)[signal];
+ for (int signal = -1; signal < cd->signalVector.count(); ++signal) {
+ ConnectionList &connectionList = cd->connectionsForSignal(signal);
// Set to the last entry in the connection list that was *not*
// deleted. This is needed to update the list's last pointer
@@ -433,13 +365,11 @@ void QObjectPrivate::cleanConnectionLists()
QObjectPrivate::Connection **prev = &connectionList.first;
QObjectPrivate::Connection *c = *prev;
- bool connected = false; // whether the signal is still connected somewhere
while (c) {
if (c->receiver) {
last = c;
prev = &c->nextConnectionList;
c = *prev;
- connected = true;
} else {
QObjectPrivate::Connection *next = c->nextConnectionList;
*prev = next;
@@ -451,19 +381,41 @@ void QObjectPrivate::cleanConnectionLists()
// Correct the connection list's last pointer.
// As conectionList.last could equal last, this could be a noop
connectionList.last = last;
+ }
+ cd->dirty = false;
+ }
+}
- if (!allConnected && !connected && signal >= 0
- && size_t(signal) < sizeof(connectedSignals) * 8) {
- // This signal is no longer connected
- connectedSignals[signal >> 5] &= ~(1 << (signal & 0x1f));
- } else if (signal == -1) {
- allConnected = connected;
- }
+/*! \internal
+
+ Returns \c true if the signal with index \a signal_index from object \a sender is connected.
+
+ \a signal_index must be the index returned by QObjectPrivate::signalIndex;
+*/
+bool QObjectPrivate::isSignalConnected(uint signalIndex, bool checkDeclarative) const
+{
+ if (checkDeclarative && isDeclarativeSignalConnected(signalIndex))
+ return true;
+
+ ConnectionData *cd = connections.load();
+ if (!cd)
+ return false;
+
+ if (cd->allsignals.first)
+ return true;
+
+ if (signalIndex < uint(cd->signalVector.count())) {
+ const QObjectPrivate::Connection *c = cd->signalVector.at(signalIndex).first;
+ while (c) {
+ if (c->receiver)
+ return true;
+ c = c->nextConnectionList;
}
- connectionLists->dirty = false;
}
+ return false;
}
+
/*!
\internal
*/
@@ -921,60 +873,50 @@ QObject::~QObject()
}
}
- // set ref to zero to indicate that this object has been deleted
- if (d->currentSender != 0)
- d->currentSender->ref = 0;
- d->currentSender = 0;
+ QObjectPrivate::ConnectionData *cd = d->connections.load();
+ if (cd) {
+ if (cd->currentSender) {
+ cd->currentSender->receiverDeleted();
+ cd->currentSender = nullptr;
+ }
- if (d->connectionLists || d->senders) {
- QMutex *signalSlotMutex = signalSlotLock(this);
- QMutexLocker locker(signalSlotMutex);
+ QBasicMutex *signalSlotMutex = signalSlotLock(this);
+ QBasicMutexLocker locker(signalSlotMutex);
// disconnect all receivers
- if (d->connectionLists) {
- ++d->connectionLists->inUse;
- int connectionListsCount = d->connectionLists->count();
- for (int signal = -1; signal < connectionListsCount; ++signal) {
- QObjectPrivate::ConnectionList &connectionList =
- (*d->connectionLists)[signal];
-
- while (QObjectPrivate::Connection *c = connectionList.first) {
- if (!c->receiver) {
- connectionList.first = c->nextConnectionList;
- c->deref();
- continue;
- }
-
- QMutex *m = signalSlotLock(c->receiver);
- bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
-
- if (c->receiver) {
- *c->prev = c->next;
- if (c->next) c->next->prev = c->prev;
- }
- c->receiver = 0;
- if (needToUnlock)
- m->unlock();
+ int receiverCount = cd->signalVector.count();
+ for (int signal = -1; signal < receiverCount; ++signal) {
+ QObjectPrivate::ConnectionList &connectionList = cd->connectionsForSignal(signal);
+ while (QObjectPrivate::Connection *c = connectionList.first) {
+ if (!c->receiver) {
connectionList.first = c->nextConnectionList;
-
- // The destroy operation must happen outside the lock
- if (c->isSlotObject) {
- c->isSlotObject = false;
- locker.unlock();
- c->slotObj->destroyIfLastRef();
- locker.relock();
- }
c->deref();
+ continue;
}
- }
- if (!--d->connectionLists->inUse) {
- delete d->connectionLists;
- } else {
- d->connectionLists->orphaned = true;
+ QBasicMutex *m = signalSlotLock(c->receiver);
+ bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
+
+ if (c->receiver) {
+ *c->prev = c->next;
+ if (c->next) c->next->prev = c->prev;
+ }
+ c->receiver = 0;
+ if (needToUnlock)
+ m->unlock();
+
+ connectionList.first = c->nextConnectionList;
+
+ // The destroy operation must happen outside the lock
+ if (c->isSlotObject) {
+ c->isSlotObject = false;
+ locker.unlock();
+ c->slotObj->destroyIfLastRef();
+ locker.relock();
+ }
+ c->deref();
}
- d->connectionLists = 0;
}
/* Disconnect all senders:
@@ -986,14 +928,15 @@ QObject::~QObject()
* thread. That's why we set node->prev to &node, that way, if node is destroyed, node will
* be updated.
*/
- QObjectPrivate::Connection *node = d->senders;
+ QObjectPrivate::Connection *node = cd->senders;
while (node) {
+ Q_ASSERT(node->receiver);
QObject *sender = node->sender;
// Send disconnectNotify before removing the connection from sender's connection list.
// This ensures any eventual destructor of sender will block on getting receiver's lock
// and not finish until we release it.
sender->disconnectNotify(QMetaObjectPrivate::signal(sender->metaObject(), node->signal_index));
- QMutex *m = signalSlotLock(sender);
+ QBasicMutex *m = signalSlotLock(sender);
node->prev = &node;
bool needToUnlock = QOrderedMutexLocker::relock(signalSlotMutex, m);
//the node has maybe been removed while the mutex was unlocked in relock?
@@ -1004,9 +947,9 @@ QObject::~QObject()
continue;
}
node->receiver = 0;
- QObjectConnectionListVector *senderLists = sender->d_func()->connectionLists;
- if (senderLists)
- senderLists->dirty = true;
+ QObjectPrivate::ConnectionData *senderData = sender->d_func()->connections.load();
+ if (senderData)
+ senderData->dirty = true;
QtPrivate::QSlotObjectBase *slotObj = nullptr;
if (node->isSlotObject) {
@@ -1026,7 +969,12 @@ QObject::~QObject()
locker.relock();
}
}
+
+ cd->objectDeleted = true;
}
+ if (cd && !cd->ref.deref())
+ delete cd;
+ d->connections.store(nullptr);
if (!d->children.isEmpty())
d->deleteChildren();
@@ -1255,7 +1203,11 @@ bool QObject::event(QEvent *e)
{
QMetaCallEvent *mce = static_cast<QMetaCallEvent*>(e);
- QConnectionSenderSwitcher sw(this, const_cast<QObject*>(mce->sender()), mce->signalId());
+ if (!d_func()->connections.load()) {
+ QBasicMutexLocker locker(signalSlotLock(this));
+ d_func()->ensureConnectionData();
+ }
+ QObjectPrivate::Sender sender(this, const_cast<QObject*>(mce->sender()), mce->signalId());
mce->placeMetaCall(this);
break;
@@ -1559,9 +1511,11 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData
}
// the current emitting thread shouldn't restore currentSender after calling moveToThread()
- if (currentSender)
- currentSender->ref = 0;
- currentSender = 0;
+ ConnectionData *cd = connections.load();
+ if (cd && cd->currentSender) {
+ cd->currentSender->receiverDeleted();
+ cd->currentSender = nullptr;
+ }
// set new thread data
targetData->ref();
@@ -2370,13 +2324,14 @@ QObject *QObject::sender() const
{
Q_D(const QObject);
- QMutexLocker locker(signalSlotLock(this));
- if (!d->currentSender)
- return 0;
+ QBasicMutexLocker locker(signalSlotLock(this));
+ QObjectPrivate::ConnectionData *cd = d->connections.load();
+ if (!cd || !cd->currentSender)
+ return nullptr;
- for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) {
- if (c->sender == d->currentSender->sender)
- return d->currentSender->sender;
+ for (QObjectPrivate::Connection *c = cd->senders; c; c = c->next) {
+ if (c->sender == cd->currentSender->sender)
+ return cd->currentSender->sender;
}
return 0;
@@ -2411,14 +2366,15 @@ int QObject::senderSignalIndex() const
{
Q_D(const QObject);
- QMutexLocker locker(signalSlotLock(this));
- if (!d->currentSender)
+ QBasicMutexLocker locker(signalSlotLock(this));
+ QObjectPrivate::ConnectionData *cd = d->connections.load();
+ if (!cd || !cd->currentSender)
return -1;
- for (QObjectPrivate::Connection *c = d->senders; c; c = c->next) {
- if (c->sender == d->currentSender->sender) {
+ for (QObjectPrivate::Connection *c = cd->senders; c; c = c->next) {
+ if (c->sender == cd->currentSender->sender) {
// Convert from signal range to method range
- return QMetaObjectPrivate::signal(c->sender->metaObject(), d->currentSender->signal).methodIndex();
+ return QMetaObjectPrivate::signal(c->sender->metaObject(), cd->currentSender->signal).methodIndex();
}
}
@@ -2474,15 +2430,14 @@ int QObject::receivers(const char *signal) const
signal_index);
}
- QMutexLocker locker(signalSlotLock(this));
- if (d->connectionLists) {
- if (signal_index < d->connectionLists->count()) {
- const QObjectPrivate::Connection *c =
- d->connectionLists->at(signal_index).first;
- while (c) {
- receivers += c->receiver ? 1 : 0;
- c = c->nextConnectionList;
- }
+ QObjectPrivate::ConnectionData *cd = d->connections.load();
+ QBasicMutexLocker locker(signalSlotLock(this));
+ if (cd && signal_index < cd->signalVector.count()) {
+ const QObjectPrivate::Connection *c =
+ cd->signalVector.at(signal_index).first;
+ while (c) {
+ receivers += c->receiver ? 1 : 0;
+ c = c->nextConnectionList;
}
}
}
@@ -2522,22 +2477,8 @@ bool QObject::isSignalConnected(const QMetaMethod &signal) const
signalIndex += QMetaObjectPrivate::signalOffset(signal.mobj);
- QMutexLocker locker(signalSlotLock(this));
- if (d->connectionLists) {
- if (signalIndex < sizeof(d->connectedSignals) * 8 && !d->connectionLists->dirty)
- return d->isSignalConnected(signalIndex);
-
- if (signalIndex < uint(d->connectionLists->count())) {
- const QObjectPrivate::Connection *c =
- d->connectionLists->at(signalIndex).first;
- while (c) {
- if (c->receiver)
- return true;
- c = c->nextConnectionList;
- }
- }
- }
- return d->isDeclarativeSignalConnected(signalIndex);
+ QBasicMutexLocker locker(signalSlotLock(this));
+ return d->isSignalConnected(signalIndex, true);
}
/*!
@@ -3300,23 +3241,21 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender,
int method_offset = rmeta ? rmeta->methodOffset() : 0;
Q_ASSERT(!rmeta || QMetaObjectPrivate::get(rmeta)->revision >= 6);
- QObjectPrivate::StaticMetaCallFunction callFunction =
- rmeta ? rmeta->d.static_metacall : 0;
+ QObjectPrivate::StaticMetaCallFunction callFunction = rmeta ? rmeta->d.static_metacall : nullptr;
QOrderedMutexLocker locker(signalSlotLock(sender),
signalSlotLock(receiver));
- if (type & Qt::UniqueConnection) {
- QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
- if (connectionLists && connectionLists->count() > signal_index) {
- const QObjectPrivate::Connection *c2 =
- (*connectionLists)[signal_index].first;
+ QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.load();
+ if (type & Qt::UniqueConnection && scd) {
+ if (scd->signalVector.count() > signal_index) {
+ const QObjectPrivate::Connection *c2 = scd->signalVector.at(signal_index).first;
int method_index_absolute = method_index + method_offset;
while (c2) {
if (!c2->isSlotObject && c2->receiver == receiver && c2->method() == method_index_absolute)
- return 0;
+ return nullptr;
c2 = c2->nextConnectionList;
}
}
@@ -3380,7 +3319,7 @@ bool QMetaObject::disconnectOne(const QObject *sender, int signal_index,
*/
bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
const QObject *receiver, int method_index, void **slot,
- QMutex *senderMutex, DisconnectType disconnectType)
+ QBasicMutex *senderMutex, DisconnectType disconnectType)
{
bool success = false;
while (c) {
@@ -3389,7 +3328,7 @@ bool QMetaObjectPrivate::disconnectHelper(QObjectPrivate::Connection *c,
&& (method_index < 0 || (!c->isSlotObject && c->method() == method_index))
&& (slot == 0 || (c->isSlotObject && c->slotObj->compare(slot)))))) {
bool needToUnlock = false;
- QMutex *receiverMutex = 0;
+ QBasicMutex *receiverMutex = nullptr;
if (c->receiver) {
receiverMutex = signalSlotLock(c->receiver);
// need to relock this receiver and sender in the correct order
@@ -3437,41 +3376,36 @@ bool QMetaObjectPrivate::disconnect(const QObject *sender,
QObject *s = const_cast<QObject *>(sender);
- QMutex *senderMutex = signalSlotLock(sender);
- QMutexLocker locker(senderMutex);
+ QBasicMutex *senderMutex = signalSlotLock(sender);
+ QBasicMutexLocker locker(senderMutex);
- QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
- if (!connectionLists)
+ QObjectPrivate::ConnectionData *scd = QObjectPrivate::get(s)->connections.load();
+ if (!scd)
return false;
- // prevent incoming connections changing the connectionLists while unlocked
- ++connectionLists->inUse;
-
bool success = false;
- if (signal_index < 0) {
- // remove from all connection lists
- for (int sig_index = -1; sig_index < connectionLists->count(); ++sig_index) {
- QObjectPrivate::Connection *c =
- (*connectionLists)[sig_index].first;
+ {
+ // prevent incoming connections changing the connections->receivers while unlocked
+ QObjectPrivate::ConnectionDataPointer connections(scd);
+
+ if (signal_index < 0) {
+ // remove from all connection lists
+ for (int sig_index = -1; sig_index < scd->signalVector.count(); ++sig_index) {
+ QObjectPrivate::Connection *c = scd->connectionsForSignal(sig_index).first;
+ if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) {
+ success = true;
+ scd->dirty = true;
+ }
+ }
+ } else if (signal_index < scd->signalVector.count()) {
+ QObjectPrivate::Connection *c = scd->signalVector.at(signal_index).first;
if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) {
success = true;
- connectionLists->dirty = true;
+ scd->dirty = true;
}
}
- } else if (signal_index < connectionLists->count()) {
- QObjectPrivate::Connection *c =
- (*connectionLists)[signal_index].first;
- if (disconnectHelper(c, receiver, method_index, slot, senderMutex, disconnectType)) {
- success = true;
- connectionLists->dirty = true;
- }
}
- --connectionLists->inUse;
- Q_ASSERT(connectionLists->inUse >= 0);
- if (connectionLists->orphaned && !connectionLists->inUse)
- delete connectionLists;
-
locker.unlock();
if (success) {
QMetaMethod smethod = QMetaObjectPrivate::signal(smeta, signal_index);
@@ -3590,7 +3524,7 @@ void QMetaObject::connectSlotsByName(QObject *o)
\a signal must be in the signal index range (see QObjectPrivate::signalIndex()).
*/
static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connection *c, void **argv,
- QMutexLocker &locker)
+ QBasicMutexLocker &locker)
{
const int *argumentTypes = c->argumentTypes.load();
if (!argumentTypes) {
@@ -3643,89 +3577,53 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect
QCoreApplication::postEvent(c->receiver, ev);
}
-/*!
- \internal
- */
-void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index,
- void **argv)
+template <bool callbacks_enabled>
+void doActivate(QObject *sender, int signal_index, void **argv)
{
- activate(sender, QMetaObjectPrivate::signalOffset(m), local_signal_index, argv);
-}
-
-/*!
- \internal
- */
-void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_index, void **argv)
-{
- int signal_index = signalOffset + local_signal_index;
+ QObjectPrivate *sp = QObjectPrivate::get(sender);
- if (sender->d_func()->blockSig)
+ if (sp->blockSig)
return;
- if (sender->d_func()->isDeclarativeSignalConnected(signal_index)
+ if (sp->isDeclarativeSignalConnected(signal_index)
&& QAbstractDeclarativeData::signalEmitted) {
Q_TRACE(QMetaObject_activate_begin_declarative_signal, sender, signal_index);
- QAbstractDeclarativeData::signalEmitted(sender->d_func()->declarativeData, sender,
+ QAbstractDeclarativeData::signalEmitted(sp->declarativeData, sender,
signal_index, argv);
Q_TRACE(QMetaObject_activate_end_declarative_signal, sender, signal_index);
}
- if (!sender->d_func()->isSignalConnected(signal_index, /*checkDeclarative =*/ false)
- && !qt_signal_spy_callback_set.signal_begin_callback
- && !qt_signal_spy_callback_set.signal_end_callback
- && !Q_TRACE_ENABLED(QMetaObject_activate_begin_signal)
- && !Q_TRACE_ENABLED(QMetaObject_activate_end_signal)) {
- // The possible declarative connection is done, and nothing else is connected, so:
- return;
- }
+ const QSignalSpyCallbackSet *signal_spy_set = callbacks_enabled ? qt_signal_spy_callback_set.load() : nullptr;
void *empty_argv[] = { nullptr };
if (!argv)
argv = empty_argv;
- if (qt_signal_spy_callback_set.signal_begin_callback != 0) {
- qt_signal_spy_callback_set.signal_begin_callback(sender, signal_index, argv);
+ if (!sp->isSignalConnected(signal_index, false)) {
+ // The possible declarative connection is done, and nothing else is connected
+ if (callbacks_enabled && signal_spy_set->signal_begin_callback != nullptr)
+ signal_spy_set->signal_begin_callback(sender, signal_index, argv);
+ Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index);
+ Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index);
+ if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
+ signal_spy_set->signal_end_callback(sender, signal_index);
+ return;
}
+
+ if (callbacks_enabled && signal_spy_set->signal_begin_callback != nullptr)
+ signal_spy_set->signal_begin_callback(sender, signal_index, argv);
Q_TRACE(QMetaObject_activate_begin_signal, sender, signal_index);
{
- QMutexLocker locker(signalSlotLock(sender));
- struct ConnectionListsRef {
- QObjectConnectionListVector *connectionLists;
- ConnectionListsRef(QObjectConnectionListVector *connectionLists) : connectionLists(connectionLists)
- {
- if (connectionLists)
- ++connectionLists->inUse;
- }
- ~ConnectionListsRef()
- {
- if (!connectionLists)
- return;
-
- --connectionLists->inUse;
- Q_ASSERT(connectionLists->inUse >= 0);
- if (connectionLists->orphaned) {
- if (!connectionLists->inUse)
- delete connectionLists;
- }
- }
-
- QObjectConnectionListVector *operator->() const { return connectionLists; }
- };
- ConnectionListsRef connectionLists = sender->d_func()->connectionLists;
- if (!connectionLists.connectionLists) {
- locker.unlock();
- if (qt_signal_spy_callback_set.signal_end_callback != 0)
- qt_signal_spy_callback_set.signal_end_callback(sender, signal_index);
- Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index);
- return;
- }
+ QBasicMutexLocker locker(signalSlotLock(sender));
+ Q_ASSERT(sp->connections);
+ QObjectPrivate::ConnectionDataPointer connections(sp->connections.load());
const QObjectPrivate::ConnectionList *list;
- if (signal_index < connectionLists->count())
- list = &connectionLists->at(signal_index);
+ if (signal_index < connections->signalVector.count())
+ list = &connections->signalVector.at(signal_index);
else
- list = &connectionLists->allsignals;
+ list = &connections->allsignals;
Qt::HANDLE currentThreadId = QThread::currentThreadId();
@@ -3741,7 +3639,7 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
continue;
QObject * const receiver = c->receiver;
- const bool receiverInSameThread = currentThreadId == receiver->d_func()->threadData->threadId.load();
+ const bool receiverInSameThread = currentThreadId == QObjectPrivate::get(receiver)->threadData->threadId.load();
// determine if this connection should be sent immediately or
// put into the event queue
@@ -3769,11 +3667,8 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
#endif
}
- QConnectionSenderSwitcher sw;
+ QObjectPrivate::Sender senderData(receiverInSameThread ? receiver : nullptr, sender, signal_index);
- if (receiverInSameThread) {
- sw.switchSender(receiver, sender, signal_index);
- }
if (c->isSlotObject) {
c->slotObj->ref();
QScopedPointer<QtPrivate::QSlotObjectBase, QSlotObjectBaseDeleter> obj(c->slotObj);
@@ -3790,57 +3685,85 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
locker.relock();
} else if (c->callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) {
//we compare the vtable to make sure we are not in the destructor of the object.
- const int methodIndex = c->method();
const int method_relative = c->method_relative;
const auto callFunction = c->callFunction;
locker.unlock();
- if (qt_signal_spy_callback_set.slot_begin_callback != 0)
- qt_signal_spy_callback_set.slot_begin_callback(receiver, methodIndex, argv);
+ const int methodIndex = (Q_HAS_TRACEPOINTS || callbacks_enabled) ? c->method() : 0;
+ if (callbacks_enabled && signal_spy_set->slot_begin_callback != nullptr)
+ signal_spy_set->slot_begin_callback(receiver, methodIndex, argv);
Q_TRACE(QMetaObject_activate_begin_slot, receiver, methodIndex);
callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv);
Q_TRACE(QMetaObject_activate_end_slot, receiver, methodIndex);
- if (qt_signal_spy_callback_set.slot_end_callback != 0)
- qt_signal_spy_callback_set.slot_end_callback(receiver, methodIndex);
+ if (callbacks_enabled && signal_spy_set->slot_end_callback != nullptr)
+ signal_spy_set->slot_end_callback(receiver, methodIndex);
locker.relock();
} else {
const int method = c->method_relative + c->method_offset;
locker.unlock();
- if (qt_signal_spy_callback_set.slot_begin_callback != 0) {
- qt_signal_spy_callback_set.slot_begin_callback(receiver, method, argv);
+ if (callbacks_enabled && signal_spy_set->slot_begin_callback != nullptr) {
+ signal_spy_set->slot_begin_callback(receiver, method, argv);
}
Q_TRACE(QMetaObject_activate_begin_slot, receiver, method);
- metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv);
+ QMetaObject::metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv);
Q_TRACE(QMetaObject_activate_end_slot, receiver, method);
- if (qt_signal_spy_callback_set.slot_end_callback != 0)
- qt_signal_spy_callback_set.slot_end_callback(receiver, method);
+ if (callbacks_enabled && signal_spy_set->slot_end_callback != nullptr)
+ signal_spy_set->slot_end_callback(receiver, method);
locker.relock();
}
- if (connectionLists->orphaned)
+ if (connections->objectDeleted)
break;
} while (c != last && (c = c->nextConnectionList) != 0);
- if (connectionLists->orphaned)
+ if (connections->objectDeleted)
break;
- } while (list != &connectionLists->allsignals &&
+ } while (list != &connections->allsignals &&
//start over for all signals;
- ((list = &connectionLists->allsignals), true));
+ ((list = &connections->allsignals), true));
}
- if (qt_signal_spy_callback_set.signal_end_callback != 0)
- qt_signal_spy_callback_set.signal_end_callback(sender, signal_index);
+ if (callbacks_enabled && signal_spy_set->signal_end_callback != nullptr)
+ signal_spy_set->signal_end_callback(sender, signal_index);
Q_TRACE(QMetaObject_activate_end_signal, sender, signal_index);
+
}
/*!
\internal
+ */
+void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_signal_index,
+ void **argv)
+{
+ int signal_index = local_signal_index + QMetaObjectPrivate::signalOffset(m);
+
+ if (Q_UNLIKELY(qt_signal_spy_callback_set.load()))
+ doActivate<true>(sender, signal_index, argv);
+ else
+ doActivate<false>(sender, signal_index, argv);
+}
+
+/*!
+ \internal
+ */
+void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_index, void **argv)
+{
+ int signal_index = signalOffset + local_signal_index;
+
+ if (Q_UNLIKELY(qt_signal_spy_callback_set.load()))
+ doActivate<true>(sender, signal_index, argv);
+ else
+ doActivate<false>(sender, signal_index, argv);
+ }
+
+/*!
+ \internal
signal_index comes from indexOfMethod()
*/
void QMetaObject::activate(QObject *sender, int signal_index, void **argv)
@@ -3853,7 +3776,7 @@ void QMetaObject::activate(QObject *sender, int signal_index, void **argv)
/*!
\internal
- Returns the signal index used in the internal connectionLists vector.
+ Returns the signal index used in the internal connections->receivers vector.
It is different from QMetaObject::indexOfSignal(): indexOfSignal is the same as indexOfMethod
while QObjectPrivate::signalIndex is smaller because it doesn't give index to slots.
@@ -4093,19 +4016,19 @@ void QObject::dumpObjectInfo() const
objectName().isEmpty() ? "unnamed" : objectName().toLocal8Bit().data());
Q_D(const QObject);
- QMutexLocker locker(signalSlotLock(this));
+ QBasicMutexLocker locker(signalSlotLock(this));
// first, look for connections where this object is the sender
qDebug(" SIGNALS OUT");
- if (d->connectionLists) {
- for (int signal_index = 0; signal_index < d->connectionLists->count(); ++signal_index) {
+ QObjectPrivate::ConnectionData *cd = d->connections.load();
+ if (cd && cd->signalVector.count()) {
+ for (int signal_index = 0; signal_index < cd->signalVector.count(); ++signal_index) {
const QMetaMethod signal = QMetaObjectPrivate::signal(metaObject(), signal_index);
qDebug(" signal: %s", signal.methodSignature().constData());
// receivers
- const QObjectPrivate::Connection *c =
- d->connectionLists->at(signal_index).first;
+ const QObjectPrivate::Connection *c = cd->signalVector.at(signal_index).first;
while (c) {
if (!c->receiver) {
qDebug(" <Disconnected receiver>");
@@ -4133,8 +4056,8 @@ void QObject::dumpObjectInfo() const
// now look for connections where this object is the receiver
qDebug(" SIGNALS IN");
- if (d->senders) {
- for (QObjectPrivate::Connection *s = d->senders; s; s = s->next) {
+ if (cd && cd->senders) {
+ for (QObjectPrivate::Connection *s = cd->senders; s; s = s->next) {
QByteArray slotName = QByteArrayLiteral("<unknown>");
if (!s->isSlotObject) {
const QMetaMethod slot = metaObject()->method(s->method());
@@ -4869,11 +4792,10 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s
QOrderedMutexLocker locker(signalSlotLock(sender),
signalSlotLock(receiver));
- if (type & Qt::UniqueConnection && slot) {
- QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists;
- if (connectionLists && connectionLists->count() > signal_index) {
- const QObjectPrivate::Connection *c2 =
- (*connectionLists)[signal_index].first;
+ if (type & Qt::UniqueConnection && slot && QObjectPrivate::get(s)->connections.load()) {
+ QObjectPrivate::ConnectionData *connections = QObjectPrivate::get(s)->connections.load();
+ if (connections->signalVector.count() > signal_index) {
+ const QObjectPrivate::Connection *c2 = connections->signalVector.at(signal_index).first;
while (c2) {
if (c2->receiver == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) {
@@ -4924,20 +4846,20 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
if (!c || !c->receiver)
return false;
- QMutex *senderMutex = signalSlotLock(c->sender);
- QMutex *receiverMutex = signalSlotLock(c->receiver);
+ QBasicMutex *senderMutex = signalSlotLock(c->sender);
+ QBasicMutex *receiverMutex = signalSlotLock(c->receiver);
{
QOrderedMutexLocker locker(senderMutex, receiverMutex);
- QObjectConnectionListVector *connectionLists = QObjectPrivate::get(c->sender)->connectionLists;
- Q_ASSERT(connectionLists);
- connectionLists->dirty = true;
+ QObjectPrivate::ConnectionData *connections = QObjectPrivate::get(c->sender)->connections.load();
+ Q_ASSERT(connections);
+ connections->dirty = true;
*c->prev = c->next;
if (c->next)
c->next->prev = c->prev;
- c->receiver = 0;
+ c->receiver = nullptr;
}
// destroy the QSlotObject, if possible
@@ -4949,7 +4871,7 @@ bool QObject::disconnect(const QMetaObject::Connection &connection)
c->sender->disconnectNotify(QMetaObjectPrivate::signal(c->sender->metaObject(),
c->signal_index));
- const_cast<QMetaObject::Connection &>(connection).d_ptr = 0;
+ const_cast<QMetaObject::Connection &>(connection).d_ptr = nullptr;
c->deref(); // has been removed from the QMetaObject::Connection object
return true;
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index a762e6f529..823c7a195a 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -79,9 +79,9 @@ struct QSignalSpyCallbackSet
EndCallback signal_end_callback,
slot_end_callback;
};
-void Q_CORE_EXPORT qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set);
+void Q_CORE_EXPORT qt_register_signal_spy_callbacks(QSignalSpyCallbackSet *callback_set);
-extern QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set;
+extern Q_CORE_EXPORT QBasicAtomicPointer<QSignalSpyCallbackSet> qt_signal_spy_callback_set;
enum { QObjectPrivateVersion = QT_VERSION };
@@ -167,11 +167,69 @@ public:
struct Sender
{
+ Sender(QObject *receiver, QObject *sender, int signal)
+ : receiver(receiver), sender(sender), signal(signal)
+ {
+ if (receiver) {
+ ConnectionData *cd = receiver->d_func()->connections.load();
+ previous = cd->currentSender;
+ cd->currentSender = this;
+ }
+ }
+ ~Sender()
+ {
+ if (receiver)
+ receiver->d_func()->connections.load()->currentSender = previous;
+ }
+ void receiverDeleted()
+ {
+ Sender *s = this;
+ while (s) {
+ s->receiver = nullptr;
+ s = s->previous;
+ }
+ }
+ Sender *previous;
+ QObject *receiver;
QObject *sender;
int signal;
- int ref;
};
+ /*
+ This contains the all connections from and to an object.
+
+ The signalVector contains the lists of connections for a given signal. The index in the vector correspond
+ to the signal index. The signal index is the one returned by QObjectPrivate::signalIndex (not
+ QMetaObject::indexOfSignal). allsignals contains a list of special connections that will get invoked on
+ any signal emission. This is done by connecting to signal index -1.
+
+ This vector is protected by the object mutex (signalSlotLock())
+
+ Each Connection is also part of a 'senders' linked list. This one contains all connections connected
+ to a slot in this object. The mutex of the receiver must be locked when touching the pointers of this
+ linked list.
+ */
+ struct ConnectionData {
+ bool objectDeleted = false; //the QObject owner of this vector has been destroyed while the vector was inUse
+ struct Ref {
+ int _ref = 0;
+ void ref() { ++_ref; }
+ int deref() { return --_ref; }
+ operator int() const { return _ref; }
+ };
+
+ Ref ref;
+ bool dirty = false; //some Connection have been disconnected (their receiver is 0) but not removed from the list yet
+ ConnectionList allsignals;
+ QVector<ConnectionList> signalVector;
+ Connection *senders = nullptr;
+ Sender *currentSender = nullptr; // object currently activating the object
+
+ ConnectionList &connectionsForSignal(int signal)
+ {
+ return signal < 0 ? allsignals : signalVector[signal];
+ }
+ };
QObjectPrivate(int version = QObjectPrivateVersion);
virtual ~QObjectPrivate();
@@ -189,19 +247,13 @@ public:
void addConnection(int signal, Connection *c);
void cleanConnectionLists();
- static inline Sender *setCurrentSender(QObject *receiver,
- Sender *sender);
- static inline void resetCurrentSender(QObject *receiver,
- Sender *currentSender,
- Sender *previousSender);
-
static QObjectPrivate *get(QObject *o) {
return o->d_func();
}
static const QObjectPrivate *get(const QObject *o) { return o->d_func(); }
int signalIndex(const char *signalName, const QMetaObject **meta = nullptr) const;
- inline bool isSignalConnected(uint signalIdx, bool checkDeclarative = true) const;
+ bool isSignalConnected(uint signalIdx, bool checkDeclarative = true) const;
inline bool isDeclarativeSignalConnected(uint signalIdx) const;
// To allow abitrary objects to call connectNotify()/disconnectNotify() without making
@@ -224,15 +276,21 @@ public:
const int *types, const QMetaObject *senderMetaObject);
static QMetaObject::Connection connect(const QObject *sender, int signal_index, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type);
static bool disconnect(const QObject *sender, int signal_index, void **slot);
+
+ void ensureConnectionData()
+ {
+ if (connections.load())
+ return;
+ ConnectionData *cd = new ConnectionData;
+ cd->ref.ref();
+ connections.store(cd);
+ }
public:
ExtraData *extraData; // extra data set by the user
QThreadData *threadData; // id of the thread that owns the object
- QObjectConnectionListVector *connectionLists;
-
- Connection *senders; // linked list of connections connected to this object
- Sender *currentSender; // object currently activating the object
- mutable quint32 connectedSignals[2];
+ using ConnectionDataPointer = QExplicitlySharedDataPointer<ConnectionData>;
+ QAtomicPointer<ConnectionData> connections;
union {
QObject *currentChildBeingDeleted; // should only be used when QObjectData::isDeletingChildren is set
@@ -246,47 +304,12 @@ public:
Q_DECLARE_TYPEINFO(QObjectPrivate::ConnectionList, Q_MOVABLE_TYPE);
-/*! \internal
-
- Returns \c true if the signal with index \a signal_index from object \a sender is connected.
- Signals with indices above a certain range are always considered connected (see connectedSignals
- in QObjectPrivate).
-
- \a signal_index must be the index returned by QObjectPrivate::signalIndex;
-*/
-inline bool QObjectPrivate::isSignalConnected(uint signal_index, bool checkDeclarative) const
-{
- return signal_index >= sizeof(connectedSignals) * 8
- || (connectedSignals[signal_index >> 5] & (1 << (signal_index & 0x1f))
- || (checkDeclarative && isDeclarativeSignalConnected(signal_index)));
-}
-
inline bool QObjectPrivate::isDeclarativeSignalConnected(uint signal_index) const
{
return declarativeData && QAbstractDeclarativeData::isSignalConnected
&& QAbstractDeclarativeData::isSignalConnected(declarativeData, q_func(), signal_index);
}
-inline QObjectPrivate::Sender *QObjectPrivate::setCurrentSender(QObject *receiver,
- Sender *sender)
-{
- Sender *previousSender = receiver->d_func()->currentSender;
- receiver->d_func()->currentSender = sender;
- return previousSender;
-}
-
-inline void QObjectPrivate::resetCurrentSender(QObject *receiver,
- Sender *currentSender,
- Sender *previousSender)
-{
- // ref is set to zero when this object is deleted during the metacall
- if (currentSender->ref == 1)
- receiver->d_func()->currentSender = previousSender;
- // if we've recursed, we need to tell the caller about the objects deletion
- if (previousSender)
- previousSender->ref = currentSender->ref;
-}
-
inline void QObjectPrivate::connectNotify(const QMetaMethod &signal)
{
q_ptr->connectNotify(signal);
diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp
deleted file mode 100644
index 5437210699..0000000000
--- a/src/corelib/kernel/qtcore_eval.cpp
+++ /dev/null
@@ -1,560 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qcoreevent.h>
-#include <qdatetime.h>
-#include <qlibraryinfo.h>
-#include <qobject.h>
-#include <qcoreapplication.h>
-#include <private/qcoreapplication_p.h>
-
-#include "stdio.h"
-#include "stdlib.h"
-
-QT_BEGIN_NAMESPACE
-
-#include "qconfig_eval.cpp"
-
-static const char boilerplate_supported_but_time_limited[] =
- "\nQt %1 Evaluation License\n"
- "Copyright (C) 2016 The Qt Company Ltd.\n"
- "This trial version may only be used for evaluation purposes\n"
- "and will shut down after 120 minutes.\n"
- "Registered to:\n"
- " Licensee: %2\n\n"
- "The evaluation expires in %4 days\n\n"
- "Contact http://www.qt.io/contact-us for pricing and purchasing information.\n";
-
-static const char boilerplate_supported[] =
- "\nQt %1 Evaluation License\n"
- "Copyright (C) 2016 The Qt Company Ltd.\n"
- "This trial version may only be used for evaluation purposes\n"
- "Registered to:\n"
- " Licensee: %2\n\n"
- "The evaluation expires in %4 days\n\n"
- "Contact http://www.qt.io/contact-us for pricing and purchasing information.\n";
-
-static const char boilerplate_expired[] =
- "This software is using the trial version of the Qt GUI toolkit.\n"
- "The trial period has expired. If you need more time to\n"
- "evaluate Qt, or if you have any questions about Qt, contact us\n"
- "at: http://www.qt.io/contact-us.\n\n";
-
-static const char will_shutdown_1min[] =
- "\nThe evaluation of Qt will SHUT DOWN in 1 minute.\n"
- "Contact http://www.qt.io/contact-us for pricing and purchasing information.\n";
-
-static const char will_shutdown_now[] =
- "\nThe evaluation of Qt has now reached its automatic\n"
- "timeout and will shut down.\n"
- "Contact http://www.qt.io/contact-us for pricing and purchasing information.\n";
-
-enum EvaluationStatus {
- EvaluationNotSupported = 0,
- EvaluationSupportedButTimeLimited,
- EvaluationSupported
-};
-
-static EvaluationStatus qt_eval_is_supported()
-{
- const volatile char *const license_key = qt_eval_key_data + 12;
-
- // fast fail
- if (!qt_eval_key_data[0] || !*license_key)
- return EvaluationNotSupported;
-
- // is this an unsupported evaluation?
- const volatile char *typecode = license_key;
- int field = 2;
- for ( ; field && *typecode; ++typecode)
- if (*typecode == '-')
- --field;
-
- if (!field && typecode[1] == '4' && typecode[2] == 'M') {
- if (typecode[0] == 'Q')
- return EvaluationSupportedButTimeLimited;
- else if (typecode[0] == 'R' || typecode[0] == 'Z')
- return EvaluationSupported;
- }
- return EvaluationNotSupported;
-}
-
-static int qt_eval_days_left()
-{
- const volatile char *const expiry_date = qt_eval_expiry_date + 12;
-
- QDate today = QDate::currentDate();
- QDate lastday = QDate::fromString(
- QString::fromLatin1(const_cast<const char*>(expiry_date)), Qt::ISODate);
- return today.daysTo(lastday);
-}
-
-static bool qt_eval_is_expired()
-{
- return qt_eval_days_left() < 0;
-}
-
-static QString qt_eval_string()
-{
- const char *msg;
- switch (qt_eval_is_supported()) {
- case EvaluationSupportedButTimeLimited:
- msg = boilerplate_supported_but_time_limited;
- break;
- case EvaluationSupported:
- msg = boilerplate_supported;
- break;
- default:
- return QString();
- }
-
- return QString::fromLatin1(msg)
- .arg(QLatin1String(QT_VERSION_STR))
- .arg(QLibraryInfo::licensee())
- .arg(qt_eval_days_left());
-}
-
-#define WARN_TIMEOUT 60 * 1000 * 119
-#define KILL_DELAY 60 * 1000 * 1
-
-class QCoreFuriCuri : public QObject
-{
-public:
-
- int warn;
- int kill;
-
- QCoreFuriCuri() : QObject(), warn(-1), kill(-1)
- {
- if (qt_eval_is_supported() == EvaluationSupportedButTimeLimited) {
- warn = startTimer(WARN_TIMEOUT);
- kill = 0;
- }
- }
-
- void timerEvent(QTimerEvent *e) override {
- if (e->timerId() == warn) {
- killTimer(warn);
- fprintf(stderr, "%s\n", will_shutdown_1min);
- kill = startTimer(KILL_DELAY);
- } else if (e->timerId() == kill) {
- fprintf(stderr, "%s\n", will_shutdown_now);
- QCoreApplication::instance()->quit();
- }
- }
-};
-
-#if defined(QT_BUILD_CORE_LIB) || defined (QT_BOOTSTRAPPED)
-
-void qt_core_eval_init(QCoreApplicationPrivate::Type type)
-{
- if (type != QCoreApplicationPrivate::Tty)
- return;
-
- if (!qt_eval_is_supported())
- return;
-
- if (qt_eval_is_expired()) {
- fprintf(stderr, "%s\n", boilerplate_expired);
- exit(0);
- } else {
- fprintf(stderr, "%s\n", qPrintable(qt_eval_string()));
- Q_UNUSED(new QCoreFuriCuri());
- }
-}
-#endif
-
-#ifdef QT_BUILD_WIDGETS_LIB
-
-QT_BEGIN_INCLUDE_NAMESPACE
-#include <qdialog.h>
-#include <qlabel.h>
-#include <qlayout.h>
-#include <qmessagebox.h>
-#if QT_CONFIG(pushbutton)
-#include <qpushbutton.h>
-#endif
-#include <qtimer.h>
-#include <qapplication.h>
-QT_END_INCLUDE_NAMESPACE
-
-
-static const char * const qtlogo_eval_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"46 55 174 2",
-" c #002E02",
-". c #00370D",
-"X c #003A0E",
-"o c #003710",
-"O c #013C13",
-"+ c #043E1A",
-"@ c #084F0A",
-"# c #0B520C",
-"$ c #054413",
-"% c #0C4C17",
-"& c #07421D",
-"* c #09451D",
-"= c #0D491E",
-"- c #125515",
-"; c #13541A",
-": c #17591B",
-"> c #1B5C1D",
-", c #1F611F",
-"< c #20621E",
-"1 c #337B1E",
-"2 c #0B4521",
-"3 c #0F4923",
-"4 c #114B24",
-"5 c #154D2A",
-"6 c #175323",
-"7 c #1C5924",
-"8 c #1C532F",
-"9 c #1E5432",
-"0 c #245936",
-"q c #265938",
-"w c #295C3B",
-"e c #246324",
-"r c #266823",
-"t c #2A6C24",
-"y c #276628",
-"u c #2D7026",
-"i c #327427",
-"p c #367927",
-"a c #37782A",
-"s c #397C2A",
-"d c #2E613E",
-"f c #336C37",
-"g c #2F6040",
-"h c #356545",
-"j c #3C6B4E",
-"k c #3F6C51",
-"l c #406E4F",
-"z c #406D52",
-"x c #477457",
-"c c #497557",
-"v c #4B7857",
-"b c #517B5E",
-"n c #3C8423",
-"m c #3E812C",
-"M c #53A61D",
-"N c #41862C",
-"B c #458A2D",
-"V c #498F2D",
-"C c #479324",
-"Z c #489226",
-"A c #4D952C",
-"S c #478B30",
-"D c #488C30",
-"F c #4D9232",
-"G c #509632",
-"H c #549A33",
-"J c #589F35",
-"K c #56A526",
-"L c #57A821",
-"P c #5BAA27",
-"I c #57A32A",
-"U c #5CA72E",
-"Y c #5DAB2A",
-"T c #5CA336",
-"R c #60AD2E",
-"E c #63B12D",
-"W c #65AF35",
-"Q c #62A53F",
-"! c #65AE39",
-"~ c #66B036",
-"^ c #6AB437",
-"/ c #67B138",
-"( c #6AB339",
-") c #6DB838",
-"_ c #70BA3C",
-"` c #4D8545",
-"' c #4E8942",
-"] c #548851",
-"[ c #6FAF4A",
-"{ c #6DB243",
-"} c #71B546",
-"| c #70B840",
-" . c #73B648",
-".. c #79BA4E",
-"X. c #7CBB53",
-"o. c #598266",
-"O. c #62886D",
-"+. c #6A8F75",
-"@. c #6B9173",
-"#. c #70937A",
-"$. c #799F79",
-"%. c #7BAF66",
-"&. c #81BD5B",
-"*. c #85BF60",
-"=. c #85AC7F",
-"-. c #8DBA7B",
-";. c #87C061",
-":. c #8AC364",
-">. c #8DC46A",
-",. c #90C56E",
-"<. c #93C771",
-"1. c #96CA73",
-"2. c #9ACB7C",
-"3. c #9FD07D",
-"4. c #779981",
-"5. c #7F9F89",
-"6. c #809F88",
-"7. c #82A18B",
-"8. c #86A192",
-"9. c #8DA994",
-"0. c #8FA998",
-"q. c #94AF9B",
-"w. c #97B991",
-"e. c #97B19E",
-"r. c #9DB6A3",
-"t. c #A3BCA7",
-"y. c #A6BCAB",
-"u. c #A9BEB1",
-"i. c #9ECD81",
-"p. c #A2CF85",
-"a. c #A5D284",
-"s. c #A6D189",
-"d. c #A9D28E",
-"f. c #ABD491",
-"g. c #B1D797",
-"h. c #B1D699",
-"j. c #B5D89E",
-"k. c #ADC5AC",
-"l. c #B1CAAE",
-"z. c #B9DAA3",
-"x. c #BDDDA8",
-"c. c #ADC1B4",
-"v. c #B2C6B6",
-"b. c #B5C6BC",
-"n. c #B6C9BA",
-"m. c #BCD1BA",
-"M. c #C6E1B4",
-"N. c #CDE5BD",
-"B. c #C2D2C6",
-"V. c #CADEC2",
-"C. c #C6D3CC",
-"Z. c #C8D7CB",
-"A. c #CEDAD2",
-"S. c #D2DDD4",
-"D. c #D3E9C6",
-"F. c #D7EBC9",
-"G. c #D9EBCD",
-"H. c #DEEED4",
-"J. c #D6E0D9",
-"K. c #DAE4DC",
-"L. c #E0EFD7",
-"P. c #E5F2DD",
-"I. c #DFE8E0",
-"U. c #E4EBE5",
-"Y. c #E9EFEA",
-"T. c #EDF4EB",
-"R. c #F0FAE6",
-"E. c #F1F8EC",
-"W. c #EDF0F0",
-"Q. c #F4F7F3",
-"!. c #F6F9F4",
-"~. c #F8FAF7",
-"^. c #FEFEFE",
-"/. c None",
-/* pixels */
-"/././././.c h ' Q / W _ &.p././././././././././././././././././././././././././././././././.",
-"/././.4 O % Z ~ ~ W ~ W R U R R ( X.>.p././././././././././././././././././././././././././.",
-"/./.. * = J _ ~ ~ ~ ~ ~ / / / / W W U P P U W .;.2././././././././././././././././././././.",
-"/.= = & a ) W ~ ~ ~ ~ ~ / W / ~ ~ ~ ^ ( ( ^ ~ R R U P Y ~ .;.2././././././././././././././.",
-"O.O = = T ^ W ~ ~ ~ ~ ~ ~ W W / W ~ ~ ~ ~ ~ ~ ~ ( ( ( ( ~ W Y Y Y Y W { &.1././././././././.",
-"0 = * 7 ~ ~ ~ ~ ~ ~ ~ ~ ~ / / W ~ ~ ~ ~ ~ ~ ~ ~ W W W ~ ~ ~ ~ ( ( ( W W R U P U W { X.1.f./.",
-"= = & e ^ W ~ ~ ~ ~ ~ ~ ~ ~ / / ~ ~ ~ ~ ~ ~ ~ ~ W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ^ ( ( / ~ W R U U Y ",
-"= = & e ^ W ~ ~ ~ ~ ~ ~ ~ ~ W W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( W ~ ~ ~ ^ ^ ( ",
-"= = * e ^ W ~ ~ ~ ~ ~ ~ / W / W ! ( / ~ W ^ ( ( ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ~ W W ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ ! ~ ~ ~ ~ ~ ~ W W ^ _ ~ K Y W W R P Y W ( ~ ~ ~ ~ ~ ~ ~ W / ~ ~ ~ ^ W ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ ~ ~ ~ ~ W ) W 1 ` w.V.L.H.D.z.,.~ Y ^ ~ ~ ~ ~ ~ W ~ ~ ~ ( ~ W W ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ ~ ~ ~ W ) V = 8.~.^.^.^.^.^.^.^.U.<.Y ~ ~ ~ ~ ~ W W ! ~ Y W ^ W ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ ~ ~ W ^ B O u.^.~.^.^.^.^.~.~.^.^.^.h.Y ^ ~ ~ ^ F $ k.R.G.1.Y / ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ ~ ~ ~ / W ( J X 7.^.~.^.^.^.^.^.^.^.^.^.^.^.s.Y / W ) a 2 U.^.^.d.U ( ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W / ~ ~ ~ ^ > w ~.^.^.^.^.^.F.%.v c.^.^.^.^.~.X.W ~ ^ > h ^.^.^.d.P ( ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ W ^ H o e.^.^.^.^.^.G.Y E n . y.^.^.^.^.M.Y ( ! $ @.^.~.^.f.U ( / ~ ~ W ~ ~ ",
-"= = & e ^ W ~ W ! ) t 4 U.^.^.^.^.^.>.U ( _ , 9 ~.^.^.^.~...^ A y.^.~.^.s.M W Y ~ ~ ~ ~ ~ ",
-"= 3 & e ^ W ~ ( ^ ( $ c ^.^.^.^.^.E.) ~ ~ ^ S o n.^.^.^.^.=.- l.v.Y.^.^.^.M.:.:.X.~ ~ ~ ~ ~ ",
-"= = & e ^ ! W W ( J X 7.^.^.^.^.^.F.Y ( W ^ T X 6.^.^.~.^.c.. J.^.^.^.^.^.^.^.^.P.~ ~ ~ ~ ~ ",
-"= = & r ^ W / W ) B o v.^.~.^.^.^.M.U / ~ ~ ! $ o.^.^.^.^.K.* S.^.^.^.^.^.^.^.^.P.~ ~ ~ ~ ~ ",
-"= = & e ^ ! ~ W ) a + S.^.^.^.^.^.z.P ( W ~ ( % z ^.^.^.^.~.f t.U.^.^.^.^.~.^.^.P.~ ~ ~ ~ ~ ",
-"* = & e ^ W ~ W ) t 3 Y.^.^.^.^.^.f.P ( ~ ~ ^ ; h ^.^.^.^.^.:.@ j ^.^.^.^.h.{ X.&.~ ~ ~ ~ ~ ",
-"3 = & e ^ W ~ ~ ^ e 8 Q.^.^.^.^.^.s.P ~ ~ W ^ > 0 ~.^.^.^.^.1.# z ^.^.^.^.d.L W R ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ ^ > q ~.^.^.^.^.^.p.U ^ ~ W ) e 9 ~.^.^.^.^.3.# k ^.^.^.^.f.Y ( / ~ ~ ~ ~ ~ ",
-"= = & e ^ W / W ^ > w ~.^.^.^.^.^.i.Y / ~ W ^ e 8 Q.^.^.^.^.a.# z ^.^.^.^.f.Y / ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W / W ^ > w ^.^.^.^.^.^.2.Y / ~ ~ ) e 8 Q.^.^.^.^.s.# z ^.^.^.^.d.P ( ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W W W ^ > q ^.^.^.^.^.^.p.Y / ~ ~ ^ e 9 Q.^.^.^.^.a.@ z ^.^.^.^.f.U / ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W / W ) 7 9 Q.^.^.^.^.^.a.P / ~ W ) , 9 Q.^.^.^.^.3.# z ^.^.~.^.f.P ^ ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W / W ) r 5 T.^.^.^.^.^.d.Y / ~ W ) > q ~.^.^.^.^.1.# k ^.^.^.^.f.Y ( ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ / / W ) i 2 I.^.^.^.^.^.h.P ( ~ W ( > g ^.^.^.^.^.:.# z ^.^.^.^.f.P / ~ ~ ~ ~ ~ ~ ",
-"= = & e ( W / W ) m O Z.^.^.^.^.^.x.P / ~ ~ ( ; j ^.^.^.^.~.&.- k ^.^.~.^.f.P / ~ ~ ~ ~ ~ ~ ",
-"= = & e ( W / W ) F o y.^.~.^.^.^.N.U ( ~ ~ W $ b ^.^.^.^.R._ - k ^.^.^.^.f.Y ( ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ ^ J X 4.^.^.^.^.^.L.~ ~ W ^ T X #.^.^.^.^.F.~ ; j ^.^.^.^.f.U ( ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ ~ ~ ~ / ^ % l ^.^.^.^.^.!. .R ^ ^ G . r.^.~.^.^.j.E : j ^.^.^.^.f.P ) ( ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ W ) u = U.^.^.^.^.^.1.Y ! ) a & K.^.^.^.^.;.~ : j ^.^.~.^.z.M I I / ~ ~ W ~ ",
-"= = & e ( W ~ ~ W ( G . q.^.^.^.^.^.D.U ^ ! X o.^.^.^.^.P.~ ^ > g ^.^.^.^.E.-.$.m.X.W ~ ~ ~ ",
-"= = & e ^ / ~ ~ ^ ! ( > w ~.^.^.^.^.^.h.T > j T.^.^.~.^.a.Y _ i 3 U.^.^.^.^.^.^.^.X.R ~ ~ ~ ",
-"= = & e ^ / ~ ~ W W ^ H . 9.^.~.^.^.^.^.K.C.~.^.^.^.^.H.W W ^ T . q.^.~.^.^.^.^.^.X.R ~ ~ ~ ",
-"= = + e ^ W / ~ W W W ) m + B.^.~.^.^.^.^.^.^.^.^.^.E.X.Y ( W ^ B 6 y.^.^.^.E.D.2.( ~ ~ ~ ~ ",
-"= = * e ^ ! / ! W ^ W W ) a 4 b.^.^.^.^.^.^.^.^.^.P...Y ( ! W ! ^ W Z [ *.X.{ Y U ~ ~ ~ ~ ~ ",
-"= = & e ( W ~ ~ W / W / W ) A < +.A.~.^.^.^.^.!.p.W R ~ ~ ~ ~ ~ W / ) E U W W / ^ ~ ~ ~ ~ ~ ",
-"= = & e ^ W ~ ~ / W / / / W ( _ Z X 6.^.^.^.^.E.W ~ ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ / ~ ~ ~ ~ ~ ~ ~ ~ ",
-"= = & e ^ ~ ~ ~ W W / W ~ ~ ~ ~ ) ; h ^.^.^.^.^.d.M U ~ / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ",
-"= = & e ^ W ~ ~ ^ W W / ~ ~ ~ W ) p + S.^.^.^.^.~.M.f. .W ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ .",
-"= = & e ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( T O +.^.~.^.^.^.^.^.&.Y ( ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( Y 2.",
-"= = & e ( W ~ ~ ~ ~ ~ ~ ~ ~ ~ / W ) N + b.^.^.^.^.^.^.&.R ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W /.",
-"= = & e ^ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W ^ N 7 r.W.^.^.^.!.X.W ~ ~ W ~ W ~ ~ ~ ~ ~ ~ / ( ( K p./.",
-"= = & e ( W ~ ~ W ~ ~ ~ ~ ~ ~ ~ ~ ~ W ( W C Q &.:.X.| ~ ~ ~ ~ W ~ / ~ ( / ( ~ W E U P 1././.",
-"= = + e ^ / / / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W / ) ^ R Y W W ~ ~ ( / ( / W R Y Y U R ( X.,././././.",
-"= = * e ( / ~ / ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ W W W ! ( ( ( W W E U P Y W ( X.,.d./././././././././.",
-"= = * e ( W ~ ~ ~ ~ W ! ~ W ~ W ~ ( ( / ^ W W U Y P W ( X.,.d./././././././././././././././.",
-"8 $ * e ( W ~ ~ ~ ! ( ( ( / ( W R Y Y Y R ( X.>.d./././././././././././././././././././././.",
-"/.d . y ^ / / / ( W Y Y P P W ( X.>.d./././././././././././././././././././././././././././.",
-"/./.h : ^ R R R W ( X.<.f./././././././././././././././././././././././././././././././././.",
-"/././.] _ *.3./././././././././././././././././././././././././././././././././././././././."
-};
-
-class EvalMessageBox : public QDialog
-{
-public:
- EvalMessageBox(bool expired)
- {
- setWindowTitle(QLatin1String(" "));
-
- QString str = expired ? QLatin1String(boilerplate_expired) : qt_eval_string();
- str = str.trimmed();
-
- QFrame *border = new QFrame(this);
-
- QLabel *pixmap_label = new QLabel(border);
- pixmap_label->setPixmap(QPixmap(qtlogo_eval_xpm));
- pixmap_label->setAlignment(Qt::AlignTop);
-
- QLabel *text_label = new QLabel(str, border);
-
- QHBoxLayout *pm_and_text_layout = new QHBoxLayout();
- pm_and_text_layout->addWidget(pixmap_label);
- pm_and_text_layout->addWidget(text_label);
-
- QVBoxLayout *master_layout = new QVBoxLayout(border);
- master_layout->addLayout(pm_and_text_layout);
-
- QVBoxLayout *border_layout = new QVBoxLayout(this);
- border_layout->setMargin(0);
- border_layout->addWidget(border);
-
- if (expired) {
- QPushButton *cmd = new QPushButton(QLatin1String("OK"), border);
- cmd->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- cmd->setDefault(true);
-
- QHBoxLayout *button_layout = new QHBoxLayout();
- master_layout->addLayout(button_layout);
- button_layout->addWidget(cmd);
-
- connect(cmd, SIGNAL(clicked()), this, SLOT(close()));
- } else {
- border->setFrameShape(QFrame::WinPanel);
- border->setFrameShadow(QFrame::Raised);
- setParent(parentWidget(), Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
- QTimer::singleShot(7000, this, SLOT(close()));
- setAttribute(Qt::WA_DeleteOnClose);
- setAttribute(Qt::WA_QuitOnClose, false);
- }
-
- setFixedSize(sizeHint());
- }
-};
-
-class QGuiFuriCuri : public QCoreFuriCuri
-{
-public:
- void timerEvent(QTimerEvent *e) {
- if (e->timerId() == warn) {
- killTimer(warn);
- QMessageBox::information(0, QLatin1String("Automatic Timeout"), QLatin1String(will_shutdown_1min));
- kill = startTimer(KILL_DELAY);
- } else if (e->timerId() == kill) {
- killTimer(kill);
- QMessageBox::information(0, QLatin1String("Automatic Timeout"), QLatin1String(will_shutdown_now));
- qApp->quit();
- }
- }
-};
-
-
-void qt_gui_eval_init(QCoreApplicationPrivate::Type type)
-{
- Q_UNUSED(type);
-
- if (!qt_eval_is_supported())
- return;
-
- if (qt_eval_is_expired()) {
- EvalMessageBox box(true);
- box.exec();
- ::exit(0);
- } else {
- Q_UNUSED(new QGuiFuriCuri());
- }
-}
-
-static QString qt_eval_title_prefix()
-{
- return QLatin1String("[Qt Evaluation] ");
-}
-
-QString qt_eval_adapt_window_title(const QString &title)
-{
- if (!qt_eval_is_supported())
- return title;
- return qt_eval_title_prefix() + title;
-}
-
-void qt_eval_init_widget(QWidget *w)
-{
- if (!qt_eval_is_supported())
- return;
- if (w->isTopLevel() && w->windowTitle().isEmpty() && w->windowType() != Qt::Desktop ) {
- w->setWindowTitle(QLatin1String(" "));
- }
-}
-#endif
-
-QT_END_NAMESPACE
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index d5b8825972..5e1447aaa9 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -458,6 +458,7 @@ void QMimeBinaryProvider::addAllMimeTypes(QList<QMimeType> &result)
void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
{
#ifdef QT_NO_XMLSTREAMREADER
+ Q_UNUSED(data);
qWarning("Cannot load mime type since QXmlStreamReader is not available.");
return;
#else
diff --git a/src/corelib/mimetypes/qmimetypeparser.cpp b/src/corelib/mimetypes/qmimetypeparser.cpp
index d10575cfe9..815e0aa03b 100644
--- a/src/corelib/mimetypes/qmimetypeparser.cpp
+++ b/src/corelib/mimetypes/qmimetypeparser.cpp
@@ -194,8 +194,9 @@ static CreateMagicMatchRuleResult createMagicMatchRule(const QXmlStreamAttribute
bool QMimeTypeParserBase::parse(QIODevice *dev, const QString &fileName, QString *errorMessage)
{
#ifdef QT_NO_XMLSTREAMREADER
+ Q_UNUSED(dev);
if (errorMessage)
- *errorMessage = QString::fromLatin1("QXmlStreamReader is not available, cannot parse.");
+ *errorMessage = QString::fromLatin1("QXmlStreamReader is not available, cannot parse '%1'.").arg(fileName);
return false;
#else
QMimeTypePrivate data;
diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp
index ead6ed5083..3ea518907b 100644
--- a/src/corelib/serialization/qdatastream.cpp
+++ b/src/corelib/serialization/qdatastream.cpp
@@ -561,6 +561,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_11 Same as Qt_5_6
\value Qt_5_12 Version 18 (Qt 5.12)
\value Qt_5_13 Version 19 (Qt 5.13)
+ \value Qt_5_14 Same as Qt_5_13
\omitvalue Qt_DefaultCompiledVersion
\sa setVersion(), version()
diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h
index 81134f74b0..6e358df02e 100644
--- a/src/corelib/serialization/qdatastream.h
+++ b/src/corelib/serialization/qdatastream.h
@@ -100,10 +100,11 @@ public:
Qt_5_11 = Qt_5_10,
Qt_5_12 = 18,
Qt_5_13 = 19,
-#if QT_VERSION >= 0x050e00
+ Qt_5_14 = Qt_5_13,
+#if QT_VERSION >= 0x050f00
#error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
#endif
- Qt_DefaultCompiledVersion = Qt_5_13
+ Qt_DefaultCompiledVersion = Qt_5_14
};
enum ByteOrder {
diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h
index ded102d32d..5b2c7ab112 100644
--- a/src/corelib/thread/qorderedmutexlocker_p.h
+++ b/src/corelib/thread/qorderedmutexlocker_p.h
@@ -58,6 +58,8 @@
QT_BEGIN_NAMESPACE
+#if QT_CONFIG(thread)
+
/*
Locks 2 mutexes in a defined order, avoiding a recursive lock if
we're trying to lock the same mutex twice.
@@ -65,9 +67,9 @@ QT_BEGIN_NAMESPACE
class QOrderedMutexLocker
{
public:
- QOrderedMutexLocker(QMutex *m1, QMutex *m2)
- : mtx1((m1 == m2) ? m1 : (std::less<QMutex *>()(m1, m2) ? m1 : m2)),
- mtx2((m1 == m2) ? 0 : (std::less<QMutex *>()(m1, m2) ? m2 : m1)),
+ QOrderedMutexLocker(QBasicMutex *m1, QBasicMutex *m2)
+ : mtx1((m1 == m2) ? m1 : (std::less<QBasicMutex *>()(m1, m2) ? m1 : m2)),
+ mtx2((m1 == m2) ? 0 : (std::less<QBasicMutex *>()(m1, m2) ? m2 : m1)),
locked(false)
{
relock();
@@ -95,12 +97,12 @@ public:
}
}
- static bool relock(QMutex *mtx1, QMutex *mtx2)
+ static bool relock(QBasicMutex *mtx1, QBasicMutex *mtx2)
{
// mtx1 is already locked, mtx2 not... do we need to unlock and relock?
if (mtx1 == mtx2)
return false;
- if (std::less<QMutex *>()(mtx1, mtx2)) {
+ if (std::less<QBasicMutex *>()(mtx1, mtx2)) {
mtx2->lock();
return true;
}
@@ -113,10 +115,58 @@ public:
}
private:
- QMutex *mtx1, *mtx2;
+ QBasicMutex *mtx1, *mtx2;
bool locked;
};
+class QBasicMutexLocker
+{
+public:
+ inline explicit QBasicMutexLocker(QBasicMutex *m) QT_MUTEX_LOCK_NOEXCEPT
+ : m(m), isLocked(true)
+ {
+ m->lock();
+ }
+ inline ~QBasicMutexLocker() { if (isLocked) unlock(); }
+
+ inline void unlock() Q_DECL_NOTHROW
+ {
+ isLocked = false;
+ m->unlock();
+ }
+
+ inline void relock() QT_MUTEX_LOCK_NOEXCEPT
+ {
+ isLocked = true;
+ m->lock();
+ }
+
+private:
+ Q_DISABLE_COPY(QBasicMutexLocker)
+
+ QBasicMutex *m;
+ bool isLocked;
+};
+
+#else
+
+class QOrderedMutexLocker
+{
+public:
+ QOrderedMutexLocker(QBasicMutex *, QBasicMutex *) {}
+ ~QOrderedMutexLocker() {}
+
+ void relock() {}
+ void unlock() {}
+
+ static bool relock(QBasicMutex *, QBasicMutex *) {}
+};
+
+using QBasicMutexLocker = QMutexLocker;
+
+#endif
+
+
QT_END_NAMESPACE
#endif
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 0f27071176..8bf20350d6 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -4136,10 +4136,9 @@ ushort QByteArray::toUShort(bool *ok, int base) const
double QByteArray::toDouble(bool *ok) const
{
- QByteArray nulled = nulTerminated();
bool nonNullOk = false;
int processed = 0;
- double d = qt_asciiToDouble(nulled.constData(), nulled.length(),
+ double d = qt_asciiToDouble(constData(), size(),
nonNullOk, processed, WhitespacesAllowed);
if (ok)
*ok = nonNullOk;
diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/tools/qcollator.cpp
index 76dcf35833..d73eb0d07c 100644
--- a/src/corelib/tools/qcollator.cpp
+++ b/src/corelib/tools/qcollator.cpp
@@ -59,20 +59,21 @@ QT_BEGIN_NAMESPACE
\ingroup string-processing
\ingroup shared
- QCollator is initialized with a QLocale and an optional collation strategy. It tries to
- initialize the collator with the specified values. The collator can then be used to compare
- and sort strings in a locale dependent fashion.
+ QCollator is initialized with a QLocale and an optional collation strategy.
+ It tries to initialize the collator with the specified values. The collator
+ can then be used to compare and sort strings in a locale dependent fashion.
- A QCollator object can be used together with template based sorting algorithms such as std::sort
- to sort a list of QStrings.
+ A QCollator object can be used together with template based sorting
+ algorithms such as std::sort to sort a list of QStrings.
- In addition to the locale and collation strategy, several optional flags can be set that influence
- the result of the collation.
+ In addition to the locale and collation strategy, several optional flags can
+ be set that influence the result of the collation.
*/
/*!
- Constructs a QCollator from \a locale. If \a locale is not specified
- the system's default locale is used.
+ Constructs a QCollator for \a locale.
+
+ If \a locale is not specified, the system's default locale is used.
\sa setLocale()
*/
@@ -128,9 +129,9 @@ QCollator &QCollator::operator=(const QCollator &other)
Move constructor. Moves from \a other into this collator.
- Note that a moved-from QCollator can only be destroyed or assigned
- to. The effect of calling other functions than the destructor or
- one of the assignment operators is undefined.
+ Note that a moved-from QCollator can only be destroyed or assigned to.
+ The effect of calling other functions than the destructor or one of the
+ assignment operators is undefined.
*/
/*!
@@ -138,9 +139,9 @@ QCollator &QCollator::operator=(const QCollator &other)
Move-assigns from \a other to this collator.
- Note that a moved-from QCollator can only be destroyed or assigned
- to. The effect of calling other functions than the destructor or
- one of the assignment operators is undefined.
+ Note that a moved-from QCollator can only be destroyed or assigned to.
+ The effect of calling other functions than the destructor or one of the
+ assignment operators is undefined.
*/
/*!
@@ -218,7 +219,8 @@ Qt::CaseSensitivity QCollator::caseSensitivity() const
Enables numeric sorting mode when \a on is set to true.
- This will enable proper sorting of numeric digits, so that e.g. 100 sorts after 99.
+ This will enable proper sorting of numeric digits, so that e.g. 100 sorts
+ after 99.
By default this mode is off.
@@ -248,11 +250,13 @@ bool QCollator::numericMode() const
/*!
\fn void QCollator::setIgnorePunctuation(bool on)
- If \a on is set to true, punctuation characters and symbols are ignored when determining sort order.
+ If \a on is set to true, punctuation characters and symbols are ignored when
+ determining sort order.
The default is locale dependent.
- \note This method is not currently supported if Qt is configured to not use ICU on Linux.
+ \note This method is not currently supported if Qt is configured to not use
+ ICU on Linux.
\sa ignorePunctuation()
*/
@@ -268,7 +272,8 @@ void QCollator::setIgnorePunctuation(bool on)
/*!
\fn bool QCollator::ignorePunctuation() const
- Returns \c true if punctuation characters and symbols are ignored when determining sort order.
+ Returns \c true if punctuation characters and symbols are ignored when
+ determining sort order.
\sa setIgnorePunctuation()
*/
@@ -278,35 +283,66 @@ bool QCollator::ignorePunctuation() const
}
/*!
- \fn int QCollator::compare(const QString &s1, const QString &s2) const
+ \since 5.13
+ \fn bool QCollator::operator()(QStringView s1, QStringView s2) const
+ \internal
+*/
+
+/*!
+ \since 5.13
+ \fn int QCollator::compare(QStringView s1, QStringView s2) const
- Compares \a s1 with \a s2. Returns an integer less than, equal to, or greater than zero
- depending on whether \a s1 is smaller, equal or larger than \a s2.
- */
+ Compares \a s1 with \a s2.
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether \a s1 sorts before, with or after \a s2.
+*/
+#if QT_STRINGVIEW_LEVEL < 2
/*!
\fn bool QCollator::operator()(const QString &s1, const QString &s2) const
\internal
*/
/*!
- \fn int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
\overload
- Compares \a s1 with \a s2. Returns an integer less than, equal to, or greater than zero
- depending on whether \a s1 is smaller, equal or larger than \a s2.
+ Compares \a s1 with \a s2.
+
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether \a s1 sorts before, with or after \a s2.
+*/
+int QCollator::compare(const QString &s1, const QString &s2) const
+{
+ return compare(QStringView(s1), QStringView(s2));
+}
+
+/*!
+ \overload
+
+ Compares \a s1 with \a s2.
+
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether \a s1 sorts before, with or after \a s2.
*/
+int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
+{
+ return compare(QStringView(s1), QStringView(s2));
+}
/*!
- \fn int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
\overload
- Compares \a s1 with \a s2. \a len1 and \a len2 specify the length of the
- QChar arrays pointer to by \a s1 and \a s2.
+ Compares \a s1 with \a s2. \a len1 and \a len2 specify the lengths of the
+ QChar arrays pointed to by \a s1 and \a s2.
- Returns an integer less than, equal to, or greater than zero
- depending on whether \a s1 is smaller, equal or larger than \a s2.
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether \a s1 sorts before, with or after \a s2.
*/
+int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
+{
+ return compare(QStringView(s1, len1), QStringView(s2, len2));
+}
+#endif // QT_STRINGVIEW_LEVEL < 2
/*!
\fn QCollatorSortKey QCollator::sortKey(const QString &string) const
@@ -314,9 +350,9 @@ bool QCollator::ignorePunctuation() const
Returns a sortKey for \a string.
Creating the sort key is usually somewhat slower, than using the compare()
- methods directly. But if the string is compared repeatedly (e.g. when sorting
- a whole list of strings), it's usually faster to create the sort keys for each
- string and then sort using the keys.
+ methods directly. But if the string is compared repeatedly (e.g. when
+ sorting a whole list of strings), it's usually faster to create the sort
+ keys for each string and then sort using the keys.
\note Not supported with the C (a.k.a. POSIX) locale on Darwin.
*/
@@ -328,8 +364,8 @@ bool QCollator::ignorePunctuation() const
\since 5.2
- The QCollatorSortKey class is always created by QCollator::sortKey()
- and is used for fast strings collation, for example when collating many strings.
+ The QCollatorSortKey class is always created by QCollator::sortKey() and is
+ used for fast strings collation, for example when collating many strings.
\reentrant
\ingroup i18n
@@ -398,9 +434,11 @@ QCollatorSortKey& QCollatorSortKey::operator=(const QCollatorSortKey &other)
/*!
\fn int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const
- Compares the key to \a otherKey. Returns a negative value if the key
- is less than \a otherKey, 0 if the key is equal to \a otherKey or a
- positive value if the key is greater than \a otherKey.
+ Compares this key to \a otherKey.
+
+ Returns a negative value if the key is less than \a otherKey, 0 if the key
+ is equal to \a otherKey or a positive value if the key is greater than \a
+ otherKey.
\sa operator<()
*/
diff --git a/src/corelib/tools/qcollator.h b/src/corelib/tools/qcollator.h
index 6fa199cb0f..700de739bb 100644
--- a/src/corelib/tools/qcollator.h
+++ b/src/corelib/tools/qcollator.h
@@ -109,12 +109,18 @@ public:
void setIgnorePunctuation(bool on);
bool ignorePunctuation() const;
+#if QT_STRINGVIEW_LEVEL < 2
int compare(const QString &s1, const QString &s2) const;
int compare(const QStringRef &s1, const QStringRef &s2) const;
int compare(const QChar *s1, int len1, const QChar *s2, int len2) const;
bool operator()(const QString &s1, const QString &s2) const
{ return compare(s1, s2) < 0; }
+#endif
+ int compare(QStringView s1, QStringView s2) const;
+
+ bool operator()(QStringView s1, QStringView s2) const
+ { return compare(s1, s2) < 0; }
QCollatorSortKey sortKey(const QString &string) const;
diff --git a/src/corelib/tools/qcollator_icu.cpp b/src/corelib/tools/qcollator_icu.cpp
index ab45b9a1a1..8acda45070 100644
--- a/src/corelib/tools/qcollator_icu.cpp
+++ b/src/corelib/tools/qcollator_icu.cpp
@@ -78,7 +78,8 @@ void QCollatorPrivate::init()
// and does case sensitive comparison.
// UCOL_QUATERNARY is used as default in a few languages such as Japanese to take care of some
// additional differences in those languages.
- UColAttributeValue val = (caseSensitivity == Qt::CaseSensitive) ? UCOL_DEFAULT_STRENGTH : UCOL_SECONDARY;
+ UColAttributeValue val = (caseSensitivity == Qt::CaseSensitive)
+ ? UCOL_DEFAULT_STRENGTH : UCOL_SECONDARY;
status = U_ZERO_ERROR;
ucol_setAttribute(collator, UCOL_STRENGTH, val, &status);
@@ -91,7 +92,8 @@ void QCollatorPrivate::init()
qWarning("ucol_setAttribute: numeric collation failed: %d", status);
status = U_ZERO_ERROR;
- ucol_setAttribute(collator, UCOL_ALTERNATE_HANDLING, ignorePunctuation ? UCOL_SHIFTED : UCOL_NON_IGNORABLE, &status);
+ ucol_setAttribute(collator, UCOL_ALTERNATE_HANDLING,
+ ignorePunctuation ? UCOL_SHIFTED : UCOL_NON_IGNORABLE, &status);
if (U_FAILURE(status))
qWarning("ucol_setAttribute: Alternate handling failed: %d", status);
@@ -105,37 +107,20 @@ void QCollatorPrivate::cleanup()
collator = nullptr;
}
-int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
+int QCollator::compare(QStringView s1, QStringView s2) const
{
if (d->dirty)
d->init();
- if (d->collator)
- return ucol_strcoll(d->collator, (const UChar *)s1, len1, (const UChar *)s2, len2);
-
- return QString::compare_helper(s1, len1, s2, len2, d->caseSensitivity);
-}
-
-int QCollator::compare(const QString &s1, const QString &s2) const
-{
- if (d->dirty)
- d->init();
-
- if (d->collator)
- return compare(s1.constData(), s1.size(), s2.constData(), s2.size());
-
- return QString::compare(s1, s2, d->caseSensitivity);
-}
-
-int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
-{
- if (d->dirty)
- d->init();
-
- if (d->collator)
- return compare(s1.constData(), s1.size(), s2.constData(), s2.size());
+ if (d->collator) {
+ return ucol_strcoll(d->collator,
+ reinterpret_cast<const UChar *>(s1.data()), s1.size(),
+ reinterpret_cast<const UChar *>(s2.data()), s2.size());
+ }
- return QStringRef::compare(s1, s2, d->caseSensitivity);
+ return QString::compare_helper(s1.data(), s1.size(),
+ s2.data(), s2.size(),
+ d->caseSensitivity);
}
QCollatorSortKey QCollator::sortKey(const QString &string) const
diff --git a/src/corelib/tools/qcollator_macx.cpp b/src/corelib/tools/qcollator_macx.cpp
index 42e67e0c12..071d7c048f 100644
--- a/src/corelib/tools/qcollator_macx.cpp
+++ b/src/corelib/tools/qcollator_macx.cpp
@@ -65,12 +65,12 @@ void QCollatorPrivate::init()
return;
LocaleRef localeRef;
- int rc = LocaleRefFromLocaleString(QLocalePrivate::get(locale)->bcp47Name().constData(), &localeRef);
- if (rc != 0)
- qWarning("couldn't initialize the locale");
+ OSStatus status =
+ LocaleRefFromLocaleString(QLocalePrivate::get(locale)->bcp47Name().constData(), &localeRef);
+ if (status != 0)
+ qWarning("Couldn't initialize the locale (%d)", int(status));
UInt32 options = 0;
-
if (caseSensitivity == Qt::CaseInsensitive)
options |= kUCCollateCaseInsensitiveMask;
if (numericMode)
@@ -78,14 +78,9 @@ void QCollatorPrivate::init()
if (!ignorePunctuation)
options |= kUCCollatePunctuationSignificantMask;
- OSStatus status = UCCreateCollator(
- localeRef,
- 0,
- options,
- &collator
- );
+ status = UCCreateCollator(localeRef, 0, options, &collator);
if (status != 0)
- qWarning("Couldn't initialize the collator");
+ qWarning("Couldn't initialize the collator (%d)", int(status));
dirty = false;
}
@@ -97,18 +92,18 @@ void QCollatorPrivate::cleanup()
collator = 0;
}
-int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
+int QCollator::compare(QStringView s1, QStringView s2) const
{
if (d->dirty)
d->init();
if (!d->collator)
- return QStringView(s1, len1).compare(QStringView(s2, len2), caseSensitivity());
+ return s1.compare(s2, caseSensitivity());
SInt32 result;
Boolean equivalent;
UCCompareText(d->collator,
- reinterpret_cast<const UniChar *>(s1), len1,
- reinterpret_cast<const UniChar *>(s2), len2,
+ reinterpret_cast<const UniChar *>(s1.data()), s1.size(),
+ reinterpret_cast<const UniChar *>(s2.data()), s2.size(),
&equivalent,
&result);
if (equivalent)
@@ -116,16 +111,6 @@ int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) con
return result < 0 ? -1 : 1;
}
-int QCollator::compare(const QString &str1, const QString &str2) const
-{
- return compare(str1.constData(), str1.size(), str2.constData(), str2.size());
-}
-
-int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
-{
- return compare(s1.constData(), s1.size(), s2.constData(), s2.size());
-}
-
QCollatorSortKey QCollator::sortKey(const QString &string) const
{
if (d->dirty)
@@ -139,13 +124,14 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const
//Documentation recommends having it 5 times as big as the input
QVector<UCCollationValue> ret(string.size() * 5);
ItemCount actualSize;
- int status = UCGetCollationKey(d->collator, reinterpret_cast<const UniChar *>(string.constData()), string.count(),
- ret.size(), &actualSize, ret.data());
+ int status = UCGetCollationKey(d->collator,
+ reinterpret_cast<const UniChar *>(string.constData()),
+ string.count(), ret.size(), &actualSize, ret.data());
- ret.resize(actualSize+1);
+ ret.resize(actualSize + 1);
if (status == kUCOutputBufferTooSmall) {
- UCGetCollationKey(d->collator, reinterpret_cast<const UniChar *>(string.constData()), string.count(),
- ret.size(), &actualSize, ret.data());
+ UCGetCollationKey(d->collator, reinterpret_cast<const UniChar *>(string.constData()),
+ string.count(), ret.size(), &actualSize, ret.data());
}
ret[actualSize] = 0;
return QCollatorSortKey(new QCollatorSortKeyPrivate(std::move(ret)));
diff --git a/src/corelib/tools/qcollator_posix.cpp b/src/corelib/tools/qcollator_posix.cpp
index 81f97a02e1..9cbc539ebe 100644
--- a/src/corelib/tools/qcollator_posix.cpp
+++ b/src/corelib/tools/qcollator_posix.cpp
@@ -65,7 +65,7 @@ void QCollatorPrivate::cleanup()
{
}
-static void stringToWCharArray(QVarLengthArray<wchar_t> &ret, const QString &string)
+static void stringToWCharArray(QVarLengthArray<wchar_t> &ret, QStringView string)
{
ret.resize(string.length());
int len = string.toWCharArray(ret.data());
@@ -73,12 +73,7 @@ static void stringToWCharArray(QVarLengthArray<wchar_t> &ret, const QString &str
ret[len] = 0;
}
-int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
-{
- return compare(QString::fromRawData(s1, len1), QString::fromRawData(s2, len2));
-}
-
-int QCollator::compare(const QString &s1, const QString &s2) const
+int QCollator::compare(QStringView s1, QStringView s2) const
{
if (d->isC())
return s1.compare(s2, caseSensitivity());
@@ -91,11 +86,6 @@ int QCollator::compare(const QString &s1, const QString &s2) const
return std::wcscoll(array1.constData(), array2.constData());
}
-int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
-{
- return compare(s1.toString(), s2.toString());
-}
-
QCollatorSortKey QCollator::sortKey(const QString &string) const
{
if (d->dirty)
diff --git a/src/corelib/tools/qcollator_win.cpp b/src/corelib/tools/qcollator_win.cpp
index 10cfdaa264..9d81de882f 100644
--- a/src/corelib/tools/qcollator_win.cpp
+++ b/src/corelib/tools/qcollator_win.cpp
@@ -87,30 +87,30 @@ void QCollatorPrivate::cleanup()
{
}
-
-int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
+int QCollator::compare(QStringView s1, QStringView s2) const
{
if (d->isC())
- return QString::compare_helper(s1, len1, s2, len2, d->caseSensitivity);
+ return s1.compare(s2, d->caseSensitivity);
if (d->dirty)
d->init();
//* from Windows documentation *
- // Returns one of the following values if successful. To maintain the C runtime convention of
- // comparing strings, the value 2 can be subtracted from a nonzero return value. Then, the
- // meaning of <0, ==0, and >0 is consistent with the C runtime.
+ // Returns one of the following values if successful. To maintain the C
+ // runtime convention of comparing strings, the value 2 can be subtracted
+ // from a nonzero return value. Then, the meaning of <0, ==0, and >0 is
+ // consistent with the C runtime.
// [...] The function returns 0 if it does not succeed.
// https://docs.microsoft.com/en-us/windows/desktop/api/stringapiset/nf-stringapiset-comparestringex#return-value
#ifndef USE_COMPARESTRINGEX
const int ret = CompareString(d->localeID, d->collator,
- reinterpret_cast<const wchar_t*>(s1), len1,
- reinterpret_cast<const wchar_t*>(s2), len2);
+ reinterpret_cast<const wchar_t *>(s1.data()), s1.size(),
+ reinterpret_cast<const wchar_t *>(s2.data()), s2.size());
#else
const int ret = CompareStringEx(LPCWSTR(d->localeName.utf16()), d->collator,
- reinterpret_cast<LPCWSTR>(s1), len1,
- reinterpret_cast<LPCWSTR>(s2), len2,
+ reinterpret_cast<LPCWSTR>(s1.data()), s1.size(),
+ reinterpret_cast<LPCWSTR>(s2.data()), s2.size(),
nullptr, nullptr, 0);
#endif
if (Q_LIKELY(ret))
@@ -132,16 +132,6 @@ int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) con
return 0;
}
-int QCollator::compare(const QString &str1, const QString &str2) const
-{
- return compare(str1.constData(), str1.size(), str2.constData(), str2.size());
-}
-
-int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
-{
- return compare(s1.constData(), s1.size(), s2.constData(), s2.size());
-}
-
QCollatorSortKey QCollator::sortKey(const QString &string) const
{
if (d->dirty)
@@ -170,7 +160,9 @@ QCollatorSortKey QCollator::sortKey(const QString &string) const
NULL, NULL, 0);
#endif
if (finalSize == 0) {
- qWarning() << "there were problems when generating the ::sortKey by LCMapStringW with error:" << GetLastError();
+ qWarning()
+ << "there were problems when generating the ::sortKey by LCMapStringW with error:"
+ << GetLastError();
}
return QCollatorSortKey(new QCollatorSortKeyPrivate(std::move(ret)));
}
diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp
index 949f63ea15..6f3c22a6ec 100644
--- a/src/corelib/tools/qline.cpp
+++ b/src/corelib/tools/qline.cpp
@@ -805,6 +805,7 @@ qreal QLineF::angleTo(const QLineF &l) const
return delta_normalized;
}
+#if QT_DEPRECATED_SINCE(5, 14)
/*!
\fn qreal QLineF::angle(const QLineF &line) const
@@ -837,6 +838,7 @@ qreal QLineF::angle(const QLineF &l) const
if (cos_line >= -1.0 && cos_line <= 1.0) rad = qAcos( cos_line );
return rad * 360 / M_2PI;
}
+#endif
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/corelib/tools/qline.h b/src/corelib/tools/qline.h
index 6361c1af9f..14980b60a0 100644
--- a/src/corelib/tools/qline.h
+++ b/src/corelib/tools/qline.h
@@ -251,7 +251,10 @@ public:
// ### Qt 6: rename intersects() or intersection() and rename IntersectType IntersectionType
IntersectType intersect(const QLineF &l, QPointF *intersectionPoint) const;
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_X("Use angleTo() instead, take care that the return value is between 0 and 360 degree.")
qreal angle(const QLineF &l) const;
+#endif
Q_DECL_CONSTEXPR inline QPointF pointAt(qreal t) const;
inline void translate(const QPointF &p);
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 9d6e0cbdd8..98cce87464 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -2086,7 +2086,7 @@ int QString::toUcs4_helper(const ushort *uc, int length, uint *out)
\note This function does not append a null character to the array.
- \sa utf16(), toUcs4(), toLatin1(), toUtf8(), toLocal8Bit(), toStdWString()
+ \sa utf16(), toUcs4(), toLatin1(), toUtf8(), toLocal8Bit(), toStdWString(), QStringView::toWCharArray()
*/
/*! \fn QString::QString(const QString &other)
@@ -6831,6 +6831,7 @@ QString QString::toUpper_helper(QString &str)
return QUnicodeTables::convertCase<QUnicodeTables::UppercaseTraits>(str);
}
+#if QT_DEPRECATED_SINCE(5, 14)
/*!
\obsolete
@@ -6844,6 +6845,7 @@ QString &QString::sprintf(const char *cformat, ...)
va_end(ap);
return *this;
}
+#endif
// ### Qt 6: Consider whether this function shouldn't be removed See task 202871.
/*!
@@ -6889,6 +6891,7 @@ QString QString::asprintf(const char *cformat, ...)
return s;
}
+#if QT_DEPRECATED_SINCE(5, 14)
/*!
\obsolete
@@ -6898,6 +6901,7 @@ QString &QString::vsprintf(const char *cformat, va_list ap)
{
return *this = vasprintf(cformat, ap);
}
+#endif
static void append_utf8(QString &qs, const char *cs, int len)
{
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index da76601e88..e9a205dfdf 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -320,8 +320,12 @@ public:
const QString &a4, const QString &a5, const QString &a6,
const QString &a7, const QString &a8, const QString &a9) const;
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_X("Use vasprintf(), arg() or QTextStream instead")
QString &vsprintf(const char *format, va_list ap) Q_ATTRIBUTE_FORMAT_PRINTF(2, 0);
+ QT_DEPRECATED_X("Use asprintf(), arg() or QTextStream instead")
QString &sprintf(const char *format, ...) Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
+#endif
static QString vasprintf(const char *format, va_list ap) Q_ATTRIBUTE_FORMAT_PRINTF(1, 0);
static QString asprintf(const char *format, ...) Q_ATTRIBUTE_FORMAT_PRINTF(1, 2);
@@ -1017,12 +1021,7 @@ QT_WARNING_DISABLE_INTEL(111) // "statement is unreachable"
inline int QString::toWCharArray(wchar_t *array) const
{
- if (sizeof(wchar_t) == sizeof(QChar)) {
- memcpy(array, d->data(), sizeof(QChar) * size());
- return size();
- } else {
- return toUcs4_helper(d->data(), size(), reinterpret_cast<uint *>(array));
- }
+ return QStringView(*this).toWCharArray(array);
}
QT_WARNING_POP
@@ -1376,14 +1375,12 @@ inline std::wstring QString::toStdWString() const
{
std::wstring str;
str.resize(length());
-
-#ifdef Q_CC_MSVC
- // VS2005 crashes if the string is empty
- if (!length())
- return str;
+#if __cplusplus >= 201703L
+ str.resize(toWCharArray(str.data()));
+#else
+ if (length())
+ str.resize(toWCharArray(&str.front()));
#endif
-
- str.resize(toWCharArray(&(*str.begin())));
return str;
}
diff --git a/src/corelib/tools/qstringview.cpp b/src/corelib/tools/qstringview.cpp
index b97e989110..c863ca7ce2 100644
--- a/src/corelib/tools/qstringview.cpp
+++ b/src/corelib/tools/qstringview.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qstringview.h"
+#include "qstring.h"
QT_BEGIN_NAMESPACE
@@ -794,4 +795,34 @@ QT_BEGIN_NAMESPACE
\sa QString::isRightToLeft()
*/
+/*!
+ \since 5.14
+
+ Transcribes this string into the given \a array.
+
+ Caller is responsible for ensuring \a array is large enough to hold the \t
+ wchar_t encoding of this string (allocating the array with the same length
+ as the string is always sufficient). The array is encoded in UTF-16 on
+ platforms where \t wchar_t is 2 bytes wide (e.g. Windows); otherwise (Unix
+ systems), \t wchar_t is assumed to be 4 bytes wide and the data is written
+ in UCS-4.
+
+ \note This function writes no null terminator to the end of \a array.
+
+ Returns the number of \t wchar_t entries written to \a array.
+
+ \sa QString::toWCharArray()
+*/
+
+int QStringView::toWCharArray(wchar_t *array) const
+{
+ if (sizeof(wchar_t) == sizeof(QChar)) {
+ memcpy(array, data(), sizeof(QChar) * size());
+ return size();
+ } else {
+ return QString::toUcs4_helper(reinterpret_cast<const ushort *>(data()), int(size()),
+ reinterpret_cast<uint *>(array));
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstringview.h b/src/corelib/tools/qstringview.h
index 2e95c2b218..4a900b5e89 100644
--- a/src/corelib/tools/qstringview.h
+++ b/src/corelib/tools/qstringview.h
@@ -272,6 +272,8 @@ public:
Q_REQUIRED_RESULT bool isRightToLeft() const Q_DECL_NOTHROW
{ return QtPrivate::isRightToLeft(*this); }
+ Q_REQUIRED_RESULT Q_CORE_EXPORT int toWCharArray(wchar_t *array) const;
+
//
// STL compatibility API:
//
diff --git a/src/gui/configure.json b/src/gui/configure.json
index 59c06af97f..2ac06173a8 100644
--- a/src/gui/configure.json
+++ b/src/gui/configure.json
@@ -30,7 +30,6 @@
"libjpeg": { "type": "enum", "values": [ "no", "qt", "system" ] },
"libpng": { "type": "enum", "values": [ "no", "qt", "system" ] },
"linuxfb": "boolean",
- "mirclient": "boolean",
"mtdev": "boolean",
"opengl": { "type": "optionalString", "values": [ "no", "yes", "desktop", "es2", "dynamic" ] },
"opengl-es-2": { "type": "void", "name": "opengl", "value": "es2" },
@@ -395,20 +394,6 @@
{ "lib": "zlib", "condition": "features.system-zlib" }
]
},
- "mirclient": {
- "label": "Mir client libraries",
- "test": {
- "tail": "static void surfaceCreateCallback(MirSurface*, void*) {}",
- "main": [
- "u_application_lifecycle_delegate_new();",
- "mir_surface_create(0, surfaceCreateCallback, 0);"
- ]
- },
- "headers": [ "mir_toolkit/mir_client_library.h", "ubuntu/application/lifecycle_delegate.h", "EGL/egl.h" ],
- "sources": [
- { "type": "pkgConfig", "args": "egl mirclient ubuntu-platform-api libcontent-hub >= 0.2.0" }
- ]
- },
"mtdev": {
"label": "mtdev",
"test": {
@@ -1295,13 +1280,6 @@
],
"output": [ "privateFeature" ]
},
- "mirclient": {
- "label": "Mir client",
- "section": "Platform plugins",
- "autoDetect": false,
- "condition": "libs.mirclient && features.xkbcommon",
- "output": [ "privateFeature" ]
- },
"mtdev": {
"label": "mtdev",
"condition": "libs.mtdev",
@@ -1828,7 +1806,7 @@ or may depend on your system and XQuartz setup."
},
{
"type": "warning",
- "condition": "features.gui && config.linux && !config.android && !features.xcb && !features.eglfs && !features.directfb && !features.linuxfb && !features.mirclient",
+ "condition": "features.gui && config.linux && !config.android && !features.xcb && !features.eglfs && !features.directfb && !features.linuxfb",
"message": "No QPA platform plugin enabled! This will
produce a Qt that cannot run GUI applications.
See \"Platform backends\" in the output of --help."
@@ -1936,7 +1914,7 @@ QMAKE_LIBDIR_OPENGL[_ES2] and QMAKE_LIBS_OPENGL[_ES2] in the mkspec for your pla
"eglfs_openwfd", "eglfs_viv", "eglfs_viv_wl", "eglfs_rcar", "eglfs_egldevice", "eglfs_gbm", "eglfs_vsp2", "eglfs_mali", "eglfs_brcm", "eglfs_x11"
]
},
- "linuxfb", "vnc", "mirclient",
+ "linuxfb", "vnc",
{
"type": "feature",
"condition": "config.integrity",
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 18e94cf256..18125460c7 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -38,8 +38,10 @@
****************************************************************************/
#include "qimage.h"
-#include "qdatastream.h"
+
#include "qbuffer.h"
+#include "qdatastream.h"
+#include "qcolortransform.h"
#include "qmap.h"
#include "qmatrix.h"
#include "qtransform.h"
@@ -54,6 +56,7 @@
#include <stdlib.h>
#include <limits.h>
#include <qpa/qplatformpixmap.h>
+#include <private/qcolortransform_p.h>
#include <private/qdrawhelper_p.h>
#include <private/qmemrotate_p.h>
#include <private/qimagescale_p.h>
@@ -1098,6 +1101,7 @@ static void copyMetadata(QImageData *dst, const QImageData *src)
dst->dpmy = src->dpmy;
dst->devicePixelRatio = src->devicePixelRatio;
dst->text = src->text;
+ dst->colorSpace = src->colorSpace;
}
/*!
@@ -4922,6 +4926,132 @@ QTransform QImage::trueMatrix(const QTransform &matrix, int w, int h)
return matrix * QTransform().translate(-delta.x(), -delta.y());
}
+/*!
+ \since 5.14
+
+ Sets the image color space to \a colorSpace without performing any conversions on image data.
+
+ \sa colorSpace()
+*/
+void QImage::setColorSpace(const QColorSpace &colorSpace)
+{
+ if (!d)
+ return;
+ if (d->colorSpace == colorSpace)
+ return;
+ if (!isDetached()) // Detach only if shared, not for read-only data.
+ detach();
+ d->colorSpace = colorSpace;
+}
+
+/*!
+ \since 5.14
+
+ Converts the image to \a colorSpace.
+
+ If the image has no valid color space, the method does nothing.
+
+ \sa convertedToColorSpace(), setColorSpace()
+*/
+void QImage::convertToColorSpace(const QColorSpace &colorSpace)
+{
+ if (!d)
+ return;
+ if (!d->colorSpace.isValid())
+ return;
+ if (!colorSpace.isValid()) {
+ qWarning() << "QImage::convertToColorSpace: Output colorspace is not valid";
+ return;
+ }
+ detach();
+ applyColorTransform(d->colorSpace.transformationToColorSpace(colorSpace));
+ d->colorSpace = colorSpace;
+}
+
+/*!
+ \since 5.14
+
+ Returns the image converted to \a colorSpace.
+
+ If the image has no valid color space, a null QImage is returned.
+
+ \sa convertToColorSpace()
+*/
+QImage QImage::convertedToColorSpace(const QColorSpace &colorSpace) const
+{
+ if (!d || !d->colorSpace.isValid() || !colorSpace.isValid())
+ return QImage();
+ QImage image = copy();
+ image.convertToColorSpace(colorSpace);
+ return image;
+}
+
+/*!
+ \since 5.14
+
+ Returns the color space of the image if a color space is defined.
+*/
+QColorSpace QImage::colorSpace() const
+{
+ if (!d)
+ return QColorSpace::Undefined;
+ return d->colorSpace;
+}
+
+/*!
+ \since 5.14
+
+ Applies the color transformation \a transform to all pixels in the image.
+*/
+void QImage::applyColorTransform(const QColorTransform &transform)
+{
+ QImage::Format oldFormat = format();
+ if (depth() > 32) {
+ if (format() != QImage::Format_RGBX64 && format() != QImage::Format_RGBA64
+ && format() != QImage::Format_RGBA64_Premultiplied)
+ *this = std::move(*this).convertToFormat(QImage::Format_RGBA64);
+ } else if (format() != QImage::Format_ARGB32 && format() != QImage::Format_RGB32
+ && format() != QImage::Format_ARGB32_Premultiplied) {
+ if (hasAlphaChannel())
+ *this = std::move(*this).convertToFormat(QImage::Format_ARGB32);
+ else
+ *this = std::move(*this).convertToFormat(QImage::Format_RGB32);
+ }
+
+ QColorTransformPrivate::TransformFlags flags = QColorTransformPrivate::Unpremultiplied;
+ switch (format()) {
+ case Format_ARGB32_Premultiplied:
+ case Format_RGBA64_Premultiplied:
+ flags = QColorTransformPrivate::Premultiplied;
+ break;
+ case Format_RGB32:
+ case Format_RGBX64:
+ flags = QColorTransformPrivate::InputOpaque;
+ break;
+ case Format_ARGB32:
+ case Format_RGBA64:
+ break;
+ default:
+ Q_UNREACHABLE();
+ }
+
+ if (depth() > 32) {
+ for (int i = 0; i < height(); ++i) {
+ QRgba64 *scanline = reinterpret_cast<QRgba64 *>(scanLine(i));
+ transform.d_func()->apply(scanline, scanline, width(), flags);
+ }
+ } else {
+ for (int i = 0; i < height(); ++i) {
+ QRgb *scanline = reinterpret_cast<QRgb *>(scanLine(i));
+ transform.d_func()->apply(scanline, scanline, width(), flags);
+ }
+ }
+
+ if (oldFormat != format())
+ *this = std::move(*this).convertToFormat(oldFormat);
+}
+
+
bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFlags flags)
{
if (format == newFormat)
diff --git a/src/gui/image/qimage.h b/src/gui/image/qimage.h
index 45f571807c..b09e69c839 100644
--- a/src/gui/image/qimage.h
+++ b/src/gui/image/qimage.h
@@ -61,9 +61,11 @@ Q_FORWARD_DECLARE_MUTABLE_CG_TYPE(CGImage);
QT_BEGIN_NAMESPACE
+class QColorSpace;
+class QColorTransform;
class QIODevice;
-class QStringList;
class QMatrix;
+class QStringList;
class QTransform;
class QVariant;
template <class T> class QList;
@@ -296,6 +298,12 @@ public:
#endif
void invertPixels(InvertMode = InvertRgb);
+ QColorSpace colorSpace() const;
+ QImage convertedToColorSpace(const QColorSpace &) const;
+ void convertToColorSpace(const QColorSpace &);
+ void setColorSpace(const QColorSpace &);
+
+ void applyColorTransform(const QColorTransform &transform);
bool load(QIODevice *device, const char* format);
bool load(const QString &fileName, const char *format = nullptr);
diff --git a/src/gui/image/qimage_conversions.cpp b/src/gui/image/qimage_conversions.cpp
index 82ffb8af8b..837ac88470 100644
--- a/src/gui/image/qimage_conversions.cpp
+++ b/src/gui/image/qimage_conversions.cpp
@@ -39,7 +39,7 @@
#include <private/qdrawhelper_p.h>
#include <private/qguiapplication_p.h>
-#include <private/qcolorprofile_p.h>
+#include <private/qcolortrclut_p.h>
#include <private/qendian_p.h>
#include <private/qsimd_p.h>
#include <private/qimage_p.h>
@@ -100,7 +100,7 @@ const uchar *qt_get_bitflip_array()
void qGamma_correct_back_to_linear_cs(QImage *image)
{
- const QColorProfile *cp = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
+ const QColorTrcLut *cp = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
if (!cp)
return;
// gamma correct the pixels back to linear color space...
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index de12a313e8..a599fc17c9 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -51,7 +51,9 @@
// We mean it.
//
+#include <QtGui/qcolorspace.h>
#include <QtGui/private/qtguiglobal_p.h>
+#include <QtGui/qimage.h>
#include <QtCore/private/qnumeric_p.h>
#include <QMap>
@@ -106,6 +108,8 @@ struct Q_GUI_EXPORT QImageData { // internal image data
QPaintEngine *paintEngine;
+ QColorSpace colorSpace;
+
struct ImageSizeParameters {
qsizetype bytesPerLine;
qsizetype totalSize;
diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp
index 140196004b..93635a051d 100644
--- a/src/gui/image/qpnghandler.cpp
+++ b/src/gui/image/qpnghandler.cpp
@@ -42,6 +42,7 @@
#ifndef QT_NO_IMAGEFORMAT_PNG
#include <qcoreapplication.h>
+#include <qdebug.h>
#include <qiodevice.h>
#include <qimage.h>
#include <qlist.h>
@@ -50,6 +51,10 @@
#include <private/qimage_p.h> // for qt_getImageText
+#include <qcolorspace.h>
+#include <private/qcolorspace_p.h>
+#include <private/qicc_p.h>
+
#include <png.h>
#include <pngconf.h>
@@ -96,9 +101,16 @@ public:
ReadingEnd,
Error
};
+ // Defines the order of how the various ways of setting colorspace overrides eachother:
+ enum ColorSpaceState {
+ Undefined = 0,
+ GammaChrm = 1, // gAMA+cHRM chunks
+ Srgb = 2, // sRGB chunk
+ Icc = 3 // iCCP chunk
+ };
QPngHandlerPrivate(QPngHandler *qq)
- : gamma(0.0), fileGamma(0.0), quality(50), compression(50), png_ptr(0), info_ptr(0), end_info(0), state(Ready), q(qq)
+ : gamma(0.0), fileGamma(0.0), quality(50), compression(50), colorSpaceState(Undefined), png_ptr(0), info_ptr(0), end_info(0), state(Ready), q(qq)
{ }
float gamma;
@@ -108,6 +120,8 @@ public:
QString description;
QSize scaledSize;
QStringList readTexts;
+ QColorSpace colorSpace;
+ ColorSpaceState colorSpaceState;
png_struct *png_ptr;
png_info *info_ptr;
@@ -226,11 +240,8 @@ void qpiw_flush_fn(png_structp /* png_ptr */)
}
static
-void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead, float screen_gamma=0.0, float file_gamma=0.0)
+void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scaledSize, bool *doScaledRead)
{
- if (screen_gamma != 0.0 && file_gamma != 0.0)
- png_set_gamma(png_ptr, 1.0f / screen_gamma, file_gamma);
-
png_uint_32 width;
png_uint_32 height;
int bit_depth = 0;
@@ -585,10 +596,45 @@ bool QPngHandlerPrivate::readPngHeader()
readPngTexts(info_ptr);
+#ifdef PNG_iCCP_SUPPORTED
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_iCCP)) {
+ png_charp name = nullptr;
+ int compressionType = 0;
+#if (PNG_LIBPNG_VER < 10500)
+ png_charp profileData = nullptr;
+#else
+ png_bytep profileData = nullptr;
+#endif
+ png_uint_32 profLen;
+ png_get_iCCP(png_ptr, info_ptr, &name, &compressionType, &profileData, &profLen);
+ if (!QIcc::fromIccProfile(QByteArray::fromRawData((const char *)profileData, profLen), &colorSpace)) {
+ qWarning() << "QPngHandler: Failed to parse ICC profile";
+ } else {
+ colorSpaceState = Icc;
+ }
+ }
+#endif
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) {
+ int rendering_intent = -1;
+ png_get_sRGB(png_ptr, info_ptr, &rendering_intent);
+ // We don't actually care about the rendering_intent, just that it is valid
+ if (rendering_intent >= 0 && rendering_intent <= 3 && colorSpaceState <= Srgb) {
+ colorSpace = QColorSpace::SRgb;
+ colorSpaceState = Srgb;
+ }
+ }
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA)) {
double file_gamma = 0.0;
png_get_gAMA(png_ptr, info_ptr, &file_gamma);
fileGamma = file_gamma;
+ if (fileGamma > 0.0f && colorSpaceState <= GammaChrm) {
+ QColorSpacePrivate *csPrivate = colorSpace.d_func();
+ csPrivate->gamut = QColorSpace::Gamut::SRgb;
+ csPrivate->transferFunction = QColorSpace::TransferFunction::Gamma;
+ csPrivate->gamma = fileGamma;
+ csPrivate->initialize();
+ colorSpaceState = GammaChrm;
+ }
}
state = ReadHeader;
@@ -613,8 +659,19 @@ bool QPngHandlerPrivate::readPngImage(QImage *outImage)
return false;
}
+ if (gamma != 0.0 && fileGamma != 0.0) {
+ // This configuration forces gamma correction and
+ // thus changes the output colorspace
+ png_set_gamma(png_ptr, 1.0f / gamma, fileGamma);
+ QColorSpacePrivate *csPrivate = colorSpace.d_func();
+ csPrivate->transferFunction = QColorSpace::TransferFunction::Gamma;
+ csPrivate->gamma = gamma;
+ csPrivate->initialize();
+ colorSpaceState = GammaChrm;
+ }
+
bool doScaledRead = false;
- setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead, gamma, fileGamma);
+ setup_qt(*outImage, png_ptr, info_ptr, scaledSize, &doScaledRead);
if (outImage->isNull()) {
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
@@ -683,6 +740,9 @@ bool QPngHandlerPrivate::readPngImage(QImage *outImage)
if (scaledSize.isValid() && outImage->size() != scaledSize)
*outImage = outImage->scaled(scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ if (colorSpaceState > Undefined && colorSpace.isValid())
+ outImage->setColorSpace(colorSpace);
+
return true;
}
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 1f137fc46f..9c80f1e2cc 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -21,7 +21,7 @@ HEADERS += \
kernel/qplatforminputcontextplugin_p.h \
kernel/qplatformintegrationfactory_p.h \
kernel/qplatformintegrationplugin.h \
- kernel/qplatformtheme.h\
+ kernel/qplatformtheme.h \
kernel/qplatformtheme_p.h \
kernel/qplatformthemefactory_p.h \
kernel/qplatformthemeplugin.h \
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 4e0c45d8ae..7218e55627 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -68,7 +68,7 @@
#include <qpalette.h>
#include <qscreen.h>
#include "qsessionmanager.h"
-#include <private/qcolorprofile_p.h>
+#include <private/qcolortrclut_p.h>
#include <private/qscreen_p.h>
#include <QtGui/qgenericpluginfactory.h>
@@ -1643,8 +1643,6 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate()
platform_theme = 0;
delete platform_integration;
platform_integration = 0;
- delete m_a8ColorProfile.load();
- delete m_a32ColorProfile.load();
window_list.clear();
screen_list.clear();
@@ -3984,32 +3982,26 @@ void QGuiApplicationPrivate::notifyDragStarted(const QDrag *drag)
}
#endif
-const QColorProfile *QGuiApplicationPrivate::colorProfileForA8Text()
+const QColorTrcLut *QGuiApplicationPrivate::colorProfileForA8Text()
{
#ifdef Q_OS_WIN
- QColorProfile *result = m_a8ColorProfile.load();
- if (!result){
- QColorProfile *cs = QColorProfile::fromGamma(2.31); // This is a hard-coded thing for Windows text rendering
- if (!m_a8ColorProfile.testAndSetRelease(0, cs))
- delete cs;
- result = m_a8ColorProfile.load();
+ if (!m_a8ColorProfile){
+ QColorTrcLut *cs = QColorTrcLut::fromGamma(2.31); // This is a hard-coded thing for Windows text rendering
+ m_a8ColorProfile.reset(cs);
}
- return result;
+ return m_a8ColorProfile.get();
#else
return colorProfileForA32Text();
#endif
}
-const QColorProfile *QGuiApplicationPrivate::colorProfileForA32Text()
+const QColorTrcLut *QGuiApplicationPrivate::colorProfileForA32Text()
{
- QColorProfile *result = m_a32ColorProfile.load();
- if (!result){
- QColorProfile *cs = QColorProfile::fromGamma(fontSmoothingGamma);
- if (!m_a32ColorProfile.testAndSetRelease(0, cs))
- delete cs;
- result = m_a32ColorProfile.load();
+ if (!m_a32ColorProfile) {
+ QColorTrcLut *cs = QColorTrcLut::fromGamma(fontSmoothingGamma);
+ m_a32ColorProfile.reset(cs);
}
- return result;
+ return m_a32ColorProfile.get();
}
void QGuiApplicationPrivate::_q_updateFocusObject(QObject *object)
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index 63646dcd50..61d9661286 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -55,6 +55,7 @@
#include <QtGui/qguiapplication.h>
#include <QtCore/QPointF>
+#include <QtCore/QSharedPointer>
#include <QtCore/private/qcoreapplication_p.h>
#include <QtCore/private/qthread_p.h>
@@ -66,7 +67,7 @@
QT_BEGIN_NAMESPACE
-class QColorProfile;
+class QColorTrcLut;
class QPlatformIntegration;
class QPlatformTheme;
class QPlatformDragQtResponse;
@@ -299,8 +300,8 @@ public:
static QInputDeviceManager *inputDeviceManager();
- const QColorProfile *colorProfileForA8Text();
- const QColorProfile *colorProfileForA32Text();
+ const QColorTrcLut *colorProfileForA8Text();
+ const QColorTrcLut *colorProfileForA32Text();
// hook reimplemented in QApplication to apply the QStyle function on the QIcon
virtual QPixmap applyQIconStyleHelper(QIcon::Mode, const QPixmap &basePixmap) const { return basePixmap; }
@@ -327,8 +328,8 @@ private:
static QGuiApplicationPrivate *self;
static QTouchDevice *m_fakeTouchDevice;
static int m_fakeMouseSourcePointId;
- QAtomicPointer<QColorProfile> m_a8ColorProfile;
- QAtomicPointer<QColorProfile> m_a32ColorProfile;
+ QSharedPointer<QColorTrcLut> m_a8ColorProfile;
+ QSharedPointer<QColorTrcLut> m_a32ColorProfile;
bool ownGlobalShareContext;
diff --git a/src/gui/opengl/qopengles2ext.h b/src/gui/opengl/qopengles2ext.h
index 8ff50a924e..8517e24267 100644
--- a/src/gui/opengl/qopengles2ext.h
+++ b/src/gui/opengl/qopengles2ext.h
@@ -1,5 +1,5 @@
-#ifndef __gl2ext_h_
-#define __gl2ext_h_ 1
+#ifndef __gles2_gl2ext_h_
+#define __gles2_gl2ext_h_ 1
#if 0
#pragma qt_no_master_include
@@ -25,7 +25,7 @@ typedef struct __GLsync *GLsync;
#endif
/*
-** Copyright (c) 2013-2017 The Khronos Group Inc.
+** Copyright (c) 2013-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
@@ -57,7 +57,7 @@ typedef struct __GLsync *GLsync;
#define GL_APIENTRYP GL_APIENTRY*
#endif
-/* Generated on date 20170331 */
+/* Generated on date 20190228 */
/* Generated C header for:
* API: gles2
@@ -178,6 +178,16 @@ GL_APICALL void GL_APIENTRY glGetPointervKHR (GLenum pname, void **params);
#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
#endif /* GL_KHR_no_error */
+#ifndef GL_KHR_parallel_shader_compile
+#define GL_KHR_parallel_shader_compile 1
+#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0
+#define GL_COMPLETION_STATUS_KHR 0x91B1
+typedef void (GL_APIENTRYP PFNGLMAXSHADERCOMPILERTHREADSKHRPROC) (GLuint count);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMaxShaderCompilerThreadsKHR (GLuint count);
+#endif
+#endif /* GL_KHR_parallel_shader_compile */
+
#ifndef GL_KHR_robust_buffer_access_behavior
#define GL_KHR_robust_buffer_access_behavior 1
#endif /* GL_KHR_robust_buffer_access_behavior */
@@ -343,12 +353,12 @@ GL_APICALL GLboolean GL_APIENTRY glIsEnablediOES (GLenum target, GLuint index);
typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXOESPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXOESPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
-typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXOESPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex);
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY glDrawElementsBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertexOES (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexOES (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
-GL_APICALL void GL_APIENTRY glMultiDrawElementsBaseVertexOES (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsBaseVertexEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex);
#endif
#endif /* GL_OES_draw_elements_base_vertex */
@@ -810,6 +820,22 @@ GL_APICALL void GL_APIENTRY glGetFloati_vOES (GLenum target, GLuint index, GLflo
#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE
#endif /* GL_AMD_compressed_ATC_texture */
+#ifndef GL_AMD_framebuffer_multisample_advanced
+#define GL_AMD_framebuffer_multisample_advanced 1
+#define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2
+#define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3
+#define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4
+#define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5
+#define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6
+#define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAdvancedAMD (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glNamedRenderbufferStorageMultisampleAdvancedAMD (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+#endif /* GL_AMD_framebuffer_multisample_advanced */
+
#ifndef GL_AMD_performance_monitor
#define GL_AMD_performance_monitor 1
#define GL_COUNTER_TYPE_AMD 0x8BC0
@@ -1070,6 +1096,20 @@ GL_APICALL void GL_APIENTRY glGetSyncivAPPLE (GLsync sync, GLenum pname, GLsizei
#define GL_SHADER_BINARY_DMP 0x9250
#endif /* GL_DMP_shader_binary */
+#ifndef GL_EXT_EGL_image_array
+#define GL_EXT_EGL_image_array 1
+#endif /* GL_EXT_EGL_image_array */
+
+#ifndef GL_EXT_EGL_image_storage
+#define GL_EXT_EGL_image_storage 1
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC) (GLenum target, GLeglImageOES image, const GLint* attrib_list);
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC) (GLuint texture, GLeglImageOES image, const GLint* attrib_list);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glEGLImageTargetTexStorageEXT (GLenum target, GLeglImageOES image, const GLint* attrib_list);
+GL_APICALL void GL_APIENTRY glEGLImageTargetTextureStorageEXT (GLuint texture, GLeglImageOES image, const GLint* attrib_list);
+#endif
+#endif /* GL_EXT_EGL_image_storage */
+
#ifndef GL_EXT_YUV_target
#define GL_EXT_YUV_target 1
#define GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT 0x8BE7
@@ -1141,6 +1181,20 @@ GL_APICALL void GL_APIENTRY glClearTexSubImageEXT (GLuint texture, GLint level,
#endif
#endif /* GL_EXT_clear_texture */
+#ifndef GL_EXT_clip_control
+#define GL_EXT_clip_control 1
+#define GL_LOWER_LEFT_EXT 0x8CA1
+#define GL_UPPER_LEFT_EXT 0x8CA2
+#define GL_NEGATIVE_ONE_TO_ONE_EXT 0x935E
+#define GL_ZERO_TO_ONE_EXT 0x935F
+#define GL_CLIP_ORIGIN_EXT 0x935C
+#define GL_CLIP_DEPTH_MODE_EXT 0x935D
+typedef void (GL_APIENTRYP PFNGLCLIPCONTROLEXTPROC) (GLenum origin, GLenum depth);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glClipControlEXT (GLenum origin, GLenum depth);
+#endif
+#endif /* GL_EXT_clip_control */
+
#ifndef GL_EXT_clip_cull_distance
#define GL_EXT_clip_cull_distance 1
#define GL_MAX_CLIP_DISTANCES_EXT 0x0D32
@@ -1211,6 +1265,11 @@ GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void);
#endif
#endif /* GL_EXT_debug_marker */
+#ifndef GL_EXT_depth_clamp
+#define GL_EXT_depth_clamp 1
+#define GL_DEPTH_CLAMP_EXT 0x864F
+#endif /* GL_EXT_depth_clamp */
+
#ifndef GL_EXT_discard_framebuffer
#define GL_EXT_discard_framebuffer 1
#define GL_COLOR_EXT 0x1800
@@ -1326,12 +1385,10 @@ GL_APICALL GLboolean GL_APIENTRY glIsEnablediEXT (GLenum target, GLuint index);
typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
typedef void (GL_APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXEXTPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
-typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex);
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL void GL_APIENTRY glDrawElementsBaseVertexEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
GL_APICALL void GL_APIENTRY glDrawRangeElementsBaseVertexEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex);
GL_APICALL void GL_APIENTRY glDrawElementsInstancedBaseVertexEXT (GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex);
-GL_APICALL void GL_APIENTRY glMultiDrawElementsBaseVertexEXT (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei primcount, const GLint *basevertex);
#endif
#endif /* GL_EXT_draw_elements_base_vertex */
@@ -1355,6 +1412,17 @@ GL_APICALL void GL_APIENTRY glDrawTransformFeedbackInstancedEXT (GLenum mode, GL
#endif
#endif /* GL_EXT_draw_transform_feedback */
+#ifndef GL_EXT_external_buffer
+#define GL_EXT_external_buffer 1
+typedef void *GLeglClientBufferEXT;
+typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEEXTERNALEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBufferStorageExternalEXT (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+GL_APICALL void GL_APIENTRY glNamedBufferStorageExternalEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+#endif
+#endif /* GL_EXT_external_buffer */
+
#ifndef GL_EXT_float_blend
#define GL_EXT_float_blend 1
#endif /* GL_EXT_float_blend */
@@ -1433,6 +1501,85 @@ GL_APICALL void GL_APIENTRY glFlushMappedBufferRangeEXT (GLenum target, GLintptr
#endif
#endif /* GL_EXT_map_buffer_range */
+#ifndef GL_EXT_memory_object
+#define GL_EXT_memory_object 1
+#define GL_TEXTURE_TILING_EXT 0x9580
+#define GL_DEDICATED_MEMORY_OBJECT_EXT 0x9581
+#define GL_PROTECTED_MEMORY_OBJECT_EXT 0x959B
+#define GL_NUM_TILING_TYPES_EXT 0x9582
+#define GL_TILING_TYPES_EXT 0x9583
+#define GL_OPTIMAL_TILING_EXT 0x9584
+#define GL_LINEAR_TILING_EXT 0x9585
+#define GL_NUM_DEVICE_UUIDS_EXT 0x9596
+#define GL_DEVICE_UUID_EXT 0x9597
+#define GL_DRIVER_UUID_EXT 0x9598
+#define GL_UUID_SIZE_EXT 16
+typedef void (GL_APIENTRYP PFNGLGETUNSIGNEDBYTEVEXTPROC) (GLenum pname, GLubyte *data);
+typedef void (GL_APIENTRYP PFNGLGETUNSIGNEDBYTEI_VEXTPROC) (GLenum target, GLuint index, GLubyte *data);
+typedef void (GL_APIENTRYP PFNGLDELETEMEMORYOBJECTSEXTPROC) (GLsizei n, const GLuint *memoryObjects);
+typedef GLboolean (GL_APIENTRYP PFNGLISMEMORYOBJECTEXTPROC) (GLuint memoryObject);
+typedef void (GL_APIENTRYP PFNGLCREATEMEMORYOBJECTSEXTPROC) (GLsizei n, GLuint *memoryObjects);
+typedef void (GL_APIENTRYP PFNGLMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, const GLint *params);
+typedef void (GL_APIENTRYP PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLBUFFERSTORAGEMEMEXTPROC) (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM2DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM3DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC) (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetUnsignedBytevEXT (GLenum pname, GLubyte *data);
+GL_APICALL void GL_APIENTRY glGetUnsignedBytei_vEXT (GLenum target, GLuint index, GLubyte *data);
+GL_APICALL void GL_APIENTRY glDeleteMemoryObjectsEXT (GLsizei n, const GLuint *memoryObjects);
+GL_APICALL GLboolean GL_APIENTRY glIsMemoryObjectEXT (GLuint memoryObject);
+GL_APICALL void GL_APIENTRY glCreateMemoryObjectsEXT (GLsizei n, GLuint *memoryObjects);
+GL_APICALL void GL_APIENTRY glMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, const GLint *params);
+GL_APICALL void GL_APIENTRY glGetMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glTexStorageMem2DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTexStorageMem2DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTexStorageMem3DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTexStorageMem3DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glBufferStorageMemEXT (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureStorageMem2DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureStorageMem2DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureStorageMem3DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureStorageMem3DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glNamedBufferStorageMemEXT (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset);
+#endif
+#endif /* GL_EXT_memory_object */
+
+#ifndef GL_EXT_memory_object_fd
+#define GL_EXT_memory_object_fd 1
+#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586
+typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYFDEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, GLint fd);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportMemoryFdEXT (GLuint memory, GLuint64 size, GLenum handleType, GLint fd);
+#endif
+#endif /* GL_EXT_memory_object_fd */
+
+#ifndef GL_EXT_memory_object_win32
+#define GL_EXT_memory_object_win32 1
+#define GL_HANDLE_TYPE_OPAQUE_WIN32_EXT 0x9587
+#define GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT 0x9588
+#define GL_DEVICE_LUID_EXT 0x9599
+#define GL_DEVICE_NODE_MASK_EXT 0x959A
+#define GL_LUID_SIZE_EXT 8
+#define GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT 0x9589
+#define GL_HANDLE_TYPE_D3D12_RESOURCE_EXT 0x958A
+#define GL_HANDLE_TYPE_D3D11_IMAGE_EXT 0x958B
+#define GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT 0x958C
+typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, void *handle);
+typedef void (GL_APIENTRYP PFNGLIMPORTMEMORYWIN32NAMEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, const void *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportMemoryWin32HandleEXT (GLuint memory, GLuint64 size, GLenum handleType, void *handle);
+GL_APICALL void GL_APIENTRY glImportMemoryWin32NameEXT (GLuint memory, GLuint64 size, GLenum handleType, const void *name);
+#endif
+#endif /* GL_EXT_memory_object_win32 */
+
#ifndef GL_EXT_multi_draw_arrays
#define GL_EXT_multi_draw_arrays 1
typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount);
@@ -1598,6 +1745,55 @@ GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location,
#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9
#endif /* GL_EXT_sRGB_write_control */
+#ifndef GL_EXT_semaphore
+#define GL_EXT_semaphore 1
+#define GL_LAYOUT_GENERAL_EXT 0x958D
+#define GL_LAYOUT_COLOR_ATTACHMENT_EXT 0x958E
+#define GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT 0x958F
+#define GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT 0x9590
+#define GL_LAYOUT_SHADER_READ_ONLY_EXT 0x9591
+#define GL_LAYOUT_TRANSFER_SRC_EXT 0x9592
+#define GL_LAYOUT_TRANSFER_DST_EXT 0x9593
+#define GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT 0x9530
+#define GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT 0x9531
+typedef void (GL_APIENTRYP PFNGLGENSEMAPHORESEXTPROC) (GLsizei n, GLuint *semaphores);
+typedef void (GL_APIENTRYP PFNGLDELETESEMAPHORESEXTPROC) (GLsizei n, const GLuint *semaphores);
+typedef GLboolean (GL_APIENTRYP PFNGLISSEMAPHOREEXTPROC) (GLuint semaphore);
+typedef void (GL_APIENTRYP PFNGLSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, const GLuint64 *params);
+typedef void (GL_APIENTRYP PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, GLuint64 *params);
+typedef void (GL_APIENTRYP PFNGLWAITSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts);
+typedef void (GL_APIENTRYP PFNGLSIGNALSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGenSemaphoresEXT (GLsizei n, GLuint *semaphores);
+GL_APICALL void GL_APIENTRY glDeleteSemaphoresEXT (GLsizei n, const GLuint *semaphores);
+GL_APICALL GLboolean GL_APIENTRY glIsSemaphoreEXT (GLuint semaphore);
+GL_APICALL void GL_APIENTRY glSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, const GLuint64 *params);
+GL_APICALL void GL_APIENTRY glGetSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, GLuint64 *params);
+GL_APICALL void GL_APIENTRY glWaitSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts);
+GL_APICALL void GL_APIENTRY glSignalSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts);
+#endif
+#endif /* GL_EXT_semaphore */
+
+#ifndef GL_EXT_semaphore_fd
+#define GL_EXT_semaphore_fd 1
+typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREFDEXTPROC) (GLuint semaphore, GLenum handleType, GLint fd);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportSemaphoreFdEXT (GLuint semaphore, GLenum handleType, GLint fd);
+#endif
+#endif /* GL_EXT_semaphore_fd */
+
+#ifndef GL_EXT_semaphore_win32
+#define GL_EXT_semaphore_win32 1
+#define GL_HANDLE_TYPE_D3D12_FENCE_EXT 0x9594
+#define GL_D3D12_FENCE_VALUE_EXT 0x9595
+typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC) (GLuint semaphore, GLenum handleType, void *handle);
+typedef void (GL_APIENTRYP PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC) (GLuint semaphore, GLenum handleType, const void *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glImportSemaphoreWin32HandleEXT (GLuint semaphore, GLenum handleType, void *handle);
+GL_APICALL void GL_APIENTRY glImportSemaphoreWin32NameEXT (GLuint semaphore, GLenum handleType, const void *name);
+#endif
+#endif /* GL_EXT_semaphore_win32 */
+
#ifndef GL_EXT_separate_shader_objects
#define GL_EXT_separate_shader_objects 1
#define GL_ACTIVE_PROGRAM_EXT 0x8259
@@ -1703,6 +1899,14 @@ GL_APICALL void GL_APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLin
#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
#endif /* GL_EXT_shader_framebuffer_fetch */
+#ifndef GL_EXT_shader_framebuffer_fetch_non_coherent
+#define GL_EXT_shader_framebuffer_fetch_non_coherent 1
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferFetchBarrierEXT (void);
+#endif
+#endif /* GL_EXT_shader_framebuffer_fetch_non_coherent */
+
#ifndef GL_EXT_shader_group_vote
#define GL_EXT_shader_group_vote 1
#endif /* GL_EXT_shader_group_vote */
@@ -1890,18 +2094,42 @@ GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalf
#define GL_TEXTURE_ASTC_DECODE_PRECISION_EXT 0x8F69
#endif /* GL_EXT_texture_compression_astc_decode_mode */
+#ifndef GL_EXT_texture_compression_bptc
+#define GL_EXT_texture_compression_bptc 1
+#define GL_COMPRESSED_RGBA_BPTC_UNORM_EXT 0x8E8C
+#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT 0x8E8D
+#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT 0x8E8E
+#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT 0x8E8F
+#endif /* GL_EXT_texture_compression_bptc */
+
#ifndef GL_EXT_texture_compression_dxt1
#define GL_EXT_texture_compression_dxt1 1
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
#endif /* GL_EXT_texture_compression_dxt1 */
+#ifndef GL_EXT_texture_compression_rgtc
+#define GL_EXT_texture_compression_rgtc 1
+#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
+#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
+#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
+#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
+#endif /* GL_EXT_texture_compression_rgtc */
+
#ifndef GL_EXT_texture_compression_s3tc
#define GL_EXT_texture_compression_s3tc 1
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
#endif /* GL_EXT_texture_compression_s3tc */
+#ifndef GL_EXT_texture_compression_s3tc_srgb
+#define GL_EXT_texture_compression_s3tc_srgb 1
+#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E
+#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
+#endif /* GL_EXT_texture_compression_s3tc_srgb */
+
#ifndef GL_EXT_texture_cube_map_array
#define GL_EXT_texture_cube_map_array 1
#define GL_TEXTURE_CUBE_MAP_ARRAY_EXT 0x9009
@@ -1923,12 +2151,24 @@ GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalf
#ifndef GL_EXT_texture_filter_minmax
#define GL_EXT_texture_filter_minmax 1
+#define GL_TEXTURE_REDUCTION_MODE_EXT 0x9366
+#define GL_WEIGHTED_AVERAGE_EXT 0x9367
#endif /* GL_EXT_texture_filter_minmax */
#ifndef GL_EXT_texture_format_BGRA8888
#define GL_EXT_texture_format_BGRA8888 1
#endif /* GL_EXT_texture_format_BGRA8888 */
+#ifndef GL_EXT_texture_format_sRGB_override
+#define GL_EXT_texture_format_sRGB_override 1
+#define GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT 0x8FBF
+#endif /* GL_EXT_texture_format_sRGB_override */
+
+#ifndef GL_EXT_texture_mirror_clamp_to_edge
+#define GL_EXT_texture_mirror_clamp_to_edge 1
+#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743
+#endif /* GL_EXT_texture_mirror_clamp_to_edge */
+
#ifndef GL_EXT_texture_norm16
#define GL_EXT_texture_norm16 1
#define GL_R16_EXT 0x822A
@@ -1938,6 +2178,10 @@ GL_APICALL void GL_APIENTRY glTexBufferRangeEXT (GLenum target, GLenum internalf
#define GL_RGB16_SNORM_EXT 0x8F9A
#endif /* GL_EXT_texture_norm16 */
+#ifndef GL_EXT_texture_query_lod
+#define GL_EXT_texture_query_lod 1
+#endif /* GL_EXT_texture_query_lod */
+
#ifndef GL_EXT_texture_rg
#define GL_EXT_texture_rg 1
#define GL_RED_EXT 0x1903
@@ -2019,6 +2263,16 @@ GL_APICALL void GL_APIENTRY glTextureViewEXT (GLuint texture, GLenum target, GLu
#define GL_UNPACK_SKIP_PIXELS_EXT 0x0CF4
#endif /* GL_EXT_unpack_subimage */
+#ifndef GL_EXT_win32_keyed_mutex
+#define GL_EXT_win32_keyed_mutex 1
+typedef GLboolean (GL_APIENTRYP PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key, GLuint timeout);
+typedef GLboolean (GL_APIENTRYP PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL GLboolean GL_APIENTRY glAcquireKeyedMutexWin32EXT (GLuint memory, GLuint64 key, GLuint timeout);
+GL_APICALL GLboolean GL_APIENTRY glReleaseKeyedMutexWin32EXT (GLuint memory, GLuint64 key);
+#endif
+#endif /* GL_EXT_win32_keyed_mutex */
+
#ifndef GL_EXT_window_rectangles
#define GL_EXT_window_rectangles 1
#define GL_INCLUSIVE_EXT 0x8F10
@@ -2121,6 +2375,11 @@ GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target,
#define GL_CUBIC_MIPMAP_LINEAR_IMG 0x913B
#endif /* GL_IMG_texture_filter_cubic */
+#ifndef GL_INTEL_blackhole_render
+#define GL_INTEL_blackhole_render 1
+#define GL_BLACKHOLE_RENDER_INTEL 0x83FC
+#endif /* GL_INTEL_blackhole_render */
+
#ifndef GL_INTEL_conservative_rasterization
#define GL_INTEL_conservative_rasterization 1
#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE
@@ -2163,7 +2422,7 @@ typedef void (GL_APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle);
typedef void (GL_APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId);
typedef void (GL_APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId);
typedef void (GL_APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue);
-typedef void (GL_APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten);
+typedef void (GL_APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten);
typedef void (GL_APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId);
typedef void (GL_APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask);
#ifdef GL_GLEXT_PROTOTYPES
@@ -2174,12 +2433,22 @@ GL_APICALL void GL_APIENTRY glEndPerfQueryINTEL (GLuint queryHandle);
GL_APICALL void GL_APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId);
GL_APICALL void GL_APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId);
GL_APICALL void GL_APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue);
-GL_APICALL void GL_APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten);
+GL_APICALL void GL_APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten);
GL_APICALL void GL_APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId);
GL_APICALL void GL_APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask);
#endif
#endif /* GL_INTEL_performance_query */
+#ifndef GL_MESA_framebuffer_flip_y
+#define GL_MESA_framebuffer_flip_y 1
+#define GL_FRAMEBUFFER_FLIP_Y_MESA 0x8BBB
+#endif /* GL_MESA_framebuffer_flip_y */
+
+#ifndef GL_MESA_program_binary_formats
+#define GL_MESA_program_binary_formats 1
+#define GL_PROGRAM_BINARY_FORMAT_MESA 0x875F
+#endif /* GL_MESA_program_binary_formats */
+
#ifndef GL_MESA_shader_integer_functions
#define GL_MESA_shader_integer_functions 1
#endif /* GL_MESA_shader_integer_functions */
@@ -2284,6 +2553,27 @@ GL_APICALL void GL_APIENTRY glBlendBarrierNV (void);
#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285
#endif /* GL_NV_blend_equation_advanced_coherent */
+#ifndef GL_NV_blend_minmax_factor
+#define GL_NV_blend_minmax_factor 1
+#define GL_FACTOR_MIN_AMD 0x901C
+#define GL_FACTOR_MAX_AMD 0x901D
+#endif /* GL_NV_blend_minmax_factor */
+
+#ifndef GL_NV_clip_space_w_scaling
+#define GL_NV_clip_space_w_scaling 1
+#define GL_VIEWPORT_POSITION_W_SCALE_NV 0x937C
+#define GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV 0x937D
+#define GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV 0x937E
+typedef void (GL_APIENTRYP PFNGLVIEWPORTPOSITIONWSCALENVPROC) (GLuint index, GLfloat xcoeff, GLfloat ycoeff);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glViewportPositionWScaleNV (GLuint index, GLfloat xcoeff, GLfloat ycoeff);
+#endif
+#endif /* GL_NV_clip_space_w_scaling */
+
+#ifndef GL_NV_compute_shader_derivatives
+#define GL_NV_compute_shader_derivatives 1
+#endif /* GL_NV_compute_shader_derivatives */
+
#ifndef GL_NV_conditional_render
#define GL_NV_conditional_render 1
#define GL_QUERY_WAIT_NV 0x8E13
@@ -2310,6 +2600,11 @@ GL_APICALL void GL_APIENTRY glSubpixelPrecisionBiasNV (GLuint xbits, GLuint ybit
#endif
#endif /* GL_NV_conservative_raster */
+#ifndef GL_NV_conservative_raster_pre_snap
+#define GL_NV_conservative_raster_pre_snap 1
+#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV 0x9550
+#endif /* GL_NV_conservative_raster_pre_snap */
+
#ifndef GL_NV_conservative_raster_pre_snap_triangles
#define GL_NV_conservative_raster_pre_snap_triangles 1
#define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D
@@ -2655,6 +2950,34 @@ GL_APICALL void GL_APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum
#endif
#endif /* GL_NV_internalformat_sample_query */
+#ifndef GL_NV_memory_attachment
+#define GL_NV_memory_attachment 1
+#define GL_ATTACHED_MEMORY_OBJECT_NV 0x95A4
+#define GL_ATTACHED_MEMORY_OFFSET_NV 0x95A5
+#define GL_MEMORY_ATTACHABLE_ALIGNMENT_NV 0x95A6
+#define GL_MEMORY_ATTACHABLE_SIZE_NV 0x95A7
+#define GL_MEMORY_ATTACHABLE_NV 0x95A8
+#define GL_DETACHED_MEMORY_INCARNATION_NV 0x95A9
+#define GL_DETACHED_TEXTURES_NV 0x95AA
+#define GL_DETACHED_BUFFERS_NV 0x95AB
+#define GL_MAX_DETACHED_TEXTURES_NV 0x95AC
+#define GL_MAX_DETACHED_BUFFERS_NV 0x95AD
+typedef void (GL_APIENTRYP PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC) (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params);
+typedef void (GL_APIENTRYP PFNGLRESETMEMORYOBJECTPARAMETERNVPROC) (GLuint memory, GLenum pname);
+typedef void (GL_APIENTRYP PFNGLTEXATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLBUFFERATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLTEXTUREATTACHMEMORYNVPROC) (GLuint texture, GLuint memory, GLuint64 offset);
+typedef void (GL_APIENTRYP PFNGLNAMEDBUFFERATTACHMEMORYNVPROC) (GLuint buffer, GLuint memory, GLuint64 offset);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glGetMemoryObjectDetachedResourcesuivNV (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params);
+GL_APICALL void GL_APIENTRY glResetMemoryObjectParameterNV (GLuint memory, GLenum pname);
+GL_APICALL void GL_APIENTRY glTexAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glBufferAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glTextureAttachMemoryNV (GLuint texture, GLuint memory, GLuint64 offset);
+GL_APICALL void GL_APIENTRY glNamedBufferAttachMemoryNV (GLuint buffer, GLuint memory, GLuint64 offset);
+#endif
+#endif /* GL_NV_memory_attachment */
+
#ifndef GL_NV_non_square_matrices
#define GL_NV_non_square_matrices 1
#define GL_FLOAT_MAT2x3_NV 0x8B65
@@ -2681,6 +3004,7 @@ GL_APICALL void GL_APIENTRY glUniformMatrix4x3fvNV (GLint location, GLsizei coun
#ifndef GL_NV_path_rendering
#define GL_NV_path_rendering 1
+typedef double GLdouble;
#define GL_PATH_FORMAT_SVG_NV 0x9070
#define GL_PATH_FORMAT_PS_NV 0x9071
#define GL_STANDARD_FONT_NAME_NV 0x9072
@@ -2891,6 +3215,25 @@ typedef GLenum (GL_APIENTRYP PFNGLPATHGLYPHINDEXARRAYNVPROC) (GLuint firstPathNa
typedef GLenum (GL_APIENTRYP PFNGLPATHMEMORYGLYPHINDEXARRAYNVPROC) (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
typedef void (GL_APIENTRYP PFNGLPROGRAMPATHFRAGMENTINPUTGENNVPROC) (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs);
typedef void (GL_APIENTRYP PFNGLGETPROGRAMRESOURCEFVNVPROC) (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params);
+typedef void (GL_APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m);
+typedef void (GL_APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+typedef void (GL_APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode);
+typedef void (GL_APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GL_APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+typedef void (GL_APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+typedef void (GL_APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
#ifdef GL_GLEXT_PROTOTYPES
GL_APICALL GLuint GL_APIENTRY glGenPathsNV (GLsizei range);
GL_APICALL void GL_APIENTRY glDeletePathsNV (GLuint path, GLsizei range);
@@ -2949,6 +3292,25 @@ GL_APICALL GLenum GL_APIENTRY glPathGlyphIndexArrayNV (GLuint firstPathName, GLe
GL_APICALL GLenum GL_APIENTRY glPathMemoryGlyphIndexArrayNV (GLuint firstPathName, GLenum fontTarget, GLsizeiptr fontSize, const void *fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale);
GL_APICALL void GL_APIENTRY glProgramPathFragmentInputGenNV (GLuint program, GLint location, GLenum genMode, GLint components, const GLfloat *coeffs);
GL_APICALL void GL_APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLfloat *params);
+GL_APICALL void GL_APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GL_APICALL void GL_APIENTRY glMatrixLoadIdentityEXT (GLenum mode);
+GL_APICALL void GL_APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m);
+GL_APICALL void GL_APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m);
+GL_APICALL void GL_APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m);
+GL_APICALL void GL_APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m);
+GL_APICALL void GL_APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m);
+GL_APICALL void GL_APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
+GL_APICALL void GL_APIENTRY glMatrixPopEXT (GLenum mode);
+GL_APICALL void GL_APIENTRY glMatrixPushEXT (GLenum mode);
+GL_APICALL void GL_APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
+GL_APICALL void GL_APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
+GL_APICALL void GL_APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z);
+GL_APICALL void GL_APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z);
#endif
#endif /* GL_NV_path_rendering */
@@ -2957,6 +3319,14 @@ GL_APICALL void GL_APIENTRY glGetProgramResourcefvNV (GLuint program, GLenum pro
#define GL_SHARED_EDGE_NV 0xC0
#endif /* GL_NV_path_rendering_shared_edge */
+#ifndef GL_NV_pixel_buffer_object
+#define GL_NV_pixel_buffer_object 1
+#define GL_PIXEL_PACK_BUFFER_NV 0x88EB
+#define GL_PIXEL_UNPACK_BUFFER_NV 0x88EC
+#define GL_PIXEL_PACK_BUFFER_BINDING_NV 0x88ED
+#define GL_PIXEL_UNPACK_BUFFER_BINDING_NV 0x88EF
+#endif /* GL_NV_pixel_buffer_object */
+
#ifndef GL_NV_polygon_mode
#define GL_NV_polygon_mode 1
#define GL_POLYGON_MODE_NV 0x0B40
@@ -3034,6 +3404,18 @@ GL_APICALL void GL_APIENTRY glResolveDepthValuesNV (void);
#define GL_NV_sample_mask_override_coverage 1
#endif /* GL_NV_sample_mask_override_coverage */
+#ifndef GL_NV_scissor_exclusive
+#define GL_NV_scissor_exclusive 1
+#define GL_SCISSOR_TEST_EXCLUSIVE_NV 0x9555
+#define GL_SCISSOR_BOX_EXCLUSIVE_NV 0x9556
+typedef void (GL_APIENTRYP PFNGLSCISSOREXCLUSIVENVPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLSCISSOREXCLUSIVEARRAYVNVPROC) (GLuint first, GLsizei count, const GLint *v);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glScissorExclusiveNV (GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glScissorExclusiveArrayvNV (GLuint first, GLsizei count, const GLint *v);
+#endif
+#endif /* GL_NV_scissor_exclusive */
+
#ifndef GL_NV_shader_atomic_fp16_vector
#define GL_NV_shader_atomic_fp16_vector 1
#endif /* GL_NV_shader_atomic_fp16_vector */
@@ -3052,6 +3434,10 @@ GL_APICALL void GL_APIENTRY glResolveDepthValuesNV (void);
#define GL_SAMPLER_CUBE_SHADOW_NV 0x8DC5
#endif /* GL_NV_shadow_samplers_cube */
+#ifndef GL_NV_stereo_view_rendering
+#define GL_NV_stereo_view_rendering 1
+#endif /* GL_NV_stereo_view_rendering */
+
#ifndef GL_NV_texture_border_clamp
#define GL_NV_texture_border_clamp 1
#define GL_TEXTURE_BORDER_COLOR_NV 0x1004
@@ -3148,6 +3534,10 @@ GL_APICALL void GL_APIENTRY glFramebufferTextureMultisampleMultiviewOVR (GLenum
#endif
#endif /* GL_OVR_multiview_multisampled_render_to_texture */
+#ifndef GL_QCOM_YUV_texture_gather
+#define GL_QCOM_YUV_texture_gather 1
+#endif /* GL_QCOM_YUV_texture_gather */
+
#ifndef GL_QCOM_alpha_test
#define GL_QCOM_alpha_test 1
#define GL_ALPHA_TEST_QCOM 0x0BC0
@@ -3245,6 +3635,38 @@ GL_APICALL void GL_APIENTRY glFramebufferFoveationParametersQCOM (GLuint framebu
#define GL_PERFMON_GLOBAL_MODE_QCOM 0x8FA0
#endif /* GL_QCOM_perfmon_global_mode */
+#ifndef GL_QCOM_shader_framebuffer_fetch_noncoherent
+#define GL_QCOM_shader_framebuffer_fetch_noncoherent 1
+#define GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM 0x96A2
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIERQCOMPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glFramebufferFetchBarrierQCOM (void);
+#endif
+#endif /* GL_QCOM_shader_framebuffer_fetch_noncoherent */
+
+#ifndef GL_QCOM_shader_framebuffer_fetch_rate
+#define GL_QCOM_shader_framebuffer_fetch_rate 1
+#endif /* GL_QCOM_shader_framebuffer_fetch_rate */
+
+#ifndef GL_QCOM_texture_foveated
+#define GL_QCOM_texture_foveated 1
+#define GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM 0x8BFB
+#define GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM 0x8BFC
+#define GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM 0x8BFD
+#define GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM 0x8BFE
+#define GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM 0x8BFF
+typedef void (GL_APIENTRYP PFNGLTEXTUREFOVEATIONPARAMETERSQCOMPROC) (GLuint texture, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea);
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glTextureFoveationParametersQCOM (GLuint texture, GLuint layer, GLuint focalPoint, GLfloat focalX, GLfloat focalY, GLfloat gainX, GLfloat gainY, GLfloat foveaArea);
+#endif
+#endif /* GL_QCOM_texture_foveated */
+
+#ifndef GL_QCOM_texture_foveated_subsampled_layout
+#define GL_QCOM_texture_foveated_subsampled_layout 1
+#define GL_FOVEATION_SUBSAMPLED_LAYOUT_METHOD_BIT_QCOM 0x00000004
+#define GL_MAX_SHADER_SUBSAMPLED_IMAGE_UNITS_QCOM 0x8FA1
+#endif /* GL_QCOM_texture_foveated_subsampled_layout */
+
#ifndef GL_QCOM_tiled_rendering
#define GL_QCOM_tiled_rendering 1
#define GL_COLOR_BUFFER_BIT0_QCOM 0x00000001
diff --git a/src/gui/opengl/qopenglext.h b/src/gui/opengl/qopenglext.h
index 63873476e4..e3f9205619 100644
--- a/src/gui/opengl/qopenglext.h
+++ b/src/gui/opengl/qopenglext.h
@@ -12,7 +12,7 @@ extern "C" {
#endif
/*
-** Copyright (c) 2013-2017 The Khronos Group Inc.
+** Copyright (c) 2013-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
@@ -57,7 +57,7 @@ extern "C" {
#define GLAPI extern
#endif
-#define GL_GLEXT_VERSION 20170325
+#define GL_GLEXT_VERSION 20190228
/* Generated C header for:
* API: gl
@@ -359,15 +359,17 @@ GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m);
#define GL_TEXTURE_FILTER_CONTROL 0x8500
#define GL_DEPTH_TEXTURE_MODE 0x884B
#define GL_COMPARE_R_TO_TEXTURE 0x884E
-#define GL_FUNC_ADD 0x8006
-#define GL_FUNC_SUBTRACT 0x800A
-#define GL_FUNC_REVERSE_SUBTRACT 0x800B
-#define GL_MIN 0x8007
-#define GL_MAX 0x8008
+#define GL_BLEND_COLOR 0x8005
+#define GL_BLEND_EQUATION 0x8009
#define GL_CONSTANT_COLOR 0x8001
#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002
#define GL_CONSTANT_ALPHA 0x8003
#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004
+#define GL_FUNC_ADD 0x8006
+#define GL_FUNC_REVERSE_SUBTRACT 0x800B
+#define GL_FUNC_SUBTRACT 0x800A
+#define GL_MIN 0x8007
+#define GL_MAX 0x8008
typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);
typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const*indices, GLsizei drawcount);
@@ -2872,6 +2874,42 @@ GLAPI void APIENTRY glTextureBarrier (void);
#endif
#endif /* GL_VERSION_4_5 */
+#ifndef GL_VERSION_4_6
+#define GL_VERSION_4_6 1
+#define GL_SHADER_BINARY_FORMAT_SPIR_V 0x9551
+#define GL_SPIR_V_BINARY 0x9552
+#define GL_PARAMETER_BUFFER 0x80EE
+#define GL_PARAMETER_BUFFER_BINDING 0x80EF
+#define GL_CONTEXT_FLAG_NO_ERROR_BIT 0x00000008
+#define GL_VERTICES_SUBMITTED 0x82EE
+#define GL_PRIMITIVES_SUBMITTED 0x82EF
+#define GL_VERTEX_SHADER_INVOCATIONS 0x82F0
+#define GL_TESS_CONTROL_SHADER_PATCHES 0x82F1
+#define GL_TESS_EVALUATION_SHADER_INVOCATIONS 0x82F2
+#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED 0x82F3
+#define GL_FRAGMENT_SHADER_INVOCATIONS 0x82F4
+#define GL_COMPUTE_SHADER_INVOCATIONS 0x82F5
+#define GL_CLIPPING_INPUT_PRIMITIVES 0x82F6
+#define GL_CLIPPING_OUTPUT_PRIMITIVES 0x82F7
+#define GL_POLYGON_OFFSET_CLAMP 0x8E1B
+#define GL_SPIR_V_EXTENSIONS 0x9553
+#define GL_NUM_SPIR_V_EXTENSIONS 0x9554
+#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE
+#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF
+#define GL_TRANSFORM_FEEDBACK_OVERFLOW 0x82EC
+#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW 0x82ED
+typedef void (APIENTRYP PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue);
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC) (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+typedef void (APIENTRYP PFNGLPOLYGONOFFSETCLAMPPROC) (GLfloat factor, GLfloat units, GLfloat clamp);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glSpecializeShader (GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue);
+GLAPI void APIENTRY glMultiDrawArraysIndirectCount (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+GLAPI void APIENTRY glMultiDrawElementsIndirectCount (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+GLAPI void APIENTRY glPolygonOffsetClamp (GLfloat factor, GLfloat units, GLfloat clamp);
+#endif
+#endif /* GL_VERSION_4_6 */
+
#ifndef GL_ARB_ES2_compatibility
#define GL_ARB_ES2_compatibility 1
#endif /* GL_ARB_ES2_compatibility */
@@ -3475,8 +3513,6 @@ typedef unsigned short GLhalfARB;
#ifndef GL_ARB_imaging
#define GL_ARB_imaging 1
-#define GL_BLEND_COLOR 0x8005
-#define GL_BLEND_EQUATION 0x8009
#define GL_CONVOLUTION_1D 0x8010
#define GL_CONVOLUTION_2D 0x8011
#define GL_SEPARABLE_2D 0x8012
@@ -3613,11 +3649,11 @@ GLAPI void APIENTRY glResetMinmax (GLenum target);
#define GL_ARB_indirect_parameters 1
#define GL_PARAMETER_BUFFER_ARB 0x80EE
#define GL_PARAMETER_BUFFER_BINDING_ARB 0x80EF
-typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
-typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSINDIRECTCOUNTARBPROC) (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTARBPROC) (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
#ifdef GL_GLEXT_PROTOTYPES
-GLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
-GLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+GLAPI void APIENTRY glMultiDrawArraysIndirectCountARB (GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+GLAPI void APIENTRY glMultiDrawElementsIndirectCountARB (GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
#endif
#endif /* GL_ARB_indirect_parameters */
@@ -3637,6 +3673,25 @@ GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor);
#ifndef GL_ARB_internalformat_query2
#define GL_ARB_internalformat_query2 1
#define GL_SRGB_DECODE_ARB 0x8299
+#define GL_VIEW_CLASS_EAC_R11 0x9383
+#define GL_VIEW_CLASS_EAC_RG11 0x9384
+#define GL_VIEW_CLASS_ETC2_RGB 0x9385
+#define GL_VIEW_CLASS_ETC2_RGBA 0x9386
+#define GL_VIEW_CLASS_ETC2_EAC_RGBA 0x9387
+#define GL_VIEW_CLASS_ASTC_4x4_RGBA 0x9388
+#define GL_VIEW_CLASS_ASTC_5x4_RGBA 0x9389
+#define GL_VIEW_CLASS_ASTC_5x5_RGBA 0x938A
+#define GL_VIEW_CLASS_ASTC_6x5_RGBA 0x938B
+#define GL_VIEW_CLASS_ASTC_6x6_RGBA 0x938C
+#define GL_VIEW_CLASS_ASTC_8x5_RGBA 0x938D
+#define GL_VIEW_CLASS_ASTC_8x6_RGBA 0x938E
+#define GL_VIEW_CLASS_ASTC_8x8_RGBA 0x938F
+#define GL_VIEW_CLASS_ASTC_10x5_RGBA 0x9390
+#define GL_VIEW_CLASS_ASTC_10x6_RGBA 0x9391
+#define GL_VIEW_CLASS_ASTC_10x8_RGBA 0x9392
+#define GL_VIEW_CLASS_ASTC_10x10_RGBA 0x9393
+#define GL_VIEW_CLASS_ASTC_12x10_RGBA 0x9394
+#define GL_VIEW_CLASS_ASTC_12x12_RGBA 0x9395
#endif /* GL_ARB_internalformat_query2 */
#ifndef GL_ARB_invalidate_subdata
@@ -3894,6 +3949,10 @@ GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params);
#define GL_COORD_REPLACE_ARB 0x8862
#endif /* GL_ARB_point_sprite */
+#ifndef GL_ARB_polygon_offset_clamp
+#define GL_ARB_polygon_offset_clamp 1
+#endif /* GL_ARB_polygon_offset_clamp */
+
#ifndef GL_ARB_post_depth_coverage
#define GL_ARB_post_depth_coverage 1
#endif /* GL_ARB_post_depth_coverage */
@@ -4292,6 +4351,10 @@ GLAPI void APIENTRY glTexPageCommitmentARB (GLenum target, GLint level, GLint xo
#define GL_ARB_sparse_texture_clamp 1
#endif /* GL_ARB_sparse_texture_clamp */
+#ifndef GL_ARB_spirv_extensions
+#define GL_ARB_spirv_extensions 1
+#endif /* GL_ARB_spirv_extensions */
+
#ifndef GL_ARB_stencil_texturing
#define GL_ARB_stencil_texturing 1
#endif /* GL_ARB_stencil_texturing */
@@ -4444,6 +4507,10 @@ GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, void
#define GL_DOT3_RGBA_ARB 0x86AF
#endif /* GL_ARB_texture_env_dot3 */
+#ifndef GL_ARB_texture_filter_anisotropic
+#define GL_ARB_texture_filter_anisotropic 1
+#endif /* GL_ARB_texture_filter_anisotropic */
+
#ifndef GL_ARB_texture_filter_minmax
#define GL_ARB_texture_filter_minmax 1
#define GL_TEXTURE_REDUCTION_MODE_ARB 0x9366
@@ -4949,6 +5016,16 @@ GLAPI void APIENTRY glBlendBarrierKHR (void);
#define GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR 0x00000008
#endif /* GL_KHR_no_error */
+#ifndef GL_KHR_parallel_shader_compile
+#define GL_KHR_parallel_shader_compile 1
+#define GL_MAX_SHADER_COMPILER_THREADS_KHR 0x91B0
+#define GL_COMPLETION_STATUS_KHR 0x91B1
+typedef void (APIENTRYP PFNGLMAXSHADERCOMPILERTHREADSKHRPROC) (GLuint count);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMaxShaderCompilerThreadsKHR (GLuint count);
+#endif
+#endif /* GL_KHR_parallel_shader_compile */
+
#ifndef GL_KHR_robust_buffer_access_behavior
#define GL_KHR_robust_buffer_access_behavior 1
#endif /* GL_KHR_robust_buffer_access_behavior */
@@ -5389,6 +5466,22 @@ GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRG
#endif
#endif /* GL_AMD_draw_buffers_blend */
+#ifndef GL_AMD_framebuffer_multisample_advanced
+#define GL_AMD_framebuffer_multisample_advanced 1
+#define GL_RENDERBUFFER_STORAGE_SAMPLES_AMD 0x91B2
+#define GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD 0x91B3
+#define GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD 0x91B4
+#define GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD 0x91B5
+#define GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B6
+#define GL_SUPPORTED_MULTISAMPLE_MODES_AMD 0x91B7
+typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEADVANCEDAMDPROC) (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glRenderbufferStorageMultisampleAdvancedAMD (GLenum target, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleAdvancedAMD (GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+#endif /* GL_AMD_framebuffer_multisample_advanced */
+
#ifndef GL_AMD_framebuffer_sample_positions
#define GL_AMD_framebuffer_sample_positions 1
#define GL_SUBSAMPLE_DISTANCE_AMD 0x883F
@@ -5428,6 +5521,10 @@ GLAPI void APIENTRY glGetNamedFramebufferParameterfvAMD (GLuint framebuffer, GLe
#define GL_FLOAT16_MAT4x3_AMD 0x91CD
#endif /* GL_AMD_gpu_shader_half_float */
+#ifndef GL_AMD_gpu_shader_int16
+#define GL_AMD_gpu_shader_int16 1
+#endif /* GL_AMD_gpu_shader_int16 */
+
#ifndef GL_AMD_gpu_shader_int64
#define GL_AMD_gpu_shader_int64 1
typedef int64_t GLint64EXT;
@@ -5649,6 +5746,14 @@ GLAPI void APIENTRY glSetMultisamplefvAMD (GLenum pname, GLuint index, const GLf
#define GL_AMD_shader_explicit_vertex_parameter 1
#endif /* GL_AMD_shader_explicit_vertex_parameter */
+#ifndef GL_AMD_shader_gpu_shader_half_float_fetch
+#define GL_AMD_shader_gpu_shader_half_float_fetch 1
+#endif /* GL_AMD_shader_gpu_shader_half_float_fetch */
+
+#ifndef GL_AMD_shader_image_load_store_lod
+#define GL_AMD_shader_image_load_store_lod 1
+#endif /* GL_AMD_shader_image_load_store_lod */
+
#ifndef GL_AMD_shader_stencil_export
#define GL_AMD_shader_stencil_export 1
#endif /* GL_AMD_shader_stencil_export */
@@ -5688,6 +5793,10 @@ GLAPI void APIENTRY glStencilOpValueAMD (GLenum face, GLuint value);
#endif
#endif /* GL_AMD_stencil_operation_extended */
+#ifndef GL_AMD_texture_gather_bias_lod
+#define GL_AMD_texture_gather_bias_lod 1
+#endif /* GL_AMD_texture_gather_bias_lod */
+
#ifndef GL_AMD_texture_texture4
#define GL_AMD_texture_texture4 1
#endif /* GL_AMD_texture_texture4 */
@@ -6388,6 +6497,17 @@ GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param);
#define GL_422_REV_AVERAGE_EXT 0x80CF
#endif /* GL_EXT_422_pixels */
+#ifndef GL_EXT_EGL_image_storage
+#define GL_EXT_EGL_image_storage 1
+typedef void *GLeglImageOES;
+typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXSTORAGEEXTPROC) (GLenum target, GLeglImageOES image, const GLint* attrib_list);
+typedef void (APIENTRYP PFNGLEGLIMAGETARGETTEXTURESTORAGEEXTPROC) (GLuint texture, GLeglImageOES image, const GLint* attrib_list);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glEGLImageTargetTexStorageEXT (GLenum target, GLeglImageOES image, const GLint* attrib_list);
+GLAPI void APIENTRY glEGLImageTargetTextureStorageEXT (GLuint texture, GLeglImageOES image, const GLint* attrib_list);
+#endif
+#endif /* GL_EXT_EGL_image_storage */
+
#ifndef GL_EXT_abgr
#define GL_EXT_abgr 1
#define GL_ABGR_EXT 0x8000
@@ -7239,6 +7359,17 @@ GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint en
#endif
#endif /* GL_EXT_draw_range_elements */
+#ifndef GL_EXT_external_buffer
+#define GL_EXT_external_buffer 1
+typedef void *GLeglClientBufferEXT;
+typedef void (APIENTRYP PFNGLBUFFERSTORAGEEXTERNALEXTPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEEXTERNALEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBufferStorageExternalEXT (GLenum target, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+GLAPI void APIENTRY glNamedBufferStorageExternalEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLeglClientBufferEXT clientBuffer, GLbitfield flags);
+#endif
+#endif /* GL_EXT_external_buffer */
+
#ifndef GL_EXT_fog_coord
#define GL_EXT_fog_coord 1
#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450
@@ -7582,6 +7713,89 @@ GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode);
#endif
#endif /* GL_EXT_light_texture */
+#ifndef GL_EXT_memory_object
+#define GL_EXT_memory_object 1
+#define GL_TEXTURE_TILING_EXT 0x9580
+#define GL_DEDICATED_MEMORY_OBJECT_EXT 0x9581
+#define GL_PROTECTED_MEMORY_OBJECT_EXT 0x959B
+#define GL_NUM_TILING_TYPES_EXT 0x9582
+#define GL_TILING_TYPES_EXT 0x9583
+#define GL_OPTIMAL_TILING_EXT 0x9584
+#define GL_LINEAR_TILING_EXT 0x9585
+#define GL_NUM_DEVICE_UUIDS_EXT 0x9596
+#define GL_DEVICE_UUID_EXT 0x9597
+#define GL_DRIVER_UUID_EXT 0x9598
+#define GL_UUID_SIZE_EXT 16
+typedef void (APIENTRYP PFNGLGETUNSIGNEDBYTEVEXTPROC) (GLenum pname, GLubyte *data);
+typedef void (APIENTRYP PFNGLGETUNSIGNEDBYTEI_VEXTPROC) (GLenum target, GLuint index, GLubyte *data);
+typedef void (APIENTRYP PFNGLDELETEMEMORYOBJECTSEXTPROC) (GLsizei n, const GLuint *memoryObjects);
+typedef GLboolean (APIENTRYP PFNGLISMEMORYOBJECTEXTPROC) (GLuint memoryObject);
+typedef void (APIENTRYP PFNGLCREATEMEMORYOBJECTSEXTPROC) (GLsizei n, GLuint *memoryObjects);
+typedef void (APIENTRYP PFNGLMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLGETMEMORYOBJECTPARAMETERIVEXTPROC) (GLuint memoryObject, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLTEXSTORAGEMEM2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLTEXSTORAGEMEM2DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLTEXSTORAGEMEM3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLTEXSTORAGEMEM3DMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLBUFFERSTORAGEMEMEXTPROC) (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM2DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM2DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM3DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM3DMULTISAMPLEEXTPROC) (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLNAMEDBUFFERSTORAGEMEMEXTPROC) (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLTEXSTORAGEMEM1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLTEXTURESTORAGEMEM1DEXTPROC) (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetUnsignedBytevEXT (GLenum pname, GLubyte *data);
+GLAPI void APIENTRY glGetUnsignedBytei_vEXT (GLenum target, GLuint index, GLubyte *data);
+GLAPI void APIENTRY glDeleteMemoryObjectsEXT (GLsizei n, const GLuint *memoryObjects);
+GLAPI GLboolean APIENTRY glIsMemoryObjectEXT (GLuint memoryObject);
+GLAPI void APIENTRY glCreateMemoryObjectsEXT (GLsizei n, GLuint *memoryObjects);
+GLAPI void APIENTRY glMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, const GLint *params);
+GLAPI void APIENTRY glGetMemoryObjectParameterivEXT (GLuint memoryObject, GLenum pname, GLint *params);
+GLAPI void APIENTRY glTexStorageMem2DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glTexStorageMem2DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glTexStorageMem3DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glTexStorageMem3DMultisampleEXT (GLenum target, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glBufferStorageMemEXT (GLenum target, GLsizeiptr size, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glTextureStorageMem2DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glTextureStorageMem2DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glTextureStorageMem3DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glTextureStorageMem3DMultisampleEXT (GLuint texture, GLsizei samples, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glNamedBufferStorageMemEXT (GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glTexStorageMem1DEXT (GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glTextureStorageMem1DEXT (GLuint texture, GLsizei levels, GLenum internalFormat, GLsizei width, GLuint memory, GLuint64 offset);
+#endif
+#endif /* GL_EXT_memory_object */
+
+#ifndef GL_EXT_memory_object_fd
+#define GL_EXT_memory_object_fd 1
+#define GL_HANDLE_TYPE_OPAQUE_FD_EXT 0x9586
+typedef void (APIENTRYP PFNGLIMPORTMEMORYFDEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, GLint fd);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glImportMemoryFdEXT (GLuint memory, GLuint64 size, GLenum handleType, GLint fd);
+#endif
+#endif /* GL_EXT_memory_object_fd */
+
+#ifndef GL_EXT_memory_object_win32
+#define GL_EXT_memory_object_win32 1
+#define GL_HANDLE_TYPE_OPAQUE_WIN32_EXT 0x9587
+#define GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT 0x9588
+#define GL_DEVICE_LUID_EXT 0x9599
+#define GL_DEVICE_NODE_MASK_EXT 0x959A
+#define GL_LUID_SIZE_EXT 8
+#define GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT 0x9589
+#define GL_HANDLE_TYPE_D3D12_RESOURCE_EXT 0x958A
+#define GL_HANDLE_TYPE_D3D11_IMAGE_EXT 0x958B
+#define GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT 0x958C
+typedef void (APIENTRYP PFNGLIMPORTMEMORYWIN32HANDLEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, void *handle);
+typedef void (APIENTRYP PFNGLIMPORTMEMORYWIN32NAMEEXTPROC) (GLuint memory, GLuint64 size, GLenum handleType, const void *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glImportMemoryWin32HandleEXT (GLuint memory, GLuint64 size, GLenum handleType, void *handle);
+GLAPI void APIENTRY glImportMemoryWin32NameEXT (GLuint memory, GLuint64 size, GLenum handleType, const void *name);
+#endif
+#endif /* GL_EXT_memory_object_win32 */
+
#ifndef GL_EXT_misc_attribute
#define GL_EXT_misc_attribute 1
#endif /* GL_EXT_misc_attribute */
@@ -7823,6 +8037,55 @@ GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei
#endif
#endif /* GL_EXT_secondary_color */
+#ifndef GL_EXT_semaphore
+#define GL_EXT_semaphore 1
+#define GL_LAYOUT_GENERAL_EXT 0x958D
+#define GL_LAYOUT_COLOR_ATTACHMENT_EXT 0x958E
+#define GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT 0x958F
+#define GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT 0x9590
+#define GL_LAYOUT_SHADER_READ_ONLY_EXT 0x9591
+#define GL_LAYOUT_TRANSFER_SRC_EXT 0x9592
+#define GL_LAYOUT_TRANSFER_DST_EXT 0x9593
+#define GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT 0x9530
+#define GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT 0x9531
+typedef void (APIENTRYP PFNGLGENSEMAPHORESEXTPROC) (GLsizei n, GLuint *semaphores);
+typedef void (APIENTRYP PFNGLDELETESEMAPHORESEXTPROC) (GLsizei n, const GLuint *semaphores);
+typedef GLboolean (APIENTRYP PFNGLISSEMAPHOREEXTPROC) (GLuint semaphore);
+typedef void (APIENTRYP PFNGLSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, const GLuint64 *params);
+typedef void (APIENTRYP PFNGLGETSEMAPHOREPARAMETERUI64VEXTPROC) (GLuint semaphore, GLenum pname, GLuint64 *params);
+typedef void (APIENTRYP PFNGLWAITSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts);
+typedef void (APIENTRYP PFNGLSIGNALSEMAPHOREEXTPROC) (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenSemaphoresEXT (GLsizei n, GLuint *semaphores);
+GLAPI void APIENTRY glDeleteSemaphoresEXT (GLsizei n, const GLuint *semaphores);
+GLAPI GLboolean APIENTRY glIsSemaphoreEXT (GLuint semaphore);
+GLAPI void APIENTRY glSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, const GLuint64 *params);
+GLAPI void APIENTRY glGetSemaphoreParameterui64vEXT (GLuint semaphore, GLenum pname, GLuint64 *params);
+GLAPI void APIENTRY glWaitSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *srcLayouts);
+GLAPI void APIENTRY glSignalSemaphoreEXT (GLuint semaphore, GLuint numBufferBarriers, const GLuint *buffers, GLuint numTextureBarriers, const GLuint *textures, const GLenum *dstLayouts);
+#endif
+#endif /* GL_EXT_semaphore */
+
+#ifndef GL_EXT_semaphore_fd
+#define GL_EXT_semaphore_fd 1
+typedef void (APIENTRYP PFNGLIMPORTSEMAPHOREFDEXTPROC) (GLuint semaphore, GLenum handleType, GLint fd);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glImportSemaphoreFdEXT (GLuint semaphore, GLenum handleType, GLint fd);
+#endif
+#endif /* GL_EXT_semaphore_fd */
+
+#ifndef GL_EXT_semaphore_win32
+#define GL_EXT_semaphore_win32 1
+#define GL_HANDLE_TYPE_D3D12_FENCE_EXT 0x9594
+#define GL_D3D12_FENCE_VALUE_EXT 0x9595
+typedef void (APIENTRYP PFNGLIMPORTSEMAPHOREWIN32HANDLEEXTPROC) (GLuint semaphore, GLenum handleType, void *handle);
+typedef void (APIENTRYP PFNGLIMPORTSEMAPHOREWIN32NAMEEXTPROC) (GLuint semaphore, GLenum handleType, const void *name);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glImportSemaphoreWin32HandleEXT (GLuint semaphore, GLenum handleType, void *handle);
+GLAPI void APIENTRY glImportSemaphoreWin32NameEXT (GLuint semaphore, GLenum handleType, const void *name);
+#endif
+#endif /* GL_EXT_semaphore_win32 */
+
#ifndef GL_EXT_separate_shader_objects
#define GL_EXT_separate_shader_objects 1
#define GL_ACTIVE_PROGRAM_EXT 0x8B8D
@@ -7843,6 +8106,19 @@ GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *strin
#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA
#endif /* GL_EXT_separate_specular_color */
+#ifndef GL_EXT_shader_framebuffer_fetch
+#define GL_EXT_shader_framebuffer_fetch 1
+#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
+#endif /* GL_EXT_shader_framebuffer_fetch */
+
+#ifndef GL_EXT_shader_framebuffer_fetch_non_coherent
+#define GL_EXT_shader_framebuffer_fetch_non_coherent 1
+typedef void (APIENTRYP PFNGLFRAMEBUFFERFETCHBARRIEREXTPROC) (void);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glFramebufferFetchBarrierEXT (void);
+#endif
+#endif /* GL_EXT_shader_framebuffer_fetch_non_coherent */
+
#ifndef GL_EXT_shader_image_load_formatted
#define GL_EXT_shader_image_load_formatted 1
#endif /* GL_EXT_shader_image_load_formatted */
@@ -8143,6 +8419,8 @@ GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint
#ifndef GL_EXT_texture_filter_minmax
#define GL_EXT_texture_filter_minmax 1
+#define GL_TEXTURE_REDUCTION_MODE_EXT 0x9366
+#define GL_WEIGHTED_AVERAGE_EXT 0x9367
#endif /* GL_EXT_texture_filter_minmax */
#ifndef GL_EXT_texture_integer
@@ -8277,6 +8555,11 @@ GLAPI void APIENTRY glTextureNormalEXT (GLenum mode);
#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F
#endif /* GL_EXT_texture_sRGB */
+#ifndef GL_EXT_texture_sRGB_R8
+#define GL_EXT_texture_sRGB_R8 1
+#define GL_SR8_EXT 0x8FBD
+#endif /* GL_EXT_texture_sRGB_R8 */
+
#ifndef GL_EXT_texture_sRGB_decode
#define GL_EXT_texture_sRGB_decode 1
#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48
@@ -8689,6 +8972,16 @@ GLAPI void APIENTRY glVertexWeightPointerEXT (GLint size, GLenum type, GLsizei s
#endif
#endif /* GL_EXT_vertex_weighting */
+#ifndef GL_EXT_win32_keyed_mutex
+#define GL_EXT_win32_keyed_mutex 1
+typedef GLboolean (APIENTRYP PFNGLACQUIREKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key, GLuint timeout);
+typedef GLboolean (APIENTRYP PFNGLRELEASEKEYEDMUTEXWIN32EXTPROC) (GLuint memory, GLuint64 key);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLboolean APIENTRY glAcquireKeyedMutexWin32EXT (GLuint memory, GLuint64 key, GLuint timeout);
+GLAPI GLboolean APIENTRY glReleaseKeyedMutexWin32EXT (GLuint memory, GLuint64 key);
+#endif
+#endif /* GL_EXT_win32_keyed_mutex */
+
#ifndef GL_EXT_window_rectangles
#define GL_EXT_window_rectangles 1
#define GL_INCLUSIVE_EXT 0x8F10
@@ -8880,6 +9173,11 @@ GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRG
#define GL_INTERLACE_READ_INGR 0x8568
#endif /* GL_INGR_interlace_read */
+#ifndef GL_INTEL_blackhole_render
+#define GL_INTEL_blackhole_render 1
+#define GL_BLACKHOLE_RENDER_INTEL 0x83FC
+#endif /* GL_INTEL_blackhole_render */
+
#ifndef GL_INTEL_conservative_rasterization
#define GL_INTEL_conservative_rasterization 1
#define GL_CONSERVATIVE_RASTERIZATION_INTEL 0x83FE
@@ -8961,7 +9259,7 @@ typedef void (APIENTRYP PFNGLENDPERFQUERYINTELPROC) (GLuint queryHandle);
typedef void (APIENTRYP PFNGLGETFIRSTPERFQUERYIDINTELPROC) (GLuint *queryId);
typedef void (APIENTRYP PFNGLGETNEXTPERFQUERYIDINTELPROC) (GLuint queryId, GLuint *nextQueryId);
typedef void (APIENTRYP PFNGLGETPERFCOUNTERINFOINTELPROC) (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue);
-typedef void (APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten);
+typedef void (APIENTRYP PFNGLGETPERFQUERYDATAINTELPROC) (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten);
typedef void (APIENTRYP PFNGLGETPERFQUERYIDBYNAMEINTELPROC) (GLchar *queryName, GLuint *queryId);
typedef void (APIENTRYP PFNGLGETPERFQUERYINFOINTELPROC) (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask);
#ifdef GL_GLEXT_PROTOTYPES
@@ -8972,7 +9270,7 @@ GLAPI void APIENTRY glEndPerfQueryINTEL (GLuint queryHandle);
GLAPI void APIENTRY glGetFirstPerfQueryIdINTEL (GLuint *queryId);
GLAPI void APIENTRY glGetNextPerfQueryIdINTEL (GLuint queryId, GLuint *nextQueryId);
GLAPI void APIENTRY glGetPerfCounterInfoINTEL (GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar *counterName, GLuint counterDescLength, GLchar *counterDesc, GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue);
-GLAPI void APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, GLvoid *data, GLuint *bytesWritten);
+GLAPI void APIENTRY glGetPerfQueryDataINTEL (GLuint queryHandle, GLuint flags, GLsizei dataSize, void *data, GLuint *bytesWritten);
GLAPI void APIENTRY glGetPerfQueryIdByNameINTEL (GLchar *queryName, GLuint *queryId);
GLAPI void APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLength, GLchar *queryName, GLuint *dataSize, GLuint *noCounters, GLuint *noInstances, GLuint *capsMask);
#endif
@@ -8993,6 +9291,11 @@ GLAPI void APIENTRY glGetPerfQueryInfoINTEL (GLuint queryId, GLuint queryNameLen
#define GL_PACK_INVERT_MESA 0x8758
#endif /* GL_MESA_pack_invert */
+#ifndef GL_MESA_program_binary_formats
+#define GL_MESA_program_binary_formats 1
+#define GL_PROGRAM_BINARY_FORMAT_MESA 0x875F
+#endif /* GL_MESA_program_binary_formats */
+
#ifndef GL_MESA_resize_buffers
#define GL_MESA_resize_buffers 1
typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void);
@@ -9005,6 +9308,13 @@ GLAPI void APIENTRY glResizeBuffersMESA (void);
#define GL_MESA_shader_integer_functions 1
#endif /* GL_MESA_shader_integer_functions */
+#ifndef GL_MESA_tile_raster_order
+#define GL_MESA_tile_raster_order 1
+#define GL_TILE_RASTER_ORDER_FIXED_MESA 0x8BB8
+#define GL_TILE_RASTER_ORDER_INCREASING_X_MESA 0x8BB9
+#define GL_TILE_RASTER_ORDER_INCREASING_Y_MESA 0x8BBA
+#endif /* GL_MESA_tile_raster_order */
+
#ifndef GL_MESA_window_pos
#define GL_MESA_window_pos 1
typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y);
@@ -9231,6 +9541,10 @@ GLAPI void APIENTRY glBlendBarrierNV (void);
#define GL_BLEND_ADVANCED_COHERENT_NV 0x9285
#endif /* GL_NV_blend_equation_advanced_coherent */
+#ifndef GL_NV_blend_minmax_factor
+#define GL_NV_blend_minmax_factor 1
+#endif /* GL_NV_blend_minmax_factor */
+
#ifndef GL_NV_blend_square
#define GL_NV_blend_square 1
#endif /* GL_NV_blend_square */
@@ -9311,6 +9625,10 @@ GLAPI void APIENTRY glCallCommandListNV (GLuint list);
#define GL_COMPUTE_PROGRAM_PARAMETER_BUFFER_NV 0x90FC
#endif /* GL_NV_compute_program5 */
+#ifndef GL_NV_compute_shader_derivatives
+#define GL_NV_compute_shader_derivatives 1
+#endif /* GL_NV_compute_shader_derivatives */
+
#ifndef GL_NV_conditional_render
#define GL_NV_conditional_render 1
#define GL_QUERY_WAIT_NV 0x8E13
@@ -9348,6 +9666,11 @@ GLAPI void APIENTRY glConservativeRasterParameterfNV (GLenum pname, GLfloat valu
#endif
#endif /* GL_NV_conservative_raster_dilate */
+#ifndef GL_NV_conservative_raster_pre_snap
+#define GL_NV_conservative_raster_pre_snap 1
+#define GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV 0x9550
+#endif /* GL_NV_conservative_raster_pre_snap */
+
#ifndef GL_NV_conservative_raster_pre_snap_triangles
#define GL_NV_conservative_raster_pre_snap_triangles 1
#define GL_CONSERVATIVE_RASTER_MODE_NV 0x954D
@@ -9359,6 +9682,10 @@ GLAPI void APIENTRY glConservativeRasterParameteriNV (GLenum pname, GLint param)
#endif
#endif /* GL_NV_conservative_raster_pre_snap_triangles */
+#ifndef GL_NV_conservative_raster_underestimation
+#define GL_NV_conservative_raster_underestimation 1
+#endif /* GL_NV_conservative_raster_underestimation */
+
#ifndef GL_NV_copy_depth_to_color
#define GL_NV_copy_depth_to_color 1
#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E
@@ -9600,6 +9927,10 @@ GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, cons
#define GL_NV_fragment_program_option 1
#endif /* GL_NV_fragment_program_option */
+#ifndef GL_NV_fragment_shader_barycentric
+#define GL_NV_fragment_shader_barycentric 1
+#endif /* GL_NV_fragment_shader_barycentric */
+
#ifndef GL_NV_fragment_shader_interlock
#define GL_NV_fragment_shader_interlock 1
#endif /* GL_NV_fragment_shader_interlock */
@@ -9667,7 +9998,7 @@ GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachmen
#define GL_PER_GPU_STORAGE_NV 0x9548
#define GL_MULTICAST_PROGRAMMABLE_SAMPLE_LOCATION_NV 0x9549
typedef void (APIENTRYP PFNGLRENDERGPUMASKNVPROC) (GLbitfield mask);
-typedef void (APIENTRYP PFNGLMULTICASTBUFFERSUBDATANVPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+typedef void (APIENTRYP PFNGLMULTICASTBUFFERSUBDATANVPROC) (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);
typedef void (APIENTRYP PFNGLMULTICASTCOPYBUFFERSUBDATANVPROC) (GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
typedef void (APIENTRYP PFNGLMULTICASTCOPYIMAGESUBDATANVPROC) (GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
typedef void (APIENTRYP PFNGLMULTICASTBLITFRAMEBUFFERNVPROC) (GLuint srcGpu, GLuint dstGpu, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
@@ -9680,7 +10011,7 @@ typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTI64VNVPROC) (GLuint gpu, GLu
typedef void (APIENTRYP PFNGLMULTICASTGETQUERYOBJECTUI64VNVPROC) (GLuint gpu, GLuint id, GLenum pname, GLuint64 *params);
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glRenderGpuMaskNV (GLbitfield mask);
-GLAPI void APIENTRY glMulticastBufferSubDataNV (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data);
+GLAPI void APIENTRY glMulticastBufferSubDataNV (GLbitfield gpuMask, GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data);
GLAPI void APIENTRY glMulticastCopyBufferSubDataNV (GLuint readGpu, GLbitfield writeGpuMask, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size);
GLAPI void APIENTRY glMulticastCopyImageSubDataNV (GLuint srcGpu, GLbitfield dstGpuMask, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
GLAPI void APIENTRY glMulticastBlitFramebufferNV (GLuint srcGpu, GLuint dstGpu, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
@@ -9884,6 +10215,96 @@ GLAPI void APIENTRY glGetInternalformatSampleivNV (GLenum target, GLenum interna
#define GL_MAX_SPOT_EXPONENT_NV 0x8505
#endif /* GL_NV_light_max_exponent */
+#ifndef GL_NV_memory_attachment
+#define GL_NV_memory_attachment 1
+#define GL_ATTACHED_MEMORY_OBJECT_NV 0x95A4
+#define GL_ATTACHED_MEMORY_OFFSET_NV 0x95A5
+#define GL_MEMORY_ATTACHABLE_ALIGNMENT_NV 0x95A6
+#define GL_MEMORY_ATTACHABLE_SIZE_NV 0x95A7
+#define GL_MEMORY_ATTACHABLE_NV 0x95A8
+#define GL_DETACHED_MEMORY_INCARNATION_NV 0x95A9
+#define GL_DETACHED_TEXTURES_NV 0x95AA
+#define GL_DETACHED_BUFFERS_NV 0x95AB
+#define GL_MAX_DETACHED_TEXTURES_NV 0x95AC
+#define GL_MAX_DETACHED_BUFFERS_NV 0x95AD
+typedef void (APIENTRYP PFNGLGETMEMORYOBJECTDETACHEDRESOURCESUIVNVPROC) (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params);
+typedef void (APIENTRYP PFNGLRESETMEMORYOBJECTPARAMETERNVPROC) (GLuint memory, GLenum pname);
+typedef void (APIENTRYP PFNGLTEXATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLBUFFERATTACHMEMORYNVPROC) (GLenum target, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLTEXTUREATTACHMEMORYNVPROC) (GLuint texture, GLuint memory, GLuint64 offset);
+typedef void (APIENTRYP PFNGLNAMEDBUFFERATTACHMEMORYNVPROC) (GLuint buffer, GLuint memory, GLuint64 offset);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetMemoryObjectDetachedResourcesuivNV (GLuint memory, GLenum pname, GLint first, GLsizei count, GLuint *params);
+GLAPI void APIENTRY glResetMemoryObjectParameterNV (GLuint memory, GLenum pname);
+GLAPI void APIENTRY glTexAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glBufferAttachMemoryNV (GLenum target, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glTextureAttachMemoryNV (GLuint texture, GLuint memory, GLuint64 offset);
+GLAPI void APIENTRY glNamedBufferAttachMemoryNV (GLuint buffer, GLuint memory, GLuint64 offset);
+#endif
+#endif /* GL_NV_memory_attachment */
+
+#ifndef GL_NV_mesh_shader
+#define GL_NV_mesh_shader 1
+#define GL_MESH_SHADER_NV 0x9559
+#define GL_TASK_SHADER_NV 0x955A
+#define GL_MAX_MESH_UNIFORM_BLOCKS_NV 0x8E60
+#define GL_MAX_MESH_TEXTURE_IMAGE_UNITS_NV 0x8E61
+#define GL_MAX_MESH_IMAGE_UNIFORMS_NV 0x8E62
+#define GL_MAX_MESH_UNIFORM_COMPONENTS_NV 0x8E63
+#define GL_MAX_MESH_ATOMIC_COUNTER_BUFFERS_NV 0x8E64
+#define GL_MAX_MESH_ATOMIC_COUNTERS_NV 0x8E65
+#define GL_MAX_MESH_SHADER_STORAGE_BLOCKS_NV 0x8E66
+#define GL_MAX_COMBINED_MESH_UNIFORM_COMPONENTS_NV 0x8E67
+#define GL_MAX_TASK_UNIFORM_BLOCKS_NV 0x8E68
+#define GL_MAX_TASK_TEXTURE_IMAGE_UNITS_NV 0x8E69
+#define GL_MAX_TASK_IMAGE_UNIFORMS_NV 0x8E6A
+#define GL_MAX_TASK_UNIFORM_COMPONENTS_NV 0x8E6B
+#define GL_MAX_TASK_ATOMIC_COUNTER_BUFFERS_NV 0x8E6C
+#define GL_MAX_TASK_ATOMIC_COUNTERS_NV 0x8E6D
+#define GL_MAX_TASK_SHADER_STORAGE_BLOCKS_NV 0x8E6E
+#define GL_MAX_COMBINED_TASK_UNIFORM_COMPONENTS_NV 0x8E6F
+#define GL_MAX_MESH_WORK_GROUP_INVOCATIONS_NV 0x95A2
+#define GL_MAX_TASK_WORK_GROUP_INVOCATIONS_NV 0x95A3
+#define GL_MAX_MESH_TOTAL_MEMORY_SIZE_NV 0x9536
+#define GL_MAX_TASK_TOTAL_MEMORY_SIZE_NV 0x9537
+#define GL_MAX_MESH_OUTPUT_VERTICES_NV 0x9538
+#define GL_MAX_MESH_OUTPUT_PRIMITIVES_NV 0x9539
+#define GL_MAX_TASK_OUTPUT_COUNT_NV 0x953A
+#define GL_MAX_DRAW_MESH_TASKS_COUNT_NV 0x953D
+#define GL_MAX_MESH_VIEWS_NV 0x9557
+#define GL_MESH_OUTPUT_PER_VERTEX_GRANULARITY_NV 0x92DF
+#define GL_MESH_OUTPUT_PER_PRIMITIVE_GRANULARITY_NV 0x9543
+#define GL_MAX_MESH_WORK_GROUP_SIZE_NV 0x953B
+#define GL_MAX_TASK_WORK_GROUP_SIZE_NV 0x953C
+#define GL_MESH_WORK_GROUP_SIZE_NV 0x953E
+#define GL_TASK_WORK_GROUP_SIZE_NV 0x953F
+#define GL_MESH_VERTICES_OUT_NV 0x9579
+#define GL_MESH_PRIMITIVES_OUT_NV 0x957A
+#define GL_MESH_OUTPUT_TYPE_NV 0x957B
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_MESH_SHADER_NV 0x959C
+#define GL_UNIFORM_BLOCK_REFERENCED_BY_TASK_SHADER_NV 0x959D
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_MESH_SHADER_NV 0x959E
+#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TASK_SHADER_NV 0x959F
+#define GL_REFERENCED_BY_MESH_SHADER_NV 0x95A0
+#define GL_REFERENCED_BY_TASK_SHADER_NV 0x95A1
+#define GL_MESH_SUBROUTINE_NV 0x957C
+#define GL_TASK_SUBROUTINE_NV 0x957D
+#define GL_MESH_SUBROUTINE_UNIFORM_NV 0x957E
+#define GL_TASK_SUBROUTINE_UNIFORM_NV 0x957F
+#define GL_MESH_SHADER_BIT_NV 0x00000040
+#define GL_TASK_SHADER_BIT_NV 0x00000080
+typedef void (APIENTRYP PFNGLDRAWMESHTASKSNVPROC) (GLuint first, GLuint count);
+typedef void (APIENTRYP PFNGLDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect);
+typedef void (APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTNVPROC) (GLintptr indirect, GLsizei drawcount, GLsizei stride);
+typedef void (APIENTRYP PFNGLMULTIDRAWMESHTASKSINDIRECTCOUNTNVPROC) (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawMeshTasksNV (GLuint first, GLuint count);
+GLAPI void APIENTRY glDrawMeshTasksIndirectNV (GLintptr indirect);
+GLAPI void APIENTRY glMultiDrawMeshTasksIndirectNV (GLintptr indirect, GLsizei drawcount, GLsizei stride);
+GLAPI void APIENTRY glMultiDrawMeshTasksIndirectCountNV (GLintptr indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride);
+#endif
+#endif /* GL_NV_mesh_shader */
+
#ifndef GL_NV_multisample_coverage
#define GL_NV_multisample_coverage 1
#endif /* GL_NV_multisample_coverage */
@@ -10311,6 +10732,32 @@ GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index);
#endif
#endif /* GL_NV_primitive_restart */
+#ifndef GL_NV_query_resource
+#define GL_NV_query_resource 1
+#define GL_QUERY_RESOURCE_TYPE_VIDMEM_ALLOC_NV 0x9540
+#define GL_QUERY_RESOURCE_MEMTYPE_VIDMEM_NV 0x9542
+#define GL_QUERY_RESOURCE_SYS_RESERVED_NV 0x9544
+#define GL_QUERY_RESOURCE_TEXTURE_NV 0x9545
+#define GL_QUERY_RESOURCE_RENDERBUFFER_NV 0x9546
+#define GL_QUERY_RESOURCE_BUFFEROBJECT_NV 0x9547
+typedef GLint (APIENTRYP PFNGLQUERYRESOURCENVPROC) (GLenum queryType, GLint tagId, GLuint bufSize, GLint *buffer);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLint APIENTRY glQueryResourceNV (GLenum queryType, GLint tagId, GLuint bufSize, GLint *buffer);
+#endif
+#endif /* GL_NV_query_resource */
+
+#ifndef GL_NV_query_resource_tag
+#define GL_NV_query_resource_tag 1
+typedef void (APIENTRYP PFNGLGENQUERYRESOURCETAGNVPROC) (GLsizei n, GLint *tagIds);
+typedef void (APIENTRYP PFNGLDELETEQUERYRESOURCETAGNVPROC) (GLsizei n, const GLint *tagIds);
+typedef void (APIENTRYP PFNGLQUERYRESOURCETAGNVPROC) (GLint tagId, const GLchar *tagString);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGenQueryResourceTagNV (GLsizei n, GLint *tagIds);
+GLAPI void APIENTRY glDeleteQueryResourceTagNV (GLsizei n, const GLint *tagIds);
+GLAPI void APIENTRY glQueryResourceTagNV (GLint tagId, const GLchar *tagString);
+#endif
+#endif /* GL_NV_query_resource_tag */
+
#ifndef GL_NV_register_combiners
#define GL_NV_register_combiners 1
#define GL_REGISTER_COMBINERS_NV 0x8522
@@ -10403,6 +10850,11 @@ GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname,
#endif
#endif /* GL_NV_register_combiners2 */
+#ifndef GL_NV_representative_fragment_test
+#define GL_NV_representative_fragment_test 1
+#define GL_REPRESENTATIVE_FRAGMENT_TEST_NV 0x937F
+#endif /* GL_NV_representative_fragment_test */
+
#ifndef GL_NV_robustness_video_memory_purge
#define GL_NV_robustness_video_memory_purge 1
#define GL_PURGED_CONTEXT_RESET_NV 0x92BB
@@ -10432,6 +10884,18 @@ GLAPI void APIENTRY glResolveDepthValuesNV (void);
#define GL_NV_sample_mask_override_coverage 1
#endif /* GL_NV_sample_mask_override_coverage */
+#ifndef GL_NV_scissor_exclusive
+#define GL_NV_scissor_exclusive 1
+#define GL_SCISSOR_TEST_EXCLUSIVE_NV 0x9555
+#define GL_SCISSOR_BOX_EXCLUSIVE_NV 0x9556
+typedef void (APIENTRYP PFNGLSCISSOREXCLUSIVENVPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
+typedef void (APIENTRYP PFNGLSCISSOREXCLUSIVEARRAYVNVPROC) (GLuint first, GLsizei count, const GLint *v);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glScissorExclusiveNV (GLint x, GLint y, GLsizei width, GLsizei height);
+GLAPI void APIENTRY glScissorExclusiveArrayvNV (GLuint first, GLsizei count, const GLint *v);
+#endif
+#endif /* GL_NV_scissor_exclusive */
+
#ifndef GL_NV_shader_atomic_counters
#define GL_NV_shader_atomic_counters 1
#endif /* GL_NV_shader_atomic_counters */
@@ -10496,6 +10960,10 @@ GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLs
#define GL_NV_shader_storage_buffer_object 1
#endif /* GL_NV_shader_storage_buffer_object */
+#ifndef GL_NV_shader_texture_footprint
+#define GL_NV_shader_texture_footprint 1
+#endif /* GL_NV_shader_texture_footprint */
+
#ifndef GL_NV_shader_thread_group
#define GL_NV_shader_thread_group 1
#define GL_WARP_SIZE_NV 0x9339
@@ -10507,6 +10975,47 @@ GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLs
#define GL_NV_shader_thread_shuffle 1
#endif /* GL_NV_shader_thread_shuffle */
+#ifndef GL_NV_shading_rate_image
+#define GL_NV_shading_rate_image 1
+#define GL_SHADING_RATE_IMAGE_NV 0x9563
+#define GL_SHADING_RATE_NO_INVOCATIONS_NV 0x9564
+#define GL_SHADING_RATE_1_INVOCATION_PER_PIXEL_NV 0x9565
+#define GL_SHADING_RATE_1_INVOCATION_PER_1X2_PIXELS_NV 0x9566
+#define GL_SHADING_RATE_1_INVOCATION_PER_2X1_PIXELS_NV 0x9567
+#define GL_SHADING_RATE_1_INVOCATION_PER_2X2_PIXELS_NV 0x9568
+#define GL_SHADING_RATE_1_INVOCATION_PER_2X4_PIXELS_NV 0x9569
+#define GL_SHADING_RATE_1_INVOCATION_PER_4X2_PIXELS_NV 0x956A
+#define GL_SHADING_RATE_1_INVOCATION_PER_4X4_PIXELS_NV 0x956B
+#define GL_SHADING_RATE_2_INVOCATIONS_PER_PIXEL_NV 0x956C
+#define GL_SHADING_RATE_4_INVOCATIONS_PER_PIXEL_NV 0x956D
+#define GL_SHADING_RATE_8_INVOCATIONS_PER_PIXEL_NV 0x956E
+#define GL_SHADING_RATE_16_INVOCATIONS_PER_PIXEL_NV 0x956F
+#define GL_SHADING_RATE_IMAGE_BINDING_NV 0x955B
+#define GL_SHADING_RATE_IMAGE_TEXEL_WIDTH_NV 0x955C
+#define GL_SHADING_RATE_IMAGE_TEXEL_HEIGHT_NV 0x955D
+#define GL_SHADING_RATE_IMAGE_PALETTE_SIZE_NV 0x955E
+#define GL_MAX_COARSE_FRAGMENT_SAMPLES_NV 0x955F
+#define GL_SHADING_RATE_SAMPLE_ORDER_DEFAULT_NV 0x95AE
+#define GL_SHADING_RATE_SAMPLE_ORDER_PIXEL_MAJOR_NV 0x95AF
+#define GL_SHADING_RATE_SAMPLE_ORDER_SAMPLE_MAJOR_NV 0x95B0
+typedef void (APIENTRYP PFNGLBINDSHADINGRATEIMAGENVPROC) (GLuint texture);
+typedef void (APIENTRYP PFNGLGETSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint entry, GLenum *rate);
+typedef void (APIENTRYP PFNGLGETSHADINGRATESAMPLELOCATIONIVNVPROC) (GLenum rate, GLuint samples, GLuint index, GLint *location);
+typedef void (APIENTRYP PFNGLSHADINGRATEIMAGEBARRIERNVPROC) (GLboolean synchronize);
+typedef void (APIENTRYP PFNGLSHADINGRATEIMAGEPALETTENVPROC) (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates);
+typedef void (APIENTRYP PFNGLSHADINGRATESAMPLEORDERNVPROC) (GLenum order);
+typedef void (APIENTRYP PFNGLSHADINGRATESAMPLEORDERCUSTOMNVPROC) (GLenum rate, GLuint samples, const GLint *locations);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBindShadingRateImageNV (GLuint texture);
+GLAPI void APIENTRY glGetShadingRateImagePaletteNV (GLuint viewport, GLuint entry, GLenum *rate);
+GLAPI void APIENTRY glGetShadingRateSampleLocationivNV (GLenum rate, GLuint samples, GLuint index, GLint *location);
+GLAPI void APIENTRY glShadingRateImageBarrierNV (GLboolean synchronize);
+GLAPI void APIENTRY glShadingRateImagePaletteNV (GLuint viewport, GLuint first, GLsizei count, const GLenum *rates);
+GLAPI void APIENTRY glShadingRateSampleOrderNV (GLenum order);
+GLAPI void APIENTRY glShadingRateSampleOrderCustomNV (GLenum rate, GLuint samples, const GLint *locations);
+#endif
+#endif /* GL_NV_shading_rate_image */
+
#ifndef GL_NV_stereo_view_rendering
#define GL_NV_stereo_view_rendering 1
#endif /* GL_NV_stereo_view_rendering */
@@ -10587,6 +11096,10 @@ GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenu
#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8
#endif /* GL_NV_texture_rectangle */
+#ifndef GL_NV_texture_rectangle_compressed
+#define GL_NV_texture_rectangle_compressed 1
+#endif /* GL_NV_texture_rectangle_compressed */
+
#ifndef GL_NV_texture_shader
#define GL_NV_texture_shader 1
#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C
@@ -10813,6 +11326,14 @@ GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSur
#endif
#endif /* GL_NV_vdpau_interop */
+#ifndef GL_NV_vdpau_interop2
+#define GL_NV_vdpau_interop2 1
+typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACEWITHPICTURESTRUCTURENVPROC) (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames, GLboolean isFrameStructure);
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceWithPictureStructureNV (const void *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames, GLboolean isFrameStructure);
+#endif
+#endif /* GL_NV_vdpau_interop2 */
+
#ifndef GL_NV_vertex_array_range
#define GL_NV_vertex_array_range 1
#define GL_VERTEX_ARRAY_RANGE_NV 0x851D
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index 5b7956d31e..f25988585e 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -1467,6 +1467,122 @@ void QOpenGLTexturePrivate::setData(int mipLevel, int layer, int layerCount, QOp
}
}
+void QOpenGLTexturePrivate::setData(int xOffset, int yOffset, int zOffset, int width, int height, int depth,
+ int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace,
+ QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options)
+{
+ switch (target) {
+ case QOpenGLTexture::Target1D:
+ Q_UNUSED(layer);
+ Q_UNUSED(cubeFace);
+ Q_UNUSED(layerCount);
+ Q_UNUSED(yOffset);
+ Q_UNUSED(zOffset);
+ Q_UNUSED(height);
+ Q_UNUSED(depth);
+ texFuncs->glTextureSubImage1D(textureId, target, bindingTarget, mipLevel,
+ xOffset, width,
+ sourceFormat, sourceType, data, options);
+ break;
+
+ case QOpenGLTexture::Target1DArray:
+ Q_UNUSED(cubeFace);
+ Q_UNUSED(yOffset);
+ Q_UNUSED(zOffset);
+ Q_UNUSED(height);
+ Q_UNUSED(depth);
+ texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
+ xOffset, layer,
+ width,
+ layerCount,
+ sourceFormat, sourceType, data, options);
+ break;
+
+ case QOpenGLTexture::Target2D:
+ Q_UNUSED(layer);
+ Q_UNUSED(cubeFace);
+ Q_UNUSED(layerCount);
+ Q_UNUSED(zOffset);
+ Q_UNUSED(depth);
+ texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, mipLevel,
+ xOffset, yOffset,
+ width, height,
+ sourceFormat, sourceType, data, options);
+ break;
+
+ case QOpenGLTexture::Target2DArray:
+ Q_UNUSED(cubeFace);
+ Q_UNUSED(zOffset);
+ Q_UNUSED(depth);
+ texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
+ xOffset, yOffset, layer,
+ width, height, layerCount,
+ sourceFormat, sourceType, data, options);
+ break;
+
+ case QOpenGLTexture::Target3D:
+ Q_UNUSED(cubeFace);
+ Q_UNUSED(layerCount);
+ texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
+ xOffset, yOffset, zOffset,
+ width, height, depth,
+ sourceFormat, sourceType, data, options);
+ break;
+
+ case QOpenGLTexture::TargetCubeMap:
+ Q_UNUSED(layer);
+ Q_UNUSED(layerCount);
+ Q_UNUSED(zOffset);
+ Q_UNUSED(depth);
+ texFuncs->glTextureSubImage2D(textureId, cubeFace, bindingTarget, mipLevel,
+ xOffset, yOffset,
+ width, height,
+ sourceFormat, sourceType, data, options);
+ break;
+
+ case QOpenGLTexture::TargetCubeMapArray: {
+ Q_UNUSED(zOffset);
+ Q_UNUSED(depth);
+ int faceIndex = cubeFace - QOpenGLTexture::CubeMapPositiveX;
+ int layerFace = 6 * layer + faceIndex;
+ texFuncs->glTextureSubImage3D(textureId, target, bindingTarget, mipLevel,
+ xOffset, yOffset, layerFace,
+ width, height,
+ layerCount,
+ sourceFormat, sourceType, data, options);
+ break;
+ }
+
+ case QOpenGLTexture::TargetRectangle:
+ Q_UNUSED(mipLevel);
+ Q_UNUSED(layer);
+ Q_UNUSED(cubeFace);
+ Q_UNUSED(layerCount);
+ Q_UNUSED(zOffset);
+ Q_UNUSED(depth);
+ texFuncs->glTextureSubImage2D(textureId, target, bindingTarget, 0,
+ xOffset, yOffset,
+ width, height,
+ sourceFormat, sourceType, data, options);
+ break;
+
+ case QOpenGLTexture::Target2DMultisample:
+ case QOpenGLTexture::Target2DMultisampleArray:
+ case QOpenGLTexture::TargetBuffer:
+ // We don't upload pixel data for these targets
+ qWarning("QOpenGLTexture::setData(): Texture target does not support pixel data upload");
+ break;
+ }
+
+ // If requested perform automatic mip map generation
+ if (mipLevel == 0 && autoGenerateMipMaps && mipLevels > 1) {
+ Q_Q(QOpenGLTexture);
+ q->generateMipMaps();
+ }
+}
+
+
void QOpenGLTexturePrivate::setCompressedData(int mipLevel, int layer, int layerCount,
QOpenGLTexture::CubeMapFace cubeFace,
int dataSize, const void *data,
@@ -3380,6 +3496,124 @@ void QOpenGLTexture::setData(PixelFormat sourceFormat, PixelType sourceType,
d->setData(0, 0, 1, QOpenGLTexture::CubeMapPositiveX, sourceFormat, sourceType, data, options);
}
+/*!
+ \since 5.14
+ \overload
+
+ This overload is to be used to update a part of the texture. Parameters \a
+ xOffset, \a yOffset, \a zOffset specify the texel offsets within the
+ texture. Parameters \a width, \a height and \a depth specify the dimensions
+ of the sub image.
+
+ The structure of the pixel data pointed to by \a data is specified by \a
+ sourceFormat and \a sourceType. The pixel data upload can optionally be
+ controlled by \a options.
+*/
+void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
+ int width, int height, int depth,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setData(xOffset, yOffset, zOffset,
+ width, height, depth,
+ 0, 0, 1,
+ QOpenGLTexture::CubeMapPositiveX, sourceFormat,
+ sourceType, data, options);
+}
+
+/*!
+ \since 5.14
+ \overload
+
+ This overload is to be used to update a part of the texture. Parameters \a
+ xOffset, \a yOffset, \a zOffset specify the texel offsets within the
+ texture. Parameters \a width, \a height and \a depth specify the dimensions
+ of the sub image. The mip map level and layerof the sub image we want to
+ update are specified with \a mipLevel and \a layer.
+
+ The structure of the pixel data pointed to by \a data is specified by \a
+ sourceFormat and \a sourceType. The pixel data upload can optionally be
+ controlled by \a options.
+*/
+void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
+ int width, int height, int depth,
+ int mipLevel, int layer,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setData(xOffset, yOffset, zOffset,
+ width, height, depth,
+ mipLevel, layer, 1,
+ QOpenGLTexture::CubeMapPositiveX, sourceFormat,
+ sourceType, data, options);
+}
+
+/*!
+ \since 5.14
+ \overload
+
+ This overload is to be used to update a part of the texture. Parameters \a
+ xOffset, \a yOffset, \a zOffset specify the texel offsets within the
+ texture. Parameters \a width, \a height and \a depth specify the dimensions
+ of the sub image.The mip map level, layer and cube map face of the sub
+ image we want to update are specified with \a mipLevel, \a layer and \a
+ face.
+
+ The structure of the pixel data pointed to by \a data is specified by \a
+ sourceFormat and \a sourceType. The pixel data upload can optionally be
+ controlled by \a options.
+*/
+void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
+ int width, int height, int depth,
+ int mipLevel, int layer,
+ CubeMapFace face,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setData(xOffset, yOffset, zOffset,
+ width, height, depth,
+ mipLevel, layer, 1,
+ face, sourceFormat,
+ sourceType, data, options);
+}
+
+/*!
+ \since 5.14
+ \overload
+
+ This overload is to be used to update a part of the texture. Parameters \a
+ xOffset, \a yOffset, \a zOffset specify the texel offsets within the
+ texture. Parameters \a width, \a height and \a depth specify the dimensions
+ of the sub image.The mip map level, starting layer, cube map face and
+ number of layers of the sub image we want to update are specified with \a
+ mipLevel, \a layer, \a face and \a layerCount.
+
+ The structure of the pixel data pointed to by \a data is specified by \a
+ sourceFormat and \a sourceType. The pixel data upload can optionally be
+ controlled by \a options.
+*/
+void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset,
+ int width, int height, int depth,
+ int mipLevel, int layer,
+ CubeMapFace face, int layerCount,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options)
+{
+ Q_D(QOpenGLTexture);
+ Q_ASSERT(d->textureId);
+ d->setData(xOffset, yOffset, zOffset,
+ width, height, depth,
+ mipLevel, layer, layerCount,
+ face, sourceFormat,
+ sourceType, data, options);
+}
+
#if QT_DEPRECATED_SINCE(5, 3)
/*!
\obsolete
diff --git a/src/gui/opengl/qopengltexture.h b/src/gui/opengl/qopengltexture.h
index c0c5283374..7d984babc8 100644
--- a/src/gui/opengl/qopengltexture.h
+++ b/src/gui/opengl/qopengltexture.h
@@ -485,6 +485,32 @@ public:
void setData(PixelFormat sourceFormat, PixelType sourceType,
const void *data, const QOpenGLPixelTransferOptions * const options = nullptr);
+ void setData(int xOffset, int yOffset, int zOffset,
+ int width, int height, int depth,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options = nullptr);
+ void setData(int xOffset, int yOffset, int zOffset,
+ int width, int height, int depth, int mipLevel,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options = nullptr);
+ void setData(int xOffset, int yOffset, int zOffset,
+ int width, int height, int depth,
+ int mipLevel, int layer,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options = nullptr);
+ void setData(int xOffset, int yOffset, int zOffset,
+ int width, int height, int depth,
+ int mipLevel, int layer,
+ CubeMapFace cubeFace,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options = nullptr);
+ void setData(int xOffset, int yOffset, int zOffset,
+ int width, int height, int depth,
+ int mipLevel, int layer,
+ CubeMapFace cubeFace, int layerCount,
+ PixelFormat sourceFormat, PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options = nullptr);
+
// Compressed data upload
// ### Qt 6: remove the non-const void * overloads
#if QT_DEPRECATED_SINCE(5, 3)
diff --git a/src/gui/opengl/qopengltexture_p.h b/src/gui/opengl/qopengltexture_p.h
index f7694f77bc..9f3457ad0a 100644
--- a/src/gui/opengl/qopengltexture_p.h
+++ b/src/gui/opengl/qopengltexture_p.h
@@ -101,6 +101,10 @@ public:
void setData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace,
QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType,
const void *data, const QOpenGLPixelTransferOptions * const options);
+ void setData(int xOffset, int yOffset, int zOffset, int width, int height, int depth,
+ int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace,
+ QOpenGLTexture::PixelFormat sourceFormat, QOpenGLTexture::PixelType sourceType,
+ const void *data, const QOpenGLPixelTransferOptions * const options);
void setCompressedData(int mipLevel, int layer, int layerCount, QOpenGLTexture::CubeMapFace cubeFace,
int dataSize, const void *data,
const QOpenGLPixelTransferOptions * const options);
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri
index c3585a4647..0e2dfed9ab 100644
--- a/src/gui/painting/painting.pri
+++ b/src/gui/painting/painting.pri
@@ -8,7 +8,15 @@ HEADERS += \
painting/qbrush.h \
painting/qcolor.h \
painting/qcolor_p.h \
- painting/qcolorprofile_p.h \
+ painting/qcolormatrix_p.h \
+ painting/qcolorspace.h \
+ painting/qcolorspace_p.h \
+ painting/qcolortransferfunction_p.h \
+ painting/qcolortransfertable_p.h \
+ painting/qcolortransform.h \
+ painting/qcolortransform_p.h \
+ painting/qcolortrc_p.h \
+ painting/qcolortrclut_p.h \
painting/qcosmeticstroker_p.h \
painting/qdatabuffer_p.h \
painting/qdrawhelper_p.h \
@@ -17,6 +25,7 @@ HEADERS += \
painting/qemulationpaintengine_p.h \
painting/qfixed_p.h \
painting/qgrayraster_p.h \
+ painting/qicc_p.h \
painting/qmatrix.h \
painting/qmemrotate_p.h \
painting/qoutlinemapper_p.h \
@@ -64,12 +73,15 @@ SOURCES += \
painting/qblittable.cpp \
painting/qbrush.cpp \
painting/qcolor.cpp \
- painting/qcolorprofile.cpp \
+ painting/qcolorspace.cpp \
+ painting/qcolortransform.cpp \
+ painting/qcolortrclut.cpp \
painting/qcompositionfunctions.cpp \
painting/qcosmeticstroker.cpp \
painting/qdrawhelper.cpp \
painting/qemulationpaintengine.cpp \
painting/qgrayraster.c \
+ painting/qicc.cpp \
painting/qimagescale.cpp \
painting/qmatrix.cpp \
painting/qmemrotate.cpp \
diff --git a/src/gui/painting/qcolormatrix_p.h b/src/gui/painting/qcolormatrix_p.h
new file mode 100644
index 0000000000..3d1dca6222
--- /dev/null
+++ b/src/gui/painting/qcolormatrix_p.h
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOLORMATRIX_H
+#define QCOLORMATRIX_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/qtguiglobal.h>
+#include <cmath>
+
+QT_BEGIN_NAMESPACE
+
+// An abstract 3 value color
+class QColorVector
+{
+public:
+ QColorVector() = default;
+ constexpr QColorVector(float x, float y, float z) : x(x), y(y), z(z), _unused(0.0f) { }
+ float x; // X, x or red
+ float y; // Y, y or green
+ float z; // Z, Y or blue
+ float _unused;
+
+ friend inline bool operator==(const QColorVector &v1, const QColorVector &v2);
+ friend inline bool operator!=(const QColorVector &v1, const QColorVector &v2);
+
+ static constexpr QColorVector null() { return QColorVector(0.0f, 0.0f, 0.0f); }
+ // Common whitepoints on normalized XYZ form:
+ static constexpr QColorVector D50() { return QColorVector(0.96421f, 1.0f, 0.82519f); }
+ static constexpr QColorVector D65() { return QColorVector(0.95043f, 1.0f, 1.08890f); }
+};
+
+inline bool operator==(const QColorVector &v1, const QColorVector &v2)
+{
+ return (std::abs(v1.x - v2.x) < (1.0f / 2048.0f))
+ && (std::abs(v1.y - v2.y) < (1.0f / 2048.0f))
+ && (std::abs(v1.z - v2.z) < (1.0f / 2048.0f));
+}
+
+inline bool operator!=(const QColorVector &v1, const QColorVector &v2)
+{
+ return !(v1 == v2);
+}
+
+
+// A matrix mapping 3 value colors.
+// Not using QMatrix because only floats are needed and performance is critical.
+class QColorMatrix
+{
+public:
+ // We are storing the matrix transposed as that is more convenient:
+ QColorVector r;
+ QColorVector g;
+ QColorVector b;
+
+ friend inline bool operator==(const QColorMatrix &m1, const QColorMatrix &m2);
+ friend inline bool operator!=(const QColorMatrix &m1, const QColorMatrix &m2);
+
+ bool isValid() const
+ {
+ // A color matrix must be invertible
+ float det = r.x * (b.z * g.y - g.z * b.y) -
+ r.y * (b.z * g.x - g.z * b.x) +
+ r.z * (b.y * g.x - g.y * b.x);
+ return !qFuzzyIsNull(det);
+ }
+
+ QColorMatrix inverted() const
+ {
+ float det = r.x * (b.z * g.y - g.z * b.y) -
+ r.y * (b.z * g.x - g.z * b.x) +
+ r.z * (b.y * g.x - g.y * b.x);
+ det = 1.0f / det;
+ QColorMatrix inv;
+ inv.r.x = (g.y * b.z - b.y * g.z) * det;
+ inv.r.y = (b.y * r.z - r.y * b.z) * det;
+ inv.r.z = (r.y * g.z - g.y * r.z) * det;
+ inv.g.x = (b.x * g.z - g.x * b.z) * det;
+ inv.g.y = (r.x * b.z - b.x * r.z) * det;
+ inv.g.z = (g.x * r.z - r.x * g.z) * det;
+ inv.b.x = (g.x * b.y - b.x * g.y) * det;
+ inv.b.y = (b.x * r.y - r.x * b.y) * det;
+ inv.b.z = (r.x * g.y - g.x * r.y) * det;
+ return inv;
+ }
+ QColorMatrix operator*(const QColorMatrix &o) const
+ {
+ QColorMatrix comb;
+ comb.r.x = r.x * o.r.x + g.x * o.r.y + b.x * o.r.z;
+ comb.g.x = r.x * o.g.x + g.x * o.g.y + b.x * o.g.z;
+ comb.b.x = r.x * o.b.x + g.x * o.b.y + b.x * o.b.z;
+
+ comb.r.y = r.y * o.r.x + g.y * o.r.y + b.y * o.r.z;
+ comb.g.y = r.y * o.g.x + g.y * o.g.y + b.y * o.g.z;
+ comb.b.y = r.y * o.b.x + g.y * o.b.y + b.y * o.b.z;
+
+ comb.r.z = r.z * o.r.x + g.z * o.r.y + b.z * o.r.z;
+ comb.g.z = r.z * o.g.x + g.z * o.g.y + b.z * o.g.z;
+ comb.b.z = r.z * o.b.x + g.z * o.b.y + b.z * o.b.z;
+ return comb;
+
+ }
+ QColorVector map(const QColorVector &c) const
+ {
+ return QColorVector { c.x * r.x + c.y * g.x + c.z * b.x,
+ c.x * r.y + c.y * g.y + c.z * b.y,
+ c.x * r.z + c.y * g.z + c.z * b.z };
+ }
+ QColorMatrix transposed() const
+ {
+ return QColorMatrix { { r.x, g.x, b.x },
+ { r.y, g.y, b.y },
+ { r.z, g.z, b.z } };
+ }
+
+ static QColorMatrix null()
+ {
+ return { QColorVector::null(), QColorVector::null(), QColorVector::null() };
+ }
+ static QColorMatrix identity()
+ {
+ return { { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f } };
+ }
+ static QColorMatrix toXyzFromSRgb()
+ {
+ return QColorMatrix { { 0.4360217452f, 0.2224751115f, 0.0139281144f },
+ { 0.3851087987f, 0.7169067264f, 0.0971015394f },
+ { 0.1430812478f, 0.0606181994f, 0.7141585946f } };
+ }
+ static QColorMatrix toXyzFromAdobeRgb()
+ {
+ return QColorMatrix { { 0.6097189188f, 0.3111021519f, 0.0194766335f },
+ { 0.2052682191f, 0.6256770492f, 0.0608891509f },
+ { 0.1492247432f, 0.0632209629f, 0.7448224425f } };
+ }
+ static QColorMatrix toXyzFromDciP3D65()
+ {
+ return QColorMatrix { { 0.5150973201f, 0.2411795557f, -0.0010491034f },
+ { 0.2919696569f, 0.6922441125f, 0.0418830328f },
+ { 0.1571449190f, 0.0665764511f, 0.7843542695f } };
+ }
+ static QColorMatrix toXyzFromProPhotoRgb()
+ {
+ return QColorMatrix { { 0.7976672649f, 0.2880374491f, 0.0000000000f },
+ { 0.1351922452f, 0.7118769884f, 0.0000000000f },
+ { 0.0313525312f, 0.0000856627f, 0.8251883388f } };
+ }
+ static QColorMatrix toXyzFromBt2020()
+ {
+ return QColorMatrix { { 0.6506130099f, 0.2695676684f, -0.0018652577f },
+ { 0.1865101457f, 0.6840794086f, 0.0172256753f },
+ { 0.1270887405f, 0.0463530831f, 0.8098278046f } };
+ }
+};
+
+inline bool operator==(const QColorMatrix &m1, const QColorMatrix &m2)
+{
+ return (m1.r == m2.r) && (m1.g == m2.g) && (m1.b == m2.b);
+}
+
+inline bool operator!=(const QColorMatrix &m1, const QColorMatrix &m2)
+{
+ return !(m1 == m2);
+}
+
+QT_END_NAMESPACE
+
+#endif // QCOLORMATRIX_P_H
diff --git a/src/gui/painting/qcolorspace.cpp b/src/gui/painting/qcolorspace.cpp
new file mode 100644
index 0000000000..24785f7b61
--- /dev/null
+++ b/src/gui/painting/qcolorspace.cpp
@@ -0,0 +1,633 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcolorspace.h"
+#include "qcolorspace_p.h"
+
+#include "qcolortransform.h"
+#include "qcolormatrix_p.h"
+#include "qcolortransferfunction_p.h"
+#include "qcolortransform_p.h"
+#include "qicc_p.h"
+
+#include <qmath.h>
+#include <qtransform.h>
+
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+QColorSpacePrivate::QColorSpacePrivate()
+ : id(QColorSpace::Unknown)
+ , gamut(QColorSpace::Gamut::Custom)
+ , transferFunction(QColorSpace::TransferFunction::Custom)
+ , gamma(0.0f)
+ , whitePoint(QColorVector::null())
+ , toXyz(QColorMatrix::null())
+{
+}
+
+QColorSpacePrivate::QColorSpacePrivate(QColorSpace::ColorSpaceId colorSpaceId)
+ : id(colorSpaceId)
+{
+ switch (colorSpaceId) {
+ case QColorSpace::Undefined:
+ gamut = QColorSpace::Gamut::Custom;
+ transferFunction = QColorSpace::TransferFunction::Custom;
+ gamma = 0.0f;
+ description = QStringLiteral("Undefined");
+ break;
+ case QColorSpace::SRgb:
+ gamut = QColorSpace::Gamut::SRgb;
+ transferFunction = QColorSpace::TransferFunction::SRgb;
+ gamma = 2.31f; // ?
+ description = QStringLiteral("sRGB");
+ break;
+ case QColorSpace::SRgbLinear:
+ gamut = QColorSpace::Gamut::SRgb;
+ transferFunction = QColorSpace::TransferFunction::Linear;
+ gamma = 1.0f;
+ description = QStringLiteral("Linear sRGB");
+ break;
+ case QColorSpace::AdobeRgb:
+ gamut = QColorSpace::Gamut::AdobeRgb;
+ transferFunction = QColorSpace::TransferFunction::Gamma;
+ gamma = 2.19921875f; // Not quite 2.2, see https://www.adobe.com/digitalimag/pdfs/AdobeRGB1998.pdf
+ description = QStringLiteral("Adobe RGB");
+ break;
+ case QColorSpace::DisplayP3:
+ gamut = QColorSpace::Gamut::DciP3D65;
+ transferFunction = QColorSpace::TransferFunction::SRgb;
+ gamma = 2.31f; // ?
+ description = QStringLiteral("Display P3");
+ break;
+ case QColorSpace::ProPhotoRgb:
+ gamut = QColorSpace::Gamut::ProPhotoRgb;
+ transferFunction = QColorSpace::TransferFunction::ProPhotoRgb;
+ gamma = 1.8f;
+ description = QStringLiteral("ProPhoto RGB");
+ break;
+ case QColorSpace::Bt2020:
+ gamut = QColorSpace::Gamut::Bt2020;
+ transferFunction = QColorSpace::TransferFunction::Bt2020;
+ gamma = 2.1f; // ?
+ description = QStringLiteral("BT.2020");
+ break;
+ case QColorSpace::Unknown:
+ qWarning("Can not create an unknown color space");
+ Q_FALLTHROUGH();
+ default:
+ Q_UNREACHABLE();
+ }
+ initialize();
+}
+
+QColorSpacePrivate::QColorSpacePrivate(QColorSpace::Gamut gamut, QColorSpace::TransferFunction fun, float gamma)
+ : gamut(gamut)
+ , transferFunction(fun)
+ , gamma(gamma)
+{
+ if (!identifyColorSpace())
+ id = QColorSpace::Unknown;
+ initialize();
+}
+
+bool QColorSpacePrivate::identifyColorSpace()
+{
+ switch (gamut) {
+ case QColorSpace::Gamut::SRgb:
+ if (transferFunction == QColorSpace::TransferFunction::SRgb) {
+ id = QColorSpace::SRgb;
+ description = QStringLiteral("sRGB");
+ return true;
+ }
+ if (transferFunction == QColorSpace::TransferFunction::Linear) {
+ id = QColorSpace::SRgbLinear;
+ description = QStringLiteral("Linear sRGB");
+ return true;
+ }
+ break;
+ case QColorSpace::Gamut::AdobeRgb:
+ if (transferFunction == QColorSpace::TransferFunction::Gamma) {
+ if (qAbs(gamma - 2.19921875f) < (1/1024.0f)) {
+ id = QColorSpace::AdobeRgb;
+ description = QStringLiteral("Adobe RGB");
+ return true;
+ }
+ }
+ break;
+ case QColorSpace::Gamut::DciP3D65:
+ if (transferFunction == QColorSpace::TransferFunction::SRgb) {
+ id = QColorSpace::DisplayP3;
+ description = QStringLiteral("Display P3");
+ return true;
+ }
+ break;
+ case QColorSpace::Gamut::ProPhotoRgb:
+ if (transferFunction == QColorSpace::TransferFunction::ProPhotoRgb) {
+ id = QColorSpace::ProPhotoRgb;
+ description = QStringLiteral("ProPhoto RGB");
+ return true;
+ }
+ if (transferFunction == QColorSpace::TransferFunction::Gamma) {
+ // ProPhoto RGB's curve is effectively gamma 1.8 for 8bit precision.
+ if (qAbs(gamma - 1.8f) < (1/1024.0f)) {
+ id = QColorSpace::ProPhotoRgb;
+ description = QStringLiteral("ProPhoto RGB");
+ return true;
+ }
+ }
+ break;
+ case QColorSpace::Gamut::Bt2020:
+ if (transferFunction == QColorSpace::TransferFunction::Bt2020) {
+ id = QColorSpace::Bt2020;
+ description = QStringLiteral("BT.2020");
+ return true;
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void QColorSpacePrivate::initialize()
+{
+ setToXyzMatrix();
+ setTransferFunction();
+}
+
+void QColorSpacePrivate::setToXyzMatrix()
+{
+ switch (gamut) {
+ case QColorSpace::Gamut::SRgb:
+ toXyz = QColorMatrix::toXyzFromSRgb();
+ whitePoint = QColorVector::D65();
+ return;
+ case QColorSpace::Gamut::AdobeRgb:
+ toXyz = QColorMatrix::toXyzFromAdobeRgb();
+ whitePoint = QColorVector::D65();
+ return;
+ case QColorSpace::Gamut::DciP3D65:
+ toXyz = QColorMatrix::toXyzFromDciP3D65();
+ whitePoint = QColorVector::D65();
+ return;
+ case QColorSpace::Gamut::ProPhotoRgb:
+ toXyz = QColorMatrix::toXyzFromProPhotoRgb();
+ whitePoint = QColorVector::D50();
+ return;
+ case QColorSpace::Gamut::Bt2020:
+ toXyz = QColorMatrix::toXyzFromBt2020();
+ whitePoint = QColorVector::D65();
+ return;
+ case QColorSpace::Gamut::Custom:
+ toXyz = QColorMatrix::null();
+ whitePoint = QColorVector::D50();
+ return;
+ }
+ Q_UNREACHABLE();
+}
+
+void QColorSpacePrivate::setTransferFunction()
+{
+ switch (transferFunction) {
+ case QColorSpace::TransferFunction::Linear:
+ trc[0].m_type = QColorTrc::Type::Function;
+ trc[0].m_fun = QColorTransferFunction();
+ break;
+ case QColorSpace::TransferFunction::Gamma:
+ trc[0].m_type = QColorTrc::Type::Function;
+ trc[0].m_fun = QColorTransferFunction::fromGamma(gamma);
+ break;
+ case QColorSpace::TransferFunction::SRgb:
+ trc[0].m_type = QColorTrc::Type::Function;
+ trc[0].m_fun = QColorTransferFunction::fromSRgb();
+ break;
+ case QColorSpace::TransferFunction::ProPhotoRgb:
+ trc[0].m_type = QColorTrc::Type::Function;
+ trc[0].m_fun = QColorTransferFunction::fromProPhotoRgb();
+ break;
+ case QColorSpace::TransferFunction::Bt2020:
+ trc[0].m_type = QColorTrc::Type::Function;
+ trc[0].m_fun = QColorTransferFunction::fromBt2020();
+ break;
+ case QColorSpace::TransferFunction::Custom:
+ break;
+ default:
+ Q_UNREACHABLE();
+ break;
+ }
+ trc[1] = trc[0];
+ trc[2] = trc[0];
+}
+
+QColorTransform QColorSpacePrivate::transformationToColorSpace(const QColorSpacePrivate *out) const
+{
+ Q_ASSERT(out);
+ QColorTransform combined;
+ combined.d_ptr.reset(new QColorTransformPrivate);
+ combined.d_ptr->colorSpaceIn = this;
+ combined.d_ptr->colorSpaceOut = out;
+ combined.d_ptr->colorMatrix = out->toXyz.inverted() * toXyz;
+ return combined;
+}
+
+/*!
+ \class QColorSpace
+ \brief The QColorSpace class provides a color space abstraction.
+ \since 5.14
+
+ \ingroup painting
+ \ingroup appearance
+ \inmodule QtGui
+
+ Color values can be interpreted in different ways, and based on the interpretation
+ can live in different spaces. We call this \e {color spaces}.
+
+ QColorSpace provides access to creating several predefined color spaces and
+ can generate QColorTransforms for converting colors from one color space to
+ another.
+
+ QColorSpace can also represent color spaces defined by ICC profiles or embedded
+ in images, that do not otherwise fit the predefined color spaces.
+
+ A color space can generally speaking be conceived as a combination of a transfer
+ function and a gamut. The gamut defines which colors the color space can represent.
+ A color space that can represent a wider range of colors is also known as a
+ wide-gamut color space. The gamut is defined by three primary colors that represent
+ exactly how red, green, and blue look in this particular color space, and a white
+ color that represents where and how bright pure white is.
+
+ The transfer function or gamma curve determines how each component in the
+ color space is encoded. These are used because human perception does not operate
+ linearly, and the transfer functions try to ensure that colors will seem evenly
+ spaced to human eyes.
+*/
+
+
+/*!
+ \enum QColorSpace::ColorSpaceId
+
+ Predefined color spaces.
+
+ \value Undefined An empty, invalid or unsupported color space.
+ \value Unknown A valid color space that doesn't match any of the predefined color spaces.
+ \value SRgb The sRGB color space, which Qt operates in by default. It is a close approximation
+ of how most classic monitors operate, and a mode most software and hardware support.
+ \l{http://www.color.org/chardata/rgb/srgb.xalter}{ICC registration of sRGB}.
+ \value SRgbLinear The sRGB color space with linear gamma. Useful for gamma-corrected blending.
+ \value AdobeRgb The Adobe RGB color space is a classic wide-gamut color space, using a gamma of 2.2.
+ \l{http://www.color.org/chardata/rgb/adobergb.xalter}{ICC registration of Adobe RGB (1998)}
+ \value DisplayP3 A color-space using the primaries of DCI-P3, but with the whitepoint and transfer
+ function of sRGB. Common in modern wide-gamut screens.
+ \l{http://www.color.org/chardata/rgb/DCIP3.xalter}{ICC registration of DCI-P3}
+ \value ProPhotoRgb The Pro Photo RGB color space, also known as ROMM RGB is a very wide gamut color space.
+ \l{http://www.color.org/chardata/rgb/rommrgb.xalter}{ICC registration of ROMM RGB}
+ \value Bt2020 BT.2020 also known as Rec.2020 is the color space of HDR TVs.
+ \l{http://www.color.org/chardata/rgb/BT2020.xalter}{ICC registration of BT.2020}
+*/
+
+/*!
+ \enum QColorSpace::Gamut
+
+ Predefined gamuts, or sets of primary colors.
+
+ \value Custom The gamut is undefined or does not match any predefined sets.
+ \value SRgb The sRGB gamut
+ \value AdobeRgb The Adobe RGB gamut
+ \value DciP3D65 The DCI-P3 gamut with the D65 whitepoint
+ \value ProPhotoRgb The ProPhoto RGB gamut with the D50 whitepoint
+ \value Bt2020 The BT.2020 gamut
+*/
+
+/*!
+ \enum QColorSpace::TransferFunction
+
+ Predefined transfer functions or gamma curves.
+
+ \value Custom The custom or null transfer function
+ \value Linear The linear transfer functions
+ \value Gamma A transfer function that is a real gamma curve based on the value of gamma()
+ \value SRgb The sRGB transfer function, composed of linear and gamma parts
+ \value ProPhotoRgb The ProPhoto RGB transfer function, composed of linear and gamma parts
+ \value Bt2020 The BT.2020 transfer function, composed of linear and gamma parts
+*/
+
+/*!
+ Creates a new colorspace object that represents \a colorSpaceId.
+ */
+QColorSpace::QColorSpace(QColorSpace::ColorSpaceId colorSpaceId)
+{
+ static QExplicitlySharedDataPointer<QColorSpacePrivate> predefinedColorspacePrivates[QColorSpace::Bt2020];
+ if (colorSpaceId <= QColorSpace::Unknown) {
+ if (!predefinedColorspacePrivates[0])
+ predefinedColorspacePrivates[0] = new QColorSpacePrivate(QColorSpace::Undefined);
+ d_ptr = predefinedColorspacePrivates[0]; // unknown and undefined both returns the static undefined colorspace.
+ } else {
+ if (!predefinedColorspacePrivates[colorSpaceId - 1])
+ predefinedColorspacePrivates[colorSpaceId - 1] = new QColorSpacePrivate(colorSpaceId);
+ d_ptr = predefinedColorspacePrivates[colorSpaceId - 1];
+ }
+
+ Q_ASSERT(colorSpaceId == QColorSpace::Undefined || isValid());
+}
+
+/*!
+ Creates a custom color space with the gamut \a gamut, using the transfer function \a fun and
+ optionally \a gamma.
+ */
+QColorSpace::QColorSpace(QColorSpace::Gamut gamut, QColorSpace::TransferFunction fun, float gamma)
+ : d_ptr(new QColorSpacePrivate(gamut, fun, gamma))
+{
+}
+
+/*!
+ Creates a custom color space with the gamut \a gamut, using a gamma transfer function of
+ \a gamma.
+ */
+QColorSpace::QColorSpace(QColorSpace::Gamut gamut, float gamma)
+ : d_ptr(new QColorSpacePrivate(gamut, TransferFunction::Gamma, gamma))
+{
+}
+
+QColorSpace::~QColorSpace()
+{
+}
+
+QColorSpace::QColorSpace(QColorSpace &&colorSpace)
+ : d_ptr(std::move(colorSpace.d_ptr))
+{
+}
+
+QColorSpace::QColorSpace(const QColorSpace &colorSpace)
+ : d_ptr(colorSpace.d_ptr)
+{
+}
+
+QColorSpace &QColorSpace::operator=(QColorSpace &&colorSpace)
+{
+ d_ptr = std::move(colorSpace.d_ptr);
+ return *this;
+}
+
+QColorSpace &QColorSpace::operator=(const QColorSpace &colorSpace)
+{
+ d_ptr = colorSpace.d_ptr;
+ return *this;
+}
+
+/*!
+ Returns the id of the predefined color space this object
+ represents or \c Unknown if it doesn't match any of them.
+*/
+QColorSpace::ColorSpaceId QColorSpace::colorSpaceId() const noexcept
+{
+ return d_ptr->id;
+}
+
+/*!
+ Returns the predefined gamut of the color space
+ or \c Gamut::Custom if it doesn't match any of them.
+*/
+QColorSpace::Gamut QColorSpace::gamut() const noexcept
+{
+ return d_ptr->gamut;
+}
+
+/*!
+ Returns the predefined transfer function of the color space
+ or \c TransferFunction::Custom if it doesn't match any of them.
+
+ \sa gamma()
+*/
+QColorSpace::TransferFunction QColorSpace::transferFunction() const noexcept
+{
+ return d_ptr->transferFunction;
+}
+
+/*!
+ Returns the gamma value of color spaces with \c TransferFunction::Gamma,
+ an approximate gamma value for other predefined color spaces, or
+ 0.0 if no approximate gamma is known.
+
+ \sa transferFunction()
+*/
+float QColorSpace::gamma() const noexcept
+{
+ return d_ptr->gamma;
+}
+
+/*!
+ Returns an ICC profile representing the color space.
+
+ If the color space was generated from an ICC profile, that profile
+ is returned, otherwise one is generated.
+
+ \note Even invalid color spaces may return the ICC profile if they
+ were generated from one, to allow applications to implement wider
+ support themselves.
+
+ \sa fromIccProfile()
+*/
+QByteArray QColorSpace::iccProfile() const
+{
+ if (!d_ptr->iccProfile.isEmpty())
+ return d_ptr->iccProfile;
+ if (!isValid())
+ return QByteArray();
+ return QIcc::toIccProfile(*this);
+}
+
+/*!
+ Creates a QColorSpace from ICC profile \a iccProfile.
+
+ \note Not all ICC profiles are supported. QColorSpace only supports
+ RGB-XYZ ICC profiles that are three-component matrix-based.
+
+ If the ICC profile is not supported an invalid QColorSpace is returned
+ where you can still read the original ICC profile using iccProfile().
+
+ \sa iccProfile()
+*/
+QColorSpace QColorSpace::fromIccProfile(const QByteArray &iccProfile)
+{
+ QColorSpace colorSpace;
+ if (QIcc::fromIccProfile(iccProfile, &colorSpace))
+ return colorSpace;
+ colorSpace.d_ptr->id = QColorSpace::Undefined;
+ colorSpace.d_ptr->iccProfile = iccProfile;
+ return colorSpace;
+}
+
+/*!
+ Returns \c true if the color space is valid.
+*/
+bool QColorSpace::isValid() const noexcept
+{
+ return d_ptr->id != QColorSpace::Undefined && d_ptr->toXyz.isValid()
+ && d_ptr->trc[0].isValid() && d_ptr->trc[1].isValid() && d_ptr->trc[2].isValid();
+}
+
+/*!
+ \relates QColorSpace
+ Returns \c true if colorspace \a colorSpace1 is equal to colorspace \a colorSpace2;
+ otherwise returns \c false
+*/
+bool operator==(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2)
+{
+ if (colorSpace1.d_ptr == colorSpace2.d_ptr)
+ return true;
+
+ if (colorSpace1.colorSpaceId() == QColorSpace::Undefined && colorSpace2.colorSpaceId() == QColorSpace::Undefined)
+ return colorSpace1.d_ptr->iccProfile == colorSpace2.d_ptr->iccProfile;
+
+ if (colorSpace1.colorSpaceId() != QColorSpace::Unknown && colorSpace2.colorSpaceId() != QColorSpace::Unknown)
+ return colorSpace1.colorSpaceId() == colorSpace2.colorSpaceId();
+
+ if (colorSpace1.gamut() != QColorSpace::Gamut::Custom && colorSpace2.gamut() != QColorSpace::Gamut::Custom) {
+ if (colorSpace1.gamut() != colorSpace2.gamut())
+ return false;
+ } else {
+ if (colorSpace1.d_ptr->toXyz != colorSpace2.d_ptr->toXyz)
+ return false;
+ }
+
+ if (colorSpace1.transferFunction() != QColorSpace::TransferFunction::Custom &&
+ colorSpace2.transferFunction() != QColorSpace::TransferFunction::Custom) {
+ if (colorSpace1.transferFunction() != colorSpace2.transferFunction())
+ return false;
+ if (colorSpace1.transferFunction() == QColorSpace::TransferFunction::Gamma)
+ return colorSpace1.gamma() == colorSpace2.gamma();
+ return true;
+ }
+
+ if (colorSpace1.d_ptr->trc[0] != colorSpace2.d_ptr->trc[0] ||
+ colorSpace1.d_ptr->trc[1] != colorSpace2.d_ptr->trc[1] ||
+ colorSpace1.d_ptr->trc[2] != colorSpace2.d_ptr->trc[2])
+ return false;
+
+ return true;
+}
+
+/*!
+ \fn bool operator!=(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2)
+ \relates QColorSpace
+
+ Returns \c true if colorspace \a colorspace1 is not equal to colorspace \a colorspace2;
+ otherwise returns \c false
+*/
+
+/*!
+ Generates and returns a color space transformation from this color space to
+ \a colorspace.
+*/
+QColorTransform QColorSpace::transformationToColorSpace(const QColorSpace &colorspace) const
+{
+ if (!isValid() || !colorspace.isValid())
+ return QColorTransform();
+
+ return d_ptr->transformationToColorSpace(colorspace.d_ptr.constData());
+}
+
+/*!
+ \internal
+*/
+QColorSpacePrivate *QColorSpace::d_func()
+{
+ d_ptr.detach();
+ return d_ptr.data();
+}
+
+/*!
+ \fn const QColorSpacePrivate* QColorSpacePrivate::d_func() const
+ \internal
+*/
+
+/*****************************************************************************
+ QColorSpace stream functions
+ *****************************************************************************/
+#if !defined(QT_NO_DATASTREAM)
+/*!
+ \fn QDataStream &operator<<(QDataStream &stream, const QColorSpace &colorSpace)
+ \relates QColorSpace
+
+ Writes the given \a colorSpace to the given \a stream as an ICC profile.
+
+ \sa QColorSpace::iccProfile(), {Serializing Qt Data Types}
+*/
+
+QDataStream &operator<<(QDataStream &s, const QColorSpace &image)
+{
+ s << image.iccProfile();
+ return s;
+}
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &stream, QColorSpace &colorSpace)
+ \relates QColorSpace
+
+ Reads a color space from the given \a stream and stores it in the given
+ \a colorSpace.
+
+ \sa QColorSpace::fromIccProfile(), {Serializing Qt Data Types}
+*/
+
+QDataStream &operator>>(QDataStream &s, QColorSpace &colorSpace)
+{
+ QByteArray iccProfile;
+ s >> iccProfile;
+ colorSpace = QColorSpace::fromIccProfile(iccProfile);
+ return s;
+}
+#endif // QT_NO_DATASTREAM
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QColorSpace &colorSpace)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace();
+ dbg << "QColorSpace(";
+ dbg << colorSpace.colorSpaceId() << ", " << colorSpace.gamut() << ", " << colorSpace.transferFunction();
+ dbg << ", gamma=" << colorSpace.gamma();
+ dbg << ')';
+ return dbg;
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/gui/painting/qcolorspace.h b/src/gui/painting/qcolorspace.h
new file mode 100644
index 0000000000..923546ec6f
--- /dev/null
+++ b/src/gui/painting/qcolorspace.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOLORSPACE_H
+#define QCOLORSPACE_H
+
+#include <QtGui/qtguiglobal.h>
+#include <QtGui/qcolortransform.h>
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+
+class QColorSpacePrivate;
+
+class Q_GUI_EXPORT QColorSpace
+{
+ Q_GADGET
+public:
+ enum ColorSpaceId {
+ Undefined = 0,
+ Unknown = 1,
+ SRgb,
+ SRgbLinear,
+ AdobeRgb,
+ DisplayP3,
+ ProPhotoRgb,
+ Bt2020,
+ };
+ Q_ENUM(ColorSpaceId)
+ enum class Gamut {
+ Custom = 0,
+ SRgb,
+ AdobeRgb,
+ DciP3D65,
+ ProPhotoRgb,
+ Bt2020,
+ };
+ Q_ENUM(Gamut)
+ enum class TransferFunction {
+ Custom = 0,
+ Linear,
+ Gamma,
+ SRgb,
+ ProPhotoRgb,
+ Bt2020,
+ };
+ Q_ENUM(TransferFunction)
+
+ QColorSpace(ColorSpaceId colorSpaceId = Undefined);
+ QColorSpace(Gamut gamut, TransferFunction fun, float gamma = 0.0f);
+ QColorSpace(Gamut gamut, float gamma);
+ ~QColorSpace();
+
+ QColorSpace(QColorSpace &&colorSpace);
+ QColorSpace(const QColorSpace &colorSpace);
+ QColorSpace &operator=(QColorSpace &&colorSpace);
+ QColorSpace &operator=(const QColorSpace &colorSpace);
+
+ ColorSpaceId colorSpaceId() const noexcept;
+ Gamut gamut() const noexcept;
+ TransferFunction transferFunction() const noexcept;
+ float gamma() const noexcept;
+
+ bool isValid() const noexcept;
+
+ friend Q_GUI_EXPORT bool operator==(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2);
+ friend inline bool operator!=(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2);
+
+ static QColorSpace fromIccProfile(const QByteArray &iccProfile);
+ QByteArray iccProfile() const;
+
+ QColorTransform transformationToColorSpace(const QColorSpace &colorspace) const;
+
+ QColorSpacePrivate *d_func();
+ inline const QColorSpacePrivate *d_func() const { return d_ptr.constData(); }
+
+private:
+ friend class QColorSpacePrivate;
+ QExplicitlySharedDataPointer<QColorSpacePrivate> d_ptr;
+};
+
+bool Q_GUI_EXPORT operator==(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2);
+inline bool operator!=(const QColorSpace &colorSpace1, const QColorSpace &colorSpace2)
+{
+ return !(colorSpace1 == colorSpace2);
+}
+
+// QColorSpace stream functions
+#if !defined(QT_NO_DATASTREAM)
+Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QColorSpace &);
+Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QColorSpace &);
+#endif
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug, const QColorSpace &);
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QCOLORSPACE_P_H
diff --git a/src/plugins/platforms/mirclient/qmirclientclipboard.h b/src/gui/painting/qcolorspace_p.h
index 09e9bcdf38..91107a9a89 100644
--- a/src/plugins/platforms/mirclient/qmirclientclipboard.h
+++ b/src/gui/painting/qcolorspace_p.h
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2016 Canonical, Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -37,56 +37,60 @@
**
****************************************************************************/
+#ifndef QCOLORSPACE_P_H
+#define QCOLORSPACE_P_H
-#ifndef QMIRCLIENTCLIPBOARD_H
-#define QMIRCLIENTCLIPBOARD_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
-#include <qpa/qplatformclipboard.h>
+#include "qcolorspace.h"
+#include "qcolormatrix_p.h"
+#include "qcolortrc_p.h"
+#include "qcolortrclut_p.h"
-#include <QMimeData>
-#include <QPointer>
+#include <QtCore/qshareddata.h>
-namespace com {
- namespace ubuntu {
- namespace content {
- class Hub;
- }
- }
-}
+QT_BEGIN_NAMESPACE
-class QDBusPendingCallWatcher;
-
-class QMirClientClipboard : public QObject, public QPlatformClipboard
+class QColorSpacePrivate : public QSharedData
{
- Q_OBJECT
public:
- QMirClientClipboard();
- virtual ~QMirClientClipboard();
-
- // QPlatformClipboard methods.
- QMimeData* mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override;
- void setMimeData(QMimeData* data, QClipboard::Mode mode = QClipboard::Clipboard) override;
- bool supportsMode(QClipboard::Mode mode) const override;
- bool ownsMode(QClipboard::Mode mode) const override;
+ QColorSpacePrivate();
+ QColorSpacePrivate(QColorSpace::ColorSpaceId colorSpaceId);
+ QColorSpacePrivate(QColorSpace::Gamut gamut, QColorSpace::TransferFunction fun, float gamma);
+ QColorSpacePrivate(const QColorSpacePrivate &other) = default;
+ QColorSpacePrivate &operator=(const QColorSpacePrivate &other) = default;
-private Q_SLOTS:
- void onApplicationStateChanged(Qt::ApplicationState state);
+ void initialize();
+ void setToXyzMatrix();
+ void setTransferFunction();
+ bool identifyColorSpace();
+ QColorTransform transformationToColorSpace(const QColorSpacePrivate *out) const;
-private:
- void updateMimeData();
- void requestMimeData();
+ QColorSpace::ColorSpaceId id;
+ QColorSpace::Gamut gamut;
+ QColorSpace::TransferFunction transferFunction;
+ float gamma;
+ QColorVector whitePoint;
- QMimeData *mMimeData;
+ QColorTrc trc[3];
+ QColorMatrix toXyz;
- enum {
- OutdatedClipboard, // Our mimeData is outdated, need to fetch latest from ContentHub
- SyncingClipboard, // Our mimeData is outdated and we are waiting for ContentHub to reply with the latest paste
- SyncedClipboard // Our mimeData is in sync with what ContentHub has
- } mClipboardState{OutdatedClipboard};
+ QString description;
+ QByteArray iccProfile;
- com::ubuntu::content::Hub *mContentHub;
-
- QDBusPendingCallWatcher *mPasteReply{nullptr};
+ mutable QSharedPointer<QColorTrcLut> lut[3];
+ mutable QAtomicInt lutsGenerated;
};
-#endif // QMIRCLIENTCLIPBOARD_H
+QT_END_NAMESPACE
+
+#endif // QCOLORSPACE_P_H
diff --git a/src/gui/painting/qcolortransferfunction_p.h b/src/gui/painting/qcolortransferfunction_p.h
new file mode 100644
index 0000000000..fd7cfa2b2b
--- /dev/null
+++ b/src/gui/painting/qcolortransferfunction_p.h
@@ -0,0 +1,207 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOLORTRANSFERFUNCTION_P_H
+#define QCOLORTRANSFERFUNCTION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/private/qtguiglobal_p.h>
+
+#include <cmath>
+
+QT_BEGIN_NAMESPACE
+
+// Defines a ICC parametric curve type 4
+class Q_GUI_EXPORT QColorTransferFunction
+{
+public:
+ QColorTransferFunction() noexcept
+ : m_a(1.0f), m_b(0.0f), m_c(1.0f), m_d(0.0f), m_e(0.0f), m_f(0.0f), m_g(1.0f), m_flags(0)
+ { }
+ QColorTransferFunction(float a, float b, float c, float d, float e, float f, float g) noexcept
+ : m_a(a), m_b(b), m_c(c), m_d(d), m_e(e), m_f(f), m_g(g), m_flags(0)
+ { }
+
+ bool isGamma() const
+ {
+ updateHints();
+ return m_flags & quint32(Hints::IsGamma);
+ }
+ bool isLinear() const
+ {
+ updateHints();
+ return m_flags & quint32(Hints::IsLinear);
+ }
+ bool isSRgb() const
+ {
+ updateHints();
+ return m_flags & quint32(Hints::IsSRgb);
+ }
+
+ float apply(float x) const
+ {
+ if (x < m_d)
+ return m_c * x + m_f;
+ else
+ return std::pow(m_a * x + m_b, m_g) + m_e;
+ }
+
+ QColorTransferFunction inverted() const
+ {
+ float a, b, c, d, e, f, g;
+
+ d = m_c * m_d + m_f;
+
+ if (!qFuzzyIsNull(m_c)) {
+ c = 1.0f / m_c;
+ f = -m_f / m_c;
+ } else {
+ c = 0.0f;
+ f = 0.0f;
+ }
+
+ if (!qFuzzyIsNull(m_a) && !qFuzzyIsNull(m_g)) {
+ a = std::pow(1.0f / m_a, m_g);
+ b = -a * m_e;
+ e = -m_b / m_a;
+ g = 1.0f / m_g;
+ } else {
+ a = 0.0f;
+ b = 0.0f;
+ e = 1.0f;
+ g = 1.0f;
+ }
+
+ return QColorTransferFunction(a, b, c, d, e, f, g);
+ }
+
+ // A few predefined curves:
+ static QColorTransferFunction fromGamma(float gamma)
+ {
+ return QColorTransferFunction(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, gamma);
+ }
+ static QColorTransferFunction fromSRgb()
+ {
+ return QColorTransferFunction(1.0f / 1.055f, 0.055f / 1.055f, 1.0f / 12.92f, 0.04045f, 0.0f, 0.0f, 2.4f);
+ }
+ static QColorTransferFunction fromBt2020()
+ {
+ return QColorTransferFunction(1.0f / 1.0993f, 0.0993f / 1.0993f, 1.0f / 4.5f, 0.08145f, 0.0f, 0.0f, 2.2f);
+ }
+ static QColorTransferFunction fromProPhotoRgb()
+ {
+ return QColorTransferFunction(1.0f, 0.0f, 1.0f / 16.0f, 16.0f / 512.0f, 0.0f, 0.0f, 1.8f);
+ }
+ bool matches(const QColorTransferFunction &o) const
+ {
+ return paramCompare(m_a, o.m_a) && paramCompare(m_b, o.m_b)
+ && paramCompare(m_c, o.m_c) && paramCompare(m_d, o.m_d)
+ && paramCompare(m_e, o.m_e) && paramCompare(m_f, o.m_f)
+ && paramCompare(m_g, o.m_g);
+ }
+ friend inline bool operator==(const QColorTransferFunction &f1, const QColorTransferFunction &f2);
+ friend inline bool operator!=(const QColorTransferFunction &f1, const QColorTransferFunction &f2);
+
+ float m_a;
+ float m_b;
+ float m_c;
+ float m_d;
+ float m_e;
+ float m_f;
+ float m_g;
+
+private:
+ static inline bool paramCompare(float p1, float p2)
+ {
+ // Much fuzzier than fuzzy compare.
+ // It tries match parameters that has been passed through a 8.8
+ // fixed point form.
+ return (qAbs(p1 - p2) <= (1.0f / 512.0f));
+ }
+
+ void updateHints() const
+ {
+ if (m_flags & quint32(Hints::Calculated))
+ return;
+ // We do not consider the case with m_d = 1.0f linear or simple,
+ // since it wouldn't be linear for applyExtended().
+ bool simple = paramCompare(m_a, 1.0f) && paramCompare(m_b, 0.0f)
+ && paramCompare(m_d, 0.0f)
+ && paramCompare(m_e, 0.0f);
+ if (simple) {
+ m_flags |= quint32(Hints::IsGamma);
+ if (qFuzzyCompare(m_g, 1.0f))
+ m_flags |= quint32(Hints::IsLinear);
+ } else {
+ if (*this == fromSRgb())
+ m_flags |= quint32(Hints::IsSRgb);
+ }
+ m_flags |= quint32(Hints::Calculated);
+ }
+ enum class Hints : quint32 {
+ Calculated = 1,
+ IsGamma = 2,
+ IsLinear = 4,
+ IsSRgb = 8
+ };
+ mutable quint32 m_flags;
+};
+
+inline bool operator==(const QColorTransferFunction &f1, const QColorTransferFunction &f2)
+{
+ return f1.matches(f2);
+}
+inline bool operator!=(const QColorTransferFunction &f1, const QColorTransferFunction &f2)
+{
+ return !f1.matches(f2);
+}
+
+QT_END_NAMESPACE
+
+#endif // QCOLORTRANSFERFUNCTION_P_H
diff --git a/src/gui/painting/qcolortransfertable_p.h b/src/gui/painting/qcolortransfertable_p.h
new file mode 100644
index 0000000000..c8b2f7bd92
--- /dev/null
+++ b/src/gui/painting/qcolortransfertable_p.h
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOLORTRANSFERTABLE_P_H
+#define QCOLORTRANSFERTABLE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/private/qtguiglobal_p.h>
+#include "qcolortransferfunction_p.h"
+
+#include <QVector>
+#include <cmath>
+
+QT_BEGIN_NAMESPACE
+
+// Defines either an ICC TRC 'curve' or a lut8/lut16 A or B table
+class Q_GUI_EXPORT QColorTransferTable
+{
+public:
+ QColorTransferTable() noexcept
+ : m_tableSize(0)
+ { }
+ QColorTransferTable(uint32_t size, const QVector<uint8_t> &table) noexcept
+ : m_tableSize(size)
+ , m_table8(table)
+ { }
+ QColorTransferTable(uint32_t size, const QVector<uint16_t> &table) noexcept
+ : m_tableSize(size)
+ , m_table16(table)
+ { }
+
+ bool isValid() const
+ {
+ if (m_tableSize < 2)
+ return false;
+
+#if !defined(QT_NO_DEBUG)
+ // The table must describe an injective curve:
+ if (!m_table8.isEmpty()) {
+ uint8_t val = 0;
+ for (uint i = 0; i < m_tableSize; ++i) {
+ Q_ASSERT(m_table8[i] >= val);
+ val = m_table8[i];
+ }
+ }
+ if (!m_table16.isEmpty()) {
+ uint16_t val = 0;
+ for (uint i = 0; i < m_tableSize; ++i) {
+ Q_ASSERT(m_table16[i] >= val);
+ val = m_table16[i];
+ }
+ }
+#endif
+ return !m_table8.isEmpty() || !m_table16.isEmpty();
+ }
+
+ float apply(float x) const
+ {
+ x = std::min(std::max(x, 0.0f), 1.0f);
+ x *= m_tableSize - 1;
+ uint32_t lo = (int)std::floor(x);
+ uint32_t hi = std::min(lo + 1, m_tableSize);
+ float frac = x - lo;
+ if (!m_table16.isEmpty())
+ return (m_table16[lo] * (1.0f - frac) + m_table16[hi] * frac) * (1.0f/65535.0f);
+ if (!m_table8.isEmpty())
+ return (m_table8[lo] * (1.0f - frac) + m_table8[hi] * frac) * (1.0f/255.0f);
+ return x;
+ }
+
+ // Apply inverse, optimized by giving a previous result a value < x.
+ float applyInverse(float x, float resultLargerThan = 0.0f) const
+ {
+ Q_ASSERT(resultLargerThan >= 0.0f && resultLargerThan <= 1.0f);
+ if (x <= 0.0f)
+ return 0.0f;
+ if (x >= 1.0f)
+ return 1.0f;
+ if (!m_table16.isEmpty()) {
+ float v = x * 65535.0f;
+ uint i = std::floor(resultLargerThan * (m_tableSize - 1)) + 1;
+ for ( ; i < m_tableSize; ++i) {
+ if (m_table16[i] > v)
+ break;
+ }
+ if (i >= m_tableSize - 1)
+ return 1.0f;
+ float y1 = m_table16[i - 1];
+ float y2 = m_table16[i];
+ Q_ASSERT(x >= y1 && x < y2);
+ float fr = (v - y1) / (y2 - y1);
+ return (i + fr) * (1.0f / (m_tableSize - 1));
+
+ }
+ if (!m_table8.isEmpty()) {
+ float v = x * 255.0f;
+ uint i = std::floor(resultLargerThan * (m_tableSize - 1)) + 1;
+ for ( ; i < m_tableSize; ++i) {
+ if (m_table8[i] > v)
+ break;
+ }
+ if (i >= m_tableSize - 1)
+ return 1.0f;
+ float y1 = m_table8[i - 1];
+ float y2 = m_table8[i];
+ Q_ASSERT(x >= y1 && x < y2);
+ float fr = (v - y1) / (y2 - y1);
+ return (i + fr) * (1.0f / (m_tableSize - 1));
+ }
+ return x;
+ }
+
+ bool asColorTransferFunction(QColorTransferFunction *transferFn)
+ {
+ Q_ASSERT(isValid());
+ Q_ASSERT(transferFn);
+ if (!m_table8.isEmpty() && (m_table8[0] != 0 || m_table8[m_tableSize - 1] != 255))
+ return false;
+ if (!m_table16.isEmpty() && (m_table16[0] != 0 || m_table16[m_tableSize - 1] != 65535))
+ return false;
+ if (m_tableSize == 2) {
+ *transferFn = QColorTransferFunction(); // Linear
+ return true;
+ }
+ // The following heuristics are based on those from Skia:
+ if (m_tableSize == 26 && !m_table16.isEmpty()) {
+ // code.facebook.com/posts/411525055626587/under-the-hood-improving-facebook-photos
+ if (m_table16[6] != 3062)
+ return false;
+ if (m_table16[12] != 12824)
+ return false;
+ if (m_table16[18] != 31237)
+ return false;
+ *transferFn = QColorTransferFunction::fromSRgb();
+ return true;
+ }
+ if (m_tableSize == 1024 && !m_table16.isEmpty()) {
+ // HP and Canon sRGB gamma tables:
+ if (m_table16[257] != 3366)
+ return false;
+ if (m_table16[513] != 14116)
+ return false;
+ if (m_table16[768] != 34318)
+ return false;
+ *transferFn = QColorTransferFunction::fromSRgb();
+ return true;
+ }
+ if (m_tableSize == 4096 && !m_table16.isEmpty()) {
+ // Nikon, Epson, and lcms2 sRGB gamma tables:
+ if (m_table16[515] != 960)
+ return false;
+ if (m_table16[1025] != 3342)
+ return false;
+ if (m_table16[2051] != 14079)
+ return false;
+ *transferFn = QColorTransferFunction::fromSRgb();
+ return true;
+ }
+ return false;
+ }
+ friend inline bool operator!=(const QColorTransferTable &t1, const QColorTransferTable &t2);
+ friend inline bool operator==(const QColorTransferTable &t1, const QColorTransferTable &t2);
+
+ uint32_t m_tableSize;
+ QVector<uint8_t> m_table8;
+ QVector<uint16_t> m_table16;
+};
+
+inline bool operator!=(const QColorTransferTable &t1, const QColorTransferTable &t2)
+{
+ if (t1.m_tableSize != t2.m_tableSize)
+ return true;
+ if (t1.m_table8.isEmpty() != t2.m_table8.isEmpty())
+ return true;
+ if (t1.m_table16.isEmpty() != t2.m_table16.isEmpty())
+ return true;
+ if (!t1.m_table8.isEmpty()) {
+ for (quint32 i = 0; i < t1.m_tableSize; ++i) {
+ if (t1.m_table8[i] != t2.m_table8[i])
+ return true;
+ }
+ }
+ if (!t1.m_table16.isEmpty()) {
+ for (quint32 i = 0; i < t1.m_tableSize; ++i) {
+ if (t1.m_table16[i] != t2.m_table16[i])
+ return true;
+ }
+ }
+ return false;
+}
+
+inline bool operator==(const QColorTransferTable &t1, const QColorTransferTable &t2)
+{
+ return !(t1 != t2);
+}
+
+QT_END_NAMESPACE
+
+#endif // QCOLORTRANSFERTABLE_P_H
diff --git a/src/gui/painting/qcolortransform.cpp b/src/gui/painting/qcolortransform.cpp
new file mode 100644
index 0000000000..b677c4b36b
--- /dev/null
+++ b/src/gui/painting/qcolortransform.cpp
@@ -0,0 +1,679 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qcolortransform.h"
+#include "qcolortransform_p.h"
+
+#include "qcolormatrix_p.h"
+#include "qcolorspace_p.h"
+#include "qcolortrc_p.h"
+#include "qcolortrclut_p.h"
+
+#include <QtCore/qatomic.h>
+#include <QtCore/qmath.h>
+#include <QtGui/qcolor.h>
+#include <QtGui/qtransform.h>
+#include <QtCore/private/qsimd_p.h>
+
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+QColorTrcLut *lutFromTrc(const QColorTrc &trc)
+{
+ if (trc.m_type == QColorTrc::Type::Table)
+ return QColorTrcLut::fromTransferTable(trc.m_table);
+ if (trc.m_type == QColorTrc::Type::Function)
+ return QColorTrcLut::fromTransferFunction(trc.m_fun);
+ qWarning() << "TRC uninitialized";
+ return nullptr;
+}
+
+void QColorTransformPrivate::updateLutsIn() const
+{
+ if (colorSpaceIn->lutsGenerated.loadAcquire())
+ return;
+ for (int i = 0; i < 3; ++i) {
+ if (!colorSpaceIn->trc[i].isValid())
+ return;
+ }
+
+ if (colorSpaceIn->trc[0] == colorSpaceIn->trc[1] && colorSpaceIn->trc[0] == colorSpaceIn->trc[2]) {
+ colorSpaceIn->lut[0].reset(lutFromTrc(colorSpaceIn->trc[0]));
+ colorSpaceIn->lut[1] = colorSpaceIn->lut[0];
+ colorSpaceIn->lut[2] = colorSpaceIn->lut[0];
+ } else {
+ for (int i = 0; i < 3; ++i)
+ colorSpaceIn->lut[i].reset(lutFromTrc(colorSpaceIn->trc[i]));
+ }
+
+ colorSpaceIn->lutsGenerated.storeRelease(1);
+}
+
+void QColorTransformPrivate::updateLutsOut() const
+{
+ if (colorSpaceOut->lutsGenerated.loadAcquire())
+ return;
+ for (int i = 0; i < 3; ++i) {
+ if (!colorSpaceOut->trc[i].isValid())
+ return;
+ }
+
+ if (colorSpaceOut->trc[0] == colorSpaceOut->trc[1] && colorSpaceOut->trc[0] == colorSpaceOut->trc[2]) {
+ colorSpaceOut->lut[0].reset(lutFromTrc(colorSpaceOut->trc[0]));
+ colorSpaceOut->lut[1] = colorSpaceOut->lut[0];
+ colorSpaceOut->lut[2] = colorSpaceOut->lut[0];
+ } else {
+ for (int i = 0; i < 3; ++i)
+ colorSpaceOut->lut[i].reset(lutFromTrc(colorSpaceOut->trc[i]));
+ }
+
+ colorSpaceOut->lutsGenerated.storeRelease(1);
+}
+
+/*!
+ \class QColorTransform
+ \brief The QColorTransform class is a transformation between color spaces.
+ \since 5.14
+
+ \ingroup painting
+ \ingroup appearance
+ \inmodule QtGui
+
+ QColorTransform is an instantiation of a transformation between color spaces.
+ It can be applied on color and pixels to convert them from one color space to
+ another.
+
+ Setting up a QColorTransform takes some preprocessing, so keeping around
+ QColorTransforms that you need often is recommended, instead of generating
+ them on the fly.
+*/
+
+
+QColorTransform::~QColorTransform() noexcept
+{
+}
+
+/*!
+ Applies the color transformation on the QRgb value \a argb.
+
+ The input should be opaque or unpremultiplied.
+*/
+QRgb QColorTransform::map(const QRgb &argb) const
+{
+ if (!d_ptr)
+ return argb;
+ Q_D(const QColorTransform);
+ constexpr float f = 1.0f / 255.0f;
+ QColorVector c = { qRed(argb) * f, qGreen(argb) * f, qBlue(argb) * f };
+ c.x = d->colorSpaceIn->trc[0].apply(c.x);
+ c.y = d->colorSpaceIn->trc[1].apply(c.y);
+ c.z = d->colorSpaceIn->trc[2].apply(c.z);
+ c = d->colorMatrix.map(c);
+ c.x = std::max(0.0f, std::min(1.0f, c.x));
+ c.y = std::max(0.0f, std::min(1.0f, c.y));
+ c.z = std::max(0.0f, std::min(1.0f, c.z));
+ if (d->colorSpaceOut->lutsGenerated.loadAcquire()) {
+ c.x = d->colorSpaceOut->lut[0]->fromLinear(c.x);
+ c.y = d->colorSpaceOut->lut[1]->fromLinear(c.y);
+ c.z = d->colorSpaceOut->lut[2]->fromLinear(c.z);
+ } else {
+ c.x = d->colorSpaceOut->trc[0].applyInverse(c.x);
+ c.y = d->colorSpaceOut->trc[1].applyInverse(c.y);
+ c.z = d->colorSpaceOut->trc[2].applyInverse(c.z);
+ }
+
+ return qRgba(c.x * 255 + 0.5f, c.y * 255 + 0.5f, c.z * 255 + 0.5f, qAlpha(argb));
+}
+
+/*!
+ Applies the color transformation on the QRgba64 value \a rgba64.
+
+ The input should be opaque or unpremultiplied.
+*/
+QRgba64 QColorTransform::map(const QRgba64 &rgba64) const
+{
+ if (!d_ptr)
+ return rgba64;
+ Q_D(const QColorTransform);
+ constexpr float f = 1.0f / 65535.0f;
+ QColorVector c = { rgba64.red() * f, rgba64.green() * f, rgba64.blue() * f };
+ c.x = d->colorSpaceIn->trc[0].apply(c.x);
+ c.y = d->colorSpaceIn->trc[1].apply(c.y);
+ c.z = d->colorSpaceIn->trc[2].apply(c.z);
+ c = d->colorMatrix.map(c);
+ c.x = std::max(0.0f, std::min(1.0f, c.x));
+ c.y = std::max(0.0f, std::min(1.0f, c.y));
+ c.z = std::max(0.0f, std::min(1.0f, c.z));
+ if (d->colorSpaceOut->lutsGenerated.loadAcquire()) {
+ c.x = d->colorSpaceOut->lut[0]->fromLinear(c.x);
+ c.y = d->colorSpaceOut->lut[1]->fromLinear(c.y);
+ c.z = d->colorSpaceOut->lut[2]->fromLinear(c.z);
+ } else {
+ c.x = d->colorSpaceOut->trc[0].applyInverse(c.x);
+ c.y = d->colorSpaceOut->trc[1].applyInverse(c.y);
+ c.z = d->colorSpaceOut->trc[2].applyInverse(c.z);
+ }
+
+ return QRgba64::fromRgba64(c.x * 65535, c.y * 65535, c.z * 65535, rgba64.alpha());
+}
+
+/*!
+ Applies the color transformation on the QColor value \a color.
+
+*/
+QColor QColorTransform::map(const QColor &color) const
+{
+ if (!d_ptr)
+ return color;
+ Q_D(const QColorTransform);
+ QColorVector c = { (float)color.redF(), (float)color.greenF(), (float)color.blueF() };
+ c.x = d->colorSpaceIn->trc[0].apply(c.x);
+ c.y = d->colorSpaceIn->trc[1].apply(c.y);
+ c.z = d->colorSpaceIn->trc[2].apply(c.z);
+ c = d->colorMatrix.map(c);
+ if (d_ptr->colorSpaceOut->lutsGenerated.loadAcquire()) {
+ c.x = d->colorSpaceOut->lut[0]->fromLinear(c.x);
+ c.y = d->colorSpaceOut->lut[1]->fromLinear(c.y);
+ c.z = d->colorSpaceOut->lut[2]->fromLinear(c.z);
+ } else {
+ c.x = d->colorSpaceOut->trc[0].applyInverse(c.x);
+ c.y = d->colorSpaceOut->trc[1].applyInverse(c.y);
+ c.z = d->colorSpaceOut->trc[2].applyInverse(c.z);
+ }
+ QColor out;
+ out.setRgbF(c.x, c.y, c.z, color.alphaF());
+ return out;
+}
+
+// Optimized sub-routines for fast block based conversion:
+
+static void applyMatrix(QColorVector *buffer, const qsizetype len, const QColorMatrix &colorMatrix)
+{
+#if defined(__SSE2__)
+ const __m128 minV = _mm_set1_ps(0.0f);
+ const __m128 maxV = _mm_set1_ps(1.0f);
+ const __m128 xMat = _mm_loadu_ps(&colorMatrix.r.x);
+ const __m128 yMat = _mm_loadu_ps(&colorMatrix.g.x);
+ const __m128 zMat = _mm_loadu_ps(&colorMatrix.b.x);
+ for (qsizetype j = 0; j < len; ++j) {
+ __m128 c = _mm_loadu_ps(&buffer[j].x);
+ __m128 cx = _mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0));
+ __m128 cy = _mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1));
+ __m128 cz = _mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2));
+ cx = _mm_mul_ps(cx, xMat);
+ cy = _mm_mul_ps(cy, yMat);
+ cz = _mm_mul_ps(cz, zMat);
+ cx = _mm_add_ps(cx, cy);
+ cx = _mm_add_ps(cx, cz);
+ // Clamp:
+ cx = _mm_min_ps(cx, maxV);
+ cx = _mm_max_ps(cx, minV);
+ _mm_storeu_ps(&buffer[j].x, cx);
+ }
+#else
+ for (int j = 0; j < len; ++j) {
+ const QColorVector cv = colorMatrix.map(buffer[j]);
+ buffer[j].x = std::max(0.0f, std::min(1.0f, cv.x));
+ buffer[j].y = std::max(0.0f, std::min(1.0f, cv.y));
+ buffer[j].z = std::max(0.0f, std::min(1.0f, cv.z));
+ }
+#endif
+}
+
+template<typename T>
+static void loadPremultiplied(QColorVector *buffer, const T *src, const qsizetype len, const QColorTransformPrivate *d_ptr);
+template<typename T>
+static void loadUnpremultiplied(QColorVector *buffer, const T *src, const qsizetype len, const QColorTransformPrivate *d_ptr);
+
+#if defined(__SSE2__)
+// Load to [0-alpha] in 4x32 SIMD
+template<typename T>
+static inline void loadP(const T &p, __m128i &v);
+
+template<>
+inline void loadP<QRgb>(const QRgb &p, __m128i &v)
+{
+ v = _mm_cvtsi32_si128(p);
+#if defined(__SSE4_1__)
+ v = _mm_cvtepu8_epi32(v);
+#else
+ v = _mm_unpacklo_epi8(v, _mm_setzero_si128());
+ v = _mm_unpacklo_epi16(v, _mm_setzero_si128());
+#endif
+}
+
+template<>
+inline void loadP<QRgba64>(const QRgba64 &p, __m128i &v)
+{
+ v = _mm_loadl_epi64((const __m128i *)&p);
+#if defined(__SSE4_1__)
+ v = _mm_cvtepu16_epi32(v);
+#else
+ v = _mm_unpacklo_epi16(v, _mm_setzero_si128());
+#endif
+ // Shuffle to ARGB as the template below expects it
+ v = _mm_shuffle_epi32(v, _MM_SHUFFLE(3, 0, 1, 2));
+}
+
+template<typename T>
+static void loadPremultiplied(QColorVector *buffer, const T *src, const qsizetype len, const QColorTransformPrivate *d_ptr)
+{
+ const __m128 v4080 = _mm_set1_ps(4080.f);
+ const __m128 iFF00 = _mm_set1_ps(1.0f / (255 * 256));
+ for (qsizetype i = 0; i < len; ++i) {
+ __m128i v;
+ loadP<T>(src[i], v);
+ __m128 vf = _mm_cvtepi32_ps(v);
+ // Approximate 1/a:
+ __m128 va = _mm_shuffle_ps(vf, vf, _MM_SHUFFLE(3, 3, 3, 3));
+ __m128 via = _mm_rcp_ps(va);
+ via = _mm_sub_ps(_mm_add_ps(via, via), _mm_mul_ps(via, _mm_mul_ps(via, va)));
+ // v * (1/a)
+ vf = _mm_mul_ps(vf, via);
+
+ // Handle zero alpha
+ __m128 vAlphaMask = _mm_cmpeq_ps(va, _mm_set1_ps(0.0f));
+ vf = _mm_andnot_ps(vAlphaMask, vf);
+
+ // LUT
+ v = _mm_cvtps_epi32(_mm_mul_ps(vf, v4080));
+ const int ridx = _mm_extract_epi16(v, 4);
+ const int gidx = _mm_extract_epi16(v, 2);
+ const int bidx = _mm_extract_epi16(v, 0);
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx], 0);
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx], 2);
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx], 4);
+ vf = _mm_mul_ps(_mm_cvtepi32_ps(v), iFF00);
+
+ _mm_storeu_ps(&buffer[i].x, vf);
+ }
+}
+
+// Load to [0-4080] in 4x32 SIMD
+template<typename T>
+static inline void loadPU(const T &p, __m128i &v);
+
+template<>
+inline void loadPU<QRgb>(const QRgb &p, __m128i &v)
+{
+ v = _mm_cvtsi32_si128(p);
+#if defined(__SSE4_1__)
+ v = _mm_cvtepu8_epi32(v);
+#else
+ v = _mm_unpacklo_epi8(v, _mm_setzero_si128());
+ v = _mm_unpacklo_epi16(v, _mm_setzero_si128());
+#endif
+ v = _mm_slli_epi32(v, 4);
+}
+
+template<>
+inline void loadPU<QRgba64>(const QRgba64 &p, __m128i &v)
+{
+ v = _mm_loadl_epi64((const __m128i *)&p);
+ v = _mm_sub_epi16(v, _mm_srli_epi16(v, 8));
+#if defined(__SSE4_1__)
+ v = _mm_cvtepu16_epi32(v);
+#else
+ v = _mm_unpacklo_epi16(v, _mm_setzero_si128());
+#endif
+ v = _mm_srli_epi32(v, 4);
+ // Shuffle to ARGB as the template below expects it
+ v = _mm_shuffle_epi32(v, _MM_SHUFFLE(3, 0, 1, 2));
+}
+
+template<typename T>
+void loadUnpremultiplied(QColorVector *buffer, const T *src, const qsizetype len, const QColorTransformPrivate *d_ptr)
+{
+ const __m128 iFF00 = _mm_set1_ps(1.0f / (255 * 256));
+ for (qsizetype i = 0; i < len; ++i) {
+ __m128i v;
+ loadPU<T>(src[i], v);
+ const int ridx = _mm_extract_epi16(v, 4);
+ const int gidx = _mm_extract_epi16(v, 2);
+ const int bidx = _mm_extract_epi16(v, 0);
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx], 0);
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx], 2);
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx], 4);
+ __m128 vf = _mm_mul_ps(_mm_cvtepi32_ps(v), iFF00);
+ _mm_storeu_ps(&buffer[i].x, vf);
+ }
+}
+
+#else
+template<>
+void loadPremultiplied<QRgb>(QColorVector *buffer, const QRgb *src, const qsizetype len, const QColorTransformPrivate *d_ptr)
+{
+ for (qsizetype i = 0; i < len; ++i) {
+ const uint p = src[i];
+ const int a = qAlpha(p);
+ if (a) {
+ const float ia = 4080.0f / a;
+ const int ridx = int(qRed(p) * ia + 0.5f);
+ const int gidx = int(qGreen(p) * ia + 0.5f);
+ const int bidx = int(qBlue(p) * ia + 0.5f);
+ buffer[i].x = d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx] * (1.0f / (255 * 256));
+ buffer[i].y = d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx] * (1.0f / (255 * 256));
+ buffer[i].z = d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx] * (1.0f / (255 * 256));
+ } else {
+ buffer[i].x = buffer[i].y = buffer[i].z = 0.0f;
+ }
+ }
+}
+
+template<>
+void loadPremultiplied<QRgba64>(QColorVector *buffer, const QRgba64 *src, const qsizetype len, const QColorTransformPrivate *d_ptr)
+{
+ for (qsizetype i = 0; i < len; ++i) {
+ const QRgba64 &p = src[i];
+ const int a = p.alpha();
+ if (a) {
+ const float ia = 4080.0f / a;
+ const int ridx = int(p.red() * ia + 0.5f);
+ const int gidx = int(p.green() * ia + 0.5f);
+ const int bidx = int(p.blue() * ia + 0.5f);
+ buffer[i].x = d_ptr->colorSpaceIn->lut[0]->m_toLinear[ridx] * (1.0f / (255 * 256));
+ buffer[i].y = d_ptr->colorSpaceIn->lut[1]->m_toLinear[gidx] * (1.0f / (255 * 256));
+ buffer[i].z = d_ptr->colorSpaceIn->lut[2]->m_toLinear[bidx] * (1.0f / (255 * 256));
+ } else {
+ buffer[i].x = buffer[i].y = buffer[i].z = 0.0f;
+ }
+ }
+}
+
+template<>
+void loadUnpremultiplied<QRgb>(QColorVector *buffer, const QRgb *src, const qsizetype len, const QColorTransformPrivate *d_ptr)
+{
+ for (qsizetype i = 0; i < len; ++i) {
+ const uint p = src[i];
+ buffer[i].x = d_ptr->colorSpaceIn->lut[0]->u8ToLinearF32(qRed(p));
+ buffer[i].y = d_ptr->colorSpaceIn->lut[1]->u8ToLinearF32(qGreen(p));
+ buffer[i].z = d_ptr->colorSpaceIn->lut[2]->u8ToLinearF32(qBlue(p));
+ }
+}
+
+template<>
+void loadUnpremultiplied<QRgba64>(QColorVector *buffer, const QRgba64 *src, const qsizetype len, const QColorTransformPrivate *d_ptr)
+{
+ for (qsizetype i = 0; i < len; ++i) {
+ const QRgba64 &p = src[i];
+ buffer[i].x = d_ptr->colorSpaceIn->lut[0]->u16ToLinearF32(p.red());
+ buffer[i].y = d_ptr->colorSpaceIn->lut[1]->u16ToLinearF32(p.green());
+ buffer[i].z = d_ptr->colorSpaceIn->lut[2]->u16ToLinearF32(p.blue());
+ }
+}
+#endif
+
+static void storePremultiplied(QRgb *dst, const QRgb *src, const QColorVector *buffer, const qsizetype len,
+ const QColorTransformPrivate *d_ptr)
+{
+#if defined(__SSE2__)
+ const __m128 v4080 = _mm_set1_ps(4080.f);
+ const __m128 iFF00 = _mm_set1_ps(1.0f / (255 * 256));
+ for (qsizetype i = 0; i < len; ++i) {
+ const int a = qAlpha(src[i]);
+ __m128 vf = _mm_loadu_ps(&buffer[i].x);
+ __m128i v = _mm_cvtps_epi32(_mm_mul_ps(vf, v4080));
+ __m128 va = _mm_set1_ps(a);
+ va = _mm_mul_ps(va, iFF00);
+ const int ridx = _mm_extract_epi16(v, 0);
+ const int gidx = _mm_extract_epi16(v, 2);
+ const int bidx = _mm_extract_epi16(v, 4);
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[0]->m_fromLinear[ridx], 4);
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[1]->m_fromLinear[gidx], 2);
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[2]->m_fromLinear[bidx], 0);
+ vf = _mm_cvtepi32_ps(v);
+ vf = _mm_mul_ps(vf, va);
+ v = _mm_cvtps_epi32(vf);
+ v = _mm_packs_epi32(v, v);
+ v = _mm_insert_epi16(v, a, 3);
+ v = _mm_packus_epi16(v, v);
+ dst[i] = _mm_cvtsi128_si32(v);
+ }
+#else
+ for (qsizetype i = 0; i < len; ++i) {
+ const int a = qAlpha(src[i]);
+ const float fa = a / (255.0f * 256.0f);
+ const float r = d_ptr->colorSpaceOut->lut[0]->m_fromLinear[int(buffer[i].x * 4080.0f + 0.5f)];
+ const float g = d_ptr->colorSpaceOut->lut[1]->m_fromLinear[int(buffer[i].y * 4080.0f + 0.5f)];
+ const float b = d_ptr->colorSpaceOut->lut[2]->m_fromLinear[int(buffer[i].z * 4080.0f + 0.5f)];
+ dst[i] = qRgba(r * fa + 0.5f, g * fa + 0.5f, b * fa + 0.5f, a);
+ }
+#endif
+}
+
+static void storeUnpremultiplied(QRgb *dst, const QRgb *src, const QColorVector *buffer, const qsizetype len,
+ const QColorTransformPrivate *d_ptr)
+{
+#if defined(__SSE2__)
+ const __m128 v4080 = _mm_set1_ps(4080.f);
+ for (qsizetype i = 0; i < len; ++i) {
+ const int a = qAlpha(src[i]);
+ __m128 vf = _mm_loadu_ps(&buffer[i].x);
+ __m128i v = _mm_cvtps_epi32(_mm_mul_ps(vf, v4080));
+ const int ridx = _mm_extract_epi16(v, 0);
+ const int gidx = _mm_extract_epi16(v, 2);
+ const int bidx = _mm_extract_epi16(v, 4);
+ v = _mm_setzero_si128();
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[0]->m_fromLinear[ridx], 2);
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[1]->m_fromLinear[gidx], 1);
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[2]->m_fromLinear[bidx], 0);
+ v = _mm_add_epi16(v, _mm_set1_epi16(0x80));
+ v = _mm_srli_epi16(v, 8);
+ v = _mm_insert_epi16(v, a, 3);
+ v = _mm_packus_epi16(v, v);
+ dst[i] = _mm_cvtsi128_si32(v);
+ }
+#else
+ for (qsizetype i = 0; i < len; ++i) {
+ const int r = d_ptr->colorSpaceOut->lut[0]->u8FromLinearF32(buffer[i].x);
+ const int g = d_ptr->colorSpaceOut->lut[1]->u8FromLinearF32(buffer[i].y);
+ const int b = d_ptr->colorSpaceOut->lut[2]->u8FromLinearF32(buffer[i].z);
+ dst[i] = (src[i] & 0xff000000) | (r << 16) | (g << 8) | (b << 0);
+ }
+#endif
+}
+
+static void storeOpaque(QRgb *dst, const QRgb *src, const QColorVector *buffer, const qsizetype len,
+ const QColorTransformPrivate *d_ptr)
+{
+ Q_UNUSED(src);
+#if defined(__SSE2__)
+ const __m128 v4080 = _mm_set1_ps(4080.f);
+ for (qsizetype i = 0; i < len; ++i) {
+ __m128 vf = _mm_loadu_ps(&buffer[i].x);
+ __m128i v = _mm_cvtps_epi32(_mm_mul_ps(vf, v4080));
+ const int ridx = _mm_extract_epi16(v, 0);
+ const int gidx = _mm_extract_epi16(v, 2);
+ const int bidx = _mm_extract_epi16(v, 4);
+ v = _mm_setzero_si128();
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[0]->m_fromLinear[ridx], 2);
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[1]->m_fromLinear[gidx], 1);
+ v = _mm_insert_epi16(v, d_ptr->colorSpaceOut->lut[2]->m_fromLinear[bidx], 0);
+ v = _mm_add_epi16(v, _mm_set1_epi16(0x80));
+ v = _mm_srli_epi16(v, 8);
+ v = _mm_insert_epi16(v, 255, 3);
+ v = _mm_packus_epi16(v, v);
+ dst[i] = _mm_cvtsi128_si32(v);
+ }
+#else
+ for (qsizetype i = 0; i < len; ++i) {
+ const int r = d_ptr->colorSpaceOut->lut[0]->u8FromLinearF32(buffer[i].x);
+ const int g = d_ptr->colorSpaceOut->lut[1]->u8FromLinearF32(buffer[i].y);
+ const int b = d_ptr->colorSpaceOut->lut[2]->u8FromLinearF32(buffer[i].z);
+ dst[i] = 0xff000000 | (r << 16) | (g << 8) | (b << 0);
+ }
+#endif
+}
+
+static void storePremultiplied(QRgba64 *dst, const QRgba64 *src, const QColorVector *buffer, const qsizetype len,
+ const QColorTransformPrivate *d_ptr)
+{
+ for (qsizetype i = 0; i < len; ++i) {
+ const int a = src[i].alpha();
+ const float fa = a / (255.0f * 256.0f);
+ const float r = d_ptr->colorSpaceOut->lut[0]->m_fromLinear[int(buffer[i].x * 4080.0f + 0.5f)];
+ const float g = d_ptr->colorSpaceOut->lut[1]->m_fromLinear[int(buffer[i].y * 4080.0f + 0.5f)];
+ const float b = d_ptr->colorSpaceOut->lut[2]->m_fromLinear[int(buffer[i].z * 4080.0f + 0.5f)];
+ dst[i] = qRgba64(r * fa + 0.5f, g * fa + 0.5f, b * fa + 0.5f, a);
+ }
+}
+
+static void storeUnpremultiplied(QRgba64 *dst, const QRgba64 *src, const QColorVector *buffer, const qsizetype len,
+ const QColorTransformPrivate *d_ptr)
+{
+ for (qsizetype i = 0; i < len; ++i) {
+ const int r = d_ptr->colorSpaceOut->lut[0]->u16FromLinearF32(buffer[i].x);
+ const int g = d_ptr->colorSpaceOut->lut[1]->u16FromLinearF32(buffer[i].y);
+ const int b = d_ptr->colorSpaceOut->lut[2]->u16FromLinearF32(buffer[i].z);
+ dst[i] = qRgba64(r, g, b, src[i].alpha());
+ }
+}
+
+static void storeOpaque(QRgba64 *dst, const QRgba64 *src, const QColorVector *buffer, const qsizetype len,
+ const QColorTransformPrivate *d_ptr)
+{
+ Q_UNUSED(src);
+ for (qsizetype i = 0; i < len; ++i) {
+ const int r = d_ptr->colorSpaceOut->lut[0]->u16FromLinearF32(buffer[i].x);
+ const int g = d_ptr->colorSpaceOut->lut[1]->u16FromLinearF32(buffer[i].y);
+ const int b = d_ptr->colorSpaceOut->lut[2]->u16FromLinearF32(buffer[i].z);
+ dst[i] = qRgba64(r, g, b, 0xFFFF);
+ }
+}
+
+static constexpr qsizetype WorkBlockSize = 256;
+
+template<typename T>
+void QColorTransformPrivate::apply(T *dst, const T *src, qsizetype count, TransformFlags flags) const
+{
+ if (!colorMatrix.isValid())
+ return;
+
+ updateLutsIn();
+ updateLutsOut();
+
+ bool doApplyMatrix = (colorMatrix != QColorMatrix::identity());
+
+ QColorVector buffer[WorkBlockSize];
+ qsizetype i = 0;
+ while (i < count) {
+ const qsizetype len = qMin(count - i, WorkBlockSize);
+ if (flags & InputPremultiplied)
+ loadPremultiplied(buffer, src + i, len, this);
+ else
+ loadUnpremultiplied(buffer, src + i, len, this);
+
+ if (doApplyMatrix)
+ applyMatrix(buffer, len, colorMatrix);
+
+ if (flags & InputOpaque)
+ storeOpaque(dst + i, src + i, buffer, len, this);
+ else if (flags & OutputPremultiplied)
+ storePremultiplied(dst + i, src + i, buffer, len, this);
+ else
+ storeUnpremultiplied(dst + i, src + i, buffer, len, this);
+
+ i += len;
+ }
+}
+
+/*!
+ \internal
+ \enum QColorTransformPrivate::TransformFlag
+
+ Defines how the transform is to be applied.
+
+ \value Unpremultiplied The input and output should both be unpremultiplied.
+ \value InputOpaque The input is guaranteed to be opaque.
+ \value InputPremultiplied The input is premultiplied.
+ \value OutputPremultiplied The output should be premultiplied.
+ \value Premultiplied Both input and output should both be premultiplied.
+*/
+
+/*!
+ \internal
+ Prepares a color transformation for fast application. You do not need to
+ call this explicitly as it will be called implicitly on the first transforms, but
+ if you want predictable performance on the first transforms, you can perform it
+ in advance.
+
+ \sa QColorTransform::map(), apply()
+*/
+void QColorTransformPrivate::prepare()
+{
+ updateLutsIn();
+ updateLutsOut();
+}
+
+/*!
+ \internal
+ Applies the color transformation on \a count QRgb pixels starting from
+ \a src and stores the result in \a dst.
+
+ Thread-safe if prepare() has been called first.
+
+ Assumes unpremultiplied data by default. Set \a flags to change defaults.
+
+ \sa prepare()
+*/
+void QColorTransformPrivate::apply(QRgb *dst, const QRgb *src, qsizetype count, TransformFlags flags) const
+{
+ apply<QRgb>(dst, src, count, flags);
+}
+
+/*!
+ \internal
+ Applies the color transformation on \a count QRgba64 pixels starting from
+ \a src and stores the result in \a dst.
+
+ Thread-safe if prepare() has been called first.
+
+ Assumes unpremultiplied data by default. Set \a flags to change defaults.
+
+ \sa prepare()
+*/
+void QColorTransformPrivate::apply(QRgba64 *dst, const QRgba64 *src, qsizetype count, TransformFlags flags) const
+{
+ apply<QRgba64>(dst, src, count, flags);
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/mirclient/qmirclientscreenobserver.h b/src/gui/painting/qcolortransform.h
index ad927319c1..9274387b97 100644
--- a/src/plugins/platforms/mirclient/qmirclientscreenobserver.h
+++ b/src/gui/painting/qcolortransform.h
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2016 Canonical, Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -37,42 +37,57 @@
**
****************************************************************************/
+#ifndef QCOLORTRANSFORM_H
+#define QCOLORTRANSFORM_H
-#ifndef QMIRCLIENTSCREENOBSERVER_H
-#define QMIRCLIENTSCREENOBSERVER_H
+#include <QtGui/qtguiglobal.h>
+#include <QtCore/qsharedpointer.h>
+#include <QtGui/qrgb.h>
-#include <QObject>
+QT_BEGIN_NAMESPACE
-#include <mir_toolkit/mir_connection.h>
+class QColor;
+class QRgba64;
+class QColorSpacePrivate;
+class QColorTransformPrivate;
-class QMirClientScreen;
-
-class QMirClientScreenObserver : public QObject
+class Q_GUI_EXPORT QColorTransform
{
- Q_OBJECT
-
public:
- QMirClientScreenObserver(MirConnection *connection);
-
- QList<QMirClientScreen*> screens() const { return mScreenList; }
- QMirClientScreen *findScreenWithId(int id);
+ QColorTransform() noexcept : d_ptr(nullptr) { }
+ ~QColorTransform() noexcept;
+ QColorTransform(const QColorTransform &colorTransform) noexcept
+ : d_ptr(colorTransform.d_ptr)
+ { }
+ QColorTransform(QColorTransform &&colorTransform) noexcept
+ : d_ptr(std::move(colorTransform.d_ptr))
+ { }
+ QColorTransform &operator=(const QColorTransform &other) noexcept
+ {
+ d_ptr = other.d_ptr;
+ return *this;
+ }
+ QColorTransform &operator=(QColorTransform &&other) noexcept
+ {
+ d_ptr = std::move(other.d_ptr);
+ return *this;
+ }
- void handleScreenPropertiesChange(QMirClientScreen *screen, int dpi,
- MirFormFactor formFactor, float scale);
+ bool isNull() const { return d_ptr.isNull(); }
-Q_SIGNALS:
- void screenAdded(QMirClientScreen *screen);
- void screenRemoved(QMirClientScreen *screen);
-
-private Q_SLOTS:
- void update();
+ QRgb map(const QRgb &argb) const;
+ QRgba64 map(const QRgba64 &rgba64) const;
+ QColor map(const QColor &color) const;
private:
- QMirClientScreen *findScreenWithId(const QList<QMirClientScreen *> &list, int id);
- void removeScreen(QMirClientScreen *screen);
+ friend class QColorSpace;
+ friend class QColorSpacePrivate;
+ friend class QImage;
- MirConnection *mMirConnection;
- QList<QMirClientScreen*> mScreenList;
+ Q_DECLARE_PRIVATE(QColorTransform)
+ QSharedPointer<QColorTransformPrivate> d_ptr;
};
-#endif // QMIRCLIENTSCREENOBSERVER_H
+QT_END_NAMESPACE
+
+#endif // QCOLORTRANSFORM_H
diff --git a/src/plugins/platforms/mirclient/qmirclientbackingstore.h b/src/gui/painting/qcolortransform_p.h
index 7644c77df2..74a1e7fe0a 100644
--- a/src/plugins/platforms/mirclient/qmirclientbackingstore.h
+++ b/src/gui/painting/qcolortransform_p.h
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2016 Canonical, Ltd.
+** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -37,38 +37,53 @@
**
****************************************************************************/
+#ifndef QCOLORTRANSFORM_P_H
+#define QCOLORTRANSFORM_P_H
-#ifndef QMIRCLIENTBACKINGSTORE_H
-#define QMIRCLIENTBACKINGSTORE_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
-#include <qpa/qplatformbackingstore.h>
+#include "qcolormatrix_p.h"
+#include "qcolorspace_p.h"
-class QOpenGLContext;
-class QOpenGLTexture;
-class QOpenGLTextureBlitter;
+QT_BEGIN_NAMESPACE
-class QMirClientBackingStore : public QPlatformBackingStore
+class QColorTransformPrivate
{
public:
- QMirClientBackingStore(QWindow* window);
- virtual ~QMirClientBackingStore();
+ QColorMatrix colorMatrix;
+ QExplicitlySharedDataPointer<const QColorSpacePrivate> colorSpaceIn;
+ QExplicitlySharedDataPointer<const QColorSpacePrivate> colorSpaceOut;
- // QPlatformBackingStore methods.
- void beginPaint(const QRegion&) override;
- void flush(QWindow* window, const QRegion& region, const QPoint& offset) override;
- void resize(const QSize& size, const QRegion& staticContents) override;
- QPaintDevice* paintDevice() override;
- QImage toImage() const override;
+ void updateLutsIn() const;
+ void updateLutsOut() const;
+ bool simpleGammaCorrection() const;
-protected:
- void updateTexture();
+ void prepare();
+ enum TransformFlag {
+ Unpremultiplied = 0,
+ InputOpaque = 1,
+ InputPremultiplied = 2,
+ OutputPremultiplied = 4,
+ Premultiplied = (InputPremultiplied | OutputPremultiplied)
+ };
+ Q_DECLARE_FLAGS(TransformFlags, TransformFlag)
-private:
- QScopedPointer<QOpenGLContext> mContext;
- QScopedPointer<QOpenGLTexture> mTexture;
- QScopedPointer<QOpenGLTextureBlitter> mBlitter;
- QImage mImage;
- QRegion mDirty;
+ void apply(QRgb *dst, const QRgb *src, qsizetype count, TransformFlags flags = Unpremultiplied) const;
+ void apply(QRgba64 *dst, const QRgba64 *src, qsizetype count, TransformFlags flags = Unpremultiplied) const;
+
+ template<typename T>
+ void apply(T *dst, const T *src, qsizetype count, TransformFlags flags) const;
};
-#endif // QMIRCLIENTBACKINGSTORE_H
+QT_END_NAMESPACE
+
+#endif // QCOLORTRANSFORM_P_H
diff --git a/src/gui/painting/qcolortrc_p.h b/src/gui/painting/qcolortrc_p.h
new file mode 100644
index 0000000000..3a649f3756
--- /dev/null
+++ b/src/gui/painting/qcolortrc_p.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOLORTRC_P_H
+#define QCOLORTRC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtGui/private/qtguiglobal_p.h>
+#include "qcolortransferfunction_p.h"
+#include "qcolortransfertable_p.h"
+
+QT_BEGIN_NAMESPACE
+
+
+// Defines an ICC TRC (Tone Reproduction Curve)
+class Q_GUI_EXPORT QColorTrc
+{
+public:
+ QColorTrc() noexcept : m_type(Type::Uninitialized)
+ { }
+ QColorTrc(const QColorTransferFunction &fun) : m_type(Type::Function), m_fun(fun)
+ { }
+ QColorTrc(const QColorTransferTable &table) : m_type(Type::Table), m_table(table)
+ { }
+
+ enum class Type {
+ Uninitialized,
+ Function,
+ Table
+ };
+
+ bool isLinear() const
+ {
+ return m_type == Type::Uninitialized || (m_type == Type::Function && m_fun.isLinear());
+ }
+ bool isValid() const
+ {
+ return m_type != Type::Uninitialized;
+ }
+ float apply(float x) const
+ {
+ if (m_type == Type::Table)
+ return m_table.apply(x);
+ if (m_type == Type::Function)
+ return m_fun.apply(x);
+ return x;
+ }
+
+ float applyInverse(float x) const
+ {
+ if (m_type == Type::Table)
+ return m_table.applyInverse(x);
+ if (m_type == Type::Function)
+ return m_fun.inverted().apply(x);
+ return x;
+ }
+
+ friend inline bool operator!=(const QColorTrc &o1, const QColorTrc &o2);
+ friend inline bool operator==(const QColorTrc &o1, const QColorTrc &o2);
+
+ Type m_type;
+ QColorTransferFunction m_fun;
+ QColorTransferTable m_table;
+};
+
+inline bool operator!=(const QColorTrc &o1, const QColorTrc &o2)
+{
+ if (o1.m_type != o2.m_type)
+ return true;
+ if (o1.m_type == QColorTrc::Type::Function)
+ return o1.m_fun != o2.m_fun;
+ if (o1.m_type == QColorTrc::Type::Table)
+ return o1.m_table != o2.m_table;
+ return false;
+}
+inline bool operator==(const QColorTrc &o1, const QColorTrc &o2)
+{
+ return !(o1 != o2);
+}
+
+QT_END_NAMESPACE
+
+#endif // QCOLORTRC
diff --git a/src/gui/painting/qcolorprofile.cpp b/src/gui/painting/qcolortrclut.cpp
index 3b7b0a248b..268d7252b4 100644
--- a/src/gui/painting/qcolorprofile.cpp
+++ b/src/gui/painting/qcolortrclut.cpp
@@ -37,14 +37,16 @@
**
****************************************************************************/
-#include "qcolorprofile_p.h"
+#include "qcolortrclut_p.h"
+#include "qcolortransferfunction_p.h"
+#include "qcolortransfertable_p.h"
#include <qmath.h>
QT_BEGIN_NAMESPACE
-QColorProfile *QColorProfile::fromGamma(qreal gamma)
+QColorTrcLut *QColorTrcLut::fromGamma(qreal gamma)
{
- QColorProfile *cp = new QColorProfile;
+ QColorTrcLut *cp = new QColorTrcLut;
for (int i = 0; i <= (255 * 16); ++i) {
cp->m_toLinear[i] = ushort(qRound(qPow(i / qreal(255 * 16), gamma) * (255 * 256)));
@@ -54,31 +56,28 @@ QColorProfile *QColorProfile::fromGamma(qreal gamma)
return cp;
}
-static qreal srgbToLinear(qreal v)
+QColorTrcLut *QColorTrcLut::fromTransferFunction(const QColorTransferFunction &fun)
{
- const qreal a = 0.055;
- if (v <= qreal(0.04045))
- return v / qreal(12.92);
- else
- return qPow((v + a) / (qreal(1) + a), qreal(2.4));
-}
+ QColorTrcLut *cp = new QColorTrcLut;
+ QColorTransferFunction inv = fun.inverted();
-static qreal linearToSrgb(qreal v)
-{
- const qreal a = 0.055;
- if (v <= qreal(0.0031308))
- return v * qreal(12.92);
- else
- return (qreal(1) + a) * qPow(v, qreal(1.0 / 2.4)) - a;
+ for (int i = 0; i <= (255 * 16); ++i) {
+ cp->m_toLinear[i] = ushort(qRound(fun.apply(i / qreal(255 * 16)) * (255 * 256)));
+ cp->m_fromLinear[i] = ushort(qRound(inv.apply(i / qreal(255 * 16)) * (255 * 256)));
+ }
+
+ return cp;
}
-QColorProfile *QColorProfile::fromSRgb()
+QColorTrcLut *QColorTrcLut::fromTransferTable(const QColorTransferTable &table)
{
- QColorProfile *cp = new QColorProfile;
+ QColorTrcLut *cp = new QColorTrcLut;
+ float minInverse = 0.0f;
for (int i = 0; i <= (255 * 16); ++i) {
- cp->m_toLinear[i] = ushort(qRound(srgbToLinear(i / qreal(255 * 16)) * (255 * 256)));
- cp->m_fromLinear[i] = ushort(qRound(linearToSrgb(i / qreal(255 * 16)) * (255 * 256)));
+ cp->m_toLinear[i] = ushort(qBound(0, qRound(table.apply(i / qreal(255 * 16)) * (255 * 256)), 65280));
+ minInverse = table.applyInverse(i / qreal(255 * 16), minInverse);
+ cp->m_fromLinear[i] = ushort(qBound(0, qRound(minInverse * (255 * 256)), 65280));
}
return cp;
diff --git a/src/gui/painting/qcolorprofile_p.h b/src/gui/painting/qcolortrclut_p.h
index 425e9abace..76a6a60803 100644
--- a/src/gui/painting/qcolorprofile_p.h
+++ b/src/gui/painting/qcolortrclut_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QCOLORPROFILE_P_H
-#define QCOLORPROFILE_P_H
+#ifndef QCOLORTRCLUT_P_H
+#define QCOLORTRCLUT_P_H
//
// W A R N I N G
@@ -52,21 +52,29 @@
//
#include <QtGui/private/qtguiglobal_p.h>
+#include <QtCore/qsharedpointer.h>
#include <QtGui/qrgb.h>
#include <QtGui/qrgba64.h>
+#include <cmath>
+
#if defined(__SSE2__)
#include <emmintrin.h>
#elif defined(__ARM_NEON__) || defined(__ARM_NEON)
#include <arm_neon.h>
#endif
+
QT_BEGIN_NAMESPACE
-class Q_GUI_EXPORT QColorProfile
+class QColorTransferFunction;
+class QColorTransferTable;
+
+class Q_GUI_EXPORT QColorTrcLut : public QEnableSharedFromThis<QColorTrcLut>
{
public:
- static QColorProfile *fromGamma(qreal gamma);
- static QColorProfile *fromSRgb();
+ static QColorTrcLut *fromGamma(qreal gamma);
+ static QColorTrcLut *fromTransferFunction(const QColorTransferFunction &transfn);
+ static QColorTrcLut *fromTransferTable(const QColorTransferTable &transTable);
// The following methods all convert opaque or unpremultiplied colors:
@@ -121,6 +129,25 @@ public:
return convertWithTable(rgb64, m_toLinear);
}
+ float u8ToLinearF32(int c) const
+ {
+ ushort v = m_toLinear[c << 4];
+ return v * (1.0f / (255*256));
+ }
+
+ float u16ToLinearF32(int c) const
+ {
+ c -= (c >> 8);
+ ushort v = m_toLinear[c >> 4];
+ return v * (1.0f / (255*256));
+ }
+
+ float toLinear(float f) const
+ {
+ ushort v = m_toLinear[(int)(f * (255 * 16) + 0.5f)];
+ return v * (1.0f / (255*256));
+ }
+
QRgb fromLinear64(QRgba64 rgb64) const
{
#if defined(__SSE2__)
@@ -176,8 +203,31 @@ public:
return convertWithTable(rgb64, m_fromLinear);
}
+ int u8FromLinearF32(float f) const
+ {
+ ushort v = m_fromLinear[(int)(f * (255 * 16) + 0.5f)];
+ return (v + 0x80) >> 8;
+ }
+ int u16FromLinearF32(float f) const
+ {
+ ushort v = m_fromLinear[(int)(f * (255 * 16) + 0.5f)];
+ return v + (v >> 8);
+ }
+ float fromLinear(float f) const
+ {
+ ushort v = m_fromLinear[(int)(f * (255 * 16) + 0.5f)];
+ return v * (1.0f / (255*256));
+ }
+
+ // We translate to 0-65280 (255*256) instead to 0-65535 to make simple
+ // shifting an accurate conversion.
+ // We translate from 0-4080 (255*16) for the same speed up, and to keep
+ // the tables small enough to fit in most inner caches.
+ ushort m_toLinear[(255 * 16) + 1]; // [0-4080] -> [0-65280]
+ ushort m_fromLinear[(255 * 16) + 1]; // [0-4080] -> [0-65280]
+
private:
- QColorProfile() { }
+ QColorTrcLut() { }
Q_ALWAYS_INLINE static QRgb convertWithTable(QRgb rgb32, const ushort *table)
{
@@ -230,16 +280,8 @@ private:
return QRgba64::fromRgba64(r, g, b, rgb64.alpha());
#endif
}
-
- // We translate to 0-65280 (255*256) instead to 0-65535 to make simple
- // shifting an accurate conversion.
- // We translate from 0-4080 (255*16) for the same speed up, and to keep
- // the tables small enough to fit in most inner caches.
- ushort m_toLinear[(255 * 16) + 1]; // [0-4080] -> [0-65280]
- ushort m_fromLinear[(255 * 16) + 1]; // [0-4080] -> [0-65280]
-
};
QT_END_NAMESPACE
-#endif // QCOLORPROFILE_P_H
+#endif // QCOLORTRCLUT_P_H
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 2dd18f6dfc..1ed51d26a2 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -43,7 +43,7 @@
#include <qstylehints.h>
#include <qguiapplication.h>
#include <qatomic.h>
-#include <private/qcolorprofile_p.h>
+#include <private/qcolortrclut_p.h>
#include <private/qdrawhelper_p.h>
#include <private/qpaintengine_raster_p.h>
#include <private/qpainter_p.h>
@@ -5523,7 +5523,7 @@ inline static void qt_bitmapblit_quint16(QRasterBuffer *rasterBuffer,
map, mapWidth, mapHeight, mapStride);
}
-static inline void alphamapblend_generic(int coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorProfile *colorProfile)
+static inline void alphamapblend_generic(int coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile)
{
if (coverage == 0) {
// nothing
@@ -5558,7 +5558,7 @@ static void qt_alphamapblit_generic(QRasterBuffer *rasterBuffer,
if (color.isTransparent())
return;
- const QColorProfile *colorProfile = nullptr;
+ const QColorTrcLut *colorProfile = nullptr;
if (useGammaCorrection)
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
@@ -5684,7 +5684,7 @@ void qt_alphamapblit_quint16(QRasterBuffer *rasterBuffer,
}
}
-static inline void rgbBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, const QColorProfile *colorProfile)
+static inline void rgbBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, const QColorTrcLut *colorProfile)
{
// Do a gammacorrected RGB alphablend...
const QRgba64 dlinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
@@ -5694,7 +5694,7 @@ static inline void rgbBlendPixel(quint32 *dst, int coverage, QRgba64 slinear, co
*dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
}
-static inline void grayBlendPixel(quint32 *dst, int coverage, QRgba64 srcLinear, const QColorProfile *colorProfile)
+static inline void grayBlendPixel(quint32 *dst, int coverage, QRgba64 srcLinear, const QColorTrcLut *colorProfile)
{
// Do a gammacorrected gray alphablend...
const QRgba64 dstLinear = colorProfile ? colorProfile->toLinear64(*dst) : QRgba64::fromArgb32(*dst);
@@ -5704,7 +5704,7 @@ static inline void grayBlendPixel(quint32 *dst, int coverage, QRgba64 srcLinear,
*dst = colorProfile ? colorProfile->fromLinear64(blend) : toArgb32(blend);
}
-static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcLinear, quint32 src, const QColorProfile *colorProfile)
+static inline void alphamapblend_argb32(quint32 *dst, int coverage, QRgba64 srcLinear, quint32 src, const QColorTrcLut *colorProfile)
{
if (coverage == 0) {
// nothing
@@ -5734,7 +5734,7 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
if (color.isTransparent())
return;
- const QColorProfile *colorProfile = nullptr;
+ const QColorTrcLut *colorProfile = nullptr;
if (useGammaCorrection)
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA8Text();
@@ -5830,7 +5830,7 @@ static inline QRgb rgbBlend(QRgb d, QRgb s, uint rgbAlpha)
#endif
}
-static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorProfile *colorProfile)
+static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, const QRgba64 &srcLinear, const QRgba64 &src, const QColorTrcLut *colorProfile)
{
if (coverage == 0xff000000) {
// nothing
@@ -5852,7 +5852,7 @@ static inline void alphargbblend_generic(uint coverage, QRgba64 *dest, int x, co
}
}
-static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorProfile *colorProfile)
+static inline void alphargbblend_argb32(quint32 *dst, uint coverage, const QRgba64 &srcLinear, quint32 src, const QColorTrcLut *colorProfile)
{
if (coverage == 0xff000000) {
// nothing
@@ -5877,7 +5877,7 @@ static void qt_alphargbblit_generic(QRasterBuffer *rasterBuffer,
if (color.isTransparent())
return;
- const QColorProfile *colorProfile = nullptr;
+ const QColorTrcLut *colorProfile = nullptr;
if (useGammaCorrection)
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
@@ -5954,7 +5954,7 @@ static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
const quint32 c = color.toArgb32();
- const QColorProfile *colorProfile = nullptr;
+ const QColorTrcLut *colorProfile = nullptr;
if (useGammaCorrection)
colorProfile = QGuiApplicationPrivate::instance()->colorProfileForA32Text();
diff --git a/src/gui/painting/qicc.cpp b/src/gui/painting/qicc.cpp
new file mode 100644
index 0000000000..d88b005782
--- /dev/null
+++ b/src/gui/painting/qicc.cpp
@@ -0,0 +1,669 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qicc_p.h"
+
+#include <qbuffer.h>
+#include <qbytearray.h>
+#include <qdatastream.h>
+#include <qloggingcategory.h>
+#include <qendian.h>
+
+#include "qcolorspace_p.h"
+#include "qcolortrc_p.h"
+
+QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcIcc, "qt.gui.icc")
+
+struct ICCProfileHeader
+{
+ quint32_be profileSize;
+
+ quint32_be preferredCmmType;
+
+ quint32_be profileVersion;
+ quint32_be profileClass;
+ quint32_be inputColorSpace;
+ quint32_be pcs;
+ quint32_be datetime[3];
+ quint32_be signature;
+ quint32_be platformSignature;
+ quint32_be flags;
+ quint32_be deviceManufacturer;
+ quint32_be deviceModel;
+ quint32_be deviceAttributes[2];
+
+ quint32_be renderingIntent;
+ qint32_be illuminantXyz[3];
+
+ quint32_be creatorSignature;
+ quint32_be profileId[4];
+
+ quint32_be reserved[7];
+
+// Technically after the header, but easier to include here:
+ quint32_be tagCount;
+};
+
+constexpr quint32 IccTag(uchar a, uchar b, uchar c, uchar d)
+{
+ return (a << 24) | (b << 16) | (c << 8) | d;
+}
+
+enum class ProfileClass : quint32 {
+ Input = IccTag('s', 'c', 'r', 'n'),
+ Display = IccTag('m', 'n', 't', 'r'),
+ // Not supported:
+ Output = IccTag('p', 'r', 't', 'r'),
+ ColorSpace = IccTag('s', 'p', 'a', 'c'),
+};
+
+enum class Tag : quint32 {
+ acsp = IccTag('a', 'c', 's', 'p'),
+ RGB_ = IccTag('R', 'G', 'B', ' '),
+ XYZ_ = IccTag('X', 'Y', 'Z', ' '),
+ rXYZ = IccTag('r', 'X', 'Y', 'Z'),
+ gXYZ = IccTag('g', 'X', 'Y', 'Z'),
+ bXYZ = IccTag('b', 'X', 'Y', 'Z'),
+ rTRC = IccTag('r', 'T', 'R', 'C'),
+ gTRC = IccTag('g', 'T', 'R', 'C'),
+ bTRC = IccTag('b', 'T', 'R', 'C'),
+ A2B0 = IccTag('A', '2', 'B', '0'),
+ A2B1 = IccTag('A', '2', 'B', '1'),
+ B2A0 = IccTag('B', '2', 'A', '0'),
+ B2A1 = IccTag('B', '2', 'A', '1'),
+ desc = IccTag('d', 'e', 's', 'c'),
+ text = IccTag('t', 'e', 'x', 't'),
+ cprt = IccTag('c', 'p', 'r', 't'),
+ curv = IccTag('c', 'u', 'r', 'v'),
+ para = IccTag('p', 'a', 'r', 'a'),
+ wtpt = IccTag('w', 't', 'p', 't'),
+ bkpt = IccTag('b', 'k', 'p', 't'),
+ mft1 = IccTag('m', 'f', 't', '1'),
+ mft2 = IccTag('m', 'f', 't', '2'),
+ mAB_ = IccTag('m', 'A', 'B', ' '),
+ mBA_ = IccTag('m', 'B', 'A', ' '),
+ chad = IccTag('c', 'h', 'a', 'd'),
+ sf32 = IccTag('s', 'f', '3', '2'),
+
+ // Apple extensions for ICCv2:
+ aarg = IccTag('a', 'a', 'r', 'g'),
+ aagg = IccTag('a', 'a', 'g', 'g'),
+ aabg = IccTag('a', 'a', 'b', 'g'),
+};
+
+inline uint qHash(const Tag &key, uint seed = 0)
+{
+ return qHash(quint32(key), seed);
+}
+
+namespace QIcc {
+
+struct TagTableEntry
+{
+ quint32_be signature;
+ quint32_be offset;
+ quint32_be size;
+};
+
+struct GenericTagData {
+ quint32_be type;
+ quint32_be null;
+};
+
+struct XYZTagData : GenericTagData {
+ qint32_be fixedX;
+ qint32_be fixedY;
+ qint32_be fixedZ;
+};
+
+struct CurvTagData : GenericTagData {
+ quint32_be valueCount;
+ quint16_be value[1];
+};
+
+struct ParaTagData : GenericTagData {
+ quint16_be curveType;
+ quint16_be null2;
+ quint32_be parameter[1];
+};
+
+// For both mAB and mBA
+struct mABTagData : GenericTagData {
+ quint8 inputChannels;
+ quint8 outputChannels;
+ quint8 padding[2];
+ quint32_be bCurvesOffset;
+ quint32_be matrixOffset;
+ quint32_be mCurvesOffset;
+ quint32_be clutOffset;
+ quint32_be aCurvesOffset;
+};
+
+struct Sf32TagData : GenericTagData {
+ quint32_be value[1];
+};
+
+static int toFixedS1516(float x)
+{
+ return int(x * 65536.0f + 0.5f);
+}
+
+static float fromFixedS1516(int x)
+{
+ return x * (1.0f / 65536.0f);
+}
+
+QColorVector fromXyzData(const XYZTagData *xyz)
+{
+ const float x = fromFixedS1516(xyz->fixedX);
+ const float y = fromFixedS1516(xyz->fixedY);
+ const float z = fromFixedS1516(xyz->fixedZ);
+ qCDebug(lcIcc) << "XYZ_ " << x << y << z;
+
+ return QColorVector(x, y, z);
+}
+
+static bool isValidIccProfile(const ICCProfileHeader &header)
+{
+ if (header.signature != uint(Tag::acsp)) {
+ qCWarning(lcIcc, "Failed ICC signature test");
+ return false;
+ }
+ if (header.profileSize < (sizeof(ICCProfileHeader) + header.tagCount * sizeof(TagTableEntry))) {
+ qCWarning(lcIcc, "Failed basic size sanity");
+ return false;
+ }
+
+ if (header.profileClass != uint(ProfileClass::Input)
+ && header.profileClass != uint(ProfileClass::Display)) {
+ qCWarning(lcIcc, "Unsupported ICC profile class %x", quint32(header.profileClass));
+ return false;
+ }
+ if (header.inputColorSpace != 0x52474220 /* 'RGB '*/) {
+ qCWarning(lcIcc, "Unsupported ICC input color space %x", quint32(header.inputColorSpace));
+ return false;
+ }
+ if (header.pcs != 0x58595a20 /* 'XYZ '*/) {
+ // ### support PCSLAB
+ qCWarning(lcIcc, "Unsupported ICC profile connection space %x", quint32(header.pcs));
+ return false;
+ }
+
+ QColorVector illuminant;
+ illuminant.x = fromFixedS1516(header.illuminantXyz[0]);
+ illuminant.y = fromFixedS1516(header.illuminantXyz[1]);
+ illuminant.z = fromFixedS1516(header.illuminantXyz[2]);
+ if (illuminant != QColorVector::D50()) {
+ qCWarning(lcIcc, "Invalid ICC illuminant");
+ return false;
+ }
+
+ return true;
+}
+
+static int writeColorTrc(QDataStream &stream, const QColorTrc &trc)
+{
+ if (trc.isLinear()) {
+ stream << uint(Tag::curv) << uint(0);
+ stream << uint(0);
+ return 12;
+ }
+
+ if (trc.m_type == QColorTrc::Type::Function) {
+ const QColorTransferFunction &fun = trc.m_fun;
+ stream << uint(Tag::para) << uint(0);
+ if (fun.isGamma()) {
+ stream << ushort(0) << ushort(0);
+ stream << toFixedS1516(fun.m_g);
+ return 12 + 4;
+ }
+ bool type3 = qFuzzyIsNull(fun.m_e) && qFuzzyIsNull(fun.m_f);
+ stream << ushort(type3 ? 3 : 4) << ushort(0);
+ stream << toFixedS1516(fun.m_g);
+ stream << toFixedS1516(fun.m_a);
+ stream << toFixedS1516(fun.m_b);
+ stream << toFixedS1516(fun.m_c);
+ stream << toFixedS1516(fun.m_d);
+ if (type3)
+ return 12 + 5 * 4;
+ stream << toFixedS1516(fun.m_e);
+ stream << toFixedS1516(fun.m_f);
+ return 12 + 7 * 4;
+ }
+
+ Q_ASSERT(trc.m_type == QColorTrc::Type::Table);
+ stream << uint(Tag::curv) << uint(0);
+ stream << uint(trc.m_table.m_tableSize);
+ if (!trc.m_table.m_table16.isEmpty()) {
+ for (uint i = 0; i < trc.m_table.m_tableSize; ++i) {
+ stream << ushort(trc.m_table.m_table16[i]);
+ }
+ } else {
+ for (uint i = 0; i < trc.m_table.m_tableSize; ++i) {
+ stream << ushort(trc.m_table.m_table8[i] * 257U);
+ }
+ }
+ return 12 + 2 * trc.m_table.m_tableSize;
+}
+
+QByteArray toIccProfile(const QColorSpace &space)
+{
+ if (!space.isValid())
+ return QByteArray();
+
+ const QColorSpacePrivate *spaceDPtr = space.d_func();
+
+ constexpr int tagCount = 9;
+ constexpr uint profileDataOffset = 128 + 4 + 12 * tagCount;
+ constexpr uint variableTagTableOffsets = 128 + 4 + 12 * 5;
+ uint currentOffset = 0;
+ uint rTrcOffset, gTrcOffset, bTrcOffset;
+ uint rTrcSize, gTrcSize, bTrcSize;
+ uint descOffset, descSize;
+
+ QBuffer buffer;
+ buffer.open(QIODevice::WriteOnly);
+ QDataStream stream(&buffer);
+
+ // Profile header:
+ stream << uint(0); // Size, we will update this later
+ stream << uint(0);
+ stream << uint(0x02400000); // Version 2.4 (note we use 'para' from version 4)
+ stream << uint(ProfileClass::Display);
+ stream << uint(Tag::RGB_);
+ stream << uint(Tag::XYZ_);
+ stream << uint(0) << uint(0) << uint(0);
+ stream << uint(Tag::acsp);
+ stream << uint(0) << uint(0) << uint(0);
+ stream << uint(0) << uint(0) << uint(0);
+ stream << uint(1); // Rendering intent
+ stream << uint(0x0000f6d6); // D50 X
+ stream << uint(0x00010000); // D50 Y
+ stream << uint(0x0000d32d); // D50 Z
+ stream << IccTag('Q','t', QT_VERSION_MAJOR, QT_VERSION_MINOR);
+ stream << uint(0) << uint(0) << uint(0) << uint(0);
+ stream << uint(0) << uint(0) << uint(0) << uint(0) << uint(0) << uint(0) << uint(0);
+
+ // Tag table:
+ stream << uint(tagCount);
+ stream << uint(Tag::rXYZ) << uint(profileDataOffset + 00) << uint(20);
+ stream << uint(Tag::gXYZ) << uint(profileDataOffset + 20) << uint(20);
+ stream << uint(Tag::bXYZ) << uint(profileDataOffset + 40) << uint(20);
+ stream << uint(Tag::wtpt) << uint(profileDataOffset + 60) << uint(20);
+ stream << uint(Tag::cprt) << uint(profileDataOffset + 80) << uint(12);
+ // From here the offset and size will be updated later:
+ stream << uint(Tag::rTRC) << uint(0) << uint(0);
+ stream << uint(Tag::gTRC) << uint(0) << uint(0);
+ stream << uint(Tag::bTRC) << uint(0) << uint(0);
+ stream << uint(Tag::desc) << uint(0) << uint(0);
+ // TODO: consider adding 'chad' tag (required in ICC >=4 when we have non-D50 whitepoint)
+ currentOffset = profileDataOffset;
+
+ // Tag data:
+ stream << uint(Tag::XYZ_) << uint(0);
+ stream << toFixedS1516(spaceDPtr->toXyz.r.x);
+ stream << toFixedS1516(spaceDPtr->toXyz.r.y);
+ stream << toFixedS1516(spaceDPtr->toXyz.r.z);
+ stream << uint(Tag::XYZ_) << uint(0);
+ stream << toFixedS1516(spaceDPtr->toXyz.g.x);
+ stream << toFixedS1516(spaceDPtr->toXyz.g.y);
+ stream << toFixedS1516(spaceDPtr->toXyz.g.z);
+ stream << uint(Tag::XYZ_) << uint(0);
+ stream << toFixedS1516(spaceDPtr->toXyz.b.x);
+ stream << toFixedS1516(spaceDPtr->toXyz.b.y);
+ stream << toFixedS1516(spaceDPtr->toXyz.b.z);
+ stream << uint(Tag::XYZ_) << uint(0);
+ stream << toFixedS1516(spaceDPtr->whitePoint.x);
+ stream << toFixedS1516(spaceDPtr->whitePoint.y);
+ stream << toFixedS1516(spaceDPtr->whitePoint.z);
+ stream << uint(Tag::text) << uint(0);
+ stream << uint(IccTag('N', '/', 'A', '\0'));
+ currentOffset += 92;
+
+ // From now on the data is variable sized:
+ rTrcOffset = currentOffset;
+ rTrcSize = writeColorTrc(stream, spaceDPtr->trc[0]);
+ currentOffset += rTrcSize;
+ if (spaceDPtr->trc[0] == spaceDPtr->trc[1]) {
+ gTrcOffset = rTrcOffset;
+ gTrcSize = rTrcSize;
+ } else {
+ gTrcOffset = currentOffset;
+ gTrcSize = writeColorTrc(stream, spaceDPtr->trc[1]);
+ currentOffset += gTrcSize;
+ }
+ if (spaceDPtr->trc[0] == spaceDPtr->trc[2]) {
+ bTrcOffset = rTrcOffset;
+ bTrcSize = rTrcSize;
+ } else {
+ bTrcOffset = currentOffset;
+ bTrcSize = writeColorTrc(stream, spaceDPtr->trc[2]);
+ currentOffset += bTrcSize;
+ }
+
+ descOffset = currentOffset;
+ QByteArray description = spaceDPtr->description.toUtf8();
+ stream << uint(Tag::desc) << uint(0);
+ stream << uint(description.size() + 1);
+ stream.writeRawData(description.constData(), description.size() + 1);
+ stream << uint(0) << uint(0);
+ stream << ushort(0) << uchar(0);
+ QByteArray macdesc(67, '\0');
+ stream.writeRawData(macdesc.constData(), 67);
+ descSize = 90 + description.size() + 1;
+ currentOffset += descSize;
+
+ buffer.close();
+ QByteArray iccProfile = buffer.buffer();
+ // Now write final size
+ *(quint32_be *)iccProfile.data() = iccProfile.size();
+ // And the final indices and sizes of variable size tags:
+ *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 4) = rTrcOffset;
+ *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 8) = rTrcSize;
+ *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 12 + 4) = gTrcOffset;
+ *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 12 + 8) = gTrcSize;
+ *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 2 * 12 + 4) = bTrcOffset;
+ *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 2 * 12 + 8) = bTrcSize;
+ *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 3 * 12 + 4) = descOffset;
+ *(quint32_be *)(iccProfile.data() + variableTagTableOffsets + 3 * 12 + 8) = descSize;
+
+#if !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS)
+ const ICCProfileHeader *iccHeader = (const ICCProfileHeader *)iccProfile.constData();
+ Q_ASSERT(qsizetype(iccHeader->profileSize) == qsizetype(iccProfile.size()));
+ Q_ASSERT(isValidIccProfile(*iccHeader));
+#endif
+
+ return iccProfile;
+}
+
+bool parseTRC(const GenericTagData *trcData, QColorTrc &gamma)
+{
+ if (trcData->type == quint32(Tag::curv)) {
+ const CurvTagData *curv = reinterpret_cast<const CurvTagData *>(trcData);
+ qCDebug(lcIcc) << "curv" << uint(curv->valueCount);
+ if (curv->valueCount == 0) {
+ gamma.m_type = QColorTrc::Type::Function;
+ gamma.m_fun = QColorTransferFunction(); // Linear
+ } else if (curv->valueCount == 1) {
+ float g = curv->value[0] * (1.0f / 256.0f);
+ qCDebug(lcIcc) << g;
+ gamma.m_type = QColorTrc::Type::Function;
+ gamma.m_fun = QColorTransferFunction::fromGamma(g);
+ } else {
+ QVector<quint16> tabl;
+ tabl.resize(curv->valueCount);
+ for (uint i = 0; i < curv->valueCount; ++i)
+ tabl[i] = curv->value[i];
+ QColorTransferTable table = QColorTransferTable(curv->valueCount, std::move(tabl));
+ QColorTransferFunction curve;
+ if (!table.asColorTransferFunction(&curve)) {
+ gamma.m_type = QColorTrc::Type::Table;
+ gamma.m_table = table;
+ } else {
+ qCDebug(lcIcc) << "Detected curv table as function";
+ gamma.m_type = QColorTrc::Type::Function;
+ gamma.m_fun = curve;
+ }
+ }
+ return true;
+ }
+ if (trcData->type == quint32(Tag::para)) {
+ const ParaTagData *para = reinterpret_cast<const ParaTagData *>(trcData);
+ qCDebug(lcIcc) << "para" << uint(para->curveType);
+ switch (para->curveType) {
+ case 0: {
+ float g = fromFixedS1516(para->parameter[0]);
+ qCDebug(lcIcc) << g;
+ gamma.m_type = QColorTrc::Type::Function;
+ gamma.m_fun = QColorTransferFunction::fromGamma(g);
+ break;
+ }
+ case 1: {
+ float g = fromFixedS1516(para->parameter[0]);
+ float a = fromFixedS1516(para->parameter[1]);
+ float b = fromFixedS1516(para->parameter[2]);
+ float d = -b / a;
+ qCDebug(lcIcc) << g << a << b;
+ gamma.m_type = QColorTrc::Type::Function;
+ gamma.m_fun = QColorTransferFunction(a, b, 0.0f, d, 0.0f, 0.0f, g);
+ break;
+ }
+ case 2: {
+ float g = fromFixedS1516(para->parameter[0]);
+ float a = fromFixedS1516(para->parameter[1]);
+ float b = fromFixedS1516(para->parameter[2]);
+ float c = fromFixedS1516(para->parameter[3]);
+ float d = -b / a;
+ qCDebug(lcIcc) << g << a << b << c;
+ gamma.m_type = QColorTrc::Type::Function;
+ gamma.m_fun = QColorTransferFunction(a, b, 0.0f, d, c, c, g);
+ break;
+ }
+ case 3: {
+ float g = fromFixedS1516(para->parameter[0]);
+ float a = fromFixedS1516(para->parameter[1]);
+ float b = fromFixedS1516(para->parameter[2]);
+ float c = fromFixedS1516(para->parameter[3]);
+ float d = fromFixedS1516(para->parameter[4]);
+ qCDebug(lcIcc) << g << a << b << c << d;
+ gamma.m_type = QColorTrc::Type::Function;
+ gamma.m_fun = QColorTransferFunction(a, b, c, d, 0.0f, 0.0f, g);
+ break;
+ }
+ case 4: {
+ float g = fromFixedS1516(para->parameter[0]);
+ float a = fromFixedS1516(para->parameter[1]);
+ float b = fromFixedS1516(para->parameter[2]);
+ float c = fromFixedS1516(para->parameter[3]);
+ float d = fromFixedS1516(para->parameter[4]);
+ float e = fromFixedS1516(para->parameter[5]);
+ float f = fromFixedS1516(para->parameter[6]);
+ qCDebug(lcIcc) << g << a << b << c << d << e << f;
+ gamma.m_type = QColorTrc::Type::Function;
+ gamma.m_fun = QColorTransferFunction(a, b, c, d, e, f, g);
+ break;
+ }
+ default:
+ qCWarning(lcIcc) << "Unknown para type" << uint(para->curveType);
+ return false;
+ }
+ return true;
+ }
+ qCWarning(lcIcc) << "Invalid TRC data type";
+ return false;
+}
+
+bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace)
+{
+ if (data.size() < qsizetype(sizeof(ICCProfileHeader))) {
+ qCWarning(lcIcc) << "fromIccProfile: failed size sanity 1";
+ return false;
+ }
+ const ICCProfileHeader *header = (const ICCProfileHeader *)data.constData();
+ if (!isValidIccProfile(*header)) {
+ qCWarning(lcIcc) << "fromIccProfile: failed general sanity check";
+ return false;
+ }
+ if (qsizetype(header->profileSize) > data.size()) {
+ qCWarning(lcIcc) << "fromIccProfile: failed size sanity 2";
+ return false;
+ }
+
+ // Read tag index
+ const TagTableEntry *tagTable = (const TagTableEntry *)(data.constData() + sizeof(ICCProfileHeader));
+ const qsizetype offsetToData = sizeof(ICCProfileHeader) + header->tagCount * sizeof(TagTableEntry);
+
+ QHash<Tag, quint32> tagIndex;
+ for (uint i = 0; i < header->tagCount; ++i) {
+ // Sanity check tag sizes and offsets:
+ if (qsizetype(tagTable[i].offset) < offsetToData) {
+ qCWarning(lcIcc) << "fromIccProfile: failed tag offset sanity 1";
+ return false;
+ }
+ // Checked separately from (+ size) to handle overflow.
+ if (tagTable[i].offset > header->profileSize) {
+ qCWarning(lcIcc) << "fromIccProfile: failed tag offset sanity 2";
+ return false;
+ }
+ if ((tagTable[i].offset + tagTable[i].size) > header->profileSize) {
+ qCWarning(lcIcc) << "fromIccProfile: failed tag offset + size sanity";
+ return false;
+ }
+// printf("'%4s' %d %d\n", (const char *)&tagTable[i].signature,
+// quint32(tagTable[i].offset),
+// quint32(tagTable[i].size));
+ tagIndex.insert(Tag(quint32(tagTable[i].signature)), tagTable[i].offset);
+ }
+ // Check the profile is three-component matrix based (what we currently support):
+ if (!tagIndex.contains(Tag::rXYZ) || !tagIndex.contains(Tag::gXYZ) || !tagIndex.contains(Tag::bXYZ) ||
+ !tagIndex.contains(Tag::rTRC) || !tagIndex.contains(Tag::gTRC) || !tagIndex.contains(Tag::bTRC) ||
+ !tagIndex.contains(Tag::wtpt)) {
+ qCWarning(lcIcc) << "fromIccProfile: Unsupported ICC profile - not three component matrix based";
+ return false;
+ }
+
+ // Parse XYZ tags
+ const XYZTagData *rXyz = (const XYZTagData *)(data.constData() + tagIndex[Tag::rXYZ]);
+ const XYZTagData *gXyz = (const XYZTagData *)(data.constData() + tagIndex[Tag::gXYZ]);
+ const XYZTagData *bXyz = (const XYZTagData *)(data.constData() + tagIndex[Tag::bXYZ]);
+ const XYZTagData *wXyz = (const XYZTagData *)(data.constData() + tagIndex[Tag::wtpt]);
+ if (rXyz->type != quint32(Tag::XYZ_) || gXyz->type != quint32(Tag::XYZ_) ||
+ wXyz->type != quint32(Tag::XYZ_) || wXyz->type != quint32(Tag::XYZ_)) {
+ qCWarning(lcIcc) << "fromIccProfile: Bad XYZ data type";
+ return false;
+ }
+ QColorSpacePrivate *colorspaceDPtr = colorSpace->d_func();
+
+ colorspaceDPtr->toXyz.r = fromXyzData(rXyz);
+ colorspaceDPtr->toXyz.g = fromXyzData(gXyz);
+ colorspaceDPtr->toXyz.b = fromXyzData(bXyz);
+ QColorVector whitePoint = fromXyzData(wXyz);
+ colorspaceDPtr->whitePoint = whitePoint;
+
+ colorspaceDPtr->gamut = QColorSpace::Gamut::Custom;
+ if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromSRgb()) {
+ qCDebug(lcIcc) << "fromIccProfile: sRGB gamut detected";
+ colorspaceDPtr->gamut = QColorSpace::Gamut::SRgb;
+ } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromAdobeRgb()) {
+ qCDebug(lcIcc) << "fromIccProfile: Adobe RGB gamut detected";
+ colorspaceDPtr->gamut = QColorSpace::Gamut::AdobeRgb;
+ } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromDciP3D65()) {
+ qCDebug(lcIcc) << "fromIccProfile: DCI-P3 D65 gamut detected";
+ colorspaceDPtr->gamut = QColorSpace::Gamut::DciP3D65;
+ } else if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromBt2020()) {
+ qCDebug(lcIcc) << "fromIccProfile: BT.2020 gamut detected";
+ colorspaceDPtr->gamut = QColorSpace::Gamut::Bt2020;
+ }
+ if (colorspaceDPtr->toXyz == QColorMatrix::toXyzFromProPhotoRgb()) {
+ qCDebug(lcIcc) << "fromIccProfile: ProPhoto RGB gamut detected";
+ colorspaceDPtr->gamut = QColorSpace::Gamut::ProPhotoRgb;
+ }
+ // Reset the matrix to our canonical values:
+ if (colorspaceDPtr->gamut != QColorSpace::Gamut::Custom)
+ colorspaceDPtr->setToXyzMatrix();
+
+ // Parse TRC tags
+ const GenericTagData *rTrc;
+ const GenericTagData *gTrc;
+ const GenericTagData *bTrc;
+ if (tagIndex.contains(Tag::aarg) && tagIndex.contains(Tag::aagg) && tagIndex.contains(Tag::aabg)) {
+ // Apple extension for parametric version of TRCs in ICCv2:
+ rTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::aarg]);
+ gTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::aagg]);
+ bTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::aabg]);
+ } else {
+ rTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::rTRC]);
+ gTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::gTRC]);
+ bTrc = (const GenericTagData *)(data.constData() + tagIndex[Tag::bTRC]);
+ }
+
+ QColorTrc rCurve;
+ QColorTrc gCurve;
+ QColorTrc bCurve;
+ if (!parseTRC(rTrc, rCurve))
+ return false;
+ if (!parseTRC(gTrc, gCurve))
+ return false;
+ if (!parseTRC(bTrc, bCurve))
+ return false;
+ if (rCurve == gCurve && gCurve == bCurve && rCurve.m_type == QColorTrc::Type::Function) {
+ if (rCurve.m_fun.isLinear()) {
+ qCDebug(lcIcc) << "fromIccProfile: Linear gamma detected";
+ colorspaceDPtr->trc[0] = QColorTransferFunction();
+ colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Linear;
+ colorspaceDPtr->gamma = 1.0f;
+ } else if (rCurve.m_fun.isGamma()) {
+ qCDebug(lcIcc) << "fromIccProfile: Simple gamma detected";
+ colorspaceDPtr->trc[0] = QColorTransferFunction::fromGamma(rCurve.m_fun.m_g);
+ colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Gamma;
+ colorspaceDPtr->gamma = rCurve.m_fun.m_g;
+ } else if (rCurve.m_fun.isSRgb()) {
+ qCDebug(lcIcc) << "fromIccProfile: sRGB gamma detected";
+ colorspaceDPtr->trc[0] = QColorTransferFunction::fromSRgb();
+ colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::SRgb;
+ } else {
+ colorspaceDPtr->trc[0] = rCurve;
+ colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Custom;
+ }
+
+ colorspaceDPtr->trc[1] = colorspaceDPtr->trc[0];
+ colorspaceDPtr->trc[2] = colorspaceDPtr->trc[0];
+ } else {
+ colorspaceDPtr->trc[0] = rCurve;
+ colorspaceDPtr->trc[1] = gCurve;
+ colorspaceDPtr->trc[2] = bCurve;
+ colorspaceDPtr->transferFunction = QColorSpace::TransferFunction::Custom;
+ }
+
+ // FIXME: try to parse the description..
+
+ if (!colorspaceDPtr->identifyColorSpace())
+ colorspaceDPtr->id = QColorSpace::Unknown;
+ else
+ qCDebug(lcIcc) << "fromIccProfile: Named colorspace detected: " << colorSpace->colorSpaceId();
+
+ colorspaceDPtr->iccProfile = data;
+
+ return true;
+}
+
+} // namespace QIcc
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/mirclient/qmirclientdebugextension.h b/src/gui/painting/qicc_p.h
index 0596561d77..c3220391f4 100644
--- a/src/plugins/platforms/mirclient/qmirclientdebugextension.h
+++ b/src/gui/painting/qicc_p.h
@@ -1,9 +1,9 @@
/****************************************************************************
**
-** Copyright (C) 2016 Canonical, Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -37,27 +37,34 @@
**
****************************************************************************/
+#ifndef QICC_P_H
+#define QICC_P_H
-#ifndef QMIRCLIENTDEBUGEXTENSION_H
-#define QMIRCLIENTDEBUGEXTENSION_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
-#include <QPoint>
-#include <QLibrary>
-struct MirSurface;
+#include <QtCore/qbytearray.h>
+#include <QtGui/qtguiglobal.h>
-typedef bool (*MapperPrototype)(MirSurface* surface, int x, int y, int* screenX, int* screenY);
+QT_BEGIN_NAMESPACE
+class QColorSpace;
-class QMirClientDebugExtension
-{
-public:
- QMirClientDebugExtension();
+namespace QIcc {
- QPoint mapSurfacePointToScreen(MirSurface *, const QPoint &point);
+Q_GUI_EXPORT bool fromIccProfile(const QByteArray &data, QColorSpace *colorSpace);
+Q_GUI_EXPORT QByteArray toIccProfile(const QColorSpace &space);
-private:
- QLibrary m_mirclientDebug;
- MapperPrototype m_mapper;
-};
+}
-#endif // QMIRCLIENTDEBUGEXTENSION_H
+QT_END_NAMESPACE
+
+#endif // QICC_P_H
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 0f5c7756ad..66af6e3de3 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -555,35 +555,6 @@ bool QRasterPaintEngine::end()
/*!
\internal
*/
-void QRasterPaintEngine::releaseBuffer()
-{
- Q_D(QRasterPaintEngine);
- d->rasterBuffer.reset(new QRasterBuffer);
-}
-
-/*!
- \internal
-*/
-QSize QRasterPaintEngine::size() const
-{
- Q_D(const QRasterPaintEngine);
- return QSize(d->rasterBuffer->width(), d->rasterBuffer->height());
-}
-
-/*!
- \internal
-*/
-#ifndef QT_NO_DEBUG
-void QRasterPaintEngine::saveBuffer(const QString &s) const
-{
- Q_D(const QRasterPaintEngine);
- d->rasterBuffer->bufferImage().save(s, "PNG");
-}
-#endif
-
-/*!
- \internal
-*/
void QRasterPaintEngine::updateMatrix(const QTransform &matrix)
{
QRasterPaintEngineState *s = state();
@@ -3845,11 +3816,6 @@ QImage::Format QRasterBuffer::prepare(QImage *image)
return format;
}
-void QRasterBuffer::resetBuffer(int val)
-{
- memset(m_buffer, val, m_height*bytes_per_line);
-}
-
QClipData::QClipData(int height)
{
clipSpanHeight = height;
@@ -4272,48 +4238,6 @@ static void qt_span_clip(int count, const QSpan *spans, void *userData)
}
}
-#ifndef QT_NO_DEBUG
-QImage QRasterBuffer::bufferImage() const
-{
- QImage image(m_width, m_height, QImage::Format_ARGB32_Premultiplied);
-
- for (int y = 0; y < m_height; ++y) {
- uint *span = (uint *)const_cast<QRasterBuffer *>(this)->scanLine(y);
-
- for (int x=0; x<m_width; ++x) {
- uint argb = span[x];
- image.setPixel(x, y, argb);
- }
- }
- return image;
-}
-#endif
-
-
-void QRasterBuffer::flushToARGBImage(QImage *target) const
-{
- int w = qMin(m_width, target->width());
- int h = qMin(m_height, target->height());
-
- for (int y=0; y<h; ++y) {
- uint *sourceLine = (uint *)const_cast<QRasterBuffer *>(this)->scanLine(y);
- QRgb *dest = (QRgb *) target->scanLine(y);
- for (int x=0; x<w; ++x) {
- QRgb pixel = sourceLine[x];
- int alpha = qAlpha(pixel);
- if (!alpha) {
- dest[x] = 0;
- } else {
- dest[x] = (alpha << 24)
- | ((255*qRed(pixel)/alpha) << 16)
- | ((255*qGreen(pixel)/alpha) << 8)
- | ((255*qBlue(pixel)/alpha) << 0);
- }
- }
- }
-}
-
-
class QGradientCache
{
public:
diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h
index 881144d1c2..c3734f1c62 100644
--- a/src/gui/painting/qpaintengine_raster_p.h
+++ b/src/gui/painting/qpaintengine_raster_p.h
@@ -208,15 +208,6 @@ public:
ClipType clipType() const;
QRect clipBoundingRect() const;
- void releaseBuffer();
-
- QSize size() const;
-
-#ifndef QT_NO_DEBUG
- void saveBuffer(const QString &s) const;
-#endif
-
-
#ifdef Q_OS_WIN
void setDC(HDC hdc);
HDC getDC() const;
@@ -442,20 +433,9 @@ public:
void init();
QImage::Format prepare(QImage *image);
- QImage::Format prepare(QPixmap *pix);
- void prepare(int w, int h);
- void prepareBuffer(int w, int h);
-
- void resetBuffer(int val=0);
uchar *scanLine(int y) { Q_ASSERT(y>=0); Q_ASSERT(y<m_height); return m_buffer + y * bytes_per_line; }
-#ifndef QT_NO_DEBUG
- QImage bufferImage() const;
-#endif
-
- void flushToARGBImage(QImage *image) const;
-
int width() const { return m_width; }
int height() const { return m_height; }
int bytesPerLine() const { return bytes_per_line; }
diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h
index 930180e9fa..9857a59070 100644
--- a/src/gui/painting/qpainter_p.h
+++ b/src/gui/painting/qpainter_p.h
@@ -54,6 +54,8 @@
#include <QtCore/qvarlengtharray.h>
#include <QtGui/private/qtguiglobal_p.h>
#include "QtGui/qbrush.h"
+#include "QtGui/qcolorspace.h"
+#include "QtGui/qcolortransform.h"
#include "QtGui/qfont.h"
#include "QtGui/qpen.h"
#include "QtGui/qregion.h"
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 6bdc82a8e9..25d488961c 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1671,19 +1671,19 @@ int QPdfEnginePrivate::writeXmpMetaData()
const QDateTime now = QDateTime::currentDateTime();
const QDate date = now.date();
const QTime time = now.time();
-
- QString timeStr;
- timeStr.sprintf("%d-%02d-%02dT%02d:%02d:%02d", date.year(), date.month(), date.day(),
- time.hour(), time.minute(), time.second());
+ const QString timeStr =
+ QString::asprintf("%d-%02d-%02dT%02d:%02d:%02d",
+ date.year(), date.month(), date.day(),
+ time.hour(), time.minute(), time.second());
const int offset = now.offsetFromUtc();
const int hours = (offset / 60) / 60;
const int mins = (offset / 60) % 60;
QString tzStr;
if (offset < 0)
- tzStr.sprintf("-%02d:%02d", -hours, -mins);
+ tzStr = QString::asprintf("-%02d:%02d", -hours, -mins);
else if (offset > 0)
- tzStr.sprintf("+%02d:%02d", hours , mins);
+ tzStr = QString::asprintf("+%02d:%02d", hours , mins);
else
tzStr = QLatin1String("Z");
diff --git a/src/gui/painting/qpdfwriter.cpp b/src/gui/painting/qpdfwriter.cpp
index 258939a763..7f18ce42be 100644
--- a/src/gui/painting/qpdfwriter.cpp
+++ b/src/gui/painting/qpdfwriter.cpp
@@ -379,6 +379,9 @@ int QPdfWriter::resolution() const
*/
#endif
+#if QT_DEPRECATED_SINCE(5, 14)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
/*!
\reimp
@@ -404,6 +407,8 @@ void QPdfWriter::setPageSizeMM(const QSizeF &size)
{
setPageSize(QPageSize(size, QPageSize::Millimeter));
}
+QT_WARNING_POP
+#endif
/*!
\internal
@@ -427,6 +432,9 @@ bool QPdfWriter::newPage()
}
+#if QT_DEPRECATED_SINCE(5, 14)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
/*!
\reimp
@@ -438,6 +446,8 @@ void QPdfWriter::setMargins(const Margins &m)
{
setPageMargins(QMarginsF(m.left, m.top, m.right, m.bottom), QPageLayout::Millimeter);
}
+QT_WARNING_POP
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/painting/qpdfwriter.h b/src/gui/painting/qpdfwriter.h
index b260805b2b..668081e008 100644
--- a/src/gui/painting/qpdfwriter.h
+++ b/src/gui/painting/qpdfwriter.h
@@ -86,10 +86,14 @@ public:
using QPagedPaintDevice::setPageSize;
#endif
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_X("Use setPageSize(QPageSize(id)) instead")
void setPageSize(PageSize size) override;
+ QT_DEPRECATED_X("Use setPageSize(QPageSize(size, QPageSize::Millimeter)) instead")
void setPageSizeMM(const QSizeF &size) override;
-
+ QT_DEPRECATED_X("Use setPageMargins(QMarginsF(l, t, r, b), QPageLayout::Millimeter) instead")
void setMargins(const Margins &m) override;
+#endif
protected:
QPaintEngine *paintEngine() const override;
diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp
index c01531caf2..f8f8d72d14 100644
--- a/src/gui/painting/qstroker.cpp
+++ b/src/gui/painting/qstroker.cpp
@@ -173,15 +173,12 @@ template <class Iterator> bool qt_stroke_side(Iterator *it, QStroker *stroker,
bool capFirst, QLineF *startTangent);
/*******************************************************************************
- * QLineF::angle gives us the smalles angle between two lines. Here we
- * want to identify the line's angle direction on the unit circle.
+ * QLineF::angleTo gives us the angle between two lines with respecting the direction.
+ * Here we want to identify the line's angle direction on the unit circle.
*/
static inline qreal adapted_angle_on_x(const QLineF &line)
{
- qreal angle = line.angle(QLineF(0, 0, 1, 0));
- if (line.dy() > 0)
- angle = 360 - angle;
- return angle;
+ return QLineF(0, 0, 1, 0).angleTo(line);
}
QStrokerOps::QStrokerOps()
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index a51e98ce85..d54fa22990 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -3164,7 +3164,104 @@ void QFontCache::decreaseCache()
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug stream, const QFont &font)
{
- return stream << "QFont(" << font.toString() << ')';
+ QDebugStateSaver saver(stream);
+ stream.nospace().noquote();
+ stream << "QFont(";
+
+ if (stream.verbosity() == QDebug::DefaultVerbosity) {
+ stream << font.toString() << ")";
+ return stream;
+ }
+
+ QString fontDescription;
+ QDebug debug(&fontDescription);
+ debug.nospace();
+
+ QFontPrivate priv;
+ const QFont defaultFont(&priv);
+
+ for (int property = QFont::FamilyResolved; property < QFont::AllPropertiesResolved; property <<= 1) {
+ const bool resolved = (font.resolve_mask & property) != 0;
+ if (!resolved && stream.verbosity() == QDebug::MinimumVerbosity)
+ continue;
+
+ #define QFONT_DEBUG_SKIP_DEFAULT(prop) \
+ if ((font.prop() == defaultFont.prop()) && stream.verbosity() == 1) \
+ continue;
+
+ QDebugStateSaver saver(debug);
+
+ switch (property) {
+ case QFont::FamilyResolved:
+ debug << font.family(); break;
+ case QFont::SizeResolved:
+ if (font.pointSizeF() >= 0)
+ debug << font.pointSizeF() << "pt";
+ else if (font.pixelSize() >= 0)
+ debug << font.pixelSize() << "px";
+ else
+ Q_UNREACHABLE();
+ break;
+ case QFont::StyleHintResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(styleHint);
+ debug.verbosity(1) << font.styleHint(); break;
+ case QFont::StyleStrategyResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(styleStrategy);
+ debug.verbosity(1) << font.styleStrategy(); break;
+ case QFont::WeightResolved:
+ debug.verbosity(1) << QFont::Weight(font.weight()); break;
+ case QFont::StyleResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(style);
+ debug.verbosity(0) << font.style(); break;
+ case QFont::UnderlineResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(underline);
+ debug << "underline=" << font.underline(); break;
+ case QFont::OverlineResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(overline);
+ debug << "overline=" << font.overline(); break;
+ case QFont::StrikeOutResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(strikeOut);
+ debug << "strikeOut=" << font.strikeOut(); break;
+ case QFont::FixedPitchResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(fixedPitch);
+ debug << "fixedPitch=" << font.fixedPitch(); break;
+ case QFont::StretchResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(stretch);
+ debug.verbosity(0) << QFont::Stretch(font.stretch()); break;
+ case QFont::KerningResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(kerning);
+ debug << "kerning=" << font.kerning(); break;
+ case QFont::CapitalizationResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(capitalization);
+ debug.verbosity(0) << font.capitalization(); break;
+ case QFont::LetterSpacingResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(letterSpacing);
+ debug << "letterSpacing=" << font.letterSpacing();
+ debug.verbosity(0) << " (" << font.letterSpacingType() << ")";
+ break;
+ case QFont::HintingPreferenceResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(hintingPreference);
+ debug.verbosity(0) << font.hintingPreference(); break;
+ case QFont::StyleNameResolved:
+ QFONT_DEBUG_SKIP_DEFAULT(styleName);
+ debug << "styleName=" << font.styleName(); break;
+ default:
+ continue;
+ };
+
+ #undef QFONT_DEBUG_SKIP_DEFAULT
+
+ debug << ", ";
+ }
+
+ if (stream.verbosity() > QDebug::MinimumVerbosity)
+ debug.verbosity(0) << "resolveMask=" << QFlags<QFont::ResolveProperties>(font.resolve_mask);
+ else
+ fontDescription.chop(2); // Last ', '
+
+ stream << fontDescription << ')';
+
+ return stream;
}
#endif
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index e86f06353a..35ef798275 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -147,6 +147,7 @@ public:
Q_ENUM(SpacingType)
enum ResolveProperties {
+ NoPropertiesResolved = 0x0000,
FamilyResolved = 0x0001,
SizeResolved = 0x0002,
StyleHintResolved = 0x0004,
@@ -167,6 +168,7 @@ public:
FamiliesResolved = 0x20000,
AllPropertiesResolved = 0x3ffff
};
+ Q_ENUM(ResolveProperties)
QFont();
QFont(const QString &family, int pointSize = -1, int weight = -1, bool italic = false);
@@ -335,6 +337,10 @@ private:
friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QFont &);
#endif
+#ifndef QT_NO_DEBUG_STREAM
+ friend Q_GUI_EXPORT QDebug operator<<(QDebug, const QFont &);
+#endif
+
QExplicitlySharedDataPointer<QFontPrivate> d;
uint resolve_mask;
};
diff --git a/src/gui/util/qvalidator.h b/src/gui/util/qvalidator.h
index cc7cbcb559..f0e72e3814 100644
--- a/src/gui/util/qvalidator.h
+++ b/src/gui/util/qvalidator.h
@@ -69,6 +69,7 @@ public:
Intermediate,
Acceptable
};
+ Q_ENUM(State)
void setLocale(const QLocale &locale);
QLocale locale() const;
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index 681d84fee8..ee1e3cfb8f 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -398,11 +398,12 @@ void QHttpNetworkConnectionPrivate::copyCredentials(int fromChannel, QAuthentica
{
Q_ASSERT(auth);
- // NTLM is a multi phase authentication. Copying credentials between authenticators would mess things up.
+ // NTLM and Negotiate do multi-phase authentication.
+ // Copying credentialsbetween authenticators would mess things up.
if (fromChannel >= 0) {
- if (!isProxy && channels[fromChannel].authMethod == QAuthenticatorPrivate::Ntlm)
- return;
- if (isProxy && channels[fromChannel].proxyAuthMethod == QAuthenticatorPrivate::Ntlm)
+ const QHttpNetworkConnectionChannel &channel = channels[fromChannel];
+ const QAuthenticatorPrivate::Method method = isProxy ? channel.proxyAuthMethod : channel.authMethod;
+ if (method == QAuthenticatorPrivate::Ntlm || method == QAuthenticatorPrivate::Negotiate)
return;
}
@@ -592,7 +593,7 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket,
if ((channels[i].authMethod != QAuthenticatorPrivate::Ntlm && request.headerField("Authorization").isEmpty()) || channels[i].lastStatus == 401) {
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].authenticator);
if (priv && priv->method != QAuthenticatorPrivate::None) {
- QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false));
+ QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false), request.url().host());
request.setHeaderField("Authorization", response);
channels[i].authenticationCredentialsSent = true;
}
@@ -604,7 +605,7 @@ void QHttpNetworkConnectionPrivate::createAuthorization(QAbstractSocket *socket,
if (!(channels[i].proxyAuthMethod == QAuthenticatorPrivate::Ntlm && channels[i].lastStatus != 407)) {
QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(channels[i].proxyAuthenticator);
if (priv && priv->method != QAuthenticatorPrivate::None) {
- QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false));
+ QByteArray response = priv->calculateResponse(request.methodName(), request.uri(false), networkProxy.hostName());
request.setHeaderField("Proxy-Authorization", response);
channels[i].proxyCredentialsSent = true;
}
diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp
index c9c3172304..a8b635c45a 100644
--- a/src/network/access/qhttpnetworkreply.cpp
+++ b/src/network/access/qhttpnetworkreply.cpp
@@ -444,6 +444,9 @@ QAuthenticatorPrivate::Method QHttpNetworkReplyPrivate::authenticationMethod(boo
} else if (method < QAuthenticatorPrivate::DigestMd5
&& line.startsWith("digest")) {
method = QAuthenticatorPrivate::DigestMd5;
+ } else if (method < QAuthenticatorPrivate::Negotiate
+ && line.startsWith("negotiate")) {
+ method = QAuthenticatorPrivate::Negotiate;
}
}
return method;
diff --git a/src/network/configure.json b/src/network/configure.json
index e6c87b550b..be9e35c7fe 100644
--- a/src/network/configure.json
+++ b/src/network/configure.json
@@ -199,6 +199,15 @@
]
},
"use": "openssl"
+ },
+ "gssapi": {
+ "label": "KRB5 GSSAPI support",
+ "type": "compile",
+ "test": {
+ "include": [ "gssapi/gssapi.h" ],
+ "main": ["gss_ctx_id_t ctx;"],
+ "qmake": "LIBS += -lgssapi_krb5"
+ }
}
},
@@ -261,7 +270,7 @@
"disable": "input.securetransport == 'no' || input.ssl == 'no'",
"condition": "config.darwin && (input.openssl == '' || input.openssl == 'no')",
"output": [
- "privateFeature",
+ "publicFeature",
{ "type": "define", "name": "QT_SECURETRANSPORT" }
]
},
@@ -283,7 +292,7 @@
"label": "DTLS",
"purpose": "Provides a DTLS implementation",
"section": "Networking",
- "condition": "features.openssl && tests.dtls",
+ "condition": "features.openssl && features.udpsocket && tests.dtls",
"output": [ "publicFeature" ]
},
"ocsp": {
@@ -374,6 +383,20 @@
"purpose": "Provides API for DNS lookups.",
"section": "Networking",
"output": [ "publicFeature" ]
+ },
+ "gssapi": {
+ "label": "GSSAPI",
+ "purpose": "Enable SPNEGO authentication through GSSAPI",
+ "section": "Networking",
+ "condition": "!config.win32 && tests.gssapi",
+ "output": [ "publicFeature", "feature" ]
+ },
+ "sspi": {
+ "label": "SSPI",
+ "purpose": "Enable NTLM/SPNEGO authentication through SSPI",
+ "section": "Networking",
+ "condition": "config.win32 && !config.winrt",
+ "output": [ "publicFeature", "feature" ]
}
},
@@ -433,7 +456,8 @@ For example:
"dtls",
"ocsp",
"sctp",
- "system-proxies"
+ "system-proxies",
+ "gssapi"
]
}
]
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index 11b80d59d5..f7269e5070 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -68,6 +68,8 @@ mac {
!uikit: LIBS_PRIVATE += -framework CoreServices -framework SystemConfiguration
}
+qtConfig(gssapi): LIBS_PRIVATE += -lgssapi_krb5
+
uikit:HEADERS += kernel/qnetworkinterface_uikit_p.h
osx:SOURCES += kernel/qnetworkproxy_mac.cpp
else:win32:!winrt: SOURCES += kernel/qnetworkproxy_win.cpp
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index 47ce9ab0c6..3ca8806c2b 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -54,20 +54,29 @@
#include <qmutex.h>
#include <private/qmutexpool_p.h>
#include <rpc.h>
-#ifndef Q_OS_WINRT
+#endif
+
+#if QT_CONFIG(sspi) // SSPI
#define SECURITY_WIN32 1
#include <security.h>
-#endif
+#elif QT_CONFIG(gssapi) // GSSAPI
+#include <gssapi/gssapi.h>
#endif
QT_BEGIN_NAMESPACE
static QByteArray qNtlmPhase1();
static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phase2data);
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
-static QByteArray qNtlmPhase1_SSPI(QAuthenticatorPrivate *ctx);
-static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& phase2data);
-#endif
+#if QT_CONFIG(sspi) // SSPI
+static QByteArray qSspiStartup(QAuthenticatorPrivate *ctx, QAuthenticatorPrivate::Method method,
+ const QString& host);
+static QByteArray qSspiContinue(QAuthenticatorPrivate *ctx, QAuthenticatorPrivate::Method method,
+ const QString& host, const QByteArray& challenge = QByteArray());
+#elif QT_CONFIG(gssapi) // GSSAPI
+static QByteArray qGssapiStartup(QAuthenticatorPrivate *ctx, const QString& host);
+static QByteArray qGssapiContinue(QAuthenticatorPrivate *ctx,
+ const QByteArray& challenge = QByteArray());
+#endif // gssapi
/*!
\class QAuthenticator
@@ -90,6 +99,7 @@ static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray&
\li Basic
\li NTLM version 2
\li Digest-MD5
+ \li SPNEGO/Negotiate
\endlist
\target qauthenticator-options
@@ -133,6 +143,10 @@ static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray&
The Digest-MD5 authentication mechanism supports no outgoing options.
+ \section2 SPNEGO/Negotiate
+
+ This authentication mechanism currently supports no incoming or outgoing options.
+
\sa QSslSocket
*/
@@ -187,7 +201,7 @@ QAuthenticator &QAuthenticator::operator=(const QAuthenticator &other)
d->options = other.d->options;
} else if (d->phase == QAuthenticatorPrivate::Start) {
delete d;
- d = 0;
+ d = nullptr;
}
return *this;
}
@@ -339,21 +353,25 @@ bool QAuthenticator::isNull() const
return !d;
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
-class QNtlmWindowsHandles
+#if QT_CONFIG(sspi) // SSPI
+class QSSPIWindowsHandles
{
public:
CredHandle credHandle;
CtxtHandle ctxHandle;
};
-#endif
+#elif QT_CONFIG(gssapi) // GSSAPI
+class QGssApiHandles
+{
+public:
+ gss_ctx_id_t gssCtx = nullptr;
+ gss_name_t targetName;
+};
+#endif // gssapi
QAuthenticatorPrivate::QAuthenticatorPrivate()
: method(None)
- #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- , ntlmWindowsHandles(0)
- #endif
, hasFailed(false)
, phase(Start)
, nonceCount(0)
@@ -363,13 +381,7 @@ QAuthenticatorPrivate::QAuthenticatorPrivate()
nonceCount = 0;
}
-QAuthenticatorPrivate::~QAuthenticatorPrivate()
-{
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
- if (ntlmWindowsHandles)
- delete ntlmWindowsHandles;
-#endif
-}
+QAuthenticatorPrivate::~QAuthenticatorPrivate() = default;
void QAuthenticatorPrivate::updateCredentials()
{
@@ -424,6 +436,9 @@ void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByt
} else if (method < DigestMd5 && str.startsWith("digest")) {
method = DigestMd5;
headerVal = current.second.mid(7);
+ } else if (method < Negotiate && str.startsWith("negotiate")) {
+ method = Negotiate;
+ headerVal = current.second.mid(10);
}
}
@@ -439,6 +454,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByt
phase = Done;
break;
case Ntlm:
+ case Negotiate:
// work is done in calculateResponse()
break;
case DigestMd5: {
@@ -456,33 +472,36 @@ void QAuthenticatorPrivate::parseHttpResponse(const QList<QPair<QByteArray, QByt
}
}
-QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMethod, const QByteArray &path)
+QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMethod, const QByteArray &path, const QString& host)
{
+#if !QT_CONFIG(sspi) && !QT_CONFIG(gssapi)
+ Q_UNUSED(host);
+#endif
QByteArray response;
- const char *methodString = 0;
+ const char* methodString = nullptr;
switch(method) {
case QAuthenticatorPrivate::None:
methodString = "";
phase = Done;
break;
case QAuthenticatorPrivate::Basic:
- methodString = "Basic ";
+ methodString = "Basic";
response = user.toLatin1() + ':' + password.toLatin1();
response = response.toBase64();
phase = Done;
break;
case QAuthenticatorPrivate::DigestMd5:
- methodString = "Digest ";
+ methodString = "Digest";
response = digestMd5Response(challenge, requestMethod, path);
phase = Done;
break;
case QAuthenticatorPrivate::Ntlm:
- methodString = "NTLM ";
+ methodString = "NTLM";
if (challenge.isEmpty()) {
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if QT_CONFIG(sspi) // SSPI
QByteArray phase1Token;
if (user.isEmpty()) // Only pull from system if no user was specified in authenticator
- phase1Token = qNtlmPhase1_SSPI(this);
+ phase1Token = qSspiStartup(this, method, host);
if (!phase1Token.isEmpty()) {
response = phase1Token.toBase64();
phase = Phase2;
@@ -496,10 +515,10 @@ QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMet
phase = Phase2;
}
} else {
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+#if QT_CONFIG(sspi) // SSPI
QByteArray phase3Token;
- if (ntlmWindowsHandles)
- phase3Token = qNtlmPhase3_SSPI(this, QByteArray::fromBase64(challenge));
+ if (sspiWindowsHandles)
+ phase3Token = qSspiContinue(this, method, host, QByteArray::fromBase64(challenge));
if (!phase3Token.isEmpty()) {
response = phase3Token.toBase64();
phase = Done;
@@ -512,8 +531,39 @@ QByteArray QAuthenticatorPrivate::calculateResponse(const QByteArray &requestMet
}
break;
+ case QAuthenticatorPrivate::Negotiate:
+ methodString = "Negotiate";
+ if (challenge.isEmpty()) {
+ QByteArray phase1Token;
+#if QT_CONFIG(sspi) // SSPI
+ phase1Token = qSspiStartup(this, method, host);
+#elif QT_CONFIG(gssapi) // GSSAPI
+ phase1Token = qGssapiStartup(this, host);
+#endif
+
+ if (!phase1Token.isEmpty()) {
+ response = phase1Token.toBase64();
+ phase = Phase2;
+ } else {
+ phase = Done;
+ }
+ } else {
+ QByteArray phase3Token;
+#if QT_CONFIG(sspi) // SSPI
+ phase3Token = qSspiContinue(this, method, host, QByteArray::fromBase64(challenge));
+#elif QT_CONFIG(gssapi) // GSSAPI
+ phase3Token = qGssapiContinue(this, QByteArray::fromBase64(challenge));
+#endif
+ if (!phase3Token.isEmpty()) {
+ response = phase3Token.toBase64();
+ phase = Done;
+ }
+ }
+
+ break;
}
- return QByteArray(methodString) + response;
+
+ return QByteArray::fromRawData(methodString, qstrlen(methodString)) + ' ' + response;
}
@@ -699,9 +749,10 @@ QByteArray QAuthenticatorPrivate::digestMd5Response(const QByteArray &challenge,
return credentials;
}
-// ---------------------------- Digest Md5 code ----------------------------------------
+// ---------------------------- End of Digest Md5 code ---------------------------------
+// ---------------------------- NTLM code ----------------------------------------------
/*
* NTLM message flags.
@@ -1419,156 +1470,237 @@ static QByteArray qNtlmPhase3(QAuthenticatorPrivate *ctx, const QByteArray& phas
return rc;
}
-#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
+// ---------------------------- End of NTLM code ---------------------------------------
+
+#if QT_CONFIG(sspi) // SSPI
+// ---------------------------- SSPI code ----------------------------------------------
// See http://davenport.sourceforge.net/ntlm.html
// and libcurl http_ntlm.c
// Handle of secur32.dll
-static HMODULE securityDLLHandle = NULL;
+static HMODULE securityDLLHandle = nullptr;
// Pointer to SSPI dispatch table
-static PSecurityFunctionTable pSecurityFunctionTable = NULL;
-
+static PSecurityFunctionTable pSecurityFunctionTable = nullptr;
-static bool q_NTLM_SSPI_library_load()
+static bool q_SSPI_library_load()
{
static QBasicMutex mutex;
QMutexLocker l(&mutex);
// Initialize security interface
- if (pSecurityFunctionTable == NULL) {
+ if (pSecurityFunctionTable == nullptr) {
securityDLLHandle = LoadLibrary(L"secur32.dll");
- if (securityDLLHandle != NULL) {
+ if (securityDLLHandle != nullptr) {
INIT_SECURITY_INTERFACE pInitSecurityInterface =
reinterpret_cast<INIT_SECURITY_INTERFACE>(
reinterpret_cast<QFunctionPointer>(GetProcAddress(securityDLLHandle, "InitSecurityInterfaceW")));
- if (pInitSecurityInterface != NULL)
+ if (pInitSecurityInterface != nullptr)
pSecurityFunctionTable = pInitSecurityInterface();
}
}
- if (pSecurityFunctionTable == NULL)
+ if (pSecurityFunctionTable == nullptr)
return false;
return true;
}
-// Phase 1:
-static QByteArray qNtlmPhase1_SSPI(QAuthenticatorPrivate *ctx)
+static QByteArray qSspiStartup(QAuthenticatorPrivate *ctx, QAuthenticatorPrivate::Method method,
+ const QString& host)
{
- QByteArray result;
+ if (!q_SSPI_library_load())
+ return QByteArray();
+
+ TimeStamp expiry; // For Windows 9x compatibility of SSPI calls
- if (!q_NTLM_SSPI_library_load())
- return result;
+ if (!ctx->sspiWindowsHandles)
+ ctx->sspiWindowsHandles.reset(new QSSPIWindowsHandles);
+ memset(&ctx->sspiWindowsHandles->credHandle, 0, sizeof(CredHandle));
- // 1. The client obtains a representation of the credential set
- // for the user via the SSPI AcquireCredentialsHandle function.
- if (!ctx->ntlmWindowsHandles)
- ctx->ntlmWindowsHandles = new QNtlmWindowsHandles;
- memset(&ctx->ntlmWindowsHandles->credHandle, 0, sizeof(CredHandle));
- TimeStamp tsDummy;
+ // Acquire our credentials handle
SECURITY_STATUS secStatus = pSecurityFunctionTable->AcquireCredentialsHandle(
- NULL, (SEC_WCHAR*)L"NTLM", SECPKG_CRED_OUTBOUND, NULL, NULL,
- NULL, NULL, &ctx->ntlmWindowsHandles->credHandle, &tsDummy);
+ nullptr,
+ (SEC_WCHAR*)(method == QAuthenticatorPrivate::Negotiate ? L"Negotiate" : L"NTLM"),
+ SECPKG_CRED_OUTBOUND, nullptr, nullptr, nullptr, nullptr,
+ &ctx->sspiWindowsHandles->credHandle, &expiry
+ );
if (secStatus != SEC_E_OK) {
- delete ctx->ntlmWindowsHandles;
- ctx->ntlmWindowsHandles = 0;
- return result;
+ ctx->sspiWindowsHandles.reset(nullptr);
+ return QByteArray();
}
- // 2. The client calls the SSPI InitializeSecurityContext function
- // to obtain an authentication request token (in our case, a Type 1 message).
- // The client sends this token to the server.
- SecBufferDesc desc;
- SecBuffer buf;
- desc.ulVersion = SECBUFFER_VERSION;
- desc.cBuffers = 1;
- desc.pBuffers = &buf;
- buf.cbBuffer = 0;
- buf.BufferType = SECBUFFER_TOKEN;
- buf.pvBuffer = NULL;
- ULONG attrs;
-
- secStatus = pSecurityFunctionTable->InitializeSecurityContext(&ctx->ntlmWindowsHandles->credHandle, NULL,
- const_cast<SEC_WCHAR*>(L"") /* host */,
- ISC_REQ_ALLOCATE_MEMORY,
- 0, SECURITY_NETWORK_DREP,
- NULL, 0,
- &ctx->ntlmWindowsHandles->ctxHandle, &desc,
- &attrs, &tsDummy);
- if (secStatus == SEC_I_COMPLETE_AND_CONTINUE ||
- secStatus == SEC_I_CONTINUE_NEEDED) {
- pSecurityFunctionTable->CompleteAuthToken(&ctx->ntlmWindowsHandles->ctxHandle, &desc);
- } else if (secStatus != SEC_E_OK) {
- if ((const char*)buf.pvBuffer)
- pSecurityFunctionTable->FreeContextBuffer(buf.pvBuffer);
- pSecurityFunctionTable->FreeCredentialsHandle(&ctx->ntlmWindowsHandles->credHandle);
- delete ctx->ntlmWindowsHandles;
- ctx->ntlmWindowsHandles = 0;
- return result;
+ return qSspiContinue(ctx, method, host);
+}
+
+static QByteArray qSspiContinue(QAuthenticatorPrivate *ctx, QAuthenticatorPrivate::Method method,
+ const QString &host, const QByteArray &challenge)
+{
+ QByteArray result;
+ SecBuffer challengeBuf;
+ SecBuffer responseBuf;
+ SecBufferDesc challengeDesc;
+ SecBufferDesc responseDesc;
+ unsigned long attrs;
+ TimeStamp expiry; // For Windows 9x compatibility of SSPI calls
+
+ if (!challenge.isEmpty())
+ {
+ // Setup the challenge "input" security buffer
+ challengeDesc.ulVersion = SECBUFFER_VERSION;
+ challengeDesc.cBuffers = 1;
+ challengeDesc.pBuffers = &challengeBuf;
+ challengeBuf.BufferType = SECBUFFER_TOKEN;
+ challengeBuf.pvBuffer = (PVOID)(challenge.data());
+ challengeBuf.cbBuffer = challenge.length();
}
- result = QByteArray((const char*)buf.pvBuffer, buf.cbBuffer);
- pSecurityFunctionTable->FreeContextBuffer(buf.pvBuffer);
+ // Setup the response "output" security buffer
+ responseDesc.ulVersion = SECBUFFER_VERSION;
+ responseDesc.cBuffers = 1;
+ responseDesc.pBuffers = &responseBuf;
+ responseBuf.BufferType = SECBUFFER_TOKEN;
+ responseBuf.pvBuffer = nullptr;
+ responseBuf.cbBuffer = 0;
+
+ // Calculate target (SPN for Negotiate, empty for NTLM)
+ std::wstring targetNameW = (method == QAuthenticatorPrivate::Negotiate
+ ? QLatin1String("HTTP/") + host : QString()).toStdWString();
+
+ // Generate our challenge-response message
+ SECURITY_STATUS secStatus = pSecurityFunctionTable->InitializeSecurityContext(
+ &ctx->sspiWindowsHandles->credHandle,
+ !challenge.isEmpty() ? &ctx->sspiWindowsHandles->ctxHandle : nullptr,
+ const_cast<wchar_t*>(targetNameW.data()),
+ ISC_REQ_ALLOCATE_MEMORY,
+ 0, SECURITY_NATIVE_DREP,
+ !challenge.isEmpty() ? &challengeDesc : nullptr,
+ 0, &ctx->sspiWindowsHandles->ctxHandle,
+ &responseDesc, &attrs,
+ &expiry
+ );
+
+ if (secStatus == SEC_I_COMPLETE_NEEDED || secStatus == SEC_I_COMPLETE_AND_CONTINUE) {
+ secStatus = pSecurityFunctionTable->CompleteAuthToken(&ctx->sspiWindowsHandles->ctxHandle,
+ &responseDesc);
+ }
+
+ if (secStatus != SEC_I_COMPLETE_AND_CONTINUE && secStatus != SEC_I_CONTINUE_NEEDED) {
+ pSecurityFunctionTable->FreeCredentialsHandle(&ctx->sspiWindowsHandles->credHandle);
+ pSecurityFunctionTable->DeleteSecurityContext(&ctx->sspiWindowsHandles->ctxHandle);
+ ctx->sspiWindowsHandles.reset(nullptr);
+ }
+
+ result = QByteArray((const char*)responseBuf.pvBuffer, responseBuf.cbBuffer);
+ pSecurityFunctionTable->FreeContextBuffer(responseBuf.pvBuffer);
+
return result;
}
-// Phase 2:
-// 3. The server receives the token from the client, and uses it as input to the
-// AcceptSecurityContext SSPI function. This creates a local security context on
-// the server to represent the client, and yields an authentication response token
-// (the Type 2 message), which is sent to the client.
+// ---------------------------- End of SSPI code ---------------------------------------
+
+#elif QT_CONFIG(gssapi) // GSSAPI
+
+// ---------------------------- GSSAPI code ----------------------------------------------
+// See postgres src/interfaces/libpq/fe-auth.c
+
+// Fetch all errors of a specific type
+static void q_GSSAPI_error_int(const char *message, OM_uint32 stat, int type)
+{
+ OM_uint32 minStat, msgCtx = 0;
+ gss_buffer_desc msg;
+
+ do {
+ gss_display_status(&minStat, stat, type, GSS_C_NO_OID, &msgCtx, &msg);
+ qDebug() << message << ": " << reinterpret_cast<const char*>(msg.value);
+ gss_release_buffer(&minStat, &msg);
+ } while (msgCtx);
+}
-// Phase 3:
-static QByteArray qNtlmPhase3_SSPI(QAuthenticatorPrivate *ctx, const QByteArray& phase2data)
+// GSSAPI errors contain two parts; extract both
+static void q_GSSAPI_error(const char *message, OM_uint32 majStat, OM_uint32 minStat)
{
- // 4. The client receives the response token from the server and calls
- // InitializeSecurityContext again, passing the server's token as input.
- // This provides us with another authentication request token (the Type 3 message).
- // The return value indicates that the security context was successfully initialized;
- // the token is sent to the server.
+ // Fetch major error codes
+ q_GSSAPI_error_int(message, majStat, GSS_C_GSS_CODE);
+ // Add the minor codes as well
+ q_GSSAPI_error_int(message, minStat, GSS_C_MECH_CODE);
+}
+
+// Send initial GSS authentication token
+static QByteArray qGssapiStartup(QAuthenticatorPrivate *ctx, const QString &host)
+{
+ OM_uint32 majStat, minStat;
+
+ if (!ctx->gssApiHandles)
+ ctx->gssApiHandles.reset(new QGssApiHandles);
+
+ // Convert target name to internal form
+ QByteArray serviceName = QStringLiteral("HTTPS@%1").arg(host).toLocal8Bit();
+ gss_buffer_desc nameDesc = {static_cast<std::size_t>(serviceName.size()), serviceName.data()};
+
+ majStat = gss_import_name(&minStat, &nameDesc,
+ GSS_C_NT_HOSTBASED_SERVICE, &ctx->gssApiHandles->targetName);
+
+ if (majStat != GSS_S_COMPLETE) {
+ q_GSSAPI_error("gss_import_name error", majStat, minStat);
+ ctx->gssApiHandles.reset(nullptr);
+ return QByteArray();
+ }
+
+ // Call qGssapiContinue with GSS_C_NO_CONTEXT to get initial packet
+ ctx->gssApiHandles->gssCtx = GSS_C_NO_CONTEXT;
+ return qGssapiContinue(ctx);
+}
+
+// Continue GSS authentication with next token as needed
+static QByteArray qGssapiContinue(QAuthenticatorPrivate *ctx, const QByteArray& challenge)
+{
+ OM_uint32 majStat, minStat, ignored;
QByteArray result;
+ gss_buffer_desc inBuf = {0, nullptr}; // GSS input token
+ gss_buffer_desc outBuf; // GSS output token
- if (pSecurityFunctionTable == NULL)
- return result;
-
- SecBuffer type_2, type_3;
- SecBufferDesc type_2_desc, type_3_desc;
- ULONG attrs;
- TimeStamp tsDummy; // For Windows 9x compatibility of SPPI calls
-
- type_2_desc.ulVersion = type_3_desc.ulVersion = SECBUFFER_VERSION;
- type_2_desc.cBuffers = type_3_desc.cBuffers = 1;
- type_2_desc.pBuffers = &type_2;
- type_3_desc.pBuffers = &type_3;
-
- type_2.BufferType = SECBUFFER_TOKEN;
- type_2.pvBuffer = (PVOID)phase2data.data();
- type_2.cbBuffer = phase2data.length();
- type_3.BufferType = SECBUFFER_TOKEN;
- type_3.pvBuffer = 0;
- type_3.cbBuffer = 0;
-
- SECURITY_STATUS secStatus = pSecurityFunctionTable->InitializeSecurityContext(&ctx->ntlmWindowsHandles->credHandle,
- &ctx->ntlmWindowsHandles->ctxHandle,
- const_cast<SEC_WCHAR*>(L"") /* host */,
- ISC_REQ_ALLOCATE_MEMORY,
- 0, SECURITY_NETWORK_DREP, &type_2_desc,
- 0, &ctx->ntlmWindowsHandles->ctxHandle, &type_3_desc,
- &attrs, &tsDummy);
-
- if (secStatus == SEC_E_OK && ((const char*)type_3.pvBuffer)) {
- result = QByteArray((const char*)type_3.pvBuffer, type_3.cbBuffer);
- pSecurityFunctionTable->FreeContextBuffer(type_3.pvBuffer);
+ if (!challenge.isEmpty()) {
+ inBuf.value = const_cast<char*>(challenge.data());
+ inBuf.length = challenge.length();
}
- pSecurityFunctionTable->FreeCredentialsHandle(&ctx->ntlmWindowsHandles->credHandle);
- pSecurityFunctionTable->DeleteSecurityContext(&ctx->ntlmWindowsHandles->ctxHandle);
- delete ctx->ntlmWindowsHandles;
- ctx->ntlmWindowsHandles = 0;
+ majStat = gss_init_sec_context(&minStat,
+ GSS_C_NO_CREDENTIAL,
+ &ctx->gssApiHandles->gssCtx,
+ ctx->gssApiHandles->targetName,
+ GSS_C_NO_OID,
+ GSS_C_MUTUAL_FLAG,
+ 0,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ challenge.isEmpty() ? GSS_C_NO_BUFFER : &inBuf,
+ nullptr,
+ &outBuf,
+ nullptr,
+ nullptr);
+
+ if (outBuf.length != 0)
+ result = QByteArray(reinterpret_cast<const char*>(outBuf.value), outBuf.length);
+ gss_release_buffer(&ignored, &outBuf);
+
+ if (majStat != GSS_S_COMPLETE && majStat != GSS_S_CONTINUE_NEEDED) {
+ q_GSSAPI_error("gss_init_sec_context error", majStat, minStat);
+ gss_release_name(&ignored, &ctx->gssApiHandles->targetName);
+ if (ctx->gssApiHandles->gssCtx)
+ gss_delete_sec_context(&ignored, &ctx->gssApiHandles->gssCtx, GSS_C_NO_BUFFER);
+ ctx->gssApiHandles.reset(nullptr);
+ }
+
+ if (majStat == GSS_S_COMPLETE) {
+ gss_release_name(&ignored, &ctx->gssApiHandles->targetName);
+ ctx->gssApiHandles.reset(nullptr);
+ }
return result;
}
-#endif // Q_OS_WIN && !Q_OS_WINRT
+
+// ---------------------------- End of GSSAPI code ----------------------------------------------
+
+#endif // gssapi
QT_END_NAMESPACE
diff --git a/src/network/kernel/qauthenticator_p.h b/src/network/kernel/qauthenticator_p.h
index 265cb7afe2..e201d22650 100644
--- a/src/network/kernel/qauthenticator_p.h
+++ b/src/network/kernel/qauthenticator_p.h
@@ -54,6 +54,7 @@
#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <qhash.h>
#include <qbytearray.h>
+#include <qscopedpointer.h>
#include <qstring.h>
#include <qauthenticator.h>
#include <qvariant.h>
@@ -61,14 +62,16 @@
QT_BEGIN_NAMESPACE
class QHttpResponseHeader;
-#ifdef Q_OS_WIN
-class QNtlmWindowsHandles;
+#if QT_CONFIG(sspi) // SSPI
+class QSSPIWindowsHandles;
+#elif QT_CONFIG(gssapi) // GSSAPI
+class QGssApiHandles;
#endif
class Q_AUTOTEST_EXPORT QAuthenticatorPrivate
{
public:
- enum Method { None, Basic, Ntlm, DigestMd5 };
+ enum Method { None, Basic, Ntlm, DigestMd5, Negotiate };
QAuthenticatorPrivate();
~QAuthenticatorPrivate();
@@ -79,8 +82,10 @@ public:
Method method;
QString realm;
QByteArray challenge;
-#ifdef Q_OS_WIN
- QNtlmWindowsHandles *ntlmWindowsHandles;
+#if QT_CONFIG(sspi) // SSPI
+ QScopedPointer<QSSPIWindowsHandles> sspiWindowsHandles;
+#elif QT_CONFIG(gssapi) // GSSAPI
+ QScopedPointer<QGssApiHandles> gssApiHandles;
#endif
bool hasFailed; //credentials have been tried but rejected by server.
@@ -100,7 +105,7 @@ public:
QString workstation;
QString userDomain;
- QByteArray calculateResponse(const QByteArray &method, const QByteArray &path);
+ QByteArray calculateResponse(const QByteArray &method, const QByteArray &path, const QString& host);
inline static QAuthenticatorPrivate *getPrivate(QAuthenticator &auth) { return auth.d; }
inline static const QAuthenticatorPrivate *getPrivate(const QAuthenticator &auth) { return auth.d; }
diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp
index 49ea17f9f8..6cae29193d 100644
--- a/src/network/socket/qhttpsocketengine.cpp
+++ b/src/network/socket/qhttpsocketengine.cpp
@@ -524,7 +524,7 @@ void QHttpSocketEngine::slotSocketConnected()
//qDebug() << "slotSocketConnected: priv=" << priv << (priv ? (int)priv->method : -1);
if (priv && priv->method != QAuthenticatorPrivate::None) {
d->credentialsSent = true;
- data += "Proxy-Authorization: " + priv->calculateResponse(method, path);
+ data += "Proxy-Authorization: " + priv->calculateResponse(method, path, d->proxy.hostName());
data += "\r\n";
}
data += "\r\n";
diff --git a/src/network/ssl/qsslcontext_openssl11.cpp b/src/network/ssl/qsslcontext_openssl11.cpp
index 21a5c779f7..db023b7331 100644
--- a/src/network/ssl/qsslcontext_openssl11.cpp
+++ b/src/network/ssl/qsslcontext_openssl11.cpp
@@ -193,7 +193,6 @@ init_context:
minVersion = TLS1_2_VERSION;
maxVersion = 0;
break;
-#if QT_CONFIG(dtls)
case QSsl::DtlsV1_0:
minVersion = DTLS1_VERSION;
maxVersion = DTLS1_VERSION;
@@ -210,7 +209,6 @@ init_context:
minVersion = DTLS1_2_VERSION;
maxVersion = DTLS_MAX_VERSION;
break;
-#endif // dtls
case QSsl::TlsV1_3OrLater:
#ifdef TLS1_3_VERSION
minVersion = TLS1_3_VERSION;
diff --git a/src/network/ssl/qsslkey_mac.cpp b/src/network/ssl/qsslkey_mac.cpp
index d460cbfdab..814fe1c4bc 100644
--- a/src/network/ssl/qsslkey_mac.cpp
+++ b/src/network/ssl/qsslkey_mac.cpp
@@ -42,7 +42,9 @@
#include <CommonCrypto/CommonCrypto.h>
-QT_USE_NAMESPACE
+#include <cstddef>
+
+QT_BEGIN_NAMESPACE
static QByteArray wrapCCCrypt(CCOperation ccOp,
QSslKeyPrivate::Cipher cipher,
@@ -64,17 +66,23 @@ static QByteArray wrapCCCrypt(CCOperation ccOp,
blockSize = kCCBlockSizeRC2;
ccAlgorithm = kCCAlgorithmRC2;
break;
- };
+ case QSslKeyPrivate::Aes128Cbc:
+ case QSslKeyPrivate::Aes192Cbc:
+ case QSslKeyPrivate::Aes256Cbc:
+ blockSize = kCCBlockSizeAES128;
+ ccAlgorithm = kCCAlgorithmAES;
+ break;
+ }
size_t plainLength = 0;
QByteArray plain(data.size() + blockSize, 0);
CCCryptorStatus status = CCCrypt(
ccOp, ccAlgorithm, kCCOptionPKCS7Padding,
- key.constData(), key.size(),
+ key.constData(), std::size_t(key.size()),
iv.constData(),
- data.constData(), data.size(),
- plain.data(), plain.size(), &plainLength);
+ data.constData(), std::size_t(data.size()),
+ plain.data(), std::size_t(plain.size()), &plainLength);
if (status == kCCSuccess)
- return plain.left(plainLength);
+ return plain.left(int(plainLength));
return QByteArray();
}
@@ -87,3 +95,5 @@ QByteArray QSslKeyPrivate::encrypt(Cipher cipher, const QByteArray &data, const
{
return wrapCCCrypt(kCCEncrypt, cipher, data, key, iv);
}
+
+QT_END_NAMESPACE
diff --git a/src/network/ssl/qsslkey_openssl.cpp b/src/network/ssl/qsslkey_openssl.cpp
index 99c1a39c73..dfb80bd829 100644
--- a/src/network/ssl/qsslkey_openssl.cpp
+++ b/src/network/ssl/qsslkey_openssl.cpp
@@ -333,6 +333,14 @@ static QByteArray doCrypt(QSslKeyPrivate::Cipher cipher, const QByteArray &data,
type = q_EVP_rc2_cbc();
#endif
break;
+ case QSslKeyPrivate::Aes128Cbc:
+ case QSslKeyPrivate::Aes192Cbc:
+ case QSslKeyPrivate::Aes256Cbc:
+ // Just to avoid compiler warnings/errors. OpenSSL uses a different
+ // codepath when reading encrypted keys, and they all correctly
+ // deduce the cipher and know how to derive a key.
+ Q_UNREACHABLE();
+ break;
}
if (type == nullptr)
diff --git a/src/network/ssl/qsslkey_p.h b/src/network/ssl/qsslkey_p.h
index 06403b5479..1f2b59904a 100644
--- a/src/network/ssl/qsslkey_p.h
+++ b/src/network/ssl/qsslkey_p.h
@@ -105,7 +105,10 @@ public:
enum Cipher {
DesCbc,
DesEde3Cbc,
- Rc2Cbc
+ Rc2Cbc,
+ Aes128Cbc,
+ Aes192Cbc,
+ Aes256Cbc
};
Q_AUTOTEST_EXPORT static QByteArray decrypt(Cipher cipher, const QByteArray &data, const QByteArray &key, const QByteArray &iv);
diff --git a/src/network/ssl/qsslkey_qt.cpp b/src/network/ssl/qsslkey_qt.cpp
index 5ebd8ac3bd..61251b641b 100644
--- a/src/network/ssl/qsslkey_qt.cpp
+++ b/src/network/ssl/qsslkey_qt.cpp
@@ -124,6 +124,37 @@ static int numberOfBits(const QByteArray &modulus)
return bits;
}
+static QByteArray deriveAesKey(QSslKeyPrivate::Cipher cipher, const QByteArray &passPhrase, const QByteArray &iv)
+{
+ // This is somewhat simplified and shortened version of what OpenSSL does.
+ // See, for example, EVP_BytesToKey for the "algorithm" itself and elsewhere
+ // in their code for what they pass as arguments to EVP_BytesToKey when
+ // deriving encryption keys (when reading/writing pems files with encrypted
+ // keys).
+
+ Q_ASSERT(iv.size() >= 8);
+
+ QCryptographicHash hash(QCryptographicHash::Md5);
+
+ QByteArray data(passPhrase);
+ data.append(iv.data(), 8); // AKA PKCS5_SALT_LEN in OpenSSL.
+
+ hash.addData(data);
+
+ if (cipher == QSslKeyPrivate::Aes128Cbc)
+ return hash.result();
+
+ QByteArray key(hash.result());
+ hash.reset();
+ hash.addData(key);
+ hash.addData(data);
+
+ if (cipher == QSslKeyPrivate::Aes192Cbc)
+ return key.append(hash.result().constData(), 8);
+
+ return key.append(hash.result());
+}
+
static QByteArray deriveKey(QSslKeyPrivate::Cipher cipher, const QByteArray &passPhrase, const QByteArray &iv)
{
QByteArray key;
@@ -145,6 +176,10 @@ static QByteArray deriveKey(QSslKeyPrivate::Cipher cipher, const QByteArray &pas
case QSslKeyPrivate::Rc2Cbc:
key = hash.result();
break;
+ case QSslKeyPrivate::Aes128Cbc:
+ case QSslKeyPrivate::Aes192Cbc:
+ case QSslKeyPrivate::Aes256Cbc:
+ return deriveAesKey(cipher, passPhrase, iv);
}
return key;
}
@@ -378,6 +413,15 @@ void QSslKeyPrivate::decodePem(const QByteArray &pem, const QByteArray &passPhra
cipher = DesEde3Cbc;
} else if (dekInfo.first() == "RC2-CBC") {
cipher = Rc2Cbc;
+// TODO: Add SChannel version too!
+#ifdef QT_SECURETRANSPORT
+ } else if (dekInfo.first() == "AES-128-CBC") {
+ cipher = Aes128Cbc;
+ } else if (dekInfo.first() == "AES-192-CBC") {
+ cipher = Aes192Cbc;
+ } else if (dekInfo.first() == "AES-256-CBC") {
+ cipher = Aes256Cbc;
+#endif // QT_SECURETRANSPORT
} else {
clear(deepClear);
return;
@@ -554,6 +598,10 @@ static EncryptionData readPbes2(const QVector<QAsn1Element> &element, const QByt
return {};
break;
} // @todo(?): case (RC5 , AES)
+ case QSslKeyPrivate::Cipher::Aes128Cbc:
+ case QSslKeyPrivate::Cipher::Aes192Cbc:
+ case QSslKeyPrivate::Cipher::Aes256Cbc:
+ Q_UNREACHABLE();
}
if (Q_LIKELY(keyDerivationAlgorithm == PKCS5_PBKDF2_ENCRYPTION_OID)) {
diff --git a/src/network/ssl/qsslkey_schannel.cpp b/src/network/ssl/qsslkey_schannel.cpp
index 5694068860..9dfbc87e9a 100644
--- a/src/network/ssl/qsslkey_schannel.cpp
+++ b/src/network/ssl/qsslkey_schannel.cpp
@@ -57,6 +57,7 @@ const wchar_t *getName(QSslKeyPrivate::Cipher cipher)
return BCRYPT_3DES_ALGORITHM;
case QSslKeyPrivate::Cipher::Rc2Cbc:
return BCRYPT_RC2_ALGORITHM;
+ default:;
}
Q_UNREACHABLE();
}
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index cf8a472606..fa012866e6 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1209,12 +1209,21 @@ void QSslSocket::setPrivateKey(const QSslKey &key)
void QSslSocket::setPrivateKey(const QString &fileName, QSsl::KeyAlgorithm algorithm,
QSsl::EncodingFormat format, const QByteArray &passPhrase)
{
- Q_D(QSslSocket);
QFile file(fileName);
- if (file.open(QIODevice::ReadOnly)) {
- d->configuration.privateKey = QSslKey(file.readAll(), algorithm,
- format, QSsl::PrivateKey, passPhrase);
+ if (!file.open(QIODevice::ReadOnly)) {
+ qCWarning(lcSsl, "QSslSocket::setPrivateKey: Couldn't open file for reading");
+ return;
+ }
+
+ QSslKey key(file.readAll(), algorithm, format, QSsl::PrivateKey, passPhrase);
+ if (key.isNull()) {
+ qCWarning(lcSsl, "QSslSocket::setPrivateKey: "
+ "The specified file does not contain a valid key");
+ return;
}
+
+ Q_D(QSslSocket);
+ d->configuration.privateKey = key;
}
/*!
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index c48cd42360..6a8269b521 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -476,7 +476,8 @@ bool QSslSocketBackendPrivate::initSslContext()
{
Q_Q(QSslSocket);
- // If no external context was set (e.g. bei QHttpNetworkConnection) we will create a default context
+ // If no external context was set (e.g. by QHttpNetworkConnection) we will
+ // create a default context
if (!sslContextPointer) {
// create a deep copy of our configuration
QSslConfigurationPrivate *configurationCopy = new QSslConfigurationPrivate(configuration);
diff --git a/src/network/ssl/qsslsocket_openssl11_symbols_p.h b/src/network/ssl/qsslsocket_openssl11_symbols_p.h
index a44d00a830..9d0a14360d 100644
--- a/src/network/ssl/qsslsocket_openssl11_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl11_symbols_p.h
@@ -82,6 +82,7 @@ Q_AUTOTEST_EXPORT const BIO_METHOD *q_BIO_s_mem();
int q_DSA_bits(DSA *a);
int q_EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *c);
+Q_AUTOTEST_EXPORT int q_EVP_PKEY_up_ref(EVP_PKEY *a);
int q_EVP_PKEY_base_id(EVP_PKEY *a);
int q_RSA_bits(RSA *a);
Q_AUTOTEST_EXPORT int q_OPENSSL_sk_num(OPENSSL_STACK *a);
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index aa1dc681e0..f136c92a65 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -150,6 +150,7 @@ DEFINEFUNC(BIO *, BIO_new, const BIO_METHOD *a, a, return nullptr, return)
DEFINEFUNC(const BIO_METHOD *, BIO_s_mem, void, DUMMYARG, return nullptr, return)
DEFINEFUNC2(int, BN_is_word, BIGNUM *a, a, BN_ULONG w, w, return 0, return)
DEFINEFUNC(int, EVP_CIPHER_CTX_reset, EVP_CIPHER_CTX *c, c, return 0, return)
+DEFINEFUNC(int, EVP_PKEY_up_ref, EVP_PKEY *a, a, return 0, return)
DEFINEFUNC(int, EVP_PKEY_base_id, EVP_PKEY *a, a, return NID_undef, return)
DEFINEFUNC(int, RSA_bits, RSA *a, a, return 0, return)
DEFINEFUNC(int, DSA_bits, DSA *a, a, return 0, return)
@@ -366,6 +367,7 @@ DEFINEFUNC2(int, EVP_PKEY_set1_DH, EVP_PKEY *a, a, DH *b, b, return -1, return)
#ifndef OPENSSL_NO_EC
DEFINEFUNC2(int, EVP_PKEY_set1_EC_KEY, EVP_PKEY *a, a, EC_KEY *b, b, return -1, return)
#endif
+DEFINEFUNC2(int, EVP_PKEY_cmp, const EVP_PKEY *a, a, const EVP_PKEY *b, b, return -1, return)
DEFINEFUNC(void, EVP_PKEY_free, EVP_PKEY *a, a, return, DUMMYARG)
DEFINEFUNC(DSA *, EVP_PKEY_get1_DSA, EVP_PKEY *a, a, return nullptr, return)
DEFINEFUNC(RSA *, EVP_PKEY_get1_RSA, EVP_PKEY *a, a, return nullptr, return)
@@ -955,6 +957,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(OPENSSL_init_crypto)
RESOLVEFUNC(ASN1_STRING_get0_data)
RESOLVEFUNC(EVP_CIPHER_CTX_reset)
+ RESOLVEFUNC(EVP_PKEY_up_ref)
RESOLVEFUNC(EVP_PKEY_base_id)
RESOLVEFUNC(RSA_bits)
RESOLVEFUNC(OPENSSL_sk_new_null)
@@ -1184,6 +1187,7 @@ bool q_resolveOpenSslSymbols()
#ifndef OPENSSL_NO_EC
RESOLVEFUNC(EVP_PKEY_set1_EC_KEY)
#endif
+ RESOLVEFUNC(EVP_PKEY_cmp)
RESOLVEFUNC(EVP_PKEY_free)
RESOLVEFUNC(EVP_PKEY_get1_DSA)
RESOLVEFUNC(EVP_PKEY_get1_RSA)
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index e09820b2f2..59b6e53940 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -284,11 +284,12 @@ const EVP_CIPHER *q_EVP_rc2_cbc();
Q_AUTOTEST_EXPORT const EVP_MD *q_EVP_sha1();
int q_EVP_PKEY_assign(EVP_PKEY *a, int b, char *c);
Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_RSA(EVP_PKEY *a, RSA *b);
-int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b);
-int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b);
+Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_DSA(EVP_PKEY *a, DSA *b);
+Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_DH(EVP_PKEY *a, DH *b);
#ifndef OPENSSL_NO_EC
-int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b);
+Q_AUTOTEST_EXPORT int q_EVP_PKEY_set1_EC_KEY(EVP_PKEY *a, EC_KEY *b);
#endif
+Q_AUTOTEST_EXPORT int q_EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
Q_AUTOTEST_EXPORT void q_EVP_PKEY_free(EVP_PKEY *a);
RSA *q_EVP_PKEY_get1_RSA(EVP_PKEY *a);
DSA *q_EVP_PKEY_get1_DSA(EVP_PKEY *a);
diff --git a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h
index c3d3070210..31a79dbc6c 100644
--- a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h
+++ b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h
@@ -131,6 +131,12 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
#endif
+#ifndef EGL_EXT_stream_acquire_mode
+#define EGL_EXT_stream_acquire_mode 1
+#define EGL_CONSUMER_AUTO_ACQUIRE_EXT 0x332B
+#define EGL_RESOURCE_BUSY_EXT 0x3353
+#endif
+
#ifndef EGL_EXT_platform_device
#define EGL_PLATFORM_DEVICE_EXT 0x313F
#endif
@@ -156,6 +162,11 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREATTRIBNVPROC) (EGLDi
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEATTRIBNVPROC) (EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib *attrib_list);
#endif
+#ifndef EGL_NV_output_drm_flip_event
+#define EGL_NV_output_drm_flip_event 1
+#define EGL_DRM_FLIP_EVENT_DATA_NV 0x333E
+#endif
+
QT_BEGIN_NAMESPACE
class QEGLStreamConvenience
diff --git a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
index 381db1ed12..40db7dbac7 100644
--- a/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
+++ b/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp
@@ -121,13 +121,12 @@ class QtFreetypeData
{
public:
QtFreetypeData()
- : library(0), hasPatentFreeLcdRendering(false)
+ : library(0)
{ }
~QtFreetypeData();
FT_Library library;
QHash<QFontEngine::FaceId, QFreetypeFace *> faces;
- bool hasPatentFreeLcdRendering;
};
QtFreetypeData::~QtFreetypeData()
@@ -153,11 +152,6 @@ QtFreetypeData *qt_getFreetypeData()
FT_Bool no_darkening = false;
FT_Property_Set(freetypeData->library, "cff", "no-stem-darkening", &no_darkening);
#endif
- // FreeType has since 2.8.1 a patent free alternative to LCD-filtering.
- FT_Int amajor, aminor = 0, apatch = 0;
- FT_Library_Version(freetypeData->library, &amajor, &aminor, &apatch);
- if (QT_VERSION_CHECK(amajor, aminor, apatch) >= QT_VERSION_CHECK(2, 8, 1))
- freetypeData->hasPatentFreeLcdRendering = true;
}
return freetypeData;
}
@@ -561,26 +555,7 @@ QFontEngineFT::Glyph::~Glyph()
delete [] data;
}
-struct LcdFilterDummy
-{
- static inline void filterPixel(uchar &, uchar &, uchar &)
- {}
-};
-
-struct LcdFilterLegacy
-{
- static inline void filterPixel(uchar &red, uchar &green, uchar &blue)
- {
- uint r = red, g = green, b = blue;
- // intra-pixel filter used by the legacy filter (adopted from _ft_lcd_filter_legacy)
- red = (r * uint(65538 * 9/13) + g * uint(65538 * 1/6) + b * uint(65538 * 1/13)) / 65536;
- green = (r * uint(65538 * 3/13) + g * uint(65538 * 4/6) + b * uint(65538 * 3/13)) / 65536;
- blue = (r * uint(65538 * 1/13) + g * uint(65538 * 1/6) + b * uint(65538 * 9/13)) / 65536;
- }
-};
-
-template <typename LcdFilter>
-static void convertRGBToARGB_helper(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr)
+static inline void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr)
{
const int offs = bgr ? -1 : 1;
const int w = width * 3;
@@ -590,7 +565,6 @@ static void convertRGBToARGB_helper(const uchar *src, uint *dst, int width, int
uchar red = src[x + 1 - offs];
uchar green = src[x + 1];
uchar blue = src[x + 1 + offs];
- LcdFilter::filterPixel(red, green, blue);
*dd++ = (0xFFU << 24) | (red << 16) | (green << 8) | blue;
}
dst += width;
@@ -598,16 +572,7 @@ static void convertRGBToARGB_helper(const uchar *src, uint *dst, int width, int
}
}
-static inline void convertRGBToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter)
-{
- if (!legacyFilter)
- convertRGBToARGB_helper<LcdFilterDummy>(src, dst, width, height, src_pitch, bgr);
- else
- convertRGBToARGB_helper<LcdFilterLegacy>(src, dst, width, height, src_pitch, bgr);
-}
-
-template <typename LcdFilter>
-static void convertRGBToARGB_V_helper(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr)
+static inline void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr)
{
const int offs = bgr ? -src_pitch : src_pitch;
while (height--) {
@@ -615,54 +580,12 @@ static void convertRGBToARGB_V_helper(const uchar *src, uint *dst, int width, in
uchar red = src[x + src_pitch - offs];
uchar green = src[x + src_pitch];
uchar blue = src[x + src_pitch + offs];
- LcdFilter::filterPixel(red, green, blue);
*dst++ = (0XFFU << 24) | (red << 16) | (green << 8) | blue;
}
src += 3*src_pitch;
}
}
-static inline void convertRGBToARGB_V(const uchar *src, uint *dst, int width, int height, int src_pitch, bool bgr, bool legacyFilter)
-{
- if (!legacyFilter)
- convertRGBToARGB_V_helper<LcdFilterDummy>(src, dst, width, height, src_pitch, bgr);
- else
- convertRGBToARGB_V_helper<LcdFilterLegacy>(src, dst, width, height, src_pitch, bgr);
-}
-
-static inline void convertGRAYToARGB(const uchar *src, uint *dst, int width, int height, int src_pitch)
-{
- while (height--) {
- const uchar *p = src;
- const uchar * const e = p + width;
- while (p < e) {
- uchar gray = *p++;
- *dst++ = (0xFFU << 24) | (gray << 16) | (gray << 8) | gray;
- }
- src += src_pitch;
- }
-}
-
-static void convoluteBitmap(const uchar *src, uchar *dst, int width, int height, int pitch)
-{
- // convolute the bitmap with a triangle filter to get rid of color fringes
- // If we take account for a gamma value of 2, we end up with
- // weights of 1, 4, 9, 4, 1. We use an approximation of 1, 3, 8, 3, 1 here,
- // as this nicely sums up to 16 :)
- int h = height;
- while (h--) {
- dst[0] = dst[1] = 0;
- //
- for (int x = 2; x < width - 2; ++x) {
- uint sum = src[x-2] + 3*src[x-1] + 8*src[x] + 3*src[x+1] + src[x+2];
- dst[x] = (uchar) (sum >> 4);
- }
- dst[width - 2] = dst[width - 1] = 0;
- src += pitch;
- dst += pitch;
- }
-}
-
static QFontEngine::SubpixelAntialiasingType subpixelAntialiasingTypeHint()
{
static int type = -1;
@@ -1153,196 +1076,97 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
int glyph_buffer_size = 0;
QScopedArrayPointer<uchar> glyph_buffer;
- bool useFreetypeRenderGlyph = false;
- if (slot->format == FT_GLYPH_FORMAT_OUTLINE && (hsubpixel || vfactor != 1)) {
- err = FT_Library_SetLcdFilter(slot->library, (FT_LcdFilter)lcdFilterType);
- // We use FT_Render_Glyph if freetype has support for lcd-filtering
- // or is version 2.8.1 or higher and can do without.
- if (err == FT_Err_Ok || qt_getFreetypeData()->hasPatentFreeLcdRendering)
- useFreetypeRenderGlyph = true;
+ FT_Render_Mode renderMode = (default_hint_style == HintLight) ? FT_RENDER_MODE_LIGHT : FT_RENDER_MODE_NORMAL;
+ switch (format) {
+ case Format_Mono:
+ renderMode = FT_RENDER_MODE_MONO;
+ break;
+ case Format_A32:
+ Q_ASSERT(hsubpixel || vfactor != 1);
+ renderMode = hsubpixel ? FT_RENDER_MODE_LCD : FT_RENDER_MODE_LCD_V;
+ break;
+ case Format_A8:
+ case Format_ARGB:
+ break;
+ default:
+ Q_UNREACHABLE();
}
- if (useFreetypeRenderGlyph) {
- err = FT_Render_Glyph(slot, hsubpixel ? FT_RENDER_MODE_LCD : FT_RENDER_MODE_LCD_V);
-
- if (err != FT_Err_Ok)
- qWarning("render glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
-
- FT_Library_SetLcdFilter(slot->library, FT_LCD_FILTER_NONE);
+ FT_Library_SetLcdFilter(slot->library, (FT_LcdFilter)lcdFilterType);
- info.height = slot->bitmap.rows / vfactor;
- info.width = hsubpixel ? slot->bitmap.width / 3 : slot->bitmap.width;
- info.x = slot->bitmap_left;
- info.y = slot->bitmap_top;
+ err = FT_Render_Glyph(slot, renderMode);
+ if (err != FT_Err_Ok)
+ qWarning("render glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
- glyph_buffer_size = info.width * info.height * 4;
- glyph_buffer.reset(new uchar[glyph_buffer_size]);
+ FT_Library_SetLcdFilter(slot->library, FT_LCD_FILTER_NONE);
- if (hsubpixel)
- convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB, false);
- else if (vfactor != 1)
- convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB, false);
- } else {
- int left = slot->metrics.horiBearingX;
- int right = slot->metrics.horiBearingX + slot->metrics.width;
- int top = slot->metrics.horiBearingY;
- int bottom = slot->metrics.horiBearingY - slot->metrics.height;
- if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP)
- transformBoundingBox(&left, &top, &right, &bottom, &matrix);
- left = FLOOR(left);
- right = CEIL(right);
- bottom = FLOOR(bottom);
- top = CEIL(top);
-
- int hpixels = TRUNC(right - left);
- // subpixel position requires one more pixel
- if (subPixelPosition > 0 && format != Format_Mono)
- hpixels++;
-
- if (hsubpixel)
- hpixels = hpixels*3 + 8;
- info.width = hpixels;
- info.height = TRUNC(top - bottom);
- info.x = TRUNC(left);
- info.y = TRUNC(top);
- if (hsubpixel) {
- info.width /= 3;
- info.x -= 1;
- }
-
- // If any of the metrics are too large to fit, don't cache them
- if (areMetricsTooLarge(info))
- return 0;
+ info.height = slot->bitmap.rows;
+ info.width = slot->bitmap.width;
+ info.x = slot->bitmap_left;
+ info.y = slot->bitmap_top;
+ if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD)
+ info.width = info.width / 3;
+ if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V)
+ info.height = info.height / vfactor;
int pitch = (format == Format_Mono ? ((info.width + 31) & ~31) >> 3 :
(format == Format_A8 ? (info.width + 3) & ~3 : info.width * 4));
- if (glyph_buffer_size < pitch * info.height) {
- glyph_buffer_size = pitch * info.height;
- glyph_buffer.reset(new uchar[glyph_buffer_size]);
- memset(glyph_buffer.data(), 0, glyph_buffer_size);
- }
- if (slot->format == FT_GLYPH_FORMAT_OUTLINE) {
- FT_Bitmap bitmap;
- bitmap.rows = info.height*vfactor;
- bitmap.width = hpixels;
- bitmap.pitch = format == Format_Mono ? (((info.width + 31) & ~31) >> 3) : ((bitmap.width + 3) & ~3);
- int bitmap_buffer_size = bitmap.rows * bitmap.pitch;
- if (!hsubpixel && vfactor == 1 && format != Format_A32) {
- Q_ASSERT(glyph_buffer_size <= bitmap_buffer_size);
- bitmap.buffer = glyph_buffer.data();
- } else {
- bitmap.buffer = new uchar[bitmap_buffer_size];
- memset(bitmap.buffer, 0, bitmap_buffer_size);
- }
- bitmap.pixel_mode = format == Format_Mono ? FT_PIXEL_MODE_MONO : FT_PIXEL_MODE_GRAY;
- FT_Matrix matrix;
- matrix.xx = (hsubpixel ? 3 : 1) << 16;
- matrix.yy = vfactor << 16;
- matrix.yx = matrix.xy = 0;
-
- FT_Outline_Transform(&slot->outline, &matrix);
- FT_Outline_Translate (&slot->outline, (hsubpixel ? -3*left +(4<<6) : -left), -bottom*vfactor);
- FT_Outline_Get_Bitmap(slot->library, &slot->outline, &bitmap);
- if (hsubpixel) {
- Q_ASSERT (bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);
- Q_ASSERT(antialias);
- uchar *convoluted = new uchar[bitmap_buffer_size];
- bool useLegacyLcdFilter = false;
- useLegacyLcdFilter = (lcdFilterType == FT_LCD_FILTER_LEGACY);
- uchar *buffer = bitmap.buffer;
- if (!useLegacyLcdFilter) {
- convoluteBitmap(bitmap.buffer, convoluted, bitmap.width, info.height, bitmap.pitch);
- buffer = convoluted;
- }
- convertRGBToARGB(buffer + 1, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch, subpixelType != Subpixel_RGB, useLegacyLcdFilter);
- delete [] convoluted;
- } else if (vfactor != 1) {
- convertRGBToARGB_V(bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch, subpixelType != Subpixel_VRGB, true);
- } else if (format == Format_A32 && bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) {
- convertGRAYToARGB(bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, bitmap.pitch);
- }
+ glyph_buffer_size = info.height * pitch;
+ glyph_buffer.reset(new uchar[glyph_buffer_size]);
- if (bitmap.buffer != glyph_buffer.data())
- delete [] bitmap.buffer;
- } else if (slot->format == FT_GLYPH_FORMAT_BITMAP) {
-#if ((FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100) >= 20500)
- Q_ASSERT(slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO || slot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA);
-#else
- Q_ASSERT(slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO);
-#endif
+ if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
+ Q_ASSERT(format == Format_Mono);
uchar *src = slot->bitmap.buffer;
uchar *dst = glyph_buffer.data();
int h = slot->bitmap.rows;
- if (format == Format_Mono) {
- int bytes = ((info.width + 7) & ~7) >> 3;
- while (h--) {
- memcpy (dst, src, bytes);
- dst += pitch;
- src += slot->bitmap.pitch;
- }
- } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
- if (hsubpixel) {
- while (h--) {
- uint *dd = (uint *)dst;
- *dd++ = 0;
- for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++) {
- uint a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffff : 0x000000);
- *dd++ = a;
- }
- *dd++ = 0;
- dst += pitch;
- src += slot->bitmap.pitch;
- }
- } else if (vfactor != 1) {
- while (h--) {
- uint *dd = (uint *)dst;
- for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++) {
- uint a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffff : 0x000000);
- *dd++ = a;
- }
- dst += pitch;
- src += slot->bitmap.pitch;
- }
- } else {
- while (h--) {
- for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++) {
- unsigned char a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xff : 0x00);
- dst[x] = a;
- }
- dst += pitch;
- src += slot->bitmap.pitch;
- }
- }
+
+ int bytes = ((info.width + 7) & ~7) >> 3;
+ while (h--) {
+ memcpy (dst, src, bytes);
+ dst += pitch;
+ src += slot->bitmap.pitch;
}
-#if ((FREETYPE_MAJOR*10000 + FREETYPE_MINOR*100) >= 20500)
- else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA)
- {
- while (h--) {
+ } else if (slot->bitmap.pixel_mode == 7 /*FT_PIXEL_MODE_BGRA*/) {
+ Q_ASSERT(format == Format_ARGB);
+ uchar *src = slot->bitmap.buffer;
+ uchar *dst = glyph_buffer.data();
+ int h = slot->bitmap.rows;
+ while (h--) {
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- const quint32 *srcPixel = (const quint32 *)src;
- quint32 *dstPixel = (quint32 *)dst;
- for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++, srcPixel++, dstPixel++) {
- const quint32 pixel = *srcPixel;
- *dstPixel = qbswap(pixel);
- }
+ const quint32 *srcPixel = (const quint32 *)src;
+ quint32 *dstPixel = (quint32 *)dst;
+ for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++, srcPixel++, dstPixel++) {
+ const quint32 pixel = *srcPixel;
+ *dstPixel = qbswap(pixel);
+ }
#else
- memcpy(dst, src, slot->bitmap.width * 4);
+ memcpy(dst, src, slot->bitmap.width * 4);
#endif
- dst += slot->bitmap.pitch;
- src += slot->bitmap.pitch;
- }
- info.width = info.linearAdvance = info.xOff = slot->bitmap.width;
- info.height = slot->bitmap.rows;
- info.x = slot->bitmap_left;
- info.y = slot->bitmap_top;
+ dst += slot->bitmap.pitch;
+ src += slot->bitmap.pitch;
}
-#endif
+ info.linearAdvance = info.xOff = slot->bitmap.width;
+ } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY) {
+ Q_ASSERT(format == Format_A8);
+ uchar *src = slot->bitmap.buffer;
+ uchar *dst = glyph_buffer.data();
+ int h = slot->bitmap.rows;
+ int bytes = info.width;
+ while (h--) {
+ memcpy (dst, src, bytes);
+ dst += pitch;
+ src += slot->bitmap.pitch;
+ }
+ } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD) {
+ Q_ASSERT(format == Format_A32);
+ convertRGBToARGB(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_RGB);
+ } else if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V) {
+ Q_ASSERT(format == Format_A32);
+ convertRGBToARGB_V(slot->bitmap.buffer, (uint *)glyph_buffer.data(), info.width, info.height, slot->bitmap.pitch, subpixelType != Subpixel_VRGB);
} else {
- qWarning("QFontEngine: Glyph neither outline nor bitmap format=%d", slot->format);
+ qWarning("QFontEngine: Glyph rendered in unknown pixel_mode=%d", slot->bitmap.pixel_mode);
return 0;
}
- }
-
if (!g) {
g = new Glyph;
diff --git a/src/platformsupport/kmsconvenience/qkmsdevice.cpp b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
index ef81f6162d..4b27522976 100644
--- a/src/platformsupport/kmsconvenience/qkmsdevice.cpp
+++ b/src/platformsupport/kmsconvenience/qkmsdevice.cpp
@@ -777,9 +777,7 @@ void QKmsDevice::discoverPlanes()
for (int i = 0; i < countFormats; ++i) {
uint32_t f = drmplane->formats[i];
plane.supportedFormats.append(f);
- QString s;
- s.sprintf("%c%c%c%c ", f, f >> 8, f >> 16, f >> 24);
- formatStr += s;
+ formatStr += QString::asprintf("%c%c%c%c ", f, f >> 8, f >> 16, f >> 24);
}
qCDebug(qLcKmsDebug, "plane %d: id = %u countFormats = %d possibleCrtcs = 0x%x supported formats = %s",
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
index 1003812767..7b3f9b624a 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
@@ -172,15 +172,9 @@ QStringList QGenericUnixTheme::xdgIconThemePaths()
if (homeIconDir.isDir())
paths.prepend(homeIconDir.absoluteFilePath());
- QString xdgDirString = QFile::decodeName(qgetenv("XDG_DATA_DIRS"));
- if (xdgDirString.isEmpty())
- xdgDirString = QLatin1String("/usr/local/share/:/usr/share/");
- const auto xdgDirs = xdgDirString.splitRef(QLatin1Char(':'));
- for (const QStringRef &xdgDir : xdgDirs) {
- const QFileInfo xdgIconsDir(xdgDir + QLatin1String("/icons"));
- if (xdgIconsDir.isDir())
- paths.append(xdgIconsDir.absoluteFilePath());
- }
+ paths.append(QStandardPaths::locateAll(QStandardPaths::GenericDataLocation,
+ QStringLiteral("icons"),
+ QStandardPaths::LocateDirectory));
return paths;
}
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
index 54fe857908..9d5ccc8a3d 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
@@ -40,10 +40,14 @@
#include "qjpeghandler_p.h"
#include <qimage.h>
+#include <qcolorspace.h>
+#include <qcolortransform.h>
+#include <qdebug.h>
#include <qvariant.h>
#include <qvector.h>
#include <qbuffer.h>
#include <qmath.h>
+#include <private/qicc_p.h>
#include <private/qsimd_p.h>
#include <private/qimage_p.h> // for qt_getImageText
@@ -725,6 +729,7 @@ public:
QRect clipRect;
QString description;
QStringList readTexts;
+ QByteArray iccProfile;
struct jpeg_decompress_struct info;
struct my_jpeg_source_mgr * iod_src;
@@ -887,6 +892,7 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device)
if (!setjmp(err.setjmp_buffer)) {
jpeg_save_markers(&info, JPEG_COM, 0xFFFF);
jpeg_save_markers(&info, JPEG_APP0 + 1, 0xFFFF); // Exif uses APP1 marker
+ jpeg_save_markers(&info, JPEG_APP0 + 2, 0xFFFF); // ICC uses APP2 marker
(void) jpeg_read_header(&info, TRUE);
@@ -919,6 +925,10 @@ bool QJpegHandlerPrivate::readJpegHeader(QIODevice *device)
readTexts.append(value);
} else if (marker->marker == JPEG_APP0 + 1) {
exifData.append((const char*)marker->data, marker->data_length);
+ } else if (marker->marker == JPEG_APP0 + 2) {
+ if (marker->data_length > 128 + 4 + 14 && strcmp((const char *)marker->data, "ICC_PROFILE") == 0) {
+ iccProfile.append((const char*)marker->data + 14, marker->data_length - 14);
+ }
}
}
@@ -954,6 +964,9 @@ bool QJpegHandlerPrivate::read(QImage *image)
for (int i = 0; i < readTexts.size()-1; i+=2)
image->setText(readTexts.at(i), readTexts.at(i+1));
+ if (!iccProfile.isEmpty())
+ image->setColorSpace(QColorSpace::fromIccProfile(iccProfile));
+
state = ReadingEnd;
return true;
}
@@ -962,7 +975,6 @@ bool QJpegHandlerPrivate::read(QImage *image)
}
return false;
-
}
Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, const uchar *src, int len);
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
index ab39af6b80..9f4c9f5703 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
@@ -114,14 +114,18 @@ public:
: QEglFSWindow(w)
, m_integration(integration)
, m_egl_stream(EGL_NO_STREAM_KHR)
+ , m_framePending(false)
{ }
void invalidateSurface() override;
void resetSurface() override;
+ void flip();
+ static void pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data);
const QEglFSKmsEglDeviceIntegration *m_integration;
EGLStreamKHR m_egl_stream;
EGLint m_latency;
+ bool m_framePending;
};
void QEglFSKmsEglDeviceWindow::invalidateSurface()
@@ -142,6 +146,9 @@ void QEglFSKmsEglDeviceWindow::resetSurface()
streamAttribs[streamAttribCount++] = EGL_STREAM_FIFO_LENGTH_KHR;
streamAttribs[streamAttribCount++] = fifoLength;
}
+
+ streamAttribs[streamAttribCount++] = EGL_CONSUMER_AUTO_ACQUIRE_EXT;
+ streamAttribs[streamAttribCount++] = EGL_FALSE;
streamAttribs[streamAttribCount++] = EGL_NONE;
m_egl_stream = m_integration->m_funcs->create_stream(display, streamAttribs);
@@ -239,6 +246,49 @@ void QEglFSKmsEglDeviceWindow::resetSurface()
qCDebug(qLcEglfsKmsDebug, "Created stream producer surface %p", m_surface);
}
+void QEglFSKmsEglDeviceWindow::flip()
+{
+ EGLDisplay display = screen()->display();
+
+ EGLAttrib acquire_attribs[3] = { EGL_NONE };
+
+ acquire_attribs[0] = EGL_DRM_FLIP_EVENT_DATA_NV;
+ acquire_attribs[1] = (EGLAttrib)this;
+ acquire_attribs[2] = EGL_NONE;
+
+ if (m_egl_stream != EGL_NO_STREAM_KHR)
+ if (!m_integration->m_funcs->acquire_stream_attrib_nv(display, m_egl_stream, acquire_attribs))
+ qWarning("eglStreamConsumerAcquireAttribNV failed: eglError: %x", eglGetError());
+
+ m_framePending = true;
+
+ while (m_framePending) {
+ drmEventContext drmEvent;
+ memset(&drmEvent, 0, sizeof(drmEvent));
+ drmEvent.version = 3;
+ drmEvent.vblank_handler = nullptr;
+ drmEvent.page_flip_handler = pageFlipHandler;
+ drmHandleEvent(m_integration->m_device->fd(), &drmEvent);
+ }
+}
+
+void QEglFSKmsEglDeviceWindow::pageFlipHandler(int fd, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+{
+ Q_UNUSED(fd);
+ Q_UNUSED(sequence);
+ Q_UNUSED(tv_sec);
+ Q_UNUSED(tv_usec);
+
+ QEglFSKmsEglDeviceWindow *window = static_cast<QEglFSKmsEglDeviceWindow*>(user_data);
+ window->m_framePending = false;
+}
+
+void QEglFSKmsEglDeviceIntegration::presentBuffer(QPlatformSurface *surface)
+{
+ QEglFSKmsEglDeviceWindow *eglWindow = static_cast<QEglFSKmsEglDeviceWindow*>(surface);
+ eglWindow->flip();
+}
+
QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const
{
QEglFSKmsEglDeviceWindow *eglWindow = new QEglFSKmsEglDeviceWindow(window, this);
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
index 5819d82ebf..a5697ec831 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
@@ -62,6 +62,8 @@ public:
bool supportsPBuffers() const override;
QEglFSWindow *createWindow(QWindow *window) const override;
+ void presentBuffer(QPlatformSurface *surface) override;
+
EGLDeviceEXT eglDevice() const { return m_egl_device; }
protected:
diff --git a/src/plugins/platforms/mirclient/mirclient.json b/src/plugins/platforms/mirclient/mirclient.json
deleted file mode 100644
index c31558a2f1..0000000000
--- a/src/plugins/platforms/mirclient/mirclient.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "Keys": [ "mirclient" ]
-}
diff --git a/src/plugins/platforms/mirclient/mirclient.pro b/src/plugins/platforms/mirclient/mirclient.pro
deleted file mode 100644
index d9eb069200..0000000000
--- a/src/plugins/platforms/mirclient/mirclient.pro
+++ /dev/null
@@ -1,61 +0,0 @@
-TARGET = qmirclient
-
-QT += \
- core-private gui-private dbus \
- theme_support-private eventdispatcher_support-private \
- fontdatabase_support-private egl_support-private
-
-qtHaveModule(linuxaccessibility_support-private): \
- QT += linuxaccessibility_support-private
-
-DEFINES += MESA_EGL_NO_X11_HEADERS
-# CONFIG += c++11 # only enables C++0x
-QMAKE_CXXFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden -std=c++11 -Werror -Wall
-QMAKE_LFLAGS += -std=c++11 -Wl,-no-undefined
-
-QMAKE_USE_PRIVATE += mirclient
-
-SOURCES = \
- qmirclientappstatecontroller.cpp \
- qmirclientbackingstore.cpp \
- qmirclientclipboard.cpp \
- qmirclientcursor.cpp \
- qmirclientdebugextension.cpp \
- qmirclientdesktopwindow.cpp \
- qmirclientglcontext.cpp \
- qmirclientinput.cpp \
- qmirclientintegration.cpp \
- qmirclientnativeinterface.cpp \
- qmirclientplatformservices.cpp \
- qmirclientplugin.cpp \
- qmirclientscreen.cpp \
- qmirclientscreenobserver.cpp \
- qmirclienttheme.cpp \
- qmirclientwindow.cpp
-
-HEADERS = \
- qmirclientappstatecontroller.h \
- qmirclientbackingstore.h \
- qmirclientclipboard.h \
- qmirclientcursor.h \
- qmirclientdebugextension.h \
- qmirclientdesktopwindow.h \
- qmirclientglcontext.h \
- qmirclientinput.h \
- qmirclientintegration.h \
- qmirclientlogging.h \
- qmirclientnativeinterface.h \
- qmirclientorientationchangeevent_p.h \
- qmirclientplatformservices.h \
- qmirclientplugin.h \
- qmirclientscreen.h \
- qmirclientscreenobserver.h \
- qmirclienttheme.h \
- qmirclientwindow.h
-
-QMAKE_USE_PRIVATE += xkbcommon
-
-PLUGIN_TYPE = platforms
-PLUGIN_CLASS_NAME = MirServerIntegrationPlugin
-!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = -
-load(qt_plugin)
diff --git a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp b/src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp
deleted file mode 100644
index 69fc9b7aa7..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qmirclientappstatecontroller.h"
-
-#include <qpa/qwindowsysteminterface.h>
-
-/*
- * QMirClientAppStateController - updates Qt's QApplication::applicationState property.
- *
- * Tries to avoid active-inactive-active invocations using a timer. The rapid state
- * change can confuse some applications.
- */
-
-QMirClientAppStateController::QMirClientAppStateController()
- : m_suspended(false)
- , m_lastActive(true)
-{
- m_inactiveTimer.setSingleShot(true);
- m_inactiveTimer.setInterval(10);
- QObject::connect(&m_inactiveTimer, &QTimer::timeout, []()
- {
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
- });
-}
-
-void QMirClientAppStateController::setSuspended()
-{
- m_inactiveTimer.stop();
- if (!m_suspended) {
- m_suspended = true;
-
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
- }
-}
-
-void QMirClientAppStateController::setResumed()
-{
- m_inactiveTimer.stop();
- if (m_suspended) {
- m_suspended = false;
-
- if (m_lastActive) {
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
- } else {
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
- }
- }
-}
-
-void QMirClientAppStateController::setWindowFocused(bool focused)
-{
- if (m_suspended) {
- return;
- }
-
- if (focused) {
- m_inactiveTimer.stop();
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
- } else {
- m_inactiveTimer.start();
- }
-
- m_lastActive = focused;
-}
diff --git a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.h b/src/plugins/platforms/mirclient/qmirclientappstatecontroller.h
deleted file mode 100644
index b3aa0022d9..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTAPPSTATECONTROLLER_H
-#define QMIRCLIENTAPPSTATECONTROLLER_H
-
-#include <QTimer>
-
-class QMirClientAppStateController
-{
-public:
- QMirClientAppStateController();
-
- void setSuspended();
- void setResumed();
-
- void setWindowFocused(bool focused);
-
-private:
- bool m_suspended;
- bool m_lastActive;
- QTimer m_inactiveTimer;
-};
-
-#endif // QMIRCLIENTAPPSTATECONTROLLER_H
diff --git a/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp b/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp
deleted file mode 100644
index 51363619d9..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qmirclientbackingstore.h"
-#include "qmirclientlogging.h"
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLTexture>
-#include <QtGui/QMatrix4x4>
-#include <QtGui/qopengltextureblitter.h>
-#include <QtGui/qopenglfunctions.h>
-
-QMirClientBackingStore::QMirClientBackingStore(QWindow* window)
- : QPlatformBackingStore(window)
- , mContext(new QOpenGLContext)
- , mTexture(new QOpenGLTexture(QOpenGLTexture::Target2D))
- , mBlitter(new QOpenGLTextureBlitter)
-{
- mContext->setFormat(window->requestedFormat());
- mContext->setScreen(window->screen());
- mContext->create();
-
- window->setSurfaceType(QSurface::OpenGLSurface);
-}
-
-QMirClientBackingStore::~QMirClientBackingStore()
-{
- mContext->makeCurrent(window()); // needed as QOpenGLTexture destructor assumes current context
-}
-
-void QMirClientBackingStore::flush(QWindow* window, const QRegion& region, const QPoint& offset)
-{
- Q_UNUSED(region);
- Q_UNUSED(offset);
- mContext->makeCurrent(window);
- glViewport(0, 0, window->width(), window->height());
-
- updateTexture();
-
- if (!mBlitter->isCreated())
- mBlitter->create();
-
- mBlitter->bind();
- mBlitter->blit(mTexture->textureId(), QMatrix4x4(), QOpenGLTextureBlitter::OriginTopLeft);
- mBlitter->release();
-
- mContext->swapBuffers(window);
-}
-
-void QMirClientBackingStore::updateTexture()
-{
- if (mDirty.isNull())
- return;
-
- if (!mTexture->isCreated()) {
- mTexture->setMinificationFilter(QOpenGLTexture::Nearest);
- mTexture->setMagnificationFilter(QOpenGLTexture::Nearest);
- mTexture->setWrapMode(QOpenGLTexture::ClampToEdge);
- mTexture->setData(mImage, QOpenGLTexture::DontGenerateMipMaps);
- mTexture->create();
- }
- mTexture->bind();
-
- QRegion fixed;
- QRect imageRect = mImage.rect();
-
- for (const QRect &rect : mDirty) {
- // intersect with image rect to be sure
- QRect r = imageRect & rect;
-
- // if the rect is wide enough it is cheaper to just extend it instead of doing an image copy
- if (r.width() >= imageRect.width() / 2) {
- r.setX(0);
- r.setWidth(imageRect.width());
- }
-
- fixed |= r;
- }
-
- for (const QRect &rect : fixed) {
- // if the sub-rect is full-width we can pass the image data directly to
- // OpenGL instead of copying, since there is no gap between scanlines
- if (rect.width() == imageRect.width()) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
- mImage.constScanLine(rect.y()));
- } else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
- mImage.copy(rect).constBits());
- }
- }
- /* End of code taken from QEGLPlatformBackingStore */
-
- mDirty = QRegion();
-}
-
-
-void QMirClientBackingStore::beginPaint(const QRegion& region)
-{
- mDirty |= region;
-}
-
-void QMirClientBackingStore::resize(const QSize& size, const QRegion& /*staticContents*/)
-{
- mImage = QImage(size, QImage::Format_RGBA8888);
-
- mContext->makeCurrent(window());
-
- if (mTexture->isCreated())
- mTexture->destroy();
-}
-
-QPaintDevice* QMirClientBackingStore::paintDevice()
-{
- return &mImage;
-}
-
-QImage QMirClientBackingStore::toImage() const
-{
- // used by QPlatformBackingStore::composeAndFlush
- return mImage;
-}
diff --git a/src/plugins/platforms/mirclient/qmirclientclipboard.cpp b/src/plugins/platforms/mirclient/qmirclientclipboard.cpp
deleted file mode 100644
index b9fc9b3b42..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientclipboard.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qmirclientclipboard.h"
-#include "qmirclientlogging.h"
-#include "qmirclientwindow.h"
-
-#include <QDBusPendingCallWatcher>
-#include <QGuiApplication>
-#include <QSignalBlocker>
-#include <QtCore/QMimeData>
-#include <QtCore/QStringList>
-
-// content-hub
-#include <com/ubuntu/content/hub.h>
-
-// get this cumbersome nested namespace out of the way
-using namespace com::ubuntu::content;
-
-QMirClientClipboard::QMirClientClipboard()
- : mMimeData(new QMimeData)
- , mContentHub(Hub::Client::instance())
-{
- connect(mContentHub, &Hub::pasteboardChanged, this, [this]() {
- if (mClipboardState == QMirClientClipboard::SyncedClipboard) {
- mClipboardState = QMirClientClipboard::OutdatedClipboard;
- emitChanged(QClipboard::Clipboard);
- }
- });
-
- connect(qGuiApp, &QGuiApplication::applicationStateChanged,
- this, &QMirClientClipboard::onApplicationStateChanged);
-
- requestMimeData();
-}
-
-QMirClientClipboard::~QMirClientClipboard()
-{
- delete mMimeData;
-}
-
-QMimeData* QMirClientClipboard::mimeData(QClipboard::Mode mode)
-{
- if (mode != QClipboard::Clipboard)
- return nullptr;
-
- // Blocks dataChanged() signal from being emitted. Makes no sense to emit it from
- // inside the data getter.
- const QSignalBlocker blocker(this);
-
- if (mClipboardState == OutdatedClipboard) {
- updateMimeData();
- } else if (mClipboardState == SyncingClipboard) {
- mPasteReply->waitForFinished();
- }
-
- return mMimeData;
-}
-
-void QMirClientClipboard::setMimeData(QMimeData* mimeData, QClipboard::Mode mode)
-{
- QWindow *focusWindow = QGuiApplication::focusWindow();
- if (focusWindow && mode == QClipboard::Clipboard && mimeData != nullptr) {
- QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId();
-
- QDBusPendingCall reply = mContentHub->createPaste(surfaceId, *mimeData);
-
- // Don't care whether it succeeded
- QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
- connect(watcher, &QDBusPendingCallWatcher::finished,
- watcher, &QObject::deleteLater);
-
- mMimeData = mimeData;
- mClipboardState = SyncedClipboard;
- emitChanged(QClipboard::Clipboard);
- }
-}
-
-bool QMirClientClipboard::supportsMode(QClipboard::Mode mode) const
-{
- return mode == QClipboard::Clipboard;
-}
-
-bool QMirClientClipboard::ownsMode(QClipboard::Mode mode) const
-{
- Q_UNUSED(mode);
- return false;
-}
-
-void QMirClientClipboard::onApplicationStateChanged(Qt::ApplicationState state)
-{
- if (state == Qt::ApplicationActive) {
- // Only focused or active applications might be allowed to paste, so we probably
- // missed changes in the clipboard while we were hidden, inactive or, more importantly,
- // suspended.
- requestMimeData();
- }
-}
-
-void QMirClientClipboard::updateMimeData()
-{
- if (qGuiApp->applicationState() != Qt::ApplicationActive) {
- // Don't even bother asking as content-hub would probably ignore our request (and should).
- return;
- }
-
- delete mMimeData;
-
- QWindow *focusWindow = QGuiApplication::focusWindow();
- if (focusWindow) {
- QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId();
- mMimeData = mContentHub->latestPaste(surfaceId);
- mClipboardState = SyncedClipboard;
- emitChanged(QClipboard::Clipboard);
- }
-}
-
-void QMirClientClipboard::requestMimeData()
-{
- if (qGuiApp->applicationState() != Qt::ApplicationActive) {
- // Don't even bother asking as content-hub would probably ignore our request (and should).
- return;
- }
-
- QWindow *focusWindow = QGuiApplication::focusWindow();
- if (!focusWindow) {
- return;
- }
-
- QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId();
- QDBusPendingCall reply = mContentHub->requestLatestPaste(surfaceId);
- mClipboardState = SyncingClipboard;
-
- mPasteReply = new QDBusPendingCallWatcher(reply, this);
- connect(mPasteReply, &QDBusPendingCallWatcher::finished,
- this, [this]() {
- delete mMimeData;
- mMimeData = mContentHub->paste(*mPasteReply);
- mClipboardState = SyncedClipboard;
- mPasteReply->deleteLater();
- mPasteReply = nullptr;
- emitChanged(QClipboard::Clipboard);
- });
-}
diff --git a/src/plugins/platforms/mirclient/qmirclientcursor.cpp b/src/plugins/platforms/mirclient/qmirclientcursor.cpp
deleted file mode 100644
index 812cde95c6..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientcursor.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015-2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qmirclientcursor.h"
-
-#include "qmirclientlogging.h"
-#include "qmirclientwindow.h"
-
-#include <mir_toolkit/mir_client_library.h>
-
-Q_LOGGING_CATEGORY(mirclientCursor, "qt.qpa.mirclient.cursor", QtWarningMsg)
-
-QMirClientCursor::QMirClientCursor(MirConnection *connection)
- : mConnection(connection)
-{
- /*
- * TODO: Add the missing cursors to Mir (LP: #1388987)
- * Those are the ones without a mir_ prefix, which are X11 cursors
- * and won't be understood by any shell other than Unity8.
- */
- mShapeToCursorName[Qt::ArrowCursor] = mir_arrow_cursor_name;
- mShapeToCursorName[Qt::UpArrowCursor] = "up_arrow";
- mShapeToCursorName[Qt::CrossCursor] = mir_crosshair_cursor_name;
- mShapeToCursorName[Qt::WaitCursor] = mir_busy_cursor_name;
- mShapeToCursorName[Qt::IBeamCursor] = mir_caret_cursor_name;
- mShapeToCursorName[Qt::SizeVerCursor] = mir_vertical_resize_cursor_name;
- mShapeToCursorName[Qt::SizeHorCursor] = mir_horizontal_resize_cursor_name;
- mShapeToCursorName[Qt::SizeBDiagCursor] = mir_diagonal_resize_bottom_to_top_cursor_name;
- mShapeToCursorName[Qt::SizeFDiagCursor] = mir_diagonal_resize_top_to_bottom_cursor_name;
- mShapeToCursorName[Qt::SizeAllCursor] = mir_omnidirectional_resize_cursor_name;
- mShapeToCursorName[Qt::BlankCursor] = mir_disabled_cursor_name;
- mShapeToCursorName[Qt::SplitVCursor] = mir_vsplit_resize_cursor_name;
- mShapeToCursorName[Qt::SplitHCursor] = mir_hsplit_resize_cursor_name;
- mShapeToCursorName[Qt::PointingHandCursor] = mir_pointing_hand_cursor_name;
- mShapeToCursorName[Qt::ForbiddenCursor] = "forbidden";
- mShapeToCursorName[Qt::WhatsThisCursor] = "whats_this";
- mShapeToCursorName[Qt::BusyCursor] = "left_ptr_watch";
- mShapeToCursorName[Qt::OpenHandCursor] = mir_open_hand_cursor_name;
- mShapeToCursorName[Qt::ClosedHandCursor] = mir_closed_hand_cursor_name;
- mShapeToCursorName[Qt::DragCopyCursor] = "dnd-copy";
- mShapeToCursorName[Qt::DragMoveCursor] = "dnd-move";
- mShapeToCursorName[Qt::DragLinkCursor] = "dnd-link";
-}
-
-namespace {
-const char *qtCursorShapeToStr(Qt::CursorShape shape)
-{
- switch (shape) {
- case Qt::ArrowCursor:
- return "Arrow";
- case Qt::UpArrowCursor:
- return "UpArrow";
- case Qt::CrossCursor:
- return "Cross";
- case Qt::WaitCursor:
- return "Wait";
- case Qt::IBeamCursor:
- return "IBeam";
- case Qt::SizeVerCursor:
- return "SizeVer";
- case Qt::SizeHorCursor:
- return "SizeHor";
- case Qt::SizeBDiagCursor:
- return "SizeBDiag";
- case Qt::SizeFDiagCursor:
- return "SizeFDiag";
- case Qt::SizeAllCursor:
- return "SizeAll";
- case Qt::BlankCursor:
- return "Blank";
- case Qt::SplitVCursor:
- return "SplitV";
- case Qt::SplitHCursor:
- return "SplitH";
- case Qt::PointingHandCursor:
- return "PointingHand";
- case Qt::ForbiddenCursor:
- return "Forbidden";
- case Qt::WhatsThisCursor:
- return "WhatsThis";
- case Qt::BusyCursor:
- return "Busy";
- case Qt::OpenHandCursor:
- return "OpenHand";
- case Qt::ClosedHandCursor:
- return "ClosedHand";
- case Qt::DragCopyCursor:
- return "DragCopy";
- case Qt::DragMoveCursor:
- return "DragMove";
- case Qt::DragLinkCursor:
- return "DragLink";
- case Qt::BitmapCursor:
- return "Bitmap";
- default:
- return "???";
- }
-}
-} // anonymous namespace
-
-void QMirClientCursor::changeCursor(QCursor *windowCursor, QWindow *window)
-{
- if (!window) {
- return;
- }
-
- MirSurface *surface = static_cast<QMirClientWindow*>(window->handle())->mirSurface();
-
- if (!surface) {
- return;
- }
-
-
- if (windowCursor) {
- qCDebug(mirclientCursor, "changeCursor shape=%s, window=%p", qtCursorShapeToStr(windowCursor->shape()), window);
- if (!windowCursor->pixmap().isNull()) {
- configureMirCursorWithPixmapQCursor(surface, *windowCursor);
- } else if (windowCursor->shape() == Qt::BitmapCursor) {
- // TODO: Implement bitmap cursor support
- applyDefaultCursorConfiguration(surface);
- } else {
- const auto &cursorName = mShapeToCursorName.value(windowCursor->shape(), QByteArray("left_ptr"));
- auto cursorConfiguration = mir_cursor_configuration_from_name(cursorName.data());
- mir_surface_configure_cursor(surface, cursorConfiguration);
- mir_cursor_configuration_destroy(cursorConfiguration);
- }
- } else {
- applyDefaultCursorConfiguration(surface);
- }
-
-}
-
-void QMirClientCursor::configureMirCursorWithPixmapQCursor(MirSurface *surface, QCursor &cursor)
-{
- QImage image = cursor.pixmap().toImage();
-
- if (image.format() != QImage::Format_ARGB32) {
- image = image.convertToFormat(QImage::Format_ARGB32);
- }
-
- MirBufferStream *bufferStream = mir_connection_create_buffer_stream_sync(mConnection,
- image.width(), image.height(), mir_pixel_format_argb_8888, mir_buffer_usage_software);
-
- {
- MirGraphicsRegion region;
- mir_buffer_stream_get_graphics_region(bufferStream, &region);
-
- char *regionLine = region.vaddr;
- Q_ASSERT(image.bytesPerLine() <= region.stride);
- for (int i = 0; i < image.height(); ++i) {
- memcpy(regionLine, image.scanLine(i), image.bytesPerLine());
- regionLine += region.stride;
- }
- }
-
- mir_buffer_stream_swap_buffers_sync(bufferStream);
-
- {
- auto configuration = mir_cursor_configuration_from_buffer_stream(bufferStream, cursor.hotSpot().x(), cursor.hotSpot().y());
- mir_surface_configure_cursor(surface, configuration);
- mir_cursor_configuration_destroy(configuration);
- }
-
- mir_buffer_stream_release_sync(bufferStream);
-}
-
-void QMirClientCursor::applyDefaultCursorConfiguration(MirSurface *surface)
-{
- auto cursorConfiguration = mir_cursor_configuration_from_name("left_ptr");
- mir_surface_configure_cursor(surface, cursorConfiguration);
- mir_cursor_configuration_destroy(cursorConfiguration);
-}
diff --git a/src/plugins/platforms/mirclient/qmirclientcursor.h b/src/plugins/platforms/mirclient/qmirclientcursor.h
deleted file mode 100644
index c5de23b272..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientcursor.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015-2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTCURSOR_H
-#define QMIRCLIENTCURSOR_H
-
-#include <qpa/qplatformcursor.h>
-
-#include <QMap>
-#include <QByteArray>
-
-struct MirConnection;
-struct MirSurface;
-
-class QMirClientCursor : public QPlatformCursor
-{
-public:
- QMirClientCursor(MirConnection *connection);
- void changeCursor(QCursor *windowCursor, QWindow *window) override;
-private:
- void configureMirCursorWithPixmapQCursor(MirSurface *surface, QCursor &cursor);
- void applyDefaultCursorConfiguration(MirSurface *surface);
- QMap<int, QByteArray> mShapeToCursorName;
- MirConnection *mConnection;
-};
-
-#endif // QMIRCLIENTCURSOR_H
diff --git a/src/plugins/platforms/mirclient/qmirclientdebugextension.cpp b/src/plugins/platforms/mirclient/qmirclientdebugextension.cpp
deleted file mode 100644
index 9aa934083d..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientdebugextension.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qmirclientdebugextension.h"
-
-#include "qmirclientlogging.h"
-
-// mir client debug
-#include <mir_toolkit/debug/surface.h>
-
-Q_LOGGING_CATEGORY(mirclientDebug, "qt.qpa.mirclient.debug")
-
-QMirClientDebugExtension::QMirClientDebugExtension()
- : m_mirclientDebug(QStringLiteral("mirclient-debug-extension"), 1)
- , m_mapper(nullptr)
-{
- qCDebug(mirclientDebug) << "NOTICE: Loading mirclient-debug-extension";
- m_mapper = (MapperPrototype) m_mirclientDebug.resolve("mir_debug_surface_coords_to_screen");
-
- if (!m_mirclientDebug.isLoaded()) {
- qCWarning(mirclientDebug) << "ERROR: mirclient-debug-extension failed to load:"
- << m_mirclientDebug.errorString();
- } else if (!m_mapper) {
- qCWarning(mirclientDebug) << "ERROR: unable to find required symbols in mirclient-debug-extension:"
- << m_mirclientDebug.errorString();
- }
-}
-
-QPoint QMirClientDebugExtension::mapSurfacePointToScreen(MirSurface *surface, const QPoint &point)
-{
- if (!m_mapper) {
- return point;
- }
-
- QPoint mappedPoint;
- bool status = m_mapper(surface, point.x(), point.y(), &mappedPoint.rx(), &mappedPoint.ry());
- if (status) {
- return mappedPoint;
- } else {
- return point;
- }
-}
diff --git a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp b/src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp
deleted file mode 100644
index 123f805c25..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qmirclientdesktopwindow.h"
-
-// local
-#include "qmirclientlogging.h"
-
-QMirClientDesktopWindow::QMirClientDesktopWindow(QWindow *window)
- : QPlatformWindow(window)
-{
- qCDebug(mirclient, "QMirClientDesktopWindow(window=%p)", window);
-}
diff --git a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.h b/src/plugins/platforms/mirclient/qmirclientdesktopwindow.h
deleted file mode 100644
index 3ba54db826..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTDESKTOPWINDOW_H
-#define QMIRCLIENTDESKTOPWINDOW_H
-
-#include <qpa/qplatformwindow.h>
-
-// TODO Implement it. For now it's just an empty, dummy class.
-class QMirClientDesktopWindow : public QPlatformWindow
-{
-public:
- QMirClientDesktopWindow(QWindow*);
-};
-
-#endif // QMIRCLIENTDESKTOPWINDOW_H
diff --git a/src/plugins/platforms/mirclient/qmirclientglcontext.cpp b/src/plugins/platforms/mirclient/qmirclientglcontext.cpp
deleted file mode 100644
index fc7d90d5ec..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientglcontext.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qmirclientglcontext.h"
-#include "qmirclientlogging.h"
-#include "qmirclientwindow.h"
-
-#include <QOpenGLFramebufferObject>
-#include <QtEglSupport/private/qeglconvenience_p.h>
-#include <QtEglSupport/private/qeglpbuffer_p.h>
-#include <QtGui/private/qopenglcontext_p.h>
-
-Q_LOGGING_CATEGORY(mirclientGraphics, "qt.qpa.mirclient.graphics", QtWarningMsg)
-
-namespace {
-
-void printEglConfig(EGLDisplay display, EGLConfig config)
-{
- Q_ASSERT(display != EGL_NO_DISPLAY);
- Q_ASSERT(config != nullptr);
-
- const char *string = eglQueryString(display, EGL_VENDOR);
- qCDebug(mirclientGraphics, "EGL vendor: %s", string);
-
- string = eglQueryString(display, EGL_VERSION);
- qCDebug(mirclientGraphics, "EGL version: %s", string);
-
- string = eglQueryString(display, EGL_EXTENSIONS);
- qCDebug(mirclientGraphics, "EGL extensions: %s", string);
-
- qCDebug(mirclientGraphics, "EGL configuration attributes:");
- q_printEglConfig(display, config);
-}
-
-} // anonymous namespace
-
-QMirClientOpenGLContext::QMirClientOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
- EGLDisplay display)
- : QEGLPlatformContext(format, share, display, 0)
-{
- if (mirclientGraphics().isDebugEnabled()) {
- printEglConfig(display, eglConfig());
- }
-}
-
-static bool needsFBOReadBackWorkaround()
-{
- static bool set = false;
- static bool needsWorkaround = false;
-
- if (Q_UNLIKELY(!set)) {
- const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
- needsWorkaround = qstrncmp(rendererString, "Mali-400", 8) == 0
- || qstrncmp(rendererString, "Mali-T7", 7) == 0
- || qstrncmp(rendererString, "PowerVR Rogue G6200", 19) == 0;
- set = true;
- }
-
- return needsWorkaround;
-}
-
-bool QMirClientOpenGLContext::makeCurrent(QPlatformSurface* surface)
-{
- const bool ret = QEGLPlatformContext::makeCurrent(surface);
-
- if (Q_LIKELY(ret)) {
- QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context());
- if (!ctx_d->workaround_brokenFBOReadBack && needsFBOReadBackWorkaround()) {
- ctx_d->workaround_brokenFBOReadBack = true;
- }
- }
- return ret;
-}
-
-// Following method used internally in the base class QEGLPlatformContext to access
-// the egl surface of a QPlatformSurface/QMirClientWindow
-EGLSurface QMirClientOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
-{
- if (surface->surface()->surfaceClass() == QSurface::Window) {
- return static_cast<QMirClientWindow *>(surface)->eglSurface();
- } else {
- return static_cast<QEGLPbuffer *>(surface)->pbuffer();
- }
-}
-
-void QMirClientOpenGLContext::swapBuffers(QPlatformSurface* surface)
-{
- QEGLPlatformContext::swapBuffers(surface);
-
- if (surface->surface()->surfaceClass() == QSurface::Window) {
- // notify window on swap completion
- auto platformWindow = static_cast<QMirClientWindow *>(surface);
- platformWindow->onSwapBuffersDone();
- }
-}
diff --git a/src/plugins/platforms/mirclient/qmirclientglcontext.h b/src/plugins/platforms/mirclient/qmirclientglcontext.h
deleted file mode 100644
index 92331a6fb1..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientglcontext.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTGLCONTEXT_H
-#define QMIRCLIENTGLCONTEXT_H
-
-#include <qpa/qplatformopenglcontext.h>
-#include <QtEglSupport/private/qeglplatformcontext_p.h>
-
-#include <EGL/egl.h>
-
-class QMirClientOpenGLContext : public QEGLPlatformContext
-{
-public:
- QMirClientOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
- EGLDisplay display);
-
- // QEGLPlatformContext methods.
- void swapBuffers(QPlatformSurface *surface) final;
- bool makeCurrent(QPlatformSurface *surface) final;
-
-protected:
- EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) final;
-};
-
-#endif // QMIRCLIENTGLCONTEXT_H
diff --git a/src/plugins/platforms/mirclient/qmirclientinput.cpp b/src/plugins/platforms/mirclient/qmirclientinput.cpp
deleted file mode 100644
index e5319b0435..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientinput.cpp
+++ /dev/null
@@ -1,708 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014-2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-// Local
-#include "qmirclientinput.h"
-#include "qmirclientintegration.h"
-#include "qmirclientnativeinterface.h"
-#include "qmirclientscreen.h"
-#include "qmirclientwindow.h"
-#include "qmirclientlogging.h"
-#include "qmirclientorientationchangeevent_p.h"
-
-// Qt
-#include <QtCore/QThread>
-#include <QtCore/qglobal.h>
-#include <QtCore/QCoreApplication>
-#include <QtGui/private/qguiapplication_p.h>
-#include <qpa/qplatforminputcontext.h>
-#include <qpa/qwindowsysteminterface.h>
-#include <QTextCodec>
-
-#include <xkbcommon/xkbcommon.h>
-#include <xkbcommon/xkbcommon-keysyms.h>
-
-#include <mir_toolkit/mir_client_library.h>
-
-Q_LOGGING_CATEGORY(mirclientInput, "qt.qpa.mirclient.input", QtWarningMsg)
-
-namespace
-{
-
-// XKB Keysyms which do not map directly to Qt types (i.e. Unicode points)
-static const uint32_t KeyTable[] = {
- XKB_KEY_Escape, Qt::Key_Escape,
- XKB_KEY_Tab, Qt::Key_Tab,
- XKB_KEY_ISO_Left_Tab, Qt::Key_Backtab,
- XKB_KEY_BackSpace, Qt::Key_Backspace,
- XKB_KEY_Return, Qt::Key_Return,
- XKB_KEY_Insert, Qt::Key_Insert,
- XKB_KEY_Delete, Qt::Key_Delete,
- XKB_KEY_Clear, Qt::Key_Delete,
- XKB_KEY_Pause, Qt::Key_Pause,
- XKB_KEY_Print, Qt::Key_Print,
-
- XKB_KEY_Home, Qt::Key_Home,
- XKB_KEY_End, Qt::Key_End,
- XKB_KEY_Left, Qt::Key_Left,
- XKB_KEY_Up, Qt::Key_Up,
- XKB_KEY_Right, Qt::Key_Right,
- XKB_KEY_Down, Qt::Key_Down,
- XKB_KEY_Prior, Qt::Key_PageUp,
- XKB_KEY_Next, Qt::Key_PageDown,
-
- XKB_KEY_Shift_L, Qt::Key_Shift,
- XKB_KEY_Shift_R, Qt::Key_Shift,
- XKB_KEY_Shift_Lock, Qt::Key_Shift,
- XKB_KEY_Control_L, Qt::Key_Control,
- XKB_KEY_Control_R, Qt::Key_Control,
- XKB_KEY_Meta_L, Qt::Key_Meta,
- XKB_KEY_Meta_R, Qt::Key_Meta,
- XKB_KEY_Alt_L, Qt::Key_Alt,
- XKB_KEY_Alt_R, Qt::Key_Alt,
- XKB_KEY_Caps_Lock, Qt::Key_CapsLock,
- XKB_KEY_Num_Lock, Qt::Key_NumLock,
- XKB_KEY_Scroll_Lock, Qt::Key_ScrollLock,
- XKB_KEY_Super_L, Qt::Key_Super_L,
- XKB_KEY_Super_R, Qt::Key_Super_R,
- XKB_KEY_Menu, Qt::Key_Menu,
- XKB_KEY_Hyper_L, Qt::Key_Hyper_L,
- XKB_KEY_Hyper_R, Qt::Key_Hyper_R,
- XKB_KEY_Help, Qt::Key_Help,
-
- XKB_KEY_KP_Space, Qt::Key_Space,
- XKB_KEY_KP_Tab, Qt::Key_Tab,
- XKB_KEY_KP_Enter, Qt::Key_Enter,
- XKB_KEY_KP_Home, Qt::Key_Home,
- XKB_KEY_KP_Left, Qt::Key_Left,
- XKB_KEY_KP_Up, Qt::Key_Up,
- XKB_KEY_KP_Right, Qt::Key_Right,
- XKB_KEY_KP_Down, Qt::Key_Down,
- XKB_KEY_KP_Prior, Qt::Key_PageUp,
- XKB_KEY_KP_Next, Qt::Key_PageDown,
- XKB_KEY_KP_End, Qt::Key_End,
- XKB_KEY_KP_Begin, Qt::Key_Clear,
- XKB_KEY_KP_Insert, Qt::Key_Insert,
- XKB_KEY_KP_Delete, Qt::Key_Delete,
- XKB_KEY_KP_Equal, Qt::Key_Equal,
- XKB_KEY_KP_Multiply, Qt::Key_Asterisk,
- XKB_KEY_KP_Add, Qt::Key_Plus,
- XKB_KEY_KP_Separator, Qt::Key_Comma,
- XKB_KEY_KP_Subtract, Qt::Key_Minus,
- XKB_KEY_KP_Decimal, Qt::Key_Period,
- XKB_KEY_KP_Divide, Qt::Key_Slash,
-
- XKB_KEY_ISO_Level3_Shift, Qt::Key_AltGr,
- XKB_KEY_Multi_key, Qt::Key_Multi_key,
- XKB_KEY_Codeinput, Qt::Key_Codeinput,
- XKB_KEY_SingleCandidate, Qt::Key_SingleCandidate,
- XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate,
- XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate,
-
- // dead keys
- XKB_KEY_dead_grave, Qt::Key_Dead_Grave,
- XKB_KEY_dead_acute, Qt::Key_Dead_Acute,
- XKB_KEY_dead_circumflex, Qt::Key_Dead_Circumflex,
- XKB_KEY_dead_tilde, Qt::Key_Dead_Tilde,
- XKB_KEY_dead_macron, Qt::Key_Dead_Macron,
- XKB_KEY_dead_breve, Qt::Key_Dead_Breve,
- XKB_KEY_dead_abovedot, Qt::Key_Dead_Abovedot,
- XKB_KEY_dead_diaeresis, Qt::Key_Dead_Diaeresis,
- XKB_KEY_dead_abovering, Qt::Key_Dead_Abovering,
- XKB_KEY_dead_doubleacute, Qt::Key_Dead_Doubleacute,
- XKB_KEY_dead_caron, Qt::Key_Dead_Caron,
- XKB_KEY_dead_cedilla, Qt::Key_Dead_Cedilla,
- XKB_KEY_dead_ogonek, Qt::Key_Dead_Ogonek,
- XKB_KEY_dead_iota, Qt::Key_Dead_Iota,
- XKB_KEY_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound,
- XKB_KEY_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound,
- XKB_KEY_dead_belowdot, Qt::Key_Dead_Belowdot,
- XKB_KEY_dead_hook, Qt::Key_Dead_Hook,
- XKB_KEY_dead_horn, Qt::Key_Dead_Horn,
- XKB_KEY_dead_stroke, Qt::Key_Dead_Stroke,
- XKB_KEY_dead_abovecomma, Qt::Key_Dead_Abovecomma,
- XKB_KEY_dead_abovereversedcomma, Qt::Key_Dead_Abovereversedcomma,
- XKB_KEY_dead_doublegrave, Qt::Key_Dead_Doublegrave,
- XKB_KEY_dead_belowring, Qt::Key_Dead_Belowring,
- XKB_KEY_dead_belowmacron, Qt::Key_Dead_Belowmacron,
- XKB_KEY_dead_belowcircumflex, Qt::Key_Dead_Belowcircumflex,
- XKB_KEY_dead_belowtilde, Qt::Key_Dead_Belowtilde,
- XKB_KEY_dead_belowbreve, Qt::Key_Dead_Belowbreve,
- XKB_KEY_dead_belowdiaeresis, Qt::Key_Dead_Belowdiaeresis,
- XKB_KEY_dead_invertedbreve, Qt::Key_Dead_Invertedbreve,
- XKB_KEY_dead_belowcomma, Qt::Key_Dead_Belowcomma,
- XKB_KEY_dead_currency, Qt::Key_Dead_Currency,
- XKB_KEY_dead_a, Qt::Key_Dead_a,
- XKB_KEY_dead_A, Qt::Key_Dead_A,
- XKB_KEY_dead_e, Qt::Key_Dead_e,
- XKB_KEY_dead_E, Qt::Key_Dead_E,
- XKB_KEY_dead_i, Qt::Key_Dead_i,
- XKB_KEY_dead_I, Qt::Key_Dead_I,
- XKB_KEY_dead_o, Qt::Key_Dead_o,
- XKB_KEY_dead_O, Qt::Key_Dead_O,
- XKB_KEY_dead_u, Qt::Key_Dead_u,
- XKB_KEY_dead_U, Qt::Key_Dead_U,
- XKB_KEY_dead_small_schwa, Qt::Key_Dead_Small_Schwa,
- XKB_KEY_dead_capital_schwa, Qt::Key_Dead_Capital_Schwa,
- XKB_KEY_dead_greek, Qt::Key_Dead_Greek,
- XKB_KEY_dead_lowline, Qt::Key_Dead_Lowline,
- XKB_KEY_dead_aboveverticalline, Qt::Key_Dead_Aboveverticalline,
- XKB_KEY_dead_belowverticalline, Qt::Key_Dead_Belowverticalline,
- XKB_KEY_dead_longsolidusoverlay, Qt::Key_Dead_Longsolidusoverlay,
-
- XKB_KEY_Mode_switch, Qt::Key_Mode_switch,
- XKB_KEY_script_switch, Qt::Key_Mode_switch,
- XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp,
- XKB_KEY_XF86AudioLowerVolume, Qt::Key_VolumeDown,
- XKB_KEY_XF86PowerOff, Qt::Key_PowerOff,
- XKB_KEY_XF86PowerDown, Qt::Key_PowerDown,
-
- 0, 0
-};
-
-Qt::WindowState mirSurfaceStateToWindowState(MirSurfaceState state)
-{
- switch (state) {
- case mir_surface_state_fullscreen:
- return Qt::WindowFullScreen;
- case mir_surface_state_maximized:
- case mir_surface_state_vertmaximized:
- case mir_surface_state_horizmaximized:
- return Qt::WindowMaximized;
- case mir_surface_state_minimized:
- return Qt::WindowMinimized;
- case mir_surface_state_hidden:
- // We should be handling this state separately.
- Q_ASSERT(false);
- case mir_surface_state_restored:
- case mir_surface_state_unknown:
- default:
- return Qt::WindowNoState;
- }
-}
-
-} // namespace
-
-class UbuntuEvent : public QEvent
-{
-public:
- UbuntuEvent(QMirClientWindow* window, const MirEvent *event, QEvent::Type type)
- : QEvent(type), window(window) {
- nativeEvent = mir_event_ref(event);
- }
- ~UbuntuEvent()
- {
- mir_event_unref(nativeEvent);
- }
-
- QPointer<QMirClientWindow> window;
- const MirEvent *nativeEvent;
-};
-
-QMirClientInput::QMirClientInput(QMirClientClientIntegration* integration)
- : QObject(nullptr)
- , mIntegration(integration)
- , mEventFilterType(static_cast<QMirClientNativeInterface*>(
- integration->nativeInterface())->genericEventFilterType())
- , mEventType(static_cast<QEvent::Type>(QEvent::registerEventType()))
- , mLastInputWindow(nullptr)
-{
- // Initialize touch device.
- mTouchDevice = new QTouchDevice;
- mTouchDevice->setType(QTouchDevice::TouchScreen);
- mTouchDevice->setCapabilities(
- QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure |
- QTouchDevice::NormalizedPosition);
- QWindowSystemInterface::registerTouchDevice(mTouchDevice);
-}
-
-QMirClientInput::~QMirClientInput()
-{
- // Qt will take care of deleting mTouchDevice.
-}
-
-static const char* nativeEventTypeToStr(MirEventType t)
-{
- switch (t)
- {
- case mir_event_type_key:
- return "key";
- case mir_event_type_motion:
- return "motion";
- case mir_event_type_surface:
- return "surface";
- case mir_event_type_resize:
- return "resize";
- case mir_event_type_prompt_session_state_change:
- return "prompt_session_state_change";
- case mir_event_type_orientation:
- return "orientation";
- case mir_event_type_close_surface:
- return "close_surface";
- case mir_event_type_input:
- return "input";
- case mir_event_type_keymap:
- return "keymap";
- case mir_event_type_input_configuration:
- return "input_configuration";
- case mir_event_type_surface_output:
- return "surface_output";
- case mir_event_type_input_device_state:
- return "input_device_state";
- default:
- return "unknown";
- }
-}
-
-void QMirClientInput::customEvent(QEvent* event)
-{
- Q_ASSERT(QThread::currentThread() == thread());
- UbuntuEvent* ubuntuEvent = static_cast<UbuntuEvent*>(event);
- const MirEvent *nativeEvent = ubuntuEvent->nativeEvent;
-
- if ((ubuntuEvent->window == nullptr) || (ubuntuEvent->window->window() == nullptr)) {
- qCWarning(mirclient) << "Attempted to deliver an event to a non-existent window, ignoring.";
- return;
- }
-
- // Event filtering.
- long result;
- if (QWindowSystemInterface::handleNativeEvent(
- ubuntuEvent->window->window(), mEventFilterType,
- const_cast<void *>(static_cast<const void *>(nativeEvent)), &result) == true) {
- qCDebug(mirclient, "event filtered out by native interface");
- return;
- }
-
- qCDebug(mirclientInput, "customEvent(type=%s)", nativeEventTypeToStr(mir_event_get_type(nativeEvent)));
-
- // Event dispatching.
- switch (mir_event_get_type(nativeEvent))
- {
- case mir_event_type_input:
- dispatchInputEvent(ubuntuEvent->window, mir_event_get_input_event(nativeEvent));
- break;
- case mir_event_type_resize:
- {
- auto resizeEvent = mir_event_get_resize_event(nativeEvent);
-
- // Enable workaround for Screen rotation
- auto const targetWindow = ubuntuEvent->window;
- if (targetWindow) {
- auto const screen = static_cast<QMirClientScreen*>(targetWindow->screen());
- if (screen) {
- screen->handleWindowSurfaceResize(
- mir_resize_event_get_width(resizeEvent),
- mir_resize_event_get_height(resizeEvent));
- }
-
- targetWindow->handleSurfaceResized(
- mir_resize_event_get_width(resizeEvent),
- mir_resize_event_get_height(resizeEvent));
- }
- break;
- }
- case mir_event_type_surface:
- handleSurfaceEvent(ubuntuEvent->window, mir_event_get_surface_event(nativeEvent));
- break;
- case mir_event_type_surface_output:
- handleSurfaceOutputEvent(ubuntuEvent->window, mir_event_get_surface_output_event(nativeEvent));
- break;
- case mir_event_type_orientation:
- dispatchOrientationEvent(ubuntuEvent->window->window(), mir_event_get_orientation_event(nativeEvent));
- break;
- case mir_event_type_close_surface:
- QWindowSystemInterface::handleCloseEvent(ubuntuEvent->window->window());
- break;
- default:
- qCDebug(mirclient, "unhandled event type: %d", static_cast<int>(mir_event_get_type(nativeEvent)));
- }
-}
-
-void QMirClientInput::postEvent(QMirClientWindow *platformWindow, const MirEvent *event)
-{
- QWindow *window = platformWindow->window();
-
- QCoreApplication::postEvent(this, new UbuntuEvent(
- platformWindow, event, mEventType));
-
- if ((window->flags().testFlag(Qt::WindowTransparentForInput)) && window->parent()) {
- QCoreApplication::postEvent(this, new UbuntuEvent(
- static_cast<QMirClientWindow*>(platformWindow->QPlatformWindow::parent()),
- event, mEventType));
- }
-}
-
-void QMirClientInput::dispatchInputEvent(QMirClientWindow *window, const MirInputEvent *ev)
-{
- switch (mir_input_event_get_type(ev))
- {
- case mir_input_event_type_key:
- dispatchKeyEvent(window, ev);
- break;
- case mir_input_event_type_touch:
- dispatchTouchEvent(window, ev);
- break;
- case mir_input_event_type_pointer:
- dispatchPointerEvent(window, ev);
- break;
- default:
- break;
- }
-}
-
-void QMirClientInput::dispatchTouchEvent(QMirClientWindow *window, const MirInputEvent *ev)
-{
- const MirTouchEvent *tev = mir_input_event_get_touch_event(ev);
-
- // FIXME(loicm) Max pressure is device specific. That one is for the Samsung Galaxy Nexus. That
- // needs to be fixed as soon as the compat input lib adds query support.
- const float kMaxPressure = 1.28;
- const QRect kWindowGeometry = window->geometry();
- QList<QWindowSystemInterface::TouchPoint> touchPoints;
-
-
- // TODO: Is it worth setting the Qt::TouchPointStationary ones? Currently they are left
- // as Qt::TouchPointMoved
- const unsigned int kPointerCount = mir_touch_event_point_count(tev);
- touchPoints.reserve(int(kPointerCount));
- for (unsigned int i = 0; i < kPointerCount; ++i) {
- QWindowSystemInterface::TouchPoint touchPoint;
-
- const float kX = mir_touch_event_axis_value(tev, i, mir_touch_axis_x) + kWindowGeometry.x();
- const float kY = mir_touch_event_axis_value(tev, i, mir_touch_axis_y) + kWindowGeometry.y(); // see bug lp:1346633 workaround comments elsewhere
- const float kW = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_major);
- const float kH = mir_touch_event_axis_value(tev, i, mir_touch_axis_touch_minor);
- const float kP = mir_touch_event_axis_value(tev, i, mir_touch_axis_pressure);
- touchPoint.id = mir_touch_event_id(tev, i);
- touchPoint.normalPosition = QPointF(kX / kWindowGeometry.width(), kY / kWindowGeometry.height());
- touchPoint.area = QRectF(kX - (kW / 2.0), kY - (kH / 2.0), kW, kH);
- touchPoint.pressure = kP / kMaxPressure;
-
- MirTouchAction touch_action = mir_touch_event_action(tev, i);
- switch (touch_action)
- {
- case mir_touch_action_down:
- mLastInputWindow = window;
- touchPoint.state = Qt::TouchPointPressed;
- break;
- case mir_touch_action_up:
- touchPoint.state = Qt::TouchPointReleased;
- break;
- case mir_touch_action_change:
- touchPoint.state = Qt::TouchPointMoved;
- break;
- default:
- Q_UNREACHABLE();
- }
-
- touchPoints.append(touchPoint);
- }
-
- ulong timestamp = mir_input_event_get_event_time(ev) / 1000000;
- QWindowSystemInterface::handleTouchEvent(window->window(), timestamp,
- mTouchDevice, touchPoints);
-}
-
-static uint32_t translateKeysym(uint32_t sym, const QString &text) {
- int code = 0;
-
- QTextCodec *systemCodec = QTextCodec::codecForLocale();
- if (sym < 128 || (sym < 256 && systemCodec->mibEnum() == 4)) {
- // upper-case key, if known
- code = isprint((int)sym) ? toupper((int)sym) : 0;
- } else if (sym >= XKB_KEY_F1 && sym <= XKB_KEY_F35) {
- return Qt::Key_F1 + (int(sym) - XKB_KEY_F1);
- } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f
- && text.unicode()->unicode() != 0x7f
- && !(sym >= XKB_KEY_dead_grave && sym <= XKB_KEY_dead_currency)) {
- code = text.unicode()->toUpper().unicode();
- } else {
- for (int i = 0; KeyTable[i]; i += 2)
- if (sym == KeyTable[i])
- code = KeyTable[i + 1];
- }
-
- return code;
-}
-
-namespace
-{
-Qt::KeyboardModifiers qt_modifiers_from_mir(MirInputEventModifiers modifiers)
-{
- Qt::KeyboardModifiers q_modifiers = Qt::NoModifier;
- if (modifiers & mir_input_event_modifier_shift) {
- q_modifiers |= Qt::ShiftModifier;
- }
- if (modifiers & mir_input_event_modifier_ctrl) {
- q_modifiers |= Qt::ControlModifier;
- }
- if (modifiers & mir_input_event_modifier_alt_left) {
- q_modifiers |= Qt::AltModifier;
- }
- if (modifiers & mir_input_event_modifier_meta) {
- q_modifiers |= Qt::MetaModifier;
- }
- if (modifiers & mir_input_event_modifier_alt_right) {
- q_modifiers |= Qt::GroupSwitchModifier;
- }
- return q_modifiers;
-}
-}
-
-void QMirClientInput::dispatchKeyEvent(QMirClientWindow *window, const MirInputEvent *event)
-{
- const MirKeyboardEvent *key_event = mir_input_event_get_keyboard_event(event);
-
- ulong timestamp = mir_input_event_get_event_time(event) / 1000000;
- xkb_keysym_t xk_sym = mir_keyboard_event_key_code(key_event);
- quint32 scan_code = mir_keyboard_event_scan_code(key_event);
- quint32 native_modifiers = mir_keyboard_event_modifiers(key_event);
-
- // Key modifier and unicode index mapping.
- auto modifiers = qt_modifiers_from_mir(native_modifiers);
-
- MirKeyboardAction action = mir_keyboard_event_action(key_event);
- QEvent::Type keyType = action == mir_keyboard_action_up
- ? QEvent::KeyRelease : QEvent::KeyPress;
-
- if (action == mir_keyboard_action_down)
- mLastInputWindow = window;
-
- QString text;
- QVarLengthArray<char, 32> chars(32);
- {
- int result = xkb_keysym_to_utf8(xk_sym, chars.data(), chars.size());
-
- if (result > 0) {
- text = QString::fromUtf8(chars.constData());
- }
- }
- int sym = translateKeysym(xk_sym, text);
-
- bool is_auto_rep = action == mir_keyboard_action_repeat;
-
- QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext();
- if (context) {
- QKeyEvent qKeyEvent(keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep);
- qKeyEvent.setTimestamp(timestamp);
- if (context->filterEvent(&qKeyEvent)) {
- qCDebug(mirclient, "key event filtered out by input context");
- return;
- }
- }
-
- QWindowSystemInterface::handleExtendedKeyEvent(window->window(), timestamp, keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep);
-}
-
-namespace
-{
-Qt::MouseButtons extract_buttons(const MirPointerEvent *pev)
-{
- Qt::MouseButtons buttons = Qt::NoButton;
- if (mir_pointer_event_button_state(pev, mir_pointer_button_primary))
- buttons |= Qt::LeftButton;
- if (mir_pointer_event_button_state(pev, mir_pointer_button_secondary))
- buttons |= Qt::RightButton;
- if (mir_pointer_event_button_state(pev, mir_pointer_button_tertiary))
- buttons |= Qt::MiddleButton;
- if (mir_pointer_event_button_state(pev, mir_pointer_button_back))
- buttons |= Qt::BackButton;
- if (mir_pointer_event_button_state(pev, mir_pointer_button_forward))
- buttons |= Qt::ForwardButton;
-
- return buttons;
-}
-}
-
-void QMirClientInput::dispatchPointerEvent(QMirClientWindow *platformWindow, const MirInputEvent *ev)
-{
- const auto window = platformWindow->window();
- const auto timestamp = mir_input_event_get_event_time(ev) / 1000000;
-
- const auto pev = mir_input_event_get_pointer_event(ev);
- const auto action = mir_pointer_event_action(pev);
-
- const auto modifiers = qt_modifiers_from_mir(mir_pointer_event_modifiers(pev));
- const auto localPoint = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x),
- mir_pointer_event_axis_value(pev, mir_pointer_axis_y));
-
- mLastInputWindow = platformWindow;
-
- switch (action) {
- case mir_pointer_action_button_up:
- case mir_pointer_action_button_down:
- case mir_pointer_action_motion:
- {
- const float hDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_hscroll);
- const float vDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_vscroll);
-
- if (hDelta != 0 || vDelta != 0) {
- // QWheelEvent::DefaultDeltasPerStep = 120 but doesn't exist on vivid
- const QPoint angleDelta(120 * hDelta, 120 * vDelta);
- QWindowSystemInterface::handleWheelEvent(window, timestamp, localPoint, window->position() + localPoint,
- QPoint(), angleDelta, modifiers, Qt::ScrollUpdate);
- }
- auto buttons = extract_buttons(pev);
- QWindowSystemInterface::handleMouseEvent(window, timestamp, localPoint, window->position() + localPoint /* Should we omit global point instead? */,
- buttons, modifiers);
- break;
- }
- case mir_pointer_action_enter:
- QWindowSystemInterface::handleEnterEvent(window, localPoint, window->position() + localPoint);
- break;
- case mir_pointer_action_leave:
- QWindowSystemInterface::handleLeaveEvent(window);
- break;
- default:
- Q_UNREACHABLE();
- }
-}
-
-static const char* nativeOrientationDirectionToStr(MirOrientation orientation)
-{
- switch (orientation) {
- case mir_orientation_normal:
- return "Normal";
- case mir_orientation_left:
- return "Left";
- case mir_orientation_inverted:
- return "Inverted";
- case mir_orientation_right:
- return "Right";
- }
- Q_UNREACHABLE();
-}
-
-void QMirClientInput::dispatchOrientationEvent(QWindow *window, const MirOrientationEvent *event)
-{
- MirOrientation mir_orientation = mir_orientation_event_get_direction(event);
- qCDebug(mirclientInput, "orientation direction: %s", nativeOrientationDirectionToStr(mir_orientation));
-
- if (!window->screen()) {
- qCDebug(mirclient, "Window has no associated screen, dropping orientation event");
- return;
- }
-
- OrientationChangeEvent::Orientation orientation;
- switch (mir_orientation) {
- case mir_orientation_normal:
- orientation = OrientationChangeEvent::TopUp;
- break;
- case mir_orientation_left:
- orientation = OrientationChangeEvent::LeftUp;
- break;
- case mir_orientation_inverted:
- orientation = OrientationChangeEvent::TopDown;
- break;
- case mir_orientation_right:
- orientation = OrientationChangeEvent::RightUp;
- break;
- default:
- qCDebug(mirclient, "No such orientation %d", mir_orientation);
- return;
- }
-
- // Dispatch orientation event to [Platform]Screen, as that is where Qt reads it. Screen will handle
- // notifying Qt of the actual orientation change - done to prevent multiple Windows each creating
- // an identical orientation change event and passing it directly to Qt.
- // [Platform]Screen can also factor in the native orientation.
- QCoreApplication::postEvent(static_cast<QMirClientScreen*>(window->screen()->handle()),
- new OrientationChangeEvent(OrientationChangeEvent::mType, orientation));
-}
-
-void QMirClientInput::handleSurfaceEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceEvent *event)
-{
- auto surfaceEventAttribute = mir_surface_event_get_attribute(event);
-
- switch (surfaceEventAttribute) {
- case mir_surface_attrib_focus: {
- window->handleSurfaceFocusChanged(
- mir_surface_event_get_attribute_value(event) == mir_surface_focused);
- break;
- }
- case mir_surface_attrib_visibility: {
- window->handleSurfaceExposeChange(
- mir_surface_event_get_attribute_value(event) == mir_surface_visibility_exposed);
- break;
- }
- // Remaining attributes are ones client sets for server, and server should not override them
- case mir_surface_attrib_state: {
- MirSurfaceState state = static_cast<MirSurfaceState>(mir_surface_event_get_attribute_value(event));
-
- if (state == mir_surface_state_hidden) {
- window->handleSurfaceVisibilityChanged(false);
- } else {
- // it's visible!
- window->handleSurfaceVisibilityChanged(true);
- window->handleSurfaceStateChanged(mirSurfaceStateToWindowState(state));
- }
- break;
- }
- case mir_surface_attrib_type:
- case mir_surface_attrib_swapinterval:
- case mir_surface_attrib_dpi:
- case mir_surface_attrib_preferred_orientation:
- case mir_surface_attribs:
- break;
- }
-}
-
-void QMirClientInput::handleSurfaceOutputEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceOutputEvent *event)
-{
- const uint32_t outputId = mir_surface_output_event_get_output_id(event);
- const int dpi = mir_surface_output_event_get_dpi(event);
- const MirFormFactor formFactor = mir_surface_output_event_get_form_factor(event);
- const float scale = mir_surface_output_event_get_scale(event);
-
- const auto screenObserver = mIntegration->screenObserver();
- QMirClientScreen *screen = screenObserver->findScreenWithId(outputId);
- if (!screen) {
- qCWarning(mirclient) << "Mir notified window" << window->window() << "on an unknown screen with id" << outputId;
- return;
- }
-
- screenObserver->handleScreenPropertiesChange(screen, dpi, formFactor, scale);
- window->handleScreenPropertiesChange(formFactor, scale);
-
- if (window->screen() != screen) {
- QWindowSystemInterface::handleWindowScreenChanged(window->window(), screen->screen());
- }
-}
diff --git a/src/plugins/platforms/mirclient/qmirclientinput.h b/src/plugins/platforms/mirclient/qmirclientinput.h
deleted file mode 100644
index 263cb5e54e..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientinput.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014-2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTINPUT_H
-#define QMIRCLIENTINPUT_H
-
-// Qt
-#include <qpa/qwindowsysteminterface.h>
-
-#include <mir_toolkit/mir_client_library.h>
-
-class QMirClientClientIntegration;
-class QMirClientWindow;
-
-class QMirClientInput : public QObject
-{
- Q_OBJECT
-
-public:
- QMirClientInput(QMirClientClientIntegration* integration);
- virtual ~QMirClientInput();
-
- // QObject methods.
- void customEvent(QEvent* event) override;
-
- void postEvent(QMirClientWindow* window, const MirEvent *event);
- QMirClientClientIntegration* integration() const { return mIntegration; }
- QMirClientWindow *lastInputWindow() const {return mLastInputWindow; }
-
-protected:
- void dispatchKeyEvent(QMirClientWindow *window, const MirInputEvent *event);
- void dispatchPointerEvent(QMirClientWindow *window, const MirInputEvent *event);
- void dispatchTouchEvent(QMirClientWindow *window, const MirInputEvent *event);
- void dispatchInputEvent(QMirClientWindow *window, const MirInputEvent *event);
-
- void dispatchOrientationEvent(QWindow* window, const MirOrientationEvent *event);
- void handleSurfaceEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceEvent *event);
- void handleSurfaceOutputEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceOutputEvent *event);
-
-private:
- QMirClientClientIntegration* mIntegration;
- QTouchDevice* mTouchDevice;
- const QByteArray mEventFilterType;
- const QEvent::Type mEventType;
-
- QMirClientWindow *mLastInputWindow;
-};
-
-#endif // QMIRCLIENTINPUT_H
diff --git a/src/plugins/platforms/mirclient/qmirclientintegration.cpp b/src/plugins/platforms/mirclient/qmirclientintegration.cpp
deleted file mode 100644
index eef96ee3de..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientintegration.cpp
+++ /dev/null
@@ -1,411 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014-2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-// Local
-#include "qmirclientintegration.h"
-#include "qmirclientbackingstore.h"
-#include "qmirclientclipboard.h"
-#include "qmirclientdebugextension.h"
-#include "qmirclientdesktopwindow.h"
-#include "qmirclientglcontext.h"
-#include "qmirclientinput.h"
-#include "qmirclientlogging.h"
-#include "qmirclientnativeinterface.h"
-#include "qmirclientscreen.h"
-#include "qmirclienttheme.h"
-#include "qmirclientwindow.h"
-
-// Qt
-#include <QFileInfo>
-#include <QGuiApplication>
-#include <qpa/qplatformnativeinterface.h>
-#include <qpa/qplatforminputcontextfactory_p.h>
-#include <qpa/qplatforminputcontext.h>
-#include <QtEglSupport/private/qeglconvenience_p.h>
-#include <QtEglSupport/private/qeglpbuffer_p.h>
-#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
-#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
-#ifndef QT_NO_ACCESSIBILITY
-#include <qpa/qplatformaccessibility.h>
-#ifndef QT_NO_ACCESSIBILITY_ATSPI_BRIDGE
-#include <QtLinuxAccessibilitySupport/private/bridge_p.h>
-#endif
-#endif
-
-#include <QOpenGLContext>
-#include <QOffscreenSurface>
-
-// platform-api
-#include <ubuntu/application/lifecycle_delegate.h>
-#include <ubuntu/application/id.h>
-#include <ubuntu/application/options.h>
-
-static void resumedCallback(const UApplicationOptions */*options*/, void* context)
-{
- auto integration = static_cast<QMirClientClientIntegration*>(context);
- integration->appStateController()->setResumed();
-}
-
-static void aboutToStopCallback(UApplicationArchive */*archive*/, void* context)
-{
- auto integration = static_cast<QMirClientClientIntegration*>(context);
- auto inputContext = integration->inputContext();
- if (inputContext) {
- inputContext->hideInputPanel();
- } else {
- qCWarning(mirclient) << "aboutToStopCallback(): no input context";
- }
- integration->appStateController()->setSuspended();
-}
-
-QMirClientClientIntegration::QMirClientClientIntegration(int argc, char **argv)
- : QPlatformIntegration()
- , mNativeInterface(new QMirClientNativeInterface(this))
- , mFontDb(new QGenericUnixFontDatabase)
- , mServices(new QMirClientPlatformServices)
- , mAppStateController(new QMirClientAppStateController)
- , mScaleFactor(1.0)
-{
- {
- QStringList args = QCoreApplication::arguments();
- setupOptions(args);
- QByteArray sessionName = generateSessionName(args);
- setupDescription(sessionName);
- }
-
- // Create new application instance
- mInstance = u_application_instance_new_from_description_with_options(mDesc, mOptions);
-
- if (Q_UNLIKELY(!mInstance))
- qFatal("QMirClientClientIntegration: connection to Mir server failed. Check that a Mir server is\n"
- "running, and the correct socket is being used and is accessible. The shell may have\n"
- "rejected the incoming connection, so check its log file");
-
- mMirConnection = u_application_instance_get_mir_connection(mInstance);
-
- // Choose the default surface format suited to the Mir platform
- QSurfaceFormat defaultFormat;
- defaultFormat.setRedBufferSize(8);
- defaultFormat.setGreenBufferSize(8);
- defaultFormat.setBlueBufferSize(8);
- QSurfaceFormat::setDefaultFormat(defaultFormat);
-
- // Initialize EGL.
- mEglNativeDisplay = mir_connection_get_egl_native_display(mMirConnection);
- ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY);
- ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE);
-
- // Has debug mode been requsted, either with "-testability" switch or QT_LOAD_TESTABILITY env var
- bool testability = qEnvironmentVariableIsSet("QT_LOAD_TESTABILITY");
- for (int i=1; !testability && i<argc; i++) {
- if (strcmp(argv[i], "-testability") == 0) {
- testability = true;
- }
- }
- if (testability) {
- mDebugExtension.reset(new QMirClientDebugExtension);
- }
-}
-
-void QMirClientClientIntegration::initialize()
-{
- // Init the ScreenObserver
- mScreenObserver.reset(new QMirClientScreenObserver(mMirConnection));
- connect(mScreenObserver.data(), &QMirClientScreenObserver::screenAdded,
- [this](QMirClientScreen *screen) { this->screenAdded(screen); });
- connect(mScreenObserver.data(), &QMirClientScreenObserver::screenRemoved,
- this, &QMirClientClientIntegration::destroyScreen);
-
- Q_FOREACH (auto screen, mScreenObserver->screens()) {
- screenAdded(screen);
- }
-
- // Initialize input.
- mInput = new QMirClientInput(this);
- mInputContext = QPlatformInputContextFactory::create();
-
- // compute the scale factor
- const int defaultGridUnit = 8;
- int gridUnit = defaultGridUnit;
- QByteArray gridUnitString = qgetenv("GRID_UNIT_PX");
- if (!gridUnitString.isEmpty()) {
- bool ok;
- gridUnit = gridUnitString.toInt(&ok);
- if (!ok) {
- gridUnit = defaultGridUnit;
- }
- }
- mScaleFactor = static_cast<qreal>(gridUnit) / defaultGridUnit;
-}
-
-QMirClientClientIntegration::~QMirClientClientIntegration()
-{
- eglTerminate(mEglDisplay);
- delete mInput;
- delete mInputContext;
- delete mServices;
-}
-
-QPlatformServices *QMirClientClientIntegration::services() const
-{
- return mServices;
-}
-
-void QMirClientClientIntegration::setupOptions(QStringList &args)
-{
- int argc = args.size() + 1;
- char **argv = new char*[argc];
- for (int i = 0; i < argc - 1; i++)
- argv[i] = qstrdup(args.at(i).toLocal8Bit());
- argv[argc - 1] = nullptr;
-
- mOptions = u_application_options_new_from_cmd_line(argc - 1, argv);
-
- for (int i = 0; i < argc; i++)
- delete [] argv[i];
- delete [] argv;
-}
-
-void QMirClientClientIntegration::setupDescription(QByteArray &sessionName)
-{
- mDesc = u_application_description_new();
-
- UApplicationId* id = u_application_id_new_from_stringn(sessionName.data(), sessionName.count());
- u_application_description_set_application_id(mDesc, id);
-
- UApplicationLifecycleDelegate* delegate = u_application_lifecycle_delegate_new();
- u_application_lifecycle_delegate_set_application_resumed_cb(delegate, &resumedCallback);
- u_application_lifecycle_delegate_set_application_about_to_stop_cb(delegate, &aboutToStopCallback);
- u_application_lifecycle_delegate_set_context(delegate, this);
- u_application_description_set_application_lifecycle_delegate(mDesc, delegate);
-}
-
-QByteArray QMirClientClientIntegration::generateSessionName(QStringList &args)
-{
- // Try to come up with some meaningful session name to uniquely identify this session,
- // helping with shell debugging
-
- if (args.count() == 0) {
- return QByteArray("QtUbuntu");
- } if (args[0].contains("qmlscene")) {
- return generateSessionNameFromQmlFile(args);
- } else {
- // use the executable name
- QFileInfo fileInfo(args[0]);
- return fileInfo.fileName().toLocal8Bit();
- }
-}
-
-QByteArray QMirClientClientIntegration::generateSessionNameFromQmlFile(QStringList &args)
-{
- Q_FOREACH (QString arg, args) {
- if (arg.endsWith(".qml")) {
- QFileInfo fileInfo(arg);
- return fileInfo.fileName().toLocal8Bit();
- }
- }
-
- // give up
- return "qmlscene";
-}
-
-QPlatformWindow* QMirClientClientIntegration::createPlatformWindow(QWindow* window) const
-{
- if (window->type() == Qt::Desktop) {
- // Desktop windows should not be backed up by a mir surface as they don't draw anything (nor should).
- return new QMirClientDesktopWindow(window);
- } else {
- return new QMirClientWindow(window, mInput, mNativeInterface, mAppStateController.data(),
- mEglDisplay, mMirConnection, mDebugExtension.data());
- }
-}
-
-bool QMirClientClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const
-{
- switch (cap) {
- case ThreadedOpenGL:
- if (qEnvironmentVariableIsEmpty("QTUBUNTU_NO_THREADED_OPENGL")) {
- return true;
- } else {
- qCDebug(mirclient, "disabled threaded OpenGL");
- return false;
- }
-
- case ThreadedPixmaps:
- case OpenGL:
- case ApplicationState:
- case MultipleWindows:
- case NonFullScreenWindows:
-#if QT_VERSION > QT_VERSION_CHECK(5, 5, 0)
- case SwitchableWidgetComposition:
-#endif
- case RasterGLSurface: // needed for QQuickWidget
- return true;
- default:
- return QPlatformIntegration::hasCapability(cap);
- }
-}
-
-QAbstractEventDispatcher *QMirClientClientIntegration::createEventDispatcher() const
-{
- return createUnixEventDispatcher();
-}
-
-QPlatformBackingStore* QMirClientClientIntegration::createPlatformBackingStore(QWindow* window) const
-{
- return new QMirClientBackingStore(window);
-}
-
-QPlatformOpenGLContext* QMirClientClientIntegration::createPlatformOpenGLContext(
- QOpenGLContext* context) const
-{
- QSurfaceFormat format(context->format());
-
- auto platformContext = new QMirClientOpenGLContext(format, context->shareHandle(), mEglDisplay);
- if (!platformContext->isValid()) {
- // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default
- // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a
- // 1.4 context, but the XCB EGL backend tries to honor it, and fails. The 1.4 context appears to
- // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default
- // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455).
- static const bool isMesa = QString(eglQueryString(mEglDisplay, EGL_VENDOR)).contains(QStringLiteral("Mesa"));
- if (isMesa) {
- qCDebug(mirclientGraphics, "Attempting to choose OpenGL 1.4 context which may suit Mesa");
- format.setMajorVersion(1);
- format.setMinorVersion(4);
- delete platformContext;
- platformContext = new QMirClientOpenGLContext(format, context->shareHandle(), mEglDisplay);
- }
- }
- return platformContext;
-}
-
-QStringList QMirClientClientIntegration::themeNames() const
-{
- return QStringList(QMirClientTheme::name);
-}
-
-QPlatformTheme* QMirClientClientIntegration::createPlatformTheme(const QString& name) const
-{
- Q_UNUSED(name);
- return new QMirClientTheme;
-}
-
-QVariant QMirClientClientIntegration::styleHint(StyleHint hint) const
-{
- switch (hint) {
- case QPlatformIntegration::StartDragDistance: {
- // default is 10 pixels (see QPlatformTheme::defaultThemeHint)
- return 10.0 * mScaleFactor;
- }
- case QPlatformIntegration::PasswordMaskDelay: {
- // return time in milliseconds - 1 second
- return QVariant(1000);
- }
- default:
- break;
- }
- return QPlatformIntegration::styleHint(hint);
-}
-
-QPlatformClipboard* QMirClientClientIntegration::clipboard() const
-{
- static QPlatformClipboard *clipboard = nullptr;
- if (!clipboard) {
- clipboard = new QMirClientClipboard;
- }
- return clipboard;
-}
-
-QPlatformNativeInterface* QMirClientClientIntegration::nativeInterface() const
-{
- return mNativeInterface;
-}
-
-QPlatformOffscreenSurface *QMirClientClientIntegration::createPlatformOffscreenSurface(
- QOffscreenSurface *surface) const
-{
- return new QEGLPbuffer(mEglDisplay, surface->requestedFormat(), surface);
-}
-
-void QMirClientClientIntegration::destroyScreen(QMirClientScreen *screen)
-{
- // FIXME: on deleting a screen while a Window is on it, Qt will automatically
- // move the window to the primaryScreen(). This will trigger a screenChanged
- // signal, causing things like QQuickScreenAttached to re-fetch screen properties
- // like DPI and physical size. However this is crashing, as Qt is calling virtual
- // functions on QPlatformScreen, for reasons unclear. As workaround, move window
- // to primaryScreen() before deleting the screen. Might be QTBUG-38650
-
- QScreen *primaryScreen = QGuiApplication::primaryScreen();
- if (screen != primaryScreen->handle()) {
- uint32_t movedWindowCount = 0;
- Q_FOREACH (QWindow *w, QGuiApplication::topLevelWindows()) {
- if (w->screen()->handle() == screen) {
- QWindowSystemInterface::handleWindowScreenChanged(w, primaryScreen);
- ++movedWindowCount;
- }
- }
- if (movedWindowCount > 0) {
- QWindowSystemInterface::flushWindowSystemEvents();
- }
- }
-
- qCDebug(mirclient) << "Removing Screen with id" << screen->mirOutputId() << "and geometry" << screen->geometry();
-#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
- delete screen;
-#else
- QPlatformIntegration::destroyScreen(screen);
-#endif
-}
-
-#ifndef QT_NO_ACCESSIBILITY
-QPlatformAccessibility *QMirClientClientIntegration::accessibility() const
-{
-#if !defined(QT_NO_ACCESSIBILITY_ATSPI_BRIDGE)
- if (!mAccessibility) {
- Q_ASSERT_X(QCoreApplication::eventDispatcher(), "QMirClientIntegration",
- "Initializing accessibility without event-dispatcher!");
- mAccessibility.reset(new QSpiAccessibleBridge());
- }
-#endif
- return mAccessibility.data();
-}
-#endif
diff --git a/src/plugins/platforms/mirclient/qmirclientintegration.h b/src/plugins/platforms/mirclient/qmirclientintegration.h
deleted file mode 100644
index 035117f4da..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientintegration.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTINTEGRATION_H
-#define QMIRCLIENTINTEGRATION_H
-
-#include <qpa/qplatformintegration.h>
-#include <QSharedPointer>
-
-#include "qmirclientappstatecontroller.h"
-#include "qmirclientplatformservices.h"
-#include "qmirclientscreenobserver.h"
-
-// platform-api
-#include <ubuntu/application/description.h>
-#include <ubuntu/application/instance.h>
-
-#include <EGL/egl.h>
-
-class QMirClientDebugExtension;
-class QMirClientInput;
-class QMirClientNativeInterface;
-class QMirClientScreen;
-class MirConnection;
-
-class QMirClientClientIntegration : public QObject, public QPlatformIntegration
-{
- Q_OBJECT
-
-public:
- QMirClientClientIntegration(int argc, char **argv);
- virtual ~QMirClientClientIntegration();
-
- // QPlatformIntegration methods.
- bool hasCapability(QPlatformIntegration::Capability cap) const override;
- QAbstractEventDispatcher *createEventDispatcher() const override;
- QPlatformNativeInterface* nativeInterface() const override;
- QPlatformBackingStore* createPlatformBackingStore(QWindow* window) const override;
- QPlatformOpenGLContext* createPlatformOpenGLContext(QOpenGLContext* context) const override;
- QPlatformFontDatabase* fontDatabase() const override { return mFontDb; }
- QStringList themeNames() const override;
- QPlatformTheme* createPlatformTheme(const QString& name) const override;
- QVariant styleHint(StyleHint hint) const override;
- QPlatformServices *services() const override;
- QPlatformWindow* createPlatformWindow(QWindow* window) const override;
- QPlatformInputContext* inputContext() const override { return mInputContext; }
- QPlatformClipboard* clipboard() const override;
- void initialize() override;
- QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override;
- QPlatformAccessibility *accessibility() const override;
-
- // New methods.
- MirConnection *mirConnection() const { return mMirConnection; }
- EGLDisplay eglDisplay() const { return mEglDisplay; }
- EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; }
- QMirClientAppStateController *appStateController() const { return mAppStateController.data(); }
- QMirClientScreenObserver *screenObserver() const { return mScreenObserver.data(); }
- QMirClientDebugExtension *debugExtension() const { return mDebugExtension.data(); }
-
-private Q_SLOTS:
- void destroyScreen(QMirClientScreen *screen);
-
-private:
- void setupOptions(QStringList &args);
- void setupDescription(QByteArray &sessionName);
- static QByteArray generateSessionName(QStringList &args);
- static QByteArray generateSessionNameFromQmlFile(QStringList &args);
-
- QMirClientNativeInterface* mNativeInterface;
- QPlatformFontDatabase* mFontDb;
-
- QMirClientPlatformServices* mServices;
-
- QMirClientInput* mInput;
- QPlatformInputContext* mInputContext;
- mutable QScopedPointer<QPlatformAccessibility> mAccessibility;
- QScopedPointer<QMirClientDebugExtension> mDebugExtension;
- QScopedPointer<QMirClientScreenObserver> mScreenObserver;
- QScopedPointer<QMirClientAppStateController> mAppStateController;
- qreal mScaleFactor;
-
- MirConnection *mMirConnection;
-
- // Platform API stuff
- UApplicationOptions* mOptions;
- UApplicationDescription* mDesc;
- UApplicationInstance* mInstance;
-
- // EGL related
- EGLDisplay mEglDisplay{EGL_NO_DISPLAY};
- EGLNativeDisplayType mEglNativeDisplay;
-};
-
-#endif // QMIRCLIENTINTEGRATION_H
diff --git a/src/plugins/platforms/mirclient/qmirclientlogging.h b/src/plugins/platforms/mirclient/qmirclientlogging.h
deleted file mode 100644
index 4921864ced..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientlogging.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTLOGGING_H
-#define QMIRCLIENTLOGGING_H
-
-#include <QLoggingCategory>
-
-#define ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop())
-
-Q_DECLARE_LOGGING_CATEGORY(mirclient)
-Q_DECLARE_LOGGING_CATEGORY(mirclientBufferSwap)
-Q_DECLARE_LOGGING_CATEGORY(mirclientInput)
-Q_DECLARE_LOGGING_CATEGORY(mirclientGraphics)
-Q_DECLARE_LOGGING_CATEGORY(mirclientCursor)
-Q_DECLARE_LOGGING_CATEGORY(mirclientDebug)
-
-#endif // QMIRCLIENTLOGGING_H
diff --git a/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp b/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp
deleted file mode 100644
index b85e6fedfa..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-// Local
-#include "qmirclientnativeinterface.h"
-#include "qmirclientscreen.h"
-#include "qmirclientglcontext.h"
-#include "qmirclientwindow.h"
-
-// Qt
-#include <QtGui/private/qguiapplication_p.h>
-#include <QtGui/qopenglcontext.h>
-#include <QtGui/qscreen.h>
-#include <QtCore/QMap>
-
-class UbuntuResourceMap : public QMap<QByteArray, QMirClientNativeInterface::ResourceType>
-{
-public:
- UbuntuResourceMap()
- : QMap<QByteArray, QMirClientNativeInterface::ResourceType>() {
- insert("egldisplay", QMirClientNativeInterface::EglDisplay);
- insert("eglcontext", QMirClientNativeInterface::EglContext);
- insert("nativeorientation", QMirClientNativeInterface::NativeOrientation);
- insert("display", QMirClientNativeInterface::Display);
- insert("mirconnection", QMirClientNativeInterface::MirConnection);
- insert("mirsurface", QMirClientNativeInterface::MirSurface);
- insert("scale", QMirClientNativeInterface::Scale);
- insert("formfactor", QMirClientNativeInterface::FormFactor);
- }
-};
-
-Q_GLOBAL_STATIC(UbuntuResourceMap, ubuntuResourceMap)
-
-QMirClientNativeInterface::QMirClientNativeInterface(const QMirClientClientIntegration *integration)
- : mIntegration(integration)
- , mGenericEventFilterType(QByteArrayLiteral("Event"))
- , mNativeOrientation(nullptr)
-{
-}
-
-QMirClientNativeInterface::~QMirClientNativeInterface()
-{
- delete mNativeOrientation;
- mNativeOrientation = nullptr;
-}
-
-void* QMirClientNativeInterface::nativeResourceForIntegration(const QByteArray &resourceString)
-{
- const QByteArray lowerCaseResource = resourceString.toLower();
-
- if (!ubuntuResourceMap()->contains(lowerCaseResource)) {
- return nullptr;
- }
-
- const ResourceType resourceType = ubuntuResourceMap()->value(lowerCaseResource);
-
- if (resourceType == QMirClientNativeInterface::MirConnection) {
- return mIntegration->mirConnection();
- } else {
- return nullptr;
- }
-}
-
-void* QMirClientNativeInterface::nativeResourceForContext(
- const QByteArray& resourceString, QOpenGLContext* context)
-{
- if (!context)
- return nullptr;
-
- const QByteArray kLowerCaseResource = resourceString.toLower();
-
- if (!ubuntuResourceMap()->contains(kLowerCaseResource))
- return nullptr;
-
- const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource);
-
- if (kResourceType == QMirClientNativeInterface::EglContext)
- return static_cast<QMirClientOpenGLContext*>(context->handle())->eglContext();
- else
- return nullptr;
-}
-
-void* QMirClientNativeInterface::nativeResourceForWindow(const QByteArray& resourceString, QWindow* window)
-{
- const QByteArray kLowerCaseResource = resourceString.toLower();
- if (!ubuntuResourceMap()->contains(kLowerCaseResource))
- return NULL;
- const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource);
-
- switch (kResourceType) {
- case EglDisplay:
- return mIntegration->eglDisplay();
- case NativeOrientation:
- // Return the device's native screen orientation.
- if (window) {
- QMirClientScreen *ubuntuScreen = static_cast<QMirClientScreen*>(window->screen()->handle());
- mNativeOrientation = new Qt::ScreenOrientation(ubuntuScreen->nativeOrientation());
- } else {
- QPlatformScreen *platformScreen = QGuiApplication::primaryScreen()->handle();
- mNativeOrientation = new Qt::ScreenOrientation(platformScreen->nativeOrientation());
- }
- return mNativeOrientation;
- case MirSurface:
- if (window) {
- auto ubuntuWindow = static_cast<QMirClientWindow*>(window->handle());
- if (ubuntuWindow) {
- return ubuntuWindow->mirSurface();
- } else {
- return nullptr;
- }
- } else {
- return nullptr;
- }
- default:
- return nullptr;
- }
-}
-
-void* QMirClientNativeInterface::nativeResourceForScreen(const QByteArray& resourceString, QScreen* screen)
-{
- const QByteArray kLowerCaseResource = resourceString.toLower();
- if (!ubuntuResourceMap()->contains(kLowerCaseResource))
- return NULL;
- const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource);
- if (!screen)
- screen = QGuiApplication::primaryScreen();
- auto ubuntuScreen = static_cast<QMirClientScreen*>(screen->handle());
- if (kResourceType == QMirClientNativeInterface::Display) {
- return mIntegration->eglNativeDisplay();
- // Changes to the following properties are emitted via the QMirClientNativeInterface::screenPropertyChanged
- // signal fired by QMirClientScreen. Connect to this signal for these properties updates.
- // WARNING: code highly thread unsafe!
- } else if (kResourceType == QMirClientNativeInterface::Scale) {
- // In application code, read with:
- // float scale = *reinterpret_cast<float*>(nativeResourceForScreen("scale", screen()));
- return &ubuntuScreen->mScale;
- } else if (kResourceType == QMirClientNativeInterface::FormFactor) {
- return &ubuntuScreen->mFormFactor;
- } else
- return NULL;
-}
-
-// Changes to these properties are emitted via the QMirClientNativeInterface::windowPropertyChanged
-// signal fired by QMirClientWindow. Connect to this signal for these properties updates.
-QVariantMap QMirClientNativeInterface::windowProperties(QPlatformWindow *window) const
-{
- QVariantMap propertyMap;
- auto w = static_cast<QMirClientWindow*>(window);
- if (w) {
- propertyMap.insert("scale", w->scale());
- propertyMap.insert("formFactor", w->formFactor());
- }
- return propertyMap;
-}
-
-QVariant QMirClientNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const
-{
- auto w = static_cast<QMirClientWindow*>(window);
- if (!w) {
- return QVariant();
- }
-
- if (name == QStringLiteral("scale")) {
- return w->scale();
- } else if (name == QStringLiteral("formFactor")) {
- return w->formFactor();
- } else {
- return QVariant();
- }
-}
-
-QVariant QMirClientNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const
-{
- QVariant returnVal = windowProperty(window, name);
- if (!returnVal.isValid()) {
- return defaultValue;
- } else {
- return returnVal;
- }
-}
diff --git a/src/plugins/platforms/mirclient/qmirclientnativeinterface.h b/src/plugins/platforms/mirclient/qmirclientnativeinterface.h
deleted file mode 100644
index eb601de301..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientnativeinterface.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTNATIVEINTERFACE_H
-#define QMIRCLIENTNATIVEINTERFACE_H
-
-#include <qpa/qplatformnativeinterface.h>
-
-#include "qmirclientintegration.h"
-
-class QPlatformScreen;
-
-class QMirClientNativeInterface : public QPlatformNativeInterface {
- Q_OBJECT
-public:
- enum ResourceType { EglDisplay, EglContext, NativeOrientation, Display, MirConnection, MirSurface, Scale, FormFactor };
-
- QMirClientNativeInterface(const QMirClientClientIntegration *integration);
- ~QMirClientNativeInterface();
-
- // QPlatformNativeInterface methods.
- void* nativeResourceForIntegration(const QByteArray &resource) override;
- void* nativeResourceForContext(const QByteArray& resourceString,
- QOpenGLContext* context) override;
- void* nativeResourceForWindow(const QByteArray& resourceString,
- QWindow* window) override;
- void* nativeResourceForScreen(const QByteArray& resourceString,
- QScreen* screen) override;
-
- QVariantMap windowProperties(QPlatformWindow *window) const override;
- QVariant windowProperty(QPlatformWindow *window, const QString &name) const override;
- QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const override;
-
- // New methods.
- const QByteArray& genericEventFilterType() const { return mGenericEventFilterType; }
-
-Q_SIGNALS: // New signals
- void screenPropertyChanged(QPlatformScreen *screen, const QString &propertyName);
-
-private:
- const QMirClientClientIntegration *mIntegration;
- const QByteArray mGenericEventFilterType;
- Qt::ScreenOrientation* mNativeOrientation;
-};
-
-#endif // QMIRCLIENTNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h b/src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h
deleted file mode 100644
index 5abd3262dc..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientorientationchangeevent_p.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTORIENTATIONCHANGEEVENT_P_H
-#define QMIRCLIENTORIENTATIONCHANGEEVENT_P_H
-
-#include <QEvent>
-#include "qmirclientlogging.h"
-
-class OrientationChangeEvent : public QEvent {
-public:
- enum Orientation { TopUp, LeftUp, TopDown, RightUp };
-
- OrientationChangeEvent(QEvent::Type type, Orientation orientation)
- : QEvent(type)
- , mOrientation(orientation)
- {
- }
-
- static const QEvent::Type mType;
- Orientation mOrientation;
-};
-
-#endif // QMIRCLIENTORIENTATIONCHANGEEVENT_P_H
diff --git a/src/plugins/platforms/mirclient/qmirclientplatformservices.cpp b/src/plugins/platforms/mirclient/qmirclientplatformservices.cpp
deleted file mode 100644
index 1ccd57fc28..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientplatformservices.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qmirclientplatformservices.h"
-
-#include <QUrl>
-
-#include <ubuntu/application/url_dispatcher/service.h>
-#include <ubuntu/application/url_dispatcher/session.h>
-
-bool QMirClientPlatformServices::openUrl(const QUrl &url)
-{
- return callDispatcher(url);
-}
-
-bool QMirClientPlatformServices::openDocument(const QUrl &url)
-{
- return callDispatcher(url);
-}
-
-bool QMirClientPlatformServices::callDispatcher(const QUrl &url)
-{
- UAUrlDispatcherSession* session = ua_url_dispatcher_session();
- if (!session)
- return false;
-
- ua_url_dispatcher_session_open(session, url.toEncoded().constData(), NULL, NULL);
-
- free(session);
-
- // We are returning true here because the other option
- // is spawning a nested event loop and wait for the
- // callback. But there is no guarantee on how fast
- // the callback is going to be so we prefer to avoid the
- // nested event loop. Long term plan is improve Qt API
- // to support an async openUrl
- return true;
-}
diff --git a/src/plugins/platforms/mirclient/qmirclientplatformservices.h b/src/plugins/platforms/mirclient/qmirclientplatformservices.h
deleted file mode 100644
index a1cd5758ca..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientplatformservices.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTPLATFORMSERVICES_H
-#define QMIRCLIENTPLATFORMSERVICES_H
-
-#include <qpa/qplatformservices.h>
-#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
-#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
-
-class QMirClientPlatformServices : public QPlatformServices {
-public:
- bool openUrl(const QUrl &url) override;
- bool openDocument(const QUrl &url) override;
-
-private:
- bool callDispatcher(const QUrl &url);
-};
-
-#endif // QMIRCLIENTPLATFORMSERVICES_H
diff --git a/src/plugins/platforms/mirclient/qmirclientplugin.cpp b/src/plugins/platforms/mirclient/qmirclientplugin.cpp
deleted file mode 100644
index fc44edfe40..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientplugin.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qmirclientplugin.h"
-#include "qmirclientintegration.h"
-#include "qmirclientlogging.h"
-
-Q_LOGGING_CATEGORY(mirclient, "qt.qpa.mirclient", QtWarningMsg)
-
-QPlatformIntegration *QMirClientIntegrationPlugin::create(const QString &system,
- const QStringList &/*paramList*/,
- int &argc, char **argv)
-{
- if (system.toLower() == QLatin1String("mirclient")) {
- return new QMirClientClientIntegration(argc, argv);
- } else {
- return 0;
- }
-}
diff --git a/src/plugins/platforms/mirclient/qmirclientplugin.h b/src/plugins/platforms/mirclient/qmirclientplugin.h
deleted file mode 100644
index 207d97b5af..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientplugin.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTPLUGIN_H
-#define QMIRCLIENTPLUGIN_H
-
-#include <qpa/qplatformintegrationplugin.h>
-
-class QMirClientIntegrationPlugin : public QPlatformIntegrationPlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "mirclient.json")
-
-public:
- QPlatformIntegration *create(const QString &system, const QStringList &paramList,
- int &argc, char **argv) override;
-};
-
-#endif // QMIRCLIENTPLUGIN_H
diff --git a/src/plugins/platforms/mirclient/qmirclientscreen.cpp b/src/plugins/platforms/mirclient/qmirclientscreen.cpp
deleted file mode 100644
index cc8db830aa..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientscreen.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014-2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-// local
-#include "qmirclientscreen.h"
-#include "qmirclientlogging.h"
-#include "qmirclientorientationchangeevent_p.h"
-#include "qmirclientnativeinterface.h"
-
-#include <mir_toolkit/mir_client_library.h>
-
-// Qt
-#include <QGuiApplication>
-#include <QtCore/qmath.h>
-#include <QScreen>
-#include <QThread>
-#include <qpa/qwindowsysteminterface.h>
-#include <QtEglSupport/private/qeglconvenience_p.h>
-
-#include <memory>
-
-static const int overrideDevicePixelRatio = qgetenv("QT_DEVICE_PIXEL_RATIO").toInt();
-
-static const char *orientationToStr(Qt::ScreenOrientation orientation) {
- switch (orientation) {
- case Qt::PrimaryOrientation:
- return "primary";
- case Qt::PortraitOrientation:
- return "portrait";
- case Qt::LandscapeOrientation:
- return "landscape";
- case Qt::InvertedPortraitOrientation:
- return "inverted portrait";
- case Qt::InvertedLandscapeOrientation:
- return "inverted landscape";
- }
- Q_UNREACHABLE();
-}
-
-const QEvent::Type OrientationChangeEvent::mType =
- static_cast<QEvent::Type>(QEvent::registerEventType());
-
-
-QMirClientScreen::QMirClientScreen(const MirOutput *output, MirConnection *connection)
- : mDevicePixelRatio(1.0)
- , mFormat(QImage::Format_RGB32)
- , mDepth(32)
- , mDpi{0}
- , mFormFactor{mir_form_factor_unknown}
- , mScale{1.0}
- , mOutputId(0)
- , mCursor(connection)
-{
- setMirOutput(output);
-}
-
-QMirClientScreen::~QMirClientScreen()
-{
-}
-
-void QMirClientScreen::customEvent(QEvent* event) {
- Q_ASSERT(QThread::currentThread() == thread());
-
- OrientationChangeEvent* oReadingEvent = static_cast<OrientationChangeEvent*>(event);
- switch (oReadingEvent->mOrientation) {
- case OrientationChangeEvent::LeftUp: {
- mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ?
- Qt::InvertedPortraitOrientation : Qt::LandscapeOrientation;
- break;
- }
- case OrientationChangeEvent::TopUp: {
- mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ?
- Qt::LandscapeOrientation : Qt::PortraitOrientation;
- break;
- }
- case OrientationChangeEvent::RightUp: {
- mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ?
- Qt::PortraitOrientation : Qt::InvertedLandscapeOrientation;
- break;
- }
- case OrientationChangeEvent::TopDown: {
- mCurrentOrientation = (screen()->primaryOrientation() == Qt::LandscapeOrientation) ?
- Qt::InvertedLandscapeOrientation : Qt::InvertedPortraitOrientation;
- break;
- }
- }
-
- // Raise the event signal so that client apps know the orientation changed
- qCDebug(mirclient, "QMirClientScreen::customEvent - handling orientation change to %s", orientationToStr(mCurrentOrientation));
- QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation);
-}
-
-void QMirClientScreen::handleWindowSurfaceResize(int windowWidth, int windowHeight)
-{
- if ((windowWidth > windowHeight && mGeometry.width() < mGeometry.height())
- || (windowWidth < windowHeight && mGeometry.width() > mGeometry.height())) {
-
- // The window aspect ratio differ's from the screen one. This means that
- // unity8 has rotated the window in its scene.
- // As there's no way to express window rotation in Qt's API, we have
- // Flip QScreen's dimensions so that orientation properties match
- // (primaryOrientation particularly).
- // FIXME: This assumes a phone scenario. Won't work, or make sense,
- // on the desktop
-
- QRect currGeometry = mGeometry;
- mGeometry.setWidth(currGeometry.height());
- mGeometry.setHeight(currGeometry.width());
-
- qCDebug(mirclient, "QMirClientScreen::handleWindowSurfaceResize - new screen geometry (w=%d, h=%d)",
- mGeometry.width(), mGeometry.height());
- QWindowSystemInterface::handleScreenGeometryChange(screen(),
- mGeometry /* newGeometry */,
- mGeometry /* newAvailableGeometry */);
-
- if (mGeometry.width() < mGeometry.height()) {
- mCurrentOrientation = Qt::PortraitOrientation;
- } else {
- mCurrentOrientation = Qt::LandscapeOrientation;
- }
- qCDebug(mirclient, "QMirClientScreen::handleWindowSurfaceResize - new orientation %s",orientationToStr(mCurrentOrientation));
- QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation);
- }
-}
-
-void QMirClientScreen::setMirOutput(const MirOutput *output)
-{
- // Physical screen size (in mm)
- mPhysicalSize.setWidth(mir_output_get_physical_width_mm(output));
- mPhysicalSize.setHeight(mir_output_get_physical_height_mm(output));
-
- // Pixel Format
-// mFormat = qImageFormatFromMirPixelFormat(mir_output_get_current_pixel_format(output)); // GERRY: TODO
-
- // Pixel depth
- mDepth = 8 * MIR_BYTES_PER_PIXEL(mir_output_get_current_pixel_format(output));
-
- // Mode = Resolution & refresh rate
- const MirOutputMode *mode = mir_output_get_current_mode(output);
- mNativeGeometry.setX(mir_output_get_position_x(output));
- mNativeGeometry.setY(mir_output_get_position_y(output));
- mNativeGeometry.setWidth(mir_output_mode_get_width(mode));
- mNativeGeometry.setHeight(mir_output_mode_get_height(mode));
-
- mRefreshRate = mir_output_mode_get_refresh_rate(mode);
-
- // UI scale & DPR
- mScale = mir_output_get_scale_factor(output);
- if (overrideDevicePixelRatio > 0) {
- mDevicePixelRatio = overrideDevicePixelRatio;
- } else {
- mDevicePixelRatio = 1.0; // FIXME - need to determine suitable DPR for the specified scale
- }
-
- mFormFactor = mir_output_get_form_factor(output);
-
- mOutputId = mir_output_get_id(output);
-
- mGeometry.setX(mNativeGeometry.x());
- mGeometry.setY(mNativeGeometry.y());
- mGeometry.setWidth(mNativeGeometry.width());
- mGeometry.setHeight(mNativeGeometry.height());
-
- // Set the default orientation based on the initial screen dimensions.
- mNativeOrientation = (mGeometry.width() >= mGeometry.height()) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
-
- // If it's a landscape device (i.e. some tablets), start in landscape, otherwise portrait
- mCurrentOrientation = (mNativeOrientation == Qt::LandscapeOrientation) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
-}
-
-void QMirClientScreen::updateMirOutput(const MirOutput *output)
-{
- auto oldRefreshRate = mRefreshRate;
- auto oldScale = mScale;
- auto oldFormFactor = mFormFactor;
- auto oldGeometry = mGeometry;
-
- setMirOutput(output);
-
- // Emit change signals in particular order
- if (oldGeometry != mGeometry) {
- QWindowSystemInterface::handleScreenGeometryChange(screen(),
- mGeometry /* newGeometry */,
- mGeometry /* newAvailableGeometry */);
- }
-
- if (!qFuzzyCompare(mRefreshRate, oldRefreshRate)) {
- QWindowSystemInterface::handleScreenRefreshRateChange(screen(), mRefreshRate);
- }
-
- auto nativeInterface = static_cast<QMirClientNativeInterface *>(qGuiApp->platformNativeInterface());
- if (!qFuzzyCompare(mScale, oldScale)) {
- nativeInterface->screenPropertyChanged(this, QStringLiteral("scale"));
- }
- if (mFormFactor != oldFormFactor) {
- nativeInterface->screenPropertyChanged(this, QStringLiteral("formFactor"));
- }
-}
-
-void QMirClientScreen::setAdditionalMirDisplayProperties(float scale, MirFormFactor formFactor, int dpi)
-{
- if (mDpi != dpi) {
- mDpi = dpi;
- QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), dpi, dpi);
- }
-
- auto nativeInterface = static_cast<QMirClientNativeInterface *>(qGuiApp->platformNativeInterface());
- if (!qFuzzyCompare(mScale, scale)) {
- mScale = scale;
- nativeInterface->screenPropertyChanged(this, QStringLiteral("scale"));
- }
- if (mFormFactor != formFactor) {
- mFormFactor = formFactor;
- nativeInterface->screenPropertyChanged(this, QStringLiteral("formFactor"));
- }
-}
-
-QDpi QMirClientScreen::logicalDpi() const
-{
- if (mDpi > 0) {
- return QDpi(mDpi, mDpi);
- } else {
- return QPlatformScreen::logicalDpi();
- }
-}
diff --git a/src/plugins/platforms/mirclient/qmirclientscreen.h b/src/plugins/platforms/mirclient/qmirclientscreen.h
deleted file mode 100644
index b31cba1964..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientscreen.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014-2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTSCREEN_H
-#define QMIRCLIENTSCREEN_H
-
-#include <qpa/qplatformscreen.h>
-#include <QSurfaceFormat>
-
-#include <mir_toolkit/common.h> // just for MirFormFactor enum
-
-#include "qmirclientcursor.h"
-
-struct MirConnection;
-struct MirOutput;
-
-class QMirClientScreen : public QObject, public QPlatformScreen
-{
- Q_OBJECT
-public:
- QMirClientScreen(const MirOutput *output, MirConnection *connection);
- virtual ~QMirClientScreen();
-
- // QPlatformScreen methods.
- QImage::Format format() const override { return mFormat; }
- int depth() const override { return mDepth; }
- QRect geometry() const override { return mGeometry; }
- QRect availableGeometry() const override { return mGeometry; }
- QSizeF physicalSize() const override { return mPhysicalSize; }
- qreal devicePixelRatio() const override { return mDevicePixelRatio; }
- QDpi logicalDpi() const override;
- Qt::ScreenOrientation nativeOrientation() const override { return mNativeOrientation; }
- Qt::ScreenOrientation orientation() const override { return mNativeOrientation; }
- QPlatformCursor *cursor() const override { return const_cast<QMirClientCursor*>(&mCursor); }
-
- // Additional Screen properties from Mir
- int mirOutputId() const { return mOutputId; }
- MirFormFactor formFactor() const { return mFormFactor; }
- float scale() const { return mScale; }
-
- // Internally used methods
- void updateMirOutput(const MirOutput *output);
- void setAdditionalMirDisplayProperties(float scale, MirFormFactor formFactor, int dpi);
- void handleWindowSurfaceResize(int width, int height);
-
- // QObject methods.
- void customEvent(QEvent* event) override;
-
-private:
- void setMirOutput(const MirOutput *output);
-
- QRect mGeometry, mNativeGeometry;
- QSizeF mPhysicalSize;
- qreal mDevicePixelRatio;
- Qt::ScreenOrientation mNativeOrientation;
- Qt::ScreenOrientation mCurrentOrientation;
- QImage::Format mFormat;
- int mDepth;
- int mDpi;
- qreal mRefreshRate;
- MirFormFactor mFormFactor;
- float mScale;
- int mOutputId;
- QMirClientCursor mCursor;
-
- friend class QMirClientNativeInterface;
-};
-
-#endif // QMIRCLIENTSCREEN_H
diff --git a/src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp b/src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp
deleted file mode 100644
index 792aeca351..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qmirclientscreenobserver.h"
-#include "qmirclientscreen.h"
-#include "qmirclientwindow.h"
-#include "qmirclientlogging.h"
-
-// Qt
-#include <QMetaObject>
-#include <QPointer>
-
-// Mir
-#include <mirclient/mir_toolkit/mir_connection.h>
-#include <mirclient/mir_toolkit/mir_display_configuration.h>
-
-#include <memory>
-
-namespace {
- static void displayConfigurationChangedCallback(MirConnection */*connection*/, void* context)
- {
- ASSERT(context != NULL);
- QMirClientScreenObserver *observer = static_cast<QMirClientScreenObserver *>(context);
- QMetaObject::invokeMethod(observer, "update");
- }
-
- const char *mirFormFactorToStr(MirFormFactor formFactor)
- {
- switch (formFactor) {
- case mir_form_factor_unknown: return "unknown";
- case mir_form_factor_phone: return "phone";
- case mir_form_factor_tablet: return "tablet";
- case mir_form_factor_monitor: return "monitor";
- case mir_form_factor_tv: return "tv";
- case mir_form_factor_projector: return "projector";
- }
- Q_UNREACHABLE();
- }
-} // anonymous namespace
-
-QMirClientScreenObserver::QMirClientScreenObserver(MirConnection *mirConnection)
- : mMirConnection(mirConnection)
-{
- mir_connection_set_display_config_change_callback(mirConnection, ::displayConfigurationChangedCallback, this);
- update();
-}
-
-void QMirClientScreenObserver::update()
-{
- // Wrap MirDisplayConfiguration to always delete when out of scope
- auto configDeleter = [](MirDisplayConfig *config) { mir_display_config_release(config); };
- using configUp = std::unique_ptr<MirDisplayConfig, decltype(configDeleter)>;
- configUp displayConfig(mir_connection_create_display_configuration(mMirConnection), configDeleter);
-
- // Mir only tells us something changed, it is up to us to figure out what.
- QList<QMirClientScreen*> newScreenList;
- QList<QMirClientScreen*> oldScreenList = mScreenList;
- mScreenList.clear();
-
- for (int i = 0; i < mir_display_config_get_num_outputs(displayConfig.get()); i++) {
- const MirOutput *output = mir_display_config_get_output(displayConfig.get(), i);
- if (mir_output_is_enabled(output)) {
- QMirClientScreen *screen = findScreenWithId(oldScreenList, mir_output_get_id(output));
- if (screen) { // we've already set up this display before
- screen->updateMirOutput(output);
- oldScreenList.removeAll(screen);
- } else {
- // new display, so create QMirClientScreen for it
- screen = new QMirClientScreen(output, mMirConnection);
- newScreenList.append(screen);
- qCDebug(mirclient) << "Added Screen with id" << mir_output_get_id(output)
- << "and geometry" << screen->geometry();
- }
- mScreenList.append(screen);
- }
- }
-
- // Announce old & unused Screens, should be deleted by the slot
- Q_FOREACH (const auto screen, oldScreenList) {
- Q_EMIT screenRemoved(screen);
- }
-
- /*
- * Mir's MirDisplayOutput does not include formFactor or scale for some reason, but Qt
- * will want that information on creating the QScreen. Only way we get that info is when
- * Mir positions a Window on that Screen. See "handleScreenPropertiesChange" method
- */
-
- // Announce new Screens
- Q_FOREACH (const auto screen, newScreenList) {
- Q_EMIT screenAdded(screen);
- }
-
- qCDebug(mirclient) << "=======================================";
- for (auto screen: mScreenList) {
- qCDebug(mirclient) << screen << "- id:" << screen->mirOutputId()
- << "geometry:" << screen->geometry()
- << "form factor:" << mirFormFactorToStr(screen->formFactor())
- << "scale:" << screen->scale();
- }
- qCDebug(mirclient) << "=======================================";
-}
-
-QMirClientScreen *QMirClientScreenObserver::findScreenWithId(int id)
-{
- return findScreenWithId(mScreenList, id);
-}
-
-QMirClientScreen *QMirClientScreenObserver::findScreenWithId(const QList<QMirClientScreen *> &list, int id)
-{
- Q_FOREACH (const auto screen, list) {
- if (screen->mirOutputId() == id) {
- return screen;
- }
- }
- return nullptr;
-}
-
-void QMirClientScreenObserver::handleScreenPropertiesChange(QMirClientScreen *screen, int dpi,
- MirFormFactor formFactor, float scale)
-{
- screen->setAdditionalMirDisplayProperties(scale, formFactor, dpi);
-}
-
diff --git a/src/plugins/platforms/mirclient/qmirclienttheme.cpp b/src/plugins/platforms/mirclient/qmirclienttheme.cpp
deleted file mode 100644
index dcfef7ca67..0000000000
--- a/src/plugins/platforms/mirclient/qmirclienttheme.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#include "qmirclienttheme.h"
-
-#include <QtCore/QVariant>
-
-const char *QMirClientTheme::name = "ubuntu";
-
-QMirClientTheme::QMirClientTheme()
-{
-}
-
-QMirClientTheme::~QMirClientTheme()
-{
-}
-
-QVariant QMirClientTheme::themeHint(ThemeHint hint) const
-{
- if (hint == QPlatformTheme::SystemIconThemeName) {
- QByteArray iconTheme = qgetenv("QTUBUNTU_ICON_THEME");
- if (iconTheme.isEmpty()) {
- return QVariant(QStringLiteral("ubuntu-mobile"));
- } else {
- return QVariant(QString(iconTheme));
- }
- } else {
- return QGenericUnixTheme::themeHint(hint);
- }
-}
diff --git a/src/plugins/platforms/mirclient/qmirclienttheme.h b/src/plugins/platforms/mirclient/qmirclienttheme.h
deleted file mode 100644
index 4bab1d0ee0..0000000000
--- a/src/plugins/platforms/mirclient/qmirclienttheme.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTTHEME_H
-#define QMIRCLIENTTHEME_H
-
-#include <QtThemeSupport/private/qgenericunixthemes_p.h>
-
-class QMirClientTheme : public QGenericUnixTheme
-{
-public:
- static const char* name;
- QMirClientTheme();
- virtual ~QMirClientTheme();
-
- // From QPlatformTheme
- QVariant themeHint(ThemeHint hint) const override;
-};
-
-#endif // QMIRCLIENTTHEME_H
diff --git a/src/plugins/platforms/mirclient/qmirclientwindow.cpp b/src/plugins/platforms/mirclient/qmirclientwindow.cpp
deleted file mode 100644
index decd21516e..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientwindow.cpp
+++ /dev/null
@@ -1,968 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014-2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-// Local
-#include "qmirclientwindow.h"
-#include "qmirclientdebugextension.h"
-#include "qmirclientnativeinterface.h"
-#include "qmirclientinput.h"
-#include "qmirclientintegration.h"
-#include "qmirclientscreen.h"
-#include "qmirclientlogging.h"
-
-#include <mir_toolkit/mir_client_library.h>
-#include <mir_toolkit/version.h>
-
-// Qt
-#include <qpa/qwindowsysteminterface.h>
-#include <QMutexLocker>
-#include <QSize>
-#include <QtMath>
-#include <QtEglSupport/private/qeglconvenience_p.h>
-
-// Platform API
-#include <ubuntu/application/instance.h>
-
-#include <EGL/egl.h>
-
-Q_LOGGING_CATEGORY(mirclientBufferSwap, "qt.qpa.mirclient.bufferSwap", QtWarningMsg)
-
-namespace
-{
-const Qt::WindowType LowChromeWindowHint = (Qt::WindowType)0x00800000;
-
-// FIXME: this used to be defined by platform-api, but it's been removed in v3. Change ubuntu-keyboard to use
-// a different enum for window roles.
-enum UAUiWindowRole {
- U_MAIN_ROLE = 1,
- U_DASH_ROLE,
- U_INDICATOR_ROLE,
- U_NOTIFICATIONS_ROLE,
- U_GREETER_ROLE,
- U_LAUNCHER_ROLE,
- U_ON_SCREEN_KEYBOARD_ROLE,
- U_SHUTDOWN_DIALOG_ROLE,
-};
-
-struct MirSpecDeleter
-{
- void operator()(MirSurfaceSpec *spec) { mir_surface_spec_release(spec); }
-};
-
-using Spec = std::unique_ptr<MirSurfaceSpec, MirSpecDeleter>;
-
-EGLNativeWindowType nativeWindowFor(MirSurface *surf)
-{
- auto stream = mir_surface_get_buffer_stream(surf);
- return reinterpret_cast<EGLNativeWindowType>(mir_buffer_stream_get_egl_native_window(stream));
-}
-
-const char *qtWindowStateToStr(Qt::WindowState state)
-{
- switch (state) {
- case Qt::WindowNoState:
- return "NoState";
- case Qt::WindowFullScreen:
- return "FullScreen";
- case Qt::WindowMaximized:
- return "Maximized";
- case Qt::WindowMinimized:
- return "Minimized";
- case Qt::WindowActive:
- return "Active";
- }
- Q_UNREACHABLE();
-}
-
-const char *mirSurfaceStateToStr(MirSurfaceState surfaceState)
-{
- switch (surfaceState) {
- case mir_surface_state_unknown: return "unknown";
- case mir_surface_state_restored: return "restored";
- case mir_surface_state_minimized: return "minimized";
- case mir_surface_state_maximized: return "vertmaximized";
- case mir_surface_state_vertmaximized: return "vertmaximized";
- case mir_surface_state_fullscreen: return "fullscreen";
- case mir_surface_state_horizmaximized: return "horizmaximized";
- case mir_surface_state_hidden: return "hidden";
- case mir_surface_states: Q_UNREACHABLE();
- }
- Q_UNREACHABLE();
-}
-
-const char *mirPixelFormatToStr(MirPixelFormat pixelFormat)
-{
- switch (pixelFormat) {
- case mir_pixel_format_invalid: return "invalid";
- case mir_pixel_format_abgr_8888: return "ABGR8888";
- case mir_pixel_format_xbgr_8888: return "XBGR8888";
- case mir_pixel_format_argb_8888: return "ARGB8888";
- case mir_pixel_format_xrgb_8888: return "XRGB8888";
- case mir_pixel_format_bgr_888: return "BGR888";
- case mir_pixel_format_rgb_888: return "RGB888";
- case mir_pixel_format_rgb_565: return "RGB565";
- case mir_pixel_format_rgba_5551: return "RGBA5551";
- case mir_pixel_format_rgba_4444: return "RGBA4444";
- case mir_pixel_formats: Q_UNREACHABLE();
- }
- Q_UNREACHABLE();
-}
-
-const char *mirSurfaceTypeToStr(MirSurfaceType type)
-{
- switch (type) {
- case mir_surface_type_normal: return "Normal"; /**< AKA "regular" */
- case mir_surface_type_utility: return "Utility"; /**< AKA "floating regular" */
- case mir_surface_type_dialog: return "Dialog";
- case mir_surface_type_gloss: return "Gloss";
- case mir_surface_type_freestyle: return "Freestyle";
- case mir_surface_type_menu: return "Menu";
- case mir_surface_type_inputmethod: return "Input Method"; /**< AKA "OSK" or handwriting etc. */
- case mir_surface_type_satellite: return "Satellite"; /**< AKA "toolbox"/"toolbar" */
- case mir_surface_type_tip: return "Tip"; /**< AKA "tooltip" */
- case mir_surface_types: Q_UNREACHABLE();
- }
- return "";
-}
-
-MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state)
-{
- switch (state) {
- case Qt::WindowNoState:
- case Qt::WindowActive:
- return mir_surface_state_restored;
- case Qt::WindowFullScreen:
- return mir_surface_state_fullscreen;
- case Qt::WindowMaximized:
- return mir_surface_state_maximized;
- case Qt::WindowMinimized:
- return mir_surface_state_minimized;
- }
- return mir_surface_state_unknown; // should never be reached
-}
-
-MirSurfaceType qtWindowTypeToMirSurfaceType(Qt::WindowType type)
-{
- switch (type & Qt::WindowType_Mask) {
- case Qt::Dialog:
- return mir_surface_type_dialog;
- case Qt::Sheet:
- case Qt::Drawer:
- return mir_surface_type_utility;
- case Qt::Popup:
- case Qt::Tool:
- return mir_surface_type_menu;
- case Qt::ToolTip:
- return mir_surface_type_tip;
- case Qt::SplashScreen:
- return mir_surface_type_freestyle;
- case Qt::Window:
- default:
- return mir_surface_type_normal;
- }
-}
-
-WId makeId()
-{
- static int id = 1;
- return id++;
-}
-
-UAUiWindowRole roleFor(QWindow *window)
-{
- QVariant roleVariant = window->property("role");
- if (!roleVariant.isValid())
- return U_MAIN_ROLE;
-
- uint role = roleVariant.toUInt();
- if (role < U_MAIN_ROLE || role > U_SHUTDOWN_DIALOG_ROLE)
- return U_MAIN_ROLE;
-
- return static_cast<UAUiWindowRole>(role);
-}
-
-QMirClientWindow *transientParentFor(QWindow *window)
-{
- QWindow *parent = window->transientParent();
- return parent ? static_cast<QMirClientWindow *>(parent->handle()) : nullptr;
-}
-
-bool requiresParent(const MirSurfaceType type)
-{
- switch (type) {
- case mir_surface_type_dialog: //FIXME - not quite what the specification dictates, but is what Mir's api dictates
- case mir_surface_type_utility:
- case mir_surface_type_gloss:
- case mir_surface_type_menu:
- case mir_surface_type_satellite:
- case mir_surface_type_tip:
- return true;
- default:
- return false;
- }
-}
-
-bool requiresParent(const Qt::WindowType type)
-{
- return requiresParent(qtWindowTypeToMirSurfaceType(type));
-}
-
-bool isMovable(const Qt::WindowType type)
-{
- auto mirType = qtWindowTypeToMirSurfaceType(type);
- switch (mirType) {
- case mir_surface_type_menu:
- case mir_surface_type_tip:
- return true;
- default:
- return false;
- }
-}
-
-Spec makeSurfaceSpec(QWindow *window, MirPixelFormat pixelFormat, QMirClientWindow *parentWindowHandle,
- MirConnection *connection)
-{
- const auto geometry = window->geometry();
- const int width = geometry.width() > 0 ? geometry.width() : 1;
- const int height = geometry.height() > 0 ? geometry.height() : 1;
- auto type = qtWindowTypeToMirSurfaceType(window->type());
-
- if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) {
- type = mir_surface_type_inputmethod;
- }
-
- MirRectangle location{geometry.x(), geometry.y(), 0, 0};
- MirSurface *parent = nullptr;
- if (parentWindowHandle) {
- parent = parentWindowHandle->mirSurface();
- // Qt uses absolute positioning, but Mir positions surfaces relative to parent.
- location.top -= parentWindowHandle->geometry().top();
- location.left -= parentWindowHandle->geometry().left();
- }
-
- Spec spec;
-
- switch (type) {
- case mir_surface_type_menu:
- spec = Spec{mir_connection_create_spec_for_menu(connection, width, height, pixelFormat, parent,
- &location, mir_edge_attachment_any)};
- break;
- case mir_surface_type_dialog:
- spec = Spec{mir_connection_create_spec_for_modal_dialog(connection, width, height, pixelFormat, parent)};
- break;
- case mir_surface_type_utility:
- spec = Spec{mir_connection_create_spec_for_dialog(connection, width, height, pixelFormat)};
- break;
- case mir_surface_type_tip:
-#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 4, 0)
- spec = Spec{mir_connection_create_spec_for_tooltip(connection, width, height, pixelFormat, parent,
- &location)};
-#else
- spec = Spec{mir_connection_create_spec_for_tip(connection, width, height, pixelFormat, parent,
- &location, mir_edge_attachment_any)};
-#endif
- break;
- case mir_surface_type_inputmethod:
- spec = Spec{mir_connection_create_spec_for_input_method(connection, width, height, pixelFormat)};
- break;
- default:
- spec = Spec{mir_connection_create_spec_for_normal_surface(connection, width, height, pixelFormat)};
- break;
- }
-
- qCDebug(mirclient, "makeSurfaceSpec(window=%p): %s spec (type=0x%x, position=(%d, %d)px, size=(%dx%d)px)",
- window, mirSurfaceTypeToStr(type), window->type(), location.left, location.top, width, height);
-
- return std::move(spec);
-}
-
-void setSizingConstraints(MirSurfaceSpec *spec, const QSize& minSize, const QSize& maxSize, const QSize& increment)
-{
- mir_surface_spec_set_min_width(spec, minSize.width());
- mir_surface_spec_set_min_height(spec, minSize.height());
- if (maxSize.width() >= minSize.width()) {
- mir_surface_spec_set_max_width(spec, maxSize.width());
- }
- if (maxSize.height() >= minSize.height()) {
- mir_surface_spec_set_max_height(spec, maxSize.height());
- }
- if (increment.width() > 0) {
- mir_surface_spec_set_width_increment(spec, increment.width());
- }
- if (increment.height() > 0) {
- mir_surface_spec_set_height_increment(spec, increment.height());
- }
-}
-
-MirSurface *createMirSurface(QWindow *window, int mirOutputId, QMirClientWindow *parentWindowHandle,
- MirPixelFormat pixelFormat, MirConnection *connection,
- mir_surface_event_callback inputCallback, void *inputContext)
-{
- auto spec = makeSurfaceSpec(window, pixelFormat, parentWindowHandle, connection);
-
- // Install event handler as early as possible
- mir_surface_spec_set_event_handler(spec.get(), inputCallback, inputContext);
-
- const auto title = window->title().toUtf8();
- mir_surface_spec_set_name(spec.get(), title.constData());
-
- setSizingConstraints(spec.get(), window->minimumSize(), window->maximumSize(), window->sizeIncrement());
-
- if (window->windowState() == Qt::WindowFullScreen) {
- mir_surface_spec_set_fullscreen_on_output(spec.get(), mirOutputId);
- }
-
- if (window->flags() & LowChromeWindowHint) {
- mir_surface_spec_set_shell_chrome(spec.get(), mir_shell_chrome_low);
- }
-
- if (!window->isVisible()) {
- mir_surface_spec_set_state(spec.get(), mir_surface_state_hidden);
- }
-
- auto surface = mir_surface_create_sync(spec.get());
- Q_ASSERT(mir_surface_is_valid(surface));
- return surface;
-}
-
-QMirClientWindow *getParentIfNecessary(QWindow *window, QMirClientInput *input)
-{
- QMirClientWindow *parentWindowHandle = nullptr;
- if (requiresParent(window->type())) {
- parentWindowHandle = transientParentFor(window);
- if (parentWindowHandle == nullptr) {
- // NOTE: Mir requires this surface have a parent. Try using the last surface to receive input as that will
- // most likely be the one that caused this surface to be created
- parentWindowHandle = input->lastInputWindow();
- }
- }
- return parentWindowHandle;
-}
-
-MirPixelFormat disableAlphaBufferIfPossible(MirPixelFormat pixelFormat)
-{
- switch (pixelFormat) {
- case mir_pixel_format_abgr_8888:
- return mir_pixel_format_xbgr_8888;
- case mir_pixel_format_argb_8888:
- return mir_pixel_format_xrgb_8888;
- default: // can do nothing, leave it alone
- return pixelFormat;
- }
-}
-} //namespace
-
-
-
-class UbuntuSurface
-{
-public:
- UbuntuSurface(QMirClientWindow *platformWindow, EGLDisplay display, QMirClientInput *input, MirConnection *connection);
- ~UbuntuSurface();
-
- UbuntuSurface(const UbuntuSurface &) = delete;
- UbuntuSurface& operator=(const UbuntuSurface &) = delete;
-
- void updateGeometry(const QRect &newGeometry);
- void updateTitle(const QString& title);
- void setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment);
-
- void onSwapBuffersDone();
- void handleSurfaceResized(int width, int height);
- int needsRepaint() const;
-
- MirSurfaceState state() const { return mir_surface_get_state(mMirSurface); }
- void setState(MirSurfaceState state);
-
- MirSurfaceType type() const { return mir_surface_get_type(mMirSurface); }
-
- void setShellChrome(MirShellChrome shellChrome);
-
- EGLSurface eglSurface() const { return mEglSurface; }
- MirSurface *mirSurface() const { return mMirSurface; }
-
- void setSurfaceParent(MirSurface*);
- bool hasParent() const { return mParented; }
-
- QSurfaceFormat format() const { return mFormat; }
-
- bool mNeedsExposeCatchup;
-
- QString persistentSurfaceId();
-
-private:
- static void surfaceEventCallback(MirSurface* surface, const MirEvent *event, void* context);
- void postEvent(const MirEvent *event);
-
- QWindow * const mWindow;
- QMirClientWindow * const mPlatformWindow;
- QMirClientInput * const mInput;
- MirConnection * const mConnection;
- QMirClientWindow * mParentWindowHandle{nullptr};
-
- MirSurface* mMirSurface;
- const EGLDisplay mEglDisplay;
- EGLSurface mEglSurface;
-
- bool mNeedsRepaint;
- bool mParented;
- QSize mBufferSize;
- QSurfaceFormat mFormat;
- MirPixelFormat mPixelFormat;
-
- QMutex mTargetSizeMutex;
- QSize mTargetSize;
- MirShellChrome mShellChrome;
- QString mPersistentIdStr;
-};
-
-UbuntuSurface::UbuntuSurface(QMirClientWindow *platformWindow, EGLDisplay display, QMirClientInput *input, MirConnection *connection)
- : mWindow(platformWindow->window())
- , mPlatformWindow(platformWindow)
- , mInput(input)
- , mConnection(connection)
- , mEglDisplay(display)
- , mNeedsRepaint(false)
- , mParented(mWindow->transientParent() || mWindow->parent())
- , mFormat(mWindow->requestedFormat())
- , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal)
-{
- // Have Qt choose most suitable EGLConfig for the requested surface format, and update format to reflect it
- EGLConfig config = q_configFromGLFormat(display, mFormat, true);
- if (config == 0) {
- // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default
- // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a
- // 1.4 context, but the XCB EGL backend tries to honor it, and fails. The 1.4 context appears to
- // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default
- // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455).
- static const bool isMesa = QString(eglQueryString(display, EGL_VENDOR)).contains(QStringLiteral("Mesa"));
- if (isMesa) {
- qCDebug(mirclientGraphics, "Attempting to choose OpenGL 1.4 context which may suit Mesa");
- mFormat.setMajorVersion(1);
- mFormat.setMinorVersion(4);
- config = q_configFromGLFormat(display, mFormat, true);
- }
- }
- if (config == 0) {
- qCritical() << "Qt failed to choose a suitable EGLConfig to suit the surface format" << mFormat;
- }
-
- mFormat = q_glFormatFromConfig(display, config, mFormat);
-
- // Have Mir decide the pixel format most suited to the chosen EGLConfig. This is the only way
- // Mir will know what EGLConfig has been chosen - it cannot deduce it from the buffers.
- mPixelFormat = mir_connection_get_egl_pixel_format(connection, display, config);
- // But the chosen EGLConfig might have an alpha buffer enabled, even if not requested by the client.
- // If that's the case, try to edit the chosen pixel format in order to disable the alpha buffer.
- // This is an optimization for the compositor, as it can avoid blending this surface.
- if (mWindow->requestedFormat().alphaBufferSize() < 0) {
- mPixelFormat = disableAlphaBufferIfPossible(mPixelFormat);
- }
-
- const auto outputId = static_cast<QMirClientScreen *>(mWindow->screen()->handle())->mirOutputId();
-
- mParentWindowHandle = getParentIfNecessary(mWindow, input);
-
- mMirSurface = createMirSurface(mWindow, outputId, mParentWindowHandle, mPixelFormat, connection, surfaceEventCallback, this);
- mEglSurface = eglCreateWindowSurface(mEglDisplay, config, nativeWindowFor(mMirSurface), nullptr);
-
- mNeedsExposeCatchup = mir_surface_get_visibility(mMirSurface) == mir_surface_visibility_occluded;
-
- // Window manager can give us a final size different from what we asked for
- // so let's check what we ended up getting
- MirSurfaceParameters parameters;
- mir_surface_get_parameters(mMirSurface, &parameters);
-
- auto geom = mWindow->geometry();
- geom.setWidth(parameters.width);
- geom.setHeight(parameters.height);
-
- // Assume that the buffer size matches the surface size at creation time
- mBufferSize = geom.size();
- QWindowSystemInterface::handleGeometryChange(mWindow, geom);
-
- qCDebug(mirclient) << "Created surface with geometry:" << geom << "title:" << mWindow->title()
- << "role:" << roleFor(mWindow);
- qCDebug(mirclientGraphics)
- << "Requested format:" << mWindow->requestedFormat()
- << "\nActual format:" << mFormat
- << "with associated Mir pixel format:" << mirPixelFormatToStr(mPixelFormat);
-}
-
-UbuntuSurface::~UbuntuSurface()
-{
- if (mEglSurface != EGL_NO_SURFACE)
- eglDestroySurface(mEglDisplay, mEglSurface);
- if (mMirSurface) {
- mir_surface_release_sync(mMirSurface);
- }
-}
-
-void UbuntuSurface::updateGeometry(const QRect &newGeometry)
-{
- qCDebug(mirclient,"updateGeometry(window=%p, width=%d, height=%d)", mWindow,
- newGeometry.width(), newGeometry.height());
-
- Spec spec;
- if (isMovable(mWindow->type())) {
- spec = Spec{makeSurfaceSpec(mWindow, mPixelFormat, mParentWindowHandle, mConnection)};
- } else {
- spec = Spec{mir_connection_create_spec_for_changes(mConnection)};
- mir_surface_spec_set_width(spec.get(), newGeometry.width());
- mir_surface_spec_set_height(spec.get(), newGeometry.height());
- }
- mir_surface_apply_spec(mMirSurface, spec.get());
-}
-
-void UbuntuSurface::updateTitle(const QString& newTitle)
-{
- const auto title = newTitle.toUtf8();
- Spec spec{mir_connection_create_spec_for_changes(mConnection)};
- mir_surface_spec_set_name(spec.get(), title.constData());
- mir_surface_apply_spec(mMirSurface, spec.get());
-}
-
-void UbuntuSurface::setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment)
-{
- Spec spec{mir_connection_create_spec_for_changes(mConnection)};
- ::setSizingConstraints(spec.get(), minSize, maxSize, increment);
- mir_surface_apply_spec(mMirSurface, spec.get());
-}
-
-void UbuntuSurface::handleSurfaceResized(int width, int height)
-{
- QMutexLocker lock(&mTargetSizeMutex);
-
- // mir's resize event is mainly a signal that we need to redraw our content. We use the
- // width/height as identifiers to figure out if this is the latest surface resize event
- // that has posted, discarding any old ones. This avoids issuing too many redraw events.
- // see TODO in postEvent as the ideal way we should handle this.
- // The actual buffer size may or may have not changed at this point, so let the rendering
- // thread drive the window geometry updates.
- mNeedsRepaint = mTargetSize.width() == width && mTargetSize.height() == height;
-}
-
-int UbuntuSurface::needsRepaint() const
-{
- if (mNeedsRepaint) {
- if (mTargetSize != mBufferSize) {
- //If the buffer hasn't changed yet, we need at least two redraws,
- //once to get the new buffer size and propagate the geometry changes
- //and the second to redraw the content at the new size
- return 2;
- } else {
- // The buffer size has already been updated so we only need one redraw
- // to render at the new size
- return 1;
- }
- }
- return 0;
-}
-
-void UbuntuSurface::setState(MirSurfaceState state)
-{
- mir_wait_for(mir_surface_set_state(mMirSurface, state));
-}
-
-void UbuntuSurface::setShellChrome(MirShellChrome chrome)
-{
- if (chrome != mShellChrome) {
- auto spec = Spec{mir_connection_create_spec_for_changes(mConnection)};
- mir_surface_spec_set_shell_chrome(spec.get(), chrome);
- mir_surface_apply_spec(mMirSurface, spec.get());
-
- mShellChrome = chrome;
- }
-}
-
-void UbuntuSurface::onSwapBuffersDone()
-{
- static int sFrameNumber = 0;
- ++sFrameNumber;
-
- EGLint eglSurfaceWidth = -1;
- EGLint eglSurfaceHeight = -1;
- eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &eglSurfaceWidth);
- eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &eglSurfaceHeight);
-
- const bool validSize = eglSurfaceWidth > 0 && eglSurfaceHeight > 0;
-
- if (validSize && (mBufferSize.width() != eglSurfaceWidth || mBufferSize.height() != eglSurfaceHeight)) {
-
- qCDebug(mirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - size changed (%d, %d) => (%d, %d)",
- mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height(), eglSurfaceWidth, eglSurfaceHeight);
-
- mBufferSize.rwidth() = eglSurfaceWidth;
- mBufferSize.rheight() = eglSurfaceHeight;
-
- QRect newGeometry = mPlatformWindow->geometry();
- newGeometry.setSize(mBufferSize);
-
- QWindowSystemInterface::handleGeometryChange(mWindow, newGeometry);
- } else {
- qCDebug(mirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - buffer size (%d,%d)",
- mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height());
- }
-}
-
-void UbuntuSurface::surfaceEventCallback(MirSurface *surface, const MirEvent *event, void* context)
-{
- Q_UNUSED(surface);
- Q_ASSERT(context != nullptr);
-
- auto s = static_cast<UbuntuSurface *>(context);
- s->postEvent(event);
-}
-
-void UbuntuSurface::postEvent(const MirEvent *event)
-{
- if (mir_event_type_resize == mir_event_get_type(event)) {
- // TODO: The current event queue just accumulates all resize events;
- // It would be nicer if we could update just one event if that event has not been dispatched.
- // As a workaround, we use the width/height as an identifier of this latest event
- // so the event handler (handleSurfaceResized) can discard/ignore old ones.
- const auto resizeEvent = mir_event_get_resize_event(event);
- const auto width = mir_resize_event_get_width(resizeEvent);
- const auto height = mir_resize_event_get_height(resizeEvent);
- qCDebug(mirclient, "resizeEvent(window=%p, width=%d, height=%d)", mWindow, width, height);
-
- QMutexLocker lock(&mTargetSizeMutex);
- mTargetSize.rwidth() = width;
- mTargetSize.rheight() = height;
- }
-
- mInput->postEvent(mPlatformWindow, event);
-}
-
-void UbuntuSurface::setSurfaceParent(MirSurface* parent)
-{
- qCDebug(mirclient, "setSurfaceParent(window=%p)", mWindow);
-
- mParented = true;
- Spec spec{mir_connection_create_spec_for_changes(mConnection)};
- mir_surface_spec_set_parent(spec.get(), parent);
- mir_surface_apply_spec(mMirSurface, spec.get());
-}
-
-QString UbuntuSurface::persistentSurfaceId()
-{
- if (mPersistentIdStr.isEmpty()) {
- MirPersistentId* mirPermaId = mir_surface_request_persistent_id_sync(mMirSurface);
- mPersistentIdStr = mir_persistent_id_as_string(mirPermaId);
- mir_persistent_id_release(mirPermaId);
- }
- return mPersistentIdStr;
-}
-
-QMirClientWindow::QMirClientWindow(QWindow *w, QMirClientInput *input, QMirClientNativeInterface *native,
- QMirClientAppStateController *appState, EGLDisplay eglDisplay,
- MirConnection *mirConnection, QMirClientDebugExtension *debugExt)
- : QObject(nullptr)
- , QPlatformWindow(w)
- , mId(makeId())
- , mWindowState(w->windowState())
- , mWindowFlags(w->flags())
- , mWindowVisible(false)
- , mAppStateController(appState)
- , mDebugExtention(debugExt)
- , mNativeInterface(native)
- , mSurface(new UbuntuSurface{this, eglDisplay, input, mirConnection})
- , mScale(1.0)
- , mFormFactor(mir_form_factor_unknown)
-{
- mWindowExposed = mSurface->mNeedsExposeCatchup == false;
-
- qCDebug(mirclient, "QMirClientWindow(window=%p, screen=%p, input=%p, surf=%p) with title '%s', role: '%d'",
- w, w->screen()->handle(), input, mSurface.get(), qPrintable(window()->title()), roleFor(window()));
-}
-
-QMirClientWindow::~QMirClientWindow()
-{
- qCDebug(mirclient, "~QMirClientWindow(window=%p)", this);
-}
-
-void QMirClientWindow::handleSurfaceResized(int width, int height)
-{
- QMutexLocker lock(&mMutex);
- qCDebug(mirclient, "handleSurfaceResize(window=%p, size=(%dx%d)px", window(), width, height);
-
- mSurface->handleSurfaceResized(width, height);
-
- // This resize event could have occurred just after the last buffer swap for this window.
- // This means the client may still be holding a buffer with the older size. The first redraw call
- // will then render at the old size. After swapping the client now will get a new buffer with the
- // updated size but it still needs re-rendering so another redraw may be needed.
- // A mir API to drop the currently held buffer would help here, so that we wouldn't have to redraw twice
- auto const numRepaints = mSurface->needsRepaint();
- lock.unlock();
- qCDebug(mirclient, "handleSurfaceResize(window=%p) redraw %d times", window(), numRepaints);
- for (int i = 0; i < numRepaints; i++) {
- qCDebug(mirclient, "handleSurfaceResize(window=%p) repainting size=(%dx%d)dp", window(), geometry().size().width(), geometry().size().height());
- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
- }
-}
-
-void QMirClientWindow::handleSurfaceExposeChange(bool exposed)
-{
- QMutexLocker lock(&mMutex);
- qCDebug(mirclient, "handleSurfaceExposeChange(window=%p, exposed=%s)", window(), exposed ? "true" : "false");
-
- mSurface->mNeedsExposeCatchup = false;
- if (mWindowExposed == exposed) return;
- mWindowExposed = exposed;
-
- lock.unlock();
- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
-}
-
-void QMirClientWindow::handleSurfaceFocusChanged(bool focused)
-{
- qCDebug(mirclient, "handleSurfaceFocusChanged(window=%p, focused=%d)", window(), focused);
- if (focused) {
- mAppStateController->setWindowFocused(true);
- QWindowSystemInterface::handleWindowActivated(window(), Qt::ActiveWindowFocusReason);
- } else {
- mAppStateController->setWindowFocused(false);
- }
-}
-
-void QMirClientWindow::handleSurfaceVisibilityChanged(bool visible)
-{
- qCDebug(mirclient, "handleSurfaceVisibilityChanged(window=%p, visible=%d)", window(), visible);
-
- if (mWindowVisible == visible) return;
- mWindowVisible = visible;
-
- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
-}
-
-void QMirClientWindow::handleSurfaceStateChanged(Qt::WindowState state)
-{
- qCDebug(mirclient, "handleSurfaceStateChanged(window=%p, %s)", window(), qtWindowStateToStr(state));
-
- if (mWindowState == state) return;
- mWindowState = state;
-
- QWindowSystemInterface::handleWindowStateChanged(window(), state);
-}
-
-void QMirClientWindow::setWindowState(Qt::WindowStates states)
-{
- Qt::WindowState state = Qt::WindowNoState;
- if (states & Qt::WindowMinimized)
- state = Qt::WindowMinimized;
- else if (states & Qt::WindowFullScreen)
- state = Qt::WindowFullScreen;
- else if (states & Qt::WindowMaximized)
- state = Qt::WindowMaximized;
-
- QMutexLocker lock(&mMutex);
- qCDebug(mirclient, "setWindowState(window=%p, %s)", this, qtWindowStateToStr(state));
-
- if (mWindowState == state) return;
- mWindowState = state;
-
- lock.unlock();
- updateSurfaceState();
-}
-
-void QMirClientWindow::setWindowFlags(Qt::WindowFlags flags)
-{
- QMutexLocker lock(&mMutex);
- qCDebug(mirclient, "setWindowFlags(window=%p, 0x%x)", this, (int)flags);
-
- if (mWindowFlags == flags) return;
- mWindowFlags = flags;
-
- mSurface->setShellChrome(mWindowFlags & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal);
-}
-
-QRect QMirClientWindow::geometry() const
-{
- if (mDebugExtention) {
- auto geom = QPlatformWindow::geometry();
- geom.moveTopLeft(mDebugExtention->mapSurfacePointToScreen(mSurface->mirSurface(), QPoint(0,0)));
- return geom;
- } else {
- return QPlatformWindow::geometry();
- }
-}
-
-void QMirClientWindow::setGeometry(const QRect& rect)
-{
- QMutexLocker lock(&mMutex);
-
- if (window()->windowState() == Qt::WindowFullScreen || window()->windowState() == Qt::WindowMaximized) {
- qCDebug(mirclient, "setGeometry(window=%p) - not resizing, window is maximized or fullscreen", window());
- return;
- }
-
- qCDebug(mirclient, "setGeometry (window=%p, position=(%d, %d)dp, size=(%dx%d)dp)",
- window(), rect.x(), rect.y(), rect.width(), rect.height());
- // Immediately update internal geometry so Qt believes position updated
- QRect newPosition(geometry());
- newPosition.moveTo(rect.topLeft());
- QPlatformWindow::setGeometry(newPosition);
-
- mSurface->updateGeometry(rect);
- // Note: don't call handleGeometryChange here, wait to see what Mir replies with.
-}
-
-void QMirClientWindow::setVisible(bool visible)
-{
- QMutexLocker lock(&mMutex);
- qCDebug(mirclient, "setVisible (window=%p, visible=%s)", window(), visible ? "true" : "false");
-
- if (mWindowVisible == visible) return;
- mWindowVisible = visible;
-
- if (visible) {
- if (!mSurface->hasParent() && window()->type() == Qt::Dialog) {
- // The dialog may have been parented after creation time
- // so morph it into a modal dialog
- auto parent = transientParentFor(window());
- if (parent) {
- mSurface->setSurfaceParent(parent->mirSurface());
- }
- }
- }
-
- lock.unlock();
- updateSurfaceState();
- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
-}
-
-void QMirClientWindow::setWindowTitle(const QString& title)
-{
- QMutexLocker lock(&mMutex);
- qCDebug(mirclient, "setWindowTitle(window=%p) title=%s)", window(), title.toUtf8().constData());
- mSurface->updateTitle(title);
-}
-
-void QMirClientWindow::propagateSizeHints()
-{
- QMutexLocker lock(&mMutex);
- const auto win = window();
- qCDebug(mirclient, "propagateSizeHints(window=%p) min(%d,%d), max(%d,%d) increment(%d, %d)",
- win, win->minimumSize().width(), win->minimumSize().height(),
- win->maximumSize().width(), win->maximumSize().height(),
- win->sizeIncrement().width(), win->sizeIncrement().height());
- mSurface->setSizingConstraints(win->minimumSize(), win->maximumSize(), win->sizeIncrement());
-}
-
-bool QMirClientWindow::isExposed() const
-{
- // mNeedsExposeCatchup because we need to render a frame to get the expose surface event from mir.
- return mWindowVisible && (mWindowExposed || (mSurface && mSurface->mNeedsExposeCatchup));
-}
-
-QSurfaceFormat QMirClientWindow::format() const
-{
- return mSurface->format();
-}
-
-QPoint QMirClientWindow::mapToGlobal(const QPoint &pos) const
-{
- if (mDebugExtention) {
- return mDebugExtention->mapSurfacePointToScreen(mSurface->mirSurface(), pos);
- } else {
- return pos;
- }
-}
-
-void* QMirClientWindow::eglSurface() const
-{
- return mSurface->eglSurface();
-}
-
-MirSurface *QMirClientWindow::mirSurface() const
-{
- return mSurface->mirSurface();
-}
-
-WId QMirClientWindow::winId() const
-{
- return mId;
-}
-
-void QMirClientWindow::onSwapBuffersDone()
-{
- QMutexLocker lock(&mMutex);
- mSurface->onSwapBuffersDone();
-
- if (mSurface->mNeedsExposeCatchup) {
- mSurface->mNeedsExposeCatchup = false;
- mWindowExposed = false;
-
- lock.unlock();
- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
- }
-}
-
-void QMirClientWindow::handleScreenPropertiesChange(MirFormFactor formFactor, float scale)
-{
- // Update the scale & form factor native-interface properties for the windows affected
- // as there is no convenient way to emit signals for those custom properties on a QScreen
- if (formFactor != mFormFactor) {
- mFormFactor = formFactor;
- Q_EMIT mNativeInterface->windowPropertyChanged(this, QStringLiteral("formFactor"));
- }
-
- if (!qFuzzyCompare(scale, mScale)) {
- mScale = scale;
- Q_EMIT mNativeInterface->windowPropertyChanged(this, QStringLiteral("scale"));
- }
-}
-
-void QMirClientWindow::updateSurfaceState()
-{
- QMutexLocker lock(&mMutex);
- MirSurfaceState newState = mWindowVisible ? qtWindowStateToMirSurfaceState(mWindowState) :
- mir_surface_state_hidden;
- qCDebug(mirclient, "updateSurfaceState (window=%p, surfaceState=%s)", window(), mirSurfaceStateToStr(newState));
- if (newState != mSurface->state()) {
- mSurface->setState(newState);
- }
-}
-
-QString QMirClientWindow::persistentSurfaceId()
-{
- return mSurface->persistentSurfaceId();
-}
diff --git a/src/plugins/platforms/mirclient/qmirclientwindow.h b/src/plugins/platforms/mirclient/qmirclientwindow.h
deleted file mode 100644
index 6c5695d62f..0000000000
--- a/src/plugins/platforms/mirclient/qmirclientwindow.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014-2016 Canonical, Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-
-#ifndef QMIRCLIENTWINDOW_H
-#define QMIRCLIENTWINDOW_H
-
-#include <qpa/qplatformwindow.h>
-#include <QSharedPointer>
-#include <QMutex>
-
-#include <mir_toolkit/common.h> // needed only for MirFormFactor enum
-
-#include <memory>
-
-#include <EGL/egl.h>
-
-class QMirClientAppStateController;
-class QMirClientDebugExtension;
-class QMirClientNativeInterface;
-class QMirClientInput;
-class QMirClientScreen;
-class UbuntuSurface;
-struct MirSurface;
-class MirConnection;
-
-class QMirClientWindow : public QObject, public QPlatformWindow
-{
- Q_OBJECT
-public:
- QMirClientWindow(QWindow *w, QMirClientInput *input, QMirClientNativeInterface* native,
- QMirClientAppStateController *appState, EGLDisplay eglDisplay,
- MirConnection *mirConnection, QMirClientDebugExtension *debugExt);
- virtual ~QMirClientWindow();
-
- // QPlatformWindow methods.
- WId winId() const override;
- QRect geometry() const override;
- void setGeometry(const QRect&) override;
- void setWindowState(Qt::WindowStates state) override;
- void setWindowFlags(Qt::WindowFlags flags) override;
- void setVisible(bool visible) override;
- void setWindowTitle(const QString &title) override;
- void propagateSizeHints() override;
- bool isExposed() const override;
-
- QPoint mapToGlobal(const QPoint &pos) const override;
- QSurfaceFormat format() const override;
-
- // Additional Window properties exposed by NativeInterface
- MirFormFactor formFactor() const { return mFormFactor; }
- float scale() const { return mScale; }
-
- // New methods.
- void *eglSurface() const;
- MirSurface *mirSurface() const;
- void handleSurfaceResized(int width, int height);
- void handleSurfaceExposeChange(bool exposed);
- void handleSurfaceFocusChanged(bool focused);
- void handleSurfaceVisibilityChanged(bool visible);
- void handleSurfaceStateChanged(Qt::WindowState state);
- void onSwapBuffersDone();
- void handleScreenPropertiesChange(MirFormFactor formFactor, float scale);
- QString persistentSurfaceId();
-
-private:
- void updateSurfaceState();
- mutable QMutex mMutex;
- const WId mId;
- Qt::WindowState mWindowState;
- Qt::WindowFlags mWindowFlags;
- bool mWindowVisible;
- bool mWindowExposed;
- QMirClientAppStateController *mAppStateController;
- QMirClientDebugExtension *mDebugExtention;
- QMirClientNativeInterface *mNativeInterface;
- std::unique_ptr<UbuntuSurface> mSurface;
- float mScale;
- MirFormFactor mFormFactor;
-};
-
-#endif // QMIRCLIENTWINDOW_H
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index acc55adf6f..c4f2b30965 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -48,6 +48,4 @@ haiku {
wasm: SUBDIRS += wasm
-qtConfig(mirclient): SUBDIRS += mirclient
-
qtConfig(integrityfb): SUBDIRS += integrity
diff --git a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
index d9b4a84aa9..1d8af9dbf0 100644
--- a/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
+++ b/src/printsupport/dialogs/qpagesetupdialog_unix.cpp
@@ -361,13 +361,21 @@ void QPageSetupWidget::initPageSizes()
QPlatformPrinterSupport *ps = QPlatformPrinterSupportPlugin::get();
if (ps) {
QPrintDevice printDevice = ps->createPrintDevice(m_printerName);
+ const QPageSize defaultSize = printDevice.defaultPageSize();
const auto pageSizes = printDevice.supportedPageSizes();
for (const QPageSize &pageSize : pageSizes)
m_ui.pageSizeCombo->addItem(pageSize.name(), QVariant::fromValue(pageSize));
- if (m_ui.pageSizeCombo->count() > 0 && printDevice.supportsCustomPageSizes()) {
- m_ui.pageSizeCombo->addItem(tr("Custom"));
- m_realCustomPageSizeIndex = m_ui.pageSizeCombo->count() - 1;
+ if (m_ui.pageSizeCombo->count() > 0) {
+ if (printDevice.supportsCustomPageSizes()) {
+ m_ui.pageSizeCombo->addItem(tr("Custom"));
+ m_realCustomPageSizeIndex = m_ui.pageSizeCombo->count() - 1;
+ }
m_blockSignals = false;
+
+ // If the defaultSize is index 0, setCurrentIndex won't emit the currentIndexChanged
+ // signal; workaround the issue by initially setting the currentIndex to -1
+ m_ui.pageSizeCombo->setCurrentIndex(-1);
+ m_ui.pageSizeCombo->setCurrentIndex(m_ui.pageSizeCombo->findData(QVariant::fromValue(defaultSize)));
return;
}
}
@@ -403,12 +411,6 @@ void QPageSetupWidget::setPrinter(QPrinter *printer, QPrintDevice *printDevice,
// Initialize the layout to the current QPrinter layout
m_pageLayout = m_printer->pageLayout();
- if (printDevice) {
- const QPageSize pageSize = printDevice->defaultPageSize();
- const QMarginsF printable = printDevice->printableMargins(pageSize, m_pageLayout.orientation(), m_printer->resolution());
- m_pageLayout.setPageSize(pageSize, qt_convertMargins(printable, QPageLayout::Point, m_pageLayout.units()));
- }
-
// Assume if margins are Points then is by default, so set to locale default units
if (m_pageLayout.units() == QPageLayout::Point) {
if (QLocale().measurementSystem() == QLocale::MetricSystem)
@@ -735,8 +737,12 @@ int QPageSetupDialog::exec()
Q_D(QPageSetupDialog);
int ret = QDialog::exec();
- if (ret == Accepted)
+ if (ret == Accepted) {
static_cast <QUnixPageSetupDialogPrivate*>(d)->widget->setupPrinter();
+ static_cast <QUnixPageSetupDialogPrivate*>(d)->widget->updateSavedValues();
+ } else {
+ static_cast <QUnixPageSetupDialogPrivate*>(d)->widget->revertToSavedValues();
+ }
return ret;
}
diff --git a/src/printsupport/dialogs/qprintpreviewdialog.cpp b/src/printsupport/dialogs/qprintpreviewdialog.cpp
index e6b665f82c..39575d5f57 100644
--- a/src/printsupport/dialogs/qprintpreviewdialog.cpp
+++ b/src/printsupport/dialogs/qprintpreviewdialog.cpp
@@ -152,8 +152,8 @@ class QPrintPreviewDialogPrivate : public QDialogPrivate
Q_DECLARE_PUBLIC(QPrintPreviewDialog)
public:
QPrintPreviewDialogPrivate()
- : printDialog(nullptr), ownPrinter(false),
- initialized(false) {}
+ : printDialog(nullptr), pageSetupDialog(nullptr),
+ ownPrinter(false), initialized(false) {}
// private slots
void _q_fit(QAction *action);
@@ -178,6 +178,7 @@ public:
void updateZoomFactor();
QPrintDialog *printDialog;
+ QPageSetupDialog *pageSetupDialog;
QPrintPreviewWidget *preview;
QPrinter *printer;
bool ownPrinter;
@@ -494,7 +495,7 @@ void QPrintPreviewDialogPrivate::updatePageNumLabel()
void QPrintPreviewDialogPrivate::updateZoomFactor()
{
- zoomFactor->lineEdit()->setText(QString().sprintf("%.1f%%", preview->zoomFactor()*100));
+ zoomFactor->lineEdit()->setText(QString::asprintf("%.1f%%", preview->zoomFactor()*100));
}
void QPrintPreviewDialogPrivate::_q_fit(QAction* action)
@@ -602,8 +603,10 @@ void QPrintPreviewDialogPrivate::_q_pageSetup()
{
Q_Q(QPrintPreviewDialog);
- QPageSetupDialog pageSetup(printer, q);
- if (pageSetup.exec() == QDialog::Accepted) {
+ if (!pageSetupDialog)
+ pageSetupDialog = new QPageSetupDialog(printer, q);
+
+ if (pageSetupDialog->exec() == QDialog::Accepted) {
// update possible orientation changes
if (preview->orientation() == QPrinter::Portrait) {
portraitAction->setChecked(true);
@@ -713,6 +716,7 @@ QPrintPreviewDialog::~QPrintPreviewDialog()
if (d->ownPrinter)
delete d->printer;
delete d->printDialog;
+ delete d->pageSetupDialog;
}
/*!
diff --git a/src/testlib/qsignaldumper.cpp b/src/testlib/qsignaldumper.cpp
index 8305c5d424..b3360b4e6c 100644
--- a/src/testlib/qsignaldumper.cpp
+++ b/src/testlib/qsignaldumper.cpp
@@ -170,13 +170,12 @@ void QSignalDumper::startDump()
{
static QSignalSpyCallbackSet set = { QTest::qSignalDumperCallback,
QTest::qSignalDumperCallbackSlot, QTest::qSignalDumperCallbackEndSignal, 0 };
- qt_register_signal_spy_callbacks(set);
+ qt_register_signal_spy_callbacks(&set);
}
void QSignalDumper::endDump()
{
- static QSignalSpyCallbackSet nset = { 0, 0, 0 ,0 };
- qt_register_signal_spy_callbacks(nset);
+ qt_register_signal_spy_callbacks(nullptr);
}
void QSignalDumper::ignoreClass(const QByteArray &klass)
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 1f69429053..a010ea467b 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -2519,6 +2519,20 @@ bool QTest::compare_helper(bool success, const char *failureMsg,
return QTestResult::compare(success, failureMsg, val1, val2, actual, expected, file, line);
}
+template <typename T>
+static bool floatingCompare(const T &t1, const T &t2)
+{
+ switch (std::fpclassify(t1))
+ {
+ case FP_INFINITE:
+ return (t1 < 0) == (t2 < 0) && std::fpclassify(t2) == FP_INFINITE;
+ case FP_NAN:
+ return std::fpclassify(t2) == FP_NAN;
+ default:
+ return qFuzzyCompare(t1, t2);
+ }
+}
+
/*! \fn bool QTest::qCompare(const qfloat16 &t1, const qfloat16 &t2, const char *actual, const char *expected, const char *file, int line)
\internal
*/
@@ -2535,16 +2549,8 @@ bool QTest::qCompare(qfloat16 const &t1, qfloat16 const &t2, const char *actual,
bool QTest::qCompare(float const &t1, float const &t2, const char *actual, const char *expected,
const char *file, int line)
{
- bool equal = false;
- int cl1 = std::fpclassify(t1);
- int cl2 = std::fpclassify(t2);
- if (cl1 == FP_INFINITE)
- equal = ((t1 < 0) == (t2 < 0)) && cl2 == FP_INFINITE;
- else if (cl1 == FP_NAN)
- equal = (cl2 == FP_NAN);
- else
- equal = qFuzzyCompare(t1, t2);
- return compare_helper(equal, "Compared floats are not the same (fuzzy compare)",
+ return compare_helper(floatingCompare(t1, t2),
+ "Compared floats are not the same (fuzzy compare)",
toString(t1), toString(t2), actual, expected, file, line);
}
@@ -2554,16 +2560,8 @@ bool QTest::qCompare(float const &t1, float const &t2, const char *actual, const
bool QTest::qCompare(double const &t1, double const &t2, const char *actual, const char *expected,
const char *file, int line)
{
- bool equal = false;
- int cl1 = std::fpclassify(t1);
- int cl2 = std::fpclassify(t2);
- if (cl1 == FP_INFINITE)
- equal = ((t1 < 0) == (t2 < 0)) && cl2 == FP_INFINITE;
- else if (cl1 == FP_NAN)
- equal = (cl2 == FP_NAN);
- else
- equal = qFuzzyCompare(t1, t2);
- return compare_helper(equal, "Compared doubles are not the same (fuzzy compare)",
+ return compare_helper(floatingCompare(t1, t2),
+ "Compared doubles are not the same (fuzzy compare)",
toString(t1), toString(t2), actual, expected, file, line);
}
@@ -2641,7 +2639,7 @@ template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE>(const TYPE &t) \
qstrncpy(msg, "nan", 128); \
break; \
default: \
- qsnprintf(msg, 128, #FORMAT, t); \
+ qsnprintf(msg, 128, #FORMAT, double(t)); \
massageExponent(msg); \
break; \
} \
@@ -2649,7 +2647,7 @@ template <> Q_TESTLIB_EXPORT char *QTest::toString<TYPE>(const TYPE &t) \
}
TO_STRING_FLOAT(float, %g)
-TO_STRING_FLOAT(double, %.12lg)
+TO_STRING_FLOAT(double, %.12g)
template <> Q_TESTLIB_EXPORT char *QTest::toString<qfloat16>(const qfloat16 &t)
{
diff --git a/src/tools/bootstrap/bootstrap.pro b/src/tools/bootstrap/bootstrap.pro
index 83e44ff9a4..3a1a186e8e 100644
--- a/src/tools/bootstrap/bootstrap.pro
+++ b/src/tools/bootstrap/bootstrap.pro
@@ -19,8 +19,6 @@ DEFINES += \
QT_NO_FOREACH \
QT_NO_CAST_FROM_ASCII
-DEFINES -= QT_EVAL
-
SOURCES += \
../../corelib/codecs/qlatincodec.cpp \
../../corelib/codecs/qtextcodec.cpp \
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index 5d777ece2e..2f52dd6ca0 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -159,6 +159,7 @@ Type Moc::parseType()
bool isVoid = false;
type.firstToken = lookup();
for (;;) {
+ skipCxxAttributes();
switch (next()) {
case SIGNED:
case UNSIGNED:
@@ -188,8 +189,11 @@ Type Moc::parseType()
}
break;
}
+
+ skipCxxAttributes();
test(ENUM) || test(CLASS) || test(STRUCT);
for(;;) {
+ skipCxxAttributes();
switch (next()) {
case IDENTIFIER:
// void mySlot(unsigned myArg)
@@ -281,6 +285,7 @@ bool Moc::parseEnum(EnumDef *def)
break;
next(IDENTIFIER);
def->values += lexem();
+ skipCxxAttributes();
} while (test(EQ) ? until(COMMA) : test(COMMA));
next(RBRACE);
if (isTypdefEnum) {
@@ -356,6 +361,15 @@ bool Moc::testFunctionAttribute(Token tok, FunctionDef *def)
return false;
}
+bool Moc::skipCxxAttributes()
+{
+ auto rewind = index;
+ if (test(LBRACK) && test(LBRACK) && until(RBRACK) && test(RBRACK))
+ return true;
+ index = rewind;
+ return false;
+}
+
bool Moc::testFunctionRevision(FunctionDef *def)
{
if (test(Q_REVISION_TOKEN)) {
@@ -381,7 +395,7 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro)
//skip modifiers and attributes
while (test(INLINE) || (test(STATIC) && (def->isStatic = true) == true) ||
(test(VIRTUAL) && (def->isVirtual = true) == true) //mark as virtual
- || testFunctionAttribute(def) || testFunctionRevision(def)) {}
+ || skipCxxAttributes() || testFunctionAttribute(def) || testFunctionRevision(def)) {}
bool templateFunction = (lookup() == TEMPLATE);
def->type = parseType();
if (def->type.name.isEmpty()) {
@@ -454,10 +468,11 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro)
until(RBRACE);
else if ((def->isAbstract = test(EQ)))
until(SEMIC);
+ else if (skipCxxAttributes())
+ until(SEMIC);
else
error();
}
-
if (scopedFunctionName) {
const QByteArray msg = "Function declaration " + def->name
+ " contains extra qualification. Ignoring as signal or slot.";
@@ -475,7 +490,7 @@ bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def)
//skip modifiers and attributes
while (test(EXPLICIT) || test(INLINE) || (test(STATIC) && (def->isStatic = true) == true) ||
(test(VIRTUAL) && (def->isVirtual = true) == true) //mark as virtual
- || testFunctionAttribute(def) || testFunctionRevision(def)) {}
+ || skipCxxAttributes() || testFunctionAttribute(def) || testFunctionRevision(def)) {}
bool tilde = test(TILDE);
def->type = parseType();
if (def->type.name.isEmpty())
@@ -565,6 +580,7 @@ void Moc::parse()
} else if (!test(SEMIC)) {
NamespaceDef def;
def.classname = nsName;
+ def.doGenerate = currentFilenames.size() <= 1;
next(LBRACE);
def.begin = index - 1;
@@ -572,25 +588,22 @@ void Moc::parse()
def.end = index;
index = def.begin + 1;
- const bool parseNamespace = currentFilenames.size() <= 1;
- if (parseNamespace) {
- for (int i = namespaceList.size() - 1; i >= 0; --i) {
- if (inNamespace(&namespaceList.at(i))) {
- def.qualified.prepend(namespaceList.at(i).classname + "::");
- }
- }
- for (const QByteArray &ns : nested) {
- NamespaceDef parentNs;
- parentNs.classname = ns;
- parentNs.qualified = def.qualified;
- def.qualified += ns + "::";
- parentNs.begin = def.begin;
- parentNs.end = def.end;
- namespaceList += parentNs;
+ for (int i = namespaceList.size() - 1; i >= 0; --i) {
+ if (inNamespace(&namespaceList.at(i))) {
+ def.qualified.prepend(namespaceList.at(i).classname + "::");
}
}
+ for (const QByteArray &ns : nested) {
+ NamespaceDef parentNs;
+ parentNs.classname = ns;
+ parentNs.qualified = def.qualified;
+ def.qualified += ns + "::";
+ parentNs.begin = def.begin;
+ parentNs.end = def.end;
+ namespaceList += parentNs;
+ }
- while (parseNamespace && inNamespace(&def) && hasNext()) {
+ while (inNamespace(&def) && hasNext()) {
switch (next()) {
case NAMESPACE:
if (test(IDENTIFIER)) {
@@ -915,7 +928,8 @@ void Moc::parse()
} else {
knownGadgets.insert(def.classname, def.qualified);
knownGadgets.insert(def.qualified, def.qualified);
- classList += def;
+ if (n.doGenerate)
+ classList += def;
}
}
}
diff --git a/src/tools/moc/moc.h b/src/tools/moc/moc.h
index d6482f4e44..2bba8a5bb9 100644
--- a/src/tools/moc/moc.h
+++ b/src/tools/moc/moc.h
@@ -188,6 +188,7 @@ Q_DECLARE_TYPEINFO(ClassDef::Interface, Q_MOVABLE_TYPE);
struct NamespaceDef : BaseDef {
bool hasQNamespace = false;
+ bool doGenerate = false;
};
Q_DECLARE_TYPEINFO(NamespaceDef, Q_MOVABLE_TYPE);
@@ -256,6 +257,8 @@ public:
bool testFunctionAttribute(Token tok, FunctionDef *def);
bool testFunctionRevision(FunctionDef *def);
+ bool skipCxxAttributes();
+
void checkSuperClasses(ClassDef *def);
void checkProperties(ClassDef* cdef);
};
diff --git a/src/tools/qvkgen/qvkgen.cpp b/src/tools/qvkgen/qvkgen.cpp
index 059f9413cb..4db3f26161 100644
--- a/src/tools/qvkgen/qvkgen.cpp
+++ b/src/tools/qvkgen/qvkgen.cpp
@@ -192,22 +192,20 @@ QString VkSpecParser::parseName()
QString funcSig(const VkSpecParser::Command &c, const char *className = nullptr)
{
- QString s;
- s.sprintf("%s %s%s%s", qPrintable(c.cmd.type),
- (className ? className : ""), (className ? "::" : ""),
- qPrintable(c.cmd.name));
+ QString s(QString::asprintf("%s %s%s%s", qPrintable(c.cmd.type),
+ (className ? className : ""), (className ? "::" : ""),
+ qPrintable(c.cmd.name)));
if (!c.args.isEmpty()) {
s += QLatin1Char('(');
bool first = true;
for (const VkSpecParser::TypedName &a : c.args) {
- QString argStr;
- argStr.sprintf("%s%s%s%s", qPrintable(a.type), (a.type.endsWith(QLatin1Char('*')) ? "" : " "),
- qPrintable(a.name), qPrintable(a.typeSuffix));
if (!first)
s += QStringLiteral(", ");
else
first = false;
- s += argStr;
+ s += QString::asprintf("%s%s%s%s", qPrintable(a.type),
+ (a.type.endsWith(QLatin1Char('*')) ? "" : " "),
+ qPrintable(a.name), qPrintable(a.typeSuffix));
}
s += QLatin1Char(')');
}
@@ -216,13 +214,12 @@ QString funcSig(const VkSpecParser::Command &c, const char *className = nullptr)
QString funcCall(const VkSpecParser::Command &c, int idx)
{
- QString s;
// template:
// [return] reinterpret_cast<PFN_vkEnumeratePhysicalDevices>(d_ptr->m_funcs[0])(instance, pPhysicalDeviceCount, pPhysicalDevices);
- s.sprintf("%sreinterpret_cast<PFN_%s>(d_ptr->m_funcs[%d])",
- (c.cmd.type == QStringLiteral("void") ? "" : "return "),
- qPrintable(c.cmd.name),
- idx);
+ QString s = QString::asprintf("%sreinterpret_cast<PFN_%s>(d_ptr->m_funcs[%d])",
+ (c.cmd.type == QStringLiteral("void") ? "" : "return "),
+ qPrintable(c.cmd.name),
+ idx);
if (!c.args.isEmpty()) {
s += QLatin1Char('(');
bool first = true;
@@ -338,10 +335,9 @@ bool genVulkanFunctionsH(const QVector<VkSpecParser::Command> &commands, const Q
*dst += QStringLiteral(";\n");
}
- QString str;
- str.sprintf(s, preamble.get(licHeaderFn).constData(), instCmdStr.toUtf8().constData(), devCmdStr.toUtf8().constData());
-
- f.write(str.toUtf8());
+ f.write(QString::asprintf(s, preamble.get(licHeaderFn).constData(),
+ instCmdStr.toUtf8().constData(),
+ devCmdStr.toUtf8().constData()).toUtf8());
return true;
}
@@ -400,10 +396,7 @@ bool genVulkanFunctionsPH(const QVector<VkSpecParser::Command> &commands, const
[](const VkSpecParser::Command &c) { return c.deviceLevel; });
const int instLevelCount = commands.count() - devLevelCount;
- QString str;
- str.sprintf(s, preamble.get(licHeaderFn).constData(), instLevelCount, devLevelCount);
-
- f.write(str.toUtf8());
+ f.write(QString::asprintf(s, preamble.get(licHeaderFn).constData(), instLevelCount, devLevelCount).toUtf8());
return true;
}
@@ -478,10 +471,12 @@ bool genVulkanFunctionsPC(const QVector<VkSpecParser::Command> &commands, const
if (instCmdNamesStr.count() > 2)
instCmdNamesStr = instCmdNamesStr.left(instCmdNamesStr.count() - 2);
- QString str;
- str.sprintf(s, preamble.get(licHeaderFn).constData(),
- instCmdWrapperStr.toUtf8().constData(), instCmdNamesStr.toUtf8().constData(), instIdx,
- devCmdWrapperStr.toUtf8().constData(), devCmdNamesStr.toUtf8().constData(), commands.count() - instIdx);
+ const QString str =
+ QString::asprintf(s, preamble.get(licHeaderFn).constData(),
+ instCmdWrapperStr.toUtf8().constData(),
+ instCmdNamesStr.toUtf8().constData(), instIdx,
+ devCmdWrapperStr.toUtf8().constData(),
+ devCmdNamesStr.toUtf8().constData(), commands.count() - instIdx);
f.write(str.toUtf8());
diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp
index 6e8c13be15..0eb6766b5a 100644
--- a/src/tools/rcc/main.cpp
+++ b/src/tools/rcc/main.cpp
@@ -155,6 +155,11 @@ int runRcc(int argc, char *argv[])
QCommandLineOption binaryOption(QStringLiteral("binary"), QStringLiteral("Output a binary file for use as a dynamic resource."));
parser.addOption(binaryOption);
+ QCommandLineOption generatorOption(QStringList{QStringLiteral("g"), QStringLiteral("generator")});
+ generatorOption.setDescription(QStringLiteral("Select generator."));
+ generatorOption.setValueName(QStringLiteral("cpp|python|python2"));
+ parser.addOption(generatorOption);
+
QCommandLineOption passOption(QStringLiteral("pass"), QStringLiteral("Pass number for big resources"), QStringLiteral("number"));
parser.addOption(passOption);
@@ -220,6 +225,18 @@ int runRcc(int argc, char *argv[])
library.setCompressThreshold(parser.value(thresholdOption).toInt());
if (parser.isSet(binaryOption))
library.setFormat(RCCResourceLibrary::Binary);
+ if (parser.isSet(generatorOption)) {
+ auto value = parser.value(generatorOption);
+ if (value == QLatin1String("cpp"))
+ library.setFormat(RCCResourceLibrary::C_Code);
+ else if (value == QLatin1String("python"))
+ library.setFormat(RCCResourceLibrary::Python3_Code);
+ else if (value == QLatin1String("python2"))
+ library.setFormat(RCCResourceLibrary::Python2_Code);
+ else
+ errorMsg = QLatin1String("Invalid generator: ") + value;
+ }
+
if (parser.isSet(passOption)) {
if (parser.value(passOption) == QLatin1String("1"))
library.setFormat(RCCResourceLibrary::Pass1);
@@ -280,6 +297,8 @@ int runRcc(int argc, char *argv[])
switch (library.format()) {
case RCCResourceLibrary::C_Code:
case RCCResourceLibrary::Pass1:
+ case RCCResourceLibrary::Python3_Code:
+ case RCCResourceLibrary::Python2_Code:
mode = QIODevice::WriteOnly | QIODevice::Text;
break;
case RCCResourceLibrary::Pass2:
diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp
index 862e574f2d..704c336860 100644
--- a/src/tools/rcc/rcc.cpp
+++ b/src/tools/rcc/rcc.cpp
@@ -68,6 +68,17 @@ enum {
#define writeString(s) write(s, sizeof(s))
+static const char pythonHeader1[] =
+R"(# Created by: object code
+# Created by: The Resource Compiler for Qt version )";
+
+static const char pythonHeader2[] = R"(
+# WARNING! All changes made in this file will be lost!
+
+from PySide2 import QtCore
+
+)";
+
void RCCResourceLibrary::write(const char *str, int len)
{
--len; // trailing \0 on string literals...
@@ -176,6 +187,8 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
{
const bool text = lib.m_format == RCCResourceLibrary::C_Code;
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
+ const bool python = lib.m_format == RCCResourceLibrary::Python3_Code
+ || lib.m_format == RCCResourceLibrary::Python2_Code;
//some info
if (text || pass1) {
if (m_language != QLocale::C) {
@@ -222,6 +235,8 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
}
if (text || pass1)
lib.writeChar('\n');
+ else if (python)
+ lib.writeString("\\\n");
if (lib.formatVersion() >= 2) {
// last modified time stamp
@@ -236,6 +251,8 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
lib.writeNumber8(lastmod);
if (text || pass1)
lib.writeChar('\n');
+ else if (python)
+ lib.writeString("\\\n");
}
}
@@ -246,6 +263,8 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
const bool pass2 = lib.m_format == RCCResourceLibrary::Pass2;
const bool binary = lib.m_format == RCCResourceLibrary::Binary;
+ const bool python = lib.m_format == RCCResourceLibrary::Python3_Code
+ || lib.m_format == RCCResourceLibrary::Python2_Code;
//capture the offset
m_dataOffset = offset;
@@ -343,20 +362,24 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
}
// write the length
-
- if (text || binary || pass2)
+ if (text || binary || pass2 || python)
lib.writeNumber4(data.size());
if (text || pass1)
lib.writeString("\n ");
+ else if (python)
+ lib.writeString("\\\n");
offset += 4;
// write the payload
const char *p = data.constData();
- if (text) {
+ if (text || python) {
for (int i = data.size(), j = 0; --i >= 0; --j) {
lib.writeHex(*p++);
if (j == 0) {
- lib.writeString("\n ");
+ if (text)
+ lib.writeString("\n ");
+ else
+ lib.writeString("\\\n");
j = 16;
}
}
@@ -368,6 +391,9 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
// done
if (text || pass1)
lib.writeString("\n ");
+ else if (python)
+ lib.writeString("\\\n");
+
return offset;
}
@@ -375,6 +401,8 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
{
const bool text = lib.m_format == RCCResourceLibrary::C_Code;
const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
+ const bool python = lib.m_format == RCCResourceLibrary::Python3_Code
+ || lib.m_format == RCCResourceLibrary::Python2_Code;
// capture the offset
m_nameOffset = offset;
@@ -390,12 +418,16 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
lib.writeNumber2(m_name.length());
if (text || pass1)
lib.writeString("\n ");
+ else if (python)
+ lib.writeString("\\\n");
offset += 2;
// write the hash
lib.writeNumber4(qt_hash(m_name));
if (text || pass1)
lib.writeString("\n ");
+ else if (python)
+ lib.writeString("\\\n");
offset += 4;
// write the m_name
@@ -404,12 +436,17 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
lib.writeNumber2(unicode[i].unicode());
if ((text || pass1) && i % 16 == 0)
lib.writeString("\n ");
+ else if (python && i % 16 == 0)
+ lib.writeString("\\\n");
}
offset += m_name.length()*2;
// done
if (text || pass1)
lib.writeString("\n ");
+ else if (python)
+ lib.writeString("\\\n");
+
return offset;
}
@@ -959,18 +996,37 @@ void RCCResourceLibrary::writeDecimal(int value)
write(buf, n + 1); // write() takes a size including terminating NUL
}
+static const char hexDigits[] = "0123456789abcdef";
+
+inline void RCCResourceLibrary::write2HexDigits(quint8 number)
+{
+ writeChar(hexDigits[number >> 4]);
+ writeChar(hexDigits[number & 0xf]);
+}
+
void RCCResourceLibrary::writeHex(quint8 tmp)
{
- const char digits[] = "0123456789abcdef";
- writeChar('0');
- writeChar('x');
- if (tmp < 16) {
- writeChar(digits[tmp]);
- } else {
- writeChar(digits[tmp >> 4]);
- writeChar(digits[tmp & 0xf]);
+ switch (m_format) {
+ case RCCResourceLibrary::Python3_Code:
+ case RCCResourceLibrary::Python2_Code:
+ if (tmp >= 32 && tmp < 127 && tmp != '"' && tmp != '\\') {
+ writeChar(char(tmp));
+ } else {
+ writeChar('\\');
+ writeChar('x');
+ write2HexDigits(tmp);
+ }
+ break;
+ default:
+ writeChar('0');
+ writeChar('x');
+ if (tmp < 16)
+ writeChar(hexDigits[tmp]);
+ else
+ write2HexDigits(tmp);
+ writeChar(',');
+ break;
}
- writeChar(',');
}
void RCCResourceLibrary::writeNumber2(quint16 number)
@@ -1038,7 +1094,9 @@ void RCCResourceLibrary::writeNumber8(quint64 number)
bool RCCResourceLibrary::writeHeader()
{
- if (m_format == C_Code || m_format == Pass1) {
+ switch (m_format) {
+ case C_Code:
+ case Pass1:
writeString("/****************************************************************************\n");
writeString("** Resource object code\n");
writeString("**\n");
@@ -1047,7 +1105,17 @@ bool RCCResourceLibrary::writeHeader()
writeString("\n**\n");
writeString("** WARNING! All changes made in this file will be lost!\n");
writeString( "*****************************************************************************/\n\n");
- } else if (m_format == Binary) {
+ break;
+ case Python3_Code:
+ case Python2_Code:
+ writeString("# Resource object code (Python ");
+ writeChar(m_format == Python3_Code ? '3' : '2');
+ writeString(")\n");
+ writeString(pythonHeader1);
+ writeByteArray(QT_VERSION_STR);
+ writeString(pythonHeader2);
+ break;
+ case Binary:
writeString("qres");
writeNumber4(0);
writeNumber4(0);
@@ -1055,6 +1123,9 @@ bool RCCResourceLibrary::writeHeader()
writeNumber4(0);
if (m_formatVersion >= 3)
writeNumber4(m_overallFlags);
+ break;
+ default:
+ break;
}
return true;
}
@@ -1062,10 +1133,21 @@ bool RCCResourceLibrary::writeHeader()
bool RCCResourceLibrary::writeDataBlobs()
{
Q_ASSERT(m_errorDevice);
- if (m_format == C_Code) {
+ switch (m_format) {
+ case C_Code:
writeString("static const unsigned char qt_resource_data[] = {\n");
- } else if (m_format == Binary) {
+ break;
+ case Python3_Code:
+ writeString("qt_resource_data = b\"\\\n");
+ break;
+ case Python2_Code:
+ writeString("qt_resource_data = \"\\\n");
+ break;
+ case Binary:
m_dataOffset = m_out.size();
+ break;
+ default:
+ break;
}
if (!m_root)
@@ -1091,24 +1173,46 @@ bool RCCResourceLibrary::writeDataBlobs()
}
}
}
- if (m_format == C_Code)
+ switch (m_format) {
+ case C_Code:
writeString("\n};\n\n");
- else if (m_format == Pass1) {
+ break;
+ case Python3_Code:
+ case Python2_Code:
+ writeString("\"\n\n");
+ break;
+ case Pass1:
if (offset < 8)
offset = 8;
writeString("\nstatic const unsigned char qt_resource_data[");
writeByteArray(QByteArray::number(offset));
writeString("] = { 'Q', 'R', 'C', '_', 'D', 'A', 'T', 'A' };\n\n");
+ break;
+ default:
+ break;
}
return true;
}
bool RCCResourceLibrary::writeDataNames()
{
- if (m_format == C_Code || m_format == Pass1)
+ switch (m_format) {
+ case C_Code:
+ case Pass1:
writeString("static const unsigned char qt_resource_name[] = {\n");
- else if (m_format == Binary)
+ break;
+ case Python3_Code:
+ writeString("qt_resource_name = b\"\\\n");
+ break;
+ case Python2_Code:
+ writeString("qt_resource_name = \"\\\n");
+ break;
+ case Binary:
m_namesOffset = m_out.size();
+ break;
+ default:
+ break;
+ }
QHash<QString, int> names;
QStack<RCCFileInfo*> pending;
@@ -1133,8 +1237,18 @@ bool RCCResourceLibrary::writeDataNames()
}
}
}
- if (m_format == C_Code || m_format == Pass1)
+ switch (m_format) {
+ case C_Code:
+ case Pass1:
writeString("\n};\n\n");
+ break;
+ case Python3_Code:
+ case Python2_Code:
+ writeString("\"\n\n");
+ break;
+ default:
+ break;
+ }
return true;
}
@@ -1149,10 +1263,24 @@ struct qt_rcc_compare_hash
bool RCCResourceLibrary::writeDataStructure()
{
- if (m_format == C_Code || m_format == Pass1)
+ switch (m_format) {
+ case C_Code:
+ case Pass1:
writeString("static const unsigned char qt_resource_struct[] = {\n");
- else if (m_format == Binary)
+ break;
+ case Python3_Code:
+ writeString("qt_resource_struct = b\"\\\n");
+ break;
+ case Python2_Code:
+ writeString("qt_resource_struct = \"\\\n");
+ break;
+ case Binary:
m_treeOffset = m_out.size();
+ break;
+ default:
+ break;
+ }
+
QStack<RCCFileInfo*> pending;
if (!m_root)
@@ -1196,8 +1324,18 @@ bool RCCResourceLibrary::writeDataStructure()
pending.push(child);
}
}
- if (m_format == C_Code || m_format == Pass1)
+ switch (m_format) {
+ case C_Code:
+ case Pass1:
writeString("\n};\n\n");
+ break;
+ case Python3_Code:
+ case Python2_Code:
+ writeString("\"\n\n");
+ break;
+ default:
+ break;
+ }
return true;
}
@@ -1387,6 +1525,19 @@ bool RCCResourceLibrary::writeInitializer()
p[i++] = (m_overallFlags >> 8) & 0xff;
p[i++] = (m_overallFlags >> 0) & 0xff;
}
+ } else if (m_format == Python3_Code || m_format == Python2_Code) {
+ writeString(R"(def qInitResources():
+ QtCore.qRegisterResourceData(0x)");
+ write2HexDigits(m_formatVersion);
+ writeString(R"(, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+def qCleanupResources():
+ QtCore.qUnregisterResourceData(0x)");
+ write2HexDigits(m_formatVersion);
+ writeString(R"(, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+qInitResources()
+)");
}
return true;
}
diff --git a/src/tools/rcc/rcc.h b/src/tools/rcc/rcc.h
index ad1c5cd166..b301355e4f 100644
--- a/src/tools/rcc/rcc.h
+++ b/src/tools/rcc/rcc.h
@@ -58,7 +58,7 @@ public:
bool readFiles(bool listMode, QIODevice &errorDevice);
- enum Format { Binary, C_Code, Pass1, Pass2 };
+ enum Format { Binary, C_Code, Pass1, Pass2, Python3_Code, Python2_Code };
void setFormat(Format f) { m_format = f; }
Format format() const { return m_format; }
@@ -136,6 +136,7 @@ private:
void writeAddNamespaceFunction(const QByteArray &name);
void writeDecimal(int value);
void writeHex(quint8 number);
+ void write2HexDigits(quint8 number);
void writeNumber2(quint16 number);
void writeNumber4(quint32 number);
void writeNumber8(quint64 number);
diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp
index caab6c16ba..5692a16bce 100644
--- a/src/widgets/dialogs/qdialog.cpp
+++ b/src/widgets/dialogs/qdialog.cpp
@@ -270,12 +270,11 @@ void QDialogPrivate::deletePlatformHelper()
The most common way to display a modal dialog is to call its
exec() function. When the user closes the dialog, exec() will
- provide a useful \l{#return}{return value}. Typically,
- to get the dialog to close and return the appropriate value, we
- connect a default button, e.g. \uicontrol OK, to the accept() slot and a
- \uicontrol Cancel button to the reject() slot.
- Alternatively you can call the done() slot with \c Accepted or
- \c Rejected.
+ provide a useful \l{#return}{return value}. To close the dialog
+ and return the appropriate value, you must connect a default button,
+ e.g. an \uicontrol OK button to the accept() slot and a
+ \uicontrol Cancel button to the reject() slot. Alternatively, you
+ can call the done() slot with \c Accepted or \c Rejected.
An alternative is to call setModal(true) or setWindowModality(),
then show(). Unlike exec(), show() returns control to the caller
diff --git a/src/widgets/doc/snippets/timeline/main.cpp b/src/widgets/doc/snippets/timeline/main.cpp
index 74aa749254..4dfa2400d0 100644
--- a/src/widgets/doc/snippets/timeline/main.cpp
+++ b/src/widgets/doc/snippets/timeline/main.cpp
@@ -48,7 +48,7 @@
**
****************************************************************************/
-#include <QtGui>
+#include <QtWidgets>
#include <math.h>
int main(int argv, char *args[])
@@ -68,7 +68,7 @@ int main(int argv, char *args[])
for (int i = 0; i < 200; ++i)
animation->setPosAt(i / 200.0, QPointF(i, i));
- QGraphicsScene *scene = new QGraphicsScene();
+ QGraphicsScene *scene = new QGraphicsScene;
scene->setSceneRect(0, 0, 250, 250);
scene->addItem(ball);
diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.cpp b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
index 78b91d5c39..ad77e2f260 100644
--- a/src/widgets/graphicsview/qgraphicsitemanimation.cpp
+++ b/src/widgets/graphicsview/qgraphicsitemanimation.cpp
@@ -115,7 +115,7 @@ public:
QGraphicsItem *item;
QPointF startPos;
- QMatrix startMatrix;
+ QTransform startTransform;
qreal step;
@@ -294,23 +294,38 @@ QList<QPair<qreal, QPointF> > QGraphicsItemAnimation::posList() const
return list;
}
+#if QT_DEPRECATED_SINCE(5, 14)
/*!
Returns the matrix used to transform the item at the specified \a step value.
+
+ \obsolete Use transformAt() instead
*/
QMatrix QGraphicsItemAnimation::matrixAt(qreal step) const
{
check_step_valid(step, "matrixAt");
+ return transformAt(step).toAffine();
+}
+#endif
+
+/*!
+ Returns the transform used for the item at the specified \a step value.
+
+ \since 5.14
+*/
+QTransform QGraphicsItemAnimation::transformAt(qreal step) const
+{
+ check_step_valid(step, "transformAt");
- QMatrix matrix;
+ QTransform transform;
if (!d->rotation.isEmpty())
- matrix.rotate(rotationAt(step));
+ transform.rotate(rotationAt(step));
if (!d->verticalScale.isEmpty())
- matrix.scale(horizontalScaleAt(step), verticalScaleAt(step));
+ transform.scale(horizontalScaleAt(step), verticalScaleAt(step));
if (!d->verticalShear.isEmpty())
- matrix.shear(horizontalShearAt(step), verticalShearAt(step));
+ transform.shear(horizontalShearAt(step), verticalShearAt(step));
if (!d->xTranslation.isEmpty())
- matrix.translate(xTranslationAt(step), yTranslationAt(step));
- return matrix;
+ transform.translate(xTranslationAt(step), yTranslationAt(step));
+ return transform;
}
/*!
@@ -542,7 +557,7 @@ void QGraphicsItemAnimation::setStep(qreal step)
|| !d->horizontalShear.isEmpty()
|| !d->xTranslation.isEmpty()
|| !d->yTranslation.isEmpty()) {
- d->item->setMatrix(d->startMatrix * matrixAt(step));
+ d->item->setTransform(d->startTransform * transformAt(step));
}
}
@@ -562,7 +577,7 @@ void QGraphicsItemAnimation::reset()
if (!d->item)
return;
d->startPos = d->item->pos();
- d->startMatrix = d->item->matrix();
+ d->startTransform = d->item->transform();
}
#endif
diff --git a/src/widgets/graphicsview/qgraphicsitemanimation.h b/src/widgets/graphicsview/qgraphicsitemanimation.h
index f983bd8026..3051fb2e2b 100644
--- a/src/widgets/graphicsview/qgraphicsitemanimation.h
+++ b/src/widgets/graphicsview/qgraphicsitemanimation.h
@@ -51,6 +51,7 @@ class QGraphicsItem;
class QMatrix;
class QPointF;
class QTimeLine;
+class QTransform;
template <class T1, class T2> struct QPair;
class QGraphicsItemAnimationPrivate;
@@ -71,7 +72,11 @@ public:
QList<QPair<qreal, QPointF> > posList() const;
void setPosAt(qreal step, const QPointF &pos);
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_X("Use transformAt() instead")
QMatrix matrixAt(qreal step) const;
+#endif
+ QTransform transformAt(qreal step) const;
qreal rotationAt(qreal step) const;
QList<QPair<qreal, qreal> > rotationList() const;
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 7c44bfe39d..9e784b41c6 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -575,10 +575,6 @@ void QApplicationPrivate::init()
initialize();
eventDispatcher->startingUp();
-#ifdef QT_EVAL
- extern void qt_gui_eval_init(QCoreApplicationPrivate::Type);
- qt_gui_eval_init(application_type);
-#endif
#ifndef QT_NO_ACCESSIBILITY
// factory for accessible interfaces for widgets shipped with Qt
QAccessible::installFactory(&qAccessibleFactory);
diff --git a/src/widgets/kernel/qformlayout.cpp b/src/widgets/kernel/qformlayout.cpp
index bd0ea2598a..9146ba84c8 100644
--- a/src/widgets/kernel/qformlayout.cpp
+++ b/src/widgets/kernel/qformlayout.cpp
@@ -783,7 +783,7 @@ void QFormLayoutPrivate::setupVerticalLayoutData(int width)
vLayouts[vidx].expansive = expanding || (vLayouts[vidx].stretch > 0);
vLayouts[vidx].empty = false;
- if (vLayouts[vidx].stretch > 0)
+ if (vLayouts[vidx].expansive)
addTopBottomStretch = false;
if (vidx > 1)
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index b71a0ed052..de79fd4154 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -1348,11 +1348,6 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow)
if (!isWindow() && parentWidget() && parentWidget()->testAttribute(Qt::WA_DropSiteRegistered))
setAttribute(Qt::WA_DropSiteRegistered, true);
-#ifdef QT_EVAL
- extern void qt_eval_init_widget(QWidget *w);
- qt_eval_init_widget(this);
-#endif
-
// need to force the resting of the icon after changing parents
if (testAttribute(Qt::WA_SetWindowIcon))
d->setWindowIcon_sys();
@@ -6054,13 +6049,7 @@ QString qt_setWindowTitle_helperHelper(const QString &title, const QWidget *widg
{
Q_ASSERT(widget);
-#ifdef QT_EVAL
- extern QString qt_eval_adapt_window_title(const QString &title);
- QString cap = qt_eval_adapt_window_title(title);
-#else
QString cap = title;
-#endif
-
if (cap.isEmpty())
return cap;
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index 0481dffda8..595beeaf47 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -310,12 +310,6 @@ bool QWidgetBackingStore::bltRect(const QRect &rect, int dx, int dy, QWidget *wi
return store->scroll(tlwRect, dx, dy);
}
-void QWidgetBackingStore::releaseBuffer()
-{
- if (store)
- store->resize(QSize());
-}
-
/*!
Prepares the window surface to paint a\ toClean region of the \a widget and
updates the BeginPaintInfo struct accordingly.
diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h
index 4d15ab138e..e7a2bca33a 100644
--- a/src/widgets/kernel/qwidgetbackingstore_p.h
+++ b/src/widgets/kernel/qwidgetbackingstore_p.h
@@ -149,7 +149,6 @@ private:
void doSync();
bool bltRect(const QRect &rect, int dx, int dy, QWidget *widget);
- void releaseBuffer();
void beginPaint(QRegion &toClean, QWidget *widget, QBackingStore *backingStore,
BeginPaintInfo *returnInfo, bool toCleanIsInTopLevelCoordinates = true);
diff --git a/src/widgets/styles/qstyle.h b/src/widgets/styles/qstyle.h
index 5ee37bd8e9..ee234457f5 100644
--- a/src/widgets/styles/qstyle.h
+++ b/src/widgets/styles/qstyle.h
@@ -832,6 +832,13 @@ public:
SP_MediaVolume,
SP_MediaVolumeMuted,
SP_LineEditClearButton,
+ SP_DialogYesToAllButton,
+ SP_DialogNoToAllButton,
+ SP_DialogSaveAllButton,
+ SP_DialogAbortButton,
+ SP_DialogRetryButton,
+ SP_DialogIgnoreButton,
+ SP_RestoreDefaultsButton,
// do not add any values below/greater than this
SP_CustomBase = 0xf0000000
};
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index c104ac2498..25d3755e12 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -4090,6 +4090,11 @@ void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, Q
if (subRule.hasFont)
p->setFont(subRule.font);
boxCopy.rect = subRule.contentsRect(opt->rect);
+ if (subRule.hasImage()) {
+ // the image is already drawn with CE_ToolBoxTabShape, adjust rect here
+ const int iconExtent = proxy()->pixelMetric(QStyle::PM_SmallIconSize, box, w);
+ boxCopy.rect.setLeft(boxCopy.rect.left() + iconExtent);
+ }
QWindowsStyle::drawControl(ce, &boxCopy, p , w);
if (subRule.hasFont)
p->setFont(oldFont);
diff --git a/src/widgets/widgets.pro b/src/widgets/widgets.pro
index e556cb8b10..6f807e1696 100644
--- a/src/widgets/widgets.pro
+++ b/src/widgets/widgets.pro
@@ -32,8 +32,6 @@ qtConfig(graphicseffect) {
QMAKE_LIBS += $$QMAKE_LIBS_GUI
-contains(DEFINES,QT_EVAL):include($$QT_SOURCE_TREE/src/corelib/eval.pri)
-
QMAKE_DYNAMIC_LIST_FILE = $$PWD/QtWidgets.dynlist
# Code coverage with TestCocoon
diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp
index 6edefaa311..54caa26fb6 100644
--- a/src/widgets/widgets/qabstractspinbox.cpp
+++ b/src/widgets/widgets/qabstractspinbox.cpp
@@ -252,7 +252,7 @@ QString QAbstractSpinBox::text() const
All values are displayed with the prefix and suffix (if set), \e
except for the special value, which only shows the special value
- text. This special text is passed in the QSpinBox::valueChanged()
+ text. This special text is passed in the QSpinBox::textChanged()
signal that passes a QString.
To turn off the special-value text display, call this function
@@ -342,18 +342,18 @@ void QAbstractSpinBox::setReadOnly(bool enable)
\since 4.3
If keyboard tracking is enabled (the default), the spinbox
- emits the valueChanged() signal while the new value is being
- entered from the keyboard.
+ emits the valueChanged() and textChanged() signals while the
+ new value is being entered from the keyboard.
E.g. when the user enters the value 600 by typing 6, 0, and 0,
the spinbox emits 3 signals with the values 6, 60, and 600
respectively.
If keyboard tracking is disabled, the spinbox doesn't emit the
- valueChanged() signal while typing. It emits the signal later,
- when the return key is pressed, when keyboard focus is lost, or
- when other spinbox functionality is used, e.g. pressing an arrow
- key.
+ valueChanged() and textChanged() signals while typing. It emits
+ the signals later, when the return key is pressed, when keyboard
+ focus is lost, or when other spinbox functionality is used, e.g.
+ pressing an arrow key.
*/
bool QAbstractSpinBox::keyboardTracking() const
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index e38e1d7750..932affde07 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -1364,7 +1364,13 @@ void QComboBoxPrivate::emitActivated(const QModelIndex &index)
return;
QString text(itemText(index));
emit q->activated(index.row());
+ emit q->textActivated(text);
+#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
emit q->activated(text);
+QT_WARNING_POP
+#endif
}
void QComboBoxPrivate::_q_emitHighlighted(const QModelIndex &index)
@@ -1374,7 +1380,13 @@ void QComboBoxPrivate::_q_emitHighlighted(const QModelIndex &index)
return;
QString text(itemText(index));
emit q->highlighted(index.row());
+ emit q->textHighlighted(text);
+#if QT_DEPRECATED_SINCE(5, 15)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
emit q->highlighted(text);
+QT_WARNING_POP
+#endif
}
void QComboBoxPrivate::_q_emitCurrentIndexChanged(const QModelIndex &index)
diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h
index 64fbebb3c5..6a87a675a4 100644
--- a/src/widgets/widgets/qcombobox.h
+++ b/src/widgets/widgets/qcombobox.h
@@ -220,15 +220,21 @@ public Q_SLOTS:
Q_SIGNALS:
void editTextChanged(const QString &);
void activated(int index);
- void activated(const QString &);
+ void textActivated(const QString &);
void highlighted(int index);
- void highlighted(const QString &);
+ void textHighlighted(const QString &);
void currentIndexChanged(int index);
+ void currentTextChanged(const QString &);
#if QT_DEPRECATED_SINCE(5, 13)
QT_DEPRECATED_X("Use currentTextChanged() instead")
void currentIndexChanged(const QString &);
#endif
- void currentTextChanged(const QString &);
+#if QT_DEPRECATED_SINCE(5, 15)
+ QT_DEPRECATED_X("Use textActivated() instead")
+ void activated(const QString &);
+ QT_DEPRECATED_X("Use textHighlighted() instead")
+ void highlighted(const QString &);
+#endif
protected:
void focusInEvent(QFocusEvent *e) override;
diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp
index 26b86f80be..28f6cdc7bd 100644
--- a/src/widgets/widgets/qdialogbuttonbox.cpp
+++ b/src/widgets/widgets/qdialogbuttonbox.cpp
@@ -387,12 +387,25 @@ QPushButton *QDialogButtonBoxPrivate::createButton(QDialogButtonBox::StandardBut
icon = QStyle::SP_DialogNoButton;
break;
case QDialogButtonBox::YesToAll:
+ icon = QStyle::SP_DialogYesToAllButton;
+ break;
case QDialogButtonBox::NoToAll:
+ icon = QStyle::SP_DialogNoToAllButton;
+ break;
case QDialogButtonBox::SaveAll:
+ icon = QStyle::SP_DialogSaveAllButton;
+ break;
case QDialogButtonBox::Abort:
+ icon = QStyle::SP_DialogAbortButton;
+ break;
case QDialogButtonBox::Retry:
+ icon = QStyle::SP_DialogRetryButton;
+ break;
case QDialogButtonBox::Ignore:
+ icon = QStyle::SP_DialogIgnoreButton;
+ break;
case QDialogButtonBox::RestoreDefaults:
+ icon = QStyle::SP_RestoreDefaultsButton;
break;
case QDialogButtonBox::NoButton:
return 0;
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index ad3d372bd3..02aa703289 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -315,7 +315,7 @@ QString QLineEdit::text() const
void QLineEdit::setText(const QString& text)
{
Q_D(QLineEdit);
- d->control->setText(text);
+ d->setText(text);
}
/*!
@@ -1483,8 +1483,11 @@ bool QLineEdit::event(QEvent * e)
} else if (e->type() == QEvent::LeaveEditFocus) {
d->setCursorVisible(false);
d->control->setCursorBlinkEnabled(false);
- if (d->control->hasAcceptableInput() || d->control->fixup())
+ if (d->edited && (d->control->hasAcceptableInput()
+ || d->control->fixup())) {
emit editingFinished();
+ d->edited = false;
+ }
}
}
#endif
@@ -1891,7 +1894,6 @@ void QLineEdit::focusInEvent(QFocusEvent *e)
/*!\reimp
*/
-
void QLineEdit::focusOutEvent(QFocusEvent *e)
{
Q_D(QLineEdit);
@@ -1914,8 +1916,10 @@ void QLineEdit::focusOutEvent(QFocusEvent *e)
#endif
if (reason != Qt::PopupFocusReason
|| !(QApplication::activePopupWidget() && QApplication::activePopupWidget()->parentWidget() == this)) {
- if (hasAcceptableInput() || d->control->fixup())
+ if (d->edited && (hasAcceptableInput() || d->control->fixup())) {
emit editingFinished();
+ d->edited = false;
+ }
}
#ifdef QT_KEYPAD_NAVIGATION
d->control->setCancelText(QString());
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 2a5a0c34dc..21e70db0ac 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -127,6 +127,7 @@ void QLineEditPrivate::_q_handleWindowActivate()
void QLineEditPrivate::_q_textEdited(const QString &text)
{
Q_Q(QLineEdit);
+ edited = true;
emit q->textEdited(text);
#if QT_CONFIG(completer)
if (control->completer()
@@ -272,6 +273,12 @@ void QLineEditPrivate::setCursorVisible(bool visible)
q->update();
}
+void QLineEditPrivate::setText(const QString& text)
+{
+ edited = true;
+ control->setText(text);
+}
+
void QLineEditPrivate::updatePasswordEchoEditing(bool editing)
{
Q_Q(QLineEdit);
diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h
index 12a2f1ddfd..dce5bf605a 100644
--- a/src/widgets/widgets/qlineedit_p.h
+++ b/src/widgets/widgets/qlineedit_p.h
@@ -151,7 +151,7 @@ public:
QLineEditPrivate()
: control(0), frame(1), contextMenuEnabled(1), cursorVisible(0),
- dragEnabled(0), clickCausedFocus(0), hscroll(0), vscroll(0),
+ dragEnabled(0), clickCausedFocus(0), edited(0), hscroll(0), vscroll(0),
alignment(Qt::AlignLeading | Qt::AlignVCenter),
leftTextMargin(0), topTextMargin(0), rightTextMargin(0), bottomTextMargin(0),
lastTextSize(0), mouseYThreshold(0)
@@ -176,6 +176,7 @@ public:
bool inSelection(int x) const;
QRect cursorRect() const;
void setCursorVisible(bool visible);
+ void setText(const QString& text);
void updatePasswordEchoEditing(bool);
@@ -202,6 +203,7 @@ public:
uint cursorVisible : 1;
uint dragEnabled : 1;
uint clickCausedFocus : 1;
+ uint edited : 1;
int hscroll;
int vscroll;
uint alignment;
diff --git a/src/widgets/widgets/qmdiarea.cpp b/src/widgets/widgets/qmdiarea.cpp
index feea7cd050..0ce561860e 100644
--- a/src/widgets/widgets/qmdiarea.cpp
+++ b/src/widgets/widgets/qmdiarea.cpp
@@ -1988,9 +1988,11 @@ QMdiSubWindow *QMdiArea::addSubWindow(QWidget *widget, Qt::WindowFlags windowFla
Q_ASSERT(child->testAttribute(Qt::WA_DeleteOnClose));
}
+ d->appendChild(child);
+
if (childFocus)
childFocus->setFocus();
- d->appendChild(child);
+
return child;
}
diff --git a/src/widgets/widgets/qspinbox.cpp b/src/widgets/widgets/qspinbox.cpp
index 7624b1ed3c..40044223e2 100644
--- a/src/widgets/widgets/qspinbox.cpp
+++ b/src/widgets/widgets/qspinbox.cpp
@@ -128,9 +128,10 @@ public:
manually. The spin box supports integer values but can be extended to
use different strings with validate(), textFromValue() and valueFromText().
- Every time the value changes QSpinBox emits two valueChanged() signals,
- one providing an int and the other a QString. The QString overload
- provides the value with both prefix() and suffix().
+ Every time the value changes QSpinBox emits valueChanged() and
+ textChanged() signals, the former providing a int and the latter
+ a QString. The textChanged() signal provides the value with both
+ prefix() and suffix().
The current value can be fetched with value() and set with setValue().
Clicking the up/down buttons or using the keyboard accelerator's
@@ -183,12 +184,23 @@ public:
*/
/*!
+ \fn void QSpinBox::textChanged(const QString &text)
+ \since 5.14
+
+ This signal is emitted whenever the spin box's text is changed.
+ The new text is passed in \a text with prefix() and suffix().
+*/
+
+#if QT_DEPRECATED_SINCE(5, 14)
+/*!
\fn void QSpinBox::valueChanged(const QString &text)
\overload
+ \obsolete Use textChanged(QString) instead
The new value is passed in \a text with prefix() and suffix().
*/
+#endif
/*!
Constructs a spin box with 0 as minimum value and 99 as maximum value, a
@@ -594,9 +606,9 @@ void QSpinBox::fixup(QString &input) const
values but can be extended to use different strings with
validate(), textFromValue() and valueFromText().
- Every time the value changes QDoubleSpinBox emits two
- valueChanged() signals, one taking providing a double and the other
- a QString. The QString overload provides the value with both
+ Every time the value changes QDoubleSpinBox emits valueChanged() and
+ textChanged() signals, the former providing a double and the latter
+ a QString. The textChanged() signal provides the value with both
prefix() and suffix(). The current value can be fetched with
value() and set with setValue().
@@ -644,12 +656,23 @@ void QSpinBox::fixup(QString &input) const
*/
/*!
+ \fn void QDoubleSpinBox::textChanged(const QString &text)
+ \since 5.14
+
+ This signal is emitted whenever the spin box's text is changed.
+ The new text is passed in \a text with prefix() and suffix().
+*/
+
+#if QT_DEPRECATED_SINCE(5, 14)
+/*!
\fn void QDoubleSpinBox::valueChanged(const QString &text);
\overload
+ \obsolete Use textChanged(QString) instead
The new value is passed in \a text with prefix() and suffix().
*/
+#endif
/*!
Constructs a spin box with 0.0 as minimum value and 99.99 as maximum value,
@@ -1068,7 +1091,13 @@ void QSpinBoxPrivate::emitSignals(EmitPolicy ep, const QVariant &old)
if (ep != NeverEmit) {
pendingEmit = false;
if (ep == AlwaysEmit || value != old) {
+#if QT_DEPRECATED_SINCE(5, 14)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
emit q->valueChanged(edit->displayText());
+QT_WARNING_POP
+#endif
+ emit q->textChanged(edit->displayText());
emit q->valueChanged(value.toInt());
}
}
@@ -1219,7 +1248,13 @@ void QDoubleSpinBoxPrivate::emitSignals(EmitPolicy ep, const QVariant &old)
if (ep != NeverEmit) {
pendingEmit = false;
if (ep == AlwaysEmit || value != old) {
+#if QT_DEPRECATED_SINCE(5, 14)
+QT_WARNING_PUSH
+QT_WARNING_DISABLE_DEPRECATED
emit q->valueChanged(edit->displayText());
+QT_WARNING_POP
+#endif
+ emit q->textChanged(edit->displayText());
emit q->valueChanged(value.toDouble());
}
}
diff --git a/src/widgets/widgets/qspinbox.h b/src/widgets/widgets/qspinbox.h
index d2eac903fb..762dd4a46a 100644
--- a/src/widgets/widgets/qspinbox.h
+++ b/src/widgets/widgets/qspinbox.h
@@ -106,7 +106,11 @@ public Q_SLOTS:
Q_SIGNALS:
void valueChanged(int);
+ void textChanged(const QString &);
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_X("Use textChanged(QString) instead")
void valueChanged(const QString &);
+#endif
private:
Q_DISABLE_COPY(QSpinBox)
@@ -168,7 +172,11 @@ public Q_SLOTS:
Q_SIGNALS:
void valueChanged(double);
+ void textChanged(const QString &);
+#if QT_DEPRECATED_SINCE(5, 14)
+ QT_DEPRECATED_X("Use textChanged(QString) instead")
void valueChanged(const QString &);
+#endif
private:
Q_DISABLE_COPY(QDoubleSpinBox)