summaryrefslogtreecommitdiffstats
path: root/src/platformsupport
diff options
context:
space:
mode:
Diffstat (limited to 'src/platformsupport')
-rw-r--r--src/platformsupport/accessibility/qaccessiblebridgeutils_p.h11
-rw-r--r--src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri4
-rw-r--r--src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp307
-rw-r--r--src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h105
-rw-r--r--src/platformsupport/clipboard/clipboard.pri2
-rw-r--r--src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h11
-rw-r--r--src/platformsupport/dbusmenu/qdbusmenutypes.cpp3
-rw-r--r--src/platformsupport/dbusmenu/qdbusmenutypes_p.h26
-rw-r--r--src/platformsupport/dbusmenu/qdbusplatformmenu_p.h11
-rw-r--r--src/platformsupport/dbustray/qdbustraytypes.cpp2
-rw-r--r--src/platformsupport/dbustray/qdbustraytypes_p.h13
-rw-r--r--src/platformsupport/dbustray/qstatusnotifieritemadaptor_p.h19
-rw-r--r--src/platformsupport/dbustray/qxdgnotificationproxy_p.h11
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_static.cpp4
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp2
-rw-r--r--src/platformsupport/eglconvenience/eglconvenience.pri24
-rw-r--r--src/platformsupport/eglconvenience/qeglconvenience_p.h1
-rw-r--r--src/platformsupport/eglconvenience/qeglpbuffer.cpp6
-rw-r--r--src/platformsupport/eglconvenience/qeglpbuffer_p.h4
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp29
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext_p.h13
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcursor.cpp410
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcursor_p.h142
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformintegration.cpp366
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformintegration_p.h122
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformscreen.cpp146
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformwindow.cpp138
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformwindow_p.h85
-rw-r--r--src/platformsupport/eglconvenience/qeglstreamconvenience.cpp112
-rw-r--r--src/platformsupport/eglconvenience/qeglstreamconvenience_p.h184
-rw-r--r--src/platformsupport/eventdispatchers/eventdispatchers.pri10
-rw-r--r--src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm628
-rw-r--r--src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h278
-rw-r--r--src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp197
-rw-r--r--src/platformsupport/eventdispatchers/qwindowsguieventdispatcher_p.h (renamed from src/platformsupport/eglconvenience/qeglplatformscreen_p.h)38
-rw-r--r--src/platformsupport/fbconvenience/qfbbackingstore_p.h6
-rw-r--r--src/platformsupport/fbconvenience/qfbscreen.cpp5
-rw-r--r--src/platformsupport/fbconvenience/qfbvthandler.cpp117
-rw-r--r--src/platformsupport/fbconvenience/qfbvthandler_p.h9
-rw-r--r--src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp24
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp23
-rw-r--r--src/platformsupport/fontdatabases/mac/coretext.pri7
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm174
-rw-r--r--src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h7
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm10
-rw-r--r--src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h2
-rw-r--r--src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp6
-rw-r--r--src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp4
-rw-r--r--src/platformsupport/input/evdevtablet/qevdevtablet.cpp2
-rw-r--r--src/platformsupport/input/evdevtablet/qevdevtablet_p.h3
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp99
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h23
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp26
-rw-r--r--src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h2
-rw-r--r--src/platformsupport/input/libinput/qlibinputhandler.cpp6
-rw-r--r--src/platformsupport/input/libinput/qlibinputkeyboard.cpp17
-rw-r--r--src/platformsupport/input/libinput/qlibinputpointer.cpp8
-rw-r--r--src/platformsupport/input/tslib/qtslib_p.h11
-rw-r--r--src/platformsupport/linuxaccessibility/atspiadaptor.cpp14
-rw-r--r--src/platformsupport/linuxaccessibility/bridge.cpp2
-rw-r--r--src/platformsupport/linuxaccessibility/bridge_p.h2
-rw-r--r--src/platformsupport/linuxaccessibility/cache.cpp3
-rw-r--r--src/platformsupport/linuxaccessibility/dbusconnection.cpp35
-rw-r--r--src/platformsupport/linuxaccessibility/dbusconnection_p.h1
-rw-r--r--src/platformsupport/linuxaccessibility/struct_marshallers_p.h32
-rw-r--r--src/platformsupport/platformcompositor/qopenglcompositor.cpp8
-rw-r--r--src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp95
-rw-r--r--src/platformsupport/platformsupport.pro1
-rw-r--r--src/platformsupport/services/genericunix/qgenericunixservices.cpp4
-rw-r--r--src/platformsupport/services/genericunix/qgenericunixservices_p.h4
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes.cpp98
-rw-r--r--src/platformsupport/themes/genericunix/qgenericunixthemes_p.h14
72 files changed, 1261 insertions, 3107 deletions
diff --git a/src/platformsupport/accessibility/qaccessiblebridgeutils_p.h b/src/platformsupport/accessibility/qaccessiblebridgeutils_p.h
index fca3e16a68..4e52e4b6fc 100644
--- a/src/platformsupport/accessibility/qaccessiblebridgeutils_p.h
+++ b/src/platformsupport/accessibility/qaccessiblebridgeutils_p.h
@@ -34,6 +34,17 @@
#ifndef QACCESSIBLEBRIDGEUTILS_H
#define QACCESSIBLEBRIDGEUTILS_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtCore/qstringlist.h>
#include <QtGui/qaccessible.h>
diff --git a/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri b/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri
deleted file mode 100644
index 9a19d3c278..0000000000
--- a/src/platformsupport/cfsocketnotifier/cfsocketnotifier.pri
+++ /dev/null
@@ -1,4 +0,0 @@
-mac {
- HEADERS += $$PWD/qcfsocketnotifier_p.h
- SOURCES += $$PWD/qcfsocketnotifier.cpp
-}
diff --git a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp
deleted file mode 100644
index b3a85292d0..0000000000
--- a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcfsocketnotifier_p.h"
-#include <QtGui/qguiapplication.h>
-#include <QtCore/qsocketnotifier.h>
-#include <QtCore/qthread.h>
-
-QT_BEGIN_NAMESPACE
-
-/**************************************************************************
- Socket Notifiers
- *************************************************************************/
-void qt_mac_socket_callback(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef,
- const void *, void *info)
-{
-
- QCFSocketNotifier *cfSocketNotifier = static_cast<QCFSocketNotifier *>(info);
- int nativeSocket = CFSocketGetNative(s);
- MacSocketInfo *socketInfo = cfSocketNotifier->macSockets.value(nativeSocket);
- QEvent notifierEvent(QEvent::SockAct);
-
- // There is a race condition that happen where we disable the notifier and
- // the kernel still has a notification to pass on. We then get this
- // notification after we've successfully disabled the CFSocket, but our Qt
- // notifier is now gone. The upshot is we have to check the notifier
- // every time.
- if (callbackType == kCFSocketReadCallBack) {
- if (socketInfo->readNotifier && socketInfo->readEnabled) {
- socketInfo->readEnabled = false;
- QGuiApplication::sendEvent(socketInfo->readNotifier, &notifierEvent);
- }
- } else if (callbackType == kCFSocketWriteCallBack) {
- if (socketInfo->writeNotifier && socketInfo->writeEnabled) {
- socketInfo->writeEnabled = false;
- QGuiApplication::sendEvent(socketInfo->writeNotifier, &notifierEvent);
- }
- }
-
- if (cfSocketNotifier->maybeCancelWaitForMoreEvents)
- cfSocketNotifier->maybeCancelWaitForMoreEvents(cfSocketNotifier->eventDispatcher);
-}
-
-/*
- Adds a loop source for the given socket to the current run loop.
-*/
-CFRunLoopSourceRef qt_mac_add_socket_to_runloop(const CFSocketRef socket)
-{
- CFRunLoopSourceRef loopSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0);
- if (!loopSource)
- return 0;
-
- CFRunLoopAddSource(CFRunLoopGetMain(), loopSource, kCFRunLoopCommonModes);
- return loopSource;
-}
-
-/*
- Removes the loop source for the given socket from the current run loop.
-*/
-void qt_mac_remove_socket_from_runloop(const CFSocketRef socket, CFRunLoopSourceRef runloop)
-{
- Q_ASSERT(runloop);
- CFRunLoopRemoveSource(CFRunLoopGetMain(), runloop, kCFRunLoopCommonModes);
- CFSocketDisableCallBacks(socket, kCFSocketReadCallBack);
- CFSocketDisableCallBacks(socket, kCFSocketWriteCallBack);
-}
-
-QCFSocketNotifier::QCFSocketNotifier()
- : eventDispatcher(0)
- , maybeCancelWaitForMoreEvents(0)
- , enableNotifiersObserver(0)
-{
-
-}
-
-QCFSocketNotifier::~QCFSocketNotifier()
-{
-
-}
-
-void QCFSocketNotifier::setHostEventDispatcher(QAbstractEventDispatcher *hostEventDispacher)
-{
- eventDispatcher = hostEventDispacher;
-}
-
-void QCFSocketNotifier::setMaybeCancelWaitForMoreEventsCallback(MaybeCancelWaitForMoreEventsFn callBack)
-{
- maybeCancelWaitForMoreEvents = callBack;
-}
-
-void QCFSocketNotifier::registerSocketNotifier(QSocketNotifier *notifier)
-{
- Q_ASSERT(notifier);
- int nativeSocket = notifier->socket();
- int type = notifier->type();
-#ifndef QT_NO_DEBUG
- if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) {
- qWarning("QSocketNotifier: Internal error");
- return;
- } else if (notifier->thread() != eventDispatcher->thread()
- || eventDispatcher->thread() != QThread::currentThread()) {
- qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");
- return;
- }
-#endif
-
- if (type == QSocketNotifier::Exception) {
- qWarning("QSocketNotifier::Exception is not supported on iOS");
- return;
- }
-
- // Check if we have a CFSocket for the native socket, create one if not.
- MacSocketInfo *socketInfo = macSockets.value(nativeSocket);
- if (!socketInfo) {
- socketInfo = new MacSocketInfo();
-
- // Create CFSocket, specify that we want both read and write callbacks (the callbacks
- // are enabled/disabled later on).
- const int callbackTypes = kCFSocketReadCallBack | kCFSocketWriteCallBack;
- CFSocketContext context = {0, this, 0, 0, 0};
- socketInfo->socket = CFSocketCreateWithNative(kCFAllocatorDefault, nativeSocket, callbackTypes, qt_mac_socket_callback, &context);
- if (CFSocketIsValid(socketInfo->socket) == false) {
- qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to create CFSocket");
- return;
- }
-
- CFOptionFlags flags = CFSocketGetSocketFlags(socketInfo->socket);
- // QSocketNotifier doesn't close the socket upon destruction/invalidation
- flags &= ~kCFSocketCloseOnInvalidate;
- // Expicitly disable automatic re-enable, as we do that manually on each runloop pass
- flags &= ~(kCFSocketAutomaticallyReenableWriteCallBack | kCFSocketAutomaticallyReenableReadCallBack);
- CFSocketSetSocketFlags(socketInfo->socket, flags);
-
- macSockets.insert(nativeSocket, socketInfo);
- }
-
- if (type == QSocketNotifier::Read) {
- Q_ASSERT(socketInfo->readNotifier == 0);
- socketInfo->readNotifier = notifier;
- socketInfo->readEnabled = false;
- } else if (type == QSocketNotifier::Write) {
- Q_ASSERT(socketInfo->writeNotifier == 0);
- socketInfo->writeNotifier = notifier;
- socketInfo->writeEnabled = false;
- }
-
- if (!enableNotifiersObserver) {
- // Create a run loop observer which enables the socket notifiers on each
- // pass of the run loop, before any sources are processed.
- CFRunLoopObserverContext context = {};
- context.info = this;
- enableNotifiersObserver = CFRunLoopObserverCreate(kCFAllocatorDefault, kCFRunLoopBeforeSources,
- true, 0, enableSocketNotifiers, &context);
- Q_ASSERT(enableNotifiersObserver);
- CFRunLoopAddObserver(CFRunLoopGetMain(), enableNotifiersObserver, kCFRunLoopCommonModes);
- }
-}
-
-void QCFSocketNotifier::unregisterSocketNotifier(QSocketNotifier *notifier)
-{
- Q_ASSERT(notifier);
- int nativeSocket = notifier->socket();
- int type = notifier->type();
-#ifndef QT_NO_DEBUG
- if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) {
- qWarning("QSocketNotifier: Internal error");
- return;
- } else if (notifier->thread() != eventDispatcher->thread() || eventDispatcher->thread() != QThread::currentThread()) {
- qWarning("QSocketNotifier: socket notifiers cannot be disabled from another thread");
- return;
- }
-#endif
-
- if (type == QSocketNotifier::Exception) {
- qWarning("QSocketNotifier::Exception is not supported on iOS");
- return;
- }
- MacSocketInfo *socketInfo = macSockets.value(nativeSocket);
- if (!socketInfo) {
- qWarning("QEventDispatcherMac::unregisterSocketNotifier: Tried to unregister a not registered notifier");
- return;
- }
-
- // Decrement read/write counters and disable callbacks if necessary.
- if (type == QSocketNotifier::Read) {
- Q_ASSERT(notifier == socketInfo->readNotifier);
- socketInfo->readNotifier = 0;
- socketInfo->readEnabled = false;
- CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
- } else if (type == QSocketNotifier::Write) {
- Q_ASSERT(notifier == socketInfo->writeNotifier);
- socketInfo->writeNotifier = 0;
- socketInfo->writeEnabled = false;
- CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
- }
-
- // Remove CFSocket from runloop if this was the last QSocketNotifier.
- if (socketInfo->readNotifier == 0 && socketInfo->writeNotifier == 0) {
- unregisterSocketInfo(socketInfo);
- delete socketInfo;
- macSockets.remove(nativeSocket);
- }
-}
-
-void QCFSocketNotifier::removeSocketNotifiers()
-{
- // Remove CFSockets from the runloop.
- foreach (MacSocketInfo *socketInfo, macSockets) {
- unregisterSocketInfo(socketInfo);
- delete socketInfo;
- }
-
- macSockets.clear();
-
- destroyRunLoopObserver();
-}
-
-void QCFSocketNotifier::destroyRunLoopObserver()
-{
- if (!enableNotifiersObserver)
- return;
-
- CFRunLoopObserverInvalidate(enableNotifiersObserver);
- CFRelease(enableNotifiersObserver);
- enableNotifiersObserver = 0;
-}
-
-void QCFSocketNotifier::unregisterSocketInfo(MacSocketInfo *socketInfo)
-{
- if (socketInfo->runloop) {
- if (CFSocketIsValid(socketInfo->socket))
- qt_mac_remove_socket_from_runloop(socketInfo->socket, socketInfo->runloop);
- CFRunLoopSourceInvalidate(socketInfo->runloop);
- CFRelease(socketInfo->runloop);
- }
- CFSocketInvalidate(socketInfo->socket);
- CFRelease(socketInfo->socket);
-}
-
-void QCFSocketNotifier::enableSocketNotifiers(CFRunLoopObserverRef ref, CFRunLoopActivity activity, void *info)
-{
- Q_UNUSED(ref);
- Q_UNUSED(activity);
-
- QCFSocketNotifier *that = static_cast<QCFSocketNotifier *>(info);
-
- foreach (MacSocketInfo *socketInfo, that->macSockets) {
- if (!CFSocketIsValid(socketInfo->socket))
- continue;
-
- if (!socketInfo->runloop) {
- // Add CFSocket to runloop.
- if (!(socketInfo->runloop = qt_mac_add_socket_to_runloop(socketInfo->socket))) {
- qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to add CFSocket to runloop");
- CFSocketInvalidate(socketInfo->socket);
- continue;
- }
-
- if (!socketInfo->readNotifier)
- CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
- if (!socketInfo->writeNotifier)
- CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
- }
-
- if (socketInfo->readNotifier && !socketInfo->readEnabled) {
- socketInfo->readEnabled = true;
- CFSocketEnableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
- }
- if (socketInfo->writeNotifier && !socketInfo->writeEnabled) {
- socketInfo->writeEnabled = true;
- CFSocketEnableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
- }
- }
-}
-
-QT_END_NAMESPACE
-
diff --git a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h b/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h
deleted file mode 100644
index 9bccc1bf98..0000000000
--- a/src/platformsupport/cfsocketnotifier/qcfsocketnotifier_p.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QCFSOCKETNOTIFIER_P_H
-#define QCFSOCKETNOTIFIER_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 <QtCore/qabstracteventdispatcher.h>
-#include <QtCore/qhash.h>
-
-#include <CoreFoundation/CoreFoundation.h>
-
-QT_BEGIN_NAMESPACE
-
-struct MacSocketInfo {
- MacSocketInfo() : socket(0), runloop(0), readNotifier(0), writeNotifier(0),
- readEnabled(false), writeEnabled(false) {}
- CFSocketRef socket;
- CFRunLoopSourceRef runloop;
- QObject *readNotifier;
- QObject *writeNotifier;
- bool readEnabled;
- bool writeEnabled;
-};
-typedef QHash<int, MacSocketInfo *> MacSocketHash;
-
-typedef void (*MaybeCancelWaitForMoreEventsFn)(QAbstractEventDispatcher *hostEventDispacher);
-
-// The CoreFoundationSocketNotifier class implements socket notifiers support using
-// CFSocket for event dispatchers running on top of the Core Foundation run loop system.
-// (currently Mac and iOS)
-//
-// The principal functions are registerSocketNotifier() and unregisterSocketNotifier().
-//
-// setHostEventDispatcher() should be called at startup.
-// removeSocketNotifiers() should be called at shutdown.
-//
-class QCFSocketNotifier
-{
-public:
- QCFSocketNotifier();
- ~QCFSocketNotifier();
- void setHostEventDispatcher(QAbstractEventDispatcher *hostEventDispacher);
- void setMaybeCancelWaitForMoreEventsCallback(MaybeCancelWaitForMoreEventsFn callBack);
- void registerSocketNotifier(QSocketNotifier *notifier);
- void unregisterSocketNotifier(QSocketNotifier *notifier);
- void removeSocketNotifiers();
-
-private:
- void destroyRunLoopObserver();
-
- static void unregisterSocketInfo(MacSocketInfo *socketInfo);
- static void enableSocketNotifiers(CFRunLoopObserverRef ref, CFRunLoopActivity activity, void *info);
-
- MacSocketHash macSockets;
- QAbstractEventDispatcher *eventDispatcher;
- MaybeCancelWaitForMoreEventsFn maybeCancelWaitForMoreEvents;
- CFRunLoopObserverRef enableNotifiersObserver;
-
- friend void qt_mac_socket_callback(CFSocketRef, CFSocketCallBackType, CFDataRef, const void *, void *);
-};
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/platformsupport/clipboard/clipboard.pri b/src/platformsupport/clipboard/clipboard.pri
index 2532430f1e..cb8315d003 100644
--- a/src/platformsupport/clipboard/clipboard.pri
+++ b/src/platformsupport/clipboard/clipboard.pri
@@ -1,5 +1,7 @@
mac {
HEADERS += $$PWD/qmacmime_p.h
OBJECTIVE_SOURCES += $$PWD/qmacmime.mm
+
+ osx: LIBS_PRIVATE += -framework AppKit
}
diff --git a/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h b/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h
index 85b5bd8d49..41ab761f12 100644
--- a/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h
+++ b/src/platformsupport/dbusmenu/qdbusmenuadaptor_p.h
@@ -45,6 +45,17 @@
#ifndef DBUSMENUADAPTOR_H
#define DBUSMENUADAPTOR_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 <QtCore/QObject>
#include <QtDBus/QtDBus>
#include "qdbusmenutypes_p.h"
diff --git a/src/platformsupport/dbusmenu/qdbusmenutypes.cpp b/src/platformsupport/dbusmenu/qdbusmenutypes.cpp
index 73957eacfe..8d5d96353c 100644
--- a/src/platformsupport/dbusmenu/qdbusmenutypes.cpp
+++ b/src/platformsupport/dbusmenu/qdbusmenutypes.cpp
@@ -208,6 +208,7 @@ QDBusMenuItemList QDBusMenuItem::items(const QList<int> &ids, const QStringList
Q_UNUSED(propertyNames)
QDBusMenuItemList ret;
QList<const QDBusPlatformMenuItem *> items = QDBusPlatformMenuItem::byIds(ids);
+ ret.reserve(items.size());
Q_FOREACH (const QDBusPlatformMenuItem *item, items)
ret << QDBusMenuItem(item);
return ret;
@@ -246,7 +247,7 @@ QDebug operator<<(QDebug d, const QDBusMenuItem &item)
{
QDebugStateSaver saver(d);
d.nospace();
- d << "QDBusMenuItem(id=" << item.m_id << ", properties=" << item.m_properties << ")";
+ d << "QDBusMenuItem(id=" << item.m_id << ", properties=" << item.m_properties << ')';
return d;
}
diff --git a/src/platformsupport/dbusmenu/qdbusmenutypes_p.h b/src/platformsupport/dbusmenu/qdbusmenutypes_p.h
index 28d16b32d5..bc9f064f88 100644
--- a/src/platformsupport/dbusmenu/qdbusmenutypes_p.h
+++ b/src/platformsupport/dbusmenu/qdbusmenutypes_p.h
@@ -34,6 +34,17 @@
#ifndef QDBUSMENUTYPES_H
#define QDBUSMENUTYPES_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QObject>
#include <QString>
#include <QDBusArgument>
@@ -46,7 +57,7 @@ QT_BEGIN_NAMESPACE
class QDBusPlatformMenu;
class QDBusPlatformMenuItem;
class QDBusMenuItem;
-typedef QList<QDBusMenuItem> QDBusMenuItemList;
+typedef QVector<QDBusMenuItem> QDBusMenuItemList;
class QDBusMenuItem
{
@@ -61,6 +72,7 @@ public:
int m_id;
QVariantMap m_properties;
};
+Q_DECLARE_TYPEINFO(QDBusMenuItem, Q_MOVABLE_TYPE);
const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuItem &item);
const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItem &item);
@@ -72,11 +84,12 @@ public:
int id;
QStringList properties;
};
+Q_DECLARE_TYPEINFO(QDBusMenuItemKeys, Q_MOVABLE_TYPE);
const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuItemKeys &keys);
const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuItemKeys &keys);
-typedef QList<QDBusMenuItemKeys> QDBusMenuItemKeysList;
+typedef QVector<QDBusMenuItemKeys> QDBusMenuItemKeysList;
class QDBusMenuLayoutItem
{
@@ -87,13 +100,14 @@ public:
int m_id;
QVariantMap m_properties;
- QList<QDBusMenuLayoutItem> m_children;
+ QVector<QDBusMenuLayoutItem> m_children;
};
+Q_DECLARE_TYPEINFO(QDBusMenuLayoutItem, Q_MOVABLE_TYPE);
const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuLayoutItem &);
const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuLayoutItem &item);
-typedef QList<QDBusMenuLayoutItem> QDBusMenuLayoutItemList;
+typedef QVector<QDBusMenuLayoutItem> QDBusMenuLayoutItemList;
class QDBusMenuEvent
{
@@ -103,11 +117,13 @@ public:
QDBusVariant m_data;
uint m_timestamp;
};
+Q_DECLARE_TYPEINFO(QDBusMenuEvent, Q_MOVABLE_TYPE); // QDBusVariant is movable, even though it cannot
+ // be marked as such until Qt 6.
const QDBusArgument &operator<<(QDBusArgument &arg, const QDBusMenuEvent &ev);
const QDBusArgument &operator>>(const QDBusArgument &arg, QDBusMenuEvent &ev);
-typedef QList<QDBusMenuEvent> QDBusMenuEventList;
+typedef QVector<QDBusMenuEvent> QDBusMenuEventList;
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const QDBusMenuItem &item);
diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h
index fdad7990e9..6d2d27463f 100644
--- a/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h
+++ b/src/platformsupport/dbusmenu/qdbusplatformmenu_p.h
@@ -33,6 +33,17 @@
#ifndef QDBUSPLATFORMMENU_H
#define QDBUSPLATFORMMENU_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.
+//
//
// W A R N I N G
// -------------
diff --git a/src/platformsupport/dbustray/qdbustraytypes.cpp b/src/platformsupport/dbustray/qdbustraytypes.cpp
index 7b7d31b7c3..83b5d5da3f 100644
--- a/src/platformsupport/dbustray/qdbustraytypes.cpp
+++ b/src/platformsupport/dbustray/qdbustraytypes.cpp
@@ -82,6 +82,8 @@ QXdgDBusImageVector iconToQXdgDBusImageVector(const QIcon &icon)
sizes.append(QSize(IconNormalSmallSize * dpr, IconNormalSmallSize * dpr));
if (!hasMediumIcon)
sizes.append(QSize(IconNormalMediumSize * dpr, IconNormalMediumSize * dpr));
+
+ ret.reserve(sizes.size());
foreach (QSize size, sizes) {
// Protocol specifies ARGB32 format in network byte order
QImage im = icon.pixmap(size).toImage().convertToFormat(QImage::Format_ARGB32);
diff --git a/src/platformsupport/dbustray/qdbustraytypes_p.h b/src/platformsupport/dbustray/qdbustraytypes_p.h
index 4e7ae70a96..d8e52b932d 100644
--- a/src/platformsupport/dbustray/qdbustraytypes_p.h
+++ b/src/platformsupport/dbustray/qdbustraytypes_p.h
@@ -35,6 +35,17 @@
#ifndef QDBUSTRAYTYPES_P_H
#define QDBUSTRAYTYPES_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#ifndef QT_NO_SYSTEMTRAYICON
#include <QObject>
@@ -56,6 +67,7 @@ struct QXdgDBusImageStruct
int height;
QByteArray data;
};
+Q_DECLARE_TYPEINFO(QXdgDBusImageStruct, Q_MOVABLE_TYPE);
typedef QVector<QXdgDBusImageStruct> QXdgDBusImageVector;
@@ -69,6 +81,7 @@ struct QXdgDBusToolTipStruct
QString title;
QString subTitle;
};
+Q_DECLARE_TYPEINFO(QXdgDBusToolTipStruct, Q_MOVABLE_TYPE);
const QDBusArgument &operator<<(QDBusArgument &argument, const QXdgDBusImageStruct &icon);
const QDBusArgument &operator>>(const QDBusArgument &argument, QXdgDBusImageStruct &icon);
diff --git a/src/platformsupport/dbustray/qstatusnotifieritemadaptor_p.h b/src/platformsupport/dbustray/qstatusnotifieritemadaptor_p.h
index 56fbb75d7a..46f605a480 100644
--- a/src/platformsupport/dbustray/qstatusnotifieritemadaptor_p.h
+++ b/src/platformsupport/dbustray/qstatusnotifieritemadaptor_p.h
@@ -45,6 +45,17 @@
#ifndef QSTATUSNOTIFIERITEMADAPTER_P_H
#define QSTATUSNOTIFIERITEMADAPTER_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.
+//
+
#ifndef QT_NO_SYSTEMTRAYICON
#include <QtCore/QObject>
@@ -75,19 +86,19 @@ class QStatusNotifierItemAdaptor: public QDBusAbstractAdaptor
" <property access=\"read\" type=\"o\" name=\"Menu\"/>\n"
" <property access=\"read\" type=\"b\" name=\"ItemIsMenu\"/>\n"
" <property access=\"read\" type=\"s\" name=\"IconName\"/>\n"
-" <property access=\"read\" type=\"(iiay)\" name=\"IconPixmap\">\n"
+" <property access=\"read\" type=\"a(iiay)\" name=\"IconPixmap\">\n"
" <annotation value=\"QXdgDBusImageVector\" name=\"org.qtproject.QtDBus.QtTypeName\"/>\n"
" </property>\n"
" <property access=\"read\" type=\"s\" name=\"OverlayIconName\"/>\n"
-" <property access=\"read\" type=\"(iiay)\" name=\"OverlayIconPixmap\">\n"
+" <property access=\"read\" type=\"a(iiay)\" name=\"OverlayIconPixmap\">\n"
" <annotation value=\"QXdgDBusImageVector\" name=\"org.qtproject.QtDBus.QtTypeName\"/>\n"
" </property>\n"
" <property access=\"read\" type=\"s\" name=\"AttentionIconName\"/>\n"
-" <property access=\"read\" type=\"(iiay)\" name=\"AttentionIconPixmap\">\n"
+" <property access=\"read\" type=\"a(iiay)\" name=\"AttentionIconPixmap\">\n"
" <annotation value=\"QXdgDBusImageVector\" name=\"org.qtproject.QtDBus.QtTypeName\"/>\n"
" </property>\n"
" <property access=\"read\" type=\"s\" name=\"AttentionMovieName\"/>\n"
-" <property access=\"read\" type=\"(s(iiay)ss)\" name=\"ToolTip\">\n"
+" <property access=\"read\" type=\"(sa(iiay)ss)\" name=\"ToolTip\">\n"
" <annotation value=\"QXdgDBusToolTipStruct\" name=\"org.qtproject.QtDBus.QtTypeName\"/>\n"
" </property>\n"
" <method name=\"ContextMenu\">\n"
diff --git a/src/platformsupport/dbustray/qxdgnotificationproxy_p.h b/src/platformsupport/dbustray/qxdgnotificationproxy_p.h
index 3e573cb118..5c74405ae8 100644
--- a/src/platformsupport/dbustray/qxdgnotificationproxy_p.h
+++ b/src/platformsupport/dbustray/qxdgnotificationproxy_p.h
@@ -45,6 +45,17 @@
#ifndef QXDGNOTIFICATIONPROXY_P_H
#define QXDGNOTIFICATIONPROXY_P_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QtCore/QObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp
index 1bc834b5ef..3aab785b34 100644
--- a/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_static.cpp
@@ -90,7 +90,7 @@ QStringList QDeviceDiscoveryStatic::scanConnectedDevices()
if (m_types & Device_InputMask) {
dir.setPath(QString::fromLatin1(QT_EVDEV_DEVICE_PATH));
foreach (const QString &deviceFile, dir.entryList()) {
- QString absoluteFilePath = dir.absolutePath() + QString::fromLatin1("/") + deviceFile;
+ QString absoluteFilePath = dir.absolutePath() + QLatin1Char('/') + deviceFile;
if (checkDeviceType(absoluteFilePath))
devices << absoluteFilePath;
}
@@ -100,7 +100,7 @@ QStringList QDeviceDiscoveryStatic::scanConnectedDevices()
if (m_types & Device_VideoMask) {
dir.setPath(QString::fromLatin1(QT_DRM_DEVICE_PATH));
foreach (const QString &deviceFile, dir.entryList()) {
- QString absoluteFilePath = dir.absolutePath() + QString::fromLatin1("/") + deviceFile;
+ QString absoluteFilePath = dir.absolutePath() + QLatin1Char('/') + deviceFile;
if (checkDeviceType(absoluteFilePath))
devices << absoluteFilePath;
}
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
index 8fa82e2ad7..f285e61a9f 100644
--- a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
@@ -210,7 +210,7 @@ bool QDeviceDiscoveryUDev::checkDeviceType(udev_device *dev)
if ((m_types & Device_Keyboard) && (qstrcmp(udev_device_get_property_value(dev, "ID_INPUT_KEYBOARD"), "1") == 0 )) {
const char *capabilities_key = udev_device_get_sysattr_value(dev, "capabilities/key");
- QStringList val = QString::fromUtf8(capabilities_key).split(QString::fromUtf8(" "), QString::SkipEmptyParts);
+ QStringList val = QString::fromUtf8(capabilities_key).split(QLatin1Char(' '), QString::SkipEmptyParts);
if (!val.isEmpty()) {
bool ok;
unsigned long long keys = val.last().toULongLong(&ok, 16);
diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri
index d102203d5e..f1e0d58a6d 100644
--- a/src/platformsupport/eglconvenience/eglconvenience.pri
+++ b/src/platformsupport/eglconvenience/eglconvenience.pri
@@ -1,29 +1,18 @@
contains(QT_CONFIG,egl) {
HEADERS += \
$$PWD/qeglconvenience_p.h \
- $$PWD/qeglpbuffer_p.h
+ $$PWD/qeglstreamconvenience_p.h
SOURCES += \
$$PWD/qeglconvenience.cpp \
- $$PWD/qeglpbuffer.cpp
+ $$PWD/qeglstreamconvenience.cpp
contains(QT_CONFIG,opengl) {
- HEADERS += $$PWD/qeglplatformcontext_p.h
- SOURCES += $$PWD/qeglplatformcontext.cpp
+ HEADERS += $$PWD/qeglplatformcontext_p.h \
+ $$PWD/qeglpbuffer_p.h
- unix {
- HEADERS += \
- $$PWD/qeglplatformcursor_p.h \
- $$PWD/qeglplatformwindow_p.h \
- $$PWD/qeglplatformscreen_p.h \
- $$PWD/qeglplatformintegration_p.h
-
- SOURCES += \
- $$PWD/qeglplatformcursor.cpp \
- $$PWD/qeglplatformwindow.cpp \
- $$PWD/qeglplatformscreen.cpp \
- $$PWD/qeglplatformintegration.cpp
- }
+ SOURCES += $$PWD/qeglplatformcontext.cpp \
+ $$PWD/qeglpbuffer.cpp
}
# Avoid X11 header collision
@@ -34,6 +23,7 @@ contains(QT_CONFIG,egl) {
$$PWD/qxlibeglintegration_p.h
SOURCES += \
$$PWD/qxlibeglintegration.cpp
+ LIBS_PRIVATE += $$QMAKE_LIBS_X11
}
CONFIG += egl
}
diff --git a/src/platformsupport/eglconvenience/qeglconvenience_p.h b/src/platformsupport/eglconvenience/qeglconvenience_p.h
index 59441d8c9a..ec6f668cba 100644
--- a/src/platformsupport/eglconvenience/qeglconvenience_p.h
+++ b/src/platformsupport/eglconvenience/qeglconvenience_p.h
@@ -88,7 +88,6 @@ public:
protected:
virtual bool filterConfig(EGLConfig config) const;
-private:
QSurfaceFormat m_format;
EGLDisplay m_display;
EGLint m_surfaceType;
diff --git a/src/platformsupport/eglconvenience/qeglpbuffer.cpp b/src/platformsupport/eglconvenience/qeglpbuffer.cpp
index 756609a641..d1a31642b2 100644
--- a/src/platformsupport/eglconvenience/qeglpbuffer.cpp
+++ b/src/platformsupport/eglconvenience/qeglpbuffer.cpp
@@ -49,13 +49,15 @@ QT_BEGIN_NAMESPACE
and return a new instance of this class.
*/
-QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface)
+QEGLPbuffer::QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface,
+ QEGLPlatformContext::Flags flags)
: QPlatformOffscreenSurface(offscreenSurface)
, m_format(format)
, m_display(display)
, m_pbuffer(EGL_NO_SURFACE)
{
- bool hasSurfaceless = q_hasEglExtension(display, "EGL_KHR_surfaceless_context");
+ bool hasSurfaceless = !flags.testFlag(QEGLPlatformContext::NoSurfaceless)
+ && q_hasEglExtension(display, "EGL_KHR_surfaceless_context");
// Disable surfaceless contexts on Mesa for now. As of 10.6.0 and Intel at least, some
// operations (glReadPixels) are unable to work without a surface since they at some
diff --git a/src/platformsupport/eglconvenience/qeglpbuffer_p.h b/src/platformsupport/eglconvenience/qeglpbuffer_p.h
index 3372c0735d..81fdab8901 100644
--- a/src/platformsupport/eglconvenience/qeglpbuffer_p.h
+++ b/src/platformsupport/eglconvenience/qeglpbuffer_p.h
@@ -47,13 +47,15 @@
#include <EGL/egl.h>
#include <qpa/qplatformoffscreensurface.h>
+#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
QT_BEGIN_NAMESPACE
class QEGLPbuffer : public QPlatformOffscreenSurface
{
public:
- QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface);
+ QEGLPbuffer(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface,
+ QEGLPlatformContext::Flags flags = 0);
~QEGLPbuffer();
QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; }
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
index bffb0eb4e8..f5ba587293 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
@@ -106,11 +106,12 @@ QT_BEGIN_NAMESPACE
#endif
QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
- EGLConfig *config, const QVariant &nativeHandle)
+ EGLConfig *config, const QVariant &nativeHandle, Flags flags)
: m_eglDisplay(display)
, m_swapInterval(-1)
, m_swapIntervalEnvChecked(false)
, m_swapIntervalFromEnv(-1)
+ , m_flags(flags)
{
if (nativeHandle.isNull()) {
m_eglConfig = config ? *config : q_configFromGLFormat(display, format);
@@ -158,6 +159,7 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont
}
}
contextAttrs.append(EGL_NONE);
+ m_contextAttrs = contextAttrs;
switch (m_format.renderableType()) {
case QSurfaceFormat::OpenVG:
@@ -248,6 +250,8 @@ void QEGLPlatformContext::initialize()
updateFormatFromGL();
}
+// Base implementation for pbuffers. Subclasses will handle the specialized cases for
+// platforms without pbuffers.
EGLSurface QEGLPlatformContext::createTemporaryOffscreenSurface()
{
// Make the context current to ensure the GL version query works. This needs a surface too.
@@ -271,6 +275,12 @@ void QEGLPlatformContext::destroyTemporaryOffscreenSurface(EGLSurface surface)
eglDestroySurface(m_eglDisplay, surface);
}
+void QEGLPlatformContext::runGLChecks()
+{
+ // Nothing to do here, subclasses may override in order to perform OpenGL
+ // queries needing a context.
+}
+
void QEGLPlatformContext::updateFormatFromGL()
{
#ifndef QT_NO_OPENGL
@@ -287,10 +297,18 @@ void QEGLPlatformContext::updateFormatFromGL()
// avoid creating an extra pbuffer surface which is apparently troublesome with some
// drivers (Mesa) when certain attributes are present (multisampling).
EGLSurface tempSurface = EGL_NO_SURFACE;
- if (!q_hasEglExtension(m_eglDisplay, "EGL_KHR_surfaceless_context"))
+ EGLContext tempContext = EGL_NO_CONTEXT;
+ if (m_flags.testFlag(NoSurfaceless) || !q_hasEglExtension(m_eglDisplay, "EGL_KHR_surfaceless_context"))
tempSurface = createTemporaryOffscreenSurface();
- if (eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, m_eglContext)) {
+ EGLBoolean ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, m_eglContext);
+ if (!ok) {
+ EGLConfig config = q_configFromGLFormat(m_eglDisplay, m_format, false, EGL_PBUFFER_BIT);
+ tempContext = eglCreateContext(m_eglDisplay, config, 0, m_contextAttrs.constData());
+ if (tempContext != EGL_NO_CONTEXT)
+ ok = eglMakeCurrent(m_eglDisplay, tempSurface, tempSurface, tempContext);
+ }
+ if (ok) {
if (m_format.renderableType() == QSurfaceFormat::OpenGL
|| m_format.renderableType() == QSurfaceFormat::OpenGLES) {
const GLubyte *s = glGetString(GL_VERSION);
@@ -334,12 +352,15 @@ void QEGLPlatformContext::updateFormatFromGL()
}
}
}
+ runGLChecks();
eglMakeCurrent(prevDisplay, prevSurfaceDraw, prevSurfaceRead, prevContext);
} else {
- qWarning("QEGLPlatformContext: Failed to make temporary surface current, format not updated");
+ qWarning("QEGLPlatformContext: Failed to make temporary surface current, format not updated (%x)", eglGetError());
}
if (tempSurface != EGL_NO_SURFACE)
destroyTemporaryOffscreenSurface(tempSurface);
+ if (tempContext != EGL_NO_CONTEXT)
+ eglDestroyContext(m_eglDisplay, tempContext);
#endif // QT_NO_OPENGL
}
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
index 50c264e1dc..41601272a3 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h
@@ -56,8 +56,14 @@ QT_BEGIN_NAMESPACE
class QEGLPlatformContext : public QPlatformOpenGLContext
{
public:
+ enum Flag {
+ NoSurfaceless = 0x01
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
QEGLPlatformContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
- EGLConfig *config = 0, const QVariant &nativeHandle = QVariant());
+ EGLConfig *config = 0, const QVariant &nativeHandle = QVariant(),
+ Flags flags = 0);
~QEGLPlatformContext();
void initialize() Q_DECL_OVERRIDE;
@@ -78,6 +84,7 @@ protected:
virtual EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) = 0;
virtual EGLSurface createTemporaryOffscreenSurface();
virtual void destroyTemporaryOffscreenSurface(EGLSurface surface);
+ virtual void runGLChecks();
private:
void init(const QSurfaceFormat &format, QPlatformOpenGLContext *share);
@@ -93,9 +100,13 @@ private:
int m_swapInterval;
bool m_swapIntervalEnvChecked;
int m_swapIntervalFromEnv;
+ Flags m_flags;
bool m_ownsContext;
+ QVector<EGLint> m_contextAttrs;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QEGLPlatformContext::Flags)
+
QT_END_NAMESPACE
#endif //QEGLPLATFORMCONTEXT_H
diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp b/src/platformsupport/eglconvenience/qeglplatformcursor.cpp
deleted file mode 100644
index 09243487c7..0000000000
--- a/src/platformsupport/eglconvenience/qeglplatformcursor.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qpa/qwindowsysteminterface.h>
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QOpenGLShaderProgram>
-#include <QtCore/QJsonDocument>
-#include <QtCore/QJsonArray>
-#include <QtCore/QJsonObject>
-#include <QtDebug>
-
-#include <QtGui/private/qguiapplication_p.h>
-
-#include "qeglplatformcursor_p.h"
-#include "qeglplatformintegration_p.h"
-#include "qeglplatformscreen_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QEGLPlatformCursor
- \brief Mouse cursor implementation using OpenGL.
- \since 5.2
- \internal
- \ingroup qpa
- */
-
-QEGLPlatformCursor::QEGLPlatformCursor(QPlatformScreen *screen)
- : m_visible(true),
- m_screen(static_cast<QEGLPlatformScreen *>(screen)),
- m_program(0),
- m_vertexCoordEntry(0),
- m_textureCoordEntry(0),
- m_textureEntry(0),
- m_deviceListener(0),
- m_updateRequested(false)
-{
- QByteArray hideCursorVal = qgetenv("QT_QPA_EGLFS_HIDECURSOR");
- if (!hideCursorVal.isEmpty())
- m_visible = hideCursorVal.toInt() == 0;
- if (!m_visible)
- return;
-
- // Try to load the cursor atlas. If this fails, m_visible is set to false and
- // paintOnScreen() and setCurrentCursor() become no-ops.
- initCursorAtlas();
-
- // initialize the cursor
-#ifndef QT_NO_CURSOR
- QCursor cursor(Qt::ArrowCursor);
- setCurrentCursor(&cursor);
-#endif
-
- m_deviceListener = new QEGLPlatformCursorDeviceListener(this);
- connect(QGuiApplicationPrivate::inputDeviceManager(), &QInputDeviceManager::deviceListChanged,
- m_deviceListener, &QEGLPlatformCursorDeviceListener::onDeviceListChanged);
- updateMouseStatus();
-}
-
-QEGLPlatformCursor::~QEGLPlatformCursor()
-{
- resetResources();
- delete m_deviceListener;
-}
-
-void QEGLPlatformCursor::updateMouseStatus()
-{
- m_visible = m_deviceListener->hasMouse();
-}
-
-bool QEGLPlatformCursorDeviceListener::hasMouse() const
-{
- return QGuiApplicationPrivate::inputDeviceManager()->deviceCount(QInputDeviceManager::DeviceTypePointer) > 0;
-}
-
-void QEGLPlatformCursorDeviceListener::onDeviceListChanged(QInputDeviceManager::DeviceType type)
-{
- if (type == QInputDeviceManager::DeviceTypePointer)
- m_cursor->updateMouseStatus();
-}
-
-void QEGLPlatformCursor::resetResources()
-{
- if (QOpenGLContext::currentContext()) {
- delete m_program;
- glDeleteTextures(1, &m_cursor.customCursorTexture);
- glDeleteTextures(1, &m_cursorAtlas.texture);
- }
- m_program = 0;
- m_cursor.customCursorTexture = 0;
- m_cursor.customCursorPending = !m_cursor.customCursorImage.isNull();
- m_cursorAtlas.texture = 0;
-}
-
-void QEGLPlatformCursor::createShaderPrograms()
-{
- static const char *textureVertexProgram =
- "attribute highp vec2 vertexCoordEntry;\n"
- "attribute highp vec2 textureCoordEntry;\n"
- "varying highp vec2 textureCoord;\n"
- "void main() {\n"
- " textureCoord = textureCoordEntry;\n"
- " gl_Position = vec4(vertexCoordEntry, 1.0, 1.0);\n"
- "}\n";
-
- static const char *textureFragmentProgram =
- "uniform sampler2D texture;\n"
- "varying highp vec2 textureCoord;\n"
- "void main() {\n"
- " gl_FragColor = texture2D(texture, textureCoord).bgra;\n"
- "}\n";
-
- m_program = new QOpenGLShaderProgram;
- m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
- m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
- m_program->link();
-
- m_vertexCoordEntry = m_program->attributeLocation("vertexCoordEntry");
- m_textureCoordEntry = m_program->attributeLocation("textureCoordEntry");
- m_textureEntry = m_program->uniformLocation("texture");
-}
-
-void QEGLPlatformCursor::createCursorTexture(uint *texture, const QImage &image)
-{
- if (!*texture)
- glGenTextures(1, texture);
- glBindTexture(GL_TEXTURE_2D, *texture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glTexImage2D(GL_TEXTURE_2D, 0 /* level */, GL_RGBA, image.width(), image.height(), 0 /* border */,
- GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
-}
-
-void QEGLPlatformCursor::initCursorAtlas()
-{
- static QByteArray json = qgetenv("QT_QPA_EGLFS_CURSOR");
- if (json.isEmpty())
- json = ":/cursor.json";
-
- QFile file(QString::fromUtf8(json));
- if (!file.open(QFile::ReadOnly)) {
- m_visible = false;
- return;
- }
-
- QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
- QJsonObject object = doc.object();
-
- QString atlas = object.value(QLatin1String("image")).toString();
- Q_ASSERT(!atlas.isEmpty());
-
- const int cursorsPerRow = object.value(QLatin1String("cursorsPerRow")).toDouble();
- Q_ASSERT(cursorsPerRow);
- m_cursorAtlas.cursorsPerRow = cursorsPerRow;
-
- const QJsonArray hotSpots = object.value(QLatin1String("hotSpots")).toArray();
- Q_ASSERT(hotSpots.count() == Qt::LastCursor + 1);
- for (int i = 0; i < hotSpots.count(); i++) {
- QPoint hotSpot(hotSpots[i].toArray()[0].toDouble(), hotSpots[i].toArray()[1].toDouble());
- m_cursorAtlas.hotSpots << hotSpot;
- }
-
- QImage image = QImage(atlas).convertToFormat(QImage::Format_ARGB32_Premultiplied);
- m_cursorAtlas.cursorWidth = image.width() / m_cursorAtlas.cursorsPerRow;
- m_cursorAtlas.cursorHeight = image.height() / ((Qt::LastCursor + cursorsPerRow) / cursorsPerRow);
- m_cursorAtlas.width = image.width();
- m_cursorAtlas.height = image.height();
- m_cursorAtlas.image = image;
-}
-
-#ifndef QT_NO_CURSOR
-void QEGLPlatformCursor::changeCursor(QCursor *cursor, QWindow *window)
-{
- Q_UNUSED(window);
- const QRect oldCursorRect = cursorRect();
- if (setCurrentCursor(cursor))
- update(oldCursorRect | cursorRect());
-}
-
-bool QEGLPlatformCursor::setCurrentCursor(QCursor *cursor)
-{
- if (!m_visible)
- return false;
-
- const Qt::CursorShape newShape = cursor ? cursor->shape() : Qt::ArrowCursor;
- if (m_cursor.shape == newShape && newShape != Qt::BitmapCursor)
- return false;
-
- if (m_cursor.shape == Qt::BitmapCursor) {
- m_cursor.customCursorImage = QImage();
- m_cursor.customCursorPending = false;
- }
- m_cursor.shape = newShape;
- if (newShape != Qt::BitmapCursor) { // standard cursor
- const float ws = (float)m_cursorAtlas.cursorWidth / m_cursorAtlas.width,
- hs = (float)m_cursorAtlas.cursorHeight / m_cursorAtlas.height;
- m_cursor.textureRect = QRectF(ws * (m_cursor.shape % m_cursorAtlas.cursorsPerRow),
- hs * (m_cursor.shape / m_cursorAtlas.cursorsPerRow),
- ws, hs);
- m_cursor.hotSpot = m_cursorAtlas.hotSpots[m_cursor.shape];
- m_cursor.texture = m_cursorAtlas.texture;
- m_cursor.size = QSize(m_cursorAtlas.cursorWidth, m_cursorAtlas.cursorHeight);
- } else {
- QImage image = cursor->pixmap().toImage();
- m_cursor.textureRect = QRectF(0, 0, 1, 1);
- m_cursor.hotSpot = cursor->hotSpot();
- m_cursor.texture = 0; // will get updated in the next render()
- m_cursor.size = image.size();
- m_cursor.customCursorImage = image;
- m_cursor.customCursorPending = true;
- }
-
- return true;
-}
-#endif
-
-class CursorUpdateEvent : public QEvent
-{
-public:
- CursorUpdateEvent(const QPoint &pos, const QRegion &rgn)
- : QEvent(QEvent::Type(QEvent::User + 1)),
- m_pos(pos),
- m_region(rgn)
- { }
- QPoint pos() const { return m_pos; }
- QRegion region() const { return m_region; }
-
-private:
- QPoint m_pos;
- QRegion m_region;
-};
-
-bool QEGLPlatformCursor::event(QEvent *e)
-{
- if (e->type() == QEvent::User + 1) {
- CursorUpdateEvent *ev = static_cast<CursorUpdateEvent *>(e);
- m_updateRequested = false;
- QWindowSystemInterface::handleExposeEvent(m_screen->topLevelAt(ev->pos()), ev->region());
- QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
- return true;
- }
- return QPlatformCursor::event(e);
-}
-
-void QEGLPlatformCursor::update(const QRegion &rgn)
-{
- if (!m_updateRequested) {
- // Must not flush the window system events directly from here since we are likely to
- // be a called directly from QGuiApplication's processMouseEvents. Flushing events
- // could cause reentering by dispatching more queued mouse events.
- m_updateRequested = true;
- QCoreApplication::postEvent(this, new CursorUpdateEvent(m_cursor.pos, rgn));
- }
-}
-
-QRect QEGLPlatformCursor::cursorRect() const
-{
- return QRect(m_cursor.pos - m_cursor.hotSpot, m_cursor.size);
-}
-
-QPoint QEGLPlatformCursor::pos() const
-{
- return m_cursor.pos;
-}
-
-void QEGLPlatformCursor::setPos(const QPoint &pos)
-{
- QGuiApplicationPrivate::inputDeviceManager()->setCursorPos(pos);
- const QRect oldCursorRect = cursorRect();
- m_cursor.pos = pos;
- update(oldCursorRect | cursorRect());
- m_screen->handleCursorMove(m_cursor.pos);
-}
-
-void QEGLPlatformCursor::pointerEvent(const QMouseEvent &event)
-{
- if (event.type() != QEvent::MouseMove)
- return;
- const QRect oldCursorRect = cursorRect();
- m_cursor.pos = event.screenPos().toPoint();
- update(oldCursorRect | cursorRect());
- m_screen->handleCursorMove(m_cursor.pos);
-}
-
-void QEGLPlatformCursor::paintOnScreen()
-{
- if (!m_visible)
- return;
-
- const QRectF cr = cursorRect();
- const QRect screenRect(m_screen->geometry());
- const GLfloat x1 = 2 * (cr.left() / screenRect.width()) - 1;
- const GLfloat x2 = 2 * (cr.right() / screenRect.width()) - 1;
- const GLfloat y1 = 1 - (cr.top() / screenRect.height()) * 2;
- const GLfloat y2 = 1 - (cr.bottom() / screenRect.height()) * 2;
- QRectF r(QPointF(x1, y1), QPointF(x2, y2));
-
- draw(r);
-}
-
-void QEGLPlatformCursor::draw(const QRectF &r)
-{
- if (!m_program) {
- // one time initialization
- initializeOpenGLFunctions();
-
- createShaderPrograms();
-
- if (!m_cursorAtlas.texture) {
- createCursorTexture(&m_cursorAtlas.texture, m_cursorAtlas.image);
-
- if (m_cursor.shape != Qt::BitmapCursor)
- m_cursor.texture = m_cursorAtlas.texture;
- }
- }
-
- if (m_cursor.shape == Qt::BitmapCursor && m_cursor.customCursorPending) {
- // upload the custom cursor
- createCursorTexture(&m_cursor.customCursorTexture, m_cursor.customCursorImage);
- m_cursor.texture = m_cursor.customCursorTexture;
- m_cursor.customCursorPending = false;
- }
-
- Q_ASSERT(m_cursor.texture);
-
- m_program->bind();
-
- const GLfloat x1 = r.left();
- const GLfloat x2 = r.right();
- const GLfloat y1 = r.top();
- const GLfloat y2 = r.bottom();
- const GLfloat cursorCoordinates[] = {
- x1, y2,
- x2, y2,
- x1, y1,
- x2, y1
- };
-
- const GLfloat s1 = m_cursor.textureRect.left();
- const GLfloat s2 = m_cursor.textureRect.right();
- const GLfloat t1 = m_cursor.textureRect.top();
- const GLfloat t2 = m_cursor.textureRect.bottom();
- const GLfloat textureCoordinates[] = {
- s1, t2,
- s2, t2,
- s1, t1,
- s2, t1
- };
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, m_cursor.texture);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- m_program->enableAttributeArray(m_vertexCoordEntry);
- m_program->enableAttributeArray(m_textureCoordEntry);
-
- m_program->setAttributeArray(m_vertexCoordEntry, cursorCoordinates, 2);
- m_program->setAttributeArray(m_textureCoordEntry, textureCoordinates, 2);
-
- m_program->setUniformValue(m_textureEntry, 0);
-
- glDisable(GL_CULL_FACE);
- glFrontFace(GL_CCW);
- glEnable(GL_BLEND);
- glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- glDisable(GL_DEPTH_TEST); // disable depth testing to make sure cursor is always on top
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
- glDisable(GL_BLEND);
-
- glBindTexture(GL_TEXTURE_2D, 0);
- m_program->disableAttributeArray(m_textureCoordEntry);
- m_program->disableAttributeArray(m_vertexCoordEntry);
-
- m_program->release();
-}
-
-QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h b/src/platformsupport/eglconvenience/qeglplatformcursor_p.h
deleted file mode 100644
index b89dd1ca43..0000000000
--- a/src/platformsupport/eglconvenience/qeglplatformcursor_p.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEGLPLATFORMCURSOR_H
-#define QEGLPLATFORMCURSOR_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/qplatformcursor.h>
-#include <qpa/qplatformscreen.h>
-#include <QtGui/QOpenGLFunctions>
-#include <QtGui/private/qinputdevicemanager_p.h>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenGLShaderProgram;
-class QEGLPlatformCursor;
-class QEGLPlatformScreen;
-
-class QEGLPlatformCursorDeviceListener : public QObject
-{
- Q_OBJECT
-
-public:
- QEGLPlatformCursorDeviceListener(QEGLPlatformCursor *cursor) : m_cursor(cursor) { }
- bool hasMouse() const;
-
-public slots:
- void onDeviceListChanged(QInputDeviceManager::DeviceType type);
-
-private:
- QEGLPlatformCursor *m_cursor;
-};
-
-class QEGLPlatformCursor : public QPlatformCursor, protected QOpenGLFunctions
-{
- Q_OBJECT
-public:
- QEGLPlatformCursor(QPlatformScreen *screen);
- ~QEGLPlatformCursor();
-
-#ifndef QT_NO_CURSOR
- void changeCursor(QCursor *cursor, QWindow *widget) Q_DECL_OVERRIDE;
-#endif
- void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE;
- QPoint pos() const Q_DECL_OVERRIDE;
- void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
-
- QRect cursorRect() const;
- void paintOnScreen();
- void resetResources();
-
- void updateMouseStatus();
-
-private:
- bool event(QEvent *e) Q_DECL_OVERRIDE;
-#ifndef QT_NO_CURSOR
- bool setCurrentCursor(QCursor *cursor);
-#endif
- void draw(const QRectF &rect);
- void update(const QRegion &region);
- void createShaderPrograms();
- void createCursorTexture(uint *texture, const QImage &image);
- void initCursorAtlas();
-
- // current cursor information
- struct Cursor {
- Cursor() : texture(0), shape(Qt::BlankCursor), customCursorTexture(0), customCursorPending(false) { }
- uint texture; // a texture from 'image' or the atlas
- Qt::CursorShape shape;
- QRectF textureRect; // normalized rect inside texture
- QSize size; // size of the cursor
- QPoint hotSpot;
- QImage customCursorImage;
- QPoint pos; // current cursor position
- uint customCursorTexture;
- bool customCursorPending;
- } m_cursor;
-
- // cursor atlas information
- struct CursorAtlas {
- CursorAtlas() : cursorsPerRow(0), texture(0), cursorWidth(0), cursorHeight(0) { }
- int cursorsPerRow;
- uint texture;
- int width, height; // width and height of the atlas
- int cursorWidth, cursorHeight; // width and height of cursors inside the atlas
- QList<QPoint> hotSpots;
- QImage image; // valid until it's uploaded
- } m_cursorAtlas;
-
- bool m_visible;
- QEGLPlatformScreen *m_screen;
- QOpenGLShaderProgram *m_program;
- int m_vertexCoordEntry;
- int m_textureCoordEntry;
- int m_textureEntry;
- QEGLPlatformCursorDeviceListener *m_deviceListener;
- bool m_updateRequested;
-};
-
-QT_END_NAMESPACE
-
-#endif // QEGLPLATFORMCURSOR_H
diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp b/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
deleted file mode 100644
index 1868ff1665..0000000000
--- a/src/platformsupport/eglconvenience/qeglplatformintegration.cpp
+++ /dev/null
@@ -1,366 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QtGui/QWindow>
-#include <QtGui/QOpenGLContext>
-#include <QtGui/QOffscreenSurface>
-#include <QtGui/QGuiApplication>
-#include <QtGui/private/qguiapplication_p.h>
-#include <qpa/qwindowsysteminterface.h>
-#include <qpa/qplatforminputcontextfactory_p.h>
-
-#include <QtPlatformSupport/private/qgenericunixfontdatabase_p.h>
-#include <QtPlatformSupport/private/qgenericunixservices_p.h>
-#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
-#include <QtPlatformSupport/private/qfbvthandler_p.h>
-#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h>
-
-#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
-#include <QtPlatformSupport/private/qevdevmousemanager_p.h>
-#include <QtPlatformSupport/private/qevdevkeyboardmanager_p.h>
-#include <QtPlatformSupport/private/qevdevtouchmanager_p.h>
-#endif
-
-#if !defined(QT_NO_TSLIB) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
-#include <QtPlatformSupport/private/qtslib_p.h>
-#endif
-
-#include <QtPlatformHeaders/qeglfsfunctions.h>
-
-#include "qeglplatformintegration_p.h"
-#include "qeglplatformcontext_p.h"
-#include "qeglplatformwindow_p.h"
-#include "qeglplatformscreen_p.h"
-#include "qeglplatformcursor_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QEGLPlatformIntegration
- \brief Base class for EGL-based QPlatformIntegration implementations.
- \since 5.2
- \internal
- \ingroup qpa
-
- This class provides most of the necessary platform integration for
- an EGL-based Unix system. Platform plugins must subclass this and
- reimplement the virtuals for creating platform screens and windows
- since they will most likely wish to use a subclass for these.
-
- The backing store, native interface accessors, font database,
- basic capability flags, etc. are provided out of the box, no
- further customization is needed.
-
- \note It is critical that this class' implementation of
- initialize() is called. Therefore subclasses should either avoid
- to reimplement this function or call the base class
- implementation.
- */
-
-QEGLPlatformIntegration::QEGLPlatformIntegration()
- : m_display(EGL_NO_DISPLAY),
- m_inputContext(0),
- m_fontDb(new QGenericUnixFontDatabase),
- m_services(new QGenericUnixServices),
- m_kbdMgr(0)
-{
-}
-
-QEGLPlatformIntegration::~QEGLPlatformIntegration()
-{
-}
-
-void QEGLPlatformIntegration::initialize()
-{
- m_display = eglGetDisplay(nativeDisplay());
- if (m_display == EGL_NO_DISPLAY)
- qFatal("Could not open egl display");
-
- EGLint major, minor;
- if (!eglInitialize(m_display, &major, &minor))
- qFatal("Could not initialize egl display");
-
- m_inputContext = QPlatformInputContextFactory::create();
-
- m_vtHandler.reset(new QFbVtHandler);
-}
-
-void QEGLPlatformIntegration::destroy()
-{
- foreach (QWindow *w, qGuiApp->topLevelWindows())
- w->destroy();
-
- if (m_display != EGL_NO_DISPLAY)
- eglTerminate(m_display);
-}
-
-QAbstractEventDispatcher *QEGLPlatformIntegration::createEventDispatcher() const
-{
- return createUnixEventDispatcher();
-}
-
-QPlatformServices *QEGLPlatformIntegration::services() const
-{
- return m_services.data();
-}
-
-QPlatformFontDatabase *QEGLPlatformIntegration::fontDatabase() const
-{
- return m_fontDb.data();
-}
-
-QPlatformBackingStore *QEGLPlatformIntegration::createPlatformBackingStore(QWindow *window) const
-{
- QOpenGLCompositorBackingStore *bs = new QOpenGLCompositorBackingStore(window);
- if (!window->handle())
- window->create();
- static_cast<QEGLPlatformWindow *>(window->handle())->setBackingStore(bs);
- return bs;
-}
-
-QPlatformWindow *QEGLPlatformIntegration::createPlatformWindow(QWindow *window) const
-{
- QWindowSystemInterface::flushWindowSystemEvents();
- QEGLPlatformWindow *w = createWindow(window);
- w->create();
- if (window->type() != Qt::ToolTip)
- w->requestActivateWindow();
- return w;
-}
-
-QPlatformOpenGLContext *QEGLPlatformIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
-{
- // If there is a "root" window into which raster and QOpenGLWidget content is
- // composited, all other contexts must share with its context.
- QOpenGLContext *compositingContext = QOpenGLCompositor::instance()->context();
- QPlatformOpenGLContext *share = compositingContext ? compositingContext->handle() : context->shareHandle();
- QVariant nativeHandle = context->nativeHandle();
- QPlatformOpenGLContext *platformContext = createContext(context->format(),
- share,
- display(),
- &nativeHandle);
- context->setNativeHandle(nativeHandle);
- return platformContext;
-}
-
-QPlatformOffscreenSurface *QEGLPlatformIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
-{
- QEGLPlatformScreen *screen = static_cast<QEGLPlatformScreen *>(surface->screen()->handle());
- return createOffscreenSurface(screen->display(), surface->requestedFormat(), surface);
-}
-
-bool QEGLPlatformIntegration::hasCapability(QPlatformIntegration::Capability cap) const
-{
- switch (cap) {
- case ThreadedPixmaps: return true;
- case OpenGL: return true;
- case ThreadedOpenGL: return true;
- case WindowManagement: return false;
- case RasterGLSurface: return true;
- default: return QPlatformIntegration::hasCapability(cap);
- }
-}
-
-QPlatformNativeInterface *QEGLPlatformIntegration::nativeInterface() const
-{
- return const_cast<QEGLPlatformIntegration *>(this);
-}
-
-enum ResourceType {
- EglDisplay,
- EglWindow,
- EglContext,
- EglConfig,
- NativeDisplay,
- XlibDisplay
-};
-
-static int resourceType(const QByteArray &key)
-{
- static const QByteArray names[] = { // match ResourceType
- QByteArrayLiteral("egldisplay"),
- QByteArrayLiteral("eglwindow"),
- QByteArrayLiteral("eglcontext"),
- QByteArrayLiteral("eglconfig"),
- QByteArrayLiteral("nativedisplay"),
- QByteArrayLiteral("display")
- };
- const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
- const QByteArray *result = std::find(names, end, key);
- if (result == end)
- result = std::find(names, end, key.toLower());
- return int(result - names);
-}
-
-void *QEGLPlatformIntegration::nativeResourceForIntegration(const QByteArray &resource)
-{
- void *result = 0;
-
- switch (resourceType(resource)) {
- case EglDisplay:
- result = display();
- break;
- case NativeDisplay:
- result = reinterpret_cast<void*>(nativeDisplay());
- break;
- default:
- break;
- }
-
- return result;
-}
-
-void *QEGLPlatformIntegration::nativeResourceForScreen(const QByteArray &resource, QScreen *)
-{
- void *result = 0;
-
- switch (resourceType(resource)) {
- case XlibDisplay:
- // Play nice when using the x11 hooks: Be compatible with xcb that allows querying
- // the X Display pointer, which is nothing but our native display.
- result = reinterpret_cast<void*>(nativeDisplay());
- break;
- default:
- break;
- }
-
- return result;
-}
-
-void *QEGLPlatformIntegration::nativeResourceForWindow(const QByteArray &resource, QWindow *window)
-{
- void *result = 0;
-
- switch (resourceType(resource)) {
- case EglDisplay:
- if (window && window->handle())
- result = static_cast<QEGLPlatformScreen *>(window->handle()->screen())->display();
- else
- result = display();
- break;
- case EglWindow:
- if (window && window->handle())
- result = reinterpret_cast<void*>(static_cast<QEGLPlatformWindow *>(window->handle())->eglWindow());
- break;
- default:
- break;
- }
-
- return result;
-}
-
-void *QEGLPlatformIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
-{
- void *result = 0;
-
- switch (resourceType(resource)) {
- case EglContext:
- if (context->handle())
- result = static_cast<QEGLPlatformContext *>(context->handle())->eglContext();
- break;
- case EglConfig:
- if (context->handle())
- result = static_cast<QEGLPlatformContext *>(context->handle())->eglConfig();
- break;
- case EglDisplay:
- if (context->handle())
- result = static_cast<QEGLPlatformContext *>(context->handle())->eglDisplay();
- break;
- default:
- break;
- }
-
- return result;
-}
-
-static void *eglContextForContext(QOpenGLContext *context)
-{
- Q_ASSERT(context);
-
- QEGLPlatformContext *handle = static_cast<QEGLPlatformContext *>(context->handle());
- if (!handle)
- return 0;
-
- return handle->eglContext();
-}
-
-QPlatformNativeInterface::NativeResourceForContextFunction QEGLPlatformIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
-{
- QByteArray lowerCaseResource = resource.toLower();
- if (lowerCaseResource == "get_egl_context")
- return NativeResourceForContextFunction(eglContextForContext);
-
- return 0;
-}
-
-QFunctionPointer QEGLPlatformIntegration::platformFunction(const QByteArray &function) const
-{
-#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
- if (function == QEglFSFunctions::loadKeymapTypeIdentifier())
- return QFunctionPointer(loadKeymapStatic);
-#else
- Q_UNUSED(function)
-#endif
-
- return 0;
-}
-
-void QEGLPlatformIntegration::loadKeymapStatic(const QString &filename)
-{
-#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
- QEGLPlatformIntegration *self = static_cast<QEGLPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration());
- if (self->m_kbdMgr)
- self->m_kbdMgr->loadKeymap(filename);
- else
- qWarning("QEGLPlatformIntegration: Cannot load keymap, no keyboard handler found");
-#else
- Q_UNUSED(filename);
-#endif
-}
-
-void QEGLPlatformIntegration::createInputHandlers()
-{
-#if !defined(QT_NO_EVDEV) && (!defined(Q_OS_ANDROID) || defined(Q_OS_ANDROID_NO_SDK))
- m_kbdMgr = new QEvdevKeyboardManager(QLatin1String("EvdevKeyboard"), QString() /* spec */, this);
- new QEvdevMouseManager(QLatin1String("EvdevMouse"), QString() /* spec */, this);
-#ifndef QT_NO_TSLIB
- const bool useTslib = qEnvironmentVariableIntValue("QT_QPA_EGLFS_TSLIB");
- if (useTslib)
- new QTsLibMouseHandler(QLatin1String("TsLib"), QString() /* spec */);
- else
-#endif // QT_NO_TSLIB
- new QEvdevTouchManager(QLatin1String("EvdevTouch"), QString() /* spec */, this);
-#endif
-}
-
-QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h b/src/platformsupport/eglconvenience/qeglplatformintegration_p.h
deleted file mode 100644
index 42fbf8c8a1..0000000000
--- a/src/platformsupport/eglconvenience/qeglplatformintegration_p.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEGLPLATFORMINTEGRATION_H
-#define QEGLPLATFORMINTEGRATION_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 <QtCore/QVariant>
-#include <qpa/qplatformintegration.h>
-#include <qpa/qplatformnativeinterface.h>
-#include <EGL/egl.h>
-
-QT_BEGIN_NAMESPACE
-
-class QEGLPlatformWindow;
-class QEGLPlatformContext;
-class QFbVtHandler;
-class QEvdevKeyboardManager;
-
-class QEGLPlatformIntegration : public QPlatformIntegration, public QPlatformNativeInterface
-{
-public:
- QEGLPlatformIntegration();
- ~QEGLPlatformIntegration();
-
- void initialize() Q_DECL_OVERRIDE;
- void destroy() Q_DECL_OVERRIDE;
-
- EGLDisplay display() const { return m_display; }
-
- QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
- QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
- QPlatformServices *services() const Q_DECL_OVERRIDE;
- QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; }
-
- QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
- QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
-
- bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
-
- QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
- // QPlatformNativeInterface
- void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
- void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) Q_DECL_OVERRIDE;
- void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
- void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE;
- NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
-
- QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE;
-
- QFbVtHandler *vtHandler() { return m_vtHandler.data(); }
-
-protected:
- virtual QEGLPlatformWindow *createWindow(QWindow *window) const = 0;
- virtual QEGLPlatformContext *createContext(const QSurfaceFormat &format,
- QPlatformOpenGLContext *shareContext,
- EGLDisplay display,
- QVariant *nativeHandle) const = 0;
- virtual QPlatformOffscreenSurface *createOffscreenSurface(EGLDisplay display,
- const QSurfaceFormat &format,
- QOffscreenSurface *surface) const = 0;
-
- virtual EGLNativeDisplayType nativeDisplay() const { return EGL_DEFAULT_DISPLAY; }
-
- void createInputHandlers();
-
-private:
- static void loadKeymapStatic(const QString &filename);
-
- EGLDisplay m_display;
- QPlatformInputContext *m_inputContext;
- QScopedPointer<QPlatformFontDatabase> m_fontDb;
- QScopedPointer<QPlatformServices> m_services;
- QScopedPointer<QFbVtHandler> m_vtHandler;
- QEvdevKeyboardManager *m_kbdMgr;
-};
-
-QT_END_NAMESPACE
-
-#endif // QEGLPLATFORMINTEGRATION_H
diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp b/src/platformsupport/eglconvenience/qeglplatformscreen.cpp
deleted file mode 100644
index 61f8cdd9b4..0000000000
--- a/src/platformsupport/eglconvenience/qeglplatformscreen.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeglplatformscreen_p.h"
-#include "qeglplatformwindow_p.h"
-#include <QtGui/qwindow.h>
-#include <qpa/qwindowsysteminterface.h>
-#include <QtPlatformSupport/private/qopenglcompositor_p.h>
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QEGLPlatformScreen
- \brief Base class for EGL-based platform screen implementations.
- \since 5.2
- \internal
- \ingroup qpa
- */
-
-QEGLPlatformScreen::QEGLPlatformScreen(EGLDisplay dpy)
- : m_dpy(dpy),
- m_pointerWindow(0)
-{
-}
-
-QEGLPlatformScreen::~QEGLPlatformScreen()
-{
- QOpenGLCompositor::destroy();
-}
-
-void QEGLPlatformScreen::handleCursorMove(const QPoint &pos)
-{
- const QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
- const QList<QOpenGLCompositorWindow *> windows = compositor->windows();
-
- // Generate enter and leave events like a real windowing system would do.
- if (windows.isEmpty())
- return;
-
- // First window is always fullscreen.
- if (windows.count() == 1) {
- QWindow *window = windows[0]->sourceWindow();
- if (m_pointerWindow != window) {
- m_pointerWindow = window;
- QWindowSystemInterface::handleEnterEvent(window, window->mapFromGlobal(pos), pos);
- }
- return;
- }
-
- QWindow *enter = 0, *leave = 0;
- for (int i = windows.count() - 1; i >= 0; --i) {
- QWindow *window = windows[i]->sourceWindow();
- const QRect geom = window->geometry();
- if (geom.contains(pos)) {
- if (m_pointerWindow != window) {
- leave = m_pointerWindow;
- m_pointerWindow = window;
- enter = window;
- }
- break;
- }
- }
-
- if (enter && leave)
- QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos);
-}
-
-QPixmap QEGLPlatformScreen::grabWindow(WId wid, int x, int y, int width, int height) const
-{
- QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
- const QList<QOpenGLCompositorWindow *> windows = compositor->windows();
- Q_ASSERT(!windows.isEmpty());
-
- QImage img;
-
- if (static_cast<QEGLPlatformWindow *>(windows.first()->sourceWindow()->handle())->isRaster()) {
- // Request the compositor to render everything into an FBO and read it back. This
- // is of course slow, but it's safe and reliable. It will not include the mouse
- // cursor, which is a plus.
- img = compositor->grab();
- } else {
- // Just a single OpenGL window without compositing. Do not support this case for now. Doing
- // glReadPixels is not an option since it would read from the back buffer which may have
- // undefined content when calling right after a swapBuffers (unless preserved swap is
- // available and enabled, but we have no support for that).
- qWarning("grabWindow: Not supported for non-composited OpenGL content. Use QQuickWindow::grabWindow() instead.");
- return QPixmap();
- }
-
- if (!wid) {
- const QSize screenSize = geometry().size();
- if (width < 0)
- width = screenSize.width() - x;
- if (height < 0)
- height = screenSize.height() - y;
- return QPixmap::fromImage(img).copy(x, y, width, height);
- }
-
- foreach (QOpenGLCompositorWindow *w, windows) {
- const QWindow *window = w->sourceWindow();
- if (window->winId() == wid) {
- const QRect geom = window->geometry();
- if (width < 0)
- width = geom.width() - x;
- if (height < 0)
- height = geom.height() - y;
- QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height));
- rect &= window->geometry();
- return QPixmap::fromImage(img).copy(rect);
- }
- }
-
- return QPixmap();
-}
-
-QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp b/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
deleted file mode 100644
index 35f38ac29a..0000000000
--- a/src/platformsupport/eglconvenience/qeglplatformwindow.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <qpa/qwindowsysteminterface.h>
-#include <QtPlatformSupport/private/qopenglcompositor_p.h>
-#include <QtPlatformSupport/private/qopenglcompositorbackingstore_p.h>
-
-#include "qeglplatformwindow_p.h"
-#include "qeglplatformscreen_p.h"
-
-QT_BEGIN_NAMESPACE
-
-/*!
- \class QEGLPlatformWindow
- \brief Base class for EGL-based platform window implementations.
- \since 5.2
- \internal
- \ingroup qpa
-
- Lightweight class providing some basic platform window operations
- and interfacing with QOpenGLCompositorBackingStore.
-
- Almost no QPlatformWindow functions are implemented here. This is
- intentional because different platform plugins may use different
- strategies for their window management (some may force fullscreen
- windows, some may not, some may share the underlying native
- surface, some may not, etc.) and therefore it is not sensible to
- enforce anything for these functions.
-
- \note Subclasses are responsible for invoking this class'
- implementation of create() and are expected to utilize the window
- stack management functions (addWindow() etc.) in
- QOpenGLCompositor.
- */
-
-QEGLPlatformWindow::QEGLPlatformWindow(QWindow *w)
- : QPlatformWindow(w),
- m_backingStore(0),
- m_raster(false),
- m_winId(0)
-{
-}
-
-static WId newWId()
-{
- static WId id = 0;
-
- if (id == std::numeric_limits<WId>::max())
- qWarning("QEGLPlatformWindow: Out of window IDs");
-
- return ++id;
-}
-
-void QEGLPlatformWindow::create()
-{
- m_winId = newWId();
-
- // Save the original surface type before changing to OpenGLSurface.
- m_raster = (window()->surfaceType() == QSurface::RasterSurface);
- if (m_raster) // change to OpenGL, but not for RasterGLSurface
- window()->setSurfaceType(QSurface::OpenGLSurface);
-
- if (window()->type() == Qt::Desktop) {
- QRect fullscreenRect(QPoint(), screen()->availableGeometry().size());
- QPlatformWindow::setGeometry(fullscreenRect);
- QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect);
- return;
- }
-}
-
-bool QEGLPlatformWindow::isRaster() const
-{
- return m_raster || window()->surfaceType() == QSurface::RasterGLSurface;
-}
-
-QWindow *QEGLPlatformWindow::sourceWindow() const
-{
- return window();
-}
-
-const QPlatformTextureList *QEGLPlatformWindow::textures() const
-{
- if (m_backingStore)
- return m_backingStore->textures();
-
- return 0;
-}
-
-void QEGLPlatformWindow::endCompositing()
-{
- if (m_backingStore)
- m_backingStore->notifyComposited();
-}
-
-WId QEGLPlatformWindow::winId() const
-{
- return m_winId;
-}
-
-void QEGLPlatformWindow::setOpacity(qreal)
-{
- if (!isRaster())
- qWarning("QEGLPlatformWindow: Cannot set opacity for non-raster windows");
-
- // Nothing to do here. The opacity is stored in the QWindow.
-}
-
-QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h b/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
deleted file mode 100644
index 852d690c92..0000000000
--- a/src/platformsupport/eglconvenience/qeglplatformwindow_p.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QEGLPLATFORMWINDOW_H
-#define QEGLPLATFORMWINDOW_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/qplatformwindow.h>
-#include <QtPlatformSupport/private/qopenglcompositor_p.h>
-#include <EGL/egl.h>
-
-QT_BEGIN_NAMESPACE
-
-class QOpenGLCompositorBackingStore;
-class QPlatformTextureList;
-
-class QEGLPlatformWindow : public QPlatformWindow, public QOpenGLCompositorWindow
-{
-public:
- QEGLPlatformWindow(QWindow *w);
-
- virtual void create();
-
- QOpenGLCompositorBackingStore *backingStore() { return m_backingStore; }
- void setBackingStore(QOpenGLCompositorBackingStore *backingStore) { m_backingStore = backingStore; }
- bool isRaster() const;
-
- QWindow *sourceWindow() const Q_DECL_OVERRIDE;
- const QPlatformTextureList *textures() const Q_DECL_OVERRIDE;
- void endCompositing() Q_DECL_OVERRIDE;
-
- WId winId() const Q_DECL_OVERRIDE;
- void setOpacity(qreal opacity) Q_DECL_OVERRIDE;
-
- virtual EGLNativeWindowType eglWindow() const = 0;
-
-private:
- QOpenGLCompositorBackingStore *m_backingStore;
- bool m_raster;
- WId m_winId;
-};
-
-QT_END_NAMESPACE
-
-#endif // QEGLPLATFORMWINDOW_H
diff --git a/src/platformsupport/eglconvenience/qeglstreamconvenience.cpp b/src/platformsupport/eglconvenience/qeglstreamconvenience.cpp
new file mode 100644
index 0000000000..2ace144811
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglstreamconvenience.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeglstreamconvenience_p.h"
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+QEGLStreamConvenience::QEGLStreamConvenience()
+ : initialized(false),
+ has_egl_platform_device(false),
+ has_egl_device_base(false),
+ has_egl_stream(false),
+ has_egl_stream_producer_eglsurface(false),
+ has_egl_stream_consumer_egloutput(false),
+ has_egl_output_drm(false),
+ has_egl_output_base(false),
+ has_egl_stream_cross_process_fd(false),
+ has_egl_stream_consumer_gltexture(false)
+{
+ const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
+ if (!extensions) {
+ qWarning("Failed to query EGL extensions");
+ return;
+ }
+
+ query_devices = reinterpret_cast<PFNEGLQUERYDEVICESEXTPROC>(eglGetProcAddress("eglQueryDevicesEXT"));
+ query_device_string = reinterpret_cast<PFNEGLQUERYDEVICESTRINGEXTPROC>(eglGetProcAddress("eglQueryDeviceStringEXT"));
+ get_platform_display = reinterpret_cast<PFNEGLGETPLATFORMDISPLAYEXTPROC>(eglGetProcAddress("eglGetPlatformDisplayEXT"));
+
+ has_egl_device_base = strstr(extensions, "EGL_EXT_device_base");
+ has_egl_platform_device = strstr(extensions, "EGL_EXT_platform_device");
+}
+
+void QEGLStreamConvenience::initialize(EGLDisplay dpy)
+{
+ if (initialized)
+ return;
+
+ if (!eglBindAPI(EGL_OPENGL_ES_API)) {
+ qWarning("Failed to bind OpenGL ES API");
+ return;
+ }
+
+ const char *extensions = eglQueryString(dpy, EGL_EXTENSIONS);
+ if (!extensions) {
+ qWarning("Failed to query EGL extensions");
+ return;
+ }
+
+ create_stream = reinterpret_cast<PFNEGLCREATESTREAMKHRPROC>(eglGetProcAddress("eglCreateStreamKHR"));
+ destroy_stream = reinterpret_cast<PFNEGLDESTROYSTREAMKHRPROC>(eglGetProcAddress("eglDestroyStreamKHR"));
+ stream_attrib = reinterpret_cast<PFNEGLSTREAMATTRIBKHRPROC>(eglGetProcAddress("eglStreamAttribKHR"));
+ query_stream = reinterpret_cast<PFNEGLQUERYSTREAMKHRPROC>(eglGetProcAddress("eglQueryStreamKHR"));
+ query_stream_u64 = reinterpret_cast<PFNEGLQUERYSTREAMU64KHRPROC>(eglGetProcAddress("eglQueryStreamu64KHR"));
+ create_stream_producer_surface = reinterpret_cast<PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC>(eglGetProcAddress("eglCreateStreamProducerSurfaceKHR"));
+ stream_consumer_output = reinterpret_cast<PFNEGLSTREAMCONSUMEROUTPUTEXTPROC>(eglGetProcAddress("eglStreamConsumerOutputEXT"));
+ get_output_layers = reinterpret_cast<PFNEGLGETOUTPUTLAYERSEXTPROC>(eglGetProcAddress("eglGetOutputLayersEXT"));
+ get_output_ports = reinterpret_cast<PFNEGLGETOUTPUTPORTSEXTPROC>(eglGetProcAddress("eglGetOutputPortsEXT"));
+ output_layer_attrib = reinterpret_cast<PFNEGLOUTPUTLAYERATTRIBEXTPROC>(eglGetProcAddress("eglOutputLayerAttribEXT"));
+ query_output_layer_attrib = reinterpret_cast<PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC>(eglGetProcAddress("eglQueryOutputLayerAttribEXT"));
+ query_output_layer_string = reinterpret_cast<PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC>(eglGetProcAddress("eglQueryOutputLayerStringEXT"));
+ query_output_port_attrib = reinterpret_cast<PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC>(eglGetProcAddress("eglQueryOutputPortAttribEXT"));
+ query_output_port_string = reinterpret_cast<PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC>(eglGetProcAddress("eglQueryOutputPortStringEXT"));
+ get_stream_file_descriptor = reinterpret_cast<PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC>(eglGetProcAddress("eglGetStreamFileDescriptorKHR"));
+ create_stream_from_file_descriptor = reinterpret_cast<PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC>(eglGetProcAddress("eglCreateStreamFromFileDescriptorKHR"));
+ stream_consumer_gltexture = reinterpret_cast<PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC>(eglGetProcAddress("eglStreamConsumerGLTextureExternalKHR"));
+ stream_consumer_acquire = reinterpret_cast<PFNEGLSTREAMCONSUMERACQUIREKHRPROC>(eglGetProcAddress("eglStreamConsumerAcquireKHR"));
+ stream_consumer_release = reinterpret_cast<PFNEGLSTREAMCONSUMERRELEASEKHRPROC>(eglGetProcAddress("eglStreamConsumerReleaseKHR"));
+
+ has_egl_stream = strstr(extensions, "EGL_KHR_stream");
+ has_egl_stream_producer_eglsurface = strstr(extensions, "EGL_KHR_stream_producer_eglsurface");
+ has_egl_stream_consumer_egloutput = strstr(extensions, "EGL_EXT_stream_consumer_egloutput");
+ has_egl_output_drm = strstr(extensions, "EGL_EXT_output_drm");
+ has_egl_output_base = strstr(extensions, "EGL_EXT_output_base");
+ has_egl_stream_cross_process_fd = strstr(extensions, "EGL_KHR_stream_cross_process_fd");
+ has_egl_stream_consumer_gltexture = strstr(extensions, "EGL_KHR_stream_consumer_gltexture");
+
+ initialized = true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h
new file mode 100644
index 0000000000..648b129579
--- /dev/null
+++ b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLSTREAMCONVENIENCE_H
+#define QEGLSTREAMCONVENIENCE_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 <qglobal.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+// This provides runtime EGLDevice/Output/Stream support even when eglext.h in
+// the sysroot is not up-to-date.
+
+#ifndef EGL_VERSION_1_5
+typedef intptr_t EGLAttrib;
+#endif
+
+#ifndef EGL_EXT_platform_base
+typedef EGLDisplay (EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC) (EGLenum platform, void *native_display, const EGLint *attrib_list);
+#endif
+
+#ifndef EGL_EXT_device_base
+typedef void *EGLDeviceEXT;
+#define EGL_NO_DEVICE_EXT ((EGLDeviceEXT)(0))
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYDEVICESEXTPROC) (EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYDEVICESTRINGEXTPROC) (EGLDeviceEXT device, EGLint name);
+#endif
+
+#ifndef EGL_EXT_output_base
+typedef void *EGLOutputLayerEXT;
+typedef void *EGLOutputPortEXT;
+#define EGL_NO_OUTPUT_LAYER_EXT ((EGLOutputLayerEXT)0)
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTLAYERSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputLayerEXT *layers, EGLint max_layers, EGLint *num_layers);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETOUTPUTPORTSEXTPROC) (EGLDisplay dpy, const EGLAttrib *attrib_list, EGLOutputPortEXT *ports, EGLint max_ports, EGLint *num_ports);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputLayerEXT layer, EGLint name);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint attribute, EGLAttrib *value);
+typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDisplay dpy, EGLOutputPortEXT port, EGLint name);
+#endif
+
+#ifndef EGL_KHR_stream
+typedef void *EGLStreamKHR;
+typedef quint64 EGLuint64KHR;
+#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0)
+#define EGL_STREAM_STATE_KHR 0x3214
+#define EGL_STREAM_STATE_CREATED_KHR 0x3215
+#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216
+#define EGL_STREAM_STATE_EMPTY_KHR 0x3217
+#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
+#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
+#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
+#define EGL_BAD_STREAM_KHR 0x321B
+#define EGL_BAD_STATE_KHR 0x321C
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint *value);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSTREAMU64KHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLuint64KHR *value);
+#endif
+
+#ifndef EGL_KHR_stream_producer_eglsurface
+#define EGL_STREAM_BIT_KHR 0x0800
+typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC) (EGLDisplay dpy, EGLConfig config, EGLStreamKHR stream, const EGLint *attrib_list);
+#endif
+
+#ifndef EGL_KHR_stream_cross_process_fd
+typedef int EGLNativeFileDescriptorKHR;
+#define EGL_NO_FILE_DESCRIPTOR_KHR ((EGLNativeFileDescriptorKHR)(-1))
+typedef EGLNativeFileDescriptorKHR (EGLAPIENTRYP PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC) (EGLDisplay dpy, EGLNativeFileDescriptorKHR file_descriptor);
+#endif
+
+#ifndef EGL_KHR_stream_consumer_gltexture
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERACQUIREKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMERRELEASEKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
+#endif
+
+#ifndef EGL_EXT_stream_consumer_egloutput
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMCONSUMEROUTPUTEXTPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLOutputLayerEXT layer);
+#endif
+
+#ifndef EGL_EXT_platform_device
+#define EGL_PLATFORM_DEVICE_EXT 0x313F
+#endif
+
+#ifndef EGL_EXT_device_drm
+#define EGL_DRM_DEVICE_FILE_EXT 0x3233
+#endif
+
+#ifndef EGL_EXT_output_drm
+#define EGL_DRM_CRTC_EXT 0x3234
+#define EGL_DRM_PLANE_EXT 0x3235
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QEGLStreamConvenience
+{
+public:
+ QEGLStreamConvenience();
+ void initialize(EGLDisplay dpy);
+
+ PFNEGLGETPLATFORMDISPLAYEXTPROC get_platform_display;
+ PFNEGLQUERYDEVICESEXTPROC query_devices;
+ PFNEGLQUERYDEVICESTRINGEXTPROC query_device_string;
+ PFNEGLCREATESTREAMKHRPROC create_stream;
+ PFNEGLDESTROYSTREAMKHRPROC destroy_stream;
+ PFNEGLSTREAMATTRIBKHRPROC stream_attrib;
+ PFNEGLQUERYSTREAMKHRPROC query_stream;
+ PFNEGLQUERYSTREAMU64KHRPROC query_stream_u64;
+ PFNEGLCREATESTREAMPRODUCERSURFACEKHRPROC create_stream_producer_surface;
+ PFNEGLSTREAMCONSUMEROUTPUTEXTPROC stream_consumer_output;
+ PFNEGLGETOUTPUTLAYERSEXTPROC get_output_layers;
+ PFNEGLGETOUTPUTPORTSEXTPROC get_output_ports;
+ PFNEGLOUTPUTLAYERATTRIBEXTPROC output_layer_attrib;
+ PFNEGLQUERYOUTPUTLAYERATTRIBEXTPROC query_output_layer_attrib;
+ PFNEGLQUERYOUTPUTLAYERSTRINGEXTPROC query_output_layer_string;
+ PFNEGLQUERYOUTPUTPORTATTRIBEXTPROC query_output_port_attrib;
+ PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC query_output_port_string;
+ PFNEGLGETSTREAMFILEDESCRIPTORKHRPROC get_stream_file_descriptor;
+ PFNEGLCREATESTREAMFROMFILEDESCRIPTORKHRPROC create_stream_from_file_descriptor;
+ PFNEGLSTREAMCONSUMERGLTEXTUREEXTERNALKHRPROC stream_consumer_gltexture;
+ PFNEGLSTREAMCONSUMERACQUIREKHRPROC stream_consumer_acquire;
+ PFNEGLSTREAMCONSUMERRELEASEKHRPROC stream_consumer_release;
+
+ bool initialized;
+
+ bool has_egl_platform_device;
+ bool has_egl_device_base;
+ bool has_egl_stream;
+ bool has_egl_stream_producer_eglsurface;
+ bool has_egl_stream_consumer_egloutput;
+ bool has_egl_output_drm;
+ bool has_egl_output_base;
+ bool has_egl_stream_cross_process_fd;
+ bool has_egl_stream_consumer_gltexture;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/platformsupport/eventdispatchers/eventdispatchers.pri b/src/platformsupport/eventdispatchers/eventdispatchers.pri
index c9bbe1f5b7..a0b37cae1a 100644
--- a/src/platformsupport/eventdispatchers/eventdispatchers.pri
+++ b/src/platformsupport/eventdispatchers/eventdispatchers.pri
@@ -6,14 +6,12 @@ SOURCES +=\
HEADERS +=\
$$PWD/qunixeventdispatcher_qpa_p.h\
$$PWD/qgenericunixeventdispatcher_p.h\
-}
-
-ios {
-OBJECTIVE_SOURCES +=\
- $$PWD/qeventdispatcher_cf.mm
+} else: win32 {
+SOURCES +=\
+ $$PWD/qwindowsguieventdispatcher.cpp
HEADERS +=\
- $$PWD/qeventdispatcher_cf_p.h
+ $$PWD/qwindowsguieventdispatcher_p.h
}
contains(QT_CONFIG, glib) {
diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm b/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm
deleted file mode 100644
index 13b7dc4358..0000000000
--- a/src/platformsupport/eventdispatchers/qeventdispatcher_cf.mm
+++ /dev/null
@@ -1,628 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qeventdispatcher_cf_p.h"
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qmetaobject.h>
-#include <QtCore/qthread.h>
-#include <QtCore/private/qcoreapplication_p.h>
-#include <QtCore/private/qcore_unix_p.h>
-#include <QtCore/private/qcore_mac_p.h>
-#include <QtCore/private/qthread_p.h>
-
-#include <qpa/qwindowsysteminterface.h>
-
-#include <limits>
-
-#include <UIKit/UIApplication.h>
-
-@interface RunLoopModeTracker : NSObject {
- QStack<CFStringRef> m_runLoopModes;
-}
-@end
-
-@implementation RunLoopModeTracker
-
-- (id) init
-{
- if (self = [super init]) {
- m_runLoopModes.push(kCFRunLoopDefaultMode);
-
- [[NSNotificationCenter defaultCenter]
- addObserver:self
- selector:@selector(receivedNotification:)
- name:nil
- object:[UIApplication sharedApplication]];
- }
-
- return self;
-}
-
-- (void) dealloc
-{
- [[NSNotificationCenter defaultCenter] removeObserver:self];
-
- [super dealloc];
-}
-
-static CFStringRef runLoopMode(NSDictionary *dictionary)
-{
- for (NSString *key in dictionary) {
- if (CFStringHasSuffix((CFStringRef)key, CFSTR("RunLoopMode")))
- return (CFStringRef)[dictionary objectForKey: key];
- }
-
- return nil;
-}
-
-- (void) receivedNotification:(NSNotification *) notification
-{
- if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePushNotification"))) {
- if (CFStringRef mode = runLoopMode(notification.userInfo))
- m_runLoopModes.push(mode);
- else
- qWarning("Encountered run loop push notification without run loop mode!");
-
- } else if (CFStringHasSuffix((CFStringRef)notification.name, CFSTR("RunLoopModePopNotification"))) {
- CFStringRef mode = runLoopMode(notification.userInfo);
- if (CFStringCompare(mode, [self currentMode], 0) == kCFCompareEqualTo)
- m_runLoopModes.pop();
- else
- qWarning("Tried to pop run loop mode '%s' that was never pushed!", qPrintable(QCFString::toQString(mode)));
-
- Q_ASSERT(m_runLoopModes.size() >= 1);
- }
-}
-
-- (CFStringRef) currentMode
-{
- return m_runLoopModes.top();
-}
-
-@end
-
-QT_BEGIN_NAMESPACE
-QT_USE_NAMESPACE
-
-class RunLoopDebugger : public QObject
-{
- Q_OBJECT
-
- Q_ENUMS(Activity)
- Q_ENUMS(Result)
-
-public:
-
- #define Q_MIRROR_ENUM(name) name = name
-
- enum Activity {
- Q_MIRROR_ENUM(kCFRunLoopEntry),
- Q_MIRROR_ENUM(kCFRunLoopBeforeTimers),
- Q_MIRROR_ENUM(kCFRunLoopBeforeSources),
- Q_MIRROR_ENUM(kCFRunLoopBeforeWaiting),
- Q_MIRROR_ENUM(kCFRunLoopAfterWaiting),
- Q_MIRROR_ENUM(kCFRunLoopExit)
- };
-
- enum Result {
- Q_MIRROR_ENUM(kCFRunLoopRunFinished),
- Q_MIRROR_ENUM(kCFRunLoopRunStopped),
- Q_MIRROR_ENUM(kCFRunLoopRunTimedOut),
- Q_MIRROR_ENUM(kCFRunLoopRunHandledSource)
- };
-};
-
-#define Q_ENUM_PRINTER(enumName) \
- static const char* qPrintable##enumName(int value) \
- { \
- return RunLoopDebugger::staticMetaObject.enumerator(RunLoopDebugger::staticMetaObject.indexOfEnumerator(#enumName)).valueToKey(value); \
- }
-
-Q_ENUM_PRINTER(Activity);
-Q_ENUM_PRINTER(Result);
-
-QDebug operator<<(QDebug s, timespec tv)
-{
- s << tv.tv_sec << "." << qSetFieldWidth(9) << qSetPadChar(QChar(48)) << tv.tv_nsec << reset;
- return s;
-}
-
-#if DEBUG_EVENT_DISPATCHER
-uint g_eventDispatcherIndentationLevel = 0;
-#endif
-
-static const CFTimeInterval kCFTimeIntervalMinimum = 0;
-static const CFTimeInterval kCFTimeIntervalDistantFuture = std::numeric_limits<CFTimeInterval>::max();
-
-#pragma mark - Class definition
-
-QEventDispatcherCoreFoundation::QEventDispatcherCoreFoundation(QObject *parent)
- : QAbstractEventDispatcher(parent)
- , m_postedEventsRunLoopSource(this, &QEventDispatcherCoreFoundation::processPostedEvents)
- , m_runLoopActivityObserver(this, &QEventDispatcherCoreFoundation::handleRunLoopActivity,
-#if DEBUG_EVENT_DISPATCHER
- kCFRunLoopAllActivities
-#else
- kCFRunLoopBeforeWaiting | kCFRunLoopAfterWaiting
-#endif
- )
- , m_runLoopModeTracker([[RunLoopModeTracker alloc] init])
- , m_runLoopTimer(0)
- , m_blockedRunLoopTimer(0)
- , m_overdueTimerScheduled(false)
- , m_processEvents(QEventLoop::EventLoopExec)
-{
- m_cfSocketNotifier.setHostEventDispatcher(this);
-
- m_postedEventsRunLoopSource.addToMode(kCFRunLoopCommonModes);
- m_runLoopActivityObserver.addToMode(kCFRunLoopCommonModes);
-}
-
-QEventDispatcherCoreFoundation::~QEventDispatcherCoreFoundation()
-{
- invalidateTimer();
- qDeleteAll(m_timerInfoList);
-
- m_cfSocketNotifier.removeSocketNotifiers();
-}
-
-/*!
- Processes all pending events that match \a flags until there are no
- more events to process. Returns \c true if pending events were handled;
- otherwise returns \c false.
-
- Note:
-
- - All events are considered equal. This function should process
- both system/native events (that we may or may not care about),
- as well as Qt-events (posted events and timers).
-
- - The function should not return until all queued/available events
- have been processed. If the WaitForMoreEvents is set, the
- function should wait only if there were no events ready,
- and _then_ process all newly queued/available events.
-
- These notes apply to other function in this class as well, such as
- hasPendingEvents().
-*/
-bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlags flags)
-{
- bool eventsProcessed = false;
-
- if (flags & (QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers))
- qWarning() << "processEvents() flags" << flags << "not supported on iOS";
-
- qEventDispatcherDebug() << "Entering with " << flags; qIndent();
-
- if (m_blockedRunLoopTimer) {
- Q_ASSERT(m_blockedRunLoopTimer == m_runLoopTimer);
-
- qEventDispatcherDebug() << "Recursing from blocked timer " << m_blockedRunLoopTimer;
- m_runLoopTimer = 0; // Unset current timer to force creation of new timer
- updateTimers();
- }
-
- if (m_processEvents.deferredWakeUp) {
- // We may be processing events recursivly as a result of processing a posted event,
- // in which case we need to signal the run-loop source so that this iteration of
- // processEvents will take care of the newly posted events.
- m_postedEventsRunLoopSource.signal();
- m_processEvents.deferredWakeUp = false;
-
- qEventDispatcherDebug() << "Processed deferred wake-up";
- }
-
- // The documentation states that this signal is emitted after the event
- // loop returns from a function that could block, which is not the case
- // here, but all the other event dispatchers emit awake at the start of
- // processEvents, and the QEventLoop auto-test has an explicit check for
- // this behavior, so we assume it's for a good reason and do it as well.
- emit awake();
-
- ProcessEventsState previousState = m_processEvents;
- m_processEvents = ProcessEventsState(flags);
-
- bool returnAfterSingleSourceHandled = !(m_processEvents.flags & QEventLoop::EventLoopExec);
-
- Q_FOREVER {
- CFStringRef mode = [m_runLoopModeTracker currentMode];
-
- CFTimeInterval duration = (m_processEvents.flags & QEventLoop::WaitForMoreEvents) ?
- kCFTimeIntervalDistantFuture : kCFTimeIntervalMinimum;
-
- qEventDispatcherDebug() << "Calling CFRunLoopRunInMode = " << qPrintable(QCFString::toQString(mode))
- << " for " << duration << " ms, processing single source = " << returnAfterSingleSourceHandled; qIndent();
-
- SInt32 result = CFRunLoopRunInMode(mode, duration, returnAfterSingleSourceHandled);
-
- qUnIndent(); qEventDispatcherDebug() << "result = " << qPrintableResult(result);
-
- eventsProcessed |= (result == kCFRunLoopRunHandledSource
- || m_processEvents.processedPostedEvents
- || m_processEvents.processedTimers);
-
- if (result == kCFRunLoopRunFinished) {
- // This should only happen at application shutdown, as the main runloop
- // will presumably always have sources registered.
- break;
- } else if (m_processEvents.wasInterrupted) {
-
- if (m_processEvents.flags & QEventLoop::EventLoopExec) {
- Q_ASSERT(result == kCFRunLoopRunStopped);
-
- // The runloop was potentially stopped (interrupted) by us, as a response to
- // a Qt event loop being asked to exit. We check that the topmost eventloop
- // is still supposed to keep going and return if not. Note that the runloop
- // might get stopped as a result of a non-top eventloop being asked to exit,
- // in which case we continue running the top event loop until that is asked
- // to exit, and then unwind back to the previous event loop which will break
- // immediately, since it has already been exited.
-
- QEventLoop *currentEventLoop = QThreadData::current()->eventLoops.top();
- Q_ASSERT(currentEventLoop);
-
- if (!currentEventLoop->isRunning()) {
- qEventDispatcherDebug() << "Top level event loop was exited";
- break;
- } else {
- qEventDispatcherDebug() << "Top level event loop still running, making another pass";
- }
- } else {
- // We were called manually, through processEvents(), and should stop processing
- // events, even if we didn't finish processing all the queued events.
- qEventDispatcherDebug() << "Top level processEvents was interrupted";
- break;
- }
- }
-
- if (m_processEvents.flags & QEventLoop::EventLoopExec) {
- // We were called from QEventLoop's exec(), which blocks until the event
- // loop is asked to exit by calling processEvents repeatedly. Instead of
- // re-entering this method again and again from QEventLoop, we can block
- // here, one lever closer to CFRunLoopRunInMode, by running the native
- // event loop again and again until we're interrupted by QEventLoop.
- continue;
- } else {
- // We were called 'manually', through processEvents()
-
- if (result == kCFRunLoopRunHandledSource) {
- // We processed one or more sources, but there might still be other
- // sources that did not get a chance to process events, so we need
- // to do another pass.
-
- // But we should only wait for more events the first time
- m_processEvents.flags &= ~QEventLoop::WaitForMoreEvents;
- continue;
-
- } else if (m_overdueTimerScheduled && !m_processEvents.processedTimers) {
- // CFRunLoopRunInMode does not guarantee that a scheduled timer with a fire
- // date in the past (overdue) will fire on the next run loop pass. The Qt
- // APIs on the other hand document eg. zero-interval timers to always be
- // handled after processing all available window-system events.
- qEventDispatcherDebug() << "Manually processing timers due to overdue timer";
- processTimers(0);
- eventsProcessed = true;
- }
- }
-
- break;
- }
-
- if (m_blockedRunLoopTimer) {
- invalidateTimer();
- m_runLoopTimer = m_blockedRunLoopTimer;
- }
-
- if (m_processEvents.deferredUpdateTimers)
- updateTimers();
-
- if (m_processEvents.deferredWakeUp) {
- m_postedEventsRunLoopSource.signal();
- qEventDispatcherDebug() << "Processed deferred wake-up";
- }
-
- bool wasInterrupted = m_processEvents.wasInterrupted;
-
- // Restore state of previous processEvents() call
- m_processEvents = previousState;
-
- if (wasInterrupted) {
- // The current processEvents run has been interrupted, but there may still be
- // others below it (eg, in the case of nested event loops). We need to trigger
- // another interrupt so that the parent processEvents call has a chance to check
- // if it should continue.
- qEventDispatcherDebug() << "Forwarding interrupt in case of nested processEvents";
- interrupt();
- }
-
- qEventDispatcherDebug() << "Returning with eventsProcessed = " << eventsProcessed; qUnIndent();
-
- return eventsProcessed;
-}
-
-void QEventDispatcherCoreFoundation::processPostedEvents()
-{
- if (m_processEvents.processedPostedEvents && !(m_processEvents.flags & QEventLoop::EventLoopExec)) {
- qEventDispatcherDebug() << "Already processed events this pass";
- return;
- }
-
- m_processEvents.processedPostedEvents = true;
-
- qEventDispatcherDebug() << "Sending posted events for " << m_processEvents.flags; qIndent();
- QCoreApplication::sendPostedEvents();
- qUnIndent();
-
- qEventDispatcherDebug() << "Sending window system events for " << m_processEvents.flags; qIndent();
- QWindowSystemInterface::sendWindowSystemEvents(m_processEvents.flags);
- qUnIndent();
-}
-
-void QEventDispatcherCoreFoundation::processTimers(CFRunLoopTimerRef timer)
-{
- if (m_processEvents.processedTimers && !(m_processEvents.flags & QEventLoop::EventLoopExec)) {
- qEventDispatcherDebug() << "Already processed timers this pass";
- m_processEvents.deferredUpdateTimers = true;
- return;
- }
-
- qEventDispatcherDebug() << "CFRunLoopTimer " << timer << " fired, activating Qt timers"; qIndent();
-
- // Activating Qt timers might recurse into processEvents() if a timer-callback
- // brings up a new event-loop or tries to processes events manually. Although
- // a CFRunLoop can recurse inside its callbacks, a single CFRunLoopTimer can
- // not. So, for each recursion into processEvents() from a timer-callback we
- // need to set up a new timer-source. Instead of doing it preemtivly each
- // time we activate Qt timers, we set a flag here, and let processEvents()
- // decide whether or not it needs to bring up a new timer source.
-
- // We may have multiple recused timers, so keep track of the previous blocked timer
- CFRunLoopTimerRef previouslyBlockedRunLoopTimer = m_blockedRunLoopTimer;
-
- m_blockedRunLoopTimer = timer;
- m_timerInfoList.activateTimers();
- m_blockedRunLoopTimer = previouslyBlockedRunLoopTimer;
- m_processEvents.processedTimers = true;
-
- qUnIndent();
-
- // Now that the timer source is unblocked we may need to schedule it again
- updateTimers();
-}
-
-void QEventDispatcherCoreFoundation::handleRunLoopActivity(CFRunLoopActivity activity)
-{
- qEventDispatcherDebug() << qPrintableActivity(activity);
-
- switch (activity) {
- case kCFRunLoopBeforeWaiting:
- if (m_processEvents.processedTimers
- && !(m_processEvents.flags & QEventLoop::EventLoopExec)
- && m_processEvents.flags & QEventLoop::WaitForMoreEvents) {
- // CoreFoundation does not treat a timer as a reason to exit CFRunLoopRunInMode
- // when asked to only process a single source, so we risk waiting a long time for
- // a 'proper' source to fire (typically a system source that we don't control).
- // To fix this we do an explicit interrupt after processing our timer, so that
- // processEvents() gets a chance to re-evaluate the state of things.
- interrupt();
- }
- emit aboutToBlock();
- break;
- case kCFRunLoopAfterWaiting:
- emit awake();
- break;
-#if DEBUG_EVENT_DISPATCHER
- case kCFRunLoopEntry:
- case kCFRunLoopBeforeTimers:
- case kCFRunLoopBeforeSources:
- case kCFRunLoopExit:
- break;
-#endif
- default:
- Q_UNREACHABLE();
- }
-}
-
-bool QEventDispatcherCoreFoundation::hasPendingEvents()
-{
- // There doesn't seem to be any API on iOS to peek into the other sources
- // to figure out if there are pending non-Qt events. As a workaround, we
- // assume that if the run-loop is currently blocking and waiting for a
- // source to signal then there are no system-events pending. If this
- // function is called from the main thread then the second clause
- // of the condition will always be true, as the run loop is
- // never waiting in that case. The function would be more aptly named
- // 'maybeHasPendingEvents' in our case.
-
- extern uint qGlobalPostedEventsCount();
- return qGlobalPostedEventsCount() || !CFRunLoopIsWaiting(CFRunLoopGetMain());
-}
-
-void QEventDispatcherCoreFoundation::wakeUp()
-{
- if (m_processEvents.processedPostedEvents && !(m_processEvents.flags & QEventLoop::EventLoopExec)) {
- // A manual processEvents call should only result in processing the events posted
- // up until then. Any newly posted events as result of processing existing posted
- // events should be handled in the next call to processEvents(). Since we're using
- // a run-loop source to process our posted events we need to prevent it from being
- // signaled as a result of posting new events, otherwise we end up in an infinite
- // loop. We do however need to signal the source at some point, so that the newly
- // posted event gets processed on the next processEvents() call, so we flag the
- // need to do a deferred wake-up.
- m_processEvents.deferredWakeUp = true;
- qEventDispatcherDebug() << "Already processed posted events, deferring wakeUp";
- return;
- }
-
- m_postedEventsRunLoopSource.signal();
- CFRunLoopWakeUp(CFRunLoopGetMain());
-
- qEventDispatcherDebug() << "Signaled posted event run-loop source";
-}
-
-void QEventDispatcherCoreFoundation::interrupt()
-{
- qEventDispatcherDebug() << "Marking current processEvent as interrupted";
- m_processEvents.wasInterrupted = true;
- CFRunLoopStop(CFRunLoopGetMain());
-}
-
-void QEventDispatcherCoreFoundation::flush()
-{
- // X11 only.
-}
-
-#pragma mark - Socket notifiers
-
-void QEventDispatcherCoreFoundation::registerSocketNotifier(QSocketNotifier *notifier)
-{
- m_cfSocketNotifier.registerSocketNotifier(notifier);
-}
-
-void QEventDispatcherCoreFoundation::unregisterSocketNotifier(QSocketNotifier *notifier)
-{
- m_cfSocketNotifier.unregisterSocketNotifier(notifier);
-}
-
-#pragma mark - Timers
-
-void QEventDispatcherCoreFoundation::registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object)
-{
- qEventDispatcherDebug() << "id = " << timerId << ", interval = " << interval
- << ", type = " << timerType << ", object = " << object;
-
- Q_ASSERT(timerId > 0 && interval >= 0 && object);
- Q_ASSERT(object->thread() == thread() && thread() == QThread::currentThread());
-
- m_timerInfoList.registerTimer(timerId, interval, timerType, object);
- updateTimers();
-}
-
-bool QEventDispatcherCoreFoundation::unregisterTimer(int timerId)
-{
- Q_ASSERT(timerId > 0);
- Q_ASSERT(thread() == QThread::currentThread());
-
- bool returnValue = m_timerInfoList.unregisterTimer(timerId);
-
- qEventDispatcherDebug() << "id = " << timerId << ", timers left: " << m_timerInfoList.size();
-
- updateTimers();
- return returnValue;
-}
-
-bool QEventDispatcherCoreFoundation::unregisterTimers(QObject *object)
-{
- Q_ASSERT(object && object->thread() == thread() && thread() == QThread::currentThread());
-
- bool returnValue = m_timerInfoList.unregisterTimers(object);
-
- qEventDispatcherDebug() << "object = " << object << ", timers left: " << m_timerInfoList.size();
-
- updateTimers();
- return returnValue;
-}
-
-QList<QAbstractEventDispatcher::TimerInfo> QEventDispatcherCoreFoundation::registeredTimers(QObject *object) const
-{
- Q_ASSERT(object);
- return m_timerInfoList.registeredTimers(object);
-}
-
-int QEventDispatcherCoreFoundation::remainingTime(int timerId)
-{
- Q_ASSERT(timerId > 0);
- return m_timerInfoList.timerRemainingTime(timerId);
-}
-
-static double timespecToSeconds(const timespec &spec)
-{
- static double nanosecondsPerSecond = 1.0 * 1000 * 1000 * 1000;
- return spec.tv_sec + (spec.tv_nsec / nanosecondsPerSecond);
-}
-
-void QEventDispatcherCoreFoundation::updateTimers()
-{
- if (m_timerInfoList.size() > 0) {
- // We have Qt timers registered, so create or reschedule CF timer to match
-
- timespec tv = { -1, -1 };
- CFAbsoluteTime timeToFire = m_timerInfoList.timerWait(tv) ?
- // We have a timer ready to fire right now, or some time in the future
- CFAbsoluteTimeGetCurrent() + timespecToSeconds(tv)
- // We have timers, but they are all currently blocked by callbacks
- : kCFTimeIntervalDistantFuture;
-
- if (!m_runLoopTimer) {
- m_runLoopTimer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault,
- timeToFire, kCFTimeIntervalDistantFuture, 0, 0, ^(CFRunLoopTimerRef timer) {
- processTimers(timer);
- });
-
- CFRunLoopAddTimer(CFRunLoopGetMain(), m_runLoopTimer, kCFRunLoopCommonModes);
- qEventDispatcherDebug() << "Created new CFRunLoopTimer " << m_runLoopTimer;
-
- } else {
- CFRunLoopTimerSetNextFireDate(m_runLoopTimer, timeToFire);
- qEventDispatcherDebug() << "Re-scheduled CFRunLoopTimer " << m_runLoopTimer;
- }
-
- m_overdueTimerScheduled = !timespecToSeconds(tv);
-
- qEventDispatcherDebug() << "Next timeout in " << tv << " seconds";
-
- } else {
- // No Qt timers are registered, so make sure we're not running any CF timers
- invalidateTimer();
-
- m_overdueTimerScheduled = false;
- }
-}
-
-void QEventDispatcherCoreFoundation::invalidateTimer()
-{
- if (!m_runLoopTimer || (m_runLoopTimer == m_blockedRunLoopTimer))
- return;
-
- CFRunLoopTimerInvalidate(m_runLoopTimer);
- qEventDispatcherDebug() << "Invalidated CFRunLoopTimer " << m_runLoopTimer;
-
- CFRelease(m_runLoopTimer);
- m_runLoopTimer = 0;
-}
-
-#include "qeventdispatcher_cf.moc"
-#include "moc_qeventdispatcher_cf_p.cpp"
-
-QT_END_NAMESPACE
diff --git a/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h b/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h
deleted file mode 100644
index 1cd9ae4ebf..0000000000
--- a/src/platformsupport/eventdispatchers/qeventdispatcher_cf_p.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL21$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-**
-** Copyright (c) 2007-2008, Apple, Inc.
-**
-** All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are met:
-**
-** * Redistributions of source code must retain the above copyright notice,
-** this list of conditions and the following disclaimer.
-**
-** * Redistributions in binary form must reproduce the above copyright notice,
-** this list of conditions and the following disclaimer in the documentation
-** and/or other materials provided with the distribution.
-**
-** * Neither the name of Apple, Inc. nor the names of its contributors
-** may be used to endorse or promote products derived from this software
-** without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-****************************************************************************/
-
-#ifndef QEVENTDISPATCHER_CF_P_H
-#define QEVENTDISPATCHER_CF_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.
-//
-
-#define DEBUG_EVENT_DISPATCHER 0
-
-#include <QtCore/qabstracteventdispatcher.h>
-#include <QtCore/private/qtimerinfo_unix_p.h>
-#include <QtCore/qdebug.h>
-#include <QtPlatformSupport/private/qcfsocketnotifier_p.h>
-#include <CoreFoundation/CoreFoundation.h>
-
-#ifdef __OBJC__
-@class RunLoopModeTracker;
-#else
-typedef struct objc_object RunLoopModeTracker;
-#endif
-
-QT_BEGIN_NAMESPACE
-
-class QEventDispatcherCoreFoundation;
-
-template <class T = QEventDispatcherCoreFoundation>
-class RunLoopSource
-{
-public:
- typedef void (T::*CallbackFunction) ();
-
- enum { kHighestPriority = 0 } RunLoopSourcePriority;
-
- RunLoopSource(T *delegate, CallbackFunction callback)
- : m_delegate(delegate), m_callback(callback)
- {
- CFRunLoopSourceContext context = {};
- context.info = this;
- context.perform = RunLoopSource::process;
-
- m_source = CFRunLoopSourceCreate(kCFAllocatorDefault, kHighestPriority, &context);
- Q_ASSERT(m_source);
- }
-
- ~RunLoopSource()
- {
- CFRunLoopSourceInvalidate(m_source);
- CFRelease(m_source);
- }
-
- void addToMode(CFStringRef mode, CFRunLoopRef runLoop = 0)
- {
- if (!runLoop)
- runLoop = CFRunLoopGetCurrent();
-
- CFRunLoopAddSource(runLoop, m_source, mode);
- }
-
- void signal() { CFRunLoopSourceSignal(m_source); }
-
-private:
- static void process(void *info)
- {
- RunLoopSource *self = static_cast<RunLoopSource *>(info);
- ((self->m_delegate)->*(self->m_callback))();
- }
-
- T *m_delegate;
- CallbackFunction m_callback;
- CFRunLoopSourceRef m_source;
-};
-
-template <class T = QEventDispatcherCoreFoundation>
-class RunLoopObserver
-{
-public:
- typedef void (T::*CallbackFunction) (CFRunLoopActivity activity);
-
- RunLoopObserver(T *delegate, CallbackFunction callback, CFOptionFlags activities)
- : m_delegate(delegate), m_callback(callback)
- {
- CFRunLoopObserverContext context = {};
- context.info = this;
-
- m_observer = CFRunLoopObserverCreate(kCFAllocatorDefault, activities, true, 0, process, &context);
- Q_ASSERT(m_observer);
- }
-
- ~RunLoopObserver()
- {
- CFRunLoopObserverInvalidate(m_observer);
- CFRelease(m_observer);
- }
-
- void addToMode(CFStringRef mode, CFRunLoopRef runLoop = 0)
- {
- if (!runLoop)
- runLoop = CFRunLoopGetCurrent();
-
- if (!CFRunLoopContainsObserver(runLoop, m_observer, mode))
- CFRunLoopAddObserver(runLoop, m_observer, mode);
- }
-
- void removeFromMode(CFStringRef mode, CFRunLoopRef runLoop = 0)
- {
- if (!runLoop)
- runLoop = CFRunLoopGetCurrent();
-
- if (CFRunLoopContainsObserver(runLoop, m_observer, mode))
- CFRunLoopRemoveObserver(runLoop, m_observer, mode);
- }
-
-private:
- static void process(CFRunLoopObserverRef, CFRunLoopActivity activity, void *info)
- {
- RunLoopObserver *self = static_cast<RunLoopObserver *>(info);
- ((self->m_delegate)->*(self->m_callback))(activity);
- }
-
- T *m_delegate;
- CallbackFunction m_callback;
- CFRunLoopObserverRef m_observer;
-};
-
-class QEventDispatcherCoreFoundation : public QAbstractEventDispatcher
-{
- Q_OBJECT
-
-public:
- explicit QEventDispatcherCoreFoundation(QObject *parent = 0);
- ~QEventDispatcherCoreFoundation();
-
- bool processEvents(QEventLoop::ProcessEventsFlags flags);
- bool hasPendingEvents();
-
- void registerSocketNotifier(QSocketNotifier *notifier);
- void unregisterSocketNotifier(QSocketNotifier *notifier);
-
- void registerTimer(int timerId, int interval, Qt::TimerType timerType, QObject *object);
- bool unregisterTimer(int timerId);
- bool unregisterTimers(QObject *object);
- QList<QAbstractEventDispatcher::TimerInfo> registeredTimers(QObject *object) const;
-
- int remainingTime(int timerId);
-
- void wakeUp();
- void interrupt();
- void flush();
-
-private:
- RunLoopSource<> m_postedEventsRunLoopSource;
- RunLoopObserver<> m_runLoopActivityObserver;
-
- RunLoopModeTracker *m_runLoopModeTracker;
-
- QTimerInfoList m_timerInfoList;
- CFRunLoopTimerRef m_runLoopTimer;
- CFRunLoopTimerRef m_blockedRunLoopTimer;
- bool m_overdueTimerScheduled;
-
- QCFSocketNotifier m_cfSocketNotifier;
-
- struct ProcessEventsState
- {
- ProcessEventsState(QEventLoop::ProcessEventsFlags f)
- : flags(f), wasInterrupted(false)
- , processedPostedEvents(false), processedTimers(false)
- , deferredWakeUp(false), deferredUpdateTimers(false) {}
-
- QEventLoop::ProcessEventsFlags flags;
- bool wasInterrupted;
- bool processedPostedEvents;
- bool processedTimers;
- bool deferredWakeUp;
- bool deferredUpdateTimers;
- };
-
- ProcessEventsState m_processEvents;
-
- void processPostedEvents();
- void processTimers(CFRunLoopTimerRef);
-
- void handleRunLoopActivity(CFRunLoopActivity activity);
-
- void updateTimers();
- void invalidateTimer();
-};
-
-QT_END_NAMESPACE
-
-#if DEBUG_EVENT_DISPATCHER
-extern uint g_eventDispatcherIndentationLevel;
-#define qEventDispatcherDebug() qDebug().nospace() \
- << qPrintable(QString(QLatin1String("| ")).repeated(g_eventDispatcherIndentationLevel)) \
- << __FUNCTION__ << "(): "
-#define qIndent() ++g_eventDispatcherIndentationLevel
-#define qUnIndent() --g_eventDispatcherIndentationLevel
-#else
-#define qEventDispatcherDebug() QT_NO_QDEBUG_MACRO()
-#define qIndent()
-#define qUnIndent()
-#endif
-
-#endif // QEVENTDISPATCHER_CF_P_H
diff --git a/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp b/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp
new file mode 100644
index 0000000000..f57d16f51d
--- /dev/null
+++ b/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher.cpp
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Samuel Gaist <samuel.gaist@edeltech.ch>
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwindowsguieventdispatcher_p.h"
+
+#include <qpa/qwindowsysteminterface.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QWindowsGuiEventDispatcher
+ \brief Event dispatcher for Windows
+
+ Maintains a global stack storing the current event dispatcher and
+ its processing flags for access from the Windows procedure
+ qWindowsWndProc. Handling the Lighthouse gui events should be done
+ from within the qWindowsWndProc to ensure correct processing of messages.
+
+ \internal
+ \ingroup qt-lighthouse-win
+*/
+
+QWindowsGuiEventDispatcher::QWindowsGuiEventDispatcher(QObject *parent) :
+ QEventDispatcherWin32(parent), m_flags(0)
+{
+ setObjectName(QStringLiteral("QWindowsGuiEventDispatcher"));
+ createInternalHwnd(); // QTBUG-40881: Do not delay registering timers, etc. for QtMfc.
+}
+
+bool QWindowsGuiEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
+{
+ const QEventLoop::ProcessEventsFlags oldFlags = m_flags;
+ m_flags = flags;
+ const bool rc = QEventDispatcherWin32::processEvents(flags);
+ m_flags = oldFlags;
+ return rc;
+}
+
+void QWindowsGuiEventDispatcher::sendPostedEvents()
+{
+ QEventDispatcherWin32::sendPostedEvents();
+ QWindowSystemInterface::sendWindowSystemEvents(m_flags);
+}
+
+// Helpers for printing debug output for WM_* messages.
+struct MessageDebugEntry
+{
+ UINT message;
+ const char *description;
+ bool interesting;
+};
+
+static const MessageDebugEntry
+messageDebugEntries[] = {
+ {WM_CREATE, "WM_CREATE", true},
+ {WM_PAINT, "WM_PAINT", true},
+ {WM_CLOSE, "WM_CLOSE", true},
+ {WM_DESTROY, "WM_DESTROY", true},
+ {WM_MOVE, "WM_MOVE", true},
+ {WM_SIZE, "WM_SIZE", true},
+ {WM_GETICON, "WM_GETICON", false},
+ {WM_KEYDOWN, "WM_KEYDOWN", true},
+ {WM_SYSKEYDOWN, "WM_SYSKEYDOWN", true},
+ {WM_SYSCOMMAND, "WM_SYSCOMMAND", true},
+ {WM_KEYUP, "WM_KEYUP", true},
+ {WM_SYSKEYUP, "WM_SYSKEYUP", true},
+#if defined(WM_APPCOMMAND)
+ {WM_APPCOMMAND, "WM_APPCOMMAND", true},
+#endif
+ {WM_IME_CHAR, "WM_IMECHAR", true},
+ {WM_IME_KEYDOWN, "WM_IMECHAR", true},
+ {WM_CANCELMODE, "WM_CANCELMODE", true},
+ {WM_CHAR, "WM_CHAR", true},
+ {WM_DEADCHAR, "WM_DEADCHAR", true},
+ {WM_ACTIVATE, "WM_ACTIVATE", true},
+ {WM_SETFOCUS, "WM_SETFOCUS", true},
+ {WM_KILLFOCUS, "WM_KILLFOCUS", true},
+ {WM_ENABLE, "WM_ENABLE", true},
+ {WM_SHOWWINDOW, "WM_SHOWWINDOW", true},
+ {WM_WINDOWPOSCHANGED, "WM_WINDOWPOSCHANGED", true},
+ {WM_SETCURSOR, "WM_SETCURSOR", false},
+ {WM_GETFONT, "WM_GETFONT", true},
+ {WM_LBUTTONDOWN, "WM_LBUTTONDOWN", true},
+ {WM_LBUTTONUP, "WM_LBUTTONUP", true},
+ {WM_LBUTTONDBLCLK, "WM_LBUTTONDBLCLK", true},
+ {WM_RBUTTONDOWN, "WM_RBUTTONDOWN", true},
+ {WM_RBUTTONUP, "WM_RBUTTONUP", true},
+ {WM_RBUTTONDBLCLK, "WM_RBUTTONDBLCLK", true},
+ {WM_MBUTTONDOWN, "WM_MBUTTONDOWN", true},
+ {WM_MBUTTONUP, "WM_MBUTTONUP", true},
+ {WM_MBUTTONDBLCLK, "WM_MBUTTONDBLCLK", true},
+ {WM_MOUSEWHEEL, "WM_MOUSEWHEEL", true},
+ {WM_XBUTTONDOWN, "WM_XBUTTONDOWN", true},
+ {WM_XBUTTONUP, "WM_XBUTTONUP", true},
+ {WM_XBUTTONDBLCLK, "WM_XBUTTONDBLCLK", true},
+ {WM_MOUSEHWHEEL, "WM_MOUSEHWHEEL", true},
+ {WM_IME_SETCONTEXT, "WM_IME_SETCONTEXT", true},
+ {WM_INPUTLANGCHANGE, "WM_INPUTLANGCHANGE", true},
+ {WM_IME_NOTIFY, "WM_IME_NOTIFY", true},
+#if defined(WM_DWMNCRENDERINGCHANGED)
+ {WM_DWMNCRENDERINGCHANGED, "WM_DWMNCRENDERINGCHANGED", true},
+#endif
+ {WM_IME_SETCONTEXT, "WM_IME_SETCONTEXT", true},
+ {WM_IME_NOTIFY, "WM_IME_NOTIFY", true},
+ {WM_RENDERFORMAT, "WM_RENDERFORMAT", true},
+ {WM_RENDERALLFORMATS, "WM_RENDERALLFORMATS", true},
+ {WM_DESTROYCLIPBOARD, "WM_DESTROYCLIPBOARD", true},
+ {WM_CAPTURECHANGED, "WM_CAPTURECHANGED", true},
+ {WM_IME_STARTCOMPOSITION, "WM_IME_STARTCOMPOSITION", true},
+ {WM_IME_COMPOSITION, "WM_IME_COMPOSITION", true},
+ {WM_IME_ENDCOMPOSITION, "WM_IME_ENDCOMPOSITION", true},
+ {WM_IME_NOTIFY, "WM_IME_NOTIFY", true},
+ {WM_IME_REQUEST, "WM_IME_REQUEST", true},
+#if !defined(Q_OS_WINCE) && !defined(QT_NO_SESSIONMANAGER)
+ {WM_QUERYENDSESSION, "WM_QUERYENDSESSION", true},
+ {WM_ENDSESSION, "WM_ENDSESSION", true},
+#endif
+#ifndef Q_OS_WINCE
+ {WM_MOUSEACTIVATE,"WM_MOUSEACTIVATE", true},
+ {WM_CHILDACTIVATE, "WM_CHILDACTIVATE", true},
+ {WM_PARENTNOTIFY, "WM_PARENTNOTIFY", true},
+ {WM_ENTERIDLE, "WM_ENTERIDLE", false},
+ {WM_GETMINMAXINFO, "WM_GETMINMAXINFO", true},
+ {WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING", true},
+ {WM_NCCREATE, "WM_NCCREATE", true},
+ {WM_NCCALCSIZE, "WM_NCCALCSIZE", true},
+ {WM_NCACTIVATE, "WM_NCACTIVATE", true},
+ {WM_NCMOUSEMOVE, "WM_NCMOUSEMOVE", true},
+ {WM_NCMOUSELEAVE, "WM_NCMOUSELEAVE", true},
+ {WM_NCLBUTTONDOWN, "WM_NCLBUTTONDOWN", true},
+ {WM_NCLBUTTONUP, "WM_NCLBUTTONUP", true},
+ {WM_ACTIVATEAPP, "WM_ACTIVATEAPP", true},
+ {WM_NCPAINT, "WM_NCPAINT", true},
+ {WM_ERASEBKGND, "WM_ERASEBKGND", true},
+ {WM_MOUSEMOVE, "WM_MOUSEMOVE", true},
+ {WM_MOUSELEAVE, "WM_MOUSELEAVE", true},
+ {WM_NCHITTEST, "WM_NCHITTEST", false},
+#ifdef WM_TOUCH
+ {WM_TOUCH, "WM_TOUCH", true},
+#endif
+ {WM_CHANGECBCHAIN, "WM_CHANGECBCHAIN", true},
+ {WM_DISPLAYCHANGE, "WM_DISPLAYCHANGE", true},
+ {WM_DRAWCLIPBOARD, "WM_DRAWCLIPBOARD", true},
+#endif // !Q_OS_WINCE
+ {WM_THEMECHANGED, "WM_THEMECHANGED", true}
+};
+
+static inline const MessageDebugEntry *messageDebugEntry(UINT msg)
+{
+ for (size_t i = 0; i < sizeof(messageDebugEntries)/sizeof(MessageDebugEntry); i++)
+ if (messageDebugEntries[i].message == msg)
+ return messageDebugEntries + i;
+ return 0;
+}
+
+const char *QWindowsGuiEventDispatcher::windowsMessageName(UINT msg)
+{
+ if (const MessageDebugEntry *e = messageDebugEntry(msg))
+ return e->description;
+ return "Unknown";
+}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h b/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher_p.h
index 4a987f6860..1e9c906cc8 100644
--- a/src/platformsupport/eglconvenience/qeglplatformscreen_p.h
+++ b/src/platformsupport/eventdispatchers/qwindowsguieventdispatcher_p.h
@@ -31,49 +31,39 @@
**
****************************************************************************/
-#ifndef QEGLPLATFORMSCREEN_H
-#define QEGLPLATFORMSCREEN_H
+#ifndef QWINDOWSGUIEVENTDISPATCHER_H
+#define QWINDOWSGUIEVENTDISPATCHER_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.
+// This file is not part of the Qt API. It exists for the convenience
+// of the QLibrary class. This header file may change from
+// version to version without notice, or even be removed.
//
// We mean it.
//
-#include <QtCore/QList>
-#include <QtCore/QPoint>
-#include <QtCore/qtextstream.h>
-#include <qpa/qplatformscreen.h>
-#include <EGL/egl.h>
+#include <QtCore/private/qeventdispatcher_win_p.h>
QT_BEGIN_NAMESPACE
-class QOpenGLContext;
-class QWindow;
-class QEGLPlatformWindow;
-
-class QEGLPlatformScreen : public QPlatformScreen
+class QWindowsGuiEventDispatcher : public QEventDispatcherWin32
{
+ Q_OBJECT
public:
- QEGLPlatformScreen(EGLDisplay dpy);
- ~QEGLPlatformScreen();
-
- EGLDisplay display() const { return m_dpy; }
+ explicit QWindowsGuiEventDispatcher(QObject *parent = 0);
- void handleCursorMove(const QPoint &pos);
+ static const char *windowsMessageName(UINT msg);
- QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE;
+ bool QT_ENSURE_STACK_ALIGNED_FOR_SSE processEvents(QEventLoop::ProcessEventsFlags flags) Q_DECL_OVERRIDE;
+ void sendPostedEvents() Q_DECL_OVERRIDE;
private:
- EGLDisplay m_dpy;
- QWindow *m_pointerWindow;
+ QEventLoop::ProcessEventsFlags m_flags;
};
QT_END_NAMESPACE
-#endif // QEGLPLATFORMSCREEN_H
+#endif // QWINDOWSGUIEVENTDISPATCHER_H
diff --git a/src/platformsupport/fbconvenience/qfbbackingstore_p.h b/src/platformsupport/fbconvenience/qfbbackingstore_p.h
index 1dc8127fed..3a44128449 100644
--- a/src/platformsupport/fbconvenience/qfbbackingstore_p.h
+++ b/src/platformsupport/fbconvenience/qfbbackingstore_p.h
@@ -60,10 +60,10 @@ public:
QFbBackingStore(QWindow *window);
~QFbBackingStore();
- virtual QPaintDevice *paintDevice() Q_DECL_OVERRIDE { return &mImage; }
- virtual void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
+ QPaintDevice *paintDevice() Q_DECL_OVERRIDE { return &mImage; }
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
- virtual void resize(const QSize &size, const QRegion &region) Q_DECL_OVERRIDE;
+ void resize(const QSize &size, const QRegion &region) Q_DECL_OVERRIDE;
const QImage image();
diff --git a/src/platformsupport/fbconvenience/qfbscreen.cpp b/src/platformsupport/fbconvenience/qfbscreen.cpp
index 566f84c9ea..d00954375d 100644
--- a/src/platformsupport/fbconvenience/qfbscreen.cpp
+++ b/src/platformsupport/fbconvenience/qfbscreen.cpp
@@ -206,10 +206,11 @@ void QFbScreen::generateRects()
}
#endif
}
- foreach (const QRect &rect, remainingScreen.rects())
+ const QVector<QRect> remainingScreenRects = remainingScreen.rects();
+ mCachedRects.reserve(mCachedRects.count() + remainingScreenRects.count());
+ foreach (const QRect &rect, remainingScreenRects)
mCachedRects += QPair<QRect, int>(rect, -1);
mIsUpToDate = true;
- return;
}
QRegion QFbScreen::doRedraw()
diff --git a/src/platformsupport/fbconvenience/qfbvthandler.cpp b/src/platformsupport/fbconvenience/qfbvthandler.cpp
index c46e470c34..5e062b3f0a 100644
--- a/src/platformsupport/fbconvenience/qfbvthandler.cpp
+++ b/src/platformsupport/fbconvenience/qfbvthandler.cpp
@@ -79,87 +79,79 @@ static void setTTYCursor(bool enable)
}
#endif
+#ifdef VTH_ENABLED
+static QFbVtHandler *vth;
+
+void QFbVtHandler::signalHandler(int sigNo)
+{
+ char a = sigNo;
+ QT_WRITE(vth->m_sigFd[0], &a, sizeof(a));
+}
+#endif
+
QFbVtHandler::QFbVtHandler(QObject *parent)
: QObject(parent),
m_tty(-1),
- m_signalFd(-1),
m_signalNotifier(0)
{
#ifdef VTH_ENABLED
- setTTYCursor(false);
-
- if (isatty(0)) {
+ if (isatty(0))
m_tty = 0;
- ioctl(m_tty, KDGKBMODE, &m_oldKbdMode);
- if (!qEnvironmentVariableIntValue("QT_QPA_ENABLE_TERMINAL_KEYBOARD")) {
- // Disable the tty keyboard.
- ioctl(m_tty, KDSKBMUTE, 1);
- ioctl(m_tty, KDSKBMODE, KBD_OFF_MODE);
- }
+ if (::socketpair(AF_UNIX, SOCK_STREAM, 0, m_sigFd)) {
+ qErrnoWarning(errno, "QFbVtHandler: socketpair() failed");
+ return;
}
- // SIGSEGV and such cannot safely be blocked. We cannot handle them in an
- // async-safe manner either. Restoring the keyboard, video mode, etc. may
- // all contain calls that cannot safely be made from a signal handler.
-
- // Other signals: block them and use signalfd.
- sigset_t mask;
- sigemptyset(&mask);
-
- // Catch Ctrl+C.
- sigaddset(&mask, SIGINT);
-
- // Ctrl+Z. Up to the platform plugins to handle it in a meaningful way.
- sigaddset(&mask, SIGTSTP);
- sigaddset(&mask, SIGCONT);
-
- // Default signal used by kill. To overcome the common issue of no cleaning
- // up when killing a locally started app via a remote session.
- sigaddset(&mask, SIGTERM);
-
- m_signalFd = signalfd(-1, &mask, SFD_CLOEXEC);
- if (m_signalFd < 0) {
- qErrnoWarning(errno, "signalfd() failed");
- } else {
- m_signalNotifier = new QSocketNotifier(m_signalFd, QSocketNotifier::Read, this);
- connect(m_signalNotifier, &QSocketNotifier::activated, this, &QFbVtHandler::handleSignal);
-
- // Block the signals that are handled via signalfd. Applies only to the current
- // thread, but new threads will inherit the creator's signal mask.
- pthread_sigmask(SIG_BLOCK, &mask, 0);
- }
+ vth = this;
+ setTTYCursor(false);
+ setKeyboardEnabled(false);
+
+ m_signalNotifier = new QSocketNotifier(m_sigFd[1], QSocketNotifier::Read, this);
+ connect(m_signalNotifier, &QSocketNotifier::activated, this, &QFbVtHandler::handleSignal);
+
+ struct sigaction sa;
+ sa.sa_flags = 0;
+ sa.sa_handler = signalHandler;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGINT, &sa, 0); // Ctrl+C
+ sigaction(SIGTSTP, &sa, 0); // Ctrl+Z
+ sigaction(SIGCONT, &sa, 0);
+ sigaction(SIGTERM, &sa, 0); // default signal used by kill
#endif
}
QFbVtHandler::~QFbVtHandler()
{
#ifdef VTH_ENABLED
- restoreKeyboard();
+ setKeyboardEnabled(true);
setTTYCursor(true);
- if (m_signalFd != -1)
- close(m_signalFd);
+ if (m_signalNotifier) {
+ close(m_sigFd[0]);
+ close(m_sigFd[1]);
+ }
#endif
}
-void QFbVtHandler::restoreKeyboard()
+void QFbVtHandler::setKeyboardEnabled(bool enable)
{
#ifdef VTH_ENABLED
if (m_tty == -1)
return;
- ioctl(m_tty, KDSKBMUTE, 0);
- ioctl(m_tty, KDSKBMODE, m_oldKbdMode);
-#endif
-}
-
-// To be called from the slot connected to suspendRequested() in case the
-// platform plugin does in fact allow suspending on Ctrl+Z.
-void QFbVtHandler::suspend()
-{
-#ifdef VTH_ENABLED
- kill(getpid(), SIGSTOP);
+ if (enable) {
+ ::ioctl(m_tty, KDSKBMUTE, 0);
+ ::ioctl(m_tty, KDSKBMODE, m_oldKbdMode);
+ } else {
+ ::ioctl(m_tty, KDGKBMODE, &m_oldKbdMode);
+ if (!qEnvironmentVariableIntValue("QT_QPA_ENABLE_TERMINAL_KEYBOARD")) {
+ ::ioctl(m_tty, KDSKBMUTE, 1);
+ ::ioctl(m_tty, KDSKBMODE, KBD_OFF_MODE);
+ }
+ }
+#else
+ Q_UNUSED(enable);
#endif
}
@@ -168,17 +160,22 @@ void QFbVtHandler::handleSignal()
#ifdef VTH_ENABLED
m_signalNotifier->setEnabled(false);
- signalfd_siginfo sig;
- if (read(m_signalFd, &sig, sizeof(sig)) == sizeof(sig)) {
- switch (sig.ssi_signo) {
+ char sigNo;
+ if (QT_READ(m_sigFd[1], &sigNo, sizeof(sigNo)) == sizeof(sigNo)) {
+ switch (sigNo) {
case SIGINT: // fallthrough
case SIGTERM:
handleInt();
break;
case SIGTSTP:
- emit suspendRequested();
+ emit aboutToSuspend();
+ setKeyboardEnabled(true);
+ setTTYCursor(true);
+ ::kill(getpid(), SIGSTOP);
break;
case SIGCONT:
+ setTTYCursor(false);
+ setKeyboardEnabled(false);
emit resumed();
break;
default:
@@ -194,7 +191,7 @@ void QFbVtHandler::handleInt()
{
#ifdef VTH_ENABLED
emit interrupted();
- restoreKeyboard();
+ setKeyboardEnabled(true);
setTTYCursor(true);
_exit(1);
#endif
diff --git a/src/platformsupport/fbconvenience/qfbvthandler_p.h b/src/platformsupport/fbconvenience/qfbvthandler_p.h
index 3681def9f0..91eba248fe 100644
--- a/src/platformsupport/fbconvenience/qfbvthandler_p.h
+++ b/src/platformsupport/fbconvenience/qfbvthandler_p.h
@@ -59,23 +59,22 @@ public:
QFbVtHandler(QObject *parent = 0);
~QFbVtHandler();
- void suspend();
-
signals:
void interrupted();
- void suspendRequested();
+ void aboutToSuspend();
void resumed();
private slots:
void handleSignal();
private:
- void restoreKeyboard();
+ void setKeyboardEnabled(bool enable);
void handleInt();
+ static void signalHandler(int sigNo);
int m_tty;
int m_oldKbdMode;
- int m_signalFd;
+ int m_sigFd[2];
QSocketNotifier *m_signalNotifier;
};
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
index c41061a9fd..728b166b71 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
@@ -76,24 +76,6 @@ void QBasicFontDatabase::populateFontDatabase()
}
}
-inline static void setHintingPreference(QFontEngine *engine, QFont::HintingPreference hintingPreference)
-{
- switch (hintingPreference) {
- case QFont::PreferNoHinting:
- engine->setDefaultHintStyle(QFontEngineFT::HintNone);
- break;
- case QFont::PreferFullHinting:
- engine->setDefaultHintStyle(QFontEngineFT::HintFull);
- break;
- case QFont::PreferVerticalHinting:
- engine->setDefaultHintStyle(QFontEngineFT::HintLight);
- break;
- case QFont::PreferDefaultHinting:
- // Leave it as it is
- break;
- }
-}
-
QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPtr)
{
FontFile *fontfile = static_cast<FontFile *> (usrPtr);
@@ -119,7 +101,7 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QFontDef &fontDef, void *usrPt
delete engine;
engine = 0;
} else {
- setHintingPreference(engine, static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
+ engine->setQtDefaultHintStyle(static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
}
return engine;
@@ -172,7 +154,7 @@ QFontEngine *QBasicFontDatabase::fontEngine(const QByteArray &fontData, qreal pi
}
fe->updateFamilyNameAndStyle();
- setHintingPreference(fe, hintingPreference);
+ fe->setQtDefaultHintStyle(static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
return fe;
}
@@ -206,7 +188,7 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt
error = FT_New_Face(library, file.constData(), index, &face);
}
if (error != FT_Err_Ok) {
- qDebug() << "FT_New_Face failed with index" << index << ":" << hex << error;
+ qDebug() << "FT_New_Face failed with index" << index << ':' << hex << error;
break;
}
numFaces = face->num_faces;
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index 112bb8e0a6..a5fe88871d 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -44,6 +44,7 @@
#include <QtGui/private/qfontengine_ft_p.h>
#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtGui/qguiapplication.h>
@@ -241,7 +242,13 @@ static const char *specialLanguages[] = {
"sa", // Siddham
"sd", // Khudawadi
"mai", // Tirhuta
- "hoc" // WarangCiti
+ "hoc", // WarangCiti
+ "", // Ahom
+ "", // AnatolianHieroglyphs
+ "", // Hatran
+ "", // Multani
+ "", // OldHungarian
+ "" // SignWriting
};
Q_STATIC_ASSERT(sizeof(specialLanguages) / sizeof(const char *) == QChar::ScriptCount);
@@ -553,10 +560,8 @@ QFontEngine::HintStyle defaultHintStyleFromMatch(QFont::HintingPreference hintin
break;
}
- if (QGuiApplication::platformNativeInterface()->nativeResourceForScreen("nofonthinting",
- QGuiApplication::primaryScreen())) {
+ if (QHighDpiScaling::isActive())
return QFontEngine::HintNone;
- }
int hint_style = 0;
if (FcPatternGetInteger (match, FC_HINT_STYLE, 0, &hint_style) == FcResultMatch) {
@@ -711,15 +716,19 @@ QStringList QFontconfigDatabase::fallbacksForFamily(const QString &family, QFont
FcPatternDestroy(pattern);
if (fontSet) {
+ QSet<QString> duplicates;
+ duplicates.reserve(fontSet->nfont + 1);
+ duplicates.insert(family.toCaseFolded());
for (int i = 0; i < fontSet->nfont; i++) {
FcChar8 *value = 0;
if (FcPatternGetString(fontSet->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
continue;
// capitalize(value);
- QString familyName = QString::fromUtf8((const char *)value);
- if (!fallbackFamilies.contains(familyName,Qt::CaseInsensitive) &&
- familyName.compare(family, Qt::CaseInsensitive)) {
+ const QString familyName = QString::fromUtf8((const char *)value);
+ const QString familyNameCF = familyName.toCaseFolded();
+ if (!duplicates.contains(familyNameCF)) {
fallbackFamilies << familyName;
+ duplicates.insert(familyNameCF);
}
}
FcFontSetDestroy(fontSet);
diff --git a/src/platformsupport/fontdatabases/mac/coretext.pri b/src/platformsupport/fontdatabases/mac/coretext.pri
index f67f00672a..ebb64d15b4 100644
--- a/src/platformsupport/fontdatabases/mac/coretext.pri
+++ b/src/platformsupport/fontdatabases/mac/coretext.pri
@@ -1,6 +1,13 @@
HEADERS += $$PWD/qcoretextfontdatabase_p.h $$PWD/qfontengine_coretext_p.h
OBJECTIVE_SOURCES += $$PWD/qfontengine_coretext.mm $$PWD/qcoretextfontdatabase.mm
+contains(QT_CONFIG, freetype) {
+ include($$QT_SOURCE_TREE/src/3rdparty/freetype_dependency.pri)
+ HEADERS += $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft_p.h
+ SOURCES += $$QT_SOURCE_TREE/src/gui/text/qfontengine_ft.cpp
+ CONFIG += opentype
+}
+
ios: \
# On iOS CoreText and CoreGraphics are stand-alone frameworks
LIBS_PRIVATE += -framework CoreText -framework CoreGraphics
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
index be70092010..0af779097c 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase.mm
@@ -33,6 +33,8 @@
#include "qglobal.h"
+#include <sys/param.h>
+
#if defined(Q_OS_MACX)
#import <Cocoa/Cocoa.h>
#import <IOKit/graphics/IOGraphicsLib.h>
@@ -43,23 +45,13 @@
#include "qcoretextfontdatabase_p.h"
#include "qfontengine_coretext_p.h"
#include <QtCore/QSettings>
-#include <QtGui/QGuiApplication>
#include <QtCore/QtEndian>
+#ifndef QT_NO_FREETYPE
+#include <QtGui/private/qfontengine_ft_p.h>
+#endif
QT_BEGIN_NAMESPACE
-namespace {
-class AutoReleasePool
-{
-public:
- AutoReleasePool(): pool([[NSAutoreleasePool alloc] init]) {}
- ~AutoReleasePool() { [pool release]; }
-
-private:
- NSAutoreleasePool *pool;
-};
-}
-
// this could become a list of all languages used for each writing
// system, instead of using the single most common language.
static const char *languageForWritingSystem[] = {
@@ -114,8 +106,12 @@ static NSInteger languageMapSort(id obj1, id obj2, void *context)
}
#endif
-QCoreTextFontDatabase::QCoreTextFontDatabase()
+QCoreTextFontDatabase::QCoreTextFontDatabase(bool useFreeType)
+#ifndef QT_NO_FREETYPE
+ : m_useFreeType(useFreeType)
+#endif
{
+ Q_UNUSED(useFreeType)
#ifdef Q_OS_MACX
QSettings appleSettings(QLatin1String("apple.com"));
QVariant appleValue = appleSettings.value(QLatin1String("AppleAntiAliasingThreshold"));
@@ -360,22 +356,56 @@ void QCoreTextFontDatabase::releaseHandle(void *handle)
CFRelease(CTFontDescriptorRef(handle));
}
+#ifndef QT_NO_FREETYPE
+static QByteArray filenameForCFUrl(CFURLRef url)
+{
+ // The on-stack buffer prevents that a QByteArray allocated for the worst case (MAXPATHLEN)
+ // stays around for the lifetime of the font. Additionally, it helps to move the char
+ // signedness cast to an acceptable place.
+ uchar buffer[MAXPATHLEN];
+ QByteArray filename;
+
+ if (!CFURLGetFileSystemRepresentation(url, true, buffer, sizeof(buffer))) {
+ qWarning("QCoreTextFontDatabase::filenameForCFUrl: could not resolve file for URL %s",
+ qPrintable(QString::fromCFString(CFURLGetString(url))));
+ } else {
+ QCFType<CFStringRef> scheme = CFURLCopyScheme(url);
+ if (QString::fromCFString(scheme) == QLatin1String("qrc"))
+ filename = ":";
+
+ filename += reinterpret_cast<char *>(buffer);
+ }
+
+ return filename;
+}
+#endif
+
extern CGAffineTransform qt_transform_from_fontdef(const QFontDef &fontDef);
QFontEngine *QCoreTextFontDatabase::fontEngine(const QFontDef &f, void *usrPtr)
{
- qreal scaledPointSize = f.pixelSize;
+ CTFontDescriptorRef descriptor = static_cast<CTFontDescriptorRef>(usrPtr);
+
+#ifndef QT_NO_FREETYPE
+ if (m_useFreeType) {
+ QCFType<CFURLRef> url(static_cast<CFURLRef>(CTFontDescriptorCopyAttribute(descriptor, kCTFontURLAttribute)));
- // When 96 DPI is forced, the Mac plugin will use DPI 72 for some
- // fonts (hardcoded in qcocoaintegration.mm) and 96 for others. This
- // discrepancy makes it impossible to find the correct point size
- // here without having the DPI used for the font. Until a proper
- // solution (requiring API change) can be made, we simply fall back
- // to passing in the point size to retain old behavior.
- if (QGuiApplication::testAttribute(Qt::AA_Use96Dpi))
- scaledPointSize = f.pointSize;
+ QByteArray filename;
+ if (url)
+ filename = filenameForCFUrl(url);
+
+ return freeTypeFontEngine(f, filename);
+ }
+#endif
+
+ // Since we do not pass in the destination DPI to CoreText when making
+ // the font, we need to pass in a point size which is scaled to include
+ // the DPI. The default DPI for the screen is 72, thus the scale factor
+ // is destinationDpi / 72, but since pixelSize = pointSize / 72 * dpi,
+ // the pixelSize is actually the scaled point size for the destination
+ // DPI, and we can use that directly.
+ qreal scaledPointSize = f.pixelSize;
- CTFontDescriptorRef descriptor = (CTFontDescriptorRef) usrPtr;
CGAffineTransform matrix = qt_transform_from_fontdef(f);
CTFontRef font = CTFontCreateWithFontDescriptor(descriptor, scaledPointSize, &matrix);
if (font) {
@@ -397,6 +427,29 @@ static void releaseFontData(void* info, const void* data, size_t size)
QFontEngine *QCoreTextFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference)
{
+#ifndef QT_NO_FREETYPE
+ if (m_useFreeType) {
+ QByteArray *fontDataCopy = new QByteArray(fontData);
+ QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(fontDataCopy,
+ fontDataCopy->constData(), fontDataCopy->size(), releaseFontData);
+ QCFType<CGFontRef> cgFont(CGFontCreateWithDataProvider(dataProvider));
+
+ if (!cgFont) {
+ qWarning("QCoreTextFontDatabase::fontEngine: CGFontCreateWithDataProvider failed");
+ return Q_NULLPTR;
+ }
+
+ QFontDef fontDef;
+ fontDef.pixelSize = pixelSize;
+ fontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi();
+ fontDef.hintingPreference = hintingPreference;
+ CGAffineTransform transform = qt_transform_from_fontdef(fontDef);
+ QCFType<CTFontRef> ctFont(CTFontCreateWithGraphicsFont(cgFont, fontDef.pixelSize, &transform, Q_NULLPTR));
+ QCFType<CFURLRef> url(static_cast<CFURLRef>(CTFontCopyAttribute(ctFont, kCTFontURLAttribute)));
+ return freeTypeFontEngine(fontDef, filenameForCFUrl(url), fontData);
+ }
+#endif
+
Q_UNUSED(hintingPreference);
QByteArray* fontDataCopy = new QByteArray(fontData);
@@ -453,7 +506,7 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
Q_UNUSED(style);
Q_UNUSED(script);
- AutoReleasePool pool;
+ QMacAutoReleasePool pool;
static QHash<QString, QStringList> fallbackLists;
@@ -568,10 +621,36 @@ QStringList QCoreTextFontDatabase::fallbacksForFamily(const QString &family, QFo
}
#if HAVE_CORETEXT
-static CFArrayRef createDescriptorArrayForFont(CTFontRef font)
+static CFArrayRef createDescriptorArrayForFont(CTFontRef font, const QString &fileName = QString())
{
CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
- CFArrayAppendValue(array, QCFType<CTFontDescriptorRef>(CTFontCopyFontDescriptor(font)));
+ QCFType<CTFontDescriptorRef> descriptor = CTFontCopyFontDescriptor(font);
+
+ Q_UNUSED(fileName)
+#ifndef QT_NO_FREETYPE
+ // The physical font source URL (usually a local file or Qt resource) is only required for
+ // FreeType, when using non-system fonts, and needs some hackery to attach in a format
+ // agreeable to OSX.
+ if (!fileName.isEmpty()) {
+ QCFType<CFURLRef> fontURL;
+
+ if (fileName.startsWith(QLatin1String(":/"))) {
+ // QUrl::fromLocalFile() doesn't accept qrc pseudo-paths like ":/fonts/myfont.ttf".
+ // Therefore construct from QString with the qrc:// scheme -> "qrc:///fonts/myfont.ttf".
+ fontURL = QUrl(QStringLiteral("qrc://") + fileName.mid(1)).toCFURL();
+ } else if (!fileName.isEmpty()) {
+ // At this point we hope that filename is in a format that QUrl can handle.
+ fontURL = QUrl::fromLocalFile(fileName).toCFURL();
+ }
+
+ QCFType<CFMutableDictionaryRef> attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 1,
+ &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionaryAddValue(attributes, kCTFontURLAttribute, fontURL);
+ descriptor = CTFontDescriptorCreateCopyWithAttributes(descriptor, attributes);
+ }
+#endif
+
+ CFArrayAppendValue(array, descriptor);
return array;
}
#endif
@@ -592,7 +671,11 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
if (cgFont) {
if (CTFontManagerRegisterGraphicsFont(cgFont, &error)) {
QCFType<CTFontRef> font = CTFontCreateWithGraphicsFont(cgFont, 0.0, NULL, NULL);
- fonts = createDescriptorArrayForFont(font);
+ fonts = createDescriptorArrayForFont(font
+#ifndef QT_NO_FREETYPE
+ , m_useFreeType ? fileName : QString()
+#endif
+ );
m_applicationFonts.append(QVariant::fromValue(QCFType<CGFontRef>::constructFromGet(cgFont)));
}
}
@@ -638,8 +721,8 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
kATSOptionFlagsDefault, &fontContainer);
} else {
FSRef ref;
- OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref);
- if (qt_mac_create_fsref(fileName, &ref) != noErr)
+ if (FSPathMakeRef(reinterpret_cast<const UInt8 *>(fileName.toUtf8().constData()),
+ &ref, 0) != noErr)
return QStringList();
e = ATSFontActivateFromFileReference(&ref, kATSFontContextLocal, kATSFontFormatUnspecified, 0,
kATSOptionFlagsDefault, &fontContainer);
@@ -892,5 +975,36 @@ void QCoreTextFontDatabase::removeApplicationFonts()
#endif
}
+#ifndef QT_NO_FREETYPE
+QFontEngine *QCoreTextFontDatabase::freeTypeFontEngine(const QFontDef &fontDef, const QByteArray &filename,
+ const QByteArray &fontData)
+{
+ QFontEngine::FaceId faceId;
+ faceId.filename = filename;
+ const bool antialias = !(fontDef.styleStrategy & QFont::NoAntialias);
+
+ QScopedPointer<QFontEngineFT> engine(new QFontEngineFT(fontDef));
+ QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_Mono;
+ if (antialias) {
+ QFontEngine::SubpixelAntialiasingType subpixelType = subpixelAntialiasingTypeHint();
+ if (subpixelType == QFontEngine::Subpixel_None || (fontDef.styleStrategy & QFont::NoSubpixelAntialias)) {
+ format = QFontEngineFT::Format_A8;
+ engine->subpixelType = QFontEngine::Subpixel_None;
+ } else {
+ format = QFontEngineFT::Format_A32;
+ engine->subpixelType = subpixelType;
+ }
+ }
+
+ if (!engine->init(faceId, antialias, format, fontData) || engine->invalid()) {
+ qWarning() << "QCoreTextFontDatabase::freeTypefontEngine Failed to create engine";
+ return Q_NULLPTR;
+ }
+ engine->setQtDefaultHintStyle(static_cast<QFont::HintingPreference>(fontDef.hintingPreference));
+
+ return engine.take();
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
index a423ed5ae2..95af1210b3 100644
--- a/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/mac/qcoretextfontdatabase_p.h
@@ -73,7 +73,7 @@ QT_BEGIN_NAMESPACE
class QCoreTextFontDatabase : public QPlatformFontDatabase
{
public:
- QCoreTextFontDatabase();
+ QCoreTextFontDatabase(bool useFreeType = false);
~QCoreTextFontDatabase();
void populateFontDatabase() Q_DECL_OVERRIDE;
void populateFamily(const QString &familyName) Q_DECL_OVERRIDE;
@@ -95,6 +95,11 @@ public:
private:
void populateFromDescriptor(CTFontDescriptorRef font);
+#ifndef QT_NO_FREETYPE
+ bool m_useFreeType;
+ QFontEngine *freeTypeFontEngine(const QFontDef &fontDef, const QByteArray &filename,
+ const QByteArray &fontData = QByteArray());
+#endif
mutable QString defaultFontName;
void removeApplicationFonts();
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 7e1dfd9275..732aead62a 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -361,16 +361,6 @@ qreal QCoreTextFontEngine::maxCharWidth() const
return bb.xoff.toReal();
}
-qreal QCoreTextFontEngine::minLeftBearing() const
-{
- return 0;
-}
-
-qreal QCoreTextFontEngine::minRightBearing() const
-{
- return 0;
-}
-
void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight)
{
QVarLengthArray<QFixedPoint> positions;
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
index f8ec1d326f..1c33ae7d84 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext_p.h
@@ -96,8 +96,6 @@ public:
QImage alphaRGBMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) Q_DECL_OVERRIDE;
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat) Q_DECL_OVERRIDE;
QImage bitmapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t) Q_DECL_OVERRIDE;
- qreal minRightBearing() const Q_DECL_OVERRIDE;
- qreal minLeftBearing() const Q_DECL_OVERRIDE;
QFixed emSquareSize() const Q_DECL_OVERRIDE;
bool supportsTransformation(const QTransform &transform) const Q_DECL_OVERRIDE;
diff --git a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp
index 2e9723329e..76d8aab8f2 100644
--- a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp
+++ b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp
@@ -43,6 +43,7 @@
#include <qplatformdefs.h>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
+#include <private/qhighdpiscaling_p.h>
#include <errno.h>
@@ -141,14 +142,15 @@ bool QEvdevMouseHandler::getHardwareMaximum()
m_hardwareHeight = absInfo.maximum - absInfo.minimum;
- QRect g = QGuiApplication::primaryScreen()->virtualGeometry();
+ QScreen *primaryScreen = QGuiApplication::primaryScreen();
+ QRect g = QHighDpi::toNativePixels(primaryScreen->virtualGeometry(), primaryScreen);
m_hardwareScalerX = static_cast<qreal>(m_hardwareWidth) / (g.right() - g.left());
m_hardwareScalerY = static_cast<qreal>(m_hardwareHeight) / (g.bottom() - g.top());
qCDebug(qLcEvdevMouse) << "Absolute pointing device"
<< "hardware max x" << m_hardwareWidth
<< "hardware max y" << m_hardwareHeight
- << "hardware scalers x" << m_hardwareScalerX << "y" << m_hardwareScalerY;
+ << "hardware scalers x" << m_hardwareScalerX << 'y' << m_hardwareScalerY;
return true;
}
diff --git a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp
index 805397f021..68db0b26ba 100644
--- a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp
+++ b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp
@@ -41,6 +41,7 @@
#include <QtPlatformSupport/private/qdevicediscovery_p.h>
#include <private/qguiapplication_p.h>
#include <private/qinputdevicemanager_p_p.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -106,7 +107,8 @@ QEvdevMouseManager::~QEvdevMouseManager()
void QEvdevMouseManager::clampPosition()
{
// clamp to screen geometry
- QRect g = QGuiApplication::primaryScreen()->virtualGeometry();
+ QScreen *primaryScreen = QGuiApplication::primaryScreen();
+ QRect g = QHighDpi::toNativePixels(primaryScreen->virtualGeometry(), primaryScreen);
if (m_x + m_xoffset < g.left())
m_x = g.left() - m_xoffset;
else if (m_x + m_xoffset > g.right())
diff --git a/src/platformsupport/input/evdevtablet/qevdevtablet.cpp b/src/platformsupport/input/evdevtablet/qevdevtablet.cpp
index c59f0f390a..c6f952c64d 100644
--- a/src/platformsupport/input/evdevtablet/qevdevtablet.cpp
+++ b/src/platformsupport/input/evdevtablet/qevdevtablet.cpp
@@ -292,7 +292,7 @@ void QEvdevTabletHandler::readData()
QEvdevTabletHandlerThread::QEvdevTabletHandlerThread(const QString &spec, QObject *parent)
- : QThread(parent), m_spec(spec), m_handler(0)
+ : QDaemonThread(parent), m_spec(spec), m_handler(0)
{
start();
}
diff --git a/src/platformsupport/input/evdevtablet/qevdevtablet_p.h b/src/platformsupport/input/evdevtablet/qevdevtablet_p.h
index f9682290d9..f546f9a88a 100644
--- a/src/platformsupport/input/evdevtablet/qevdevtablet_p.h
+++ b/src/platformsupport/input/evdevtablet/qevdevtablet_p.h
@@ -48,6 +48,7 @@
#include <QObject>
#include <QString>
#include <QThread>
+#include <QtCore/private/qthread_p.h>
QT_BEGIN_NAMESPACE
@@ -68,7 +69,7 @@ private:
QEvdevTabletData *d;
};
-class QEvdevTabletHandlerThread : public QThread
+class QEvdevTabletHandlerThread : public QDaemonThread
{
public:
explicit QEvdevTabletHandlerThread(const QString &spec, QObject *parent = 0);
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
index 885326e512..ad348cc083 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler.cpp
@@ -38,6 +38,7 @@
#include <QGuiApplication>
#include <QLoggingCategory>
#include <QtCore/private/qcore_unix_p.h>
+#include <QtGui/private/qhighdpiscaling_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <linux/input.h>
@@ -106,9 +107,8 @@ public:
int m_currentSlot;
int findClosestContact(const QHash<int, Contact> &contacts, int x, int y, int *dist);
- void reportPoints();
- void registerDevice();
void addTouchPoint(const Contact &contact, Qt::TouchPointStates *combinedStates);
+ void reportPoints();
int hw_range_x_min;
int hw_range_x_max;
@@ -118,7 +118,6 @@ public:
int hw_pressure_max;
QString hw_name;
bool m_forceToActiveWindow;
- QTouchDevice *m_device;
bool m_typeB;
QTransform m_rotate;
bool m_singleTouch;
@@ -131,23 +130,11 @@ QEvdevTouchScreenData::QEvdevTouchScreenData(QEvdevTouchScreenHandler *q_ptr, co
hw_range_x_min(0), hw_range_x_max(0),
hw_range_y_min(0), hw_range_y_max(0),
hw_pressure_min(0), hw_pressure_max(0),
- m_device(0), m_typeB(false), m_singleTouch(false)
+ m_typeB(false), m_singleTouch(false)
{
m_forceToActiveWindow = args.contains(QLatin1String("force_window"));
}
-void QEvdevTouchScreenData::registerDevice()
-{
- m_device = new QTouchDevice;
- m_device->setName(hw_name);
- m_device->setType(QTouchDevice::TouchScreen);
- m_device->setCapabilities(QTouchDevice::Position | QTouchDevice::Area);
- if (hw_pressure_max > hw_pressure_min)
- m_device->setCapabilities(m_device->capabilities() | QTouchDevice::Pressure);
-
- QWindowSystemInterface::registerTouchDevice(m_device);
-}
-
#define LONG_BITS (sizeof(long) << 3)
#define NUM_LONGS(bits) (((bits) + LONG_BITS - 1) / LONG_BITS)
@@ -159,9 +146,9 @@ static inline bool testBit(long bit, const long *array)
#endif
QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const QString &spec, QObject *parent)
- : QObject(parent), m_notify(0), m_fd(-1), d(0)
+ : QObject(parent), m_notify(Q_NULLPTR), m_fd(-1), d(Q_NULLPTR), m_device(Q_NULLPTR)
#if !defined(QT_NO_MTDEV)
- , m_mtdev(0)
+ , m_mtdev(Q_NULLPTR)
#endif
{
setObjectName(QLatin1String("Evdev Touch Handler"));
@@ -298,7 +285,7 @@ QEvdevTouchScreenHandler::QEvdevTouchScreenHandler(const QString &device, const
if (inverty)
d->m_rotate *= QTransform::fromTranslate(0.5, 0.5).scale(1.0, -1.0).translate(-0.5, -0.5);
- d->registerDevice();
+ registerTouchDevice();
}
QEvdevTouchScreenHandler::~QEvdevTouchScreenHandler()
@@ -314,6 +301,13 @@ QEvdevTouchScreenHandler::~QEvdevTouchScreenHandler()
QT_CLOSE(m_fd);
delete d;
+
+ unregisterTouchDevice();
+}
+
+QTouchDevice *QEvdevTouchScreenHandler::touchDevice() const
+{
+ return m_device;
}
void QEvdevTouchScreenHandler::readData()
@@ -367,15 +361,44 @@ err:
qErrnoWarning(errno, "evdevtouch: Could not read from input device");
if (errno == ENODEV) { // device got disconnected -> stop reading
delete m_notify;
- m_notify = 0;
+ m_notify = Q_NULLPTR;
+
QT_CLOSE(m_fd);
m_fd = -1;
+
+ unregisterTouchDevice();
}
return;
}
}
}
+void QEvdevTouchScreenHandler::registerTouchDevice()
+{
+ if (m_device)
+ return;
+
+ m_device = new QTouchDevice;
+ m_device->setName(d->hw_name);
+ m_device->setType(QTouchDevice::TouchScreen);
+ m_device->setCapabilities(QTouchDevice::Position | QTouchDevice::Area);
+ if (d->hw_pressure_max > d->hw_pressure_min)
+ m_device->setCapabilities(m_device->capabilities() | QTouchDevice::Pressure);
+
+ QWindowSystemInterface::registerTouchDevice(m_device);
+}
+
+void QEvdevTouchScreenHandler::unregisterTouchDevice()
+{
+ if (!m_device)
+ return;
+
+ QWindowSystemInterface::unregisterTouchDevice(m_device);
+
+ delete m_device;
+ m_device = Q_NULLPTR;
+}
+
void QEvdevTouchScreenData::addTouchPoint(const Contact &contact, Qt::TouchPointStates *combinedStates)
{
QWindowSystemInterface::TouchPoint tp;
@@ -418,11 +441,11 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
m_currentData.y = qBound(hw_range_y_min, data->value, hw_range_y_max);
if (m_singleTouch)
m_contacts[m_currentSlot].y = m_currentData.y;
- if (m_typeB) {
- m_contacts[m_currentSlot].y = m_currentData.y;
- if (m_contacts[m_currentSlot].state == Qt::TouchPointStationary)
- m_contacts[m_currentSlot].state = Qt::TouchPointMoved;
- }
+ if (m_typeB) {
+ m_contacts[m_currentSlot].y = m_currentData.y;
+ if (m_contacts[m_currentSlot].state == Qt::TouchPointStationary)
+ m_contacts[m_currentSlot].state = Qt::TouchPointMoved;
+ }
} else if (data->code == ABS_MT_TRACKING_ID) {
m_currentData.trackingId = data->value;
if (m_typeB) {
@@ -604,9 +627,10 @@ void QEvdevTouchScreenData::reportPoints()
QWindow *win = QGuiApplication::focusWindow();
if (!win)
return;
- winRect = win->geometry();
+ winRect = QHighDpi::toNativePixels(win->geometry(), win);
} else {
- winRect = QGuiApplication::primaryScreen()->geometry();
+ QScreen *primary = QGuiApplication::primaryScreen();
+ winRect = QHighDpi::toNativePixels(primary->geometry(), primary);
}
const int hw_w = hw_range_x_max - hw_range_x_min;
@@ -637,12 +661,12 @@ void QEvdevTouchScreenData::reportPoints()
tp.pressure = (tp.pressure - hw_pressure_min) / qreal(hw_pressure_max - hw_pressure_min);
}
- QWindowSystemInterface::handleTouchEvent(0, m_device, m_touchPoints);
+ QWindowSystemInterface::handleTouchEvent(Q_NULLPTR, q->touchDevice(), m_touchPoints);
}
QEvdevTouchScreenHandlerThread::QEvdevTouchScreenHandlerThread(const QString &device, const QString &spec, QObject *parent)
- : QThread(parent), m_device(device), m_spec(spec), m_handler(0)
+ : QDaemonThread(parent), m_device(device), m_spec(spec), m_handler(Q_NULLPTR), m_touchDeviceRegistered(false)
{
start();
}
@@ -656,9 +680,24 @@ QEvdevTouchScreenHandlerThread::~QEvdevTouchScreenHandlerThread()
void QEvdevTouchScreenHandlerThread::run()
{
m_handler = new QEvdevTouchScreenHandler(m_device, m_spec);
+ // Report the registration to the parent thread by invoking the method asynchronously
+ QMetaObject::invokeMethod(this, "notifyTouchDeviceRegistered", Qt::QueuedConnection);
+
exec();
+
delete m_handler;
- m_handler = 0;
+ m_handler = Q_NULLPTR;
+}
+
+bool QEvdevTouchScreenHandlerThread::isTouchDeviceRegistered() const
+{
+ return m_touchDeviceRegistered;
+}
+
+void QEvdevTouchScreenHandlerThread::notifyTouchDeviceRegistered()
+{
+ m_touchDeviceRegistered = true;
+ emit touchDeviceRegistered();
}
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h b/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h
index a6d3a860f5..ca9756d5de 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchhandler_p.h
@@ -49,6 +49,7 @@
#include <QString>
#include <QList>
#include <QThread>
+#include <QtCore/private/qthread_p.h>
#include <qpa/qwindowsysteminterface.h>
#if !defined(QT_NO_MTDEV)
@@ -65,33 +66,47 @@ class QEvdevTouchScreenHandler : public QObject
Q_OBJECT
public:
- explicit QEvdevTouchScreenHandler(const QString &device, const QString &spec = QString(), QObject *parent = 0);
+ explicit QEvdevTouchScreenHandler(const QString &device, const QString &spec = QString(), QObject *parent = Q_NULLPTR);
~QEvdevTouchScreenHandler();
+ QTouchDevice *touchDevice() const;
+
private slots:
void readData();
private:
+ void registerTouchDevice();
+ void unregisterTouchDevice();
+
QSocketNotifier *m_notify;
int m_fd;
QEvdevTouchScreenData *d;
+ QTouchDevice *m_device;
#if !defined(QT_NO_MTDEV)
mtdev *m_mtdev;
#endif
};
-class QEvdevTouchScreenHandlerThread : public QThread
+class QEvdevTouchScreenHandlerThread : public QDaemonThread
{
+ Q_OBJECT
public:
- explicit QEvdevTouchScreenHandlerThread(const QString &device, const QString &spec, QObject *parent = 0);
+ explicit QEvdevTouchScreenHandlerThread(const QString &device, const QString &spec, QObject *parent = Q_NULLPTR);
~QEvdevTouchScreenHandlerThread();
void run() Q_DECL_OVERRIDE;
- QEvdevTouchScreenHandler *handler() { return m_handler; }
+
+ bool isTouchDeviceRegistered() const;
+
+signals:
+ void touchDeviceRegistered();
private:
+ Q_INVOKABLE void notifyTouchDeviceRegistered();
+
QString m_device;
QString m_spec;
QEvdevTouchScreenHandler *m_handler;
+ bool m_touchDeviceRegistered;
};
QT_END_NAMESPACE
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp b/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp
index 98fc83700c..57028495c5 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchmanager.cpp
@@ -95,13 +95,12 @@ QEvdevTouchManager::~QEvdevTouchManager()
void QEvdevTouchManager::addDevice(const QString &deviceNode)
{
- qCDebug(qLcEvdevTouch) << "Adding device at" << deviceNode;
+ qCDebug(qLcEvdevTouch) << "evdevtouch: Adding device at" << deviceNode;
QEvdevTouchScreenHandlerThread *handler;
handler = new QEvdevTouchScreenHandlerThread(deviceNode, m_spec);
if (handler) {
m_activeDevices.insert(deviceNode, handler);
- QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount(
- QInputDeviceManager::DeviceTypeTouch, m_activeDevices.count());
+ connect(handler, &QEvdevTouchScreenHandlerThread::touchDeviceRegistered, this, &QEvdevTouchManager::updateInputDeviceCount);
} else {
qWarning("evdevtouch: Failed to open touch device %s", qPrintable(deviceNode));
}
@@ -110,13 +109,28 @@ void QEvdevTouchManager::addDevice(const QString &deviceNode)
void QEvdevTouchManager::removeDevice(const QString &deviceNode)
{
if (m_activeDevices.contains(deviceNode)) {
- qCDebug(qLcEvdevTouch) << "Removing device at" << deviceNode;
+ qCDebug(qLcEvdevTouch) << "evdevtouch: Removing device at" << deviceNode;
QEvdevTouchScreenHandlerThread *handler = m_activeDevices.value(deviceNode);
m_activeDevices.remove(deviceNode);
- QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount(
- QInputDeviceManager::DeviceTypeTouch, m_activeDevices.count());
delete handler;
+
+ updateInputDeviceCount();
}
}
+void QEvdevTouchManager::updateInputDeviceCount()
+{
+ int registeredTouchDevices = 0;
+ Q_FOREACH (QEvdevTouchScreenHandlerThread *handler, m_activeDevices) {
+ if (handler->isTouchDeviceRegistered())
+ ++registeredTouchDevices;
+ }
+
+ qCDebug(qLcEvdevTouch) << "evdevtouch: Updating QInputDeviceManager device count:" << registeredTouchDevices << " touch devices,"
+ << m_activeDevices.count() - registeredTouchDevices << "pending handler(s)" ;
+
+ QInputDeviceManagerPrivate::get(QGuiApplicationPrivate::inputDeviceManager())->setDeviceCount(
+ QInputDeviceManager::DeviceTypeTouch, registeredTouchDevices);
+}
+
QT_END_NAMESPACE
diff --git a/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h b/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h
index bf484fd88b..289c345ac4 100644
--- a/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h
+++ b/src/platformsupport/input/evdevtouch/qevdevtouchmanager_p.h
@@ -65,6 +65,8 @@ private slots:
void addDevice(const QString &deviceNode);
void removeDevice(const QString &deviceNode);
+ void updateInputDeviceCount();
+
private:
QString m_spec;
QDeviceDiscovery *m_deviceDiscovery;
diff --git a/src/platformsupport/input/libinput/qlibinputhandler.cpp b/src/platformsupport/input/libinput/qlibinputhandler.cpp
index 1a64ad5a30..5aa66a4eaf 100644
--- a/src/platformsupport/input/libinput/qlibinputhandler.cpp
+++ b/src/platformsupport/input/libinput/qlibinputhandler.cpp
@@ -46,7 +46,7 @@
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(qLcInput, "qt.qpa.input")
+Q_LOGGING_CATEGORY(qLcLibInput, "qt.qpa.input")
static int liOpen(const char *path, int flags, void *user_data)
{
@@ -75,7 +75,7 @@ static void liLogHandler(libinput *libinput, libinput_log_priority priority, con
if (n > 0) {
if (buf[n - 1] == '\n')
buf[n - 1] = '\0';
- qCDebug(qLcInput, "libinput: %s", buf);
+ qCDebug(qLcLibInput, "libinput: %s", buf);
}
}
@@ -93,7 +93,7 @@ QLibInputHandler::QLibInputHandler(const QString &key, const QString &spec)
qFatal("Failed to get libinput context");
libinput_log_set_handler(m_li, liLogHandler);
- if (qLcInput().isDebugEnabled())
+ if (qLcLibInput().isDebugEnabled())
libinput_log_set_priority(m_li, LIBINPUT_LOG_PRIORITY_DEBUG);
if (libinput_udev_assign_seat(m_li, "seat0"))
diff --git a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp
index 5f1bc550b4..ec7ea7ef0d 100644
--- a/src/platformsupport/input/libinput/qlibinputkeyboard.cpp
+++ b/src/platformsupport/input/libinput/qlibinputkeyboard.cpp
@@ -33,6 +33,7 @@
#include "qlibinputkeyboard_p.h"
#include <QtCore/QTextCodec>
+#include <QtCore/QLoggingCategory>
#include <qpa/qwindowsysteminterface.h>
#include <libinput.h>
#ifndef QT_NO_XKBCOMMON_EVDEV
@@ -42,6 +43,8 @@
QT_BEGIN_NAMESPACE
+Q_DECLARE_LOGGING_CATEGORY(qLcLibInput)
+
const int REPEAT_DELAY = 500;
const int REPEAT_RATE = 100;
@@ -128,6 +131,7 @@ QLibInputKeyboard::QLibInputKeyboard()
#endif
{
#ifndef QT_NO_XKBCOMMON_EVDEV
+ qCDebug(qLcLibInput) << "Using xkbcommon for key mapping";
m_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (!m_ctx) {
qWarning("Failed to create xkb context");
@@ -150,6 +154,8 @@ QLibInputKeyboard::QLibInputKeyboard()
m_repeatTimer.setSingleShot(true);
connect(&m_repeatTimer, &QTimer::timeout, this, &QLibInputKeyboard::handleRepeat);
+#else
+ qCWarning(qLcLibInput) << "X-less xkbcommon not available, not performing key mapping";
#endif
}
@@ -174,10 +180,13 @@ void QLibInputKeyboard::processKey(libinput_event_keyboard *e)
const uint32_t k = libinput_event_keyboard_get_key(e) + 8;
const bool pressed = libinput_event_keyboard_get_key_state(e) == LIBINPUT_KEY_STATE_PRESSED;
- QByteArray chars;
- chars.resize(1 + xkb_state_key_get_utf8(m_state, k, Q_NULLPTR, 0));
- xkb_state_key_get_utf8(m_state, k, chars.data(), chars.size());
- const QString text = QString::fromUtf8(chars);
+ QVarLengthArray<char, 32> chars(32);
+ const int size = xkb_state_key_get_utf8(m_state, k, chars.data(), chars.size());
+ if (Q_UNLIKELY(size + 1 > chars.size())) { // +1 for NUL
+ chars.resize(size + 1);
+ xkb_state_key_get_utf8(m_state, k, chars.data(), chars.size());
+ }
+ const QString text = QString::fromUtf8(chars.constData(), size);
const xkb_keysym_t sym = xkb_state_key_get_one_sym(m_state, k);
diff --git a/src/platformsupport/input/libinput/qlibinputpointer.cpp b/src/platformsupport/input/libinput/qlibinputpointer.cpp
index 48e5a6cf1c..55339a841a 100644
--- a/src/platformsupport/input/libinput/qlibinputpointer.cpp
+++ b/src/platformsupport/input/libinput/qlibinputpointer.cpp
@@ -36,6 +36,7 @@
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#include <qpa/qwindowsysteminterface.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -81,7 +82,8 @@ void QLibInputPointer::processMotion(libinput_event_pointer *e)
{
const double dx = libinput_event_pointer_get_dx(e);
const double dy = libinput_event_pointer_get_dy(e);
- const QRect g = QGuiApplication::primaryScreen()->virtualGeometry();
+ QScreen * const primaryScreen = QGuiApplication::primaryScreen();
+ const QRect g = QHighDpi::toNativePixels(primaryScreen->virtualGeometry(), primaryScreen);
m_pos.setX(qBound(g.left(), qRound(m_pos.x() + dx), g.right()));
m_pos.setY(qBound(g.top(), qRound(m_pos.y() + dy), g.bottom()));
@@ -110,7 +112,9 @@ void QLibInputPointer::processAxis(libinput_event_pointer *e)
void QLibInputPointer::setPos(const QPoint &pos)
{
- const QRect g = QGuiApplication::primaryScreen()->virtualGeometry();
+ QScreen * const primaryScreen = QGuiApplication::primaryScreen();
+ const QRect g = QHighDpi::toNativePixels(primaryScreen->virtualGeometry(), primaryScreen);
+
m_pos.setX(qBound(g.left(), pos.x(), g.right()));
m_pos.setY(qBound(g.top(), pos.y(), g.bottom()));
}
diff --git a/src/platformsupport/input/tslib/qtslib_p.h b/src/platformsupport/input/tslib/qtslib_p.h
index c3ee6697fa..b6448c67d7 100644
--- a/src/platformsupport/input/tslib/qtslib_p.h
+++ b/src/platformsupport/input/tslib/qtslib_p.h
@@ -34,6 +34,17 @@
#ifndef QTSLIB_H
#define QTSLIB_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include <QObject>
struct tsdev;
diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
index c040dab5e1..0293c74fb9 100644
--- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
@@ -1431,7 +1431,9 @@ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QS
QSpiObjectReference(connection, QDBusObjectPath(QSPI_OBJECT_PATH_ROOT))));
} else if (function == QLatin1String("GetChildren")) {
QSpiObjectReferenceArray children;
- for (int i = 0; i < interface->childCount(); ++i) {
+ const int numChildren = interface->childCount();
+ children.reserve(numChildren);
+ for (int i = 0; i < numChildren; ++i) {
QString childPath = pathForInterface(interface->child(i));
QSpiObjectReference ref(connection, QDBusObjectPath(childPath));
children << ref;
@@ -1507,7 +1509,7 @@ QSpiRelationArray AtSpiAdaptor::relationSet(QAccessibleInterface *interface, con
Q_FOREACH (const RelationPair &pair, relationInterfaces) {
// FIXME: this loop seems a bit strange... "related" always have one item when we check.
//And why is it a list, when it always have one item? And it seems to assume that the QAccessible::Relation enum maps directly to AtSpi
- QList<QSpiObjectReference> related;
+ QSpiObjectReferenceArray related;
QDBusObjectPath path = QDBusObjectPath(pathForInterface(pair.first));
related.append(QSpiObjectReference(connection, path));
@@ -1747,7 +1749,9 @@ QSpiActionArray AtSpiAdaptor::getActions(QAccessibleInterface *interface) const
{
QAccessibleActionInterface *actionInterface = interface->actionInterface();
QSpiActionArray actions;
- Q_FOREACH (const QString &actionName, QAccessibleBridgeUtils::effectiveActionNames(interface)) {
+ const QStringList actionNames = QAccessibleBridgeUtils::effectiveActionNames(interface);
+ actions.reserve(actionNames.size());
+ Q_FOREACH (const QString &actionName, actionNames) {
QSpiAction action;
QStringList keyBindings;
@@ -2308,7 +2312,7 @@ bool AtSpiAdaptor::tableInterface(QAccessibleInterface *interface, const QString
(column < 0) ||
(row >= interface->tableInterface()->rowCount()) ||
(column >= interface->tableInterface()->columnCount())) {
- qAtspiDebug() << "WARNING: invalid index for tableInterface GetAccessibleAt (" << row << ", " << column << ")";
+ qAtspiDebug() << "WARNING: invalid index for tableInterface GetAccessibleAt (" << row << ", " << column << ')';
return false;
}
@@ -2327,7 +2331,7 @@ bool AtSpiAdaptor::tableInterface(QAccessibleInterface *interface, const QString
int column = message.arguments().at(1).toInt();
QAccessibleInterface *cell = interface->tableInterface()->cellAt(row, column);
if (!cell) {
- qAtspiDebug() << "WARNING: AtSpiAdaptor::GetIndexAt(" << row << "," << column << ") did not find a cell. " << interface;
+ qAtspiDebug() << "WARNING: AtSpiAdaptor::GetIndexAt(" << row << ',' << column << ") did not find a cell. " << interface;
return false;
}
int index = interface->indexOfChild(cell);
diff --git a/src/platformsupport/linuxaccessibility/bridge.cpp b/src/platformsupport/linuxaccessibility/bridge.cpp
index 55ef7161d1..bd02b032f9 100644
--- a/src/platformsupport/linuxaccessibility/bridge.cpp
+++ b/src/platformsupport/linuxaccessibility/bridge.cpp
@@ -99,7 +99,7 @@ void QSpiAccessibleBridge::notifyAccessibilityUpdate(QAccessibleEvent *event)
{
if (!dbusAdaptor)
return;
- if (isActive())
+ if (isActive() && event->accessibleInterface())
dbusAdaptor->notify(event);
}
diff --git a/src/platformsupport/linuxaccessibility/bridge_p.h b/src/platformsupport/linuxaccessibility/bridge_p.h
index 802b1e4725..69ab618e17 100644
--- a/src/platformsupport/linuxaccessibility/bridge_p.h
+++ b/src/platformsupport/linuxaccessibility/bridge_p.h
@@ -66,7 +66,7 @@ public:
virtual ~QSpiAccessibleBridge();
- virtual void notifyAccessibilityUpdate(QAccessibleEvent *event) Q_DECL_OVERRIDE;
+ void notifyAccessibilityUpdate(QAccessibleEvent *event) Q_DECL_OVERRIDE;
QDBusConnection dBusConnection() const;
public Q_SLOTS:
diff --git a/src/platformsupport/linuxaccessibility/cache.cpp b/src/platformsupport/linuxaccessibility/cache.cpp
index 2ece905fdf..0ccd2cba6e 100644
--- a/src/platformsupport/linuxaccessibility/cache.cpp
+++ b/src/platformsupport/linuxaccessibility/cache.cpp
@@ -78,8 +78,7 @@ void QSpiDBusCache::emitRemoveAccessible(const QSpiObjectReference& item)
QSpiAccessibleCacheArray QSpiDBusCache::GetItems()
{
- QList <QSpiAccessibleCacheItem> cacheArray;
- return cacheArray;
+ return QSpiAccessibleCacheArray();
}
QT_END_NAMESPACE
diff --git a/src/platformsupport/linuxaccessibility/dbusconnection.cpp b/src/platformsupport/linuxaccessibility/dbusconnection.cpp
index 45729fa065..ae1ba1819a 100644
--- a/src/platformsupport/linuxaccessibility/dbusconnection.cpp
+++ b/src/platformsupport/linuxaccessibility/dbusconnection.cpp
@@ -42,10 +42,16 @@
#include <QDBusConnectionInterface>
#include "bus_interface.h"
+#include <QtGui/qguiapplication.h>
+#include <qplatformnativeinterface.h>
+
QT_BEGIN_NAMESPACE
-QString A11Y_SERVICE = QStringLiteral("org.a11y.Bus");
-QString A11Y_PATH = QStringLiteral("/org/a11y/bus");
+/* note: do not change these to QStringLiteral;
+ we are unloaded before QtDBus is done using the strings.
+ */
+#define A11Y_SERVICE QLatin1String("org.a11y.Bus")
+#define A11Y_PATH QLatin1String("/org/a11y/bus")
/*!
\class DBusConnection
@@ -65,6 +71,29 @@ DBusConnection::DBusConnection(QObject *parent)
// If it is registered already, setup a11y right away
if (c.interface()->isServiceRegistered(A11Y_SERVICE))
serviceRegistered();
+
+ // In addition try if there is an xatom exposing the bus address, this allows applications run as root to work
+ QString address = getAddressFromXCB();
+ if (!address.isEmpty()) {
+ m_enabled = true;
+ connectA11yBus(address);
+ }
+}
+
+QString DBusConnection::getAddressFromXCB()
+{
+ QGuiApplication *app = qobject_cast<QGuiApplication *>(QCoreApplication::instance());
+ if (!app)
+ return QString();
+ QPlatformNativeInterface *platformNativeInterface = app->platformNativeInterface();
+ QByteArray *addressByteArray = reinterpret_cast<QByteArray*>(
+ platformNativeInterface->nativeResourceForIntegration(QByteArrayLiteral("AtspiBus")));
+ if (addressByteArray) {
+ QString address = QString::fromLatin1(*addressByteArray);
+ delete addressByteArray;
+ return address;
+ }
+ return QString();
}
// We have the a11y registry on the session bus.
@@ -111,7 +140,7 @@ void DBusConnection::connectA11yBus(const QString &address)
qWarning("Could not find Accessibility DBus address.");
return;
}
- m_a11yConnection = QDBusConnection(QDBusConnection::connectToBus(address, QStringLiteral("a11y")));
+ m_a11yConnection = QDBusConnection(QDBusConnection::connectToBus(address, QLatin1String("a11y")));
if (m_enabled)
emit enabledChanged(true);
diff --git a/src/platformsupport/linuxaccessibility/dbusconnection_p.h b/src/platformsupport/linuxaccessibility/dbusconnection_p.h
index a0bd6450bf..30707a3f95 100644
--- a/src/platformsupport/linuxaccessibility/dbusconnection_p.h
+++ b/src/platformsupport/linuxaccessibility/dbusconnection_p.h
@@ -68,6 +68,7 @@ Q_SIGNALS:
void enabledChanged(bool enabled);
private Q_SLOTS:
+ QString getAddressFromXCB();
void serviceRegistered();
void serviceUnregistered();
void connectA11yBus(const QString &address);
diff --git a/src/platformsupport/linuxaccessibility/struct_marshallers_p.h b/src/platformsupport/linuxaccessibility/struct_marshallers_p.h
index 7788ceb7cc..61d79e6daa 100644
--- a/src/platformsupport/linuxaccessibility/struct_marshallers_p.h
+++ b/src/platformsupport/linuxaccessibility/struct_marshallers_p.h
@@ -46,7 +46,7 @@
// We mean it.
//
-#include <QtCore/qlist.h>
+#include <QtCore/qvector.h>
#include <QtCore/qpair.h>
#include <QtDBus/QDBusArgument>
#include <QtDBus/QDBusConnection>
@@ -55,8 +55,8 @@
#ifndef QT_NO_ACCESSIBILITY
QT_BEGIN_NAMESPACE
-typedef QList <int> QSpiIntList;
-typedef QList <uint> QSpiUIntList;
+typedef QVector<int> QSpiIntList;
+typedef QVector<uint> QSpiUIntList;
// FIXME: make this copy on write
struct QSpiObjectReference
@@ -68,26 +68,29 @@ struct QSpiObjectReference
QSpiObjectReference(const QDBusConnection& connection, const QDBusObjectPath& path)
: service(connection.baseService()), path(path) {}
};
+Q_DECLARE_TYPEINFO(QSpiObjectReference, Q_MOVABLE_TYPE); // QDBusObjectPath is movable, even though it
+ // cannot be marked that way until Qt 6
QDBusArgument &operator<<(QDBusArgument &argument, const QSpiObjectReference &address);
const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiObjectReference &address);
-typedef QList <QSpiObjectReference> QSpiObjectReferenceArray;
+typedef QVector<QSpiObjectReference> QSpiObjectReferenceArray;
struct QSpiAccessibleCacheItem
{
QSpiObjectReference path;
QSpiObjectReference application;
QSpiObjectReference parent;
- QList <QSpiObjectReference> children;
+ QSpiObjectReferenceArray children;
QStringList supportedInterfaces;
QString name;
uint role;
QString description;
QSpiUIntList state;
};
+Q_DECLARE_TYPEINFO(QSpiAccessibleCacheItem, Q_MOVABLE_TYPE);
-typedef QList <QSpiAccessibleCacheItem> QSpiAccessibleCacheArray;
+typedef QVector<QSpiAccessibleCacheItem> QSpiAccessibleCacheArray;
QDBusArgument &operator<<(QDBusArgument &argument, const QSpiAccessibleCacheItem &item);
const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiAccessibleCacheItem &item);
@@ -98,8 +101,9 @@ struct QSpiAction
QString description;
QString keyBinding;
};
+Q_DECLARE_TYPEINFO(QSpiAction, Q_MOVABLE_TYPE);
-typedef QList <QSpiAction> QSpiActionArray;
+typedef QVector<QSpiAction> QSpiActionArray;
QDBusArgument &operator<<(QDBusArgument &argument, const QSpiAction &action);
const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiAction &action);
@@ -109,14 +113,15 @@ struct QSpiEventListener
QString listenerAddress;
QString eventName;
};
+Q_DECLARE_TYPEINFO(QSpiEventListener, Q_MOVABLE_TYPE);
-typedef QList <QSpiEventListener> QSpiEventListenerArray;
+typedef QVector<QSpiEventListener> QSpiEventListenerArray;
QDBusArgument &operator<<(QDBusArgument &argument, const QSpiEventListener &action);
const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiEventListener &action);
-typedef QPair < unsigned int, QList < QSpiObjectReference > > QSpiRelationArrayEntry;
-typedef QList< QSpiRelationArrayEntry > QSpiRelationArray;
+typedef QPair<unsigned int, QSpiObjectReferenceArray> QSpiRelationArrayEntry;
+typedef QVector<QSpiRelationArrayEntry> QSpiRelationArray;
//a(iisv)
struct QSpiTextRange {
@@ -125,18 +130,22 @@ struct QSpiTextRange {
QString contents;
QVariant v;
};
-typedef QList <QSpiTextRange> QSpiTextRangeList;
+Q_DECLARE_TYPEINFO(QSpiTextRange, Q_MOVABLE_TYPE);
+
+typedef QVector<QSpiTextRange> QSpiTextRangeList;
typedef QMap <QString, QString> QSpiAttributeSet;
enum QSpiAppUpdateType {
QSPI_APP_UPDATE_ADDED = 0,
QSPI_APP_UPDATE_REMOVED = 1
};
+Q_DECLARE_TYPEINFO(QSpiAppUpdateType, Q_PRIMITIVE_TYPE);
struct QSpiAppUpdate {
int type; /* Is an application added or removed */
QString address; /* D-Bus address of application added or removed */
};
+Q_DECLARE_TYPEINFO(QSpiAppUpdate, Q_MOVABLE_TYPE);
QDBusArgument &operator<<(QDBusArgument &argument, const QSpiAppUpdate &update);
const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiAppUpdate &update);
@@ -150,6 +159,7 @@ struct QSpiDeviceEvent {
QString text;
bool isText;
};
+Q_DECLARE_TYPEINFO(QSpiDeviceEvent, Q_MOVABLE_TYPE);
QDBusArgument &operator<<(QDBusArgument &argument, const QSpiDeviceEvent &event);
const QDBusArgument &operator>>(const QDBusArgument &argument, QSpiDeviceEvent &event);
diff --git a/src/platformsupport/platformcompositor/qopenglcompositor.cpp b/src/platformsupport/platformcompositor/qopenglcompositor.cpp
index 2e386532e2..c65d69e842 100644
--- a/src/platformsupport/platformcompositor/qopenglcompositor.cpp
+++ b/src/platformsupport/platformcompositor/qopenglcompositor.cpp
@@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
It is up to the platform plugin to manage the lifetime of the
compositor (instance(), destroy()), set the correct destination
- context and window as early as possible (setTargetWindow()),
+ context and window as early as possible (setTarget()),
register the composited windows as they are shown, activated,
raised and lowered (addWindow(), moveToTop(), etc.), and to
schedule repaints (update()).
@@ -177,11 +177,11 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &targetWindowRect, QOpenGLTextureBlitter *blitter)
{
- const QRect rectInWindow = textures->geometry(idx);
- QRect clipRect = textures->clipRect(idx);
+ const QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty())
- clipRect = QRect(QPoint(0, 0), rectInWindow.size());
+ return;
+ const QRect rectInWindow = textures->geometry(idx);
const QRect clippedRectInWindow = rectInWindow & clipRect.translated(rectInWindow.topLeft());
const QRect srcRect = toBottomLeftRect(clipRect, rectInWindow.height());
diff --git a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp
index 55f8ea160c..8ec5d20e05 100644
--- a/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp
+++ b/src/platformsupport/platformcompositor/qopenglcompositorbackingstore.cpp
@@ -34,11 +34,17 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QWindow>
#include <QtGui/QPainter>
+#include <QtGui/QOffscreenSurface>
#include <qpa/qplatformbackingstore.h>
+#include <private/qwindow_p.h>
#include "qopenglcompositorbackingstore_p.h"
#include "qopenglcompositor_p.h"
+#ifndef GL_UNPACK_ROW_LENGTH
+#define GL_UNPACK_ROW_LENGTH 0x0CF2
+#endif
+
QT_BEGIN_NAMESPACE
/*!
@@ -77,13 +83,28 @@ QOpenGLCompositorBackingStore::~QOpenGLCompositorBackingStore()
{
if (m_bsTexture) {
QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ // With render-to-texture-widgets QWidget makes sure the TLW's shareContext() is
+ // made current before destroying backingstores. That is however not the case for
+ // windows with regular widgets only.
+ QScopedPointer<QOffscreenSurface> tempSurface;
+ if (!ctx) {
+ ctx = QOpenGLCompositor::instance()->context();
+ tempSurface.reset(new QOffscreenSurface);
+ tempSurface->setFormat(ctx->format());
+ tempSurface->create();
+ ctx->makeCurrent(tempSurface.data());
+ }
+
if (ctx && m_bsTextureContext && ctx->shareGroup() == m_bsTextureContext->shareGroup())
glDeleteTextures(1, &m_bsTexture);
else
qWarning("QOpenGLCompositorBackingStore: Texture is not valid in the current context");
+
+ if (tempSurface)
+ ctx->doneCurrent();
}
- delete m_textures;
+ delete m_textures; // this does not actually own any GL resources
}
QPaintDevice *QOpenGLCompositorBackingStore::paintDevice()
@@ -111,29 +132,39 @@ void QOpenGLCompositorBackingStore::updateTexture()
QRegion fixed;
QRect imageRect = m_image.rect();
- foreach (const QRect &rect, m_dirty.rects()) {
- // intersect with image rect to be sure
- QRect r = imageRect & rect;
-
- // if the rect is wide enough it's cheaper to just
- // extend it instead of doing an image copy
- if (r.width() >= imageRect.width() / 2) {
- r.setX(0);
- r.setWidth(imageRect.width());
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx->isOpenGLES() || ctx->format().majorVersion() >= 3) {
+ foreach (const QRect &rect, m_dirty.rects()) {
+ QRect r = imageRect & rect;
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, m_image.width());
+ glTexSubImage2D(GL_TEXTURE_2D, 0, r.x(), r.y(), r.width(), r.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ m_image.constScanLine(r.y()) + r.x() * 4);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}
-
- fixed |= r;
- }
-
- foreach (const QRect &rect, fixed.rects()) {
- // if the sub-rect is full-width we can pass the image data directly to
- // OpenGL instead of copying, since there's 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,
- m_image.constScanLine(rect.y()));
- } else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
- m_image.copy(rect).constBits());
+ } else {
+ foreach (const QRect &rect, m_dirty.rects()) {
+ // intersect with image rect to be sure
+ QRect r = imageRect & rect;
+
+ // if the rect is wide enough it's 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;
+ }
+ foreach (const QRect &rect, fixed.rects()) {
+ // if the sub-rect is full-width we can pass the image data directly to
+ // OpenGL instead of copying, since there's 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,
+ m_image.constScanLine(rect.y()));
+ } else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.width(), rect.height(), GL_RGBA, GL_UNSIGNED_BYTE,
+ m_image.copy(rect).constBits());
+ }
}
}
@@ -143,16 +174,15 @@ void QOpenGLCompositorBackingStore::updateTexture()
void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
{
- // Called for ordinary raster windows. This is rare since RasterGLSurface
- // support is claimed which leads to having all QWidget windows marked as
- // RasterGLSurface instead of just Raster. These go through
- // compositeAndFlush() instead of this function.
+ // Called for ordinary raster windows.
Q_UNUSED(region);
Q_UNUSED(offset);
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
QOpenGLContext *dstCtx = compositor->context();
+ Q_ASSERT(dstCtx);
+
QWindow *dstWin = compositor->targetWindow();
if (!dstWin)
return;
@@ -169,7 +199,7 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi
QPlatformTextureList *textures, QOpenGLContext *context,
bool translucentBackground)
{
- // QOpenGLWidget/QQuickWidget content provided as textures. The raster content should go on top.
+ // QOpenGLWidget/QQuickWidget content provided as textures. The raster content goes on top.
Q_UNUSED(region);
Q_UNUSED(offset);
@@ -178,12 +208,20 @@ void QOpenGLCompositorBackingStore::composeAndFlush(QWindow *window, const QRegi
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
QOpenGLContext *dstCtx = compositor->context();
+ Q_ASSERT(dstCtx); // setTarget() must have been called before, e.g. from QEGLFSWindow
+
+ // The compositor's context and the context to which QOpenGLWidget/QQuickWidget
+ // textures belong are not the same. They share resources, though.
+ Q_ASSERT(context->shareGroup() == dstCtx->shareGroup());
+
QWindow *dstWin = compositor->targetWindow();
if (!dstWin)
return;
dstCtx->makeCurrent(dstWin);
+ QWindowPrivate::get(window)->lastComposeTime.start();
+
m_textures->clear();
for (int i = 0; i < textures->count(); ++i)
m_textures->appendTexture(textures->source(i), textures->textureId(i), textures->geometry(i),
@@ -237,6 +275,7 @@ void QOpenGLCompositorBackingStore::resize(const QSize &size, const QRegion &sta
if (m_bsTexture) {
glDeleteTextures(1, &m_bsTexture);
m_bsTexture = 0;
+ m_bsTextureContext = Q_NULLPTR;
}
}
diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro
index 34e2ed3c9b..1ea6d0eb69 100644
--- a/src/platformsupport/platformsupport.pro
+++ b/src/platformsupport/platformsupport.pro
@@ -7,7 +7,6 @@ mac:LIBS_PRIVATE += -lz
DEFINES += QT_NO_CAST_FROM_ASCII
PRECOMPILED_HEADER = ../corelib/global/qt_pch.h
-include(cfsocketnotifier/cfsocketnotifier.pri)
include(cglconvenience/cglconvenience.pri)
include(eglconvenience/eglconvenience.pri)
include(eventdispatchers/eventdispatchers.pri)
diff --git a/src/platformsupport/services/genericunix/qgenericunixservices.cpp b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
index b59ae431f4..33cb4391f0 100644
--- a/src/platformsupport/services/genericunix/qgenericunixservices.cpp
+++ b/src/platformsupport/services/genericunix/qgenericunixservices.cpp
@@ -134,7 +134,7 @@ bool QGenericUnixServices::openUrl(const QUrl &url)
return openDocument(url);
if (m_webBrowser.isEmpty() && !detectWebBrowser(desktopEnvironment(), true, &m_webBrowser)) {
- qWarning("%s: Unable to detect a web browser to launch '%s'", Q_FUNC_INFO, qPrintable(url.toString()));
+ qWarning("Unable to detect a web browser to launch '%s'", qPrintable(url.toString()));
return false;
}
return launch(m_webBrowser, url);
@@ -143,7 +143,7 @@ bool QGenericUnixServices::openUrl(const QUrl &url)
bool QGenericUnixServices::openDocument(const QUrl &url)
{
if (m_documentLauncher.isEmpty() && !detectWebBrowser(desktopEnvironment(), false, &m_documentLauncher)) {
- qWarning("%s: Unable to detect a launcher for '%s'", Q_FUNC_INFO, qPrintable(url.toString()));
+ qWarning("Unable to detect a launcher for '%s'", qPrintable(url.toString()));
return false;
}
return launch(m_documentLauncher, url);
diff --git a/src/platformsupport/services/genericunix/qgenericunixservices_p.h b/src/platformsupport/services/genericunix/qgenericunixservices_p.h
index 0c15d62165..89d5a4dab4 100644
--- a/src/platformsupport/services/genericunix/qgenericunixservices_p.h
+++ b/src/platformsupport/services/genericunix/qgenericunixservices_p.h
@@ -57,8 +57,8 @@ public:
QByteArray desktopEnvironment() const Q_DECL_OVERRIDE;
- virtual bool openUrl(const QUrl &url) Q_DECL_OVERRIDE;
- virtual bool openDocument(const QUrl &url) Q_DECL_OVERRIDE;
+ bool openUrl(const QUrl &url) Q_DECL_OVERRIDE;
+ bool openDocument(const QUrl &url) Q_DECL_OVERRIDE;
private:
QString m_webBrowser;
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
index 2963b0502d..0bcd3464b7 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes.cpp
@@ -47,6 +47,7 @@
#include <QtCore/QLoggingCategory>
#include <QtCore/QSettings>
#include <QtCore/QVariant>
+#include <QtCore/QStandardPaths>
#include <QtCore/QStringList>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
@@ -209,14 +210,16 @@ public:
, wheelScrollLines(3)
{ }
- static QString kdeGlobals(const QString &kdeDir)
+ static QString kdeGlobals(const QString &kdeDir, int kdeVersion)
{
+ if (kdeVersion > 4)
+ return kdeDir + QStringLiteral("/kdeglobals");
return kdeDir + QStringLiteral("/share/config/kdeglobals");
}
void refresh();
- static QVariant readKdeSetting(const QString &key, const QStringList &kdeDirs, QHash<QString, QSettings*> &kdeSettings);
- static void readKdeSystemPalette(const QStringList &kdeDirs, QHash<QString, QSettings*> &kdeSettings, QPalette *pal);
+ static QVariant readKdeSetting(const QString &key, const QStringList &kdeDirs, int kdeVersion, QHash<QString, QSettings*> &kdeSettings);
+ static void readKdeSystemPalette(const QStringList &kdeDirs, int kdeVersion, QHash<QString, QSettings*> &kdeSettings, QPalette *pal);
static QFont *kdeFont(const QVariant &fontValue);
static QStringList kdeIconThemeSearchPaths(const QStringList &kdeDirs);
@@ -251,30 +254,30 @@ void QKdeThemePrivate::refresh()
QHash<QString, QSettings*> kdeSettings;
QPalette systemPalette = QPalette();
- readKdeSystemPalette(kdeDirs, kdeSettings, &systemPalette);
+ readKdeSystemPalette(kdeDirs, kdeVersion, kdeSettings, &systemPalette);
resources.palettes[QPlatformTheme::SystemPalette] = new QPalette(systemPalette);
//## TODO tooltip color
- const QVariant styleValue = readKdeSetting(QStringLiteral("widgetStyle"), kdeDirs, kdeSettings);
+ const QVariant styleValue = readKdeSetting(QStringLiteral("widgetStyle"), kdeDirs, kdeVersion, kdeSettings);
if (styleValue.isValid()) {
const QString style = styleValue.toString();
if (style != styleNames.front())
styleNames.push_front(style);
}
- const QVariant singleClickValue = readKdeSetting(QStringLiteral("KDE/SingleClick"), kdeDirs, kdeSettings);
+ const QVariant singleClickValue = readKdeSetting(QStringLiteral("KDE/SingleClick"), kdeDirs, kdeVersion, kdeSettings);
if (singleClickValue.isValid())
singleClick = singleClickValue.toBool();
- const QVariant themeValue = readKdeSetting(QStringLiteral("Icons/Theme"), kdeDirs, kdeSettings);
+ const QVariant themeValue = readKdeSetting(QStringLiteral("Icons/Theme"), kdeDirs, kdeVersion, kdeSettings);
if (themeValue.isValid())
iconThemeName = themeValue.toString();
- const QVariant toolBarIconSizeValue = readKdeSetting(QStringLiteral("ToolbarIcons/Size"), kdeDirs, kdeSettings);
+ const QVariant toolBarIconSizeValue = readKdeSetting(QStringLiteral("ToolbarIcons/Size"), kdeDirs, kdeVersion, kdeSettings);
if (toolBarIconSizeValue.isValid())
toolBarIconSize = toolBarIconSizeValue.toInt();
- const QVariant toolbarStyleValue = readKdeSetting(QStringLiteral("Toolbar style/ToolButtonStyle"), kdeDirs, kdeSettings);
+ const QVariant toolbarStyleValue = readKdeSetting(QStringLiteral("Toolbar style/ToolButtonStyle"), kdeDirs, kdeVersion, kdeSettings);
if (toolbarStyleValue.isValid()) {
const QString toolBarStyle = toolbarStyleValue.toString();
if (toolBarStyle == QLatin1String("TextBesideIcon"))
@@ -285,17 +288,17 @@ void QKdeThemePrivate::refresh()
toolButtonStyle = Qt::ToolButtonTextUnderIcon;
}
- const QVariant wheelScrollLinesValue = readKdeSetting(QStringLiteral("KDE/WheelScrollLines"), kdeDirs, kdeSettings);
+ const QVariant wheelScrollLinesValue = readKdeSetting(QStringLiteral("KDE/WheelScrollLines"), kdeDirs, kdeVersion, kdeSettings);
if (wheelScrollLinesValue.isValid())
wheelScrollLines = wheelScrollLinesValue.toInt();
// Read system font, ignore 'smallestReadableFont'
- if (QFont *systemFont = kdeFont(readKdeSetting(QStringLiteral("font"), kdeDirs, kdeSettings)))
+ if (QFont *systemFont = kdeFont(readKdeSetting(QStringLiteral("font"), kdeDirs, kdeVersion, kdeSettings)))
resources.fonts[QPlatformTheme::SystemFont] = systemFont;
else
resources.fonts[QPlatformTheme::SystemFont] = new QFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize);
- if (QFont *fixedFont = kdeFont(readKdeSetting(QStringLiteral("fixed"), kdeDirs, kdeSettings))) {
+ if (QFont *fixedFont = kdeFont(readKdeSetting(QStringLiteral("fixed"), kdeDirs, kdeVersion, kdeSettings))) {
resources.fonts[QPlatformTheme::FixedFont] = fixedFont;
} else {
fixedFont = new QFont(QLatin1String(defaultSystemFontNameC), defaultSystemFontSize);
@@ -306,12 +309,12 @@ void QKdeThemePrivate::refresh()
qDeleteAll(kdeSettings);
}
-QVariant QKdeThemePrivate::readKdeSetting(const QString &key, const QStringList &kdeDirs, QHash<QString, QSettings*> &kdeSettings)
+QVariant QKdeThemePrivate::readKdeSetting(const QString &key, const QStringList &kdeDirs, int kdeVersion, QHash<QString, QSettings*> &kdeSettings)
{
foreach (const QString &kdeDir, kdeDirs) {
QSettings *settings = kdeSettings.value(kdeDir);
if (!settings) {
- const QString kdeGlobalsPath = kdeGlobals(kdeDir);
+ const QString kdeGlobalsPath = kdeGlobals(kdeDir, kdeVersion);
if (QFileInfo(kdeGlobalsPath).isReadable()) {
settings = new QSettings(kdeGlobalsPath, QSettings::IniFormat);
kdeSettings.insert(kdeDir, settings);
@@ -339,9 +342,9 @@ static inline bool kdeColor(QPalette *pal, QPalette::ColorRole role, const QVari
return true;
}
-void QKdeThemePrivate::readKdeSystemPalette(const QStringList &kdeDirs, QHash<QString, QSettings*> &kdeSettings, QPalette *pal)
+void QKdeThemePrivate::readKdeSystemPalette(const QStringList &kdeDirs, int kdeVersion, QHash<QString, QSettings*> &kdeSettings, QPalette *pal)
{
- if (!kdeColor(pal, QPalette::Button, readKdeSetting(QStringLiteral("Colors:Button/BackgroundNormal"), kdeDirs, kdeSettings))) {
+ if (!kdeColor(pal, QPalette::Button, readKdeSetting(QStringLiteral("Colors:Button/BackgroundNormal"), kdeDirs, kdeVersion, kdeSettings))) {
// kcolorscheme.cpp: SetDefaultColors
const QColor defaultWindowBackground(214, 210, 208);
const QColor defaultButtonBackground(223, 220, 217);
@@ -349,18 +352,18 @@ void QKdeThemePrivate::readKdeSystemPalette(const QStringList &kdeDirs, QHash<QS
return;
}
- kdeColor(pal, QPalette::Window, readKdeSetting(QStringLiteral("Colors:Window/BackgroundNormal"), kdeDirs, kdeSettings));
- kdeColor(pal, QPalette::Text, readKdeSetting(QStringLiteral("Colors:View/ForegroundNormal"), kdeDirs, kdeSettings));
- kdeColor(pal, QPalette::WindowText, readKdeSetting(QStringLiteral("Colors:Window/ForegroundNormal"), kdeDirs, kdeSettings));
- kdeColor(pal, QPalette::Base, readKdeSetting(QStringLiteral("Colors:View/BackgroundNormal"), kdeDirs, kdeSettings));
- kdeColor(pal, QPalette::Highlight, readKdeSetting(QStringLiteral("Colors:Selection/BackgroundNormal"), kdeDirs, kdeSettings));
- kdeColor(pal, QPalette::HighlightedText, readKdeSetting(QStringLiteral("Colors:Selection/ForegroundNormal"), kdeDirs, kdeSettings));
- kdeColor(pal, QPalette::AlternateBase, readKdeSetting(QStringLiteral("Colors:View/BackgroundAlternate"), kdeDirs, kdeSettings));
- kdeColor(pal, QPalette::ButtonText, readKdeSetting(QStringLiteral("Colors:Button/ForegroundNormal"), kdeDirs, kdeSettings));
- kdeColor(pal, QPalette::Link, readKdeSetting(QStringLiteral("Colors:View/ForegroundLink"), kdeDirs, kdeSettings));
- kdeColor(pal, QPalette::LinkVisited, readKdeSetting(QStringLiteral("Colors:View/ForegroundVisited"), kdeDirs, kdeSettings));
- kdeColor(pal, QPalette::ToolTipBase, readKdeSetting(QStringLiteral("Colors:Tooltip/BackgroundNormal"), kdeDirs, kdeSettings));
- kdeColor(pal, QPalette::ToolTipText, readKdeSetting(QStringLiteral("Colors:Tooltip/ForegroundNormal"), kdeDirs, kdeSettings));
+ kdeColor(pal, QPalette::Window, readKdeSetting(QStringLiteral("Colors:Window/BackgroundNormal"), kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::Text, readKdeSetting(QStringLiteral("Colors:View/ForegroundNormal"), kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::WindowText, readKdeSetting(QStringLiteral("Colors:Window/ForegroundNormal"), kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::Base, readKdeSetting(QStringLiteral("Colors:View/BackgroundNormal"), kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::Highlight, readKdeSetting(QStringLiteral("Colors:Selection/BackgroundNormal"), kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::HighlightedText, readKdeSetting(QStringLiteral("Colors:Selection/ForegroundNormal"), kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::AlternateBase, readKdeSetting(QStringLiteral("Colors:View/BackgroundAlternate"), kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::ButtonText, readKdeSetting(QStringLiteral("Colors:Button/ForegroundNormal"), kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::Link, readKdeSetting(QStringLiteral("Colors:View/ForegroundLink"), kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::LinkVisited, readKdeSetting(QStringLiteral("Colors:View/ForegroundVisited"), kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::ToolTipBase, readKdeSetting(QStringLiteral("Colors:Tooltip/BackgroundNormal"), kdeDirs, kdeVersion, kdeSettings));
+ kdeColor(pal, QPalette::ToolTipText, readKdeSetting(QStringLiteral("Colors:Tooltip/ForegroundNormal"), kdeDirs, kdeVersion, kdeSettings));
// The above code sets _all_ color roles to "normal" colors. In KDE, the disabled
// color roles are calculated by applying various effects described in kdeglobals.
@@ -502,6 +505,11 @@ QPlatformTheme *QKdeTheme::createKdeTheme()
if (kdeVersion < 4)
return 0;
+ if (kdeVersion > 4)
+ // Plasma 5 follows XDG spec
+ // but uses the same config file format:
+ return new QKdeTheme(QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation), kdeVersion);
+
// Determine KDE prefixes in the following priority order:
// - KDEHOME and KDEDIRS environment variables
// - ~/.kde(<version>)
@@ -538,7 +546,7 @@ QPlatformTheme *QKdeTheme::createKdeTheme()
kdeDirs.removeDuplicates();
if (kdeDirs.isEmpty()) {
- qWarning("%s: Unable to determine KDE dirs", Q_FUNC_INFO);
+ qWarning("Unable to determine KDE dirs");
return 0;
}
@@ -569,23 +577,23 @@ const char *QGnomeTheme::name = "gnome";
class QGnomeThemePrivate : public QPlatformThemePrivate
{
public:
- QGnomeThemePrivate() : fontsConfigured(false) { }
+ QGnomeThemePrivate() : systemFont(Q_NULLPTR), fixedFont(Q_NULLPTR) {}
+ ~QGnomeThemePrivate() { delete systemFont; delete fixedFont; }
+
void configureFonts(const QString &gtkFontName) const
{
- Q_ASSERT(!fontsConfigured);
+ Q_ASSERT(!systemFont);
const int split = gtkFontName.lastIndexOf(QChar::Space);
float size = gtkFontName.mid(split+1).toFloat();
QString fontName = gtkFontName.left(split);
- systemFont = QFont(fontName, size);
- fixedFont = QFont(QLatin1String("monospace"), systemFont.pointSize());
- fixedFont.setStyleHint(QFont::TypeWriter);
- fontsConfigured = true;
+ systemFont = new QFont(fontName, size);
+ fixedFont = new QFont(QLatin1String("monospace"), systemFont->pointSize());
+ fixedFont->setStyleHint(QFont::TypeWriter);
}
- mutable QFont systemFont;
- mutable QFont fixedFont;
- mutable bool fontsConfigured;
+ mutable QFont *systemFont;
+ mutable QFont *fixedFont;
};
QGnomeTheme::QGnomeTheme()
@@ -601,8 +609,9 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
case QPlatformTheme::DialogButtonBoxLayout:
return QVariant(QPlatformDialogHelper::GnomeLayout);
case QPlatformTheme::SystemIconThemeName:
+ return QVariant(QStringLiteral("Adwaita"));
case QPlatformTheme::SystemIconFallbackThemeName:
- return QVariant(QString(QStringLiteral("gnome")));
+ return QVariant(QStringLiteral("gnome"));
case QPlatformTheme::IconThemeSearchPaths:
return QVariant(QGenericUnixTheme::xdgIconThemePaths());
case QPlatformTheme::StyleNames: {
@@ -623,13 +632,13 @@ QVariant QGnomeTheme::themeHint(QPlatformTheme::ThemeHint hint) const
const QFont *QGnomeTheme::font(Font type) const
{
Q_D(const QGnomeTheme);
- if (!d->fontsConfigured)
+ if (!d->systemFont)
d->configureFonts(gtkFontName());
switch (type) {
case QPlatformTheme::SystemFont:
- return &d->systemFont;
+ return d->systemFont;
case QPlatformTheme::FixedFont:
- return &d->fixedFont;
+ return d->fixedFont;
default:
return 0;
}
@@ -683,7 +692,7 @@ QPlatformTheme *QGenericUnixTheme::createUnixTheme(const QString &name)
#endif
if (name == QLatin1String(QGnomeTheme::name))
return new QGnomeTheme;
- return new QGenericUnixTheme;
+ return Q_NULLPTR;
}
QStringList QGenericUnixTheme::themeNames()
@@ -715,8 +724,7 @@ QStringList QGenericUnixTheme::themeNames()
if (!session.isEmpty() && session != QLatin1String("default") && !result.contains(session))
result.push_back(session);
} // desktopSettingsAware
- if (result.isEmpty())
- result.push_back(QLatin1String(QGenericUnixTheme::name));
+ result.append(QLatin1String(QGenericUnixTheme::name));
return result;
}
diff --git a/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h b/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
index 115b9d9f91..77aa04fe95 100644
--- a/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
+++ b/src/platformsupport/themes/genericunix/qgenericunixthemes_p.h
@@ -75,8 +75,8 @@ public:
static QPlatformTheme *createUnixTheme(const QString &name);
static QStringList themeNames();
- virtual const QFont *font(Font type) const Q_DECL_OVERRIDE;
- virtual QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE;
+ const QFont *font(Font type) const Q_DECL_OVERRIDE;
+ QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE;
static QStringList xdgIconThemePaths();
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
@@ -96,11 +96,11 @@ public:
QKdeTheme(const QStringList& kdeDirs, int kdeVersion);
static QPlatformTheme *createKdeTheme();
- virtual QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE;
+ QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE;
- virtual const QPalette *palette(Palette type = SystemPalette) const Q_DECL_OVERRIDE;
+ const QPalette *palette(Palette type = SystemPalette) const Q_DECL_OVERRIDE;
- virtual const QFont *font(Font type) const Q_DECL_OVERRIDE;
+ const QFont *font(Font type) const Q_DECL_OVERRIDE;
#if !defined(QT_NO_DBUS) && !defined(QT_NO_SYSTEMTRAYICON)
QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const Q_DECL_OVERRIDE;
#endif
@@ -116,8 +116,8 @@ class QGnomeTheme : public QPlatformTheme
Q_DECLARE_PRIVATE(QGnomeTheme)
public:
QGnomeTheme();
- virtual QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE;
- virtual const QFont *font(Font type) const Q_DECL_OVERRIDE;
+ QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE;
+ const QFont *font(Font type) const Q_DECL_OVERRIDE;
QString standardButtonText(int button) const Q_DECL_OVERRIDE;
virtual QString gtkFontName() const;